summaryrefslogtreecommitdiff
path: root/src/engine/objects/Crab.cpp
blob: c4e057b8ccbf586b2c6e8b70e8d20f480d4f934e (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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
#include <libultraship.h>
#include <libultra/gbi.h>
#include "Crab.h"
#include <vector>
#include "engine/CoreMath.h"

#include "port/Game.h"
#include "port/interpolation/FrameInterpolation.h"

extern "C" {
#include "macros.h"
#include "main.h"
#include "defines.h"
#include "camera.h"
#include "update_objects.h"
#include "render_objects.h"
#include "racing/actors.h"
#include "code_80057C60.h"
#include "code_80086E70.h"
#include "racing/math_util.h"
#include "math_util_2.h"
#include "code_80005FD0.h"
#include "textures/some_data.h"
#include "ending/ceremony_and_credits.h"
#include "assets/models/tracks/koopa_troopa_beach/koopa_troopa_beach_data.h"
#include "assets/textures/tracks/koopa_troopa_beach/koopa_troopa_beach_data.h"
#include "assets/models/common_data.h"
}

size_t OCrab::_count = 0;

OCrab::OCrab(const SpawnParams& params) : OObject(params) {
    Name = "Crab";
    ResourceName = "mk:crab";
    _idx = _count;
    _start = params.PatrolStart.value_or(FVector2D(0, 0));
    _end = params.PatrolEnd.value_or(FVector2D(0, 0));

    find_unused_obj_index(&_objectIndex);

    init_object(_objectIndex, 0);
    gObjectList[_objectIndex].pos[0] = gObjectList[_objectIndex].origin_pos[0] = _start.x * xOrientation;
    gObjectList[_objectIndex].pos[2] = gObjectList[_objectIndex].origin_pos[2] = _start.z;

    gObjectList[_objectIndex].unk_01C[0] = _end.x * xOrientation;
    gObjectList[_objectIndex].unk_01C[2] = _end.z;

    _count++;
}

void OCrab::SetSpawnParams(SpawnParams& params) {
    params.Name = std::string(ResourceName);
    params.PatrolStart = _start;
    params.PatrolEnd = _end;
}

void OCrab::Tick(void) {
    s32 objectIndex = _objectIndex;
    if (gObjectList[objectIndex].state != 0) {
        OCrab::func_80082B34(objectIndex);
        func_8008A6DC(objectIndex, 500.0f);
        OCrab::func_80082C30(objectIndex);
        OCrab::func_80082E18(objectIndex);
    }
}

Vtx common_vtx_crab[] = {
    { { { -32, -31, 0 }, 0, { 0, 0 }, { 255, 255, 255, 255 } } },
    { { { 31, -31, 0 }, 0, { 4032, 0 }, { 255, 255, 255, 255 } } },
    { { { 31, 31, 0 }, 0, { 4032, 3968 }, { 255, 255, 255, 255 } } },
    { { { -32, 31, 0 }, 0, { 0, 3968 }, { 255, 255, 255, 255 } } },
};

void OCrab::Draw(s32 cameraId) {
    Camera* camera;
    s32 objectIndex = _objectIndex;
    if (gObjectList[objectIndex].state >= 2) {
        camera = &camera1[cameraId];
        FrameInterpolation_RecordOpenChild("crab", (_idx << 5) | cameraId);
        func_8004A6EC(objectIndex, 0.5f);
        FrameInterpolation_RecordCloseChild();
        gObjectList[objectIndex].orientation[1] =
            func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], camera->pos);
        FrameInterpolation_RecordOpenChild("crab2", (_idx << 5) | cameraId);
        rsp_set_matrix_transformation(gObjectList[objectIndex].pos, gObjectList[objectIndex].orientation,
                                      gObjectList[objectIndex].sizeScaling);
        gSPDisplayList(gDisplayListHead++, (Gfx*) D_0D007D78);
        gDPLoadTLUT_pal256(gDisplayListHead++, gObjectList[objectIndex].activeTLUT);
        rsp_load_texture((u8*) gObjectList[objectIndex].activeTexture, 64, 64);
        gSPVertex(gDisplayListHead++, (uintptr_t) common_vtx_crab, 4, 0);
        gSPDisplayList(gDisplayListHead++, (Gfx*) common_rectangle_display);
        gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF);
        FrameInterpolation_RecordCloseChild();
    }
}

void OCrab::DrawModel(s32 cameraId) {
    s32 someIndex;
    s32 objectIndex = _objectIndex;
    func_8008A364(objectIndex, cameraId, 0x2AABU, 800);
    if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) {
        Camera* camera;
        s32 objectIndex;

        if (gObjectList[objectIndex].state >= 2) {
            camera = &camera1[cameraId];
            FrameInterpolation_RecordOpenChild("crab3", (_idx << 5) | cameraId);
            func_8004A6EC(objectIndex, 0.5f);
            FrameInterpolation_RecordCloseChild();
            gObjectList[objectIndex].orientation[1] =
                func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], camera->pos);
            FrameInterpolation_RecordOpenChild("crab4", (_idx << 5) | cameraId);
            rsp_set_matrix_transformation(gObjectList[objectIndex].pos, gObjectList[objectIndex].orientation,
                                          gObjectList[objectIndex].sizeScaling);
            gSPDisplayList(gDisplayListHead++, (Gfx*) D_0D007D78);
            gDPLoadTLUT_pal256(gDisplayListHead++, gObjectList[objectIndex].activeTLUT);
            rsp_load_texture((u8*) gObjectList[objectIndex].activeTexture, 64, 64);
            gSPVertex(gDisplayListHead++, (uintptr_t) common_vtx_crab, 4, 0);
            gSPDisplayList(gDisplayListHead++, (Gfx*) common_rectangle_display);
            gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF);
            FrameInterpolation_RecordCloseChild();
        }
    }
}

void OCrab::init_ktb_crab(s32 objectIndex) {
    Object* object;

    init_texture_object(objectIndex, (uint8_t*) d_course_koopa_troopa_beach_crab_tlut,
                        (const char**) d_course_koopa_troopa_beach_crab_frames, 64, (u16) 64);
    object = &gObjectList[objectIndex];
    object->sizeScaling = 0.15f;
    object->textureListIndex = 0;
    object_next_state(objectIndex);
    object->boundingBoxSize = 1;
    set_object_flag(objectIndex, 0x04000420);
    func_80086EAC(objectIndex, 0, 1);
    set_obj_origin_offset(objectIndex, 0.0f, 0.0f, 0.0f);
    set_obj_orientation(objectIndex, 0U, 0U, 0x8000U);
    object->unk_034 = 1.5f;
    set_object_flag(objectIndex, 0x00000200);
}

void OCrab::func_80082B34(s32 objectIndex) {
    switch (gObjectList[objectIndex].state) { /* irregular */
        case 0:
            break;
        case 1:
            OCrab::init_ktb_crab(objectIndex);
            break;
        case 2:
            func_80072E54(objectIndex, 0, 3, 1, 2, -1);
            break;
        case 3:
            func_80072E54(objectIndex, 4, 6, 1, 2, -1);
            break;
    }
    if (gObjectList[objectIndex].state >= 2) {
        func_80073514(objectIndex);
    }
}

void OCrab::func_80082C30(s32 objectIndex) {
    switch (gObjectList[objectIndex].unk_0AE) {
        case 1:
            if (func_80087A0C(objectIndex, gObjectList[objectIndex].origin_pos[0], gObjectList[objectIndex].unk_01C[0],
                              gObjectList[objectIndex].origin_pos[2], gObjectList[objectIndex].unk_01C[2]) != 0) {
                func_800726CC(objectIndex, 3);
                func_80086FD4(objectIndex);
            }
            break;
        case 2:
            if (func_80087104(objectIndex, 0x003CU) != 0) {
                gObjectList[objectIndex].unk_034 = 0.8f;
                func_800726CC(objectIndex, 2);
                func_80086FD4(objectIndex);
            }
            break;
        case 3:
            if (func_80087954(objectIndex, 0x0000003C) != 0) {
                func_80086FD4(objectIndex);
                func_800726CC(objectIndex, 3);
            }
            break;
        case 4:
            if (func_80087104(objectIndex, 0x003CU) != 0) {
                func_800726CC(objectIndex, 2);
                func_80086FD4(objectIndex);
            }
            break;
        case 5:
            if (func_8008789C(objectIndex, 0x0000003C) != 0) {
                func_800726CC(objectIndex, 3);
                func_8008701C(objectIndex, 2);
            }
            break;
    }
    object_calculate_new_pos_offset(objectIndex);
    if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) {
        func_80088538(objectIndex);
        gObjectList[objectIndex].pos[1] = (f32) (gObjectList[objectIndex].surfaceHeight + 2.5);
    }
}

void OCrab::func_80082E18(s32 objectIndex) {
    if (gObjectList[objectIndex].state >= 2) {
        func_80089F24(objectIndex);
    }
}

void OCrab::DrawEditorProperties() {
    ImGui::Text("Start Location");
    ImGui::SameLine();

    if (ImGui::DragFloat2("##PathSpan", (float*)&_start)) {
    }
    ImGui::SameLine();
    if (ImGui::Button(ICON_FA_UNDO "##ResetPathSpan")) {
        _start = FVector2D(0.0f, 0.0f);
        gObjectList[_objectIndex].pos[0] = gObjectList[_objectIndex].origin_pos[0] = _start.x * xOrientation;
        gObjectList[_objectIndex].pos[2] = gObjectList[_objectIndex].origin_pos[2] = _start.z;
    }

    ImGui::Text("Patrol Location");
    ImGui::SameLine();

    if (ImGui::DragFloat2("##PatrolLoc", (float*)&_end)) {
    }
    ImGui::SameLine();
    if (ImGui::Button(ICON_FA_UNDO "##ResetPatrolLoc")) {
        _end = FVector2D(0.0f, 0.0f);
        gObjectList[_objectIndex].unk_01C[0] = _end.x * xOrientation;
        gObjectList[_objectIndex].unk_01C[2] = _end.z;
    }
}