sm64

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

butterfly.inc.c (3276B)


      1 // butterfly.inc.c
      2 
      3 void bhv_butterfly_init(void) {
      4     cur_obj_init_animation(1);
      5 
      6     o->oButterflyYPhase = random_float() * 100.0f;
      7     o->header.gfx.animInfo.animFrame = random_float() * 7.0f;
      8     o->oHomeX = o->oPosX;
      9     o->oHomeY = o->oPosY;
     10     o->oHomeZ = o->oPosZ;
     11 }
     12 
     13 void butterfly_step(s32 speed) {
     14     struct FloorGeometry *sp24;
     15     s16 yaw = o->oMoveAngleYaw;
     16     s16 pitch = o->oMoveAnglePitch;
     17     s16 yPhase = o->oButterflyYPhase;
     18     f32 floorY;
     19 
     20     o->oVelX = sins(yaw) * (f32) speed;
     21     o->oVelY = sins(pitch) * (f32) speed;
     22     o->oVelZ = coss(yaw) * (f32) speed;
     23 
     24     o->oPosX += o->oVelX;
     25     o->oPosZ += o->oVelZ;
     26 
     27     if (o->oAction == BUTTERFLY_ACT_FOLLOW_MARIO) {
     28         o->oPosY -= o->oVelY + coss((s32)(yPhase * 655.36)) * 20.0f / 4;
     29     } else {
     30         o->oPosY -= o->oVelY;
     31     }
     32 
     33     floorY = find_floor_height_and_data(o->oPosX, o->oPosY, o->oPosZ, &sp24);
     34 
     35     if (o->oPosY < floorY + 2.0f) {
     36         o->oPosY = floorY + 2.0f;
     37     }
     38 
     39     o->oButterflyYPhase++;
     40     if (o->oButterflyYPhase > 100) {
     41         o->oButterflyYPhase = 0;
     42     }
     43 }
     44 
     45 void butterfly_calculate_angle(void) {
     46     gMarioObject->oPosX += 5 * o->oButterflyYPhase / 4;
     47     gMarioObject->oPosZ += 5 * o->oButterflyYPhase / 4;
     48     obj_turn_toward_object(o, gMarioObject, 16, 0x300);
     49     gMarioObject->oPosX -= 5 * o->oButterflyYPhase / 4;
     50     gMarioObject->oPosZ -= 5 * o->oButterflyYPhase / 4;
     51 
     52     gMarioObject->oPosY += (5 * o->oButterflyYPhase + 0x100) / 4;
     53     obj_turn_toward_object(o, gMarioObject, 15, 0x500);
     54     gMarioObject->oPosY -= (5 * o->oButterflyYPhase + 0x100) / 4;
     55 }
     56 
     57 void butterfly_act_rest(void) {
     58     if (is_point_within_radius_of_mario(o->oPosX, o->oPosY, o->oPosZ, 1000)) {
     59         cur_obj_init_animation(0);
     60 
     61         o->oAction = BUTTERFLY_ACT_FOLLOW_MARIO;
     62         o->oMoveAngleYaw = gMarioObject->header.gfx.angle[1];
     63     }
     64 }
     65 
     66 void butterfly_act_follow_mario(void) {
     67     butterfly_calculate_angle();
     68 
     69     butterfly_step(7);
     70 
     71     if (!is_point_within_radius_of_mario(o->oHomeX, o->oHomeY, o->oHomeZ, 1200)) {
     72         o->oAction = BUTTERFLY_ACT_RETURN_HOME;
     73     }
     74 }
     75 
     76 void butterfly_act_return_home(void) {
     77     f32 homeDistX = o->oHomeX - o->oPosX;
     78     f32 homeDistY = o->oHomeY - o->oPosY;
     79     f32 homeDistZ = o->oHomeZ - o->oPosZ;
     80     s16 hAngleToHome = atan2s(homeDistZ, homeDistX);
     81     s16 vAngleToHome = atan2s(sqrtf(homeDistX * homeDistX + homeDistZ * homeDistZ), -homeDistY);
     82 
     83     o->oMoveAngleYaw = approach_s16_symmetric(o->oMoveAngleYaw, hAngleToHome, 0x800);
     84     o->oMoveAnglePitch = approach_s16_symmetric(o->oMoveAnglePitch, vAngleToHome, 0x50);
     85 
     86     butterfly_step(7);
     87 
     88     if (homeDistX * homeDistX + homeDistY * homeDistY + homeDistZ * homeDistZ < 144.0f) {
     89         cur_obj_init_animation(1);
     90 
     91         o->oAction = BUTTERFLY_ACT_RESTING;
     92         o->oPosX = o->oHomeX;
     93         o->oPosY = o->oHomeY;
     94         o->oPosZ = o->oHomeZ;
     95     }
     96 }
     97 
     98 void bhv_butterfly_loop(void) {
     99     switch (o->oAction) {
    100         case BUTTERFLY_ACT_RESTING:
    101             butterfly_act_rest();
    102             break;
    103 
    104         case BUTTERFLY_ACT_FOLLOW_MARIO:
    105             butterfly_act_follow_mario();
    106             break;
    107 
    108         case BUTTERFLY_ACT_RETURN_HOME:
    109             butterfly_act_return_home();
    110             break;
    111     }
    112 
    113     set_object_visibility(o, 3000);
    114 }