dan game: soul gauge drawn as on the cabinet #66
No files matched your search
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -100,5 +100,25 @@
|
||||
"tamashii_fire": {
|
||||
"x": 1698,
|
||||
"y": 34
|
||||
},
|
||||
"track_red": {
|
||||
"x": 738,
|
||||
"y": 242
|
||||
},
|
||||
"1p_lamp": {
|
||||
"x": 738,
|
||||
"y": 242
|
||||
},
|
||||
"2p_lamp": {
|
||||
"x": 738,
|
||||
"y": 242
|
||||
},
|
||||
"lamp_clear": {
|
||||
"x": 738,
|
||||
"y": 242
|
||||
},
|
||||
"bar_fade_clear": {
|
||||
"x": 733,
|
||||
"y": 241
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -155,14 +155,18 @@ function DanBackground:draw_back()
|
||||
self.chibi:draw()
|
||||
end
|
||||
|
||||
-- dan soul gauge separator overlay (static, drawn at a hardcoded fade).
|
||||
-- the soul gauge's strip the lane covers (the cabinet draws the gauge over the lane), then
|
||||
-- its threshold marker, on top of everything
|
||||
local LANE_TOP, GAUGE_BOTTOM = 276, 288
|
||||
function DanBackground:draw_fore()
|
||||
if not self._gauge_overlay then
|
||||
self._gauge_overlay = tex.get_texture("game/gauge_dan/overlay") or 0
|
||||
end
|
||||
if self._gauge_overlay ~= 0 then
|
||||
tex.draw_texture(self._gauge_overlay, { fade = 0.15 })
|
||||
local redraw = _G.g_dan_gauge_redraw
|
||||
if redraw then
|
||||
tex.begin_scissor(0, LANE_TOP, tex.get_screen_width(), GAUGE_BOTTOM - LANE_TOP)
|
||||
local ok, err = pcall(redraw)
|
||||
tex.end_scissor()
|
||||
if not ok then error(err, 0) end
|
||||
end
|
||||
self.dan_info:draw_marker()
|
||||
end
|
||||
|
||||
-- dan condition plate, drawn in the gauge's own layer.
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
-- 段位道場 exam-panel extras only Lua can draw: the soul-gauge pass-threshold
|
||||
-- callout plate + captions, anchored on the gauge's own 50-cell grid.
|
||||
-- callout plate + captions and the white threshold marker on the threshold cell, anchored
|
||||
-- on the gauge's own 50-cell grid. It also hands the threshold (in cells) to the gauge script
|
||||
-- (g_dan_gauge_border), which colours the track by it.
|
||||
local M = {}
|
||||
M.__index = M
|
||||
|
||||
@@ -11,23 +13,30 @@ local LABEL_SIZE = 30 -- arcade MS 明朝 36; ours reads
|
||||
local WHITE = { 255, 255, 255, 255 }
|
||||
local BLACK = { 0, 0, 0, 255 }
|
||||
|
||||
local PLATE_W, PLATE_H = 586, 60
|
||||
local PLATE_W, PLATE_H = 586, 60 -- the plate's grey body; the art adds a 9 px margin
|
||||
local PLATE_ART_PAD = 9 -- (the pill's top/left edge and the drop shadow)
|
||||
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 VALUE_CY = 35 -- its ink centre y, plate-local
|
||||
local NAME_SIZE = 26 -- arcade id 142
|
||||
local VALUE_SIZE = 36 -- arcade id 141
|
||||
|
||||
-- the threshold marker (gauge_border_cell): its white inside (x 7, y 7 in the art) lands on
|
||||
-- the threshold cell's left edge + 1, from y 238, as the cabinet's border_N
|
||||
local MARKER_INNER_X, MARKER_INNER_Y = 7, 7
|
||||
local MARKER_Y = 238
|
||||
|
||||
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)
|
||||
name_label = nil, plate = nil, plate_tried = false,
|
||||
marker = nil, marker_tried = false }, M)
|
||||
end
|
||||
|
||||
function M:plate_id()
|
||||
@@ -38,9 +47,12 @@ function M:plate_id()
|
||||
return self.plate
|
||||
end
|
||||
|
||||
-- Called from Background:handle_dan.
|
||||
function M:handle(state)
|
||||
self.state = state
|
||||
function M:marker_id()
|
||||
if not self.marker_tried then
|
||||
self.marker_tried = true
|
||||
self.marker = tex.get_texture("game/dan_info/gauge_border_cell")
|
||||
end
|
||||
return self.marker
|
||||
end
|
||||
|
||||
local function gauge_exam(state)
|
||||
@@ -51,6 +63,14 @@ local function gauge_exam(state)
|
||||
return nil
|
||||
end
|
||||
|
||||
-- Called from Background:handle_dan.
|
||||
function M:handle(state)
|
||||
self.state = state
|
||||
local ex = gauge_exam(state)
|
||||
_G.g_dan_gauge_border = (ex and ex.red and ex.red > 0)
|
||||
and math.max(1, math.min(CELL_COUNT, math.floor(ex.red / 2))) or nil
|
||||
end
|
||||
|
||||
-- Called from Background:draw_fore(), i.e. after the whole GAME_DAN HUD.
|
||||
function M:draw()
|
||||
local st = self.state
|
||||
@@ -84,7 +104,7 @@ function M:draw()
|
||||
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 })
|
||||
tex.draw_texture(pid, { x = px - PLATE_ART_PAD, y = py - PLATE_ART_PAD })
|
||||
end
|
||||
|
||||
-- fail soft: with no plate art the two captions still draw, at the same places
|
||||
@@ -103,4 +123,16 @@ function M:draw()
|
||||
end
|
||||
end
|
||||
|
||||
-- The threshold marker, drawn over the lane's frame as on the cabinet (it reaches below the
|
||||
-- gauge), so from Background:draw_fore() rather than with the plate in the gauge layer.
|
||||
function M:draw_marker()
|
||||
local ex = gauge_exam(self.state)
|
||||
if not ex or not ex.red or ex.red <= 0 then return end
|
||||
local n = math.max(1, math.min(CELL_COUNT, math.floor(ex.red / 2)))
|
||||
local mid = self:marker_id()
|
||||
if not mid then return end
|
||||
local cell_left = GAUGE_X0 + CELL_PITCH * (n - 1)
|
||||
tex.draw_texture(mid, { x = cell_left + 1 - MARKER_INNER_X, y = MARKER_Y - MARKER_INNER_Y })
|
||||
end
|
||||
|
||||
return M
|
||||
+88
-2
@@ -4,6 +4,7 @@
|
||||
-- length-1 (at length it left a dark gap cell before it)
|
||||
-- * the clear mark sits gauge_clear_mark_offset cells (skin_config: 1, the cell edge) before
|
||||
-- the exact clear fraction, not the parent's 87/60
|
||||
-- The dan gauge is drawn as the cabinet's tamashii_gauge (see draw_dan below).
|
||||
-- Everything else is the parent's file, loaded from its own copy.
|
||||
|
||||
-- the parent skin's copy of a script: the second match on package.path (the first is this file)
|
||||
@@ -23,10 +24,21 @@ assert(load_parent("game/gauge"), "game/gauge: the parent skin has no gauge scri
|
||||
local function clamp(v, lo, hi) return math.max(lo, math.min(hi, v)) end
|
||||
|
||||
local parent_new = Gauge.new
|
||||
function Gauge.new(...)
|
||||
local self = parent_new(...)
|
||||
function Gauge.new(is_2p, dan, string_diff, opts)
|
||||
local self = parent_new(is_2p, dan, string_diff, opts)
|
||||
local mark = tex.get_skin_config("gauge_clear_mark_offset")
|
||||
self.clear_mark_offset = mark and mark.x
|
||||
if dan then
|
||||
local screen = (opts and opts.screen) or "game"
|
||||
local p = (opts and opts.player_str and (opts.player_str .. "_")) or (is_2p and "2p_" or "1p_")
|
||||
local function t(name) return tex.get_texture(screen .. "/gauge_dan/" .. name) end
|
||||
self.cab = {
|
||||
track_red = t("track_red"),
|
||||
lamp = t(p .. "lamp"),
|
||||
lamp_clear = t("lamp_clear"),
|
||||
fade_clear = t("bar_fade_clear"),
|
||||
}
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
@@ -101,3 +113,77 @@ function Gauge:render(y, mirror, idx, points, previous_points, max_points, clear
|
||||
self:blit(self.tamashii_dark, nil, nil, y, nil, nil, nil, idx)
|
||||
end
|
||||
end
|
||||
|
||||
-- The dan gauge as the cabinet's tamashii_gauge draws it: the gold track (border), the red
|
||||
-- track (track_red, gauge_bg) up to the threshold, the lit cells as one lamp stretched 21 px
|
||||
-- per cell (lamp_clear, yellow, once the gauge reaches the threshold), the glow on a newly lit
|
||||
-- cell, the cell separators at the cabinet's 103/255, then 魂: grey, white once cleared, and
|
||||
-- in flames at full. The threshold comes from the dan exam (background dan_info sets
|
||||
-- g_dan_gauge_border, in cells); without it, or without the cabinet pieces, the parent draws.
|
||||
local CAB_CELL = 21
|
||||
local CAB_TRACK = 20.88 -- gauge_bg: 160 px x 0.1305 per cell
|
||||
local CAB_SEPARATOR = 103 / 255
|
||||
local parent_draw_dan = Gauge.draw_dan
|
||||
|
||||
-- The cabinet draws the gauge over the lane; the engine draws the lane after it, so its top
|
||||
-- edge (y 276, 184 px x 1.5) hides the cells' last rows. The gauge leaves a redraw for the
|
||||
-- dan background's draw_fore (g_dan_gauge_redraw), which repeats it clipped to that strip.
|
||||
local function draw_cab(self, border, points, previous_points, max_points, is_rainbow,
|
||||
anim_active, anim_alpha, rainbow_fade, rainbow_frac, fire_frame)
|
||||
local cab = self.cab
|
||||
local function layer(t, x, x2, fade, frame, scale, center)
|
||||
if t then
|
||||
tex.draw_texture(t, { x = x, x2 = x2, fade = fade, frame = frame, scale = scale, center = center })
|
||||
end
|
||||
end
|
||||
|
||||
local length, solid, alpha, show_up = self:cells(points, previous_points, max_points, anim_active, anim_alpha)
|
||||
local clear = length >= border
|
||||
|
||||
layer(self.border)
|
||||
if border > 0 then layer(cab.track_red, nil, CAB_TRACK * border - 160) end
|
||||
if solid > 0 then layer(clear and cab.lamp_clear or cab.lamp, nil, CAB_CELL * solid - 8) end
|
||||
|
||||
if is_rainbow and rainbow_fade >= 0 then
|
||||
local frame_a = math.floor(rainbow_frac) % 8
|
||||
local frame_b = (frame_a + 1) % 8
|
||||
local f = rainbow_frac - math.floor(rainbow_frac)
|
||||
layer(self.rainbow, nil, nil, rainbow_fade, frame_a)
|
||||
layer(self.rainbow, nil, nil, rainbow_fade * f, frame_b)
|
||||
end
|
||||
|
||||
if show_up and length > 0 then
|
||||
layer(clear and cab.fade_clear or self.bar_fade, (length - 1) * CAB_CELL, nil, alpha)
|
||||
end
|
||||
|
||||
layer(self.overlay, nil, nil, CAB_SEPARATOR)
|
||||
|
||||
if is_rainbow then
|
||||
layer(self.fire, nil, nil, nil, fire_frame, 0.75, true)
|
||||
layer(self.tamashii)
|
||||
if fire_frame == 0 or fire_frame == 1 or fire_frame == 4 or fire_frame == 5 then
|
||||
layer(self.tamashii_overlay, nil, nil, 0.5)
|
||||
end
|
||||
elseif clear then
|
||||
layer(self.tamashii)
|
||||
else
|
||||
layer(self.tamashii_dark)
|
||||
end
|
||||
end
|
||||
|
||||
function Gauge:draw_dan(points, previous_points, max_points, is_rainbow,
|
||||
anim_active, anim_alpha, rainbow_fade, rainbow_frac, fire_frame)
|
||||
local cab = self.cab
|
||||
local border = _G.g_dan_gauge_border
|
||||
if not (cab and cab.track_red and cab.lamp and cab.lamp_clear and border) then
|
||||
_G.g_dan_gauge_redraw = nil
|
||||
return parent_draw_dan(self, points, previous_points, max_points, is_rainbow,
|
||||
anim_active, anim_alpha, rainbow_fade, rainbow_frac, fire_frame)
|
||||
end
|
||||
draw_cab(self, border, points, previous_points, max_points, is_rainbow,
|
||||
anim_active, anim_alpha, rainbow_fade, rainbow_frac, fire_frame)
|
||||
_G.g_dan_gauge_redraw = function()
|
||||
draw_cab(self, border, points, previous_points, max_points, is_rainbow,
|
||||
anim_active, anim_alpha, rainbow_fade, rainbow_frac, fire_frame)
|
||||
end
|
||||
end
|
||||
Reference in new issue
Block a user