yoshi.inc.c (5761B)
1 // yoshi.inc.c 2 3 // X/Z coordinates of Yoshi's homes that he switches between. 4 // Note that this doesn't contain the Y coordinate since the castle roof is flat, 5 // so o->oHomeY is never updated. 6 static s16 sYoshiHomeLocations[] = { 0, -5625, -1364, -5912, -1403, -4609, -1004, -5308 }; 7 8 void bhv_yoshi_init(void) { 9 o->oGravity = 2.0f; 10 o->oFriction = 0.9f; 11 o->oBuoyancy = 1.3f; 12 o->oInteractionSubtype = INT_SUBTYPE_NPC; 13 14 if (save_file_get_total_star_count(gCurrSaveFileNum - 1, COURSE_MIN - 1, COURSE_MAX - 1) < 120 15 || sYoshiDead == TRUE) { 16 o->activeFlags = ACTIVE_FLAG_DEACTIVATED; 17 } 18 } 19 20 void yoshi_walk_loop(void) { 21 UNUSED s16 collisionFlags; 22 s16 animFrame = o->header.gfx.animInfo.animFrame; 23 24 o->oForwardVel = 10.0f; 25 collisionFlags = object_step(); 26 o->oMoveAngleYaw = approach_s16_symmetric(o->oMoveAngleYaw, o->oYoshiTargetYaw, 0x500); 27 28 if (is_point_close_to_object(o, o->oHomeX, 3174.0f, o->oHomeZ, 200)) { 29 o->oAction = YOSHI_ACT_IDLE; 30 } 31 32 cur_obj_init_animation(1); 33 34 if (animFrame == 0 || animFrame == 15) { 35 cur_obj_play_sound_2(SOUND_GENERAL_YOSHI_WALK); 36 } 37 38 if (o->oInteractStatus == INT_STATUS_INTERACTED) { 39 o->oAction = YOSHI_ACT_TALK; 40 } 41 42 if (o->oPosY < 2100.0f) { 43 create_respawner(MODEL_YOSHI, bhvYoshi, 3000); 44 o->activeFlags = ACTIVE_FLAG_DEACTIVATED; 45 } 46 } 47 48 void yoshi_idle_loop(void) { 49 s16 chosenHome; 50 UNUSED s16 animFrame = o->header.gfx.animInfo.animFrame; 51 52 if (o->oTimer > 90) { 53 chosenHome = random_float() * 3.99; 54 55 if (o->oYoshiChosenHome == chosenHome) { 56 return; 57 } else { 58 o->oYoshiChosenHome = chosenHome; 59 } 60 61 o->oHomeX = sYoshiHomeLocations[o->oYoshiChosenHome * 2]; 62 o->oHomeZ = sYoshiHomeLocations[o->oYoshiChosenHome * 2 + 1]; 63 o->oYoshiTargetYaw = atan2s(o->oHomeZ - o->oPosZ, o->oHomeX - o->oPosX); 64 o->oAction = YOSHI_ACT_WALK; 65 } 66 67 cur_obj_init_animation(0); 68 69 if (o->oInteractStatus == INT_STATUS_INTERACTED) { 70 o->oAction = YOSHI_ACT_TALK; 71 } 72 73 // Credits; Yoshi appears at this position overlooking the castle near the end of the credits 74 if (gPlayerCameraState->cameraEvent == CAM_EVENT_START_ENDING || 75 gPlayerCameraState->cameraEvent == CAM_EVENT_START_END_WAVING) { 76 o->oAction = YOSHI_ACT_CREDITS; 77 o->oPosX = -1798.0f; 78 o->oPosY = 3174.0f; 79 o->oPosZ = -3644.0f; 80 } 81 } 82 83 void yoshi_talk_loop(void) { 84 if ((s16) o->oMoveAngleYaw == (s16) o->oAngleToMario) { 85 cur_obj_init_animation(0); 86 if (set_mario_npc_dialog(MARIO_DIALOG_LOOK_FRONT) == MARIO_DIALOG_STATUS_SPEAK) { 87 o->activeFlags |= ACTIVE_FLAG_INITIATED_TIME_STOP; 88 if (cutscene_object_with_dialog(CUTSCENE_DIALOG, o, DIALOG_161) != 0) { 89 o->activeFlags &= ~ACTIVE_FLAG_INITIATED_TIME_STOP; 90 o->oInteractStatus = 0; 91 o->oHomeX = sYoshiHomeLocations[2]; 92 o->oHomeZ = sYoshiHomeLocations[3]; 93 o->oYoshiTargetYaw = atan2s(o->oHomeZ - o->oPosZ, o->oHomeX - o->oPosX); 94 o->oAction = YOSHI_ACT_GIVE_PRESENT; 95 } 96 } 97 } else { 98 cur_obj_init_animation(1); 99 play_puzzle_jingle(); 100 o->oMoveAngleYaw = approach_s16_symmetric(o->oMoveAngleYaw, o->oAngleToMario, 0x500); 101 } 102 } 103 104 void yoshi_walk_and_jump_off_roof_loop(void) { 105 s16 animFrame = o->header.gfx.animInfo.animFrame; 106 107 o->oForwardVel = 10.0f; 108 object_step(); 109 cur_obj_init_animation(1); 110 111 if (o->oTimer == 0) { 112 cutscene_object(CUTSCENE_STAR_SPAWN, o); 113 } 114 115 o->oMoveAngleYaw = approach_s16_symmetric(o->oMoveAngleYaw, o->oYoshiTargetYaw, 0x500); 116 117 if (is_point_close_to_object(o, o->oHomeX, 3174.0f, o->oHomeZ, 200)) { 118 cur_obj_init_animation(2); 119 cur_obj_play_sound_2(SOUND_GENERAL_ENEMY_ALERT1); 120 o->oForwardVel = 50.0f; 121 o->oVelY = 40.0f; 122 o->oMoveAngleYaw = -0x3FFF; 123 o->oAction = YOSHI_ACT_FINISH_JUMPING_AND_DESPAWN; 124 } 125 126 if (animFrame == 0 || animFrame == 15) { 127 cur_obj_play_sound_2(SOUND_GENERAL_YOSHI_WALK); 128 } 129 } 130 131 void yoshi_finish_jumping_and_despawn_loop(void) { 132 cur_obj_extend_animation_if_at_end(); 133 obj_move_xyz_using_fvel_and_yaw(o); 134 135 o->oVelY -= 2.0; 136 137 if (o->oPosY < 2100.0f) { 138 set_mario_npc_dialog(MARIO_DIALOG_STOP); 139 gObjCutsceneDone = TRUE; 140 sYoshiDead = TRUE; 141 o->activeFlags = ACTIVE_FLAG_DEACTIVATED; 142 } 143 } 144 145 void yoshi_give_present_loop(void) { 146 s32 globalTimer = gGlobalTimer; 147 148 if (gHudDisplay.lives == 100) { 149 play_sound(SOUND_GENERAL_COLLECT_1UP, gGlobalSoundSource); 150 gSpecialTripleJump = TRUE; 151 o->oAction = YOSHI_ACT_WALK_JUMP_OFF_ROOF; 152 return; 153 } 154 155 if (!(globalTimer & 3)) { 156 play_sound(SOUND_MENU_YOSHI_GAIN_LIVES, gGlobalSoundSource); 157 gMarioState->numLives++; 158 } 159 } 160 161 void bhv_yoshi_loop(void) { 162 switch (o->oAction) { 163 case YOSHI_ACT_IDLE: 164 yoshi_idle_loop(); 165 break; 166 167 case YOSHI_ACT_WALK: 168 yoshi_walk_loop(); 169 break; 170 171 case YOSHI_ACT_TALK: 172 yoshi_talk_loop(); 173 break; 174 175 case YOSHI_ACT_WALK_JUMP_OFF_ROOF: 176 yoshi_walk_and_jump_off_roof_loop(); 177 break; 178 179 case YOSHI_ACT_FINISH_JUMPING_AND_DESPAWN: 180 yoshi_finish_jumping_and_despawn_loop(); 181 break; 182 183 case YOSHI_ACT_GIVE_PRESENT: 184 yoshi_give_present_loop(); 185 break; 186 187 case YOSHI_ACT_CREDITS: 188 cur_obj_init_animation(0); 189 break; 190 } 191 192 curr_obj_random_blink(&o->oYoshiBlinkTimer); 193 }