Compare commits

...

2 Commits

Author SHA1 Message Date
d4b4e2c003 Make G work with open containers too 2025-04-01 00:02:03 +02:00
c8eab8dc4d Add enqueueOpenContainers 2025-04-01 00:01:58 +02:00
2 changed files with 119 additions and 71 deletions

View File

@@ -3,6 +3,7 @@
if not CLIENT then return end
local utils = require("Cyka.utils")
local dump = require("Cyka.dump")
---@class ItemLocation
---@field inventory Barotrauma.ItemInventory
@@ -124,7 +125,9 @@ local function tryMoveItem(item, itemTree, force)
-- MyModGlobal.debugPrint(string.format("Can be put in slot %d: %s", itemLocation.slotIndex, tostring(canBePut)))
if itemLocation.maxFits > 0 and canBePut then
moved = moved or itemLocation.inventory.TryPutItem(item, itemLocation.slotIndex, false, true, Character.Controlled, true)
moved = moved or
itemLocation.inventory.TryPutItem(item, itemLocation.slotIndex, false, true, Character.Controlled,
true)
if moved then
itemLocation.maxFits = itemLocation.inventory.HowManyCanBePut(item.Prefab, itemLocation.slotIndex)
end
@@ -152,7 +155,9 @@ local function tryMoveItem(item, itemTree, force)
if maxFits > 0 then
-- MyModGlobal.debugPrint(string.format("Trying to move item to empty slot at index: %d", itemLocation.slotIndex))
moved = moved or itemLocation.inventory.TryPutItem(item, itemLocation.slotIndex, true, false, Character.Controlled, true)
moved = moved or
itemLocation.inventory.TryPutItem(item, itemLocation.slotIndex, true, false, Character.Controlled,
true)
if moved then
itemLocation.maxFits = itemLocation.inventory.HowManyCanBePut(item.Prefab, itemLocation.slotIndex)
end
@@ -225,7 +230,9 @@ end
-- Function to quickly stack items from inventory to containers
-- 6 and 7 are hands
-- 9..18 are main slots
local inventorySlotsToStack = { 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 }
local inventorySlotsToStack = { 6, 7, }
-- local inventorySlotsToStack = { 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 }
---@param character Barotrauma.Character
local function quickStackItems(character)
if not character then
MyModGlobal.debugPrint("No character found")
@@ -257,31 +264,38 @@ local function quickStackItems(character)
--DumpTable(itemTree)
local toMove = {}
for _, slotid in ipairs(inventorySlotsToStack) do
MyModGlobal.debugPrint(string.format("Processing inventory slot: %d", slotid))
local slot = inventory.slots[slotid]
if #slot.items > 0 then
local item = slot.items[1]
local tags = item.Prefab.Tags
local shouldSuss = true
for tag in tags do
if tag.value:find("tool") or tag.value:find("weapon") then
MyModGlobal.debugPrint(string.format("Item '%s' is a tool or weapon, skipping", item.Name))
shouldSuss = false
break
end
end
if shouldSuss then
local before = #toMove
toMove = utils.enqueueSlot(slot, toMove)
local after = #toMove
MyModGlobal.debugPrint(string.format("Enqueued %d items from the inventory slot %d", after - before,
slotid))
end
for item in character.HeldItems do
MyModGlobal.debugPrint(string.format("Item: %s", item.Prefab.Identifier.Value))
if item.OwnInventory then
toMove = utils.enqueueInventory(item.OwnInventory, toMove)
end
end
-- for _, slotid in ipairs(inventorySlotsToStack) do
-- MyModGlobal.debugPrint(string.format("Processing inventory slot: %d", slotid))
-- local slot = inventory.slots[slotid]
-- if #slot.items > 0 then
-- -- local item = slot.items[1]
-- -- local tags = item.Prefab.Tags
-- local shouldSuss = true
-- -- for tag in tags do
-- -- if tag.value:find("tool") or tag.value:find("weapon") then
-- -- MyModGlobal.debugPrint(string.format("Item '%s' is a tool or weapon, skipping", item.Name))
-- -- shouldSuss = false
-- -- break
-- -- end
-- -- end
-- if shouldSuss then
-- local before = #toMove
-- toMove = utils.enqueueSlot(slot, toMove)
-- local after = #toMove
-- MyModGlobal.debugPrint(string.format("Enqueued %d items from the inventory slot %d", after - before,
-- slotid))
-- end
-- end
-- end
local openContainers = utils.getOpenContainers()
for _, container in ipairs(openContainers) do
local inventories = container.OwnInventories
@@ -308,8 +322,38 @@ local function stackToCursor()
return
end
for _, slot in ipairs(slots) do
local item
local item, slot
local function predicate(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
-- UPDATE: OK well that was a stupid idea, it returns an error for other shit as well
-- What other shit? Wish I knew
-- So we'll use HowManyCanBePut instead...
local moved = slot.inventory.TryPutItem(ititem, slot.slotIndex - 1, false, true, Character.Controlled,
true)
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
local maxFits = slot.inventory.HowManyCanBePut(ititem.Prefab, slot.slotIndex - 1)
if maxFits <= 0 then
MyModGlobal.debugPrint(string.format("Item %s has no more fits in slot %d", ititem.Name, slot
.slotIndex - 1))
return false, true
end
end
end
-- We gotta do a little juggling...
for _, sslot in ipairs(slots) do
slot = sslot
local items
if not slot.slot.items or #slot.slot.items == 0 then
MyModGlobal.debugPrint("No items in slot")
goto continue
@@ -317,32 +361,9 @@ local function stackToCursor()
item = slot.slot.items[1]
MyModGlobal.debugPrint(string.format("Stacking all player items to %s", item.Prefab.Identifier.Value))
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
-- UPDATE: OK well that was a stupid idea, it returns an error for other shit as well
-- What other shit? Wish I knew
-- So we'll use HowManyCanBePut instead...
local moved = slot.inventory.TryPutItem(ititem, slot.slotIndex - 1, false, true, Character.Controlled, true)
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
local maxFits = slot.inventory.HowManyCanBePut(ititem.Prefab, slot.slotIndex - 1)
if maxFits <= 0 then
MyModGlobal.debugPrint(string.format("Item %s has no more fits in slot %d", ititem.Name, slot
.slotIndex - 1))
return false, true
end
end
end)
items = {}
utils.enqueueAllPlayerItems(items, predicate)
utils.enqueueOpenContainers(items, predicate)
::continue::
end
end
@@ -374,7 +395,8 @@ local function stackAllToCursor()
-- UPDATE: OK well that was a stupid idea, it returns an error for other shit as well
-- What other shit? Wish I knew
-- So we'll use HowManyCanBePut instead...
local moved = slot.inventory.TryPutItem(ititem, slot.slotIndex - 1, false, true, Character.Controlled, true)
local moved = slot.inventory.TryPutItem(ititem, slot.slotIndex - 1, false, true, Character.Controlled,
true)
if not moved then
MyModGlobal.debugPrint(string.format("Failed to move item %s to slot %d", ititem.Name, slot
.slotIndex - 1))

View File

@@ -11,6 +11,23 @@
---@field inventory Barotrauma.ItemInventory
---@field slotIndex number
---@return Barotrauma.Item[], string?
local function getOpenContainers()
local controlledCharacter = Character.Controlled
if not controlledCharacter then return {}, "No controlled character" end
local selectedItem = controlledCharacter.SelectedItem
if not selectedItem then return {}, "No selected item" end
return { selectedItem }, nil
end
---@return Barotrauma.Item, string?
local function getFirstOpenContainer()
local containers, err = getOpenContainers()
if err then return nil, err end
if #containers == 0 then return nil, "No open containers" end
return containers[1], nil
end
-- We got to do this shit because enqueueInventory calls enqueueItem
-- And enqueueItem calls enqueueInventory
-- So unless we define them both before using them
@@ -18,6 +35,7 @@
local enqueueItem
local enqueueSlot
local enqueueInventory
local enqueueOpenContainers
local allPlayerItems
local allSubmarineItems
local allOwnedItems
@@ -163,6 +181,30 @@ allPlayerItems = function(queue, predicate, loadRefs)
return queue
end
---@param queue Barotrauma.Item[]
---@param predicate? FilterPredicate
---@param loadRefs? boolean
---@return Barotrauma.Item[], string?
enqueueOpenContainers = function(queue, predicate, loadRefs)
queue = queue or {}
predicate = predicate or function() return true end
local containers, err = getOpenContainers()
if err then return queue, err end
for _, container in ipairs(containers) do
local inventories = container.OwnInventories
if not inventories then goto continue end
for containerInventory in inventories do
queue, err = enqueueInventory(containerInventory, queue, predicate, loadRefs)
if err then return queue, err end
end
::continue::
end
return queue
end
---@param queue Barotrauma.Item[]
---@param predicate? FilterPredicate
---@return Barotrauma.Item[], string?
@@ -213,23 +255,6 @@ allOwnedItems = function(queue, predicate, loadRefs)
return queue
end
---@return Barotrauma.Item[], string?
local function getOpenContainers()
local controlledCharacter = Character.Controlled
if not controlledCharacter then return {}, "No controlled character" end
local selectedItem = controlledCharacter.SelectedItem
if not selectedItem then return {}, "No selected item" end
return { selectedItem }, nil
end
---@return Barotrauma.Item, string?
local function getFirstOpenContainer()
local containers, err = getOpenContainers()
if err then return nil, err end
if #containers == 0 then return nil, "No open containers" end
return containers[1], nil
end
-- There is actually no need to recurse deep
-- Because we can only have an item in the inventory open
-- And not an item in an item in the inventory
@@ -354,6 +379,7 @@ return {
enqueueAllPlayerItems = allPlayerItems,
enqueueAllSubmarineItems = allSubmarineItems,
enqueueAllOwnedItems = allOwnedItems,
enqueueOpenContainers = enqueueOpenContainers,
getOpenContainers = getOpenContainers,
getFirstOpenContainer = getFirstOpenContainer,
getSlotsUnderCursor = getSlotsUnderCursor,