summaryrefslogtreecommitdiff
path: root/src/engine
diff options
context:
space:
mode:
authorMegaMech <inkstudios1@hotmail.com>2024-12-16 16:42:17 -0700
committerMegaMech <inkstudios1@hotmail.com>2024-12-16 16:42:17 -0700
commit60014ec46695fb964a685d6a17d5fc63e02ab7b8 (patch)
tree7b7f58cb395ce42008c5e08d30d43eff2de0743d /src/engine
parent7f22f75db7fa7a1b2149bc953d2a159c52bc5e8b (diff)
More changes
Diffstat (limited to 'src/engine')
-rw-r--r--src/engine/World.h47
-rw-r--r--src/engine/courses/BansheeBoardwalk.cpp8
-rw-r--r--src/engine/courses/PodiumCeremony.cpp41
-rw-r--r--src/engine/courses/TestCourse.cpp7
-rw-r--r--src/engine/objects/CheepCheep.cpp244
-rw-r--r--src/engine/objects/CheepCheep.h48
-rw-r--r--src/engine/objects/Mole.cpp2
-rw-r--r--src/engine/objects/Mole.h6
-rw-r--r--src/engine/objects/Podium.cpp140
-rw-r--r--src/engine/objects/Podium.h38
-rw-r--r--src/engine/objects/Seagull.cpp5
-rw-r--r--src/engine/objects/Trophy.cpp1
-rw-r--r--src/engine/objects/Trophy.h13
-rw-r--r--src/engine/particles/ParticleEmitter.cpp13
-rw-r--r--src/engine/particles/ParticleEmitter.h23
-rw-r--r--src/engine/particles/StarEmitter.cpp31
-rw-r--r--src/engine/particles/StarEmitter.h42
17 files changed, 684 insertions, 25 deletions
diff --git a/src/engine/World.h b/src/engine/World.h
index 3b48284e8..a90ff7441 100644
--- a/src/engine/World.h
+++ b/src/engine/World.h
@@ -22,6 +22,53 @@ extern "C" {
#include "engine/Engine.h"
};
+struct FVector {
+ float x, y, z;
+
+ FVector& operator=(const FVector& other) {
+ x = other.x;
+ y = other.y;
+ z = other.z;
+ return *this;
+ }
+};
+
+/**
+ * For selecting a section of a course path
+ * Usage: IPathSpan(point1, point2) --> IPathSpan(40, 65)
+ */
+struct IPathSpan {
+ int Start, End;
+
+ // Default Constructor
+ IPathSpan() : Start(0), End(0) {}
+
+ // Parameterized Constructor
+ IPathSpan(int InStart, int InEnd)
+ : Start(InStart), End(InEnd) {}
+
+ // Copy Assignment Operator
+ IPathSpan& operator=(const IPathSpan& Other) {
+ if (this != &Other) { // Avoid self-assignment
+ Start = Other.Start;
+ End = Other.End;
+ }
+ return *this;
+ }
+
+ // Equality Operator
+ bool operator==(const IPathSpan& Other) const {
+ return Start == Other.Start && End == Other.End;
+ }
+
+ // Inequality Operator
+ bool operator!=(const IPathSpan& Other) const {
+ return !(*this == Other);
+ }
+};
+
+
+
class OObject;
class Cup; // <-- Forward declaration
class Course;
diff --git a/src/engine/courses/BansheeBoardwalk.cpp b/src/engine/courses/BansheeBoardwalk.cpp
index 9983ac0b7..80549ac90 100644
--- a/src/engine/courses/BansheeBoardwalk.cpp
+++ b/src/engine/courses/BansheeBoardwalk.cpp
@@ -7,6 +7,7 @@
#include "World.h"
#include "engine/actors/AFinishline.h"
#include "engine/objects/BombKart.h"
+#include "engine/objects/CheepCheep.h"
#include "assets/banshee_boardwalk_data.h"
#include "assets/boo_frames.h"
@@ -150,6 +151,9 @@ void BansheeBoardwalk::SpawnActors() {
gWorldInstance.AddActor(new AFinishline());
spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_banshee_boardwalk_item_box_spawns));
+
+
+ gWorldInstance.AddObject(new OCheepCheep(FVector(xOrientation * -1650.0, -200.0f, -1650.0f), OCheepCheep::CheepType::RACE, IPathSpan(160, 170)));
}
void BansheeBoardwalk::SpawnVehicles() {
@@ -199,7 +203,7 @@ void BansheeBoardwalk::UpdateCourseObjects() {
update_bat();
}
wrapper_update_boos();
- update_cheep_cheep(0);
+ //update_cheep_cheep(0);
}
}
@@ -207,7 +211,7 @@ void BansheeBoardwalk::RenderCourseObjects(s32 cameraId) {
if (gGamestate != CREDITS_SEQUENCE) {
render_object_trash_bin(cameraId);
render_object_bat(cameraId);
- func_8005217C(cameraId);
+ //func_8005217C(cameraId); // render cheep cheep
render_object_boos(cameraId);
}
}
diff --git a/src/engine/courses/PodiumCeremony.cpp b/src/engine/courses/PodiumCeremony.cpp
index e05b54e51..6f04bd291 100644
--- a/src/engine/courses/PodiumCeremony.cpp
+++ b/src/engine/courses/PodiumCeremony.cpp
@@ -8,6 +8,9 @@
#include "engine/objects/BombKart.h"
#include "assets/royal_raceway_data.h"
#include "assets/ceremony_data.h"
+#include "engine/objects/Trophy.h"
+#include "engine/objects/Podium.h"
+#include "engine/objects/CheepCheep.h"
extern "C" {
#include "main.h"
@@ -30,6 +33,7 @@ extern "C" {
#include "collision.h"
#include "memory.h"
#include "courses/staff_ghost_data.h"
+ #include "podium_ceremony_actors.h"
extern const char *royal_raceway_dls[];
}
@@ -160,6 +164,43 @@ void PodiumCeremony::SpawnActors() {
spawn_foliage((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_royal_raceway_tree_spawn));
spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_royal_raceway_item_box_spawns));
spawn_piranha_plants((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_royal_raceway_piranha_plant_spawn));
+
+ gWorldInstance.AddObject(new OCheepCheep(FVector((f32)0xf37e, (f32)0x0013, (f32)0xfe22), OCheepCheep::CheepType::PODIUM_CEREMONY, IPathSpan(0, 0)));
+ gWorldInstance.AddObject(new OPodium(FVector((f32)0xf37e, (f32)0x0013, (f32)0xfe22)));
+
+ FVector pos = {0,0,0};
+ pos.y = 90.0f;
+ OTrophy::TrophyType type = OTrophy::TrophyType::BRONZE;
+ switch(D_802874D8.unk1D) {
+ case 0: // Bronze
+ if (gCCSelection == CC_150) {
+ OTrophy::TrophyType::BRONZE_150;
+ } else {
+ OTrophy::TrophyType::BRONZE;
+ }
+ break;
+ case 1: // Silver
+ pos.x -= 3.0;
+ pos.z += 15.0;
+
+ if (gCCSelection == CC_150) {
+ OTrophy::TrophyType::SILVER_150;
+ } else {
+ OTrophy::TrophyType::SILVER;
+ }
+ break;
+ case 2: // Gold
+ pos.x -= 2.0;
+ pos.z -= 15.0;
+ if (gCCSelection == CC_150) {
+ OTrophy::TrophyType::GOLD_150;
+ } else {
+ OTrophy::TrophyType::GOLD;
+ }
+ break;
+ }
+
+ gWorldInstance.AddObject(new OTrophy(pos, type, OTrophy::Behaviour::PODIUM_CEREMONY));
}
void PodiumCeremony::SpawnVehicles() {
diff --git a/src/engine/courses/TestCourse.cpp b/src/engine/courses/TestCourse.cpp
index 2750c727f..465f97012 100644
--- a/src/engine/courses/TestCourse.cpp
+++ b/src/engine/courses/TestCourse.cpp
@@ -14,6 +14,7 @@
#include "engine/actors/ACloud.h"
#include "engine/vehicles/Train.h"
#include "engine/objects/Trophy.h"
+#include "engine/objects/CheepCheep.h"
extern "C" {
#include "main.h"
@@ -189,14 +190,14 @@ void TestCourse::SpawnActors() {
rrxing->crossingTrigger = crossing1;
Vec3f pos = {0, 80, 0};
- //gWorldInstance.AddActor(new ACloud(pos));
+ // gWorldInstance.AddActor(new ACloud(pos));
// gWorldInstance.AddActor(new OSeagull(0, pos));
// gWorldInstance.AddActor(new OSeagull(1, pos));
// gWorldInstance.AddActor(new OSeagull(2, pos));
// gWorldInstance.AddActor(new OSeagull(3, pos));
-
- gWorldInstance.AddObject(new OTrophy(FVector(0,0,0), OTrophy::TrophyType::GOLD, OTrophy::Behaviour::GO_FISH));
+ gWorldInstance.AddObject(new OCheepCheep(FVector(0, 40, 0), OCheepCheep::CheepType::RACE, IPathSpan(0, 10)));
+ //gWorldInstance.AddObject(new OTrophy(FVector(0,0,0), OTrophy::TrophyType::GOLD, OTrophy::Behaviour::GO_FISH));
}
// Likely sets minimap boundaries
diff --git a/src/engine/objects/CheepCheep.cpp b/src/engine/objects/CheepCheep.cpp
new file mode 100644
index 000000000..e81ba7c24
--- /dev/null
+++ b/src/engine/objects/CheepCheep.cpp
@@ -0,0 +1,244 @@
+#include "CheepCheep.h"
+
+#include "assets/banshee_boardwalk_data.h"
+#include "assets/common_data.h"
+
+extern "C" {
+#include "math_util.h"
+#include "math_util_2.h"
+#include "render_objects.h"
+#include "update_objects.h"
+#include "code_800029B0.h"
+#include "code_80086E70.h"
+#include "waypoints.h"
+#include "code_80057C60.h"
+#include "some_data.h"
+extern Vec3s D_800E634C[];
+extern Lights1 D_800E45C0[];
+}
+
+OCheepCheep::OCheepCheep(const FVector& pos, CheepType type, IPathSpan span) {
+ _type = type;
+ _spawnPos = pos;
+ _span = span;
+}
+
+void OCheepCheep::Tick() { // update_cheep_cheep
+ s32 objectIndex;
+ switch (_type) {
+ case CheepType::RACE:
+ UNUSED s32 pad;
+
+ OCheepCheep::func_8007BD04(0);
+ objectIndex = indexObjectList2[0];
+ OCheepCheep::func_8007BBBC(objectIndex);
+ object_calculate_new_pos_offset(objectIndex);
+ break;
+ case CheepType::PODIUM_CEREMONY:
+ objectIndex = indexObjectList2[0];
+ if (D_801658BC == 1) {
+ D_801658BC = 0;
+ init_object(objectIndex, 0);
+ }
+ if (gObjectList[objectIndex].state != 0) {
+ OCheepCheep::func_8007BEC8(objectIndex);
+ OCheepCheep::func_8007BFB0(objectIndex);
+ }
+ break;
+ }
+}
+
+void OCheepCheep::Draw(s32 cameraId) { // func_8005217C
+ Lights1* D_800E45C0l = (Lights1*) (D_800E45C0);
+ Object* object;
+ s32 temp_a3;
+
+ temp_a3 = indexObjectList2[0];
+ object = &gObjectList[temp_a3];
+ if (object->state >= 2) {
+ if (is_obj_flag_status_active(temp_a3, 0x10) != 0) {
+ rsp_set_matrix_transformation(object->pos, object->direction_angle, object->sizeScaling);
+ func_800520C0(temp_a3);
+
+ gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D007828);
+ gSPLight(gDisplayListHead++, &D_800E45C0l[0].l[0], LIGHT_1);
+ gSPLight(gDisplayListHead++, &D_800E45C0l[0].a, LIGHT_2);
+ gSPDisplayList(gDisplayListHead++, (Gfx*)d_course_banshee_boardwalk_dl_7B38);
+ gSPLight(gDisplayListHead++, &D_800E45C0l[1].l[0], LIGHT_1);
+ gSPLight(gDisplayListHead++, &D_800E45C0l[1].a, LIGHT_2);
+ gSPDisplayList(gDisplayListHead++, (Gfx*)d_course_banshee_boardwalk_dl_7978);
+ gSPLight(gDisplayListHead++, &D_800E45C0l[2].l[0], LIGHT_1);
+ gSPLight(gDisplayListHead++, &D_800E45C0l[2].a, LIGHT_2);
+ gSPDisplayList(gDisplayListHead++, (Gfx*)d_course_banshee_boardwalk_dl_78C0);
+ gSPLight(gDisplayListHead++, &D_800E45C0l[3].l[0], LIGHT_1);
+ gSPLight(gDisplayListHead++, &D_800E45C0l[3].a, LIGHT_2);
+ gSPDisplayList(gDisplayListHead++, (Gfx*)d_course_banshee_boardwalk_dl_7650);
+ }
+ }
+}
+
+void OCheepCheep::func_8007BBBC(s32 objectIndex) {
+ f32 var_f14;
+ Object* object;
+
+ object = &gObjectList[objectIndex];
+ switch (object->state) {
+ case 1:
+ func_800735BC(objectIndex, (Gfx*)d_course_banshee_boardwalk_dl_cheep_cheep, 2.0f);
+ set_object_flag(objectIndex, 0x00000010);
+ object->unk_0D5 = 0;
+ break;
+ case 2:
+ if (gIsMirrorMode != 0) {
+ func_80087E08(objectIndex, 18.0f, 0.7f, 25.0f, (s16) -0x00005800, 0x0000012C);
+ } else {
+ func_80087E08(objectIndex, 18.0f, 0.7f, 25.0f, (s16) 0x00005800, 0x0000012C);
+ }
+ if (object->velocity[2] < 0.0f) {
+ var_f14 = -object->velocity[2];
+ } else {
+ var_f14 = object->velocity[2];
+ }
+ object->direction_angle[0] = func_80041658(object->velocity[1], var_f14);
+ set_and_run_timer_object(objectIndex, 0x00000046);
+ break;
+ case 3:
+ func_80072428(objectIndex);
+ break;
+ case 0:
+ break;
+ }
+}
+
+void OCheepCheep::func_8007BD04(s32 playerId) {
+ s32 objectIndex;
+
+ objectIndex = indexObjectList2[0];
+ if (gObjectList[objectIndex].state == 0) {
+ if (((s32) gNearestWaypointByPlayerId[playerId] >= _span.Start) &&
+ ((s32) gNearestWaypointByPlayerId[playerId] <= _span.End)) {
+ set_obj_origin_pos(objectIndex, xOrientation * _spawnPos.x, _spawnPos.y, _spawnPos.z);
+ init_object(objectIndex, 1);
+ }
+ }
+}
+
+void OCheepCheep::init_var_cheep_cheep(s32 objectIndex) {
+ Object* object;
+
+ object = &gObjectList[objectIndex];
+ object->unk_0D5 = 1;
+ object->status = 0;
+ object->model = (Gfx*)d_course_banshee_boardwalk_dl_cheep_cheep;
+ object->sizeScaling = 0.2f;
+ object_next_state(objectIndex);
+ set_obj_origin_pos(objectIndex, D_800E634C[0][0], D_800E634C[0][1] + 55.0, D_800E634C[0][2]);
+ set_obj_origin_offset(objectIndex, 0.0f, 30.0f, 0.0f);
+ set_obj_direction_angle(objectIndex, 0U, 0x3800U, 0U);
+}
+
+void OCheepCheep::func_8007BEC8(s32 objectIndex) {
+ Object* object;
+
+ object = &gObjectList[objectIndex];
+ switch (object->state) {
+ case 1:
+ OCheepCheep::init_var_cheep_cheep(objectIndex);
+ break;
+ case 2:
+ if (set_and_run_timer_object(objectIndex, 0x0000003C) != 0) {
+ set_object_flag(objectIndex, 0x00000010);
+ func_80086E70(objectIndex);
+ }
+ break;
+ case 3:
+ if (object->unk_0AE == 0) {
+ object_next_state(objectIndex);
+ }
+ break;
+ case 4:
+ if (set_and_run_timer_object(objectIndex, 0x0000000A) != 0) {
+ func_8008701C(objectIndex, 2);
+ }
+ break;
+ case 5:
+ if (object->unk_0AE == 0) {
+ func_80072428(objectIndex);
+ }
+ break;
+ case 0:
+ default:
+ break;
+ }
+}
+
+void OCheepCheep::func_8007BFB0(s32 objectIndex) {
+ Object* object;
+
+ object = &gObjectList[objectIndex];
+ switch (object->unk_0AE) {
+ case 0:
+ break;
+ case 1:
+ object->velocity[1] = -0.2f;
+ if ((f64) object->offset[1] <= 0.0) {
+ object->offset[1] = 0.0f;
+ object->velocity[1] = 0.0f;
+ func_80086F60(objectIndex);
+ }
+ break;
+ case 2:
+ if (func_800871AC(objectIndex, 0x00000014) != 0) {
+ object->unk_084[7] = 0x0040;
+ }
+ break;
+ case 3:
+ object->sizeScaling = (f32) ((f64) object->sizeScaling - 0.0015);
+ if ((s32) object->direction_angle[0] >= 0xA01) {
+ object->unk_084[7] -= 4;
+ }
+ if (u16_step_up_towards(object->direction_angle, 0x0C00U, (u16) object->unk_084[7]) != 0) {
+ func_80086FD4(objectIndex);
+ }
+ break;
+ case 4:
+ object->sizeScaling = (f32) ((f64) object->sizeScaling - 0.0015);
+ object->unk_034 = 0.001f;
+ func_80086FD4(objectIndex);
+ object->unk_084[7] = 0;
+ break;
+ case 5:
+ if (object->unk_034 <= 0.004) {
+ object->unk_034 += 0.0002;
+ }
+ object->sizeScaling += object->unk_034;
+ s16_step_up_towards(&object->unk_084[7], 0x0100, 0x0010);
+ object->direction_angle[0] -= object->unk_084[7];
+ if (func_80087060(objectIndex, 0x00000035) != 0) {
+ func_80086FD4(objectIndex);
+ }
+ break;
+ case 6:
+ if (func_80087060(objectIndex, 0x0000000F) != 0) {
+ func_80086FD4(objectIndex);
+ D_801658CE = 1;
+ }
+ break;
+ case 7:
+ object->sizeScaling = (f32) ((f64) object->sizeScaling - 0.05);
+ if ((f64) object->sizeScaling <= 0.01) {
+ clear_object_flag(objectIndex, 0x00000010);
+ object->sizeScaling = 0.000001f;
+ func_80086FD4(objectIndex);
+ }
+ break;
+ case 8:
+ func_80086F60(objectIndex);
+ break;
+ }
+ if (object->unk_0AE < 0xA) {
+ func_80074344(objectIndex, &object->sizeScaling, 0.2f, 0.21f, 0.001f, 0, -1);
+ }
+ object_add_velocity_offset_y(objectIndex);
+ object_calculate_new_pos_offset(objectIndex);
+}
diff --git a/src/engine/objects/CheepCheep.h b/src/engine/objects/CheepCheep.h
new file mode 100644
index 000000000..32e9a5aeb
--- /dev/null
+++ b/src/engine/objects/CheepCheep.h
@@ -0,0 +1,48 @@
+#pragma once
+
+#include <libultraship.h>
+#include <vector>
+#include "Object.h"
+
+#include "World.h"
+
+extern "C" {
+#include "macros.h"
+#include "main.h"
+#include "common_structs.h"
+#include "objects.h"
+#include "course_offsets.h"
+#include "some_data.h"
+}
+
+
+class OCheepCheep : public OObject {
+public:
+ enum CheepType {
+ RACE,
+ PODIUM_CEREMONY
+ };
+
+ enum Behaviour : uint16_t {
+ };
+
+public:
+
+ explicit OCheepCheep(const FVector& pos, CheepType type, IPathSpan span);
+
+ virtual void Tick() override;
+ virtual void Draw(s32 cameraId) override;
+ void func_8007BBBC(s32 objectIndex);
+ void func_8007BD04(s32 playerId);
+ void init_var_cheep_cheep(s32 objectIndex);
+ void func_8007BEC8(s32 objectIndex);
+ void func_8007BFB0(s32 objectIndex);
+
+private:
+
+ s32 _idx;
+ CheepType _type;
+ FVector _spawnPos;
+ IPathSpan _span;
+
+};
diff --git a/src/engine/objects/Mole.cpp b/src/engine/objects/Mole.cpp
index 9ef7f40ef..78b186e77 100644
--- a/src/engine/objects/Mole.cpp
+++ b/src/engine/objects/Mole.cpp
@@ -72,7 +72,7 @@ void OMole::Tick() {
}
}
-void OMole::Draw(Camera* camera) {
+void OMole::Draw(s32 cameraId) {
}
diff --git a/src/engine/objects/Mole.h b/src/engine/objects/Mole.h
index d5d605fa5..7ff95c58c 100644
--- a/src/engine/objects/Mole.h
+++ b/src/engine/objects/Mole.h
@@ -2,7 +2,7 @@
#include <libultraship.h>
#include <vector>
-#include "GameObject.h"
+#include "Object.h"
extern "C" {
#include "macros.h"
@@ -16,7 +16,7 @@ extern "C" {
}
-class OMole : public GameObject {
+class OMole : public OObject {
public:
enum Behaviour : uint16_t {
};
@@ -25,7 +25,7 @@ public:
explicit OMole(Vec3f pos);
virtual void Tick() override;
- virtual void Draw(Camera*) override;
+ virtual void Draw(s32 cameraId) override;
void func_80054E10(s32 objectIndex);
void func_80054EB8();
diff --git a/src/engine/objects/Podium.cpp b/src/engine/objects/Podium.cpp
new file mode 100644
index 000000000..426a65b60
--- /dev/null
+++ b/src/engine/objects/Podium.cpp
@@ -0,0 +1,140 @@
+#include "Podium.h"
+#include "assets/ceremony_data.h"
+
+extern "C" {
+#include "main.h"
+#include "defines.h"
+#include "update_objects.h"
+#include "render_objects.h"
+#include "code_80057C60.h"
+#include "podium_ceremony_actors.h"
+#include "math_util.h"
+#include "math_util_2.h"
+#include "assets/common_data.h"
+#include "some_data.h"
+#include "code_80091440.h"
+#include "code_80086E70.h"
+#include "code_80086E70.h"
+extern Vec3s D_800E634C[];
+}
+
+// Might be Cheep Cheep related?
+// Vec3s D_800E634C[] = {
+// { 0xf37e, 0x0013, 0xfe22 },
+// { 0xf37b, 0x0013, 0xfe31 },
+// { 0xf380, 0x0013, 0xfe14 },
+// };
+
+OPodium::OPodium(const FVector& pos) {
+
+ for (size_t i = 0; i < NUM_PODIUMS; i++) {
+ s32 objectIndex = indexObjectList1[i];
+ init_object(objectIndex, 0);
+ set_obj_origin_pos(objectIndex, pos.x - 1.5, pos.y, pos.z);
+ }
+}
+
+void OPodium::Tick() { // func_80086604
+ s32 objectIndex;
+ // if ((D_8016347C != 0) && (D_802874D8.unk1D < 3)) {
+ // if (D_801658C6 == 0) {
+ // for (size_t i = 0; i < 3; i++) {
+ // objectIndex = indexObjectList1[i];
+ // init_object(objectIndex, 0);
+ // }
+ // D_801658C6 = 1;
+ // }
+ // }
+ for (size_t i = 0; i != NUM_PODIUMS; i++) {
+ objectIndex = indexObjectList1[i];
+ if (gObjectList[objectIndex].state != 0) {
+ OPodium::func_80086528(objectIndex, i);
+ OPodium::func_80086424(objectIndex);
+ }
+ }
+}
+
+void OPodium::Draw(s32 cameraId) { // func_80055F48
+ for (size_t i = 0; i < NUM_PODIUMS; i++) {
+ Object* object;
+
+ object = &gObjectList[i];
+ if (object->state >= 2) {
+ func_80043220(object->pos, object->direction_angle, object->sizeScaling, object->model);
+ rsp_set_matrix_transformation(object->pos, object->direction_angle, object->sizeScaling);
+ gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D0077A0);
+ gSPDisplayList(gDisplayListHead++, object->model);
+ }
+ }
+}
+
+void OPodium::func_8008629C(s32 objectIndex, s32 arg1) {
+ switch (arg1) { /* irregular */
+ case 0:
+ gObjectList[objectIndex].model = (Gfx*)podium_dl3;
+ gObjectList[objectIndex].unk_04C = 0x00000038;
+ break;
+ case 1:
+ gObjectList[objectIndex].model = (Gfx*)podium2_dl3;
+ gObjectList[objectIndex].unk_04C = 0x0000002B;
+ break;
+ case 2:
+ gObjectList[objectIndex].model = (Gfx*)podium3_dl3;
+ gObjectList[objectIndex].unk_04C = 0x0000001E;
+ break;
+ default:
+ break;
+ }
+ gObjectList[objectIndex].sizeScaling = 1.0f;
+ //set_obj_origin_pos(objectIndex, D_800E634C[0][0] - 1.5, D_800E634C[0][1], D_800E634C[0][2]);
+ set_obj_origin_offset(objectIndex, 0.0f, -10.0f, 0.0f);
+ set_obj_direction_angle(objectIndex, 0U, 0xF8E4U, 0U);
+ gObjectList[objectIndex].unk_048 = 0;
+ object_next_state(objectIndex);
+}
+
+void OPodium::func_80086424(s32 objectIndex) {
+ switch (gObjectList[objectIndex].unk_0AE) {
+ case 0:
+ break;
+ case 1:
+ gObjectList[objectIndex].velocity[1] = 0.75f;
+ func_80086FD4(objectIndex);
+ break;
+ case 2:
+ if (gObjectList[objectIndex].offset[1] >= -2.0) {
+ gObjectList[objectIndex].velocity[1] -= 0.1;
+ }
+ object_add_velocity_offset_y(objectIndex);
+ if (gObjectList[objectIndex].offset[1] >= 0.0) {
+ gObjectList[objectIndex].offset[1] = 0.0f;
+ gObjectList[objectIndex].velocity[1] = 0.0f;
+ func_80086F60(objectIndex);
+ }
+ break;
+ }
+ object_calculate_new_pos_offset(objectIndex);
+}
+
+void OPodium::func_80086528(s32 objectIndex, s32 arg1) {
+ switch (gObjectList[objectIndex].state) { /* irregular */
+ case 1:
+ func_8008629C(objectIndex, arg1);
+ break;
+ case 2:
+ if (set_and_run_timer_object(objectIndex, gObjectList[objectIndex].unk_04C) != 0) {
+ func_80091440(arg1);
+ func_80086E70(objectIndex);
+ object_next_state(objectIndex);
+ }
+ break;
+ case 0:
+ break;
+ case 3:
+ if (gObjectList[objectIndex].unk_0AE == 0) {
+ gObjectList[objectIndex].unk_048 = 1;
+ object_next_state(objectIndex);
+ }
+ break;
+ }
+}
diff --git a/src/engine/objects/Podium.h b/src/engine/objects/Podium.h
new file mode 100644
index 000000000..2b3a1033a
--- /dev/null
+++ b/src/engine/objects/Podium.h
@@ -0,0 +1,38 @@
+#pragma once
+
+#include <libultraship.h>
+#include <vector>
+
+#include "World.h"
+
+extern "C" {
+#include "macros.h"
+#include "main.h"
+#include "vehicles.h"
+#include "waypoints.h"
+#include "common_structs.h"
+#include "objects.h"
+#include "course_offsets.h"
+#include "some_data.h"
+}
+
+
+class OPodium : public OObject {
+public:
+ enum Behaviour : uint16_t {
+ };
+
+public:
+
+ explicit OPodium(const FVector& pos);
+
+ virtual void Tick() override;
+ virtual void Draw(s32 cameraId) override;
+ void func_8008629C(s32 objectIndex, s32 arg1);
+ void func_80086424(s32 objectIndex);
+ void func_80086528(s32 objectIndex, s32 arg1);
+
+private:
+
+ s32 _idx;
+};
diff --git a/src/engine/objects/Seagull.cpp b/src/engine/objects/Seagull.cpp
index 4b36bbf31..b641ab5b4 100644
--- a/src/engine/objects/Seagull.cpp
+++ b/src/engine/objects/Seagull.cpp
@@ -2,7 +2,6 @@
#include <libultra/gbi.h>
#include "Seagull.h"
#include "engine/Actor.h"
-#include "ObjectReimpl.h"
#include <vector>
#include "port/Game.h"
@@ -135,7 +134,7 @@ void OSeagull::func_8008275C(s32 objectIndex) {
switch (gObjectList[objectIndex].unk_0DD) {
case 1:
func_8008B78C(objectIndex);
- ObjectImpl::CalculateNewPosOffset(this);
+ object_calculate_new_pos_offset(objectIndex);
break;
case 2:
func_8008B78C(objectIndex);
@@ -145,7 +144,7 @@ void OSeagull::func_8008275C(s32 objectIndex) {
Offset[0] *= 2.0;
Offset[1] *= 2.5;
Offset[2] *= 2.0;
- ObjectImpl::CalculateNewPosOffset(this);
+ object_calculate_new_pos_offset(objectIndex);
gObjectList[objectIndex].direction_angle[1] =
get_angle_between_two_vectors(gObjectList[objectIndex].unk_01C, gObjectList[objectIndex].pos);
break;
diff --git a/src/engine/objects/Trophy.cpp b/src/engine/objects/Trophy.cpp
index 464a2277c..5ac54f5ec 100644
--- a/src/engine/objects/Trophy.cpp
+++ b/src/engine/objects/Trophy.cpp
@@ -226,7 +226,6 @@ void OTrophy::Draw(s32 cameraId) {
func_80057A50(40, 0, (char*) "Trophies Collected: ", (s16) numTrophies);
break;
}
-
}
}
diff --git a/src/engine/objects/Trophy.h b/src/engine/objects/Trophy.h
index d73e04929..d413faf12 100644
--- a/src/engine/objects/Trophy.h
+++ b/src/engine/objects/Trophy.h
@@ -3,6 +3,7 @@
#include <libultraship.h>
#include <vector>
#include "Object.h"
+#include "World.h"
extern "C" {
#include "macros.h"
@@ -15,18 +16,6 @@ extern "C" {
#include "some_data.h"
}
-//! @todo move this like World.h or something
-struct FVector {
- float x, y, z;
-
- FVector& operator=(const FVector& other) {
- x = other.x;
- y = other.y;
- z = other.z;
- return *this;
- }
-};
-
class OTrophy : public OObject {
public:
enum TrophyType {
diff --git a/src/engine/particles/ParticleEmitter.cpp b/src/engine/particles/ParticleEmitter.cpp
new file mode 100644
index 000000000..5154abf56
--- /dev/null
+++ b/src/engine/particles/ParticleEmitter.cpp
@@ -0,0 +1,13 @@
+#include <libultraship.h>
+
+#include "ParticleEmitter.h"
+
+
+
+ParticleEmitter::ParticleEmitter() {}
+
+ // Virtual functions to be overridden by derived classes
+void ParticleEmitter::Tick() { }
+void ParticleEmitter::Draw(s32 cameraId) { }
+
+bool ParticleEmitter::IsMod() { return false; }
diff --git a/src/engine/particles/ParticleEmitter.h b/src/engine/particles/ParticleEmitter.h
new file mode 100644
index 000000000..1a71164d1
--- /dev/null
+++ b/src/engine/particles/ParticleEmitter.h
@@ -0,0 +1,23 @@
+#pragma once
+
+#include <libultraship.h>
+
+extern "C" {
+#include "macros.h"
+#include "main.h"
+#include "camera.h"
+#include "common_structs.h"
+
+
+class ParticleEmitter {
+public:
+ virtual ~ParticleEmitter() = default; // Virtual destructor for proper cleanup in derived classes
+
+ explicit ParticleEmitter();
+
+ virtual void Tick();
+ virtual void Draw(s32 cameraId);
+ virtual bool IsMod();
+};
+
+} \ No newline at end of file
diff --git a/src/engine/particles/StarEmitter.cpp b/src/engine/particles/StarEmitter.cpp
new file mode 100644
index 000000000..b717f177d
--- /dev/null
+++ b/src/engine/particles/StarEmitter.cpp
@@ -0,0 +1,31 @@
+
+
+#include "StarEmitter.h"
+
+extern "C" {
+#include "render_objects.h"
+#include "common_data.h"
+#include "code_80057C60.h"
+}
+
+void StarEmitter::Tick() {
+
+}
+
+void StarEmitter::Draw(s32 cameraId) { // func_80054BE8
+ s32 var_s0;
+ s32 temp_a0;
+ Camera* camera;
+
+ camera = &camera1[cameraId];
+ gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D007AE0);
+ load_texture_block_ia8_nomirror(D_8018D488, 0x00000020, 0x00000020);
+ func_8004B35C(0x000000FF, 0x000000FF, 0, 0x000000FF);
+ D_80183E80[0] = 0;
+ for (var_s0 = 0; var_s0 < gObjectParticle3_SIZE; var_s0++) {
+ temp_a0 = gObjectParticle3[var_s0];
+ if ((temp_a0 != -1) && (gObjectList[temp_a0].state >= 2)) {
+ func_80054AFC(temp_a0, camera->pos);
+ }
+ }
+}
diff --git a/src/engine/particles/StarEmitter.h b/src/engine/particles/StarEmitter.h
new file mode 100644
index 000000000..20841598c
--- /dev/null
+++ b/src/engine/particles/StarEmitter.h
@@ -0,0 +1,42 @@
+#pragma once
+
+#include <libultraship.h>
+#include <vector>
+#include "ParticleEmitter.h"
+
+extern "C" {
+#include "macros.h"
+#include "main.h"
+#include "vehicles.h"
+#include "waypoints.h"
+#include "common_structs.h"
+#include "objects.h"
+#include "course_offsets.h"
+#include "some_data.h"
+}
+
+/**
+ * Used in the podium ceremony when the trophy appears
+ */
+class StarEmitter : public ParticleEmitter {
+public:
+ enum Behaviour : uint16_t {
+ };
+
+public:
+ f32 Diameter = 0.0f; // Waddle in a circle around the spawn point at this diameter.
+ uint16_t MirrorModeAngleOffset;
+
+ explicit StarEmitter(Vec3f pos);
+
+ virtual void Tick() override;
+ virtual void Draw(s32 cameraId) override;
+ void func_80086700(s32 objectIndex);
+ void func_80086940(s32 objectIndex);
+ void func_80086C14(s32 objectIndex);
+ void func_80086C6C(s32 objectIndex);
+
+private:
+
+ s32 _idx;
+};