summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMegaMech <MegaMech@users.noreply.github.com>2025-02-07 14:36:55 -0700
committerGitHub <noreply@github.com>2025-02-07 14:36:55 -0700
commitfc1e1a97825c129f114a5c59ab1820d1a1b9187f (patch)
tree3d18b98adf1a3c62fcbd203f55a89e047782808a /src
parent6f8cbc0279004a39635c922b824e8561f5355bc5 (diff)
Reimpl star emitter (#180)
* Reimpl star emitter * Remove OObject Lists * wip mole reimpl * nearly fix moles * Cleanup * Update reimpl seagull * Rework finishline to auto spawn and not to run in credits * Fix train crossing direction in extra mode * Clarification * micro optimization * update mole --------- Co-authored-by: MegaMech <7255464+MegaMech@users.noreply.github.com>
Diffstat (limited to 'src')
-rw-r--r--src/code_800029B0.c2
-rw-r--r--src/ending/ceremony_and_credits.c10
-rw-r--r--src/engine/TrainCrossing.cpp3
-rw-r--r--src/engine/World.cpp7
-rw-r--r--src/engine/World.h1
-rw-r--r--src/engine/actors/AFinishline.cpp26
-rw-r--r--src/engine/actors/AFinishline.h3
-rw-r--r--src/engine/courses/BansheeBoardwalk.cpp2
-rw-r--r--src/engine/courses/BowsersCastle.cpp2
-rw-r--r--src/engine/courses/ChocoMountain.cpp1
-rw-r--r--src/engine/courses/Course.cpp5
-rw-r--r--src/engine/courses/Course.h4
-rw-r--r--src/engine/courses/DKJungle.cpp32
-rw-r--r--src/engine/courses/FrappeSnowland.cpp2
-rw-r--r--src/engine/courses/KalimariDesert.cpp124
-rw-r--r--src/engine/courses/KoopaTroopaBeach.cpp14
-rw-r--r--src/engine/courses/LuigiRaceway.cpp1
-rw-r--r--src/engine/courses/MarioRaceway.cpp6
-rw-r--r--src/engine/courses/MarioRaceway.h1
-rw-r--r--src/engine/courses/MooMooFarm.cpp230
-rw-r--r--src/engine/courses/MooMooFarm.h4
-rw-r--r--src/engine/courses/PodiumCeremony.cpp3
-rw-r--r--src/engine/courses/RainbowRoad.cpp2
-rw-r--r--src/engine/courses/RoyalRaceway.cpp2
-rw-r--r--src/engine/courses/SherbetLand.cpp35
-rw-r--r--src/engine/courses/TestCourse.cpp150
-rw-r--r--src/engine/courses/TestCourse.h2
-rw-r--r--src/engine/courses/ToadsTurnpike.cpp95
-rw-r--r--src/engine/courses/WarioStadium.cpp16
-rw-r--r--src/engine/courses/YoshiValley.cpp2
-rw-r--r--src/engine/objects/Bat.cpp50
-rw-r--r--src/engine/objects/Bat.h1
-rw-r--r--src/engine/objects/Crab.cpp28
-rw-r--r--src/engine/objects/Crab.h1
-rw-r--r--src/engine/objects/Flagpole.cpp8
-rw-r--r--src/engine/objects/Flagpole.h1
-rw-r--r--src/engine/objects/HotAirBalloon.cpp8
-rw-r--r--src/engine/objects/HotAirBalloon.h1
-rw-r--r--src/engine/objects/Mole.cpp270
-rw-r--r--src/engine/objects/Mole.h23
-rw-r--r--src/engine/objects/MoleGroup.cpp50
-rw-r--r--src/engine/objects/MoleGroup.h27
-rw-r--r--src/engine/objects/Object.cpp1
-rw-r--r--src/engine/objects/Object.h1
-rw-r--r--src/engine/objects/Penguin.cpp91
-rw-r--r--src/engine/objects/Penguin.h20
-rw-r--r--src/engine/objects/Podium.cpp57
-rw-r--r--src/engine/objects/Podium.h5
-rw-r--r--src/engine/objects/Seagull.cpp36
-rw-r--r--src/engine/objects/Seagull.h5
-rw-r--r--src/engine/objects/Snowman.cpp54
-rw-r--r--src/engine/objects/Snowman.h4
-rw-r--r--src/engine/objects/Thwomp.cpp69
-rw-r--r--src/engine/objects/Thwomp.h1
-rw-r--r--src/engine/objects/TrashBin.cpp17
-rw-r--r--src/engine/objects/TrashBin.h1
-rw-r--r--src/engine/objects/Trophy.cpp101
-rw-r--r--src/engine/objects/Trophy.h6
-rw-r--r--src/engine/particles/StarEmitter.cpp37
-rw-r--r--src/engine/particles/StarEmitter.h7
-rw-r--r--src/port/Game.cpp15
-rw-r--r--src/port/Game.h2
-rw-r--r--src/racing/actors.c10
-rw-r--r--src/render_objects.c44
-rw-r--r--src/render_objects.h1
-rw-r--r--src/update_objects.c40
-rw-r--r--src/update_objects.h3
67 files changed, 925 insertions, 958 deletions
diff --git a/src/code_800029B0.c b/src/code_800029B0.c
index a75691622..88453dcaa 100644
--- a/src/code_800029B0.c
+++ b/src/code_800029B0.c
@@ -323,8 +323,8 @@ void credits_spawn_actors(void) {
gNextFreeMemoryAddress += 0x9000;
destroy_all_actors();
CM_CleanWorld();
-
CM_CreditsSpawnActors();
+ CM_BeginPlay();
gNumPermanentActors = gNumActors;
}
diff --git a/src/ending/ceremony_and_credits.c b/src/ending/ceremony_and_credits.c
index 5b964e0d6..fd8b2405c 100644
--- a/src/ending/ceremony_and_credits.c
+++ b/src/ending/ceremony_and_credits.c
@@ -22,7 +22,8 @@
#include "code_80057C60.h"
#include "defines.h"
-#include "src/port/Engine.h"
+#include "port/Engine.h"
+#include "port/Game.h"
f32 D_802856B0 = 98.0f;
f32 D_802856B4 = 12.0f;
@@ -996,8 +997,11 @@ void func_80284154(CinematicCamera* camera) {
void func_80284184(CinematicCamera* camera) {
f32 trophy;
- trophy = ((gObjectList[indexObjectList1[3]].pos[1] - camera->lookAt[1]) * 0.9f) + camera->lookAt[1];
- f32_lerp(&camera->pos[1], trophy, 0.5);
+
+ if (gTrophyIndex != NULL) {
+ trophy = ((gObjectList[gTrophyIndex].pos[1] - camera->lookAt[1]) * 0.9f) + camera->lookAt[1];
+ f32_lerp(&camera->pos[1], trophy, 0.5);
+ }
}
void func_802841E8(CinematicCamera* camera) {
diff --git a/src/engine/TrainCrossing.cpp b/src/engine/TrainCrossing.cpp
index 2d4442a30..8dce6984b 100644
--- a/src/engine/TrainCrossing.cpp
+++ b/src/engine/TrainCrossing.cpp
@@ -10,11 +10,12 @@ extern "C" {
#include "main.h"
#include "vehicles.h"
#include "code_80005FD0.h"
+#include "code_80057C60.h"
#include "common_structs.h"
}
TrainCrossing::TrainCrossing(Vec3f position, u32 waypointMin, u32 waypointMax, f32 approachRadius, f32 exitRadius) {
- Position[0] = position[0];
+ Position[0] = position[0] * xOrientation;
Position[1] = position[1];
Position[2] = position[2];
ApproachRadius = approachRadius;
diff --git a/src/engine/World.cpp b/src/engine/World.cpp
index d67a2577c..a63c22b10 100644
--- a/src/engine/World.cpp
+++ b/src/engine/World.cpp
@@ -195,6 +195,13 @@ void World::DrawParticles(s32 cameraId) {
}
}
+// Sets OObjects or AActors static member variables back to default values
+void World::Reset() {
+ for (const auto& object : Objects) {
+ object->Reset();
+ }
+}
+
Object* World::GetObjectByIndex(size_t index) {
//if (index < this->Objects.size()) {
// Assuming GameActor::a is accessible, use reinterpret_cast if needed
diff --git a/src/engine/World.h b/src/engine/World.h
index 3ba6e0437..9490293b7 100644
--- a/src/engine/World.h
+++ b/src/engine/World.h
@@ -65,6 +65,7 @@ public:
void TickParticles();
void DrawParticles(s32 cameraId);
ParticleEmitter* AddEmitter(ParticleEmitter* emitter);
+ void Reset(void); // Sets OObjects or AActors static member variables back to default values
void AddCup(Cup*);
void SetCup(Cup* cup);
diff --git a/src/engine/actors/AFinishline.cpp b/src/engine/actors/AFinishline.cpp
index cc920f2bb..77dd37ede 100644
--- a/src/engine/actors/AFinishline.cpp
+++ b/src/engine/actors/AFinishline.cpp
@@ -1,5 +1,6 @@
#include <libultraship.h>
#include <libultra/gbi.h>
+#include "CoreMath.h"
#include "AFinishline.h"
#include "engine/Actor.h"
@@ -16,23 +17,24 @@ extern f32 gKartHopInitialVelocityTable[];
extern f32 gKartGravityTable[];
}
-AFinishline::AFinishline(Vec3f pos) {
- if (pos != nullptr) { // Allow user to set their own values
- Pos[0] = pos[0];
- Pos[1] = pos[1] - 15;
- Pos[2] = pos[2];
- } else { // Default to first waypoint position
- Pos[0] = D_80164490->posX;
- Pos[1] = (f32) (D_80164490->posY - 15);
- Pos[2] = D_80164490->posZ;
+AFinishline::AFinishline(std::optional<FVector> pos) {
+
+ if (pos.has_value()) {
+ // Set spawn point to the provided position
+ Pos[0] = D_8015F8D0[0] = pos.value().x;
+ Pos[1] = D_8015F8D0[1] = pos.value().y - 15;
+ Pos[2] = D_8015F8D0[2] = pos.value().z;
+ } else {
+ // Set spawn point to the tracks first path point.
+ Pos[0] = D_8015F8D0[0] = D_80164490->posX;
+ Pos[1] = D_8015F8D0[1] = (f32) (D_80164490->posY - 15);
+ Pos[2] = D_8015F8D0[2] = D_80164490->posZ;
}
Rot[0] = 0;
Rot[1] = 0;
Rot[2] = 0;
-
-
Flags = -0x8000 | 0x4000;
BoundingBoxSize = 0.0f;
@@ -40,8 +42,6 @@ AFinishline::AFinishline(Vec3f pos) {
void AFinishline::Tick() {}
-extern Gfx cloud_mesh[];
-
void AFinishline::Draw(Camera *camera) {
Mat4 mtx;
s16 temp = Pos[2];
diff --git a/src/engine/actors/AFinishline.h b/src/engine/actors/AFinishline.h
index ea27f3b61..61b561a5e 100644
--- a/src/engine/actors/AFinishline.h
+++ b/src/engine/actors/AFinishline.h
@@ -1,6 +1,7 @@
#pragma once
#include <libultraship.h>
+#include "CoreMath.h"
#include "engine/Actor.h"
extern "C" {
@@ -16,7 +17,7 @@ public:
* Default behaviour places the finishline at the first waypoint.
* @arg pos, optional. Sets a custom position
*/
- AFinishline(Vec3f pos = nullptr);
+ AFinishline(std::optional<FVector> pos);
virtual ~AFinishline() override = default;
diff --git a/src/engine/courses/BansheeBoardwalk.cpp b/src/engine/courses/BansheeBoardwalk.cpp
index 4ff92d107..5ebaf2bc1 100644
--- a/src/engine/courses/BansheeBoardwalk.cpp
+++ b/src/engine/courses/BansheeBoardwalk.cpp
@@ -150,8 +150,6 @@ void BansheeBoardwalk::LoadTextures() {
}
void BansheeBoardwalk::BeginPlay() {
- gWorldInstance.AddActor(new AFinishline());
-
spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_banshee_boardwalk_item_box_spawns));
diff --git a/src/engine/courses/BowsersCastle.cpp b/src/engine/courses/BowsersCastle.cpp
index 6f4ecccc5..cac1dde92 100644
--- a/src/engine/courses/BowsersCastle.cpp
+++ b/src/engine/courses/BowsersCastle.cpp
@@ -149,8 +149,6 @@ void BowsersCastle::LoadTextures() {
}
void BowsersCastle::BeginPlay() {
- gWorldInstance.AddActor(new AFinishline());
-
spawn_foliage((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_bowsers_castle_tree_spawn));
spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_bowsers_castle_item_box_spawns));
diff --git a/src/engine/courses/ChocoMountain.cpp b/src/engine/courses/ChocoMountain.cpp
index 4406159e9..632f31981 100644
--- a/src/engine/courses/ChocoMountain.cpp
+++ b/src/engine/courses/ChocoMountain.cpp
@@ -164,7 +164,6 @@ void ChocoMountain::LoadTextures() {
}
void ChocoMountain::BeginPlay() {
- gWorldInstance.AddActor(new AFinishline());
spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_choco_mountain_item_box_spawns));
spawn_falling_rocks((struct ActorSpawnData*)LOAD_ASSET_RAW((const char*)d_course_choco_mountain_falling_rock_spawns));
diff --git a/src/engine/courses/Course.cpp b/src/engine/courses/Course.cpp
index 3b2ac641d..3e5c0b2ab 100644
--- a/src/engine/courses/Course.cpp
+++ b/src/engine/courses/Course.cpp
@@ -225,11 +225,6 @@ void Course::Waypoints(Player* player, int8_t playerId) {
}
}
-void Course::SpawnVehicles() {
-}
-void Course::UpdateVehicles() {
-}
-
void Course::Render(struct UnkStruct_800DC5EC* arg0) {
}
void Course::RenderCredits() {
diff --git a/src/engine/courses/Course.h b/src/engine/courses/Course.h
index d4f637073..889012a12 100644
--- a/src/engine/courses/Course.h
+++ b/src/engine/courses/Course.h
@@ -78,6 +78,8 @@ public:
const char* gfx = nullptr;
size_t gfxSize = 0;
const course_texture* textures = nullptr;
+ bool bSpawnFinishline = true;
+ std::optional<FVector> FinishlineSpawnPoint;
virtual ~Course() = default;
@@ -107,8 +109,6 @@ public:
virtual void SetStaffGhost();
virtual void Render(struct UnkStruct_800DC5EC*);
virtual void RenderCredits();
- virtual void SpawnVehicles();
- virtual void UpdateVehicles();
virtual void Waypoints(Player* player, int8_t playerId);
virtual void Collision();
virtual void ScrollingTextures();
diff --git a/src/engine/courses/DKJungle.cpp b/src/engine/courses/DKJungle.cpp
index a49a029c3..bb9c951bc 100644
--- a/src/engine/courses/DKJungle.cpp
+++ b/src/engine/courses/DKJungle.cpp
@@ -151,29 +151,29 @@ void DKJungle::LoadTextures() {
}
void DKJungle::BeginPlay() {
- gWorldInstance.AddActor(new AFinishline());
-
spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_dks_jungle_parkway_item_box_spawns));
+
init_kiwano_fruit();
func_80298D10();
+ if (gGamestate != CREDITS_SEQUENCE) {
+ generate_ferry_waypoints();
- generate_ferry_waypoints();
-
- // The original game only ran vehicle logic every second frame.
- // Thus the speed gets divided by two to set speed to match properly
- gWorldInstance.AddActor(new ABoat((0.6666666f)/4, 0));
+ // The original game only ran vehicle logic every second frame.
+ // Thus the speed gets divided by two to set speed to match properly
+ gWorldInstance.AddActor(new ABoat((0.6666666f)/4, 0));
- if (gModeSelection == VERSUS) {
- Vec3f pos = {0, 0, 0};
+ if (gModeSelection == VERSUS) {
+ Vec3f pos = {0, 0, 0};
- gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][50], 50, 3, 0.8333333f));
- gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][100], 100, 1, 0.8333333f));
- gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][150], 150, 3, 0.8333333f));
- gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][190], 190, 1, 0.8333333f));
- gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][250], 250, 3, 0.8333333f));
- gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f));
- gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f));
+ gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][50], 50, 3, 0.8333333f));
+ gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][100], 100, 1, 0.8333333f));
+ gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][150], 150, 3, 0.8333333f));
+ gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][190], 190, 1, 0.8333333f));
+ gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][250], 250, 3, 0.8333333f));
+ gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f));
+ gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f));
+ }
}
}
diff --git a/src/engine/courses/FrappeSnowland.cpp b/src/engine/courses/FrappeSnowland.cpp
index 61527d685..7383946d1 100644
--- a/src/engine/courses/FrappeSnowland.cpp
+++ b/src/engine/courses/FrappeSnowland.cpp
@@ -128,8 +128,6 @@ void FrappeSnowland::LoadTextures() {
}
void FrappeSnowland::BeginPlay() {
- gWorldInstance.AddActor(new AFinishline());
-
spawn_foliage((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_frappe_snowland_tree_spawns));
spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_frappe_snowland_item_box_spawns));
diff --git a/src/engine/courses/KalimariDesert.cpp b/src/engine/courses/KalimariDesert.cpp
index e783d4e0f..133a38e08 100644
--- a/src/engine/courses/KalimariDesert.cpp
+++ b/src/engine/courses/KalimariDesert.cpp
@@ -141,75 +141,77 @@ void KalimariDesert::BeginPlay() {
Vec3f velocity = { 0.0f, 0.0f, 0.0f };
Vec3s rotation = { 0, 0, 0 };
- gWorldInstance.AddActor(new AFinishline());
-
spawn_foliage((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_kalimari_desert_cactus_spawn));
spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_kalimari_desert_item_box_spawns));
- Vec3f crossingPos = {-2500, 2, 2355};
- Vec3f crossingPos2 = {-1639, 2, 68};
- uintptr_t* crossing1 = (uintptr_t*) gWorldInstance.AddCrossing(crossingPos, 306, 310, 900.0f, 650.0f);
- uintptr_t* crossing2 = (uintptr_t*) gWorldInstance.AddCrossing(crossingPos2, 176, 182, 900.0f, 650.0f);
-
- vec3f_set(position, -1680.0f, 2.0f, 35.0f);
- position[0] *= gCourseDirection;
- rrxing = (struct RailroadCrossing*) GET_ACTOR(add_actor_to_empty_slot(position, rotation, velocity,
- ACTOR_RAILROAD_CROSSING));
- rrxing->crossingTrigger = crossing2;
- vec3f_set(position, -1600.0f, 2.0f, 35.0f);
- position[0] *= gCourseDirection;
- rrxing = (struct RailroadCrossing*) GET_ACTOR(add_actor_to_empty_slot(position, rotation, velocity,
- ACTOR_RAILROAD_CROSSING));
- rrxing->crossingTrigger = crossing2;
- vec3s_set(rotation, 0, -0x2000, 0);
- vec3f_set(position, -2459.0f, 2.0f, 2263.0f);
- position[0] *= gCourseDirection;
- rrxing = (struct RailroadCrossing*) GET_ACTOR(add_actor_to_empty_slot(position, rotation, velocity,
- ACTOR_RAILROAD_CROSSING));
- rrxing->crossingTrigger = crossing1;
- vec3f_set(position, -2467.0f, 2.0f, 2375.0f);
- position[0] *= gCourseDirection;
- rrxing = (struct RailroadCrossing*) GET_ACTOR(add_actor_to_empty_slot(position, rotation, velocity,
- ACTOR_RAILROAD_CROSSING));
- rrxing->crossingTrigger = crossing1;
-
-
-
- generate_train_waypoints();
-
- s32 centerWaypoint = 160;
-
- // Spawn two trains
- for (size_t i = 0; i < _numTrains; ++i) {
- uint32_t waypoint = CalculateWaypointDistribution(i, _numTrains, gVehicle2DWaypointLength, centerWaypoint);
-
- if (CVarGetInteger("gMultiplayerNoFeatureCuts", 0) == false) {
- // Multiplayer modes have no tender and no carriages
- if (gActiveScreenMode != SCREEN_MODE_1P) {
- _tender = ATrain::TenderStatus::NO_TENDER;
- _numCarriages = 0;
- }
+ if (gGamestate != CREDITS_SEQUENCE) {
- // 2 player versus mode has a tender and a carriage
- if ((gModeSelection == VERSUS) && (gPlayerCountSelection1 == 2)) {
- _tender = ATrain::TenderStatus::HAS_TENDER;
- _numCarriages = 1;
+ Vec3f crossingPos = {-2500, 2, 2355};
+ Vec3f crossingPos2 = {-1639, 2, 68};
+ uintptr_t* crossing1 = (uintptr_t*) gWorldInstance.AddCrossing(crossingPos, 306, 310, 900.0f, 650.0f);
+ uintptr_t* crossing2 = (uintptr_t*) gWorldInstance.AddCrossing(crossingPos2, 176, 182, 900.0f, 650.0f);
+
+ vec3f_set(position, -1680.0f, 2.0f, 35.0f);
+ position[0] *= gCourseDirection;
+ rrxing = (struct RailroadCrossing*) GET_ACTOR(add_actor_to_empty_slot(position, rotation, velocity,
+ ACTOR_RAILROAD_CROSSING));
+ rrxing->crossingTrigger = crossing2;
+ vec3f_set(position, -1600.0f, 2.0f, 35.0f);
+ position[0] *= gCourseDirection;
+ rrxing = (struct RailroadCrossing*) GET_ACTOR(add_actor_to_empty_slot(position, rotation, velocity,
+ ACTOR_RAILROAD_CROSSING));
+ rrxing->crossingTrigger = crossing2;
+
+ // Original game forgot to put gCourseDirection to face the crossing the right direction in extra mode
+ vec3s_set(rotation, 0, -0x2000 * gCourseDirection, 0);
+ vec3f_set(position, -2459.0f, 2.0f, 2263.0f);
+ position[0] *= gCourseDirection;
+ rrxing = (struct RailroadCrossing*) GET_ACTOR(add_actor_to_empty_slot(position, rotation, velocity,
+ ACTOR_RAILROAD_CROSSING));
+ rrxing->crossingTrigger = crossing1;
+ vec3f_set(position, -2467.0f, 2.0f, 2375.0f);
+ position[0] *= gCourseDirection;
+ rrxing = (struct RailroadCrossing*) GET_ACTOR(add_actor_to_empty_slot(position, rotation, velocity,
+ ACTOR_RAILROAD_CROSSING));
+ rrxing->crossingTrigger = crossing1;
+
+
+ generate_train_waypoints();
+
+ s32 centerWaypoint = 160;
+
+ // Spawn two trains
+ for (size_t i = 0; i < _numTrains; ++i) {
+ uint32_t waypoint = CalculateWaypointDistribution(i, _numTrains, gVehicle2DWaypointLength, centerWaypoint);
+
+ if (CVarGetInteger("gMultiplayerNoFeatureCuts", 0) == false) {
+ // Multiplayer modes have no tender and no carriages
+ if (gActiveScreenMode != SCREEN_MODE_1P) {
+ _tender = ATrain::TenderStatus::NO_TENDER;
+ _numCarriages = 0;
+ }
+
+ // 2 player versus mode has a tender and a carriage
+ if ((gModeSelection == VERSUS) && (gPlayerCountSelection1 == 2)) {
+ _tender = ATrain::TenderStatus::HAS_TENDER;
+ _numCarriages = 1;
+ }
}
- }
- gWorldInstance.AddActor(new ATrain(_tender, _numCarriages, 2.5f, waypoint));
- }
+ gWorldInstance.AddActor(new ATrain(_tender, _numCarriages, 2.5f, waypoint));
+ }
- if (gModeSelection == VERSUS) {
- Vec3f pos = {0, 0, 0};
+ if (gModeSelection == VERSUS) {
+ Vec3f pos = {0, 0, 0};
- gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][50], 50, 3, 0.8333333f));
- gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][138], 138, 1, 0.8333333f));
- gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][280], 280, 3, 0.8333333f));
- gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][404], 404, 1, 0.8333333f));
- gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][510], 510, 3, 0.8333333f));
- gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f));
- gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f));
+ gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][50], 50, 3, 0.8333333f));
+ gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][138], 138, 1, 0.8333333f));
+ gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][280], 280, 3, 0.8333333f));
+ gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][404], 404, 1, 0.8333333f));
+ gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][510], 510, 3, 0.8333333f));
+ gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f));
+ gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f));
+ }
}
}
diff --git a/src/engine/courses/KoopaTroopaBeach.cpp b/src/engine/courses/KoopaTroopaBeach.cpp
index 4e017912e..3fd22598a 100644
--- a/src/engine/courses/KoopaTroopaBeach.cpp
+++ b/src/engine/courses/KoopaTroopaBeach.cpp
@@ -140,8 +140,6 @@ void KoopaTroopaBeach::LoadTextures() {
}
void KoopaTroopaBeach::BeginPlay() {
- gWorldInstance.AddActor(new AFinishline());
-
init_actor_hot_air_balloon_item_box(328.0f * gCourseDirection, 70.0f, 2541.0f);
spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_koopa_troopa_beach_item_box_spawns));
spawn_palm_trees((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_koopa_troopa_beach_tree_spawn));
@@ -161,21 +159,15 @@ void KoopaTroopaBeach::BeginPlay() {
if (gGamestate == CREDITS_SEQUENCE) {
for (size_t i = 0; i < NUM_SEAGULLS; i++) {
- //gWorldInstance.AddObject(new OSeagull(FVector(-360.0f, 60.0f, -1300.0f)));
- Vec3f pos = {-360.0f, 60.0f, -1300.0f};
- gWorldInstance.AddObject(new OSeagull(pos));
+ gWorldInstance.AddObject(new OSeagull(FVector(-360.0f, 60.0f, -1300.0f)));
}
} else { // Normal gameplay
for (size_t i = 0; i < 4; i++) {
- Vec3f pos = {-985.0f, 15.0f, 1200.0f};
- gWorldInstance.AddObject(new OSeagull(pos));
- //gWorldInstance.AddObject(new OSeagull(FVector(-985.0f, 15.0f, 1200.0f)));
+ gWorldInstance.AddObject(new OSeagull(FVector(-985.0f, 15.0f, 1200.0f)));
}
for (size_t i = 0; i < 6; i++) {
- //gWorldInstance.AddObject(new OSeagull(FVector(328.0f, 20.0f, 2541.0f)));
- Vec3f pos2 = {328.0f, 20.0f, 2541.0f};
- gWorldInstance.AddObject(new OSeagull(pos2));
+ gWorldInstance.AddObject(new OSeagull(FVector(328.0f, 20.0f, 2541.0f)));
}
}
diff --git a/src/engine/courses/LuigiRaceway.cpp b/src/engine/courses/LuigiRaceway.cpp
index a821ec2d9..555af3212 100644
--- a/src/engine/courses/LuigiRaceway.cpp
+++ b/src/engine/courses/LuigiRaceway.cpp
@@ -165,7 +165,6 @@ void LuigiRaceway::LoadTextures() {
}
void LuigiRaceway::BeginPlay() {
- gWorldInstance.AddActor(new AFinishline());
spawn_foliage((struct ActorSpawnData*) LOAD_ASSET_RAW(d_course_luigi_raceway_tree_spawn));
spawn_all_item_boxes((struct ActorSpawnData*) LOAD_ASSET_RAW(d_course_luigi_raceway_item_box_spawns));
diff --git a/src/engine/courses/MarioRaceway.cpp b/src/engine/courses/MarioRaceway.cpp
index a2cc96525..e3b9bba21 100644
--- a/src/engine/courses/MarioRaceway.cpp
+++ b/src/engine/courses/MarioRaceway.cpp
@@ -180,8 +180,6 @@ void MarioRaceway::BeginPlay() {
Vec3f velocity = { 0.0f, 0.0f, 0.0f };
Vec3s rotation = { 0, 0, 0 };
- gWorldInstance.AddActor(new AFinishline());
-
spawn_foliage((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_mario_raceway_tree_spawns));
spawn_piranha_plants((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_mario_raceway_piranha_plant_spawns));
spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_mario_raceway_item_box_spawns));
@@ -204,10 +202,6 @@ void MarioRaceway::BeginPlay() {
}
}
-void MarioRaceway::SpawnVehicles() {
-
-}
-
// Likely sets minimap boundaries
void MarioRaceway::MinimapSettings() {
D_8018D220 = reinterpret_cast<uint8_t (*)[1024]>(dma_textures(gTextureExhaust5, 0x443, 0x1000));
diff --git a/src/engine/courses/MarioRaceway.h b/src/engine/courses/MarioRaceway.h
index 9714fd0f5..a91226dbe 100644
--- a/src/engine/courses/MarioRaceway.h
+++ b/src/engine/courses/MarioRaceway.h
@@ -27,7 +27,6 @@ public:
virtual void Load() override;
virtual void LoadTextures() override;
virtual void BeginPlay() override;
- virtual void SpawnVehicles() override;
virtual void MinimapSettings() override;
virtual void InitCourseObjects() override;
virtual void SomeSounds() override;
diff --git a/src/engine/courses/MooMooFarm.cpp b/src/engine/courses/MooMooFarm.cpp
index 5adaeb2a6..cf83a920d 100644
--- a/src/engine/courses/MooMooFarm.cpp
+++ b/src/engine/courses/MooMooFarm.cpp
@@ -8,6 +8,7 @@
#include "engine/actors/AFinishline.h"
#include "engine/objects/BombKart.h"
#include "assets/moo_moo_farm_data.h"
+#include "engine/objects/MoleGroup.h"
#include "engine/objects/Mole.h"
extern "C" {
@@ -159,14 +160,156 @@ void MooMooFarm::LoadTextures() {
dma_textures(gTextureCow05Right, 0x00000400U, 0x00000800U);
}
-void MooMooFarm::BeginPlay() {
- gWorldInstance.AddActor(new AFinishline());
+// These are full arrays that are not used in the original game
+static std::vector<FVector> sMoleSpawns1 = {
+ { FVector(771, 20, -2022) },
+ { FVector(807, 15, -2063) },
+ { FVector(847, 18, -2040) },
+ { FVector(913, 14, -2054) },
+ { FVector(939, 21, -1997) },
+ { FVector(941, 17, -2024) },
+ { FVector(994, 17, -1994) },
+ { FVector(863, 22, -2010) },
+};
+
+static std::vector<FVector> sMoleSpawns2 = {
+ { FVector(1500, 2, 1140) },
+ { FVector(1510, 15, 1050) },
+ { FVector(1609, 21, 935) },
+ { FVector(1289, 3, 1269) },
+ { FVector(1468, 22, 1046) },
+ { FVector(1380, 12, 1154) },
+ { FVector(1297, 19, 1170) },
+ { FVector(1589, 11, 1004) },
+ { FVector(1414, 3, 1185) },
+ { FVector(1405, 4, 1254) },
+ { FVector(1463, 8, 1118) },
+};
+static std::vector<FVector> sMoleSpawns3 = {
+ { FVector(701, 2, 1279) },
+ { FVector(811, 8, 1278) },
+ { FVector(791, 16, 1229) },
+ { FVector(876, 15, 1266) },
+ { FVector(984, 23, 1248) },
+ { FVector(891, 20, 1242) },
+ { FVector(920, 15, 1304) },
+ { FVector(823, 6, 1327) },
+ { FVector(717, 8, 1239) },
+ { FVector(695, 19, 1176) },
+ { FVector(628, 8, 1191) },
+ { FVector(724, 4, 1339) },
+};
+
+void MooMooFarm::BeginPlay() {
if (gPlayerCountSelection1 != 4) {
spawn_foliage((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_moo_moo_farm_tree_spawn));
}
spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_moo_moo_farm_item_box_spawns));
+ for (size_t i = 0; i < gObjectParticle2_SIZE; i++) {
+ find_unused_obj_index(&gObjectParticle2[i]);
+ }
+
+ if (gGamestate != CREDITS_SEQUENCE) {
+ switch(gCCSelection) {
+ case CC_50: {
+ std::vector<FVector> moleSpawns1_50 = { { FVector(771, 20, -2022) },
+ { FVector(807, 15, -2063) },
+ { FVector(847, 18, -2040) },
+ { FVector(913, 14, -2054) } };
+
+ gWorldInstance.AddObject(new OMoleGroup(moleSpawns1_50));
+
+ std::vector<FVector> moleSpawns2_50 = { { FVector(1500, 2, 1140) }, { FVector(1510, 15, 1050) },
+ { FVector(1609, 21, 935) }, { FVector(1289, 3, 1269) },
+ { FVector(1468, 22, 1046) }, { FVector(1380, 12, 1154) } };
+
+ gWorldInstance.AddObject(new OMoleGroup(moleSpawns2_50));
+
+ std::vector<FVector> moleSpawns3_50 = { { FVector(701, 2, 1279) }, { FVector(811, 8, 1278) },
+ { FVector(791, 16, 1229) }, { FVector(876, 15, 1266) },
+ { FVector(984, 23, 1248) }, { FVector(891, 20, 1242) } };
+
+ gWorldInstance.AddObject(new OMoleGroup(moleSpawns3_50));
+ break;
+ }
+ case CC_100: {
+ std::vector<FVector> moleSpawns1_100 = { { FVector(771, 20, -2022) },
+ { FVector(807, 15, -2063) },
+ { FVector(847, 18, -2040) },
+ { FVector(913, 14, -2054) },
+ { FVector(939, 21, -1997) } };
+
+ gWorldInstance.AddObject(new OMoleGroup(moleSpawns1_100));
+
+ std::vector<FVector> moleSpawns2_100 = { { FVector(1500, 2, 1140) }, { FVector(1510, 15, 1050) },
+ { FVector(1609, 21, 935) }, { FVector(1289, 3, 1269) },
+ { FVector(1468, 22, 1046) }, { FVector(1380, 12, 1154) },
+ { FVector(1297, 19, 1170) }, { FVector(1589, 11, 1004) } };
+
+ gWorldInstance.AddObject(new OMoleGroup(moleSpawns2_100));
+
+ std::vector<FVector> moleSpawns3_100 = { { FVector(701, 2, 1279) }, { FVector(811, 8, 1278) },
+ { FVector(791, 16, 1229) }, { FVector(876, 15, 1266) },
+ { FVector(984, 23, 1248) }, { FVector(891, 20, 1242) },
+ { FVector(920, 15, 1304) }, { FVector(823, 6, 1327) } };
+
+ gWorldInstance.AddObject(new OMoleGroup(moleSpawns3_100));
+ break;
+ }
+ case CC_150: {
+ std::vector<FVector> moleSpawns1_150 = { { FVector(771, 20, -2022) },
+ { FVector(807, 15, -2063) },
+ { FVector(847, 18, -2040) },
+ { FVector(913, 14, -2054) },
+ { FVector(939, 21, -1997) } };
+
+ gWorldInstance.AddObject(new OMoleGroup(moleSpawns1_150));
+
+ std::vector<FVector> moleSpawns2_150 = { { FVector(1500, 2, 1140) }, { FVector(1510, 15, 1050) },
+ { FVector(1609, 21, 935) }, { FVector(1289, 3, 1269) },
+ { FVector(1468, 22, 1046) }, { FVector(1380, 12, 1154) },
+ { FVector(1297, 19, 1170) }, { FVector(1589, 11, 1004) } };
+
+ gWorldInstance.AddObject(new OMoleGroup(moleSpawns2_150));
+
+ std::vector<FVector> moleSpawns3_150 = { { FVector(701, 2, 1279) }, { FVector(811, 8, 1278) },
+ { FVector(791, 16, 1229) }, { FVector(876, 15, 1266) },
+ { FVector(984, 23, 1248) }, { FVector(891, 20, 1242) },
+ { FVector(920, 15, 1304) }, { FVector(823, 6, 1327) },
+ { FVector(717, 8, 1239) }, { FVector(695, 19, 1176) } };
+
+ gWorldInstance.AddObject(new OMoleGroup(moleSpawns3_150));
+ break;
+ }
+ case CC_EXTRA: {
+ std::vector<FVector> moleSpawns1_extra = { { FVector(771, 20, -2022) },
+ { FVector(807, 15, -2063) },
+ { FVector(847, 18, -2040) },
+ { FVector(913, 14, -2054) },
+ { FVector(939, 21, -1997) } };
+
+ gWorldInstance.AddObject(new OMoleGroup(moleSpawns1_extra));
+
+ std::vector<FVector> moleSpawns2_extra = { { FVector(1500, 2, 1140) }, { FVector(1510, 15, 1050) },
+ { FVector(1609, 21, 935) }, { FVector(1289, 3, 1269) },
+ { FVector(1468, 22, 1046) }, { FVector(1380, 12, 1154) },
+ { FVector(1297, 19, 1170) }, { FVector(1589, 11, 1004) } };
+
+ gWorldInstance.AddObject(new OMoleGroup(moleSpawns2_extra));
+
+ std::vector<FVector> moleSpawns3_extra = { { FVector(701, 2, 1279) }, { FVector(811, 8, 1278) },
+ { FVector(791, 16, 1229) }, { FVector(876, 15, 1266) },
+ { FVector(984, 23, 1248) }, { FVector(891, 20, 1242) },
+ { FVector(920, 15, 1304) }, { FVector(823, 6, 1327) } };
+
+ gWorldInstance.AddObject(new OMoleGroup(moleSpawns3_extra));
+ break;
+ }
+ }
+ }
+
if (gModeSelection == VERSUS) {
Vec3f pos = {0, 0, 0};
@@ -189,89 +332,6 @@ void MooMooFarm::MinimapSettings() {
D_8018D2E8 = 36;
}
-void MooMooFarm::InitCourseObjects() {
- size_t objectId;
- size_t i;
- if (gGamestate != CREDITS_SEQUENCE) {
- if ((gPlayerCount == 1) || ((gPlayerCount == 2) && (gModeSelection == VERSUS))) {
- switch (gCCSelection) { /* switch 2; irregular */
- case CC_50: /* switch 2 */
- D_8018D1C8 = 4;
- D_8018D1D0 = 6;
- D_8018D1D8 = 6;
- break;
- case CC_100: /* switch 2 */
- D_8018D1C8 = 5;
- D_8018D1D0 = 8;
- D_8018D1D8 = 8;
- break;
- case CC_150: /* switch 2 */
- D_8018D1C8 = 5;
- D_8018D1D0 = 8;
- D_8018D1D8 = 10;
- break;
- case CC_EXTRA: /* switch 2 */
- D_8018D1C8 = 5;
- D_8018D1D0 = 8;
- D_8018D1D8 = 8;
- break;
- }
- } else {
- D_8018D1C8 = 4;
- D_8018D1D0 = 6;
- D_8018D1D8 = 6;
- }
-
- Vec3f pos = {0, 22, 0};
- for (size_t i = 0; i < NUM_GROUP1_MOLES; i++) {
- D_8018D198[i] = 0;
- gWorldInstance.AddObject(new OMole(pos));
-
- }
-
- // for (i = 0; i < NUM_GROUP1_MOLES; i++) {
- // D_8018D198[i] = 0;
- // find_unused_obj_index(&indexObjectList1[i]);
- // }
- // for (i = 0; i < NUM_GROUP2_MOLES; i++) {
- // D_8018D1A8[i] = 0;
- // find_unused_obj_index(&indexObjectList1[i]);
- // }
- // for (i = 0; i < NUM_GROUP3_MOLES; i++) {
- // D_8018D1B8[i] = 0;
- // find_unused_obj_index(&indexObjectList1[i]);
- // }
- // for (i = 0; i < NUM_TOTAL_MOLES; i++) {
- // find_unused_obj_index(&gObjectParticle1[i]);
- // objectId = gObjectParticle1[i];
- // init_object(objectId, 0);
- // gObjectList[objectId].pos[0] = gMoleSpawns.asVec3sList[i][0] * xOrientation;
- // gObjectList[objectId].pos[2] = gMoleSpawns.asVec3sList[i][2];
- // func_800887C0(objectId);
- // gObjectList[objectId].sizeScaling = 0.7f;
- // }
-
-
- for (i = 0; i < gObjectParticle2_SIZE; i++) {
- find_unused_obj_index(&gObjectParticle2[i]);
- }
- }
-}
-
-void MooMooFarm::UpdateCourseObjects() {
- if (gGamestate != CREDITS_SEQUENCE) {
- //update_moles();
- }
-}
-
-void MooMooFarm::RenderCourseObjects(s32 cameraId) {
- if (gGamestate != CREDITS_SEQUENCE) {
- //render_object_moles(cameraId);
- }
-}
-
-void MooMooFarm::SomeSounds() {}
-
void MooMooFarm::WhatDoesThisDo(Player* player, int8_t playerId) {
if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x145) &&
((s16) gNearestWaypointByPlayerId[playerId] < 0x18B)) {
diff --git a/src/engine/courses/MooMooFarm.h b/src/engine/courses/MooMooFarm.h
index 0293b1b04..8b8b1b811 100644
--- a/src/engine/courses/MooMooFarm.h
+++ b/src/engine/courses/MooMooFarm.h
@@ -31,10 +31,6 @@ public:
virtual void LoadTextures() override;
virtual void BeginPlay() override;
virtual void MinimapSettings() override;
- virtual void InitCourseObjects() override;
- virtual void UpdateCourseObjects() override;
- virtual void RenderCourseObjects(s32 cameraId) override;
- virtual void SomeSounds() override;
virtual void WhatDoesThisDo(Player* player, int8_t playerId) override;
virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override;
virtual void MinimapFinishlinePosition() override;
diff --git a/src/engine/courses/PodiumCeremony.cpp b/src/engine/courses/PodiumCeremony.cpp
index 736a3ed9f..637dbc5d3 100644
--- a/src/engine/courses/PodiumCeremony.cpp
+++ b/src/engine/courses/PodiumCeremony.cpp
@@ -11,6 +11,7 @@
#include "engine/objects/Trophy.h"
#include "engine/objects/Podium.h"
#include "engine/objects/CheepCheep.h"
+#include "engine/particles/StarEmitter.h"
extern "C" {
#include "main.h"
@@ -186,7 +187,7 @@ void PodiumCeremony::BeginPlay() {
break;
}
- gWorldInstance.AddObject(new OTrophy(pos, type, OTrophy::Behaviour::PODIUM_CEREMONY));
+ OTrophy* trophy = reinterpret_cast<OTrophy*>(gWorldInstance.AddObject(new OTrophy(pos, type, OTrophy::Behaviour::PODIUM_CEREMONY)));
Vec3f kart = {0, 0, 0};
gWorldInstance.AddObject(new OBombKart(kart, &D_80164550[3][3], 3, 5, 1.25f));
diff --git a/src/engine/courses/RainbowRoad.cpp b/src/engine/courses/RainbowRoad.cpp
index b878eebfb..11ca643b8 100644
--- a/src/engine/courses/RainbowRoad.cpp
+++ b/src/engine/courses/RainbowRoad.cpp
@@ -134,8 +134,6 @@ void RainbowRoad::LoadTextures() {
}
void RainbowRoad::BeginPlay() {
- gWorldInstance.AddActor(new AFinishline());
-
spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_rainbow_road_item_box_spawns));
if (gGamestate != CREDITS_SEQUENCE) {
diff --git a/src/engine/courses/RoyalRaceway.cpp b/src/engine/courses/RoyalRaceway.cpp
index de1ab164b..7ff7579ff 100644
--- a/src/engine/courses/RoyalRaceway.cpp
+++ b/src/engine/courses/RoyalRaceway.cpp
@@ -171,8 +171,6 @@ void RoyalRaceway::LoadTextures() {
}
void RoyalRaceway::BeginPlay() {
- gWorldInstance.AddActor(new AFinishline());
-
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));
diff --git a/src/engine/courses/SherbetLand.cpp b/src/engine/courses/SherbetLand.cpp
index 7e77ecdbb..a452d2c03 100644
--- a/src/engine/courses/SherbetLand.cpp
+++ b/src/engine/courses/SherbetLand.cpp
@@ -130,22 +130,13 @@ void SherbetLand::LoadTextures() {
}
void SherbetLand::BeginPlay() {
- gWorldInstance.AddActor(new AFinishline());
-
spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_sherbet_land_item_box_spawns));
-
-
-// Originally, multiplayer did not spawn the big penguin
-// if (gPlayerCountSelection1 == 1) {
+ // Multiplayer does not spawn the big penguin
+// if (gPlayerCountSelection1 == 1) {
Vec3f pos = {-383.0f, 2.0f, -690.0f};
gWorldInstance.AddObject(new OPenguin(pos, 0, OPenguin::PenguinType::EMPEROR, OPenguin::Behaviour::STRUT));
-// }
-
- //! @bug Skip spawning penguins due to animation crash for now
- if (gGamestate == CREDITS_SEQUENCE) {
- return;
- }
+// }
Vec3f pos2 = {-2960.0f, -80.0f, 1521.0f};
auto penguin = reinterpret_cast<OPenguin*>(gWorldInstance.AddObject(new OPenguin(pos2, 0x150, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE)));
@@ -199,15 +190,17 @@ void SherbetLand::BeginPlay() {
auto penguin14 = reinterpret_cast<OPenguin*>(gWorldInstance.AddObject(new OPenguin(pos11, 0x9000, OPenguin::PenguinType::CHICK, OPenguin::Behaviour::SLIDE6)));
penguin14->MirrorModeAngleOffset = -0x4000;
- if (gModeSelection == VERSUS) {
- Vec3f kart = {0, 0, 0};
- gWorldInstance.AddObject(new OBombKart(kart, &D_80164550[0][50], 50, 3, 0.8333333f));
- gWorldInstance.AddObject(new OBombKart(kart, &D_80164550[0][100], 100, 1, 0.8333333f));
- gWorldInstance.AddObject(new OBombKart(kart, &D_80164550[0][150], 150, 3, 0.8333333f));
- gWorldInstance.AddObject(new OBombKart(kart, &D_80164550[0][200], 200, 1, 0.8333333f));
- gWorldInstance.AddObject(new OBombKart(kart, &D_80164550[0][250], 250, 3, 0.8333333f));
- gWorldInstance.AddObject(new OBombKart(kart, &D_80164550[0][0], 0, 0, 0.8333333f));
- gWorldInstance.AddObject(new OBombKart(kart, &D_80164550[0][0], 0, 0, 0.8333333f));
+ if (gGamestate != CREDITS_SEQUENCE) {
+ if (gModeSelection == VERSUS) {
+ Vec3f kart = {0, 0, 0};
+ gWorldInstance.AddObject(new OBombKart(kart, &D_80164550[0][50], 50, 3, 0.8333333f));
+ gWorldInstance.AddObject(new OBombKart(kart, &D_80164550[0][100], 100, 1, 0.8333333f));
+ gWorldInstance.AddObject(new OBombKart(kart, &D_80164550[0][150], 150, 3, 0.8333333f));
+ gWorldInstance.AddObject(new OBombKart(kart, &D_80164550[0][200], 200, 1, 0.8333333f));
+ gWorldInstance.AddObject(new OBombKart(kart, &D_80164550[0][250], 250, 3, 0.8333333f));
+ gWorldInstance.AddObject(new OBombKart(kart, &D_80164550[0][0], 0, 0, 0.8333333f));
+ gWorldInstance.AddObject(new OBombKart(kart, &D_80164550[0][0], 0, 0, 0.8333333f));
+ }
}
}
diff --git a/src/engine/courses/TestCourse.cpp b/src/engine/courses/TestCourse.cpp
index 30a925d80..aaf3143c3 100644
--- a/src/engine/courses/TestCourse.cpp
+++ b/src/engine/courses/TestCourse.cpp
@@ -25,7 +25,6 @@
#include "engine/objects/HotAirBalloon.h"
#include "engine/objects/Crab.h"
#include "engine/objects/Boos.h"
-#include "engine/particles/StarEmitter.h"
extern "C" {
#include "main.h"
@@ -151,6 +150,64 @@ void TestCourse::LoadTextures() {
dma_textures(gTexturePiranhaPlant9, 0x000003E8U, 0x00000800U);
}
+Path2D test_course_path2D[] = {
+ { 0, 0},
+ { 0, -100},
+ { 0, -200},
+ { 0, -300},
+ { 0, -400},
+ { 0, -500},
+ { 0, -600},
+ { 0, -700},
+ { 0, -800},
+ { 0, -900},
+ { 0, -1000},
+ { 0, -1096}, // Main point 1
+ { 100, -1090},
+ { 200, -1085},
+ { 300, -1080},
+ { 400, -1075},
+ { 500, -1072}, // Curve begins to smooth here
+ { 600, -1068},
+ { 700, -1065},
+ { 800, -1063},
+ { 900, -1061},
+ { 984, -1060}, // Main point 2
+ { 990, -900},
+ { 995, -800},
+ { 997, -700},
+ { 998, -600},
+ { 999, -500},
+ { 999, -400},
+ { 999, -300},
+ { 999, -200},
+ { 999, -100},
+ { 999, 0},
+ { 999, 100},
+ { 999, 200},
+ { 999, 300},
+ { 999, 400},
+ { 999, 500},
+ { 999, 600},
+ { 999, 700},
+ { 999, 800},
+ { 999, 900},
+ { 999, 940}, // Main point 3
+ { 900, 945},
+ { 800, 945},
+ { 700, 947},
+ { 600, 948},
+ { 500, 949},
+ { 400, 949},
+ { 300, 949},
+ { 200, 950},
+ { 100, 950},
+ { 0, 950}, // Main point 4
+
+ // End of path
+ { -32768, -32768 } // Terminator
+};
+
void TestCourse::BeginPlay() {
struct ActorSpawnData itemboxes[] = {
{ 200, 1500, 200 , 0},
@@ -174,8 +231,6 @@ void TestCourse::BeginPlay() {
{{ -32768, 0, 0 }, {0}},
};
- gWorldInstance.AddActor(new AFinishline());
-
spawn_all_item_boxes(itemboxes);
spawn_falling_rocks(rocks);
@@ -211,7 +266,6 @@ void TestCourse::BeginPlay() {
//gWorldInstance.AddObject(new OSnowman(FVector(0, 0, 0)));
//gWorldInstance.AddObject(new OTrashBin(FVector(0.0f, 0.0f, 0.0f), FRotation(0, 90, 0), 1.0f, OTrashBin::Behaviour::MUNCHING));
-//gWorldInstance.AddEmitter(new StarEmitter(FVector(0,50,0)));
//gWorldInstance.AddObject(new OHedgehog(FVector(0, 0, 0), FVector2D(0, -200), 9));
//gWorldInstance.AddObject(new OFlagpole(FVector(0, 0, -200), 0x400));
// gWorldInstance.AddObject(new OHotAirBalloon(FVector(0.0, 20.0f, -200.0f)));
@@ -221,6 +275,18 @@ void TestCourse::BeginPlay() {
// gWorldInstance.AddObject(new OBoos(10, IPathSpan(0, 5), IPathSpan(18, 23), IPathSpan(25, 50)));
+ gVehicle2DWaypoint = test_course_path2D;
+ gVehicle2DWaypointLength = 53;
+ D_80162EB0 = spawn_actor_on_surface(test_course_path2D[0].x, 2000.0f, test_course_path2D[0].z);
+
+ //gWorldInstance.AddTrain(ATrain::TenderStatus::HAS_TENDER, 5, 2.5f, 0);
+ //gWorldInstance.AddTrain(ATrain::TenderStatus::HAS_TENDER, 5, 2.5f, 8);
+
+ Vec3f pos2 = {0, 0, 0};
+
+ gWorldInstance.AddObject(new OBombKart(pos2, &D_80164550[0][25], 25, 4, 0.8333333f));
+ gWorldInstance.AddObject(new OBombKart(pos2, &D_80164550[0][45], 45, 4, 0.8333333f));
+
}
// Likely sets minimap boundaries
@@ -236,82 +302,6 @@ void TestCourse::MinimapSettings() {
D_80165728 = -240;
}
-Path2D test_course_path2D[] = {
- { 0, 0},
- { 0, -100},
- { 0, -200},
- { 0, -300},
- { 0, -400},
- { 0, -500},
- { 0, -600},
- { 0, -700},
- { 0, -800},
- { 0, -900},
- { 0, -1000},
- { 0, -1096}, // Main point 1
- { 100, -1090},
- { 200, -1085},
- { 300, -1080},
- { 400, -1075},
- { 500, -1072}, // Curve begins to smooth here
- { 600, -1068},
- { 700, -1065},
- { 800, -1063},
- { 900, -1061},
- { 984, -1060}, // Main point 2
- { 990, -900},
- { 995, -800},
- { 997, -700},
- { 998, -600},
- { 999, -500},
- { 999, -400},
- { 999, -300},
- { 999, -200},
- { 999, -100},
- { 999, 0},
- { 999, 100},
- { 999, 200},
- { 999, 300},
- { 999, 400},
- { 999, 500},
- { 999, 600},
- { 999, 700},
- { 999, 800},
- { 999, 900},
- { 999, 940}, // Main point 3
- { 900, 945},
- { 800, 945},
- { 700, 947},
- { 600, 948},
- { 500, 949},
- { 400, 949},
- { 300, 949},
- { 200, 950},
- { 100, 950},
- { 0, 950}, // Main point 4
-
- // End of path
- { -32768, -32768 } // Terminator
-};
-
-void TestCourse::SpawnVehicles() {
- gVehicle2DWaypoint = test_course_path2D;
- gVehicle2DWaypointLength = 53;
- D_80162EB0 = spawn_actor_on_surface(test_course_path2D[0].x, 2000.0f, test_course_path2D[0].z);
-
- //gWorldInstance.AddTrain(ATrain::TenderStatus::HAS_TENDER, 5, 2.5f, 0);
- //gWorldInstance.AddTrain(ATrain::TenderStatus::HAS_TENDER, 5, 2.5f, 8);
-
- Vec3f pos = {0, 0, 0};
-
- gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][25], 25, 4, 0.8333333f));
- gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][45], 45, 4, 0.8333333f));
-}
-
-void TestCourse::UpdateVehicles() {
- update_vehicle_trains();
-}
-
void TestCourse::InitCourseObjects() {}
void TestCourse::SomeSounds() {}
diff --git a/src/engine/courses/TestCourse.h b/src/engine/courses/TestCourse.h
index 2ba8a9f49..3421304e2 100644
--- a/src/engine/courses/TestCourse.h
+++ b/src/engine/courses/TestCourse.h
@@ -36,8 +36,6 @@ public:
virtual void Render(struct UnkStruct_800DC5EC*) override;
virtual void RenderCredits() override;
virtual void Collision() override;
- virtual void SpawnVehicles() override;
- virtual void UpdateVehicles() override;
virtual void Destroy() override;
virtual bool IsMod() override;
};
diff --git a/src/engine/courses/ToadsTurnpike.cpp b/src/engine/courses/ToadsTurnpike.cpp
index f6aa3f738..a9507acad 100644
--- a/src/engine/courses/ToadsTurnpike.cpp
+++ b/src/engine/courses/ToadsTurnpike.cpp
@@ -118,6 +118,14 @@ ToadsTurnpike::ToadsTurnpike() {
Props.Clouds = gToadsTurnpikeRainbowRoadStars;
Props.CloudList = gToadsTurnpikeRainbowRoadStars;
+
+ FVector finish;
+ finish.x = (gIsMirrorMode != 0) ? 100 + 138.0f : 100 - 138.0f;
+ finish.y = (f32) (0 - 15);
+ finish.z = 16;
+
+ this->FinishlineSpawnPoint = finish;
+
Props.MinimapFinishlineX = 0;
Props.MinimapFinishlineY = 0;
@@ -149,58 +157,53 @@ void ToadsTurnpike::LoadTextures() {
}
void ToadsTurnpike::BeginPlay() {
- Vec3f pos;
- pos[0] = (gIsMirrorMode != 0) ? D_80164490->posX + 138.0f : D_80164490->posX - 138.0f;
- pos[1] = (f32) (D_80164490->posY - 15);
- pos[2] = D_80164490->posZ;
-
- gWorldInstance.AddActor(new AFinishline(pos));
-
spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_toads_turnpike_item_box_spawns));
- uint32_t waypoint;
- f32 a = ((gCCSelection * 90.0) / 216.0f) + 4.583333333333333;
- f32 b = ((gCCSelection * 90.0) / 216.0f) + 2.9166666666666665;
- a /= 2; // Normally vehicle logic is only ran every 2 frames. This slows the vehicles down to match.
- b /= 2;
-
- // Other game modes spawn seven of each vehicle
- if (gModeSelection == TIME_TRIALS) {
- _numTrucks = 8;
- _numBuses = 8;
- _numTankerTrucks = 8;
- _numCars = 8;
- }
-
- for (size_t i = 0; i < _numTrucks; i++) {
- waypoint = CalculateWaypointDistribution(i, _numTrucks, gWaypointCountByPathIndex[0], 0);
- gWorldInstance.AddActor(new ATruck(a, b, &D_80164550[0][0], waypoint));
- }
+ if (gGamestate != CREDITS_SEQUENCE) {
+ uint32_t waypoint;
+ f32 a = ((gCCSelection * 90.0) / 216.0f) + 4.583333333333333;
+ f32 b = ((gCCSelection * 90.0) / 216.0f) + 2.9166666666666665;
+ a /= 2; // Normally vehicle logic is only ran every 2 frames. This slows the vehicles down to match.
+ b /= 2;
+
+ // Other game modes spawn seven of each vehicle
+ if (gModeSelection == TIME_TRIALS) {
+ _numTrucks = 8;
+ _numBuses = 8;
+ _numTankerTrucks = 8;
+ _numCars = 8;
+ }
- for (size_t i = 0; i < _numBuses; i++) {
- waypoint = CalculateWaypointDistribution(i, _numBuses, gWaypointCountByPathIndex[0], 75);
- gWorldInstance.AddActor(new ABus(a, b, &D_80164550[0][0], waypoint));
- }
+ for (size_t i = 0; i < _numTrucks; i++) {
+ waypoint = CalculateWaypointDistribution(i, _numTrucks, gWaypointCountByPathIndex[0], 0);
+ gWorldInstance.AddActor(new ATruck(a, b, &D_80164550[0][0], waypoint));
+ }
- for (size_t i = 0; i < _numTankerTrucks; i++) {
- waypoint = CalculateWaypointDistribution(i, _numTankerTrucks, gWaypointCountByPathIndex[0], 50);
- gWorldInstance.AddActor(new ATankerTruck(a, b, &D_80164550[0][0], waypoint));
- }
+ for (size_t i = 0; i < _numBuses; i++) {
+ waypoint = CalculateWaypointDistribution(i, _numBuses, gWaypointCountByPathIndex[0], 75);
+ gWorldInstance.AddActor(new ABus(a, b, &D_80164550[0][0], waypoint));
+ }
- for (size_t i = 0; i < _numCars; i++) {
- waypoint = CalculateWaypointDistribution(i, _numCars, gWaypointCountByPathIndex[0], 25);
- gWorldInstance.AddActor(new ACar(a, b, &D_80164550[0][0], waypoint));
- }
+ for (size_t i = 0; i < _numTankerTrucks; i++) {
+ waypoint = CalculateWaypointDistribution(i, _numTankerTrucks, gWaypointCountByPathIndex[0], 50);
+ gWorldInstance.AddActor(new ATankerTruck(a, b, &D_80164550[0][0], waypoint));
+ }
+
+ for (size_t i = 0; i < _numCars; i++) {
+ waypoint = CalculateWaypointDistribution(i, _numCars, gWaypointCountByPathIndex[0], 25);
+ gWorldInstance.AddActor(new ACar(a, b, &D_80164550[0][0], waypoint));
+ }
- if (gModeSelection == VERSUS) {
- Vec3f pos = {0, 0, 0};
- gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][50], 50, 3, 0.8333333f));
- gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][100], 100, 1, 0.8333333f));
- gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][150], 150, 3, 0.8333333f));
- gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][200], 200, 1, 0.8333333f));
- gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][250], 250, 3, 0.8333333f));
- gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f));
- gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f));
+ if (gModeSelection == VERSUS) {
+ Vec3f pos = {0, 0, 0};
+ gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][50], 50, 3, 0.8333333f));
+ gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][100], 100, 1, 0.8333333f));
+ gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][150], 150, 3, 0.8333333f));
+ gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][200], 200, 1, 0.8333333f));
+ gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][250], 250, 3, 0.8333333f));
+ gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f));
+ gWorldInstance.AddObject(new OBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f));
+ }
}
}
diff --git a/src/engine/courses/WarioStadium.cpp b/src/engine/courses/WarioStadium.cpp
index 44a8d5d1a..d60d754c0 100644
--- a/src/engine/courses/WarioStadium.cpp
+++ b/src/engine/courses/WarioStadium.cpp
@@ -114,6 +114,14 @@ WarioStadium::WarioStadium() {
Props.Clouds = gWarioStadiumStars;
Props.CloudList = gWarioStadiumStars;
+
+ FVector finish;
+ finish.x = (gIsMirrorMode != 0) ? 13 + 12.0f : 13 - 12.0f;
+ finish.y = (f32) (0 - 15);
+ finish.z = -9;
+
+ this->FinishlineSpawnPoint = finish;
+
Props.MinimapFinishlineX = 0;
Props.MinimapFinishlineY = 0;
@@ -156,14 +164,6 @@ void WarioStadium::LoadTextures() {
}
void WarioStadium::BeginPlay() {
- Vec3f finish;
- finish[0] = (gIsMirrorMode != 0) ? D_80164490->posX + 12.0f : D_80164490->posX - 12.0f;
- (gIsMirrorMode != 0) ? D_80164490->posX + 12.0f : D_80164490->posX - 12.0f;
- finish[1] = D_8015F8D0[1] = (f32) (D_80164490->posY - 15);
- finish[2] = D_8015F8D0[2] = D_80164490->posZ;
-
- gWorldInstance.AddActor(new AFinishline(finish));
-
spawn_all_item_boxes((struct ActorSpawnData*) LOAD_ASSET_RAW(d_course_wario_stadium_item_box_spawns));
Vec3f pos = { -131.0f, 83.0f, 286.0f };
diff --git a/src/engine/courses/YoshiValley.cpp b/src/engine/courses/YoshiValley.cpp
index 9366f45ea..98d887b03 100644
--- a/src/engine/courses/YoshiValley.cpp
+++ b/src/engine/courses/YoshiValley.cpp
@@ -142,8 +142,6 @@ void YoshiValley::BeginPlay() {
Vec3f velocity = { 0.0f, 0.0f, 0.0f };
Vec3s rotation = { 0, 0, 0 };
- gWorldInstance.AddActor(new AFinishline());
-
spawn_foliage((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_yoshi_valley_tree_spawn));
spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_yoshi_valley_item_box_spawns));
vec3f_set(position, -2300.0f, 0.0f, 634.0f);
diff --git a/src/engine/objects/Bat.cpp b/src/engine/objects/Bat.cpp
index f32ef2d41..b90f7c857 100644
--- a/src/engine/objects/Bat.cpp
+++ b/src/engine/objects/Bat.cpp
@@ -19,19 +19,21 @@ const char* sBoardwalkTexList[] = { gTextureBat1, gTextureBat2, gTextureBat3, gT
size_t OBat::_count = 0;
OBat::OBat(const FVector& pos, const FRotation& rot) {
- s32 objectId = indexObjectList1[0];
- init_texture_object(objectId, (uint8_t*)d_course_banshee_boardwalk_bat_tlut, sBoardwalkTexList, 0x20U,
+
+ find_unused_obj_index(&_objectIndex);
+
+ init_texture_object(_objectIndex, (uint8_t*)d_course_banshee_boardwalk_bat_tlut, sBoardwalkTexList, 0x20U,
(u16) 0x00000040);
- gObjectList[objectId].orientation[0] = rot.pitch;
- gObjectList[objectId].orientation[1] = rot.roll;
- gObjectList[objectId].orientation[2] = rot.yaw; // 0x8000
+ gObjectList[_objectIndex].orientation[0] = rot.pitch;
+ gObjectList[_objectIndex].orientation[1] = rot.roll;
+ gObjectList[_objectIndex].orientation[2] = rot.yaw; // 0x8000
_count++;
}
void OBat::Tick() {
s32 var_s2;
- s32 temp_s0;
+ s32 objectIndex;
Object* object;
if (D_8018CFC8 != 0) {
@@ -40,28 +42,28 @@ void OBat::Tick() {
if (D_8018D000 != 0) {
D_8018D000 -= 1;
}
- temp_s0 = indexObjectList1[0];
- func_80072E54(temp_s0, 0, 3, 1, 0, -1);
- func_80073514(temp_s0);
- object = &gObjectList[temp_s0];
- func_80073CB0(temp_s0, &object->primAlpha, -0x00001000, 0x00001000, 0x00000400, 0, -1);
+ objectIndex = _objectIndex;
+ func_80072E54(objectIndex, 0, 3, 1, 0, -1);
+ func_80073514(objectIndex);
+ object = &gObjectList[objectIndex];
+ func_80073CB0(objectIndex, &object->primAlpha, -0x00001000, 0x00001000, 0x00000400, 0, -1);
object->orientation[2] = object->primAlpha + 0x8000;
if ((D_8018CFB0 != 0) || (D_8018CFC8 != 0)) {
D_8018CFD8 = 0;
for (var_s2 = 0; var_s2 < 40; var_s2++) {
- temp_s0 = gObjectParticle2[var_s2];
- if (temp_s0 == -1) {
+ objectIndex = gObjectParticle2[var_s2];
+ if (objectIndex == -1) {
continue;
}
- object = &gObjectList[temp_s0];
+ object = &gObjectList[objectIndex];
if (object->state == 0) {
continue;
}
- OBat::func_8007D8D4(temp_s0, 1);
- OBat::func_8007DAF8(temp_s0, 1);
- OBat::func_8007D794(temp_s0);
+ OBat::func_8007D8D4(objectIndex, 1);
+ OBat::func_8007DAF8(objectIndex, 1);
+ OBat::func_8007D794(objectIndex);
if (object->state == 0) {
delete_object_wrapper(&gObjectParticle2[var_s2]);
}
@@ -74,19 +76,19 @@ void OBat::Tick() {
if ((D_8018CFE8 != 0) || (D_8018D000 != 0)) {
D_8018D010 = 0;
for (var_s2 = 0; var_s2 < 30; var_s2++) {
- temp_s0 = gObjectParticle3[var_s2];
- if (temp_s0 == -1) {
+ objectIndex = gObjectParticle3[var_s2];
+ if (objectIndex == -1) {
continue;
}
- object = &gObjectList[temp_s0];
+ object = &gObjectList[objectIndex];
if (object->state == 0) {
continue;
}
- OBat::func_8007D8D4(temp_s0, 2);
- OBat::func_8007DAF8(temp_s0, 2);
- OBat::func_8007D794(temp_s0);
+ OBat::func_8007D8D4(objectIndex, 2);
+ OBat::func_8007DAF8(objectIndex, 2);
+ OBat::func_8007D794(objectIndex);
if (object->state == 0) {
delete_object_wrapper(&gObjectParticle3[var_s2]);
}
@@ -103,7 +105,7 @@ void OBat::Draw(s32 cameraId) {
s32 objectIndex;
Camera* temp_s7;
- objectIndex = indexObjectList1[0];
+ objectIndex = _objectIndex;
temp_s7 = &camera1[cameraId];
OBat::func_80046F60((u8*)gObjectList[objectIndex].activeTLUT, (u8*)gObjectList[objectIndex].activeTexture, 0x00000020, 0x00000040,
5);
diff --git a/src/engine/objects/Bat.h b/src/engine/objects/Bat.h
index 39a9e65d8..f9e0df074 100644
--- a/src/engine/objects/Bat.h
+++ b/src/engine/objects/Bat.h
@@ -56,4 +56,5 @@ private:
FVector _pos;
static size_t _count;
size_t _idx;
+ s32 _objectIndex;
};
diff --git a/src/engine/objects/Crab.cpp b/src/engine/objects/Crab.cpp
index 3a71e075d..c722a9037 100644
--- a/src/engine/objects/Crab.cpp
+++ b/src/engine/objects/Crab.cpp
@@ -28,26 +28,24 @@ extern "C" {
size_t OCrab::_count = 0;
OCrab::OCrab(const FVector2D& start, const FVector2D& end) {
- s32 objectId;
_idx = _count;
_start = start;
_end = end;
- objectId = indexObjectList1[_idx];
- init_object(objectId, 0);
- gObjectList[objectId].pos[0] = gObjectList[objectId].origin_pos[0] = start.x * xOrientation;
- gObjectList[objectId].pos[2] = gObjectList[objectId].origin_pos[2] = start.z;
+ find_unused_obj_index(&_objectIndex);
- gObjectList[objectId].unk_01C[0] = end.x * xOrientation;
- gObjectList[objectId].unk_01C[2] = end.z;
+ 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::Tick(void) {
- s32 objectIndex;
-
- objectIndex = indexObjectList1[_idx];
+ s32 objectIndex = _objectIndex;
if (gObjectList[objectIndex].state != 0) {
OCrab::func_80082B34(objectIndex);
func_8008A6DC(objectIndex, 500.0f);
@@ -58,7 +56,7 @@ void OCrab::Tick(void) {
void OCrab::Draw(s32 cameraId) {
Camera* camera;
- s32 objectIndex = indexObjectList1[_idx];
+ s32 objectIndex = _objectIndex;
if (gObjectList[objectIndex].state >= 2) {
Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(common_vtx_hedgehog);
camera = &camera1[cameraId];
@@ -74,11 +72,9 @@ void OCrab::Draw(s32 cameraId) {
void OCrab::DrawModel(s32 cameraId) {
s32 someIndex;
- s32 test;
-
- test = indexObjectList1[_idx];
- func_8008A364(test, cameraId, 0x2AABU, 800);
- if (is_obj_flag_status_active(test, VISIBLE) != 0) {
+ s32 objectIndex = _objectIndex;
+ func_8008A364(objectIndex, cameraId, 0x2AABU, 800);
+ if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) {
Camera *camera;
s32 objectIndex;
diff --git a/src/engine/objects/Crab.h b/src/engine/objects/Crab.h
index 4cadd3b87..2d1ef5e93 100644
--- a/src/engine/objects/Crab.h
+++ b/src/engine/objects/Crab.h
@@ -46,4 +46,5 @@ private:
FVector2D _end;
static size_t _count;
s32 _idx;
+ s32 _objectIndex;
};
diff --git a/src/engine/objects/Flagpole.cpp b/src/engine/objects/Flagpole.cpp
index 682f74915..7b5e5af20 100644
--- a/src/engine/objects/Flagpole.cpp
+++ b/src/engine/objects/Flagpole.cpp
@@ -20,13 +20,15 @@ OFlagpole::OFlagpole(const FVector& pos, s16 direction) {
_pos = pos;
_direction = direction;
- init_object(indexObjectList1[_idx], 0);
+ find_unused_obj_index(&_objectIndex);
+
+ init_object(_objectIndex, 0);
_count++;
}
void OFlagpole::Tick() { // func_80083080
- s32 objectIndex = indexObjectList1[_idx];
+ s32 objectIndex = _objectIndex;
if (gObjectList[objectIndex].state != 0) {
OFlagpole::func_80083018(objectIndex);
@@ -35,7 +37,7 @@ void OFlagpole::Tick() { // func_80083080
}
void OFlagpole::Draw(s32 cameraId) { // func_80055228
- s32 objectIndex = indexObjectList1[_idx];
+ s32 objectIndex = _objectIndex;
func_8008A364(objectIndex, cameraId, 0x4000U, 0x000005DC);
if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) {
diff --git a/src/engine/objects/Flagpole.h b/src/engine/objects/Flagpole.h
index 5824fcf18..034db865e 100644
--- a/src/engine/objects/Flagpole.h
+++ b/src/engine/objects/Flagpole.h
@@ -42,4 +42,5 @@ private:
s16 _direction;
static size_t _count;
size_t _idx;
+ s32 _objectIndex;
};
diff --git a/src/engine/objects/HotAirBalloon.cpp b/src/engine/objects/HotAirBalloon.cpp
index 234eef6d9..917fd7354 100644
--- a/src/engine/objects/HotAirBalloon.cpp
+++ b/src/engine/objects/HotAirBalloon.cpp
@@ -27,11 +27,13 @@ OHotAirBalloon::OHotAirBalloon(const FVector& pos) {
_visible = &mod;
}
- init_object(indexObjectList1[0], 0);
+ find_unused_obj_index(&_objectIndex);
+
+ init_object(_objectIndex, 0);
}
void OHotAirBalloon::Tick() {
- s32 objectIndex = indexObjectList1[0];
+ s32 objectIndex = _objectIndex;
if (*_visible) {
if (gObjectList[objectIndex].state != 0) {
@@ -49,7 +51,7 @@ void OHotAirBalloon::Tick() {
void OHotAirBalloon::Draw(s32 cameraId) {
s32 objectIndex;
- objectIndex = indexObjectList1[0];
+ objectIndex = _objectIndex;
if (*_visible) {
if (gGamestate != CREDITS_SEQUENCE) {
func_8008A1D0(objectIndex, cameraId, 0x000005DC, 0x00000BB8);
diff --git a/src/engine/objects/HotAirBalloon.h b/src/engine/objects/HotAirBalloon.h
index 301e111c4..5dad406db 100644
--- a/src/engine/objects/HotAirBalloon.h
+++ b/src/engine/objects/HotAirBalloon.h
@@ -31,4 +31,5 @@ public:
private:
FVector _pos;
bool *_visible;
+ s32 _objectIndex;
};
diff --git a/src/engine/objects/Mole.cpp b/src/engine/objects/Mole.cpp
index 7cc21e118..fdf5e7b08 100644
--- a/src/engine/objects/Mole.cpp
+++ b/src/engine/objects/Mole.cpp
@@ -22,64 +22,59 @@ extern "C" {
#include "external.h"
}
-OMole::OMole(Vec3f pos) {
+size_t OMole::_count = 0;
- find_unused_obj_index(&indexObjectList1[0]);
-}
+OMole::OMole(FVector pos, OMoleGroup* group) {
+ _idx = _count;
+ _group = group;
-void OMole::Tick() {
- s32 var_s1;
- s32 objectIndex;
+ find_unused_obj_index(&_objectIndex);
- for (var_s1 = 0; var_s1 < D_8018D1C8; var_s1++) {
- objectIndex = indexObjectList1[var_s1];
- if (gObjectList[objectIndex].state == 0) {
- if (are_players_in_course_section(8, 9) != 0) {
- func_80081FF4(objectIndex, 1);
- }
- } else {
- OMole::func_800821AC(objectIndex, 1);
- }
- }
+ gObjectList[_objectIndex].pos[0] = pos.x * xOrientation;
+ gObjectList[_objectIndex].pos[1] = pos.y;
+ gObjectList[_objectIndex].pos[2] = pos.z;
- for (var_s1 = 0; var_s1 < D_8018D1D0; var_s1++) {
- objectIndex = indexObjectList2[var_s1];
- if (gObjectList[objectIndex].state == 0) {
- if (are_players_in_course_section(0x0010, 0x0013) != 0) {
- OMole::func_80081FF4(objectIndex, 2);
- }
- } else {
- OMole::func_800821AC(objectIndex, 2);
- }
- }
+ gObjectList[_objectIndex].origin_pos[0] = pos.x * xOrientation;
+ gObjectList[_objectIndex].origin_pos[1] = pos.y - 9.0;
+ gObjectList[_objectIndex].origin_pos[2] = pos.z;
- for (var_s1 = 0; var_s1 < D_8018D1D8; var_s1++) {
- objectIndex = indexObjectList3[var_s1];
- if (gObjectList[objectIndex].state == 0) {
- if (are_players_in_course_section(0x0011, 0x0014) != 0) {
- func_80081FF4(objectIndex, 3);
- }
- } else {
- OMole::func_800821AC(objectIndex, 3);
- }
- }
+ // This is probably the mole particles
+ find_unused_obj_index(&_moleIndex);
+ init_object(_moleIndex, 0);
+ gObjectList[_moleIndex].pos[0] = pos.x * xOrientation;
+ gObjectList[_moleIndex].pos[2] = pos.z;
+ func_800887C0(_moleIndex);
+ gObjectList[_moleIndex].sizeScaling = 0.7f;
- for (var_s1 = 0; var_s1 < gObjectParticle2_SIZE; var_s1++) {
- objectIndex = gObjectParticle2[var_s1];
- if (gObjectList[objectIndex].state != 0) {
- OMole::func_80081790(objectIndex);
+ _count++;
+}
+
+void OMole::Tick() {
+ if (_idx == 0) {
+ for (size_t i = 0; i < gObjectParticle2_SIZE; i++) {
+ s32 objectIndex = gObjectParticle2[i];
+ if (gObjectList[objectIndex].state != 0) {
+ OMole::func_80081790(objectIndex);
+ }
}
}
}
void OMole::Draw(s32 cameraId) {
+ size_t i;
+ OMole::func_80054D00(_objectIndex, cameraId);
+
+ OMole::func_80054EB8();
+ if (_idx == 0) {
+ OMole::func_80054F04(cameraId);
+ }
}
void OMole::func_80081790(s32 objectIndex) {
switch (gObjectList[objectIndex].state) {
case 0:
- break; /* irregular */
+ break;
case 1:
if (func_80087E08(objectIndex, gObjectList[objectIndex].velocity[1], 0.3f, gObjectList[objectIndex].unk_034,
gObjectList[objectIndex].orientation[1], 0x00000032) != 0) {
@@ -94,10 +89,6 @@ void OMole::func_80081790(s32 objectIndex) {
}
}
-
-
-
-
void OMole::func_80081AFC(s32 objectIndex, s32 arg1) {
s8* sp2C;
Object* object;
@@ -119,7 +110,7 @@ void OMole::func_80081AFC(s32 objectIndex, s32 arg1) {
case 0x3:
if (object->unk_0AE == 0) {
func_80086EAC(objectIndex, 2, 4);
- func_8008153C(objectIndex);
+ OMole::func_8008153C(objectIndex);
object_next_state(objectIndex);
func_800C98B8(object->pos, object->velocity, SOUND_ARG_LOAD(0x19, 0x01, 0x80, 0x07));
}
@@ -139,18 +130,21 @@ void OMole::func_80081AFC(s32 objectIndex, s32 arg1) {
if (object->unk_0AE == 0) {
clear_object_flag(objectIndex, 0x00000200);
func_80072428(objectIndex);
- switch (arg1) { /* switch 1; irregular */
- case 1: /* switch 1 */
- sp2C = D_8018D198;
- break;
- case 2: /* switch 1 */
- sp2C = D_8018D1A8;
- break;
- case 3: /* switch 1 */
- sp2C = D_8018D1B8;
- break;
- }
- sp2C[object->type] = 0;
+
+ _group->_moles[object->type].Active = false;
+
+ // switch (arg1) {
+ // case 1:
+ // sp2C = D_8018D198;
+ // break;
+ // case 2:
+ // sp2C = D_8018D1A8;
+ // break;
+ // case 3:
+ // sp2C = D_8018D1B8;
+ // break;
+ // }
+ //sp2C[object->type] = 0;
}
break;
case 0:
@@ -162,17 +156,55 @@ void OMole::func_80081AFC(s32 objectIndex, s32 arg1) {
}
}
+void OMole::func_8008153C(s32 objectIndex) {
+ UNUSED s32 stackPadding[3];
+ s32 sp70;
+ s32 var_s1;
+ s32 var_s7;
+ s32 loopObjectIndex;
+
+ if (gPlayerCountSelection1 == 1) {
+ sp70 = 8;
+ } else {
+ sp70 = 4;
+ }
+
+ for (var_s7 = 0; var_s7 < sp70; var_s7++) {
+ for (var_s1 = 0; var_s1 < gObjectParticle2_SIZE; var_s1++) {
+ loopObjectIndex = gObjectParticle2[var_s1];
+
+ if (gObjectList[loopObjectIndex].state != 0) {
+ continue;
+ }
+
+ u8* mole = (u8*) LOAD_ASSET_RAW(d_course_moo_moo_farm_mole_dirt);
+ init_object(loopObjectIndex, 0);
+ gObjectList[loopObjectIndex].activeTLUT = d_course_moo_moo_farm_mole_dirt;
+ gObjectList[loopObjectIndex].tlutList = mole;
+ gObjectList[loopObjectIndex].sizeScaling = 0.15f;
+ gObjectList[loopObjectIndex].velocity[1] = random_int(0x000AU);
+ gObjectList[loopObjectIndex].velocity[1] = (gObjectList[loopObjectIndex].velocity[1] * 0.1) + 4.8;
+ gObjectList[loopObjectIndex].unk_034 = random_int(5U);
+ gObjectList[loopObjectIndex].unk_034 = (gObjectList[loopObjectIndex].unk_034 * 0.01) + 0.8;
+ gObjectList[loopObjectIndex].orientation[1] = (0x10000 / sp70) * var_s1;
+ gObjectList[loopObjectIndex].origin_pos[0] = gObjectList[objectIndex].origin_pos[0];
+ gObjectList[loopObjectIndex].origin_pos[1] = gObjectList[objectIndex].origin_pos[1] - 13.0;
+ gObjectList[loopObjectIndex].origin_pos[2] = gObjectList[objectIndex].origin_pos[2];
+ break;
+ }
+ }
+}
+
void OMole::func_80081D34(s32 objectIndex) {
Player* player;
- Camera* var_s4;
- s32 var_s2;
+ Camera* camera;
s32 var_s5;
Object* object;
var_s5 = 0;
player = gPlayerOne;
- var_s4 = camera1;
- for (var_s2 = 0; var_s2 < D_8018D158; var_s2++, player++, var_s4++) {
+ camera = camera1;
+ for (size_t i = 0; i < D_8018D158; i++, player++, camera++) {
if ((is_obj_flag_status_active(objectIndex, 0x00000200) != 0) && !(player->effects & 0x80000000) &&
(has_collided_with_player(objectIndex, player) != 0)) {
if ((player->type & 0x8000) && !(player->type & 0x100)) {
@@ -182,11 +214,11 @@ void OMole::func_80081D34(s32 objectIndex) {
func_80072180();
}
if (player->effects & 0x200) {
- func_800C9060(var_s2, 0x1900A046U);
+ func_800C9060(i, 0x1900A046U);
} else {
player->soundEffects |= 2;
}
- object->direction_angle[1] = var_s4->rot[1];
+ object->direction_angle[1] = camera->rot[1];
object->velocity[1] = (player->unk_094 / 2) + 3.0;
object->unk_034 = player->unk_094 + 1.0;
if (object->velocity[1] >= 5.0) {
@@ -209,66 +241,23 @@ void OMole::func_80081D34(s32 objectIndex) {
}
}
+static const char* frames[] = {
+ gTextureMole1,
+ gTextureMole2,
+ gTextureMole3,
+ gTextureMole4,
+ gTextureMole5,
+ gTextureMole6,
+ gTextureMole7,
+ d_course_moo_moo_farm_mole_dirt,
+};
-void OMole::func_80081FF4(s32 objectIndex, s32 arg1) {
- UNUSED s32 stackPadding0;
- UNUSED s32 stackPadding1;
- s32 moleCount;
- s16 var_v1;
- s16 offset;
- s32 var_a0;
- s8* var_a2;
-
- init_object(objectIndex, 0);
- gObjectList[objectIndex].unk_04C = random_int(0x001EU) + 5;
- switch (arg1) { /* irregular */
- case 1:
- var_a2 = D_8018D198;
- moleCount = NUM_GROUP1_MOLES;
- offset = 0;
- break;
- case 2:
- var_a2 = D_8018D1A8;
- moleCount = NUM_GROUP2_MOLES;
- offset = 24;
- // offset = NUM_GROUP1_MOLES;
- break;
- case 3:
- var_a2 = D_8018D1B8;
- moleCount = NUM_GROUP3_MOLES;
- offset = 57;
- // offset = NUM_GROUP1_MOLES + NUM_GROUP2_MOLES;
- break;
- }
- var_v1 = random_int(moleCount);
- for (var_a0 = 0; var_a0 < moleCount; var_a0++) {
- if (var_a2[var_v1] != 0) {
- var_v1++;
- if (var_v1 == moleCount) {
- var_v1 = 0;
- }
- } else {
- var_a2[var_v1] = 1;
- gObjectList[objectIndex].type = var_v1;
- break;
- }
- }
- /*
- Ideally `gMoleSpawns` wouldn't be a union at all and its just be a list of Vec3s
- Even more ideally each mole group would have its own array for its spawns
- gObjectList[objectIndex].origin_pos[0] = gMoleSpawns.asVec3sList[offset + var_v1][0] * xOrientation;
- gObjectList[objectIndex].origin_pos[1] = gMoleSpawns.asVec3sList[offset + var_v1][1] - 9.0;
- gObjectList[objectIndex].origin_pos[2] = gMoleSpawns.asVec3sList[offset + var_v1][2];
- */
- gObjectList[objectIndex].origin_pos[0] = gMoleSpawns.asFlatList[offset + (var_v1 * 3) + 0] * xOrientation;
- gObjectList[objectIndex].origin_pos[1] = gMoleSpawns.asFlatList[offset + (var_v1 * 3) + 1] - 9.0;
- gObjectList[objectIndex].origin_pos[2] = gMoleSpawns.asFlatList[offset + (var_v1 * 3) + 2];
-}
void OMole::func_80081848(s32 objectIndex) {
- u8* mole = (u8*) LOAD_ASSET_RAW(d_course_moo_moo_farm_mole_frames);
- u8* tlut = (u8*) LOAD_ASSET_RAW(d_course_moo_moo_farm_mole_tlut);
- init_texture_object(objectIndex, (u8*)d_course_moo_moo_farm_mole_tlut, (const char**) mole, 0x20U, (u16) 0x00000040);
+ init_texture_object(objectIndex, (u8*)d_course_moo_moo_farm_mole_tlut, (const char**) frames, 0x20U, (u16) 0x00000040);
+ //gObjectList[objectIndex].activeTexture = (const char*)d_course_moo_moo_farm_mole_frames;
+ //gObjectList[objectIndex].activeTLUT = (const char*)d_course_moo_moo_farm_mole_tlut;
+
gObjectList[objectIndex].sizeScaling = 0.15f;
gObjectList[objectIndex].textureListIndex = 0;
set_obj_origin_offset(objectIndex, 0.0f, 0.0f, 0.0f);
@@ -358,9 +347,9 @@ void OMole::func_80054E10(s32 objectIndex) {
void OMole::func_80054EB8() {
s32 someIndex;
- for (someIndex = 0; someIndex < NUM_TOTAL_MOLES; someIndex++) {
- func_80054E10(gObjectParticle1[someIndex]);
- }
+ //for (someIndex = 0; someIndex < NUM_TOTAL_MOLES; someIndex++) {
+ func_80054E10(_moleIndex);
+ //}
}
void OMole::func_80054D00(s32 objectIndex, s32 cameraId) {
@@ -382,41 +371,24 @@ void OMole::func_80054D00(s32 objectIndex, s32 cameraId) {
}
void OMole::func_80054F04(s32 cameraId) {
- s32 var_s2;
- s32 objectIndex;
- Camera* sp44;
- Object* object;
+ Camera* camera = &camera1[cameraId];
- sp44 = &camera1[cameraId];
gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D0079C8);
load_texture_block_rgba16_mirror((u8*) LOAD_ASSET_RAW(d_course_moo_moo_farm_mole_dirt), 0x00000010, 0x00000010);
- for (var_s2 = 0; var_s2 < gObjectParticle2_SIZE; var_s2++) {
- objectIndex = gObjectParticle2[var_s2];
- object = &gObjectList[objectIndex];
+
+if (_idx == 0) {
+ for (size_t i = 0; i < gObjectParticle2_SIZE; i++) {
+ s32 objectIndex = gObjectParticle2[i];
+ Object* object = &gObjectList[objectIndex];
if (object->state > 0) {
func_8008A364(objectIndex, cameraId, 0x2AABU, 0x000000C8);
if ((is_obj_flag_status_active(objectIndex, VISIBLE) != 0) && (gMatrixHudCount <= MTX_HUD_POOL_SIZE_MAX)) {
- object->orientation[1] = func_800418AC(object->pos[0], object->pos[2], sp44->pos);
+ object->orientation[1] = func_800418AC(object->pos[0], object->pos[2], camera->pos);
rsp_set_matrix_gObjectList(objectIndex);
gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D006980);
}
}
}
+}
gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF);
}
-
-void OMole::render_object_moles(s32 cameraId) {
- s32 i;
-
- for (i = 0; i < NUM_GROUP1_MOLES; i++) {
- OMole::func_80054D00(indexObjectList1[i], cameraId);
- }
- for (i = 0; i < NUM_GROUP2_MOLES; i++) {
- OMole::func_80054D00(indexObjectList2[i], cameraId);
- }
- for (i = 0; i < NUM_GROUP3_MOLES; i++) {
- OMole::func_80054D00(indexObjectList3[i], cameraId);
- }
- OMole::func_80054EB8();
- OMole::func_80054F04(cameraId);
-} \ No newline at end of file
diff --git a/src/engine/objects/Mole.h b/src/engine/objects/Mole.h
index 7ff95c58c..7707b5383 100644
--- a/src/engine/objects/Mole.h
+++ b/src/engine/objects/Mole.h
@@ -3,6 +3,8 @@
#include <libultraship.h>
#include <vector>
#include "Object.h"
+#include "CoreMath.h"
+#include "MoleGroup.h"
extern "C" {
#include "macros.h"
@@ -15,14 +17,11 @@ extern "C" {
#include "some_data.h"
}
+class OMoleGroup;
class OMole : public OObject {
public:
- enum Behaviour : uint16_t {
- };
-
-public:
- explicit OMole(Vec3f pos);
+ explicit OMole(FVector pos, OMoleGroup* group);
virtual void Tick() override;
virtual void Draw(s32 cameraId) override;
@@ -33,20 +32,18 @@ public:
void render_object_moles(s32 cameraId);
void func_80054D00(s32 objectIndex, s32 cameraId);
void func_800821AC(s32 objectIndex, s32 arg1);
- void func_80081FF4(s32 objectIndex, s32 arg1);
void func_80081D34(s32 objectIndex);
void func_80081AFC(s32 objectIndex, s32 arg1);
void func_80081A88(s32 objectIndex);
void func_80081924(s32 objectIndex);
void func_80081848(s32 objectIndex);
void func_80081790(s32 objectIndex);
+ void func_8008153C(s32 objectIndex);
+ s32 _objectIndex;
+ s32 _moleIndex;
private:
- s32 _idx;
- s32 _state;
- s32 _timer;
- s32 _status;
- bool _toggle;
-
- SplineData *spline;
+ static size_t _count;
+ size_t _idx;
+ OMoleGroup* _group;
};
diff --git a/src/engine/objects/MoleGroup.cpp b/src/engine/objects/MoleGroup.cpp
new file mode 100644
index 000000000..6e98edbbb
--- /dev/null
+++ b/src/engine/objects/MoleGroup.cpp
@@ -0,0 +1,50 @@
+#include "MoleGroup.h"
+#include "Mole.h"
+
+extern "C" {
+#include "code_80057C60.h"
+#include "update_objects.h"
+#include "math_util.h"
+#include "math_util_2.h"
+}
+
+OMoleGroup::OMoleGroup(std::vector<FVector> spawns) {
+ for (auto& pos : spawns) {
+ pos.x * xOrientation;
+ OMole* ptr = reinterpret_cast<OMole*>(gWorldInstance.AddObject(new OMole(pos, this)));
+ _moles.push_back({ptr, pos, false});
+ }
+}
+
+void OMoleGroup::Tick() {
+ for (auto &mole : _moles) {
+ if (gObjectList[mole.Mole->_objectIndex].state == 0) {
+ func_80081FF4(mole.Mole->_objectIndex);
+ } else {
+ mole.Mole->func_800821AC(mole.Mole->_objectIndex, 1);
+ }
+ }
+}
+
+void OMoleGroup::func_80081FF4(s32 objectIndex) {
+ init_object(objectIndex, 0);
+ gObjectList[objectIndex].unk_04C = random_int(30) + 5;
+
+ s16 mole = random_int(_moles.size() - 1);
+ for (size_t i = 0; i < _moles.size() - 1; i++) {
+ if (_moles[mole].Active == true) {
+ mole++;
+ if (mole == _moles.size()) {
+ mole = 0;
+ }
+ } else { // if not active
+ _moles[mole].Active = true;
+ gObjectList[objectIndex].type = mole;
+ break;
+ }
+ }
+
+ gObjectList[objectIndex].origin_pos[0] = _moles[mole].Pos.x * xOrientation;
+ gObjectList[objectIndex].origin_pos[1] = _moles[mole].Pos.y - 9.0;
+ gObjectList[objectIndex].origin_pos[2] = _moles[mole].Pos.z;
+}
diff --git a/src/engine/objects/MoleGroup.h b/src/engine/objects/MoleGroup.h
new file mode 100644
index 000000000..dfb920985
--- /dev/null
+++ b/src/engine/objects/MoleGroup.h
@@ -0,0 +1,27 @@
+#pragma once
+
+#include <libultraship.h>
+#include <vector>
+#include "World.h"
+#include "CoreMath.h"
+#include "Mole.h"
+
+class OMole;
+
+class OMoleGroup : public OObject {
+public:
+ struct MoleEntry {
+ OMole* Mole;
+ FVector Pos;
+ bool Active;
+ };
+
+ explicit OMoleGroup(std::vector<FVector> moles);
+
+ virtual void Tick() override;
+
+ void func_80081FF4(s32 objectIndex);
+
+
+ std::vector<MoleEntry> _moles;
+};
diff --git a/src/engine/objects/Object.cpp b/src/engine/objects/Object.cpp
index eb23b853e..d532dd566 100644
--- a/src/engine/objects/Object.cpp
+++ b/src/engine/objects/Object.cpp
@@ -20,3 +20,4 @@ void OObject::Expire() { }
void OObject::Destroy() {
PendingDestroy = true;
}
+void OObject::Reset() { }
diff --git a/src/engine/objects/Object.h b/src/engine/objects/Object.h
index c02deda23..b78b27240 100644
--- a/src/engine/objects/Object.h
+++ b/src/engine/objects/Object.h
@@ -22,4 +22,5 @@ public:
virtual void Draw(s32 cameraId);
virtual void Expire();
virtual void Destroy(); // Mark object for deletion at the start of the next frame
+ virtual void Reset();
};
diff --git a/src/engine/objects/Penguin.cpp b/src/engine/objects/Penguin.cpp
index c690e1ef2..1eeb00ff4 100644
--- a/src/engine/objects/Penguin.cpp
+++ b/src/engine/objects/Penguin.cpp
@@ -33,22 +33,16 @@ extern "C" {
extern s8 gPlayerCount;
}
-size_t OPenguin::_count = 0;
OPenguin::OPenguin(Vec3f pos, u16 direction, PenguinType type, Behaviour behaviour) {
- _idx = _count;
_type = type;
_bhv = behaviour;
- if (_idx >= 32) {
- printf("MAX penguin REACHED (32), skipping\n");
- return;
- }
+ find_unused_obj_index(&_objectIndex);
- s32 objectIndex = indexObjectList1[_idx];
- init_object(objectIndex, 0);
+ init_object(_objectIndex, 0);
- Object *object = &gObjectList[objectIndex];
+ Object *object = &gObjectList[_objectIndex];
object->origin_pos[0] = pos[0] * xOrientation;
object->origin_pos[1] = pos[1];
object->origin_pos[2] = pos[2];
@@ -75,14 +69,11 @@ OPenguin::OPenguin(Vec3f pos, u16 direction, PenguinType type, Behaviour behavio
object->boundingBoxSize = 0x000C;
break;
}
-
- _count++;
}
void OPenguin::Tick(void) {
- s32 objectIndex;
+ s32 objectIndex = _objectIndex;
- objectIndex = indexObjectList1[_idx];
if (gObjectList[objectIndex].state != 0) {
if (_type == PenguinType::EMPEROR) {
OPenguin::EmperorPenguin(objectIndex);
@@ -90,7 +81,7 @@ void OPenguin::Tick(void) {
OPenguin::OtherPenguin(objectIndex);
}
- OPenguin::Behaviours(objectIndex, _idx);
+ OPenguin::Behaviours(objectIndex);
}
if (func_80072320(objectIndex, 1) != 0) {
func_80089820(objectIndex, 1.75f, 1.5f, 0x1900A046U);
@@ -107,7 +98,7 @@ void OPenguin::Tick(void) {
}
void OPenguin::Draw(s32 cameraId) {
- s32 objectIndex;
+ s32 objectIndex = _objectIndex;
s32 temp_s1;
s32 drawDistance;
u16 var_s1;
@@ -121,26 +112,26 @@ void OPenguin::Draw(s32 cameraId) {
var_s3 = 0x00015F90;
}
- objectIndex = indexObjectList1[_idx];
+
if (gObjectList[objectIndex].state >= 2) {
- if (gPlayerCountSelection1 == 1) {
+
+ // This code decreased draw dist if there's more players.
+ // The var_s1 = 0x4000 for everything is just a guess.
+ // It seems to check the angle of the camera.
+ // These changes were so instance indices are not required.
+
+ //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;
- }
- }
+ drawDistance = 1500;
+ //} else {
+ // if (func_80072320(objectIndex, 8) != 0) {
+ // drawDistance = 500;
+ // var_s1 = 0x4000;
+ // } else {
+ // drawDistance = 600;
+ // 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);
@@ -148,7 +139,7 @@ void OPenguin::Draw(s32 cameraId) {
}
}
-void OPenguin::Behaviours(s32 objectIndex, s32 arg1) { // func_800850B0
+void OPenguin::Behaviours(s32 objectIndex) { // func_800850B0
Object* object;
object = &gObjectList[objectIndex];
@@ -157,7 +148,7 @@ void OPenguin::Behaviours(s32 objectIndex, s32 arg1) { // func_800850B0
OPenguin::func_80085080(objectIndex);
break;
case 2:
- OPenguin::func_8008502C(objectIndex, arg1);
+ OPenguin::func_8008502C(objectIndex);
break;
case 3:
OPenguin::func_80084D2C(objectIndex, 0);
@@ -226,17 +217,17 @@ void OPenguin::func_80084D2C(s32 objectIndex, s32 arg1) {
}
break;
case 3:
- switch (arg1) { /* switch 1; irregular */
- case 0: /* switch 1 */
+ switch (arg1) {
+ case 0:
sp24 = 1.0f;
break;
- case 1: /* switch 1 */
+ case 1:
sp24 = 1.5f;
break;
- case 2: /* switch 1 */
+ case 2:
sp24 = 2.0f;
break;
- case 3: /* switch 1 */
+ case 3:
sp24 = 2.5f;
break;
}
@@ -285,7 +276,7 @@ void OPenguin::func_80085080(s32 objectIndex) {
func_800873F4(objectIndex);
}
-void OPenguin::func_8008502C(s32 objectIndex, s32 arg1) {
+void OPenguin::func_8008502C(s32 objectIndex) {
func_80088038(objectIndex, gObjectList[objectIndex].unk_01C[1], gObjectList[objectIndex].unk_0C6);
object_calculate_new_pos_offset(objectIndex);
func_800873F4(objectIndex);
@@ -371,6 +362,8 @@ void OPenguin::OtherPenguin(s32 objectIndex) {
}
}
+bool OPenguin::_toggle = false;
+
void OPenguin::InitOtherPenguin(s32 objectIndex) {
Object* object;
@@ -380,7 +373,7 @@ void OPenguin::InitOtherPenguin(s32 objectIndex) {
object->vertex = (Vtx*) d_course_sherbet_land_unk_data11;
//object->boundingBoxSize = 4;
object->unk_09C = 2;
- object->unk_04C = random_int(0x012CU);
+ object->unk_04C = random_int(300);
set_object_flag(objectIndex, 0x04000220);
// This code has been significantly refactored from the original func_800845C8
@@ -388,7 +381,15 @@ void OPenguin::InitOtherPenguin(s32 objectIndex) {
switch(_bhv) {
case Behaviour::CIRCLE:
object->unk_01C[1] = Diameter;
- object->unk_0C4 = (_idx << 0xF) & 0xFFFF;
+
+ if (_toggle) {
+ object->unk_0C4 = 0x8000;
+ } else {
+ object->unk_0C4 = 0;
+ }
+
+ _toggle = !_toggle;
+
//object->unk_0DD = 2;
func_800722A4(objectIndex, 8);
break;
@@ -411,3 +412,7 @@ void OPenguin::InitOtherPenguin(s32 objectIndex) {
object->type = get_animation_length(d_course_sherbet_land_unk_data11, 0);
object_next_state(objectIndex);
}
+
+void OPenguin::Reset() {
+ _toggle = false;
+}
diff --git a/src/engine/objects/Penguin.h b/src/engine/objects/Penguin.h
index 63c2207c1..72ba16285 100644
--- a/src/engine/objects/Penguin.h
+++ b/src/engine/objects/Penguin.h
@@ -40,32 +40,22 @@ public:
explicit OPenguin(Vec3f pos, u16 direction, PenguinType type, Behaviour behaviour);
- ~OPenguin() {
- _count--;
- }
-
- static size_t GetCount() {
- return _count;
- }
-
-
virtual void Tick() override;
virtual void Draw(s32 cameraId) override;
+ virtual void Reset() override;
private:
- void Behaviours(s32 objectIndex, s32 arg1);
+ void Behaviours(s32 objectIndex);
void EmperorPenguin(s32 objectIndex);
void func_80085080(s32 objectIndex);
- void func_8008502C(s32 objectIndex, s32 arg1);
+ void func_8008502C(s32 objectIndex);
void func_80084D2C(s32 objectIndex, s32 arg1);
void InitEmperorPenguin(s32 objectIndex);
void OtherPenguin(s32 objectIndex);
void InitOtherPenguin(s32 objectIndex);
- static size_t _count;
- s32 _idx;
+ static bool _toggle;
+ s32 _objectIndex;
PenguinType _type;
Behaviour _bhv;
-
-
};
diff --git a/src/engine/objects/Podium.cpp b/src/engine/objects/Podium.cpp
index 1922c98a5..d8f1e2ff2 100644
--- a/src/engine/objects/Podium.cpp
+++ b/src/engine/objects/Podium.cpp
@@ -29,45 +29,66 @@ OPodium::OPodium(const FVector& pos) {
_pos = 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);
- }
+ find_unused_obj_index(&_podium1Index);
+ find_unused_obj_index(&_podium2Index);
+ find_unused_obj_index(&_podium3Index);
+
+ //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);
+ init_object(_podium1Index, 0);
+ init_object(_podium2Index, 0);
+ init_object(_podium3Index, 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);
- }
+
+ if (gObjectList[_podium1Index].state != 0) {
+ OPodium::func_80086528(_podium1Index, 0);
+ OPodium::func_80086424(_podium1Index);
+ }
+
+ if (gObjectList[_podium2Index].state != 0) {
+ OPodium::func_80086528(_podium2Index, 1);
+ OPodium::func_80086424(_podium2Index);
+ }
+
+ if (gObjectList[_podium3Index].state != 0) {
+ OPodium::func_80086528(_podium3Index, 2);
+ OPodium::func_80086424(_podium3Index);
}
}
void OPodium::Draw(s32 cameraId) { // func_80055F48
- for (size_t i = 0; i < NUM_PODIUMS; i++) {
- Object* object;
+ Object* object = &gObjectList[_podium1Index];
+ 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);
+ }
- object = &gObjectList[indexObjectList1[i]];
+ object = &gObjectList[_podium2Index];
+ 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);
+ }
+
+ object = &gObjectList[_podium3Index];
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) {
diff --git a/src/engine/objects/Podium.h b/src/engine/objects/Podium.h
index ea79d7232..fafdfe63d 100644
--- a/src/engine/objects/Podium.h
+++ b/src/engine/objects/Podium.h
@@ -33,7 +33,8 @@ public:
void func_80086528(s32 objectIndex, s32 arg1);
private:
-
- s32 _idx;
+ s32 _podium1Index;
+ s32 _podium2Index;
+ s32 _podium3Index;
FVector _pos;
};
diff --git a/src/engine/objects/Seagull.cpp b/src/engine/objects/Seagull.cpp
index cced70348..11043238f 100644
--- a/src/engine/objects/Seagull.cpp
+++ b/src/engine/objects/Seagull.cpp
@@ -31,12 +31,11 @@ SplineData* D_800E633C[] = { &D_800E6034, &D_800E60F0, &D_800E61B4, &D_800E6280
size_t OSeagull::_count = 0;
-OSeagull::OSeagull(Vec3f pos) {
- size_t objectIndex;
+OSeagull::OSeagull(FVector pos) {
_idx = _count;
- _pos[0] = pos[0];
- _pos[1] = pos[1];
- _pos[2] = pos[2];
+ _pos.x = pos.x;
+ _pos.y = pos.y;
+ _pos.z = pos.z;
s16 randZ;
s16 randX;
@@ -45,18 +44,16 @@ OSeagull::OSeagull(Vec3f pos) {
randY = random_int(20);
randZ = random_int(200) + -100.0;
- //for (i = 0; i < NUM_SEAGULLS; i++) {
+ find_unused_obj_index(&_objectIndex);
+ init_object(_objectIndex, 0);
- objectIndex = indexObjectList2[_idx];
- init_object(objectIndex, 0);
-
- set_obj_origin_pos(objectIndex, pos[0], pos[1], pos[2]);
+ set_obj_origin_pos(_objectIndex, pos.x, pos.y, pos.z);
if (_idx < (NUM_SEAGULLS / 2)) {
- gObjectList[objectIndex].unk_0D5 = 0;
+ gObjectList[_objectIndex].unk_0D5 = 0;
} else {
- gObjectList[objectIndex].unk_0D5 = 1;
+ gObjectList[_objectIndex].unk_0D5 = 1;
}
_count++;
@@ -64,7 +61,7 @@ OSeagull::OSeagull(Vec3f pos) {
void OSeagull::Tick() {
Object* object;
- s32 objectIndex = indexObjectList2[_idx];
+ s32 objectIndex = _objectIndex;
object = &gObjectList[objectIndex];
if (object->state == 0) {
@@ -83,10 +80,11 @@ void OSeagull::Tick() {
if (gGamestate != CREDITS_SEQUENCE) {
func_800C98B8(object->pos, D_80183E40, SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x43));
} else {
- objectIndex = indexObjectList2[1];
- if (gCutsceneShotTimer <= 150) {
- object = &gObjectList[objectIndex];
- func_800C98B8(object->pos, D_80183E40, SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x43));
+ if (_idx == 1) {
+ if (gCutsceneShotTimer <= 150) {
+ object = &gObjectList[_objectIndex];
+ func_800C98B8(object->pos, D_80183E40, SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x43));
+ }
}
}
}
@@ -108,7 +106,7 @@ void OSeagull::Tick() {
}
void OSeagull::Draw(s32 cameraId) { // render_object_seagulls
- s32 objectIndex = indexObjectList2[_idx];
+ s32 objectIndex = _objectIndex;
if (func_8008A364(objectIndex, cameraId, 0x5555U, 0x000005DC) < 0x9C401 && CVarGetInteger("gNoCulling", 0) == 0) {
D_80165908 = 1;
@@ -172,7 +170,7 @@ void OSeagull::func_8008241C(s32 objectIndex, s32 arg1) {
randY = random_int(0x0014);
randZ = random_int(0x00C8) + -100.0;
- set_obj_origin_pos(objectIndex, (randX + _pos[0]) * xOrientation, randY + _pos[1], randZ + _pos[2]);
+ set_obj_origin_pos(objectIndex, (randX + _pos.x) * xOrientation, randY + _pos.y, randZ + _pos.z);
set_obj_direction_angle(objectIndex, 0U, 0U, 0U);
gObjectList[objectIndex].unk_034 = 1.0f;
func_80086EF0(objectIndex);
diff --git a/src/engine/objects/Seagull.h b/src/engine/objects/Seagull.h
index c6898dcc2..a0e5cd233 100644
--- a/src/engine/objects/Seagull.h
+++ b/src/engine/objects/Seagull.h
@@ -19,7 +19,7 @@ extern "C" {
//! @todo unk_0D5 needs to be a struct variable probably. What does it do? Behaviour?
class OSeagull : public OObject {
public:
- explicit OSeagull(Vec3f pos);
+ explicit OSeagull(FVector pos);
~OSeagull() {
_count--;
@@ -38,7 +38,8 @@ public:
void func_8008241C(s32 objectIndex, s32 arg1);
void func_80082714(s32 objectIndex, s32 arg1);
private:
- Vec3f _pos;
+ s32 _objectIndex;
+ FVector _pos;
static size_t _count;
s32 _idx;
bool _toggle;
diff --git a/src/engine/objects/Snowman.cpp b/src/engine/objects/Snowman.cpp
index c05f464ef..2052a8adb 100644
--- a/src/engine/objects/Snowman.cpp
+++ b/src/engine/objects/Snowman.cpp
@@ -20,31 +20,30 @@ 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;
+ find_unused_obj_index(&_headIndex);
+ init_object(_headIndex, 0);
+ gObjectList[_headIndex].origin_pos[0] = pos.x * xOrientation;
+ gObjectList[_headIndex].origin_pos[1] = pos.y + 5.0 + 3.0;
+ gObjectList[_headIndex].origin_pos[2] = pos.z;
+ gObjectList[_headIndex].pos[0] = pos.x * xOrientation;
+ gObjectList[_headIndex].pos[1] = pos.y + 5.0 + 3.0;
+ gObjectList[_headIndex].pos[2] = pos.z;
+
+ find_unused_obj_index(&_bodyIndex);
+ init_object(_bodyIndex, 0);
+ gObjectList[_bodyIndex].origin_pos[0] = pos.x * xOrientation;
+ gObjectList[_bodyIndex].origin_pos[1] = pos.y + 3.0;
+ gObjectList[_bodyIndex].origin_pos[2] = pos.z;
+ gObjectList[_bodyIndex].unk_0D5 = 0; // Section Id no longer used.
+
+ gObjectList[_bodyIndex].pos[0] = pos.x * xOrientation;
+ gObjectList[_bodyIndex].pos[1] = pos.y + 3.0;
+ gObjectList[_bodyIndex].pos[2] = pos.z;
_count++;
}
void OSnowman::Tick() {
- s32 var_s0;
s32 var_s3;
s32 var_s4;
s32 objectIndex;
@@ -52,8 +51,8 @@ void OSnowman::Tick() {
//! @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];
+ for (size_t i = 0; i < gObjectParticle2_SIZE; i++) {
+ objectIndex = gObjectParticle2[i];
if (objectIndex == DELETED_OBJECT_ID) {
continue;
@@ -66,14 +65,13 @@ void OSnowman::Tick() {
if (gObjectList[objectIndex].state != 0) {
continue;
}
- delete_object_wrapper(&gObjectParticle2[var_s0]);
- if (var_s0) {} // ??
+ delete_object_wrapper(&gObjectParticle2[i]);
}
}
//for (var_s0 = 0; var_s0 < NUM_SNOWMEN; var_s0++) {
- var_s4 = indexObjectList1[_idx];
- var_s3 = indexObjectList2[_idx];
+ var_s4 = _bodyIndex;
+ var_s3 = _headIndex;
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) {
@@ -113,7 +111,7 @@ void OSnowman::func_800836F0(Vec3f pos) {
void OSnowman::DrawHead(s32 cameraId) {
s32 objectIndex;
Camera* camera = &camera1[cameraId];
- objectIndex = indexObjectList1[_idx];
+ objectIndex = _bodyIndex;
if (gObjectList[objectIndex].state >= 2) {
func_8008A364(objectIndex, cameraId, 0x2AABU, 0x00000258);
if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) {
@@ -127,7 +125,7 @@ void OSnowman::DrawHead(s32 cameraId) {
(u8*)gObjectList[objectIndex].activeTexture, gObjectList[objectIndex].vertex,
0x00000040, 0x00000040, 0x00000040, 0x00000020);
}
- objectIndex = indexObjectList2[_idx];
+ objectIndex = _headIndex;
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,
diff --git a/src/engine/objects/Snowman.h b/src/engine/objects/Snowman.h
index e3e2a0138..ffa927769 100644
--- a/src/engine/objects/Snowman.h
+++ b/src/engine/objects/Snowman.h
@@ -46,9 +46,11 @@ public:
void func_80083538(s32 objectIndex, Vec3f arg1, s32 arg2, s32 arg3);
void func_8008379C(s32 objectIndex);
-
private:
FVector _pos;
static size_t _count;
size_t _idx;
+ s32 _objectIndex;
+ s32 _headIndex;
+ s32 _bodyIndex;
};
diff --git a/src/engine/objects/Thwomp.cpp b/src/engine/objects/Thwomp.cpp
index afa12b03b..6a04f07bb 100644
--- a/src/engine/objects/Thwomp.cpp
+++ b/src/engine/objects/Thwomp.cpp
@@ -52,11 +52,9 @@ OThwomp::OThwomp(s16 x, s16 z, s16 direction, f32 scale, s16 behaviour, s16 prim
_boundingBoxSize = boundingBoxSize;
State = (States)behaviour;
- if (_idx >= 32) {
- printf("MAX THWOMPS REACHED (32), skipping\n");
- return;
- }
- s32 objectId = indexObjectList1[_idx];
+ find_unused_obj_index(&_objectIndex);
+
+ s32 objectId = _objectIndex;
init_object(objectId, 0);
gObjectList[objectId].origin_pos[0] = x * xOrientation;
gObjectList[objectId].origin_pos[2] = z;
@@ -79,9 +77,8 @@ void OThwomp::Tick60fps() { // func_80081210
s32 var_s2_3;
s32 var_s4;
- objectIndex = indexObjectList1[_idx];
- func_800722CC(objectIndex, 0x00000010);
- OThwomp::SetVisibility(objectIndex);
+ func_800722CC(_objectIndex, 0x00000010);
+ OThwomp::SetVisibility(_objectIndex);
OThwomp::func_8007F8D8();
@@ -92,26 +89,25 @@ void OThwomp::Tick60fps() { // func_80081210
D_80165834[1] += 0x200;
}
- objectIndex = indexObjectList1[_idx];
- if (gObjectList[objectIndex].state != 0) {
+ if (gObjectList[_objectIndex].state != 0) {
switch (State) {
case STATIONARY:
- OThwomp::StationaryBehaviour(objectIndex);
+ OThwomp::StationaryBehaviour(_objectIndex);
break;
case MOVE_AND_ROTATE:
- OThwomp::MoveAndRotateBehaviour(objectIndex);
+ OThwomp::MoveAndRotateBehaviour(_objectIndex);
break;
case MOVE_FAR:
- OThwomp::MoveFarBehaviour(objectIndex);
+ OThwomp::MoveFarBehaviour(_objectIndex);
break;
case STATIONARY_FAST:
- OThwomp::StationaryFastBehaviour(objectIndex);
+ OThwomp::StationaryFastBehaviour(_objectIndex);
break;
case JAILED:
- OThwomp::JailedBehaviour(objectIndex);
+ OThwomp::JailedBehaviour(_objectIndex);
break;
case SLIDE:
- OThwomp::SlidingBehaviour(objectIndex);
+ OThwomp::SlidingBehaviour(_objectIndex);
break;
}
}
@@ -121,27 +117,25 @@ void OThwomp::Tick60fps() { // func_80081210
player->tyres[FRONT_LEFT].unk_14 &= ~3;
player->unk_046 &= ~0x0006;
- objectIndex = indexObjectList1[_idx];
if (!(player->effects & BOO_EFFECT)) {
- OThwomp::func_80080B28(objectIndex, var_s4);
+ OThwomp::func_80080B28(_objectIndex, var_s4);
}
- if (is_obj_flag_status_active(objectIndex, 0x00020000) != 0) {
- OThwomp::SetPlayerCrushedEffect(objectIndex, player);
+ if (is_obj_flag_status_active(_objectIndex, 0x00020000) != 0) {
+ OThwomp::SetPlayerCrushedEffect(_objectIndex, player);
}
- if (is_obj_flag_status_active(objectIndex, 0x00010000) != 0) {
- OThwomp::func_80080A4C(objectIndex, var_s4);
+ if (is_obj_flag_status_active(_objectIndex, 0x00010000) != 0) {
+ OThwomp::func_80080A4C(_objectIndex, var_s4);
}
}
OThwomp::func_8007542C(3);
- objectIndex = indexObjectList1[_idx];
- if (func_80072320(objectIndex, 0x00000020) == 0) {
+ if (func_80072320(_objectIndex, 0x00000020) == 0) {
return;
}
- func_800722CC(objectIndex, 0x00000020);
- OThwomp::AddParticles(objectIndex);
+ func_800722CC(_objectIndex, 0x00000020);
+ OThwomp::AddParticles(_objectIndex);
for (var_s4 = 0; var_s4 < gObjectParticle2_SIZE; var_s4++) {
objectIndex = gObjectParticle2[var_s4];
@@ -160,7 +154,7 @@ void OThwomp::Tick60fps() { // func_80081210
}
void OThwomp::func_800810F4(s32 objectIndex) {
- switch (gObjectList[objectIndex].state) { /* irregular */
+ switch (gObjectList[objectIndex].state) {
case 0:
break;
case 1:
@@ -336,7 +330,6 @@ void OThwomp::SetVisibility(s32 objectIndex) { // func_8008A4CC
void OThwomp::func_8007F8D8() {
Player* player;
- s32 objectIndex;
s32 var_s0;
s32 someIndex;
s32 var_s4;
@@ -345,11 +338,10 @@ void OThwomp::func_8007F8D8() {
player = gPlayerOne;
var_s4 = 1;
- objectIndex = indexObjectList1[_idx];
- object = &gObjectList[objectIndex];
+ object = &gObjectList[_objectIndex];
if (object->unk_0D5 == 3) {
var_s0 = 0;
- if ((object->state >= 2) && (func_80072354(objectIndex, 8) != 0)) {
+ if ((object->state >= 2) && (func_80072354(_objectIndex, 8) != 0)) {
var_s0 = 1;
}
var_s4 *= var_s0;
@@ -368,7 +360,6 @@ void OThwomp::func_8007F8D8() {
s32 OThwomp::func_8007F75C(s32 playerId) {
s32 someIndex;
- s32 objectIndex;
s32 temp_s7;
s32 var_s6;
s32 waypoint;
@@ -377,17 +368,15 @@ s32 OThwomp::func_8007F75C(s32 playerId) {
var_s6 = 0;
if ((waypoint >= 0xAA) && (waypoint < 0xB5)) {
temp_s7 = random_int(0x0032U) + 0x32;
- objectIndex = indexObjectList1[_idx];
- if (gObjectList[objectIndex].unk_0D5 == 3) {
+ if (gObjectList[_objectIndex].unk_0D5 == 3) {
var_s6 = 1;
- OThwomp::func_8007F660(objectIndex, playerId, temp_s7);
+ OThwomp::func_8007F660(_objectIndex, playerId, temp_s7);
}
} else if ((waypoint >= 0xD7) && (waypoint < 0xE2)) {
- objectIndex = indexObjectList1[_idx];
- if (gObjectList[objectIndex].unk_0D5 == 3) {
+ if (gObjectList[_objectIndex].unk_0D5 == 3) {
var_s6 = 1;
- OThwomp::func_8007F6C4(objectIndex, playerId);
+ OThwomp::func_8007F6C4(_objectIndex, playerId);
}
}
return var_s6;
@@ -668,7 +657,7 @@ Lights1 D_800E4680 = gdSPDefLights1(85, 85, 85, 255, 255, 255, 0, 0, 120);
Lights1 D_800E4698 = gdSPDefLights1(85, 85, 85, 255, 255, 255, 0, 0, 120);
void OThwomp::Draw(s32 cameraId) {
- s32 objectIndex = 0;
+ s32 objectIndex = _objectIndex;
s32 i;
UNUSED s32 stackPadding0;
s16 minusone, plusone;
@@ -677,14 +666,12 @@ void OThwomp::Draw(s32 cameraId) {
camera = &camera1[cameraId];
if (cameraId == PLAYER_ONE) {
- objectIndex = indexObjectList1[_idx];
clear_object_flag(objectIndex, 0x00070000);
func_800722CC(objectIndex, 0x00000110);
}
OThwomp::TranslateThwompLights();
- objectIndex = indexObjectList1[_idx];
minusone = gObjectList[objectIndex].unk_0DF - 1;
plusone = gObjectList[objectIndex].unk_0DF + 1;
diff --git a/src/engine/objects/Thwomp.h b/src/engine/objects/Thwomp.h
index 22c674bb5..75aeaf1a0 100644
--- a/src/engine/objects/Thwomp.h
+++ b/src/engine/objects/Thwomp.h
@@ -113,6 +113,7 @@ public:
private:
static size_t _count;
s32 _idx;
+ s32 _objectIndex;
s16 _faceDirection;
//! @todo Write this better. This effects the squish size and the bounding box size.
// We should probably return to the programmer the pointer to the actor so they can do thwomp->squishSize = value.
diff --git a/src/engine/objects/TrashBin.cpp b/src/engine/objects/TrashBin.cpp
index 43d43b1fc..6aa556470 100644
--- a/src/engine/objects/TrashBin.cpp
+++ b/src/engine/objects/TrashBin.cpp
@@ -26,7 +26,9 @@ OTrashBin::OTrashBin(const FVector& pos, const FRotation& rotation, f32 scale, O
_scale = scale;
_bhv = bhv;
- init_object(indexObjectList1[1], 0);
+ find_unused_obj_index(&_objectIndex);
+
+ init_object(_objectIndex, 0);
if (GetCourse() != GetBansheeBoardwalk()) {
_drawBin = true;
@@ -34,26 +36,23 @@ OTrashBin::OTrashBin(const FVector& pos, const FRotation& rotation, f32 scale, O
}
void OTrashBin::Tick() {
- s32 objectIndex = indexObjectList1[1];
- OTrashBin::func_8007E00C(objectIndex);
+ OTrashBin::func_8007E00C(_objectIndex);
switch(_bhv) {
case STATIC:
break;
case MUNCHING:
- func_8007DDC0(objectIndex);
+ func_8007DDC0(_objectIndex);
break;
}
}
void OTrashBin::Draw(s32 cameraId) {
- s32 objectIndex;
Object* object;
- objectIndex = indexObjectList1[1];
- func_8008A364(objectIndex, cameraId, 0x5555U, 0x00000320);
- if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) {
- object = &gObjectList[objectIndex];
+ func_8008A364(_objectIndex, cameraId, 0x5555U, 0x00000320);
+ if (is_obj_flag_status_active(_objectIndex, VISIBLE) != 0) {
+ object = &gObjectList[_objectIndex];
if (object->state >= 2) {
func_80043220(object->pos, object->orientation, object->sizeScaling, object->model);
}
diff --git a/src/engine/objects/TrashBin.h b/src/engine/objects/TrashBin.h
index 2ef500f92..2ebe13e87 100644
--- a/src/engine/objects/TrashBin.h
+++ b/src/engine/objects/TrashBin.h
@@ -41,5 +41,6 @@ private:
FRotation _rot;
float _scale;
size_t _idx;
+ s32 _objectIndex;
bool _drawBin = false;
};
diff --git a/src/engine/objects/Trophy.cpp b/src/engine/objects/Trophy.cpp
index 4de758aab..54bd70d3e 100644
--- a/src/engine/objects/Trophy.cpp
+++ b/src/engine/objects/Trophy.cpp
@@ -1,6 +1,8 @@
#include "Trophy.h"
#include "assets/common_data.h"
#include "assets/data_segment2.h"
+#include "port/Game.h"
+
extern "C" {
#include "main.h"
#include "defines.h"
@@ -8,6 +10,7 @@ extern "C" {
#include "code_80057C60.h"
#include "assets/ceremony_data.h"
#include "podium_ceremony_actors.h"
+#include "engine/particles/StarEmitter.h"
#include "math_util.h"
#include "math_util_2.h"
#include "data/some_data.h"
@@ -18,12 +21,18 @@ extern "C" {
}
OTrophy::OTrophy(const FVector& pos, TrophyType trophy, Behaviour bhv) {
- s32 objectIndex = indexObjectList1[3];
_trophy = trophy;
_spawnPos = pos;
_spawnPos.y += 16.0f; // Adjust the height so the trophy sits on the surface when positioned to 0,0,0
_bhv = bhv;
+ find_unused_obj_index(&_objectIndex);
+
+ // If you're trying to place multiple trophies in the podium ceremony
+ // This will make the camera look at the last trophy spawned.
+ // Thus this will need to be changed if that's not desired.
+ gTrophyIndex = _objectIndex;
+
if (bhv == OTrophy::Behaviour::PODIUM_CEREMONY) {
_toggleVisibility = &D_801658CE;
} else {
@@ -34,55 +43,57 @@ OTrophy::OTrophy(const FVector& pos, TrophyType trophy, Behaviour bhv) {
// This allows spawning for mods
if (*_toggleVisibility == true) {
- init_object(objectIndex, 0);
+ init_object(_objectIndex, 0);
}
switch (trophy) {
case TrophyType::GOLD:
- gObjectList[objectIndex].model = (Gfx*)gold_trophy_dl10;
+ gObjectList[_objectIndex].model = (Gfx*)gold_trophy_dl10;
break;
case TrophyType::SILVER:
- gObjectList[objectIndex].model = (Gfx*)gold_trophy_dl12;
+ gObjectList[_objectIndex].model = (Gfx*)gold_trophy_dl12;
break;
case TrophyType::BRONZE:
- gObjectList[objectIndex].model = (Gfx*)gold_trophy_dl14;
+ gObjectList[_objectIndex].model = (Gfx*)gold_trophy_dl14;
break;
case TrophyType::GOLD_150:
- gObjectList[objectIndex].model = (Gfx*)gold_trophy_dl11;
+ gObjectList[_objectIndex].model = (Gfx*)gold_trophy_dl11;
break;
case TrophyType::SILVER_150:
- gObjectList[objectIndex].model = (Gfx*)gold_trophy_dl13;
+ gObjectList[_objectIndex].model = (Gfx*)gold_trophy_dl13;
break;
case TrophyType::BRONZE_150:
- gObjectList[objectIndex].model = (Gfx*)gold_trophy_dl15;
+ gObjectList[_objectIndex].model = (Gfx*)gold_trophy_dl15;
break;
}
// Set defaults for modded behaviours
if (_bhv != OTrophy::Behaviour::PODIUM_CEREMONY) {
- gObjectList[objectIndex].sizeScaling = 0.025f;
- gObjectList[objectIndex].unk_084[1] = 0x0200;
- object_next_state(objectIndex);
- func_80086E70(objectIndex);
+ gObjectList[_objectIndex].sizeScaling = 0.025f;
+ gObjectList[_objectIndex].unk_084[1] = 0x0200;
+ object_next_state(_objectIndex);
+ func_80086E70(_objectIndex);
}
switch(_bhv) {
case OTrophy::Behaviour::GO_FISH:
- gObjectList[objectIndex].sizeScaling = 0.010f;
+ gObjectList[_objectIndex].sizeScaling = 0.010f;
break;
}
- Object *object = &gObjectList[objectIndex];
+ Object *object = &gObjectList[_objectIndex];
object->origin_pos[0] = _spawnPos.x;
object->origin_pos[1] = _spawnPos.y;
object->origin_pos[2] = _spawnPos.z;
object->pos[0] = _spawnPos.x;
object->pos[1] = _spawnPos.y;
object->pos[2] = _spawnPos.z;
+
+ _emitter = reinterpret_cast<StarEmitter*>(gWorldInstance.AddEmitter(new StarEmitter()));
}
void OTrophy::Tick() { // func_80086D80
- s32 objectIndex = indexObjectList1[3];
+ s32 objectIndex = _objectIndex;
s32 var_s0;
// Fallback for podium ceremony where the trophy is not spawned until it is needed
@@ -197,7 +208,7 @@ void OTrophy::Tick() { // func_80086D80
}
void OTrophy::Draw(s32 cameraId) {
- s32 listIndex = indexObjectList1[3];
+ s32 listIndex = _objectIndex;
Mat4 someMatrix1;
Mat4 someMatrix2;
Object* object;
@@ -333,62 +344,8 @@ void OTrophy::func_80086C6C(s32 objectIndex) {
} else {
sp24[1] = gObjectList[objectIndex].pos[1] - 2.0;
}
- func_800773D8(sp24, (s32) D_801658F4);
-}
-void OTrophy::func_800773D8(f32* arg0, s32 arg1) {
- s32 objectIndex = add_unused_obj_index(gObjectParticle3, &gNextFreeObjectParticle3, gObjectParticle3_SIZE);
- if (objectIndex != NULL_OBJECT_ID) {
- func_80077138(objectIndex, arg0, arg1);
+ if (_emitter != nullptr) {
+ _emitter->Emit(sp24, D_801658F4);
}
}
-
-void OTrophy::func_80077138(s32 objectIndex, Vec3f arg1, s32 arg2) {
- s8 temp_v0_3;
- Vec3s sp30;
-
- init_object(objectIndex, arg2);
- gObjectList[objectIndex].unk_0D5 = 0x0C;
- gObjectList[objectIndex].sizeScaling = 0.05f;
- set_obj_origin_pos(objectIndex, arg1[0], arg1[1], arg1[2]);
- set_obj_orientation(objectIndex, 0U, 0U, 0U);
- set_obj_origin_offset(objectIndex, 0.0f, 0.0f, 0.0f);
- switch (arg2) {
- case 0:
- gObjectList[objectIndex].velocity[1] = -1.0f;
- gObjectList[objectIndex].unk_034 = (f32) ((random_int(0x004BU) * 0.01) + 0.25);
- gObjectList[objectIndex].direction_angle[1] = random_int(0x0040U) << 0xA;
- func_8008751C(objectIndex);
- gObjectList[objectIndex].unk_084[5] = 0x001E;
- break;
- case 1:
- gObjectList[objectIndex].velocity[1] = 1.5f;
- gObjectList[objectIndex].unk_034 = (f32) ((random_int(0x0064U) * 0.01) + 0.5);
- gObjectList[objectIndex].direction_angle[1] = random_int(0x0040U) << 0xA;
- func_8008751C(objectIndex);
- gObjectList[objectIndex].unk_084[5] = 0x0032;
- break;
- }
- temp_v0_3 = random_int(0x000CU);
- if (temp_v0_3 < 9) {
- func_8005C674(temp_v0_3, &sp30[2], &sp30[1], sp30);
- gObjectList[objectIndex].unk_048 = 0;
- gObjectList[objectIndex].unk_084[0] = sp30[2];
- gObjectList[objectIndex].unk_084[1] = sp30[1];
- gObjectList[objectIndex].unk_084[2] = sp30[0];
- } else {
- temp_v0_3 = random_int(3U);
- func_8005C6B4(temp_v0_3, &sp30[2], &sp30[1], sp30);
- gObjectList[objectIndex].unk_084[0] = sp30[2];
- gObjectList[objectIndex].unk_084[1] = sp30[1];
- gObjectList[objectIndex].unk_084[2] = sp30[0];
- gObjectList[objectIndex].unk_084[4] = temp_v0_3;
- gObjectList[objectIndex].unk_048 = 1;
- }
- gObjectList[objectIndex].primAlpha = 0x00FF;
- gObjectList[objectIndex].unk_084[3] = random_int(0x0800U) + 0x400;
- if ((gObjectList[objectIndex].direction_angle[1] < 0x3000) ||
- (gObjectList[objectIndex].direction_angle[1] >= 0xB001)) {
- gObjectList[objectIndex].unk_084[3] = -gObjectList[objectIndex].unk_084[3];
- }
-} \ No newline at end of file
diff --git a/src/engine/objects/Trophy.h b/src/engine/objects/Trophy.h
index a227ef5b9..c2bb937ab 100644
--- a/src/engine/objects/Trophy.h
+++ b/src/engine/objects/Trophy.h
@@ -4,6 +4,7 @@
#include <vector>
#include "Object.h"
#include "World.h"
+#include "engine/particles/StarEmitter.h"
extern "C" {
#include "macros.h"
@@ -43,12 +44,11 @@ public:
void func_80086940(s32 objectIndex);
void func_80086C14(s32 objectIndex);
void func_80086C6C(s32 objectIndex);
- void func_800773D8(f32* arg0, s32 arg1);
- void func_80077138(s32 objectIndex, Vec3f arg1, s32 arg2);
private:
+ StarEmitter* _emitter;
- s32 _idx;
+ s32 _objectIndex;
TrophyType _trophy;
FVector _spawnPos;
Behaviour _bhv;
diff --git a/src/engine/particles/StarEmitter.cpp b/src/engine/particles/StarEmitter.cpp
index e700b4c8c..242e1a75a 100644
--- a/src/engine/particles/StarEmitter.cpp
+++ b/src/engine/particles/StarEmitter.cpp
@@ -12,30 +12,30 @@ extern "C" {
#include "math_util_2.h"
}
-StarEmitter::StarEmitter(FVector pos) {
- s32 objectIndex = add_unused_obj_index(gObjectParticle3, &gNextFreeObjectParticle3, gObjectParticle3_SIZE);
+StarEmitter::StarEmitter() {
+ for (size_t i = 0; i < gObjectParticle3_SIZE; i++) {
+ ObjectIndex[i] = NULL_OBJECT_ID;
+ }
+}
+
+void StarEmitter::Emit(Vec3f arg1, s32 arg2) { // func_80077138
+ s32 objectIndex;
s8 temp_v0_3;
Vec3s sp30;
- for (size_t i = 0; i < D_80165738; i++) {
- find_unused_obj_index(&gObjectParticle3[i]);
- init_object(gObjectParticle3[i], 0);
- }
+ objectIndex = add_unused_obj_index(&ObjectIndex[0], &_next, gObjectParticle3_SIZE);
if (objectIndex == NULL_OBJECT_ID) {
return;
- //func_80077138(objectIndex, arg0, arg1);
}
- D_801658F4 = 1;
-
- init_object(objectIndex, D_801658F4);
+ init_object(objectIndex, arg2);
gObjectList[objectIndex].unk_0D5 = 0x0C;
gObjectList[objectIndex].sizeScaling = 0.05f;
- set_obj_origin_pos(objectIndex, pos.x, pos.y, pos.z);
+ set_obj_origin_pos(objectIndex, arg1[0], arg1[1], arg1[2]);
set_obj_orientation(objectIndex, 0U, 0U, 0U);
set_obj_origin_offset(objectIndex, 0.0f, 0.0f, 0.0f);
- switch (D_801658F4) {
+ switch (arg2) {
case 0:
gObjectList[objectIndex].velocity[1] = -1.0f;
gObjectList[objectIndex].unk_034 = (f32) ((random_int(0x004BU) * 0.01) + 0.25);
@@ -81,15 +81,14 @@ void StarEmitter::Tick() { // func_80077640
Object* object;
for (someIndex = 0; someIndex < gObjectParticle3_SIZE; someIndex++) {
- objectIndex = gObjectParticle3[someIndex];
+ objectIndex = ObjectIndex[someIndex];
if (objectIndex != DELETED_OBJECT_ID) {
object = &gObjectList[objectIndex];
- printf("Tick Star %d\n", object->state);
if (object->state != 0) {
StarEmitter::func_80077450(objectIndex);
StarEmitter::func_80077584(objectIndex);
if (object->state == 0) {
- //delete_object_wrapper(&gObjectParticle3[someIndex]);
+ delete_object_wrapper(&ObjectIndex[someIndex]);
}
}
}
@@ -107,16 +106,14 @@ void StarEmitter::Draw(s32 cameraId) { // func_80054BE8
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];
+ temp_a0 = ObjectIndex[var_s0];
if ((temp_a0 != -1) && (gObjectList[temp_a0].state >= 2)) {
- printf("Draw Star\n");
StarEmitter::func_80054AFC(temp_a0, camera->pos);
}
}
}
void StarEmitter::func_80054AFC(s32 objectIndex, Vec3f arg1) {
- printf("Drawing Star!\n");
D_80183E80[0] = func_800418E8(gObjectList[objectIndex].pos[2], gObjectList[objectIndex].pos[1], arg1);
D_80183E80[1] = func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], arg1);
D_80183E80[2] = (u16) gObjectList[objectIndex].orientation[2];
@@ -168,13 +165,11 @@ void StarEmitter::func_80077450(s32 objectIndex) {
(func_80073B00(objectIndex, &gObjectList[objectIndex].primAlpha, 0x000000FF, 0, 0x00000010, 0, 0) !=
0)) {
func_80086F60(objectIndex);
- //func_80072428(objectIndex);
+ func_80072428(objectIndex);
}
break;
}
if (gObjectList[objectIndex].unk_048 != 0) {
- printf("SOME THING\n");
-
gObjectList[objectIndex].unk_084[4] = (s16) ((s32) (gObjectList[objectIndex].unk_084[4] + 1) % 3);
func_8005C6B4(gObjectList[objectIndex].unk_084[4], &sp3C, &sp3A, &sp38);
gObjectList[objectIndex].unk_084[0] = sp3C;
diff --git a/src/engine/particles/StarEmitter.h b/src/engine/particles/StarEmitter.h
index 285c959f4..e1c6e0416 100644
--- a/src/engine/particles/StarEmitter.h
+++ b/src/engine/particles/StarEmitter.h
@@ -28,16 +28,17 @@ public:
f32 Diameter = 0.0f; // Waddle in a circle around the spawn point at this diameter.
uint16_t MirrorModeAngleOffset;
- explicit StarEmitter(FVector pos);
+ explicit StarEmitter();
virtual void Tick() override;
virtual void Draw(s32 cameraId) override;
+ void Emit(Vec3f arg1, s32 arg2);
void func_80077428(s32 objectIndex);
void func_80077584(s32 objectIndex);
void func_80077450(s32 objectIndex);
void func_80054AFC(s32 objectIndex, Vec3f arg1);
private:
-
- s32 _idx;
+ s32 ObjectIndex[128];
+ s32 _next = 0;
};
diff --git a/src/port/Game.cpp b/src/port/Game.cpp
index 5ac56da94..f016aec39 100644
--- a/src/port/Game.cpp
+++ b/src/port/Game.cpp
@@ -93,6 +93,8 @@ Cup* gBattleCup;
ModelLoader gModelLoader;
+s32 gTrophyIndex = NULL;
+
void CustomEngineInit() {
gMarioRaceway = new MarioRaceway();
@@ -348,8 +350,16 @@ void CM_DrawActors(Camera* camera, struct Actor* actor) {
}
void CM_BeginPlay() {
- if (gWorldInstance.CurrentCourse) {
- gWorldInstance.CurrentCourse->BeginPlay();
+ Course* course = gWorldInstance.CurrentCourse;
+
+ if (course) {
+
+ // Do not spawn finishline in credits or battle mode. And if bSpawnFinishline.
+ if ((gGamestate != CREDITS_SEQUENCE) && (gGamestate != BATTLE) && (course->bSpawnFinishline)) {
+ gWorldInstance.AddActor(new AFinishline(course->FinishlineSpawnPoint));
+ }
+
+ course->BeginPlay();
}
}
@@ -615,6 +625,7 @@ void CM_CleanWorld(void) {
gWorldInstance.Objects.clear();
gWorldInstance.Emitters.clear();
gWorldInstance.Lakitus.clear();
+ gWorldInstance.Reset();
}
struct Actor* CM_AddBaseActor(void) {
diff --git a/src/port/Game.h b/src/port/Game.h
index 5ef93fa1d..96bfcbee8 100644
--- a/src/port/Game.h
+++ b/src/port/Game.h
@@ -11,6 +11,8 @@ extern "C" {
#include "camera.h"
#include "actor_types.h"
+extern s32 gTrophyIndex;
+
Properties* CM_GetProps();
Properties* CM_GetPropsCourseId(s32 courseId);
diff --git a/src/racing/actors.c b/src/racing/actors.c
index 4b586cf75..9fc8059ef 100644
--- a/src/racing/actors.c
+++ b/src/racing/actors.c
@@ -830,6 +830,10 @@ void spawn_piranha_plants(struct ActorSpawnData* spawnData) {
Vec3s startingRot;
s32 temp;
+ if (gGamestate == CREDITS_SEQUENCE) {
+ return;
+ }
+
vec3f_set(startingVelocity, 0, 0, 0);
vec3s_set(startingRot, 0, 0, 0);
@@ -894,6 +898,10 @@ void spawn_foliage(struct ActorSpawnData* actor) {
rotation[1] = 0;
rotation[2] = 0;
+ if (gGamestate == CREDITS_SEQUENCE) {
+ return;
+ }
+
while (var_s3->pos[0] != END_OF_SPAWN_DATA) {
position[0] = var_s3->pos[0] * gCourseDirection;
position[2] = var_s3->pos[2];
@@ -958,7 +966,7 @@ void spawn_all_item_boxes(struct ActorSpawnData* spawnData) {
struct ActorSpawnData* temp_s0 = spawnData;
// struct ItemBox *itemBox;
- if ((gModeSelection == TIME_TRIALS) || (gPlaceItemBoxes == 0)) {
+ if ((gModeSelection == TIME_TRIALS) || (gPlaceItemBoxes == 0) || (gGamestate == CREDITS_SEQUENCE)) {
return;
}
diff --git a/src/render_objects.c b/src/render_objects.c
index 409bab57c..d3fcaaa64 100644
--- a/src/render_objects.c
+++ b/src/render_objects.c
@@ -3956,50 +3956,6 @@ void func_800557B4(s32 objectIndex, u32 arg1, u32 arg2) {
}
}
-void render_object_train_penguins(s32 cameraId) {
- s32 i;
- s32 objectIndex;
- s32 temp_s1;
- s32 var_a3;
- u16 var_s1;
- u32 var_s3;
-
- if (gPlayerCountSelection1 == 1) {
- var_s3 = 0x0003D090;
- } else if (gPlayerCountSelection1 == 2) {
- var_s3 = 0x00027100;
- } else {
- var_s3 = 0x00015F90;
- }
- for (i = 0; i < NUM_PENGUINS; i++) {
- objectIndex = indexObjectList1[i];
- if (gObjectList[objectIndex].state >= 2) {
- if (gPlayerCountSelection1 == 1) {
- var_s1 = 0x4000;
- if (i == 0) {
- var_a3 = 0x000005DC;
- } else if (func_80072320(objectIndex, 8) != 0) {
- var_a3 = 0x00000320;
- } else {
- var_a3 = 0x000003E8;
- }
- } else {
- if (func_80072320(objectIndex, 8) != 0) {
- var_a3 = 0x000001F4;
- var_s1 = 0x4000;
- } else {
- var_a3 = 0x00000258;
- var_s1 = 0x5555;
- }
- }
- temp_s1 = func_8008A364(objectIndex, cameraId, var_s1, var_a3);
- if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) {
- func_800557B4(objectIndex, (u32) temp_s1, var_s3);
- }
- }
- }
-}
-
void func_80055EF4(s32 objectIndex, UNUSED s32 arg1) {
Object* object;
diff --git a/src/render_objects.h b/src/render_objects.h
index ee13cb47c..d4c45eed7 100644
--- a/src/render_objects.h
+++ b/src/render_objects.h
@@ -363,7 +363,6 @@ void render_object_seagulls(s32);
void render_object_crabs(s32);
void func_800557AC(void);
void func_800557B4(s32, u32, u32);
-void render_object_train_penguins(s32);
void func_80055AB8(s32, s32);
void render_object_chain_chomps(s32);
void func_80055EF4(s32, s32);
diff --git a/src/update_objects.c b/src/update_objects.c
index 3f25e136f..55ae23246 100644
--- a/src/update_objects.c
+++ b/src/update_objects.c
@@ -3910,46 +3910,6 @@ void func_8007E4C4(void) {
}
}
-void func_8008153C(s32 objectIndex) {
- UNUSED s32 stackPadding[3];
- s32 sp70;
- s32 var_s1;
- s32 var_s7;
- s32 loopObjectIndex;
-
- if (gPlayerCountSelection1 == 1) {
- sp70 = 8;
- } else {
- sp70 = 4;
- }
-
- for (var_s7 = 0; var_s7 < sp70; var_s7++) {
- for (var_s1 = 0; var_s1 < gObjectParticle2_SIZE; var_s1++) {
- loopObjectIndex = gObjectParticle2[var_s1];
-
- if (gObjectList[loopObjectIndex].state != 0) {
- continue;
- }
-
- u8* mole = (u8*) LOAD_ASSET(d_course_moo_moo_farm_mole_dirt);
-
- init_object(loopObjectIndex, 0);
- gObjectList[loopObjectIndex].activeTLUT = d_course_moo_moo_farm_mole_dirt;
- gObjectList[loopObjectIndex].tlutList = mole;
- gObjectList[loopObjectIndex].sizeScaling = 0.15f;
- gObjectList[loopObjectIndex].velocity[1] = random_int(0x000AU);
- gObjectList[loopObjectIndex].velocity[1] = (gObjectList[loopObjectIndex].velocity[1] * 0.1) + 4.8;
- gObjectList[loopObjectIndex].unk_034 = random_int(5U);
- gObjectList[loopObjectIndex].unk_034 = (gObjectList[loopObjectIndex].unk_034 * 0.01) + 0.8;
- gObjectList[loopObjectIndex].orientation[1] = (0x10000 / sp70) * var_s1;
- gObjectList[loopObjectIndex].origin_pos[0] = gObjectList[objectIndex].origin_pos[0];
- gObjectList[loopObjectIndex].origin_pos[1] = gObjectList[objectIndex].origin_pos[1] - 13.0;
- gObjectList[loopObjectIndex].origin_pos[2] = gObjectList[objectIndex].origin_pos[2];
- break;
- }
- }
-}
-
void func_80083F18(s32 objectIndex) {
switch (gObjectList[objectIndex].state) {
case 0:
diff --git a/src/update_objects.h b/src/update_objects.h
index 6f7b840c2..1e25698c1 100644
--- a/src/update_objects.h
+++ b/src/update_objects.h
@@ -282,14 +282,12 @@ void func_80081080(s32);
void func_800810F4(s32);
void func_80081208(void);
void func_80081210(void);
-void func_8008153C(s32);
void func_80081790(s32);
void func_80081848(s32);
void func_80081924(s32);
void func_80081A88(s32);
void func_80081AFC(s32, s32);
void func_80081D34(s32);
-void func_80081FF4(s32, s32);
void func_800821AC(s32, s32);
void update_moles(void);
void func_8008241C(s32, s32);
@@ -353,7 +351,6 @@ void func_80086700(s32);
void func_80086940(s32);
void func_80086C14(s32);
void func_80086C6C(s32);
-void func_80086D80(void);
extern f32 D_800E43B0[];
extern Vtx D_800E43F0[];