From 6e4c39eabed35f1ccdd96f6afe71b6198a3a1b70 Mon Sep 17 00:00:00 2001 From: MysterD Date: Wed, 12 Aug 2020 19:39:31 -0700 Subject: [PATCH] Kept more randomness, fixing tree leaves, fix pole segfault --- src/engine/behavior_script.c | 10 +++++++++- src/game/behaviors/tree_particles.inc.c | 3 ++- src/game/mario_actions_automatic.c | 10 ++++++++++ src/game/object_helpers.c | 25 +++++++++++++++++++++++++ src/game/object_helpers.h | 1 + 5 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/engine/behavior_script.c b/src/engine/behavior_script.c index bc615156..3faa8faa 100644 --- a/src/engine/behavior_script.c +++ b/src/engine/behavior_script.c @@ -30,6 +30,7 @@ #define BHV_CMD_GET_ADDR_OF_CMD(index) (uintptr_t)(&gCurBhvCommand[index]) static u16 gRandomSeed16; +static u16 gSavedSeed16; // Unused function that directly jumps to a behavior command and resets the object's stack index. static void goto_behavior_unused(const BehaviorScript *bhvAddr) { @@ -39,7 +40,6 @@ static void goto_behavior_unused(const BehaviorScript *bhvAddr) { void force_replicable_seed(u8 always) { // force the seed to consistent values - extern u16 gRandomSeed16; extern u32 gGlobalTimer; static u32 lastTimer = 0; static f32 lastPos[3] = { 0 }; @@ -48,6 +48,7 @@ void force_replicable_seed(u8 always) { && lastPos[1] == gCurrentObject->oPosY / 10 && lastPos[2] == gCurrentObject->oPosZ / 10 && !always) { + gSavedSeed16 = 0; return; } gRandomSeed16 = (u16)(gCurrentObject->oPosX / 1000.0f) @@ -63,10 +64,17 @@ void force_replicable_seed(u8 always) { // Generate a pseudorandom integer from 0 to 65535 from the random seed, and update the seed. u16 random_u16(void) { + // restore random seed when applicable + if (gSavedSeed16 != 0) { + gRandomSeed16 = gSavedSeed16; + gSavedSeed16 = 0; + } + // override this function for synchronized entities if (gCurrentObject->oSyncID != 0) { struct SyncObject* so = &syncObjects[gCurrentObject->oSyncID]; if (so->o != NULL && !so->keepRandomSeed) { + gSavedSeed16 = gRandomSeed16; force_replicable_seed(FALSE); } } diff --git a/src/game/behaviors/tree_particles.inc.c b/src/game/behaviors/tree_particles.inc.c index 6c5587ff..6202a5d1 100644 --- a/src/game/behaviors/tree_particles.inc.c +++ b/src/game/behaviors/tree_particles.inc.c @@ -37,7 +37,8 @@ void bhv_snow_leaf_particle_spawn_init(void) { s32 isSnow; f32 scale; UNUSED s32 unused2; - gMarioObject->oActiveParticleFlags &= ~0x2000; + struct Object* player = nearest_player_to_object(o); + player->oActiveParticleFlags &= ~0x2000; if (gCurrLevelNum == LEVEL_CCM || gCurrLevelNum == LEVEL_SL) isSnow = 1; else diff --git a/src/game/mario_actions_automatic.c b/src/game/mario_actions_automatic.c index 47d113c9..5b061c91 100644 --- a/src/game/mario_actions_automatic.c +++ b/src/game/mario_actions_automatic.c @@ -56,6 +56,8 @@ void play_climbing_sounds(struct MarioState *m, s32 b) { } s32 set_pole_position(struct MarioState *m, f32 offsetY) { + if (m->usedObj == NULL) { m->usedObj = cur_obj_find_nearest_pole(); } + UNUSED s32 unused1; UNUSED s32 unused2; UNUSED s32 unused3; @@ -114,6 +116,7 @@ s32 set_pole_position(struct MarioState *m, f32 offsetY) { s32 act_holding_pole(struct MarioState *m) { struct Object *marioObj = m->marioObj; + if (m->usedObj == NULL) { m->usedObj = cur_obj_find_nearest_pole(); } #ifdef VERSION_JP if (m->input & INPUT_A_PRESSED) { @@ -186,6 +189,7 @@ s32 act_holding_pole(struct MarioState *m) { } s32 act_climbing_pole(struct MarioState *m) { + if (m->usedObj == NULL) { m->usedObj = cur_obj_find_nearest_pole(); } s32 sp24; struct Object *marioObj = m->marioObj; s16 cameraAngle = m->area->camera->yaw; @@ -223,6 +227,7 @@ s32 act_climbing_pole(struct MarioState *m) { } s32 act_grab_pole_slow(struct MarioState *m) { + if (m->usedObj == NULL) { m->usedObj = cur_obj_find_nearest_pole(); } play_sound_if_no_flag(m, SOUND_MARIO_WHOA, MARIO_MARIO_SOUND_PLAYED); if (set_pole_position(m, 0.0f) == POLE_NONE) { @@ -238,6 +243,7 @@ s32 act_grab_pole_slow(struct MarioState *m) { s32 act_grab_pole_fast(struct MarioState *m) { struct Object *marioObj = m->marioObj; + if (m->usedObj == NULL) { m->usedObj = cur_obj_find_nearest_pole(); } play_sound_if_no_flag(m, SOUND_MARIO_WHOA, MARIO_MARIO_SOUND_PLAYED); m->faceAngle[1] += marioObj->oMarioPoleYawVel; @@ -261,6 +267,7 @@ s32 act_grab_pole_fast(struct MarioState *m) { s32 act_top_of_pole_transition(struct MarioState *m) { struct Object *marioObj = m->marioObj; + if (m->usedObj == NULL) { m->usedObj = cur_obj_find_nearest_pole(); } marioObj->oMarioPoleYawVel = 0; if (m->actionArg == 0) { @@ -281,6 +288,7 @@ s32 act_top_of_pole_transition(struct MarioState *m) { s32 act_top_of_pole(struct MarioState *m) { UNUSED struct Object *marioObj = m->marioObj; + if (m->usedObj == NULL) { m->usedObj = cur_obj_find_nearest_pole(); } if (m->input & INPUT_A_PRESSED) { return set_mario_action(m, ACT_TOP_OF_POLE_JUMP, 0); @@ -761,6 +769,8 @@ s32 act_in_cannon(struct MarioState *m) { } s32 act_tornado_twirling(struct MarioState *m) { + if (m->usedObj = NULL) { return; } + struct Surface *floor; Vec3f nextPos; f32 sinAngleVel; diff --git a/src/game/object_helpers.c b/src/game/object_helpers.c index d8407347..44309065 100644 --- a/src/game/object_helpers.c +++ b/src/game/object_helpers.c @@ -865,6 +865,31 @@ f32 cur_obj_dist_to_nearest_object_with_behavior(const BehaviorScript *behavior) return dist; } +struct Object* cur_obj_find_nearest_pole(void) { + struct Object* closestObj = NULL; + struct Object* obj; + struct ObjectNode* listHead; + f32 minDist = 0x20000; + + listHead = &gObjectLists[OBJ_LIST_POLELIKE]; + obj = (struct Object*) listHead->next; + + while (obj != (struct Object*) listHead) { + if (obj->oInteractType & INTERACT_POLE) { + if (obj->activeFlags != ACTIVE_FLAG_DEACTIVATED && obj != o) { + f32 objDist = dist_between_objects(o, obj); + if (objDist < minDist) { + closestObj = obj; + minDist = objDist; + } + } + } + obj = (struct Object*) obj->header.next; + } + + return closestObj; +} + struct Object *cur_obj_find_nearest_object_with_behavior(const BehaviorScript *behavior, f32 *dist) { uintptr_t *behaviorAddr = segmented_to_virtual(behavior); struct Object *closestObj = NULL; diff --git a/src/game/object_helpers.h b/src/game/object_helpers.h index 80955162..b45baf98 100644 --- a/src/game/object_helpers.h +++ b/src/game/object_helpers.h @@ -139,6 +139,7 @@ void obj_set_face_angle_to_move_angle(struct Object *obj); u32 get_object_list_from_behavior(const BehaviorScript *behavior); struct Object *cur_obj_nearest_object_with_behavior(const BehaviorScript *behavior); f32 cur_obj_dist_to_nearest_object_with_behavior(const BehaviorScript* behavior); +struct Object* cur_obj_find_nearest_pole(void); struct Object *cur_obj_find_nearest_object_with_behavior(const BehaviorScript * behavior, f32 *dist); struct Object *find_unimportant_object(void); s32 count_unimportant_objects(void);