sm64

A Super Mario 64 decompilation
Log | Files | Refs | README | LICENSE

bowser_flame.inc.c (8026B)


      1 // bowser_flame.inc.c
      2 
      3 struct ObjectHitbox sGrowingBowserFlameHitbox = {
      4     /* interactType:      */ INTERACT_FLAME,
      5     /* downOffset:        */ 20,
      6     /* damageOrCoinValue: */ 1,
      7     /* health:            */ 0,
      8     /* numLootCoins:      */ 0,
      9     /* radius:            */ 10,
     10     /* height:            */ 40,
     11     /* hurtboxRadius:     */ 0,
     12     /* hurtboxHeight:     */ 0,
     13 };
     14 
     15 struct ObjectHitbox sBowserFlameHitbox = {
     16     /* interactType:      */ INTERACT_FLAME,
     17     /* downOffset:        */ 0,
     18     /* damageOrCoinValue: */ 1,
     19     /* health:            */ 0,
     20     /* numLootCoins:      */ 0,
     21     /* radius:            */ 10,
     22     /* height:            */ 40,
     23     /* hurtboxRadius:     */ 0,
     24     /* hurtboxHeight:     */ 0,
     25 };
     26 
     27 void bowser_flame_despawn(void) {
     28     obj_mark_for_deletion(o);
     29     spawn_object_with_scale(o, MODEL_NONE, bhvBlackSmokeUpward, 1.0f);
     30     if (random_float() < 0.1) {
     31         spawn_object(o, MODEL_YELLOW_COIN, bhvTemporaryYellowCoin);
     32     }
     33 }
     34 
     35 s32 bowser_flame_should_despawn(s32 maxTime) {
     36     if (maxTime < o->oTimer) {
     37         return TRUE;
     38     }
     39 
     40     // Flames should despawn if they fall off the arena.
     41     if (o->oFloorType == SURFACE_BURNING) {
     42         return TRUE;
     43     }
     44     if (o->oFloorType == SURFACE_DEATH_PLANE) {
     45         return TRUE;
     46     }
     47 
     48     return FALSE;
     49 }
     50 
     51 void bhv_flame_bowser_init(void) {
     52     o->oAnimState = (s32)(random_float() * 10.0f);
     53     o->oMoveAngleYaw = random_u16();
     54     o->oVelY = random_float() < 0.2 ? 80.0f : 20.0f;
     55     o->oForwardVel = 10.0f;
     56     o->oGravity = -1.0f;
     57     o->oFlameScale = random_float() + 1.0f;
     58 }
     59 
     60 void bhv_flame_large_burning_out_init(void) {
     61     o->oAnimState = (s32)(random_float() * 10.0f);
     62     o->oMoveAngleYaw = random_u16();
     63     o->oVelY = 10.0f;
     64     o->oForwardVel = 0.0f;
     65     o->oFlameScale = 7.0f;
     66 }
     67 
     68 void bowser_flame_move(void) {
     69     s32 timer = ((o->oFlameSpeedTimerOffset + gGlobalTimer) & 0x3F) << 10;
     70     o->oPosX += sins(o->oMoveAngleYaw) * sins(timer) * 4.0f;
     71     o->oPosZ += coss(o->oMoveAngleYaw) * sins(timer) * 4.0f;
     72 }
     73 
     74 void bhv_flame_bowser_loop(void) {
     75     cur_obj_update_floor_and_walls();
     76     cur_obj_move_standard(78);
     77 
     78     if (o->oVelY < -4.0f) {
     79         o->oVelY = -4.0f;
     80     }
     81 
     82     if (o->oAction == 0) {
     83         cur_obj_become_intangible();
     84         bowser_flame_move();
     85 
     86         if (o->oMoveFlags & OBJ_MOVE_LANDED) {
     87             o->oAction++;
     88             if (cur_obj_has_behavior(bhvFlameLargeBurningOut)) {
     89                 o->oFlameScale = 8.0f;
     90             } else {
     91                 o->oFlameScale = random_float() * 2 + 6.0f;
     92             }
     93             o->oForwardVel = 0;
     94             o->oVelY = 0;
     95             o->oGravity = 0;
     96         }
     97     } else {
     98         cur_obj_become_tangible();
     99 
    100         if (o->oTimer > o->oFlameScale * 10 + 5.0f) {
    101             o->oFlameScale -= 0.15;
    102             if (o->oFlameScale <= 0) {
    103                 bowser_flame_despawn();
    104             }
    105         }
    106     }
    107 
    108     cur_obj_scale(o->oFlameScale);
    109     o->oGraphYOffset = o->header.gfx.scale[1] * 14.0f;
    110     obj_set_hitbox(o, &sBowserFlameHitbox);
    111 }
    112 
    113 void bhv_flame_moving_forward_growing_init(void) {
    114     o->oForwardVel = 30.0f;
    115     obj_translate_xz_random(o, 80.0f);
    116     o->oAnimState = (s32)(random_float() * 10.0f);
    117     o->oFlameScale = 3.0f;
    118 }
    119 
    120 void bhv_flame_moving_forward_growing_loop(void) {
    121     UNUSED u8 filler[4];
    122     UNUSED struct Object *flame;
    123 
    124     obj_set_hitbox(o, &sGrowingBowserFlameHitbox);
    125     o->oFlameScale = o->oFlameScale + 0.5;
    126     cur_obj_scale(o->oFlameScale);
    127 
    128     if (o->oMoveAnglePitch > 0x800) {
    129         o->oMoveAnglePitch -= 0x200;
    130     }
    131 
    132     cur_obj_set_pos_via_transform();
    133     cur_obj_update_floor_height();
    134 
    135     if (o->oFlameScale > 30.0f) {
    136         obj_mark_for_deletion(o);
    137     }
    138 
    139     if (o->oPosY < o->oFloorHeight) {
    140         o->oPosY = o->oFloorHeight;
    141         flame = spawn_object(o, MODEL_RED_FLAME, bhvFlameBowser);
    142         obj_mark_for_deletion(o);
    143     }
    144 }
    145 
    146 void bhv_flame_floating_landing_init(void) {
    147     o->oAnimState = (s32)(random_float() * 10.0f);
    148     o->oMoveAngleYaw = random_u16();
    149     if (o->oBhvParams2ndByte != 0) {
    150         o->oForwardVel = random_float() * 5.0f;
    151     } else {
    152         o->oForwardVel = random_float() * 70.0f;
    153     }
    154     o->oVelY = random_float() * 20.0f;
    155     o->oGravity = -1.0f;
    156     o->oFlameSpeedTimerOffset = random_float() * 64.0f;
    157 }
    158 
    159 f32 sFlameFloatingYLimit[] = { -8.0f, -6.0f, -3.0f };
    160 
    161 void bhv_flame_floating_landing_loop(void) {
    162     UNUSED u8 filler[4];
    163 
    164     cur_obj_update_floor_and_walls();
    165     cur_obj_move_standard(78);
    166     bowser_flame_move();
    167 
    168     if (bowser_flame_should_despawn(900)) {
    169         obj_mark_for_deletion(o);
    170     }
    171 
    172     if (o->oVelY < sFlameFloatingYLimit[o->oBhvParams2ndByte]) {
    173         o->oVelY = sFlameFloatingYLimit[o->oBhvParams2ndByte];
    174     }
    175 
    176     if (o->oMoveFlags & OBJ_MOVE_LANDED) {
    177         if (o->oBhvParams2ndByte == 0) {
    178             spawn_object(o, MODEL_RED_FLAME, bhvFlameLargeBurningOut);
    179         } else {
    180             spawn_object(o, MODEL_NONE, bhvBlueFlamesGroup); //? wonder if they meant MODEL_BLUE_FLAME?
    181         }
    182         obj_mark_for_deletion(o);
    183     }
    184 
    185     o->oGraphYOffset = o->header.gfx.scale[1] * 14.0f;
    186 }
    187 
    188 void bhv_blue_bowser_flame_init(void) {
    189     obj_translate_xz_random(o, 80.0f);
    190     o->oAnimState = (s32)(random_float() * 10.0f);
    191     o->oVelY = 7.0f;
    192     o->oForwardVel = 35.0f;
    193     o->oFlameScale = 3.0f;
    194     o->oFlameUnusedRand = random_float() * 0.5;
    195     o->oGravity = 1.0f;
    196     o->oFlameSpeedTimerOffset = (s32)(random_float() * 64.0f);
    197 }
    198 
    199 void bhv_blue_bowser_flame_loop(void) {
    200     s32 i;
    201 
    202     obj_set_hitbox(o, &sGrowingBowserFlameHitbox);
    203 
    204     if (o->oFlameScale < 16.0f) {
    205         o->oFlameScale = o->oFlameScale + 0.5;
    206     }
    207 
    208     cur_obj_scale(o->oFlameScale);
    209     cur_obj_update_floor_and_walls();
    210     cur_obj_move_standard(78);
    211 
    212     if (o->oTimer > 20) {
    213         if (o->oBhvParams2ndByte == 0) {
    214             for (i = 0; i < 3; i++) {
    215                 spawn_object_relative_with_scale(0, 0, 0, 0, 5.0f, o, MODEL_RED_FLAME,
    216                                                  bhvFlameFloatingLanding);
    217             }
    218         } else {
    219             spawn_object_relative_with_scale(1, 0, 0, 0, 8.0f, o, MODEL_BLUE_FLAME,
    220                                              bhvFlameFloatingLanding);
    221             spawn_object_relative_with_scale(2, 0, 0, 0, 8.0f, o, MODEL_BLUE_FLAME,
    222                                              bhvFlameFloatingLanding);
    223         }
    224         obj_mark_for_deletion(o);
    225     }
    226 }
    227 
    228 void bhv_flame_bouncing_init(void) {
    229     o->oAnimState = (s32)(random_float() * 10.0f);
    230     o->oVelY = 30.0f;
    231     o->oForwardVel = 20.0f;
    232     o->oFlameScale = o->header.gfx.scale[0];
    233     o->oFlameSpeedTimerOffset = (s32)(random_float() * 64.0f);
    234 }
    235 
    236 void bhv_flame_bouncing_loop(void) {
    237     struct Object *bowser;
    238 
    239     if (o->oTimer == 0) {
    240         o->oFlameBowser = cur_obj_nearest_object_with_behavior(bhvBowser);
    241     }
    242 
    243     bowser = o->oFlameBowser;
    244     o->oForwardVel = 15.0f;
    245     o->oBounciness = -1.0f;
    246     cur_obj_scale(o->oFlameScale);
    247     obj_set_hitbox(o, &sGrowingBowserFlameHitbox);
    248     cur_obj_update_floor_and_walls();
    249     cur_obj_move_standard(78);
    250 
    251     if (bowser_flame_should_despawn(300)) {
    252         obj_mark_for_deletion(o);
    253     }
    254 
    255     if (bowser != NULL) {
    256         if (bowser->oHeldState == HELD_FREE) {
    257             if (lateral_dist_between_objects(o, bowser) < 300.0f) {
    258                 obj_mark_for_deletion(o);
    259             }
    260         }
    261     }
    262 }
    263 
    264 void bhv_blue_flames_group_loop(void) {
    265     struct Object *flame;
    266     s32 i;
    267 
    268     if (o->oTimer == 0) {
    269         o->oMoveAngleYaw = obj_angle_to_object(o, gMarioObject);
    270         o->oBlueFlameNextScale = 5.0f;
    271     }
    272 
    273     if (o->oTimer < 16) {
    274         if (!(o->oTimer & 1)) {
    275             for (i = 0; i < 3; i++) {
    276                 flame = spawn_object(o, MODEL_BLUE_FLAME, bhvFlameBouncing);
    277                 flame->oMoveAngleYaw += i * 0x5555;
    278                 flame->header.gfx.scale[0] = o->oBlueFlameNextScale;
    279             }
    280             o->oBlueFlameNextScale -= 0.5;
    281         }
    282     } else {
    283         obj_mark_for_deletion(o);
    284     }
    285 }