summaryrefslogtreecommitdiff
path: root/src/actors/falling_rock/update.inc.c
blob: b700a4226ece9bfd77998bb565fc1c5d92f5faae (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include <actors.h>
#include <code_800029B0.h>
#include <main.h>
#include <assets/choco_mountain_data.h>

void func_8029CF0C(struct ActorSpawnData* spawnData, struct FallingRock* rock) {
#ifndef TARGET_N64
    struct ActorSpawnData* temp_v0 = spawnData;
#else
    s32 segment = SEGMENT_NUMBER2(spawnData);
    s32 offset = SEGMENT_OFFSET(spawnData);
    struct ActorSpawnData* temp_v0 = (struct ActorSpawnData*) VIRTUAL_TO_PHYSICAL2(gSegmentTable[segment] + offset);
#endif
    Vec3s sp24 = { 60, 120, 180 };
#ifndef TARGET_N64
    temp_v0 += rock->unk_06;
#endif
    rock->respawnTimer = sp24[rock->unk_06]; // * 2
    rock->pos[0] = (f32) temp_v0[rock->unk_06].pos[0] * gCourseDirection;
    rock->pos[1] = (f32) temp_v0[rock->unk_06].pos[1] + 10.0f;
    rock->pos[2] = (f32) temp_v0[rock->unk_06].pos[2];
    vec3f_set(rock->velocity, 0, 0, 0);
    vec3s_set(rock->rot, 0, 0, 0);
}

/**
 * @brief Spawns falling sRockSpawnData.
 * Used in Choco Mountain.
 *
 * @param spawnData
 */
static struct ActorSpawnData* sRockSpawnData;
void spawn_falling_rocks(struct ActorSpawnData* spawnData) {
#ifndef TARGET_N64
    struct ActorSpawnData* temp_s0 = spawnData;
    sRockSpawnData = spawnData;
#else
    s32 addr = SEGMENT_NUMBER2(spawnData);
    s32 offset = SEGMENT_OFFSET(spawnData);
    // Casting this to prevent warning does not work.
    struct ActorSpawnData* temp_s0 = (struct ActorSpawnData*) VIRTUAL_TO_PHYSICAL2(gSegmentTable[addr] + offset);
#endif
    struct FallingRock* temp_v1;
    Vec3f startingPos;
    Vec3f startingVelocity;
    Vec3s startingRot;
    s16 temp;

    while (temp_s0->pos[0] != -0x8000) {
        startingPos[0] = temp_s0->pos[0] * gCourseDirection;
        startingPos[1] = temp_s0->pos[1] + 10.0f;
        startingPos[2] = temp_s0->pos[2];
        vec3f_set(startingVelocity, 0, 0, 0);
        vec3s_set(startingRot, 0, 0, 0);
        temp = add_actor_to_empty_slot(startingPos, startingRot, startingVelocity, ACTOR_FALLING_ROCK);
        temp_v1 = (struct FallingRock*) GET_ACTOR(temp);

        temp_v1->unk_06 = temp_s0->someId;
        func_802AAAAC((Collision*) &temp_v1->unk30);
        temp_s0++;
    }
}

/**
 * @brief Updates the falling rock actor.
 * Actor used in Choco Mountain.
 *
 * @param rock
 */
void update_actor_falling_rocks(struct FallingRock* rock) {
    Vec3f unkVec;
    f32 pad0;
    f32 pad1;

    if (rock->respawnTimer != 0) {
        rock->respawnTimer -= 1;
        return;
    }
    if (rock->pos[1] < CM_GetWaterLevel(rock->pos, NULL)) {
        func_8029CF0C(sRockSpawnData, rock);
    }
    rock->rot[0] += (s16) ((rock->velocity[2] * 5461.0f) / 20.0f);
    rock->rot[2] += (s16) ((rock->velocity[0] * 5461.0f) / 20.0f);
    rock->velocity[1] -= 0.1;
    if (rock->velocity[1] < (-2.0f)) {
        rock->velocity[1] = -2.0f;
    }
    rock->pos[0] += rock->velocity[0];
    rock->pos[1] += rock->velocity[1];
    rock->pos[2] += rock->velocity[2];
    pad1 = rock->velocity[1];
    check_bounding_collision(&rock->unk30, 10.0f, rock->pos[0], rock->pos[1], rock->pos[2]);
    pad0 = rock->unk30.surfaceDistance[2];
    if (pad0 < 0.0f) {
        unkVec[0] = -rock->unk30.orientationVector[0];
        unkVec[1] = -rock->unk30.orientationVector[1];
        unkVec[2] = -rock->unk30.orientationVector[2];
        rock->pos[0] += unkVec[0] * rock->unk30.surfaceDistance[2];
        rock->pos[1] += unkVec[1] * rock->unk30.surfaceDistance[2];
        rock->pos[2] += unkVec[2] * rock->unk30.surfaceDistance[2];
        adjust_pos_orthogonally(unkVec, pad0, rock->velocity, 2.0f);
        rock->velocity[1] = -1.2f * pad1;
        func_800C98B8(rock->pos, rock->velocity, SOUND_ARG_LOAD(0x19, 0x00, 0x80, 0x0F));
    }
    pad0 = rock->unk30.surfaceDistance[0];
    if (pad0 < 0.0f) {
        unkVec[1] = -rock->unk30.unk48[1];
        if (unkVec[1] == 0.0f) {
            rock->velocity[1] *= -1.2f;
            return;
        } else {
            unkVec[0] = -rock->unk30.unk48[0];
            unkVec[2] = -rock->unk30.unk48[2];
            rock->pos[0] += unkVec[0] * rock->unk30.surfaceDistance[0];
            rock->pos[1] += unkVec[1] * rock->unk30.surfaceDistance[0];
            rock->pos[2] += unkVec[2] * rock->unk30.surfaceDistance[0];
            adjust_pos_orthogonally(unkVec, pad0, rock->velocity, 2.0f);
            rock->velocity[1] = -1.2f * pad1;
            func_800C98B8(rock->pos, rock->velocity, SOUND_ARG_LOAD(0x19, 0x00, 0x80, 0x0F));
        }
    }
    pad0 = rock->unk30.surfaceDistance[1];
    if (pad0 < 0.0f) {
        unkVec[1] = -rock->unk30.unk54[1];
        if (unkVec[1] == 0.0f) {
            rock->velocity[1] *= -1.2f;
        } else {
            unkVec[0] = -rock->unk30.unk54[0];
            unkVec[2] = -rock->unk30.unk54[2];
            rock->pos[0] += unkVec[0] * rock->unk30.surfaceDistance[1];
            rock->pos[1] += unkVec[1] * rock->unk30.surfaceDistance[1];
            rock->pos[2] += unkVec[2] * rock->unk30.surfaceDistance[1];
            pad1 = rock->velocity[1];
            adjust_pos_orthogonally(unkVec, pad0, rock->velocity, 2.0f);
            rock->velocity[1] = -1.2f * pad1;
            func_800C98B8(rock->pos, rock->velocity, SOUND_ARG_LOAD(0x19, 0x00, 0x80, 0x0F));
        }
    }
}