107 lines
4.1 KiB
Lua
107 lines
4.1 KiB
Lua
-- 段位道場 exam-panel extras only Lua can draw: the soul-gauge pass-threshold
|
|
-- callout plate + captions, anchored on the gauge's own 50-cell grid.
|
|
local M = {}
|
|
M.__index = M
|
|
|
|
local GAUGE_Y = 248
|
|
local GAUGE_X0 = 738 -- cell 1 starts here
|
|
local CELL_PITCH = 21
|
|
local CELL_COUNT = 50
|
|
local LABEL_SIZE = 30 -- arcade MS 明朝 36; ours reads heavier
|
|
local WHITE = { 255, 255, 255, 255 }
|
|
local BLACK = { 0, 0, 0, 255 }
|
|
|
|
local PLATE_W, PLATE_H = 586, 60
|
|
local PLATE_GAP = 12 -- px between the plate's bottom and the bar top
|
|
local PLATE_OVERHANG = 24 -- px the plate extends PAST the threshold
|
|
|
|
local PILL_CX, PILL_CY = 150, 20 -- 魂ゲージ ink centre, plate-local
|
|
local VALUE_RIGHT = 532 -- 100%以上 is RIGHT-aligned to this
|
|
local VALUE_CY = 22 -- its ink centre y, plate-local
|
|
local NAME_SIZE = 26 -- arcade id 142
|
|
local VALUE_SIZE = 36 -- arcade id 141
|
|
|
|
local CAP_FILL = { 255, 255, 255, 255 }
|
|
local CAP_OUTLINE = { 80, 60, 45, 255 } -- #503C2D
|
|
local VALUE_OUTLINE = { 0, 0, 0, 255 }
|
|
|
|
function M.new()
|
|
return setmetatable({ state = nil, label = nil, label_for = nil,
|
|
name_label = nil, plate = nil, plate_tried = false }, M)
|
|
end
|
|
|
|
function M:plate_id()
|
|
if not self.plate_tried then
|
|
self.plate_tried = true
|
|
self.plate = tex.get_texture("game/dan_info/gauge_border_plate")
|
|
end
|
|
return self.plate
|
|
end
|
|
|
|
-- Called from Background:handle_dan.
|
|
function M:handle(state)
|
|
self.state = state
|
|
end
|
|
|
|
local function gauge_exam(state)
|
|
if not state or not state.exams then return nil end
|
|
for _, e in ipairs(state.exams) do
|
|
if e.type == "gauge" then return e end
|
|
end
|
|
return nil
|
|
end
|
|
|
|
-- Called from Background:draw_fore(), i.e. after the whole GAME_DAN HUD.
|
|
function M:draw()
|
|
local st = self.state
|
|
if not st then return end
|
|
local ex = gauge_exam(st)
|
|
if not ex or not ex.red or ex.red <= 0 then return end
|
|
|
|
-- the threshold, on the gauge's own 50-cell grid (2 % quantised)
|
|
local pct = ex.red
|
|
local n = math.floor(pct / 2)
|
|
if n < 1 then n = 1 end -- border_0 == border_1 on the cabinet
|
|
if n > CELL_COUNT then n = CELL_COUNT end -- dan.json may say >100 %; the cabinet cannot
|
|
local x = GAUGE_X0 + CELL_PITCH * n - CELL_PITCH / 2 - 1
|
|
|
|
if self.label_for ~= ex.red then
|
|
-- skin_config: dan_gauge_name (魂ゲージ) and dan_exam_text_gauge ("%s %以上", %% = %)
|
|
local fmt = tex.skin_text("dan_exam_text_gauge"):gsub("%%%%", "\1")
|
|
local caption = fmt:gsub("%%s", tostring(ex.red)):gsub("\1", "%%")
|
|
self.label = text.create_raw_text(caption,
|
|
VALUE_SIZE, CAP_FILL, VALUE_OUTLINE, false,
|
|
4.0 / tex.get_screen_scale())
|
|
self.name_label = text.create_raw_text(tex.skin_text("dan_gauge_name"),
|
|
NAME_SIZE, CAP_FILL, CAP_OUTLINE, false,
|
|
3.0 / tex.get_screen_scale())
|
|
self.label_for = ex.red
|
|
end
|
|
|
|
local pid = self:plate_id()
|
|
-- the plate overhangs the threshold by 24 px (the baked arrow lands ON it)
|
|
-- and floats PLATE_GAP above the bar
|
|
local px = math.max(0, math.floor(x - PLATE_W + PLATE_OVERHANG + 0.5))
|
|
local py = GAUGE_Y - PLATE_GAP - PLATE_H
|
|
if pid then
|
|
tex.draw_texture(pid, { x = px, y = py })
|
|
end
|
|
|
|
-- fail soft: with no plate art the two captions still draw, at the same places
|
|
if self.name_label then
|
|
self.name_label:draw({
|
|
x = math.floor(px + PILL_CX - self.name_label.width / 2 + 0.5),
|
|
y = math.floor(py + PILL_CY - self.name_label.height / 2 + 0.5),
|
|
})
|
|
end
|
|
if self.label then
|
|
-- tx_border is RIGHT-aligned; its box's right edge is plate-local 532
|
|
self.label:draw({
|
|
x = math.floor(px + VALUE_RIGHT - self.label.width + 0.5),
|
|
y = math.floor(py + VALUE_CY - self.label.height / 2 + 0.5),
|
|
})
|
|
end
|
|
end
|
|
|
|
return M
|