[Feature] Add Zone Scripting Capabilities

This commit is contained in:
Kinglykrab
2025-05-22 23:41:47 -04:00
parent f7775c7a75
commit 54c53ce389
8 changed files with 823 additions and 225 deletions
+196 -184
View File
@@ -278,6 +278,7 @@ int PerlembParser::EventCommon(
EQ::ItemInstance* inst, EQ::ItemInstance* inst,
const SPDat_Spell_Struct* spell, const SPDat_Spell_Struct* spell,
Mob* mob, Mob* mob,
Zone* zone,
uint32 extra_data, uint32 extra_data,
bool is_global, bool is_global,
std::vector<std::any>* extra_pointers std::vector<std::any>* extra_pointers
@@ -287,52 +288,22 @@ int PerlembParser::EventCommon(
return 0; return 0;
} }
bool is_player_quest = false; QuestType quest_type = GetQuestTypes(
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_merc_quest = false;
bool is_global_merc_quest = false;
bool is_item_quest = false;
bool is_spell_quest = false;
std::string package_name;
GetQuestTypes(
is_player_quest,
is_global_player_quest,
is_bot_quest,
is_global_bot_quest,
is_merc_quest,
is_global_merc_quest,
is_global_npc_quest,
is_item_quest,
is_spell_quest,
event_id, event_id,
npc_mob, npc_mob,
inst, inst,
mob, mob,
zone,
is_global is_global
); );
GetQuestPackageName( std::string package_name = GetQuestPackageName(
is_player_quest, quest_type,
is_global_player_quest,
is_bot_quest,
is_global_bot_quest,
is_merc_quest,
is_global_merc_quest,
is_global_npc_quest,
is_item_quest,
is_spell_quest,
package_name,
event_id, event_id,
object_id, object_id,
data, data,
npc_mob, npc_mob,
inst, inst
is_global
); );
const std::string& sub_name = QuestEventSubroutines[event_id]; const std::string& sub_name = QuestEventSubroutines[event_id];
@@ -348,15 +319,7 @@ int PerlembParser::EventCommon(
/* Check for QGlobal export event enable */ /* Check for QGlobal export event enable */
if (parse->perl_event_export_settings[event_id].qglobals) { if (parse->perl_event_export_settings[event_id].qglobals) {
ExportQGlobals( ExportQGlobals(
is_player_quest, quest_type,
is_global_player_quest,
is_bot_quest,
is_global_bot_quest,
is_merc_quest,
is_global_merc_quest,
is_global_npc_quest,
is_item_quest,
is_spell_quest,
package_name, package_name,
npc_mob, npc_mob,
mob, mob,
@@ -367,15 +330,7 @@ int PerlembParser::EventCommon(
/* Check for Mob export event enable */ /* Check for Mob export event enable */
if (parse->perl_event_export_settings[event_id].mob) { if (parse->perl_event_export_settings[event_id].mob) {
ExportMobVariables( ExportMobVariables(
is_player_quest, quest_type,
is_global_player_quest,
is_bot_quest,
is_global_bot_quest,
is_merc_quest,
is_global_merc_quest,
is_global_npc_quest,
is_item_quest,
is_spell_quest,
package_name, package_name,
mob, mob,
npc_mob npc_mob
@@ -397,19 +352,24 @@ int PerlembParser::EventCommon(
ExportEventVariables(package_name, event_id, object_id, data, npc_mob, inst, mob, extra_data, extra_pointers); ExportEventVariables(package_name, event_id, object_id, data, npc_mob, inst, mob, extra_data, extra_pointers);
} }
if (is_player_quest || is_global_player_quest) { if (quest_type == QuestType::Player || quest_type == QuestType::PlayerGlobal) {
return SendCommands(package_name.c_str(), QuestEventSubroutines[event_id], 0, mob, mob, nullptr, nullptr); return SendCommands(package_name.c_str(), QuestEventSubroutines[event_id], 0, mob, mob, nullptr, nullptr);
} else if (is_bot_quest || is_global_bot_quest || is_merc_quest || is_global_merc_quest) { } else if (
quest_type == QuestType::Bot ||
quest_type == QuestType::BotGlobal ||
quest_type == QuestType::Merc ||
quest_type == QuestType::MercGlobal
) {
return SendCommands(package_name.c_str(), QuestEventSubroutines[event_id], 0, npc_mob, mob, nullptr, nullptr); return SendCommands(package_name.c_str(), QuestEventSubroutines[event_id], 0, npc_mob, mob, nullptr, nullptr);
} else if (is_item_quest) { } else if (quest_type == QuestType::Item || quest_type == QuestType::ItemGlobal) {
return SendCommands(package_name.c_str(), QuestEventSubroutines[event_id], 0, mob, mob, inst, nullptr); return SendCommands(package_name.c_str(), QuestEventSubroutines[event_id], 0, mob, mob, inst, nullptr);
} else if (is_spell_quest) { } else if (quest_type == QuestType::Spell || quest_type == QuestType::SpellGlobal) {
if (mob) { if (mob) {
return SendCommands(package_name.c_str(), QuestEventSubroutines[event_id], 0, mob, mob, nullptr, spell); return SendCommands(package_name.c_str(), QuestEventSubroutines[event_id], 0, mob, mob, nullptr, spell);
} else { } else {
return SendCommands(package_name.c_str(), QuestEventSubroutines[event_id], 0, npc_mob, mob, nullptr, spell); return SendCommands(package_name.c_str(), QuestEventSubroutines[event_id], 0, npc_mob, mob, nullptr, spell);
} }
} else { } else if (quest_type == QuestType::NPC || quest_type == QuestType::NPCGlobal) {
return SendCommands( return SendCommands(
package_name.c_str(), package_name.c_str(),
QuestEventSubroutines[event_id], QuestEventSubroutines[event_id],
@@ -439,6 +399,7 @@ int PerlembParser::EventNPC(
nullptr, nullptr,
nullptr, nullptr,
mob, mob,
nullptr,
extra_data, extra_data,
false, false,
extra_pointers extra_pointers
@@ -462,6 +423,7 @@ int PerlembParser::EventGlobalNPC(
nullptr, nullptr,
nullptr, nullptr,
mob, mob,
nullptr,
extra_data, extra_data,
true, true,
extra_pointers extra_pointers
@@ -484,6 +446,7 @@ int PerlembParser::EventPlayer(
nullptr, nullptr,
nullptr, nullptr,
client, client,
nullptr,
extra_data, extra_data,
false, false,
extra_pointers extra_pointers
@@ -506,6 +469,7 @@ int PerlembParser::EventGlobalPlayer(
nullptr, nullptr,
nullptr, nullptr,
client, client,
nullptr,
extra_data, extra_data,
true, true,
extra_pointers extra_pointers
@@ -534,6 +498,7 @@ int PerlembParser::EventItem(
inst, inst,
nullptr, nullptr,
client, client,
nullptr,
extra_data, extra_data,
false, false,
extra_pointers extra_pointers
@@ -558,6 +523,7 @@ int PerlembParser::EventSpell(
nullptr, nullptr,
&spells[spell_id], &spells[spell_id],
client, client,
nullptr,
extra_data, extra_data,
false, false,
extra_pointers extra_pointers
@@ -1192,20 +1158,12 @@ void PerlembParser::MapFunctions()
#endif // EMBPERL_XS_CLASSES #endif // EMBPERL_XS_CLASSES
} }
void PerlembParser::GetQuestTypes( QuestType PerlembParser::GetQuestTypes(
bool& is_player_quest,
bool& is_global_player_quest,
bool& is_bot_quest,
bool& is_global_bot_quest,
bool& is_merc_quest,
bool& is_global_merc_quest,
bool& is_global_npc_quest,
bool& is_item_quest,
bool& is_spell_quest,
QuestEventID event_id, QuestEventID event_id,
Mob* npc_mob, Mob* npc_mob,
EQ::ItemInstance* inst, EQ::ItemInstance* inst,
Mob* mob, Mob* mob,
Zone* zone,
bool is_global bool is_global
) )
{ {
@@ -1219,100 +1177,72 @@ void PerlembParser::GetQuestTypes(
event_id == EVENT_SPELL_FADE || event_id == EVENT_SPELL_FADE ||
event_id == EVENT_SPELL_EFFECT_TRANSLOCATE_COMPLETE event_id == EVENT_SPELL_EFFECT_TRANSLOCATE_COMPLETE
) { ) {
is_spell_quest = true; return is_global ? QuestType::SpellGlobal : QuestType::Spell;
} else { } else {
if (npc_mob) { if (npc_mob) {
if (!inst) { if (!inst) {
if (is_global) { if (npc_mob->IsBot()) {
if (npc_mob->IsBot()) { return is_global ? QuestType::BotGlobal : QuestType::Bot;
is_global_bot_quest = true; } else if (npc_mob->IsMerc()) {
} else if (npc_mob->IsMerc()) { return is_global ? QuestType::MercGlobal : QuestType::Merc;
is_global_merc_quest = true;
}
} else {
if (npc_mob->IsBot()) {
is_bot_quest = true;
} else if (npc_mob->IsMerc()) {
is_merc_quest = true;
}
} }
} else { } else {
is_item_quest = true; return is_global ? QuestType::ItemGlobal : QuestType::Item;
} }
} else if (!npc_mob && mob) { } else if (!npc_mob && mob) {
if (!inst) { if (!inst) {
if (is_global) { if (mob->IsClient()) {
if (mob->IsClient()) { return is_global ? QuestType::PlayerGlobal : QuestType::Player;
is_global_player_quest = true;
}
} else {
if (mob->IsClient()) {
is_player_quest = true;
}
} }
} else { } else {
is_item_quest = true; return is_global ? QuestType::ItemGlobal : QuestType::Item;
} }
} else if (zone) {
return is_global ? QuestType::ZoneGlobal : QuestType::Zone;
} }
} }
} }
void PerlembParser::GetQuestPackageName( std::string PerlembParser::GetQuestPackageName(
bool& is_player_quest, QuestType quest_type,
bool& is_global_player_quest,
bool& is_bot_quest,
bool& is_global_bot_quest,
bool& is_merc_quest,
bool& is_global_merc_quest,
bool& is_global_npc_quest,
bool& is_item_quest,
bool& is_spell_quest,
std::string& package_name,
QuestEventID event_id, QuestEventID event_id,
uint32 object_id, uint32 object_id,
const char* data, const char* data,
Mob* npc_mob, Mob* npc_mob,
EQ::ItemInstance* inst, EQ::ItemInstance* inst
bool is_global
) )
{ {
if ( if (quest_type == QuestType::NPC) {
!is_player_quest && return fmt::format("qst_npc_{}", npc_mob->GetNPCTypeID());
!is_global_player_quest && } else if (quest_type == QuestType::NPCGlobal) {
!is_bot_quest && return "qst_global_npc";
!is_global_bot_quest && } else if (quest_type == QuestType::Item || quest_type == QuestType::ItemGlobal) {
!is_merc_quest &&
!is_global_merc_quest &&
!is_item_quest &&
!is_spell_quest
) {
if (is_global) {
is_global_npc_quest = true;
package_name = "qst_global_npc";
} else {
package_name = fmt::format("qst_npc_{}", npc_mob->GetNPCTypeID());
}
} else if (is_item_quest) {
if (!inst) { if (!inst) {
return; return "";
} }
package_name = fmt::format("qst_item_{}", inst->GetID()); return fmt::format("qst_item_{}", inst->GetID());
} else if (is_player_quest) { } else if (quest_type == QuestType::Player) {
package_name = "qst_player"; return "qst_player";
} else if (is_global_player_quest) { } else if (quest_type == QuestType::PlayerGlobal) {
package_name = "qst_global_player"; return "qst_global_player";
} else if (is_bot_quest) { } else if (quest_type == QuestType::Bot) {
package_name = "qst_bot"; return "qst_bot";
} else if (is_global_bot_quest) { } else if (quest_type == QuestType::BotGlobal) {
package_name = "qst_global_bot"; return "qst_global_bot";
} else if (is_merc_quest) { } else if (quest_type == QuestType::Merc) {
package_name = "qst_merc"; return "qst_merc";
} else if (is_global_merc_quest) { } else if (quest_type == QuestType::MercGlobal) {
package_name = "qst_global_merc"; return "qst_global_merc";
} else { } else if (quest_type == QuestType::Spell || quest_type == QuestType::SpellGlobal) {
package_name = fmt::format("qst_spell_{}", object_id); return fmt::format("qst_spell_{}", object_id);
} else if (quest_type == QuestType::Zone) {
return "qst_zone";
} else if (quest_type == QuestType::ZoneGlobal) {
return "qst_global_zone";
} }
return "";
} }
void PerlembParser::ExportCharID(const std::string& package_name, int& char_id, Mob* npc_mob, Mob* mob) void PerlembParser::ExportCharID(const std::string& package_name, int& char_id, Mob* npc_mob, Mob* mob)
@@ -1331,15 +1261,7 @@ void PerlembParser::ExportCharID(const std::string& package_name, int& char_id,
} }
void PerlembParser::ExportQGlobals( void PerlembParser::ExportQGlobals(
bool is_player_quest, QuestType quest_type,
bool is_global_player_quest,
bool is_bot_quest,
bool is_global_bot_quest,
bool is_merc_quest,
bool is_global_merc_quest,
bool is_global_npc_quest,
bool is_item_quest,
bool is_spell_quest,
std::string& package_name, std::string& package_name,
Mob* npc_mob, Mob* npc_mob,
Mob* mob, Mob* mob,
@@ -1347,16 +1269,7 @@ void PerlembParser::ExportQGlobals(
) )
{ {
//NPC quest //NPC quest
if ( if (quest_type == QuestType::NPC || quest_type == QuestType::NPCGlobal) {
!is_player_quest &&
!is_global_player_quest &&
!is_bot_quest &&
!is_global_bot_quest &&
!is_merc_quest &&
!is_global_merc_quest &&
!is_item_quest &&
!is_spell_quest
) {
//only export for npcs that are global enabled. //only export for npcs that are global enabled.
if (npc_mob && npc_mob->GetQglobal()) { if (npc_mob && npc_mob->GetQglobal()) {
std::map<std::string, std::string> globhash; std::map<std::string, std::string> globhash;
@@ -1485,15 +1398,7 @@ void PerlembParser::ExportQGlobals(
} }
void PerlembParser::ExportMobVariables( void PerlembParser::ExportMobVariables(
bool is_player_quest, QuestType quest_type,
bool is_global_player_quest,
bool is_bot_quest,
bool is_global_bot_quest,
bool is_merc_quest,
bool is_global_merc_quest,
bool is_global_npc_quest,
bool is_item_quest,
bool is_spell_quest,
std::string& package_name, std::string& package_name,
Mob* mob, Mob* mob,
Mob* npc_mob Mob* npc_mob
@@ -1511,15 +1416,7 @@ void PerlembParser::ExportMobVariables(
ExportVar(package_name.c_str(), "bot_owner_char_id", mob->CastToBot()->GetBotOwnerCharacterID()); ExportVar(package_name.c_str(), "bot_owner_char_id", mob->CastToBot()->GetBotOwnerCharacterID());
} }
if ( if (quest_type == QuestType::NPC || quest_type == QuestType::NPCGlobal) {
!is_player_quest &&
!is_global_player_quest &&
!is_bot_quest &&
!is_global_bot_quest &&
!is_merc_quest &&
!is_global_merc_quest &&
!is_item_quest
) {
if (mob && mob->IsClient() && npc_mob && npc_mob->IsNPC()) { if (mob && mob->IsClient() && npc_mob && npc_mob->IsNPC()) {
Client* c = mob->CastToClient(); Client* c = mob->CastToClient();
@@ -1543,16 +1440,7 @@ void PerlembParser::ExportMobVariables(
ExportVar(package_name.c_str(), "userid", mob->GetID()); ExportVar(package_name.c_str(), "userid", mob->GetID());
} }
if ( if (quest_type == QuestType::NPC || quest_type == QuestType::NPCGlobal) {
!is_player_quest &&
!is_global_player_quest &&
!is_bot_quest &&
!is_global_bot_quest &&
!is_merc_quest &&
!is_global_merc_quest &&
!is_item_quest &&
!is_spell_quest
) {
if (npc_mob->IsNPC()) { if (npc_mob->IsNPC()) {
ExportVar(package_name.c_str(), "mname", npc_mob->GetName()); ExportVar(package_name.c_str(), "mname", npc_mob->GetName());
ExportVar(package_name.c_str(), "mobid", npc_mob->GetID()); ExportVar(package_name.c_str(), "mobid", npc_mob->GetID());
@@ -2648,6 +2536,7 @@ int PerlembParser::EventBot(
nullptr, nullptr,
nullptr, nullptr,
mob, mob,
nullptr,
extra_data, extra_data,
false, false,
extra_pointers extra_pointers
@@ -2671,6 +2560,7 @@ int PerlembParser::EventGlobalBot(
nullptr, nullptr,
nullptr, nullptr,
mob, mob,
nullptr,
extra_data, extra_data,
true, true,
extra_pointers extra_pointers
@@ -2768,6 +2658,7 @@ int PerlembParser::EventMerc(
nullptr, nullptr,
nullptr, nullptr,
mob, mob,
nullptr,
extra_data, extra_data,
false, false,
extra_pointers extra_pointers
@@ -2791,6 +2682,127 @@ int PerlembParser::EventGlobalMerc(
nullptr, nullptr,
nullptr, nullptr,
mob, mob,
nullptr,
extra_data,
true,
extra_pointers
);
}
void PerlembParser::LoadZoneScript(std::string filename)
{
if (!perl || zone_quest_status_ != questUnloaded) {
return;
}
try {
perl->eval_file("qst_zone", filename.c_str());
} catch (std::string e) {
AddError(
fmt::format(
"Error Compiling Zone Quest File [{}] Error [{}]",
filename,
e
)
);
zone_quest_status_ = questFailedToLoad;
return;
}
zone_quest_status_ = questLoaded;
}
void PerlembParser::LoadGlobalZoneScript(std::string filename)
{
if (!perl || global_zone_quest_status_ != questUnloaded) {
return;
}
try {
perl->eval_file("qst_global_zone", filename.c_str());
} catch (std::string e) {
AddError(
fmt::format(
"Error Compiling Global Zone uest File [{}] Error [{}]",
filename,
e
)
);
global_zone_quest_status_ = questFailedToLoad;
return;
}
global_zone_quest_status_ = questLoaded;
}
bool PerlembParser::ZoneHasQuestSub(QuestEventID event_id)
{
if (
!perl ||
zone_quest_status_ != questLoaded ||
event_id >= _LargestEventID
) {
return false;
}
return perl->SubExists("qst_zone", QuestEventSubroutines[event_id]);
}
bool PerlembParser::GlobalZoneHasQuestSub(QuestEventID event_id)
{
if (
!perl ||
global_zone_quest_status_ != questLoaded ||
event_id >= _LargestEventID
) {
return false;
}
return perl->SubExists("qst_global_zone", QuestEventSubroutines[event_id]);
}
int PerlembParser::EventZone(
QuestEventID event_id,
Zone* zone,
std::string data,
uint32 extra_data,
std::vector<std::any>* extra_pointers
)
{
return EventCommon(
event_id,
0,
data.c_str(),
nullptr,
nullptr,
nullptr,
nullptr,
zone,
extra_data,
false,
extra_pointers
);
}
int PerlembParser::EventGlobalZone(
QuestEventID event_id,
Zone* zone,
std::string data,
uint32 extra_data,
std::vector<std::any>* extra_pointers
)
{
return EventCommon(
event_id,
0,
data.c_str(),
nullptr,
nullptr,
nullptr,
nullptr,
zone,
extra_data, extra_data,
true, true,
extra_pointers extra_pointers
+47 -41
View File
@@ -41,6 +41,23 @@ typedef enum {
questFailedToLoad questFailedToLoad
} PerlQuestStatus; } PerlQuestStatus;
enum class QuestType {
Bot,
BotGlobal,
Item,
ItemGlobal,
Merc,
MercGlobal,
NPC,
NPCGlobal,
Player,
PlayerGlobal,
Spell,
SpellGlobal,
Zone,
ZoneGlobal
};
class PerlembParser : public QuestInterface { class PerlembParser : public QuestInterface {
public: public:
PerlembParser(); PerlembParser();
@@ -136,6 +153,22 @@ public:
std::vector<std::any>* extra_pointers std::vector<std::any>* extra_pointers
); );
virtual int EventZone(
QuestEventID event_id,
Zone* zone,
std::string data,
uint32 extra_data,
std::vector<std::any>* extra_pointers
);
virtual int EventGlobalZone(
QuestEventID event_id,
Zone* zone,
std::string data,
uint32 extra_data,
std::vector<std::any>* extra_pointers
);
virtual bool HasQuestSub(uint32 npc_id, QuestEventID event_id); virtual bool HasQuestSub(uint32 npc_id, QuestEventID event_id);
virtual bool HasGlobalQuestSub(QuestEventID event_id); virtual bool HasGlobalQuestSub(QuestEventID event_id);
virtual bool PlayerHasQuestSub(QuestEventID event_id); virtual bool PlayerHasQuestSub(QuestEventID event_id);
@@ -146,6 +179,8 @@ public:
virtual bool GlobalBotHasQuestSub(QuestEventID event_id); virtual bool GlobalBotHasQuestSub(QuestEventID event_id);
virtual bool MercHasQuestSub(QuestEventID event_id); virtual bool MercHasQuestSub(QuestEventID event_id);
virtual bool GlobalMercHasQuestSub(QuestEventID event_id); virtual bool GlobalMercHasQuestSub(QuestEventID event_id);
virtual bool ZoneHasQuestSub(QuestEventID event_id);
virtual bool GlobalZoneHasQuestSub(QuestEventID event_id);
virtual void LoadNPCScript(std::string filename, int npc_id); virtual void LoadNPCScript(std::string filename, int npc_id);
virtual void LoadGlobalNPCScript(std::string filename); virtual void LoadGlobalNPCScript(std::string filename);
@@ -157,6 +192,8 @@ public:
virtual void LoadGlobalBotScript(std::string filename); virtual void LoadGlobalBotScript(std::string filename);
virtual void LoadMercScript(std::string filename); virtual void LoadMercScript(std::string filename);
virtual void LoadGlobalMercScript(std::string filename); virtual void LoadGlobalMercScript(std::string filename);
virtual void LoadZoneScript(std::string filename);
virtual void LoadGlobalZoneScript(std::string filename);
virtual void AddVar(std::string name, std::string val); virtual void AddVar(std::string name, std::string val);
virtual std::string GetVar(std::string name); virtual std::string GetVar(std::string name);
@@ -182,6 +219,7 @@ private:
EQ::ItemInstance* inst, EQ::ItemInstance* inst,
const SPDat_Spell_Struct* spell, const SPDat_Spell_Struct* spell,
Mob* mob, Mob* mob,
Zone* zone,
uint32 extra_data, uint32 extra_data,
bool is_global, bool is_global,
std::vector<std::any>* extra_pointers std::vector<std::any>* extra_pointers
@@ -199,54 +237,28 @@ private:
void MapFunctions(); void MapFunctions();
void GetQuestTypes( QuestType GetQuestTypes(
bool& is_player_quest,
bool& is_global_player_quest,
bool& is_bot_quest,
bool& is_global_bot_quest,
bool& is_merc_quest,
bool& is_global_merc_quest,
bool& is_global_npc_quest,
bool& is_item_quest,
bool& is_spell_quest,
QuestEventID event, QuestEventID event,
Mob* npc_mob, Mob* npc_mob,
EQ::ItemInstance* inst, EQ::ItemInstance* inst,
Mob* mob, Mob* mob,
Zone* zone,
bool is_global bool is_global
); );
void GetQuestPackageName( std::string GetQuestPackageName(
bool& is_player_quest, QuestType quest_type,
bool& is_global_player_quest,
bool& is_bot_quest,
bool& is_global_bot_quest,
bool& is_merc_quest,
bool& is_global_merc_quest,
bool& is_global_npc_quest,
bool& is_item_quest,
bool& is_spell_quest,
std::string& package_name,
QuestEventID event, QuestEventID event,
uint32 object_id, uint32 object_id,
const char* data, const char* data,
Mob* npc_mob, Mob* npc_mob,
EQ::ItemInstance* inst, EQ::ItemInstance* inst
bool is_global
); );
void ExportCharID(const std::string& package_name, int& char_id, Mob* npc_mob, Mob* mob); void ExportCharID(const std::string& package_name, int& char_id, Mob* npc_mob, Mob* mob);
void ExportQGlobals( void ExportQGlobals(
bool is_player_quest, QuestType quest_type,
bool is_global_player_quest,
bool is_bot_quest,
bool is_global_bot_quest,
bool is_merc_quest,
bool is_global_merc_quest,
bool is_global_npc_quest,
bool is_item_quest,
bool is_spell_quest,
std::string& package_name, std::string& package_name,
Mob* npc_mob, Mob* npc_mob,
Mob* mob, Mob* mob,
@@ -254,15 +266,7 @@ private:
); );
void ExportMobVariables( void ExportMobVariables(
bool is_player_quest, QuestType quest_type,
bool is_global_player_quest,
bool is_bot_quest,
bool is_global_bot_quest,
bool is_merc_quest,
bool is_global_merc_quest,
bool is_global_npc_quest,
bool is_item_quest,
bool is_spell_quest,
std::string& package_name, std::string& package_name,
Mob* mob, Mob* mob,
Mob* npc_mob Mob* npc_mob
@@ -295,6 +299,8 @@ private:
PerlQuestStatus global_bot_quest_status_; PerlQuestStatus global_bot_quest_status_;
PerlQuestStatus merc_quest_status_; PerlQuestStatus merc_quest_status_;
PerlQuestStatus global_merc_quest_status_; PerlQuestStatus global_merc_quest_status_;
PerlQuestStatus zone_quest_status_;
PerlQuestStatus global_zone_quest_status_;
SV* _empty_sv; SV* _empty_sv;
+54
View File
@@ -598,6 +598,51 @@ bool Perl_Zone_VariableExists(Zone* self, const std::string variable_name)
return self->VariableExists(variable_name); return self->VariableExists(variable_name);
} }
uint32 Perl_Zone_GetTimerDuration(Zone* self, std::string name)
{
return self->GetTimerDuration(name);
}
uint32 Perl_Zone_GetTimerRemainingTime(Zone* self, std::string name)
{
return self->GetTimerRemainingTime(name);
}
bool Perl_Zone_HasTimer(Zone* self, std::string name)
{
return self->HasTimer(name);
}
bool Perl_Zone_IsPausedTimer(Zone* self, std::string name)
{
return self->IsPausedTimer(name);
}
void Perl_Zone_PauseTimer(Zone* self, std::string name)
{
self->PauseTimer(name);
}
void Perl_Zone_ResumeTimer(Zone* self, std::string name)
{
self->ResumeTimer(name);
}
void Perl_Zone_SetTimer(Zone* self, std::string name, uint32 duration)
{
self->SetTimer(name, duration);
}
void Perl_Zone_StopTimer(Zone* self, std::string name)
{
self->StopTimer(name);
}
void Perl_Zone_StopAllTimers(Zone* self)
{
self->StopAllTimers();
}
void perl_register_zone() void perl_register_zone()
{ {
perl::interpreter perl(PERL_GET_THX); perl::interpreter perl(PERL_GET_THX);
@@ -689,6 +734,8 @@ void perl_register_zone()
package.add("GetSnowDuration", (int(*)(Zone*, uint8))&Perl_Zone_GetSnowDuration); package.add("GetSnowDuration", (int(*)(Zone*, uint8))&Perl_Zone_GetSnowDuration);
package.add("GetTimeType", &Perl_Zone_GetTimeType); package.add("GetTimeType", &Perl_Zone_GetTimeType);
package.add("GetTimeZone", &Perl_Zone_GetTimeZone); package.add("GetTimeZone", &Perl_Zone_GetTimeZone);
package.add("GetTimerDuration", &Perl_Zone_GetTimerDuration);
package.add("GetTimerRemainingTime", &Perl_Zone_GetTimerRemainingTime);
package.add("GetZoneDescription", &Perl_Zone_GetZoneDescription); package.add("GetZoneDescription", &Perl_Zone_GetZoneDescription);
package.add("GetZoneID", &Perl_Zone_GetZoneID); package.add("GetZoneID", &Perl_Zone_GetZoneID);
package.add("GetZoneType", &Perl_Zone_GetZoneType); package.add("GetZoneType", &Perl_Zone_GetZoneType);
@@ -701,12 +748,14 @@ void perl_register_zone()
package.add("GetZoneTotalBlockedSpells", &Perl_Zone_GetZoneTotalBlockedSpells); package.add("GetZoneTotalBlockedSpells", &Perl_Zone_GetZoneTotalBlockedSpells);
package.add("HasGraveyard", &Perl_Zone_HasGraveyard); package.add("HasGraveyard", &Perl_Zone_HasGraveyard);
package.add("HasMap", &Perl_Zone_HasMap); package.add("HasMap", &Perl_Zone_HasMap);
package.add("HasTimer", &Perl_Zone_HasTimer);
package.add("HasWaterMap", &Perl_Zone_HasWaterMap); package.add("HasWaterMap", &Perl_Zone_HasWaterMap);
package.add("HasWeather", &Perl_Zone_HasWeather); package.add("HasWeather", &Perl_Zone_HasWeather);
package.add("IsCity", &Perl_Zone_IsCity); package.add("IsCity", &Perl_Zone_IsCity);
package.add("IsHotzone", &Perl_Zone_IsHotzone); package.add("IsHotzone", &Perl_Zone_IsHotzone);
package.add("IsInstancePersistent", &Perl_Zone_IsInstancePersistent); package.add("IsInstancePersistent", &Perl_Zone_IsInstancePersistent);
package.add("IsIdleWhenEmpty", &Perl_Zone_IsIdleWhenEmpty); package.add("IsIdleWhenEmpty", &Perl_Zone_IsIdleWhenEmpty);
package.add("IsPausedTimer", &Perl_Zone_IsPausedTimer);
package.add("IsPVPZone", &Perl_Zone_IsPVPZone); package.add("IsPVPZone", &Perl_Zone_IsPVPZone);
package.add("IsRaining", &Perl_Zone_IsRaining); package.add("IsRaining", &Perl_Zone_IsRaining);
package.add("IsSnowing", &Perl_Zone_IsSnowing); package.add("IsSnowing", &Perl_Zone_IsSnowing);
@@ -715,8 +764,10 @@ void perl_register_zone()
package.add("IsStaticZone", &Perl_Zone_IsStaticZone); package.add("IsStaticZone", &Perl_Zone_IsStaticZone);
package.add("IsUCSServerAvailable", &Perl_Zone_IsUCSServerAvailable); package.add("IsUCSServerAvailable", &Perl_Zone_IsUCSServerAvailable);
package.add("IsWaterZone", &Perl_Zone_IsWaterZone); package.add("IsWaterZone", &Perl_Zone_IsWaterZone);
package.add("PauseTimer", &Perl_Zone_PauseTimer);
package.add("Repop", (void(*)(Zone*))&Perl_Zone_Repop); package.add("Repop", (void(*)(Zone*))&Perl_Zone_Repop);
package.add("Repop", (void(*)(Zone*, bool))&Perl_Zone_Repop); package.add("Repop", (void(*)(Zone*, bool))&Perl_Zone_Repop);
package.add("ResumeTimer", &Perl_Zone_ResumeTimer);
package.add("SetAAEXPModifier", &Perl_Zone_SetAAEXPModifier); package.add("SetAAEXPModifier", &Perl_Zone_SetAAEXPModifier);
package.add("SetAAEXPModifierByCharacterID", &Perl_Zone_SetAAEXPModifierByCharacterID); package.add("SetAAEXPModifierByCharacterID", &Perl_Zone_SetAAEXPModifierByCharacterID);
package.add("SetBucket", (void(*)(Zone*, const std::string, const std::string))&Perl_Zone_SetBucket); package.add("SetBucket", (void(*)(Zone*, const std::string, const std::string))&Perl_Zone_SetBucket);
@@ -726,7 +777,10 @@ void perl_register_zone()
package.add("SetInstanceTimer", &Perl_Zone_SetInstanceTimer); package.add("SetInstanceTimer", &Perl_Zone_SetInstanceTimer);
package.add("SetInstanceTimeRemaining", &Perl_Zone_SetInstanceTimeRemaining); package.add("SetInstanceTimeRemaining", &Perl_Zone_SetInstanceTimeRemaining);
package.add("SetIsHotzone", &Perl_Zone_SetIsHotzone); package.add("SetIsHotzone", &Perl_Zone_SetIsHotzone);
package.add("SetTimer", &Perl_Zone_SetTimer);
package.add("SetVariable", &Perl_Zone_SetVariable); package.add("SetVariable", &Perl_Zone_SetVariable);
package.add("StopTimer", &Perl_Zone_StopTimer);
package.add("StopAllTimers", &Perl_Zone_StopAllTimers);
package.add("ShowZoneGlobalLoot", &Perl_Zone_ShowZoneGlobalLoot); package.add("ShowZoneGlobalLoot", &Perl_Zone_ShowZoneGlobalLoot);
package.add("VariableExists", &Perl_Zone_VariableExists); package.add("VariableExists", &Perl_Zone_VariableExists);
} }
+45
View File
@@ -163,6 +163,28 @@ public:
return 0; return 0;
} }
virtual int EventZone(
QuestEventID event_id,
Zone* zone,
std::string data,
uint32 extra_data,
std::vector<std::any>* extra_pointers
)
{
return 0;
}
virtual int EventGlobalZone(
QuestEventID event_id,
Zone* zone,
std::string data,
uint32 extra_data,
std::vector<std::any>* extra_pointers
)
{
return 0;
}
virtual bool HasQuestSub(uint32 npc_id, QuestEventID event_id) virtual bool HasQuestSub(uint32 npc_id, QuestEventID event_id)
{ {
return false; return false;
@@ -223,6 +245,16 @@ public:
return false; return false;
} }
virtual bool ZoneHasQuestSub(QuestEventID event_id)
{
return false;
}
virtual bool GlobalZoneHasQuestSub(QuestEventID event_id)
{
return false;
}
virtual void LoadNPCScript(std::string filename, int npc_id) { } virtual void LoadNPCScript(std::string filename, int npc_id) { }
virtual void LoadGlobalNPCScript(std::string filename) { } virtual void LoadGlobalNPCScript(std::string filename) { }
virtual void LoadPlayerScript(std::string filename) { } virtual void LoadPlayerScript(std::string filename) { }
@@ -234,6 +266,8 @@ public:
virtual void LoadGlobalBotScript(std::string filename) { } virtual void LoadGlobalBotScript(std::string filename) { }
virtual void LoadMercScript(std::string filename) { } virtual void LoadMercScript(std::string filename) { }
virtual void LoadGlobalMercScript(std::string filename) { } virtual void LoadGlobalMercScript(std::string filename) { }
virtual void LoadZoneScript(std::string filename) { }
virtual void LoadGlobalZoneScript(std::string filename) { }
virtual int DispatchEventNPC( virtual int DispatchEventNPC(
QuestEventID event_id, QuestEventID event_id,
@@ -308,6 +342,17 @@ public:
return 0; return 0;
} }
virtual int DispatchEventZone(
QuestEventID event_id,
Zone* zone,
std::string data,
uint32 extra_data,
std::vector<std::any>* extra_pointers
)
{
return 0;
}
virtual void AddVar(std::string name, std::string val) { } virtual void AddVar(std::string name, std::string val) { }
virtual std::string GetVar(std::string name) virtual std::string GetVar(std::string name)
{ {
+219
View File
@@ -49,6 +49,8 @@ QuestParserCollection::QuestParserCollection()
_global_bot_quest_status = QuestUnloaded; _global_bot_quest_status = QuestUnloaded;
_merc_quest_status = QuestUnloaded; _merc_quest_status = QuestUnloaded;
_global_merc_quest_status = QuestUnloaded; _global_merc_quest_status = QuestUnloaded;
_zone_quest_status = QuestUnloaded;
_global_zone_quest_status = QuestUnloaded;
} }
QuestParserCollection::~QuestParserCollection() { } QuestParserCollection::~QuestParserCollection() { }
@@ -98,6 +100,8 @@ void QuestParserCollection::ReloadQuests(bool reset_timers)
_global_bot_quest_status = QuestUnloaded; _global_bot_quest_status = QuestUnloaded;
_merc_quest_status = QuestUnloaded; _merc_quest_status = QuestUnloaded;
_global_merc_quest_status = QuestUnloaded; _global_merc_quest_status = QuestUnloaded;
_zone_quest_status = QuestUnloaded;
_global_zone_quest_status = QuestUnloaded;
_spell_quest_status.clear(); _spell_quest_status.clear();
_item_quest_status.clear(); _item_quest_status.clear();
@@ -426,6 +430,49 @@ bool QuestParserCollection::MercHasQuestSub(QuestEventID event_id)
return MercHasQuestSubLocal(event_id) || MercHasQuestSubGlobal(event_id); return MercHasQuestSubLocal(event_id) || MercHasQuestSubGlobal(event_id);
} }
bool QuestParserCollection::ZoneHasQuestSubLocal(QuestEventID event_id)
{
if (_zone_quest_status == QuestUnloaded) {
std::string filename;
auto qi = GetQIByZoneQuest(filename);
if (qi) {
_zone_quest_status = qi->GetIdentifier();
qi->LoadZoneScript(filename);
return qi->ZoneHasQuestSub(event_id);
}
} else if (_zone_quest_status != QuestFailedToLoad) {
auto iter = _interfaces.find(_zone_quest_status);
return iter->second->ZoneHasQuestSub(event_id);
}
return false;
}
bool QuestParserCollection::ZoneHasQuestSubGlobal(QuestEventID event_id)
{
if (_global_zone_quest_status == QuestUnloaded) {
std::string filename;
auto qi = GetQIByGlobalZoneQuest(filename);
if (qi) {
_global_zone_quest_status = qi->GetIdentifier();
qi->LoadGlobalZoneScript(filename);
return qi->GlobalZoneHasQuestSub(event_id);
}
} else if (_global_zone_quest_status != QuestFailedToLoad) {
auto iter = _interfaces.find(_global_zone_quest_status);
return iter->second->GlobalZoneHasQuestSub(event_id);
}
return false;
}
bool QuestParserCollection::ZoneHasQuestSub(QuestEventID event_id)
{
return ZoneHasQuestSubLocal(event_id) || ZoneHasQuestSubGlobal(event_id);
}
int QuestParserCollection::EventNPC( int QuestParserCollection::EventNPC(
QuestEventID event_id, QuestEventID event_id,
NPC* npc, NPC* npc,
@@ -924,6 +971,83 @@ int QuestParserCollection::EventMercGlobal(
return 0; return 0;
} }
int QuestParserCollection::EventZone(
QuestEventID event_id,
Zone* zone,
std::string data,
uint32 extra_data,
std::vector<std::any>* extra_pointers
)
{
const int local_return = EventZoneLocal(event_id, zone, data, extra_data, extra_pointers);
const int global_return = EventZoneGlobal(event_id, zone, data, extra_data, extra_pointers);
const int default_return = DispatchEventZone(event_id, zone, 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::EventZoneLocal(
QuestEventID event_id,
Zone* zone,
std::string data,
uint32 extra_data,
std::vector<std::any>* extra_pointers
)
{
if (_zone_quest_status == QuestUnloaded) {
std::string filename;
auto qi = GetQIByZoneQuest(filename);
if (qi) {
_zone_quest_status = qi->GetIdentifier();
qi->LoadZoneScript(filename);
return qi->EventZone(event_id, zone, data, extra_data, extra_pointers);
}
} else {
if (_zone_quest_status != QuestFailedToLoad) {
auto iter = _interfaces.find(_zone_quest_status);
return iter->second->EventZone(event_id, zone, data, extra_data, extra_pointers);
}
}
return 0;
}
int QuestParserCollection::EventZoneGlobal(
QuestEventID event_id,
Zone* zone,
std::string data,
uint32 extra_data,
std::vector<std::any>* extra_pointers
)
{
if (_global_zone_quest_status == QuestUnloaded) {
std::string filename;
auto qi = GetQIByGlobalZoneQuest(filename);
if (qi) {
_global_zone_quest_status = qi->GetIdentifier();
qi->LoadGlobalZoneScript(filename);
return qi->EventGlobalZone(event_id, zone, data, extra_data, extra_pointers);
}
} else {
if (_global_zone_quest_status != QuestFailedToLoad) {
auto iter = _interfaces.find(_global_zone_quest_status);
return iter->second->EventGlobalZone(event_id, zone, data, extra_data, extra_pointers);
}
}
return 0;
}
QuestInterface* QuestParserCollection::GetQIByNPCQuest(uint32 npc_id, std::string& filename) QuestInterface* QuestParserCollection::GetQIByNPCQuest(uint32 npc_id, std::string& filename)
{ {
if (!zone) { if (!zone) {
@@ -1425,6 +1549,81 @@ QuestInterface* QuestParserCollection::GetQIByGlobalMercQuest(std::string& filen
return nullptr; return nullptr;
} }
QuestInterface* QuestParserCollection::GetQIByZoneQuest(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()
);
const std::string& zone_versioned_path = fmt::format(
"{}/{}/v{}",
path.GetQuestsPath(),
zone->GetShortName(),
zone->GetInstanceVersion()
);
std::vector<std::string> file_names = {
fmt::format("{}/zone", zone_versioned_path), // Local versioned by Instance Version ./quests/zone/v0/zone.ext
fmt::format("{}/zone_v{}", zone_path, zone->GetInstanceVersion()), // Local by Instance Version
fmt::format("{}/zone", zone_path), // Local
fmt::format("{}/zone", 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::GetQIByGlobalZoneQuest(std::string& filename)
{
if (!zone) {
return nullptr;
}
std::string file_name;
for (auto* e: _load_precedence) {
file_name = fmt::format(
"{}/{}/global_zone.{}",
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<std::string>& quest_errors) void QuestParserCollection::GetErrors(std::list<std::string>& quest_errors)
{ {
quest_errors.clear(); quest_errors.clear();
@@ -1561,6 +1760,26 @@ int QuestParserCollection::DispatchEventMerc(
return ret; return ret;
} }
int QuestParserCollection::DispatchEventZone(
QuestEventID event_id,
Zone* zone,
std::string data,
uint32 extra_data,
std::vector<std::any>* extra_pointers
)
{
int ret = 0;
for (const auto& e: _load_precedence) {
int i = e->DispatchEventZone(event_id, zone, data, extra_data, extra_pointers);
if (i != 0) {
ret = i;
}
}
return ret;
}
void QuestParserCollection::LoadPerlEventExportSettings(PerlEventExportSettings* s) void QuestParserCollection::LoadPerlEventExportSettings(PerlEventExportSettings* s)
{ {
for (int i = 0; i < _LargestEventID; i++) { for (int i = 0; i < _LargestEventID; i++) {
+39
View File
@@ -72,6 +72,7 @@ public:
bool ItemHasQuestSub(EQ::ItemInstance* inst, QuestEventID event_id); bool ItemHasQuestSub(EQ::ItemInstance* inst, QuestEventID event_id);
bool BotHasQuestSub(QuestEventID event_id); bool BotHasQuestSub(QuestEventID event_id);
bool MercHasQuestSub(QuestEventID event_id); bool MercHasQuestSub(QuestEventID event_id);
bool ZoneHasQuestSub(QuestEventID event_id);
int EventNPC( int EventNPC(
QuestEventID event_id, QuestEventID event_id,
@@ -172,6 +173,14 @@ public:
std::vector<std::any>* extra_pointers = nullptr std::vector<std::any>* extra_pointers = nullptr
); );
int EventZone(
QuestEventID event_id,
Zone* zone,
std::string data,
uint32 extra_data = 0,
std::vector<std::any>* extra_pointers = nullptr
);
void GetErrors(std::list<std::string> &quest_errors); void GetErrors(std::list<std::string> &quest_errors);
/* /*
@@ -209,6 +218,8 @@ private:
bool BotHasQuestSubGlobal(QuestEventID event_id); bool BotHasQuestSubGlobal(QuestEventID event_id);
bool MercHasQuestSubLocal(QuestEventID event_id); bool MercHasQuestSubLocal(QuestEventID event_id);
bool MercHasQuestSubGlobal(QuestEventID event_id); bool MercHasQuestSubGlobal(QuestEventID event_id);
bool ZoneHasQuestSubLocal(QuestEventID event_id);
bool ZoneHasQuestSubGlobal(QuestEventID event_id);
int EventNPCLocal( int EventNPCLocal(
QuestEventID event_id, QuestEventID event_id,
@@ -280,6 +291,22 @@ private:
std::vector<std::any>* extra_pointers std::vector<std::any>* extra_pointers
); );
int EventZoneLocal(
QuestEventID event_id,
Zone* zone,
std::string data,
uint32 extra_data,
std::vector<std::any>* extra_pointers
);
int EventZoneGlobal(
QuestEventID event_id,
Zone* zone,
std::string data,
uint32 extra_data,
std::vector<std::any>* extra_pointers
);
QuestInterface* GetQIByNPCQuest(uint32 npc_id, std::string& filename); QuestInterface* GetQIByNPCQuest(uint32 npc_id, std::string& filename);
QuestInterface* GetQIByGlobalNPCQuest(std::string& filename); QuestInterface* GetQIByGlobalNPCQuest(std::string& filename);
QuestInterface* GetQIByPlayerQuest(std::string& filename); QuestInterface* GetQIByPlayerQuest(std::string& filename);
@@ -291,6 +318,8 @@ private:
QuestInterface* GetQIByGlobalBotQuest(std::string& filename); QuestInterface* GetQIByGlobalBotQuest(std::string& filename);
QuestInterface* GetQIByMercQuest(std::string& filename); QuestInterface* GetQIByMercQuest(std::string& filename);
QuestInterface* GetQIByGlobalMercQuest(std::string& filename); QuestInterface* GetQIByGlobalMercQuest(std::string& filename);
QuestInterface* GetQIByZoneQuest(std::string& filename);
QuestInterface* GetQIByGlobalZoneQuest(std::string& filename);
int DispatchEventNPC( int DispatchEventNPC(
QuestEventID event_id, QuestEventID event_id,
@@ -347,6 +376,14 @@ private:
std::vector<std::any>* extra_pointers std::vector<std::any>* extra_pointers
); );
int DispatchEventZone(
QuestEventID event_id,
Zone* zone,
std::string data,
uint32 extra_data,
std::vector<std::any>* extra_pointers
);
std::map<uint32, QuestInterface*> _interfaces; std::map<uint32, QuestInterface*> _interfaces;
std::map<uint32, std::string> _extensions; std::map<uint32, std::string> _extensions;
std::list<QuestInterface*> _load_precedence; std::list<QuestInterface*> _load_precedence;
@@ -359,6 +396,8 @@ private:
uint32 _global_bot_quest_status; uint32 _global_bot_quest_status;
uint32 _merc_quest_status; uint32 _merc_quest_status;
uint32 _global_merc_quest_status; uint32 _global_merc_quest_status;
uint32 _zone_quest_status;
uint32 _global_zone_quest_status;
std::map<uint32, uint32> _spell_quest_status; std::map<uint32, uint32> _spell_quest_status;
std::map<uint32, uint32> _item_quest_status; std::map<uint32, uint32> _item_quest_status;
std::map<std::string, uint32> _encounter_quest_status; std::map<std::string, uint32> _encounter_quest_status;
+197
View File
@@ -1693,6 +1693,17 @@ bool Zone::Process() {
} }
} }
const bool has_timer_event = parse->ZoneHasQuestSub(EVENT_TIMER);
for (auto e : zone_timers) {
LogError("has_timer_event [{}]", has_timer_event ? "y" : "n");
if (e.timer_.Enabled() && e.timer_.Check()) {
if (has_timer_event) {
parse->EventZone(EVENT_TIMER, this, e.name);
}
}
}
mMovementManager->Process(); mMovementManager->Process();
return true; return true;
@@ -3301,4 +3312,190 @@ void Zone::ReloadMaps()
pathing = IPathfinder::Load(map_name); pathing = IPathfinder::Load(map_name);
} }
uint32 Zone::GetTimerDuration(std::string name)
{
const auto& e = std::find_if(
zone_timers.begin(),
zone_timers.end(),
[&name](ZoneTimer e) {
return e.name == name;
}
);
return e != zone_timers.end() ? e->timer_.GetDuration() : 0;
}
uint32 Zone::GetTimerRemainingTime(std::string name)
{
const auto& e = std::find_if(
zone_timers.begin(),
zone_timers.end(),
[&name](ZoneTimer e) {
return e.name == name;
}
);
return e != zone_timers.end() ? e->timer_.GetRemainingTime() : 0;
}
bool Zone::HasTimer(std::string name)
{
const auto& e = std::find_if(
zone_timers.begin(),
zone_timers.end(),
[&name](ZoneTimer e) {
return e.name == name;
}
);
return e != zone_timers.end();
}
bool Zone::IsPausedTimer(std::string name)
{
const auto& e = std::find_if(
paused_zone_timers.begin(),
paused_zone_timers.end(),
[&name](PausedZoneTimer e) {
return e.name == name;
}
);
return e != paused_zone_timers.end();
}
void Zone::PauseTimer(std::string name)
{
if (zone_timers.empty()) {
return;
}
uint32 remaining_time = 0;
if (!zone_timers.empty()) {
for (auto e = zone_timers.begin(); e != zone_timers.end(); e++) {
if (e->name == name) {
remaining_time = e->timer_.GetRemainingTime();
zone_timers.erase(e);
break;
}
}
}
paused_zone_timers.emplace_back(
PausedZoneTimer{
.name = name,
.remaining_time = remaining_time
}
);
}
void Zone::ResumeTimer(std::string name)
{
if (paused_zone_timers.empty()) {
return;
}
uint32 remaining_time = 0;
if (!paused_zone_timers.empty()) {
for (auto e = paused_zone_timers.begin(); e != paused_zone_timers.end(); e++) {
if (e->name == name) {
remaining_time = e->remaining_time;
paused_zone_timers.erase(e);
break;
}
}
}
if (!remaining_time) {
LogQuests("Paused timer [{}] not found or has expired.", name);
return;
}
const std::string& export_string = fmt::format(
"{} {}",
name,
remaining_time
);
const bool has_resume_event = parse->ZoneHasQuestSub(EVENT_TIMER_RESUME);
if (!zone_timers.empty()) {
for (auto e : zone_timers) {
if (e.name == name) {
e.timer_.Enable();
e.timer_.Start(remaining_time, false);
LogQuests(
"Resuming timer [{}] with [{}] ms remaining",
name,
remaining_time
);
if (has_resume_event) {
parse->EventZone(EVENT_TIMER_RESUME, this, export_string);
}
}
}
}
zone_timers.emplace_back(ZoneTimer(name, remaining_time));
if (has_resume_event) {
parse->EventZone(EVENT_TIMER_RESUME, this, export_string);
}
LogQuests(
"Creating a new timer and resuming [{}] with [{}] ms remaining",
name,
remaining_time
);
}
void Zone::SetTimer(std::string name, uint32 duration)
{
zone_timers.emplace_back(ZoneTimer(name, duration));
if (parse->ZoneHasQuestSub(EVENT_TIMER_START)) {
parse->EventZone(EVENT_TIMER_START, this, name);
}
}
void Zone::StopTimer(std::string name)
{
if (zone_timers.empty()) {
return;
}
const bool has_stop_event = parse->ZoneHasQuestSub(EVENT_TIMER_STOP);
for (auto e = zone_timers.begin(); e != zone_timers.end(); e++) {
if (e->name == name) {
if (has_stop_event) {
parse->EventZone(EVENT_TIMER_STOP, this, name);
}
zone_timers.erase(e);
break;
}
}
}
void Zone::StopAllTimers()
{
if (zone_timers.empty()) {
return;
}
const bool has_stop_event = parse->ZoneHasQuestSub(EVENT_TIMER_STOP);
for (auto e = zone_timers.begin(); e != zone_timers.end(); e++) {
if (has_stop_event) {
parse->EventZone(EVENT_TIMER_STOP, this, e->name);
}
e = zone_timers.erase(e);
}
}
#include "zone_loot.cpp" #include "zone_loot.cpp"
+26
View File
@@ -486,6 +486,21 @@ public:
static void ClearZoneState(uint32 zone_id, uint32 instance_id); static void ClearZoneState(uint32 zone_id, uint32 instance_id);
void ReloadMaps(); void ReloadMaps();
struct PausedZoneTimer {
std::string name;
uint32 remaining_time;
};
uint32 GetTimerDuration(std::string name);
uint32 GetTimerRemainingTime(std::string name);
bool HasTimer(std::string name);
bool IsPausedTimer(std::string name);
void PauseTimer(std::string name);
void ResumeTimer(std::string name);
void SetTimer(std::string name, uint32 duration);
void StopTimer(std::string name);
void StopAllTimers();
private: private:
bool allow_mercs; bool allow_mercs;
bool can_bind; bool can_bind;
@@ -552,6 +567,17 @@ private:
std::vector<BaseDataRepository::BaseData> m_base_data = { }; std::vector<BaseDataRepository::BaseData> m_base_data = { };
uint32_t m_zone_server_id = 0; uint32_t m_zone_server_id = 0;
class ZoneTimer {
public:
inline ZoneTimer(std::string _name, uint32 duration)
: name(_name), timer_(duration) { timer_.Start(duration, false); }
std::string name;
Timer timer_;
};
std::vector<ZoneTimer> zone_timers;
std::vector<PausedZoneTimer> paused_zone_timers;
}; };
#endif #endif