Implement quickstack to existing stacks in inventory
This commit is contained in:
@@ -18,6 +18,7 @@ MyModGlobal = {
|
|||||||
FIX = Keys.R,
|
FIX = Keys.R,
|
||||||
UNLOAD = Keys.E,
|
UNLOAD = Keys.E,
|
||||||
RELOAD = Keys.R,
|
RELOAD = Keys.R,
|
||||||
|
STACK_TO_CURSOR = Keys.G,
|
||||||
NESTED_CONTAINERS = true,
|
NESTED_CONTAINERS = true,
|
||||||
DEBUG_MODE = true,
|
DEBUG_MODE = true,
|
||||||
},
|
},
|
||||||
@@ -86,6 +87,15 @@ Hook.Patch("Barotrauma.Character", "ControlLocalPlayer", function(instance, ptab
|
|||||||
quickstack.quickStackItems(instance)
|
quickstack.quickStackItems(instance)
|
||||||
end, Hook.HookMethodType.After)
|
end, Hook.HookMethodType.After)
|
||||||
|
|
||||||
|
Hook.Patch("Barotrauma.Character", "ControlLocalPlayer", function(instance, ptable)
|
||||||
|
if not PlayerInput.KeyHit(MyModGlobal.CONFIG.STACK_TO_CURSOR) then return end
|
||||||
|
if not PlayerInput.IsShiftDown() then
|
||||||
|
quickstack.stackToCursor()
|
||||||
|
else
|
||||||
|
quickstack.stackAllToCursor()
|
||||||
|
end
|
||||||
|
end, Hook.HookMethodType.After)
|
||||||
|
|
||||||
Hook.Patch("Barotrauma.Character", "ControlLocalPlayer", function(instance, ptable)
|
Hook.Patch("Barotrauma.Character", "ControlLocalPlayer", function(instance, ptable)
|
||||||
if not PlayerInput.KeyHit(MyModGlobal.CONFIG.FABRICATOR_KEY) then return end
|
if not PlayerInput.KeyHit(MyModGlobal.CONFIG.FABRICATOR_KEY) then return end
|
||||||
fabricatorstack.tryStackFabricator(instance)
|
fabricatorstack.tryStackFabricator(instance)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
-- luacheck: globals MyModGlobal Character
|
-- luacheck: globals MyModGlobal Character
|
||||||
|
-- luacheck: max line length 420
|
||||||
local utils = require("Cyka.utils")
|
local utils = require("Cyka.utils")
|
||||||
|
|
||||||
---@class ItemLocation
|
---@class ItemLocation
|
||||||
@@ -188,37 +189,6 @@ local function tryMoveItems(items, itemTree, force)
|
|||||||
return errs
|
return errs
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
---@return Barotrauma.Item[]
|
|
||||||
local function getOpenContainers()
|
|
||||||
-- MyModGlobal.debugPrint("Attempting to find open container...")
|
|
||||||
-- local containers = {}
|
|
||||||
-- for item in Item.ItemList do
|
|
||||||
-- ---@cast item Barotrauma.Item
|
|
||||||
-- local isok = true
|
|
||||||
-- isok = isok and item ~= nil
|
|
||||||
-- isok = isok and item.OwnInventory ~= nil
|
|
||||||
-- isok = isok and item.OwnInventory.visualSlots ~= nil
|
|
||||||
-- isok = isok and #item.OwnInventory.visualSlots > 0
|
|
||||||
-- -- I don't know what rootContainer is
|
|
||||||
-- -- It seems to be the parent of the current item...?
|
|
||||||
-- -- Maybe the world object...
|
|
||||||
-- -- Either way - static objects that we may open have it
|
|
||||||
-- -- And our own inventory does not
|
|
||||||
-- -- So it's a good selector for now
|
|
||||||
-- isok = isok and item.rootContainer ~= nil
|
|
||||||
-- if isok then
|
|
||||||
-- containers[#containers + 1] = item
|
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
|
|
||||||
local controlledCharacter = Character.Controlled
|
|
||||||
if not controlledCharacter then return {} end
|
|
||||||
local selectedItem = controlledCharacter.SelectedItem
|
|
||||||
if not selectedItem then return {} end
|
|
||||||
return { selectedItem }
|
|
||||||
end
|
|
||||||
|
|
||||||
---@param character Barotrauma.Character
|
---@param character Barotrauma.Character
|
||||||
---@return table<string, ItemLocation[]>, string
|
---@return table<string, ItemLocation[]>, string
|
||||||
local function tryBuildCharacterItemTree(character)
|
local function tryBuildCharacterItemTree(character)
|
||||||
@@ -310,7 +280,7 @@ local function quickStackItems(character)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local openContainers = getOpenContainers()
|
local openContainers = utils.getOpenContainers()
|
||||||
for _, container in ipairs(openContainers) do
|
for _, container in ipairs(openContainers) do
|
||||||
local inventories = container.OwnInventories
|
local inventories = container.OwnInventories
|
||||||
MyModGlobal.debugPrint(string.format("Found %d inventories in the open container", #inventories))
|
MyModGlobal.debugPrint(string.format("Found %d inventories in the open container", #inventories))
|
||||||
@@ -329,6 +299,78 @@ local function quickStackItems(character)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function stackToCursor()
|
||||||
|
local slots, err = utils.getSlotsUnderCursor()
|
||||||
|
if err then
|
||||||
|
MyModGlobal.debugPrint(string.format("Error getting slots under cursor: %s", err))
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, slot in ipairs(slots) do
|
||||||
|
local item
|
||||||
|
if not slot.slot.items or #slot.slot.items == 0 then
|
||||||
|
MyModGlobal.debugPrint("No items in slot")
|
||||||
|
goto continue
|
||||||
|
end
|
||||||
|
|
||||||
|
item = slot.slot.items[1]
|
||||||
|
utils.enqueueAllPlayerItems({}, function(ititem)
|
||||||
|
if ititem.Prefab.Identifier.Value == item.Prefab.Identifier.Value then
|
||||||
|
if item == ititem then return false end
|
||||||
|
-- We are moving items in the predicate because we expect to only
|
||||||
|
-- Select a small subset of all items
|
||||||
|
-- And it is much easier to let the game decide when we can not move
|
||||||
|
-- Any more items (via return value of TryPutItem)
|
||||||
|
-- And we then know that we can safely stop
|
||||||
|
local moved = slot.inventory.TryPutItem(ititem, slot.slotIndex - 1, false, true, nil)
|
||||||
|
if not moved then
|
||||||
|
MyModGlobal.debugPrint(string.format("Failed to move item %s to slot %d", ititem.Name, slot
|
||||||
|
.slotIndex - 1))
|
||||||
|
return false, true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
::continue::
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function stackAllToCursor()
|
||||||
|
local slots, err = utils.getSlotsUnderCursor()
|
||||||
|
if err then
|
||||||
|
MyModGlobal.debugPrint(string.format("Error getting slots under cursor: %s", err))
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, slot in ipairs(slots) do
|
||||||
|
local item
|
||||||
|
if not slot.slot.items or #slot.slot.items == 0 then
|
||||||
|
MyModGlobal.debugPrint("No items in slot")
|
||||||
|
goto continue
|
||||||
|
end
|
||||||
|
|
||||||
|
item = slot.slot.items[1]
|
||||||
|
utils.enqueueAllOwnedItems({}, function(ititem)
|
||||||
|
if ititem.Prefab.Identifier.Value == item.Prefab.Identifier.Value then
|
||||||
|
if item == ititem then return false end
|
||||||
|
-- We are moving items in the predicate because we expect to only
|
||||||
|
-- Select a small subset of all items
|
||||||
|
-- And it is much easier to let the game decide when we can not move
|
||||||
|
-- Any more items (via return value of TryPutItem)
|
||||||
|
-- And we then know that we can safely stop
|
||||||
|
local moved = slot.inventory.TryPutItem(ititem, slot.slotIndex - 1, false, true, nil)
|
||||||
|
if not moved then
|
||||||
|
MyModGlobal.debugPrint(string.format("Failed to move item %s to slot %d", ititem.Name, slot
|
||||||
|
.slotIndex - 1))
|
||||||
|
return false, true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
::continue::
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
return {
|
return {
|
||||||
buildItemTree = buildItemTree,
|
buildItemTree = buildItemTree,
|
||||||
tryBuildCharacterItemTree = tryBuildCharacterItemTree,
|
tryBuildCharacterItemTree = tryBuildCharacterItemTree,
|
||||||
@@ -336,5 +378,6 @@ return {
|
|||||||
tryMoveItem = tryMoveItem,
|
tryMoveItem = tryMoveItem,
|
||||||
tryMoveItems = tryMoveItems,
|
tryMoveItems = tryMoveItems,
|
||||||
quickStackItems = quickStackItems,
|
quickStackItems = quickStackItems,
|
||||||
getOpenContainers = getOpenContainers
|
stackToCursor = stackToCursor,
|
||||||
|
stackAllToCursor = stackAllToCursor,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
-- luacheck: globals Character MyModGlobal Timer
|
-- luacheck: globals Character MyModGlobal Timer
|
||||||
local cursormacroer = require("Cyka.cursormacroer")
|
local utils = require("Cyka.utils")
|
||||||
local dump = require("Cyka.dump")
|
|
||||||
|
|
||||||
---@param inventory Barotrauma.ItemInventory
|
---@param inventory Barotrauma.ItemInventory
|
||||||
---@param predicate fun(slot: InventorySlot): boolean
|
---@param predicate fun(slot: InventorySlot): boolean
|
||||||
|
|||||||
@@ -333,7 +333,12 @@ local function getFirstSlotUnderCursor()
|
|||||||
local slots, err = getSlotsUnderCursor()
|
local slots, err = getSlotsUnderCursor()
|
||||||
if err then return nil, err end
|
if err then return nil, err end
|
||||||
if #slots == 0 then return nil, "No slots found under cursor" end
|
if #slots == 0 then return nil, "No slots found under cursor" end
|
||||||
return slots[1], nil
|
for _, slot in ipairs(slots) do
|
||||||
|
if #slot.items > 0 then
|
||||||
|
return slot
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return slots[1]
|
||||||
end
|
end
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
Reference in New Issue
Block a user