From 64eff5815a96ec129fd7b2e5aee97f1a6a3f2512 Mon Sep 17 00:00:00 2001 From: sruon Date: Wed, 8 Apr 2026 01:08:14 -0600 Subject: [PATCH] Call onItemDrop when passing through the recycle bin Co-Authored-By: atom0s --- scripts/items/chaosbringer.lua | 6 ++++-- scripts/items/rajas_ring.lua | 6 ++++-- scripts/items/sattva_ring.lua | 6 ++++-- scripts/items/tamas_ring.lua | 6 ++++-- scripts/specs/types/Item.lua | 2 +- src/common/types/flag.h | 3 ++- src/map/lua/luautils.cpp | 4 ++-- src/map/lua/luautils.h | 2 +- src/map/utils/charutils.cpp | 18 ++++++++++++++++++ 9 files changed, 40 insertions(+), 13 deletions(-) diff --git a/scripts/items/chaosbringer.lua b/scripts/items/chaosbringer.lua index 35963534a57..3e5928fd1a7 100644 --- a/scripts/items/chaosbringer.lua +++ b/scripts/items/chaosbringer.lua @@ -5,8 +5,10 @@ ---@type TItem local itemObject = {} -itemObject.onItemDrop = function(target, item) - target:setCharVar('ChaosbringerKills', 0) +itemObject.onItemDrop = function(target, item, recycleBin) + if not recycleBin then + target:setCharVar('ChaosbringerKills', 0) + end end itemObject.onItemEquip = function(target, item) diff --git a/scripts/items/rajas_ring.lua b/scripts/items/rajas_ring.lua index aeb96dac8d0..71b2772d107 100644 --- a/scripts/items/rajas_ring.lua +++ b/scripts/items/rajas_ring.lua @@ -11,8 +11,10 @@ end itemObject.onItemUse = function(target) end -itemObject.onItemDrop = function(target, item) - xi.mission.setVar(target, xi.mission.log_id.COP, xi.mission.id.cop.DAWN, 'Timer', 1, GetSystemTime() + 27 * 24 * 60 * 60) +itemObject.onItemDrop = function(target, item, recycleBin) + if not recycleBin then + xi.mission.setVar(target, xi.mission.log_id.COP, xi.mission.id.cop.DAWN, 'Timer', 1, GetSystemTime() + 27 * 24 * 60 * 60) + end end return itemObject diff --git a/scripts/items/sattva_ring.lua b/scripts/items/sattva_ring.lua index c3b9e6d9223..afe566d7599 100644 --- a/scripts/items/sattva_ring.lua +++ b/scripts/items/sattva_ring.lua @@ -11,8 +11,10 @@ end itemObject.onItemUse = function(target) end -itemObject.onItemDrop = function(target, item) - xi.mission.setVar(target, xi.mission.log_id.COP, xi.mission.id.cop.DAWN, 'Timer', 1, GetSystemTime() + 27 * 24 * 60 * 60) +itemObject.onItemDrop = function(target, item, recycleBin) + if not recycleBin then + xi.mission.setVar(target, xi.mission.log_id.COP, xi.mission.id.cop.DAWN, 'Timer', 1, GetSystemTime() + 27 * 24 * 60 * 60) + end end return itemObject diff --git a/scripts/items/tamas_ring.lua b/scripts/items/tamas_ring.lua index a23d59a5ee3..330a12c43a8 100644 --- a/scripts/items/tamas_ring.lua +++ b/scripts/items/tamas_ring.lua @@ -11,8 +11,10 @@ end itemObject.onItemUse = function(target) end -itemObject.onItemDrop = function(target, item) - xi.mission.setVar(target, xi.mission.log_id.COP, xi.mission.id.cop.DAWN, 'Timer', 1, GetSystemTime() + 27 * 24 * 60 * 60) +itemObject.onItemDrop = function(target, item, recycleBin) + if not recycleBin then + xi.mission.setVar(target, xi.mission.log_id.COP, xi.mission.id.cop.DAWN, 'Timer', 1, GetSystemTime() + 27 * 24 * 60 * 60) + end end return itemObject diff --git a/scripts/specs/types/Item.lua b/scripts/specs/types/Item.lua index 4aa0b9f3f6d..5039b27a5f6 100644 --- a/scripts/specs/types/Item.lua +++ b/scripts/specs/types/Item.lua @@ -6,7 +6,7 @@ ---@field onItemUnequip? fun(PUser: CBaseEntity, PItem: CItem): nil ---@field onItemEquip? fun(PUser: CBaseEntity, PItem: CItem): nil ---@field onItemAdditionalEffect? fun(attacker: CBaseEntity, target: CBaseEntity, baseAttackDamage: integer, item: CItem): (integer, integer, integer) ----@field onItemDrop? fun(PUser: CBaseEntity, PItem: CItem): nil +---@field onItemDrop? fun(PUser: CBaseEntity, PItem: CItem, recycleBin: boolean): nil ---@field onEffectGain? fun(target: CBaseEntity, effect: CStatusEffect): nil ---@field onEffectLose? fun(target: CBaseEntity, effect: CStatusEffect): nil ---@field onEffectTick? fun(target: CBaseEntity, effect: CStatusEffect): nil diff --git a/src/common/types/flag.h b/src/common/types/flag.h index 50e77d6db79..cdca565a84d 100644 --- a/src/common/types/flag.h +++ b/src/common/types/flag.h @@ -79,4 +79,5 @@ constexpr Flag Flag::No{ false }; // : inside xi:: // -using SendPacket = xi::Flag; +using SendPacket = xi::Flag; +using IsRecycleBin = xi::Flag; diff --git a/src/map/lua/luautils.cpp b/src/map/lua/luautils.cpp index bd829fcb242..cf10cf4328f 100644 --- a/src/map/lua/luautils.cpp +++ b/src/map/lua/luautils.cpp @@ -2726,7 +2726,7 @@ int32 OnItemUse(CBaseEntity* PUser, CBaseEntity* PTarget, CItem* PItem, action_t } // Trigger Code on an item when it has been dropped -void OnItemDrop(CBaseEntity* PUser, CItem* PItem) +void OnItemDrop(CBaseEntity* PUser, CItem* PItem, IsRecycleBin recycleBin) { TracyZoneScoped; @@ -2738,7 +2738,7 @@ void OnItemDrop(CBaseEntity* PUser, CItem* PItem) return; } - auto result = onItemDrop(PUser, PItem); + auto result = onItemDrop(PUser, PItem, static_cast(recycleBin)); if (!result.valid()) { sol::error err = result; diff --git a/src/map/lua/luautils.h b/src/map/lua/luautils.h index fb608efa439..9810a48e61d 100644 --- a/src/map/lua/luautils.h +++ b/src/map/lua/luautils.h @@ -331,7 +331,7 @@ void OnUpdateAttachment(CBattleEntity* PEntity, CItemPuppet* attachment, uint8 m int32 OnItemUse(CBaseEntity* PUser, CBaseEntity* PTarget, CItem* PItem, action_t& action); auto OnItemCheck(CBaseEntity* PTarget, CItem* PItem, ITEMCHECK param = ITEMCHECK::NONE, CBaseEntity* PCaster = nullptr) -> std::tuple; -void OnItemDrop(CBaseEntity* PUser, CItem* PItem); +void OnItemDrop(CBaseEntity* PUser, CItem* PItem, IsRecycleBin recycleBin = IsRecycleBin::No); void OnItemEquip(CBaseEntity* PUser, CItem* PItem); void OnItemUnequip(CBaseEntity* PUser, CItem* PItem); void CheckForGearSet(CBaseEntity* PTarget); diff --git a/src/map/utils/charutils.cpp b/src/map/utils/charutils.cpp index 522df332de7..a8c0e4c9527 100644 --- a/src/map/utils/charutils.cpp +++ b/src/map/utils/charutils.cpp @@ -2919,6 +2919,7 @@ void AddItemToRecycleBin(CCharEntity* PChar, uint32 container, uint8 slotID, uin PChar->pushPacket(nullptr, static_cast(container), slotID); PChar->pushPacket(PItem, LOC_RECYCLEBIN, NewSlotID); PChar->pushPacket(nullptr, PItem->getID(), quantity, MsgStd::ThrowAway); + luautils::OnItemDrop(PChar, PItem, IsRecycleBin::Yes); } else { @@ -2930,12 +2931,19 @@ void AddItemToRecycleBin(CCharEntity* PChar, uint32 container, uint8 slotID, uin else // Bin is full { // Evict recycle bin slot 1 + CItem* PEvictedItem = RecycleBin->GetItem(1); RecycleBin->InsertItem(nullptr, 1); db::preparedStmt("DELETE FROM char_inventory WHERE charid = ? AND location = ? AND slot = ? LIMIT 1", PChar->id, LOC_RECYCLEBIN, 1); + if (PEvictedItem) + { + luautils::OnItemDrop(PChar, PEvictedItem); + destroy(PEvictedItem); + } + // Move everything around to accomodate for (int i = 2; i <= 10; ++i) { @@ -2975,6 +2983,7 @@ void AddItemToRecycleBin(CCharEntity* PChar, uint32 container, uint8 slotID, uin PChar->pushPacket(PUpdatedItem, LOC_RECYCLEBIN, i); } PChar->pushPacket(nullptr, PItem->getID(), quantity, MsgStd::ThrowAway); + luautils::OnItemDrop(PChar, PItem, IsRecycleBin::Yes); } PChar->pushPacket(PChar); } @@ -2984,6 +2993,15 @@ void EmptyRecycleBin(CCharEntity* PChar) TracyZoneScoped; CItemContainer* recycleBin = PChar->getStorage(LOC_RECYCLEBIN); + + for (uint8 slotID = 1; slotID <= recycleBin->GetSize(); ++slotID) + { + if (CItem* PItem = recycleBin->GetItem(slotID)) + { + luautils::OnItemDrop(PChar, PItem); + } + } + db::preparedStmt("DELETE FROM char_inventory WHERE charid = ? AND location = 17", PChar->id); recycleBin->Clear(); }