Skip to content

Commit

Permalink
Fix stack splitting (without breaking the world)
Browse files Browse the repository at this point in the history
Close #63, for real this time.
  • Loading branch information
veechs committed Jan 26, 2025
1 parent 4b34ff5 commit fd27e52
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 0 deletions.
1 change: 1 addition & 0 deletions Bagshui.lua
Original file line number Diff line number Diff line change
Expand Up @@ -717,6 +717,7 @@ local Bagshui = {
CloseAllWindows = "CloseAllWindows",
DeleteCursorItem = "ClearCursor",
MoneyFrame_UpdateMoney = "MoneyFrame_UpdateMoney",
OpenStackSplitFrame = "OpenStackSplitFrame",
PickupBagFromSlot = "PickupInventoryItem",
PickupInventoryItem = "PickupInventoryItem",
PutItemInBag = "PickupInventoryItem",
Expand Down
50 changes: 50 additions & 0 deletions Components/Bagshui.BlizzFixes.lua
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,54 @@ function Bagshui:MoneyFrame_UpdateMoney(wowApiFunctionName)
end



--- Hack to make stack splitting work consistently.
--- Without this, mouseover events can reset the ID of a group's parent frame,
--- changing the bag number of the pending split. As a result, the split ends
--- up targeting the wrong item. We work around it by doing a hard capture of
--- the bag/slot numbers in `Bagshui:PickupItem()` into the `pending` properties
--- just before calling `ContainerFrameItemButton_OnClick()`. Then once the
--- Blizzard code has done its thing and calls `OpenStackSplitFrame()`, we intercept
--- the call and reassign the frame's `SplitStack` property, which is the callback
--- used when the split is invoked.
---@param wowApiFunctionName string Hooked WoW API function that triggered this call.
---@param maxStack any `OpenStackSplitFrame()` parameter.
---@param parent any `OpenStackSplitFrame()` parameter.
---@param anchor any `OpenStackSplitFrame()` parameter.
---@param anchorTo any `OpenStackSplitFrame()` parameter.
function Bagshui:OpenStackSplitFrame(wowApiFunctionName, maxStack, parent, anchor, anchorTo)

-- Reset just teo be safe.
self.splitStackBagNum = nil
self.splitStackSlotNum = nil

-- Create our override function only once.
if not self.SplitStackOverride then
function self.SplitStackOverride(button, amount)
_G.SplitContainerItem(self.splitStackBagNum, self.splitStackSlotNum, amount)
end
end

-- Detect values set by `Bagshui:PickupItem()` and prepare them for
-- `self.SplitStackOverride() to consume. This will only execute
-- when Bagshui code has set things up and won't interfere with normal
-- stack splitting functionality.
if
type(parent) == "table"
and self.pendingSplitStackBagNum
and self.pendingSplitStackSlotNum
then
self.splitStackBagNum = self.pendingSplitStackBagNum
self.splitStackSlotNum = self.pendingSplitStackSlotNum
self.pendingSplitStackBagNum = nil
self.pendingSplitStackSlotNum = nil
-- Replace the callback set by
parent.SplitStack = self.SplitStackOverride
end

-- Pass along to the normal `OpenStackSplitFrame()` to handle everything.
self.hooks:OriginalHook(wowApiFunctionName, maxStack, parent, anchor, anchorTo)
end


end)
9 changes: 9 additions & 0 deletions Components/Bagshui.Cursor.lua
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ Bagshui:LoadComponent(function()
---@param callPickupContainerItem boolean?
function Bagshui:PickupItem(item, inventoryClass, itemSlotButton, callPickupContainerItem)

self.pendingSplitStackBagNum = nil
self.pendingSplitStackSlotNum = nil
self.splitStackBagNum = nil
self.splitStackSlotNum = nil

-- Track where the pickup call came from so we know whether it's being put down
-- in the same inventory or moved to a different one.
local owningFrame = inventoryClass and inventoryClass.uiFrame or _G.this
Expand Down Expand Up @@ -157,6 +162,10 @@ function Bagshui:PickupItem(item, inventoryClass, itemSlotButton, callPickupCont
else
-- Don't need to (and can't) pass bagNum/slotNum to ContainerFrameItemButton_OnClick(),
-- since it pulls them from _G.this:GetId()/_G.this:GetParent():GetId().
if _G.IsShiftKeyDown() then
self.pendingSplitStackBagNum = item.bagNum
self.pendingSplitStackSlotNum = item.slotNum
end
_G.ContainerFrameItemButton_OnClick("LeftButton")
end
end
Expand Down

0 comments on commit fd27e52

Please sign in to comment.