sm64

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

hoot.inc.c (7343B)


      1 // hoot.inc.c
      2 
      3 void bhv_hoot_init(void) {
      4     cur_obj_init_animation(0);
      5 
      6     o->oHomeX = o->oPosX + 800.0f;
      7     o->oHomeY = o->oPosY - 150.0f;
      8     o->oHomeZ = o->oPosZ + 300.0f;
      9     o->header.gfx.node.flags |= GRAPH_RENDER_INVISIBLE;
     10 
     11     cur_obj_become_intangible();
     12 }
     13 
     14 f32 hoot_find_next_floor(struct FloorGeometry **floorGeo, f32 arg1) {
     15     f32 sp24 = arg1 * sins(o->oMoveAngleYaw) + o->oPosX;
     16     UNUSED f32 sp20 = o->oPosY;
     17     f32 sp1c = arg1 * coss(o->oMoveAngleYaw) + o->oPosZ;
     18     f32 floorY = find_floor_height_and_data(sp24, 10000.0f, sp1c, floorGeo);
     19 
     20     return floorY;
     21 }
     22 
     23 void hoot_floor_bounce(void) {
     24     struct FloorGeometry *floorGeo;
     25     f32 floorY;
     26 
     27     floorY = hoot_find_next_floor(&floorGeo, 375.0f);
     28     if (floorY + 75.0f > o->oPosY) {
     29         o->oMoveAnglePitch -= 3640.8888;
     30     }
     31 
     32     floorY = hoot_find_next_floor(&floorGeo, 200.0f);
     33     if (floorY + 125.0f > o->oPosY) {
     34         o->oMoveAnglePitch -= 7281.7776;
     35     }
     36 
     37     floorY = hoot_find_next_floor(&floorGeo, 0);
     38     if (floorY + 125.0f > o->oPosY) {
     39         o->oPosY = floorY + 125.0f;
     40     }
     41 
     42     if (o->oMoveAnglePitch < -21845.3328) {
     43         o->oMoveAnglePitch = -21845;
     44     }
     45 }
     46 
     47 void hoot_free_step(s16 fastOscY, s32 speed) {
     48     struct FloorGeometry *floorGeo;
     49     s16 yaw = o->oMoveAngleYaw;
     50     s16 pitch = o->oMoveAnglePitch;
     51     s16 animFrame = o->header.gfx.animInfo.animFrame;
     52     f32 xPrev = o->oPosX;
     53     f32 zPrev = o->oPosZ;
     54     f32 hSpeed;
     55 
     56     o->oVelY = sins(pitch) * speed;
     57     hSpeed = coss(pitch) * speed;
     58     o->oVelX = sins(yaw) * hSpeed;
     59     o->oVelZ = coss(yaw) * hSpeed;
     60 
     61     o->oPosX += o->oVelX;
     62     if (fastOscY == 0) {
     63         o->oPosY -= o->oVelY + coss((s32)(animFrame * 3276.8)) * 50.0f / 4;
     64     } else {
     65         o->oPosY -= o->oVelY + coss((s32)(animFrame * 6553.6)) * 50.0f / 4;
     66     }
     67     o->oPosZ += o->oVelZ;
     68 
     69     find_floor_height_and_data(o->oPosX, o->oPosY, o->oPosZ, &floorGeo);
     70     if (floorGeo == NULL) {
     71         o->oPosX = xPrev;
     72         o->oPosZ = zPrev;
     73     }
     74 
     75     if (animFrame == 0) {
     76         cur_obj_play_sound_2(SOUND_GENERAL_SWISH_WATER);
     77     }
     78 }
     79 
     80 void hoot_player_set_yaw(void) {
     81     s16 stickX = gPlayer3Controller->rawStickX;
     82     s16 stickY = gPlayer3Controller->rawStickY;
     83     UNUSED s16 pitch = o->oMoveAnglePitch;
     84 
     85     if (stickX < 10 && stickX >= -9) {
     86         stickX = 0;
     87     }
     88 
     89     if (stickY < 10 && stickY >= -9) {
     90         stickY = 0;
     91     }
     92 
     93     o->oMoveAngleYaw -= 5 * stickX;
     94 }
     95 
     96 void hoot_carry_step(s32 speed, UNUSED f32 xPrev, UNUSED f32 zPrev) {
     97     s16 yaw = o->oMoveAngleYaw;
     98     s16 pitch = o->oMoveAnglePitch;
     99     s16 animFrame = o->header.gfx.animInfo.animFrame;
    100     f32 hSpeed;
    101 
    102     o->oVelY = sins(pitch) * speed;
    103     hSpeed = coss(pitch) * speed;
    104     o->oVelX = sins(yaw) * hSpeed;
    105     o->oVelZ = coss(yaw) * hSpeed;
    106 
    107     o->oPosX += o->oVelX;
    108     o->oPosY -= o->oVelY + coss((s32)(animFrame * 6553.6)) * 50.0f / 4;
    109     o->oPosZ += o->oVelZ;
    110 
    111     if (animFrame == 0) {
    112         cur_obj_play_sound_2(SOUND_GENERAL_SWISH_WATER);
    113     }
    114 }
    115 
    116 void hoot_surface_collision(f32 xPrev, UNUSED f32 yPrev, f32 zPrev) {
    117     struct FloorGeometry *floorGeo;
    118     struct WallCollisionData hitbox;
    119     f32 floorY;
    120 
    121     hitbox.x = o->oPosX;
    122     hitbox.y = o->oPosY;
    123     hitbox.z = o->oPosZ;
    124     hitbox.offsetY = 10.0;
    125     hitbox.radius = 50.0;
    126 
    127     if (find_wall_collisions(&hitbox) != 0) {
    128         o->oPosX = hitbox.x;
    129         o->oPosY = hitbox.y;
    130         o->oPosZ = hitbox.z;
    131         gMarioObject->oInteractStatus |= INT_STATUS_MARIO_UNK7;
    132     }
    133 
    134     floorY = find_floor_height_and_data(o->oPosX, o->oPosY, o->oPosZ, &floorGeo);
    135     if (floorGeo == NULL) {
    136         o->oPosX = xPrev;
    137         o->oPosZ = zPrev;
    138         return;
    139     }
    140 
    141     if (absf_2(o->oPosX) > 8000.0f) {
    142         o->oPosX = xPrev;
    143     }
    144 
    145     if (absf_2(o->oPosZ) > 8000.0f) {
    146         o->oPosZ = zPrev;
    147     }
    148 
    149     if (floorY + 125.0f > o->oPosY) {
    150         o->oPosY = floorY + 125.0f;
    151     }
    152 }
    153 
    154 void hoot_act_ascent(f32 xPrev, f32 zPrev) {
    155     f32 negX = 0 - o->oPosX;
    156     f32 negZ = 0 - o->oPosZ;
    157     s16 angleToOrigin = atan2s(negZ, negX);
    158 
    159     o->oMoveAngleYaw = approach_s16_symmetric(o->oMoveAngleYaw, angleToOrigin, 0x500);
    160     o->oMoveAnglePitch = 0xCE38;
    161 
    162     if (o->oTimer >= 29) {
    163         cur_obj_play_sound_1(SOUND_ENV_WIND2);
    164         o->header.gfx.animInfo.animFrame = 1;
    165     }
    166 
    167     if (o->oPosY > 6500.0f) {
    168         o->oAction = HOOT_ACT_CARRY;
    169     }
    170 
    171     hoot_carry_step(60, xPrev, zPrev);
    172 }
    173 
    174 void hoot_action_loop(void) {
    175     f32 xPrev = o->oPosX;
    176     f32 yPrev = o->oPosY;
    177     f32 zPrev = o->oPosZ;
    178 
    179     switch (o->oAction) {
    180         case HOOT_ACT_ASCENT:
    181             hoot_act_ascent(xPrev, zPrev);
    182             break;
    183 
    184         case HOOT_ACT_CARRY:
    185             hoot_player_set_yaw();
    186 
    187             o->oMoveAnglePitch = 0x71C;
    188 
    189             if (o->oPosY < 2700.0f) {
    190                 set_time_stop_flags(TIME_STOP_ENABLED | TIME_STOP_MARIO_AND_DOORS);
    191 
    192                 if (cutscene_object_with_dialog(CUTSCENE_DIALOG, o, DIALOG_045) != 0) {
    193                     clear_time_stop_flags(TIME_STOP_ENABLED | TIME_STOP_MARIO_AND_DOORS);
    194                     o->oAction = HOOT_ACT_TIRED;
    195                 }
    196             }
    197 
    198             hoot_carry_step(20, xPrev, zPrev);
    199             break;
    200 
    201         case HOOT_ACT_TIRED:
    202             hoot_player_set_yaw();
    203 
    204             o->oMoveAnglePitch = 0;
    205 
    206             hoot_carry_step(20, xPrev, zPrev);
    207 
    208             if (o->oTimer > 60) {
    209                 gMarioObject->oInteractStatus |= INT_STATUS_MARIO_UNK7;
    210             }
    211             break;
    212     }
    213 
    214     hoot_surface_collision(xPrev, yPrev, zPrev);
    215 }
    216 
    217 void hoot_turn_to_home(void) {
    218     f32 homeDistX = o->oHomeX - o->oPosX;
    219     f32 homeDistY = o->oHomeY - o->oPosY;
    220     f32 homeDistZ = o->oHomeZ - o->oPosZ;
    221     s16 hAngleToHome = atan2s(homeDistZ, homeDistX);
    222     s16 vAngleToHome = atan2s(sqrtf(homeDistX * homeDistX + homeDistZ * homeDistZ), -homeDistY);
    223 
    224     o->oMoveAngleYaw = approach_s16_symmetric(o->oMoveAngleYaw, hAngleToHome, 0x140);
    225     o->oMoveAnglePitch = approach_s16_symmetric(o->oMoveAnglePitch, vAngleToHome, 0x140);
    226 }
    227 
    228 void hoot_awake_loop(void) {
    229     if (o->oInteractStatus == TRUE) { //! Note: Not a flag, treated as a TRUE/FALSE statement
    230         hoot_action_loop();
    231         cur_obj_init_animation(1);
    232     } else {
    233         cur_obj_init_animation(0);
    234 
    235         hoot_turn_to_home();
    236         hoot_floor_bounce();
    237         hoot_free_step(0, 10);
    238 
    239         o->oAction = 0;
    240         o->oTimer = 0;
    241     }
    242 
    243     set_object_visibility(o, 2000);
    244 }
    245 
    246 void bhv_hoot_loop(void) {
    247     switch (o->oHootAvailability) {
    248         case HOOT_AVAIL_ASLEEP_IN_TREE:
    249             if (is_point_within_radius_of_mario(o->oPosX, o->oPosY, o->oPosZ, 50)) {
    250                 o->header.gfx.node.flags &= ~GRAPH_RENDER_INVISIBLE;
    251                 o->oHootAvailability = HOOT_AVAIL_WANTS_TO_TALK;
    252             }
    253             break;
    254 
    255         case HOOT_AVAIL_WANTS_TO_TALK:
    256             hoot_awake_loop();
    257 
    258             if (set_mario_npc_dialog(MARIO_DIALOG_LOOK_UP) == MARIO_DIALOG_STATUS_SPEAK
    259                 && cutscene_object_with_dialog(CUTSCENE_DIALOG, o, DIALOG_044)) {
    260                 set_mario_npc_dialog(MARIO_DIALOG_STOP);
    261 
    262                 cur_obj_become_tangible();
    263 
    264                 o->oHootAvailability = HOOT_AVAIL_READY_TO_FLY;
    265             }
    266             break;
    267 
    268         case HOOT_AVAIL_READY_TO_FLY:
    269             hoot_awake_loop();
    270             break;
    271     }
    272 }