sm64

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

controllable_platform.inc.c (7836B)


      1 // controllable_platform.inc.c
      2 
      3 static s8 D_80331694 = 0;
      4 
      5 void controllable_platform_act_1(void) {
      6     o->oParentRelativePosY -= 4.0f;
      7     if (o->oParentRelativePosY < 41.0f) {
      8         o->oParentRelativePosY = 41.0f;
      9         o->oAction = 2;
     10     }
     11 }
     12 
     13 void controllable_platform_act_2(void) {
     14     if (o->oBhvParams2ndByte == D_80331694) {
     15         return;
     16     }
     17 
     18     o->oParentRelativePosY += 4.0f;
     19     if (o->oParentRelativePosY > 51.0f) {
     20         o->oParentRelativePosY = 51.0f;
     21         o->oAction = 0;
     22     }
     23 }
     24 
     25 void bhv_controllable_platform_sub_loop(void) {
     26     switch (o->oAction) {
     27         case 0:
     28             if (o->oTimer < 30) {
     29                 break;
     30             }
     31 
     32             if (gMarioObject->platform == o) {
     33                 D_80331694 = o->oBhvParams2ndByte;
     34 #if defined(VERSION_SH) || defined(VERSION_CN)
     35                 o->parentObj->header.gfx.node.flags &= ~GRAPH_RENDER_INVISIBLE;
     36 #endif
     37                 o->oAction = 1;
     38                 cur_obj_play_sound_2(SOUND_GENERAL_MOVING_PLATFORM_SWITCH);
     39             }
     40             break;
     41 
     42         case 1:
     43             controllable_platform_act_1();
     44             break;
     45 
     46         case 2:
     47             controllable_platform_act_2();
     48             break;
     49     }
     50 
     51     o->oVelX = o->parentObj->oVelX;
     52     o->oVelZ = o->parentObj->oVelZ;
     53 
     54     if (o->parentObj->activeFlags == ACTIVE_FLAG_DEACTIVATED) {
     55         o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
     56     }
     57 }
     58 
     59 void bhv_controllable_platform_init(void) {
     60     struct Object *sp34;
     61 
     62     sp34 = spawn_object_rel_with_rot(o, MODEL_HMC_METAL_ARROW_PLATFORM, bhvControllablePlatformSub, 0,
     63                                      51, 204, 0, 0, 0);
     64     sp34->oBhvParams2ndByte = 1;
     65     sp34 = spawn_object_rel_with_rot(o, MODEL_HMC_METAL_ARROW_PLATFORM, bhvControllablePlatformSub, 0,
     66                                      51, -204, 0, -0x8000, 0);
     67     sp34->oBhvParams2ndByte = 2;
     68     sp34 = spawn_object_rel_with_rot(o, MODEL_HMC_METAL_ARROW_PLATFORM, bhvControllablePlatformSub, 204,
     69                                      51, 0, 0, 0x4000, 0);
     70     sp34->oBhvParams2ndByte = 3;
     71     sp34 = spawn_object_rel_with_rot(o, MODEL_HMC_METAL_ARROW_PLATFORM, bhvControllablePlatformSub,
     72                                      -204, 51, 0, 0, -0x4000, 0);
     73     sp34->oBhvParams2ndByte = 4;
     74 
     75     D_80331694 = 0;
     76 
     77     o->oControllablePlatformUnkFC = o->oPosY;
     78 }
     79 
     80 void controllable_platform_hit_wall(s8 sp1B) {
     81     o->oControllablePlatformUnkF8 = sp1B;
     82     o->oTimer = 0;
     83     D_80331694 = 5;
     84 
     85     cur_obj_play_sound_2(SOUND_GENERAL_QUIET_POUND1);
     86 #if ENABLE_RUMBLE
     87     queue_rumble_data(50, 80);
     88 #endif
     89 }
     90 
     91 void controllable_platform_check_walls(s8 sp1B, s8 sp1C[3], Vec3f sp20, UNUSED Vec3f sp24, Vec3f sp28) {
     92     if (sp1C[1] == 1 || (sp1C[0] == 1 && sp1C[2] == 1)) {
     93         controllable_platform_hit_wall(sp1B);
     94     } else {
     95         if (sp1C[0] == 1) {
     96             if (((sp1B == 1 || sp1B == 2) && (s32) sp20[2] != 0)
     97                 || ((sp1B == 3 || sp1B == 4) && (s32) sp20[0] != 0)) {
     98                 controllable_platform_hit_wall(sp1B);
     99             } else {
    100                 o->oPosX += sp20[0];
    101                 o->oPosZ += sp20[2];
    102             }
    103         }
    104 
    105         if (sp1C[2] == 1) {
    106             if (((sp1B == 1 || sp1B == 2) && (s32) sp28[2] != 0)
    107                 || ((sp1B == 3 || sp1B == 4) && (s32) sp28[0] != 0)) {
    108                 controllable_platform_hit_wall(sp1B);
    109             } else {
    110                 o->oPosX += sp28[0];
    111                 o->oPosZ += sp28[2];
    112             }
    113         }
    114     }
    115 
    116     if (!is_point_within_radius_of_mario(o->oPosX, o->oPosY, o->oPosZ, 400)) {
    117         D_80331694 = 6;
    118         o->oControllablePlatformUnk100 = 1;
    119         o->oTimer = 0;
    120     }
    121 }
    122 
    123 void controllable_platform_shake_on_wall_hit(void) {
    124     if (o->oControllablePlatformUnkF8 == 1 || o->oControllablePlatformUnkF8 == 2) {
    125         o->oFaceAnglePitch = sins(o->oTimer * 0x1000) * 182.04444 * 10.0;
    126         o->oPosY = o->oControllablePlatformUnkFC + sins(o->oTimer * 0x2000) * 20.0f;
    127     } else {
    128         o->oFaceAngleRoll = sins(o->oTimer * 0x1000) * 182.04444 * 10.0;
    129         o->oPosY = o->oControllablePlatformUnkFC + sins(o->oTimer * 0x2000) * 20.0f;
    130     }
    131 
    132     if (o->oTimer == 32) {
    133         D_80331694 = o->oControllablePlatformUnkF8;
    134         o->oFaceAnglePitch = 0;
    135         o->oFaceAngleRoll = 0;
    136         o->oPosY = o->oControllablePlatformUnkFC;
    137     }
    138 }
    139 
    140 void controllable_platform_tilt_from_mario(void) {
    141     s16 sp1E = gMarioObject->header.gfx.pos[0] - o->oPosX;
    142     s16 sp1C = gMarioObject->header.gfx.pos[2] - o->oPosZ;
    143 
    144     if (gMarioObject->platform == o
    145         || gMarioObject->platform == cur_obj_nearest_object_with_behavior(bhvControllablePlatformSub)) {
    146         o->oFaceAnglePitch = sp1C * 4;
    147         o->oFaceAngleRoll = -sp1E * 4;
    148         if (D_80331694 == 6) {
    149             D_80331694 = 0;
    150             o->oTimer = 0;
    151             o->header.gfx.node.flags &= ~GRAPH_RENDER_INVISIBLE;
    152         }
    153     } else {
    154     }
    155 }
    156 
    157 void bhv_controllable_platform_loop(void) {
    158     s8 sp54[3];
    159     Vec3f sp48;
    160     Vec3f sp3C;
    161     Vec3f sp30;
    162 
    163     o->oAngleVelRoll = 0;
    164     o->oAngleVelPitch = 0;
    165     o->oVelX = 0;
    166     o->oVelZ = 0;
    167 
    168     switch (D_80331694) {
    169         case 0:
    170             o->oFaceAnglePitch /= 2;
    171             o->oFaceAngleRoll /= 2;
    172             if (o->oControllablePlatformUnk100 == 1 && o->oTimer > 30) {
    173                 D_80331694 = 6;
    174                 o->oTimer = 0;
    175             }
    176             break;
    177 
    178         case 1:
    179             o->oVelZ = 10.0f;
    180             sp54[0] = obj_find_wall_displacement(sp48, o->oPosX + 250.0, o->oPosY, o->oPosZ + 300.0, 50.0f);
    181             sp54[1] = obj_find_wall_displacement(sp3C, o->oPosX, o->oPosY, o->oPosZ + 300.0, 50.0f);
    182             sp54[2] = obj_find_wall_displacement(sp30, o->oPosX - 250.0, o->oPosY, o->oPosZ + 300.0, 50.0f);
    183             controllable_platform_check_walls(2, sp54, sp48, sp3C, sp30);
    184             break;
    185 
    186         case 2:
    187             o->oVelZ = -10.0f;
    188             sp54[0] = obj_find_wall_displacement(sp48, o->oPosX + 250.0, o->oPosY, o->oPosZ - 300.0, 50.0f);
    189             sp54[1] = obj_find_wall_displacement(sp3C, o->oPosX, o->oPosY, o->oPosZ - 300.0, 50.0f);
    190             sp54[2] = obj_find_wall_displacement(sp30, o->oPosX - 250.0, o->oPosY, o->oPosZ - 300.0, 50.0f);
    191             controllable_platform_check_walls(1, sp54, sp48, sp3C, sp30);
    192             break;
    193 
    194         case 3:
    195             o->oVelX = 10.0f;
    196             sp54[0] = obj_find_wall_displacement(sp48, o->oPosX + 300.0, o->oPosY, o->oPosZ + 250.0, 50.0f);
    197             sp54[1] = obj_find_wall_displacement(sp3C, o->oPosX + 300.0, o->oPosY, o->oPosZ, 50.0f);
    198             sp54[2] = obj_find_wall_displacement(sp30, o->oPosX + 300.0, o->oPosY, o->oPosZ - 250.0, 50.0f);
    199             controllable_platform_check_walls(4, sp54, sp48, sp3C, sp30);
    200             break;
    201 
    202         case 4:
    203             o->oVelX = -10.0f;
    204             sp54[0] = obj_find_wall_displacement(sp48, o->oPosX - 300.0, o->oPosY, o->oPosZ + 250.0, 50.0f);
    205             sp54[1] = obj_find_wall_displacement(sp3C, o->oPosX - 300.0, o->oPosY, o->oPosZ, 50.0f);
    206             sp54[2] = obj_find_wall_displacement(sp30, o->oPosX - 300.0, o->oPosY, o->oPosZ - 250.0, 50.0f);
    207             controllable_platform_check_walls(3, sp54, sp48, sp3C, sp30);
    208             break;
    209 
    210         case 5:
    211             controllable_platform_shake_on_wall_hit();
    212             return;
    213             break;
    214 
    215         case 6:
    216             if (obj_flicker_and_disappear(o, 150)) {
    217                 spawn_object_abs_with_rot(o, 0, MODEL_HMC_METAL_PLATFORM, bhvControllablePlatform,
    218                                           o->oHomeX, o->oHomeY, o->oHomeZ, 0, 0, 0);
    219             }
    220             break;
    221     }
    222 
    223     controllable_platform_tilt_from_mario();
    224     o->oPosX += o->oVelX;
    225     o->oPosZ += o->oVelZ;
    226     if (D_80331694 != 0 && D_80331694 != 6) {
    227         cur_obj_play_sound_1(SOUND_ENV_ELEVATOR2);
    228     }
    229 }