2019-08-25 04:46:40 +00:00
|
|
|
// yoshi.c.inc
|
|
|
|
|
|
|
|
// X/Z coordinates of Yoshi's homes that he switches between.
|
|
|
|
// Note that this doesn't contain the Y coordinate since the castle roof is flat,
|
|
|
|
// so o->oHomeY is never updated.
|
|
|
|
static s16 sYoshiHomeLocations[] = { 0, -5625, -1364, -5912, -1403, -4609, -1004, -5308 };
|
|
|
|
|
|
|
|
void bhv_yoshi_init(void) {
|
|
|
|
o->oGravity = 2.0f;
|
|
|
|
o->oFriction = 0.9f;
|
|
|
|
o->oBuoyancy = 1.3f;
|
2019-09-01 19:50:50 +00:00
|
|
|
o->oInteractionSubtype = INT_SUBTYPE_NPC;
|
2019-08-25 04:46:40 +00:00
|
|
|
|
2019-12-02 02:52:53 +00:00
|
|
|
if (save_file_get_total_star_count(gCurrSaveFileNum - 1, 0, 24) < 120 || sYoshiDead == TRUE) {
|
2019-08-25 04:46:40 +00:00
|
|
|
o->activeFlags = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void yoshi_walk_loop(void) {
|
|
|
|
UNUSED s16 sp26;
|
|
|
|
s16 sp24 = o->header.gfx.unk38.animFrame;
|
|
|
|
|
|
|
|
o->oForwardVel = 10.0f;
|
2019-12-02 02:52:53 +00:00
|
|
|
sp26 = object_step();
|
2019-08-25 04:46:40 +00:00
|
|
|
o->oMoveAngleYaw = approach_s16_symmetric(o->oMoveAngleYaw, o->oYoshiTargetYaw, 0x500);
|
2019-12-02 02:52:53 +00:00
|
|
|
if (is_point_close_to_object(o, o->oHomeX, 3174.0f, o->oHomeZ, 200))
|
2019-08-25 04:46:40 +00:00
|
|
|
o->oAction = YOSHI_ACT_IDLE;
|
|
|
|
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_init_animation(1);
|
2019-08-25 04:46:40 +00:00
|
|
|
if (sp24 == 0 || sp24 == 15)
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_play_sound_2(SOUND_GENERAL_YOSHI_WALK);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
if (o->oInteractStatus == INT_STATUS_INTERACTED)
|
|
|
|
o->oAction = YOSHI_ACT_TALK;
|
|
|
|
|
|
|
|
if (o->oPosY < 2100.0f) {
|
|
|
|
create_respawner(MODEL_YOSHI, bhvYoshi, 3000);
|
|
|
|
o->activeFlags = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void yoshi_idle_loop(void) {
|
|
|
|
s16 chosenHome;
|
|
|
|
UNUSED s16 sp1C = o->header.gfx.unk38.animFrame;
|
|
|
|
|
|
|
|
if (o->oTimer > 90) {
|
2020-04-03 18:57:26 +00:00
|
|
|
chosenHome = random_float() * 3.99;
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
if (o->oYoshiChosenHome == chosenHome) {
|
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
o->oYoshiChosenHome = chosenHome;
|
|
|
|
}
|
|
|
|
|
|
|
|
o->oHomeX = sYoshiHomeLocations[o->oYoshiChosenHome * 2];
|
|
|
|
o->oHomeZ = sYoshiHomeLocations[o->oYoshiChosenHome * 2 + 1];
|
|
|
|
o->oYoshiTargetYaw = atan2s(o->oHomeZ - o->oPosZ, o->oHomeX - o->oPosX);
|
|
|
|
o->oAction = YOSHI_ACT_WALK;
|
|
|
|
}
|
|
|
|
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_init_animation(0);
|
2019-08-25 04:46:40 +00:00
|
|
|
if (o->oInteractStatus == INT_STATUS_INTERACTED)
|
|
|
|
o->oAction = YOSHI_ACT_TALK;
|
|
|
|
|
|
|
|
// Credits; Yoshi appears at this position overlooking the castle near the end of the credits
|
2020-01-03 15:38:57 +00:00
|
|
|
if (gPlayerCameraState->cameraEvent == CAM_EVENT_START_ENDING ||
|
|
|
|
gPlayerCameraState->cameraEvent == CAM_EVENT_START_END_WAVING) {
|
2019-08-25 04:46:40 +00:00
|
|
|
o->oAction = YOSHI_ACT_CREDITS;
|
|
|
|
o->oPosX = -1798.0f;
|
|
|
|
o->oPosY = 3174.0f;
|
|
|
|
o->oPosZ = -3644.0f;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void yoshi_talk_loop(void) {
|
|
|
|
if ((s16) o->oMoveAngleYaw == (s16) o->oAngleToMario) {
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_init_animation(0);
|
2019-08-25 04:46:40 +00:00
|
|
|
if (set_mario_npc_dialog(1) == 2) {
|
|
|
|
o->activeFlags |= 0x20;
|
2020-01-03 15:38:57 +00:00
|
|
|
if (cutscene_object_with_dialog(CUTSCENE_DIALOG, o, DIALOG_161)) {
|
2019-08-25 04:46:40 +00:00
|
|
|
o->activeFlags &= ~0x20;
|
|
|
|
o->oInteractStatus = 0;
|
|
|
|
o->oHomeX = sYoshiHomeLocations[2];
|
|
|
|
o->oHomeZ = sYoshiHomeLocations[3];
|
|
|
|
o->oYoshiTargetYaw = atan2s(o->oHomeZ - o->oPosZ, o->oHomeX - o->oPosX);
|
|
|
|
o->oAction = YOSHI_ACT_GIVE_PRESENT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_init_animation(1);
|
2019-08-25 04:46:40 +00:00
|
|
|
play_puzzle_jingle();
|
|
|
|
o->oMoveAngleYaw = approach_s16_symmetric(o->oMoveAngleYaw, o->oAngleToMario, 0x500);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void yoshi_walk_and_jump_off_roof_loop(void) {
|
|
|
|
s16 sp26 = o->header.gfx.unk38.animFrame;
|
|
|
|
|
|
|
|
o->oForwardVel = 10.0f;
|
2019-12-02 02:52:53 +00:00
|
|
|
object_step();
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_init_animation(1);
|
2019-08-25 04:46:40 +00:00
|
|
|
if (o->oTimer == 0)
|
2019-10-05 19:08:05 +00:00
|
|
|
cutscene_object(CUTSCENE_STAR_SPAWN, o);
|
2019-08-25 04:46:40 +00:00
|
|
|
|
|
|
|
o->oMoveAngleYaw = approach_s16_symmetric(o->oMoveAngleYaw, o->oYoshiTargetYaw, 0x500);
|
2019-12-02 02:52:53 +00:00
|
|
|
if (is_point_close_to_object(o, o->oHomeX, 3174.0f, o->oHomeZ, 200)) {
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_init_animation(2);
|
|
|
|
cur_obj_play_sound_2(SOUND_GENERAL_ENEMY_ALERT1);
|
2019-08-25 04:46:40 +00:00
|
|
|
o->oForwardVel = 50.0f;
|
|
|
|
o->oVelY = 40.0f;
|
|
|
|
o->oMoveAngleYaw = -0x3FFF;
|
|
|
|
o->oAction = YOSHI_ACT_FINISH_JUMPING_AND_DESPAWN;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sp26 == 0 || sp26 == 15) {
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_play_sound_2(SOUND_GENERAL_YOSHI_WALK);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void yoshi_finish_jumping_and_despawn_loop(void) {
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_extend_animation_if_at_end();
|
2019-08-25 04:46:40 +00:00
|
|
|
obj_move_xyz_using_fvel_and_yaw(o);
|
|
|
|
o->oVelY -= 2.0;
|
|
|
|
if (o->oPosY < 2100.0f) {
|
|
|
|
set_mario_npc_dialog(0);
|
2020-01-03 15:38:57 +00:00
|
|
|
gObjCutsceneDone = TRUE;
|
2019-12-02 02:52:53 +00:00
|
|
|
sYoshiDead = 1;
|
2019-08-25 04:46:40 +00:00
|
|
|
o->activeFlags = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void yoshi_give_present_loop(void) {
|
|
|
|
s32 sp1C = gGlobalTimer;
|
|
|
|
|
|
|
|
if (gHudDisplay.lives == 100) {
|
2019-10-05 19:08:05 +00:00
|
|
|
play_sound(SOUND_GENERAL_COLLECT_1UP, gDefaultSoundArgs);
|
2019-08-25 04:46:40 +00:00
|
|
|
gSpecialTripleJump = 1;
|
|
|
|
o->oAction = YOSHI_ACT_WALK_JUMP_OFF_ROOF;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((sp1C & 0x03) == 0) {
|
2019-10-05 19:08:05 +00:00
|
|
|
play_sound(SOUND_MENU_YOSHI_GAIN_LIVES, gDefaultSoundArgs);
|
2019-08-25 04:46:40 +00:00
|
|
|
gMarioState->numLives++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-02 03:42:52 +00:00
|
|
|
void bhv_yoshi_loop(void) {
|
2019-08-25 04:46:40 +00:00
|
|
|
switch (o->oAction) {
|
|
|
|
case YOSHI_ACT_IDLE:
|
|
|
|
yoshi_idle_loop();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case YOSHI_ACT_WALK:
|
|
|
|
yoshi_walk_loop();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case YOSHI_ACT_TALK:
|
|
|
|
yoshi_talk_loop();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case YOSHI_ACT_WALK_JUMP_OFF_ROOF:
|
|
|
|
yoshi_walk_and_jump_off_roof_loop();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case YOSHI_ACT_FINISH_JUMPING_AND_DESPAWN:
|
|
|
|
yoshi_finish_jumping_and_despawn_loop();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case YOSHI_ACT_GIVE_PRESENT:
|
|
|
|
yoshi_give_present_loop();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case YOSHI_ACT_CREDITS:
|
2020-03-02 03:42:52 +00:00
|
|
|
cur_obj_init_animation(0);
|
2019-08-25 04:46:40 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2020-03-02 03:42:52 +00:00
|
|
|
curr_obj_random_blink(&o->oYoshiUnkF4);
|
2019-08-25 04:46:40 +00:00
|
|
|
}
|