From dffee38dc622254a9847e1a09d79c572d1aaf388 Mon Sep 17 00:00:00 2001 From: SecretsOTheP Date: Mon, 21 Apr 2014 22:19:12 -0400 Subject: [PATCH] It's never ogre with these hatelist crashes.. --- changelog.txt | 3 +++ zone/entity.cpp | 33 +++++++++++++++++++++++++++++++++ zone/entity.h | 1 + zone/hate_list.cpp | 20 +++++++++++++------- zone/mob.cpp | 2 -- 5 files changed, 50 insertions(+), 9 deletions(-) diff --git a/changelog.txt b/changelog.txt index 08d664a70..3a6858ffb 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,8 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 04/21/2014 == +Secrets: Crash fix for more hatelist crashes. + == 04/20/2014 == Secrets: Changed the functionality of EQDEBUG cmake flag. It now suppresses logs, but shows crashes in any scenario when set to 1. It will also now show crashes even if the log system is disabled. KLS: Change to how quest signals work, signals with no delay will now be added to the signal queue. This addresses an odd timing issue where NPCs are in a state of life/death flux when a signal from event_death goes off. diff --git a/zone/entity.cpp b/zone/entity.cpp index ed5ee33f0..3f6130745 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -1283,6 +1283,33 @@ void EntityList::RemoveFromTargets(Mob *mob, bool RemoveFromXTargets) } } +void EntityList::RemoveFromTargets(uint16 MobID, bool RemoveFromXTargets) +{ + Mob* mob = entity_list.GetMob(MobID); + + if(!mob) + return; + + auto it = mob_list.begin(); + while (it != mob_list.end()) { + Mob *m = it->second; + ++it; + + if (!m) + continue; + + m->RemoveFromHateList(mob); + + if (RemoveFromXTargets) { + if (m->IsClient()) + m->CastToClient()->RemoveXTarget(mob, false); + // FadingMemories calls this function passing the client. + else if (mob->IsClient()) + mob->CastToClient()->RemoveXTarget(m, false); + } + } +} + void EntityList::RemoveFromXTargets(Mob *mob) { auto it = client_list.begin(); @@ -2080,6 +2107,9 @@ bool EntityList::RemoveMob(uint16 delete_id) if (delete_id == 0) return true; + //Moved this from ~Mob, because it could cause a crash in some cases where a hate list was still used and that mob was the only one on the hate list. + entity_list.RemoveFromTargets(delete_id, true); + auto it = mob_list.find(delete_id); if (it != mob_list.end()) { if (npc_list.count(delete_id)) @@ -2101,6 +2131,9 @@ bool EntityList::RemoveMob(Mob *delete_mob) if (delete_mob == 0) return true; + //Moved this from ~Mob, because it could cause a crash in some cases where a hate list was still used and that mob was the only one on the hate list. + entity_list.RemoveFromTargets(delete_mob, true); + auto it = mob_list.begin(); while (it != mob_list.end()) { if (it->second == delete_mob) { diff --git a/zone/entity.h b/zone/entity.h index ede4b3bea..9db343921 100644 --- a/zone/entity.h +++ b/zone/entity.h @@ -290,6 +290,7 @@ public: void ExpeditionWarning(uint32 minutes_left); void RemoveFromTargets(Mob* mob, bool RemoveFromXTargets = false); + void RemoveFromTargets(uint16 mob, bool RemoveFromXTargets = false); void RemoveFromXTargets(Mob* mob); void RemoveFromAutoXTargets(Mob* mob); void ReplaceWithTarget(Mob* pOldMob, Mob*pNewTarget); diff --git a/zone/hate_list.cpp b/zone/hate_list.cpp index 6980746df..abc33866e 100644 --- a/zone/hate_list.cpp +++ b/zone/hate_list.cpp @@ -60,14 +60,16 @@ void HateList::Wipe() while(iterator != list.end()) { Mob* m = (*iterator)->ent; - parse->EventNPC(EVENT_HATE_LIST, owner->CastToNPC(), m, "0", 0); - //iterator + if(m) + { + parse->EventNPC(EVENT_HATE_LIST, owner->CastToNPC(), m, "0", 0); + if(m->IsClient()) + m->CastToClient()->DecrementAggroCount(); + } delete (*iterator); iterator = list.erase(iterator); - if(m->IsClient()) - m->CastToClient()->DecrementAggroCount(); } } @@ -203,6 +205,9 @@ void HateList::Add(Mob *ent, int32 in_hate, int32 in_dam, bool bFrenzy, bool iAd bool HateList::RemoveEnt(Mob *ent) { + if (!ent) + return NULL; + bool found = false; auto iterator = list.begin(); @@ -211,14 +216,15 @@ bool HateList::RemoveEnt(Mob *ent) if((*iterator)->ent == ent) { parse->EventNPC(EVENT_HATE_LIST, owner->CastToNPC(), ent, "0", 0); - delete (*iterator); - iterator = list.erase(iterator); found = true; if(ent->IsClient()) ent->CastToClient()->DecrementAggroCount(); - } + delete (*iterator); + iterator = list.erase(iterator); + + } else ++iterator; } diff --git a/zone/mob.cpp b/zone/mob.cpp index 48452f26a..0fa0b1c07 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -401,8 +401,6 @@ Mob::~Mob() if(!corpse || (corpse && !corpse->IsPlayerCorpse())) entity_list.QueueClients(this, &app, true); - entity_list.RemoveFromTargets(this, true); - if(trade) { Mob *with = trade->With(); if(with && with->IsClient()) {