[Quest API] Let HasQuestSub check encounters (#2435)

This fixes an edge case where trading would not detect the npc had a
quest handler if it was registered inside a Lua encounter.
This commit is contained in:
hg 2022-09-20 13:21:48 -04:00 committed by GitHub
parent b2a73dc572
commit dbf8440a32
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 73 additions and 11 deletions

View File

@ -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 {

View File

@ -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);

View File

@ -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) { }

View File

@ -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<std::any> *extra_pointers) {
int rd = DispatchEventNPC(evt, npc, init, data, extra_data, extra_pointers);

View File

@ -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<std::any> *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<std::any> *extra_pointers);
int EventNPCGlobal(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, std::vector<std::any> *extra_pointers);

View File

@ -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;
}