commit
ce93cfc34c
22
MCServer/Plugins/APIDump/Hooks/OnKilled.lua
Normal file
22
MCServer/Plugins/APIDump/Hooks/OnKilled.lua
Normal file
@ -0,0 +1,22 @@
|
||||
return
|
||||
{
|
||||
HOOK_KILLED =
|
||||
{
|
||||
CalledWhen = "A player or a mob died.",
|
||||
DefaultFnName = "OnKilled",
|
||||
Desc = [[
|
||||
This hook is called whenever player or a mob dies. It can be used to change the death message.
|
||||
]]
|
||||
Params =
|
||||
{
|
||||
{ Name = "Victim", Type = "{{cEntity}}", Notes = "The player or mob that died" },
|
||||
{ Name = "TDI", Type = "{{TakeDamageInfo}}", Notes = "Informations about the death" },
|
||||
{ Name = "DeathMessage", Type = "string", Notes = "The default death message. An empty string if the victim is not a player" },
|
||||
},
|
||||
Returns = [[
|
||||
The function may return two values. The first value is a boolean specifying whether other plugins should be called. If it is true, the other plugins won't get notified of the death. If it is false, the other plugins will get notified.</p>
|
||||
<p>The second value is a string containing the death message. If the victim is a player, this death message is broadcasted instead of the default death message. If it is empty, no death message is broadcasted. If it is nil, the message is left unchanged. If the victim is not a player, the death message is never broadcasted.</p>
|
||||
<p>In either case, the victim is dead.
|
||||
]],
|
||||
}, -- HOOK_KILLED
|
||||
}
|
@ -7,11 +7,7 @@ return
|
||||
Desc = [[
|
||||
This hook is called whenever a {{cPawn|pawn}}'s (a player's or a mob's) health reaches zero. This
|
||||
means that the pawn is about to be killed, unless a plugin "revives" them by setting their health
|
||||
back to a positive value.</p>
|
||||
<p>
|
||||
FIXME: There is no HOOK_KILLED notification hook yet; this is deliberate because HOOK_KILLED has
|
||||
been recently renamed to HOOK_KILLING, and plugins need to be updated. Once updated, the HOOK_KILLED
|
||||
notification will be implemented.
|
||||
back to a positive value.
|
||||
]],
|
||||
Params =
|
||||
{
|
||||
|
@ -64,6 +64,7 @@ public:
|
||||
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 OnKilled (cEntity & a_Victim, TakeDamageInfo & a_TDI, AString & a_DeathMessage) = 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 OnPlayerAnimation (cPlayer & a_Player, int a_Animation) = 0;
|
||||
|
@ -750,6 +750,30 @@ bool cPluginLua::OnHopperPushingItem(cWorld & a_World, cHopperEntity & a_Hopper,
|
||||
|
||||
|
||||
|
||||
bool cPluginLua::OnKilled(cEntity & a_Victim, TakeDamageInfo & a_TDI, AString & a_DeathMessage)
|
||||
{
|
||||
cCSLock Lock(m_CriticalSection);
|
||||
if (!m_LuaState.IsValid())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool res = false;
|
||||
cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_KILLED];
|
||||
for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
|
||||
{
|
||||
m_LuaState.Call((int)(**itr), &a_Victim, &a_TDI, a_DeathMessage, cLuaState::Return, res, a_DeathMessage);
|
||||
if (res)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cPluginLua::OnKilling(cEntity & a_Victim, cEntity * a_Killer, TakeDamageInfo & a_TDI)
|
||||
{
|
||||
cCSLock Lock(m_CriticalSection);
|
||||
|
@ -123,6 +123,7 @@ public:
|
||||
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 OnKilled (cEntity & a_Victim, TakeDamageInfo & a_TDI, AString & a_DeathMessage) 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 OnPlayerAnimation (cPlayer & a_Player, int a_Animation) override;
|
||||
|
@ -675,6 +675,25 @@ bool cPluginManager::CallHookHopperPushingItem(cWorld & a_World, cHopperEntity &
|
||||
|
||||
|
||||
|
||||
bool cPluginManager::CallHookKilled(cEntity & a_Victim, TakeDamageInfo & a_TDI, AString & a_DeathMessage)
|
||||
{
|
||||
FIND_HOOK(HOOK_KILLED);
|
||||
VERIFY_HOOK;
|
||||
|
||||
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
|
||||
{
|
||||
if ((*itr)->OnKilled(a_Victim, a_TDI, a_DeathMessage))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cPluginManager::CallHookKilling(cEntity & a_Victim, cEntity * a_Killer, TakeDamageInfo & a_TDI)
|
||||
{
|
||||
FIND_HOOK(HOOK_KILLING);
|
||||
|
@ -94,6 +94,7 @@ public:
|
||||
HOOK_HANDSHAKE,
|
||||
HOOK_HOPPER_PULLING_ITEM,
|
||||
HOOK_HOPPER_PUSHING_ITEM,
|
||||
HOOK_KILLED,
|
||||
HOOK_KILLING,
|
||||
HOOK_LOGIN,
|
||||
HOOK_PLAYER_BREAKING_BLOCK,
|
||||
@ -211,6 +212,7 @@ public:
|
||||
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 CallHookKilled (cEntity & a_Victim, TakeDamageInfo & a_TDI, AString & a_DeathMessage);
|
||||
bool CallHookKilling (cEntity & a_Victim, cEntity * a_Killer, TakeDamageInfo & a_TDI);
|
||||
bool CallHookLogin (cClientHandle & a_Client, int a_ProtocolVersion, const AString & a_Username);
|
||||
bool CallHookPlayerAnimation (cPlayer & a_Player, int a_Animation);
|
||||
|
@ -744,6 +744,13 @@ void cEntity::KilledBy(TakeDamageInfo & a_TDI)
|
||||
return;
|
||||
}
|
||||
|
||||
// If the victim is a player the hook is handled by the cPlayer class
|
||||
if (!IsPlayer())
|
||||
{
|
||||
AString emptystring = AString("");
|
||||
cRoot::Get()->GetPluginManager()->CallHookKilled(*this, a_TDI, emptystring);
|
||||
}
|
||||
|
||||
// Drop loot:
|
||||
cItems Drops;
|
||||
GetDrops(Drops, a_TDI.Attacker);
|
||||
|
@ -920,11 +920,11 @@ void cPlayer::KilledBy(TakeDamageInfo & a_TDI)
|
||||
{
|
||||
Pickups.Add(cItem(E_ITEM_RED_APPLE));
|
||||
}
|
||||
|
||||
m_Stats.AddValue(statItemsDropped, (StatValue)Pickups.Size());
|
||||
|
||||
m_World->SpawnItemPickups(Pickups, GetPosX(), GetPosY(), GetPosZ(), 10);
|
||||
SaveToDisk(); // Save it, yeah the world is a tough place !
|
||||
cPluginManager * PluginManager = cRoot::Get()->GetPluginManager();
|
||||
|
||||
if ((a_TDI.Attacker == nullptr) && m_World->ShouldBroadcastDeathMessages())
|
||||
{
|
||||
@ -950,7 +950,12 @@ void cPlayer::KilledBy(TakeDamageInfo & a_TDI)
|
||||
case dtExplosion: DamageText = "blew up"; break;
|
||||
default: DamageText = "died, somehow; we've no idea how though"; break;
|
||||
}
|
||||
GetWorld()->BroadcastChatDeath(Printf("%s %s", GetName().c_str(), DamageText.c_str()));
|
||||
AString DeathMessage = Printf("%s %s", GetName().c_str(), DamageText.c_str());
|
||||
PluginManager->CallHookKilled(*this, a_TDI, DeathMessage);
|
||||
if (DeathMessage != AString(""))
|
||||
{
|
||||
GetWorld()->BroadcastChatDeath(DeathMessage);
|
||||
}
|
||||
}
|
||||
else if (a_TDI.Attacker == nullptr) // && !m_World->ShouldBroadcastDeathMessages() by fallthrough
|
||||
{
|
||||
@ -959,15 +964,23 @@ void cPlayer::KilledBy(TakeDamageInfo & a_TDI)
|
||||
else if (a_TDI.Attacker->IsPlayer())
|
||||
{
|
||||
cPlayer * Killer = (cPlayer *)a_TDI.Attacker;
|
||||
|
||||
GetWorld()->BroadcastChatDeath(Printf("%s was killed by %s", GetName().c_str(), Killer->GetName().c_str()));
|
||||
AString DeathMessage = Printf("%s was killed by %s", GetName().c_str(), Killer->GetName().c_str());
|
||||
PluginManager->CallHookKilled(*this, a_TDI, DeathMessage);
|
||||
if (DeathMessage != AString(""))
|
||||
{
|
||||
GetWorld()->BroadcastChatDeath(DeathMessage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AString KillerClass = a_TDI.Attacker->GetClass();
|
||||
KillerClass.erase(KillerClass.begin()); // Erase the 'c' of the class (e.g. "cWitch" -> "Witch")
|
||||
|
||||
GetWorld()->BroadcastChatDeath(Printf("%s was killed by a %s", GetName().c_str(), KillerClass.c_str()));
|
||||
AString DeathMessage = Printf("%s was killed by a %s", GetName().c_str(), KillerClass.c_str());
|
||||
PluginManager->CallHookKilled(*this, a_TDI, DeathMessage);
|
||||
if (DeathMessage != AString(""))
|
||||
{
|
||||
GetWorld()->BroadcastChatDeath(DeathMessage);
|
||||
}
|
||||
}
|
||||
|
||||
m_Stats.AddValue(statDeaths);
|
||||
|
Loading…
Reference in New Issue
Block a user