summaryrefslogtreecommitdiff
path: root/src/engine/objects/Snowman.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine/objects/Snowman.cpp')
-rw-r--r--src/engine/objects/Snowman.cpp343
1 files changed, 343 insertions, 0 deletions
diff --git a/src/engine/objects/Snowman.cpp b/src/engine/objects/Snowman.cpp
new file mode 100644
index 000000000..c05f464ef
--- /dev/null
+++ b/src/engine/objects/Snowman.cpp
@@ -0,0 +1,343 @@
+#include "Snowman.h"
+#include "World.h"
+
+extern "C" {
+#include "render_objects.h"
+#include "update_objects.h"
+#include "assets/frappe_snowland_data.h"
+#include "assets/common_data.h"
+#include "math_util.h"
+#include "math_util_2.h"
+#include "code_80086E70.h"
+#include "code_80057C60.h"
+}
+
+static const char* sSnowmanHeadList[] = { d_course_frappe_snowland_snowman_head };
+
+size_t OSnowman::_count = 0;
+
+OSnowman::OSnowman(const FVector& pos) {
+ _idx = _count;
+ _pos = pos;
+
+ s32 objectId = indexObjectList2[_idx];
+ init_object(objectId, 0);
+ gObjectList[objectId].origin_pos[0] = pos.x * xOrientation;
+ gObjectList[objectId].origin_pos[1] = pos.y + 5.0 + 3.0;
+ gObjectList[objectId].origin_pos[2] = pos.z;
+ gObjectList[objectId].pos[0] = pos.x * xOrientation;
+ gObjectList[objectId].pos[1] = pos.y + 5.0 + 3.0;
+ gObjectList[objectId].pos[2] = pos.z;
+
+ objectId = indexObjectList1[_idx];
+ init_object(objectId, 0);
+ gObjectList[objectId].origin_pos[0] = pos.x * xOrientation;
+ gObjectList[objectId].origin_pos[1] = pos.y + 3.0;
+ gObjectList[objectId].origin_pos[2] = pos.z;
+ gObjectList[objectId].unk_0D5 = 0; // Section Id no longer used.
+
+ gObjectList[objectId].pos[0] = pos.x * xOrientation;
+ gObjectList[objectId].pos[1] = pos.y + 3.0;
+ gObjectList[objectId].pos[2] = pos.z;
+
+ _count++;
+}
+
+void OSnowman::Tick() {
+ s32 var_s0;
+ s32 var_s3;
+ s32 var_s4;
+ s32 objectIndex;
+ Object* object;
+
+ //! @todo quick hack to add the snow particles on hit. Need to separate into its own class
+ if (_idx == 0) {
+ for (var_s0 = 0; var_s0 < gObjectParticle2_SIZE; var_s0++) {
+ objectIndex = gObjectParticle2[var_s0];
+
+ if (objectIndex == DELETED_OBJECT_ID) {
+ continue;
+ }
+
+ if (gObjectList[objectIndex].state == 0) {
+ continue;
+ }
+ func_8008379C(objectIndex);
+ if (gObjectList[objectIndex].state != 0) {
+ continue;
+ }
+ delete_object_wrapper(&gObjectParticle2[var_s0]);
+ if (var_s0) {} // ??
+ }
+ }
+
+ //for (var_s0 = 0; var_s0 < NUM_SNOWMEN; var_s0++) {
+ var_s4 = indexObjectList1[_idx];
+ var_s3 = indexObjectList2[_idx];
+ OSnowman::func_80083A94(var_s3); // snowman head
+ OSnowman::func_80083C04(var_s4); // snowman body
+ if (is_obj_index_flag_status_inactive(var_s4, 0x00001000) != 0) {
+ object = &gObjectList[var_s4];
+ if ((are_players_in_course_section(object->unk_0D5 - 1, object->unk_0D5 + 1) != 0) && (func_80089B50(var_s4) != 0)) {
+ set_object_flag(var_s4, 0x00001000);
+ clear_object_flag(var_s4, 0x00000010);
+ func_800726CC(var_s4, 0x0000000A);
+ func_8008701C(var_s3, 0x0000000A);
+ OSnowman::func_800836F0(object->pos);
+ }
+ } else if (func_80072320(var_s4, 2) != 0) {
+ func_800722CC(var_s4, 2);
+ func_8008701C(var_s3, 0x00000014);
+ }
+ //}
+}
+
+void OSnowman::Draw(s32 cameraId) {
+ OSnowman::DrawHead(cameraId);
+ OSnowman::DrawBody(cameraId);
+}
+
+void OSnowman::func_800836F0(Vec3f pos) {
+ s32 objectIndex;
+ s32 i;
+
+ for (i = 0; i < D_8018D3BC; i++) {
+ objectIndex = add_unused_obj_index(&gObjectParticle2[0], &gNextFreeObjectParticle2, gObjectParticle2_SIZE);
+ if (objectIndex == NULL_OBJECT_ID) {
+ break;
+ }
+ OSnowman::func_80083538(objectIndex, pos, i, D_8018D3BC);
+ }
+}
+
+void OSnowman::DrawHead(s32 cameraId) {
+ s32 objectIndex;
+ Camera* camera = &camera1[cameraId];
+ objectIndex = indexObjectList1[_idx];
+ if (gObjectList[objectIndex].state >= 2) {
+ func_8008A364(objectIndex, cameraId, 0x2AABU, 0x00000258);
+ if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) {
+ D_80183E80[0] = (s16) gObjectList[objectIndex].orientation[0];
+ D_80183E80[1] =
+ func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], camera->pos);
+ D_80183E80[2] = (u16) gObjectList[objectIndex].orientation[2];
+ if (is_obj_flag_status_active(objectIndex, 0x00000010) != 0) {
+ draw_2d_texture_at(gObjectList[objectIndex].pos, (u16*) D_80183E80,
+ gObjectList[objectIndex].sizeScaling, (u8*) gObjectList[objectIndex].activeTLUT,
+ (u8*)gObjectList[objectIndex].activeTexture, gObjectList[objectIndex].vertex,
+ 0x00000040, 0x00000040, 0x00000040, 0x00000020);
+ }
+ objectIndex = indexObjectList2[_idx];
+ D_80183E80[0] = (s16) gObjectList[objectIndex].orientation[0];
+ D_80183E80[2] = (u16) gObjectList[objectIndex].orientation[2];
+ draw_2d_texture_at(gObjectList[objectIndex].pos, (u16*) D_80183E80,
+ gObjectList[objectIndex].sizeScaling, (u8*) gObjectList[objectIndex].activeTLUT,
+ (u8*)gObjectList[objectIndex].activeTexture, gObjectList[objectIndex].vertex, 0x00000040,
+ 0x00000040, 0x00000040, 0x00000020);
+ }
+ }
+}
+
+void OSnowman::DrawBody(s32 cameraId) {
+ UNUSED s32 stackPadding[2];
+ Camera* sp44;
+ s32 someIndex;
+ s32 objectIndex;
+ Object* object;
+
+ sp44 = &camera1[cameraId];
+ load_texture_and_tlut((u8*)d_course_frappe_snowland_snow_tlut, (u8*)d_course_frappe_snowland_snow, 0x00000020, 0x00000020);
+
+ //! @todo quick hack to add the snow particles on hit. Need to separate into its own class
+ if (_idx == 0) {
+ for (someIndex = 0; someIndex < gObjectParticle2_SIZE; someIndex++) {
+ objectIndex = gObjectParticle2[someIndex];
+ if (objectIndex != NULL_OBJECT_ID) {
+ object = &gObjectList[objectIndex];
+ if (object->state > 0) {
+ func_8008A364(objectIndex, cameraId, 0x2AABU, 0x000001F4);
+ if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) {
+ object->orientation[1] = func_800418AC(object->pos[0], object->pos[2], sp44->pos);
+ rsp_set_matrix_gObjectList(objectIndex);
+ gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D0069E0);
+ }
+ }
+ }
+ }
+ }
+ gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF);
+}
+
+void OSnowman::func_80083C04(s32 objectIndex) {
+ Object* object;
+
+ object = &gObjectList[objectIndex];
+ switch (object->state) {
+ case 0:
+ break;
+ case 1:
+ OSnowman::func_80083B0C(objectIndex);
+ break;
+ case 2:
+ set_and_run_timer_object(objectIndex, 0x00000096);
+ break;
+ case 10:
+ if (set_and_run_timer_object(objectIndex, 0x0000012C) != 0) {
+ func_800722A4(objectIndex, 2);
+ }
+ break;
+ case 11:
+ if (set_and_run_timer_object(objectIndex, 0x0000000A) != 0) {
+ set_object_flag(objectIndex, 0x00000010);
+ object->sizeScaling = 0.001f;
+ }
+ break;
+ case 12:
+ if (func_80074118(objectIndex, &object->sizeScaling, 0.001f, 0.1f, 0.0025f, 0, 0) != 0) {
+ object_next_state(objectIndex);
+ }
+ break;
+ case 13:
+ func_800726CC(objectIndex, 2);
+ clear_object_flag(objectIndex, 0x00001000);
+ break;
+ }
+ if (object->state >= 2) {
+ func_80073514(objectIndex);
+ }
+ OSnowman::func_80083BE4(objectIndex);
+}
+
+void OSnowman::func_80083BE4(s32 objectIndex) {
+ object_calculate_new_pos_offset(objectIndex);
+}
+
+void OSnowman::func_80083868(s32 objectIndex) {
+ Object* object;
+ Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(D_0D0061B0);
+ init_texture_object(objectIndex, (u8*)d_course_frappe_snowland_snowman_tlut, (const char**)sSnowmanHeadList, 0x40U, (u16) 0x00000040);
+ object = &gObjectList[objectIndex];
+ object->vertex = vtx;
+ object->sizeScaling = 0.1f;
+ object->textureListIndex = 0;
+ object_next_state(objectIndex);
+ set_obj_origin_offset(objectIndex, 0.0f, 0.0f, 0.0f);
+ object->orientation[0] = 0;
+ object->orientation[1] = 0;
+ object->orientation[2] = 0x8000;
+ object->primAlpha = random_int(0x2000U) - 0x1000;
+ func_80086E70(objectIndex);
+ object->unk_034 = 1.5f;
+ set_object_flag(objectIndex, 0x00000200);
+}
+
+void OSnowman::func_80083948(s32 objectIndex) {
+ switch (gObjectList[objectIndex].unk_0AE) {
+ case 1:
+ func_80086FD4(objectIndex);
+ break;
+ case 2:
+ func_800871AC(objectIndex, 0x00000014);
+ break;
+ case 3:
+ func_8008701C(objectIndex, 1);
+ break;
+ case 10:
+ func_80087C48(objectIndex, 10.0f, 0.5f, 0x0000000A);
+ break;
+ case 11:
+ func_80087D24(objectIndex, 0.0f, 0.2f, -7.0f);
+ break;
+ case 20:
+ if (f32_step_up_towards(&gObjectList[objectIndex].offset[1], 0.0f, 0.2f) != 0) {
+ func_80073800(objectIndex, 0);
+ func_8008701C(objectIndex, 1);
+ }
+ break;
+ case 0:
+ default:
+ break;
+ }
+ object_calculate_new_pos_offset(objectIndex);
+ OSnowman::func_80073D0C(objectIndex, &gObjectList[objectIndex].primAlpha, -0x00001000, 0x00001000, 0x00000400, 1, -1);
+ gObjectList[objectIndex].orientation[2] = gObjectList[objectIndex].primAlpha + 0x8000;
+}
+
+bool OSnowman::func_80073D0C(s32 objectIndex, s16* arg1, s32 arg2, s32 arg3, s32 arg4, s32 arg5, s32 arg6) {
+ return func_80073B78(0, objectIndex, arg1, arg2, arg3, arg4, arg5, arg6);
+}
+
+void OSnowman::func_80083A94(s32 objectIndex) {
+ switch (gObjectList[objectIndex].state) {
+ case 0:
+ break;
+ case 1:
+ OSnowman::func_80083868(objectIndex);
+ break;
+ }
+ if (gObjectList[objectIndex].state >= 2) {
+ func_80073514(objectIndex);
+ }
+ OSnowman::func_80083948(objectIndex);
+}
+
+static const char* sSnowmanBodyList[] = { d_course_frappe_snowland_snowman_body };
+
+void OSnowman::func_80083B0C(s32 objectIndex) {
+ Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(common_vtx_hedgehog);
+ init_texture_object(objectIndex, (u8*)d_course_frappe_snowland_snowman_tlut, (const char**)sSnowmanBodyList, 0x40U, (u16) 0x00000040);
+ gObjectList[objectIndex].vertex = vtx;
+ gObjectList[objectIndex].sizeScaling = 0.1f;
+ gObjectList[objectIndex].textureListIndex = 0;
+ object_next_state(objectIndex);
+ set_obj_origin_offset(objectIndex, 0.0f, 0.0f, 0.0f);
+ gObjectList[objectIndex].orientation[0] = 0;
+ gObjectList[objectIndex].orientation[1] = 0;
+ gObjectList[objectIndex].orientation[2] = 0x8000;
+ gObjectList[objectIndex].boundingBoxSize = 2;
+ gObjectList[objectIndex].unk_034 = 1.5f;
+ set_object_flag(objectIndex, 0x04000210);
+}
+
+
+void OSnowman::func_80083538(s32 objectIndex, Vec3f arg1, s32 arg2, s32 arg3) {
+ Object* object;
+
+ init_object(objectIndex, 0);
+ object = &gObjectList[objectIndex];
+ object->activeTexture = (const char*)d_course_frappe_snowland_snow;
+ object->textureList = (const char**)d_course_frappe_snowland_snow;
+ object->activeTLUT = d_course_frappe_snowland_snow_tlut;
+ object->tlutList = (u8*)d_course_frappe_snowland_snow_tlut;
+ object->sizeScaling = random_int(0x0064U);
+ object->sizeScaling = (object->sizeScaling * 0.001) + 0.05;
+ object->velocity[1] = random_int(0x0014U);
+ object->velocity[1] = (object->velocity[1] * 0.5) + 2.6;
+ object->unk_034 = random_int(0x000AU);
+ object->unk_034 = (object->unk_034 * 0.1) + 4.5;
+ object->direction_angle[1] = (arg2 << 0x10) / arg3;
+ object->origin_pos[0] = arg1[0];
+ object->origin_pos[1] = arg1[1];
+ object->origin_pos[2] = arg1[2];
+ object->primAlpha = random_int(0x4000U) + 0x1000;
+}
+
+void OSnowman::func_8008379C(s32 objectIndex) {
+ switch (gObjectList[objectIndex].state) {
+ case 0:
+ break;
+ case 1:
+ if (func_80087E08(objectIndex, gObjectList[objectIndex].velocity[1], 0.74f,
+ gObjectList[objectIndex].unk_034, gObjectList[objectIndex].direction_angle[1],
+ 0x00000064) != 0) {
+ object_next_state(objectIndex);
+ }
+ break;
+ case 2:
+ func_80086F60(objectIndex);
+ func_80072428(objectIndex);
+ break;
+ }
+ object_calculate_new_pos_offset(objectIndex);
+ gObjectList[objectIndex].orientation[2] += gObjectList[objectIndex].primAlpha;
+}