diff --git a/zone/lua_parser.cpp b/zone/lua_parser.cpp index 3c1ab4904..84ee44319 100644 --- a/zone/lua_parser.cpp +++ b/zone/lua_parser.cpp @@ -1095,6 +1095,19 @@ bool LuaParser::HasFunction(std::string subname, std::string package_name) { return false; } +bool LuaParser::HasEncounterSub(const std::string& package_name, QuestEventID evt) +{ + auto it = lua_encounter_events_registered.find(package_name); + if (it != lua_encounter_events_registered.end()) { + for (auto riter = it->second.begin(); riter != it->second.end(); ++riter) { + if (riter->event_id == evt) { + return true; + } + } + } + return false; +} + void LuaParser::MapFunctions(lua_State *L) { try { diff --git a/zone/lua_parser.h b/zone/lua_parser.h index cf09d0162..cd3d06646 100644 --- a/zone/lua_parser.h +++ b/zone/lua_parser.h @@ -58,6 +58,7 @@ public: virtual bool SpellHasQuestSub(uint32 spell_id, QuestEventID evt); virtual bool ItemHasQuestSub(EQ::ItemInstance *itm, QuestEventID evt); virtual bool EncounterHasQuestSub(std::string encounter_name, QuestEventID evt); + virtual bool HasEncounterSub(const std::string& package_name, QuestEventID evt); virtual void LoadNPCScript(std::string filename, int npc_id); virtual void LoadGlobalNPCScript(std::string filename); diff --git a/zone/quest_interface.h b/zone/quest_interface.h index ed615876a..0bab655f2 100644 --- a/zone/quest_interface.h +++ b/zone/quest_interface.h @@ -55,6 +55,7 @@ public: virtual bool SpellHasQuestSub(uint32 spell_id, QuestEventID evt) { return false; } virtual bool ItemHasQuestSub(EQ::ItemInstance *itm, QuestEventID evt) { return false; } virtual bool EncounterHasQuestSub(std::string encounter_name, QuestEventID evt) { return false; } + virtual bool HasEncounterSub(const std::string& package_name, QuestEventID evt) { return false; } virtual void LoadNPCScript(std::string filename, int npc_id) { } virtual void LoadGlobalNPCScript(std::string filename) { } diff --git a/zone/quest_parser_collection.cpp b/zone/quest_parser_collection.cpp index 31f0faa08..a9f55df7b 100644 --- a/zone/quest_parser_collection.cpp +++ b/zone/quest_parser_collection.cpp @@ -97,8 +97,13 @@ void QuestParserCollection::RemoveEncounter(const std::string name) { } } -bool QuestParserCollection::HasQuestSub(uint32 npcid, QuestEventID evt) { - return HasQuestSubLocal(npcid, evt) || HasQuestSubGlobal(evt); +bool QuestParserCollection::HasQuestSub(uint32 npcid, QuestEventID evt, bool check_encounters) { + return HasQuestSubLocal(npcid, evt) || HasQuestSubGlobal(evt) || (check_encounters && NPCHasEncounterSub(npcid, evt)); +} + +bool QuestParserCollection::NPCHasEncounterSub(uint32 npc_id, QuestEventID evt) { + std::string package_name = "npc_" + std::to_string(npc_id); + return HasEncounterSub(evt, package_name); } bool QuestParserCollection::HasQuestSubLocal(uint32 npcid, QuestEventID evt) { @@ -151,8 +156,12 @@ bool QuestParserCollection::HasQuestSubGlobal(QuestEventID evt) { return false; } -bool QuestParserCollection::PlayerHasQuestSub(QuestEventID evt) { - return PlayerHasQuestSubLocal(evt) || PlayerHasQuestSubGlobal(evt); +bool QuestParserCollection::PlayerHasQuestSub(QuestEventID evt, bool check_encounters) { + return PlayerHasQuestSubLocal(evt) || PlayerHasQuestSubGlobal(evt) || (check_encounters && PlayerHasEncounterSub(evt)); +} + +bool QuestParserCollection::PlayerHasEncounterSub(QuestEventID evt) { + return HasEncounterSub(evt, "player"); } bool QuestParserCollection::PlayerHasQuestSubLocal(QuestEventID evt) { @@ -187,7 +196,16 @@ bool QuestParserCollection::PlayerHasQuestSubGlobal(QuestEventID evt) { return false; } -bool QuestParserCollection::SpellHasQuestSub(uint32 spell_id, QuestEventID evt) { +bool QuestParserCollection::SpellHasEncounterSub(uint32 spell_id, QuestEventID evt) { + std::string package_name = "spell_" + std::to_string(spell_id); + return HasEncounterSub(evt, package_name); +} + +bool QuestParserCollection::SpellHasQuestSub(uint32 spell_id, QuestEventID evt, bool check_encounters) { + if (check_encounters && SpellHasEncounterSub(spell_id, evt)) { + return true; + } + auto iter = _spell_quest_status.find(spell_id); if(iter != _spell_quest_status.end()) { //loaded or failed to load @@ -209,10 +227,22 @@ bool QuestParserCollection::SpellHasQuestSub(uint32 spell_id, QuestEventID evt) return false; } -bool QuestParserCollection::ItemHasQuestSub(EQ::ItemInstance *itm, QuestEventID evt) { +bool QuestParserCollection::ItemHasEncounterSub(EQ::ItemInstance* item, QuestEventID evt) { + if (item) { + std::string package_name = "item_" + std::to_string(item->GetID()); + return HasEncounterSub(evt, package_name); + } + return false; +} + +bool QuestParserCollection::ItemHasQuestSub(EQ::ItemInstance *itm, QuestEventID evt, bool check_encounters) { if (itm == nullptr) return false; + if (check_encounters && ItemHasEncounterSub(itm, evt)) { + return true; + } + std::string item_script; if(itm->GetItem()->ScriptFileID != 0) { item_script = "script_"; @@ -245,6 +275,18 @@ bool QuestParserCollection::ItemHasQuestSub(EQ::ItemInstance *itm, QuestEventID return false; } +bool QuestParserCollection::HasEncounterSub(QuestEventID evt, const std::string& package_name) { + for (auto it = _encounter_quest_status.begin(); it != _encounter_quest_status.end(); ++it) { + if (it->second != QuestFailedToLoad) { + auto qit = _interfaces.find(it->second); + if (qit != _interfaces.end() && qit->second->HasEncounterSub(package_name, evt)) { + return true; + } + } + } + return false; +} + int QuestParserCollection::EventNPC(QuestEventID evt, NPC *npc, Mob *init, std::string data, uint32 extra_data, std::vector *extra_pointers) { int rd = DispatchEventNPC(evt, npc, init, data, extra_data, extra_pointers); diff --git a/zone/quest_parser_collection.h b/zone/quest_parser_collection.h index 78b195d38..8e1fc0768 100644 --- a/zone/quest_parser_collection.h +++ b/zone/quest_parser_collection.h @@ -67,10 +67,10 @@ public: void ReloadQuests(bool reset_timers = true); void RemoveEncounter(const std::string name); - bool HasQuestSub(uint32 npcid, QuestEventID evt); - bool PlayerHasQuestSub(QuestEventID evt); - bool SpellHasQuestSub(uint32 spell_id, QuestEventID evt); - bool ItemHasQuestSub(EQ::ItemInstance *itm, QuestEventID evt); + bool HasQuestSub(uint32 npcid, QuestEventID evt, bool check_encounters = false); + bool PlayerHasQuestSub(QuestEventID evt, bool check_encounters = false); + bool SpellHasQuestSub(uint32 spell_id, QuestEventID evt, bool check_encounters = false); + bool ItemHasQuestSub(EQ::ItemInstance *itm, QuestEventID evt, bool check_encounters = false); int EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, std::vector *extra_pointers = nullptr); @@ -109,8 +109,13 @@ public: private: bool HasQuestSubLocal(uint32 npcid, QuestEventID evt); bool HasQuestSubGlobal(QuestEventID evt); + bool NPCHasEncounterSub(uint32 npc_id, QuestEventID evt); bool PlayerHasQuestSubLocal(QuestEventID evt); bool PlayerHasQuestSubGlobal(QuestEventID evt); + bool PlayerHasEncounterSub(QuestEventID evt); + bool SpellHasEncounterSub(uint32 spell_id, QuestEventID evt); + bool ItemHasEncounterSub(EQ::ItemInstance* item, QuestEventID evt); + bool HasEncounterSub(QuestEventID evt, const std::string& package_name); int EventNPCLocal(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, std::vector *extra_pointers); int EventNPCGlobal(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, std::vector *extra_pointers); diff --git a/zone/trading.cpp b/zone/trading.cpp index c051aa6c9..7b876da9e 100644 --- a/zone/trading.cpp +++ b/zone/trading.cpp @@ -875,7 +875,7 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st } bool quest_npc = false; - if(parse->HasQuestSub(tradingWith->GetNPCTypeID(), EVENT_TRADE)) { + if (parse->HasQuestSub(tradingWith->GetNPCTypeID(), EVENT_TRADE, true)) { // This is a quest NPC quest_npc = true; }