Kept more randomness, fixing tree leaves, fix pole segfault

This commit is contained in:
MysterD 2020-08-12 19:39:31 -07:00
parent 48f42d1873
commit 6e4c39eabe
5 changed files with 47 additions and 2 deletions

View File

@ -30,6 +30,7 @@
#define BHV_CMD_GET_ADDR_OF_CMD(index) (uintptr_t)(&gCurBhvCommand[index]) #define BHV_CMD_GET_ADDR_OF_CMD(index) (uintptr_t)(&gCurBhvCommand[index])
static u16 gRandomSeed16; static u16 gRandomSeed16;
static u16 gSavedSeed16;
// Unused function that directly jumps to a behavior command and resets the object's stack index. // Unused function that directly jumps to a behavior command and resets the object's stack index.
static void goto_behavior_unused(const BehaviorScript *bhvAddr) { 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) { void force_replicable_seed(u8 always) {
// force the seed to consistent values // force the seed to consistent values
extern u16 gRandomSeed16;
extern u32 gGlobalTimer; extern u32 gGlobalTimer;
static u32 lastTimer = 0; static u32 lastTimer = 0;
static f32 lastPos[3] = { 0 }; static f32 lastPos[3] = { 0 };
@ -48,6 +48,7 @@ void force_replicable_seed(u8 always) {
&& lastPos[1] == gCurrentObject->oPosY / 10 && lastPos[1] == gCurrentObject->oPosY / 10
&& lastPos[2] == gCurrentObject->oPosZ / 10 && lastPos[2] == gCurrentObject->oPosZ / 10
&& !always) { && !always) {
gSavedSeed16 = 0;
return; return;
} }
gRandomSeed16 = (u16)(gCurrentObject->oPosX / 1000.0f) 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. // Generate a pseudorandom integer from 0 to 65535 from the random seed, and update the seed.
u16 random_u16(void) { u16 random_u16(void) {
// restore random seed when applicable
if (gSavedSeed16 != 0) {
gRandomSeed16 = gSavedSeed16;
gSavedSeed16 = 0;
}
// override this function for synchronized entities // override this function for synchronized entities
if (gCurrentObject->oSyncID != 0) { if (gCurrentObject->oSyncID != 0) {
struct SyncObject* so = &syncObjects[gCurrentObject->oSyncID]; struct SyncObject* so = &syncObjects[gCurrentObject->oSyncID];
if (so->o != NULL && !so->keepRandomSeed) { if (so->o != NULL && !so->keepRandomSeed) {
gSavedSeed16 = gRandomSeed16;
force_replicable_seed(FALSE); force_replicable_seed(FALSE);
} }
} }

View File

@ -37,7 +37,8 @@ void bhv_snow_leaf_particle_spawn_init(void) {
s32 isSnow; s32 isSnow;
f32 scale; f32 scale;
UNUSED s32 unused2; UNUSED s32 unused2;
gMarioObject->oActiveParticleFlags &= ~0x2000; struct Object* player = nearest_player_to_object(o);
player->oActiveParticleFlags &= ~0x2000;
if (gCurrLevelNum == LEVEL_CCM || gCurrLevelNum == LEVEL_SL) if (gCurrLevelNum == LEVEL_CCM || gCurrLevelNum == LEVEL_SL)
isSnow = 1; isSnow = 1;
else else

View File

@ -56,6 +56,8 @@ void play_climbing_sounds(struct MarioState *m, s32 b) {
} }
s32 set_pole_position(struct MarioState *m, f32 offsetY) { 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 unused1;
UNUSED s32 unused2; UNUSED s32 unused2;
UNUSED s32 unused3; UNUSED s32 unused3;
@ -114,6 +116,7 @@ s32 set_pole_position(struct MarioState *m, f32 offsetY) {
s32 act_holding_pole(struct MarioState *m) { s32 act_holding_pole(struct MarioState *m) {
struct Object *marioObj = m->marioObj; struct Object *marioObj = m->marioObj;
if (m->usedObj == NULL) { m->usedObj = cur_obj_find_nearest_pole(); }
#ifdef VERSION_JP #ifdef VERSION_JP
if (m->input & INPUT_A_PRESSED) { if (m->input & INPUT_A_PRESSED) {
@ -186,6 +189,7 @@ s32 act_holding_pole(struct MarioState *m) {
} }
s32 act_climbing_pole(struct MarioState *m) { s32 act_climbing_pole(struct MarioState *m) {
if (m->usedObj == NULL) { m->usedObj = cur_obj_find_nearest_pole(); }
s32 sp24; s32 sp24;
struct Object *marioObj = m->marioObj; struct Object *marioObj = m->marioObj;
s16 cameraAngle = m->area->camera->yaw; 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) { 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); play_sound_if_no_flag(m, SOUND_MARIO_WHOA, MARIO_MARIO_SOUND_PLAYED);
if (set_pole_position(m, 0.0f) == POLE_NONE) { 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) { s32 act_grab_pole_fast(struct MarioState *m) {
struct Object *marioObj = m->marioObj; 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); play_sound_if_no_flag(m, SOUND_MARIO_WHOA, MARIO_MARIO_SOUND_PLAYED);
m->faceAngle[1] += marioObj->oMarioPoleYawVel; 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) { s32 act_top_of_pole_transition(struct MarioState *m) {
struct Object *marioObj = m->marioObj; struct Object *marioObj = m->marioObj;
if (m->usedObj == NULL) { m->usedObj = cur_obj_find_nearest_pole(); }
marioObj->oMarioPoleYawVel = 0; marioObj->oMarioPoleYawVel = 0;
if (m->actionArg == 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) { s32 act_top_of_pole(struct MarioState *m) {
UNUSED struct Object *marioObj = m->marioObj; UNUSED struct Object *marioObj = m->marioObj;
if (m->usedObj == NULL) { m->usedObj = cur_obj_find_nearest_pole(); }
if (m->input & INPUT_A_PRESSED) { if (m->input & INPUT_A_PRESSED) {
return set_mario_action(m, ACT_TOP_OF_POLE_JUMP, 0); 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) { s32 act_tornado_twirling(struct MarioState *m) {
if (m->usedObj = NULL) { return; }
struct Surface *floor; struct Surface *floor;
Vec3f nextPos; Vec3f nextPos;
f32 sinAngleVel; f32 sinAngleVel;

View File

@ -865,6 +865,31 @@ f32 cur_obj_dist_to_nearest_object_with_behavior(const BehaviorScript *behavior)
return dist; 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) { struct Object *cur_obj_find_nearest_object_with_behavior(const BehaviorScript *behavior, f32 *dist) {
uintptr_t *behaviorAddr = segmented_to_virtual(behavior); uintptr_t *behaviorAddr = segmented_to_virtual(behavior);
struct Object *closestObj = NULL; struct Object *closestObj = NULL;

View File

@ -139,6 +139,7 @@ void obj_set_face_angle_to_move_angle(struct Object *obj);
u32 get_object_list_from_behavior(const BehaviorScript *behavior); u32 get_object_list_from_behavior(const BehaviorScript *behavior);
struct Object *cur_obj_nearest_object_with_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); 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 *cur_obj_find_nearest_object_with_behavior(const BehaviorScript * behavior, f32 *dist);
struct Object *find_unimportant_object(void); struct Object *find_unimportant_object(void);
s32 count_unimportant_objects(void); s32 count_unimportant_objects(void);