diff --git a/zone/embparser.cpp b/zone/embparser.cpp index 12dcea6d5..030638a44 100644 --- a/zone/embparser.cpp +++ b/zone/embparser.cpp @@ -197,6 +197,9 @@ const char* QuestEventSubroutines[_LargestEventID] = { "EVENT_TIMER_RESUME", "EVENT_TIMER_START", "EVENT_TIMER_STOP", + "EVENT_ENTITY_VARIABLE_DELETE", + "EVENT_ENTITY_VARIABLE_SET", + "EVENT_ENTITY_VARIABLE_UPDATE", // Add new events before these or Lua crashes "EVENT_SPELL_EFFECT_BOT", @@ -2423,6 +2426,26 @@ void PerlembParser::ExportEventVariables( break; } + case EVENT_ENTITY_VARIABLE_DELETE: + case EVENT_ENTITY_VARIABLE_SET: { + if (extra_pointers && extra_pointers->size() == 2) { + ExportVar(package_name.c_str(), "variable_name", std::any_cast(extra_pointers->at(0)).c_str()); + ExportVar(package_name.c_str(), "variable_value", std::any_cast(extra_pointers->at(1)).c_str()); + } + + break; + } + + case EVENT_ENTITY_VARIABLE_UPDATE: { + if (extra_pointers && extra_pointers->size() == 3) { + ExportVar(package_name.c_str(), "variable_name", std::any_cast(extra_pointers->at(0)).c_str()); + ExportVar(package_name.c_str(), "old_value", std::any_cast(extra_pointers->at(1)).c_str()); + ExportVar(package_name.c_str(), "new_value", std::any_cast(extra_pointers->at(2)).c_str()); + } + + break; + } + default: { break; } diff --git a/zone/embparser_api.cpp b/zone/embparser_api.cpp index 3cd6e2c19..f37f264bb 100644 --- a/zone/embparser_api.cpp +++ b/zone/embparser_api.cpp @@ -6626,9 +6626,9 @@ void perl_register_quest() package.add("settarget", &Perl__settarget); package.add("settime", (void(*)(int, int))&Perl__settime); package.add("settime", (void(*)(int, int, bool))&Perl__settime); - package.add("set_timer", (void(*)(std::string, uint32))&Perl__settimer), - package.add("set_timer", (void(*)(std::string, uint32, EQ::ItemInstance*))&Perl__settimer), - package.add("set_timer", (void(*)(std::string, uint32, Mob*))&Perl__settimer), + package.add("settimer", (void(*)(std::string, uint32))&Perl__settimer), + package.add("settimer", (void(*)(std::string, uint32, EQ::ItemInstance*))&Perl__settimer), + package.add("settimer", (void(*)(std::string, uint32, Mob*))&Perl__settimer), package.add("settimerMS", (void(*)(std::string, uint32))&Perl__settimerMS); package.add("settimerMS", (void(*)(std::string, uint32, EQ::ItemInstance*))&Perl__settimerMS); package.add("settimerMS", (void(*)(std::string, uint32, Mob*))&Perl__settimerMS); diff --git a/zone/event_codes.h b/zone/event_codes.h index 2b0cec5b3..42754671a 100644 --- a/zone/event_codes.h +++ b/zone/event_codes.h @@ -139,6 +139,9 @@ typedef enum { EVENT_TIMER_RESUME, EVENT_TIMER_START, EVENT_TIMER_STOP, + EVENT_ENTITY_VARIABLE_DELETE, + EVENT_ENTITY_VARIABLE_SET, + EVENT_ENTITY_VARIABLE_UPDATE, // Add new events before these or Lua crashes EVENT_SPELL_EFFECT_BOT, diff --git a/zone/lua_general.cpp b/zone/lua_general.cpp index 054cf66de..813b50c6a 100644 --- a/zone/lua_general.cpp +++ b/zone/lua_general.cpp @@ -6660,7 +6660,10 @@ luabind::scope lua_register_events() { luabind::value("timer_pause", static_cast(EVENT_TIMER_PAUSE)), luabind::value("timer_resume", static_cast(EVENT_TIMER_RESUME)), luabind::value("timer_start", static_cast(EVENT_TIMER_START)), - luabind::value("timer_stop", static_cast(EVENT_TIMER_STOP)) + luabind::value("timer_stop", static_cast(EVENT_TIMER_STOP)), + luabind::value("entity_variable_delete", static_cast(EVENT_ENTITY_VARIABLE_DELETE)), + luabind::value("entity_variable_set", static_cast(EVENT_ENTITY_VARIABLE_SET)), + luabind::value("entity_variable_update", static_cast(EVENT_ENTITY_VARIABLE_UPDATE)) )]; } diff --git a/zone/lua_parser.cpp b/zone/lua_parser.cpp index 4ef4310c8..72c767845 100644 --- a/zone/lua_parser.cpp +++ b/zone/lua_parser.cpp @@ -180,6 +180,9 @@ const char *LuaEvents[_LargestEventID] = { "event_timer_resume", "event_timer_start", "event_timer_stop", + "event_entity_variable_delete", + "event_entity_variable_set", + "event_entity_variable_update" }; extern Zone *zone; @@ -212,44 +215,47 @@ LuaParser::LuaParser() { BotArgumentDispatch[i] = handle_bot_null; } - NPCArgumentDispatch[EVENT_SAY] = handle_npc_event_say; - NPCArgumentDispatch[EVENT_AGGRO_SAY] = handle_npc_event_say; - NPCArgumentDispatch[EVENT_PROXIMITY_SAY] = handle_npc_event_say; - NPCArgumentDispatch[EVENT_TRADE] = handle_npc_event_trade; - NPCArgumentDispatch[EVENT_HP] = handle_npc_event_hp; - NPCArgumentDispatch[EVENT_TARGET_CHANGE] = handle_npc_single_mob; - NPCArgumentDispatch[EVENT_CAST_ON] = handle_npc_cast; - NPCArgumentDispatch[EVENT_KILLED_MERIT] = handle_npc_single_client; - NPCArgumentDispatch[EVENT_SLAY] = handle_npc_single_mob; - NPCArgumentDispatch[EVENT_ENTER] = handle_npc_single_client; - NPCArgumentDispatch[EVENT_EXIT] = handle_npc_single_client; - NPCArgumentDispatch[EVENT_TASK_ACCEPTED] = handle_npc_task_accepted; - NPCArgumentDispatch[EVENT_POPUP_RESPONSE] = handle_npc_popup; - NPCArgumentDispatch[EVENT_WAYPOINT_ARRIVE] = handle_npc_waypoint; - NPCArgumentDispatch[EVENT_WAYPOINT_DEPART] = handle_npc_waypoint; - NPCArgumentDispatch[EVENT_HATE_LIST] = handle_npc_hate; - NPCArgumentDispatch[EVENT_COMBAT] = handle_npc_hate; - NPCArgumentDispatch[EVENT_SIGNAL] = handle_npc_signal; - NPCArgumentDispatch[EVENT_TIMER] = handle_npc_timer; - NPCArgumentDispatch[EVENT_DEATH] = handle_npc_death; - NPCArgumentDispatch[EVENT_DEATH_COMPLETE] = handle_npc_death; - NPCArgumentDispatch[EVENT_DEATH_ZONE] = handle_npc_death; - NPCArgumentDispatch[EVENT_CAST] = handle_npc_cast; - NPCArgumentDispatch[EVENT_CAST_BEGIN] = handle_npc_cast; - NPCArgumentDispatch[EVENT_FEIGN_DEATH] = handle_npc_single_client; - NPCArgumentDispatch[EVENT_ENTER_AREA] = handle_npc_area; - NPCArgumentDispatch[EVENT_LEAVE_AREA] = handle_npc_area; - NPCArgumentDispatch[EVENT_LOOT_ZONE] = handle_npc_loot_zone; - NPCArgumentDispatch[EVENT_SPAWN_ZONE] = handle_npc_spawn_zone; - NPCArgumentDispatch[EVENT_PAYLOAD] = handle_npc_payload; - NPCArgumentDispatch[EVENT_DESPAWN_ZONE] = handle_npc_despawn_zone; - NPCArgumentDispatch[EVENT_DAMAGE_GIVEN] = handle_npc_damage; - NPCArgumentDispatch[EVENT_DAMAGE_TAKEN] = handle_npc_damage; - NPCArgumentDispatch[EVENT_LOOT_ADDED] = handle_npc_loot_added; - NPCArgumentDispatch[EVENT_TIMER_PAUSE] = handle_npc_timer_pause_resume_start; - NPCArgumentDispatch[EVENT_TIMER_RESUME] = handle_npc_timer_pause_resume_start; - NPCArgumentDispatch[EVENT_TIMER_START] = handle_npc_timer_pause_resume_start; - NPCArgumentDispatch[EVENT_TIMER_STOP] = handle_npc_timer_stop; + NPCArgumentDispatch[EVENT_SAY] = handle_npc_event_say; + NPCArgumentDispatch[EVENT_AGGRO_SAY] = handle_npc_event_say; + NPCArgumentDispatch[EVENT_PROXIMITY_SAY] = handle_npc_event_say; + NPCArgumentDispatch[EVENT_TRADE] = handle_npc_event_trade; + NPCArgumentDispatch[EVENT_HP] = handle_npc_event_hp; + NPCArgumentDispatch[EVENT_TARGET_CHANGE] = handle_npc_single_mob; + NPCArgumentDispatch[EVENT_CAST_ON] = handle_npc_cast; + NPCArgumentDispatch[EVENT_KILLED_MERIT] = handle_npc_single_client; + NPCArgumentDispatch[EVENT_SLAY] = handle_npc_single_mob; + NPCArgumentDispatch[EVENT_ENTER] = handle_npc_single_client; + NPCArgumentDispatch[EVENT_EXIT] = handle_npc_single_client; + NPCArgumentDispatch[EVENT_TASK_ACCEPTED] = handle_npc_task_accepted; + NPCArgumentDispatch[EVENT_POPUP_RESPONSE] = handle_npc_popup; + NPCArgumentDispatch[EVENT_WAYPOINT_ARRIVE] = handle_npc_waypoint; + NPCArgumentDispatch[EVENT_WAYPOINT_DEPART] = handle_npc_waypoint; + NPCArgumentDispatch[EVENT_HATE_LIST] = handle_npc_hate; + NPCArgumentDispatch[EVENT_COMBAT] = handle_npc_hate; + NPCArgumentDispatch[EVENT_SIGNAL] = handle_npc_signal; + NPCArgumentDispatch[EVENT_TIMER] = handle_npc_timer; + NPCArgumentDispatch[EVENT_DEATH] = handle_npc_death; + NPCArgumentDispatch[EVENT_DEATH_COMPLETE] = handle_npc_death; + NPCArgumentDispatch[EVENT_DEATH_ZONE] = handle_npc_death; + NPCArgumentDispatch[EVENT_CAST] = handle_npc_cast; + NPCArgumentDispatch[EVENT_CAST_BEGIN] = handle_npc_cast; + NPCArgumentDispatch[EVENT_FEIGN_DEATH] = handle_npc_single_client; + NPCArgumentDispatch[EVENT_ENTER_AREA] = handle_npc_area; + NPCArgumentDispatch[EVENT_LEAVE_AREA] = handle_npc_area; + NPCArgumentDispatch[EVENT_LOOT_ZONE] = handle_npc_loot_zone; + NPCArgumentDispatch[EVENT_SPAWN_ZONE] = handle_npc_spawn_zone; + NPCArgumentDispatch[EVENT_PAYLOAD] = handle_npc_payload; + NPCArgumentDispatch[EVENT_DESPAWN_ZONE] = handle_npc_despawn_zone; + NPCArgumentDispatch[EVENT_DAMAGE_GIVEN] = handle_npc_damage; + NPCArgumentDispatch[EVENT_DAMAGE_TAKEN] = handle_npc_damage; + NPCArgumentDispatch[EVENT_LOOT_ADDED] = handle_npc_loot_added; + NPCArgumentDispatch[EVENT_TIMER_PAUSE] = handle_npc_timer_pause_resume_start; + NPCArgumentDispatch[EVENT_TIMER_RESUME] = handle_npc_timer_pause_resume_start; + NPCArgumentDispatch[EVENT_TIMER_START] = handle_npc_timer_pause_resume_start; + NPCArgumentDispatch[EVENT_TIMER_STOP] = handle_npc_timer_stop; + NPCArgumentDispatch[EVENT_ENTITY_VARIABLE_DELETE] = handle_npc_entity_variable; + NPCArgumentDispatch[EVENT_ENTITY_VARIABLE_SET] = handle_npc_entity_variable; + NPCArgumentDispatch[EVENT_ENTITY_VARIABLE_UPDATE] = handle_npc_entity_variable; PlayerArgumentDispatch[EVENT_SAY] = handle_player_say; PlayerArgumentDispatch[EVENT_ENVIRONMENTAL_DAMAGE] = handle_player_environmental_damage; @@ -334,6 +340,9 @@ LuaParser::LuaParser() { PlayerArgumentDispatch[EVENT_TIMER_RESUME] = handle_player_timer_pause_resume_start; PlayerArgumentDispatch[EVENT_TIMER_START] = handle_player_timer_pause_resume_start; PlayerArgumentDispatch[EVENT_TIMER_STOP] = handle_player_timer_stop; + PlayerArgumentDispatch[EVENT_ENTITY_VARIABLE_DELETE] = handle_player_entity_variable; + PlayerArgumentDispatch[EVENT_ENTITY_VARIABLE_SET] = handle_player_entity_variable; + PlayerArgumentDispatch[EVENT_ENTITY_VARIABLE_UPDATE] = handle_player_entity_variable; ItemArgumentDispatch[EVENT_ITEM_CLICK] = handle_item_click; ItemArgumentDispatch[EVENT_ITEM_CLICK_CAST] = handle_item_click; @@ -360,31 +369,34 @@ LuaParser::LuaParser() { EncounterArgumentDispatch[EVENT_ENCOUNTER_LOAD] = handle_encounter_load; EncounterArgumentDispatch[EVENT_ENCOUNTER_UNLOAD] = handle_encounter_unload; - BotArgumentDispatch[EVENT_CAST] = handle_bot_cast; - BotArgumentDispatch[EVENT_CAST_BEGIN] = handle_bot_cast; - BotArgumentDispatch[EVENT_CAST_ON] = handle_bot_cast; - BotArgumentDispatch[EVENT_COMBAT] = handle_bot_combat; - BotArgumentDispatch[EVENT_DEATH] = handle_bot_death; - BotArgumentDispatch[EVENT_DEATH_COMPLETE] = handle_bot_death; - BotArgumentDispatch[EVENT_POPUP_RESPONSE] = handle_bot_popup_response; - BotArgumentDispatch[EVENT_SAY] = handle_bot_say; - BotArgumentDispatch[EVENT_SIGNAL] = handle_bot_signal; - BotArgumentDispatch[EVENT_SLAY] = handle_bot_slay; - BotArgumentDispatch[EVENT_TARGET_CHANGE] = handle_bot_target_change; - BotArgumentDispatch[EVENT_TIMER] = handle_bot_timer; - BotArgumentDispatch[EVENT_TRADE] = handle_bot_trade; - BotArgumentDispatch[EVENT_USE_SKILL] = handle_bot_use_skill; - BotArgumentDispatch[EVENT_PAYLOAD] = handle_bot_payload; - BotArgumentDispatch[EVENT_EQUIP_ITEM_BOT] = handle_bot_equip_item; - BotArgumentDispatch[EVENT_UNEQUIP_ITEM_BOT] = handle_bot_equip_item; - BotArgumentDispatch[EVENT_DAMAGE_GIVEN] = handle_bot_damage; - BotArgumentDispatch[EVENT_DAMAGE_TAKEN] = handle_bot_damage; - BotArgumentDispatch[EVENT_LEVEL_UP] = handle_bot_level_up; - BotArgumentDispatch[EVENT_LEVEL_DOWN] = handle_bot_level_down; - BotArgumentDispatch[EVENT_TIMER_PAUSE] = handle_bot_timer_pause_resume_start; - BotArgumentDispatch[EVENT_TIMER_RESUME] = handle_bot_timer_pause_resume_start; - BotArgumentDispatch[EVENT_TIMER_START] = handle_bot_timer_pause_resume_start; - BotArgumentDispatch[EVENT_TIMER_STOP] = handle_bot_timer_stop; + BotArgumentDispatch[EVENT_CAST] = handle_bot_cast; + BotArgumentDispatch[EVENT_CAST_BEGIN] = handle_bot_cast; + BotArgumentDispatch[EVENT_CAST_ON] = handle_bot_cast; + BotArgumentDispatch[EVENT_COMBAT] = handle_bot_combat; + BotArgumentDispatch[EVENT_DEATH] = handle_bot_death; + BotArgumentDispatch[EVENT_DEATH_COMPLETE] = handle_bot_death; + BotArgumentDispatch[EVENT_POPUP_RESPONSE] = handle_bot_popup_response; + BotArgumentDispatch[EVENT_SAY] = handle_bot_say; + BotArgumentDispatch[EVENT_SIGNAL] = handle_bot_signal; + BotArgumentDispatch[EVENT_SLAY] = handle_bot_slay; + BotArgumentDispatch[EVENT_TARGET_CHANGE] = handle_bot_target_change; + BotArgumentDispatch[EVENT_TIMER] = handle_bot_timer; + BotArgumentDispatch[EVENT_TRADE] = handle_bot_trade; + BotArgumentDispatch[EVENT_USE_SKILL] = handle_bot_use_skill; + BotArgumentDispatch[EVENT_PAYLOAD] = handle_bot_payload; + BotArgumentDispatch[EVENT_EQUIP_ITEM_BOT] = handle_bot_equip_item; + BotArgumentDispatch[EVENT_UNEQUIP_ITEM_BOT] = handle_bot_equip_item; + BotArgumentDispatch[EVENT_DAMAGE_GIVEN] = handle_bot_damage; + BotArgumentDispatch[EVENT_DAMAGE_TAKEN] = handle_bot_damage; + BotArgumentDispatch[EVENT_LEVEL_UP] = handle_bot_level_up; + BotArgumentDispatch[EVENT_LEVEL_DOWN] = handle_bot_level_down; + BotArgumentDispatch[EVENT_TIMER_PAUSE] = handle_bot_timer_pause_resume_start; + BotArgumentDispatch[EVENT_TIMER_RESUME] = handle_bot_timer_pause_resume_start; + BotArgumentDispatch[EVENT_TIMER_START] = handle_bot_timer_pause_resume_start; + BotArgumentDispatch[EVENT_TIMER_STOP] = handle_bot_timer_stop; + BotArgumentDispatch[EVENT_ENTITY_VARIABLE_DELETE] = handle_bot_entity_variable; + BotArgumentDispatch[EVENT_ENTITY_VARIABLE_SET] = handle_bot_entity_variable; + BotArgumentDispatch[EVENT_ENTITY_VARIABLE_UPDATE] = handle_bot_entity_variable; #endif L = nullptr; diff --git a/zone/lua_parser_events.cpp b/zone/lua_parser_events.cpp index cad4c9233..51187bf21 100644 --- a/zone/lua_parser_events.cpp +++ b/zone/lua_parser_events.cpp @@ -584,6 +584,36 @@ void handle_npc_timer_stop( lua_setfield(L, -2, "timer"); } +void handle_npc_entity_variable( + QuestInterface *parse, + lua_State* L, + NPC* npc, + Mob *init, + std::string data, + uint32 extra_data, + std::vector *extra_pointers +) +{ + if (extra_pointers) { + if (extra_pointers->size() == 2) { + lua_pushstring(L, std::any_cast(extra_pointers->at(0)).c_str()); + lua_setfield(L, -2, "variable_name"); + + lua_pushstring(L, std::any_cast(extra_pointers->at(1)).c_str()); + lua_setfield(L, -2, "variable_value"); + } else if (extra_pointers->size() == 3) { + lua_pushstring(L, std::any_cast(extra_pointers->at(0)).c_str()); + lua_setfield(L, -2, "variable_name"); + + lua_pushstring(L, std::any_cast(extra_pointers->at(1)).c_str()); + lua_setfield(L, -2, "old_value"); + + lua_pushstring(L, std::any_cast(extra_pointers->at(2)).c_str()); + lua_setfield(L, -2, "new_value"); + } + } +} + // Player void handle_player_say( QuestInterface *parse, @@ -1596,6 +1626,35 @@ void handle_player_alt_currency_gain_loss( lua_setfield(L, -2, "total"); } +void handle_player_entity_variable( + QuestInterface *parse, + lua_State* L, + Client* client, + std::string data, + uint32 extra_data, + std::vector *extra_pointers +) +{ + if (extra_pointers) { + if (extra_pointers->size() == 2) { + lua_pushstring(L, std::any_cast(extra_pointers->at(0)).c_str()); + lua_setfield(L, -2, "variable_name"); + + lua_pushstring(L, std::any_cast(extra_pointers->at(1)).c_str()); + lua_setfield(L, -2, "variable_value"); + } else if (extra_pointers->size() == 3) { + lua_pushstring(L, std::any_cast(extra_pointers->at(0)).c_str()); + lua_setfield(L, -2, "variable_name"); + + lua_pushstring(L, std::any_cast(extra_pointers->at(1)).c_str()); + lua_setfield(L, -2, "old_value"); + + lua_pushstring(L, std::any_cast(extra_pointers->at(2)).c_str()); + lua_setfield(L, -2, "new_value"); + } + } +} + // Item void handle_item_click( QuestInterface *parse, @@ -2577,4 +2636,34 @@ void handle_bot_timer_stop( lua_setfield(L, -2, "timer"); } +void handle_bot_entity_variable( + QuestInterface *parse, + lua_State* L, + Bot* bot, + Mob *init, + std::string data, + uint32 extra_data, + std::vector *extra_pointers +) +{ + if (extra_pointers) { + if (extra_pointers->size() == 2) { + lua_pushstring(L, std::any_cast(extra_pointers->at(0)).c_str()); + lua_setfield(L, -2, "variable_name"); + + lua_pushstring(L, std::any_cast(extra_pointers->at(1)).c_str()); + lua_setfield(L, -2, "variable_value"); + } else if (extra_pointers->size() == 3) { + lua_pushstring(L, std::any_cast(extra_pointers->at(0)).c_str()); + lua_setfield(L, -2, "variable_name"); + + lua_pushstring(L, std::any_cast(extra_pointers->at(1)).c_str()); + lua_setfield(L, -2, "old_value"); + + lua_pushstring(L, std::any_cast(extra_pointers->at(2)).c_str()); + lua_setfield(L, -2, "new_value"); + } + } +} + #endif diff --git a/zone/lua_parser_events.h b/zone/lua_parser_events.h index da7d7bd06..0c3309a65 100644 --- a/zone/lua_parser_events.h +++ b/zone/lua_parser_events.h @@ -240,6 +240,16 @@ void handle_npc_timer_stop( std::vector *extra_pointers ); +void handle_npc_entity_variable( + QuestInterface *parse, + lua_State* L, + NPC* npc, + Mob *init, + std::string data, + uint32 extra_data, + std::vector *extra_pointers +); + // Player void handle_player_say( QuestInterface *parse, @@ -808,6 +818,15 @@ void handle_player_timer_stop( std::vector *extra_pointers ); +void handle_player_entity_variable( + QuestInterface *parse, + lua_State* L, + Client* client, + std::string data, + uint32 extra_data, + std::vector *extra_pointers +); + // Item void handle_item_click( QuestInterface *parse, @@ -1192,5 +1211,15 @@ void handle_bot_timer_stop( std::vector *extra_pointers ); +void handle_bot_entity_variable( + QuestInterface *parse, + lua_State* L, + Bot* bot, + Mob* init, + std::string data, + uint32 extra_data, + std::vector *extra_pointers +); + #endif #endif diff --git a/zone/mob.cpp b/zone/mob.cpp index b4fa5db27..24095b1d0 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -5547,6 +5547,24 @@ bool Mob::ClearEntityVariables() return false; } + if ( + (IsBot() && parse->BotHasQuestSub(EVENT_ENTITY_VARIABLE_DELETE)) || + (IsClient() && parse->PlayerHasQuestSub(EVENT_ENTITY_VARIABLE_DELETE)) || + (IsNPC() && parse->HasQuestSub(GetNPCTypeID(), EVENT_ENTITY_VARIABLE_DELETE)) + ) { + for (const auto& e : m_EntityVariables) { + std::vector args = { e.first, e.second }; + + if (IsBot()) { + parse->EventBot(EVENT_ENTITY_VARIABLE_DELETE, CastToBot(), nullptr, "", 0, &args); + } else if (IsClient()) { + parse->EventPlayer(EVENT_ENTITY_VARIABLE_DELETE, CastToClient(), "", 0, &args); + } else if (IsNPC()) { + parse->EventNPC(EVENT_ENTITY_VARIABLE_DELETE, CastToNPC(), nullptr, "", 0, &args); + } + } + } + m_EntityVariables.clear(); return true; } @@ -5563,6 +5581,23 @@ bool Mob::DeleteEntityVariable(std::string variable_name) } m_EntityVariables.erase(v); + + if ( + (IsBot() && parse->BotHasQuestSub(EVENT_ENTITY_VARIABLE_DELETE)) || + (IsClient() && parse->PlayerHasQuestSub(EVENT_ENTITY_VARIABLE_DELETE)) || + (IsNPC() && parse->HasQuestSub(GetNPCTypeID(), EVENT_ENTITY_VARIABLE_DELETE)) + ) { + std::vector args = { v->first, v->second }; + + if (IsBot()) { + parse->EventBot(EVENT_ENTITY_VARIABLE_DELETE, CastToBot(), nullptr, "", 0, &args); + } else if (IsClient()) { + parse->EventPlayer(EVENT_ENTITY_VARIABLE_DELETE, CastToClient(), "", 0, &args); + } else if (IsNPC()) { + parse->EventNPC(EVENT_ENTITY_VARIABLE_DELETE, CastToNPC(), nullptr, "", 0, &args); + } + } + return true; } @@ -5573,22 +5608,22 @@ std::string Mob::GetEntityVariable(std::string variable_name) } const auto& v = m_EntityVariables.find(variable_name); - if (v != m_EntityVariables.end()) { - return v->second; - } - return std::string(); + return v != m_EntityVariables.end() ? v->second : std::string(); } std::vector Mob::GetEntityVariables() { std::vector l; + if (m_EntityVariables.empty()) { return l; } + l.reserve(m_EntityVariables.size()); + for (const auto& v : m_EntityVariables) { - l.push_back(v.first); + l.emplace_back(v.first); } return l; @@ -5600,12 +5635,7 @@ bool Mob::EntityVariableExists(std::string variable_name) return false; } - const auto& v = m_EntityVariables.find(variable_name); - if (v != m_EntityVariables.end()) { - return true; - } - - return false; + return m_EntityVariables.find(variable_name) != m_EntityVariables.end(); } void Mob::SetEntityVariable(std::string variable_name, std::string variable_value) @@ -5614,6 +5644,34 @@ void Mob::SetEntityVariable(std::string variable_name, std::string variable_valu return; } + const QuestEventID event_id = ( + !EntityVariableExists(variable_name) ? + EVENT_ENTITY_VARIABLE_SET : + EVENT_ENTITY_VARIABLE_UPDATE + ); + + if ( + (IsBot() && parse->BotHasQuestSub(event_id)) || + (IsClient() && parse->PlayerHasQuestSub(event_id)) || + (IsNPC() && parse->HasQuestSub(GetNPCTypeID(), event_id)) + ) { + std::vector args; + + if (event_id != EVENT_ENTITY_VARIABLE_UPDATE) { + args = { variable_name, variable_value }; + } else { + args = { variable_name, GetEntityVariable(variable_name), variable_value }; + } + + if (IsBot()) { + parse->EventBot(event_id, CastToBot(), nullptr, "", 0, &args); + } else if (IsClient()) { + parse->EventPlayer(event_id, CastToClient(), "", 0, &args); + } else if (IsNPC()) { + parse->EventNPC(event_id, CastToNPC(), nullptr, "", 0, &args); + } + } + m_EntityVariables[variable_name] = variable_value; }