summaryrefslogtreecommitdiff
path: root/src/engine/objects/Penguin.cpp
diff options
context:
space:
mode:
authorMegaMech <7255464+MegaMech@users.noreply.github.com>2024-12-11 20:58:18 -0700
committerMegaMech <7255464+MegaMech@users.noreply.github.com>2024-12-11 20:58:18 -0700
commit95b8cca50025f7fa10e47ca24ac5f71f9813a2e3 (patch)
treedcb7bc04eb38b8f98b6348f4b15a46124aa51faf /src/engine/objects/Penguin.cpp
parenta4890f9dfcc993f3001d491395294f6836cdc0dc (diff)
Reimplementing objects
Diffstat (limited to 'src/engine/objects/Penguin.cpp')
-rw-r--r--src/engine/objects/Penguin.cpp409
1 files changed, 409 insertions, 0 deletions
diff --git a/src/engine/objects/Penguin.cpp b/src/engine/objects/Penguin.cpp
new file mode 100644
index 000000000..c126174a1
--- /dev/null
+++ b/src/engine/objects/Penguin.cpp
@@ -0,0 +1,409 @@
+#include <libultraship.h>
+#include <libultra/gbi.h>
+#include "Penguin.h"
+#include <vector>
+
+#include "port/Game.h"
+
+extern "C" {
+#include "macros.h"
+#include "main.h"
+#include "actors.h"
+#include "math_util.h"
+#include "sounds.h"
+#include "update_objects.h"
+#include "render_player.h"
+#include "external.h"
+#include "bomb_kart.h"
+#include "collision.h"
+#include "code_80086E70.h"
+#include "render_objects.h"
+#include "code_80057C60.h"
+#include "defines.h"
+#include "code_80005FD0.h"
+#include "math_util_2.h"
+#include "collision.h"
+#include "assets/bowsers_castle_data.h"
+#include "ceremony_and_credits.h"
+#include "objects.h"
+#include "update_objects.h"
+#include "render_objects.h"
+#include "course_offsets.h"
+#include "data/some_data.h"
+extern s8 gPlayerCount;
+}
+
+OPenguin::OPenguin(s32 i, Vec3f pos, u16 direction, PenguinType type, Behaviour behaviour) {
+ if (i >= 32) {
+ printf("MAX penguin REACHED (32), skipping\n");
+ return;
+ }
+ _idx = i;
+ _type = type;
+ _bhv = behaviour;
+
+ s32 objectIndex = indexObjectList1[i];
+ init_object(objectIndex, 0);
+
+ Object *object = &gObjectList[objectIndex];
+ object->origin_pos[0] = pos[0] * xOrientation;
+ object->origin_pos[1] = pos[1];
+ object->origin_pos[2] = pos[2];
+ object->unk_0C6 = direction;
+
+ switch(type) {
+ case PenguinType::CHICK:
+ object->surfaceHeight = 5.0f;
+ object->sizeScaling = 0.04f;
+ object->boundingBoxSize = 4;
+ break;
+ case PenguinType::ADULT:
+ object->surfaceHeight = -80.0f;
+ object->sizeScaling = 0.08f;
+ object->boundingBoxSize = 4;
+ break;
+ case PenguinType::CREDITS:
+ object->surfaceHeight = -80.0f;
+ object->sizeScaling = 0.08f;
+ object->sizeScaling = 0.15f;
+ break;
+ case PenguinType::EMPEROR:
+ object->sizeScaling = 0.2f;
+ object->boundingBoxSize = 0x000C;
+ break;
+ }
+
+}
+
+void OPenguin::Tick(void) {
+ s32 objectIndex;
+
+ objectIndex = indexObjectList1[_idx];
+ if (gObjectList[objectIndex].state != 0) {
+ if (_type == PenguinType::EMPEROR) {
+ OPenguin::EmperorPenguin(objectIndex);
+ } else {
+ OPenguin::OtherPenguin(objectIndex);
+ }
+
+ OPenguin::Behaviours(objectIndex, _idx);
+ }
+ if (func_80072320(objectIndex, 1) != 0) {
+ func_80089820(objectIndex, 1.75f, 1.5f, 0x1900A046U);
+ } else if (func_80072320(objectIndex, 8) != 0) {
+ func_80089820(objectIndex, 1.3f, 1.0f, 0x1900A046U);
+ } else {
+ func_80089820(objectIndex, 1.5f, 1.25f, 0x1900A046U);
+ }
+ if ((is_obj_flag_status_active(objectIndex, 0x02000000) != 0) &&
+ (func_80072354(objectIndex, 0x00000020) != 0)) {
+ func_800722A4(objectIndex, 0x00000060);
+ clear_object_flag(objectIndex, 0x02000000);
+ }
+}
+
+void OPenguin::Draw(s32 cameraId) {
+ s32 objectIndex;
+ s32 temp_s1;
+ s32 drawDistance;
+ u16 var_s1;
+ u32 var_s3;
+
+ if (gPlayerCountSelection1 == 1) {
+ var_s3 = 0x0003D090;
+ } else if (gPlayerCountSelection1 == 2) {
+ var_s3 = 0x00027100;
+ } else {
+ var_s3 = 0x00015F90;
+ }
+
+ objectIndex = indexObjectList1[_idx];
+ if (gObjectList[objectIndex].state >= 2) {
+ if (gPlayerCountSelection1 == 1) {
+ var_s1 = 0x4000;
+ if (_idx == 0) {
+ drawDistance = 0x000005DC;
+ } else if (func_80072320(objectIndex, 8) != 0) {
+ drawDistance = 0x00000320;
+ } else {
+ drawDistance = 0x000003E8;
+ }
+ } else {
+ if (func_80072320(objectIndex, 8) != 0) {
+ drawDistance = 0x000001F4;
+ var_s1 = 0x4000;
+ } else {
+ drawDistance = 0x00000258;
+ var_s1 = 0x5555;
+ }
+ }
+ temp_s1 = func_8008A364(objectIndex, cameraId, var_s1, drawDistance);
+ if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) {
+ func_800557B4(objectIndex, (u32) temp_s1, var_s3);
+ }
+ }
+}
+
+void OPenguin::Behaviours(s32 objectIndex, s32 arg1) { // func_800850B0
+ Object* object;
+
+ object = &gObjectList[objectIndex];
+ switch (_bhv) {
+ case 1: // emperor
+ OPenguin::func_80085080(objectIndex);
+ break;
+ case 2:
+ OPenguin::func_8008502C(objectIndex, arg1);
+ break;
+ case 3:
+ OPenguin::func_80084D2C(objectIndex, 0);
+ break;
+ case 4:
+ OPenguin::func_80084D2C(objectIndex, 1);
+ break;
+ case 5:
+ OPenguin::func_80084D2C(objectIndex, 2);
+ break;
+ case 6:
+ OPenguin::func_80084D2C(objectIndex, 3);
+ break;
+ }
+ if (func_80072320(objectIndex, 0x00000020) != 0) {
+ if (func_80072320(objectIndex, 0x00000040) != 0) {
+ func_800722CC(objectIndex, 0x00000040);
+ object->unk_084[6] = 0;
+ object->unk_084[7] = 0x0096;
+ }
+ if (object->unk_084[7] == 0) {
+ func_800722CC(objectIndex, 0x00000020);
+ } else {
+ object->unk_084[7]--;
+ object->orientation[0] = object->direction_angle[0];
+ object->orientation[1] += 0x2000;
+ object->orientation[2] = object->direction_angle[2];
+ }
+ } else {
+ object->orientation[0] = object->direction_angle[0];
+ object->orientation[1] = object->direction_angle[1];
+ object->orientation[2] = object->direction_angle[2];
+ }
+}
+
+void OPenguin::func_80084D2C(s32 objectIndex, s32 arg1) {
+ f32 sp24;
+
+ switch (gObjectList[objectIndex].unk_0AE) {
+ case 0:
+ break;
+ case 1:
+ gObjectList[objectIndex].direction_angle[1] =
+ func_800417B4(gObjectList[objectIndex].direction_angle[1], gObjectList[objectIndex].unk_0C6);
+ if (gObjectList[objectIndex].direction_angle[1] == gObjectList[objectIndex].unk_0C6) {
+ gObjectList[objectIndex].unk_09C = 4;
+ gObjectList[objectIndex].unk_034 = 0.4f;
+ func_80086FD4(objectIndex);
+ }
+ break;
+ case 2:
+ f32_step_towards(&gObjectList[objectIndex].unk_034, 0.8f, 0.02f);
+ if (func_80087060(objectIndex, 0x0000000F) != 0) {
+ func_800722A4(objectIndex, 1);
+ func_800722A4(objectIndex, 2);
+ gObjectList[objectIndex].unk_09C = 1;
+ gObjectList[objectIndex].unk_0D8 = 1;
+ gObjectList[objectIndex].textureListIndex = 0;
+ gObjectList[objectIndex].type =
+ get_animation_length(d_course_sherbet_land_unk_data11, gObjectList[objectIndex].unk_0D8);
+ func_800726CC(objectIndex, 3);
+ func_80086FD4(objectIndex);
+ if (func_80072354(objectIndex, 0x00000020) != 0) {
+ func_800722A4(objectIndex, 0x00000080);
+ }
+ }
+ break;
+ case 3:
+ switch (arg1) { /* switch 1; irregular */
+ case 0: /* switch 1 */
+ sp24 = 1.0f;
+ break;
+ case 1: /* switch 1 */
+ sp24 = 1.5f;
+ break;
+ case 2: /* switch 1 */
+ sp24 = 2.0f;
+ break;
+ case 3: /* switch 1 */
+ sp24 = 2.5f;
+ break;
+ }
+ f32_step_towards(&gObjectList[objectIndex].unk_034, sp24, 0.15f);
+ if ((func_80072354(objectIndex, 2) != 0) && (sp24 == gObjectList[objectIndex].unk_034)) {
+ func_80086FD4(objectIndex);
+ }
+ break;
+ case 4:
+ if (func_80087060(objectIndex, 0x0000001E) != 0) {
+ func_800722CC(objectIndex, 1);
+ func_80086FD4(objectIndex);
+ }
+ break;
+ case 5:
+ f32_step_towards(&gObjectList[objectIndex].unk_034, 0.4f, 0.2f);
+ if (func_80087060(objectIndex, 0x0000000A) != 0) {
+ func_800722A4(objectIndex, 2);
+ gObjectList[objectIndex].unk_0D8 = 2;
+ gObjectList[objectIndex].textureListIndex = 0;
+ gObjectList[objectIndex].type =
+ get_animation_length(d_course_sherbet_land_unk_data11, gObjectList[objectIndex].unk_0D8);
+ func_800726CC(objectIndex, 3);
+ func_80086FD4(objectIndex);
+ }
+ break;
+ case 6:
+ if (func_80072354(objectIndex, 2) != 0) {
+ gObjectList[objectIndex].unk_0D8 = 0;
+ gObjectList[objectIndex].textureListIndex = 0;
+ gObjectList[objectIndex].type =
+ get_animation_length(d_course_sherbet_land_unk_data11, gObjectList[objectIndex].unk_0D8);
+ gObjectList[objectIndex].unk_0C6 += 0x8000;
+ func_800726CC(objectIndex, 2);
+ func_8008701C(objectIndex, 1);
+ }
+ break;
+ }
+ func_8008781C(objectIndex);
+ object_calculate_new_pos_offset(objectIndex);
+}
+
+void OPenguin::func_80085080(s32 objectIndex) {
+ func_8008B78C(objectIndex);
+ object_calculate_new_pos_offset(objectIndex);
+ func_800873F4(objectIndex);
+}
+
+void OPenguin::func_8008502C(s32 objectIndex, s32 arg1) {
+ func_80088038(objectIndex, gObjectList[objectIndex].unk_01C[1], gObjectList[objectIndex].unk_0C6);
+ object_calculate_new_pos_offset(objectIndex);
+ func_800873F4(objectIndex);
+}
+
+
+void OPenguin::EmperorPenguin(s32 objectIndex) {
+ switch (gObjectList[objectIndex].state) {
+ case 0:
+ break;
+ case 1:
+ OPenguin::InitEmperorPenguin(objectIndex);
+ break;
+ case 2:
+ func_80072E54(objectIndex, 0, gObjectList[objectIndex].type, 1, 0, -1);
+ break;
+ }
+}
+
+void OPenguin::InitEmperorPenguin(s32 objectIndex) {
+ Object* object;
+
+ object = &gObjectList[objectIndex];
+ object->unk_0D8 = 0;
+ object->model = (Gfx*) d_course_sherbet_land_unk_data1;
+ object->vertex = (Vtx*) d_course_sherbet_land_unk_data11;
+ //object->sizeScaling = 0.2f;
+ //object->boundingBoxSize = 0x000C;
+ object->unk_09C = 1;
+ set_obj_direction_angle(objectIndex, 0U, 0U, 0U);
+ object->unk_0DD = 1;
+ func_80086EF0(objectIndex);
+ object->spline = D_800E672C[0];
+ set_object_flag(objectIndex, 0x04000800);
+ object->type = get_animation_length(d_course_sherbet_land_unk_data11, 0);
+ object_next_state(objectIndex);
+}
+
+void OPenguin::OtherPenguin(s32 objectIndex) {
+ Object* object;
+
+ object = &gObjectList[objectIndex];
+ switch (object->state) {
+ case 0:
+ break;
+ case 1:
+ OPenguin::InitOtherPenguin(objectIndex);
+ break;
+ case 2:
+ func_80072E54(objectIndex, 0, (s32) object->type, (s32) object->unk_09C, 0, -1);
+ if (func_80072354(objectIndex, 0x00000020) != 0) {
+ if (object->unk_084[6] == 0) {
+ object->unk_084[6] = random_int(0x005AU) + 0x5A;
+ func_800722A4(objectIndex, 0x00000080);
+ } else {
+ object->unk_084[6]--;
+ }
+ }
+ break;
+ case 3:
+ func_80072E54(objectIndex, 0, object->type, 1, 0, 0);
+ break;
+ case 4:
+ func_800722CC(objectIndex, 2);
+ object_next_state(objectIndex);
+ break;
+ }
+ if (func_80072320(objectIndex, 0x00000020) != 0) {
+ if (object->unk_084[6] == 0) {
+ func_800722A4(objectIndex, 0x00000080);
+ object->unk_084[6] = 0x0010;
+ } else {
+ object->unk_084[6]--;
+ }
+ }
+ if (func_80072320(objectIndex, 0x00000080) != 0) {
+ func_800722CC(objectIndex, 0x00000080);
+ if (func_80072320(objectIndex, 0x00000010) != 0) {
+ func_800C98B8(object->pos, object->velocity, SOUND_ARG_LOAD(0x19, 0x00, 0x70, 0x49));
+ } else {
+ func_800C98B8(object->pos, object->velocity, SOUND_ARG_LOAD(0x19, 0x00, 0x70, 0x17));
+ }
+ }
+}
+
+void OPenguin::InitOtherPenguin(s32 objectIndex) {
+ Object* object;
+
+ object = &gObjectList[objectIndex];
+ object->unk_0D8 = 0;
+ object->model = (Gfx*) d_course_sherbet_land_unk_data1;
+ object->vertex = (Vtx*) d_course_sherbet_land_unk_data11;
+ //object->boundingBoxSize = 4;
+ object->unk_09C = 2;
+ object->unk_04C = random_int(0x012CU);
+ set_object_flag(objectIndex, 0x04000220);
+
+ // This code has been significantly refactored from the original func_800845C8
+ // Into a switch statement instead of checking for the index of the penguin
+ switch(_bhv) {
+ case Behaviour::CIRCLE:
+ object->unk_01C[1] = Diameter;
+ object->unk_0C4 = (_idx << 0xF) & 0xFFFF;
+ //object->unk_0DD = 2;
+ func_800722A4(objectIndex, 8);
+ break;
+ case Behaviour::SLIDE3:
+ case Behaviour::SLIDE4:
+ case Behaviour::SLIDE6:
+ case Behaviour::STRUT:
+
+ if (gIsMirrorMode) {
+ object->unk_0C6 = MirrorModeAngleOffset;
+ }
+
+ set_obj_direction_angle(objectIndex, 0U, object->unk_0C6 + 0x8000, 0U);
+ func_800722A4(objectIndex, 20);
+ break;
+ }
+
+ func_80086EF0(objectIndex);
+ object->unk_034 = 0.0f;
+ object->type = get_animation_length(d_course_sherbet_land_unk_data11, 0);
+ object_next_state(objectIndex);
+}