// bowser.c.inc void ActionBowserTailAnchor0(void) { struct Object *bowser = o->parentObj; obj_become_tangible(); obj_scale(1.0f); if (bowser->oAction == 19) bowser->oIntangibleTimer = -1; else if (are_objects_collided(o, gMarioObject)) { bowser->oIntangibleTimer = 0; o->oAction = 2; } else bowser->oIntangibleTimer = -1; } void ActionBowserTailAnchor1(void) { if (o->oTimer > 30) o->oAction = 0; } void ActionBowserTailAnchor2(void) { if (o->parentObj->oAction == 19) { o->parentObj->oIntangibleTimer = -1; o->oAction = 0; } obj_become_intangible(); } void (*sBowserTailAnchorActions[])(void) = { ActionBowserTailAnchor0, ActionBowserTailAnchor1, ActionBowserTailAnchor2 }; s8 D_8032F4FC[] = { 7, 8, 9, 12, 13, 14, 15, 4, 3, 16, 17, 19, 3, 3, 3, 3 }; s16 D_8032F50C[] = { 60, 0 }; s16 D_8032F510[] = { 50, 0 }; s8 D_8032F514[] = { 24, 42, 60, -1 }; s16 D_8032F518[3] = { 119, 120, 121 }; s16 D_8032F520[][3] = { { 1, 10, 40 }, { 0, 0, 74 }, { -1, -10, 114 }, { 1, -20, 134 }, { -1, 20, 154 }, { 1, 40, 164 }, { -1, -40, 174 }, { 1, -80, 179 }, { -1, 80, 184 }, { 1, 160, 186 }, { -1, -160, 186 }, { 1, 0, 0 } }; void bhv_bowser_tail_anchor_loop(void) { obj_call_action_function(sBowserTailAnchorActions); o->oParentRelativePosX = 90.0f; if (o->parentObj->oAction == 4) o->parentObj->oIntangibleTimer = -1; o->oInteractStatus = 0; } void bhv_bowser_flame_spawn_loop(void) { struct Object *bowser = o->parentObj; s32 sp30; f32 sp2C; f32 sp28; f32 sp24 = coss(bowser->oMoveAngleYaw); f32 sp20 = sins(bowser->oMoveAngleYaw); s16 *sp1C = segmented_to_virtual(bowser_seg6_unkmoveshorts_060576FC); if (bowser->oSoundStateID == 6) { sp30 = bowser->header.gfx.unk38.animFrame + 1.0f; if (bowser->header.gfx.unk38.curAnim->unk08 == sp30) sp30 = 0; if (sp30 > 45 && sp30 < 85) { PlaySound(SOUND_CH6_BOWSERSPITFIRE); sp2C = sp1C[5 * sp30]; sp28 = sp1C[5 * sp30 + 2]; o->oPosX = bowser->oPosX + (sp28 * sp20 + sp2C * sp24); o->oPosY = bowser->oPosY + sp1C[5 * sp30 + 1]; o->oPosZ = bowser->oPosZ + (sp28 * sp24 - sp2C * sp20); o->oMoveAnglePitch = sp1C[5 * sp30 + 4] + 0xC00; o->oMoveAngleYaw = sp1C[5 * sp30 + 3] + (s16) bowser->oMoveAngleYaw; if (!(sp30 & 1)) spawn_object(o, MODEL_RED_FLAME, bhvFlameMovingForwardGrowing); } } } void bhv_bowser_body_anchor_loop(void) { copy_object_pos_and_angle(o, o->parentObj); if (o->parentObj->oAction == 4) { #ifndef VERSION_JP if (o->parentObj->oSubAction == 11) o->oInteractType = 0; else o->oInteractType = 0x800000; #else o->oInteractType = 0x800000; #endif } else { o->oInteractType = 8; if (o->parentObj->oOpacity < 100) obj_become_intangible(); else obj_become_tangible(); } if (o->parentObj->oHeldState != HELD_FREE) obj_become_intangible(); o->oInteractStatus = 0; } s32 func_802B38B4(void) { struct Object *wave; if (o->oBehParams2ndByte == 2) { wave = spawn_object(o, MODEL_BOWSER_WAVE, bhvBowserShockWave); wave->oPosY = o->oFloorHeight; return 1; } return 0; } void func_802B392C(s32 *a) { if (o->oMoveFlags & 1) { a[0]++; if (a[0] < 4) { func_802A11B4(o, 8); func_802AA618(0, 0, 60.0f); PlaySound2(SOUND_OBJECT_BOWSERWALK); } } } #define BITDW (o->oBehParams2ndByte == 0) #define BITFS (o->oBehParams2ndByte == 1) #define BITS (o->oBehParams2ndByte == 2) s32 func_802B39B8(void) { set_obj_animation_and_sound_state(15); if (obj_check_anim_frame(21)) o->oForwardVel = 3.0f; if (func_8029F788()) return 1; else return 0; } s32 func_802B3A30(void) { o->oForwardVel = 3.0f; set_obj_animation_and_sound_state(13); if (func_8029F788()) return 1; else return 0; } s32 func_802B3A98(void) { set_obj_animation_and_sound_state(14); if (obj_check_anim_frame(20)) o->oForwardVel = 0.0f; if (func_8029F788()) return 1; else return 0; } void func_802B3B0C(void) { if (o->oUnknownUnk88 == 0) o->oAction = 5; else if (o->oUnknownUnk88 == 1) o->oAction = 6; else if (o->oBehParams2ndByte == 1) o->oAction = 13; else o->oAction = 0; } void ActionBowser5() // not much { o->oForwardVel = 0.0f; set_obj_animation_and_sound_state(12); func_802B3B0C(); } void ActionBowser6(void) { if (o->oSubAction == 0) { if (func_802B39B8()) o->oSubAction++; } else if (o->oSubAction == 1) { if (func_802B3A30()) o->oSubAction++; } else if (func_802B3A98()) { if (o->oUnknownUnk88 == 1) o->oUnknownUnk88 = 0; func_802B3B0C(); } } static void Unknown802B3CCC(void) // unused { if (gDebugInfo[5][1] != 0) { o->oAction = D_8032F4FC[gDebugInfo[5][2] & 0xf]; gDebugInfo[5][1] = 0; } } void func_802B3D24(void) { f32 rand = RandomFloat(); if (o->oBowserUnk110 == 0) { if (o->oBowserUnkF4 & 2) { if (o->oDistanceToMario < 1500.0f) o->oAction = 15; // nearby else o->oAction = 17; // far away } else o->oAction = 14; o->oBowserUnk110++; } else { o->oBowserUnk110 = 0; #ifndef VERSION_JP if (!gCurrDemoInput) { if (rand < 0.1) o->oAction = 3; // rare 1/10 chance else o->oAction = 14; // common } else { o->oAction = 14; // ensure demo starts with action 14. } #else if (rand < 0.1) o->oAction = 3; // rare 1/10 chance else o->oAction = 14; // common #endif } } void func_802B3E44(void) { f32 rand = RandomFloat(); if (o->oBowserUnk110 == 0) { if (o->oBowserUnkF4 & 2) { if (o->oDistanceToMario < 1300.0f) // nearby { if (rand < 0.5) // 50/50 o->oAction = 16; else o->oAction = 9; } else // far away { o->oAction = 7; if (500.0f < o->oBowserDistToCentre && o->oBowserDistToCentre < 1500.0f && rand < 0.5) // away from centre and good luck o->oAction = 13; } } else o->oAction = 14; o->oBowserUnk110++; } else { o->oBowserUnk110 = 0; o->oAction = 14; } } void func_802B3FDC(void) { f32 rand = RandomFloat(); if (o->oBowserUnkF4 & 2) { if (o->oDistanceToMario < 1000.0f) { if (rand < 0.4) o->oAction = 9; else if (rand < 0.8) o->oAction = 8; else o->oAction = 15; } else if (rand < 0.5) o->oAction = 13; else o->oAction = 7; } else o->oAction = 14; } void func_802B4124(void) { o->oAction = 13; } void func_802B4144(void) { switch (o->oBowserUnk110) { case 0: if (o->oBowserUnk106 == 0) func_802B3FDC(); else func_802B4124(); o->oBowserUnk110 = 1; break; case 1: o->oBowserUnk110 = 0; o->oAction = 14; break; } } #ifndef VERSION_JP void func_u_802B4AF4(void) { if (o->oVelY < 0 && o->oPosY < (o->oHomeY - 300.0f)) { o->oPosX = o->oPosZ = 0; o->oPosY = o->oHomeY + 2000.0f; o->oVelY = 0; o->oForwardVel = 0; } } #endif void ActionBowser18() // unused? { if (func_802A4AB0(12)) o->oAction = 0; } void ActionBowser0() // only lasts one frame { o->oBowserEyesShut = 0; set_obj_animation_and_sound_state(12); // stop him still o->oAngleVelYaw = 0; o->oForwardVel = 0.0f; o->oVelY = 0.0f; if (BITDW) func_802B3D24(); else if (BITFS) func_802B3E44(); else func_802B4144(); // Action 14 commonly follows } void ActionBowser15(void) { o->oForwardVel = 0.0f; if (o->oTimer == 0) PlaySound2(SOUND_OBJECT_BOWSERINHALING); if (func_802A4AB0(6)) o->oAction = 0; } void ActionBowser14() // turn towards Mario { UNUSED s32 facing; // is Bowser facing Mario? s16 turnSpeed; s16 angleFromMario = abs_angle_diff(o->oMoveAngleYaw, o->oAngleToMario); if (BITFS) turnSpeed = 0x400; else if (o->oHealth > 2) turnSpeed = 0x400; else if (o->oHealth == 2) turnSpeed = 0x300; else turnSpeed = 0x200; facing = obj_rotate_yaw_toward(o->oAngleToMario, turnSpeed); if (o->oSubAction == 0) { o->oBowserUnkF8 = 0; if (func_802B39B8()) o->oSubAction++; } else if (o->oSubAction == 1) { if (func_802B3A30()) { o->oBowserUnkF8++; if (o->oBowserUnkF4 & 0x20000) { if (o->oBowserUnkF8 > 4) o->oBowserUnkF4 &= ~0x20000; } else if (angleFromMario < 0x2000) o->oSubAction++; } } else if (func_802B3A98()) o->oAction = 0; } void ActionBowser16(void) { switch (o->oSubAction) { case 0: obj_become_intangible(); o->oUnk1AC_S16 = 0; o->oBowserUnkF8 = 30; if (o->oTimer == 0) PlaySound2(SOUND_CH9_UNK66); if (o->oOpacity == 0) { o->oSubAction++; o->oMoveAngleYaw = o->oAngleToMario; } break; case 1: if (o->oBowserUnkF8--) o->oForwardVel = 100.0f; else { o->oSubAction = 2; o->oMoveAngleYaw = o->oAngleToMario; } if (abs_angle_diff(o->oMoveAngleYaw, o->oAngleToMario) > 0x4000) if (o->oDistanceToMario > 500.0f) { o->oSubAction = 2; o->oMoveAngleYaw = o->oAngleToMario; // large change in angle? PlaySound2(SOUND_CH9_UNK66); } break; case 2: o->oForwardVel = 0.0f; o->oUnk1AC_S16 = 0xFF; if (o->oOpacity == 0xFF) o->oAction = 0; obj_become_tangible(); break; } } void ActionBowser8(void) // only in sky { s32 frame; set_obj_animation_and_sound_state(11); frame = o->header.gfx.unk38.animFrame; if (frame > 24 && frame < 36) { PlaySound(SOUND_CH6_BOWSERSPITFIRE); if (frame == 35) spawn_object_relative(1, 0, 0x190, 0x64, o, MODEL_RED_FLAME, bhvBlueBowserFlame); else spawn_object_relative(0, 0, 0x190, 0x64, o, MODEL_RED_FLAME, bhvBlueBowserFlame); } if (func_8029F788()) o->oAction = 0; o->oBowserUnkF4 |= 0x20000; } void ActionBowser12(void) { if (o->oTimer == 0) { o->oForwardVel = -400.0f; o->oVelY = 100.0f; o->oMoveAngleYaw = o->oBowserAngleToCentre + 0x8000; o->oBowserEyesShut = 1; } if (o->oSubAction == 0) { set_obj_animation_and_sound_state(25); o->oSubAction++; o->oBowserUnkF8 = 0; } else if (o->oSubAction == 1) { set_obj_animation_and_sound_state(25); func_8029F728(); func_802B392C(&o->oBowserUnkF8); if ((o->oBowserUnkF8 > 2)) { set_obj_animation_and_sound_state(26); o->oVelY = 0.0f; o->oForwardVel = 0.0f; o->oSubAction++; } } else if (o->oSubAction == 2) { if (func_8029F788()) { if (o->oHealth == 1) o->oAction = 3; else o->oAction = 0; o->oBowserEyesShut = 0; } } else { } } s32 func_802B4A44(void) { set_obj_animation_and_sound_state(9); if (obj_check_anim_frame(11)) return 1; else return 0; } s32 func_802B4A94(void) { if (o->oMoveFlags & 1) { o->oForwardVel = 0; o->oVelY = 0; func_802AA618(0, 0, 60.0f); set_obj_animation_and_sound_state(8); o->header.gfx.unk38.animFrame = 0; func_802A11B4(o, 7); if (BITDW) { if (o->oDistanceToMario < 850.0f) gMarioObject->oInteractStatus |= INTERACT_GRABBABLE; else gMarioObject->oInteractStatus |= INTERACT_HOOT; // hmm... } return 1; } else return 0; } void func_802B4BA4(void) { if (BITS && o->oBowserUnkF4 & 0x10000) if (o->oBowserDistToCentre > 1000.0f) o->oForwardVel = 60.0f; } void ActionBowser13(void) { UNUSED s32 unused; if (o->oSubAction == 0) { if (func_802B4A44()) { if (BITS && o->oBowserUnkF4 & 0x10000) o->oVelY = 70.0f; else o->oVelY = 80.0f; o->oBowserUnkF8 = 0; func_802B4BA4(); o->oSubAction++; } } else if (o->oSubAction == 1) { #ifndef VERSION_JP if (o->oBehParams2ndByte == 2 && o->oUnknownUnkF4_S32 & 0x10000) func_u_802B4AF4(); if (func_802B4A94()) { o->oBowserUnkF4 &= 0xfffeffff; o->oForwardVel = 0.0f; o->oSubAction++; func_802B38B4(); if (BITFS) o->oAction = 19; } else { } #else if (func_802B4A94()) { o->oBowserUnkF4 &= 0xfffeffff; o->oForwardVel = 0.0f; o->oSubAction++; func_802B38B4(); if (BITFS) o->oAction = 19; } else { } #endif } else if (func_8029F788()) o->oAction = 0; } void ActionBowser17(void) { f32 sp1C = D_8032F50C[0]; f32 sp18 = D_8032F510[0]; if (o->oSubAction == 0) { if (func_802B4A44()) { o->oVelY = sp1C; o->oForwardVel = sp18; o->oBowserUnkF8 = 0; o->oSubAction++; } } else if (o->oSubAction == 1) { if (func_802B4A94()) o->oSubAction++; } else if (func_8029F788()) o->oAction = 0; } void ActionBowser10(void) { o->oForwardVel = 0.0f; if (o->oTimer == 0) o->oBowserUnkF8 = 0; switch (o->oSubAction) { case 0: set_obj_animation_and_sound_state(23); if (func_8029F788()) o->oBowserUnkF8++; if (o->oBowserUnkF8 > 0) o->oSubAction++; break; case 1: set_obj_animation_and_sound_state(24); if (func_8029F788()) o->oAction = 11; break; } } void ActionBowser9(void) { if (gHudDisplay.wedges < 4) o->oBowserUnk108 = 3; else o->oBowserUnk108 = RandomFloat() * 3.0f + 1.0f; set_obj_animation_and_sound_state(22); if (obj_check_anim_frame(5)) obj_spit_fire(0, 200, 180, 7.0f, MODEL_RED_FLAME, 30.0f, 10.0f, 0x1000); if (func_8029F788()) o->oSubAction++; if (o->oSubAction >= o->oBowserUnk108) o->oAction = 0; } s32 func_802B5108(s32 a0, s16 a1) { if (o->oSubAction == 0) { if (func_802A4AB0(15)) o->oSubAction++; } else if (o->oSubAction == 1) { if (func_802A4AB0(14)) o->oSubAction++; } else set_obj_animation_and_sound_state(12); o->oForwardVel = 0.0f; o->oMoveAngleYaw += a1; if (o->oTimer >= a0) return 1; else return 0; } void ActionBowser11(void) { if (func_802B5108(63, 0x200)) o->oAction = 0; } void ActionBowser7(void) { s32 sp34; if (o->oTimer == 0) o->oForwardVel = 0.0f; switch (o->oSubAction) { case 0: o->oBowserUnkF8 = 0; if (func_802A4AB0(18)) o->oSubAction = 1; break; case 1: o->oForwardVel = 50.0f; if (func_802A4AB0(0x13) != 0) { o->oBowserUnkF8++; if (o->oBowserUnkF8 >= 6) o->oSubAction = 3; if (o->oBowserUnkF8 >= 2) if (abs_angle_diff(o->oAngleToMario, o->oMoveAngleYaw) > 0x2000) o->oSubAction = 3; } obj_rotate_yaw_toward(o->oAngleToMario, 0x200); break; case 3: o->oBowserUnkF8 = 0; set_obj_animation_and_sound_state(21); spawn_object_relative_with_scale(0, 100, -50, 0, 3.0f, o, MODEL_SMOKE, &bhvWhitePuffSmoke2); spawn_object_relative_with_scale(0, -100, -50, 0, 3.0f, o, MODEL_SMOKE, &bhvWhitePuffSmoke2); if (approach_f32_signed(&o->oForwardVel, 0, -1.0f)) o->oSubAction = 2; func_8029F728(); break; case 2: o->oForwardVel = 0.0f; set_obj_animation_and_sound_state(20); if (func_8029F788()) { if (BITS) sp34 = 10; else sp34 = 30; if (o->oBowserUnkF8 > sp34) o->oAction = 0; o->oBowserUnkF8++; } func_8029F728(); break; } if (o->oMoveFlags & 0x400) o->oAction = 10; } s32 func_802B5588(void) { struct Object *mine; f32 sp18; mine = obj_find_nearest_object_with_behavior(bhvBowserBomb, &sp18); if (mine != NULL && sp18 < 800.0f) { mine->oInteractStatus |= INTERACT_MR_BLIZZARD; return 1; } return 0; } void ActionBowser1(void) // unused? { UNUSED s32 unused; if (o->oTimer < 2) o->oBowserUnkF8 = 0; if (o->oSubAction == 0) { set_obj_animation_and_sound_state(2); func_802B392C(&o->oBowserUnkF8); if (o->oMoveFlags & 2) { o->oForwardVel = 0.0f; o->oSubAction++; } } else if (func_802A4AB0(0)) o->oAction = 0; if (func_802B5588()) { o->oHealth--; if (o->oHealth <= 0) o->oAction = 4; else o->oAction = 12; } } void func_802B5738(void) { o->oUnk1AC_S16 = 0; if (o->oOpacity == 0) { o->oForwardVel = 0.0f; o->oVelY = 0.0f; o->oPosY = o->oHomeY - 1000.0f; } } void ActionBowser2(void) { s32 sp2C; UNUSED s32 unused; s8 *sp24 = (s8 *) o->oFloor; if (sp24 != NULL && sp24[4] & 1) sp2C = 1; else sp2C = 0; o->oBowserUnkF4 |= 0x10000; switch (o->oSubAction) { case 0: if (o->oTimer == 0) { o->oFaceAnglePitch = 0; o->oFaceAngleRoll = 0; } //? missing else o->oFaceAnglePitch += 0x800; o->oFaceAngleRoll += 0x800; if (!(o->oFaceAnglePitch & 0xFFFF)) o->oSubAction++; func_802B5738(); break; case 1: set_obj_animation_and_sound_state(9); if (obj_check_anim_frame(11)) { o->oMoveAngleYaw = o->oBowserAngleToCentre; o->oVelY = 150.0f; o->oUnk1AC_S16 = 0xFF; o->oBowserUnkF8 = 0; o->oSubAction++; } else func_802B5738(); break; case 2: if (o->oPosY > o->oHomeY) { o->oDragStrength = 0.0f; if (o->oBowserDistToCentre < 2500.0f) { if (absf(o->oFloorHeight - o->oHomeY) < 100.0f) approach_f32_signed(&o->oForwardVel, 0, -5.0f); else obj_obj_forward_vel_approach_upward(150.0f, 2.0f); } else obj_obj_forward_vel_approach_upward(150.0f, 2.0f); } if (func_802B4A94()) { o->oDragStrength = 10.0f; o->oSubAction++; if (sp2C == 0) func_802B38B4(); else if (BITS) o->oAction = 13; if (BITFS) o->oAction = 19; } #ifndef VERSION_JP func_u_802B4AF4(); #else if (o->oVelY < 0.0f && o->oPosY < o->oHomeY - 300.0f) { o->oPosZ = 0.0f, o->oPosX = o->oPosZ; o->oPosY = o->oHomeY + 2000.0f; o->oVelY = 0.0f; } #endif break; case 3: if (func_8029F788()) { o->oAction = 0; o->oBowserUnkF4 &= ~0x10000; func_8029F728(); } break; } print_debug_bottom_up("sp %d", o->oForwardVel); } void ActionBowser3(void) { if (item_in_array(o->oTimer, D_8032F514)) PlaySound2(SOUND_OBJECT_BOWSERWALK); if (func_802A4AB0(10)) o->oAction = 0; } void func_802B5C78(void) { if (BITS) gSecondCameraFocus = spawn_object(o, MODEL_STAR, &bhvGrandStar); else { gSecondCameraFocus = spawn_object(o, MODEL_BOWSER_KEY, &bhvBowserKey); PlaySound2(SOUND_CH8_UNK61); } gSecondCameraFocus->oAngleVelYaw = o->oAngleVelYaw; } void func_802B5D18(void) { set_obj_animation_and_sound_state(16); if (BITS) o->oForwardVel = -400.0f; else o->oForwardVel = -200.0f; o->oVelY = 100.0f; o->oMoveAngleYaw = o->oBowserAngleToCentre + 0x8000; o->oBowserUnkF8 = 0; o->oSubAction++; } void func_802B5DD8(void) { o->oBowserEyesShut = 1; func_802B392C(&o->oBowserUnkF8); if (o->oMoveFlags & 1) PlaySound2(SOUND_OBJECT_BOWSERWALK); if (o->oMoveFlags & 2) { o->oForwardVel = 0.0f; o->oSubAction++; } } s32 func_802B5E7C(void) { s32 ret = 0; obj_become_intangible(); if (func_802A4AB0(17) && o->oDistanceToMario < 700.0f && abs_angle_diff(gMarioObject->oMoveAngleYaw, o->oAngleToMario) > 0x6000) ret = 1; func_8029F728(); o->oBowserUnkF8 = 0; return ret; } s32 func_802B5F20(void) { s32 ret = 0; if (o->header.gfx.scale[0] < 0.8) o->oAngleVelYaw += 0x80; if (o->header.gfx.scale[0] > 0.2) { o->header.gfx.scale[0] = o->header.gfx.scale[0] - 0.02; o->header.gfx.scale[2] = o->header.gfx.scale[2] - 0.02; } else { o->header.gfx.scale[1] = o->header.gfx.scale[1] - 0.01; o->oVelY = 20.0f; o->oGravity = 0.0f; } if (o->header.gfx.scale[1] < 0.5) ret = 1; o->oMoveAngleYaw += o->oAngleVelYaw; if (o->oOpacity >= 3) o->oOpacity -= 2; return ret; } void func_802B60B8(void) { obj_scale(0); o->oForwardVel = 0.0f; o->oVelY = 0.0f; o->oGravity = 0.0f; } s32 func_802B6120(void) { s32 ret = 0; if (o->oBowserUnkF8 < 2) { if (o->oBowserUnkF8 == 0) { func_8031FFB4(0, 60, 40); o->oBowserUnkF8++; } if (obj_update_dialog_unk1(2, 18, D_8032F518[o->oBehParams2ndByte], 0)) { o->oBowserUnkF8++; PlaySound2(SOUND_CH8_UNK60); func_80320040(0, 60); func_8031F7CC(0, 1); } } else if (func_802B5F20()) { func_802B60B8(); spawn_triangle_break_particles(20, 116, 1.0f, 0); func_802B5C78(); set_mario_npc_dialog(0); ret = 1; } return ret; } s32 func_802B6254(void) { UNUSED s32 unused; s32 ret = 0; s32 sp1C; if (o->oBowserUnkF8 < 2) { if (gHudDisplay.stars < 120) sp1C = 121; else sp1C = 163; if (o->oBowserUnkF8 == 0) { func_8031FFB4(0, 60, 40); o->oBowserUnkF8++; } if (obj_update_dialog_unk1(2, 18, sp1C, 0)) { obj_set_model(MODEL_BOWSER2); func_80320040(0, 60); func_8031F7CC(0, 1); func_802B5C78(); o->oBowserUnkF8++; } } else if (o->oOpacity > 4) o->oOpacity -= 4; else { func_802B60B8(); ret = 1; } return ret; } void ActionBowser4(void) { switch (o->oSubAction) { case 0: func_802B5D18(); break; case 1: func_802B5DD8(); break; case 2: if (func_802B5E7C()) { o->oBowserUnkF8 = 0; if (BITS) o->oSubAction = 10; else { o->activeFlags |= 0x80; o->oSubAction++; } } break; case 3: if (func_802B6120()) o->oSubAction++; break; case 4: break; case 10: if (func_802B6254()) o->oSubAction++; break; case 11: break; } } void func_802B64E8(struct Object *bowser, s16 a1) { s16 angle; angle = o->oBowserAngleToCentre + 0x8000; bowser->oAngleVelPitch = coss(angle) * a1; bowser->oAngleVelRoll = -sins(angle) * a1; } void ActionBowser19(void) { struct Object *platform = obj_nearest_object_with_behavior(bhvTiltingBowserLavaPlatform); UNUSED s16 sp2A = o->oBowserAngleToCentre + 0x8000; s16 sp28; UNUSED s32 unused; s32 i; s32 sp1C; if (platform == NULL) o->oAction = 0; else { i = 0; sp1C = 1; while (D_8032F520[i][2] != 0) { if (o->oTimer < D_8032F520[i][2]) { sp28 = D_8032F520[i][1]; if (D_8032F520[i][0] > 0) sp28 = (D_8032F520[i][2] - o->oTimer - 1) * sp28; else sp28 = (o->oTimer - D_8032F520[i - 1][2]) * sp28; func_802B64E8(platform, sp28); if (sp28 != 0) play_sound(SOUND_ENVIRONMENT_UNKNOWN4, platform->header.gfx.cameraToObject); sp1C = 0; break; } i++; } if (sp1C) { o->oAction = 0; platform->oAngleVelPitch = 0; platform->oAngleVelRoll = 0; platform->oFaceAnglePitch = 0; platform->oFaceAngleRoll = 0; } } func_8029F728(); } s32 func_802B67C4(void) // bowser off stage? { if (o->oAction != 2 && o->oAction != 19) { if (o->oPosY < o->oHomeY - 1000.0f) return 1; if (o->oMoveFlags & 1) { if (o->oFloorType == 1) return 1; if (o->oFloorType == 10) return 1; } } return 0; } void (*sBowserActions[])(void) = { ActionBowser0, ActionBowser1, ActionBowser2, ActionBowser3, ActionBowser4, ActionBowser5, ActionBowser6, ActionBowser7, ActionBowser8, ActionBowser9, ActionBowser10, ActionBowser11, ActionBowser12, ActionBowser13, ActionBowser14, ActionBowser15, ActionBowser16, ActionBowser17, ActionBowser18, ActionBowser19 }; struct SoundState D_8032F5B8[] = { { 0, 0, 0, NO_SOUND }, { 0, 0, 0, NO_SOUND }, { 0, 0, 0, NO_SOUND }, { 0, 0, 0, NO_SOUND }, { 0, 0, 0, NO_SOUND }, { 0, 0, 0, NO_SOUND }, { 0, 0, 0, NO_SOUND }, { 0, 0, 0, NO_SOUND }, { 1, 0, -1, SOUND_OBJECT_BOWSERWALK }, { 1, 0, -1, SOUND_CH9_UNK04 }, { 1, 0, -1, SOUND_CH9_UNK04 }, { 0, 0, 0, NO_SOUND }, { 0, 0, 0, NO_SOUND }, { 1, 20, 40, SOUND_OBJECT_BOWSERWALK }, { 1, 20, -1, SOUND_OBJECT_BOWSERWALK }, { 1, 20, 40, SOUND_OBJECT_BOWSERWALK }, { 1, 0, -1, SOUND_OBJECT_BOWSERTAILPICKUP }, { 1, 0, -1, SOUND_OBJECT_BOWSERDEFEATED }, { 1, 8, -1, SOUND_OBJECT_BOWSERWALK }, { 1, 8, 17, SOUND_OBJECT_BOWSERWALK }, { 1, 8, -10, SOUND_OBJECT_BOWSERWALK }, { 0, 0, 0, NO_SOUND }, { 1, 5, -1, SOUND_OBJECT_FLAMEBLOWN }, { 0, 0, 0, NO_SOUND }, { 0, 0, 0, NO_SOUND }, { 1, 0, -1, SOUND_OBJECT_BOWSERTAILPICKUP }, { 1, 0, -1, SOUND_CH9_UNK04 } }; s8 D_8032F690[4] = { 0, 0, 1, 0 }; s8 D_8032F694[4] = { 1, 1, 3, 0 }; extern u8 bowser_3_seg7_collision_07004B94[]; extern u8 bowser_3_seg7_collision_07004C18[]; extern u8 bowser_3_seg7_collision_07004C9C[]; extern u8 bowser_3_seg7_collision_07004D20[]; extern u8 bowser_3_seg7_collision_07004DA4[]; extern u8 bowser_3_seg7_collision_07004E28[]; extern u8 bowser_3_seg7_collision_07004EAC[]; extern u8 bowser_3_seg7_collision_07004F30[]; extern u8 bowser_3_seg7_collision_07004FB4[]; extern u8 bowser_3_seg7_collision_07005038[]; struct Struct8032F698 D_8032F698[] = { { NULL, 0, 0, 0, 0 }, { bowser_3_seg7_collision_07004B94, -800, -1000, -20992, 0 }, { bowser_3_seg7_collision_07004C18, -1158, 390, -18432, 0 }, { bowser_3_seg7_collision_07004C9C, -1158, 390, -7680, 0 }, { bowser_3_seg7_collision_07004D20, 0, 1240, -6144, 0 }, { bowser_3_seg7_collision_07004DA4, 0, 1240, 6144, 0 }, { bowser_3_seg7_collision_07004E28, 1158, 390, 7680, 0 }, { bowser_3_seg7_collision_07004EAC, 1158, 390, 18432, 0 }, { bowser_3_seg7_collision_07004F30, 800, -1000, 20992, 0 }, { bowser_3_seg7_collision_07004FB4, 800, -1000, -31744, 0 }, { bowser_3_seg7_collision_07005038, -800, -1000, 31744, 0 } }; void func_802B688C(void) { struct Surface *floor; struct Object *platform; UNUSED f32 floorHeight; if ((platform = o->platform) != NULL) apply_platform_displacement(0, platform); o->oBowserUnk10E = 0; obj_update_floor_and_walls(); obj_call_action_function(sBowserActions); obj_move_standard(-78); if (func_802B67C4()) o->oAction = 2; // bowser go home? floorHeight = find_floor(o->oPosX, o->oPosY, o->oPosZ, &floor); if ((floor != NULL) && (floor->object != 0)) o->platform = floor->object; else o->platform = NULL; exec_anim_sound_state(D_8032F5B8); } void func_802B697C(void) { o->oBowserUnkF4 &= ~0x20000; obj_become_intangible(); switch (o->oBowserUnk10E) { case 0: PlaySound2(SOUND_OBJECT_BOWSERTAILPICKUP); func_8029FA5C(3, 1); o->oBowserUnk10E++; break; case 1: if (func_8029F788()) { set_obj_animation_and_sound_state(2); o->oBowserUnk10E++; } break; case 2: break; } o->oMoveFlags = 0; o->oBowserHeldAnglePitch = gMarioObject->oMoveAnglePitch; o->oBowserHeldAngleVelYaw = gMarioObject->oAngleVelYaw; o->oMoveAngleYaw = gMarioObject->oMoveAngleYaw; } void func_802B6AC0(void) { f32 sp1C; o->oBowserUnk10E = 0; obj_get_thrown_or_placed(1.0f, 1.0f, 1); sp1C = o->oBowserHeldAngleVelYaw / 3000.0 * 70.0f; if (sp1C < 0.0f) sp1C = -sp1C; if (sp1C > 90.0f) sp1C *= 2.5; // > 90 => get bigger? o->oForwardVel = coss(o->oBowserHeldAnglePitch) * sp1C; o->oVelY = -sins(o->oBowserHeldAnglePitch) * sp1C; obj_become_intangible(); o->prevObj->oAction = 1; // not sure what prevObj is o->prevObj->oTimer = 0; o->prevObj->oSubAction = 0; o->oTimer = 0; o->oSubAction = 0; } void bhv_bowser_loop(void) { 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); o->oBowserAngleToCentre = atan2s(0.0f - o->oPosZ, 0.0f - o->oPosX); angleToMario = abs_angle_diff(o->oMoveAngleYaw, o->oAngleToMario); angleToCentre = abs_angle_diff(o->oMoveAngleYaw, o->oBowserAngleToCentre); o->oBowserUnkF4 &= ~0xFF; if (angleToMario < 0x2000) o->oBowserUnkF4 |= 2; if (angleToCentre < 0x3800) o->oBowserUnkF4 |= 4; if (o->oBowserDistToCentre < 1000.0f) o->oBowserUnkF4 |= 0x10; if (o->oDistanceToMario < 850.0f) o->oBowserUnkF4 |= 8; switch (o->oHeldState) { case HELD_FREE: func_802B688C(); break; case HELD_HELD: func_802B697C(); break; case HELD_THROWN: func_802B6AC0(); break; case HELD_DROPPED: func_802B6AC0(); break; } obj_align_gfx_with_floor(); if (o->oAction != 4) if (o->oUnk1AC_S16 != o->oOpacity) { if (o->oUnk1AC_S16 > o->oOpacity) { o->oOpacity += 20; if (o->oOpacity >= 0x100) o->oOpacity = 0xFF; } else { o->oOpacity -= 20; if (o->oOpacity < 0) o->oOpacity = 0; } } } void bhv_bowser_init(void) { s32 level; // 0 is dw, 1 is fs, 2 is sky o->oBowserUnk110 = 1; o->oOpacity = 0xFF; o->oUnk1AC_S16 = 0xFF; if (gCurrLevelNum == LEVEL_BOWSER_2) level = 1; else if (gCurrLevelNum == LEVEL_BOWSER_3) level = 2; else level = 0; o->oBehParams2ndByte = level; o->oBowserUnk1B2 = D_8032F690[level]; o->oHealth = D_8032F694[level]; func_802A11B4(o, 4); o->oAction = 5; o->oBowserUnk1AE = 0; o->oBowserEyesShut = 0; } #undef BITDW #undef BITFS #undef BITS Gfx *Geo18_802B798C(s32 run, UNUSED struct GraphNode *node, Mat4 mtx) { Mat4 sp20; struct Object *sp1C; if (run == TRUE) { sp1C = (struct Object *) gCurGraphNodeObject; if (sp1C->prevObj != NULL) { func_8029D704(sp20, mtx, gCurGraphNodeCamera->matrixPtr); func_8029D558(sp20, sp1C->prevObj); func_8029EA0C(sp1C->prevObj); } } return NULL; } void func_802B70C8(struct Object *a0, struct GraphNodeSwitchCase *switchCase) { s32 sp1C; s16 sp1A; sp1A = abs_angle_diff(a0->oMoveAngleYaw, a0->oAngleToMario); sp1C = switchCase->selectedCase; switch (sp1C) { case 0: if (sp1A > 0x2000) { if (a0->oAngleVelYaw > 0) switchCase->selectedCase = 5; if (a0->oAngleVelYaw < 0) switchCase->selectedCase = 3; } if (a0->oBowserUnk1AE > 50) switchCase->selectedCase = 1; break; case 1: if (a0->oBowserUnk1AE > 2) switchCase->selectedCase = 2; break; case 2: if (a0->oBowserUnk1AE > 2) switchCase->selectedCase = 9; break; case 9: if (a0->oBowserUnk1AE > 2) switchCase->selectedCase = 0; break; case 5: if (a0->oBowserUnk1AE > 2) { switchCase->selectedCase = 6; if (a0->oAngleVelYaw <= 0) switchCase->selectedCase = 0; } break; case 6: if (a0->oAngleVelYaw <= 0) switchCase->selectedCase = 5; break; case 3: if (a0->oBowserUnk1AE > 2) { switchCase->selectedCase = 4; if (a0->oAngleVelYaw >= 0) switchCase->selectedCase = 0; } break; case 4: if (a0->oAngleVelYaw >= 0) switchCase->selectedCase = 3; break; default: switchCase->selectedCase = 0; } if (switchCase->selectedCase != sp1C) a0->oBowserUnk1AE = -1; } /** Geo switch for controlling the state of bowser's eye direction and open/closed * state. Checks whether oBowserEyesShut is TRUE and closes eyes if so and processes * direction otherwise. */ s32 geo_switch_bowser_eyes(s32 run, struct GraphNode *node, UNUSED Mat4 *mtx) { UNUSED s16 sp36; UNUSED s32 unused; struct Object *obj = (struct Object *) gCurGraphNodeObject; struct GraphNodeSwitchCase *switchCase = (struct GraphNodeSwitchCase *) node; if (run == TRUE) { if (gCurGraphNodeHeldObject != NULL) obj = (struct Object *) gCurGraphNodeHeldObject->objNode; switch (sp36 = obj->oBowserEyesShut) { case 0: // eyes open, handle eye looking direction func_802B70C8(obj, switchCase); break; case 1: // eyes closed, blinking switchCase->selectedCase = 2; break; } obj->oBowserUnk1AE++; } return 0; } Gfx *Geo18_802B7D44(s32 a0, struct GraphNode *node, UNUSED s32 a2) { Gfx *sp2C = NULL; Gfx *sp28; struct Object *sp24; struct GraphNodeGenerated *sp20; if (a0 == 1) { sp24 = (struct Object *) gCurGraphNodeObject; sp20 = (struct GraphNodeGenerated *) node; if (gCurGraphNodeHeldObject != 0) sp24 = (struct Object *) gCurGraphNodeHeldObject->objNode; if (sp24->oOpacity == 0xFF) sp20->fnNode.node.flags = (sp20->fnNode.node.flags & 0xFF) | 0x100; else sp20->fnNode.node.flags = (sp20->fnNode.node.flags & 0xFF) | (0x100 | 0x400); sp28 = sp2C = alloc_display_list(16); if (sp24->oBowserUnk1B2 != 0) { gSPClearGeometryMode(sp28++, G_LIGHTING); } gSPEndDisplayList(sp28); } return sp2C; } void ActionFallingBowserPlatform0(void) { o->oPlatformUnkF8 = obj_nearest_object_with_behavior(&bhvBowser); set_object_collision_data(o, D_8032F698[o->oBehParams2ndByte].unk0); if (o->oBowserUnkF8 != 0) o->oAction = 1; } void ActionFallingBowserPlatform1(void) { UNUSED s32 unused; struct Object *sp0 = o->oPlatformUnkF8; if (sp0->platform == o) if (sp0->oAction == 13 && sp0->oUnknownUnkF4_S32 & 0x10000) o->oAction = 2; if (sp0->oHealth == 1 && (sp0->oAction == 3 || sp0->oHeldState != HELD_FREE)) o->oSubAction = 1; if (o->oSubAction == 0) o->oPlatformUnkFC = 0; else { if ((gDebugInfo[4][6] + 20) * (o->oBehParams2ndByte - 1) < o->oPlatformUnkFC) o->oAction = 2; o->oPlatformUnkFC++; } } void ActionFallingBowserPlatform2(void) { Vec3f sp24; s16 sp22; f32 sp1C; UNUSED struct Object *sp18 = o->oPlatformUnkF8; if (o->oTimer == 0 || o->oTimer == 22) PlaySound2(SOUND_GENERAL_BOWSERPLATFORM_2); if (o->oTimer < 22) { set_camera_shake_2(SHAKE_2_FALLING_BITS_PLAT); o->oVelY = 8.0f; o->oGravity = 0.0f; } else o->oGravity = -4.0f; if ((o->oTimer & 1) == 0 && o->oTimer < 14) { sp22 = D_8032F698[o->oBehParams2ndByte].unk3 + (gDebugInfo[4][1] << 8); sp1C = -(o->oTimer / 2) * 290 + 1740; func_802B8F7C(sp24, &o->oPosX); o->oPosX = D_8032F698[o->oBehParams2ndByte].unk1 + sins(sp22 + 5296) * sp1C; o->oPosZ = D_8032F698[o->oBehParams2ndByte].unk2 + coss(sp22 + 5296) * sp1C; o->oPosY = 307.0f; func_802AA618(4, 0, 100.0f); o->oPosX = D_8032F698[o->oBehParams2ndByte].unk1 + sins(sp22 - 5296) * sp1C; o->oPosZ = D_8032F698[o->oBehParams2ndByte].unk2 + coss(sp22 - 5296) * sp1C; func_802AA618(4, 0, 100); func_802B8F7C(&o->oPosX, sp24); } obj_move_using_fvel_and_gravity(); if (o->oTimer > 300) mark_object_for_deletion(o); } void (*sFallingBowserPlatformActions[])(void) = { ActionFallingBowserPlatform0, ActionFallingBowserPlatform1, ActionFallingBowserPlatform2 }; struct ObjectHitbox sGrowingBowserFlameHitbox = { /* interactType: */ INTERACT_FLAME, /* downOffset: */ 20, /* damageOrCoinValue: */ 1, /* health: */ 0, /* numLootCoins: */ 0, /* radius: */ 10, /* height: */ 40, /* hurtboxRadius: */ 0, /* hurtboxHeight: */ 0, }; struct ObjectHitbox sBowserFlameHitbox = { /* interactType: */ INTERACT_FLAME, /* downOffset: */ 0, /* damageOrCoinValue: */ 1, /* health: */ 0, /* numLootCoins: */ 0, /* radius: */ 10, /* height: */ 40, /* hurtboxRadius: */ 0, /* hurtboxHeight: */ 0, }; f32 D_8032F748[] = { -8.0f, -6.0f, -3.0f }; void bhv_falling_bowser_platform_loop(void) { obj_call_action_function(sFallingBowserPlatformActions); } void func_802B7A58(void) { mark_object_for_deletion(o); spawn_object_with_scale(o, MODEL_NONE, &bhvBlackSmokeUpward, 1.0f); if (RandomFloat() < 0.1) spawn_object(o, MODEL_YELLOW_COIN, &bhvTemporaryYellowCoin); } s32 func_802B7ADC(s32 a0) { if (a0 < o->oTimer) return 1; if (o->oFloorType == 1) return 1; if (o->oFloorType == 10) return 1; return 0; } void bhv_flame_bowser_init(void) { o->oAnimState = (s32)(RandomFloat() * 10.0f); o->oMoveAngleYaw = RandomU16(); if (RandomFloat() < 0.2) o->oVelY = 80.0f; else o->oVelY = 20.0f; o->oForwardVel = 10.0f; o->oGravity = -1.0f; o->oFlameUnkF4 = RandomFloat() + 1.0f; } void bhv_flame_large_burning_out_init(void) { o->oAnimState = (s32)(RandomFloat() * 10.0f); o->oMoveAngleYaw = RandomU16(); o->oVelY = 10.0f; o->oForwardVel = 0.0f; o->oFlameUnkF4 = 7.0f; } void func_802B7CFC(void) { s32 sp4; sp4 = ((o->oFlameUnkF8 + gGlobalTimer) & 0x3F) << 10; o->oPosX += sins(o->oMoveAngleYaw) * sins(sp4) * 4.0f; o->oPosZ += coss(o->oMoveAngleYaw) * sins(sp4) * 4.0f; } void bhv_flame_bowser_loop(void) { obj_update_floor_and_walls(); obj_move_standard(78); if (o->oVelY < -4.0f) o->oVelY = -4.0f; if (o->oAction == 0) { obj_become_intangible(); func_802B7CFC(); if (o->oMoveFlags & 1) { o->oAction++; if (obj_has_behavior(bhvFlameLargeBurningOut)) o->oFlameUnkF4 = 8.0f; else o->oFlameUnkF4 = RandomFloat() * 2 + 6.0f; o->oForwardVel = 0; o->oVelY = 0; o->oGravity = 0; } } else { obj_become_tangible(); if (o->oTimer > o->oFlameUnkF4 * 10 + 5.0f) { o->oFlameUnkF4 -= 0.15; if (o->oFlameUnkF4 <= 0.0f) func_802B7A58(); } } obj_scale(o->oFlameUnkF4); o->oGraphYOffset = o->header.gfx.scale[1] * 14.0f; set_object_hitbox(o, &sBowserFlameHitbox); } void bhv_flame_moving_forward_growing_init(void) { o->oForwardVel = 30.0f; translate_object_xz_random(o, 80.0f); o->oAnimState = (s32)(RandomFloat() * 10.0f); o->oFlameUnkF4 = 3.0f; } void bhv_flame_moving_forward_growing_loop(void) { UNUSED s32 unused; UNUSED struct Object *sp18; set_object_hitbox(o, &sGrowingBowserFlameHitbox); o->oFlameUnkF4 = o->oFlameUnkF4 + 0.5; obj_scale(o->oFlameUnkF4); if (o->oMoveAnglePitch > 0x800) o->oMoveAnglePitch -= 0x200; func_802A2A38(); obj_update_floor_height(); if (o->oFlameUnkF4 > 30.0f) mark_object_for_deletion(o); if (o->oPosY < o->oFloorHeight) { o->oPosY = o->oFloorHeight; sp18 = spawn_object(o, MODEL_RED_FLAME, &bhvFlameBowser); mark_object_for_deletion(o); } } void bhv_flame_floating_landing_init(void) { o->oAnimState = (s32)(RandomFloat() * 10.0f); o->oMoveAngleYaw = RandomU16(); if (o->oBehParams2ndByte != 0) o->oForwardVel = RandomFloat() * 5.0f; else o->oForwardVel = RandomFloat() * 70.0f; o->oVelY = RandomFloat() * 20.0f; o->oGravity = -1.0f; o->oFlameUnkF8 = RandomFloat() * 64.0f; } void bhv_flame_floating_landing_loop(void) { UNUSED s32 unused; obj_update_floor_and_walls(); obj_move_standard(0x4e); func_802B7CFC(); if (func_802B7ADC(900)) mark_object_for_deletion(o); if (o->oVelY < D_8032F748[o->oBehParams2ndByte]) o->oVelY = D_8032F748[o->oBehParams2ndByte]; if (o->oMoveFlags & 1) { if (o->oBehParams2ndByte == 0) spawn_object(o, MODEL_RED_FLAME, &bhvFlameLargeBurningOut); else spawn_object(o, MODEL_NONE, &bhvBlueFlamesGroup); //? wonder if they meant MODEL_BLUE_FLAME? mark_object_for_deletion(o); } o->oGraphYOffset = o->header.gfx.scale[1] * 14.0f; } void bhv_blue_bowser_flame_init(void) { translate_object_xz_random(o, 80.0f); o->oAnimState = (s32)(RandomFloat() * 10.0f); o->oVelY = 7.0f; o->oForwardVel = 35.0f; o->oFlameUnkF4 = 3.0f; o->oFlameUnkFC = RandomFloat() * 0.5; o->oGravity = 1.0f; o->oFlameUnkF8 = (s32)(RandomFloat() * 64.0f); } void bhv_blue_bowser_flame_loop(void) { s32 i; set_object_hitbox(o, &sGrowingBowserFlameHitbox); if (o->oFlameUnkF4 < 16.0f) o->oFlameUnkF4 = o->oFlameUnkF4 + 0.5; obj_scale(o->oFlameUnkF4); obj_update_floor_and_walls(); obj_move_standard(0x4e); if (o->oTimer > 0x14) { if (o->oBehParams2ndByte == 0) for (i = 0; i < 3; i++) spawn_object_relative_with_scale(0, 0, 0, 0, 5.0f, o, MODEL_RED_FLAME, &bhvFlameFloatingLanding); else { spawn_object_relative_with_scale(1, 0, 0, 0, 8.0f, o, MODEL_BLUE_FLAME, &bhvFlameFloatingLanding); spawn_object_relative_with_scale(2, 0, 0, 0, 8.0f, o, MODEL_BLUE_FLAME, &bhvFlameFloatingLanding); } mark_object_for_deletion(o); } } void bhv_flame_bouncing_init(void) { o->oAnimState = (s32)(RandomFloat() * 10.0f); o->oVelY = 30.0f; o->oForwardVel = 20.0f; o->oFlameUnkF4 = o->header.gfx.scale[0]; o->oFlameUnkF8 = (s32)(RandomFloat() * 64.0f); } void bhv_flame_bouncing_loop(void) { struct Object *sp1C; if (o->oTimer == 0) o->oFlameUnk100 = obj_nearest_object_with_behavior(&bhvBowser); sp1C = o->oFlameUnk100; o->oForwardVel = 15.0f; o->oBounce = -1.0f; obj_scale(o->oFlameUnkF4); set_object_hitbox(o, &sGrowingBowserFlameHitbox); obj_update_floor_and_walls(); obj_move_standard(78); if (func_802B7ADC(300)) mark_object_for_deletion(o); if (sp1C != NULL) if (sp1C->oHeldState == 0) if (lateral_dist_between_objects(o, sp1C) < 300.0f) mark_object_for_deletion(o); } void bhv_blue_flames_group_loop(void) { struct Object *flame; s32 i; if (o->oTimer == 0) { o->oMoveAngleYaw = angle_to_object(o, gMarioObject); o->oBlueFlameUnkF8 = 5.0f; } if (o->oTimer < 16) { if ((o->oTimer & 1) == 0) { for (i = 0; i < 3; i++) { flame = spawn_object(o, MODEL_BLUE_FLAME, bhvFlameBouncing); flame->oMoveAngleYaw += i * 0x5555; flame->header.gfx.scale[0] = o->oBlueFlameUnkF8; } o->oBlueFlameUnkF8 -= 0.5; } } else mark_object_for_deletion(o); }