mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-22 21:46:51 +02:00
605 lines
19 KiB
Lua
605 lines
19 KiB
Lua
-- The player's item PC: _PlayersPC and the three item rows behind it
|
|
-- (engine/events/pokecenter_pc.asm PlayerWithdrawItemMenu /
|
|
-- PlayerDepositItemMenu / PlayerTossItemMenu), plus TossItemFromPC
|
|
-- (engine/pokemon/mon_menu.asm). Both of the cart's callers land here:
|
|
--
|
|
-- PlayersPC PLAYERSPC_NORMAL -- the <PLAYER>'s PC row of the
|
|
-- Pokecenter's whose-PC menu (src/ui/gen2/CenterPcMenu.lua):
|
|
-- WITHDRAW ITEM / DEPOSIT ITEM / TOSS ITEM / MAIL BOX /
|
|
-- LOG OFF
|
|
-- _PlayersHousePC PLAYERSPC_HOUSE -- the bedroom PC's whole screen: the
|
|
-- boot sound and PlayersPCTurnOnText first, DECORATION on
|
|
-- the list, TURN OFF instead of LOG OFF, and the answer
|
|
-- carried back out (TRUE only when a decoration moved) so
|
|
-- PlayersHousePCScript can take its `.Warp` arm
|
|
--
|
|
-- The menu's rows run through the ui.pc.items hook -- the same name and the
|
|
-- same (game, items) payload the Gen 1 PC uses
|
|
-- (src/world/OverworldController.lua openPC) -- with the exit row appended
|
|
-- after it, the way that site appends LOG OFF.
|
|
--
|
|
-- Items live on save.pcItems, the id -> count map ReceiveItem's PC half
|
|
-- already writes (src/core/gen2/MomShopping.lua receiveItemToPc): fifty
|
|
-- distinct stacks of at most 99, like wPCItems. DEPOSIT opens the PACK as a
|
|
-- chooser held by this screen, exactly the arrangement the mart's sell flow
|
|
-- uses (src/ui/gen2/MartMenu.lua enterSell), because DepositSellPack is the
|
|
-- same routine on the cart.
|
|
|
|
local Bag = require("src.inventory.Bag")
|
|
local Chrome = require("src.ui.gen2.Chrome")
|
|
local Logger = require("src.core.Logger")
|
|
local Runtime = require("src.mods.Runtime")
|
|
local Screens = require("src.ui.Screens")
|
|
local Sound = require("src.core.Sound")
|
|
|
|
local ItemPcMenu = {}
|
|
ItemPcMenu.__index = ItemPcMenu
|
|
ItemPcMenu.isOpaque = true
|
|
|
|
-- MAX_PC_ITEMS stacks of at most MAX_ITEM_STACK (constants/item_constants.asm),
|
|
-- the same pair src/core/gen2/MomShopping.lua enforces for Mom's deliveries.
|
|
local PC_ITEM_CAPACITY = 50
|
|
local MAX_STACK = 99
|
|
|
|
-- PlayersPCMenuData .PlayersPCMenuPointers strings, verbatim. .WhichPC picks
|
|
-- which rows a caller sees: PLAYERSPC_NORMAL ends on LOG OFF, PLAYERSPC_HOUSE
|
|
-- carries DECORATION and ends on TURN OFF.
|
|
local ENTRIES = {
|
|
{ id = "withdraw", label = "WITHDRAW ITEM" },
|
|
{ id = "deposit", label = "DEPOSIT ITEM" },
|
|
{ id = "toss", label = "TOSS ITEM" },
|
|
{ id = "mailbox", label = "MAIL BOX" },
|
|
}
|
|
local LOG_OFF = { id = "logoff", label = "LOG OFF" }
|
|
local DECORATION = { id = "decoration", label = "DECORATION" }
|
|
local TURN_OFF = { id = "turnoff", label = "TURN OFF" }
|
|
|
|
-- ui.pc.items identity: an unhooked build hands its own list back.
|
|
local function sameItems(_, items) return items end
|
|
|
|
-- PCItemsJoypad's ScrollingMenu is `db 4, 8 ; rows, columns`.
|
|
local VISIBLE_ROWS = 4
|
|
|
|
-- charmap.asm: the quantity glyph.
|
|
local TIMES = "\xc3\x97"
|
|
|
|
function ItemPcMenu:wantsFillScale() return true end
|
|
function ItemPcMenu:drawsWidescreen() return true end
|
|
|
|
-- opts: save, items (items.lua), house (PLAYERSPC_HOUSE: boot text,
|
|
-- DECORATION row, TURN OFF), events (wEventFlags, for the decoration
|
|
-- menu), onClose(changedDecorations)
|
|
function ItemPcMenu.new(game, opts)
|
|
opts = opts or {}
|
|
local self = setmetatable({}, ItemPcMenu)
|
|
self.game = game
|
|
self.save = opts.save or (game and game.save)
|
|
self.items = opts.items or (game and game.data and game.data.items)
|
|
self.data = game and game.data
|
|
self.onClose = opts.onClose
|
|
self.house = opts.house and true or false
|
|
self.events = opts.events
|
|
-- wChangedDecorations, carried out so `special PlayersHousePC` can answer
|
|
-- TRUE and PlayersHousePCScript can take its `.Warp` arm.
|
|
self.changedDecorations = false
|
|
if self.save then self.save.pcItems = self.save.pcItems or {} end
|
|
local entries = {}
|
|
for i, entry in ipairs(ENTRIES) do entries[i] = entry end
|
|
if self.house then entries[#entries + 1] = DECORATION end
|
|
-- Same hook name and same (game, items) payload as the Gen 1 PC menu
|
|
-- (src/world/OverworldController.lua openPC), so one mod source can add a
|
|
-- row to both generations' PCs. Unguarded, like that site: the list is
|
|
-- built once per session, not per frame. A hook that answers with anything
|
|
-- but a table is degraded to the vanilla list.
|
|
local hooked = Runtime.call("ui.pc.items", sameItems, game, entries)
|
|
if type(hooked) == "table" then
|
|
entries = hooked
|
|
else
|
|
Logger.error("ui.pc.items returned %s; keeping the vanilla items",
|
|
type(hooked))
|
|
end
|
|
-- LOG OFF / TURN OFF is appended AFTER the hook, exactly as the Gen 1 site
|
|
-- appends LOG OFF: a mod cannot orphan the way out of the PC.
|
|
entries[#entries + 1] = self.house and TURN_OFF or LOG_OFF
|
|
self.entries = entries
|
|
self.index = 1
|
|
self.phase = "menu"
|
|
self.rows = {}
|
|
self.listIndex = 1
|
|
self.scroll = 0
|
|
self.message = nil
|
|
self.qtyState = nil
|
|
self.confirm = nil
|
|
if self.house then
|
|
-- _PlayersHousePC: PC_PlayBootSound, then PlayersPCTurnOnText.
|
|
self:playSfx("Sfx_BootPc")
|
|
self:say({ { "{PLAYER} turned on", "the PC." } })
|
|
end
|
|
return self
|
|
end
|
|
|
|
function ItemPcMenu:playSfx(name)
|
|
local data = self.data
|
|
local sfx = data and data.audio and data.audio.sfx
|
|
if sfx and sfx[Sound.resolve(data, name)] then
|
|
Sound.play(data, name)
|
|
end
|
|
end
|
|
|
|
function ItemPcMenu:playerName()
|
|
local player = self.save and self.save.player
|
|
return (player and player.name) or "GOLD"
|
|
end
|
|
|
|
-- A queue of text pages, each a list of lines; A or B turns them, and the last
|
|
-- one runs onDone. The item PC's messages never log off by themselves, which
|
|
-- is _PlayersPC's `.loop`: a refusal drops back into the same menu.
|
|
function ItemPcMenu:say(pages, onDone)
|
|
self.message = { pages = pages, page = 1, onDone = onDone }
|
|
end
|
|
|
|
function ItemPcMenu:close()
|
|
-- _PlayersHousePC plays PC_PlayShutdownSound only on the unchanged arm;
|
|
-- `.changed_deco_tiles` leaves for the map reload without it.
|
|
if self.house and not self.changedDecorations then
|
|
self:playSfx("Sfx_ShutDownPc")
|
|
end
|
|
if self.onClose then self.onClose(self.changedDecorations) end
|
|
end
|
|
|
|
-- ---------------------------------------------------------------- the items
|
|
|
|
function ItemPcMenu:def(id)
|
|
return self.items and self.items[id]
|
|
end
|
|
|
|
-- _CheckTossableItem: KEY ITEMs and HMs answer non-zero. The extractor
|
|
-- carries that as `canToss = false`; an id with no attributes row counts as
|
|
-- tossable, the way the PACK's sell gate treats it.
|
|
function ItemPcMenu:cantToss(id)
|
|
local def = self:def(id)
|
|
return def ~= nil and def.canToss == false
|
|
end
|
|
|
|
function ItemPcMenu:rebuild()
|
|
local pc = (self.save and self.save.pcItems) or {}
|
|
local rows = {}
|
|
for id, count in pairs(pc) do
|
|
if (count or 0) > 0 then
|
|
local def = self:def(id)
|
|
rows[#rows + 1] = {
|
|
id = id, count = count,
|
|
name = (def and def.name) or id,
|
|
index = def and def.index or math.huge,
|
|
}
|
|
end
|
|
end
|
|
-- wPCItems keeps acquisition order; without that recorded, item id order is
|
|
-- the stable choice, the same sort the PACK uses.
|
|
table.sort(rows, function(a, b)
|
|
if a.index ~= b.index then return a.index < b.index end
|
|
return a.id < b.id
|
|
end)
|
|
self.rows = rows
|
|
if self.listIndex > #rows + 1 then self.listIndex = #rows + 1 end
|
|
if self.listIndex < 1 then self.listIndex = 1 end
|
|
self:ensureVisible()
|
|
end
|
|
|
|
function ItemPcMenu:listTotal()
|
|
return #self.rows + 1 -- CANCEL
|
|
end
|
|
|
|
function ItemPcMenu:ensureVisible()
|
|
if self.listIndex <= self.scroll then
|
|
self.scroll = self.listIndex - 1
|
|
elseif self.listIndex > self.scroll + VISIBLE_ROWS then
|
|
self.scroll = self.listIndex - VISIBLE_ROWS
|
|
end
|
|
self.scroll = math.max(0, math.min(self.scroll,
|
|
math.max(0, self:listTotal() - VISIBLE_ROWS)))
|
|
end
|
|
|
|
-- ReceiveItem over wPCItems: a new id needs one of the fifty stacks, a grown
|
|
-- one may not pass 99. False is the no-carry the deposit turns into
|
|
-- _PlayersPCNoRoomDepositText.
|
|
function ItemPcMenu:pcAdd(id, qty)
|
|
local pc = self.save.pcItems
|
|
local held = pc[id] or 0
|
|
if held == 0 then
|
|
local stacks = 0
|
|
for _, count in pairs(pc) do
|
|
if (count or 0) > 0 then stacks = stacks + 1 end
|
|
end
|
|
if stacks >= PC_ITEM_CAPACITY then return false end
|
|
end
|
|
if held + qty > MAX_STACK then return false end
|
|
pc[id] = held + qty
|
|
return true
|
|
end
|
|
|
|
function ItemPcMenu:pcRemove(id, qty)
|
|
local pc = self.save.pcItems
|
|
local held = (pc[id] or 0) - qty
|
|
pc[id] = held > 0 and held or nil
|
|
end
|
|
|
|
-- HasNoItems (engine/pokemon/mon_menu.asm): every pocket, TM/HMs included --
|
|
-- which the flat inventory answers in one walk. Badges share the table but
|
|
-- are not bag items.
|
|
local function bagIsEmpty(save)
|
|
for id, count in pairs((save and save.inventory) or {}) do
|
|
if (count or 0) > 0 and not Bag.isBadge(id) then return false end
|
|
end
|
|
return true
|
|
end
|
|
|
|
-- BuySellToss_InterpretJoypad (engine/items/buy_sell_toss.asm): up and down
|
|
-- wrap through the ends, left and right step by ten and clamp.
|
|
local function qtyStep(qty, max, delta)
|
|
local n = qty + delta
|
|
if delta == 1 then
|
|
if n > max then n = 1 end
|
|
elseif delta == -1 then
|
|
if n < 1 then n = max end
|
|
elseif delta > 0 then
|
|
if n > max then n = max end
|
|
else
|
|
if n <= 0 then n = 1 end
|
|
end
|
|
return n
|
|
end
|
|
|
|
-- prompt is the two lines under the selector; onAccept(qty) commits.
|
|
function ItemPcMenu:askQuantity(max, prompt, onAccept)
|
|
self.qtyState = { qty = 1, max = max, prompt = prompt, onAccept = onAccept }
|
|
end
|
|
|
|
-- ------------------------------------------------------------ the three rows
|
|
|
|
function ItemPcMenu:withdraw(row, qty)
|
|
-- PlayerWithdrawItemMenu .withdraw: ReceiveItem into the bag first; only a
|
|
-- carry tosses the stack out of the PC.
|
|
if not Bag.add(self.save, row.id, qty, self.data) then
|
|
self:say({ { "There's no room", "for more items." } })
|
|
return
|
|
end
|
|
self:pcRemove(row.id, qty)
|
|
self:rebuild()
|
|
self:say({ { ("Withdrew %d"):format(qty), row.name .. "(S)." } })
|
|
end
|
|
|
|
function ItemPcMenu:chooseWithdraw()
|
|
local row = self.rows[self.listIndex]
|
|
if not row then
|
|
self.phase = "menu"
|
|
return
|
|
end
|
|
-- .Submenu: an item without a quantity attribute (a KEY ITEM in the PC) is
|
|
-- always x1; everything else asks _PlayersPCHowManyWithdrawText.
|
|
if self:cantToss(row.id) then
|
|
self:withdraw(row, 1)
|
|
return
|
|
end
|
|
self:askQuantity(row.count,
|
|
{ "How many do you", "want to withdraw?" },
|
|
function(qty) self:withdraw(row, qty) end)
|
|
end
|
|
|
|
function ItemPcMenu:deposit(id, name, qty)
|
|
if not self:pcAdd(id, qty) then
|
|
self:say({ { "There's no room to", "store items." } })
|
|
return
|
|
end
|
|
Bag.remove(self.save, id, qty)
|
|
if self.pack then self.pack:rebuild() end
|
|
self:say({ { ("Deposited %d"):format(qty), name .. "(S)." } })
|
|
end
|
|
|
|
function ItemPcMenu:enterDeposit()
|
|
-- .CheckItemsInBag: an empty bag never opens the PACK.
|
|
if bagIsEmpty(self.save) then
|
|
self:say({ { "No items here!" } })
|
|
return
|
|
end
|
|
self.phase = "deposit"
|
|
-- DepositSellPack: the PACK as a chooser, held and drawn by this screen the
|
|
-- way the mart holds its sell PACK. `world = {}` keeps field items inert.
|
|
self.pack = Screens.build(self.game, "Gen2PackMenu", {
|
|
save = self.save,
|
|
items = self.items,
|
|
world = {},
|
|
onChoose = function(id, count) self:offerToDeposit(id, count) end,
|
|
onClose = function() self:leaveDeposit() end,
|
|
})
|
|
end
|
|
|
|
function ItemPcMenu:leaveDeposit()
|
|
self.pack = nil
|
|
self.phase = "menu"
|
|
end
|
|
|
|
function ItemPcMenu:offerToDeposit(id, count)
|
|
-- .TryDepositItem's `.no_toss` arm is a bare ret: a KEY ITEM or HM stays in
|
|
-- the bag with no message at all.
|
|
if self:cantToss(id) then return end
|
|
if (count or 0) < 1 then return end
|
|
local def = self:def(id)
|
|
local name = (def and def.name) or id
|
|
self:askQuantity(count,
|
|
{ "How many do you", "want to deposit?" },
|
|
function(qty) self:deposit(id, name, qty) end)
|
|
end
|
|
|
|
function ItemPcMenu:chooseToss()
|
|
local row = self.rows[self.listIndex]
|
|
if not row then
|
|
self.phase = "menu"
|
|
return
|
|
end
|
|
-- TossItemFromPC .key_item -> .CantToss.
|
|
if self:cantToss(row.id) then
|
|
self:say({ { "That's too impor-", "tant to toss out!" } })
|
|
return
|
|
end
|
|
self:askQuantity(row.count,
|
|
{ "Toss out how many", row.name .. "(S)?" },
|
|
function(qty)
|
|
-- .ItemsThrowAwayText's yes/no sits between the count and the toss.
|
|
self.confirm = {
|
|
prompt = { ("Throw away %d"):format(qty), row.name .. "(S)?" },
|
|
choice = 1,
|
|
onYes = function()
|
|
self:pcRemove(row.id, qty)
|
|
self:rebuild()
|
|
self:say({ { "Discarded", row.name .. "(S)." } })
|
|
end,
|
|
}
|
|
end)
|
|
end
|
|
|
|
-- ------------------------------------------------------------------ the menu
|
|
|
|
function ItemPcMenu:choose()
|
|
local entry = self.entries[self.index]
|
|
if not entry then return end
|
|
local game = self.game
|
|
if entry.id == "withdraw" or entry.id == "toss" then
|
|
self.phase = entry.id
|
|
self.listIndex = 1
|
|
self.scroll = 0
|
|
self:rebuild()
|
|
return
|
|
end
|
|
if entry.id == "deposit" then
|
|
self:enterDeposit()
|
|
return
|
|
end
|
|
if entry.id == "mailbox" then
|
|
if not (game and game.stack) then return end
|
|
Screens.push(game, "Gen2MailboxMenu", {
|
|
save = self.save,
|
|
onClose = function() game.stack:pop() end,
|
|
})
|
|
return
|
|
end
|
|
if entry.id == "decoration" then
|
|
if not (game and game.stack) then return end
|
|
Screens.push(game, "Gen2DecorationMenu", {
|
|
save = self.save,
|
|
events = self.events,
|
|
onDone = function(changed)
|
|
self.changedDecorations = self.changedDecorations or changed or false
|
|
game.stack:pop()
|
|
end,
|
|
})
|
|
return
|
|
end
|
|
-- logoff / turnoff: PlayerLogOffMenu serves both rows.
|
|
self:close()
|
|
end
|
|
|
|
-- ------------------------------------------------------------------- update
|
|
|
|
function ItemPcMenu:update(_dt)
|
|
local input = self.game and self.game.input
|
|
if not input then return end
|
|
|
|
if self.message then
|
|
if input:wasPressed("a") or input:wasPressed("b") then
|
|
local m = self.message
|
|
if m.page < #m.pages then
|
|
m.page = m.page + 1
|
|
return
|
|
end
|
|
self.message = nil
|
|
if m.onDone then m.onDone() end
|
|
end
|
|
return
|
|
end
|
|
|
|
if self.qtyState then
|
|
local q = self.qtyState
|
|
if input:wasPressed("up") then
|
|
q.qty = qtyStep(q.qty, q.max, 1)
|
|
elseif input:wasPressed("down") then
|
|
q.qty = qtyStep(q.qty, q.max, -1)
|
|
elseif input:wasPressed("right") then
|
|
q.qty = qtyStep(q.qty, q.max, 10)
|
|
elseif input:wasPressed("left") then
|
|
q.qty = qtyStep(q.qty, q.max, -10)
|
|
elseif input:wasPressed("b") then
|
|
self.qtyState = nil
|
|
elseif input:wasPressed("a") then
|
|
self.qtyState = nil
|
|
q.onAccept(q.qty)
|
|
end
|
|
return
|
|
end
|
|
|
|
if self.confirm then
|
|
local c = self.confirm
|
|
if input:wasPressed("up") or input:wasPressed("down") then
|
|
c.choice = c.choice == 1 and 2 or 1
|
|
elseif input:wasPressed("b") then
|
|
self.confirm = nil
|
|
if c.onNo then c.onNo() end
|
|
elseif input:wasPressed("a") then
|
|
self.confirm = nil
|
|
if c.choice == 1 then
|
|
if c.onYes then c.onYes() end
|
|
elseif c.onNo then
|
|
c.onNo()
|
|
end
|
|
end
|
|
return
|
|
end
|
|
|
|
if self.phase == "deposit" then
|
|
if self.pack then
|
|
self.pack:update(_dt)
|
|
else
|
|
self.phase = "menu"
|
|
end
|
|
return
|
|
end
|
|
|
|
if self.phase == "withdraw" or self.phase == "toss" then
|
|
if input:wasPressed("up") then
|
|
self.listIndex = self.listIndex > 1 and self.listIndex - 1
|
|
or self:listTotal()
|
|
self:ensureVisible()
|
|
elseif input:wasPressed("down") then
|
|
self.listIndex = self.listIndex < self:listTotal() and self.listIndex + 1
|
|
or 1
|
|
self:ensureVisible()
|
|
elseif input:wasPressed("b") then
|
|
self.phase = "menu"
|
|
elseif input:wasPressed("a") then
|
|
if self.phase == "withdraw" then
|
|
self:chooseWithdraw()
|
|
else
|
|
self:chooseToss()
|
|
end
|
|
end
|
|
return
|
|
end
|
|
|
|
if input:wasPressed("up") then
|
|
self.index = self.index > 1 and self.index - 1 or #self.entries
|
|
elseif input:wasPressed("down") then
|
|
self.index = self.index < #self.entries and self.index + 1 or 1
|
|
elseif input:wasPressed("a") then
|
|
self:choose()
|
|
elseif input:wasPressed("b") then
|
|
-- DoNthMenu's carry is `.turn_off`.
|
|
self:close()
|
|
end
|
|
end
|
|
|
|
-- --------------------------------------------------------------------- draw
|
|
|
|
function ItemPcMenu:drawBottomLines(lines)
|
|
Chrome.box(0, 12, 20, 6)
|
|
if not lines then return end
|
|
local name = self:playerName()
|
|
local startY = #lines >= 3 and 13 or 14
|
|
for i, line in ipairs(lines) do
|
|
Chrome.print((line:gsub("{PLAYER}", name)), 1, startY + (i - 1) * 2)
|
|
end
|
|
end
|
|
|
|
function ItemPcMenu:drawList()
|
|
Chrome.box(0, 0, 20, 12)
|
|
for row = 1, VISIBLE_ROWS do
|
|
local i = row + self.scroll
|
|
local ty = row * 2
|
|
if i <= #self.rows then
|
|
local entry = self.rows[i]
|
|
if i == self.listIndex then Chrome.cursor(5, ty) end
|
|
Chrome.print(entry.name, 6, ty)
|
|
-- PlaceMenuItemQuantity (engine/menus/menu_2.asm:24): the xNN is the
|
|
-- entry's second line, right-aligned in a blank-padded 2-digit field.
|
|
Chrome.print(TIMES .. Chrome.number(entry.count, 2), 7, ty + 1)
|
|
elseif i == self:listTotal() then
|
|
if i == self.listIndex then Chrome.cursor(5, ty) end
|
|
Chrome.print("CANCEL", 6, ty)
|
|
end
|
|
end
|
|
-- UpdateItemDescription under the list.
|
|
local row = self.rows[self.listIndex]
|
|
local def = row and self:def(row.id)
|
|
local description = def and def.description
|
|
if description then
|
|
local first, second = description:match("^(.-)<NEXT>(.*)$")
|
|
if not first then first, second = description:match("^(.-)\n(.*)$") end
|
|
Chrome.box(0, 12, 20, 6)
|
|
Chrome.print(first or description, 1, 14)
|
|
if second then Chrome.print(second, 1, 16) end
|
|
else
|
|
Chrome.box(0, 12, 20, 6)
|
|
end
|
|
end
|
|
|
|
function ItemPcMenu:drawPanel()
|
|
Chrome.clear()
|
|
|
|
if self.phase == "deposit" and self.pack then
|
|
self.pack:drawPanel()
|
|
elseif self.phase == "withdraw" or self.phase == "toss" then
|
|
self:drawList()
|
|
else
|
|
-- _PlayersPCAskWhatDoText, printed under the list the whole time. The
|
|
-- box goes down first: the menu window overlays it where the house's
|
|
-- six-row list runs past row 12, the way the cart's windows stack.
|
|
self:drawBottomLines({ "What do you want", "to do?" })
|
|
-- PlayersPCMenuData is menu_coords 0, 0, 15, 12; the house list is one
|
|
-- row taller than that box, so size it to the entries.
|
|
Chrome.box(0, 0, 16, math.max(12, #self.entries * 2 + 2))
|
|
for i, entry in ipairs(self.entries) do
|
|
local ty = i * 2
|
|
if i == self.index then Chrome.cursor(1, ty) end
|
|
Chrome.print(entry.label, 2, ty)
|
|
end
|
|
end
|
|
|
|
if self.qtyState then
|
|
local q = self.qtyState
|
|
self:drawBottomLines(q.prompt)
|
|
Chrome.box(7, 15, 13, 3)
|
|
Chrome.print(TIMES, 8, 16)
|
|
Chrome.print(Chrome.number(q.qty, 2, true), 9, 16)
|
|
elseif self.confirm then
|
|
self:drawBottomLines(self.confirm.prompt)
|
|
Chrome.box(14, 7, 6, 5)
|
|
Chrome.print("YES", 16, 8)
|
|
Chrome.print("NO", 16, 10)
|
|
Chrome.cursor(15, self.confirm.choice == 1 and 8 or 10)
|
|
elseif self.message then
|
|
self:drawBottomLines(self.message.pages[self.message.page])
|
|
end
|
|
|
|
love.graphics.setColor(1, 1, 1, 1)
|
|
end
|
|
|
|
function ItemPcMenu:draw()
|
|
self:drawPanel()
|
|
end
|
|
|
|
function ItemPcMenu:drawWidescreen(winW, winH)
|
|
local G = love.graphics
|
|
G.setColor(1, 1, 1, 1)
|
|
G.rectangle("fill", 0, 0, winW, winH)
|
|
local scale = Chrome.fitScale(winW, winH)
|
|
G.push()
|
|
G.translate(Chrome.fitOrigin(winW, winH, scale))
|
|
G.scale(scale, scale)
|
|
self:drawPanel()
|
|
G.pop()
|
|
end
|
|
|
|
ItemPcMenu.ENTRIES = ENTRIES
|
|
ItemPcMenu.PC_ITEM_CAPACITY = PC_ITEM_CAPACITY
|
|
|
|
return ItemPcMenu
|