Added HUD rendering to hide-and-seek

This commit is contained in:
MysterD 2022-02-16 18:10:06 -08:00
parent c46296700a
commit a44acd51f2
8 changed files with 356 additions and 39 deletions

View File

@ -33,6 +33,7 @@ in_files = [
"src/game/save_file.h",
"src/game/sound_init.h",
"src/pc/djui/djui_hud_utils.h",
"src/pc/network/network_player.h",
]
override_allowed_functions = {
@ -59,6 +60,7 @@ override_disallowed_functions = {
"src/game/interaction.h": [ "process_interactions", "_handle_" ],
"src/game/sound_init.h": [ "_loop_", "thread4_", "set_sound_mode" ],
"src/pc/network/network_utils.h": [ "network_get_player_text_color[^_]" ],
"src/pc/network/network_player.h": [ "_init", "_connected[^_]", "_shutdown", "_disconnected", "_update" ],
}
###########################################################

View File

@ -22,6 +22,7 @@ Contributors:
GammaTendonNine
gunvalk
IsaacBrumby
jkcoxson
Llennpie
LuigiNoodle
PeachyPeach

View File

@ -275,6 +275,15 @@
<br />
- network_player.h
- [get_network_player_from_area](#get_network_player_from_area)
- [get_network_player_from_level](#get_network_player_from_level)
- [get_network_player_smallest_global](#get_network_player_smallest_global)
- [network_player_connected_count](#network_player_connected_count)
- [network_player_from_global_index](#network_player_from_global_index)
<br />
- network_utils.h
- [network_get_player_text_color_string](#network_get_player_text_color_string)
- [network_global_index_from_local](#network_global_index_from_local)
@ -4699,6 +4708,113 @@
<br />
---
# functions from network_player.h
<br />
## [get_network_player_from_area](#get_network_player_from_area)
### Lua Example
`local NetworkPlayerValue = get_network_player_from_area(courseNum, actNum, levelNum, areaIndex)`
### Parameters
| Field | Type |
| ----- | ---- |
| courseNum | integer |
| actNum | integer |
| levelNum | integer |
| areaIndex | integer |
### Returns
[NetworkPlayer](structs.md#NetworkPlayer)
### C Prototype
`struct NetworkPlayer* get_network_player_from_area(s16 courseNum, s16 actNum, s16 levelNum, s16 areaIndex);`
[:arrow_up_small:](#)
<br />
## [get_network_player_from_level](#get_network_player_from_level)
### Lua Example
`local NetworkPlayerValue = get_network_player_from_level(courseNum, actNum, levelNum)`
### Parameters
| Field | Type |
| ----- | ---- |
| courseNum | integer |
| actNum | integer |
| levelNum | integer |
### Returns
[NetworkPlayer](structs.md#NetworkPlayer)
### C Prototype
`struct NetworkPlayer* get_network_player_from_level(s16 courseNum, s16 actNum, s16 levelNum);`
[:arrow_up_small:](#)
<br />
## [get_network_player_smallest_global](#get_network_player_smallest_global)
### Lua Example
`local NetworkPlayerValue = get_network_player_smallest_global()`
### Parameters
- None
### Returns
[NetworkPlayer](structs.md#NetworkPlayer)
### C Prototype
`struct NetworkPlayer* get_network_player_smallest_global(void);`
[:arrow_up_small:](#)
<br />
## [network_player_connected_count](#network_player_connected_count)
### Lua Example
`local integerValue = network_player_connected_count()`
### Parameters
- None
### Returns
- integer
### C Prototype
`u8 network_player_connected_count(void);`
[:arrow_up_small:](#)
<br />
## [network_player_from_global_index](#network_player_from_global_index)
### Lua Example
`local NetworkPlayerValue = network_player_from_global_index(globalIndex)`
### Parameters
| Field | Type |
| ----- | ---- |
| globalIndex | integer |
### Returns
[NetworkPlayer](structs.md#NetworkPlayer)
### C Prototype
`struct NetworkPlayer* network_player_from_global_index(u8 globalIndex);`
[:arrow_up_small:](#)
<br />
---
# functions from network_utils.h

View File

@ -13,7 +13,9 @@ gGlobalSyncTable.roundNumber = 0
gGlobalSyncTable.roundEnded = ROUND_END_UNKNOWN
sRoundEndedTimer = 0
sRoundIntermissionTime = 5 * 30 -- five seconds
sRoundEndedTimeout = 15 * 30 -- fifteen seconds
sFlashingIndex = 0
sDisplayCenterTimer = 0
-- server keeps track of last player turned seeker
sLastSeekerIndex = 0
@ -29,6 +31,7 @@ sLastPos.y = 0
sLastPos.z = 0
sDistanceMoved = 0
sDistanceTimer = 0
sDistanceTimeout = 10 * 30
function server_update(m)
-- figure out state of the game
@ -72,8 +75,7 @@ function server_update(m)
end
-- if round was over for 5 seconds
sRoundEndedTimer = sRoundEndedTimer + 1
if sRoundEndedTimer >= sRoundIntermissionTime then
if sRoundEndedTimer >= sRoundEndedTimeout then
-- reset seekers
for i=0,(MAX_PLAYERS-1) do
gPlayerSyncTable[i].seeking = false
@ -118,16 +120,19 @@ function camping_detection(m)
end
-- if the player has moved enough, reset the timer
if sDistanceMoved > 20 then
if sDistanceMoved > 25 then
sDistanceTimer = 0
end
-- inform the player that they need to move, or make them a seeker
if sDistanceTimer == 30 * 1 then
djui_popup_create('\\#ff4040\\Keep moving!', 3)
elseif sDistanceTimer > 30 * 6 then
if sDistanceTimer > sDistanceTimeout then
s.seeking = true
end
-- make sound
if sDistanceTimer > 0 and sDistanceTimer % 30 == 1 then
play_sound(SOUND_MENU_CAMERA_BUZZ, m.marioObj.header.gfx.cameraToObject)
end
end
function update()
@ -148,18 +153,13 @@ function update()
sDistanceTimer = 0
end
-- update sLastSeekerTimer
-- update sLastSeekerTimer and sRoundEndedTimer
if gGlobalSyncTable.roundEnded == 0 then
sLastSeekerTimer = sLastSeekerTimer + 1
local timeLeft = sLastSeekerTimeout - sLastSeekerTimer
if timeLeft == 60 * 30 then
djui_popup_create('\\#ff4040\\Seekers have one minute to get someone!', 3)
elseif timeLeft == 30 * 30 then
djui_popup_create('\\#ff4040\\Seekers have 30 seconds to get someone!', 3)
elseif timeLeft == 10 * 30 then
djui_popup_create('\\#ff4040\\Seekers have 10 seconds to get someone!', 3)
end
else
sRoundEndedTimer = sRoundEndedTimer + 1
end
sDisplayCenterTimer = sDisplayCenterTimer + 1
end
function mario_update(m)
@ -249,6 +249,131 @@ function on_player_connected(m)
s.seeking = false
end
function hud_top_render()
-- check gamemode enabled state
if not gGlobalSyncTable.hideAndSeek then
return
end
local seconds = 0
local text = ''
if network_player_connected_count() < 2 then
seconds = 60
text = 'waiting for players'
elseif gGlobalSyncTable.roundEnded == 0 then
seconds = math.floor((sLastSeekerTimeout - sLastSeekerTimer) / 30)
text = 'seekers have ' .. seconds .. ' seconds'
else
seconds = math.floor((sRoundEndedTimeout - sRoundEndedTimer) / 30)
text = 'next round in ' .. seconds .. ' seconds'
end
if seconds < 0 then seconds = 0 end
local scale = 0.50
-- get width of screen and text
local screenWidth = djui_hud_get_screen_width()
local width = djui_hud_measure_text(text) * scale
local x = (screenWidth - width) / 2.0
local y = 0
local background = 0.0
if seconds < 60 and gGlobalSyncTable.roundEnded == 0 then
background = (math.sin(sFlashingIndex / 10.0) * 0.5 + 0.5) * 1.0
background = background * background
background = background * background
end
-- render top
djui_hud_set_color(255 * background, 0, 0, 128);
djui_hud_render_rect(x - 6, y, width + 12, 16);
djui_hud_set_color(255, 255, 255, 255);
djui_hud_print_text(text, x, y, scale);
end
function hud_bottom_render()
local seconds = math.floor((sDistanceTimeout - sDistanceTimer) / 30)
if seconds < 0 then seconds = 0 end
if sDistanceTimer < 1 then return end
local text = 'Keep moving! (' .. seconds .. ')'
local scale = 0.50
-- get width of screen and text
local screenWidth = djui_hud_get_screen_width()
local screenHeight = djui_hud_get_screen_height()
local width = djui_hud_measure_text(text) * scale
local x = (screenWidth - width) / 2.0
local y = screenHeight - 16
local background = (math.sin(sFlashingIndex / 10.0) * 0.5 + 0.5) * 1.0
background = background * background
background = background * background
-- render top
djui_hud_set_color(255 * background, 0, 0, 128);
djui_hud_render_rect(x - 6, y, width + 12, 16);
djui_hud_set_color(255, 255, 255, 255);
djui_hud_print_text(text, x, y, scale);
end
function hud_center_render()
if sDisplayCenterTimer > 30 * 5 then return end
-- set text
local text = ''
if gGlobalSyncTable.roundEnded == ROUND_END_SEEKER_WIN then
text = 'Seekers Win!'
elseif gGlobalSyncTable.roundEnded == ROUND_END_HIDER_WIN then
text = 'Hiders Win!'
elseif gGlobalSyncTable.roundEnded == 0 then
text = 'Go!'
else
return
end
-- set scale
local scale = 1 - (sRoundEndedTimer / 30) + 4
if scale < 0 then scale = 0 end
if scale > 1 then scale = 1 end
scale = scale * scale
scale = scale * scale
scale = scale * scale
-- get width of screen and text
local screenWidth = djui_hud_get_screen_width()
local screenHeight = djui_hud_get_screen_height()
local width = djui_hud_measure_text(text) * scale
local height = 32 * scale
local x = (screenWidth - width) / 2.0
local y = (screenHeight - height) / 2.0
-- render
djui_hud_set_color(0, 0, 0, 128);
djui_hud_render_rect(x - 6 * scale, y, width + 12 * scale, height);
djui_hud_set_color(255, 255, 255, 255);
djui_hud_print_text(text, x, y, scale);
end
function on_hud_render()
-- render to N64 screen space, with the HUD font
djui_hud_set_resolution(RESOLUTION_N64)
djui_hud_set_font(FONT_NORMAL)
hud_top_render()
hud_bottom_render()
hud_center_render()
sFlashingIndex = sFlashingIndex + 1
end
function on_hide_and_seek_command(msg)
if not network_is_server() then
djui_chat_message_create('Only the server can change this setting!')
@ -271,33 +396,20 @@ end
-----------------------
function on_round_number_changed(tag, oldVal, newVal)
-- inform players when a new round has begun
if oldVal < newVal then
djui_popup_create('\\#a0ffa0\\a new round has begun', 2)
sDistanceMoved = 100
sDistanceTimer = 0
play_character_sound(gMarioStates[0], CHAR_SOUND_HERE_WE_GO)
end
play_character_sound(gMarioStates[0], CHAR_SOUND_HERE_WE_GO)
sDisplayCenterTimer = 0
end
function on_round_ended_changed(tag, oldVal, newVal)
-- inform players when a round has ended
local tColor = '\\#ffa0a0\\'
if newVal == ROUND_END_UNKNOWN then
djui_popup_create(tColor .. 'the round has ended', 2)
elseif newVal == ROUND_END_HIDER_WIN then
if not gPlayerSyncTable[0].seeking then tColor = '\\#a0ffa0\\' end
djui_popup_create(tColor .. 'Hiders win!', 2)
elseif newVal == ROUND_END_SEEKER_WIN then
if gPlayerSyncTable[0].seeking then tColor = '\\#a0ffa0\\' end
djui_popup_create(tColor .. 'Seekers win!', 2)
end
if oldVal == 0 and newVal ~= 0 then
sLastSeekerTimer = 0
play_sound(SOUND_MENU_CLICK_CHANGE_VIEW, gMarioStates[0].marioObj.header.gfx.cameraToObject)
sDisplayCenterTimer = 0
elseif newVal == 0 and oldVal ~= 0 then
sLastSeekerTimer = 0
end
sRoundEndedTimer = 0
end
function on_seeking_changed(tag, oldVal, newVal)
@ -323,6 +435,7 @@ hook_event(HOOK_MARIO_UPDATE, mario_update)
hook_event(HOOK_BEFORE_PHYS_STEP, mario_before_phys_step)
hook_event(HOOK_ON_PVP_ATTACK, on_pvp_attack)
hook_event(HOOK_ON_PLAYER_CONNECTED, on_player_connected)
hook_event(HOOK_ON_HUD_RENDER, on_hud_render)
hook_chat_command('hide-and-seek', "[on|off] turn hide-and-seek on or off", on_hide_and_seek_command)
@ -330,6 +443,6 @@ hook_chat_command('hide-and-seek', "[on|off] turn hide-and-seek on or off", on_h
hook_on_sync_table_change(gGlobalSyncTable, 'roundNumber', 0, on_round_number_changed)
hook_on_sync_table_change(gGlobalSyncTable, 'roundEnded', 0, on_round_ended_changed)
for i=0,(MAX_PLAYERS-1) do
gPlayerSyncTable[i].seeking = false
gPlayerSyncTable[i].seeking = true
hook_on_sync_table_change(gPlayerSyncTable[i], 'seeking', i, on_seeking_changed)
end

View File

@ -4,6 +4,7 @@
#include "game/level_update.h"
#include "pc/lua/smlua_hooks.h"
#include "djui_panel_playerlist.h"
#include "djui_hud_utils.h"
static Gfx* sSavedDisplayListHead = NULL;
@ -52,6 +53,8 @@ void djui_render_patch(void) {
void djui_render(void) {
if (gDjuiDisabled) { return; }
sSavedDisplayListHead = gDisplayListHead;
gDjuiHudUtilsZ = 0;
create_dl_ortho_matrix();
smlua_call_event_hooks(HOOK_ON_HUD_RENDER);

View File

@ -16,6 +16,8 @@
static enum HudUtilsResolution sResolution = RESOLUTION_DJUI;
static enum DjuiFontType sFont = FONT_NORMAL;
f32 gDjuiHudUtilsZ = 0;
extern ALIGNED8 const u8 texture_hud_char_camera[];
extern ALIGNED8 const u8 texture_hud_char_lakitu[];
extern ALIGNED8 const u8 texture_hud_char_no_camera[];
@ -95,6 +97,8 @@ f32 djui_hud_measure_text(const char* message) {
void djui_hud_print_text(const char* message, float x, float y, float scale) {
if (message == NULL) { return; }
gDjuiHudUtilsZ += 0.01f;
const struct DjuiFont* font = gDjuiFonts[sFont];
f32 fontScale = font->defaultFontScale * scale;
@ -107,7 +111,7 @@ void djui_hud_print_text(const char* message, float x, float y, float scale) {
f32 translatedX = x;
f32 translatedY = y;
djui_hud_position_translate(&translatedX, &translatedY);
create_dl_translation_matrix(DJUI_MTX_PUSH, translatedX, translatedY, 0);
create_dl_translation_matrix(DJUI_MTX_PUSH, translatedX, translatedY, gDjuiHudUtilsZ);
// compute font size
f32 translatedFontSize = fontScale;
@ -137,11 +141,13 @@ void djui_hud_print_text(const char* message, float x, float y, float scale) {
}
static void djui_hud_render_texture_raw(const u8* texture, u32 bitSize, u32 width, u32 height, f32 x, f32 y, f32 scaleW, f32 scaleH) {
gDjuiHudUtilsZ += 0.01f;
// translate position
f32 translatedX = x;
f32 translatedY = y;
djui_hud_position_translate(&translatedX, &translatedY);
create_dl_translation_matrix(DJUI_MTX_PUSH, translatedX, translatedY, 0);
create_dl_translation_matrix(DJUI_MTX_PUSH, translatedX, translatedY, gDjuiHudUtilsZ);
// translate scale
f32 translatedW = scaleW;
@ -162,11 +168,13 @@ void djui_hud_render_texture(struct TextureInfo* texInfo, f32 x, f32 y, f32 scal
}
void djui_hud_render_rect(f32 x, f32 y, f32 width, f32 height) {
gDjuiHudUtilsZ += 0.01f;
// translate position
f32 translatedX = x;
f32 translatedY = y;
djui_hud_position_translate(&translatedX, &translatedY);
create_dl_translation_matrix(DJUI_MTX_PUSH, translatedX, translatedY, 0);
create_dl_translation_matrix(DJUI_MTX_PUSH, translatedX, translatedY, gDjuiHudUtilsZ);
// translate scale
f32 translatedW = width;

View File

@ -25,6 +25,7 @@ struct GlobalTextures {
};
extern struct GlobalTextures gGlobalTextures;
extern f32 gDjuiHudUtilsZ;
void djui_hud_set_resolution(enum HudUtilsResolution resolutionType);
void djui_hud_set_font(enum DjuiFontType fontType);

View File

@ -17,6 +17,7 @@
#include "src/game/save_file.h"
#include "src/game/sound_init.h"
#include "src/pc/djui/djui_hud_utils.h"
#include "src/pc/network/network_player.h"
//////////////
@ -2929,6 +2930,71 @@ int smlua_func_stop_and_set_height_to_floor(lua_State* L) {
return 1;
}
//////////////////////
// network_player.h //
//////////////////////
int smlua_func_get_network_player_from_area(lua_State* L) {
if(!smlua_functions_valid_param_count(L, 4)) { return 0; }
s16 courseNum = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { return 0; }
s16 actNum = smlua_to_integer(L, 2);
if (!gSmLuaConvertSuccess) { return 0; }
s16 levelNum = smlua_to_integer(L, 3);
if (!gSmLuaConvertSuccess) { return 0; }
s16 areaIndex = smlua_to_integer(L, 4);
if (!gSmLuaConvertSuccess) { return 0; }
smlua_push_object(L, LOT_NETWORKPLAYER, get_network_player_from_area(courseNum, actNum, levelNum, areaIndex));
return 1;
}
int smlua_func_get_network_player_from_level(lua_State* L) {
if(!smlua_functions_valid_param_count(L, 3)) { return 0; }
s16 courseNum = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { return 0; }
s16 actNum = smlua_to_integer(L, 2);
if (!gSmLuaConvertSuccess) { return 0; }
s16 levelNum = smlua_to_integer(L, 3);
if (!gSmLuaConvertSuccess) { return 0; }
smlua_push_object(L, LOT_NETWORKPLAYER, get_network_player_from_level(courseNum, actNum, levelNum));
return 1;
}
int smlua_func_get_network_player_smallest_global(UNUSED lua_State* L) {
if(!smlua_functions_valid_param_count(L, 0)) { return 0; }
smlua_push_object(L, LOT_NETWORKPLAYER, get_network_player_smallest_global());
return 1;
}
int smlua_func_network_player_connected_count(UNUSED lua_State* L) {
if(!smlua_functions_valid_param_count(L, 0)) { return 0; }
lua_pushinteger(L, network_player_connected_count());
return 1;
}
int smlua_func_network_player_from_global_index(lua_State* L) {
if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
u8 globalIndex = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { return 0; }
smlua_push_object(L, LOT_NETWORKPLAYER, network_player_from_global_index(globalIndex));
return 1;
}
/////////////////////
// network_utils.h //
/////////////////////
@ -3721,6 +3787,13 @@ void smlua_bind_functions_autogen(void) {
smlua_bind_function(L, "stationary_ground_step", smlua_func_stationary_ground_step);
smlua_bind_function(L, "stop_and_set_height_to_floor", smlua_func_stop_and_set_height_to_floor);
// network_player.h
smlua_bind_function(L, "get_network_player_from_area", smlua_func_get_network_player_from_area);
smlua_bind_function(L, "get_network_player_from_level", smlua_func_get_network_player_from_level);
smlua_bind_function(L, "get_network_player_smallest_global", smlua_func_get_network_player_smallest_global);
smlua_bind_function(L, "network_player_connected_count", smlua_func_network_player_connected_count);
smlua_bind_function(L, "network_player_from_global_index", smlua_func_network_player_from_global_index);
// network_utils.h
smlua_bind_function(L, "network_get_player_text_color_string", smlua_func_network_get_player_text_color_string);
smlua_bind_function(L, "network_global_index_from_local", smlua_func_network_global_index_from_local);