diff --git a/zone/embparser.cpp b/zone/embparser.cpp index 9c91ba974..aa62f2b52 100644 --- a/zone/embparser.cpp +++ b/zone/embparser.cpp @@ -31,7 +31,7 @@ #include #include -extern Zone *zone; +extern Zone* zone; #ifdef EMBPERL_XS void perl_register_quest(); @@ -59,7 +59,7 @@ void perl_register_bot(); #endif // EMBPERL_XS_CLASSES #endif // EMBPERL_XS -const char *QuestEventSubroutines[_LargestEventID] = { +const char* QuestEventSubroutines[_LargestEventID] = { "EVENT_SAY", "EVENT_ITEM", "EVENT_DEATH", @@ -204,8 +204,8 @@ PerlembParser::PerlembParser() : perl(nullptr) global_npc_quest_status_ = questUnloaded; player_quest_status_ = questUnloaded; global_player_quest_status_ = questUnloaded; - bot_quest_status_ = questUnloaded; - global_bot_quest_status_ = questUnloaded; + bot_quest_status_ = questUnloaded; + global_bot_quest_status_ = questUnloaded; } PerlembParser::~PerlembParser() @@ -216,16 +216,16 @@ PerlembParser::~PerlembParser() void PerlembParser::ReloadQuests() { try { - if (perl == nullptr) { + if (!perl) { perl = new Embperl; - } - else { + } else { perl->Reinit(); } + MapFunctions(); } - catch (std::exception &e) { - if (perl != nullptr) { + catch (std::exception& e) { + if (perl) { delete perl; perl = nullptr; } @@ -236,286 +236,362 @@ void PerlembParser::ReloadQuests() errors_.clear(); npc_quest_status_.clear(); + global_npc_quest_status_ = questUnloaded; player_quest_status_ = questUnloaded; global_player_quest_status_ = questUnloaded; - bot_quest_status_ = questUnloaded; - global_bot_quest_status_ = questUnloaded; + bot_quest_status_ = questUnloaded; + global_bot_quest_status_ = questUnloaded; item_quest_status_.clear(); spell_quest_status_.clear(); } int PerlembParser::EventCommon( - QuestEventID event, - uint32 objid, - const char *data, - Mob *npcmob, - EQ::ItemInstance *item_inst, + QuestEventID event_id, + uint32 object_id, + const char* data, + Mob* npc_mob, + EQ::ItemInstance* inst, const SPDat_Spell_Struct* spell, - Mob *mob, - uint32 extradata, - bool global, - std::vector *extra_pointers -) { - if (!perl) { + Mob* mob, + uint32 extra_data, + bool is_global, + std::vector* extra_pointers +) +{ + if (!perl || event_id >= _LargestEventID) { return 0; } - if (event >= _LargestEventID) { - return 0; - } - - bool isPlayerQuest = false; - bool isGlobalPlayerQuest = false; - bool isGlobalNPC = false; - bool isBotQuest = false; - bool isGlobalBotQuest = false; - bool isItemQuest = false; - bool isSpellQuest = false; + bool is_player_quest = false; + bool is_global_player_quest = false; + bool is_global_npc_quest = false; + bool is_bot_quest = false; + bool is_global_bot_quest = false; + bool is_item_quest = false; + bool is_spell_quest = false; std::string package_name; GetQuestTypes( - isPlayerQuest, - isGlobalPlayerQuest, - isBotQuest, - isGlobalBotQuest, - isGlobalNPC, - isItemQuest, - isSpellQuest, - event, - npcmob, - item_inst, + is_player_quest, + is_global_player_quest, + is_bot_quest, + is_global_bot_quest, + is_global_npc_quest, + is_item_quest, + is_spell_quest, + event_id, + npc_mob, + inst, mob, - global + is_global ); GetQuestPackageName( - isPlayerQuest, - isGlobalPlayerQuest, - isBotQuest, - isGlobalBotQuest, - isGlobalNPC, - isItemQuest, - isSpellQuest, + is_player_quest, + is_global_player_quest, + is_bot_quest, + is_global_bot_quest, + is_global_npc_quest, + is_item_quest, + is_spell_quest, package_name, - event, - objid, + event_id, + object_id, data, - npcmob, - item_inst, - global + npc_mob, + inst, + is_global ); - const char *sub_name = QuestEventSubroutines[event]; - if (!perl->SubExists(package_name.c_str(), sub_name)) { + const std::string& sub_name = QuestEventSubroutines[event_id]; + + if (!perl->SubExists(package_name.c_str(), sub_name.c_str())) { return 0; } int char_id = 0; - ExportCharID(package_name, char_id, npcmob, mob); + + ExportCharID(package_name, char_id, npc_mob, mob); /* Check for QGlobal export event enable */ - if (parse->perl_event_export_settings[event].qglobals) { + if (parse->perl_event_export_settings[event_id].qglobals) { ExportQGlobals( - isPlayerQuest, - isGlobalPlayerQuest, - isBotQuest, - isGlobalBotQuest, - isGlobalNPC, - isItemQuest, - isSpellQuest, + is_player_quest, + is_global_player_quest, + is_bot_quest, + is_global_bot_quest, + is_global_npc_quest, + is_item_quest, + is_spell_quest, package_name, - npcmob, + npc_mob, mob, char_id ); } /* Check for Mob export event enable */ - if (parse->perl_event_export_settings[event].mob) { + if (parse->perl_event_export_settings[event_id].mob) { ExportMobVariables( - isPlayerQuest, - isGlobalPlayerQuest, - isBotQuest, - isGlobalBotQuest, - isGlobalNPC, - isItemQuest, - isSpellQuest, + is_player_quest, + is_global_player_quest, + is_bot_quest, + is_global_bot_quest, + is_global_npc_quest, + is_item_quest, + is_spell_quest, package_name, mob, - npcmob + npc_mob ); } /* Check for Zone export event enable */ - if (parse->perl_event_export_settings[event].zone) { + if (parse->perl_event_export_settings[event_id].zone) { ExportZoneVariables(package_name); } /* Check for Item export event enable */ - if (parse->perl_event_export_settings[event].item) { + if (parse->perl_event_export_settings[event_id].item) { ExportItemVariables(package_name, mob); } /* Check for Event export event enable */ - if (parse->perl_event_export_settings[event].event_variables) { - ExportEventVariables(package_name, event, objid, data, npcmob, item_inst, mob, extradata, extra_pointers); + if (parse->perl_event_export_settings[event_id].event_variables) { + ExportEventVariables(package_name, event_id, object_id, data, npc_mob, inst, mob, extra_data, extra_pointers); } - if (isPlayerQuest || isGlobalPlayerQuest) { - return SendCommands(package_name.c_str(), sub_name, 0, mob, mob, nullptr, nullptr); - } else if (isBotQuest || isGlobalBotQuest) { - return SendCommands(package_name.c_str(), sub_name, 0, npcmob, mob, nullptr, nullptr); - } else if (isItemQuest) { - return SendCommands(package_name.c_str(), sub_name, 0, mob, mob, item_inst, nullptr); - } else if (isSpellQuest) { + if (is_player_quest || is_global_player_quest) { + return SendCommands(package_name.c_str(), QuestEventSubroutines[event_id], 0, mob, mob, nullptr, nullptr); + } else if (is_bot_quest || is_global_bot_quest) { + return SendCommands(package_name.c_str(), QuestEventSubroutines[event_id], 0, npc_mob, mob, nullptr, nullptr); + } else if (is_item_quest) { + return SendCommands(package_name.c_str(), QuestEventSubroutines[event_id], 0, mob, mob, inst, nullptr); + } else if (is_spell_quest) { if (mob) { - return SendCommands(package_name.c_str(), sub_name, 0, mob, mob, nullptr, spell); + return SendCommands(package_name.c_str(), QuestEventSubroutines[event_id], 0, mob, mob, nullptr, spell); } else { - return SendCommands(package_name.c_str(), sub_name, 0, npcmob, mob, nullptr, spell); + return SendCommands(package_name.c_str(), QuestEventSubroutines[event_id], 0, npc_mob, mob, nullptr, spell); } } else { - return SendCommands(package_name.c_str(), sub_name, objid, npcmob, mob, nullptr, nullptr); + return SendCommands( + package_name.c_str(), + QuestEventSubroutines[event_id], + object_id, + npc_mob, + mob, + nullptr, + nullptr + ); } } int PerlembParser::EventNPC( - QuestEventID evt, NPC *npc, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers + QuestEventID event_id, + NPC* npc, + Mob* mob, + std::string data, + uint32 extra_data, + std::vector* extra_pointers ) { - return EventCommon(evt, npc->GetNPCTypeID(), data.c_str(), npc, nullptr, nullptr, mob, extra_data, false, extra_pointers); + return EventCommon( + event_id, + npc->GetNPCTypeID(), + data.c_str(), + npc, + nullptr, + nullptr, + mob, + extra_data, + false, + extra_pointers + ); } int PerlembParser::EventGlobalNPC( - QuestEventID evt, NPC *npc, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers + QuestEventID event_id, + NPC* npc, + Mob* mob, + std::string data, + uint32 extra_data, + std::vector* extra_pointers ) { - return EventCommon(evt, npc->GetNPCTypeID(), data.c_str(), npc, nullptr, nullptr, mob, extra_data, true, extra_pointers); + return EventCommon( + event_id, + npc->GetNPCTypeID(), + data.c_str(), + npc, + nullptr, + nullptr, + mob, + extra_data, + true, + extra_pointers + ); } int PerlembParser::EventPlayer( - QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers + QuestEventID event_id, + Client* client, + std::string data, + uint32 extra_data, + std::vector* extra_pointers ) { - return EventCommon(evt, 0, data.c_str(), nullptr, nullptr, nullptr, client, extra_data, false, extra_pointers); + return EventCommon( + event_id, + 0, + data.c_str(), + nullptr, + nullptr, + nullptr, + client, + extra_data, + false, + extra_pointers + ); } int PerlembParser::EventGlobalPlayer( - QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers + QuestEventID event_id, + Client* client, + std::string data, + uint32 extra_data, + std::vector* extra_pointers ) { - return EventCommon(evt, 0, data.c_str(), nullptr, nullptr, nullptr, client, extra_data, true, extra_pointers); + return EventCommon( + event_id, + 0, + data.c_str(), + nullptr, + nullptr, + nullptr, + client, + extra_data, + true, + extra_pointers + ); } int PerlembParser::EventItem( - QuestEventID evt, Client *client, EQ::ItemInstance *item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers + QuestEventID event_id, + Client* client, + EQ::ItemInstance* inst, + Mob* mob, + std::string data, + uint32 extra_data, + std::vector* extra_pointers ) { - // needs pointer validation on 'item' argument - return EventCommon(evt, item->GetID(), nullptr, nullptr, item, nullptr, client, extra_data, false, extra_pointers); + if (!inst) { + return 0; + } + + return EventCommon( + event_id, + inst->GetID(), + nullptr, + nullptr, + inst, + nullptr, + client, + extra_data, + false, + extra_pointers + ); } int PerlembParser::EventSpell( - QuestEventID evt, Mob *mob, Client *client, uint32 spell_id, std::string data, uint32 extra_data, - std::vector *extra_pointers + QuestEventID event_id, + Mob* mob, + Client* client, + uint32 spell_id, + std::string data, + uint32 extra_data, + std::vector* extra_pointers ) { - return EventCommon(evt, spell_id, data.c_str(), mob, nullptr, &spells[spell_id], client, extra_data, false, extra_pointers); + return EventCommon( + event_id, + spell_id, + data.c_str(), + mob, + nullptr, + &spells[spell_id], + client, + extra_data, + false, + extra_pointers + ); } -bool PerlembParser::HasQuestSub(uint32 npcid, QuestEventID evt) +bool PerlembParser::HasQuestSub(uint32 npc_id, QuestEventID event_id) { - std::stringstream package_name; - package_name << "qst_npc_" << npcid; - - if (!perl) { + if (!perl || event_id >= _LargestEventID) { return false; } - if (evt >= _LargestEventID) { - return false; - } - - const char *subname = QuestEventSubroutines[evt]; - - auto iter = npc_quest_status_.find(npcid); + auto iter = npc_quest_status_.find(npc_id); if (iter == npc_quest_status_.end() || iter->second == QuestFailedToLoad) { return false; } - return (perl->SubExists(package_name.str().c_str(), subname)); + const std::string& package_name = fmt::format( + "qst_npc_{}", + npc_id + ); + + return perl->SubExists(package_name.c_str(), QuestEventSubroutines[event_id]); } -bool PerlembParser::HasGlobalQuestSub(QuestEventID evt) +bool PerlembParser::HasGlobalQuestSub(QuestEventID event_id) { - if (!perl) { + if ( + !perl || + global_npc_quest_status_ != questLoaded || + event_id >= _LargestEventID + ) { return false; } - if (global_npc_quest_status_ != questLoaded) { - return false; - } - - if (evt >= _LargestEventID) { - return false; - } - - const char *subname = QuestEventSubroutines[evt]; - - return (perl->SubExists("qst_global_npc", subname)); + return perl->SubExists("qst_global_npc", QuestEventSubroutines[event_id]); } -bool PerlembParser::PlayerHasQuestSub(QuestEventID evt) +bool PerlembParser::PlayerHasQuestSub(QuestEventID event_id) { - if (!perl) { + if ( + !perl || + player_quest_status_ != questLoaded || + event_id >= _LargestEventID + ) { return false; } - if (player_quest_status_ != questLoaded) { - return false; - } - - if (evt >= _LargestEventID) { - return false; - } - - const char *subname = QuestEventSubroutines[evt]; - - return (perl->SubExists("qst_player", subname)); + return perl->SubExists("qst_player", QuestEventSubroutines[event_id]); } -bool PerlembParser::GlobalPlayerHasQuestSub(QuestEventID evt) +bool PerlembParser::GlobalPlayerHasQuestSub(QuestEventID event_id) { - if (!perl) { + if ( + !perl || + global_player_quest_status_ != questLoaded || + event_id >= _LargestEventID + ) { return false; } - if (global_player_quest_status_ != questLoaded) { - return false; - } - - if (evt >= _LargestEventID) { - return false; - } - - const char *subname = QuestEventSubroutines[evt]; - - return (perl->SubExists("qst_global_player", subname)); + return perl->SubExists("qst_global_player", QuestEventSubroutines[event_id]); } -bool PerlembParser::SpellHasQuestSub(uint32 spell_id, QuestEventID evt) +bool PerlembParser::SpellHasQuestSub(uint32 spell_id, QuestEventID event_id) { - std::stringstream package_name; - package_name << "qst_spell_" << spell_id; - - if (!perl) { + if (!perl || event_id >= _LargestEventID) { return false; } @@ -524,48 +600,35 @@ bool PerlembParser::SpellHasQuestSub(uint32 spell_id, QuestEventID evt) return false; } - if (evt >= _LargestEventID) { - return false; - } + const std::string& package_name = fmt::format( + "qst_spell_{}", + spell_id + ); - const char *subname = QuestEventSubroutines[evt]; - - return (perl->SubExists(package_name.str().c_str(), subname)); + return perl->SubExists(package_name.c_str(), QuestEventSubroutines[event_id]); } -bool PerlembParser::ItemHasQuestSub(EQ::ItemInstance *itm, QuestEventID evt) +bool PerlembParser::ItemHasQuestSub(EQ::ItemInstance* inst, QuestEventID event_id) { - - if (!perl) { + if (!perl || !inst || event_id >= _LargestEventID) { return false; } - if (itm == nullptr) { - return false; - } - - if (evt >= _LargestEventID) { - return false; - } - - std::stringstream package_name; - package_name << "qst_item_" << itm->GetID(); - - const char *subname = QuestEventSubroutines[evt]; - - auto iter = item_quest_status_.find(itm->GetID()); + auto iter = item_quest_status_.find(inst->GetID()); if (iter == item_quest_status_.end() || iter->second == QuestFailedToLoad) { return false; } - return (perl->SubExists(package_name.str().c_str(), subname)); + const std::string& package_name = fmt::format( + "qst_item_{}", + inst->GetID() + ); + + return perl->SubExists(package_name.c_str(), QuestEventSubroutines[event_id]); } void PerlembParser::LoadNPCScript(std::string filename, int npc_id) { - std::stringstream package_name; - package_name << "qst_npc_" << npc_id; - if (!perl) { return; } @@ -575,10 +638,14 @@ void PerlembParser::LoadNPCScript(std::string filename, int npc_id) return; } + const std::string& package_name = fmt::format( + "qst_npc_{}", + npc_id + ); + try { - perl->eval_file(package_name.str().c_str(), filename.c_str()); - } - catch (std::string e) { + perl->eval_file(package_name.c_str(), filename.c_str()); + } catch (std::string e) { AddError( fmt::format( "Error Compiling NPC Quest File [{}] NPC ID [{}] Error [{}]", @@ -597,18 +664,13 @@ void PerlembParser::LoadNPCScript(std::string filename, int npc_id) void PerlembParser::LoadGlobalNPCScript(std::string filename) { - if (!perl) { - return; - } - - if (global_npc_quest_status_ != questUnloaded) { + if (!perl || global_npc_quest_status_ != questUnloaded) { return; } try { perl->eval_file("qst_global_npc", filename.c_str()); - } - catch (std::string e) { + } catch (std::string e) { AddError( fmt::format( "Error Compiling Global NPC Quest File [{}] Error [{}]", @@ -626,18 +688,13 @@ void PerlembParser::LoadGlobalNPCScript(std::string filename) void PerlembParser::LoadPlayerScript(std::string filename) { - if (!perl) { - return; - } - - if (player_quest_status_ != questUnloaded) { + if (!perl || player_quest_status_ != questUnloaded) { return; } try { perl->eval_file("qst_player", filename.c_str()); - } - catch (std::string e) { + } catch (std::string e) { AddError( fmt::format( "Error Compiling Player Quest File [{}] Error [{}]", @@ -655,18 +712,13 @@ void PerlembParser::LoadPlayerScript(std::string filename) void PerlembParser::LoadGlobalPlayerScript(std::string filename) { - if (!perl) { - return; - } - - if (global_player_quest_status_ != questUnloaded) { + if (!perl || global_player_quest_status_ != questUnloaded) { return; } try { perl->eval_file("qst_global_player", filename.c_str()); - } - catch (std::string e) { + } catch (std::string e) { AddError( fmt::format( "Error Compiling Global Player Quest File [{}] Error [{}]", @@ -682,49 +734,43 @@ void PerlembParser::LoadGlobalPlayerScript(std::string filename) global_player_quest_status_ = questLoaded; } -void PerlembParser::LoadItemScript(std::string filename, EQ::ItemInstance *item) +void PerlembParser::LoadItemScript(std::string filename, EQ::ItemInstance* inst) { - if (item == nullptr) { + if (!inst || !perl) { return; } - std::stringstream package_name; - package_name << "qst_item_" << item->GetID(); - - if (!perl) { - return; - } - - auto iter = item_quest_status_.find(item->GetID()); + auto iter = item_quest_status_.find(inst->GetID()); if (iter != item_quest_status_.end()) { return; } + const std::string& package_name = fmt::format( + "qst_item_{}", + inst->GetID() + ); + try { - perl->eval_file(package_name.str().c_str(), filename.c_str()); - } - catch (std::string e) { + perl->eval_file(package_name.c_str(), filename.c_str()); + } catch (std::string e) { AddError( fmt::format( "Error Compiling Item Quest File [{}] Item ID [{}] Error [{}]", filename, - item->GetID(), + inst->GetID(), e ) ); - item_quest_status_[item->GetID()] = questFailedToLoad; + item_quest_status_[inst->GetID()] = questFailedToLoad; return; } - item_quest_status_[item->GetID()] = questLoaded; + item_quest_status_[inst->GetID()] = questLoaded; } void PerlembParser::LoadSpellScript(std::string filename, uint32 spell_id) { - std::stringstream package_name; - package_name << "qst_spell_" << spell_id; - if (!perl) { return; } @@ -734,10 +780,14 @@ void PerlembParser::LoadSpellScript(std::string filename, uint32 spell_id) return; } + const std::string& package_name = fmt::format( + "qst_spell_{}", + spell_id + ); + try { - perl->eval_file(package_name.str().c_str(), filename.c_str()); - } - catch (std::string e) { + perl->eval_file(package_name.c_str(), filename.c_str()); + } catch (std::string e) { AddError( fmt::format( "Error Compiling Spell Quest File [{}] Spell ID [{}] Error [{}]", @@ -769,7 +819,7 @@ std::string PerlembParser::GetVar(std::string name) return std::string(); } -void PerlembParser::ExportHash(const char *pkgprefix, const char *hashname, std::map &vals) +void PerlembParser::ExportHash(const char* prefix, const char* hash_name, std::map& vals) { if (!perl) { return; @@ -777,7 +827,11 @@ void PerlembParser::ExportHash(const char *pkgprefix, const char *hashname, std: try { perl->sethash( - std::string(pkgprefix).append("::").append(hashname).c_str(), + fmt::format( + "{}::{}", + prefix, + hash_name + ).c_str(), vals ); } catch (std::string e) { @@ -790,37 +844,21 @@ void PerlembParser::ExportHash(const char *pkgprefix, const char *hashname, std: } } -void PerlembParser::ExportVar(const char *pkgprefix, const char *varname, int value) +void PerlembParser::ExportVar(const char* prefix, const char* variable_name, int value) { - if (!perl) { return; } try { - perl->seti(std::string(pkgprefix).append("::").append(varname).c_str(), value); - - } - catch (std::string e) { - AddError( + perl->seti( fmt::format( - "Error exporting Perl variable [{}]", - e - ) + "{}::{}", + prefix, + variable_name + ).c_str(), + value ); - } -} - -void PerlembParser::ExportVar(const char *pkgprefix, const char *varname, unsigned int value) -{ - - if (!perl) { - return; - } - - try { - perl->seti(std::string(pkgprefix).append("::").append(varname).c_str(), value); - } catch (std::string e) { AddError( fmt::format( @@ -831,15 +869,21 @@ void PerlembParser::ExportVar(const char *pkgprefix, const char *varname, unsign } } -void PerlembParser::ExportVar(const char *pkgprefix, const char *varname, float value) +void PerlembParser::ExportVar(const char* prefix, const char* variable_name, unsigned int value) { - if (!perl) { return; } try { - perl->setd(std::string(pkgprefix).append("::").append(varname).c_str(), value); + perl->seti( + fmt::format( + "{}::{}", + prefix, + variable_name + ).c_str(), + value + ); } catch (std::string e) { AddError( fmt::format( @@ -850,16 +894,47 @@ void PerlembParser::ExportVar(const char *pkgprefix, const char *varname, float } } -void PerlembParser::ExportVar(const char *pkgprefix, const char *varname, const char *value) +void PerlembParser::ExportVar(const char* prefix, const char* variable_name, float value) { if (!perl) { return; } try { - perl->setstr(std::string(pkgprefix).append("::").append(varname).c_str(), value); + perl->setd( + fmt::format( + "{}::{}", + prefix, + variable_name + ).c_str(), + value + ); + } catch (std::string e) { + AddError( + fmt::format( + "Error exporting Perl variable [{}]", + e + ) + ); } - catch (std::string e) { +} + +void PerlembParser::ExportVar(const char* prefix, const char* variable_name, const char* value) +{ + if (!perl) { + return; + } + + try { + perl->setstr( + fmt::format( + "{}::{}", + prefix, + variable_name + ).c_str(), + value + ); + } catch (std::string e) { AddError( fmt::format( "Error exporting Perl variable [{}]", @@ -870,29 +945,35 @@ void PerlembParser::ExportVar(const char *pkgprefix, const char *varname, const } -void PerlembParser::ExportVar(const char* pkgprefix, const char* varname, const char* classname, void* value) +void PerlembParser::ExportVar(const char* prefix, const char* variable_name, const char* class_name, void* value) { if (!perl) { return; } - // todo: try/catch shouldn't be necessary here (called perl apis don't throw) try { - perl->setptr(std::string(pkgprefix).append("::").append(varname).c_str(), classname, value); - } - catch (std::string e) { + perl->setptr( + fmt::format( + "{}::{}", + prefix, + variable_name + ).c_str(), + class_name, + value + ); + } catch (std::string e) { AddError(fmt::format("Error exporting Perl variable [{}]", e)); } } int PerlembParser::SendCommands( - const char *pkgprefix, - const char *event, + const char* prefix, + const char* event_id, uint32 object_id, - Mob *other, - Mob *mob, - EQ::ItemInstance *item_inst, - const SPDat_Spell_Struct *spell + Mob* other, + Mob* mob, + EQ::ItemInstance* inst, + const SPDat_Spell_Struct* spell ) { if (!perl) { @@ -901,26 +982,23 @@ int PerlembParser::SendCommands( int ret_value = 0; if (mob && mob->IsClient()) { - quest_manager.StartQuest(other, mob->CastToClient(), item_inst, spell); - } - else { + quest_manager.StartQuest(other, mob->CastToClient(), inst, spell); + } else { quest_manager.StartQuest(other); } try { - - std::string cmd = "package " + (std::string) (pkgprefix) + (std::string) (";"); - perl->eval(cmd.c_str()); + perl->eval(fmt::format("package {};", prefix).c_str()); #ifdef EMBPERL_XS_CLASSES dTHX; { - std::string cl = (std::string) "$" + (std::string) pkgprefix + (std::string) "::client"; - std::string np = (std::string) "$" + (std::string) pkgprefix + (std::string) "::npc"; - std::string qi = (std::string) "$" + (std::string) pkgprefix + (std::string) "::questitem"; - std::string sp = (std::string) "$" + (std::string) pkgprefix + (std::string) "::spell"; - std::string enl = (std::string) "$" + (std::string) pkgprefix + (std::string) "::entity_list"; - std::string bot = (std::string) "$" + (std::string) pkgprefix + (std::string) "::bot"; + std::string cl = fmt::format("${}::client", prefix); + std::string np = fmt::format("${}::npc", prefix); + std::string qi = fmt::format("${}::questitem", prefix); + std::string sp = fmt::format("${}::spell", prefix); + std::string enl = fmt::format("${}::entity_list", prefix); + std::string bot = fmt::format("${}::bot", prefix); if (clear_vars_.find(cl) != clear_vars_.end()) { auto e = fmt::format("{} = undef;", cl); @@ -956,11 +1034,11 @@ int PerlembParser::SendCommands( std::string buf; //init a couple special vars: client, npc, entity_list - Client *curc = quest_manager.GetInitiator(); - buf = fmt::format("{}::client", pkgprefix); - SV *client = get_sv(buf.c_str(), true); - if (curc) { - sv_setref_pv(client, "Client", curc); + Client* c = quest_manager.GetInitiator(); + buf = fmt::format("{}::client", prefix); + SV* client = get_sv(buf.c_str(), true); + if (c) { + sv_setref_pv(client, "Client", c); } else { //clear out the value, mainly to get rid of blessedness sv_setsv(client, _empty_sv); @@ -968,52 +1046,52 @@ int PerlembParser::SendCommands( //only export NPC if it's a npc quest if (!other->IsClient() && other->IsNPC()) { - NPC *curn = quest_manager.GetNPC(); - buf = fmt::format("{}::npc", pkgprefix); - SV *npc = get_sv(buf.c_str(), true); - sv_setref_pv(npc, "NPC", curn); + NPC* n = quest_manager.GetNPC(); + buf = fmt::format("{}::npc", prefix); + SV* npc = get_sv(buf.c_str(), true); + sv_setref_pv(npc, "NPC", n); } if (!other->IsClient() && other->IsBot()) { - Bot *curb = quest_manager.GetBot(); - buf = fmt::format("{}::bot", pkgprefix); - SV *bot = get_sv(buf.c_str(), true); - sv_setref_pv(bot, "Bot", curb); + Bot* b = quest_manager.GetBot(); + buf = fmt::format("{}::bot", prefix); + SV* bot = get_sv(buf.c_str(), true); + sv_setref_pv(bot, "Bot", b); } - //only export QuestItem if it's an item quest - if (item_inst) { - EQ::ItemInstance *curi = quest_manager.GetQuestItem(); - buf = fmt::format("{}::questitem", pkgprefix); - SV *questitem = get_sv(buf.c_str(), true); - sv_setref_pv(questitem, "QuestItem", curi); + //only export QuestItem if it's an inst quest + if (inst) { + auto i = quest_manager.GetQuestItem(); + buf = fmt::format("{}::questitem", prefix); + SV* questitem = get_sv(buf.c_str(), true); + sv_setref_pv(questitem, "QuestItem", i); } if (spell) { - const SPDat_Spell_Struct* current_spell = quest_manager.GetQuestSpell(); - SPDat_Spell_Struct* real_spell = const_cast(current_spell); - buf = fmt::format("{}::spell", pkgprefix); - SV *spell = get_sv(buf.c_str(), true); - sv_setref_pv(spell, "Spell", (void *) real_spell); + const auto current_spell = quest_manager.GetQuestSpell(); + auto real_spell = const_cast(current_spell); + buf = fmt::format("{}::spell", prefix); + SV* spell = get_sv(buf.c_str(), true); + sv_setref_pv(spell, "Spell", (void*) real_spell); } - buf = fmt::format("{}::entity_list", pkgprefix); - SV *el = get_sv(buf.c_str(), true); + buf = fmt::format("{}::entity_list", prefix); + SV* el = get_sv(buf.c_str(), true); sv_setref_pv(el, "EntityList", &entity_list); #endif //now call the requested sub - ret_value = perl->dosub(std::string(pkgprefix).append("::").append(event).c_str()); + ret_value = perl->dosub(std::string(prefix).append("::").append(event_id).c_str()); #ifdef EMBPERL_XS_CLASSES { - std::string cl = (std::string) "$" + (std::string) pkgprefix + (std::string) "::client"; - std::string np = (std::string) "$" + (std::string) pkgprefix + (std::string) "::npc"; - std::string qi = (std::string) "$" + (std::string) pkgprefix + (std::string) "::questitem"; - std::string sp = (std::string) "$" + (std::string) pkgprefix + (std::string) "::spell"; - std::string enl = (std::string) "$" + (std::string) pkgprefix + (std::string) "::entity_list"; - std::string bot = (std::string) "$" + (std::string) pkgprefix + (std::string) "::bot"; + std::string cl = fmt::format("${}::client", prefix); + std::string np = fmt::format("${}::npc", prefix); + std::string qi = fmt::format("${}::questitem", prefix); + std::string sp = fmt::format("${}::spell", prefix); + std::string enl = fmt::format("${}::entity_list", prefix); + std::string bot = fmt::format("${}::bot", prefix); clear_vars_[cl] = 1; clear_vars_[np] = 1; @@ -1028,8 +1106,8 @@ int PerlembParser::SendCommands( AddError( fmt::format( "Script Error | Package [{}] Event [{}] Error [{}]", - pkgprefix, - event, + prefix, + event_id, Strings::Trim(e) ) ); @@ -1040,7 +1118,7 @@ int PerlembParser::SendCommands( #ifdef EMBPERL_XS_CLASSES if (!quest_manager.QuestsRunning()) { std::string eval_str; - for (const auto &v : clear_vars_) { + for (const auto& v: clear_vars_) { eval_str += fmt::format("{} = undef;", v.first); } @@ -1093,161 +1171,165 @@ void PerlembParser::MapFunctions() } void PerlembParser::GetQuestTypes( - bool &isPlayerQuest, - bool &isGlobalPlayerQuest, - bool &isBotQuest, - bool &isGlobalBotQuest, - bool &isGlobalNPC, - bool &isItemQuest, - bool &isSpellQuest, - QuestEventID event, - Mob *npcmob, - EQ::ItemInstance *item_inst, - Mob *mob, - bool global -) { + bool& is_player_quest, + bool& is_global_player_quest, + bool& is_bot_quest, + bool& is_global_bot_quest, + bool& is_global_npc_quest, + bool& is_item_quest, + bool& is_spell_quest, + QuestEventID event_id, + Mob* npc_mob, + EQ::ItemInstance* inst, + Mob* mob, + bool is_global +) +{ if ( - event == EVENT_SPELL_EFFECT_CLIENT || - event == EVENT_SPELL_EFFECT_NPC || - event == EVENT_SPELL_EFFECT_BOT || - event == EVENT_SPELL_EFFECT_BUFF_TIC_CLIENT || - event == EVENT_SPELL_EFFECT_BUFF_TIC_NPC || - event == EVENT_SPELL_EFFECT_BUFF_TIC_BOT || - event == EVENT_SPELL_FADE || - event == EVENT_SPELL_EFFECT_TRANSLOCATE_COMPLETE + event_id == EVENT_SPELL_EFFECT_CLIENT || + event_id == EVENT_SPELL_EFFECT_NPC || + event_id == EVENT_SPELL_EFFECT_BOT || + event_id == EVENT_SPELL_EFFECT_BUFF_TIC_CLIENT || + event_id == EVENT_SPELL_EFFECT_BUFF_TIC_NPC || + event_id == EVENT_SPELL_EFFECT_BUFF_TIC_BOT || + event_id == EVENT_SPELL_FADE || + event_id == EVENT_SPELL_EFFECT_TRANSLOCATE_COMPLETE ) { - isSpellQuest = true; + is_spell_quest = true; } else { - if (npcmob) { - if (!item_inst) { - if (global) { - if (npcmob->IsBot()) { - isGlobalBotQuest = true; + if (npc_mob) { + if (!inst) { + if (is_global) { + if (npc_mob->IsBot()) { + is_global_bot_quest = true; } } else { - if (npcmob->IsBot()) { - isBotQuest = true; + if (npc_mob->IsBot()) { + is_bot_quest = true; } } } else { - isItemQuest = true; + is_item_quest = true; } - } else if (!npcmob && mob) { - if (!item_inst) { - if (global) { + } else if (!npc_mob && mob) { + if (!inst) { + if (is_global) { if (mob->IsClient()) { - isGlobalPlayerQuest = true; + is_global_player_quest = true; } } else { if (mob->IsClient()) { - isPlayerQuest = true; + is_player_quest = true; } } } else { - isItemQuest = true; + is_item_quest = true; } } } } void PerlembParser::GetQuestPackageName( - bool &isPlayerQuest, - bool &isGlobalPlayerQuest, - bool &isBotQuest, - bool &isGlobalBotQuest, - bool &isGlobalNPC, - bool &isItemQuest, - bool &isSpellQuest, - std::string &package_name, - QuestEventID event, - uint32 objid, - const char *data, - Mob *npcmob, - EQ::ItemInstance *item_inst, - bool global + bool& is_player_quest, + bool& is_global_player_quest, + bool& is_bot_quest, + bool& is_global_bot_quest, + bool& is_global_npc_quest, + bool& is_item_quest, + bool& is_spell_quest, + std::string& package_name, + QuestEventID event_id, + uint32 object_id, + const char* data, + Mob* npc_mob, + EQ::ItemInstance* inst, + bool is_global ) { if ( - !isPlayerQuest && - !isGlobalPlayerQuest && - !isBotQuest && - !isGlobalBotQuest && - !isItemQuest && - !isSpellQuest + !is_player_quest && + !is_global_player_quest && + !is_bot_quest && + !is_global_bot_quest && + !is_item_quest && + !is_spell_quest ) { - if (global) { - isGlobalNPC = true; - package_name = "qst_global_npc"; + if (is_global) { + is_global_npc_quest = true; + package_name = "qst_global_npc"; } else { - package_name = fmt::format("qst_npc_{}", npcmob->GetNPCTypeID()); + package_name = fmt::format("qst_npc_{}", npc_mob->GetNPCTypeID()); } - } else if (isItemQuest) { - // need a valid EQ::ItemInstance pointer check here..unsure how to cancel this process - const EQ::ItemData *item = item_inst->GetItem(); - package_name = fmt::format("qst_item_{}", item->ID); - } else if (isPlayerQuest) { + } else if (is_item_quest) { + if (!inst) { + return; + } + + package_name = fmt::format("qst_item_{}", inst->GetID()); + } else if (is_player_quest) { package_name = "qst_player"; - } else if (isGlobalPlayerQuest) { + } else if (is_global_player_quest) { package_name = "qst_global_player"; - } else if (isBotQuest) { + } else if (is_bot_quest) { package_name = "qst_bot"; - } else if (isGlobalBotQuest) { + } else if (is_global_bot_quest) { package_name = "qst_global_bot"; } else { - package_name = fmt::format("qst_spell_{}", objid); + package_name = fmt::format("qst_spell_{}", object_id); } } -void PerlembParser::ExportCharID(const std::string &package_name, int &char_id, Mob *npcmob, Mob *mob) +void PerlembParser::ExportCharID(const std::string& package_name, int& char_id, Mob* npc_mob, Mob* mob) { if (mob && mob->IsClient()) { // some events like waypoint and spawn don't have a player involved char_id = mob->CastToClient()->CharacterID(); } else { - if (npcmob) { - char_id = -static_cast(npcmob->GetNPCTypeID()); // make char id negative npc id as a fudge - } - else if (mob && mob->IsNPC()) { + if (npc_mob) { + char_id = -static_cast(npc_mob->GetNPCTypeID()); // make char id negative npc id as a fudge + } else if (mob && mob->IsNPC()) { char_id = -static_cast(mob->CastToNPC()->GetNPCTypeID()); // make char id negative npc id as a fudge } } + ExportVar(package_name.c_str(), "charid", char_id); } void PerlembParser::ExportQGlobals( - bool isPlayerQuest, - bool isGlobalPlayerQuest, - bool isBotQuest, - bool isGlobalBotQuest, - bool isGlobalNPC, - bool isItemQuest, - bool isSpellQuest, - std::string &package_name, - Mob *npcmob, - Mob *mob, + bool is_player_quest, + bool is_global_player_quest, + bool is_bot_quest, + bool is_global_bot_quest, + bool is_global_npc_quest, + bool is_item_quest, + bool is_spell_quest, + std::string& package_name, + Mob* npc_mob, + Mob* mob, int char_id -) { +) +{ //NPC quest if ( - !isPlayerQuest && - !isGlobalPlayerQuest && - !isBotQuest && - !isGlobalBotQuest && - !isItemQuest && - !isSpellQuest + !is_player_quest && + !is_global_player_quest && + !is_bot_quest && + !is_global_bot_quest && + !is_item_quest && + !is_spell_quest ) { //only export for npcs that are global enabled. - if (npcmob && npcmob->GetQglobal()) { + if (npc_mob && npc_mob->GetQglobal()) { std::map globhash; - QGlobalCache *npc_c = nullptr; - QGlobalCache *char_c = nullptr; - QGlobalCache *zone_c = nullptr; + QGlobalCache* npc_c = nullptr; + QGlobalCache* char_c = nullptr; + QGlobalCache* zone_c = nullptr; //retrieve our globals - if (npcmob) { - if (npcmob->IsNPC()) { - npc_c = npcmob->CastToNPC()->GetQGlobals(); - } else if (npcmob->IsClient()) { - char_c = npcmob->CastToClient()->GetQGlobals(); + if (npc_mob) { + if (npc_mob->IsNPC()) { + npc_c = npc_mob->CastToNPC()->GetQGlobals(); + } else if (npc_mob->IsClient()) { + char_c = npc_mob->CastToClient()->GetQGlobals(); } } @@ -1258,9 +1340,9 @@ void PerlembParser::ExportQGlobals( zone_c = zone->GetQGlobals(); if (!npc_c) { - if (npcmob && npcmob->IsNPC()) { - npc_c = npcmob->CastToNPC()->CreateQGlobals(); - npc_c->LoadByNPCID(npcmob->GetNPCTypeID()); + if (npc_mob && npc_mob->IsNPC()) { + npc_c = npc_mob->CastToNPC()->CreateQGlobals(); + npc_c->LoadByNPCID(npc_mob->GetNPCTypeID()); } } @@ -1282,17 +1364,17 @@ void PerlembParser::ExportQGlobals( QGlobalCache::Combine( globalMap, npc_c->GetBucket(), - npcmob->GetNPCTypeID(), + npc_mob->GetNPCTypeID(), char_id, - zone->GetZoneID()) - ; + zone->GetZoneID() + ); } if (char_c) { QGlobalCache::Combine( globalMap, char_c->GetBucket(), - npcmob->GetNPCTypeID(), + npc_mob->GetNPCTypeID(), char_id, zone->GetZoneID() ); @@ -1302,7 +1384,7 @@ void PerlembParser::ExportQGlobals( QGlobalCache::Combine( globalMap, zone_c->GetBucket(), - npcmob->GetNPCTypeID(), + npc_mob->GetNPCTypeID(), char_id, zone->GetZoneID() ); @@ -1319,8 +1401,8 @@ void PerlembParser::ExportQGlobals( } } else { std::map globhash; - QGlobalCache *char_c = nullptr; - QGlobalCache *zone_c = nullptr; + QGlobalCache* char_c = nullptr; + QGlobalCache* zone_c = nullptr; //retrieve our globals if (mob && mob->IsClient()) { @@ -1363,17 +1445,18 @@ void PerlembParser::ExportQGlobals( } void PerlembParser::ExportMobVariables( - bool isPlayerQuest, - bool isGlobalPlayerQuest, - bool isBotQuest, - bool isGlobalBotQuest, - bool isGlobalNPC, - bool isItemQuest, - bool isSpellQuest, - std::string &package_name, - Mob *mob, - Mob *npcmob -) { + bool is_player_quest, + bool is_global_player_quest, + bool is_bot_quest, + bool is_global_bot_quest, + bool is_global_npc_quest, + bool is_item_quest, + bool is_spell_quest, + std::string& package_name, + Mob* mob, + Mob* npc_mob +) +{ uint8 fac = 0; if (mob && mob->IsClient()) { ExportVar(package_name.c_str(), "uguild_id", mob->CastToClient()->GuildID()); @@ -1387,18 +1470,23 @@ void PerlembParser::ExportMobVariables( } if ( - !isPlayerQuest && - !isGlobalPlayerQuest && - !isBotQuest && - !isGlobalBotQuest && - !isItemQuest + !is_player_quest && + !is_global_player_quest && + !is_bot_quest && + !is_global_bot_quest && + !is_item_quest ) { - if (mob && mob->IsClient() && npcmob && npcmob->IsNPC()) { - Client *client = mob->CastToClient(); + if (mob && mob->IsClient() && npc_mob && npc_mob->IsNPC()) { + Client* c = mob->CastToClient(); - fac = client->GetFactionLevel( - client->CharacterID(), npcmob->GetID(), client->GetFactionRace(), - client->GetClass(), client->GetDeity(), npcmob->GetPrimaryFaction(), npcmob + fac = c->GetFactionLevel( + c->CharacterID(), + npc_mob->GetID(), + c->GetFactionRace(), + c->GetClass(), + c->GetDeity(), + npc_mob->GetPrimaryFaction(), + npc_mob ); } } @@ -1412,25 +1500,25 @@ void PerlembParser::ExportMobVariables( } if ( - !isPlayerQuest && - !isGlobalPlayerQuest && - !isBotQuest && - !isGlobalBotQuest && - !isItemQuest && - !isSpellQuest + !is_player_quest && + !is_global_player_quest && + !is_bot_quest && + !is_global_bot_quest && + !is_item_quest && + !is_spell_quest ) { - if (npcmob->IsNPC()) { - ExportVar(package_name.c_str(), "mname", npcmob->GetName()); - ExportVar(package_name.c_str(), "mobid", npcmob->GetID()); - ExportVar(package_name.c_str(), "mlevel", npcmob->GetLevel()); - ExportVar(package_name.c_str(), "hpratio", npcmob->GetHPRatio()); - ExportVar(package_name.c_str(), "x", npcmob->GetX()); - ExportVar(package_name.c_str(), "y", npcmob->GetY()); - ExportVar(package_name.c_str(), "z", npcmob->GetZ()); - ExportVar(package_name.c_str(), "h", npcmob->GetHeading()); - if (npcmob->GetTarget()) { - ExportVar(package_name.c_str(), "targetid", npcmob->GetTarget()->GetID()); - ExportVar(package_name.c_str(), "targetname", npcmob->GetTarget()->GetName()); + if (npc_mob->IsNPC()) { + ExportVar(package_name.c_str(), "mname", npc_mob->GetName()); + ExportVar(package_name.c_str(), "mobid", npc_mob->GetID()); + ExportVar(package_name.c_str(), "mlevel", npc_mob->GetLevel()); + ExportVar(package_name.c_str(), "hpratio", npc_mob->GetHPRatio()); + ExportVar(package_name.c_str(), "x", npc_mob->GetX()); + ExportVar(package_name.c_str(), "y", npc_mob->GetY()); + ExportVar(package_name.c_str(), "z", npc_mob->GetZ()); + ExportVar(package_name.c_str(), "h", npc_mob->GetHeading()); + if (npc_mob->GetTarget()) { + ExportVar(package_name.c_str(), "targetid", npc_mob->GetTarget()->GetID()); + ExportVar(package_name.c_str(), "targetname", npc_mob->GetTarget()->GetName()); } } @@ -1440,7 +1528,7 @@ void PerlembParser::ExportMobVariables( } } -void PerlembParser::ExportZoneVariables(std::string &package_name) +void PerlembParser::ExportZoneVariables(std::string& package_name) { if (zone) { ExportVar(package_name.c_str(), "zoneid", zone->GetZoneID()); @@ -1448,7 +1536,7 @@ void PerlembParser::ExportZoneVariables(std::string &package_name) ExportVar(package_name.c_str(), "zonesn", zone->GetShortName()); ExportVar(package_name.c_str(), "instanceid", zone->GetInstanceID()); ExportVar(package_name.c_str(), "instanceversion", zone->GetInstanceVersion()); - TimeOfDay_Struct eqTime{}; + TimeOfDay_Struct eqTime{ }; zone->zone_time.GetCurrentEQTimeOfDay(time(0), &eqTime); ExportVar(package_name.c_str(), "zonehour", eqTime.hour - 1); ExportVar(package_name.c_str(), "zonemin", eqTime.minute); @@ -1457,67 +1545,63 @@ void PerlembParser::ExportZoneVariables(std::string &package_name) } } -void PerlembParser::ExportItemVariables(std::string &package_name, Mob *mob) +void PerlembParser::ExportItemVariables(std::string& package_name, Mob* mob) { if (mob && mob->IsClient()) { - std::string hashname = package_name + std::string("::hasitem"); - - //start with an empty hash - perl->eval(std::string("%").append(hashname).append(" = ();").c_str()); + perl->eval(fmt::format("%{}::hasitem = ();", package_name).c_str()); for (int slot = EQ::invslot::EQUIPMENT_BEGIN; slot <= EQ::invslot::GENERAL_END; slot++) { - int itemid = mob->CastToClient()->GetItemIDAt(slot); - if (itemid != -1 && itemid != 0) { - // this is really ugly with fmtlib, I think I did it right - auto hi_decl = fmt::format("push (@{{${0}{{{1}}}}},{2});", hashname, itemid, slot); + int item_id = mob->CastToClient()->GetItemIDAt(slot); + if (item_id != -1 && item_id != 0) { + auto hi_decl = fmt::format("push (@{{${0}::hasitem{{{1}}}}},{2});", package_name, item_id, slot); perl->eval(hi_decl.c_str()); } } } if (mob && mob->IsClient()) { - std::string hashname = package_name + std::string("::oncursor"); - perl->eval(std::string("%").append(hashname).append(" = ();").c_str()); - int itemid = mob->CastToClient()->GetItemIDAt(EQ::invslot::slotCursor); - if (itemid != -1 && itemid != 0) { - // this is really ugly with fmtlib, I think I did it right - auto hi_decl = fmt::format("push (@{{${0}{{{1}}}}},{2});", hashname, itemid, EQ::invslot::slotCursor); + perl->eval(fmt::format("%{}::oncursor = ();", package_name).c_str()); + + int item_id = mob->CastToClient()->GetItemIDAt(EQ::invslot::slotCursor); + if (item_id != -1 && item_id != 0) { + auto hi_decl = fmt::format("push (@{{${0}::oncursor{{{1}}}}},{2});", package_name, item_id, EQ::invslot::slotCursor); perl->eval(hi_decl.c_str()); } } } void PerlembParser::ExportEventVariables( - std::string &package_name, - QuestEventID event, - uint32 objid, - const char *data, - Mob *npcmob, - EQ::ItemInstance *item_inst, - Mob *mob, - uint32 extradata, - std::vector *extra_pointers -) { - switch (event) { + std::string& package_name, + QuestEventID event_id, + uint32 object_id, + const char* data, + Mob* npc_mob, + EQ::ItemInstance* inst, + Mob* mob, + uint32 extra_data, + std::vector* extra_pointers +) +{ + switch (event_id) { case EVENT_SAY: { - if (npcmob && npcmob->IsNPC() && mob) { - npcmob->CastToNPC()->DoQuestPause(mob); + if (npc_mob && npc_mob->IsNPC() && mob) { + npc_mob->CastToNPC()->DoQuestPause(mob); } - ExportVar(package_name.c_str(), "data", objid); + ExportVar(package_name.c_str(), "data", object_id); ExportVar(package_name.c_str(), "text", data); - ExportVar(package_name.c_str(), "langid", extradata); + ExportVar(package_name.c_str(), "langid", extra_data); break; } case EVENT_TRADE: { if (extra_pointers) { - size_t sz = extra_pointers->size(); + size_t sz = extra_pointers->size(); for (size_t i = 0; i < sz; ++i) { - auto* inst = std::any_cast(extra_pointers->at(i)); - const uint32 item_id = inst ? inst->GetItem()->ID : 0; - const int16 item_charges = inst ? inst->GetCharges() : 0; - const auto is_attuned = inst ? inst->IsAttuned() : false; + auto* inst = std::any_cast(extra_pointers->at(i)); + const uint32 item_id = inst ? inst->GetItem()->ID : 0; + const int16 item_charges = inst ? inst->GetCharges() : 0; + const auto is_attuned = inst ? inst->IsAttuned() : false; auto var_name = fmt::format("item{}", i + 1); ExportVar(package_name.c_str(), var_name.c_str(), item_id); @@ -1537,9 +1621,9 @@ void PerlembParser::ExportEventVariables( } } - auto unique_id = npcmob->GetNPCTypeID(); - if (npcmob->IsBot()) { - unique_id = npcmob->CastToBot()->GetBotID(); + auto unique_id = npc_mob->GetNPCTypeID(); + if (npc_mob->IsBot()) { + unique_id = npc_mob->CastToBot()->GetBotID(); } ExportVar(package_name.c_str(), "copper", GetVar(fmt::format("copper.{}", unique_id)).c_str()); @@ -1554,7 +1638,7 @@ void PerlembParser::ExportEventVariables( perl->eval(fmt::format("++${}{{${}::item3}};", hash_name, package_name).c_str()); perl->eval(fmt::format("++${}{{${}::item4}};", hash_name, package_name).c_str()); - if (npcmob->IsBot()) { + if (npc_mob->IsBot()) { perl->eval(fmt::format("++${}{{${}::item5}};", hash_name, package_name).c_str()); perl->eval(fmt::format("++${}{{${}::item6}};", hash_name, package_name).c_str()); perl->eval(fmt::format("++${}{{${}::item7}};", hash_name, package_name).c_str()); @@ -1579,8 +1663,8 @@ void PerlembParser::ExportEventVariables( } case EVENT_HP: { - ExportVar(package_name.c_str(), "hpevent", extradata ? "-1" : data); - ExportVar(package_name.c_str(), "inchpevent", extradata ? data : "-1"); + ExportVar(package_name.c_str(), "hpevent", extra_data ? "-1" : data); + ExportVar(package_name.c_str(), "inchpevent", extra_data ? data : "-1"); break; } @@ -1632,7 +1716,12 @@ void PerlembParser::ExportEventVariables( ExportVar(package_name.c_str(), "corpse_id", sep.arg[3]); if (extra_pointers && extra_pointers->size() >= 1) { - ExportVar(package_name.c_str(), "item", "QuestItem", std::any_cast(extra_pointers->at(0))); + ExportVar( + package_name.c_str(), + "item", + "QuestItem", + std::any_cast(extra_pointers->at(0)) + ); } if (extra_pointers && extra_pointers->size() == 2) { @@ -1667,7 +1756,7 @@ void PerlembParser::ExportEventVariables( } if (IsValidSpell(Strings::ToUnsignedInt(sep.arg[0]))) { - ExportVar(package_name.c_str(), "spell", "Spell", (void*)&spells[Strings::ToUnsignedInt(sep.arg[0])]); + ExportVar(package_name.c_str(), "spell", "Spell", (void*) &spells[Strings::ToUnsignedInt(sep.arg[0])]); } break; @@ -1703,19 +1792,24 @@ void PerlembParser::ExportEventVariables( case EVENT_PLAYER_PICKUP: { ExportVar(package_name.c_str(), "picked_up_id", data); - ExportVar(package_name.c_str(), "picked_up_entity_id", extradata); + ExportVar(package_name.c_str(), "picked_up_entity_id", extra_data); if (extra_pointers && extra_pointers->size() == 1) { - ExportVar(package_name.c_str(), "item", "QuestItem", std::any_cast(extra_pointers->at(0))); + ExportVar( + package_name.c_str(), + "item", + "QuestItem", + std::any_cast(extra_pointers->at(0)) + ); } break; } case EVENT_AGGRO_SAY: { - ExportVar(package_name.c_str(), "data", objid); + ExportVar(package_name.c_str(), "data", object_id); ExportVar(package_name.c_str(), "text", data); - ExportVar(package_name.c_str(), "langid", extradata); + ExportVar(package_name.c_str(), "langid", extra_data); break; } @@ -1733,30 +1827,30 @@ void PerlembParser::ExportEventVariables( } case EVENT_PROXIMITY_SAY: { - ExportVar(package_name.c_str(), "data", objid); + ExportVar(package_name.c_str(), "data", object_id); ExportVar(package_name.c_str(), "text", data); - ExportVar(package_name.c_str(), "langid", extradata); + ExportVar(package_name.c_str(), "langid", extra_data); break; } case EVENT_SCALE_CALC: case EVENT_ITEM_ENTER_ZONE: { // need a valid EQ::ItemInstance pointer check here..unsure how to cancel this process - ExportVar(package_name.c_str(), "itemid", objid); - ExportVar(package_name.c_str(), "itemname", item_inst->GetItem()->Name); + ExportVar(package_name.c_str(), "itemid", object_id); + ExportVar(package_name.c_str(), "itemname", inst->GetItem()->Name); break; } case EVENT_ITEM_CLICK_CAST: case EVENT_ITEM_CLICK: { // need a valid EQ::ItemInstance pointer check here..unsure how to cancel this process - ExportVar(package_name.c_str(), "itemid", objid); - ExportVar(package_name.c_str(), "itemname", item_inst->GetItem()->Name); - ExportVar(package_name.c_str(), "slotid", extradata); - ExportVar(package_name.c_str(), "spell_id", item_inst->GetItem()->Click.Effect); + ExportVar(package_name.c_str(), "itemid", object_id); + ExportVar(package_name.c_str(), "itemname", inst->GetItem()->Name); + ExportVar(package_name.c_str(), "slotid", extra_data); + ExportVar(package_name.c_str(), "spell_id", inst->GetItem()->Click.Effect); - if (IsValidSpell(item_inst->GetItem()->Click.Effect)) { - ExportVar(package_name.c_str(), "spell", "Spell", (void*)&spells[item_inst->GetItem()->Click.Effect]); + if (IsValidSpell(inst->GetItem()->Click.Effect)) { + ExportVar(package_name.c_str(), "spell", "Spell", (void*) &spells[inst->GetItem()->Click.Effect]); } break; @@ -1767,15 +1861,20 @@ void PerlembParser::ExportEventVariables( ExportVar(package_name.c_str(), "slot_id", data); if (extra_pointers && extra_pointers->size() == 1) { - auto* item = std::any_cast(extra_pointers->at(0)); - if (item) { - ExportVar(package_name.c_str(), "item_id", item->GetID()); - ExportVar(package_name.c_str(), "item_name", item->GetItem()->Name); - ExportVar(package_name.c_str(), "spell_id", item->GetItem()->Click.Effect); - ExportVar(package_name.c_str(), "item", "QuestItem", item); + auto* inst = std::any_cast(extra_pointers->at(0)); + if (inst) { + ExportVar(package_name.c_str(), "item_id", inst->GetID()); + ExportVar(package_name.c_str(), "item_name", inst->GetItem()->Name); + ExportVar(package_name.c_str(), "spell_id", inst->GetItem()->Click.Effect); + ExportVar(package_name.c_str(), "item", "QuestItem", inst); - if (IsValidSpell(item->GetItem()->Click.Effect)) { - ExportVar(package_name.c_str(), "spell", "Spell", (void*)&spells[item->GetItem()->Click.Effect]); + if (IsValidSpell(inst->GetItem()->Click.Effect)) { + ExportVar( + package_name.c_str(), + "spell", + "Spell", + (void*) &spells[inst->GetItem()->Click.Effect] + ); } } } @@ -1805,14 +1904,14 @@ void PerlembParser::ExportEventVariables( case EVENT_SPELL_EFFECT_NPC: case EVENT_SPELL_FADE: { Seperator sep(data); - ExportVar(package_name.c_str(), "spell_id", objid); + ExportVar(package_name.c_str(), "spell_id", object_id); ExportVar(package_name.c_str(), "caster_id", sep.arg[0]); ExportVar(package_name.c_str(), "tics_remaining", sep.arg[1]); ExportVar(package_name.c_str(), "caster_level", sep.arg[2]); ExportVar(package_name.c_str(), "buff_slot", sep.arg[3]); - if (IsValidSpell(objid)) { - ExportVar(package_name.c_str(), "spell", "Spell", (void*)&spells[objid]); + if (IsValidSpell(object_id)) { + ExportVar(package_name.c_str(), "spell", "Spell", (void*) &spells[object_id]); } break; @@ -1821,26 +1920,36 @@ void PerlembParser::ExportEventVariables( //tradeskill events case EVENT_COMBINE_SUCCESS: case EVENT_COMBINE_FAILURE: { - ExportVar(package_name.c_str(), "recipe_id", extradata); + ExportVar(package_name.c_str(), "recipe_id", extra_data); ExportVar(package_name.c_str(), "recipe_name", data); break; } case EVENT_FORAGE_SUCCESS: { - ExportVar(package_name.c_str(), "foraged_item", extradata); + ExportVar(package_name.c_str(), "foraged_item", extra_data); if (extra_pointers && extra_pointers->size() == 1) { - ExportVar(package_name.c_str(), "item", "QuestItem", std::any_cast(extra_pointers->at(0))); + ExportVar( + package_name.c_str(), + "item", + "QuestItem", + std::any_cast(extra_pointers->at(0)) + ); } break; } case EVENT_FISH_SUCCESS: { - ExportVar(package_name.c_str(), "fished_item", extradata); + ExportVar(package_name.c_str(), "fished_item", extra_data); if (extra_pointers && extra_pointers->size() == 1) { - ExportVar(package_name.c_str(), "item", "QuestItem", std::any_cast(extra_pointers->at(0))); + ExportVar( + package_name.c_str(), + "item", + "QuestItem", + std::any_cast(extra_pointers->at(0)) + ); } break; @@ -1848,7 +1957,7 @@ void PerlembParser::ExportEventVariables( case EVENT_CLICK_OBJECT: { ExportVar(package_name.c_str(), "objectid", data); - ExportVar(package_name.c_str(), "clicker_id", extradata); + ExportVar(package_name.c_str(), "clicker_id", extra_data); if (extra_pointers && extra_pointers->size() == 1) { ExportVar(package_name.c_str(), "object", "Object", std::any_cast(extra_pointers->at(0))); @@ -1858,10 +1967,15 @@ void PerlembParser::ExportEventVariables( } case EVENT_DISCOVER_ITEM: { - ExportVar(package_name.c_str(), "itemid", extradata); + ExportVar(package_name.c_str(), "itemid", extra_data); if (extra_pointers && extra_pointers->size() == 1) { - ExportVar(package_name.c_str(), "item", "QuestItem", std::any_cast(extra_pointers->at(0))); + ExportVar( + package_name.c_str(), + "item", + "QuestItem", + std::any_cast(extra_pointers->at(0)) + ); } break; @@ -1871,15 +1985,15 @@ void PerlembParser::ExportEventVariables( Seperator sep(data); ExportVar(package_name.c_str(), "command", (sep.arg[0] + 1)); ExportVar(package_name.c_str(), "args", (sep.argnum >= 1 ? (&data[strlen(sep.arg[0]) + 1]) : "0")); - ExportVar(package_name.c_str(), "data", objid); + ExportVar(package_name.c_str(), "data", object_id); ExportVar(package_name.c_str(), "text", data); - ExportVar(package_name.c_str(), "langid", extradata); + ExportVar(package_name.c_str(), "langid", extra_data); break; } case EVENT_RESPAWN: { ExportVar(package_name.c_str(), "option", data); - ExportVar(package_name.c_str(), "resurrect", extradata); + ExportVar(package_name.c_str(), "resurrect", extra_data); break; } @@ -1894,16 +2008,20 @@ void PerlembParser::ExportEventVariables( ExportVar(package_name.c_str(), "killed_entity_id", sep.arg[4]); if (extra_pointers && extra_pointers->size() >= 1) { - Corpse *corpse = std::any_cast(extra_pointers->at(0)); + Corpse* corpse = std::any_cast(extra_pointers->at(0)); if (corpse) { ExportVar(package_name.c_str(), "killed_corpse_id", corpse->GetID()); } } if (extra_pointers && extra_pointers->size() >= 2) { - NPC *killed = std::any_cast(extra_pointers->at(1)); + NPC* killed = std::any_cast(extra_pointers->at(1)); if (killed) { - ExportVar(package_name.c_str(), "killed_bot_id", killed->IsBot() ? killed->CastToBot()->GetBotID() : 0); + ExportVar( + package_name.c_str(), + "killed_bot_id", + killed->IsBot() ? killed->CastToBot()->GetBotID() : 0 + ); ExportVar(package_name.c_str(), "killed_npc_id", killed->IsNPC() ? killed->GetNPCTypeID() : 0); ExportVar(package_name.c_str(), "killed_x", killed->GetX()); ExportVar(package_name.c_str(), "killed_y", killed->GetY()); @@ -1915,22 +2033,22 @@ void PerlembParser::ExportEventVariables( } case EVENT_DROP_ITEM: { - ExportVar(package_name.c_str(), "quantity", item_inst->IsStackable() ? item_inst->GetCharges() : 1); - ExportVar(package_name.c_str(), "itemname", item_inst->GetItem()->Name); - ExportVar(package_name.c_str(), "itemid", item_inst->GetItem()->ID); - ExportVar(package_name.c_str(), "spell_id", item_inst->GetItem()->Click.Effect); - ExportVar(package_name.c_str(), "slotid", extradata); + ExportVar(package_name.c_str(), "quantity", inst->IsStackable() ? inst->GetCharges() : 1); + ExportVar(package_name.c_str(), "itemname", inst->GetItem()->Name); + ExportVar(package_name.c_str(), "itemid", inst->GetItem()->ID); + ExportVar(package_name.c_str(), "spell_id", inst->GetItem()->Click.Effect); + ExportVar(package_name.c_str(), "slotid", extra_data); break; } case EVENT_DROP_ITEM_CLIENT: { if (extra_pointers && extra_pointers->size() == 1) { - EQ::ItemInstance* item_instance = std::any_cast(extra_pointers->at(0)); + auto item_instance = std::any_cast(extra_pointers->at(0)); ExportVar(package_name.c_str(), "quantity", item_instance->IsStackable() ? item_instance->GetCharges() : 1); ExportVar(package_name.c_str(), "item_name", item_instance->GetItem()->Name); ExportVar(package_name.c_str(), "item_id", item_instance->GetItem()->ID); ExportVar(package_name.c_str(), "spell_id", item_instance->GetItem()->Click.Effect); - ExportVar(package_name.c_str(), "slot_id", extradata); + ExportVar(package_name.c_str(), "slot_id", extra_data); ExportVar(package_name.c_str(), "item", "QuestItem", item_instance); } @@ -1954,7 +2072,7 @@ void PerlembParser::ExportEventVariables( case EVENT_COMBINE_VALIDATE: { Seperator sep(data); - ExportVar(package_name.c_str(), "recipe_id", extradata); + ExportVar(package_name.c_str(), "recipe_id", extra_data); ExportVar(package_name.c_str(), "validate_type", sep.arg[0]); std::string zone_id = "-1"; @@ -1974,9 +2092,9 @@ void PerlembParser::ExportEventVariables( Seperator sep(data); ExportVar(package_name.c_str(), "bot_command", (sep.arg[0] + 1)); ExportVar(package_name.c_str(), "args", (sep.argnum >= 1 ? (&data[strlen(sep.arg[0]) + 1]) : "0")); - ExportVar(package_name.c_str(), "data", objid); + ExportVar(package_name.c_str(), "data", object_id); ExportVar(package_name.c_str(), "text", data); - ExportVar(package_name.c_str(), "langid", extradata); + ExportVar(package_name.c_str(), "langid", extra_data); break; } @@ -2016,7 +2134,7 @@ void PerlembParser::ExportEventVariables( case EVENT_EQUIP_ITEM_CLIENT: case EVENT_UNEQUIP_ITEM_CLIENT: { Seperator sep(data); - ExportVar(package_name.c_str(), "item_id", extradata); + ExportVar(package_name.c_str(), "item_id", extra_data); ExportVar(package_name.c_str(), "item_quantity", sep.arg[0]); ExportVar(package_name.c_str(), "slot_id", sep.arg[1]); @@ -2030,7 +2148,7 @@ void PerlembParser::ExportEventVariables( case EVENT_EQUIP_ITEM_BOT: case EVENT_UNEQUIP_ITEM_BOT: { Seperator sep(data); - ExportVar(package_name.c_str(), "item_id", extradata); + ExportVar(package_name.c_str(), "item_id", extra_data); ExportVar(package_name.c_str(), "item_quantity", sep.arg[0]); ExportVar(package_name.c_str(), "slot_id", sep.arg[1]); @@ -2142,7 +2260,7 @@ void PerlembParser::ExportEventVariables( } case EVENT_INSPECT: { - ExportVar(package_name.c_str(), "target_id", extradata); + ExportVar(package_name.c_str(), "target_id", extra_data); if (extra_pointers && extra_pointers->size() == 1) { ExportVar(package_name.c_str(), "target", "Mob", std::any_cast(extra_pointers->at(0))); @@ -2177,9 +2295,9 @@ void PerlembParser::ExportEventVariables( } case EVENT_DESPAWN: { - ExportVar(package_name.c_str(), "despawned_entity_id", npcmob->GetID()); - ExportVar(package_name.c_str(), "despawned_bot_id", npcmob->IsBot() ? npcmob->CastToBot()->GetBotID() : 0); - ExportVar(package_name.c_str(), "despawned_npc_id", npcmob->IsNPC() ? npcmob->GetNPCTypeID() : 0); + ExportVar(package_name.c_str(), "despawned_entity_id", npc_mob->GetID()); + ExportVar(package_name.c_str(), "despawned_bot_id", npc_mob->IsBot() ? npc_mob->CastToBot()->GetBotID() : 0); + ExportVar(package_name.c_str(), "despawned_npc_id", npc_mob->IsNPC() ? npc_mob->GetNPCTypeID() : 0); break; } @@ -2201,7 +2319,7 @@ void PerlembParser::ExportEventVariables( } case EVENT_DAMAGE_GIVEN: - case EVENT_DAMAGE_TAKEN:{ + case EVENT_DAMAGE_TAKEN: { Seperator sep(data); ExportVar(package_name.c_str(), "entity_id", sep.arg[0]); ExportVar(package_name.c_str(), "damage", sep.arg[1]); @@ -2214,7 +2332,7 @@ void PerlembParser::ExportEventVariables( ExportVar(package_name.c_str(), "special_attack", sep.arg[8]); if (IsValidSpell(Strings::ToUnsignedInt(sep.arg[2]))) { - ExportVar(package_name.c_str(), "spell", "Spell", (void*)&spells[Strings::ToUnsignedInt(sep.arg[2])]); + ExportVar(package_name.c_str(), "spell", "Spell", (void*) &spells[Strings::ToUnsignedInt(sep.arg[2])]); } break; @@ -2222,7 +2340,7 @@ void PerlembParser::ExportEventVariables( case EVENT_DESTROY_ITEM_CLIENT: { if (extra_pointers && extra_pointers->size() == 1) { - EQ::ItemInstance* inst = std::any_cast(extra_pointers->at(0)); + auto inst = std::any_cast(extra_pointers->at(0)); ExportVar(package_name.c_str(), "item_id", inst->GetID()); ExportVar(package_name.c_str(), "item_name", inst->GetItem()->Name); ExportVar(package_name.c_str(), "quantity", inst->IsStackable() ? inst->GetCharges() : 1); @@ -2241,7 +2359,7 @@ void PerlembParser::ExportEventVariables( ExportVar(package_name.c_str(), "spell_id", sep.arg[1]); if (IsValidSpell(Strings::ToUnsignedInt(sep.arg[1]))) { - ExportVar(package_name.c_str(), "spell", "Spell", (void*)&spells[Strings::ToUnsignedInt(sep.arg[1])]); + ExportVar(package_name.c_str(), "spell", "Spell", (void*) &spells[Strings::ToUnsignedInt(sep.arg[1])]); } break; @@ -2249,7 +2367,7 @@ void PerlembParser::ExportEventVariables( case EVENT_LOOT_ADDED: { if (extra_pointers && extra_pointers->size() == 1) { - auto *inst = std::any_cast(extra_pointers->at(0)); + auto inst = std::any_cast(extra_pointers->at(0)); if (inst) { ExportVar(package_name.c_str(), "item", "QuestItem", inst); ExportVar(package_name.c_str(), "item_id", inst->GetID()); @@ -2299,11 +2417,7 @@ void PerlembParser::ExportEventVariables( void PerlembParser::LoadBotScript(std::string filename) { - if (!perl) { - return; - } - - if (bot_quest_status_ != questUnloaded) { + if (!perl || bot_quest_status_ != questUnloaded) { return; } @@ -2327,11 +2441,7 @@ void PerlembParser::LoadBotScript(std::string filename) void PerlembParser::LoadGlobalBotScript(std::string filename) { - if (!perl) { - return; - } - - if (global_bot_quest_status_ != questUnloaded) { + if (!perl || global_bot_quest_status_ != questUnloaded) { return; } @@ -2353,64 +2463,76 @@ void PerlembParser::LoadGlobalBotScript(std::string filename) global_bot_quest_status_ = questLoaded; } -bool PerlembParser::BotHasQuestSub(QuestEventID evt) +bool PerlembParser::BotHasQuestSub(QuestEventID event_id) { - if (!perl) { + if ( + !perl || + bot_quest_status_ != questLoaded || + event_id >= _LargestEventID + ) { return false; } - if (bot_quest_status_ != questLoaded) { - return false; - } - - if (evt >= _LargestEventID) { - return false; - } - - const char *subname = QuestEventSubroutines[evt]; - - return (perl->SubExists("qst_bot", subname)); + return perl->SubExists("qst_bot", QuestEventSubroutines[event_id]); } -bool PerlembParser::GlobalBotHasQuestSub(QuestEventID evt) +bool PerlembParser::GlobalBotHasQuestSub(QuestEventID event_id) { - if (!perl) { + if ( + !perl || + global_bot_quest_status_ != questLoaded || + event_id >= _LargestEventID + ) { return false; } - if (global_bot_quest_status_ != questLoaded) { - return false; - } - - if (evt >= _LargestEventID) { - return false; - } - - const char *subname = QuestEventSubroutines[evt]; - - return (perl->SubExists("qst_global_bot", subname)); + return (perl->SubExists("qst_global_bot", QuestEventSubroutines[event_id])); } int PerlembParser::EventBot( - QuestEventID evt, - Bot *bot, - Mob *mob, + QuestEventID event_id, + Bot* bot, + Mob* mob, std::string data, uint32 extra_data, - std::vector *extra_pointers -) { - return EventCommon(evt, 0, data.c_str(), bot, nullptr, nullptr, mob, extra_data, false, extra_pointers); + std::vector* extra_pointers +) +{ + return EventCommon( + event_id, + 0, + data.c_str(), + bot, + nullptr, + nullptr, + mob, + extra_data, + false, + extra_pointers + ); } int PerlembParser::EventGlobalBot( - QuestEventID evt, - Bot *bot, - Mob *mob, + QuestEventID event_id, + Bot* bot, + Mob* mob, std::string data, uint32 extra_data, - std::vector *extra_pointers -) { - return EventCommon(evt, 0, data.c_str(), bot, nullptr, nullptr, mob, extra_data, true, extra_pointers); + std::vector* extra_pointers +) +{ + return EventCommon( + event_id, + 0, + data.c_str(), + bot, + nullptr, + nullptr, + mob, + extra_data, + true, + extra_pointers + ); } #endif diff --git a/zone/embparser.h b/zone/embparser.h index 6377e194a..208b60ca7 100644 --- a/zone/embparser.h +++ b/zone/embparser.h @@ -31,13 +31,11 @@ class Mob; class Client; class NPC; -namespace EQ -{ +namespace EQ { class ItemInstance; } -typedef enum -{ +typedef enum { questUnloaded, questLoaded, questFailedToLoad @@ -49,84 +47,91 @@ public: ~PerlembParser(); virtual int EventNPC( - QuestEventID evt, + QuestEventID event_id, NPC* npc, - Mob *init, + Mob* init, std::string data, uint32 extra_data, - std::vector *extra_pointers + std::vector* extra_pointers ); + virtual int EventGlobalNPC( - QuestEventID evt, + QuestEventID event_id, NPC* npc, - Mob *init, + Mob* init, std::string data, uint32 extra_data, - std::vector *extra_pointers + std::vector* extra_pointers ); + virtual int EventPlayer( - QuestEventID evt, - Client *client, + QuestEventID event_id, + Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers + std::vector* extra_pointers ); + virtual int EventGlobalPlayer( - QuestEventID evt, - Client *client, + QuestEventID event_id, + Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers + std::vector* extra_pointers ); + virtual int EventItem( - QuestEventID evt, - Client *client, - EQ::ItemInstance *item, - Mob *mob, + QuestEventID event_id, + Client* client, + EQ::ItemInstance* item, + Mob* mob, std::string data, uint32 extra_data, - std::vector *extra_pointers + std::vector* extra_pointers ); + virtual int EventSpell( - QuestEventID evt, + QuestEventID event_id, Mob* mob, - Client *client, + Client* client, uint32 spell_id, std::string data, uint32 extra_data, - std::vector *extra_pointers - ); - virtual int EventBot( - QuestEventID evt, - Bot *bot, - Mob *init, - std::string data, - uint32 extra_data, - std::vector *extra_pointers - ); - virtual int EventGlobalBot( - QuestEventID evt, - Bot *bot, - Mob *init, - std::string data, - uint32 extra_data, - std::vector *extra_pointers + std::vector* extra_pointers ); - virtual bool HasQuestSub(uint32 npcid, QuestEventID evt); - virtual bool HasGlobalQuestSub(QuestEventID evt); - virtual bool PlayerHasQuestSub(QuestEventID evt); - virtual bool GlobalPlayerHasQuestSub(QuestEventID evt); - virtual bool SpellHasQuestSub(uint32 spell_id, QuestEventID evt); - virtual bool ItemHasQuestSub(EQ::ItemInstance *itm, QuestEventID evt); - virtual bool BotHasQuestSub(QuestEventID evt); - virtual bool GlobalBotHasQuestSub(QuestEventID evt); + virtual int EventBot( + QuestEventID event_id, + Bot* bot, + Mob* init, + std::string data, + uint32 extra_data, + std::vector* extra_pointers + ); + + virtual int EventGlobalBot( + QuestEventID event_id, + Bot* bot, + Mob* init, + std::string data, + uint32 extra_data, + std::vector* extra_pointers + ); + + virtual bool HasQuestSub(uint32 npc_id, QuestEventID event_id); + virtual bool HasGlobalQuestSub(QuestEventID event_id); + virtual bool PlayerHasQuestSub(QuestEventID event_id); + virtual bool GlobalPlayerHasQuestSub(QuestEventID event_id); + virtual bool SpellHasQuestSub(uint32 spell_id, QuestEventID event_id); + virtual bool ItemHasQuestSub(EQ::ItemInstance* inst, QuestEventID event_id); + virtual bool BotHasQuestSub(QuestEventID event_id); + virtual bool GlobalBotHasQuestSub(QuestEventID event_id); virtual void LoadNPCScript(std::string filename, int npc_id); virtual void LoadGlobalNPCScript(std::string filename); virtual void LoadPlayerScript(std::string filename); virtual void LoadGlobalPlayerScript(std::string filename); - virtual void LoadItemScript(std::string filename, EQ::ItemInstance *item); + virtual void LoadItemScript(std::string filename, EQ::ItemInstance* inst); virtual void LoadSpellScript(std::string filename, uint32 spell_id); virtual void LoadBotScript(std::string filename); virtual void LoadGlobalBotScript(std::string filename); @@ -137,120 +142,131 @@ public: virtual uint32 GetIdentifier() { return 0xf8b05c11; } private: - Embperl *perl; + Embperl* perl; - void ExportHash(const char *pkgprefix, const char *hashname, std::map &vals); - void ExportVar(const char *pkgprefix, const char *varname, const char *value); - void ExportVar(const char *pkgprefix, const char *varname, int32 value); - void ExportVar(const char *pkgprefix, const char *varname, uint32 value); - void ExportVar(const char *pkgprefix, const char *varname, float value); - void ExportVar(const char* pkgprefix, const char* varname, const char* classname, void* value); + void ExportHash(const char* prefix, const char* hash_name, std::map& vals); + void ExportVar(const char* prefix, const char* variable_name, const char* value); + void ExportVar(const char* prefix, const char* variable_name, int32 value); + void ExportVar(const char* prefix, const char* variable_name, uint32 value); + void ExportVar(const char* prefix, const char* variable_name, float value); + void ExportVar(const char* prefix, const char* variable_name, const char* class_name, void* value); int EventCommon( QuestEventID event, - uint32 objid, + uint32 object_id, const char* data, - Mob* npcmob, - EQ::ItemInstance* item_inst, + Mob* npc_mob, + EQ::ItemInstance* inst, const SPDat_Spell_Struct* spell, Mob* mob, - uint32 extradata, - bool global, - std::vector *extra_pointers + uint32 extra_data, + bool is_global, + std::vector* extra_pointers ); + int SendCommands( - const char *pkgprefix, - const char *event, + const char* prefix, + const char* event, uint32 spell_id, Mob* other, Mob* mob, - EQ::ItemInstance *item_inst, - const SPDat_Spell_Struct *spell + EQ::ItemInstance* inst, + const SPDat_Spell_Struct* spell ); + void MapFunctions(); void GetQuestTypes( - bool &isPlayerQuest, - bool &isGlobalPlayerQuest, - bool &isBotQuest, - bool &isGlobalBotQuest, - bool &isGlobalNPC, - bool &isItemQuest, - bool &isSpellQuest, + bool& is_player_quest, + bool& is_global_player_quest, + bool& is_bot_quest, + bool& is_global_bot_quest, + bool& is_global_npc_quest, + bool& is_item_quest, + bool& is_spell_quest, QuestEventID event, - Mob* npcmob, - EQ::ItemInstance* item_inst, + Mob* npc_mob, + EQ::ItemInstance* inst, Mob* mob, - bool global + bool is_global ); + void GetQuestPackageName( - bool &isPlayerQuest, - bool &isGlobalPlayerQuest, - bool &isBotQuest, - bool &isGlobalBotQuest, - bool &isGlobalNPC, - bool &isItemQuest, - bool &isSpellQuest, - std::string &package_name, + bool& is_player_quest, + bool& is_global_player_quest, + bool& is_bot_quest, + bool& is_global_bot_quest, + bool& is_global_npc_quest, + bool& is_item_quest, + bool& is_spell_quest, + std::string& package_name, QuestEventID event, - uint32 objid, - const char * data, - Mob* npcmob, - EQ::ItemInstance* item_inst, - bool global + uint32 object_id, + const char* data, + Mob* npc_mob, + EQ::ItemInstance* inst, + bool is_global ); - void ExportCharID(const std::string &package_name, int &char_id, Mob *npcmob, Mob *mob); + + void ExportCharID(const std::string& package_name, int& char_id, Mob* npc_mob, Mob* mob); + void ExportQGlobals( - bool isPlayerQuest, - bool isGlobalPlayerQuest, - bool isBotQuest, - bool isGlobalBotQuest, - bool isGlobalNPC, - bool isItemQuest, - bool isSpellQuest, - std::string &package_name, - Mob *npcmob, - Mob *mob, + bool is_player_quest, + bool is_global_player_quest, + bool is_bot_quest, + bool is_global_bot_quest, + bool is_global_npc_quest, + bool is_item_quest, + bool is_spell_quest, + std::string& package_name, + Mob* npc_mob, + Mob* mob, int char_id ); + void ExportMobVariables( - bool isPlayerQuest, - bool isGlobalPlayerQuest, - bool isBotQuest, - bool isGlobalBotQuest, - bool isGlobalNPC, - bool isItemQuest, - bool isSpellQuest, - std::string &package_name, - Mob *mob, - Mob *npcmob - ); - void ExportZoneVariables(std::string &package_name); - void ExportItemVariables(std::string &package_name, Mob *mob); - void ExportEventVariables( - std::string &package_name, - QuestEventID event, - uint32 objid, - const char* data, - Mob* npcmob, - EQ::ItemInstance* item_inst, + bool is_player_quest, + bool is_global_player_quest, + bool is_bot_quest, + bool is_global_bot_quest, + bool is_global_npc_quest, + bool is_item_quest, + bool is_spell_quest, + std::string& package_name, Mob* mob, - uint32 extradata, - std::vector *extra_pointers + Mob* npc_mob + ); + + void ExportZoneVariables(std::string& package_name); + + void ExportItemVariables(std::string& package_name, Mob* mob); + + void ExportEventVariables( + std::string& package_name, + QuestEventID event, + uint32 object_id, + const char* data, + Mob* npc_mob, + EQ::ItemInstance* inst, + Mob* mob, + uint32 extra_data, + std::vector* extra_pointers ); std::map npc_quest_status_; + std::map item_quest_status_; + std::map spell_quest_status_; + PerlQuestStatus global_npc_quest_status_; PerlQuestStatus player_quest_status_; PerlQuestStatus global_player_quest_status_; - std::map item_quest_status_; - std::map spell_quest_status_; PerlQuestStatus bot_quest_status_; PerlQuestStatus global_bot_quest_status_; + SV* _empty_sv; + std::map vars_; - SV *_empty_sv; - std::map clear_vars_; + std::map clear_vars_; }; #endif diff --git a/zone/embperl.cpp b/zone/embperl.cpp index 4bc5ea8ac..21a82f111 100644 --- a/zone/embperl.cpp +++ b/zone/embperl.cpp @@ -27,16 +27,18 @@ Eglin XS(XS_EQEmuIO_PRINT); #endif //EMBPERL_IO_CAPTURE -const char *argv_eqemu[] = { "", +const char* argv_eqemu[] = { + "", #ifdef EMBPERL_IO_CAPTURE - "-w", "-W", + "-w", "-W", #endif - "-e", "0;", nullptr }; + "-e", "0;", nullptr +}; #ifdef EMBPERL_IO_CAPTURE - int argc = 5; +int argc = 5; #else - int argc = 3; +int argc = 3; #endif //so embedded scripts can use xs extensions (ala 'use socket;') EXTERN_C void boot_DynaLoader(pTHX_ CV* cv); @@ -46,7 +48,7 @@ EXTERN_C void xs_init(pTHX) strncpy(file, __FILE__, 256); file[255] = '\0'; - char buf[128]; //shouldent have any function names longer than this. + char buf[128]; //shouldent have any function names longer than this. //add the strcpy stuff to get rid of const warnings.... @@ -58,20 +60,20 @@ EXTERN_C void xs_init(pTHX) Embperl::Embperl() { - char **argv = (char **)argv_eqemu; - char **env = { nullptr }; - in_use = true; //in case one of these files generates an event + char** argv = (char**) argv_eqemu; + char** env = { nullptr }; PERL_SYS_INIT3(&argc, &argv, &env); DoInit(); } -void Embperl::DoInit() { - char **argv = (char **)argv_eqemu; - char **env = { nullptr }; +void Embperl::DoInit() +{ + char** argv = (char**) argv_eqemu; my_perl = perl_alloc(); //setup perl... - if(!my_perl) + if (!my_perl) { throw "Failed to init Perl (perl_alloc)"; + } PERL_SET_CONTEXT(my_perl); PERL_SET_INTERP(my_perl); PL_perl_destruct_level = 1; @@ -80,17 +82,17 @@ void Embperl::DoInit() { perl_run(my_perl); //a little routine we use a lot. - eval_pv("sub my_eval { eval $_[0];}", TRUE); //dies on error + eval_pv("sub my_eval { eval $_[0];}", TRUE); //dies on error //ruin the perl exit and command: - eval_pv("sub my_exit {}",TRUE); - eval_pv("sub my_sleep {}",TRUE); - if(gv_stashpv("CORE::GLOBAL", FALSE)) { - GV *exitgp = gv_fetchpv("CORE::GLOBAL::exit", TRUE, SVt_PVCV); - GvCV_set(exitgp, perl_get_cv("my_exit", TRUE)); //dies on error + eval_pv("sub my_exit {}", TRUE); + eval_pv("sub my_sleep {}", TRUE); + if (gv_stashpv("CORE::GLOBAL", FALSE)) { + GV* exitgp = gv_fetchpv("CORE::GLOBAL::exit", TRUE, SVt_PVCV); + GvCV_set(exitgp, perl_get_cv("my_exit", TRUE)); //dies on error GvIMPORTED_CV_on(exitgp); - GV *sleepgp = gv_fetchpv("CORE::GLOBAL::sleep", TRUE, SVt_PVCV); - GvCV_set(sleepgp, perl_get_cv("my_sleep", TRUE)); //dies on error + GV* sleepgp = gv_fetchpv("CORE::GLOBAL::sleep", TRUE, SVt_PVCV); + GvCV_set(sleepgp, perl_get_cv("my_sleep", TRUE)); //dies on error GvIMPORTED_CV_on(sleepgp); } @@ -98,8 +100,7 @@ void Embperl::DoInit() { try { init_eval_file(); } - catch(std::string& e) - { + catch (std::string& e) { //remember... lasterr() is no good if we crap out here, in construction LogQuests("Perl Error [{}]", e); throw "failed to install eval_file hook"; @@ -110,69 +111,62 @@ void Embperl::DoInit() { //make a tieable class to capture IO and pass it into EQEMuLog eval_pv( "package EQEmuIO; " - "sub TIEHANDLE { my $me = bless {}, $_[0]; $me->PRINT('Creating '. $me); return($me); } " - "sub WRITE { } " - //dunno why I need to shift off fmt here, but it dosent like without it - "sub PRINTF { my $me = shift; my $fmt = shift; $me->PRINT(sprintf($fmt, @_)); } " - "sub CLOSE { my $me = shift; $me->PRINT('Closing '.$me); } " - "sub DESTROY { my $me = shift; $me->PRINT('Destroying '.$me); } " - //this ties us for all packages, just do it in quest since thats kinda 'our' package - "package quest;" - " if(tied *STDOUT) { untie(*STDOUT); }" - " if(tied *STDERR) { untie(*STDERR); }" - " tie *STDOUT, 'EQEmuIO';" - " tie *STDERR, 'EQEmuIO';" - ,FALSE); + "sub TIEHANDLE { my $me = bless {}, $_[0]; $me->PRINT('Creating '. $me); return($me); } " + "sub WRITE { } " + "sub PRINTF { my $me = shift; my $fmt = shift; $me->PRINT(sprintf($fmt, @_)); } " + "sub CLOSE { my $me = shift; $me->PRINT('Closing '.$me); } " + "sub DESTROY { my $me = shift; $me->PRINT('Destroying '.$me); } " + "package quest;" + " if(tied *STDOUT) { untie(*STDOUT); }" + " if(tied *STDERR) { untie(*STDERR); }" + " tie *STDOUT, 'EQEmuIO';" + " tie *STDERR, 'EQEmuIO';", FALSE); #endif //EMBPERL_IO_CAPTURE #ifdef EMBPERL_PLUGIN eval_pv( - "package plugin; " - ,FALSE + "package plugin; ", FALSE ); LogQuests("Loading perlemb plugins"); - try - { + try { std::string perl_command; perl_command = "main::eval_file('plugin', '" + Config->PluginPlFile + "');"; eval_pv(perl_command.c_str(), FALSE); } - catch(std::string& e) - { + catch (std::string& e) { LogQuests("Warning [{}]: [{}]", Config->PluginPlFile, e); } - try - { + try { //should probably read the directory in c, instead, so that //I can echo filenames as I do it, but c'mon... I'm lazy and this 1 line reads in all the plugins - std::string perl_command = - "if(opendir(D,'" + path.GetPluginsPath() +"')) { " + const std::string& perl_command = ( + "if(opendir(D,'" + + path.GetPluginsPath() + + "')) { " " my @d = readdir(D);" " closedir(D);" " foreach(@d){ " - " main::eval_file('plugin','" + path.GetPluginsPath() + "/'.$_)if/\\.pl$/;" + " main::eval_file('plugin','" + + path.GetPluginsPath() + + "/'.$_)if/\\.pl$/;" " }" - "}"; - eval_pv(perl_command.c_str(),FALSE); + "}"); + eval_pv(perl_command.c_str(), FALSE); } - catch(std::string& e) - { + catch (std::string& e) { LogQuests("Warning [{}]", e); } #endif //EMBPERL_PLUGIN - in_use = false; } Embperl::~Embperl() { - in_use = true; #ifdef EMBPERL_IO_CAPTURE eval_pv( "package quest;" " if(tied *STDOUT) { untie(*STDOUT); }" - " if(tied *STDERR) { untie(*STDERR); }" - ,FALSE); + " if(tied *STDERR) { untie(*STDERR); }", FALSE); #endif PL_perl_destruct_level = 1; perl_destruct(my_perl); @@ -181,17 +175,15 @@ Embperl::~Embperl() my_perl = NULL; } -void Embperl::Reinit() { - in_use = true; +void Embperl::Reinit() +{ PERL_SET_CONTEXT(my_perl); PERL_SET_INTERP(my_perl); PL_perl_destruct_level = 1; perl_destruct(my_perl); perl_free(my_perl); my_perl = NULL; - //Now reinit... DoInit(); - in_use = false; } void Embperl::init_eval_file(void) @@ -201,38 +193,30 @@ void Embperl::init_eval_file(void) "no warnings 'all';" "use Symbol qw(delete_package);" "sub eval_file {" - "my($package, $filename) = @_;" - "$filename=~s/\'//g;" - "if(! -r $filename) { print \"Unable to read perl file '$filename'\\n\"; return; }" - "my $mtime = -M $filename;" - "if(defined $Cache{$package}{mtime}&&$Cache{$package}{mtime} <= $mtime && !($package eq 'plugin')){" - " return;" - "} else {" - // we 'my' $filename,$mtime,$package,$sub to prevent them from changing our state up here. - " eval(\"package $package; my(\\$filename,\\$mtime,\\$package,\\$sub); \\$isloaded = 1; require './$filename'; \");" - " print $@ if $@;" -/* "local *FH;open FH, $filename or die \"open '$filename' $!\";" - "local($/) = undef;my $sub = ;close FH;" - "my $eval = qq{package $package; sub handler { $sub; }};" - "{ my($filename,$mtime,$package,$sub); eval $eval; }" - "die $@ if $@;" - "$Cache{$package}{mtime} = $mtime; ${$package.'::isloaded'} = 1;}" -*/ - "}" + "my($package, $filename) = @_;" + "$filename=~s/\'//g;" + "if(! -r $filename) { print \"Unable to read perl file '$filename'\\n\"; return; }" + "my $mtime = -M $filename;" + "if(defined $Cache{$package}{mtime}&&$Cache{$package}{mtime} <= $mtime && !($package eq 'plugin')){" + " return;" + "} else {" + // we 'my' $filename,$mtime,$package,$sub to prevent them from changing our state up here. + " eval(\"package $package; my(\\$filename,\\$mtime,\\$package,\\$sub); \\$isloaded = 1; require './$filename'; \");" + " print $@ if $@;" "}" - ,FALSE); - } + "}", FALSE); +} -int Embperl::eval_file(const char * packagename, const char * filename) +int Embperl::eval_file(const char* package_name, const char* filename) { std::vector args; - args.push_back(packagename); + args.push_back(package_name); args.push_back(filename); return dosub("main::eval_file", &args); } -int Embperl::dosub(const char * subname, const std::vector * args, int mode) +int Embperl::dosub(const char* sub_name, const std::vector* args, int mode) { dSP; int ret_value = 0; @@ -242,27 +226,29 @@ int Embperl::dosub(const char * subname, const std::vector * args, ENTER; SAVETMPS; PUSHMARK(SP); + if (args && !args->empty()) { for (auto i = args->begin(); i != args->end(); ++i) { XPUSHs(sv_2mortal(newSVpv(i->c_str(), i->length()))); } } + PUTBACK; - count = call_pv(subname, mode); + count = call_pv(sub_name, mode); SPAGAIN; if (SvTRUE(ERRSV)) { error = SvPV_nolen(ERRSV); POPs; - } - else { + } else { if (count == 1) { - SV *ret = POPs; + SV* ret = POPs; if (SvTYPE(ret) == SVt_IV) { IV v = SvIV(ret); ret_value = v; } + PUTBACK; } } @@ -273,8 +259,8 @@ int Embperl::dosub(const char * subname, const std::vector * args, // not sure why we pass this as blind args, strange // check for syntax errors if (args && !args->empty()) { - const std::string &filename = args->back(); - std::string sub = subname; + const std::string& filename = args->back(); + std::string sub = sub_name; if (sub == "main::eval_file" && !filename.empty() && File::Exists(filename)) { BenchTimer benchmark; @@ -286,8 +272,10 @@ int Embperl::dosub(const char * subname, const std::vector * args, std::string syntax_error = Process::execute( fmt::format("{} -c {} 2>&1", perl, filename) ); + LogQuests("Perl eval [{}] took [{}]", filename, benchmark.elapsed()); syntax_error = Strings::Trim(syntax_error); + if (!Strings::Contains(syntax_error, "syntax OK")) { syntax_error += SvPVX(ERRSV); throw syntax_error; @@ -305,19 +293,22 @@ int Embperl::dosub(const char * subname, const std::vector * args, } //evaluate an expression. throw error on fail -int Embperl::eval(const char * code) +int Embperl::eval(const char* code) { std::vector arg; arg.push_back(code); - return dosub("main::my_eval", &arg, G_SCALAR|G_EVAL|G_KEEPERR); + return dosub("main::my_eval", &arg, G_SCALAR | G_EVAL | G_KEEPERR); } -bool Embperl::SubExists(const char *package, const char *sub) { - HV *stash = gv_stashpv(package, false); - if(!stash) - return(false); +bool Embperl::SubExists(const char* package, const char* sub) +{ + HV* stash = gv_stashpv(package, false); + if (!stash) { + return (false); + } + int len = strlen(sub); - return(hv_exists(stash, sub, len)); + return (hv_exists(stash, sub, len)); } #ifdef EMBPERL_IO_CAPTURE @@ -331,8 +322,8 @@ XS(XS_EQEmuIO_PRINT) } for (int r = 1; r < items; r++) { - char *str = SvPV_nolen(ST(r)); - char *cur = str; + char* str = SvPV_nolen(ST(r)); + char* cur = str; /* Strip newlines from log message 'str' */ *std::remove(str, str + strlen(str), '\n') = '\0'; diff --git a/zone/embperl.h b/zone/embperl.h index 02047e32e..9fe757184 100644 --- a/zone/embperl.h +++ b/zone/embperl.h @@ -73,7 +73,6 @@ private: //install a perl func void init_eval_file(void); - bool in_use; //true if perl is executing protected: //the embedded interpreter PerlInterpreter * my_perl; @@ -87,59 +86,66 @@ public: void Reinit(); //evaluate an expression. throws string errors on fail - int eval(const char * code); + int eval(const char* code); //execute a subroutine. throws lasterr on failure - int dosub(const char * subname, const std::vector * args = nullptr, int mode = G_SCALAR|G_EVAL); + int dosub(const char* sub_name, const std::vector* args = nullptr, int mode = G_SCALAR | G_EVAL); //put an integer into a perl varable - void seti(const char *varname, int val) const { - SV *t = get_sv(varname, true); + void seti(const char* variable_name, int val) const + { + SV* t = get_sv(variable_name, true); sv_setiv(t, val); } + //put a real into a perl varable - void setd(const char *varname, float val) const { - SV *t = get_sv(varname, true); + void setd(const char* variable_name, float val) const + { + SV* t = get_sv(variable_name, true); sv_setnv(t, val); } + //put a string into a perl varable - void setstr(const char *varname, const char *val) const { - SV *t = get_sv(varname, true); + void setstr(const char* variable_name, const char* val) const + { + SV* t = get_sv(variable_name, true); sv_setpv(t, val); } + // put a pointer into a blessed perl variable - void setptr(const char* varname, const char* classname, void* val) const { - SV* t = get_sv(varname, GV_ADD); - sv_setref_pv(t, classname, val); + void setptr(const char* variable_name, const char* class_name, void* val) const + { + SV* t = get_sv(variable_name, GV_ADD); + sv_setref_pv(t, class_name, val); } // put key-value pairs in hash - void sethash(const char *varname, std::map &vals) + void sethash(const char* variable_name, std::map& vals) { - std::map::iterator it; + std::map::iterator it; // Get hash and clear it. - HV *hv = get_hv(varname, TRUE); + HV* hv = get_hv(variable_name, TRUE); hv_clear(hv); // Iterate through key-value pairs, storing them in hash - for (it = vals.begin(); it != vals.end(); ++it) - { - int keylen = static_cast(it->first.length()); + for (it = vals.begin(); it != vals.end(); ++it) { + int key_length = static_cast(it->first.length()); - SV *val = newSVpv(it->second.c_str(), it->second.length()); + SV* val = newSVpv(it->second.c_str(), it->second.length()); // If val was not added to hash, reset reference count - if (hv_store(hv, it->first.c_str(), keylen, val, 0) == nullptr) + if (!hv_store(hv, it->first.c_str(), key_length, val, 0)) { val->sv_refcnt = 0; + } } } //loads a file and compiles it into our interpreter (assuming it hasn't already been read in) //idea borrowed from perlembed - int eval_file(const char * packagename, const char * filename); + int eval_file(const char* package_name, const char* filename); //check to see if a sub exists in package - bool SubExists(const char *package, const char *sub); + bool SubExists(const char* package, const char* sub); }; #endif //EMBPERL diff --git a/zone/quest_interface.h b/zone/quest_interface.h index c614ea430..deeaa4df3 100644 --- a/zone/quest_interface.h +++ b/zone/quest_interface.h @@ -26,105 +26,262 @@ class Client; class NPC; -namespace EQ -{ +namespace EQ { class ItemInstance; } class QuestInterface { public: - virtual int EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { return 0; } - virtual int EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { return 0; } - virtual int EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { return 0; } - virtual int EventGlobalPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { return 0; } - virtual int EventItem(QuestEventID evt, Client *client, EQ::ItemInstance *item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers) { return 0; } - virtual int EventSpell(QuestEventID evt, Mob* mob, Client *client, uint32 spell_id, std::string data, uint32 extra_data, - std::vector *extra_pointers) { return 0; } - virtual int EventEncounter(QuestEventID evt, std::string encounter_name, std::string data, uint32 extra_data, - std::vector *extra_pointers) { return 0; } - virtual int EventBot( - QuestEventID evt, - Bot *bot, - Mob *init, + virtual int EventNPC( + QuestEventID event_id, + NPC* npc, + Mob* init, std::string data, uint32 extra_data, - std::vector *extra_pointer - ) { + std::vector* extra_pointers + ) + { + return 0; + } + + virtual int EventGlobalNPC( + QuestEventID event_id, + NPC* npc, + Mob* init, + std::string data, + uint32 extra_data, + std::vector* extra_pointers + ) + { + return 0; + } + + virtual int EventPlayer( + QuestEventID event_id, + Client* client, + std::string data, + uint32 extra_data, + std::vector* extra_pointers + ) + { + return 0; + } + + virtual int EventGlobalPlayer( + QuestEventID event_id, + Client* client, + std::string data, + uint32 extra_data, + std::vector* extra_pointers + ) + { + return 0; + } + + virtual int EventItem( + QuestEventID event_id, + Client* client, + EQ::ItemInstance* inst, + Mob* mob, + std::string data, + uint32 extra_data, + std::vector* extra_pointers + ) + { + return 0; + } + + virtual int EventSpell( + QuestEventID event_id, + Mob* mob, + Client* client, + uint32 spell_id, + std::string data, + uint32 extra_data, + std::vector* extra_pointers + ) + { + return 0; + } + + virtual int EventEncounter( + QuestEventID event_id, + std::string encounter_name, + std::string data, + uint32 extra_data, + std::vector* extra_pointers + ) + { + return 0; + } + + virtual int EventBot( + QuestEventID event_id, + Bot* bot, + Mob* init, + std::string data, + uint32 extra_data, + std::vector* extra_pointers + ) + { return 0; } virtual int EventGlobalBot( - QuestEventID evt, - Bot *bot, - Mob *init, + QuestEventID event_id, + Bot* bot, + Mob* init, std::string data, uint32 extra_data, - std::vector *extra_pointers - ) { + std::vector* extra_pointers + ) + { return 0; } - virtual bool HasQuestSub(uint32 npcid, QuestEventID evt) { return false; } - virtual bool HasGlobalQuestSub(QuestEventID evt) { return false; } - virtual bool PlayerHasQuestSub(QuestEventID evt) { return false; } - virtual bool GlobalPlayerHasQuestSub(QuestEventID evt) { return false; } - 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 bool BotHasQuestSub(QuestEventID evt) { return false; } - virtual bool GlobalBotHasQuestSub(QuestEventID evt) { return false; } + virtual bool HasQuestSub(uint32 npc_id, QuestEventID event_id) + { + return false; + } + + virtual bool HasGlobalQuestSub(QuestEventID event_id) + { + return false; + } + + virtual bool PlayerHasQuestSub(QuestEventID event_id) + { + return false; + } + + virtual bool GlobalPlayerHasQuestSub(QuestEventID event_id) + { + return false; + } + + virtual bool SpellHasQuestSub(uint32 spell_id, QuestEventID event_id) + { + return false; + } + + virtual bool ItemHasQuestSub(EQ::ItemInstance* itm, QuestEventID event_id) + { + return false; + } + + virtual bool EncounterHasQuestSub(std::string encounter_name, QuestEventID event_id) + { + return false; + } + + virtual bool HasEncounterSub(const std::string& package_name, QuestEventID event_id) + { + return false; + } + + virtual bool BotHasQuestSub(QuestEventID event_id) + { + return false; + } + + virtual bool GlobalBotHasQuestSub(QuestEventID event_id) + { + return false; + } virtual void LoadNPCScript(std::string filename, int npc_id) { } virtual void LoadGlobalNPCScript(std::string filename) { } virtual void LoadPlayerScript(std::string filename) { } virtual void LoadGlobalPlayerScript(std::string filename) { } - virtual void LoadItemScript(std::string filename, EQ::ItemInstance *item) { } + virtual void LoadItemScript(std::string filename, EQ::ItemInstance* inst) { } virtual void LoadSpellScript(std::string filename, uint32 spell_id) { } virtual void LoadEncounterScript(std::string filename, std::string encounter_name) { } virtual void LoadBotScript(std::string filename) { } virtual void LoadGlobalBotScript(std::string filename) { } - virtual int DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { return 0; } - virtual int DispatchEventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { return 0; } - virtual int DispatchEventItem(QuestEventID evt, Client *client, EQ::ItemInstance *item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers) { return 0; } - virtual int DispatchEventSpell(QuestEventID evt, Mob* mob, Client *client, uint32 spell_id, std::string data, uint32 extra_data, - std::vector *extra_pointers) { return 0; } - virtual int DispatchEventBot( - QuestEventID evt, - Bot *bot, - Mob *init, + virtual int DispatchEventNPC( + QuestEventID event_id, + NPC* npc, + Mob* init, std::string data, uint32 extra_data, - std::vector *extra_pointers - ) { + std::vector* extra_pointers + ) + { + return 0; + } + + virtual int DispatchEventPlayer( + QuestEventID event_id, + Client* client, + std::string data, + uint32 extra_data, + std::vector* extra_pointers + ) + { + return 0; + } + + virtual int DispatchEventItem( + QuestEventID event_id, + Client* client, + EQ::ItemInstance* inst, + Mob* mob, + std::string data, + uint32 extra_data, + std::vector* extra_pointers + ) + { + return 0; + } + + virtual int DispatchEventSpell( + QuestEventID event_id, + Mob* mob, + Client* client, + uint32 spell_id, + std::string data, + uint32 extra_data, + std::vector* extra_pointers + ) + { + return 0; + } + + virtual int DispatchEventBot( + QuestEventID event_id, + Bot* bot, + Mob* init, + std::string data, + uint32 extra_data, + std::vector* extra_pointers + ) + { return 0; } virtual void AddVar(std::string name, std::string val) { } - virtual std::string GetVar(std::string name) { return std::string(); } + virtual std::string GetVar(std::string name) + { + return std::string(); + } virtual void Init() { } virtual void ReloadQuests() { } virtual uint32 GetIdentifier() = 0; - virtual void RemoveEncounter(const std::string &name) { } + virtual void RemoveEncounter(const std::string& name) { } - virtual void GetErrors(std::list &quest_errors) { + virtual void GetErrors(std::list& quest_errors) + { quest_errors.insert(quest_errors.end(), errors_.begin(), errors_.end()); } - virtual void AddError(std::string error) { + virtual void AddError(std::string error) + { LogQuests("{}", error); LogQuestErrors("{}", Strings::Trim(error)); errors_.push_back(error); + if (errors_.size() > RuleI(World, MaximumQuestErrors)) { errors_.pop_front(); } diff --git a/zone/quest_parser_collection.cpp b/zone/quest_parser_collection.cpp index acd850d40..c14a8cf4c 100644 --- a/zone/quest_parser_collection.cpp +++ b/zone/quest_parser_collection.cpp @@ -27,453 +27,563 @@ #include "questmgr.h" #include "../common/path_manager.h" #include "../common/repositories/perl_event_export_settings_repository.h" +#include "../common/file.h" #include extern Zone* zone; extern void MapOpcodes(); -QuestParserCollection::QuestParserCollection() { - _player_quest_status = QuestUnloaded; +QuestParserCollection::QuestParserCollection() +{ + _player_quest_status = QuestUnloaded; _global_player_quest_status = QuestUnloaded; - _global_npc_quest_status = QuestUnloaded; - _bot_quest_status = QuestUnloaded; - _global_bot_quest_status = QuestUnloaded; + _global_npc_quest_status = QuestUnloaded; + _bot_quest_status = QuestUnloaded; + _global_bot_quest_status = QuestUnloaded; } -QuestParserCollection::~QuestParserCollection() { -} +QuestParserCollection::~QuestParserCollection() { } -void QuestParserCollection::RegisterQuestInterface(QuestInterface *qi, std::string ext) { +void QuestParserCollection::RegisterQuestInterface(QuestInterface* qi, std::string ext) +{ _interfaces[qi->GetIdentifier()] = qi; _extensions[qi->GetIdentifier()] = ext; _load_precedence.push_back(qi); } -void QuestParserCollection::ClearInterfaces() { +void QuestParserCollection::ClearInterfaces() +{ _interfaces.clear(); _extensions.clear(); _load_precedence.clear(); } -void QuestParserCollection::AddVar(std::string name, std::string val) { - auto iter = _load_precedence.begin(); - while(iter != _load_precedence.end()) { - (*iter)->AddVar(name, val); - ++iter; +void QuestParserCollection::AddVar(std::string name, std::string val) +{ + for (const auto& e: _load_precedence) { + e->AddVar(name, val); } } -void QuestParserCollection::Init() { - auto iter = _load_precedence.begin(); - while(iter != _load_precedence.end()) { - (*iter)->Init(); - ++iter; +void QuestParserCollection::Init() +{ + for (const auto& e: _load_precedence) { + e->Init(); } } -void QuestParserCollection::ReloadQuests(bool reset_timers) { +void QuestParserCollection::ReloadQuests(bool reset_timers) +{ if (reset_timers) { quest_manager.ClearAllTimers(); } MapOpcodes(); + _npc_quest_status.clear(); - _player_quest_status = QuestUnloaded; + + _player_quest_status = QuestUnloaded; _global_player_quest_status = QuestUnloaded; - _global_npc_quest_status = QuestUnloaded; - _bot_quest_status = QuestUnloaded; - _global_bot_quest_status = QuestUnloaded; + _global_npc_quest_status = QuestUnloaded; + _bot_quest_status = QuestUnloaded; + _global_bot_quest_status = QuestUnloaded; _spell_quest_status.clear(); _item_quest_status.clear(); _encounter_quest_status.clear(); - auto iter = _load_precedence.begin(); - while (iter != _load_precedence.end()) { - (*iter)->ReloadQuests(); - ++iter; + + for (const auto& e: _load_precedence) { + e->ReloadQuests(); } } -void QuestParserCollection::RemoveEncounter(const std::string name) { - auto iter = _load_precedence.begin(); - while(iter != _load_precedence.end()) { - (*iter)->RemoveEncounter(name); - ++iter; +void QuestParserCollection::RemoveEncounter(const std::string& name) +{ + for (const auto& e: _load_precedence) { + e->RemoveEncounter(name); } } -bool QuestParserCollection::HasQuestSub(uint32 npcid, QuestEventID evt) { - return HasQuestSubLocal(npcid, evt) || HasQuestSubGlobal(evt) || NPCHasEncounterSub(npcid, evt); +bool QuestParserCollection::HasQuestSub(uint32 npc_id, QuestEventID event_id) +{ + return ( + HasQuestSubLocal(npc_id, event_id) || + HasQuestSubGlobal(event_id) || + NPCHasEncounterSub(npc_id, event_id) + ); } -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::NPCHasEncounterSub(uint32 npc_id, QuestEventID event_id) +{ + return HasEncounterSub( + event_id, + fmt::format( + "npc_{}", + npc_id + ) + ); } -bool QuestParserCollection::HasQuestSubLocal(uint32 npcid, QuestEventID evt) { - auto iter = _npc_quest_status.find(npcid); +bool QuestParserCollection::HasQuestSubLocal(uint32 npc_id, QuestEventID event_id) +{ + auto iter = _npc_quest_status.find(npc_id); - if(iter != _npc_quest_status.end()) { - //loaded or failed to load - if(iter->second != QuestFailedToLoad) { + if (iter != _npc_quest_status.end()) { + if (iter->second != QuestFailedToLoad) { //loaded or failed to load auto qiter = _interfaces.find(iter->second); - if(qiter->second->HasQuestSub(npcid, evt)) { + if (qiter->second->HasQuestSub(npc_id, event_id)) { return true; } } } else { std::string filename; - QuestInterface *qi = GetQIByNPCQuest(npcid, filename); - if(qi) { - _npc_quest_status[npcid] = qi->GetIdentifier(); + auto qi = GetQIByNPCQuest(npc_id, filename); - qi->LoadNPCScript(filename, npcid); - if(qi->HasQuestSub(npcid, evt)) { + if (qi) { + _npc_quest_status[npc_id] = qi->GetIdentifier(); + + qi->LoadNPCScript(filename, npc_id); + if (qi->HasQuestSub(npc_id, event_id)) { return true; } } else { - _npc_quest_status[npcid] = QuestFailedToLoad; + _npc_quest_status[npc_id] = QuestFailedToLoad; } } + return false; } -bool QuestParserCollection::HasQuestSubGlobal(QuestEventID evt) { - if(_global_npc_quest_status == QuestUnloaded) { +bool QuestParserCollection::HasQuestSubGlobal(QuestEventID event_id) +{ + if (_global_npc_quest_status == QuestUnloaded) { std::string filename; - QuestInterface *qi = GetQIByGlobalNPCQuest(filename); - if(qi) { + auto qi = GetQIByGlobalNPCQuest(filename); + + if (qi) { qi->LoadGlobalNPCScript(filename); _global_npc_quest_status = qi->GetIdentifier(); - if(qi->HasGlobalQuestSub(evt)) { + if (qi->HasGlobalQuestSub(event_id)) { return true; } } } else { - if(_global_npc_quest_status != QuestFailedToLoad) { + if (_global_npc_quest_status != QuestFailedToLoad) { auto qiter = _interfaces.find(_global_npc_quest_status); - if(qiter->second->HasGlobalQuestSub(evt)) { + if (qiter->second->HasGlobalQuestSub(event_id)) { return true; } } } + return false; } -bool QuestParserCollection::PlayerHasQuestSub(QuestEventID evt) { - return PlayerHasQuestSubLocal(evt) || PlayerHasQuestSubGlobal(evt) || PlayerHasEncounterSub(evt); +bool QuestParserCollection::PlayerHasQuestSub(QuestEventID event_id) +{ + return ( + PlayerHasQuestSubLocal(event_id) || + PlayerHasQuestSubGlobal(event_id) || + PlayerHasEncounterSub(event_id) + ); } -bool QuestParserCollection::PlayerHasEncounterSub(QuestEventID evt) { - return HasEncounterSub(evt, "player"); +bool QuestParserCollection::PlayerHasEncounterSub(QuestEventID event_id) +{ + return HasEncounterSub(event_id, "player"); } -bool QuestParserCollection::PlayerHasQuestSubLocal(QuestEventID evt) { - if(_player_quest_status == QuestUnloaded) { +bool QuestParserCollection::PlayerHasQuestSubLocal(QuestEventID event_id) +{ + if (_player_quest_status == QuestUnloaded) { std::string filename; - QuestInterface *qi = GetQIByPlayerQuest(filename); - if(qi) { + auto qi = GetQIByPlayerQuest(filename); + + if (qi) { _player_quest_status = qi->GetIdentifier(); qi->LoadPlayerScript(filename); - return qi->PlayerHasQuestSub(evt); + return qi->PlayerHasQuestSub(event_id); } - } else if(_player_quest_status != QuestFailedToLoad) { + } else if (_player_quest_status != QuestFailedToLoad) { auto iter = _interfaces.find(_player_quest_status); - return iter->second->PlayerHasQuestSub(evt); + return iter->second->PlayerHasQuestSub(event_id); } + return false; } -bool QuestParserCollection::PlayerHasQuestSubGlobal(QuestEventID evt) { - if(_global_player_quest_status == QuestUnloaded) { +bool QuestParserCollection::PlayerHasQuestSubGlobal(QuestEventID event_id) +{ + if (_global_player_quest_status == QuestUnloaded) { std::string filename; - QuestInterface *qi = GetQIByGlobalPlayerQuest(filename); - if(qi) { + auto qi = GetQIByGlobalPlayerQuest(filename); + + if (qi) { _global_player_quest_status = qi->GetIdentifier(); qi->LoadGlobalPlayerScript(filename); - return qi->GlobalPlayerHasQuestSub(evt); + return qi->GlobalPlayerHasQuestSub(event_id); } - } else if(_global_player_quest_status != QuestFailedToLoad) { + } else if (_global_player_quest_status != QuestFailedToLoad) { auto iter = _interfaces.find(_global_player_quest_status); - return iter->second->GlobalPlayerHasQuestSub(evt); + return iter->second->GlobalPlayerHasQuestSub(event_id); } + return false; } -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::SpellHasEncounterSub(uint32 spell_id, QuestEventID event_id) +{ + return HasEncounterSub( + event_id, + fmt::format( + "spell_{}", + spell_id + ) + ); } -bool QuestParserCollection::SpellHasQuestSub(uint32 spell_id, QuestEventID evt) { - if (SpellHasEncounterSub(spell_id, evt)) { +bool QuestParserCollection::SpellHasQuestSub(uint32 spell_id, QuestEventID event_id) +{ + if (SpellHasEncounterSub(spell_id, event_id)) { return true; } - auto iter = _spell_quest_status.find(spell_id); - if(iter != _spell_quest_status.end()) { - //loaded or failed to load - if(iter->second != QuestFailedToLoad) { - auto qiter = _interfaces.find(iter->second); - return qiter->second->SpellHasQuestSub(spell_id, evt); - } - } else if(_spell_quest_status[spell_id] != QuestFailedToLoad){ - std::string filename; - QuestInterface *qi = GetQIBySpellQuest(spell_id, filename); - if(qi) { - _spell_quest_status[spell_id] = qi->GetIdentifier(); - qi->LoadSpellScript(filename, spell_id); - return qi->SpellHasQuestSub(spell_id, evt); - } else { - _spell_quest_status[spell_id] = QuestFailedToLoad; - } - } - return false; -} - -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) { - if (itm == nullptr) - return false; - - if (ItemHasEncounterSub(itm, evt)) { - return true; - } - - std::string item_script; - if(itm->GetItem()->ScriptFileID != 0) { - item_script = "script_"; - item_script += std::to_string(itm->GetItem()->ScriptFileID); - } else if(strlen(itm->GetItem()->CharmFile) > 0) { - item_script = itm->GetItem()->CharmFile; - } else { - item_script = std::to_string(itm->GetID()); - } - - uint32 item_id = itm->GetID(); - auto iter = _item_quest_status.find(item_id); - if(iter != _item_quest_status.end()) { - //loaded or failed to load - if(iter->second != QuestFailedToLoad) { - auto qiter = _interfaces.find(iter->second); - return qiter->second->ItemHasQuestSub(itm, evt); - } - } else { - std::string filename; - QuestInterface *qi = GetQIByItemQuest(item_script, filename); - if(qi) { - _item_quest_status[item_id] = qi->GetIdentifier(); - qi->LoadItemScript(filename, itm); - return qi->ItemHasQuestSub(itm, evt); - } else { - _item_quest_status[item_id] = QuestFailedToLoad; - } - } - 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); - int rl = EventNPCLocal(evt, npc, init, data, extra_data, extra_pointers); - int rg = EventNPCGlobal(evt, npc, init, data, extra_data, extra_pointers); - - //Local quests returning non-default values have priority over global quests - if(rl != 0) { - return rl; - } else if(rg != 0) { - return rg; - } else if(rd != 0) { - return rd; - } - - return 0; -} - -int QuestParserCollection::EventNPCLocal(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { - auto iter = _npc_quest_status.find(npc->GetNPCTypeID()); - if(iter != _npc_quest_status.end()) { - //loaded or failed to load - if(iter->second != QuestFailedToLoad) { - auto qiter = _interfaces.find(iter->second); - return qiter->second->EventNPC(evt, npc, init, data, extra_data, extra_pointers); - } - } else if (_npc_quest_status[npc->GetNPCTypeID()] != QuestFailedToLoad){ - std::string filename; - QuestInterface *qi = GetQIByNPCQuest(npc->GetNPCTypeID(), filename); - if(qi) { - _npc_quest_status[npc->GetNPCTypeID()] = qi->GetIdentifier(); - qi->LoadNPCScript(filename, npc->GetNPCTypeID()); - return qi->EventNPC(evt, npc, init, data, extra_data, extra_pointers); - } else { - _npc_quest_status[npc->GetNPCTypeID()] = QuestFailedToLoad; - } - } - return 0; -} - -int QuestParserCollection::EventNPCGlobal(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { - if(_global_npc_quest_status != QuestUnloaded && _global_npc_quest_status != QuestFailedToLoad) { - auto qiter = _interfaces.find(_global_npc_quest_status); - return qiter->second->EventGlobalNPC(evt, npc, init, data, extra_data, extra_pointers); - } - else if(_global_npc_quest_status != QuestFailedToLoad){ - std::string filename; - QuestInterface *qi = GetQIByGlobalNPCQuest(filename); - if(qi) { - _global_npc_quest_status = qi->GetIdentifier(); - qi->LoadGlobalNPCScript(filename); - return qi->EventGlobalNPC(evt, npc, init, data, extra_data, extra_pointers); - } else { - _global_npc_quest_status = QuestFailedToLoad; - } - } - return 0; -} - -int QuestParserCollection::EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { - int rd = DispatchEventPlayer(evt, client, data, extra_data, extra_pointers); - int rl = EventPlayerLocal(evt, client, data, extra_data, extra_pointers); - int rg = EventPlayerGlobal(evt, client, data, extra_data, extra_pointers); - - //Local quests returning non-default values have priority over global quests - if(rl != 0) { - return rl; - } else if(rg != 0) { - return rg; - } else if(rd != 0) { - return rd; - } - - return 0; -} - -int QuestParserCollection::EventPlayerLocal(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { - if(_player_quest_status == QuestUnloaded) { - std::string filename; - QuestInterface *qi = GetQIByPlayerQuest(filename); - if(qi) { - _player_quest_status = qi->GetIdentifier(); - qi->LoadPlayerScript(filename); - return qi->EventPlayer(evt, client, data, extra_data, extra_pointers); - } - } else { - if(_player_quest_status != QuestFailedToLoad) { - auto iter = _interfaces.find(_player_quest_status); - return iter->second->EventPlayer(evt, client, data, extra_data, extra_pointers); - } - } - return 0; -} - -int QuestParserCollection::EventPlayerGlobal(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { - if(_global_player_quest_status == QuestUnloaded) { - std::string filename; - QuestInterface *qi = GetQIByGlobalPlayerQuest(filename); - if(qi) { - _global_player_quest_status = qi->GetIdentifier(); - qi->LoadGlobalPlayerScript(filename); - return qi->EventGlobalPlayer(evt, client, data, extra_data, extra_pointers); - } - } else { - if(_global_player_quest_status != QuestFailedToLoad) { - auto iter = _interfaces.find(_global_player_quest_status); - return iter->second->EventGlobalPlayer(evt, client, data, extra_data, extra_pointers); - } - } - return 0; -} - -int QuestParserCollection::EventItem(QuestEventID evt, Client *client, EQ::ItemInstance *item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers) { - // needs pointer validation check on 'item' argument - - std::string item_script; - if(item->GetItem()->ScriptFileID != 0) { - item_script = "script_"; - item_script += std::to_string(item->GetItem()->ScriptFileID); - } else if(strlen(item->GetItem()->CharmFile) > 0) { - item_script = item->GetItem()->CharmFile; - } else { - item_script = std::to_string(item->GetID()); - } - - uint32 item_id = item->GetID(); - auto iter = _item_quest_status.find(item_id); - if(iter != _item_quest_status.end()) { - //loaded or failed to load - if(iter->second != QuestFailedToLoad) { - auto qiter = _interfaces.find(iter->second); - int ret = DispatchEventItem(evt, client, item, mob, data, extra_data, extra_pointers); - int i = qiter->second->EventItem(evt, client, item, mob, data, extra_data, extra_pointers); - if(i != 0) { - ret = i; - } - return ret; - } - return DispatchEventItem(evt, client, item, mob, data, extra_data, extra_pointers); - } else if(_item_quest_status[item_id] != QuestFailedToLoad){ - std::string filename; - QuestInterface *qi = GetQIByItemQuest(item_script, filename); - if(qi) { - _item_quest_status[item_id] = qi->GetIdentifier(); - qi->LoadItemScript(filename, item); - int ret = DispatchEventItem(evt, client, item, mob, data, extra_data, extra_pointers); - int i = qi->EventItem(evt, client, item, mob, data, extra_data, extra_pointers); - if(i != 0) { - ret = i; - } - return ret; - } else { - _item_quest_status[item_id] = QuestFailedToLoad; - return DispatchEventItem(evt, client, item, mob, data, extra_data, extra_pointers); - } - } - return 0; -} - -int QuestParserCollection::EventSpell( - QuestEventID evt, - Mob* mob, - Client *client, - uint32 spell_id, - std::string data, - uint32 extra_data, - std::vector *extra_pointers -) { auto iter = _spell_quest_status.find(spell_id); if (iter != _spell_quest_status.end()) { //loaded or failed to load if (iter->second != QuestFailedToLoad) { - auto qi = _interfaces.find(iter->second); - int ret = DispatchEventSpell(evt, mob, client, spell_id, data, extra_data, extra_pointers); - int i = qi->second->EventSpell(evt, mob, client, spell_id, data, extra_data, extra_pointers); + auto qiter = _interfaces.find(iter->second); + return qiter->second->SpellHasQuestSub(spell_id, event_id); + } + } else if (_spell_quest_status[spell_id] != QuestFailedToLoad) { + std::string filename; + auto qi = GetQIBySpellQuest(spell_id, filename); + + if (qi) { + _spell_quest_status[spell_id] = qi->GetIdentifier(); + qi->LoadSpellScript(filename, spell_id); + return qi->SpellHasQuestSub(spell_id, event_id); + } else { + _spell_quest_status[spell_id] = QuestFailedToLoad; + } + } + + return false; +} + +bool QuestParserCollection::ItemHasEncounterSub(EQ::ItemInstance* inst, QuestEventID event_id) +{ + if (inst) { + return HasEncounterSub( + event_id, + fmt::format( + "item_{}", + inst->GetID() + ) + ); + } + + return false; +} + +bool QuestParserCollection::ItemHasQuestSub(EQ::ItemInstance* inst, QuestEventID event_id) +{ + if (!inst) { + return false; + } + + if (ItemHasEncounterSub(inst, event_id)) { + return true; + } + + std::string item_script; + if (inst->GetItem()->ScriptFileID != 0) { + item_script = fmt::format( + "script_{}", + inst->GetItem()->ScriptFileID + ); + } else if (strlen(inst->GetItem()->CharmFile) > 0) { + item_script = inst->GetItem()->CharmFile; + } else { + item_script = std::to_string(inst->GetID()); + } + + uint32 item_id = inst->GetID(); + auto iter = _item_quest_status.find(item_id); + if (iter != _item_quest_status.end()) { + //loaded or failed to load + if (iter->second != QuestFailedToLoad) { + auto qiter = _interfaces.find(iter->second); + return qiter->second->ItemHasQuestSub(inst, event_id); + } + } else { + std::string filename; + auto qi = GetQIByItemQuest(item_script, filename); + if (qi) { + _item_quest_status[item_id] = qi->GetIdentifier(); + qi->LoadItemScript(filename, inst); + return qi->ItemHasQuestSub(inst, event_id); + } else { + _item_quest_status[item_id] = QuestFailedToLoad; + } + } + + return false; +} + +bool QuestParserCollection::HasEncounterSub(QuestEventID event_id, 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, event_id)) { + return true; + } + } + } + + return false; +} + +bool QuestParserCollection::BotHasQuestSubLocal(QuestEventID event_id) +{ + if (_bot_quest_status == QuestUnloaded) { + std::string filename; + auto qi = GetQIByBotQuest(filename); + + if (qi) { + _bot_quest_status = qi->GetIdentifier(); + qi->LoadBotScript(filename); + return qi->BotHasQuestSub(event_id); + } + } else if (_bot_quest_status != QuestFailedToLoad) { + auto iter = _interfaces.find(_bot_quest_status); + return iter->second->BotHasQuestSub(event_id); + } + + return false; +} + +bool QuestParserCollection::BotHasQuestSubGlobal(QuestEventID event_id) +{ + if (_global_bot_quest_status == QuestUnloaded) { + std::string filename; + auto qi = GetQIByGlobalBotQuest(filename); + + if (qi) { + _global_bot_quest_status = qi->GetIdentifier(); + qi->LoadGlobalBotScript(filename); + return qi->GlobalBotHasQuestSub(event_id); + } + } else if (_global_bot_quest_status != QuestFailedToLoad) { + auto iter = _interfaces.find(_global_bot_quest_status); + return iter->second->GlobalBotHasQuestSub(event_id); + } + + return false; +} + +bool QuestParserCollection::BotHasQuestSub(QuestEventID event_id) +{ + return BotHasQuestSubLocal(event_id) || BotHasQuestSubGlobal(event_id); +} + +int QuestParserCollection::EventNPC( + QuestEventID event_id, + NPC* npc, + Mob* init, + std::string data, + uint32 extra_data, + std::vector* extra_pointers +) +{ + const int local_return = EventNPCLocal(event_id, npc, init, data, extra_data, extra_pointers); + const int global_return = EventNPCGlobal(event_id, npc, init, data, extra_data, extra_pointers); + const int default_return = DispatchEventNPC(event_id, npc, init, data, extra_data, extra_pointers); + + if (local_return != 0) { + return local_return; + } else if (global_return != 0) { + return global_return; + } else if (default_return != 0) { + return default_return; + } + + return 0; +} + +int QuestParserCollection::EventNPCLocal( + QuestEventID event_id, + NPC* npc, + Mob* init, + std::string data, + uint32 extra_data, + std::vector* extra_pointers +) +{ + auto iter = _npc_quest_status.find(npc->GetNPCTypeID()); + if (iter != _npc_quest_status.end()) { + //loaded or failed to load + if (iter->second != QuestFailedToLoad) { + auto qiter = _interfaces.find(iter->second); + return qiter->second->EventNPC(event_id, npc, init, data, extra_data, extra_pointers); + } + } else if (_npc_quest_status[npc->GetNPCTypeID()] != QuestFailedToLoad) { + std::string filename; + auto qi = GetQIByNPCQuest(npc->GetNPCTypeID(), filename); + + if (qi) { + _npc_quest_status[npc->GetNPCTypeID()] = qi->GetIdentifier(); + qi->LoadNPCScript(filename, npc->GetNPCTypeID()); + return qi->EventNPC(event_id, npc, init, data, extra_data, extra_pointers); + } else { + _npc_quest_status[npc->GetNPCTypeID()] = QuestFailedToLoad; + } + } + + return 0; +} + +int QuestParserCollection::EventNPCGlobal( + QuestEventID event_id, + NPC* npc, + Mob* init, + std::string data, + uint32 extra_data, + std::vector* extra_pointers +) +{ + if (_global_npc_quest_status != QuestUnloaded && _global_npc_quest_status != QuestFailedToLoad) { + auto qiter = _interfaces.find(_global_npc_quest_status); + return qiter->second->EventGlobalNPC(event_id, npc, init, data, extra_data, extra_pointers); + } else if (_global_npc_quest_status != QuestFailedToLoad) { + std::string filename; + auto qi = GetQIByGlobalNPCQuest(filename); + + if (qi) { + _global_npc_quest_status = qi->GetIdentifier(); + qi->LoadGlobalNPCScript(filename); + return qi->EventGlobalNPC(event_id, npc, init, data, extra_data, extra_pointers); + } else { + _global_npc_quest_status = QuestFailedToLoad; + } + } + + return 0; +} + +int QuestParserCollection::EventPlayer( + QuestEventID event_id, + Client* client, + std::string data, + uint32 extra_data, + std::vector* extra_pointers +) +{ + const int local_return = EventPlayerLocal(event_id, client, data, extra_data, extra_pointers); + const int global_return = EventPlayerGlobal(event_id, client, data, extra_data, extra_pointers); + const int default_return = DispatchEventPlayer(event_id, client, data, extra_data, extra_pointers); + + if (local_return != 0) { + return local_return; + } else if (global_return != 0) { + return global_return; + } else if (default_return != 0) { + return default_return; + } + + return 0; +} + +int QuestParserCollection::EventPlayerLocal( + QuestEventID event_id, + Client* client, + std::string data, + uint32 extra_data, + std::vector* extra_pointers +) +{ + if (_player_quest_status == QuestUnloaded) { + std::string filename; + auto qi = GetQIByPlayerQuest(filename); + + if (qi) { + _player_quest_status = qi->GetIdentifier(); + qi->LoadPlayerScript(filename); + return qi->EventPlayer(event_id, client, data, extra_data, extra_pointers); + } + } else { + if (_player_quest_status != QuestFailedToLoad) { + auto iter = _interfaces.find(_player_quest_status); + return iter->second->EventPlayer(event_id, client, data, extra_data, extra_pointers); + } + } + + return 0; +} + +int QuestParserCollection::EventPlayerGlobal( + QuestEventID event_id, + Client* client, + std::string data, + uint32 extra_data, + std::vector* extra_pointers +) +{ + if (_global_player_quest_status == QuestUnloaded) { + std::string filename; + auto qi = GetQIByGlobalPlayerQuest(filename); + + if (qi) { + _global_player_quest_status = qi->GetIdentifier(); + qi->LoadGlobalPlayerScript(filename); + return qi->EventGlobalPlayer(event_id, client, data, extra_data, extra_pointers); + } + } else { + if (_global_player_quest_status != QuestFailedToLoad) { + auto iter = _interfaces.find(_global_player_quest_status); + return iter->second->EventGlobalPlayer(event_id, client, data, extra_data, extra_pointers); + } + } + + return 0; +} + +int QuestParserCollection::EventItem( + QuestEventID event_id, + Client* client, + EQ::ItemInstance* inst, + Mob* mob, + std::string data, + uint32 extra_data, + std::vector* extra_pointers +) +{ + if (!inst) { + return 0; + } + + std::string item_script; + if (inst->GetItem()->ScriptFileID != 0) { + item_script = fmt::format( + "script_{}", + inst->GetItem()->ScriptFileID + ); + } else if (strlen(inst->GetItem()->CharmFile) > 0) { + item_script = inst->GetItem()->CharmFile; + } else { + item_script = std::to_string(inst->GetID()); + } + + uint32 item_id = inst->GetID(); + auto iter = _item_quest_status.find(item_id); + if (iter != _item_quest_status.end()) { + //loaded or failed to load + if (iter->second != QuestFailedToLoad) { + auto qiter = _interfaces.find(iter->second); + int ret = DispatchEventItem(event_id, client, inst, mob, data, extra_data, extra_pointers); + int i = qiter->second->EventItem(event_id, client, inst, mob, data, extra_data, extra_pointers); if (i != 0) { ret = i; } @@ -481,15 +591,94 @@ int QuestParserCollection::EventSpell( return ret; } - return DispatchEventSpell(evt, mob, client, spell_id, data, extra_data, extra_pointers); + return DispatchEventItem(event_id, client, inst, mob, data, extra_data, extra_pointers); + } else if (_item_quest_status[item_id] != QuestFailedToLoad) { + std::string filename; + auto qi = GetQIByItemQuest(item_script, filename); + + if (qi) { + _item_quest_status[item_id] = qi->GetIdentifier(); + + qi->LoadItemScript(filename, inst); + + int ret = DispatchEventItem( + event_id, + client, + inst, + mob, + data, + extra_data, + extra_pointers + ); + + int i = qi->EventItem(event_id, client, inst, mob, data, extra_data, extra_pointers); + if (i != 0) { + ret = i; + } + + return ret; + } else { + _item_quest_status[item_id] = QuestFailedToLoad; + return DispatchEventItem(event_id, client, inst, mob, data, extra_data, extra_pointers); + } + } + + return 0; +} + +int QuestParserCollection::EventSpell( + QuestEventID event_id, + Mob* mob, + Client* client, + uint32 spell_id, + std::string data, + uint32 extra_data, + std::vector* extra_pointers +) +{ + auto iter = _spell_quest_status.find(spell_id); + if (iter != _spell_quest_status.end()) { + //loaded or failed to load + if (iter->second != QuestFailedToLoad) { + auto qi = _interfaces.find(iter->second); + int ret = DispatchEventSpell(event_id, mob, client, spell_id, data, extra_data, extra_pointers); + int i = qi->second->EventSpell(event_id, mob, client, spell_id, data, extra_data, extra_pointers); + if (i != 0) { + ret = i; + } + + return ret; + } + + return DispatchEventSpell(event_id, mob, client, spell_id, data, extra_data, extra_pointers); } else if (_spell_quest_status[spell_id] != QuestFailedToLoad) { std::string filename; - QuestInterface *qi = GetQIBySpellQuest(spell_id, filename); + auto qi = GetQIBySpellQuest(spell_id, filename); + if (qi) { _spell_quest_status[spell_id] = qi->GetIdentifier(); + qi->LoadSpellScript(filename, spell_id); - int ret = DispatchEventSpell(evt, mob, client, spell_id, data, extra_data, extra_pointers); - int i = qi->EventSpell(evt, mob, client, spell_id, data, extra_data, extra_pointers); + + int ret = DispatchEventSpell( + event_id, + mob, + client, + spell_id, + data, + extra_data, + extra_pointers + ); + + int i = qi->EventSpell( + event_id, + mob, + client, + spell_id, + data, + extra_data, + extra_pointers + ); if (i != 0) { ret = i; } @@ -497,567 +686,584 @@ int QuestParserCollection::EventSpell( return ret; } else { _spell_quest_status[spell_id] = QuestFailedToLoad; - return DispatchEventSpell(evt, mob, client, spell_id, data, extra_data, extra_pointers); + return DispatchEventSpell(event_id, mob, client, spell_id, data, extra_data, extra_pointers); } } + return 0; } -int QuestParserCollection::EventEncounter(QuestEventID evt, std::string encounter_name, std::string data, uint32 extra_data, - std::vector *extra_pointers) { +int QuestParserCollection::EventEncounter( + QuestEventID event_id, + std::string encounter_name, + std::string data, + uint32 extra_data, + std::vector* extra_pointers +) +{ auto iter = _encounter_quest_status.find(encounter_name); - if(iter != _encounter_quest_status.end()) { - //loaded or failed to load - if(iter->second != QuestFailedToLoad) { + if (iter != _encounter_quest_status.end()) { + if (iter->second != QuestFailedToLoad) { // Loaded or failed to load auto qiter = _interfaces.find(iter->second); - return qiter->second->EventEncounter(evt, encounter_name, data, extra_data, extra_pointers); + return qiter->second->EventEncounter(event_id, encounter_name, data, extra_data, extra_pointers); } - } else if(_encounter_quest_status[encounter_name] != QuestFailedToLoad){ + } else if (_encounter_quest_status[encounter_name] != QuestFailedToLoad) { std::string filename; - QuestInterface *qi = GetQIByEncounterQuest(encounter_name, filename); - if(qi) { + auto qi = GetQIByEncounterQuest(encounter_name, filename); + + if (qi) { _encounter_quest_status[encounter_name] = qi->GetIdentifier(); qi->LoadEncounterScript(filename, encounter_name); - return qi->EventEncounter(evt, encounter_name, data, extra_data, extra_pointers); + return qi->EventEncounter(event_id, encounter_name, data, extra_data, extra_pointers); } else { _encounter_quest_status[encounter_name] = QuestFailedToLoad; } } + return 0; } -QuestInterface *QuestParserCollection::GetQIByNPCQuest(uint32 npcid, std::string &filename) { - // first look for /quests/zone/npcid.ext (precedence) - filename = fmt::format("{}/{}/{}", path.GetQuestsPath(), zone->GetShortName(), npcid); - - std::string tmp; - FILE *f = nullptr; - - auto iter = _load_precedence.begin(); - while(iter != _load_precedence.end()) { - tmp = filename; - auto ext = _extensions.find((*iter)->GetIdentifier()); - tmp += "."; - tmp += ext->second; - f = fopen(tmp.c_str(), "r"); - if(f) { - fclose(f); - filename = tmp; - return (*iter); - } - - ++iter; - } - - //second look for /quests/zone/npcname.ext (precedence) - const NPCType *npc_type = content_db.LoadNPCTypesData(npcid); - if (!npc_type && npcid != ZONE_CONTROLLER_NPC_ID) { - return nullptr; - } - - std::string npc_name; - if (npcid == ZONE_CONTROLLER_NPC_ID){ - npc_name = "zone_controller"; - } - else{ - npc_name = npc_type->name; - } - int sz = static_cast(npc_name.length()); - for(int i = 0; i < sz; ++i) { - if(npc_name[i] == '`') { - npc_name[i] = '-'; - } - } - - filename = fmt::format("{}/{}/{}", path.GetQuestsPath(), zone->GetShortName(), npc_name); - - iter = _load_precedence.begin(); - while(iter != _load_precedence.end()) { - tmp = filename; - auto ext = _extensions.find((*iter)->GetIdentifier()); - tmp += "."; - tmp += ext->second; - f = fopen(tmp.c_str(), "r"); - if(f) { - fclose(f); - filename = tmp; - return (*iter); - } - - ++iter; - } - - // third look for /quests/global/npcid.ext (precedence) - filename = fmt::format("{}/{}/{}", path.GetQuestsPath(), QUEST_GLOBAL_DIRECTORY, npcid); - iter = _load_precedence.begin(); - while(iter != _load_precedence.end()) { - tmp = filename; - auto ext = _extensions.find((*iter)->GetIdentifier()); - tmp += "."; - tmp += ext->second; - f = fopen(tmp.c_str(), "r"); - if(f) { - fclose(f); - filename = tmp; - return (*iter); - } - - ++iter; - } - - // fourth look for /quests/global/npcname.ext (precedence) - filename = fmt::format("{}/{}/{}", path.GetQuestsPath(), QUEST_GLOBAL_DIRECTORY, npc_name); - iter = _load_precedence.begin(); - while(iter != _load_precedence.end()) { - tmp = filename; - auto ext = _extensions.find((*iter)->GetIdentifier()); - tmp += "."; - tmp += ext->second; - f = fopen(tmp.c_str(), "r"); - if(f) { - fclose(f); - filename = tmp; - return (*iter); - } - - ++iter; - } - - // fifth look for /quests/zone/default.ext (precedence) - filename = fmt::format("{}/{}/default", path.GetQuestsPath(), zone->GetShortName()); - iter = _load_precedence.begin(); - while(iter != _load_precedence.end()) { - tmp = filename; - auto ext = _extensions.find((*iter)->GetIdentifier()); - tmp += "."; - tmp += ext->second; - f = fopen(tmp.c_str(), "r"); - if(f) { - fclose(f); - filename = tmp; - return (*iter); - } - - ++iter; - } - - // last look for /quests/global/default.ext (precedence) - filename = fmt::format("{}/{}/default", path.GetQuestsPath(), QUEST_GLOBAL_DIRECTORY); - iter = _load_precedence.begin(); - while(iter != _load_precedence.end()) { - tmp = filename; - auto ext = _extensions.find((*iter)->GetIdentifier()); - tmp += "."; - tmp += ext->second; - f = fopen(tmp.c_str(), "r"); - if(f) { - fclose(f); - filename = tmp; - return (*iter); - } - - ++iter; - } - - return nullptr; -} - -QuestInterface *QuestParserCollection::GetQIByPlayerQuest(std::string &filename) { - if(!zone || !zone->IsLoaded()) - return nullptr; - - // first look for /quests/zone/player_v[instance_version].ext (precedence) - filename = fmt::format("{}/{}/player_v{}", path.GetQuestsPath(), zone->GetShortName(), zone->GetInstanceVersion()); - std::string tmp; - FILE *f = nullptr; - - auto iter = _load_precedence.begin(); - while(iter != _load_precedence.end()) { - tmp = filename; - auto ext = _extensions.find((*iter)->GetIdentifier()); - tmp += "."; - tmp += ext->second; - f = fopen(tmp.c_str(), "r"); - if(f) { - fclose(f); - filename = tmp; - return (*iter); - } - - ++iter; - } - - // second look for /quests/zone/player.ext (precedence) - filename = fmt::format("{}/{}/player", path.GetQuestsPath(), zone->GetShortName()); - - iter = _load_precedence.begin(); - while(iter != _load_precedence.end()) { - tmp = filename; - auto ext = _extensions.find((*iter)->GetIdentifier()); - tmp += "."; - tmp += ext->second; - f = fopen(tmp.c_str(), "r"); - if(f) { - fclose(f); - filename = tmp; - return (*iter); - } - - ++iter; - } - - // third look for /quests/global/player.ext (precedence) - filename = fmt::format("{}/{}/player", path.GetQuestsPath(), QUEST_GLOBAL_DIRECTORY); - iter = _load_precedence.begin(); - while(iter != _load_precedence.end()) { - tmp = filename; - auto ext = _extensions.find((*iter)->GetIdentifier()); - tmp += "."; - tmp += ext->second; - f = fopen(tmp.c_str(), "r"); - if(f) { - fclose(f); - filename = tmp; - return (*iter); - } - - ++iter; - } - - return nullptr; -} - -QuestInterface *QuestParserCollection::GetQIByGlobalNPCQuest(std::string &filename) { - // simply look for /quests/global/global_npc.ext - filename = fmt::format("{}/{}/global_npc", path.GetQuestsPath(), QUEST_GLOBAL_DIRECTORY); - - std::string tmp; - FILE *f = nullptr; - - auto iter = _load_precedence.begin(); - while(iter != _load_precedence.end()) { - tmp = filename; - auto ext = _extensions.find((*iter)->GetIdentifier()); - tmp += "."; - tmp += ext->second; - - f = fopen(tmp.c_str(), "r"); - if(f) { - fclose(f); - filename = tmp; - return (*iter); - } - - ++iter; - } - - return nullptr; -} - -QuestInterface *QuestParserCollection::GetQIByGlobalPlayerQuest(std::string &filename) { - // first look for /quests/global/player.ext (precedence) - filename = fmt::format("{}/{}/global_player", path.GetQuestsPath(), QUEST_GLOBAL_DIRECTORY); - std::string tmp; - FILE *f = nullptr; - - auto iter = _load_precedence.begin(); - while(iter != _load_precedence.end()) { - tmp = filename; - auto ext = _extensions.find((*iter)->GetIdentifier()); - tmp += "."; - tmp += ext->second; - f = fopen(tmp.c_str(), "r"); - if(f) { - fclose(f); - filename = tmp; - return (*iter); - } - - ++iter; - } - - return nullptr; -} - -QuestInterface *QuestParserCollection::GetQIBySpellQuest(uint32 spell_id, std::string &filename) { - //first look for /quests/zone/spells/spell_id.ext (precedence) - filename = fmt::format("{}/{}/spells/{}", path.GetQuestsPath(), zone->GetShortName(), spell_id); - std::string tmp; - FILE *f = nullptr; - - auto iter = _load_precedence.begin(); - while(iter != _load_precedence.end()) { - tmp = filename; - auto ext = _extensions.find((*iter)->GetIdentifier()); - tmp += "."; - tmp += ext->second; - f = fopen(tmp.c_str(), "r"); - if(f) { - fclose(f); - filename = tmp; - return (*iter); - } - - ++iter; - } - - // second look for /quests/global/spells/spell_id.ext (precedence) - filename = fmt::format("{}/{}/spells/{}", path.GetQuestsPath(), QUEST_GLOBAL_DIRECTORY, spell_id); - - iter = _load_precedence.begin(); - while(iter != _load_precedence.end()) { - tmp = filename; - auto ext = _extensions.find((*iter)->GetIdentifier()); - tmp += "."; - tmp += ext->second; - f = fopen(tmp.c_str(), "r"); - if(f) { - fclose(f); - filename = tmp; - return (*iter); - } - - ++iter; - } - - // third look for /quests/zone/spells/default.ext (precedence) - filename = fmt::format("{}/{}/spells/default", path.GetQuestsPath(), zone->GetShortName()); - - iter = _load_precedence.begin(); - while(iter != _load_precedence.end()) { - tmp = filename; - auto ext = _extensions.find((*iter)->GetIdentifier()); - tmp += "."; - tmp += ext->second; - f = fopen(tmp.c_str(), "r"); - if(f) { - fclose(f); - filename = tmp; - return (*iter); - } - - ++iter; - } - - // last look for /quests/global/spells/default.ext (precedence) - filename = fmt::format("{}/{}/spells/default", path.GetQuestsPath(), QUEST_GLOBAL_DIRECTORY); - - iter = _load_precedence.begin(); - while(iter != _load_precedence.end()) { - tmp = filename; - auto ext = _extensions.find((*iter)->GetIdentifier()); - tmp += "."; - tmp += ext->second; - f = fopen(tmp.c_str(), "r"); - if(f) { - fclose(f); - filename = tmp; - return (*iter); - } - - ++iter; - } - - return nullptr; -} - -QuestInterface *QuestParserCollection::GetQIByItemQuest(std::string item_script, std::string &filename) { - // first look for /quests/zone/items/item_script.ext (precedence) - filename = fmt::format("{}/{}/items/{}", path.GetQuestsPath(), zone->GetShortName(), item_script); - std::string tmp; - FILE *f = nullptr; - - auto iter = _load_precedence.begin(); - while(iter != _load_precedence.end()) { - tmp = filename; - auto ext = _extensions.find((*iter)->GetIdentifier()); - tmp += "."; - tmp += ext->second; - f = fopen(tmp.c_str(), "r"); - if(f) { - fclose(f); - filename = tmp; - return (*iter); - } - - ++iter; - } - - // second look for /quests/global/items/item_script.ext (precedence) - filename = fmt::format("{}/{}/items/{}", path.GetQuestsPath(), QUEST_GLOBAL_DIRECTORY, item_script); - - iter = _load_precedence.begin(); - while(iter != _load_precedence.end()) { - tmp = filename; - auto ext = _extensions.find((*iter)->GetIdentifier()); - tmp += "."; - tmp += ext->second; - f = fopen(tmp.c_str(), "r"); - if(f) { - fclose(f); - filename = tmp; - return (*iter); - } - - ++iter; - } - - // third look for /quests/zone/items/default.ext (precedence) - filename = fmt::format("{}/{}/items/default", path.GetQuestsPath(), zone->GetShortName()); - iter = _load_precedence.begin(); - while(iter != _load_precedence.end()) { - tmp = filename; - auto ext = _extensions.find((*iter)->GetIdentifier()); - tmp += "."; - tmp += ext->second; - f = fopen(tmp.c_str(), "r"); - if(f) { - fclose(f); - filename = tmp; - return (*iter); - } - - ++iter; - } - - // last look for /quests/global/items/default.ext (precedence) - filename = fmt::format("{}/{}/items/default", path.GetQuestsPath(), QUEST_GLOBAL_DIRECTORY); - iter = _load_precedence.begin(); - while(iter != _load_precedence.end()) { - tmp = filename; - auto ext = _extensions.find((*iter)->GetIdentifier()); - tmp += "."; - tmp += ext->second; - f = fopen(tmp.c_str(), "r"); - if(f) { - fclose(f); - filename = tmp; - return (*iter); - } - - ++iter; - } - - return nullptr; -} - -QuestInterface *QuestParserCollection::GetQIByEncounterQuest(std::string encounter_name, std::string &filename) { - // first look for /quests/zone/encounters/encounter_name.ext (precedence) - filename = fmt::format("{}/{}/encounters/{}", path.GetQuestsPath(), zone->GetShortName(), encounter_name); - std::string tmp; - FILE *f = nullptr; - - auto iter = _load_precedence.begin(); - while(iter != _load_precedence.end()) { - tmp = filename; - auto ext = _extensions.find((*iter)->GetIdentifier()); - tmp += "."; - tmp += ext->second; - f = fopen(tmp.c_str(), "r"); - if(f) { - fclose(f); - filename = tmp; - return (*iter); - } - - ++iter; - } - - // second look for /quests/global/encounters/encounter_name.ext (precedence) - filename = fmt::format("{}/{}/encounters/{}", path.GetQuestsPath(), QUEST_GLOBAL_DIRECTORY, encounter_name); - - iter = _load_precedence.begin(); - while(iter != _load_precedence.end()) { - tmp = filename; - auto ext = _extensions.find((*iter)->GetIdentifier()); - tmp += "."; - tmp += ext->second; - f = fopen(tmp.c_str(), "r"); - if(f) { - fclose(f); - filename = tmp; - return (*iter); - } - - ++iter; - } - - return nullptr; -} - -void QuestParserCollection::GetErrors(std::list &quest_errors) { - quest_errors.clear(); - auto iter = _load_precedence.begin(); - while (iter != _load_precedence.end()) { - (*iter)->GetErrors(quest_errors); - ++iter; - } -} - -int QuestParserCollection::DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { - int ret = 0; - auto iter = _load_precedence.begin(); - while(iter != _load_precedence.end()) { - int i = (*iter)->DispatchEventNPC(evt, npc, init, data, extra_data, extra_pointers); - if(i != 0) { - ret = i; - } - ++iter; - } - return ret; -} - -int QuestParserCollection::DispatchEventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { - int ret = 0; - auto iter = _load_precedence.begin(); - while(iter != _load_precedence.end()) { - int i = (*iter)->DispatchEventPlayer(evt, client, data, extra_data, extra_pointers); - if(i != 0) { - ret = i; - } - ++iter; - } - return ret; -} - -int QuestParserCollection::DispatchEventItem(QuestEventID evt, Client *client, EQ::ItemInstance *item, Mob *mob, std::string data, - uint32 extra_data, std::vector *extra_pointers) { - int ret = 0; - auto iter = _load_precedence.begin(); - while(iter != _load_precedence.end()) { - int i = (*iter)->DispatchEventItem(evt, client, item, mob, data, extra_data, extra_pointers); - if(i != 0) { - ret = i; - } - ++iter; - } - return ret; -} - -int QuestParserCollection::DispatchEventSpell( - QuestEventID evt, - Mob* mob, - Client *client, - uint32 spell_id, +int QuestParserCollection::EventBot( + QuestEventID event_id, + Bot* bot, + Mob* init, std::string data, uint32 extra_data, - std::vector *extra_pointers -) { + std::vector* extra_pointers +) +{ + const int local_return = EventBotLocal(event_id, bot, init, data, extra_data, extra_pointers); + const int global_return = EventBotGlobal(event_id, bot, init, data, extra_data, extra_pointers); + const int default_return = DispatchEventBot(event_id, bot, init, data, extra_data, extra_pointers); + + if (local_return != 0) { + return local_return; + } else if (global_return != 0) { + return global_return; + } else if (default_return != 0) { + return default_return; + } + + return 0; +} + +int QuestParserCollection::EventBotLocal( + QuestEventID event_id, + Bot* bot, + Mob* init, + std::string data, + uint32 extra_data, + std::vector* extra_pointers +) +{ + if (_bot_quest_status == QuestUnloaded) { + std::string filename; + auto qi = GetQIByBotQuest(filename); + + if (qi) { + _bot_quest_status = qi->GetIdentifier(); + qi->LoadBotScript(filename); + return qi->EventBot(event_id, bot, init, data, extra_data, extra_pointers); + } + } else { + if (_bot_quest_status != QuestFailedToLoad) { + auto iter = _interfaces.find(_bot_quest_status); + return iter->second->EventBot(event_id, bot, init, data, extra_data, extra_pointers); + } + } + + return 0; +} + +int QuestParserCollection::EventBotGlobal( + QuestEventID event_id, + Bot* bot, + Mob* init, + std::string data, + uint32 extra_data, + std::vector* extra_pointers +) +{ + if (_global_bot_quest_status == QuestUnloaded) { + std::string filename; + auto qi = GetQIByGlobalBotQuest(filename); + + if (qi) { + _global_bot_quest_status = qi->GetIdentifier(); + qi->LoadGlobalBotScript(filename); + return qi->EventGlobalBot(event_id, bot, init, data, extra_data, extra_pointers); + } + } else { + if (_global_bot_quest_status != QuestFailedToLoad) { + auto iter = _interfaces.find(_global_bot_quest_status); + return iter->second->EventGlobalBot(event_id, bot, init, data, extra_data, extra_pointers); + } + } + + return 0; +} + +QuestInterface* QuestParserCollection::GetQIByNPCQuest(uint32 npc_id, std::string& filename) +{ + if (!zone || !zone->IsLoaded()) { + return nullptr; + } + + const auto npc_type = content_db.LoadNPCTypesData(npc_id); + if (!npc_type && npc_id != ZONE_CONTROLLER_NPC_ID) { + return nullptr; + } + + std::string npc_name = npc_id == ZONE_CONTROLLER_NPC_ID ? "zone_controller" : npc_type->name; + + Strings::FindReplace(npc_name, "`", "-"); + + const std::string& global_path = fmt::format( + "{}/{}", + path.GetQuestsPath(), + QUEST_GLOBAL_DIRECTORY + ); + + const std::string& zone_path = fmt::format( + "{}/{}", + path.GetQuestsPath(), + zone->GetShortName() + ); + + std::vector file_names = { + fmt::format("{}/{}", zone_path, npc_id), // Local by NPC ID + fmt::format("{}/{}", zone_path, npc_name), // Local by NPC Name + fmt::format("{}/{}", global_path, npc_id), // Global by NPC ID + fmt::format("{}/{}", global_path, npc_name), // Global by NPC ID + fmt::format("{}/default", zone_path), // Zone Default + fmt::format("{}/default", global_path), // Global Default + }; + + std::string file_name; + + for (auto & file : file_names) { + for (auto* e: _load_precedence) { + file_name = fmt::format( + "{}.{}", + file, + _extensions.find(e->GetIdentifier())->second + ); + + if (File::Exists(file_name)) { + filename = file_name; + return e; + } + } + } + + return nullptr; +} + +QuestInterface* QuestParserCollection::GetQIByPlayerQuest(std::string& filename) +{ + if (!zone || !zone->IsLoaded()) { + return nullptr; + } + + const std::string& global_path = fmt::format( + "{}/{}", + path.GetQuestsPath(), + QUEST_GLOBAL_DIRECTORY + ); + + const std::string& zone_path = fmt::format( + "{}/{}", + path.GetQuestsPath(), + zone->GetShortName() + ); + + std::vector file_names = { + fmt::format("{}/player_v{}", zone_path, zone->GetInstanceVersion()), // Local by Instance Version + fmt::format("{}/player", zone_path), // Local + fmt::format("{}/player", global_path) // Global + }; + + std::string file_name; + for (auto & file : file_names) { + for (auto* e: _load_precedence) { + file_name = fmt::format( + "{}.{}", + file, + _extensions.find(e->GetIdentifier())->second + ); + + if (File::Exists(file_name)) { + filename = file_name; + return e; + } + } + } + + return nullptr; +} + +QuestInterface* QuestParserCollection::GetQIByGlobalNPCQuest(std::string& filename) +{ + if (!zone || !zone->IsLoaded()) { + return nullptr; + } + + std::string file_name; + + for (auto* e: _load_precedence) { + file_name = fmt::format( + "{}/{}/global_npc.{}", + path.GetQuestsPath(), + QUEST_GLOBAL_DIRECTORY, + _extensions.find(e->GetIdentifier())->second + ); + + if (File::Exists(file_name)) { + filename = file_name; + return e; + } + } + + return nullptr; +} + +QuestInterface* QuestParserCollection::GetQIByGlobalPlayerQuest(std::string& filename) +{ + if (!zone || !zone->IsLoaded()) { + return nullptr; + } + + std::string file_name; + for (auto* e: _load_precedence) { + file_name = fmt::format( + "{}/{}/global_player.{}", + path.GetQuestsPath(), + QUEST_GLOBAL_DIRECTORY, + _extensions.find(e->GetIdentifier())->second + ); + + if (File::Exists(file_name)) { + filename = file_name; + return e; + } + } + + return nullptr; +} + +QuestInterface* QuestParserCollection::GetQIBySpellQuest(uint32 spell_id, std::string& filename) +{ + if (!zone || !zone->IsLoaded()) { + return nullptr; + } + + const std::string& global_path = fmt::format( + "{}/{}/spells", + path.GetQuestsPath(), + QUEST_GLOBAL_DIRECTORY + ); + + const std::string& zone_path = fmt::format( + "{}/{}/spells", + path.GetQuestsPath(), + zone->GetShortName() + ); + + std::vector file_names = { + fmt::format("{}/{}", zone_path, spell_id), // Local + fmt::format("{}/{}", global_path, spell_id), // Global + fmt::format("{}/default", zone_path), // Local Default + fmt::format("{}/default", global_path) // Global Default + }; + + std::string file_name; + for (auto & file : file_names) { + for (auto* e: _load_precedence) { + file_name = fmt::format( + "{}.{}", + file, + _extensions.find(e->GetIdentifier())->second + ); + + if (File::Exists(file_name)) { + filename = file_name; + return e; + } + } + } + + return nullptr; +} + +QuestInterface* QuestParserCollection::GetQIByItemQuest(std::string item_script, std::string& filename) +{ + if (!zone || !zone->IsLoaded()) { + return nullptr; + } + + const std::string& global_path = fmt::format( + "{}/{}/items", + path.GetQuestsPath(), + QUEST_GLOBAL_DIRECTORY + ); + + const std::string& zone_path = fmt::format( + "{}/{}/items", + path.GetQuestsPath(), + zone->GetShortName() + ); + + std::vector file_names = { + fmt::format("{}/{}", zone_path, item_script), // Local + fmt::format("{}/{}", global_path, item_script), // Global + fmt::format("{}/default", zone_path), // Local Default + fmt::format("{}/default", global_path) // Global Default + }; + + std::string file_name; + for (auto & file : file_names) { + for (auto* e: _load_precedence) { + file_name = fmt::format( + "{}.{}", + file, + _extensions.find(e->GetIdentifier())->second + ); + + if (File::Exists(file_name)) { + filename = file_name; + return e; + } + } + } + + return nullptr; +} + +QuestInterface* QuestParserCollection::GetQIByEncounterQuest(std::string encounter_name, std::string& filename) +{ + if (!zone || !zone->IsLoaded()) { + return nullptr; + } + + const std::string& global_path = fmt::format( + "{}/{}/encounters", + path.GetQuestsPath(), + QUEST_GLOBAL_DIRECTORY + ); + + const std::string& zone_path = fmt::format( + "{}/{}/encounters", + path.GetQuestsPath(), + zone->GetShortName() + ); + + std::vector file_names = { + fmt::format("{}/{}", zone_path, encounter_name), // Local + fmt::format("{}/{}", global_path, encounter_name) // Global + }; + + std::string file_name; + for (auto & file : file_names) { + for (auto* e: _load_precedence) { + file_name = fmt::format( + "{}.{}", + file, + _extensions.find(e->GetIdentifier())->second + ); + + if (File::Exists(file_name)) { + filename = file_name; + return e; + } + } + } + + return nullptr; +} + +QuestInterface* QuestParserCollection::GetQIByBotQuest(std::string& filename) +{ + if (!zone || !zone->IsLoaded()) { + return nullptr; + } + + const std::string& global_path = fmt::format( + "{}/{}", + path.GetQuestsPath(), + QUEST_GLOBAL_DIRECTORY + ); + + const std::string& zone_path = fmt::format( + "{}/{}", + path.GetQuestsPath(), + zone->GetShortName() + ); + + std::vector file_names = { + fmt::format("{}/bot_v{}", zone_path, zone->GetInstanceVersion()), // Local by Instance Version + fmt::format("{}/bot", zone_path), // Local + fmt::format("{}/bot", global_path) // Global + }; + + std::string file_name; + for (auto & file : file_names) { + for (auto* e: _load_precedence) { + file_name = fmt::format( + "{}.{}", + file, + _extensions.find(e->GetIdentifier())->second + ); + + if (File::Exists(file_name)) { + filename = file_name; + return e; + } + } + } + + return nullptr; +} + +QuestInterface* QuestParserCollection::GetQIByGlobalBotQuest(std::string& filename) +{ + if (!zone || !zone->IsLoaded()) { + return nullptr; + } + + std::string file_name; + for (auto* e: _load_precedence) { + file_name = fmt::format( + "{}/{}/global_bot.{}", + path.GetQuestsPath(), + QUEST_GLOBAL_DIRECTORY, + _extensions.find(e->GetIdentifier())->second + ); + + if (File::Exists(file_name)) { + filename = file_name; + return e; + } + } + + return nullptr; +} + +void QuestParserCollection::GetErrors(std::list& quest_errors) +{ + quest_errors.clear(); + + for (const auto& e: _load_precedence) { + e->GetErrors(quest_errors); + } +} + +int QuestParserCollection::DispatchEventNPC( + QuestEventID event_id, + NPC* npc, + Mob* init, + std::string data, + uint32 extra_data, + std::vector* extra_pointers +) +{ int ret = 0; - auto iter = _load_precedence.begin(); - while(iter != _load_precedence.end()) { - int i = (*iter)->DispatchEventSpell(evt, mob, client, spell_id, data, extra_data, extra_pointers); - if(i != 0) { + + for (const auto& e: _load_precedence) { + const int i = e->DispatchEventNPC(event_id, npc, init, data, extra_data, extra_pointers); + if (i != 0) { ret = i; } - ++iter; } + return ret; } -void QuestParserCollection::LoadPerlEventExportSettings(PerlEventExportSettings *s) +int QuestParserCollection::DispatchEventPlayer( + QuestEventID event_id, + Client* client, + std::string data, + uint32 extra_data, + std::vector* extra_pointers +) +{ + int ret = 0; + + for (const auto& e: _load_precedence) { + const int i = e->DispatchEventPlayer(event_id, client, data, extra_data, extra_pointers); + if (i != 0) { + ret = i; + } + } + + return ret; +} + +int QuestParserCollection::DispatchEventItem( + QuestEventID event_id, + Client* client, + EQ::ItemInstance* inst, + Mob* mob, + std::string data, + uint32 extra_data, + std::vector* extra_pointers +) +{ + int ret = 0; + + for (const auto& e: _load_precedence) { + const int i = e->DispatchEventItem(event_id, client, inst, mob, data, extra_data, extra_pointers); + if (i != 0) { + ret = i; + } + } + + return ret; +} + +int QuestParserCollection::DispatchEventSpell( + QuestEventID event_id, + Mob* mob, + Client* client, + uint32 spell_id, + std::string data, + uint32 extra_data, + std::vector* extra_pointers +) +{ + int ret = 0; + + for (const auto& e: _load_precedence) { + const int i = e->DispatchEventSpell(event_id, mob, client, spell_id, data, extra_data, extra_pointers); + if (i != 0) { + ret = i; + } + } + + return ret; +} + +int QuestParserCollection::DispatchEventBot( + QuestEventID event_id, + Bot* bot, + Mob* init, + std::string data, + uint32 extra_data, + std::vector* extra_pointers +) +{ + int ret = 0; + + for (const auto& e: _load_precedence) { + int i = e->DispatchEventBot(event_id, bot, init, data, extra_data, extra_pointers); + if (i != 0) { + ret = i; + } + } + + return ret; +} + +void QuestParserCollection::LoadPerlEventExportSettings(PerlEventExportSettings* s) { for (int i = 0; i < _LargestEventID; i++) { s[i].qglobals = 1; @@ -1067,8 +1273,9 @@ void QuestParserCollection::LoadPerlEventExportSettings(PerlEventExportSettings s[i].event_variables = 1; } - auto settings = PerlEventExportSettingsRepository::All(database); - for (auto &e: settings) { + const auto& l = PerlEventExportSettingsRepository::All(database); + + for (const auto& e: l) { s[e.event_id].qglobals = e.export_qglobals; s[e.event_id].mob = e.export_mob; s[e.event_id].zone = e.export_zone; @@ -1076,232 +1283,5 @@ void QuestParserCollection::LoadPerlEventExportSettings(PerlEventExportSettings s[e.event_id].event_variables = e.export_event; } - LogInfo("Loaded [{}] Perl Event Export Settings", settings.size()); -} - -int QuestParserCollection::DispatchEventBot( - QuestEventID evt, - Bot *bot, - Mob *init, - std::string data, - uint32 extra_data, - std::vector *extra_pointers -) { - int ret = 0; - auto iter = _load_precedence.begin(); - while (iter != _load_precedence.end()) { - int i = (*iter)->DispatchEventBot(evt, bot, init, data, extra_data, extra_pointers); - if (i != 0) { - ret = i; - } - - ++iter; - } - - return ret; -} - -int QuestParserCollection::EventBot( - QuestEventID evt, - Bot *bot, - Mob *init, - std::string data, - uint32 extra_data, - std::vector *extra_pointers -) { - auto rd = DispatchEventBot(evt, bot, init, data, extra_data, extra_pointers); - auto rl = EventBotLocal(evt, bot, init, data, extra_data, extra_pointers); - auto rg = EventBotGlobal(evt, bot, init, data, extra_data, extra_pointers); - - //Local quests returning non-default values have priority over global quests - if (rl != 0) { - return rl; - } else if (rg != 0) { - return rg; - } else if (rd != 0) { - return rd; - } - - return 0; -} - -int QuestParserCollection::EventBotLocal( - QuestEventID evt, - Bot *bot, - Mob *init, - std::string data, - uint32 extra_data, - std::vector *extra_pointers -) { - if (_bot_quest_status == QuestUnloaded) { - std::string filename; - QuestInterface *qi = GetQIByBotQuest(filename); - if (qi) { - _bot_quest_status = qi->GetIdentifier(); - qi->LoadBotScript(filename); - return qi->EventBot(evt, bot, init, data, extra_data, extra_pointers); - } - } else { - if (_bot_quest_status != QuestFailedToLoad) { - auto iter = _interfaces.find(_bot_quest_status); - return iter->second->EventBot(evt, bot, init, data, extra_data, extra_pointers); - } - } - - return 0; -} - -int QuestParserCollection::EventBotGlobal( - QuestEventID evt, - Bot *bot, - Mob *init, - std::string data, - uint32 extra_data, - std::vector *extra_pointers -) { - if (_global_bot_quest_status == QuestUnloaded) { - std::string filename; - QuestInterface *qi = GetQIByGlobalBotQuest(filename); - if (qi) { - _global_bot_quest_status = qi->GetIdentifier(); - qi->LoadGlobalBotScript(filename); - return qi->EventGlobalBot(evt, bot, init, data, extra_data, extra_pointers); - } - } else { - if (_global_bot_quest_status != QuestFailedToLoad) { - auto iter = _interfaces.find(_global_bot_quest_status); - return iter->second->EventGlobalBot(evt, bot, init, data, extra_data, extra_pointers); - } - } - - return 0; -} - -bool QuestParserCollection::BotHasQuestSubLocal(QuestEventID evt) { - if (_bot_quest_status == QuestUnloaded) { - std::string filename; - QuestInterface *qi = GetQIByBotQuest(filename); - if (qi) { - _bot_quest_status = qi->GetIdentifier(); - qi->LoadBotScript(filename); - return qi->BotHasQuestSub(evt); - } - } else if (_bot_quest_status != QuestFailedToLoad) { - auto iter = _interfaces.find(_bot_quest_status); - return iter->second->BotHasQuestSub(evt); - } - - return false; -} - -bool QuestParserCollection::BotHasQuestSubGlobal(QuestEventID evt) { - if (_global_bot_quest_status == QuestUnloaded) { - std::string filename; - QuestInterface *qi = GetQIByGlobalBotQuest(filename); - if (qi) { - _global_bot_quest_status = qi->GetIdentifier(); - qi->LoadGlobalBotScript(filename); - return qi->GlobalBotHasQuestSub(evt); - } - } else if (_global_bot_quest_status != QuestFailedToLoad) { - auto iter = _interfaces.find(_global_bot_quest_status); - return iter->second->GlobalBotHasQuestSub(evt); - } - - return false; -} - -bool QuestParserCollection::BotHasQuestSub(QuestEventID evt) { - return BotHasQuestSubLocal(evt) || BotHasQuestSubGlobal(evt); -} - -QuestInterface *QuestParserCollection::GetQIByBotQuest(std::string &filename) { - if (!zone || !zone->IsLoaded()) { - return nullptr; - } - - // first look for /quests/zone/bot_v[instance_version].ext (precedence) - filename = fmt::format("{}/{}/bot_v{}", path.GetQuestsPath(), zone->GetShortName(), zone->GetInstanceVersion()); - std::string tmp; - FILE *f = nullptr; - - auto iter = _load_precedence.begin(); - while (iter != _load_precedence.end()) { - auto ext = _extensions.find((*iter)->GetIdentifier()); - - tmp = fmt::format("{}.{}", filename, ext->second); - - f = fopen(tmp.c_str(), "r"); - if (f) { - fclose(f); - filename = tmp; - return (*iter); - } - - ++iter; - } - - // second look for /quests/zone/bot.ext (precedence) - filename = fmt::format("{}/{}/bot", path.GetQuestsPath(), zone->GetShortName()); - - iter = _load_precedence.begin(); - while(iter != _load_precedence.end()) { - auto ext = _extensions.find((*iter)->GetIdentifier()); - - tmp = fmt::format("{}.{}", filename, ext->second); - - f = fopen(tmp.c_str(), "r"); - if (f) { - fclose(f); - filename = tmp; - return (*iter); - } - - ++iter; - } - - // third look for /quests/global/bot.ext (precedence) - filename = fmt::format("{}/{}/bot", path.GetQuestsPath(), QUEST_GLOBAL_DIRECTORY); - iter = _load_precedence.begin(); - while (iter != _load_precedence.end()) { - auto ext = _extensions.find((*iter)->GetIdentifier()); - - tmp = fmt::format("{}.{}", filename, ext->second); - - f = fopen(tmp.c_str(), "r"); - if (f) { - fclose(f); - filename = tmp; - return (*iter); - } - - ++iter; - } - - return nullptr; -} - -QuestInterface *QuestParserCollection::GetQIByGlobalBotQuest(std::string &filename) { - // first look for /quests/global/global_bot.ext (precedence) - filename = fmt::format("{}/{}/global_bot", path.GetQuestsPath(), QUEST_GLOBAL_DIRECTORY); - std::string tmp; - FILE *f = nullptr; - - auto iter = _load_precedence.begin(); - while (iter != _load_precedence.end()) { - auto ext = _extensions.find((*iter)->GetIdentifier()); - - tmp = fmt::format("{}.{}", filename, ext->second); - - f = fopen(tmp.c_str(), "r"); - if (f) { - fclose(f); - filename = tmp; - return (*iter); - } - - ++iter; - } - - return nullptr; + LogInfo("Loaded [{}] Perl Event Export Settings", l.size()); } diff --git a/zone/quest_parser_collection.h b/zone/quest_parser_collection.h index 1c68eab51..30997c709 100644 --- a/zone/quest_parser_collection.h +++ b/zone/quest_parser_collection.h @@ -59,33 +59,66 @@ public: QuestParserCollection(); ~QuestParserCollection(); - void RegisterQuestInterface(QuestInterface *qi, std::string ext); - void UnRegisterQuestInterface(QuestInterface *qi, std::string ext); + void RegisterQuestInterface(QuestInterface* qi, std::string ext); void ClearInterfaces(); void AddVar(std::string name, std::string val); void Init(); void ReloadQuests(bool reset_timers = true); - void RemoveEncounter(const std::string name); + 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 BotHasQuestSub(QuestEventID evt); + bool HasQuestSub(uint32 npc_id, QuestEventID event_id); + bool PlayerHasQuestSub(QuestEventID event_id); + bool SpellHasQuestSub(uint32 spell_id, QuestEventID event_id); + bool ItemHasQuestSub(EQ::ItemInstance* inst, QuestEventID event_id); + bool BotHasQuestSub(QuestEventID event_id); - int EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers = nullptr); - int EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers = nullptr); - int EventItem(QuestEventID evt, Client *client, EQ::ItemInstance *item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers = nullptr); - int EventSpell(QuestEventID evt, Mob* mob, Client *client, uint32 spell_id, std::string data, uint32 extra_data, - std::vector *extra_pointers = nullptr); - int EventEncounter(QuestEventID evt, std::string encounter_name, std::string data, uint32 extra_data, - std::vector *extra_pointers = nullptr); + int EventNPC( + QuestEventID event_id, + NPC* npc, + Mob* init, + std::string data, + uint32 extra_data, + std::vector* extra_pointers = nullptr + ); + + int EventPlayer( + QuestEventID event_id, + Client* client, + std::string data, + uint32 extra_data, + std::vector* extra_pointers = nullptr + ); + + int EventItem( + QuestEventID event_id, + Client* client, + EQ::ItemInstance* inst, + Mob* mob, + std::string data, + uint32 extra_data, + std::vector* extra_pointers = nullptr + ); + + int EventSpell( + QuestEventID event_id, + Mob* mob, + Client* client, + uint32 spell_id, + std::string data, + uint32 extra_data, + std::vector* extra_pointers = nullptr + ); + + int EventEncounter( + QuestEventID event_id, + std::string encounter_name, + std::string data, + uint32 extra_data, + std::vector* extra_pointers = nullptr + ); int EventBot( - QuestEventID evt, + QuestEventID event_id, Bot *bot, Mob *init, std::string data, @@ -117,32 +150,63 @@ public: void LoadPerlEventExportSettings(PerlEventExportSettings* s); 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); - bool BotHasQuestSubLocal(QuestEventID evt); - bool BotHasQuestSubGlobal(QuestEventID evt); + bool HasQuestSubLocal(uint32 npc_id, QuestEventID event_id); + bool HasQuestSubGlobal(QuestEventID event_id); + bool NPCHasEncounterSub(uint32 npc_id, QuestEventID event_id); + bool PlayerHasQuestSubLocal(QuestEventID event_id); + bool PlayerHasQuestSubGlobal(QuestEventID event_id); + bool PlayerHasEncounterSub(QuestEventID event_id); + bool SpellHasEncounterSub(uint32 spell_id, QuestEventID event_id); + bool ItemHasEncounterSub(EQ::ItemInstance* inst, QuestEventID event_id); + bool HasEncounterSub(QuestEventID event_id, const std::string& package_name); + bool BotHasQuestSubLocal(QuestEventID event_id); + bool BotHasQuestSubGlobal(QuestEventID event_id); + + int EventNPCLocal( + QuestEventID event_id, + NPC* npc, + Mob* init, + std::string data, + uint32 extra_data, + std::vector* extra_pointers + ); + + int EventNPCGlobal( + QuestEventID event_id, + NPC* npc, + Mob* init, + std::string data, + uint32 extra_data, + std::vector* extra_pointers + ); + + int EventPlayerLocal( + QuestEventID event_id, + Client* client, + std::string data, + uint32 extra_data, + std::vector* extra_pointers + ); + + int EventPlayerGlobal( + QuestEventID event_id, + Client* client, + std::string data, + uint32 extra_data, + std::vector* extra_pointers + ); - 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); - int EventPlayerLocal(QuestEventID evt, Client *client, std::string data, uint32 extra_data, std::vector *extra_pointers); - int EventPlayerGlobal(QuestEventID evt, Client *client, std::string data, uint32 extra_data, std::vector *extra_pointers); int EventBotLocal( - QuestEventID evt, + QuestEventID event_id, Bot *bot, Mob *init, std::string data, uint32 extra_data, std::vector *extra_pointers ); + int EventBotGlobal( - QuestEventID evt, + QuestEventID event_id, Bot *bot, Mob *init, std::string data, @@ -150,47 +214,74 @@ private: std::vector *extra_pointers ); - QuestInterface *GetQIByNPCQuest(uint32 npcid, std::string &filename); - QuestInterface *GetQIByGlobalNPCQuest(std::string &filename); - QuestInterface *GetQIByPlayerQuest(std::string &filename); - QuestInterface *GetQIByGlobalPlayerQuest(std::string &filename); - QuestInterface *GetQIBySpellQuest(uint32 spell_id, std::string &filename); - QuestInterface *GetQIByItemQuest(std::string item_script, std::string &filename); - QuestInterface *GetQIByEncounterQuest(std::string encounter_name, std::string &filename); - QuestInterface *GetQIByBotQuest(std::string &filename); - QuestInterface *GetQIByGlobalBotQuest(std::string &filename); + QuestInterface* GetQIByNPCQuest(uint32 npc_id, std::string& filename); + QuestInterface* GetQIByGlobalNPCQuest(std::string& filename); + QuestInterface* GetQIByPlayerQuest(std::string& filename); + QuestInterface* GetQIByGlobalPlayerQuest(std::string& filename); + QuestInterface* GetQIBySpellQuest(uint32 spell_id, std::string& filename); + QuestInterface* GetQIByItemQuest(std::string item_script, std::string& filename); + QuestInterface* GetQIByEncounterQuest(std::string encounter_name, std::string& filename); + QuestInterface* GetQIByBotQuest(std::string& filename); + QuestInterface* GetQIByGlobalBotQuest(std::string& filename); - int DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); - int DispatchEventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers); - int DispatchEventItem(QuestEventID evt, Client *client, EQ::ItemInstance *item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers); - int DispatchEventSpell(QuestEventID evt, Mob* mob, Client *client, uint32 spell_id, std::string data, uint32 extra_data, - std::vector *extra_pointers); - int DispatchEventBot( - QuestEventID evt, - Bot *bot, - Mob *init, + int DispatchEventNPC( + QuestEventID event_id, + NPC* npc, + Mob* init, std::string data, uint32 extra_data, - std::vector *extra_pointers + std::vector* extra_pointers + ); + + int DispatchEventPlayer( + QuestEventID event_id, + Client* client, + std::string data, + uint32 extra_data, + std::vector* extra_pointers + ); + + int DispatchEventItem( + QuestEventID event_id, + Client* client, + EQ::ItemInstance* inst, + Mob* mob, + std::string data, + uint32 extra_data, + std::vector* extra_pointers + ); + + int DispatchEventSpell( + QuestEventID event_id, + Mob* mob, + Client* client, + uint32 spell_id, + std::string data, + uint32 extra_data, + std::vector* extra_pointers + ); + + int DispatchEventBot( + QuestEventID event_id, + Bot* bot, + Mob* init, + std::string data, + uint32 extra_data, + std::vector* extra_pointers ); std::map _interfaces; - std::map _extensions; - std::list _load_precedence; + std::map _extensions; + std::list _load_precedence; - //0x00 = Unloaded - //0xFFFFFFFF = Failed to Load - std::map _npc_quest_status; - uint32 _global_npc_quest_status; - uint32 _player_quest_status; - uint32 _global_player_quest_status; - uint32 _bot_quest_status; - uint32 _global_bot_quest_status; - std::map _spell_quest_status; - std::map _item_quest_status; + std::map _npc_quest_status; + uint32 _global_npc_quest_status; + uint32 _player_quest_status; + uint32 _global_player_quest_status; + uint32 _bot_quest_status; + uint32 _global_bot_quest_status; + std::map _spell_quest_status; + std::map _item_quest_status; std::map _encounter_quest_status; };