diff --git a/autogen/convert_structs.py b/autogen/convert_structs.py
index 5de01e582..a5b59c69b 100644
--- a/autogen/convert_structs.py
+++ b/autogen/convert_structs.py
@@ -62,6 +62,10 @@ override_field_types = {
"Object": { "oAnimations": "ObjectAnimPointer*"}
}
+override_field_mutable = {
+ "NetworkPlayer": [ "overrideModelIndex", "overridePaletteIndex" ],
+}
+
override_field_immutable = {
"MarioState": [ "playerIndex" ],
"Character": [ "*" ],
@@ -212,6 +216,10 @@ def get_struct_field_info(struct, field):
if fid in override_field_immutable[sid] or '*' in override_field_immutable[sid]:
fimmutable = 'true'
+ if sid in override_field_mutable:
+ if fid in override_field_mutable[sid] or '*' in override_field_mutable[sid]:
+ fimmutable = 'false'
+
return fid, ftype, fimmutable, lvt, lot
def build_struct(struct):
diff --git a/docs/lua/functions.md b/docs/lua/functions.md
index d18b101c6..64585c0f0 100644
--- a/docs/lua/functions.md
+++ b/docs/lua/functions.md
@@ -624,6 +624,8 @@
- smlua_misc_utils.h
- [get_network_area_timer](#get_network_area_timer)
+ - [hud_hide](#hud_hide)
+ - [hud_show](#hud_show)
@@ -11461,6 +11463,42 @@ The `reliable` field will ensure that the packet arrives, but should be used spa
+## [hud_hide](#hud_hide)
+
+### Lua Example
+`hud_hide()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void hud_hide(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [hud_show](#hud_show)
+
+### Lua Example
+`hud_show()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void hud_show(void);`
+
+[:arrow_up_small:](#)
+
+
+
---
# functions from smlua_obj_utils.h
diff --git a/docs/lua/structs.md b/docs/lua/structs.md
index dddd8a960..533f1780e 100644
--- a/docs/lua/structs.md
+++ b/docs/lua/structs.md
@@ -837,6 +837,8 @@
| modelIndex | `integer` | read-only |
| name | `string` | read-only |
| onRxSeqId | `integer` | read-only |
+| overrideModelIndex | `integer` | |
+| overridePaletteIndex | `integer` | |
| paletteIndex | `integer` | read-only |
| type | `integer` | read-only |
diff --git a/mods/football.lua b/mods/football.lua
index e6592568e..f5d6389b3 100644
--- a/mods/football.lua
+++ b/mods/football.lua
@@ -514,7 +514,9 @@ function bhv_ball_loop(obj)
local colNormals = {}
if info.surface ~= nil then
table.insert(colNormals, { x = info.surface.normal.x, y = info.surface.normal.y, z = info.surface.normal.z })
- bhv_ball_particle_bounce(obj)
+ if vMag > 5 then
+ bhv_ball_particle_bounce(obj)
+ end
else
table.insert(colNormals, nil)
end
@@ -673,10 +675,13 @@ gGlobalSyncTable.gameState = GAME_STATE_WAIT
gGlobalSyncTable.displayText = ' '
gGlobalSyncTable.displayFont = FONT_HUD
gGlobalSyncTable.displayColor = 0xFFFFFF
-gGlobalSyncTable.scoreNormal = 0
-gGlobalSyncTable.scoreMetal = 0
+gGlobalSyncTable.scoreRed = 0
+gGlobalSyncTable.scoreBlue = 0
function gamemode_initialize()
+ -- hide the SM64 HUD
+ hud_hide()
+
-- prevent warp doors from working
local wasRefreshed = false
local obj = obj_get_first(OBJ_LIST_SURFACE)
@@ -872,24 +877,24 @@ function gamemode_active()
end
if scoringTeam == 1 then
- gGlobalSyncTable.scoreNormal = gGlobalSyncTable.scoreNormal + 1
+ gGlobalSyncTable.scoreRed = gGlobalSyncTable.scoreRed + 1
gGlobalSyncTable.displayFont = FONT_NORMAL
- gGlobalSyncTable.displayColor = 0x99FF99
- if gGlobalSyncTable.scoreNormal >= sMaxScore then
- gGlobalSyncTable.displayText = 'normal team wins!'
+ gGlobalSyncTable.displayColor = 0xFF9999
+ if gGlobalSyncTable.scoreRed >= sMaxScore then
+ gGlobalSyncTable.displayText = 'red team wins!'
gameOver = true
else
- gGlobalSyncTable.displayText = 'normal team scored' .. displayName
+ gGlobalSyncTable.displayText = 'red team scored' .. displayName
end
else
- gGlobalSyncTable.scoreMetal = gGlobalSyncTable.scoreMetal + 1
+ gGlobalSyncTable.scoreBlue = gGlobalSyncTable.scoreBlue + 1
gGlobalSyncTable.displayFont = FONT_NORMAL
gGlobalSyncTable.displayColor = 0x9999FF
- if gGlobalSyncTable.scoreMetal >= sMaxScore then
- gGlobalSyncTable.displayText = 'metal team wins!'
+ if gGlobalSyncTable.scoreBlue >= sMaxScore then
+ gGlobalSyncTable.displayText = 'blue team wins!'
gameOver = true
else
- gGlobalSyncTable.displayText = 'metal team scored' .. displayName
+ gGlobalSyncTable.displayText = 'blue team scored' .. displayName
end
end
@@ -962,7 +967,7 @@ function gamemode_oob()
gGlobalSyncTable.displayFont = FONT_NORMAL
gGlobalSyncTable.displayText = 'out of bounds'
- gGlobalSyncTable.displayColor = 0xFF9999
+ gGlobalSyncTable.displayColor = 0xFFFFFF
-- start the round
if sStateTimer <= 0 then
@@ -984,8 +989,8 @@ function gamemode_over()
if sStateTimer <= 0 then
-- shuffle teams
gamemode_shuffle()
- gGlobalSyncTable.scoreMetal = 0
- gGlobalSyncTable.scoreNormal = 0
+ gGlobalSyncTable.scoreRed = 0
+ gGlobalSyncTable.scoreBlue = 0
gGlobalSyncTable.gameState = GAME_STATE_WAIT
sStateTimer = sWaitTimeout
end
@@ -1072,15 +1077,15 @@ function hud_score_render()
end
-- render
- djui_hud_set_color(100, 255, 100, 180);
+ djui_hud_set_color(255, 100, 100, 180);
djui_hud_render_rect(x - xOffset, y, width, height + 4);
djui_hud_set_color(100, 100, 255, 180);
djui_hud_render_rect(x + xOffset, y, width, height + 4);
djui_hud_set_color(255, 255, 255, 255);
- djui_hud_print_text(tostring(gGlobalSyncTable.scoreNormal), x - xOffset + textOffset, y + 2, 1);
- djui_hud_print_text(tostring(gGlobalSyncTable.scoreMetal), x + xOffset + textOffset, y + 2, 1);
+ djui_hud_print_text(tostring(gGlobalSyncTable.scoreRed), x - xOffset + textOffset, y + 2, 1);
+ djui_hud_print_text(tostring(gGlobalSyncTable.scoreBlue), x + xOffset + textOffset, y + 2, 1);
end
function on_hud_render()
@@ -1140,8 +1145,8 @@ function on_football_reset_command(msg)
elseif msg == 'game' then
djui_chat_message_create('Resetting the game.')
gamemode_shuffle()
- gGlobalSyncTable.scoreMetal = 0
- gGlobalSyncTable.scoreNormal = 0
+ gGlobalSyncTable.scoreRed = 0
+ gGlobalSyncTable.scoreBlue = 0
gGlobalSyncTable.displayText = ' '
gGlobalSyncTable.gameState = GAME_STATE_WAIT
sStateTimer = sWaitTimeout
@@ -1238,21 +1243,24 @@ function mario_update(m)
-- set metal state and health
local s = gPlayerSyncTable[m.playerIndex]
+ local np = gNetworkPlayers[m.playerIndex]
if s.team == 2 then
- m.marioBodyState.modelState = MODEL_STATE_METAL
+ np.overridePaletteIndex = 7
+ m.marioBodyState.modelState = 0
elseif s.team == 1 then
+ np.overridePaletteIndex = 15
m.marioBodyState.modelState = 0
else
+ np.overridePaletteIndex = np.paletteIndex
m.marioBodyState.modelState = MODEL_STATE_NOISE_ALPHA
end
m.health = 0x880
-- update description
- local np = gNetworkPlayers[m.playerIndex]
if s.team == 1 then
- network_player_set_description(np, "normal", 64, 255, 64, 255)
+ network_player_set_description(np, "red", 255, 64, 64, 255)
elseif s.team == 2 then
- network_player_set_description(np, "metal", 64, 64, 255, 255)
+ network_player_set_description(np, "blue", 64, 64, 255, 255)
else
network_player_set_description(np, "unknown", 64, 64, 64, 255)
end
diff --git a/src/game/behaviors/klepto.inc.c b/src/game/behaviors/klepto.inc.c
index 4bc0ce69b..64c40c245 100644
--- a/src/game/behaviors/klepto.inc.c
+++ b/src/game/behaviors/klepto.inc.c
@@ -422,7 +422,7 @@ void bhv_klepto_update(void) {
if (network_owns_object(o) && kleptoHoldingCap) {
struct NetworkPlayer* np = network_player_from_global_index(o->globalPlayerIndex);
if (np == NULL) { np = gNetworkPlayerLocal; }
- u8 modelIndex = (np->modelIndex < CT_MAX) ? np->modelIndex : 0;
+ u8 modelIndex = (np->overrideModelIndex < CT_MAX) ? np->overrideModelIndex : 0;
u32 capModel = gCharacters[modelIndex].capModelId;
save_file_clear_flags(SAVE_FLAG_CAP_ON_KLEPTO);
diff --git a/src/game/hud.c b/src/game/hud.c
index a4c12b0db..70434769b 100644
--- a/src/game/hud.c
+++ b/src/game/hud.c
@@ -18,6 +18,7 @@
#include "pc/network/network.h"
extern bool gDjuiInMainMenu;
+u8 gOverrideHideHud;
/* @file hud.c
* This file implements HUD rendering and power meter animations.
@@ -492,32 +493,34 @@ void render_hud(void) {
create_dl_ortho_matrix();
#endif
+ bool showHud = (configHUD && !gDjuiInMainMenu && !gOverrideHideHud);
+
if (gCurrentArea != NULL && gCurrentArea->camera->mode == CAMERA_MODE_INSIDE_CANNON) {
render_hud_cannon_reticle();
}
- if (hudDisplayFlags & HUD_DISPLAY_FLAG_LIVES && configHUD && !gDjuiInMainMenu) {
+ if (hudDisplayFlags & HUD_DISPLAY_FLAG_LIVES && showHud) {
render_hud_mario_lives();
}
- if (hudDisplayFlags & HUD_DISPLAY_FLAG_COIN_COUNT && configHUD && !gDjuiInMainMenu) {
+ if (hudDisplayFlags & HUD_DISPLAY_FLAG_COIN_COUNT && showHud) {
render_hud_coins();
}
- if (hudDisplayFlags & HUD_DISPLAY_FLAG_STAR_COUNT && configHUD && !gDjuiInMainMenu) {
+ if (hudDisplayFlags & HUD_DISPLAY_FLAG_STAR_COUNT && showHud) {
render_hud_stars();
}
- if (hudDisplayFlags & HUD_DISPLAY_FLAG_KEYS && configHUD && !gDjuiInMainMenu) {
+ if (hudDisplayFlags & HUD_DISPLAY_FLAG_KEYS && showHud) {
render_hud_keys();
}
- if (hudDisplayFlags & HUD_DISPLAY_FLAG_CAMERA_AND_POWER && configHUD && !gDjuiInMainMenu) {
+ if (hudDisplayFlags & HUD_DISPLAY_FLAG_CAMERA_AND_POWER && showHud) {
render_hud_power_meter();
render_hud_camera_status();
}
- if (hudDisplayFlags & HUD_DISPLAY_FLAG_TIMER && configHUD && !gDjuiInMainMenu) {
+ if (hudDisplayFlags & HUD_DISPLAY_FLAG_TIMER && showHud) {
render_hud_timer();
}
}
diff --git a/src/game/hud.h b/src/game/hud.h
index fb0da74cf..9eff6992e 100644
--- a/src/game/hud.h
+++ b/src/game/hud.h
@@ -25,6 +25,8 @@ enum CameraHUDLut {
GLYPH_CAM_WARIO_HEAD,
};
+u8 gOverrideHideHud;
+
void set_hud_camera_status(s16 status);
void render_hud(void);
diff --git a/src/game/mario.c b/src/game/mario.c
index 960c681f6..fdc88d10b 100644
--- a/src/game/mario.c
+++ b/src/game/mario.c
@@ -2181,8 +2181,8 @@ static void init_single_mario(struct MarioState* m) {
gNetworkPlayers[playerIndex].fadeOpacity = 0;
}
- // set mario/luigi model
- u8 modelIndex = gNetworkPlayers[playerIndex].modelIndex;
+ // set character model
+ u8 modelIndex = gNetworkPlayers[playerIndex].overrideModelIndex;
if (modelIndex >= CT_MAX) { modelIndex = 0; }
m->character = &gCharacters[modelIndex];
m->marioObj->header.gfx.sharedChild = gLoadedGraphNodes[m->character->modelId];
diff --git a/src/game/mario_misc.c b/src/game/mario_misc.c
index 673042a41..7c92da1ef 100644
--- a/src/game/mario_misc.c
+++ b/src/game/mario_misc.c
@@ -488,7 +488,7 @@ Gfx* geo_mario_tilt_torso(s32 callContext, struct GraphNode* node, Mat4* mtx) {
struct MarioBodyState* bodyState = &gBodyStates[plrIdx];
s32 action = bodyState->action;
- u8 charIndex = gNetworkPlayers[plrIdx].modelIndex;
+ u8 charIndex = gNetworkPlayers[plrIdx].overrideModelIndex;
if (charIndex >= CT_MAX) { charIndex = 0; }
struct Character* character = &gCharacters[charIndex];
@@ -807,7 +807,7 @@ Gfx* geo_mario_set_player_colors(s32 callContext, struct GraphNode* node, UNUSED
struct GraphNodeGenerated* asGenerated = (struct GraphNodeGenerated*) node;
Gfx* gfx = NULL;
u8 index = geo_get_processing_object_index();
- u8 colorIndex = gNetworkPlayers[index].paletteIndex;
+ u8 colorIndex = gNetworkPlayers[index].overridePaletteIndex;
struct MarioBodyState* bodyState = &gBodyStates[index];
if (callContext == GEO_CONTEXT_RENDER) {
@@ -838,8 +838,8 @@ Gfx* geo_mario_set_player_colors(s32 callContext, struct GraphNode* node, UNUSED
Gfx* geo_mario_cap_display_list(s32 callContext, struct GraphNode* node, UNUSED Mat4* c) {
if (callContext != GEO_CONTEXT_RENDER) { return NULL; }
u8 globalIndex = geo_get_processing_object_index();
- u8 colorIndex = gNetworkPlayers[globalIndex].paletteIndex;
- u8 charIndex = gNetworkPlayers[globalIndex].modelIndex;
+ u8 colorIndex = gNetworkPlayers[globalIndex].overridePaletteIndex;
+ u8 charIndex = gNetworkPlayers[globalIndex].overrideModelIndex;
if (charIndex >= CT_MAX) { charIndex = 0; }
struct Character* character = &gCharacters[charIndex];
diff --git a/src/pc/crash_handler.c b/src/pc/crash_handler.c
index f7022b294..e9fddc690 100644
--- a/src/pc/crash_handler.c
+++ b/src/pc/crash_handler.c
@@ -20,6 +20,7 @@
#include "pc/gfx/gfx_pc.h"
#include "game/game_init.h"
#include "game/ingame_menu.h"
+#include "game/object_list_processor.h"
#include "game/segment2.h"
#include "game/mario.h"
#include "gfx_dimensions.h"
diff --git a/src/pc/djui/djui_panel_player.c b/src/pc/djui/djui_panel_player.c
index d91bebee2..eed4eb624 100644
--- a/src/pc/djui/djui_panel_player.c
+++ b/src/pc/djui/djui_panel_player.c
@@ -41,7 +41,9 @@ static void djui_panel_player_name_on_focus_end(struct DjuiBase* caller) {
void djui_panel_player_value_changed(UNUSED struct DjuiBase* caller) {
if (configPlayerModel >= CT_MAX) { configPlayerModel = 0; }
- gNetworkPlayers[0].modelIndex = configPlayerModel;
+ if (gNetworkPlayers[0].overrideModelIndex == gNetworkPlayers[0].modelIndex) { gNetworkPlayers[0].overrideModelIndex = configPlayerModel; }
+ if (gNetworkPlayers[0].overridePaletteIndex == gNetworkPlayers[0].paletteIndex) { gNetworkPlayers[0].overridePaletteIndex = configPlayerPalette; }
+ gNetworkPlayers[0].modelIndex = configPlayerModel;
gNetworkPlayers[0].paletteIndex = configPlayerPalette;
network_player_update_model(0);
diff --git a/src/pc/djui/djui_panel_playerlist.c b/src/pc/djui/djui_panel_playerlist.c
index dfe9417e3..986dd2288 100644
--- a/src/pc/djui/djui_panel_playerlist.c
+++ b/src/pc/djui/djui_panel_playerlist.c
@@ -17,7 +17,7 @@ static struct DjuiText* djuiTextDescriptions[MAX_PLAYERS] = { 0 };
static struct DjuiText* djuiTextLocations[MAX_PLAYERS] = { 0 };
static void playerlist_update_row(u8 i, struct NetworkPlayer* np) {
- u8 charIndex = np->modelIndex;
+ u8 charIndex = np->overrideModelIndex;
if (charIndex >= CT_MAX) { charIndex = 0; }
djuiImages[i]->texture = gCharacters[charIndex].hudHeadTexture.texture;
diff --git a/src/pc/lua/smlua_cobject_autogen.c b/src/pc/lua/smlua_cobject_autogen.c
index 458cd2483..2fbf17960 100644
--- a/src/pc/lua/smlua_cobject_autogen.c
+++ b/src/pc/lua/smlua_cobject_autogen.c
@@ -646,33 +646,35 @@ static struct LuaObjectField sModeTransitionInfoFields[LUA_MODE_TRANSITION_INFO_
{ "transitionStart", LVT_COBJECT, offsetof(struct ModeTransitionInfo, transitionStart), true, LOT_LINEARTRANSITIONPOINT },
};
-#define LUA_NETWORK_PLAYER_FIELD_COUNT 23
+#define LUA_NETWORK_PLAYER_FIELD_COUNT 25
static struct LuaObjectField sNetworkPlayerFields[LUA_NETWORK_PLAYER_FIELD_COUNT] = {
- { "connected", LVT_BOOL, offsetof(struct NetworkPlayer, connected), true, LOT_NONE },
- { "currActNum", LVT_S16, offsetof(struct NetworkPlayer, currActNum), true, LOT_NONE },
- { "currAreaIndex", LVT_S16, offsetof(struct NetworkPlayer, currAreaIndex), true, LOT_NONE },
- { "currAreaSyncValid", LVT_BOOL, offsetof(struct NetworkPlayer, currAreaSyncValid), true, LOT_NONE },
- { "currCourseNum", LVT_S16, offsetof(struct NetworkPlayer, currCourseNum), true, LOT_NONE },
- { "currLevelAreaSeqId", LVT_U16, offsetof(struct NetworkPlayer, currLevelAreaSeqId), true, LOT_NONE },
- { "currLevelNum", LVT_S16, offsetof(struct NetworkPlayer, currLevelNum), true, LOT_NONE },
- { "currLevelSyncValid", LVT_BOOL, offsetof(struct NetworkPlayer, currLevelSyncValid), true, LOT_NONE },
- { "description", LVT_STRING, offsetof(struct NetworkPlayer, description), true, LOT_NONE },
- { "descriptionA", LVT_U8, offsetof(struct NetworkPlayer, descriptionA), true, LOT_NONE },
- { "descriptionB", LVT_U8, offsetof(struct NetworkPlayer, descriptionB), true, LOT_NONE },
- { "descriptionG", LVT_U8, offsetof(struct NetworkPlayer, descriptionG), true, LOT_NONE },
- { "descriptionR", LVT_U8, offsetof(struct NetworkPlayer, descriptionR), true, LOT_NONE },
- { "fadeOpacity", LVT_U8, offsetof(struct NetworkPlayer, fadeOpacity), true, LOT_NONE },
- { "globalIndex", LVT_U8, offsetof(struct NetworkPlayer, globalIndex), true, LOT_NONE },
- { "lastReceived", LVT_F32, offsetof(struct NetworkPlayer, lastReceived), true, LOT_NONE },
- { "lastSent", LVT_F32, offsetof(struct NetworkPlayer, lastSent), true, LOT_NONE },
- { "localIndex", LVT_U8, offsetof(struct NetworkPlayer, localIndex), true, LOT_NONE },
- { "modelIndex", LVT_U8, offsetof(struct NetworkPlayer, modelIndex), true, LOT_NONE },
- { "name", LVT_STRING, offsetof(struct NetworkPlayer, name), true, LOT_NONE },
- { "onRxSeqId", LVT_U8, offsetof(struct NetworkPlayer, onRxSeqId), true, LOT_NONE },
- { "paletteIndex", LVT_U8, offsetof(struct NetworkPlayer, paletteIndex), true, LOT_NONE },
-// { "rxPacketHash", LOT_???, offsetof(struct NetworkPlayer, rxPacketHash), true, LOT_??? }, <--- UNIMPLEMENTED
-// { "rxSeqIds", LOT_???, offsetof(struct NetworkPlayer, rxSeqIds), true, LOT_??? }, <--- UNIMPLEMENTED
- { "type", LVT_U8, offsetof(struct NetworkPlayer, type), true, LOT_NONE },
+ { "connected", LVT_BOOL, offsetof(struct NetworkPlayer, connected), true, LOT_NONE },
+ { "currActNum", LVT_S16, offsetof(struct NetworkPlayer, currActNum), true, LOT_NONE },
+ { "currAreaIndex", LVT_S16, offsetof(struct NetworkPlayer, currAreaIndex), true, LOT_NONE },
+ { "currAreaSyncValid", LVT_BOOL, offsetof(struct NetworkPlayer, currAreaSyncValid), true, LOT_NONE },
+ { "currCourseNum", LVT_S16, offsetof(struct NetworkPlayer, currCourseNum), true, LOT_NONE },
+ { "currLevelAreaSeqId", LVT_U16, offsetof(struct NetworkPlayer, currLevelAreaSeqId), true, LOT_NONE },
+ { "currLevelNum", LVT_S16, offsetof(struct NetworkPlayer, currLevelNum), true, LOT_NONE },
+ { "currLevelSyncValid", LVT_BOOL, offsetof(struct NetworkPlayer, currLevelSyncValid), true, LOT_NONE },
+ { "description", LVT_STRING, offsetof(struct NetworkPlayer, description), true, LOT_NONE },
+ { "descriptionA", LVT_U8, offsetof(struct NetworkPlayer, descriptionA), true, LOT_NONE },
+ { "descriptionB", LVT_U8, offsetof(struct NetworkPlayer, descriptionB), true, LOT_NONE },
+ { "descriptionG", LVT_U8, offsetof(struct NetworkPlayer, descriptionG), true, LOT_NONE },
+ { "descriptionR", LVT_U8, offsetof(struct NetworkPlayer, descriptionR), true, LOT_NONE },
+ { "fadeOpacity", LVT_U8, offsetof(struct NetworkPlayer, fadeOpacity), true, LOT_NONE },
+ { "globalIndex", LVT_U8, offsetof(struct NetworkPlayer, globalIndex), true, LOT_NONE },
+ { "lastReceived", LVT_F32, offsetof(struct NetworkPlayer, lastReceived), true, LOT_NONE },
+ { "lastSent", LVT_F32, offsetof(struct NetworkPlayer, lastSent), true, LOT_NONE },
+ { "localIndex", LVT_U8, offsetof(struct NetworkPlayer, localIndex), true, LOT_NONE },
+ { "modelIndex", LVT_U8, offsetof(struct NetworkPlayer, modelIndex), true, LOT_NONE },
+ { "name", LVT_STRING, offsetof(struct NetworkPlayer, name), true, LOT_NONE },
+ { "onRxSeqId", LVT_U8, offsetof(struct NetworkPlayer, onRxSeqId), true, LOT_NONE },
+ { "overrideModelIndex", LVT_U8, offsetof(struct NetworkPlayer, overrideModelIndex), false, LOT_NONE },
+ { "overridePaletteIndex", LVT_U8, offsetof(struct NetworkPlayer, overridePaletteIndex), false, LOT_NONE },
+ { "paletteIndex", LVT_U8, offsetof(struct NetworkPlayer, paletteIndex), true, LOT_NONE },
+// { "rxPacketHash", LOT_???, offsetof(struct NetworkPlayer, rxPacketHash), true, LOT_??? }, <--- UNIMPLEMENTED
+// { "rxSeqIds", LOT_???, offsetof(struct NetworkPlayer, rxSeqIds), true, LOT_??? }, <--- UNIMPLEMENTED
+ { "type", LVT_U8, offsetof(struct NetworkPlayer, type), true, LOT_NONE },
};
#define LUA_OBJECT_FIELD_COUNT 750
diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c
index ea5d82fbc..3a55d933c 100644
--- a/src/pc/lua/smlua_functions_autogen.c
+++ b/src/pc/lua/smlua_functions_autogen.c
@@ -7304,6 +7304,24 @@ int smlua_func_get_network_area_timer(UNUSED lua_State* L) {
return 1;
}
+int smlua_func_hud_hide(UNUSED lua_State* L) {
+ if(!smlua_functions_valid_param_count(L, 0)) { return 0; }
+
+
+ hud_hide();
+
+ return 1;
+}
+
+int smlua_func_hud_show(UNUSED lua_State* L) {
+ if(!smlua_functions_valid_param_count(L, 0)) { return 0; }
+
+
+ hud_show();
+
+ return 1;
+}
+
///////////////////////
// smlua_obj_utils.h //
///////////////////////
@@ -8618,6 +8636,8 @@ void smlua_bind_functions_autogen(void) {
// smlua_misc_utils.h
smlua_bind_function(L, "get_network_area_timer", smlua_func_get_network_area_timer);
+ smlua_bind_function(L, "hud_hide", smlua_func_hud_hide);
+ smlua_bind_function(L, "hud_show", smlua_func_hud_show);
// smlua_obj_utils.h
smlua_bind_function(L, "obj_get_first", smlua_func_obj_get_first);
diff --git a/src/pc/lua/utils/smlua_misc_utils.c b/src/pc/lua/utils/smlua_misc_utils.c
index 5dc9bb1cc..40965db1f 100644
--- a/src/pc/lua/utils/smlua_misc_utils.c
+++ b/src/pc/lua/utils/smlua_misc_utils.c
@@ -1,9 +1,19 @@
#include "types.h"
+#include "game/hud.h"
#include "pc/lua/smlua.h"
#include "smlua_misc_utils.h"
#include "pc/debuglog.h"
u32 get_network_area_timer(void) {
return gNetworkAreaTimer;
-}
\ No newline at end of file
+}
+
+void hud_hide(void) {
+ gOverrideHideHud = 1;
+}
+
+void hud_show(void) {
+ gOverrideHideHud = 0;
+}
+
diff --git a/src/pc/lua/utils/smlua_misc_utils.h b/src/pc/lua/utils/smlua_misc_utils.h
index 53363d33a..fe5bacefb 100644
--- a/src/pc/lua/utils/smlua_misc_utils.h
+++ b/src/pc/lua/utils/smlua_misc_utils.h
@@ -3,4 +3,7 @@
u32 get_network_area_timer(void);
+void hud_hide(void);
+void hud_show(void);
+
#endif
diff --git a/src/pc/network/network.c b/src/pc/network/network.c
index 00d728624..2b5c47cbc 100644
--- a/src/pc/network/network.c
+++ b/src/pc/network/network.c
@@ -66,6 +66,10 @@ void network_set_system(enum NetworkSystemType nsType) {
}
bool network_init(enum NetworkType inNetworkType) {
+ // reset override hide hud
+ extern u8 gOverrideHideHud;
+ gOverrideHideHud = 0;
+
// sanity check network system
if (gNetworkSystem == NULL) {
LOG_ERROR("no network system attached");
diff --git a/src/pc/network/network_player.c b/src/pc/network/network_player.c
index b072d3c44..8e41b6b32 100644
--- a/src/pc/network/network_player.c
+++ b/src/pc/network/network_player.c
@@ -17,12 +17,19 @@ static char sDefaultPlayerName[] = "Player";
void network_player_init(void) {
gNetworkPlayers[0].modelIndex = (configPlayerModel < CT_MAX) ? configPlayerModel : 0;
gNetworkPlayers[0].paletteIndex = configPlayerPalette;
+ gNetworkPlayers[0].overrideModelIndex = gNetworkPlayers[0].modelIndex;
+ gNetworkPlayers[0].overridePaletteIndex = gNetworkPlayers[0].paletteIndex;
}
void network_player_update_model(u8 localIndex) {
struct MarioState* m = &gMarioStates[localIndex];
if (m == NULL) { return; }
- m->character = &gCharacters[gNetworkPlayers[localIndex].modelIndex];
+ struct NetworkPlayer* np = &gNetworkPlayers[localIndex];
+
+ u8 index = np->overrideModelIndex;
+ if (index >= CT_MAX) { index = 0; }
+ m->character = &gCharacters[index];
+
if (m->marioObj == NULL) { return; }
m->marioObj->header.gfx.sharedChild = gLoadedGraphNodes[m->character->modelId];
}
@@ -113,12 +120,20 @@ struct NetworkPlayer* get_network_player_smallest_global(void) {
}
void network_player_update(void) {
+ for (int i = 0; i < MAX_PLAYERS; i++) {
+ struct NetworkPlayer* np = &gNetworkPlayers[i];
+ if (!np->connected && i > 0) { continue; }
+
+ network_player_update_model(i);
+ }
+
if (!network_player_any_connected()) { return; }
if (gNetworkType == NT_SERVER) {
for (int i = 1; i < MAX_PLAYERS; i++) {
struct NetworkPlayer* np = &gNetworkPlayers[i];
- if (!np->connected) { continue; }
+ if (!np->connected && i > 0) { continue; }
+
float elapsed = (clock_elapsed() - np->lastReceived);
#ifndef DEVELOPMENT
if (elapsed > NETWORK_PLAYER_TIMEOUT) {
@@ -179,6 +194,8 @@ u8 network_player_connected(enum NetworkPlayerType type, u8 globalIndex, u8 mode
np->lastSent = clock_elapsed();
if ((type != NPT_LOCAL) && (gNetworkType == NT_SERVER || type == NPT_SERVER)) { gNetworkSystem->save_id(localIndex, 0); }
+ if (np->modelIndex == np->overrideModelIndex) { np->overrideModelIndex = modelIndex; }
+ if (np->paletteIndex == np->overridePaletteIndex) { np->overridePaletteIndex = paletteIndex; }
np->modelIndex = modelIndex;
np->paletteIndex = paletteIndex;
network_player_update_model(localIndex);
@@ -208,6 +225,8 @@ u8 network_player_connected(enum NetworkPlayerType type, u8 globalIndex, u8 mode
np->fadeOpacity = 0;
np->modelIndex = modelIndex;
np->paletteIndex = paletteIndex;
+ np->overrideModelIndex = modelIndex;
+ np->overridePaletteIndex = paletteIndex;
snprintf(np->name, MAX_PLAYER_STRING, "%s", name);
network_player_update_model(localIndex);
diff --git a/src/pc/network/network_player.h b/src/pc/network/network_player.h
index eecb675c8..8f227f31e 100644
--- a/src/pc/network/network_player.h
+++ b/src/pc/network/network_player.h
@@ -44,6 +44,9 @@ struct NetworkPlayer {
u8 descriptionB;
u8 descriptionA;
+ u8 overrideModelIndex;
+ u8 overridePaletteIndex;
+
u16 rxSeqIds[MAX_RX_SEQ_IDS];
u32 rxPacketHash[MAX_RX_SEQ_IDS];
};
diff --git a/src/pc/network/network_utils.c b/src/pc/network/network_utils.c
index a538f2b34..5da54f039 100644
--- a/src/pc/network/network_utils.c
+++ b/src/pc/network/network_utils.c
@@ -30,7 +30,7 @@ u8* network_get_player_text_color(u8 localIndex) {
if (localIndex >= MAX_PLAYERS) { localIndex = 0; }
struct NetworkPlayer* np = &gNetworkPlayers[localIndex];
- u8* rgb = get_player_color(np->paletteIndex, 0);
+ u8* rgb = get_player_color(np->overridePaletteIndex, 0);
static u8 sTextRgb[3] = { 0 };
for (int i = 0; i < 3; i++) {
sTextRgb[i] = 127 + rgb[i] / 2;
diff --git a/src/pc/network/packets/packet_network_players.c b/src/pc/network/packets/packet_network_players.c
index 7a7bb8643..70288c833 100644
--- a/src/pc/network/packets/packet_network_players.c
+++ b/src/pc/network/packets/packet_network_players.c
@@ -114,7 +114,7 @@ void network_receive_network_players(struct Packet* p) {
gNetworkSystem->save_id(localIndex, networkId);
}
} else {
- np->modelIndex = (modelIndex < CT_MAX) ? modelIndex : 0;
+ np->modelIndex = (modelIndex < CT_MAX) ? modelIndex : 0;
np->paletteIndex = paletteIndex;
network_player_update_model(localIndex);
}
diff --git a/src/pc/network/packets/packet_player_settings.c b/src/pc/network/packets/packet_player_settings.c
index 45cd6e14e..cb132caf3 100644
--- a/src/pc/network/packets/packet_player_settings.c
+++ b/src/pc/network/packets/packet_player_settings.c
@@ -48,7 +48,11 @@ void network_receive_player_settings(struct Packet* p) {
struct NetworkPlayer* np = network_player_from_global_index(globalId);
snprintf(np->name, MAX_PLAYER_STRING, "%s", playerName);
- np->modelIndex = playerModel;
+
+ if (np->modelIndex == np->overrideModelIndex) { np->overrideModelIndex = playerModel; }
+ if (np->paletteIndex == np->overridePaletteIndex) { np->overridePaletteIndex = playerPalette; }
+
+ np->modelIndex = playerModel;
np->paletteIndex = playerPalette;
network_player_update_model(np->localIndex);