summaryrefslogtreecommitdiff
path: root/src/engine
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine')
-rw-r--r--src/engine/GarbageCollector.cpp3
-rw-r--r--src/engine/RaceManager.cpp77
-rw-r--r--src/engine/RaceManager.h31
-rw-r--r--src/engine/World.cpp49
-rw-r--r--src/engine/World.h6
-rw-r--r--src/engine/actors/Text.cpp19
-rw-r--r--src/engine/actors/Text.h2
7 files changed, 171 insertions, 16 deletions
diff --git a/src/engine/GarbageCollector.cpp b/src/engine/GarbageCollector.cpp
index e7f2d9975..d356602d3 100644
--- a/src/engine/GarbageCollector.cpp
+++ b/src/engine/GarbageCollector.cpp
@@ -1,6 +1,9 @@
#include "GarbageCollector.h"
#include "World.h"
+/**
+ * Removes objects if they are marked for deletion
+ */
void RunGarbageCollector() {
CleanActors();
CleanObjects();
diff --git a/src/engine/RaceManager.cpp b/src/engine/RaceManager.cpp
new file mode 100644
index 000000000..ae1ef828f
--- /dev/null
+++ b/src/engine/RaceManager.cpp
@@ -0,0 +1,77 @@
+#include "RaceManager.h"
+
+#include "AllActors.h"
+#include "World.h"
+#include "port/Game.h"
+#include "engine/editor/Editor.h"
+#include "engine/editor/SceneManager.h"
+
+extern "C" {
+#include "render_courses.h"
+}
+
+RaceManager::RaceManager(World& world) : WorldContext(world) {
+}
+
+void RaceManager::Load() {
+ if (WorldContext.CurrentCourse) {
+ WorldContext.CurrentCourse->Load();
+ }
+}
+
+void RaceManager::PreInit() {
+ // Ruleset options
+ if (CVarGetInteger("gDisableItemboxes", false) == true) {
+ gPlaceItemBoxes = false;
+ } else {
+ gPlaceItemBoxes = true;
+ }
+}
+
+void RaceManager::BeginPlay() {
+ auto course = WorldContext.CurrentCourse;
+
+ if (course) {
+ // Do not spawn finishline in credits or battle mode. And if bSpawnFinishline.
+ if ((gGamestate != CREDITS_SEQUENCE) && (gModeSelection != BATTLE)) {
+ if (course->bSpawnFinishline) {
+ if (course->FinishlineSpawnPoint.has_value()) {
+ AFinishline::Spawn(course->FinishlineSpawnPoint.value(), IRotator(0, 0, 0));
+ } else {
+ AFinishline::Spawn();
+ }
+
+ }
+ }
+ gEditor.AddLight("Sun", nullptr, D_800DC610[1].l->l.dir);
+
+ course->BeginPlay();
+ }
+}
+
+void RaceManager::PostInit() {
+ // Ruleset options
+ if (CVarGetInteger("gAllThwompsAreMarty", false) == true) {
+ for (auto object : gWorldInstance.Objects) {
+ if (OThwomp* thwomp = dynamic_cast<OThwomp*>(object)) {
+ gObjectList[thwomp->_objectIndex].unk_0D5 = OThwomp::States::JAILED; // Sets all the thwomp behaviour flags to marty
+ thwomp->Behaviour = OThwomp::States::JAILED;
+ }
+ }
+ }
+
+ if (CVarGetInteger("gAllBombKartsChase", false) == true) {
+ for (auto object : gWorldInstance.Objects) {
+ if (OBombKart* kart = dynamic_cast<OBombKart*>(object)) {
+ kart->Behaviour = OBombKart::States::CHASE;
+ }
+ }
+ }
+
+ if (CVarGetInteger("gGoFish", false) == true) {
+ OTrophy::Spawn(FVector(0,0,0), OTrophy::TrophyType::GOLD, OTrophy::Behaviour::GO_FISH);
+ }
+}
+
+void RaceManager::Clean() {
+}
diff --git a/src/engine/RaceManager.h b/src/engine/RaceManager.h
new file mode 100644
index 000000000..fb38bb33c
--- /dev/null
+++ b/src/engine/RaceManager.h
@@ -0,0 +1,31 @@
+#pragma once
+
+class World;
+
+/**
+ * This may eventually become GameMode class
+ *
+ * The RaceManager orchestrates the event lifecycle
+ * It defines when a race begins, actors spawn, and the race ends.
+ *
+ * It does not define the game mode itself.
+ *
+ * You must call the base function if you want the
+ * default functionality to run
+ * Example:
+ * MyRaceManager::BeginPlay() {
+ * RaceManager::BeginPlay() // <-- Calls default functionality
+ * // My code here
+ * }
+ */
+class RaceManager {
+public:
+ RaceManager(World& world);
+ virtual void Load(); // virtual required here in the base class to allow inherited classes to override
+ virtual void PreInit();
+ virtual void BeginPlay();
+ virtual void PostInit();
+ virtual void Clean();
+protected:
+ World& WorldContext;
+};
diff --git a/src/engine/World.cpp b/src/engine/World.cpp
index 0430edf6d..cca7a2199 100644
--- a/src/engine/World.cpp
+++ b/src/engine/World.cpp
@@ -21,14 +21,17 @@ extern "C" {
#include "mario_raceway_data.h"
}
-World::World() {}
-World::~World() {
- CM_CleanWorld();
-}
-
std::shared_ptr<Course> CurrentCourse;
Cup* CurrentCup;
+World::World() {
+ RaceManagerInstance = std::make_unique<RaceManager>(*this);
+}
+
+World::~World() {
+ ClearWorld();
+}
+
std::shared_ptr<Course> World::AddCourse(std::shared_ptr<Course> course) {
gWorldInstance.Courses.push_back(course);
return course;
@@ -252,13 +255,39 @@ Object* World::GetObjectByIndex(size_t index) {
return nullptr; // Or handle the error as needed
}
+// Deletes all objects from the world
void World::ClearWorld(void) {
- CM_CleanWorld();
+ printf("[Game.cpp] Clean World\n");
+ World* world = &gWorldInstance;
+ for (auto& actor : world->Actors) {
+ delete actor;
+ }
- // for (size_t i = 0; i < ARRAY_COUNT(gCollisionMesh); i++) {
+ gWorldInstance.Reset(); // Reset OObjects
+ for (auto& object : world->Objects) {
+ delete object;
+ }
- // }
+ for (auto& emitter : world->Emitters) {
+ delete emitter;
+ }
+
+ for (auto& actor : world->StaticMeshActors) {
+ delete actor;
+ }
+
+ for (size_t i = 0; i < ARRAY_COUNT(gWorldInstance.playerBombKart); i++) {
+ gWorldInstance.playerBombKart[i].state = PlayerBombKart::PlayerBombKartState::DISABLED;
+ gWorldInstance.playerBombKart[i]._primAlpha = 0;
+ }
+
+ gEditor.ClearObjects();
+ gWorldInstance.Actors.clear();
+ gWorldInstance.StaticMeshActors.clear();
+ gWorldInstance.Objects.clear();
+ gWorldInstance.Emitters.clear();
+ gWorldInstance.Lakitus.clear();
+
+ gWorldInstance.GetRaceManager().Clean();
- // gCollisionMesh
- // Paths
}
diff --git a/src/engine/World.h b/src/engine/World.h
index 52a307be5..4e1e6e06e 100644
--- a/src/engine/World.h
+++ b/src/engine/World.h
@@ -9,6 +9,7 @@
#include "TrainCrossing.h"
#include <memory>
#include <unordered_map>
+#include "RaceManager.h"
#include "Actor.h"
#include "StaticMeshActor.h"
#include "particles/ParticleEmitter.h"
@@ -50,6 +51,9 @@ public:
explicit World();
~World();
+ RaceManager& GetRaceManager() { return *RaceManagerInstance; }
+ void SetRaceManager(std::unique_ptr<RaceManager> manager) { RaceManagerInstance = std::move(manager); }
+
std::shared_ptr<Course> AddCourse(std::shared_ptr<Course> course);
AActor* AddActor(AActor* actor);
@@ -130,7 +134,7 @@ public:
std::vector<std::shared_ptr<Course>> Courses;
size_t CourseIndex = 0; // For browsing courses.
private:
-
+ std::unique_ptr<RaceManager> RaceManagerInstance;
};
extern World gWorldInstance;
diff --git a/src/engine/actors/Text.cpp b/src/engine/actors/Text.cpp
index 2d2fab0b0..06a74c54d 100644
--- a/src/engine/actors/Text.cpp
+++ b/src/engine/actors/Text.cpp
@@ -77,7 +77,11 @@ AText::AText(const SpawnParams& params) : AActor(params) {
* But these need to be checked thoroughly before white-listing.
*/
std::string AText::ValidateString(const std::string_view& s) {
- if (s.empty()) { return "Blank Text"; }
+ if (CVarGetInteger("gIsEditorEnabled", false) == true) {
+ if (s.empty()) { return "Blank Text"; }
+ } else {
+ if (s.empty()) { return ""; }
+ }
Text.clear();
@@ -100,6 +104,11 @@ std::string AText::ValidateString(const std::string_view& s) {
return Text;
}
+void AText::SetText(std::string text) {
+ AText::ValidateString(text);
+ Refresh();
+}
+
/*
* Most changes during runtime require a refresh because the text is generated statically
* with the intention of this code being somewhat performant
@@ -353,7 +362,9 @@ void AText::DrawText3D(Camera* camera) { // Based on func_80095BD0
FrameInterpolation_RecordOpenChild("actor_text", TAG_LETTER(this));
gSPDisplayList(gDisplayListHead++, (Gfx*)D_020077A8);
- switch (1) {
+
+ for (CharacterList& tex : TextureList) {
+ switch (tex.mode) {
case 1:
gSPDisplayList(gDisplayListHead++, (Gfx*)D_020077F8);
break;
@@ -361,8 +372,6 @@ void AText::DrawText3D(Camera* camera) { // Based on func_80095BD0
gSPDisplayList(gDisplayListHead++, (Gfx*)D_02007818);
break;
}
-
- for (CharacterList& tex : TextureList) {
//printf("tex texture %p width %d height %d mode %d col %f\n", tex.Texture, tex.width, tex.height, tex.mode, tex.column);
gDPLoadTextureTile_4b(gDisplayListHead++, (Gfx*)tex.Texture, G_IM_FMT_I, tex.width, 0, 0, 0, tex.width, tex.height + 2, 0,
G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD,
@@ -585,4 +594,4 @@ void AText::DrawColourEditor(bool* updated) {
}
}
}
-} \ No newline at end of file
+}
diff --git a/src/engine/actors/Text.h b/src/engine/actors/Text.h
index 7a9ac7407..e0b436709 100644
--- a/src/engine/actors/Text.h
+++ b/src/engine/actors/Text.h
@@ -118,6 +118,8 @@ public:
void DrawColourEditor(bool* updated);
void FollowPlayer();
+ void SetText(std::string text);
+
std::string ValidateString(const std::string_view& text);
void Refresh();
void Print3D(char* text, s32 tracking, s32 mode);