2020-03-01 22:42:52 -05:00
|
|
|
// spawn_default_star.c.inc
|
2019-08-25 00:46:40 -04:00
|
|
|
|
|
|
|
static struct ObjectHitbox sCollectStarHitbox = {
|
|
|
|
/* interactType: */ INTERACT_STAR_OR_KEY,
|
|
|
|
/* downOffset: */ 0,
|
|
|
|
/* damageOrCoinValue: */ 0,
|
|
|
|
/* health: */ 0,
|
|
|
|
/* numLootCoins: */ 0,
|
|
|
|
/* radius: */ 80,
|
|
|
|
/* height: */ 50,
|
|
|
|
/* hurtboxRadius: */ 0,
|
|
|
|
/* hurtboxHeight: */ 0,
|
|
|
|
};
|
|
|
|
|
|
|
|
void bhv_collect_star_init(void) {
|
|
|
|
s8 sp1F;
|
|
|
|
u8 sp1E;
|
|
|
|
|
|
|
|
sp1F = (o->oBehParams >> 24) & 0xFF;
|
|
|
|
sp1E = save_file_get_star_flags(gCurrSaveFileNum - 1, gCurrCourseNum - 1);
|
|
|
|
if (sp1E & (1 << sp1F)) {
|
|
|
|
o->header.gfx.sharedChild = gLoadedGraphNodes[MODEL_TRANSPARENT_STAR];
|
|
|
|
} else {
|
|
|
|
o->header.gfx.sharedChild = gLoadedGraphNodes[MODEL_STAR];
|
|
|
|
}
|
|
|
|
|
2020-03-01 22:42:52 -05:00
|
|
|
obj_set_hitbox(o, &sCollectStarHitbox);
|
2019-08-25 00:46:40 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void bhv_collect_star_loop(void) {
|
|
|
|
o->oFaceAngleYaw += 0x800;
|
|
|
|
|
|
|
|
if (o->oInteractStatus & INT_STATUS_INTERACTED) {
|
|
|
|
mark_obj_for_deletion(o);
|
|
|
|
o->oInteractStatus = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void bhv_star_spawn_init(void) {
|
|
|
|
o->oMoveAngleYaw = atan2s(o->oHomeZ - o->oPosZ, o->oHomeX - o->oPosX);
|
|
|
|
o->oStarSpawnDisFromHome = sqrtf(sqr(o->oHomeX - o->oPosX) + sqr(o->oHomeZ - o->oPosZ));
|
|
|
|
o->oVelY = (o->oHomeY - o->oPosY) / 30.0f;
|
|
|
|
o->oForwardVel = o->oStarSpawnDisFromHome / 30.0f;
|
|
|
|
o->oStarSpawnUnkFC = o->oPosY;
|
2020-01-03 10:38:57 -05:00
|
|
|
if (o->oBehParams2ndByte == 0 || gCurrCourseNum == COURSE_BBH)
|
2019-10-05 15:08:05 -04:00
|
|
|
cutscene_object(CUTSCENE_STAR_SPAWN, o);
|
2019-08-25 00:46:40 -04:00
|
|
|
else
|
2020-01-03 10:38:57 -05:00
|
|
|
cutscene_object(CUTSCENE_RED_COIN_STAR_SPAWN, o);
|
2019-08-25 00:46:40 -04:00
|
|
|
|
|
|
|
set_time_stop_flags(TIME_STOP_ENABLED | TIME_STOP_MARIO_AND_DOORS);
|
|
|
|
o->activeFlags |= 0x20;
|
2020-03-01 22:42:52 -05:00
|
|
|
cur_obj_become_intangible();
|
2019-08-25 00:46:40 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void bhv_star_spawn_loop(void) {
|
|
|
|
switch (o->oAction) {
|
|
|
|
case 0:
|
|
|
|
o->oFaceAngleYaw += 0x1000;
|
|
|
|
if (o->oTimer > 20)
|
|
|
|
o->oAction = 1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
obj_move_xyz_using_fvel_and_yaw(o);
|
|
|
|
o->oStarSpawnUnkFC += o->oVelY;
|
|
|
|
o->oPosY = o->oStarSpawnUnkFC + sins((o->oTimer * 0x8000) / 30) * 400.0f;
|
|
|
|
o->oFaceAngleYaw += 0x1000;
|
|
|
|
spawn_object(o, MODEL_NONE, bhvSparkleSpawn);
|
2020-03-01 22:42:52 -05:00
|
|
|
cur_obj_play_sound_1(SOUND_ENV_STAR);
|
2019-08-25 00:46:40 -04:00
|
|
|
if (o->oTimer == 30) {
|
|
|
|
o->oAction = 2;
|
|
|
|
o->oForwardVel = 0;
|
|
|
|
play_power_star_jingle(TRUE);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
if (o->oTimer < 20)
|
|
|
|
o->oVelY = 20 - o->oTimer;
|
|
|
|
else
|
|
|
|
o->oVelY = -10.0f;
|
|
|
|
|
|
|
|
spawn_object(o, MODEL_NONE, bhvSparkleSpawn);
|
|
|
|
obj_move_xyz_using_fvel_and_yaw(o);
|
|
|
|
o->oFaceAngleYaw = o->oFaceAngleYaw - o->oTimer * 0x10 + 0x1000;
|
2020-03-01 22:42:52 -05:00
|
|
|
cur_obj_play_sound_1(SOUND_ENV_STAR);
|
2019-08-25 00:46:40 -04:00
|
|
|
|
|
|
|
if (o->oPosY < o->oHomeY) {
|
2020-03-01 22:42:52 -05:00
|
|
|
cur_obj_play_sound_2(SOUND_GENERAL_STAR_APPEARS);
|
|
|
|
cur_obj_become_tangible();
|
2019-08-25 00:46:40 -04:00
|
|
|
o->oPosY = o->oHomeY;
|
|
|
|
o->oAction = 3;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 3:
|
|
|
|
o->oFaceAngleYaw += 0x800;
|
|
|
|
if (o->oTimer == 20) {
|
2020-01-03 10:38:57 -05:00
|
|
|
gObjCutsceneDone = TRUE;
|
2019-08-25 00:46:40 -04:00
|
|
|
clear_time_stop_flags(TIME_STOP_ENABLED | TIME_STOP_MARIO_AND_DOORS);
|
|
|
|
o->activeFlags &= ~0x20;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (o->oInteractStatus & INT_STATUS_INTERACTED) {
|
|
|
|
mark_obj_for_deletion(o);
|
|
|
|
o->oInteractStatus = 0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-01 22:42:52 -05:00
|
|
|
struct Object *spawn_star(struct Object *sp30, f32 sp34, f32 sp38, f32 sp3C) {
|
2019-08-25 00:46:40 -04:00
|
|
|
sp30 = spawn_object_abs_with_rot(o, 0, MODEL_STAR, bhvStarSpawnCoordinates, o->oPosX, o->oPosY,
|
|
|
|
o->oPosZ, 0, 0, 0);
|
|
|
|
sp30->oBehParams = o->oBehParams;
|
|
|
|
sp30->oHomeX = sp34;
|
|
|
|
sp30->oHomeY = sp38;
|
|
|
|
sp30->oHomeZ = sp3C;
|
|
|
|
sp30->oFaceAnglePitch = 0;
|
|
|
|
sp30->oFaceAngleRoll = 0;
|
|
|
|
return sp30;
|
|
|
|
}
|
|
|
|
|
2020-03-01 22:42:52 -05:00
|
|
|
void spawn_default_star(f32 sp20, f32 sp24, f32 sp28) {
|
2019-08-25 00:46:40 -04:00
|
|
|
struct Object *sp1C;
|
2020-03-01 22:42:52 -05:00
|
|
|
sp1C = spawn_star(sp1C, sp20, sp24, sp28);
|
2019-08-25 00:46:40 -04:00
|
|
|
sp1C->oBehParams2ndByte = 0;
|
|
|
|
}
|
|
|
|
|
2020-03-01 22:42:52 -05:00
|
|
|
void spawn_red_coin_cutscene_star(f32 sp20, f32 sp24, f32 sp28) {
|
2019-08-25 00:46:40 -04:00
|
|
|
struct Object *sp1C;
|
2020-03-01 22:42:52 -05:00
|
|
|
sp1C = spawn_star(sp1C, sp20, sp24, sp28);
|
2019-08-25 00:46:40 -04:00
|
|
|
sp1C->oBehParams2ndByte = 1;
|
|
|
|
}
|
|
|
|
|
2020-03-01 22:42:52 -05:00
|
|
|
void spawn_no_exit_star(f32 sp20, f32 sp24, f32 sp28) {
|
2019-08-25 00:46:40 -04:00
|
|
|
struct Object *sp1C;
|
2020-03-01 22:42:52 -05:00
|
|
|
sp1C = spawn_star(sp1C, sp20, sp24, sp28);
|
2019-08-25 00:46:40 -04:00
|
|
|
sp1C->oBehParams2ndByte = 1;
|
2019-09-01 15:50:50 -04:00
|
|
|
sp1C->oInteractionSubtype |= INT_SUBTYPE_NO_EXIT;
|
2019-08-25 00:46:40 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void bhv_hidden_red_coin_star_init(void) {
|
|
|
|
s16 sp36;
|
|
|
|
struct Object *sp30;
|
|
|
|
|
|
|
|
if (gCurrCourseNum != 3)
|
|
|
|
spawn_object(o, MODEL_TRANSPARENT_STAR, bhvRedCoinStarMarker);
|
|
|
|
|
|
|
|
sp36 = count_objects_with_behavior(bhvRedCoin);
|
|
|
|
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;
|
|
|
|
o->activeFlags = 0;
|
|
|
|
}
|
|
|
|
|
2019-10-05 15:08:05 -04:00
|
|
|
o->oHiddenStarTriggerCounter = 8 - sp36;
|
2019-08-25 00:46:40 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void bhv_hidden_red_coin_star_loop(void) {
|
2019-10-05 15:08:05 -04:00
|
|
|
gRedCoinsCollected = o->oHiddenStarTriggerCounter;
|
2019-08-25 00:46:40 -04:00
|
|
|
switch (o->oAction) {
|
|
|
|
case 0:
|
2019-10-05 15:08:05 -04:00
|
|
|
if (o->oHiddenStarTriggerCounter == 8)
|
2019-08-25 00:46:40 -04:00
|
|
|
o->oAction = 1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
if (o->oTimer > 2) {
|
2020-03-01 22:42:52 -05:00
|
|
|
spawn_red_coin_cutscene_star(o->oPosX, o->oPosY, o->oPosZ);
|
|
|
|
spawn_mist_particles();
|
2019-08-25 00:46:40 -04:00
|
|
|
o->activeFlags = 0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|