diff --git a/autogen/convert_constants.py b/autogen/convert_constants.py index 22e1365c..8e681493 100644 --- a/autogen/convert_constants.py +++ b/autogen/convert_constants.py @@ -28,10 +28,12 @@ in_files = [ "src/game/object_list_processor.h", "src/engine/graph_node.h", "levels/level_defines.h", + "src/game/obj_behaviors.c", ] exclude_constants = { - '*': [ '^MAXCONTROLLERS$', '^AREA_[^T].*', '^AREA_T[HTO]', '^CONT_ERR.*', '^READ_MASK$', '^SIGN_RANGE$', ] + '*': [ '^MAXCONTROLLERS$', '^AREA_[^T].*', '^AREA_T[HTO]', '^CONT_ERR.*', '^READ_MASK$', '^SIGN_RANGE$', ], + 'src/game/obj_behaviors.c': ['^o$'], } include_constants = { diff --git a/autogen/convert_functions.py b/autogen/convert_functions.py index b0885845..6d56bd6c 100644 --- a/autogen/convert_functions.py +++ b/autogen/convert_functions.py @@ -50,7 +50,7 @@ in_files = [ override_allowed_functions = { "src/audio/external.h": [ " play_", "fade" ], "src/game/camera.h": [ "set_.*camera_.*shake", "set_camera_mode" ], - "src/game/rumble_init.c": [ "queue_rumble_"], + "src/game/rumble_init.c": [ "queue_rumble_", "reset_rumble_timers" ], "src/pc/djui/djui_popup.h" : [ "create" ], "src/game/save_file.h": [ "save_file_get_" ], "src/pc/lua/utils/smlua_model_utils.h": [ "smlua_model_util_get_id" ], diff --git a/autogen/lua_constants/built-in.lua b/autogen/lua_constants/built-in.lua index eab590df..cc36a243 100644 --- a/autogen/lua_constants/built-in.lua +++ b/autogen/lua_constants/built-in.lua @@ -249,16 +249,22 @@ function approach_s32(current, target, inc, dec) current = target end end + + -- keep within 32 bits + if current > 2147483647 then + current = -2147483648 + (current - 2147483647) + elseif current < -2147483648 then + current = 2147483647 + (current - (-2147483648)) + end return current; end --- @param bank number ---- @param playFlags number --- @param soundID number --- @param priority number ---- @param flags2 number +--- @param flags number --- @return number -function SOUND_ARG_LOAD(bank, playFlags, soundID, priority, flags2) - if flags2 == nil then flags2 = 0 end - return ((bank << 28) | (playFlags << 24) | (soundID << 16) | (priority << 8) | (flags2 << 4) | 1) +function SOUND_ARG_LOAD(bank, soundID, priority, flags) + if flags == nil then flags = 0 end + return (bank << 28) | (soundID << 16) | (priority << 8) | flags | SOUND_STATUS_WAITING end diff --git a/autogen/lua_definitions/constants.lua b/autogen/lua_definitions/constants.lua index 671dad86..787f5476 100644 --- a/autogen/lua_definitions/constants.lua +++ b/autogen/lua_definitions/constants.lua @@ -251,18 +251,24 @@ function approach_s32(current, target, inc, dec) current = target end end + + -- keep within 32 bits + if current > 2147483647 then + current = -2147483648 + (current - 2147483647) + elseif current < -2147483648 then + current = 2147483647 + (current - (-2147483648)) + end return current; end --- @param bank number ---- @param playFlags number --- @param soundID number --- @param priority number ---- @param flags2 number +--- @param flags number --- @return number -function SOUND_ARG_LOAD(bank, playFlags, soundID, priority, flags2) - if flags2 == nil then flags2 = 0 end - return ((bank << 28) | (playFlags << 24) | (soundID << 16) | (priority << 8) | (flags2 << 4) | 1) +function SOUND_ARG_LOAD(bank, soundID, priority, flags) + if flags == nil then flags = 0 end + return (bank << 28) | (soundID << 16) | (priority << 8) | flags | SOUND_STATUS_WAITING end @@ -3750,6 +3756,21 @@ NPT_SERVER = 2 --- @type NetworkPlayerType NPT_CLIENT = 3 +--- @type integer +OBJ_COL_FLAGS_LANDED = (OBJ_COL_FLAG_GROUNDED | OBJ_COL_FLAG_NO_Y_VEL) + +--- @type integer +OBJ_COL_FLAG_GROUNDED = (1 << 0) + +--- @type integer +OBJ_COL_FLAG_HIT_WALL = (1 << 1) + +--- @type integer +OBJ_COL_FLAG_NO_Y_VEL = (1 << 3) + +--- @type integer +OBJ_COL_FLAG_UNDERWATER = (1 << 2) + --- @type integer ACTIVE_FLAG_ACTIVE = (1 << 0) diff --git a/autogen/lua_definitions/functions.lua b/autogen/lua_definitions/functions.lua index b318d282..bba404f4 100644 --- a/autogen/lua_definitions/functions.lua +++ b/autogen/lua_definitions/functions.lua @@ -3414,6 +3414,19 @@ function queue_rumble_data_object(object, a0, a1) -- ... end +--- @param m MarioState +--- @return nil +function reset_rumble_timers(m) + -- ... +end + +--- @param m MarioState +--- @param a0 integer +--- @return nil +function reset_rumble_timers_2(m, a0) + -- ... +end + --- @param capPos Vec3s --- @return integer function save_file_get_cap_pos(capPos) @@ -3476,12 +3489,38 @@ function collision_find_surface_on_ray(startX, startY, startZ, endX, endY, endZ) -- ... end +--- @return Surface +function get_water_surface_pseudo_floor() + -- ... +end + --- @param actFlags integer --- @return integer function allocate_mario_action(actFlags) -- ... end +--- @param m MarioState +--- @param index integer +--- @return number +function get_hand_foot_pos_x(m, index) + -- ... +end + +--- @param m MarioState +--- @param index integer +--- @return number +function get_hand_foot_pos_y(m, index) + -- ... +end + +--- @param m MarioState +--- @param index integer +--- @return number +function get_hand_foot_pos_z(m, index) + -- ... +end + --- @return integer function get_network_area_timer() -- ... diff --git a/docs/lua/constants.md b/docs/lua/constants.md index 5230a7a0..41650607 100644 --- a/docs/lua/constants.md +++ b/docs/lua/constants.md @@ -26,6 +26,7 @@ - [enum MarioHandGSCId](#enum-MarioHandGSCId) - [network_player.h](#network_playerh) - [enum NetworkPlayerType](#enum-NetworkPlayerType) +- [obj_behaviors.c](#obj_behaviorsc) - [object_constants.h](#object_constantsh) - [object_list_processor.h](#object_list_processorh) - [enum ObjectList](#enum-ObjectList) @@ -1316,6 +1317,17 @@
+## [obj_behaviors.c](#obj_behaviors.c) +- OBJ_COL_FLAGS_LANDED +- OBJ_COL_FLAG_GROUNDED +- OBJ_COL_FLAG_HIT_WALL +- OBJ_COL_FLAG_NO_Y_VEL +- OBJ_COL_FLAG_UNDERWATER + +[:arrow_up_small:](#) + +
+ ## [object_constants.h](#object_constants.h) - ACTIVE_FLAG_ACTIVE - ACTIVE_FLAG_DEACTIVATED diff --git a/docs/lua/functions.md b/docs/lua/functions.md index 6c550dd2..903b71c5 100644 --- a/docs/lua/functions.md +++ b/docs/lua/functions.md @@ -613,6 +613,8 @@ - [queue_rumble_data](#queue_rumble_data) - [queue_rumble_data_mario](#queue_rumble_data_mario) - [queue_rumble_data_object](#queue_rumble_data_object) + - [reset_rumble_timers](#reset_rumble_timers) + - [reset_rumble_timers_2](#reset_rumble_timers_2)
@@ -630,11 +632,15 @@ - smlua_collision_utils.h - [collision_find_surface_on_ray](#collision_find_surface_on_ray) + - [get_water_surface_pseudo_floor](#get_water_surface_pseudo_floor)
- smlua_misc_utils.h - [allocate_mario_action](#allocate_mario_action) + - [get_hand_foot_pos_x](#get_hand_foot_pos_x) + - [get_hand_foot_pos_y](#get_hand_foot_pos_y) + - [get_hand_foot_pos_z](#get_hand_foot_pos_z) - [get_network_area_timer](#get_network_area_timer) - [hud_hide](#hud_hide) - [hud_show](#hud_show) @@ -11411,6 +11417,47 @@ The `reliable` field will ensure that the packet arrives, but should be used spa
+## [reset_rumble_timers](#reset_rumble_timers) + +### Lua Example +`reset_rumble_timers(m)` + +### Parameters +| Field | Type | +| ----- | ---- | +| m | [MarioState](structs.md#MarioState) | + +### Returns +- None + +### C Prototype +`void reset_rumble_timers(struct MarioState* m);` + +[:arrow_up_small:](#) + +
+ +## [reset_rumble_timers_2](#reset_rumble_timers_2) + +### Lua Example +`reset_rumble_timers_2(m, a0)` + +### Parameters +| Field | Type | +| ----- | ---- | +| m | [MarioState](structs.md#MarioState) | +| a0 | `integer` | + +### Returns +- None + +### C Prototype +`void reset_rumble_timers_2(struct MarioState* m, s32 a0);` + +[:arrow_up_small:](#) + +
+ --- # functions from save_file.h @@ -11609,6 +11656,24 @@ The `reliable` field will ensure that the packet arrives, but should be used spa
+## [get_water_surface_pseudo_floor](#get_water_surface_pseudo_floor) + +### Lua Example +`local SurfaceValue = get_water_surface_pseudo_floor()` + +### Parameters +- None + +### Returns +[Surface](structs.md#Surface) + +### C Prototype +`struct Surface* get_water_surface_pseudo_floor(void);` + +[:arrow_up_small:](#) + +
+ --- # functions from smlua_misc_utils.h @@ -11635,6 +11700,69 @@ The `reliable` field will ensure that the packet arrives, but should be used spa
+## [get_hand_foot_pos_x](#get_hand_foot_pos_x) + +### Lua Example +`local numberValue = get_hand_foot_pos_x(m, index)` + +### Parameters +| Field | Type | +| ----- | ---- | +| m | [MarioState](structs.md#MarioState) | +| index | `integer` | + +### Returns +- `number` + +### C Prototype +`f32 get_hand_foot_pos_x(struct MarioState* m, u8 index);` + +[:arrow_up_small:](#) + +
+ +## [get_hand_foot_pos_y](#get_hand_foot_pos_y) + +### Lua Example +`local numberValue = get_hand_foot_pos_y(m, index)` + +### Parameters +| Field | Type | +| ----- | ---- | +| m | [MarioState](structs.md#MarioState) | +| index | `integer` | + +### Returns +- `number` + +### C Prototype +`f32 get_hand_foot_pos_y(struct MarioState* m, u8 index);` + +[:arrow_up_small:](#) + +
+ +## [get_hand_foot_pos_z](#get_hand_foot_pos_z) + +### Lua Example +`local numberValue = get_hand_foot_pos_z(m, index)` + +### Parameters +| Field | Type | +| ----- | ---- | +| m | [MarioState](structs.md#MarioState) | +| index | `integer` | + +### Returns +- `number` + +### C Prototype +`f32 get_hand_foot_pos_z(struct MarioState* m, u8 index);` + +[:arrow_up_small:](#) + +
+ ## [get_network_area_timer](#get_network_area_timer) ### Lua Example diff --git a/src/pc/lua/smlua_constants_autogen.c b/src/pc/lua/smlua_constants_autogen.c index 85813c0a..1fed4e74 100644 --- a/src/pc/lua/smlua_constants_autogen.c +++ b/src/pc/lua/smlua_constants_autogen.c @@ -227,17 +227,22 @@ char gSmluaConstants[] = "" " current = target\n" " end\n" " end\n" +" -- keep within 32 bits\n" +" if current > 2147483647 then\n" +" current = -2147483648 + (current - 2147483647)\n" +" elseif current < -2147483648 then\n" +" current = 2147483647 + (current - (-2147483648))\n" +" end\n" " return current;\n" "end\n" "--- @param bank number\n" -"--- @param playFlags number\n" "--- @param soundID number\n" "--- @param priority number\n" -"--- @param flags2 number\n" +"--- @param flags number\n" "--- @return number\n" -"function SOUND_ARG_LOAD(bank, playFlags, soundID, priority, flags2)\n" -" if flags2 == nil then flags2 = 0 end\n" -" return ((bank << 28) | (playFlags << 24) | (soundID << 16) | (priority << 8) | (flags2 << 4) | 1)\n" +"function SOUND_ARG_LOAD(bank, soundID, priority, flags)\n" +" if flags == nil then flags = 0 end\n" +" return (bank << 28) | (soundID << 16) | (priority << 8) | flags | SOUND_STATUS_WAITING\n" "end\n" "id_bhvStarDoor = 0\n" "id_bhvMrI = 1\n" @@ -1391,6 +1396,11 @@ char gSmluaConstants[] = "" "NPT_LOCAL = 1\n" "NPT_SERVER = 2\n" "NPT_CLIENT = 3\n" +"OBJ_COL_FLAG_GROUNDED = (1 << 0)\n" +"OBJ_COL_FLAG_HIT_WALL = (1 << 1)\n" +"OBJ_COL_FLAG_UNDERWATER = (1 << 2)\n" +"OBJ_COL_FLAG_NO_Y_VEL = (1 << 3)\n" +"OBJ_COL_FLAGS_LANDED = (OBJ_COL_FLAG_GROUNDED | OBJ_COL_FLAG_NO_Y_VEL)\n" "ACTIVE_FLAG_DEACTIVATED = 0\n" "ACTIVE_FLAG_ACTIVE = (1 << 0)\n" "ACTIVE_FLAG_FAR_AWAY = (1 << 1)\n" diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c index f7021451..5eb027f0 100644 --- a/src/pc/lua/smlua_functions_autogen.c +++ b/src/pc/lua/smlua_functions_autogen.c @@ -7263,6 +7263,32 @@ int smlua_func_queue_rumble_data_object(lua_State* L) { return 1; } +int smlua_func_reset_rumble_timers(lua_State* L) { + if(!smlua_functions_valid_param_count(L, 1)) { return 0; } + + struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIOSTATE); + if (!gSmLuaConvertSuccess) { return 0; } + + extern void reset_rumble_timers(struct MarioState* m); + reset_rumble_timers(m); + + return 1; +} + +int smlua_func_reset_rumble_timers_2(lua_State* L) { + if(!smlua_functions_valid_param_count(L, 2)) { return 0; } + + struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIOSTATE); + if (!gSmLuaConvertSuccess) { return 0; } + s32 a0 = smlua_to_integer(L, 2); + if (!gSmLuaConvertSuccess) { return 0; } + + extern void reset_rumble_timers_2(struct MarioState* m, s32 a0); + reset_rumble_timers_2(m, a0); + + return 1; +} + ///////////////// // save_file.h // ///////////////// @@ -7396,6 +7422,15 @@ int smlua_func_collision_find_surface_on_ray(lua_State* L) { return 1; } +int smlua_func_get_water_surface_pseudo_floor(UNUSED lua_State* L) { + if(!smlua_functions_valid_param_count(L, 0)) { return 0; } + + + smlua_push_object(L, LOT_SURFACE, get_water_surface_pseudo_floor()); + + return 1; +} + //////////////////////// // smlua_misc_utils.h // //////////////////////// @@ -7411,6 +7446,45 @@ int smlua_func_allocate_mario_action(lua_State* L) { return 1; } +int smlua_func_get_hand_foot_pos_x(lua_State* L) { + if(!smlua_functions_valid_param_count(L, 2)) { return 0; } + + struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIOSTATE); + if (!gSmLuaConvertSuccess) { return 0; } + u8 index = smlua_to_integer(L, 2); + if (!gSmLuaConvertSuccess) { return 0; } + + lua_pushnumber(L, get_hand_foot_pos_x(m, index)); + + return 1; +} + +int smlua_func_get_hand_foot_pos_y(lua_State* L) { + if(!smlua_functions_valid_param_count(L, 2)) { return 0; } + + struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIOSTATE); + if (!gSmLuaConvertSuccess) { return 0; } + u8 index = smlua_to_integer(L, 2); + if (!gSmLuaConvertSuccess) { return 0; } + + lua_pushnumber(L, get_hand_foot_pos_y(m, index)); + + return 1; +} + +int smlua_func_get_hand_foot_pos_z(lua_State* L) { + if(!smlua_functions_valid_param_count(L, 2)) { return 0; } + + struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIOSTATE); + if (!gSmLuaConvertSuccess) { return 0; } + u8 index = smlua_to_integer(L, 2); + if (!gSmLuaConvertSuccess) { return 0; } + + lua_pushnumber(L, get_hand_foot_pos_z(m, index)); + + return 1; +} + int smlua_func_get_network_area_timer(UNUSED lua_State* L) { if(!smlua_functions_valid_param_count(L, 0)) { return 0; } @@ -8765,6 +8839,8 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "queue_rumble_data", smlua_func_queue_rumble_data); smlua_bind_function(L, "queue_rumble_data_mario", smlua_func_queue_rumble_data_mario); smlua_bind_function(L, "queue_rumble_data_object", smlua_func_queue_rumble_data_object); + smlua_bind_function(L, "reset_rumble_timers", smlua_func_reset_rumble_timers); + smlua_bind_function(L, "reset_rumble_timers_2", smlua_func_reset_rumble_timers_2); // save_file.h smlua_bind_function(L, "save_file_get_cap_pos", smlua_func_save_file_get_cap_pos); @@ -8778,9 +8854,13 @@ void smlua_bind_functions_autogen(void) { // smlua_collision_utils.h smlua_bind_function(L, "collision_find_surface_on_ray", smlua_func_collision_find_surface_on_ray); + smlua_bind_function(L, "get_water_surface_pseudo_floor", smlua_func_get_water_surface_pseudo_floor); // smlua_misc_utils.h smlua_bind_function(L, "allocate_mario_action", smlua_func_allocate_mario_action); + smlua_bind_function(L, "get_hand_foot_pos_x", smlua_func_get_hand_foot_pos_x); + smlua_bind_function(L, "get_hand_foot_pos_y", smlua_func_get_hand_foot_pos_y); + smlua_bind_function(L, "get_hand_foot_pos_z", smlua_func_get_hand_foot_pos_z); 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); diff --git a/src/pc/lua/utils/smlua_collision_utils.c b/src/pc/lua/utils/smlua_collision_utils.c index 1898549b..f1c5ef71 100644 --- a/src/pc/lua/utils/smlua_collision_utils.c +++ b/src/pc/lua/utils/smlua_collision_utils.c @@ -1,6 +1,7 @@ #include "types.h" #include "src/engine/surface_collision.h" +#include "game/mario_step.h" #include "pc/lua/smlua.h" #include "smlua_collision_utils.h" @@ -160,3 +161,7 @@ struct RayIntersectionInfo* collision_find_surface_on_ray(f32 startX, f32 startY find_surface_on_ray(orig, end, &info.surface, info.hitPos); return &info; } + +struct Surface* get_water_surface_pseudo_floor(void) { + return &gWaterSurfacePseudoFloor; +} diff --git a/src/pc/lua/utils/smlua_collision_utils.h b/src/pc/lua/utils/smlua_collision_utils.h index 39c0dda5..6ac1f61b 100644 --- a/src/pc/lua/utils/smlua_collision_utils.h +++ b/src/pc/lua/utils/smlua_collision_utils.h @@ -112,4 +112,6 @@ extern struct GlobalObjectCollisionData gGlobalObjectCollisionData; struct RayIntersectionInfo* collision_find_surface_on_ray(f32 startX, f32 startY, f32 startZ, f32 endX, f32 endY, f32 endZ); +struct Surface* get_water_surface_pseudo_floor(void); + #endif diff --git a/src/pc/lua/utils/smlua_misc_utils.c b/src/pc/lua/utils/smlua_misc_utils.c index 0b786268..bb6bb986 100644 --- a/src/pc/lua/utils/smlua_misc_utils.c +++ b/src/pc/lua/utils/smlua_misc_utils.c @@ -38,4 +38,19 @@ bool warp_to_castle(s32 aLevel) { u32 allocate_mario_action(u32 actFlags) { actFlags = actFlags & (~((u32)0xFF)); return actFlags | ACT_FLAG_CUSTOM_ACTION | gLuaMarioActionIndex++; -} \ No newline at end of file +} + +f32 get_hand_foot_pos_x(struct MarioState* m, u8 index) { + if (index >= 4) { index = 0; } + return m->marioBodyState->handFootPos[index][0]; +} + +f32 get_hand_foot_pos_y(struct MarioState* m, u8 index) { + if (index >= 4) { index = 0; } + return m->marioBodyState->handFootPos[index][1]; +} + +f32 get_hand_foot_pos_z(struct MarioState* m, u8 index) { + if (index >= 4) { index = 0; } + return m->marioBodyState->handFootPos[index][2]; +} diff --git a/src/pc/lua/utils/smlua_misc_utils.h b/src/pc/lua/utils/smlua_misc_utils.h index 5fdd83ed..a44064f1 100644 --- a/src/pc/lua/utils/smlua_misc_utils.h +++ b/src/pc/lua/utils/smlua_misc_utils.h @@ -13,4 +13,8 @@ bool warp_to_castle(s32 aLevel); u32 allocate_mario_action(u32 actFlags); +f32 get_hand_foot_pos_x(struct MarioState* m, u8 index); +f32 get_hand_foot_pos_y(struct MarioState* m, u8 index); +f32 get_hand_foot_pos_z(struct MarioState* m, u8 index); + #endif diff --git a/src/pc/lua/utils/smlua_obj_utils.c b/src/pc/lua/utils/smlua_obj_utils.c index 6bfc351e..a4237c9b 100644 --- a/src/pc/lua/utils/smlua_obj_utils.c +++ b/src/pc/lua/utils/smlua_obj_utils.c @@ -9,8 +9,10 @@ #include "pc/debuglog.h" static struct Object* spawn_object_internal(enum BehaviorId behaviorId, enum ModelExtendedId modelId, f32 x, f32 y, f32 z, LuaFunction objSetupFunction, bool doSync) { - // prevent spawning objects before area is synchronized - if (gNetworkPlayerLocal == NULL || !gNetworkPlayerLocal->currAreaSyncValid) { return NULL; } + if (doSync) { + // prevent spawning objects before area is synchronized + if (gNetworkPlayerLocal == NULL || !gNetworkPlayerLocal->currAreaSyncValid) { return NULL; } + } const BehaviorScript* behavior = get_behavior_from_id(behaviorId); if (behavior == NULL) { diff --git a/src/pc/network/packets/packet_sync_valid.c b/src/pc/network/packets/packet_sync_valid.c index 710c1f5a..c7967bb1 100644 --- a/src/pc/network/packets/packet_sync_valid.c +++ b/src/pc/network/packets/packet_sync_valid.c @@ -5,15 +5,17 @@ #include "pc/debuglog.h" void network_send_sync_valid(struct NetworkPlayer* toNp, s16 courseNum, s16 actNum, s16 levelNum, s16 areaIndex) { - if (toNp == gNetworkPlayerLocal && !toNp->currAreaSyncValid) { - network_player_update_course_level(toNp, courseNum, actNum, levelNum, areaIndex); - smlua_call_event_hooks(HOOK_ON_SYNC_VALID); - } + bool wasAreaSyncValid = toNp->currAreaSyncValid; // set the NetworkPlayers sync valid toNp->currLevelSyncValid = true; toNp->currAreaSyncValid = true; + if (toNp == gNetworkPlayerLocal && !wasAreaSyncValid) { + network_player_update_course_level(toNp, courseNum, actNum, levelNum, areaIndex); + smlua_call_event_hooks(HOOK_ON_SYNC_VALID); + } + if (gNetworkType == NT_SERVER && toNp == gNetworkPlayerLocal) { // the player is the server, no need to send sync valid gNetworkAreaSyncing = false; @@ -61,14 +63,15 @@ void network_receive_sync_valid(struct Packet* p) { return; } - if (np == gNetworkPlayerLocal && !np->currAreaSyncValid) { + bool wasAreaSyncValid = np->currAreaSyncValid; + np->currLevelSyncValid = true; + np->currAreaSyncValid = true; + + if (np == gNetworkPlayerLocal && !wasAreaSyncValid) { network_player_update_course_level(np, courseNum, actNum, levelNum, areaIndex); smlua_call_event_hooks(HOOK_ON_SYNC_VALID); } - np->currLevelSyncValid = true; - np->currAreaSyncValid = true; - // inform server if (fromGlobalIndex != gNetworkPlayerServer->globalIndex) { LOG_INFO("informing server of sync valid");