diff --git a/zone/attack.cpp b/zone/attack.cpp index 8db313cc8..7355cc707 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -2705,68 +2705,7 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy Corpse* corpse = nullptr; - // Parse quests even if we're killed by an NPC - if (oos) { - if (IsNPC()) { - auto emote_id = GetEmoteID(); - if (emote_id) { - DoNPCEmote(EQ::constants::EmoteEventTypes::OnDeath, emoteid, killer_mob); - } - } - - if (oos->IsNPC()) { - if (parse->HasQuestSub(oos->GetNPCTypeID(), EVENT_NPC_SLAY)) { - parse->EventNPC(EVENT_NPC_SLAY, oos->CastToNPC(), this, "", 0); - } - - auto emote_id = oos->GetEmoteID(); - if (emote_id) { - oos->CastToNPC()->DoNPCEmote(EQ::constants::EmoteEventTypes::KilledNPC, emote_id, this); - } - if (killer_mob) { - killer_mob->TrySpellOnKill(killed_level, spell); - } - } - } - - if (killer_mob && killer_mob->IsBot()) { - if (parse->BotHasQuestSub(EVENT_NPC_SLAY)) { - parse->EventBot(EVENT_NPC_SLAY, killer_mob->CastToBot(), this, "", 0); - } - - killer_mob->TrySpellOnKill(killed_level, spell); - } - - m_combat_record.Stop(); - if (parse->HasQuestSub(GetNPCTypeID(), EVENT_DEATH_COMPLETE)) { - const auto& export_string = fmt::format( - "{} {} {} {}", - killer_mob ? killer_mob->GetID() : 0, - damage, - spell, - static_cast(attack_skill) - ); - - std::vector args = { corpse }; - - parse->EventNPC(EVENT_DEATH_COMPLETE, this, oos, export_string, 0, &args); - } - - /* Zone controller process EVENT_DEATH_ZONE (Death events) */ - - if (parse->HasQuestSub(ZONE_CONTROLLER_NPC_ID, EVENT_DEATH_ZONE)) { - const auto& export_string = fmt::format( - "{} {} {} {}", - killer_mob ? killer_mob->GetID() : 0, - damage, - spell, - static_cast(attack_skill) - ); - - std::vector args = { corpse, this }; - - DispatchZoneControllerEvent(EVENT_DEATH_ZONE, oos, export_string, 0, &args); - } + const uint16 entity_id = GetID(); if (!HasOwner() && !IsMerc() && !GetSwarmInfo() && (!is_merchant || allow_merchant_corpse) && ((killer && (killer->IsClient() || (killer->HasOwner() && killer->GetUltimateOwner()->IsClient()) || @@ -2877,6 +2816,39 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy entity_list.RemoveFromXTargets(this); } + + // Parse quests even if we're killed by an NPC + if (oos) { + if (IsNPC()) { + auto emote_id = GetEmoteID(); + if (emote_id) { + DoNPCEmote(EQ::constants::EmoteEventTypes::OnDeath, emoteid, killer_mob); + } + } + + if (oos->IsNPC()) { + if (parse->HasQuestSub(oos->GetNPCTypeID(), EVENT_NPC_SLAY)) { + parse->EventNPC(EVENT_NPC_SLAY, oos->CastToNPC(), this, "", 0); + } + + auto emote_id = oos->GetEmoteID(); + if (emote_id) { + oos->CastToNPC()->DoNPCEmote(EQ::constants::EmoteEventTypes::KilledNPC, emote_id, this); + } + if (killer_mob) { + killer_mob->TrySpellOnKill(killed_level, spell); + } + } + } + + if (killer_mob && killer_mob->IsBot()) { + if (parse->BotHasQuestSub(EVENT_NPC_SLAY)) { + parse->EventBot(EVENT_NPC_SLAY, killer_mob->CastToBot(), this, "", 0); + } + + killer_mob->TrySpellOnKill(killed_level, spell); + } + WipeHateList(); p_depop = true; @@ -2885,6 +2857,39 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy entity_list.UpdateFindableNPCState(this, true); + m_combat_record.Stop(); + + if (parse->HasQuestSub(GetNPCTypeID(), EVENT_DEATH_COMPLETE)) { + const auto& export_string = fmt::format( + "{} {} {} {} {}", + killer_mob ? killer_mob->GetID() : 0, + damage, + spell, + static_cast(attack_skill), + entity_id + ); + + std::vector args = { corpse }; + + parse->EventNPC(EVENT_DEATH_COMPLETE, this, oos, export_string, 0, &args); + } + + // Zone controller process EVENT_DEATH_ZONE (Death events) + if (parse->HasQuestSub(ZONE_CONTROLLER_NPC_ID, EVENT_DEATH_ZONE)) { + const auto& export_string = fmt::format( + "{} {} {} {} {}", + killer_mob ? killer_mob->GetID() : 0, + damage, + spell, + static_cast(attack_skill), + entity_id + ); + + std::vector args = { corpse, this }; + + DispatchZoneControllerEvent(EVENT_DEATH_ZONE, oos, export_string, 0, &args); + } + return true; } diff --git a/zone/embparser.cpp b/zone/embparser.cpp index 454132dde..9c91ba974 100644 --- a/zone/embparser.cpp +++ b/zone/embparser.cpp @@ -1891,6 +1891,7 @@ 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]); + ExportVar(package_name.c_str(), "killed_entity_id", sep.arg[4]); if (extra_pointers && extra_pointers->size() >= 1) { Corpse *corpse = std::any_cast(extra_pointers->at(0)); @@ -1902,7 +1903,6 @@ void PerlembParser::ExportEventVariables( if (extra_pointers && extra_pointers->size() >= 2) { NPC *killed = std::any_cast(extra_pointers->at(1)); if (killed) { - ExportVar(package_name.c_str(), "killed_entity_id", killed->GetID()); ExportVar(package_name.c_str(), "killed_bot_id", killed->IsBot() ? killed->CastToBot()->GetBotID() : 0); ExportVar(package_name.c_str(), "killed_npc_id", killed->IsNPC() ? killed->GetNPCTypeID() : 0); ExportVar(package_name.c_str(), "killed_x", killed->GetX()); diff --git a/zone/lua_parser_events.cpp b/zone/lua_parser_events.cpp index 867912e2e..49f902f7b 100644 --- a/zone/lua_parser_events.cpp +++ b/zone/lua_parser_events.cpp @@ -289,12 +289,13 @@ void handle_npc_death( uint32 extra_data, std::vector *extra_pointers ) { + Seperator sep(data.c_str()); + Lua_Mob l_mob(init); luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob); l_mob_o.push(L); lua_setfield(L, -2, "other"); - Seperator sep(data.c_str()); lua_pushinteger(L, Strings::ToInt(sep.arg[0])); lua_setfield(L, -2, "killer_id"); @@ -317,6 +318,9 @@ void handle_npc_death( lua_pushinteger(L, Strings::ToInt(sep.arg[3])); lua_setfield(L, -2, "skill_id"); + lua_pushinteger(L, Strings::ToUnsignedInt(sep.arg[4])); + lua_setfield(L, -2, "killed_entity_id"); + if (extra_pointers && extra_pointers->size() >= 1) { Lua_Corpse l_corpse(std::any_cast(extra_pointers->at(0))); luabind::adl::object l_corpse_o = luabind::adl::object(L, l_corpse); @@ -600,14 +604,14 @@ void handle_player_death( l_mob_o.push(L); lua_setfield(L, -2, "other"); - lua_pushinteger(L, Strings::ToInt(sep.arg[1])); + lua_pushinteger(L, Strings::ToUnsignedInt(sep.arg[0])); lua_setfield(L, -2, "killer_id"); - lua_pushinteger(L, Strings::ToInt(sep.arg[2])); + lua_pushinteger(L, Strings::ToInt(sep.arg[1])); lua_setfield(L, -2, "damage"); - int spell_id = Strings::ToInt(sep.arg[3]); - if(IsValidSpell(spell_id)) { + const uint32 spell_id = Strings::ToUnsignedInt(sep.arg[2]); + if (IsValidSpell(spell_id)) { Lua_Spell l_spell(&spells[spell_id]); luabind::adl::object l_spell_o = luabind::adl::object(L, l_spell); l_spell_o.push(L); @@ -619,8 +623,11 @@ void handle_player_death( lua_setfield(L, -2, "spell"); } - lua_pushinteger(L, Strings::ToInt(sep.arg[4])); + lua_pushinteger(L, Strings::ToInt(sep.arg[3])); lua_setfield(L, -2, "skill"); + + lua_pushinteger(L, Strings::ToUnsignedInt(sep.arg[4])); + lua_setfield(L, -2, "killed_entity_id"); } void handle_player_timer( @@ -2136,6 +2143,9 @@ void handle_bot_death( l_mob_o.push(L); lua_setfield(L, -2, "other"); + lua_pushinteger(L, Strings::ToUnsignedInt(sep.arg[0])); + lua_setfield(L, -2, "killer_id"); + lua_pushinteger(L, Strings::ToInt(sep.arg[1])); lua_setfield(L, -2, "damage"); @@ -2154,6 +2164,9 @@ void handle_bot_death( lua_pushinteger(L, Strings::ToInt(sep.arg[3])); lua_setfield(L, -2, "skill"); + + lua_pushinteger(L, Strings::ToUnsignedInt(sep.arg[4])); + lua_setfield(L, -2, "killed_entity_id"); } void handle_bot_popup_response(