sm64

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

fire_piranha_plant.inc.c (4921B)


      1 // fire_piranha_plant.inc.c
      2 
      3 struct ObjectHitbox sFirePiranhaPlantHitbox = {
      4     /* interactType:      */ INTERACT_BOUNCE_TOP,
      5     /* downOffset:        */ 0,
      6     /* damageOrCoinValue: */ 2,
      7     /* health:            */ 0,
      8     /* numLootCoins:      */ 1,
      9     /* radius:            */ 80,
     10     /* height:            */ 160,
     11     /* hurtboxRadius:     */ 50,
     12     /* hurtboxHeight:     */ 150,
     13 };
     14 
     15 f32 D_80331B5C[] = {
     16     0.5f,
     17     2.0f,
     18 };
     19 
     20 struct ObjectHitbox sPiranhaPlantFireHitbox = {
     21     /* interactType:      */ INTERACT_FLAME,
     22     /* downOffset:        */ 10,
     23     /* damageOrCoinValue: */ 0,
     24     /* health:            */ 0,
     25     /* numLootCoins:      */ 0,
     26     /* radius:            */ 10,
     27     /* height:            */ 20,
     28     /* hurtboxRadius:     */ 10,
     29     /* hurtboxHeight:     */ 20,
     30 };
     31 
     32 s32 sNumActiveFirePiranhaPlants;
     33 s32 sNumKilledFirePiranhaPlants;
     34 
     35 void bhv_fire_piranha_plant_init(void) {
     36     o->oFirePiranhaPlantNeutralScale = D_80331B5C[(u16)(o->oBhvParams >> 16)];
     37     obj_set_hitbox(o, &sFirePiranhaPlantHitbox);
     38 
     39     if ((u16)(o->oBhvParams >> 16) != 0) {
     40         o->oFlags |= OBJ_FLAG_PERSISTENT_RESPAWN;
     41         o->oHealth = 1;
     42 
     43         if (o->oBhvParams & 0x0000FF00) {
     44             o->oNumLootCoins = 0;
     45         } else {
     46             o->oNumLootCoins = 2;
     47         }
     48     }
     49 
     50     sNumActiveFirePiranhaPlants = sNumKilledFirePiranhaPlants = 0;
     51 }
     52 
     53 static void fire_piranha_plant_act_hide(void) {
     54     if (o->oFirePiranhaPlantDeathSpinTimer != 0) {
     55         o->oMoveAngleYaw += (s32) o->oFirePiranhaPlantDeathSpinVel;
     56         approach_f32_ptr(&o->oFirePiranhaPlantDeathSpinVel, 0.0f, 200.0f);
     57 
     58         if (cur_obj_check_if_near_animation_end()
     59             && --o->oFirePiranhaPlantDeathSpinTimer == 0) {
     60             cur_obj_play_sound_2(SOUND_OBJ_ENEMY_DEFEAT_SHRINK);
     61         }
     62     } else if (approach_f32_ptr(&o->oFirePiranhaPlantScale, 0.0f,
     63                                 0.04f * o->oFirePiranhaPlantNeutralScale)) {
     64         cur_obj_become_intangible();
     65 
     66         if (o->oFirePiranhaPlantActive) {
     67             sNumActiveFirePiranhaPlants--;
     68             o->oFirePiranhaPlantActive = FALSE;
     69 
     70             if ((u16)(o->oBhvParams >> 16) != 0 && o->oHealth == 0) {
     71                 if (++sNumKilledFirePiranhaPlants == 5) {
     72                     spawn_default_star(-6300.0f, -1850.0f, -6300.0f);
     73                 }
     74 
     75                 obj_die_if_health_non_positive();
     76                 set_object_respawn_info_bits(o, 1);
     77             }
     78         } else if (sNumActiveFirePiranhaPlants < 2 && o->oTimer > 100
     79                    && o->oDistanceToMario > 100.0f && o->oDistanceToMario < 800.0f) {
     80             cur_obj_play_sound_2(SOUND_OBJ_PIRANHA_PLANT_APPEAR);
     81 
     82             o->oFirePiranhaPlantActive = TRUE;
     83             sNumActiveFirePiranhaPlants++;
     84 
     85             cur_obj_unhide();
     86             o->oAction = FIRE_PIRANHA_PLANT_ACT_GROW;
     87             o->oMoveAngleYaw = o->oAngleToMario;
     88         } else {
     89             cur_obj_hide();
     90         }
     91     }
     92 
     93     cur_obj_extend_animation_if_at_end();
     94 }
     95 
     96 static void fire_piranha_plant_act_grow(void) {
     97     cur_obj_init_anim_extend(4);
     98 
     99     if (approach_f32_ptr(&o->oFirePiranhaPlantScale, o->oFirePiranhaPlantNeutralScale,
    100                          0.04f * o->oFirePiranhaPlantNeutralScale)) {
    101         if (o->oTimer > 80) {
    102             cur_obj_play_sound_2(SOUND_OBJ_PIRANHA_PLANT_SHRINK);
    103             o->oAction = FIRE_PIRANHA_PLANT_ACT_HIDE;
    104             cur_obj_init_animation_with_sound(0);
    105         } else if (o->oTimer < 50) {
    106             cur_obj_rotate_yaw_toward(o->oAngleToMario, 0x400);
    107         } else if (obj_is_rendering_enabled() && cur_obj_check_anim_frame(56)) {
    108             cur_obj_play_sound_2(SOUND_OBJ_FLAME_BLOWN);
    109             obj_spit_fire(0, (s32)(30.0f * o->oFirePiranhaPlantNeutralScale),
    110                           (s32)(140.0f * o->oFirePiranhaPlantNeutralScale),
    111                           2.5f * o->oFirePiranhaPlantNeutralScale, MODEL_RED_FLAME_SHADOW,
    112                           20.0f, 15.0f, 0x1000);
    113         }
    114     } else if (o->oFirePiranhaPlantScale > o->oFirePiranhaPlantNeutralScale / 2) {
    115         cur_obj_become_tangible();
    116     }
    117 }
    118 
    119 void bhv_fire_piranha_plant_update(void) {
    120     cur_obj_scale(o->oFirePiranhaPlantScale);
    121 
    122     switch (o->oAction) {
    123         case FIRE_PIRANHA_PLANT_ACT_HIDE:
    124             fire_piranha_plant_act_hide();
    125             break;
    126         case FIRE_PIRANHA_PLANT_ACT_GROW:
    127             fire_piranha_plant_act_grow();
    128             break;
    129     }
    130 
    131     if (obj_check_attacks(&sFirePiranhaPlantHitbox, o->oAction) != 0) {
    132         if (--o->oHealth < 0) {
    133             if (o->oFirePiranhaPlantActive) {
    134                 sNumActiveFirePiranhaPlants--;
    135             }
    136         } else {
    137             cur_obj_init_animation_with_sound(2);
    138         }
    139 
    140         o->oAction = FIRE_PIRANHA_PLANT_ACT_HIDE;
    141         o->oFirePiranhaPlantDeathSpinTimer = 10;
    142         o->oFirePiranhaPlantDeathSpinVel = 8000.0f;
    143 
    144         cur_obj_become_intangible();
    145     }
    146 }