From 9b60035656c7d82720fccf1c590139c700a585f3 Mon Sep 17 00:00:00 2001 From: Emagi Date: Sat, 11 Jan 2025 09:22:25 -0500 Subject: [PATCH] LUA function Resurrect updated with 8th and 9th argument for revive_sickness_spell_id and revive_sickness_spell_tier respectively. Fixed avoiding crash with bad spawn ptr if resurrect caster left zone. --- source/WorldServer/LuaFunctions.cpp | 15 +++++++++++++-- source/WorldServer/client.cpp | 10 ++++++++-- source/WorldServer/client.h | 6 +++++- source/WorldServer/zoneserver.cpp | 17 +++++++++++++++-- 4 files changed, 41 insertions(+), 7 deletions(-) diff --git a/source/WorldServer/LuaFunctions.cpp b/source/WorldServer/LuaFunctions.cpp index 9b6e2d5..ec5e931 100644 --- a/source/WorldServer/LuaFunctions.cpp +++ b/source/WorldServer/LuaFunctions.cpp @@ -9134,6 +9134,8 @@ int EQ2Emu_lua_Resurrect(lua_State* state) { string heal_name = lua_interface->GetStringValue(state, 5); int8 crit_mod = lua_interface->GetInt32Value(state, 6); bool no_calcs = lua_interface->GetInt32Value(state, 7) == 1; + int32 revive_spell_id = lua_interface->GetInt32Value(state, 8); + int8 revive_spell_tier = lua_interface->GetInt32Value(state, 9); LuaSpell* spell = lua_interface->GetCurrentSpell(state); lua_interface->ResetFunctionStack(state); @@ -9173,7 +9175,7 @@ int EQ2Emu_lua_Resurrect(lua_State* state) { client->GetResurrectMutex()->writelock(__FUNCTION__, __LINE__); rez->active = true; - rez->caster = caster; + rez->caster = caster->GetID(); rez->expire_timer = new Timer; int32 duration = spell->spell->GetSpellDuration(); rez->expire_timer->Start(duration * 100); @@ -9185,6 +9187,10 @@ int EQ2Emu_lua_Resurrect(lua_State* state) { rez->heal_name = heal_name; else rez->heal_name = rez->spell_name; + rez->orig_spell_id = spell->spell->GetSpellID(); + rez->orig_spell_tier = spell->spell->GetSpellTier(); + rez->revive_sickness_spell_id = revive_spell_id; + rez->revive_sickness_spell_tier = revive_spell_tier; rez->no_calcs = no_calcs; rez->crit_mod = crit_mod; rez->spell_visual = spell->spell->GetSpellData()->spell_visual; @@ -9214,7 +9220,7 @@ int EQ2Emu_lua_Resurrect(lua_State* state) { client->GetResurrectMutex()->writelock(__FUNCTION__, __LINE__); rez->active = true; - rez->caster = caster; + rez->caster = caster->GetID(); rez->expire_timer = new Timer; int32 duration = spell->spell->GetSpellDuration(); rez->expire_timer->Start(duration * 100); @@ -9226,6 +9232,11 @@ int EQ2Emu_lua_Resurrect(lua_State* state) { rez->heal_name = heal_name; else rez->heal_name = rez->spell_name; + + rez->orig_spell_id = spell->spell->GetSpellID(); + rez->orig_spell_tier = spell->spell->GetSpellTier(); + rez->revive_sickness_spell_id = revive_spell_id; + rez->revive_sickness_spell_tier = revive_spell_tier; rez->no_calcs = no_calcs; rez->crit_mod = crit_mod; rez->spell_visual = spell->spell->GetSpellData()->spell_visual; diff --git a/source/WorldServer/client.cpp b/source/WorldServer/client.cpp index d30de7b..4aa5c92 100644 --- a/source/WorldServer/client.cpp +++ b/source/WorldServer/client.cpp @@ -11493,7 +11493,10 @@ Mutex* Client::GetResurrectMutex() { } void Client::SendResurrectionWindow() { - Spawn* caster = current_rez.caster; + if(!GetCurrentZone()) + return; + + Spawn* caster = GetCurrentZone()->GetSpawnByID(current_rez.caster); if (!caster || !player) return; @@ -11520,7 +11523,10 @@ void Client::SendResurrectionWindow() { } void Client::AcceptResurrection() { - Spawn* caster = current_rez.caster; + if(!GetCurrentZone()) + return; + + Spawn* caster = GetCurrentZone()->GetSpawnByID(current_rez.caster); if (!player || !caster) return; diff --git a/source/WorldServer/client.h b/source/WorldServer/client.h index 24e79c2..c130abe 100644 --- a/source/WorldServer/client.h +++ b/source/WorldServer/client.h @@ -126,7 +126,7 @@ struct PendingGuildInvite { }; struct PendingResurrection { - Spawn* caster; + int32 caster; // don't use the spawn pointer as the player can leave and cause a zone crash Timer* expire_timer; string spell_name; string heal_name; @@ -140,6 +140,10 @@ struct PendingResurrection { bool crit; bool should_delete; int32 spell_visual; + int32 orig_spell_id; + int8 orig_spell_tier; + int32 revive_sickness_spell_id; + int8 revive_sickness_spell_tier; }; #define PAPERDOLL_TYPE_FULL 0 diff --git a/source/WorldServer/zoneserver.cpp b/source/WorldServer/zoneserver.cpp index 28d3722..258c36c 100644 --- a/source/WorldServer/zoneserver.cpp +++ b/source/WorldServer/zoneserver.cpp @@ -7746,13 +7746,17 @@ void ZoneServer::ResurrectSpawn(Spawn* spawn, Client* client) { if(!client || !spawn) return; PendingResurrection* rez = client->GetCurrentRez(); - if(!rez || !rez->caster) + if(!rez) return; PacketStruct* packet = 0; float power_perc = rez->mp_perc; float health_perc = rez->hp_perc; - Spawn* caster_spawn = rez->caster; + Spawn* caster_spawn = GetSpawnByID(rez->caster); + + if(!caster_spawn) + return; + sint32 heal_amt = 0; sint32 power_amt = 0; bool no_calcs = rez->no_calcs; @@ -7844,6 +7848,15 @@ void ZoneServer::ResurrectSpawn(Spawn* spawn, Client* client) { spawn->SendSpawnChanges(true); spawn->SetTempActionState(-1); spawn->appearance.attackable = 1; + + if(rez->revive_sickness_spell_id) { + Spell* spell = master_spell_list.GetSpell(rez->revive_sickness_spell_id, rez->revive_sickness_spell_tier); + + if (spell) + { + GetSpellProcess()->CastInstant(spell, caster ? caster : (Entity*)client->GetPlayer(), (Entity*)client->GetPlayer()); + } + } } void ZoneServer::SendDispellPacket(Entity* caster, Spawn* target, string dispell_name, string spell_name, int8 dispell_type){