From 1363d5d20980ecac1a67b18dc95f6a7c6c74ad74 Mon Sep 17 00:00:00 2001 From: KimLS Date: Sun, 19 May 2013 23:39:18 -0700 Subject: [PATCH] Lua fixes, need to get perl working again D= --- zone/embparser.cpp | 4 +- zone/embparser_api.cpp | 74 +++++----- zone/lua_general.cpp | 203 ++++++++++++++++++++++++--- zone/lua_parser.cpp | 24 +++- zone/npc.cpp | 7 +- zone/questmgr.cpp | 308 +++++++++++++++++++++++++++++++---------- zone/questmgr.h | 52 +++---- 7 files changed, 506 insertions(+), 166 deletions(-) diff --git a/zone/embparser.cpp b/zone/embparser.cpp index feda38403..7f7a09e14 100644 --- a/zone/embparser.cpp +++ b/zone/embparser.cpp @@ -1066,8 +1066,8 @@ void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID { switch (event) { case EVENT_SAY: { - if(npc && mob) { - npc->DoQuestPause(mob); + if(npcmob && mob) { + npcmob->DoQuestPause(mob); } ExportVar(package_name.c_str(), "data", objid); diff --git a/zone/embparser_api.cpp b/zone/embparser_api.cpp index 5afc3721e..0e21ba6aa 100644 --- a/zone/embparser_api.cpp +++ b/zone/embparser_api.cpp @@ -220,7 +220,8 @@ XS(XS__spawn) float y = (float)SvNV(ST(4)); float z = (float)SvNV(ST(5)); - RETVAL = quest_manager.spawn2(npc_type, grid, unused, x, y, z, 0); + Mob *r = quest_manager.spawn2(npc_type, grid, unused, x, y, z, 0); + RETVAL = (r != nullptr) ? r->GetID() : 0; XSprePUSH; PUSHu((UV)RETVAL); XSRETURN(1); @@ -244,7 +245,8 @@ XS(XS__spawn2) float z = (float)SvNV(ST(5)); float heading = (float)SvNV(ST(6)); - RETVAL = quest_manager.spawn2(npc_type, grid, unused, x, y, z, heading); + Mob *r = quest_manager.spawn2(npc_type, grid, unused, x, y, z, heading); + RETVAL = (r != nullptr) ? r->GetID() : 0; XSprePUSH; PUSHu((UV)RETVAL); XSRETURN(1); @@ -270,7 +272,9 @@ XS(XS__unique_spawn) if(items == 7) heading = (float)SvNV(ST(6)); - RETVAL = quest_manager.unique_spawn(npc_type, grid, unused, x, y, z, heading); + Mob *r = quest_manager.unique_spawn(npc_type, grid, unused, x, y, z, heading); + RETVAL = (r != nullptr) ? r->GetID() : 0; + XSprePUSH; PUSHu((UV)RETVAL); XSRETURN(1); @@ -288,7 +292,9 @@ XS(XS__spawn_from_spawn2) int spawn2_id = (int)SvIV(ST(0)); - RETVAL = quest_manager.spawn_from_spawn2(spawn2_id); + Mob *r = quest_manager.spawn_from_spawn2(spawn2_id); + RETVAL = (r != nullptr) ? r->GetID() : 0; + XSprePUSH; PUSHu((UV)RETVAL); XSRETURN(1); @@ -1557,6 +1563,30 @@ XS(XS__clear_proximity) XSRETURN_EMPTY; } +XS(XS__enable_proximity_say); +XS(XS__enable_proximity_say) +{ + dXSARGS; + if (items != 0) + Perl_croak(aTHX_ "Usage: enable_proximity_say()"); + + quest_manager.enable_proximity_say(); + + XSRETURN_EMPTY; +} + +XS(XS__disable_proximity_say); +XS(XS__disable_proximity_say) +{ + dXSARGS; + if (items != 0) + Perl_croak(aTHX_ "Usage: disable_proximity_say()"); + + quest_manager.disable_proximity_say(); + + XSRETURN_EMPTY; +} + XS(XS__setanim); XS(XS__setanim) //Cisyouc: mob->setappearance() addition { @@ -1581,38 +1611,6 @@ XS(XS__showgrid) XSRETURN_EMPTY; } -XS(XS__showpath); -XS(XS__showpath) -{ - dXSARGS; - if (items != 3) - Perl_croak(aTHX_ "Usage: showpath(x, y, z)"); - - float x = (float)SvNV(ST(0)); - float y = (float)SvNV(ST(1)); - float z = (float)SvNV(ST(2)); - - quest_manager.showpath(x, y, z); - - XSRETURN_EMPTY; -} - -XS(XS__pathto); -XS(XS__pathto) -{ - dXSARGS; - if (items != 3) - Perl_croak(aTHX_ "Usage: pathto(x, y, z)"); - - float x = (float)SvNV(ST(0)); - float y = (float)SvNV(ST(1)); - float z = (float)SvNV(ST(2)); - - quest_manager.pathto(x, y, z); - - XSRETURN_EMPTY; -} - XS(XS__spawn_condition); XS(XS__spawn_condition) { @@ -3421,10 +3419,10 @@ EXTERN_C XS(boot_quest) newXS(strcpy(buf, "ChooseRandom"), XS__ChooseRandom, file); newXS(strcpy(buf, "set_proximity"), XS__set_proximity, file); newXS(strcpy(buf, "clear_proximity"), XS__clear_proximity, file); + newXS(strcpy(buf, "enable_proximity_say"), XS__enable_proximity_say, file); + newXS(strcpy(buf, "disable_proximity_say"), XS__disable_proximity_say, file); newXS(strcpy(buf, "setanim"), XS__setanim, file); newXS(strcpy(buf, "showgrid"), XS__showgrid, file); - newXS(strcpy(buf, "showpath"), XS__showpath, file); - newXS(strcpy(buf, "pathto"), XS__pathto, file); newXS(strcpy(buf, "spawn_condition"), XS__spawn_condition, file); newXS(strcpy(buf, "get_spawn_condition"), XS__get_spawn_condition, file); newXS(strcpy(buf, "toggle_spawn_event"), XS__toggle_spawn_event, file); diff --git a/zone/lua_general.cpp b/zone/lua_general.cpp index 803f5ced2..b3cb9757a 100644 --- a/zone/lua_general.cpp +++ b/zone/lua_general.cpp @@ -7,7 +7,11 @@ #include #include "lua_parser.h" +#include "lua_item.h" +#include "lua_iteminst.h" +#include "lua_mob.h" #include "QuestParserCollection.h" +#include "questmgr.h" struct Events { }; @@ -27,35 +31,202 @@ void unload_encounter(std::string name) { parse->EventEncounter(EVENT_ENCOUNTER_UNLOAD, name, 0); } +void register_event(std::string package_name, std::string name, int evt, luabind::object func) { + lua_registered_event e; + e.encounter_name = name; + e.lua_reference = func; + e.event_id = static_cast(evt); + + auto liter = lua_encounter_events_registered.find(package_name); + if(liter == lua_encounter_events_registered.end()) { + std::list elist; + elist.push_back(e); + lua_encounter_events_registered[package_name] = elist; + } else { + std::list elist = liter->second; + auto iter = elist.begin(); + while(iter != elist.end()) { + if(iter->event_id == evt && iter->encounter_name.compare(name) == 0) { + //already registered this event for this encounter + return; + } + ++iter; + } + + elist.push_back(e); + lua_encounter_events_registered[package_name] = elist; + } +} + +void unregister_event(std::string package_name, std::string name, int evt) { + auto liter = lua_encounter_events_registered.find(package_name); + if(liter != lua_encounter_events_registered.end()) { + std::list elist = liter->second; + auto iter = elist.begin(); + while(iter != elist.end()) { + if(iter->event_id == evt && iter->encounter_name.compare(name) == 0) { + iter = elist.erase(iter); + } + } + lua_encounter_events_registered[package_name] = elist; + } +} + void register_npc_event(std::string name, int evt, int npc_id, luabind::object func) { if(luabind::type(func) == LUA_TFUNCTION) { std::stringstream package_name; package_name << "npc_" << npc_id; - lua_registered_event e; - e.encounter_name = name; - e.lua_reference = func; - e.event_id = static_cast(evt); - - auto liter = lua_encounter_events_registered.find(package_name.str()); - if(liter == lua_encounter_events_registered.end()) { - std::list elist; - elist.push_back(e); - lua_encounter_events_registered[package_name.str()] = elist; - } else { - std::list elist = liter->second; - elist.push_back(e); - lua_encounter_events_registered[package_name.str()] = elist; - } + register_event(package_name.str(), name, evt, func); } } +void unregister_npc_event(std::string name, int evt, int npc_id) { + std::stringstream package_name; + package_name << "npc_" << npc_id; + + unregister_event(package_name.str(), name, evt); +} + +void register_player_event(std::string name, int evt, luabind::object func) { + if(luabind::type(func) == LUA_TFUNCTION) { + register_event("player", name, evt, func); + } +} + +void unregister_player_event(std::string name, int evt) { + unregister_event("player", name, evt); +} + +void register_item_event(std::string name, int evt, Lua_Item item, luabind::object func) { + const Item_Struct *itm = item; + if(!itm) { + return; + } + + std::stringstream package_name; + package_name << "item_"; + + std::stringstream item_name; + if(EVENT_SCALE_CALC == evt || EVENT_ITEM_ENTER_ZONE == evt) + { + item_name << itm->CharmFile; + } + else if(EVENT_ITEM_CLICK == evt || EVENT_ITEM_CLICK_CAST == evt) + { + item_name << "script_"; + item_name << itm->ScriptFileID; + } + else + { + item_name << "item_"; + item_name << itm->ID; + } + + package_name << item_name; + + if(luabind::type(func) == LUA_TFUNCTION) { + register_event(package_name.str(), name, evt, func); + } +} + +void unregister_item_event(std::string name, int evt, Lua_Item item) { + const Item_Struct *itm = item; + if(!itm) { + return; + } + + std::stringstream package_name; + package_name << "item_"; + + std::stringstream item_name; + if(EVENT_SCALE_CALC == evt || EVENT_ITEM_ENTER_ZONE == evt) + { + item_name << itm->CharmFile; + } + else if(EVENT_ITEM_CLICK == evt || EVENT_ITEM_CLICK_CAST == evt) + { + item_name << "script_"; + item_name << itm->ScriptFileID; + } + else + { + item_name << "item_"; + item_name << itm->ID; + } + + package_name << item_name; + unregister_event(package_name.str(), name, evt); +} + +void register_spell_event(std::string name, int evt, int spell_id, luabind::object func) { + if(luabind::type(func) == LUA_TFUNCTION) { + std::stringstream package_name; + package_name << "spell_" << spell_id; + + register_event(package_name.str(), name, evt, func); + } +} + +void unregister_spell_event(std::string name, int evt, int spell_id) { + std::stringstream package_name; + package_name << "spell_" << spell_id; + + unregister_event(package_name.str(), name, evt); +} + +void lua_say(const char *str) { + quest_manager.say(str); +} + +void lua_say(const char *str, int language) { + quest_manager.say(str, language); +} + +void lua_me(const char *str) { + quest_manager.me(str); +} + +void lua_summon_item(uint32 itemid, int charges = 0) { + quest_manager.summonitem(itemid, charges); +} + +Lua_Mob lua_spawn2(int npc_type, int grid, int unused, double x, double y, double z, double heading) { + return Lua_Mob(quest_manager.spawn2(npc_type, grid, unused, + static_cast(x), static_cast(y), static_cast(z), static_cast(heading))); +} + +Lua_Mob lua_unique_spawn(int npc_type, int grid, int unused, double x, double y, double z, double heading = 0.0) { + return Lua_Mob(quest_manager.unique_spawn(npc_type, grid, unused, + static_cast(x), static_cast(y), static_cast(z), static_cast(heading))); +} + +Lua_Mob lua_spawn_from_spawn2(uint32 spawn2_id) { + return Lua_Mob(quest_manager.spawn_from_spawn2(spawn2_id)); +} + luabind::scope lua_register_general() { return luabind::namespace_("eq") [ luabind::def("load_encounter", &load_encounter), luabind::def("unload_encounter", &unload_encounter), - luabind::def("register_npc_event", ®ister_npc_event) + luabind::def("register_npc_event", ®ister_npc_event), + luabind::def("unregister_npc_event", &unregister_npc_event), + luabind::def("register_player_event", ®ister_player_event), + luabind::def("unregister_player_event", &unregister_player_event), + luabind::def("register_item_event", ®ister_item_event), + luabind::def("unregister_item_event", &unregister_item_event), + luabind::def("register_spell_event", ®ister_spell_event), + luabind::def("unregister_spell_event", &unregister_spell_event), + luabind::def("say", (void(*)(const char*))&lua_say), + luabind::def("say", (void(*)(const char*, int))&lua_say), + luabind::def("me", (void(*)(const char*))&lua_me), + luabind::def("summon_item", (void(*)(uint32))&lua_summon_item), + luabind::def("summon_item", (void(*)(uint32,int))&lua_summon_item), + luabind::def("spawn2", (Lua_Mob(*)(int,int,int,double,double,double,double))&lua_spawn2), + luabind::def("unique_spawn", (Lua_Mob(*)(int,int,int,double,double,double))&lua_unique_spawn), + luabind::def("unique_spawn", (Lua_Mob(*)(int,int,int,double,double,double,double))&lua_unique_spawn), + luabind::def("spawn_from_spawn2", (Lua_Mob(*)(uint32))&lua_spawn_from_spawn2) ]; } diff --git a/zone/lua_parser.cpp b/zone/lua_parser.cpp index 8aba16e13..366a634c3 100644 --- a/zone/lua_parser.cpp +++ b/zone/lua_parser.cpp @@ -24,6 +24,7 @@ #include "lua_general.h" #include "zone.h" +#include "questmgr.h" #include "lua_parser.h" const char *LuaEvents[_LargestEventID] = { @@ -202,11 +203,15 @@ int LuaParser::_EventNPC(std::string package_name, QuestEventID evt, NPC* npc, M auto arg_function = NPCArgumentDispatch[evt]; arg_function(this, L, npc, init, data, extra_data); + Client *c = (init && init->IsClient()) ? init->CastToClient() : nullptr; + quest_manager.StartQuest(npc, c, nullptr); if(lua_pcall(L, 1, 1, 0)) { std::string error = lua_tostring(L, -1); AddError(error); + quest_manager.EndQuest(); return 0; } + quest_manager.EndQuest(); if(lua_isnumber(L, -1)) { int ret = static_cast(lua_tointeger(L, -1)); @@ -288,11 +293,14 @@ int LuaParser::_EventPlayer(std::string package_name, QuestEventID evt, Client * auto arg_function = PlayerArgumentDispatch[evt]; arg_function(this, L, client, data, extra_data); + quest_manager.StartQuest(nullptr, client, nullptr); if(lua_pcall(L, 1, 1, 0)) { std::string error = lua_tostring(L, -1); AddError(error); + quest_manager.EndQuest(); return 0; } + quest_manager.EndQuest(); if(lua_isnumber(L, -1)) { int ret = static_cast(lua_tointeger(L, -1)); @@ -379,11 +387,14 @@ int LuaParser::_EventItem(std::string package_name, QuestEventID evt, Client *cl auto arg_function = ItemArgumentDispatch[evt]; arg_function(this, L, client, item, objid, extra_data); + quest_manager.StartQuest(nullptr, client, item); if(lua_pcall(L, 1, 1, 0)) { std::string error = lua_tostring(L, -1); AddError(error); + quest_manager.EndQuest(); return 0; } + quest_manager.EndQuest(); if(lua_isnumber(L, -1)) { int ret = static_cast(lua_tointeger(L, -1)); @@ -450,11 +461,14 @@ int LuaParser::_EventSpell(std::string package_name, QuestEventID evt, NPC* npc, auto arg_function = SpellArgumentDispatch[evt]; arg_function(this, L, npc, client, spell_id, extra_data); + quest_manager.StartQuest(npc, client, nullptr); if(lua_pcall(L, 1, 1, 0)) { std::string error = lua_tostring(L, -1); AddError(error); + quest_manager.EndQuest(); return 0; } + quest_manager.EndQuest(); if(lua_isnumber(L, -1)) { int ret = static_cast(lua_tointeger(L, -1)); @@ -502,14 +516,18 @@ int LuaParser::_EventEncounter(std::string package_name, QuestEventID evt, std:: lua_getfield(L, LUA_REGISTRYINDEX, package_name.c_str()); lua_getfield(L, -1, sub_name); - //For now encounters just call event_encounter_load/event_encounter_unload with no arguments - //So we dont pass anything + lua_createtable(L, 0, 0); + lua_pushstring(L, encounter_name.c_str()); + lua_setfield(L, -2, "name"); - if(lua_pcall(L, 0, 1, 0)) { + quest_manager.StartQuest(nullptr, nullptr, nullptr); + if(lua_pcall(L, 1, 1, 0)) { std::string error = lua_tostring(L, -1); AddError(error); + quest_manager.EndQuest(); return 0; } + quest_manager.EndQuest(); if(lua_isnumber(L, -1)) { int ret = static_cast(lua_tointeger(L, -1)); diff --git a/zone/npc.cpp b/zone/npc.cpp index 697ec18ee..8f900127a 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -2473,10 +2473,11 @@ uint32 NPC::GetSpawnKillCount() } void NPC::DoQuestPause(Mob *other) { - if(IsMoving() && !IsOnHatelist(other)) + if(IsMoving() && !IsOnHatelist(other)) { PauseWandering(RuleI(NPC, SayPauseTimeInSec)); - - if(!IsMoving()) FaceTarget(other); + } else if(!IsMoving()) { + FaceTarget(other); + } } \ No newline at end of file diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index 174521d06..670ca113d 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -91,9 +91,24 @@ extern EntityList entity_list; //declare our global instance QuestManager quest_manager; +#define QuestManagerCurrentQuestVars() \ + Mob *owner = nullptr; \ + Client *initiator = nullptr; \ + ItemInst* questitem = nullptr; \ + bool depop_npc = false; \ + do { \ + if(!quests_running_.empty()) { \ + running_quest e = quests_running_.top(); \ + owner = e.owner; \ + initiator = e.initiator; \ + questitem = e.questitem; \ + depop_npc = e.depop_npc; \ + } \ + } while(0) + QuestManager::QuestManager() { - depop_npc = false; HaveProximitySays = false; + } QuestManager::~QuestManager() { @@ -143,23 +158,23 @@ void QuestManager::Process() { } void QuestManager::StartQuest(Mob *_owner, Client *_initiator, ItemInst* _questitem) { - quest_mutex.lock(); - owner = _owner; - initiator = _initiator; - questitem = _questitem; - depop_npc = false; + running_quest run; + run.owner = _owner; + run.initiator = _initiator; + run.questitem = _questitem; + run.depop_npc = false; + quests_running_.push(run); } void QuestManager::EndQuest() { - quest_mutex.unlock(); - - if(depop_npc && owner->IsNPC()) { + running_quest run = quests_running_.top(); + if(run.depop_npc && run.owner->IsNPC()) { //clear out any timers for them... list::iterator cur = QTimerList.begin(), end, tmp; end = QTimerList.end(); while (cur != end) { - if(cur->mob == owner) { + if(cur->mob == run.owner) { tmp = cur; tmp++; QTimerList.erase(cur); @@ -169,9 +184,9 @@ void QuestManager::EndQuest() { } } - owner->Depop(); - owner = nullptr; //just to be safe + run.owner->Depop(); } + quests_running_.pop(); } void QuestManager::ClearAllTimers() { @@ -190,10 +205,12 @@ void QuestManager::ClearAllTimers() { //quest perl functions void QuestManager::echo(int colour, const char *str) { + QuestManagerCurrentQuestVars(); entity_list.MessageClose(initiator, false, 200, colour, str); } void QuestManager::say(const char *str) { + QuestManagerCurrentQuestVars(); if (!owner) { LogFile->write(EQEMuLog::Quest, "QuestManager::say called with nullptr owner. Probably syntax error in quest file."); return; @@ -209,6 +226,7 @@ void QuestManager::say(const char *str) { } void QuestManager::say(const char *str, uint8 language) { + QuestManagerCurrentQuestVars(); if (!owner) { LogFile->write(EQEMuLog::Quest, "QuestManager::say called with nullptr owner. Probably syntax error in quest file."); return; @@ -219,12 +237,14 @@ void QuestManager::say(const char *str, uint8 language) { } void QuestManager::me(const char *str) { + QuestManagerCurrentQuestVars(); if (!initiator) return; entity_list.MessageClose(initiator, false, 200, 10, str); } void QuestManager::summonitem(uint32 itemid, int16 charges) { + QuestManagerCurrentQuestVars(); if(!initiator) return; initiator->SummonItem(itemid, charges); @@ -239,31 +259,27 @@ void QuestManager::write(const char *file, const char *str) { fclose (pFile); } -uint16 QuestManager::spawn2(int npc_type, int grid, int unused, float x, float y, float z, float heading) { +Mob* QuestManager::spawn2(int npc_type, int grid, int unused, float x, float y, float z, float heading) { const NPCType* tmp = 0; if (tmp = database.GetNPCType(npc_type)) { NPC* npc = new NPC(tmp, 0, x, y, z, heading, FlyMode3); npc->AddLootTable(); entity_list.AddNPC(npc,true,true); - // Sleep in main thread? ICK! - // Sleep(200); - // check is irrelevent, it's impossible for npc to be 0 here - // (we're in main thread, nothing else can possibly modify it) if(grid > 0) { npc->AssignWaypoints(grid); } npc->SendPosUpdate(); - return(npc->GetID()); + return npc; } - return(0); + return nullptr; } -uint16 QuestManager::unique_spawn(int npc_type, int grid, int unused, float x, float y, float z, float heading) { +Mob* QuestManager::unique_spawn(int npc_type, int grid, int unused, float x, float y, float z, float heading) { Mob *other = entity_list.GetMobByNpcTypeID(npc_type); if(other != nullptr) { - return(other->GetID()); + return other; } const NPCType* tmp = 0; @@ -272,21 +288,17 @@ uint16 QuestManager::unique_spawn(int npc_type, int grid, int unused, float x, f NPC* npc = new NPC(tmp, 0, x, y, z, heading, FlyMode3); npc->AddLootTable(); entity_list.AddNPC(npc,true,true); - // Sleep in main thread? ICK! - // Sleep(200); - // check is irrelevent, it's impossible for npc to be 0 here - // (we're in main thread, nothing else can possibly modify it) if(grid > 0) { npc->AssignWaypoints(grid); } npc->SendPosUpdate(); - return(npc->GetID()); + return npc; } - return(0); + return nullptr; } -uint16 QuestManager::spawn_from_spawn2(uint32 spawn2_id) +Mob* QuestManager::spawn_from_spawn2(uint32 spawn2_id) { LinkedListIterator iterator(zone->spawn2_list); iterator.Reset(); @@ -312,26 +324,26 @@ uint16 QuestManager::spawn_from_spawn2(uint32 spawn2_id) sg = zone->spawn_group_list.GetSpawnGroup(found_spawn->SpawnGroupID()); if(!sg) { - return 0; + return nullptr; } } uint32 npcid = sg->GetNPCType(); if(npcid == 0) { - return 0; + return nullptr; } const NPCType* tmp = database.GetNPCType(npcid); if(!tmp) { - return 0; + return nullptr; } if(tmp->unique_spawn_by_name) { if(!entity_list.LimitCheckName(tmp->name)) { - return 0; + return nullptr; } } @@ -339,7 +351,7 @@ uint16 QuestManager::spawn_from_spawn2(uint32 spawn2_id) { if(!entity_list.LimitCheckType(npcid, tmp->spawn_limit)) { - return 0; + return nullptr; } } @@ -362,9 +374,10 @@ uint16 QuestManager::spawn_from_spawn2(uint32 spawn2_id) found_spawn->LoadGrid(); } - return npc->GetID(); + return npc; } - return 0; + + return nullptr; } void QuestManager::enable_spawn2(uint32 spawn2_id) @@ -390,16 +403,19 @@ void QuestManager::disable_spawn2(uint32 spawn2_id) } void QuestManager::setstat(int stat, int value) { + QuestManagerCurrentQuestVars(); if (initiator) initiator->SetStats(stat, value); } -void QuestManager::incstat(int stat, int value) { //old setstat command aza +void QuestManager::incstat(int stat, int value) { + QuestManagerCurrentQuestVars(); if (initiator) initiator->IncStats(stat, value); } void QuestManager::castspell(int spell_id, int target_id) { + QuestManagerCurrentQuestVars(); if (owner) { Mob *tgt = entity_list.GetMob(target_id); if(tgt != nullptr) @@ -408,11 +424,13 @@ void QuestManager::castspell(int spell_id, int target_id) { } void QuestManager::selfcast(int spell_id) { + QuestManagerCurrentQuestVars(); if (initiator) initiator->SpellFinished(spell_id, initiator, 10, 0, -1, spells[spell_id].ResistDiff); } void QuestManager::addloot(int item_id, int charges, bool equipitem) { + QuestManagerCurrentQuestVars(); if(item_id != 0){ if(owner->IsNPC()) owner->CastToNPC()->AddItem(item_id, charges, equipitem); @@ -420,6 +438,7 @@ void QuestManager::addloot(int item_id, int charges, bool equipitem) { } void QuestManager::Zone(const char *zone_name) { + QuestManagerCurrentQuestVars(); if (initiator && initiator->IsClient()) { ServerPacket* pack = new ServerPacket(ServerOP_ZoneToZoneRequest, sizeof(ZoneToZone_Struct)); @@ -438,6 +457,7 @@ void QuestManager::Zone(const char *zone_name) { } void QuestManager::settimer(const char *timer_name, int seconds) { + QuestManagerCurrentQuestVars(); list::iterator cur = QTimerList.begin(), end; @@ -457,6 +477,7 @@ void QuestManager::settimer(const char *timer_name, int seconds) { } void QuestManager::settimerMS(const char *timer_name, int milliseconds) { + QuestManagerCurrentQuestVars(); list::iterator cur = QTimerList.begin(), end; @@ -476,6 +497,7 @@ void QuestManager::settimerMS(const char *timer_name, int milliseconds) { } void QuestManager::stoptimer(const char *timer_name) { + QuestManagerCurrentQuestVars(); list::iterator cur = QTimerList.begin(), end; @@ -492,6 +514,7 @@ void QuestManager::stoptimer(const char *timer_name) { } void QuestManager::stopalltimers() { + QuestManagerCurrentQuestVars(); list::iterator cur = QTimerList.begin(), end, tmp; @@ -513,6 +536,7 @@ void QuestManager::stopalltimers() { } void QuestManager::emote(const char *str) { + QuestManagerCurrentQuestVars(); if (!owner) { LogFile->write(EQEMuLog::Quest, "QuestManager::emote called with nullptr owner. Probably syntax error in quest file."); return; @@ -523,6 +547,7 @@ void QuestManager::emote(const char *str) { } void QuestManager::shout(const char *str) { + QuestManagerCurrentQuestVars(); if (!owner) { LogFile->write(EQEMuLog::Quest, "QuestManager::shout called with nullptr owner. Probably syntax error in quest file."); return; @@ -533,6 +558,7 @@ void QuestManager::shout(const char *str) { } void QuestManager::shout2(const char *str) { + QuestManagerCurrentQuestVars(); if (!owner) { LogFile->write(EQEMuLog::Quest, "QuestManager::shout2 called with nullptr owner. Probably syntax error in quest file."); return; @@ -543,13 +569,15 @@ void QuestManager::shout2(const char *str) { } void QuestManager::gmsay(const char *str, uint32 color, bool send_to_world, uint32 to_guilddbid, uint32 to_minstatus) { + QuestManagerCurrentQuestVars(); if(send_to_world) worldserver.SendEmoteMessage(0, to_guilddbid, to_minstatus, color, "%s", str); else entity_list.MessageStatus(to_guilddbid, to_minstatus, color, "%s", str); } -void QuestManager::depop(int npc_type) { // depop NPC and don't start spawn timer +void QuestManager::depop(int npc_type) { + QuestManagerCurrentQuestVars(); if (!owner || !owner->IsNPC()) { LogFile->write(EQEMuLog::Quest, "QuestManager::depop called with nullptr owner or non-NPC owner. Probably syntax error in quest file."); return; @@ -572,7 +600,8 @@ void QuestManager::depop(int npc_type) { // depop NPC and don't start spawn time } } -void QuestManager::depop_withtimer(int npc_type) { // depop NPC and start spawn timer +void QuestManager::depop_withtimer(int npc_type) { + QuestManagerCurrentQuestVars(); if (!owner || !owner->IsNPC()) { LogFile->write(EQEMuLog::Quest, "QuestManager::depop_withtimer called with nullptr owner or non-NPC owner. Probably syntax error in quest file."); return; @@ -596,6 +625,7 @@ void QuestManager::depop_withtimer(int npc_type) { // depop NPC and start spawn } void QuestManager::depopall(int npc_type) { + QuestManagerCurrentQuestVars(); if(owner && owner->IsNPC() && (npc_type > 0)) { entity_list.DepopAll(npc_type); } @@ -623,6 +653,7 @@ void QuestManager::repopzone() { } void QuestManager::settarget(const char *type, int target_id) { + QuestManagerCurrentQuestVars(); if(!owner->IsNPC()) return; Mob* tmp = nullptr; @@ -638,6 +669,7 @@ void QuestManager::settarget(const char *type, int target_id) { } void QuestManager::follow(int entity_id, int distance) { + QuestManagerCurrentQuestVars(); if(!owner->IsNPC()) return; owner->SetFollowID(entity_id); @@ -645,12 +677,14 @@ void QuestManager::follow(int entity_id, int distance) { } void QuestManager::sfollow() { + QuestManagerCurrentQuestVars(); if(!owner->IsNPC()) return; owner->SetFollowID(0); } void QuestManager::changedeity(int diety_id) { + QuestManagerCurrentQuestVars(); //Changes the deity. if(initiator) { @@ -669,22 +703,24 @@ void QuestManager::changedeity(int diety_id) { } void QuestManager::exp(int amt) { + QuestManagerCurrentQuestVars(); if (initiator && initiator->IsClient()) initiator->AddEXP(amt); } void QuestManager::level(int newlevel) { + QuestManagerCurrentQuestVars(); if (initiator && initiator->IsClient()) initiator->SetLevel(newlevel, true); } void QuestManager::traindisc(int discipline_tome_item_id) { + QuestManagerCurrentQuestVars(); if (initiator && initiator->IsClient()) initiator->TrainDiscipline(discipline_tome_item_id); } bool QuestManager::isdisctome(int item_id) { -//get the item info const Item_Struct *item = database.GetItem(item_id); if(item == nullptr) { return(false); @@ -745,11 +781,13 @@ bool QuestManager::isdisctome(int item_id) { } void QuestManager::safemove() { + QuestManagerCurrentQuestVars(); if (initiator && initiator->IsClient()) initiator->GoToSafeCoords(zone->GetZoneID(), 0); } void QuestManager::rain(int weather) { + QuestManagerCurrentQuestVars(); zone->zone_weather = weather; EQApplicationPacket* outapp = new EQApplicationPacket(OP_Weather, 8); *((uint32*) &outapp->pBuffer[4]) = (uint32) weather; // Why not just use 0x01/2/3? @@ -758,6 +796,7 @@ void QuestManager::rain(int weather) { } void QuestManager::snow(int weather) { + QuestManagerCurrentQuestVars(); zone->zone_weather = weather + 1; EQApplicationPacket* outapp = new EQApplicationPacket(OP_Weather, 8); outapp->pBuffer[0] = 0x01; @@ -767,6 +806,7 @@ void QuestManager::snow(int weather) { } void QuestManager::surname(const char *name) { + QuestManagerCurrentQuestVars(); //Changes the last name. if(initiator) { @@ -783,6 +823,7 @@ void QuestManager::surname(const char *name) { } void QuestManager::permaclass(int class_id) { + QuestManagerCurrentQuestVars(); //Makes the client the class specified initiator->SetBaseClass(class_id); initiator->Save(2); @@ -790,6 +831,7 @@ void QuestManager::permaclass(int class_id) { } void QuestManager::permarace(int race_id) { + QuestManagerCurrentQuestVars(); //Makes the client the race specified initiator->SetBaseRace(race_id); initiator->Save(2); @@ -797,6 +839,7 @@ void QuestManager::permarace(int race_id) { } void QuestManager::permagender(int gender_id) { + QuestManagerCurrentQuestVars(); //Makes the client the gender specified initiator->SetBaseGender(gender_id); initiator->Save(2); @@ -804,6 +847,7 @@ void QuestManager::permagender(int gender_id) { } uint16 QuestManager::scribespells(uint8 max_level, uint8 min_level) { + QuestManagerCurrentQuestVars(); uint16 book_slot, count; uint16 curspell; @@ -845,6 +889,7 @@ uint16 QuestManager::scribespells(uint8 max_level, uint8 min_level) { } uint16 QuestManager::traindiscs(uint8 max_level, uint8 min_level) { + QuestManagerCurrentQuestVars(); uint16 count; uint16 curspell; @@ -898,14 +943,17 @@ uint16 QuestManager::traindiscs(uint8 max_level, uint8 min_level) { } void QuestManager::unscribespells() { + QuestManagerCurrentQuestVars(); initiator->UnscribeSpellAll(); } void QuestManager::untraindiscs() { + QuestManagerCurrentQuestVars(); initiator->UntrainDiscAll(); } void QuestManager::givecash(int copper, int silver, int gold, int platinum) { + QuestManagerCurrentQuestVars(); if (initiator && initiator->IsClient() && ((copper + silver + gold + platinum) > 0)) { initiator->AddMoneyToPP(copper, silver, gold, platinum, true); @@ -954,6 +1002,7 @@ void QuestManager::givecash(int copper, int silver, int gold, int platinum) { } void QuestManager::pvp(const char *mode) { + QuestManagerCurrentQuestVars(); if (!strcasecmp(mode,"on")) { if (initiator) @@ -965,16 +1014,19 @@ void QuestManager::pvp(const char *mode) { } void QuestManager::movepc(int zone_id, float x, float y, float z, float heading) { + QuestManagerCurrentQuestVars(); if (initiator && initiator->IsClient()) initiator->MovePC(zone_id, x, y, z, heading); } void QuestManager::gmmove(float x, float y, float z) { + QuestManagerCurrentQuestVars(); if (initiator && initiator->IsClient()) initiator->GMMove(x, y, z); } void QuestManager::movegrp(int zoneid, float x, float y, float z) { + QuestManagerCurrentQuestVars(); if (initiator && initiator->IsClient()) { Group *g = entity_list.GetGroupByClient(initiator); @@ -1000,29 +1052,34 @@ void QuestManager::movegrp(int zoneid, float x, float y, float z) { } void QuestManager::doanim(int anim_id) { + QuestManagerCurrentQuestVars(); owner->DoAnim(anim_id); } void QuestManager::addskill(int skill_id, int value) { - if(skill_id < 0 || skill_id > HIGHEST_SKILL) //must check before casting. + QuestManagerCurrentQuestVars(); + if(skill_id < 0 || skill_id > HIGHEST_SKILL) return; if (initiator && initiator->IsClient()) initiator->AddSkill((SkillType) skill_id, value); } void QuestManager::setlanguage(int skill_id, int value) { + QuestManagerCurrentQuestVars(); if (initiator && initiator->IsClient()) initiator->SetLanguageSkill(skill_id, value); } void QuestManager::setskill(int skill_id, int value) { - if(skill_id < 0 || skill_id > HIGHEST_SKILL) //must check before casting. + QuestManagerCurrentQuestVars(); + if(skill_id < 0 || skill_id > HIGHEST_SKILL) return; if (initiator && initiator->IsClient()) initiator->SetSkill((SkillType) skill_id, value); } void QuestManager::setallskill(int value) { + QuestManagerCurrentQuestVars(); if (!initiator) return; if (initiator && initiator->IsClient()) { @@ -1034,6 +1091,7 @@ void QuestManager::setallskill(int value) { } void QuestManager::attack(const char *client_name) { + QuestManagerCurrentQuestVars(); if(!owner->IsNPC()) return; Client* getclient = entity_list.GetClientByName(client_name); @@ -1045,6 +1103,7 @@ void QuestManager::attack(const char *client_name) { } void QuestManager::attacknpc(int npc_entity_id) { + QuestManagerCurrentQuestVars(); if(!owner->IsNPC()) return; Mob *it = entity_list.GetMob(npc_entity_id); @@ -1059,6 +1118,7 @@ void QuestManager::attacknpc(int npc_entity_id) { } void QuestManager::attacknpctype(int npc_type_id) { + QuestManagerCurrentQuestVars(); if(!owner->IsNPC()) return; Mob *it = entity_list.GetMobByNpcTypeID(npc_type_id); @@ -1073,15 +1133,15 @@ void QuestManager::attacknpctype(int npc_type_id) { } void QuestManager::save() { + QuestManagerCurrentQuestVars(); if (initiator && initiator->IsClient()) initiator->Save(); } void QuestManager::faction(int faction_id, int faction_value, int temp) { + QuestManagerCurrentQuestVars(); if (initiator && initiator->IsClient()) { if(faction_id != 0 && faction_value != 0) { - // fixed faction command - //Client *p; initiator->SetFactionLevel2( initiator->CharacterID(), faction_id, @@ -1090,12 +1150,12 @@ void QuestManager::faction(int faction_id, int faction_value, int temp) { initiator->GetDeity(), faction_value, temp); - } } } void QuestManager::setsky(uint8 new_sky) { + QuestManagerCurrentQuestVars(); if (zone) zone->newzone_data.sky = new_sky; EQApplicationPacket* outapp = new EQApplicationPacket(OP_NewZone, sizeof(NewZone_Struct)); @@ -1105,12 +1165,14 @@ void QuestManager::setsky(uint8 new_sky) { } void QuestManager::setguild(uint32 new_guild_id, uint8 new_rank) { + QuestManagerCurrentQuestVars(); if (initiator && initiator->IsClient()) { guild_mgr.SetGuild(initiator->CharacterID(), new_guild_id, new_rank); } } void QuestManager::CreateGuild(const char *guild_name, const char *leader) { + QuestManagerCurrentQuestVars(); uint32 cid = database.GetCharacterID(leader); char hString[250]; if (cid == 0) { @@ -1143,6 +1205,7 @@ void QuestManager::settime(uint8 new_hour, uint8 new_min) { } void QuestManager::itemlink(int item_id) { + QuestManagerCurrentQuestVars(); const ItemInst* inst = database.CreateItem(item_id); char* link = 0; if (initiator->MakeItemLink(link, inst)) @@ -1152,8 +1215,6 @@ void QuestManager::itemlink(int item_id) { } void QuestManager::signalwith(int npc_id, int signal_id, int wait_ms) { -// signal command - // signal(npcid) - generates EVENT_SIGNAL on specified npc if(wait_ms > 0) { STimerList.push_back(SignalTimer(wait_ms, npc_id, signal_id)); return; @@ -1175,9 +1236,7 @@ void QuestManager::signal(int npc_id, int wait_ms) { } void QuestManager::setglobal(const char *varname, const char *newvalue, int options, const char *duration) { -// qglobal variable commands - // setglobal(varname,value,options,duration) - //MYSQL_ROW row; + QuestManagerCurrentQuestVars(); int qgZoneid=zone->GetZoneID(); int qgCharid=0; int qgNpcid = owner->GetNPCTypeID(); @@ -1315,7 +1374,7 @@ void QuestManager::targlobal(const char *varname, const char *value, const char } void QuestManager::delglobal(const char *varname) { - // delglobal(varname) + QuestManagerCurrentQuestVars(); char errbuf[MYSQL_ERRMSG_SIZE]; char *query = 0; int qgZoneid=zone->GetZoneID(); @@ -1417,6 +1476,7 @@ int QuestManager::QGVarDuration(const char *fmt) } void QuestManager::ding() { + QuestManagerCurrentQuestVars(); //makes a sound. if (initiator && initiator->IsClient()) initiator->SendSound(); @@ -1424,65 +1484,77 @@ void QuestManager::ding() { } void QuestManager::rebind(int zoneid, float x, float y, float z) { + QuestManagerCurrentQuestVars(); if(initiator && initiator->IsClient()) { initiator->SetBindPoint(zoneid, x, y, z); } } void QuestManager::start(int32 wp) { + QuestManagerCurrentQuestVars(); if(!owner->IsNPC()) return; owner->CastToNPC()->AssignWaypoints(wp); } void QuestManager::stop() { + QuestManagerCurrentQuestVars(); if(!owner->IsNPC()) return; owner->CastToNPC()->StopWandering(); } void QuestManager::pause(int duration) { + QuestManagerCurrentQuestVars(); if(!owner->IsNPC()) return; owner->CastToNPC()->PauseWandering(duration); } void QuestManager::moveto(float x, float y, float z, float h, bool saveguardspot) { + QuestManagerCurrentQuestVars(); if(!owner->IsNPC()) return; owner->CastToNPC()->MoveTo(x, y, z, h, saveguardspot); } void QuestManager::resume() { + QuestManagerCurrentQuestVars(); if(!owner->IsNPC()) return; owner->CastToNPC()->ResumeWandering(); } void QuestManager::addldonpoints(int32 points, uint32 theme) { + QuestManagerCurrentQuestVars(); if(initiator) initiator->UpdateLDoNPoints(points, theme); } void QuestManager::addldonwin(int32 wins, uint32 theme) { + QuestManagerCurrentQuestVars(); if(initiator) initiator->UpdateLDoNWins(theme, wins); } void QuestManager::addldonloss(int32 losses, uint32 theme) { + QuestManagerCurrentQuestVars(); if(initiator) initiator->UpdateLDoNLosses(theme, losses); } void QuestManager::setnexthpevent(int at) { + QuestManagerCurrentQuestVars(); owner->SetNextHPEvent( at ); } void QuestManager::setnextinchpevent(int at) { + QuestManagerCurrentQuestVars(); owner->SetNextIncHPEvent( at ); } void QuestManager::respawn(int npc_type, int grid) { + QuestManagerCurrentQuestVars(); if(!owner->IsNPC()) return; //char tempa[100]; @@ -1510,6 +1582,7 @@ void QuestManager::respawn(int npc_type, int grid) { } void QuestManager::set_proximity(float minx, float maxx, float miny, float maxy, float minz, float maxz) { + QuestManagerCurrentQuestVars(); if(!owner->IsNPC()) return; @@ -1521,20 +1594,24 @@ void QuestManager::set_proximity(float minx, float maxx, float miny, float maxy, owner->CastToNPC()->proximity->max_y = maxy; owner->CastToNPC()->proximity->min_z = minz; owner->CastToNPC()->proximity->max_z = maxz; - - owner->CastToNPC()->proximity->say = parse->HasQuestSub(owner->CastToNPC()->GetNPCTypeID(), "EVENT_PROXIMITY_SAY"); - - if(owner->CastToNPC()->proximity->say) - HaveProximitySays = true; } void QuestManager::clear_proximity() { + QuestManagerCurrentQuestVars(); if(!owner->IsNPC()) return; entity_list.RemoveProximity(owner->GetID()); safe_delete(owner->CastToNPC()->proximity); } +void QuestManager::enable_proximity_say() { + HaveProximitySays = true; +} + +void QuestManager::disable_proximity_say() { + HaveProximitySays = false; +} + void QuestManager::setanim(int npc_type, int animnum) { //adds appearance changes Mob* thenpc = entity_list.GetMobByNpcTypeID(npc_type); @@ -1543,9 +1620,9 @@ void QuestManager::setanim(int npc_type, int animnum) { thenpc->SetAppearance(EmuAppearance(animnum)); } - //displays an in game path based on a waypoint grid void QuestManager::showgrid(int grid) { + QuestManagerCurrentQuestVars(); if(initiator == nullptr) return; @@ -1584,16 +1661,6 @@ void QuestManager::showgrid(int grid) { safe_delete_array(query); } -//displays an in game path based on path finding. -void QuestManager::showpath(float x, float y, float z) { - say("showpath not implemented yet."); -} - -//causes the npc to use path finding to walk to x,y,z -void QuestManager::pathto(float x, float y, float z) { - say("pathto not implemented yet."); -} - //change the value of a spawn condition void QuestManager::spawn_condition(const char *zone_short, uint32 instance_id, uint16 condition_id, short new_value) { zone->spawn_conditions.SetCondition(zone_short, instance_id, condition_id, new_value); @@ -1610,21 +1677,23 @@ void QuestManager::toggle_spawn_event(int event_id, bool enable, bool reset_base } bool QuestManager::has_zone_flag(int zone_id) { + QuestManagerCurrentQuestVars(); return(initiator->HasZoneFlag(zone_id)); } void QuestManager::set_zone_flag(int zone_id) { + QuestManagerCurrentQuestVars(); initiator->SetZoneFlag(zone_id); } void QuestManager::clear_zone_flag(int zone_id) { + QuestManagerCurrentQuestVars(); initiator->ClearZoneFlag(zone_id); } void QuestManager::sethp(int hpperc) { - int newhp; - - newhp = (owner->GetMaxHP()*(100-hpperc))/100; + QuestManagerCurrentQuestVars(); + int newhp = (owner->GetMaxHP() * (100 - hpperc)) / 100; owner->Damage(owner, newhp, SPELL_UNKNOWN, HAND_TO_HAND, false, 0, false); } @@ -1726,44 +1795,53 @@ bool QuestManager::isdooropen(uint32 doorid) { } void QuestManager::npcrace(int race_id) { + QuestManagerCurrentQuestVars(); owner->SendIllusionPacket(race_id); } void QuestManager::npcgender(int gender_id) { + QuestManagerCurrentQuestVars(); owner->SendIllusionPacket(owner->GetRace(), gender_id); } void QuestManager::npcsize(int newsize) { + QuestManagerCurrentQuestVars(); owner->ChangeSize(newsize, true); } void QuestManager::npctexture(int newtexture) { + QuestManagerCurrentQuestVars(); owner->SendIllusionPacket(owner->GetRace(), 0xFF, newtexture); } void QuestManager::playerrace(int race_id) { + QuestManagerCurrentQuestVars(); initiator->SendIllusionPacket(race_id); } void QuestManager::playergender(int gender_id) { + QuestManagerCurrentQuestVars(); initiator->SendIllusionPacket(initiator->GetRace(), gender_id); } void QuestManager::playersize(int newsize) { + QuestManagerCurrentQuestVars(); initiator->ChangeSize(newsize, true); } void QuestManager::playertexture(int newtexture) { + QuestManagerCurrentQuestVars(); initiator->SendIllusionPacket(initiator->GetRace(), 0xFF, newtexture); } void QuestManager::playerfeature(char *feature, int setting) { + QuestManagerCurrentQuestVars(); uint16 Race = initiator->GetRace(); uint8 Gender = initiator->GetGender(); uint8 Texture = 0xFF; @@ -1820,6 +1898,7 @@ void QuestManager::playerfeature(char *feature, int setting) void QuestManager::npcfeature(char *feature, int setting) { + QuestManagerCurrentQuestVars(); uint16 Race = owner->GetRace(); uint8 Gender = owner->GetGender(); uint8 Texture = 0xFF; @@ -1876,6 +1955,7 @@ void QuestManager::npcfeature(char *feature, int setting) void QuestManager::popup(char *title, char *text, uint32 popupid, uint32 buttons, uint32 Duration) { + QuestManagerCurrentQuestVars(); if(initiator) initiator->SendPopupToClient(title, text, popupid, buttons, Duration); } @@ -1897,6 +1977,7 @@ bool QuestManager::botquest() bool QuestManager::createBot(const char *name, const char *lastname, uint8 level, uint16 race, uint8 botclass, uint8 gender) { + QuestManagerCurrentQuestVars(); std::string TempErrorMessage; uint32 MaxBotCreate = RuleI(Bots, CreateBotCount); @@ -1957,22 +2038,26 @@ bool QuestManager::createBot(const char *name, const char *lastname, uint8 level #endif //BOTS void QuestManager::taskselector(int taskcount, int *tasks) { + QuestManagerCurrentQuestVars(); if(RuleB(TaskSystem, EnableTaskSystem) && initiator && owner && taskmanager) taskmanager->SendTaskSelector(initiator, owner, taskcount, tasks); } void QuestManager::enabletask(int taskcount, int *tasks) { + QuestManagerCurrentQuestVars(); if(RuleB(TaskSystem, EnableTaskSystem) && initiator && taskmanager) initiator->EnableTask(taskcount, tasks); } void QuestManager::disabletask(int taskcount, int *tasks) { + QuestManagerCurrentQuestVars(); if(RuleB(TaskSystem, EnableTaskSystem) && initiator && taskmanager) initiator->DisableTask(taskcount, tasks); } bool QuestManager::istaskenabled(int taskid) { + QuestManagerCurrentQuestVars(); if(RuleB(TaskSystem, EnableTaskSystem) && initiator && taskmanager) return initiator->IsTaskEnabled(taskid); @@ -1981,12 +2066,14 @@ bool QuestManager::istaskenabled(int taskid) { } void QuestManager::tasksetselector(int tasksetid) { + QuestManagerCurrentQuestVars(); _log(TASKS__UPDATE, "TaskSetSelector called for task set %i", tasksetid); if(RuleB(TaskSystem, EnableTaskSystem) && initiator && owner && taskmanager) initiator->TaskSetSelector(owner, tasksetid); } bool QuestManager::istaskactive(int task) { + QuestManagerCurrentQuestVars(); if(RuleB(TaskSystem, EnableTaskSystem) && initiator) return initiator->IsTaskActive(task); @@ -1994,6 +2081,7 @@ bool QuestManager::istaskactive(int task) { return false; } bool QuestManager::istaskactivityactive(int task, int activity) { + QuestManagerCurrentQuestVars(); if(RuleB(TaskSystem, EnableTaskSystem) && initiator) return initiator->IsTaskActivityActive(task, activity); @@ -2001,44 +2089,51 @@ bool QuestManager::istaskactivityactive(int task, int activity) { return false; } int QuestManager::gettaskactivitydonecount(int task, int activity) { + QuestManagerCurrentQuestVars(); if(RuleB(TaskSystem, EnableTaskSystem) && initiator) return initiator->GetTaskActivityDoneCountFromTaskID(task, activity); - return 0; //improper args + return 0; } void QuestManager::updatetaskactivity(int task, int activity, int count) { + QuestManagerCurrentQuestVars(); if(RuleB(TaskSystem, EnableTaskSystem) && initiator) initiator->UpdateTaskActivity(task, activity, count); } void QuestManager::resettaskactivity(int task, int activity) { + QuestManagerCurrentQuestVars(); if(RuleB(TaskSystem, EnableTaskSystem) && initiator) initiator->ResetTaskActivity(task, activity); } void QuestManager::taskexploredarea(int exploreid) { + QuestManagerCurrentQuestVars(); if(RuleB(TaskSystem, EnableTaskSystem) && initiator) initiator->UpdateTasksOnExplore(exploreid); } void QuestManager::assigntask(int taskid) { + QuestManagerCurrentQuestVars(); if(RuleB(TaskSystem, EnableTaskSystem) && initiator && owner) initiator->AssignTask(taskid, owner->GetID()); } void QuestManager::failtask(int taskid) { + QuestManagerCurrentQuestVars(); if(RuleB(TaskSystem, EnableTaskSystem) && initiator) initiator->FailTask(taskid); } int QuestManager::tasktimeleft(int taskid) { + QuestManagerCurrentQuestVars(); if(RuleB(TaskSystem, EnableTaskSystem) && initiator) return initiator->TaskTimeLeft(taskid); @@ -2047,6 +2142,7 @@ int QuestManager::tasktimeleft(int taskid) { } int QuestManager::enabledtaskcount(int taskset) { + QuestManagerCurrentQuestVars(); if(RuleB(TaskSystem, EnableTaskSystem) && initiator) return initiator->EnabledTaskCount(taskset); @@ -2054,6 +2150,7 @@ int QuestManager::enabledtaskcount(int taskset) { return -1; } int QuestManager::firsttaskinset(int taskset) { + QuestManagerCurrentQuestVars(); if(RuleB(TaskSystem, EnableTaskSystem) && taskmanager) return taskmanager->FirstTaskInSet(taskset); @@ -2061,6 +2158,7 @@ int QuestManager::firsttaskinset(int taskset) { return -1; } int QuestManager::lasttaskinset(int taskset) { + QuestManagerCurrentQuestVars(); if(RuleB(TaskSystem, EnableTaskSystem) && taskmanager) return taskmanager->LastTaskInSet(taskset); @@ -2068,6 +2166,7 @@ int QuestManager::lasttaskinset(int taskset) { return -1; } int QuestManager::nexttaskinset(int taskset, int taskid) { + QuestManagerCurrentQuestVars(); if(RuleB(TaskSystem, EnableTaskSystem) && taskmanager) return taskmanager->NextTaskInSet(taskset, taskid); @@ -2075,12 +2174,14 @@ int QuestManager::nexttaskinset(int taskset, int taskid) { return -1; } int QuestManager::activespeaktask() { + QuestManagerCurrentQuestVars(); if(RuleB(TaskSystem, EnableTaskSystem) && initiator && owner) return initiator->ActiveSpeakTask(owner->GetNPCTypeID()); return 0; } int QuestManager::activespeakactivity(int taskid) { + QuestManagerCurrentQuestVars(); if(RuleB(TaskSystem, EnableTaskSystem) && initiator && owner) return initiator->ActiveSpeakActivity(owner->GetNPCTypeID(), taskid); @@ -2088,6 +2189,7 @@ int QuestManager::activespeakactivity(int taskid) { return 0; } int QuestManager::istaskcompleted(int taskid) { + QuestManagerCurrentQuestVars(); if(RuleB(TaskSystem, EnableTaskSystem) && initiator) return initiator->IsTaskCompleted(taskid); @@ -2095,6 +2197,7 @@ int QuestManager::istaskcompleted(int taskid) { return -1; } int QuestManager::activetasksinset(int taskset) { + QuestManagerCurrentQuestVars(); if(RuleB(TaskSystem, EnableTaskSystem) && initiator) return initiator->ActiveTasksInSet(taskset); @@ -2102,6 +2205,7 @@ int QuestManager::activetasksinset(int taskset) { return -1; } int QuestManager::completedtasksinset(int taskset) { + QuestManagerCurrentQuestVars(); if(RuleB(TaskSystem, EnableTaskSystem) && initiator) return initiator->CompletedTasksInSet(taskset); @@ -2110,6 +2214,7 @@ int QuestManager::completedtasksinset(int taskset) { } bool QuestManager::istaskappropriate(int task) { + QuestManagerCurrentQuestVars(); if(RuleB(TaskSystem, EnableTaskSystem) && initiator && taskmanager) return taskmanager->AppropriateLevel(task, initiator->GetLevel()); @@ -2142,6 +2247,7 @@ void QuestManager::we(int type, const char *str) { int QuestManager::getlevel(uint8 type) { + QuestManagerCurrentQuestVars(); if (type == 0) { return (initiator->GetLevel()); @@ -2201,6 +2307,7 @@ uint16 QuestManager::CreateGroundObjectFromModel(const char *model, float x, flo void QuestManager::ModifyNPCStat(const char *identifier, const char *newValue) { + QuestManagerCurrentQuestVars(); if(owner){ if(owner->IsNPC()) { @@ -2212,6 +2319,7 @@ void QuestManager::ModifyNPCStat(const char *identifier, const char *newValue) int QuestManager::collectitems_processSlot(int16 slot_id, uint32 item_id, bool remove) { + QuestManagerCurrentQuestVars(); ItemInst *item; int quantity = 0; @@ -2337,6 +2445,7 @@ uint32 QuestManager::MerchantCountItem(uint32 NPCid, uint32 itemid) { // Item Link for use in Variables - "my $example_link = quest::varlink(item_id);" const char* QuestManager::varlink(char* perltext, int item_id) { + QuestManagerCurrentQuestVars(); const ItemInst* inst = database.CreateItem(item_id); if (!inst) return "INVALID ITEM ID IN VARLINK"; @@ -2344,7 +2453,7 @@ const char* QuestManager::varlink(char* perltext, int item_id) { char* tempstr = 0; if (initiator->MakeItemLink(link, inst)) { // make a link to the item MakeAnyLenString(&tempstr, "%c%s%s%c", 0x12, link, inst->GetItem()->Name, 0x12); - strn0cpy(perltext, tempstr,250); // the perl string is only 250 chars, so make sure the link isn't too large + strn0cpy(perltext, tempstr, 250); // the perl string is only 250 chars, so make sure the link isn't too large safe_delete_array(tempstr); // MakeAnyLenString() uses new, so clean up after it } safe_delete_array(link); // MakeItemLink() uses new also @@ -2354,6 +2463,7 @@ const char* QuestManager::varlink(char* perltext, int item_id) { uint16 QuestManager::CreateInstance(const char *zone, int16 version, uint32 duration) { + QuestManagerCurrentQuestVars(); if(initiator) { uint32 zone_id = database.GetZoneID(zone); @@ -2384,6 +2494,7 @@ void QuestManager::DestroyInstance(uint16 instance_id) uint16 QuestManager::GetInstanceID(const char *zone, int16 version) { + QuestManagerCurrentQuestVars(); if(initiator) { return database.GetInstanceID(zone, initiator->CharacterID(), version); @@ -2393,6 +2504,7 @@ uint16 QuestManager::GetInstanceID(const char *zone, int16 version) void QuestManager::AssignToInstance(uint16 instance_id) { + QuestManagerCurrentQuestVars(); if(initiator) { database.AddClientToInstance(instance_id, initiator->CharacterID()); @@ -2401,6 +2513,7 @@ void QuestManager::AssignToInstance(uint16 instance_id) void QuestManager::AssignGroupToInstance(uint16 instance_id) { + QuestManagerCurrentQuestVars(); if(initiator) { Group *g = initiator->GetGroup(); @@ -2414,6 +2527,7 @@ void QuestManager::AssignGroupToInstance(uint16 instance_id) void QuestManager::AssignRaidToInstance(uint16 instance_id) { + QuestManagerCurrentQuestVars(); if(initiator) { Raid *r = initiator->GetRaid(); @@ -2427,6 +2541,7 @@ void QuestManager::AssignRaidToInstance(uint16 instance_id) void QuestManager::MovePCInstance(int zone_id, int instance_id, float x, float y, float z, float heading) { + QuestManagerCurrentQuestVars(); if(initiator) { initiator->MovePC(zone_id, instance_id, x, y, z, heading); @@ -2435,6 +2550,7 @@ void QuestManager::MovePCInstance(int zone_id, int instance_id, float x, float y void QuestManager::FlagInstanceByGroupLeader(uint32 zone, int16 version) { + QuestManagerCurrentQuestVars(); if(initiator) { Group *g = initiator->GetGroup(); @@ -2446,6 +2562,7 @@ void QuestManager::FlagInstanceByGroupLeader(uint32 zone, int16 version) void QuestManager::FlagInstanceByRaidLeader(uint32 zone, int16 version) { + QuestManagerCurrentQuestVars(); if(initiator) { Raid *r = initiator->GetRaid(); @@ -2457,6 +2574,7 @@ void QuestManager::FlagInstanceByRaidLeader(uint32 zone, int16 version) } const char* QuestManager::saylink(char* Phrase, bool silent, char* LinkName) { + QuestManagerCurrentQuestVars(); const char *ERR_MYSQLERROR = "Error in saylink phrase queries"; char errbuf[MYSQL_ERRMSG_SIZE]; @@ -2548,6 +2666,7 @@ const char* QuestManager::getguildnamebyid(int guild_id) { void QuestManager::SetRunning(bool val) { + QuestManagerCurrentQuestVars(); if(!owner) return; owner->SetRunning(val); @@ -2555,6 +2674,7 @@ void QuestManager::SetRunning(bool val) bool QuestManager::IsRunning() { + QuestManagerCurrentQuestVars(); if(!owner) return false; return owner->IsRunning(); @@ -2562,6 +2682,7 @@ bool QuestManager::IsRunning() void QuestManager::FlyMode(uint8 flymode) { + QuestManagerCurrentQuestVars(); if(initiator) { if (flymode >= 0 && flymode < 3) { @@ -2580,6 +2701,7 @@ void QuestManager::FlyMode(uint8 flymode) uint8 QuestManager::FactionValue() { + QuestManagerCurrentQuestVars(); FACTION_VALUE oldfac; uint8 newfac = 0; if(initiator && owner->IsNPC()) { @@ -2621,21 +2743,23 @@ uint8 QuestManager::FactionValue() } void QuestManager::enabletitle(int titleset) { + QuestManagerCurrentQuestVars(); initiator->EnableTitle(titleset); } - - bool QuestManager::checktitle(int titleset) { + QuestManagerCurrentQuestVars(); return initiator->CheckTitle(titleset); } void QuestManager::removetitle(int titleset) { + QuestManagerCurrentQuestVars(); initiator->RemoveTitle(titleset); } void QuestManager::wearchange(uint8 slot, uint16 texture) { + QuestManagerCurrentQuestVars(); if(owner){ owner->SendTextureWC(slot, texture); if(owner->IsNPC()) { @@ -2646,6 +2770,7 @@ void QuestManager::wearchange(uint8 slot, uint16 texture) void QuestManager::voicetell(char *str, int macronum, int racenum, int gendernum) { + QuestManagerCurrentQuestVars(); if(owner && str) { Client *c = entity_list.GetClientByName(str); @@ -2674,6 +2799,7 @@ void QuestManager::voicetell(char *str, int macronum, int racenum, int gendernum } void QuestManager::LearnRecipe(uint32 recipe_id) { + QuestManagerCurrentQuestVars(); if(!initiator) return; initiator->LearnRecipe(recipe_id); @@ -2736,7 +2862,6 @@ void QuestManager::CrossZoneSignalPlayerByName(const char *CharName, uint32 data safe_delete(pack); } - void QuestManager::CrossZoneMessagePlayerByName(uint32 Type, const char *CharName, const char *Message){ uint32 message_len = strlen(CharName) + 1; uint32 message_len2 = strlen(Message) + 1; @@ -2749,3 +2874,38 @@ void QuestManager::CrossZoneMessagePlayerByName(uint32 Type, const char *CharNam safe_delete(pack); } +Client *QuestManager::GetInitiator() const { + if(!quests_running_.empty()) { + running_quest e = quests_running_.top(); + return e.initiator; + } + + return nullptr; +} + +NPC *QuestManager::GetNPC() const { + if(!quests_running_.empty()) { + running_quest e = quests_running_.top(); + return (e.owner && e.owner->IsNPC()) ? e.owner->CastToNPC() : nullptr; + } + + return nullptr; +} + +Mob *QuestManager::GetOwner() const { + if(!quests_running_.empty()) { + running_quest e = quests_running_.top(); + return e.owner; + } + + return nullptr; +} + +ItemInst *QuestManager::GetQuestItem() const { + if(!quests_running_.empty()) { + running_quest e = quests_running_.top(); + return e.questitem; + } + + return nullptr; +} diff --git a/zone/questmgr.h b/zone/questmgr.h index 09b40eee1..f980d0dbd 100644 --- a/zone/questmgr.h +++ b/zone/questmgr.h @@ -18,18 +18,24 @@ #ifndef __QUEST_MANAGER_H__ #define __QUEST_MANAGER_H__ -#include "../common/Mutex.h" #include "../common/timer.h" #include "tasks.h" #include #include +#include using namespace std; class NPC; class Client; class QuestManager { + struct running_quest { + Mob *owner; + Client *initiator; + ItemInst* questitem; + bool depop_npc; + }; public: QuestManager(); virtual ~QuestManager(); @@ -42,21 +48,20 @@ public: void ClearTimers(Mob *who); void ClearAllTimers(); - //quest perl functions + //quest functions void echo(int colour, const char *str); void say(const char *str); void say(const char *str, uint8 language); void me(const char *str); void summonitem(uint32 itemid, int16 charges = 0); - //getZoneID(const char *short_name) void write(const char *file, const char *str); - uint16 spawn2(int npc_type, int grid, int unused, float x, float y, float z, float heading); - uint16 unique_spawn(int npc_type, int grid, int unused, float x, float y, float z, float heading = 0); - uint16 spawn_from_spawn2(uint32 spawn2_id); + Mob* spawn2(int npc_type, int grid, int unused, float x, float y, float z, float heading); + Mob* unique_spawn(int npc_type, int grid, int unused, float x, float y, float z, float heading = 0); + Mob* spawn_from_spawn2(uint32 spawn2_id); void enable_spawn2(uint32 spawn2_id); void disable_spawn2(uint32 spawn2_id); void setstat(int stat, int value); - void incstat(int stat, int value); //old setstat command + void incstat(int stat, int value); void castspell(int spell_id, int target_id); void selfcast(int spell_id); void addloot(int item_id, int charges = 0, bool equipitem = true); @@ -133,10 +138,10 @@ public: void respawn(int npc_type, int grid); void set_proximity(float minx, float maxx, float miny, float maxy, float minz=-999999, float maxz=999999); void clear_proximity(); + void enable_proximity_say(); + void disable_proximity_say(); void setanim(int npc_type, int animnum); void showgrid(int gridid); - void showpath(float x, float y, float z); - void pathto(float x, float y, float z); void spawn_condition(const char *zone_short, uint32 instance_id, uint16 condition_id, short new_value); short get_spawn_condition(const char *zone_short, uint32 instance_id, uint16 condition_id); void toggle_spawn_event(int event_id, bool enable, bool reset_base); @@ -195,15 +200,12 @@ public: void enabletitle(int titleset); bool checktitle(int titlecheck); void removetitle(int titlecheck); - uint16 CreateGroundObject(uint32 itemid, float x, float y, float z, float heading, uint32 decay_time = 300000); uint16 CreateGroundObjectFromModel(const char* model, float x, float y, float z, float heading, uint8 type = 0x00, uint32 decay_time = 0); void ModifyNPCStat(const char *identifier, const char *newValue); void UpdateSpawnTimer(uint32 id, uint32 newTime); - void MerchantSetItem(uint32 NPCid, uint32 itemid, uint32 quantity = 0); uint32 MerchantCountItem(uint32 NPCid, uint32 itemid); - uint16 CreateInstance(const char *zone, int16 version, uint32 duration); void DestroyInstance(uint16 instance_id); uint16 GetInstanceID(const char *zone, int16 version); @@ -213,7 +215,6 @@ public: void MovePCInstance(int zone_id, int instance_id, float x, float y, float z, float heading); void FlagInstanceByGroupLeader(uint32 zone, int16 version); void FlagInstanceByRaidLeader(uint32 zone, int16 version); - const char* varlink(char* perltext, int item_id); const char* saylink(char* Phrase, bool silent, char* LinkName); const char* getguildnamebyid(int guild_id); @@ -228,20 +229,16 @@ public: uint16 CreateDoor( const char* model, float x, float y, float z, float heading, uint8 opentype, uint16 size); int32 GetZoneID(const char *zone); const char *GetZoneLongName(const char *zone); - - //not in here because it retains perl types - //thing ChooseRandom(array_of_things) - - inline Client *GetInitiator() const { return(initiator); } - inline NPC *GetNPC() const { return(owner->IsNPC()?owner->CastToNPC():nullptr); } - inline Mob *GetOwner() const { return(owner); } - inline ItemInst *GetQuestItem() const {return questitem; } - inline bool ProximitySayInUse() { return HaveProximitySays; } - void CrossZoneSignalPlayerByCharID(int charid, uint32 data); void CrossZoneSignalPlayerByName(const char *CharName, uint32 data); void CrossZoneMessagePlayerByName(uint32 Type, const char *CharName, const char *Message); + Client *GetInitiator() const; + NPC *GetNPC() const; + Mob *GetOwner() const; + ItemInst *GetQuestItem() const; + inline bool ProximitySayInUse() { return HaveProximitySays; } + #ifdef BOTS int createbotcount(); int spawnbotcount(); @@ -251,14 +248,9 @@ public: inline uint16 GetMana(uint32 spell_id) { return( spells[spell_id].mana); } -protected: - Mob *owner; //NPC is never nullptr when functions are called. - Client *initiator; //this can be null. - ItemInst* questitem; // this is usually nullptr. +private: + std::stack quests_running_; - bool depop_npc; //true if EndQuest should depop the NPC - - Mutex quest_mutex; bool HaveProximitySays; int QGVarDuration(const char *fmt);