SpaghettiKart
Loading...
Searching...
No Matches
Track.h
Go to the documentation of this file.
1#ifndef ENGINE_TRACK_H
2#define ENGINE_TRACK_H
3
4#include <libultraship/libultraship.h>
5#include "CoreMath.h"
6
7#ifdef __cplusplus
9#include <optional>
10#include <nlohmann/json.hpp>
13extern "C" {
14#endif
15
16#include "defines.h"
17#include "camera.h"
18#include "data/some_data.h"
19#include "bomb_kart.h"
20#include "path_spawn_metadata.h"
21#include "waypoints.h"
22#include "sounds.h"
23#include "common_structs.h"
24#include "code_800029B0.h"
25
26#ifdef __cplusplus
27}
28#endif
29
40
41// Extends infinitely in the Y direction
42// If a player is overtop of a water volume then it should use its height
43// Recommend using the new water surface type. This is here to support the stock tracks.
44// Albeit, there's no reason you cannot use this so long as you input a square.
45// How to use: WaterVolumes.push_back({0, -100, 100, -100, 100});
47 float Height; // Y coordinate of the Water level
48 float MinX;
49 float MaxX;
50 float MinZ;
51 float MaxZ;
52};
53
54typedef struct MinimapProps {
55 const char* Texture;
56 int16_t Width;
57 int16_t Height;
58 IVector2D Pos[2]; // Minimap position for players 1 and 2. 3/4 player mode is hard-coded to the center.
59 int32_t PlayerX; // The offset to place the player markers
60 int32_t PlayerY;
61 float PlayerScaleFactor; // Scale factor of the player markers
62 float FinishlineX; // The offset to place the finishline texture on the minimap
64 RGB8 Colour; // Colour of the visible pixels (the track path)
66
67void ResizeMinimap(MinimapProps* minimap);
68void ReverseGfx(Gfx* gfx);
69
70void InvertTriangleWinding(Gfx* gfx);
71void InvertTriangleWindingByName(const char* name);
74
81typedef struct {
82 uint64_t crc;
83 u8 surfaceType; // Determines what kind of surface the player drives on (ex. dirt, asphalt, etc.)
85 u16 clip; // enum in CustomTrack.h
86 u16 layer; // enum in CustomTrack.h
89
90typedef struct Properties {
91 char Name[128];
92 char DebugName[128];
93 char TrackLength[128];
96 const char* AIBehaviour;
99 float NearPersp;
100 float FarPersp;
101 int16_t* AIDistance;
108 TrackPathPoint* PathTable[4]; // Only used for podium ceremony
109 TrackPathPoint* PathTable2[5]; // The fifth entry is for vehicles
110 uint8_t* CloudTexture;
115 float WaterLevel; // Used for effects, and Lakitu pick up height. Not necessarily the visual water model height.
116
117#ifdef __cplusplus
118 nlohmann::json to_json() const {
119 nlohmann::json j;
120 j["Name"] = Name ? Name : "";
121 j["DebugName"] = DebugName ? DebugName : "";
122 j["TrackLength"] = TrackLength ? TrackLength : "";
123 //j["AIBehaviour"] = AIBehaviour ? AIBehaviour : "";
124 j["LakituTowType"] = LakituTowType;
125 j["AIMaximumSeparation"] = AIMaximumSeparation;
126 j["AIMinimumSeparation"] = AIMinimumSeparation;
127 j["NearPersp"] = NearPersp;
128 j["FarPersp"] = FarPersp;
129
130 // AIDistance as a JSON array
131 j["AIDistance"] = std::vector<int16_t>(AIDistance, AIDistance + 32); // gAIDistances array size of 32
132
133 j["AISteeringSensitivity"] = AISteeringSensitivity;
134
135 // PathSizes - Assuming TrackPathSizes can be serialized similarly
136 // j["PathSizes"] = PathSizes; // Implement your serialization logic here
137
138 j["CurveTargetSpeed"] = { CurveTargetSpeed[0], CurveTargetSpeed[1], CurveTargetSpeed[2], CurveTargetSpeed[3] };
139 j["NormalTargetSpeed"] = { NormalTargetSpeed[0], NormalTargetSpeed[1], NormalTargetSpeed[2], NormalTargetSpeed[3] };
140 j["D_0D0096B8"] = { D_0D0096B8[0], D_0D0096B8[1], D_0D0096B8[2], D_0D0096B8[3] };
141 j["OffTrackTargetSpeed"] = { OffTrackTargetSpeed[0], OffTrackTargetSpeed[1], OffTrackTargetSpeed[2], OffTrackTargetSpeed[3] };
142
143 // Serialize arrays PathTable and PathTable2 (convert pointers into a JSON array if possible)
144 //j["PathTable"] = {{}};
145 //j["PathTable2"] = {{}};
146 // Populate PathTable and PathTable2
147
148 //j["Clouds"] = Clouds ? nlohmann::json{{"x", Clouds->x, "y", Clouds->y, "z", Clouds->z}} : nullptr;
149 //j["CloudList"] = CloudList ? nlohmann::json{{"x", CloudList->x, "y", CloudList->y, "z", CloudList->z}} : nullptr;
150
151 j["MinimapPosition"] = {Minimap.Pos[0].X, Minimap.Pos[0].Y};
152 j["MinimapPosition2P"] = {Minimap.Pos[1].X, Minimap.Pos[1].Y};
153 j["MinimapPlayerX"] = Minimap.PlayerX;
154 j["MinimapPlayerY"] = Minimap.PlayerY;
155 j["MinimapPlayerScaleFactor"] = Minimap.PlayerScaleFactor;
156 j["MinimapFinishlineX"] = Minimap.FinishlineX;
157 j["MinimapFinishlineY"] = Minimap.FinishlineY;
158 j["MinimapColour"] = {static_cast<int>(Minimap.Colour.r), static_cast<int>(Minimap.Colour.g), static_cast<int>(Minimap.Colour.b)};
159 // SkyboxColors - assuming SkyboxColors can be serialized similarly
160
161 #define TO_INT(value) static_cast<int>(value)
162 j["Skybox"] = {
163 TO_INT(Skybox.TopRight.r), TO_INT(Skybox.TopRight.g), TO_INT(Skybox.TopRight.b),
164 TO_INT(Skybox.BottomRight.r), TO_INT(Skybox.BottomRight.g), TO_INT(Skybox.BottomRight.b),
165 TO_INT(Skybox.BottomLeft.r), TO_INT(Skybox.BottomLeft.g), TO_INT(Skybox.BottomLeft.b),
166 TO_INT(Skybox.TopLeft.r), TO_INT(Skybox.TopLeft.g), TO_INT(Skybox.TopLeft.b),
167 TO_INT(Skybox.FloorTopRight.r), TO_INT(Skybox.FloorTopRight.g), TO_INT(Skybox.FloorTopRight.b),
168 TO_INT(Skybox.FloorBottomRight.r), TO_INT(Skybox.FloorBottomRight.g), TO_INT(Skybox.FloorBottomRight.b),
169 TO_INT(Skybox.FloorBottomLeft.r), TO_INT(Skybox.FloorBottomLeft.g), TO_INT(Skybox.FloorBottomLeft.b),
170 TO_INT(Skybox.FloorTopLeft.r), TO_INT(Skybox.FloorTopLeft.g), TO_INT(Skybox.FloorTopLeft.b)
171 };
172 j["Sequence"] = static_cast<int>(Sequence);
173
174 j["WaterLevel"] = static_cast<float>(WaterLevel);
175 #undef CAST_TO_INT
176
177 return j;
178 }
179
180 // Function to load struct from JSON
181 void from_json(const nlohmann::json& j) {
182 strncpy(Name, j.at("Name").get<std::string>().c_str(), sizeof(Name) - 1);
183 Name[sizeof(Name) - 1] = '\0'; // Ensure null termination
184
185 strncpy(DebugName, j.at("DebugName").get<std::string>().c_str(), sizeof(DebugName) - 1);
186 DebugName[sizeof(DebugName) - 1] = '\0'; // Ensure null termination
187
188 strncpy(TrackLength, j.at("TrackLength").get<std::string>().c_str(), sizeof(TrackLength) - 1);
189 TrackLength[sizeof(TrackLength) - 1] = '\0'; // Ensure null termination
190
191 //AIBehaviour = j.at("AIBehaviour").get<std::string>().c_str();
192 LakituTowType = j.at("LakituTowType").get<int>();
193
194 AIMaximumSeparation = j.at("AIMaximumSeparation").get<float>();
195 AIMinimumSeparation = j.at("AIMinimumSeparation").get<float>();
196 NearPersp = j.at("NearPersp").get<float>();
197 FarPersp = j.at("FarPersp").get<float>();
198
199 const auto temp = j.at("AIDistance").get<std::vector<int16_t>>();
200
201 // Ensure the vector has 32 entries
202 if (temp.size() == 32) {
203 // Copy the data into the existing AIDistances array
204 std::copy(temp.begin(), temp.end(), AIDistance);
205 } else {
206 printf("[Track.h] [from_json()] AIDistance array not size of 32\n");
207 }
208
209 AISteeringSensitivity = j.at("AISteeringSensitivity").get<uint32_t>();
210
211 // Deserialize PathSizes and other custom structs if needed
212
213 CurveTargetSpeed[0] = j.at("CurveTargetSpeed")[0].get<float>();
214 CurveTargetSpeed[1] = j.at("CurveTargetSpeed")[1].get<float>();
215 CurveTargetSpeed[2] = j.at("CurveTargetSpeed")[2].get<float>();
216 CurveTargetSpeed[3] = j.at("CurveTargetSpeed")[3].get<float>();
217
218 NormalTargetSpeed[0] = j.at("NormalTargetSpeed")[0].get<float>();
219 NormalTargetSpeed[1] = j.at("NormalTargetSpeed")[1].get<float>();
220 NormalTargetSpeed[2] = j.at("NormalTargetSpeed")[2].get<float>();
221 NormalTargetSpeed[3] = j.at("NormalTargetSpeed")[3].get<float>();
222
223 D_0D0096B8[0] = j.at("D_0D0096B8")[0].get<float>();
224 D_0D0096B8[1] = j.at("D_0D0096B8")[1].get<float>();
225 D_0D0096B8[2] = j.at("D_0D0096B8")[2].get<float>();
226 D_0D0096B8[3] = j.at("D_0D0096B8")[3].get<float>();
227
228 OffTrackTargetSpeed[0] = j.at("OffTrackTargetSpeed")[0].get<float>();
229 OffTrackTargetSpeed[1] = j.at("OffTrackTargetSpeed")[1].get<float>();
230 OffTrackTargetSpeed[2] = j.at("OffTrackTargetSpeed")[2].get<float>();
231 OffTrackTargetSpeed[3] = j.at("OffTrackTargetSpeed")[3].get<float>();
232
233 // Deserialize arrays PathTable and PathTable2 similarly
234
235 //Clouds = nullptr; // Deserialize if data is present
236 //CloudList = nullptr; // Deserialize if data is present
237 Minimap.Pos[0].X = j.at("MinimapPosition")[0].get<int32_t>();
238 Minimap.Pos[0].Y = j.at("MinimapPosition")[1].get<int32_t>();
239 Minimap.Pos[1].X = j.at("MinimapPosition2P")[0].get<int32_t>();
240 Minimap.Pos[1].Y = j.at("MinimapPosition2P")[1].get<int32_t>();
241 Minimap.PlayerX = j.at("MinimapPlayerX").get<int32_t>();
242 Minimap.PlayerY = j.at("MinimapPlayerY").get<int32_t>();
243 Minimap.PlayerScaleFactor = j.at("MinimapPlayerScaleFactor").get<float>();
244 Minimap.FinishlineX = j.at("MinimapFinishlineX").get<float>();
245 Minimap.FinishlineY = j.at("MinimapFinishlineY").get<float>();
246 Minimap.Colour.r = j.at("MinimapColour")[0].get<uint8_t>();
247 Minimap.Colour.g = j.at("MinimapColour")[1].get<uint8_t>();
248 Minimap.Colour.b = j.at("MinimapColour")[2].get<uint8_t>();
249 //textures = nullptr; // Deserialize textures if present
250
251 Skybox.TopRight.r = j.at("Skybox")[0].get<uint8_t>();
252 Skybox.TopRight.g = j.at("Skybox")[1].get<uint8_t>();
253 Skybox.TopRight.b = j.at("Skybox")[2].get<uint8_t>();
254
255 Skybox.BottomRight.r = j.at("Skybox")[3].get<uint8_t>();
256 Skybox.BottomRight.g = j.at("Skybox")[4].get<uint8_t>();
257 Skybox.BottomRight.b = j.at("Skybox")[5].get<uint8_t>();
258
259 Skybox.BottomLeft.r = j.at("Skybox")[6].get<uint8_t>();
260 Skybox.BottomLeft.g = j.at("Skybox")[7].get<uint8_t>();
261 Skybox.BottomLeft.b = j.at("Skybox")[8].get<uint8_t>();
262
263 Skybox.TopLeft.r = j.at("Skybox")[9].get<uint8_t>();
264 Skybox.TopLeft.g = j.at("Skybox")[10].get<uint8_t>();
265 Skybox.TopLeft.b = j.at("Skybox")[11].get<uint8_t>();
266
267 Skybox.FloorTopRight.r = j.at("Skybox")[12].get<uint8_t>();
268 Skybox.FloorTopRight.g = j.at("Skybox")[13].get<uint8_t>();
269 Skybox.FloorTopRight.b = j.at("Skybox")[14].get<uint8_t>();
270
271 Skybox.FloorBottomRight.r = j.at("Skybox")[15].get<uint8_t>();
272 Skybox.FloorBottomRight.g = j.at("Skybox")[16].get<uint8_t>();
273 Skybox.FloorBottomRight.b = j.at("Skybox")[17].get<uint8_t>();
274
275 Skybox.FloorBottomLeft.r = j.at("Skybox")[18].get<uint8_t>();
276 Skybox.FloorBottomLeft.g = j.at("Skybox")[19].get<uint8_t>();
277 Skybox.FloorBottomLeft.b = j.at("Skybox")[20].get<uint8_t>();
278
279 Skybox.FloorTopLeft.r = j.at("Skybox")[21].get<uint8_t>();
280 Skybox.FloorTopLeft.g = j.at("Skybox")[22].get<uint8_t>();
281 Skybox.FloorTopLeft.b = j.at("Skybox")[23].get<uint8_t>();
282
283 Sequence = static_cast<MusicSeq>(j.at("Sequence").get<int>());
284 WaterLevel = j.at("WaterLevel").get<float>();
285 }
286 void SetText(char* name, const char* title, size_t bufferSize) {
287 // Copy the title into the name buffer, ensuring it's null-terminated and within bounds
288 std::strncpy(name, title, bufferSize - 1);
289 name[bufferSize - 1] = '\0'; // Ensure the string is null-terminated
290 }
291
292 const char* GetName() {
293 return Name;
294 }
295
296 void New() {
297 SetText(Name, "", sizeof(Name));
298 SetText(DebugName, "", sizeof(DebugName));
299 SetText(TrackLength, "", sizeof(TrackLength));
300 }
301#endif
302
304
305#ifdef __cplusplus
306
307
308class World; // <-- Forward declare
309
310
311class Track {
312public:
313 enum class CloudType {
314 NONE,
315 CLOUDS,
316 SNOW,
317 STARS
318 };
319 // Required to save scenefile data
320 std::shared_ptr<Ship::Archive> Archive;
321 std::string ResourceName;
322
323 Properties Props;
324 enum CloudType mCloudType;
325
326 // This allows multiple water levels in a map.
327 // Ex. DK Jungle where there's a waterfall and you can drive above and below it.
328 std::vector<WaterVolume> WaterVolumes;
329
330 bool bSpawnFinishline = true;
331 std::optional<FVector> FinishlineSpawnPoint;
332
333
334 std::vector<SpawnParams> SpawnList;
335
336 bool bTourEnabled = false;
337 std::vector<TourCamera::CameraShot> TourShots;
338
339 explicit Track();
340
341 virtual ~Track() {
343 };
344
345 virtual void Load(); // Decompress and load stock tracks or from o2r but TrackSectionsPtr must be set.
346 virtual void Load(Vtx* vtx, Gfx *gfx); // Load custom track from code. Load must be overridden and then call to this base class method impl.
347
352 virtual void BeginPlay();
353 void SpawnActors();
354 virtual void SomeCollisionThing(Player *player, Vec3f arg1, Vec3f arg2, Vec3f arg3, f32* arg4, f32* arg5, f32* arg6, f32* arg7);
355 virtual void InitTrackObjects();
356 virtual void TickTrackObjects();
357 virtual void DrawTrackObjects(s32 cameraId);
358 virtual void SomeSounds();
359 virtual void CreditsSpawnActors();
360 virtual void WhatDoesThisDo(Player*, int8_t);
361 virtual void WhatDoesThisDoAI(Player*, int8_t);
362 virtual void SetStaffGhost();
363 virtual void Draw(ScreenContext*);
364 virtual void DrawCredits();
365 virtual void Waypoints(Player* player, int8_t playerId);
366 virtual f32 GetWaterLevel(FVector pos, Collision* collision);
367 virtual void Tick();
368 // Draw transparent models (water, signs, arrows, etc.)
369 virtual void DrawTransparency(ScreenContext* screen, uint16_t pathCounter, uint16_t cameraRot,
370 uint16_t playerDirection);
371 virtual void Destroy();
372 // Note that this will be false for custom tracks made using code
373 // Probably ok
374 virtual bool IsMod() { return false; };
375
376
377 protected:
378 void Init();
379};
380
381void InvertTriangleWindingModdedInternal(Gfx* gfx, const char* gfxName);
382
383#endif
384
385#endif // ENGINE_TRACK_H
void RestoreTriangleWinding()
Definition Track.cpp:293
void InvertTriangleWindingModdedInternal(Gfx *gfx, const char *gfxName)
Definition Track.cpp:193
void InvertTriangleWindingByName(const char *name)
Definition Track.cpp:284
void ReverseGfx(Gfx *gfx)
void RestoreTriangleWinding()
Definition Track.cpp:293
struct Properties Properties
void ResizeMinimap(MinimapProps *minimap)
Definition Track.cpp:37
void InvertTriangleWinding(Gfx *gfx)
Definition Track.cpp:280
bool IsTriangleWindingInverted()
Definition Track.cpp:342
Definition World.h:40
f32 Vec3f[3]
Definition common_structs.h:10
f32 Vec4f[4]
Definition common_structs.h:11
#define j
@ SNOW
Definition mk64.h:91
void Destroy()
Definition ImguiUI.cpp:90
@ f32
Definition GenericArray.h:59
void SpawnActors(std::vector< std::pair< std::string, SpawnParams > > spawnList)
struct StarData CloudData
MusicSeq
Definition sounds.h:119
Definition CoreMath.h:119
Definition Track.h:54
IVector2D Pos[2]
Definition Track.h:58
int16_t Width
Definition Track.h:56
RGB8 Colour
Definition Track.h:64
float FinishlineY
Definition Track.h:63
int32_t PlayerY
Definition Track.h:60
const char * Texture
Definition Track.h:55
float PlayerScaleFactor
Definition Track.h:61
float FinishlineX
Definition Track.h:62
int32_t PlayerX
Definition Track.h:59
int16_t Height
Definition Track.h:57
Definition Track.h:90
char Name[128]
Definition Track.h:91
uint8_t * CloudTexture
Definition Track.h:110
TrackPathPoint * PathTable2[5]
Definition Track.h:109
CloudData * Clouds
Definition Track.h:111
Vec4f D_0D0096B8
Definition Track.h:106
Vec4f CurveTargetSpeed
Definition Track.h:104
float AIMaximumSeparation
Definition Track.h:97
float WaterLevel
Definition Track.h:115
int32_t LakituTowType
Definition Track.h:94
Vec4f OffTrackTargetSpeed
Definition Track.h:107
uint32_t AISteeringSensitivity
Definition Track.h:102
TrackPathPoint * PathTable[4]
Definition Track.h:108
const char * AIBehaviour
Definition Track.h:96
TrackPathSizes PathSizes
Definition Track.h:103
float NearPersp
Definition Track.h:99
SkyboxColours Skybox
Definition Track.h:113
float AIMinimumSeparation
Definition Track.h:98
char TrackLength[128]
Definition Track.h:93
enum MusicSeq Sequence
Definition Track.h:114
int16_t * AIDistance
Definition Track.h:101
char DebugName[128]
Definition Track.h:92
CloudData * CloudList
Definition Track.h:112
float FarPersp
Definition Track.h:100
MinimapProps Minimap
Definition Track.h:95
Vec4f NormalTargetSpeed
Definition Track.h:105
Definition common_structs.h:427
Definition Track.h:30
RGB8 BottomLeft
Definition Track.h:33
RGB8 FloorBottomRight
Definition Track.h:36
RGB8 BottomRight
Definition Track.h:32
RGB8 FloorBottomLeft
Definition Track.h:37
RGB8 TopRight
Definition Track.h:31
RGB8 TopLeft
Definition Track.h:34
RGB8 FloorTopRight
Definition Track.h:35
RGB8 FloorTopLeft
Definition Track.h:38
Definition waypoints.h:14
Definition path_spawn_metadata.h:9
Definition Track.h:81
uint64_t crc
Definition Track.h:82
u8 sectionId
Definition Track.h:84
u16 layer
Definition Track.h:86
u8 surfaceType
Definition Track.h:83
u16 clip
Definition Track.h:85
Vec3f location
Definition Track.h:87
Definition Track.h:46
float Height
Definition Track.h:47
float MaxX
Definition Track.h:49
float MinZ
Definition Track.h:50
float MinX
Definition Track.h:48
float MaxZ
Definition Track.h:51