diff --git a/zone/entity.cpp b/zone/entity.cpp index f79409249..4bf59ddf0 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -602,6 +602,8 @@ void EntityList::EncounterProcess() auto it = encounter_list.begin(); while (it != encounter_list.end()) { if (!it->second->Process()) { + // if Process is returning false here, we probably just got called from ReloadQuests .. oh well + parse->RemoveEncounter(it->second->GetName()); safe_delete(it->second); free_ids.push(it->first); it = encounter_list.erase(it); @@ -2565,6 +2567,7 @@ void EntityList::RemoveAllEncounters() { auto it = encounter_list.begin(); while (it != encounter_list.end()) { + parse->RemoveEncounter(it->second->GetName()); safe_delete(it->second); free_ids.push(it->first); it = encounter_list.erase(it); diff --git a/zone/lua_parser.cpp b/zone/lua_parser.cpp index 494e3e0e2..59b10d4bf 100644 --- a/zone/lua_parser.cpp +++ b/zone/lua_parser.cpp @@ -988,6 +988,16 @@ void LuaParser::ReloadQuests() { } } +/* + * This function is intended only to clean up lua_encounters when the Encounter object is + * about to be destroyed. It won't clean up memory else where, since the caller of this + * function is responsible for that + */ +void LuaParser::RemoveEncounter(const std::string &name) +{ + lua_encounters.erase(name); +} + void LuaParser::LoadScript(std::string filename, std::string package_name) { auto iter = loaded_.find(package_name); if(iter != loaded_.end()) { diff --git a/zone/lua_parser.h b/zone/lua_parser.h index 8265a191f..d058daf13 100644 --- a/zone/lua_parser.h +++ b/zone/lua_parser.h @@ -71,6 +71,7 @@ public: virtual std::string GetVar(std::string name); virtual void Init(); virtual void ReloadQuests(); + virtual void RemoveEncounter(const std::string &name); virtual uint32 GetIdentifier() { return 0xb0712acc; } virtual int DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, diff --git a/zone/quest_interface.h b/zone/quest_interface.h index a2a6c73c8..d0f121cb6 100644 --- a/zone/quest_interface.h +++ b/zone/quest_interface.h @@ -78,6 +78,7 @@ public: virtual void Init() { } virtual void ReloadQuests() { } virtual uint32 GetIdentifier() = 0; + virtual void RemoveEncounter(const std::string &name) { } //TODO: Set maximum quest errors instead of hard coding it virtual void GetErrors(std::list &err) { diff --git a/zone/quest_parser_collection.cpp b/zone/quest_parser_collection.cpp index a4d9a5e21..625425839 100644 --- a/zone/quest_parser_collection.cpp +++ b/zone/quest_parser_collection.cpp @@ -89,6 +89,14 @@ void QuestParserCollection::ReloadQuests(bool reset_timers) { } } +void QuestParserCollection::RemoveEncounter(const std::string name) { + auto iter = _load_precedence.begin(); + while(iter != _load_precedence.end()) { + (*iter)->RemoveEncounter(name); + ++iter; + } +} + bool QuestParserCollection::HasQuestSub(uint32 npcid, QuestEventID evt) { return HasQuestSubLocal(npcid, evt) || HasQuestSubGlobal(evt); } diff --git a/zone/quest_parser_collection.h b/zone/quest_parser_collection.h index a5dc07a95..082b5b6f4 100644 --- a/zone/quest_parser_collection.h +++ b/zone/quest_parser_collection.h @@ -65,6 +65,7 @@ public: void AddVar(std::string name, std::string val); void Init(); void ReloadQuests(bool reset_timers = true); + void RemoveEncounter(const std::string name); bool HasQuestSub(uint32 npcid, QuestEventID evt); bool PlayerHasQuestSub(QuestEventID evt);