diff --git a/zone/embparser.cpp b/zone/embparser.cpp index 88420ea1f..00a049d21 100644 --- a/zone/embparser.cpp +++ b/zone/embparser.cpp @@ -1561,6 +1561,13 @@ void PerlembParser::ExportEventVariables( break; } + case EVENT_TARGET_CHANGE: { + if (extra_pointers && extra_pointers->size() == 1) { + ExportVar(package_name.c_str(), "target", "Mob", std::any_cast(extra_pointers->at(0))); + } + break; + } + case EVENT_WAYPOINT_ARRIVE: case EVENT_WAYPOINT_DEPART: { ExportVar(package_name.c_str(), "wp", data); diff --git a/zone/lua_parser.cpp b/zone/lua_parser.cpp index e1d96e7eb..3139240bf 100644 --- a/zone/lua_parser.cpp +++ b/zone/lua_parser.cpp @@ -286,6 +286,7 @@ LuaParser::LuaParser() { PlayerArgumentDispatch[EVENT_ITEM_CLICK_CAST_CLIENT] = handle_player_item_click; PlayerArgumentDispatch[EVENT_ITEM_CLICK_CLIENT] = handle_player_item_click; PlayerArgumentDispatch[EVENT_DESTROY_ITEM_CLIENT] = handle_player_destroy_item; + PlayerArgumentDispatch[EVENT_TARGET_CHANGE] = handle_player_target_change; ItemArgumentDispatch[EVENT_ITEM_CLICK] = handle_item_click; ItemArgumentDispatch[EVENT_ITEM_CLICK_CAST] = handle_item_click; diff --git a/zone/lua_parser_events.cpp b/zone/lua_parser_events.cpp index b6c31a903..1b42c27a6 100644 --- a/zone/lua_parser_events.cpp +++ b/zone/lua_parser_events.cpp @@ -1340,6 +1340,22 @@ void handle_player_destroy_item( } } +void handle_player_target_change( + QuestInterface *parse, + lua_State* L, + Client* client, + std::string data, + uint32 extra_data, + std::vector *extra_pointers +) { + if (extra_pointers && extra_pointers->size() == 1) { + Lua_Mob l_mob(std::any_cast(extra_pointers->at(0))); + luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob); + l_mob_o.push(L); + lua_setfield(L, -2, "other"); + } +} + // Item void handle_item_click( QuestInterface *parse, diff --git a/zone/lua_parser_events.h b/zone/lua_parser_events.h index 7603c27a3..e06602eba 100644 --- a/zone/lua_parser_events.h +++ b/zone/lua_parser_events.h @@ -698,6 +698,15 @@ void handle_player_destroy_item( std::vector *extra_pointers ); +void handle_player_target_change( + QuestInterface *parse, + lua_State* L, + Client* client, + std::string data, + uint32 extra_data, + std::vector *extra_pointers +); + // Item void handle_item_click( QuestInterface *parse, diff --git a/zone/mob.cpp b/zone/mob.cpp index f388b2828..34ebe1e1b 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -4259,19 +4259,36 @@ void Mob::SetTarget(Mob *mob) target = mob; entity_list.UpdateHoTT(this); - if (IsNPC()) { - parse->EventNPC(EVENT_TARGET_CHANGE, CastToNPC(), mob, "", 0); - } - else if (IsClient()) { - parse->EventPlayer(EVENT_TARGET_CHANGE, CastToClient(), "", 0); + const auto has_target_change_event = ( + parse->HasQuestSub(GetNPCTypeID(), EVENT_TARGET_CHANGE) || + parse->PlayerHasQuestSub(EVENT_TARGET_CHANGE) || + parse->BotHasQuestSub(EVENT_TARGET_CHANGE) + ); - if (CastToClient()->admin > AccountStatus::GMMgmt) { - DisplayInfo(mob); + if (has_target_change_event) { + std::vector args; + + args.emplace_back(mob); + + if (IsNPC()) { + if (parse->HasQuestSub(GetNPCTypeID(), EVENT_TARGET_CHANGE)) { + parse->EventNPC(EVENT_TARGET_CHANGE, CastToNPC(), mob, "", 0, &args); + } + } else if (IsClient()) { + if (parse->PlayerHasQuestSub(EVENT_TARGET_CHANGE)) { + parse->EventPlayer(EVENT_TARGET_CHANGE, CastToClient(), "", 0, &args); + } + + if (CastToClient()->admin > AccountStatus::GMMgmt) { + DisplayInfo(mob); + } + + CastToClient()->SetBotPrecombat(false); // Any change in target will nullify this flag (target == mob checked above) + } else if (IsBot()) { + if (parse->BotHasQuestSub(EVENT_TARGET_CHANGE)) { + parse->EventBot(EVENT_TARGET_CHANGE, CastToBot(), mob, "", 0, &args); + } } - - CastToClient()->SetBotPrecombat(false); // Any change in target will nullify this flag (target == mob checked above) - } else if (IsBot()) { - parse->EventBot(EVENT_TARGET_CHANGE, CastToBot(), mob, "", 0); } if (IsPet() && GetOwner() && GetOwner()->IsClient()) {