Prevented SM64 hang on object count overflow

This commit is contained in:
MysterD 2022-02-22 01:10:17 -08:00
parent 94bc7940cc
commit 1131fb02db
75 changed files with 503 additions and 312 deletions

View file

@ -384,7 +384,7 @@
// group 9 // group 9
#define MODEL_BOO 0x54 // boo_geo #define MODEL_BOO 0x54 // boo_geo
#define MODEL_BETA_BOO_KEY 0x55 // small_key_geo #define MODEL_BETA_BOO_KEY 0x55 // small_key_geo
#define MODEL_HAUNTED_CHAIR 0x56 // haunted_chair_geo #define MODEL_HAUNTED_CHAIR 0x56 // haunted_chair_geo
#define MODEL_MAD_PIANO 0x57 // mad_piano_geo #define MODEL_MAD_PIANO 0x57 // mad_piano_geo
#define MODEL_BOOKEND_PART 0x58 // bookend_part_geo #define MODEL_BOOKEND_PART 0x58 // bookend_part_geo
@ -561,7 +561,7 @@
#define MODEL_PEACH 0xDE // peach_geo #define MODEL_PEACH 0xDE // peach_geo
#define MODEL_CHUCKYA 0xDF // chuckya_geo #define MODEL_CHUCKYA 0xDF // chuckya_geo
#define MODEL_WHITE_PUFF 0xE0 // white_puff_geo #define MODEL_WHITE_PUFF 0xE0 // white_puff_geo
#define MODEL_TRAJECTORY_MARKER_BALL 0xE1 // bowling_ball_track_geo - duplicate used in SSL Pyramid small sized and as a track ball #define MODEL_TRAJECTORY_MARKER_BALL 0xE1 // bowling_ball_track_geo - duplicate used in SSL Pyramid small sized and as a track ball
// Menu Models (overwrites Level Geometry IDs) // Menu Models (overwrites Level Geometry IDs)
#define MODEL_MAIN_MENU_MARIO_SAVE_BUTTON MODEL_LEVEL_GEOMETRY_03 // main_menu_geo_0001D0 #define MODEL_MAIN_MENU_MARIO_SAVE_BUTTON MODEL_LEVEL_GEOMETRY_03 // main_menu_geo_0001D0

View file

@ -195,7 +195,9 @@ static s32 bhv_cmd_spawn_child(void) {
const BehaviorScript *behavior = BHV_CMD_GET_VPTR(2); const BehaviorScript *behavior = BHV_CMD_GET_VPTR(2);
struct Object *child = spawn_object_at_origin(gCurrentObject, 0, model, behavior); struct Object *child = spawn_object_at_origin(gCurrentObject, 0, model, behavior);
obj_copy_pos_and_angle(child, gCurrentObject); if (child != NULL) {
obj_copy_pos_and_angle(child, gCurrentObject);
}
gCurBhvCommand += 3; gCurBhvCommand += 3;
return BHV_PROC_CONTINUE; return BHV_PROC_CONTINUE;
@ -208,9 +210,11 @@ static s32 bhv_cmd_spawn_obj(void) {
const BehaviorScript *behavior = BHV_CMD_GET_VPTR(2); const BehaviorScript *behavior = BHV_CMD_GET_VPTR(2);
struct Object *object = spawn_object_at_origin(gCurrentObject, 0, model, behavior); struct Object *object = spawn_object_at_origin(gCurrentObject, 0, model, behavior);
obj_copy_pos_and_angle(object, gCurrentObject); if (object != NULL) {
// TODO: Does this cmd need renaming? This line is the only difference between this and the above func. obj_copy_pos_and_angle(object, gCurrentObject);
gCurrentObject->prevObj = object; // TODO: Does this cmd need renaming? This line is the only difference between this and the above func.
gCurrentObject->prevObj = object;
}
gCurBhvCommand += 3; gCurBhvCommand += 3;
return BHV_PROC_CONTINUE; return BHV_PROC_CONTINUE;
@ -224,8 +228,10 @@ static s32 bhv_cmd_spawn_child_with_param(void) {
const BehaviorScript *behavior = BHV_CMD_GET_VPTR(2); const BehaviorScript *behavior = BHV_CMD_GET_VPTR(2);
struct Object *child = spawn_object_at_origin(gCurrentObject, 0, modelID, behavior); struct Object *child = spawn_object_at_origin(gCurrentObject, 0, modelID, behavior);
obj_copy_pos_and_angle(child, gCurrentObject); if (child != NULL) {
child->oBehParams2ndByte = bhvParam; obj_copy_pos_and_angle(child, gCurrentObject);
child->oBehParams2ndByte = bhvParam;
}
gCurBhvCommand += 3; gCurBhvCommand += 3;
return BHV_PROC_CONTINUE; return BHV_PROC_CONTINUE;

View file

@ -60,10 +60,14 @@ void bhv_beta_trampoline_top_loop(void) {
struct Object *trampolinePart; struct Object *trampolinePart;
trampolinePart = spawn_object(o, MODEL_TRAMPOLINE_CENTER, bhvBetaTrampolineSpring); trampolinePart = spawn_object(o, MODEL_TRAMPOLINE_CENTER, bhvBetaTrampolineSpring);
trampolinePart->oPosY -= 75.0f; if (trampolinePart != NULL) {
trampolinePart->oPosY -= 75.0f;
}
trampolinePart = spawn_object(o, MODEL_TRAMPOLINE_BASE, bhvStaticObject); trampolinePart = spawn_object(o, MODEL_TRAMPOLINE_BASE, bhvStaticObject);
trampolinePart->oPosY -= 150.0f; if (trampolinePart != NULL) {
trampolinePart->oPosY -= 150.0f;
}
} }
// Update o->oBetaTrampolineMarioOnTrampoline, and reset // Update o->oBetaTrampolineMarioOnTrampoline, and reset

View file

@ -104,6 +104,7 @@ void bhv_tank_fish_group_loop(void) {
// spawns fifteen fish and moves them within 200.0f // spawns fifteen fish and moves them within 200.0f
for (i = 0; i < 15; i++) { for (i = 0; i < 15; i++) {
fish = spawn_object_relative(0, 300, 0, -200, o, MODEL_FISH, bhvBlueFish); fish = spawn_object_relative(0, 300, 0, -200, o, MODEL_FISH, bhvBlueFish);
if (fish == NULL) { continue; }
obj_translate_xyz_random(fish, 200.0f); obj_translate_xyz_random(fish, 200.0f);
} }

View file

@ -36,7 +36,9 @@ void bobomb_act_explode(void) {
cur_obj_scale(1.0 + (f32) o->oTimer / 5.0); cur_obj_scale(1.0 + (f32) o->oTimer / 5.0);
else { else {
explosion = spawn_object(o, MODEL_EXPLOSION, bhvExplosion); explosion = spawn_object(o, MODEL_EXPLOSION, bhvExplosion);
explosion->oGraphYOffset += 100.0f; if (explosion != NULL) {
explosion->oGraphYOffset += 100.0f;
}
bobomb_spawn_coin(); bobomb_spawn_coin();
create_respawner(MODEL_BLACK_BOBOMB, bhvBobomb, 3000); create_respawner(MODEL_BLACK_BOBOMB, bhvBobomb, 3000);

View file

@ -134,7 +134,7 @@ void bhv_courtyard_boo_triplet_init(void) {
MODEL_BOO, MODEL_BOO,
bhvGhostHuntBoo bhvGhostHuntBoo
); );
if (boo == NULL) { continue; }
boo->oMoveAngleYaw = random_u16(); boo->oMoveAngleYaw = random_u16();
} }
} }
@ -841,7 +841,9 @@ void bhv_boo_with_cage_init(void) {
obj_mark_for_deletion(o); obj_mark_for_deletion(o);
} else { } else {
cage = spawn_object(o, MODEL_HAUNTED_CAGE, bhvBooCage); cage = spawn_object(o, MODEL_HAUNTED_CAGE, bhvBooCage);
cage->oBehParams = o->oBehParams; if (cage != NULL) {
cage->oBehParams = o->oBehParams;
}
} }
} }
@ -881,11 +883,12 @@ void bhv_merry_go_round_boo_manager_loop(void) {
if (o->oMerryGoRoundBooManagerNumBoosSpawned < 5) { if (o->oMerryGoRoundBooManagerNumBoosSpawned < 5) {
if (o->oMerryGoRoundBooManagerNumBoosSpawned - o->oMerryGoRoundBooManagerNumBoosKilled < 2) { if (o->oMerryGoRoundBooManagerNumBoosSpawned - o->oMerryGoRoundBooManagerNumBoosKilled < 2) {
struct Object* boo = spawn_object(o, MODEL_BOO, bhvMerryGoRoundBoo); struct Object* boo = spawn_object(o, MODEL_BOO, bhvMerryGoRoundBoo);
if (boo != NULL) {
network_set_sync_id(boo); network_set_sync_id(boo);
struct Object* spawn_objects[] = { boo }; struct Object* spawn_objects[] = { boo };
u32 models[] = { MODEL_BOO }; u32 models[] = { MODEL_BOO };
network_send_spawn_objects(spawn_objects, models, 1); network_send_spawn_objects(spawn_objects, models, 1);
}
o->oMerryGoRoundBooManagerNumBoosSpawned++; o->oMerryGoRoundBooManagerNumBoosSpawned++;
network_send_object(o); network_send_object(o);
@ -898,12 +901,14 @@ void bhv_merry_go_round_boo_manager_loop(void) {
if (o->oMerryGoRoundBooManagerNumBoosKilled > 4) { if (o->oMerryGoRoundBooManagerNumBoosKilled > 4) {
if (player == gMarioObjects[0]) { if (player == gMarioObjects[0]) {
struct Object* boo = spawn_object(o, MODEL_BOO, bhvMerryGoRoundBigBoo); struct Object* boo = spawn_object(o, MODEL_BOO, bhvMerryGoRoundBigBoo);
obj_copy_behavior_params(boo, o); if (boo != NULL) {
obj_copy_behavior_params(boo, o);
network_set_sync_id(boo); network_set_sync_id(boo);
struct Object* spawn_objects[] = { boo }; struct Object* spawn_objects[] = { boo };
u32 models[] = { MODEL_BOO }; u32 models[] = { MODEL_BOO };
network_send_spawn_objects(spawn_objects, models, 1); network_send_spawn_objects(spawn_objects, models, 1);
}
o->oAction = 2; o->oAction = 2;
network_send_object(o); network_send_object(o);

View file

@ -67,20 +67,24 @@ void bhv_big_boulder_generator_loop(void) {
if (is_point_within_radius_of_mario(o->oPosX, o->oPosY, o->oPosZ, 6000)) { if (is_point_within_radius_of_mario(o->oPosX, o->oPosY, o->oPosZ, 6000)) {
if ((o->oTimer & 0x3F) == 0) { if ((o->oTimer & 0x3F) == 0) {
sp1C = spawn_object(o, MODEL_HMC_ROLLING_ROCK, bhvBigBoulder); sp1C = spawn_object(o, MODEL_HMC_ROLLING_ROCK, bhvBigBoulder);
sp1C->oMoveAngleYaw = random_float() * 4096.0f; if (sp1C != NULL) {
sp1C->oMoveAngleYaw = random_float() * 4096.0f;
struct Object* spawn_objects[] = { sp1C }; struct Object* spawn_objects[] = { sp1C };
u32 models[] = { MODEL_HMC_ROLLING_ROCK }; u32 models[] = { MODEL_HMC_ROLLING_ROCK };
network_send_spawn_objects(spawn_objects, models, 1); network_send_spawn_objects(spawn_objects, models, 1);
}
} }
} else { } else {
if ((o->oTimer & 0x7F) == 0) { if ((o->oTimer & 0x7F) == 0) {
sp1C = spawn_object(o, MODEL_HMC_ROLLING_ROCK, bhvBigBoulder); sp1C = spawn_object(o, MODEL_HMC_ROLLING_ROCK, bhvBigBoulder);
sp1C->oMoveAngleYaw = random_float() * 4096.0f; if (sp1C != NULL) {
sp1C->oMoveAngleYaw = random_float() * 4096.0f;
struct Object* spawn_objects[] = { sp1C }; struct Object* spawn_objects[] = { sp1C };
u32 models[] = { MODEL_HMC_ROLLING_ROCK }; u32 models[] = { MODEL_HMC_ROLLING_ROCK };
network_send_spawn_objects(spawn_objects, models, 1); network_send_spawn_objects(spawn_objects, models, 1);
}
} }
} }
} }

View file

@ -55,13 +55,15 @@ void bhv_bouncing_fireball_loop(void) {
if (network_owns_object(o)) { if (network_owns_object(o)) {
sp2C = spawn_object(o, MODEL_RED_FLAME, bhvBouncingFireballFlame); sp2C = spawn_object(o, MODEL_RED_FLAME, bhvBouncingFireballFlame);
sp28 = (10 - o->oTimer) * 0.5; sp28 = (10 - o->oTimer) * 0.5;
obj_scale_xyz(sp2C, sp28, sp28, sp28); if (sp2C != NULL) {
if (o->oTimer == 0) obj_scale_xyz(sp2C, sp28, sp28, sp28);
obj_become_tangible(sp2C); if (o->oTimer == 0)
obj_become_tangible(sp2C);
struct Object* spawn_objects[] = { sp2C }; struct Object* spawn_objects[] = { sp2C };
u32 models[] = { MODEL_RED_FLAME }; u32 models[] = { MODEL_RED_FLAME };
network_send_spawn_objects(spawn_objects, models, 1); network_send_spawn_objects(spawn_objects, models, 1);
}
network_send_object(o); network_send_object(o);
} }

View file

@ -204,12 +204,14 @@ void bhv_generic_bowling_ball_spawner_loop(void) {
} }
// this branch only runs for one player at a time // this branch only runs for one player at a time
bowlingBall = spawn_object(o, MODEL_BOWLING_BALL, bhvBowlingBall); bowlingBall = spawn_object(o, MODEL_BOWLING_BALL, bhvBowlingBall);
bowlingBall->oBehParams2ndByte = o->oBehParams2ndByte; if (bowlingBall != NULL) {
bowlingBall->oBehParams2ndByte = o->oBehParams2ndByte;
// send out the bowlingBall object // send out the bowlingBall object
struct Object* spawn_objects[] = { bowlingBall }; struct Object* spawn_objects[] = { bowlingBall };
u32 models[] = { MODEL_BOWLING_BALL }; u32 models[] = { MODEL_BOWLING_BALL };
network_send_spawn_objects(spawn_objects, models, 1); network_send_spawn_objects(spawn_objects, models, 1);
}
} }
} }
} }
@ -235,12 +237,14 @@ void bhv_thi_bowling_ball_spawner_loop(void) {
if (network_owns_object(o) && (s32)(random_float() * 1.5) == 0) { if (network_owns_object(o) && (s32)(random_float() * 1.5) == 0) {
// this branch only runs for one player at a time // this branch only runs for one player at a time
bowlingBall = spawn_object(o, MODEL_BOWLING_BALL, bhvBowlingBall); bowlingBall = spawn_object(o, MODEL_BOWLING_BALL, bhvBowlingBall);
bowlingBall->oBehParams2ndByte = o->oBehParams2ndByte; if (bowlingBall != NULL) {
bowlingBall->oBehParams2ndByte = o->oBehParams2ndByte;
// send out the bowlingBall object // send out the bowlingBall object
struct Object* spawn_objects[] = { bowlingBall }; struct Object* spawn_objects[] = { bowlingBall };
u32 models[] = { MODEL_BOWLING_BALL }; u32 models[] = { MODEL_BOWLING_BALL };
network_send_spawn_objects(spawn_objects, models, 1); network_send_spawn_objects(spawn_objects, models, 1);
}
} }
} }
} }

View file

@ -87,10 +87,11 @@ void bhv_bowser_flame_spawn_loop(void) {
struct MarioState* marioState = nearest_mario_state_to_object(o); struct MarioState* marioState = nearest_mario_state_to_object(o);
if (marioState->playerIndex == 0) { if (marioState->playerIndex == 0) {
struct Object* flame = spawn_object(o, MODEL_RED_FLAME, bhvFlameMovingForwardGrowing); struct Object* flame = spawn_object(o, MODEL_RED_FLAME, bhvFlameMovingForwardGrowing);
if (flame != NULL) {
struct Object* spawn_objects[] = { flame }; struct Object* spawn_objects[] = { flame };
u32 models[] = { MODEL_RED_FLAME }; u32 models[] = { MODEL_RED_FLAME };
network_send_spawn_objects(spawn_objects, models, 1); network_send_spawn_objects(spawn_objects, models, 1);
}
} }
} }
} }
@ -135,11 +136,13 @@ s32 bowser_spawn_shockwave(void) {
struct MarioState* marioState = nearest_mario_state_to_object(o); struct MarioState* marioState = nearest_mario_state_to_object(o);
if (marioState->playerIndex == 0) { if (marioState->playerIndex == 0) {
wave = spawn_object(o, MODEL_BOWSER_WAVE, bhvBowserShockWave); wave = spawn_object(o, MODEL_BOWSER_WAVE, bhvBowserShockWave);
wave->oPosY = o->oFloorHeight; if (wave != NULL) {
wave->oPosY = o->oFloorHeight;
struct Object* spawn_objects[] = { wave }; struct Object* spawn_objects[] = { wave };
u32 models[] = { MODEL_BOWSER_WAVE }; u32 models[] = { MODEL_BOWSER_WAVE };
network_send_spawn_objects(spawn_objects, models, 1); network_send_spawn_objects(spawn_objects, models, 1);
}
} }
return 1; return 1;
} }
@ -847,7 +850,7 @@ void bowser_spawn_grand_star_key(void) {
reward = (prevReward != NULL) ? prevReward : spawn_object(o, MODEL_STAR, bhvGrandStar); reward = (prevReward != NULL) ? prevReward : spawn_object(o, MODEL_STAR, bhvGrandStar);
gSecondCameraFocus = reward; gSecondCameraFocus = reward;
if (prevReward == NULL) { if (prevReward == NULL && reward != NULL) {
// set the home position // set the home position
reward->oHomeX = reward->oPosX; reward->oHomeX = reward->oPosX;
reward->oHomeY = reward->oPosY; reward->oHomeY = reward->oPosY;
@ -862,7 +865,7 @@ void bowser_spawn_grand_star_key(void) {
gSecondCameraFocus = reward; gSecondCameraFocus = reward;
cur_obj_play_sound_2(SOUND_GENERAL2_BOWSER_KEY); cur_obj_play_sound_2(SOUND_GENERAL2_BOWSER_KEY);
if (prevReward == NULL) { if (prevReward == NULL && reward != NULL) {
// set the home position // set the home position
reward->oHomeX = reward->oPosX; reward->oHomeX = reward->oPosX;
reward->oHomeY = reward->oPosY; reward->oHomeY = reward->oPosY;
@ -1801,8 +1804,10 @@ void bhv_blue_flames_group_loop(void) {
if ((o->oTimer & 1) == 0) { if ((o->oTimer & 1) == 0) {
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
flame = spawn_object(o, MODEL_BLUE_FLAME, bhvFlameBouncing); flame = spawn_object(o, MODEL_BLUE_FLAME, bhvFlameBouncing);
flame->oMoveAngleYaw += i * 0x5555; if (flame != NULL) {
flame->header.gfx.scale[0] = o->oBlueFlameUnkF8; flame->oMoveAngleYaw += i * 0x5555;
flame->header.gfx.scale[0] = o->oBlueFlameUnkF8;
}
} }
o->oBlueFlameUnkF8 -= 0.5; o->oBlueFlameUnkF8 -= 0.5;
} }

View file

@ -55,9 +55,11 @@ void bhv_bowser_bomb_explosion_loop(void) {
cur_obj_scale((f32) o->oTimer / 14.0f * 9.0 + 1.0); cur_obj_scale((f32) o->oTimer / 14.0f * 9.0 + 1.0);
if ((o->oTimer % 4 == 0) && (o->oTimer < 20)) { if ((o->oTimer % 4 == 0) && (o->oTimer < 20)) {
mineSmoke = spawn_object(o, MODEL_BOWSER_SMOKE, bhvBowserBombSmoke); mineSmoke = spawn_object(o, MODEL_BOWSER_SMOKE, bhvBowserBombSmoke);
mineSmoke->oPosX += random_float() * 600.0f - 400.0f; if (mineSmoke != NULL) {
mineSmoke->oPosZ += random_float() * 600.0f - 400.0f; mineSmoke->oPosX += random_float() * 600.0f - 400.0f;
mineSmoke->oVelY += random_float() * 10.0f; mineSmoke->oPosZ += random_float() * 600.0f - 400.0f;
mineSmoke->oVelY += random_float() * 10.0f;
}
} }
if (o->oTimer % 2 == 0) if (o->oTimer % 2 == 0)

View file

@ -88,6 +88,7 @@ void bhv_lll_bowser_puzzle_spawn_piece(s16 model, const BehaviorScript *behavior
f32 xOffset, f32 zOffset, f32 xOffset, f32 zOffset,
s8 initialAction, s8 *actionList) { s8 initialAction, s8 *actionList) {
struct Object *puzzlePiece = spawn_object(o, model, behavior); struct Object *puzzlePiece = spawn_object(o, model, behavior);
if (puzzlePiece == NULL) { return; }
puzzlePiece->oPosX += xOffset; puzzlePiece->oPosX += xOffset;
puzzlePiece->oPosY += 50.0f; puzzlePiece->oPosY += 50.0f;
puzzlePiece->oPosZ += zOffset; puzzlePiece->oPosZ += zOffset;

View file

@ -5,6 +5,7 @@ void spawn_triangle_break_particles(s16 numTris, s16 triModel, f32 triSize, s16
s32 i; s32 i;
for (i = 0; i < numTris; i++) { for (i = 0; i < numTris; i++) {
triangle = spawn_object(o, triModel, bhvBreakBoxTriangle); triangle = spawn_object(o, triModel, bhvBreakBoxTriangle);
if (triangle == NULL) { continue; }
triangle->oAnimState = triAnimState; triangle->oAnimState = triAnimState;
triangle->oPosY += 100.0f; triangle->oPosY += 100.0f;
triangle->oMoveAngleYaw = random_u16(); triangle->oMoveAngleYaw = random_u16();

View file

@ -29,6 +29,7 @@ void bhv_breakable_box_small_init(void) {
void small_breakable_box_spawn_dust(void) { void small_breakable_box_spawn_dust(void) {
struct Object *sp24 = spawn_object(o, MODEL_SMOKE, bhvSmoke); struct Object *sp24 = spawn_object(o, MODEL_SMOKE, bhvSmoke);
if (sp24 == NULL) { return; }
sp24->oPosX += (s32)(random_float() * 80.0f) - 40; sp24->oPosX += (s32)(random_float() * 80.0f) - 40;
sp24->oPosZ += (s32)(random_float() * 80.0f) - 40; sp24->oPosZ += (s32)(random_float() * 80.0f) - 40;
} }

View file

@ -14,9 +14,11 @@ void bhv_object_bubble_loop(void) {
if (bubbleY > waterY) { if (bubbleY > waterY) {
if (gFreeObjectList.next) { if (gFreeObjectList.next) {
bubbleSplash = spawn_object_at_origin(o, 0, MODEL_SMALL_WATER_SPLASH, bhvBubbleSplash); bubbleSplash = spawn_object_at_origin(o, 0, MODEL_SMALL_WATER_SPLASH, bhvBubbleSplash);
bubbleSplash->oPosX = o->oPosX; if (bubbleSplash != NULL) {
bubbleSplash->oPosY = bubbleY + 5.0f; bubbleSplash->oPosX = o->oPosX;
bubbleSplash->oPosZ = o->oPosZ; bubbleSplash->oPosY = bubbleY + 5.0f;
bubbleSplash->oPosZ = o->oPosZ;
}
} }
o->activeFlags = ACTIVE_FLAG_DEACTIVATED; o->activeFlags = ACTIVE_FLAG_DEACTIVATED;

View file

@ -222,6 +222,7 @@ void bully_spawn_coin(void) {
#else #else
cur_obj_play_sound_2(SOUND_GENERAL_COIN_SPURT_2); cur_obj_play_sound_2(SOUND_GENERAL_COIN_SPURT_2);
#endif #endif
if (coin == NULL) { return; }
coin->oForwardVel = 10.0f; coin->oForwardVel = 10.0f;
coin->oVelY = 100.0f; coin->oVelY = 100.0f;
coin->oPosY = o->oPosY + 310.0f; coin->oPosY = o->oPosY + 310.0f;
@ -306,8 +307,10 @@ void bhv_bully_loop(void) {
void big_bully_spawn_minion(s32 arg0, s32 arg1, s32 arg2, s16 arg3) { void big_bully_spawn_minion(s32 arg0, s32 arg1, s32 arg2, s16 arg3) {
struct Object *bully = struct Object *bully =
spawn_object_abs_with_rot(o, 0, MODEL_BULLY, bhvSmallBully, arg0, arg1, arg2, 0, arg3, 00); spawn_object_abs_with_rot(o, 0, MODEL_BULLY, bhvSmallBully, arg0, arg1, arg2, 0, arg3, 00);
bully->oBullySubtype = BULLY_STYPE_MINION; if (bully != NULL) {
bully->oBehParams2ndByte = BULLY_BP_SIZE_SMALL; bully->oBullySubtype = BULLY_STYPE_MINION;
bully->oBehParams2ndByte = BULLY_BP_SIZE_SMALL;
}
} }
void bhv_big_bully_with_minions_init(void) { void bhv_big_bully_with_minions_init(void) {

View file

@ -8,11 +8,13 @@ static void bhv_cannon_closed_init_non_spawn(void) {
void bhv_cannon_closed_init(void) { void bhv_cannon_closed_init(void) {
struct Object* cannon = spawn_object(o, MODEL_CANNON_BASE, bhvCannon); struct Object* cannon = spawn_object(o, MODEL_CANNON_BASE, bhvCannon);
cannon->parentObj = cannon; if (cannon != NULL) {
cannon->oBehParams2ndByte = o->oBehParams2ndByte; cannon->parentObj = cannon;
cannon->oPosX = o->oHomeX; cannon->oBehParams2ndByte = o->oBehParams2ndByte;
cannon->oPosY = o->oHomeY; cannon->oPosX = o->oHomeX;
cannon->oPosZ = o->oHomeZ; cannon->oPosY = o->oHomeY;
cannon->oPosZ = o->oHomeZ;
}
bhv_cannon_closed_init_non_spawn(); bhv_cannon_closed_init_non_spawn();
} }

View file

@ -15,6 +15,7 @@ void bhv_castle_floor_trap_init(void) {
struct Object *sp2C; struct Object *sp2C;
sp2C = spawn_object_relative(0, -358, 0, 0, o, MODEL_CASTLE_BOWSER_TRAP, bhvFloorTrapInCastle); sp2C = spawn_object_relative(0, -358, 0, 0, o, MODEL_CASTLE_BOWSER_TRAP, bhvFloorTrapInCastle);
sp2C = spawn_object_relative(0, 358, 0, 0, o, MODEL_CASTLE_BOWSER_TRAP, bhvFloorTrapInCastle); sp2C = spawn_object_relative(0, 358, 0, 0, o, MODEL_CASTLE_BOWSER_TRAP, bhvFloorTrapInCastle);
if (sp2C == NULL) { return; }
sp2C->oMoveAngleYaw += 0x8000; sp2C->oMoveAngleYaw += 0x8000;
} }

View file

@ -22,6 +22,7 @@ void bhv_checkerboard_elevator_group_init(void) {
sp2C = spawn_object_relative(i, 0, i * sp3C, sp38, o, MODEL_CHECKERBOARD_PLATFORM, sp2C = spawn_object_relative(i, 0, i * sp3C, sp38, o, MODEL_CHECKERBOARD_PLATFORM,
bhvCheckerboardPlatformSub); bhvCheckerboardPlatformSub);
if (sp2C == NULL) { continue; }
sp2C->oCheckerBoardPlatformUnk1AC = D_8032F754[sp34].unk2; sp2C->oCheckerBoardPlatformUnk1AC = D_8032F754[sp34].unk2;
sp2C->oTimer = 0; sp2C->oTimer = 0;
vec3f_copy_2(sp2C->header.gfx.scale, D_8032F754[sp34].unk1); vec3f_copy_2(sp2C->header.gfx.scale, D_8032F754[sp34].unk1);

View file

@ -172,7 +172,7 @@ void spawn_coin_in_formation(s32 sp50, s32 sp54) {
if (sp3C) { if (sp3C) {
sp4C = spawn_object_relative(sp50, sp40[0], sp40[1], sp40[2], o, MODEL_YELLOW_COIN, sp4C = spawn_object_relative(sp50, sp40[0], sp40[1], sp40[2], o, MODEL_YELLOW_COIN,
bhvCoinFormationSpawn); bhvCoinFormationSpawn);
sp4C->oCoinUnkF8 = sp38; if (sp4C != NULL) { sp4C->oCoinUnkF8 = sp38; }
} }
} }
@ -260,6 +260,7 @@ void bhv_golden_coin_sparkles_loop(void) {
UNUSED s32 unused; UNUSED s32 unused;
f32 sp24 = 30.0f; f32 sp24 = 30.0f;
sp2C = spawn_object(o, MODEL_SPARKLES, bhvCoinSparkles); sp2C = spawn_object(o, MODEL_SPARKLES, bhvCoinSparkles);
if (sp2C == NULL) { return; }
sp2C->oPosX += random_float() * sp24 - sp24 / 2; sp2C->oPosX += random_float() * sp24 - sp24 / 2;
sp2C->oPosZ += random_float() * sp24 - sp24 / 2; sp2C->oPosZ += random_float() * sp24 - sp24 / 2;
} }

View file

@ -28,6 +28,7 @@ void bhv_punch_tiny_triangle_init(void) {
struct Object *triangle; struct Object *triangle;
for (i = 0; i < 6; i++) { for (i = 0; i < 6; i++) {
triangle = spawn_object(o, MODEL_DIRT_ANIMATION, bhvPunchTinyTriangle); triangle = spawn_object(o, MODEL_DIRT_ANIMATION, bhvPunchTinyTriangle);
if (triangle == NULL) { continue; }
triangle->oMoveAngleYaw = o->parentObj->oMoveAngleYaw + D_8032F2CC[2 * i] + 0x8000; triangle->oMoveAngleYaw = o->parentObj->oMoveAngleYaw + D_8032F2CC[2 * i] + 0x8000;
triangle->oVelY = sins(D_8032F2CC[2 * i + 1]) * 25.0f; triangle->oVelY = sins(D_8032F2CC[2 * i + 1]) * 25.0f;
triangle->oForwardVel = coss(D_8032F2CC[2 * i + 1]) * 25.0f; triangle->oForwardVel = coss(D_8032F2CC[2 * i + 1]) * 25.0f;
@ -54,6 +55,7 @@ void bhv_tiny_star_particles_init(void) {
struct Object *particle; struct Object *particle;
for (i = 0; i < 7; i++) { for (i = 0; i < 7; i++) {
particle = spawn_object(o, MODEL_CARTOON_STAR, bhvWallTinyStarParticle); particle = spawn_object(o, MODEL_CARTOON_STAR, bhvWallTinyStarParticle);
if (particle == NULL) { continue; }
particle->oMoveAngleYaw = o->parentObj->oMoveAngleYaw + D_8032F2E4[2 * i] + 0x8000; particle->oMoveAngleYaw = o->parentObj->oMoveAngleYaw + D_8032F2E4[2 * i] + 0x8000;
particle->oVelY = sins(D_8032F2E4[2 * i + 1]) * 25.0f; particle->oVelY = sins(D_8032F2E4[2 * i + 1]) * 25.0f;
particle->oForwardVel = coss(D_8032F2E4[2 * i + 1]) * 25.0f; particle->oForwardVel = coss(D_8032F2E4[2 * i + 1]) * 25.0f;
@ -79,6 +81,7 @@ void bhv_pound_tiny_star_particle_init(void) {
struct Object *particle; struct Object *particle;
for (sp24 = 0; sp24 < sp20; sp24++) { for (sp24 = 0; sp24 < sp20; sp24++) {
particle = spawn_object(o, MODEL_CARTOON_STAR, bhvPoundTinyStarParticle); particle = spawn_object(o, MODEL_CARTOON_STAR, bhvPoundTinyStarParticle);
if (particle == NULL) { continue; }
particle->oMoveAngleYaw = (sp24 * 65536) / sp20; particle->oMoveAngleYaw = (sp24 * 65536) / sp20;
} }
} }

View file

@ -55,19 +55,19 @@ void bhv_controllable_platform_sub_loop(void) {
void bhv_controllable_platform_init(void) { void bhv_controllable_platform_init(void) {
controllablePlatformSubs[0] = spawn_object_rel_with_rot(o, MODEL_HMC_METAL_ARROW_PLATFORM, bhvControllablePlatformSub, 0, controllablePlatformSubs[0] = spawn_object_rel_with_rot(o, MODEL_HMC_METAL_ARROW_PLATFORM, bhvControllablePlatformSub, 0,
51, 204, 0, 0, 0); 51, 204, 0, 0, 0);
controllablePlatformSubs[0]->oBehParams2ndByte = 1; if (controllablePlatformSubs[0] != NULL) { controllablePlatformSubs[0]->oBehParams2ndByte = 1; }
controllablePlatformSubs[1] = spawn_object_rel_with_rot(o, MODEL_HMC_METAL_ARROW_PLATFORM, bhvControllablePlatformSub, 0, controllablePlatformSubs[1] = spawn_object_rel_with_rot(o, MODEL_HMC_METAL_ARROW_PLATFORM, bhvControllablePlatformSub, 0,
51, -204, 0, -0x8000, 0); 51, -204, 0, -0x8000, 0);
controllablePlatformSubs[1]->oBehParams2ndByte = 2; if (controllablePlatformSubs[1] != NULL) { controllablePlatformSubs[1]->oBehParams2ndByte = 2; }
controllablePlatformSubs[2] = spawn_object_rel_with_rot(o, MODEL_HMC_METAL_ARROW_PLATFORM, bhvControllablePlatformSub, 204, controllablePlatformSubs[2] = spawn_object_rel_with_rot(o, MODEL_HMC_METAL_ARROW_PLATFORM, bhvControllablePlatformSub, 204,
51, 0, 0, 0x4000, 0); 51, 0, 0, 0x4000, 0);
controllablePlatformSubs[2]->oBehParams2ndByte = 3; if (controllablePlatformSubs[2] != NULL) { controllablePlatformSubs[2]->oBehParams2ndByte = 3; }
controllablePlatformSubs[3] = spawn_object_rel_with_rot(o, MODEL_HMC_METAL_ARROW_PLATFORM, bhvControllablePlatformSub, controllablePlatformSubs[3] = spawn_object_rel_with_rot(o, MODEL_HMC_METAL_ARROW_PLATFORM, bhvControllablePlatformSub,
-204, 51, 0, 0, -0x4000, 0); -204, 51, 0, 0, -0x4000, 0);
controllablePlatformSubs[3]->oBehParams2ndByte = 4; if (controllablePlatformSubs[3] != NULL) { controllablePlatformSubs[3]->oBehParams2ndByte = 4; }
D_80331694 = 0; D_80331694 = 0;
@ -94,6 +94,7 @@ void bhv_controllable_platform_init(void) {
network_init_object_field(o, &o->oFaceAngleRoll); network_init_object_field(o, &o->oFaceAngleRoll);
network_init_object_field(o, &o->header.gfx.node.flags); network_init_object_field(o, &o->header.gfx.node.flags);
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
if (controllablePlatformSubs[i] == NULL) { continue; }
network_init_object_field(o, &controllablePlatformSubs[i]->oAction); network_init_object_field(o, &controllablePlatformSubs[i]->oAction);
network_init_object_field(o, &controllablePlatformSubs[i]->oPrevAction); network_init_object_field(o, &controllablePlatformSubs[i]->oPrevAction);
network_init_object_field(o, &controllablePlatformSubs[i]->oTimer); network_init_object_field(o, &controllablePlatformSubs[i]->oTimer);

View file

@ -44,9 +44,11 @@ void bhv_respawner_loop(void) {
if (!is_point_within_radius_of_mario(o->oPosX, o->oPosY, o->oPosZ, o->oRespawnerMinSpawnDist)) { if (!is_point_within_radius_of_mario(o->oPosX, o->oPosY, o->oPosZ, o->oRespawnerMinSpawnDist)) {
u32 syncID = o->oSyncID; u32 syncID = o->oSyncID;
spawnedObject = spawn_object(o, o->oRespawnerModelToRespawn, o->oRespawnerBehaviorToRespawn); spawnedObject = spawn_object(o, o->oRespawnerModelToRespawn, o->oRespawnerBehaviorToRespawn);
spawnedObject->oBehParams = o->oBehParams; if (spawnedObject != NULL) {
spawnedObject->oSyncID = syncID; spawnedObject->oBehParams = o->oBehParams;
network_override_object(syncID, spawnedObject); spawnedObject->oSyncID = syncID;
network_override_object(syncID, spawnedObject);
}
o->oSyncID = 0; o->oSyncID = 0;
o->activeFlags = ACTIVE_FLAG_DEACTIVATED; o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
@ -57,14 +59,18 @@ void create_respawner(s32 model, const BehaviorScript *behToSpawn, s32 minSpawnD
struct Object *respawner = spawn_object_abs_with_rot(o, 0, MODEL_NONE, bhvRespawner, o->oHomeX, struct Object *respawner = spawn_object_abs_with_rot(o, 0, MODEL_NONE, bhvRespawner, o->oHomeX,
o->oHomeY, o->oHomeZ, 0, 0, 0); o->oHomeY, o->oHomeZ, 0, 0, 0);
u8 syncID = o->oSyncID; u8 syncID = o->oSyncID;
respawner->oBehParams = o->oBehParams; if (respawner != NULL) {
respawner->oRespawnerModelToRespawn = model; respawner->oBehParams = o->oBehParams;
respawner->oRespawnerMinSpawnDist = minSpawnDist; respawner->oRespawnerModelToRespawn = model;
respawner->oRespawnerBehaviorToRespawn = behToSpawn; respawner->oRespawnerMinSpawnDist = minSpawnDist;
respawner->oSyncID = syncID; respawner->oRespawnerBehaviorToRespawn = behToSpawn;
respawner->oSyncID = syncID;
}
if (syncID < RESERVED_IDS_SYNC_OBJECT_OFFSET) { if (syncID < RESERVED_IDS_SYNC_OBJECT_OFFSET) {
network_override_object(syncID, respawner); if (respawner != NULL) {
network_override_object(syncID, respawner);
}
o->oSyncID = 0; o->oSyncID = 0;
o->oFlags |= OBJ_FLAG_PERSISTENT_RESPAWN; // pretty sure this is required o->oFlags |= OBJ_FLAG_PERSISTENT_RESPAWN; // pretty sure this is required
} }

View file

@ -4,18 +4,23 @@ void bhv_lll_drawbridge_spawner_init(void) {
struct Object *drawbridge[2]; struct Object *drawbridge[2];
drawbridge[0] = spawn_object(o, MODEL_LLL_DRAWBRIDGE_PART, bhvLllDrawbridge); drawbridge[0] = spawn_object(o, MODEL_LLL_DRAWBRIDGE_PART, bhvLllDrawbridge);
drawbridge[0]->oMoveAngleYaw = o->oMoveAngleYaw; if (drawbridge[0] != NULL) {
drawbridge[0]->oPosX += coss(o->oMoveAngleYaw) * 640.0f; drawbridge[0]->oMoveAngleYaw = o->oMoveAngleYaw;
drawbridge[0]->oPosZ += sins(o->oMoveAngleYaw) * 640.0f; drawbridge[0]->oPosX += coss(o->oMoveAngleYaw) * 640.0f;
drawbridge[0]->oPosZ += sins(o->oMoveAngleYaw) * 640.0f;
}
drawbridge[1] = spawn_object(o, MODEL_LLL_DRAWBRIDGE_PART, bhvLllDrawbridge); drawbridge[1] = spawn_object(o, MODEL_LLL_DRAWBRIDGE_PART, bhvLllDrawbridge);
drawbridge[1]->oMoveAngleYaw = o->oMoveAngleYaw + 0x8000; if (drawbridge[1] != NULL) {
drawbridge[1]->oPosX += coss(o->oMoveAngleYaw) * -640.0f; drawbridge[1]->oMoveAngleYaw = o->oMoveAngleYaw + 0x8000;
drawbridge[1]->oPosZ += sins(o->oMoveAngleYaw) * -640.0f; drawbridge[1]->oPosX += coss(o->oMoveAngleYaw) * -640.0f;
drawbridge[1]->oPosZ += sins(o->oMoveAngleYaw) * -640.0f;
}
if (!network_sync_object_initialized(o)) { if (!network_sync_object_initialized(o)) {
network_init_object(o, 3000.0f); network_init_object(o, 3000.0f);
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
if (drawbridge[i] == NULL) { continue; }
network_init_object_field(o, &drawbridge[i]->oFaceAngleRoll); network_init_object_field(o, &drawbridge[i]->oFaceAngleRoll);
network_init_object_field(o, &drawbridge[i]->oAction); network_init_object_field(o, &drawbridge[i]->oAction);
network_init_object_field(o, &drawbridge[i]->oPrevAction); network_init_object_field(o, &drawbridge[i]->oPrevAction);

View file

@ -135,17 +135,19 @@ void exclamation_box_spawn_contents(struct Struct802C0DF0 *a0, u8 a1) {
s32 model = exclamation_replace_model(m, a0->model); s32 model = exclamation_replace_model(m, a0->model);
sp1C = spawn_object(o, model, a0->behavior); sp1C = spawn_object(o, model, a0->behavior);
sp1C->oVelY = 20.0f; if (sp1C != NULL) {
sp1C->oForwardVel = 3.0f; sp1C->oVelY = 20.0f;
sp1C->oMoveAngleYaw = player->oMoveAngleYaw; sp1C->oForwardVel = 3.0f;
sp1C->globalPlayerIndex = player->globalPlayerIndex; sp1C->oMoveAngleYaw = player->oMoveAngleYaw;
sp1C->globalPlayerIndex = player->globalPlayerIndex;
}
o->oBehParams |= a0->unk2 << 24; o->oBehParams |= a0->unk2 << 24;
if (a0->model == 122) if (a0->model == 122)
o->oFlags |= 0x4000; o->oFlags |= 0x4000;
// send non-star spawn events // send non-star spawn events
// stars cant be sent here to due jankiness in oBehParams // stars cant be sent here to due jankiness in oBehParams
if (a0->behavior != bhvSpawnedStar) { if (a0->behavior != bhvSpawnedStar && sp1C != NULL) {
// hack: if any other sync objects get spawned here we have to check for them // hack: if any other sync objects get spawned here we have to check for them
if (a0->behavior == bhvKoopaShell) { if (a0->behavior == bhvKoopaShell) {
network_set_sync_id(sp1C); network_set_sync_id(sp1C);

View file

@ -43,6 +43,7 @@ void fish_act_spawn(void) {
*/ */
for (i = 0; i < schoolQuantity; i++) { for (i = 0; i < schoolQuantity; i++) {
fishObject = spawn_object(o, model, bhvFish); fishObject = spawn_object(o, model, bhvFish);
if (fishObject == NULL) { continue; }
fishObject->oBehParams2ndByte = o->oBehParams2ndByte; fishObject->oBehParams2ndByte = o->oBehParams2ndByte;
obj_init_animation_with_sound(fishObject, fishAnimation, 0); obj_init_animation_with_sound(fishObject, fishAnimation, 0);
obj_translate_xyz_random(fishObject, 700.0f); obj_translate_xyz_random(fishObject, 700.0f);

View file

@ -72,7 +72,7 @@ void bhv_flamethrower_loop(void) {
o->oAction++; o->oAction++;
o->oFlameThowerUnk110 = sp34; o->oFlameThowerUnk110 = sp34;
flame = spawn_object_relative(o->oBehParams2ndByte, 0, 0, 0, o, model, bhvFlamethrowerFlame); flame = spawn_object_relative(o->oBehParams2ndByte, 0, 0, 0, o, model, bhvFlamethrowerFlame);
flame->oForwardVel = flameVel; if (flame != NULL) { flame->oForwardVel = flameVel; }
cur_obj_play_sound_1(SOUND_AIR_BLOW_FIRE); cur_obj_play_sound_1(SOUND_AIR_BLOW_FIRE);
} else if (o->oTimer > 60) } else if (o->oTimer > 60)
o->oAction = 0; o->oAction = 0;

View file

@ -23,11 +23,15 @@ void bhv_openable_grill_loop(void) {
grillIdx = o->oBehParams2ndByte; grillIdx = o->oBehParams2ndByte;
grillObj = spawn_object_relative(-1, gOpenableGrills[grillIdx].halfWidth, 0, 0, o, gOpenableGrills[grillIdx].modelID, grillObj = spawn_object_relative(-1, gOpenableGrills[grillIdx].halfWidth, 0, 0, o, gOpenableGrills[grillIdx].modelID,
bhvOpenableCageDoor); bhvOpenableCageDoor);
grillObj->oMoveAngleYaw += 0x8000; if (grillObj != NULL) {
obj_set_collision_data(grillObj, gOpenableGrills[grillIdx].collision); grillObj->oMoveAngleYaw += 0x8000;
obj_set_collision_data(grillObj, gOpenableGrills[grillIdx].collision);
}
grillObj = spawn_object_relative(1, -gOpenableGrills[grillIdx].halfWidth, 0, 0, o, gOpenableGrills[grillIdx].modelID, grillObj = spawn_object_relative(1, -gOpenableGrills[grillIdx].halfWidth, 0, 0, o, gOpenableGrills[grillIdx].modelID,
bhvOpenableCageDoor); bhvOpenableCageDoor);
obj_set_collision_data(grillObj, gOpenableGrills[grillIdx].collision); if (grillObj != NULL) {
obj_set_collision_data(grillObj, gOpenableGrills[grillIdx].collision);
}
o->oAction++; o->oAction++;
break; break;
case 1: case 1:

View file

@ -16,6 +16,7 @@ void bhv_ground_sand_init(void) {
void spawn_smoke_with_velocity(void) { void spawn_smoke_with_velocity(void) {
struct Object *smoke = spawn_object_with_scale(o, MODEL_SMOKE, bhvWhitePuffSmoke2, 1.0f); struct Object *smoke = spawn_object_with_scale(o, MODEL_SMOKE, bhvWhitePuffSmoke2, 1.0f);
if (smoke == NULL) { return; }
smoke->oForwardVel = D_8032F3F4[0]; smoke->oForwardVel = D_8032F3F4[0];
smoke->oVelY = D_8032F3F4[1]; smoke->oVelY = D_8032F3F4[1];
smoke->oGravity = D_8032F3F4[2]; smoke->oGravity = D_8032F3F4[2];

View file

@ -8,7 +8,7 @@ void bhv_hidden_star_init(void) {
if (sp36 == 0) { if (sp36 == 0) {
sp30 = sp30 =
spawn_object_abs_with_rot(o, 0, MODEL_STAR, bhvStar, o->oPosX, o->oPosY, o->oPosZ, 0, 0, 0); spawn_object_abs_with_rot(o, 0, MODEL_STAR, bhvStar, o->oPosX, o->oPosY, o->oPosZ, 0, 0, 0);
sp30->oBehParams = o->oBehParams; if (sp30 != NULL) { sp30->oBehParams = o->oBehParams; }
o->activeFlags = ACTIVE_FLAG_DEACTIVATED; o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
} }

View file

@ -426,11 +426,13 @@ void bhv_klepto_update(void) {
save_file_clear_flags(SAVE_FLAG_CAP_ON_KLEPTO); save_file_clear_flags(SAVE_FLAG_CAP_ON_KLEPTO);
struct Object* cap = spawn_object(o, capModel, bhvNormalCap); struct Object* cap = spawn_object(o, capModel, bhvNormalCap);
cap->globalPlayerIndex = o->globalPlayerIndex; if (cap != NULL) {
cap->globalPlayerIndex = o->globalPlayerIndex;
struct Object* spawn_objects[] = { cap }; struct Object* spawn_objects[] = { cap };
u32 models[] = { capModel }; u32 models[] = { capModel };
network_send_spawn_objects(spawn_objects, models, 1); network_send_spawn_objects(spawn_objects, models, 1);
}
} else if (o->oAnimState == KLEPTO_ANIM_STATE_HOLDING_STAR) { } else if (o->oAnimState == KLEPTO_ANIM_STATE_HOLDING_STAR) {
spawn_default_star(-5550.0f, 300.0f, -930.0f); spawn_default_star(-5550.0f, 300.0f, -930.0f);

View file

@ -350,11 +350,13 @@ void shelled_koopa_attack_handler(s32 attackType) {
struct MarioState* marioState = nearest_mario_state_to_object(o); struct MarioState* marioState = nearest_mario_state_to_object(o);
if (marioState->playerIndex == 0) { if (marioState->playerIndex == 0) {
struct Object* shell = spawn_object(o, MODEL_KOOPA_SHELL, bhvKoopaShell); struct Object* shell = spawn_object(o, MODEL_KOOPA_SHELL, bhvKoopaShell);
network_set_sync_id(shell); if (shell != NULL) {
network_set_sync_id(shell);
struct Object* spawn_objects[] = { shell }; struct Object* spawn_objects[] = { shell };
u32 models[] = { MODEL_KOOPA_SHELL }; u32 models[] = { MODEL_KOOPA_SHELL };
network_send_spawn_objects(spawn_objects, models, 1); network_send_spawn_objects(spawn_objects, models, 1);
}
} }
//! Because bob-ombs/corkboxes come after koopa in processing order, //! Because bob-ombs/corkboxes come after koopa in processing order,

View file

@ -18,8 +18,10 @@ void koopa_shell_spawn_water_drop(void) {
spawn_object(o, MODEL_WAVE_TRAIL, bhvObjectWaveTrail); spawn_object(o, MODEL_WAVE_TRAIL, bhvObjectWaveTrail);
if (gMarioStates[o->heldByPlayerIndex].forwardVel > 10.0f) { if (gMarioStates[o->heldByPlayerIndex].forwardVel > 10.0f) {
drop = spawn_object_with_scale(o, MODEL_WHITE_PARTICLE_SMALL, bhvWaterDroplet, 1.5f); drop = spawn_object_with_scale(o, MODEL_WHITE_PARTICLE_SMALL, bhvWaterDroplet, 1.5f);
drop->oVelY = random_float() * 30.0f; if (drop != NULL) {
obj_translate_xz_random(drop, 110.0f); drop->oVelY = random_float() * 30.0f;
obj_translate_xz_random(drop, 110.0f);
}
} }
} }
@ -48,6 +50,7 @@ void bhv_koopa_shell_flame_spawn(void) {
void koopa_shell_spawn_sparkles(f32 a) { void koopa_shell_spawn_sparkles(f32 a) {
struct Object *sp1C = spawn_object(o, MODEL_NONE, bhvSparkleSpawn); struct Object *sp1C = spawn_object(o, MODEL_NONE, bhvSparkleSpawn);
if (sp1C == NULL) { return; }
sp1C->oPosY += a; sp1C->oPosY += a;
} }

View file

@ -22,6 +22,7 @@ void bhv_lll_floating_wood_bridge_loop(void) {
for (i = 1; i < 4; i++) { for (i = 1; i < 4; i++) {
sp3C = spawn_object_relative(0, (i - 2) * 300, 0, 0, o, MODEL_LLL_WOOD_BRIDGE, sp3C = spawn_object_relative(0, (i - 2) * 300, 0, 0, o, MODEL_LLL_WOOD_BRIDGE,
bhvLllWoodPiece); bhvLllWoodPiece);
if (sp3C == NULL) { continue; }
sp3C->oLllWoodPieceOscillationTimer = i * 4096; sp3C->oLllWoodPieceOscillationTimer = i * 4096;
} }
o->oAction = 1; o->oAction = 1;

View file

@ -4,12 +4,14 @@ void hexagonal_ring_spawn_flames(void) {
struct Object *sp1C; struct Object *sp1C;
f32 size; f32 size;
sp1C = spawn_object(o, MODEL_RED_FLAME, bhvVolcanoFlames); sp1C = spawn_object(o, MODEL_RED_FLAME, bhvVolcanoFlames);
sp1C->oPosY += 550.0f; if (sp1C != NULL) {
sp1C->oMoveAngleYaw = random_u16() << 0x10 >> 0x10; sp1C->oPosY += 550.0f;
sp1C->oForwardVel = random_float() * 40.0f + 20.0f; sp1C->oMoveAngleYaw = random_u16() << 0x10 >> 0x10;
sp1C->oVelY = random_float() * 50.0f + 10.0f; sp1C->oForwardVel = random_float() * 40.0f + 20.0f;
size = random_float() * 6.0 + 3.0; sp1C->oVelY = random_float() * 50.0f + 10.0f;
obj_scale_xyz(sp1C, size, size, size); size = random_float() * 6.0 + 3.0;
obj_scale_xyz(sp1C, size, size, size);
}
if (random_float() < 0.1) if (random_float() < 0.1)
cur_obj_play_sound_2(SOUND_GENERAL_VOLCANO_EXPLOSION); cur_obj_play_sound_2(SOUND_GENERAL_VOLCANO_EXPLOSION);
} }

View file

@ -20,10 +20,12 @@ void fire_bar_spawn_flames(s16 a0) {
sp20 = (o->oBehParams2ndByte == 0) ? 4 : 3; sp20 = (o->oBehParams2ndByte == 0) ? 4 : 3;
for (i = 0; i < sp20; i++) { for (i = 0; i < sp20; i++) {
sp2C = spawn_object(o, MODEL_RED_FLAME, bhvLllRotatingHexFlame); sp2C = spawn_object(o, MODEL_RED_FLAME, bhvLllRotatingHexFlame);
sp2C->oLllRotatingHexFlameUnkF4 += sp1C; if (sp2C != NULL) {
sp2C->oLllRotatingHexFlameUnkF8 = o->oPosY - 200.0f; sp2C->oLllRotatingHexFlameUnkF4 += sp1C;
sp2C->oLllRotatingHexFlameUnkFC += sp18; sp2C->oLllRotatingHexFlameUnkF8 = o->oPosY - 200.0f;
obj_scale_xyz(sp2C, 6.0f, 6.0f, 6.0f); sp2C->oLllRotatingHexFlameUnkFC += sp18;
obj_scale_xyz(sp2C, 6.0f, 6.0f, 6.0f);
}
sp1C += sins(a0) * 150.0f; sp1C += sins(a0) * 150.0f;
sp18 += coss(a0) * 150.0f; sp18 += coss(a0) * 150.0f;
} }

View file

@ -27,7 +27,9 @@ static struct ObjectHitbox sMantaRayHitbox = {
void bhv_manta_ray_init(void) { void bhv_manta_ray_init(void) {
struct Object *sp1C; struct Object *sp1C;
sp1C = spawn_object(o, MODEL_NONE, bhvMantaRayRingManager); sp1C = spawn_object(o, MODEL_NONE, bhvMantaRayRingManager);
o->parentObj = sp1C; if (sp1C != NULL) {
o->parentObj = sp1C;
}
obj_set_hitbox(o, &sMantaRayHitbox); obj_set_hitbox(o, &sMantaRayHitbox);
cur_obj_scale(2.5f); cur_obj_scale(2.5f);
@ -37,7 +39,9 @@ void bhv_manta_ray_init(void) {
network_init_object_field(o, &o->oMantaUnk1AC); network_init_object_field(o, &o->oMantaUnk1AC);
network_init_object_field(o, &o->oMoveAnglePitch); network_init_object_field(o, &o->oMoveAnglePitch);
network_init_object_field(o, &o->oMoveAngleRoll); network_init_object_field(o, &o->oMoveAngleRoll);
network_init_object_field(o, &sp1C->oWaterRingMgrNextRingIndex); if (sp1C != NULL) {
network_init_object_field(o, &sp1C->oWaterRingMgrNextRingIndex);
}
} }
void manta_ray_move(void) { void manta_ray_move(void) {
@ -78,20 +82,24 @@ void manta_ray_act_spawn_ring(void) {
if (o->oTimer == 0 || o->oTimer == 50 || o->oTimer == 150 || o->oTimer == 200 || o->oTimer == 250) { if (o->oTimer == 0 || o->oTimer == 50 || o->oTimer == 150 || o->oTimer == 200 || o->oTimer == 250) {
sp18 = spawn_object(o, MODEL_WATER_RING, bhvMantaRayWaterRing); sp18 = spawn_object(o, MODEL_WATER_RING, bhvMantaRayWaterRing);
sp18->oFaceAngleYaw = o->oMoveAngleYaw; if (sp18 != NULL) {
sp18->oFaceAnglePitch = o->oMoveAnglePitch + 0x4000; sp18->oFaceAngleYaw = o->oMoveAngleYaw;
sp18->oPosX = o->oPosX + 200.0f * sins(o->oMoveAngleYaw + 0x8000); sp18->oFaceAnglePitch = o->oMoveAnglePitch + 0x4000;
sp18->oPosY = o->oPosY + 10.0f + 200.0f * sins(o->oMoveAnglePitch); sp18->oPosX = o->oPosX + 200.0f * sins(o->oMoveAngleYaw + 0x8000);
sp18->oPosZ = o->oPosZ + 200.0f * coss(o->oMoveAngleYaw + 0x8000); sp18->oPosY = o->oPosY + 10.0f + 200.0f * sins(o->oMoveAnglePitch);
sp18->oWaterRingIndex = sp1C->oWaterRingMgrNextRingIndex; sp18->oPosZ = o->oPosZ + 200.0f * coss(o->oMoveAngleYaw + 0x8000);
sp18->oWaterRingIndex = sp1C->oWaterRingMgrNextRingIndex;
}
sp1C->oWaterRingMgrNextRingIndex++; sp1C->oWaterRingMgrNextRingIndex++;
if (sp1C->oWaterRingMgrNextRingIndex > 0x2710) if (sp1C->oWaterRingMgrNextRingIndex > 0x2710)
sp1C->oWaterRingMgrNextRingIndex = 0; sp1C->oWaterRingMgrNextRingIndex = 0;
struct Object* spawn_objects[] = { sp18 }; if (sp18 != NULL) {
u32 models[] = { MODEL_WATER_RING }; struct Object* spawn_objects[] = { sp18 };
network_send_spawn_objects(spawn_objects, models, 1); u32 models[] = { MODEL_WATER_RING };
network_send_spawn_objects(spawn_objects, models, 1);
}
network_send_object(o); network_send_object(o);
} }

View file

@ -243,10 +243,12 @@ void bhv_moneybag_hidden_loop(void) {
network_send_object(o); network_send_object(o);
network_set_sync_id(moneyBag); if (moneyBag != NULL) {
struct Object* spawn_objects[] = { moneyBag }; network_set_sync_id(moneyBag);
u32 models[] = { MODEL_MONEYBAG }; struct Object* spawn_objects[] = { moneyBag };
network_send_spawn_objects(spawn_objects, models, 1); u32 models[] = { MODEL_MONEYBAG };
network_send_spawn_objects(spawn_objects, models, 1);
}
} }
} }
break; break;

View file

@ -449,10 +449,11 @@ void bhv_monty_mole_update(void) {
if (sMontyMoleKillStreak == 7 && network_owns_object(o)) { if (sMontyMoleKillStreak == 7 && network_owns_object(o)) {
play_puzzle_jingle(); play_puzzle_jingle();
struct Object* oneUp = spawn_object(o, MODEL_1UP, bhv1upWalking); struct Object* oneUp = spawn_object(o, MODEL_1UP, bhv1upWalking);
if (oneUp != NULL) {
struct Object* spawn_objects[] = { oneUp }; struct Object* spawn_objects[] = { oneUp };
u32 models[] = { MODEL_1UP }; u32 models[] = { MODEL_1UP };
network_send_spawn_objects(spawn_objects, models, 1); network_send_spawn_objects(spawn_objects, models, 1);
}
} }
} else { } else {
sMontyMoleKillStreak = 0; sMontyMoleKillStreak = 0;

View file

@ -40,13 +40,15 @@ void spawn_mr_i_particle(void) {
struct Object *particle; struct Object *particle;
f32 sp18 = o->header.gfx.scale[1]; f32 sp18 = o->header.gfx.scale[1];
particle = spawn_object(o, MODEL_PURPLE_MARBLE, bhvMrIParticle); particle = spawn_object(o, MODEL_PURPLE_MARBLE, bhvMrIParticle);
particle->oPosY += 50.0f * sp18; if (particle != NULL) {
particle->oPosX += sins(o->oMoveAngleYaw) * 90.0f * sp18; particle->oPosY += 50.0f * sp18;
particle->oPosZ += coss(o->oMoveAngleYaw) * 90.0f * sp18; particle->oPosX += sins(o->oMoveAngleYaw) * 90.0f * sp18;
particle->oPosZ += coss(o->oMoveAngleYaw) * 90.0f * sp18;
struct Object* spawn_objects[] = { particle }; struct Object* spawn_objects[] = { particle };
u32 models[] = { MODEL_PURPLE_MARBLE }; u32 models[] = { MODEL_PURPLE_MARBLE };
network_send_spawn_objects(spawn_objects, models, 1); network_send_spawn_objects(spawn_objects, models, 1);
}
cur_obj_play_sound_2(SOUND_OBJ_MRI_SHOOT); cur_obj_play_sound_2(SOUND_OBJ_MRI_SHOOT);
} }

View file

@ -389,6 +389,7 @@ void bhv_1up_hidden_in_pole_spawner_loop(void) {
} }
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
if (spawn_objects[i] == NULL) { continue; }
spawn_objects[i]->parentObj = spawn_objects[i]; spawn_objects[i]->parentObj = spawn_objects[i];
network_set_sync_id(spawn_objects[i]); network_set_sync_id(spawn_objects[i]);
} }

View file

@ -14,7 +14,9 @@ void bhv_orange_number_loop(void) {
if (o->oTimer == 35) { if (o->oTimer == 35) {
sp1C = spawn_object(o, MODEL_SPARKLES, bhvGoldenCoinSparkles); sp1C = spawn_object(o, MODEL_SPARKLES, bhvGoldenCoinSparkles);
sp1C->oPosY -= 30.f; if (sp1C != NULL) {
sp1C->oPosY -= 30.f;
}
o->activeFlags = ACTIVE_FLAG_DEACTIVATED; o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
} }
} }

View file

@ -29,7 +29,9 @@ void bhv_giant_pole_loop(void) {
struct Object *topBall; struct Object *topBall;
if (o->oTimer == 0) { if (o->oTimer == 0) {
topBall = spawn_object(o, MODEL_YELLOW_SPHERE, bhvYellowBall); topBall = spawn_object(o, MODEL_YELLOW_SPHERE, bhvYellowBall);
topBall->oPosY += o->hitboxHeight + 50.0f; if (topBall != NULL) {
topBall->oPosY += o->hitboxHeight + 50.0f;
}
} }
bhv_pole_base_loop(); bhv_pole_base_loop();
} }

View file

@ -19,6 +19,7 @@ void bhv_pyramid_elevator_init(void) {
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
ball = spawn_object(o, MODEL_TRAJECTORY_MARKER_BALL, bhvPyramidElevatorTrajectoryMarkerBall); ball = spawn_object(o, MODEL_TRAJECTORY_MARKER_BALL, bhvPyramidElevatorTrajectoryMarkerBall);
if (ball == NULL) { continue; }
ball->oPosY = 4600 - i * 460; ball->oPosY = 4600 - i * 460;
} }

View file

@ -53,10 +53,12 @@ void bhv_pyramid_top_spinning(void) {
// with a random velocity and angle. // with a random velocity and angle.
if (o->oTimer < 90) { if (o->oTimer < 90) {
pyramidFragment = spawn_object(o, MODEL_DIRT_ANIMATION, bhvPyramidTopFragment); pyramidFragment = spawn_object(o, MODEL_DIRT_ANIMATION, bhvPyramidTopFragment);
pyramidFragment->oForwardVel = random_float() * 10.0f + 20.0f; if (pyramidFragment != NULL) {
pyramidFragment->oMoveAngleYaw = random_u16(); pyramidFragment->oForwardVel = random_float() * 10.0f + 20.0f;
pyramidFragment->oPyramidTopFragmentsScale = 0.8f; pyramidFragment->oMoveAngleYaw = random_u16();
pyramidFragment->oGravity = random_float() + 2.0f; pyramidFragment->oPyramidTopFragmentsScale = 0.8f;
pyramidFragment->oGravity = random_float() + 2.0f;
}
} }
// After enough time, transition to the exploding state. // After enough time, transition to the exploding state.
@ -79,11 +81,13 @@ void bhv_pyramid_top_explode(void) {
pyramidFragment = spawn_object( pyramidFragment = spawn_object(
o, MODEL_DIRT_ANIMATION, bhvPyramidTopFragment o, MODEL_DIRT_ANIMATION, bhvPyramidTopFragment
); );
pyramidFragment->oForwardVel = random_float() * 50 + 80; if (pyramidFragment != NULL) {
pyramidFragment->oVelY = random_float() * 80 + 20; pyramidFragment->oForwardVel = random_float() * 50 + 80;
pyramidFragment->oMoveAngleYaw = random_u16(); pyramidFragment->oVelY = random_float() * 80 + 20;
pyramidFragment->oPyramidTopFragmentsScale = 3; pyramidFragment->oMoveAngleYaw = random_u16();
pyramidFragment->oGravity = random_float() * 2 + 5; pyramidFragment->oPyramidTopFragmentsScale = 3;
pyramidFragment->oGravity = random_float() * 2 + 5;
}
} }
// Deactivate the pyramid top. // Deactivate the pyramid top.

View file

@ -152,14 +152,16 @@ void bhv_scuttlebug_spawn_loop(void) {
if (o->oTimer > 30 && 500.0f < distanceToPlayer && distanceToPlayer < 1500.0f) { if (o->oTimer > 30 && 500.0f < distanceToPlayer && distanceToPlayer < 1500.0f) {
cur_obj_play_sound_2(SOUND_OBJ2_SCUTTLEBUG_ALERT); cur_obj_play_sound_2(SOUND_OBJ2_SCUTTLEBUG_ALERT);
scuttlebug = spawn_object(o, MODEL_SCUTTLEBUG, bhvScuttlebug); scuttlebug = spawn_object(o, MODEL_SCUTTLEBUG, bhvScuttlebug);
scuttlebug->oScuttlebugUnkF4 = o->oScuttlebugSpawnerUnkF4; if (scuttlebug != NULL) {
scuttlebug->oForwardVel = 30.0f; scuttlebug->oScuttlebugUnkF4 = o->oScuttlebugSpawnerUnkF4;
scuttlebug->oVelY = 80.0f; scuttlebug->oForwardVel = 30.0f;
scuttlebug->oVelY = 80.0f;
network_set_sync_id(scuttlebug); network_set_sync_id(scuttlebug);
struct Object* spawn_objects[] = { scuttlebug }; struct Object* spawn_objects[] = { scuttlebug };
u32 models[] = { MODEL_SCUTTLEBUG }; u32 models[] = { MODEL_SCUTTLEBUG };
network_send_spawn_objects(spawn_objects, models, 1); network_send_spawn_objects(spawn_objects, models, 1);
}
o->oAction++; o->oAction++;
o->oScuttlebugUnkF4 = 1; o->oScuttlebugUnkF4 = 1;

View file

@ -8,38 +8,46 @@ void bhv_seaweed_bundle_init(void) {
struct Object *seaweed; struct Object *seaweed;
seaweed = spawn_object(o, MODEL_SEAWEED, bhvSeaweed); seaweed = spawn_object(o, MODEL_SEAWEED, bhvSeaweed);
seaweed->oFaceAngleYaw = 14523; if (seaweed != NULL) {
seaweed->oFaceAnglePitch = 5500; seaweed->oFaceAngleYaw = 14523;
seaweed->oFaceAngleRoll = 9600; seaweed->oFaceAnglePitch = 5500;
seaweed->header.gfx.scale[0] = 1.0; seaweed->oFaceAngleRoll = 9600;
seaweed->header.gfx.scale[1] = 1.0; seaweed->header.gfx.scale[0] = 1.0;
seaweed->header.gfx.scale[2] = 1.0; seaweed->header.gfx.scale[1] = 1.0;
seaweed->header.gfx.scale[2] = 1.0;
}
//! gfx.animFrame uninitialized //! gfx.animFrame uninitialized
seaweed = spawn_object(o, MODEL_SEAWEED, bhvSeaweed); seaweed = spawn_object(o, MODEL_SEAWEED, bhvSeaweed);
seaweed->oFaceAngleYaw = 41800; if (seaweed != NULL) {
seaweed->oFaceAnglePitch = 6102; seaweed->oFaceAngleYaw = 41800;
seaweed->oFaceAngleRoll = 0; seaweed->oFaceAnglePitch = 6102;
seaweed->header.gfx.scale[0] = 0.8; seaweed->oFaceAngleRoll = 0;
seaweed->header.gfx.scale[1] = 0.9; seaweed->header.gfx.scale[0] = 0.8;
seaweed->header.gfx.scale[2] = 0.8; seaweed->header.gfx.scale[1] = 0.9;
seaweed->header.gfx.animInfo.animFrame = random_float() * 80.0f; seaweed->header.gfx.scale[2] = 0.8;
seaweed->header.gfx.animInfo.animFrame = random_float() * 80.0f;
}
seaweed = spawn_object(o, MODEL_SEAWEED, bhvSeaweed); seaweed = spawn_object(o, MODEL_SEAWEED, bhvSeaweed);
seaweed->oFaceAngleYaw = 40500; if (seaweed != NULL) {
seaweed->oFaceAnglePitch = 8700; seaweed->oFaceAngleYaw = 40500;
seaweed->oFaceAngleRoll = 4100; seaweed->oFaceAnglePitch = 8700;
seaweed->header.gfx.scale[0] = 0.8; seaweed->oFaceAngleRoll = 4100;
seaweed->header.gfx.scale[1] = 0.8; seaweed->header.gfx.scale[0] = 0.8;
seaweed->header.gfx.scale[2] = 0.8; seaweed->header.gfx.scale[1] = 0.8;
seaweed->header.gfx.animInfo.animFrame = random_float() * 80.0f; seaweed->header.gfx.scale[2] = 0.8;
seaweed->header.gfx.animInfo.animFrame = random_float() * 80.0f;
}
seaweed = spawn_object(o, MODEL_SEAWEED, bhvSeaweed); seaweed = spawn_object(o, MODEL_SEAWEED, bhvSeaweed);
seaweed->oFaceAngleYaw = 57236; if (seaweed != NULL) {
seaweed->oFaceAnglePitch = 9500; seaweed->oFaceAngleYaw = 57236;
seaweed->oFaceAngleRoll = 0; seaweed->oFaceAnglePitch = 9500;
seaweed->header.gfx.scale[0] = 1.2; seaweed->oFaceAngleRoll = 0;
seaweed->header.gfx.scale[1] = 1.2; seaweed->header.gfx.scale[0] = 1.2;
seaweed->header.gfx.scale[2] = 1.2; seaweed->header.gfx.scale[1] = 1.2;
seaweed->header.gfx.animInfo.animFrame = random_float() * 80.0f; seaweed->header.gfx.scale[2] = 1.2;
seaweed->header.gfx.animInfo.animFrame = random_float() * 80.0f;
}
} }

View file

@ -48,9 +48,11 @@ void bhv_snow_mound_spawn_loop(void) {
if (o->oTimer == 64 || o->oTimer == 128 || o->oTimer == 192 || o->oTimer == 224 || o->oTimer == 256) { if (o->oTimer == 64 || o->oTimer == 128 || o->oTimer == 192 || o->oTimer == 224 || o->oTimer == 256) {
if (network_owns_object(o)) { if (network_owns_object(o)) {
sp1C = spawn_object(o, MODEL_SL_SNOW_TRIANGLE, bhvSlidingSnowMound); sp1C = spawn_object(o, MODEL_SL_SNOW_TRIANGLE, bhvSlidingSnowMound);
sp1C->oHomeX = o->oPosX; if (sp1C != NULL) {
sp1C->oHomeY = o->oPosY; sp1C->oHomeX = o->oPosX;
sp1C->oHomeZ = o->oPosZ; sp1C->oHomeY = o->oPosY;
sp1C->oHomeZ = o->oPosZ;
}
network_send_object(o); network_send_object(o);
} }
} }

View file

@ -114,9 +114,11 @@ void snufit_act_shoot(void) {
o->oSnufitRecoil = -30; o->oSnufitRecoil = -30;
o->oTimer = 0; o->oTimer = 0;
struct Object* spawn_objects[] = { bullet }; if (bullet != NULL) {
u32 models[] = { MODEL_BOWLING_BALL }; struct Object* spawn_objects[] = { bullet };
network_send_spawn_objects(spawn_objects, models, 1); u32 models[] = { MODEL_BOWLING_BALL };
network_send_spawn_objects(spawn_objects, models, 1);
}
} else { } else {
cur_obj_play_sound_2(SOUND_OBJ_SNUFIT_SHOOT); cur_obj_play_sound_2(SOUND_OBJ_SNUFIT_SHOOT);
o->oSnufitRecoil = -30; o->oSnufitRecoil = -30;

View file

@ -149,9 +149,11 @@ void bhv_spawn_star_no_level_exit(struct Object* object, u32 sp20, u8 networkSen
} }
struct Object *sp1C = spawn_object(object, MODEL_STAR, bhvSpawnedStarNoLevelExit); struct Object *sp1C = spawn_object(object, MODEL_STAR, bhvSpawnedStarNoLevelExit);
sp1C->oBehParams = sp20 << 24; if (sp1C != NULL) {
sp1C->oInteractionSubtype = INT_SUBTYPE_NO_EXIT; sp1C->oBehParams = sp20 << 24;
obj_set_angle(sp1C, 0, 0, 0); sp1C->oInteractionSubtype = INT_SUBTYPE_NO_EXIT;
obj_set_angle(sp1C, 0, 0, 0);
}
if (networkSendEvent) { if (networkSendEvent) {
network_send_spawn_star_nle(object, sp20); network_send_spawn_star_nle(object, sp20);
} }

View file

@ -117,6 +117,7 @@ void bhv_star_spawn_loop(void) {
struct Object *spawn_star(struct Object *sp30, f32 sp34, f32 sp38, f32 sp3C) { struct Object *spawn_star(struct Object *sp30, f32 sp34, f32 sp38, f32 sp3C) {
sp30 = spawn_object_abs_with_rot(o, 0, MODEL_STAR, bhvStarSpawnCoordinates, o->oPosX, o->oPosY, sp30 = spawn_object_abs_with_rot(o, 0, MODEL_STAR, bhvStarSpawnCoordinates, o->oPosX, o->oPosY,
o->oPosZ, 0, 0, 0); o->oPosZ, 0, 0, 0);
if (sp30 == NULL) { return NULL; }
sp30->oBehParams = o->oBehParams; sp30->oBehParams = o->oBehParams;
sp30->oHomeX = sp34; sp30->oHomeX = sp34;
sp30->oHomeY = sp38; sp30->oHomeY = sp38;
@ -196,7 +197,7 @@ void bhv_hidden_red_coin_star_init(void) {
if (sp36 == 0) { if (sp36 == 0) {
sp30 = sp30 =
spawn_object_abs_with_rot(o, 0, MODEL_STAR, bhvStar, o->oPosX, o->oPosY, o->oPosZ, 0, 0, 0); spawn_object_abs_with_rot(o, 0, MODEL_STAR, bhvStar, o->oPosX, o->oPosY, o->oPosZ, 0, 0, 0);
sp30->oBehParams = o->oBehParams; if (sp30 != NULL) { sp30->oBehParams = o->oBehParams; }
o->activeFlags = ACTIVE_FLAG_DEACTIVATED; o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
} }

View file

@ -16,6 +16,7 @@ void bhv_squarish_path_parent_init(void) {
s16 action = (i == 0) ? 1 : 3; s16 action = (i == 0) ? 1 : 3;
s16 offset = (i == 0) ? (-radius) : (radius); s16 offset = (i == 0) ? (-radius) : (radius);
struct Object* square = spawn_object(o, MODEL_BITDW_SQUARE_PLATFORM, bhvSquarishPathMoving); struct Object* square = spawn_object(o, MODEL_BITDW_SQUARE_PLATFORM, bhvSquarishPathMoving);
if (square == NULL) { continue; }
square->oPosX = o->oPosX + offset; square->oPosX = o->oPosX + offset;
square->oPosY = o->oPosY; square->oPosY = o->oPosY;
square->oPosZ = o->oPosZ + offset; square->oPosZ = o->oPosZ + offset;

View file

@ -86,22 +86,26 @@ void spawn_and_init_wf_platforms(s16 a, const BehaviorScript *bhv) {
s16 yaw; s16 yaw;
struct Object *platform = spawn_object(o, a, bhv); struct Object *platform = spawn_object(o, a, bhv);
yaw = o->oPlatformSpawnerUnkF4 * o->oPlatformSpawnerUnkFC + o->oPlatformSpawnerUnkF8; yaw = o->oPlatformSpawnerUnkF4 * o->oPlatformSpawnerUnkFC + o->oPlatformSpawnerUnkF8;
platform->oMoveAngleYaw = yaw; if (platform != NULL) {
platform->oPosX += o->oPlatformSpawnerUnk100 * sins(yaw); platform->oMoveAngleYaw = yaw;
platform->oPosY += 100 * o->oPlatformSpawnerUnkF4; platform->oPosX += o->oPlatformSpawnerUnk100 * sins(yaw);
platform->oPosZ += o->oPlatformSpawnerUnk100 * coss(yaw); platform->oPosY += 100 * o->oPlatformSpawnerUnkF4;
platform->oPlatformUnk110 = o->oPlatformSpawnerUnk104; platform->oPosZ += o->oPlatformSpawnerUnk100 * coss(yaw);
platform->oPlatformUnk10C = o->oPlatformSpawnerUnk108; platform->oPlatformUnk110 = o->oPlatformSpawnerUnk104;
platform->oPlatformUnk10C = o->oPlatformSpawnerUnk108;
}
o->oPlatformSpawnerUnkF4++; o->oPlatformSpawnerUnkF4++;
if (bhv == bhvWfSolidTowerPlatform || bhv == bhvWfSlidingTowerPlatform) { if (platform != NULL) {
u32 loopTime = 1 + (platform->oPlatformUnk110 / platform->oPlatformUnk10C); if (bhv == bhvWfSolidTowerPlatform || bhv == bhvWfSlidingTowerPlatform) {
loopTime *= 2; u32 loopTime = 1 + (platform->oPlatformUnk110 / platform->oPlatformUnk10C);
loopTime += 1; loopTime *= 2;
platform->areaTimerType = AREA_TIMER_TYPE_LOOP; loopTime += 1;
platform->areaTimer = 0; platform->areaTimerType = AREA_TIMER_TYPE_LOOP;
platform->areaTimerDuration = loopTime; platform->areaTimer = 0;
platform->areaTimerRunOnceCallback = load_object_collision_model; platform->areaTimerDuration = loopTime;
platform->areaTimerRunOnceCallback = load_object_collision_model;
}
} }
} }

View file

@ -123,7 +123,7 @@ struct Object* spawn_treasure_chest(s8 sp3B, s32 sp3C, s32 sp40, s32 sp44, s16 s
struct Object* sp34; struct Object* sp34;
sp34 = spawn_object_abs_with_rot(o, 0, MODEL_TREASURE_CHEST_BASE, bhvTreasureChestBottom, sp3C, sp34 = spawn_object_abs_with_rot(o, 0, MODEL_TREASURE_CHEST_BASE, bhvTreasureChestBottom, sp3C,
sp40, sp44, 0, sp4A, 0); sp40, sp44, 0, sp4A, 0);
sp34->oBehParams2ndByte = sp3B; if (sp34 != NULL) { sp34->oBehParams2ndByte = sp3B; }
return sp34; return sp34;
} }

View file

@ -46,23 +46,27 @@ void bhv_snow_leaf_particle_spawn_init(void) {
if (isSnow) { if (isSnow) {
if (random_float() < 0.5) { if (random_float() < 0.5) {
obj = spawn_object(o, MODEL_WHITE_PARTICLE_DL, bhvTreeSnow); obj = spawn_object(o, MODEL_WHITE_PARTICLE_DL, bhvTreeSnow);
scale = random_float(); if (obj != NULL) {
obj_scale_xyz(obj, scale, scale, scale); scale = random_float();
obj->oMoveAngleYaw = random_u16(); obj_scale_xyz(obj, scale, scale, scale);
obj->oForwardVel = random_float() * 5.0f; obj->oMoveAngleYaw = random_u16();
obj->oVelY = random_float() * 15.0f; obj->oForwardVel = random_float() * 5.0f;
obj->oVelY = random_float() * 15.0f;
}
} }
} else { } else {
if (random_float() < 0.3) { if (random_float() < 0.3) {
obj = spawn_object(o, MODEL_LEAVES, bhvTreeLeaf); obj = spawn_object(o, MODEL_LEAVES, bhvTreeLeaf);
scale = random_float() * 3.0f; if (obj != NULL) {
obj_scale_xyz(obj, scale, scale, scale); scale = random_float() * 3.0f;
obj->oMoveAngleYaw = random_u16(); obj_scale_xyz(obj, scale, scale, scale);
obj->oForwardVel = random_float() * 5.0f + 5.0f; obj->oMoveAngleYaw = random_u16();
obj->oVelY = random_float() * 15.0f; obj->oForwardVel = random_float() * 5.0f + 5.0f;
obj->oFaceAnglePitch = random_u16(); obj->oVelY = random_float() * 15.0f;
obj->oFaceAngleRoll = random_u16(); obj->oFaceAnglePitch = random_u16();
obj->oFaceAngleYaw = random_u16(); obj->oFaceAngleRoll = random_u16();
obj->oFaceAngleYaw = random_u16();
}
} }
} }
} }

View file

@ -93,7 +93,7 @@ void tumbling_bridge_act_1(void) {
platformObj = spawn_object_relative( platformObj = spawn_object_relative(
0, relativePlatformX, relativePlatformY + relativeInitialPlatformY, relativePlatformZ, o, 0, relativePlatformX, relativePlatformY + relativeInitialPlatformY, relativePlatformZ, o,
sTumblingBridgeParams[bridgeID].model, bhvTumblingBridgePlatform); sTumblingBridgeParams[bridgeID].model, bhvTumblingBridgePlatform);
if (platformObj == NULL) { continue; }
obj_set_collision_data(platformObj, sTumblingBridgeParams[bridgeID].segAddr); obj_set_collision_data(platformObj, sTumblingBridgeParams[bridgeID].segAddr);
} }

View file

@ -81,16 +81,18 @@ void bhv_water_bomb_spawner_update(void) {
// update the spawner // update the spawner
network_send_object(o); network_send_object(o);
// send out the waterBomb objects if (waterBombShadow != NULL) {
struct Object* spawn_objects[] = { // send out the waterBomb objects
waterBomb, struct Object* spawn_objects[] = {
waterBombShadow waterBomb,
}; waterBombShadow
u32 models[] = { };
MODEL_WATER_BOMB, u32 models[] = {
MODEL_WATER_BOMB_SHADOW MODEL_WATER_BOMB,
}; MODEL_WATER_BOMB_SHADOW
network_send_spawn_objects(spawn_objects, models, 2); };
network_send_spawn_objects(spawn_objects, models, 2);
}
} }
} }
} }

View file

@ -168,7 +168,9 @@ void water_ring_spawner_act_inactive(void) {
if ((o->oTimer == 0) || (o->oTimer == 50) || (o->oTimer == 150) || (o->oTimer == 200) if ((o->oTimer == 0) || (o->oTimer == 50) || (o->oTimer == 150) || (o->oTimer == 200)
|| (o->oTimer == 250)) { || (o->oTimer == 250)) {
waterRing = spawn_object(o, MODEL_WATER_RING, bhvJetStreamWaterRing); waterRing = spawn_object(o, MODEL_WATER_RING, bhvJetStreamWaterRing);
waterRing->oWaterRingIndex = currentObj->oWaterRingMgrNextRingIndex; if (waterRing != NULL) {
waterRing->oWaterRingIndex = currentObj->oWaterRingMgrNextRingIndex;
}
currentObj->oWaterRingMgrNextRingIndex++; currentObj->oWaterRingMgrNextRingIndex++;
if (currentObj->oWaterRingMgrNextRingIndex >= 10001) if (currentObj->oWaterRingMgrNextRingIndex >= 10001)
currentObj->oWaterRingMgrNextRingIndex = 0; currentObj->oWaterRingMgrNextRingIndex = 0;

View file

@ -122,7 +122,9 @@ void bhv_shallow_water_splash_init(void) {
if ((random_u16() & 0xFF) <= 0) // Strange if ((random_u16() & 0xFF) <= 0) // Strange
{ {
fishObj = spawn_water_droplet(o, &sWaterDropletFishParams); fishObj = spawn_water_droplet(o, &sWaterDropletFishParams);
obj_init_animation_with_sound(fishObj, blue_fish_seg3_anims_0301C2B0, 0); if (fishObj != NULL) {
obj_init_animation_with_sound(fishObj, blue_fish_seg3_anims_0301C2B0, 0);
}
} }
} }

View file

@ -4,6 +4,7 @@ void spawn_wind_particles(s16 pitch, s16 yaw) {
s32 i; s32 i;
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
struct Object *wind = spawn_object(o, MODEL_MIST, bhvWind); struct Object *wind = spawn_object(o, MODEL_MIST, bhvWind);
if (wind == NULL) { continue; }
wind->oMoveAngleYaw = yaw; wind->oMoveAngleYaw = yaw;
wind->oMoveAnglePitch = pitch; wind->oMoveAnglePitch = pitch;
} }

View file

@ -397,6 +397,7 @@ void mario_blow_off_cap(struct MarioState *m, f32 capSpeed) {
u8 capModel = m->character->capModelId; u8 capModel = m->character->capModelId;
capObject = spawn_object(m->marioObj, capModel, bhvNormalCap); capObject = spawn_object(m->marioObj, capModel, bhvNormalCap);
if (capObject == NULL) { return; }
capObject->globalPlayerIndex = gNetworkPlayers[m->playerIndex].globalIndex; capObject->globalPlayerIndex = gNetworkPlayers[m->playerIndex].globalIndex;
capObject->oBehParams = m->playerIndex + 1; capObject->oBehParams = m->playerIndex + 1;

View file

@ -47,7 +47,9 @@ void spawn_macro_abs_yrot_2params(u32 model, const BehaviorScript *behavior, s16
if (behavior != NULL) { if (behavior != NULL) {
struct Object *newObj = spawn_object_abs_with_rot( struct Object *newObj = spawn_object_abs_with_rot(
&gMacroObjectDefaultParent, 0, model, behavior, x, y, z, 0, convert_rotation(ry), 0); &gMacroObjectDefaultParent, 0, model, behavior, x, y, z, 0, convert_rotation(ry), 0);
newObj->oBehParams = ((u32) params) << 16; if (newObj != NULL) {
newObj->oBehParams = ((u32) params) << 16;
}
} }
} }
@ -60,7 +62,9 @@ void spawn_macro_abs_yrot_param1(u32 model, const BehaviorScript *behavior, s16
if (behavior != NULL) { if (behavior != NULL) {
struct Object *newObj = spawn_object_abs_with_rot( struct Object *newObj = spawn_object_abs_with_rot(
&gMacroObjectDefaultParent, 0, model, behavior, x, y, z, 0, convert_rotation(ry), 0); &gMacroObjectDefaultParent, 0, model, behavior, x, y, z, 0, convert_rotation(ry), 0);
newObj->oBehParams = ((u32) param) << 24; if (newObj != NULL) {
newObj->oBehParams = ((u32) param) << 24;
}
} }
} }
@ -72,6 +76,7 @@ void spawn_macro_abs_special(u32 model, const BehaviorScript *behavior, s16 x, s
s16 unkC) { s16 unkC) {
struct Object *newObj = struct Object *newObj =
spawn_object_abs_with_rot(&gMacroObjectDefaultParent, 0, model, behavior, x, y, z, 0, 0, 0); spawn_object_abs_with_rot(&gMacroObjectDefaultParent, 0, model, behavior, x, y, z, 0, 0, 0);
if (newObj == NULL) { return; }
// Are all three of these values unused? // Are all three of these values unused?
newObj->oMacroUnk108 = (f32) unkA; newObj->oMacroUnk108 = (f32) unkA;
@ -87,6 +92,7 @@ static void spawn_macro_coin_unknown(const BehaviorScript *behavior, s16 a1[]) {
sp3C = spawn_object_abs_with_rot(&gMacroObjectDefaultParent, 0, model, behavior, sp3C = spawn_object_abs_with_rot(&gMacroObjectDefaultParent, 0, model, behavior,
a1[1], a1[2], a1[3], 0, convert_rotation(a1[0]), 0); a1[1], a1[2], a1[3], 0, convert_rotation(a1[0]), 0);
if (sp3C == NULL) { return; }
sp3C->oUnk1A8 = a1[4]; sp3C->oUnk1A8 = a1[4];
sp3C->oBehParams = (a1[4] & 0xFF) >> 16; sp3C->oBehParams = (a1[4] & 0xFF) >> 16;
@ -160,13 +166,15 @@ void spawn_macro_objects(s16 areaIndex, s16 *macroObjList) {
0 // Z-rotation 0 // Z-rotation
); );
newObj->oUnk1A8 = macroObject[MACRO_OBJ_PARAMS]; if (newObj != NULL) {
newObj->oBehParams = ((macroObject[MACRO_OBJ_PARAMS] & 0x00FF) << 16) newObj->oUnk1A8 = macroObject[MACRO_OBJ_PARAMS];
+ (macroObject[MACRO_OBJ_PARAMS] & 0xFF00); newObj->oBehParams = ((macroObject[MACRO_OBJ_PARAMS] & 0x00FF) << 16)
newObj->oBehParams2ndByte = macroObject[MACRO_OBJ_PARAMS] & 0x00FF; + (macroObject[MACRO_OBJ_PARAMS] & 0xFF00);
newObj->respawnInfoType = RESPAWN_INFO_TYPE_16; newObj->oBehParams2ndByte = macroObject[MACRO_OBJ_PARAMS] & 0x00FF;
newObj->respawnInfo = macroObjList - 1; newObj->respawnInfoType = RESPAWN_INFO_TYPE_16;
newObj->parentObj = newObj; newObj->respawnInfo = macroObjList - 1;
newObj->parentObj = newObj;
}
} }
} }
} }

View file

@ -946,7 +946,9 @@ s32 act_bubbled(struct MarioState* m) {
if (m->bubbleObj == NULL) { if (m->bubbleObj == NULL) {
//m->bubbleObj = spawn_object(m->marioObj, MODEL_BUBBLE, bhvBubblePlayer); //m->bubbleObj = spawn_object(m->marioObj, MODEL_BUBBLE, bhvBubblePlayer);
m->bubbleObj = spawn_object(m->marioObj, MODEL_BUBBLE_PLAYER, bhvBubblePlayer); m->bubbleObj = spawn_object(m->marioObj, MODEL_BUBBLE_PLAYER, bhvBubblePlayer);
m->bubbleObj->heldByPlayerIndex = m->playerIndex; if (m->bubbleObj != NULL) {
m->bubbleObj->heldByPlayerIndex = m->playerIndex;
}
} }
// force inactive state // force inactive state

View file

@ -297,6 +297,7 @@ void handle_save_menu(struct MarioState *m) {
*/ */
struct Object *spawn_obj_at_mario_rel_yaw(struct MarioState *m, s32 model, const BehaviorScript *behavior, s16 relYaw) { struct Object *spawn_obj_at_mario_rel_yaw(struct MarioState *m, s32 model, const BehaviorScript *behavior, s16 relYaw) {
struct Object *o = spawn_object(m->marioObj, model, behavior); struct Object *o = spawn_object(m->marioObj, model, behavior);
if (o == NULL) { return NULL; }
o->oFaceAngleYaw = m->faceAngle[1] + relYaw; o->oFaceAngleYaw = m->faceAngle[1] + relYaw;
o->oPosX = m->pos[0]; o->oPosX = m->pos[0];
@ -2239,7 +2240,9 @@ static void end_peach_cutscene_mario_landing(struct MarioState *m) {
if (m->playerIndex == 0) { if (m->playerIndex == 0) {
sEndJumboStarObj = spawn_object_abs_with_rot(gCurrentObject, 0, MODEL_STAR, bhvStaticObject, 0, sEndJumboStarObj = spawn_object_abs_with_rot(gCurrentObject, 0, MODEL_STAR, bhvStaticObject, 0,
2528, -1800, 0, 0, 0); 2528, -1800, 0, 0, 0);
obj_scale(sEndJumboStarObj, 3.0); if (sEndJumboStarObj != NULL) {
obj_scale(sEndJumboStarObj, 3.0);
}
} }
advance_cutscene_step(m); advance_cutscene_step(m);
} }
@ -2298,9 +2301,9 @@ static void end_peach_cutscene_spawn_peach(struct MarioState *m) {
sEndLeftToadObj = spawn_object_abs_with_rot(gCurrentObject, 0, MODEL_TOAD, bhvEndToad, -200, sEndLeftToadObj = spawn_object_abs_with_rot(gCurrentObject, 0, MODEL_TOAD, bhvEndToad, -200,
906, -1290, 0, 0, 0); 906, -1290, 0, 0, 0);
sEndPeachObj->oOpacity = 127; if (sEndPeachObj != NULL) { sEndPeachObj->oOpacity = 127; }
sEndRightToadObj->oOpacity = 255; if (sEndRightToadObj != NULL) { sEndRightToadObj->oOpacity = 255; }
sEndLeftToadObj->oOpacity = 255; if (sEndLeftToadObj != NULL) { sEndLeftToadObj->oOpacity = 255; }
D_8032CBE4 = 4; D_8032CBE4 = 4;
sEndPeachAnimation = 4; sEndPeachAnimation = 4;
@ -2309,7 +2312,7 @@ static void end_peach_cutscene_spawn_peach(struct MarioState *m) {
sEndToadAnims[1] = 5; sEndToadAnims[1] = 5;
} }
if (m->actionTimer >= TIMER_FADE_IN_PEACH) { if (m->actionTimer >= TIMER_FADE_IN_PEACH && sEndPeachObj != NULL) {
sEndPeachObj->oOpacity = camera_approach_f32_symmetric(sEndPeachObj->oOpacity, 255.0f, 2.0f); sEndPeachObj->oOpacity = camera_approach_f32_symmetric(sEndPeachObj->oOpacity, 255.0f, 2.0f);
} }
if (m->actionTimer >= 40) { if (m->actionTimer >= 40) {
@ -2320,7 +2323,7 @@ static void end_peach_cutscene_spawn_peach(struct MarioState *m) {
advance_cutscene_step(m); advance_cutscene_step(m);
} }
// probably added sounds later and missed the previous >= 40 check // probably added sounds later and missed the previous >= 40 check
if (m->actionTimer >= 40) { if (m->actionTimer >= 40 && sEndPeachObj != NULL) {
play_sound(SOUND_AIR_PEACH_TWINKLE, sEndPeachObj->header.gfx.cameraToObject); play_sound(SOUND_AIR_PEACH_TWINKLE, sEndPeachObj->header.gfx.cameraToObject);
} }
} }
@ -2828,9 +2831,9 @@ static s32 act_end_waving_cutscene(struct MarioState *m) {
sEndLeftToadObj = spawn_object_abs_with_rot(gCurrentObject, 0, MODEL_TOAD, bhvEndToad, -180, sEndLeftToadObj = spawn_object_abs_with_rot(gCurrentObject, 0, MODEL_TOAD, bhvEndToad, -180,
906, -1170, 0, 0, 0); 906, -1170, 0, 0, 0);
sEndPeachObj->oOpacity = 255; if (sEndPeachObj != NULL) { sEndPeachObj->oOpacity = 255; }
sEndRightToadObj->oOpacity = 255; if (sEndRightToadObj != NULL) { sEndRightToadObj->oOpacity = 255; }
sEndLeftToadObj->oOpacity = 255; if (sEndLeftToadObj != NULL) { sEndLeftToadObj->oOpacity = 255; }
sEndPeachAnimation = 11; sEndPeachAnimation = 11;
sEndToadAnims[0] = 6; sEndToadAnims[0] = 6;

View file

@ -287,6 +287,7 @@ void bhv_toad_message_init(void) {
static void star_door_unlock_spawn_particles(s16 angleOffset) { static void star_door_unlock_spawn_particles(s16 angleOffset) {
struct Object *sparkleParticle = spawn_object(gCurrentObject, 0, bhvSparkleSpawn); struct Object *sparkleParticle = spawn_object(gCurrentObject, 0, bhvSparkleSpawn);
if (sparkleParticle == NULL) { return; }
sparkleParticle->oPosX += sparkleParticle->oPosX +=
100.0f * sins((gCurrentObject->oUnlockDoorStarTimer * 0x2800) + angleOffset); 100.0f * sins((gCurrentObject->oUnlockDoorStarTimer * 0x2800) + angleOffset);

View file

@ -682,9 +682,11 @@ void obj_spawn_yellow_coins(struct Object *obj, s8 nCoins) {
rng_position_init(o->oPosX, o->oPosY, o->oPosZ); rng_position_init(o->oPosX, o->oPosY, o->oPosZ);
for (count = 0; count < nCoins; count++) { for (count = 0; count < nCoins; count++) {
coin = spawn_object(obj, MODEL_YELLOW_COIN, bhvMovingYellowCoin); coin = spawn_object(obj, MODEL_YELLOW_COIN, bhvMovingYellowCoin);
coin->oForwardVel = random_float() * 20; if (coin != NULL) {
coin->oVelY = random_float() * 40 + 20; coin->oForwardVel = random_float() * 20;
coin->oMoveAngleYaw = random_u16(); coin->oVelY = random_float() * 40 + 20;
coin->oMoveAngleYaw = random_u16();
}
} }
rng_position_finish(); rng_position_finish();
} }
@ -807,10 +809,12 @@ s32 obj_lava_death(void) {
if ((o->oTimer % 8) == 0) { if ((o->oTimer % 8) == 0) {
cur_obj_play_sound_2(SOUND_OBJ_BULLY_EXPLODE_2); cur_obj_play_sound_2(SOUND_OBJ_BULLY_EXPLODE_2);
deathSmoke = spawn_object(o, MODEL_SMOKE, bhvBobombBullyDeathSmoke); deathSmoke = spawn_object(o, MODEL_SMOKE, bhvBobombBullyDeathSmoke);
deathSmoke->oPosX += random_float() * 20.0f; if (deathSmoke != NULL) {
deathSmoke->oPosY += random_float() * 20.0f; deathSmoke->oPosX += random_float() * 20.0f;
deathSmoke->oPosZ += random_float() * 20.0f; deathSmoke->oPosY += random_float() * 20.0f;
deathSmoke->oForwardVel = random_float() * 10.0f; deathSmoke->oPosZ += random_float() * 20.0f;
deathSmoke->oForwardVel = random_float() * 10.0f;
}
} }
return FALSE; return FALSE;
@ -827,6 +831,7 @@ void spawn_orange_number(s8 behParam, s16 relX, s16 relY, s16 relZ) {
} }
orangeNumber = spawn_object_relative(behParam, relX, relY, relZ, o, MODEL_NUMBER, bhvOrangeNumber); orangeNumber = spawn_object_relative(behParam, relX, relY, relZ, o, MODEL_NUMBER, bhvOrangeNumber);
if (orangeNumber == NULL) { return; }
orangeNumber->oPosY += 25.0f; orangeNumber->oPosY += 25.0f;
} }

View file

@ -516,6 +516,7 @@ struct Object *spawn_object_abs_with_rot(struct Object *parent, s16 uselessArg,
s16 x, s16 y, s16 z, s16 rx, s16 ry, s16 rz) { s16 x, s16 y, s16 z, s16 rx, s16 ry, s16 rz) {
// 'uselessArg' is unused in the function spawn_object_at_origin() // 'uselessArg' is unused in the function spawn_object_at_origin()
struct Object *newObj = spawn_object_at_origin(parent, uselessArg, model, behavior); struct Object *newObj = spawn_object_at_origin(parent, uselessArg, model, behavior);
if (newObj == NULL) { return NULL; }
obj_set_pos(newObj, x, y, z); obj_set_pos(newObj, x, y, z);
obj_set_angle(newObj, rx, ry, rz); obj_set_angle(newObj, rx, ry, rz);
@ -530,6 +531,7 @@ struct Object *spawn_object_abs_with_rot(struct Object *parent, s16 uselessArg,
struct Object *spawn_object_rel_with_rot(struct Object *parent, u32 model, const BehaviorScript *behavior, struct Object *spawn_object_rel_with_rot(struct Object *parent, u32 model, const BehaviorScript *behavior,
s16 xOff, s16 yOff, s16 zOff, s16 rx, s16 ry, UNUSED s16 rz) { s16 xOff, s16 yOff, s16 zOff, s16 rx, s16 ry, UNUSED s16 rz) {
struct Object *newObj = spawn_object_at_origin(parent, 0, model, behavior); struct Object *newObj = spawn_object_at_origin(parent, 0, model, behavior);
if (newObj == NULL) { return NULL; }
newObj->oFlags |= OBJ_FLAG_TRANSFORM_RELATIVE_TO_PARENT; newObj->oFlags |= OBJ_FLAG_TRANSFORM_RELATIVE_TO_PARENT;
obj_set_parent_relative_pos(newObj, xOff, yOff, zOff); obj_set_parent_relative_pos(newObj, xOff, yOff, zOff);
obj_set_angle(newObj, rx, ry, zOff); // Nice typo you got there Nintendo. obj_set_angle(newObj, rx, ry, zOff); // Nice typo you got there Nintendo.
@ -539,6 +541,7 @@ struct Object *spawn_object_rel_with_rot(struct Object *parent, u32 model, const
struct Object *spawn_obj_with_transform_flags(struct Object *sp20, s32 model, const BehaviorScript *sp28) { struct Object *spawn_obj_with_transform_flags(struct Object *sp20, s32 model, const BehaviorScript *sp28) {
struct Object *sp1C = spawn_object(sp20, model, sp28); struct Object *sp1C = spawn_object(sp20, model, sp28);
if (sp1C == NULL) { return NULL; }
sp1C->oFlags |= OBJ_FLAG_0020 | OBJ_FLAG_SET_THROW_MATRIX_FROM_TRANSFORM; sp1C->oFlags |= OBJ_FLAG_0020 | OBJ_FLAG_SET_THROW_MATRIX_FROM_TRANSFORM;
return sp1C; return sp1C;
} }
@ -546,6 +549,7 @@ struct Object *spawn_obj_with_transform_flags(struct Object *sp20, s32 model, co
struct Object *spawn_water_droplet(struct Object *parent, struct WaterDropletParams *params) { struct Object *spawn_water_droplet(struct Object *parent, struct WaterDropletParams *params) {
f32 randomScale; f32 randomScale;
struct Object *newObj = spawn_object(parent, params->model, params->behavior); struct Object *newObj = spawn_object(parent, params->model, params->behavior);
if (newObj == NULL) { return NULL; }
if (params->flags & WATER_DROPLET_FLAG_RAND_ANGLE) { if (params->flags & WATER_DROPLET_FLAG_RAND_ANGLE) {
newObj->oMoveAngleYaw = random_u16(); newObj->oMoveAngleYaw = random_u16();
@ -589,6 +593,7 @@ struct Object *spawn_object_at_origin(struct Object *parent, UNUSED s32 unusedAr
behaviorAddr = segmented_to_virtual(behavior); behaviorAddr = segmented_to_virtual(behavior);
obj = create_object(behaviorAddr); obj = create_object(behaviorAddr);
if (obj == NULL) { return NULL; }
obj->parentObj = parent; obj->parentObj = parent;
obj->header.gfx.areaIndex = parent->header.gfx.areaIndex; obj->header.gfx.areaIndex = parent->header.gfx.areaIndex;
@ -603,6 +608,7 @@ struct Object *spawn_object_at_origin(struct Object *parent, UNUSED s32 unusedAr
struct Object *spawn_object(struct Object *parent, s32 model, const BehaviorScript *behavior) { struct Object *spawn_object(struct Object *parent, s32 model, const BehaviorScript *behavior) {
struct Object *obj = spawn_object_at_origin(parent, 0, model, behavior); struct Object *obj = spawn_object_at_origin(parent, 0, model, behavior);
if (obj == NULL) { return NULL; }
obj_copy_pos_and_angle(obj, parent); obj_copy_pos_and_angle(obj, parent);
@ -615,6 +621,7 @@ struct Object *try_to_spawn_object(s16 offsetY, f32 scale, struct Object *parent
if (gFreeObjectList.next != NULL) { if (gFreeObjectList.next != NULL) {
obj = spawn_object(parent, model, behavior); obj = spawn_object(parent, model, behavior);
if (obj == NULL) { return NULL; }
obj->oPosY += offsetY; obj->oPosY += offsetY;
obj_scale(obj, scale); obj_scale(obj, scale);
return obj; return obj;
@ -625,6 +632,7 @@ struct Object *try_to_spawn_object(s16 offsetY, f32 scale, struct Object *parent
struct Object *spawn_object_with_scale(struct Object *parent, s32 model, const BehaviorScript *behavior, f32 scale) { struct Object *spawn_object_with_scale(struct Object *parent, s32 model, const BehaviorScript *behavior, f32 scale) {
struct Object *obj = spawn_object_at_origin(parent, 0, model, behavior); struct Object *obj = spawn_object_at_origin(parent, 0, model, behavior);
if (obj == NULL) { return NULL; }
obj_copy_pos_and_angle(obj, parent); obj_copy_pos_and_angle(obj, parent);
obj_scale(obj, scale); obj_scale(obj, scale);
@ -640,6 +648,7 @@ static void obj_build_relative_transform(struct Object *obj) {
struct Object *spawn_object_relative(s16 behaviorParam, s16 relativePosX, s16 relativePosY, s16 relativePosZ, struct Object *spawn_object_relative(s16 behaviorParam, s16 relativePosX, s16 relativePosY, s16 relativePosZ,
struct Object *parent, s32 model, const BehaviorScript *behavior) { struct Object *parent, s32 model, const BehaviorScript *behavior) {
struct Object *obj = spawn_object_at_origin(parent, 0, model, behavior); struct Object *obj = spawn_object_at_origin(parent, 0, model, behavior);
if (obj == NULL) { return NULL; }
obj_copy_pos_and_angle(obj, parent); obj_copy_pos_and_angle(obj, parent);
obj_set_parent_relative_pos(obj, relativePosX, relativePosY, relativePosZ); obj_set_parent_relative_pos(obj, relativePosX, relativePosY, relativePosZ);
@ -656,6 +665,7 @@ struct Object *spawn_object_relative_with_scale(s16 behaviorParam, s16 relativeP
s32 model, const BehaviorScript *behavior) { s32 model, const BehaviorScript *behavior) {
struct Object *obj = spawn_object_relative(behaviorParam, relativePosX, relativePosY, relativePosZ, struct Object *obj = spawn_object_relative(behaviorParam, relativePosX, relativePosY, relativePosZ,
parent, model, behavior); parent, model, behavior);
if (obj == NULL) { return NULL; }
obj_scale(obj, scale); obj_scale(obj, scale);
return obj; return obj;
@ -1741,6 +1751,7 @@ static void obj_spawn_loot_coins(struct Object *obj, s32 numCoins, f32 sp30,
obj->oNumLootCoins--; obj->oNumLootCoins--;
coin = spawn_object(obj, model, coinBehavior); coin = spawn_object(obj, model, coinBehavior);
if (coin == NULL) { return; }
obj_translate_xz_random(coin, posJitter); obj_translate_xz_random(coin, posJitter);
coin->oPosY = spawnHeight; coin->oPosY = spawnHeight;
coin->oCoinUnk110 = sp30; coin->oCoinUnk110 = sp30;
@ -1764,6 +1775,7 @@ void cur_obj_spawn_loot_coin_at_mario_pos(struct MarioState* m) {
o->oNumLootCoins--; o->oNumLootCoins--;
coin = spawn_object(o, MODEL_YELLOW_COIN, bhvSingleCoinGetsSpawned); coin = spawn_object(o, MODEL_YELLOW_COIN, bhvSingleCoinGetsSpawned);
if (coin == NULL) { return; }
coin->oVelY = 30.0f; coin->oVelY = 30.0f;
obj_copy_pos(coin, m->marioObj); obj_copy_pos(coin, m->marioObj);
@ -2235,6 +2247,7 @@ void cur_obj_spawn_particles(struct SpawnParticlesInfo *info) {
scale = random_float() * (info->sizeRange * 0.1f) + info->sizeBase * 0.1f; scale = random_float() * (info->sizeRange * 0.1f) + info->sizeBase * 0.1f;
particle = spawn_object(o, info->model, bhvWhitePuffExplosion); particle = spawn_object(o, info->model, bhvWhitePuffExplosion);
if (particle == NULL) { return; }
particle->oBehParams2ndByte = info->behParam; particle->oBehParams2ndByte = info->behParam;
particle->oMoveAngleYaw = random_u16(); particle->oMoveAngleYaw = random_u16();
@ -2488,6 +2501,7 @@ void cur_obj_call_action_function(void (*actionFunctions[])(void)) {
static struct Object *spawn_star_with_no_lvl_exit(s32 sp20, s32 sp24) { static struct Object *spawn_star_with_no_lvl_exit(s32 sp20, s32 sp24) {
struct Object *sp1C = spawn_object(o, MODEL_STAR, bhvSpawnedStarNoLevelExit); struct Object *sp1C = spawn_object(o, MODEL_STAR, bhvSpawnedStarNoLevelExit);
if (sp1C == NULL) { return NULL; }
sp1C->oSparkleSpawnUnk1B0 = sp24; sp1C->oSparkleSpawnUnk1B0 = sp24;
sp1C->oBehParams = o->oBehParams; sp1C->oBehParams = o->oBehParams;
sp1C->oBehParams2ndByte = sp20; sp1C->oBehParams2ndByte = sp20;

View file

@ -254,6 +254,7 @@ void spawn_particle(u32 activeParticleFlag, s16 model, const BehaviorScript *beh
struct Object *particle; struct Object *particle;
gCurrentObject->oActiveParticleFlags |= activeParticleFlag; gCurrentObject->oActiveParticleFlags |= activeParticleFlag;
particle = spawn_object_at_origin(gCurrentObject, 0, model, behavior); particle = spawn_object_at_origin(gCurrentObject, 0, model, behavior);
if (particle == NULL) { return; }
obj_copy_pos_and_angle(particle, gCurrentObject); obj_copy_pos_and_angle(particle, gCurrentObject);
} }
} }
@ -514,45 +515,46 @@ void spawn_objects_from_info(UNUSED s32 unused, struct SpawnInfo *spawnInfo) {
if ((spawnInfo->behaviorArg & (RESPAWN_INFO_DONT_RESPAWN << 8)) if ((spawnInfo->behaviorArg & (RESPAWN_INFO_DONT_RESPAWN << 8))
!= (RESPAWN_INFO_DONT_RESPAWN << 8)) { != (RESPAWN_INFO_DONT_RESPAWN << 8)) {
object = create_object(script); object = create_object(script);
if (object != NULL) {
// Behavior parameters are often treated as four separate bytes, but
// are stored as an s32.
object->oBehParams = spawnInfo->behaviorArg;
// The second byte of the behavior parameters is copied over to a special field
// as it is the most frequently used by objects.
object->oBehParams2ndByte = ((spawnInfo->behaviorArg) >> 16) & 0xFF;
// Behavior parameters are often treated as four separate bytes, but object->behavior = script;
// are stored as an s32. object->unused1 = 0;
object->oBehParams = spawnInfo->behaviorArg;
// The second byte of the behavior parameters is copied over to a special field
// as it is the most frequently used by objects.
object->oBehParams2ndByte = ((spawnInfo->behaviorArg) >> 16) & 0xFF;
object->behavior = script; // Record death/collection in the SpawnInfo
object->unused1 = 0; object->respawnInfoType = RESPAWN_INFO_TYPE_32;
object->respawnInfo = &spawnInfo->behaviorArg;
// Record death/collection in the SpawnInfo // found a player
object->respawnInfoType = RESPAWN_INFO_TYPE_32; if (spawnInfo->behaviorArg & (1 << 31) && object->behavior == bhvMario) {
object->respawnInfo = &spawnInfo->behaviorArg; u16 playerIndex = (spawnInfo->behaviorArg & ~(1 << 31));
object->oBehParams = playerIndex + 1;
// found a player gMarioObjects[playerIndex] = object;
if (spawnInfo->behaviorArg & (1 << 31) && object->behavior == bhvMario) { if (playerIndex == 0) {
u16 playerIndex = (spawnInfo->behaviorArg & ~(1 << 31)); gMarioObject = object;
object->oBehParams = playerIndex + 1; }
gMarioObjects[playerIndex] = object; geo_make_first_child(&object->header.gfx.node);
if (playerIndex == 0) {
gMarioObject = object;
} }
geo_make_first_child(&object->header.gfx.node);
geo_obj_init_spawninfo(&object->header.gfx, spawnInfo);
object->oPosX = spawnInfo->startPos[0];
object->oPosY = spawnInfo->startPos[1];
object->oPosZ = spawnInfo->startPos[2];
object->oFaceAnglePitch = spawnInfo->startAngle[0];
object->oFaceAngleYaw = spawnInfo->startAngle[1];
object->oFaceAngleRoll = spawnInfo->startAngle[2];
object->oMoveAnglePitch = spawnInfo->startAngle[0];
object->oMoveAngleYaw = spawnInfo->startAngle[1];
object->oMoveAngleRoll = spawnInfo->startAngle[2];
} }
geo_obj_init_spawninfo(&object->header.gfx, spawnInfo);
object->oPosX = spawnInfo->startPos[0];
object->oPosY = spawnInfo->startPos[1];
object->oPosZ = spawnInfo->startPos[2];
object->oFaceAnglePitch = spawnInfo->startAngle[0];
object->oFaceAngleYaw = spawnInfo->startAngle[1];
object->oFaceAngleRoll = spawnInfo->startAngle[2];
object->oMoveAnglePitch = spawnInfo->startAngle[0];
object->oMoveAngleYaw = spawnInfo->startAngle[1];
object->oMoveAngleRoll = spawnInfo->startAngle[2];
} }
spawnInfo = spawnInfo->next; spawnInfo = spawnInfo->next;

View file

@ -233,8 +233,7 @@ struct Object *allocate_object(struct ObjectNode *objList) {
// If no unimportant object exists, then the object pool is exhausted. // If no unimportant object exists, then the object pool is exhausted.
if (unimportantObj == NULL) { if (unimportantObj == NULL) {
// We've met with a terrible fate. // We've met with a terrible fate.
while (TRUE) { return NULL;
}
} else { } else {
// If an unimportant object does exist, unload it and take its slot. // If an unimportant object does exist, unload it and take its slot.
unload_object(unimportantObj); unload_object(unimportantObj);
@ -347,6 +346,7 @@ struct Object *create_object(const BehaviorScript *bhvScript) {
objList = &gObjectLists[objListIndex]; objList = &gObjectLists[objListIndex];
obj = allocate_object(objList); obj = allocate_object(objList);
if (obj == NULL) { return NULL; }
obj->curBhvCommand = bhvScript; obj->curBhvCommand = bhvScript;
obj->behavior = behavior; obj->behavior = behavior;

View file

@ -50,6 +50,7 @@ void exec_anim_sound_state(struct SoundState *soundStates) {
*/ */
void create_sound_spawner(s32 soundMagic) { void create_sound_spawner(s32 soundMagic) {
struct Object *obj = spawn_object(gCurrentObject, 0, bhvSoundSpawner); struct Object *obj = spawn_object(gCurrentObject, 0, bhvSoundSpawner);
if (obj == NULL) { return; }
obj->oSoundEffectUnkF4 = soundMagic; obj->oSoundEffectUnkF4 = soundMagic;
} }

View file

@ -99,6 +99,7 @@ void render_100_coin_star(u8 stars) {
// If the 100 coin star has been collected, create a new star selector next to the coin score. // If the 100 coin star has been collected, create a new star selector next to the coin score.
sStarSelectorModels[6] = spawn_object_abs_with_rot(gCurrentObject, 0, MODEL_STAR, sStarSelectorModels[6] = spawn_object_abs_with_rot(gCurrentObject, 0, MODEL_STAR,
bhvActSelectorStarType, 370, 24, -300, 0, 0, 0); bhvActSelectorStarType, 370, 24, -300, 0, 0, 0);
if (sStarSelectorModels[6] == NULL) { return; }
sStarSelectorModels[6]->oStarSelectorSize = 0.8; sStarSelectorModels[6]->oStarSelectorSize = 0.8;
sStarSelectorModels[6]->oStarSelectorType = STAR_SELECTOR_100_COINS; sStarSelectorModels[6]->oStarSelectorType = STAR_SELECTOR_100_COINS;
} }
@ -158,6 +159,7 @@ void bhv_act_selector_init(void) {
sStarSelectorModels[i] = sStarSelectorModels[i] =
spawn_object_abs_with_rot(gCurrentObject, 0, selectorModelIDs[i], bhvActSelectorStarType, spawn_object_abs_with_rot(gCurrentObject, 0, selectorModelIDs[i], bhvActSelectorStarType,
75 + sVisibleStars * -75 + i * 152, 248, -300, 0, 0, 0); 75 + sVisibleStars * -75 + i * 152, 248, -300, 0, 0, 0);
if (sStarSelectorModels[i] == NULL) { continue; }
sStarSelectorModels[i]->oStarSelectorSize = 1.0f; sStarSelectorModels[i]->oStarSelectorSize = 1.0f;
} }

View file

@ -139,6 +139,7 @@ static void debug_reload_lua(void) {
static void debug_spawn_object(void) { static void debug_spawn_object(void) {
struct Object* box = spawn_object(gMarioStates[0].marioObj, MODEL_BREAKABLE_BOX_SMALL, bhvBreakableBoxSmall); struct Object* box = spawn_object(gMarioStates[0].marioObj, MODEL_BREAKABLE_BOX_SMALL, bhvBreakableBoxSmall);
if (box == NULL) { return; }
if (!network_set_sync_id(box)) { if (!network_set_sync_id(box)) {
box->activeFlags = ACTIVE_FLAG_DEACTIVATED; box->activeFlags = ACTIVE_FLAG_DEACTIVATED;
return; return;

View file

@ -22,6 +22,11 @@ struct Object* spawn_object_sync(enum BehaviorId behaviorId, enum ModelExtendedI
} }
struct Object* obj = spawn_object(gMarioStates[0].marioObj, loadedModelId, behavior); struct Object* obj = spawn_object(gMarioStates[0].marioObj, loadedModelId, behavior);
if (obj == NULL) {
LOG_ERROR("failed to allocate object");
return NULL;
}
if (!network_set_sync_id(obj)) { if (!network_set_sync_id(obj)) {
obj->activeFlags = ACTIVE_FLAG_DEACTIVATED; obj->activeFlags = ACTIVE_FLAG_DEACTIVATED;
LOG_ERROR("failed to set sync id"); LOG_ERROR("failed to set sync id");

View file

@ -209,18 +209,20 @@ void network_receive_area(struct Packet* p) {
LOG_INFO("rx respawner"); LOG_INFO("rx respawner");
if (syncId < RESERVED_IDS_SYNC_OBJECT_OFFSET) { if (syncId < RESERVED_IDS_SYNC_OBJECT_OFFSET) {
struct Object* respawner = spawn_object_abs_with_rot(gMarioStates[0].marioObj, 0, MODEL_NONE, bhvRespawner, posX, posY, posZ, 0, 0, 0); struct Object* respawner = spawn_object_abs_with_rot(gMarioStates[0].marioObj, 0, MODEL_NONE, bhvRespawner, posX, posY, posZ, 0, 0, 0);
respawner->parentObj = respawner; if (respawner != NULL) {
respawner->oBehParams = behParams; respawner->parentObj = respawner;
respawner->oRespawnerModelToRespawn = respawnerModelToRespawn; respawner->oBehParams = behParams;
respawner->oRespawnerMinSpawnDist = respawnerMinSpawnDist; respawner->oRespawnerModelToRespawn = respawnerModelToRespawn;
respawner->oRespawnerBehaviorToRespawn = get_behavior_from_id(behaviorToRespawn); respawner->oRespawnerMinSpawnDist = respawnerMinSpawnDist;
respawner->oSyncID = syncId; respawner->oRespawnerBehaviorToRespawn = get_behavior_from_id(behaviorToRespawn);
respawner->oSyncID = syncId;
}
struct Object* o = so->o; struct Object* o = so->o;
o->oSyncID = 0; o->oSyncID = 0;
o->activeFlags = ACTIVE_FLAG_DEACTIVATED; o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
so->o = respawner; if (respawner != NULL) { so->o = respawner; }
LOG_INFO("rx respawner replaced!"); LOG_INFO("rx respawner replaced!");
} }
} }

View file

@ -164,6 +164,11 @@ void network_receive_spawn_objects(struct Packet* p) {
void* behavior = (void*)get_behavior_from_id(data.behaviorId); void* behavior = (void*)get_behavior_from_id(data.behaviorId);
struct Object* o = spawn_object(parentObj, data.model, behavior); struct Object* o = spawn_object(parentObj, data.model, behavior);
if (o == NULL) {
LOG_ERROR("ERROR: failed to allocate object!");
return;
}
o->globalPlayerIndex = data.globalPlayerIndex; o->globalPlayerIndex = data.globalPlayerIndex;
o->createdThroughNetwork = true; o->createdThroughNetwork = true;
memcpy(o->rawData.asU32, data.rawData, sizeof(u32) * 80); memcpy(o->rawData.asU32, data.rawData, sizeof(u32) * 80);