Skip to content

Commit 8bfe0b0

Browse files
committed
item: EquipItemByName auto-slot uses Item::Cursor::PickupBagItem
Replace the auto-slot path's Script_PickupContainerItem stack-fake (SetTop + PushNumber x2 + call) with the shared Item::Cursor::PickupBagItem, which drives the engine's cursor primitive directly -- the same one C_Item.PickupItem uses. The ClearCursor at the top still runs first, so PickupBagItem's empty-cursor guard is satisfied; bail if the pickup didn't take (locked item / busy cursor) rather than auto-equipping nothing. Drops the now-unused ScriptFn_t typedef. FUN_SCRIPT_PICKUP_CONTAINER_ITEM now has no callers -- the Script-pickup stack-fake is gone from the codebase. Explicit-dstSlot path (atomic FUN_INVENTORY_SWAP) is unchanged. Verified in-game (auto-slot equip by name and by id).
1 parent e9c2e74 commit 8bfe0b0

1 file changed

Lines changed: 11 additions & 13 deletions

File tree

src/item/Equipment.cpp

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "Game.h"
1515
#include "Offsets.h"
1616
#include "item/Arg.h"
17+
#include "item/Cursor.h"
1718
#include "item/ID.h"
1819
#include "item/Location.h"
1920
#include "item/Swap.h"
@@ -181,8 +182,6 @@ int __fastcall Script_C_Item_EquipItemByName(void *L) {
181182
const bool hasDstSlot = Game::Lua::IsNumber(L, 2);
182183
const int dstSlot = hasDstSlot ? static_cast<int>(Game::Lua::ToNumber(L, 2)) : 0;
183184

184-
using ScriptFn_t = int(__fastcall *)(void *L);
185-
186185
// Return any held cursor item to its slot BEFORE searching for
187186
// the target. FUN_INVENTORY_SWAP's end-of-call cleanup at
188187
// FUN_00495190(0, 1) clears LOCAL cursor globals but skips the
@@ -203,17 +202,16 @@ int __fastcall Script_C_Item_EquipItemByName(void *L) {
203202
return 0;
204203
}
205204

206-
// Auto-slot path: pickup the item via Script_PickupContainerItem
207-
// (its state-machine handles spell-cast targeting / repair /
208-
// enchant-scroll / etc., none of which we want to replicate), then
209-
// call the engine's `CGPlayer::AutoEquipCursorItem` helper directly
210-
// — `Script_AutoEquipCursorItem` is a thin wrapper that just
211-
// resolves the local player and calls this with flag=0.
212-
Game::Lua::SetTop(L, 0);
213-
Game::Lua::PushNumber(L, static_cast<double>(found.bagID));
214-
Game::Lua::PushNumber(L, static_cast<double>(found.slotIndex));
215-
auto pickup = reinterpret_cast<ScriptFn_t>(Offsets::FUN_SCRIPT_PICKUP_CONTAINER_ITEM);
216-
pickup(L);
205+
// Auto-slot path: pick the item up onto the cursor, then call the
206+
// engine's `CGPlayer::AutoEquipCursorItem` helper directly
207+
// (`Script_AutoEquipCursorItem` is a thin wrapper that just resolves
208+
// the local player and calls this with flag=0). The pickup goes through
209+
// the shared `Item::Cursor::PickupBagItem`, which drives the engine's
210+
// cursor primitive directly (no Script_PickupContainerItem stack-fake);
211+
// its empty-cursor guard is satisfied by the ClearCursor above. Bail if
212+
// the pickup didn't take (locked item / busy cursor) — nothing to equip.
213+
if (!Item::Cursor::PickupBagItem(L, found.bagID, found.slotIndex))
214+
return 0;
217215

218216
using ResolveUnitToken_t = void *(__fastcall *)(const char *token);
219217
using AutoEquipCursor_t = void (__thiscall *)(void *player, int flag);

0 commit comments

Comments
 (0)