139 lines
5.7 KiB
Lua
139 lines
5.7 KiB
Lua
-- Player name/title plate (coin / band / dan variants), drawn over the player row.
|
|
local ENGINE_DEFAULT_TITLE = "Donder Debut!"
|
|
local TEXT_SPACING = 2.0
|
|
|
|
local DAN_FRAME_COUNT = 25
|
|
local TITLE_BG_FRAMES = 5 -- the 5 title backgrounds
|
|
|
|
-- name boxes, canvas px: {centre_x, centre_y, font}
|
|
local NAME_COIN = { 226, 53, 30 } -- 1p_coin / 2p_coin
|
|
local NAME_COIN_BARE = { 204, 53, 30 } -- no badge (PLAYER_NUM_ALL)
|
|
local NAME_BAND = { 226, 67.5, 24 } -- 1p / 1p_shougou
|
|
local NAME_BAND_DANI = { 261, 67.5, 24 } -- 1p_dani / 1p_shougou_dani
|
|
local NAME_BAND_BARE = { 204, 67.5, 24 } -- newentry
|
|
local NAME_BOX_W = 190 -- every text_name rect is 190 wide
|
|
local TITLE_CX, TITLE_CY, TITLE_FONT, TITLE_BOX_W = 226.5, 34.5, 22, 215
|
|
|
|
Nameplate = {}
|
|
Nameplate.__index = Nameplate
|
|
|
|
local PLAYER_NUM_AI = 5
|
|
local PLAYER_NUM_ALL = 0
|
|
|
|
function Nameplate.new(name, title, player_num, dan, is_gold, is_rainbow, title_bg)
|
|
local self = setmetatable({}, Nameplate)
|
|
|
|
self.player_num = player_num
|
|
self.dan = dan
|
|
self.is_gold = is_gold
|
|
self.is_rainbow = is_rainbow
|
|
self.title_bg = title_bg
|
|
|
|
-- "Donder Debut!" is the "no title set" default.
|
|
self.has_title = (title ~= nil and title ~= "" and title ~= ENGINE_DEFAULT_TITLE)
|
|
self.shadow = tex.get_texture("global/nameplate/shadow")
|
|
self.ai = tex.get_texture("global/nameplate/ai")
|
|
self.outline = tex.get_texture("global/nameplate/outline")
|
|
self.frame_top = tex.get_texture("global/nameplate/frame_top")
|
|
self.frame_top_rainbow = tex.get_texture("global/nameplate/frame_top_rainbow")
|
|
self.dan_emblem_bg = tex.get_texture("global/nameplate/dan_emblem_bg")
|
|
self.dan_emblem = tex.get_texture("global/nameplate/dan_emblem")
|
|
self.dan_emblem_gold = tex.get_texture("global/nameplate/dan_emblem_gold")
|
|
|
|
-- clamp dan to the texture's frame count (fail-soft: a chart boot can hand over dan = 69)
|
|
local emblem_info = tex.get_texture_info("nameplate", "dan_emblem")
|
|
local reported = (emblem_info and emblem_info.frame_count) or 0
|
|
local dan_frames = (reported > 1) and reported or DAN_FRAME_COUNT
|
|
self.has_dan = (type(dan) == "number" and dan >= 0 and dan < dan_frames)
|
|
-- coin plate = no title and no dan
|
|
self.is_coin = not self.has_title and not self.has_dan
|
|
self.has_badge = (player_num ~= PLAYER_NUM_ALL and player_num ~= PLAYER_NUM_AI)
|
|
|
|
self.rainbow_anim = tex.get_animation(12, "global")
|
|
|
|
local box = self:name_box()
|
|
-- white fill + black outline; the font is squeezed horizontally to fit the box (x2 below)
|
|
self.name_text = text.create_raw_text(name or "", box[3], { 255, 255, 255, 255 }, { 0, 0, 0, 255 },
|
|
false, 2, TEXT_SPACING)
|
|
self.title_text = text.create_raw_text(title or "", TITLE_FONT, { 0, 0, 0, 255 }, { 0, 0, 0, 0 },
|
|
false, 0, TEXT_SPACING)
|
|
|
|
if self.has_badge then
|
|
local pnum_key = tostring(player_num) .. "p"
|
|
self.pnum_tex = tex.get_texture("global/nameplate/" .. pnum_key)
|
|
end
|
|
|
|
return self
|
|
end
|
|
|
|
-- which name box this plate uses
|
|
function Nameplate:name_box()
|
|
if self.is_coin then
|
|
return self.has_badge and NAME_COIN or NAME_COIN_BARE
|
|
end
|
|
if not self.has_badge then return NAME_BAND_BARE end
|
|
return self.has_dan and NAME_BAND_DANI or NAME_BAND
|
|
end
|
|
|
|
-- one centred, whole-pixel-snapped OutlinedText draw inside a Lumen EditText box.
|
|
local function draw_in_box(t, x, y, cx, cy, box_w, fade)
|
|
if not t or t.width == nil then return end
|
|
local w = math.floor(math.min(t.width, box_w) + 0.5)
|
|
local dx = math.floor(x + cx - (w - TEXT_SPACING) / 2.0 + 0.5)
|
|
local dy = math.floor(y + cy - t.height / 2 + 0.5)
|
|
t:draw({ x = dx, y = dy, x2 = w - t.width, fade = fade })
|
|
end
|
|
|
|
function Nameplate:update(current_ms)
|
|
self.rainbow_anim:update(current_ms)
|
|
end
|
|
|
|
function Nameplate:draw(x, y, fade)
|
|
fade = fade or 1.0
|
|
|
|
if self.player_num == PLAYER_NUM_AI then
|
|
tex.draw_texture(self.ai, { x = x, y = y })
|
|
return
|
|
end
|
|
|
|
-- white plate
|
|
tex.draw_texture(self.shadow, { x = x, y = y, fade = fade })
|
|
|
|
if not self.is_coin then
|
|
-- title band + title background; clamp title_bg to a valid frame
|
|
local frame = (self.player_num == PLAYER_NUM_ALL) and 2 or self.title_bg
|
|
if type(frame) ~= "number" or frame < 0 or frame >= TITLE_BG_FRAMES then frame = 0 end
|
|
if self.is_rainbow then
|
|
local ra = self.rainbow_anim.attribute
|
|
if ra > 0 and ra < 6 then
|
|
tex.draw_texture(self.frame_top_rainbow, { frame = math.floor(ra) - 1, x = x, y = y, fade = fade })
|
|
end
|
|
tex.draw_texture(self.frame_top_rainbow, { frame = math.floor(ra), x = x, y = y, fade = fade })
|
|
else
|
|
tex.draw_texture(self.frame_top, { frame = frame, x = x, y = y, fade = fade })
|
|
end
|
|
tex.draw_texture(self.outline, { x = x, y = y, fade = fade })
|
|
end
|
|
|
|
-- dan chip (band family only)
|
|
if self.has_dan and not self.is_coin then
|
|
tex.draw_texture(self.dan_emblem_bg, { x = x, y = y, fade = fade })
|
|
local emblem = self.is_gold and self.dan_emblem_gold or self.dan_emblem
|
|
tex.draw_texture(emblem, { frame = self.dan, x = x, y = y, fade = fade })
|
|
end
|
|
|
|
-- player-number badge
|
|
if self.has_badge then
|
|
tex.draw_texture(self.pnum_tex, { x = x, y = y, fade = fade })
|
|
end
|
|
|
|
-- title text (band family only)
|
|
if not self.is_coin and self.has_title then
|
|
draw_in_box(self.title_text, x, y, TITLE_CX, TITLE_CY, TITLE_BOX_W, fade)
|
|
end
|
|
|
|
-- name text
|
|
local box = self:name_box()
|
|
draw_in_box(self.name_text, x, y, box[1], box[2], NAME_BOX_W, fade)
|
|
end
|