2022-12-17 18:32:55 +00:00
-- name: Nametags
-- incompatible: nametags
2023-02-21 02:44:24 +00:00
-- description: Nametags\nBy \\#ec7731\\Agent X\\#dcdcdc\\\n\nThis mod adds nametags to sm64ex-coop, this helps to easily identify other players without the player list, nametags can toggled on and off with \\#ffff00\\/nametag-distance 7000\\#dcdcdc\\ and \\#ffff00\\/nametag-distance 0\\#dcdcdc\\ respectively.
2022-12-17 18:32:55 +00:00
MAX_SCALE = 0.32
gGlobalSyncTable.dist = 7000
2023-02-21 02:44:24 +00:00
gGlobalSyncTable.health = true
showSelfTag = false
2022-12-17 18:32:55 +00:00
2023-04-24 23:45:25 +00:00
gStateExtras = { }
for i = 0 , ( MAX_PLAYERS - 1 ) do
gStateExtras [ i ] = { }
local e = gStateExtras [ i ]
e.prevPos = { }
e.prevPos . x = 0
e.prevPos . y = 0
e.prevPos . z = 0
e.prevScale = 1
end
2022-12-17 18:32:55 +00:00
for k , v in pairs ( gActiveMods ) do
local name = v.name : lower ( )
if v.enabled and ( name : find ( " hide " ) or name : find ( " hns " ) or name : find ( " hunt " ) ) then
2023-02-21 02:44:24 +00:00
gGlobalSyncTable.dist = 0
2022-12-17 18:32:55 +00:00
end
end
2023-02-21 02:44:24 +00:00
function on_or_off ( value )
if value then return " \\ #00ff00 \\ ON " end
return " \\ #ff0000 \\ OFF "
end
2022-12-17 18:32:55 +00:00
function clamp ( x , a , b )
if x < a then return a end
if x > b then return b end
return x
end
--- @param m MarioState
function active_player ( m )
local np = gNetworkPlayers [ m.playerIndex ]
if m.playerIndex == 0 then
return 1
end
if not np.connected then
return 0
end
if np.currCourseNum ~= gNetworkPlayers [ 0 ] . currCourseNum then
return 0
end
if np.currActNum ~= gNetworkPlayers [ 0 ] . currActNum then
return 0
end
if np.currLevelNum ~= gNetworkPlayers [ 0 ] . currLevelNum then
return 0
end
if np.currAreaIndex ~= gNetworkPlayers [ 0 ] . currAreaIndex then
return 0
end
return is_player_active ( m )
end
function if_then_else ( cond , if_true , if_false )
if cond then return if_true end
return if_false
end
function djui_hud_set_adjusted_color ( r , g , b , a )
local multiplier = 1
if is_game_paused ( ) then multiplier = 0.5 end
djui_hud_set_color ( r * multiplier , g * multiplier , b * multiplier , a )
end
2023-04-24 23:45:25 +00:00
function djui_hud_print_outlined_text ( text , prevx , prevy , prevscale , x , y , scale , r , g , b , a , outlineDarkness )
djui_hud_set_resolution ( RESOLUTION_N64 )
2022-12-17 18:32:55 +00:00
-- render outline
2023-02-21 02:44:24 +00:00
djui_hud_set_adjusted_color ( r * outlineDarkness , g * outlineDarkness , b * outlineDarkness , a )
2023-04-24 23:45:25 +00:00
local offset = ( 1 * ( scale * 2 ) )
local prevoffset = ( 1 * ( prevscale * 2 ) )
djui_hud_print_text_interpolated ( text , prevx - prevoffset , prevy , prevscale , x - offset , y , scale )
djui_hud_print_text_interpolated ( text , prevx + prevoffset , prevy , prevscale , x + offset , y , scale )
djui_hud_print_text_interpolated ( text , prevx , prevy - prevoffset , prevscale , x , y - offset , scale )
djui_hud_print_text_interpolated ( text , prevx , prevy + prevoffset , prevscale , x , y + offset , scale )
2022-12-17 18:32:55 +00:00
-- render text
djui_hud_set_adjusted_color ( r , g , b , 255 )
2023-04-24 23:45:25 +00:00
djui_hud_print_text_interpolated ( text , prevx , prevy , prevscale , x , y , scale )
2022-12-17 18:32:55 +00:00
djui_hud_set_color ( 255 , 255 , 255 , 255 )
end
2023-02-21 02:44:24 +00:00
function name_without_hex ( name )
local s = ' '
local inSlash = false
for i = 1 , # name do
local c = name : sub ( i , i )
if c == ' \\ ' then
inSlash = not inSlash
elseif not inSlash then
s = s .. c
2022-12-17 18:32:55 +00:00
end
end
2023-02-21 02:44:24 +00:00
return s
2022-12-17 18:32:55 +00:00
end
function on_hud_render ( )
2023-02-21 02:44:24 +00:00
if gGlobalSyncTable.dist == 0 or not gNetworkPlayers [ 0 ] . currAreaSyncValid or obj_get_first_with_behavior_id ( id_bhvActSelector ) ~= nil then return end
2022-12-17 18:32:55 +00:00
djui_hud_set_resolution ( RESOLUTION_N64 )
djui_hud_set_font ( FONT_NORMAL )
2023-02-21 02:44:24 +00:00
for i = if_then_else ( showSelfTag , 0 , 1 ) , ( MAX_PLAYERS - 1 ) do
2022-12-17 18:32:55 +00:00
local m = gMarioStates [ i ]
2023-02-21 02:44:24 +00:00
if active_player ( m ) ~= 0 and m.action ~= ACT_IN_CANNON and ( m.playerIndex ~= 0 or ( m.playerIndex == 0 and m.action ~= ACT_FIRST_PERSON ) ) then
2022-12-17 18:32:55 +00:00
local out = { x = 0 , y = 0 , z = 0 }
2023-02-21 02:44:24 +00:00
local pos = { x = m.marioObj . header.gfx . pos.x , y = m.pos . y + 210 , z = m.marioObj . header.gfx . pos.z }
2022-12-17 18:32:55 +00:00
djui_hud_world_pos_to_screen_pos ( pos , out )
local scale = MAX_SCALE
if m.playerIndex ~= 0 and vec3f_dist ( gMarioStates [ 0 ] . pos , m.pos ) > 1000 then
scale = 0.5
scale = scale + vec3f_dist ( gMarioStates [ 0 ] . pos , m.pos ) / gGlobalSyncTable.dist
scale = clamp ( 1 - scale , 0 , MAX_SCALE )
end
2023-02-21 02:44:24 +00:00
local name = name_without_hex ( gNetworkPlayers [ i ] . name )
2022-12-17 18:32:55 +00:00
local color = { r = 162 , g = 202 , b = 234 }
network_player_palette_to_color ( gNetworkPlayers [ i ] , SHIRT , color )
2023-02-21 02:44:24 +00:00
local measure = djui_hud_measure_text ( name ) * scale * 0.5
local alpha = if_then_else ( m.action ~= ACT_CROUCHING and m.action ~= ACT_START_CRAWLING and m.action ~= ACT_CRAWLING and m.action ~= ACT_STOP_CRAWLING , 255 , 100 )
2023-04-24 23:45:25 +00:00
local e = gStateExtras [ i ]
djui_hud_print_outlined_text ( name , e.prevPos . x - measure , e.prevPos . y , e.prevScale , out.x - measure , out.y , scale , color.r , color.g , color.b , alpha , 0.25 )
2023-02-21 02:44:24 +00:00
if m.playerIndex ~= 0 and gGlobalSyncTable.health then
djui_hud_set_adjusted_color ( 255 , 255 , 255 , alpha )
local healthScale = 75 * scale
2023-04-24 23:45:25 +00:00
local prevHealthScale = 75 * e.prevScale
hud_render_power_meter_interpolated ( m.health ,
e.prevPos . x - ( prevHealthScale * 0.5 ) , e.prevPos . y - prevHealthScale , prevHealthScale , prevHealthScale ,
out.x - ( healthScale * 0.5 ) , out.y - healthScale , healthScale , healthScale )
2023-02-21 02:44:24 +00:00
end
2023-04-24 23:45:25 +00:00
e.prevPos . x = out.x
e.prevPos . y = out.y
e.prevPos . z = out.z
e.prevScale = scale
2022-12-17 18:32:55 +00:00
end
end
end
2023-02-21 02:44:24 +00:00
function on_nametag_distance_command ( msg )
local dist = tonumber ( msg )
if dist ~= nil then
djui_chat_message_create ( " Set nametag distance to " .. msg )
gGlobalSyncTable.dist = dist
return true
2022-12-17 18:32:55 +00:00
end
2023-02-21 02:44:24 +00:00
return false
2022-12-17 18:32:55 +00:00
end
2023-02-21 02:44:24 +00:00
function on_show_health_command ( )
gGlobalSyncTable.health = not gGlobalSyncTable.health
djui_chat_message_create ( " Show health status: " .. on_or_off ( gGlobalSyncTable.health ) )
2022-12-17 18:32:55 +00:00
return true
end
2023-02-21 02:44:24 +00:00
function on_show_tag_command ( )
showSelfTag = not showSelfTag
djui_chat_message_create ( " Show my tag status: " .. on_or_off ( showSelfTag ) )
2022-12-17 18:32:55 +00:00
return true
end
hook_event ( HOOK_ON_HUD_RENDER , on_hud_render )
if network_is_server ( ) then
2023-02-21 02:44:24 +00:00
hook_chat_command ( " nametag-distance " , " [number] set the distance at which nametags disappear, default is 7000, 0 turns nametags off " , on_nametag_distance_command )
hook_chat_command ( " show-health " , " to toggle showing health above the nametag, default is \\ #00ff00 \\ ON " , on_show_health_command )
2022-12-17 18:32:55 +00:00
end
2023-02-21 02:44:24 +00:00
hook_chat_command ( " show-tag " , " to toggle your own nametag on or off, default is \\ #ff0000 \\ OFF " , on_show_tag_command )