diff --git a/MCServer/Plugins/HookNotify/HookNotify.lua b/MCServer/Plugins/HookNotify/HookNotify.lua index d0221b668..519d837fe 100644 --- a/MCServer/Plugins/HookNotify/HookNotify.lua +++ b/MCServer/Plugins/HookNotify/HookNotify.lua @@ -13,6 +13,7 @@ function Initialize(Plugin) Plugin:SetVersion(1) PluginManager = cRoot:Get():GetPluginManager() + PluginManager:AddHook(Plugin, cPluginManager.HOOK_BLOCK_TO_PICKUPS); PluginManager:AddHook(Plugin, cPluginManager.HOOK_CHAT); PluginManager:AddHook(Plugin, cPluginManager.HOOK_CHUNK_GENERATED); PluginManager:AddHook(Plugin, cPluginManager.HOOK_CHUNK_GENERATING); @@ -72,6 +73,16 @@ end +function OnBlockToPickups(...) + LOG("************************"); + LogHook("OnBlockToPickups", unpack(arg)); + LOG("========================"); +end; + + + + + function OnChat(...) LogHook("OnChat", unpack(arg)); end diff --git a/source/Bindings.cpp b/source/Bindings.cpp index 43e93cdd3..4ae632920 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 01/27/13 05:58:09. +** Generated automatically by tolua++-1.0.92 on 01/27/13 05:59:07. */ #ifndef __cplusplus @@ -21254,6 +21254,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_endmodule(tolua_S); tolua_cclass(tolua_S,"cPluginManager","cPluginManager","",NULL); tolua_beginmodule(tolua_S,"cPluginManager"); + tolua_constant(tolua_S,"HOOK_BLOCK_TO_PICKUPS",cPluginManager::HOOK_BLOCK_TO_PICKUPS); tolua_constant(tolua_S,"HOOK_CHAT",cPluginManager::HOOK_CHAT); tolua_constant(tolua_S,"HOOK_CHUNK_GENERATED",cPluginManager::HOOK_CHUNK_GENERATED); tolua_constant(tolua_S,"HOOK_CHUNK_GENERATING",cPluginManager::HOOK_CHUNK_GENERATING); diff --git a/source/Bindings.h b/source/Bindings.h index 97c11871e..4459db37f 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 01/27/13 05:58:09. +** Generated automatically by tolua++-1.0.92 on 01/27/13 05:59:07. */ /* Exported function */ diff --git a/source/Blocks/BlockHandler.cpp b/source/Blocks/BlockHandler.cpp index 715db910e..5c535e052 100644 --- a/source/Blocks/BlockHandler.cpp +++ b/source/Blocks/BlockHandler.cpp @@ -3,6 +3,8 @@ #include "BlockHandler.h" #include "../Item.h" #include "../World.h" +#include "../Root.h" +#include "../PluginManager.h" #include "BlockSand.h" #include "BlockGravel.h" #include "BlockDoor.h" @@ -321,11 +323,15 @@ void cBlockHandler::ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) -void cBlockHandler::DropBlock(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) +void cBlockHandler::DropBlock(cWorld * a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ) { cItems Pickups; NIBBLETYPE Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); ConvertToPickups(Pickups, Meta); + + // Allow plugins to modify the pickups: + cRoot::Get()->GetPluginManager()->CallHookBlockToPickups(a_World, a_Digger, a_BlockX, a_BlockY, a_BlockZ, m_BlockType, Meta, Pickups); + if (!Pickups.empty()) { a_World->SpawnItemPickups(Pickups, a_BlockX, a_BlockY, a_BlockZ); @@ -423,7 +429,7 @@ void cBlockHandler::Check(cWorld * a_World, int a_BlockX, int a_BlockY, int a_Bl { if (DoesDropOnUnsuitable()) { - DropBlock(a_World, a_BlockX, a_BlockY, a_BlockZ); + DropBlock(a_World, NULL, a_BlockX, a_BlockY, a_BlockZ); } a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); diff --git a/source/Blocks/BlockHandler.h b/source/Blocks/BlockHandler.h index d2ef527da..e551668f9 100644 --- a/source/Blocks/BlockHandler.h +++ b/source/Blocks/BlockHandler.h @@ -68,8 +68,8 @@ public: /// Called when the item is mined to convert it into pickups. Pickups may specify multiple items. virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta); - /// Handles the dropping of a block based on what ConvertToDrops() returns. This will not destroy the block - virtual void DropBlock(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ); + /// Handles the dropping of a block based on what ConvertToDrops() returns. This will not destroy the block. a_Digger is the entity causing the drop; it may be NULL + virtual void DropBlock(cWorld * a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ); /// Returns step sound name of block virtual const char * GetStepSound(void); diff --git a/source/Blocks/BlockLeaves.h b/source/Blocks/BlockLeaves.h index 76b5e6d60..101f7c087 100644 --- a/source/Blocks/BlockLeaves.h +++ b/source/Blocks/BlockLeaves.h @@ -113,7 +113,7 @@ public: return; } // Decay the leaves: - DropBlock(a_World, a_BlockX, a_BlockY, a_BlockZ); + DropBlock(a_World, NULL, a_BlockX, a_BlockY, a_BlockZ); a_World->DigBlock(a_BlockX, a_BlockY, a_BlockZ); diff --git a/source/Items/ItemBucket.h b/source/Items/ItemBucket.h index 18b344914..35cc1bd2b 100644 --- a/source/Items/ItemBucket.h +++ b/source/Items/ItemBucket.h @@ -152,7 +152,7 @@ public: cBlockHandler * Handler = BlockHandler(CurrentBlock); if (Handler->DoesDropOnUnsuitable()) { - Handler->DropBlock(a_World, a_BlockX, a_BlockY, a_BlockZ); + Handler->DropBlock(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ); } } diff --git a/source/Items/ItemHandler.cpp b/source/Items/ItemHandler.cpp index eaac6ba3c..4a465c272 100644 --- a/source/Items/ItemHandler.cpp +++ b/source/Items/ItemHandler.cpp @@ -222,16 +222,16 @@ bool cItemHandler::OnDiggingBlock(cWorld * a_World, cPlayer * a_Player, cItem * -void cItemHandler::OnBlockDestroyed(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z) +void cItemHandler::OnBlockDestroyed(cWorld * a_World, cPlayer * a_Player, cItem * a_Item, int a_BlockX, int a_BlockY, int a_BlockZ) { - char Block = a_World->GetBlock(a_X, a_Y, a_Z); - cBlockHandler *Handler = cBlockHandler::GetBlockHandler(Block); + BLOCKTYPE Block = a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ); + cBlockHandler * Handler = cBlockHandler::GetBlockHandler(Block); - if(a_Player->GetGameMode() == eGameMode_Survival) + if (a_Player->GetGameMode() == eGameMode_Survival) { - if(!BlockRequiresSpecialTool(Block) || CanHarvestBlock(Block)) + if (!BlockRequiresSpecialTool(Block) || CanHarvestBlock(Block)) { - Handler->DropBlock(a_World, a_X, a_Y, a_Z); + Handler->DropBlock(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ); } } @@ -242,7 +242,7 @@ void cItemHandler::OnBlockDestroyed(cWorld *a_World, cPlayer *a_Player, cItem *a -void cItemHandler::OnFoodEaten(cWorld *a_World, cPlayer *a_Player, cItem *a_Item) +void cItemHandler::OnFoodEaten(cWorld * a_World, cPlayer * a_Player, cItem * a_Item) { } diff --git a/source/Items/ItemHandler.h b/source/Items/ItemHandler.h index f03184704..58e7324d8 100644 --- a/source/Items/ItemHandler.h +++ b/source/Items/ItemHandler.h @@ -28,7 +28,7 @@ public: virtual bool OnDiggingBlock(cWorld * a_World, cPlayer * a_Player, cItem * a_HeldItem, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace); /// Called when the player destroys a block using this item. This also calls the drop function for the destroyed block - virtual void OnBlockDestroyed(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z); + virtual void OnBlockDestroyed(cWorld * a_World, cPlayer * a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z); /// Called after the player has eaten this item. virtual void OnFoodEaten(cWorld *a_World, cPlayer *a_Player, cItem *a_Item); diff --git a/source/Items/ItemShovel.h b/source/Items/ItemShovel.h index b1260311e..7914a1703 100644 --- a/source/Items/ItemShovel.h +++ b/source/Items/ItemShovel.h @@ -20,12 +20,12 @@ public: } - virtual bool OnDiggingBlock(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override + virtual bool OnDiggingBlock(cWorld * a_World, cPlayer * a_Player, cItem * a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override { BLOCKTYPE Block = a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ); if (Block == E_BLOCK_SNOW) { - BlockHandler(Block)->DropBlock(a_World, a_BlockX, a_BlockY, a_BlockZ); + BlockHandler(Block)->DropBlock(a_World, a_Player, a_BlockX, a_BlockY, a_BlockZ); a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); a_Player->UseEquippedItem(); diff --git a/source/ManualBindings.cpp b/source/ManualBindings.cpp index 2af64ce53..be4a1cb66 100644 --- a/source/ManualBindings.cpp +++ b/source/ManualBindings.cpp @@ -908,7 +908,7 @@ void ManualBindings::Bind( lua_State* tolua_S ) tolua_function(tolua_S, "LOGWARN", tolua_LOGWARN); tolua_function(tolua_S, "LOGERROR", tolua_LOGERROR); tolua_function(tolua_S, "Log", tolua_LOG); // Deprecated - + tolua_beginmodule(tolua_S, "cRoot"); tolua_function(tolua_S, "ForEachWorld", tolua_cRoot_ForEachWorld); tolua_function(tolua_S, "FindAndDoWithPlayer", tolua_cRoot_FindAndDoWithPlayer); diff --git a/source/Piston.cpp b/source/Piston.cpp index 49093df95..d179d70b6 100644 --- a/source/Piston.cpp +++ b/source/Piston.cpp @@ -98,7 +98,7 @@ void cPiston::ExtendPiston( int pistx, int pisty, int pistz ) cBlockHandler * Handler = BlockHandler(currBlock); if (Handler->DoesDropOnUnsuitable()) { - Handler->DropBlock(m_World, pistx, pisty, pistz); + Handler->DropBlock(m_World, NULL, pistx, pisty, pistz); } } int oldx = pistx, oldy = pisty, oldz = pistz; diff --git a/source/Plugin.cpp b/source/Plugin.cpp index 6857215e6..0dab44e78 100644 --- a/source/Plugin.cpp +++ b/source/Plugin.cpp @@ -38,18 +38,18 @@ void cPlugin::Tick(float a_Dt) -/* -// TODO -bool cPlugin::OnBlockToPickup(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups) +bool cPlugin::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) { + UNUSED(a_World); + UNUSED(a_Digger); + UNUSED(a_BlockX); + UNUSED(a_BlockY); + UNUSED(a_BlockZ); UNUSED(a_BlockType); UNUSED(a_BlockMeta); - UNUSED(a_Player); - UNUSED(a_EquippedItem); UNUSED(a_Pickups); return false; } -*/ diff --git a/source/Plugin.h b/source/Plugin.h index be453b811..5988fb7b1 100644 --- a/source/Plugin.h +++ b/source/Plugin.h @@ -48,7 +48,7 @@ public: * On all these functions, return true if you want to override default behavior and not call other plugins on that callback. * You can also return false, so default behavior is used. **/ - // TODO: virtual bool OnBlockToPickup (BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups); + 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); virtual bool OnChat (cPlayer * a_Player, const AString & a_Message); virtual bool OnChunkGenerated (cWorld * a_World, int a_ChunkX, int a_ChunkZ); virtual bool OnChunkGenerating (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_pLuaChunk); diff --git a/source/PluginManager.cpp b/source/PluginManager.cpp index cda7a0dba..2fada4714 100644 --- a/source/PluginManager.cpp +++ b/source/PluginManager.cpp @@ -213,73 +213,26 @@ void cPluginManager::Tick(float a_Dt) -/* -bool cPluginManager::CallHookBlockToPickup( - BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, - const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups +bool cPluginManager::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 ) { - HookMap::iterator Plugins = m_Hooks.find(HOOK_POST_CRAFTING); + HookMap::iterator Plugins = m_Hooks.find(HOOK_BLOCK_TO_PICKUPS); if (Plugins == m_Hooks.end()) { return false; } for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) { - if ((*itr)->OnBlockToPickup(a_BlockType, a_BlockMeta, a_Player, a_EquippedItem, a_Pickups)) + if ((*itr)->OnBlockToPickups(a_World, a_Digger, a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_Pickups)) { return true; } } return false; } -*/ - - - - - -/* -bool cPluginManager::CallHookBlockDig(cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status, BLOCKTYPE a_OldBlock, NIBBLETYPE a_OldMeta) -{ - HookMap::iterator Plugins = m_Hooks.find(HOOK_BLOCK_DIG); - if (Plugins == m_Hooks.end()) - { - return false; - } - for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) - { - if ((*itr)->OnBlockDig(a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_Status, a_OldBlock, a_OldMeta)) - { - return true; - } - } - return false; -} -*/ - - - - - -/* -bool cPluginManager::CallHookBlockPlace(cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, const cItem & a_HeldItem) -{ - HookMap::iterator Plugins = m_Hooks.find(HOOK_BLOCK_PLACE); - if (Plugins == m_Hooks.end()) - { - return false; - } - for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) - { - if ((*itr)->OnBlockPlace(a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_HeldItem)) - { - return true; - } - } - return false; -} -*/ diff --git a/source/PluginManager.h b/source/PluginManager.h index 4de79f539..cbcfb96a2 100644 --- a/source/PluginManager.h +++ b/source/PluginManager.h @@ -46,6 +46,7 @@ public: // tolua_export // tolua_begin enum PluginHook { + HOOK_BLOCK_TO_PICKUPS, HOOK_CHAT, HOOK_CHUNK_GENERATED, HOOK_CHUNK_GENERATING, @@ -97,7 +98,7 @@ public: // tolua_export unsigned int GetNumPlugins() const; // tolua_export - // TODO: bool CallHookBlockToPickup (BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups); + 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, const AString & a_Message); bool CallHookChunkGenerated (cWorld * a_World, int a_ChunkX, int a_ChunkZ); bool CallHookChunkGenerating (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_Chunk); diff --git a/source/Plugin_NewLua.cpp b/source/Plugin_NewLua.cpp index ef7c148be..0ddfb54f8 100644 --- a/source/Plugin_NewLua.cpp +++ b/source/Plugin_NewLua.cpp @@ -164,6 +164,39 @@ void cPlugin_NewLua::Tick(float a_Dt) +bool cPlugin_NewLua::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); + const char * FnName = GetHookFnName(cPluginManager::HOOK_BLOCK_TO_PICKUPS); + ASSERT(FnName != NULL); + if (!PushFunction(FnName)) + { + return false; + } + + tolua_pushusertype(m_LuaState, a_World, "cWorld"); + tolua_pushusertype(m_LuaState, a_Digger, "cEntity"); + tolua_pushnumber (m_LuaState, a_BlockX); + tolua_pushnumber (m_LuaState, a_BlockY); + tolua_pushnumber (m_LuaState, a_BlockZ); + tolua_pushnumber (m_LuaState, a_BlockType); + tolua_pushnumber (m_LuaState, a_BlockMeta); + tolua_pushusertype(m_LuaState, &a_Pickups, "cItems"); + + if (!CallFunction(8, 1, FnName)) + { + return false; + } + + bool bRetVal = (tolua_toboolean(m_LuaState, -1, 0) > 0); + lua_pop(m_LuaState, 1); + return bRetVal; +} + + + + + bool cPlugin_NewLua::OnChat(cPlayer * a_Player, const AString & a_Message) { cCSLock Lock(m_CriticalSection); @@ -1154,6 +1187,7 @@ const char * cPlugin_NewLua::GetHookFnName(cPluginManager::PluginHook a_Hook) { switch (a_Hook) { + case cPluginManager::HOOK_BLOCK_TO_PICKUPS: return "OnBlockToPickups"; case cPluginManager::HOOK_CHAT: return "OnChat"; case cPluginManager::HOOK_CHUNK_GENERATED: return "OnChunkGenerated"; case cPluginManager::HOOK_CHUNK_GENERATING: return "OnChunkGenerating"; diff --git a/source/Plugin_NewLua.h b/source/Plugin_NewLua.h index a038b88eb..45152e4d7 100644 --- a/source/Plugin_NewLua.h +++ b/source/Plugin_NewLua.h @@ -30,7 +30,7 @@ public: virtual void Tick(float a_Dt) override; - // TODO: virtual bool OnBlockToPickup (BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups) 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, const AString & a_Message) override; virtual bool OnChunkGenerated (cWorld * a_World, int a_ChunkX, int a_ChunkZ) override; virtual bool OnChunkGenerating (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_pLuaChunk ) override; diff --git a/source/Simulator/ClassicFluidSimulator.cpp b/source/Simulator/ClassicFluidSimulator.cpp index 232e8205d..e195ffdc5 100644 --- a/source/Simulator/ClassicFluidSimulator.cpp +++ b/source/Simulator/ClassicFluidSimulator.cpp @@ -384,7 +384,7 @@ void cClassicFluidSimulator::Simulate(float a_Dt) cBlockHandler * Handler = BlockHandler(DownID); if (Handler->DoesDropOnUnsuitable()) { - Handler->DropBlock(m_World, pos.x, pos.y - 1, pos.z); + Handler->DropBlock(m_World, NULL, pos.x, pos.y - 1, pos.z); } } if (pos.y > 0) @@ -420,7 +420,7 @@ void cClassicFluidSimulator::Simulate(float a_Dt) cBlockHandler * Handler = BlockHandler(DownID); if (Handler->DoesDropOnUnsuitable()) { - Handler->DropBlock(m_World, p.x, p.y, p.z); + Handler->DropBlock(m_World, NULL, p.x, p.y, p.z); } } diff --git a/source/Simulator/FloodyFluidSimulator.cpp b/source/Simulator/FloodyFluidSimulator.cpp index e89bb6bf6..9d4cda2fc 100644 --- a/source/Simulator/FloodyFluidSimulator.cpp +++ b/source/Simulator/FloodyFluidSimulator.cpp @@ -240,7 +240,7 @@ void cFloodyFluidSimulator::SpreadToNeighbor(int a_BlockX, int a_BlockY, int a_B cBlockHandler * Handler = BlockHandler(Block); if (Handler->DoesDropOnUnsuitable()) { - Handler->DropBlock(m_World, a_BlockX, a_BlockY, a_BlockZ); + Handler->DropBlock(m_World, NULL, a_BlockX, a_BlockY, a_BlockZ); } }