mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-12 16:31:05 +02:00
226 lines
7.3 KiB
Lua
226 lines
7.3 KiB
Lua
-- Items panel: money, the 20-slot bag (Bag.add/remove, ordered by
|
|
-- Bag.order), gym badges (boolean flags on inventory), and PC Item
|
|
-- storage (a plain S.save.pcItems dict, created on first use).
|
|
|
|
local Bag = require("src.inventory.Bag")
|
|
|
|
local M = {}
|
|
|
|
local ROW_H = 20
|
|
local LIST_H = 200
|
|
local VISIBLE_ROWS = math.floor(LIST_H / ROW_H)
|
|
|
|
local function mark(S)
|
|
S.dirty = true
|
|
end
|
|
|
|
-- Prev/Next pagination (mirrors Events/Dex panels) so bag/PC lists longer
|
|
-- than VISIBLE_ROWS stay fully reachable instead of truncating silently.
|
|
local function clampScroll(scroll, total)
|
|
local maxScroll = math.max(0, total - VISIBLE_ROWS)
|
|
scroll = scroll or 0
|
|
if scroll > maxScroll then scroll = maxScroll end
|
|
if scroll < 0 then scroll = 0 end
|
|
return scroll
|
|
end
|
|
|
|
local function pageSlice(items, scroll)
|
|
local page = {}
|
|
for i = 1, math.min(VISIBLE_ROWS, #items - scroll) do
|
|
page[i] = items[scroll + i]
|
|
end
|
|
return page
|
|
end
|
|
|
|
local function drawPager(Kit, x, y, total, scroll, onPrev, onNext)
|
|
if Kit.button(x, y, 90, 26, "Prev") then onPrev() end
|
|
if Kit.button(x + 100, y, 90, 26, "Next") then onNext() end
|
|
local shown = math.min(VISIBLE_ROWS, math.max(0, total - scroll))
|
|
Kit.label(x + 210, y + 5, string.format("%d-%d of %d",
|
|
total > 0 and scroll + 1 or 0, scroll + shown, total))
|
|
end
|
|
|
|
local function clamp(n, lo, hi)
|
|
if n < lo then return lo end
|
|
if n > hi then return hi end
|
|
return n
|
|
end
|
|
|
|
local function isBadgeId(id)
|
|
return id:find("BADGE", 1, true) ~= nil
|
|
end
|
|
|
|
local function badgeIds(cat)
|
|
local ids = {}
|
|
for _, id in ipairs(cat.items) do
|
|
if isBadgeId(id) then table.insert(ids, id) end
|
|
end
|
|
return ids
|
|
end
|
|
|
|
local function bagLines(save)
|
|
local order = Bag.order(save)
|
|
local lines = {}
|
|
for i, id in ipairs(order) do
|
|
lines[i] = string.format("%-16s x%d", id, save.inventory[id] or 0)
|
|
end
|
|
return lines, order
|
|
end
|
|
|
|
local function pcItemOrder(pcItems)
|
|
local ids = {}
|
|
for id in pairs(pcItems) do table.insert(ids, id) end
|
|
table.sort(ids)
|
|
return ids
|
|
end
|
|
|
|
local function pcLines(pcItems, order)
|
|
local lines = {}
|
|
for i, id in ipairs(order) do
|
|
lines[i] = string.format("%-16s x%d", id, pcItems[id] or 0)
|
|
end
|
|
return lines
|
|
end
|
|
|
|
local function pcAdd(save, id, qty)
|
|
save.pcItems = save.pcItems or {}
|
|
local pc = save.pcItems
|
|
pc[id] = math.min(99, (pc[id] or 0) + (qty or 1))
|
|
end
|
|
|
|
local function pcRemove(save, id, qty)
|
|
local pc = save.pcItems
|
|
if not pc or not pc[id] then return end
|
|
pc[id] = pc[id] - (qty or 1)
|
|
if pc[id] <= 0 then pc[id] = nil end
|
|
end
|
|
|
|
function M.draw(S, Kit, x, y)
|
|
S.save.pcItems = S.save.pcItems or {}
|
|
|
|
-- Money
|
|
Kit.label(x, y, "Money: $" .. tostring(S.save.money))
|
|
local moneyBtnY = y + 22
|
|
if Kit.button(x, moneyBtnY, 60, 26, "-100") then
|
|
S.save.money = clamp(S.save.money - 100, 0, 999999); mark(S)
|
|
end
|
|
if Kit.button(x + 66, moneyBtnY, 60, 26, "-10") then
|
|
S.save.money = clamp(S.save.money - 10, 0, 999999); mark(S)
|
|
end
|
|
if Kit.button(x + 132, moneyBtnY, 60, 26, "+10") then
|
|
S.save.money = clamp(S.save.money + 10, 0, 999999); mark(S)
|
|
end
|
|
if Kit.button(x + 198, moneyBtnY, 60, 26, "+100") then
|
|
S.save.money = clamp(S.save.money + 100, 0, 999999); mark(S)
|
|
end
|
|
|
|
-- Item picker (species-like picker over S.cat.items) shared by bag/PC add
|
|
local pickerY = moneyBtnY + 40
|
|
S.itemPickerIdx = clamp(S.itemPickerIdx or 1, 1, #S.cat.items)
|
|
local pickId = S.cat.items[S.itemPickerIdx]
|
|
Kit.label(x, pickerY + 5, "Item:")
|
|
if Kit.button(x + 46, pickerY, 26, 26, "<") then
|
|
S.itemPickerIdx = ((S.itemPickerIdx - 2) % #S.cat.items) + 1
|
|
end
|
|
Kit.label(x + 82, pickerY + 5, pickId)
|
|
if Kit.button(x + 280, pickerY, 26, 26, ">") then
|
|
S.itemPickerIdx = (S.itemPickerIdx % #S.cat.items) + 1
|
|
end
|
|
if Kit.button(x + 320, pickerY, 110, 26, "Add to Bag") then
|
|
if Bag.add(S.save, pickId, 1) then mark(S) end
|
|
end
|
|
if Kit.button(x + 440, pickerY, 110, 26, "Add to PC") then
|
|
pcAdd(S.save, pickId, 1); mark(S)
|
|
end
|
|
|
|
-- Bag list
|
|
local bagLabelY = pickerY + 40
|
|
Kit.label(x, bagLabelY, string.format("Bag (%d/%d slots)", Bag.slots(S.save), Bag.CAPACITY))
|
|
local bagListY = bagLabelY + 20
|
|
local lines, order = bagLines(S.save)
|
|
S.selectedBagIdx = clamp(S.selectedBagIdx or 1, 1, math.max(#order, 1))
|
|
S.bagScroll = clampScroll(S.bagScroll, #order)
|
|
local bagClick = Kit.list(x, bagListY, 300, LIST_H, pageSlice(lines, S.bagScroll),
|
|
S.selectedBagIdx - S.bagScroll, ROW_H)
|
|
if bagClick then S.selectedBagIdx = S.bagScroll + bagClick end
|
|
|
|
local bagPagerY = bagListY + LIST_H + 8
|
|
drawPager(Kit, x, bagPagerY, #order, S.bagScroll,
|
|
function() S.bagScroll = clampScroll(S.bagScroll - VISIBLE_ROWS, #order) end,
|
|
function() S.bagScroll = clampScroll(S.bagScroll + VISIBLE_ROWS, #order) end)
|
|
|
|
local bagActionsY = bagPagerY + 34
|
|
if Kit.button(x, bagActionsY, 100, 28, "Remove 1") then
|
|
local id = order[S.selectedBagIdx]
|
|
if id then
|
|
Bag.remove(S.save, id, 1)
|
|
S.selectedBagIdx = clamp(S.selectedBagIdx, 1, math.max(#Bag.order(S.save), 1))
|
|
mark(S)
|
|
end
|
|
end
|
|
if Kit.button(x + 110, bagActionsY, 100, 28, "Remove all") then
|
|
local id = order[S.selectedBagIdx]
|
|
if id then
|
|
Bag.remove(S.save, id, S.save.inventory[id])
|
|
S.selectedBagIdx = clamp(S.selectedBagIdx, 1, math.max(#Bag.order(S.save), 1))
|
|
mark(S)
|
|
end
|
|
end
|
|
|
|
-- PC items list (mirrors bag UX; plain dict, no slot cap)
|
|
local pcLabelY = bagActionsY + 40
|
|
local pcOrder = pcItemOrder(S.save.pcItems)
|
|
Kit.label(x, pcLabelY, string.format("PC Items (%d kinds)", #pcOrder))
|
|
local pcListY = pcLabelY + 20
|
|
S.selectedPcIdx = clamp(S.selectedPcIdx or 1, 1, math.max(#pcOrder, 1))
|
|
S.pcScroll = clampScroll(S.pcScroll, #pcOrder)
|
|
local pcClick = Kit.list(x, pcListY, 300, LIST_H,
|
|
pageSlice(pcLines(S.save.pcItems, pcOrder), S.pcScroll),
|
|
S.selectedPcIdx - S.pcScroll, ROW_H)
|
|
if pcClick then S.selectedPcIdx = S.pcScroll + pcClick end
|
|
|
|
local pcPagerY = pcListY + LIST_H + 8
|
|
drawPager(Kit, x, pcPagerY, #pcOrder, S.pcScroll,
|
|
function() S.pcScroll = clampScroll(S.pcScroll - VISIBLE_ROWS, #pcOrder) end,
|
|
function() S.pcScroll = clampScroll(S.pcScroll + VISIBLE_ROWS, #pcOrder) end)
|
|
|
|
local pcActionsY = pcPagerY + 34
|
|
if Kit.button(x, pcActionsY, 100, 28, "Remove 1") then
|
|
local id = pcOrder[S.selectedPcIdx]
|
|
if id then
|
|
pcRemove(S.save, id, 1)
|
|
pcOrder = pcItemOrder(S.save.pcItems)
|
|
S.selectedPcIdx = clamp(S.selectedPcIdx, 1, math.max(#pcOrder, 1))
|
|
mark(S)
|
|
end
|
|
end
|
|
if Kit.button(x + 110, pcActionsY, 100, 28, "Remove all") then
|
|
local id = pcOrder[S.selectedPcIdx]
|
|
if id then
|
|
pcRemove(S.save, id, S.save.pcItems[id])
|
|
pcOrder = pcItemOrder(S.save.pcItems)
|
|
S.selectedPcIdx = clamp(S.selectedPcIdx, 1, math.max(#pcOrder, 1))
|
|
mark(S)
|
|
end
|
|
end
|
|
|
|
-- Badges: boolean flags directly on inventory, toggled by click
|
|
local badgeLabelY = pcActionsY + 40
|
|
Kit.label(x, badgeLabelY, "Badges (click to toggle)")
|
|
local badgeY = badgeLabelY + 20
|
|
local ids = badgeIds(S.cat)
|
|
for i, id in ipairs(ids) do
|
|
local col = (i - 1) % 4
|
|
local row = math.floor((i - 1) / 4)
|
|
local bx = x + col * 150
|
|
local by = badgeY + row * 30
|
|
local on = S.save.inventory[id] == true
|
|
if Kit.button(bx, by, 144, 26, id .. (on and " [X]" or "")) then
|
|
if on then S.save.inventory[id] = nil else S.save.inventory[id] = true end
|
|
mark(S)
|
|
end
|
|
end
|
|
end
|
|
|
|
return M
|