From 4df9661903ffcdf878412bcca926c517ccb1664d Mon Sep 17 00:00:00 2001 From: Alex King <89047260+Kinglykrab@users.noreply.github.com> Date: Mon, 13 Feb 2023 01:15:19 -0500 Subject: [PATCH] [Quest API] Add EVENT_DROP_ITEM_CLIENT to Perl/Lua (#2869) * [Quest API] Add EVENT_DROP_ITEM_CLIENT to Perl/Lua - Add `EVENT_DROP_ITEM_CLIENT`, exports `$quantity,` $item_name`, `$item_id`, `$spell_id`, `$slot_id`, and `$item`. - Add `event_drop_item_client`, exports `e.quantity`, `e.item_name`, `e.item_id`, `e.spell_id`, `e.slot_id`, and `e.item`. * Update inventory.cpp * Update inventory.cpp * Update lua_general.cpp * Update inventory.cpp --- zone/embparser.cpp | 14 ++++++++++++++ zone/event_codes.h | 1 + zone/inventory.cpp | 23 +++++++++++++++++++---- zone/lua_general.cpp | 3 ++- zone/lua_parser.cpp | 2 ++ zone/lua_parser_events.cpp | 34 ++++++++++++++++++++++++++++++++++ zone/lua_parser_events.h | 9 +++++++++ 7 files changed, 81 insertions(+), 5 deletions(-) diff --git a/zone/embparser.cpp b/zone/embparser.cpp index 00a049d21..3818f151a 100644 --- a/zone/embparser.cpp +++ b/zone/embparser.cpp @@ -176,6 +176,7 @@ const char *QuestEventSubroutines[_LargestEventID] = { "EVENT_ITEM_CLICK_CLIENT", "EVENT_ITEM_CLICK_CAST_CLIENT", "EVENT_DESTROY_ITEM_CLIENT", + "EVENT_DROP_ITEM_CLIENT", // Add new events before these or Lua crashes "EVENT_SPELL_EFFECT_BOT", "EVENT_SPELL_EFFECT_BUFF_TIC_BOT" @@ -1883,6 +1884,19 @@ void PerlembParser::ExportEventVariables( break; } + case EVENT_DROP_ITEM_CLIENT: { + if (extra_pointers && extra_pointers->size() == 1) { + EQ::ItemInstance* item_instance = std::any_cast(extra_pointers->at(0)); + ExportVar(package_name.c_str(), "quantity", item_instance->IsStackable() ? item_instance->GetCharges() : 1); + ExportVar(package_name.c_str(), "item_name", item_instance->GetItem()->Name); + ExportVar(package_name.c_str(), "item_id", item_instance->GetItem()->ID); + ExportVar(package_name.c_str(), "spell_id", item_instance->GetItem()->Click.Effect); + ExportVar(package_name.c_str(), "slot_id", extradata); + ExportVar(package_name.c_str(), "item", "QuestItem", item_instance); + } + break; + } + case EVENT_SPAWN_ZONE: { ExportVar(package_name.c_str(), "spawned_entity_id", mob->GetID()); ExportVar(package_name.c_str(), "spawned_bot_id", mob->IsBot() ? mob->CastToBot()->GetBotID() : 0); diff --git a/zone/event_codes.h b/zone/event_codes.h index fb9052a00..d0cf7e6aa 100644 --- a/zone/event_codes.h +++ b/zone/event_codes.h @@ -121,6 +121,7 @@ typedef enum { EVENT_ITEM_CLICK_CLIENT, EVENT_ITEM_CLICK_CAST_CLIENT, EVENT_DESTROY_ITEM_CLIENT, + EVENT_DROP_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 531a9b049..e677b9407 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -903,6 +903,9 @@ void Client::DropItem(int16 slot_id, bool recurse) } } + + int i = 0; + if (player_event_logs.IsEventEnabled(PlayerEvent::DROPPED_ITEM)) { auto e = PlayerEvent::DroppedItemEvent{ .item_id = inst->GetID(), @@ -913,10 +916,22 @@ void Client::DropItem(int16 slot_id, bool recurse) RecordPlayerEventLog(PlayerEvent::DROPPED_ITEM, e); } - int i = parse->EventItem(EVENT_DROP_ITEM, this, inst, nullptr, "", slot_id); - if (i != 0) { - LogInventory("Item drop handled by [EVENT_DROP_ITEM]"); - safe_delete(inst); + if (parse->ItemHasQuestSub(inst, EVENT_DROP_ITEM)) { + parse->EventItem(EVENT_DROP_ITEM, this, inst, nullptr, "", slot_id); + if (i != 0) { + LogInventory("Item drop handled by [EVENT_DROP_ITEM]"); + safe_delete(inst); + } + } + + if (parse->PlayerHasQuestSub(EVENT_DROP_ITEM_CLIENT)) { + std::vector args = { inst }; + + i = parse->EventPlayer(EVENT_DROP_ITEM_CLIENT, this, "", slot_id, &args); + if (i != 0) { + LogInventory("Item drop handled by [EVENT_DROP_ITEM_CLIENT]"); + safe_delete(inst); + } } } else { // Item doesn't exist in inventory! diff --git a/zone/lua_general.cpp b/zone/lua_general.cpp index 23a2fa398..d12eb0be5 100644 --- a/zone/lua_general.cpp +++ b/zone/lua_general.cpp @@ -4751,7 +4751,8 @@ luabind::scope lua_register_events() { 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("destroy_item_client", static_cast(EVENT_DESTROY_ITEM_CLIENT)) + luabind::value("destroy_item_client", static_cast(EVENT_DESTROY_ITEM_CLIENT)), + luabind::value("drop_item_client", static_cast(EVENT_DROP_ITEM_CLIENT)) )]; } diff --git a/zone/lua_parser.cpp b/zone/lua_parser.cpp index 3139240bf..ebf95f424 100644 --- a/zone/lua_parser.cpp +++ b/zone/lua_parser.cpp @@ -163,6 +163,7 @@ const char *LuaEvents[_LargestEventID] = { "event_item_click_client", "event_item_click_cast_client", "event_destroy_item_client" + "event_drop_item_client" }; extern Zone *zone; @@ -287,6 +288,7 @@ LuaParser::LuaParser() { 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; + PlayerArgumentDispatch[EVENT_DROP_ITEM_CLIENT] = handle_player_drop_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 1b42c27a6..ad7a12c5f 100644 --- a/zone/lua_parser_events.cpp +++ b/zone/lua_parser_events.cpp @@ -1334,6 +1334,40 @@ void handle_player_destroy_item( 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"); + } +} + +void handle_player_drop_item( + QuestInterface *parse, + lua_State* L, + Client* client, + std::string data, + uint32 extra_data, + std::vector *extra_pointers +) { + lua_pushnumber(L, extra_data); + lua_setfield(L, -2, "slot_id"); + + if (extra_pointers && extra_pointers->size() == 1) { + EQ::ItemInstance* item_inst = std::any_cast(extra_pointers->at(0)); + + lua_pushnumber(L, item_inst->IsStackable() ? item_inst->GetCharges() : 1); + lua_setfield(L, -2, "quantity"); + + lua_pushnumber(L, item_inst->GetItem()->ID); + lua_setfield(L, -2, "item_id"); + + lua_pushstring(L, item_inst->GetItem()->Name); + lua_setfield(L, -2, "item_name"); + + lua_pushnumber(L, item_inst->GetItem()->Click.Effect); + lua_setfield(L, -2, "spell_id"); + + Lua_Item l_item(item_inst->GetItem()); luabind::adl::object l_item_o = luabind::adl::object(L, l_item); l_item_o.push(L); lua_setfield(L, -2, "item"); diff --git a/zone/lua_parser_events.h b/zone/lua_parser_events.h index e06602eba..b8399548b 100644 --- a/zone/lua_parser_events.h +++ b/zone/lua_parser_events.h @@ -707,6 +707,15 @@ void handle_player_target_change( std::vector *extra_pointers ); +void handle_player_drop_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,