This commit is contained in:
Kinglykrab 2025-05-31 21:17:09 -04:00
parent 54c53ce389
commit aae810e616
7 changed files with 192 additions and 102 deletions

View File

@ -222,6 +222,8 @@ PerlembParser::PerlembParser() : perl(nullptr)
global_bot_quest_status_ = questUnloaded;
merc_quest_status_ = questUnloaded;
global_merc_quest_status_ = questUnloaded;
zone_quest_status_ = questUnloaded;
global_zone_quest_status_ = questUnloaded;
}
PerlembParser::~PerlembParser()
@ -265,6 +267,8 @@ void PerlembParser::ReloadQuests()
global_bot_quest_status_ = questUnloaded;
merc_quest_status_ = questUnloaded;
global_merc_quest_status_ = questUnloaded;
zone_quest_status_ = questUnloaded;
global_zone_quest_status_ = questUnloaded;
item_quest_status_.clear();
spell_quest_status_.clear();
@ -353,21 +357,21 @@ int PerlembParser::EventCommon(
}
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, nullptr);
} 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, nullptr);
} 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, nullptr);
} else if (quest_type == QuestType::Spell || quest_type == QuestType::SpellGlobal) {
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, nullptr);
} 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, nullptr);
}
} else if (quest_type == QuestType::NPC || quest_type == QuestType::NPCGlobal) {
return SendCommands(
@ -377,8 +381,20 @@ int PerlembParser::EventCommon(
npc_mob,
mob,
nullptr,
nullptr,
nullptr
);
} else if (quest_type == QuestType::Zone || quest_type == QuestType::ZoneGlobal) {
return SendCommands(
package_name.c_str(),
QuestEventSubroutines[event_id],
0,
nullptr,
nullptr,
nullptr,
nullptr,
zone
);
}
}
@ -972,7 +988,8 @@ int PerlembParser::SendCommands(
Mob* other,
Mob* mob,
EQ::ItemInstance* inst,
const SPDat_Spell_Struct* spell
const SPDat_Spell_Struct* spell,
Zone* zone
)
{
if (!perl) {
@ -980,12 +997,20 @@ int PerlembParser::SendCommands(
}
int ret_value = 0;
QuestManager::RunningQuest q;
if (mob && mob->IsClient()) {
quest_manager.StartQuest(other, mob->CastToClient(), inst, spell);
} else {
quest_manager.StartQuest(other);
q.owner = other;
q.initiator = mob->CastToClient();
q.questitem = inst;
q.questspell = spell;
}
if (zone) {
q.zone = zone;
}
quest_manager.StartQuest(q);
try {
perl->eval(fmt::format("package {};", prefix).c_str());
@ -1024,21 +1049,23 @@ int PerlembParser::SendCommands(
sv_setsv(client, _empty_sv);
}
if (other->IsBot()) {
Bot* b = quest_manager.GetBot();
buf = fmt::format("{}::bot", prefix);
SV* bot = get_sv(buf.c_str(), true);
sv_setref_pv(bot, "Bot", b);
} else if (other->IsMerc()) {
Merc* m = quest_manager.GetMerc();
buf = fmt::format("{}::merc", prefix);
SV* merc = get_sv(buf.c_str(), true);
sv_setref_pv(merc, "Merc", m);
} else if (other->IsNPC()) {
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) {
if (other->IsBot()) {
Bot* b = quest_manager.GetBot();
buf = fmt::format("{}::bot", prefix);
SV* bot = get_sv(buf.c_str(), true);
sv_setref_pv(bot, "Bot", b);
} else if (other->IsMerc()) {
Merc* m = quest_manager.GetMerc();
buf = fmt::format("{}::merc", prefix);
SV* merc = get_sv(buf.c_str(), true);
sv_setref_pv(merc, "Merc", m);
} else if (other->IsNPC()) {
NPC* n = quest_manager.GetNPC();
buf = fmt::format("{}::npc", prefix);
SV* npc = get_sv(buf.c_str(), true);
sv_setref_pv(npc, "NPC", n);
}
}
//only export QuestItem if it's an inst quest
@ -2724,7 +2751,7 @@ void PerlembParser::LoadGlobalZoneScript(std::string filename)
} catch (std::string e) {
AddError(
fmt::format(
"Error Compiling Global Zone uest File [{}] Error [{}]",
"Error Compiling Global Zone Quest File [{}] Error [{}]",
filename,
e
)

View File

@ -232,7 +232,8 @@ private:
Mob* other,
Mob* mob,
EQ::ItemInstance* inst,
const SPDat_Spell_Struct* spell
const SPDat_Spell_Struct* spell,
Zone* zone
);
void MapFunctions();

View File

@ -489,7 +489,13 @@ int LuaParser::_EventNPC(std::string package_name, QuestEventID evt, NPC* npc, M
arg_function(this, L, npc, init, data, extra_data, extra_pointers);
Client *c = (init && init->IsClient()) ? init->CastToClient() : nullptr;
quest_manager.StartQuest(npc, c);
QuestManager::RunningQuest q;
q.owner = npc;
q.initiator = c;
quest_manager.StartQuest(q);
if(lua_pcall(L, 1, 1, start + 1)) {
std::string error = lua_tostring(L, -1);
AddError(error);
@ -582,7 +588,13 @@ int LuaParser::_EventPlayer(std::string package_name, QuestEventID evt, Client *
auto arg_function = PlayerArgumentDispatch[evt];
arg_function(this, L, client, data, extra_data, extra_pointers);
quest_manager.StartQuest(client, client);
QuestManager::RunningQuest q;
q.owner = client;
q.initiator = client;
quest_manager.StartQuest(q);
if(lua_pcall(L, 1, 1, start + 1)) {
std::string error = lua_tostring(L, -1);
AddError(error);
@ -666,7 +678,14 @@ int LuaParser::_EventItem(std::string package_name, QuestEventID evt, Client *cl
auto arg_function = ItemArgumentDispatch[evt];
arg_function(this, L, client, item, mob, data, extra_data, extra_pointers);
quest_manager.StartQuest(client, client, item);
QuestManager::RunningQuest q;
q.owner = client;
q.initiator = client;
q.questitem = item;
quest_manager.StartQuest(q);
if(lua_pcall(L, 1, 1, start + 1)) {
std::string error = lua_tostring(L, -1);
AddError(error);
@ -748,7 +767,14 @@ int LuaParser::_EventSpell(std::string package_name, QuestEventID evt, Mob* mob,
auto arg_function = SpellArgumentDispatch[evt];
arg_function(this, L, mob, client, spell_id, data, extra_data, extra_pointers);
quest_manager.StartQuest(mob, client, nullptr, const_cast<SPDat_Spell_Struct*>(&spells[spell_id]));
QuestManager::RunningQuest q;
q.owner = client;
q.initiator = client;
q.questspell = const_cast<SPDat_Spell_Struct*>(&spells[spell_id]);
quest_manager.StartQuest(q);
if(lua_pcall(L, 1, 1, start + 1)) {
std::string error = lua_tostring(L, -1);
AddError(error);
@ -814,7 +840,13 @@ int LuaParser::_EventEncounter(std::string package_name, QuestEventID evt, std::
auto arg_function = EncounterArgumentDispatch[evt];
arg_function(this, L, enc, data, extra_data, extra_pointers);
quest_manager.StartQuest(enc, nullptr, nullptr, nullptr, encounter_name);
QuestManager::RunningQuest q;
q.owner = enc;
q.encounter = encounter_name;
quest_manager.StartQuest(q);
if(lua_pcall(L, 1, 1, start + 1)) {
std::string error = lua_tostring(L, -1);
AddError(error);
@ -1757,7 +1789,13 @@ int LuaParser::_EventBot(
arg_function(this, L, bot, init, data, extra_data, extra_pointers);
auto* c = (init && init->IsClient()) ? init->CastToClient() : nullptr;
quest_manager.StartQuest(bot, c);
QuestManager::RunningQuest q;
q.owner = bot;
q.initiator = c;
quest_manager.StartQuest(q);
if(lua_pcall(L, 1, 1, start + 1)) {
std::string error = lua_tostring(L, -1);
AddError(error);
@ -1936,7 +1974,13 @@ int LuaParser::_EventMerc(
arg_function(this, L, merc, init, data, extra_data, extra_pointers);
auto* c = (init && init->IsClient()) ? init->CastToClient() : nullptr;
quest_manager.StartQuest(merc, c);
QuestManager::RunningQuest q;
q.owner = merc;
q.initiator = c;
quest_manager.StartQuest(q);
if(lua_pcall(L, 1, 1, start + 1)) {
std::string error = lua_tostring(L, -1);
AddError(error);

View File

@ -87,6 +87,7 @@ void QuestParserCollection::ReloadQuests(bool reset_timers)
{
if (reset_timers) {
quest_manager.ClearAllTimers();
zone->StopAllTimers();
}
MapOpcodes();

View File

@ -64,10 +64,10 @@ QuestManager quest_manager;
EQ::ItemInstance* questitem = nullptr; \
const SPDat_Spell_Struct* questspell = nullptr; \
bool depop_npc = false; \
std::string encounter; \
std::string encounter = ""; \
do { \
if(!quests_running_.empty()) { \
running_quest e = quests_running_.top(); \
if(!m_running_quests.empty()) { \
RunningQuest e = m_running_quests.top(); \
owner = e.owner; \
initiator = e.initiator; \
questitem = e.questitem; \
@ -124,33 +124,34 @@ void QuestManager::Process() {
}
}
void QuestManager::StartQuest(Mob *_owner, Client *_initiator, EQ::ItemInstance* _questitem, const SPDat_Spell_Struct* _questspell, std::string encounter) {
running_quest run;
run.owner = _owner;
run.initiator = _initiator;
run.questitem = _questitem;
run.questspell = _questspell;
run.depop_npc = false;
run.encounter = encounter;
quests_running_.push(run);
void QuestManager::StartQuest(RunningQuest q)
{
m_running_quests.push(q);
}
void QuestManager::EndQuest() {
running_quest run = quests_running_.top();
if(run.depop_npc && run.owner->IsNPC()) {
RunningQuest run = m_running_quests.top();
if (run.depop_npc && run.owner->IsNPC()) {
//clear out any timers for them...
std::list<QuestTimer>::iterator cur = QTimerList.begin(), end;
end = QTimerList.end();
while (cur != end) {
if (cur->mob == run.owner)
if (cur->mob == run.owner) {
cur = QTimerList.erase(cur);
else
} else {
++cur;
}
}
run.owner->Depop();
}
quests_running_.pop();
if (run.zone && run.zone == zone) {
zone->StopAllTimers();
}
m_running_quests.pop();
}
void QuestManager::ClearAllTimers() {
@ -1098,18 +1099,18 @@ void QuestManager::depop(int npc_type) {
tmp->CastToNPC()->Depop();
}
else {
running_quest e = quests_running_.top();
RunningQuest e = m_running_quests.top();
e.depop_npc = true;
quests_running_.pop();
quests_running_.push(e);
m_running_quests.pop();
m_running_quests.push(e);
}
}
}
else { //depop self
running_quest e = quests_running_.top();
RunningQuest e = m_running_quests.top();
e.depop_npc = true;
quests_running_.pop();
quests_running_.push(e);
m_running_quests.pop();
m_running_quests.push(e);
}
}
}
@ -1606,7 +1607,7 @@ void QuestManager::save() {
void QuestManager::faction(int faction_id, int faction_value, int temp) {
QuestManagerCurrentQuestVars();
running_quest run = quests_running_.top();
RunningQuest run = m_running_quests.top();
if(run.owner->IsCharmed() == false && initiator) {
if(faction_id != 0 && faction_value != 0) {
initiator->SetFactionLevel2(
@ -2077,10 +2078,10 @@ void QuestManager::respawn(int npcTypeID, int grid) {
if (!owner || !owner->IsNPC())
return;
running_quest e = quests_running_.top();
RunningQuest e = m_running_quests.top();
e.depop_npc = true;
quests_running_.pop();
quests_running_.push(e);
m_running_quests.pop();
m_running_quests.push(e);
const NPCType* npcType = nullptr;
if ((npcType = content_db.LoadNPCTypesData(npcTypeID)))
@ -3980,81 +3981,90 @@ void QuestManager::ReloadZoneStaticData()
}
}
Client *QuestManager::GetInitiator() const {
if(!quests_running_.empty()) {
running_quest e = quests_running_.top();
Client* QuestManager::GetInitiator() const
{
if (!m_running_quests.empty()) {
RunningQuest e = m_running_quests.top();
return e.initiator;
}
return nullptr;
}
NPC *QuestManager::GetNPC() const {
if(!quests_running_.empty()) {
running_quest e = quests_running_.top();
NPC* QuestManager::GetNPC() const
{
if (!m_running_quests.empty()) {
RunningQuest e = m_running_quests.top();
return (e.owner && e.owner->IsNPC()) ? e.owner->CastToNPC() : nullptr;
}
return nullptr;
}
Bot *QuestManager::GetBot() const {
if (!quests_running_.empty()) {
running_quest e = quests_running_.top();
Bot* QuestManager::GetBot() const
{
if (!m_running_quests.empty()) {
RunningQuest e = m_running_quests.top();
return (e.owner && e.owner->IsBot()) ? e.owner->CastToBot() : nullptr;
}
return nullptr;
}
Merc *QuestManager::GetMerc() const {
if (!quests_running_.empty()) {
running_quest e = quests_running_.top();
Merc* QuestManager::GetMerc() const
{
if (!m_running_quests.empty()) {
RunningQuest e = m_running_quests.top();
return (e.owner && e.owner->IsMerc()) ? e.owner->CastToMerc() : nullptr;
}
return nullptr;
}
Mob *QuestManager::GetOwner() const {
if(!quests_running_.empty()) {
running_quest e = quests_running_.top();
Mob* QuestManager::GetOwner() const
{
if (!m_running_quests.empty()) {
RunningQuest e = m_running_quests.top();
return e.owner;
}
return nullptr;
}
EQ::InventoryProfile *QuestManager::GetInventory() const {
if(!quests_running_.empty()) {
running_quest e = quests_running_.top();
EQ::InventoryProfile* QuestManager::GetInventory() const
{
if (!m_running_quests.empty()) {
RunningQuest e = m_running_quests.top();
return &e.initiator->GetInv();
}
return nullptr;
}
EQ::ItemInstance *QuestManager::GetQuestItem() const {
if(!quests_running_.empty()) {
running_quest e = quests_running_.top();
EQ::ItemInstance* QuestManager::GetQuestItem() const
{
if (!m_running_quests.empty()) {
RunningQuest e = m_running_quests.top();
return e.questitem;
}
return nullptr;
}
const SPDat_Spell_Struct *QuestManager::GetQuestSpell() {
if(!quests_running_.empty()) {
running_quest e = quests_running_.top();
const SPDat_Spell_Struct* QuestManager::GetQuestSpell()
{
if (!m_running_quests.empty()) {
RunningQuest e = m_running_quests.top();
return e.questspell;
}
return nullptr;
}
std::string QuestManager::GetEncounter() const {
if(!quests_running_.empty()) {
running_quest e = quests_running_.top();
std::string QuestManager::GetEncounter() const
{
if (!m_running_quests.empty()) {
RunningQuest e = m_running_quests.top();
return e.encounter;
}

View File

@ -34,14 +34,6 @@ namespace EQ
}
class QuestManager {
struct running_quest {
Mob *owner;
Client *initiator;
EQ::ItemInstance* questitem;
const SPDat_Spell_Struct* questspell;
bool depop_npc;
std::string encounter;
};
struct PausedTimer {
Mob* owner;
@ -49,12 +41,23 @@ class QuestManager {
uint32 time;
};
public:
struct RunningQuest {
Mob *owner = nullptr;
Client *initiator = nullptr;
EQ::ItemInstance* questitem = nullptr;
const SPDat_Spell_Struct* questspell = nullptr;
bool depop_npc = false;
std::string encounter = "";
Zone* zone = nullptr;
};
QuestManager();
virtual ~QuestManager();
void StartQuest(Mob *_owner, Client *_initiator = nullptr, EQ::ItemInstance* _questitem = nullptr, const SPDat_Spell_Struct* _questspell = nullptr, std::string encounter = "");
void StartQuest(RunningQuest q);
void EndQuest();
bool QuestsRunning() { return !quests_running_.empty(); }
bool QuestsRunning() { return !m_running_quests.empty(); }
void Process();
@ -381,7 +384,7 @@ public:
bool handin(std::map<std::string, uint32> required);
private:
std::stack<running_quest> quests_running_;
std::stack<RunningQuest> m_running_quests;
bool HaveProximitySays;

View File

@ -1696,7 +1696,6 @@ 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);
@ -1946,6 +1945,8 @@ void Zone::Repop(bool is_forced)
quest_manager.ClearAllTimers();
StopAllTimers();
LogInfo("Loading spawn groups");
if (!content_db.LoadSpawnGroups(short_name, GetInstanceVersion(), &spawn_group_list)) {
LogError("Loading spawn groups failed");
@ -3457,7 +3458,8 @@ 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);
const std::string& export_string = fmt::format("{} {}", name, duration);
parse->EventZone(EVENT_TIMER_START, this, export_string);
}
}
@ -3483,6 +3485,10 @@ void Zone::StopTimer(std::string name)
void Zone::StopAllTimers()
{
if (!IsLoaded()) {
return;
}
if (zone_timers.empty()) {
return;
}
@ -3493,8 +3499,6 @@ void Zone::StopAllTimers()
if (has_stop_event) {
parse->EventZone(EVENT_TIMER_STOP, this, e->name);
}
e = zone_timers.erase(e);
}
}