diff options
Diffstat (limited to 'src')
102 files changed, 1067 insertions, 965 deletions
diff --git a/src/Bindings/CMakeLists.txt b/src/Bindings/CMakeLists.txt index 930ee9771..5c56231c6 100644 --- a/src/Bindings/CMakeLists.txt +++ b/src/Bindings/CMakeLists.txt @@ -37,14 +37,12 @@ SET (HDRS set (BINDING_OUTPUTS ${CMAKE_CURRENT_SOURCE_DIR}/Bindings.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Bindings.h - ${CMAKE_CURRENT_SOURCE_DIR}/LuaState_Call.inc ) set(BINDING_DEPENDENCIES tolua ../Bindings/virtual_method_hooks.lua ../Bindings/AllToLua.pkg - ../Bindings/gen_LuaState_Call.lua ../Bindings/LuaFunctions.h ../Bindings/LuaWindow.h ../Bindings/Plugin.h @@ -127,7 +125,6 @@ if (NOT MSVC) endif () set_source_files_properties(${CMAKE_SOURCE_DIR}/src/Bindings/Bindings.cpp PROPERTIES GENERATED TRUE) set_source_files_properties(${CMAKE_SOURCE_DIR}/src/Bindings/Bindings.h PROPERTIES GENERATED TRUE) -set_source_files_properties(${CMAKE_SOURCE_DIR}/src/Bindings/LuaState_Call.inc PROPERTIES GENERATED TRUE) set_source_files_properties(${CMAKE_SOURCE_DIR}/src/Bindings/Bindings.cpp PROPERTIES COMPILE_FLAGS -Wno-error) diff --git a/src/Bindings/LuaChunkStay.cpp b/src/Bindings/LuaChunkStay.cpp index a3d3a8090..23da12f68 100644 --- a/src/Bindings/LuaChunkStay.cpp +++ b/src/Bindings/LuaChunkStay.cpp @@ -130,8 +130,11 @@ void cLuaChunkStay::Enable(cChunkMap & a_ChunkMap, int a_OnChunkAvailableStackPo void cLuaChunkStay::OnChunkAvailable(int a_ChunkX, int a_ChunkZ) { - cPluginLua::cOperation Op(m_Plugin); - Op().Call((int)m_OnChunkAvailable, a_ChunkX, a_ChunkZ); + if (m_OnChunkAvailable.IsValid()) + { + cPluginLua::cOperation Op(m_Plugin); + Op().Call((int)m_OnChunkAvailable, a_ChunkX, a_ChunkZ); + } } @@ -140,6 +143,7 @@ void cLuaChunkStay::OnChunkAvailable(int a_ChunkX, int a_ChunkZ) bool cLuaChunkStay::OnAllChunksAvailable(void) { + if (m_OnAllChunksAvailable.IsValid()) { // Call the callback: cPluginLua::cOperation Op(m_Plugin); diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp index 85e3f9fc5..928436a2f 100644 --- a/src/Bindings/LuaState.cpp +++ b/src/Bindings/LuaState.cpp @@ -16,6 +16,8 @@ extern "C" #include "Bindings.h" #include "ManualBindings.h" #include "DeprecatedBindings.h" +#include "../Entities/Entity.h" +#include "../BlockEntities/BlockEntity.h" // fwd: SQLite/lsqlite3.c extern "C" @@ -520,7 +522,7 @@ void cLuaState::Push(cBlockEntity * a_BlockEntity) { ASSERT(IsValid()); - tolua_pushusertype(m_LuaState, a_BlockEntity, "cBlockEntity"); + tolua_pushusertype(m_LuaState, a_BlockEntity, (a_BlockEntity == nullptr) ? "cBlockEntity" : a_BlockEntity->GetClass()); m_NumCurrentFunctionArgs += 1; } @@ -556,7 +558,61 @@ void cLuaState::Push(cEntity * a_Entity) { ASSERT(IsValid()); - tolua_pushusertype(m_LuaState, a_Entity, "cEntity"); + if (a_Entity == nullptr) + { + lua_pushnil(m_LuaState); + } + else + { + switch (a_Entity->GetEntityType()) + { + case cEntity::etMonster: + { + // Don't push specific mob types, as those are not exported in the API: + tolua_pushusertype(m_LuaState, a_Entity, "cMonster"); + break; + } + case cEntity::etPlayer: + { + tolua_pushusertype(m_LuaState, a_Entity, "cPlayer"); + break; + } + case cEntity::etPickup: + { + tolua_pushusertype(m_LuaState, a_Entity, "cPickup"); + break; + } + case cEntity::etTNT: + { + tolua_pushusertype(m_LuaState, a_Entity, "cTNTEntity"); + break; + } + case cEntity::etProjectile: + { + tolua_pushusertype(m_LuaState, a_Entity, "cProjectileEntity"); + break; + } + case cEntity::etFloater: + { + tolua_pushusertype(m_LuaState, a_Entity, "cFloater"); + break; + } + + case cEntity::etEntity: + case cEntity::etEnderCrystal: + case cEntity::etFallingBlock: + case cEntity::etMinecart: + case cEntity::etBoat: + case cEntity::etExpOrb: + case cEntity::etItemFrame: + case cEntity::etPainting: + { + // Push the generic entity class type: + tolua_pushusertype(m_LuaState, a_Entity, "cEntity"); + } + } // switch (EntityType) + } + m_NumCurrentFunctionArgs += 1; } diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h index ef87c3efc..899228a66 100644 --- a/src/Bindings/LuaState.h +++ b/src/Bindings/LuaState.h @@ -240,10 +240,24 @@ public: /** Retrieve value at a_StackPos, if it is a valid cWorld class. If not, a_Value is unchanged */ void GetStackValue(int a_StackPos, pWorld & a_Value); + /** Call the specified Lua function. + Returns true if call succeeded, false if there was an error. + A special param of cRet & signifies the end of param list and the start of return values. + Example call: Call(Fn, Param1, Param2, Param3, cLuaState::Return, Ret1, Ret2) */ + template <typename FnT, typename... Args> + bool Call(const FnT & a_Function, Args &&... args) + { + PushFunction(a_Function); + return PushCallPop(args...); + } - // Include the cLuaState::Call() overload implementation that is generated by the gen_LuaState_Call.lua script: - #include "LuaState_Call.inc" - + /** Retrieves a list of values from the Lua stack, starting at the specified index. */ + template <typename T, typename... Args> + inline void GetStackValues(int a_StartStackPos, T & a_Ret, Args &&... args) + { + GetStackValue(a_StartStackPos, a_Ret); + GetStackValues(a_StartStackPos + 1, args...); + } /** Returns true if the specified parameters on the stack are of the specified usertable type; also logs warning if not. Used for static functions */ bool CheckParamUserTable(int a_StartParam, const char * a_UserTable, int a_EndParam = -1); @@ -310,6 +324,7 @@ public: static void LogStack(lua_State * a_LuaState, const char * a_Header = NULL); protected: + lua_State * m_LuaState; /** If true, the state is owned by this object and will be auto-Closed. False => attached state */ @@ -327,6 +342,63 @@ protected: int m_NumCurrentFunctionArgs; + /** Variadic template terminator: Counting zero args returns zero. */ + int CountArgs(void) + { + return 0; + } + + /** Variadic template: Counting args means add one to the count of the rest. */ + template <typename T, typename... Args> + int CountArgs(T, Args... args) + { + return 1 + CountArgs(args...); + } + + /** Variadic template terminator: If there's nothing more to push / pop, just call the function. + Note that there are no return values either, because those are prefixed by a cRet value, so the arg list is never empty. */ + bool PushCallPop(void) + { + return CallFunction(0); + } + + /** Variadic template recursor: More params to push. Push them and recurse. */ + template <typename T, typename... Args> + inline bool PushCallPop(T a_Param, Args &&... args) + { + Push(a_Param); + return PushCallPop(args...); + } + + /** Variadic template terminator: If there's nothing more to push, but return values to collect, call the function and collect the returns. */ + template <typename... Args> + bool PushCallPop(cLuaState::cRet, Args &&... args) + { + // Calculate the number of return values (number of args left): + int NumReturns = CountArgs(args...); + + // Call the function: + if (!CallFunction(NumReturns)) + { + return false; + } + + // Collect the return values: + GetStackValues(-NumReturns, args...); + lua_pop(m_LuaState, NumReturns); + + // All successful: + return true; + } + + /** Variadic template terminator: If there are no more values to get, bail out. + This function is not available in the public API, because it's an error to request no values directly; only internal functions can do that. + If you get a compile error saying this function is not accessible, check your calling code, you aren't reading any stack values. */ + void GetStackValues(int a_StartingStackPos) + { + // Do nothing + } + /** Pushes the function of the specified name onto the stack. Returns true if successful. Logs a warning on failure (incl. m_SubsystemName) */ diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index f643f06ec..0558533ce 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -1160,7 +1160,7 @@ static int tolua_cWorld_QueueTask(lua_State * tolua_S) return lua_do_error(tolua_S, "Error in function call '#funcname#': Could not get function reference of parameter #1"); } - self->QueueTask(new cLuaWorldTask(*Plugin, FnRef)); + self->QueueTask(make_unique<cLuaWorldTask>(*Plugin, FnRef)); return 0; } diff --git a/src/Bindings/ManualBindings_RankManager.cpp b/src/Bindings/ManualBindings_RankManager.cpp index 3c58a0a92..66174bf86 100644 --- a/src/Bindings/ManualBindings_RankManager.cpp +++ b/src/Bindings/ManualBindings_RankManager.cpp @@ -34,7 +34,7 @@ static int tolua_cRankManager_AddGroup(lua_State * L) S.GetStackValue(2, GroupName); // Add the group: - cRoot::Get()->GetRankManager().AddGroup(GroupName); + cRoot::Get()->GetRankManager()->AddGroup(GroupName); return 0; } @@ -63,7 +63,7 @@ static int tolua_cRankManager_AddGroupToRank(lua_State * L) S.GetStackValues(2, GroupName, RankName); // Add the group to the rank: - S.Push(cRoot::Get()->GetRankManager().AddGroupToRank(GroupName, RankName)); + S.Push(cRoot::Get()->GetRankManager()->AddGroupToRank(GroupName, RankName)); return 1; } @@ -92,7 +92,7 @@ static int tolua_cRankManager_AddPermissionToGroup(lua_State * L) S.GetStackValues(2, Permission, GroupName); // Add the group to the rank: - S.Push(cRoot::Get()->GetRankManager().AddPermissionToGroup(Permission, GroupName)); + S.Push(cRoot::Get()->GetRankManager()->AddPermissionToGroup(Permission, GroupName)); return 1; } @@ -121,7 +121,7 @@ static int tolua_cRankManager_AddRank(lua_State * L) S.GetStackValues(2, RankName, MsgPrefix, MsgSuffix, MsgNameColorCode); // Add the rank: - cRoot::Get()->GetRankManager().AddRank(RankName, MsgPrefix, MsgSuffix, MsgNameColorCode); + cRoot::Get()->GetRankManager()->AddRank(RankName, MsgPrefix, MsgSuffix, MsgNameColorCode); return 0; } @@ -142,7 +142,7 @@ static int tolua_cRankManager_ClearPlayerRanks(lua_State * L) } // Remove all players: - cRoot::Get()->GetRankManager().ClearPlayerRanks(); + cRoot::Get()->GetRankManager()->ClearPlayerRanks(); return 1; } @@ -166,7 +166,7 @@ static int tolua_cRankManager_GetAllGroups(lua_State * L) } // Get the groups: - AStringVector Groups = cRoot::Get()->GetRankManager().GetAllGroups(); + AStringVector Groups = cRoot::Get()->GetRankManager()->GetAllGroups(); // Push the results: S.Push(Groups); @@ -193,7 +193,7 @@ static int tolua_cRankManager_GetAllPermissions(lua_State * L) } // Get the permissions: - AStringVector Permissions = cRoot::Get()->GetRankManager().GetAllPermissions(); + AStringVector Permissions = cRoot::Get()->GetRankManager()->GetAllPermissions(); // Push the results: S.Push(Permissions); @@ -220,7 +220,7 @@ static int tolua_cRankManager_GetAllPlayerUUIDs(lua_State * L) } // Get the player uuid's: - AStringVector Players = cRoot::Get()->GetRankManager().GetAllPlayerUUIDs(); + AStringVector Players = cRoot::Get()->GetRankManager()->GetAllPlayerUUIDs(); // Push the results: S.Push(Players); @@ -247,7 +247,7 @@ static int tolua_cRankManager_GetAllRanks(lua_State * L) } // Get the ranks: - AStringVector Ranks = cRoot::Get()->GetRankManager().GetAllRanks(); + AStringVector Ranks = cRoot::Get()->GetRankManager()->GetAllRanks(); // Push the results: S.Push(Ranks); @@ -274,7 +274,7 @@ static int tolua_cRankManager_GetDefaultRank(lua_State * L) } // Return the rank name: - S.Push(cRoot::Get()->GetRankManager().GetDefaultRank()); + S.Push(cRoot::Get()->GetRankManager()->GetDefaultRank()); return 1; } @@ -303,7 +303,7 @@ static int tolua_cRankManager_GetGroupPermissions(lua_State * L) S.GetStackValue(2, GroupName); // Get the permissions: - AStringVector Permissions = cRoot::Get()->GetRankManager().GetGroupPermissions(GroupName); + AStringVector Permissions = cRoot::Get()->GetRankManager()->GetGroupPermissions(GroupName); // Push the results: S.Push(Permissions); @@ -335,7 +335,7 @@ static int tolua_cRankManager_GetPlayerGroups(lua_State * L) S.GetStackValue(2, PlayerUUID); // Get the groups: - AStringVector Groups = cRoot::Get()->GetRankManager().GetPlayerGroups(PlayerUUID); + AStringVector Groups = cRoot::Get()->GetRankManager()->GetPlayerGroups(PlayerUUID); // Push the results: S.Push(Groups); @@ -368,7 +368,7 @@ static int tolua_cRankManager_GetPlayerMsgVisuals(lua_State * L) // Get the permissions: AString MsgPrefix, MsgSuffix, MsgNameColorCode; - if (!cRoot::Get()->GetRankManager().GetPlayerMsgVisuals(PlayerUUID, MsgPrefix, MsgSuffix, MsgNameColorCode)) + if (!cRoot::Get()->GetRankManager()->GetPlayerMsgVisuals(PlayerUUID, MsgPrefix, MsgSuffix, MsgNameColorCode)) { return 0; } @@ -405,7 +405,7 @@ static int tolua_cRankManager_GetPlayerPermissions(lua_State * L) S.GetStackValue(2, PlayerUUID); // Get the permissions: - AStringVector Permissions = cRoot::Get()->GetRankManager().GetPlayerPermissions(PlayerUUID); + AStringVector Permissions = cRoot::Get()->GetRankManager()->GetPlayerPermissions(PlayerUUID); // Push the results: S.Push(Permissions); @@ -437,7 +437,7 @@ static int tolua_cRankManager_GetPlayerRankName(lua_State * L) S.GetStackValue(2, PlayerUUID); // Get the rank name: - AString RankName = cRoot::Get()->GetRankManager().GetPlayerRankName(PlayerUUID); + AString RankName = cRoot::Get()->GetRankManager()->GetPlayerRankName(PlayerUUID); // Push the result: S.Push(RankName); @@ -469,7 +469,7 @@ static int tolua_cRankManager_GetPlayerName(lua_State * L) S.GetStackValue(2, PlayerUUID); // Get the player name: - AString PlayerName = cRoot::Get()->GetRankManager().GetPlayerName(PlayerUUID); + AString PlayerName = cRoot::Get()->GetRankManager()->GetPlayerName(PlayerUUID); // Push the result: S.Push(PlayerName); @@ -501,7 +501,7 @@ static int tolua_cRankManager_GetRankGroups(lua_State * L) S.GetStackValue(2, RankName); // Get the groups: - AStringVector Groups = cRoot::Get()->GetRankManager().GetRankGroups(RankName); + AStringVector Groups = cRoot::Get()->GetRankManager()->GetRankGroups(RankName); // Push the results: S.Push(Groups); @@ -533,7 +533,7 @@ static int tolua_cRankManager_GetRankPermissions(lua_State * L) S.GetStackValue(2, RankName); // Get the permissions: - AStringVector Permissions = cRoot::Get()->GetRankManager().GetRankPermissions(RankName); + AStringVector Permissions = cRoot::Get()->GetRankManager()->GetRankPermissions(RankName); // Push the results: S.Push(Permissions); @@ -566,7 +566,7 @@ static int tolua_cRankManager_GetRankVisuals(lua_State * L) // Get the visuals: AString MsgPrefix, MsgSuffix, MsgNameColorCode; - if (!cRoot::Get()->GetRankManager().GetRankVisuals(RankName, MsgPrefix, MsgSuffix, MsgNameColorCode)) + if (!cRoot::Get()->GetRankManager()->GetRankVisuals(RankName, MsgPrefix, MsgSuffix, MsgNameColorCode)) { // No such rank, return nothing: return 0; @@ -604,7 +604,7 @@ static int tolua_cRankManager_GroupExists(lua_State * L) S.GetStackValue(2, GroupName); // Get the response: - bool res = cRoot::Get()->GetRankManager().GroupExists(GroupName); + bool res = cRoot::Get()->GetRankManager()->GroupExists(GroupName); // Push the result: S.Push(res); @@ -636,7 +636,7 @@ static int tolua_cRankManager_IsGroupInRank(lua_State * L) S.GetStackValues(2, GroupName, RankName); // Get the response: - bool res = cRoot::Get()->GetRankManager().IsGroupInRank(GroupName, RankName); + bool res = cRoot::Get()->GetRankManager()->IsGroupInRank(GroupName, RankName); // Push the result: S.Push(res); @@ -668,7 +668,7 @@ static int tolua_cRankManager_IsPermissionInGroup(lua_State * L) S.GetStackValues(2, Permission, GroupName); // Get the response: - bool res = cRoot::Get()->GetRankManager().IsPermissionInGroup(Permission, GroupName); + bool res = cRoot::Get()->GetRankManager()->IsPermissionInGroup(Permission, GroupName); // Push the result: S.Push(res); @@ -700,7 +700,7 @@ static int tolua_cRankManager_IsPlayerRankSet(lua_State * L) S.GetStackValue(2, PlayerUUID); // Get the response: - bool res = cRoot::Get()->GetRankManager().IsPlayerRankSet(PlayerUUID); + bool res = cRoot::Get()->GetRankManager()->IsPlayerRankSet(PlayerUUID); // Push the result: S.Push(res); @@ -732,7 +732,7 @@ static int tolua_cRankManager_RankExists(lua_State * L) S.GetStackValue(2, RankName); // Get the response: - bool res = cRoot::Get()->GetRankManager().RankExists(RankName); + bool res = cRoot::Get()->GetRankManager()->RankExists(RankName); // Push the result: S.Push(res); @@ -764,7 +764,7 @@ static int tolua_cRankManager_RemoveGroup(lua_State * L) S.GetStackValue(2, GroupName); // Remove the group: - cRoot::Get()->GetRankManager().RemoveGroup(GroupName); + cRoot::Get()->GetRankManager()->RemoveGroup(GroupName); return 0; } @@ -793,7 +793,7 @@ static int tolua_cRankManager_RemoveGroupFromRank(lua_State * L) S.GetStackValues(2, GroupName, RankName); // Remove the group: - cRoot::Get()->GetRankManager().RemoveGroupFromRank(GroupName, RankName); + cRoot::Get()->GetRankManager()->RemoveGroupFromRank(GroupName, RankName); return 0; } @@ -822,7 +822,7 @@ static int tolua_cRankManager_RemovePermissionFromGroup(lua_State * L) S.GetStackValues(2, Permission, GroupName); // Remove the group: - cRoot::Get()->GetRankManager().RemovePermissionFromGroup(Permission, GroupName); + cRoot::Get()->GetRankManager()->RemovePermissionFromGroup(Permission, GroupName); return 0; } @@ -851,7 +851,7 @@ static int tolua_cRankManager_RemovePlayerRank(lua_State * L) S.GetStackValue(2, PlayerUUID); // Remove the player's rank: - cRoot::Get()->GetRankManager().RemovePlayerRank(PlayerUUID); + cRoot::Get()->GetRankManager()->RemovePlayerRank(PlayerUUID); return 0; } @@ -881,7 +881,7 @@ static int tolua_cRankManager_RemoveRank(lua_State * L) S.GetStackValues(2, RankName, ReplacementRankName); // Remove the rank: - cRoot::Get()->GetRankManager().RemoveRank(RankName, ReplacementRankName); + cRoot::Get()->GetRankManager()->RemoveRank(RankName, ReplacementRankName); return 0; } @@ -910,7 +910,7 @@ static int tolua_cRankManager_RenameGroup(lua_State * L) S.GetStackValues(2, OldName, NewName); // Remove the group: - bool res = cRoot::Get()->GetRankManager().RenameGroup(OldName, NewName); + bool res = cRoot::Get()->GetRankManager()->RenameGroup(OldName, NewName); // Push the result: S.Push(res); @@ -942,7 +942,7 @@ static int tolua_cRankManager_RenameRank(lua_State * L) S.GetStackValues(2, OldName, NewName); // Remove the rank: - bool res = cRoot::Get()->GetRankManager().RenameRank(OldName, NewName); + bool res = cRoot::Get()->GetRankManager()->RenameRank(OldName, NewName); // Push the result: S.Push(res); @@ -974,7 +974,7 @@ static int tolua_cRankManager_SetDefaultRank(lua_State * L) S.GetStackValue(2, RankName); // Set the rank, return the result: - S.Push(cRoot::Get()->GetRankManager().SetDefaultRank(RankName)); + S.Push(cRoot::Get()->GetRankManager()->SetDefaultRank(RankName)); return 1; } @@ -1003,7 +1003,7 @@ static int tolua_cRankManager_SetPlayerRank(lua_State * L) S.GetStackValues(2, PlayerUUID, PlayerName, RankName); // Set the rank: - cRoot::Get()->GetRankManager().SetPlayerRank(PlayerUUID, PlayerName, RankName); + cRoot::Get()->GetRankManager()->SetPlayerRank(PlayerUUID, PlayerName, RankName); return 0; } @@ -1032,7 +1032,7 @@ static int tolua_cRankManager_SetRankVisuals(lua_State * L) S.GetStackValues(2, RankName, MsgPrefix, MsgSuffix, MsgNameColorCode); // Set the visuals: - cRoot::Get()->GetRankManager().SetRankVisuals(RankName, MsgPrefix, MsgSuffix, MsgNameColorCode); + cRoot::Get()->GetRankManager()->SetRankVisuals(RankName, MsgPrefix, MsgSuffix, MsgNameColorCode); return 0; } diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h index fb22dd33e..8cc9ff0cd 100644 --- a/src/Bindings/Plugin.h +++ b/src/Bindings/Plugin.h @@ -45,26 +45,26 @@ public: virtual void Tick(float a_Dt) = 0; /** Calls the specified hook with the params given. Returns the bool that the hook callback returns.*/ - virtual bool OnBlockSpread (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source) = 0; - virtual bool OnBlockToPickups (cWorld * a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups) = 0; - virtual bool OnChat (cPlayer * a_Player, AString & a_Message) = 0; - virtual bool OnChunkAvailable (cWorld * a_World, int a_ChunkX, int a_ChunkZ) = 0; - virtual bool OnChunkGenerated (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc) = 0; - virtual bool OnChunkGenerating (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc) = 0; - virtual bool OnChunkUnloaded (cWorld * a_World, int a_ChunkX, int a_ChunkZ) = 0; - virtual bool OnChunkUnloading (cWorld * a_World, int a_ChunkX, int a_ChunkZ) = 0; - virtual bool OnCollectingPickup (cPlayer * a_Player, cPickup * a_Pickup) = 0; - virtual bool OnCraftingNoRecipe (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) = 0; + virtual bool OnBlockSpread (cWorld & a_World, int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source) = 0; + virtual bool OnBlockToPickups (cWorld & a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups) = 0; + virtual bool OnChat (cPlayer & a_Player, AString & a_Message) = 0; + virtual bool OnChunkAvailable (cWorld & a_World, int a_ChunkX, int a_ChunkZ) = 0; + virtual bool OnChunkGenerated (cWorld & a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc) = 0; + virtual bool OnChunkGenerating (cWorld & a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc) = 0; + virtual bool OnChunkUnloaded (cWorld & a_World, int a_ChunkX, int a_ChunkZ) = 0; + virtual bool OnChunkUnloading (cWorld & a_World, int a_ChunkX, int a_ChunkZ) = 0; + virtual bool OnCollectingPickup (cPlayer & a_Player, cPickup & a_Pickup) = 0; + virtual bool OnCraftingNoRecipe (cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe * a_Recipe) = 0; virtual bool OnDisconnect (cClientHandle & a_Client, const AString & a_Reason) = 0; virtual bool OnEntityAddEffect (cEntity & a_Entity, int a_EffectType, int a_EffectDurationTicks, int a_EffectIntensity, double a_DistanceModifier) = 0; virtual bool OnExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split) = 0; virtual bool OnExploded (cWorld & a_World, double a_ExplosionSize, bool a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData) = 0; virtual bool OnExploding (cWorld & a_World, double & a_ExplosionSize, bool & a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData) = 0; - virtual bool OnHandshake (cClientHandle * a_Client, const AString & a_Username) = 0; + virtual bool OnHandshake (cClientHandle & a_Client, const AString & a_Username) = 0; virtual bool OnHopperPullingItem (cWorld & a_World, cHopperEntity & a_Hopper, int a_DstSlotNum, cBlockEntityWithItems & a_SrcEntity, int a_SrcSlotNum) = 0; virtual bool OnHopperPushingItem (cWorld & a_World, cHopperEntity & a_Hopper, int a_SrcSlotNum, cBlockEntityWithItems & a_DstEntity, int a_DstSlotNum) = 0; virtual bool OnKilling (cEntity & a_Victim, cEntity * a_Killer, TakeDamageInfo & a_TDI) = 0; - virtual bool OnLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username) = 0; + virtual bool OnLogin (cClientHandle & a_Client, int a_ProtocolVersion, const AString & a_Username) = 0; virtual bool OnPlayerAnimation (cPlayer & a_Player, int a_Animation) = 0; virtual bool OnPlayerBreakingBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) = 0; virtual bool OnPlayerBrokenBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) = 0; @@ -89,8 +89,8 @@ public: virtual bool OnPlayerUsingItem (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) = 0; virtual bool OnPluginMessage (cClientHandle & a_Client, const AString & a_Channel, const AString & a_Message) = 0; virtual bool OnPluginsLoaded (void) = 0; - virtual bool OnPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) = 0; - virtual bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) = 0; + virtual bool OnPostCrafting (cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe & a_Recipe) = 0; + virtual bool OnPreCrafting (cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe & a_Recipe) = 0; virtual bool OnProjectileHitBlock (cProjectileEntity & a_Projectile, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Face, const Vector3d & a_BlockHitPos) = 0; virtual bool OnProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity) = 0; virtual bool OnServerPing (cClientHandle & a_ClientHandle, AString & a_ServerDescription, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon) = 0; @@ -99,8 +99,8 @@ public: virtual bool OnSpawningEntity (cWorld & a_World, cEntity & a_Entity) = 0; virtual bool OnSpawningMonster (cWorld & a_World, cMonster & a_Monster) = 0; virtual bool OnTakeDamage (cEntity & a_Receiver, TakeDamageInfo & a_TakeDamageInfo) = 0; - virtual bool OnUpdatedSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player) = 0; - virtual bool OnUpdatingSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player) = 0; + virtual bool OnUpdatedSign (cWorld & a_World, int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player) = 0; + virtual bool OnUpdatingSign (cWorld & a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player) = 0; virtual bool OnWeatherChanged (cWorld & a_World) = 0; virtual bool OnWeatherChanging (cWorld & a_World, eWeather & a_NewWeather) = 0; virtual bool OnWorldStarted (cWorld & a_World) = 0; @@ -110,7 +110,7 @@ public: Command permissions have already been checked. Returns true if command handled successfully */ - virtual bool HandleCommand(const AStringVector & a_Split, cPlayer * a_Player) = 0; + virtual bool HandleCommand(const AStringVector & a_Split, cPlayer & a_Player) = 0; /** Handles the console command split into a_Split. Returns true if command handled successfully. Output is to be sent to the a_Output callback. diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp index 2629eb641..eec31e8a6 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -202,14 +202,14 @@ void cPluginLua::Tick(float a_Dt) -bool cPluginLua::OnBlockSpread(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source) +bool cPluginLua::OnBlockSpread(cWorld & a_World, int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source) { cCSLock Lock(m_CriticalSection); bool res = false; cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_BLOCK_SPREAD]; for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) { - m_LuaState.Call((int)(**itr), a_World, a_BlockX, a_BlockY, a_BlockZ, a_Source, cLuaState::Return, res); + m_LuaState.Call((int)(**itr), &a_World, a_BlockX, a_BlockY, a_BlockZ, a_Source, cLuaState::Return, res); if (res) { return true; @@ -222,14 +222,14 @@ bool cPluginLua::OnBlockSpread(cWorld * a_World, int a_BlockX, int a_BlockY, int -bool cPluginLua::OnBlockToPickups(cWorld * a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups) +bool cPluginLua::OnBlockToPickups(cWorld & a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups) { cCSLock Lock(m_CriticalSection); bool res = false; cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_BLOCK_TO_PICKUPS]; for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) { - m_LuaState.Call((int)(**itr), a_World, a_Digger, a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, &a_Pickups, cLuaState::Return, res); + m_LuaState.Call((int)(**itr), &a_World, a_Digger, a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, &a_Pickups, cLuaState::Return, res); if (res) { return true; @@ -242,14 +242,14 @@ bool cPluginLua::OnBlockToPickups(cWorld * a_World, cEntity * a_Digger, int a_Bl -bool cPluginLua::OnChat(cPlayer * a_Player, AString & a_Message) +bool cPluginLua::OnChat(cPlayer & a_Player, AString & a_Message) { cCSLock Lock(m_CriticalSection); bool res = false; cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_CHAT]; for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) { - m_LuaState.Call((int)(**itr), a_Player, a_Message, cLuaState::Return, res, a_Message); + m_LuaState.Call((int)(**itr), &a_Player, a_Message, cLuaState::Return, res, a_Message); if (res) { return true; @@ -262,14 +262,14 @@ bool cPluginLua::OnChat(cPlayer * a_Player, AString & a_Message) -bool cPluginLua::OnChunkAvailable(cWorld * a_World, int a_ChunkX, int a_ChunkZ) +bool cPluginLua::OnChunkAvailable(cWorld & a_World, int a_ChunkX, int a_ChunkZ) { cCSLock Lock(m_CriticalSection); bool res = false; cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_CHUNK_AVAILABLE]; for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) { - m_LuaState.Call((int)(**itr), a_World, a_ChunkX, a_ChunkZ, cLuaState::Return, res); + m_LuaState.Call((int)(**itr), &a_World, a_ChunkX, a_ChunkZ, cLuaState::Return, res); if (res) { return true; @@ -282,14 +282,14 @@ bool cPluginLua::OnChunkAvailable(cWorld * a_World, int a_ChunkX, int a_ChunkZ) -bool cPluginLua::OnChunkGenerated(cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc) +bool cPluginLua::OnChunkGenerated(cWorld & a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc) { cCSLock Lock(m_CriticalSection); bool res = false; cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_CHUNK_GENERATED]; for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) { - m_LuaState.Call((int)(**itr), a_World, a_ChunkX, a_ChunkZ, a_ChunkDesc, cLuaState::Return, res); + m_LuaState.Call((int)(**itr), &a_World, a_ChunkX, a_ChunkZ, a_ChunkDesc, cLuaState::Return, res); if (res) { return true; @@ -302,14 +302,14 @@ bool cPluginLua::OnChunkGenerated(cWorld * a_World, int a_ChunkX, int a_ChunkZ, -bool cPluginLua::OnChunkGenerating(cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc) +bool cPluginLua::OnChunkGenerating(cWorld & a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc) { cCSLock Lock(m_CriticalSection); bool res = false; cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_CHUNK_GENERATING]; for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) { - m_LuaState.Call((int)(**itr), a_World, a_ChunkX, a_ChunkZ, a_ChunkDesc, cLuaState::Return, res); + m_LuaState.Call((int)(**itr), &a_World, a_ChunkX, a_ChunkZ, a_ChunkDesc, cLuaState::Return, res); if (res) { return true; @@ -322,14 +322,14 @@ bool cPluginLua::OnChunkGenerating(cWorld * a_World, int a_ChunkX, int a_ChunkZ, -bool cPluginLua::OnChunkUnloaded(cWorld * a_World, int a_ChunkX, int a_ChunkZ) +bool cPluginLua::OnChunkUnloaded(cWorld & a_World, int a_ChunkX, int a_ChunkZ) { cCSLock Lock(m_CriticalSection); bool res = false; cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_CHUNK_UNLOADED]; for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) { - m_LuaState.Call((int)(**itr), a_World, a_ChunkX, a_ChunkZ, cLuaState::Return, res); + m_LuaState.Call((int)(**itr), &a_World, a_ChunkX, a_ChunkZ, cLuaState::Return, res); if (res) { return true; @@ -342,14 +342,14 @@ bool cPluginLua::OnChunkUnloaded(cWorld * a_World, int a_ChunkX, int a_ChunkZ) -bool cPluginLua::OnChunkUnloading(cWorld * a_World, int a_ChunkX, int a_ChunkZ) +bool cPluginLua::OnChunkUnloading(cWorld & a_World, int a_ChunkX, int a_ChunkZ) { cCSLock Lock(m_CriticalSection); bool res = false; cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_CHUNK_UNLOADING]; for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) { - m_LuaState.Call((int)(**itr), a_World, a_ChunkX, a_ChunkZ, cLuaState::Return, res); + m_LuaState.Call((int)(**itr), &a_World, a_ChunkX, a_ChunkZ, cLuaState::Return, res); if (res) { return true; @@ -362,14 +362,14 @@ bool cPluginLua::OnChunkUnloading(cWorld * a_World, int a_ChunkX, int a_ChunkZ) -bool cPluginLua::OnCollectingPickup(cPlayer * a_Player, cPickup * a_Pickup) +bool cPluginLua::OnCollectingPickup(cPlayer & a_Player, cPickup & a_Pickup) { cCSLock Lock(m_CriticalSection); bool res = false; cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_COLLECTING_PICKUP]; for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) { - m_LuaState.Call((int)(**itr), a_Player, a_Pickup, cLuaState::Return, res); + m_LuaState.Call((int)(**itr), &a_Player, &a_Pickup, cLuaState::Return, res); if (res) { return true; @@ -382,14 +382,14 @@ bool cPluginLua::OnCollectingPickup(cPlayer * a_Player, cPickup * a_Pickup) -bool cPluginLua::OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) +bool cPluginLua::OnCraftingNoRecipe(cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe * a_Recipe) { cCSLock Lock(m_CriticalSection); bool res = false; cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_CRAFTING_NO_RECIPE]; for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) { - m_LuaState.Call((int)(**itr), (cPlayer *)a_Player, a_Grid, a_Recipe, cLuaState::Return, res); + m_LuaState.Call((int)(**itr), &a_Player, &a_Grid, &a_Recipe, cLuaState::Return, res); if (res) { return true; @@ -471,12 +471,12 @@ bool cPluginLua::OnExploded(cWorld & a_World, double a_ExplosionSize, bool a_Can { switch (a_Source) { - case esOther: m_LuaState.Call((int)(**itr), &a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source, a_SourceData, cLuaState::Return, res); break; - case esPrimedTNT: m_LuaState.Call((int)(**itr), &a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source, (cTNTEntity *)a_SourceData, cLuaState::Return, res); break; - case esMonster: m_LuaState.Call((int)(**itr), &a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source, (cMonster *)a_SourceData, cLuaState::Return, res); break; - case esBed: m_LuaState.Call((int)(**itr), &a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source, (Vector3i *)a_SourceData, cLuaState::Return, res); break; - case esEnderCrystal: m_LuaState.Call((int)(**itr), &a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source, (Vector3i *)a_SourceData, cLuaState::Return, res); break; - case esGhastFireball: m_LuaState.Call((int)(**itr), &a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source, a_SourceData, cLuaState::Return, res); break; + case esOther: m_LuaState.Call((int)(**itr), &a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source, a_SourceData, cLuaState::Return, res); break; + case esPrimedTNT: m_LuaState.Call((int)(**itr), &a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source, (cTNTEntity *)a_SourceData, cLuaState::Return, res); break; + case esMonster: m_LuaState.Call((int)(**itr), &a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source, (cMonster *)a_SourceData, cLuaState::Return, res); break; + case esBed: m_LuaState.Call((int)(**itr), &a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source, (Vector3i *)a_SourceData, cLuaState::Return, res); break; + case esEnderCrystal: m_LuaState.Call((int)(**itr), &a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source, (Vector3i *)a_SourceData, cLuaState::Return, res); break; + case esGhastFireball: m_LuaState.Call((int)(**itr), &a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source, a_SourceData, cLuaState::Return, res); break; case esWitherSkullBlack: case esWitherSkullBlue: m_LuaState.Call((int)(**itr), &a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source, a_SourceData, cLuaState::Return, res); break; case esWitherBirth: m_LuaState.Call((int)(**itr), &a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source, a_SourceData, cLuaState::Return, res); break; @@ -536,14 +536,14 @@ bool cPluginLua::OnExploding(cWorld & a_World, double & a_ExplosionSize, bool & -bool cPluginLua::OnHandshake(cClientHandle * a_Client, const AString & a_Username) +bool cPluginLua::OnHandshake(cClientHandle & a_Client, const AString & a_Username) { cCSLock Lock(m_CriticalSection); bool res = false; cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_HANDSHAKE]; for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) { - m_LuaState.Call((int)(**itr), a_Client, a_Username, cLuaState::Return, res); + m_LuaState.Call((int)(**itr), &a_Client, a_Username, cLuaState::Return, res); if (res) { return true; @@ -617,14 +617,14 @@ bool cPluginLua::OnKilling(cEntity & a_Victim, cEntity * a_Killer, TakeDamageInf -bool cPluginLua::OnLogin(cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username) +bool cPluginLua::OnLogin(cClientHandle & a_Client, int a_ProtocolVersion, const AString & a_Username) { cCSLock Lock(m_CriticalSection); bool res = false; cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_LOGIN]; for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) { - m_LuaState.Call((int)(**itr), a_Client, a_ProtocolVersion, a_Username, cLuaState::Return, res); + m_LuaState.Call((int)(**itr), &a_Client, a_ProtocolVersion, a_Username, cLuaState::Return, res); if (res) { return true; @@ -784,7 +784,7 @@ bool cPluginLua::OnPlayerFishing(cPlayer & a_Player, cItems & a_Reward) cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_PLAYER_FISHING]; for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) { - m_LuaState.Call((int)(**itr), &a_Player, a_Reward, cLuaState::Return, res); + m_LuaState.Call((int)(**itr), &a_Player, &a_Reward, cLuaState::Return, res); if (res) { return true; @@ -1115,14 +1115,14 @@ bool cPluginLua::OnPluginsLoaded(void) -bool cPluginLua::OnPostCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) +bool cPluginLua::OnPostCrafting(cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe & a_Recipe) { cCSLock Lock(m_CriticalSection); bool res = false; cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_POST_CRAFTING]; for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) { - m_LuaState.Call((int)(**itr), a_Player, a_Grid, a_Recipe, cLuaState::Return, res); + m_LuaState.Call((int)(**itr), &a_Player, &a_Grid, &a_Recipe, cLuaState::Return, res); if (res) { return true; @@ -1135,14 +1135,14 @@ bool cPluginLua::OnPostCrafting(const cPlayer * a_Player, const cCraftingGrid * -bool cPluginLua::OnPreCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) +bool cPluginLua::OnPreCrafting(cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe & a_Recipe) { cCSLock Lock(m_CriticalSection); bool res = false; cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_PRE_CRAFTING]; for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) { - m_LuaState.Call((int)(**itr), a_Player, a_Grid, a_Recipe, cLuaState::Return, res); + m_LuaState.Call((int)(**itr), &a_Player, &a_Grid, &a_Recipe, cLuaState::Return, res); if (res) { return true; @@ -1316,7 +1316,7 @@ bool cPluginLua::OnTakeDamage(cEntity & a_Receiver, TakeDamageInfo & a_TDI) bool cPluginLua::OnUpdatedSign( - cWorld * a_World, + cWorld & a_World, int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player @@ -1327,7 +1327,7 @@ bool cPluginLua::OnUpdatedSign( cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_UPDATED_SIGN]; for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) { - m_LuaState.Call((int)(**itr), a_World, a_BlockX, a_BlockY, a_BlockZ, a_Line1, a_Line2, a_Line3, a_Line4, a_Player, cLuaState::Return, res); + m_LuaState.Call((int)(**itr), &a_World, a_BlockX, a_BlockY, a_BlockZ, a_Line1, a_Line2, a_Line3, a_Line4, a_Player, cLuaState::Return, res); if (res) { return true; @@ -1341,7 +1341,7 @@ bool cPluginLua::OnUpdatedSign( bool cPluginLua::OnUpdatingSign( - cWorld * a_World, + cWorld & a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player @@ -1352,7 +1352,7 @@ bool cPluginLua::OnUpdatingSign( cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_UPDATING_SIGN]; for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) { - m_LuaState.Call((int)(**itr), a_World, a_BlockX, a_BlockY, a_BlockZ, a_Line1, a_Line2, a_Line3, a_Line4, a_Player, cLuaState::Return, res, a_Line1, a_Line2, a_Line3, a_Line4); + m_LuaState.Call((int)(**itr), &a_World, a_BlockX, a_BlockY, a_BlockZ, a_Line1, a_Line2, a_Line3, a_Line4, a_Player, cLuaState::Return, res, a_Line1, a_Line2, a_Line3, a_Line4); if (res) { return true; @@ -1435,7 +1435,7 @@ bool cPluginLua::OnWorldTick(cWorld & a_World, float a_Dt, int a_LastTickDuratio -bool cPluginLua::HandleCommand(const AStringVector & a_Split, cPlayer * a_Player) +bool cPluginLua::HandleCommand(const AStringVector & a_Split, cPlayer & a_Player) { ASSERT(!a_Split.empty()); CommandMap::iterator cmd = m_Commands.find(a_Split[0]); @@ -1447,7 +1447,7 @@ bool cPluginLua::HandleCommand(const AStringVector & a_Split, cPlayer * a_Player cCSLock Lock(m_CriticalSection); bool res = false; - m_LuaState.Call(cmd->second, a_Split, a_Player, cLuaState::Return, res); + m_LuaState.Call(cmd->second, a_Split, &a_Player, cLuaState::Return, res); return res; } diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h index eda65b76c..6bb134efc 100644 --- a/src/Bindings/PluginLua.h +++ b/src/Bindings/PluginLua.h @@ -69,26 +69,26 @@ public: virtual void Tick(float a_Dt) override; - virtual bool OnBlockSpread (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source) override; - virtual bool OnBlockToPickups (cWorld * a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups) override; - virtual bool OnChat (cPlayer * a_Player, AString & a_Message) override; - virtual bool OnChunkAvailable (cWorld * a_World, int a_ChunkX, int a_ChunkZ) override; - virtual bool OnChunkGenerated (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc) override; - virtual bool OnChunkGenerating (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc) override; - virtual bool OnChunkUnloaded (cWorld * a_World, int a_ChunkX, int a_ChunkZ) override; - virtual bool OnChunkUnloading (cWorld * a_World, int a_ChunkX, int a_ChunkZ) override; - virtual bool OnCollectingPickup (cPlayer * a_Player, cPickup * a_Pickup) override; - virtual bool OnCraftingNoRecipe (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override; + virtual bool OnBlockSpread (cWorld & a_World, int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source) override; + virtual bool OnBlockToPickups (cWorld & a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups) override; + virtual bool OnChat (cPlayer & a_Player, AString & a_Message) override; + virtual bool OnChunkAvailable (cWorld & a_World, int a_ChunkX, int a_ChunkZ) override; + virtual bool OnChunkGenerated (cWorld & a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc) override; + virtual bool OnChunkGenerating (cWorld & a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc) override; + virtual bool OnChunkUnloaded (cWorld & a_World, int a_ChunkX, int a_ChunkZ) override; + virtual bool OnChunkUnloading (cWorld & a_World, int a_ChunkX, int a_ChunkZ) override; + virtual bool OnCollectingPickup (cPlayer & a_Player, cPickup & a_Pickup) override; + virtual bool OnCraftingNoRecipe (cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe * a_Recipe) override; virtual bool OnDisconnect (cClientHandle & a_Client, const AString & a_Reason) override; virtual bool OnEntityAddEffect (cEntity & a_Entity, int a_EffectType, int a_EffectDurationTicks, int a_EffectIntensity, double a_DistanceModifier) override; virtual bool OnExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split) override; virtual bool OnExploded (cWorld & a_World, double a_ExplosionSize, bool a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData) override; virtual bool OnExploding (cWorld & a_World, double & a_ExplosionSize, bool & a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData) override; - virtual bool OnHandshake (cClientHandle * a_Client, const AString & a_Username) override; + virtual bool OnHandshake (cClientHandle & a_Client, const AString & a_Username) override; virtual bool OnHopperPullingItem (cWorld & a_World, cHopperEntity & a_Hopper, int a_DstSlotNum, cBlockEntityWithItems & a_SrcEntity, int a_SrcSlotNum) override; virtual bool OnHopperPushingItem (cWorld & a_World, cHopperEntity & a_Hopper, int a_SrcSlotNum, cBlockEntityWithItems & a_DstEntity, int a_DstSlotNum) override; virtual bool OnKilling (cEntity & a_Victim, cEntity * a_Killer, TakeDamageInfo & a_TDI) override; - virtual bool OnLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username) override; + virtual bool OnLogin (cClientHandle & a_Client, int a_ProtocolVersion, const AString & a_Username) override; virtual bool OnPlayerAnimation (cPlayer & a_Player, int a_Animation) override; virtual bool OnPlayerBreakingBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override; virtual bool OnPlayerBrokenBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override; @@ -113,8 +113,8 @@ public: virtual bool OnPlayerUsingItem (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override; virtual bool OnPluginMessage (cClientHandle & a_Client, const AString & a_Channel, const AString & a_Message) override; virtual bool OnPluginsLoaded (void) override; - virtual bool OnPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override; - virtual bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override; + virtual bool OnPostCrafting (cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe & a_Recipe) override; + virtual bool OnPreCrafting (cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe & a_Recipe) override; virtual bool OnProjectileHitBlock (cProjectileEntity & a_Projectile, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Face, const Vector3d & a_BlockHitPos) override; virtual bool OnProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity) override; virtual bool OnServerPing (cClientHandle & a_ClientHandle, AString & a_ServerDescription, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon) override; @@ -123,14 +123,14 @@ public: virtual bool OnSpawningEntity (cWorld & a_World, cEntity & a_Entity) override; virtual bool OnSpawningMonster (cWorld & a_World, cMonster & a_Monster) override; virtual bool OnTakeDamage (cEntity & a_Receiver, TakeDamageInfo & a_TakeDamageInfo) override; - virtual bool OnUpdatedSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player) override; - virtual bool OnUpdatingSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player) override; + virtual bool OnUpdatedSign (cWorld & a_World, int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player) override; + virtual bool OnUpdatingSign (cWorld & a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player) override; virtual bool OnWeatherChanged (cWorld & a_World) override; virtual bool OnWeatherChanging (cWorld & a_World, eWeather & a_NewWeather) override; virtual bool OnWorldStarted (cWorld & a_World) override; virtual bool OnWorldTick (cWorld & a_World, float a_Dt, int a_LastTickDurationMSec) override; - virtual bool HandleCommand(const AStringVector & a_Split, cPlayer * a_Player) override; + virtual bool HandleCommand(const AStringVector & a_Split, cPlayer & a_Player) override; virtual bool HandleConsoleCommand(const AStringVector & a_Split, cCommandOutputCallback & a_Output) override; diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index e0faa838a..479e71951 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -225,7 +225,7 @@ void cPluginManager::Tick(float a_Dt) -bool cPluginManager::CallHookBlockSpread(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source) +bool cPluginManager::CallHookBlockSpread(cWorld & a_World, int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source) { FIND_HOOK(HOOK_BLOCK_SPREAD); VERIFY_HOOK; @@ -245,7 +245,7 @@ bool cPluginManager::CallHookBlockSpread(cWorld * a_World, int a_BlockX, int a_B bool cPluginManager::CallHookBlockToPickups( - cWorld * a_World, cEntity * a_Digger, + cWorld & a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups ) @@ -267,7 +267,7 @@ bool cPluginManager::CallHookBlockToPickups( -bool cPluginManager::CallHookChat(cPlayer * a_Player, AString & a_Message) +bool cPluginManager::CallHookChat(cPlayer & a_Player, AString & a_Message) { // Check if the message contains a command, execute it: switch (HandleCommand(a_Player, a_Message, true)) @@ -288,14 +288,14 @@ bool cPluginManager::CallHookChat(cPlayer * a_Player, AString & a_Message) case crError: { // An error in the plugin has prevented the command from executing. Report the error to the player: - a_Player->SendMessageFailure(Printf("Something went wrong while executing command \"%s\"", a_Message.c_str())); + a_Player.SendMessageFailure(Printf("Something went wrong while executing command \"%s\"", a_Message.c_str())); return true; } case crNoPermission: { // The player is not allowed to execute this command - a_Player->SendMessageFailure(Printf("Forbidden command; insufficient privileges: \"%s\"", a_Message.c_str())); + a_Player.SendMessageFailure(Printf("Forbidden command; insufficient privileges: \"%s\"", a_Message.c_str())); return true; } @@ -311,8 +311,8 @@ bool cPluginManager::CallHookChat(cPlayer * a_Player, AString & a_Message) { AStringVector Split(StringSplit(a_Message, " ")); ASSERT(!Split.empty()); // This should not happen - we know there's at least one char in the message so the split needs to be at least one item long - a_Player->SendMessageInfo(Printf("Unknown command: \"%s\"", a_Message.c_str())); - LOGINFO("Player %s issued an unknown command: \"%s\"", a_Player->GetName().c_str(), a_Message.c_str()); + a_Player.SendMessageInfo(Printf("Unknown command: \"%s\"", a_Message.c_str())); + LOGINFO("Player %s issued an unknown command: \"%s\"", a_Player.GetName().c_str(), a_Message.c_str()); return true; // Cancel sending } @@ -334,7 +334,7 @@ bool cPluginManager::CallHookChat(cPlayer * a_Player, AString & a_Message) -bool cPluginManager::CallHookChunkAvailable(cWorld * a_World, int a_ChunkX, int a_ChunkZ) +bool cPluginManager::CallHookChunkAvailable(cWorld & a_World, int a_ChunkX, int a_ChunkZ) { FIND_HOOK(HOOK_CHUNK_AVAILABLE); VERIFY_HOOK; @@ -353,7 +353,7 @@ bool cPluginManager::CallHookChunkAvailable(cWorld * a_World, int a_ChunkX, int -bool cPluginManager::CallHookChunkGenerated(cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc) +bool cPluginManager::CallHookChunkGenerated(cWorld & a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc) { FIND_HOOK(HOOK_CHUNK_GENERATED); VERIFY_HOOK; @@ -372,7 +372,7 @@ bool cPluginManager::CallHookChunkGenerated(cWorld * a_World, int a_ChunkX, int -bool cPluginManager::CallHookChunkGenerating(cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc) +bool cPluginManager::CallHookChunkGenerating(cWorld & a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc) { FIND_HOOK(HOOK_CHUNK_GENERATING); VERIFY_HOOK; @@ -391,7 +391,7 @@ bool cPluginManager::CallHookChunkGenerating(cWorld * a_World, int a_ChunkX, int -bool cPluginManager::CallHookChunkUnloaded(cWorld * a_World, int a_ChunkX, int a_ChunkZ) +bool cPluginManager::CallHookChunkUnloaded(cWorld & a_World, int a_ChunkX, int a_ChunkZ) { FIND_HOOK(HOOK_CHUNK_UNLOADED); VERIFY_HOOK; @@ -410,7 +410,7 @@ bool cPluginManager::CallHookChunkUnloaded(cWorld * a_World, int a_ChunkX, int a -bool cPluginManager::CallHookChunkUnloading(cWorld * a_World, int a_ChunkX, int a_ChunkZ) +bool cPluginManager::CallHookChunkUnloading(cWorld & a_World, int a_ChunkX, int a_ChunkZ) { FIND_HOOK(HOOK_CHUNK_UNLOADING); VERIFY_HOOK; @@ -429,14 +429,14 @@ bool cPluginManager::CallHookChunkUnloading(cWorld * a_World, int a_ChunkX, int -bool cPluginManager::CallHookCollectingPickup(cPlayer * a_Player, cPickup & a_Pickup) +bool cPluginManager::CallHookCollectingPickup(cPlayer & a_Player, cPickup & a_Pickup) { FIND_HOOK(HOOK_COLLECTING_PICKUP); VERIFY_HOOK; for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) { - if ((*itr)->OnCollectingPickup(a_Player, &a_Pickup)) + if ((*itr)->OnCollectingPickup(a_Player, a_Pickup)) { return true; } @@ -448,7 +448,7 @@ bool cPluginManager::CallHookCollectingPickup(cPlayer * a_Player, cPickup & a_Pi -bool cPluginManager::CallHookCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) +bool cPluginManager::CallHookCraftingNoRecipe(cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe * a_Recipe) { FIND_HOOK(HOOK_CRAFTING_NO_RECIPE); VERIFY_HOOK; @@ -562,7 +562,7 @@ bool cPluginManager::CallHookExploding(cWorld & a_World, double & a_ExplosionSiz -bool cPluginManager::CallHookHandshake(cClientHandle * a_ClientHandle, const AString & a_Username) +bool cPluginManager::CallHookHandshake(cClientHandle & a_ClientHandle, const AString & a_Username) { FIND_HOOK(HOOK_HANDSHAKE); VERIFY_HOOK; @@ -638,7 +638,7 @@ bool cPluginManager::CallHookKilling(cEntity & a_Victim, cEntity * a_Killer, Tak -bool cPluginManager::CallHookLogin(cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username) +bool cPluginManager::CallHookLogin(cClientHandle & a_Client, int a_ProtocolVersion, const AString & a_Username) { FIND_HOOK(HOOK_LOGIN); VERIFY_HOOK; @@ -1111,7 +1111,7 @@ bool cPluginManager::CallHookPluginsLoaded(void) -bool cPluginManager::CallHookPostCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) +bool cPluginManager::CallHookPostCrafting(cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe & a_Recipe) { FIND_HOOK(HOOK_POST_CRAFTING); VERIFY_HOOK; @@ -1130,7 +1130,7 @@ bool cPluginManager::CallHookPostCrafting(const cPlayer * a_Player, const cCraft -bool cPluginManager::CallHookPreCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) +bool cPluginManager::CallHookPreCrafting(cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe & a_Recipe) { FIND_HOOK(HOOK_PRE_CRAFTING); VERIFY_HOOK; @@ -1299,7 +1299,7 @@ bool cPluginManager::CallHookTakeDamage(cEntity & a_Receiver, TakeDamageInfo & a -bool cPluginManager::CallHookUpdatingSign(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player) +bool cPluginManager::CallHookUpdatingSign(cWorld & a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player) { FIND_HOOK(HOOK_UPDATING_SIGN); VERIFY_HOOK; @@ -1318,7 +1318,7 @@ bool cPluginManager::CallHookUpdatingSign(cWorld * a_World, int a_BlockX, int a_ -bool cPluginManager::CallHookUpdatedSign(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player) +bool cPluginManager::CallHookUpdatedSign(cWorld & a_World, int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player) { FIND_HOOK(HOOK_UPDATED_SIGN); VERIFY_HOOK; @@ -1413,10 +1413,8 @@ bool cPluginManager::CallHookWorldTick(cWorld & a_World, float a_Dt, int a_LastT -cPluginManager::CommandResult cPluginManager::HandleCommand(cPlayer * a_Player, const AString & a_Command, bool a_ShouldCheckPermissions) +cPluginManager::CommandResult cPluginManager::HandleCommand(cPlayer & a_Player, const AString & a_Command, bool a_ShouldCheckPermissions) { - ASSERT(a_Player != NULL); - AStringVector Split(StringSplit(a_Command, " ")); if (Split.empty()) { @@ -1431,19 +1429,19 @@ cPluginManager::CommandResult cPluginManager::HandleCommand(cPlayer * a_Player, } // Ask plugins first if a command is okay to execute the command: - if (CallHookExecuteCommand(a_Player, Split)) + if (CallHookExecuteCommand(&a_Player, Split)) { - LOGINFO("Player %s tried executing command \"%s\" that was stopped by the HOOK_EXECUTE_COMMAND hook", a_Player->GetName().c_str(), Split[0].c_str()); + LOGINFO("Player %s tried executing command \"%s\" that was stopped by the HOOK_EXECUTE_COMMAND hook", a_Player.GetName().c_str(), Split[0].c_str()); return crBlocked; } if ( a_ShouldCheckPermissions && !cmd->second.m_Permission.empty() && - !a_Player->HasPermission(cmd->second.m_Permission) + !a_Player.HasPermission(cmd->second.m_Permission) ) { - LOGINFO("Player %s tried to execute forbidden command: \"%s\"", a_Player->GetName().c_str(), Split[0].c_str()); + LOGINFO("Player %s tried to execute forbidden command: \"%s\"", a_Player.GetName().c_str(), Split[0].c_str()); return crNoPermission; } @@ -1652,7 +1650,7 @@ AString cPluginManager::GetCommandPermission(const AString & a_Command) -cPluginManager::CommandResult cPluginManager::ExecuteCommand(cPlayer * a_Player, const AString & a_Command) +cPluginManager::CommandResult cPluginManager::ExecuteCommand(cPlayer & a_Player, const AString & a_Command) { return HandleCommand(a_Player, a_Command, true); } @@ -1661,7 +1659,7 @@ cPluginManager::CommandResult cPluginManager::ExecuteCommand(cPlayer * a_Player, -cPluginManager::CommandResult cPluginManager::ForceExecuteCommand(cPlayer * a_Player, const AString & a_Command) +cPluginManager::CommandResult cPluginManager::ForceExecuteCommand(cPlayer & a_Player, const AString & a_Command) { return HandleCommand(a_Player, a_Command, false); } @@ -1830,6 +1828,7 @@ bool cPluginManager::DoWithPlugin(const AString & a_PluginName, cPluginCallback bool cPluginManager::AddPlugin(cPlugin * a_Plugin) { m_Plugins[a_Plugin->GetDirectory()] = a_Plugin; + if (a_Plugin->Initialize()) { // Initialization OK diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index fff3bc323..c69850be6 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -178,26 +178,26 @@ public: size_t GetNumPlugins() const; // tolua_export // Calls for individual hooks. Each returns false if the action is to continue or true if the plugin wants to abort - bool CallHookBlockSpread (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source); - bool CallHookBlockToPickups (cWorld * a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups); - bool CallHookChat (cPlayer * a_Player, AString & a_Message); - bool CallHookChunkAvailable (cWorld * a_World, int a_ChunkX, int a_ChunkZ); - bool CallHookChunkGenerated (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc); - bool CallHookChunkGenerating (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc); - bool CallHookChunkUnloaded (cWorld * a_World, int a_ChunkX, int a_ChunkZ); - bool CallHookChunkUnloading (cWorld * a_World, int a_ChunkX, int a_ChunkZ); - bool CallHookCollectingPickup (cPlayer * a_Player, cPickup & a_Pickup); - bool CallHookCraftingNoRecipe (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe); + bool CallHookBlockSpread (cWorld & a_World, int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source); + bool CallHookBlockToPickups (cWorld & a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups); + bool CallHookChat (cPlayer & a_Player, AString & a_Message); + bool CallHookChunkAvailable (cWorld & a_World, int a_ChunkX, int a_ChunkZ); + bool CallHookChunkGenerated (cWorld & a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc); + bool CallHookChunkGenerating (cWorld & a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc); + bool CallHookChunkUnloaded (cWorld & a_World, int a_ChunkX, int a_ChunkZ); + bool CallHookChunkUnloading (cWorld & a_World, int a_ChunkX, int a_ChunkZ); + bool CallHookCollectingPickup (cPlayer & a_Player, cPickup & a_Pickup); + bool CallHookCraftingNoRecipe (cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe * a_Recipe); bool CallHookDisconnect (cClientHandle & a_Client, const AString & a_Reason); bool CallHookEntityAddEffect (cEntity & a_Entity, int a_EffectType, int a_EffectDurationTicks, int a_EffectIntensity, double a_DistanceModifier); bool CallHookExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split); // If a_Player == NULL, it is a console cmd bool CallHookExploded (cWorld & a_World, double a_ExplosionSize, bool a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData); bool CallHookExploding (cWorld & a_World, double & a_ExplosionSize, bool & a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData); - bool CallHookHandshake (cClientHandle * a_ClientHandle, const AString & a_Username); + bool CallHookHandshake (cClientHandle & a_ClientHandle, const AString & a_Username); bool CallHookHopperPullingItem (cWorld & a_World, cHopperEntity & a_Hopper, int a_DstSlotNum, cBlockEntityWithItems & a_SrcEntity, int a_SrcSlotNum); bool CallHookHopperPushingItem (cWorld & a_World, cHopperEntity & a_Hopper, int a_SrcSlotNum, cBlockEntityWithItems & a_DstEntity, int a_DstSlotNum); bool CallHookKilling (cEntity & a_Victim, cEntity * a_Killer, TakeDamageInfo & a_TDI); - bool CallHookLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username); + bool CallHookLogin (cClientHandle & a_Client, int a_ProtocolVersion, const AString & a_Username); bool CallHookPlayerAnimation (cPlayer & a_Player, int a_Animation); bool CallHookPlayerBreakingBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); bool CallHookPlayerBrokenBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); @@ -222,8 +222,8 @@ public: bool CallHookPlayerUsingItem (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ); bool CallHookPluginMessage (cClientHandle & a_Client, const AString & a_Channel, const AString & a_Message); bool CallHookPluginsLoaded (void); - bool CallHookPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe); - bool CallHookPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe); + bool CallHookPostCrafting (cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe & a_Recipe); + bool CallHookPreCrafting (cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe & a_Recipe); bool CallHookProjectileHitBlock (cProjectileEntity & a_Projectile, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Face, const Vector3d & a_BlockHitPos); bool CallHookProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity); bool CallHookServerPing (cClientHandle & a_ClientHandle, AString & a_ServerDescription, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon); @@ -232,8 +232,8 @@ public: bool CallHookSpawningEntity (cWorld & a_World, cEntity & a_Entity); bool CallHookSpawningMonster (cWorld & a_World, cMonster & a_Monster); bool CallHookTakeDamage (cEntity & a_Receiver, TakeDamageInfo & a_TDI); - bool CallHookUpdatedSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player); - bool CallHookUpdatingSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player); + bool CallHookUpdatedSign (cWorld & a_World, int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player); + bool CallHookUpdatingSign (cWorld & a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player); bool CallHookWeatherChanged (cWorld & a_World); bool CallHookWeatherChanging (cWorld & a_World, eWeather & a_NewWeather); bool CallHookWorldStarted (cWorld & a_World); @@ -264,10 +264,10 @@ public: AString GetCommandPermission(const AString & a_Command); // tolua_export /** Executes the command, as if it was requested by a_Player. Checks permissions first. Returns crExecuted if executed. */ - CommandResult ExecuteCommand(cPlayer * a_Player, const AString & a_Command); // tolua_export + CommandResult ExecuteCommand(cPlayer & a_Player, const AString & a_Command); // tolua_export /** Executes the command, as if it was requested by a_Player. Permisssions are not checked. Returns crExecuted if executed. */ - CommandResult ForceExecuteCommand(cPlayer * a_Player, const AString & a_Command); // tolua_export + CommandResult ForceExecuteCommand(cPlayer & a_Player, const AString & a_Command); // tolua_export /** Removes all console command bindings that the specified plugin has made */ void RemovePluginConsoleCommands(cPlugin * a_Plugin); @@ -341,7 +341,7 @@ private: bool AddPlugin(cPlugin * a_Plugin); /** Tries to match a_Command to the internal table of commands, if a match is found, the corresponding plugin is called. Returns crExecuted if the command is executed. */ - cPluginManager::CommandResult HandleCommand(cPlayer * a_Player, const AString & a_Command, bool a_ShouldCheckPermissions); + CommandResult HandleCommand(cPlayer & a_Player, const AString & a_Command, bool a_ShouldCheckPermissions); } ; // tolua_export diff --git a/src/Bindings/gen_LuaState_Call.lua b/src/Bindings/gen_LuaState_Call.lua deleted file mode 100644 index 7f62573c7..000000000 --- a/src/Bindings/gen_LuaState_Call.lua +++ /dev/null @@ -1,224 +0,0 @@ - --- gen_LuaState_Call.lua - --- Generates the cLuaState::Call() function templates that are included from LuaState.h - ---[[ -The cLuaState::Call() family of functions provides a template-based system for calling any Lua function -either by name or by reference with almost any number of parameters and return values. This is done by -providing a number of overloads of the same name with variable number of template-type parameters. To -separate the arguments from the return values, a special type of cLuaState::cRet is used. ---]] - - - - -print("Generating LuaState_Call.inc . . .") - - - - --- List of combinations (# params, # returns) to generate: -local Combinations = -{ - -- no return values: - {0, 0}, - {1, 0}, - {2, 0}, - {3, 0}, - {4, 0}, - - -- 1 return value: - {0, 1}, - {1, 1}, - {2, 1}, - {3, 1}, - {4, 1}, - {5, 1}, - {6, 1}, - {7, 1}, - {8, 1}, - {9, 1}, - {10, 1}, - - -- 2 return values: - {0, 2}, - {1, 2}, - {2, 2}, - {3, 2}, - {4, 2}, - {5, 2}, - {6, 2}, - {7, 2}, - {8, 2}, - {9, 2}, - - -- Special combinations: - {5, 5}, - {7, 3}, - {8, 3}, - {9, 5}, -} - - - - ---- Writes a single overloaded function definition for the specified number of params and returns into f ---[[ -The format for the generated function is this: -/** Call the specified 3-param 2-return Lua function: -Returns true if call succeeded, false if there was an error. */ -template <typename FnT, typename ParamT1, typename ParamT2, typename ParamT3, typename RetT1, typename RetT2> -bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1, RetT2 & a_Ret2) -{ - UNUSED(a_RetMark); - if (!PushFunction(a_Function)) - { - return false; - } - Push(a_Param1); - Push(a_Param2); - Push(a_Param3); - if (!CallFunction(2)) - { - return false; - } - GetStackValue(-2, a_Ret1); - GetStackValue(-1, a_Ret2); - lua_pop(m_LuaState, 2); - return true; -} -Note especially the negative numbers in GetStackValue() calls. ---]] -local function WriteOverload(f, a_NumParams, a_NumReturns) - -- Write the function doxy-comments: - f:write("/** Call the specified ", a_NumParams, "-param ", a_NumReturns, "-return Lua function:\n") - f:write("Returns true if call succeeded, false if there was an error. */\n") - - -- Write the template <...> line: - f:write("template <typename FnT") - for i = 1, a_NumParams do - f:write(", typename ParamT", i) - end - if (a_NumReturns > 0) then - for i = 1, a_NumReturns do - f:write(", typename RetT", i) - end - end - f:write(">\n") - - -- Write the function signature: - f:write("bool Call(") - f:write("const FnT & a_Function") - for i = 1, a_NumParams do - f:write(", ParamT", i, " a_Param", i) - end - if (a_NumReturns > 0) then - f:write(", const cLuaState::cRet & a_RetMark") - for i = 1, a_NumReturns do - f:write(", RetT", i, " & a_Ret", i) - end - end - f:write(")\n") - - -- Common code: - f:write("{\n") - if (a_NumReturns > 0) then - f:write("\tUNUSED(a_RetMark);\n") - end - f:write("\tif (!PushFunction(a_Function))\n") - f:write("\t{\n") - f:write("\t\treturn false;\n") - f:write("\t}\n") - - -- Push the params: - for i = 1, a_NumParams do - f:write("\tPush(a_Param", i, ");\n") - end - - -- Call the function: - f:write("\tif (!CallFunction(", a_NumReturns, "))\n") - f:write("\t{\n") - f:write("\t\treturn false;\n") - f:write("\t}\n") - - -- Get the return values: - for i = 1, a_NumReturns do - f:write("\tGetStackValue(", -1 - a_NumReturns + i, ", a_Ret", i, ");\n") - end - - -- Pop the returns off the stack, if needed: - if (a_NumReturns > 0) then - f:write("\tlua_pop(m_LuaState, ", a_NumReturns, ");\n") - end - - -- Everything ok: - f:write("\treturn true;\n") - f:write("}\n") - - -- Separate from the next function: - f:write("\n\n\n\n\n") -end - - - - - -local f = assert(io.open("LuaState_Call.inc", "w")) - --- Write file header: -f:write([[ -// LuaState_Call.inc - -// This file is auto-generated by gen_LuaState_Call.lua -// Make changes to the generator instead of to this file! - -// This file contains the various overloads for the cLuaState::Call() function -// Each overload handles a different number of parameters / return values -]]) -f:write("\n\n\n\n\n") - --- Write out a template function for each overload: -for _, combination in ipairs(Combinations) do - WriteOverload(f, combination[1], combination[2]) -end - --- Generate the cLuaState::GetStackValues() multi-param templates: -for i = 2, 6 do - f:write("/** Reads ", i, " consecutive values off the stack */\ntemplate <\n") - - -- Write the template function header: - local txt = {} - for idx = 1, i do - table.insert(txt, "\ttypename ArgT" .. idx) - end - f:write(table.concat(txt, ",\n")) - - -- Write the argument declarations: - txt = {} - f:write("\n>\nvoid GetStackValues(\n\tint a_BeginPos,\n") - for idx = 1, i do - table.insert(txt, "\tArgT" .. idx .. " & Arg" .. idx) - end - f:write(table.concat(txt, ",\n")) - - -- Write the function body: - f:write("\n)\n{\n") - for idx = 1, i do - f:write("\tGetStackValue(a_BeginPos + ", idx - 1, ", Arg", idx, ");\n") - end - f:write("}\n\n\n\n\n\n") -end - --- Close the generated file -f:close() - - - - - -print("LuaState_Call.inc generated.") - - - - diff --git a/src/Bindings/virtual_method_hooks.lua b/src/Bindings/virtual_method_hooks.lua index 8ad30bf78..a52728ff8 100644 --- a/src/Bindings/virtual_method_hooks.lua +++ b/src/Bindings/virtual_method_hooks.lua @@ -7,16 +7,6 @@ local default_private_access = false --- Code generators used by the build --- Note that these are not exactly needed for the bindings, but rather we --- misuse tolua's Lua engine to process files for us -dofile("gen_LuaState_Call.lua") - - - - - - local access = {public = 0, protected = 1, private = 2} function preparse_hook(p) diff --git a/src/BlockEntities/BeaconEntity.cpp b/src/BlockEntities/BeaconEntity.cpp index bcd7878a0..fe5bcf143 100644 --- a/src/BlockEntities/BeaconEntity.cpp +++ b/src/BlockEntities/BeaconEntity.cpp @@ -2,10 +2,11 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "BeaconEntity.h" +#include <algorithm> #include "../BlockArea.h" #include "../Entities/Player.h" -#include <algorithm> + @@ -227,7 +228,7 @@ void cBeaconEntity::GiveEffects(void) virtual bool Item(cPlayer * a_Player) { Vector3d PlayerPosition = Vector3d(a_Player->GetPosition()); - PlayerPosition.y = std::min(static_cast<double>(m_PosY), static_cast<double>(PlayerPosition.y)); + PlayerPosition.y = std::min(static_cast<double>(m_PosY), PlayerPosition.y); // TODO: Vanilla minecraft uses an AABB check instead of a radius one Vector3d BeaconPosition = Vector3d(m_PosX, m_PosY, m_PosZ); diff --git a/src/BlockEntities/BeaconEntity.h b/src/BlockEntities/BeaconEntity.h index 8c2dad254..d1db3a68f 100644 --- a/src/BlockEntities/BeaconEntity.h +++ b/src/BlockEntities/BeaconEntity.h @@ -32,6 +32,8 @@ class cBeaconEntity : public: // tolua_end + BLOCKENTITY_PROTODEF(cBeaconEntity); + cBeaconEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); // cBlockEntity overrides: diff --git a/src/BlockEntities/BlockEntity.h b/src/BlockEntities/BlockEntity.h index 54ab40f3e..b04d20340 100644 --- a/src/BlockEntities/BlockEntity.h +++ b/src/BlockEntities/BlockEntity.h @@ -5,6 +5,28 @@ +/** Place this macro in the declaration of each cBlockEntity descendant. */ +#define BLOCKENTITY_PROTODEF(classname) \ + virtual bool IsA(const char * a_ClassName) const override \ + { \ + return ((strcmp(a_ClassName, #classname) == 0) || super::IsA(a_ClassName)); \ + } \ + virtual const char * GetClass(void) const override \ + { \ + return #classname; \ + } \ + static const char * GetClassStatic(void) \ + { \ + return #classname; \ + } \ + virtual const char * GetParentClass(void) const override \ + { \ + return super::GetClass(); \ + } + + + + namespace Json { @@ -55,6 +77,15 @@ public: { return "cBlockEntity"; } + + /** Returns true if the object is the specified class, or its descendant. */ + virtual bool IsA(const char * a_ClassName) const { return (strcmp(a_ClassName, "cBlockEntity") == 0); } + + /** Returns the name of the tompost class (the most descendant). Used for Lua bindings to push the correct object type. */ + virtual const char * GetClass(void) const { return GetClassStatic(); } + + /** Returns the name of the parent class, or empty string if no parent class. */ + virtual const char * GetParentClass(void) const { return ""; } // tolua_begin diff --git a/src/BlockEntities/BlockEntityWithItems.h b/src/BlockEntities/BlockEntityWithItems.h index 00173cbcb..cb7bc2fb4 100644 --- a/src/BlockEntities/BlockEntityWithItems.h +++ b/src/BlockEntities/BlockEntityWithItems.h @@ -25,10 +25,12 @@ class cBlockEntityWithItems : public cBlockEntityWindowOwner { typedef cBlockEntity super; - + public: // tolua_end + BLOCKENTITY_PROTODEF(cBlockEntityWithItems); + cBlockEntityWithItems( BLOCKTYPE a_BlockType, // Type of the block that the entity represents int a_BlockX, int a_BlockY, int a_BlockZ, // Position of the block entity diff --git a/src/BlockEntities/ChestEntity.h b/src/BlockEntities/ChestEntity.h index af5d851a8..09fffb923 100644 --- a/src/BlockEntities/ChestEntity.h +++ b/src/BlockEntities/ChestEntity.h @@ -33,13 +33,13 @@ public: // tolua_end + BLOCKENTITY_PROTODEF(cChestEntity); + /** Constructor used for normal operation */ cChestEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World, BLOCKTYPE a_Type); virtual ~cChestEntity(); - static const char * GetClassStatic(void) { return "cChestEntity"; } - // cBlockEntity overrides: virtual void SendTo(cClientHandle & a_Client) override; virtual void UsedBy(cPlayer * a_Player) override; diff --git a/src/BlockEntities/CommandBlockEntity.h b/src/BlockEntities/CommandBlockEntity.h index 939f38610..217390293 100644 --- a/src/BlockEntities/CommandBlockEntity.h +++ b/src/BlockEntities/CommandBlockEntity.h @@ -36,6 +36,8 @@ public: // tolua_end + BLOCKENTITY_PROTODEF(cCommandBlockEntity); + /// Creates a new empty command block entity cCommandBlockEntity(int a_X, int a_Y, int a_Z, cWorld * a_World); diff --git a/src/BlockEntities/DispenserEntity.h b/src/BlockEntities/DispenserEntity.h index b33d08342..5ba87b716 100644 --- a/src/BlockEntities/DispenserEntity.h +++ b/src/BlockEntities/DispenserEntity.h @@ -17,11 +17,11 @@ public: // tolua_end + BLOCKENTITY_PROTODEF(cDispenserEntity); + /** Constructor used for normal operation */ cDispenserEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); - static const char * GetClassStatic(void) { return "cDispenserEntity"; } - // tolua_begin /** Spawns a projectile of the given kind in front of the dispenser with the specified speed. */ diff --git a/src/BlockEntities/DropSpenserEntity.cpp b/src/BlockEntities/DropSpenserEntity.cpp index 2cbc947dc..e39b938a0 100644 --- a/src/BlockEntities/DropSpenserEntity.cpp +++ b/src/BlockEntities/DropSpenserEntity.cpp @@ -61,7 +61,7 @@ void cDropSpenserEntity::DropSpense(cChunk & a_Chunk) { // Pick one of the occupied slots: int OccupiedSlots[9]; - uint SlotsCnt = 0; + int SlotsCnt = 0; for (int i = m_Contents.GetNumSlots() - 1; i >= 0; i--) { if (!m_Contents.GetSlot(i).IsEmpty()) diff --git a/src/BlockEntities/DropSpenserEntity.h b/src/BlockEntities/DropSpenserEntity.h index 23f0ae89a..f77a28c28 100644 --- a/src/BlockEntities/DropSpenserEntity.h +++ b/src/BlockEntities/DropSpenserEntity.h @@ -45,11 +45,11 @@ public: // tolua_end + BLOCKENTITY_PROTODEF(cDropSpenserEntity); + cDropSpenserEntity(BLOCKTYPE a_BlockType, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); virtual ~cDropSpenserEntity(); - static const char * GetClassStatic(void) { return "cDropSpenserEntity"; } - // cBlockEntity overrides: virtual bool Tick(float a_Dt, cChunk & a_Chunk) override; virtual void SendTo(cClientHandle & a_Client) override; diff --git a/src/BlockEntities/DropperEntity.h b/src/BlockEntities/DropperEntity.h index 8e07bc6f8..91adf660f 100644 --- a/src/BlockEntities/DropperEntity.h +++ b/src/BlockEntities/DropperEntity.h @@ -25,11 +25,11 @@ public: // tolua_end + BLOCKENTITY_PROTODEF(cDropperEntity); + /// Constructor used for normal operation cDropperEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); - static const char * GetClassStatic(void) { return "cDropperEntity"; } - protected: // cDropSpenserEntity overrides: virtual void DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) override; diff --git a/src/BlockEntities/EnderChestEntity.h b/src/BlockEntities/EnderChestEntity.h index 2719eb5e4..17abd880a 100644 --- a/src/BlockEntities/EnderChestEntity.h +++ b/src/BlockEntities/EnderChestEntity.h @@ -18,11 +18,11 @@ class cEnderChestEntity : public: // tolua_end + BLOCKENTITY_PROTODEF(cEnderChestEntity); + cEnderChestEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); virtual ~cEnderChestEntity(); - static const char * GetClassStatic(void) { return "cEnderChestEntity"; } - // cBlockEntity overrides: virtual void UsedBy(cPlayer * a_Player) override; virtual void SendTo(cClientHandle & a_Client) override { UNUSED(a_Client); } diff --git a/src/BlockEntities/FlowerPotEntity.h b/src/BlockEntities/FlowerPotEntity.h index b68d3b118..5b86621f5 100644 --- a/src/BlockEntities/FlowerPotEntity.h +++ b/src/BlockEntities/FlowerPotEntity.h @@ -36,6 +36,8 @@ public: // tolua_end + BLOCKENTITY_PROTODEF(cFlowerPotEntity); + /** Creates a new flowerpot entity at the specified block coords. a_World may be NULL */ cFlowerPotEntity(int a_BlocX, int a_BlockY, int a_BlockZ, cWorld * a_World); @@ -59,8 +61,6 @@ public: static bool IsFlower(short m_ItemType, short m_ItemData); - static const char * GetClassStatic(void) { return "cFlowerPotEntity"; } - private: cItem m_Item; diff --git a/src/BlockEntities/FurnaceEntity.cpp b/src/BlockEntities/FurnaceEntity.cpp index d165df079..d8ca15c6c 100644 --- a/src/BlockEntities/FurnaceEntity.cpp +++ b/src/BlockEntities/FurnaceEntity.cpp @@ -5,6 +5,7 @@ #include "../UI/Window.h" #include "../Entities/Player.h" #include "../Root.h" +#include "../Chunk.h" @@ -13,8 +14,9 @@ enum { - PROGRESSBAR_SMELTING = 0, - PROGRESSBAR_FUEL = 1, + PROGRESSBAR_FUEL = 0, + PROGRESSBAR_SMELTING = 2, + PROGRESSBAR_SMELTING_CONFIRM = 3, } ; @@ -22,17 +24,15 @@ enum cFurnaceEntity::cFurnaceEntity(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cWorld * a_World) : - super(E_BLOCK_FURNACE, a_BlockX, a_BlockY, a_BlockZ, ContentsWidth, ContentsHeight, a_World), - m_BlockType(a_BlockType), + super(a_BlockType, a_BlockX, a_BlockY, a_BlockZ, ContentsWidth, ContentsHeight, a_World), m_BlockMeta(a_BlockMeta), m_CurrentRecipe(NULL), - m_IsCooking((a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) == E_BLOCK_LIT_FURNACE)), + m_IsDestroyed(false), + m_IsCooking(a_BlockType == E_BLOCK_LIT_FURNACE), m_NeedCookTime(0), m_TimeCooked(0), m_FuelBurnTime(0), - m_TimeBurned(0), - m_LastProgressFuel(0), - m_LastProgressCook(0) + m_TimeBurned(0) { m_Contents.AddListener(*this); } @@ -57,27 +57,28 @@ cFurnaceEntity::~cFurnaceEntity() void cFurnaceEntity::UsedBy(cPlayer * a_Player) { - if (GetWindow() == NULL) + cWindow * Window = GetWindow(); + if (Window == nullptr) { OpenWindow(new cFurnaceWindow(m_PosX, m_PosY, m_PosZ, this)); + Window = GetWindow(); } - cWindow * Window = GetWindow(); - if (Window != NULL) + + if (Window != nullptr) { if (a_Player->GetWindow() != Window) { a_Player->OpenWindow(Window); - BroadcastProgress(PROGRESSBAR_FUEL, static_cast<short>(m_LastProgressFuel)); - BroadcastProgress(PROGRESSBAR_SMELTING, static_cast<short>(m_LastProgressCook)); } } + + UpdateProgressBars(true); } -/// Restarts cooking. Used after the furnace is loaded from storage to set up the internal variables so that cooking continues, if it was active. Returns true if cooking. bool cFurnaceEntity::ContinueCooking(void) { UpdateInput(); @@ -92,14 +93,16 @@ bool cFurnaceEntity::ContinueCooking(void) bool cFurnaceEntity::Tick(float a_Dt, cChunk & a_Chunk) { UNUSED(a_Dt); - UNUSED(a_Chunk); + if (m_FuelBurnTime <= 0) { - // No fuel is burning, reset progressbars and bail out - if ((m_LastProgressCook > 0) || (m_LastProgressFuel > 0)) - { - UpdateProgressBars(); - } + // If a furnace is out of fuel, the progress bar reverses at twice the speed of cooking. + m_TimeCooked = std::max((m_TimeCooked - 2), 0); + + // Reset progressbars, block type, and bail out + m_BlockType = E_BLOCK_FURNACE; + a_Chunk.FastSetBlock(GetRelX(), m_PosY, GetRelZ(), E_BLOCK_FURNACE, m_BlockMeta); + UpdateProgressBars(); return false; } @@ -139,12 +142,12 @@ void cFurnaceEntity::SendTo(cClientHandle & a_Client) -void cFurnaceEntity::BroadcastProgress(int a_ProgressbarID, short a_Value) +void cFurnaceEntity::BroadcastProgress(short a_ProgressbarID, short a_Value) { cWindow * Window = GetWindow(); if (Window != NULL) { - Window->BroadcastProgress(a_ProgressbarID, a_Value); + Window->SetProperty(a_ProgressbarID, a_Value); } } @@ -152,7 +155,6 @@ void cFurnaceEntity::BroadcastProgress(int a_ProgressbarID, short a_Value) -/// One item finished cooking void cFurnaceEntity::FinishOne() { m_TimeCooked = 0; @@ -166,8 +168,6 @@ void cFurnaceEntity::FinishOne() m_Contents.ChangeSlotCount(fsOutput, m_CurrentRecipe->Out->m_ItemCount); } m_Contents.ChangeSlotCount(fsInput, -m_CurrentRecipe->In->m_ItemCount); - - UpdateIsCooking(); } @@ -181,8 +181,7 @@ void cFurnaceEntity::BurnNewFuel(void) if (NewTime == 0) { // The item in the fuel slot is not suitable - m_FuelBurnTime = 0; - m_TimeBurned = 0; + SetBurnTimes(0, 0); SetIsCooking(false); return; } @@ -194,8 +193,7 @@ void cFurnaceEntity::BurnNewFuel(void) } // Burn one new fuel: - m_FuelBurnTime = NewTime; - m_TimeBurned = 0; + SetBurnTimes(NewTime, 0); SetIsCooking(true); if (m_Contents.GetSlot(fsFuel).m_ItemType == E_ITEM_LAVA_BUCKET) { @@ -215,32 +213,18 @@ void cFurnaceEntity::OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum) { super::OnSlotChanged(a_ItemGrid, a_SlotNum); - if (m_World == NULL) + if (m_IsDestroyed) { - // The furnace isn't initialized yet, do no processing return; } ASSERT(a_ItemGrid == &m_Contents); switch (a_SlotNum) { - case fsInput: - { - UpdateInput(); - break; - } - - case fsFuel: - { - UpdateFuel(); - break; - } - - case fsOutput: - { - UpdateOutput(); - break; - } + case fsInput: UpdateInput(); break; + case fsFuel: UpdateFuel(); break; + case fsOutput: UpdateOutput(); break; + default: ASSERT(!"Invalid furnace slot update!"); break; } } @@ -249,7 +233,6 @@ void cFurnaceEntity::OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum) -/// Updates the current recipe, based on the current input void cFurnaceEntity::UpdateInput(void) { if (!m_Contents.GetSlot(fsInput).IsEqual(m_LastInput)) @@ -263,8 +246,8 @@ void cFurnaceEntity::UpdateInput(void) m_CurrentRecipe = FR->GetRecipeFrom(m_Contents.GetSlot(fsInput)); if (!CanCookInputToOutput()) { - // This input cannot be cooked - m_NeedCookTime = 0; + // This input cannot be cooked, reset cook counter immediately + SetCookTimes(0, 0); SetIsCooking(false); } else @@ -284,7 +267,6 @@ void cFurnaceEntity::UpdateInput(void) -/// Called when the fuel slot changes or when the fuel is spent, burns another piece of fuel if appropriate void cFurnaceEntity::UpdateFuel(void) { if (m_FuelBurnTime > m_TimeBurned) @@ -301,14 +283,12 @@ void cFurnaceEntity::UpdateFuel(void) -/// Called when the output slot changes; starts burning if space became available void cFurnaceEntity::UpdateOutput(void) { if (!CanCookInputToOutput()) { // Cannot cook anymore: - m_TimeCooked = 0; - m_NeedCookTime = 0; + SetCookTimes(0, 0); SetIsCooking(false); return; } @@ -324,30 +304,6 @@ void cFurnaceEntity::UpdateOutput(void) -/// Updates the m_IsCooking, based on the input slot, output slot and m_FuelBurnTime / m_TimeBurned -void cFurnaceEntity::UpdateIsCooking(void) -{ - if ( - !CanCookInputToOutput() || // Cannot cook this - (m_FuelBurnTime <= 0) || // No fuel - (m_TimeBurned >= m_FuelBurnTime) // Fuel burnt out - ) - { - // Reset everything - SetIsCooking(false); - m_TimeCooked = 0; - m_NeedCookTime = 0; - return; - } - - SetIsCooking(true); -} - - - - - -/// Returns true if the input can be cooked into output and the item counts allow for another cooking operation bool cFurnaceEntity::CanCookInputToOutput(void) const { if (m_CurrentRecipe == NULL) @@ -382,25 +338,20 @@ bool cFurnaceEntity::CanCookInputToOutput(void) const -/// Broadcasts progressbar updates, if needed -void cFurnaceEntity::UpdateProgressBars(void) +void cFurnaceEntity::UpdateProgressBars(bool a_ForceUpdate) { // In order to preserve bandwidth, an update is sent only every 10th tick - // That's why the comparisons use the division by eight - - int CurFuel = (m_FuelBurnTime > 0) ? (200 - 200 * m_TimeBurned / m_FuelBurnTime) : 0; - if ((CurFuel / 8) != (m_LastProgressFuel / 8)) + if (!a_ForceUpdate && (m_World->GetWorldAge() % 10 != 0)) { - BroadcastProgress(PROGRESSBAR_FUEL, static_cast<short>(CurFuel)); - m_LastProgressFuel = CurFuel; + return; } - int CurCook = (m_NeedCookTime > 0) ? (200 * m_TimeCooked / m_NeedCookTime) : 0; - if ((CurCook / 8) != (m_LastProgressCook / 8)) - { - BroadcastProgress(PROGRESSBAR_SMELTING, static_cast<short>(CurCook)); - m_LastProgressCook = CurCook; - } + int CurFuel = (m_FuelBurnTime > 0) ? 200 - (200 * m_TimeBurned / m_FuelBurnTime) : 0; + BroadcastProgress(PROGRESSBAR_FUEL, static_cast<short>(CurFuel)); + + int CurCook = (m_NeedCookTime > 0) ? (200 * m_TimeCooked / m_NeedCookTime) : 0; + BroadcastProgress(PROGRESSBAR_SMELTING_CONFIRM, 200); // Post 1.8, Mojang requires a random packet with an ID of three and value of 200. Wat. Wat. Wat. + BroadcastProgress(PROGRESSBAR_SMELTING, static_cast<short>(CurCook)); } @@ -413,9 +364,12 @@ void cFurnaceEntity::SetIsCooking(bool a_IsCooking) { return; } - m_IsCooking = a_IsCooking; - // Light or extinguish the furnace: - m_World->FastSetBlock(m_PosX, m_PosY, m_PosZ, m_IsCooking ? E_BLOCK_LIT_FURNACE : E_BLOCK_FURNACE, m_BlockMeta); + // Only light the furnace as it is extinguished only when the fuel runs out, not when cooking stops - handled in this::Tick() + if (m_IsCooking) + { + m_BlockType = E_BLOCK_LIT_FURNACE; + m_World->FastSetBlock(m_PosX, m_PosY, m_PosZ, E_BLOCK_LIT_FURNACE, m_BlockMeta); + } } diff --git a/src/BlockEntities/FurnaceEntity.h b/src/BlockEntities/FurnaceEntity.h index ed3317af6..8e48810ba 100644 --- a/src/BlockEntities/FurnaceEntity.h +++ b/src/BlockEntities/FurnaceEntity.h @@ -38,114 +38,128 @@ public: // tolua_end - /// Constructor used for normal operation + BLOCKENTITY_PROTODEF(cFurnaceEntity); + + /** Constructor used for normal operation */ cFurnaceEntity(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cWorld * a_World); virtual ~cFurnaceEntity(); - static const char * GetClassStatic() { return "cFurnaceEntity"; } - // cBlockEntity overrides: virtual void SendTo(cClientHandle & a_Client) override; virtual bool Tick(float a_Dt, cChunk & a_Chunk) override; virtual void UsedBy(cPlayer * a_Player) override; + virtual void Destroy() override + { + m_IsDestroyed = true; + super::Destroy(); + } - /// Restarts cooking. Used after the furnace is loaded from storage to set up the internal variables so that cooking continues, if it was active. Returns true if cooking. + /** Restarts cooking + Used after the furnace is loaded from storage to set up the internal variables so that cooking continues, if it was active + Returns true if cooking */ bool ContinueCooking(void); - - void ResetCookTimer(); // tolua_begin - /// Returns the item in the input slot + /** Returns the item in the input slot */ const cItem & GetInputSlot(void) const { return GetSlot(fsInput); } - /// Returns the item in the fuel slot + /** Returns the item in the fuel slot */ const cItem & GetFuelSlot(void) const { return GetSlot(fsFuel); } - /// Returns the item in the output slot + /** Returns the item in the output slot */ const cItem & GetOutputSlot(void) const { return GetSlot(fsOutput); } - /// Sets the item in the input slot + /** Sets the item in the input slot */ void SetInputSlot(const cItem & a_Item) { SetSlot(fsInput, a_Item); } - /// Sets the item in the fuel slot + /** Sets the item in the fuel slot */ void SetFuelSlot(const cItem & a_Item) { SetSlot(fsFuel, a_Item); } - /// Sets the item in the output slot + /** Sets the item in the output slot */ void SetOutputSlot(const cItem & a_Item) { SetSlot(fsOutput, a_Item); } - /// Returns the time that the current item has been cooking, in ticks - int GetTimeCooked(void) const {return m_TimeCooked; } + /** Returns the time that the current item has been cooking, in ticks */ + int GetTimeCooked(void) const { return m_TimeCooked; } - /// Returns the time until the current item finishes cooking, in ticks + /** Returns the time until the current item finishes cooking, in ticks */ int GetCookTimeLeft(void) const { return m_NeedCookTime - m_TimeCooked; } - /// Returns the time until the current fuel is depleted, in ticks - int GetFuelBurnTimeLeft(void) const {return m_FuelBurnTime - m_TimeBurned; } + /** Returns the time until the current fuel is depleted, in ticks */ + int GetFuelBurnTimeLeft(void) const { return m_FuelBurnTime - m_TimeBurned; } - /// Returns true if there's time left before the current fuel is depleted + /** Returns true if there's time left before the current fuel is depleted */ bool HasFuelTimeLeft(void) const { return (GetFuelBurnTimeLeft() > 0); } // tolua_end - void SetBurnTimes(int a_FuelBurnTime, int a_TimeBurned) {m_FuelBurnTime = a_FuelBurnTime; m_TimeBurned = a_TimeBurned; } - void SetCookTimes(int a_NeedCookTime, int a_TimeCooked) {m_NeedCookTime = a_NeedCookTime; m_TimeCooked = a_TimeCooked; } + void SetBurnTimes(int a_FuelBurnTime, int a_TimeBurned) + { + m_FuelBurnTime = a_FuelBurnTime; + m_TimeBurned = a_TimeBurned; + } + + void SetCookTimes(int a_NeedCookTime, int a_TimeCooked) + { + m_NeedCookTime = a_NeedCookTime; + m_TimeCooked = a_TimeCooked; + } protected: - - /// Block type of the block currently represented by this entity (changes when furnace lights up) - BLOCKTYPE m_BlockType; - /// Block meta of the block currently represented by this entity + /** Block meta of the block currently represented by this entity */ NIBBLETYPE m_BlockMeta; - /// The recipe for the current input slot + /** The recipe for the current input slot */ const cFurnaceRecipe::cRecipe * m_CurrentRecipe; - /// The item that is being smelted + /** The item that is being smelted */ cItem m_LastInput; + + /** Set to true when the furnace entity has been destroyed to prevent the block being set again */ + bool m_IsDestroyed; - bool m_IsCooking; ///< Set to true if the furnace is cooking an item - - // All timers are in ticks - int m_NeedCookTime; ///< Amount of time needed to fully cook current item - int m_TimeCooked; ///< Amount of time that the current item has been cooking - int m_FuelBurnTime; ///< Amount of time that the current fuel can burn (in total); zero if no fuel burning - int m_TimeBurned; ///< Amount of time that the current fuel has been burning - - int m_LastProgressFuel; ///< Last value sent as the progress for the fuel - int m_LastProgressCook; ///< Last value sent as the progress for the cooking + /** Set to true if the furnace is cooking an item */ + bool m_IsCooking; + /** Amount of ticks needed to fully cook current item */ + int m_NeedCookTime; + + /** Amount of ticks that the current item has been cooking */ + int m_TimeCooked; + + /** Amount of ticks that the current fuel can burn (in total); zero if no fuel burning */ + int m_FuelBurnTime; + + /** Amount of ticks that the current fuel has been burning */ + int m_TimeBurned; - /// Sends the specified progressbar value to all clients of the window - void BroadcastProgress(int a_ProgressbarID, short a_Value); + /** Sends the specified progressbar value to all clients of the window */ + void BroadcastProgress(short a_ProgressbarID, short a_Value); - /// One item finished cooking + /** One item finished cooking */ void FinishOne(); - /// Starts burning a new fuel, if possible + /** Starts burning a new fuel, if possible */ void BurnNewFuel(void); - /// Updates the recipe, based on the current input + /** Updates the recipe, based on the current input */ void UpdateInput(void); - /// Called when the fuel slot changes or when the fuel is spent, burns another piece of fuel if appropriate + /** Called when the fuel slot changes or when the fuel is spent, burns another piece of fuel if appropriate */ void UpdateFuel(void); - /// Called when the output slot changes + /** Called when the output slot changes */ void UpdateOutput(void); - /// Updates the m_IsCooking, based on the input slot, output slot and m_FuelBurnTime / m_TimeBurned - void UpdateIsCooking(void); - - /// Returns true if the input can be cooked into output and the item counts allow for another cooking operation + /** Returns true if the input can be cooked into output and the item counts allow for another cooking operation */ bool CanCookInputToOutput(void) const; - /// Broadcasts progressbar updates, if needed - void UpdateProgressBars(void); + /** Broadcasts progressbar updates, if needed */ + void UpdateProgressBars(bool a_ForceUpdate = false); - /// Sets the m_IsCooking variable, updates the furnace block type based on the value + /** Sets the m_IsCooking variable, updates the furnace block type based on the value */ void SetIsCooking(bool a_IsCooking); // cItemGrid::cListener overrides: diff --git a/src/BlockEntities/HopperEntity.h b/src/BlockEntities/HopperEntity.h index 5d06581c2..7070bbad3 100644 --- a/src/BlockEntities/HopperEntity.h +++ b/src/BlockEntities/HopperEntity.h @@ -31,6 +31,8 @@ public: // tolua_end + BLOCKENTITY_PROTODEF(cHopperEntity); + /// Constructor used for normal operation cHopperEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); @@ -40,8 +42,6 @@ public: */ bool GetOutputBlockPos(NIBBLETYPE a_BlockMeta, int & a_OutputX, int & a_OutputY, int & a_OutputZ); - static const char * GetClassStatic(void) { return "cHopperEntity"; } - protected: Int64 m_LastMoveItemsInTick; diff --git a/src/BlockEntities/JukeboxEntity.h b/src/BlockEntities/JukeboxEntity.h index 49d2faa89..7a69d6499 100644 --- a/src/BlockEntities/JukeboxEntity.h +++ b/src/BlockEntities/JukeboxEntity.h @@ -26,6 +26,8 @@ public: // tolua_end + BLOCKENTITY_PROTODEF(cJukeboxEntity); + cJukeboxEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); virtual ~cJukeboxEntity(); @@ -51,8 +53,6 @@ public: // tolua_end - static const char * GetClassStatic(void) { return "cJukeboxEntity"; } - virtual void UsedBy(cPlayer * a_Player) override; virtual void SendTo(cClientHandle &) override {} diff --git a/src/BlockEntities/MobHeadEntity.h b/src/BlockEntities/MobHeadEntity.h index fcdeaa8a6..7f69bc5ad 100644 --- a/src/BlockEntities/MobHeadEntity.h +++ b/src/BlockEntities/MobHeadEntity.h @@ -34,6 +34,8 @@ public: // tolua_end + BLOCKENTITY_PROTODEF(cMobHeadEntity); + /** Creates a new mob head entity at the specified block coords. a_World may be NULL */ cMobHeadEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); @@ -62,8 +64,6 @@ public: virtual void UsedBy(cPlayer * a_Player) override; virtual void SendTo(cClientHandle & a_Client) override; - static const char * GetClassStatic(void) { return "cMobHeadEntity"; } - private: eMobHeadType m_Type; diff --git a/src/BlockEntities/NoteEntity.h b/src/BlockEntities/NoteEntity.h index d1ffa126a..74dbde046 100644 --- a/src/BlockEntities/NoteEntity.h +++ b/src/BlockEntities/NoteEntity.h @@ -40,6 +40,8 @@ public: // tolua_end + BLOCKENTITY_PROTODEF(cNoteEntity); + /// Creates a new note entity. a_World may be NULL cNoteEntity(int a_X, int a_Y, int a_Z, cWorld * a_World); virtual ~cNoteEntity() {} @@ -64,8 +66,6 @@ public: } } - static const char * GetClassStatic(void) { return "cNoteEntity"; } - private: char m_Pitch; } ; // tolua_export diff --git a/src/BlockEntities/SignEntity.h b/src/BlockEntities/SignEntity.h index 53c43b758..be13c7a32 100644 --- a/src/BlockEntities/SignEntity.h +++ b/src/BlockEntities/SignEntity.h @@ -34,6 +34,8 @@ public: // tolua_end + BLOCKENTITY_PROTODEF(cSignEntity); + /// Creates a new empty sign entity at the specified block coords and block type (wall or standing). a_World may be NULL cSignEntity(BLOCKTYPE a_BlockType, int a_X, int a_Y, int a_Z, cWorld * a_World); @@ -53,8 +55,6 @@ public: virtual void UsedBy(cPlayer * a_Player) override; virtual void SendTo(cClientHandle & a_Client) override; - static const char * GetClassStatic(void) { return "cSignEntity"; } - private: AString m_Line[4]; diff --git a/src/BlockInServerPluginInterface.h b/src/BlockInServerPluginInterface.h index e82435364..70c9944a8 100644 --- a/src/BlockInServerPluginInterface.h +++ b/src/BlockInServerPluginInterface.h @@ -6,14 +6,30 @@ #include "Root.h" #include "Bindings/PluginManager.h" -class cBlockInServerPluginInterface : public cBlockPluginInterface + + + + +class cBlockInServerPluginInterface : + public cBlockPluginInterface { public: cBlockInServerPluginInterface(cWorld & a_World) : m_World(a_World) {} + + virtual bool CallHookBlockSpread(int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source) + { + return cPluginManager::Get()->CallHookBlockSpread(m_World, a_BlockX, a_BlockY, a_BlockZ, a_Source); + } + virtual bool CallHookBlockToPickups(cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups) override { - return cRoot::Get()->GetPluginManager()->CallHookBlockToPickups(&m_World, a_Digger, a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_Pickups); + return cPluginManager::Get()->CallHookBlockToPickups(m_World, a_Digger, a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_Pickups); } + private: cWorld & m_World; }; + + + + diff --git a/src/Blocks/BlockDirt.h b/src/Blocks/BlockDirt.h index 19f889372..89dfc963d 100644 --- a/src/Blocks/BlockDirt.h +++ b/src/Blocks/BlockDirt.h @@ -89,7 +89,7 @@ public: Chunk->GetBlockTypeMeta(BlockX, BlockY + 1, BlockZ, AboveDest, AboveMeta); if (cBlockInfo::GetHandler(AboveDest)->CanDirtGrowGrass(AboveMeta)) { - if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread(Chunk->GetWorld(), Chunk->GetPosX() * cChunkDef::Width + BlockX, BlockY, Chunk->GetPosZ() * cChunkDef::Width + BlockZ, ssGrassSpread)) + if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread(*Chunk->GetWorld(), Chunk->GetPosX() * cChunkDef::Width + BlockX, BlockY, Chunk->GetPosZ() * cChunkDef::Width + BlockZ, ssGrassSpread)) { Chunk->FastSetBlock(BlockX, BlockY, BlockZ, E_BLOCK_GRASS, 0); } diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index 904e0a921..b6ef5dd6f 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -4,6 +4,7 @@ #include "../Item.h" #include "../World.h" #include "../Chunk.h" +#include "BlockPluginInterface.h" #include "BlockAnvil.h" #include "BlockBed.h" #include "BlockBigFlower.h" @@ -82,7 +83,6 @@ #include "BlockWorkbench.h" -#include "BlockPluginInterface.h" diff --git a/src/Blocks/BlockLever.h b/src/Blocks/BlockLever.h index 3b63b396c..f5bedea6c 100644 --- a/src/Blocks/BlockLever.h +++ b/src/Blocks/BlockLever.h @@ -1,9 +1,9 @@ #pragma once #include "BlockHandler.h" +#include "../Chunk.h" #include "MetaRotator.h" - - +#include "BlockSlab.h" class cBlockLeverHandler : @@ -93,13 +93,35 @@ public: virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { - NIBBLETYPE Meta; - a_Chunk.UnboundedRelGetBlockMeta(a_RelX, a_RelY, a_RelZ, Meta); + NIBBLETYPE Meta = a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ); + + eBlockFace Face = BlockMetaDataToBlockFace(Meta); + + AddFaceDirection(a_RelX, a_RelY, a_RelZ, Face, true); + + if ((a_RelY < 0) || (a_RelY >= cChunkDef::Height -1)) + { + return false; + } + + BLOCKTYPE BlockIsOn; + a_Chunk.UnboundedRelGetBlock(a_RelX, a_RelY, a_RelZ, BlockIsOn, Meta); - AddFaceDirection(a_RelX, a_RelY, a_RelZ, BlockMetaDataToBlockFace(Meta), true); - BLOCKTYPE BlockIsOn; a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockIsOn); - return (a_RelY > 0) && cBlockInfo::FullyOccupiesVoxel(BlockIsOn); + if (cBlockInfo::FullyOccupiesVoxel(BlockIsOn)) + { + return true; + } + else if (cBlockSlabHandler::IsAnySlabType(BlockIsOn)) + { + // Check if the slab is turned up side down + if (((Meta & 0x08) == 0x08) && (Face == BLOCK_FACE_TOP)) + { + return true; + } + } + + return false; } diff --git a/src/Blocks/BlockPluginInterface.h b/src/Blocks/BlockPluginInterface.h index 3a36c40b1..b769bcf3e 100644 --- a/src/Blocks/BlockPluginInterface.h +++ b/src/Blocks/BlockPluginInterface.h @@ -1,7 +1,11 @@ #pragma once -/** This interface is used to decouple block handlers from the cPluginManager dependancy through cWorld. + + + + +/** This interface is used to decouple block handlers from the cPluginManager dependency through cWorld. The block handlers call this interface, which is then implemented by the specific classes that the caller provides. */ @@ -10,5 +14,10 @@ class cBlockPluginInterface public: virtual ~cBlockPluginInterface() {} + virtual bool CallHookBlockSpread(int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source) = 0; virtual bool CallHookBlockToPickups(cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups) = 0; }; + + + + diff --git a/src/Blocks/BlockRedstone.h b/src/Blocks/BlockRedstone.h index 37d61ed73..2785eb479 100644 --- a/src/Blocks/BlockRedstone.h +++ b/src/Blocks/BlockRedstone.h @@ -3,6 +3,7 @@ #include "BlockHandler.h" #include "../World.h" +#include "BlockSlab.h" @@ -16,11 +17,33 @@ public: : cBlockHandler(a_BlockType) { } - + + virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { - return ((a_RelY > 0) && cBlockInfo::FullyOccupiesVoxel(a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ))); + if (a_RelY <= 0) + { + return false; + } + + BLOCKTYPE BelowBlock; + NIBBLETYPE BelowBlockMeta; + a_Chunk.GetBlockTypeMeta(a_RelX, a_RelY - 1, a_RelZ, BelowBlock, BelowBlockMeta); + + if (cBlockInfo::FullyOccupiesVoxel(BelowBlock)) + { + return true; + } + else if (cBlockSlabHandler::IsAnySlabType(BelowBlock)) + { + // Check if the slab is turned up side down + if ((BelowBlockMeta & 0x08) == 0x08) + { + return true; + } + } + return false; } diff --git a/src/Blocks/BlockRedstoneRepeater.h b/src/Blocks/BlockRedstoneRepeater.h index 1eb67f714..e8262dc40 100644 --- a/src/Blocks/BlockRedstoneRepeater.h +++ b/src/Blocks/BlockRedstoneRepeater.h @@ -5,6 +5,7 @@ #include "Chunk.h" #include "MetaRotator.h" #include "ChunkInterface.h" +#include "BlockSlab.h" @@ -44,6 +45,7 @@ public: } + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { // Reset meta to zero @@ -59,7 +61,28 @@ public: virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { - return ((a_RelY > 0) && cBlockInfo::IsSolid(a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ))); + if (a_RelY <= 0) + { + return false; + } + + BLOCKTYPE BelowBlock; + NIBBLETYPE BelowBlockMeta; + a_Chunk.GetBlockTypeMeta(a_RelX, a_RelY - 1, a_RelZ, BelowBlock, BelowBlockMeta); + + if (cBlockInfo::FullyOccupiesVoxel(BelowBlock)) + { + return true; + } + else if (cBlockSlabHandler::IsAnySlabType(BelowBlock)) + { + // Check if the slab is turned up side down + if ((BelowBlockMeta & 0x08) == 0x08) + { + return true; + } + } + return false; } diff --git a/src/Blocks/BlockSlab.h b/src/Blocks/BlockSlab.h index ffe2414f7..d762154df 100644 --- a/src/Blocks/BlockSlab.h +++ b/src/Blocks/BlockSlab.h @@ -13,6 +13,7 @@ #include "../Items/ItemHandler.h" #include "Root.h" #include "ChunkInterface.h" +#include "../Entities/Player.h" diff --git a/src/Blocks/BlockVine.h b/src/Blocks/BlockVine.h index 06d84f2d4..213324cc1 100644 --- a/src/Blocks/BlockVine.h +++ b/src/Blocks/BlockVine.h @@ -166,23 +166,31 @@ public: return false; } + virtual void OnUpdate(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_BlockPluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) { UNUSED(a_ChunkInterface); UNUSED(a_WorldInterface); - UNUSED(a_BlockPluginInterface); + // Vine cannot grow down if at the bottom: + if (a_RelY < 1) + { + return; + } + + // Grow one block down, if possible: BLOCKTYPE Block; a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY - 1, a_RelZ, Block); if (Block == E_BLOCK_AIR) { - if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread((cWorld*) &a_WorldInterface, a_RelX + a_Chunk.GetPosX() * cChunkDef::Width, a_RelY - 1, a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width, ssVineSpread)) + if (!a_BlockPluginInterface.CallHookBlockSpread(a_RelX + a_Chunk.GetPosX() * cChunkDef::Width, a_RelY - 1, a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width, ssVineSpread)) { a_Chunk.UnboundedRelSetBlock(a_RelX, a_RelY - 1, a_RelZ, E_BLOCK_VINES, a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ)); } } } + virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override { return ((a_Meta >> 1) | (a_Meta << 3)) & 0x0f; // Rotate bits to the right diff --git a/src/CheckBasicStyle.lua b/src/CheckBasicStyle.lua index b244b1fbc..76ae8c325 100644 --- a/src/CheckBasicStyle.lua +++ b/src/CheckBasicStyle.lua @@ -41,6 +41,7 @@ local g_ShouldProcessExt = --- The list of files not to be processed: local g_IgnoredFiles = { + "Bindings/Bindings.h", "Bindings/Bindings.cpp", "LeakFinder.cpp", "LeakFinder.h", diff --git a/src/Chunk.cpp b/src/Chunk.cpp index 96b8eda4e..7d6d88b26 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -119,7 +119,7 @@ cChunk::cChunk( cChunk::~cChunk() { - cPluginManager::Get()->CallHookChunkUnloaded(m_World, m_PosX, m_PosZ); + cPluginManager::Get()->CallHookChunkUnloaded(*m_World, m_PosX, m_PosZ); // LOGINFO("### delete cChunk() (%i, %i) from %p, thread 0x%x ###", m_PosX, m_PosZ, this, GetCurrentThreadId()); @@ -333,7 +333,7 @@ void cChunk::SetAllData(cSetChunkData & a_SetChunkData) { BLOCKTYPE EntityBlockType = (*itr)->GetBlockType(); BLOCKTYPE WorldBlockType = GetBlock((*itr)->GetRelX(), (*itr)->GetPosY(), (*itr)->GetRelZ()); - ASSERT(EntityBlockType == WorldBlockType); + ASSERT(WorldBlockType == EntityBlockType); } // for itr - m_BlockEntities #endif // _DEBUG @@ -1750,11 +1750,11 @@ void cChunk::SetAreaBiome(int a_MinRelX, int a_MaxRelX, int a_MinRelZ, int a_Max -void cChunk::CollectPickupsByPlayer(cPlayer * a_Player) +void cChunk::CollectPickupsByPlayer(cPlayer & a_Player) { - double PosX = a_Player->GetPosX(); - double PosY = a_Player->GetPosY(); - double PosZ = a_Player->GetPosZ(); + double PosX = a_Player.GetPosX(); + double PosY = a_Player.GetPosY(); + double PosZ = a_Player.GetPosZ(); for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr) { @@ -2614,7 +2614,7 @@ BLOCKTYPE cChunk::GetBlock(int a_RelX, int a_RelY, int a_RelZ) const -void cChunk::GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) +void cChunk::GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) const { a_BlockType = GetBlock(a_RelX, a_RelY, a_RelZ); a_BlockMeta = m_ChunkData.GetMeta(a_RelX, a_RelY, a_RelZ); diff --git a/src/Chunk.h b/src/Chunk.h index bc66b6528..5f8fcaf7b 100644 --- a/src/Chunk.h +++ b/src/Chunk.h @@ -33,7 +33,7 @@ class cChunkMap; class cBeaconEntity; class cBoundingBox; class cChestEntity; -class cCHunkDataCallback; +class cChunkDataCallback; class cCommandBlockEntity; class cDispenserEntity; class cFurnaceEntity; @@ -186,7 +186,7 @@ public: void FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta, bool a_SendToClients = true); // Doesn't force block updates on neighbors, use for simple changes such as grass growing etc. BLOCKTYPE GetBlock(int a_RelX, int a_RelY, int a_RelZ) const; BLOCKTYPE GetBlock(const Vector3i & a_RelCoords) const { return GetBlock(a_RelCoords.x, a_RelCoords.y, a_RelCoords.z); } - void GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta); + void GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) const; void GetBlockInfo (int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_Meta, NIBBLETYPE & a_SkyLight, NIBBLETYPE & a_BlockLight); /** Returns the chunk into which the specified block belongs, by walking the neighbors. @@ -218,7 +218,7 @@ public: Sends the chunk to all relevant clients. */ void SetAreaBiome(int a_MinRelX, int a_MaxRelX, int a_MinRelZ, int a_MaxRelZ, EMCSBiome a_Biome); - void CollectPickupsByPlayer(cPlayer * a_Player); + void CollectPickupsByPlayer(cPlayer & a_Player); /** Sets the sign text. Returns true if successful. Also sends update packets to all clients in the chunk */ bool SetSignLines(int a_RelX, int a_RelY, int a_RelZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4); diff --git a/src/ChunkDef.h b/src/ChunkDef.h index 6ffe47ffb..260aace58 100644 --- a/src/ChunkDef.h +++ b/src/ChunkDef.h @@ -226,7 +226,7 @@ public: { if ((a_BlockIdx > -1) && (a_BlockIdx < NumBlocks)) { - if (static_cast<size_t>((a_BlockIdx / 2)) >= a_Buffer.size()) + if (static_cast<size_t>(a_BlockIdx / 2) >= a_Buffer.size()) { return (a_IsSkyLightNibble ? 0xff : 0); } diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 299fe0eca..6f56b23e0 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -954,7 +954,7 @@ void cChunkMap::SetChunkData(cSetChunkData & a_SetChunkData) } // Notify plugins of the chunk becoming available - cPluginManager::Get()->CallHookChunkAvailable(m_World, ChunkX, ChunkZ); + cPluginManager::Get()->CallHookChunkAvailable(*m_World, ChunkX, ChunkZ); } @@ -1145,11 +1145,11 @@ void cChunkMap::FastSetBlocks(sSetBlockList & a_BlockList) -void cChunkMap::CollectPickupsByPlayer(cPlayer * a_Player) +void cChunkMap::CollectPickupsByPlayer(cPlayer & a_Player) { - int BlockX = (int)(a_Player->GetPosX()); // Truncating doesn't matter much; we're scanning entire chunks anyway - int BlockY = (int)(a_Player->GetPosY()); - int BlockZ = (int)(a_Player->GetPosZ()); + int BlockX = (int)(a_Player.GetPosX()); // Truncating doesn't matter much; we're scanning entire chunks anyway + int BlockY = (int)(a_Player.GetPosY()); + int BlockZ = (int)(a_Player.GetPosZ()); int ChunkX = 0, ChunkZ = 0; cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); int OtherChunkX = ChunkX + ((BlockX > 8) ? 1 : -1); @@ -2973,7 +2973,7 @@ void cChunkMap::cChunkLayer::UnloadUnusedChunks(void) if ( (m_Chunks[i] != NULL) && // Is valid (m_Chunks[i]->CanUnload()) && // Can unload - !cPluginManager::Get()->CallHookChunkUnloading(m_Parent->GetWorld(), m_Chunks[i]->GetPosX(), m_Chunks[i]->GetPosZ()) // Plugins agree + !cPluginManager::Get()->CallHookChunkUnloading(*(m_Parent->GetWorld()), m_Chunks[i]->GetPosX(), m_Chunks[i]->GetPosZ()) // Plugins agree ) { // The cChunk destructor calls our GetChunk() while removing its entities @@ -2987,6 +2987,8 @@ void cChunkMap::cChunkLayer::UnloadUnusedChunks(void) + + void cChunkMap::FastSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) { cCSLock Lock(m_CSFastSetBlock); diff --git a/src/ChunkMap.h b/src/ChunkMap.h index 6e92833f1..38e7f4052 100644 --- a/src/ChunkMap.h +++ b/src/ChunkMap.h @@ -144,7 +144,7 @@ public: void FastSetQueuedBlocks(); void FastSetBlocks (sSetBlockList & a_BlockList); - void CollectPickupsByPlayer(cPlayer * a_Player); + void CollectPickupsByPlayer(cPlayer & a_Player); BLOCKTYPE GetBlock (int a_BlockX, int a_BlockY, int a_BlockZ); NIBBLETYPE GetBlockMeta (int a_BlockX, int a_BlockY, int a_BlockZ); diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 3b677460b..f15d845ef 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -248,9 +248,12 @@ AString cClientHandle::GenerateOfflineUUID(const AString & a_Username) // xxxxxxxx-xxxx-3xxx-yxxx-xxxxxxxxxxxx where x is any hexadecimal digit and y is one of 8, 9, A, or B // Note that we generate a short UUID (without the dashes) + // First make the username lowercase: + AString lcUsername = StrToLower(a_Username); + // Generate an md5 checksum, and use it as base for the ID: unsigned char MD5[16]; - md5((const unsigned char *)a_Username.c_str(), a_Username.length(), MD5); + md5((const unsigned char *)lcUsername.c_str(), lcUsername.length(), MD5); MD5[6] &= 0x0f; // Need to trim to 4 bits only... MD5[8] &= 0x0f; // ... otherwise %01x overflows into two chars return Printf("%02x%02x%02x%02x%02x%02x3%01x%02x8%01x%02x%02x%02x%02x%02x%02x%02x", @@ -537,9 +540,11 @@ void cClientHandle::RemoveFromAllChunks() } { + // Reset all chunk lists: cCSLock Lock(m_CSChunkLists); m_LoadedChunks.clear(); m_ChunksToSend.clear(); + m_SentChunks.clear(); // Also reset the LastStreamedChunk coords to bogus coords, // so that all chunks are streamed in subsequent StreamChunks() call (FS #407) @@ -593,7 +598,7 @@ bool cClientHandle::HandleLogin(int a_ProtocolVersion, const AString & a_Usernam m_Username = a_Username; // Let the plugins know about this event, they may refuse the player: - if (cRoot::Get()->GetPluginManager()->CallHookLogin(this, a_ProtocolVersion, a_Username)) + if (cRoot::Get()->GetPluginManager()->CallHookLogin(*this, a_ProtocolVersion, a_Username)) { Destroy(); return false; @@ -1712,7 +1717,7 @@ void cClientHandle::HandleKeepAlive(int a_KeepAliveID) bool cClientHandle::HandleHandshake(const AString & a_Username) { - if (!cRoot::Get()->GetPluginManager()->CallHookHandshake(this, a_Username)) + if (!cRoot::Get()->GetPluginManager()->CallHookHandshake(*this, a_Username)) { if (cRoot::Get()->GetServer()->GetNumPlayers() >= cRoot::Get()->GetServer()->GetMaxPlayers()) { @@ -2024,7 +2029,17 @@ void cClientHandle::SendBlockBreakAnim(int a_EntityID, int a_BlockX, int a_Block void cClientHandle::SendBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) { - m_Protocol->SendBlockChange(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); + int ChunkX, ChunkZ = 0; + cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); + cChunkCoords ChunkCoords = cChunkCoords(ChunkX, ChunkZ); + + // Do not send block changes in chunks that weren't sent to the client yet: + cCSLock Lock(m_CSChunkLists); + if (std::find(m_SentChunks.begin(), m_SentChunks.end(), ChunkCoords) != m_SentChunks.end()) + { + Lock.Unlock(); + m_Protocol->SendBlockChange(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); + } } @@ -2034,8 +2049,15 @@ void cClientHandle::SendBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, BL void cClientHandle::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) { ASSERT(!a_Changes.empty()); // We don't want to be sending empty change packets! - - m_Protocol->SendBlockChanges(a_ChunkX, a_ChunkZ, a_Changes); + + // Do not send block changes in chunks that weren't sent to the client yet: + cChunkCoords ChunkCoords = cChunkCoords(a_ChunkX, a_ChunkZ); + cCSLock Lock(m_CSChunkLists); + if (std::find(m_SentChunks.begin(), m_SentChunks.end(), ChunkCoords) != m_SentChunks.end()) + { + Lock.Unlock(); + m_Protocol->SendBlockChanges(a_ChunkX, a_ChunkZ, a_Changes); + } } @@ -2099,6 +2121,12 @@ void cClientHandle::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializ m_Protocol->SendChunkData(a_ChunkX, a_ChunkZ, a_Serializer); + // Add the chunk to the list of chunks sent to the player: + { + cCSLock Lock(m_CSChunkLists); + m_SentChunks.push_back(cChunkCoords(a_ChunkX, a_ChunkZ)); + } + // If it is the chunk the player's in, make them spawn (in the tick thread): if ((m_State == csAuthenticated) || (m_State == csDownloadingWorld)) { @@ -2628,6 +2656,12 @@ void cClientHandle::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_D void cClientHandle::SendUnloadChunk(int a_ChunkX, int a_ChunkZ) { + // Remove the chunk from the list of chunks sent to the client: + { + cCSLock Lock(m_CSChunkLists); + m_SentChunks.remove(cChunkCoords(a_ChunkX, a_ChunkZ)); + } + m_Protocol->SendUnloadChunk(a_ChunkX, a_ChunkZ); } @@ -2702,7 +2736,7 @@ void cClientHandle::SendWindowOpen(const cWindow & a_Window) -void cClientHandle::SendWindowProperty(const cWindow & a_Window, int a_Property, int a_Value) +void cClientHandle::SendWindowProperty(const cWindow & a_Window, short a_Property, short a_Value) { m_Protocol->SendWindowProperty(a_Window, a_Property, a_Value); } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index a9cc29d50..80cf16963 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -204,7 +204,7 @@ public: void SendWholeInventory (const cWindow & a_Window); void SendWindowClose (const cWindow & a_Window); void SendWindowOpen (const cWindow & a_Window); - void SendWindowProperty (const cWindow & a_Window, int a_Property, int a_Value); + void SendWindowProperty (const cWindow & a_Window, short a_Property, short a_Value); // tolua_begin const AString & GetUsername(void) const; @@ -343,6 +343,7 @@ private: cCriticalSection m_CSChunkLists; cChunkCoordsList m_LoadedChunks; // Chunks that the player belongs to cChunkCoordsList m_ChunksToSend; // Chunks that need to be sent to the player (queued because they weren't generated yet or there's not enough time to send them) + cChunkCoordsList m_SentChunks; // Chunks that are currently sent to the client cProtocol * m_Protocol; diff --git a/src/CraftingRecipes.cpp b/src/CraftingRecipes.cpp index ed3409207..0828a6c74 100644 --- a/src/CraftingRecipes.cpp +++ b/src/CraftingRecipes.cpp @@ -280,10 +280,10 @@ cCraftingRecipes::~cCraftingRecipes() -void cCraftingRecipes::GetRecipe(const cPlayer * a_Player, const cCraftingGrid & a_CraftingGrid, cCraftingRecipe & a_Recipe) +void cCraftingRecipes::GetRecipe(cPlayer & a_Player, cCraftingGrid & a_CraftingGrid, cCraftingRecipe & a_Recipe) { // Allow plugins to intercept recipes using a pre-craft hook: - if (cRoot::Get()->GetPluginManager()->CallHookPreCrafting(a_Player, &a_CraftingGrid, &a_Recipe)) + if (cRoot::Get()->GetPluginManager()->CallHookPreCrafting(a_Player, a_CraftingGrid, a_Recipe)) { return; } @@ -294,7 +294,7 @@ void cCraftingRecipes::GetRecipe(const cPlayer * a_Player, const cCraftingGrid & if (Recipe.get() == NULL) { // Allow plugins to intercept a no-recipe-found situation: - cRoot::Get()->GetPluginManager()->CallHookCraftingNoRecipe(a_Player, &a_CraftingGrid, &a_Recipe); + cRoot::Get()->GetPluginManager()->CallHookCraftingNoRecipe(a_Player, a_CraftingGrid, &a_Recipe); return; } for (cRecipeSlots::const_iterator itr = Recipe->m_Ingredients.begin(); itr != Recipe->m_Ingredients.end(); ++itr) @@ -304,7 +304,7 @@ void cCraftingRecipes::GetRecipe(const cPlayer * a_Player, const cCraftingGrid & a_Recipe.SetResult(Recipe->m_Result); // Allow plugins to intercept recipes after they are processed: - cRoot::Get()->GetPluginManager()->CallHookPostCrafting(a_Player, &a_CraftingGrid, &a_Recipe); + cRoot::Get()->GetPluginManager()->CallHookPostCrafting(a_Player, a_CraftingGrid, a_Recipe); } diff --git a/src/CraftingRecipes.h b/src/CraftingRecipes.h index fe1e15817..5ebabe098 100644 --- a/src/CraftingRecipes.h +++ b/src/CraftingRecipes.h @@ -115,7 +115,7 @@ public: ~cCraftingRecipes(); /// Returns the recipe for current crafting grid. Doesn't modify the grid. Clears a_Recipe if no recipe found. - void GetRecipe(const cPlayer * a_Player, const cCraftingGrid & a_CraftingGrid, cCraftingRecipe & a_Recipe); + void GetRecipe(cPlayer & a_Player, cCraftingGrid & a_CraftingGrid, cCraftingRecipe & a_Recipe); protected: diff --git a/src/Enchantments.cpp b/src/Enchantments.cpp index 264878c22..80a9810b6 100644 --- a/src/Enchantments.cpp +++ b/src/Enchantments.cpp @@ -6,6 +6,7 @@ #include "Enchantments.h" #include "WorldStorage/FastNBT.h" #include "FastRandom.h" +#include "Noise.h" @@ -1019,3 +1020,30 @@ cEnchantments cEnchantments::GetRandomEnchantmentFromVector(cWeightedEnchantment + +cEnchantments cEnchantments::GenerateEnchantmentFromVector(cWeightedEnchantments & a_Enchantments, int a_Seed) +{ + int AllWeights = 0; + for (const auto Enchantment : a_Enchantments) + { + AllWeights += Enchantment.m_Weight; + } + + cNoise Noise(a_Seed); + int RandomNumber = Noise.IntNoise1DInt(AllWeights) / 7 % AllWeights; + + for (const auto Enchantment : a_Enchantments) + { + RandomNumber -= Enchantment.m_Weight; + if (RandomNumber < 0) + { + return Enchantment.m_Enchantments; + } + } + + return cEnchantments(); +} + + + + diff --git a/src/Enchantments.h b/src/Enchantments.h index 824f6aa55..e4390a5f2 100644 --- a/src/Enchantments.h +++ b/src/Enchantments.h @@ -128,6 +128,9 @@ public: /** Gets random enchantment from Vector and returns it */ static cEnchantments GetRandomEnchantmentFromVector(cWeightedEnchantments & a_Enchantments); + /** Returns an enchantment from a Vector using cNoise. Mostly used for generators.*/ + static cEnchantments GenerateEnchantmentFromVector(cWeightedEnchantments & a_Enchantments, int a_Seed); + /** Returns true if a_Other doesn't contain exactly the same enchantments and levels */ bool operator !=(const cEnchantments & a_Other) const; diff --git a/src/Entities/ArrowEntity.cpp b/src/Entities/ArrowEntity.cpp index c265c5043..7e429c62e 100644 --- a/src/Entities/ArrowEntity.cpp +++ b/src/Entities/ArrowEntity.cpp @@ -149,14 +149,14 @@ void cArrowEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) -void cArrowEntity::CollectedBy(cPlayer * a_Dest) +void cArrowEntity::CollectedBy(cPlayer & a_Dest) { - if (m_IsInGround && !m_bIsCollected && CanPickup(*a_Dest)) + if (m_IsInGround && !m_bIsCollected && CanPickup(a_Dest)) { // Do not add the arrow to the inventory when the player is in creative: - if (!a_Dest->IsGameModeCreative()) + if (!a_Dest.IsGameModeCreative()) { - int NumAdded = a_Dest->GetInventory().AddItem(E_ITEM_ARROW); + int NumAdded = a_Dest.GetInventory().AddItem(E_ITEM_ARROW); if (NumAdded == 0) { // No space in the inventory @@ -164,7 +164,7 @@ void cArrowEntity::CollectedBy(cPlayer * a_Dest) } } - GetWorld()->BroadcastCollectEntity(*this, *a_Dest); + GetWorld()->BroadcastCollectEntity(*this, a_Dest); GetWorld()->BroadcastSoundEffect("random.pop", GetPosX(), GetPosY(), GetPosZ(), 0.5, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64)); m_bIsCollected = true; } @@ -229,3 +229,7 @@ void cArrowEntity::Tick(float a_Dt, cChunk & a_Chunk) } } } + + + + diff --git a/src/Entities/ArrowEntity.h b/src/Entities/ArrowEntity.h index a1e7a17e7..1e4d8eebb 100644 --- a/src/Entities/ArrowEntity.h +++ b/src/Entities/ArrowEntity.h @@ -97,7 +97,7 @@ protected: // cProjectileEntity overrides: virtual void OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace) override; virtual void OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) override; - virtual void CollectedBy(cPlayer * a_Player) override; + virtual void CollectedBy(cPlayer & a_Player) override; virtual void Tick(float a_Dt, cChunk & a_Chunk) override; }; // tolua_export diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h index 858f760ce..451ac3711 100644 --- a/src/Entities/Entity.h +++ b/src/Entities/Entity.h @@ -172,13 +172,13 @@ public: /// Returns true if the entity is of the specified class or a subclass (cPawn's IsA("cEntity") returns true) virtual bool IsA(const char * a_ClassName) const; - /// Returns the topmost class name for the object - virtual const char * GetClass(void) const; - - // Returns the class name of this class + /** Returns the class name of this class */ static const char * GetClassStatic(void); + + /** Returns the topmost class name for the object */ + virtual const char * GetClass(void) const; - /// Returns the topmost class's parent class name for the object. cEntity returns an empty string (no parent). + /** Returns the topmost class's parent class name for the object. cEntity returns an empty string (no parent). */ virtual const char * GetParentClass(void) const; cWorld * GetWorld(void) const { return m_World; } diff --git a/src/Entities/Minecart.h b/src/Entities/Minecart.h index 6b6ad36b5..ab906fd06 100644 --- a/src/Entities/Minecart.h +++ b/src/Entities/Minecart.h @@ -127,7 +127,7 @@ public: ContentsWidth = 9, }; - const cItem & GetSlot(int a_Idx) const { return m_Contents.GetSlot(a_Idx); } + const cItem & GetSlot(int a_Idx) const { return m_Contents.GetSlot(a_Idx); } void SetSlot(size_t a_Idx, const cItem & a_Item) { m_Contents.SetSlot(a_Idx, a_Item); } protected: diff --git a/src/Entities/Pickup.cpp b/src/Entities/Pickup.cpp index 87b5bed07..e5e28446d 100644 --- a/src/Entities/Pickup.cpp +++ b/src/Entities/Pickup.cpp @@ -191,10 +191,8 @@ void cPickup::Tick(float a_Dt, cChunk & a_Chunk) -bool cPickup::CollectedBy(cPlayer * a_Dest) +bool cPickup::CollectedBy(cPlayer & a_Dest) { - ASSERT(a_Dest != NULL); - if (m_bCollected) { // LOG("Pickup %d cannot be collected by \"%s\", because it has already been collected.", m_UniqueID, a_Dest->GetName().c_str()); @@ -214,21 +212,21 @@ bool cPickup::CollectedBy(cPlayer * a_Dest) return false; } - int NumAdded = a_Dest->GetInventory().AddItem(m_Item); + int NumAdded = a_Dest.GetInventory().AddItem(m_Item); if (NumAdded > 0) { // Check achievements switch (m_Item.m_ItemType) { - case E_BLOCK_LOG: a_Dest->AwardAchievement(achMineWood); break; - case E_ITEM_LEATHER: a_Dest->AwardAchievement(achKillCow); break; - case E_ITEM_DIAMOND: a_Dest->AwardAchievement(achDiamonds); break; - case E_ITEM_BLAZE_ROD: a_Dest->AwardAchievement(achBlazeRod); break; + case E_BLOCK_LOG: a_Dest.AwardAchievement(achMineWood); break; + case E_ITEM_LEATHER: a_Dest.AwardAchievement(achKillCow); break; + case E_ITEM_DIAMOND: a_Dest.AwardAchievement(achDiamonds); break; + case E_ITEM_BLAZE_ROD: a_Dest.AwardAchievement(achBlazeRod); break; default: break; } m_Item.m_ItemCount -= NumAdded; - m_World->BroadcastCollectEntity(*this, *a_Dest); + m_World->BroadcastCollectEntity(*this, a_Dest); // Also send the "pop" sound effect with a somewhat random pitch (fast-random using EntityID ;) m_World->BroadcastSoundEffect("random.pop", GetPosX(), GetPosY(), GetPosZ(), 0.5, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64)); if (m_Item.m_ItemCount <= 0) diff --git a/src/Entities/Pickup.h b/src/Entities/Pickup.h index e3e0f61c7..d1176a7cf 100644 --- a/src/Entities/Pickup.h +++ b/src/Entities/Pickup.h @@ -32,7 +32,7 @@ public: virtual void SpawnOn(cClientHandle & a_ClientHandle) override; - bool CollectedBy(cPlayer * a_Dest); // tolua_export + bool CollectedBy(cPlayer & a_Dest); // tolua_export virtual void Tick(float a_Dt, cChunk & a_Chunk) override; diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index f58a0a016..6bd0a3d20 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -245,7 +245,7 @@ void cPlayer::Tick(float a_Dt, cChunk & a_Chunk) if (m_Health > 0) // make sure player is alive { - m_World->CollectPickupsByPlayer(this); + m_World->CollectPickupsByPlayer(*this); if ((m_EatingFinishTick >= 0) && (m_EatingFinishTick <= m_World->GetWorldAge())) { @@ -2134,19 +2134,19 @@ void cPlayer::ApplyFoodExhaustionFromMovement() void cPlayer::LoadRank(void) { // Load the values from cRankManager: - cRankManager & RankMgr = cRoot::Get()->GetRankManager(); - m_Rank = RankMgr.GetPlayerRankName(m_UUID); + cRankManager * RankMgr = cRoot::Get()->GetRankManager(); + m_Rank = RankMgr->GetPlayerRankName(m_UUID); if (m_Rank.empty()) { - m_Rank = RankMgr.GetDefaultRank(); + m_Rank = RankMgr->GetDefaultRank(); } else { // Update the name: - RankMgr.UpdatePlayerName(m_UUID, m_PlayerName); + RankMgr->UpdatePlayerName(m_UUID, m_PlayerName); } - m_Permissions = RankMgr.GetPlayerPermissions(m_UUID); - RankMgr.GetRankVisuals(m_Rank, m_MsgPrefix, m_MsgSuffix, m_MsgNameColorCode); + m_Permissions = RankMgr->GetPlayerPermissions(m_UUID); + RankMgr->GetRankVisuals(m_Rank, m_MsgPrefix, m_MsgSuffix, m_MsgNameColorCode); // Break up the individual permissions on each dot, into m_SplitPermissions: m_SplitPermissions.clear(); diff --git a/src/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp index acc9bd674..ab25ac30c 100644 --- a/src/Entities/ProjectileEntity.cpp +++ b/src/Entities/ProjectileEntity.cpp @@ -424,8 +424,12 @@ void cProjectileEntity::SpawnOn(cClientHandle & a_Client) -void cProjectileEntity::CollectedBy(cPlayer * a_Dest) +void cProjectileEntity::CollectedBy(cPlayer & a_Dest) { // Overriden in arrow UNUSED(a_Dest); } + + + + diff --git a/src/Entities/ProjectileEntity.h b/src/Entities/ProjectileEntity.h index 990136a32..03eda9739 100644 --- a/src/Entities/ProjectileEntity.h +++ b/src/Entities/ProjectileEntity.h @@ -59,7 +59,7 @@ public: } /// Called by Chunk when the projectile is eligible for player collection - virtual void CollectedBy(cPlayer * a_Dest); + virtual void CollectedBy(cPlayer & a_Dest); // tolua_begin diff --git a/src/Generating/BioGen.cpp b/src/Generating/BioGen.cpp index 8924a7999..b9face1f8 100644 --- a/src/Generating/BioGen.cpp +++ b/src/Generating/BioGen.cpp @@ -45,7 +45,7 @@ void cBioGenConstant::InitializeBiomeGen(cIniFile & a_IniFile) //////////////////////////////////////////////////////////////////////////////// // cBioGenCache: -cBioGenCache::cBioGenCache(cBiomeGen * a_BioGenToCache, int a_CacheSize) : +cBioGenCache::cBioGenCache(cBiomeGenPtr a_BioGenToCache, int a_CacheSize) : m_BioGenToCache(a_BioGenToCache), m_CacheSize(a_CacheSize), m_CacheOrder(new int[a_CacheSize]), @@ -145,25 +145,13 @@ void cBioGenCache::InitializeBiomeGen(cIniFile & a_IniFile) //////////////////////////////////////////////////////////////////////////////// // cBioGenMulticache: -cBioGenMulticache::cBioGenMulticache(cBiomeGen * a_BioGenToCache, size_t a_CacheSize, size_t a_CachesLength) : - m_CachesLength(a_CachesLength) +cBioGenMulticache::cBioGenMulticache(cBiomeGenPtr a_BioGenToCache, size_t a_SubCacheSize, size_t a_NumSubCaches) : + m_NumSubCaches(a_NumSubCaches) { - m_Caches.reserve(a_CachesLength); - for (size_t i = 0; i < a_CachesLength; i++) + m_Caches.reserve(a_NumSubCaches); + for (size_t i = 0; i < a_NumSubCaches; i++) { - m_Caches.push_back(new cBioGenCache(a_BioGenToCache, a_CacheSize)); - } -} - - - - - -cBioGenMulticache::~cBioGenMulticache() -{ - for (cBiomeGens::iterator it = m_Caches.begin(); it != m_Caches.end(); it++) - { - delete *it; + m_Caches.push_back(cBiomeGenPtr(new cBioGenCache(a_BioGenToCache, a_SubCacheSize))); } } @@ -174,7 +162,7 @@ cBioGenMulticache::~cBioGenMulticache() void cBioGenMulticache::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) { const size_t coefficient = 3; - const size_t cacheIdx = ((size_t)a_ChunkX + coefficient * (size_t)a_ChunkZ) % m_CachesLength; + const size_t cacheIdx = ((size_t)a_ChunkX + coefficient * (size_t)a_ChunkZ) % m_NumSubCaches; m_Caches[cacheIdx]->GenBiomes(a_ChunkX, a_ChunkZ, a_BiomeMap); } @@ -185,10 +173,9 @@ void cBioGenMulticache::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMa void cBioGenMulticache::InitializeBiomeGen(cIniFile & a_IniFile) { - for (cBiomeGens::iterator it = m_Caches.begin(); it != m_Caches.end(); it++) + for (auto itr : m_Caches) { - cBiomeGen * tmp = *it; - tmp->InitializeBiomeGen(a_IniFile); + itr->InitializeBiomeGen(a_IniFile); } } @@ -760,8 +747,8 @@ void cBioGenTwoLevel::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap int DistortZ[cChunkDef::Width + 1][cChunkDef::Width + 1]; for (int x = 0; x <= 4; x++) for (int z = 0; z <= 4; z++) { - float BlockX = BaseX + x * 4; - float BlockZ = BaseZ + z * 4; + float BlockX = static_cast<float>(BaseX + x * 4); + float BlockZ = static_cast<float>(BaseZ + z * 4); double NoiseX = m_AmpX1 * m_Noise1.CubicNoise2D(BlockX * m_FreqX1, BlockZ * m_FreqX1); NoiseX += m_AmpX2 * m_Noise2.CubicNoise2D(BlockX * m_FreqX2, BlockZ * m_FreqX2); NoiseX += m_AmpX3 * m_Noise3.CubicNoise2D(BlockX * m_FreqX3, BlockZ * m_FreqX3); @@ -785,7 +772,7 @@ void cBioGenTwoLevel::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap int BiomeGroup = m_VoronoiLarge.GetValueAt(DistortX[x][z], DistortZ[x][z], SeedX, SeedZ, MinDist2) / 7; int BiomeIdx = m_VoronoiSmall.GetValueAt(DistortX[x][z], DistortZ[x][z], SeedX, SeedZ, MinDist2) / 11; int MinDist1 = (DistortX[x][z] - SeedX) * (DistortX[x][z] - SeedX) + (DistortZ[x][z] - SeedZ) * (DistortZ[x][z] - SeedZ); - cChunkDef::SetBiome(a_BiomeMap, x, z, SelectBiome(BiomeGroup, BiomeIdx, (MinDist1 < MinDist2 / 4) ? 0 : 1)); + cChunkDef::SetBiome(a_BiomeMap, x, z, SelectBiome(BiomeGroup, BiomeIdx, (MinDist1 < MinDist2 / 4) ? 1 : 0)); } } } @@ -932,7 +919,7 @@ void cBioGenTwoLevel::InitializeBiomeGen(cIniFile & a_IniFile) //////////////////////////////////////////////////////////////////////////////// // cBiomeGen: -cBiomeGen * cBiomeGen::CreateBiomeGen(cIniFile & a_IniFile, int a_Seed, bool & a_CacheOffByDefault) +cBiomeGenPtr cBiomeGen::CreateBiomeGen(cIniFile & a_IniFile, int a_Seed, bool & a_CacheOffByDefault) { AString BiomeGenName = a_IniFile.GetValueSet("Generator", "BiomeGen", ""); if (BiomeGenName.empty()) @@ -988,7 +975,7 @@ cBiomeGen * cBiomeGen::CreateBiomeGen(cIniFile & a_IniFile, int a_Seed, bool & a } res->InitializeBiomeGen(a_IniFile); - return res; + return cBiomeGenPtr(res); } diff --git a/src/Generating/BioGen.h b/src/Generating/BioGen.h index 22ddfae5c..5fd0844d9 100644 --- a/src/Generating/BioGen.h +++ b/src/Generating/BioGen.h @@ -48,12 +48,12 @@ class cBioGenCache : typedef cBiomeGen super; public: - cBioGenCache(cBiomeGen * a_BioGenToCache, int a_CacheSize); // Doesn't take ownership of a_BioGenToCache - ~cBioGenCache(); + cBioGenCache(cBiomeGenPtr a_BioGenToCache, int a_CacheSize); + virtual ~cBioGenCache(); protected: - cBiomeGen * m_BioGenToCache; + cBiomeGenPtr m_BioGenToCache; struct sCacheData { @@ -87,19 +87,21 @@ class cBioGenMulticache : typedef cBiomeGen super; public: - /* - a_CacheSize defines the size of each singular cache - a_CachesLength defines how many caches are used for the multicache - */ - cBioGenMulticache(cBiomeGen * a_BioGenToCache, size_t a_CacheSize, size_t a_CachesLength); // Doesn't take ownership of a_BioGenToCache - ~cBioGenMulticache(); + /* Creates a new multicache - a cache that divides the caching into several sub-caches based on the chunk coords. + This allows us to use shorter cache depths with faster lookups for more covered area. (#381) + a_SubCacheSize defines the size of each sub-cache + a_NumSubCaches defines how many sub-caches are used for the multicache. */ + cBioGenMulticache(cBiomeGenPtr a_BioGenToCache, size_t a_SubCacheSize, size_t a_NumSubCaches); protected: - typedef std::vector<cBiomeGen *> cBiomeGens; + typedef std::vector<cBiomeGenPtr> cBiomeGenPtrs; + + /** Number of sub-caches. Pulled out of m_Caches.size() for faster access. */ + size_t m_NumSubCaches; - size_t m_CachesLength; - cBiomeGens m_Caches; + /** Individual sub-caches. */ + cBiomeGenPtrs m_Caches; virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; diff --git a/src/Generating/ChunkDesc.cpp b/src/Generating/ChunkDesc.cpp index c0b646fd0..566332b1f 100644 --- a/src/Generating/ChunkDesc.cpp +++ b/src/Generating/ChunkDesc.cpp @@ -269,10 +269,10 @@ void cChunkDesc::ReadBlockArea(cBlockArea & a_Dest, int a_MinRelX, int a_MaxRelX LOGWARNING("%s: MaxRelX less than zero, adjusting to zero", __FUNCTION__); a_MaxRelX = 0; } - else if (a_MaxRelX >= cChunkDef::Width) + else if (a_MaxRelX > cChunkDef::Width) { LOGWARNING("%s: MaxRelX more than chunk width, adjusting to chunk width", __FUNCTION__); - a_MaxRelX = cChunkDef::Width - 1; + a_MaxRelX = cChunkDef::Width; } if (a_MinRelY < 0) @@ -290,10 +290,10 @@ void cChunkDesc::ReadBlockArea(cBlockArea & a_Dest, int a_MinRelX, int a_MaxRelX LOGWARNING("%s: MaxRelY less than zero, adjusting to zero", __FUNCTION__); a_MaxRelY = 0; } - else if (a_MaxRelY >= cChunkDef::Height) + else if (a_MaxRelY > cChunkDef::Height) { LOGWARNING("%s: MaxRelY more than chunk height, adjusting to chunk height", __FUNCTION__); - a_MaxRelY = cChunkDef::Height - 1; + a_MaxRelY = cChunkDef::Height; } if (a_MinRelZ < 0) @@ -311,10 +311,10 @@ void cChunkDesc::ReadBlockArea(cBlockArea & a_Dest, int a_MinRelX, int a_MaxRelX LOGWARNING("%s: MaxRelZ less than zero, adjusting to zero", __FUNCTION__); a_MaxRelZ = 0; } - else if (a_MaxRelZ >= cChunkDef::Width) + else if (a_MaxRelZ > cChunkDef::Width) { LOGWARNING("%s: MaxRelZ more than chunk width, adjusting to chunk width", __FUNCTION__); - a_MaxRelZ = cChunkDef::Width - 1; + a_MaxRelZ = cChunkDef::Width; } // Prepare the block area: diff --git a/src/Generating/CompoGen.cpp b/src/Generating/CompoGen.cpp index 178673e32..0105fdb70 100644 --- a/src/Generating/CompoGen.cpp +++ b/src/Generating/CompoGen.cpp @@ -663,7 +663,7 @@ void cCompoGenNether::InitializeCompoGen(cIniFile & a_IniFile) //////////////////////////////////////////////////////////////////////////////// // cCompoGenCache: -cCompoGenCache::cCompoGenCache(cTerrainCompositionGen & a_Underlying, int a_CacheSize) : +cCompoGenCache::cCompoGenCache(cTerrainCompositionGenPtr a_Underlying, int a_CacheSize) : m_Underlying(a_Underlying), m_CacheSize(a_CacheSize), m_CacheOrder(new int[a_CacheSize]), @@ -739,7 +739,7 @@ void cCompoGenCache::ComposeTerrain(cChunkDesc & a_ChunkDesc) // Not in the cache: m_NumMisses++; - m_Underlying.ComposeTerrain(a_ChunkDesc); + m_Underlying->ComposeTerrain(a_ChunkDesc); // Insert it as the first item in the MRU order: int Idx = m_CacheOrder[m_CacheSize - 1]; @@ -760,7 +760,7 @@ void cCompoGenCache::ComposeTerrain(cChunkDesc & a_ChunkDesc) void cCompoGenCache::InitializeCompoGen(cIniFile & a_IniFile) { - m_Underlying.InitializeCompoGen(a_IniFile); + m_Underlying->InitializeCompoGen(a_IniFile); } diff --git a/src/Generating/CompoGen.h b/src/Generating/CompoGen.h index 096b0fb5a..b145b6ba3 100644 --- a/src/Generating/CompoGen.h +++ b/src/Generating/CompoGen.h @@ -144,12 +144,12 @@ protected: -/// Caches most-recently-used chunk composition of another composition generator. Caches only the types and metas +/** Caches most-recently-used chunk composition of another composition generator. Caches only the types and metas */ class cCompoGenCache : public cTerrainCompositionGen { public: - cCompoGenCache(cTerrainCompositionGen & a_Underlying, int a_CacheSize); // Doesn't take ownership of a_Underlying + cCompoGenCache(cTerrainCompositionGenPtr a_Underlying, int a_CacheSize); // Doesn't take ownership of a_Underlying ~cCompoGenCache(); // cTerrainCompositionGen override: @@ -158,7 +158,7 @@ public: protected: - cTerrainCompositionGen & m_Underlying; + cTerrainCompositionGenPtr m_Underlying; struct sCacheData { diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp index 87461b944..358d97c92 100644 --- a/src/Generating/ComposableGenerator.cpp +++ b/src/Generating/ComposableGenerator.cpp @@ -39,7 +39,7 @@ //////////////////////////////////////////////////////////////////////////////// // cTerrainCompositionGen: -cTerrainCompositionGen * cTerrainCompositionGen::CreateCompositionGen(cIniFile & a_IniFile, cBiomeGen & a_BiomeGen, cTerrainHeightGen & a_HeightGen, int a_Seed) +cTerrainCompositionGenPtr cTerrainCompositionGen::CreateCompositionGen(cIniFile & a_IniFile, cBiomeGenPtr a_BiomeGen, cTerrainHeightGen & a_HeightGen, int a_Seed) { AString CompoGenName = a_IniFile.GetValueSet("Generator", "CompositionGen", ""); if (CompoGenName.empty()) @@ -107,7 +107,7 @@ cTerrainCompositionGen * cTerrainCompositionGen::CreateCompositionGen(cIniFile & // Read the settings from the ini file: res->InitializeCompoGen(a_IniFile); - return res; + return cTerrainCompositionGenPtr(res); } @@ -119,12 +119,9 @@ cTerrainCompositionGen * cTerrainCompositionGen::CreateCompositionGen(cIniFile & cComposableGenerator::cComposableGenerator(cChunkGenerator & a_ChunkGenerator) : super(a_ChunkGenerator), - m_BiomeGen(NULL), - m_HeightGen(NULL), - m_CompositionGen(NULL), - m_UnderlyingBiomeGen(NULL), - m_UnderlyingHeightGen(NULL), - m_UnderlyingCompositionGen(NULL) + m_BiomeGen(nullptr), + m_HeightGen(nullptr), + m_CompositionGen(nullptr) { } @@ -132,33 +129,6 @@ cComposableGenerator::cComposableGenerator(cChunkGenerator & a_ChunkGenerator) : -cComposableGenerator::~cComposableGenerator() -{ - // Delete the generating composition: - for (cFinishGenList::const_iterator itr = m_FinishGens.begin(); itr != m_FinishGens.end(); ++itr) - { - delete *itr; - } - m_FinishGens.clear(); - - delete m_CompositionGen; - m_CompositionGen = NULL; - delete m_HeightGen; - m_HeightGen = NULL; - delete m_BiomeGen; - m_BiomeGen = NULL; - delete m_UnderlyingCompositionGen; - m_UnderlyingCompositionGen = NULL; - delete m_UnderlyingHeightGen; - m_UnderlyingHeightGen = NULL; - delete m_UnderlyingBiomeGen; - m_UnderlyingBiomeGen = NULL; -} - - - - - void cComposableGenerator::Initialize(cIniFile & a_IniFile) { super::Initialize(a_IniFile); @@ -245,15 +215,14 @@ void cComposableGenerator::InitBiomeGen(cIniFile & a_IniFile) CacheSize = 4; } LOGD("Using a cache for biomegen of size %d.", CacheSize); - m_UnderlyingBiomeGen = m_BiomeGen; if (MultiCacheLength > 0) { LOGD("Enabling multicache for biomegen of length %d.", MultiCacheLength); - m_BiomeGen = new cBioGenMulticache(m_UnderlyingBiomeGen, CacheSize, MultiCacheLength); + m_BiomeGen = cBiomeGenPtr(new cBioGenMulticache(m_BiomeGen, CacheSize, MultiCacheLength)); } else { - m_BiomeGen = new cBioGenCache(m_UnderlyingBiomeGen, CacheSize); + m_BiomeGen = cBiomeGenPtr(new cBioGenCache(m_BiomeGen, CacheSize)); } } @@ -264,7 +233,7 @@ void cComposableGenerator::InitBiomeGen(cIniFile & a_IniFile) void cComposableGenerator::InitHeightGen(cIniFile & a_IniFile) { bool CacheOffByDefault = false; - m_HeightGen = cTerrainHeightGen::CreateHeightGen(a_IniFile, *m_BiomeGen, m_ChunkGenerator.GetSeed(), CacheOffByDefault); + m_HeightGen = cTerrainHeightGen::CreateHeightGen(a_IniFile, m_BiomeGen, m_ChunkGenerator.GetSeed(), CacheOffByDefault); // Add a cache, if requested: int CacheSize = a_IniFile.GetValueSetI("Generator", "HeightGenCacheSize", CacheOffByDefault ? 0 : 64); @@ -278,8 +247,7 @@ void cComposableGenerator::InitHeightGen(cIniFile & a_IniFile) CacheSize = 4; } LOGD("Using a cache for Heightgen of size %d.", CacheSize); - m_UnderlyingHeightGen = m_HeightGen; - m_HeightGen = new cHeiGenCache(*m_UnderlyingHeightGen, CacheSize); + m_HeightGen = cTerrainHeightGenPtr(new cHeiGenCache(m_HeightGen, CacheSize)); } } @@ -289,13 +257,12 @@ void cComposableGenerator::InitHeightGen(cIniFile & a_IniFile) void cComposableGenerator::InitCompositionGen(cIniFile & a_IniFile) { - m_CompositionGen = cTerrainCompositionGen::CreateCompositionGen(a_IniFile, *m_BiomeGen, *m_HeightGen, m_ChunkGenerator.GetSeed()); + m_CompositionGen = cTerrainCompositionGen::CreateCompositionGen(a_IniFile, m_BiomeGen, *m_HeightGen, m_ChunkGenerator.GetSeed()); int CompoGenCacheSize = a_IniFile.GetValueSetI("Generator", "CompositionGenCacheSize", 64); if (CompoGenCacheSize > 1) { - m_UnderlyingCompositionGen = m_CompositionGen; - m_CompositionGen = new cCompoGenCache(*m_UnderlyingCompositionGen, 32); + m_CompositionGen = cTerrainCompositionGenPtr(new cCompoGenCache(m_CompositionGen, 32)); } } @@ -319,7 +286,7 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) { int DefaultBottomLavaLevel = (Dimension == dimNether) ? 30 : 10; int BottomLavaLevel = a_IniFile.GetValueSetI("Generator", "BottomLavaLevel", DefaultBottomLavaLevel); - m_FinishGens.push_back(new cFinishGenBottomLava(BottomLavaLevel)); + m_FinishGens.push_back(cFinishGenPtr(new cFinishGenBottomLava(BottomLavaLevel))); } else if (NoCaseCompare(*itr, "DeadBushes") == 0) { @@ -341,20 +308,20 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) AllowedBlocks.push_back(E_BLOCK_HARDENED_CLAY); AllowedBlocks.push_back(E_BLOCK_STAINED_CLAY); - m_FinishGens.push_back(new cFinishGenSingleTopBlock(Seed, E_BLOCK_DEAD_BUSH, AllowedBiomes, 2, AllowedBlocks)); + m_FinishGens.push_back(cFinishGenPtr(new cFinishGenSingleTopBlock(Seed, E_BLOCK_DEAD_BUSH, AllowedBiomes, 2, AllowedBlocks))); } else if (NoCaseCompare(*itr, "DirectOverhangs") == 0) { - m_FinishGens.push_back(new cStructGenDirectOverhangs(Seed)); + m_FinishGens.push_back(cFinishGenPtr(new cStructGenDirectOverhangs(Seed))); } else if (NoCaseCompare(*itr, "DistortedMembraneOverhangs") == 0) { - m_FinishGens.push_back(new cStructGenDistortedMembraneOverhangs(Seed)); + m_FinishGens.push_back(cFinishGenPtr(new cStructGenDistortedMembraneOverhangs(Seed))); } else if (NoCaseCompare(*itr, "DualRidgeCaves") == 0) { float Threshold = (float)a_IniFile.GetValueSetF("Generator", "DualRidgeCavesThreshold", 0.3); - m_FinishGens.push_back(new cStructGenDualRidgeCaves(Seed, Threshold)); + m_FinishGens.push_back(cFinishGenPtr(new cStructGenDualRidgeCaves(Seed, Threshold))); } else if (NoCaseCompare(*itr, "DungeonRooms") == 0) { @@ -362,24 +329,24 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) int MaxSize = a_IniFile.GetValueSetI("Generator", "DungeonRoomsMaxSize", 7); int MinSize = a_IniFile.GetValueSetI("Generator", "DungeonRoomsMinSize", 5); AString HeightDistrib = a_IniFile.GetValueSet ("Generator", "DungeonRoomsHeightDistrib", "0, 0; 10, 10; 11, 500; 40, 500; 60, 40; 90, 1"); - m_FinishGens.push_back(new cDungeonRoomsFinisher(*m_HeightGen, Seed, GridSize, MaxSize, MinSize, HeightDistrib)); + m_FinishGens.push_back(cFinishGenPtr(new cDungeonRoomsFinisher(m_HeightGen, Seed, GridSize, MaxSize, MinSize, HeightDistrib))); } else if (NoCaseCompare(*itr, "Ice") == 0) { - m_FinishGens.push_back(new cFinishGenIce); + m_FinishGens.push_back(cFinishGenPtr(new cFinishGenIce)); } else if (NoCaseCompare(*itr, "LavaLakes") == 0) { int Probability = a_IniFile.GetValueSetI("Generator", "LavaLakesProbability", 10); - m_FinishGens.push_back(new cStructGenLakes(Seed * 5 + 16873, E_BLOCK_STATIONARY_LAVA, *m_HeightGen, Probability)); + m_FinishGens.push_back(cFinishGenPtr(new cStructGenLakes(Seed * 5 + 16873, E_BLOCK_STATIONARY_LAVA, m_HeightGen, Probability))); } else if (NoCaseCompare(*itr, "LavaSprings") == 0) { - m_FinishGens.push_back(new cFinishGenFluidSprings(Seed, E_BLOCK_LAVA, a_IniFile, Dimension)); + m_FinishGens.push_back(cFinishGenPtr(new cFinishGenFluidSprings(Seed, E_BLOCK_LAVA, a_IniFile, Dimension))); } else if (NoCaseCompare(*itr, "MarbleCaves") == 0) { - m_FinishGens.push_back(new cStructGenMarbleCaves(Seed)); + m_FinishGens.push_back(cFinishGenPtr(new cStructGenMarbleCaves(Seed))); } else if (NoCaseCompare(*itr, "MineShafts") == 0) { @@ -389,10 +356,10 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) int ChanceCorridor = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceCorridor", 600); int ChanceCrossing = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceCrossing", 200); int ChanceStaircase = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceStaircase", 200); - m_FinishGens.push_back(new cStructGenMineShafts( + m_FinishGens.push_back(cFinishGenPtr(new cStructGenMineShafts( Seed, GridSize, MaxOffset, MaxSystemSize, ChanceCorridor, ChanceCrossing, ChanceStaircase - )); + ))); } else if (NoCaseCompare(*itr, "Lilypads") == 0) { @@ -406,7 +373,7 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) AllowedBlocks.push_back(E_BLOCK_WATER); AllowedBlocks.push_back(E_BLOCK_STATIONARY_WATER); - m_FinishGens.push_back(new cFinishGenSingleTopBlock(Seed, E_BLOCK_LILY_PAD, AllowedBiomes, 4, AllowedBlocks)); + m_FinishGens.push_back(cFinishGenPtr(new cFinishGenSingleTopBlock(Seed, E_BLOCK_LILY_PAD, AllowedBiomes, 4, AllowedBlocks))); } else if (NoCaseCompare(*itr, "NaturalPatches") == 0) { @@ -455,18 +422,18 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) AndesiteVein.NestSize = 32; Ores.push_back(AndesiteVein); - m_FinishGens.push_back(new cStructGenOreNests(Seed, Ores, E_BLOCK_STONE)); + m_FinishGens.push_back(cFinishGenPtr(new cStructGenOreNests(Seed, Ores, E_BLOCK_STONE))); } else if (NoCaseCompare(*itr, "NetherClumpFoliage") == 0) { - m_FinishGens.push_back(new cFinishGenNetherClumpFoliage(Seed)); + m_FinishGens.push_back(cFinishGenPtr(new cFinishGenNetherClumpFoliage(Seed))); } else if (NoCaseCompare(*itr, "NetherForts") == 0) { int GridSize = a_IniFile.GetValueSetI("Generator", "NetherFortsGridSize", 512); int MaxOffset = a_IniFile.GetValueSetI("Generator", "NetherFortMaxOffset", 128); int MaxDepth = a_IniFile.GetValueSetI("Generator", "NetherFortsMaxDepth", 12); - m_FinishGens.push_back(new cNetherFortGen(Seed, GridSize, MaxOffset, MaxDepth)); + m_FinishGens.push_back(cFinishGenPtr(new cNetherFortGen(Seed, GridSize, MaxOffset, MaxDepth))); } else if (NoCaseCompare(*itr, "NetherOreNests") == 0) { @@ -480,7 +447,7 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) QuartzVein.NestSize = 8; Ores.push_back(QuartzVein); - m_FinishGens.push_back(new cStructGenOreNests(Seed, Ores, E_BLOCK_NETHERRACK)); + m_FinishGens.push_back(cFinishGenPtr(new cStructGenOreNests(Seed, Ores, E_BLOCK_NETHERRACK))); } else if (NoCaseCompare(*itr, "OreNests") == 0) @@ -535,11 +502,11 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) DiamondVein.NestSize = 4; Ores.push_back(DiamondVein); - m_FinishGens.push_back(new cStructGenOreNests(Seed, Ores, E_BLOCK_STONE)); + m_FinishGens.push_back(cFinishGenPtr(new cStructGenOreNests(Seed, Ores, E_BLOCK_STONE))); } else if (NoCaseCompare(*itr, "POCPieces") == 0) { - m_FinishGens.push_back(new cPOCPieceGenerator(Seed)); + m_FinishGens.push_back(cFinishGenPtr(new cPOCPieceGenerator(Seed))); } else if (NoCaseCompare(*itr, "PreSimulator") == 0) { @@ -548,7 +515,7 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) bool PreSimulateWater = a_IniFile.GetValueSetB("Generator", "PreSimulatorWater", true); bool PreSimulateLava = a_IniFile.GetValueSetB("Generator", "PreSimulatorLava", true); - m_FinishGens.push_back(new cFinishGenPreSimulator(PreSimulateFallingBlocks, PreSimulateWater, PreSimulateLava)); + m_FinishGens.push_back(cFinishGenPtr(new cFinishGenPreSimulator(PreSimulateFallingBlocks, PreSimulateWater, PreSimulateLava))); } else if (NoCaseCompare(*itr, "RainbowRoads") == 0) { @@ -556,11 +523,11 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) int MaxOffset = a_IniFile.GetValueSetI("Generator", "RainbowRoadsMaxOffset", 128); int MaxDepth = a_IniFile.GetValueSetI("Generator", "RainbowRoadsMaxDepth", 30); int MaxSize = a_IniFile.GetValueSetI("Generator", "RainbowRoadsMaxSize", 260); - m_FinishGens.push_back(new cRainbowRoadsGen(Seed, GridSize, MaxOffset, MaxDepth, MaxSize)); + m_FinishGens.push_back(cFinishGenPtr(new cRainbowRoadsGen(Seed, GridSize, MaxOffset, MaxDepth, MaxSize))); } else if (NoCaseCompare(*itr, "Ravines") == 0) { - m_FinishGens.push_back(new cStructGenRavines(Seed, 128)); + m_FinishGens.push_back(cFinishGenPtr(new cStructGenRavines(Seed, 128))); } else if (NoCaseCompare(*itr, "RoughRavines") == 0) { @@ -580,7 +547,7 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) double MinCeilingHeightEdge = a_IniFile.GetValueSetF("Generator", "RoughRavinesMinCeilingHeightEdge", 38); double MaxCeilingHeightCenter = a_IniFile.GetValueSetF("Generator", "RoughRavinesMaxCeilingHeightCenter", 58); double MinCeilingHeightCenter = a_IniFile.GetValueSetF("Generator", "RoughRavinesMinCeilingHeightCenter", 36); - m_FinishGens.push_back(new cRoughRavines( + m_FinishGens.push_back(cFinishGenPtr(new cRoughRavines( Seed, MaxSize, MinSize, (float)MaxCenterWidth, (float)MinCenterWidth, (float)MaxRoughness, (float)MinRoughness, @@ -589,27 +556,27 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) (float)MaxCeilingHeightEdge, (float)MinCeilingHeightEdge, (float)MaxCeilingHeightCenter, (float)MinCeilingHeightCenter, GridSize, MaxOffset - )); + ))); } else if (NoCaseCompare(*itr, "Snow") == 0) { - m_FinishGens.push_back(new cFinishGenSnow); + m_FinishGens.push_back(cFinishGenPtr(new cFinishGenSnow)); } else if (NoCaseCompare(*itr, "SprinkleFoliage") == 0) { - m_FinishGens.push_back(new cFinishGenSprinkleFoliage(Seed)); + m_FinishGens.push_back(cFinishGenPtr(new cFinishGenSprinkleFoliage(Seed))); } else if (NoCaseCompare(*itr, "TallGrass") == 0) { - m_FinishGens.push_back(new cFinishGenTallGrass(Seed)); + m_FinishGens.push_back(cFinishGenPtr(new cFinishGenTallGrass(Seed))); } else if (NoCaseCompare(*itr, "TestRails") == 0) { - m_FinishGens.push_back(new cTestRailsGen(Seed, 100, 1, 7, 50)); + m_FinishGens.push_back(cFinishGenPtr(new cTestRailsGen(Seed, 100, 1, 7, 50))); } else if (NoCaseCompare(*itr, "Trees") == 0) { - m_FinishGens.push_back(new cStructGenTrees(Seed, m_BiomeGen, m_HeightGen, m_CompositionGen)); + m_FinishGens.push_back(cFinishGenPtr(new cStructGenTrees(Seed, m_BiomeGen, m_HeightGen, m_CompositionGen))); } else if (NoCaseCompare(*itr, "UnderwaterBases") == 0) { @@ -617,7 +584,7 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) int MaxOffset = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseMaxOffset", 128); int MaxDepth = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseMaxDepth", 7); int MaxSize = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseMaxSize", 128); - m_FinishGens.push_back(new cUnderwaterBaseGen(Seed, GridSize, MaxOffset, MaxDepth, MaxSize, *m_BiomeGen)); + m_FinishGens.push_back(cFinishGenPtr(new cUnderwaterBaseGen(Seed, GridSize, MaxOffset, MaxDepth, MaxSize, m_BiomeGen))); } else if (NoCaseCompare(*itr, "Villages") == 0) { @@ -627,23 +594,23 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) int MaxSize = a_IniFile.GetValueSetI("Generator", "VillageMaxSize", 128); int MinDensity = a_IniFile.GetValueSetI("Generator", "VillageMinDensity", 50); int MaxDensity = a_IniFile.GetValueSetI("Generator", "VillageMaxDensity", 80); - m_FinishGens.push_back(new cVillageGen(Seed, GridSize, MaxOffset, MaxDepth, MaxSize, MinDensity, MaxDensity, *m_BiomeGen, *m_HeightGen)); + m_FinishGens.push_back(cFinishGenPtr(new cVillageGen(Seed, GridSize, MaxOffset, MaxDepth, MaxSize, MinDensity, MaxDensity, m_BiomeGen, m_HeightGen))); } else if (NoCaseCompare(*itr, "WaterLakes") == 0) { int Probability = a_IniFile.GetValueSetI("Generator", "WaterLakesProbability", 25); - m_FinishGens.push_back(new cStructGenLakes(Seed * 3 + 652, E_BLOCK_STATIONARY_WATER, *m_HeightGen, Probability)); + m_FinishGens.push_back(cFinishGenPtr(new cStructGenLakes(Seed * 3 + 652, E_BLOCK_STATIONARY_WATER, m_HeightGen, Probability))); } else if (NoCaseCompare(*itr, "WaterSprings") == 0) { - m_FinishGens.push_back(new cFinishGenFluidSprings(Seed, E_BLOCK_WATER, a_IniFile, Dimension)); + m_FinishGens.push_back(cFinishGenPtr(new cFinishGenFluidSprings(Seed, E_BLOCK_WATER, a_IniFile, Dimension))); } else if (NoCaseCompare(*itr, "WormNestCaves") == 0) { int Size = a_IniFile.GetValueSetI("Generator", "WormNestCavesSize", 64); int Grid = a_IniFile.GetValueSetI("Generator", "WormNestCavesGrid", 96); int MaxOffset = a_IniFile.GetValueSetI("Generator", "WormNestMaxOffset", 32); - m_FinishGens.push_back(new cStructGenWormNestCaves(Seed, Size, Grid, MaxOffset)); + m_FinishGens.push_back(cFinishGenPtr(new cStructGenWormNestCaves(Seed, Size, Grid, MaxOffset))); } else { diff --git a/src/Generating/ComposableGenerator.h b/src/Generating/ComposableGenerator.h index 6b7627d2e..a091f8d53 100644 --- a/src/Generating/ComposableGenerator.h +++ b/src/Generating/ComposableGenerator.h @@ -24,6 +24,16 @@ See http://forum.mc-server.org/showthread.php?tid=409 for details. +// Forward-declare the shared pointers to subgenerator classes: +class cBiomeGen; +class cTerrainHeightGen; +class cTerrainCompositionGen; +class cFinishGen; +typedef SharedPtr<cBiomeGen> cBiomeGenPtr; +typedef SharedPtr<cTerrainHeightGen> cTerrainHeightGenPtr; +typedef SharedPtr<cTerrainCompositionGen> cTerrainCompositionGenPtr; +typedef SharedPtr<cFinishGen> cFinishGenPtr; + // fwd: Noise3DGenerator.h class cNoise3DComposable; @@ -53,8 +63,7 @@ public: a_CacheOffByDefault gets set to whether the cache should be disabled by default. Used in BiomeVisualiser, too. Implemented in BioGen.cpp! */ - static cBiomeGen * CreateBiomeGen(cIniFile & a_IniFile, int a_Seed, bool & a_CacheOffByDefault); - + static cBiomeGenPtr CreateBiomeGen(cIniFile & a_IniFile, int a_Seed, bool & a_CacheOffByDefault); } ; @@ -83,7 +92,7 @@ public: a_CacheOffByDefault gets set to whether the cache should be disabled by default Implemented in HeiGen.cpp! */ - static cTerrainHeightGen * CreateHeightGen(cIniFile & a_IniFile, cBiomeGen & a_BiomeGen, int a_Seed, bool & a_CacheOffByDefault); + static cTerrainHeightGenPtr CreateHeightGen(cIniFile & a_IniFile, cBiomeGenPtr a_BiomeGen, int a_Seed, bool & a_CacheOffByDefault); } ; @@ -109,7 +118,7 @@ public: a_BiomeGen is the underlying biome generator, some composition generators may depend on it to generate more biomes a_HeightGen is the underlying height generator, some composition generators may depend on it providing additional values */ - static cTerrainCompositionGen * CreateCompositionGen(cIniFile & a_IniFile, cBiomeGen & a_BiomeGen, cTerrainHeightGen & a_HeightGen, int a_Seed); + static cTerrainCompositionGenPtr CreateCompositionGen(cIniFile & a_IniFile, cBiomeGenPtr a_BiomeGen, cTerrainHeightGen & a_HeightGen, int a_Seed); } ; @@ -131,7 +140,7 @@ public: virtual void GenFinish(cChunkDesc & a_ChunkDesc) = 0; } ; -typedef std::list<cFinishGen *> cFinishGenList; +typedef std::list<cFinishGenPtr> cFinishGenList; @@ -144,7 +153,6 @@ class cComposableGenerator : public: cComposableGenerator(cChunkGenerator & a_ChunkGenerator); - virtual ~cComposableGenerator(); virtual void Initialize(cIniFile & a_IniFile) override; virtual void GenerateBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; @@ -152,15 +160,10 @@ public: protected: // The generation composition: - cBiomeGen * m_BiomeGen; - cTerrainHeightGen * m_HeightGen; - cTerrainCompositionGen * m_CompositionGen; - cFinishGenList m_FinishGens; - - // Generators underlying the caches: - cBiomeGen * m_UnderlyingBiomeGen; - cTerrainHeightGen * m_UnderlyingHeightGen; - cTerrainCompositionGen * m_UnderlyingCompositionGen; + cBiomeGenPtr m_BiomeGen; + cTerrainHeightGenPtr m_HeightGen; + cTerrainCompositionGenPtr m_CompositionGen; + cFinishGenList m_FinishGens; /** Reads the biome gen settings from the ini and initializes m_BiomeGen accordingly */ diff --git a/src/Generating/DistortedHeightmap.cpp b/src/Generating/DistortedHeightmap.cpp index bf8995dcb..e6849fadf 100644 --- a/src/Generating/DistortedHeightmap.cpp +++ b/src/Generating/DistortedHeightmap.cpp @@ -276,13 +276,13 @@ const cDistortedHeightmap::sGenParam cDistortedHeightmap::m_GenParam[256] = -cDistortedHeightmap::cDistortedHeightmap(int a_Seed, cBiomeGen & a_BiomeGen) : +cDistortedHeightmap::cDistortedHeightmap(int a_Seed, cBiomeGenPtr a_BiomeGen) : m_NoiseDistortX(a_Seed + 1000), m_NoiseDistortZ(a_Seed + 2000), m_OceanFloorSelect(a_Seed + 3000), m_MesaFloor(a_Seed + 4000), m_BiomeGen(a_BiomeGen), - m_UnderlyingHeiGen(a_Seed, a_BiomeGen), + m_UnderlyingHeiGen(new cHeiGenBiomal(a_Seed, a_BiomeGen)), m_HeightGen(m_UnderlyingHeiGen, 64), m_IsInitialized(false) { @@ -577,7 +577,7 @@ void cDistortedHeightmap::UpdateDistortAmps(void) { for (int x = -1; x <= 1; x++) { - m_BiomeGen.GenBiomes(m_CurChunkX + x, m_CurChunkZ + z, Biomes[x + 1][z + 1]); + m_BiomeGen->GenBiomes(m_CurChunkX + x, m_CurChunkZ + z, Biomes[x + 1][z + 1]); } // for x } // for z diff --git a/src/Generating/DistortedHeightmap.h b/src/Generating/DistortedHeightmap.h index e6b3c9d3f..d073f29e4 100644 --- a/src/Generating/DistortedHeightmap.h +++ b/src/Generating/DistortedHeightmap.h @@ -35,7 +35,7 @@ public: NIBBLETYPE BlockMeta; } ; - cDistortedHeightmap(int a_Seed, cBiomeGen & a_BiomeGen); + cDistortedHeightmap(int a_Seed, cBiomeGenPtr a_BiomeGen); protected: typedef cChunkDef::BiomeMap BiomeNeighbors[3][3]; @@ -64,9 +64,14 @@ protected: int m_CurChunkZ; NOISE_DATATYPE m_DistortedHeightmap[17 * 257 * 17]; - cBiomeGen & m_BiomeGen; - cHeiGenBiomal m_UnderlyingHeiGen; // This generator provides us with base heightmap (before distortion) - cHeiGenCache m_HeightGen; // Cache above m_UnderlyingHeiGen + /** The bime generator to query for biomes. */ + cBiomeGenPtr m_BiomeGen; + + /** The generator that provides the base heightmap (before distortion). */ + cTerrainHeightGenPtr m_UnderlyingHeiGen; + + /** Cache for m_UnderlyingHeiGen. */ + cHeiGenCache m_HeightGen; /// Heightmap for the current chunk, before distortion (from m_HeightGen). Used for optimization. cChunkDef::HeightMap m_CurChunkHeights; diff --git a/src/Generating/DungeonRoomsFinisher.cpp b/src/Generating/DungeonRoomsFinisher.cpp index f213455d6..93fe8b472 100644 --- a/src/Generating/DungeonRoomsFinisher.cpp +++ b/src/Generating/DungeonRoomsFinisher.cpp @@ -6,6 +6,7 @@ #include "Globals.h" #include "DungeonRoomsFinisher.h" #include "../FastRandom.h" +#include "../BlockEntities/ChestEntity.h" @@ -175,7 +176,33 @@ protected: } a_ChunkDesc.SetBlockTypeMeta(RelX, m_FloorHeight + 1, RelZ, E_BLOCK_CHEST, (NIBBLETYPE)a_Chest.y); - // TODO: Fill the chest with random loot + // Fill the chest with random loot + static const cLootProbab LootProbab[] = + { + // Item, MinAmount, MaxAmount, Weight + { cItem(E_ITEM_GOLDEN_APPLE), 1, 1, 1 }, + { cItem(E_ITEM_DIAMOND_HORSE_ARMOR), 1, 1, 1 }, + { cItem(E_ITEM_GOLD_HORSE_ARMOR), 1, 1, 2 }, + { cItem(E_ITEM_13_DISC), 1, 1, 4 }, + { cItem(E_ITEM_CAT_DISC), 1, 1, 4 }, + { cItem(E_ITEM_IRON_HORSE_ARMOR), 1, 1, 5 }, + { cItem(E_ITEM_IRON), 1, 4, 10 }, + { cItem(E_ITEM_WHEAT), 1, 4, 10 }, + { cItem(E_ITEM_GUNPOWDER), 1, 4, 10 }, + { cItem(E_ITEM_STRING), 1, 4, 10 }, + { cItem(E_ITEM_REDSTONE_DUST), 1, 4, 10 }, + { cItem(E_ITEM_SADDLE), 1, 1, 10 }, + { cItem(E_ITEM_BUCKET), 1, 1, 10 }, + { cItem(E_ITEM_BREAD), 1, 1, 10 }, + { cItem(E_ITEM_NAME_TAG), 1, 1, 10 }, + } ; + + cChestEntity * ChestEntity = (cChestEntity *)a_ChunkDesc.GetBlockEntity(RelX, m_FloorHeight + 1, RelZ); + ASSERT((ChestEntity != NULL) && (ChestEntity->GetBlockType() == E_BLOCK_CHEST)); + cNoise Noise(a_ChunkDesc.GetChunkX() ^ a_ChunkDesc.GetChunkZ()); + int NumSlots = 3 + ((Noise.IntNoise3DInt(a_Chest.x, a_Chest.y, a_Chest.z) / 11) % 4); + int Seed = Noise.IntNoise2DInt(RelX, RelZ); + ChestEntity->GetContents().GenerateRandomLootWithBooks(LootProbab, ARRAYCOUNT(LootProbab), NumSlots, Seed); } @@ -193,6 +220,7 @@ protected: // The chunk is not intersecting the room at all, bail out return; } + int b = m_FloorHeight + 1; // Bottom int t = m_FloorHeight + 1 + ROOM_HEIGHT; // Top ReplaceCuboidRandom(a_ChunkDesc, m_StartX, m_FloorHeight, m_StartZ, m_EndX + 1, b, m_EndZ + 1, E_BLOCK_MOSSY_COBBLESTONE, E_BLOCK_COBBLESTONE); // Floor @@ -230,7 +258,7 @@ protected: //////////////////////////////////////////////////////////////////////////////// // cDungeonRoomsFinisher: -cDungeonRoomsFinisher::cDungeonRoomsFinisher(cTerrainHeightGen & a_HeightGen, int a_Seed, int a_GridSize, int a_MaxSize, int a_MinSize, const AString & a_HeightDistrib) : +cDungeonRoomsFinisher::cDungeonRoomsFinisher(cTerrainHeightGenPtr a_HeightGen, int a_Seed, int a_GridSize, int a_MaxSize, int a_MinSize, const AString & a_HeightDistrib) : super(a_Seed + 100, a_GridSize, a_GridSize, a_GridSize, a_GridSize, a_MaxSize, a_MaxSize, 1024), m_HeightGen(a_HeightGen), m_MaxHalfSize((a_MaxSize + 1) / 2), @@ -266,7 +294,7 @@ cDungeonRoomsFinisher::cStructurePtr cDungeonRoomsFinisher::CreateStructure(int int RelX = a_OriginX, RelY = 0, RelZ = a_OriginZ; cChunkDef::AbsoluteToRelative(RelX, RelY, RelZ, ChunkX, ChunkZ); cChunkDef::HeightMap HeightMap; - m_HeightGen.GenHeightMap(ChunkX, ChunkZ, HeightMap); + m_HeightGen->GenHeightMap(ChunkX, ChunkZ, HeightMap); int Height = cChunkDef::GetHeight(HeightMap, RelX, RelZ); // Max room height at {a_OriginX, a_OriginZ} Height = Clamp(m_HeightProbability.MapValue(rnd % m_HeightProbability.GetSum()), 10, Height - 5); diff --git a/src/Generating/DungeonRoomsFinisher.h b/src/Generating/DungeonRoomsFinisher.h index 2b52c9de6..09dd0448a 100644 --- a/src/Generating/DungeonRoomsFinisher.h +++ b/src/Generating/DungeonRoomsFinisher.h @@ -26,12 +26,12 @@ public: a_HeightGen is the underlying height generator, so that the rooms can always be placed under the terrain. a_MaxSize and a_MinSize are the maximum and minimum sizes of the room's internal (air) area, in blocks across. a_HeightDistrib is the string defining the height distribution for the rooms (cProbabDistrib format). */ - cDungeonRoomsFinisher(cTerrainHeightGen & a_HeightGen, int a_Seed, int a_GridSize, int a_MaxSize, int a_MinSize, const AString & a_HeightDistrib); + cDungeonRoomsFinisher(cTerrainHeightGenPtr a_HeightGen, int a_Seed, int a_GridSize, int a_MaxSize, int a_MinSize, const AString & a_HeightDistrib); protected: /** The height gen that is used for limiting the rooms' Y coords */ - cTerrainHeightGen & m_HeightGen; + cTerrainHeightGenPtr m_HeightGen; /** Maximum half-size (from center to wall) of the dungeon room's inner (air) area. Default is 3 (vanilla). */ int m_MaxHalfSize; diff --git a/src/Generating/HeiGen.cpp b/src/Generating/HeiGen.cpp index 79d529a6a..b7d4b337c 100644 --- a/src/Generating/HeiGen.cpp +++ b/src/Generating/HeiGen.cpp @@ -19,7 +19,7 @@ //////////////////////////////////////////////////////////////////////////////// // cTerrainHeightGen: -cTerrainHeightGen * cTerrainHeightGen::CreateHeightGen(cIniFile &a_IniFile, cBiomeGen & a_BiomeGen, int a_Seed, bool & a_CacheOffByDefault) +cTerrainHeightGenPtr cTerrainHeightGen::CreateHeightGen(cIniFile & a_IniFile, cBiomeGenPtr a_BiomeGen, int a_Seed, bool & a_CacheOffByDefault) { AString HeightGenName = a_IniFile.GetValueSet("Generator", "HeightGen", ""); if (HeightGenName.empty()) @@ -84,7 +84,7 @@ cTerrainHeightGen * cTerrainHeightGen::CreateHeightGen(cIniFile &a_IniFile, cBio // Read the settings: res->InitializeHeightGen(a_IniFile); - return res; + return cTerrainHeightGenPtr(res); } @@ -118,7 +118,7 @@ void cHeiGenFlat::InitializeHeightGen(cIniFile & a_IniFile) //////////////////////////////////////////////////////////////////////////////// // cHeiGenCache: -cHeiGenCache::cHeiGenCache(cTerrainHeightGen & a_HeiGenToCache, int a_CacheSize) : +cHeiGenCache::cHeiGenCache(cTerrainHeightGenPtr a_HeiGenToCache, int a_CacheSize) : m_HeiGenToCache(a_HeiGenToCache), m_CacheSize(a_CacheSize), m_CacheOrder(new int[a_CacheSize]), @@ -190,7 +190,7 @@ void cHeiGenCache::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap // Not in the cache: m_NumMisses++; - m_HeiGenToCache.GenHeightMap(a_ChunkX, a_ChunkZ, a_HeightMap); + m_HeiGenToCache->GenHeightMap(a_ChunkX, a_ChunkZ, a_HeightMap); // Insert it as the first item in the MRU order: int Idx = m_CacheOrder[m_CacheSize - 1]; @@ -210,7 +210,7 @@ void cHeiGenCache::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap void cHeiGenCache::InitializeHeightGen(cIniFile & a_IniFile) { - m_HeiGenToCache.InitializeHeightGen(a_IniFile); + m_HeiGenToCache->InitializeHeightGen(a_IniFile); } @@ -317,7 +317,9 @@ void cHeiGenClassic::InitializeHeightGen(cIniFile & a_IniFile) cHeiGenMountains::cHeiGenMountains(int a_Seed) : m_Seed(a_Seed), - m_Noise(a_Seed) + m_MountainNoise(a_Seed + 100), + m_DitchNoise(a_Seed + 200), + m_Perlin(a_Seed + 300) { } @@ -332,9 +334,11 @@ void cHeiGenMountains::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::Heigh NOISE_DATATYPE StartZ = (NOISE_DATATYPE)(a_ChunkZ * cChunkDef::Width); NOISE_DATATYPE EndZ = (NOISE_DATATYPE)(a_ChunkZ * cChunkDef::Width + cChunkDef::Width - 1); NOISE_DATATYPE Workspace[16 * 16]; - NOISE_DATATYPE Noise[16 * 16]; + NOISE_DATATYPE MountainNoise[16 * 16]; + NOISE_DATATYPE DitchNoise[16 * 16]; NOISE_DATATYPE PerlinNoise[16 * 16]; - m_Noise.Generate2D(Noise, 16, 16, StartX, EndX, StartZ, EndZ, Workspace); + m_MountainNoise.Generate2D(MountainNoise, 16, 16, StartX, EndX, StartZ, EndZ, Workspace); + m_DitchNoise.Generate2D(DitchNoise, 16, 16, StartX, EndX, StartZ, EndZ, Workspace); m_Perlin.Generate2D(PerlinNoise, 16, 16, StartX, EndX, StartZ, EndZ, Workspace); for (int z = 0; z < cChunkDef::Width; z++) { @@ -342,7 +346,7 @@ void cHeiGenMountains::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::Heigh for (int x = 0; x < cChunkDef::Width; x++) { int idx = IdxZ + x; - int hei = 100 - (int)((Noise[idx] + PerlinNoise[idx]) * 15); + int hei = 100 - (int)((MountainNoise[idx] - DitchNoise[idx] + PerlinNoise[idx]) * 15); if (hei < 10) { hei = 10; @@ -363,9 +367,12 @@ void cHeiGenMountains::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::Heigh void cHeiGenMountains::InitializeHeightGen(cIniFile & a_IniFile) { // TODO: Read the params from an INI file - m_Noise.AddOctave(0.1f, 0.1f); - m_Noise.AddOctave(0.05f, 0.5f); - m_Noise.AddOctave(0.02f, 1.5f); + m_MountainNoise.AddOctave(0.1f, 0.2f); + m_MountainNoise.AddOctave(0.05f, 0.4f); + m_MountainNoise.AddOctave(0.02f, 1.0f); + m_DitchNoise.AddOctave(0.1f, 0.2f); + m_DitchNoise.AddOctave(0.05f, 0.4f); + m_DitchNoise.AddOctave(0.02f, 1.0f); m_Perlin.AddOctave(0.01f, 1.5f); } @@ -479,7 +486,7 @@ void cHeiGenBiomal::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMa { for (int x = -1; x <= 1; x++) { - m_BiomeGen.GenBiomes(a_ChunkX + x, a_ChunkZ + z, Biomes[x + 1][z + 1]); + m_BiomeGen->GenBiomes(a_ChunkX + x, a_ChunkZ + z, Biomes[x + 1][z + 1]); } // for x } // for z diff --git a/src/Generating/HeiGen.h b/src/Generating/HeiGen.h index 5c106c7d9..6ae5ba362 100644 --- a/src/Generating/HeiGen.h +++ b/src/Generating/HeiGen.h @@ -45,7 +45,7 @@ class cHeiGenCache : public cTerrainHeightGen { public: - cHeiGenCache(cTerrainHeightGen & a_HeiGenToCache, int a_CacheSize); // Doesn't take ownership of a_HeiGenToCache + cHeiGenCache(cTerrainHeightGenPtr a_HeiGenToCache, int a_CacheSize); ~cHeiGenCache(); // cTerrainHeightGen overrides: @@ -57,7 +57,7 @@ public: protected: - cTerrainHeightGen & m_HeiGenToCache; + cTerrainHeightGenPtr m_HeiGenToCache; struct sCacheData { @@ -115,7 +115,8 @@ public: protected: int m_Seed; - cRidgedMultiNoise m_Noise; + cRidgedMultiNoise m_MountainNoise; + cRidgedMultiNoise m_DitchNoise; cPerlinNoise m_Perlin; // cTerrainHeightGen overrides: @@ -131,7 +132,7 @@ class cHeiGenBiomal : public cTerrainHeightGen { public: - cHeiGenBiomal(int a_Seed, cBiomeGen & a_BiomeGen) : + cHeiGenBiomal(int a_Seed, cBiomeGenPtr a_BiomeGen) : m_Noise(a_Seed), m_BiomeGen(a_BiomeGen) { @@ -141,8 +142,8 @@ protected: typedef cChunkDef::BiomeMap BiomeNeighbors[3][3]; - cNoise m_Noise; - cBiomeGen & m_BiomeGen; + cNoise m_Noise; + cBiomeGenPtr m_BiomeGen; // Per-biome terrain generator parameters: struct sGenParam diff --git a/src/Generating/StructGen.cpp b/src/Generating/StructGen.cpp index c23a72621..bdefcd8c1 100644 --- a/src/Generating/StructGen.cpp +++ b/src/Generating/StructGen.cpp @@ -411,7 +411,7 @@ void cStructGenLakes::CreateLakeImage(int a_ChunkX, int a_ChunkZ, cBlockArea & a // Find the minimum height in this chunk: cChunkDef::HeightMap HeightMap; - m_HeiGen.GenHeightMap(a_ChunkX, a_ChunkZ, HeightMap); + m_HeiGen->GenHeightMap(a_ChunkX, a_ChunkZ, HeightMap); HEIGHTTYPE MinHeight = HeightMap[0]; for (size_t i = 1; i < ARRAYCOUNT(HeightMap); i++) { diff --git a/src/Generating/StructGen.h b/src/Generating/StructGen.h index 96aa3e437..906fdd722 100644 --- a/src/Generating/StructGen.h +++ b/src/Generating/StructGen.h @@ -24,7 +24,7 @@ class cStructGenTrees : public cFinishGen { public: - cStructGenTrees(int a_Seed, cBiomeGen * a_BiomeGen, cTerrainHeightGen * a_HeightGen, cTerrainCompositionGen * a_CompositionGen) : + cStructGenTrees(int a_Seed, cBiomeGenPtr a_BiomeGen, cTerrainHeightGenPtr a_HeightGen, cTerrainCompositionGenPtr a_CompositionGen) : m_Seed(a_Seed), m_Noise(a_Seed), m_BiomeGen(a_BiomeGen), @@ -36,9 +36,9 @@ protected: int m_Seed; cNoise m_Noise; - cBiomeGen * m_BiomeGen; - cTerrainHeightGen * m_HeightGen; - cTerrainCompositionGen * m_CompositionGen; + cBiomeGenPtr m_BiomeGen; + cTerrainHeightGenPtr m_HeightGen; + cTerrainCompositionGenPtr m_CompositionGen; /** Generates and applies an image of a single tree. Parts of the tree inside the chunk are applied to a_BlockX. @@ -124,7 +124,7 @@ class cStructGenLakes : public cFinishGen { public: - cStructGenLakes(int a_Seed, BLOCKTYPE a_Fluid, cTerrainHeightGen & a_HeiGen, int a_Probability) : + cStructGenLakes(int a_Seed, BLOCKTYPE a_Fluid, cTerrainHeightGenPtr a_HeiGen, int a_Probability) : m_Noise(a_Seed), m_Seed(a_Seed), m_Fluid(a_Fluid), @@ -134,11 +134,11 @@ public: } protected: - cNoise m_Noise; - int m_Seed; - BLOCKTYPE m_Fluid; - cTerrainHeightGen & m_HeiGen; - int m_Probability; ///< Chance, 0 .. 100, of a chunk having the lake + cNoise m_Noise; + int m_Seed; + BLOCKTYPE m_Fluid; + cTerrainHeightGenPtr m_HeiGen; + int m_Probability; ///< Chance, 0 .. 100, of a chunk having the lake // cFinishGen override: virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; diff --git a/src/Generating/UnderwaterBaseGen.cpp b/src/Generating/UnderwaterBaseGen.cpp index 9278ea546..8916f4b5f 100644 --- a/src/Generating/UnderwaterBaseGen.cpp +++ b/src/Generating/UnderwaterBaseGen.cpp @@ -93,7 +93,7 @@ protected: -cUnderwaterBaseGen::cUnderwaterBaseGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth, int a_MaxSize, cBiomeGen & a_BiomeGen) : +cUnderwaterBaseGen::cUnderwaterBaseGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth, int a_MaxSize, cBiomeGenPtr a_BiomeGen) : super(a_Seed, a_GridSize, a_GridSize, a_MaxOffset, a_MaxOffset, a_MaxSize, a_MaxSize, 100), m_Noise(a_Seed + 1000), m_MaxDepth(a_MaxDepth), @@ -112,7 +112,7 @@ cGridStructGen::cStructurePtr cUnderwaterBaseGen::CreateStructure(int a_GridX, i int ChunkX, ChunkZ; cChunkDef::BlockToChunk(a_OriginX, a_OriginZ, ChunkX, ChunkZ); cChunkDef::BiomeMap Biomes; - m_BiomeGen.GenBiomes(ChunkX, ChunkZ, Biomes); + m_BiomeGen->GenBiomes(ChunkX, ChunkZ, Biomes); // Check if all the biomes are ocean: // If just one is not, no base is created, because it's likely that an unfriendly biome is too close diff --git a/src/Generating/UnderwaterBaseGen.h b/src/Generating/UnderwaterBaseGen.h index d6267b602..b24eb1075 100644 --- a/src/Generating/UnderwaterBaseGen.h +++ b/src/Generating/UnderwaterBaseGen.h @@ -22,7 +22,7 @@ class cUnderwaterBaseGen : typedef cGridStructGen super; public: - cUnderwaterBaseGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth, int a_MaxSize, cBiomeGen & a_BiomeGen); + cUnderwaterBaseGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth, int a_MaxSize, cBiomeGenPtr a_BiomeGen); protected: class cUnderwaterBase; // fwd: UnderwaterBaseGen.cpp @@ -38,7 +38,7 @@ protected: int m_MaxSize; /** The underlying biome generator that defines whether the base is created or not */ - cBiomeGen & m_BiomeGen; + cBiomeGenPtr m_BiomeGen; // cGridStructGen overrides: diff --git a/src/Generating/VillageGen.cpp b/src/Generating/VillageGen.cpp index a7f66b75e..1806fd427 100644 --- a/src/Generating/VillageGen.cpp +++ b/src/Generating/VillageGen.cpp @@ -116,7 +116,7 @@ public: int a_MaxSize, int a_Density, cPiecePool & a_Prefabs, - cTerrainHeightGen & a_HeightGen, + cTerrainHeightGenPtr a_HeightGen, BLOCKTYPE a_RoadBlock, BLOCKTYPE a_WaterRoadBlock ) : @@ -175,7 +175,7 @@ protected: cPiecePool & m_Prefabs; /** The underlying height generator, used for placing the structures on top of the terrain. */ - cTerrainHeightGen & m_HeightGen; + cTerrainHeightGenPtr m_HeightGen; /** The village pieces, placed by the generator. */ cPlacedPieces m_Pieces; @@ -194,7 +194,7 @@ protected: // Each intersecting prefab is placed on ground, then drawn // Each intersecting road is drawn by replacing top soil blocks with gravel / sandstone blocks cChunkDef::HeightMap HeightMap; // Heightmap for this chunk, used by roads - m_HeightGen.GenHeightMap(a_Chunk.GetChunkX(), a_Chunk.GetChunkZ(), HeightMap); + m_HeightGen->GenHeightMap(a_Chunk.GetChunkX(), a_Chunk.GetChunkZ(), HeightMap); for (cPlacedPieces::iterator itr = m_Pieces.begin(), end = m_Pieces.end(); itr != end; ++itr) { cPrefab & Prefab = (cPrefab &)((*itr)->GetPiece()); @@ -224,7 +224,7 @@ protected: int BlockY; cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); cChunkDef::HeightMap HeightMap; - m_HeightGen.GenHeightMap(ChunkX, ChunkZ, HeightMap); + m_HeightGen->GenHeightMap(ChunkX, ChunkZ, HeightMap); int TerrainHeight = cChunkDef::GetHeight(HeightMap, BlockX, BlockZ); a_Piece.MoveToGroundBy(TerrainHeight - FirstConnector.m_Pos.y + 1); } @@ -359,7 +359,7 @@ static cVillagePiecePool * g_PlainsVillagePools[] = -cVillageGen::cVillageGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth, int a_MaxSize, int a_MinDensity, int a_MaxDensity, cBiomeGen & a_BiomeGen, cTerrainHeightGen & a_HeightGen) : +cVillageGen::cVillageGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth, int a_MaxSize, int a_MinDensity, int a_MaxDensity, cBiomeGenPtr a_BiomeGen, cTerrainHeightGenPtr a_HeightGen) : super(a_Seed, a_GridSize, a_GridSize, a_MaxOffset, a_MaxOffset, a_MaxSize, a_MaxSize, 100), m_Noise(a_Seed + 1000), m_MaxDepth(a_MaxDepth), @@ -381,7 +381,7 @@ cGridStructGen::cStructurePtr cVillageGen::CreateStructure(int a_GridX, int a_Gr int ChunkX, ChunkZ; cChunkDef::BlockToChunk(a_OriginX, a_OriginZ, ChunkX, ChunkZ); cChunkDef::BiomeMap Biomes; - m_BiomeGen.GenBiomes(ChunkX, ChunkZ, Biomes); + m_BiomeGen->GenBiomes(ChunkX, ChunkZ, Biomes); // Check if all the biomes are village-friendly: // If just one is not, no village is created, because it's likely that an unfriendly biome is too close diff --git a/src/Generating/VillageGen.h b/src/Generating/VillageGen.h index 694ea2358..ed8d739df 100644 --- a/src/Generating/VillageGen.h +++ b/src/Generating/VillageGen.h @@ -21,7 +21,7 @@ class cVillageGen : { typedef cGridStructGen super; public: - cVillageGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth, int a_MaxSize, int a_MinDensity, int a_MaxDensity, cBiomeGen & a_BiomeGen, cTerrainHeightGen & a_HeightGen); + cVillageGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth, int a_MaxSize, int a_MinDensity, int a_MaxDensity, cBiomeGenPtr a_BiomeGen, cTerrainHeightGenPtr a_HeightGen); protected: class cVillage; // fwd: VillageGen.cpp @@ -42,10 +42,10 @@ protected: int m_MaxDensity; /** The underlying biome generator that defines whether the village is created or not */ - cBiomeGen & m_BiomeGen; + cBiomeGenPtr m_BiomeGen; /** The underlying height generator, used to position the prefabs crossing chunk borders */ - cTerrainHeightGen & m_HeightGen; + cTerrainHeightGenPtr m_HeightGen; // cGridStructGen overrides: diff --git a/src/Globals.h b/src/Globals.h index 4ee1352eb..e0a25ed83 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -361,19 +361,8 @@ void inline LOGD(const char* a_Format, ...) #define assert_test(x) ( !!(x) || (assert(!#x), exit(1), 0)) #endif -// Allow both Older versions of MSVC and newer versions of everything use a shared_ptr: -// Note that we cannot typedef, because C++ doesn't allow (partial) templates to be typedeffed. -#if (defined(_MSC_VER) && (_MSC_VER < 1600)) - // MSVC before 2010 doesn't have std::shared_ptr, but has std::tr1::shared_ptr, defined in <memory> included earlier - #define SharedPtr std::tr1::shared_ptr -#elif (defined(_MSC_VER) || (__cplusplus >= 201103L)) - // C++11 has std::shared_ptr in <memory>, included earlier - #define SharedPtr std::shared_ptr -#else - // C++03 has std::tr1::shared_ptr in <tr1/memory> - #include <tr1/memory> - #define SharedPtr std::tr1::shared_ptr -#endif +// Unified shared ptr from before C++11. Also no silly undercores. +#define SharedPtr std::shared_ptr @@ -419,6 +408,12 @@ typename std::enable_if<std::is_arithmetic<T>::value, C>::type CeilC(T a_Value) +//temporary replacement for std::make_unique until we get c++14 +template <class T, class... Args> +std::unique_ptr<T> make_unique(Args&&... args) +{ + return std::unique_ptr<T>(new T(args...)); +} #ifndef TOLUA_TEMPLATE_BIND @@ -436,3 +431,4 @@ typename std::enable_if<std::is_arithmetic<T>::value, C>::type CeilC(T a_Value) #include "BlockInfo.h" + diff --git a/src/ItemGrid.cpp b/src/ItemGrid.cpp index 2344dc0a5..1977216d8 100644 --- a/src/ItemGrid.cpp +++ b/src/ItemGrid.cpp @@ -637,14 +637,35 @@ void cItemGrid::GenerateRandomLootWithBooks(const cLootProbab * a_LootProbabs, s int Rnd = (Noise.IntNoise1DInt(i) / 7); int LootRnd = Rnd % TotalProbab; Rnd >>= 8; - cItem CurrentLoot = cItem(E_ITEM_BOOK, 1, 0); // TODO: enchantment + cItem CurrentLoot = cItem(E_ITEM_ENCHANTED_BOOK, 1, 0); + + // Choose the enchantments + cWeightedEnchantments Enchantments; + cEnchantments::AddItemEnchantmentWeights(Enchantments, E_ITEM_BOOK, 24 + Noise.IntNoise2DInt(a_Seed, TotalProbab) % 7); + int NumEnchantments = Noise.IntNoise3DInt(TotalProbab, Rnd, a_Seed) % 5; // The number of enchantments this book wil get. + + for (int j = 0; j <= NumEnchantments; j++) + { + cEnchantments Enchantment = cEnchantments::GenerateEnchantmentFromVector(Enchantments, Noise.IntNoise2DInt(NumEnchantments, i)); + CurrentLoot.m_Enchantments.Add(Enchantment); + cEnchantments::RemoveEnchantmentWeightFromVector(Enchantments, Enchantment); + cEnchantments::CheckEnchantmentConflictsFromVector(Enchantments, Enchantment); + } + for (size_t j = 0; j < a_CountLootProbabs; j++) { - LootRnd -= a_LootProbabs[i].m_Weight; + LootRnd -= a_LootProbabs[j].m_Weight; if (LootRnd < 0) { - CurrentLoot = a_LootProbabs[i].m_Item; - CurrentLoot.m_ItemCount = a_LootProbabs[i].m_MinAmount + (Rnd % (a_LootProbabs[i].m_MaxAmount - a_LootProbabs[i].m_MinAmount)); + CurrentLoot = a_LootProbabs[j].m_Item; + if ((a_LootProbabs[j].m_MaxAmount - a_LootProbabs[j].m_MinAmount) > 0) + { + CurrentLoot.m_ItemCount = a_LootProbabs[j].m_MinAmount + (Rnd % (a_LootProbabs[j].m_MaxAmount - a_LootProbabs[j].m_MinAmount)); + } + else + { + CurrentLoot.m_ItemCount = a_LootProbabs[j].m_MinAmount; + } Rnd >>= 8; break; } diff --git a/src/Protocol/MojangAPI.cpp b/src/Protocol/MojangAPI.cpp index 0a6716e6f..a4b4dbd3b 100644 --- a/src/Protocol/MojangAPI.cpp +++ b/src/Protocol/MojangAPI.cpp @@ -214,14 +214,17 @@ cMojangAPI::~cMojangAPI() -void cMojangAPI::Start(cIniFile & a_SettingsIni) +void cMojangAPI::Start(cIniFile & a_SettingsIni, bool a_ShouldAuth) { m_NameToUUIDServer = a_SettingsIni.GetValueSet("MojangAPI", "NameToUUIDServer", DEFAULT_NAME_TO_UUID_SERVER); m_NameToUUIDAddress = a_SettingsIni.GetValueSet("MojangAPI", "NameToUUIDAddress", DEFAULT_NAME_TO_UUID_ADDRESS); m_UUIDToProfileServer = a_SettingsIni.GetValueSet("MojangAPI", "UUIDToProfileServer", DEFAULT_UUID_TO_PROFILE_SERVER); m_UUIDToProfileAddress = a_SettingsIni.GetValueSet("MojangAPI", "UUIDToProfileAddress", DEFAULT_UUID_TO_PROFILE_ADDRESS); LoadCachesFromDisk(); - m_UpdateThread->Start(); + if (a_ShouldAuth) + { + m_UpdateThread->Start(); + } } diff --git a/src/Protocol/MojangAPI.h b/src/Protocol/MojangAPI.h index fa4c16e4e..393fd4baa 100644 --- a/src/Protocol/MojangAPI.h +++ b/src/Protocol/MojangAPI.h @@ -38,7 +38,7 @@ public: /** Initializes the API; reads the settings from the specified ini file. Loads cached results from disk. */ - void Start(cIniFile & a_SettingsIni); + void Start(cIniFile & a_SettingsIni, bool a_ShouldAuth); /** Connects to the specified server using SSL, sends the given request and receives the response. Checks Mojang certificates using the hard-coded Starfield root CA certificate. diff --git a/src/Protocol/Protocol.h b/src/Protocol/Protocol.h index 7225f663d..02a8a52f6 100644 --- a/src/Protocol/Protocol.h +++ b/src/Protocol/Protocol.h @@ -130,7 +130,7 @@ public: virtual void SendWholeInventory (const cWindow & a_Window) = 0; virtual void SendWindowClose (const cWindow & a_Window) = 0; virtual void SendWindowOpen (const cWindow & a_Window) = 0; - virtual void SendWindowProperty (const cWindow & a_Window, int a_Property, int a_Value) = 0; + virtual void SendWindowProperty (const cWindow & a_Window, short a_Property, short a_Value) = 0; /// Returns the ServerID used for authentication through session.minecraft.net virtual AString GetAuthServerID(void) = 0; diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index a7abd240f..204691ede 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -1439,7 +1439,7 @@ void cProtocol172::SendWindowOpen(const cWindow & a_Window) -void cProtocol172::SendWindowProperty(const cWindow & a_Window, int a_Property, int a_Value) +void cProtocol172::SendWindowProperty(const cWindow & a_Window, short a_Property, short a_Value) { ASSERT(m_State == 3); // In game mode? diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h index 7709df59d..f939bfb5e 100644 --- a/src/Protocol/Protocol17x.h +++ b/src/Protocol/Protocol17x.h @@ -134,7 +134,7 @@ public: virtual void SendWholeInventory (const cWindow & a_Window) override; virtual void SendWindowClose (const cWindow & a_Window) override; virtual void SendWindowOpen (const cWindow & a_Window) override; - virtual void SendWindowProperty (const cWindow & a_Window, int a_Property, int a_Value) override; + virtual void SendWindowProperty (const cWindow & a_Window, short a_Property, short a_Value) override; virtual AString GetAuthServerID(void) override { return m_AuthServerID; } diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index acdb48cf7..c9118c239 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -1500,7 +1500,7 @@ void cProtocol180::SendWindowOpen(const cWindow & a_Window) -void cProtocol180::SendWindowProperty(const cWindow & a_Window, int a_Property, int a_Value) +void cProtocol180::SendWindowProperty(const cWindow & a_Window, short a_Property, short a_Value) { ASSERT(m_State == 3); // In game mode? diff --git a/src/Protocol/Protocol18x.h b/src/Protocol/Protocol18x.h index 8c0b77a21..92d9825ef 100644 --- a/src/Protocol/Protocol18x.h +++ b/src/Protocol/Protocol18x.h @@ -133,7 +133,7 @@ public: virtual void SendWholeInventory (const cWindow & a_Window) override; virtual void SendWindowClose (const cWindow & a_Window) override; virtual void SendWindowOpen (const cWindow & a_Window) override; - virtual void SendWindowProperty (const cWindow & a_Window, int a_Property, int a_Value) override; + virtual void SendWindowProperty (const cWindow & a_Window, short a_Property, short a_Value) override; virtual AString GetAuthServerID(void) override { return m_AuthServerID; } diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index 15bcd03b1..0c1e83b67 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -350,7 +350,7 @@ void cProtocolRecognizer::SendHealth(void) -void cProtocolRecognizer::SendWindowProperty(const cWindow & a_Window, int a_Property, int a_Value) +void cProtocolRecognizer::SendWindowProperty(const cWindow & a_Window, short a_Property, short a_Value) { ASSERT(m_Protocol != NULL); m_Protocol->SendWindowProperty(a_Window, a_Property, a_Value); diff --git a/src/Protocol/ProtocolRecognizer.h b/src/Protocol/ProtocolRecognizer.h index b42cfdec2..dcf653e75 100644 --- a/src/Protocol/ProtocolRecognizer.h +++ b/src/Protocol/ProtocolRecognizer.h @@ -121,7 +121,7 @@ public: virtual void SendWholeInventory (const cWindow & a_Window) override; virtual void SendWindowClose (const cWindow & a_Window) override; virtual void SendWindowOpen (const cWindow & a_Window) override; - virtual void SendWindowProperty (const cWindow & a_Window, int a_Property, int a_Value) override; + virtual void SendWindowProperty (const cWindow & a_Window, short a_Property, short a_Value) override; virtual AString GetAuthServerID(void) override; diff --git a/src/Root.cpp b/src/Root.cpp index aa3d43cba..02455518c 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -142,8 +142,9 @@ void cRoot::Start(void) } LOG("Starting server..."); - m_MojangAPI.Start(IniFile); // Mojang API needs to be started before plugins, so that plugins may use it for DB upgrades on server init - if (!m_Server->InitServer(IniFile)) + bool ShouldAuthenticate = IniFile.GetValueSetB("Authentication", "Authenticate", true); + m_MojangAPI.Start(IniFile, ShouldAuthenticate); // Mojang API needs to be started before plugins, so that plugins may use it for DB upgrades on server init + if (!m_Server->InitServer(IniFile, ShouldAuthenticate)) { IniFile.WriteFile("settings.ini"); LOGERROR("Failure starting server, aborting..."); @@ -154,7 +155,8 @@ void cRoot::Start(void) m_WebAdmin->Init(); LOGD("Loading settings..."); - m_RankManager.Initialize(m_MojangAPI); + m_RankManager = new cRankManager(); + m_RankManager->Initialize(m_MojangAPI); m_CraftingRecipes = new cCraftingRecipes; m_FurnaceRecipe = new cFurnaceRecipe(); diff --git a/src/Root.h b/src/Root.h index 84c6a98ec..020a6cff0 100644 --- a/src/Root.h +++ b/src/Root.h @@ -86,7 +86,7 @@ public: cPluginManager * GetPluginManager (void) { return m_PluginManager; } // tolua_export cAuthenticator & GetAuthenticator (void) { return m_Authenticator; } cMojangAPI & GetMojangAPI (void) { return m_MojangAPI; } - cRankManager & GetRankManager (void) { return m_RankManager; } + cRankManager * GetRankManager (void) { return m_RankManager; } /** Queues a console command for execution through the cServer class. The command will be executed in the tick thread @@ -185,7 +185,7 @@ private: cPluginManager * m_PluginManager; cAuthenticator m_Authenticator; cMojangAPI m_MojangAPI; - cRankManager m_RankManager; + cRankManager * m_RankManager; cHTTPServer m_HTTPServer; bool m_bStop; diff --git a/src/Server.cpp b/src/Server.cpp index 969ffd693..db3ab2ed4 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -196,7 +196,7 @@ void cServer::PlayerDestroying(const cPlayer * a_Player) -bool cServer::InitServer(cIniFile & a_SettingsIni) +bool cServer::InitServer(cIniFile & a_SettingsIni, bool a_ShouldAuth) { m_Description = a_SettingsIni.GetValueSet("Server", "Description", "MCServer - in C++!"); m_MaxPlayers = a_SettingsIni.GetValueSetI("Server", "MaxPlayers", 100); @@ -247,7 +247,7 @@ bool cServer::InitServer(cIniFile & a_SettingsIni) m_bIsConnected = true; m_ServerID = "-"; - m_ShouldAuthenticate = a_SettingsIni.GetValueSetB("Authentication", "Authenticate", true); + m_ShouldAuthenticate = a_ShouldAuth; if (m_ShouldAuthenticate) { MTRand mtrand1; @@ -450,7 +450,7 @@ bool cServer::Start(void) bool cServer::Command(cClientHandle & a_Client, AString & a_Cmd) { - return cRoot::Get()->GetPluginManager()->CallHookChat(a_Client.GetPlayer(), a_Cmd); + return cRoot::Get()->GetPluginManager()->CallHookChat(*(a_Client.GetPlayer()), a_Cmd); } @@ -491,6 +491,17 @@ void cServer::ExecuteConsoleCommand(const AString & a_Cmd, cCommandOutputCallbac { if (split.size() > 1) { + cPluginManager::PluginMap map = cPluginManager::Get()->GetAllPlugins(); + + for (auto plugin_entry : map) + { + if (plugin_entry.first == split[1]) + { + a_Output.Out("Error! Plugin is already loaded!"); + a_Output.Finished(); + return; + } + } a_Output.Out(cPluginManager::Get()->LoadPlugin(split[1]) ? "Plugin loaded" : "Error occurred loading plugin"); } else diff --git a/src/Server.h b/src/Server.h index 6d659fa40..022794bbc 100644 --- a/src/Server.h +++ b/src/Server.h @@ -56,7 +56,7 @@ class cServer // tolua_export public: // tolua_export virtual ~cServer() {} - bool InitServer(cIniFile & a_SettingsIni); + bool InitServer(cIniFile & a_SettingsIni, bool a_ShouldAuth); // tolua_begin diff --git a/src/Simulator/FireSimulator.cpp b/src/Simulator/FireSimulator.cpp index 7ae84af7b..d3deee74a 100644 --- a/src/Simulator/FireSimulator.cpp +++ b/src/Simulator/FireSimulator.cpp @@ -333,7 +333,7 @@ void cFireSimulator::TrySpreadFire(cChunk * a_Chunk, int a_RelX, int a_RelY, int int a_PosX = x + a_Chunk->GetPosX() * cChunkDef::Width; int a_PosZ = z + a_Chunk->GetPosZ() * cChunkDef::Width; - if (cRoot::Get()->GetPluginManager()->CallHookBlockSpread(&m_World, a_PosX, y, a_PosZ, ssFireSpread)) + if (cRoot::Get()->GetPluginManager()->CallHookBlockSpread(m_World, a_PosX, y, a_PosZ, ssFireSpread)) { return; } @@ -382,7 +382,7 @@ void cFireSimulator::RemoveFuelNeighbors(cChunk * a_Chunk, int a_RelX, int a_Rel } bool ShouldReplaceFuel = (m_World.GetTickRandomNumber(MAX_CHANCE_REPLACE_FUEL) < m_ReplaceFuelChance); - if (ShouldReplaceFuel && !cRoot::Get()->GetPluginManager()->CallHookBlockSpread(&m_World, AbsX, Y, AbsZ, ssFireSpread)) + if (ShouldReplaceFuel && !cRoot::Get()->GetPluginManager()->CallHookBlockSpread(m_World, AbsX, Y, AbsZ, ssFireSpread)) { Neighbour->SetBlock(X, Y, Z, E_BLOCK_FIRE, 0); } diff --git a/src/UI/SlotArea.cpp b/src/UI/SlotArea.cpp index 999bed989..88d9f44fc 100644 --- a/src/UI/SlotArea.cpp +++ b/src/UI/SlotArea.cpp @@ -714,7 +714,7 @@ void cSlotAreaCrafting::UpdateRecipe(cPlayer & a_Player) { cCraftingGrid Grid(GetPlayerSlots(a_Player) + 1, m_GridSize, m_GridSize); cCraftingRecipe & Recipe = GetRecipeForPlayer(a_Player); - cRoot::Get()->GetCraftingRecipes()->GetRecipe(&a_Player, Grid, Recipe); + cRoot::Get()->GetCraftingRecipes()->GetRecipe(a_Player, Grid, Recipe); SetSlot(0, a_Player, Recipe.GetResult()); m_ParentWindow.SendSlot(a_Player, this, 0); } @@ -736,7 +736,7 @@ cCraftingRecipe & cSlotAreaCrafting::GetRecipeForPlayer(cPlayer & a_Player) // Not found. Add a new one: cCraftingGrid Grid(GetPlayerSlots(a_Player) + 1, m_GridSize, m_GridSize); cCraftingRecipe Recipe(Grid); - cRoot::Get()->GetCraftingRecipes()->GetRecipe(&a_Player, Grid, Recipe); + cRoot::Get()->GetCraftingRecipes()->GetRecipe(a_Player, Grid, Recipe); m_Recipes.push_back(std::make_pair(a_Player.GetUniqueID(), Recipe)); return m_Recipes.back().second; } diff --git a/src/UI/Window.cpp b/src/UI/Window.cpp index d83336f75..802d0d219 100644 --- a/src/UI/Window.cpp +++ b/src/UI/Window.cpp @@ -758,20 +758,7 @@ void cWindow::BroadcastWholeWindow(void) -void cWindow::BroadcastProgress(int a_Progressbar, int a_Value) -{ - cCSLock Lock(m_CS); - for (cPlayerList::iterator itr = m_OpenedBy.begin(); itr != m_OpenedBy.end(); ++itr) - { - (*itr)->GetClientHandle()->SendWindowProperty(*this, a_Progressbar, a_Value); - } // for itr - m_OpenedBy[] -} - - - - - -void cWindow::SetProperty(int a_Property, int a_Value) +void cWindow::SetProperty(short a_Property, short a_Value) { cCSLock Lock(m_CS); for (cPlayerList::iterator itr = m_OpenedBy.begin(), end = m_OpenedBy.end(); itr != end; ++itr) @@ -784,7 +771,7 @@ void cWindow::SetProperty(int a_Property, int a_Value) -void cWindow::SetProperty(int a_Property, int a_Value, cPlayer & a_Player) +void cWindow::SetProperty(short a_Property, short a_Value, cPlayer & a_Player) { a_Player.GetClientHandle()->SendWindowProperty(*this, a_Property, a_Value); } @@ -919,7 +906,7 @@ cEnchantingWindow::cEnchantingWindow(int a_BlockX, int a_BlockY, int a_BlockZ) : -void cEnchantingWindow::SetProperty(int a_Property, int a_Value) +void cEnchantingWindow::SetProperty(short a_Property, short a_Value) { if ((a_Property < 0) || ((size_t)a_Property >= ARRAYCOUNT(m_PropertyValue))) { @@ -935,7 +922,7 @@ void cEnchantingWindow::SetProperty(int a_Property, int a_Value) -void cEnchantingWindow::SetProperty(int a_Property, int a_Value, cPlayer & a_Player) +void cEnchantingWindow::SetProperty(short a_Property, short a_Value, cPlayer & a_Player) { if ((a_Property < 0) || ((size_t)a_Property >= ARRAYCOUNT(m_PropertyValue))) { @@ -951,7 +938,7 @@ void cEnchantingWindow::SetProperty(int a_Property, int a_Value, cPlayer & a_Pla -int cEnchantingWindow::GetPropertyValue(int a_Property) +short cEnchantingWindow::GetPropertyValue(short a_Property) { if ((a_Property < 0) || ((size_t)a_Property >= ARRAYCOUNT(m_PropertyValue))) { diff --git a/src/UI/Window.h b/src/UI/Window.h index 6b6dce346..26dd7f125 100644 --- a/src/UI/Window.h +++ b/src/UI/Window.h @@ -130,9 +130,6 @@ public: /// Sends the contents of the whole window to all clients of this window. void BroadcastWholeWindow(void); - - /// Sends the progressbar to all clients of this window (same as SetProperty) - void BroadcastProgress(int a_Progressbar, int a_Value); // tolua_begin @@ -140,10 +137,10 @@ public: void SetWindowTitle(const AString & a_WindowTitle) { m_WindowTitle = a_WindowTitle; } /// Sends the UpdateWindowProperty (0x69) packet to all clients of the window - virtual void SetProperty(int a_Property, int a_Value); + virtual void SetProperty(short a_Property, short a_Value); /// Sends the UpdateWindowPropert(0x69) packet to the specified player - virtual void SetProperty(int a_Property, int a_Value, cPlayer & a_Player); + virtual void SetProperty(short a_Property, short a_Value, cPlayer & a_Player); // tolua_end @@ -287,16 +284,16 @@ class cEnchantingWindow : typedef cWindow super; public: cEnchantingWindow(int a_BlockX, int a_BlockY, int a_BlockZ); - virtual void SetProperty(int a_Property, int a_Value, cPlayer & a_Player) override; - virtual void SetProperty(int a_Property, int a_Value) override; + virtual void SetProperty(short a_Property, short a_Value, cPlayer & a_Player) override; + virtual void SetProperty(short a_Property, short a_Value) override; /** Return the Value of a Property */ - int GetPropertyValue(int a_Property); + short GetPropertyValue(short a_Property); cSlotArea * m_SlotArea; protected: - int m_PropertyValue[3]; + short m_PropertyValue[3]; int m_BlockX, m_BlockY, m_BlockZ; }; diff --git a/src/World.cpp b/src/World.cpp index a3c804b44..1f9361386 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -256,14 +256,14 @@ cWorld::cWorld(const AString & a_WorldName, eDimension a_Dimension, const AStrin m_IsDeepSnowEnabled(false), m_ShouldLavaSpawnFire(true), m_VillagersShouldHarvestCrops(true), - m_SimulatorManager(NULL), - m_SandSimulator(NULL), + m_SimulatorManager(), + m_SandSimulator(), m_WaterSimulator(NULL), - m_LavaSimulator(NULL), - m_FireSimulator(NULL), + m_LavaSimulator(nullptr), + m_FireSimulator(), m_RedstoneSimulator(NULL), m_MaxPlayers(10), - m_ChunkMap(NULL), + m_ChunkMap(), m_bAnimals(true), m_Weather(eWeather_Sunny), m_WeatherInterval(24000), // Guaranteed 1 day of sunshine at server start :) @@ -303,11 +303,8 @@ cWorld::cWorld(const AString & a_WorldName, eDimension a_Dimension, const AStrin cWorld::~cWorld() { - delete m_SimulatorManager; m_SimulatorManager = NULL; - delete m_SandSimulator; m_SandSimulator = NULL; delete m_WaterSimulator; m_WaterSimulator = NULL; delete m_LavaSimulator; m_LavaSimulator = NULL; - delete m_FireSimulator; m_FireSimulator = NULL; delete m_RedstoneSimulator; m_RedstoneSimulator = NULL; UnloadUnusedChunks(); @@ -319,8 +316,6 @@ cWorld::~cWorld() Serializer.Save(); m_MapManager.SaveMapData(); - - delete m_ChunkMap; } @@ -631,7 +626,7 @@ void cWorld::Start(void) InitialiseAndLoadMobSpawningValues(IniFile); SetTimeOfDay(IniFile.GetValueSetI("General", "TimeInTicks", m_TimeOfDay)); - m_ChunkMap = new cChunkMap(this); + m_ChunkMap = make_unique<cChunkMap>(this); m_LastSave = 0; m_LastUnload = 0; @@ -641,16 +636,16 @@ void cWorld::Start(void) m_BlockTickQueueCopy.reserve(1000); // Simulators: - m_SimulatorManager = new cSimulatorManager(*this); + m_SimulatorManager = make_unique<cSimulatorManager>(*this); m_WaterSimulator = InitializeFluidSimulator(IniFile, "Water", E_BLOCK_WATER, E_BLOCK_STATIONARY_WATER); m_LavaSimulator = InitializeFluidSimulator(IniFile, "Lava", E_BLOCK_LAVA, E_BLOCK_STATIONARY_LAVA); - m_SandSimulator = new cSandSimulator(*this, IniFile); - m_FireSimulator = new cFireSimulator(*this, IniFile); + m_SandSimulator = make_unique<cSandSimulator>(*this, IniFile); + m_FireSimulator = make_unique<cFireSimulator>(*this, IniFile); m_RedstoneSimulator = InitializeRedstoneSimulator(IniFile); // Water, Lava and Redstone simulators get registered in their initialize function. - m_SimulatorManager->RegisterSimulator(m_SandSimulator, 1); - m_SimulatorManager->RegisterSimulator(m_FireSimulator, 1); + m_SimulatorManager->RegisterSimulator(m_SandSimulator.get(), 1); + m_SimulatorManager->RegisterSimulator(m_FireSimulator.get(), 1); m_Lighting.Start(this); m_Storage.Start(this, m_StorageSchema, m_StorageCompressionFactor); @@ -1059,7 +1054,6 @@ void cWorld::TickQueuedTasks(void) for (cTasks::iterator itr = Tasks.begin(), end = Tasks.end(); itr != end; ++itr) { (*itr)->Run(*this); - delete *itr; } // for itr - m_Tasks[] } @@ -1069,14 +1063,28 @@ void cWorld::TickQueuedTasks(void) void cWorld::TickScheduledTasks(void) { - // Make a copy of the tasks to avoid deadlocks on accessing m_Tasks + // Move the tasks to be executed to a seperate vector to avoid deadlocks on accessing m_Tasks cScheduledTasks Tasks; { cCSLock Lock(m_CSScheduledTasks); - while (!m_ScheduledTasks.empty() && (m_ScheduledTasks.front()->m_TargetTick < m_WorldAge)) + auto WorldAge = m_WorldAge; + + // Move all the due tasks from m_ScheduledTasks into Tasks: + for (auto itr = m_ScheduledTasks.begin(); itr != m_ScheduledTasks.end();) // Cannot use range-basd for, we're modifying the container { - Tasks.push_back(m_ScheduledTasks.front()); - m_ScheduledTasks.pop_front(); + if ((*itr)->m_TargetTick < WorldAge) + { + auto next = itr; + ++next; + Tasks.push_back(std::move(*itr)); + m_ScheduledTasks.erase(itr); + itr = next; + } + else + { + // All the eligible tasks have been moved, bail out now + break; + } } } @@ -1084,7 +1092,6 @@ void cWorld::TickScheduledTasks(void) for (cScheduledTasks::iterator itr = Tasks.begin(), end = Tasks.end(); itr != end; ++itr) { (*itr)->m_Task->Run(*this); - delete *itr; } // for itr - m_Tasks[] } @@ -2593,14 +2600,14 @@ void cWorld::UnloadUnusedChunks(void) void cWorld::QueueUnloadUnusedChunks(void) { - QueueTask(new cWorld::cTaskUnloadUnusedChunks); + QueueTask(make_unique<cWorld::cTaskUnloadUnusedChunks>()); } -void cWorld::CollectPickupsByPlayer(cPlayer * a_Player) +void cWorld::CollectPickupsByPlayer(cPlayer & a_Player) { m_ChunkMap->CollectPickupsByPlayer(a_Player); } @@ -2902,13 +2909,13 @@ bool cWorld::SetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, const AStrin AString Line2(a_Line2); AString Line3(a_Line3); AString Line4(a_Line4); - if (cRoot::Get()->GetPluginManager()->CallHookUpdatingSign(this, a_BlockX, a_BlockY, a_BlockZ, Line1, Line2, Line3, Line4, a_Player)) + if (cRoot::Get()->GetPluginManager()->CallHookUpdatingSign(*this, a_BlockX, a_BlockY, a_BlockZ, Line1, Line2, Line3, Line4, a_Player)) { return false; } if (m_ChunkMap->SetSignLines(a_BlockX, a_BlockY, a_BlockZ, Line1, Line2, Line3, Line4)) { - cRoot::Get()->GetPluginManager()->CallHookUpdatedSign(this, a_BlockX, a_BlockY, a_BlockZ, Line1, Line2, Line3, Line4, a_Player); + cRoot::Get()->GetPluginManager()->CallHookUpdatedSign(*this, a_BlockX, a_BlockY, a_BlockZ, Line1, Line2, Line3, Line4, a_Player); return true; } return false; @@ -3049,17 +3056,17 @@ void cWorld::SaveAllChunks(void) void cWorld::QueueSaveAllChunks(void) { - QueueTask(new cWorld::cTaskSaveAllChunks); + QueueTask(make_unique<cWorld::cTaskSaveAllChunks>()); } -void cWorld::QueueTask(cTask * a_Task) +void cWorld::QueueTask(std::unique_ptr<cTask> a_Task) { cCSLock Lock(m_CSTasks); - m_Tasks.push_back(a_Task); + m_Tasks.push_back(std::move(a_Task)); } @@ -3076,11 +3083,11 @@ void cWorld::ScheduleTask(int a_DelayTicks, cTask * a_Task) { if ((*itr)->m_TargetTick >= TargetTick) { - m_ScheduledTasks.insert(itr, new cScheduledTask(TargetTick, a_Task)); + m_ScheduledTasks.insert(itr, make_unique<cScheduledTask>(TargetTick, a_Task)); return; } } - m_ScheduledTasks.push_back(new cScheduledTask(TargetTick, a_Task)); + m_ScheduledTasks.push_back(make_unique<cScheduledTask>(TargetTick, a_Task)); } @@ -3633,7 +3640,7 @@ bool cWorld::cChunkGeneratorCallbacks::HasChunkAnyClients(int a_ChunkX, int a_Ch void cWorld::cChunkGeneratorCallbacks::CallHookChunkGenerating(cChunkDesc & a_ChunkDesc) { cPluginManager::Get()->CallHookChunkGenerating( - m_World, a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ(), &a_ChunkDesc + *m_World, a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ(), &a_ChunkDesc ); } @@ -3644,7 +3651,7 @@ void cWorld::cChunkGeneratorCallbacks::CallHookChunkGenerating(cChunkDesc & a_Ch void cWorld::cChunkGeneratorCallbacks::CallHookChunkGenerated (cChunkDesc & a_ChunkDesc) { cPluginManager::Get()->CallHookChunkGenerated( - m_World, a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ(), &a_ChunkDesc + *m_World, a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ(), &a_ChunkDesc ); } diff --git a/src/World.h b/src/World.h index 02d0a92b8..0ced90562 100644 --- a/src/World.h +++ b/src/World.h @@ -103,7 +103,7 @@ public: virtual void Run(cWorld & a_World) = 0; } ; - typedef std::vector<cTask *> cTasks; + typedef std::vector<std::unique_ptr<cTask>> cTasks; class cTaskSaveAllChunks : @@ -298,7 +298,7 @@ public: /** Queues a task to unload unused chunks onto the tick thread. The prefferred way of unloading*/ void QueueUnloadUnusedChunks(void); // tolua_export - void CollectPickupsByPlayer(cPlayer * a_Player); + void CollectPickupsByPlayer(cPlayer & a_Player); /** Adds the player to the world. Uses a queue to store the player object until the Tick thread processes the addition event. @@ -506,7 +506,7 @@ public: // tolua_end - inline cSimulatorManager * GetSimulatorManager(void) { return m_SimulatorManager; } + inline cSimulatorManager * GetSimulatorManager(void) { return m_SimulatorManager.get(); } inline cFluidSimulator * GetWaterSimulator(void) { return m_WaterSimulator; } inline cFluidSimulator * GetLavaSimulator (void) { return m_LavaSimulator; } @@ -671,7 +671,7 @@ public: void QueueSaveAllChunks(void); // tolua_export /** Queues a task onto the tick thread. The task object will be deleted once the task is finished */ - void QueueTask(cTask * a_Task); // Exported in ManualBindings.cpp + void QueueTask(std::unique_ptr<cTask> a_Task); // Exported in ManualBindings.cpp /** Queues a task onto the tick thread, with the specified delay. The task object will be deleted once the task is finished */ @@ -764,7 +764,7 @@ public: cChunkGenerator & GetGenerator(void) { return m_Generator; } cWorldStorage & GetStorage (void) { return m_Storage; } - cChunkMap * GetChunkMap (void) { return m_ChunkMap; } + cChunkMap * GetChunkMap (void) { return m_ChunkMap.get(); } /** Sets the blockticking to start at the specified block. Only one blocktick per chunk may be set, second call overwrites the first call */ void SetNextBlockTick(int a_BlockX, int a_BlockY, int a_BlockZ); // tolua_export @@ -861,7 +861,8 @@ private: } }; - typedef std::list<cScheduledTask *> cScheduledTasks; + typedef std::unique_ptr<cScheduledTask> cScheduledTaskPtr; + typedef std::list<cScheduledTaskPtr> cScheduledTasks; AString m_WorldName; @@ -913,11 +914,11 @@ private: std::vector<BlockTickQueueItem *> m_BlockTickQueue; std::vector<BlockTickQueueItem *> m_BlockTickQueueCopy; // Second is for safely removing the objects from the queue - cSimulatorManager * m_SimulatorManager; - cSandSimulator * m_SandSimulator; - cFluidSimulator * m_WaterSimulator; - cFluidSimulator * m_LavaSimulator; - cFireSimulator * m_FireSimulator; + std::unique_ptr<cSimulatorManager> m_SimulatorManager; + std::unique_ptr<cSandSimulator> m_SandSimulator; + cFluidSimulator * m_WaterSimulator; + cFluidSimulator * m_LavaSimulator; + std::unique_ptr<cFireSimulator> m_FireSimulator; cRedstoneSimulator<cChunk, cWorld> * m_RedstoneSimulator; cCriticalSection m_CSPlayers; @@ -927,7 +928,7 @@ private: unsigned int m_MaxPlayers; - cChunkMap * m_ChunkMap; + std::unique_ptr<cChunkMap> m_ChunkMap; bool m_bAnimals; std::set<eMonsterType> m_AllowedMobs; |