Replace ItemCallbacks with lambdas (#3993)
This commit is contained in:
parent
115bc5609a
commit
e225b7f826
@ -379,7 +379,7 @@ cLuaState::cStackTable::cStackTable(cLuaState & a_LuaState, int a_StackPos):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cLuaState::cStackTable::ForEachArrayElement(std::function<bool(cLuaState & a_LuaState, int a_Index)> a_ElementCallback) const
|
void cLuaState::cStackTable::ForEachArrayElement(cFunctionRef<bool(cLuaState & a_LuaState, int a_Index)> a_ElementCallback) const
|
||||||
{
|
{
|
||||||
auto numElements = luaL_getn(m_LuaState, m_StackPos);
|
auto numElements = luaL_getn(m_LuaState, m_StackPos);
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
@ -404,7 +404,7 @@ void cLuaState::cStackTable::ForEachArrayElement(std::function<bool(cLuaState &
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cLuaState::cStackTable::ForEachElement(std::function<bool(cLuaState & a_LuaState)> a_ElementCallback) const
|
void cLuaState::cStackTable::ForEachElement(cFunctionRef<bool(cLuaState & a_LuaState)> a_ElementCallback) const
|
||||||
{
|
{
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
auto stackTop = lua_gettop(m_LuaState);
|
auto stackTop = lua_gettop(m_LuaState);
|
||||||
|
@ -39,6 +39,7 @@ extern "C"
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
#include "../Defines.h"
|
#include "../Defines.h"
|
||||||
|
#include "../FunctionRef.h"
|
||||||
#include "PluginManager.h"
|
#include "PluginManager.h"
|
||||||
#include "LuaState_Typedefs.inc"
|
#include "LuaState_Typedefs.inc"
|
||||||
|
|
||||||
@ -521,14 +522,14 @@ public:
|
|||||||
The callback receives the LuaState in which the table resides, and the element's index. The LuaState has
|
The callback receives the LuaState in which the table resides, and the element's index. The LuaState has
|
||||||
the element on top of its stack. If the callback returns true, the iteration is aborted, if it returns
|
the element on top of its stack. If the callback returns true, the iteration is aborted, if it returns
|
||||||
false, the iteration continues with the next element. */
|
false, the iteration continues with the next element. */
|
||||||
void ForEachArrayElement(std::function<bool(cLuaState & a_LuaState, int a_Index)> a_ElementCallback) const;
|
void ForEachArrayElement(cFunctionRef<bool(cLuaState & a_LuaState, int a_Index)> a_ElementCallback) const;
|
||||||
|
|
||||||
/** Iterates over all dictionary elements in the table in random order, and calls the a_ElementCallback for
|
/** Iterates over all dictionary elements in the table in random order, and calls the a_ElementCallback for
|
||||||
each of them.
|
each of them.
|
||||||
The callback receives the LuaState in which the table reside. The LuaState has the element on top of its
|
The callback receives the LuaState in which the table reside. The LuaState has the element on top of its
|
||||||
stack, and the element's key just below it. If the callback returns true, the iteration is aborted, if it
|
stack, and the element's key just below it. If the callback returns true, the iteration is aborted, if it
|
||||||
returns false, the iteration continues with the next element. */
|
returns false, the iteration continues with the next element. */
|
||||||
void ForEachElement(std::function<bool(cLuaState & a_LuaState)> a_ElementCallback) const;
|
void ForEachElement(cFunctionRef<bool(cLuaState & a_LuaState)> a_ElementCallback) const;
|
||||||
|
|
||||||
cLuaState & GetLuaState(void) const { return m_LuaState; }
|
cLuaState & GetLuaState(void) const { return m_LuaState; }
|
||||||
|
|
||||||
|
@ -54,22 +54,15 @@ cLuaWindow::~cLuaWindow()
|
|||||||
m_Contents.RemoveListener(*this);
|
m_Contents.RemoveListener(*this);
|
||||||
|
|
||||||
// Close open lua window from players, to avoid dangling pointers
|
// Close open lua window from players, to avoid dangling pointers
|
||||||
class cPlayerCallback : public cPlayerListCallback
|
cRoot::Get()->ForEachPlayer([this](cPlayer & a_Player)
|
||||||
{
|
|
||||||
virtual bool Item(cPlayer * a_Player)
|
|
||||||
{
|
{
|
||||||
if (a_Player->GetWindow() == m_LuaWindow)
|
if (a_Player.GetWindow() == this)
|
||||||
{
|
{
|
||||||
a_Player->CloseWindow(false);
|
a_Player.CloseWindow(false);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
cLuaWindow * m_LuaWindow;
|
);
|
||||||
public:
|
|
||||||
cPlayerCallback(cLuaWindow & a_LuaWindow) { m_LuaWindow = &a_LuaWindow; }
|
|
||||||
} PlayerCallback(*this);
|
|
||||||
|
|
||||||
cRoot::Get()->ForEachPlayer(PlayerCallback);
|
|
||||||
|
|
||||||
// Must delete slot areas now, because they are referencing this->m_Contents and would try to access it in cWindow's
|
// Must delete slot areas now, because they are referencing this->m_Contents and would try to access it in cWindow's
|
||||||
// destructor, when the member is already gone.
|
// destructor, when the member is already gone.
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
|
|
||||||
class cPlayer;
|
class cPlayer;
|
||||||
typedef cItemCallback<cPlayer> cPlayerListCallback;
|
typedef cFunctionRef<bool(cPlayer &)> cPlayerListCallback;
|
||||||
|
|
||||||
|
|
||||||
/** A window that has been created by a Lua plugin and is handled entirely by that plugin
|
/** A window that has been created by a Lua plugin and is handled entirely by that plugin
|
||||||
|
@ -1483,44 +1483,29 @@ static int tolua_cPluginManager_CallPlugin(lua_State * tolua_S)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Call the destination plugin using a plugin callback:
|
// Call the destination plugin using a plugin callback:
|
||||||
class cCallback :
|
int NumReturns = 0;
|
||||||
public cPluginManager::cPluginCallback
|
auto PluginCallback = [&](cPlugin & a_Plugin)
|
||||||
{
|
|
||||||
public:
|
|
||||||
int m_NumReturns;
|
|
||||||
|
|
||||||
cCallback(const AString & a_FunctionName, cLuaState & a_SrcLuaState) :
|
|
||||||
m_NumReturns(0),
|
|
||||||
m_FunctionName(a_FunctionName),
|
|
||||||
m_SrcLuaState(a_SrcLuaState)
|
|
||||||
{
|
{
|
||||||
}
|
if (!a_Plugin.IsLoaded())
|
||||||
protected:
|
|
||||||
const AString & m_FunctionName;
|
|
||||||
cLuaState & m_SrcLuaState;
|
|
||||||
|
|
||||||
virtual bool Item(cPlugin * a_Plugin) override
|
|
||||||
{
|
|
||||||
if (!a_Plugin->IsLoaded())
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_NumReturns = static_cast<cPluginLua *>(a_Plugin)->CallFunctionFromForeignState(
|
NumReturns = static_cast<cPluginLua &>(a_Plugin).CallFunctionFromForeignState(
|
||||||
m_FunctionName, m_SrcLuaState, 4, lua_gettop(m_SrcLuaState)
|
FunctionName, L, 4, lua_gettop(L)
|
||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
}
|
};
|
||||||
} Callback(FunctionName, L);
|
|
||||||
if (!cPluginManager::Get()->DoWithPlugin(PluginName, Callback))
|
if (!cPluginManager::Get()->DoWithPlugin(PluginName, PluginCallback))
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (Callback.m_NumReturns < 0)
|
if (NumReturns < 0)
|
||||||
{
|
{
|
||||||
// The call has failed, there are zero return values. Do NOT return negative number (Lua considers that a "yield")
|
// The call has failed, there are zero return values. Do NOT return negative number (Lua considers that a "yield")
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return Callback.m_NumReturns;
|
return NumReturns;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3243,42 +3228,29 @@ static int tolua_cRoot_DoWithPlayerByUUID(lua_State * tolua_S)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
class cCallback :
|
|
||||||
public cPlayerListCallback
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
cCallback(cLuaState & a_LuaState) :
|
|
||||||
m_LuaState(a_LuaState)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool Item(cPlayer * a_Player) override
|
|
||||||
{
|
|
||||||
bool ret = false;
|
|
||||||
m_LuaState.Call(m_FnRef, a_Player, cLuaState::Return, ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
cLuaState & m_LuaState;
|
|
||||||
cLuaState::cRef m_FnRef;
|
|
||||||
} Callback(L);
|
|
||||||
|
|
||||||
// Get parameters:
|
// Get parameters:
|
||||||
cRoot * Self;
|
cRoot * Self;
|
||||||
cUUID PlayerUUID;
|
cUUID PlayerUUID;
|
||||||
L.GetStackValues(1, Self, PlayerUUID, Callback.m_FnRef);
|
cLuaState::cRef FnRef;
|
||||||
|
L.GetStackValues(1, Self, PlayerUUID, FnRef);
|
||||||
|
|
||||||
if (PlayerUUID.IsNil())
|
if (PlayerUUID.IsNil())
|
||||||
{
|
{
|
||||||
return L.ApiParamError("Expected a non-nil UUID for parameter #1");
|
return L.ApiParamError("Expected a non-nil UUID for parameter #1");
|
||||||
}
|
}
|
||||||
if (!Callback.m_FnRef.IsValid())
|
if (!FnRef.IsValid())
|
||||||
{
|
{
|
||||||
return L.ApiParamError("Expected a valid callback function for parameter #2");
|
return L.ApiParamError("Expected a valid callback function for parameter #2");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call the function:
|
// Call the function:
|
||||||
bool res = Self->DoWithPlayerByUUID(PlayerUUID, Callback);
|
bool res = Self->DoWithPlayerByUUID(PlayerUUID, [&](cPlayer & a_Player)
|
||||||
|
{
|
||||||
|
bool ret = false;
|
||||||
|
L.Call(FnRef, &a_Player, cLuaState::Return, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// Push the result as the return value:
|
// Push the result as the return value:
|
||||||
L.Push(res);
|
L.Push(res);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
|
|
||||||
// ManualBindings.h
|
// ManualBindings.h
|
||||||
|
|
||||||
// Declares the cManualBindings class used as a namespace for functions exported to the Lua API manually
|
// Declares the cManualBindings class used as a namespace for functions exported to the Lua API manually
|
||||||
@ -57,7 +57,7 @@ public:
|
|||||||
template <
|
template <
|
||||||
class Ty1,
|
class Ty1,
|
||||||
class Ty2,
|
class Ty2,
|
||||||
bool (Ty1::*DoWithFn)(const AString &, cItemCallback<Ty2> &)
|
bool (Ty1::*DoWithFn)(const AString &, cFunctionRef<bool(Ty2 &)>)
|
||||||
>
|
>
|
||||||
static int DoWith(lua_State * tolua_S)
|
static int DoWith(lua_State * tolua_S)
|
||||||
{
|
{
|
||||||
@ -89,28 +89,14 @@ public:
|
|||||||
return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a valid callback function for parameter #2");
|
return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a valid callback function for parameter #2");
|
||||||
}
|
}
|
||||||
|
|
||||||
class cLuaCallback : public cItemCallback<Ty2>
|
// Call the DoWith function:
|
||||||
{
|
bool res = (Self->*DoWithFn)(ItemName, [&](Ty2 & a_Item)
|
||||||
public:
|
|
||||||
cLuaCallback(cLuaState & a_LuaState, cLuaState::cRef & a_FnRef):
|
|
||||||
m_LuaState(a_LuaState),
|
|
||||||
m_FnRef(a_FnRef)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
virtual bool Item(Ty2 * a_Item) override
|
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
m_LuaState.Call(m_FnRef, a_Item, cLuaState::Return, ret);
|
L.Call(FnRef, &a_Item, cLuaState::Return, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
cLuaState & m_LuaState;
|
);
|
||||||
cLuaState::cRef & m_FnRef;
|
|
||||||
} Callback(L, FnRef);
|
|
||||||
|
|
||||||
// Call the DoWith function:
|
|
||||||
bool res = (Self->*DoWithFn)(ItemName, Callback);
|
|
||||||
|
|
||||||
// Push the result as the return value:
|
// Push the result as the return value:
|
||||||
L.Push(res);
|
L.Push(res);
|
||||||
@ -125,7 +111,7 @@ public:
|
|||||||
template <
|
template <
|
||||||
class Ty1,
|
class Ty1,
|
||||||
class Ty2,
|
class Ty2,
|
||||||
bool (Ty1::*DoWithFn)(const AString &, cItemCallback<Ty2> &)
|
bool (Ty1::*DoWithFn)(const AString &, cFunctionRef<bool(Ty2 &)>)
|
||||||
>
|
>
|
||||||
static int StaticDoWith(lua_State * tolua_S)
|
static int StaticDoWith(lua_State * tolua_S)
|
||||||
{
|
{
|
||||||
@ -152,28 +138,14 @@ public:
|
|||||||
return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a valid callback function for parameter #2");
|
return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a valid callback function for parameter #2");
|
||||||
}
|
}
|
||||||
|
|
||||||
class cLuaCallback : public cItemCallback<Ty2>
|
// Call the DoWith function:
|
||||||
{
|
bool res = (Ty1::Get()->*DoWithFn)(ItemName, [&](Ty2 & a_Item)
|
||||||
public:
|
|
||||||
cLuaCallback(cLuaState & a_LuaState, cLuaState::cRef & a_FnRef):
|
|
||||||
m_LuaState(a_LuaState),
|
|
||||||
m_FnRef(a_FnRef)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
virtual bool Item(Ty2 * a_Item) override
|
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
m_LuaState.Call(m_FnRef, a_Item, cLuaState::Return, ret);
|
L.Call(FnRef, &a_Item, cLuaState::Return, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
cLuaState & m_LuaState;
|
);
|
||||||
cLuaState::cRef & m_FnRef;
|
|
||||||
} Callback(L, FnRef);
|
|
||||||
|
|
||||||
// Call the DoWith function:
|
|
||||||
bool res = (Ty1::Get()->*DoWithFn)(ItemName, Callback);
|
|
||||||
|
|
||||||
// Push the result as the return value:
|
// Push the result as the return value:
|
||||||
L.Push(res);
|
L.Push(res);
|
||||||
@ -187,7 +159,7 @@ public:
|
|||||||
template <
|
template <
|
||||||
class Ty1,
|
class Ty1,
|
||||||
class Ty2,
|
class Ty2,
|
||||||
bool (Ty1::*DoWithFn)(UInt32, cItemCallback<Ty2> &)
|
bool (Ty1::*DoWithFn)(UInt32, cFunctionRef<bool(Ty2 &)>)
|
||||||
>
|
>
|
||||||
static int DoWithID(lua_State * tolua_S)
|
static int DoWithID(lua_State * tolua_S)
|
||||||
{
|
{
|
||||||
@ -215,28 +187,14 @@ public:
|
|||||||
return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a valid callback function for parameter #2");
|
return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a valid callback function for parameter #2");
|
||||||
}
|
}
|
||||||
|
|
||||||
class cLuaCallback : public cItemCallback<Ty2>
|
// Call the DoWith function:
|
||||||
{
|
bool res = (Self->*DoWithFn)(ItemID, [&](Ty2 & a_Item)
|
||||||
public:
|
|
||||||
cLuaCallback(cLuaState & a_LuaState, cLuaState::cRef & a_FnRef):
|
|
||||||
m_LuaState(a_LuaState),
|
|
||||||
m_FnRef(a_FnRef)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
virtual bool Item(Ty2 * a_Item) override
|
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
m_LuaState.Call(m_FnRef, a_Item, cLuaState::Return, ret);
|
L.Call(FnRef, &a_Item, cLuaState::Return, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
cLuaState & m_LuaState;
|
);
|
||||||
cLuaState::cRef & m_FnRef;
|
|
||||||
} Callback(L, FnRef);
|
|
||||||
|
|
||||||
// Call the DoWith function:
|
|
||||||
bool res = (Self->*DoWithFn)(ItemID, Callback);
|
|
||||||
|
|
||||||
// Push the result as the return value:
|
// Push the result as the return value:
|
||||||
L.Push(res);
|
L.Push(res);
|
||||||
@ -251,7 +209,7 @@ public:
|
|||||||
template <
|
template <
|
||||||
class SELF,
|
class SELF,
|
||||||
class ITEM,
|
class ITEM,
|
||||||
bool (SELF::*DoWithFn)(int, int, int, cItemCallback<ITEM> &)
|
bool (SELF::*DoWithFn)(int, int, int, cFunctionRef<bool(ITEM &)>)
|
||||||
>
|
>
|
||||||
static int DoWithXYZ(lua_State * tolua_S)
|
static int DoWithXYZ(lua_State * tolua_S)
|
||||||
{
|
{
|
||||||
@ -282,28 +240,14 @@ public:
|
|||||||
return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a valid callback function for parameter #5");
|
return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a valid callback function for parameter #5");
|
||||||
}
|
}
|
||||||
|
|
||||||
class cLuaCallback : public cItemCallback<ITEM>
|
// Call the DoWith function:
|
||||||
{
|
bool res = (Self->*DoWithFn)(BlockX, BlockY, BlockZ, [&](ITEM & a_Item)
|
||||||
public:
|
|
||||||
cLuaCallback(cLuaState & a_LuaState, cLuaState::cRef & a_FnRef):
|
|
||||||
m_LuaState(a_LuaState),
|
|
||||||
m_FnRef(a_FnRef)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
virtual bool Item(ITEM * a_Item) override
|
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
m_LuaState.Call(m_FnRef, a_Item, cLuaState::Return, ret);
|
L.Call(FnRef, &a_Item, cLuaState::Return, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
cLuaState & m_LuaState;
|
);
|
||||||
cLuaState::cRef & m_FnRef;
|
|
||||||
} Callback(L, FnRef);
|
|
||||||
|
|
||||||
// Call the DoWith function:
|
|
||||||
bool res = (Self->*DoWithFn)(BlockX, BlockY, BlockZ, Callback);
|
|
||||||
|
|
||||||
// Push the result as the return value:
|
// Push the result as the return value:
|
||||||
L.Push(res);
|
L.Push(res);
|
||||||
@ -318,7 +262,7 @@ public:
|
|||||||
template <
|
template <
|
||||||
class SELF,
|
class SELF,
|
||||||
class ITEM,
|
class ITEM,
|
||||||
bool (SELF::*DoWithFn)(int, int, int, cItemCallback<ITEM> &),
|
bool (SELF::*DoWithFn)(int, int, int, cFunctionRef<bool(ITEM &)>),
|
||||||
bool (SELF::*CoordCheckFn)(int, int, int) const
|
bool (SELF::*CoordCheckFn)(int, int, int) const
|
||||||
>
|
>
|
||||||
static int DoWithXYZ(lua_State * tolua_S)
|
static int DoWithXYZ(lua_State * tolua_S)
|
||||||
@ -356,28 +300,14 @@ public:
|
|||||||
).c_str());
|
).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
class cLuaCallback : public cItemCallback<ITEM>
|
// Call the DoWith function:
|
||||||
{
|
bool res = (Self->*DoWithFn)(BlockX, BlockY, BlockZ, [&](ITEM & a_Item)
|
||||||
public:
|
|
||||||
cLuaCallback(cLuaState & a_LuaState, cLuaState::cRef & a_FnRef):
|
|
||||||
m_LuaState(a_LuaState),
|
|
||||||
m_FnRef(a_FnRef)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
virtual bool Item(ITEM * a_Item) override
|
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
m_LuaState.Call(m_FnRef, a_Item, cLuaState::Return, ret);
|
L.Call(FnRef, &a_Item, cLuaState::Return, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
cLuaState & m_LuaState;
|
);
|
||||||
cLuaState::cRef & m_FnRef;
|
|
||||||
} Callback(L, FnRef);
|
|
||||||
|
|
||||||
// Call the DoWith function:
|
|
||||||
bool res = (Self->*DoWithFn)(BlockX, BlockY, BlockZ, Callback);
|
|
||||||
|
|
||||||
// Push the result as the return value:
|
// Push the result as the return value:
|
||||||
L.Push(res);
|
L.Push(res);
|
||||||
@ -391,7 +321,7 @@ public:
|
|||||||
template <
|
template <
|
||||||
class Ty1,
|
class Ty1,
|
||||||
class Ty2,
|
class Ty2,
|
||||||
bool (Ty1::*ForEachFn)(int, int, cItemCallback<Ty2> &)
|
bool (Ty1::*ForEachFn)(int, int, cFunctionRef<bool(Ty2 &)>)
|
||||||
>
|
>
|
||||||
static int ForEachInChunk(lua_State * tolua_S)
|
static int ForEachInChunk(lua_State * tolua_S)
|
||||||
{
|
{
|
||||||
@ -421,28 +351,14 @@ public:
|
|||||||
return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a valid callback function for parameter #4");
|
return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a valid callback function for parameter #4");
|
||||||
}
|
}
|
||||||
|
|
||||||
class cLuaCallback : public cItemCallback<Ty2>
|
// Call the DoWith function:
|
||||||
{
|
bool res = (Self->*ForEachFn)(ChunkX, ChunkZ, [&](Ty2 & a_Item)
|
||||||
public:
|
|
||||||
cLuaCallback(cLuaState & a_LuaState, cLuaState::cRef & a_FnRef):
|
|
||||||
m_LuaState(a_LuaState),
|
|
||||||
m_FnRef(a_FnRef)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
virtual bool Item(Ty2 * a_Item) override
|
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
m_LuaState.Call(m_FnRef, a_Item, cLuaState::Return, ret);
|
L.Call(FnRef, &a_Item, cLuaState::Return, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
cLuaState & m_LuaState;
|
);
|
||||||
cLuaState::cRef & m_FnRef;
|
|
||||||
} Callback(L, FnRef);
|
|
||||||
|
|
||||||
// Call the DoWith function:
|
|
||||||
bool res = (Self->*ForEachFn)(ChunkX, ChunkZ, Callback);
|
|
||||||
|
|
||||||
// Push the result as the return value:
|
// Push the result as the return value:
|
||||||
L.Push(res);
|
L.Push(res);
|
||||||
@ -456,7 +372,7 @@ public:
|
|||||||
template <
|
template <
|
||||||
class Ty1,
|
class Ty1,
|
||||||
class Ty2,
|
class Ty2,
|
||||||
bool (Ty1::*ForEachFn)(const cBoundingBox &, cItemCallback<Ty2> &)
|
bool (Ty1::*ForEachFn)(const cBoundingBox &, cFunctionRef<bool(Ty2 &)>)
|
||||||
>
|
>
|
||||||
static int ForEachInBox(lua_State * tolua_S)
|
static int ForEachInBox(lua_State * tolua_S)
|
||||||
{
|
{
|
||||||
@ -488,36 +404,19 @@ public:
|
|||||||
return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a valid callback function for parameter #2");
|
return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a valid callback function for parameter #2");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Callback wrapper for the Lua function:
|
bool res = (Self->*ForEachFn)(*Box, [&](Ty2 & a_Item)
|
||||||
class cLuaCallback : public cItemCallback<Ty2>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
cLuaCallback(cLuaState & a_LuaState, cLuaState::cRef & a_FuncRef) :
|
|
||||||
m_LuaState(a_LuaState),
|
|
||||||
m_FnRef(a_FuncRef)
|
|
||||||
{
|
{
|
||||||
}
|
bool ret = false;
|
||||||
|
if (!L.Call(FnRef, &a_Item, cLuaState::Return, ret))
|
||||||
private:
|
|
||||||
cLuaState & m_LuaState;
|
|
||||||
cLuaState::cRef & m_FnRef;
|
|
||||||
|
|
||||||
// cItemCallback<Ty2> overrides:
|
|
||||||
virtual bool Item(Ty2 * a_Item) override
|
|
||||||
{
|
|
||||||
bool res = false;
|
|
||||||
if (!m_LuaState.Call(m_FnRef, a_Item, cLuaState::Return, res))
|
|
||||||
{
|
{
|
||||||
LOGWARNING("Failed to call Lua callback");
|
LOGWARNING("Failed to call Lua callback");
|
||||||
m_LuaState.LogStackTrace();
|
L.LogStackTrace();
|
||||||
return true; // Abort enumeration
|
return true; // Abort enumeration
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return ret;
|
||||||
}
|
}
|
||||||
} Callback(L, FnRef);
|
);
|
||||||
|
|
||||||
bool res = (Self->*ForEachFn)(*Box, Callback);
|
|
||||||
|
|
||||||
// Push the result as the return value:
|
// Push the result as the return value:
|
||||||
L.Push(res);
|
L.Push(res);
|
||||||
@ -531,7 +430,7 @@ public:
|
|||||||
template <
|
template <
|
||||||
class Ty1,
|
class Ty1,
|
||||||
class Ty2,
|
class Ty2,
|
||||||
bool (Ty1::*ForEachFn)(cItemCallback<Ty2> &)
|
bool (Ty1::*ForEachFn)(cFunctionRef<bool(Ty2 &)>)
|
||||||
>
|
>
|
||||||
static int ForEach(lua_State * tolua_S)
|
static int ForEach(lua_State * tolua_S)
|
||||||
{
|
{
|
||||||
@ -558,29 +457,14 @@ public:
|
|||||||
return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a valid callback function for parameter #1");
|
return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a valid callback function for parameter #1");
|
||||||
}
|
}
|
||||||
|
|
||||||
class cLuaCallback : public cItemCallback<Ty2>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
cLuaCallback(cLuaState & a_LuaState, cLuaState::cRef & a_FnRef):
|
|
||||||
m_LuaState(a_LuaState),
|
|
||||||
m_FnRef(a_FnRef)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
cLuaState & m_LuaState;
|
|
||||||
cLuaState::cRef & m_FnRef;
|
|
||||||
|
|
||||||
virtual bool Item(Ty2 * a_Item) override
|
|
||||||
{
|
|
||||||
bool res = false; // By default continue the enumeration
|
|
||||||
m_LuaState.Call(m_FnRef, a_Item, cLuaState::Return, res);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
} Callback(L, FnRef);
|
|
||||||
|
|
||||||
// Call the enumeration:
|
// Call the enumeration:
|
||||||
bool res = (Self->*ForEachFn)(Callback);
|
bool res = (Self->*ForEachFn)([&](Ty2 & a_Item)
|
||||||
|
{
|
||||||
|
bool ret = false; // By default continue the enumeration
|
||||||
|
L.Call(FnRef, &a_Item, cLuaState::Return, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// Push the return value:
|
// Push the return value:
|
||||||
L.Push(res);
|
L.Push(res);
|
||||||
@ -595,7 +479,7 @@ public:
|
|||||||
template <
|
template <
|
||||||
class Ty1,
|
class Ty1,
|
||||||
class Ty2,
|
class Ty2,
|
||||||
bool (Ty1::*ForEachFn)(cItemCallback<Ty2> &)
|
bool (Ty1::*ForEachFn)(cFunctionRef<bool(Ty2 &)>)
|
||||||
>
|
>
|
||||||
static int StaticForEach(lua_State * tolua_S)
|
static int StaticForEach(lua_State * tolua_S)
|
||||||
{
|
{
|
||||||
@ -616,29 +500,14 @@ public:
|
|||||||
return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a valid callback function for parameter #1");
|
return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a valid callback function for parameter #1");
|
||||||
}
|
}
|
||||||
|
|
||||||
class cLuaCallback : public cItemCallback<Ty2>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
cLuaCallback(cLuaState & a_LuaState, cLuaState::cRef & a_FnRef):
|
|
||||||
m_LuaState(a_LuaState),
|
|
||||||
m_FnRef(a_FnRef)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
cLuaState & m_LuaState;
|
|
||||||
cLuaState::cRef & m_FnRef;
|
|
||||||
|
|
||||||
virtual bool Item(Ty2 * a_Item) override
|
|
||||||
{
|
|
||||||
bool res = false; // By default continue the enumeration
|
|
||||||
m_LuaState.Call(m_FnRef, a_Item, cLuaState::Return, res);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
} Callback(L, FnRef);
|
|
||||||
|
|
||||||
// Call the enumeration:
|
// Call the enumeration:
|
||||||
bool res = (Ty1::Get()->*ForEachFn)(Callback);
|
bool res = (Ty1::Get()->*ForEachFn)([&](Ty2 & a_Item)
|
||||||
|
{
|
||||||
|
bool ret = false; // By default continue the enumeration
|
||||||
|
L.Call(FnRef, &a_Item, cLuaState::Return, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// Push the return value:
|
// Push the return value:
|
||||||
L.Push(res);
|
L.Push(res);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
|
|
||||||
// ManualBindings_World.cpp
|
// ManualBindings_World.cpp
|
||||||
|
|
||||||
// Implements the manual Lua API bindings for the cWorld class
|
// Implements the manual Lua API bindings for the cWorld class
|
||||||
@ -237,10 +237,10 @@ static int tolua_cWorld_DoWithPlayerByUUID(lua_State * tolua_S)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Call the function:
|
// Call the function:
|
||||||
bool res = Self->DoWithPlayerByUUID(PlayerUUID, [&](cPlayer * a_Player)
|
bool res = Self->DoWithPlayerByUUID(PlayerUUID, [&](cPlayer & a_Player)
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
L.Call(FnRef, a_Player, cLuaState::Return, ret);
|
L.Call(FnRef, &a_Player, cLuaState::Return, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -1993,14 +1993,14 @@ bool cPluginManager::IsValidHookType(int a_HookType)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cPluginManager::DoWithPlugin(const AString & a_PluginName, cPluginCallback & a_Callback)
|
bool cPluginManager::DoWithPlugin(const AString & a_PluginName, cPluginCallback a_Callback)
|
||||||
{
|
{
|
||||||
// TODO: Implement locking for plugins
|
// TODO: Implement locking for plugins
|
||||||
for (auto & plugin: m_Plugins)
|
for (auto & plugin: m_Plugins)
|
||||||
{
|
{
|
||||||
if (plugin->GetName() == a_PluginName)
|
if (plugin->GetName() == a_PluginName)
|
||||||
{
|
{
|
||||||
return a_Callback.Item(plugin.get());
|
return a_Callback(*plugin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -2010,12 +2010,12 @@ bool cPluginManager::DoWithPlugin(const AString & a_PluginName, cPluginCallback
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cPluginManager::ForEachPlugin(cPluginCallback & a_Callback)
|
bool cPluginManager::ForEachPlugin(cPluginCallback a_Callback)
|
||||||
{
|
{
|
||||||
// TODO: Implement locking for plugins
|
// TODO: Implement locking for plugins
|
||||||
for (auto & plugin: m_Plugins)
|
for (auto & plugin: m_Plugins)
|
||||||
{
|
{
|
||||||
if (a_Callback.Item(plugin.get()))
|
if (a_Callback(*plugin))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "Defines.h"
|
#include "Defines.h"
|
||||||
|
#include "FunctionRef.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -194,7 +195,7 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
/** The interface used for enumerating and extern-calling plugins */
|
/** The interface used for enumerating and extern-calling plugins */
|
||||||
typedef cItemCallback<cPlugin> cPluginCallback;
|
using cPluginCallback = cFunctionRef<bool(cPlugin &)>;
|
||||||
|
|
||||||
typedef std::list<cPlugin *> PluginList;
|
typedef std::list<cPlugin *> PluginList;
|
||||||
|
|
||||||
@ -372,18 +373,18 @@ public:
|
|||||||
|
|
||||||
/** Calls the specified callback with the plugin object of the specified plugin.
|
/** Calls the specified callback with the plugin object of the specified plugin.
|
||||||
Returns false if plugin not found, otherwise returns the value that the callback has returned. */
|
Returns false if plugin not found, otherwise returns the value that the callback has returned. */
|
||||||
bool DoWithPlugin(const AString & a_PluginName, cPluginCallback & a_Callback);
|
bool DoWithPlugin(const AString & a_PluginName, cPluginCallback a_Callback);
|
||||||
|
|
||||||
/** Calls the specified callback for each plugin in m_Plugins.
|
/** Calls the specified callback for each plugin in m_Plugins.
|
||||||
Returns true if all plugins have been reported, false if the callback has aborted the enumeration by returning true. */
|
Returns true if all plugins have been reported, false if the callback has aborted the enumeration by returning true. */
|
||||||
bool ForEachPlugin(cPluginCallback & a_Callback);
|
bool ForEachPlugin(cPluginCallback a_Callback);
|
||||||
|
|
||||||
/** Returns the name of the folder (cPlugin::GetFolderName()) from which the specified plugin was loaded. */
|
/** Returns the name of the folder (cPlugin::GetFolderName()) from which the specified plugin was loaded. */
|
||||||
AString GetPluginFolderName(const AString & a_PluginName); // tolua_export
|
AString GetPluginFolderName(const AString & a_PluginName); // tolua_export
|
||||||
|
|
||||||
/** Returns the path where individual plugins' folders are expected.
|
/** Returns the path where individual plugins' folders are expected.
|
||||||
The path doesn't end in a slash. */
|
The path doesn't end in a slash. */
|
||||||
static AString GetPluginsPath(void) { return FILE_IO_PREFIX + AString("Plugins"); } // tolua_export
|
static AString GetPluginsPath(void) { return FILE_IO_PREFIX "Plugins"; } // tolua_export
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class cRoot;
|
friend class cRoot;
|
||||||
|
@ -2163,7 +2163,7 @@ size_t cBlockArea::MakeIndexForSize(Vector3i a_RelPos, Vector3i a_Size)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cBlockArea::DoWithBlockEntityRelAt(int a_RelX, int a_RelY, int a_RelZ, cItemCallback<cBlockEntity> & a_Callback)
|
bool cBlockArea::DoWithBlockEntityRelAt(int a_RelX, int a_RelY, int a_RelZ, cBlockEntityCallback a_Callback)
|
||||||
{
|
{
|
||||||
ASSERT(IsValidRelCoords(a_RelX, a_RelY, a_RelZ));
|
ASSERT(IsValidRelCoords(a_RelX, a_RelY, a_RelZ));
|
||||||
if (!HasBlockEntities())
|
if (!HasBlockEntities())
|
||||||
@ -2176,14 +2176,14 @@ bool cBlockArea::DoWithBlockEntityRelAt(int a_RelX, int a_RelY, int a_RelZ, cIte
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return a_Callback.Item(itr->second);
|
return a_Callback(*itr->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cBlockArea::DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cItemCallback<cBlockEntity> & a_Callback)
|
bool cBlockArea::DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback a_Callback)
|
||||||
{
|
{
|
||||||
return DoWithBlockEntityRelAt(a_BlockX - m_Origin.x, a_BlockY - m_Origin.y, a_BlockZ - m_Origin.z, a_Callback);
|
return DoWithBlockEntityRelAt(a_BlockX - m_Origin.x, a_BlockY - m_Origin.y, a_BlockZ - m_Origin.z, a_Callback);
|
||||||
}
|
}
|
||||||
@ -2192,7 +2192,7 @@ bool cBlockArea::DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, c
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cBlockArea::ForEachBlockEntity(cItemCallback<cBlockEntity> & a_Callback)
|
bool cBlockArea::ForEachBlockEntity(cBlockEntityCallback a_Callback)
|
||||||
{
|
{
|
||||||
if (!HasBlockEntities())
|
if (!HasBlockEntities())
|
||||||
{
|
{
|
||||||
@ -2200,7 +2200,7 @@ bool cBlockArea::ForEachBlockEntity(cItemCallback<cBlockEntity> & a_Callback)
|
|||||||
}
|
}
|
||||||
for (auto & keyPair: *m_BlockEntities)
|
for (auto & keyPair: *m_BlockEntities)
|
||||||
{
|
{
|
||||||
if (a_Callback.Item(keyPair.second))
|
if (a_Callback(*keyPair.second))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -17,13 +17,14 @@
|
|||||||
#include "ForEachChunkProvider.h"
|
#include "ForEachChunkProvider.h"
|
||||||
#include "ChunkDataCallback.h"
|
#include "ChunkDataCallback.h"
|
||||||
#include "Cuboid.h"
|
#include "Cuboid.h"
|
||||||
|
#include "FunctionRef.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// fwd:
|
// fwd:
|
||||||
class cCuboid;
|
class cCuboid;
|
||||||
|
using cBlockEntityCallback = cFunctionRef<bool(cBlockEntity &)>;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -379,18 +380,18 @@ public:
|
|||||||
/** Calls the callback for the block entity at the specified coords.
|
/** Calls the callback for the block entity at the specified coords.
|
||||||
Returns false if there is no block entity at those coords, or the block area doesn't have baBlockEntities.
|
Returns false if there is no block entity at those coords, or the block area doesn't have baBlockEntities.
|
||||||
Returns the value that the callback has returned if there is a block entity. */
|
Returns the value that the callback has returned if there is a block entity. */
|
||||||
bool DoWithBlockEntityRelAt(int a_RelX, int a_RelY, int a_RelZ, cItemCallback<cBlockEntity> & a_Callback);
|
bool DoWithBlockEntityRelAt(int a_RelX, int a_RelY, int a_RelZ, cBlockEntityCallback a_Callback);
|
||||||
|
|
||||||
/** Calls the callback for the block entity at the specified coords.
|
/** Calls the callback for the block entity at the specified coords.
|
||||||
Returns false if there is no block entity at those coords.
|
Returns false if there is no block entity at those coords.
|
||||||
Returns the value that the callback has returned if there is a block entity. */
|
Returns the value that the callback has returned if there is a block entity. */
|
||||||
bool DoWithBlockEntityAt (int a_BlockX, int a_BlockY, int a_BlockZ, cItemCallback<cBlockEntity> & a_Callback);
|
bool DoWithBlockEntityAt (int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback a_Callback);
|
||||||
|
|
||||||
/** Calls the callback for all the block entities.
|
/** Calls the callback for all the block entities.
|
||||||
If the callback returns true, aborts the enumeration and returns false.
|
If the callback returns true, aborts the enumeration and returns false.
|
||||||
If the callback returns true, continues with the next BE.
|
If the callback returns true, continues with the next BE.
|
||||||
Returns true if all block entities have been enumerated (including the case when there is none or the area is without baBlockEntities). */
|
Returns true if all block entities have been enumerated (including the case when there is none or the area is without baBlockEntities). */
|
||||||
bool ForEachBlockEntity(cItemCallback<cBlockEntity> & a_Callback);
|
bool ForEachBlockEntity(cBlockEntityCallback a_Callback);
|
||||||
|
|
||||||
/** Direct read-only access to block entities. */
|
/** Direct read-only access to block entities. */
|
||||||
const cBlockEntities & GetBlockEntities(void) const { ASSERT(HasBlockEntities()); return *m_BlockEntities; }
|
const cBlockEntities & GetBlockEntities(void) const { ASSERT(HasBlockEntities()); return *m_BlockEntities; }
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
|
|
||||||
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
||||||
|
|
||||||
#include "BeaconEntity.h"
|
#include "BeaconEntity.h"
|
||||||
@ -195,33 +195,21 @@ void cBeaconEntity::UpdateBeacon(void)
|
|||||||
GetWindow()->SetProperty(0, m_BeaconLevel);
|
GetWindow()->SetProperty(0, m_BeaconLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
class cPlayerCallback :
|
Vector3d BeaconPosition(m_PosX, m_PosY, m_PosZ);
|
||||||
public cPlayerListCallback
|
GetWorld()->ForEachPlayer([=](cPlayer & a_Player)
|
||||||
{
|
|
||||||
public:
|
|
||||||
cPlayerCallback(Vector3d a_Position):
|
|
||||||
m_Position(a_Position)
|
|
||||||
{
|
{
|
||||||
}
|
Vector3d Distance = BeaconPosition - a_Player.GetPosition();
|
||||||
|
|
||||||
virtual bool Item(cPlayer * a_Player)
|
|
||||||
{
|
|
||||||
Vector3d Distance = m_Position - a_Player->GetPosition();
|
|
||||||
if (
|
if (
|
||||||
(std::abs(Distance.y) <= 14) &&
|
(std::abs(Distance.y) <= 14) &&
|
||||||
(std::abs(Distance.x) <= 20) &&
|
(std::abs(Distance.x) <= 20) &&
|
||||||
(std::abs(Distance.z) <= 20)
|
(std::abs(Distance.z) <= 20)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
a_Player->AwardAchievement(eStatistic::achFullBeacon);
|
a_Player.AwardAchievement(eStatistic::achFullBeacon);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
);
|
||||||
private:
|
|
||||||
Vector3d m_Position;
|
|
||||||
} PlayerCallback(Vector3d(m_PosX, m_PosY, m_PosZ));
|
|
||||||
GetWorld()->ForEachPlayer(PlayerCallback);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,46 +237,28 @@ void cBeaconEntity::GiveEffects(void)
|
|||||||
SecondaryEffect = m_SecondaryEffect;
|
SecondaryEffect = m_SecondaryEffect;
|
||||||
}
|
}
|
||||||
|
|
||||||
class cPlayerCallback : public cPlayerListCallback
|
Vector3d BeaconPosition(m_PosX, m_PosY, m_PosZ);
|
||||||
{
|
GetWorld()->ForEachPlayer([=](cPlayer & a_Player)
|
||||||
int m_Radius;
|
|
||||||
Vector3d m_Position;
|
|
||||||
cEntityEffect::eType m_PrimaryEffect, m_SecondaryEffect;
|
|
||||||
short m_EffectLevel;
|
|
||||||
|
|
||||||
virtual bool Item(cPlayer * a_Player)
|
|
||||||
{
|
{
|
||||||
Vector3d PlayerPosition = Vector3d(a_Player->GetPosition());
|
auto PlayerPosition = a_Player.GetPosition();
|
||||||
if (PlayerPosition.y > m_Position.y)
|
if (PlayerPosition.y > BeaconPosition.y)
|
||||||
{
|
{
|
||||||
PlayerPosition.y = m_Position.y;
|
PlayerPosition.y = BeaconPosition.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Vanilla minecraft uses an AABB check instead of a radius one
|
// TODO: Vanilla minecraft uses an AABB check instead of a radius one
|
||||||
if ((PlayerPosition - m_Position).Length() <= m_Radius)
|
if ((PlayerPosition - BeaconPosition).Length() <= Radius)
|
||||||
{
|
{
|
||||||
a_Player->AddEntityEffect(m_PrimaryEffect, 180, m_EffectLevel);
|
a_Player.AddEntityEffect(m_PrimaryEffect, 180, EffectLevel);
|
||||||
|
|
||||||
if (m_SecondaryEffect != cEntityEffect::effNoEffect)
|
if (m_SecondaryEffect != cEntityEffect::effNoEffect)
|
||||||
{
|
{
|
||||||
a_Player->AddEntityEffect(m_SecondaryEffect, 180, 0);
|
a_Player.AddEntityEffect(m_SecondaryEffect, 180, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
);
|
||||||
public:
|
|
||||||
cPlayerCallback(int a_Radius, Vector3d a_Position, cEntityEffect::eType a_PrimaryEffect, cEntityEffect::eType a_SecondaryEffect, short a_EffectLevel):
|
|
||||||
m_Radius(a_Radius),
|
|
||||||
m_Position(a_Position),
|
|
||||||
m_PrimaryEffect(a_PrimaryEffect),
|
|
||||||
m_SecondaryEffect(a_SecondaryEffect),
|
|
||||||
m_EffectLevel(a_EffectLevel)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
} PlayerCallback(Radius, Vector3d(m_PosX, m_PosY, m_PosZ), m_PrimaryEffect, SecondaryEffect, EffectLevel);
|
|
||||||
GetWorld()->ForEachPlayer(PlayerCallback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -138,33 +138,18 @@ bool cChestEntity::UsedBy(cPlayer * a_Player)
|
|||||||
void cChestEntity::ScanNeighbours()
|
void cChestEntity::ScanNeighbours()
|
||||||
{
|
{
|
||||||
// Callback for finding neighbouring chest:
|
// Callback for finding neighbouring chest:
|
||||||
class cFindNeighbour :
|
auto FindNeighbour = [this](cChestEntity & a_Chest)
|
||||||
public cChestCallback
|
|
||||||
{
|
{
|
||||||
public:
|
if (a_Chest.GetBlockType() != m_BlockType)
|
||||||
cChestEntity * m_Neighbour;
|
|
||||||
BLOCKTYPE m_ChestType;
|
|
||||||
|
|
||||||
cFindNeighbour(BLOCKTYPE a_ChestType) :
|
|
||||||
m_Neighbour(nullptr),
|
|
||||||
m_ChestType(a_ChestType)
|
|
||||||
{
|
{
|
||||||
|
// Neighboring block is not the same type of chest
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
m_Neighbour = &a_Chest;
|
||||||
virtual bool Item(cChestEntity * a_Chest) override
|
return false;
|
||||||
{
|
|
||||||
if (a_Chest->GetBlockType() != m_ChestType)
|
|
||||||
{
|
|
||||||
// Neighboring block is not the same type of chest
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
m_Neighbour = a_Chest;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Scan horizontally adjacent blocks for any neighbouring chest of the same type:
|
// Scan horizontally adjacent blocks for any neighbouring chest of the same type:
|
||||||
cFindNeighbour FindNeighbour(m_BlockType);
|
|
||||||
if (
|
if (
|
||||||
m_World->DoWithChestAt(m_PosX - 1, m_PosY, m_PosZ, FindNeighbour) ||
|
m_World->DoWithChestAt(m_PosX - 1, m_PosY, m_PosZ, FindNeighbour) ||
|
||||||
m_World->DoWithChestAt(m_PosX + 1, m_PosY, m_PosZ, FindNeighbour) ||
|
m_World->DoWithChestAt(m_PosX + 1, m_PosY, m_PosZ, FindNeighbour) ||
|
||||||
@ -172,7 +157,6 @@ void cChestEntity::ScanNeighbours()
|
|||||||
m_World->DoWithChestAt(m_PosX, m_PosY, m_PosZ + 1, FindNeighbour)
|
m_World->DoWithChestAt(m_PosX, m_PosY, m_PosZ + 1, FindNeighbour)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
m_Neighbour = FindNeighbour.m_Neighbour;
|
|
||||||
m_Neighbour->m_Neighbour = this;
|
m_Neighbour->m_Neighbour = this;
|
||||||
// Force neighbour's window shut. Does Mojang server do this or should a double window open?
|
// Force neighbour's window shut. Does Mojang server do this or should a double window open?
|
||||||
m_Neighbour->DestroyWindow();
|
m_Neighbour->DestroyWindow();
|
||||||
|
@ -193,8 +193,7 @@ bool cHopperEntity::MovePickupsIn(cChunk & a_Chunk, Int64 a_CurrentTick)
|
|||||||
{
|
{
|
||||||
UNUSED(a_CurrentTick);
|
UNUSED(a_CurrentTick);
|
||||||
|
|
||||||
class cHopperPickupSearchCallback :
|
class cHopperPickupSearchCallback
|
||||||
public cEntityCallback
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
cHopperPickupSearchCallback(const Vector3i & a_Pos, cItemGrid & a_Contents) :
|
cHopperPickupSearchCallback(const Vector3i & a_Pos, cItemGrid & a_Contents) :
|
||||||
@ -204,22 +203,20 @@ bool cHopperEntity::MovePickupsIn(cChunk & a_Chunk, Int64 a_CurrentTick)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool Item(cEntity * a_Entity) override
|
bool operator () (cEntity & a_Entity)
|
||||||
{
|
{
|
||||||
ASSERT(a_Entity != nullptr);
|
if (!a_Entity.IsPickup())
|
||||||
|
|
||||||
if (!a_Entity->IsPickup())
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3f EntityPos = a_Entity->GetPosition();
|
Vector3f EntityPos = a_Entity.GetPosition();
|
||||||
Vector3f BlockPos(m_Pos.x + 0.5f, static_cast<float>(m_Pos.y) + 1, m_Pos.z + 0.5f); // One block above hopper, and search from center outwards
|
Vector3f BlockPos(m_Pos.x + 0.5f, static_cast<float>(m_Pos.y) + 1, m_Pos.z + 0.5f); // One block above hopper, and search from center outwards
|
||||||
double Distance = (EntityPos - BlockPos).Length();
|
double Distance = (EntityPos - BlockPos).Length();
|
||||||
|
|
||||||
if (Distance < 0.5)
|
if (Distance < 0.5)
|
||||||
{
|
{
|
||||||
if (TrySuckPickupIn(static_cast<cPickup *>(a_Entity)))
|
if (TrySuckPickupIn(static_cast<cPickup &>(a_Entity)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -228,9 +225,9 @@ bool cHopperEntity::MovePickupsIn(cChunk & a_Chunk, Int64 a_CurrentTick)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TrySuckPickupIn(cPickup * a_Pickup)
|
bool TrySuckPickupIn(cPickup & a_Pickup)
|
||||||
{
|
{
|
||||||
cItem & Item = a_Pickup->GetItem();
|
cItem & Item = a_Pickup.GetItem();
|
||||||
|
|
||||||
for (int i = 0; i < ContentsWidth * ContentsHeight; i++)
|
for (int i = 0; i < ContentsWidth * ContentsHeight; i++)
|
||||||
{
|
{
|
||||||
@ -238,7 +235,7 @@ bool cHopperEntity::MovePickupsIn(cChunk & a_Chunk, Int64 a_CurrentTick)
|
|||||||
{
|
{
|
||||||
m_bFoundPickupsAbove = true;
|
m_bFoundPickupsAbove = true;
|
||||||
m_Contents.SetSlot(i, Item);
|
m_Contents.SetSlot(i, Item);
|
||||||
a_Pickup->Destroy(); // Kill pickup
|
a_Pickup.Destroy(); // Kill pickup
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -252,7 +249,7 @@ bool cHopperEntity::MovePickupsIn(cChunk & a_Chunk, Int64 a_CurrentTick)
|
|||||||
|
|
||||||
if (Item.IsEmpty())
|
if (Item.IsEmpty())
|
||||||
{
|
{
|
||||||
a_Pickup->Destroy(); // Kill pickup if all items were added
|
a_Pickup.Destroy(); // Kill pickup if all items were added
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
|
|
||||||
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
||||||
|
|
||||||
#include "MobSpawnerEntity.h"
|
#include "MobSpawnerEntity.h"
|
||||||
@ -138,47 +138,36 @@ void cMobSpawnerEntity::SpawnEntity(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
class cCallback : public cChunkCallback
|
auto MobType = m_Entity;
|
||||||
{
|
bool EntitiesSpawned = m_World->DoWithChunk(GetChunkX(), GetChunkZ(), [&](cChunk & a_Chunk)
|
||||||
public:
|
|
||||||
cCallback(int a_RelX, int a_RelY, int a_RelZ, eMonsterType a_MobType, int a_NearbyEntitiesNum) :
|
|
||||||
m_RelX(a_RelX),
|
|
||||||
m_RelY(a_RelY),
|
|
||||||
m_RelZ(a_RelZ),
|
|
||||||
m_MobType(a_MobType),
|
|
||||||
m_NearbyEntitiesNum(a_NearbyEntitiesNum)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool Item(cChunk * a_Chunk)
|
|
||||||
{
|
{
|
||||||
auto & Random = GetRandomProvider();
|
auto & Random = GetRandomProvider();
|
||||||
|
|
||||||
bool EntitiesSpawned = false;
|
bool HaveSpawnedEntity = false;
|
||||||
for (size_t i = 0; i < 4; i++)
|
for (size_t i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
if (m_NearbyEntitiesNum >= 6)
|
if (NearbyEntities >= 6)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
int RelX = m_RelX + static_cast<int>((Random.RandReal<double>() - Random.RandReal<double>()) * 4.0);
|
int RelX = m_RelX + static_cast<int>((Random.RandReal<double>() - Random.RandReal<double>()) * 4.0);
|
||||||
int RelY = m_RelY + Random.RandInt(-1, 1);
|
int RelY = m_PosY + Random.RandInt(-1, 1);
|
||||||
int RelZ = m_RelZ + static_cast<int>((Random.RandReal<double>() - Random.RandReal<double>()) * 4.0);
|
int RelZ = m_RelZ + static_cast<int>((Random.RandReal<double>() - Random.RandReal<double>()) * 4.0);
|
||||||
|
|
||||||
cChunk * Chunk = a_Chunk->GetRelNeighborChunkAdjustCoords(RelX, RelZ);
|
cChunk * Chunk = a_Chunk.GetRelNeighborChunkAdjustCoords(RelX, RelZ);
|
||||||
if ((Chunk == nullptr) || !Chunk->IsValid())
|
if ((Chunk == nullptr) || !Chunk->IsValid())
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
EMCSBiome Biome = Chunk->GetBiomeAt(RelX, RelZ);
|
EMCSBiome Biome = Chunk->GetBiomeAt(RelX, RelZ);
|
||||||
|
|
||||||
if (cMobSpawner::CanSpawnHere(Chunk, RelX, RelY, RelZ, m_MobType, Biome))
|
if (cMobSpawner::CanSpawnHere(Chunk, RelX, RelY, RelZ, MobType, Biome))
|
||||||
{
|
{
|
||||||
double PosX = Chunk->GetPosX() * cChunkDef::Width + RelX;
|
double PosX = Chunk->GetPosX() * cChunkDef::Width + RelX;
|
||||||
double PosZ = Chunk->GetPosZ() * cChunkDef::Width + RelZ;
|
double PosZ = Chunk->GetPosZ() * cChunkDef::Width + RelZ;
|
||||||
|
|
||||||
auto Monster = cMonster::NewMonsterFromType(m_MobType);
|
auto Monster = cMonster::NewMonsterFromType(MobType);
|
||||||
if (Monster == nullptr)
|
if (Monster == nullptr)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
@ -188,7 +177,7 @@ void cMobSpawnerEntity::SpawnEntity(void)
|
|||||||
Monster->SetYaw(Random.RandReal(360.0f));
|
Monster->SetYaw(Random.RandReal(360.0f));
|
||||||
if (Chunk->GetWorld()->SpawnMobFinalize(std::move(Monster)) != cEntity::INVALID_ID)
|
if (Chunk->GetWorld()->SpawnMobFinalize(std::move(Monster)) != cEntity::INVALID_ID)
|
||||||
{
|
{
|
||||||
EntitiesSpawned = true;
|
HaveSpawnedEntity = true;
|
||||||
Chunk->BroadcastSoundParticleEffect(
|
Chunk->BroadcastSoundParticleEffect(
|
||||||
EffectID::PARTICLE_MOBSPAWN,
|
EffectID::PARTICLE_MOBSPAWN,
|
||||||
static_cast<int>(PosX * 8.0),
|
static_cast<int>(PosX * 8.0),
|
||||||
@ -196,19 +185,15 @@ void cMobSpawnerEntity::SpawnEntity(void)
|
|||||||
static_cast<int>(PosZ * 8.0),
|
static_cast<int>(PosZ * 8.0),
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
m_NearbyEntitiesNum++;
|
NearbyEntities++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return EntitiesSpawned;
|
return EntitiesSpawned;
|
||||||
}
|
}
|
||||||
protected:
|
);
|
||||||
int m_RelX, m_RelY, m_RelZ;
|
|
||||||
eMonsterType m_MobType;
|
|
||||||
int m_NearbyEntitiesNum;
|
|
||||||
} Callback(m_RelX, m_PosY, m_RelZ, m_Entity, NearbyEntities);
|
|
||||||
|
|
||||||
if (m_World->DoWithChunk(GetChunkX(), GetChunkZ(), Callback))
|
if (EntitiesSpawned)
|
||||||
{
|
{
|
||||||
ResetTimer();
|
ResetTimer();
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
|
|
||||||
// BlockBed.cpp
|
// BlockBed.cpp
|
||||||
|
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "BlockBed.h"
|
#include "BlockBed.h"
|
||||||
|
|
||||||
#include "BroadcastInterface.h"
|
#include "BroadcastInterface.h"
|
||||||
#include "Entities/../World.h"
|
|
||||||
#include "Entities/Player.h"
|
#include "Entities/Player.h"
|
||||||
|
#include "../World.h"
|
||||||
#include "../BoundingBox.h"
|
#include "../BoundingBox.h"
|
||||||
#include "../Mobs/Monster.h"
|
#include "../Mobs/Monster.h"
|
||||||
#include "../BlockEntities/BedEntity.h"
|
#include "../BlockEntities/BedEntity.h"
|
||||||
@ -53,66 +53,6 @@ void cBlockBedHandler::OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInt
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
class cFindMobs :
|
|
||||||
public cEntityCallback
|
|
||||||
{
|
|
||||||
virtual bool Item(cEntity * a_Entity) override
|
|
||||||
{
|
|
||||||
return (
|
|
||||||
(a_Entity->GetEntityType() == cEntity::etMonster) &&
|
|
||||||
(static_cast<cMonster*>(a_Entity)->GetMobFamily() == cMonster::mfHostile)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class cTimeFastForwardTester :
|
|
||||||
public cPlayerListCallback
|
|
||||||
{
|
|
||||||
virtual bool Item(cPlayer * a_Player) override
|
|
||||||
{
|
|
||||||
if (!a_Player->IsInBed())
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class cPlayerBedStateUnsetter :
|
|
||||||
public cPlayerListCallback
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
cPlayerBedStateUnsetter(Vector3i a_Position, cChunkInterface & a_ChunkInterface) :
|
|
||||||
m_Position(a_Position),
|
|
||||||
m_ChunkInterface(a_ChunkInterface)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool Item(cPlayer * a_Player) override
|
|
||||||
{
|
|
||||||
cBlockBedHandler::SetBedOccupationState(m_ChunkInterface, a_Player->GetLastBedPos(), false);
|
|
||||||
a_Player->SetIsInBed(false);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Vector3i m_Position;
|
|
||||||
cChunkInterface & m_ChunkInterface;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cBlockBedHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ)
|
bool cBlockBedHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ)
|
||||||
{
|
{
|
||||||
if (a_WorldInterface.GetDimension() != dimOverworld)
|
if (a_WorldInterface.GetDimension() != dimOverworld)
|
||||||
@ -133,7 +73,14 @@ bool cBlockBedHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cFindMobs FindMobs;
|
auto FindMobs = [](cEntity & a_Entity)
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
(a_Entity.GetEntityType() == cEntity::etMonster) &&
|
||||||
|
(static_cast<cMonster&>(a_Entity).GetMobFamily() == cMonster::mfHostile)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
if (!a_Player.GetWorld()->ForEachEntityInBox(cBoundingBox(a_Player.GetPosition() - Vector3i(0, 5, 0), 8, 10), FindMobs))
|
if (!a_Player.GetWorld()->ForEachEntityInBox(cBoundingBox(a_Player.GetPosition() - Vector3i(0, 5, 0), 8, 10), FindMobs))
|
||||||
{
|
{
|
||||||
a_Player.SendMessageFailure("You may not rest now, there are monsters nearby");
|
a_Player.SendMessageFailure("You may not rest now, there are monsters nearby");
|
||||||
@ -164,11 +111,24 @@ bool cBlockBedHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface
|
|||||||
a_Player.SetIsInBed(true);
|
a_Player.SetIsInBed(true);
|
||||||
a_Player.SendMessageSuccess("Home position set successfully");
|
a_Player.SendMessageSuccess("Home position set successfully");
|
||||||
|
|
||||||
cTimeFastForwardTester Tester;
|
auto TimeFastForwardTester = [](cPlayer & a_OtherPlayer)
|
||||||
if (a_WorldInterface.ForEachPlayer(Tester))
|
|
||||||
{
|
{
|
||||||
cPlayerBedStateUnsetter Unsetter(Vector3i(a_BlockX + PillowDirection.x, a_BlockY, a_BlockZ + PillowDirection.z), a_ChunkInterface);
|
if (!a_OtherPlayer.IsInBed())
|
||||||
a_WorldInterface.ForEachPlayer(Unsetter);
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (a_WorldInterface.ForEachPlayer(TimeFastForwardTester))
|
||||||
|
{
|
||||||
|
a_WorldInterface.ForEachPlayer([&](cPlayer & a_OtherPlayer)
|
||||||
|
{
|
||||||
|
cBlockBedHandler::SetBedOccupationState(a_ChunkInterface, a_OtherPlayer.GetLastBedPos(), false);
|
||||||
|
a_OtherPlayer.SetIsInBed(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
);
|
||||||
a_WorldInterface.SetTimeOfDay(0);
|
a_WorldInterface.SetTimeOfDay(0);
|
||||||
a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta & 0x0b); // Clear the "occupied" bit of the bed's block
|
a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta & 0x0b); // Clear the "occupied" bit of the bed's block
|
||||||
}
|
}
|
||||||
@ -184,25 +144,12 @@ bool cBlockBedHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface
|
|||||||
|
|
||||||
void cBlockBedHandler::OnPlacedByPlayer(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, const sSetBlock & a_BlockChange)
|
void cBlockBedHandler::OnPlacedByPlayer(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, const sSetBlock & a_BlockChange)
|
||||||
{
|
{
|
||||||
class cBedColor :
|
a_Player.GetWorld()->DoWithBedAt(a_BlockChange.GetX(), a_BlockChange.GetY(), a_BlockChange.GetZ(), [&](cBedEntity & a_Bed)
|
||||||
public cBedCallback
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
short m_Color;
|
|
||||||
|
|
||||||
cBedColor(short a_Color) :
|
|
||||||
m_Color(a_Color)
|
|
||||||
{
|
{
|
||||||
}
|
a_Bed.SetColor(a_Player.GetEquippedItem().m_ItemDamage);
|
||||||
|
|
||||||
virtual bool Item(cBedEntity * a_Bed) override
|
|
||||||
{
|
|
||||||
a_Bed->SetColor(m_Color);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
);
|
||||||
cBedColor BedCallback(a_Player.GetEquippedItem().m_ItemDamage);
|
|
||||||
a_Player.GetWorld()->DoWithBedAt(a_BlockChange.GetX(), a_BlockChange.GetY(), a_BlockChange.GetZ(), BedCallback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -211,19 +158,12 @@ void cBlockBedHandler::OnPlacedByPlayer(cChunkInterface & a_ChunkInterface, cWor
|
|||||||
|
|
||||||
void cBlockBedHandler::ConvertToPickups(cWorldInterface & a_WorldInterface, cItems & a_Pickups, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ)
|
void cBlockBedHandler::ConvertToPickups(cWorldInterface & a_WorldInterface, cItems & a_Pickups, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||||
{
|
{
|
||||||
class cBedColor :
|
short Color = E_META_WOOL_RED;
|
||||||
public cBedCallback
|
a_WorldInterface.DoWithBedAt(a_BlockX, a_BlockY, a_BlockZ, [&](cBedEntity & a_Bed)
|
||||||
{
|
|
||||||
public:
|
|
||||||
short m_Color = E_META_WOOL_RED;
|
|
||||||
|
|
||||||
virtual bool Item(cBedEntity * a_Bed) override
|
|
||||||
{
|
{
|
||||||
m_Color = a_Bed->GetColor();
|
Color = a_Bed.GetColor();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
);
|
||||||
cBedColor BedCallback;
|
a_Pickups.Add(cItem(E_ITEM_BED, 1, Color));
|
||||||
a_WorldInterface.DoWithBedAt(a_BlockX, a_BlockY, a_BlockZ, BedCallback);
|
|
||||||
a_Pickups.Add(cItem(E_ITEM_BED, 1, BedCallback.m_Color));
|
|
||||||
}
|
}
|
||||||
|
@ -30,36 +30,32 @@ public:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
class cCallback : public cBlockEntityCallback
|
a_WorldInterface.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ, [](cBlockEntity & a_BlockEntity)
|
||||||
{
|
|
||||||
virtual bool Item(cBlockEntity * a_BlockEntity)
|
|
||||||
{
|
{
|
||||||
if (a_BlockEntity->GetBlockType() != E_BLOCK_HEAD)
|
if (a_BlockEntity.GetBlockType() != E_BLOCK_HEAD)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
cMobHeadEntity * MobHeadEntity = static_cast<cMobHeadEntity*>(a_BlockEntity);
|
auto & MobHeadEntity = static_cast<cMobHeadEntity&>(a_BlockEntity);
|
||||||
|
|
||||||
cItems Pickups;
|
cItems Pickups;
|
||||||
Pickups.Add(E_ITEM_HEAD, 1, static_cast<short>(MobHeadEntity->GetType()));
|
Pickups.Add(E_ITEM_HEAD, 1, static_cast<short>(MobHeadEntity.GetType()));
|
||||||
auto & r1 = GetRandomProvider();
|
auto & r1 = GetRandomProvider();
|
||||||
|
|
||||||
// Mid-block position first
|
// Mid-block position first
|
||||||
double MicroX, MicroY, MicroZ;
|
double MicroX, MicroY, MicroZ;
|
||||||
MicroX = MobHeadEntity->GetPosX() + 0.5;
|
MicroX = MobHeadEntity.GetPosX() + 0.5;
|
||||||
MicroY = MobHeadEntity->GetPosY() + 0.5;
|
MicroY = MobHeadEntity.GetPosY() + 0.5;
|
||||||
MicroZ = MobHeadEntity->GetPosZ() + 0.5;
|
MicroZ = MobHeadEntity.GetPosZ() + 0.5;
|
||||||
|
|
||||||
// Add random offset second
|
// Add random offset second
|
||||||
MicroX += r1.RandReal<double>(-0.5, 0.5);
|
MicroX += r1.RandReal<double>(-0.5, 0.5);
|
||||||
MicroZ += r1.RandReal<double>(-0.5, 0.5);
|
MicroZ += r1.RandReal<double>(-0.5, 0.5);
|
||||||
|
|
||||||
MobHeadEntity->GetWorld()->SpawnItemPickups(Pickups, MicroX, MicroY, MicroZ);
|
MobHeadEntity.GetWorld()->SpawnItemPickups(Pickups, MicroX, MicroY, MicroZ);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} Callback;
|
);
|
||||||
|
|
||||||
a_WorldInterface.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ, Callback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
|
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
|
||||||
|
@ -1,15 +1,18 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "FunctionRef.h"
|
||||||
#include "../Mobs/MonsterTypes.h"
|
#include "../Mobs/MonsterTypes.h"
|
||||||
|
|
||||||
|
class cBedEntity;
|
||||||
typedef cItemCallback<cBlockEntity> cBlockEntityCallback;
|
class cBlockEntity;
|
||||||
class cBroadcastInterface;
|
class cBroadcastInterface;
|
||||||
class cItems;
|
class cItems;
|
||||||
class cPlayer;
|
class cPlayer;
|
||||||
|
|
||||||
|
using cBedCallback = cFunctionRef<bool(cBedEntity &)>;
|
||||||
|
using cBlockEntityCallback = cFunctionRef<bool(cBlockEntity &)>;
|
||||||
|
using cPlayerListCallback = cFunctionRef<bool(cPlayer &)>;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -28,7 +31,10 @@ public:
|
|||||||
|
|
||||||
virtual void DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, bool a_CanCauseFire, eExplosionSource a_Source, void * a_SourceData) = 0;
|
virtual void DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, bool a_CanCauseFire, eExplosionSource a_Source, void * a_SourceData) = 0;
|
||||||
|
|
||||||
virtual bool DoWithBedAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBedCallback & a_Callback) = 0;
|
virtual bool DoWithBedAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBedCallback a_Callback) = 0;
|
||||||
|
|
||||||
|
/** Calls the callback for the block entity at the specified coords; returns false if there's no block entity at those coords, true if found */
|
||||||
|
virtual bool DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback a_Callback) = 0;
|
||||||
|
|
||||||
/** Spawns item pickups for each item in the list. May compress pickups if too many entities: */
|
/** Spawns item pickups for each item in the list. May compress pickups if too many entities: */
|
||||||
virtual void SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_BlockY, double a_BlockZ, double a_FlyAwaySpeed = 1.0, bool IsPlayerCreated = false) = 0;
|
virtual void SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_BlockY, double a_BlockZ, double a_FlyAwaySpeed = 1.0, bool IsPlayerCreated = false) = 0;
|
||||||
@ -46,19 +52,16 @@ public:
|
|||||||
Returns the UniqueID of the spawned experience orb, or cEntity::INVALID_ID on failure. */
|
Returns the UniqueID of the spawned experience orb, or cEntity::INVALID_ID on failure. */
|
||||||
virtual UInt32 SpawnExperienceOrb(double a_X, double a_Y, double a_Z, int a_Reward) = 0;
|
virtual UInt32 SpawnExperienceOrb(double a_X, double a_Y, double a_Z, int a_Reward) = 0;
|
||||||
|
|
||||||
/** Calls the callback for the block entity at the specified coords; returns false if there's no block entity at those coords, true if found */
|
|
||||||
virtual bool DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback & a_Callback) = 0;
|
|
||||||
|
|
||||||
/** Sends the block on those coords to the player */
|
/** Sends the block on those coords to the player */
|
||||||
virtual void SendBlockTo(int a_BlockX, int a_BlockY, int a_BlockZ, cPlayer & a_Player) = 0;
|
virtual void SendBlockTo(int a_BlockX, int a_BlockY, int a_BlockZ, cPlayer & a_Player) = 0;
|
||||||
|
|
||||||
/** Calls the callback for each player in the list; returns true if all players processed, false if the callback aborted by returning true */
|
/** Calls the callback for each player in the list; returns true if all players processed, false if the callback aborted by returning true */
|
||||||
virtual bool ForEachPlayer(cItemCallback<cPlayer> & a_Callback) = 0;
|
virtual bool ForEachPlayer(cPlayerListCallback a_Callback) = 0;
|
||||||
|
|
||||||
/** Calls the callback for each entity that has a nonempty intersection with the specified boundingbox.
|
/** Calls the callback for each entity that has a nonempty intersection with the specified boundingbox.
|
||||||
Returns true if all entities processed, false if the callback aborted by returning true.
|
Returns true if all entities processed, false if the callback aborted by returning true.
|
||||||
If any chunk in the box is missing, ignores the entities in that chunk silently. */
|
If any chunk in the box is missing, ignores the entities in that chunk silently. */
|
||||||
virtual bool ForEachEntityInBox(const cBoundingBox & a_Box, cEntityCallback & a_Callback) = 0;
|
virtual bool ForEachEntityInBox(const cBoundingBox & a_Box, cEntityCallback a_Callback) = 0;
|
||||||
|
|
||||||
virtual void SetTimeOfDay(int a_TimeOfDay) = 0;
|
virtual void SetTimeOfDay(int a_TimeOfDay) = 0;
|
||||||
|
|
||||||
|
@ -112,6 +112,7 @@ SET (HDRS
|
|||||||
FastRandom.h
|
FastRandom.h
|
||||||
ForEachChunkProvider.h
|
ForEachChunkProvider.h
|
||||||
FurnaceRecipe.h
|
FurnaceRecipe.h
|
||||||
|
FunctionRef.h
|
||||||
Globals.h
|
Globals.h
|
||||||
IniFile.h
|
IniFile.h
|
||||||
Inventory.h
|
Inventory.h
|
||||||
|
@ -2114,17 +2114,12 @@ bool cChunk::HasEntity(UInt32 a_EntityID)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunk::ForEachEntity(cEntityCallback & a_Callback)
|
bool cChunk::ForEachEntity(cEntityCallback a_Callback)
|
||||||
{
|
{
|
||||||
// The entity list is locked by the parent chunkmap's CS
|
// The entity list is locked by the parent chunkmap's CS
|
||||||
for (auto itr = m_Entities.begin(), itr2 = itr; itr != m_Entities.end(); itr = itr2)
|
for (const auto & Entity : m_Entities)
|
||||||
{
|
{
|
||||||
++itr2;
|
if (Entity->IsTicking() && a_Callback(*Entity))
|
||||||
if (!(*itr)->IsTicking())
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (a_Callback.Item(itr->get()))
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -2136,23 +2131,22 @@ bool cChunk::ForEachEntity(cEntityCallback & a_Callback)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunk::ForEachEntityInBox(const cBoundingBox & a_Box, cEntityCallback & a_Callback)
|
bool cChunk::ForEachEntityInBox(const cBoundingBox & a_Box, cEntityCallback a_Callback)
|
||||||
{
|
{
|
||||||
// The entity list is locked by the parent chunkmap's CS
|
// The entity list is locked by the parent chunkmap's CS
|
||||||
for (auto itr = m_Entities.begin(), itr2 = itr; itr != m_Entities.end(); itr = itr2)
|
for (const auto & Entity : m_Entities)
|
||||||
{
|
{
|
||||||
++itr2;
|
if (!Entity->IsTicking())
|
||||||
if (!(*itr)->IsTicking())
|
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
cBoundingBox EntBox((*itr)->GetPosition(), (*itr)->GetWidth() / 2, (*itr)->GetHeight());
|
cBoundingBox EntBox(Entity->GetPosition(), Entity->GetWidth() / 2, Entity->GetHeight());
|
||||||
if (!EntBox.DoesIntersect(a_Box))
|
if (!EntBox.DoesIntersect(a_Box))
|
||||||
{
|
{
|
||||||
// The entity is not in the specified box
|
// The entity is not in the specified box
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (a_Callback.Item(itr->get()))
|
if (a_Callback(*Entity))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -2164,23 +2158,14 @@ bool cChunk::ForEachEntityInBox(const cBoundingBox & a_Box, cEntityCallback & a_
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunk::DoWithEntityByID(UInt32 a_EntityID, cEntityCallback & a_Callback, bool & a_CallbackResult)
|
bool cChunk::DoWithEntityByID(UInt32 a_EntityID, cEntityCallback a_Callback, bool & a_CallbackResult)
|
||||||
{
|
|
||||||
return DoWithEntityByID(a_EntityID, std::bind(&cEntityCallback::Item, &a_Callback, std::placeholders::_1), a_CallbackResult);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunk::DoWithEntityByID(UInt32 a_EntityID, cLambdaEntityCallback a_Callback, bool & a_CallbackResult)
|
|
||||||
{
|
{
|
||||||
// The entity list is locked by the parent chunkmap's CS
|
// The entity list is locked by the parent chunkmap's CS
|
||||||
for (const auto & Entity : m_Entities)
|
for (const auto & Entity : m_Entities)
|
||||||
{
|
{
|
||||||
if ((Entity->GetUniqueID() == a_EntityID) && (Entity->IsTicking()))
|
if ((Entity->GetUniqueID() == a_EntityID) && (Entity->IsTicking()))
|
||||||
{
|
{
|
||||||
a_CallbackResult = a_Callback(Entity.get());
|
a_CallbackResult = a_Callback(*Entity);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} // for itr - m_Entitites[]
|
} // for itr - m_Entitites[]
|
||||||
@ -2192,7 +2177,7 @@ bool cChunk::DoWithEntityByID(UInt32 a_EntityID, cLambdaEntityCallback a_Callbac
|
|||||||
|
|
||||||
|
|
||||||
template <class tyEntity, BLOCKTYPE... tBlocktype>
|
template <class tyEntity, BLOCKTYPE... tBlocktype>
|
||||||
bool cChunk::GenericForEachBlockEntity(cItemCallback<tyEntity>& a_Callback)
|
bool cChunk::GenericForEachBlockEntity(cFunctionRef<bool(tyEntity &)> a_Callback)
|
||||||
{
|
{
|
||||||
// The blockentity list is locked by the parent chunkmap's CS
|
// The blockentity list is locked by the parent chunkmap's CS
|
||||||
for (auto & KeyPair : m_BlockEntities)
|
for (auto & KeyPair : m_BlockEntities)
|
||||||
@ -2203,7 +2188,7 @@ bool cChunk::GenericForEachBlockEntity(cItemCallback<tyEntity>& a_Callback)
|
|||||||
(IsOneOf<tBlocktype...>(Block->GetBlockType()))
|
(IsOneOf<tBlocktype...>(Block->GetBlockType()))
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (a_Callback.Item(static_cast<tyEntity *>(Block)))
|
if (a_Callback(*static_cast<tyEntity *>(Block)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -2216,7 +2201,7 @@ bool cChunk::GenericForEachBlockEntity(cItemCallback<tyEntity>& a_Callback)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunk::ForEachBlockEntity(cBlockEntityCallback & a_Callback)
|
bool cChunk::ForEachBlockEntity(cBlockEntityCallback a_Callback)
|
||||||
{
|
{
|
||||||
return GenericForEachBlockEntity<cBlockEntity>(a_Callback);
|
return GenericForEachBlockEntity<cBlockEntity>(a_Callback);
|
||||||
}
|
}
|
||||||
@ -2225,7 +2210,7 @@ bool cChunk::ForEachBlockEntity(cBlockEntityCallback & a_Callback)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunk::ForEachBrewingstand(cBrewingstandCallback & a_Callback)
|
bool cChunk::ForEachBrewingstand(cBrewingstandCallback a_Callback)
|
||||||
{
|
{
|
||||||
return GenericForEachBlockEntity<cBrewingstandEntity,
|
return GenericForEachBlockEntity<cBrewingstandEntity,
|
||||||
E_BLOCK_BREWING_STAND
|
E_BLOCK_BREWING_STAND
|
||||||
@ -2236,7 +2221,7 @@ bool cChunk::ForEachBrewingstand(cBrewingstandCallback & a_Callback)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunk::ForEachChest(cChestCallback & a_Callback)
|
bool cChunk::ForEachChest(cChestCallback a_Callback)
|
||||||
{
|
{
|
||||||
return GenericForEachBlockEntity<cChestEntity,
|
return GenericForEachBlockEntity<cChestEntity,
|
||||||
E_BLOCK_CHEST
|
E_BLOCK_CHEST
|
||||||
@ -2247,7 +2232,7 @@ bool cChunk::ForEachChest(cChestCallback & a_Callback)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunk::ForEachDispenser(cDispenserCallback & a_Callback)
|
bool cChunk::ForEachDispenser(cDispenserCallback a_Callback)
|
||||||
{
|
{
|
||||||
return GenericForEachBlockEntity<cDispenserEntity,
|
return GenericForEachBlockEntity<cDispenserEntity,
|
||||||
E_BLOCK_DISPENSER
|
E_BLOCK_DISPENSER
|
||||||
@ -2258,7 +2243,7 @@ bool cChunk::ForEachDispenser(cDispenserCallback & a_Callback)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunk::ForEachDropper(cDropperCallback & a_Callback)
|
bool cChunk::ForEachDropper(cDropperCallback a_Callback)
|
||||||
{
|
{
|
||||||
return GenericForEachBlockEntity<cDropperEntity,
|
return GenericForEachBlockEntity<cDropperEntity,
|
||||||
E_BLOCK_DROPPER
|
E_BLOCK_DROPPER
|
||||||
@ -2269,7 +2254,7 @@ bool cChunk::ForEachDropper(cDropperCallback & a_Callback)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunk::ForEachDropSpenser(cDropSpenserCallback & a_Callback)
|
bool cChunk::ForEachDropSpenser(cDropSpenserCallback a_Callback)
|
||||||
{
|
{
|
||||||
return GenericForEachBlockEntity<cDropSpenserEntity,
|
return GenericForEachBlockEntity<cDropSpenserEntity,
|
||||||
E_BLOCK_DISPENSER,
|
E_BLOCK_DISPENSER,
|
||||||
@ -2281,7 +2266,7 @@ bool cChunk::ForEachDropSpenser(cDropSpenserCallback & a_Callback)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunk::ForEachFurnace(cFurnaceCallback & a_Callback)
|
bool cChunk::ForEachFurnace(cFurnaceCallback a_Callback)
|
||||||
{
|
{
|
||||||
return GenericForEachBlockEntity<cFurnaceEntity,
|
return GenericForEachBlockEntity<cFurnaceEntity,
|
||||||
E_BLOCK_FURNACE,
|
E_BLOCK_FURNACE,
|
||||||
@ -2294,7 +2279,7 @@ bool cChunk::ForEachFurnace(cFurnaceCallback & a_Callback)
|
|||||||
|
|
||||||
|
|
||||||
template <class tyEntity, BLOCKTYPE... tBlocktype>
|
template <class tyEntity, BLOCKTYPE... tBlocktype>
|
||||||
bool cChunk::GenericDoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cItemCallback<tyEntity>& a_Callback)
|
bool cChunk::GenericDoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFunctionRef<bool(tyEntity &)> a_Callback)
|
||||||
{
|
{
|
||||||
// The blockentity list is locked by the parent chunkmap's CS
|
// The blockentity list is locked by the parent chunkmap's CS
|
||||||
cBlockEntity * Block = GetBlockEntity(a_BlockX, a_BlockY, a_BlockZ);
|
cBlockEntity * Block = GetBlockEntity(a_BlockX, a_BlockY, a_BlockZ);
|
||||||
@ -2309,14 +2294,14 @@ bool cChunk::GenericDoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ
|
|||||||
{
|
{
|
||||||
return false; // Not any of the given tBlocktypes
|
return false; // Not any of the given tBlocktypes
|
||||||
}
|
}
|
||||||
return !a_Callback.Item(static_cast<tyEntity *>(Block));
|
return !a_Callback(*static_cast<tyEntity *>(Block));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunk::DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback & a_Callback)
|
bool cChunk::DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback a_Callback)
|
||||||
{
|
{
|
||||||
return GenericDoWithBlockEntityAt<cBlockEntity>(a_BlockX, a_BlockY, a_BlockZ, a_Callback);
|
return GenericDoWithBlockEntityAt<cBlockEntity>(a_BlockX, a_BlockY, a_BlockZ, a_Callback);
|
||||||
}
|
}
|
||||||
@ -2324,7 +2309,7 @@ bool cChunk::DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBloc
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunk::DoWithBeaconAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconCallback & a_Callback)
|
bool cChunk::DoWithBeaconAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconCallback a_Callback)
|
||||||
{
|
{
|
||||||
return GenericDoWithBlockEntityAt<cBeaconEntity,
|
return GenericDoWithBlockEntityAt<cBeaconEntity,
|
||||||
E_BLOCK_BEACON
|
E_BLOCK_BEACON
|
||||||
@ -2334,7 +2319,7 @@ bool cChunk::DoWithBeaconAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconCal
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunk::DoWithBedAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBedCallback & a_Callback)
|
bool cChunk::DoWithBedAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBedCallback a_Callback)
|
||||||
{
|
{
|
||||||
return GenericDoWithBlockEntityAt<cBedEntity,
|
return GenericDoWithBlockEntityAt<cBedEntity,
|
||||||
E_BLOCK_BED
|
E_BLOCK_BED
|
||||||
@ -2344,7 +2329,7 @@ bool cChunk::DoWithBedAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBedCallback
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunk::DoWithBrewingstandAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBrewingstandCallback & a_Callback)
|
bool cChunk::DoWithBrewingstandAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBrewingstandCallback a_Callback)
|
||||||
{
|
{
|
||||||
return GenericDoWithBlockEntityAt<cBrewingstandEntity,
|
return GenericDoWithBlockEntityAt<cBrewingstandEntity,
|
||||||
E_BLOCK_BREWING_STAND
|
E_BLOCK_BREWING_STAND
|
||||||
@ -2355,7 +2340,7 @@ bool cChunk::DoWithBrewingstandAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBre
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunk::DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallback & a_Callback)
|
bool cChunk::DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallback a_Callback)
|
||||||
{
|
{
|
||||||
return GenericDoWithBlockEntityAt<cChestEntity,
|
return GenericDoWithBlockEntityAt<cChestEntity,
|
||||||
E_BLOCK_CHEST,
|
E_BLOCK_CHEST,
|
||||||
@ -2367,7 +2352,7 @@ bool cChunk::DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallb
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunk::DoWithDispenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDispenserCallback & a_Callback)
|
bool cChunk::DoWithDispenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDispenserCallback a_Callback)
|
||||||
{
|
{
|
||||||
return GenericDoWithBlockEntityAt<cDispenserEntity,
|
return GenericDoWithBlockEntityAt<cDispenserEntity,
|
||||||
E_BLOCK_DISPENSER
|
E_BLOCK_DISPENSER
|
||||||
@ -2378,7 +2363,7 @@ bool cChunk::DoWithDispenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDispen
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunk::DoWithDropperAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDropperCallback & a_Callback)
|
bool cChunk::DoWithDropperAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDropperCallback a_Callback)
|
||||||
{
|
{
|
||||||
return GenericDoWithBlockEntityAt<cDropperEntity,
|
return GenericDoWithBlockEntityAt<cDropperEntity,
|
||||||
E_BLOCK_DROPPER
|
E_BLOCK_DROPPER
|
||||||
@ -2389,7 +2374,7 @@ bool cChunk::DoWithDropperAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDropperC
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunk::DoWithDropSpenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDropSpenserCallback & a_Callback)
|
bool cChunk::DoWithDropSpenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDropSpenserCallback a_Callback)
|
||||||
{
|
{
|
||||||
return GenericDoWithBlockEntityAt<cDropSpenserEntity,
|
return GenericDoWithBlockEntityAt<cDropSpenserEntity,
|
||||||
E_BLOCK_DISPENSER,
|
E_BLOCK_DISPENSER,
|
||||||
@ -2401,7 +2386,7 @@ bool cChunk::DoWithDropSpenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDrop
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunk::DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceCallback & a_Callback)
|
bool cChunk::DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceCallback a_Callback)
|
||||||
{
|
{
|
||||||
return GenericDoWithBlockEntityAt<cFurnaceEntity,
|
return GenericDoWithBlockEntityAt<cFurnaceEntity,
|
||||||
E_BLOCK_FURNACE,
|
E_BLOCK_FURNACE,
|
||||||
@ -2413,7 +2398,7 @@ bool cChunk::DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceC
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunk::DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNoteBlockCallback & a_Callback)
|
bool cChunk::DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNoteBlockCallback a_Callback)
|
||||||
{
|
{
|
||||||
return GenericDoWithBlockEntityAt<cNoteEntity,
|
return GenericDoWithBlockEntityAt<cNoteEntity,
|
||||||
E_BLOCK_NOTE_BLOCK
|
E_BLOCK_NOTE_BLOCK
|
||||||
@ -2424,7 +2409,7 @@ bool cChunk::DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNoteBl
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunk::DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cCommandBlockCallback & a_Callback)
|
bool cChunk::DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cCommandBlockCallback a_Callback)
|
||||||
{
|
{
|
||||||
return GenericDoWithBlockEntityAt<cCommandBlockEntity,
|
return GenericDoWithBlockEntityAt<cCommandBlockEntity,
|
||||||
E_BLOCK_COMMAND_BLOCK
|
E_BLOCK_COMMAND_BLOCK
|
||||||
@ -2435,7 +2420,7 @@ bool cChunk::DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cCom
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunk::DoWithMobHeadAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadCallback & a_Callback)
|
bool cChunk::DoWithMobHeadAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadCallback a_Callback)
|
||||||
{
|
{
|
||||||
return GenericDoWithBlockEntityAt<cMobHeadEntity,
|
return GenericDoWithBlockEntityAt<cMobHeadEntity,
|
||||||
E_BLOCK_HEAD
|
E_BLOCK_HEAD
|
||||||
@ -2446,7 +2431,7 @@ bool cChunk::DoWithMobHeadAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadC
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunk::DoWithFlowerPotAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFlowerPotCallback & a_Callback)
|
bool cChunk::DoWithFlowerPotAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFlowerPotCallback a_Callback)
|
||||||
{
|
{
|
||||||
return GenericDoWithBlockEntityAt<cFlowerPotEntity,
|
return GenericDoWithBlockEntityAt<cFlowerPotEntity,
|
||||||
E_BLOCK_FLOWER_POT
|
E_BLOCK_FLOWER_POT
|
||||||
|
64
src/Chunk.h
64
src/Chunk.h
@ -37,18 +37,7 @@ class cMobCensus;
|
|||||||
class cMobSpawner;
|
class cMobSpawner;
|
||||||
class cSetChunkData;
|
class cSetChunkData;
|
||||||
|
|
||||||
typedef std::list<cClientHandle *> cClientHandleList;
|
typedef std::list<cClientHandle *> cClientHandleList;
|
||||||
typedef cItemCallback<cEntity> cEntityCallback;
|
|
||||||
typedef cItemCallback<cBeaconEntity> cBeaconCallback;
|
|
||||||
typedef cItemCallback<cBedEntity> cBedCallback;
|
|
||||||
typedef cItemCallback<cBrewingstandEntity> cBrewingstandCallback;
|
|
||||||
typedef cItemCallback<cChestEntity> cChestCallback;
|
|
||||||
typedef cItemCallback<cDispenserEntity> cDispenserCallback;
|
|
||||||
typedef cItemCallback<cFurnaceEntity> cFurnaceCallback;
|
|
||||||
typedef cItemCallback<cNoteEntity> cNoteBlockCallback;
|
|
||||||
typedef cItemCallback<cCommandBlockEntity> cCommandBlockCallback;
|
|
||||||
typedef cItemCallback<cMobHeadEntity> cMobHeadCallback;
|
|
||||||
typedef cItemCallback<cFlowerPotEntity> cFlowerPotCallback;
|
|
||||||
|
|
||||||
// A convenience macro for calling GetChunkAndRelByAbsolute.
|
// A convenience macro for calling GetChunkAndRelByAbsolute.
|
||||||
#define PREPARE_REL_AND_CHUNK(Position, OriginalChunk) cChunk * Chunk; Vector3i Rel; bool RelSuccess = (OriginalChunk).GetChunkAndRelByAbsolute(Position, &Chunk, Rel);
|
#define PREPARE_REL_AND_CHUNK(Position, OriginalChunk) cChunk * Chunk; Vector3i Rel; bool RelSuccess = (OriginalChunk).GetChunkAndRelByAbsolute(Position, &Chunk, Rel);
|
||||||
@ -258,87 +247,86 @@ public:
|
|||||||
bool HasEntity(UInt32 a_EntityID);
|
bool HasEntity(UInt32 a_EntityID);
|
||||||
|
|
||||||
/** Calls the callback for each entity; returns true if all entities processed, false if the callback aborted by returning true */
|
/** Calls the callback for each entity; returns true if all entities processed, false if the callback aborted by returning true */
|
||||||
bool ForEachEntity(cEntityCallback & a_Callback); // Lua-accessible
|
bool ForEachEntity(cEntityCallback a_Callback); // Lua-accessible
|
||||||
|
|
||||||
/** Calls the callback for each entity that has a nonempty intersection with the specified boundingbox.
|
/** Calls the callback for each entity that has a nonempty intersection with the specified boundingbox.
|
||||||
Returns true if all entities processed, false if the callback aborted by returning true. */
|
Returns true if all entities processed, false if the callback aborted by returning true. */
|
||||||
bool ForEachEntityInBox(const cBoundingBox & a_Box, cEntityCallback & a_Callback); // Lua-accessible
|
bool ForEachEntityInBox(const cBoundingBox & a_Box, cEntityCallback a_Callback); // Lua-accessible
|
||||||
|
|
||||||
/** Calls the callback if the entity with the specified ID is found, with the entity object as the callback param. Returns true if entity found. */
|
/** Calls the callback if the entity with the specified ID is found, with the entity object as the callback param. Returns true if entity found. */
|
||||||
bool DoWithEntityByID(UInt32 a_EntityID, cEntityCallback & a_Callback, bool & a_CallbackResult); // Lua-accessible
|
bool DoWithEntityByID(UInt32 a_EntityID, cEntityCallback a_Callback, bool & a_CallbackResult); // Lua-accessible
|
||||||
bool DoWithEntityByID(UInt32 a_EntityID, cLambdaEntityCallback a_Callback, bool & a_CallbackResult); // Lambda version
|
|
||||||
|
|
||||||
/** Calls the callback for each tyEntity; returns true if all block entities processed, false if the callback aborted by returning true
|
/** Calls the callback for each tyEntity; returns true if all block entities processed, false if the callback aborted by returning true
|
||||||
tBlocktypes are all blocktypes convertible to tyEntity which are to be called. If no block type is given the callback is called for every block entity
|
tBlocktypes are all blocktypes convertible to tyEntity which are to be called. If no block type is given the callback is called for every block entity
|
||||||
Accessible only from within Chunk.cpp */
|
Accessible only from within Chunk.cpp */
|
||||||
template <class tyEntity, BLOCKTYPE... tBlocktype>
|
template <class tyEntity, BLOCKTYPE... tBlocktype>
|
||||||
bool GenericForEachBlockEntity(cItemCallback<tyEntity>& a_Callback);
|
bool GenericForEachBlockEntity(cFunctionRef<bool(tyEntity &)> a_Callback);
|
||||||
|
|
||||||
/** Calls the callback for each block entity; returns true if all block entities processed, false if the callback aborted by returning true */
|
/** Calls the callback for each block entity; returns true if all block entities processed, false if the callback aborted by returning true */
|
||||||
bool ForEachBlockEntity(cBlockEntityCallback & a_Callback); // Lua-accessible
|
bool ForEachBlockEntity(cBlockEntityCallback a_Callback); // Lua-accessible
|
||||||
|
|
||||||
/** Calls the callback for each brewingstand; returns true if all brewingstands processed, false if the callback aborted by returning true */
|
/** Calls the callback for each brewingstand; returns true if all brewingstands processed, false if the callback aborted by returning true */
|
||||||
bool ForEachBrewingstand(cBrewingstandCallback & a_Callback); // Lua-accessible
|
bool ForEachBrewingstand(cBrewingstandCallback a_Callback); // Lua-accessible
|
||||||
|
|
||||||
/** Calls the callback for each chest; returns true if all chests processed, false if the callback aborted by returning true */
|
/** Calls the callback for each chest; returns true if all chests processed, false if the callback aborted by returning true */
|
||||||
bool ForEachChest(cChestCallback & a_Callback); // Lua-accessible
|
bool ForEachChest(cChestCallback a_Callback); // Lua-accessible
|
||||||
|
|
||||||
/** Calls the callback for each dispenser; returns true if all dispensers processed, false if the callback aborted by returning true */
|
/** Calls the callback for each dispenser; returns true if all dispensers processed, false if the callback aborted by returning true */
|
||||||
bool ForEachDispenser(cDispenserCallback & a_Callback);
|
bool ForEachDispenser(cDispenserCallback a_Callback);
|
||||||
|
|
||||||
/** Calls the callback for each dropper; returns true if all droppers processed, false if the callback aborted by returning true */
|
/** Calls the callback for each dropper; returns true if all droppers processed, false if the callback aborted by returning true */
|
||||||
bool ForEachDropper(cDropperCallback & a_Callback);
|
bool ForEachDropper(cDropperCallback a_Callback);
|
||||||
|
|
||||||
/** Calls the callback for each dropspenser; returns true if all dropspensers processed, false if the callback aborted by returning true */
|
/** Calls the callback for each dropspenser; returns true if all dropspensers processed, false if the callback aborted by returning true */
|
||||||
bool ForEachDropSpenser(cDropSpenserCallback & a_Callback);
|
bool ForEachDropSpenser(cDropSpenserCallback a_Callback);
|
||||||
|
|
||||||
/** Calls the callback for each furnace; returns true if all furnaces processed, false if the callback aborted by returning true */
|
/** Calls the callback for each furnace; returns true if all furnaces processed, false if the callback aborted by returning true */
|
||||||
bool ForEachFurnace(cFurnaceCallback & a_Callback); // Lua-accessible
|
bool ForEachFurnace(cFurnaceCallback a_Callback); // Lua-accessible
|
||||||
|
|
||||||
/** Calls the callback for the tyEntity at the specified coords; returns false if there's no such block entity at those coords, true if found
|
/** Calls the callback for the tyEntity at the specified coords; returns false if there's no such block entity at those coords, true if found
|
||||||
tBlocktype is a list of the blocktypes to be called. If no BLOCKTYPE template arguments are given the callback is called for any block entity
|
tBlocktype is a list of the blocktypes to be called. If no BLOCKTYPE template arguments are given the callback is called for any block entity
|
||||||
Accessible only from within Chunk.cpp */
|
Accessible only from within Chunk.cpp */
|
||||||
template <class tyEntity, BLOCKTYPE... tBlocktype>
|
template <class tyEntity, BLOCKTYPE... tBlocktype>
|
||||||
bool GenericDoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cItemCallback<tyEntity>& a_Callback);
|
bool GenericDoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFunctionRef<bool(tyEntity &)> a_Callback);
|
||||||
|
|
||||||
/** Calls the callback for the block entity at the specified coords; returns false if there's no block entity at those coords, true if found */
|
/** Calls the callback for the block entity at the specified coords; returns false if there's no block entity at those coords, true if found */
|
||||||
bool DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback & a_Callback); // Lua-acessible
|
bool DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback a_Callback); // Lua-acessible
|
||||||
|
|
||||||
/** Calls the callback for the beacon at the specified coords; returns false if there's no beacon at those coords, true if found */
|
/** Calls the callback for the beacon at the specified coords; returns false if there's no beacon at those coords, true if found */
|
||||||
bool DoWithBeaconAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconCallback & a_Callback); // Lua-acessible
|
bool DoWithBeaconAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconCallback a_Callback); // Lua-acessible
|
||||||
|
|
||||||
/** Calls the callback for the brewingstand at the specified coords; returns false if there's no brewingstand at those coords, true if found */
|
/** Calls the callback for the brewingstand at the specified coords; returns false if there's no brewingstand at those coords, true if found */
|
||||||
bool DoWithBrewingstandAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBrewingstandCallback & a_Callback); // Lua-acessible
|
bool DoWithBrewingstandAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBrewingstandCallback a_Callback); // Lua-acessible
|
||||||
|
|
||||||
/** Calls the callback for the bed at the specified coords; returns false if there's no bed at those coords, true if found */
|
/** Calls the callback for the bed at the specified coords; returns false if there's no bed at those coords, true if found */
|
||||||
bool DoWithBedAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBedCallback & a_Callback); // Lua-acessible
|
bool DoWithBedAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBedCallback a_Callback); // Lua-acessible
|
||||||
|
|
||||||
/** Calls the callback for the chest at the specified coords; returns false if there's no chest at those coords, true if found */
|
/** Calls the callback for the chest at the specified coords; returns false if there's no chest at those coords, true if found */
|
||||||
bool DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallback & a_Callback); // Lua-acessible
|
bool DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallback a_Callback); // Lua-acessible
|
||||||
|
|
||||||
/** Calls the callback for the dispenser at the specified coords; returns false if there's no dispenser at those coords or callback returns true, returns true if found */
|
/** Calls the callback for the dispenser at the specified coords; returns false if there's no dispenser at those coords or callback returns true, returns true if found */
|
||||||
bool DoWithDispenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDispenserCallback & a_Callback);
|
bool DoWithDispenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDispenserCallback a_Callback);
|
||||||
|
|
||||||
/** Calls the callback for the dispenser at the specified coords; returns false if there's no dropper at those coords or callback returns true, returns true if found */
|
/** Calls the callback for the dispenser at the specified coords; returns false if there's no dropper at those coords or callback returns true, returns true if found */
|
||||||
bool DoWithDropperAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDropperCallback & a_Callback);
|
bool DoWithDropperAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDropperCallback a_Callback);
|
||||||
|
|
||||||
/** Calls the callback for the dispenser at the specified coords; returns false if there's no dropspenser at those coords or callback returns true, returns true if found */
|
/** Calls the callback for the dispenser at the specified coords; returns false if there's no dropspenser at those coords or callback returns true, returns true if found */
|
||||||
bool DoWithDropSpenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDropSpenserCallback & a_Callback);
|
bool DoWithDropSpenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDropSpenserCallback a_Callback);
|
||||||
|
|
||||||
/** Calls the callback for the furnace at the specified coords; returns false if there's no furnace at those coords or callback returns true, returns true if found */
|
/** Calls the callback for the furnace at the specified coords; returns false if there's no furnace at those coords or callback returns true, returns true if found */
|
||||||
bool DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceCallback & a_Callback); // Lua-accessible
|
bool DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceCallback a_Callback); // Lua-accessible
|
||||||
|
|
||||||
/** Calls the callback for the noteblock at the specified coords; returns false if there's no noteblock at those coords or callback returns true, returns true if found */
|
/** Calls the callback for the noteblock at the specified coords; returns false if there's no noteblock at those coords or callback returns true, returns true if found */
|
||||||
bool DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNoteBlockCallback & a_Callback);
|
bool DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNoteBlockCallback a_Callback);
|
||||||
|
|
||||||
/** Calls the callback for the command block at the specified coords; returns false if there's no command block at those coords or callback returns true, returns true if found */
|
/** Calls the callback for the command block at the specified coords; returns false if there's no command block at those coords or callback returns true, returns true if found */
|
||||||
bool DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cCommandBlockCallback & a_Callback);
|
bool DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cCommandBlockCallback a_Callback);
|
||||||
|
|
||||||
/** Calls the callback for the mob head block at the specified coords; returns false if there's no mob head block at those coords or callback returns true, returns true if found */
|
/** Calls the callback for the mob head block at the specified coords; returns false if there's no mob head block at those coords or callback returns true, returns true if found */
|
||||||
bool DoWithMobHeadAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadCallback & a_Callback);
|
bool DoWithMobHeadAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadCallback a_Callback);
|
||||||
|
|
||||||
/** Calls the callback for the flower pot at the specified coords; returns false if there's no flower pot at those coords or callback returns true, returns true if found */
|
/** Calls the callback for the flower pot at the specified coords; returns false if there's no flower pot at those coords or callback returns true, returns true if found */
|
||||||
bool DoWithFlowerPotAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFlowerPotCallback & a_Callback);
|
bool DoWithFlowerPotAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFlowerPotCallback a_Callback);
|
||||||
|
|
||||||
/** Retrieves the test on the sign at the specified coords; returns false if there's no sign at those coords, true if found */
|
/** Retrieves the test on the sign at the specified coords; returns false if there's no sign at those coords, true if found */
|
||||||
bool GetSignLines (int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4); // Lua-accessible
|
bool GetSignLines (int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4); // Lua-accessible
|
||||||
|
127
src/ChunkMap.cpp
127
src/ChunkMap.cpp
@ -731,7 +731,7 @@ bool cChunkMap::UseBlockEntity(cPlayer * a_Player, int a_BlockX, int a_BlockY, i
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunkMap::DoWithChunk(int a_ChunkX, int a_ChunkZ, cChunkCallback & a_Callback)
|
bool cChunkMap::DoWithChunk(int a_ChunkX, int a_ChunkZ, cChunkCallback a_Callback)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSChunks);
|
cCSLock Lock(m_CSChunks);
|
||||||
cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkZ);
|
cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkZ);
|
||||||
@ -739,30 +739,15 @@ bool cChunkMap::DoWithChunk(int a_ChunkX, int a_ChunkZ, cChunkCallback & a_Callb
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return a_Callback.Item(Chunk);
|
return a_Callback(*Chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool cChunkMap::DoWithChunkAt(Vector3i a_BlockPos, std::function<bool(cChunk &)> a_Callback)
|
bool cChunkMap::DoWithChunkAt(Vector3i a_BlockPos, cChunkCallback a_Callback)
|
||||||
{
|
{
|
||||||
int ChunkX, ChunkZ;
|
int ChunkX, ChunkZ;
|
||||||
cChunkDef::BlockToChunk(a_BlockPos.x, a_BlockPos.z, ChunkX, ChunkZ);
|
cChunkDef::BlockToChunk(a_BlockPos.x, a_BlockPos.z, ChunkX, ChunkZ);
|
||||||
struct cCallBackWrapper : cChunkCallback
|
return DoWithChunk(ChunkX, ChunkZ, a_Callback);
|
||||||
{
|
|
||||||
cCallBackWrapper(std::function<bool(cChunk &)> a_InnerCallback) :
|
|
||||||
m_Callback(a_InnerCallback)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool Item(cChunk * a_Chunk)
|
|
||||||
{
|
|
||||||
return m_Callback(*a_Chunk);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::function<bool(cChunk &)> m_Callback;
|
|
||||||
} callback(a_Callback);
|
|
||||||
return DoWithChunk(ChunkX, ChunkZ, callback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1598,7 +1583,7 @@ OwnedEntity cChunkMap::RemoveEntity(cEntity & a_Entity)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunkMap::ForEachEntity(cEntityCallback & a_Callback)
|
bool cChunkMap::ForEachEntity(cEntityCallback a_Callback)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSChunks);
|
cCSLock Lock(m_CSChunks);
|
||||||
for (const auto & Chunk : m_Chunks)
|
for (const auto & Chunk : m_Chunks)
|
||||||
@ -1615,7 +1600,7 @@ bool cChunkMap::ForEachEntity(cEntityCallback & a_Callback)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunkMap::ForEachEntityInChunk(int a_ChunkX, int a_ChunkZ, cEntityCallback & a_Callback)
|
bool cChunkMap::ForEachEntityInChunk(int a_ChunkX, int a_ChunkZ, cEntityCallback a_Callback)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSChunks);
|
cCSLock Lock(m_CSChunks);
|
||||||
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ);
|
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ);
|
||||||
@ -1630,7 +1615,7 @@ bool cChunkMap::ForEachEntityInChunk(int a_ChunkX, int a_ChunkZ, cEntityCallback
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunkMap::ForEachEntityInBox(const cBoundingBox & a_Box, cEntityCallback & a_Callback)
|
bool cChunkMap::ForEachEntityInBox(const cBoundingBox & a_Box, cEntityCallback a_Callback)
|
||||||
{
|
{
|
||||||
// Calculate the chunk range for the box:
|
// Calculate the chunk range for the box:
|
||||||
int MinChunkX = FloorC(a_Box.GetMinX() / cChunkDef::Width);
|
int MinChunkX = FloorC(a_Box.GetMinX() / cChunkDef::Width);
|
||||||
@ -1792,60 +1777,41 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_
|
|||||||
area.Write(*m_World, bx - ExplosionSizeInt, MinY, bz - ExplosionSizeInt);
|
area.Write(*m_World, bx - ExplosionSizeInt, MinY, bz - ExplosionSizeInt);
|
||||||
}
|
}
|
||||||
|
|
||||||
class cTNTDamageCallback :
|
Vector3d ExplosionPos{ a_BlockX, a_BlockY, a_BlockZ };
|
||||||
public cEntityCallback
|
cBoundingBox bbTNT(ExplosionPos, 0.5, 1);
|
||||||
{
|
bbTNT.Expand(ExplosionSizeInt * 2, ExplosionSizeInt * 2, ExplosionSizeInt * 2);
|
||||||
public:
|
|
||||||
cTNTDamageCallback(cBoundingBox & a_CBBBTNT, Vector3d a_CBExplosionPos, int a_CBExplosionSize) :
|
|
||||||
m_bbTNT(a_CBBBTNT),
|
|
||||||
m_ExplosionPos(a_CBExplosionPos),
|
|
||||||
m_ExplosionSize(a_CBExplosionSize)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool Item(cEntity * a_Entity) override
|
ForEachEntity([&](cEntity & a_Entity)
|
||||||
{
|
{
|
||||||
if (a_Entity->IsPickup() && (a_Entity->GetTicksAlive() < 20))
|
if (a_Entity.IsPickup() && (a_Entity.GetTicksAlive() < 20))
|
||||||
{
|
{
|
||||||
// If pickup age is smaller than one second, it is invincible (so we don't kill pickups that were just spawned)
|
// If pickup age is smaller than one second, it is invincible (so we don't kill pickups that were just spawned)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3d DistanceFromExplosion = a_Entity->GetPosition() - m_ExplosionPos;
|
Vector3d DistanceFromExplosion = a_Entity.GetPosition() - ExplosionPos;
|
||||||
|
|
||||||
if (!a_Entity->IsTNT() && !a_Entity->IsFallingBlock()) // Don't apply damage to other TNT entities and falling blocks, they should be invincible
|
if (!a_Entity.IsTNT() && !a_Entity.IsFallingBlock()) // Don't apply damage to other TNT entities and falling blocks, they should be invincible
|
||||||
{
|
{
|
||||||
cBoundingBox bbEntity(a_Entity->GetPosition(), a_Entity->GetWidth() / 2, a_Entity->GetHeight());
|
cBoundingBox bbEntity(a_Entity.GetPosition(), a_Entity.GetWidth() / 2, a_Entity.GetHeight());
|
||||||
|
|
||||||
if (!m_bbTNT.IsInside(bbEntity)) // If bbEntity is inside bbTNT, not vice versa!
|
if (!bbTNT.IsInside(bbEntity)) // If bbEntity is inside bbTNT, not vice versa!
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure that the damage dealt is inversely proportional to the distance to the TNT centre - the closer a player is, the harder they are hit
|
// Ensure that the damage dealt is inversely proportional to the distance to the TNT centre - the closer a player is, the harder they are hit
|
||||||
a_Entity->TakeDamage(dtExplosion, nullptr, static_cast<int>((1 / DistanceFromExplosion.Length()) * 6 * m_ExplosionSize), 0);
|
a_Entity.TakeDamage(dtExplosion, nullptr, static_cast<int>((1 / DistanceFromExplosion.Length()) * 6 * ExplosionSizeInt), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply force to entities around the explosion - code modified from World.cpp DoExplosionAt()
|
// Apply force to entities around the explosion - code modified from World.cpp DoExplosionAt()
|
||||||
DistanceFromExplosion.Normalize();
|
DistanceFromExplosion.Normalize();
|
||||||
DistanceFromExplosion *= m_ExplosionSize * m_ExplosionSize;
|
DistanceFromExplosion *= ExplosionSizeInt * ExplosionSizeInt;
|
||||||
a_Entity->AddSpeed(DistanceFromExplosion);
|
a_Entity.AddSpeed(DistanceFromExplosion);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
);
|
||||||
protected:
|
|
||||||
cBoundingBox & m_bbTNT;
|
|
||||||
Vector3d m_ExplosionPos;
|
|
||||||
int m_ExplosionSize;
|
|
||||||
};
|
|
||||||
|
|
||||||
cBoundingBox bbTNT(Vector3d(a_BlockX, a_BlockY, a_BlockZ), 0.5, 1);
|
|
||||||
bbTNT.Expand(ExplosionSizeInt * 2, ExplosionSizeInt * 2, ExplosionSizeInt * 2);
|
|
||||||
|
|
||||||
|
|
||||||
cTNTDamageCallback TNTDamageCallback(bbTNT, Vector3d(a_BlockX, a_BlockY, a_BlockZ), ExplosionSizeInt);
|
|
||||||
ForEachEntity(TNTDamageCallback);
|
|
||||||
|
|
||||||
// Wake up all simulators for the area, so that water and lava flows and sand falls into the blasted holes (FS #391):
|
// Wake up all simulators for the area, so that water and lava flows and sand falls into the blasted holes (FS #391):
|
||||||
m_World->GetSimulatorManager()->WakeUpArea(cCuboid(
|
m_World->GetSimulatorManager()->WakeUpArea(cCuboid(
|
||||||
@ -1858,16 +1824,7 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunkMap::DoWithEntityByID(UInt32 a_UniqueID, cEntityCallback & a_Callback)
|
bool cChunkMap::DoWithEntityByID(UInt32 a_UniqueID, cEntityCallback a_Callback)
|
||||||
{
|
|
||||||
return DoWithEntityByID(a_UniqueID, std::bind(&cEntityCallback::Item, &a_Callback, std::placeholders::_1));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunkMap::DoWithEntityByID(UInt32 a_UniqueID, cLambdaEntityCallback a_Callback)
|
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSChunks);
|
cCSLock Lock(m_CSChunks);
|
||||||
bool res = false;
|
bool res = false;
|
||||||
@ -1885,7 +1842,7 @@ bool cChunkMap::DoWithEntityByID(UInt32 a_UniqueID, cLambdaEntityCallback a_Call
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunkMap::ForEachBlockEntityInChunk(int a_ChunkX, int a_ChunkZ, cBlockEntityCallback & a_Callback)
|
bool cChunkMap::ForEachBlockEntityInChunk(int a_ChunkX, int a_ChunkZ, cBlockEntityCallback a_Callback)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSChunks);
|
cCSLock Lock(m_CSChunks);
|
||||||
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ);
|
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ);
|
||||||
@ -1900,7 +1857,7 @@ bool cChunkMap::ForEachBlockEntityInChunk(int a_ChunkX, int a_ChunkZ, cBlockEnti
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunkMap::ForEachBrewingstandInChunk(int a_ChunkX, int a_ChunkZ, cBrewingstandCallback & a_Callback)
|
bool cChunkMap::ForEachBrewingstandInChunk(int a_ChunkX, int a_ChunkZ, cBrewingstandCallback a_Callback)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSChunks);
|
cCSLock Lock(m_CSChunks);
|
||||||
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ);
|
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ);
|
||||||
@ -1915,7 +1872,7 @@ bool cChunkMap::ForEachBrewingstandInChunk(int a_ChunkX, int a_ChunkZ, cBrewings
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunkMap::ForEachChestInChunk(int a_ChunkX, int a_ChunkZ, cChestCallback & a_Callback)
|
bool cChunkMap::ForEachChestInChunk(int a_ChunkX, int a_ChunkZ, cChestCallback a_Callback)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSChunks);
|
cCSLock Lock(m_CSChunks);
|
||||||
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ);
|
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ);
|
||||||
@ -1930,7 +1887,7 @@ bool cChunkMap::ForEachChestInChunk(int a_ChunkX, int a_ChunkZ, cChestCallback &
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunkMap::ForEachDispenserInChunk(int a_ChunkX, int a_ChunkZ, cDispenserCallback & a_Callback)
|
bool cChunkMap::ForEachDispenserInChunk(int a_ChunkX, int a_ChunkZ, cDispenserCallback a_Callback)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSChunks);
|
cCSLock Lock(m_CSChunks);
|
||||||
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ);
|
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ);
|
||||||
@ -1945,7 +1902,7 @@ bool cChunkMap::ForEachDispenserInChunk(int a_ChunkX, int a_ChunkZ, cDispenserCa
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunkMap::ForEachDropperInChunk(int a_ChunkX, int a_ChunkZ, cDropperCallback & a_Callback)
|
bool cChunkMap::ForEachDropperInChunk(int a_ChunkX, int a_ChunkZ, cDropperCallback a_Callback)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSChunks);
|
cCSLock Lock(m_CSChunks);
|
||||||
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ);
|
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ);
|
||||||
@ -1960,7 +1917,7 @@ bool cChunkMap::ForEachDropperInChunk(int a_ChunkX, int a_ChunkZ, cDropperCallba
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunkMap::ForEachDropSpenserInChunk(int a_ChunkX, int a_ChunkZ, cDropSpenserCallback & a_Callback)
|
bool cChunkMap::ForEachDropSpenserInChunk(int a_ChunkX, int a_ChunkZ, cDropSpenserCallback a_Callback)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSChunks);
|
cCSLock Lock(m_CSChunks);
|
||||||
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ);
|
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ);
|
||||||
@ -1975,7 +1932,7 @@ bool cChunkMap::ForEachDropSpenserInChunk(int a_ChunkX, int a_ChunkZ, cDropSpens
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunkMap::ForEachFurnaceInChunk(int a_ChunkX, int a_ChunkZ, cFurnaceCallback & a_Callback)
|
bool cChunkMap::ForEachFurnaceInChunk(int a_ChunkX, int a_ChunkZ, cFurnaceCallback a_Callback)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSChunks);
|
cCSLock Lock(m_CSChunks);
|
||||||
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ);
|
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ);
|
||||||
@ -1990,7 +1947,7 @@ bool cChunkMap::ForEachFurnaceInChunk(int a_ChunkX, int a_ChunkZ, cFurnaceCallba
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunkMap::DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback & a_Callback)
|
bool cChunkMap::DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback a_Callback)
|
||||||
{
|
{
|
||||||
int ChunkX, ChunkZ;
|
int ChunkX, ChunkZ;
|
||||||
int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ;
|
int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ;
|
||||||
@ -2008,7 +1965,7 @@ bool cChunkMap::DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cB
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunkMap::DoWithBeaconAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconCallback & a_Callback)
|
bool cChunkMap::DoWithBeaconAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconCallback a_Callback)
|
||||||
{
|
{
|
||||||
int ChunkX, ChunkZ;
|
int ChunkX, ChunkZ;
|
||||||
int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ;
|
int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ;
|
||||||
@ -2026,7 +1983,7 @@ bool cChunkMap::DoWithBeaconAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBeacon
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunkMap::DoWithBedAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBedCallback & a_Callback)
|
bool cChunkMap::DoWithBedAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBedCallback a_Callback)
|
||||||
{
|
{
|
||||||
int ChunkX, ChunkZ;
|
int ChunkX, ChunkZ;
|
||||||
int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ;
|
int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ;
|
||||||
@ -2044,7 +2001,7 @@ bool cChunkMap::DoWithBedAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBedCallba
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunkMap::DoWithBrewingstandAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBrewingstandCallback & a_Callback)
|
bool cChunkMap::DoWithBrewingstandAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBrewingstandCallback a_Callback)
|
||||||
{
|
{
|
||||||
int ChunkX, ChunkZ;
|
int ChunkX, ChunkZ;
|
||||||
int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ;
|
int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ;
|
||||||
@ -2062,7 +2019,7 @@ bool cChunkMap::DoWithBrewingstandAt(int a_BlockX, int a_BlockY, int a_BlockZ, c
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunkMap::DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallback & a_Callback)
|
bool cChunkMap::DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallback a_Callback)
|
||||||
{
|
{
|
||||||
int ChunkX, ChunkZ;
|
int ChunkX, ChunkZ;
|
||||||
int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ;
|
int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ;
|
||||||
@ -2080,7 +2037,7 @@ bool cChunkMap::DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, cChestCa
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunkMap::DoWithDispenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDispenserCallback & a_Callback)
|
bool cChunkMap::DoWithDispenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDispenserCallback a_Callback)
|
||||||
{
|
{
|
||||||
int ChunkX, ChunkZ;
|
int ChunkX, ChunkZ;
|
||||||
int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ;
|
int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ;
|
||||||
@ -2098,7 +2055,7 @@ bool cChunkMap::DoWithDispenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDis
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunkMap::DoWithDropperAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDropperCallback & a_Callback)
|
bool cChunkMap::DoWithDropperAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDropperCallback a_Callback)
|
||||||
{
|
{
|
||||||
int ChunkX, ChunkZ;
|
int ChunkX, ChunkZ;
|
||||||
int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ;
|
int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ;
|
||||||
@ -2116,7 +2073,7 @@ bool cChunkMap::DoWithDropperAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDropp
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunkMap::DoWithDropSpenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDropSpenserCallback & a_Callback)
|
bool cChunkMap::DoWithDropSpenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDropSpenserCallback a_Callback)
|
||||||
{
|
{
|
||||||
int ChunkX, ChunkZ;
|
int ChunkX, ChunkZ;
|
||||||
int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ;
|
int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ;
|
||||||
@ -2134,7 +2091,7 @@ bool cChunkMap::DoWithDropSpenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cD
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunkMap::DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceCallback & a_Callback)
|
bool cChunkMap::DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceCallback a_Callback)
|
||||||
{
|
{
|
||||||
int ChunkX, ChunkZ;
|
int ChunkX, ChunkZ;
|
||||||
int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ;
|
int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ;
|
||||||
@ -2151,7 +2108,7 @@ bool cChunkMap::DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurna
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunkMap::DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNoteBlockCallback & a_Callback)
|
bool cChunkMap::DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNoteBlockCallback a_Callback)
|
||||||
{
|
{
|
||||||
int ChunkX, ChunkZ;
|
int ChunkX, ChunkZ;
|
||||||
int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ;
|
int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ;
|
||||||
@ -2168,7 +2125,7 @@ bool cChunkMap::DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNot
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunkMap::DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cCommandBlockCallback & a_Callback)
|
bool cChunkMap::DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cCommandBlockCallback a_Callback)
|
||||||
{
|
{
|
||||||
int ChunkX, ChunkZ;
|
int ChunkX, ChunkZ;
|
||||||
int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ;
|
int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ;
|
||||||
@ -2186,7 +2143,7 @@ bool cChunkMap::DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, c
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunkMap::DoWithMobHeadAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadCallback & a_Callback)
|
bool cChunkMap::DoWithMobHeadAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadCallback a_Callback)
|
||||||
{
|
{
|
||||||
int ChunkX, ChunkZ;
|
int ChunkX, ChunkZ;
|
||||||
int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ;
|
int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ;
|
||||||
@ -2204,7 +2161,7 @@ bool cChunkMap::DoWithMobHeadAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHe
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunkMap::DoWithFlowerPotAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFlowerPotCallback & a_Callback)
|
bool cChunkMap::DoWithFlowerPotAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFlowerPotCallback a_Callback)
|
||||||
{
|
{
|
||||||
int ChunkX, ChunkZ;
|
int ChunkX, ChunkZ;
|
||||||
int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ;
|
int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ;
|
||||||
@ -2442,7 +2399,7 @@ bool cChunkMap::ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinCh
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunkMap::ForEachLoadedChunk(std::function<bool(int, int)> a_Callback)
|
bool cChunkMap::ForEachLoadedChunk(cFunctionRef<bool(int, int)> a_Callback)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSChunks);
|
cCSLock Lock(m_CSChunks);
|
||||||
for (const auto & Chunk : m_Chunks)
|
for (const auto & Chunk : m_Chunks)
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include "ChunkDataCallback.h"
|
#include "ChunkDataCallback.h"
|
||||||
#include "EffectID.h"
|
#include "EffectID.h"
|
||||||
|
#include "FunctionRef.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -38,25 +39,23 @@ class cSetChunkData;
|
|||||||
class cBoundingBox;
|
class cBoundingBox;
|
||||||
class cDeadlockDetect;
|
class cDeadlockDetect;
|
||||||
|
|
||||||
typedef std::list<cClientHandle *> cClientHandleList;
|
typedef std::list<cClientHandle *> cClientHandleList;
|
||||||
typedef cChunk * cChunkPtr;
|
typedef cChunk * cChunkPtr;
|
||||||
typedef cItemCallback<cEntity> cEntityCallback;
|
using cEntityCallback = cFunctionRef<bool(cEntity &)>;
|
||||||
typedef cItemCallback<cBlockEntity> cBlockEntityCallback;
|
using cBeaconCallback = cFunctionRef<bool(cBeaconEntity &)>;
|
||||||
typedef cItemCallback<cBeaconEntity> cBeaconCallback;
|
using cBedCallback = cFunctionRef<bool(cBedEntity &)>;
|
||||||
typedef cItemCallback<cBedEntity> cBedCallback;
|
using cBlockEntityCallback = cFunctionRef<bool(cBlockEntity &)>;
|
||||||
typedef cItemCallback<cBrewingstandEntity> cBrewingstandCallback;
|
using cBrewingstandCallback = cFunctionRef<bool(cBrewingstandEntity &)>;
|
||||||
typedef cItemCallback<cChestEntity> cChestCallback;
|
using cChestCallback = cFunctionRef<bool(cChestEntity &)>;
|
||||||
typedef cItemCallback<cDispenserEntity> cDispenserCallback;
|
using cChunkCallback = cFunctionRef<bool(cChunk &)>;
|
||||||
typedef cItemCallback<cDropperEntity> cDropperCallback;
|
using cDispenserCallback = cFunctionRef<bool(cDispenserEntity &)>;
|
||||||
typedef cItemCallback<cDropSpenserEntity> cDropSpenserCallback;
|
using cDropperCallback = cFunctionRef<bool(cDropperEntity &)>;
|
||||||
typedef cItemCallback<cFlowerPotEntity> cFlowerPotCallback;
|
using cDropSpenserCallback = cFunctionRef<bool(cDropSpenserEntity &)>;
|
||||||
typedef cItemCallback<cFurnaceEntity> cFurnaceCallback;
|
using cFurnaceCallback = cFunctionRef<bool(cFurnaceEntity &)>;
|
||||||
typedef cItemCallback<cNoteEntity> cNoteBlockCallback;
|
using cNoteBlockCallback = cFunctionRef<bool(cNoteEntity &)>;
|
||||||
typedef cItemCallback<cCommandBlockEntity> cCommandBlockCallback;
|
using cCommandBlockCallback = cFunctionRef<bool(cCommandBlockEntity &)>;
|
||||||
typedef cItemCallback<cMobHeadEntity> cMobHeadCallback;
|
using cMobHeadCallback = cFunctionRef<bool(cMobHeadEntity &)>;
|
||||||
typedef cItemCallback<cChunk> cChunkCallback;
|
using cFlowerPotCallback = cFunctionRef<bool(cFlowerPotEntity &)>;
|
||||||
|
|
||||||
typedef std::function<bool (cEntity *)> cLambdaEntityCallback;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -106,10 +105,10 @@ public:
|
|||||||
bool UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z);
|
bool UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z);
|
||||||
|
|
||||||
/** Calls the callback for the chunk specified, with ChunkMapCS locked; returns false if the chunk doesn't exist, otherwise returns the same value as the callback */
|
/** Calls the callback for the chunk specified, with ChunkMapCS locked; returns false if the chunk doesn't exist, otherwise returns the same value as the callback */
|
||||||
bool DoWithChunk(int a_ChunkX, int a_ChunkZ, cChunkCallback & a_Callback);
|
bool DoWithChunk(int a_ChunkX, int a_ChunkZ, cChunkCallback a_Callback);
|
||||||
|
|
||||||
/** Calls the callback for the chunk at the block position specified, with ChunkMapCS locked; returns false if the chunk doesn't exist, otherwise returns the same value as the callback */
|
/** Calls the callback for the chunk at the block position specified, with ChunkMapCS locked; returns false if the chunk doesn't exist, otherwise returns the same value as the callback */
|
||||||
bool DoWithChunkAt(Vector3i a_BlockPos, std::function<bool(cChunk &)> a_Callback);
|
bool DoWithChunkAt(Vector3i a_BlockPos, cChunkCallback a_Callback);
|
||||||
|
|
||||||
/** Wakes up simulators for the specified block */
|
/** Wakes up simulators for the specified block */
|
||||||
void WakeUpSimulators(Vector3i a_Block);
|
void WakeUpSimulators(Vector3i a_Block);
|
||||||
@ -230,102 +229,101 @@ public:
|
|||||||
OwnedEntity RemoveEntity(cEntity & a_Entity);
|
OwnedEntity RemoveEntity(cEntity & a_Entity);
|
||||||
|
|
||||||
/** Calls the callback for each entity in the entire world; returns true if all entities processed, false if the callback aborted by returning true */
|
/** Calls the callback for each entity in the entire world; returns true if all entities processed, false if the callback aborted by returning true */
|
||||||
bool ForEachEntity(cEntityCallback & a_Callback); // Lua-accessible
|
bool ForEachEntity(cEntityCallback a_Callback); // Lua-accessible
|
||||||
|
|
||||||
/** Calls the callback for each entity in the specified chunk; returns true if all entities processed, false if the callback aborted by returning true */
|
/** Calls the callback for each entity in the specified chunk; returns true if all entities processed, false if the callback aborted by returning true */
|
||||||
bool ForEachEntityInChunk(int a_ChunkX, int a_ChunkZ, cEntityCallback & a_Callback); // Lua-accessible
|
bool ForEachEntityInChunk(int a_ChunkX, int a_ChunkZ, cEntityCallback a_Callback); // Lua-accessible
|
||||||
|
|
||||||
/** Calls the callback for each entity that has a nonempty intersection with the specified boundingbox.
|
/** Calls the callback for each entity that has a nonempty intersection with the specified boundingbox.
|
||||||
Returns true if all entities processed, false if the callback aborted by returning true.
|
Returns true if all entities processed, false if the callback aborted by returning true.
|
||||||
If any chunk in the box is missing, ignores the entities in that chunk silently. */
|
If any chunk in the box is missing, ignores the entities in that chunk silently. */
|
||||||
bool ForEachEntityInBox(const cBoundingBox & a_Box, cEntityCallback & a_Callback); // Lua-accessible
|
bool ForEachEntityInBox(const cBoundingBox & a_Box, cEntityCallback a_Callback); // Lua-accessible
|
||||||
|
|
||||||
/** Destroys and returns a list of blocks destroyed in the explosion at the specified coordinates */
|
/** Destroys and returns a list of blocks destroyed in the explosion at the specified coordinates */
|
||||||
void DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, cVector3iArray & a_BlockAffected);
|
void DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, cVector3iArray & a_BlockAffected);
|
||||||
|
|
||||||
/** Calls the callback if the entity with the specified ID is found, with the entity object as the callback param.
|
/** Calls the callback if the entity with the specified ID is found, with the entity object as the callback param.
|
||||||
Returns true if entity found and callback returned false. */
|
Returns true if entity found and callback returned false. */
|
||||||
bool DoWithEntityByID(UInt32 a_EntityID, cEntityCallback & a_Callback); // Lua-accessible
|
bool DoWithEntityByID(UInt32 a_EntityID, cEntityCallback a_Callback); // Lua-accessible
|
||||||
bool DoWithEntityByID(UInt32 a_EntityID, cLambdaEntityCallback a_Callback); // Lambda version
|
|
||||||
|
|
||||||
/** Calls the callback for each block entity in the specified chunk.
|
/** Calls the callback for each block entity in the specified chunk.
|
||||||
Returns true if all block entities processed, false if the callback aborted by returning true. */
|
Returns true if all block entities processed, false if the callback aborted by returning true. */
|
||||||
bool ForEachBlockEntityInChunk(int a_ChunkX, int a_ChunkZ, cBlockEntityCallback & a_Callback); // Lua-accessible
|
bool ForEachBlockEntityInChunk(int a_ChunkX, int a_ChunkZ, cBlockEntityCallback a_Callback); // Lua-accessible
|
||||||
|
|
||||||
/** Calls the callback for brewingstand in the specified chunk.
|
/** Calls the callback for brewingstand in the specified chunk.
|
||||||
Returns true if all brewingstands processed, false if the callback aborted by returning true. */
|
Returns true if all brewingstands processed, false if the callback aborted by returning true. */
|
||||||
bool ForEachBrewingstandInChunk(int a_ChunkX, int a_ChunkZ, cBrewingstandCallback & a_Callback); // Lua-accessible
|
bool ForEachBrewingstandInChunk(int a_ChunkX, int a_ChunkZ, cBrewingstandCallback a_Callback); // Lua-accessible
|
||||||
|
|
||||||
/** Calls the callback for each chest in the specified chunk.
|
/** Calls the callback for each chest in the specified chunk.
|
||||||
Returns true if all chests processed, false if the callback aborted by returning true. */
|
Returns true if all chests processed, false if the callback aborted by returning true. */
|
||||||
bool ForEachChestInChunk(int a_ChunkX, int a_ChunkZ, cChestCallback & a_Callback); // Lua-accessible
|
bool ForEachChestInChunk(int a_ChunkX, int a_ChunkZ, cChestCallback a_Callback); // Lua-accessible
|
||||||
|
|
||||||
/** Calls the callback for each dispenser in the specified chunk.
|
/** Calls the callback for each dispenser in the specified chunk.
|
||||||
Returns true if all dispensers processed, false if the callback aborted by returning true. */
|
Returns true if all dispensers processed, false if the callback aborted by returning true. */
|
||||||
bool ForEachDispenserInChunk(int a_ChunkX, int a_ChunkZ, cDispenserCallback & a_Callback);
|
bool ForEachDispenserInChunk(int a_ChunkX, int a_ChunkZ, cDispenserCallback a_Callback);
|
||||||
|
|
||||||
/** Calls the callback for each dropper in the specified chunk.
|
/** Calls the callback for each dropper in the specified chunk.
|
||||||
Returns true if all droppers processed, false if the callback aborted by returning true. */
|
Returns true if all droppers processed, false if the callback aborted by returning true. */
|
||||||
bool ForEachDropperInChunk(int a_ChunkX, int a_ChunkZ, cDropperCallback & a_Callback);
|
bool ForEachDropperInChunk(int a_ChunkX, int a_ChunkZ, cDropperCallback a_Callback);
|
||||||
|
|
||||||
/** Calls the callback for each dropspenser in the specified chunk.
|
/** Calls the callback for each dropspenser in the specified chunk.
|
||||||
Returns true if all dropspensers processed, false if the callback aborted by returning true. */
|
Returns true if all dropspensers processed, false if the callback aborted by returning true. */
|
||||||
bool ForEachDropSpenserInChunk(int a_ChunkX, int a_ChunkZ, cDropSpenserCallback & a_Callback);
|
bool ForEachDropSpenserInChunk(int a_ChunkX, int a_ChunkZ, cDropSpenserCallback a_Callback);
|
||||||
|
|
||||||
/** Calls the callback for each furnace in the specified chunk.
|
/** Calls the callback for each furnace in the specified chunk.
|
||||||
Returns true if all furnaces processed, false if the callback aborted by returning true. */
|
Returns true if all furnaces processed, false if the callback aborted by returning true. */
|
||||||
bool ForEachFurnaceInChunk(int a_ChunkX, int a_ChunkZ, cFurnaceCallback & a_Callback); // Lua-accessible
|
bool ForEachFurnaceInChunk(int a_ChunkX, int a_ChunkZ, cFurnaceCallback a_Callback); // Lua-accessible
|
||||||
|
|
||||||
/** Calls the callback for the block entity at the specified coords.
|
/** Calls the callback for the block entity at the specified coords.
|
||||||
Returns false if there's no block entity at those coords, true if found. */
|
Returns false if there's no block entity at those coords, true if found. */
|
||||||
bool DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback & a_Callback); // Lua-acessible
|
bool DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback a_Callback); // Lua-acessible
|
||||||
|
|
||||||
/** Calls the callback for the beacon at the specified coords.
|
/** Calls the callback for the beacon at the specified coords.
|
||||||
Returns false if there's no beacon at those coords, true if found. */
|
Returns false if there's no beacon at those coords, true if found. */
|
||||||
bool DoWithBeaconAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconCallback & a_Callback); // Lua-acessible
|
bool DoWithBeaconAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconCallback a_Callback); // Lua-acessible
|
||||||
|
|
||||||
/** Calls the callback for the bed at the specified coords.
|
/** Calls the callback for the bed at the specified coords.
|
||||||
Returns false if there's no bed at those coords, true if found. */
|
Returns false if there's no bed at those coords, true if found. */
|
||||||
bool DoWithBedAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBedCallback & a_Callback); // Lua-acessible
|
bool DoWithBedAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBedCallback a_Callback); // Lua-acessible
|
||||||
|
|
||||||
/** Calls the callback for the brewingstand at the specified coords; returns false if there's no brewingstand at those coords, true if found */
|
/** Calls the callback for the brewingstand at the specified coords; returns false if there's no brewingstand at those coords, true if found */
|
||||||
bool DoWithBrewingstandAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBrewingstandCallback & a_Callback); // Lua-acessible
|
bool DoWithBrewingstandAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBrewingstandCallback a_Callback); // Lua-acessible
|
||||||
|
|
||||||
/** Calls the callback for the chest at the specified coords.
|
/** Calls the callback for the chest at the specified coords.
|
||||||
Returns false if there's no chest at those coords, true if found. */
|
Returns false if there's no chest at those coords, true if found. */
|
||||||
bool DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallback & a_Callback); // Lua-acessible
|
bool DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallback a_Callback); // Lua-acessible
|
||||||
|
|
||||||
/** Calls the callback for the dispenser at the specified coords.
|
/** Calls the callback for the dispenser at the specified coords.
|
||||||
Returns false if there's no dispenser at those coords or callback returns true, returns true if found. */
|
Returns false if there's no dispenser at those coords or callback returns true, returns true if found. */
|
||||||
bool DoWithDispenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDispenserCallback & a_Callback); // Lua-accessible
|
bool DoWithDispenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDispenserCallback a_Callback); // Lua-accessible
|
||||||
|
|
||||||
/** Calls the callback for the dropper at the specified coords.
|
/** Calls the callback for the dropper at the specified coords.
|
||||||
Returns false if there's no dropper at those coords or callback returns true, returns true if found. */
|
Returns false if there's no dropper at those coords or callback returns true, returns true if found. */
|
||||||
bool DoWithDropperAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDropperCallback & a_Callback); // Lua-accessible
|
bool DoWithDropperAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDropperCallback a_Callback); // Lua-accessible
|
||||||
|
|
||||||
/** Calls the callback for the dropspenser at the specified coords.
|
/** Calls the callback for the dropspenser at the specified coords.
|
||||||
Returns false if there's no dropspenser at those coords or callback returns true, returns true if found. */
|
Returns false if there's no dropspenser at those coords or callback returns true, returns true if found. */
|
||||||
bool DoWithDropSpenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDropSpenserCallback & a_Callback); // Lua-accessible
|
bool DoWithDropSpenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDropSpenserCallback a_Callback); // Lua-accessible
|
||||||
|
|
||||||
/** Calls the callback for the furnace at the specified coords.
|
/** Calls the callback for the furnace at the specified coords.
|
||||||
Returns false if there's no furnace at those coords or callback returns true, returns true if found. */
|
Returns false if there's no furnace at those coords or callback returns true, returns true if found. */
|
||||||
bool DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceCallback & a_Callback); // Lua-accessible
|
bool DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceCallback a_Callback); // Lua-accessible
|
||||||
|
|
||||||
/** Calls the callback for the noteblock at the specified coords.
|
/** Calls the callback for the noteblock at the specified coords.
|
||||||
Returns false if there's no noteblock at those coords or callback returns true, returns true if found. */
|
Returns false if there's no noteblock at those coords or callback returns true, returns true if found. */
|
||||||
bool DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNoteBlockCallback & a_Callback); // Lua-accessible
|
bool DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNoteBlockCallback a_Callback); // Lua-accessible
|
||||||
|
|
||||||
/** Calls the callback for the command block at the specified coords.
|
/** Calls the callback for the command block at the specified coords.
|
||||||
Returns false if there's no command block at those coords or callback returns true, returns true if found. */
|
Returns false if there's no command block at those coords or callback returns true, returns true if found. */
|
||||||
bool DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cCommandBlockCallback & a_Callback); // Lua-accessible
|
bool DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cCommandBlockCallback a_Callback); // Lua-accessible
|
||||||
|
|
||||||
/** Calls the callback for the mob head block at the specified coords.
|
/** Calls the callback for the mob head block at the specified coords.
|
||||||
Returns false if there's no mob head block at those coords or callback returns true, returns true if found. */
|
Returns false if there's no mob head block at those coords or callback returns true, returns true if found. */
|
||||||
bool DoWithMobHeadAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadCallback & a_Callback); // Lua-accessible
|
bool DoWithMobHeadAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadCallback a_Callback); // Lua-accessible
|
||||||
|
|
||||||
/** Calls the callback for the flower pot at the specified coords.
|
/** Calls the callback for the flower pot at the specified coords.
|
||||||
Returns false if there's no flower pot at those coords or callback returns true, returns true if found. */
|
Returns false if there's no flower pot at those coords or callback returns true, returns true if found. */
|
||||||
bool DoWithFlowerPotAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFlowerPotCallback & a_Callback); // Lua-accessible
|
bool DoWithFlowerPotAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFlowerPotCallback a_Callback); // Lua-accessible
|
||||||
|
|
||||||
/** Retrieves the test on the sign at the specified coords.
|
/** Retrieves the test on the sign at the specified coords.
|
||||||
Returns false if there's no sign at those coords, true if found. */
|
Returns false if there's no sign at those coords, true if found. */
|
||||||
@ -363,7 +361,7 @@ public:
|
|||||||
bool ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ, cChunkDataCallback & a_Callback);
|
bool ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ, cChunkDataCallback & a_Callback);
|
||||||
|
|
||||||
/** Calls the callback for each loaded chunk. Returns true if all chunks have been processed successfully */
|
/** Calls the callback for each loaded chunk. Returns true if all chunks have been processed successfully */
|
||||||
bool ForEachLoadedChunk(std::function<bool(int, int)> a_Callback);
|
bool ForEachLoadedChunk(cFunctionRef<bool(int, int)> a_Callback);
|
||||||
|
|
||||||
/** Writes the block area into the specified coords. Returns true if all chunks have been processed. Prefer cBlockArea::Write() instead. */
|
/** Writes the block area into the specified coords. Returns true if all chunks have been processed. Prefer cBlockArea::Write() instead. */
|
||||||
bool WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes);
|
bool WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes);
|
||||||
|
@ -1660,9 +1660,9 @@ void cClientHandle::HandleSlotSelected(Int16 a_SlotNum)
|
|||||||
|
|
||||||
void cClientHandle::HandleSpectate(const cUUID & a_PlayerUUID)
|
void cClientHandle::HandleSpectate(const cUUID & a_PlayerUUID)
|
||||||
{
|
{
|
||||||
m_Player->GetWorld()->DoWithPlayerByUUID(a_PlayerUUID, [=](cPlayer * a_ToSpectate)
|
m_Player->GetWorld()->DoWithPlayerByUUID(a_PlayerUUID, [=](cPlayer & a_ToSpectate)
|
||||||
{
|
{
|
||||||
m_Player->TeleportToEntity(*a_ToSpectate);
|
m_Player->TeleportToEntity(a_ToSpectate);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -1734,9 +1734,9 @@ void cClientHandle::HandleUseEntity(UInt32 a_TargetEntityID, bool a_IsLeftClick)
|
|||||||
// If the player is a spectator, let him spectate
|
// If the player is a spectator, let him spectate
|
||||||
if (m_Player->IsGameModeSpectator() && a_IsLeftClick)
|
if (m_Player->IsGameModeSpectator() && a_IsLeftClick)
|
||||||
{
|
{
|
||||||
m_Player->GetWorld()->DoWithEntityByID(a_TargetEntityID, [=](cEntity * a_Entity)
|
m_Player->GetWorld()->DoWithEntityByID(a_TargetEntityID, [=](cEntity & a_Entity)
|
||||||
{
|
{
|
||||||
m_Player->AttachTo(a_Entity);
|
m_Player->AttachTo(&a_Entity);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
@ -1745,20 +1745,18 @@ void cClientHandle::HandleUseEntity(UInt32 a_TargetEntityID, bool a_IsLeftClick)
|
|||||||
// If it is a right click, call the entity's OnRightClicked() handler:
|
// If it is a right click, call the entity's OnRightClicked() handler:
|
||||||
if (!a_IsLeftClick)
|
if (!a_IsLeftClick)
|
||||||
{
|
{
|
||||||
class cRclkEntity : public cEntityCallback
|
cWorld * World = m_Player->GetWorld();
|
||||||
{
|
World->DoWithEntityByID(a_TargetEntityID, [=](cEntity & a_Entity)
|
||||||
cPlayer & m_Player;
|
|
||||||
virtual bool Item(cEntity * a_Entity) override
|
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
cPluginManager::Get()->CallHookPlayerRightClickingEntity(m_Player, *a_Entity) ||
|
cPluginManager::Get()->CallHookPlayerRightClickingEntity(*m_Player, a_Entity) ||
|
||||||
(
|
(
|
||||||
m_Player.IsGameModeSpectator() && // Spectators cannot interact with every entity
|
m_Player->IsGameModeSpectator() && // Spectators cannot interact with every entity
|
||||||
(
|
(
|
||||||
!a_Entity->IsMinecart() || // They can only interact with minecarts
|
!a_Entity.IsMinecart() || // They can only interact with minecarts
|
||||||
(
|
(
|
||||||
(reinterpret_cast<cMinecart *>(a_Entity)->GetPayload() != cMinecart::mpChest) && // And only if the type matches a minecart with a chest or
|
(static_cast<cMinecart &>(a_Entity).GetPayload() != cMinecart::mpChest) && // And only if the type matches a minecart with a chest or
|
||||||
(reinterpret_cast<cMinecart *>(a_Entity)->GetPayload() != cMinecart::mpHopper) // a minecart with a hopper
|
(static_cast<cMinecart &>(a_Entity).GetPayload() != cMinecart::mpHopper) // a minecart with a hopper
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -1766,52 +1764,34 @@ void cClientHandle::HandleUseEntity(UInt32 a_TargetEntityID, bool a_IsLeftClick)
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
a_Entity->OnRightClicked(m_Player);
|
a_Entity.OnRightClicked(*m_Player);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
public:
|
);
|
||||||
cRclkEntity(cPlayer & a_Player) : m_Player(a_Player) {}
|
|
||||||
} Callback (*m_Player);
|
|
||||||
|
|
||||||
cWorld * World = m_Player->GetWorld();
|
|
||||||
World->DoWithEntityByID(a_TargetEntityID, Callback);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If it is a left click, attack the entity:
|
// If it is a left click, attack the entity:
|
||||||
class cDamageEntity : public cEntityCallback
|
m_Player->GetWorld()->DoWithEntityByID(a_TargetEntityID, [=](cEntity & a_Entity)
|
||||||
{
|
|
||||||
public:
|
|
||||||
cPlayer * m_Me;
|
|
||||||
|
|
||||||
cDamageEntity(cPlayer * a_Player) :
|
|
||||||
m_Me(a_Player)
|
|
||||||
{
|
{
|
||||||
}
|
if (!a_Entity.GetWorld()->IsPVPEnabled())
|
||||||
|
|
||||||
virtual bool Item(cEntity * a_Entity) override
|
|
||||||
{
|
|
||||||
if (!a_Entity->GetWorld()->IsPVPEnabled())
|
|
||||||
{
|
{
|
||||||
// PVP is disabled, disallow players hurting other players:
|
// PVP is disabled, disallow players hurting other players:
|
||||||
if (a_Entity->IsPlayer())
|
if (a_Entity.IsPlayer())
|
||||||
{
|
{
|
||||||
// Player is hurting another player which is not allowed when PVP is disabled so ignore it
|
// Player is hurting another player which is not allowed when PVP is disabled so ignore it
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
a_Entity->TakeDamage(*m_Me);
|
a_Entity.TakeDamage(*m_Player);
|
||||||
m_Me->AddFoodExhaustion(0.3);
|
m_Player->AddFoodExhaustion(0.3);
|
||||||
if (a_Entity->IsPawn())
|
if (a_Entity.IsPawn())
|
||||||
{
|
{
|
||||||
m_Me->NotifyNearbyWolves(static_cast<cPawn*>(a_Entity), true);
|
m_Player->NotifyNearbyWolves(static_cast<cPawn*>(&a_Entity), true);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} Callback(m_Player);
|
);
|
||||||
|
|
||||||
cWorld * World = m_Player->GetWorld();
|
|
||||||
World->DoWithEntityByID(a_TargetEntityID, Callback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1860,17 +1840,8 @@ bool cClientHandle::CheckMultiLogin(const AString & a_Username)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
class cCallback :
|
|
||||||
public cPlayerListCallback
|
|
||||||
{
|
|
||||||
virtual bool Item(cPlayer * a_Player) override
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} Callback;
|
|
||||||
|
|
||||||
// Check if the player is in any World.
|
// Check if the player is in any World.
|
||||||
if (cRoot::Get()->DoWithPlayer(a_Username, Callback))
|
if (cRoot::Get()->DoWithPlayer(a_Username, [](cPlayer &) { return true; }))
|
||||||
{
|
{
|
||||||
Kick("A player of the username is already logged in");
|
Kick("A player of the username is already logged in");
|
||||||
return false;
|
return false;
|
||||||
|
@ -56,25 +56,12 @@ bool cDeadlockDetect::Start(int a_IntervalSec)
|
|||||||
m_IntervalSec = a_IntervalSec;
|
m_IntervalSec = a_IntervalSec;
|
||||||
|
|
||||||
// Read the initial world data:
|
// Read the initial world data:
|
||||||
class cFillIn :
|
cRoot::Get()->ForEachWorld([=](cWorld & a_World)
|
||||||
public cWorldListCallback
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
cFillIn(cDeadlockDetect * a_Detect) :
|
|
||||||
m_Detect(a_Detect)
|
|
||||||
{
|
{
|
||||||
}
|
SetWorldAge(a_World.GetName(), a_World.GetWorldAge());
|
||||||
|
|
||||||
virtual bool Item(cWorld * a_World) override
|
|
||||||
{
|
|
||||||
m_Detect->SetWorldAge(a_World->GetName(), a_World->GetWorldAge());
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
);
|
||||||
protected:
|
|
||||||
cDeadlockDetect * m_Detect;
|
|
||||||
} FillIn(this);
|
|
||||||
cRoot::Get()->ForEachWorld(FillIn);
|
|
||||||
return super::Start();
|
return super::Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,25 +102,12 @@ void cDeadlockDetect::Execute(void)
|
|||||||
while (!m_ShouldTerminate)
|
while (!m_ShouldTerminate)
|
||||||
{
|
{
|
||||||
// Check the world ages:
|
// Check the world ages:
|
||||||
class cChecker :
|
cRoot::Get()->ForEachWorld([=](cWorld & a_World)
|
||||||
public cWorldListCallback
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
cChecker(cDeadlockDetect * a_Detect) :
|
|
||||||
m_Detect(a_Detect)
|
|
||||||
{
|
{
|
||||||
}
|
CheckWorldAge(a_World.GetName(), a_World.GetWorldAge());
|
||||||
|
|
||||||
protected:
|
|
||||||
cDeadlockDetect * m_Detect;
|
|
||||||
|
|
||||||
virtual bool Item(cWorld * a_World) override
|
|
||||||
{
|
|
||||||
m_Detect->CheckWorldAge(a_World->GetName(), a_World->GetWorldAge());
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} Checker(this);
|
);
|
||||||
cRoot::Get()->ForEachWorld(Checker);
|
|
||||||
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(CYCLE_MILLISECONDS));
|
std::this_thread::sleep_for(std::chrono::milliseconds(CYCLE_MILLISECONDS));
|
||||||
} // while (should run)
|
} // while (should run)
|
||||||
|
@ -302,38 +302,22 @@ void cEntity::TakeDamage(eDamageType a_DamageType, cEntity * a_Attacker, int a_R
|
|||||||
|
|
||||||
void cEntity::TakeDamage(eDamageType a_DamageType, UInt32 a_AttackerID, int a_RawDamage, double a_KnockbackAmount)
|
void cEntity::TakeDamage(eDamageType a_DamageType, UInt32 a_AttackerID, int a_RawDamage, double a_KnockbackAmount)
|
||||||
{
|
{
|
||||||
class cFindEntity : public cEntityCallback
|
m_World->DoWithEntityByID(a_AttackerID, [=](cEntity & a_Attacker)
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
cEntity * m_Entity;
|
|
||||||
eDamageType m_DamageType;
|
|
||||||
int m_RawDamage;
|
|
||||||
double m_KnockbackAmount;
|
|
||||||
|
|
||||||
virtual bool Item(cEntity * a_Attacker) override
|
|
||||||
{
|
{
|
||||||
cPawn * Attacker;
|
cPawn * Attacker;
|
||||||
if (a_Attacker->IsPawn())
|
if (a_Attacker.IsPawn())
|
||||||
{
|
{
|
||||||
Attacker = static_cast<cPawn*>(a_Attacker);
|
Attacker = static_cast<cPawn*>(&a_Attacker);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Attacker = nullptr;
|
Attacker = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TakeDamage(a_DamageType, Attacker, a_RawDamage, a_KnockbackAmount);
|
||||||
m_Entity->TakeDamage(m_DamageType, Attacker, m_RawDamage, m_KnockbackAmount);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} Callback;
|
);
|
||||||
|
|
||||||
Callback.m_Entity = this;
|
|
||||||
Callback.m_DamageType = a_DamageType;
|
|
||||||
Callback.m_RawDamage = a_RawDamage;
|
|
||||||
Callback.m_KnockbackAmount = a_KnockbackAmount;
|
|
||||||
m_World->DoWithEntityByID(a_AttackerID, Callback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -664,7 +648,7 @@ bool cEntity::ArmorCoversAgainst(eDamageType a_DamageType)
|
|||||||
|
|
||||||
int cEntity::GetEnchantmentCoverAgainst(const cEntity * a_Attacker, eDamageType a_DamageType, int a_Damage)
|
int cEntity::GetEnchantmentCoverAgainst(const cEntity * a_Attacker, eDamageType a_DamageType, int a_Damage)
|
||||||
{
|
{
|
||||||
int TotalEPF = 0.0;
|
int TotalEPF = 0;
|
||||||
|
|
||||||
const cItem ArmorItems[] = { GetEquippedHelmet(), GetEquippedChestplate(), GetEquippedLeggings(), GetEquippedBoots() };
|
const cItem ArmorItems[] = { GetEquippedHelmet(), GetEquippedChestplate(), GetEquippedLeggings(), GetEquippedBoots() };
|
||||||
for (size_t i = 0; i < ARRAYCOUNT(ArmorItems); i++)
|
for (size_t i = 0; i < ARRAYCOUNT(ArmorItems); i++)
|
||||||
|
@ -13,8 +13,7 @@
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// cFloaterEntityCollisionCallback
|
// cFloaterEntityCollisionCallback
|
||||||
class cFloaterEntityCollisionCallback :
|
class cFloaterEntityCollisionCallback
|
||||||
public cEntityCallback
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
cFloaterEntityCollisionCallback(cFloater * a_Floater, const Vector3d & a_Pos, const Vector3d & a_NextPos) :
|
cFloaterEntityCollisionCallback(cFloater * a_Floater, const Vector3d & a_Pos, const Vector3d & a_NextPos) :
|
||||||
@ -25,14 +24,14 @@ public:
|
|||||||
m_HitEntity(nullptr)
|
m_HitEntity(nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
virtual bool Item(cEntity * a_Entity) override
|
bool operator () (cEntity & a_Entity)
|
||||||
{
|
{
|
||||||
if (!a_Entity->IsMob()) // Floaters can only pull mobs not other entities.
|
if (!a_Entity.IsMob()) // Floaters can only pull mobs not other entities.
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
cBoundingBox EntBox(a_Entity->GetPosition(), a_Entity->GetWidth() / 2, a_Entity->GetHeight());
|
cBoundingBox EntBox(a_Entity.GetPosition(), a_Entity.GetWidth() / 2, a_Entity.GetHeight());
|
||||||
|
|
||||||
double LineCoeff;
|
double LineCoeff;
|
||||||
eBlockFace Face;
|
eBlockFace Face;
|
||||||
@ -47,7 +46,7 @@ public:
|
|||||||
{
|
{
|
||||||
// The entity is closer than anything we've stored so far, replace it as the potential victim
|
// The entity is closer than anything we've stored so far, replace it as the potential victim
|
||||||
m_MinCoeff = LineCoeff;
|
m_MinCoeff = LineCoeff;
|
||||||
m_HitEntity = a_Entity;
|
m_HitEntity = &a_Entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't break the enumeration, we want all the entities
|
// Don't break the enumeration, we want all the entities
|
||||||
@ -75,32 +74,6 @@ protected:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// cFloaterCheckEntityExist
|
|
||||||
class cFloaterCheckEntityExist :
|
|
||||||
public cEntityCallback
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
cFloaterCheckEntityExist(void) :
|
|
||||||
m_EntityExists(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Item(cEntity * a_Entity) override
|
|
||||||
{
|
|
||||||
m_EntityExists = true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DoesExist(void) const { return m_EntityExists; }
|
|
||||||
protected:
|
|
||||||
bool m_EntityExists;
|
|
||||||
} ;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
cFloater::cFloater(double a_X, double a_Y, double a_Z, Vector3d a_Speed, UInt32 a_PlayerID, int a_CountDownTime) :
|
cFloater::cFloater(double a_X, double a_Y, double a_Z, Vector3d a_Speed, UInt32 a_PlayerID, int a_CountDownTime) :
|
||||||
cEntity(etFloater, a_X, a_Y, a_Z, 0.2, 0.2),
|
cEntity(etFloater, a_X, a_Y, a_Z, 0.2, 0.2),
|
||||||
m_BitePos(Vector3d(a_X, a_Y, a_Z)),
|
m_BitePos(Vector3d(a_X, a_Y, a_Z)),
|
||||||
@ -200,18 +173,16 @@ void cFloater::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cFloaterCheckEntityExist EntityCallback;
|
if (!m_World->DoWithEntityByID(m_PlayerID, [](cEntity &) { return true; })) // The owner doesn't exist anymore. Destroy the floater entity.
|
||||||
m_World->DoWithEntityByID(m_PlayerID, EntityCallback);
|
|
||||||
if (!EntityCallback.DoesExist()) // The owner doesn't exist anymore. Destroy the floater entity.
|
|
||||||
{
|
{
|
||||||
Destroy(true);
|
Destroy(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_AttachedMobID != cEntity::INVALID_ID)
|
if (m_AttachedMobID != cEntity::INVALID_ID)
|
||||||
{
|
{
|
||||||
m_World->DoWithEntityByID(m_AttachedMobID, EntityCallback); // The mob the floater was attached to doesn't exist anymore.
|
if (!m_World->DoWithEntityByID(m_AttachedMobID, [](cEntity &) { return true; }))
|
||||||
if (!EntityCallback.DoesExist())
|
|
||||||
{
|
{
|
||||||
|
// The mob the floater was attached to doesn't exist anymore.
|
||||||
m_AttachedMobID = cEntity::INVALID_ID;
|
m_AttachedMobID = cEntity::INVALID_ID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
|
|
||||||
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
||||||
|
|
||||||
#include "LeashKnot.h"
|
#include "LeashKnot.h"
|
||||||
@ -38,58 +38,42 @@ void cLeashKnot::OnRightClicked(cPlayer & a_Player)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cLeashKnot::TiePlayersLeashedMobs(cPlayer & a_Player, bool a_ShouldBroadCast)
|
void cLeashKnot::TiePlayersLeashedMobs(cPlayer & a_Player, bool a_ShouldBroadcast)
|
||||||
{
|
{
|
||||||
// Check leashed nearby mobs to tie them to this knot
|
// Check leashed nearby mobs to tie them to this knot
|
||||||
class LookForLeasheds : public cEntityCallback
|
// taking world from player (instead from this) because this can be called before entity was initialized
|
||||||
{
|
a_Player.GetWorld()->ForEachEntityInBox(cBoundingBox(GetPosition(), 8, 8, -4), [&](cEntity & a_Entity)
|
||||||
public:
|
|
||||||
cLeashKnot * m_Knot;
|
|
||||||
cPlayer * m_Player;
|
|
||||||
bool m_ShouldBroadcast;
|
|
||||||
|
|
||||||
LookForLeasheds(cLeashKnot * a_Knot, cPlayer * a_PlayerLeashedTo, bool a_ShouldBroadcast) :
|
|
||||||
m_Knot(a_Knot),
|
|
||||||
m_Player(a_PlayerLeashedTo),
|
|
||||||
m_ShouldBroadcast(a_ShouldBroadcast)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool Item(cEntity * a_Entity) override
|
|
||||||
{
|
{
|
||||||
// If the entity is not a monster skip it
|
// If the entity is not a monster skip it
|
||||||
if (a_Entity->GetEntityType() != cEntity::eEntityType::etMonster)
|
if (a_Entity.GetEntityType() != cEntity::eEntityType::etMonster)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
cMonster * PotentialLeashed = static_cast<cMonster*>(a_Entity);
|
auto & PotentialLeashed = static_cast<cMonster&>(a_Entity);
|
||||||
|
|
||||||
// If can't be leashed skip it
|
// If can't be leashed skip it
|
||||||
if (!PotentialLeashed->CanBeLeashed())
|
if (!PotentialLeashed.CanBeLeashed())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If it's not leashed to the player skip it
|
// If it's not leashed to the player skip it
|
||||||
if (
|
if (
|
||||||
!PotentialLeashed->IsLeashed() ||
|
!PotentialLeashed.IsLeashed() ||
|
||||||
!PotentialLeashed->GetLeashedTo()->IsPlayer() ||
|
!PotentialLeashed.GetLeashedTo()->IsPlayer() ||
|
||||||
(PotentialLeashed->GetLeashedTo()->GetUniqueID() != m_Player->GetUniqueID())
|
(PotentialLeashed.GetLeashedTo()->GetUniqueID() != a_Player.GetUniqueID())
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// All conditions met, unleash from player and leash to fence
|
// All conditions met, unleash from player and leash to fence
|
||||||
PotentialLeashed->Unleash(false, false);
|
PotentialLeashed.Unleash(false, false);
|
||||||
PotentialLeashed->LeashTo(*m_Knot, m_ShouldBroadcast);
|
PotentialLeashed.LeashTo(*this, a_ShouldBroadcast);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} LookForLeashedsCallback(this, &a_Player, a_ShouldBroadCast);
|
);
|
||||||
|
|
||||||
// taking world from player (instead from this) because this can be called before entity was initialized
|
|
||||||
a_Player.GetWorld()->ForEachEntityInBox(cBoundingBox(GetPosition(), 8, 8, -4), LookForLeashedsCallback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -158,26 +142,19 @@ void cLeashKnot::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
|
|||||||
|
|
||||||
cLeashKnot * cLeashKnot::FindKnotAtPos(cWorldInterface & a_WorldInterface, Vector3i a_BlockPos)
|
cLeashKnot * cLeashKnot::FindKnotAtPos(cWorldInterface & a_WorldInterface, Vector3i a_BlockPos)
|
||||||
{
|
{
|
||||||
class LookForKnot : public cEntityCallback
|
cLeashKnot * LeashKnot = nullptr;
|
||||||
{
|
a_WorldInterface.ForEachEntityInBox(cBoundingBox(a_BlockPos, 0.5, 1), [&](cEntity & a_Entity)
|
||||||
public:
|
|
||||||
cLeashKnot * m_LeashKnot = nullptr;
|
|
||||||
|
|
||||||
virtual bool Item(cEntity * a_Entity) override
|
|
||||||
{
|
{
|
||||||
if (a_Entity->IsLeashKnot())
|
if (a_Entity.IsLeashKnot())
|
||||||
{
|
{
|
||||||
m_LeashKnot = reinterpret_cast<cLeashKnot *>(a_Entity);
|
LeashKnot = static_cast<cLeashKnot *>(&a_Entity);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
);
|
||||||
|
|
||||||
} CallbackFindKnot;
|
return LeashKnot;
|
||||||
|
|
||||||
a_WorldInterface.ForEachEntityInBox(cBoundingBox(a_BlockPos, 0.5, 1), CallbackFindKnot);
|
|
||||||
|
|
||||||
return CallbackFindKnot.m_LeashKnot;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,8 +20,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
class cMinecartCollisionCallback :
|
class cMinecartCollisionCallback
|
||||||
public cEntityCallback
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
cMinecartCollisionCallback(Vector3d a_Pos, double a_Height, double a_Width, UInt32 a_UniqueID, UInt32 a_AttacheeUniqueID) :
|
cMinecartCollisionCallback(Vector3d a_Pos, double a_Height, double a_Width, UInt32 a_UniqueID, UInt32 a_AttacheeUniqueID) :
|
||||||
@ -35,33 +34,31 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool Item(cEntity * a_Entity) override
|
bool operator () (cEntity & a_Entity)
|
||||||
{
|
{
|
||||||
ASSERT(a_Entity != nullptr);
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
(
|
(
|
||||||
!a_Entity->IsPlayer() ||
|
!a_Entity.IsPlayer() ||
|
||||||
reinterpret_cast<cPlayer *>(a_Entity)->IsGameModeSpectator() // Spectators doesn't collide with anything
|
static_cast<cPlayer &>(a_Entity).IsGameModeSpectator() // Spectators doesn't collide with anything
|
||||||
) &&
|
) &&
|
||||||
!a_Entity->IsMob() &&
|
!a_Entity.IsMob() &&
|
||||||
!a_Entity->IsMinecart() &&
|
!a_Entity.IsMinecart() &&
|
||||||
!a_Entity->IsBoat()
|
!a_Entity.IsBoat()
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if ((a_Entity->GetUniqueID() == m_UniqueID) || (a_Entity->GetUniqueID() == m_AttacheeUniqueID))
|
else if ((a_Entity.GetUniqueID() == m_UniqueID) || (a_Entity.GetUniqueID() == m_AttacheeUniqueID))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
cBoundingBox bbEntity(a_Entity->GetPosition(), a_Entity->GetWidth() / 2, a_Entity->GetHeight());
|
cBoundingBox bbEntity(a_Entity.GetPosition(), a_Entity.GetWidth() / 2, a_Entity.GetHeight());
|
||||||
cBoundingBox bbMinecart(Vector3d(m_Pos.x, floor(m_Pos.y), m_Pos.z), m_Width / 2, m_Height);
|
cBoundingBox bbMinecart(Vector3d(m_Pos.x, floor(m_Pos.y), m_Pos.z), m_Width / 2, m_Height);
|
||||||
|
|
||||||
if (bbEntity.DoesIntersect(bbMinecart))
|
if (bbEntity.DoesIntersect(bbMinecart))
|
||||||
{
|
{
|
||||||
m_CollidedEntityPos = a_Entity->GetPosition();
|
m_CollidedEntityPos = a_Entity.GetPosition();
|
||||||
m_DoesIntersect = true;
|
m_DoesIntersect = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
|
|
||||||
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
||||||
|
|
||||||
#include "Pawn.h"
|
#include "Pawn.h"
|
||||||
@ -80,49 +80,37 @@ void cPawn::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
|
|||||||
Effect->OnTick(*this);
|
Effect->OnTick(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
class Pusher : public cEntityCallback
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
cEntity * m_Pusher;
|
|
||||||
|
|
||||||
Pusher(cEntity * a_Pusher) :
|
|
||||||
m_Pusher(a_Pusher)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool Item(cEntity * a_Entity) override
|
|
||||||
{
|
|
||||||
if (a_Entity->GetUniqueID() == m_Pusher->GetUniqueID())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// we only push other mobs, boats and minecarts
|
|
||||||
if ((a_Entity->GetEntityType() != etMonster) && (a_Entity->GetEntityType() != etMinecart) && (a_Entity->GetEntityType() != etBoat))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// do not push a boat / minecart you're sitting in
|
|
||||||
if (m_Pusher->IsAttachedTo(a_Entity))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3d v3Delta = a_Entity->GetPosition() - m_Pusher->GetPosition();
|
|
||||||
v3Delta.y = 0.0; // we only push sideways
|
|
||||||
v3Delta *= 1.0 / (v3Delta.Length() + 0.01); // we push harder if we're close
|
|
||||||
// QUESTION: is there an additional multiplier for this? current shoving seems a bit weak
|
|
||||||
|
|
||||||
a_Entity->AddSpeed(v3Delta);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} Callback(this);
|
|
||||||
|
|
||||||
// Spectators cannot push entities around
|
// Spectators cannot push entities around
|
||||||
if ((!IsPlayer()) || (!reinterpret_cast<cPlayer *>(this)->IsGameModeSpectator()))
|
if ((!IsPlayer()) || (!static_cast<cPlayer *>(this)->IsGameModeSpectator()))
|
||||||
{
|
{
|
||||||
m_World->ForEachEntityInBox(cBoundingBox(GetPosition(), GetWidth(), GetHeight()), Callback);
|
m_World->ForEachEntityInBox(cBoundingBox(GetPosition(), GetWidth(), GetHeight()), [=](cEntity & a_Entity)
|
||||||
|
{
|
||||||
|
if (a_Entity.GetUniqueID() == GetUniqueID())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we only push other mobs, boats and minecarts
|
||||||
|
if ((a_Entity.GetEntityType() != etMonster) && (a_Entity.GetEntityType() != etMinecart) && (a_Entity.GetEntityType() != etBoat))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// do not push a boat / minecart you're sitting in
|
||||||
|
if (IsAttachedTo(&a_Entity))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3d v3Delta = a_Entity.GetPosition() - GetPosition();
|
||||||
|
v3Delta.y = 0.0; // we only push sideways
|
||||||
|
v3Delta *= 1.0 / (v3Delta.Length() + 0.01); // we push harder if we're close
|
||||||
|
// QUESTION: is there an additional multiplier for this? current shoving seems a bit weak
|
||||||
|
|
||||||
|
a_Entity.AddSpeed(v3Delta);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
super::Tick(a_Dt, a_Chunk);
|
super::Tick(a_Dt, a_Chunk);
|
||||||
|
@ -17,8 +17,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
class cPickupCombiningCallback :
|
class cPickupCombiningCallback
|
||||||
public cEntityCallback
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
cPickupCombiningCallback(Vector3d a_Position, cPickup * a_Pickup) :
|
cPickupCombiningCallback(Vector3d a_Position, cPickup * a_Pickup) :
|
||||||
@ -28,21 +27,21 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool Item(cEntity * a_Entity) override
|
bool operator () (cEntity & a_Entity)
|
||||||
{
|
{
|
||||||
ASSERT(a_Entity->IsTicking());
|
ASSERT(a_Entity.IsTicking());
|
||||||
if (!a_Entity->IsPickup() || (a_Entity->GetUniqueID() <= m_Pickup->GetUniqueID()) || !a_Entity->IsOnGround())
|
if (!a_Entity.IsPickup() || (a_Entity.GetUniqueID() <= m_Pickup->GetUniqueID()) || !a_Entity.IsOnGround())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Vector3d EntityPos = a_Entity->GetPosition();
|
Vector3d EntityPos = a_Entity.GetPosition();
|
||||||
double Distance = (EntityPos - m_Position).Length();
|
double Distance = (EntityPos - m_Position).Length();
|
||||||
|
|
||||||
cPickup * OtherPickup = static_cast<cPickup *>(a_Entity);
|
auto & OtherPickup = static_cast<cPickup &>(a_Entity);
|
||||||
cItem & Item = OtherPickup->GetItem();
|
cItem & Item = OtherPickup.GetItem();
|
||||||
if ((Distance < 1.2) && Item.IsEqual(m_Pickup->GetItem()) && OtherPickup->CanCombine())
|
if ((Distance < 1.2) && Item.IsEqual(m_Pickup->GetItem()) && OtherPickup.CanCombine())
|
||||||
{
|
{
|
||||||
short CombineCount = Item.m_ItemCount;
|
short CombineCount = Item.m_ItemCount;
|
||||||
if ((CombineCount + m_Pickup->GetItem().m_ItemCount) > Item.GetMaxStackSize())
|
if ((CombineCount + m_Pickup->GetItem().m_ItemCount) > Item.GetMaxStackSize())
|
||||||
@ -64,16 +63,16 @@ public:
|
|||||||
int DiffX = FloorC(m_Pickup->GetPosX() * 32.0) - FloorC(EntityPos.x * 32.0);
|
int DiffX = FloorC(m_Pickup->GetPosX() * 32.0) - FloorC(EntityPos.x * 32.0);
|
||||||
int DiffY = FloorC(m_Pickup->GetPosY() * 32.0) - FloorC(EntityPos.y * 32.0);
|
int DiffY = FloorC(m_Pickup->GetPosY() * 32.0) - FloorC(EntityPos.y * 32.0);
|
||||||
int DiffZ = FloorC(m_Pickup->GetPosZ() * 32.0) - FloorC(EntityPos.z * 32.0);
|
int DiffZ = FloorC(m_Pickup->GetPosZ() * 32.0) - FloorC(EntityPos.z * 32.0);
|
||||||
a_Entity->GetWorld()->BroadcastEntityRelMove(*a_Entity, static_cast<char>(DiffX), static_cast<char>(DiffY), static_cast<char>(DiffZ));
|
a_Entity.GetWorld()->BroadcastEntityRelMove(a_Entity, static_cast<char>(DiffX), static_cast<char>(DiffY), static_cast<char>(DiffZ));
|
||||||
/* End of experimental animation */
|
/* End of experimental animation */
|
||||||
a_Entity->Destroy();
|
a_Entity.Destroy();
|
||||||
|
|
||||||
// Reset the timer
|
// Reset the timer
|
||||||
m_Pickup->SetAge(0);
|
m_Pickup->SetAge(0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
a_Entity->GetWorld()->BroadcastEntityMetadata(*a_Entity);
|
a_Entity.GetWorld()->BroadcastEntityMetadata(a_Entity);
|
||||||
}
|
}
|
||||||
m_FoundMatchingPickup = true;
|
m_FoundMatchingPickup = true;
|
||||||
}
|
}
|
||||||
|
@ -1005,36 +1005,21 @@ bool cPlayer::DoTakeDamage(TakeDamageInfo & a_TDI)
|
|||||||
void cPlayer::NotifyNearbyWolves(cPawn * a_Opponent, bool a_IsPlayerInvolved)
|
void cPlayer::NotifyNearbyWolves(cPawn * a_Opponent, bool a_IsPlayerInvolved)
|
||||||
{
|
{
|
||||||
ASSERT(a_Opponent != nullptr);
|
ASSERT(a_Opponent != nullptr);
|
||||||
class LookForWolves : public cEntityCallback
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
cPlayer * m_Player;
|
|
||||||
cPawn * m_Attacker;
|
|
||||||
bool m_IsPlayerInvolved;
|
|
||||||
|
|
||||||
LookForWolves(cPlayer * a_Me, cPawn * a_MyAttacker, bool a_PlayerInvolved) :
|
m_World->ForEachEntityInBox(cBoundingBox(GetPosition(), 16), [&] (cEntity & a_Entity)
|
||||||
m_Player(a_Me),
|
|
||||||
m_Attacker(a_MyAttacker),
|
|
||||||
m_IsPlayerInvolved(a_PlayerInvolved)
|
|
||||||
{
|
{
|
||||||
}
|
if (a_Entity.IsMob())
|
||||||
|
|
||||||
virtual bool Item(cEntity * a_Entity) override
|
|
||||||
{
|
|
||||||
if (a_Entity->IsMob())
|
|
||||||
{
|
{
|
||||||
cMonster * Mob = static_cast<cMonster*>(a_Entity);
|
auto & Mob = static_cast<cMonster&>(a_Entity);
|
||||||
if (Mob->GetMobType() == mtWolf)
|
if (Mob.GetMobType() == mtWolf)
|
||||||
{
|
{
|
||||||
cWolf * Wolf = static_cast<cWolf*>(Mob);
|
auto & Wolf = static_cast<cWolf&>(Mob);
|
||||||
Wolf->ReceiveNearbyFightInfo(m_Player->GetUUID(), m_Attacker, m_IsPlayerInvolved);
|
Wolf.ReceiveNearbyFightInfo(GetUUID(), a_Opponent, a_IsPlayerInvolved);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} Callback(this, a_Opponent, a_IsPlayerInvolved);
|
);
|
||||||
|
|
||||||
m_World->ForEachEntityInBox(cBoundingBox(GetPosition(), 16), Callback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2415,17 +2400,12 @@ void cPlayer::HandleFloater()
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
class cFloaterCallback :
|
m_World->DoWithEntityByID(m_FloaterID, [](cEntity & a_Entity)
|
||||||
public cEntityCallback
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual bool Item(cEntity * a_Entity) override
|
|
||||||
{
|
{
|
||||||
a_Entity->Destroy(true);
|
a_Entity.Destroy(true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} Callback;
|
);
|
||||||
m_World->DoWithEntityByID(m_FloaterID, Callback);
|
|
||||||
SetIsFishing(false);
|
SetIsFishing(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2669,29 +2649,18 @@ bool cPlayer::DoesPlacingBlocksIntersectEntity(const sSetBlockVector & a_Blocks)
|
|||||||
cWorld * World = GetWorld();
|
cWorld * World = GetWorld();
|
||||||
|
|
||||||
// Check to see if any entity intersects any block being placed
|
// Check to see if any entity intersects any block being placed
|
||||||
class DoesIntersectBlock : public cEntityCallback
|
return !World->ForEachEntityInBox(PlacingBounds, [&](cEntity & a_Entity)
|
||||||
{
|
|
||||||
public:
|
|
||||||
const std::vector<cBoundingBox> & m_BoundingBoxes;
|
|
||||||
|
|
||||||
// The distance inside the block the entity can still be.
|
|
||||||
const double EPSILON = 0.0005;
|
|
||||||
|
|
||||||
DoesIntersectBlock(const std::vector<cBoundingBox> & a_BoundingBoxes) :
|
|
||||||
m_BoundingBoxes(a_BoundingBoxes)
|
|
||||||
{
|
{
|
||||||
}
|
// The distance inside the block the entity can still be.
|
||||||
|
const double EPSILON = 0.0005;
|
||||||
|
|
||||||
virtual bool Item(cEntity * a_Entity) override
|
if (!a_Entity.DoesPreventBlockPlacement())
|
||||||
{
|
|
||||||
if (!a_Entity->DoesPreventBlockPlacement())
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
cBoundingBox EntBox(a_Entity->GetPosition(), a_Entity->GetWidth() / 2, a_Entity->GetHeight());
|
cBoundingBox EntBox(a_Entity.GetPosition(), a_Entity.GetWidth() / 2, a_Entity.GetHeight());
|
||||||
for (auto BlockBox: m_BoundingBoxes)
|
for (auto BlockBox : PlacementBoxes)
|
||||||
{
|
{
|
||||||
|
|
||||||
// Put in a little bit of wiggle room
|
// Put in a little bit of wiggle room
|
||||||
BlockBox.Expand(-EPSILON, -EPSILON, -EPSILON);
|
BlockBox.Expand(-EPSILON, -EPSILON, -EPSILON);
|
||||||
if (EntBox.DoesIntersect(BlockBox))
|
if (EntBox.DoesIntersect(BlockBox))
|
||||||
@ -2701,15 +2670,7 @@ bool cPlayer::DoesPlacingBlocksIntersectEntity(const sSetBlockVector & a_Blocks)
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} Callback(PlacementBoxes);
|
);
|
||||||
|
|
||||||
// See if any entities in that bounding box collide with anyone
|
|
||||||
if (!World->ForEachEntityInBox(PlacingBounds, Callback))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -126,8 +126,7 @@ protected:
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// cProjectileEntityCollisionCallback:
|
// cProjectileEntityCollisionCallback:
|
||||||
|
|
||||||
class cProjectileEntityCollisionCallback :
|
class cProjectileEntityCollisionCallback
|
||||||
public cEntityCallback
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
cProjectileEntityCollisionCallback(cProjectileEntity * a_Projectile, const Vector3d & a_Pos, const Vector3d & a_NextPos) :
|
cProjectileEntityCollisionCallback(cProjectileEntity * a_Projectile, const Vector3d & a_Pos, const Vector3d & a_NextPos) :
|
||||||
@ -140,11 +139,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual bool Item(cEntity * a_Entity) override
|
bool operator () (cEntity & a_Entity)
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
(a_Entity == m_Projectile) || // Do not check collisions with self
|
(&a_Entity == m_Projectile) || // Do not check collisions with self
|
||||||
(a_Entity->GetUniqueID() == m_Projectile->GetCreatorUniqueID()) // Do not check whoever shot the projectile
|
(a_Entity.GetUniqueID() == m_Projectile->GetCreatorUniqueID()) // Do not check whoever shot the projectile
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// Don't check creator only for the first 5 ticks so that projectiles can collide with the creator
|
// Don't check creator only for the first 5 ticks so that projectiles can collide with the creator
|
||||||
@ -154,7 +153,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cBoundingBox EntBox(a_Entity->GetPosition(), a_Entity->GetWidth() / 2, a_Entity->GetHeight());
|
cBoundingBox EntBox(a_Entity.GetPosition(), a_Entity.GetWidth() / 2, a_Entity.GetHeight());
|
||||||
|
|
||||||
// Instead of colliding the bounding box with another bounding box in motion, we collide an enlarged bounding box with a hairline.
|
// Instead of colliding the bounding box with another bounding box in motion, we collide an enlarged bounding box with a hairline.
|
||||||
// The results should be good enough for our purposes
|
// The results should be good enough for our purposes
|
||||||
@ -168,20 +167,20 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!a_Entity->IsMob() &&
|
!a_Entity.IsMob() &&
|
||||||
!a_Entity->IsMinecart() &&
|
!a_Entity.IsMinecart() &&
|
||||||
(
|
(
|
||||||
!a_Entity->IsPlayer() ||
|
!a_Entity.IsPlayer() ||
|
||||||
static_cast<cPlayer *>(a_Entity)->IsGameModeSpectator()
|
static_cast<cPlayer &>(a_Entity).IsGameModeSpectator()
|
||||||
) &&
|
) &&
|
||||||
!a_Entity->IsBoat()
|
!a_Entity.IsBoat()
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// Not an entity that interacts with a projectile
|
// Not an entity that interacts with a projectile
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cPluginManager::Get()->CallHookProjectileHitEntity(*m_Projectile, *a_Entity))
|
if (cPluginManager::Get()->CallHookProjectileHitEntity(*m_Projectile, a_Entity))
|
||||||
{
|
{
|
||||||
// A plugin disagreed.
|
// A plugin disagreed.
|
||||||
return false;
|
return false;
|
||||||
@ -191,7 +190,7 @@ public:
|
|||||||
{
|
{
|
||||||
// The entity is closer than anything we've stored so far, replace it as the potential victim
|
// The entity is closer than anything we've stored so far, replace it as the potential victim
|
||||||
m_MinCoeff = LineCoeff;
|
m_MinCoeff = LineCoeff;
|
||||||
m_HitEntity = a_Entity;
|
m_HitEntity = &a_Entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't break the enumeration, we want all the entities
|
// Don't break the enumeration, we want all the entities
|
||||||
@ -327,20 +326,13 @@ void cProjectileEntity::OnHitEntity(cEntity & a_EntityHit, Vector3d a_HitPos)
|
|||||||
// If we were created by a player and we hit a pawn, notify attacking player's wolves
|
// If we were created by a player and we hit a pawn, notify attacking player's wolves
|
||||||
if (a_EntityHit.IsPawn() && (GetCreatorName() != ""))
|
if (a_EntityHit.IsPawn() && (GetCreatorName() != ""))
|
||||||
{
|
{
|
||||||
class cNotifyWolves : public cEntityCallback
|
auto EntityHit = static_cast<cPawn *>(&a_EntityHit);
|
||||||
{
|
m_World->DoWithEntityByID(GetCreatorUniqueID(), [=](cEntity & a_Hitter)
|
||||||
public:
|
|
||||||
cPawn * m_EntityHit;
|
|
||||||
|
|
||||||
virtual bool Item(cEntity * a_Hitter) override
|
|
||||||
{
|
{
|
||||||
static_cast<cPlayer*>(a_Hitter)->NotifyNearbyWolves(m_EntityHit, true);
|
static_cast<cPlayer&>(a_Hitter).NotifyNearbyWolves(EntityHit, true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} Callback;
|
);
|
||||||
|
|
||||||
Callback.m_EntityHit = static_cast<cPawn*>(&a_EntityHit);
|
|
||||||
m_World->DoWithEntityByID(GetCreatorUniqueID(), Callback);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,60 +16,6 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// cSplashPotionEntityCallback:
|
|
||||||
|
|
||||||
/** Used to distribute the splashed potion effect among nearby entities */
|
|
||||||
class cSplashPotionCallback :
|
|
||||||
public cEntityCallback
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/** Creates the callback.
|
|
||||||
@param a_HitPos The position where the splash potion has splashed
|
|
||||||
@param a_EntityEffectType The effect type of the potion
|
|
||||||
@param a_EntityEffect The effect description */
|
|
||||||
cSplashPotionCallback(Vector3d a_HitPos, cEntityEffect::eType a_EntityEffectType, const cEntityEffect & a_EntityEffect) :
|
|
||||||
m_HitPos(a_HitPos),
|
|
||||||
m_EntityEffectType(a_EntityEffectType),
|
|
||||||
m_EntityEffect(a_EntityEffect)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Called by cWorld::ForEachEntity(), adds the stored entity effect to the entity, if it is close enough. */
|
|
||||||
virtual bool Item(cEntity * a_Entity) override
|
|
||||||
{
|
|
||||||
if (!a_Entity->IsPawn())
|
|
||||||
{
|
|
||||||
// Not an entity that can take effects
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
double SplashDistance = (a_Entity->GetPosition() - m_HitPos).Length();
|
|
||||||
if (SplashDistance >= 20)
|
|
||||||
{
|
|
||||||
// Too far away
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// y = -0.25x + 1, where x is the distance from the player. Approximation for potion splash.
|
|
||||||
// TODO: better equation
|
|
||||||
double Reduction = -0.25 * SplashDistance + 1.0;
|
|
||||||
Reduction = std::max(Reduction, 0.0);
|
|
||||||
|
|
||||||
static_cast<cPawn *>(a_Entity)->AddEntityEffect(m_EntityEffectType, m_EntityEffect.GetDuration(), m_EntityEffect.GetIntensity(), Reduction);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Vector3d m_HitPos;
|
|
||||||
cEntityEffect::eType m_EntityEffectType;
|
|
||||||
const cEntityEffect & m_EntityEffect;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// cSplashPotionEntity:
|
// cSplashPotionEntity:
|
||||||
|
|
||||||
@ -119,8 +65,30 @@ void cSplashPotionEntity::OnHitEntity(cEntity & a_EntityHit, Vector3d a_HitPos)
|
|||||||
|
|
||||||
void cSplashPotionEntity::Splash(Vector3d a_HitPos)
|
void cSplashPotionEntity::Splash(Vector3d a_HitPos)
|
||||||
{
|
{
|
||||||
cSplashPotionCallback Callback(a_HitPos, m_EntityEffectType, m_EntityEffect);
|
m_World->ForEachEntity([=](cEntity & a_Entity)
|
||||||
m_World->ForEachEntity(Callback);
|
{
|
||||||
|
if (!a_Entity.IsPawn())
|
||||||
|
{
|
||||||
|
// Not an entity that can take effects
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
double SplashDistance = (a_Entity.GetPosition() - a_HitPos).Length();
|
||||||
|
if (SplashDistance >= 20)
|
||||||
|
{
|
||||||
|
// Too far away
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// y = -0.25x + 1, where x is the distance from the player. Approximation for potion splash.
|
||||||
|
// TODO: better equation
|
||||||
|
double Reduction = -0.25 * SplashDistance + 1.0;
|
||||||
|
Reduction = std::max(Reduction, 0.0);
|
||||||
|
|
||||||
|
static_cast<cPawn &>(a_Entity).AddEntityEffect(m_EntityEffectType, m_EntityEffect.GetDuration(), m_EntityEffect.GetIntensity(), Reduction);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
m_World->BroadcastSoundParticleEffect(
|
m_World->BroadcastSoundParticleEffect(
|
||||||
EffectID::PARTICLE_SPLASH_POTION,
|
EffectID::PARTICLE_SPLASH_POTION,
|
||||||
|
@ -74,29 +74,12 @@ void cThrownEnderPearlEntity::TeleportCreator(Vector3d a_HitPos)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
class cProjectileCreatorCallbackForPlayers : public cPlayerListCallback
|
GetWorld()->FindAndDoWithPlayer(m_CreatorData.m_Name, [=](cPlayer & a_Entity)
|
||||||
{
|
|
||||||
public:
|
|
||||||
cProjectileCreatorCallbackForPlayers(cEntity * a_Attacker, Vector3i a_CallbackHitPos) :
|
|
||||||
m_Attacker(a_Attacker),
|
|
||||||
m_HitPos(a_CallbackHitPos)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool Item(cPlayer * a_Entity) override
|
|
||||||
{
|
{
|
||||||
// Teleport the creator here, make them take 5 damage:
|
// Teleport the creator here, make them take 5 damage:
|
||||||
a_Entity->TeleportToCoords(m_HitPos.x, m_HitPos.y + 0.2, m_HitPos.z);
|
a_Entity.TeleportToCoords(a_HitPos.x, a_HitPos.y + 0.2, a_HitPos.z);
|
||||||
a_Entity->TakeDamage(dtEnderPearl, m_Attacker, 5, 0);
|
a_Entity.TakeDamage(dtEnderPearl, this, 5, 0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
);
|
||||||
private:
|
|
||||||
|
|
||||||
cEntity * m_Attacker;
|
|
||||||
Vector3i m_HitPos;
|
|
||||||
};
|
|
||||||
|
|
||||||
cProjectileCreatorCallbackForPlayers PCCFP(this, a_HitPos);
|
|
||||||
GetWorld()->FindAndDoWithPlayer(m_CreatorData.m_Name, PCCFP);
|
|
||||||
}
|
}
|
||||||
|
58
src/FunctionRef.h
Normal file
58
src/FunctionRef.h
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// Declared only so it can be partially specialized
|
||||||
|
template <class Signature>
|
||||||
|
class cFunctionRef;
|
||||||
|
|
||||||
|
/** A light-weight, type-erased reference to a function object.
|
||||||
|
This is similar to a std::function but doesn't copy the function object
|
||||||
|
which means that mutable function objects will be modified for the caller
|
||||||
|
but would not be if using a std::function (See #3990 for implications of this).
|
||||||
|
A cFunctionRef has no empty state but is non-owning and so is safe to call
|
||||||
|
as long as the referred object is still alive. */
|
||||||
|
template <class Ret, class... Args>
|
||||||
|
class cFunctionRef<Ret(Args...)>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/** Construct from a function object. */
|
||||||
|
template <class FunctionObject>
|
||||||
|
cFunctionRef(FunctionObject && a_FunctionObject)
|
||||||
|
{
|
||||||
|
// Store an opaque reference to the object.
|
||||||
|
m_CallableData = &a_FunctionObject;
|
||||||
|
|
||||||
|
// Along with a function that knows how to call the object.
|
||||||
|
m_CallFunction = &ObjectFunctionCaller<FunctionObject>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Call the referenced function object */
|
||||||
|
Ret operator () (Args... a_Args)
|
||||||
|
{
|
||||||
|
return m_CallFunction(m_CallableData, std::forward<Args>(a_Args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
/** Function that performs the call. */
|
||||||
|
template <class ObjectType>
|
||||||
|
static Ret ObjectFunctionCaller(void * a_Callable, Args... a_Args)
|
||||||
|
{
|
||||||
|
// Convert opaque reference to the concrete type.
|
||||||
|
using ObjectPtr = typename std::add_pointer<ObjectType>::type;
|
||||||
|
auto & Object = *static_cast<ObjectPtr>(a_Callable);
|
||||||
|
|
||||||
|
// Forward the call down to the object.
|
||||||
|
return Object(std::forward<Args>(a_Args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
using cCallFunction = Ret(*)(void *, Args...);
|
||||||
|
|
||||||
|
/** Type erased reference to a callable. */
|
||||||
|
void * m_CallableData;
|
||||||
|
|
||||||
|
/** Function that knows how to call the type erased reference. */
|
||||||
|
cCallFunction m_CallFunction;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
@ -416,20 +416,6 @@ template class SizeChecker<UInt8, 1>;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** A generic interface used mainly in ForEach() functions */
|
|
||||||
template <typename Type> class cItemCallback
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual ~cItemCallback() {}
|
|
||||||
|
|
||||||
/** Called for each item in the internal list; return true to stop the loop, or false to continue enumerating */
|
|
||||||
virtual bool Item(Type * a_Type) = 0;
|
|
||||||
} ;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** Clamp X to the specified range. */
|
/** Clamp X to the specified range. */
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T Clamp(T a_Value, T a_Min, T a_Max)
|
T Clamp(T a_Value, T a_Min, T a_Max)
|
||||||
|
@ -20,8 +20,7 @@
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// cFloaterCallback
|
// cFloaterCallback
|
||||||
class cFloaterCallback :
|
class cFloaterCallback
|
||||||
public cEntityCallback
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
cFloaterCallback(void) :
|
cFloaterCallback(void) :
|
||||||
@ -30,13 +29,14 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool Item(cEntity * a_Entity) override
|
bool operator () (cEntity & a_Entity)
|
||||||
{
|
{
|
||||||
m_CanPickup = reinterpret_cast<cFloater *>(a_Entity)->CanPickup();
|
auto & Floater = static_cast<cFloater &>(a_Entity);
|
||||||
m_Pos = Vector3d(a_Entity->GetPosX(), a_Entity->GetPosY(), a_Entity->GetPosZ());
|
m_CanPickup = Floater.CanPickup();
|
||||||
m_BitePos = reinterpret_cast<cFloater *>(a_Entity)->GetBitePos();
|
m_Pos = Floater.GetPosition();
|
||||||
m_AttachedMobID = reinterpret_cast<cFloater *>(a_Entity)->GetAttachedMobID();
|
m_BitePos = Floater.GetBitePos();
|
||||||
a_Entity->Destroy(true);
|
m_AttachedMobID = Floater.GetAttachedMobID();
|
||||||
|
Floater.Destroy(true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,33 +57,6 @@ protected:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// cSweepEntityCallback:
|
|
||||||
|
|
||||||
class cSweepEntityCallback :
|
|
||||||
public cEntityCallback
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
cSweepEntityCallback(Vector3d a_PlayerPos) :
|
|
||||||
m_PlayerPos(a_PlayerPos)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool Item(cEntity * a_Entity) override
|
|
||||||
{
|
|
||||||
Vector3d Speed = m_PlayerPos - a_Entity->GetPosition();
|
|
||||||
a_Entity->AddSpeed(Speed);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Vector3d m_PlayerPos;
|
|
||||||
} ;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class cItemFishingRodHandler :
|
class cItemFishingRodHandler :
|
||||||
public cItemHandler
|
public cItemHandler
|
||||||
{
|
{
|
||||||
@ -117,8 +90,13 @@ public:
|
|||||||
|
|
||||||
if (FloaterInfo.IsAttached())
|
if (FloaterInfo.IsAttached())
|
||||||
{
|
{
|
||||||
cSweepEntityCallback SweepEntity(a_Player->GetPosition());
|
a_World->DoWithEntityByID(FloaterInfo.GetAttachedMobID(), [=](cEntity & a_Entity)
|
||||||
a_World->DoWithEntityByID(FloaterInfo.GetAttachedMobID(), SweepEntity);
|
{
|
||||||
|
Vector3d Speed = a_Player->GetPosition() - a_Entity.GetPosition();
|
||||||
|
a_Entity.AddSpeed(Speed);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
else if (FloaterInfo.CanPickup())
|
else if (FloaterInfo.CanPickup())
|
||||||
{
|
{
|
||||||
|
@ -62,42 +62,30 @@ public:
|
|||||||
int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace
|
int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// Use a callback to set the properties of the mob head block entity:
|
auto HeadType = static_cast<eMobHeadType>(a_EquippedItem.m_ItemDamage);
|
||||||
class cCallback : public cBlockEntityCallback
|
auto BlockMeta = static_cast<NIBBLETYPE>(a_BlockFace);
|
||||||
{
|
|
||||||
cPlayer & m_Player;
|
|
||||||
eMobHeadType m_HeadType;
|
|
||||||
NIBBLETYPE m_BlockMeta;
|
|
||||||
|
|
||||||
virtual bool Item(cBlockEntity * a_BlockEntity)
|
// Use a callback to set the properties of the mob head block entity:
|
||||||
|
a_World.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ, [&](cBlockEntity & a_BlockEntity)
|
||||||
{
|
{
|
||||||
if (a_BlockEntity->GetBlockType() != E_BLOCK_HEAD)
|
if (a_BlockEntity.GetBlockType() != E_BLOCK_HEAD)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto MobHeadEntity = static_cast<cMobHeadEntity *>(a_BlockEntity);
|
auto & MobHeadEntity = static_cast<cMobHeadEntity &>(a_BlockEntity);
|
||||||
|
|
||||||
int Rotation = 0;
|
int Rotation = 0;
|
||||||
if (m_BlockMeta == 1)
|
if (BlockMeta == 1)
|
||||||
{
|
{
|
||||||
Rotation = FloorC(m_Player.GetYaw() * 16.0f / 360.0f + 0.5f) & 0x0f;
|
Rotation = FloorC(a_Player.GetYaw() * 16.0f / 360.0f + 0.5f) & 0x0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
MobHeadEntity->SetType(m_HeadType);
|
MobHeadEntity.SetType(HeadType);
|
||||||
MobHeadEntity->SetRotation(static_cast<eMobHeadRotation>(Rotation));
|
MobHeadEntity.SetRotation(static_cast<eMobHeadRotation>(Rotation));
|
||||||
MobHeadEntity->GetWorld()->BroadcastBlockEntity(MobHeadEntity->GetPosX(), MobHeadEntity->GetPosY(), MobHeadEntity->GetPosZ());
|
MobHeadEntity.GetWorld()->BroadcastBlockEntity(MobHeadEntity.GetPosX(), MobHeadEntity.GetPosY(), MobHeadEntity.GetPosZ());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
);
|
||||||
public:
|
|
||||||
cCallback (cPlayer & a_CBPlayer, eMobHeadType a_HeadType, NIBBLETYPE a_BlockMeta) :
|
|
||||||
m_Player(a_CBPlayer),
|
|
||||||
m_HeadType(a_HeadType),
|
|
||||||
m_BlockMeta(a_BlockMeta)
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
cCallback Callback(a_Player, static_cast<eMobHeadType>(a_EquippedItem.m_ItemDamage), static_cast<NIBBLETYPE>(a_BlockFace));
|
|
||||||
a_World.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ, Callback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -243,24 +231,16 @@ public:
|
|||||||
// If it is a mob head, check the correct head type using the block entity:
|
// If it is a mob head, check the correct head type using the block entity:
|
||||||
if (BlockType == E_BLOCK_HEAD)
|
if (BlockType == E_BLOCK_HEAD)
|
||||||
{
|
{
|
||||||
class cHeadCallback: public cBlockEntityCallback
|
bool IsWitherHead = false;
|
||||||
{
|
a_World.DoWithBlockEntityAt(BlockX, BlockY, BlockZ, [&](cBlockEntity & a_Entity)
|
||||||
virtual bool Item(cBlockEntity * a_Entity) override
|
|
||||||
{
|
{
|
||||||
ASSERT(a_Entity->GetBlockType() == E_BLOCK_HEAD);
|
ASSERT(a_Entity.GetBlockType() == E_BLOCK_HEAD);
|
||||||
cMobHeadEntity * MobHead = static_cast<cMobHeadEntity *>(a_Entity);
|
auto & MobHead = static_cast<cMobHeadEntity &>(a_Entity);
|
||||||
m_IsWitherHead = (MobHead->GetType() == SKULL_TYPE_WITHER);
|
IsWitherHead = (MobHead.GetType() == SKULL_TYPE_WITHER);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
public:
|
);
|
||||||
cHeadCallback(void):
|
if (!IsWitherHead)
|
||||||
m_IsWitherHead(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
bool m_IsWitherHead;
|
|
||||||
} callback;
|
|
||||||
a_World.DoWithBlockEntityAt(BlockX, BlockY, BlockZ, callback);
|
|
||||||
if (!callback.m_IsWitherHead)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -287,25 +267,18 @@ public:
|
|||||||
/** Awards the achievement to all players close to the specified point. */
|
/** Awards the achievement to all players close to the specified point. */
|
||||||
void AwardSpawnWitherAchievement(cWorld & a_World, int a_BlockX, int a_BlockY, int a_BlockZ)
|
void AwardSpawnWitherAchievement(cWorld & a_World, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||||
{
|
{
|
||||||
class cPlayerCallback : public cPlayerListCallback
|
Vector3f Pos{ static_cast<float>(a_BlockX), static_cast<float>(a_BlockY), static_cast<float>(a_BlockZ) };
|
||||||
{
|
a_World.ForEachPlayer([=](cPlayer & a_Player)
|
||||||
Vector3f m_Pos;
|
|
||||||
|
|
||||||
virtual bool Item(cPlayer * a_Player)
|
|
||||||
{
|
{
|
||||||
// If player is close, award achievement:
|
// If player is close, award achievement:
|
||||||
double Dist = (a_Player->GetPosition() - m_Pos).Length();
|
double Dist = (a_Player.GetPosition() - Pos).Length();
|
||||||
if (Dist < 50.0)
|
if (Dist < 50.0)
|
||||||
{
|
{
|
||||||
a_Player->AwardAchievement(achSpawnWither);
|
a_Player.AwardAchievement(achSpawnWither);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
);
|
||||||
public:
|
|
||||||
cPlayerCallback(const Vector3f & a_Pos) : m_Pos(a_Pos) {}
|
|
||||||
} PlayerCallback(Vector3f(static_cast<float>(a_BlockX), static_cast<float>(a_BlockY), static_cast<float>(a_BlockZ)));
|
|
||||||
a_World.ForEachPlayer(PlayerCallback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -199,12 +199,12 @@ bool cLineBlockTracer::Trace(double a_StartX, double a_StartY, double a_StartZ,
|
|||||||
m_DiffY = m_EndY - m_StartY;
|
m_DiffY = m_EndY - m_StartY;
|
||||||
m_DiffZ = m_EndZ - m_StartZ;
|
m_DiffZ = m_EndZ - m_StartZ;
|
||||||
|
|
||||||
// The actual trace is handled with ChunkMapCS locked by calling our Item() for the specified chunk
|
// The actual trace is handled with ChunkMapCS locked by calling our ChunkCallback for the specified chunk
|
||||||
int BlockX = FloorC(m_StartX);
|
int BlockX = FloorC(m_StartX);
|
||||||
int BlockZ = FloorC(m_StartZ);
|
int BlockZ = FloorC(m_StartZ);
|
||||||
int ChunkX, ChunkZ;
|
int ChunkX, ChunkZ;
|
||||||
cChunkDef::BlockToChunk(BlockX, BlockZ, ChunkX, ChunkZ);
|
cChunkDef::BlockToChunk(BlockX, BlockZ, ChunkX, ChunkZ);
|
||||||
return m_World->DoWithChunk(ChunkX, ChunkZ, *this);
|
return m_World->DoWithChunk(ChunkX, ChunkZ, [this](cChunk & a_Chunk) { return ChunkCallback(&a_Chunk); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -308,7 +308,7 @@ bool cLineBlockTracer::MoveToNextBlock(void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cLineBlockTracer::Item(cChunk * a_Chunk)
|
bool cLineBlockTracer::ChunkCallback(cChunk * a_Chunk)
|
||||||
{
|
{
|
||||||
ASSERT((m_CurrentY >= 0) && (m_CurrentY < cChunkDef::Height)); // This should be provided by FixStartAboveWorld() / FixStartBelowWorld()
|
ASSERT((m_CurrentY >= 0) && (m_CurrentY < cChunkDef::Height)); // This should be provided by FixStartAboveWorld() / FixStartBelowWorld()
|
||||||
|
|
||||||
|
@ -18,17 +18,12 @@
|
|||||||
// fwd: Chunk.h
|
// fwd: Chunk.h
|
||||||
class cChunk;
|
class cChunk;
|
||||||
|
|
||||||
// fwd: cChunkMap.h
|
|
||||||
typedef cItemCallback<cChunk> cChunkCallback;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class cLineBlockTracer :
|
class cLineBlockTracer :
|
||||||
public cBlockTracer,
|
public cBlockTracer
|
||||||
public cChunkCallback
|
|
||||||
{
|
{
|
||||||
typedef cBlockTracer super;
|
typedef cBlockTracer super;
|
||||||
|
|
||||||
@ -109,8 +104,7 @@ protected:
|
|||||||
/** Moves m_Current to the next block on the line; returns false if no move is possible (reached the end) */
|
/** Moves m_Current to the next block on the line; returns false if no move is possible (reached the end) */
|
||||||
bool MoveToNextBlock(void);
|
bool MoveToNextBlock(void);
|
||||||
|
|
||||||
// cChunkCallback overrides:
|
bool ChunkCallback(cChunk * a_Chunk);
|
||||||
virtual bool Item(cChunk * a_Chunk) override;
|
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
42
src/Map.cpp
42
src/Map.cpp
@ -120,27 +120,17 @@ bool cMap::UpdatePixel(unsigned int a_X, unsigned int a_Z)
|
|||||||
int RelX = BlockX - (ChunkX * cChunkDef::Width);
|
int RelX = BlockX - (ChunkX * cChunkDef::Width);
|
||||||
int RelZ = BlockZ - (ChunkZ * cChunkDef::Width);
|
int RelZ = BlockZ - (ChunkZ * cChunkDef::Width);
|
||||||
|
|
||||||
class cCalculatePixelCb :
|
ASSERT(m_World != nullptr);
|
||||||
public cChunkCallback
|
|
||||||
{
|
|
||||||
cMap * m_Map;
|
|
||||||
|
|
||||||
int m_RelX, m_RelZ;
|
ColorID PixelData;
|
||||||
|
m_World->DoWithChunk(ChunkX, ChunkZ, [&](cChunk & a_Chunk)
|
||||||
ColorID m_PixelData;
|
|
||||||
|
|
||||||
public:
|
|
||||||
cCalculatePixelCb(cMap * a_Map, int a_RelX, int a_RelZ)
|
|
||||||
: m_Map(a_Map), m_RelX(a_RelX), m_RelZ(a_RelZ), m_PixelData(E_BASE_COLOR_TRANSPARENT) {}
|
|
||||||
|
|
||||||
virtual bool Item(cChunk * a_Chunk) override
|
|
||||||
{
|
{
|
||||||
if (!a_Chunk->IsValid())
|
if (!a_Chunk.IsValid())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_Map->GetDimension() == dimNether)
|
if (GetDimension() == dimNether)
|
||||||
{
|
{
|
||||||
// TODO 2014-02-22 xdot: Nether maps
|
// TODO 2014-02-22 xdot: Nether maps
|
||||||
|
|
||||||
@ -151,22 +141,22 @@ bool cMap::UpdatePixel(unsigned int a_X, unsigned int a_Z)
|
|||||||
BLOCKTYPE TargetBlock;
|
BLOCKTYPE TargetBlock;
|
||||||
NIBBLETYPE TargetMeta;
|
NIBBLETYPE TargetMeta;
|
||||||
|
|
||||||
auto Height = a_Chunk->GetHeight(m_RelX, m_RelZ);
|
auto Height = a_Chunk.GetHeight(RelX, RelZ);
|
||||||
auto ChunkHeight = cChunkDef::Height;
|
auto ChunkHeight = cChunkDef::Height;
|
||||||
a_Chunk->GetBlockTypeMeta(m_RelX, Height, m_RelZ, TargetBlock, TargetMeta);
|
a_Chunk.GetBlockTypeMeta(RelX, Height, RelZ, TargetBlock, TargetMeta);
|
||||||
auto ColourID = BlockHandler(TargetBlock)->GetMapBaseColourID(TargetMeta);
|
auto ColourID = BlockHandler(TargetBlock)->GetMapBaseColourID(TargetMeta);
|
||||||
|
|
||||||
if (IsBlockWater(TargetBlock))
|
if (IsBlockWater(TargetBlock))
|
||||||
{
|
{
|
||||||
ChunkHeight /= 4;
|
ChunkHeight /= 4;
|
||||||
while (((--Height) != -1) && IsBlockWater(a_Chunk->GetBlock(m_RelX, Height, m_RelZ)))
|
while (((--Height) != -1) && IsBlockWater(a_Chunk.GetBlock(RelX, Height, RelZ)))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ColourID == 0)
|
else if (ColourID == 0)
|
||||||
{
|
{
|
||||||
while (((--Height) != -1) && ((ColourID = BlockHandler(a_Chunk->GetBlock(m_RelX, Height, m_RelZ))->GetMapBaseColourID(a_Chunk->GetMeta(m_RelX, Height, m_RelZ))) == 0))
|
while (((--Height) != -1) && ((ColourID = BlockHandler(a_Chunk.GetBlock(RelX, Height, RelZ))->GetMapBaseColourID(a_Chunk.GetMeta(RelX, Height, RelZ))) == 0))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -174,20 +164,12 @@ bool cMap::UpdatePixel(unsigned int a_X, unsigned int a_Z)
|
|||||||
|
|
||||||
// Multiply base color ID by 4 and add brightness ID
|
// Multiply base color ID by 4 and add brightness ID
|
||||||
const int BrightnessIDSize = static_cast<int>(BrightnessID.size());
|
const int BrightnessIDSize = static_cast<int>(BrightnessID.size());
|
||||||
m_PixelData = ColourID * 4 + BrightnessID[static_cast<size_t>(Clamp<int>((BrightnessIDSize * Height) / ChunkHeight, 0, BrightnessIDSize - 1))];
|
PixelData = ColourID * 4 + BrightnessID[static_cast<size_t>(Clamp<int>((BrightnessIDSize * Height) / ChunkHeight, 0, BrightnessIDSize - 1))];
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
);
|
||||||
|
|
||||||
ColorID GetPixelData(void) const
|
SetPixel(a_X, a_Z, PixelData);
|
||||||
{
|
|
||||||
return m_PixelData;
|
|
||||||
}
|
|
||||||
} CalculatePixelCb(this, RelX, RelZ);
|
|
||||||
|
|
||||||
ASSERT(m_World != nullptr);
|
|
||||||
m_World->DoWithChunk(ChunkX, ChunkZ, CalculatePixelCb);
|
|
||||||
|
|
||||||
SetPixel(a_X, a_Z, CalculatePixelCb.GetPixelData());
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ cMapManager::cMapManager(cWorld * a_World)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cMapManager::DoWithMap(UInt32 a_ID, cMapCallback & a_Callback)
|
bool cMapManager::DoWithMap(UInt32 a_ID, cMapCallback a_Callback)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CS);
|
cCSLock Lock(m_CS);
|
||||||
cMap * Map = GetMapData(a_ID);
|
cMap * Map = GetMapData(a_ID);
|
||||||
@ -33,7 +33,7 @@ bool cMapManager::DoWithMap(UInt32 a_ID, cMapCallback & a_Callback)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
a_Callback.Item(Map);
|
a_Callback(*Map);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,12 +11,13 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "FunctionRef.h"
|
||||||
#include "Map.h"
|
#include "Map.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef cItemCallback<cMap> cMapCallback;
|
using cMapCallback = cFunctionRef<bool(cMap &)>;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -41,7 +42,7 @@ public:
|
|||||||
/** Calls the callback for the map with the specified ID.
|
/** Calls the callback for the map with the specified ID.
|
||||||
Returns true if the map was found and the callback called, false if map not found.
|
Returns true if the map was found and the callback called, false if map not found.
|
||||||
Callback return value is ignored. */
|
Callback return value is ignored. */
|
||||||
bool DoWithMap(UInt32 a_ID, cMapCallback & a_Callback); // Exported in ManualBindings.cpp
|
bool DoWithMap(UInt32 a_ID, cMapCallback a_Callback); // Exported in ManualBindings.cpp
|
||||||
|
|
||||||
/** Ticks each registered map */
|
/** Ticks each registered map */
|
||||||
void TickMaps(void);
|
void TickMaps(void);
|
||||||
|
@ -369,7 +369,7 @@ cMonster * cMobSpawner::TryToSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY,
|
|||||||
auto NewMobPtr = newMob.get();
|
auto NewMobPtr = newMob.get();
|
||||||
if (newMob)
|
if (newMob)
|
||||||
{
|
{
|
||||||
m_Spawned.insert(std::move(newMob));
|
m_Spawned.push_back(std::move(newMob));
|
||||||
}
|
}
|
||||||
return NewMobPtr;
|
return NewMobPtr;
|
||||||
}
|
}
|
||||||
@ -390,15 +390,6 @@ void cMobSpawner::NewPack()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
cMobSpawner::tSpawnedContainer & cMobSpawner::getSpawned(void)
|
|
||||||
{
|
|
||||||
return m_Spawned;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cMobSpawner::CanSpawnAnything(void)
|
bool cMobSpawner::CanSpawnAnything(void)
|
||||||
{
|
{
|
||||||
return !m_AllowedTypes.empty();
|
return !m_AllowedTypes.empty();
|
||||||
|
@ -37,8 +37,10 @@ public :
|
|||||||
// return true if there is at least one allowed type
|
// return true if there is at least one allowed type
|
||||||
bool CanSpawnAnything(void);
|
bool CanSpawnAnything(void);
|
||||||
|
|
||||||
typedef const std::set<std::unique_ptr<cMonster>> tSpawnedContainer;
|
std::vector<std::unique_ptr<cMonster>> & getSpawned(void)
|
||||||
tSpawnedContainer & getSpawned(void);
|
{
|
||||||
|
return m_Spawned;
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns true if specified type of mob can spawn on specified block */
|
/** Returns true if specified type of mob can spawn on specified block */
|
||||||
static bool CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, eMonsterType a_MobType, EMCSBiome a_Biome);
|
static bool CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, eMonsterType a_MobType, EMCSBiome a_Biome);
|
||||||
@ -55,7 +57,7 @@ protected :
|
|||||||
std::set<eMonsterType> m_AllowedTypes;
|
std::set<eMonsterType> m_AllowedTypes;
|
||||||
bool m_NewPack;
|
bool m_NewPack;
|
||||||
eMonsterType m_MobType;
|
eMonsterType m_MobType;
|
||||||
std::set<std::unique_ptr<cMonster>> m_Spawned;
|
std::vector<std::unique_ptr<cMonster>> m_Spawned;
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
@ -81,21 +81,16 @@ void cCreeper::GetDrops(cItems & a_Drops, cEntity * a_Killer)
|
|||||||
a_Killer->IsProjectile() &&
|
a_Killer->IsProjectile() &&
|
||||||
((reinterpret_cast<cProjectileEntity *>(a_Killer))->GetCreatorUniqueID() != cEntity::INVALID_ID))
|
((reinterpret_cast<cProjectileEntity *>(a_Killer))->GetCreatorUniqueID() != cEntity::INVALID_ID))
|
||||||
{
|
{
|
||||||
class cProjectileCreatorCallback : public cEntityCallback
|
auto ProjectileCreatorCallback = [](cEntity & a_Entity)
|
||||||
{
|
|
||||||
public:
|
|
||||||
cProjectileCreatorCallback(void) {}
|
|
||||||
|
|
||||||
virtual bool Item(cEntity * a_Entity) override
|
|
||||||
{
|
{
|
||||||
if (a_Entity->IsMob() && ((reinterpret_cast<cMonster *>(a_Entity))->GetMobType() == mtSkeleton))
|
if (a_Entity.IsMob() && ((static_cast<cMonster &>(a_Entity)).GetMobType() == mtSkeleton))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
};
|
||||||
} PCC;
|
|
||||||
if (GetWorld()->DoWithEntityByID((reinterpret_cast<cProjectileEntity *>(a_Killer))->GetCreatorUniqueID(), PCC))
|
if (GetWorld()->DoWithEntityByID(static_cast<cProjectileEntity *>(a_Killer)->GetCreatorUniqueID(), ProjectileCreatorCallback))
|
||||||
{
|
{
|
||||||
AddRandomDropItem(a_Drops, 1, 1, static_cast<short>(m_World->GetTickRandomNumber(11) + E_ITEM_FIRST_DISC));
|
AddRandomDropItem(a_Drops, 1, 1, static_cast<short>(m_World->GetTickRandomNumber(11) + E_ITEM_FIRST_DISC));
|
||||||
}
|
}
|
||||||
|
@ -10,8 +10,7 @@
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// cPlayerLookCheck
|
// cPlayerLookCheck
|
||||||
class cPlayerLookCheck :
|
class cPlayerLookCheck
|
||||||
public cPlayerListCallback
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
cPlayerLookCheck(Vector3d a_EndermanPos, int a_SightDistance) :
|
cPlayerLookCheck(Vector3d a_EndermanPos, int a_SightDistance) :
|
||||||
@ -21,29 +20,29 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool Item(cPlayer * a_Player) override
|
bool operator () (cPlayer & a_Player)
|
||||||
{
|
{
|
||||||
// Don't check players who cannot be targeted
|
// Don't check players who cannot be targeted
|
||||||
if (!a_Player->CanMobsTarget())
|
if (!a_Player.CanMobsTarget())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't check players who are more than SightDistance (64) blocks away
|
// Don't check players who are more than SightDistance (64) blocks away
|
||||||
auto Direction = m_EndermanPos - a_Player->GetPosition();
|
auto Direction = m_EndermanPos - a_Player.GetPosition();
|
||||||
if (Direction.Length() > m_SightDistance)
|
if (Direction.Length() > m_SightDistance)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't check if the player has a pumpkin on his head
|
// Don't check if the player has a pumpkin on his head
|
||||||
if (a_Player->GetEquippedHelmet().m_ItemType == E_BLOCK_PUMPKIN)
|
if (a_Player.GetEquippedHelmet().m_ItemType == E_BLOCK_PUMPKIN)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the player's crosshair is within 5 degrees of the enderman, it counts as looking
|
// If the player's crosshair is within 5 degrees of the enderman, it counts as looking
|
||||||
auto LookVector = a_Player->GetLookVector();
|
auto LookVector = a_Player.GetLookVector();
|
||||||
auto dot = Direction.Dot(LookVector);
|
auto dot = Direction.Dot(LookVector);
|
||||||
if (dot <= cos(0.09)) // 0.09 rad ~ 5 degrees
|
if (dot <= cos(0.09)) // 0.09 rad ~ 5 degrees
|
||||||
{
|
{
|
||||||
@ -51,13 +50,13 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Check if endermen are angered through water in Vanilla
|
// TODO: Check if endermen are angered through water in Vanilla
|
||||||
if (!cLineBlockTracer::LineOfSightTrace(*a_Player->GetWorld(), m_EndermanPos, a_Player->GetPosition(), cLineBlockTracer::losAirWater))
|
if (!cLineBlockTracer::LineOfSightTrace(*a_Player.GetWorld(), m_EndermanPos, a_Player.GetPosition(), cLineBlockTracer::losAirWater))
|
||||||
{
|
{
|
||||||
// No direct line of sight
|
// No direct line of sight
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Player = a_Player;
|
m_Player = &a_Player;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,30 +90,25 @@ void cOcelot::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
|
|||||||
|
|
||||||
void cOcelot::TickFollowPlayer()
|
void cOcelot::TickFollowPlayer()
|
||||||
{
|
{
|
||||||
class cCallback :
|
Vector3d OwnerPos;
|
||||||
public cPlayerListCallback
|
bool OwnerFlying = false;
|
||||||
|
auto Callback = [&](cPlayer & a_Player)
|
||||||
{
|
{
|
||||||
virtual bool Item(cPlayer * a_Player) override
|
OwnerPos = a_Player.GetPosition();
|
||||||
{
|
OwnerFlying = a_Player.IsFlying();
|
||||||
OwnerPos = a_Player->GetPosition();
|
return true;
|
||||||
OwnerFlying = a_Player->IsFlying();
|
};
|
||||||
return true;
|
|
||||||
}
|
|
||||||
public:
|
|
||||||
Vector3d OwnerPos;
|
|
||||||
bool OwnerFlying;
|
|
||||||
} Callback;
|
|
||||||
|
|
||||||
if (m_World->DoWithPlayerByUUID(m_OwnerUUID, Callback))
|
if (m_World->DoWithPlayerByUUID(m_OwnerUUID, Callback))
|
||||||
{
|
{
|
||||||
// The player is present in the world, follow him:
|
// The player is present in the world, follow him:
|
||||||
double Distance = (Callback.OwnerPos - GetPosition()).Length();
|
double Distance = (OwnerPos - GetPosition()).Length();
|
||||||
if (Distance > 12)
|
if (Distance > 12)
|
||||||
{
|
{
|
||||||
if (!Callback.OwnerFlying)
|
if (!OwnerFlying)
|
||||||
{
|
{
|
||||||
Callback.OwnerPos.y = FindFirstNonAirBlockPosition(Callback.OwnerPos.x, Callback.OwnerPos.z);
|
OwnerPos.y = FindFirstNonAirBlockPosition(OwnerPos.x, OwnerPos.z);
|
||||||
TeleportToCoords(Callback.OwnerPos.x, Callback.OwnerPos.y, Callback.OwnerPos.z);
|
TeleportToCoords(OwnerPos.x, OwnerPos.y, OwnerPos.z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Distance < 2)
|
if (Distance < 2)
|
||||||
@ -122,9 +117,9 @@ void cOcelot::TickFollowPlayer()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!Callback.OwnerFlying)
|
if (!OwnerFlying)
|
||||||
{
|
{
|
||||||
MoveToPosition(Callback.OwnerPos);
|
MoveToPosition(OwnerPos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -205,27 +200,19 @@ void cOcelot::SpawnOn(cClientHandle & a_ClientHandle)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
class cFindSittingCat :
|
|
||||||
public cEntityCallback
|
|
||||||
{
|
|
||||||
virtual bool Item(cEntity * a_Entity) override
|
|
||||||
{
|
|
||||||
return (
|
|
||||||
(a_Entity->GetEntityType() == cEntity::etMonster) &&
|
|
||||||
(static_cast<cMonster *>(a_Entity)->GetMobType() == eMonsterType::mtOcelot) &&
|
|
||||||
(static_cast<cOcelot *>(a_Entity)->IsSitting())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cOcelot::IsCatSittingOnBlock(cWorld * a_World, Vector3d a_BlockPosition)
|
bool cOcelot::IsCatSittingOnBlock(cWorld * a_World, Vector3d a_BlockPosition)
|
||||||
{
|
{
|
||||||
cFindSittingCat FindSittingCat;
|
return a_World->ForEachEntityInBox(
|
||||||
return a_World->ForEachEntityInBox(cBoundingBox(Vector3d(a_BlockPosition.x, a_BlockPosition.y + 1, a_BlockPosition.z), 1), FindSittingCat);
|
cBoundingBox(Vector3d(a_BlockPosition.x, a_BlockPosition.y + 1, a_BlockPosition.z), 1),
|
||||||
|
[=](cEntity & a_Entity)
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
(a_Entity.GetEntityType() == cEntity::etMonster) &&
|
||||||
|
(static_cast<cMonster &>(a_Entity).GetMobType() == eMonsterType::mtOcelot) &&
|
||||||
|
(static_cast<cOcelot &>(a_Entity).IsSitting())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -109,23 +109,18 @@ void cPassiveMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
|
|||||||
Vector3f Pos = (GetPosition() + m_LovePartner->GetPosition()) * 0.5;
|
Vector3f Pos = (GetPosition() + m_LovePartner->GetPosition()) * 0.5;
|
||||||
UInt32 BabyID = m_World->SpawnMob(Pos.x, Pos.y, Pos.z, GetMobType(), true);
|
UInt32 BabyID = m_World->SpawnMob(Pos.x, Pos.y, Pos.z, GetMobType(), true);
|
||||||
|
|
||||||
class cBabyInheritCallback :
|
cPassiveMonster * Baby = nullptr;
|
||||||
public cEntityCallback
|
|
||||||
{
|
m_World->DoWithEntityByID(BabyID, [&](cEntity & a_Entity)
|
||||||
public:
|
|
||||||
cPassiveMonster * Baby;
|
|
||||||
cBabyInheritCallback() : Baby(nullptr) { }
|
|
||||||
virtual bool Item(cEntity * a_Entity) override
|
|
||||||
{
|
{
|
||||||
Baby = static_cast<cPassiveMonster *>(a_Entity);
|
Baby = static_cast<cPassiveMonster *>(&a_Entity);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} Callback;
|
);
|
||||||
|
|
||||||
m_World->DoWithEntityByID(BabyID, Callback);
|
if (Baby != nullptr)
|
||||||
if (Callback.Baby != nullptr)
|
|
||||||
{
|
{
|
||||||
Callback.Baby->InheritFromParents(this, m_LovePartner);
|
Baby->InheritFromParents(this, m_LovePartner);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_World->SpawnExperienceOrb(Pos.x, Pos.y, Pos.z, GetRandomProvider().RandInt(1, 6));
|
m_World->SpawnExperienceOrb(Pos.x, Pos.y, Pos.z, GetRandomProvider().RandInt(1, 6));
|
||||||
@ -159,49 +154,37 @@ void cPassiveMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
|
|||||||
{
|
{
|
||||||
if (m_LovePartner == nullptr)
|
if (m_LovePartner == nullptr)
|
||||||
{
|
{
|
||||||
class LookForLover : public cEntityCallback
|
m_World->ForEachEntityInBox(cBoundingBox(GetPosition(), 8, 8), [=](cEntity & a_Entity)
|
||||||
{
|
|
||||||
public:
|
|
||||||
cEntity * m_Me;
|
|
||||||
|
|
||||||
LookForLover(cEntity * a_Me) :
|
|
||||||
m_Me(a_Me)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool Item(cEntity * a_Entity) override
|
|
||||||
{
|
{
|
||||||
// If the entity is not a monster, don't breed with it
|
// If the entity is not a monster, don't breed with it
|
||||||
// Also, do not self-breed
|
// Also, do not self-breed
|
||||||
if ((a_Entity->GetEntityType() != etMonster) || (a_Entity == m_Me))
|
if ((a_Entity.GetEntityType() != etMonster) || (&a_Entity == this))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
cPassiveMonster * Me = static_cast<cPassiveMonster*>(m_Me);
|
auto & Me = static_cast<cPassiveMonster&>(*this);
|
||||||
cPassiveMonster * PotentialPartner = static_cast<cPassiveMonster*>(a_Entity);
|
auto & PotentialPartner = static_cast<cPassiveMonster&>(a_Entity);
|
||||||
|
|
||||||
// If the potential partner is not of the same species, don't breed with it
|
// If the potential partner is not of the same species, don't breed with it
|
||||||
if (PotentialPartner->GetMobType() != Me->GetMobType())
|
if (PotentialPartner.GetMobType() != Me.GetMobType())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the potential partner is not in love
|
// If the potential partner is not in love
|
||||||
// Or they already have a mate, do not breed with them
|
// Or they already have a mate, do not breed with them
|
||||||
if ((!PotentialPartner->IsInLove()) || (PotentialPartner->GetPartner() != nullptr))
|
if ((!PotentialPartner.IsInLove()) || (PotentialPartner.GetPartner() != nullptr))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// All conditions met, let's breed!
|
// All conditions met, let's breed!
|
||||||
PotentialPartner->EngageLoveMode(Me);
|
PotentialPartner.EngageLoveMode(&Me);
|
||||||
Me->EngageLoveMode(PotentialPartner);
|
Me.EngageLoveMode(&PotentialPartner);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} Callback(this);
|
);
|
||||||
|
|
||||||
m_World->ForEachEntityInBox(cBoundingBox(GetPosition(), 8, 8, -4), Callback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_LoveTimer--;
|
m_LoveTimer--;
|
||||||
|
@ -101,28 +101,19 @@ void cWither::KilledBy(TakeDamageInfo & a_TDI)
|
|||||||
{
|
{
|
||||||
super::KilledBy(a_TDI);
|
super::KilledBy(a_TDI);
|
||||||
|
|
||||||
class cPlayerCallback : public cPlayerListCallback
|
Vector3d Pos = GetPosition();
|
||||||
{
|
m_World->ForEachPlayer([=](cPlayer & a_Player)
|
||||||
Vector3f m_Pos;
|
|
||||||
|
|
||||||
virtual bool Item(cPlayer * a_Player)
|
|
||||||
{
|
{
|
||||||
// TODO 2014-05-21 xdot: Vanilla minecraft uses an AABB check instead of a radius one
|
// TODO 2014-05-21 xdot: Vanilla minecraft uses an AABB check instead of a radius one
|
||||||
double Dist = (a_Player->GetPosition() - m_Pos).Length();
|
double Dist = (a_Player.GetPosition() - Pos).Length();
|
||||||
if (Dist < 50.0)
|
if (Dist < 50.0)
|
||||||
{
|
{
|
||||||
// If player is close, award achievement
|
// If player is close, award achievement
|
||||||
a_Player->AwardAchievement(achKillWither);
|
a_Player.AwardAchievement(achKillWither);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
);
|
||||||
public:
|
|
||||||
cPlayerCallback(const Vector3f & a_Pos) : m_Pos(a_Pos) {}
|
|
||||||
|
|
||||||
} PlayerCallback(GetPosition());
|
|
||||||
|
|
||||||
m_World->ForEachPlayer(PlayerCallback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -80,19 +80,13 @@ void cWolf::NotifyAlliesOfFight(cPawn * a_Opponent)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_NotificationCooldown = 15;
|
m_NotificationCooldown = 15;
|
||||||
class cCallback : public cPlayerListCallback
|
|
||||||
{
|
m_World->DoWithPlayerByUUID(m_OwnerUUID, [=](cPlayer & a_Player)
|
||||||
virtual bool Item(cPlayer * a_Player) override
|
|
||||||
{
|
{
|
||||||
a_Player->NotifyNearbyWolves(m_Opponent, false);
|
a_Player.NotifyNearbyWolves(a_Opponent, false);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
public:
|
);
|
||||||
cPawn * m_Opponent;
|
|
||||||
} Callback;
|
|
||||||
|
|
||||||
Callback.m_Opponent = a_Opponent;
|
|
||||||
m_World->DoWithPlayerByUUID(m_OwnerUUID, Callback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cWolf::Attack(std::chrono::milliseconds a_Dt)
|
bool cWolf::Attack(std::chrono::milliseconds a_Dt)
|
||||||
@ -347,30 +341,25 @@ void cWolf::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
|
|||||||
|
|
||||||
void cWolf::TickFollowPlayer()
|
void cWolf::TickFollowPlayer()
|
||||||
{
|
{
|
||||||
class cCallback :
|
Vector3d OwnerPos;
|
||||||
public cPlayerListCallback
|
bool OwnerFlying;
|
||||||
|
auto Callback = [&](cPlayer & a_Player)
|
||||||
{
|
{
|
||||||
virtual bool Item(cPlayer * a_Player) override
|
OwnerPos = a_Player.GetPosition();
|
||||||
{
|
OwnerFlying = a_Player.IsFlying();
|
||||||
OwnerPos = a_Player->GetPosition();
|
return true;
|
||||||
OwnerFlying = a_Player->IsFlying();
|
};
|
||||||
return true;
|
|
||||||
}
|
|
||||||
public:
|
|
||||||
Vector3d OwnerPos;
|
|
||||||
bool OwnerFlying;
|
|
||||||
} Callback;
|
|
||||||
|
|
||||||
if (m_World->DoWithPlayerByUUID(m_OwnerUUID, Callback))
|
if (m_World->DoWithPlayerByUUID(m_OwnerUUID, Callback))
|
||||||
{
|
{
|
||||||
// The player is present in the world, follow him:
|
// The player is present in the world, follow him:
|
||||||
double Distance = (Callback.OwnerPos - GetPosition()).Length();
|
double Distance = (OwnerPos - GetPosition()).Length();
|
||||||
if (Distance > 20)
|
if (Distance > 20)
|
||||||
{
|
{
|
||||||
if (!Callback.OwnerFlying)
|
if (!OwnerFlying)
|
||||||
{
|
{
|
||||||
Callback.OwnerPos.y = FindFirstNonAirBlockPosition(Callback.OwnerPos.x, Callback.OwnerPos.z);
|
OwnerPos.y = FindFirstNonAirBlockPosition(OwnerPos.x, OwnerPos.z);
|
||||||
TeleportToCoords(Callback.OwnerPos.x, Callback.OwnerPos.y, Callback.OwnerPos.z);
|
TeleportToCoords(OwnerPos.x, OwnerPos.y, OwnerPos.z);
|
||||||
SetTarget(nullptr);
|
SetTarget(nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -385,9 +374,9 @@ void cWolf::TickFollowPlayer()
|
|||||||
{
|
{
|
||||||
if (GetTarget() == nullptr)
|
if (GetTarget() == nullptr)
|
||||||
{
|
{
|
||||||
if (!Callback.OwnerFlying)
|
if (!OwnerFlying)
|
||||||
{
|
{
|
||||||
MoveToPosition(Callback.OwnerPos);
|
MoveToPosition(OwnerPos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
70
src/Root.cpp
70
src/Root.cpp
@ -1,4 +1,4 @@
|
|||||||
|
|
||||||
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
||||||
|
|
||||||
#include "Root.h"
|
#include "Root.h"
|
||||||
@ -352,22 +352,16 @@ void cRoot::Start(std::unique_ptr<cSettingsRepositoryInterface> a_OverridesRepo)
|
|||||||
void cRoot::StopServer()
|
void cRoot::StopServer()
|
||||||
{
|
{
|
||||||
// Kick all players from the server with custom disconnect message
|
// Kick all players from the server with custom disconnect message
|
||||||
class cPlayerCallback : public cPlayerListCallback
|
|
||||||
{
|
bool SentDisconnect = false;
|
||||||
AString m_ShutdownMessage;
|
cRoot::Get()->ForEachPlayer([&](cPlayer & a_Player)
|
||||||
virtual bool Item(cPlayer * a_Player)
|
|
||||||
{
|
{
|
||||||
a_Player->GetClientHandlePtr()->Kick(m_ShutdownMessage);
|
a_Player.GetClientHandlePtr()->Kick(m_Server->GetShutdownMessage());
|
||||||
m_HasSentDisconnect = true;
|
SentDisconnect = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
public:
|
);
|
||||||
bool m_HasSentDisconnect;
|
if (SentDisconnect)
|
||||||
cPlayerCallback(AString a_ShutdownMessage) : m_ShutdownMessage(a_ShutdownMessage) { m_HasSentDisconnect = false; }
|
|
||||||
} PlayerCallback(m_Server->GetShutdownMessage());
|
|
||||||
|
|
||||||
cRoot::Get()->ForEachPlayer(PlayerCallback);
|
|
||||||
if (PlayerCallback.m_HasSentDisconnect)
|
|
||||||
{
|
{
|
||||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
}
|
}
|
||||||
@ -590,14 +584,13 @@ cWorld * cRoot::GetWorld(const AString & a_WorldName)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cRoot::ForEachWorld(cWorldListCallback & a_Callback)
|
bool cRoot::ForEachWorld(cWorldListCallback a_Callback)
|
||||||
{
|
{
|
||||||
for (WorldMap::iterator itr = m_WorldsByName.begin(), itr2 = itr; itr != m_WorldsByName.end(); itr = itr2)
|
for (auto & World : m_WorldsByName)
|
||||||
{
|
{
|
||||||
++itr2;
|
if (World.second != nullptr)
|
||||||
if (itr->second != nullptr)
|
|
||||||
{
|
{
|
||||||
if (a_Callback.Item(itr->second))
|
if (a_Callback(*World.second))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -770,7 +763,7 @@ void cRoot::BroadcastChat(const cCompositeChat & a_Message)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cRoot::ForEachPlayer(cPlayerListCallback & a_Callback)
|
bool cRoot::ForEachPlayer(cPlayerListCallback a_Callback)
|
||||||
{
|
{
|
||||||
for (WorldMap::iterator itr = m_WorldsByName.begin(), itr2 = itr; itr != m_WorldsByName.end(); itr = itr2)
|
for (WorldMap::iterator itr = m_WorldsByName.begin(), itr2 = itr; itr != m_WorldsByName.end(); itr = itr2)
|
||||||
{
|
{
|
||||||
@ -787,20 +780,22 @@ bool cRoot::ForEachPlayer(cPlayerListCallback & a_Callback)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cRoot::FindAndDoWithPlayer(const AString & a_PlayerName, cPlayerListCallback & a_Callback)
|
bool cRoot::FindAndDoWithPlayer(const AString & a_PlayerName, cPlayerListCallback a_Callback)
|
||||||
{
|
{
|
||||||
class cCallback : public cPlayerListCallback
|
class cCallback
|
||||||
{
|
{
|
||||||
size_t m_BestRating;
|
size_t m_BestRating;
|
||||||
size_t m_NameLength;
|
size_t m_NameLength;
|
||||||
const AString m_PlayerName;
|
const AString m_PlayerName;
|
||||||
|
|
||||||
virtual bool Item (cPlayer * a_pPlayer)
|
public:
|
||||||
|
|
||||||
|
bool operator () (cPlayer & a_Player)
|
||||||
{
|
{
|
||||||
size_t Rating = RateCompareString (m_PlayerName, a_pPlayer->GetName());
|
size_t Rating = RateCompareString (m_PlayerName, a_Player.GetName());
|
||||||
if ((Rating > 0) && (Rating >= m_BestRating))
|
if ((Rating > 0) && (Rating >= m_BestRating))
|
||||||
{
|
{
|
||||||
m_BestMatch = a_pPlayer->GetName();
|
m_BestMatch = a_Player.GetName();
|
||||||
if (Rating > m_BestRating)
|
if (Rating > m_BestRating)
|
||||||
{
|
{
|
||||||
m_NumMatches = 0;
|
m_NumMatches = 0;
|
||||||
@ -815,7 +810,6 @@ bool cRoot::FindAndDoWithPlayer(const AString & a_PlayerName, cPlayerListCallbac
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
|
||||||
cCallback (const AString & a_CBPlayerName) :
|
cCallback (const AString & a_CBPlayerName) :
|
||||||
m_BestRating(0),
|
m_BestRating(0),
|
||||||
m_NameLength(a_CBPlayerName.length()),
|
m_NameLength(a_CBPlayerName.length()),
|
||||||
@ -840,7 +834,7 @@ bool cRoot::FindAndDoWithPlayer(const AString & a_PlayerName, cPlayerListCallbac
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cRoot::DoWithPlayerByUUID(const cUUID & a_PlayerUUID, cPlayerListCallback & a_Callback)
|
bool cRoot::DoWithPlayerByUUID(const cUUID & a_PlayerUUID, cPlayerListCallback a_Callback)
|
||||||
{
|
{
|
||||||
for (WorldMap::iterator itr = m_WorldsByName.begin(); itr != m_WorldsByName.end(); ++itr)
|
for (WorldMap::iterator itr = m_WorldsByName.begin(); itr != m_WorldsByName.end(); ++itr)
|
||||||
{
|
{
|
||||||
@ -856,7 +850,7 @@ bool cRoot::DoWithPlayerByUUID(const cUUID & a_PlayerUUID, cPlayerListCallback &
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cRoot::DoWithPlayer(const AString & a_PlayerName, cPlayerListCallback & a_Callback)
|
bool cRoot::DoWithPlayer(const AString & a_PlayerName, cPlayerListCallback a_Callback)
|
||||||
{
|
{
|
||||||
for (auto World : m_WorldsByName)
|
for (auto World : m_WorldsByName)
|
||||||
{
|
{
|
||||||
@ -1048,25 +1042,11 @@ int cRoot::GetFurnaceFuelBurnTime(const cItem & a_Fuel)
|
|||||||
AStringVector cRoot::GetPlayerTabCompletionMultiWorld(const AString & a_Text)
|
AStringVector cRoot::GetPlayerTabCompletionMultiWorld(const AString & a_Text)
|
||||||
{
|
{
|
||||||
AStringVector Results;
|
AStringVector Results;
|
||||||
class cWorldCallback : public cWorldListCallback
|
ForEachWorld([&](cWorld & a_World)
|
||||||
{
|
|
||||||
public:
|
|
||||||
cWorldCallback(AStringVector & a_Results, const AString & a_Search) :
|
|
||||||
m_Results(a_Results),
|
|
||||||
m_Search(a_Search)
|
|
||||||
{
|
{
|
||||||
}
|
a_World.TabCompleteUserName(a_Text, Results);
|
||||||
|
|
||||||
virtual bool Item(cWorld * a_World) override
|
|
||||||
{
|
|
||||||
a_World->TabCompleteUserName(m_Search, m_Results);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
private:
|
);
|
||||||
AStringVector & m_Results;
|
|
||||||
const AString & m_Search;
|
|
||||||
} WC(Results, a_Text);
|
|
||||||
|
|
||||||
Get()->ForEachWorld(WC);
|
|
||||||
return Results;
|
return Results;
|
||||||
}
|
}
|
||||||
|
15
src/Root.h
15
src/Root.h
@ -5,6 +5,7 @@
|
|||||||
#include "Protocol/MojangAPI.h"
|
#include "Protocol/MojangAPI.h"
|
||||||
#include "HTTP/HTTPServer.h"
|
#include "HTTP/HTTPServer.h"
|
||||||
#include "Defines.h"
|
#include "Defines.h"
|
||||||
|
#include "FunctionRef.h"
|
||||||
#include "RankManager.h"
|
#include "RankManager.h"
|
||||||
|
|
||||||
|
|
||||||
@ -27,8 +28,8 @@ class cSettingsRepositoryInterface;
|
|||||||
class cDeadlockDetect;
|
class cDeadlockDetect;
|
||||||
class cUUID;
|
class cUUID;
|
||||||
|
|
||||||
typedef cItemCallback<cPlayer> cPlayerListCallback;
|
using cPlayerListCallback = cFunctionRef<bool(cPlayer &)>;
|
||||||
typedef cItemCallback<cWorld> cWorldListCallback;
|
using cWorldListCallback = cFunctionRef<bool(cWorld &)>;
|
||||||
|
|
||||||
namespace Json
|
namespace Json
|
||||||
{
|
{
|
||||||
@ -76,7 +77,7 @@ public:
|
|||||||
// tolua_end
|
// tolua_end
|
||||||
|
|
||||||
/** Calls the callback for each world; returns true if the callback didn't abort (return true) */
|
/** Calls the callback for each world; returns true if the callback didn't abort (return true) */
|
||||||
bool ForEachWorld(cWorldListCallback & a_Callback); // >> Exported in ManualBindings <<
|
bool ForEachWorld(cWorldListCallback a_Callback); // >> Exported in ManualBindings <<
|
||||||
|
|
||||||
/** Writes chunkstats, for each world and totals, to the output callback */
|
/** Writes chunkstats, for each world and totals, to the output callback */
|
||||||
void LogChunkStats(cCommandOutputCallback & a_Output);
|
void LogChunkStats(cCommandOutputCallback & a_Output);
|
||||||
@ -139,16 +140,16 @@ public:
|
|||||||
void SetSavingEnabled(bool a_SavingEnabled); // tolua_export
|
void SetSavingEnabled(bool a_SavingEnabled); // tolua_export
|
||||||
|
|
||||||
/** Calls the callback for each player in all worlds */
|
/** Calls the callback for each player in all worlds */
|
||||||
bool ForEachPlayer(cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS <<
|
bool ForEachPlayer(cPlayerListCallback a_Callback); // >> EXPORTED IN MANUALBINDINGS <<
|
||||||
|
|
||||||
/** Finds a player from a partial or complete player name and calls the callback - case-insensitive */
|
/** Finds a player from a partial or complete player name and calls the callback - case-insensitive */
|
||||||
bool FindAndDoWithPlayer(const AString & a_PlayerName, cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS <<
|
bool FindAndDoWithPlayer(const AString & a_PlayerName, cPlayerListCallback a_Callback); // >> EXPORTED IN MANUALBINDINGS <<
|
||||||
|
|
||||||
/** Finds the player over his uuid and calls the callback */
|
/** Finds the player over his uuid and calls the callback */
|
||||||
bool DoWithPlayerByUUID(const cUUID & a_PlayerUUID, cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS <<
|
bool DoWithPlayerByUUID(const cUUID & a_PlayerUUID, cPlayerListCallback a_Callback); // >> EXPORTED IN MANUALBINDINGS <<
|
||||||
|
|
||||||
/** Finds the player using it's complete username and calls the callback */
|
/** Finds the player using it's complete username and calls the callback */
|
||||||
bool DoWithPlayer(const AString & a_PlayerName, cPlayerListCallback & a_Callback);
|
bool DoWithPlayer(const AString & a_PlayerName, cPlayerListCallback a_Callback);
|
||||||
|
|
||||||
/** Send playerlist of all worlds to player */
|
/** Send playerlist of all worlds to player */
|
||||||
void SendPlayerLists(cPlayer * a_DestPlayer);
|
void SendPlayerLists(cPlayer * a_DestPlayer);
|
||||||
|
@ -487,7 +487,7 @@ cObjective * cScoreboard::GetObjectiveIn(eDisplaySlot a_Slot)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cScoreboard::ForEachObjectiveWith(cObjective::eType a_Type, cObjectiveCallback & a_Callback)
|
bool cScoreboard::ForEachObjectiveWith(cObjective::eType a_Type, cObjectiveCallback a_Callback)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSObjectives);
|
cCSLock Lock(m_CSObjectives);
|
||||||
|
|
||||||
@ -496,7 +496,7 @@ bool cScoreboard::ForEachObjectiveWith(cObjective::eType a_Type, cObjectiveCallb
|
|||||||
if (it->second.GetType() == a_Type)
|
if (it->second.GetType() == a_Type)
|
||||||
{
|
{
|
||||||
// Call callback
|
// Call callback
|
||||||
if (a_Callback.Item(&it->second))
|
if (a_Callback(it->second))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -509,14 +509,14 @@ bool cScoreboard::ForEachObjectiveWith(cObjective::eType a_Type, cObjectiveCallb
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cScoreboard::ForEachObjective(cObjectiveCallback & a_Callback)
|
bool cScoreboard::ForEachObjective(cObjectiveCallback a_Callback)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSObjectives);
|
cCSLock Lock(m_CSObjectives);
|
||||||
|
|
||||||
for (cObjectiveMap::iterator it = m_Objectives.begin(); it != m_Objectives.end(); ++it)
|
for (cObjectiveMap::iterator it = m_Objectives.begin(); it != m_Objectives.end(); ++it)
|
||||||
{
|
{
|
||||||
// Call callback
|
// Call callback
|
||||||
if (a_Callback.Item(&it->second))
|
if (a_Callback(it->second))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -528,14 +528,14 @@ bool cScoreboard::ForEachObjective(cObjectiveCallback & a_Callback)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cScoreboard::ForEachTeam(cTeamCallback & a_Callback)
|
bool cScoreboard::ForEachTeam(cTeamCallback a_Callback)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSTeams);
|
cCSLock Lock(m_CSTeams);
|
||||||
|
|
||||||
for (cTeamMap::iterator it = m_Teams.begin(); it != m_Teams.end(); ++it)
|
for (cTeamMap::iterator it = m_Teams.begin(); it != m_Teams.end(); ++it)
|
||||||
{
|
{
|
||||||
// Call callback
|
// Call callback
|
||||||
if (a_Callback.Item(&it->second))
|
if (a_Callback(it->second))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -11,14 +11,15 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "FunctionRef.h"
|
||||||
|
|
||||||
|
|
||||||
class cObjective;
|
class cObjective;
|
||||||
class cTeam;
|
class cTeam;
|
||||||
class cWorld;
|
class cWorld;
|
||||||
|
|
||||||
typedef cItemCallback<cObjective> cObjectiveCallback;
|
using cObjectiveCallback = cFunctionRef<bool(cObjective &)>;
|
||||||
typedef cItemCallback<cTeam> cTeamCallback;
|
using cTeamCallback = cFunctionRef<bool(cTeam &)>;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -266,15 +267,15 @@ public:
|
|||||||
|
|
||||||
/** Execute callback for each objective with the specified type
|
/** Execute callback for each objective with the specified type
|
||||||
Returns true if all objectives processed, false if the callback aborted by returning true. */
|
Returns true if all objectives processed, false if the callback aborted by returning true. */
|
||||||
bool ForEachObjectiveWith(cObjective::eType a_Type, cObjectiveCallback & a_Callback);
|
bool ForEachObjectiveWith(cObjective::eType a_Type, cObjectiveCallback a_Callback);
|
||||||
|
|
||||||
/** Execute callback for each objective.
|
/** Execute callback for each objective.
|
||||||
Returns true if all objectives have been processed, false if the callback aborted by returning true. */
|
Returns true if all objectives have been processed, false if the callback aborted by returning true. */
|
||||||
bool ForEachObjective(cObjectiveCallback & a_Callback); // Exported in ManualBindings.cpp
|
bool ForEachObjective(cObjectiveCallback a_Callback); // Exported in ManualBindings.cpp
|
||||||
|
|
||||||
/** Execute callback for each team.
|
/** Execute callback for each team.
|
||||||
Returns true if all teams have been processed, false if the callback aborted by returning true. */
|
Returns true if all teams have been processed, false if the callback aborted by returning true. */
|
||||||
bool ForEachTeam(cTeamCallback & a_Callback); // Exported in ManualBindings.cpp
|
bool ForEachTeam(cTeamCallback a_Callback); // Exported in ManualBindings.cpp
|
||||||
|
|
||||||
void SetDisplay(cObjective * a_Objective, eDisplaySlot a_Slot);
|
void SetDisplay(cObjective * a_Objective, eDisplaySlot a_Slot);
|
||||||
|
|
||||||
|
@ -498,26 +498,20 @@ void cServer::ExecuteConsoleCommand(const AString & a_Cmd, cCommandOutputCallbac
|
|||||||
}
|
}
|
||||||
if (split[0] == "destroyentities")
|
if (split[0] == "destroyentities")
|
||||||
{
|
{
|
||||||
class WorldCallback : public cWorldListCallback
|
cRoot::Get()->ForEachWorld([](cWorld & a_World)
|
||||||
{
|
|
||||||
virtual bool Item(cWorld * a_World) override
|
|
||||||
{
|
{
|
||||||
class EntityCallback : public cEntityCallback
|
a_World.ForEachEntity([](cEntity & a_Entity)
|
||||||
{
|
|
||||||
virtual bool Item(cEntity * a_Entity) override
|
|
||||||
{
|
{
|
||||||
if (!a_Entity->IsPlayer())
|
if (!a_Entity.IsPlayer())
|
||||||
{
|
{
|
||||||
a_Entity->Destroy();
|
a_Entity.Destroy();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} EC;
|
);
|
||||||
a_World->ForEachEntity(EC);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} WC;
|
);
|
||||||
cRoot::Get()->ForEachWorld(WC);
|
|
||||||
a_Output.Out("Destroyed all entities");
|
a_Output.Out("Destroyed all entities");
|
||||||
a_Output.Finished();
|
a_Output.Finished();
|
||||||
return;
|
return;
|
||||||
|
@ -44,17 +44,12 @@ public:
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
class cSetPowerToCommandBlock : public cCommandBlockCallback
|
a_World.DoWithCommandBlockAt(a_Position.x, a_Position.y, a_Position.z, [](cCommandBlockEntity & a_CommandBlock)
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual bool Item(cCommandBlockEntity * a_CommandBlock) override
|
|
||||||
{
|
{
|
||||||
a_CommandBlock->Activate();
|
a_CommandBlock.Activate();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} CmdBlockSP;
|
);
|
||||||
|
|
||||||
a_World.DoWithCommandBlockAt(a_Position.x, a_Position.y, a_Position.z, CmdBlockSP);
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,18 +56,12 @@ public:
|
|||||||
bool WasPoweredPreviously = IsActivated(a_Meta);
|
bool WasPoweredPreviously = IsActivated(a_Meta);
|
||||||
if (IsPoweredNow && !WasPoweredPreviously)
|
if (IsPoweredNow && !WasPoweredPreviously)
|
||||||
{
|
{
|
||||||
class cSetPowerToDropSpenser :
|
a_World.DoWithDropSpenserAt(a_Position.x, a_Position.y, a_Position.z, [](cDropSpenserEntity & a_DropSpenser)
|
||||||
public cDropSpenserCallback
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual bool Item(cDropSpenserEntity * a_DropSpenser) override
|
|
||||||
{
|
{
|
||||||
a_DropSpenser->Activate();
|
a_DropSpenser.Activate();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} DrSpSP;
|
);
|
||||||
|
|
||||||
a_World.DoWithDropSpenserAt(a_Position.x, a_Position.y, a_Position.z, DrSpSP);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the internal dropspenser state if necessary
|
// Update the internal dropspenser state if necessary
|
||||||
|
@ -45,17 +45,12 @@ public:
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
class cSetPowerToNoteBlock : public cNoteBlockCallback
|
a_World.DoWithNoteBlockAt(a_Position.x, a_Position.y, a_Position.z, [](cNoteEntity & a_NoteBlock)
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual bool Item(cNoteEntity * a_NoteBlock) override
|
|
||||||
{
|
{
|
||||||
a_NoteBlock->MakeSound();
|
a_NoteBlock.MakeSound();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} NoteBlockSP;
|
);
|
||||||
|
|
||||||
a_World.DoWithNoteBlockAt(a_Position.x, a_Position.y, a_Position.z, NoteBlockSP);
|
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -27,49 +27,37 @@ public:
|
|||||||
{
|
{
|
||||||
UNUSED(a_Meta);
|
UNUSED(a_Meta);
|
||||||
|
|
||||||
class cPressurePlateCallback :
|
unsigned int NumberOfEntities;
|
||||||
public cEntityCallback
|
bool FoundPlayer;
|
||||||
{
|
a_World.ForEachEntityInBox(cBoundingBox(Vector3d(0.5, 0, 0.5) + a_Position, 0.5, 0.5), [&](cEntity & a_Entity)
|
||||||
public:
|
|
||||||
cPressurePlateCallback(void) :
|
|
||||||
m_NumberOfEntities(0),
|
|
||||||
m_FoundPlayer(false)
|
|
||||||
{
|
{
|
||||||
}
|
if (a_Entity.IsPlayer())
|
||||||
|
|
||||||
virtual bool Item(cEntity * a_Entity) override
|
|
||||||
{
|
|
||||||
if (a_Entity->IsPlayer())
|
|
||||||
{
|
{
|
||||||
m_FoundPlayer = true;
|
FoundPlayer = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_NumberOfEntities++;
|
NumberOfEntities++;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
);
|
||||||
unsigned int m_NumberOfEntities;
|
|
||||||
bool m_FoundPlayer;
|
|
||||||
} PressurePlateCallback;
|
|
||||||
a_World.ForEachEntityInBox(cBoundingBox(Vector3d(0.5, 0, 0.5) + a_Position, 0.5, 0.5), PressurePlateCallback);
|
|
||||||
|
|
||||||
switch (a_BlockType)
|
switch (a_BlockType)
|
||||||
{
|
{
|
||||||
case E_BLOCK_STONE_PRESSURE_PLATE:
|
case E_BLOCK_STONE_PRESSURE_PLATE:
|
||||||
{
|
{
|
||||||
return (PressurePlateCallback.m_FoundPlayer ? 15 : 0);
|
return (FoundPlayer ? 15 : 0);
|
||||||
}
|
}
|
||||||
case E_BLOCK_WOODEN_PRESSURE_PLATE:
|
case E_BLOCK_WOODEN_PRESSURE_PLATE:
|
||||||
{
|
{
|
||||||
return (PressurePlateCallback.m_NumberOfEntities != 0 ? 15 : 0);
|
return (NumberOfEntities != 0 ? 15 : 0);
|
||||||
}
|
}
|
||||||
case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE:
|
case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE:
|
||||||
{
|
{
|
||||||
return std::min(static_cast<unsigned char>(CeilC(PressurePlateCallback.m_NumberOfEntities / 10.f)), static_cast<unsigned char>(15));
|
return std::min(static_cast<unsigned char>(CeilC(NumberOfEntities / 10.f)), static_cast<unsigned char>(15));
|
||||||
}
|
}
|
||||||
case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE:
|
case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE:
|
||||||
{
|
{
|
||||||
return std::min(static_cast<unsigned char>(PressurePlateCallback.m_NumberOfEntities), static_cast<unsigned char>(15));
|
return std::min(static_cast<unsigned char>(NumberOfEntities), static_cast<unsigned char>(15));
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
|
@ -44,17 +44,12 @@ public:
|
|||||||
UNUSED(a_Position);
|
UNUSED(a_Position);
|
||||||
UNUSED(a_BlockType);
|
UNUSED(a_BlockType);
|
||||||
|
|
||||||
class cContainerCallback : public cBlockEntityCallback
|
UInt8 SignalStrength = 0;
|
||||||
{
|
auto RearCoordinate = cBlockComparatorHandler::GetRearCoordinate(a_Position, a_Meta & 0x3);
|
||||||
public:
|
a_World.DoWithBlockEntityAt(RearCoordinate.x, RearCoordinate.y, RearCoordinate.z, [&](cBlockEntity & a_BlockEntity)
|
||||||
cContainerCallback() : m_SignalStrength(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool Item(cBlockEntity * a_BlockEntity) override
|
|
||||||
{
|
{
|
||||||
// Skip BlockEntities that don't have slots
|
// Skip BlockEntities that don't have slots
|
||||||
auto BlockEntityWithItems = dynamic_cast<cBlockEntityWithItems *>(a_BlockEntity);
|
auto BlockEntityWithItems = dynamic_cast<cBlockEntityWithItems *>(&a_BlockEntity);
|
||||||
if (BlockEntityWithItems == nullptr)
|
if (BlockEntityWithItems == nullptr)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@ -68,23 +63,18 @@ public:
|
|||||||
Fullness += static_cast<float>(Contents.GetSlot(Slot).m_ItemCount) / Contents.GetSlot(Slot).GetMaxStackSize();
|
Fullness += static_cast<float>(Contents.GetSlot(Slot).m_ItemCount) / Contents.GetSlot(Slot).GetMaxStackSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_SignalStrength = (Fullness < 0.001 /* container empty? */) ? 0 : static_cast<unsigned char>(1 + (Fullness / Contents.GetNumSlots()) * 14);
|
SignalStrength = (Fullness < 0.001 /* container empty? */) ? 0 : static_cast<UInt8>(1 + (Fullness / Contents.GetNumSlots()) * 14);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
);
|
||||||
unsigned char m_SignalStrength;
|
auto RearPower = SignalStrength;
|
||||||
} CCB;
|
|
||||||
|
|
||||||
auto RearCoordinate = cBlockComparatorHandler::GetRearCoordinate(a_Position, a_Meta & 0x3);
|
|
||||||
a_World.DoWithBlockEntityAt(RearCoordinate.x, RearCoordinate.y, RearCoordinate.z, CCB);
|
|
||||||
auto RearPower = CCB.m_SignalStrength;
|
|
||||||
auto RearType = a_World.GetBlock(RearCoordinate);
|
auto RearType = a_World.GetBlock(RearCoordinate);
|
||||||
|
|
||||||
auto PotentialSourceHandler = cIncrementalRedstoneSimulator::GetComponentHandler(RearType);
|
auto PotentialSourceHandler = cIncrementalRedstoneSimulator::GetComponentHandler(RearType);
|
||||||
if (PotentialSourceHandler != nullptr)
|
if (PotentialSourceHandler != nullptr)
|
||||||
{
|
{
|
||||||
NIBBLETYPE RearMeta = a_World.GetBlockMeta(RearCoordinate);
|
NIBBLETYPE RearMeta = a_World.GetBlockMeta(RearCoordinate);
|
||||||
RearPower = std::max(CCB.m_SignalStrength, PotentialSourceHandler->GetPowerDeliveredToPosition(a_World, RearCoordinate, RearType, RearMeta, a_Position, a_BlockType));
|
RearPower = std::max(SignalStrength, PotentialSourceHandler->GetPowerDeliveredToPosition(a_World, RearCoordinate, RearType, RearMeta, a_Position, a_BlockType));
|
||||||
}
|
}
|
||||||
|
|
||||||
return RearPower;
|
return RearPower;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "RedstoneHandler.h"
|
#include "RedstoneHandler.h"
|
||||||
@ -28,38 +28,15 @@ public:
|
|||||||
UNUSED(a_BlockType);
|
UNUSED(a_BlockType);
|
||||||
UNUSED(a_Meta);
|
UNUSED(a_Meta);
|
||||||
|
|
||||||
class cGetTrappedChestPlayers :
|
int NumberOfPlayers = 0;
|
||||||
public cItemCallback<cChestEntity>
|
VERIFY(!a_World.DoWithChestAt(a_Position.x, a_Position.y, a_Position.z, [&](cChestEntity & a_Chest)
|
||||||
{
|
|
||||||
public:
|
|
||||||
cGetTrappedChestPlayers(void) :
|
|
||||||
m_NumberOfPlayers(0)
|
|
||||||
{
|
{
|
||||||
}
|
ASSERT(a_Chest.GetBlockType() == E_BLOCK_TRAPPED_CHEST);
|
||||||
|
NumberOfPlayers = a_Chest.GetNumberOfPlayers();
|
||||||
virtual ~cGetTrappedChestPlayers() override
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool Item(cChestEntity * a_Chest) override
|
|
||||||
{
|
|
||||||
ASSERT(a_Chest->GetBlockType() == E_BLOCK_TRAPPED_CHEST);
|
|
||||||
m_NumberOfPlayers = a_Chest->GetNumberOfPlayers();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
));
|
||||||
unsigned char GetPowerLevel(void) const
|
return static_cast<unsigned char>(std::min(NumberOfPlayers, 15));
|
||||||
{
|
|
||||||
return static_cast<unsigned char>(std::min(m_NumberOfPlayers, 15));
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
int m_NumberOfPlayers;
|
|
||||||
|
|
||||||
} GTCP;
|
|
||||||
|
|
||||||
VERIFY(!a_World.DoWithChestAt(a_Position.x, a_Position.y, a_Position.z, GTCP));
|
|
||||||
return GTCP.GetPowerLevel();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual cVector3iArray Update(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
|
virtual cVector3iArray Update(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override
|
||||||
|
@ -39,26 +39,7 @@ public:
|
|||||||
|
|
||||||
if (Type == E_BLOCK_TRIPWIRE)
|
if (Type == E_BLOCK_TRIPWIRE)
|
||||||
{
|
{
|
||||||
class cTripwireCallback :
|
if (!a_World.ForEachEntityInBox(cBoundingBox(Vector3d(0.5, 0, 0.5) + Position, 0.5, 0.5), [](cEntity &) { return true; }))
|
||||||
public cEntityCallback
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
cTripwireCallback(void) :
|
|
||||||
m_NumberOfEntities(0),
|
|
||||||
m_FoundPlayer(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool Item(cEntity * a_Entity) override
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int m_NumberOfEntities;
|
|
||||||
bool m_FoundPlayer;
|
|
||||||
} TripwireCallback;
|
|
||||||
|
|
||||||
if (!a_World.ForEachEntityInBox(cBoundingBox(Vector3d(0.5, 0, 0.5) + Position, 0.5, 0.5), TripwireCallback))
|
|
||||||
{
|
{
|
||||||
FoundActivated = true;
|
FoundActivated = true;
|
||||||
}
|
}
|
||||||
|
@ -362,12 +362,12 @@ void cWindow::OwnerDestroyed()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWindow::ForEachPlayer(cItemCallback<cPlayer> & a_Callback)
|
bool cWindow::ForEachPlayer(cPlayerListCallback a_Callback)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CS);
|
cCSLock Lock(m_CS);
|
||||||
for (cPlayerList::iterator itr = m_OpenedBy.begin(), end = m_OpenedBy.end(); itr != end; ++itr)
|
for (auto & Player : m_OpenedBy)
|
||||||
{
|
{
|
||||||
if (a_Callback.Item(*itr))
|
if (a_Callback(*Player))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -379,12 +379,12 @@ bool cWindow::ForEachPlayer(cItemCallback<cPlayer> & a_Callback)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWindow::ForEachClient(cItemCallback<cClientHandle> & a_Callback)
|
bool cWindow::ForEachClient(cClientHandleCallback a_Callback)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CS);
|
cCSLock Lock(m_CS);
|
||||||
for (cPlayerList::iterator itr = m_OpenedBy.begin(), end = m_OpenedBy.end(); itr != end; ++itr)
|
for (auto & Player : m_OpenedBy)
|
||||||
{
|
{
|
||||||
if (a_Callback.Item((*itr)->GetClientHandle()))
|
if (a_Callback(*Player->GetClientHandle()))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "../FunctionRef.h"
|
||||||
#include "../ItemGrid.h"
|
#include "../ItemGrid.h"
|
||||||
|
|
||||||
|
|
||||||
@ -31,7 +32,8 @@ class cWorld;
|
|||||||
|
|
||||||
typedef std::list<cPlayer *> cPlayerList;
|
typedef std::list<cPlayer *> cPlayerList;
|
||||||
typedef std::vector<cSlotArea *> cSlotAreas;
|
typedef std::vector<cSlotArea *> cSlotAreas;
|
||||||
|
using cPlayerListCallback = cFunctionRef<bool(cPlayer &)>;
|
||||||
|
using cClientHandleCallback = cFunctionRef<bool(cClientHandle &)>;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -151,10 +153,10 @@ public:
|
|||||||
void OwnerDestroyed(void);
|
void OwnerDestroyed(void);
|
||||||
|
|
||||||
/** Calls the callback safely for each player that has this window open; returns true if all players have been enumerated */
|
/** Calls the callback safely for each player that has this window open; returns true if all players have been enumerated */
|
||||||
bool ForEachPlayer(cItemCallback<cPlayer> & a_Callback);
|
bool ForEachPlayer(cPlayerListCallback a_Callback);
|
||||||
|
|
||||||
/** Calls the callback safely for each client that has this window open; returns true if all clients have been enumerated */
|
/** Calls the callback safely for each client that has this window open; returns true if all clients have been enumerated */
|
||||||
bool ForEachClient(cItemCallback<cClientHandle> & a_Callback);
|
bool ForEachClient(cClientHandleCallback a_Callback);
|
||||||
|
|
||||||
/** Called on shift-clicking to distribute the stack into other areas; Modifies a_ItemStack as it is distributed!
|
/** Called on shift-clicking to distribute the stack into other areas; Modifies a_ItemStack as it is distributed!
|
||||||
if a_ShouldApply is true, the changes are written into the slots;
|
if a_ShouldApply is true, the changes are written into the slots;
|
||||||
|
@ -21,30 +21,6 @@ static const char DEFAULT_WEBADMIN_PORTS[] = "8080";
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// cPlayerAccum:
|
|
||||||
|
|
||||||
/** Helper class - appends all player names together in an HTML list */
|
|
||||||
class cPlayerAccum :
|
|
||||||
public cPlayerListCallback
|
|
||||||
{
|
|
||||||
virtual bool Item(cPlayer * a_Player) override
|
|
||||||
{
|
|
||||||
m_Contents.append("<li>");
|
|
||||||
m_Contents.append(a_Player->GetName());
|
|
||||||
m_Contents.append("</li>");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
AString m_Contents;
|
|
||||||
} ;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// cWebadminRequestData
|
// cWebadminRequestData
|
||||||
|
|
||||||
|
192
src/World.cpp
192
src/World.cpp
@ -1,4 +1,4 @@
|
|||||||
|
|
||||||
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
||||||
|
|
||||||
#include "World.h"
|
#include "World.h"
|
||||||
@ -1122,59 +1122,52 @@ void cWorld::TickMobs(std::chrono::milliseconds a_Dt)
|
|||||||
{
|
{
|
||||||
m_ChunkMap->SpawnMobs(Spawner);
|
m_ChunkMap->SpawnMobs(Spawner);
|
||||||
// do the spawn
|
// do the spawn
|
||||||
for (cMobSpawner::tSpawnedContainer::const_iterator itr2 = Spawner.getSpawned().begin(); itr2 != Spawner.getSpawned().end(); ++itr2)
|
for (auto & Mob : Spawner.getSpawned())
|
||||||
{
|
{
|
||||||
SpawnMobFinalize(std::move(const_cast<std::unique_ptr<cMonster> &>(*itr2)));
|
SpawnMobFinalize(std::move(Mob));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // for i - AllFamilies[]
|
} // for i - AllFamilies[]
|
||||||
} // if (Spawning enabled)
|
} // if (Spawning enabled)
|
||||||
|
|
||||||
class cCallback : public cEntityCallback
|
ForEachEntity([=](cEntity & a_Entity)
|
||||||
{
|
|
||||||
virtual bool Item(cEntity * a_Entity) override
|
|
||||||
{
|
{
|
||||||
if (!a_Entity->IsMob())
|
if (!a_Entity.IsMob())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!a_Entity->IsTicking())
|
if (!a_Entity.IsTicking())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Monster = static_cast<cMonster *>(a_Entity);
|
auto & Monster = static_cast<cMonster &>(a_Entity);
|
||||||
ASSERT(Monster->GetParentChunk() != nullptr); // A ticking entity must have a valid parent chunk
|
ASSERT(Monster.GetParentChunk() != nullptr); // A ticking entity must have a valid parent chunk
|
||||||
|
|
||||||
// Tick close mobs
|
// Tick close mobs
|
||||||
if (Monster->GetParentChunk()->HasAnyClients())
|
if (Monster.GetParentChunk()->HasAnyClients())
|
||||||
{
|
{
|
||||||
Monster->Tick(m_Dt, *(a_Entity->GetParentChunk()));
|
Monster.Tick(a_Dt, *(a_Entity.GetParentChunk()));
|
||||||
}
|
}
|
||||||
// Destroy far hostile mobs except if last target was a player
|
// Destroy far hostile mobs except if last target was a player
|
||||||
else if ((Monster->GetMobFamily() == cMonster::eFamily::mfHostile) && !Monster->WasLastTargetAPlayer())
|
else if ((Monster.GetMobFamily() == cMonster::eFamily::mfHostile) && !Monster.WasLastTargetAPlayer())
|
||||||
{
|
{
|
||||||
if (Monster->GetMobType() != eMonsterType::mtWolf)
|
if (Monster.GetMobType() != eMonsterType::mtWolf)
|
||||||
{
|
{
|
||||||
Monster->Destroy(true);
|
Monster.Destroy(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto Wolf = static_cast<cWolf *>(Monster);
|
auto & Wolf = static_cast<cWolf &>(Monster);
|
||||||
if (Wolf->IsAngry())
|
if (Wolf.IsAngry())
|
||||||
{
|
{
|
||||||
Monster->Destroy(true);
|
Monster.Destroy(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
public:
|
);
|
||||||
std::chrono::milliseconds m_Dt;
|
|
||||||
} Callback;
|
|
||||||
|
|
||||||
Callback.m_Dt = a_Dt;
|
|
||||||
ForEachEntity(Callback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1326,7 +1319,7 @@ void cWorld::WakeUpSimulatorsInArea(const cCuboid & a_Area)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWorld::ForEachBlockEntityInChunk(int a_ChunkX, int a_ChunkZ, cBlockEntityCallback & a_Callback)
|
bool cWorld::ForEachBlockEntityInChunk(int a_ChunkX, int a_ChunkZ, cBlockEntityCallback a_Callback)
|
||||||
{
|
{
|
||||||
return m_ChunkMap->ForEachBlockEntityInChunk(a_ChunkX, a_ChunkZ, a_Callback);
|
return m_ChunkMap->ForEachBlockEntityInChunk(a_ChunkX, a_ChunkZ, a_Callback);
|
||||||
}
|
}
|
||||||
@ -1335,7 +1328,7 @@ bool cWorld::ForEachBlockEntityInChunk(int a_ChunkX, int a_ChunkZ, cBlockEntityC
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWorld::ForEachBrewingstandInChunk(int a_ChunkX, int a_ChunkZ, cBrewingstandCallback & a_Callback)
|
bool cWorld::ForEachBrewingstandInChunk(int a_ChunkX, int a_ChunkZ, cBrewingstandCallback a_Callback)
|
||||||
{
|
{
|
||||||
return m_ChunkMap->ForEachBrewingstandInChunk(a_ChunkX, a_ChunkZ, a_Callback);
|
return m_ChunkMap->ForEachBrewingstandInChunk(a_ChunkX, a_ChunkZ, a_Callback);
|
||||||
}
|
}
|
||||||
@ -1344,7 +1337,7 @@ bool cWorld::ForEachBrewingstandInChunk(int a_ChunkX, int a_ChunkZ, cBrewingstan
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWorld::ForEachChestInChunk(int a_ChunkX, int a_ChunkZ, cChestCallback & a_Callback)
|
bool cWorld::ForEachChestInChunk(int a_ChunkX, int a_ChunkZ, cChestCallback a_Callback)
|
||||||
{
|
{
|
||||||
return m_ChunkMap->ForEachChestInChunk(a_ChunkX, a_ChunkZ, a_Callback);
|
return m_ChunkMap->ForEachChestInChunk(a_ChunkX, a_ChunkZ, a_Callback);
|
||||||
}
|
}
|
||||||
@ -1353,7 +1346,7 @@ bool cWorld::ForEachChestInChunk(int a_ChunkX, int a_ChunkZ, cChestCallback & a_
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWorld::ForEachDispenserInChunk(int a_ChunkX, int a_ChunkZ, cDispenserCallback & a_Callback)
|
bool cWorld::ForEachDispenserInChunk(int a_ChunkX, int a_ChunkZ, cDispenserCallback a_Callback)
|
||||||
{
|
{
|
||||||
return m_ChunkMap->ForEachDispenserInChunk(a_ChunkX, a_ChunkZ, a_Callback);
|
return m_ChunkMap->ForEachDispenserInChunk(a_ChunkX, a_ChunkZ, a_Callback);
|
||||||
}
|
}
|
||||||
@ -1362,7 +1355,7 @@ bool cWorld::ForEachDispenserInChunk(int a_ChunkX, int a_ChunkZ, cDispenserCallb
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWorld::ForEachDropperInChunk(int a_ChunkX, int a_ChunkZ, cDropperCallback & a_Callback)
|
bool cWorld::ForEachDropperInChunk(int a_ChunkX, int a_ChunkZ, cDropperCallback a_Callback)
|
||||||
{
|
{
|
||||||
return m_ChunkMap->ForEachDropperInChunk(a_ChunkX, a_ChunkZ, a_Callback);
|
return m_ChunkMap->ForEachDropperInChunk(a_ChunkX, a_ChunkZ, a_Callback);
|
||||||
}
|
}
|
||||||
@ -1371,7 +1364,7 @@ bool cWorld::ForEachDropperInChunk(int a_ChunkX, int a_ChunkZ, cDropperCallback
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWorld::ForEachDropSpenserInChunk(int a_ChunkX, int a_ChunkZ, cDropSpenserCallback & a_Callback)
|
bool cWorld::ForEachDropSpenserInChunk(int a_ChunkX, int a_ChunkZ, cDropSpenserCallback a_Callback)
|
||||||
{
|
{
|
||||||
return m_ChunkMap->ForEachDropSpenserInChunk(a_ChunkX, a_ChunkZ, a_Callback);
|
return m_ChunkMap->ForEachDropSpenserInChunk(a_ChunkX, a_ChunkZ, a_Callback);
|
||||||
}
|
}
|
||||||
@ -1380,7 +1373,7 @@ bool cWorld::ForEachDropSpenserInChunk(int a_ChunkX, int a_ChunkZ, cDropSpenserC
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWorld::ForEachFurnaceInChunk(int a_ChunkX, int a_ChunkZ, cFurnaceCallback & a_Callback)
|
bool cWorld::ForEachFurnaceInChunk(int a_ChunkX, int a_ChunkZ, cFurnaceCallback a_Callback)
|
||||||
{
|
{
|
||||||
return m_ChunkMap->ForEachFurnaceInChunk(a_ChunkX, a_ChunkZ, a_Callback);
|
return m_ChunkMap->ForEachFurnaceInChunk(a_ChunkX, a_ChunkZ, a_Callback);
|
||||||
}
|
}
|
||||||
@ -1435,7 +1428,7 @@ void cWorld::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_Blo
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWorld::DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback & a_Callback)
|
bool cWorld::DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback a_Callback)
|
||||||
{
|
{
|
||||||
return m_ChunkMap->DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback);
|
return m_ChunkMap->DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback);
|
||||||
}
|
}
|
||||||
@ -1444,7 +1437,7 @@ bool cWorld::DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBloc
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWorld::DoWithBeaconAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconCallback & a_Callback)
|
bool cWorld::DoWithBeaconAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconCallback a_Callback)
|
||||||
{
|
{
|
||||||
return m_ChunkMap->DoWithBeaconAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback);
|
return m_ChunkMap->DoWithBeaconAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback);
|
||||||
}
|
}
|
||||||
@ -1453,7 +1446,7 @@ bool cWorld::DoWithBeaconAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconCal
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWorld::DoWithBedAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBedCallback & a_Callback)
|
bool cWorld::DoWithBedAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBedCallback a_Callback)
|
||||||
{
|
{
|
||||||
return m_ChunkMap->DoWithBedAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback);
|
return m_ChunkMap->DoWithBedAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback);
|
||||||
}
|
}
|
||||||
@ -1462,7 +1455,7 @@ bool cWorld::DoWithBedAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBedCallback
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWorld::DoWithBrewingstandAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBrewingstandCallback & a_Callback)
|
bool cWorld::DoWithBrewingstandAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBrewingstandCallback a_Callback)
|
||||||
{
|
{
|
||||||
return m_ChunkMap->DoWithBrewingstandAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback);
|
return m_ChunkMap->DoWithBrewingstandAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback);
|
||||||
}
|
}
|
||||||
@ -1471,7 +1464,7 @@ bool cWorld::DoWithBrewingstandAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBre
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWorld::DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallback & a_Callback)
|
bool cWorld::DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallback a_Callback)
|
||||||
{
|
{
|
||||||
return m_ChunkMap->DoWithChestAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback);
|
return m_ChunkMap->DoWithChestAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback);
|
||||||
}
|
}
|
||||||
@ -1480,7 +1473,7 @@ bool cWorld::DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallb
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWorld::DoWithDispenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDispenserCallback & a_Callback)
|
bool cWorld::DoWithDispenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDispenserCallback a_Callback)
|
||||||
{
|
{
|
||||||
return m_ChunkMap->DoWithDispenserAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback);
|
return m_ChunkMap->DoWithDispenserAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback);
|
||||||
}
|
}
|
||||||
@ -1489,7 +1482,7 @@ bool cWorld::DoWithDispenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDispen
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWorld::DoWithDropperAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDropperCallback & a_Callback)
|
bool cWorld::DoWithDropperAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDropperCallback a_Callback)
|
||||||
{
|
{
|
||||||
return m_ChunkMap->DoWithDropperAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback);
|
return m_ChunkMap->DoWithDropperAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback);
|
||||||
}
|
}
|
||||||
@ -1498,7 +1491,7 @@ bool cWorld::DoWithDropperAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDropperC
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWorld::DoWithDropSpenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDropSpenserCallback & a_Callback)
|
bool cWorld::DoWithDropSpenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDropSpenserCallback a_Callback)
|
||||||
{
|
{
|
||||||
return m_ChunkMap->DoWithDropSpenserAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback);
|
return m_ChunkMap->DoWithDropSpenserAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback);
|
||||||
}
|
}
|
||||||
@ -1507,7 +1500,7 @@ bool cWorld::DoWithDropSpenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDrop
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWorld::DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceCallback & a_Callback)
|
bool cWorld::DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceCallback a_Callback)
|
||||||
{
|
{
|
||||||
return m_ChunkMap->DoWithFurnaceAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback);
|
return m_ChunkMap->DoWithFurnaceAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback);
|
||||||
}
|
}
|
||||||
@ -1516,7 +1509,7 @@ bool cWorld::DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceC
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWorld::DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNoteBlockCallback & a_Callback)
|
bool cWorld::DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNoteBlockCallback a_Callback)
|
||||||
{
|
{
|
||||||
return m_ChunkMap->DoWithNoteBlockAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback);
|
return m_ChunkMap->DoWithNoteBlockAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback);
|
||||||
}
|
}
|
||||||
@ -1525,7 +1518,7 @@ bool cWorld::DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNoteBl
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWorld::DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cCommandBlockCallback & a_Callback)
|
bool cWorld::DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cCommandBlockCallback a_Callback)
|
||||||
{
|
{
|
||||||
return m_ChunkMap->DoWithCommandBlockAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback);
|
return m_ChunkMap->DoWithCommandBlockAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback);
|
||||||
}
|
}
|
||||||
@ -1534,7 +1527,7 @@ bool cWorld::DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cCom
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWorld::DoWithMobHeadAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadCallback & a_Callback)
|
bool cWorld::DoWithMobHeadAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadCallback a_Callback)
|
||||||
{
|
{
|
||||||
return m_ChunkMap->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback);
|
return m_ChunkMap->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback);
|
||||||
}
|
}
|
||||||
@ -1543,7 +1536,7 @@ bool cWorld::DoWithMobHeadAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadC
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWorld::DoWithFlowerPotAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFlowerPotCallback & a_Callback)
|
bool cWorld::DoWithFlowerPotAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFlowerPotCallback a_Callback)
|
||||||
{
|
{
|
||||||
return m_ChunkMap->DoWithFlowerPotAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback);
|
return m_ChunkMap->DoWithFlowerPotAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback);
|
||||||
}
|
}
|
||||||
@ -1561,7 +1554,7 @@ bool cWorld::GetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWorld::DoWithChunk(int a_ChunkX, int a_ChunkZ, cChunkCallback & a_Callback)
|
bool cWorld::DoWithChunk(int a_ChunkX, int a_ChunkZ, cChunkCallback a_Callback)
|
||||||
{
|
{
|
||||||
return m_ChunkMap->DoWithChunk(a_ChunkX, a_ChunkZ, a_Callback);
|
return m_ChunkMap->DoWithChunk(a_ChunkX, a_ChunkZ, a_Callback);
|
||||||
}
|
}
|
||||||
@ -1570,31 +1563,7 @@ bool cWorld::DoWithChunk(int a_ChunkX, int a_ChunkZ, cChunkCallback & a_Callback
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWorld::DoWithChunk(int a_ChunkX, int a_ChunkZ, std::function<bool(cChunk &)> a_Callback)
|
bool cWorld::DoWithChunkAt(Vector3i a_BlockPos, cChunkCallback a_Callback)
|
||||||
{
|
|
||||||
struct cCallBackWrapper : cChunkCallback
|
|
||||||
{
|
|
||||||
cCallBackWrapper(std::function<bool(cChunk &)> a_InnerCallback) :
|
|
||||||
m_Callback(a_InnerCallback)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool Item(cChunk * a_Chunk)
|
|
||||||
{
|
|
||||||
return m_Callback(*a_Chunk);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::function<bool(cChunk &)> m_Callback;
|
|
||||||
} callback(a_Callback);
|
|
||||||
return m_ChunkMap->DoWithChunk(a_ChunkX, a_ChunkZ, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWorld::DoWithChunkAt(Vector3i a_BlockPos, std::function<bool(cChunk &)> a_Callback)
|
|
||||||
{
|
{
|
||||||
return m_ChunkMap->DoWithChunkAt(a_BlockPos, a_Callback);
|
return m_ChunkMap->DoWithChunkAt(a_BlockPos, a_Callback);
|
||||||
}
|
}
|
||||||
@ -3170,18 +3139,13 @@ bool cWorld::IsPlayerReferencedInWorldOrChunk(cPlayer & a_Player)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWorld::ForEachPlayer(cPlayerListCallback & a_Callback)
|
bool cWorld::ForEachPlayer(cPlayerListCallback a_Callback)
|
||||||
{
|
{
|
||||||
// Calls the callback for each player in the list
|
// Calls the callback for each player in the list
|
||||||
cCSLock Lock(m_CSPlayers);
|
cCSLock Lock(m_CSPlayers);
|
||||||
for (cPlayerList::iterator itr = m_Players.begin(), itr2 = itr; itr != m_Players.end(); itr = itr2)
|
for (auto & Player : m_Players)
|
||||||
{
|
{
|
||||||
++itr2;
|
if (Player->IsTicking() && a_Callback(*Player))
|
||||||
if (!(*itr)->IsTicking())
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (a_Callback.Item(*itr))
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -3193,19 +3157,15 @@ bool cWorld::ForEachPlayer(cPlayerListCallback & a_Callback)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWorld::DoWithPlayer(const AString & a_PlayerName, cPlayerListCallback & a_Callback)
|
bool cWorld::DoWithPlayer(const AString & a_PlayerName, cPlayerListCallback a_Callback)
|
||||||
{
|
{
|
||||||
// Calls the callback for the specified player in the list
|
// Calls the callback for the specified player in the list
|
||||||
cCSLock Lock(m_CSPlayers);
|
cCSLock Lock(m_CSPlayers);
|
||||||
for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
for (auto & Player : m_Players)
|
||||||
{
|
{
|
||||||
if (!(*itr)->IsTicking())
|
if (Player->IsTicking() && (NoCaseCompare(Player->GetName(), a_PlayerName) == 0))
|
||||||
{
|
{
|
||||||
continue;
|
a_Callback(*Player);
|
||||||
}
|
|
||||||
if (NoCaseCompare((*itr)->GetName(), a_PlayerName) == 0)
|
|
||||||
{
|
|
||||||
a_Callback.Item(*itr);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} // for itr - m_Players[]
|
} // for itr - m_Players[]
|
||||||
@ -3216,7 +3176,7 @@ bool cWorld::DoWithPlayer(const AString & a_PlayerName, cPlayerListCallback & a_
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWorld::FindAndDoWithPlayer(const AString & a_PlayerNameHint, cPlayerListCallback & a_Callback)
|
bool cWorld::FindAndDoWithPlayer(const AString & a_PlayerNameHint, cPlayerListCallback a_Callback)
|
||||||
{
|
{
|
||||||
cPlayer * BestMatch = nullptr;
|
cPlayer * BestMatch = nullptr;
|
||||||
size_t BestRating = 0;
|
size_t BestRating = 0;
|
||||||
@ -3243,7 +3203,7 @@ bool cWorld::FindAndDoWithPlayer(const AString & a_PlayerNameHint, cPlayerListCa
|
|||||||
|
|
||||||
if (BestMatch != nullptr)
|
if (BestMatch != nullptr)
|
||||||
{
|
{
|
||||||
return a_Callback.Item (BestMatch);
|
return a_Callback(*BestMatch);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -3252,27 +3212,14 @@ bool cWorld::FindAndDoWithPlayer(const AString & a_PlayerNameHint, cPlayerListCa
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWorld::DoWithPlayerByUUID(const cUUID & a_PlayerUUID, cPlayerListCallback & a_Callback)
|
bool cWorld::DoWithPlayerByUUID(const cUUID & a_PlayerUUID, cPlayerListCallback a_Callback)
|
||||||
{
|
|
||||||
return DoWithPlayerByUUID(a_PlayerUUID, std::bind(&cPlayerListCallback::Item, &a_Callback, std::placeholders::_1));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWorld::DoWithPlayerByUUID(const cUUID & a_PlayerUUID, cLambdaPlayerCallback a_Callback)
|
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSPlayers);
|
cCSLock Lock(m_CSPlayers);
|
||||||
for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
for (auto & Player : m_Players)
|
||||||
{
|
{
|
||||||
if (!(*itr)->IsTicking())
|
if (Player->IsTicking() && (Player->GetUUID() == a_PlayerUUID))
|
||||||
{
|
{
|
||||||
continue;
|
return a_Callback(*Player);
|
||||||
}
|
|
||||||
if ((*itr)->GetUUID() == a_PlayerUUID)
|
|
||||||
{
|
|
||||||
return a_Callback(*itr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -3340,7 +3287,7 @@ void cWorld::SendPlayerList(cPlayer * a_DestPlayer)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWorld::ForEachEntity(cEntityCallback & a_Callback)
|
bool cWorld::ForEachEntity(cEntityCallback a_Callback)
|
||||||
{
|
{
|
||||||
return m_ChunkMap->ForEachEntity(a_Callback);
|
return m_ChunkMap->ForEachEntity(a_Callback);
|
||||||
}
|
}
|
||||||
@ -3349,7 +3296,7 @@ bool cWorld::ForEachEntity(cEntityCallback & a_Callback)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWorld::ForEachEntityInChunk(int a_ChunkX, int a_ChunkZ, cEntityCallback & a_Callback)
|
bool cWorld::ForEachEntityInChunk(int a_ChunkX, int a_ChunkZ, cEntityCallback a_Callback)
|
||||||
{
|
{
|
||||||
return m_ChunkMap->ForEachEntityInChunk(a_ChunkX, a_ChunkZ, a_Callback);
|
return m_ChunkMap->ForEachEntityInChunk(a_ChunkX, a_ChunkZ, a_Callback);
|
||||||
}
|
}
|
||||||
@ -3358,7 +3305,7 @@ bool cWorld::ForEachEntityInChunk(int a_ChunkX, int a_ChunkZ, cEntityCallback &
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWorld::ForEachEntityInBox(const cBoundingBox & a_Box, cEntityCallback & a_Callback)
|
bool cWorld::ForEachEntityInBox(const cBoundingBox & a_Box, cEntityCallback a_Callback)
|
||||||
{
|
{
|
||||||
return m_ChunkMap->ForEachEntityInBox(a_Box, a_Callback);
|
return m_ChunkMap->ForEachEntityInBox(a_Box, a_Callback);
|
||||||
}
|
}
|
||||||
@ -3367,16 +3314,7 @@ bool cWorld::ForEachEntityInBox(const cBoundingBox & a_Box, cEntityCallback & a_
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWorld::DoWithEntityByID(UInt32 a_UniqueID, cEntityCallback & a_Callback)
|
bool cWorld::DoWithEntityByID(UInt32 a_UniqueID, cEntityCallback a_Callback)
|
||||||
{
|
|
||||||
return DoWithEntityByID(a_UniqueID, std::bind(&cEntityCallback::Item, &a_Callback, std::placeholders::_1));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWorld::DoWithEntityByID(UInt32 a_UniqueID, cLambdaEntityCallback a_Callback)
|
|
||||||
{
|
{
|
||||||
// First check the entities-to-add:
|
// First check the entities-to-add:
|
||||||
{
|
{
|
||||||
@ -3385,7 +3323,7 @@ bool cWorld::DoWithEntityByID(UInt32 a_UniqueID, cLambdaEntityCallback a_Callbac
|
|||||||
{
|
{
|
||||||
if (ent->GetUniqueID() == a_UniqueID)
|
if (ent->GetUniqueID() == a_UniqueID)
|
||||||
{
|
{
|
||||||
a_Callback(ent.get());
|
a_Callback(*ent);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} // for ent - m_EntitiesToAdd[]
|
} // for ent - m_EntitiesToAdd[]
|
||||||
@ -3517,20 +3455,12 @@ bool cWorld::SetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, const AStrin
|
|||||||
|
|
||||||
bool cWorld::SetCommandBlockCommand(int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Command)
|
bool cWorld::SetCommandBlockCommand(int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Command)
|
||||||
{
|
{
|
||||||
class cUpdateCommandBlock : public cCommandBlockCallback
|
return DoWithCommandBlockAt(a_BlockX, a_BlockY, a_BlockZ, [&](cCommandBlockEntity & a_CommandBlock)
|
||||||
{
|
|
||||||
AString m_Command;
|
|
||||||
public:
|
|
||||||
cUpdateCommandBlock(const AString & a_CallbackCommand) : m_Command(a_CallbackCommand) {}
|
|
||||||
|
|
||||||
virtual bool Item(cCommandBlockEntity * a_CommandBlock) override
|
|
||||||
{
|
{
|
||||||
a_CommandBlock->SetCommand(m_Command);
|
a_CommandBlock.SetCommand(a_Command);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} CmdBlockCB (a_Command);
|
);
|
||||||
|
|
||||||
return DoWithCommandBlockAt(a_BlockX, a_BlockY, a_BlockZ, CmdBlockCB);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3625,7 +3555,7 @@ bool cWorld::ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinChunk
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWorld::ForEachLoadedChunk(std::function<bool(int, int)> a_Callback)
|
bool cWorld::ForEachLoadedChunk(cFunctionRef<bool(int, int)> a_Callback)
|
||||||
{
|
{
|
||||||
return m_ChunkMap->ForEachLoadedChunk(a_Callback);
|
return m_ChunkMap->ForEachLoadedChunk(a_Callback);
|
||||||
}
|
}
|
||||||
|
83
src/World.h
83
src/World.h
@ -59,21 +59,6 @@ typedef std::list< std::pair< std::unique_ptr<cPlayer>, cWorld * > > cAwaitingPl
|
|||||||
typedef std::unique_ptr<cSetChunkData> cSetChunkDataPtr;
|
typedef std::unique_ptr<cSetChunkData> cSetChunkDataPtr;
|
||||||
typedef std::vector<cSetChunkDataPtr> cSetChunkDataPtrs;
|
typedef std::vector<cSetChunkDataPtr> cSetChunkDataPtrs;
|
||||||
|
|
||||||
typedef cItemCallback<cPlayer> cPlayerListCallback;
|
|
||||||
typedef cItemCallback<cEntity> cEntityCallback;
|
|
||||||
typedef cItemCallback<cBeaconEntity> cBeaconCallback;
|
|
||||||
typedef cItemCallback<cBrewingstandEntity> cBrewingstandCallback;
|
|
||||||
typedef cItemCallback<cChestEntity> cChestCallback;
|
|
||||||
typedef cItemCallback<cDispenserEntity> cDispenserCallback;
|
|
||||||
typedef cItemCallback<cFurnaceEntity> cFurnaceCallback;
|
|
||||||
typedef cItemCallback<cNoteEntity> cNoteBlockCallback;
|
|
||||||
typedef cItemCallback<cCommandBlockEntity> cCommandBlockCallback;
|
|
||||||
typedef cItemCallback<cMobHeadEntity> cMobHeadCallback;
|
|
||||||
typedef cItemCallback<cFlowerPotEntity> cFlowerPotCallback;
|
|
||||||
|
|
||||||
typedef std::function<bool (cPlayer *)> cLambdaPlayerCallback;
|
|
||||||
typedef std::function<bool (cEntity *)> cLambdaEntityCallback;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -282,21 +267,20 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** Calls the callback for each player in the list; returns true if all players processed, false if the callback aborted by returning true */
|
/** Calls the callback for each player in the list; returns true if all players processed, false if the callback aborted by returning true */
|
||||||
virtual bool ForEachPlayer(cPlayerListCallback & a_Callback) override; // >> EXPORTED IN MANUALBINDINGS <<
|
virtual bool ForEachPlayer(cPlayerListCallback a_Callback) override; // >> EXPORTED IN MANUALBINDINGS <<
|
||||||
|
|
||||||
/** Calls the callback for the player of the given name; returns true if the player was found and the callback called, false if player not found.
|
/** Calls the callback for the player of the given name; returns true if the player was found and the callback called, false if player not found.
|
||||||
Callback return value is ignored. If there are multiple players of the same name, only (random) one is processed by the callback. */
|
Callback return value is ignored. If there are multiple players of the same name, only (random) one is processed by the callback. */
|
||||||
bool DoWithPlayer(const AString & a_PlayerName, cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS <<
|
bool DoWithPlayer(const AString & a_PlayerName, cPlayerListCallback a_Callback); // >> EXPORTED IN MANUALBINDINGS <<
|
||||||
|
|
||||||
/** Finds a player from a partial or complete player name and calls the callback - case-insensitive */
|
/** Finds a player from a partial or complete player name and calls the callback - case-insensitive */
|
||||||
bool FindAndDoWithPlayer(const AString & a_PlayerNameHint, cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS <<
|
bool FindAndDoWithPlayer(const AString & a_PlayerNameHint, cPlayerListCallback a_Callback); // >> EXPORTED IN MANUALBINDINGS <<
|
||||||
|
|
||||||
// TODO: This interface is dangerous - rewrite to DoWithClosestPlayer(pos, sight, action)
|
// TODO: This interface is dangerous - rewrite to DoWithClosestPlayer(pos, sight, action)
|
||||||
cPlayer * FindClosestPlayer(Vector3d a_Pos, float a_SightLimit, bool a_CheckLineOfSight = true);
|
cPlayer * FindClosestPlayer(Vector3d a_Pos, float a_SightLimit, bool a_CheckLineOfSight = true);
|
||||||
|
|
||||||
/** Finds the player over his uuid and calls the callback */
|
/** Finds the player over his uuid and calls the callback */
|
||||||
bool DoWithPlayerByUUID(const cUUID & a_PlayerUUID, cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS <<
|
bool DoWithPlayerByUUID(const cUUID & a_PlayerUUID, cPlayerListCallback a_Callback); // >> EXPORTED IN MANUALBINDINGS <<
|
||||||
bool DoWithPlayerByUUID(const cUUID & a_PlayerUUID, cLambdaPlayerCallback a_Callback); // Lambda version
|
|
||||||
|
|
||||||
void SendPlayerList(cPlayer * a_DestPlayer); // Sends playerlist to the player
|
void SendPlayerList(cPlayer * a_DestPlayer); // Sends playerlist to the player
|
||||||
|
|
||||||
@ -313,20 +297,19 @@ public:
|
|||||||
OwnedEntity RemoveEntity(cEntity & a_Entity);
|
OwnedEntity RemoveEntity(cEntity & a_Entity);
|
||||||
|
|
||||||
/** Calls the callback for each entity in the entire world; returns true if all entities processed, false if the callback aborted by returning true */
|
/** Calls the callback for each entity in the entire world; returns true if all entities processed, false if the callback aborted by returning true */
|
||||||
bool ForEachEntity(cEntityCallback & a_Callback); // Exported in ManualBindings.cpp
|
bool ForEachEntity(cEntityCallback a_Callback); // Exported in ManualBindings.cpp
|
||||||
|
|
||||||
/** Calls the callback for each entity in the specified chunk; returns true if all entities processed, false if the callback aborted by returning true */
|
/** Calls the callback for each entity in the specified chunk; returns true if all entities processed, false if the callback aborted by returning true */
|
||||||
bool ForEachEntityInChunk(int a_ChunkX, int a_ChunkZ, cEntityCallback & a_Callback); // Exported in ManualBindings.cpp
|
bool ForEachEntityInChunk(int a_ChunkX, int a_ChunkZ, cEntityCallback a_Callback); // Exported in ManualBindings.cpp
|
||||||
|
|
||||||
/** Calls the callback for each entity that has a nonempty intersection with the specified boundingbox.
|
/** Calls the callback for each entity that has a nonempty intersection with the specified boundingbox.
|
||||||
Returns true if all entities processed, false if the callback aborted by returning true.
|
Returns true if all entities processed, false if the callback aborted by returning true.
|
||||||
If any chunk in the box is missing, ignores the entities in that chunk silently. */
|
If any chunk in the box is missing, ignores the entities in that chunk silently. */
|
||||||
virtual bool ForEachEntityInBox(const cBoundingBox & a_Box, cEntityCallback & a_Callback) override; // Exported in ManualBindings.cpp
|
virtual bool ForEachEntityInBox(const cBoundingBox & a_Box, cEntityCallback a_Callback) override; // Exported in ManualBindings.cpp
|
||||||
|
|
||||||
/** Calls the callback if the entity with the specified ID is found, with the entity object as the callback param.
|
/** Calls the callback if the entity with the specified ID is found, with the entity object as the callback param.
|
||||||
Returns true if entity found and callback returned false. */
|
Returns true if entity found and callback returned false. */
|
||||||
bool DoWithEntityByID(UInt32 a_UniqueID, cEntityCallback & a_Callback); // Exported in ManualBindings.cpp
|
bool DoWithEntityByID(UInt32 a_UniqueID, cEntityCallback a_Callback); // Exported in ManualBindings.cpp
|
||||||
bool DoWithEntityByID(UInt32 a_UniqueID, cLambdaEntityCallback a_Callback); // Lambda version
|
|
||||||
|
|
||||||
/** Compares clients of two chunks, calls the callback accordingly */
|
/** Compares clients of two chunks, calls the callback accordingly */
|
||||||
void CompareChunkClients(int a_ChunkX1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkZ2, cClientDiffCallback & a_Callback);
|
void CompareChunkClients(int a_ChunkX1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkZ2, cClientDiffCallback & a_Callback);
|
||||||
@ -390,7 +373,7 @@ public:
|
|||||||
virtual bool ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ, cChunkDataCallback & a_Callback) override;
|
virtual bool ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ, cChunkDataCallback & a_Callback) override;
|
||||||
|
|
||||||
/** Calls the callback for each loaded chunk. Returns true if all chunks have been processed successfully */
|
/** Calls the callback for each loaded chunk. Returns true if all chunks have been processed successfully */
|
||||||
bool ForEachLoadedChunk(std::function<bool(int, int)> a_Callback);
|
bool ForEachLoadedChunk(cFunctionRef<bool(int, int)> a_Callback);
|
||||||
|
|
||||||
// tolua_begin
|
// tolua_begin
|
||||||
|
|
||||||
@ -541,25 +524,25 @@ public:
|
|||||||
inline cRedstoneSimulator * GetRedstoneSimulator(void) { return m_RedstoneSimulator; }
|
inline cRedstoneSimulator * GetRedstoneSimulator(void) { return m_RedstoneSimulator; }
|
||||||
|
|
||||||
/** Calls the callback for each block entity in the specified chunk; returns true if all block entities processed, false if the callback aborted by returning true */
|
/** Calls the callback for each block entity in the specified chunk; returns true if all block entities processed, false if the callback aborted by returning true */
|
||||||
bool ForEachBlockEntityInChunk(int a_ChunkX, int a_ChunkZ, cBlockEntityCallback & a_Callback); // Exported in ManualBindings.cpp
|
bool ForEachBlockEntityInChunk(int a_ChunkX, int a_ChunkZ, cBlockEntityCallback a_Callback); // Exported in ManualBindings.cpp
|
||||||
|
|
||||||
/** Calls the callback for each brewingstand in the specified chunk; returns true if all brewingstands processed, false if the callback aborted by returning true */
|
/** Calls the callback for each brewingstand in the specified chunk; returns true if all brewingstands processed, false if the callback aborted by returning true */
|
||||||
bool ForEachBrewingstandInChunk(int a_ChunkX, int a_ChunkZ, cBrewingstandCallback & a_Callback); // Exported in ManualBindings.cpp
|
bool ForEachBrewingstandInChunk(int a_ChunkX, int a_ChunkZ, cBrewingstandCallback a_Callback); // Exported in ManualBindings.cpp
|
||||||
|
|
||||||
/** Calls the callback for each chest in the specified chunk; returns true if all chests processed, false if the callback aborted by returning true */
|
/** Calls the callback for each chest in the specified chunk; returns true if all chests processed, false if the callback aborted by returning true */
|
||||||
bool ForEachChestInChunk(int a_ChunkX, int a_ChunkZ, cChestCallback & a_Callback); // Exported in ManualBindings.cpp
|
bool ForEachChestInChunk(int a_ChunkX, int a_ChunkZ, cChestCallback a_Callback); // Exported in ManualBindings.cpp
|
||||||
|
|
||||||
/** Calls the callback for each dispenser in the specified chunk; returns true if all dispensers processed, false if the callback aborted by returning true */
|
/** Calls the callback for each dispenser in the specified chunk; returns true if all dispensers processed, false if the callback aborted by returning true */
|
||||||
bool ForEachDispenserInChunk(int a_ChunkX, int a_ChunkZ, cDispenserCallback & a_Callback);
|
bool ForEachDispenserInChunk(int a_ChunkX, int a_ChunkZ, cDispenserCallback a_Callback);
|
||||||
|
|
||||||
/** Calls the callback for each dropper in the specified chunk; returns true if all droppers processed, false if the callback aborted by returning true */
|
/** Calls the callback for each dropper in the specified chunk; returns true if all droppers processed, false if the callback aborted by returning true */
|
||||||
bool ForEachDropperInChunk(int a_ChunkX, int a_ChunkZ, cDropperCallback & a_Callback);
|
bool ForEachDropperInChunk(int a_ChunkX, int a_ChunkZ, cDropperCallback a_Callback);
|
||||||
|
|
||||||
/** Calls the callback for each dropspenser in the specified chunk; returns true if all dropspensers processed, false if the callback aborted by returning true */
|
/** Calls the callback for each dropspenser in the specified chunk; returns true if all dropspensers processed, false if the callback aborted by returning true */
|
||||||
bool ForEachDropSpenserInChunk(int a_ChunkX, int a_ChunkZ, cDropSpenserCallback & a_Callback);
|
bool ForEachDropSpenserInChunk(int a_ChunkX, int a_ChunkZ, cDropSpenserCallback a_Callback);
|
||||||
|
|
||||||
/** Calls the callback for each furnace in the specified chunk; returns true if all furnaces processed, false if the callback aborted by returning true */
|
/** Calls the callback for each furnace in the specified chunk; returns true if all furnaces processed, false if the callback aborted by returning true */
|
||||||
bool ForEachFurnaceInChunk(int a_ChunkX, int a_ChunkZ, cFurnaceCallback & a_Callback); // Exported in ManualBindings.cpp
|
bool ForEachFurnaceInChunk(int a_ChunkX, int a_ChunkZ, cFurnaceCallback a_Callback); // Exported in ManualBindings.cpp
|
||||||
|
|
||||||
/** Does an explosion with the specified strength at the specified coordinates.
|
/** Does an explosion with the specified strength at the specified coordinates.
|
||||||
Executes the HOOK_EXPLODING and HOOK_EXPLODED hooks as part of the processing.
|
Executes the HOOK_EXPLODING and HOOK_EXPLODED hooks as part of the processing.
|
||||||
@ -568,43 +551,43 @@ public:
|
|||||||
virtual void DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, bool a_CanCauseFire, eExplosionSource a_Source, void * a_SourceData) override;
|
virtual void DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, bool a_CanCauseFire, eExplosionSource a_Source, void * a_SourceData) override;
|
||||||
|
|
||||||
/** Calls the callback for the block entity at the specified coords; returns false if there's no block entity at those coords, true if found */
|
/** Calls the callback for the block entity at the specified coords; returns false if there's no block entity at those coords, true if found */
|
||||||
virtual bool DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback & a_Callback) override; // Exported in ManualBindings.cpp
|
virtual bool DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback a_Callback) override; // Exported in ManualBindings.cpp
|
||||||
|
|
||||||
/** Calls the callback for the beacon at the specified coords; returns false if there's no beacon at those coords, true if found */
|
/** Calls the callback for the beacon at the specified coords; returns false if there's no beacon at those coords, true if found */
|
||||||
bool DoWithBeaconAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconCallback & a_Callback); // Exported in ManualBindings.cpp
|
bool DoWithBeaconAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconCallback a_Callback); // Exported in ManualBindings.cpp
|
||||||
|
|
||||||
/** Calls the callback for the bed at the specified coords; returns false if there's no bed at those coords, true if found */
|
/** Calls the callback for the bed at the specified coords; returns false if there's no bed at those coords, true if found */
|
||||||
virtual bool DoWithBedAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBedCallback & a_Callback) override; // Exported in ManualBindings.cpp
|
virtual bool DoWithBedAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBedCallback a_Callback) override; // Exported in ManualBindings.cpp
|
||||||
|
|
||||||
/** Calls the callback for the brewingstand at the specified coords; returns false if there's no brewingstand at those coords, true if found */
|
/** Calls the callback for the brewingstand at the specified coords; returns false if there's no brewingstand at those coords, true if found */
|
||||||
bool DoWithBrewingstandAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBrewingstandCallback & a_Callback); // Lua-acessible
|
bool DoWithBrewingstandAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBrewingstandCallback a_Callback); // Lua-acessible
|
||||||
|
|
||||||
/** Calls the callback for the chest at the specified coords; returns false if there's no chest at those coords, true if found */
|
/** Calls the callback for the chest at the specified coords; returns false if there's no chest at those coords, true if found */
|
||||||
bool DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallback & a_Callback); // Exported in ManualBindings.cpp
|
bool DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallback a_Callback); // Exported in ManualBindings.cpp
|
||||||
|
|
||||||
/** Calls the callback for the dispenser at the specified coords; returns false if there's no dispenser at those coords or callback returns true, returns true if found */
|
/** Calls the callback for the dispenser at the specified coords; returns false if there's no dispenser at those coords or callback returns true, returns true if found */
|
||||||
bool DoWithDispenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDispenserCallback & a_Callback); // Exported in ManualBindings.cpp
|
bool DoWithDispenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDispenserCallback a_Callback); // Exported in ManualBindings.cpp
|
||||||
|
|
||||||
/** Calls the callback for the dropper at the specified coords; returns false if there's no dropper at those coords or callback returns true, returns true if found */
|
/** Calls the callback for the dropper at the specified coords; returns false if there's no dropper at those coords or callback returns true, returns true if found */
|
||||||
bool DoWithDropperAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDropperCallback & a_Callback); // Exported in ManualBindings.cpp
|
bool DoWithDropperAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDropperCallback a_Callback); // Exported in ManualBindings.cpp
|
||||||
|
|
||||||
/** Calls the callback for the dropspenser at the specified coords; returns false if there's no dropspenser at those coords or callback returns true, returns true if found */
|
/** Calls the callback for the dropspenser at the specified coords; returns false if there's no dropspenser at those coords or callback returns true, returns true if found */
|
||||||
bool DoWithDropSpenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDropSpenserCallback & a_Callback); // Exported in ManualBindings.cpp
|
bool DoWithDropSpenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDropSpenserCallback a_Callback); // Exported in ManualBindings.cpp
|
||||||
|
|
||||||
/** Calls the callback for the furnace at the specified coords; returns false if there's no furnace at those coords or callback returns true, returns true if found */
|
/** Calls the callback for the furnace at the specified coords; returns false if there's no furnace at those coords or callback returns true, returns true if found */
|
||||||
bool DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceCallback & a_Callback); // Exported in ManualBindings.cpp
|
bool DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceCallback a_Callback); // Exported in ManualBindings.cpp
|
||||||
|
|
||||||
/** Calls the callback for the noteblock at the specified coords; returns false if there's no noteblock at those coords or callback returns true, returns true if found */
|
/** Calls the callback for the noteblock at the specified coords; returns false if there's no noteblock at those coords or callback returns true, returns true if found */
|
||||||
bool DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNoteBlockCallback & a_Callback); // Exported in ManualBindings.cpp
|
bool DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNoteBlockCallback a_Callback); // Exported in ManualBindings.cpp
|
||||||
|
|
||||||
/** Calls the callback for the command block at the specified coords; returns false if there's no command block at those coords or callback returns true, returns true if found */
|
/** Calls the callback for the command block at the specified coords; returns false if there's no command block at those coords or callback returns true, returns true if found */
|
||||||
bool DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cCommandBlockCallback & a_Callback); // Exported in ManualBindings.cpp
|
bool DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cCommandBlockCallback a_Callback); // Exported in ManualBindings.cpp
|
||||||
|
|
||||||
/** Calls the callback for the mob head block at the specified coords; returns false if there's no mob head block at those coords or callback returns true, returns true if found */
|
/** Calls the callback for the mob head block at the specified coords; returns false if there's no mob head block at those coords or callback returns true, returns true if found */
|
||||||
bool DoWithMobHeadAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadCallback & a_Callback); // Exported in ManualBindings.cpp
|
bool DoWithMobHeadAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadCallback a_Callback); // Exported in ManualBindings.cpp
|
||||||
|
|
||||||
/** Calls the callback for the flower pot at the specified coords; returns false if there's no flower pot at those coords or callback returns true, returns true if found */
|
/** Calls the callback for the flower pot at the specified coords; returns false if there's no flower pot at those coords or callback returns true, returns true if found */
|
||||||
bool DoWithFlowerPotAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFlowerPotCallback & a_Callback); // Exported in ManualBindings.cpp
|
bool DoWithFlowerPotAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFlowerPotCallback a_Callback); // Exported in ManualBindings.cpp
|
||||||
|
|
||||||
/** Retrieves the test on the sign at the specified coords; returns false if there's no sign at those coords, true if found */
|
/** Retrieves the test on the sign at the specified coords; returns false if there's no sign at those coords, true if found */
|
||||||
bool GetSignLines (int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4); // Exported in ManualBindings.cpp
|
bool GetSignLines (int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4); // Exported in ManualBindings.cpp
|
||||||
@ -612,13 +595,13 @@ public:
|
|||||||
/** a_Player is using block entity at [x, y, z], handle that: */
|
/** a_Player is using block entity at [x, y, z], handle that: */
|
||||||
void UseBlockEntity(cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) {m_ChunkMap->UseBlockEntity(a_Player, a_BlockX, a_BlockY, a_BlockZ); } // tolua_export
|
void UseBlockEntity(cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) {m_ChunkMap->UseBlockEntity(a_Player, a_BlockX, a_BlockY, a_BlockZ); } // tolua_export
|
||||||
|
|
||||||
/** Calls the callback for the chunk specified, with ChunkMapCS locked; returns false if the chunk doesn't exist, otherwise returns the same value as the callback */
|
/** Calls the callback for the chunk specified, with ChunkMapCS locked.
|
||||||
bool DoWithChunk(int a_ChunkX, int a_ChunkZ, cChunkCallback & a_Callback);
|
Returns false if the chunk doesn't exist, otherwise returns the same value as the callback */
|
||||||
bool DoWithChunk(int a_ChunkX, int a_ChunkZ, std::function<bool(cChunk &)> a_Callback);
|
bool DoWithChunk(int a_ChunkX, int a_ChunkZ, cChunkCallback a_Callback);
|
||||||
|
|
||||||
/** Calls the callback for the chunk at the block position specified, with ChunkMapCS locked.
|
/** Calls the callback for the chunk at the block position specified, with ChunkMapCS locked.
|
||||||
Returns false if the chunk isn't loaded, otherwise returns the same value as the callback */
|
Returns false if the chunk isn't loaded, otherwise returns the same value as the callback */
|
||||||
bool DoWithChunkAt(Vector3i a_BlockPos, std::function<bool(cChunk &)> a_Callback);
|
bool DoWithChunkAt(Vector3i a_BlockPos, cChunkCallback a_Callback);
|
||||||
|
|
||||||
void GrowTreeImage(const sSetBlockVector & a_Blocks);
|
void GrowTreeImage(const sSetBlockVector & a_Blocks);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user