[modding] Implement Vehicles & Fix Animations (#109)

* Train works

* Fix minimap

* Fix highway

* Fix

* Refactor train and boat

* Update

* Implement Trucks

* Fix tanker

* Finish implementing vehicles

* Fix animations

* Fix spawn players

* Fix spawn players

* Fix loading custom data

---------

Co-authored-by: MegaMech <7255464+MegaMech@users.noreply.github.com>
This commit is contained in:
MegaMech
2024-10-15 13:09:43 -06:00
committed by GitHub
parent 58d56fcba8
commit a0862b6a15
82 changed files with 3130 additions and 808 deletions
+7
View File
@@ -22,6 +22,13 @@ void Cup::Previous() {
}
}
void Cup::SetCourse(size_t position) {
if ((position < 0) || (position >= Courses.size())) {
throw std::invalid_argument("Invalid course index.");
}
CursorPosition = position;
}
Course* Cup::GetCourse() {
return Courses[CursorPosition];
}
+1
View File
@@ -20,6 +20,7 @@ public:
virtual void Next();
virtual void Previous();
virtual void SetCourse(size_t position);
virtual Course* GetCourse();
virtual size_t GetSize();
};
+5 -2
View File
@@ -5,6 +5,7 @@
#include "bomb_kart.h"
#include "objects.h"
#include "path_spawn_metadata.h"
#include "waypoints.h"
typedef struct {
RGB8 TopRight;
@@ -23,6 +24,8 @@ typedef struct {
const char* DebugName;
const char* CourseLength;
const char* AIBehaviour;
const char* MinimapTexture;
s16 D_800E5548[2];
float AIMaximumSeparation;
float AIMinimumSeparation;
float NearPersp;
@@ -34,8 +37,8 @@ typedef struct {
Vec4f D_0D009568;
Vec4f D_0D0096B8;
Vec4f D_0D009808;
const char* PathTable[4];
const char* PathTable2[4];
TrackWaypoint* PathTable[4];
TrackWaypoint* PathTable2[4];
CloudData *Clouds;
CloudData *CloudList;
s32 MinimapFinishlineX;
-3
View File
@@ -19,6 +19,3 @@ void GameObject::Render(Camera* camera) { }
void GameObject::Collision() {}
void GameObject::Expire() { }
void GameObject::Destroy() { }
// World* GameObject::GetWorld() {
// // return &gWorldInstance;
// }
+109
View File
@@ -0,0 +1,109 @@
#include <libultraship.h>
#include <libultra/gbi.h>
#include "Smoke.h"
#include "World.h"
#include "vehicles/Vehicle.h"
#include "vehicles/Train.h"
#include "vehicles/Boat.h"
extern "C" {
#include "macros.h"
#include "render_objects.h"
#include "code_80057C60.h"
#include "update_objects.h"
#include "math_util_2.h"
#include "assets/common_data.h"
}
//! @todo: This should be an Object class one day
void TrainSmokeTick() {
s32 count;
s32 i;
s32 temp_a0;
Object* object;
for (auto& vehicle : gWorldInstance.Vehicles) {
if (auto train = dynamic_cast<ATrain*>(vehicle.get())) {
if (train->SmokeTimer != 0) {
train->SmokeTimer -= 1;
}
if ((train->SomeFlags != 0) || (train->SmokeTimer != 0)) {
count = 0;
for (i = 0; i < 128; i++) {
temp_a0 = train->SmokeParticles[i];
if (temp_a0 != -1) {
object = &gObjectList[temp_a0];
if (object->state != 0) {
func_80075714(temp_a0);
if (object->state == 0) {
delete_object_wrapper(&train->SmokeParticles[i]);
}
count += 1;
}
}
}
if (count != 0) {
train->SmokeTimer = 100;
}
}
} else if (auto boat = dynamic_cast<ABoat*>(vehicle.get())) {
if (boat->SmokeTimer != 0) {
boat->SmokeTimer -= 1;
}
if ((boat->SomeFlags != 0) || (boat->SmokeTimer != 0)) {
count = 0;
for (size_t i = 0; i < 128; i++) {
temp_a0 = boat->SmokeParticles[i];
if (temp_a0 != -1) {
object = &gObjectList[temp_a0];
if (object->state != 0) {
func_80075B84(temp_a0);
if (object->state == 0) {
delete_object_wrapper(&boat->SmokeParticles[i]);
}
count += 1;
}
}
}
if (count != 0) {
boat->SmokeTimer = 100;
}
}
}
}
}
void TrainSmokeDraw(s32 cameraId) {
Camera* camera = &camera1[cameraId];
for (auto& vehicle : gWorldInstance.Vehicles) {
if (auto train = dynamic_cast<ATrain*>(vehicle.get())) {
gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D007AE0);
load_texture_block_i8_nomirror((uint8_t*)D_0D029458, 32, 32);
func_8004B72C(255, 255, 255, 255, 255, 255, 255);
D_80183E80[0] = 0;
D_80183E80[2] = 0x8000;
if ((train->SomeFlags != 0) &&
(is_particle_on_screen(train->Locomotive.position, camera, 0x4000U) != 0)) {
for (size_t i = 0; i < 128; i++) {
render_object_train_smoke_particle(train->SmokeParticles[i], cameraId);
}
}
} else if (auto boat = dynamic_cast<ABoat*>(vehicle.get())) {
gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D007AE0);
load_texture_block_i8_nomirror((uint8_t*)D_0D029458, 32, 32);
func_8004B72C(255, 255, 255, 255, 255, 255, 255);
D_80183E80[0] = 0;
D_80183E80[2] = 0x8000;
if ((boat->SomeFlags != 0) && (is_particle_on_screen(boat->Position, camera, 0x4000U) != 0)) {
for (size_t i = 0; i < gObjectParticle2_SIZE; i++) {
render_object_paddle_boat_smoke_particle(boat->SmokeParticles[i], cameraId);
}
}
}
}
}
+7
View File
@@ -0,0 +1,7 @@
#ifndef _ENGINE_SMOKE_H
#define _ENGINE_SMOKE_H
void TrainSmokeTick(void);
void TrainSmokeDraw(s32 cameraId);
#endif // _ENGINE_SMOKE_H
+89
View File
@@ -0,0 +1,89 @@
#include <libultraship.h>
#include "TrainCrossing.h"
#include "World.h"
#include "vehicles/Vehicle.h"
#include "vehicles/Train.h"
#include <memory>
extern "C" {
#include "macros.h"
#include "main.h"
#include "vehicles.h"
#include "code_80005FD0.h"
#include "common_structs.h"
}
TrainCrossing::TrainCrossing(Vec3f position, u32 waypointMin, u32 waypointMax, f32 approachRadius, f32 exitRadius) {
Position[0] = position[0];
Position[1] = position[1];
Position[2] = position[2];
ApproachRadius = approachRadius;
ExitRadius = exitRadius;
WaypointMin = waypointMin;
WaypointMax = waypointMax;
}
void TrainCrossing::CrossingTrigger() {
f32 waypoint;
s32 i;
OnTriggered = 0;
for (const auto& vehicle : gWorldInstance.Vehicles) {
if (auto train = dynamic_cast<ATrain*>(vehicle.get())) {;
f32 radius = DynamicRadius(train->Locomotive.position, train->Locomotive.velocity, Position);
if (Distance(train->Locomotive.position, Position) < radius) {
OnTriggered = true; // Trigger within range
}
}
}
if (OnTriggered) {
Timer += 1;
} else {
Timer = 0;
}
}
void TrainCrossing::AICrossingBehaviour(s32 playerId) {
bStopAICrossing[playerId] = 0;
if ((!(D_801631E0[playerId] != 0)) ||
(set_vehicle_render_distance_flags(gPlayers[playerId].pos, TRAIN_CROSSING_AI_DISTANCE, 0))) {
if ((OnTriggered == 1) && ((Timer) > FRAMES_SINCE_CROSSING_ACTIVATED)) {
if ((sSomeNearestWaypoint > WaypointMin) && (sSomeNearestWaypoint < WaypointMax)) {
printf("STOP AI\n");
bStopAICrossing[playerId] = 1;
}
}
}
}
f32 TrainCrossing::Distance(Vec3f a, Vec3f b) {
float dx = b[0] - a[0]; // Difference in x-coordinates
float dy = b[1] - a[1]; // Difference in y-coordinates
float dz = b[2] - a[2]; // Difference in z-coordinates
return sqrt(dx * dx + dy * dy + dz * dz); // Return the distance
}
f32 TrainCrossing::DynamicRadius(Vec3f trainPos, Vec3f trainVelocity, Vec3f crossingPos) {
// Calculate direction of train (this assumes velocity is a normalized direction vector)
Vec3f trainToCrossing;
trainToCrossing[0] = crossingPos[0] - trainPos[0];
trainToCrossing[1] = crossingPos[1] - trainPos[1];
trainToCrossing[2] = crossingPos[2] - trainPos[2];
// Dot product to check if the train is approaching or moving away from the crossing
f32 dotProduct = trainToCrossing[0] * trainVelocity[0] +
trainToCrossing[1] * trainVelocity[1] +
trainToCrossing[2] * trainVelocity[2];
if (dotProduct > 0) {
// Train is approaching the crossing
return ApproachRadius;
} else {
// Train has passed the crossing
return ExitRadius;
}
}
+35
View File
@@ -0,0 +1,35 @@
#pragma once
#include <libultraship.h>
extern "C" {
#include "common_structs.h"
}
/**
* @brief TrainCrossing class
* @arg Vec3f position of the crossing
* @arg u32 waypointMin
* @arg u32 waypointMax
*
* Min/Max are used to determine the range for AI to stop for the crossing.
*
*/
class TrainCrossing {
public:
TrainCrossing(Vec3f position, u32 waypointMin, u32 waypointMax, f32 approachRadius, f32 exitRadius);
Vec3f Position;
s32 OnTriggered = 0;
u32 Timer;
u32 WaypointMin;
u32 WaypointMax;
f32 ApproachRadius;
f32 ExitRadius;
virtual void CrossingTrigger();
virtual void AICrossingBehaviour(s32 playerId);
f32 Distance(Vec3f a, Vec3f b);
f32 DynamicRadius(Vec3f trainPos, Vec3f trainVelocity, Vec3f crossingPos);
};
+58
View File
@@ -2,6 +2,16 @@
#include "World.h"
#include "Cup.h"
#include "courses/Course.h"
#include "vehicles/Vehicle.h"
#include "vehicles/Train.h"
#include "vehicles/Boat.h"
#include "vehicles/Truck.h"
#include "vehicles/Bus.h"
#include "vehicles/TankerTruck.h"
#include "vehicles/Car.h"
#include "TrainCrossing.h"
#include <memory>
extern "C" {
#include "camera.h"
@@ -38,6 +48,54 @@ void World::SetCourseFromCup() {
CurrentCourse = CurrentCup->GetCourse();
}
// Required for spawning vehicles in divisions across path points
static size_t trains;
static size_t trucks;
static size_t busses;
static size_t tankerTrucks;
static size_t cars;
static size_t boats;
void World::AddTrain(size_t numCarriages, f32 speed, uint32_t waypoint) {
Vehicles.push_back(std::make_unique<ATrain>(trains, numCarriages, speed, waypoint));
trains++;
}
void World::AddBoat(f32 speed, uint32_t waypoint) {
Vehicles.push_back(std::make_unique<ABoat>(boats, speed, waypoint));
boats++;
}
void World::AddTruck(f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint) {
Vehicles.push_back(std::make_unique<ATruck>(trucks, speedA, speedB, path, waypoint));
trucks++;
}
void World::AddBus(f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint) {
Vehicles.push_back(std::make_unique<ABus>(busses, speedA, speedB, path, waypoint));
busses++;
}
void World::AddTankerTruck(f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint) {
Vehicles.push_back(std::make_unique<ATankerTruck>(tankerTrucks, speedA, speedB, path, waypoint));
tankerTrucks++;
}
void World::AddCar(f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint) {
Vehicles.push_back(std::make_unique<ACar>(cars, speedA, speedB, path, waypoint));
cars++;
}
void World::ResetVehicles(void) {
trains = trucks = busses = tankerTrucks = cars = boats = 0;
Vehicles.clear();
}
TrainCrossing* World::AddCrossing(Vec3f position, u32 waypointMin, u32 waypointMax, f32 approachRadius, f32 exitRadius) {
auto crossing = std::make_shared<TrainCrossing>(position, waypointMin, waypointMax, approachRadius, exitRadius);
Crossings.push_back(crossing);
return crossing.get();
}
//const char* World::GetCupName() {
// //return this->Cups[CupIndex].Name;
//}
+22 -2
View File
@@ -3,6 +3,11 @@
#include <libultraship.h>
#include "GameObject.h"
#include "Cup.h"
#include "vehicles/Vehicle.h"
#include "vehicles/Train.h"
#include "vehicles/Car.h"
#include "TrainCrossing.h"
#include <memory>
extern "C" {
#include "camera.h"
@@ -12,6 +17,10 @@ extern "C" {
class Cup; // <-- Forward declaration
class Course;
class AVehicle;
class ATrain;
class ACar;
class TrainCrossing;
class World {
@@ -81,7 +90,7 @@ public:
virtual void SetCourseFromCup();
void SetCup();
World* GetWorld();
World* GetWorld(void);
// These are only for browsing through the course list
@@ -100,6 +109,18 @@ public:
std::vector<std::unique_ptr<GameObject>> GameObjects;
// std::vector<std::unique_ptr<GameActor>> GameActors;
void AddBoat(f32 speed, uint32_t waypoint);
void AddTrain(size_t numCarriages, f32 speed, uint32_t waypoint);
void AddTruck(f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint);
void AddBus(f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint);
void AddTankerTruck(f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint);
void AddCar(f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint);
std::vector<std::unique_ptr<AVehicle>> Vehicles;
void ResetVehicles(void);
TrainCrossing* AddCrossing(Vec3f position, u32 waypointMin, u32 waypointMax, f32 approachRadius, f32 exitRadius);
std::vector<std::shared_ptr<TrainCrossing>> Crossings;
std::vector<Course*> Courses;
size_t CourseIndex = 0; // For browsing courses.
private:
@@ -107,4 +128,3 @@ private:
};
extern World gWorldInstance;
+14 -15
View File
@@ -38,6 +38,9 @@ BansheeBoardwalk::BansheeBoardwalk() {
this->gfx = d_course_banshee_boardwalk_packed_dls;
this->gfxSize = 3689;
this->textures = banshee_boardwalk_textures;
Props.MinimapTexture = gTextureCourseOutlineBansheeBoardwalk;
Props.D_800E5548[0] = 64;
Props.D_800E5548[1] = 64;
Props.Id = "mk:banshee_boardwalk";
Props.Name = "banshee boardwalk";
@@ -74,12 +77,12 @@ BansheeBoardwalk::BansheeBoardwalk() {
Props.D_0D009808[2] = 5.75f;
Props.D_0D009808[3] = 6.3333334f;
Props.PathTable[0] = d_course_banshee_boardwalk_unknown_waypoints;
Props.PathTable[0] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_banshee_boardwalk_unknown_waypoints);
Props.PathTable[1] = NULL;
Props.PathTable[2] = NULL;
Props.PathTable[3] = NULL;
Props.PathTable2[0] = d_course_banshee_boardwalk_track_waypoints;
Props.PathTable2[0] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_banshee_boardwalk_track_waypoints);
Props.PathTable2[1] = NULL;
Props.PathTable2[2] = NULL;
Props.PathTable2[3] = NULL;
@@ -103,7 +106,7 @@ void BansheeBoardwalk::LoadTextures() {
}
void BansheeBoardwalk::SpawnActors() {
spawn_all_item_boxes(d_course_banshee_boardwalk_item_box_spawns);
spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_banshee_boardwalk_item_box_spawns));
}
void BansheeBoardwalk::Init() { }
@@ -188,17 +191,13 @@ void BansheeBoardwalk::WhatDoesThisDoAI(Player* player, int8_t playerId) {
}
void BansheeBoardwalk::SpawnBombKarts() {
World* world = GetWorld();
if (world) {
world->SpawnObject(std::make_unique<OBombKart>(140, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(165, 1, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(330, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(550, 1, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(595, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
}
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(140, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(165, 1, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(330, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(550, 1, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(595, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
}
// Positions the finishline on the minimap
@@ -282,7 +281,7 @@ void BansheeBoardwalk::GenerateCollision() {
D_801625EC = 0;
D_801625F4 = 0;
D_801625F0 = 0;
parse_course_displaylists(d_course_banshee_boardwalk_track_sections);
parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_banshee_boardwalk_track_sections));
func_80295C6C();
find_vtx_and_set_colours(segmented_gfx_to_virtual(reinterpret_cast<void*>(0x07000878)), 128, 0, 0, 0);
D_8015F8E4 = -80.0f;
+3
View File
@@ -38,6 +38,9 @@ BigDonut::BigDonut() {
this->gfx = d_course_big_donut_packed_dls;
this->gfxSize = 528;
this->textures = big_donut_textures;
Props.MinimapTexture = gTextureCourseOutlineBigDonut;
Props.D_800E5548[0] = 64;
Props.D_800E5548[1] = 64;
Props.Name = "big donut";
Props.DebugName = "doughnut";
+3
View File
@@ -38,6 +38,9 @@ BlockFort::BlockFort() {
this->gfx = d_course_block_fort_packed_dls;
this->gfxSize = 699;
this->textures = block_fort_textures;
Props.MinimapTexture = gTextureCourseOutlineBlockFort;
Props.D_800E5548[0] = 64;
Props.D_800E5548[1] = 64;
Props.Name = "block fort";
Props.DebugName = "block";
+20 -16
View File
@@ -28,6 +28,7 @@ extern "C" {
#include "staff_ghosts.h"
#include "actors.h"
#include "collision.h"
#include "code_8003DC40.h"
#include "memory.h"
extern const char *bowsers_castle_dls[];
}
@@ -37,6 +38,9 @@ BowsersCastle::BowsersCastle() {
this->gfx = d_course_bowsers_castle_packed_dls;
this->gfxSize = 4900;
this->textures = bowsers_castle_textures;
Props.MinimapTexture = gTextureCourseOutlineBowsersCastle;
Props.D_800E5548[0] = 64;
Props.D_800E5548[1] = 64;
Props.Id = "mk:bowsers_castle";
Props.Name = "bowser's castle";
@@ -73,12 +77,12 @@ BowsersCastle::BowsersCastle() {
Props.D_0D009808[2] = 5.75f;
Props.D_0D009808[3] = 6.3333334f;
Props.PathTable[0] = d_course_bowsers_castle_unknown_waypoints;
Props.PathTable[0] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_bowsers_castle_unknown_waypoints);
Props.PathTable[1] = NULL;
Props.PathTable[2] = NULL;
Props.PathTable[3] = NULL;
Props.PathTable2[0] = d_course_bowsers_castle_track_waypoints;
Props.PathTable2[0] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_bowsers_castle_track_waypoints);
Props.PathTable2[1] = NULL;
Props.PathTable2[2] = NULL;
Props.PathTable2[3] = NULL;
@@ -103,8 +107,8 @@ void BowsersCastle::LoadTextures() {
}
void BowsersCastle::SpawnActors() {
spawn_foliage(d_course_bowsers_castle_tree_spawn);
spawn_all_item_boxes(d_course_bowsers_castle_item_box_spawns);
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));
}
void BowsersCastle::Init() { }
@@ -211,17 +215,13 @@ void BowsersCastle::WhatDoesThisDoAI(Player* player, int8_t playerId) {
}
void BowsersCastle::SpawnBombKarts() {
World* world = GetWorld();
if (world) {
world->SpawnObject(std::make_unique<OBombKart>(140, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(165, 1, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(330, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(550, 1, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(595, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
}
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(140, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(165, 1, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(330, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(550, 1, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(595, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
}
// Positions the finishline on the minimap
@@ -267,8 +267,12 @@ void BowsersCastle::RenderCredits() {
void BowsersCastle::Collision() {}
void BowsersCastle::SomeCollisionThing(Player *player, Vec3f arg1, Vec3f arg2, Vec3f arg3, f32* arg4, f32* arg5, f32* arg6, f32* arg7) {
func_8003E6EC(player, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
}
void BowsersCastle::GenerateCollision() {
parse_course_displaylists(d_course_bowsers_castle_addr);
parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_bowsers_castle_addr));
func_80295C6C();
find_vtx_and_set_colours(segmented_gfx_to_virtual(reinterpret_cast<void*>(0x07001350)), 0x32, 0, 0, 0);
D_8015F8E4 = -50.0f;
+2 -1
View File
@@ -39,8 +39,9 @@ public:
virtual void SetStaffGhost() override;
virtual void BeginPlay() override;
virtual void Render(struct UnkStruct_800DC5EC*) override;
virtual void RenderCredits() override;
virtual void RenderCredits() override;
virtual void Collision() override;
virtual void SomeCollisionThing(Player *player, Vec3f arg1, Vec3f arg2, Vec3f arg3, f32* arg4, f32* arg5, f32* arg6, f32* arg7) override;
virtual void SpawnBombKarts() override;
virtual void GenerateCollision() override;
virtual void Waypoints(Player*, int8_t) override;
+20 -16
View File
@@ -28,6 +28,7 @@ extern "C" {
#include "staff_ghosts.h"
#include "actors.h"
#include "collision.h"
#include "code_8003DC40.h"
#include "memory.h"
extern const char *choco_mountain_dls[];
}
@@ -37,6 +38,9 @@ ChocoMountain::ChocoMountain() {
this->gfx = d_course_choco_mountain_packed_dls;
this->gfxSize = 2910;
this->textures = choco_mountain_textures;
Props.MinimapTexture = gTextureCourseOutlineChocoMountain;
Props.D_800E5548[0] = 64;
Props.D_800E5548[1] = 64;
Props.Id = "mk:choco_mountain";
Props.Name = "choco mountain";
@@ -73,12 +77,12 @@ ChocoMountain::ChocoMountain() {
Props.D_0D009808[2] = 5.75f;
Props.D_0D009808[3] = 6.3333334f;
Props.PathTable[0] = d_course_choco_mountain_unknown_waypoints;
Props.PathTable[0] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_choco_mountain_unknown_waypoints);
Props.PathTable[1] = NULL;
Props.PathTable[2] = NULL;
Props.PathTable[3] = NULL;
Props.PathTable2[0] = d_course_choco_mountain_track_waypoints;
Props.PathTable2[0] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_choco_mountain_track_waypoints);
Props.PathTable2[1] = NULL;
Props.PathTable2[2] = NULL;
Props.PathTable2[3] = NULL;
@@ -102,8 +106,8 @@ void ChocoMountain::LoadTextures() {
}
void ChocoMountain::SpawnActors() {
spawn_all_item_boxes(d_course_choco_mountain_item_box_spawns);
spawn_falling_rocks(d_course_choco_mountain_falling_rock_spawns);
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));
}
void ChocoMountain::Init() { }
@@ -164,17 +168,13 @@ void ChocoMountain::WhatDoesThisDoAI(Player* player, int8_t playerId) {
}
void ChocoMountain::SpawnBombKarts() {
World* world = GetWorld();
if (world) {
world->SpawnObject(std::make_unique<OBombKart>(140, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(165, 1, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(330, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(550, 1, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(595, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
}
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(140, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(165, 1, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(330, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(550, 1, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(595, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
}
// Positions the finishline on the minimap
@@ -240,6 +240,10 @@ void ChocoMountain::RenderCredits() {
void ChocoMountain::Collision() {}
void ChocoMountain::SomeCollisionThing(Player *player, Vec3f arg1, Vec3f arg2, Vec3f arg3, f32* arg4, f32* arg5, f32* arg6, f32* arg7) {
func_8003E37C(player, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
}
void ChocoMountain::GenerateCollision() {
D_800DC5BC = 1;
D_801625EC = 255;
@@ -266,7 +270,7 @@ void ChocoMountain::GenerateCollision() {
nullify_displaylist((uintptr_t) segmented_gfx_to_virtual(reinterpret_cast<void*>(0x070003C8)));
}
parse_course_displaylists(d_course_choco_mountain_addr);
parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_choco_mountain_addr));
func_802B5CAC(0x238E, 0x31C7, D_8015F590);
func_80295C6C();
D_8015F8E4 = -80.0f;
+1
View File
@@ -39,6 +39,7 @@ public:
virtual void Render(struct UnkStruct_800DC5EC*) override;
virtual void RenderCredits() override;
virtual void Collision() override;
virtual void SomeCollisionThing(Player *player, Vec3f arg1, Vec3f arg2, Vec3f arg3, f32* arg4, f32* arg5, f32* arg6, f32* arg7) override;
virtual void SpawnBombKarts() override;
virtual void GenerateCollision() override;
virtual void Destroy() override;
+1 -6
View File
@@ -147,6 +147,7 @@ void Course::UpdateClouds(s32 arg0, Camera* camera) {
}
}
// Adjusts player speed on steep hills
void Course::SomeCollisionThing(Player *player, Vec3f arg1, Vec3f arg2, Vec3f arg3, f32* arg4, f32* arg5, f32* arg6, f32* arg7) {
func_8003E048(player, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
}
@@ -197,12 +198,6 @@ void Course::SetStaffGhost() {
}
void Course::SpawnBombKarts() {
// GetWorld()->SpawnBombKarts();
}
World* Course::GetWorld() {
return nullptr;
//&gWorldInstance;
}
void Course::Waypoints(Player* player, int8_t playerId) {
+9 -11
View File
@@ -17,6 +17,7 @@ extern "C" {
#include "bomb_kart.h"
#include "path_spawn_metadata.h"
#include "Engine.h"
#include "waypoints.h"
CProperties *CourseManager_GetProps();
@@ -54,6 +55,8 @@ public:
const char* DebugName;
const char* CourseLength;
const char* AIBehaviour;
const char* MinimapTexture;
s16 D_800E5548[2];
float AIMaximumSeparation;
float AIMinimumSeparation;
float NearPersp;
@@ -65,8 +68,8 @@ public:
Vec4f D_0D009568;
Vec4f D_0D0096B8;
Vec4f D_0D009808;
const char* PathTable[4];
const char* PathTable2[4];
TrackWaypoint* PathTable[4];
TrackWaypoint* PathTable2[4];
CloudData *Clouds;
CloudData *CloudList;
int32_t MinimapFinishlineX;
@@ -81,15 +84,12 @@ public:
size_t gfxSize = 0;
const course_texture* textures = nullptr;
virtual ~Course() = default; // Virtual destructor for proper cleanup in derived classes
virtual ~Course() = default;
// Constructor
explicit Course(); // UUID should be passed in constructor
explicit Course();
// Virtual functions to be overridden by derived classes
virtual void Load();
virtual void Load(Vtx* vtx, Gfx *gfx);
// This function may not be needed due to otr system.
virtual void Load(); // Decompress and load stock courses. Must be overridden for custom courses
virtual void Load(Vtx* vtx, Gfx *gfx); // Load custom course
virtual void LoadTextures();
virtual void SpawnActors();
virtual void Init();
@@ -117,8 +117,6 @@ public:
virtual void GenerateCollision();
virtual void Water();
virtual void Destroy();
virtual World* GetWorld();
};
#endif
+23 -51
View File
@@ -9,6 +9,8 @@
#include "BombKart.h"
#include "assets/dks_jungle_parkway_data.h"
#include "engine/vehicles/Utils.h"
extern "C" {
#include "main.h"
#include "camera.h"
@@ -28,6 +30,7 @@ extern "C" {
#include "staff_ghosts.h"
#include "actors.h"
#include "collision.h"
#include "code_8003DC40.h"
#include "memory.h"
#include "sounds.h"
extern const char *d_course_dks_jungle_parkway_unknown_dl_list[];
@@ -39,6 +42,9 @@ DKJungle::DKJungle() {
this->gfx = d_course_dks_jungle_parkway_packed_dls;
this->gfxSize = 4997;
this->textures = dks_jungle_parkway_textures;
Props.MinimapTexture = gTextureCourseOutlineDksJungleParkway;
Props.D_800E5548[0] = 64;
Props.D_800E5548[1] = 64;
Props.Name = "d.k.'s jungle parkway";
Props.DebugName = "jungle";
@@ -74,12 +80,12 @@ DKJungle::DKJungle() {
Props.D_0D009808[2] = 5.75f;
Props.D_0D009808[3] = 6.3333334f;
Props.PathTable[0] = d_course_dks_jungle_parkway_unknown_waypoints;
Props.PathTable[0] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_dks_jungle_parkway_unknown_waypoints);
Props.PathTable[1] = NULL;
Props.PathTable[2] = NULL;
Props.PathTable[3] = NULL;
Props.PathTable2[0] = d_course_dks_jungle_parkway_track_waypoints;
Props.PathTable2[0] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_dks_jungle_parkway_track_waypoints);
Props.PathTable2[1] = NULL;
Props.PathTable2[2] = NULL;
Props.PathTable2[3] = NULL;
@@ -106,7 +112,7 @@ void DKJungle::LoadTextures() {
}
void DKJungle::SpawnActors() {
spawn_all_item_boxes(d_course_dks_jungle_parkway_item_box_spawns);
spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_dks_jungle_parkway_item_box_spawns));
init_kiwano_fruit();
func_80298D10();
}
@@ -190,17 +196,13 @@ void DKJungle::WhatDoesThisDoAI(Player* player, int8_t playerId) {
}
void DKJungle::SpawnBombKarts() {
World* world = GetWorld();
if (world) {
world->SpawnObject(std::make_unique<OBombKart>(40, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(100, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(265, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(285, 1, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(420, 1, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
}
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(40, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(100, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(265, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(285, 1, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(420, 1, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
}
// Positions the finishline on the minimap
@@ -241,48 +243,18 @@ void DKJungle::RenderCredits() {
void DKJungle::Collision() {}
void DKJungle::SpawnVehicles() {
s16 trainCarYRot;
UNUSED Vec3f pad;
TrainCarStuff* tempLocomotive;
TrainCarStuff* tempTender;
TrainCarStuff* tempPassengerCar;
Vec3s trainCarRot;
VehicleStuff* tempBoxTruck;
VehicleStuff* tempSchoolBus;
VehicleStuff* tempTankerTruck;
VehicleStuff* tempCar;
PaddleBoatStuff* tempPaddleWheelBoat;
Vec3s paddleWheelBoatRot;
s32 loopIndex;
s32 loopIndex2;
f32 origXPos;
f32 origZPos;
for (loopIndex = 0; loopIndex < NUM_ACTIVE_PADDLE_BOATS; loopIndex++) {
tempPaddleWheelBoat = &gPaddleBoats[loopIndex];
if (tempPaddleWheelBoat->isActive == 1) {
origXPos = tempPaddleWheelBoat->position[0];
origZPos = tempPaddleWheelBoat->position[2];
tempPaddleWheelBoat->rotY = update_vehicle_following_waypoint(
tempPaddleWheelBoat->position, (s16*) &tempPaddleWheelBoat->waypointIndex,
tempPaddleWheelBoat->speed);
tempPaddleWheelBoat->velocity[0] = tempPaddleWheelBoat->position[0] - origXPos;
tempPaddleWheelBoat->velocity[2] = tempPaddleWheelBoat->position[2] - origZPos;
vec3s_set(paddleWheelBoatRot, 0, tempPaddleWheelBoat->rotY, 0);
tempPaddleWheelBoat->actorIndex =
add_actor_to_empty_slot(tempPaddleWheelBoat->position, paddleWheelBoatRot,
tempPaddleWheelBoat->velocity, ACTOR_PADDLE_BOAT);
}
}
void DKJungle::SomeCollisionThing(Player *player, Vec3f arg1, Vec3f arg2, Vec3f arg3, f32* arg4, f32* arg5, f32* arg6, f32* arg7) {
func_8003F138(player, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
}
void DKJungle::UpdateVehicles() {
update_vehicle_paddle_boats();
void DKJungle::SpawnVehicles() {
generate_ferry_waypoints();
gWorldInstance.AddBoat(1.6666666f, 0);
}
void DKJungle::GenerateCollision() {
parse_course_displaylists(d_course_dks_jungle_parkway_addr);
parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_dks_jungle_parkway_addr));
func_80295C6C();
D_8015F8E4 = -475.0f;
// d_course_dks_jungle_parkway_packed_dl_3FA8
+1 -1
View File
@@ -41,8 +41,8 @@ public:
virtual void Render(struct UnkStruct_800DC5EC*) override;
virtual void RenderCredits() override;
virtual void SpawnVehicles() override;
virtual void UpdateVehicles() override;
virtual void Collision() override;
virtual void SomeCollisionThing(Player *player, Vec3f arg1, Vec3f arg2, Vec3f arg3, f32* arg4, f32* arg5, f32* arg6, f32* arg7) override;
virtual void SpawnBombKarts() override;
virtual void GenerateCollision() override;
virtual void Waypoints(Player* player, int8_t playerId) override;
+3
View File
@@ -38,6 +38,9 @@ DoubleDeck::DoubleDeck() {
this->gfx = d_course_double_deck_packed_dls;
this->gfxSize = 699;
this->textures = double_deck_textures;
Props.MinimapTexture = gTextureCourseOutlineDoubleDeck;
Props.D_800E5548[0] = 64;
Props.D_800E5548[1] = 64;
Props.Name = "double deck";
Props.DebugName = "deck";
+15 -16
View File
@@ -40,6 +40,9 @@ FrappeSnowland::FrappeSnowland() {
this->gfx = d_course_frappe_snowland_packed_dls;
this->gfxSize = 4140;
this->textures = frappe_snowland_textures;
Props.MinimapTexture = gTextureCourseOutlineFrappeSnowland;
Props.D_800E5548[0] = 64;
Props.D_800E5548[1] = 64;
Props.Name = "frappe snowland";
Props.DebugName = "snow";
@@ -75,12 +78,12 @@ FrappeSnowland::FrappeSnowland() {
Props.D_0D009808[2] = 5.75f;
Props.D_0D009808[3] = 6.3333334f;
Props.PathTable[0] = d_course_frappe_snowland_unknown_waypoints;
Props.PathTable[0] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_frappe_snowland_unknown_waypoints);
Props.PathTable[1] = NULL;
Props.PathTable[2] = NULL;
Props.PathTable[3] = NULL;
Props.PathTable2[0] = d_course_frappe_snowland_track_waypoints;
Props.PathTable2[0] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_frappe_snowland_track_waypoints);
Props.PathTable2[1] = NULL;
Props.PathTable2[2] = NULL;
Props.PathTable2[3] = NULL;
@@ -106,8 +109,8 @@ void FrappeSnowland::LoadTextures() {
}
void FrappeSnowland::SpawnActors() {
spawn_foliage(d_course_frappe_snowland_tree_spawns);
spawn_all_item_boxes(d_course_frappe_snowland_item_box_spawns);
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));
}
void FrappeSnowland::Init() { }
@@ -186,17 +189,13 @@ void FrappeSnowland::WhatDoesThisDo(Player* player, int8_t playerId) {}
void FrappeSnowland::WhatDoesThisDoAI(Player* player, int8_t playerId) {}
void FrappeSnowland::SpawnBombKarts() {
World* world = GetWorld();
if (world) {
world->SpawnObject(std::make_unique<OBombKart>(140, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(165, 1, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(330, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(550, 1, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(595, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
}
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(140, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(165, 1, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(330, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(550, 1, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(595, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
}
// Positions the finishline on the minimap
@@ -234,7 +233,7 @@ void FrappeSnowland::RenderCredits() {
void FrappeSnowland::Collision() {}
void FrappeSnowland::GenerateCollision() {
parse_course_displaylists(d_course_frappe_snowland_addr);
parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_frappe_snowland_addr));
func_80295C6C();
D_8015F8E4 = -50.0f;
}
+36 -88
View File
@@ -8,6 +8,9 @@
#include "World.h"
#include "BombKart.h"
#include "kalimari_desert_data.h"
#include "engine/vehicles/Utils.h"
#include "engine/vehicles/Vehicle.h"
extern "C" {
#include "main.h"
@@ -37,6 +40,9 @@ KalimariDesert::KalimariDesert() {
this->gfx = d_course_kalimari_desert_packed_dls;
this->gfxSize = 5328;
this->textures = kalimari_desert_textures;
Props.MinimapTexture = gTextureCourseOutlineKalimariDesert;
Props.D_800E5548[0] = 64;
Props.D_800E5548[1] = 96;
Props.Name = "kalimari desert";
Props.DebugName = "desert";
@@ -72,12 +78,12 @@ KalimariDesert::KalimariDesert() {
Props.D_0D009808[2] = 5.75f;
Props.D_0D009808[3] = 6.3333334f;
Props.PathTable[0] = d_course_kalimari_desert_unknown_waypoints;
Props.PathTable[0] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_kalimari_desert_unknown_waypoints);
Props.PathTable[1] = NULL;
Props.PathTable[2] = NULL;
Props.PathTable[3] = NULL;
Props.PathTable2[0] = d_course_kalimari_desert_track_waypoints;
Props.PathTable2[0] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_kalimari_desert_track_waypoints);
Props.PathTable2[1] = NULL;
Props.PathTable2[2] = NULL;
Props.PathTable2[3] = NULL;
@@ -111,29 +117,35 @@ void KalimariDesert::SpawnActors() {
Vec3f velocity = { 0.0f, 0.0f, 0.0f };
Vec3s rotation = { 0, 0, 0 };
spawn_foliage(d_course_kalimari_desert_cactus_spawn);
spawn_all_item_boxes(d_course_kalimari_desert_item_box_spawns);
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*) &gActorList[add_actor_to_empty_slot(position, rotation, velocity,
ACTOR_RAILROAD_CROSSING)];
rrxing->crossingId = 1;
rrxing->crossingTrigger = crossing2;
vec3f_set(position, -1600.0f, 2.0f, 35.0f);
position[0] *= gCourseDirection;
rrxing = (struct RailroadCrossing*) &gActorList[add_actor_to_empty_slot(position, rotation, velocity,
ACTOR_RAILROAD_CROSSING)];
rrxing->crossingId = 1;
rrxing->crossingTrigger = crossing2;
vec3s_set(rotation, 0, -0x2000, 0);
vec3f_set(position, -2459.0f, 2.0f, 2263.0f);
position[0] *= gCourseDirection;
rrxing = (struct RailroadCrossing*) &gActorList[add_actor_to_empty_slot(position, rotation, velocity,
ACTOR_RAILROAD_CROSSING)];
rrxing->crossingId = 0;
rrxing->crossingTrigger = crossing1;
vec3f_set(position, -2467.0f, 2.0f, 2375.0f);
position[0] *= gCourseDirection;
rrxing = (struct RailroadCrossing*) &gActorList[add_actor_to_empty_slot(position, rotation, velocity,
ACTOR_RAILROAD_CROSSING)];
rrxing->crossingId = 0;
rrxing->crossingTrigger = crossing1;
}
void KalimariDesert::Init() {}
@@ -165,14 +177,6 @@ void KalimariDesert::InitCourseObjects() {
}
}
void KalimariDesert::UpdateCourseObjects() {
update_train_smoke();
}
void KalimariDesert::RenderCourseObjects(s32 cameraId) {
render_object_trains_smoke_particles(cameraId);
}
void KalimariDesert::SomeSounds() {}
void KalimariDesert::WhatDoesThisDo(Player* player, int8_t playerId) {}
@@ -180,17 +184,13 @@ void KalimariDesert::WhatDoesThisDo(Player* player, int8_t playerId) {}
void KalimariDesert::WhatDoesThisDoAI(Player* player, int8_t playerId) {}
void KalimariDesert::SpawnBombKarts() {
World* world = GetWorld();
if (world) {
world->SpawnObject(std::make_unique<OBombKart>(140, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(165, 1, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(330, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(550, 1, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(595, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
}
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(140, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(165, 1, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(330, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(550, 1, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(595, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
}
// Positions the finishline on the minimap
@@ -202,71 +202,19 @@ void KalimariDesert::MinimapFinishlinePosition() {
void KalimariDesert::SetStaffGhost() {}
void KalimariDesert::SpawnVehicles() {
s16 trainCarYRot;
UNUSED Vec3f pad;
TrainCarStuff* tempLocomotive;
TrainCarStuff* tempTender;
TrainCarStuff* tempPassengerCar;
Vec3s trainCarRot;
VehicleStuff* tempBoxTruck;
VehicleStuff* tempSchoolBus;
VehicleStuff* tempTankerTruck;
VehicleStuff* tempCar;
PaddleBoatStuff* tempPaddleWheelBoat;
Vec3s paddleWheelBoatRot;
s32 loopIndex;
s32 loopIndex2;
f32 origXPos;
f32 origZPos;
generate_train_waypoints();
for (loopIndex = 0; loopIndex < NUM_TRAINS; loopIndex++) {
tempLocomotive = &gTrainList[loopIndex].locomotive;
origXPos = tempLocomotive->position[0];
origZPos = tempLocomotive->position[2];
trainCarYRot = update_vehicle_following_waypoint(
tempLocomotive->position, (s16*) &tempLocomotive->waypointIndex, gTrainList[loopIndex].speed);
tempLocomotive->velocity[0] = tempLocomotive->position[0] - origXPos;
tempLocomotive->velocity[2] = tempLocomotive->position[2] - origZPos;
vec3s_set(trainCarRot, 0, trainCarYRot, 0);
tempLocomotive->actorIndex = add_actor_to_empty_slot(tempLocomotive->position, trainCarRot,
tempLocomotive->velocity, ACTOR_TRAIN_ENGINE);
s32 numTrains = 2;
s32 centerWaypoint = 160;
tempTender = &gTrainList[loopIndex].tender;
if (tempTender->isActive == 1) {
origXPos = tempTender->position[0];
origZPos = tempTender->position[2];
trainCarYRot = update_vehicle_following_waypoint(
tempTender->position, (s16*) &tempTender->waypointIndex, gTrainList[loopIndex].speed);
tempTender->velocity[0] = tempTender->position[0] - origXPos;
tempTender->velocity[2] = tempTender->position[2] - origZPos;
vec3s_set(trainCarRot, 0, trainCarYRot, 0);
tempTender->actorIndex = add_actor_to_empty_slot(tempTender->position, trainCarRot,
tempTender->velocity, ACTOR_TRAIN_TENDER);
}
for (loopIndex2 = 0; loopIndex2 < NUM_PASSENGER_CAR_ENTRIES; loopIndex2++) {
tempPassengerCar = &gTrainList[loopIndex].passengerCars[loopIndex2];
if (tempPassengerCar->isActive == 1) {
origXPos = tempPassengerCar->position[0];
origZPos = tempPassengerCar->position[2];
trainCarYRot = update_vehicle_following_waypoint(tempPassengerCar->position,
(s16*) &tempPassengerCar->waypointIndex,
gTrainList[loopIndex].speed);
tempPassengerCar->velocity[0] = tempPassengerCar->position[0] - origXPos;
tempPassengerCar->velocity[2] = tempPassengerCar->position[2] - origZPos;
vec3s_set(trainCarRot, 0, trainCarYRot, 0);
tempPassengerCar->actorIndex =
add_actor_to_empty_slot(tempPassengerCar->position, trainCarRot, tempPassengerCar->velocity,
ACTOR_TRAIN_PASSENGER_CAR);
}
}
// Spawn two trains
for (size_t i = 0; i < numTrains; ++i) {
uint32_t waypoint = CalculateWaypointDistribution(i, numTrains, gVehicle2DWaypointLength, centerWaypoint);
gWorldInstance.AddTrain(5, 5.0f, waypoint);
}
}
void KalimariDesert::UpdateVehicles() {
update_vehicle_trains();
}
void KalimariDesert::BeginPlay() { }
void KalimariDesert::Render(struct UnkStruct_800DC5EC* arg0) {
func_802B5D64(D_800DC610, D_802B87D4, 0, 1);
@@ -308,7 +256,7 @@ void KalimariDesert::RenderCredits() {
void KalimariDesert::Collision() {}
void KalimariDesert::GenerateCollision() {
parse_course_displaylists(d_course_kalimari_desert_addr);
parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_kalimari_desert_addr));
func_80295C6C();
D_8015F8E4 = gCourseMinY - 10.0f;
}
-3
View File
@@ -29,8 +29,6 @@ public:
virtual void Init() 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;
@@ -40,7 +38,6 @@ public:
virtual void Render(struct UnkStruct_800DC5EC*) override;
virtual void RenderCredits() override;
virtual void SpawnVehicles() override;
virtual void UpdateVehicles() override;
virtual void Collision() override;
virtual void SpawnBombKarts() override;
virtual void GenerateCollision() override;
+21 -17
View File
@@ -28,6 +28,7 @@ extern "C" {
#include "staff_ghosts.h"
#include "actors.h"
#include "collision.h"
#include "code_8003DC40.h"
#include "memory.h"
extern const char *koopa_troopa_beach_dls[];
extern s8 gPlayerCount;
@@ -38,6 +39,9 @@ KoopaTroopaBeach::KoopaTroopaBeach() {
this->gfx = d_course_koopa_troopa_beach_packed_dls;
this->gfxSize = 5720;
this->textures = koopa_troopa_beach_textures;
Props.MinimapTexture = gTextureCourseOutlineKoopaTroopaBeach;
Props.D_800E5548[0] = 64;
Props.D_800E5548[1] = 64;
Props.Id = "mk:koopa_beach";
Props.Name = "koopa troopa beach";
@@ -74,13 +78,13 @@ KoopaTroopaBeach::KoopaTroopaBeach() {
Props.D_0D009808[2] = 5.75f;
Props.D_0D009808[3] = 6.3333334f;
Props.PathTable[0] = d_course_koopa_troopa_beach_unknown_waypoints;
Props.PathTable[0] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_koopa_troopa_beach_unknown_waypoints);
Props.PathTable[1] = NULL;
Props.PathTable[2] = NULL;
Props.PathTable[3] = NULL;
Props.PathTable2[0] = d_course_koopa_troopa_beach_track_waypoints;
Props.PathTable2[1] = d_course_koopa_troopa_beach_track_waypoints_2;
Props.PathTable2[0] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_koopa_troopa_beach_track_waypoints);
Props.PathTable2[1] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_koopa_troopa_beach_track_waypoints_2);
Props.PathTable2[2] = NULL;
Props.PathTable2[3] = NULL;
@@ -104,8 +108,8 @@ void KoopaTroopaBeach::LoadTextures() {
void KoopaTroopaBeach::SpawnActors() {
init_actor_hot_air_balloon_item_box(328.0f * gCourseDirection, 70.0f, 2541.0f);
spawn_all_item_boxes(d_course_koopa_troopa_beach_item_box_spawns);
spawn_palm_trees(d_course_koopa_troopa_beach_tree_spawn);
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));
}
void KoopaTroopaBeach::Init() {}
@@ -179,17 +183,13 @@ void KoopaTroopaBeach::WhatDoesThisDo(Player* player, int8_t playerId) {}
void KoopaTroopaBeach::WhatDoesThisDoAI(Player* player, int8_t playerId) {}
void KoopaTroopaBeach::SpawnBombKarts() {
World* world = GetWorld();
if (world) {
world->SpawnObject(std::make_unique<OBombKart>(140, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(165, 1, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(330, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(550, 1, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(595, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
}
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(140, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(165, 1, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(330, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(550, 1, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(595, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
}
// Positions the finishline on the minimap
@@ -235,8 +235,12 @@ void KoopaTroopaBeach::RenderCredits() {
void KoopaTroopaBeach::Collision() {}
void KoopaTroopaBeach::SomeCollisionThing(Player *player, Vec3f arg1, Vec3f arg2, Vec3f arg3, f32* arg4, f32* arg5, f32* arg6, f32* arg7) {
func_8003E37C(player, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
}
void KoopaTroopaBeach::GenerateCollision() {
parse_course_displaylists(d_course_koopa_troopa_beach_addr);
parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_koopa_troopa_beach_addr));
func_80295C6C();
find_vtx_and_set_colours(segmented_gfx_to_virtual(reinterpret_cast<void*>(0x0700ADE0)), -0x6A, 255, 255, 255);
find_vtx_and_set_colours(segmented_gfx_to_virtual(reinterpret_cast<void*>(0x0700A540)), -0x6A, 255, 255, 255);
+1
View File
@@ -40,6 +40,7 @@ public:
virtual void Render(struct UnkStruct_800DC5EC*) override;
virtual void RenderCredits() override;
virtual void Collision() override;
virtual void SomeCollisionThing(Player *player, Vec3f arg1, Vec3f arg2, Vec3f arg3, f32* arg4, f32* arg5, f32* arg6, f32* arg7) override;
virtual void SpawnBombKarts() override;
virtual void GenerateCollision() override;
virtual void Water() override;
+20 -16
View File
@@ -28,6 +28,7 @@ extern "C" {
#include "staff_ghosts.h"
#include "actors.h"
#include "collision.h"
#include "code_8003DC40.h"
#include "memory.h"
extern const char *luigi_raceway_dls[];
extern s16 currentScreenSection;
@@ -38,6 +39,9 @@ LuigiRaceway::LuigiRaceway() {
this->gfx = d_course_luigi_raceway_packed_dls;
this->gfxSize = 6377;
this->textures = luigi_raceway_textures;
Props.MinimapTexture = gTextureCourseOutlineLuigiRaceway;
Props.D_800E5548[0] = 64;
Props.D_800E5548[1] = 96;
Props.Id = "mk:luigi_raceway";
Props.Name = "luigi raceway";
@@ -74,12 +78,12 @@ LuigiRaceway::LuigiRaceway() {
Props.D_0D009808[2] = 5.75f;
Props.D_0D009808[3] = 6.3333334f;
Props.PathTable[0] = d_course_luigi_raceway_unknown_waypoints;
Props.PathTable[0] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_luigi_raceway_unknown_waypoints);
Props.PathTable[1] = NULL;
Props.PathTable[2] = NULL;
Props.PathTable[3] = NULL;
Props.PathTable2[0] = d_course_luigi_raceway_track_waypoints;
Props.PathTable2[0] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_luigi_raceway_track_waypoints);
Props.PathTable2[1] = NULL;
Props.PathTable2[2] = NULL;
Props.PathTable2[3] = NULL;
@@ -105,8 +109,8 @@ void LuigiRaceway::LoadTextures() {
}
void LuigiRaceway::SpawnActors() {
spawn_foliage(d_course_luigi_raceway_tree_spawn);
spawn_all_item_boxes(d_course_luigi_raceway_item_box_spawns);
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));
}
void LuigiRaceway::Init() {}
@@ -186,17 +190,13 @@ void LuigiRaceway::WhatDoesThisDoAI(Player* player, int8_t playerId) {
}
void LuigiRaceway::SpawnBombKarts() {
World* world = GetWorld();
if (world) {
world->SpawnObject(std::make_unique<OBombKart>(40, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(100, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(265, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(285, 1, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(420, 1, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
}
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(40, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(100, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(265, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(285, 1, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(420, 1, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
}
// Positions the finishline on the minimap
@@ -328,8 +328,12 @@ void LuigiRaceway::RenderCredits() {
void LuigiRaceway::Collision() {}
void LuigiRaceway::SomeCollisionThing(Player *player, Vec3f arg1, Vec3f arg2, Vec3f arg3, f32* arg4, f32* arg5, f32* arg6, f32* arg7) {
func_8003E9EC(player, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
}
void LuigiRaceway::GenerateCollision() {
parse_course_displaylists(d_course_luigi_raceway_addr);
parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_luigi_raceway_addr));
func_80295C6C();
D_8015F8E4 = gCourseMinY - 10.0f;
}
+2 -1
View File
@@ -38,8 +38,9 @@ public:
virtual void SetStaffGhost() override;
virtual void BeginPlay() override;
virtual void Render(struct UnkStruct_800DC5EC*) override;
virtual void RenderCredits() override;
virtual void RenderCredits() override;
virtual void Collision() override;
virtual void SomeCollisionThing(Player *player, Vec3f arg1, Vec3f arg2, Vec3f arg3, f32* arg4, f32* arg5, f32* arg6, f32* arg7) override;
virtual void SpawnBombKarts() override;
virtual void GenerateCollision() override;
virtual void Destroy() override;
+16 -17
View File
@@ -37,6 +37,9 @@ MarioRaceway::MarioRaceway() {
this->gfx = d_course_mario_raceway_packed_dls;
this->gfxSize = 3367;
this->textures = mario_raceway_textures;
Props.MinimapTexture = gTextureCourseOutlineMarioRaceway;
Props.D_800E5548[0] = 64;
Props.D_800E5548[1] = 64;
Props.Id = "mk:mario_raceway";
Props.Name = "Mario Raceway";
@@ -74,12 +77,12 @@ MarioRaceway::MarioRaceway() {
Props.D_0D009808[2] = 5.75f;
Props.D_0D009808[3] = 6.3333334f;
Props.PathTable[0] = d_course_mario_raceway_unknown_waypoints;
Props.PathTable[0] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_mario_raceway_unknown_waypoints);
Props.PathTable[1] = NULL;
Props.PathTable[2] = NULL;
Props.PathTable[3] = NULL;
Props.PathTable2[0] = d_course_mario_raceway_track_waypoints;
Props.PathTable2[0] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_mario_raceway_track_waypoints);
Props.PathTable2[1] = NULL;
Props.PathTable2[2] = NULL;
Props.PathTable2[3] = NULL;
@@ -117,9 +120,9 @@ void MarioRaceway::SpawnActors() {
Vec3f position;
Vec3f velocity = { 0.0f, 0.0f, 0.0f };
Vec3s rotation = { 0, 0, 0 };
spawn_foliage(d_course_mario_raceway_tree_spawns);
spawn_piranha_plants(d_course_mario_raceway_piranha_plant_spawns);
spawn_all_item_boxes(d_course_mario_raceway_item_box_spawns);
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));
vec3f_set(position, 150.0f, 40.0f, -1300.0f);
position[0] *= gCourseDirection;
add_actor_to_empty_slot(position, rotation, velocity, ACTOR_MARIO_SIGN);
@@ -192,17 +195,13 @@ void MarioRaceway::WhatDoesThisDoAI(Player* player, int8_t playerId) {
}
void MarioRaceway::SpawnBombKarts() {
World* world = GetWorld();
if (world) {
world->SpawnObject(std::make_unique<OBombKart>(40, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(100, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(265, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(285, 1, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(420, 1, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
}
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(40, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(100, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(265, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(285, 1, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(420, 1, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
}
// Positions the finishline on the minimap
@@ -346,7 +345,7 @@ void MarioRaceway::GenerateCollision() {
generate_collision_mesh_with_defaults(segmented_gfx_to_virtual(reinterpret_cast<void*>(0x07002D68)));
}
parse_course_displaylists(d_course_mario_raceway_addr);
parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_mario_raceway_addr));
func_80295C6C();
D_8015F8E4 = gCourseMinY - 10.0f;
}
+15 -16
View File
@@ -40,6 +40,9 @@ MooMooFarm::MooMooFarm() {
this->gfx = d_course_moo_moo_farm_packed_dls;
this->gfxSize = 3304;
this->textures = moo_moo_farm_textures;
Props.MinimapTexture = gTextureCourseOutlineMooMooFarm;
Props.D_800E5548[0] = 64;
Props.D_800E5548[1] = 64;
Props.Name = "moo moo farm";
Props.DebugName = "farm";
@@ -75,12 +78,12 @@ MooMooFarm::MooMooFarm() {
Props.D_0D009808[2] = 5.75f;
Props.D_0D009808[3] = 6.3333334f;
Props.PathTable[0] = d_course_moo_moo_farm_unknown_waypoints;
Props.PathTable[0] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_moo_moo_farm_unknown_waypoints);
Props.PathTable[1] = NULL;
Props.PathTable[2] = NULL;
Props.PathTable[3] = NULL;
Props.PathTable2[0] = d_course_moo_moo_farm_track_waypoints;
Props.PathTable2[0] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_moo_moo_farm_track_waypoints);
Props.PathTable2[1] = NULL;
Props.PathTable2[2] = NULL;
Props.PathTable2[3] = NULL;
@@ -117,9 +120,9 @@ void MooMooFarm::LoadTextures() {
void MooMooFarm::SpawnActors() {
if (gPlayerCountSelection1 != 4) {
spawn_foliage(d_course_moo_moo_farm_tree_spawn);
spawn_foliage((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_moo_moo_farm_tree_spawn));
}
spawn_all_item_boxes(d_course_moo_moo_farm_item_box_spawns);
spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_moo_moo_farm_item_box_spawns));
}
void MooMooFarm::Init() {}
@@ -237,17 +240,13 @@ void MooMooFarm::WhatDoesThisDoAI(Player* player, int8_t playerId) {
}
void MooMooFarm::SpawnBombKarts() {
World* world = GetWorld();
if (world) {
world->SpawnObject(std::make_unique<OBombKart>(40, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(100, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(265, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(285, 1, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(420, 1, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
}
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(40, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(100, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(265, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(285, 1, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(420, 1, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
}
// Positions the finishline on the minimap
@@ -340,7 +339,7 @@ void MooMooFarm::RenderCredits() {
void MooMooFarm::Collision() {}
void MooMooFarm::GenerateCollision() {
parse_course_displaylists(d_course_moo_moo_farm_addr);
parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_moo_moo_farm_addr));
func_80295C6C();
D_8015F8E4 = gCourseMinY - 10.0f;
}
+15 -17
View File
@@ -37,6 +37,8 @@ PodiumCeremony::PodiumCeremony() {
this->gfx = d_course_royal_raceway_packed_dls;
this->gfxSize = 5670;
this->textures = royal_raceway_textures;
Props.D_800E5548[0] = 0;
Props.D_800E5548[1] = 0;
Props.Name = "royal raceway";
Props.DebugName = "p circuit";
@@ -69,12 +71,12 @@ PodiumCeremony::PodiumCeremony() {
Props.D_0D009808[2] = 5.75f;
Props.D_0D009808[3] = 6.3333334f;
Props.PathTable[0] = d_course_royal_raceway_unknown_waypoints;
Props.PathTable[0] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_royal_raceway_unknown_waypoints);
Props.PathTable[1] = NULL;
Props.PathTable[2] = NULL;
Props.PathTable[3] = NULL;
Props.PathTable2[0] = d_course_royal_raceway_track_waypoints;
Props.PathTable2[0] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_royal_raceway_track_waypoints);
Props.PathTable2[1] = NULL;
Props.PathTable2[2] = NULL;
Props.PathTable2[3] = NULL;
@@ -98,9 +100,9 @@ void PodiumCeremony::LoadTextures() {
}
void PodiumCeremony::SpawnActors() {
spawn_foliage(d_course_royal_raceway_tree_spawn);
spawn_all_item_boxes(d_course_royal_raceway_item_box_spawns);
spawn_piranha_plants(d_course_royal_raceway_piranha_plant_spawn);
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));
}
void PodiumCeremony::Init() { }
@@ -164,17 +166,13 @@ void PodiumCeremony::WhatDoesThisDoAI(Player* player, int8_t playerId) {
}
void PodiumCeremony::SpawnBombKarts() {
World* world = GetWorld();
if (world) {
world->SpawnObject(std::make_unique<OBombKart>(40, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(100, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(265, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(285, 1, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(420, 1, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
}
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(40, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(100, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(265, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(285, 1, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(420, 1, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
}
// Positions the finishline on the minimap
@@ -233,7 +231,7 @@ void PodiumCeremony::RenderCredits() {
void PodiumCeremony::Collision() {}
void PodiumCeremony::GenerateCollision() {
parse_course_displaylists(d_course_royal_raceway_addr);
parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_royal_raceway_addr));
func_80295C6C();
D_8015F8E4 = -60.0f;
}
+14 -15
View File
@@ -37,6 +37,9 @@ RainbowRoad::RainbowRoad() {
this->gfx = d_course_rainbow_road_packed_dls;
this->gfxSize = 5670;
this->textures = rainbow_road_textures;
Props.MinimapTexture = gTextureCourseOutlineRainbowRoad;
Props.D_800E5548[0] = 64;
Props.D_800E5548[1] = 96;
Props.Name = "rainbow road";
Props.DebugName = "rainbow";
@@ -72,12 +75,12 @@ RainbowRoad::RainbowRoad() {
Props.D_0D009808[2] = 5.75f;
Props.D_0D009808[3] = 6.3333334f;
Props.PathTable[0] = d_course_rainbow_road_unknown_waypoints;
Props.PathTable[0] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_rainbow_road_unknown_waypoints);
Props.PathTable[1] = NULL;
Props.PathTable[2] = NULL;
Props.PathTable[3] = NULL;
Props.PathTable2[0] = d_course_rainbow_road_track_waypoints;
Props.PathTable2[0] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_rainbow_road_track_waypoints);
Props.PathTable2[1] = NULL;
Props.PathTable2[2] = NULL;
Props.PathTable2[3] = NULL;
@@ -101,7 +104,7 @@ void RainbowRoad::LoadTextures() {
}
void RainbowRoad::SpawnActors() {
spawn_all_item_boxes(d_course_rainbow_road_item_box_spawns);
spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_rainbow_road_item_box_spawns));
}
void RainbowRoad::Init() {}
@@ -157,17 +160,13 @@ void RainbowRoad::WhatDoesThisDo(Player* player, int8_t playerId) {}
void RainbowRoad::WhatDoesThisDoAI(Player* player, int8_t playerId) {}
void RainbowRoad::SpawnBombKarts() {
World* world = GetWorld();
if (world) {
world->SpawnObject(std::make_unique<OBombKart>(40, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(100, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(265, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(285, 1, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(420, 1, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
}
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(40, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(100, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(265, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(285, 1, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(420, 1, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
}
// Positions the finishline on the minimap
@@ -195,7 +194,7 @@ void RainbowRoad::Collision() {}
void RainbowRoad::GenerateCollision() {
D_800DC5C8 = 1;
parse_course_displaylists(d_course_rainbow_road_addr);
parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_rainbow_road_addr));
func_80295C6C();
D_8015F8E4 = 0.0f;
// d_course_rainbow_road_packed_dl_2068
+16 -17
View File
@@ -37,6 +37,9 @@ RoyalRaceway::RoyalRaceway() {
this->gfx = d_course_royal_raceway_packed_dls;
this->gfxSize = 5670;
this->textures = royal_raceway_textures;
Props.MinimapTexture = gTextureCourseOutlineRoyalRaceway;
Props.D_800E5548[0] = 64;
Props.D_800E5548[1] = 64;
Props.Name = "royal raceway";
Props.DebugName = "p circuit";
@@ -72,12 +75,12 @@ RoyalRaceway::RoyalRaceway() {
Props.D_0D009808[2] = 5.75f;
Props.D_0D009808[3] = 6.3333334f;
Props.PathTable[0] = d_course_royal_raceway_unknown_waypoints;
Props.PathTable[0] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_royal_raceway_unknown_waypoints);
Props.PathTable[1] = NULL;
Props.PathTable[2] = NULL;
Props.PathTable[3] = NULL;
Props.PathTable2[0] = d_course_royal_raceway_track_waypoints;
Props.PathTable2[0] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_royal_raceway_track_waypoints);
Props.PathTable2[1] = NULL;
Props.PathTable2[2] = NULL;
Props.PathTable2[3] = NULL;
@@ -112,9 +115,9 @@ void RoyalRaceway::LoadTextures() {
}
void RoyalRaceway::SpawnActors() {
spawn_foliage(d_course_royal_raceway_tree_spawn);
spawn_all_item_boxes(d_course_royal_raceway_item_box_spawns);
spawn_piranha_plants(d_course_royal_raceway_piranha_plant_spawn);
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));
}
void RoyalRaceway::Init() {}
@@ -178,17 +181,13 @@ void RoyalRaceway::WhatDoesThisDoAI(Player* player, int8_t playerId) {
}
void RoyalRaceway::SpawnBombKarts() {
World* world = GetWorld();
if (world) {
world->SpawnObject(std::make_unique<OBombKart>(40, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(100, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(265, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(285, 1, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(420, 1, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
}
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(40, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(100, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(265, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(285, 1, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(420, 1, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
}
// Positions the finishline on the minimap
@@ -247,7 +246,7 @@ void RoyalRaceway::RenderCredits() {
void RoyalRaceway::Collision() {}
void RoyalRaceway::GenerateCollision() {
parse_course_displaylists(d_course_royal_raceway_addr);
parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_royal_raceway_addr));
func_80295C6C();
D_8015F8E4 = -60.0f;
}
+14 -15
View File
@@ -37,6 +37,9 @@ SherbetLand::SherbetLand() {
this->gfx = d_course_sherbet_land_packed_dls;
this->gfxSize = 1803;
this->textures = sherbet_land_textures;
Props.MinimapTexture = gTextureCourseOutlineSherbetLand;
Props.D_800E5548[0] = 64;
Props.D_800E5548[1] = 64;
Props.Name = "sherbet land";
Props.DebugName = "sherbet";
@@ -72,12 +75,12 @@ SherbetLand::SherbetLand() {
Props.D_0D009808[2] = 5.75f;
Props.D_0D009808[3] = 6.3333334f;
Props.PathTable[0] = d_course_sherbet_land_unknown_waypoints;
Props.PathTable[0] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_sherbet_land_unknown_waypoints);
Props.PathTable[1] = NULL;
Props.PathTable[2] = NULL;
Props.PathTable[3] = NULL;
Props.PathTable2[0] = d_course_sherbet_land_track_waypoints;
Props.PathTable2[0] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_sherbet_land_track_waypoints);
Props.PathTable2[1] = NULL;
Props.PathTable2[2] = NULL;
Props.PathTable2[3] = NULL;
@@ -101,7 +104,7 @@ void SherbetLand::LoadTextures() {
}
void SherbetLand::SpawnActors() {
spawn_all_item_boxes(d_course_sherbet_land_item_box_spawns);
spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_sherbet_land_item_box_spawns));
}
void SherbetLand::Init() {}
@@ -146,17 +149,13 @@ void SherbetLand::WhatDoesThisDo(Player* player, int8_t playerId) {}
void SherbetLand::WhatDoesThisDoAI(Player* player, int8_t playerId) {}
void SherbetLand::SpawnBombKarts() {
World* world = GetWorld();
if (world) {
world->SpawnObject(std::make_unique<OBombKart>(40, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(100, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(265, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(285, 1, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(420, 1, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
}
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(40, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(100, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(265, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(285, 1, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(420, 1, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
}
// Positions the finishline on the minimap
@@ -184,7 +183,7 @@ void SherbetLand::RenderCredits() {
void SherbetLand::Collision() {}
void SherbetLand::GenerateCollision() {
parse_course_displaylists(d_course_sherbet_land_addr);
parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_sherbet_land_addr));
func_80295C6C();
D_8015F8E4 = -18.0f;
// d_course_sherbet_land_packed_dl_1EB8
+3
View File
@@ -38,6 +38,9 @@ Skyscraper::Skyscraper() {
this->gfx = d_course_skyscraper_packed_dls;
this->gfxSize = 548;
this->textures = skyscraper_textures;
Props.MinimapTexture = gTextureCourseOutlineSkyscraper;
Props.D_800E5548[0] = 64;
Props.D_800E5548[1] = 64;
Props.Name = "skyscraper";
Props.DebugName = "skyscraper";
+103 -18
View File
@@ -44,6 +44,7 @@ extern "C" {
TestCourse::TestCourse() {
this->gfxSize = 100;
this->textures = NULL;
Props.MinimapTexture = gTextureCourseOutlineMarioRaceway;
Props.Id = "mk:test_course";
Props.Name = "Test Course";
@@ -59,7 +60,7 @@ TestCourse::TestCourse() {
Props.NearPersp = 9.0f;
Props.FarPersp = 4500.0f;
Props.PathSizes = {52, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0};
Props.PathSizes = {51, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0};
Props.D_0D009418[0] = 4.1666665f;
Props.D_0D009418[1] = 5.5833334f;
@@ -81,12 +82,12 @@ TestCourse::TestCourse() {
Props.D_0D009808[2] = 5.75f;
Props.D_0D009808[3] = 6.3333334f;
//Props.PathTable[0] = test_course_path;
Props.PathTable[0] = test_course_path;
Props.PathTable[1] = NULL;
Props.PathTable[2] = NULL;
Props.PathTable[3] = NULL;
//Props.PathTable2[0] = test_course_path;
Props.PathTable2[0] = test_course_path;
Props.PathTable2[1] = NULL;
Props.PathTable2[2] = NULL;
Props.PathTable2[3] = NULL;
@@ -126,6 +127,9 @@ void TestCourse::LoadTextures() {
void TestCourse::SpawnActors() {
struct ActorSpawnData itemboxes[] = {
{ 200, 1500, 200 , 0},
{ 350, 2500, 300 , 1},
{ 400, 2000, 350 , 2},
{ 40, 0, -800, 0},
{ -40, 0, -800, 0},
{ 0, 0, -800, 0},
@@ -138,13 +142,27 @@ struct ActorSpawnData itemboxes[] = {
};
struct ActorSpawnData rocks[] = {
{{ 200, 3000, 200 }, {0}},
{{ 200, 1500, 200 }, {0}},
{{ 350, 2500, 300 }, {1}},
{{ 400, 2000, 350 }, {2}},
{{ -32768, 0, 0 }, {0}},
};
spawn_all_item_boxes((const char*)itemboxes);
spawn_falling_rocks((const char*)rocks);
spawn_all_item_boxes(itemboxes);
spawn_falling_rocks(rocks);
struct RailroadCrossing* rrxing;
Vec3f position;
Vec3f velocity = { 0.0f, 0.0f, 0.0f };
Vec3s rotation = { 0, 0, 0 };
vec3f_set(position, 50.0f, 2.0f, 50.0f);
Vec3f crossingPos = {0, 2, 0};
uintptr_t* crossing1 = (uintptr_t*) gWorldInstance.AddCrossing(crossingPos, 0, 2, 900.0f, 650.0f);
position[0] *= gCourseDirection;
rrxing = (struct RailroadCrossing*) &gActorList[add_actor_to_empty_slot(position, rotation, velocity,
ACTOR_RAILROAD_CROSSING)];
rrxing->crossingTrigger = crossing1;
}
void TestCourse::Init() {}
@@ -162,6 +180,77 @@ 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(5, 5.0f, 0);
gWorldInstance.AddTrain(5, 5.0f, 8);
}
void TestCourse::UpdateVehicles() {
update_vehicle_trains();
}
void TestCourse::InitCourseObjects() {}
void TestCourse::SomeSounds() {}
@@ -197,17 +286,13 @@ void TestCourse::WhatDoesThisDoAI(Player* player, int8_t playerId) {
}
void TestCourse::SpawnBombKarts() {
World* world = GetWorld();
if (world) {
world->SpawnObject(std::make_unique<OBombKart>(40, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(100, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(265, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(285, 1, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(420, 1, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
}
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(40, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(100, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(265, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(285, 1, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(420, 1, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
}
// Positions the finishline on the minimap
@@ -242,7 +327,7 @@ void TestCourse::Collision() {}
void TestCourse::GenerateCollision() {
generate_collision_mesh_with_defaults(mario_Plane_001_mesh);
parse_course_displaylists((const char*)test_course_addr);
parse_course_displaylists((TrackSectionsI*)test_course_addr);
func_80295C6C();
D_8015F8E4 = gCourseMinY - 10.0f;
}
+2
View File
@@ -39,6 +39,8 @@ 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 SpawnBombKarts() override;
virtual void GenerateCollision() override;
virtual void Destroy() override;
+60 -70
View File
@@ -9,6 +9,8 @@
#include "BombKart.h"
#include "assets/toads_turnpike_data.h"
#include "engine/vehicles/Utils.h"
extern "C" {
#include "main.h"
#include "camera.h"
@@ -40,6 +42,9 @@ ToadsTurnpike::ToadsTurnpike() {
this->gfx = d_course_toads_turnpike_packed_dls;
this->gfxSize = 3427;
this->textures = toads_turnpike_textures;
Props.MinimapTexture = gTextureCourseOutlineToadsTurnpike;
Props.D_800E5548[0] = 128;
Props.D_800E5548[1] = 64;
Props.Name = "toad's turnpike";
Props.DebugName = "highway";
@@ -53,7 +58,7 @@ ToadsTurnpike::ToadsTurnpike() {
Props.NearPersp = 9.0f;
Props.FarPersp = 4500.0f;
Props.PathSizes = {0x3E8, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0};
Props.PathSizes = {1000, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0};
Props.D_0D009418[0] = 4.1666665f;
Props.D_0D009418[1] = 5.5833334f;
@@ -75,12 +80,12 @@ ToadsTurnpike::ToadsTurnpike() {
Props.D_0D009808[2] = 5.75f;
Props.D_0D009808[3] = 6.3333334f;
Props.PathTable[0] = d_course_toads_turnpike_unknown_waypoints;
Props.PathTable[0] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_toads_turnpike_unknown_waypoints);
Props.PathTable[1] = NULL;
Props.PathTable[2] = NULL;
Props.PathTable[3] = NULL;
Props.PathTable2[0] = d_course_toads_turnpike_track_waypoints;
Props.PathTable2[0] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_toads_turnpike_track_waypoints);
Props.PathTable2[1] = NULL;
Props.PathTable2[2] = NULL;
Props.PathTable2[3] = NULL;
@@ -104,14 +109,7 @@ void ToadsTurnpike::LoadTextures() {
}
void ToadsTurnpike::SpawnActors() {
D_801625EC = 43;
D_801625F4 = 13;
D_801625F0 = 4;
D_802B87B0 = 993;
D_802B87B4 = 1000;
parse_course_displaylists(d_course_toads_turnpike_addr);
func_80295C6C();
D_8015F8E4 = gCourseMinY - 10.0f;
spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_toads_turnpike_item_box_spawns));
}
void ToadsTurnpike::Init() {}
@@ -162,17 +160,13 @@ void ToadsTurnpike::WhatDoesThisDoAI(Player* player, int8_t playerId) {
}
void ToadsTurnpike::SpawnBombKarts() {
World* world = GetWorld();
if (world) {
world->SpawnObject(std::make_unique<OBombKart>(40, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(100, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(265, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(285, 1, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(420, 1, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
}
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(40, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(100, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(265, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(285, 1, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(420, 1, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
}
// Positions the finishline on the minimap
@@ -218,55 +212,51 @@ void ToadsTurnpike::RenderCredits() {
void ToadsTurnpike::Collision() {}
void ToadsTurnpike::SpawnVehicles() {
s16 trainCarYRot;
UNUSED Vec3f pad;
TrainCarStuff* tempLocomotive;
TrainCarStuff* tempTender;
TrainCarStuff* tempPassengerCar;
Vec3s trainCarRot;
VehicleStuff* tempBoxTruck;
VehicleStuff* tempSchoolBus;
VehicleStuff* tempTankerTruck;
VehicleStuff* tempCar;
PaddleBoatStuff* tempPaddleWheelBoat;
Vec3s paddleWheelBoatRot;
s32 loopIndex;
s32 loopIndex2;
f32 origXPos;
f32 origZPos;
f32 a = ((gCCSelection * 90.0) / 216.0f) + 4.583333333333333;
f32 b = ((gCCSelection * 90.0) / 216.0f) + 2.9166666666666665;
uint32_t waypoint;
for (loopIndex = 0; loopIndex < NUM_RACE_BOX_TRUCKS; loopIndex++) {
tempBoxTruck = &gBoxTruckList[loopIndex];
spawn_vehicle_on_road(tempBoxTruck);
tempBoxTruck->actorIndex = add_actor_to_empty_slot(tempBoxTruck->position, tempBoxTruck->rotation,
tempBoxTruck->velocity, ACTOR_BOX_TRUCK);
}
for (loopIndex = 0; loopIndex < NUM_RACE_SCHOOL_BUSES; loopIndex++) {
tempSchoolBus = &gSchoolBusList[loopIndex];
spawn_vehicle_on_road(tempSchoolBus);
tempSchoolBus->actorIndex = add_actor_to_empty_slot(tempSchoolBus->position, tempSchoolBus->rotation,
tempSchoolBus->velocity, ACTOR_SCHOOL_BUS);
}
for (loopIndex = 0; loopIndex < NUM_RACE_TANKER_TRUCKS; loopIndex++) {
tempTankerTruck = &gTankerTruckList[loopIndex];
spawn_vehicle_on_road(tempTankerTruck);
tempTankerTruck->actorIndex =
add_actor_to_empty_slot(tempTankerTruck->position, tempTankerTruck->rotation,
tempTankerTruck->velocity, ACTOR_TANKER_TRUCK);
}
for (loopIndex = 0; loopIndex < NUM_RACE_CARS; loopIndex++) {
tempCar = &gCarList[loopIndex];
spawn_vehicle_on_road(tempCar);
tempCar->actorIndex =
add_actor_to_empty_slot(tempCar->position, tempCar->rotation, tempCar->velocity, ACTOR_CAR);
}
}
if (gModeSelection == TIME_TRIALS) {
for (size_t i = 0; i < NUM_TIME_TRIAL_BOX_TRUCKS; i++) {
waypoint = CalculateWaypointDistribution(i, NUM_TIME_TRIAL_BOX_TRUCKS, gWaypointCountByPathIndex[0], 0);
gWorldInstance.AddTruck(a, b, &D_80164550[0][0], waypoint);
}
void ToadsTurnpike::UpdateVehicles() {
update_vehicle_box_trucks();
update_vehicle_school_bus();
update_vehicle_tanker_trucks();
update_vehicle_cars();
for (size_t i = 0; i < NUM_TIME_TRIAL_SCHOOL_BUSES; i++) {
waypoint = CalculateWaypointDistribution(i, NUM_TIME_TRIAL_SCHOOL_BUSES, gWaypointCountByPathIndex[0], 75);
gWorldInstance.AddBus(a, b, &D_80164550[0][0], waypoint);
}
for (size_t i = 0; i < NUM_TIME_TRIAL_TANKER_TRUCKS; i++) {
waypoint = CalculateWaypointDistribution(i, NUM_TIME_TRIAL_TANKER_TRUCKS, gWaypointCountByPathIndex[0], 50);
gWorldInstance.AddTankerTruck(a, b, &D_80164550[0][0], waypoint);
}
for (size_t i = 0; i < NUM_TIME_TRIAL_CARS; i++) {
waypoint = CalculateWaypointDistribution(i, NUM_TIME_TRIAL_CARS, gWaypointCountByPathIndex[0], 25);
gWorldInstance.AddCar(a, b, &D_80164550[0][0], waypoint);
}
} else { // All other modes
for (size_t i = 0; i < NUM_RACE_BOX_TRUCKS; i++) {
uint32_t waypoint = CalculateWaypointDistribution(i, NUM_RACE_BOX_TRUCKS, gWaypointCountByPathIndex[0], 0);
gWorldInstance.AddTruck(a, b, &D_80164550[0][0], waypoint);
}
for (size_t i = 0; i < NUM_RACE_SCHOOL_BUSES; i++) {
waypoint = CalculateWaypointDistribution(i, NUM_RACE_SCHOOL_BUSES, gWaypointCountByPathIndex[0], 75);
gWorldInstance.AddBus(a, b,&D_80164550[0][0], waypoint);
}
for (size_t i = 0; i < NUM_RACE_TANKER_TRUCKS; i++) {
waypoint = CalculateWaypointDistribution(i, NUM_RACE_TANKER_TRUCKS, gWaypointCountByPathIndex[0], 50);
gWorldInstance.AddTankerTruck(a, b, &D_80164550[0][0], waypoint);
}
for (size_t i = 0; i < NUM_RACE_CARS; i++) {
waypoint = CalculateWaypointDistribution(i, NUM_RACE_CARS, gWaypointCountByPathIndex[0], 25);
gWorldInstance.AddCar(a, b, &D_80164550[0][0], waypoint);
}
}
}
void ToadsTurnpike::GenerateCollision() {
@@ -275,7 +265,7 @@ void ToadsTurnpike::GenerateCollision() {
D_801625F0 = 4;
D_802B87B0 = 993;
D_802B87B4 = 1000;
parse_course_displaylists(d_course_toads_turnpike_addr);
parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_toads_turnpike_addr));
func_80295C6C();
D_8015F8E4 = gCourseMinY - 10.0f;
}
-1
View File
@@ -40,7 +40,6 @@ public:
virtual void RenderCredits() override;
virtual void Collision() override;
virtual void SpawnVehicles() override;
virtual void UpdateVehicles() override;
virtual void SpawnBombKarts() override;
virtual void GenerateCollision() override;
virtual void Destroy() override;
+19 -15
View File
@@ -28,6 +28,7 @@ extern "C" {
#include "staff_ghosts.h"
#include "actors.h"
#include "collision.h"
#include "code_8003DC40.h"
#include "memory.h"
extern const char *wario_stadium_dls[];
extern s16 currentScreenSection;
@@ -38,6 +39,9 @@ WarioStadium::WarioStadium() {
this->gfx = d_course_wario_stadium_packed_dls;
this->gfxSize = 5272;
this->textures = wario_stadium_textures;
Props.MinimapTexture = gTextureCourseOutlineWarioStadium;
Props.D_800E5548[0] = 64;
Props.D_800E5548[1] = 64;
Props.Name = "wario stadium";
Props.DebugName = "stadium";
@@ -73,12 +77,12 @@ WarioStadium::WarioStadium() {
Props.D_0D009808[2] = 5.75f;
Props.D_0D009808[3] = 6.3333334f;
Props.PathTable[0] = d_course_wario_stadium_unknown_waypoints;
Props.PathTable[0] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_wario_stadium_unknown_waypoints);
Props.PathTable[1] = NULL;
Props.PathTable[2] = NULL;
Props.PathTable[3] = NULL;
Props.PathTable2[0] = d_course_wario_stadium_track_waypoints;
Props.PathTable2[0] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_wario_stadium_track_waypoints);
Props.PathTable2[1] = NULL;
Props.PathTable2[2] = NULL;
Props.PathTable2[3] = NULL;
@@ -106,7 +110,7 @@ void WarioStadium::SpawnActors() {
Vec3f velocity = { 0.0f, 0.0f, 0.0f };
Vec3s rotation = { 0, 0, 0 };
spawn_all_item_boxes(d_course_wario_stadium_item_box_spawns);
spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_wario_stadium_item_box_spawns));
vec3f_set(position, -131.0f, 83.0f, 286.0f);
position[0] *= gCourseDirection;
add_actor_to_empty_slot(position, rotation, velocity, ACTOR_WARIO_SIGN);
@@ -153,17 +157,13 @@ void WarioStadium::WhatDoesThisDo(Player* player, int8_t playerId) {}
void WarioStadium::WhatDoesThisDoAI(Player* player, int8_t playerId) {}
void WarioStadium::SpawnBombKarts() {
World* world = GetWorld();
if (world) {
world->SpawnObject(std::make_unique<OBombKart>(40, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(100, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(265, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(285, 1, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(420, 1, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
}
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(40, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(100, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(265, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(285, 1, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(420, 1, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
}
// Positions the finishline on the minimap
@@ -269,8 +269,12 @@ void WarioStadium::RenderCredits() {
void WarioStadium::Collision() {}
void WarioStadium::SomeCollisionThing(Player *player, Vec3f arg1, Vec3f arg2, Vec3f arg3, f32* arg4, f32* arg5, f32* arg6, f32* arg7) {
func_8003EE2C(player, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
}
void WarioStadium::GenerateCollision() {
parse_course_displaylists(d_course_wario_stadium_addr);
parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_wario_stadium_addr));
func_80295C6C();
D_8015F8E4 = gCourseMinY - 10.0f;
// d_course_wario_stadium_packed_dl_C50
+1
View File
@@ -40,6 +40,7 @@ public:
virtual void Render(struct UnkStruct_800DC5EC*) override;
virtual void RenderCredits() override;
virtual void Collision() override;
virtual void SomeCollisionThing(Player *player, Vec3f arg1, Vec3f arg2, Vec3f arg3, f32* arg4, f32* arg5, f32* arg6, f32* arg7) override;
virtual void SpawnBombKarts() override;
virtual void GenerateCollision() override;
virtual void Destroy() override;
+21 -22
View File
@@ -38,6 +38,9 @@ YoshiValley::YoshiValley() {
this->gfx = d_course_yoshi_valley_packed_dls;
this->gfxSize = 4140;
this->textures = yoshi_valley_textures;
Props.MinimapTexture = gTextureCourseOutlineYoshiValley;
Props.D_800E5548[0] = 64;
Props.D_800E5548[1] = 64;
Props.Name = "yoshi valley";
Props.DebugName = "maze";
@@ -73,15 +76,15 @@ YoshiValley::YoshiValley() {
Props.D_0D009808[2] = 5.75f;
Props.D_0D009808[3] = 6.3333334f;
Props.PathTable[0] = d_course_yoshi_valley_unknown_waypoints;
Props.PathTable[1] = d_course_yoshi_valley_unknown_waypoints_2;
Props.PathTable[2] = d_course_yoshi_valley_unknown_waypoints_3;
Props.PathTable[3] = d_course_yoshi_valley_unknown_waypoints_4;
Props.PathTable[0] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_yoshi_valley_unknown_waypoints);
Props.PathTable[1] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_yoshi_valley_unknown_waypoints_2);
Props.PathTable[2] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_yoshi_valley_unknown_waypoints_3);
Props.PathTable[3] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_yoshi_valley_unknown_waypoints_4);
Props.PathTable2[0] = d_course_yoshi_valley_track_waypoints;
Props.PathTable2[1] = d_course_yoshi_valley_track_waypoints_2;
Props.PathTable2[2] = d_course_yoshi_valley_track_waypoints_3;
Props.PathTable2[3] = d_course_yoshi_valley_track_waypoints_4;
Props.PathTable2[0] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_yoshi_valley_track_waypoints);
Props.PathTable2[1] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_yoshi_valley_track_waypoints_2);
Props.PathTable2[2] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_yoshi_valley_track_waypoints_3);
Props.PathTable2[3] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_yoshi_valley_track_waypoints_4);
Props.Clouds = gYoshiValleyMooMooFarmClouds;
Props.CloudList = gYoshiValleyMooMooFarmClouds;
@@ -107,8 +110,8 @@ void YoshiValley::SpawnActors() {
Vec3f velocity = { 0.0f, 0.0f, 0.0f };
Vec3s rotation = { 0, 0, 0 };
spawn_foliage(d_course_yoshi_valley_tree_spawn);
spawn_all_item_boxes(d_course_yoshi_valley_item_box_spawns);
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);
position[0] *= gCourseDirection;
add_actor_to_empty_slot(position, rotation, velocity, ACTOR_YOSHI_EGG);
@@ -168,17 +171,13 @@ void YoshiValley::WhatDoesThisDo(Player* player, int8_t playerId) {}
void YoshiValley::WhatDoesThisDoAI(Player* player, int8_t playerId) {}
void YoshiValley::SpawnBombKarts() {
World* world = GetWorld();
if (world) {
world->SpawnObject(std::make_unique<OBombKart>(140, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(165, 1, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(330, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(550, 1, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(595, 3, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
world->SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
}
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(140, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(165, 1, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(330, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(550, 1, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(595, 3, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
gWorldInstance.SpawnObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0));
}
// Positions the finishline on the minimap
@@ -210,7 +209,7 @@ void YoshiValley::Collision() {}
void YoshiValley::GenerateCollision() {
Lights1 lights4 = gdSPDefLights1(100, 100, 100, 255, 254, 254, 0, 0, 120);
func_802B5D64(&lights4, -0x38F0, 0x1C70, 1);
parse_course_displaylists(d_course_yoshi_valley_addr);
parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_yoshi_valley_addr));
func_80295C6C();
D_8015F8E4 = gCourseMinY - 10.0f;
}
+198
View File
@@ -0,0 +1,198 @@
#include <libultraship.h>
#include "Boat.h"
#include <vector>
extern "C" {
#include "macros.h"
#include "main.h"
#include "defines.h"
#include "code_80005FD0.h"
#include "actors.h"
#include "math_util.h"
#include "sounds.h"
#include "update_objects.h"
extern s8 gPlayerCount;
}
ABoat::ABoat(size_t idx, f32 speed, u32 waypoint) {
Path2D* temp_a2;
u16 waypointOffset;
Index = idx;
Speed = speed;
// Set to the default value
std::fill(SmokeParticles, SmokeParticles + 128, NULL_OBJECT_ID);
waypointOffset = waypoint;
temp_a2 = &gVehicle2DWaypoint[waypointOffset];
Position[0] = temp_a2->x;
Position[1] = D_80162EB2;
Position[2] = temp_a2->z;
WaypointIndex = Index * 0xB4;
ActorIndex = -1;
if (gPlayerCount >= 3) {
IsActive = 0;
} else {
IsActive = 1;
}
Velocity[0] = 0.0f;
Velocity[1] = 0.0f;
Velocity[2] = 0.0f;
}
void ABoat::Spawn() {
Vec3s paddleWheelBoatRot;
if (IsActive == 1) {
f32 origXPos = Position[0];
f32 origZPos = Position[2];
RotY = update_vehicle_following_waypoint(
Position, (s16*) &WaypointIndex,
Speed);
Velocity[0] = Position[0] - origXPos;
Velocity[2] = Position[2] - origZPos;
vec3s_set(paddleWheelBoatRot, 0, RotY, 0);
ActorIndex = add_actor_to_empty_slot(Position, paddleWheelBoatRot,
Velocity, ACTOR_PADDLE_BOAT);
}
}
void ABoat::BeginPlay() {}
void ABoat::Draw(s32 playerId) {}
void ABoat::Tick() {
Path2D* waypoint;
struct Actor* paddleBoatActor;
f32 temp_f26;
f32 temp_f28;
f32 temp_f30;
s16 temp_a1;
s32 temp;
s16 var_v1;
Vec3f sp94;
Vec3f sp88;
UNUSED s32 pad;
Vec3f smokePos;
UNUSED s32 pad2;
AnotherSmokeTimer += 1;
if (IsActive == 1) {
temp_f26 = Position[0];
temp_f28 = Position[1];
temp_f30 = Position[2];
update_vehicle_following_waypoint(Position, (s16*) &WaypointIndex,
Speed);
SomeFlags = set_vehicle_render_distance_flags(Position, BOAT_SMOKE_RENDER_DISTANCE,
SomeFlags);
if ((((s16) AnotherSmokeTimer % 10) == 0) && (SomeFlags != 0)) {
smokePos[0] = (f32) ((f64) Position[0] - 30.0);
smokePos[1] = (f32) ((f64) Position[1] + 180.0);
smokePos[2] = (f32) ((f64) Position[2] + 45.0);
adjust_position_by_angle(smokePos, Position, RotY);
//spawn_ferry_smoke(Index, smokePos, 1.1f);
AddSmoke(Index, smokePos, 1.1f);
smokePos[0] = (f32) ((f64) Position[0] + 30.0);
smokePos[1] = (f32) ((f64) Position[1] + 180.0);
smokePos[2] = (f32) ((f64) Position[2] + 45.0);
adjust_position_by_angle(smokePos, Position, RotY);
//spawn_ferry_smoke(Index, smokePos, 1.1f);
AddSmoke(Index, smokePos, 1.1f);
}
if (random_int(100) == 0) {
if (random_int(2) == 0) {
func_800C98B8(Position, Velocity, SOUND_ARG_LOAD(0x19, 0x01, 0x80, 0x47));
} else {
func_800C98B8(Position, Velocity, SOUND_ARG_LOAD(0x19, 0x01, 0x80, 0x48));
}
}
sp94[0] = temp_f26;
sp94[1] = temp_f28;
sp94[2] = temp_f30;
waypoint = &gVehicle2DWaypoint[(WaypointIndex + 5) % gVehicle2DWaypointLength];
sp88[0] = (f32) waypoint->x;
sp88[1] = (f32) D_80162EB0;
sp88[2] = (f32) waypoint->z;
temp_a1 = get_angle_between_waypoints(sp94, sp88);
temp = temp_a1 - RotY;
var_v1 = temp;
if (var_v1 < 0) {
var_v1 = -var_v1;
}
if (var_v1 >= 0x1771) {
if (Speed > 0.2) {
Speed -= 0.04;
}
if (var_v1 >= 0x3D) {
var_v1 = 0x003C;
}
} else {
if (Speed < 2.0) {
Speed += 0.02;
}
if (var_v1 >= 0x1F) {
var_v1 = 0x001E;
}
}
if (temp >= 0x8000) {
RotY -= var_v1;
} else if (temp > 0) {
RotY += var_v1;
} else if (temp < -0x7FFF) {
RotY += var_v1;
} else if (temp < 0) {
RotY -= var_v1;
}
Velocity[0] = Position[0] - temp_f26;
Velocity[1] = Position[1] - temp_f28;
Velocity[2] = Position[2] - temp_f30;
paddleBoatActor = &gActorList[ActorIndex];
paddleBoatActor->pos[0] = Position[0];
paddleBoatActor->pos[1] = Position[1];
paddleBoatActor->pos[2] = Position[2];
if (gIsMirrorMode != 0) {
paddleBoatActor->rot[1] = -RotY;
} else {
paddleBoatActor->rot[1] = RotY;
}
Velocity[0] = Velocity[0];
Velocity[1] = Velocity[1];
Velocity[2] = Velocity[2];
}
}
void ABoat::Collision(s32 playerId, Player* player) {
f32 x_diff;
f32 y_diff;
f32 z_diff;
f32 playerX;
f32 playerZ;
f32 playerY;
if (!((player->effects & 0x01000000)) && (!(player->effects & HIT_BY_ITEM_EFFECT))) {
playerX = player->pos[0];
playerY = player->pos[1];
playerZ = player->pos[2];
if (IsActive == 1) {
x_diff = playerX - Position[0];
y_diff = playerY - Position[1];
z_diff = playerZ - Position[2];
if ((x_diff > -300.0) && (x_diff < 300.0)) {
if ((z_diff > -300.0) && (z_diff < 300.0)) {
if ((func_80006018(Position[0], Position[2],
Velocity[0], Velocity[2], 200.0f,
60.0f, playerX, playerZ) == 1) &&
(y_diff < 60.0)) {
player->soundEffects |= 0x80000;
}
}
}
}
}
}
s32 ABoat::AddSmoke(size_t ferryIndex, Vec3f pos, f32 velocity) {
s32 objectIndex = add_unused_obj_index(SmokeParticles, &NextParticlePtr, gObjectParticle2_SIZE);
if (objectIndex != NULL_OBJECT_ID) {
init_ferry_smoke(objectIndex, pos, velocity);
}
return objectIndex;
}
+42
View File
@@ -0,0 +1,42 @@
#pragma once
#include <libultraship.h>
#include "Vehicle.h"
#include <vector>
extern "C" {
#include "main.h"
#include "vehicles.h"
}
class AVehicle; // Forward declare
class ABoat : public AVehicle {
public:
const char* Type = "mk:boat";
size_t Index;
bool IsActive; // The paddle wheel boat only shows up if the number of players is < 3
Vec3f Position;
Vec3f Velocity;
u16 WaypointIndex;
s16 ActorIndex;
f32 Speed;
s16 RotY = 0;
s32 SomeFlags;
int32_t SmokeParticles[128];
int32_t NextParticlePtr = 0;
int16_t AnotherSmokeTimer = 0;
int16_t SmokeTimer = 0;
explicit ABoat(size_t idx, f32 speed, uint32_t waypoint);
virtual void Spawn() override;
virtual void BeginPlay() override;
virtual void Tick() override;
virtual void Draw(s32 playerId) override;
virtual void Collision(s32 playerId, Player* player) override;
virtual s32 AddSmoke(size_t, Vec3f, f32);
};
+283
View File
@@ -0,0 +1,283 @@
#include <libultraship.h>
#include "Bus.h"
#include <vector>
extern "C" {
#include "macros.h"
#include "main.h"
#include "defines.h"
#include "code_80005FD0.h"
#include "actors.h"
#include "math_util.h"
#include "sounds.h"
#include "update_objects.h"
#include "render_player.h"
#include "external.h"
extern s8 gPlayerCount;
}
ABus::ABus(size_t idx, f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint) {
TrackWaypoint* temp_v0;
u16 waypointOffset;
s32 numWaypoints = gWaypointCountByPathIndex[0];
Index = idx;
waypointOffset = waypoint;
temp_v0 = &path[waypointOffset];
Position[0] = (f32) temp_v0->posX;
Position[1] = (f32) temp_v0->posY;
Position[2] = (f32) temp_v0->posZ;
ActorIndex = -1;
WaypointIndex = waypointOffset;
Velocity[0] = 0.0f;
Velocity[1] = 0.0f;
Velocity[2] = 0.0f;
if (gModeSelection == TIME_TRIALS) {
SomeType = ((Index - 1) % 3);
} else {
SomeType = random_int(3);
}
SomeMultiplierTheSequel = (f32) ((f64) (f32) (SomeType - 1) * 0.6);
if (((gCCSelection > CC_50) || (gModeSelection == TIME_TRIALS)) && (SomeType == 2)) {
Speed = speedA;
} else {
Speed = speedB;
}
Rotation[0] = 0;
Rotation[2] = 0;
if (D_8016347A == 0) {
Rotation[1] = func_8000D6D0(Position, (s16*) &WaypointIndex, Speed,
SomeMultiplierTheSequel, 0, 3);
} else {
Rotation[1] =
func_8000D940(Position, (s16*) &WaypointIndex, Speed, SomeMultiplierTheSequel, 0);
}
D_801631C8 = 10;
}
void ABus::Spawn() {
spawn_vehicle_on_road(Position, Rotation, Velocity, WaypointIndex, SomeMultiplierTheSequel,
Speed);
ActorIndex = add_actor_to_empty_slot(Position, Rotation, Velocity, ACTOR_SCHOOL_BUS);
}
void ABus::BeginPlay() {
}
void ABus::Draw(s32 playerId) {
s32 var_v0;
s32 var_s2;
s32 waypointCount;
u16 temp_a1;
waypointCount = gWaypointCountByPathIndex[0];
if (!(gPlayers[playerId].unk_094 < 1.6666666666666667)) {
temp_a1 = WaypointIndex;
for (var_v0 = 0; var_v0 < 0x18; var_v0 += 3) {
if (((sSomeNearestWaypoint + var_v0) % waypointCount) == temp_a1) {
D_801634F8[playerId].unk4 = func_800145A8(SomeType, D_80163068[playerId], temp_a1);
return;
}
}
}
}
void ABus::Tick() {
f32 temp_f0_2;
f32 temp_f0_3;
f32 sp5C;
f32 sp58;
f32 sp54;
f32 temp_f2_2;
s16 var_a1;
s16 thing;
Vec3f sp40;
Vec3f sp34;
sp5C = Position[0];
sp58 = Position[1];
sp54 = Position[2];
sp40[0] = sp58;
sp40[1] = 0.0f;
sp40[2] = 0.0f;
temp_f0_2 = func_80013C74(SomeType, WaypointIndex);
if (SomeMultiplierTheSequel < temp_f0_2) {
SomeMultiplierTheSequel = SomeMultiplierTheSequel + 0.06;
if (temp_f0_2 < SomeMultiplierTheSequel) {
SomeMultiplierTheSequel = temp_f0_2;
}
}
if (temp_f0_2 < SomeMultiplierTheSequel) {
SomeMultiplierTheSequel = SomeMultiplierTheSequel - 0.06;
if (SomeMultiplierTheSequel < temp_f0_2) {
SomeMultiplierTheSequel = temp_f0_2;
}
}
if (D_8016347A == 0) {
var_a1 = func_8000D6D0(Position, (s16*) &WaypointIndex, Speed,
SomeMultiplierTheSequel, 0, 3);
} else {
var_a1 = func_8000D940(Position, (s16*) &WaypointIndex, Speed,
SomeMultiplierTheSequel, 0);
}
adjust_angle(&Rotation[1], var_a1, 100);
temp_f0_3 = Position[0] - sp5C;
temp_f2_2 = Position[2] - sp54;
sp34[0] = Position[1];
sp34[1] = 0.0f;
sp34[2] = sqrtf((temp_f0_3 * temp_f0_3) + (temp_f2_2 * temp_f2_2));
thing = get_angle_between_two_vectors(sp40, sp34);
adjust_angle(&Rotation[0], -thing, 100);
Velocity[0] = Position[0] - sp5C;
Velocity[1] = Position[1] - sp58;
Velocity[2] = Position[2] - sp54;
struct Actor* vehicleActor = &gActorList[ActorIndex];
vehicleActor->pos[0] = Position[0];
vehicleActor->pos[1] = Position[1];
vehicleActor->pos[2] = Position[2];
vehicleActor->rot[0] = Rotation[0];
if (gIsMirrorMode != 0) {
vehicleActor->rot[1] = -Rotation[1];
} else {
vehicleActor->rot[1] = Rotation[1];
}
vehicleActor->rot[2] = Rotation[2];
vehicleActor->velocity[0] = Velocity[0];
vehicleActor->velocity[1] = Velocity[1];
vehicleActor->velocity[2] = Velocity[2];
}
void ABus::Collision(s32 playerId, Player* player) {
f32 temp_f12;
f32 temp_f14;
f32 temp_f22;
f32 spC4;
f32 spC0;
f32 spBC;
if (((D_801631E0[playerId] != 1) || ((((player->type & PLAYER_HUMAN) != 0)) && !(player->type & PLAYER_KART_AI))) &&
!(player->effects & 0x01000000)) {
spC4 = player->pos[0];
spC0 = player->pos[1];
spBC = player->pos[2];
temp_f12 = spC4 - Position[0];
temp_f22 = spC0 - Position[1];
temp_f14 = spBC - Position[2];
if (((temp_f12) > -100.0) && ((temp_f12) < 100.0)) {
if ((temp_f22 > -20.0) && (temp_f22 < 20.0)) {
if (((temp_f14) > -100.0) && ((temp_f14) < 100.0)) {
if (func_80006018(Position[0], Position[2], Velocity[0],
Velocity[2], SomeArg3, SomeArg4, spC4, spBC) == (s32) 1) {
player->soundEffects |= REVERSE_SOUND_EFFECT;
}
}
}
}
if ((player->type & PLAYER_HUMAN) && !(player->type & PLAYER_KART_AI)) {
if (((temp_f12) > -300.0) && ((temp_f12) < 300.0) && ((temp_f22 > -20.0)) && (temp_f22 < 20.0) &&
(((temp_f14) > -300.0)) && ((temp_f14) < 300.0)) {
if ((D_801631C8 > 0) && (SomeFlags == 0)) {
D_801631C8 -= 1;
SomeFlags |= (RENDER_VEHICLE << playerId);
func_800C9D80(Position, Velocity, SoundBits);
}
} else {
if (SomeFlags != 0) {
SomeFlags &= ~(RENDER_VEHICLE << playerId);
if (SomeFlags == 0) {
D_801631C8 += 1;
func_800C9EF4(Position, SoundBits);
}
}
}
if (((temp_f12) > -200.0) && ((temp_f12) < 200.0) && ((temp_f22 > -20.0)) && (temp_f22 < 20.0) &&
(((temp_f14) > -200.0)) && ((temp_f14) < 200.0)) {
if (!(SomeFlagsTheSequel & ((1 << playerId)))) {
s32 var_s1 = 0;
u16 path = gWaypointCountByPathIndex[0];
s32 t1;
s32 t2;
switch (D_8016347A) {
case 0:
t1 = func_80007BF8(WaypointIndex, gNearestWaypointByPlayerId[playerId], 10, 0,
path);
if ((D_80163270[playerId] == 0) && (t1 > 0) && (player->unk_094 < Speed)) {
var_s1 = 1;
}
if ((D_80163270[playerId] == 1) && (t1 > 0)) {
var_s1 = 1;
}
break;
case 1:
t2 = func_80007BF8(WaypointIndex, gNearestWaypointByPlayerId[playerId], 0, 10,
path);
if (t2 > 0) {
if (random_int(2) == 0) {
// temp_v1_2 = D_80163270[playerId];
if (D_80163270[playerId] == 0) {
var_s1 = 1;
}
if ((D_80163270[playerId] == 1) && (player->unk_094 < Speed)) {
var_s1 = 1;
}
} else {
SomeFlagsTheSequel |= ((1 << playerId));
}
}
break;
}
if (var_s1 == 1) {
u32 soundBits2 = SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x3B);
switch (SoundBits) {
case SOUND_ARG_LOAD(0x51, 0x01, 0x80, 0x05):
soundBits2 = SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x3B);
if (random_int(4) == 0) {
soundBits2 = SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x3C);
}
break;
case SOUND_ARG_LOAD(0x51, 0x01, 0x80, 0x02):
if (random_int(2) != 0) {
soundBits2 = SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x3D);
} else {
soundBits2 = SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x3E);
}
break;
case SOUND_ARG_LOAD(0x51, 0x01, 0x80, 0x03):
if (random_int(2) != 0) {
soundBits2 = SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x3F);
} else {
soundBits2 = SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x40);
}
break;
case SOUND_ARG_LOAD(0x51, 0x01, 0x80, 0x04):
if (random_int(2) != 0) {
soundBits2 = SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x41);
} else {
soundBits2 = SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x42);
}
break;
}
SomeFlagsTheSequel |= ((1 << playerId));
func_800C98B8(Position, Velocity, soundBits2);
}
}
} else {
if (SomeFlagsTheSequel & ((1 << playerId))) {
SomeFlagsTheSequel &= ~((1 << playerId));
}
}
}
}
}
+43
View File
@@ -0,0 +1,43 @@
#pragma once
#include <libultraship.h>
#include "Vehicle.h"
#include <vector>
extern "C" {
#include "main.h"
#include "vehicles.h"
#include "waypoints.h"
#include "sounds.h"
}
class AVehicle; // Forward declare
class ABus : public AVehicle {
public:
const char* Type;
size_t Index;
f32 Speed;
s16 ActorIndex;
Vec3f Position;
Vec3f Velocity;
Vec3s Rotation;
f32 SomeMultiplierTheSequel;
s8 SomeFlagsTheSequel = 0;
u16 WaypointIndex;
s8 SomeFlags = 0;
s16 SomeType;
f32 SomeArg3 = 55.0f;
f32 SomeArg4 = 12.5f;
u32 SoundBits = SOUND_ARG_LOAD(0x51, 0x01, 0x80, 0x03);
explicit ABus(size_t idx, f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint);
virtual void Spawn() override;
virtual void BeginPlay() override;
virtual void Tick() override;
virtual void Draw(s32 playerId) override;
virtual void Collision(s32 playerId, Player* player) override;
};
+283
View File
@@ -0,0 +1,283 @@
#include <libultraship.h>
#include "Car.h"
#include <vector>
extern "C" {
#include "macros.h"
#include "main.h"
#include "defines.h"
#include "code_80005FD0.h"
#include "actors.h"
#include "math_util.h"
#include "sounds.h"
#include "update_objects.h"
#include "render_player.h"
#include "external.h"
extern s8 gPlayerCount;
}
ACar::ACar(size_t idx, f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint) {
TrackWaypoint* temp_v0;
u16 waypointOffset;
s32 numWaypoints = gWaypointCountByPathIndex[0];
Index = idx;
waypointOffset = waypoint;
temp_v0 = &path[waypointOffset];
Position[0] = (f32) temp_v0->posX;
Position[1] = (f32) temp_v0->posY;
Position[2] = (f32) temp_v0->posZ;
ActorIndex = -1;
WaypointIndex = waypointOffset;
Velocity[0] = 0.0f;
Velocity[1] = 0.0f;
Velocity[2] = 0.0f;
if (gModeSelection == TIME_TRIALS) {
SomeType = ((Index - 1) % 3);
} else {
SomeType = random_int(3);
}
SomeMultiplierTheSequel = (f32) ((f64) (f32) (SomeType - 1) * 0.6);
if (((gCCSelection > CC_50) || (gModeSelection == TIME_TRIALS)) && (SomeType == 2)) {
Speed = speedA;
} else {
Speed = speedB;
}
Rotation[0] = 0;
Rotation[2] = 0;
if (D_8016347A == 0) {
Rotation[1] = func_8000D6D0(Position, (s16*) &WaypointIndex, Speed,
SomeMultiplierTheSequel, 0, 3);
} else {
Rotation[1] =
func_8000D940(Position, (s16*) &WaypointIndex, Speed, SomeMultiplierTheSequel, 0);
}
D_801631C8 = 10;
}
void ACar::Spawn() {
spawn_vehicle_on_road(Position, Rotation, Velocity, WaypointIndex, SomeMultiplierTheSequel,
Speed);
ActorIndex = add_actor_to_empty_slot(Position, Rotation, Velocity, ACTOR_CAR);
}
void ACar::BeginPlay() {
}
void ACar::Tick() {
f32 temp_f0_2;
f32 temp_f0_3;
f32 sp5C;
f32 sp58;
f32 sp54;
f32 temp_f2_2;
s16 var_a1;
s16 thing;
Vec3f sp40;
Vec3f sp34;
sp5C = Position[0];
sp58 = Position[1];
sp54 = Position[2];
sp40[0] = sp58;
sp40[1] = 0.0f;
sp40[2] = 0.0f;
temp_f0_2 = func_80013C74(SomeType, WaypointIndex);
if (SomeMultiplierTheSequel < temp_f0_2) {
SomeMultiplierTheSequel = SomeMultiplierTheSequel + 0.06;
if (temp_f0_2 < SomeMultiplierTheSequel) {
SomeMultiplierTheSequel = temp_f0_2;
}
}
if (temp_f0_2 < SomeMultiplierTheSequel) {
SomeMultiplierTheSequel = SomeMultiplierTheSequel - 0.06;
if (SomeMultiplierTheSequel < temp_f0_2) {
SomeMultiplierTheSequel = temp_f0_2;
}
}
if (D_8016347A == 0) {
var_a1 = func_8000D6D0(Position, (s16*) &WaypointIndex, Speed,
SomeMultiplierTheSequel, 0, 3);
} else {
var_a1 = func_8000D940(Position, (s16*) &WaypointIndex, Speed,
SomeMultiplierTheSequel, 0);
}
adjust_angle(&Rotation[1], var_a1, 100);
temp_f0_3 = Position[0] - sp5C;
temp_f2_2 = Position[2] - sp54;
sp34[0] = Position[1];
sp34[1] = 0.0f;
sp34[2] = sqrtf((temp_f0_3 * temp_f0_3) + (temp_f2_2 * temp_f2_2));
thing = get_angle_between_two_vectors(sp40, sp34);
adjust_angle(&Rotation[0], -thing, 100);
Velocity[0] = Position[0] - sp5C;
Velocity[1] = Position[1] - sp58;
Velocity[2] = Position[2] - sp54;
struct Actor* vehicleActor = &gActorList[ActorIndex];
vehicleActor->pos[0] = Position[0];
vehicleActor->pos[1] = Position[1];
vehicleActor->pos[2] = Position[2];
vehicleActor->rot[0] = Rotation[0];
if (gIsMirrorMode != 0) {
vehicleActor->rot[1] = -Rotation[1];
} else {
vehicleActor->rot[1] = Rotation[1];
}
vehicleActor->rot[2] = Rotation[2];
vehicleActor->velocity[0] = Velocity[0];
vehicleActor->velocity[1] = Velocity[1];
vehicleActor->velocity[2] = Velocity[2];
}
void ACar::Draw(s32 playerId) {
s32 var_v0;
s32 var_s2;
s32 waypointCount;
u16 temp_a1;
waypointCount = gWaypointCountByPathIndex[0];
if (!(gPlayers[playerId].unk_094 < 1.6666666666666667)) {
temp_a1 = WaypointIndex;
for (var_v0 = 0; var_v0 < 0x18; var_v0 += 3) {
if (((sSomeNearestWaypoint + var_v0) % waypointCount) == temp_a1) {
D_801634F8[playerId].unk4 = func_800145A8(SomeType, D_80163068[playerId], temp_a1);
return;
}
}
}
}
void ACar::Collision(s32 playerId, Player* player) {
f32 temp_f12;
f32 temp_f14;
f32 temp_f22;
f32 spC4;
f32 spC0;
f32 spBC;
if (((D_801631E0[playerId] != 1) || ((((player->type & PLAYER_HUMAN) != 0)) && !(player->type & PLAYER_KART_AI))) &&
!(player->effects & 0x01000000)) {
spC4 = player->pos[0];
spC0 = player->pos[1];
spBC = player->pos[2];
temp_f12 = spC4 - Position[0];
temp_f22 = spC0 - Position[1];
temp_f14 = spBC - Position[2];
if (((temp_f12) > -100.0) && ((temp_f12) < 100.0)) {
if ((temp_f22 > -20.0) && (temp_f22 < 20.0)) {
if (((temp_f14) > -100.0) && ((temp_f14) < 100.0)) {
if (func_80006018(Position[0], Position[2], Velocity[0],
Velocity[2], SomeArg3, SomeArg4, spC4, spBC) == (s32) 1) {
player->soundEffects |= REVERSE_SOUND_EFFECT;
}
}
}
}
if ((player->type & PLAYER_HUMAN) && !(player->type & PLAYER_KART_AI)) {
if (((temp_f12) > -300.0) && ((temp_f12) < 300.0) && ((temp_f22 > -20.0)) && (temp_f22 < 20.0) &&
(((temp_f14) > -300.0)) && ((temp_f14) < 300.0)) {
if ((D_801631C8 > 0) && (SomeFlags == 0)) {
D_801631C8 -= 1;
SomeFlags |= (RENDER_VEHICLE << playerId);
func_800C9D80(Position, Velocity, SoundBits);
}
} else {
if (SomeFlags != 0) {
SomeFlags &= ~(RENDER_VEHICLE << playerId);
if (SomeFlags == 0) {
D_801631C8 += 1;
func_800C9EF4(Position, SoundBits);
}
}
}
if (((temp_f12) > -200.0) && ((temp_f12) < 200.0) && ((temp_f22 > -20.0)) && (temp_f22 < 20.0) &&
(((temp_f14) > -200.0)) && ((temp_f14) < 200.0)) {
if (!(SomeFlagsTheSequel & ((1 << playerId)))) {
s32 var_s1 = 0;
u16 path = gWaypointCountByPathIndex[0];
s32 t1;
s32 t2;
switch (D_8016347A) {
case 0:
t1 = func_80007BF8(WaypointIndex, gNearestWaypointByPlayerId[playerId], 10, 0,
path);
if ((D_80163270[playerId] == 0) && (t1 > 0) && (player->unk_094 < Speed)) {
var_s1 = 1;
}
if ((D_80163270[playerId] == 1) && (t1 > 0)) {
var_s1 = 1;
}
break;
case 1:
t2 = func_80007BF8(WaypointIndex, gNearestWaypointByPlayerId[playerId], 0, 10,
path);
if (t2 > 0) {
if (random_int(2) == 0) {
// temp_v1_2 = D_80163270[playerId];
if (D_80163270[playerId] == 0) {
var_s1 = 1;
}
if ((D_80163270[playerId] == 1) && (player->unk_094 < Speed)) {
var_s1 = 1;
}
} else {
SomeFlagsTheSequel |= ((1 << playerId));
}
}
break;
}
if (var_s1 == 1) {
u32 soundBits2 = SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x3B);
switch (SoundBits) {
case SOUND_ARG_LOAD(0x51, 0x01, 0x80, 0x05):
soundBits2 = SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x3B);
if (random_int(4) == 0) {
soundBits2 = SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x3C);
}
break;
case SOUND_ARG_LOAD(0x51, 0x01, 0x80, 0x02):
if (random_int(2) != 0) {
soundBits2 = SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x3D);
} else {
soundBits2 = SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x3E);
}
break;
case SOUND_ARG_LOAD(0x51, 0x01, 0x80, 0x03):
if (random_int(2) != 0) {
soundBits2 = SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x3F);
} else {
soundBits2 = SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x40);
}
break;
case SOUND_ARG_LOAD(0x51, 0x01, 0x80, 0x04):
if (random_int(2) != 0) {
soundBits2 = SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x41);
} else {
soundBits2 = SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x42);
}
break;
}
SomeFlagsTheSequel |= ((1 << playerId));
func_800C98B8(Position, Velocity, soundBits2);
}
}
} else {
if (SomeFlagsTheSequel & ((1 << playerId))) {
SomeFlagsTheSequel &= ~((1 << playerId));
}
}
}
}
}
+43
View File
@@ -0,0 +1,43 @@
#pragma once
#include <libultraship.h>
#include "Vehicle.h"
#include <vector>
extern "C" {
#include "main.h"
#include "vehicles.h"
#include "waypoints.h"
#include "sounds.h"
}
class AVehicle; // Forward declare
class ACar : public AVehicle {
public:
explicit ACar(size_t idx, f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint);
const char* Type;
size_t Index;
f32 Speed;
s16 ActorIndex;
Vec3f Position;
Vec3f Velocity;
Vec3s Rotation;
f32 SomeMultiplierTheSequel;
s8 SomeFlagsTheSequel = 0;
u16 WaypointIndex;
s8 SomeFlags = 0;
s16 SomeType;
f32 SomeArg3 = 11.5f;
f32 SomeArg4 = 8.5f;
u32 SoundBits = SOUND_ARG_LOAD(0x51, 0x01, 0x80, 0x05);
virtual void Spawn() override;
virtual void BeginPlay() override;
virtual void Tick() override;
virtual void Draw(s32 playerId) override;
virtual void Collision(s32 playerId, Player* player) override;
};
+283
View File
@@ -0,0 +1,283 @@
#include <libultraship.h>
#include "TankerTruck.h"
#include <vector>
extern "C" {
#include "macros.h"
#include "main.h"
#include "defines.h"
#include "code_80005FD0.h"
#include "actors.h"
#include "math_util.h"
#include "sounds.h"
#include "update_objects.h"
#include "render_player.h"
#include "external.h"
extern s8 gPlayerCount;
}
ATankerTruck::ATankerTruck(size_t idx, f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint) {
TrackWaypoint* temp_v0;
u16 waypointOffset;
s32 numWaypoints = gWaypointCountByPathIndex[0];
Index = idx;
waypointOffset = waypoint;
temp_v0 = &path[waypointOffset];
Position[0] = (f32) temp_v0->posX;
Position[1] = (f32) temp_v0->posY;
Position[2] = (f32) temp_v0->posZ;
ActorIndex = -1;
WaypointIndex = waypointOffset;
Velocity[0] = 0.0f;
Velocity[1] = 0.0f;
Velocity[2] = 0.0f;
if (gModeSelection == TIME_TRIALS) {
SomeType = ((Index - 1) % 3);
} else {
SomeType = random_int(3);
}
SomeMultiplierTheSequel = (f32) ((f64) (f32) (SomeType - 1) * 0.6);
if (((gCCSelection > CC_50) || (gModeSelection == TIME_TRIALS)) && (SomeType == 2)) {
Speed = speedA;
} else {
Speed = speedB;
}
Rotation[0] = 0;
Rotation[2] = 0;
if (D_8016347A == 0) {
Rotation[1] = func_8000D6D0(Position, (s16*) &WaypointIndex, Speed,
SomeMultiplierTheSequel, 0, 3);
} else {
Rotation[1] =
func_8000D940(Position, (s16*) &WaypointIndex, Speed, SomeMultiplierTheSequel, 0);
}
D_801631C8 = 10;
}
void ATankerTruck::Spawn() {
spawn_vehicle_on_road(Position, Rotation, Velocity, WaypointIndex, SomeMultiplierTheSequel,
Speed);
ActorIndex = add_actor_to_empty_slot(Position, Rotation, Velocity, ACTOR_TANKER_TRUCK);
}
void ATankerTruck::BeginPlay() {
}
void ATankerTruck::Draw(s32 playerId) {
s32 var_v0;
s32 var_s2;
s32 waypointCount;
u16 temp_a1;
waypointCount = gWaypointCountByPathIndex[0];
if (!(gPlayers[playerId].unk_094 < 1.6666666666666667)) {
temp_a1 = WaypointIndex;
for (var_v0 = 0; var_v0 < 0x18; var_v0 += 3) {
if (((sSomeNearestWaypoint + var_v0) % waypointCount) == temp_a1) {
D_801634F8[playerId].unk4 = func_800145A8(SomeType, D_80163068[playerId], temp_a1);
return;
}
}
}
}
void ATankerTruck::Tick() {
f32 temp_f0_2;
f32 temp_f0_3;
f32 sp5C;
f32 sp58;
f32 sp54;
f32 temp_f2_2;
s16 var_a1;
s16 thing;
Vec3f sp40;
Vec3f sp34;
sp5C = Position[0];
sp58 = Position[1];
sp54 = Position[2];
sp40[0] = sp58;
sp40[1] = 0.0f;
sp40[2] = 0.0f;
temp_f0_2 = func_80013C74(SomeType, WaypointIndex);
if (SomeMultiplierTheSequel < temp_f0_2) {
SomeMultiplierTheSequel = SomeMultiplierTheSequel + 0.06;
if (temp_f0_2 < SomeMultiplierTheSequel) {
SomeMultiplierTheSequel = temp_f0_2;
}
}
if (temp_f0_2 < SomeMultiplierTheSequel) {
SomeMultiplierTheSequel = SomeMultiplierTheSequel - 0.06;
if (SomeMultiplierTheSequel < temp_f0_2) {
SomeMultiplierTheSequel = temp_f0_2;
}
}
if (D_8016347A == 0) {
var_a1 = func_8000D6D0(Position, (s16*) &WaypointIndex, Speed,
SomeMultiplierTheSequel, 0, 3);
} else {
var_a1 = func_8000D940(Position, (s16*) &WaypointIndex, Speed,
SomeMultiplierTheSequel, 0);
}
adjust_angle(&Rotation[1], var_a1, 100);
temp_f0_3 = Position[0] - sp5C;
temp_f2_2 = Position[2] - sp54;
sp34[0] = Position[1];
sp34[1] = 0.0f;
sp34[2] = sqrtf((temp_f0_3 * temp_f0_3) + (temp_f2_2 * temp_f2_2));
thing = get_angle_between_two_vectors(sp40, sp34);
adjust_angle(&Rotation[0], -thing, 100);
Velocity[0] = Position[0] - sp5C;
Velocity[1] = Position[1] - sp58;
Velocity[2] = Position[2] - sp54;
struct Actor* vehicleActor = &gActorList[ActorIndex];
vehicleActor->pos[0] = Position[0];
vehicleActor->pos[1] = Position[1];
vehicleActor->pos[2] = Position[2];
vehicleActor->rot[0] = Rotation[0];
if (gIsMirrorMode != 0) {
vehicleActor->rot[1] = -Rotation[1];
} else {
vehicleActor->rot[1] = Rotation[1];
}
vehicleActor->rot[2] = Rotation[2];
vehicleActor->velocity[0] = Velocity[0];
vehicleActor->velocity[1] = Velocity[1];
vehicleActor->velocity[2] = Velocity[2];
}
void ATankerTruck::Collision(s32 playerId, Player* player) {
f32 temp_f12;
f32 temp_f14;
f32 temp_f22;
f32 spC4;
f32 spC0;
f32 spBC;
if (((D_801631E0[playerId] != 1) || ((((player->type & PLAYER_HUMAN) != 0)) && !(player->type & PLAYER_KART_AI))) &&
!(player->effects & 0x01000000)) {
spC4 = player->pos[0];
spC0 = player->pos[1];
spBC = player->pos[2];
temp_f12 = spC4 - Position[0];
temp_f22 = spC0 - Position[1];
temp_f14 = spBC - Position[2];
if (((temp_f12) > -100.0) && ((temp_f12) < 100.0)) {
if ((temp_f22 > -20.0) && (temp_f22 < 20.0)) {
if (((temp_f14) > -100.0) && ((temp_f14) < 100.0)) {
if (func_80006018(Position[0], Position[2], Velocity[0],
Velocity[2], SomeArg3, SomeArg4, spC4, spBC) == (s32) 1) {
player->soundEffects |= REVERSE_SOUND_EFFECT;
}
}
}
}
if ((player->type & PLAYER_HUMAN) && !(player->type & PLAYER_KART_AI)) {
if (((temp_f12) > -300.0) && ((temp_f12) < 300.0) && ((temp_f22 > -20.0)) && (temp_f22 < 20.0) &&
(((temp_f14) > -300.0)) && ((temp_f14) < 300.0)) {
if ((D_801631C8 > 0) && (SomeFlags == 0)) {
D_801631C8 -= 1;
SomeFlags |= (RENDER_VEHICLE << playerId);
func_800C9D80(Position, Velocity, SoundBits);
}
} else {
if (SomeFlags != 0) {
SomeFlags &= ~(RENDER_VEHICLE << playerId);
if (SomeFlags == 0) {
D_801631C8 += 1;
func_800C9EF4(Position, SoundBits);
}
}
}
if (((temp_f12) > -200.0) && ((temp_f12) < 200.0) && ((temp_f22 > -20.0)) && (temp_f22 < 20.0) &&
(((temp_f14) > -200.0)) && ((temp_f14) < 200.0)) {
if (!(SomeFlagsTheSequel & ((1 << playerId)))) {
s32 var_s1 = 0;
u16 path = gWaypointCountByPathIndex[0];
s32 t1;
s32 t2;
switch (D_8016347A) {
case 0:
t1 = func_80007BF8(WaypointIndex, gNearestWaypointByPlayerId[playerId], 10, 0,
path);
if ((D_80163270[playerId] == 0) && (t1 > 0) && (player->unk_094 < Speed)) {
var_s1 = 1;
}
if ((D_80163270[playerId] == 1) && (t1 > 0)) {
var_s1 = 1;
}
break;
case 1:
t2 = func_80007BF8(WaypointIndex, gNearestWaypointByPlayerId[playerId], 0, 10,
path);
if (t2 > 0) {
if (random_int(2) == 0) {
// temp_v1_2 = D_80163270[playerId];
if (D_80163270[playerId] == 0) {
var_s1 = 1;
}
if ((D_80163270[playerId] == 1) && (player->unk_094 < Speed)) {
var_s1 = 1;
}
} else {
SomeFlagsTheSequel |= ((1 << playerId));
}
}
break;
}
if (var_s1 == 1) {
u32 soundBits2 = SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x3B);
switch (SoundBits) {
case SOUND_ARG_LOAD(0x51, 0x01, 0x80, 0x05):
soundBits2 = SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x3B);
if (random_int(4) == 0) {
soundBits2 = SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x3C);
}
break;
case SOUND_ARG_LOAD(0x51, 0x01, 0x80, 0x02):
if (random_int(2) != 0) {
soundBits2 = SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x3D);
} else {
soundBits2 = SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x3E);
}
break;
case SOUND_ARG_LOAD(0x51, 0x01, 0x80, 0x03):
if (random_int(2) != 0) {
soundBits2 = SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x3F);
} else {
soundBits2 = SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x40);
}
break;
case SOUND_ARG_LOAD(0x51, 0x01, 0x80, 0x04):
if (random_int(2) != 0) {
soundBits2 = SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x41);
} else {
soundBits2 = SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x42);
}
break;
}
SomeFlagsTheSequel |= ((1 << playerId));
func_800C98B8(Position, Velocity, soundBits2);
}
}
} else {
if (SomeFlagsTheSequel & ((1 << playerId))) {
SomeFlagsTheSequel &= ~((1 << playerId));
}
}
}
}
}
+43
View File
@@ -0,0 +1,43 @@
#pragma once
#include <libultraship.h>
#include "Vehicle.h"
#include <vector>
extern "C" {
#include "main.h"
#include "vehicles.h"
#include "waypoints.h"
#include "sounds.h"
}
class AVehicle; // Forward declare
class ATankerTruck : public AVehicle {
public:
const char* Type;
size_t Index;
f32 Speed;
s16 ActorIndex;
Vec3f Position;
Vec3f Velocity;
Vec3s Rotation;
f32 SomeMultiplierTheSequel;
s8 SomeFlagsTheSequel = 0;
u16 WaypointIndex;
s8 SomeFlags = 0;
s16 SomeType;
f32 SomeArg3 = 55.0f;
f32 SomeArg4 = 12.5f;
u32 SoundBits = SOUND_ARG_LOAD(0x51, 0x01, 0x80, 0x03);
explicit ATankerTruck(size_t idx, f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint);
virtual void Spawn() override;
virtual void BeginPlay() override;
virtual void Tick() override;
virtual void Draw(s32 playerId) override;
virtual void Collision(s32 playerId, Player* player) override;
};
+294
View File
@@ -0,0 +1,294 @@
#include <libultraship.h>
#include <libultra/gbi.h>
#include "Train.h"
#include <vector>
extern "C" {
#include "macros.h"
#include "main.h"
#include "defines.h"
#include "code_80005FD0.h"
#include "vehicles.h"
#include "actors.h"
#include "math_util.h"
#include "sounds.h"
#include "update_objects.h"
#include "waypoints.h"
#include "code_80057C60.h"
#include "math_util_2.h"
#include "render_objects.h"
#include "assets/common_data.h"
// #include "common_structs.h"
}
ATrain::ATrain(size_t idx, size_t numCarriages, f32 speed, uint32_t waypoint) {
u16 waypointOffset;
TrainCarStuff* ptr1;
Path2D* pos;
Index = idx;
Speed = speed;
// Set to the default value
std::fill(SmokeParticles, SmokeParticles + 128, NULL_OBJECT_ID);
for (size_t i = 0; i < numCarriages; i++) {
PassengerCars.push_back(TrainCarStuff());
}
// outputs 160 or 392 depending on the train.
// Wraps the value around to always output a valid waypoint.
waypointOffset = waypoint;
// 120.0f is about the maximum usable value
for (size_t i = 0; i < PassengerCars.size(); i++) {
waypointOffset += 4;
ptr1 = &PassengerCars[i];
pos = &gVehicle2DWaypoint[waypointOffset];
set_vehicle_pos_waypoint(ptr1, pos, waypointOffset);
}
// Smaller offset for the tender
waypointOffset += 3;
pos = &gVehicle2DWaypoint[waypointOffset];
set_vehicle_pos_waypoint(&this->Tender, pos, waypointOffset);
waypointOffset += 4;
pos = &gVehicle2DWaypoint[waypointOffset];
set_vehicle_pos_waypoint(&Locomotive, pos, waypointOffset);
// Only use locomotive unless overwritten below.
NumCars = LOCOMOTIVE_ONLY;
// Spawn all rolling stock in single player mode.
switch (gScreenModeSelection) {
case SCREEN_MODE_1P: // single player
Tender.isActive = 1;
// clang-format off
// Same line required for matching...
for (size_t i = 0; i < numCarriages; i++) { PassengerCars[i].isActive = 1; }
// clang-format on
NumCars = NUM_TENDERS + numCarriages;
break;
// Spawn locomotive, tender, and one passenger car in versus 2/3 player mode.
case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL: // multiplayer fall-through
case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL:
if (gModeSelection != GRAND_PRIX) {
Tender.isActive = 1;
PassengerCars[4].isActive = 1;
NumCars = NUM_TENDERS + NUM_2P_PASSENGER_CARS;
}
break;
}
AnotherSmokeTimer = 0;
}
void ATrain::Spawn() {
TrainCarStuff* tempLocomotive;
TrainCarStuff* tempTender;
TrainCarStuff* tempPassengerCar;
Vec3s trainCarRot;
s16 trainCarYRot;
f32 origXPos;
f32 origZPos;
tempLocomotive = &Locomotive;
origXPos = tempLocomotive->position[0];
origZPos = tempLocomotive->position[2];
trainCarYRot = update_vehicle_following_waypoint(
tempLocomotive->position, (s16*) &tempLocomotive->waypointIndex, Speed);
tempLocomotive->velocity[0] = tempLocomotive->position[0] - origXPos;
tempLocomotive->velocity[2] = tempLocomotive->position[2] - origZPos;
vec3s_set(trainCarRot, 0, trainCarYRot, 0);
tempLocomotive->actorIndex = add_actor_to_empty_slot(tempLocomotive->position, trainCarRot,
tempLocomotive->velocity, ACTOR_TRAIN_ENGINE);
tempTender = &Tender;
if (tempTender->isActive == 1) {
origXPos = tempTender->position[0];
origZPos = tempTender->position[2];
trainCarYRot = update_vehicle_following_waypoint(
tempTender->position, (s16*) &tempTender->waypointIndex, Speed);
tempTender->velocity[0] = tempTender->position[0] - origXPos;
tempTender->velocity[2] = tempTender->position[2] - origZPos;
vec3s_set(trainCarRot, 0, trainCarYRot, 0);
tempTender->actorIndex = add_actor_to_empty_slot(tempTender->position, trainCarRot,
tempTender->velocity, ACTOR_TRAIN_TENDER);
}
for (size_t i = 0; i < PassengerCars.size(); i++) {
tempPassengerCar = &PassengerCars[i];
if (tempPassengerCar->isActive == 1) {
origXPos = tempPassengerCar->position[0];
origZPos = tempPassengerCar->position[2];
trainCarYRot = update_vehicle_following_waypoint(tempPassengerCar->position,
(s16*) &tempPassengerCar->waypointIndex,
Speed);
tempPassengerCar->velocity[0] = tempPassengerCar->position[0] - origXPos;
tempPassengerCar->velocity[2] = tempPassengerCar->position[2] - origZPos;
vec3s_set(trainCarRot, 0, trainCarYRot, 0);
tempPassengerCar->actorIndex =
add_actor_to_empty_slot(tempPassengerCar->position, trainCarRot, tempPassengerCar->velocity,
ACTOR_TRAIN_PASSENGER_CAR);
}
}
}
void ATrain::BeginPlay() {
}
void ATrain::SyncComponents(TrainCarStuff* trainCar, s16 orientationY) {
struct TrainCar* trainCarActor;
//! @todo: Change actorIndex to ptr to TrainCar actor
trainCarActor = (struct TrainCar*) &gActorList[trainCar->actorIndex];
trainCarActor->pos[0] = trainCar->position[0];
trainCarActor->pos[1] = trainCar->position[1];
trainCarActor->pos[2] = trainCar->position[2];
if (gIsMirrorMode != 0) {
trainCarActor->rot[1] = -orientationY;
} else {
trainCarActor->rot[1] = orientationY;
}
trainCarActor->velocity[0] = trainCar->velocity[0];
trainCarActor->velocity[2] = trainCar->velocity[2];
}
void ATrain::Tick() {
f32 temp_f20;
TrainCarStuff* car;
u16 oldWaypointIndex;
s16 orientationYUpdate;
f32 temp_f22;
s32 j;
Vec3f smokePos;
AnotherSmokeTimer += 1;
oldWaypointIndex = (u16) Locomotive.waypointIndex;
temp_f20 = Locomotive.position[0];
temp_f22 = Locomotive.position[2];
orientationYUpdate = update_vehicle_following_waypoint(
Locomotive.position, (s16*) &Locomotive.waypointIndex, Speed);
Locomotive.velocity[0] = Locomotive.position[0] - temp_f20;
Locomotive.velocity[2] = Locomotive.position[2] - temp_f22;
sync_train_components(&Locomotive, orientationYUpdate);
if ((oldWaypointIndex != Locomotive.waypointIndex) &&
((Locomotive.waypointIndex == 0x00BE) ||
(Locomotive.waypointIndex == 0x0140))) { // play crossing bell sound
func_800C98B8(Locomotive.position, Locomotive.velocity,
SOUND_ARG_LOAD(0x19, 0x01, 0x80, 0x0E));
} else if (random_int(100) == 0) { // play train whistle sound
func_800C98B8(Locomotive.position, Locomotive.velocity,
SOUND_ARG_LOAD(0x19, 0x01, 0x80, 0x0D));
}
SomeFlags = set_vehicle_render_distance_flags(
Locomotive.position, TRAIN_SMOKE_RENDER_DISTANCE, SomeFlags);
// Renders locomotive smoke on all screens if any player is within range.
if ((((s16) AnotherSmokeTimer % 5) == 0) && (SomeFlags != 0)) {
smokePos[0] = Locomotive.position[0];
smokePos[1] = (f32) ((f64) Locomotive.position[1] + 65.0);
smokePos[2] = (f32) ((f64) Locomotive.position[2] + 25.0);
adjust_position_by_angle(smokePos, Locomotive.position, orientationYUpdate);
//spawn_train_smoke(Index, smokePos, 1.1f);
printf("\nSMOKE HERE: %d\n\n", Index);
AddSmoke(Index, smokePos, 1.1f);
}
car = &Tender;
if (car->isActive == 1) {
temp_f20 = car->position[0];
temp_f22 = car->position[2];
orientationYUpdate =
update_vehicle_following_waypoint(car->position, (s16*) &car->waypointIndex, Speed);
car->velocity[0] = car->position[0] - temp_f20;
car->velocity[2] = car->position[2] - temp_f22;
sync_train_components(car, orientationYUpdate);
}
for (j = 0; j < PassengerCars.size(); j++) {
car = &PassengerCars[j];
if (car->isActive == 1) {
temp_f20 = car->position[0];
temp_f22 = car->position[2];
orientationYUpdate =
update_vehicle_following_waypoint(car->position, (s16*) &car->waypointIndex, Speed);
car->velocity[0] = car->position[0] - temp_f20;
car->velocity[2] = car->position[2] - temp_f22;
sync_train_components(car, orientationYUpdate);
}
}
}
void ATrain::Collision(s32 playerId, Player* player) {
TrainCarStuff* trainCar;
f32 playerPosX;
f32 playerPosZ;
f32 x_dist;
f32 z_dist;
s32 trainIndex;
if (D_801631E0[playerId] != 1) {
if (!(player->effects & 0x01000000)) {
playerPosX = player->pos[0];
playerPosZ = player->pos[2];
trainCar = &Locomotive;
x_dist = playerPosX - trainCar->position[0];
z_dist = playerPosZ - trainCar->position[2];
if ((x_dist > -100.0) && (x_dist < 100.0)) {
if ((z_dist > -100.0) && (z_dist < 100.0)) {
if (func_80006018(trainCar->position[0], trainCar->position[2], trainCar->velocity[0],
trainCar->velocity[2], 60.0f, 20.0f, playerPosX, playerPosZ) == 1) {
player->soundEffects |= REVERSE_SOUND_EFFECT;
}
trainCar = &Tender;
if (trainCar->isActive == 1) {
if (func_80006018(trainCar->position[0], trainCar->position[2], trainCar->velocity[0],
trainCar->velocity[2], 30.0f, 20.0f, playerPosX, playerPosZ) == 1) {
player->soundEffects |= REVERSE_SOUND_EFFECT;
}
}
}
}
for (size_t i = 0; i < PassengerCars.size(); i++) {
trainCar = &PassengerCars[i];
x_dist = playerPosX - trainCar->position[0];
z_dist = playerPosZ - trainCar->position[2];
if (trainCar->isActive == 1) {
if ((x_dist > -100.0) && (x_dist < 100.0)) {
if ((z_dist > -100.0) && (z_dist < 100.0)) {
if (func_80006018(trainCar->position[0], trainCar->position[2], trainCar->velocity[0],
trainCar->velocity[2], 30.0f, 20.0f, playerPosX, playerPosZ) == 1) {
player->soundEffects |= REVERSE_SOUND_EFFECT;
}
}
}
}
}
}
}
}
void ATrain::Draw(s32 playerId) {
}
s32 ATrain::AddSmoke(s32 trainIndex, Vec3f pos, f32 velocity) {
s32 objectIndex = add_unused_obj_index(SmokeParticles, &NextParticlePtr, gObjectParticle2_SIZE);
if (objectIndex != NULL_OBJECT_ID) {
init_train_smoke(objectIndex, pos, velocity);
}
return objectIndex;
}
+42
View File
@@ -0,0 +1,42 @@
#pragma once
#include <libultraship.h>
#include "Vehicle.h"
#include <vector>
extern "C" {
#include "main.h"
#include "vehicles.h"
}
class AVehicle; // Forward declare
class ATrain : public AVehicle {
public:
TrainCarStuff Locomotive;
TrainCarStuff Tender;
std::vector<TrainCarStuff> PassengerCars;
f32 Speed; // 120.0f is about the maximum usable value
s32 SomeFlags;
f32 SomeMultiplier;
size_t NumCars; // Non-locomotive car count?
const char* Type = "mk:train";
size_t Index; // Spawns the train in halves of the train path
int32_t SmokeParticles[128];
int32_t NextParticlePtr = 0;
int16_t AnotherSmokeTimer = 0;
int16_t SmokeTimer = 0;
explicit ATrain(size_t idx, size_t numCarriages, f32 speed, uint32_t waypoint);
virtual void Spawn() override;
virtual void BeginPlay() override;
virtual void Tick() override;
virtual void Draw(s32 playerId) override;
virtual void Collision(s32 playerId, Player* player) override;
s32 AddSmoke(s32 trainIndex, Vec3f pos, f32 velocity);
void SyncComponents(TrainCarStuff* trainCar, s16 orientationY);
};
+300
View File
@@ -0,0 +1,300 @@
#include <libultraship.h>
#include "Truck.h"
#include <vector>
extern "C" {
#include "macros.h"
#include "main.h"
#include "defines.h"
#include "code_80005FD0.h"
#include "actors.h"
#include "math_util.h"
#include "sounds.h"
#include "update_objects.h"
#include "render_player.h"
#include "external.h"
extern s8 gPlayerCount;
}
ATruck::ATruck(size_t idx, f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint) {
TrackWaypoint* temp_v0;
u16 waypointOffset;
s32 numWaypoints = gWaypointCountByPathIndex[0];
Index = idx;
waypointOffset = waypoint;
temp_v0 = &path[waypointOffset];
Position[0] = (f32) temp_v0->posX;
Position[1] = (f32) temp_v0->posY;
Position[2] = (f32) temp_v0->posZ;
ActorIndex = -1;
WaypointIndex = waypointOffset;
Velocity[0] = 0.0f;
Velocity[1] = 0.0f;
Velocity[2] = 0.0f;
if (gModeSelection == TIME_TRIALS) {
SomeType = ((Index - 1) % 3);
} else {
SomeType = random_int(3);
}
SomeMultiplierTheSequel = (f32) ((f64) (f32) (SomeType - 1) * 0.6);
if (((gCCSelection > CC_50) || (gModeSelection == TIME_TRIALS)) && (SomeType == 2)) {
Speed = speedA;
} else {
Speed = speedB;
}
Rotation[0] = 0;
Rotation[2] = 0;
if (D_8016347A == 0) {
Rotation[1] = func_8000D6D0(Position, (s16*) &WaypointIndex, Speed,
SomeMultiplierTheSequel, 0, 3);
} else {
Rotation[1] =
func_8000D940(Position, (s16*) &WaypointIndex, Speed, SomeMultiplierTheSequel, 0);
}
D_801631C8 = 10;
}
void ATruck::Spawn() {
spawn_vehicle_on_road(Position, Rotation, Velocity, WaypointIndex, SomeMultiplierTheSequel,
Speed);
ActorIndex = add_actor_to_empty_slot(Position, Rotation, Velocity, ACTOR_BOX_TRUCK);
//if (Compare(Dict[Type], "mk:bus")) {
// spawn_vehicle_on_road(Position, Rotation, Velocity, WaypointIndex, SomeMultiplierTheSequel, Speed);
// ActorIndex = add_actor_to_empty_slot(Position, Rotation,
// Velocity, ACTOR_SCHOOL_BUS);
//}
// if (Compare(Dict[Type], "mk:tanker")) {
// spawn_vehicle_on_road(tempTankerTruck);
// tempTankerTruck->actorIndex =
// add_actor_to_empty_slot(tempTankerTruck->position, tempTankerTruck->rotation,
// tempTankerTruck->velocity, ACTOR_TANKER_TRUCK);
// }
// if (Compare(Dict[Type], "mk:car")) {
// tempCar = &gCarList[loopIndex];
// spawn_vehicle_on_road(tempCar);
// tempCar->actorIndex =
// add_actor_to_empty_slot(tempCar->position, tempCar->rotation, tempCar->velocity, ACTOR_CAR);
// }
}
void ATruck::BeginPlay() {
}
void ATruck::Draw(s32 playerId) {
s32 var_v0;
s32 var_s2;
s32 waypointCount;
u16 temp_a1;
waypointCount = gWaypointCountByPathIndex[0];
if (!(gPlayers[playerId].unk_094 < 1.6666666666666667)) {
temp_a1 = WaypointIndex;
for (var_v0 = 0; var_v0 < 0x18; var_v0 += 3) {
if (((sSomeNearestWaypoint + var_v0) % waypointCount) == temp_a1) {
D_801634F8[playerId].unk4 = func_800145A8(SomeType, D_80163068[playerId], temp_a1);
return;
}
}
}
}
void ATruck::Tick() {
f32 temp_f0_2;
f32 temp_f0_3;
f32 sp5C;
f32 sp58;
f32 sp54;
f32 temp_f2_2;
s16 var_a1;
s16 thing;
Vec3f sp40;
Vec3f sp34;
sp5C = Position[0];
sp58 = Position[1];
sp54 = Position[2];
sp40[0] = sp58;
sp40[1] = 0.0f;
sp40[2] = 0.0f;
temp_f0_2 = func_80013C74(SomeType, WaypointIndex);
if (SomeMultiplierTheSequel < temp_f0_2) {
SomeMultiplierTheSequel = SomeMultiplierTheSequel + 0.06;
if (temp_f0_2 < SomeMultiplierTheSequel) {
SomeMultiplierTheSequel = temp_f0_2;
}
}
if (temp_f0_2 < SomeMultiplierTheSequel) {
SomeMultiplierTheSequel = SomeMultiplierTheSequel - 0.06;
if (SomeMultiplierTheSequel < temp_f0_2) {
SomeMultiplierTheSequel = temp_f0_2;
}
}
if (D_8016347A == 0) {
var_a1 = func_8000D6D0(Position, (s16*) &WaypointIndex, Speed,
SomeMultiplierTheSequel, 0, 3);
} else {
var_a1 = func_8000D940(Position, (s16*) &WaypointIndex, Speed,
SomeMultiplierTheSequel, 0);
}
adjust_angle(&Rotation[1], var_a1, 100);
temp_f0_3 = Position[0] - sp5C;
temp_f2_2 = Position[2] - sp54;
sp34[0] = Position[1];
sp34[1] = 0.0f;
sp34[2] = sqrtf((temp_f0_3 * temp_f0_3) + (temp_f2_2 * temp_f2_2));
thing = get_angle_between_two_vectors(sp40, sp34);
adjust_angle(&Rotation[0], -thing, 100);
Velocity[0] = Position[0] - sp5C;
Velocity[1] = Position[1] - sp58;
Velocity[2] = Position[2] - sp54;
struct Actor* vehicleActor = &gActorList[ActorIndex];
vehicleActor->pos[0] = Position[0];
vehicleActor->pos[1] = Position[1];
vehicleActor->pos[2] = Position[2];
vehicleActor->rot[0] = Rotation[0];
if (gIsMirrorMode != 0) {
vehicleActor->rot[1] = -Rotation[1];
} else {
vehicleActor->rot[1] = Rotation[1];
}
vehicleActor->rot[2] = Rotation[2];
vehicleActor->velocity[0] = Velocity[0];
vehicleActor->velocity[1] = Velocity[1];
vehicleActor->velocity[2] = Velocity[2];
}
void ATruck::Collision(s32 playerId, Player* player) {
f32 temp_f12;
f32 temp_f14;
f32 temp_f22;
f32 spC4;
f32 spC0;
f32 spBC;
if (((D_801631E0[playerId] != 1) || ((((player->type & PLAYER_HUMAN) != 0)) && !(player->type & PLAYER_KART_AI))) &&
!(player->effects & 0x01000000)) {
spC4 = player->pos[0];
spC0 = player->pos[1];
spBC = player->pos[2];
temp_f12 = spC4 - Position[0];
temp_f22 = spC0 - Position[1];
temp_f14 = spBC - Position[2];
if (((temp_f12) > -100.0) && ((temp_f12) < 100.0)) {
if ((temp_f22 > -20.0) && (temp_f22 < 20.0)) {
if (((temp_f14) > -100.0) && ((temp_f14) < 100.0)) {
if (func_80006018(Position[0], Position[2], Velocity[0],
Velocity[2], SomeArg3, SomeArg4, spC4, spBC) == (s32) 1) {
player->soundEffects |= REVERSE_SOUND_EFFECT;
}
}
}
}
if ((player->type & PLAYER_HUMAN) && !(player->type & PLAYER_KART_AI)) {
if (((temp_f12) > -300.0) && ((temp_f12) < 300.0) && ((temp_f22 > -20.0)) && (temp_f22 < 20.0) &&
(((temp_f14) > -300.0)) && ((temp_f14) < 300.0)) {
if ((D_801631C8 > 0) && (SomeFlags == 0)) {
D_801631C8 -= 1;
SomeFlags |= (RENDER_VEHICLE << playerId);
func_800C9D80(Position, Velocity, SoundBits);
}
} else {
if (SomeFlags != 0) {
SomeFlags &= ~(RENDER_VEHICLE << playerId);
if (SomeFlags == 0) {
D_801631C8 += 1;
func_800C9EF4(Position, SoundBits);
}
}
}
if (((temp_f12) > -200.0) && ((temp_f12) < 200.0) && ((temp_f22 > -20.0)) && (temp_f22 < 20.0) &&
(((temp_f14) > -200.0)) && ((temp_f14) < 200.0)) {
if (!(SomeFlagsTheSequel & ((1 << playerId)))) {
s32 var_s1 = 0;
u16 path = gWaypointCountByPathIndex[0];
s32 t1;
s32 t2;
switch (D_8016347A) {
case 0:
t1 = func_80007BF8(WaypointIndex, gNearestWaypointByPlayerId[playerId], 10, 0,
path);
if ((D_80163270[playerId] == 0) && (t1 > 0) && (player->unk_094 < Speed)) {
var_s1 = 1;
}
if ((D_80163270[playerId] == 1) && (t1 > 0)) {
var_s1 = 1;
}
break;
case 1:
t2 = func_80007BF8(WaypointIndex, gNearestWaypointByPlayerId[playerId], 0, 10,
path);
if (t2 > 0) {
if (random_int(2) == 0) {
// temp_v1_2 = D_80163270[playerId];
if (D_80163270[playerId] == 0) {
var_s1 = 1;
}
if ((D_80163270[playerId] == 1) && (player->unk_094 < Speed)) {
var_s1 = 1;
}
} else {
SomeFlagsTheSequel |= ((1 << playerId));
}
}
break;
}
if (var_s1 == 1) {
u32 soundBits2 = SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x3B);
switch (SoundBits) {
case SOUND_ARG_LOAD(0x51, 0x01, 0x80, 0x05):
soundBits2 = SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x3B);
if (random_int(4) == 0) {
soundBits2 = SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x3C);
}
break;
case SOUND_ARG_LOAD(0x51, 0x01, 0x80, 0x02):
if (random_int(2) != 0) {
soundBits2 = SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x3D);
} else {
soundBits2 = SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x3E);
}
break;
case SOUND_ARG_LOAD(0x51, 0x01, 0x80, 0x03):
if (random_int(2) != 0) {
soundBits2 = SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x3F);
} else {
soundBits2 = SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x40);
}
break;
case SOUND_ARG_LOAD(0x51, 0x01, 0x80, 0x04):
if (random_int(2) != 0) {
soundBits2 = SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x41);
} else {
soundBits2 = SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x42);
}
break;
}
SomeFlagsTheSequel |= ((1 << playerId));
func_800C98B8(Position, Velocity, soundBits2);
}
}
} else {
if (SomeFlagsTheSequel & ((1 << playerId))) {
SomeFlagsTheSequel &= ~((1 << playerId));
}
}
}
}
}
+43
View File
@@ -0,0 +1,43 @@
#pragma once
#include <libultraship.h>
#include "Vehicle.h"
#include <vector>
extern "C" {
#include "main.h"
#include "vehicles.h"
#include "waypoints.h"
#include "sounds.h"
}
class AVehicle; // Forward declare
class ATruck : public AVehicle {
public:
const char* Type;
size_t Index;
f32 Speed;
s16 ActorIndex;
Vec3f Position;
Vec3f Velocity;
Vec3s Rotation;
f32 SomeMultiplierTheSequel;
s8 SomeFlagsTheSequel = 0;
u16 WaypointIndex;
s8 SomeFlags = 0;
s16 SomeType;
f32 SomeArg3 = 55.0f;
f32 SomeArg4 = 12.5f;
u32 SoundBits = SOUND_ARG_LOAD(0x51, 0x01, 0x80, 0x03);
explicit ATruck(size_t idx, f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint);
virtual void Spawn() override;
virtual void BeginPlay() override;
virtual void Tick() override;
virtual void Draw(s32 playerId) override;
virtual void Collision(s32 playerId, Player* player) override;
};
+12
View File
@@ -0,0 +1,12 @@
#include <libultraship.h>
#include "Utils.h"
extern "C" {
#include "macros.h"
#include "defines.h"
#include "code_80005FD0.h"
}
uint32_t CalculateWaypointDistribution(size_t i, uint32_t numVehicles, size_t numWaypoints, uint32_t centerWaypoint) {
return (uint32_t)(((i * numWaypoints) / numVehicles) + centerWaypoint) % numWaypoints;
}
+5
View File
@@ -0,0 +1,5 @@
#pragma once
#include <libultraship.h>
uint32_t CalculateWaypointDistribution(size_t i, uint32_t numVehicles, size_t numWaypoints, uint32_t centerWaypoint);
+19
View File
@@ -0,0 +1,19 @@
#include "Vehicle.h"
AVehicle::AVehicle() {}
void AVehicle::Spawn() {
}
void AVehicle::BeginPlay() {
}
void AVehicle::Tick() {
}
void AVehicle::Draw(s32 playerId) {
}
void AVehicle::Collision(s32 playerId, Player* player) {
}
+27
View File
@@ -0,0 +1,27 @@
#ifndef VEHICLE_H
#define VEHICLE_H
#include <libultraship.h>
extern "C" {
#include "common_structs.h"
}
// Base class
class AVehicle {
public:
virtual ~AVehicle() = default; // Virtual destructor for proper cleanup in derived classes
explicit AVehicle();
const char* Type;
uint8_t uuid[16];
virtual void Spawn();
virtual void BeginPlay();
virtual void Tick();
virtual void Draw(s32 playerId);
virtual void Collision(s32 playerId, Player* player);
};
#endif // VEHICLE_H