From e225b7f8262df48ad4d7094bc295add3007b0649 Mon Sep 17 00:00:00 2001 From: peterbell10 Date: Mon, 11 Sep 2017 22:20:49 +0100 Subject: Replace ItemCallbacks with lambdas (#3993) --- src/Bindings/LuaState.cpp | 4 +- src/Bindings/LuaState.h | 5 +- src/Bindings/LuaWindow.cpp | 15 +- src/Bindings/LuaWindow.h | 2 +- src/Bindings/ManualBindings.cpp | 68 ++---- src/Bindings/ManualBindings.h | 235 +++++---------------- src/Bindings/ManualBindings_World.cpp | 6 +- src/Bindings/PluginManager.cpp | 8 +- src/Bindings/PluginManager.h | 9 +- src/BlockArea.cpp | 10 +- src/BlockArea.h | 9 +- src/BlockEntities/BeaconEntity.cpp | 60 ++---- src/BlockEntities/ChestEntity.cpp | 28 +-- src/BlockEntities/HopperEntity.cpp | 21 +- src/BlockEntities/MobSpawnerEntity.cpp | 41 ++-- src/Blocks/BlockBed.cpp | 130 +++--------- src/Blocks/BlockMobHead.h | 22 +- src/Blocks/WorldInterface.h | 23 +- src/CMakeLists.txt | 1 + src/Chunk.cpp | 83 +++----- src/Chunk.h | 64 +++--- src/ChunkMap.cpp | 127 ++++------- src/ChunkMap.h | 92 ++++---- src/ClientHandle.cpp | 73 ++----- src/DeadlockDetect.cpp | 38 +--- src/Entities/Entity.cpp | 28 +-- src/Entities/Floater.cpp | 45 +--- src/Entities/LeashKnot.cpp | 61 ++---- src/Entities/Minecart.cpp | 23 +- src/Entities/Pawn.cpp | 68 +++--- src/Entities/Pickup.cpp | 23 +- src/Entities/Player.cpp | 73 ++----- src/Entities/ProjectileEntity.cpp | 40 ++-- src/Entities/SplashPotionEntity.cpp | 80 +++---- src/Entities/ThrownEnderPearlEntity.cpp | 25 +-- src/FunctionRef.h | 58 +++++ src/Globals.h | 14 -- src/Items/ItemFishingRod.h | 52 ++--- src/Items/ItemMobHead.h | 75 +++---- src/LineBlockTracer.cpp | 6 +- src/LineBlockTracer.h | 10 +- src/Map.cpp | 42 ++-- src/MapManager.cpp | 4 +- src/MapManager.h | 5 +- src/MobSpawner.cpp | 11 +- src/MobSpawner.h | 8 +- src/Mobs/Creeper.cpp | 15 +- src/Mobs/Enderman.cpp | 17 +- src/Mobs/Ocelot.cpp | 61 +++--- src/Mobs/PassiveMonster.cpp | 49 ++--- src/Mobs/Wither.cpp | 19 +- src/Mobs/Wolf.cpp | 45 ++-- src/Root.cpp | 70 +++--- src/Root.h | 15 +- src/Scoreboard.cpp | 12 +- src/Scoreboard.h | 11 +- src/Server.cpp | 18 +- .../CommandBlockHandler.h | 11 +- .../DropSpenserHandler.h | 12 +- .../NoteBlockHandler.h | 11 +- .../PressurePlateHandler.h | 34 +-- .../RedstoneComparatorHandler.h | 26 +-- .../TrappedChestHandler.h | 37 +--- .../TripwireHookHandler.h | 21 +- src/UI/Window.cpp | 12 +- src/UI/Window.h | 8 +- src/WebAdmin.cpp | 24 --- src/World.cpp | 192 ++++++----------- src/World.h | 83 +++----- 69 files changed, 915 insertions(+), 1813 deletions(-) create mode 100644 src/FunctionRef.h diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp index 7bd4becb6..82dbfb780 100644 --- a/src/Bindings/LuaState.cpp +++ b/src/Bindings/LuaState.cpp @@ -379,7 +379,7 @@ cLuaState::cStackTable::cStackTable(cLuaState & a_LuaState, int a_StackPos): -void cLuaState::cStackTable::ForEachArrayElement(std::function a_ElementCallback) const +void cLuaState::cStackTable::ForEachArrayElement(cFunctionRef a_ElementCallback) const { auto numElements = luaL_getn(m_LuaState, m_StackPos); #ifdef _DEBUG @@ -404,7 +404,7 @@ void cLuaState::cStackTable::ForEachArrayElement(std::function a_ElementCallback) const +void cLuaState::cStackTable::ForEachElement(cFunctionRef a_ElementCallback) const { #ifdef _DEBUG auto stackTop = lua_gettop(m_LuaState); diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h index 98f1cbc28..60af36228 100644 --- a/src/Bindings/LuaState.h +++ b/src/Bindings/LuaState.h @@ -39,6 +39,7 @@ extern "C" #include #include "../Defines.h" +#include "../FunctionRef.h" #include "PluginManager.h" #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 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. */ - void ForEachArrayElement(std::function a_ElementCallback) const; + void ForEachArrayElement(cFunctionRef a_ElementCallback) const; /** Iterates over all dictionary elements in the table in random order, and calls the a_ElementCallback for each of them. 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 returns false, the iteration continues with the next element. */ - void ForEachElement(std::function a_ElementCallback) const; + void ForEachElement(cFunctionRef a_ElementCallback) const; cLuaState & GetLuaState(void) const { return m_LuaState; } diff --git a/src/Bindings/LuaWindow.cpp b/src/Bindings/LuaWindow.cpp index 2802c69db..ae390e576 100644 --- a/src/Bindings/LuaWindow.cpp +++ b/src/Bindings/LuaWindow.cpp @@ -54,22 +54,15 @@ cLuaWindow::~cLuaWindow() m_Contents.RemoveListener(*this); // Close open lua window from players, to avoid dangling pointers - class cPlayerCallback : public cPlayerListCallback - { - virtual bool Item(cPlayer * a_Player) + cRoot::Get()->ForEachPlayer([this](cPlayer & a_Player) { - if (a_Player->GetWindow() == m_LuaWindow) + if (a_Player.GetWindow() == this) { - a_Player->CloseWindow(false); + a_Player.CloseWindow(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 // destructor, when the member is already gone. diff --git a/src/Bindings/LuaWindow.h b/src/Bindings/LuaWindow.h index 8f3349d00..6177b2cbe 100644 --- a/src/Bindings/LuaWindow.h +++ b/src/Bindings/LuaWindow.h @@ -15,7 +15,7 @@ class cPlayer; -typedef cItemCallback cPlayerListCallback; +typedef cFunctionRef cPlayerListCallback; /** A window that has been created by a Lua plugin and is handled entirely by that plugin diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 38dc2cf83..5f8a3507d 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -1483,44 +1483,29 @@ static int tolua_cPluginManager_CallPlugin(lua_State * tolua_S) } // Call the destination plugin using a plugin callback: - class cCallback : - public cPluginManager::cPluginCallback - { - public: - int m_NumReturns; - - cCallback(const AString & a_FunctionName, cLuaState & a_SrcLuaState) : - m_NumReturns(0), - m_FunctionName(a_FunctionName), - m_SrcLuaState(a_SrcLuaState) + int NumReturns = 0; + auto PluginCallback = [&](cPlugin & a_Plugin) { - } - protected: - const AString & m_FunctionName; - cLuaState & m_SrcLuaState; - - virtual bool Item(cPlugin * a_Plugin) override - { - if (!a_Plugin->IsLoaded()) + if (!a_Plugin.IsLoaded()) { return false; } - m_NumReturns = static_cast(a_Plugin)->CallFunctionFromForeignState( - m_FunctionName, m_SrcLuaState, 4, lua_gettop(m_SrcLuaState) + NumReturns = static_cast(a_Plugin).CallFunctionFromForeignState( + FunctionName, L, 4, lua_gettop(L) ); return true; - } - } Callback(FunctionName, L); - if (!cPluginManager::Get()->DoWithPlugin(PluginName, Callback)) + }; + + if (!cPluginManager::Get()->DoWithPlugin(PluginName, PluginCallback)) { 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") return 0; } - return Callback.m_NumReturns; + return NumReturns; } @@ -3243,42 +3228,29 @@ static int tolua_cRoot_DoWithPlayerByUUID(lua_State * tolua_S) 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: cRoot * Self; cUUID PlayerUUID; - L.GetStackValues(1, Self, PlayerUUID, Callback.m_FnRef); + cLuaState::cRef FnRef; + L.GetStackValues(1, Self, PlayerUUID, FnRef); if (PlayerUUID.IsNil()) { 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"); } // 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: L.Push(res); diff --git a/src/Bindings/ManualBindings.h b/src/Bindings/ManualBindings.h index dc9d9462f..0272e993b 100644 --- a/src/Bindings/ManualBindings.h +++ b/src/Bindings/ManualBindings.h @@ -1,4 +1,4 @@ - + // ManualBindings.h // Declares the cManualBindings class used as a namespace for functions exported to the Lua API manually @@ -57,7 +57,7 @@ public: template < class Ty1, class Ty2, - bool (Ty1::*DoWithFn)(const AString &, cItemCallback &) + bool (Ty1::*DoWithFn)(const AString &, cFunctionRef) > 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"); } - class cLuaCallback : public cItemCallback - { - 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 + // Call the DoWith function: + bool res = (Self->*DoWithFn)(ItemName, [&](Ty2 & a_Item) { bool ret = false; - m_LuaState.Call(m_FnRef, a_Item, cLuaState::Return, ret); + L.Call(FnRef, &a_Item, cLuaState::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: L.Push(res); @@ -125,7 +111,7 @@ public: template < class Ty1, class Ty2, - bool (Ty1::*DoWithFn)(const AString &, cItemCallback &) + bool (Ty1::*DoWithFn)(const AString &, cFunctionRef) > 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"); } - class cLuaCallback : public cItemCallback - { - 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 + // Call the DoWith function: + bool res = (Ty1::Get()->*DoWithFn)(ItemName, [&](Ty2 & a_Item) { bool ret = false; - m_LuaState.Call(m_FnRef, a_Item, cLuaState::Return, ret); + L.Call(FnRef, &a_Item, cLuaState::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: L.Push(res); @@ -187,7 +159,7 @@ public: template < class Ty1, class Ty2, - bool (Ty1::*DoWithFn)(UInt32, cItemCallback &) + bool (Ty1::*DoWithFn)(UInt32, cFunctionRef) > 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"); } - class cLuaCallback : public cItemCallback - { - 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 + // Call the DoWith function: + bool res = (Self->*DoWithFn)(ItemID, [&](Ty2 & a_Item) { bool ret = false; - m_LuaState.Call(m_FnRef, a_Item, cLuaState::Return, ret); + L.Call(FnRef, &a_Item, cLuaState::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: L.Push(res); @@ -251,7 +209,7 @@ public: template < class SELF, class ITEM, - bool (SELF::*DoWithFn)(int, int, int, cItemCallback &) + bool (SELF::*DoWithFn)(int, int, int, cFunctionRef) > 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"); } - class cLuaCallback : public cItemCallback - { - 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 + // Call the DoWith function: + bool res = (Self->*DoWithFn)(BlockX, BlockY, BlockZ, [&](ITEM & a_Item) { bool ret = false; - m_LuaState.Call(m_FnRef, a_Item, cLuaState::Return, ret); + L.Call(FnRef, &a_Item, cLuaState::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: L.Push(res); @@ -318,7 +262,7 @@ public: template < class SELF, class ITEM, - bool (SELF::*DoWithFn)(int, int, int, cItemCallback &), + bool (SELF::*DoWithFn)(int, int, int, cFunctionRef), bool (SELF::*CoordCheckFn)(int, int, int) const > static int DoWithXYZ(lua_State * tolua_S) @@ -356,28 +300,14 @@ public: ).c_str()); } - class cLuaCallback : public cItemCallback - { - 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 + // Call the DoWith function: + bool res = (Self->*DoWithFn)(BlockX, BlockY, BlockZ, [&](ITEM & a_Item) { bool ret = false; - m_LuaState.Call(m_FnRef, a_Item, cLuaState::Return, ret); + L.Call(FnRef, &a_Item, cLuaState::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: L.Push(res); @@ -391,7 +321,7 @@ public: template < class Ty1, class Ty2, - bool (Ty1::*ForEachFn)(int, int, cItemCallback &) + bool (Ty1::*ForEachFn)(int, int, cFunctionRef) > 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"); } - class cLuaCallback : public cItemCallback - { - 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 + // Call the DoWith function: + bool res = (Self->*ForEachFn)(ChunkX, ChunkZ, [&](Ty2 & a_Item) { bool ret = false; - m_LuaState.Call(m_FnRef, a_Item, cLuaState::Return, ret); + L.Call(FnRef, &a_Item, cLuaState::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: L.Push(res); @@ -456,7 +372,7 @@ public: template < class Ty1, class Ty2, - bool (Ty1::*ForEachFn)(const cBoundingBox &, cItemCallback &) + bool (Ty1::*ForEachFn)(const cBoundingBox &, cFunctionRef) > 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"); } - // Callback wrapper for the Lua function: - class cLuaCallback : public cItemCallback - { - public: - cLuaCallback(cLuaState & a_LuaState, cLuaState::cRef & a_FuncRef) : - m_LuaState(a_LuaState), - m_FnRef(a_FuncRef) + bool res = (Self->*ForEachFn)(*Box, [&](Ty2 & a_Item) { - } - - private: - cLuaState & m_LuaState; - cLuaState::cRef & m_FnRef; - - // cItemCallback overrides: - virtual bool Item(Ty2 * a_Item) override - { - bool res = false; - if (!m_LuaState.Call(m_FnRef, a_Item, cLuaState::Return, res)) + bool ret = false; + if (!L.Call(FnRef, &a_Item, cLuaState::Return, ret)) { LOGWARNING("Failed to call Lua callback"); - m_LuaState.LogStackTrace(); + L.LogStackTrace(); return true; // Abort enumeration } - return res; + return ret; } - } Callback(L, FnRef); - - bool res = (Self->*ForEachFn)(*Box, Callback); + ); // Push the result as the return value: L.Push(res); @@ -531,7 +430,7 @@ public: template < class Ty1, class Ty2, - bool (Ty1::*ForEachFn)(cItemCallback &) + bool (Ty1::*ForEachFn)(cFunctionRef) > 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"); } - class cLuaCallback : public cItemCallback - { - 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 + // Call the enumeration: + bool res = (Self->*ForEachFn)([&](Ty2 & a_Item) { - bool res = false; // By default continue the enumeration - m_LuaState.Call(m_FnRef, a_Item, cLuaState::Return, res); - return res; + bool ret = false; // By default continue the enumeration + L.Call(FnRef, &a_Item, cLuaState::Return, ret); + return ret; } - } Callback(L, FnRef); - - // Call the enumeration: - bool res = (Self->*ForEachFn)(Callback); + ); // Push the return value: L.Push(res); @@ -595,7 +479,7 @@ public: template < class Ty1, class Ty2, - bool (Ty1::*ForEachFn)(cItemCallback &) + bool (Ty1::*ForEachFn)(cFunctionRef) > 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"); } - class cLuaCallback : public cItemCallback - { - 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 + // Call the enumeration: + bool res = (Ty1::Get()->*ForEachFn)([&](Ty2 & a_Item) { - bool res = false; // By default continue the enumeration - m_LuaState.Call(m_FnRef, a_Item, cLuaState::Return, res); - return res; + bool ret = false; // By default continue the enumeration + L.Call(FnRef, &a_Item, cLuaState::Return, ret); + return ret; } - } Callback(L, FnRef); - - // Call the enumeration: - bool res = (Ty1::Get()->*ForEachFn)(Callback); + ); // Push the return value: L.Push(res); diff --git a/src/Bindings/ManualBindings_World.cpp b/src/Bindings/ManualBindings_World.cpp index 10b5daf1e..826439e3f 100644 --- a/src/Bindings/ManualBindings_World.cpp +++ b/src/Bindings/ManualBindings_World.cpp @@ -1,4 +1,4 @@ - + // ManualBindings_World.cpp // 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: - bool res = Self->DoWithPlayerByUUID(PlayerUUID, [&](cPlayer * a_Player) + bool res = Self->DoWithPlayerByUUID(PlayerUUID, [&](cPlayer & a_Player) { bool ret = false; - L.Call(FnRef, a_Player, cLuaState::Return, ret); + L.Call(FnRef, &a_Player, cLuaState::Return, ret); return ret; } ); diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index 7c4712f0f..9a9b56792 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -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 for (auto & plugin: m_Plugins) { if (plugin->GetName() == a_PluginName) { - return a_Callback.Item(plugin.get()); + return a_Callback(*plugin); } } 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 for (auto & plugin: m_Plugins) { - if (a_Callback.Item(plugin.get())) + if (a_Callback(*plugin)) { return false; } diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index 66f7d290a..fdc1d1e7a 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -3,6 +3,7 @@ #include "Defines.h" +#include "FunctionRef.h" @@ -194,7 +195,7 @@ public: /** The interface used for enumerating and extern-calling plugins */ - typedef cItemCallback cPluginCallback; + using cPluginCallback = cFunctionRef; typedef std::list PluginList; @@ -372,18 +373,18 @@ public: /** 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. */ - 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. 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. */ AString GetPluginFolderName(const AString & a_PluginName); // tolua_export /** Returns the path where individual plugins' folders are expected. 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: friend class cRoot; diff --git a/src/BlockArea.cpp b/src/BlockArea.cpp index 1b714d640..b32851afc 100644 --- a/src/BlockArea.cpp +++ b/src/BlockArea.cpp @@ -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 & 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)); if (!HasBlockEntities()) @@ -2176,14 +2176,14 @@ bool cBlockArea::DoWithBlockEntityRelAt(int a_RelX, int a_RelY, int a_RelZ, cIte { 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 & 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); } @@ -2192,7 +2192,7 @@ bool cBlockArea::DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, c -bool cBlockArea::ForEachBlockEntity(cItemCallback & a_Callback) +bool cBlockArea::ForEachBlockEntity(cBlockEntityCallback a_Callback) { if (!HasBlockEntities()) { @@ -2200,7 +2200,7 @@ bool cBlockArea::ForEachBlockEntity(cItemCallback & a_Callback) } for (auto & keyPair: *m_BlockEntities) { - if (a_Callback.Item(keyPair.second)) + if (a_Callback(*keyPair.second)) { return false; } diff --git a/src/BlockArea.h b/src/BlockArea.h index ab7fb8f2c..60a2821bd 100644 --- a/src/BlockArea.h +++ b/src/BlockArea.h @@ -17,13 +17,14 @@ #include "ForEachChunkProvider.h" #include "ChunkDataCallback.h" #include "Cuboid.h" +#include "FunctionRef.h" // fwd: class cCuboid; - +using cBlockEntityCallback = cFunctionRef; @@ -379,18 +380,18 @@ public: /** 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 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 & 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. 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. */ - bool DoWithBlockEntityAt (int a_BlockX, int a_BlockY, int a_BlockZ, cItemCallback & a_Callback); + bool DoWithBlockEntityAt (int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback a_Callback); /** Calls the callback for all the block entities. If the callback returns true, aborts the enumeration and returns false. 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). */ - bool ForEachBlockEntity(cItemCallback & a_Callback); + bool ForEachBlockEntity(cBlockEntityCallback a_Callback); /** Direct read-only access to block entities. */ const cBlockEntities & GetBlockEntities(void) const { ASSERT(HasBlockEntities()); return *m_BlockEntities; } diff --git a/src/BlockEntities/BeaconEntity.cpp b/src/BlockEntities/BeaconEntity.cpp index a98547ba7..1d088a56f 100644 --- a/src/BlockEntities/BeaconEntity.cpp +++ b/src/BlockEntities/BeaconEntity.cpp @@ -1,4 +1,4 @@ - + #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "BeaconEntity.h" @@ -195,33 +195,21 @@ void cBeaconEntity::UpdateBeacon(void) GetWindow()->SetProperty(0, m_BeaconLevel); } - class cPlayerCallback : - public cPlayerListCallback - { - public: - cPlayerCallback(Vector3d a_Position): - m_Position(a_Position) + Vector3d BeaconPosition(m_PosX, m_PosY, m_PosZ); + GetWorld()->ForEachPlayer([=](cPlayer & a_Player) { - } - - virtual bool Item(cPlayer * a_Player) - { - Vector3d Distance = m_Position - a_Player->GetPosition(); + Vector3d Distance = BeaconPosition - a_Player.GetPosition(); if ( (std::abs(Distance.y) <= 14) && (std::abs(Distance.x) <= 20) && (std::abs(Distance.z) <= 20) ) { - a_Player->AwardAchievement(eStatistic::achFullBeacon); + a_Player.AwardAchievement(eStatistic::achFullBeacon); } 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; } - class cPlayerCallback : public cPlayerListCallback - { - int m_Radius; - Vector3d m_Position; - cEntityEffect::eType m_PrimaryEffect, m_SecondaryEffect; - short m_EffectLevel; - - virtual bool Item(cPlayer * a_Player) + Vector3d BeaconPosition(m_PosX, m_PosY, m_PosZ); + GetWorld()->ForEachPlayer([=](cPlayer & a_Player) { - Vector3d PlayerPosition = Vector3d(a_Player->GetPosition()); - if (PlayerPosition.y > m_Position.y) + auto PlayerPosition = a_Player.GetPosition(); + 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 - 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) { - a_Player->AddEntityEffect(m_SecondaryEffect, 180, 0); + a_Player.AddEntityEffect(m_SecondaryEffect, 180, 0); } } 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); + ); } diff --git a/src/BlockEntities/ChestEntity.cpp b/src/BlockEntities/ChestEntity.cpp index a8f5b7242..5e8b29a45 100644 --- a/src/BlockEntities/ChestEntity.cpp +++ b/src/BlockEntities/ChestEntity.cpp @@ -138,33 +138,18 @@ bool cChestEntity::UsedBy(cPlayer * a_Player) void cChestEntity::ScanNeighbours() { // Callback for finding neighbouring chest: - class cFindNeighbour : - public cChestCallback + auto FindNeighbour = [this](cChestEntity & a_Chest) { - public: - cChestEntity * m_Neighbour; - BLOCKTYPE m_ChestType; - - cFindNeighbour(BLOCKTYPE a_ChestType) : - m_Neighbour(nullptr), - m_ChestType(a_ChestType) + if (a_Chest.GetBlockType() != m_BlockType) { + // Neighboring block is not the same type of chest + return true; } - - virtual bool Item(cChestEntity * a_Chest) override - { - if (a_Chest->GetBlockType() != m_ChestType) - { - // Neighboring block is not the same type of chest - return true; - } - m_Neighbour = a_Chest; - return false; - } + m_Neighbour = &a_Chest; + return false; }; // Scan horizontally adjacent blocks for any neighbouring chest of the same type: - cFindNeighbour FindNeighbour(m_BlockType); if ( 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_Neighbour = FindNeighbour.m_Neighbour; m_Neighbour->m_Neighbour = this; // Force neighbour's window shut. Does Mojang server do this or should a double window open? m_Neighbour->DestroyWindow(); diff --git a/src/BlockEntities/HopperEntity.cpp b/src/BlockEntities/HopperEntity.cpp index 0467685af..2fac188b1 100644 --- a/src/BlockEntities/HopperEntity.cpp +++ b/src/BlockEntities/HopperEntity.cpp @@ -193,8 +193,7 @@ bool cHopperEntity::MovePickupsIn(cChunk & a_Chunk, Int64 a_CurrentTick) { UNUSED(a_CurrentTick); - class cHopperPickupSearchCallback : - public cEntityCallback + class cHopperPickupSearchCallback { public: 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; } - Vector3f EntityPos = a_Entity->GetPosition(); + Vector3f EntityPos = a_Entity.GetPosition(); Vector3f BlockPos(m_Pos.x + 0.5f, static_cast(m_Pos.y) + 1, m_Pos.z + 0.5f); // One block above hopper, and search from center outwards double Distance = (EntityPos - BlockPos).Length(); if (Distance < 0.5) { - if (TrySuckPickupIn(static_cast(a_Entity))) + if (TrySuckPickupIn(static_cast(a_Entity))) { return false; } @@ -228,9 +225,9 @@ bool cHopperEntity::MovePickupsIn(cChunk & a_Chunk, Int64 a_CurrentTick) 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++) { @@ -238,7 +235,7 @@ bool cHopperEntity::MovePickupsIn(cChunk & a_Chunk, Int64 a_CurrentTick) { m_bFoundPickupsAbove = true; m_Contents.SetSlot(i, Item); - a_Pickup->Destroy(); // Kill pickup + a_Pickup.Destroy(); // Kill pickup return true; } @@ -252,7 +249,7 @@ bool cHopperEntity::MovePickupsIn(cChunk & a_Chunk, Int64 a_CurrentTick) 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; } diff --git a/src/BlockEntities/MobSpawnerEntity.cpp b/src/BlockEntities/MobSpawnerEntity.cpp index 5246ae6ca..8a4cc4d38 100644 --- a/src/BlockEntities/MobSpawnerEntity.cpp +++ b/src/BlockEntities/MobSpawnerEntity.cpp @@ -1,4 +1,4 @@ - + #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "MobSpawnerEntity.h" @@ -138,47 +138,36 @@ void cMobSpawnerEntity::SpawnEntity(void) return; } - class cCallback : public cChunkCallback - { - 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 MobType = m_Entity; + bool EntitiesSpawned = m_World->DoWithChunk(GetChunkX(), GetChunkZ(), [&](cChunk & a_Chunk) { auto & Random = GetRandomProvider(); - bool EntitiesSpawned = false; + bool HaveSpawnedEntity = false; for (size_t i = 0; i < 4; i++) { - if (m_NearbyEntitiesNum >= 6) + if (NearbyEntities >= 6) { break; } int RelX = m_RelX + static_cast((Random.RandReal() - Random.RandReal()) * 4.0); - int RelY = m_RelY + Random.RandInt(-1, 1); + int RelY = m_PosY + Random.RandInt(-1, 1); int RelZ = m_RelZ + static_cast((Random.RandReal() - Random.RandReal()) * 4.0); - cChunk * Chunk = a_Chunk->GetRelNeighborChunkAdjustCoords(RelX, RelZ); + cChunk * Chunk = a_Chunk.GetRelNeighborChunkAdjustCoords(RelX, RelZ); if ((Chunk == nullptr) || !Chunk->IsValid()) { continue; } 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 PosZ = Chunk->GetPosZ() * cChunkDef::Width + RelZ; - auto Monster = cMonster::NewMonsterFromType(m_MobType); + auto Monster = cMonster::NewMonsterFromType(MobType); if (Monster == nullptr) { continue; @@ -188,7 +177,7 @@ void cMobSpawnerEntity::SpawnEntity(void) Monster->SetYaw(Random.RandReal(360.0f)); if (Chunk->GetWorld()->SpawnMobFinalize(std::move(Monster)) != cEntity::INVALID_ID) { - EntitiesSpawned = true; + HaveSpawnedEntity = true; Chunk->BroadcastSoundParticleEffect( EffectID::PARTICLE_MOBSPAWN, static_cast(PosX * 8.0), @@ -196,19 +185,15 @@ void cMobSpawnerEntity::SpawnEntity(void) static_cast(PosZ * 8.0), 0 ); - m_NearbyEntitiesNum++; + NearbyEntities++; } } } 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(); } diff --git a/src/Blocks/BlockBed.cpp b/src/Blocks/BlockBed.cpp index 77572a254..0032ec079 100644 --- a/src/Blocks/BlockBed.cpp +++ b/src/Blocks/BlockBed.cpp @@ -1,12 +1,12 @@ - + // BlockBed.cpp #include "Globals.h" #include "BlockBed.h" #include "BroadcastInterface.h" -#include "Entities/../World.h" #include "Entities/Player.h" +#include "../World.h" #include "../BoundingBox.h" #include "../Mobs/Monster.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(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) { if (a_WorldInterface.GetDimension() != dimOverworld) @@ -133,7 +73,14 @@ bool cBlockBedHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface } else { - cFindMobs FindMobs; + auto FindMobs = [](cEntity & a_Entity) + { + return ( + (a_Entity.GetEntityType() == cEntity::etMonster) && + (static_cast(a_Entity).GetMobFamily() == cMonster::mfHostile) + ); + }; + 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"); @@ -164,11 +111,24 @@ bool cBlockBedHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface a_Player.SetIsInBed(true); a_Player.SendMessageSuccess("Home position set successfully"); - cTimeFastForwardTester Tester; - if (a_WorldInterface.ForEachPlayer(Tester)) + auto TimeFastForwardTester = [](cPlayer & a_OtherPlayer) { - cPlayerBedStateUnsetter Unsetter(Vector3i(a_BlockX + PillowDirection.x, a_BlockY, a_BlockZ + PillowDirection.z), a_ChunkInterface); - a_WorldInterface.ForEachPlayer(Unsetter); + if (!a_OtherPlayer.IsInBed()) + { + 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_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) { - class cBedColor : - public cBedCallback - { - public: - short m_Color; - - cBedColor(short a_Color) : - m_Color(a_Color) + a_Player.GetWorld()->DoWithBedAt(a_BlockChange.GetX(), a_BlockChange.GetY(), a_BlockChange.GetZ(), [&](cBedEntity & a_Bed) { - } - - virtual bool Item(cBedEntity * a_Bed) override - { - a_Bed->SetColor(m_Color); + a_Bed.SetColor(a_Player.GetEquippedItem().m_ItemDamage); 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) { - class cBedColor : - public cBedCallback - { - public: - short m_Color = E_META_WOOL_RED; - - virtual bool Item(cBedEntity * a_Bed) override + short Color = E_META_WOOL_RED; + a_WorldInterface.DoWithBedAt(a_BlockX, a_BlockY, a_BlockZ, [&](cBedEntity & a_Bed) { - m_Color = a_Bed->GetColor(); + Color = a_Bed.GetColor(); return true; } - }; - cBedColor BedCallback; - a_WorldInterface.DoWithBedAt(a_BlockX, a_BlockY, a_BlockZ, BedCallback); - a_Pickups.Add(cItem(E_ITEM_BED, 1, BedCallback.m_Color)); + ); + a_Pickups.Add(cItem(E_ITEM_BED, 1, Color)); } diff --git a/src/Blocks/BlockMobHead.h b/src/Blocks/BlockMobHead.h index 30aba2491..764cd7f65 100644 --- a/src/Blocks/BlockMobHead.h +++ b/src/Blocks/BlockMobHead.h @@ -30,36 +30,32 @@ public: return; } - class cCallback : public cBlockEntityCallback - { - virtual bool Item(cBlockEntity * a_BlockEntity) + a_WorldInterface.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; } - cMobHeadEntity * MobHeadEntity = static_cast(a_BlockEntity); + auto & MobHeadEntity = static_cast(a_BlockEntity); cItems Pickups; - Pickups.Add(E_ITEM_HEAD, 1, static_cast(MobHeadEntity->GetType())); + Pickups.Add(E_ITEM_HEAD, 1, static_cast(MobHeadEntity.GetType())); auto & r1 = GetRandomProvider(); // Mid-block position first double MicroX, MicroY, MicroZ; - MicroX = MobHeadEntity->GetPosX() + 0.5; - MicroY = MobHeadEntity->GetPosY() + 0.5; - MicroZ = MobHeadEntity->GetPosZ() + 0.5; + MicroX = MobHeadEntity.GetPosX() + 0.5; + MicroY = MobHeadEntity.GetPosY() + 0.5; + MicroZ = MobHeadEntity.GetPosZ() + 0.5; // Add random offset second MicroX += r1.RandReal(-0.5, 0.5); MicroZ += r1.RandReal(-0.5, 0.5); - MobHeadEntity->GetWorld()->SpawnItemPickups(Pickups, MicroX, MicroY, MicroZ); + MobHeadEntity.GetWorld()->SpawnItemPickups(Pickups, MicroX, MicroY, MicroZ); return false; } - } Callback; - - a_WorldInterface.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ, Callback); + ); } virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override diff --git a/src/Blocks/WorldInterface.h b/src/Blocks/WorldInterface.h index 524e8d642..1619a8fce 100644 --- a/src/Blocks/WorldInterface.h +++ b/src/Blocks/WorldInterface.h @@ -1,15 +1,18 @@ - + #pragma once - +#include "FunctionRef.h" #include "../Mobs/MonsterTypes.h" - -typedef cItemCallback cBlockEntityCallback; +class cBedEntity; +class cBlockEntity; class cBroadcastInterface; class cItems; class cPlayer; +using cBedCallback = cFunctionRef; +using cBlockEntityCallback = cFunctionRef; +using cPlayerListCallback = cFunctionRef; @@ -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 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: */ 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. */ 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 */ 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 */ - virtual bool ForEachPlayer(cItemCallback & 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. 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. */ - 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; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 08bb2c270..8a6a5ec7b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -112,6 +112,7 @@ SET (HDRS FastRandom.h ForEachChunkProvider.h FurnaceRecipe.h + FunctionRef.h Globals.h IniFile.h Inventory.h diff --git a/src/Chunk.cpp b/src/Chunk.cpp index 3effcb690..8289d2a77 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -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 - for (auto itr = m_Entities.begin(), itr2 = itr; itr != m_Entities.end(); itr = itr2) + for (const auto & Entity : m_Entities) { - ++itr2; - if (!(*itr)->IsTicking()) - { - continue; - } - if (a_Callback.Item(itr->get())) + if (Entity->IsTicking() && a_Callback(*Entity)) { 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 - for (auto itr = m_Entities.begin(), itr2 = itr; itr != m_Entities.end(); itr = itr2) + for (const auto & Entity : m_Entities) { - ++itr2; - if (!(*itr)->IsTicking()) + if (!Entity->IsTicking()) { continue; } - cBoundingBox EntBox((*itr)->GetPosition(), (*itr)->GetWidth() / 2, (*itr)->GetHeight()); + cBoundingBox EntBox(Entity->GetPosition(), Entity->GetWidth() / 2, Entity->GetHeight()); if (!EntBox.DoesIntersect(a_Box)) { // The entity is not in the specified box continue; } - if (a_Callback.Item(itr->get())) + if (a_Callback(*Entity)) { 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) -{ - 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) +bool cChunk::DoWithEntityByID(UInt32 a_EntityID, cEntityCallback a_Callback, bool & a_CallbackResult) { // The entity list is locked by the parent chunkmap's CS for (const auto & Entity : m_Entities) { if ((Entity->GetUniqueID() == a_EntityID) && (Entity->IsTicking())) { - a_CallbackResult = a_Callback(Entity.get()); + a_CallbackResult = a_Callback(*Entity); return true; } } // for itr - m_Entitites[] @@ -2192,7 +2177,7 @@ bool cChunk::DoWithEntityByID(UInt32 a_EntityID, cLambdaEntityCallback a_Callbac template -bool cChunk::GenericForEachBlockEntity(cItemCallback& a_Callback) +bool cChunk::GenericForEachBlockEntity(cFunctionRef a_Callback) { // The blockentity list is locked by the parent chunkmap's CS for (auto & KeyPair : m_BlockEntities) @@ -2203,7 +2188,7 @@ bool cChunk::GenericForEachBlockEntity(cItemCallback& a_Callback) (IsOneOf(Block->GetBlockType())) ) { - if (a_Callback.Item(static_cast(Block))) + if (a_Callback(*static_cast(Block))) { return false; } @@ -2216,7 +2201,7 @@ bool cChunk::GenericForEachBlockEntity(cItemCallback& a_Callback) -bool cChunk::ForEachBlockEntity(cBlockEntityCallback & a_Callback) +bool cChunk::ForEachBlockEntity(cBlockEntityCallback a_Callback) { return GenericForEachBlockEntity(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 -bool cChunk::GenericDoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cItemCallback& a_Callback) +bool cChunk::GenericDoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFunctionRef a_Callback) { // The blockentity list is locked by the parent chunkmap's CS 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 !a_Callback.Item(static_cast(Block)); + return !a_Callback(*static_cast(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(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 cClientHandleList; -typedef cItemCallback cEntityCallback; -typedef cItemCallback cBeaconCallback; -typedef cItemCallback cBedCallback; -typedef cItemCallback cBrewingstandCallback; -typedef cItemCallback cChestCallback; -typedef cItemCallback cDispenserCallback; -typedef cItemCallback cFurnaceCallback; -typedef cItemCallback cNoteBlockCallback; -typedef cItemCallback cCommandBlockCallback; -typedef cItemCallback cMobHeadCallback; -typedef cItemCallback cFlowerPotCallback; +typedef std::list cClientHandleList; // A convenience macro for calling GetChunkAndRelByAbsolute. #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); /** 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. 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. */ - 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 + bool DoWithEntityByID(UInt32 a_EntityID, cEntityCallback a_Callback, bool & a_CallbackResult); // Lua-accessible /** 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 Accessible only from within Chunk.cpp */ template - bool GenericForEachBlockEntity(cItemCallback& a_Callback); + bool GenericForEachBlockEntity(cFunctionRef a_Callback); /** 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 */ - 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 */ - 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 */ - 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 */ - 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 */ - 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 */ - 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 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 */ template - bool GenericDoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cItemCallback& a_Callback); + bool GenericDoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFunctionRef 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 */ - 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 */ - 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 */ - 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 */ - 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 */ - 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 */ - 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 */ - 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 */ - 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 */ - 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 */ - 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 */ - 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 */ - 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 */ - 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 */ 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 diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 1bb4ff89c..8b98254c4 100644 --- a/src/ChunkMap.cpp +++ b/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); 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 a_Callback.Item(Chunk); + return a_Callback(*Chunk); } -bool cChunkMap::DoWithChunkAt(Vector3i a_BlockPos, std::function a_Callback) +bool cChunkMap::DoWithChunkAt(Vector3i a_BlockPos, cChunkCallback a_Callback) { int ChunkX, ChunkZ; cChunkDef::BlockToChunk(a_BlockPos.x, a_BlockPos.z, ChunkX, ChunkZ); - struct cCallBackWrapper : cChunkCallback - { - cCallBackWrapper(std::function a_InnerCallback) : - m_Callback(a_InnerCallback) - { - } - - virtual bool Item(cChunk * a_Chunk) - { - return m_Callback(*a_Chunk); - } - - private: - std::function m_Callback; - } callback(a_Callback); - return DoWithChunk(ChunkX, ChunkZ, callback); + return DoWithChunk(ChunkX, ChunkZ, a_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); 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); 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: 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); } - class cTNTDamageCallback : - public cEntityCallback - { - public: - cTNTDamageCallback(cBoundingBox & a_CBBBTNT, Vector3d a_CBExplosionPos, int a_CBExplosionSize) : - m_bbTNT(a_CBBBTNT), - m_ExplosionPos(a_CBExplosionPos), - m_ExplosionSize(a_CBExplosionSize) - { - } + Vector3d ExplosionPos{ a_BlockX, a_BlockY, a_BlockZ }; + cBoundingBox bbTNT(ExplosionPos, 0.5, 1); + bbTNT.Expand(ExplosionSizeInt * 2, ExplosionSizeInt * 2, ExplosionSizeInt * 2); - 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) 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; } // 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((1 / DistanceFromExplosion.Length()) * 6 * m_ExplosionSize), 0); + a_Entity.TakeDamage(dtExplosion, nullptr, static_cast((1 / DistanceFromExplosion.Length()) * 6 * ExplosionSizeInt), 0); } // Apply force to entities around the explosion - code modified from World.cpp DoExplosionAt() DistanceFromExplosion.Normalize(); - DistanceFromExplosion *= m_ExplosionSize * m_ExplosionSize; - a_Entity->AddSpeed(DistanceFromExplosion); + DistanceFromExplosion *= ExplosionSizeInt * ExplosionSizeInt; + a_Entity.AddSpeed(DistanceFromExplosion); 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): 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) -{ - return DoWithEntityByID(a_UniqueID, std::bind(&cEntityCallback::Item, &a_Callback, std::placeholders::_1)); -} - - - - - -bool cChunkMap::DoWithEntityByID(UInt32 a_UniqueID, cLambdaEntityCallback a_Callback) +bool cChunkMap::DoWithEntityByID(UInt32 a_UniqueID, cEntityCallback a_Callback) { cCSLock Lock(m_CSChunks); 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); 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); 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); 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); 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); 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); 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); 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 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 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 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 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 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 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 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 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 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 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 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 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 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 a_Callback) +bool cChunkMap::ForEachLoadedChunk(cFunctionRef a_Callback) { cCSLock Lock(m_CSChunks); for (const auto & Chunk : m_Chunks) diff --git a/src/ChunkMap.h b/src/ChunkMap.h index 66d1d4840..ea542fb45 100644 --- a/src/ChunkMap.h +++ b/src/ChunkMap.h @@ -10,6 +10,7 @@ #include "ChunkDataCallback.h" #include "EffectID.h" +#include "FunctionRef.h" @@ -38,25 +39,23 @@ class cSetChunkData; class cBoundingBox; class cDeadlockDetect; -typedef std::list cClientHandleList; -typedef cChunk * cChunkPtr; -typedef cItemCallback cEntityCallback; -typedef cItemCallback cBlockEntityCallback; -typedef cItemCallback cBeaconCallback; -typedef cItemCallback cBedCallback; -typedef cItemCallback cBrewingstandCallback; -typedef cItemCallback cChestCallback; -typedef cItemCallback cDispenserCallback; -typedef cItemCallback cDropperCallback; -typedef cItemCallback cDropSpenserCallback; -typedef cItemCallback cFlowerPotCallback; -typedef cItemCallback cFurnaceCallback; -typedef cItemCallback cNoteBlockCallback; -typedef cItemCallback cCommandBlockCallback; -typedef cItemCallback cMobHeadCallback; -typedef cItemCallback cChunkCallback; - -typedef std::function cLambdaEntityCallback; +typedef std::list cClientHandleList; +typedef cChunk * cChunkPtr; +using cEntityCallback = cFunctionRef; +using cBeaconCallback = cFunctionRef; +using cBedCallback = cFunctionRef; +using cBlockEntityCallback = cFunctionRef; +using cBrewingstandCallback = cFunctionRef; +using cChestCallback = cFunctionRef; +using cChunkCallback = cFunctionRef; +using cDispenserCallback = cFunctionRef; +using cDropperCallback = cFunctionRef; +using cDropSpenserCallback = cFunctionRef; +using cFurnaceCallback = cFunctionRef; +using cNoteBlockCallback = cFunctionRef; +using cCommandBlockCallback = cFunctionRef; +using cMobHeadCallback = cFunctionRef; +using cFlowerPotCallback = cFunctionRef; @@ -106,10 +105,10 @@ public: 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 */ - 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 */ - bool DoWithChunkAt(Vector3i a_BlockPos, std::function a_Callback); + bool DoWithChunkAt(Vector3i a_BlockPos, cChunkCallback a_Callback); /** Wakes up simulators for the specified block */ void WakeUpSimulators(Vector3i a_Block); @@ -230,102 +229,101 @@ public: 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 */ - 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 */ - 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. 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. */ - 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 */ 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. Returns true if entity found and callback returned false. */ - bool DoWithEntityByID(UInt32 a_EntityID, cEntityCallback & a_Callback); // Lua-accessible - bool DoWithEntityByID(UInt32 a_EntityID, cLambdaEntityCallback a_Callback); // Lambda version + bool DoWithEntityByID(UInt32 a_EntityID, cEntityCallback a_Callback); // Lua-accessible /** 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); // Lua-accessible + bool ForEachBlockEntityInChunk(int a_ChunkX, int a_ChunkZ, cBlockEntityCallback a_Callback); // Lua-accessible /** Calls the callback for 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); // 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. 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. 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. */ - 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. */ - 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. */ - 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. 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. */ - 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. 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 */ - 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. */ - 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. */ - 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. 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. 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. 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. */ - 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. 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. 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. 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. 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); /** Calls the callback for each loaded chunk. Returns true if all chunks have been processed successfully */ - bool ForEachLoadedChunk(std::function a_Callback); + bool ForEachLoadedChunk(cFunctionRef a_Callback); /** 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); diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index f42f52cb1..6a3e47d94 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1660,9 +1660,9 @@ void cClientHandle::HandleSlotSelected(Int16 a_SlotNum) 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; }); } @@ -1734,9 +1734,9 @@ void cClientHandle::HandleUseEntity(UInt32 a_TargetEntityID, bool a_IsLeftClick) // If the player is a spectator, let him spectate 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; @@ -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 (!a_IsLeftClick) { - class cRclkEntity : public cEntityCallback - { - cPlayer & m_Player; - virtual bool Item(cEntity * a_Entity) override + cWorld * World = m_Player->GetWorld(); + World->DoWithEntityByID(a_TargetEntityID, [=](cEntity & a_Entity) { 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(a_Entity)->GetPayload() != cMinecart::mpChest) && // And only if the type matches a minecart with a chest or - (reinterpret_cast(a_Entity)->GetPayload() != cMinecart::mpHopper) // a minecart with a hopper + (static_cast(a_Entity).GetPayload() != cMinecart::mpChest) && // And only if the type matches a minecart with a chest or + (static_cast(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; } - a_Entity->OnRightClicked(m_Player); + a_Entity.OnRightClicked(*m_Player); 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; } // If it is a left click, attack the entity: - class cDamageEntity : public cEntityCallback - { - public: - cPlayer * m_Me; - - cDamageEntity(cPlayer * a_Player) : - m_Me(a_Player) - { - } - - virtual bool Item(cEntity * a_Entity) override + m_Player->GetWorld()->DoWithEntityByID(a_TargetEntityID, [=](cEntity & a_Entity) { - if (!a_Entity->GetWorld()->IsPVPEnabled()) + if (!a_Entity.GetWorld()->IsPVPEnabled()) { // 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 return true; } } - a_Entity->TakeDamage(*m_Me); - m_Me->AddFoodExhaustion(0.3); - if (a_Entity->IsPawn()) + a_Entity.TakeDamage(*m_Player); + m_Player->AddFoodExhaustion(0.3); + if (a_Entity.IsPawn()) { - m_Me->NotifyNearbyWolves(static_cast(a_Entity), true); + m_Player->NotifyNearbyWolves(static_cast(&a_Entity), 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; } - class cCallback : - public cPlayerListCallback - { - virtual bool Item(cPlayer * a_Player) override - { - return true; - } - } Callback; - // 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"); return false; diff --git a/src/DeadlockDetect.cpp b/src/DeadlockDetect.cpp index df14e610b..411d452f6 100644 --- a/src/DeadlockDetect.cpp +++ b/src/DeadlockDetect.cpp @@ -56,25 +56,12 @@ bool cDeadlockDetect::Start(int a_IntervalSec) m_IntervalSec = a_IntervalSec; // Read the initial world data: - class cFillIn : - public cWorldListCallback - { - public: - cFillIn(cDeadlockDetect * a_Detect) : - m_Detect(a_Detect) - { - } - - virtual bool Item(cWorld * a_World) override + cRoot::Get()->ForEachWorld([=](cWorld & a_World) { - m_Detect->SetWorldAge(a_World->GetName(), a_World->GetWorldAge()); + SetWorldAge(a_World.GetName(), a_World.GetWorldAge()); return false; } - - protected: - cDeadlockDetect * m_Detect; - } FillIn(this); - cRoot::Get()->ForEachWorld(FillIn); + ); return super::Start(); } @@ -115,25 +102,12 @@ void cDeadlockDetect::Execute(void) while (!m_ShouldTerminate) { // Check the world ages: - class cChecker : - public cWorldListCallback - { - public: - cChecker(cDeadlockDetect * a_Detect) : - m_Detect(a_Detect) - { - } - - protected: - cDeadlockDetect * m_Detect; - - virtual bool Item(cWorld * a_World) override + cRoot::Get()->ForEachWorld([=](cWorld & a_World) { - m_Detect->CheckWorldAge(a_World->GetName(), a_World->GetWorldAge()); + CheckWorldAge(a_World.GetName(), a_World.GetWorldAge()); return false; } - } Checker(this); - cRoot::Get()->ForEachWorld(Checker); + ); std::this_thread::sleep_for(std::chrono::milliseconds(CYCLE_MILLISECONDS)); } // while (should run) diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index ba75f0443..a57449122 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -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) { - class cFindEntity : public cEntityCallback - { - public: - - cEntity * m_Entity; - eDamageType m_DamageType; - int m_RawDamage; - double m_KnockbackAmount; - - virtual bool Item(cEntity * a_Attacker) override + m_World->DoWithEntityByID(a_AttackerID, [=](cEntity & a_Attacker) { cPawn * Attacker; - if (a_Attacker->IsPawn()) + if (a_Attacker.IsPawn()) { - Attacker = static_cast(a_Attacker); + Attacker = static_cast(&a_Attacker); } else { Attacker = nullptr; } - - m_Entity->TakeDamage(m_DamageType, Attacker, m_RawDamage, m_KnockbackAmount); + TakeDamage(a_DamageType, Attacker, a_RawDamage, a_KnockbackAmount); 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 TotalEPF = 0.0; + int TotalEPF = 0; const cItem ArmorItems[] = { GetEquippedHelmet(), GetEquippedChestplate(), GetEquippedLeggings(), GetEquippedBoots() }; for (size_t i = 0; i < ARRAYCOUNT(ArmorItems); i++) diff --git a/src/Entities/Floater.cpp b/src/Entities/Floater.cpp index eeaa6cf3d..de5824068 100644 --- a/src/Entities/Floater.cpp +++ b/src/Entities/Floater.cpp @@ -13,8 +13,7 @@ //////////////////////////////////////////////////////////////////////////////// // cFloaterEntityCollisionCallback -class cFloaterEntityCollisionCallback : - public cEntityCallback +class cFloaterEntityCollisionCallback { public: cFloaterEntityCollisionCallback(cFloater * a_Floater, const Vector3d & a_Pos, const Vector3d & a_NextPos) : @@ -25,14 +24,14 @@ public: 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; } - 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; eBlockFace Face; @@ -47,7 +46,7 @@ public: { // The entity is closer than anything we've stored so far, replace it as the potential victim m_MinCoeff = LineCoeff; - m_HitEntity = a_Entity; + m_HitEntity = &a_Entity; } // 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) : cEntity(etFloater, a_X, a_Y, a_Z, 0.2, 0.2), 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; - m_World->DoWithEntityByID(m_PlayerID, EntityCallback); - if (!EntityCallback.DoesExist()) // The owner doesn't exist anymore. Destroy the floater entity. + if (!m_World->DoWithEntityByID(m_PlayerID, [](cEntity &) { return true; })) // The owner doesn't exist anymore. Destroy the floater entity. { Destroy(true); } if (m_AttachedMobID != cEntity::INVALID_ID) { - m_World->DoWithEntityByID(m_AttachedMobID, EntityCallback); // The mob the floater was attached to doesn't exist anymore. - if (!EntityCallback.DoesExist()) + if (!m_World->DoWithEntityByID(m_AttachedMobID, [](cEntity &) { return true; })) { + // The mob the floater was attached to doesn't exist anymore. m_AttachedMobID = cEntity::INVALID_ID; } } diff --git a/src/Entities/LeashKnot.cpp b/src/Entities/LeashKnot.cpp index a86dc9d53..51002531d 100644 --- a/src/Entities/LeashKnot.cpp +++ b/src/Entities/LeashKnot.cpp @@ -1,4 +1,4 @@ - + #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #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 - class LookForLeasheds : public cEntityCallback - { - 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 + // 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) { // 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; } - cMonster * PotentialLeashed = static_cast(a_Entity); + auto & PotentialLeashed = static_cast(a_Entity); // If can't be leashed skip it - if (!PotentialLeashed->CanBeLeashed()) + if (!PotentialLeashed.CanBeLeashed()) { return false; } // If it's not leashed to the player skip it if ( - !PotentialLeashed->IsLeashed() || - !PotentialLeashed->GetLeashedTo()->IsPlayer() || - (PotentialLeashed->GetLeashedTo()->GetUniqueID() != m_Player->GetUniqueID()) + !PotentialLeashed.IsLeashed() || + !PotentialLeashed.GetLeashedTo()->IsPlayer() || + (PotentialLeashed.GetLeashedTo()->GetUniqueID() != a_Player.GetUniqueID()) ) { return false; } // All conditions met, unleash from player and leash to fence - PotentialLeashed->Unleash(false, false); - PotentialLeashed->LeashTo(*m_Knot, m_ShouldBroadcast); + PotentialLeashed.Unleash(false, false); + PotentialLeashed.LeashTo(*this, a_ShouldBroadcast); 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) { - class LookForKnot : public cEntityCallback - { - public: - cLeashKnot * m_LeashKnot = nullptr; - - virtual bool Item(cEntity * a_Entity) override + cLeashKnot * LeashKnot = nullptr; + a_WorldInterface.ForEachEntityInBox(cBoundingBox(a_BlockPos, 0.5, 1), [&](cEntity & a_Entity) { - if (a_Entity->IsLeashKnot()) + if (a_Entity.IsLeashKnot()) { - m_LeashKnot = reinterpret_cast(a_Entity); + LeashKnot = static_cast(&a_Entity); return true; } return false; } + ); - } CallbackFindKnot; - - a_WorldInterface.ForEachEntityInBox(cBoundingBox(a_BlockPos, 0.5, 1), CallbackFindKnot); - - return CallbackFindKnot.m_LeashKnot; + return LeashKnot; } diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index 7f32dc910..8921f8894 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -20,8 +20,7 @@ -class cMinecartCollisionCallback : - public cEntityCallback +class cMinecartCollisionCallback { public: 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 ( ( - !a_Entity->IsPlayer() || - reinterpret_cast(a_Entity)->IsGameModeSpectator() // Spectators doesn't collide with anything + !a_Entity.IsPlayer() || + static_cast(a_Entity).IsGameModeSpectator() // Spectators doesn't collide with anything ) && - !a_Entity->IsMob() && - !a_Entity->IsMinecart() && - !a_Entity->IsBoat() + !a_Entity.IsMob() && + !a_Entity.IsMinecart() && + !a_Entity.IsBoat() ) { 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; } - 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); if (bbEntity.DoesIntersect(bbMinecart)) { - m_CollidedEntityPos = a_Entity->GetPosition(); + m_CollidedEntityPos = a_Entity.GetPosition(); m_DoesIntersect = true; return true; } diff --git a/src/Entities/Pawn.cpp b/src/Entities/Pawn.cpp index 233cdfa85..a116f97e3 100644 --- a/src/Entities/Pawn.cpp +++ b/src/Entities/Pawn.cpp @@ -1,4 +1,4 @@ - + #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "Pawn.h" @@ -80,49 +80,37 @@ void cPawn::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) Effect->OnTick(*this); } - class Pusher : public cEntityCallback + // Spectators cannot push entities around + if ((!IsPlayer()) || (!static_cast(this)->IsGameModeSpectator())) { - 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)) + 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; } - - // 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 - if ((!IsPlayer()) || (!reinterpret_cast(this)->IsGameModeSpectator())) - { - m_World->ForEachEntityInBox(cBoundingBox(GetPosition(), GetWidth(), GetHeight()), Callback); + ); } super::Tick(a_Dt, a_Chunk); diff --git a/src/Entities/Pickup.cpp b/src/Entities/Pickup.cpp index 0c6c8feab..fcae586f6 100644 --- a/src/Entities/Pickup.cpp +++ b/src/Entities/Pickup.cpp @@ -17,8 +17,7 @@ -class cPickupCombiningCallback : - public cEntityCallback +class cPickupCombiningCallback { public: 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()); - if (!a_Entity->IsPickup() || (a_Entity->GetUniqueID() <= m_Pickup->GetUniqueID()) || !a_Entity->IsOnGround()) + ASSERT(a_Entity.IsTicking()); + if (!a_Entity.IsPickup() || (a_Entity.GetUniqueID() <= m_Pickup->GetUniqueID()) || !a_Entity.IsOnGround()) { return false; } - Vector3d EntityPos = a_Entity->GetPosition(); + Vector3d EntityPos = a_Entity.GetPosition(); double Distance = (EntityPos - m_Position).Length(); - cPickup * OtherPickup = static_cast(a_Entity); - cItem & Item = OtherPickup->GetItem(); - if ((Distance < 1.2) && Item.IsEqual(m_Pickup->GetItem()) && OtherPickup->CanCombine()) + auto & OtherPickup = static_cast(a_Entity); + cItem & Item = OtherPickup.GetItem(); + if ((Distance < 1.2) && Item.IsEqual(m_Pickup->GetItem()) && OtherPickup.CanCombine()) { short CombineCount = Item.m_ItemCount; 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 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); - a_Entity->GetWorld()->BroadcastEntityRelMove(*a_Entity, static_cast(DiffX), static_cast(DiffY), static_cast(DiffZ)); + a_Entity.GetWorld()->BroadcastEntityRelMove(a_Entity, static_cast(DiffX), static_cast(DiffY), static_cast(DiffZ)); /* End of experimental animation */ - a_Entity->Destroy(); + a_Entity.Destroy(); // Reset the timer m_Pickup->SetAge(0); } else { - a_Entity->GetWorld()->BroadcastEntityMetadata(*a_Entity); + a_Entity.GetWorld()->BroadcastEntityMetadata(a_Entity); } m_FoundMatchingPickup = true; } diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 8d35d0bf5..8ce577b8f 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1005,36 +1005,21 @@ bool cPlayer::DoTakeDamage(TakeDamageInfo & a_TDI) void cPlayer::NotifyNearbyWolves(cPawn * a_Opponent, bool a_IsPlayerInvolved) { 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_Player(a_Me), - m_Attacker(a_MyAttacker), - m_IsPlayerInvolved(a_PlayerInvolved) - { - } - virtual bool Item(cEntity * a_Entity) override + m_World->ForEachEntityInBox(cBoundingBox(GetPosition(), 16), [&] (cEntity & a_Entity) { - if (a_Entity->IsMob()) + if (a_Entity.IsMob()) { - cMonster * Mob = static_cast(a_Entity); - if (Mob->GetMobType() == mtWolf) + auto & Mob = static_cast(a_Entity); + if (Mob.GetMobType() == mtWolf) { - cWolf * Wolf = static_cast(Mob); - Wolf->ReceiveNearbyFightInfo(m_Player->GetUUID(), m_Attacker, m_IsPlayerInvolved); + auto & Wolf = static_cast(Mob); + Wolf.ReceiveNearbyFightInfo(GetUUID(), a_Opponent, a_IsPlayerInvolved); } } return false; } - } Callback(this, a_Opponent, a_IsPlayerInvolved); - - m_World->ForEachEntityInBox(cBoundingBox(GetPosition(), 16), Callback); + ); } @@ -2415,17 +2400,12 @@ void cPlayer::HandleFloater() { return; } - class cFloaterCallback : - public cEntityCallback - { - public: - virtual bool Item(cEntity * a_Entity) override + m_World->DoWithEntityByID(m_FloaterID, [](cEntity & a_Entity) { - a_Entity->Destroy(true); + a_Entity.Destroy(true); return true; } - } Callback; - m_World->DoWithEntityByID(m_FloaterID, Callback); + ); SetIsFishing(false); } @@ -2669,29 +2649,18 @@ bool cPlayer::DoesPlacingBlocksIntersectEntity(const sSetBlockVector & a_Blocks) cWorld * World = GetWorld(); // Check to see if any entity intersects any block being placed - class DoesIntersectBlock : public cEntityCallback - { - public: - const std::vector & m_BoundingBoxes; - - // The distance inside the block the entity can still be. - const double EPSILON = 0.0005; - - DoesIntersectBlock(const std::vector & a_BoundingBoxes) : - m_BoundingBoxes(a_BoundingBoxes) + return !World->ForEachEntityInBox(PlacingBounds, [&](cEntity & a_Entity) { - } + // 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; } - cBoundingBox EntBox(a_Entity->GetPosition(), a_Entity->GetWidth() / 2, a_Entity->GetHeight()); - for (auto BlockBox: m_BoundingBoxes) + cBoundingBox EntBox(a_Entity.GetPosition(), a_Entity.GetWidth() / 2, a_Entity.GetHeight()); + for (auto BlockBox : PlacementBoxes) { - // Put in a little bit of wiggle room BlockBox.Expand(-EPSILON, -EPSILON, -EPSILON); if (EntBox.DoesIntersect(BlockBox)) @@ -2701,15 +2670,7 @@ bool cPlayer::DoesPlacingBlocksIntersectEntity(const sSetBlockVector & a_Blocks) } return false; } - } Callback(PlacementBoxes); - - // See if any entities in that bounding box collide with anyone - if (!World->ForEachEntityInBox(PlacingBounds, Callback)) - { - return true; - } - - return false; + ); } diff --git a/src/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp index 1017f954a..0649e5b95 100644 --- a/src/Entities/ProjectileEntity.cpp +++ b/src/Entities/ProjectileEntity.cpp @@ -126,8 +126,7 @@ protected: //////////////////////////////////////////////////////////////////////////////// // cProjectileEntityCollisionCallback: -class cProjectileEntityCollisionCallback : - public cEntityCallback +class cProjectileEntityCollisionCallback { public: 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 ( - (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 == m_Projectile) || // Do not check collisions with self + (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 @@ -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. // The results should be good enough for our purposes @@ -168,20 +167,20 @@ public: } if ( - !a_Entity->IsMob() && - !a_Entity->IsMinecart() && + !a_Entity.IsMob() && + !a_Entity.IsMinecart() && ( - !a_Entity->IsPlayer() || - static_cast(a_Entity)->IsGameModeSpectator() + !a_Entity.IsPlayer() || + static_cast(a_Entity).IsGameModeSpectator() ) && - !a_Entity->IsBoat() + !a_Entity.IsBoat() ) { // Not an entity that interacts with a projectile return false; } - if (cPluginManager::Get()->CallHookProjectileHitEntity(*m_Projectile, *a_Entity)) + if (cPluginManager::Get()->CallHookProjectileHitEntity(*m_Projectile, a_Entity)) { // A plugin disagreed. return false; @@ -191,7 +190,7 @@ public: { // The entity is closer than anything we've stored so far, replace it as the potential victim m_MinCoeff = LineCoeff; - m_HitEntity = a_Entity; + m_HitEntity = &a_Entity; } // 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 (a_EntityHit.IsPawn() && (GetCreatorName() != "")) { - class cNotifyWolves : public cEntityCallback - { - public: - cPawn * m_EntityHit; - - virtual bool Item(cEntity * a_Hitter) override + auto EntityHit = static_cast(&a_EntityHit); + m_World->DoWithEntityByID(GetCreatorUniqueID(), [=](cEntity & a_Hitter) { - static_cast(a_Hitter)->NotifyNearbyWolves(m_EntityHit, true); + static_cast(a_Hitter).NotifyNearbyWolves(EntityHit, true); return true; } - } Callback; - - Callback.m_EntityHit = static_cast(&a_EntityHit); - m_World->DoWithEntityByID(GetCreatorUniqueID(), Callback); + ); } } diff --git a/src/Entities/SplashPotionEntity.cpp b/src/Entities/SplashPotionEntity.cpp index 8356806b3..15be9706e 100644 --- a/src/Entities/SplashPotionEntity.cpp +++ b/src/Entities/SplashPotionEntity.cpp @@ -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(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: @@ -119,8 +65,30 @@ void cSplashPotionEntity::OnHitEntity(cEntity & a_EntityHit, Vector3d a_HitPos) void cSplashPotionEntity::Splash(Vector3d a_HitPos) { - cSplashPotionCallback Callback(a_HitPos, m_EntityEffectType, m_EntityEffect); - m_World->ForEachEntity(Callback); + m_World->ForEachEntity([=](cEntity & a_Entity) + { + 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(a_Entity).AddEntityEffect(m_EntityEffectType, m_EntityEffect.GetDuration(), m_EntityEffect.GetIntensity(), Reduction); + return false; + } + ); m_World->BroadcastSoundParticleEffect( EffectID::PARTICLE_SPLASH_POTION, diff --git a/src/Entities/ThrownEnderPearlEntity.cpp b/src/Entities/ThrownEnderPearlEntity.cpp index 4dedffc5b..ca362d3bd 100644 --- a/src/Entities/ThrownEnderPearlEntity.cpp +++ b/src/Entities/ThrownEnderPearlEntity.cpp @@ -74,29 +74,12 @@ void cThrownEnderPearlEntity::TeleportCreator(Vector3d a_HitPos) return; } - class cProjectileCreatorCallbackForPlayers : public cPlayerListCallback - { - public: - cProjectileCreatorCallbackForPlayers(cEntity * a_Attacker, Vector3i a_CallbackHitPos) : - m_Attacker(a_Attacker), - m_HitPos(a_CallbackHitPos) - { - } - - virtual bool Item(cPlayer * a_Entity) override + GetWorld()->FindAndDoWithPlayer(m_CreatorData.m_Name, [=](cPlayer & a_Entity) { // 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->TakeDamage(dtEnderPearl, m_Attacker, 5, 0); + a_Entity.TeleportToCoords(a_HitPos.x, a_HitPos.y + 0.2, a_HitPos.z); + a_Entity.TakeDamage(dtEnderPearl, this, 5, 0); return true; } - - private: - - cEntity * m_Attacker; - Vector3i m_HitPos; - }; - - cProjectileCreatorCallbackForPlayers PCCFP(this, a_HitPos); - GetWorld()->FindAndDoWithPlayer(m_CreatorData.m_Name, PCCFP); + ); } diff --git a/src/FunctionRef.h b/src/FunctionRef.h new file mode 100644 index 000000000..8215fd0db --- /dev/null +++ b/src/FunctionRef.h @@ -0,0 +1,58 @@ + +#pragma once + +// Declared only so it can be partially specialized +template +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 cFunctionRef +{ +public: + /** Construct from a function object. */ + template + 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; + } + + /** Call the referenced function object */ + Ret operator () (Args... a_Args) + { + return m_CallFunction(m_CallableData, std::forward(a_Args)...); + } + +private: + + /** Function that performs the call. */ + template + static Ret ObjectFunctionCaller(void * a_Callable, Args... a_Args) + { + // Convert opaque reference to the concrete type. + using ObjectPtr = typename std::add_pointer::type; + auto & Object = *static_cast(a_Callable); + + // Forward the call down to the object. + return Object(std::forward(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; +}; + + diff --git a/src/Globals.h b/src/Globals.h index 0c48d2ad9..78c0539fb 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -416,20 +416,6 @@ template class SizeChecker; - -/** A generic interface used mainly in ForEach() functions */ -template 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. */ template T Clamp(T a_Value, T a_Min, T a_Max) diff --git a/src/Items/ItemFishingRod.h b/src/Items/ItemFishingRod.h index 012f13a6c..0720cb3e1 100644 --- a/src/Items/ItemFishingRod.h +++ b/src/Items/ItemFishingRod.h @@ -20,8 +20,7 @@ //////////////////////////////////////////////////////////////////////////////// // cFloaterCallback -class cFloaterCallback : - public cEntityCallback +class cFloaterCallback { public: cFloaterCallback(void) : @@ -30,13 +29,14 @@ public: { } - virtual bool Item(cEntity * a_Entity) override + bool operator () (cEntity & a_Entity) { - m_CanPickup = reinterpret_cast(a_Entity)->CanPickup(); - m_Pos = Vector3d(a_Entity->GetPosX(), a_Entity->GetPosY(), a_Entity->GetPosZ()); - m_BitePos = reinterpret_cast(a_Entity)->GetBitePos(); - m_AttachedMobID = reinterpret_cast(a_Entity)->GetAttachedMobID(); - a_Entity->Destroy(true); + auto & Floater = static_cast(a_Entity); + m_CanPickup = Floater.CanPickup(); + m_Pos = Floater.GetPosition(); + m_BitePos = Floater.GetBitePos(); + m_AttachedMobID = Floater.GetAttachedMobID(); + Floater.Destroy(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 : public cItemHandler { @@ -117,8 +90,13 @@ public: if (FloaterInfo.IsAttached()) { - cSweepEntityCallback SweepEntity(a_Player->GetPosition()); - a_World->DoWithEntityByID(FloaterInfo.GetAttachedMobID(), SweepEntity); + a_World->DoWithEntityByID(FloaterInfo.GetAttachedMobID(), [=](cEntity & a_Entity) + { + Vector3d Speed = a_Player->GetPosition() - a_Entity.GetPosition(); + a_Entity.AddSpeed(Speed); + return true; + } + ); } else if (FloaterInfo.CanPickup()) { diff --git a/src/Items/ItemMobHead.h b/src/Items/ItemMobHead.h index fdecabbbf..5cbcf52f7 100644 --- a/src/Items/ItemMobHead.h +++ b/src/Items/ItemMobHead.h @@ -62,42 +62,30 @@ public: 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: - class cCallback : public cBlockEntityCallback - { - cPlayer & m_Player; - eMobHeadType m_HeadType; - NIBBLETYPE m_BlockMeta; + auto HeadType = static_cast(a_EquippedItem.m_ItemDamage); + auto BlockMeta = static_cast(a_BlockFace); - 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; } - auto MobHeadEntity = static_cast(a_BlockEntity); + auto & MobHeadEntity = static_cast(a_BlockEntity); 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->SetRotation(static_cast(Rotation)); - MobHeadEntity->GetWorld()->BroadcastBlockEntity(MobHeadEntity->GetPosX(), MobHeadEntity->GetPosY(), MobHeadEntity->GetPosZ()); + MobHeadEntity.SetType(HeadType); + MobHeadEntity.SetRotation(static_cast(Rotation)); + MobHeadEntity.GetWorld()->BroadcastBlockEntity(MobHeadEntity.GetPosX(), MobHeadEntity.GetPosY(), MobHeadEntity.GetPosZ()); 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(a_EquippedItem.m_ItemDamage), static_cast(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 (BlockType == E_BLOCK_HEAD) { - class cHeadCallback: public cBlockEntityCallback - { - virtual bool Item(cBlockEntity * a_Entity) override + bool IsWitherHead = false; + a_World.DoWithBlockEntityAt(BlockX, BlockY, BlockZ, [&](cBlockEntity & a_Entity) { - ASSERT(a_Entity->GetBlockType() == E_BLOCK_HEAD); - cMobHeadEntity * MobHead = static_cast(a_Entity); - m_IsWitherHead = (MobHead->GetType() == SKULL_TYPE_WITHER); + ASSERT(a_Entity.GetBlockType() == E_BLOCK_HEAD); + auto & MobHead = static_cast(a_Entity); + IsWitherHead = (MobHead.GetType() == SKULL_TYPE_WITHER); return true; } - public: - cHeadCallback(void): - m_IsWitherHead(false) - { - } - bool m_IsWitherHead; - } callback; - a_World.DoWithBlockEntityAt(BlockX, BlockY, BlockZ, callback); - if (!callback.m_IsWitherHead) + ); + if (!IsWitherHead) { return false; } @@ -287,25 +267,18 @@ public: /** 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) { - class cPlayerCallback : public cPlayerListCallback - { - Vector3f m_Pos; - - virtual bool Item(cPlayer * a_Player) + Vector3f Pos{ static_cast(a_BlockX), static_cast(a_BlockY), static_cast(a_BlockZ) }; + a_World.ForEachPlayer([=](cPlayer & a_Player) { // 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) { - a_Player->AwardAchievement(achSpawnWither); + a_Player.AwardAchievement(achSpawnWither); } return false; } - - public: - cPlayerCallback(const Vector3f & a_Pos) : m_Pos(a_Pos) {} - } PlayerCallback(Vector3f(static_cast(a_BlockX), static_cast(a_BlockY), static_cast(a_BlockZ))); - a_World.ForEachPlayer(PlayerCallback); + ); } diff --git a/src/LineBlockTracer.cpp b/src/LineBlockTracer.cpp index 471d9e13b..e194ae653 100644 --- a/src/LineBlockTracer.cpp +++ b/src/LineBlockTracer.cpp @@ -199,12 +199,12 @@ bool cLineBlockTracer::Trace(double a_StartX, double a_StartY, double a_StartZ, m_DiffY = m_EndY - m_StartY; 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 BlockZ = FloorC(m_StartZ); int 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() diff --git a/src/LineBlockTracer.h b/src/LineBlockTracer.h index 2851cfbd7..2204e3671 100644 --- a/src/LineBlockTracer.h +++ b/src/LineBlockTracer.h @@ -18,17 +18,12 @@ // fwd: Chunk.h class cChunk; -// fwd: cChunkMap.h -typedef cItemCallback cChunkCallback; - - class cLineBlockTracer : - public cBlockTracer, - public cChunkCallback + public cBlockTracer { 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) */ bool MoveToNextBlock(void); - // cChunkCallback overrides: - virtual bool Item(cChunk * a_Chunk) override; + bool ChunkCallback(cChunk * a_Chunk); } ; diff --git a/src/Map.cpp b/src/Map.cpp index 2fe901d8e..87cc9bfdf 100644 --- a/src/Map.cpp +++ b/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 RelZ = BlockZ - (ChunkZ * cChunkDef::Width); - class cCalculatePixelCb : - public cChunkCallback - { - cMap * m_Map; - - int m_RelX, m_RelZ; - - 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) {} + ASSERT(m_World != nullptr); - virtual bool Item(cChunk * a_Chunk) override + ColorID PixelData; + m_World->DoWithChunk(ChunkX, ChunkZ, [&](cChunk & a_Chunk) { - if (!a_Chunk->IsValid()) + if (!a_Chunk.IsValid()) { return false; } - if (m_Map->GetDimension() == dimNether) + if (GetDimension() == dimNether) { // TODO 2014-02-22 xdot: Nether maps @@ -151,22 +141,22 @@ bool cMap::UpdatePixel(unsigned int a_X, unsigned int a_Z) BLOCKTYPE TargetBlock; NIBBLETYPE TargetMeta; - auto Height = a_Chunk->GetHeight(m_RelX, m_RelZ); + auto Height = a_Chunk.GetHeight(RelX, RelZ); 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); if (IsBlockWater(TargetBlock)) { 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; } } 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; } @@ -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 const int BrightnessIDSize = static_cast(BrightnessID.size()); - m_PixelData = ColourID * 4 + BrightnessID[static_cast(Clamp((BrightnessIDSize * Height) / ChunkHeight, 0, BrightnessIDSize - 1))]; + PixelData = ColourID * 4 + BrightnessID[static_cast(Clamp((BrightnessIDSize * Height) / ChunkHeight, 0, BrightnessIDSize - 1))]; return false; } + ); - ColorID GetPixelData(void) const - { - return m_PixelData; - } - } CalculatePixelCb(this, RelX, RelZ); - - ASSERT(m_World != nullptr); - m_World->DoWithChunk(ChunkX, ChunkZ, CalculatePixelCb); - - SetPixel(a_X, a_Z, CalculatePixelCb.GetPixelData()); + SetPixel(a_X, a_Z, PixelData); return true; } diff --git a/src/MapManager.cpp b/src/MapManager.cpp index 4408af76b..ae020d800 100644 --- a/src/MapManager.cpp +++ b/src/MapManager.cpp @@ -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); cMap * Map = GetMapData(a_ID); @@ -33,7 +33,7 @@ bool cMapManager::DoWithMap(UInt32 a_ID, cMapCallback & a_Callback) } else { - a_Callback.Item(Map); + a_Callback(*Map); return true; } } diff --git a/src/MapManager.h b/src/MapManager.h index 6730e515e..8959b1d8b 100644 --- a/src/MapManager.h +++ b/src/MapManager.h @@ -11,12 +11,13 @@ +#include "FunctionRef.h" #include "Map.h" -typedef cItemCallback cMapCallback; +using cMapCallback = cFunctionRef; @@ -41,7 +42,7 @@ public: /** 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. 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 */ void TickMaps(void); diff --git a/src/MobSpawner.cpp b/src/MobSpawner.cpp index 1e0db5175..eb5684202 100644 --- a/src/MobSpawner.cpp +++ b/src/MobSpawner.cpp @@ -369,7 +369,7 @@ cMonster * cMobSpawner::TryToSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, auto NewMobPtr = newMob.get(); if (newMob) { - m_Spawned.insert(std::move(newMob)); + m_Spawned.push_back(std::move(newMob)); } return NewMobPtr; } @@ -390,15 +390,6 @@ void cMobSpawner::NewPack() -cMobSpawner::tSpawnedContainer & cMobSpawner::getSpawned(void) -{ - return m_Spawned; -} - - - - - bool cMobSpawner::CanSpawnAnything(void) { return !m_AllowedTypes.empty(); diff --git a/src/MobSpawner.h b/src/MobSpawner.h index 14c721ae3..c396637d5 100644 --- a/src/MobSpawner.h +++ b/src/MobSpawner.h @@ -37,8 +37,10 @@ public : // return true if there is at least one allowed type bool CanSpawnAnything(void); - typedef const std::set> tSpawnedContainer; - tSpawnedContainer & getSpawned(void); + std::vector> & getSpawned(void) + { + return m_Spawned; + } /** 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); @@ -55,7 +57,7 @@ protected : std::set m_AllowedTypes; bool m_NewPack; eMonsterType m_MobType; - std::set> m_Spawned; + std::vector> m_Spawned; } ; diff --git a/src/Mobs/Creeper.cpp b/src/Mobs/Creeper.cpp index 84b68cf7c..adab8c5aa 100644 --- a/src/Mobs/Creeper.cpp +++ b/src/Mobs/Creeper.cpp @@ -81,21 +81,16 @@ void cCreeper::GetDrops(cItems & a_Drops, cEntity * a_Killer) a_Killer->IsProjectile() && ((reinterpret_cast(a_Killer))->GetCreatorUniqueID() != cEntity::INVALID_ID)) { - class cProjectileCreatorCallback : public cEntityCallback - { - public: - cProjectileCreatorCallback(void) {} - - virtual bool Item(cEntity * a_Entity) override + auto ProjectileCreatorCallback = [](cEntity & a_Entity) { - if (a_Entity->IsMob() && ((reinterpret_cast(a_Entity))->GetMobType() == mtSkeleton)) + if (a_Entity.IsMob() && ((static_cast(a_Entity)).GetMobType() == mtSkeleton)) { return true; } return false; - } - } PCC; - if (GetWorld()->DoWithEntityByID((reinterpret_cast(a_Killer))->GetCreatorUniqueID(), PCC)) + }; + + if (GetWorld()->DoWithEntityByID(static_cast(a_Killer)->GetCreatorUniqueID(), ProjectileCreatorCallback)) { AddRandomDropItem(a_Drops, 1, 1, static_cast(m_World->GetTickRandomNumber(11) + E_ITEM_FIRST_DISC)); } diff --git a/src/Mobs/Enderman.cpp b/src/Mobs/Enderman.cpp index 5cfe0d4cd..000496df0 100644 --- a/src/Mobs/Enderman.cpp +++ b/src/Mobs/Enderman.cpp @@ -10,8 +10,7 @@ //////////////////////////////////////////////////////////////////////////////// // cPlayerLookCheck -class cPlayerLookCheck : - public cPlayerListCallback +class cPlayerLookCheck { public: 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 - if (!a_Player->CanMobsTarget()) + if (!a_Player.CanMobsTarget()) { return false; } // 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) { return false; } // 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; } // 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); 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 - 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 return false; } - m_Player = a_Player; + m_Player = &a_Player; return true; } diff --git a/src/Mobs/Ocelot.cpp b/src/Mobs/Ocelot.cpp index e5004a1d1..50dd249c0 100644 --- a/src/Mobs/Ocelot.cpp +++ b/src/Mobs/Ocelot.cpp @@ -90,30 +90,25 @@ void cOcelot::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) void cOcelot::TickFollowPlayer() { - class cCallback : - public cPlayerListCallback + Vector3d OwnerPos; + bool OwnerFlying = false; + auto Callback = [&](cPlayer & a_Player) { - virtual bool Item(cPlayer * a_Player) override - { - OwnerPos = a_Player->GetPosition(); - OwnerFlying = a_Player->IsFlying(); - return true; - } - public: - Vector3d OwnerPos; - bool OwnerFlying; - } Callback; + OwnerPos = a_Player.GetPosition(); + OwnerFlying = a_Player.IsFlying(); + return true; + }; if (m_World->DoWithPlayerByUUID(m_OwnerUUID, Callback)) { // The player is present in the world, follow him: - double Distance = (Callback.OwnerPos - GetPosition()).Length(); + double Distance = (OwnerPos - GetPosition()).Length(); if (Distance > 12) { - if (!Callback.OwnerFlying) + if (!OwnerFlying) { - Callback.OwnerPos.y = FindFirstNonAirBlockPosition(Callback.OwnerPos.x, Callback.OwnerPos.z); - TeleportToCoords(Callback.OwnerPos.x, Callback.OwnerPos.y, Callback.OwnerPos.z); + OwnerPos.y = FindFirstNonAirBlockPosition(OwnerPos.x, OwnerPos.z); + TeleportToCoords(OwnerPos.x, OwnerPos.y, OwnerPos.z); } } if (Distance < 2) @@ -122,9 +117,9 @@ void cOcelot::TickFollowPlayer() } 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(a_Entity)->GetMobType() == eMonsterType::mtOcelot) && - (static_cast(a_Entity)->IsSitting()) - ); - } -}; - - - - - bool cOcelot::IsCatSittingOnBlock(cWorld * a_World, Vector3d a_BlockPosition) { - cFindSittingCat FindSittingCat; - return a_World->ForEachEntityInBox(cBoundingBox(Vector3d(a_BlockPosition.x, a_BlockPosition.y + 1, a_BlockPosition.z), 1), FindSittingCat); + return a_World->ForEachEntityInBox( + cBoundingBox(Vector3d(a_BlockPosition.x, a_BlockPosition.y + 1, a_BlockPosition.z), 1), + [=](cEntity & a_Entity) + { + return ( + (a_Entity.GetEntityType() == cEntity::etMonster) && + (static_cast(a_Entity).GetMobType() == eMonsterType::mtOcelot) && + (static_cast(a_Entity).IsSitting()) + ); + } + ); } diff --git a/src/Mobs/PassiveMonster.cpp b/src/Mobs/PassiveMonster.cpp index a2089e13f..c9345662d 100644 --- a/src/Mobs/PassiveMonster.cpp +++ b/src/Mobs/PassiveMonster.cpp @@ -109,23 +109,18 @@ void cPassiveMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) Vector3f Pos = (GetPosition() + m_LovePartner->GetPosition()) * 0.5; UInt32 BabyID = m_World->SpawnMob(Pos.x, Pos.y, Pos.z, GetMobType(), true); - class cBabyInheritCallback : - public cEntityCallback - { - public: - cPassiveMonster * Baby; - cBabyInheritCallback() : Baby(nullptr) { } - virtual bool Item(cEntity * a_Entity) override + cPassiveMonster * Baby = nullptr; + + m_World->DoWithEntityByID(BabyID, [&](cEntity & a_Entity) { - Baby = static_cast(a_Entity); + Baby = static_cast(&a_Entity); return true; } - } Callback; + ); - m_World->DoWithEntityByID(BabyID, Callback); - if (Callback.Baby != nullptr) + if (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)); @@ -159,49 +154,37 @@ void cPassiveMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) { if (m_LovePartner == nullptr) { - class LookForLover : public cEntityCallback - { - public: - cEntity * m_Me; - - LookForLover(cEntity * a_Me) : - m_Me(a_Me) - { - } - - virtual bool Item(cEntity * a_Entity) override + m_World->ForEachEntityInBox(cBoundingBox(GetPosition(), 8, 8), [=](cEntity & a_Entity) { // If the entity is not a monster, don't breed with it // Also, do not self-breed - if ((a_Entity->GetEntityType() != etMonster) || (a_Entity == m_Me)) + if ((a_Entity.GetEntityType() != etMonster) || (&a_Entity == this)) { return false; } - cPassiveMonster * Me = static_cast(m_Me); - cPassiveMonster * PotentialPartner = static_cast(a_Entity); + auto & Me = static_cast(*this); + auto & PotentialPartner = static_cast(a_Entity); // 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; } // If the potential partner is not in love // 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; } // All conditions met, let's breed! - PotentialPartner->EngageLoveMode(Me); - Me->EngageLoveMode(PotentialPartner); + PotentialPartner.EngageLoveMode(&Me); + Me.EngageLoveMode(&PotentialPartner); return true; } - } Callback(this); - - m_World->ForEachEntityInBox(cBoundingBox(GetPosition(), 8, 8, -4), Callback); + ); } m_LoveTimer--; diff --git a/src/Mobs/Wither.cpp b/src/Mobs/Wither.cpp index dd85d7d2b..2cf564fca 100644 --- a/src/Mobs/Wither.cpp +++ b/src/Mobs/Wither.cpp @@ -101,28 +101,19 @@ void cWither::KilledBy(TakeDamageInfo & a_TDI) { super::KilledBy(a_TDI); - class cPlayerCallback : public cPlayerListCallback - { - Vector3f m_Pos; - - virtual bool Item(cPlayer * a_Player) + Vector3d Pos = GetPosition(); + m_World->ForEachPlayer([=](cPlayer & a_Player) { // 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 player is close, award achievement - a_Player->AwardAchievement(achKillWither); + a_Player.AwardAchievement(achKillWither); } return false; } - - public: - cPlayerCallback(const Vector3f & a_Pos) : m_Pos(a_Pos) {} - - } PlayerCallback(GetPosition()); - - m_World->ForEachPlayer(PlayerCallback); + ); } diff --git a/src/Mobs/Wolf.cpp b/src/Mobs/Wolf.cpp index f3b859c76..45df3dd05 100644 --- a/src/Mobs/Wolf.cpp +++ b/src/Mobs/Wolf.cpp @@ -80,19 +80,13 @@ void cWolf::NotifyAlliesOfFight(cPawn * a_Opponent) return; } m_NotificationCooldown = 15; - class cCallback : public cPlayerListCallback - { - virtual bool Item(cPlayer * a_Player) override + + m_World->DoWithPlayerByUUID(m_OwnerUUID, [=](cPlayer & a_Player) { - a_Player->NotifyNearbyWolves(m_Opponent, false); + a_Player.NotifyNearbyWolves(a_Opponent, 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) @@ -347,30 +341,25 @@ void cWolf::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) void cWolf::TickFollowPlayer() { - class cCallback : - public cPlayerListCallback + Vector3d OwnerPos; + bool OwnerFlying; + auto Callback = [&](cPlayer & a_Player) { - virtual bool Item(cPlayer * a_Player) override - { - OwnerPos = a_Player->GetPosition(); - OwnerFlying = a_Player->IsFlying(); - return true; - } - public: - Vector3d OwnerPos; - bool OwnerFlying; - } Callback; + OwnerPos = a_Player.GetPosition(); + OwnerFlying = a_Player.IsFlying(); + return true; + }; if (m_World->DoWithPlayerByUUID(m_OwnerUUID, Callback)) { // The player is present in the world, follow him: - double Distance = (Callback.OwnerPos - GetPosition()).Length(); + double Distance = (OwnerPos - GetPosition()).Length(); if (Distance > 20) { - if (!Callback.OwnerFlying) + if (!OwnerFlying) { - Callback.OwnerPos.y = FindFirstNonAirBlockPosition(Callback.OwnerPos.x, Callback.OwnerPos.z); - TeleportToCoords(Callback.OwnerPos.x, Callback.OwnerPos.y, Callback.OwnerPos.z); + OwnerPos.y = FindFirstNonAirBlockPosition(OwnerPos.x, OwnerPos.z); + TeleportToCoords(OwnerPos.x, OwnerPos.y, OwnerPos.z); SetTarget(nullptr); } } @@ -385,9 +374,9 @@ void cWolf::TickFollowPlayer() { if (GetTarget() == nullptr) { - if (!Callback.OwnerFlying) + if (!OwnerFlying) { - MoveToPosition(Callback.OwnerPos); + MoveToPosition(OwnerPos); } } } diff --git a/src/Root.cpp b/src/Root.cpp index 38c95f822..1de5d9b7c 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -1,4 +1,4 @@ - + #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "Root.h" @@ -352,22 +352,16 @@ void cRoot::Start(std::unique_ptr a_OverridesRepo) void cRoot::StopServer() { // Kick all players from the server with custom disconnect message - class cPlayerCallback : public cPlayerListCallback - { - AString m_ShutdownMessage; - virtual bool Item(cPlayer * a_Player) + + bool SentDisconnect = false; + cRoot::Get()->ForEachPlayer([&](cPlayer & a_Player) { - a_Player->GetClientHandlePtr()->Kick(m_ShutdownMessage); - m_HasSentDisconnect = true; + a_Player.GetClientHandlePtr()->Kick(m_Server->GetShutdownMessage()); + SentDisconnect = true; return false; } - public: - bool m_HasSentDisconnect; - cPlayerCallback(AString a_ShutdownMessage) : m_ShutdownMessage(a_ShutdownMessage) { m_HasSentDisconnect = false; } - } PlayerCallback(m_Server->GetShutdownMessage()); - - cRoot::Get()->ForEachPlayer(PlayerCallback); - if (PlayerCallback.m_HasSentDisconnect) + ); + if (SentDisconnect) { 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 (itr->second != nullptr) + if (World.second != nullptr) { - if (a_Callback.Item(itr->second)) + if (a_Callback(*World.second)) { 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) { @@ -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_NameLength; 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)) { - m_BestMatch = a_pPlayer->GetName(); + m_BestMatch = a_Player.GetName(); if (Rating > m_BestRating) { m_NumMatches = 0; @@ -815,7 +810,6 @@ bool cRoot::FindAndDoWithPlayer(const AString & a_PlayerName, cPlayerListCallbac return false; } - public: cCallback (const AString & a_CBPlayerName) : m_BestRating(0), 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) { @@ -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) { @@ -1048,25 +1042,11 @@ int cRoot::GetFurnaceFuelBurnTime(const cItem & a_Fuel) AStringVector cRoot::GetPlayerTabCompletionMultiWorld(const AString & a_Text) { AStringVector Results; - class cWorldCallback : public cWorldListCallback - { - public: - cWorldCallback(AStringVector & a_Results, const AString & a_Search) : - m_Results(a_Results), - m_Search(a_Search) + ForEachWorld([&](cWorld & a_World) { - } - - virtual bool Item(cWorld * a_World) override - { - a_World->TabCompleteUserName(m_Search, m_Results); + a_World.TabCompleteUserName(a_Text, Results); return false; } - private: - AStringVector & m_Results; - const AString & m_Search; - } WC(Results, a_Text); - - Get()->ForEachWorld(WC); + ); return Results; } diff --git a/src/Root.h b/src/Root.h index 46b202c88..4f191cf35 100644 --- a/src/Root.h +++ b/src/Root.h @@ -5,6 +5,7 @@ #include "Protocol/MojangAPI.h" #include "HTTP/HTTPServer.h" #include "Defines.h" +#include "FunctionRef.h" #include "RankManager.h" @@ -27,8 +28,8 @@ class cSettingsRepositoryInterface; class cDeadlockDetect; class cUUID; -typedef cItemCallback cPlayerListCallback; -typedef cItemCallback cWorldListCallback; +using cPlayerListCallback = cFunctionRef; +using cWorldListCallback = cFunctionRef; namespace Json { @@ -76,7 +77,7 @@ public: // tolua_end /** 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 */ void LogChunkStats(cCommandOutputCallback & a_Output); @@ -139,16 +140,16 @@ public: void SetSavingEnabled(bool a_SavingEnabled); // tolua_export /** 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 */ - 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 */ - 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 */ - 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 */ void SendPlayerLists(cPlayer * a_DestPlayer); diff --git a/src/Scoreboard.cpp b/src/Scoreboard.cpp index 4dde5b2dd..eec20e31c 100644 --- a/src/Scoreboard.cpp +++ b/src/Scoreboard.cpp @@ -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); @@ -496,7 +496,7 @@ bool cScoreboard::ForEachObjectiveWith(cObjective::eType a_Type, cObjectiveCallb if (it->second.GetType() == a_Type) { // Call callback - if (a_Callback.Item(&it->second)) + if (a_Callback(it->second)) { 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); for (cObjectiveMap::iterator it = m_Objectives.begin(); it != m_Objectives.end(); ++it) { // Call callback - if (a_Callback.Item(&it->second)) + if (a_Callback(it->second)) { 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); for (cTeamMap::iterator it = m_Teams.begin(); it != m_Teams.end(); ++it) { // Call callback - if (a_Callback.Item(&it->second)) + if (a_Callback(it->second)) { return false; } diff --git a/src/Scoreboard.h b/src/Scoreboard.h index 597c502c7..0e70a7654 100644 --- a/src/Scoreboard.h +++ b/src/Scoreboard.h @@ -11,14 +11,15 @@ +#include "FunctionRef.h" class cObjective; class cTeam; class cWorld; -typedef cItemCallback cObjectiveCallback; -typedef cItemCallback cTeamCallback; +using cObjectiveCallback = cFunctionRef; +using cTeamCallback = cFunctionRef; @@ -266,15 +267,15 @@ public: /** Execute callback for each objective with the specified type 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. 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. 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); diff --git a/src/Server.cpp b/src/Server.cpp index 6ddb14ae5..89dccb1f1 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -498,26 +498,20 @@ void cServer::ExecuteConsoleCommand(const AString & a_Cmd, cCommandOutputCallbac } if (split[0] == "destroyentities") { - class WorldCallback : public cWorldListCallback - { - virtual bool Item(cWorld * a_World) override + cRoot::Get()->ForEachWorld([](cWorld & a_World) { - class EntityCallback : public cEntityCallback - { - virtual bool Item(cEntity * a_Entity) override + a_World.ForEachEntity([](cEntity & a_Entity) { - if (!a_Entity->IsPlayer()) + if (!a_Entity.IsPlayer()) { - a_Entity->Destroy(); + a_Entity.Destroy(); } return false; } - } EC; - a_World->ForEachEntity(EC); + ); return false; } - } WC; - cRoot::Get()->ForEachWorld(WC); + ); a_Output.Out("Destroyed all entities"); a_Output.Finished(); return; diff --git a/src/Simulator/IncrementalRedstoneSimulator/CommandBlockHandler.h b/src/Simulator/IncrementalRedstoneSimulator/CommandBlockHandler.h index 2e7150080..672a4927b 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/CommandBlockHandler.h +++ b/src/Simulator/IncrementalRedstoneSimulator/CommandBlockHandler.h @@ -44,17 +44,12 @@ public: return {}; } - class cSetPowerToCommandBlock : public cCommandBlockCallback - { - public: - virtual bool Item(cCommandBlockEntity * a_CommandBlock) override + a_World.DoWithCommandBlockAt(a_Position.x, a_Position.y, a_Position.z, [](cCommandBlockEntity & a_CommandBlock) { - a_CommandBlock->Activate(); + a_CommandBlock.Activate(); return false; } - } CmdBlockSP; - - a_World.DoWithCommandBlockAt(a_Position.x, a_Position.y, a_Position.z, CmdBlockSP); + ); return {}; } diff --git a/src/Simulator/IncrementalRedstoneSimulator/DropSpenserHandler.h b/src/Simulator/IncrementalRedstoneSimulator/DropSpenserHandler.h index 42598f519..295afd34e 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/DropSpenserHandler.h +++ b/src/Simulator/IncrementalRedstoneSimulator/DropSpenserHandler.h @@ -56,18 +56,12 @@ public: bool WasPoweredPreviously = IsActivated(a_Meta); if (IsPoweredNow && !WasPoweredPreviously) { - class cSetPowerToDropSpenser : - public cDropSpenserCallback - { - public: - virtual bool Item(cDropSpenserEntity * a_DropSpenser) override + a_World.DoWithDropSpenserAt(a_Position.x, a_Position.y, a_Position.z, [](cDropSpenserEntity & a_DropSpenser) { - a_DropSpenser->Activate(); + a_DropSpenser.Activate(); return false; } - } DrSpSP; - - a_World.DoWithDropSpenserAt(a_Position.x, a_Position.y, a_Position.z, DrSpSP); + ); } // Update the internal dropspenser state if necessary diff --git a/src/Simulator/IncrementalRedstoneSimulator/NoteBlockHandler.h b/src/Simulator/IncrementalRedstoneSimulator/NoteBlockHandler.h index 7ecc64c72..46fcd6716 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/NoteBlockHandler.h +++ b/src/Simulator/IncrementalRedstoneSimulator/NoteBlockHandler.h @@ -45,17 +45,12 @@ public: return {}; } - class cSetPowerToNoteBlock : public cNoteBlockCallback - { - public: - virtual bool Item(cNoteEntity * a_NoteBlock) override + a_World.DoWithNoteBlockAt(a_Position.x, a_Position.y, a_Position.z, [](cNoteEntity & a_NoteBlock) { - a_NoteBlock->MakeSound(); + a_NoteBlock.MakeSound(); return false; } - } NoteBlockSP; - - a_World.DoWithNoteBlockAt(a_Position.x, a_Position.y, a_Position.z, NoteBlockSP); + ); return {}; } diff --git a/src/Simulator/IncrementalRedstoneSimulator/PressurePlateHandler.h b/src/Simulator/IncrementalRedstoneSimulator/PressurePlateHandler.h index 944543460..63add8982 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/PressurePlateHandler.h +++ b/src/Simulator/IncrementalRedstoneSimulator/PressurePlateHandler.h @@ -27,49 +27,37 @@ public: { UNUSED(a_Meta); - class cPressurePlateCallback : - public cEntityCallback - { - public: - cPressurePlateCallback(void) : - m_NumberOfEntities(0), - m_FoundPlayer(false) + unsigned int NumberOfEntities; + bool FoundPlayer; + a_World.ForEachEntityInBox(cBoundingBox(Vector3d(0.5, 0, 0.5) + a_Position, 0.5, 0.5), [&](cEntity & a_Entity) { - } - - virtual bool Item(cEntity * a_Entity) override - { - if (a_Entity->IsPlayer()) + if (a_Entity.IsPlayer()) { - m_FoundPlayer = true; + FoundPlayer = true; } - m_NumberOfEntities++; + NumberOfEntities++; 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) { case E_BLOCK_STONE_PRESSURE_PLATE: { - return (PressurePlateCallback.m_FoundPlayer ? 15 : 0); + return (FoundPlayer ? 15 : 0); } 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: { - return std::min(static_cast(CeilC(PressurePlateCallback.m_NumberOfEntities / 10.f)), static_cast(15)); + return std::min(static_cast(CeilC(NumberOfEntities / 10.f)), static_cast(15)); } case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE: { - return std::min(static_cast(PressurePlateCallback.m_NumberOfEntities), static_cast(15)); + return std::min(static_cast(NumberOfEntities), static_cast(15)); } default: { diff --git a/src/Simulator/IncrementalRedstoneSimulator/RedstoneComparatorHandler.h b/src/Simulator/IncrementalRedstoneSimulator/RedstoneComparatorHandler.h index cd43a4875..8c33ae266 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/RedstoneComparatorHandler.h +++ b/src/Simulator/IncrementalRedstoneSimulator/RedstoneComparatorHandler.h @@ -44,17 +44,12 @@ public: UNUSED(a_Position); UNUSED(a_BlockType); - class cContainerCallback : public cBlockEntityCallback - { - public: - cContainerCallback() : m_SignalStrength(0) - { - } - - virtual bool Item(cBlockEntity * a_BlockEntity) override + UInt8 SignalStrength = 0; + auto RearCoordinate = cBlockComparatorHandler::GetRearCoordinate(a_Position, a_Meta & 0x3); + a_World.DoWithBlockEntityAt(RearCoordinate.x, RearCoordinate.y, RearCoordinate.z, [&](cBlockEntity & a_BlockEntity) { // Skip BlockEntities that don't have slots - auto BlockEntityWithItems = dynamic_cast(a_BlockEntity); + auto BlockEntityWithItems = dynamic_cast(&a_BlockEntity); if (BlockEntityWithItems == nullptr) { return false; @@ -68,23 +63,18 @@ public: Fullness += static_cast(Contents.GetSlot(Slot).m_ItemCount) / Contents.GetSlot(Slot).GetMaxStackSize(); } - m_SignalStrength = (Fullness < 0.001 /* container empty? */) ? 0 : static_cast(1 + (Fullness / Contents.GetNumSlots()) * 14); + SignalStrength = (Fullness < 0.001 /* container empty? */) ? 0 : static_cast(1 + (Fullness / Contents.GetNumSlots()) * 14); return false; } - - unsigned char m_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 RearPower = SignalStrength; auto RearType = a_World.GetBlock(RearCoordinate); auto PotentialSourceHandler = cIncrementalRedstoneSimulator::GetComponentHandler(RearType); if (PotentialSourceHandler != nullptr) { 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; diff --git a/src/Simulator/IncrementalRedstoneSimulator/TrappedChestHandler.h b/src/Simulator/IncrementalRedstoneSimulator/TrappedChestHandler.h index 4ae4aff3d..80e55faec 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/TrappedChestHandler.h +++ b/src/Simulator/IncrementalRedstoneSimulator/TrappedChestHandler.h @@ -1,4 +1,4 @@ - + #pragma once #include "RedstoneHandler.h" @@ -28,38 +28,15 @@ public: UNUSED(a_BlockType); UNUSED(a_Meta); - class cGetTrappedChestPlayers : - public cItemCallback - { - public: - cGetTrappedChestPlayers(void) : - m_NumberOfPlayers(0) - { - } - - virtual ~cGetTrappedChestPlayers() override - { - } - - virtual bool Item(cChestEntity * a_Chest) override + int NumberOfPlayers = 0; + VERIFY(!a_World.DoWithChestAt(a_Position.x, a_Position.y, a_Position.z, [&](cChestEntity & a_Chest) { - ASSERT(a_Chest->GetBlockType() == E_BLOCK_TRAPPED_CHEST); - m_NumberOfPlayers = a_Chest->GetNumberOfPlayers(); + ASSERT(a_Chest.GetBlockType() == E_BLOCK_TRAPPED_CHEST); + NumberOfPlayers = a_Chest.GetNumberOfPlayers(); return true; } - - unsigned char GetPowerLevel(void) const - { - return static_cast(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(); + )); + return static_cast(std::min(NumberOfPlayers, 15)); } virtual cVector3iArray Update(cWorld & a_World, Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta, PoweringData a_PoweringData) const override diff --git a/src/Simulator/IncrementalRedstoneSimulator/TripwireHookHandler.h b/src/Simulator/IncrementalRedstoneSimulator/TripwireHookHandler.h index 609db932d..47225715f 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/TripwireHookHandler.h +++ b/src/Simulator/IncrementalRedstoneSimulator/TripwireHookHandler.h @@ -39,26 +39,7 @@ public: if (Type == E_BLOCK_TRIPWIRE) { - class cTripwireCallback : - 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)) + if (!a_World.ForEachEntityInBox(cBoundingBox(Vector3d(0.5, 0, 0.5) + Position, 0.5, 0.5), [](cEntity &) { return true; })) { FoundActivated = true; } diff --git a/src/UI/Window.cpp b/src/UI/Window.cpp index 8bbc4f482..cf02c0f00 100644 --- a/src/UI/Window.cpp +++ b/src/UI/Window.cpp @@ -362,12 +362,12 @@ void cWindow::OwnerDestroyed() -bool cWindow::ForEachPlayer(cItemCallback & a_Callback) +bool cWindow::ForEachPlayer(cPlayerListCallback a_Callback) { 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; } @@ -379,12 +379,12 @@ bool cWindow::ForEachPlayer(cItemCallback & a_Callback) -bool cWindow::ForEachClient(cItemCallback & a_Callback) +bool cWindow::ForEachClient(cClientHandleCallback a_Callback) { 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; } diff --git a/src/UI/Window.h b/src/UI/Window.h index d7a29dc47..bdd489d32 100644 --- a/src/UI/Window.h +++ b/src/UI/Window.h @@ -9,6 +9,7 @@ #pragma once +#include "../FunctionRef.h" #include "../ItemGrid.h" @@ -31,7 +32,8 @@ class cWorld; typedef std::list cPlayerList; typedef std::vector cSlotAreas; - +using cPlayerListCallback = cFunctionRef; +using cClientHandleCallback = cFunctionRef; @@ -151,10 +153,10 @@ public: void OwnerDestroyed(void); /** Calls the callback safely for each player that has this window open; returns true if all players have been enumerated */ - bool ForEachPlayer(cItemCallback & 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 */ - bool ForEachClient(cItemCallback & 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! if a_ShouldApply is true, the changes are written into the slots; diff --git a/src/WebAdmin.cpp b/src/WebAdmin.cpp index eefe57b73..335b6b94e 100644 --- a/src/WebAdmin.cpp +++ b/src/WebAdmin.cpp @@ -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("
  • "); - m_Contents.append(a_Player->GetName()); - m_Contents.append("
  • "); - return false; - } - -public: - - AString m_Contents; -} ; - - - - - //////////////////////////////////////////////////////////////////////////////// // cWebadminRequestData diff --git a/src/World.cpp b/src/World.cpp index e2ac24e71..086596eb3 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -1,4 +1,4 @@ - + #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "World.h" @@ -1122,59 +1122,52 @@ void cWorld::TickMobs(std::chrono::milliseconds a_Dt) { m_ChunkMap->SpawnMobs(Spawner); // 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 &>(*itr2))); + SpawnMobFinalize(std::move(Mob)); } } } // for i - AllFamilies[] } // if (Spawning enabled) - class cCallback : public cEntityCallback - { - virtual bool Item(cEntity * a_Entity) override + ForEachEntity([=](cEntity & a_Entity) { - if (!a_Entity->IsMob()) + if (!a_Entity.IsMob()) { return false; } - if (!a_Entity->IsTicking()) + if (!a_Entity.IsTicking()) { return false; } - auto Monster = static_cast(a_Entity); - ASSERT(Monster->GetParentChunk() != nullptr); // A ticking entity must have a valid parent chunk + auto & Monster = static_cast(a_Entity); + ASSERT(Monster.GetParentChunk() != nullptr); // A ticking entity must have a valid parent chunk // 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 - 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 { - auto Wolf = static_cast(Monster); - if (Wolf->IsAngry()) + auto & Wolf = static_cast(Monster); + if (Wolf.IsAngry()) { - Monster->Destroy(true); + Monster.Destroy(true); } } } 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); } @@ -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); } @@ -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); } @@ -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); } @@ -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); } @@ -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); } @@ -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); } @@ -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); } @@ -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); } @@ -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); } @@ -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); } @@ -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); } @@ -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); } @@ -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); } @@ -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); } @@ -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); } @@ -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); } @@ -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); } @@ -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); } @@ -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); } @@ -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); } @@ -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 a_Callback) -{ - struct cCallBackWrapper : cChunkCallback - { - cCallBackWrapper(std::function a_InnerCallback) : - m_Callback(a_InnerCallback) - { - } - - virtual bool Item(cChunk * a_Chunk) - { - return m_Callback(*a_Chunk); - } - - private: - std::function m_Callback; - } callback(a_Callback); - return m_ChunkMap->DoWithChunk(a_ChunkX, a_ChunkZ, callback); -} - - - - - -bool cWorld::DoWithChunkAt(Vector3i a_BlockPos, std::function a_Callback) +bool cWorld::DoWithChunkAt(Vector3i a_BlockPos, cChunkCallback 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 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 (!(*itr)->IsTicking()) - { - continue; - } - if (a_Callback.Item(*itr)) + if (Player->IsTicking() && a_Callback(*Player)) { 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 cCSLock Lock(m_CSPlayers); - for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) + for (auto & Player : m_Players) { - if (!(*itr)->IsTicking()) - { - continue; - } - if (NoCaseCompare((*itr)->GetName(), a_PlayerName) == 0) + if (Player->IsTicking() && (NoCaseCompare(Player->GetName(), a_PlayerName) == 0)) { - a_Callback.Item(*itr); + a_Callback(*Player); return true; } } // 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; size_t BestRating = 0; @@ -3243,7 +3203,7 @@ bool cWorld::FindAndDoWithPlayer(const AString & a_PlayerNameHint, cPlayerListCa if (BestMatch != nullptr) { - return a_Callback.Item (BestMatch); + return a_Callback(*BestMatch); } return false; } @@ -3252,27 +3212,14 @@ bool cWorld::FindAndDoWithPlayer(const AString & a_PlayerNameHint, cPlayerListCa -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) +bool cWorld::DoWithPlayerByUUID(const cUUID & a_PlayerUUID, cPlayerListCallback a_Callback) { 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; - } - if ((*itr)->GetUUID() == a_PlayerUUID) - { - return a_Callback(*itr); + return a_Callback(*Player); } } 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); } @@ -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); } @@ -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); } @@ -3367,16 +3314,7 @@ bool cWorld::ForEachEntityInBox(const cBoundingBox & a_Box, cEntityCallback & a_ -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) +bool cWorld::DoWithEntityByID(UInt32 a_UniqueID, cEntityCallback a_Callback) { // First check the entities-to-add: { @@ -3385,7 +3323,7 @@ bool cWorld::DoWithEntityByID(UInt32 a_UniqueID, cLambdaEntityCallback a_Callbac { if (ent->GetUniqueID() == a_UniqueID) { - a_Callback(ent.get()); + a_Callback(*ent); return true; } } // 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) { - class cUpdateCommandBlock : public cCommandBlockCallback - { - AString m_Command; - public: - cUpdateCommandBlock(const AString & a_CallbackCommand) : m_Command(a_CallbackCommand) {} - - virtual bool Item(cCommandBlockEntity * a_CommandBlock) override + return DoWithCommandBlockAt(a_BlockX, a_BlockY, a_BlockZ, [&](cCommandBlockEntity & a_CommandBlock) { - a_CommandBlock->SetCommand(m_Command); + a_CommandBlock.SetCommand(a_Command); 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 a_Callback) +bool cWorld::ForEachLoadedChunk(cFunctionRef a_Callback) { return m_ChunkMap->ForEachLoadedChunk(a_Callback); } diff --git a/src/World.h b/src/World.h index 22847b975..f6fb32005 100644 --- a/src/World.h +++ b/src/World.h @@ -59,21 +59,6 @@ typedef std::list< std::pair< std::unique_ptr, cWorld * > > cAwaitingPl typedef std::unique_ptr cSetChunkDataPtr; typedef std::vector cSetChunkDataPtrs; -typedef cItemCallback cPlayerListCallback; -typedef cItemCallback cEntityCallback; -typedef cItemCallback cBeaconCallback; -typedef cItemCallback cBrewingstandCallback; -typedef cItemCallback cChestCallback; -typedef cItemCallback cDispenserCallback; -typedef cItemCallback cFurnaceCallback; -typedef cItemCallback cNoteBlockCallback; -typedef cItemCallback cCommandBlockCallback; -typedef cItemCallback cMobHeadCallback; -typedef cItemCallback cFlowerPotCallback; - -typedef std::function cLambdaPlayerCallback; -typedef std::function cLambdaEntityCallback; - @@ -282,21 +267,20 @@ public: #endif /** 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. 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 */ - 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) cPlayer * FindClosestPlayer(Vector3d a_Pos, float a_SightLimit, bool a_CheckLineOfSight = true); /** 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, cLambdaPlayerCallback a_Callback); // Lambda version + bool DoWithPlayerByUUID(const cUUID & a_PlayerUUID, cPlayerListCallback a_Callback); // >> EXPORTED IN MANUALBINDINGS << void SendPlayerList(cPlayer * a_DestPlayer); // Sends playerlist to the player @@ -313,20 +297,19 @@ public: 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 */ - 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 */ - 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. 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. */ - 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. 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, cLambdaEntityCallback a_Callback); // Lambda version + bool DoWithEntityByID(UInt32 a_UniqueID, cEntityCallback a_Callback); // Exported in ManualBindings.cpp /** 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); @@ -390,7 +373,7 @@ public: 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 */ - bool ForEachLoadedChunk(std::function a_Callback); + bool ForEachLoadedChunk(cFunctionRef a_Callback); // tolua_begin @@ -541,25 +524,25 @@ public: 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 */ - 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 */ - 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 */ - 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 */ - 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 */ - 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 */ - 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 */ - 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. 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; /** 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 */ - 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 */ - 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 */ - 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 */ - 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 */ - 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 */ - 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 */ - 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 */ - 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 */ - 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 */ - 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 */ - 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 */ - 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 */ 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: */ 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 */ - bool DoWithChunk(int a_ChunkX, int a_ChunkZ, cChunkCallback & a_Callback); - bool DoWithChunk(int a_ChunkX, int a_ChunkZ, std::function a_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); /** 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 */ - bool DoWithChunkAt(Vector3i a_BlockPos, std::function a_Callback); + bool DoWithChunkAt(Vector3i a_BlockPos, cChunkCallback a_Callback); void GrowTreeImage(const sSetBlockVector & a_Blocks); -- cgit v1.2.3