From 339d55511127981335193d07037719a4b26c4600 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sat, 29 Mar 2014 15:26:41 +0100 Subject: [PATCH 1/5] Added HOOK_PROJECTILE_HIT_ENTITY --- src/Bindings/Plugin.h | 1 + src/Bindings/PluginLua.cpp | 20 ++++++++++++++++++++ src/Bindings/PluginLua.h | 1 + src/Bindings/PluginManager.cpp | 21 +++++++++++++++++++++ src/Bindings/PluginManager.h | 5 +++++ src/Entities/ProjectileEntity.cpp | 6 ++++++ 6 files changed, 54 insertions(+) diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h index 057fa0304..75b04d12f 100644 --- a/src/Bindings/Plugin.h +++ b/src/Bindings/Plugin.h @@ -90,6 +90,7 @@ public: 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 OnProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity) = 0; virtual bool OnSpawnedEntity (cWorld & a_World, cEntity & a_Entity) = 0; virtual bool OnSpawnedMonster (cWorld & a_World, cMonster & a_Monster) = 0; virtual bool OnSpawningEntity (cWorld & a_World, cEntity & a_Entity) = 0; diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp index 4f0e13f12..d4e4b3ee8 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -1108,6 +1108,26 @@ bool cPluginLua::OnPreCrafting(const cPlayer * a_Player, const cCraftingGrid * a +bool cPluginLua::OnProjectileHitEntity(cProjectileEntity & a_Projectile, cEntity & a_HitEntity) +{ + cCSLock Lock(m_CriticalSection); + bool res = false; + cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_PROJECTILE_HIT_ENTITY]; + for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) + { + m_LuaState.Call((int)(**itr), &a_Projectile, &a_HitEntity, cLuaState::Return, res); + if (res) + { + return true; + } + } + return false; +} + + + + + bool cPluginLua::OnSpawnedEntity(cWorld & a_World, cEntity & a_Entity) { cCSLock Lock(m_CriticalSection); diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h index f51056186..1533b1a66 100644 --- a/src/Bindings/PluginLua.h +++ b/src/Bindings/PluginLua.h @@ -113,6 +113,7 @@ public: 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 OnProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity) override; virtual bool OnSpawnedEntity (cWorld & a_World, cEntity & a_Entity) override; virtual bool OnSpawnedMonster (cWorld & a_World, cMonster & a_Monster) override; virtual bool OnSpawningEntity (cWorld & a_World, cEntity & a_Entity) override; diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index 7d346c522..aa2c09a3d 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -1154,6 +1154,27 @@ bool cPluginManager::CallHookPreCrafting(const cPlayer * a_Player, const cCrafti +bool cPluginManager::CallHookProjectileHitEntity(cProjectileEntity & a_Projectile, cEntity & a_HitEntity) +{ + HookMap::iterator Plugins = m_Hooks.find(HOOK_PROJECTILE_HIT_ENTITY); + if (Plugins == m_Hooks.end()) + { + return false; + } + for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) + { + if ((*itr)->OnProjectileHitEntity(a_Projectile, a_HitEntity)) + { + return true; + } + } + return false; +} + + + + + bool cPluginManager::CallHookSpawnedEntity(cWorld & a_World, cEntity & a_Entity) { HookMap::iterator Plugins = m_Hooks.find(HOOK_SPAWNED_ENTITY); diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index 7895be959..c5071ee83 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -18,6 +18,9 @@ class cChunkDesc; // fwd: Entities/Entity.h class cEntity; +// fwd: Entities/ProjectileEntity.h +class cProjectileEntity; + // fwd: Mobs/Monster.h class cMonster; @@ -102,6 +105,7 @@ public: // tolua_export HOOK_PLUGINS_LOADED, HOOK_POST_CRAFTING, HOOK_PRE_CRAFTING, + HOOK_PROJECTILE_HIT_ENTITY, HOOK_SPAWNED_ENTITY, HOOK_SPAWNED_MONSTER, HOOK_SPAWNING_ENTITY, @@ -201,6 +205,7 @@ public: // tolua_export 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 CallHookProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity); bool CallHookSpawnedEntity (cWorld & a_World, cEntity & a_Entity); bool CallHookSpawnedMonster (cWorld & a_World, cMonster & a_Monster); bool CallHookSpawningEntity (cWorld & a_World, cEntity & a_Entity); diff --git a/src/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp index f4ab825f2..bc359e1da 100644 --- a/src/Entities/ProjectileEntity.cpp +++ b/src/Entities/ProjectileEntity.cpp @@ -4,6 +4,7 @@ // Implements the cProjectileEntity class representing the common base class for projectiles, as well as individual projectile types #include "Globals.h" +#include "../Bindings/PluginManager.h" #include "ProjectileEntity.h" #include "../ClientHandle.h" #include "Player.h" @@ -148,6 +149,11 @@ public: // TODO: Some entities don't interact with the projectiles (pickups, falling blocks) // TODO: Allow plugins to interfere about which entities can be hit + if (cPluginManager::Get()->CallHookProjectileHitEntity(*m_Projectile, *a_Entity)) + { + // A plugin disagreed. + return false; + } if (LineCoeff < m_MinCoeff) { From a6ef40cb6efa1b8da549c81c7e1137d523240c17 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sat, 29 Mar 2014 15:43:03 +0100 Subject: [PATCH 2/5] Fixed error when the hook gets called. --- src/Bindings/LuaState.cpp | 12 ++++++++++++ src/Bindings/LuaState.h | 2 ++ src/Entities/ProjectileEntity.cpp | 1 - 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp index 47380b8a7..13eb17f7d 100644 --- a/src/Bindings/LuaState.cpp +++ b/src/Bindings/LuaState.cpp @@ -479,6 +479,18 @@ void cLuaState::Push(cEntity * a_Entity) +void cLuaState::Push(cProjectileEntity * a_ProjectileEntity) +{ + ASSERT(IsValid()); + + tolua_pushusertype(m_LuaState, a_ProjectileEntity, "cProjectileEntity"); + m_NumCurrentFunctionArgs += 1; +} + + + + + void cLuaState::Push(cMonster * a_Monster) { ASSERT(IsValid()); diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h index f0047b362..b9ca2f29b 100644 --- a/src/Bindings/LuaState.h +++ b/src/Bindings/LuaState.h @@ -38,6 +38,7 @@ extern "C" class cWorld; class cPlayer; class cEntity; +class cProjectileEntity; class cMonster; class cItem; class cItems; @@ -183,6 +184,7 @@ public: void Push(cPlayer * a_Player); void Push(const cPlayer * a_Player); void Push(cEntity * a_Entity); + void Push(cProjectileEntity * a_ProjectileEntity); void Push(cMonster * a_Monster); void Push(cItem * a_Item); void Push(cItems * a_Items); diff --git a/src/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp index bc359e1da..07cb34f35 100644 --- a/src/Entities/ProjectileEntity.cpp +++ b/src/Entities/ProjectileEntity.cpp @@ -148,7 +148,6 @@ public: } // TODO: Some entities don't interact with the projectiles (pickups, falling blocks) - // TODO: Allow plugins to interfere about which entities can be hit if (cPluginManager::Get()->CallHookProjectileHitEntity(*m_Projectile, *a_Entity)) { // A plugin disagreed. From ec4638a228edcf4c745088838e972ea07edc7cba Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sat, 29 Mar 2014 16:00:45 +0100 Subject: [PATCH 3/5] Added HOOK_PROJECTILE_HIT_BLOCK. --- src/Bindings/Plugin.h | 1 + src/Bindings/PluginLua.cpp | 20 ++++++++++++++++++++ src/Bindings/PluginLua.h | 1 + src/Bindings/PluginManager.cpp | 21 +++++++++++++++++++++ src/Bindings/PluginManager.h | 2 ++ src/Entities/ProjectileEntity.cpp | 5 +++++ 6 files changed, 50 insertions(+) diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h index 75b04d12f..df0bd4dcc 100644 --- a/src/Bindings/Plugin.h +++ b/src/Bindings/Plugin.h @@ -90,6 +90,7 @@ public: 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 OnProjectileHitBlock (cProjectileEntity & a_Projectile) = 0; virtual bool OnProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity) = 0; virtual bool OnSpawnedEntity (cWorld & a_World, cEntity & a_Entity) = 0; virtual bool OnSpawnedMonster (cWorld & a_World, cMonster & a_Monster) = 0; diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp index d4e4b3ee8..7e69e0f4b 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -1108,6 +1108,26 @@ bool cPluginLua::OnPreCrafting(const cPlayer * a_Player, const cCraftingGrid * a +bool cPluginLua::OnProjectileHitBlock(cProjectileEntity & a_Projectile) +{ + cCSLock Lock(m_CriticalSection); + bool res = false; + cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_PROJECTILE_HIT_BLOCK]; + for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) + { + m_LuaState.Call((int)(**itr), &a_Projectile, cLuaState::Return, res); + if (res) + { + return true; + } + } + return false; +} + + + + + bool cPluginLua::OnProjectileHitEntity(cProjectileEntity & a_Projectile, cEntity & a_HitEntity) { cCSLock Lock(m_CriticalSection); diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h index 1533b1a66..59542d23a 100644 --- a/src/Bindings/PluginLua.h +++ b/src/Bindings/PluginLua.h @@ -113,6 +113,7 @@ public: 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 OnProjectileHitBlock (cProjectileEntity & a_Projectile) override; virtual bool OnProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity) override; virtual bool OnSpawnedEntity (cWorld & a_World, cEntity & a_Entity) override; virtual bool OnSpawnedMonster (cWorld & a_World, cMonster & a_Monster) override; diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index aa2c09a3d..6a5356c0b 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -1154,6 +1154,27 @@ bool cPluginManager::CallHookPreCrafting(const cPlayer * a_Player, const cCrafti +bool cPluginManager::CallHookProjectileHitBlock(cProjectileEntity & a_Projectile) +{ + HookMap::iterator Plugins = m_Hooks.find(HOOK_PROJECTILE_HIT_BLOCK); + if (Plugins == m_Hooks.end()) + { + return false; + } + for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) + { + if ((*itr)->OnProjectileHitBlock(a_Projectile)) + { + return true; + } + } + return false; +} + + + + + bool cPluginManager::CallHookProjectileHitEntity(cProjectileEntity & a_Projectile, cEntity & a_HitEntity) { HookMap::iterator Plugins = m_Hooks.find(HOOK_PROJECTILE_HIT_ENTITY); diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index c5071ee83..512bc1351 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -105,6 +105,7 @@ public: // tolua_export HOOK_PLUGINS_LOADED, HOOK_POST_CRAFTING, HOOK_PRE_CRAFTING, + HOOK_PROJECTILE_HIT_BLOCK, HOOK_PROJECTILE_HIT_ENTITY, HOOK_SPAWNED_ENTITY, HOOK_SPAWNED_MONSTER, @@ -205,6 +206,7 @@ public: // tolua_export 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 CallHookProjectileHitBlock (cProjectileEntity & a_Projectile); bool CallHookProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity); bool CallHookSpawnedEntity (cWorld & a_World, cEntity & a_Entity); bool CallHookSpawnedMonster (cWorld & a_World, cMonster & a_Monster); diff --git a/src/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp index 07cb34f35..b724c9c55 100644 --- a/src/Entities/ProjectileEntity.cpp +++ b/src/Entities/ProjectileEntity.cpp @@ -67,6 +67,11 @@ protected: eBlockFace Face; if (bb.CalcLineIntersection(Line1, Line2, LineCoeff, Face)) { + if (cPluginManager::Get()->CallHookProjectileHitBlock(*m_Projectile)) + { + return true; + } + Vector3d Intersection = Line1 + m_Projectile->GetSpeed() * LineCoeff; m_Projectile->OnHitSolidBlock(Intersection, Face); return true; From 379d403443e5ecf3e66cf151391f5a8c4bd4d5c6 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sat, 29 Mar 2014 16:08:39 +0100 Subject: [PATCH 4/5] Documented both hooks. --- .../APIDump/Hooks/OnProjectileHitBlock.lua | 24 ++++++++++++++++++ .../APIDump/Hooks/OnProjectileHitEntity.lua | 25 +++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 MCServer/Plugins/APIDump/Hooks/OnProjectileHitBlock.lua create mode 100644 MCServer/Plugins/APIDump/Hooks/OnProjectileHitEntity.lua diff --git a/MCServer/Plugins/APIDump/Hooks/OnProjectileHitBlock.lua b/MCServer/Plugins/APIDump/Hooks/OnProjectileHitBlock.lua new file mode 100644 index 000000000..1588d420c --- /dev/null +++ b/MCServer/Plugins/APIDump/Hooks/OnProjectileHitBlock.lua @@ -0,0 +1,24 @@ +return +{ + HOOK_PROJECTILE_HIT_BLOCK = + { + CalledWhen = "A projectile hits a solid block.", + DefaultFnName = "OnProjectileHitBlock", -- also used as pagename + Desc = [[ + This hook is called when a {{cProjectileEntity|projectile}} hits a solid block.. + ]], + Params = + { + { Name = "ProjectileEntity", Type = "{{cProjectileEntity}}", Notes = "The projectile that hit an entity." }, + }, + Returns = [[ + If the function returns false or no value, the next plugin's callback is called. If the function + returns true, no other callback is called for this event and the projectile flies through block.. + ]], + }, -- HOOK_PROJECTILE_HIT_BLOCK +} + + + + + diff --git a/MCServer/Plugins/APIDump/Hooks/OnProjectileHitEntity.lua b/MCServer/Plugins/APIDump/Hooks/OnProjectileHitEntity.lua new file mode 100644 index 000000000..dd949fb46 --- /dev/null +++ b/MCServer/Plugins/APIDump/Hooks/OnProjectileHitEntity.lua @@ -0,0 +1,25 @@ +return +{ + HOOK_PROJECTILE_HIT_ENTITY = + { + CalledWhen = "A projectile hits another entity.", + DefaultFnName = "OnProjectileHitEntity", -- also used as pagename + Desc = [[ + This hook is called when a {{cProjectileEntity|projectile}} hits another entity. + ]], + Params = + { + { Name = "ProjectileEntity", Type = "{{cProjectileEntity}}", Notes = "The projectile that hit an entity." }, + { Name = "Entity", Type = "{{cEntity}}", Notes = "The entity wich was hit." }, + }, + Returns = [[ + If the function returns false or no value, the next plugin's callback is called. If the function + returns true, no other callback is called for this event and the projectile flies through the entity. + ]], + }, -- HOOK_PROJECTILE_HIT_ENTITY +} + + + + + From 98a12127ceaa0834bfea66fa6f9e381b1f8f4357 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sat, 29 Mar 2014 17:05:24 +0100 Subject: [PATCH 5/5] Fixed the OnProjectileHitBlock hook not stopping projectiles. --- src/Entities/ProjectileEntity.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp index b724c9c55..a9735a53c 100644 --- a/src/Entities/ProjectileEntity.cpp +++ b/src/Entities/ProjectileEntity.cpp @@ -69,7 +69,7 @@ protected: { if (cPluginManager::Get()->CallHookProjectileHitBlock(*m_Projectile)) { - return true; + return false; } Vector3d Intersection = Line1 + m_Projectile->GetSpeed() * LineCoeff;