tuxie.inc.c (11362B)
1 // tuxie.inc.c 2 3 void play_penguin_walking_sound(s32 walk) { 4 s32 sound; 5 6 if (o->oSoundStateID == 0) { 7 if (walk == PENGUIN_WALK_BABY) { 8 sound = SOUND_OBJ_BABY_PENGUIN_WALK; 9 } else { // PENGUIN_WALK_BIG 10 sound = SOUND_OBJ_BIG_PENGUIN_WALK; 11 } 12 set_obj_anim_with_accel_and_sound(1, 11, sound); 13 } 14 } 15 16 void tuxies_mother_act_2(void) { 17 f32 sp24; 18 UNUSED u8 filler[4]; 19 struct Object *sp1C = cur_obj_find_nearest_object_with_behavior(bhvSmallPenguin, &sp24); 20 21 if (cur_obj_find_nearby_held_actor(bhvUnused20E0, 1000.0f) != NULL) { 22 if (o->oSubAction == 0) { 23 cur_obj_init_animation_with_sound(0); 24 o->oForwardVel = 10.0f; 25 if (cur_obj_lateral_dist_from_mario_to_home() > 800.0f) { 26 o->oSubAction = 1; 27 } 28 cur_obj_rotate_yaw_toward(o->oAngleToMario, 0x400); 29 } else { 30 o->oForwardVel = 0.0f; 31 cur_obj_init_animation_with_sound(3); 32 if (cur_obj_lateral_dist_from_mario_to_home() < 700.0f) { 33 o->oSubAction = 0; 34 } 35 } 36 } else { 37 o->oForwardVel = 0.0f; 38 cur_obj_init_animation_with_sound(3); 39 } 40 41 if (sp1C != NULL && sp24 < 300.0f && sp1C->oHeldState != HELD_FREE) { 42 o->oAction = 1; 43 sp1C->oSmallPenguinUnk88 = TRUE; 44 o->prevObj = sp1C; 45 } 46 } 47 48 void tuxies_mother_act_1(void) { 49 switch (o->oSubAction) { 50 case 0: 51 cur_obj_init_animation_with_sound(3); 52 if (!cur_obj_is_mario_on_platform()) { 53 s32 sp2C = (o->oBhvParams >> 16) & 0xFF; 54 s32 sp28 = (o->prevObj->oBhvParams >> 16) & 0xFF; 55 s32 dialogID; 56 57 if (sp2C == sp28) { 58 dialogID = DIALOG_058; 59 } else { 60 dialogID = DIALOG_059; 61 } 62 if (cur_obj_update_dialog_with_cutscene(MARIO_DIALOG_LOOK_UP, 63 DIALOG_FLAG_TURN_TO_MARIO, CUTSCENE_DIALOG, dialogID)) { 64 if (dialogID == DIALOG_058) { 65 o->oSubAction = 1; 66 } else { 67 o->oSubAction = 2; 68 } 69 o->prevObj->oInteractionSubtype |= INT_SUBTYPE_DROP_IMMEDIATELY; 70 } 71 } else { 72 cur_obj_init_animation_with_sound(0); 73 } 74 break; 75 76 case 1: 77 if (o->prevObj->oHeldState == HELD_FREE) { 78 //! This line is was almost certainly supposed to be something 79 // like o->prevObj->oInteractionSubtype &= ~INT_SUBTYPE_DROP_IMMEDIATELY; 80 // however, this code uses the value of o->oInteractionSubtype 81 // rather than its offset to rawData. For this object, 82 // o->oInteractionSubtype is always 0, so the result is this: 83 // o->prevObj->oUnknownUnk88 &= ~INT_SUBTYPE_DROP_IMMEDIATELY 84 // which has no effect as o->prevObj->oUnknownUnk88 is always 0 85 // or 1, which is not affected by the bitwise AND. 86 o->prevObj->OBJECT_FIELD_S32(o->oInteractionSubtype) &= ~INT_SUBTYPE_DROP_IMMEDIATELY; 87 obj_set_behavior(o->prevObj, bhvUnused20E0); 88 #ifndef VERSION_JP 89 cur_obj_spawn_star_at_y_offset(3167.0f, -4300.0f, 5108.0f, 200.0f); 90 #else 91 spawn_default_star(3500.0f, -4300.0f, 4650.0f); 92 #endif 93 o->oAction = 2; 94 } 95 break; 96 97 case 2: 98 if (o->prevObj->oHeldState == HELD_FREE) { 99 //! Same bug as above 100 o->prevObj->OBJECT_FIELD_S32(o->oInteractionSubtype) &= ~INT_SUBTYPE_DROP_IMMEDIATELY; 101 obj_set_behavior(o->prevObj, bhvPenguinBaby); 102 o->oAction = 2; 103 } 104 break; 105 } 106 } 107 108 void tuxies_mother_act_0(void) { 109 s32 sp2C = FALSE; 110 f32 sp28; 111 struct Object *sp24 = cur_obj_find_nearest_object_with_behavior(bhvSmallPenguin, &sp28); 112 113 cur_obj_scale(4.0f); 114 cur_obj_init_animation_with_sound(3); 115 116 if (sp28 < 500.0f) { 117 sp2C = TRUE; 118 } 119 120 if (sp24 != NULL && sp28 < 300.0f && sp24->oHeldState != HELD_FREE) { 121 o->oAction = 1; 122 sp24->oSmallPenguinUnk88 = TRUE; 123 o->prevObj = sp24; 124 } else { 125 switch (o->oSubAction) { 126 case 0: 127 if (cur_obj_can_mario_activate_textbox_2(300.0f, 100.0f) && !sp2C) { 128 o->oSubAction++; 129 } 130 break; 131 case 1: 132 if (cur_obj_update_dialog_with_cutscene(MARIO_DIALOG_LOOK_UP, 133 DIALOG_FLAG_TURN_TO_MARIO, CUTSCENE_DIALOG, DIALOG_057)) { 134 o->oSubAction++; 135 } 136 break; 137 case 2: 138 if (o->oDistanceToMario > 450.0f) { 139 o->oSubAction = 0; 140 } 141 break; 142 } 143 } 144 145 if (cur_obj_check_anim_frame(1)) { 146 cur_obj_play_sound_2(SOUND_OBJ_BIG_PENGUIN_YELL); 147 } 148 } 149 150 void (*sTuxiesMotherActions[])(void) = { 151 tuxies_mother_act_0, 152 tuxies_mother_act_1, 153 tuxies_mother_act_2, 154 }; 155 156 void bhv_tuxies_mother_loop(void) { 157 o->activeFlags |= ACTIVE_FLAG_UNK10; 158 cur_obj_update_floor_and_walls(); 159 cur_obj_call_action_function(sTuxiesMotherActions); 160 cur_obj_move_standard(-78); 161 play_penguin_walking_sound(PENGUIN_WALK_BIG); 162 o->oInteractStatus = 0; 163 } 164 165 void small_penguin_dive_with_mario(void) { 166 if (mario_is_dive_sliding()) { 167 o->oSmallPenguinUnk100 = o->oAction; 168 o->oAction = 3; 169 } 170 } 171 172 void small_penguin_act_2(void) { 173 s32 sp1C = FALSE; 174 175 if (o->oTimer == 0 176 && cur_obj_dist_to_nearest_object_with_behavior(bhvTuxiesMother) < 1000.0f) { 177 sp1C = TRUE; 178 } 179 cur_obj_init_animation_with_sound(0); 180 o->oForwardVel = o->oSmallPenguinUnk104 + 3.0f; 181 cur_obj_rotate_yaw_toward(o->oAngleToMario + 0x8000, o->oSmallPenguinUnk110 + 0x600); 182 if (o->oDistanceToMario > o->oSmallPenguinUnk108 + 500.0f) { 183 o->oAction = 0; 184 } 185 small_penguin_dive_with_mario(); 186 if (sp1C) { 187 o->oAction = 5; 188 } 189 } 190 191 void small_penguin_act_1(void) { 192 cur_obj_init_animation_with_sound(0); 193 o->oForwardVel = o->oSmallPenguinUnk104 + 3.0f; 194 cur_obj_rotate_yaw_toward(o->oAngleToMario, o->oSmallPenguinUnk110 + 0x600); 195 if (o->oDistanceToMario < o->oSmallPenguinUnk108 + 300.0f) { 196 o->oAction = 0; 197 } 198 if (o->oDistanceToMario > 1100.0f) { 199 o->oAction = 0; 200 } 201 small_penguin_dive_with_mario(); 202 } 203 204 void small_penguin_act_3(void) { 205 if (o->oTimer > 5) { 206 if (o->oTimer == 6) { 207 cur_obj_play_sound_2(SOUND_OBJ_BABY_PENGUIN_DIVE); 208 } 209 cur_obj_init_animation_with_sound(1); 210 if (o->oTimer > 25 && !mario_is_dive_sliding()) { 211 o->oAction = 4; 212 } 213 } 214 } 215 216 void small_penguin_act_4(void) { 217 if (o->oTimer > 20) { 218 o->oForwardVel = 0.0f; 219 cur_obj_init_animation_with_sound(2); 220 if (o->oTimer > 40) { 221 o->oAction = o->oSmallPenguinUnk100; 222 } 223 } 224 } 225 226 void small_penguin_act_0(void) { 227 s32 sp1C = FALSE; 228 229 cur_obj_init_animation_with_sound(3); 230 if (o->oTimer == 0) { 231 o->oSmallPenguinUnk110 = (s32)(random_float() * 0x400); 232 o->oSmallPenguinUnk108 = random_float() * 100.0f; 233 o->oSmallPenguinUnk104 = random_float(); 234 o->oForwardVel = 0.0f; 235 if (cur_obj_dist_to_nearest_object_with_behavior(bhvTuxiesMother) < 1000.0f) { 236 sp1C = TRUE; 237 } 238 } 239 if (o->oDistanceToMario < 1000.0f && o->oDistanceToMario > o->oSmallPenguinUnk108 + 600.0f) { 240 o->oAction = 1; 241 } else if (o->oDistanceToMario < o->oSmallPenguinUnk108 + 300.0f) { 242 o->oAction = 2; 243 } 244 if (sp1C) { 245 o->oAction = 5; 246 } 247 if (cur_obj_mario_far_away()) { 248 cur_obj_set_pos_to_home(); 249 } 250 } 251 252 void small_penguin_act_5(void) { 253 f32 sp24; 254 s16 sp22; 255 struct Object *sp1C = cur_obj_nearest_object_with_behavior(bhvTuxiesMother); 256 257 if (sp1C != NULL) { 258 if (o->oDistanceToMario < 1000.0f) { 259 o->oForwardVel = 2.0f; 260 } else { 261 o->oForwardVel = 0.0f; 262 } 263 264 sp24 = dist_between_objects(o, sp1C); 265 sp22 = obj_angle_to_object(o, sp1C); 266 267 if (sp24 > 200.0f) { 268 cur_obj_rotate_yaw_toward(sp22, 0x400); 269 } else { 270 cur_obj_rotate_yaw_toward(sp22 + 0x8000, 0x400); 271 } 272 273 cur_obj_init_animation_with_sound(0); 274 } 275 276 small_penguin_dive_with_mario(); 277 } 278 279 void (*sSmallPenguinActions[])(void) = { 280 small_penguin_act_0, 281 small_penguin_act_1, 282 small_penguin_act_2, 283 small_penguin_act_3, 284 small_penguin_act_4, 285 small_penguin_act_5, 286 }; 287 288 void small_penguin_free_actions(void) { 289 if (o->oSmallPenguinUnk88) { 290 o->oAction = 5; 291 o->oSmallPenguinUnk88 = FALSE; 292 } 293 cur_obj_update_floor_and_walls(); 294 cur_obj_call_action_function(sSmallPenguinActions); 295 cur_obj_move_standard(-78); 296 play_penguin_walking_sound(PENGUIN_WALK_BABY); 297 } 298 299 void bhv_small_penguin_loop(void) { 300 switch (o->oHeldState) { 301 case HELD_FREE: 302 small_penguin_free_actions(); 303 break; 304 case HELD_HELD: 305 cur_obj_unrender_set_action_and_anim(0, 0); 306 if (cur_obj_has_behavior(bhvPenguinBaby)) { 307 obj_set_behavior(o, bhvSmallPenguin); 308 } 309 obj_copy_pos(o, gMarioObject); 310 if (gGlobalTimer % 30 == 0) { 311 #ifndef VERSION_JP 312 play_sound(SOUND_OBJ2_BABY_PENGUIN_YELL, gMarioObject->header.gfx.cameraToObject); 313 #else 314 play_sound(SOUND_OBJ2_BABY_PENGUIN_YELL, o->header.gfx.cameraToObject); 315 #endif 316 } 317 break; 318 case HELD_THROWN: 319 cur_obj_get_thrown_or_placed(0, 0, 0); 320 break; 321 case HELD_DROPPED: 322 cur_obj_get_dropped(); 323 break; 324 } 325 } 326 327 /** Geo switch logic for Tuxie's mother's eyes. Cases 0-4. Interestingly, case 328 * 4 is unused, and is the eye state seen in Shoshinkai 1995 footage. 329 */ 330 Gfx *geo_switch_tuxie_mother_eyes(s32 run, struct GraphNode *node, UNUSED Mat4 *mtx) { 331 if (run == TRUE) { 332 struct Object *obj = (struct Object *) gCurGraphNodeObject; 333 struct GraphNodeSwitchCase *switchCase = (struct GraphNodeSwitchCase *) node; 334 s32 timer; 335 336 switchCase->selectedCase = 0; 337 338 // timer logic for blinking. uses cases 0-2. 339 timer = gGlobalTimer % 50; 340 if (timer < 43) { 341 switchCase->selectedCase = 0; 342 } else if (timer < 45) { 343 switchCase->selectedCase = 1; 344 } else if (timer < 47) { 345 switchCase->selectedCase = 2; 346 } else { 347 switchCase->selectedCase = 1; 348 } 349 350 /** make Tuxie's Mother have angry eyes if Mario takes the correct baby 351 * after giving it back. The easiest way to check this is to see if she's 352 * moving, since she only does when she's chasing Mario. 353 */ 354 if (obj->behavior == segmented_to_virtual(bhvTuxiesMother)) { 355 if (obj->oForwardVel > 5.0f) { 356 switchCase->selectedCase = 3; 357 } 358 } 359 } 360 361 return NULL; 362 }