wip: removing vec3 tls

This commit is contained in:
orng 2026-03-26 01:10:27 -05:00
parent c18e86944f
commit 7b021bc99d
62 changed files with 1070 additions and 1045 deletions

View file

@ -2750,7 +2750,7 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) {
// 4J-PB - Call the useItemOn with the TestOnly flag set // 4J-PB - Call the useItemOn with the TestOnly flag set
bool bUseItemOn = gameMode->useItemOn( bool bUseItemOn = gameMode->useItemOn(
player, level, itemInstance, x, y, z, face, player, level, itemInstance, x, y, z, face,
hitResult->pos, true); &hitResult->pos, true);
/* 4J-Jev: /* 4J-Jev:
* Moved this here so we have item tooltips to * Moved this here so we have item tooltips to
@ -3900,7 +3900,7 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) {
bool usedItem = false; bool usedItem = false;
gameMode->useItemOn(player, level, nullptr, hitResult->x, gameMode->useItemOn(player, level, nullptr, hitResult->x,
hitResult->y, hitResult->z, 0, hitResult->y, hitResult->z, 0,
hitResult->pos, false, &usedItem); &hitResult->pos, false, &usedItem);
} else { } else {
ui.PlayUISFX(eSFX_Press); ui.PlayUISFX(eSFX_Press);
app.LoadCrafting2x2Menu(iPad, player); app.LoadCrafting2x2Menu(iPad, player);

View file

@ -1551,7 +1551,8 @@ void PlayerConnection::handlePlayerAbilities(
// StringBuilder result = new StringBuilder(); // StringBuilder result = new StringBuilder();
// for (String candidate : server.getAutoCompletions(player, // for (String candidate : server.getAutoCompletions(player,
//packet.getMessage())) { if (result.length() > 0) result.append("\0"); // packet.getMessage())) { if (result.length() > 0)
// result.append("\0");
// result.append(candidate); // result.append(candidate);
// } // }

View file

@ -27,373 +27,359 @@
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
namespace boost { namespace spirit { namespace lex { namespace lexertl namespace boost {
{ namespace spirit {
/////////////////////////////////////////////////////////////////////////// namespace lex {
namespace detail namespace lexertl {
{ ///////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////// namespace detail {
// The must_escape function checks if the given character value needs ///////////////////////////////////////////////////////////////////////
// to be preceded by a backslash character to disable its special // The must_escape function checks if the given character value needs
// meaning in the context of a regular expression // to be preceded by a backslash character to disable its special
/////////////////////////////////////////////////////////////////////// // meaning in the context of a regular expression
template <typename Char> ///////////////////////////////////////////////////////////////////////
inline bool must_escape(Char c) template <typename Char>
{ inline bool must_escape(Char c) {
// FIXME: more needed? // FIXME: more needed?
switch (c) { switch (c) {
case '+': case '/': case '*': case '?': case '+':
case '|': case '/':
case '(': case ')': case '*':
case '[': case ']': case '?':
case '{': case '}': case '|':
case '.': case '(':
case '^': case '$': case ')':
case '\\': case '[':
case '"': case ']':
return true; case '{':
case '}':
case '.':
case '^':
case '$':
case '\\':
case '"':
return true;
default: default:
break; break;
} }
return false; return false;
} }
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
// The escape function returns the string representation of the given // The escape function returns the string representation of the given
// character value, possibly escaped with a backslash character, to // character value, possibly escaped with a backslash character, to
// allow it being safely used in a regular expression definition. // allow it being safely used in a regular expression definition.
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
template <typename Char> template <typename Char>
inline std::basic_string<Char> escape(Char ch) inline std::basic_string<Char> escape(Char ch) {
{ std::basic_string<Char> result(1, ch);
std::basic_string<Char> result(1, ch); if (detail::must_escape(ch)) {
if (detail::must_escape(ch)) typedef typename std::basic_string<Char>::size_type size_type;
{ result.insert((size_type)0, 1, '\\');
typedef typename std::basic_string<Char>::size_type size_type; }
result.insert((size_type)0, 1, '\\'); return result;
} }
return result;
}
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
// //
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
inline boost::lexer::regex_flags map_flags(unsigned int flags) inline boost::lexer::regex_flags map_flags(unsigned int flags) {
{ unsigned int retval = boost::lexer::none;
unsigned int retval = boost::lexer::none; if (flags & match_flags::match_not_dot_newline)
if (flags & match_flags::match_not_dot_newline) retval |= boost::lexer::dot_not_newline;
retval |= boost::lexer::dot_not_newline; if (flags & match_flags::match_icase) retval |= boost::lexer::icase;
if (flags & match_flags::match_icase)
retval |= boost::lexer::icase;
return boost::lexer::regex_flags(retval); return boost::lexer::regex_flags(retval);
} }
} // namespace detail
///////////////////////////////////////////////////////////////////////////
template <typename Lexer, typename F>
bool generate_static(Lexer const&,
std::basic_ostream<typename Lexer::char_type>&,
typename Lexer::char_type const*, F);
///////////////////////////////////////////////////////////////////////////
//
// Every lexer type to be used as a lexer for Spirit has to conform to
// the following public interface:
//
// typedefs:
// iterator_type The type of the iterator exposed by this lexer.
// token_type The type of the tokens returned from the exposed
// iterators.
//
// functions:
// default constructor
// Since lexers are instantiated as base classes
// only it might be a good idea to make this
// constructor protected.
// begin, end Return a pair of iterators, when dereferenced
// returning the sequence of tokens recognized in
// the input stream given as the parameters to the
// begin() function.
// add_token Should add the definition of a token to be
// recognized by this lexer.
// clear Should delete all current token definitions
// associated with the given state of this lexer
// object.
//
// template parameters:
// Iterator The type of the iterator used to access the
// underlying character stream.
// Token The type of the tokens to be returned from the
// exposed token iterator.
// Functor The type of the InputPolicy to use to instantiate
// the multi_pass iterator type to be used as the
// token iterator (returned from begin()/end()).
//
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
//
// The lexer class is a implementation of a Spirit.Lex lexer on
// top of Ben Hanson's lexertl library as outlined above (For more
// information about lexertl go here: http://www.benhanson.net/lexertl.html).
//
// This class is supposed to be used as the first and only template
// parameter while instantiating instances of a lex::lexer class.
//
///////////////////////////////////////////////////////////////////////////
template <typename Token = token<>,
typename Iterator = typename Token::iterator_type,
typename Functor = functor<Token, lexertl::detail::data, Iterator> >
class lexer {
private:
struct dummy {
void true_() {}
};
typedef void (dummy::*safe_bool)();
static std::size_t const all_states_id = static_cast<std::size_t>(-2);
public:
operator safe_bool() const { return initialized_dfa_ ? &dummy::true_ : 0; }
typedef
typename boost::detail::iterator_traits<Iterator>::value_type char_type;
typedef std::basic_string<char_type> string_type;
typedef boost::lexer::basic_rules<char_type> basic_rules_type;
// Every lexer type to be used as a lexer for Spirit has to conform to
// a public interface .
typedef Token token_type;
typedef typename Token::id_type id_type;
typedef iterator<Functor> iterator_type;
private:
// this type is purely used for the iterator_type construction below
struct iterator_data_type {
typedef typename Functor::semantic_actions_type semantic_actions_type;
iterator_data_type(
boost::lexer::basic_state_machine<char_type> const& sm,
boost::lexer::basic_rules<char_type> const& rules,
semantic_actions_type const& actions)
: state_machine_(sm), rules_(rules), actions_(actions) {}
boost::lexer::basic_state_machine<char_type> const& state_machine_;
boost::lexer::basic_rules<char_type> const& rules_;
semantic_actions_type const& actions_;
private:
// silence MSVC warning C4512: assignment operator could not be
// generated
iterator_data_type& operator=(iterator_data_type const&);
};
public:
// Return the start iterator usable for iterating over the generated
// tokens.
iterator_type begin(Iterator& first, Iterator const& last,
char_type const* initial_state = 0) const {
if (!init_dfa()) // never minimize DFA for dynamic lexers
return iterator_type();
iterator_data_type iterator_data(state_machine_, rules_, actions_);
return iterator_type(iterator_data, first, last, initial_state);
} }
/////////////////////////////////////////////////////////////////////////// // Return the end iterator usable to stop iterating over the generated
template <typename Lexer, typename F> // tokens.
bool generate_static(Lexer const& iterator_type end() const { return iterator_type(); }
, std::basic_ostream<typename Lexer::char_type>&
, typename Lexer::char_type const*, F);
/////////////////////////////////////////////////////////////////////////// protected:
// // Lexer instances can be created by means of a derived class only.
// Every lexer type to be used as a lexer for Spirit has to conform to lexer(unsigned int flags)
// the following public interface: : flags_(detail::map_flags(flags)),
// rules_(flags_),
// typedefs: initialized_dfa_(false) {}
// iterator_type The type of the iterator exposed by this lexer.
// token_type The type of the tokens returned from the exposed
// iterators.
//
// functions:
// default constructor
// Since lexers are instantiated as base classes
// only it might be a good idea to make this
// constructor protected.
// begin, end Return a pair of iterators, when dereferenced
// returning the sequence of tokens recognized in
// the input stream given as the parameters to the
// begin() function.
// add_token Should add the definition of a token to be
// recognized by this lexer.
// clear Should delete all current token definitions
// associated with the given state of this lexer
// object.
//
// template parameters:
// Iterator The type of the iterator used to access the
// underlying character stream.
// Token The type of the tokens to be returned from the
// exposed token iterator.
// Functor The type of the InputPolicy to use to instantiate
// the multi_pass iterator type to be used as the
// token iterator (returned from begin()/end()).
//
///////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////// public:
// // interface for token definition management
// The lexer class is a implementation of a Spirit.Lex lexer on std::size_t add_token(char_type const* state, char_type tokendef,
// top of Ben Hanson's lexertl library as outlined above (For more std::size_t token_id, char_type const* targetstate) {
// information about lexertl go here: http://www.benhanson.net/lexertl.html). add_state(state);
// initialized_dfa_ = false;
// This class is supposed to be used as the first and only template if (state == all_states())
// parameter while instantiating instances of a lex::lexer class. return rules_.add(state, detail::escape(tokendef), token_id,
// rules_.dot());
///////////////////////////////////////////////////////////////////////////
template <typename Token = token<>
, typename Iterator = typename Token::iterator_type
, typename Functor = functor<Token, lexertl::detail::data, Iterator> >
class lexer
{
private:
struct dummy { void true_() {} };
typedef void (dummy::*safe_bool)();
static std::size_t const all_states_id = static_cast<std::size_t>(-2); if (0 == targetstate)
targetstate = state;
else
add_state(targetstate);
return rules_.add(state, detail::escape(tokendef), token_id,
targetstate);
}
std::size_t add_token(char_type const* state, string_type const& tokendef,
std::size_t token_id, char_type const* targetstate) {
add_state(state);
initialized_dfa_ = false;
if (state == all_states())
return rules_.add(state, tokendef, token_id, rules_.dot());
public: if (0 == targetstate)
operator safe_bool() const targetstate = state;
{ return initialized_dfa_ ? &dummy::true_ : 0; } else
add_state(targetstate);
return rules_.add(state, tokendef, token_id, targetstate);
}
typedef typename boost::detail::iterator_traits<Iterator>::value_type // interface for pattern definition management
char_type; void add_pattern(char_type const* state, string_type const& name,
typedef std::basic_string<char_type> string_type; string_type const& patterndef) {
add_state(state);
rules_.add_macro(name.c_str(), patterndef);
initialized_dfa_ = false;
}
typedef boost::lexer::basic_rules<char_type> basic_rules_type; boost::lexer::rules const& get_rules() const { return rules_; }
// Every lexer type to be used as a lexer for Spirit has to conform to void clear(char_type const* state) {
// a public interface . std::size_t s = rules_.state(state);
typedef Token token_type; if (boost::lexer::npos != s) rules_.clear(state);
typedef typename Token::id_type id_type; initialized_dfa_ = false;
typedef iterator<Functor> iterator_type; }
std::size_t add_state(char_type const* state) {
if (state == all_states()) return all_states_id;
private: std::size_t stateid = rules_.state(state);
// this type is purely used for the iterator_type construction below if (boost::lexer::npos == stateid) {
struct iterator_data_type stateid = rules_.add_state(state);
{
typedef typename Functor::semantic_actions_type semantic_actions_type;
iterator_data_type(
boost::lexer::basic_state_machine<char_type> const& sm
, boost::lexer::basic_rules<char_type> const& rules
, semantic_actions_type const& actions)
: state_machine_(sm), rules_(rules), actions_(actions)
{}
boost::lexer::basic_state_machine<char_type> const& state_machine_;
boost::lexer::basic_rules<char_type> const& rules_;
semantic_actions_type const& actions_;
private:
// silence MSVC warning C4512: assignment operator could not be generated
iterator_data_type& operator= (iterator_data_type const&);
};
public:
// Return the start iterator usable for iterating over the generated
// tokens.
iterator_type begin(Iterator& first, Iterator const& last
, char_type const* initial_state = 0) const
{
if (!init_dfa()) // never minimize DFA for dynamic lexers
return iterator_type();
iterator_data_type iterator_data(state_machine_, rules_, actions_);
return iterator_type(iterator_data, first, last, initial_state);
}
// Return the end iterator usable to stop iterating over the generated
// tokens.
iterator_type end() const
{
return iterator_type();
}
protected:
// Lexer instances can be created by means of a derived class only.
lexer(unsigned int flags)
: flags_(detail::map_flags(flags))
, rules_(flags_)
, initialized_dfa_(false)
{}
public:
// interface for token definition management
std::size_t add_token(char_type const* state, char_type tokendef,
std::size_t token_id, char_type const* targetstate)
{
add_state(state);
initialized_dfa_ = false;
if (state == all_states())
return rules_.add(state, detail::escape(tokendef), token_id, rules_.dot());
if (0 == targetstate)
targetstate = state;
else
add_state(targetstate);
return rules_.add(state, detail::escape(tokendef), token_id, targetstate);
}
std::size_t add_token(char_type const* state, string_type const& tokendef,
std::size_t token_id, char_type const* targetstate)
{
add_state(state);
initialized_dfa_ = false;
if (state == all_states())
return rules_.add(state, tokendef, token_id, rules_.dot());
if (0 == targetstate)
targetstate = state;
else
add_state(targetstate);
return rules_.add(state, tokendef, token_id, targetstate);
}
// interface for pattern definition management
void add_pattern (char_type const* state, string_type const& name,
string_type const& patterndef)
{
add_state(state);
rules_.add_macro(name.c_str(), patterndef);
initialized_dfa_ = false; initialized_dfa_ = false;
} }
return stateid;
}
string_type initial_state() const { return string_type(rules_.initial()); }
string_type all_states() const { return string_type(rules_.all_states()); }
boost::lexer::rules const& get_rules() const { return rules_; } // Register a semantic action with the given id
template <typename F>
void clear(char_type const* state) void add_action(std::size_t unique_id, std::size_t state, F act) {
{ // If you see an error here stating add_action is not a member of
std::size_t s = rules_.state(state); // fusion::unused_type then you are probably having semantic actions
if (boost::lexer::npos != s) // attached to at least one token in the lexer definition without
rules_.clear(state); // using the lex::lexertl::actor_lexer<> as its base class.
initialized_dfa_ = false; typedef typename Functor::wrap_action_type wrapper_type;
} if (state == all_states_id) {
std::size_t add_state(char_type const* state) // add the action to all known states
{ typedef typename basic_rules_type::string_size_t_map::value_type
if (state == all_states())
return all_states_id;
std::size_t stateid = rules_.state(state);
if (boost::lexer::npos == stateid) {
stateid = rules_.add_state(state);
initialized_dfa_ = false;
}
return stateid;
}
string_type initial_state() const
{
return string_type(rules_.initial());
}
string_type all_states() const
{
return string_type(rules_.all_states());
}
// Register a semantic action with the given id
template <typename F>
void add_action(std::size_t unique_id, std::size_t state, F act)
{
// If you see an error here stating add_action is not a member of
// fusion::unused_type then you are probably having semantic actions
// attached to at least one token in the lexer definition without
// using the lex::lexertl::actor_lexer<> as its base class.
typedef typename Functor::wrap_action_type wrapper_type;
if (state == all_states_id) {
// add the action to all known states
typedef typename
basic_rules_type::string_size_t_map::value_type
state_type; state_type;
std::size_t states = rules_.statemap().size(); std::size_t states = rules_.statemap().size();
BOOST_FOREACH(state_type const& s, rules_.statemap()) { BOOST_FOREACH (state_type const& s, rules_.statemap()) {
for (std::size_t j = 0; j < states; ++j) for (std::size_t j = 0; j < states; ++j)
actions_.add_action(unique_id + j, s.second, wrapper_type::call(act)); actions_.add_action(unique_id + j, s.second,
} wrapper_type::call(act));
}
else {
actions_.add_action(unique_id, state, wrapper_type::call(act));
} }
} else {
actions_.add_action(unique_id, state, wrapper_type::call(act));
} }
// template <typename F> }
// void add_action(std::size_t unique_id, char_type const* state, F act) // template <typename F>
// { // void add_action(std::size_t unique_id, char_type const* state, F
// typedef typename Functor::wrap_action_type wrapper_type; // act)
// actions_.add_action(unique_id, add_state(state), wrapper_type::call(act)); // {
// } // typedef typename Functor::wrap_action_type wrapper_type;
// actions_.add_action(unique_id, add_state(state),
// wrapper_type::call(act));
// }
// We do not minimize the state machine by default anymore because // We do not minimize the state machine by default anymore because
// Ben said: "If you can afford to generate a lexer at runtime, there // Ben said: "If you can afford to generate a lexer at runtime, there
// is little point in calling minimise." // is little point in calling minimise."
// Go figure. // Go figure.
bool init_dfa(bool minimize = false) const bool init_dfa(bool minimize = false) const {
{ if (!initialized_dfa_) {
if (!initialized_dfa_) { state_machine_.clear();
state_machine_.clear(); typedef boost::lexer::basic_generator<char_type> generator;
typedef boost::lexer::basic_generator<char_type> generator; generator::build(rules_, state_machine_);
generator::build (rules_, state_machine_); if (minimize) generator::minimise(state_machine_);
if (minimize)
generator::minimise (state_machine_);
#if defined(BOOST_SPIRIT_LEXERTL_DEBUG) #if defined(BOOST_SPIRIT_LEXERTL_DEBUG)
boost::lexer::debug::dump(state_machine_, std::cerr); boost::lexer::debug::dump(state_machine_, std::cerr);
#endif #endif
initialized_dfa_ = true; initialized_dfa_ = true;
// // release memory held by rules description // // release memory held by rules description
// basic_rules_type rules; // basic_rules_type rules;
// rules.init_state_info(rules_); // preserve states // rules.init_state_info(rules_); // preserve
// std::swap(rules, rules_); // states std::swap(rules, rules_);
}
return true;
} }
return true;
}
private: private:
// lexertl specific data // lexertl specific data
mutable boost::lexer::basic_state_machine<char_type> state_machine_; mutable boost::lexer::basic_state_machine<char_type> state_machine_;
boost::lexer::regex_flags flags_; boost::lexer::regex_flags flags_;
/*mutable*/ basic_rules_type rules_; /*mutable*/ basic_rules_type rules_;
typename Functor::semantic_actions_type actions_; typename Functor::semantic_actions_type actions_;
mutable bool initialized_dfa_; mutable bool initialized_dfa_;
// generator functions must be able to access members directly // generator functions must be able to access members directly
template <typename Lexer, typename F> template <typename Lexer, typename F>
friend bool generate_static(Lexer const& friend bool generate_static(Lexer const&,
, std::basic_ostream<typename Lexer::char_type>& std::basic_ostream<typename Lexer::char_type>&,
, typename Lexer::char_type const*, F); typename Lexer::char_type const*, F);
}; };
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// //
// The actor_lexer class is another implementation of a Spirit.Lex // The actor_lexer class is another implementation of a Spirit.Lex
// lexer on top of Ben Hanson's lexertl library as outlined above (For // lexer on top of Ben Hanson's lexertl library as outlined above (For
// more information about lexertl go here: // more information about lexertl go here:
// http://www.benhanson.net/lexertl.html). // http://www.benhanson.net/lexertl.html).
// //
// The only difference to the lexer class above is that token_def // The only difference to the lexer class above is that token_def
// definitions may have semantic (lexer) actions attached while being // definitions may have semantic (lexer) actions attached while being
// defined: // defined:
// //
// int w; // int w;
// token_def word = "[^ \t\n]+"; // token_def word = "[^ \t\n]+";
// self = word[++ref(w)]; // see example: word_count_lexer // self = word[++ref(w)]; // see example: word_count_lexer
// //
// This class is supposed to be used as the first and only template // This class is supposed to be used as the first and only template
// parameter while instantiating instances of a lex::lexer class. // parameter while instantiating instances of a lex::lexer class.
// //
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
template <typename Token = token<> template <typename Token = token<>,
, typename Iterator = typename Token::iterator_type typename Iterator = typename Token::iterator_type,
, typename Functor = functor<Token, lexertl::detail::data, Iterator, mpl::true_> > typename Functor =
class actor_lexer : public lexer<Token, Iterator, Functor> functor<Token, lexertl::detail::data, Iterator, mpl::true_> >
{ class actor_lexer : public lexer<Token, Iterator, Functor> {
protected: protected:
// Lexer instances can be created by means of a derived class only. // Lexer instances can be created by means of a derived class only.
actor_lexer(unsigned int flags) actor_lexer(unsigned int flags) : lexer<Token, Iterator, Functor>(flags) {}
: lexer<Token, Iterator, Functor>(flags) {} };
};
}}}} } // namespace lexertl
} // namespace lex
} // namespace spirit
} // namespace boost
#endif #endif

View file

@ -1506,7 +1506,7 @@ bool LocalPlayer::handleMouseClick(int button) {
bool usedItem = false; bool usedItem = false;
if (minecraft->gameMode->useItemOn( if (minecraft->gameMode->useItemOn(
minecraft->localplayers[GetXboxPad()], level, item, x, y, z, minecraft->localplayers[GetXboxPad()], level, item, x, y, z,
face, minecraft->hitResult->pos, false, &usedItem)) { face, &minecraft->hitResult->pos, false, &usedItem)) {
// Presume that if we actually used the held item, then we've // Presume that if we actually used the held item, then we've
// placed it // placed it
if (usedItem) { if (usedItem) {

View file

@ -23,4 +23,4 @@ bool DirtyChunkSorter::operator()(const Chunk* c0, const Chunk* c1) const {
if (d0 > d1) return true; if (d0 > d1) return true;
return c0->id >= c1->id; // 4J - was c0.id < c1.id ? 1 : -1 return c0->id >= c1->id; // 4J - was c0.id < c1.id ? 1 : -1
} }

View file

@ -613,4 +613,4 @@ void LivingEntityRenderer::renderNameTag(std::shared_ptr<LivingEntity> mob,
glDisable(GL_BLEND); glDisable(GL_BLEND);
glColor4f(1, 1, 1, 1); glColor4f(1, 1, 1, 1);
glPopMatrix(); glPopMatrix();
} }

View file

@ -54,10 +54,11 @@ void MinecartRenderer::render(std::shared_ptr<Entity> _cart, double x, double y,
y += (p0->y + p1->y) / 2 - yy; y += (p0->y + p1->y) / 2 - yy;
z += p->z - zz; z += p->z - zz;
Vec3* dir = p1->add(-p0->x, -p0->y, -p0->z); Vec3* dir = Vec3::newTemp(-p0->x, -p0->y, -p0->z);
*dir = dir->add(p1->x, p1->y, p1->z);
if (dir->length() == 0) { if (dir->length() == 0) {
} else { } else {
dir = dir->normalize(); *dir = dir->normalize();
rot = (float)(atan2(dir->z, dir->x) * 180 / PI); rot = (float)(atan2(dir->z, dir->x) * 180 / PI);
xRot = (float)(atan(dir->y) * 73); xRot = (float)(atan(dir->y) * 73);
} }
@ -146,4 +147,4 @@ void MinecartRenderer::renderMinecartContents(std::shared_ptr<Minecart> cart,
glPushMatrix(); glPushMatrix();
renderer->renderTile(tile, tileData, brightness); renderer->renderTile(tile, tileData, brightness);
glPopMatrix(); glPopMatrix();
} }

View file

@ -301,11 +301,12 @@ void GameRenderer::pick(float a) {
} }
if (mc->hitResult != NULL) { if (mc->hitResult != NULL) {
dist = mc->hitResult->pos->distanceTo(from); dist = mc->hitResult->pos.distanceTo(*from);
} }
Vec3* b = mc->cameraTargetPlayer->getViewVector(a); Vec3* b = mc->cameraTargetPlayer->getViewVector(a);
Vec3* to = from->add(b->x * range, b->y * range, b->z * range); Vec3* to = Vec3::newTemp(b->x * range, b->y * range, b->z * range);
*to = to->add(from->x, from->y, from->z);
hovered = nullptr; hovered = nullptr;
float overlap = 1; float overlap = 1;
std::vector<std::shared_ptr<Entity> >* objects = mc->level->getEntities( std::vector<std::shared_ptr<Entity> >* objects = mc->level->getEntities(
@ -527,7 +528,7 @@ void GameRenderer::moveCameraToPlayer(float a) {
Vec3::newTemp(x + xo, y + yo, z + zo), Vec3::newTemp(x + xo, y + yo, z + zo),
Vec3::newTemp(x - xd + xo, y - yd + yo, z - zd + zo)); Vec3::newTemp(x - xd + xo, y - yd + yo, z - zd + zo));
if (hr != NULL) { if (hr != NULL) {
double dist = hr->pos->distanceTo(Vec3::newTemp(x, y, z)); double dist = hr->pos.distanceTo(*Vec3::newTemp(x, y, z));
if (dist < cameraDist) cameraDist = dist; if (dist < cameraDist) cameraDist = dist;
delete hr; delete hr;
} }
@ -1867,7 +1868,7 @@ void GameRenderer::setupClearColor(float a) {
Vec3* sunAngle = Mth::sin(level->getSunAngle(a)) > 0 Vec3* sunAngle = Mth::sin(level->getSunAngle(a)) > 0
? Vec3::newTemp(-1, 0, 0) ? Vec3::newTemp(-1, 0, 0)
: Vec3::newTemp(1, 0, 0); : Vec3::newTemp(1, 0, 0);
float d = (float)player->getViewVector(a)->dot(sunAngle); float d = (float)player->getViewVector(a)->dot(*sunAngle);
if (d < 0) d = 0; if (d < 0) d = 0;
if (d > 0) { if (d > 0) {
float* c = float* c =

View file

@ -22,13 +22,15 @@ void Lighting::turnOn() {
float d = 0.6f; float d = 0.6f;
float s = 0.0f; float s = 0.0f;
Vec3* l = Vec3::newTemp(0.2f, 1.0f, -0.7f)->normalize(); Vec3* l = Vec3::newTemp(0.2f, 1.0f, -0.7f);
*l = l->normalize();
glLight(GL_LIGHT0, GL_POSITION, getBuffer(l->x, l->y, l->z, 0)); glLight(GL_LIGHT0, GL_POSITION, getBuffer(l->x, l->y, l->z, 0));
glLight(GL_LIGHT0, GL_DIFFUSE, getBuffer(d, d, d, 1)); glLight(GL_LIGHT0, GL_DIFFUSE, getBuffer(d, d, d, 1));
glLight(GL_LIGHT0, GL_AMBIENT, getBuffer(0.0f, 0.0f, 0.0f, 1.0f)); glLight(GL_LIGHT0, GL_AMBIENT, getBuffer(0.0f, 0.0f, 0.0f, 1.0f));
glLight(GL_LIGHT0, GL_SPECULAR, getBuffer(s, s, s, 1.0f)); glLight(GL_LIGHT0, GL_SPECULAR, getBuffer(s, s, s, 1.0f));
l = Vec3::newTemp(-0.2f, 1.0f, 0.7f)->normalize(); l = Vec3::newTemp(-0.2f, 1.0f, 0.7f);
*l = l->normalize();
glLight(GL_LIGHT1, GL_POSITION, getBuffer(l->x, l->y, l->z, 0)); glLight(GL_LIGHT1, GL_POSITION, getBuffer(l->x, l->y, l->z, 0));
glLight(GL_LIGHT1, GL_DIFFUSE, getBuffer(d, d, d, 1)); glLight(GL_LIGHT1, GL_DIFFUSE, getBuffer(d, d, d, 1));
glLight(GL_LIGHT1, GL_AMBIENT, getBuffer(0.0f, 0.0f, 0.0f, 1.0f)); glLight(GL_LIGHT1, GL_AMBIENT, getBuffer(0.0f, 0.0f, 0.0f, 1.0f));
@ -55,4 +57,4 @@ void Lighting::turnOnGui() {
glRotatef(165, 1, 0, 0); glRotatef(165, 1, 0, 0);
turnOn(); turnOn();
glPopMatrix(); glPopMatrix();
} }

View file

@ -45,15 +45,15 @@ void _Polygon::mirror() {
} }
void _Polygon::render(Tesselator* t, float scale) { void _Polygon::render(Tesselator* t, float scale) {
Vec3* v0 = vertices[1]->pos->vectorTo(vertices[0]->pos); Vec3 v0 = vertices[1]->pos->vectorTo(*vertices[0]->pos);
Vec3* v1 = vertices[1]->pos->vectorTo(vertices[2]->pos); Vec3 v1 = vertices[1]->pos->vectorTo(*vertices[2]->pos);
Vec3* n = v1->cross(v0)->normalize(); Vec3 n = v1.cross(v0).normalize();
t->begin(); t->begin();
if (_flipNormal) { if (_flipNormal) {
t->normal(-(float)n->x, -(float)n->y, -(float)n->z); t->normal(-(float)n.x, -(float)n.y, -(float)n.z);
} else { } else {
t->normal((float)n->x, (float)n->y, (float)n->z); t->normal((float)n.x, (float)n.y, (float)n.z);
} }
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
@ -67,4 +67,4 @@ void _Polygon::render(Tesselator* t, float scale) {
_Polygon* _Polygon::flipNormal() { _Polygon* _Polygon::flipNormal() {
_flipNormal = true; _flipNormal = true;
return this; return this;
} }

View file

@ -95,4 +95,4 @@ void AvoidPlayerGoal::tick() {
mob->getNavigation()->setSpeedModifier(sprintSpeedModifier); mob->getNavigation()->setSpeedModifier(sprintSpeedModifier);
else else
mob->getNavigation()->setSpeedModifier(walkSpeedModifier); mob->getNavigation()->setSpeedModifier(walkSpeedModifier);
} }

View file

@ -54,4 +54,4 @@ bool BegGoal::playerHoldingInteresting(std::shared_ptr<Player> player) {
if (item == NULL) return false; if (item == NULL) return false;
if (!wolf->isTame() && item->id == Item::bone_Id) return true; if (!wolf->isTame() && item->id == Item::bone_Id) return true;
return wolf->isFood(item); return wolf->isFood(item);
} }

View file

@ -85,4 +85,4 @@ void FollowOwnerGoal::tick() {
} }
} }
} }
} }

View file

@ -34,4 +34,4 @@ void LeapAtTargetGoal::start() {
mob->xd += (xdd / dd * 0.5f) * 0.8f + mob->xd * 0.2f; mob->xd += (xdd / dd * 0.5f) * 0.8f + mob->xd * 0.2f;
mob->zd += (zdd / dd * 0.5f) * 0.8f + mob->zd * 0.2f; mob->zd += (zdd / dd * 0.5f) * 0.8f + mob->zd * 0.2f;
mob->yd = yd; mob->yd = yd;
} }

View file

@ -62,4 +62,4 @@ void LookAtPlayerGoal::tick() {
lookAt.lock()->x, lookAt.lock()->y + lookAt.lock()->getHeadHeight(), lookAt.lock()->x, lookAt.lock()->y + lookAt.lock()->getHeadHeight(),
lookAt.lock()->z, 10, mob->getMaxHeadXRot()); lookAt.lock()->z, 10, mob->getMaxHeadXRot());
--lookTime; --lookTime;
} }

View file

@ -68,4 +68,4 @@ void MoveIndoorsGoal::stop() {
insideX = _doorInfo->getIndoorX(); insideX = _doorInfo->getIndoorX();
insideZ = _doorInfo->getIndoorZ(); insideZ = _doorInfo->getIndoorZ();
doorInfo = std::weak_ptr<DoorInfo>(); doorInfo = std::weak_ptr<DoorInfo>();
} }

View file

@ -41,4 +41,4 @@ void MoveTowardsTargetGoal::stop() { target = std::weak_ptr<Mob>(); }
void MoveTowardsTargetGoal::start() { void MoveTowardsTargetGoal::start() {
mob->getNavigation()->moveTo(wantedX, wantedY, wantedZ, speedModifier); mob->getNavigation()->moveTo(wantedX, wantedY, wantedZ, speedModifier);
} }

View file

@ -74,4 +74,4 @@ bool NearestAttackableTargetGoal::canUse() {
void NearestAttackableTargetGoal::start() { void NearestAttackableTargetGoal::start() {
mob->setTarget(target.lock()); mob->setTarget(target.lock());
TargetGoal::start(); TargetGoal::start();
} }

View file

@ -57,4 +57,4 @@ void OcelotAttackGoal::tick() {
if (attackTime > 0) return; if (attackTime > 0) return;
attackTime = 20; attackTime = 20;
mob->doHurtTarget(target.lock()); mob->doHurtTarget(target.lock());
} }

View file

@ -38,4 +38,4 @@ void SitGoal::start() {
void SitGoal::stop() { mob->setSitting(false); } void SitGoal::stop() { mob->setSitting(false); }
void SitGoal::wantToSit(bool _wantToSit) { this->_wantToSit = _wantToSit; } void SitGoal::wantToSit(bool _wantToSit) { this->_wantToSit = _wantToSit; }

View file

@ -72,4 +72,4 @@ void TakeFlowerGoal::tick() {
villager->getNavigation()->stop(); villager->getNavigation()->stop();
} }
} }
} }

View file

@ -115,4 +115,4 @@ bool TargetGoal::canReach(std::shared_ptr<LivingEntity> target) {
int zz = last->z - Mth::floor(target->z); int zz = last->z - Mth::floor(target->z);
delete path; delete path;
return xx * xx + zz * zz <= 1.5 * 1.5; return xx * xx + zz * zz <= 1.5 * 1.5;
} }

View file

@ -84,4 +84,4 @@ void TemptGoal::tick() {
mob->getNavigation()->moveTo(player.lock(), speedModifier); mob->getNavigation()->moveTo(player.lock(), speedModifier);
} }
bool TemptGoal::isRunning() { return _isRunning; } bool TemptGoal::isRunning() { return _isRunning; }

View file

@ -38,4 +38,4 @@ bool TradeWithPlayerGoal::canUse() {
void TradeWithPlayerGoal::start() { mob->getNavigation()->stop(); } void TradeWithPlayerGoal::start() { mob->getNavigation()->stop(); }
void TradeWithPlayerGoal::stop() { mob->setTradingPlayer(nullptr); } void TradeWithPlayerGoal::stop() { mob->setTradingPlayer(nullptr); }

View file

@ -283,4 +283,4 @@ Path* PathFinder::reconstruct_path(Node* from, Node* to) {
Path* ret = new Path(nodes); Path* ret = new Path(nodes);
delete[] nodes.data; delete[] nodes.data;
return ret; return ret;
} }

View file

@ -151,7 +151,7 @@ void PathNavigation::updatePath() {
float waypointRadiusSqr = mob->bbWidth * mob->bbWidth; float waypointRadiusSqr = mob->bbWidth * mob->bbWidth;
for (int i = path->getIndex(); i < firstElevation; ++i) { for (int i = path->getIndex(); i < firstElevation; ++i) {
Vec3* pathPos = path->getPos(mob->shared_from_this(), i); Vec3* pathPos = path->getPos(mob->shared_from_this(), i);
if (mobPos->distanceToSqr(pathPos) < waypointRadiusSqr) { if (mobPos->distanceToSqr(*pathPos) < waypointRadiusSqr) {
path->setIndex(i + 1); path->setIndex(i + 1);
} }
} }
@ -170,7 +170,7 @@ void PathNavigation::updatePath() {
// stuck detection (probably pushed off path) // stuck detection (probably pushed off path)
if (_tick - lastStuckCheck > 100) { if (_tick - lastStuckCheck > 100) {
if (mobPos->distanceToSqr(lastStuckCheckPos) < 1.5 * 1.5) stop(); if (mobPos->distanceToSqr(*lastStuckCheckPos) < 1.5 * 1.5) stop();
lastStuckCheck = _tick; lastStuckCheck = _tick;
lastStuckCheckPos->x = mobPos->x; lastStuckCheckPos->x = mobPos->x;
lastStuckCheckPos->y = mobPos->y; lastStuckCheckPos->y = mobPos->y;
@ -329,4 +329,4 @@ bool PathNavigation::canWalkAbove(int startX, int startY, int startZ, int sx,
return true; return true;
} }
void PathNavigation::setLevel(Level* level) { this->level = level; } void PathNavigation::setLevel(Level* level) { this->level = level; }

View file

@ -135,14 +135,14 @@ Vec3* LiquidTile::getFlow(LevelSource* level, int x, int y, int z) {
t = getRenderedDepth(level, xt, yt - 1, zt); t = getRenderedDepth(level, xt, yt - 1, zt);
if (t >= 0) { if (t >= 0) {
int dir = t - (mid - 8); int dir = t - (mid - 8);
flow = flow->add((xt - x) * dir, (yt - y) * dir, *flow = flow->add((xt - x) * dir, (yt - y) * dir,
(zt - z) * dir); (zt - z) * dir);
} }
} }
} else { } else {
if (t >= 0) { if (t >= 0) {
int dir = t - mid; int dir = t - mid;
flow = *flow =
flow->add((xt - x) * dir, (yt - y) * dir, (zt - z) * dir); flow->add((xt - x) * dir, (yt - y) * dir, (zt - z) * dir);
} }
} }
@ -157,9 +157,9 @@ Vec3* LiquidTile::getFlow(LevelSource* level, int x, int y, int z) {
if (ok || isSolidFace(level, x, y + 1, z + 1, 3)) ok = true; if (ok || isSolidFace(level, x, y + 1, z + 1, 3)) ok = true;
if (ok || isSolidFace(level, x - 1, y + 1, z, 4)) ok = true; if (ok || isSolidFace(level, x - 1, y + 1, z, 4)) ok = true;
if (ok || isSolidFace(level, x + 1, y + 1, z, 5)) ok = true; if (ok || isSolidFace(level, x + 1, y + 1, z, 5)) ok = true;
if (ok) flow = flow->normalize()->add(0, -6, 0); if (ok) *flow = flow->normalize().add(0, -6, 0);
} }
flow = flow->normalize(); *flow = flow->normalize();
return flow; return flow;
} }

View file

@ -443,7 +443,7 @@ HitResult* StairTile::clip(Level* level, int xt, int yt, int zt, Vec3* a,
for (unsigned int i = 0; i < 8; ++i) { for (unsigned int i = 0; i < 8; ++i) {
HitResult* result = results[i]; HitResult* result = results[i];
if (result != NULL) { if (result != NULL) {
double dist = result->pos->distanceToSqr(b); double dist = result->pos.distanceToSqr(*b);
if (dist > closestDist) { if (dist > closestDist) {
closest = result; closest = result;

View file

@ -15,6 +15,7 @@
#include "../Headers/net.minecraft.world.food.h" #include "../Headers/net.minecraft.world.food.h"
#include "../Headers/net.minecraft.world.h" #include "../Headers/net.minecraft.world.h"
#include "../Headers/net.minecraft.h" #include "../Headers/net.minecraft.h"
#include "Util/Vec3.h"
#include "Tile.h" #include "Tile.h"
std::wstring Tile::TILE_DESCRIPTION_PREFIX = L"Tile."; std::wstring Tile::TILE_DESCRIPTION_PREFIX = L"Tile.";
@ -2120,52 +2121,65 @@ float Tile::getExplosionResistance(std::shared_ptr<Entity> source) {
HitResult* Tile::clip(Level* level, int xt, int yt, int zt, Vec3* a, Vec3* b) { HitResult* Tile::clip(Level* level, int xt, int yt, int zt, Vec3* a, Vec3* b) {
updateShape(level, xt, yt, zt); updateShape(level, xt, yt, zt);
a = a->add(-xt, -yt, -zt); *a = a->add(-xt, -yt, -zt);
b = b->add(-xt, -yt, -zt); *b = b->add(-xt, -yt, -zt);
ThreadStorage* tls = m_tlsShape; ThreadStorage* tls = m_tlsShape;
Vec3* xh0 = a->clipX(b, tls->xx0); auto xh0 = a->clipX(*b, tls->xx0);
Vec3* xh1 = a->clipX(b, tls->xx1); auto xh1 = a->clipX(*b, tls->xx1);
Vec3* yh0 = a->clipY(b, tls->yy0); auto yh0 = a->clipY(*b, tls->yy0);
Vec3* yh1 = a->clipY(b, tls->yy1); auto yh1 = a->clipY(*b, tls->yy1);
Vec3* zh0 = a->clipZ(b, tls->zz0); auto zh0 = a->clipZ(*b, tls->zz0);
Vec3* zh1 = a->clipZ(b, tls->zz1); auto zh1 = a->clipZ(*b, tls->zz1);
Vec3* closest = NULL; Vec3* closest = nullptr;
if (containsX(xh0) && if (xh0.has_value() and containsX(&*xh0) and
(closest == NULL || a->distanceToSqr(xh0) < a->distanceToSqr(closest))) (closest == nullptr or
closest = xh0; a->distanceToSqr(*xh0) < a->distanceToSqr(*closest)))
if (containsX(xh1) && *closest = *xh0;
(closest == NULL || a->distanceToSqr(xh1) < a->distanceToSqr(closest)))
closest = xh1; if (xh1.has_value() and containsX(&*xh1) and
if (containsY(yh0) && (closest == nullptr or
(closest == NULL || a->distanceToSqr(yh0) < a->distanceToSqr(closest))) a->distanceToSqr(*xh1) < a->distanceToSqr(*closest)))
closest = yh0; *closest = *xh1;
if (containsY(yh1) &&
(closest == NULL || a->distanceToSqr(yh1) < a->distanceToSqr(closest))) if (yh0.has_value() and containsY(&*yh0) and
closest = yh1; (closest == nullptr or
if (containsZ(zh0) && a->distanceToSqr(*yh0) < a->distanceToSqr(*closest)))
(closest == NULL || a->distanceToSqr(zh0) < a->distanceToSqr(closest))) *closest = *yh0;
closest = zh0;
if (containsZ(zh1) && if (yh1.has_value() and containsY(&*yh1) and
(closest == NULL || a->distanceToSqr(zh1) < a->distanceToSqr(closest))) (closest == nullptr or
closest = zh1; a->distanceToSqr(*yh1) < a->distanceToSqr(*closest)))
*closest = *yh1;
if (zh0.has_value() and containsZ(&*zh0) and
(closest == nullptr or
a->distanceToSqr(*zh0) < a->distanceToSqr(*closest)))
*closest = *zh0;
if (zh1.has_value() and containsZ(&*zh1) and
(closest == nullptr or
a->distanceToSqr(*zh1) < a->distanceToSqr(*closest)))
*closest = *zh1;
if (closest == NULL) return NULL; if (closest == NULL) return NULL;
int face = -1; int face = -1;
if (closest == xh0) face = Facing::WEST; if (*closest == xh0) face = Facing::WEST;
if (closest == xh1) face = Facing::EAST; if (*closest == xh1) face = Facing::EAST;
if (closest == yh0) face = Facing::DOWN; if (*closest == yh0) face = Facing::DOWN;
if (closest == yh1) face = Facing::UP; if (*closest == yh1) face = Facing::UP;
if (closest == zh0) face = Facing::NORTH; if (*closest == zh0) face = Facing::NORTH;
if (closest == zh1) face = Facing::SOUTH; if (*closest == zh1) face = Facing::SOUTH;
return new HitResult(xt, yt, zt, face, closest->add(xt, yt, zt)); *closest = closest->add(xt, yt, zt);
return new HitResult(xt, yt, zt, face, *closest);
} }
bool Tile::containsX(Vec3* v) { bool Tile::containsX(Vec3* v) {

View file

@ -113,4 +113,4 @@ void HorseInventoryMenu::removed(std::shared_ptr<Player> player) {
std::shared_ptr<Container> HorseInventoryMenu::getContainer() { std::shared_ptr<Container> HorseInventoryMenu::getContainer() {
return horseContainer; return horseContainer;
} }

View file

@ -1874,4 +1874,4 @@ unsigned int Entity::getAnimOverrideBitmask() {
} }
return m_uiAnimOverrideBitmask; return m_uiAnimOverrideBitmask;
} }

View file

@ -424,6 +424,7 @@ private:
static int extraWanderTicks; static int extraWanderTicks;
static thread_local bool m_tlsUseSmallIds; static thread_local bool m_tlsUseSmallIds;
public: public:
static void tickExtraWandering(); static void tickExtraWandering();
static void countFlagsForPIX(); static void countFlagsForPIX();

View file

@ -31,6 +31,7 @@
#include "../Util/ParticleTypes.h" #include "../Util/ParticleTypes.h"
#include "../Stats/GenericStats.h" #include "../Stats/GenericStats.h"
#include "ItemEntity.h" #include "ItemEntity.h"
#include "Util/Vec3.h"
const double LivingEntity::MIN_MOVEMENT_DISTANCE = 0.005; const double LivingEntity::MIN_MOVEMENT_DISTANCE = 0.005;
@ -800,7 +801,7 @@ void LivingEntity::breakItem(std::shared_ptr<ItemInstance> itemInstance) {
-random->nextFloat() * 0.6 - 0.3, 0.6); -random->nextFloat() * 0.6 - 0.3, 0.6);
p->xRot(-xRot * PI / 180); p->xRot(-xRot * PI / 180);
p->yRot(-yRot * PI / 180); p->yRot(-yRot * PI / 180);
p = p->add(x, y + getHeadHeight(), z); *p = p->add(x, y + getHeadHeight(), z);
level->addParticle(PARTICLE_ICONCRACK(itemInstance->getItem()->id, 0), level->addParticle(PARTICLE_ICONCRACK(itemInstance->getItem()->id, 0),
p->x, p->y, p->z, d->x, d->y + 0.05, d->z); p->x, p->y, p->z, d->x, d->y + 0.05, d->z);
} }
@ -1691,7 +1692,8 @@ Vec3* LivingEntity::getPos(float a) {
HitResult* LivingEntity::pick(double range, float a) { HitResult* LivingEntity::pick(double range, float a) {
Vec3* from = getPos(a); Vec3* from = getPos(a);
Vec3* b = getViewVector(a); Vec3* b = getViewVector(a);
Vec3* to = from->add(b->x * range, b->y * range, b->z * range); Vec3* to = Vec3::newTemp(b->x * range, b->y * range, b->z * range);
*to = to->add(from->x, from->y, from->z);
return level->clip(from, to); return level->clip(from, to);
} }

View file

@ -210,4 +210,4 @@ void MinecartContainer::applyNaturalSlowdown() {
xd *= keep; xd *= keep;
yd *= 0; yd *= 0;
zd *= keep; zd *= keep;
} }

View file

@ -224,7 +224,7 @@ void Arrow::tick() {
from = Vec3::newTemp(x, y, z); from = Vec3::newTemp(x, y, z);
to = Vec3::newTemp(x + xd, y + yd, z + zd); to = Vec3::newTemp(x + xd, y + yd, z + zd);
if (res != NULL) { if (res != NULL) {
to = Vec3::newTemp(res->pos->x, res->pos->y, res->pos->z); to = Vec3::newTemp(res->pos.x, res->pos.y, res->pos.z);
} }
std::shared_ptr<Entity> hitEntity = nullptr; std::shared_ptr<Entity> hitEntity = nullptr;
std::vector<std::shared_ptr<Entity> >* objects = level->getEntities( std::vector<std::shared_ptr<Entity> >* objects = level->getEntities(
@ -359,9 +359,9 @@ void Arrow::tick() {
zTile = res->z; zTile = res->z;
lastTile = level->getTile(xTile, yTile, zTile); lastTile = level->getTile(xTile, yTile, zTile);
lastData = level->getData(xTile, yTile, zTile); lastData = level->getData(xTile, yTile, zTile);
xd = (float)(res->pos->x - x); xd = (float)(res->pos.x - x);
yd = (float)(res->pos->y - y); yd = (float)(res->pos.y - y);
zd = (float)(res->pos->z - z); zd = (float)(res->pos.z - z);
float dd = (float)sqrt(xd * xd + yd * yd + zd * zd); float dd = (float)sqrt(xd * xd + yd * yd + zd * zd);
// 4J added check - zero dd here was creating NaNs // 4J added check - zero dd here was creating NaNs
if (dd > 0.0001f) { if (dd > 0.0001f) {

View file

@ -67,4 +67,4 @@ ePARTICLE_TYPE DragonFireball::getTrailParticleType() {
return eParticleType_dragonbreath; return eParticleType_dragonbreath;
} }
bool DragonFireball::shouldBurn() { return false; } bool DragonFireball::shouldBurn() { return false; }

View file

@ -314,7 +314,8 @@ void EnderDragon::aiStep() {
// v->y, v->z, lSteps); unsigned int d = 0; for(unsigned int d = 1; // v->y, v->z, lSteps); unsigned int d = 0; for(unsigned int d = 1;
// d < 3; ++d) // d < 3; ++d)
{ {
Vec3* vN = v->normalize(); Vec3* vN = Vec3::newTemp(v->x, v->y, v->z);
*vN = v->normalize();
vN->yRot(-PI / 4); vN->yRot(-PI / 4);
for (unsigned int i = 0; i < 8; ++i) { for (unsigned int i = 0; i < 8; ++i) {
if (getSynchedAction() == e_EnderdragonAction_Landing) { if (getSynchedAction() == e_EnderdragonAction_Landing) {
@ -478,12 +479,14 @@ void EnderDragon::aiStep() {
} else if (getSynchedAction() == e_EnderdragonAction_Sitting_Scanning) { } else if (getSynchedAction() == e_EnderdragonAction_Sitting_Scanning) {
if (attackTarget != NULL) { if (attackTarget != NULL) {
Vec3* aim = Vec3::newTemp((attackTarget->x - x), 0, Vec3* aim = Vec3::newTemp((attackTarget->x - x), 0,
(attackTarget->z - z)) (attackTarget->z - z));
->normalize(); *aim = aim->normalize();
Vec3* dir = Vec3::newTemp(sin(yRot * PI / 180), 0, Vec3* dir = Vec3::newTemp(sin(yRot * PI / 180), 0,
-cos(yRot * PI / 180)) -cos(yRot * PI / 180));
->normalize();
float dot = (float)dir->dot(aim); *dir = dir->normalize();
float dot = (float)dir->dot(*aim);
float angleDegs = acos(dot) * 180 / PI; float angleDegs = acos(dot) * 180 / PI;
angleDegs = angleDegs + 0.5f; angleDegs = angleDegs + 0.5f;
@ -562,12 +565,13 @@ void EnderDragon::aiStep() {
if (yRotD < -50) yRotD = -50; if (yRotD < -50) yRotD = -50;
Vec3* aim = Vec3* aim =
Vec3::newTemp((xTarget - x), (yTarget - y), (zTarget - z)) Vec3::newTemp((xTarget - x), (yTarget - y), (zTarget - z));
->normalize(); *aim = aim->normalize();
Vec3* dir = Vec3* dir =
Vec3::newTemp(sin(yRot * PI / 180), yd, -cos(yRot * PI / 180)) Vec3::newTemp(sin(yRot * PI / 180), yd, -cos(yRot * PI / 180));
->normalize(); *dir = dir->normalize();
float dot = (float)(dir->dot(aim) + 0.5f) / 1.5f; float dot = (float)(dir->dot(*aim) + 0.5f) / 1.5f;
if (dot < 0) dot = 0; if (dot < 0) dot = 0;
yRotA *= 0.80f; yRotA *= 0.80f;
@ -591,8 +595,9 @@ void EnderDragon::aiStep() {
move(xd, yd, zd); move(xd, yd, zd);
} }
Vec3* actual = Vec3::newTemp(xd, yd, zd)->normalize(); Vec3* actual = Vec3::newTemp(xd, yd, zd);
float slide = (float)(actual->dot(dir) + 1) / 2.0f; *actual = actual->normalize();
float slide = (float)(actual->dot(*dir) + 1) / 2.0f;
slide = 0.8f + 0.15f * slide; slide = 0.8f + 0.15f * slide;
xd *= slide; xd *= slide;
@ -734,12 +739,14 @@ void EnderDragon::aiStep() {
if (this->canSee(attackTarget)) { if (this->canSee(attackTarget)) {
m_fireballCharge++; m_fireballCharge++;
Vec3* aim = Vec3::newTemp((attackTarget->x - x), 0, Vec3* aim = Vec3::newTemp((attackTarget->x - x), 0,
(attackTarget->z - z)) (attackTarget->z - z));
->normalize(); *aim = aim->normalize();
Vec3* dir = Vec3::newTemp(sin(yRot * PI / 180), 0, Vec3* dir = Vec3::newTemp(sin(yRot * PI / 180), 0,
-cos(yRot * PI / 180)) -cos(yRot * PI / 180));
->normalize(); *dir = dir->normalize();
float dot = (float)dir->dot(aim);
float dot = (float)dir->dot(*aim);
float angleDegs = acos(dot) * 180 / PI; float angleDegs = acos(dot) * 180 / PI;
angleDegs = angleDegs + 0.5f; angleDegs = angleDegs + 0.5f;
@ -979,8 +986,8 @@ void EnderDragon::findNewTarget() {
int targetNodeIndex = 0; int targetNodeIndex = 0;
if (playerNearestToEgg != NULL) { if (playerNearestToEgg != NULL) {
Vec3* aim = Vec3::newTemp(playerNearestToEgg->x, 0, Vec3* aim = Vec3::newTemp(playerNearestToEgg->x, 0,
playerNearestToEgg->z) playerNearestToEgg->z);
->normalize(); *aim = aim->normalize();
// app.DebugPrintf("Final marker node near (%f,%d,%f)\n", // app.DebugPrintf("Final marker node near (%f,%d,%f)\n",
// -aim->x*40,105,-aim->z*40 ); // -aim->x*40,105,-aim->z*40 );
targetNodeIndex = targetNodeIndex =

View file

@ -114,14 +114,16 @@ bool EnderMan::isLookingAtMe(std::shared_ptr<Player> player) {
std::shared_ptr<ItemInstance> helmet = player->inventory->armor[3]; std::shared_ptr<ItemInstance> helmet = player->inventory->armor[3];
if (helmet != NULL && helmet->id == Tile::pumpkin_Id) return false; if (helmet != NULL && helmet->id == Tile::pumpkin_Id) return false;
Vec3* look = player->getViewVector(1)->normalize(); Vec3* look = player->getViewVector(1);
*look = look->normalize();
Vec3* dir = Vec3::newTemp( Vec3* dir = Vec3::newTemp(
x - player->x, x - player->x,
(bb->y0 + bbHeight / 2) - (player->y + player->getHeadHeight()), (bb->y0 + bbHeight / 2) - (player->y + player->getHeadHeight()),
z - player->z); z - player->z);
double dist = dir->length(); double dist = dir->length();
dir = dir->normalize(); *dir = dir->normalize();
double dot = look->dot(dir); double dot = look->dot(*dir);
if (dot > 1 - 0.025 / dist) { if (dot > 1 - 0.025 / dist) {
return player->canSee(shared_from_this()); return player->canSee(shared_from_this());
} }
@ -251,7 +253,7 @@ bool EnderMan::teleport() {
bool EnderMan::teleportTowards(std::shared_ptr<Entity> e) { bool EnderMan::teleportTowards(std::shared_ptr<Entity> e) {
Vec3* dir = Vec3::newTemp( Vec3* dir = Vec3::newTemp(
x - e->x, bb->y0 + bbHeight / 2 - e->y + e->getHeadHeight(), z - e->z); x - e->x, bb->y0 + bbHeight / 2 - e->y + e->getHeadHeight(), z - e->z);
dir = dir->normalize(); *dir = dir->normalize();
double d = 16; double d = 16;
double xx = x + (random->nextDouble() - 0.5) * 8 - dir->x * d; double xx = x + (random->nextDouble() - 0.5) * 8 - dir->x * d;
double yy = y + (random->nextInt(16) - 8) - dir->y * d; double yy = y + (random->nextInt(16) - 8) - dir->y * d;
@ -378,4 +380,4 @@ bool EnderMan::isCreepy() { return entityData->getByte(DATA_CREEPY) > 0; }
void EnderMan::setCreepy(bool creepy) { void EnderMan::setCreepy(bool creepy) {
entityData->set(DATA_CREEPY, (uint8_t)(creepy ? 1 : 0)); entityData->set(DATA_CREEPY, (uint8_t)(creepy ? 1 : 0));
} }

View file

@ -265,4 +265,4 @@ bool ExperienceOrb::shouldRender(Vec3* c) {
if (distance < 4) return false; if (distance < 4) return false;
return Entity::shouldRender(c); return Entity::shouldRender(c);
} }

View file

@ -173,7 +173,7 @@ void Fireball::tick() {
from = Vec3::newTemp(x, y, z); from = Vec3::newTemp(x, y, z);
to = Vec3::newTemp(x + xd, y + yd, z + zd); to = Vec3::newTemp(x + xd, y + yd, z + zd);
if (res != NULL) { if (res != NULL) {
to = Vec3::newTemp(res->pos->x, res->pos->y, res->pos->z); *to = Vec3{res->pos.x, res->pos.y, res->pos.z};
} }
std::shared_ptr<Entity> hitEntity = nullptr; std::shared_ptr<Entity> hitEntity = nullptr;
std::vector<std::shared_ptr<Entity> >* objects = level->getEntities( std::vector<std::shared_ptr<Entity> >* objects = level->getEntities(
@ -326,4 +326,4 @@ int Fireball::getLightColor(float a) { return 15 << 20 | 15 << 4; }
ePARTICLE_TYPE Fireball::getTrailParticleType() { return eParticleType_smoke; } ePARTICLE_TYPE Fireball::getTrailParticleType() { return eParticleType_smoke; }
bool Fireball::shouldBurn() { return true; } bool Fireball::shouldBurn() { return true; }

View file

@ -210,7 +210,7 @@ void FishingHook::tick() {
from = Vec3::newTemp(x, y, z); from = Vec3::newTemp(x, y, z);
to = Vec3::newTemp(x + xd, y + yd, z + zd); to = Vec3::newTemp(x + xd, y + yd, z + zd);
if (res != NULL) { if (res != NULL) {
to = Vec3::newTemp(res->pos->x, res->pos->y, res->pos->z); to = Vec3::newTemp(res->pos.x, res->pos.y, res->pos.z);
} }
std::shared_ptr<Entity> hitEntity = nullptr; std::shared_ptr<Entity> hitEntity = nullptr;
std::vector<std::shared_ptr<Entity> >* objects = level->getEntities( std::vector<std::shared_ptr<Entity> >* objects = level->getEntities(
@ -412,4 +412,4 @@ int FishingHook::retrieve() {
void FishingHook::remove() { void FishingHook::remove() {
Entity::remove(); Entity::remove();
if (owner != NULL) owner->fishing = nullptr; if (owner != NULL) owner->fishing = nullptr;
} }

View file

@ -217,4 +217,4 @@ void Ghast::readAdditionalSaveData(CompoundTag* tag) {
FlyingMob::readAdditionalSaveData(tag); FlyingMob::readAdditionalSaveData(tag);
if (tag->contains(L"ExplosionPower")) if (tag->contains(L"ExplosionPower"))
explosionPower = tag->getInt(L"ExplosionPower"); explosionPower = tag->getInt(L"ExplosionPower");
} }

View file

@ -129,10 +129,9 @@ bool Minecart::hurt(DamageSource* source, float hurtDamage) {
if (dynamic_cast<EntityDamageSource*>(source) != NULL) { if (dynamic_cast<EntityDamageSource*>(source) != NULL) {
std::shared_ptr<Entity> attacker = source->getDirectEntity(); std::shared_ptr<Entity> attacker = source->getDirectEntity();
if (attacker->instanceof if (attacker->instanceof(eTYPE_PLAYER) &&
(eTYPE_PLAYER) && !std::dynamic_pointer_cast<Player>(attacker)->isAllowedToHurtEntity(
!std::dynamic_pointer_cast<Player>(attacker) shared_from_this())) {
->isAllowedToHurtEntity(shared_from_this())) {
return false; return false;
} }
} }
@ -149,9 +148,9 @@ bool Minecart::hurt(DamageSource* source, float hurtDamage) {
if (rider.lock() != NULL && rider.lock() == source->getEntity()) if (rider.lock() != NULL && rider.lock() == source->getEntity())
hurtDamage += 1; hurtDamage += 1;
bool creativePlayer = bool creativePlayer = source->getEntity() != NULL &&
source->getEntity() != NULL && source->getEntity()->instanceof source->getEntity()->instanceof(eTYPE_PLAYER) &&
(eTYPE_PLAYER) && std::dynamic_pointer_cast<Player>(source->getEntity()) std::dynamic_pointer_cast<Player>(source->getEntity())
->abilities.instabuild; ->abilities.instabuild;
if (creativePlayer || getDamage() > 20 * 2) { if (creativePlayer || getDamage() > 20 * 2) {
@ -310,8 +309,8 @@ void Minecart::tick() {
AUTO_VAR(itEnd, entities->end()); AUTO_VAR(itEnd, entities->end());
for (AUTO_VAR(it, entities->begin()); it != itEnd; it++) { for (AUTO_VAR(it, entities->begin()); it != itEnd; it++) {
std::shared_ptr<Entity> e = (*it); // entities->at(i); std::shared_ptr<Entity> e = (*it); // entities->at(i);
if (e != rider.lock() && e->isPushable() && e->instanceof if (e != rider.lock() && e->isPushable() &&
(eTYPE_MINECART)) { e->instanceof(eTYPE_MINECART)) {
std::shared_ptr<Minecart> cart = std::shared_ptr<Minecart> cart =
std::dynamic_pointer_cast<Minecart>(e); std::dynamic_pointer_cast<Minecart>(e);
cart->m_bHasPushedCartThisTick = false; cart->m_bHasPushedCartThisTick = false;
@ -405,7 +404,7 @@ void Minecart::moveAlongTrack(int xt, int yt, int zt, double maxSpeed,
xd = pow * xD / dd; xd = pow * xD / dd;
zd = pow * zD / dd; zd = pow * zD / dd;
if (rider.lock() != NULL && rider.lock()->instanceof (eTYPE_LIVINGENTITY)) { if (rider.lock() != NULL && rider.lock()->instanceof(eTYPE_LIVINGENTITY)) {
std::shared_ptr<LivingEntity> living = std::shared_ptr<LivingEntity> living =
std::dynamic_pointer_cast<LivingEntity>(rider.lock()); std::dynamic_pointer_cast<LivingEntity>(rider.lock());
@ -689,10 +688,9 @@ void Minecart::push(std::shared_ptr<Entity> e) {
if (level->isClientSide) return; if (level->isClientSide) return;
if (e == rider.lock()) return; if (e == rider.lock()) return;
if (e->instanceof (eTYPE_LIVINGENTITY) && !e->instanceof if (e->instanceof(eTYPE_LIVINGENTITY) && !e->instanceof(eTYPE_PLAYER) &&
(eTYPE_PLAYER) && !e->instanceof !e->instanceof(eTYPE_VILLAGERGOLEM) && (getType() == TYPE_RIDEABLE) &&
(eTYPE_VILLAGERGOLEM) && (getType() == TYPE_RIDEABLE) && (xd * xd + zd * zd > 0.01)) {
(xd * xd + zd * zd > 0.01)) {
if ((rider.lock() == NULL) && (e->riding == NULL)) { if ((rider.lock() == NULL) && (e->riding == NULL)) {
e->ride(shared_from_this()); e->ride(shared_from_this());
} }
@ -718,7 +716,7 @@ void Minecart::push(std::shared_ptr<Entity> e) {
xa *= 0.5; xa *= 0.5;
za *= 0.5; za *= 0.5;
if (e->instanceof (eTYPE_MINECART)) { if (e->instanceof(eTYPE_MINECART)) {
double xo = e->x - x; double xo = e->x - x;
double zo = e->z - z; double zo = e->z - z;
@ -726,12 +724,13 @@ void Minecart::push(std::shared_ptr<Entity> e) {
// other // other
// Fix for #38882 - TU5: Gameplay: Minecart with furnace is not // Fix for #38882 - TU5: Gameplay: Minecart with furnace is not
// able to move another minecart on the rail. // able to move another minecart on the rail.
Vec3* dir = Vec3::newTemp(xo, 0, zo)->normalize(); Vec3* dir = Vec3::newTemp(xo, 0, zo);
*dir = dir->normalize();
Vec3* facing = Vec3* facing =
Vec3::newTemp(cos(yRot * PI / 180), 0, sin(yRot * PI / 180)) Vec3::newTemp(cos(yRot * PI / 180), 0, sin(yRot * PI / 180));
->normalize(); *facing = facing->normalize();
double dot = abs(dir->dot(facing)); double dot = abs(dir->dot(*facing));
if (dot < 0.8f) { if (dot < 0.8f) {
return; return;

View file

@ -305,4 +305,4 @@ void Ocelot::setSittingOnTile(bool val) {
bool Ocelot::isSittingOnTile() { bool Ocelot::isSittingOnTile() {
uint8_t current = entityData->getByte(DATA_FLAGS_ID); uint8_t current = entityData->getByte(DATA_FLAGS_ID);
return (current & 0x02) > 0; return (current & 0x02) > 0;
} }

View file

@ -248,4 +248,4 @@ int Slime::getMaxHeadXRot() { return 0; }
bool Slime::doPlayJumpSound() { return getSize() > 0; } bool Slime::doPlayJumpSound() { return getSize() > 0; }
bool Slime::doPlayLandSound() { return getSize() > 2; } bool Slime::doPlayLandSound() { return getSize() > 2; }

View file

@ -151,4 +151,4 @@ void ThrownPotion::addAdditonalSaveData(CompoundTag* tag) {
if (potionItem != NULL) if (potionItem != NULL)
tag->putCompound(L"Potion", potionItem->save(new CompoundTag())); tag->putCompound(L"Potion", potionItem->save(new CompoundTag()));
} }

View file

@ -212,4 +212,4 @@ void Witch::performRangedAttack(std::shared_ptr<LivingEntity> target,
potion->shoot(xd, yd + dist * 0.2f, zd, 0.75f, 8); potion->shoot(xd, yd + dist * 0.2f, zd, 0.75f, 8);
level->addEntity(potion); level->addEntity(potion);
} }

View file

@ -506,4 +506,4 @@ bool WitherBoss::isPowered() { return getHealth() <= getMaxHealth() / 2; }
MobType WitherBoss::getMobType() { return UNDEAD; } MobType WitherBoss::getMobType() { return UNDEAD; }
void WitherBoss::ride(std::shared_ptr<Entity> e) { riding = nullptr; } void WitherBoss::ride(std::shared_ptr<Entity> e) { riding = nullptr; }

View file

@ -328,4 +328,4 @@ void PathfinderMob::onLeashDistance(float distanceToLeashHolder) {}
bool PathfinderMob::couldWander() { bool PathfinderMob::couldWander() {
return (noActionTime < SharedConstants::TICKS_PER_SECOND * 5) || return (noActionTime < SharedConstants::TICKS_PER_SECOND * 5) ||
(isExtraWanderingEnabled()); (isExtraWanderingEnabled());
} }

View file

@ -142,7 +142,7 @@ void Throwable::tick() {
from = Vec3::newTemp(x, y, z); from = Vec3::newTemp(x, y, z);
to = Vec3::newTemp(x + xd, y + yd, z + zd); to = Vec3::newTemp(x + xd, y + yd, z + zd);
if (res != NULL) { if (res != NULL) {
to = Vec3::newTemp(res->pos->x, res->pos->y, res->pos->z); to = Vec3::newTemp(res->pos.x, res->pos.y, res->pos.z);
} }
if (!level->isClientSide) { if (!level->isClientSide) {
@ -256,4 +256,4 @@ std::shared_ptr<LivingEntity> Throwable::getOwner() {
owner = level->getPlayerByName(ownerName); owner = level->getPlayerByName(ownerName);
} }
return owner; return owner;
} }

View file

@ -5,6 +5,7 @@
#include "../Headers/net.minecraft.world.level.tile.h" #include "../Headers/net.minecraft.world.level.tile.h"
#include "../Headers/net.minecraft.world.phys.h" #include "../Headers/net.minecraft.world.phys.h"
#include "ItemInstance.h" #include "ItemInstance.h"
#include "Util/Vec3.h"
#include "BoatItem.h" #include "BoatItem.h"
BoatItem::BoatItem(int id) : Item(id) { maxStackSize = 1; } BoatItem::BoatItem(int id) : Item(id) { maxStackSize = 1; }
@ -36,7 +37,8 @@ bool BoatItem::TestUse(std::shared_ptr<ItemInstance> itemInstance, Level* level,
float za = yCos * xCos; float za = yCos * xCos;
double range = 5; double range = 5;
Vec3* to = from->add(xa * range, ya * range, za * range); Vec3* to = Vec3::newTemp(xa * range, ya * range, za * range);
*to = to->add(from->x, from->y, from->z);
HitResult* hr = level->clip(from, to, true); HitResult* hr = level->clip(from, to, true);
if (hr == NULL) return false; if (hr == NULL) return false;
@ -72,7 +74,8 @@ std::shared_ptr<ItemInstance> BoatItem::use(
float za = yCos * xCos; float za = yCos * xCos;
double range = 5; double range = 5;
Vec3* to = from->add(xa * range, ya * range, za * range); Vec3* to = Vec3::newTemp(xa * range, ya * range, za * range);
*to = to->add(from->x, from->y, from->z);
HitResult* hr = level->clip(from, to, true); HitResult* hr = level->clip(from, to, true);
if (hr == NULL) return itemInstance; if (hr == NULL) return itemInstance;
@ -131,4 +134,4 @@ std::shared_ptr<ItemInstance> BoatItem::use(
delete hr; delete hr;
return itemInstance; return itemInstance;
} }

View file

@ -15,6 +15,7 @@
#include "Item.h" #include "Item.h"
#include "HangingEntityItem.h" #include "HangingEntityItem.h"
#include "../Util/HtmlString.h" #include "../Util/HtmlString.h"
#include "Util/Vec3.h"
typedef Item::Tier _Tier; typedef Item::Tier _Tier;
@ -1614,7 +1615,8 @@ HitResult* Item::getPlayerPOVHitResult(Level* level,
float za = yCos * xCos; float za = yCos * xCos;
double range = 5; double range = 5;
Vec3* to = from->add(xa * range, ya * range, za * range); Vec3* to = Vec3::newTemp(xa * range, ya * range, za * range);
*to = to->add(from->x, from->y, from->z);
return level->clip(from, to, alsoPickLiquid, !alsoPickLiquid); return level->clip(from, to, alsoPickLiquid, !alsoPickLiquid);
} }

View file

@ -44,4 +44,4 @@ struct ChunkPosKeyEq {
bool operator()(const ChunkPos& x, const ChunkPos& y) const { bool operator()(const ChunkPos& x, const ChunkPos& y) const {
return ChunkPos::eq_test(x, y); return ChunkPos::eq_test(x, y);
} }
}; };

View file

@ -2490,7 +2490,7 @@ bool Level::checkAndHandleWater(AABB* box, Material* material,
} }
} }
if (current->length() > 0 && e->isPushedByWater()) { if (current->length() > 0 && e->isPushedByWater()) {
current = current->normalize(); *current = current->normalize();
double pow = 0.014; double pow = 0.014;
e->xd += current->x * pow; e->xd += current->x * pow;
e->yd += current->y * pow; e->yd += current->y * pow;

View file

@ -121,9 +121,9 @@ int RandomLevelSource::getMinDistanceToEdge(int xxx, int zzz, int worldSize,
(xxx > (max - falloffStart) && xxx < (max + falloffStart))) { (xxx > (max - falloffStart) && xxx < (max + falloffStart))) {
Vec3* point = Vec3::newTemp(xxx, 0, zzz); Vec3* point = Vec3::newTemp(xxx, 0, zzz);
if (xxx > 0) if (xxx > 0)
dist = point->distanceFromLine(topRight, bottomRight); dist = point->distanceFromLine(*topRight, *bottomRight);
else else
dist = point->distanceFromLine(topLeft, bottomLeft); dist = point->distanceFromLine(*topLeft, *bottomLeft);
closest = dist; closest = dist;
} }
@ -132,9 +132,9 @@ int RandomLevelSource::getMinDistanceToEdge(int xxx, int zzz, int worldSize,
(zzz > (max - falloffStart) && zzz < (max + falloffStart))) { (zzz > (max - falloffStart) && zzz < (max + falloffStart))) {
Vec3* point = Vec3::newTemp(xxx, 0, zzz); Vec3* point = Vec3::newTemp(xxx, 0, zzz);
if (zzz > 0) if (zzz > 0)
dist = point->distanceFromLine(bottomLeft, bottomRight); dist = point->distanceFromLine(*bottomLeft, *bottomRight);
else else
dist = point->distanceFromLine(topLeft, topRight); dist = point->distanceFromLine(*topLeft, *topRight);
if (dist < closest) closest = dist; if (dist < closest) closest = dist;
} }

View file

@ -435,7 +435,7 @@ void Player::tick() {
// minecart. For some reason some of the torches come off so it will also need some fixing along the way. // minecart. For some reason some of the torches come off so it will also need some fixing along the way.
static bool madeTrack = false; static bool madeTrack = false;
if( !madeTrack ) if( !madeTrack )
{ {
this->drop( std::shared_ptr<ItemInstance>( new ItemInstance( Item::minecart, 1 ) ) ); this->drop( std::shared_ptr<ItemInstance>( new ItemInstance( Item::minecart, 1 ) ) );
this->drop( std::shared_ptr<ItemInstance>( new ItemInstance( Tile::goldenRail, 10 ) ) ); this->drop( std::shared_ptr<ItemInstance>( new ItemInstance( Tile::goldenRail, 10 ) ) );
this->drop( std::shared_ptr<ItemInstance>( new ItemInstance( Tile::lever, 10 ) ) ); this->drop( std::shared_ptr<ItemInstance>( new ItemInstance( Tile::lever, 10 ) ) );
@ -537,7 +537,7 @@ void Player::spawnEatParticles(std::shared_ptr<ItemInstance> useItem,
-random->nextFloat() * 0.6 - 0.3, 0.6); -random->nextFloat() * 0.6 - 0.3, 0.6);
p->xRot(-xRot * PI / 180); p->xRot(-xRot * PI / 180);
p->yRot(-yRot * PI / 180); p->yRot(-yRot * PI / 180);
p = p->add(x, y + getHeadHeight(), z); *p = p->add(x, y + getHeadHeight(), z);
level->addParticle(PARTICLE_ICONCRACK(useItem->getItem()->id, 0), level->addParticle(PARTICLE_ICONCRACK(useItem->getItem()->id, 0),
p->x, p->y, p->z, d->x, d->y + 0.05, d->z); p->x, p->y, p->z, d->x, d->y + 0.05, d->z);

View file

@ -5,7 +5,9 @@
#include "../Platform/stdafx.h" #include "../Platform/stdafx.h"
#include "AABB.h" #include "AABB.h"
#include <optional>
#include "HitResult.h" #include "HitResult.h"
#include "Util/Vec3.h"
unsigned int AABB::tlsIdx = 0; unsigned int AABB::tlsIdx = 0;
AABB::ThreadStorage* AABB::tlsDefault = NULL; AABB::ThreadStorage* AABB::tlsDefault = NULL;
@ -238,55 +240,62 @@ AABB* AABB::shrink(double xa, double ya, double za) {
AABB* AABB::copy() { return AABB::newTemp(x0, y0, z0, x1, y1, z1); } AABB* AABB::copy() { return AABB::newTemp(x0, y0, z0, x1, y1, z1); }
HitResult* AABB::clip(Vec3* a, Vec3* b) { HitResult* AABB::clip(Vec3* a, Vec3* b) {
Vec3* xh0 = a->clipX(b, x0); auto xh0 = a->clipX(*b, x0);
Vec3* xh1 = a->clipX(b, x1); auto xh1 = a->clipX(*b, x1);
Vec3* yh0 = a->clipY(b, y0); auto yh0 = a->clipY(*b, y0);
Vec3* yh1 = a->clipY(b, y1); auto yh1 = a->clipY(*b, y1);
Vec3* zh0 = a->clipZ(b, z0); auto zh0 = a->clipZ(*b, z0);
Vec3* zh1 = a->clipZ(b, z1); auto zh1 = a->clipZ(*b, z1);
if (!containsX(xh0)) xh0 = NULL; if (!(xh0.has_value() and containsX(&*xh0))) xh0 = std::nullopt;
if (!containsX(xh1)) xh1 = NULL; if (!(xh1.has_value() and containsX(&*xh1))) xh1 = std::nullopt;
if (!containsY(yh0)) yh0 = NULL; if (!(yh0.has_value() and containsY(&*yh0))) yh0 = std::nullopt;
if (!containsY(yh1)) yh1 = NULL; if (!(yh1.has_value() and containsY(&*yh1))) yh1 = std::nullopt;
if (!containsZ(zh0)) zh0 = NULL; if (!(zh0.has_value() and containsZ(&*zh0))) zh0 = std::nullopt;
if (!containsZ(zh1)) zh1 = NULL; if (!(zh1.has_value() and containsZ(&*zh1))) zh1 = std::nullopt;
Vec3* closest = nullptr;
Vec3* closest = NULL; if (xh0.has_value() and
(closest == nullptr or
a->distanceToSqr(*xh0) < a->distanceToSqr(*closest)))
*closest = *xh0;
if (xh1.has_value() and
(closest == nullptr or
a->distanceToSqr(*xh1) < a->distanceToSqr(*closest)))
*closest = *xh1;
if (yh0.has_value() and
(closest == nullptr or
a->distanceToSqr(*yh0) < a->distanceToSqr(*closest)))
*closest = *yh0;
if (yh1.has_value() and
(closest == nullptr or
a->distanceToSqr(*yh1) < a->distanceToSqr(*closest)))
*closest = *yh1;
if (zh0.has_value() and
(closest == nullptr or
a->distanceToSqr(*zh0) < a->distanceToSqr(*closest)))
*closest = *zh0;
if (zh1.has_value() and
(closest == nullptr or
a->distanceToSqr(*zh1) < a->distanceToSqr(*closest)))
*closest = *zh1;
if (xh0 != NULL && if (closest == nullptr) return nullptr;
(closest == NULL || a->distanceToSqr(xh0) < a->distanceToSqr(closest)))
closest = xh0;
if (xh1 != NULL &&
(closest == NULL || a->distanceToSqr(xh1) < a->distanceToSqr(closest)))
closest = xh1;
if (yh0 != NULL &&
(closest == NULL || a->distanceToSqr(yh0) < a->distanceToSqr(closest)))
closest = yh0;
if (yh1 != NULL &&
(closest == NULL || a->distanceToSqr(yh1) < a->distanceToSqr(closest)))
closest = yh1;
if (zh0 != NULL &&
(closest == NULL || a->distanceToSqr(zh0) < a->distanceToSqr(closest)))
closest = zh0;
if (zh1 != NULL &&
(closest == NULL || a->distanceToSqr(zh1) < a->distanceToSqr(closest)))
closest = zh1;
if (closest == NULL) return NULL;
int face = -1; int face = -1;
if (closest == xh0) face = 4; if (*closest == xh0) face = 4;
if (closest == xh1) face = 5; if (*closest == xh1) face = 5;
if (closest == yh0) face = 0; if (*closest == yh0) face = 0;
if (closest == yh1) face = 1; if (*closest == yh1) face = 1;
if (closest == zh0) face = 2; if (*closest == zh0) face = 2;
if (closest == zh1) face = 3; if (*closest == zh1) face = 3;
return new HitResult(0, 0, 0, face, closest); closest = Vec3::newTemp(closest->x, closest->y, closest->z);
return new HitResult(0, 0, 0, face, *closest);
} }
bool AABB::containsX(Vec3* v) { bool AABB::containsX(Vec3* v) {

View file

@ -3,13 +3,13 @@
#include "../Headers/net.minecraft.world.entity.h" #include "../Headers/net.minecraft.world.entity.h"
#include "HitResult.h" #include "HitResult.h"
HitResult::HitResult(int x, int y, int z, int f, Vec3* pos) { HitResult::HitResult(int x, int y, int z, int f, const Vec3& pos) {
type = TILE; type = TILE;
this->x = x; this->x = x;
this->y = y; this->y = y;
this->z = z; this->z = z;
this->f = f; this->f = f;
this->pos = Vec3::newTemp(pos->x, pos->y, pos->z); this->pos = pos;
this->entity = nullptr; this->entity = nullptr;
} }
@ -17,14 +17,14 @@ HitResult::HitResult(int x, int y, int z, int f, Vec3* pos) {
HitResult::HitResult(std::shared_ptr<Entity> entity) { HitResult::HitResult(std::shared_ptr<Entity> entity) {
type = ENTITY; type = ENTITY;
this->entity = entity; this->entity = entity;
pos = Vec3::newTemp(entity->x, entity->y, entity->z); pos = {entity->x, entity->y, entity->z};
x = y = z = f = 0; x = y = z = f = 0;
} }
double HitResult::distanceTo(std::shared_ptr<Entity> e) { double HitResult::distanceTo(std::shared_ptr<Entity> e) {
double xd = pos->x - e->x; double xd = pos.x - e->x;
double yd = pos->y - e->y; double yd = pos.y - e->y;
double zd = pos->z - e->z; double zd = pos.z - e->z;
return xd * xd + yd * yd + zd * zd; return xd * xd + yd * yd + zd * zd;
} }

View file

@ -7,12 +7,12 @@ public:
Type type; Type type;
int x, y, z, f; int x, y, z, f;
Vec3* pos; Vec3 pos;
std::shared_ptr<Entity> entity; std::shared_ptr<Entity> entity;
HitResult(int x, int y, int z, int f, Vec3* pos); HitResult(int x, int y, int z, int f, const Vec3& pos);
HitResult(std::shared_ptr<Entity> entity); HitResult(std::shared_ptr<Entity> entity);
double distanceTo(std::shared_ptr<Entity> e); double distanceTo(std::shared_ptr<Entity> e);
}; };

View file

@ -1,5 +1,7 @@
#include "../Platform/stdafx.h" #include "../Platform/stdafx.h"
#include "Vec3.h" #include "Vec3.h"
#include <format>
#include <optional>
#include "AABB.h" #include "AABB.h"
unsigned int Vec3::tlsIdx = 0; unsigned int Vec3::tlsIdx = 0;
@ -62,108 +64,99 @@ Vec3* Vec3::set(double x, double y, double z) {
return this; return this;
} }
Vec3* Vec3::interpolateTo(Vec3* t, double p) { Vec3 Vec3::vectorTo(const Vec3& p) const { return {p.x - x, p.y - y, p.z - z}; }
double xt = x + (t->x - x) * p;
double yt = y + (t->y - y) * p;
double zt = z + (t->z - z) * p;
return Vec3::newTemp(xt, yt, zt); Vec3 Vec3::normalize() const {
double dist = std::sqrt(x * x + y * y + z * z);
if (dist < 0.0001) return {0, 0, 0};
return {x / dist, y / dist, z / dist};
} }
Vec3* Vec3::vectorTo(Vec3* p) { double Vec3::dot(const Vec3& p) const { return x * p.x + y * p.y + z * p.z; }
return Vec3::newTemp(p->x - x, p->y - y, p->z - z);
Vec3 Vec3::cross(const Vec3& p) const {
return {y * p.z - z * p.y, z * p.x - x * p.z, x * p.y - y * p.x};
} }
Vec3* Vec3::normalize() { Vec3 Vec3::add(double x, double y, double z) const {
double dist = (double)(sqrt(x * x + y * y + z * z)); return {this->x + x, this->y + y, this->z + z};
if (dist < 0.0001) return Vec3::newTemp(0, 0, 0);
return Vec3::newTemp(x / dist, y / dist, z / dist);
} }
double Vec3::dot(Vec3* p) { return x * p->x + y * p->y + z * p->z; } double Vec3::distanceTo(const Vec3& p) const {
double xd = p.x - x;
Vec3* Vec3::cross(Vec3* p) { double yd = p.y - y;
return Vec3::newTemp(y * p->z - z * p->y, z * p->x - x * p->z, double zd = p.z - z;
x * p->y - y * p->x); return std::sqrt(xd * xd + yd * yd + zd * zd);
} }
Vec3* Vec3::add(double x, double y, double z) { double Vec3::distanceToSqr(const Vec3& p) {
return Vec3::newTemp(this->x + x, this->y + y, this->z + z); double xd = p.x - x;
} double yd = p.y - y;
double zd = p.z - z;
double Vec3::distanceTo(Vec3* p) {
double xd = p->x - x;
double yd = p->y - y;
double zd = p->z - z;
return (double)sqrt(xd * xd + yd * yd + zd * zd);
}
double Vec3::distanceToSqr(Vec3* p) {
double xd = p->x - x;
double yd = p->y - y;
double zd = p->z - z;
return xd * xd + yd * yd + zd * zd; return xd * xd + yd * yd + zd * zd;
} }
double Vec3::distanceToSqr(double x2, double y2, double z2) { double Vec3::distanceToSqr(const double x2, const double y2,
const double z2) const {
double xd = x2 - x; double xd = x2 - x;
double yd = y2 - y; double yd = y2 - y;
double zd = z2 - z; double zd = z2 - z;
return xd * xd + yd * yd + zd * zd; return xd * xd + yd * yd + zd * zd;
} }
Vec3* Vec3::scale(double l) { return Vec3::newTemp(x * l, y * l, z * l); } Vec3 Vec3::scale(const double l) const { return {x * l, y * l, z * l}; }
double Vec3::length() { return sqrt(x * x + y * y + z * z); } double Vec3::length() const { return sqrt(x * x + y * y + z * z); }
Vec3* Vec3::clipX(Vec3* b, double xt) { std::optional<Vec3> Vec3::clipX(const Vec3& b, const double xt) const {
double xd = b->x - x; double xd = b.x - x;
double yd = b->y - y; double yd = b.y - y;
double zd = b->z - z; double zd = b.z - z;
if (xd * xd < 0.0000001f) return NULL; if (xd * xd < 0.0000001f) return std::nullopt;
double d = (xt - x) / xd; double d = (xt - x) / xd;
if (d < 0 || d > 1) return NULL; if (d < 0 || d > 1) return std::nullopt;
return Vec3::newTemp(x + xd * d, y + yd * d, z + zd * d);
return Vec3{x + xd * d, y + yd * d, z + zd * d};
} }
Vec3* Vec3::clipY(Vec3* b, double yt) { std::optional<Vec3> Vec3::clipY(const Vec3& b, const double yt) const {
double xd = b->x - x; double xd = b.x - x;
double yd = b->y - y; double yd = b.y - y;
double zd = b->z - z; double zd = b.z - z;
if (yd * yd < 0.0000001f) return NULL; if (yd * yd < 0.0000001f) return std::nullopt;
double d = (yt - y) / yd; double d = (yt - y) / yd;
if (d < 0 || d > 1) return NULL; if (d < 0 || d > 1) return std::nullopt;
return Vec3::newTemp(x + xd * d, y + yd * d, z + zd * d);
return Vec3{x + xd * d, y + yd * d, z + zd * d};
} }
Vec3* Vec3::clipZ(Vec3* b, double zt) { std::optional<Vec3> Vec3::clipZ(const Vec3& b, const double zt) const {
double xd = b->x - x; double xd = b.x - x;
double yd = b->y - y; double yd = b.y - y;
double zd = b->z - z; double zd = b.z - z;
if (zd * zd < 0.0000001f) return NULL; if (zd * zd < 0.0000001f) return std::nullopt;
double d = (zt - z) / zd; double d = (zt - z) / zd;
if (d < 0 || d > 1) return NULL; if (d < 0 || d > 1) return std::nullopt;
return Vec3::newTemp(x + xd * d, y + yd * d, z + zd * d);
return Vec3{x + xd * d, y + yd * d, z + zd * d};
} }
std::wstring Vec3::toString() { std::wstring Vec3::toString() const {
static wchar_t buf[128]; return std::format(L"({},{},{})", x, y, z);
swprintf(buf, 128, L"(%f,%f,%f)", x, y, z);
return std::wstring(buf);
} }
Vec3* Vec3::lerp(Vec3* v, double a) { Vec3 Vec3::lerp(const Vec3& v, const double a) const {
return Vec3::newTemp(x + (v->x - x) * a, y + (v->y - y) * a, return {x + (v.x - x) * a, y + (v.y - y) * a, z + (v.z - z) * a};
z + (v->z - z) * a);
} }
void Vec3::xRot(float degs) { void Vec3::xRot(const float degs) {
double _cos = cos(degs); // 4J - cos/sin were floats but seems pointless double _cos = cos(degs); // 4J - cos/sin were floats but seems pointless
// wasting precision here // wasting precision here
double _sin = sin(degs); double _sin = sin(degs);
@ -177,7 +170,7 @@ void Vec3::xRot(float degs) {
z = zz; z = zz;
} }
void Vec3::yRot(float degs) { void Vec3::yRot(const float degs) {
double _cos = cos(degs); // 4J - cos/sin were floats but seems pointless double _cos = cos(degs); // 4J - cos/sin were floats but seems pointless
// wasting precision here // wasting precision here
double _sin = sin(degs); double _sin = sin(degs);
@ -191,7 +184,7 @@ void Vec3::yRot(float degs) {
z = zz; z = zz;
} }
void Vec3::zRot(float degs) { void Vec3::zRot(const float degs) {
double _cos = cos(degs); // 4J - cos/sin were floats but seems pointless double _cos = cos(degs); // 4J - cos/sin were floats but seems pointless
// wasting precision here // wasting precision here
double _sin = sin(degs); double _sin = sin(degs);
@ -230,23 +223,24 @@ double Vec3::distanceTo(AABB* box) {
return sqrt(xd * xd + yd * yd + zd * zd); return sqrt(xd * xd + yd * yd + zd * zd);
} }
Vec3* Vec3::closestPointOnLine(Vec3* p1, Vec3* p2) { Vec3 Vec3::closestPointOnLine(const Vec3& p1, const Vec3& p2) const {
Vec3* diff = newTemp(x - p1->x, y - p1->y, z - p1->z); Vec3 diff = {x - p1.x, y - p1.y, z - p1.z};
Vec3* dir = newTemp(p2->x - p1->x, p2->y - p1->y, p2->z - p1->z); Vec3 dir = {p2.x - p1.x, p2.y - p1.y, p2.z - p1.z};
float dot1 = diff->dot(dir); float dot1 = diff.dot(dir);
if (dot1 <= 0.0f) return p1; if (dot1 <= 0.0f) return p1;
float dot2 = dir->dot(dir); float dot2 = dir.dot(dir);
if (dot2 <= dot1) return p2; if (dot2 <= dot1) return p2;
float t = dot1 / dot2; float t = dot1 / dot2;
return newTemp(p1->x + t * dir->x, p1->y + t * dir->y, p1->z + t * dir->z);
return {p1.x + t * dir.x, p1.y + t * dir.y, p1.z + t * dir.z};
} }
double Vec3::distanceFromLine(Vec3* p1, Vec3* p2) { double Vec3::distanceFromLine(const Vec3& p1, const Vec3& p2) const {
Vec3* closestPoint = closestPointOnLine(p1, p2); Vec3 closestPoint = closestPointOnLine(p1, p2);
Vec3* diff = Vec3 diff{x - closestPoint.x, y - closestPoint.y, z - closestPoint.z};
newTemp(x - closestPoint->x, y - closestPoint->y, z - closestPoint->z); return diff.length();
return diff->length();
} }

View file

@ -1,5 +1,6 @@
#pragma once #pragma once
#include <optional>
class AABB; class AABB;
class Vec3 { class Vec3 {
@ -29,28 +30,28 @@ public:
static Vec3* newTemp(double x, double y, double z); static Vec3* newTemp(double x, double y, double z);
double x, y, z; double x, y, z;
private:
Vec3() {} Vec3() {}
Vec3(double x, double y, double z); Vec3(double x, double y, double z);
private:
Vec3* set(double x, double y, double z); Vec3* set(double x, double y, double z);
public: public:
Vec3* interpolateTo(Vec3* t, double p); Vec3 vectorTo(const Vec3& p) const;
Vec3* vectorTo(Vec3* p); Vec3 normalize() const;
Vec3* normalize(); double dot(const Vec3& p) const;
double dot(Vec3* p); Vec3 cross(const Vec3& p) const;
Vec3* cross(Vec3* p); Vec3 add(double x, double y, double z) const;
Vec3* add(double x, double y, double z); double distanceTo(const Vec3& p) const;
double distanceTo(Vec3* p); double distanceToSqr(const Vec3& p);
double distanceToSqr(Vec3* p); double distanceToSqr(double x2, double y2, double z2) const;
double distanceToSqr(double x2, double y2, double z2); Vec3 scale(double l) const;
Vec3* scale(double l); double length() const;
double length(); std::optional<Vec3> clipX(const Vec3& b, double xt) const;
Vec3* clipX(Vec3* b, double xt); std::optional<Vec3> clipY(const Vec3& b, double yt) const;
Vec3* clipY(Vec3* b, double yt); std::optional<Vec3> clipZ(const Vec3& b, double zt) const;
Vec3* clipZ(Vec3* b, double zt); std::wstring toString() const;
std::wstring toString(); Vec3 lerp(const Vec3& v, double a) const;
Vec3* lerp(Vec3* v, double a);
void xRot(float degs); void xRot(float degs);
void yRot(float degs); void yRot(float degs);
void zRot(float degs); void zRot(float degs);
@ -58,6 +59,10 @@ public:
// 4J Added // 4J Added
double distanceTo(AABB* box); double distanceTo(AABB* box);
Vec3* closestPointOnLine(Vec3* p1, Vec3* p2); Vec3 closestPointOnLine(const Vec3& p1, const Vec3& p2) const;
double distanceFromLine(Vec3* p1, Vec3* p2); double distanceFromLine(const Vec3& p1, const Vec3& p2) const;
};
constexpr bool operator==(const Vec3& rhs) const {
return x == rhs.x and y == rhs.y and z == rhs.z;
}
};