diff --git a/autogen/convert_functions.py b/autogen/convert_functions.py index 8ab92a973..7426fcac9 100644 --- a/autogen/convert_functions.py +++ b/autogen/convert_functions.py @@ -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" ], } ########################################################### diff --git a/credits.txt b/credits.txt index e2d35f471..daac4bbd5 100644 --- a/credits.txt +++ b/credits.txt @@ -22,6 +22,7 @@ Contributors: GammaTendonNine gunvalk IsaacBrumby + jkcoxson Llennpie LuigiNoodle PeachyPeach diff --git a/docs/lua/functions.md b/docs/lua/functions.md index 0a61ff05c..40ae0e659 100644 --- a/docs/lua/functions.md +++ b/docs/lua/functions.md @@ -275,6 +275,15 @@
+- 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) + +
+ - 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 @@
+--- +# functions from network_player.h + +
+ + +## [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:](#) + +
+ +## [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:](#) + +
+ +## [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:](#) + +
+ +## [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:](#) + +
+ +## [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:](#) + +
+ --- # functions from network_utils.h diff --git a/mods/hide-and-seek.lua b/mods/hide-and-seek.lua index 30e030178..f352b862d 100644 --- a/mods/hide-and-seek.lua +++ b/mods/hide-and-seek.lua @@ -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 diff --git a/src/pc/djui/djui.c b/src/pc/djui/djui.c index 5a396b305..3c8834c91 100644 --- a/src/pc/djui/djui.c +++ b/src/pc/djui/djui.c @@ -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); diff --git a/src/pc/djui/djui_hud_utils.c b/src/pc/djui/djui_hud_utils.c index ef204ac7c..012cbc27c 100644 --- a/src/pc/djui/djui_hud_utils.c +++ b/src/pc/djui/djui_hud_utils.c @@ -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; diff --git a/src/pc/djui/djui_hud_utils.h b/src/pc/djui/djui_hud_utils.h index 1d62ea2be..4c9bbec79 100644 --- a/src/pc/djui/djui_hud_utils.h +++ b/src/pc/djui/djui_hud_utils.h @@ -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); diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c index e89282aaf..4546e34e0 100644 --- a/src/pc/lua/smlua_functions_autogen.c +++ b/src/pc/lua/smlua_functions_autogen.c @@ -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);