1
0

Have zone pointer tracked in the luaspell so we can assure we delete the spell properly when zone shuts down or spawn is gone

This commit is contained in:
Emagi 2024-12-01 18:24:56 -05:00
parent 9e986f3ace
commit 716caffb14
4 changed files with 19 additions and 2 deletions

View File

@ -1615,6 +1615,7 @@ void LuaInterface::DeletePendingSpells(bool all) {
if(!all) {
// rely on targets the spell->caster could be corrupt
bool spellDeleted = false;
if(spell->targets.size() > 0) {
spell->MSpellTargets.readlock(__FUNCTION__, __LINE__);
for (int8 i = 0; i < spell->targets.size(); i++) {
@ -1625,10 +1626,16 @@ void LuaInterface::DeletePendingSpells(bool all) {
if(!targetZone)
continue;
spellDeleted = true;
targetZone->GetSpellProcess()->DeleteActiveSpell(spell, true);
}
spell->MSpellTargets.releasereadlock(__FUNCTION__, __LINE__);
}
if(!spellDeleted && spell->zone != nullptr) {
spell->zone->GetSpellProcess()->DeleteActiveSpell(spell, true);
}
}
spells_pending_delete.erase(spell);
@ -2056,6 +2063,7 @@ LuaSpell* LuaInterface::LoadSpellScript(const char* name) {
spell->has_proc = false;
spell->initial_caster_char_id = 0;
spell->initial_target_char_id = 0;
spell->zone = nullptr;
MSpells.lock();
current_spells[spell->state] = spell;
@ -2354,6 +2362,7 @@ LuaSpell* LuaInterface::CreateSpellScript(const char* name, lua_State* existStat
new_spell->has_proc = false;
new_spell->initial_caster_char_id = 0;
new_spell->initial_target_char_id = 0;
new_spell->zone = nullptr;
current_spells[new_spell->state] = new_spell;
return new_spell;

View File

@ -103,7 +103,7 @@ struct LuaSpell{
int32 effect_bitmask;
bool restored; // restored spell cross zone
std::atomic<bool> has_proc;
ZoneServer* zone;
};
class LUAUserData{

View File

@ -649,6 +649,7 @@ bool SpellProcess::CastInstant(Spell* spell, Entity* caster, Entity* target, boo
}
lua_spell->caster = caster;
lua_spell->zone = caster->GetZone();
lua_spell->initial_caster_char_id = (caster && caster->IsPlayer()) ? ((Player*)caster)->GetCharacterID() : 0;
lua_spell->spell = spell;
lua_spell->initial_target = target->GetID();
@ -1068,6 +1069,7 @@ void SpellProcess::ProcessSpell(ZoneServer* zone, Spell* spell, Entity* caster,
int8 spell_type = spell->GetSpellData()->spell_type;
lua_spell->caster = caster;
lua_spell->zone = caster->GetZone();
lua_spell->initial_caster_char_id = (caster && caster->IsPlayer()) ? ((Player*)caster)->GetCharacterID() : 0;
lua_spell->spell = spell;
@ -1630,6 +1632,7 @@ void SpellProcess::ProcessSpell(ZoneServer* zone, Spell* spell, Entity* caster,
cast_timer->target_id = target ? target->GetID() : 0;
cast_timer->spell = lua_spell;
cast_timer->spell->caster = caster;
cast_timer->spell->zone = caster->GetZone();
cast_timer->delete_timer = false;
cast_timer->timer = new Timer(spell->GetSpellData()->cast_time * 10);
cast_timer->zone = zone;

View File

@ -8175,6 +8175,8 @@ void WorldDatabase::LoadCharacterSpellEffects(int32 char_id, Client* client, int
if(!isExistingLuaSpell)
lua_spell->caster = player; // TODO: get actual player
lua_spell->zone = player->GetZone();
player->MSpellEffects.releasewritelock();
if(!isMaintained)
@ -8286,6 +8288,9 @@ void WorldDatabase::LoadCharacterSpellEffects(int32 char_id, Client* client, int
info->maintained_effects[effect_slot].spell = lua_spell;
if(!isExistingLuaSpell)
lua_spell->caster = player;
lua_spell->zone = player->GetZone();
player->MMaintainedSpells.releasewritelock();
LogWrite(LUA__WARNING, 0, "LUA", "WorldDatabase::LoadCharacterSpellEffects: %s process spell caster %s (%u), caster char id: %u, target id %u (%s).", lua_spell->spell->GetName(), lua_spell->caster ? lua_spell->caster->GetName() : "",