From 7e59d34939236746c438a60d2dc1b1862a8b9fdf Mon Sep 17 00:00:00 2001 From: MysterD Date: Thu, 12 Aug 2021 18:13:41 -0700 Subject: [PATCH] Added new MAXIMUM type to network area timer system. Exclamation boxes now reappear at the correct time --- .gitignore | 1 + data/behavior_data.c | 1 + include/types.h | 9 +++++- src/engine/behavior_script.c | 32 ++++++++++++++----- src/engine/surface_load.c | 2 +- src/game/behavior_actions.h | 1 + src/game/behaviors/bomp.inc.c | 6 ++-- src/game/behaviors/bowser_puzzle_piece.inc.c | 3 +- .../behaviors/checkerboard_platform.inc.c | 3 +- src/game/behaviors/ddd_pole.inc.c | 4 ++- src/game/behaviors/exclamation_box.inc.c | 16 +++++++--- src/game/behaviors/rotating_platform.inc.c | 3 +- src/game/behaviors/sliding_platform.inc.c | 4 ++- src/game/behaviors/tower_platform.inc.c | 3 +- src/game/spawn_object.c | 4 ++- 15 files changed, 68 insertions(+), 24 deletions(-) diff --git a/.gitignore b/.gitignore index 871d913d..8b8760e8 100644 --- a/.gitignore +++ b/.gitignore @@ -86,6 +86,7 @@ build-windows-visual-studio/.vs # misc todo.txt +todo-old.txt # luigi sounds sound/samples/sfx_custom_luigi*/*.aiff diff --git a/data/behavior_data.c b/data/behavior_data.c index 0cb07397..44a9a4b8 100644 --- a/data/behavior_data.c +++ b/data/behavior_data.c @@ -2853,6 +2853,7 @@ const BehaviorScript bhvExclamationBox[] = { OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), SET_FLOAT(oCollisionDistance, 300), SET_HOME(), + CALL_NATIVE(bhv_exclamation_box_init), BEGIN_LOOP(), CALL_NATIVE(bhv_exclamation_box_loop), END_LOOP(), diff --git a/include/types.h b/include/types.h index 8281c7ae..d06a0503 100644 --- a/include/types.h +++ b/include/types.h @@ -62,6 +62,12 @@ enum SpTaskState { SPTASK_STATE_FINISHED_DP }; +enum AreaTimerType { + AREA_TIMER_TYPE_NONE, + AREA_TIMER_TYPE_LOOP, + AREA_TIMER_TYPE_MAXIMUM, +}; + struct SPTask { /*0x00*/ OSTask task; @@ -221,8 +227,9 @@ struct Object /*0x21C*/ Mat4 transform; /*0x25C*/ void *respawnInfo; /*?????*/ u8 createdThroughNetwork; + /*?????*/ enum AreaTimerType areaTimerType; /*?????*/ u32 areaTimer; - /*?????*/ u32 areaTimerLoopLength; + /*?????*/ u32 areaTimerDuration; /*?????*/ u8 globalPlayerIndex; }; diff --git a/src/engine/behavior_script.c b/src/engine/behavior_script.c index aa6cb80c..bf63c735 100644 --- a/src/engine/behavior_script.c +++ b/src/engine/behavior_script.c @@ -952,22 +952,38 @@ static BhvCommandProc BehaviorCmdTable[] = { // Execute the behavior script of the current object, process the object flags, and other miscellaneous code for updating objects. void cur_obj_update(void) { // handle network area timer - if (gCurrentObject->areaTimerLoopLength > 0) { + if (gCurrentObject->areaTimerType != AREA_TIMER_TYPE_NONE) { // make sure the area is valid if (gNetworkPlayerLocal == NULL || !gNetworkPlayerLocal->currAreaSyncValid) { return; } // catch up the timer in total loop increments - u32 difference = (gNetworkAreaTimer - gCurrentObject->areaTimer); - if (difference >= gCurrentObject->areaTimerLoopLength) { - u32 catchup = difference / gCurrentObject->areaTimerLoopLength; - catchup *= gCurrentObject->areaTimerLoopLength; - gCurrentObject->areaTimer += catchup; + if (gCurrentObject->areaTimerType == AREA_TIMER_TYPE_LOOP) { + assert(gCurrentObject->areaTimerDuration > 0); + u32 difference = (gNetworkAreaTimer - gCurrentObject->areaTimer); + if (difference >= gCurrentObject->areaTimerDuration) { + u32 catchup = difference / gCurrentObject->areaTimerDuration; + catchup *= gCurrentObject->areaTimerDuration; + gCurrentObject->areaTimer += catchup; + } + } + + // catch up the timer for maximum + if (gCurrentObject->areaTimerType == AREA_TIMER_TYPE_MAXIMUM) { + assert(gCurrentObject->areaTimerDuration > 0); + u32 difference = (gNetworkAreaTimer - gCurrentObject->areaTimer); + if (difference >= gCurrentObject->areaTimerDuration) { + if (gCurrentObject->areaTimer < 10) { + gCurrentObject->areaTimer = gNetworkAreaTimer; + } else { + gCurrentObject->areaTimer = (gNetworkAreaTimer - gCurrentObject->areaTimerDuration); + } + } } // cancel object update if it's running faster than the timer - if (gCurrentObject->areaTimer >= gNetworkAreaTimer) { + if (gCurrentObject->areaTimer > gNetworkAreaTimer) { return; } } @@ -1076,7 +1092,7 @@ cur_obj_update_begin:; } // update network area timer - if (gCurrentObject->areaTimerLoopLength > 0) { + if (gCurrentObject->areaTimerType != AREA_TIMER_TYPE_NONE) { gCurrentObject->areaTimer++; if (gCurrentObject->areaTimer < gNetworkAreaTimer) { goto cur_obj_update_begin; diff --git a/src/engine/surface_load.c b/src/engine/surface_load.c index 79806512..947f1ab4 100644 --- a/src/engine/surface_load.c +++ b/src/engine/surface_load.c @@ -762,7 +762,7 @@ void load_object_surfaces(s16** data, s16* vertexData) { * Transform an object's vertices, reload them, and render the object. */ void load_object_collision_model(void) { - if (gCurrentObject->areaTimerLoopLength > 0) { + if (gCurrentObject->areaTimerType != AREA_TIMER_TYPE_NONE) { // only load collision model on last frame if (!cur_obj_is_last_nat_update_per_frame()) { return; } } diff --git a/src/game/behavior_actions.h b/src/game/behavior_actions.h index 26d77ea9..7d358ede 100644 --- a/src/game/behavior_actions.h +++ b/src/game/behavior_actions.h @@ -214,6 +214,7 @@ void bhv_fish_loop(void); void bhv_wdw_express_elevator_loop(void); void bhv_bub_spawner_loop(void); void bhv_bub_loop(void); +void bhv_exclamation_box_init(void); void bhv_exclamation_box_loop(void); void bhv_rotating_exclamation_box_loop(void); void bhv_sound_spawner_init(void); diff --git a/src/game/behaviors/bomp.inc.c b/src/game/behaviors/bomp.inc.c index 33b60c63..3b725a0a 100644 --- a/src/game/behaviors/bomp.inc.c +++ b/src/game/behaviors/bomp.inc.c @@ -4,8 +4,9 @@ void bhv_small_bomp_init(void) { o->oFaceAngleYaw -= 0x4000; o->oSmallBompInitX = o->oPosX; o->oTimer = position_based_random_float_position() * 100.0f; + o->areaTimerType = AREA_TIMER_TYPE_LOOP; o->areaTimer = 0; - o->areaTimerLoopLength = 168; + o->areaTimerDuration = 168; } void bhv_small_bomp_loop(void) { @@ -62,8 +63,9 @@ void bhv_small_bomp_loop(void) { void bhv_large_bomp_init(void) { o->oMoveAngleYaw += 0x4000; o->oTimer = position_based_random_float_position() * 100.0f; + o->areaTimerType = AREA_TIMER_TYPE_LOOP; o->areaTimer = 0; - o->areaTimerLoopLength = 168; + o->areaTimerDuration = 168; } void bhv_large_bomp_loop(void) { diff --git a/src/game/behaviors/bowser_puzzle_piece.inc.c b/src/game/behaviors/bowser_puzzle_piece.inc.c index b3e8969c..f151435a 100644 --- a/src/game/behaviors/bowser_puzzle_piece.inc.c +++ b/src/game/behaviors/bowser_puzzle_piece.inc.c @@ -95,8 +95,9 @@ void bhv_lll_bowser_puzzle_spawn_piece(s16 model, const BehaviorScript *behavior puzzlePiece->oBowserPuzzlePieceActionList = actionList; puzzlePiece->oBowserPuzzlePieceNextAction = actionList; puzzlePiece->oTimer = 0; + puzzlePiece->areaTimerType = AREA_TIMER_TYPE_LOOP; puzzlePiece->areaTimer = 0; - puzzlePiece->areaTimerLoopLength = 650; + puzzlePiece->areaTimerDuration = 650; } /** diff --git a/src/game/behaviors/checkerboard_platform.inc.c b/src/game/behaviors/checkerboard_platform.inc.c index 4d317f2a..b45a35c8 100644 --- a/src/game/behaviors/checkerboard_platform.inc.c +++ b/src/game/behaviors/checkerboard_platform.inc.c @@ -50,8 +50,9 @@ void checkerboard_plat_act_rotate(s32 a0, s16 a1) { void bhv_checkerboard_platform_init(void) { o->oCheckerBoardPlatformUnkFC = o->parentObj->oBehParams2ndByte; + o->areaTimerType = AREA_TIMER_TYPE_LOOP; o->areaTimer = 0; - o->areaTimerLoopLength = 132 + o->oCheckerBoardPlatformUnkFC * 2; + o->areaTimerDuration = 132 + o->oCheckerBoardPlatformUnkFC * 2; } void bhv_checkerboard_platform_loop(void) { diff --git a/src/game/behaviors/ddd_pole.inc.c b/src/game/behaviors/ddd_pole.inc.c index f6f1daab..48339e1f 100644 --- a/src/game/behaviors/ddd_pole.inc.c +++ b/src/game/behaviors/ddd_pole.inc.c @@ -6,8 +6,10 @@ void bhv_ddd_pole_init(void) { o->hitboxDownOffset = 100.0f; o->oDDDPoleMaxOffset = 100.0f * o->oBehParams2ndByte; } + + o->areaTimerType = AREA_TIMER_TYPE_LOOP; o->areaTimer = 0; - o->areaTimerLoopLength = (((u16)o->oDDDPoleMaxOffset / 10) + 20) * 2; + o->areaTimerDuration = (((u16)o->oDDDPoleMaxOffset / 10) + 20) * 2; } void bhv_ddd_pole_update(void) { diff --git a/src/game/behaviors/exclamation_box.inc.c b/src/game/behaviors/exclamation_box.inc.c index 15c61c3f..e177cf11 100644 --- a/src/game/behaviors/exclamation_box.inc.c +++ b/src/game/behaviors/exclamation_box.inc.c @@ -181,12 +181,18 @@ void (*sExclamationBoxActions[])(void) = { exclamation_box_act_0, exclamation_bo exclamation_box_act_4, exclamation_box_act_5, exclamation_box_act_6 }; +void bhv_exclamation_box_init(void) { + struct SyncObject* so = network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS); + so->syncDeathEvent = FALSE; + network_init_object_field(o, &o->oExclamationBoxForce); + network_init_object_field(o, &o->areaTimer); + + o->areaTimerType = AREA_TIMER_TYPE_MAXIMUM; + o->areaTimer = 0; + o->areaTimerDuration = 300; +} + void bhv_exclamation_box_loop(void) { - if (!network_sync_object_initialized(o)) { - struct SyncObject* so = network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS); - so->syncDeathEvent = FALSE; - network_init_object_field(o, &o->oExclamationBoxForce); - } cur_obj_scale(2.0f); cur_obj_call_action_function(sExclamationBoxActions); } diff --git a/src/game/behaviors/rotating_platform.inc.c b/src/game/behaviors/rotating_platform.inc.c index 5df52345..3bf4b5f9 100644 --- a/src/game/behaviors/rotating_platform.inc.c +++ b/src/game/behaviors/rotating_platform.inc.c @@ -9,8 +9,9 @@ struct WFRotatingPlatformData sWFRotatingPlatformData[] = { }; void bhv_wf_rotating_wooden_platform_init(void) { + o->areaTimerType = AREA_TIMER_TYPE_LOOP; o->areaTimer = 0; - o->areaTimerLoopLength = 380; + o->areaTimerDuration = 380; } void bhv_wf_rotating_wooden_platform_loop(void) { diff --git a/src/game/behaviors/sliding_platform.inc.c b/src/game/behaviors/sliding_platform.inc.c index 3ec8728f..e8f126b3 100644 --- a/src/game/behaviors/sliding_platform.inc.c +++ b/src/game/behaviors/sliding_platform.inc.c @@ -20,8 +20,10 @@ void bhv_wf_sliding_platform_init(void) { } o->oTimer = position_based_random_float_position() * 100.0f; + + o->areaTimerType = AREA_TIMER_TYPE_LOOP; o->areaTimer = 0; - o->areaTimerLoopLength = 152; + o->areaTimerDuration = 152; } void bhv_wf_sliding_platform_loop(void) { diff --git a/src/game/behaviors/tower_platform.inc.c b/src/game/behaviors/tower_platform.inc.c index 7e5e1c00..7c3d25e4 100644 --- a/src/game/behaviors/tower_platform.inc.c +++ b/src/game/behaviors/tower_platform.inc.c @@ -97,8 +97,9 @@ void spawn_and_init_wf_platforms(s16 a, const BehaviorScript *bhv) { u32 loopTime = 1 + (platform->oPlatformUnk110 / platform->oPlatformUnk10C); loopTime *= 2; loopTime += 1; + platform->areaTimerType = AREA_TIMER_TYPE_LOOP; platform->areaTimer = 0; - platform->areaTimerLoopLength = loopTime; + platform->areaTimerDuration = loopTime; } void spawn_wf_platform_group(void) { diff --git a/src/game/spawn_object.c b/src/game/spawn_object.c index 11773d00..3888792d 100644 --- a/src/game/spawn_object.c +++ b/src/game/spawn_object.c @@ -305,8 +305,10 @@ struct Object *allocate_object(struct ObjectNode *objList) { obj->header.gfx.throwMatrix = NULL; obj->createdThroughNetwork = false; + + obj->areaTimerType = AREA_TIMER_TYPE_NONE; obj->areaTimer = 0; - obj->areaTimerLoopLength = 0; + obj->areaTimerDuration = 0; return obj; }