Merge branch 'unstable' of github.com:sm64ex-coop-dev/sm64ex-coop into unstable

This commit is contained in:
MysterD 2022-03-30 19:26:06 -07:00
commit 0e50998a39
10 changed files with 210 additions and 67 deletions

View file

@ -1469,4 +1469,4 @@ MAKEFLAGS += --no-builtin-rules
-include $(DEP_FILES) -include $(DEP_FILES)
print-% : ; $(info $* is a $(flavor $*) variable set to [$($*)]) @true print-% : ; $(info $* is a $(flavor $*) variable set to [$($*)]) @true

View file

@ -301,25 +301,26 @@ void bhv_bobomb_buddy_init(void) {
} }
void bobomb_buddy_act_idle(void) { void bobomb_buddy_act_idle(void) {
UNUSED u8 filler[4]; s16 animFrame = o->header.gfx.animInfo.animFrame;
s16 sp1a = o->header.gfx.animInfo.animFrame;
UNUSED s16 collisionFlags = 0;
o->oBobombBuddyPosXCopy = o->oPosX; o->oBobombBuddyPosXCopy = o->oPosX;
o->oBobombBuddyPosYCopy = o->oPosY; o->oBobombBuddyPosYCopy = o->oPosY;
o->oBobombBuddyPosZCopy = o->oPosZ; o->oBobombBuddyPosZCopy = o->oPosZ;
collisionFlags = object_step(); object_step();
if ((sp1a == 5) || (sp1a == 16)) if ((animFrame == 5) || (animFrame == 16)) {
cur_obj_play_sound_2(SOUND_OBJ_BOBOMB_WALK); cur_obj_play_sound_2(SOUND_OBJ_BOBOMB_WALK);
}
struct Object* player = nearest_player_to_object(o); struct Object* player = nearest_player_to_object(o);
if (dist_between_objects(o, player) < 1000.0f) if (dist_between_objects(o, player) < 1000.0f) {
o->oMoveAngleYaw = approach_s16_symmetric(o->oMoveAngleYaw, obj_angle_to_object(o, player), 0x140); o->oMoveAngleYaw = approach_s16_symmetric(o->oMoveAngleYaw, obj_angle_to_object(o, player), 0x140);
}
if (o->oInteractStatus == INT_STATUS_INTERACTED) if (o->oInteractStatus == INT_STATUS_INTERACTED) {
o->oAction = BOBOMB_BUDDY_ACT_TURN_TO_TALK; o->oAction = BOBOMB_BUDDY_ACT_TURN_TO_TALK;
}
} }
/** /**
@ -345,24 +346,27 @@ void bobomb_buddy_cannon_dialog(s16 dialogFirstText, s16 dialogSecondText) {
forceCannonOpen = FALSE; forceCannonOpen = FALSE;
cannonClosed = cur_obj_nearest_object_with_behavior(bhvCannonClosed); cannonClosed = cur_obj_nearest_object_with_behavior(bhvCannonClosed);
if (cannonClosed != 0) if (cannonClosed != 0) {
o->oBobombBuddyCannonStatus = BOBOMB_BUDDY_CANNON_OPENING; o->oBobombBuddyCannonStatus = BOBOMB_BUDDY_CANNON_OPENING;
else } else {
o->oBobombBuddyCannonStatus = BOBOMB_BUDDY_CANNON_STOP_TALKING; o->oBobombBuddyCannonStatus = BOBOMB_BUDDY_CANNON_STOP_TALKING;
}
} }
break; break;
case BOBOMB_BUDDY_CANNON_OPENING: case BOBOMB_BUDDY_CANNON_OPENING:
cannonClosed = cur_obj_nearest_object_with_behavior(bhvCannonClosed); cannonClosed = cur_obj_nearest_object_with_behavior(bhvCannonClosed);
cutscene = cutscene_object(CUTSCENE_PREPARE_CANNON, cannonClosed); cutscene = cutscene_object(CUTSCENE_PREPARE_CANNON, cannonClosed);
if (cutscene == -1) if (cutscene == -1) {
o->oBobombBuddyCannonStatus = BOBOMB_BUDDY_CANNON_OPENED; o->oBobombBuddyCannonStatus = BOBOMB_BUDDY_CANNON_OPENED;
}
break; break;
case BOBOMB_BUDDY_CANNON_OPENED: case BOBOMB_BUDDY_CANNON_OPENED:
buddyText = cutscene_object_with_dialog(CUTSCENE_DIALOG, o, dialogSecondText); buddyText = cutscene_object_with_dialog(CUTSCENE_DIALOG, o, dialogSecondText);
if (buddyText != 0) if (buddyText != 0) {
o->oBobombBuddyCannonStatus = BOBOMB_BUDDY_CANNON_STOP_TALKING; o->oBobombBuddyCannonStatus = BOBOMB_BUDDY_CANNON_STOP_TALKING;
}
break; break;
case BOBOMB_BUDDY_CANNON_STOP_TALKING: case BOBOMB_BUDDY_CANNON_STOP_TALKING:
@ -400,25 +404,28 @@ void bobomb_buddy_act_talk(void) {
break; break;
case BOBOMB_BUDDY_ROLE_CANNON: case BOBOMB_BUDDY_ROLE_CANNON:
if (gCurrCourseNum == COURSE_BOB) if (gCurrCourseNum == COURSE_BOB) {
bobomb_buddy_cannon_dialog(DIALOG_004, DIALOG_105); bobomb_buddy_cannon_dialog(DIALOG_004, DIALOG_105);
else } else {
bobomb_buddy_cannon_dialog(DIALOG_047, DIALOG_106); bobomb_buddy_cannon_dialog(DIALOG_047, DIALOG_106);
}
break; break;
} }
} }
} }
void bobomb_buddy_act_turn_to_talk(void) { void bobomb_buddy_act_turn_to_talk(void) {
s16 sp1e = o->header.gfx.animInfo.animFrame; s16 animFrame = o->header.gfx.animInfo.animFrame;
if ((sp1e == 5) || (sp1e == 16)) if ((animFrame == 5) || (animFrame == 16)) {
cur_obj_play_sound_2(SOUND_OBJ_BOBOMB_WALK); cur_obj_play_sound_2(SOUND_OBJ_BOBOMB_WALK);
}
struct Object* player = nearest_player_to_object(o); struct Object *player = nearest_interacting_player_to_object(o);
s32 angleToPlayer = obj_angle_to_object(o, player); s32 angleToPlayer = obj_angle_to_object(o, player);
o->oMoveAngleYaw = approach_s16_symmetric(o->oMoveAngleYaw, angleToPlayer, 0x1000); o->oMoveAngleYaw = approach_s16_symmetric(o->oMoveAngleYaw, angleToPlayer, 0x1000);
if ((s16) o->oMoveAngleYaw == (s16) angleToPlayer) if ((s16) o->oMoveAngleYaw == (s16) angleToPlayer) {
o->oAction = BOBOMB_BUDDY_ACT_TALK; o->oAction = BOBOMB_BUDDY_ACT_TALK;
}
cur_obj_play_sound_2(SOUND_ACTION_READ_SIGN); cur_obj_play_sound_2(SOUND_ACTION_READ_SIGN);
} }

View file

@ -1,19 +1,22 @@
// bowser.c.inc // bowser.c.inc
static u32 networkBowserAnimationIndex = 0; static u32 networkBowserAnimationIndex = 0;
static u8 bowserIsDying = FALSE; static u8 bowserIsDying = FALSE;
static u8 bowserCutscenePlayed = FALSE;
static u8 bowserIsCutscenePlayer = FALSE;
void bowser_tail_anchor_act_0(void) { void bowser_tail_anchor_act_0(void) {
struct Object* bowser = o->parentObj; struct Object* bowser = o->parentObj;
struct Object* player = nearest_player_to_object(o); struct Object* player = nearest_player_to_object(o);
cur_obj_become_tangible(); cur_obj_become_tangible();
cur_obj_scale(1.0f); cur_obj_scale(1.0f);
if (bowser->oAction == 19) if (bowser->oAction == 5 || bowser->oAction == 6 || bowser->oAction == 19 || bowser->oAction == 20) {
bowser->oIntangibleTimer = -1; bowser->oIntangibleTimer = -1;
else if (obj_check_if_collided_with_object(o, player)) { } else if (obj_check_if_collided_with_object(o, player)) {
bowser->oIntangibleTimer = 0; bowser->oIntangibleTimer = 0;
o->oAction = 2; o->oAction = 2;
} else } else {
bowser->oIntangibleTimer = -1; bowser->oIntangibleTimer = -1;
}
} }
void bowser_tail_anchor_act_1(void) { void bowser_tail_anchor_act_1(void) {
@ -177,31 +180,37 @@ s32 bowser_set_anim_look_up_and_walk(void) {
s32 bowser_set_anim_slow_gait(void) { s32 bowser_set_anim_slow_gait(void) {
o->oForwardVel = 3.0f; o->oForwardVel = 3.0f;
cur_obj_init_animation_with_sound(13); cur_obj_init_animation_with_sound(13);
if (cur_obj_check_if_near_animation_end()) if (cur_obj_check_if_near_animation_end()) {
return 1; return 1;
else }
return 0; return 0;
} }
s32 bowser_set_anim_look_down(void) { s32 bowser_set_anim_look_down(void) {
cur_obj_init_animation_with_sound(14); cur_obj_init_animation_with_sound(14);
if (cur_obj_check_anim_frame(20)) if (cur_obj_check_anim_frame(20)) {
o->oForwardVel = 0.0f; o->oForwardVel = 0.0f;
if (cur_obj_check_if_near_animation_end()) }
if (cur_obj_check_if_near_animation_end()) {
return 1; return 1;
else }
return 0; return 0;
} }
void bowser_initialize_action(void) { void bowser_initialize_action(void) {
if (o->oBowserUnk88 == 0) if (o->oBowserUnk88 == 0 && !bowserCutscenePlayed) {
o->oAction = 5; o->oAction = 5;
else if (o->oBowserUnk88 == 1) } else if (o->oBowserUnk88 == 1 && !bowserCutscenePlayed) {
o->oAction = 6; o->oAction = 6;
else if (o->oBehParams2ndByte == 1) } else if (o->oBehParams2ndByte == 1) {
bowserCutscenePlayed = TRUE;
o->oAction = 13; o->oAction = 13;
else if (bowserIsCutscenePlayer) { network_send_object_reliability(o, TRUE); }
} else {
bowserCutscenePlayed = TRUE;
o->oAction = 0; o->oAction = 0;
if (bowserIsCutscenePlayer) { network_send_object_reliability(o, TRUE); }
}
} }
void bowser_act_text_wait(void) // not much void bowser_act_text_wait(void) // not much
@ -374,12 +383,13 @@ void bowser_act_default(void) // only lasts one frame
o->oAngleVelYaw = 0; o->oAngleVelYaw = 0;
o->oForwardVel = 0.0f; o->oForwardVel = 0.0f;
o->oVelY = 0.0f; o->oVelY = 0.0f;
if (BITDW) if (BITDW) {
bowser_bitdw_act_controller(); bowser_bitdw_act_controller();
else if (BITFS) } else if (BITFS) {
bowser_bitfs_act_controller(); bowser_bitfs_act_controller();
else } else {
bowser_bits_act_controller(); bowser_bits_act_controller();
}
// Action 14 commonly follows // Action 14 commonly follows
} }
@ -850,12 +860,14 @@ 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 && reward != NULL) { if (network_owns_object(o) && 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;
reward->oHomeZ = reward->oPosZ; reward->oHomeZ = reward->oPosZ;
network_set_sync_id(reward); network_set_sync_id(reward);
struct Object* spawn_objects[] = { reward }; struct Object* spawn_objects[] = { reward };
u32 models[] = { MODEL_STAR }; u32 models[] = { MODEL_STAR };
network_send_spawn_objects(spawn_objects, models, 1); network_send_spawn_objects(spawn_objects, models, 1);
@ -921,7 +933,6 @@ s32 bowser_dead_wait_for_mario(void) {
s32 bowser_dead_twirl_into_trophy(void) { s32 bowser_dead_twirl_into_trophy(void) {
bowserIsDying = TRUE; bowserIsDying = TRUE;
s32 ret = 0;
if (o->header.gfx.scale[0] < 0.8) if (o->header.gfx.scale[0] < 0.8)
o->oAngleVelYaw += 0x80; o->oAngleVelYaw += 0x80;
if (o->header.gfx.scale[0] > 0.2) { if (o->header.gfx.scale[0] > 0.2) {
@ -933,11 +944,11 @@ s32 bowser_dead_twirl_into_trophy(void) {
o->oGravity = 0.0f; o->oGravity = 0.0f;
} }
if (o->header.gfx.scale[1] < 0.5) if (o->header.gfx.scale[1] < 0.5)
ret = 1; return 1;
o->oMoveAngleYaw += o->oAngleVelYaw; o->oMoveAngleYaw += o->oAngleVelYaw;
if (o->oOpacity >= 3) if (o->oOpacity >= 3)
o->oOpacity -= 2; o->oOpacity -= 2;
return ret; return 0;
} }
void bowser_dead_hide(void) { void bowser_dead_hide(void) {
@ -1094,6 +1105,9 @@ void bowser_act_ride_tilting_platform(void) {
cur_obj_extend_animation_if_at_end(); cur_obj_extend_animation_if_at_end();
} }
void bowser_act_nothing(void) {
}
s32 bowser_check_fallen_off_stage(void) // bowser off stage? s32 bowser_check_fallen_off_stage(void) // bowser off stage?
{ {
@ -1114,7 +1128,8 @@ void (*sBowserActions[])(void) = { bowser_act_default, bowser_act_thrown_droppe
bowser_act_dead, bowser_act_text_wait, bowser_act_intro_walk, bowser_act_charge_mario, bowser_act_dead, bowser_act_text_wait, bowser_act_intro_walk, bowser_act_charge_mario,
bowser_act_spit_fire_into_sky, bowser_act_spit_fire_onto_floor, bowser_act_hit_edge, bowser_act_turn_from_edge, bowser_act_spit_fire_into_sky, bowser_act_spit_fire_onto_floor, bowser_act_hit_edge, bowser_act_turn_from_edge,
bowser_act_hit_mine, bowser_act_jump, bowser_act_walk_to_mario, bowser_act_breath_fire, bowser_act_hit_mine, bowser_act_jump, bowser_act_walk_to_mario, bowser_act_breath_fire,
bowser_act_teleport, bowser_act_jump_towards_mario, bowser_act_unused_slow_walk, bowser_act_ride_tilting_platform }; bowser_act_teleport, bowser_act_jump_towards_mario, bowser_act_unused_slow_walk, bowser_act_ride_tilting_platform,
bowser_act_nothing, };
struct SoundState D_8032F5B8[] = { { 0, 0, 0, NO_SOUND }, struct SoundState D_8032F5B8[] = { { 0, 0, 0, NO_SOUND },
{ 0, 0, 0, NO_SOUND }, { 0, 0, 0, NO_SOUND },
{ 0, 0, 0, NO_SOUND }, { 0, 0, 0, NO_SOUND },
@ -1257,8 +1272,13 @@ void bhv_bowser_loop(void) {
geo_obj_init_animation(&o->header.gfx, &anim); geo_obj_init_animation(&o->header.gfx, &anim);
} }
} }
// If Bowser isn't in a cutscene, It's been played already.
if (!bowserCutscenePlayed && (o->oAction != 5 && o->oAction != 6 && o->oAction != 20)) {
bowserCutscenePlayed = TRUE;
}
s16 angleToMario; // AngleToMario from Bowser's perspective s16 angleToMario; // AngleToMario from Bowser's perspective
s16 angleToCentre; // AngleToCentre from Bowser's perspective s16 angleToCentre; // AngleToCentre from Bowser's perspective
o->oBowserDistToCentre = sqrtf(o->oPosX * o->oPosX + o->oPosZ * o->oPosZ); o->oBowserDistToCentre = sqrtf(o->oPosX * o->oPosX + o->oPosZ * o->oPosZ);
@ -1314,6 +1334,13 @@ void bhv_bowser_loop(void) {
} }
void bhv_bowser_override_ownership(u8* shouldOverride, u8* shouldOwn) { void bhv_bowser_override_ownership(u8* shouldOverride, u8* shouldOwn) {
// Nothing state sanity check.
if (o->oAction == 20) {
*shouldOverride = TRUE;
*shouldOwn = FALSE;
return;
}
// tilting platform // tilting platform
static u8 tiltingTimer = 0; static u8 tiltingTimer = 0;
if (o->oAction == 19) { tiltingTimer = 5; } if (o->oAction == 19) { tiltingTimer = 5; }
@ -1327,6 +1354,7 @@ void bhv_bowser_override_ownership(u8* shouldOverride, u8* shouldOwn) {
static u8 bhv_bowser_ignore_if_true(void) { static u8 bhv_bowser_ignore_if_true(void) {
if (bowserIsDying) { return TRUE; } if (bowserIsDying) { return TRUE; }
if (o->oAction == 19) { return TRUE; } // let the platform get to a stable state if (o->oAction == 19) { return TRUE; } // let the platform get to a stable state
if (bowserIsCutscenePlayer && (o->oAction == 5 || o->oAction == 6)) { return TRUE; } // Ignore updates till our cutscene is done.
return FALSE; return FALSE;
} }
@ -1346,21 +1374,32 @@ void bhv_bowser_init(void) {
o->oBowserUnk1B2 = D_8032F690[level]; o->oBowserUnk1B2 = D_8032F690[level];
o->oHealth = D_8032F694[level]; o->oHealth = D_8032F694[level];
cur_obj_start_cam_event(o, CAM_EVENT_BOWSER_INIT); cur_obj_start_cam_event(o, CAM_EVENT_BOWSER_INIT);
o->oAction = 5;
o->oBowserUnk1AE = 0; o->oBowserUnk1AE = 0;
o->oBowserEyesShut = 0; o->oBowserEyesShut = 0;
bowserCutscenePlayed = FALSE;
struct SyncObject* so = network_init_object(o, 8000.0f);
if (so) { // Make sure we're the first to trigger Bowser.
so->override_ownership = bhv_bowser_override_ownership; if (!is_other_player_active()) {
so->ignore_if_true = bhv_bowser_ignore_if_true; bowserIsCutscenePlayer = TRUE;
so->fullObjectSync = TRUE; o->oAction = 5; // bowser_act_text_wait
network_init_object_field_with_size(o, &o->header.gfx.node.flags, 16); } else { // If we aren't do nothing till we get our sync.
network_init_object_field_with_size(o, &o->header.gfx.animInfo.animFrame, 16); bowserIsCutscenePlayer = FALSE;
network_init_object_field(o, &networkBowserAnimationIndex); o->oAction = 20; // bowser_act_nothing
network_init_object_field(o, &o->header.gfx.scale[0]); }
network_init_object_field(o, &o->header.gfx.scale[1]);
network_init_object_field(o, &o->header.gfx.scale[2]); if (!network_sync_object_initialized(o)) {
struct SyncObject* so = network_init_object(o, 8000.0f);
if (so) {
so->override_ownership = bhv_bowser_override_ownership;
so->ignore_if_true = bhv_bowser_ignore_if_true;
so->fullObjectSync = TRUE;
network_init_object_field_with_size(o, &o->header.gfx.node.flags, 16);
network_init_object_field_with_size(o, &o->header.gfx.animInfo.animFrame, 16);
network_init_object_field(o, &networkBowserAnimationIndex);
network_init_object_field(o, &o->header.gfx.scale[0]);
network_init_object_field(o, &o->header.gfx.scale[1]);
network_init_object_field(o, &o->header.gfx.scale[2]);
}
} }
} }

View file

@ -1,8 +1,8 @@
// grand_star.c.inc // grand_star.c.inc
s32 arc_to_goal_pos(Vec3f a0, Vec3f a1, f32 yVel, f32 gravity) { s32 arc_to_goal_pos(Vec3f empty, Vec3f pos, f32 yVel, f32 gravity) {
f32 dx = a0[0] - a1[0]; f32 dx = empty[0] - pos[0];
f32 dz = a0[2] - a1[2]; f32 dz = empty[2] - pos[2];
f32 planarDist = sqrtf(dx * dx + dz * dz); f32 planarDist = sqrtf(dx * dx + dz * dz);
o->oMoveAngleYaw = atan2s(dz, dx); o->oMoveAngleYaw = atan2s(dz, dx);
o->oVelY = yVel; o->oVelY = yVel;
@ -22,12 +22,15 @@ void bhv_grand_star_init(void) {
struct Object *other = cur_obj_nearest_object_with_behavior(bhvGrandStar); struct Object *other = cur_obj_nearest_object_with_behavior(bhvGrandStar);
if (other == NULL) { if (other == NULL) {
if (!network_sync_object_initialized(o)) { if (!network_sync_object_initialized(o)) {
struct SyncObject *so = network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS); struct SyncObject *so = network_init_object(o, 4000.0f);
if (so) { if (so) {
network_init_object_field_with_size(o, &o->activeFlags, 16); network_init_object_field(o, &o->header.gfx.scale[0]);
network_init_object_field(o, &o->header.gfx.scale[1]);
network_init_object_field(o, &o->header.gfx.scale[2]);
network_init_object_field(o, &o->oPrevAction); network_init_object_field(o, &o->oPrevAction);
network_init_object_field(o, &o->oAction); network_init_object_field(o, &o->oAction);
network_init_object_field(o, &o->oSubAction); network_init_object_field(o, &o->oSubAction);
network_init_object_field(o, &o->oInteractStatus);
network_init_object_field(o, &o->oTimer); network_init_object_field(o, &o->oTimer);
network_init_object_field(o, &o->oHomeX); network_init_object_field(o, &o->oHomeX);
network_init_object_field(o, &o->oHomeY); network_init_object_field(o, &o->oHomeY);
@ -41,7 +44,7 @@ void bhv_grand_star_init(void) {
network_init_object_field(o, &o->oAngleVelYaw); network_init_object_field(o, &o->oAngleVelYaw);
network_init_object_field(o, &o->oMoveAngleYaw); network_init_object_field(o, &o->oMoveAngleYaw);
network_init_object_field(o, &o->oFaceAngleYaw); network_init_object_field(o, &o->oFaceAngleYaw);
network_init_object_field(o, &o->oGrandStarUnk108); network_init_object_field(o, &o->oGraphYOffset);
} }
} }
return; return;
@ -66,12 +69,12 @@ void bhv_grand_star_loop(void) {
spawn_sparkle_particles(3, 200, 80, -60); spawn_sparkle_particles(3, 200, 80, -60);
} else if (o->oAction == 1) { } else if (o->oAction == 1) {
if (o->oTimer == 0) { if (o->oTimer == 0) {
Vec3f sp28; Vec3f empty;
sp28[0] = sp28[1] = sp28[2] = 0.0f; empty[0] = empty[1] = empty[2] = 0.0f;
cur_obj_play_sound_2(SOUND_GENERAL_GRAND_STAR); cur_obj_play_sound_2(SOUND_GENERAL_GRAND_STAR);
cutscene_object(CUTSCENE_STAR_SPAWN, o); cutscene_object(CUTSCENE_STAR_SPAWN, o);
o->oGrandStarUnk108 = arc_to_goal_pos(sp28, &o->oPosX, 80.0f, -2.0f); o->oGrandStarUnk108 = arc_to_goal_pos(empty, &o->oPosX, 80.0f, -2.0f);
} }
cur_obj_move_using_fvel_and_gravity(); cur_obj_move_using_fvel_and_gravity();
if (o->oSubAction == 0) { if (o->oSubAction == 0) {
@ -92,13 +95,25 @@ void bhv_grand_star_loop(void) {
cur_obj_play_sound_2(SOUND_GENERAL_GRAND_STAR_JUMP); cur_obj_play_sound_2(SOUND_GENERAL_GRAND_STAR_JUMP);
} }
spawn_sparkle_particles(3, 200, 80, -60); spawn_sparkle_particles(3, 200, 80, -60);
} else { } else if (o->oAction == 2) {
// Make our object tangible.
cur_obj_become_tangible(); cur_obj_become_tangible();
// Check for if the jumbo star has been collected.
if (o->oInteractStatus & INT_STATUS_INTERACTED) { if (o->oInteractStatus & INT_STATUS_INTERACTED) {
// Make sure we're in the jumbo star cutscene.
if (gMarioStates[0].action != ACT_JUMBO_STAR_CUTSCENE) { if (gMarioStates[0].action != ACT_JUMBO_STAR_CUTSCENE) {
set_mario_action(&gMarioStates[0], ACT_JUMBO_STAR_CUTSCENE, 0); set_mario_action(&gMarioStates[0], ACT_JUMBO_STAR_CUTSCENE, 0);
} }
// Increment our action, The star despawns next action.
o->oAction++;
}
} else {
// The star cutscene has started, Make sure the star is deleted
// if it isn't already deactivated.
if (o->activeFlags != ACTIVE_FLAG_DEACTIVATED) {
// Mark our object for deletion.
obj_mark_for_deletion(o); obj_mark_for_deletion(o);
// Reset our interactive status.
o->oInteractStatus = 0; o->oInteractStatus = 0;
} }
} }
@ -108,4 +123,4 @@ void bhv_grand_star_loop(void) {
o->oFaceAngleYaw += o->oAngleVelYaw; o->oFaceAngleYaw += o->oAngleVelYaw;
cur_obj_scale(2.0f); cur_obj_scale(2.0f);
o->oGraphYOffset = 110.0f; o->oGraphYOffset = 110.0f;
} }

View file

@ -327,4 +327,4 @@ void bhv_treasure_chest_loop(void) {
case 2: case 2:
break; break;
} }
} }

View file

@ -3336,7 +3336,8 @@ void reset_camera(struct Camera *c) {
} }
void init_camera(struct Camera *c) { void init_camera(struct Camera *c) {
struct Surface *floor = 0; struct Surface *floor = NULL;
struct Object *obj = NULL;
Vec3f marioOffset; Vec3f marioOffset;
s32 i; s32 i;
@ -3391,18 +3392,34 @@ void init_camera(struct Camera *c) {
case LEVEL_BOWSER_1: case LEVEL_BOWSER_1:
#ifndef VERSION_JP #ifndef VERSION_JP
if (gCurrDemoInput == NULL) { if (gCurrDemoInput == NULL) {
// Make sure Bowser is in a state that we'd start speaking to him in.
obj = find_object_with_behavior(bhvBowser);
if (obj != NULL && obj->oAction != 5) { break; }
start_cutscene(c, CUTSCENE_ENTER_BOWSER_ARENA); start_cutscene(c, CUTSCENE_ENTER_BOWSER_ARENA);
} else if (gSecondCameraFocus != NULL) { } else if (gSecondCameraFocus != NULL) {
gSecondCameraFocus->oBowserUnk88 = 2; gSecondCameraFocus->oBowserUnk88 = 2;
} }
#else #else
// Make sure Bowser is in a state that we'd start speaking to him in.
obj = find_object_with_behavior(bhvBowser);
if (obj != NULL && obj->oAction != 5) { break; }
start_cutscene(c, CUTSCENE_ENTER_BOWSER_ARENA); start_cutscene(c, CUTSCENE_ENTER_BOWSER_ARENA);
#endif #endif
break; break;
case LEVEL_BOWSER_2: case LEVEL_BOWSER_2:
// Make sure Bowser is in a state that we'd start speaking to him in.
obj = find_object_with_behavior(bhvBowser);
if (obj != NULL && obj->oAction != 5) { break; }
start_cutscene(c, CUTSCENE_ENTER_BOWSER_ARENA); start_cutscene(c, CUTSCENE_ENTER_BOWSER_ARENA);
break; break;
case LEVEL_BOWSER_3: case LEVEL_BOWSER_3:
// Make sure Bowser is in a state that we'd start speaking to him in.
obj = find_object_with_behavior(bhvBowser);
if (obj != NULL && obj->oAction != 5) { break; }
start_cutscene(c, CUTSCENE_ENTER_BOWSER_ARENA); start_cutscene(c, CUTSCENE_ENTER_BOWSER_ARENA);
break; break;

View file

@ -536,6 +536,14 @@ u8 is_player_active(struct MarioState* m) {
return TRUE; return TRUE;
} }
u8 is_other_player_active(void) {
for (s32 i = 1; i < MAX_PLAYERS; i++) {
struct MarioState *m = &gMarioStates[i];
if (is_player_active(m)) { return TRUE; }
}
return FALSE;
}
u8 is_player_in_local_area(struct MarioState* m) { u8 is_player_in_local_area(struct MarioState* m) {
if (gNetworkType == NT_NONE && m == &gMarioStates[0]) { return TRUE; } if (gNetworkType == NT_NONE && m == &gMarioStates[0]) { return TRUE; }
struct NetworkPlayer* np = &gNetworkPlayers[m->playerIndex]; struct NetworkPlayer* np = &gNetworkPlayers[m->playerIndex];
@ -589,6 +597,43 @@ struct Object* nearest_player_to_object(struct Object *obj) {
return nearest->marioObj; return nearest->marioObj;
} }
/**
* Returns closest MarioState that's interacting with the object.
*/
struct MarioState *nearest_interacting_mario_state_to_object(struct Object *obj) {
struct MarioState *nearest = NULL;
f32 nearestDist = 0;
u8 checkActive = TRUE;
do {
for (s32 i = 0; i < MAX_PLAYERS; i++) {
if (gMarioStates[i].marioObj == obj) { continue; }
if (gMarioStates[i].interactObj != obj) { continue; }
if (checkActive && !is_player_active(&gMarioStates[i])) { continue; }
float dist = dist_between_objects(obj, gMarioStates[i].marioObj);
if (nearest == NULL || dist < nearestDist) {
nearest = &gMarioStates[i];
nearestDist = dist;
}
}
if (!checkActive) { break; }
checkActive = FALSE;
} while (nearest == NULL);
if (nearest == NULL) {
nearest = &gMarioStates[0];
}
return nearest;
}
/**
* Returns closest marioObj that's interacting with the object.
*/
struct Object *nearest_interacting_player_to_object(struct Object *obj) {
struct MarioState *nearest = nearest_interacting_mario_state_to_object(obj);
return nearest->marioObj;
}
/** /**
* Returns whether or not the MarioState is the closet MarioState * Returns whether or not the MarioState is the closet MarioState
* to the object. * to the object.

View file

@ -163,9 +163,12 @@ void bhv_rr_cruiser_wing_init(void);
void bhv_rr_cruiser_wing_loop(void); void bhv_rr_cruiser_wing_loop(void);
struct Object* spawn_default_star(f32 sp20, f32 sp24, f32 sp28); struct Object* spawn_default_star(f32 sp20, f32 sp24, f32 sp28);
u8 is_player_active(struct MarioState* m); u8 is_player_active(struct MarioState* m);
u8 is_other_player_active(void);
u8 is_player_in_local_area(struct MarioState* m); u8 is_player_in_local_area(struct MarioState* m);
struct MarioState* nearest_mario_state_to_object(struct Object* obj); struct MarioState* nearest_mario_state_to_object(struct Object* obj);
struct Object* nearest_player_to_object(struct Object* obj); struct Object* nearest_player_to_object(struct Object* obj);
struct MarioState *nearest_interacting_mario_state_to_object(struct Object *obj);
struct Object *nearest_interacting_player_to_object(struct Object *obj);
u8 is_nearest_mario_state_to_object(struct MarioState* m, struct Object* obj); u8 is_nearest_mario_state_to_object(struct MarioState* m, struct Object* obj);
u8 is_nearest_player_to_object(struct Object* m, struct Object* obj); u8 is_nearest_player_to_object(struct Object* m, struct Object* obj);
#endif // OBJ_BEHAVIORS_H #endif // OBJ_BEHAVIORS_H

View file

@ -1036,6 +1036,22 @@ s32 count_objects_with_behavior(const BehaviorScript *behavior) {
return count; return count;
} }
struct Object *find_object_with_behavior(const BehaviorScript *behavior) {
uintptr_t *behaviorAddr = segmented_to_virtual(behavior);
struct ObjectNode *listHead = &gObjectLists[get_object_list_from_behavior(behaviorAddr)];
struct ObjectNode *obj = listHead->next;
while (listHead != obj) {
if (((struct Object *) obj)->behavior == behaviorAddr) {
return (struct Object *)obj;
}
obj = obj->next;
}
return NULL;
}
struct Object *cur_obj_find_nearby_held_actor(const BehaviorScript *behavior, f32 maxDist) { struct Object *cur_obj_find_nearby_held_actor(const BehaviorScript *behavior, f32 maxDist) {
const BehaviorScript *behaviorAddr = segmented_to_virtual(behavior); const BehaviorScript *behaviorAddr = segmented_to_virtual(behavior);
struct ObjectNode *listHead; struct ObjectNode *listHead;

View file

@ -146,6 +146,7 @@ f32 cur_obj_dist_to_nearest_object_with_behavior(const BehaviorScript* behavior)
struct Object* cur_obj_find_nearest_pole(void); struct Object* cur_obj_find_nearest_pole(void);
struct Object *cur_obj_find_nearest_object_with_behavior(const BehaviorScript * behavior, f32 *dist); struct Object *cur_obj_find_nearest_object_with_behavior(const BehaviorScript * behavior, f32 *dist);
u16 cur_obj_count_objects_with_behavior(const BehaviorScript* behavior, f32 dist); u16 cur_obj_count_objects_with_behavior(const BehaviorScript* behavior, f32 dist);
struct Object *find_object_with_behavior(const BehaviorScript *behavior);
struct Object *find_unimportant_object(void); struct Object *find_unimportant_object(void);
s32 count_unimportant_objects(void); s32 count_unimportant_objects(void);
s32 count_objects_with_behavior(const BehaviorScript *behavior); s32 count_objects_with_behavior(const BehaviorScript *behavior);