Merge pull request #842 from mc-server/ProjectileHooks
Projectile hooks
This commit is contained in:
commit
37812813d3
24
MCServer/Plugins/APIDump/Hooks/OnProjectileHitBlock.lua
Normal file
24
MCServer/Plugins/APIDump/Hooks/OnProjectileHitBlock.lua
Normal file
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
25
MCServer/Plugins/APIDump/Hooks/OnProjectileHitEntity.lua
Normal file
25
MCServer/Plugins/APIDump/Hooks/OnProjectileHitEntity.lua
Normal file
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
|
@ -90,6 +90,8 @@ 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;
|
||||
virtual bool OnSpawningEntity (cWorld & a_World, cEntity & a_Entity) = 0;
|
||||
|
@ -1108,6 +1108,46 @@ 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);
|
||||
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);
|
||||
|
@ -113,6 +113,8 @@ 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;
|
||||
virtual bool OnSpawningEntity (cWorld & a_World, cEntity & a_Entity) override;
|
||||
|
@ -1154,6 +1154,48 @@ 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);
|
||||
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);
|
||||
|
@ -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,8 @@ 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,
|
||||
HOOK_SPAWNING_ENTITY,
|
||||
@ -201,6 +206,8 @@ 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);
|
||||
bool CallHookSpawningEntity (cWorld & a_World, cEntity & a_Entity);
|
||||
|
@ -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"
|
||||
@ -66,6 +67,11 @@ protected:
|
||||
eBlockFace Face;
|
||||
if (bb.CalcLineIntersection(Line1, Line2, LineCoeff, Face))
|
||||
{
|
||||
if (cPluginManager::Get()->CallHookProjectileHitBlock(*m_Projectile))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Vector3d Intersection = Line1 + m_Projectile->GetSpeed() * LineCoeff;
|
||||
m_Projectile->OnHitSolidBlock(Intersection, Face);
|
||||
return true;
|
||||
@ -147,7 +153,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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user