From d79f601d5a62f2291615955fac196dbab5caa15a Mon Sep 17 00:00:00 2001
From: Nounours Heureux
- 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 =
{
diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h
index 1330bca0d..2fdf73a65 100644
--- a/src/Bindings/Plugin.h
+++ b/src/Bindings/Plugin.h
@@ -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;
diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp
index d3ffcd0f4..9be4e0eb4 100644
--- a/src/Bindings/PluginLua.cpp
+++ b/src/Bindings/PluginLua.cpp
@@ -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);
diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h
index a763cdfdf..7de70ef1f 100644
--- a/src/Bindings/PluginLua.h
+++ b/src/Bindings/PluginLua.h
@@ -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;
diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp
index 5b6bec728..712c385c7 100644
--- a/src/Bindings/PluginManager.cpp
+++ b/src/Bindings/PluginManager.cpp
@@ -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);
diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h
index 6bcef87bf..153f4996d 100644
--- a/src/Bindings/PluginManager.h
+++ b/src/Bindings/PluginManager.h
@@ -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);
diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp
index 108f79e82..500204a98 100644
--- a/src/Entities/Entity.cpp
+++ b/src/Entities/Entity.cpp
@@ -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);
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
index 0ca560d75..97e2eca3a 100644
--- a/src/Entities/Player.cpp
+++ b/src/Entities/Player.cpp
@@ -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);
From ee28d718392da59cfbd80a57271e62798ce01a12 Mon Sep 17 00:00:00 2001
From: Nounours Heureux
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.
+In either case, the victim is dead. + ]], + }, -- HOOK_KILLED +}