sm64ex-coop/mods/arena/arena-hud.lua

270 lines
8.9 KiB
Lua

gHudIcons = {
flags = {
[0] = { tex = TEX_FLAG, prevX = 0, prevY = 0, r = 255, g = 255, b = 255 },
[1] = { tex = TEX_FLAG, prevX = 0, prevY = 0, r = 255, g = 120, b = 120 },
[2] = { tex = TEX_FLAG, prevX = 0, prevY = 0, r = 120, g = 120, b = 255 },
},
koth = { tex = TEX_KOTH, prevX = 0, prevY = 0, r = 255, g = 255, b = 255 },
}
function rank_str(rank)
if rank == 1 then
return '1st'
elseif rank == 2 then
return '2nd'
elseif rank == 3 then
return '3rd'
else
return tostring(rank) .. 'th'
end
end
function rank_color_g(rank)
return clamp(255 - 255 * (rank / 8), 0, 255)
end
function update_ranking_descriptions()
for i = 0, (MAX_PLAYERS - 1) do
local s = gPlayerSyncTable[i]
local np = gNetworkPlayers[i]
local m = gMarioStates[i]
if active_player(m) then
if s.rank > 0 then
local score = s.kills
if gGameModes[gGlobalSyncTable.gameMode].useScore then
score = s.score
end
local description = string.format('%s %d', rank_str(s.rank), score)
local r = 255
local g = rank_color_g(i)
local b = 0
network_player_set_description(np, description, r, g, b, 255)
else
network_player_set_description(np, ' ', 255, 255, 255, 255)
end
end
end
end
function render_game_mode()
local m = gMarioStates[0]
local np = gNetworkPlayers[0]
local s = gPlayerSyncTable[0]
if s.rank <= 0 then
return
end
local scoreCap = gGameModes[gGlobalSyncTable.gameMode].scoreCap
local txt = string.format("%s", gGameModes[gGlobalSyncTable.gameMode].name)
if gGlobalSyncTable.gameMode == GAME_MODE_DM then
txt = string.format("%s | First to %d kills", gGameModes[gGlobalSyncTable.gameMode].name, scoreCap)
elseif gGlobalSyncTable.gameMode == GAME_MODE_TDM then
txt = string.format("%s | First team to %d kills", gGameModes[gGlobalSyncTable.gameMode].name, scoreCap)
elseif gGlobalSyncTable.gameMode == GAME_MODE_CTF then
txt = string.format("%s | First team to %d captures", gGameModes[gGlobalSyncTable.gameMode].name, scoreCap)
elseif gGlobalSyncTable.gameMode == GAME_MODE_FT then
txt = string.format("%s | First to %d points", gGameModes[gGlobalSyncTable.gameMode].name, scoreCap)
elseif gGlobalSyncTable.gameMode == GAME_MODE_TFT then
txt = string.format("%s | First team to %d points", gGameModes[gGlobalSyncTable.gameMode].name, scoreCap)
elseif gGlobalSyncTable.gameMode == GAME_MODE_KOTH then
txt = string.format("%s | First to %d points", gGameModes[gGlobalSyncTable.gameMode].name, scoreCap)
elseif gGlobalSyncTable.gameMode == GAME_MODE_TKOTH then
txt = string.format("%s | First team to %d points", gGameModes[gGlobalSyncTable.gameMode].name, scoreCap)
end
local scale = 0.25
local width = (djui_hud_measure_text(txt) + 8) * scale
local height = 4 * scale + 28 * scale
local x = 4 * scale
local y = 2 * scale
djui_hud_set_color(0, 0, 0, 128)
djui_hud_render_rect(x, y, width, height)
x = x + 4 * scale
djui_hud_set_color(0, 0, 0, 255)
djui_hud_print_text(txt, x + 2 * scale, y + 2 * scale, scale)
djui_hud_set_color(255, 255, 255, 255)
djui_hud_print_text(txt, x + 0 * scale, y + 0 * scale, scale)
end
function render_single_team_score(team)
local txt = string.format("%d", calculate_team_score(team))
local scale = 0.25
local width = 64 * scale
local textWidth = djui_hud_measure_text(txt) * scale
local height = 4 * scale + 28 * scale
local x = 4 * scale
local y = 72 * scale
if team == 1 then
djui_hud_set_color(128, 0, 0, 128)
elseif team == 2 then
x = x + 72 * scale
djui_hud_set_color(0, 0, 128, 128)
end
djui_hud_render_rect(x, y, width, height)
x = x + (width - textWidth) / 2
djui_hud_set_color(0, 0, 0, 255)
djui_hud_print_text(txt, x + 2 * scale, y + 2 * scale, scale)
djui_hud_set_color(255, 255, 255, 255)
djui_hud_print_text(txt, x + 0 * scale, y + 0 * scale, scale)
end
function render_team_score()
if not gGameModes[gGlobalSyncTable.gameMode].teams then
return
end
render_single_team_score(1)
render_single_team_score(2)
end
function render_local_rank()
local m = gMarioStates[0]
local np = gNetworkPlayers[0]
local s = gPlayerSyncTable[0]
if s.rank <= 0 then
return
end
local rankTxt = ""
if gGameModes[gGlobalSyncTable.gameMode].useScore then
rankTxt = string.format("%s | %d points | %d kills | %d deaths", rank_str(s.rank), s.score, s.kills, s.deaths)
else
rankTxt = string.format("%s | %d kills | %d deaths", rank_str(s.rank), s.kills, s.deaths)
end
local scale = 0.25
local width = (djui_hud_measure_text(rankTxt) + 8) * scale
local height = 4 * scale + 28 * scale
local x = 4 * scale
local y = 36 * scale
djui_hud_set_color(0, 0, 0, 128)
djui_hud_render_rect(x, y, width, height)
x = x + 4 * scale
djui_hud_set_color(0, 0, 0, 255)
djui_hud_print_text(rankTxt, x + 2 * scale, y + 2 * scale, scale)
djui_hud_set_color(255, rank_color_g(s.rank), 0, 255)
djui_hud_print_text(rankTxt, x + 0 * scale, y + 0 * scale, scale)
end
function render_server_message()
local txt = gGlobalSyncTable.message
if txt == nil or string.len(txt) <= 1 then
return
end
-- get screen dimensions
local screenWidth = djui_hud_get_screen_width()
local screenHeight = djui_hud_get_screen_height()
local scale = 1
local width = (djui_hud_measure_text(txt) + 8) * scale
local height = 4 * scale + 28 * scale
local x = (screenWidth - width) / 2
local y = (screenHeight / 4)
djui_hud_set_color(0, 0, 0, 128)
djui_hud_render_rect(x, y, width, height)
x = x + 4 * scale
djui_hud_set_color(0, 0, 0, 255)
djui_hud_print_text(txt, x + 2 * scale, y + 2 * scale, scale)
djui_hud_set_color(255, 255, 255, 255)
djui_hud_print_text(txt, x + 0 * scale, y + 0 * scale, scale)
end
function render_health()
-- get screen dimensions
local screenWidth = djui_hud_get_screen_width()
local screenHeight = djui_hud_get_screen_height()
local scale = 1
local width = 128 * scale
local height = 16 * scale
local x = math.floor((screenWidth - width) / 2)
local y = math.floor(screenHeight - height - 4 * scale)
djui_hud_set_color(0, 0, 0, 128)
djui_hud_render_rect(x, y, width, height)
x = x + 2 * scale
y = y + 2 * scale
width = width - 4 * scale
height = height - 4 * scale
health = mario_health_float(gMarioStates[0])
if health > 0 and health < 0.02 then
health = 0.02
end
width = math.floor(width * health)
rscale = clamp(((1 - health) ^ 2) * 3, 0, 1)
gscale = clamp((health ^ 2) * 2, 0, 1)
djui_hud_set_color(255 * rscale, 255 * gscale, 0, 128)
djui_hud_render_rect(x, y, width, height)
end
function render_hud_icon(obj, hudIcon)
local pos = { x = obj.oPosX, y = obj.oPosY, z = obj.oPosZ }
local out = { x = 0, y = 0, z = 0 }
djui_hud_world_pos_to_screen_pos(pos, out)
if out.z > -260 then
return
end
local alpha = clamp(vec3f_dist(pos, gMarioStates[0].pos) / 5000, 0, 1) - 0.2
if alpha <= 0 then
return
end
alpha = 1 - ((1 - alpha) ^ 3)
local dX = out.x - 4
local dY = out.y - 4
djui_hud_set_color(hudIcon.r, hudIcon.g, hudIcon.b, alpha * 200)
djui_hud_render_texture_interpolated(hudIcon.tex, hudIcon.prevX, hudIcon.prevY, 0.3, 0.3, dX, dY, 0.3, 0.3)
hudIcon.prevX = dX
hudIcon.prevY = dY
end
function on_hud_render()
-- set resolution and font
djui_hud_set_resolution(RESOLUTION_N64)
djui_hud_set_font(FONT_NORMAL)
-- do the things
update_ranking_descriptions()
render_game_mode()
render_local_rank()
render_team_score()
render_server_message()
render_health()
-- render hud icons
if gGlobalSyncTable.gameMode == GAME_MODE_FT or gGlobalSyncTable.gameMode == GAME_MODE_TFT then
if gArenaFlagInfo[0] ~= nil and gArenaFlagInfo[0].obj ~= nil then
render_hud_icon(gArenaFlagInfo[0].obj, gHudIcons.flags[0])
end
elseif gGlobalSyncTable.gameMode == GAME_MODE_CTF then
if gArenaFlagInfo[1] ~= nil and gArenaFlagInfo[1].obj ~= nil then
render_hud_icon(gArenaFlagInfo[1].obj, gHudIcons.flags[1])
end
if gArenaFlagInfo[2] ~= nil and gArenaFlagInfo[2].obj ~= nil then
render_hud_icon(gArenaFlagInfo[2].obj, gHudIcons.flags[2])
end
elseif gGlobalSyncTable.gameMode == GAME_MODE_KOTH or gGlobalSyncTable.gameMode == GAME_MODE_TKOTH then
if gArenaKothActiveObj ~= nil then
render_hud_icon(gArenaKothActiveObj, gHudIcons.koth)
end
end
end
hud_hide()
hook_event(HOOK_ON_HUD_RENDER, on_hud_render)