sm64

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

mr_i.inc.c (8035B)


      1 // mr_i.inc.c
      2 
      3 // this is actually the MrI particle loop function. piranha
      4 // plant code later on reuses this function.
      5 void bhv_piranha_particle_loop(void) {
      6     if (o->oTimer == 0) {
      7         o->oVelY = 20.0f + 20.0f * random_float();
      8         o->oForwardVel = 20.0f + 20.0f * random_float();
      9         o->oMoveAngleYaw = random_u16();
     10     }
     11     cur_obj_move_using_fvel_and_gravity();
     12 }
     13 
     14 void mr_i_piranha_particle_act_0(void) {
     15     cur_obj_scale(3.0f);
     16     o->oForwardVel = 20.0f;
     17     cur_obj_update_floor_and_walls();
     18 
     19     if (o->oInteractStatus & INT_STATUS_INTERACTED) {
     20         o->oAction = 1;
     21     } else if ((o->oTimer > 100) || (o->oMoveFlags & OBJ_MOVE_HIT_WALL)
     22                || (o->activeFlags & ACTIVE_FLAG_IN_DIFFERENT_ROOM)) {
     23         obj_mark_for_deletion(o);
     24         spawn_mist_particles();
     25     }
     26 }
     27 
     28 void mr_i_piranha_particle_act_1(void) {
     29     s32 i;
     30     obj_mark_for_deletion(o);
     31     for (i = 0; i < 10; i++) {
     32         spawn_object(o, MODEL_PURPLE_MARBLE, bhvPurpleParticle);
     33     }
     34 }
     35 
     36 void (*sMrIParticleActions[])(void) = {
     37     mr_i_piranha_particle_act_0,
     38     mr_i_piranha_particle_act_1,
     39 };
     40 
     41 void bhv_mr_i_particle_loop(void) {
     42     cur_obj_call_action_function(sMrIParticleActions);
     43 }
     44 
     45 void spawn_mr_i_particle(void) {
     46     struct Object *particle;
     47     f32 sp18 = o->header.gfx.scale[1];
     48 
     49     particle = spawn_object(o, MODEL_PURPLE_MARBLE, bhvMrIParticle);
     50     particle->oPosY += 50.0f * sp18;
     51     particle->oPosX += sins(o->oMoveAngleYaw) * 90.0f * sp18;
     52     particle->oPosZ += coss(o->oMoveAngleYaw) * 90.0f * sp18;
     53 
     54     cur_obj_play_sound_2(SOUND_OBJ_MRI_SHOOT);
     55 }
     56 
     57 void bhv_mr_i_body_loop(void) {
     58     obj_copy_pos_and_angle(o, o->parentObj);
     59 
     60     if (!(o->activeFlags & ACTIVE_FLAG_IN_DIFFERENT_ROOM)) {
     61         obj_copy_scale(o, o->parentObj);
     62         obj_set_parent_relative_pos(o, 0, 0, o->header.gfx.scale[1] * 100.0f);
     63         obj_build_transform_from_pos_and_angle(o, 44, 15);
     64         obj_translate_local(o, 6, 44);
     65         o->oFaceAnglePitch = o->oMoveAnglePitch;
     66         o->oGraphYOffset = o->header.gfx.scale[1] * 100.0f;
     67     }
     68 
     69     if (o->parentObj->oMrIUnk110 != 1) {
     70         o->oAnimState = -1;
     71     } else {
     72         o->oAnimState++;
     73         if (o->oAnimState == 15) {
     74             o->parentObj->oMrIUnk110 = 0;
     75         }
     76     }
     77 
     78     if (o->parentObj->activeFlags == ACTIVE_FLAG_DEACTIVATED) {
     79         obj_mark_for_deletion(o);
     80     }
     81 }
     82 
     83 void mr_i_act_3(void) {
     84     s16 sp36;
     85     s16 sp34;
     86     f32 sp30;
     87     f32 sp2C;
     88     UNUSED u8 filler[8];
     89     f32 sp20;
     90     f32 sp1C;
     91 
     92     if (o->oBhvParams2ndByte != 0) {
     93         sp1C = 2.0f;
     94     } else {
     95         sp1C = 1.0f;
     96     }
     97 
     98     if (o->oMrIUnk100 < 0) {
     99         sp34 = 0x1000;
    100     } else {
    101         sp34 = -0x1000;
    102     }
    103 
    104     sp2C = (o->oTimer + 1) / 96.0f;
    105 
    106     if (o->oTimer < 64) {
    107         sp36 = o->oMoveAngleYaw;
    108         o->oMoveAngleYaw += sp34 * coss(0x4000 * sp2C);
    109 
    110         if (sp36 < 0 && o->oMoveAngleYaw >= 0) {
    111             cur_obj_play_sound_2(SOUND_OBJ2_MRI_SPINNING);
    112         }
    113 
    114         o->oMoveAnglePitch = (1.0 - coss(0x4000 * sp2C)) * -0x4000;
    115         cur_obj_shake_y(4.0f);
    116     } else if (o->oTimer < 96) {
    117         if (o->oTimer == 64) {
    118             cur_obj_play_sound_2(SOUND_OBJ_MRI_DEATH);
    119         }
    120 
    121         sp30 = (f32)(o->oTimer - 63) / 32;
    122         o->oMoveAngleYaw += sp34 * coss(0x4000 * sp2C);
    123         o->oMoveAnglePitch = (1.0 - coss(0x4000 * sp2C)) * -0x4000;
    124 
    125         cur_obj_shake_y((s32)((1.0f - sp30) * 4)); // trucating the f32?
    126         sp20 = coss(0x4000 * sp30) * 0.4 + 0.6;
    127         cur_obj_scale(sp20 * sp1C);
    128     } else if (o->oTimer < 104) {
    129         // do nothing
    130     } else if (o->oTimer < 168) {
    131         if (o->oTimer == 104) {
    132             cur_obj_become_intangible();
    133             spawn_mist_particles();
    134             o->oMrIScale = sp1C * 0.6;
    135             if (o->oBhvParams2ndByte != 0) {
    136                 o->oPosY += 100.0f;
    137                 spawn_default_star(1370, 2000.0f, -320.0f);
    138                 obj_mark_for_deletion(o);
    139             } else {
    140                 cur_obj_spawn_loot_blue_coin();
    141             }
    142         }
    143 
    144         o->oMrIScale -= 0.2 * sp1C;
    145 
    146         if (o->oMrIScale < 0) {
    147             o->oMrIScale = 0;
    148         }
    149 
    150         cur_obj_scale(o->oMrIScale);
    151     } else {
    152         obj_mark_for_deletion(o);
    153     }
    154 }
    155 
    156 void mr_i_act_2(void) {
    157     s16 sp1E = o->oMoveAngleYaw;
    158     s16 sp1C;
    159 
    160     if (o->oTimer == 0) {
    161         if (o->oBhvParams2ndByte != 0) {
    162             o->oMrIUnkF4 = 200;
    163         } else {
    164             o->oMrIUnkF4 = 120;
    165         }
    166         o->oMrIUnkFC = 0;
    167         o->oMrIUnk100 = 0;
    168         o->oMrIUnk104 = 0;
    169     }
    170 
    171     obj_turn_toward_object(o, gMarioObject, 0x10, 0x800);
    172     obj_turn_toward_object(o, gMarioObject, 0x0F, 0x400);
    173 
    174     sp1C = sp1E - (s16)(o->oMoveAngleYaw);
    175 
    176     if (sp1C == 0) {
    177         o->oMrIUnkFC = 0;
    178         o->oMrIUnk100 = 0;
    179     } else if (sp1C > 0) {
    180         if (o->oMrIUnk100 > 0) {
    181             o->oMrIUnkFC += sp1C;
    182         } else {
    183             o->oMrIUnkFC = 0;
    184         }
    185         o->oMrIUnk100 = 1;
    186     } else {
    187         if (o->oMrIUnk100 < 0) {
    188             o->oMrIUnkFC -= sp1C;
    189         } else {
    190             o->oMrIUnkFC = 0;
    191         }
    192         o->oMrIUnk100 = -1;
    193     }
    194 
    195     if (o->oMrIUnkFC == 0) {
    196         o->oMrIUnkF4 = 120;
    197     }
    198     if (o->oMrIUnkFC > 65536) {
    199         o->oAction = 3;
    200     }
    201 
    202     o->oMrIUnkF4--;
    203 
    204     if (o->oMrIUnkF4 == 0) {
    205         o->oMrIUnkF4 = 120;
    206         o->oMrIUnkFC = 0;
    207     }
    208 
    209     if (o->oMrIUnkFC < 5000) {
    210         if (o->oMrIUnk104 == o->oMrIUnk108) {
    211             o->oMrIUnk110 = 1;
    212         }
    213 
    214         if (o->oMrIUnk104 == o->oMrIUnk108 + 20) {
    215             spawn_mr_i_particle();
    216             o->oMrIUnk104 = 0;
    217             o->oMrIUnk108 = (s32)(random_float() * 50.0f + 50.0f);
    218         }
    219         o->oMrIUnk104++;
    220     } else {
    221         o->oMrIUnk104 = 0;
    222         o->oMrIUnk108 = (s32)(random_float() * 50.0f + 50.0f);
    223     }
    224 
    225     if (o->oDistanceToMario > 800.0f) {
    226         o->oAction = 1;
    227     }
    228 }
    229 
    230 void mr_i_act_1(void) {
    231     s16 sp1E = obj_angle_to_object(o, gMarioObject);
    232     s16 sp1C = abs_angle_diff(o->oMoveAngleYaw, sp1E);
    233     s16 sp1A = abs_angle_diff(o->oMoveAngleYaw, gMarioObject->oFaceAngleYaw);
    234 
    235     if (o->oTimer == 0) {
    236         cur_obj_become_tangible();
    237         o->oMoveAnglePitch = 0;
    238         o->oMrIUnk104 = 30;
    239         o->oMrIUnk108 = random_float() * 20.0f;
    240         if (o->oMrIUnk108 & 1) {
    241             o->oAngleVelYaw = -256;
    242         } else {
    243             o->oAngleVelYaw = 256;
    244         }
    245     }
    246 
    247     if (sp1C < 1024 && sp1A > 0x4000) {
    248         if (o->oDistanceToMario < 700.0f) {
    249             o->oAction = 2;
    250         } else {
    251             o->oMrIUnk104++;
    252         }
    253     } else {
    254         o->oMoveAngleYaw += o->oAngleVelYaw;
    255         o->oMrIUnk104 = 30;
    256     }
    257 
    258     if (o->oMrIUnk104 == o->oMrIUnk108 + 60) {
    259         o->oMrIUnk110 = 1;
    260     }
    261 
    262     if (o->oMrIUnk104 > o->oMrIUnk108 + 80) {
    263         o->oMrIUnk104 = 0;
    264         o->oMrIUnk108 = random_float() * 80.0f;
    265         spawn_mr_i_particle();
    266     }
    267 }
    268 
    269 void mr_i_act_0(void) {
    270 #ifndef VERSION_JP
    271     obj_set_angle(o, 0, 0, 0);
    272 #else
    273     o->oMoveAnglePitch = 0;
    274     o->oMoveAngleYaw = 0;
    275     o->oMoveAngleRoll = 0;
    276 #endif
    277     cur_obj_scale(o->oBhvParams2ndByte + 1);
    278 
    279     if (o->oTimer == 0) {
    280         cur_obj_set_pos_to_home();
    281     }
    282 
    283     if (o->oDistanceToMario < 1500.0f) {
    284         o->oAction = 1;
    285     }
    286 }
    287 
    288 void (*sMrIActions[])(void) = {
    289     mr_i_act_0,
    290     mr_i_act_1,
    291     mr_i_act_2,
    292     mr_i_act_3,
    293 };
    294 
    295 struct ObjectHitbox sMrIHitbox = {
    296     /* interactType:      */ INTERACT_DAMAGE,
    297     /* downOffset:        */ 0,
    298     /* damageOrCoinValue: */ 2,
    299     /* health:            */ 2,
    300     /* numLootCoins:      */ 5,
    301     /* radius:            */ 80,
    302     /* height:            */ 150,
    303     /* hurtboxRadius:     */ 0,
    304     /* hurtboxHeight:     */ 0,
    305 };
    306 
    307 void bhv_mr_i_loop(void) {
    308     obj_set_hitbox(o, &sMrIHitbox);
    309     cur_obj_call_action_function(sMrIActions);
    310 
    311     if (o->oAction != 3) {
    312         if ((o->oDistanceToMario > 3000.0f) || (o->activeFlags & ACTIVE_FLAG_IN_DIFFERENT_ROOM)) {
    313             o->oAction = 0;
    314         }
    315     }
    316 
    317     o->oInteractStatus = 0;
    318 }