diff --git a/zone/lua_parser.cpp b/zone/lua_parser.cpp index 5063833b5..29cb3fd17 100644 --- a/zone/lua_parser.cpp +++ b/zone/lua_parser.cpp @@ -409,6 +409,11 @@ LuaParser::LuaParser() { BotArgumentDispatch[EVENT_ENTITY_VARIABLE_SET] = handle_bot_entity_variable; BotArgumentDispatch[EVENT_ENTITY_VARIABLE_UPDATE] = handle_bot_entity_variable; BotArgumentDispatch[EVENT_SPELL_BLOCKED] = handle_bot_spell_blocked; + + ZoneArgumentDispatch[EVENT_TIMER_PAUSE] = handle_zone_timer_pause_resume_start; + ZoneArgumentDispatch[EVENT_TIMER_RESUME] = handle_zone_timer_pause_resume_start; + ZoneArgumentDispatch[EVENT_TIMER_START] = handle_zone_timer_pause_resume_start; + ZoneArgumentDispatch[EVENT_TIMER_STOP] = handle_zone_timer_stop; #endif L = nullptr; @@ -2083,3 +2088,190 @@ void LuaParser::LoadMercScript(std::string filename) { void LuaParser::LoadGlobalMercScript(std::string filename) { LoadScript(filename, "global_merc"); } + +int LuaParser::EventZone( + QuestEventID evt, + Zone *zone, + std::string data, + uint32 extra_data, + std::vector *extra_pointers +) { + evt = ConvertLuaEvent(evt); + if (evt >= _LargestEventID) { + return 0; + } + + if (!zone) { + return 0; + } + + if (!ZoneHasQuestSub(evt)) { + return 0; + } + + return _EventZone("zone", evt, zone, data, extra_data, extra_pointers); +} + +int LuaParser::EventGlobalZone( + QuestEventID evt, + Zone *zone, + std::string data, + uint32 extra_data, + std::vector *extra_pointers +) { + evt = ConvertLuaEvent(evt); + if (evt >= _LargestEventID) { + return 0; + } + + if (!zone) { + return 0; + } + + if (!GlobalZoneHasQuestSub(evt)) { + return 0; + } + + return _EventZone("global_zone", evt, zone, data, extra_data, extra_pointers); +} + +int LuaParser::_EventZone( + std::string package_name, + QuestEventID evt, + Zone *zone, + std::string data, + uint32 extra_data, + std::vector *extra_pointers, + luabind::adl::object *l_func +) { + const char *sub_name = LuaEvents[evt]; + int start = lua_gettop(L); + + try { + int npop = 2; + PushErrorHandler(L); + if(l_func != nullptr) { + l_func->push(L); + } else { + lua_getfield(L, LUA_REGISTRYINDEX, package_name.c_str()); + lua_getfield(L, -1, sub_name); + npop = 3; + } + + lua_createtable(L, 0, 0); + //push self + Lua_Zone l_zone(zone); + luabind::adl::object l_zone_o = luabind::adl::object(L, l_zone); + l_zone_o.push(L); + lua_setfield(L, -2, "self"); + + auto arg_function = ZoneArgumentDispatch[evt]; + arg_function(this, L, zone, data, extra_data, extra_pointers); + + QuestManager::RunningQuest q; + + q.zone = zone; + + quest_manager.StartQuest(q); + + if(lua_pcall(L, 1, 1, start + 1)) { + std::string error = lua_tostring(L, -1); + AddError(error); + quest_manager.EndQuest(); + lua_pop(L, npop); + return 0; + } + quest_manager.EndQuest(); + + if(lua_isnumber(L, -1)) { + int ret = static_cast(lua_tointeger(L, -1)); + lua_pop(L, npop); + return ret; + } + + lua_pop(L, npop); + } catch(std::exception &ex) { + AddError( + fmt::format( + "Lua Exception | [{}] for Zone [{}] in [{}]: {}", + sub_name, + zone->GetShortName(), + package_name, + ex.what() + ) + ); + + //Restore our stack to the best of our ability + int end = lua_gettop(L); + int n = end - start; + if(n > 0) { + lua_pop(L, n); + } + } + + return 0; +} + +int LuaParser::DispatchEventZone( + QuestEventID evt, + Zone *zone, + std::string data, + uint32 extra_data, + std::vector *extra_pointers +) { + evt = ConvertLuaEvent(evt); + if (evt >= _LargestEventID) { + return 0; + } + + std::string package_name = "zone"; + + auto iter = lua_encounter_events_registered.find(package_name); + if (iter == lua_encounter_events_registered.end()) { + return 0; + } + + int ret = 0; + auto riter = iter->second.begin(); + while (riter != iter->second.end()) { + if (riter->event_id == evt) { + package_name = fmt::format("encounter_{}", riter->encounter_name); + int i = _EventZone(package_name, evt, zone, data, extra_data, extra_pointers, &riter->lua_reference); + if (i != 0) { + ret = i; + } + } + + ++riter; + } + + return ret; +} + +bool LuaParser::ZoneHasQuestSub(QuestEventID evt) { + evt = ConvertLuaEvent(evt); + if (evt >= _LargestEventID) { + return false; + } + + const char *subname = LuaEvents[evt]; + return HasFunction(subname, "zone"); +} + +bool LuaParser::GlobalZoneHasQuestSub(QuestEventID evt) { + evt = ConvertLuaEvent(evt); + if (evt >= _LargestEventID) { + return false; + } + + const char *subname = LuaEvents[evt]; + return HasFunction(subname, "global_zone"); +} + +void LuaParser::LoadZoneScript(std::string filename) { + LoadScript(filename, "zone"); +} + +void LuaParser::LoadGlobalZoneScript(std::string filename) { + LoadScript(filename, "global_zone"); +} diff --git a/zone/lua_parser.h b/zone/lua_parser.h index fbd50a984..c1bad7088 100644 --- a/zone/lua_parser.h +++ b/zone/lua_parser.h @@ -125,6 +125,20 @@ public: uint32 extra_data, std::vector* extra_pointers ); + virtual int EventZone( + QuestEventID evt, + Zone* zone, + std::string data, + uint32 extra_data, + std::vector* extra_pointers + ); + virtual int EventGlobalZone( + QuestEventID evt, + Zone* zone, + std::string data, + uint32 extra_data, + std::vector* extra_pointers + ); virtual bool HasQuestSub(uint32 npc_id, QuestEventID evt); virtual bool HasGlobalQuestSub(QuestEventID evt); @@ -138,6 +152,8 @@ public: virtual bool GlobalBotHasQuestSub(QuestEventID evt); virtual bool MercHasQuestSub(QuestEventID evt); virtual bool GlobalMercHasQuestSub(QuestEventID evt); + virtual bool ZoneHasQuestSub(QuestEventID evt); + virtual bool GlobalZoneHasQuestSub(QuestEventID evt); virtual void LoadNPCScript(std::string filename, int npc_id); virtual void LoadGlobalNPCScript(std::string filename); @@ -150,6 +166,8 @@ public: virtual void LoadGlobalBotScript(std::string filename); virtual void LoadMercScript(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 std::string GetVar(std::string name); @@ -207,6 +225,13 @@ public: uint32 extra_data, std::vector* extra_pointers ); + virtual int DispatchEventZone( + QuestEventID evt, + Zone* zone, + std::string data, + uint32 extra_data, + std::vector* extra_pointers + ); static LuaParser* Instance() { static LuaParser inst; @@ -307,6 +332,15 @@ private: std::vector* extra_pointers, luabind::adl::object* l_func = nullptr ); + int _EventZone( + std::string package_name, + QuestEventID evt, + Zone* zone, + std::string data, + uint32 extra_data, + std::vector* extra_pointers, + luabind::adl::object* l_func = nullptr + ); void LoadScript(std::string filename, std::string package_name); void MapFunctions(lua_State *L); @@ -317,12 +351,13 @@ private: std::vector mods_; lua_State *L; - NPCArgumentHandler NPCArgumentDispatch[_LargestEventID]; - PlayerArgumentHandler PlayerArgumentDispatch[_LargestEventID]; - ItemArgumentHandler ItemArgumentDispatch[_LargestEventID]; - SpellArgumentHandler SpellArgumentDispatch[_LargestEventID]; + NPCArgumentHandler NPCArgumentDispatch[_LargestEventID]; + PlayerArgumentHandler PlayerArgumentDispatch[_LargestEventID]; + ItemArgumentHandler ItemArgumentDispatch[_LargestEventID]; + SpellArgumentHandler SpellArgumentDispatch[_LargestEventID]; EncounterArgumentHandler EncounterArgumentDispatch[_LargestEventID]; - BotArgumentHandler BotArgumentDispatch[_LargestEventID]; + BotArgumentHandler BotArgumentDispatch[_LargestEventID]; + ZoneArgumentHandler ZoneArgumentDispatch[_LargestEventID]; }; #endif diff --git a/zone/lua_parser_events.cpp b/zone/lua_parser_events.cpp index 8d2517fe3..cb176e1c1 100644 --- a/zone/lua_parser_events.cpp +++ b/zone/lua_parser_events.cpp @@ -2873,4 +2873,35 @@ void handle_bot_spell_blocked( lua_setfield(L, -2, "cast_spell"); } +// Zone + +void handle_zone_timer_pause_resume_start( + QuestInterface *parse, + lua_State* L, + Zone* zone, + std::string data, + uint32 extra_data, + std::vector *extra_pointers +) { + Seperator sep(data.c_str()); + + lua_pushstring(L, sep.arg[0]); + lua_setfield(L, -2, "timer"); + + lua_pushinteger(L, Strings::ToUnsignedInt(sep.arg[1])); + lua_setfield(L, -2, "duration"); +} + +void handle_zone_timer_stop( + QuestInterface *parse, + lua_State* L, + Zone* zone, + std::string data, + uint32 extra_data, + std::vector *extra_pointers +) { + lua_pushstring(L, data.c_str()); + lua_setfield(L, -2, "timer"); +} + #endif diff --git a/zone/lua_parser_events.h b/zone/lua_parser_events.h index 3cb428c58..afb5a6957 100644 --- a/zone/lua_parser_events.h +++ b/zone/lua_parser_events.h @@ -9,6 +9,7 @@ typedef void(*SpellArgumentHandler)(QuestInterface*, lua_State*, Mob*, Client*, typedef void(*EncounterArgumentHandler)(QuestInterface*, lua_State*, Encounter* encounter, std::string, uint32, std::vector*); typedef void(*BotArgumentHandler)(QuestInterface*, lua_State*, Bot*, Mob*, std::string, uint32, std::vector*); typedef void(*MercArgumentHandler)(QuestInterface*, lua_State*, Merc*, Mob*, std::string, uint32, std::vector*); +typedef void(*ZoneArgumentHandler)(QuestInterface*, lua_State*, Zone*, std::string, uint32, std::vector*); // NPC void handle_npc_event_say( @@ -1278,5 +1279,24 @@ void handle_bot_spell_blocked( std::vector *extra_pointers ); +// Zone +void handle_zone_timer_pause_resume_start( + QuestInterface *parse, + lua_State* L, + Zone* zone, + std::string data, + uint32 extra_data, + std::vector *extra_pointers +); + +void handle_zone_timer_stop( + QuestInterface *parse, + lua_State* L, + Zone* zone, + std::string data, + uint32 extra_data, + std::vector *extra_pointers +); + #endif #endif