Added new MAXIMUM type to network area timer system. Exclamation boxes now reappear at the correct time

This commit is contained in:
MysterD 2021-08-12 18:13:41 -07:00
parent 383feba3b1
commit 7e59d34939
15 changed files with 68 additions and 24 deletions

1
.gitignore vendored
View file

@ -86,6 +86,7 @@ build-windows-visual-studio/.vs
# misc
todo.txt
todo-old.txt
# luigi sounds
sound/samples/sfx_custom_luigi*/*.aiff

View file

@ -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(),

View file

@ -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;
};

View file

@ -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;

View file

@ -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; }
}

View file

@ -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);

View file

@ -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) {

View file

@ -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;
}
/**

View file

@ -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) {

View file

@ -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) {

View file

@ -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);
}

View file

@ -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) {

View file

@ -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) {

View file

@ -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) {

View file

@ -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;
}