mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-11-22 12:05:11 +00:00
Merge branch 'unstable' of github.com:sm64ex-coop-dev/sm64ex-coop into unstable
This commit is contained in:
commit
0e50998a39
10 changed files with 210 additions and 67 deletions
2
Makefile
2
Makefile
|
@ -1469,4 +1469,4 @@ MAKEFLAGS += --no-builtin-rules
|
|||
|
||||
-include $(DEP_FILES)
|
||||
|
||||
print-% : ; $(info $* is a $(flavor $*) variable set to [$($*)]) @true
|
||||
print-% : ; $(info $* is a $(flavor $*) variable set to [$($*)]) @true
|
|
@ -301,25 +301,26 @@ void bhv_bobomb_buddy_init(void) {
|
|||
}
|
||||
|
||||
void bobomb_buddy_act_idle(void) {
|
||||
UNUSED u8 filler[4];
|
||||
s16 sp1a = o->header.gfx.animInfo.animFrame;
|
||||
UNUSED s16 collisionFlags = 0;
|
||||
s16 animFrame = o->header.gfx.animInfo.animFrame;
|
||||
|
||||
o->oBobombBuddyPosXCopy = o->oPosX;
|
||||
o->oBobombBuddyPosYCopy = o->oPosY;
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (o->oInteractStatus == INT_STATUS_INTERACTED)
|
||||
if (o->oInteractStatus == INT_STATUS_INTERACTED) {
|
||||
o->oAction = BOBOMB_BUDDY_ACT_TURN_TO_TALK;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -345,24 +346,27 @@ void bobomb_buddy_cannon_dialog(s16 dialogFirstText, s16 dialogSecondText) {
|
|||
forceCannonOpen = FALSE;
|
||||
|
||||
cannonClosed = cur_obj_nearest_object_with_behavior(bhvCannonClosed);
|
||||
if (cannonClosed != 0)
|
||||
if (cannonClosed != 0) {
|
||||
o->oBobombBuddyCannonStatus = BOBOMB_BUDDY_CANNON_OPENING;
|
||||
else
|
||||
} else {
|
||||
o->oBobombBuddyCannonStatus = BOBOMB_BUDDY_CANNON_STOP_TALKING;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case BOBOMB_BUDDY_CANNON_OPENING:
|
||||
cannonClosed = cur_obj_nearest_object_with_behavior(bhvCannonClosed);
|
||||
cutscene = cutscene_object(CUTSCENE_PREPARE_CANNON, cannonClosed);
|
||||
if (cutscene == -1)
|
||||
if (cutscene == -1) {
|
||||
o->oBobombBuddyCannonStatus = BOBOMB_BUDDY_CANNON_OPENED;
|
||||
}
|
||||
break;
|
||||
|
||||
case BOBOMB_BUDDY_CANNON_OPENED:
|
||||
buddyText = cutscene_object_with_dialog(CUTSCENE_DIALOG, o, dialogSecondText);
|
||||
if (buddyText != 0)
|
||||
if (buddyText != 0) {
|
||||
o->oBobombBuddyCannonStatus = BOBOMB_BUDDY_CANNON_STOP_TALKING;
|
||||
}
|
||||
break;
|
||||
|
||||
case BOBOMB_BUDDY_CANNON_STOP_TALKING:
|
||||
|
@ -400,25 +404,28 @@ void bobomb_buddy_act_talk(void) {
|
|||
break;
|
||||
|
||||
case BOBOMB_BUDDY_ROLE_CANNON:
|
||||
if (gCurrCourseNum == COURSE_BOB)
|
||||
if (gCurrCourseNum == COURSE_BOB) {
|
||||
bobomb_buddy_cannon_dialog(DIALOG_004, DIALOG_105);
|
||||
else
|
||||
} else {
|
||||
bobomb_buddy_cannon_dialog(DIALOG_047, DIALOG_106);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bobomb_buddy_act_turn_to_talk(void) {
|
||||
s16 sp1e = o->header.gfx.animInfo.animFrame;
|
||||
if ((sp1e == 5) || (sp1e == 16))
|
||||
s16 animFrame = o->header.gfx.animInfo.animFrame;
|
||||
if ((animFrame == 5) || (animFrame == 16)) {
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
cur_obj_play_sound_2(SOUND_ACTION_READ_SIGN);
|
||||
}
|
||||
|
|
|
@ -1,19 +1,22 @@
|
|||
// bowser.c.inc
|
||||
static u32 networkBowserAnimationIndex = 0;
|
||||
static u8 bowserIsDying = FALSE;
|
||||
static u8 bowserCutscenePlayed = FALSE;
|
||||
static u8 bowserIsCutscenePlayer = FALSE;
|
||||
|
||||
void bowser_tail_anchor_act_0(void) {
|
||||
struct Object* bowser = o->parentObj;
|
||||
struct Object* player = nearest_player_to_object(o);
|
||||
cur_obj_become_tangible();
|
||||
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;
|
||||
else if (obj_check_if_collided_with_object(o, player)) {
|
||||
} else if (obj_check_if_collided_with_object(o, player)) {
|
||||
bowser->oIntangibleTimer = 0;
|
||||
o->oAction = 2;
|
||||
} else
|
||||
} else {
|
||||
bowser->oIntangibleTimer = -1;
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
o->oForwardVel = 3.0f;
|
||||
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;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 bowser_set_anim_look_down(void) {
|
||||
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;
|
||||
if (cur_obj_check_if_near_animation_end())
|
||||
}
|
||||
if (cur_obj_check_if_near_animation_end()) {
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void bowser_initialize_action(void) {
|
||||
if (o->oBowserUnk88 == 0)
|
||||
if (o->oBowserUnk88 == 0 && !bowserCutscenePlayed) {
|
||||
o->oAction = 5;
|
||||
else if (o->oBowserUnk88 == 1)
|
||||
} else if (o->oBowserUnk88 == 1 && !bowserCutscenePlayed) {
|
||||
o->oAction = 6;
|
||||
else if (o->oBehParams2ndByte == 1)
|
||||
} else if (o->oBehParams2ndByte == 1) {
|
||||
bowserCutscenePlayed = TRUE;
|
||||
o->oAction = 13;
|
||||
else
|
||||
if (bowserIsCutscenePlayer) { network_send_object_reliability(o, TRUE); }
|
||||
} else {
|
||||
bowserCutscenePlayed = TRUE;
|
||||
o->oAction = 0;
|
||||
if (bowserIsCutscenePlayer) { network_send_object_reliability(o, TRUE); }
|
||||
}
|
||||
}
|
||||
|
||||
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->oForwardVel = 0.0f;
|
||||
o->oVelY = 0.0f;
|
||||
if (BITDW)
|
||||
if (BITDW) {
|
||||
bowser_bitdw_act_controller();
|
||||
else if (BITFS)
|
||||
} else if (BITFS) {
|
||||
bowser_bitfs_act_controller();
|
||||
else
|
||||
} else {
|
||||
bowser_bits_act_controller();
|
||||
}
|
||||
// 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);
|
||||
gSecondCameraFocus = reward;
|
||||
|
||||
if (prevReward == NULL && reward != NULL) {
|
||||
if (network_owns_object(o) && prevReward == NULL && reward != NULL) {
|
||||
// set the home position
|
||||
reward->oHomeX = reward->oPosX;
|
||||
reward->oHomeY = reward->oPosY;
|
||||
reward->oHomeZ = reward->oPosZ;
|
||||
|
||||
network_set_sync_id(reward);
|
||||
|
||||
struct Object* spawn_objects[] = { reward };
|
||||
u32 models[] = { MODEL_STAR };
|
||||
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) {
|
||||
bowserIsDying = TRUE;
|
||||
s32 ret = 0;
|
||||
if (o->header.gfx.scale[0] < 0.8)
|
||||
o->oAngleVelYaw += 0x80;
|
||||
if (o->header.gfx.scale[0] > 0.2) {
|
||||
|
@ -933,11 +944,11 @@ s32 bowser_dead_twirl_into_trophy(void) {
|
|||
o->oGravity = 0.0f;
|
||||
}
|
||||
if (o->header.gfx.scale[1] < 0.5)
|
||||
ret = 1;
|
||||
return 1;
|
||||
o->oMoveAngleYaw += o->oAngleVelYaw;
|
||||
if (o->oOpacity >= 3)
|
||||
o->oOpacity -= 2;
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void bowser_dead_hide(void) {
|
||||
|
@ -1094,6 +1105,9 @@ void bowser_act_ride_tilting_platform(void) {
|
|||
cur_obj_extend_animation_if_at_end();
|
||||
}
|
||||
|
||||
void bowser_act_nothing(void) {
|
||||
|
||||
}
|
||||
|
||||
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_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_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 },
|
||||
{ 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);
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
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) {
|
||||
// Nothing state sanity check.
|
||||
if (o->oAction == 20) {
|
||||
*shouldOverride = TRUE;
|
||||
*shouldOwn = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
// tilting platform
|
||||
static u8 tiltingTimer = 0;
|
||||
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) {
|
||||
if (bowserIsDying) { return TRUE; }
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -1346,21 +1374,32 @@ void bhv_bowser_init(void) {
|
|||
o->oBowserUnk1B2 = D_8032F690[level];
|
||||
o->oHealth = D_8032F694[level];
|
||||
cur_obj_start_cam_event(o, CAM_EVENT_BOWSER_INIT);
|
||||
o->oAction = 5;
|
||||
o->oBowserUnk1AE = 0;
|
||||
o->oBowserEyesShut = 0;
|
||||
|
||||
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]);
|
||||
bowserCutscenePlayed = FALSE;
|
||||
|
||||
// Make sure we're the first to trigger Bowser.
|
||||
if (!is_other_player_active()) {
|
||||
bowserIsCutscenePlayer = TRUE;
|
||||
o->oAction = 5; // bowser_act_text_wait
|
||||
} else { // If we aren't do nothing till we get our sync.
|
||||
bowserIsCutscenePlayer = FALSE;
|
||||
o->oAction = 20; // bowser_act_nothing
|
||||
}
|
||||
|
||||
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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// grand_star.c.inc
|
||||
|
||||
s32 arc_to_goal_pos(Vec3f a0, Vec3f a1, f32 yVel, f32 gravity) {
|
||||
f32 dx = a0[0] - a1[0];
|
||||
f32 dz = a0[2] - a1[2];
|
||||
s32 arc_to_goal_pos(Vec3f empty, Vec3f pos, f32 yVel, f32 gravity) {
|
||||
f32 dx = empty[0] - pos[0];
|
||||
f32 dz = empty[2] - pos[2];
|
||||
f32 planarDist = sqrtf(dx * dx + dz * dz);
|
||||
o->oMoveAngleYaw = atan2s(dz, dx);
|
||||
o->oVelY = yVel;
|
||||
|
@ -22,12 +22,15 @@ void bhv_grand_star_init(void) {
|
|||
struct Object *other = cur_obj_nearest_object_with_behavior(bhvGrandStar);
|
||||
if (other == NULL) {
|
||||
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) {
|
||||
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->oAction);
|
||||
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->oHomeX);
|
||||
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->oMoveAngleYaw);
|
||||
network_init_object_field(o, &o->oFaceAngleYaw);
|
||||
network_init_object_field(o, &o->oGrandStarUnk108);
|
||||
network_init_object_field(o, &o->oGraphYOffset);
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
@ -66,12 +69,12 @@ void bhv_grand_star_loop(void) {
|
|||
spawn_sparkle_particles(3, 200, 80, -60);
|
||||
} else if (o->oAction == 1) {
|
||||
if (o->oTimer == 0) {
|
||||
Vec3f sp28;
|
||||
sp28[0] = sp28[1] = sp28[2] = 0.0f;
|
||||
Vec3f empty;
|
||||
empty[0] = empty[1] = empty[2] = 0.0f;
|
||||
|
||||
cur_obj_play_sound_2(SOUND_GENERAL_GRAND_STAR);
|
||||
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();
|
||||
if (o->oSubAction == 0) {
|
||||
|
@ -92,13 +95,25 @@ void bhv_grand_star_loop(void) {
|
|||
cur_obj_play_sound_2(SOUND_GENERAL_GRAND_STAR_JUMP);
|
||||
}
|
||||
spawn_sparkle_particles(3, 200, 80, -60);
|
||||
} else {
|
||||
} else if (o->oAction == 2) {
|
||||
// Make our object tangible.
|
||||
cur_obj_become_tangible();
|
||||
// Check for if the jumbo star has been collected.
|
||||
if (o->oInteractStatus & INT_STATUS_INTERACTED) {
|
||||
// Make sure we're in the jumbo star cutscene.
|
||||
if (gMarioStates[0].action != ACT_JUMBO_STAR_CUTSCENE) {
|
||||
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);
|
||||
// Reset our interactive status.
|
||||
o->oInteractStatus = 0;
|
||||
}
|
||||
}
|
||||
|
@ -108,4 +123,4 @@ void bhv_grand_star_loop(void) {
|
|||
o->oFaceAngleYaw += o->oAngleVelYaw;
|
||||
cur_obj_scale(2.0f);
|
||||
o->oGraphYOffset = 110.0f;
|
||||
}
|
||||
}
|
|
@ -327,4 +327,4 @@ void bhv_treasure_chest_loop(void) {
|
|||
case 2:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3336,7 +3336,8 @@ void reset_camera(struct Camera *c) {
|
|||
}
|
||||
|
||||
void init_camera(struct Camera *c) {
|
||||
struct Surface *floor = 0;
|
||||
struct Surface *floor = NULL;
|
||||
struct Object *obj = NULL;
|
||||
Vec3f marioOffset;
|
||||
s32 i;
|
||||
|
||||
|
@ -3391,18 +3392,34 @@ void init_camera(struct Camera *c) {
|
|||
case LEVEL_BOWSER_1:
|
||||
#ifndef VERSION_JP
|
||||
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);
|
||||
} else if (gSecondCameraFocus != NULL) {
|
||||
gSecondCameraFocus->oBowserUnk88 = 2;
|
||||
}
|
||||
#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);
|
||||
#endif
|
||||
break;
|
||||
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);
|
||||
break;
|
||||
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);
|
||||
break;
|
||||
|
||||
|
|
|
@ -536,6 +536,14 @@ u8 is_player_active(struct MarioState* m) {
|
|||
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) {
|
||||
if (gNetworkType == NT_NONE && m == &gMarioStates[0]) { return TRUE; }
|
||||
struct NetworkPlayer* np = &gNetworkPlayers[m->playerIndex];
|
||||
|
@ -589,6 +597,43 @@ struct Object* nearest_player_to_object(struct Object *obj) {
|
|||
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
|
||||
* to the object.
|
||||
|
|
|
@ -163,9 +163,12 @@ void bhv_rr_cruiser_wing_init(void);
|
|||
void bhv_rr_cruiser_wing_loop(void);
|
||||
struct Object* spawn_default_star(f32 sp20, f32 sp24, f32 sp28);
|
||||
u8 is_player_active(struct MarioState* m);
|
||||
u8 is_other_player_active(void);
|
||||
u8 is_player_in_local_area(struct MarioState* m);
|
||||
struct MarioState* nearest_mario_state_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_player_to_object(struct Object* m, struct Object* obj);
|
||||
#endif // OBJ_BEHAVIORS_H
|
||||
|
|
|
@ -1036,6 +1036,22 @@ s32 count_objects_with_behavior(const BehaviorScript *behavior) {
|
|||
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) {
|
||||
const BehaviorScript *behaviorAddr = segmented_to_virtual(behavior);
|
||||
struct ObjectNode *listHead;
|
||||
|
|
|
@ -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_object_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);
|
||||
s32 count_unimportant_objects(void);
|
||||
s32 count_objects_with_behavior(const BehaviorScript *behavior);
|
||||
|
|
Loading…
Reference in a new issue