Browse Source

Able to repop in Antonica and not have issues deconstructing spells from spawns

Emagi 1 month ago
parent
commit
efca012970

+ 11 - 3
EQ2/source/WorldServer/SpellProcess.cpp

@@ -410,8 +410,10 @@ bool SpellProcess::DeleteCasterSpell(Spawn* caster, Spell* spell, string reason)
 	return ret;
 }
 
-bool SpellProcess::DeleteCasterSpell(LuaSpell* spell, string reason, bool removing_all_spells, Spawn* remove_target, bool zone_shutting_down){
-    std::shared_lock lock(MSpellProcess);	
+bool SpellProcess::DeleteCasterSpell(LuaSpell* spell, string reason, bool removing_all_spells, Spawn* remove_target, bool zone_shutting_down, bool shared_lock_spell){
+	if(shared_lock_spell) {
+		MSpellProcess.lock_shared();
+	}
 
 	bool ret = false;
 	Spawn* target = 0;
@@ -435,6 +437,9 @@ bool SpellProcess::DeleteCasterSpell(LuaSpell* spell, string reason, bool removi
 				}
 			}
 			spell->MSpellTargets.releasewritelock(__FUNCTION__, __LINE__);
+			if(shared_lock_spell) {
+				MSpellProcess.unlock_shared();
+			}
 			return target_valid;
 		}
 		spell->MSpellTargets.releasewritelock(__FUNCTION__, __LINE__);
@@ -534,6 +539,9 @@ bool SpellProcess::DeleteCasterSpell(LuaSpell* spell, string reason, bool removi
 			lua_interface->RemoveSpell(spell, true, SpellScriptTimersHasSpell(spell), reason, removing_all_spells);
 	}
 	
+	if(shared_lock_spell) {
+		MSpellProcess.unlock_shared();
+	}
 	return ret;
 }
 
@@ -2012,7 +2020,7 @@ void SpellProcess::RemoveSpellTimersFromSpawn(Spawn* spawn, bool remove_all, boo
 			if (!spell)
 				continue;
 			if(spell->caster == spawn && call_expire_function){
-				DeleteCasterSpell(spell, "expired", remove_all);
+				DeleteCasterSpell(spell, "expired", remove_all, nullptr, false, lock_spell_process);
 				continue;
 			}
 			if (spell->spell->GetSpellData()->persist_through_death)

+ 2 - 2
EQ2/source/WorldServer/SpellProcess.h

@@ -268,7 +268,7 @@ public:
 
 	/// <summary>Remove the given spell from the ZpellProcess</summary>
 	/// <param name='spell'>LuaSpell to remove</param>
-	bool DeleteCasterSpell(LuaSpell* spell, string reason="", bool removing_all_spells = false, Spawn* remove_target = nullptr, bool zone_shutting_down = false);
+	bool DeleteCasterSpell(LuaSpell* spell, string reason="", bool removing_all_spells = false, Spawn* remove_target = nullptr, bool zone_shutting_down = false, bool shared_lock_spell = true);
 
 	/// <summary>Interrupt the spell</summary>
 	/// <param name='interrupt'>InterruptStruct that contains all the info</param>
@@ -399,8 +399,8 @@ public:
 	static void AddSelfAndPetToCharTargets(LuaSpell* spell, Spawn* caster, bool onlyPet=false);
 	void DeleteActiveSpell(LuaSpell* spell);
 	static bool AddLuaSpellTarget(LuaSpell* lua_spell, int32 id, bool lock_spell_targets = true);
-private:
 	mutable std::shared_mutex MSpellProcess;
+private:
 	MutexMap<Entity*,Spell*> spell_que;
 	MutexList<LuaSpell*> active_spells;
 	MutexList<CastTimer*> cast_timers;

+ 5 - 2
EQ2/source/WorldServer/zoneserver.cpp

@@ -531,7 +531,7 @@ void ZoneServer::DeleteData(bool boot_clients){
 					client->Disconnect();
 			}
 			else{
-				RemoveSpawnSupportFunctions(spawn, true);
+				RemoveSpawnSupportFunctions(spawn, boot_clients);
 				RemoveSpawnFromGrid(spawn, spawn->GetLocation());
 				AddPendingDelete(spawn);
 			}
@@ -841,8 +841,11 @@ void ZoneServer::ProcessDepop(bool respawns_allowed, bool repop) {
 		}
 		MSpawnList.releasewritelock(__FUNCTION__, __LINE__);
 	}
-	else
+	else {
+		spellProcess->MSpellProcess.lock();
 		DeleteData(false);
+		spellProcess->MSpellProcess.unlock();
+	}
 
 	if(repop)
 	{