From d4afc7898219d0e43ae20805270da2494f67a320 Mon Sep 17 00:00:00 2001 From: Alex King <89047260+Kinglykrab@users.noreply.github.com> Date: Mon, 13 Feb 2023 00:58:27 -0500 Subject: [PATCH] [Quest API] Add EVENT_DESTROY_ITEM_CLIENT to Perl/Lua. (#2871) * [Quest API] Add EVENT_DESTROY_ITEM_CLIENT to Perl/Lua. - Add `EVENT_DESTROY_ITEM_CLIENT`, exports `$item_id`, `$item_name`, `$quantity`, and `$item`. - Add `event_destroy_item_client`, exports `e.item_id`, `e.item_name`, `e.quantity`, and `e.item`. - Allows operators to use player scripts for item destroys. * Update lua_parser_events.h * Update inventory.cpp --- zone/embparser.cpp | 12 ++++++++++++ zone/event_codes.h | 1 + zone/inventory.cpp | 35 +++++++++++++++++++++++++++++++---- zone/lua_general.cpp | 3 ++- zone/lua_parser.cpp | 4 +++- zone/lua_parser_events.cpp | 25 +++++++++++++++++++++++++ zone/lua_parser_events.h | 9 +++++++++ 7 files changed, 83 insertions(+), 6 deletions(-) diff --git a/zone/embparser.cpp b/zone/embparser.cpp index 0aea3f2c1..88420ea1f 100644 --- a/zone/embparser.cpp +++ b/zone/embparser.cpp @@ -175,6 +175,7 @@ const char *QuestEventSubroutines[_LargestEventID] = { "EVENT_DAMAGE_TAKEN", "EVENT_ITEM_CLICK_CLIENT", "EVENT_ITEM_CLICK_CAST_CLIENT", + "EVENT_DESTROY_ITEM_CLIENT", // Add new events before these or Lua crashes "EVENT_SPELL_EFFECT_BOT", "EVENT_SPELL_EFFECT_BUFF_TIC_BOT" @@ -2133,6 +2134,17 @@ void PerlembParser::ExportEventVariables( break; } + case EVENT_DESTROY_ITEM_CLIENT: { + if (extra_pointers && extra_pointers->size() == 1) { + EQ::ItemInstance* inst = std::any_cast(extra_pointers->at(0)); + ExportVar(package_name.c_str(), "item_id", inst->GetID()); + ExportVar(package_name.c_str(), "item_name", inst->GetItem()->Name); + ExportVar(package_name.c_str(), "quantity", inst->IsStackable() ? inst->GetCharges() : 1); + ExportVar(package_name.c_str(), "item", "QuestItem", inst); + } + break; + } + default: { break; } diff --git a/zone/event_codes.h b/zone/event_codes.h index 801dfbfbd..fb9052a00 100644 --- a/zone/event_codes.h +++ b/zone/event_codes.h @@ -120,6 +120,7 @@ typedef enum { EVENT_DAMAGE_TAKEN, EVENT_ITEM_CLICK_CLIENT, EVENT_ITEM_CLICK_CAST_CLIENT, + EVENT_DESTROY_ITEM_CLIENT, // Add new events before these or Lua crashes EVENT_SPELL_EFFECT_BOT, EVENT_SPELL_EFFECT_BUFF_TIC_BOT, diff --git a/zone/inventory.cpp b/zone/inventory.cpp index 1d9606395..531a9b049 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -1130,7 +1130,16 @@ void Client::SendCursorBuffer() LogInventory("([{}]) Duplicate lore items are not allowed - destroying item [{}](id:[{}]) on cursor", GetName(), test_item->Name, test_item->ID); MessageString(Chat::Loot, 290); - parse->EventItem(EVENT_DESTROY_ITEM, this, test_inst, nullptr, "", 0); + + if (parse->ItemHasQuestSub(test_inst, EVENT_DESTROY_ITEM)) { + parse->EventItem(EVENT_DESTROY_ITEM, this, test_inst, nullptr, "", 0); + } + + if (parse->PlayerHasQuestSub(EVENT_DESTROY_ITEM_CLIENT)) { + std::vector args = { test_inst }; + parse->EventPlayer(EVENT_DESTROY_ITEM_CLIENT, this, "", 0, &args); + } + DeleteItemInInventory(EQ::invslot::slotCursor); SendCursorBuffer(); } @@ -1861,7 +1870,16 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { LogInventory("([{}]) Duplicate lore items are not allowed - destroying item [{}](id:[{}]) on cursor", GetName(), test_item->Name, test_item->ID); MessageString(Chat::Loot, 290); - parse->EventItem(EVENT_DESTROY_ITEM, this, test_inst, nullptr, "", 0); + + if (parse->ItemHasQuestSub(test_inst, EVENT_DESTROY_ITEM)) { + parse->EventItem(EVENT_DESTROY_ITEM, this, test_inst, nullptr, "", 0); + } + + if (parse->PlayerHasQuestSub(EVENT_DESTROY_ITEM_CLIENT)) { + std::vector args = { test_inst }; + parse->EventPlayer(EVENT_DESTROY_ITEM_CLIENT, this, "", 0, &args); + } + DeleteItemInInventory(EQ::invslot::slotCursor, 0, true); if (player_event_logs.IsEventEnabled(PlayerEvent::ITEM_DESTROY)) { @@ -1886,8 +1904,8 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { if(RuleB(QueryServ, PlayerLogMoves)) { QSSwapItemAuditor(move_in); } // QS Audit EQ::ItemInstance *inst = m_inv.GetItem(EQ::invslot::slotCursor); - if(inst) { - parse->EventItem(EVENT_DESTROY_ITEM, this, inst, nullptr, "", 0); + + if (inst) { if (player_event_logs.IsEventEnabled(PlayerEvent::ITEM_DESTROY)) { auto e = PlayerEvent::DestroyItemEvent{ .item_id = inst->GetItem()->ID, @@ -1898,6 +1916,15 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { RecordPlayerEventLog(PlayerEvent::ITEM_DESTROY, e); } + + if (parse->ItemHasQuestSub(inst, EVENT_DESTROY_ITEM)) { + parse->EventItem(EVENT_DESTROY_ITEM, this, inst, nullptr, "", 0); + } + + if (parse->PlayerHasQuestSub(EVENT_DESTROY_ITEM_CLIENT)) { + std::vector args = { inst }; + parse->EventPlayer(EVENT_DESTROY_ITEM_CLIENT, this, "", 0, &args); + } } DeleteItemInInventory(move_in->from_slot); diff --git a/zone/lua_general.cpp b/zone/lua_general.cpp index 6883ce518..23a2fa398 100644 --- a/zone/lua_general.cpp +++ b/zone/lua_general.cpp @@ -4750,7 +4750,8 @@ luabind::scope lua_register_events() { luabind::value("damage_given", static_cast(EVENT_DAMAGE_GIVEN)), luabind::value("damage_taken", static_cast(EVENT_DAMAGE_TAKEN)), luabind::value("item_click_client", static_cast(EVENT_ITEM_CLICK_CLIENT)), - luabind::value("item_click_cast_client", static_cast(EVENT_ITEM_CLICK_CAST_CLIENT)) + luabind::value("item_click_cast_client", static_cast(EVENT_ITEM_CLICK_CAST_CLIENT)), + luabind::value("destroy_item_client", static_cast(EVENT_DESTROY_ITEM_CLIENT)) )]; } diff --git a/zone/lua_parser.cpp b/zone/lua_parser.cpp index 737543d4b..e1d96e7eb 100644 --- a/zone/lua_parser.cpp +++ b/zone/lua_parser.cpp @@ -161,7 +161,8 @@ const char *LuaEvents[_LargestEventID] = { "event_damage_given", "event_damage_taken", "event_item_click_client", - "event_item_click_cast_client" + "event_item_click_cast_client", + "event_destroy_item_client" }; extern Zone *zone; @@ -284,6 +285,7 @@ LuaParser::LuaParser() { PlayerArgumentDispatch[EVENT_DAMAGE_TAKEN] = handle_player_damage; 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; 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 2a4e5d8fc..b6c31a903 100644 --- a/zone/lua_parser_events.cpp +++ b/zone/lua_parser_events.cpp @@ -1315,6 +1315,31 @@ void handle_player_item_click( } } +void handle_player_destroy_item( + 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_pushnumber(L, std::any_cast(extra_pointers->at(0))->GetID()); + lua_setfield(L, -2, "item_id"); + + lua_pushstring(L, std::any_cast(extra_pointers->at(0))->GetItem()->Name); + lua_setfield(L, -2, "item_name"); + + lua_pushnumber(L, std::any_cast(extra_pointers->at(0))->IsStackable() ? std::any_cast(extra_pointers->at(0))->GetCharges() : 1); + lua_setfield(L, -2, "quantity"); + + Lua_ItemInst l_item(std::any_cast(extra_pointers->at(0))); + luabind::adl::object l_item_o = luabind::adl::object(L, l_item); + l_item_o.push(L); + lua_setfield(L, -2, "item"); + } +} + // Item void handle_item_click( QuestInterface *parse, diff --git a/zone/lua_parser_events.h b/zone/lua_parser_events.h index 327f90a7e..7603c27a3 100644 --- a/zone/lua_parser_events.h +++ b/zone/lua_parser_events.h @@ -689,6 +689,15 @@ void handle_player_item_click( std::vector *extra_pointers ); +void handle_player_destroy_item( + QuestInterface *parse, + lua_State* L, + Client* client, + std::string data, + uint32 extra_data, + std::vector *extra_pointers +); + // Item void handle_item_click( QuestInterface *parse,