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
#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_MAD_PIANO 0x57 // mad_piano_geo
#define MODEL_BOOKEND_PART 0x58 // bookend_part_geo
@ -561,7 +561,7 @@
#define MODEL_PEACH 0xDE // peach_geo
#define MODEL_CHUCKYA 0xDF // chuckya_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)
#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);
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;
return BHV_PROC_CONTINUE;
@ -208,9 +210,11 @@ static s32 bhv_cmd_spawn_obj(void) {
const BehaviorScript *behavior = BHV_CMD_GET_VPTR(2);
struct Object *object = spawn_object_at_origin(gCurrentObject, 0, model, behavior);
obj_copy_pos_and_angle(object, gCurrentObject);
// TODO: Does this cmd need renaming? This line is the only difference between this and the above func.
gCurrentObject->prevObj = object;
if (object != NULL) {
obj_copy_pos_and_angle(object, gCurrentObject);
// TODO: Does this cmd need renaming? This line is the only difference between this and the above func.
gCurrentObject->prevObj = object;
}
gCurBhvCommand += 3;
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);
struct Object *child = spawn_object_at_origin(gCurrentObject, 0, modelID, behavior);
obj_copy_pos_and_angle(child, gCurrentObject);
child->oBehParams2ndByte = bhvParam;
if (child != NULL) {
obj_copy_pos_and_angle(child, gCurrentObject);
child->oBehParams2ndByte = bhvParam;
}
gCurBhvCommand += 3;
return BHV_PROC_CONTINUE;

View file

@ -60,10 +60,14 @@ void bhv_beta_trampoline_top_loop(void) {
struct Object *trampolinePart;
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->oPosY -= 150.0f;
if (trampolinePart != NULL) {
trampolinePart->oPosY -= 150.0f;
}
}
// 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
for (i = 0; i < 15; i++) {
fish = spawn_object_relative(0, 300, 0, -200, o, MODEL_FISH, bhvBlueFish);
if (fish == NULL) { continue; }
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);
else {
explosion = spawn_object(o, MODEL_EXPLOSION, bhvExplosion);
explosion->oGraphYOffset += 100.0f;
if (explosion != NULL) {
explosion->oGraphYOffset += 100.0f;
}
bobomb_spawn_coin();
create_respawner(MODEL_BLACK_BOBOMB, bhvBobomb, 3000);

View file

@ -134,7 +134,7 @@ void bhv_courtyard_boo_triplet_init(void) {
MODEL_BOO,
bhvGhostHuntBoo
);
if (boo == NULL) { continue; }
boo->oMoveAngleYaw = random_u16();
}
}
@ -841,7 +841,9 @@ void bhv_boo_with_cage_init(void) {
obj_mark_for_deletion(o);
} else {
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 - o->oMerryGoRoundBooManagerNumBoosKilled < 2) {
struct Object* boo = spawn_object(o, MODEL_BOO, bhvMerryGoRoundBoo);
network_set_sync_id(boo);
struct Object* spawn_objects[] = { boo };
u32 models[] = { MODEL_BOO };
network_send_spawn_objects(spawn_objects, models, 1);
if (boo != NULL) {
network_set_sync_id(boo);
struct Object* spawn_objects[] = { boo };
u32 models[] = { MODEL_BOO };
network_send_spawn_objects(spawn_objects, models, 1);
}
o->oMerryGoRoundBooManagerNumBoosSpawned++;
network_send_object(o);
@ -898,12 +901,14 @@ void bhv_merry_go_round_boo_manager_loop(void) {
if (o->oMerryGoRoundBooManagerNumBoosKilled > 4) {
if (player == gMarioObjects[0]) {
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);
struct Object* spawn_objects[] = { boo };
u32 models[] = { MODEL_BOO };
network_send_spawn_objects(spawn_objects, models, 1);
network_set_sync_id(boo);
struct Object* spawn_objects[] = { boo };
u32 models[] = { MODEL_BOO };
network_send_spawn_objects(spawn_objects, models, 1);
}
o->oAction = 2;
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 ((o->oTimer & 0x3F) == 0) {
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 };
u32 models[] = { MODEL_HMC_ROLLING_ROCK };
network_send_spawn_objects(spawn_objects, models, 1);
struct Object* spawn_objects[] = { sp1C };
u32 models[] = { MODEL_HMC_ROLLING_ROCK };
network_send_spawn_objects(spawn_objects, models, 1);
}
}
} else {
if ((o->oTimer & 0x7F) == 0) {
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 };
u32 models[] = { MODEL_HMC_ROLLING_ROCK };
network_send_spawn_objects(spawn_objects, models, 1);
struct Object* spawn_objects[] = { sp1C };
u32 models[] = { MODEL_HMC_ROLLING_ROCK };
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)) {
sp2C = spawn_object(o, MODEL_RED_FLAME, bhvBouncingFireballFlame);
sp28 = (10 - o->oTimer) * 0.5;
obj_scale_xyz(sp2C, sp28, sp28, sp28);
if (o->oTimer == 0)
obj_become_tangible(sp2C);
if (sp2C != NULL) {
obj_scale_xyz(sp2C, sp28, sp28, sp28);
if (o->oTimer == 0)
obj_become_tangible(sp2C);
struct Object* spawn_objects[] = { sp2C };
u32 models[] = { MODEL_RED_FLAME };
network_send_spawn_objects(spawn_objects, models, 1);
struct Object* spawn_objects[] = { sp2C };
u32 models[] = { MODEL_RED_FLAME };
network_send_spawn_objects(spawn_objects, models, 1);
}
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
bowlingBall = spawn_object(o, MODEL_BOWLING_BALL, bhvBowlingBall);
bowlingBall->oBehParams2ndByte = o->oBehParams2ndByte;
if (bowlingBall != NULL) {
bowlingBall->oBehParams2ndByte = o->oBehParams2ndByte;
// send out the bowlingBall object
struct Object* spawn_objects[] = { bowlingBall };
u32 models[] = { MODEL_BOWLING_BALL };
network_send_spawn_objects(spawn_objects, models, 1);
// send out the bowlingBall object
struct Object* spawn_objects[] = { bowlingBall };
u32 models[] = { MODEL_BOWLING_BALL };
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) {
// this branch only runs for one player at a time
bowlingBall = spawn_object(o, MODEL_BOWLING_BALL, bhvBowlingBall);
bowlingBall->oBehParams2ndByte = o->oBehParams2ndByte;
if (bowlingBall != NULL) {
bowlingBall->oBehParams2ndByte = o->oBehParams2ndByte;
// send out the bowlingBall object
struct Object* spawn_objects[] = { bowlingBall };
u32 models[] = { MODEL_BOWLING_BALL };
network_send_spawn_objects(spawn_objects, models, 1);
// send out the bowlingBall object
struct Object* spawn_objects[] = { bowlingBall };
u32 models[] = { MODEL_BOWLING_BALL };
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);
if (marioState->playerIndex == 0) {
struct Object* flame = spawn_object(o, MODEL_RED_FLAME, bhvFlameMovingForwardGrowing);
struct Object* spawn_objects[] = { flame };
u32 models[] = { MODEL_RED_FLAME };
network_send_spawn_objects(spawn_objects, models, 1);
if (flame != NULL) {
struct Object* spawn_objects[] = { flame };
u32 models[] = { MODEL_RED_FLAME };
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);
if (marioState->playerIndex == 0) {
wave = spawn_object(o, MODEL_BOWSER_WAVE, bhvBowserShockWave);
wave->oPosY = o->oFloorHeight;
if (wave != NULL) {
wave->oPosY = o->oFloorHeight;
struct Object* spawn_objects[] = { wave };
u32 models[] = { MODEL_BOWSER_WAVE };
network_send_spawn_objects(spawn_objects, models, 1);
struct Object* spawn_objects[] = { wave };
u32 models[] = { MODEL_BOWSER_WAVE };
network_send_spawn_objects(spawn_objects, models, 1);
}
}
return 1;
}
@ -847,7 +850,7 @@ void bowser_spawn_grand_star_key(void) {
reward = (prevReward != NULL) ? prevReward : spawn_object(o, MODEL_STAR, bhvGrandStar);
gSecondCameraFocus = reward;
if (prevReward == NULL) {
if (prevReward == NULL && reward != NULL) {
// set the home position
reward->oHomeX = reward->oPosX;
reward->oHomeY = reward->oPosY;
@ -862,7 +865,7 @@ void bowser_spawn_grand_star_key(void) {
gSecondCameraFocus = reward;
cur_obj_play_sound_2(SOUND_GENERAL2_BOWSER_KEY);
if (prevReward == NULL) {
if (prevReward == NULL && reward != NULL) {
// set the home position
reward->oHomeX = reward->oPosX;
reward->oHomeY = reward->oPosY;
@ -1801,8 +1804,10 @@ void bhv_blue_flames_group_loop(void) {
if ((o->oTimer & 1) == 0) {
for (i = 0; i < 3; i++) {
flame = spawn_object(o, MODEL_BLUE_FLAME, bhvFlameBouncing);
flame->oMoveAngleYaw += i * 0x5555;
flame->header.gfx.scale[0] = o->oBlueFlameUnkF8;
if (flame != NULL) {
flame->oMoveAngleYaw += i * 0x5555;
flame->header.gfx.scale[0] = o->oBlueFlameUnkF8;
}
}
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);
if ((o->oTimer % 4 == 0) && (o->oTimer < 20)) {
mineSmoke = spawn_object(o, MODEL_BOWSER_SMOKE, bhvBowserBombSmoke);
mineSmoke->oPosX += random_float() * 600.0f - 400.0f;
mineSmoke->oPosZ += random_float() * 600.0f - 400.0f;
mineSmoke->oVelY += random_float() * 10.0f;
if (mineSmoke != NULL) {
mineSmoke->oPosX += random_float() * 600.0f - 400.0f;
mineSmoke->oPosZ += random_float() * 600.0f - 400.0f;
mineSmoke->oVelY += random_float() * 10.0f;
}
}
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,
s8 initialAction, s8 *actionList) {
struct Object *puzzlePiece = spawn_object(o, model, behavior);
if (puzzlePiece == NULL) { return; }
puzzlePiece->oPosX += xOffset;
puzzlePiece->oPosY += 50.0f;
puzzlePiece->oPosZ += zOffset;

View file

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

View file

@ -29,6 +29,7 @@ void bhv_breakable_box_small_init(void) {
void small_breakable_box_spawn_dust(void) {
struct Object *sp24 = spawn_object(o, MODEL_SMOKE, bhvSmoke);
if (sp24 == NULL) { return; }
sp24->oPosX += (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 (gFreeObjectList.next) {
bubbleSplash = spawn_object_at_origin(o, 0, MODEL_SMALL_WATER_SPLASH, bhvBubbleSplash);
bubbleSplash->oPosX = o->oPosX;
bubbleSplash->oPosY = bubbleY + 5.0f;
bubbleSplash->oPosZ = o->oPosZ;
if (bubbleSplash != NULL) {
bubbleSplash->oPosX = o->oPosX;
bubbleSplash->oPosY = bubbleY + 5.0f;
bubbleSplash->oPosZ = o->oPosZ;
}
}
o->activeFlags = ACTIVE_FLAG_DEACTIVATED;

View file

@ -222,6 +222,7 @@ void bully_spawn_coin(void) {
#else
cur_obj_play_sound_2(SOUND_GENERAL_COIN_SPURT_2);
#endif
if (coin == NULL) { return; }
coin->oForwardVel = 10.0f;
coin->oVelY = 100.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) {
struct Object *bully =
spawn_object_abs_with_rot(o, 0, MODEL_BULLY, bhvSmallBully, arg0, arg1, arg2, 0, arg3, 00);
bully->oBullySubtype = BULLY_STYPE_MINION;
bully->oBehParams2ndByte = BULLY_BP_SIZE_SMALL;
if (bully != NULL) {
bully->oBullySubtype = BULLY_STYPE_MINION;
bully->oBehParams2ndByte = BULLY_BP_SIZE_SMALL;
}
}
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) {
struct Object* cannon = spawn_object(o, MODEL_CANNON_BASE, bhvCannon);
cannon->parentObj = cannon;
cannon->oBehParams2ndByte = o->oBehParams2ndByte;
cannon->oPosX = o->oHomeX;
cannon->oPosY = o->oHomeY;
cannon->oPosZ = o->oHomeZ;
if (cannon != NULL) {
cannon->parentObj = cannon;
cannon->oBehParams2ndByte = o->oBehParams2ndByte;
cannon->oPosX = o->oHomeX;
cannon->oPosY = o->oHomeY;
cannon->oPosZ = o->oHomeZ;
}
bhv_cannon_closed_init_non_spawn();
}

View file

@ -15,6 +15,7 @@ void bhv_castle_floor_trap_init(void) {
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);
if (sp2C == NULL) { return; }
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,
bhvCheckerboardPlatformSub);
if (sp2C == NULL) { continue; }
sp2C->oCheckerBoardPlatformUnk1AC = D_8032F754[sp34].unk2;
sp2C->oTimer = 0;
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) {
sp4C = spawn_object_relative(sp50, sp40[0], sp40[1], sp40[2], o, MODEL_YELLOW_COIN,
bhvCoinFormationSpawn);
sp4C->oCoinUnkF8 = sp38;
if (sp4C != NULL) { sp4C->oCoinUnkF8 = sp38; }
}
}
@ -260,6 +260,7 @@ void bhv_golden_coin_sparkles_loop(void) {
UNUSED s32 unused;
f32 sp24 = 30.0f;
sp2C = spawn_object(o, MODEL_SPARKLES, bhvCoinSparkles);
if (sp2C == NULL) { return; }
sp2C->oPosX += 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;
for (i = 0; i < 6; i++) {
triangle = spawn_object(o, MODEL_DIRT_ANIMATION, bhvPunchTinyTriangle);
if (triangle == NULL) { continue; }
triangle->oMoveAngleYaw = o->parentObj->oMoveAngleYaw + D_8032F2CC[2 * i] + 0x8000;
triangle->oVelY = sins(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;
for (i = 0; i < 7; i++) {
particle = spawn_object(o, MODEL_CARTOON_STAR, bhvWallTinyStarParticle);
if (particle == NULL) { continue; }
particle->oMoveAngleYaw = o->parentObj->oMoveAngleYaw + D_8032F2E4[2 * i] + 0x8000;
particle->oVelY = sins(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;
for (sp24 = 0; sp24 < sp20; sp24++) {
particle = spawn_object(o, MODEL_CARTOON_STAR, bhvPoundTinyStarParticle);
if (particle == NULL) { continue; }
particle->oMoveAngleYaw = (sp24 * 65536) / sp20;
}
}

View file

@ -55,19 +55,19 @@ void bhv_controllable_platform_sub_loop(void) {
void bhv_controllable_platform_init(void) {
controllablePlatformSubs[0] = spawn_object_rel_with_rot(o, MODEL_HMC_METAL_ARROW_PLATFORM, bhvControllablePlatformSub, 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,
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,
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,
-204, 51, 0, 0, -0x4000, 0);
controllablePlatformSubs[3]->oBehParams2ndByte = 4;
if (controllablePlatformSubs[3] != NULL) { controllablePlatformSubs[3]->oBehParams2ndByte = 4; }
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->header.gfx.node.flags);
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]->oPrevAction);
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)) {
u32 syncID = o->oSyncID;
spawnedObject = spawn_object(o, o->oRespawnerModelToRespawn, o->oRespawnerBehaviorToRespawn);
spawnedObject->oBehParams = o->oBehParams;
spawnedObject->oSyncID = syncID;
network_override_object(syncID, spawnedObject);
if (spawnedObject != NULL) {
spawnedObject->oBehParams = o->oBehParams;
spawnedObject->oSyncID = syncID;
network_override_object(syncID, spawnedObject);
}
o->oSyncID = 0;
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,
o->oHomeY, o->oHomeZ, 0, 0, 0);
u8 syncID = o->oSyncID;
respawner->oBehParams = o->oBehParams;
respawner->oRespawnerModelToRespawn = model;
respawner->oRespawnerMinSpawnDist = minSpawnDist;
respawner->oRespawnerBehaviorToRespawn = behToSpawn;
respawner->oSyncID = syncID;
if (respawner != NULL) {
respawner->oBehParams = o->oBehParams;
respawner->oRespawnerModelToRespawn = model;
respawner->oRespawnerMinSpawnDist = minSpawnDist;
respawner->oRespawnerBehaviorToRespawn = behToSpawn;
respawner->oSyncID = syncID;
}
if (syncID < RESERVED_IDS_SYNC_OBJECT_OFFSET) {
network_override_object(syncID, respawner);
if (respawner != NULL) {
network_override_object(syncID, respawner);
}
o->oSyncID = 0;
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];
drawbridge[0] = spawn_object(o, MODEL_LLL_DRAWBRIDGE_PART, bhvLllDrawbridge);
drawbridge[0]->oMoveAngleYaw = o->oMoveAngleYaw;
drawbridge[0]->oPosX += coss(o->oMoveAngleYaw) * 640.0f;
drawbridge[0]->oPosZ += sins(o->oMoveAngleYaw) * 640.0f;
if (drawbridge[0] != NULL) {
drawbridge[0]->oMoveAngleYaw = o->oMoveAngleYaw;
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]->oMoveAngleYaw = o->oMoveAngleYaw + 0x8000;
drawbridge[1]->oPosX += coss(o->oMoveAngleYaw) * -640.0f;
drawbridge[1]->oPosZ += sins(o->oMoveAngleYaw) * -640.0f;
if (drawbridge[1] != NULL) {
drawbridge[1]->oMoveAngleYaw = o->oMoveAngleYaw + 0x8000;
drawbridge[1]->oPosX += coss(o->oMoveAngleYaw) * -640.0f;
drawbridge[1]->oPosZ += sins(o->oMoveAngleYaw) * -640.0f;
}
if (!network_sync_object_initialized(o)) {
network_init_object(o, 3000.0f);
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]->oAction);
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);
sp1C = spawn_object(o, model, a0->behavior);
sp1C->oVelY = 20.0f;
sp1C->oForwardVel = 3.0f;
sp1C->oMoveAngleYaw = player->oMoveAngleYaw;
sp1C->globalPlayerIndex = player->globalPlayerIndex;
if (sp1C != NULL) {
sp1C->oVelY = 20.0f;
sp1C->oForwardVel = 3.0f;
sp1C->oMoveAngleYaw = player->oMoveAngleYaw;
sp1C->globalPlayerIndex = player->globalPlayerIndex;
}
o->oBehParams |= a0->unk2 << 24;
if (a0->model == 122)
o->oFlags |= 0x4000;
// send non-star spawn events
// 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
if (a0->behavior == bhvKoopaShell) {
network_set_sync_id(sp1C);

View file

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

View file

@ -72,7 +72,7 @@ void bhv_flamethrower_loop(void) {
o->oAction++;
o->oFlameThowerUnk110 = sp34;
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);
} else if (o->oTimer > 60)
o->oAction = 0;

View file

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

View file

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

View file

@ -8,7 +8,7 @@ void bhv_hidden_star_init(void) {
if (sp36 == 0) {
sp30 =
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;
}

View file

@ -426,11 +426,13 @@ void bhv_klepto_update(void) {
save_file_clear_flags(SAVE_FLAG_CAP_ON_KLEPTO);
struct Object* cap = spawn_object(o, capModel, bhvNormalCap);
cap->globalPlayerIndex = o->globalPlayerIndex;
if (cap != NULL) {
cap->globalPlayerIndex = o->globalPlayerIndex;
struct Object* spawn_objects[] = { cap };
u32 models[] = { capModel };
network_send_spawn_objects(spawn_objects, models, 1);
struct Object* spawn_objects[] = { cap };
u32 models[] = { capModel };
network_send_spawn_objects(spawn_objects, models, 1);
}
} else if (o->oAnimState == KLEPTO_ANIM_STATE_HOLDING_STAR) {
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);
if (marioState->playerIndex == 0) {
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 };
u32 models[] = { MODEL_KOOPA_SHELL };
network_send_spawn_objects(spawn_objects, models, 1);
struct Object* spawn_objects[] = { shell };
u32 models[] = { MODEL_KOOPA_SHELL };
network_send_spawn_objects(spawn_objects, models, 1);
}
}
//! 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);
if (gMarioStates[o->heldByPlayerIndex].forwardVel > 10.0f) {
drop = spawn_object_with_scale(o, MODEL_WHITE_PARTICLE_SMALL, bhvWaterDroplet, 1.5f);
drop->oVelY = random_float() * 30.0f;
obj_translate_xz_random(drop, 110.0f);
if (drop != NULL) {
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) {
struct Object *sp1C = spawn_object(o, MODEL_NONE, bhvSparkleSpawn);
if (sp1C == NULL) { return; }
sp1C->oPosY += a;
}

View file

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

View file

@ -4,12 +4,14 @@ void hexagonal_ring_spawn_flames(void) {
struct Object *sp1C;
f32 size;
sp1C = spawn_object(o, MODEL_RED_FLAME, bhvVolcanoFlames);
sp1C->oPosY += 550.0f;
sp1C->oMoveAngleYaw = random_u16() << 0x10 >> 0x10;
sp1C->oForwardVel = random_float() * 40.0f + 20.0f;
sp1C->oVelY = random_float() * 50.0f + 10.0f;
size = random_float() * 6.0 + 3.0;
obj_scale_xyz(sp1C, size, size, size);
if (sp1C != NULL) {
sp1C->oPosY += 550.0f;
sp1C->oMoveAngleYaw = random_u16() << 0x10 >> 0x10;
sp1C->oForwardVel = random_float() * 40.0f + 20.0f;
sp1C->oVelY = random_float() * 50.0f + 10.0f;
size = random_float() * 6.0 + 3.0;
obj_scale_xyz(sp1C, size, size, size);
}
if (random_float() < 0.1)
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;
for (i = 0; i < sp20; i++) {
sp2C = spawn_object(o, MODEL_RED_FLAME, bhvLllRotatingHexFlame);
sp2C->oLllRotatingHexFlameUnkF4 += sp1C;
sp2C->oLllRotatingHexFlameUnkF8 = o->oPosY - 200.0f;
sp2C->oLllRotatingHexFlameUnkFC += sp18;
obj_scale_xyz(sp2C, 6.0f, 6.0f, 6.0f);
if (sp2C != NULL) {
sp2C->oLllRotatingHexFlameUnkF4 += sp1C;
sp2C->oLllRotatingHexFlameUnkF8 = o->oPosY - 200.0f;
sp2C->oLllRotatingHexFlameUnkFC += sp18;
obj_scale_xyz(sp2C, 6.0f, 6.0f, 6.0f);
}
sp1C += sins(a0) * 150.0f;
sp18 += coss(a0) * 150.0f;
}

View file

@ -27,7 +27,9 @@ static struct ObjectHitbox sMantaRayHitbox = {
void bhv_manta_ray_init(void) {
struct Object *sp1C;
sp1C = spawn_object(o, MODEL_NONE, bhvMantaRayRingManager);
o->parentObj = sp1C;
if (sp1C != NULL) {
o->parentObj = sp1C;
}
obj_set_hitbox(o, &sMantaRayHitbox);
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->oMoveAnglePitch);
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) {
@ -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) {
sp18 = spawn_object(o, MODEL_WATER_RING, bhvMantaRayWaterRing);
sp18->oFaceAngleYaw = o->oMoveAngleYaw;
sp18->oFaceAnglePitch = o->oMoveAnglePitch + 0x4000;
sp18->oPosX = o->oPosX + 200.0f * sins(o->oMoveAngleYaw + 0x8000);
sp18->oPosY = o->oPosY + 10.0f + 200.0f * sins(o->oMoveAnglePitch);
sp18->oPosZ = o->oPosZ + 200.0f * coss(o->oMoveAngleYaw + 0x8000);
sp18->oWaterRingIndex = sp1C->oWaterRingMgrNextRingIndex;
if (sp18 != NULL) {
sp18->oFaceAngleYaw = o->oMoveAngleYaw;
sp18->oFaceAnglePitch = o->oMoveAnglePitch + 0x4000;
sp18->oPosX = o->oPosX + 200.0f * sins(o->oMoveAngleYaw + 0x8000);
sp18->oPosY = o->oPosY + 10.0f + 200.0f * sins(o->oMoveAnglePitch);
sp18->oPosZ = o->oPosZ + 200.0f * coss(o->oMoveAngleYaw + 0x8000);
sp18->oWaterRingIndex = sp1C->oWaterRingMgrNextRingIndex;
}
sp1C->oWaterRingMgrNextRingIndex++;
if (sp1C->oWaterRingMgrNextRingIndex > 0x2710)
sp1C->oWaterRingMgrNextRingIndex = 0;
struct Object* spawn_objects[] = { sp18 };
u32 models[] = { MODEL_WATER_RING };
network_send_spawn_objects(spawn_objects, models, 1);
if (sp18 != NULL) {
struct Object* spawn_objects[] = { sp18 };
u32 models[] = { MODEL_WATER_RING };
network_send_spawn_objects(spawn_objects, models, 1);
}
network_send_object(o);
}

View file

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

View file

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

View file

@ -40,13 +40,15 @@ void spawn_mr_i_particle(void) {
struct Object *particle;
f32 sp18 = o->header.gfx.scale[1];
particle = spawn_object(o, MODEL_PURPLE_MARBLE, bhvMrIParticle);
particle->oPosY += 50.0f * sp18;
particle->oPosX += sins(o->oMoveAngleYaw) * 90.0f * sp18;
particle->oPosZ += coss(o->oMoveAngleYaw) * 90.0f * sp18;
if (particle != NULL) {
particle->oPosY += 50.0f * sp18;
particle->oPosX += sins(o->oMoveAngleYaw) * 90.0f * sp18;
particle->oPosZ += coss(o->oMoveAngleYaw) * 90.0f * sp18;
struct Object* spawn_objects[] = { particle };
u32 models[] = { MODEL_PURPLE_MARBLE };
network_send_spawn_objects(spawn_objects, models, 1);
struct Object* spawn_objects[] = { particle };
u32 models[] = { MODEL_PURPLE_MARBLE };
network_send_spawn_objects(spawn_objects, models, 1);
}
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++) {
if (spawn_objects[i] == NULL) { continue; }
spawn_objects[i]->parentObj = 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) {
sp1C = spawn_object(o, MODEL_SPARKLES, bhvGoldenCoinSparkles);
sp1C->oPosY -= 30.f;
if (sp1C != NULL) {
sp1C->oPosY -= 30.f;
}
o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
}
}

View file

@ -29,7 +29,9 @@ void bhv_giant_pole_loop(void) {
struct Object *topBall;
if (o->oTimer == 0) {
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();
}

View file

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

View file

@ -53,10 +53,12 @@ void bhv_pyramid_top_spinning(void) {
// with a random velocity and angle.
if (o->oTimer < 90) {
pyramidFragment = spawn_object(o, MODEL_DIRT_ANIMATION, bhvPyramidTopFragment);
pyramidFragment->oForwardVel = random_float() * 10.0f + 20.0f;
pyramidFragment->oMoveAngleYaw = random_u16();
pyramidFragment->oPyramidTopFragmentsScale = 0.8f;
pyramidFragment->oGravity = random_float() + 2.0f;
if (pyramidFragment != NULL) {
pyramidFragment->oForwardVel = random_float() * 10.0f + 20.0f;
pyramidFragment->oMoveAngleYaw = random_u16();
pyramidFragment->oPyramidTopFragmentsScale = 0.8f;
pyramidFragment->oGravity = random_float() + 2.0f;
}
}
// After enough time, transition to the exploding state.
@ -79,11 +81,13 @@ void bhv_pyramid_top_explode(void) {
pyramidFragment = spawn_object(
o, MODEL_DIRT_ANIMATION, bhvPyramidTopFragment
);
pyramidFragment->oForwardVel = random_float() * 50 + 80;
pyramidFragment->oVelY = random_float() * 80 + 20;
pyramidFragment->oMoveAngleYaw = random_u16();
pyramidFragment->oPyramidTopFragmentsScale = 3;
pyramidFragment->oGravity = random_float() * 2 + 5;
if (pyramidFragment != NULL) {
pyramidFragment->oForwardVel = random_float() * 50 + 80;
pyramidFragment->oVelY = random_float() * 80 + 20;
pyramidFragment->oMoveAngleYaw = random_u16();
pyramidFragment->oPyramidTopFragmentsScale = 3;
pyramidFragment->oGravity = random_float() * 2 + 5;
}
}
// 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) {
cur_obj_play_sound_2(SOUND_OBJ2_SCUTTLEBUG_ALERT);
scuttlebug = spawn_object(o, MODEL_SCUTTLEBUG, bhvScuttlebug);
scuttlebug->oScuttlebugUnkF4 = o->oScuttlebugSpawnerUnkF4;
scuttlebug->oForwardVel = 30.0f;
scuttlebug->oVelY = 80.0f;
if (scuttlebug != NULL) {
scuttlebug->oScuttlebugUnkF4 = o->oScuttlebugSpawnerUnkF4;
scuttlebug->oForwardVel = 30.0f;
scuttlebug->oVelY = 80.0f;
network_set_sync_id(scuttlebug);
struct Object* spawn_objects[] = { scuttlebug };
u32 models[] = { MODEL_SCUTTLEBUG };
network_send_spawn_objects(spawn_objects, models, 1);
network_set_sync_id(scuttlebug);
struct Object* spawn_objects[] = { scuttlebug };
u32 models[] = { MODEL_SCUTTLEBUG };
network_send_spawn_objects(spawn_objects, models, 1);
}
o->oAction++;
o->oScuttlebugUnkF4 = 1;

View file

@ -8,38 +8,46 @@ void bhv_seaweed_bundle_init(void) {
struct Object *seaweed;
seaweed = spawn_object(o, MODEL_SEAWEED, bhvSeaweed);
seaweed->oFaceAngleYaw = 14523;
seaweed->oFaceAnglePitch = 5500;
seaweed->oFaceAngleRoll = 9600;
seaweed->header.gfx.scale[0] = 1.0;
seaweed->header.gfx.scale[1] = 1.0;
seaweed->header.gfx.scale[2] = 1.0;
if (seaweed != NULL) {
seaweed->oFaceAngleYaw = 14523;
seaweed->oFaceAnglePitch = 5500;
seaweed->oFaceAngleRoll = 9600;
seaweed->header.gfx.scale[0] = 1.0;
seaweed->header.gfx.scale[1] = 1.0;
seaweed->header.gfx.scale[2] = 1.0;
}
//! gfx.animFrame uninitialized
seaweed = spawn_object(o, MODEL_SEAWEED, bhvSeaweed);
seaweed->oFaceAngleYaw = 41800;
seaweed->oFaceAnglePitch = 6102;
seaweed->oFaceAngleRoll = 0;
seaweed->header.gfx.scale[0] = 0.8;
seaweed->header.gfx.scale[1] = 0.9;
seaweed->header.gfx.scale[2] = 0.8;
seaweed->header.gfx.animInfo.animFrame = random_float() * 80.0f;
if (seaweed != NULL) {
seaweed->oFaceAngleYaw = 41800;
seaweed->oFaceAnglePitch = 6102;
seaweed->oFaceAngleRoll = 0;
seaweed->header.gfx.scale[0] = 0.8;
seaweed->header.gfx.scale[1] = 0.9;
seaweed->header.gfx.scale[2] = 0.8;
seaweed->header.gfx.animInfo.animFrame = random_float() * 80.0f;
}
seaweed = spawn_object(o, MODEL_SEAWEED, bhvSeaweed);
seaweed->oFaceAngleYaw = 40500;
seaweed->oFaceAnglePitch = 8700;
seaweed->oFaceAngleRoll = 4100;
seaweed->header.gfx.scale[0] = 0.8;
seaweed->header.gfx.scale[1] = 0.8;
seaweed->header.gfx.scale[2] = 0.8;
seaweed->header.gfx.animInfo.animFrame = random_float() * 80.0f;
if (seaweed != NULL) {
seaweed->oFaceAngleYaw = 40500;
seaweed->oFaceAnglePitch = 8700;
seaweed->oFaceAngleRoll = 4100;
seaweed->header.gfx.scale[0] = 0.8;
seaweed->header.gfx.scale[1] = 0.8;
seaweed->header.gfx.scale[2] = 0.8;
seaweed->header.gfx.animInfo.animFrame = random_float() * 80.0f;
}
seaweed = spawn_object(o, MODEL_SEAWEED, bhvSeaweed);
seaweed->oFaceAngleYaw = 57236;
seaweed->oFaceAnglePitch = 9500;
seaweed->oFaceAngleRoll = 0;
seaweed->header.gfx.scale[0] = 1.2;
seaweed->header.gfx.scale[1] = 1.2;
seaweed->header.gfx.scale[2] = 1.2;
seaweed->header.gfx.animInfo.animFrame = random_float() * 80.0f;
if (seaweed != NULL) {
seaweed->oFaceAngleYaw = 57236;
seaweed->oFaceAnglePitch = 9500;
seaweed->oFaceAngleRoll = 0;
seaweed->header.gfx.scale[0] = 1.2;
seaweed->header.gfx.scale[1] = 1.2;
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 (network_owns_object(o)) {
sp1C = spawn_object(o, MODEL_SL_SNOW_TRIANGLE, bhvSlidingSnowMound);
sp1C->oHomeX = o->oPosX;
sp1C->oHomeY = o->oPosY;
sp1C->oHomeZ = o->oPosZ;
if (sp1C != NULL) {
sp1C->oHomeX = o->oPosX;
sp1C->oHomeY = o->oPosY;
sp1C->oHomeZ = o->oPosZ;
}
network_send_object(o);
}
}

View file

@ -114,9 +114,11 @@ void snufit_act_shoot(void) {
o->oSnufitRecoil = -30;
o->oTimer = 0;
struct Object* spawn_objects[] = { bullet };
u32 models[] = { MODEL_BOWLING_BALL };
network_send_spawn_objects(spawn_objects, models, 1);
if (bullet != NULL) {
struct Object* spawn_objects[] = { bullet };
u32 models[] = { MODEL_BOWLING_BALL };
network_send_spawn_objects(spawn_objects, models, 1);
}
} else {
cur_obj_play_sound_2(SOUND_OBJ_SNUFIT_SHOOT);
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);
sp1C->oBehParams = sp20 << 24;
sp1C->oInteractionSubtype = INT_SUBTYPE_NO_EXIT;
obj_set_angle(sp1C, 0, 0, 0);
if (sp1C != NULL) {
sp1C->oBehParams = sp20 << 24;
sp1C->oInteractionSubtype = INT_SUBTYPE_NO_EXIT;
obj_set_angle(sp1C, 0, 0, 0);
}
if (networkSendEvent) {
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) {
sp30 = spawn_object_abs_with_rot(o, 0, MODEL_STAR, bhvStarSpawnCoordinates, o->oPosX, o->oPosY,
o->oPosZ, 0, 0, 0);
if (sp30 == NULL) { return NULL; }
sp30->oBehParams = o->oBehParams;
sp30->oHomeX = sp34;
sp30->oHomeY = sp38;
@ -196,7 +197,7 @@ void bhv_hidden_red_coin_star_init(void) {
if (sp36 == 0) {
sp30 =
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;
}

View file

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

View file

@ -86,22 +86,26 @@ void spawn_and_init_wf_platforms(s16 a, const BehaviorScript *bhv) {
s16 yaw;
struct Object *platform = spawn_object(o, a, bhv);
yaw = o->oPlatformSpawnerUnkF4 * o->oPlatformSpawnerUnkFC + o->oPlatformSpawnerUnkF8;
platform->oMoveAngleYaw = yaw;
platform->oPosX += o->oPlatformSpawnerUnk100 * sins(yaw);
platform->oPosY += 100 * o->oPlatformSpawnerUnkF4;
platform->oPosZ += o->oPlatformSpawnerUnk100 * coss(yaw);
platform->oPlatformUnk110 = o->oPlatformSpawnerUnk104;
platform->oPlatformUnk10C = o->oPlatformSpawnerUnk108;
if (platform != NULL) {
platform->oMoveAngleYaw = yaw;
platform->oPosX += o->oPlatformSpawnerUnk100 * sins(yaw);
platform->oPosY += 100 * o->oPlatformSpawnerUnkF4;
platform->oPosZ += o->oPlatformSpawnerUnk100 * coss(yaw);
platform->oPlatformUnk110 = o->oPlatformSpawnerUnk104;
platform->oPlatformUnk10C = o->oPlatformSpawnerUnk108;
}
o->oPlatformSpawnerUnkF4++;
if (bhv == bhvWfSolidTowerPlatform || bhv == bhvWfSlidingTowerPlatform) {
u32 loopTime = 1 + (platform->oPlatformUnk110 / platform->oPlatformUnk10C);
loopTime *= 2;
loopTime += 1;
platform->areaTimerType = AREA_TIMER_TYPE_LOOP;
platform->areaTimer = 0;
platform->areaTimerDuration = loopTime;
platform->areaTimerRunOnceCallback = load_object_collision_model;
if (platform != NULL) {
if (bhv == bhvWfSolidTowerPlatform || bhv == bhvWfSlidingTowerPlatform) {
u32 loopTime = 1 + (platform->oPlatformUnk110 / platform->oPlatformUnk10C);
loopTime *= 2;
loopTime += 1;
platform->areaTimerType = AREA_TIMER_TYPE_LOOP;
platform->areaTimer = 0;
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;
sp34 = spawn_object_abs_with_rot(o, 0, MODEL_TREASURE_CHEST_BASE, bhvTreasureChestBottom, sp3C,
sp40, sp44, 0, sp4A, 0);
sp34->oBehParams2ndByte = sp3B;
if (sp34 != NULL) { sp34->oBehParams2ndByte = sp3B; }
return sp34;
}

View file

@ -46,23 +46,27 @@ void bhv_snow_leaf_particle_spawn_init(void) {
if (isSnow) {
if (random_float() < 0.5) {
obj = spawn_object(o, MODEL_WHITE_PARTICLE_DL, bhvTreeSnow);
scale = random_float();
obj_scale_xyz(obj, scale, scale, scale);
obj->oMoveAngleYaw = random_u16();
obj->oForwardVel = random_float() * 5.0f;
obj->oVelY = random_float() * 15.0f;
if (obj != NULL) {
scale = random_float();
obj_scale_xyz(obj, scale, scale, scale);
obj->oMoveAngleYaw = random_u16();
obj->oForwardVel = random_float() * 5.0f;
obj->oVelY = random_float() * 15.0f;
}
}
} else {
if (random_float() < 0.3) {
obj = spawn_object(o, MODEL_LEAVES, bhvTreeLeaf);
scale = random_float() * 3.0f;
obj_scale_xyz(obj, scale, scale, scale);
obj->oMoveAngleYaw = random_u16();
obj->oForwardVel = random_float() * 5.0f + 5.0f;
obj->oVelY = random_float() * 15.0f;
obj->oFaceAnglePitch = random_u16();
obj->oFaceAngleRoll = random_u16();
obj->oFaceAngleYaw = random_u16();
if (obj != NULL) {
scale = random_float() * 3.0f;
obj_scale_xyz(obj, scale, scale, scale);
obj->oMoveAngleYaw = random_u16();
obj->oForwardVel = random_float() * 5.0f + 5.0f;
obj->oVelY = random_float() * 15.0f;
obj->oFaceAnglePitch = 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(
0, relativePlatformX, relativePlatformY + relativeInitialPlatformY, relativePlatformZ, o,
sTumblingBridgeParams[bridgeID].model, bhvTumblingBridgePlatform);
if (platformObj == NULL) { continue; }
obj_set_collision_data(platformObj, sTumblingBridgeParams[bridgeID].segAddr);
}

View file

@ -81,16 +81,18 @@ void bhv_water_bomb_spawner_update(void) {
// update the spawner
network_send_object(o);
// send out the waterBomb objects
struct Object* spawn_objects[] = {
waterBomb,
waterBombShadow
};
u32 models[] = {
MODEL_WATER_BOMB,
MODEL_WATER_BOMB_SHADOW
};
network_send_spawn_objects(spawn_objects, models, 2);
if (waterBombShadow != NULL) {
// send out the waterBomb objects
struct Object* spawn_objects[] = {
waterBomb,
waterBombShadow
};
u32 models[] = {
MODEL_WATER_BOMB,
MODEL_WATER_BOMB_SHADOW
};
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)
|| (o->oTimer == 250)) {
waterRing = spawn_object(o, MODEL_WATER_RING, bhvJetStreamWaterRing);
waterRing->oWaterRingIndex = currentObj->oWaterRingMgrNextRingIndex;
if (waterRing != NULL) {
waterRing->oWaterRingIndex = currentObj->oWaterRingMgrNextRingIndex;
}
currentObj->oWaterRingMgrNextRingIndex++;
if (currentObj->oWaterRingMgrNextRingIndex >= 10001)
currentObj->oWaterRingMgrNextRingIndex = 0;

View file

@ -122,7 +122,9 @@ void bhv_shallow_water_splash_init(void) {
if ((random_u16() & 0xFF) <= 0) // Strange
{
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;
for (i = 0; i < 3; i++) {
struct Object *wind = spawn_object(o, MODEL_MIST, bhvWind);
if (wind == NULL) { continue; }
wind->oMoveAngleYaw = yaw;
wind->oMoveAnglePitch = pitch;
}

View file

@ -397,6 +397,7 @@ void mario_blow_off_cap(struct MarioState *m, f32 capSpeed) {
u8 capModel = m->character->capModelId;
capObject = spawn_object(m->marioObj, capModel, bhvNormalCap);
if (capObject == NULL) { return; }
capObject->globalPlayerIndex = gNetworkPlayers[m->playerIndex].globalIndex;
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) {
struct Object *newObj = spawn_object_abs_with_rot(
&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) {
struct Object *newObj = spawn_object_abs_with_rot(
&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) {
struct Object *newObj =
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?
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,
a1[1], a1[2], a1[3], 0, convert_rotation(a1[0]), 0);
if (sp3C == NULL) { return; }
sp3C->oUnk1A8 = a1[4];
sp3C->oBehParams = (a1[4] & 0xFF) >> 16;
@ -160,13 +166,15 @@ void spawn_macro_objects(s16 areaIndex, s16 *macroObjList) {
0 // Z-rotation
);
newObj->oUnk1A8 = macroObject[MACRO_OBJ_PARAMS];
newObj->oBehParams = ((macroObject[MACRO_OBJ_PARAMS] & 0x00FF) << 16)
+ (macroObject[MACRO_OBJ_PARAMS] & 0xFF00);
newObj->oBehParams2ndByte = macroObject[MACRO_OBJ_PARAMS] & 0x00FF;
newObj->respawnInfoType = RESPAWN_INFO_TYPE_16;
newObj->respawnInfo = macroObjList - 1;
newObj->parentObj = newObj;
if (newObj != NULL) {
newObj->oUnk1A8 = macroObject[MACRO_OBJ_PARAMS];
newObj->oBehParams = ((macroObject[MACRO_OBJ_PARAMS] & 0x00FF) << 16)
+ (macroObject[MACRO_OBJ_PARAMS] & 0xFF00);
newObj->oBehParams2ndByte = macroObject[MACRO_OBJ_PARAMS] & 0x00FF;
newObj->respawnInfoType = RESPAWN_INFO_TYPE_16;
newObj->respawnInfo = macroObjList - 1;
newObj->parentObj = newObj;
}
}
}
}

View file

@ -946,7 +946,9 @@ s32 act_bubbled(struct MarioState* m) {
if (m->bubbleObj == NULL) {
//m->bubbleObj = spawn_object(m->marioObj, MODEL_BUBBLE, 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

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 *o = spawn_object(m->marioObj, model, behavior);
if (o == NULL) { return NULL; }
o->oFaceAngleYaw = m->faceAngle[1] + relYaw;
o->oPosX = m->pos[0];
@ -2239,7 +2240,9 @@ static void end_peach_cutscene_mario_landing(struct MarioState *m) {
if (m->playerIndex == 0) {
sEndJumboStarObj = spawn_object_abs_with_rot(gCurrentObject, 0, MODEL_STAR, bhvStaticObject, 0,
2528, -1800, 0, 0, 0);
obj_scale(sEndJumboStarObj, 3.0);
if (sEndJumboStarObj != NULL) {
obj_scale(sEndJumboStarObj, 3.0);
}
}
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,
906, -1290, 0, 0, 0);
sEndPeachObj->oOpacity = 127;
sEndRightToadObj->oOpacity = 255;
sEndLeftToadObj->oOpacity = 255;
if (sEndPeachObj != NULL) { sEndPeachObj->oOpacity = 127; }
if (sEndRightToadObj != NULL) { sEndRightToadObj->oOpacity = 255; }
if (sEndLeftToadObj != NULL) { sEndLeftToadObj->oOpacity = 255; }
D_8032CBE4 = 4;
sEndPeachAnimation = 4;
@ -2309,7 +2312,7 @@ static void end_peach_cutscene_spawn_peach(struct MarioState *m) {
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);
}
if (m->actionTimer >= 40) {
@ -2320,7 +2323,7 @@ static void end_peach_cutscene_spawn_peach(struct MarioState *m) {
advance_cutscene_step(m);
}
// 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);
}
}
@ -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,
906, -1170, 0, 0, 0);
sEndPeachObj->oOpacity = 255;
sEndRightToadObj->oOpacity = 255;
sEndLeftToadObj->oOpacity = 255;
if (sEndPeachObj != NULL) { sEndPeachObj->oOpacity = 255; }
if (sEndRightToadObj != NULL) { sEndRightToadObj->oOpacity = 255; }
if (sEndLeftToadObj != NULL) { sEndLeftToadObj->oOpacity = 255; }
sEndPeachAnimation = 11;
sEndToadAnims[0] = 6;

View file

@ -287,6 +287,7 @@ void bhv_toad_message_init(void) {
static void star_door_unlock_spawn_particles(s16 angleOffset) {
struct Object *sparkleParticle = spawn_object(gCurrentObject, 0, bhvSparkleSpawn);
if (sparkleParticle == NULL) { return; }
sparkleParticle->oPosX +=
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);
for (count = 0; count < nCoins; count++) {
coin = spawn_object(obj, MODEL_YELLOW_COIN, bhvMovingYellowCoin);
coin->oForwardVel = random_float() * 20;
coin->oVelY = random_float() * 40 + 20;
coin->oMoveAngleYaw = random_u16();
if (coin != NULL) {
coin->oForwardVel = random_float() * 20;
coin->oVelY = random_float() * 40 + 20;
coin->oMoveAngleYaw = random_u16();
}
}
rng_position_finish();
}
@ -807,10 +809,12 @@ s32 obj_lava_death(void) {
if ((o->oTimer % 8) == 0) {
cur_obj_play_sound_2(SOUND_OBJ_BULLY_EXPLODE_2);
deathSmoke = spawn_object(o, MODEL_SMOKE, bhvBobombBullyDeathSmoke);
deathSmoke->oPosX += random_float() * 20.0f;
deathSmoke->oPosY += random_float() * 20.0f;
deathSmoke->oPosZ += random_float() * 20.0f;
deathSmoke->oForwardVel = random_float() * 10.0f;
if (deathSmoke != NULL) {
deathSmoke->oPosX += random_float() * 20.0f;
deathSmoke->oPosY += random_float() * 20.0f;
deathSmoke->oPosZ += random_float() * 20.0f;
deathSmoke->oForwardVel = random_float() * 10.0f;
}
}
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);
if (orangeNumber == NULL) { return; }
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) {
// 'uselessArg' is unused in the function spawn_object_at_origin()
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_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,
s16 xOff, s16 yOff, s16 zOff, s16 rx, s16 ry, UNUSED s16 rz) {
struct Object *newObj = spawn_object_at_origin(parent, 0, model, behavior);
if (newObj == NULL) { return NULL; }
newObj->oFlags |= OBJ_FLAG_TRANSFORM_RELATIVE_TO_PARENT;
obj_set_parent_relative_pos(newObj, xOff, yOff, zOff);
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 *sp1C = spawn_object(sp20, model, sp28);
if (sp1C == NULL) { return NULL; }
sp1C->oFlags |= OBJ_FLAG_0020 | OBJ_FLAG_SET_THROW_MATRIX_FROM_TRANSFORM;
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) {
f32 randomScale;
struct Object *newObj = spawn_object(parent, params->model, params->behavior);
if (newObj == NULL) { return NULL; }
if (params->flags & WATER_DROPLET_FLAG_RAND_ANGLE) {
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);
obj = create_object(behaviorAddr);
if (obj == NULL) { return NULL; }
obj->parentObj = parent;
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 *obj = spawn_object_at_origin(parent, 0, model, behavior);
if (obj == NULL) { return NULL; }
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) {
obj = spawn_object(parent, model, behavior);
if (obj == NULL) { return NULL; }
obj->oPosY += offsetY;
obj_scale(obj, scale);
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 *obj = spawn_object_at_origin(parent, 0, model, behavior);
if (obj == NULL) { return NULL; }
obj_copy_pos_and_angle(obj, parent);
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 *parent, s32 model, const BehaviorScript *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_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) {
struct Object *obj = spawn_object_relative(behaviorParam, relativePosX, relativePosY, relativePosZ,
parent, model, behavior);
if (obj == NULL) { return NULL; }
obj_scale(obj, scale);
return obj;
@ -1741,6 +1751,7 @@ static void obj_spawn_loot_coins(struct Object *obj, s32 numCoins, f32 sp30,
obj->oNumLootCoins--;
coin = spawn_object(obj, model, coinBehavior);
if (coin == NULL) { return; }
obj_translate_xz_random(coin, posJitter);
coin->oPosY = spawnHeight;
coin->oCoinUnk110 = sp30;
@ -1764,6 +1775,7 @@ void cur_obj_spawn_loot_coin_at_mario_pos(struct MarioState* m) {
o->oNumLootCoins--;
coin = spawn_object(o, MODEL_YELLOW_COIN, bhvSingleCoinGetsSpawned);
if (coin == NULL) { return; }
coin->oVelY = 30.0f;
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;
particle = spawn_object(o, info->model, bhvWhitePuffExplosion);
if (particle == NULL) { return; }
particle->oBehParams2ndByte = info->behParam;
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) {
struct Object *sp1C = spawn_object(o, MODEL_STAR, bhvSpawnedStarNoLevelExit);
if (sp1C == NULL) { return NULL; }
sp1C->oSparkleSpawnUnk1B0 = sp24;
sp1C->oBehParams = o->oBehParams;
sp1C->oBehParams2ndByte = sp20;

View file

@ -254,6 +254,7 @@ void spawn_particle(u32 activeParticleFlag, s16 model, const BehaviorScript *beh
struct Object *particle;
gCurrentObject->oActiveParticleFlags |= activeParticleFlag;
particle = spawn_object_at_origin(gCurrentObject, 0, model, behavior);
if (particle == NULL) { return; }
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))
!= (RESPAWN_INFO_DONT_RESPAWN << 8)) {
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
// 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;
object->behavior = script;
object->unused1 = 0;
object->behavior = script;
object->unused1 = 0;
// Record death/collection in the SpawnInfo
object->respawnInfoType = RESPAWN_INFO_TYPE_32;
object->respawnInfo = &spawnInfo->behaviorArg;
// Record death/collection in the SpawnInfo
object->respawnInfoType = RESPAWN_INFO_TYPE_32;
object->respawnInfo = &spawnInfo->behaviorArg;
// found a player
if (spawnInfo->behaviorArg & (1 << 31) && object->behavior == bhvMario) {
u16 playerIndex = (spawnInfo->behaviorArg & ~(1 << 31));
object->oBehParams = playerIndex + 1;
gMarioObjects[playerIndex] = object;
if (playerIndex == 0) {
gMarioObject = object;
// found a player
if (spawnInfo->behaviorArg & (1 << 31) && object->behavior == bhvMario) {
u16 playerIndex = (spawnInfo->behaviorArg & ~(1 << 31));
object->oBehParams = playerIndex + 1;
gMarioObjects[playerIndex] = object;
if (playerIndex == 0) {
gMarioObject = object;
}
geo_make_first_child(&object->header.gfx.node);
}
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;

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

View file

@ -50,6 +50,7 @@ void exec_anim_sound_state(struct SoundState *soundStates) {
*/
void create_sound_spawner(s32 soundMagic) {
struct Object *obj = spawn_object(gCurrentObject, 0, bhvSoundSpawner);
if (obj == NULL) { return; }
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.
sStarSelectorModels[6] = spawn_object_abs_with_rot(gCurrentObject, 0, MODEL_STAR,
bhvActSelectorStarType, 370, 24, -300, 0, 0, 0);
if (sStarSelectorModels[6] == NULL) { return; }
sStarSelectorModels[6]->oStarSelectorSize = 0.8;
sStarSelectorModels[6]->oStarSelectorType = STAR_SELECTOR_100_COINS;
}
@ -158,6 +159,7 @@ void bhv_act_selector_init(void) {
sStarSelectorModels[i] =
spawn_object_abs_with_rot(gCurrentObject, 0, selectorModelIDs[i], bhvActSelectorStarType,
75 + sVisibleStars * -75 + i * 152, 248, -300, 0, 0, 0);
if (sStarSelectorModels[i] == NULL) { continue; }
sStarSelectorModels[i]->oStarSelectorSize = 1.0f;
}

View file

@ -139,6 +139,7 @@ static void debug_reload_lua(void) {
static void debug_spawn_object(void) {
struct Object* box = spawn_object(gMarioStates[0].marioObj, MODEL_BREAKABLE_BOX_SMALL, bhvBreakableBoxSmall);
if (box == NULL) { return; }
if (!network_set_sync_id(box)) {
box->activeFlags = ACTIVE_FLAG_DEACTIVATED;
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);
if (obj == NULL) {
LOG_ERROR("failed to allocate object");
return NULL;
}
if (!network_set_sync_id(obj)) {
obj->activeFlags = ACTIVE_FLAG_DEACTIVATED;
LOG_ERROR("failed to set sync id");

View file

@ -209,18 +209,20 @@ void network_receive_area(struct Packet* p) {
LOG_INFO("rx respawner");
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);
respawner->parentObj = respawner;
respawner->oBehParams = behParams;
respawner->oRespawnerModelToRespawn = respawnerModelToRespawn;
respawner->oRespawnerMinSpawnDist = respawnerMinSpawnDist;
respawner->oRespawnerBehaviorToRespawn = get_behavior_from_id(behaviorToRespawn);
respawner->oSyncID = syncId;
if (respawner != NULL) {
respawner->parentObj = respawner;
respawner->oBehParams = behParams;
respawner->oRespawnerModelToRespawn = respawnerModelToRespawn;
respawner->oRespawnerMinSpawnDist = respawnerMinSpawnDist;
respawner->oRespawnerBehaviorToRespawn = get_behavior_from_id(behaviorToRespawn);
respawner->oSyncID = syncId;
}
struct Object* o = so->o;
o->oSyncID = 0;
o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
so->o = respawner;
if (respawner != NULL) { so->o = respawner; }
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);
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->createdThroughNetwork = true;
memcpy(o->rawData.asU32, data.rawData, sizeof(u32) * 80);