mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-11 16:51:29 +00:00
[Quest API] Export corpse in EVENT_DEATH_COMPLETE (#2519)
It wasn't possible to easily obtain the corpse from post-death events because the killed entity id is assigned to the corpse and reset to 0 on the entity before the events are dispatched. This exposes the killed entity's corpse to EVENT_DEATH_COMPLETE and EVENT_DEATH_ZONE. Lua exports a Corpse object and perl exports a corpse entity id. The purpose of this is to make it easier to add items dynamically on death. Ideally this would be done in EVENT_DEATH before the corpse is made, but there's currently some combat system bugs that make that event unusable since it can be dispatched multiple times. A follow up will provide an api to reset corpse decay times since adding items after corpse creation will require quests to manually reset the decay timer in case the corpse had zero items.
This commit is contained in:
parent
13b2af1a91
commit
69e90c1739
@ -1903,6 +1903,7 @@ bool Client::Death(Mob* killerMob, int64 damage, uint16 spell, EQ::skills::Skill
|
||||
}
|
||||
|
||||
bool LeftCorpse = false;
|
||||
Corpse* new_corpse = nullptr;
|
||||
|
||||
// now we apply the exp loss, unmem their spells, and make a corpse
|
||||
// unless they're a GM (or less than lvl 10
|
||||
@ -1938,7 +1939,7 @@ bool Client::Death(Mob* killerMob, int64 damage, uint16 spell, EQ::skills::Skill
|
||||
if ((RuleB(Character, LeaveCorpses) && GetLevel() >= RuleI(Character, DeathItemLossLevel)) || RuleB(Character, LeaveNakedCorpses))
|
||||
{
|
||||
// creating the corpse takes the cash/items off the player too
|
||||
auto new_corpse = new Corpse(this, exploss);
|
||||
new_corpse = new Corpse(this, exploss);
|
||||
|
||||
std::string tmp;
|
||||
database.GetVariable("ServerType", tmp);
|
||||
@ -2038,7 +2039,8 @@ bool Client::Death(Mob* killerMob, int64 damage, uint16 spell, EQ::skills::Skill
|
||||
QServ->PlayerLogEvent(Player_Log_Deaths, CharacterID(), event_desc);
|
||||
}
|
||||
|
||||
parse->EventPlayer(EVENT_DEATH_COMPLETE, this, export_string, 0);
|
||||
std::vector<std::any> args = { new_corpse };
|
||||
parse->EventPlayer(EVENT_DEATH_COMPLETE, this, export_string, 0, &args);
|
||||
return true;
|
||||
}
|
||||
//SYNC WITH: tune.cpp, mob.h TuneNPCAttack
|
||||
@ -2604,6 +2606,8 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy
|
||||
bool allow_merchant_corpse = RuleB(Merchant, AllowCorpse);
|
||||
bool is_merchant = (class_ == MERCHANT || class_ == ADVENTURE_MERCHANT || MerchantType != 0);
|
||||
|
||||
Corpse* corpse = nullptr;
|
||||
|
||||
if (!HasOwner() && !IsMerc() && !GetSwarmInfo() && (!is_merchant || allow_merchant_corpse) &&
|
||||
((killer && (killer->IsClient() || (killer->HasOwner() && killer->GetUltimateOwner()->IsClient()) ||
|
||||
(killer->IsNPC() && killer->CastToNPC()->GetSwarmInfo() && killer->CastToNPC()->GetSwarmInfo()->GetOwner() && killer->CastToNPC()->GetSwarmInfo()->GetOwner()->IsClient())))
|
||||
@ -2620,7 +2624,7 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy
|
||||
entity_list.RemoveFromAutoXTargets(this);
|
||||
|
||||
uint32 emoteid = GetEmoteID();
|
||||
auto corpse = new Corpse(this, &itemlist, GetNPCTypeID(), &NPCTypedata,
|
||||
corpse = new Corpse(this, &itemlist, GetNPCTypeID(), &NPCTypedata,
|
||||
level > 54 ? RuleI(NPC, MajorNPCCorpseDecayTimeMS)
|
||||
: RuleI(NPC, MinorNPCCorpseDecayTimeMS));
|
||||
entity_list.LimitRemoveNPC(this);
|
||||
@ -2737,11 +2741,12 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy
|
||||
|
||||
entity_list.UpdateFindableNPCState(this, true);
|
||||
|
||||
parse->EventNPC(EVENT_DEATH_COMPLETE, this, oos, export_string, 0);
|
||||
std::vector<std::any> args = { corpse };
|
||||
parse->EventNPC(EVENT_DEATH_COMPLETE, this, oos, export_string, 0, &args);
|
||||
combat_record.Stop();
|
||||
|
||||
/* Zone controller process EVENT_DEATH_ZONE (Death events) */
|
||||
std::vector<std::any> args = { this };
|
||||
args.push_back(this);
|
||||
DispatchZoneControllerEvent(EVENT_DEATH_ZONE, oos, export_string, 0, &args);
|
||||
|
||||
return true;
|
||||
|
||||
@ -1611,9 +1611,17 @@ void PerlembParser::ExportEventVariables(
|
||||
ExportVar(package_name.c_str(), "killer_damage", sep.arg[1]);
|
||||
ExportVar(package_name.c_str(), "killer_spell", sep.arg[2]);
|
||||
ExportVar(package_name.c_str(), "killer_skill", sep.arg[3]);
|
||||
if (extra_pointers && !extra_pointers->empty())
|
||||
if (extra_pointers && extra_pointers->size() >= 1)
|
||||
{
|
||||
NPC* killed = std::any_cast<NPC*>(extra_pointers->at(0));
|
||||
Corpse* corpse = std::any_cast<Corpse*>(extra_pointers->at(0));
|
||||
if (corpse)
|
||||
{
|
||||
ExportVar(package_name.c_str(), "killed_corpse_id", corpse->GetID());
|
||||
}
|
||||
}
|
||||
if (extra_pointers && extra_pointers->size() >= 2)
|
||||
{
|
||||
NPC* killed = std::any_cast<NPC*>(extra_pointers->at(1));
|
||||
if (killed)
|
||||
{
|
||||
ExportVar(package_name.c_str(), "killed_npc_id", killed->GetNPCTypeID());
|
||||
|
||||
@ -210,9 +210,17 @@ void handle_npc_death(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init,
|
||||
lua_pushinteger(L, std::stoi(sep.arg[3]));
|
||||
lua_setfield(L, -2, "skill_id");
|
||||
|
||||
if (extra_pointers && !extra_pointers->empty())
|
||||
if (extra_pointers && extra_pointers->size() >= 1)
|
||||
{
|
||||
Lua_NPC l_npc(std::any_cast<NPC*>(extra_pointers->at(0)));
|
||||
Lua_Corpse l_corpse(std::any_cast<Corpse*>(extra_pointers->at(0)));
|
||||
luabind::adl::object l_corpse_o = luabind::adl::object(L, l_corpse);
|
||||
l_corpse_o.push(L);
|
||||
lua_setfield(L, -2, "corpse");
|
||||
}
|
||||
|
||||
if (extra_pointers && extra_pointers->size() >= 2)
|
||||
{
|
||||
Lua_NPC l_npc(std::any_cast<NPC*>(extra_pointers->at(1)));
|
||||
luabind::adl::object l_npc_o = luabind::adl::object(L, l_npc);
|
||||
l_npc_o.push(L);
|
||||
lua_setfield(L, -2, "killed");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user