diff --git a/src/code_80057C60.c b/src/code_80057C60.c index a4fb77372..d9be361fa 100644 --- a/src/code_80057C60.c +++ b/src/code_80057C60.c @@ -692,12 +692,6 @@ void render_object_for_player(s32 cameraId) { CourseManager_DrawObjects(cameraId); CM_DrawParticles(cameraId); - // CourseManager_RenderCourseObjects(cameraId); - // CourseManager_TrainSmokeDraw(cameraId); - // CourseManager_DrawThwomps(cameraId); - // CourseManager_DrawPenguins(cameraId); - // CourseManager_DrawSeagulls(cameraId); - // switch (gCurrentCourseId) { // case COURSE_MARIO_RACEWAY: // break; @@ -1287,9 +1281,6 @@ void func_80059AC8(void) { } CourseManager_TickObjects60fps(); - - CourseManager_TickThwomps(); // func_8005A71C(); - } } @@ -1579,9 +1570,6 @@ void func_8005A71C(void) { void update_object(void) { CourseManager_UpdateCourseObjects(); - // CourseManager_TrainSmokeTick(); - // CourseManager_TickPenguins(); - // CourseManager_TickSeagulls(); // switch (gCurrentCourseId) { // case COURSE_MARIO_RACEWAY: diff --git a/src/engine/Smoke.cpp b/src/engine/Smoke.cpp index 9d74397dc..9841bfffb 100644 --- a/src/engine/Smoke.cpp +++ b/src/engine/Smoke.cpp @@ -24,7 +24,7 @@ void TrainSmokeTick() { Object* object; for (auto& vehicle : gWorldInstance.Vehicles) { - if (auto train = dynamic_cast(vehicle.get())) { + if (auto train = dynamic_cast(vehicle)) { if (train->SmokeTimer != 0) { train->SmokeTimer -= 1; } @@ -48,7 +48,7 @@ void TrainSmokeTick() { train->SmokeTimer = 100; } } - } else if (auto boat = dynamic_cast(vehicle.get())) { + } else if (auto boat = dynamic_cast(vehicle)) { if (boat->SmokeTimer != 0) { boat->SmokeTimer -= 1; } @@ -79,7 +79,7 @@ void TrainSmokeTick() { void TrainSmokeDraw(s32 cameraId) { Camera* camera = &camera1[cameraId]; for (auto& vehicle : gWorldInstance.Vehicles) { - if (auto train = dynamic_cast(vehicle.get())) { + if (auto train = dynamic_cast(vehicle)) { 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); @@ -92,7 +92,7 @@ void TrainSmokeDraw(s32 cameraId) { render_object_train_smoke_particle(train->SmokeParticles[i], cameraId); } } - } else if (auto boat = dynamic_cast(vehicle.get())) { + } else if (auto boat = dynamic_cast(vehicle)) { gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D007AE0); load_texture_block_i8_nomirror((uint8_t*)D_0D029458, 32, 32); diff --git a/src/engine/TrainCrossing.cpp b/src/engine/TrainCrossing.cpp index 13232c962..98c7c766b 100644 --- a/src/engine/TrainCrossing.cpp +++ b/src/engine/TrainCrossing.cpp @@ -30,7 +30,7 @@ void TrainCrossing::CrossingTrigger() { for (const auto& vehicle : gWorldInstance.Vehicles) { - if (auto train = dynamic_cast(vehicle.get())) {; + if (auto train = dynamic_cast(vehicle)) {; f32 radius = DynamicRadius(train->Locomotive.position, train->Locomotive.velocity, Position); if (Distance(train->Locomotive.position, Position) < radius) { diff --git a/src/engine/World.cpp b/src/engine/World.cpp index 5cd85213b..ded60a262 100644 --- a/src/engine/World.cpp +++ b/src/engine/World.cpp @@ -3,14 +3,7 @@ #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 "objects/BombKart.h" -#include "objects/Penguin.h" #include "TrainCrossing.h" #include #include "objects/Object.h" @@ -40,53 +33,13 @@ 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; -static size_t thwomps; -static size_t penguins; -static size_t seagulls; -/** - * Note that you can only remove the tender if there are no carriages - * @arg waypoint initial waypoint to spawn at. - */ -void World::AddTrain(ATrain::TenderStatus tender, size_t numCarriages, f32 speed, uint32_t waypoint) { - Vehicles.push_back(std::make_unique(trains, tender, numCarriages, speed, waypoint)); - trains++; -} - -void World::AddBoat(f32 speed, uint32_t waypoint) { - Vehicles.push_back(std::make_unique(boats, speed, waypoint)); - boats++; -} - -void World::AddTruck(f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint) { - Vehicles.push_back(std::make_unique(trucks, speedA, speedB, path, waypoint)); - trucks++; -} - -void World::AddBus(f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint) { - Vehicles.push_back(std::make_unique(busses, speedA, speedB, path, waypoint)); - busses++; -} - -void World::AddTankerTruck(f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint) { - Vehicles.push_back(std::make_unique(tankerTrucks, speedA, speedB, path, waypoint)); - tankerTrucks++; -} - -void World::AddCar(f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint) { - Vehicles.push_back(std::make_unique(cars, speedA, speedB, path, waypoint)); - cars++; +AVehicle* World::AddVehicle(AVehicle* vehicle) { + Vehicles.push_back(vehicle); + return Vehicles.back(); } void World::ClearVehicles(void) { - trains = trucks = busses = tankerTrucks = cars = boats = thwomps = 0; Vehicles.clear(); } @@ -97,28 +50,7 @@ TrainCrossing* World::AddCrossing(Vec3f position, u32 waypointMin, u32 waypointM } void World::AddBombKart(Vec3f pos, TrackWaypoint* waypoint, uint16_t waypointIndex, uint16_t state, f32 unk_3C) { - BombKarts.push_back(std::make_unique(pos, waypoint, waypointIndex, state, unk_3C)); -} - -void World::AddThwomp(s16 x, s16 z, s16 direction, f32 scale, s16 behaviour, s16 primAlpha, u16 boundingBoxSize) { - Thwomps.push_back( - std::make_unique(thwomps, x, z, direction, scale, behaviour, primAlpha, boundingBoxSize)); - thwomps++; - gNumActiveThwomps = thwomps; -} - -std::shared_ptr World::AddPenguin(Vec3f pos, u16 direction, OPenguin::PenguinType type, OPenguin::Behaviour behaviour) { - auto penguin = std::make_shared(penguins, pos, direction, type, behaviour); - Penguins.push_back(penguin); - penguins++; - return penguin; -} - -std::shared_ptr World::AddSeagull(Vec3f pos) { - auto seagull = std::make_shared(seagulls, pos); - Seagulls.push_back(seagull); - seagulls++; - return seagull; + BombKarts.push_back(new OBombKart(pos, waypoint, waypointIndex, state, unk_3C)); } u32 World::GetCupIndex() { diff --git a/src/engine/World.h b/src/engine/World.h index 1aa09fb57..4fdf55bc8 100644 --- a/src/engine/World.h +++ b/src/engine/World.h @@ -102,11 +102,8 @@ class OObject; class Cup; // <-- Forward declaration class Course; class AVehicle; -class ATrain; -class ACar; +class OBombKart; class TrainCrossing; -class OThwomp; -class OSeagull; class OLakitu; class World { @@ -212,33 +209,19 @@ public: std::vector Actors; std::vector Objects; + std::vector Vehicles; + std::vector BombKarts; std::vector Emitters; std::unordered_map Lakitus; - /** Actors */ - void AddBoat(f32 speed, uint32_t waypoint); - void AddTrain(ATrain::TenderStatus tender, 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> Vehicles; + AVehicle* AddVehicle(AVehicle* vehicle); + void ClearVehicles(void); /** Objects **/ - std::vector> BombKarts; void AddBombKart(Vec3f pos, TrackWaypoint* waypoint, uint16_t waypointIndex, uint16_t state, f32 unk_3C); - std::vector> Thwomps; - void AddThwomp(s16 x, s16 z, s16 direction, f32 scale, s16 behaviour, s16 primAlpha, u16 boundingBoxSize = 7); - - std::vector> Penguins; - std::shared_ptr AddPenguin(Vec3f pos, u16 direction, OPenguin::PenguinType type, OPenguin::Behaviour behaviour); - - std::vector> Seagulls; - std::shared_ptr AddSeagull(Vec3f pos); - TrainCrossing* AddCrossing(Vec3f position, u32 waypointMin, u32 waypointMax, f32 approachRadius, f32 exitRadius); std::vector> Crossings; diff --git a/src/engine/courses/BowsersCastle.cpp b/src/engine/courses/BowsersCastle.cpp index d5766b668..49ae93385 100644 --- a/src/engine/courses/BowsersCastle.cpp +++ b/src/engine/courses/BowsersCastle.cpp @@ -7,6 +7,7 @@ #include "World.h" #include "engine/actors/AFinishline.h" #include "engine/objects/BombKart.h" +#include "engine/objects/Thwomp.h" #include "bowsers_castle_data.h" extern "C" { @@ -153,6 +154,47 @@ void BowsersCastle::SpawnActors() { 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)); + + switch (gCCSelection) { + case CC_100: + case CC_EXTRA: + gWorldInstance.AddObject(new OThwomp(0x0320, 0xf92a, 0xC000, 1.0f, 1, 0)); + gWorldInstance.AddObject(new OThwomp(0x044c, 0xf92a, 0xC000, 1.0f, 1, 1)); + gWorldInstance.AddObject(new OThwomp(0x02bc, 0xf95c, 0xC000, 1.0f, 2, 0)); + gWorldInstance.AddObject(new OThwomp(0x04b0, 0xf8f8, 0xC000, 1.0f, 2, 1)); + gWorldInstance.AddObject(new OThwomp(0x04b0, 0xf5ba, 0xC000, 1.0f, 3, 0)); + gWorldInstance.AddObject(new OThwomp(0x04b0, 0xf592, 0xC000, 1.0f, 3, 1)); + gWorldInstance.AddObject(new OThwomp(0x091a, 0xf5bf, 0xC000, 1.0f, 4, 0)); + gWorldInstance.AddObject(new OThwomp(0x091a, 0xf597, 0xC000, 1.0f, 4, 1)); + gWorldInstance.AddObject(new OThwomp(0x0596, 0xf92f, 0xC000, 1.5f, 6, 0)); + gWorldInstance.AddObject(new OThwomp(0x082a, 0xf9f2, 0x4000, 1.0f, 5, 0)); + gWorldInstance.AddObject(new OThwomp(0x073a, 0xf9f2, 0x4000, 1.0f, 5, 1)); + break; + case CC_50: + gWorldInstance.AddObject(new OThwomp(0x3B6, 0xF92A, 0xC000, 1.0f, 1, 0)); + gWorldInstance.AddObject(new OThwomp(0x0352, 0xf95c, 0xC000, 1.0f, 2, 0)); + gWorldInstance.AddObject(new OThwomp(0x04b0, 0xf5ba, 0xC000, 1.0f, 3, 0)); + gWorldInstance.AddObject(new OThwomp(0x04b0, 0xf592, 0xC000, 1.0f, 3, 1)); + gWorldInstance.AddObject(new OThwomp(0x091a, 0xf5b0, 0xC000, 1.0f, 4, 0)); + gWorldInstance.AddObject(new OThwomp(0x0596, 0xf92f, 0xC000, 1.5f, 6, 0)); + gWorldInstance.AddObject(new OThwomp(0x082a, 0xf9f2, 0x4000, 1.0f, 5, 0)); + gWorldInstance.AddObject(new OThwomp(0x073a, 0xf9f2, 0x4000, 1.0f, 5, 1)); + break; + case CC_150: + gWorldInstance.AddObject(new OThwomp(0x0320, 0xf92a, 0xC000, 1.0f, 1, 0)); + gWorldInstance.AddObject(new OThwomp(0x044c, 0xf92a, 0xC000, 1.0f, 1, 1)); + gWorldInstance.AddObject(new OThwomp(0x02bc, 0xf95c, 0xC000, 1.0f, 2, 0)); + gWorldInstance.AddObject(new OThwomp(0x04b0, 0xf8f8, 0xC000, 1.0f, 2, 1)); + gWorldInstance.AddObject(new OThwomp(0x04b0, 0xf5ba, 0xC000, 1.0f, 3, 0)); + gWorldInstance.AddObject(new OThwomp(0x04b0, 0xf592, 0xC000, 1.0f, 3, 1)); + gWorldInstance.AddObject(new OThwomp(0x091a, 0xf5c9, 0xC000, 1.0f, 4, 0)); + gWorldInstance.AddObject(new OThwomp(0x091a, 0xf5ab, 0xC000, 1.0f, 4, 1)); + gWorldInstance.AddObject(new OThwomp(0x091a, 0xf58d, 0xC000, 1.0f, 4, 2)); + gWorldInstance.AddObject(new OThwomp(0x0596, 0xf92f, 0xC000, 1.5f, 6, 0)); + gWorldInstance.AddObject(new OThwomp(0x082a, 0xf9f2, 0x4000, 1.0f, 5, 0)); + gWorldInstance.AddObject(new OThwomp(0x073a, 0xf9f2, 0x4000, 1.0f, 5, 1)); + break; + } } void BowsersCastle::SpawnVehicles() { @@ -181,47 +223,6 @@ void BowsersCastle::InitCourseObjects() { size_t objectId; size_t i; - switch (gCCSelection) { - case CC_100: - case CC_EXTRA: - gWorldInstance.AddThwomp(0x0320, 0xf92a, 0xC000, 1.0f, 1, 0); - gWorldInstance.AddThwomp(0x044c, 0xf92a, 0xC000, 1.0f, 1, 1); - gWorldInstance.AddThwomp(0x02bc, 0xf95c, 0xC000, 1.0f, 2, 0); - gWorldInstance.AddThwomp(0x04b0, 0xf8f8, 0xC000, 1.0f, 2, 1); - gWorldInstance.AddThwomp(0x04b0, 0xf5ba, 0xC000, 1.0f, 3, 0); - gWorldInstance.AddThwomp(0x04b0, 0xf592, 0xC000, 1.0f, 3, 1); - gWorldInstance.AddThwomp(0x091a, 0xf5bf, 0xC000, 1.0f, 4, 0); - gWorldInstance.AddThwomp(0x091a, 0xf597, 0xC000, 1.0f, 4, 1); - gWorldInstance.AddThwomp(0x0596, 0xf92f, 0xC000, 1.5f, 6, 0); - gWorldInstance.AddThwomp(0x082a, 0xf9f2, 0x4000, 1.0f, 5, 0); - gWorldInstance.AddThwomp(0x073a, 0xf9f2, 0x4000, 1.0f, 5, 1); - break; - case CC_50: - gWorldInstance.AddThwomp(0x3B6, 0xF92A, 0xC000, 1.0f, 1, 0); - gWorldInstance.AddThwomp(0x0352, 0xf95c, 0xC000, 1.0f, 2, 0); - gWorldInstance.AddThwomp(0x04b0, 0xf5ba, 0xC000, 1.0f, 3, 0); - gWorldInstance.AddThwomp(0x04b0, 0xf592, 0xC000, 1.0f, 3, 1); - gWorldInstance.AddThwomp(0x091a, 0xf5b0, 0xC000, 1.0f, 4, 0); - gWorldInstance.AddThwomp(0x0596, 0xf92f, 0xC000, 1.5f, 6, 0); - gWorldInstance.AddThwomp(0x082a, 0xf9f2, 0x4000, 1.0f, 5, 0); - gWorldInstance.AddThwomp(0x073a, 0xf9f2, 0x4000, 1.0f, 5, 1); - break; - case CC_150: - gWorldInstance.AddThwomp(0x0320, 0xf92a, 0xC000, 1.0f, 1, 0); - gWorldInstance.AddThwomp(0x044c, 0xf92a, 0xC000, 1.0f, 1, 1); - gWorldInstance.AddThwomp(0x02bc, 0xf95c, 0xC000, 1.0f, 2, 0); - gWorldInstance.AddThwomp(0x04b0, 0xf8f8, 0xC000, 1.0f, 2, 1); - gWorldInstance.AddThwomp(0x04b0, 0xf5ba, 0xC000, 1.0f, 3, 0); - gWorldInstance.AddThwomp(0x04b0, 0xf592, 0xC000, 1.0f, 3, 1); - gWorldInstance.AddThwomp(0x091a, 0xf5c9, 0xC000, 1.0f, 4, 0); - gWorldInstance.AddThwomp(0x091a, 0xf5ab, 0xC000, 1.0f, 4, 1); - gWorldInstance.AddThwomp(0x091a, 0xf58d, 0xC000, 1.0f, 4, 2); - gWorldInstance.AddThwomp(0x0596, 0xf92f, 0xC000, 1.5f, 6, 0); - gWorldInstance.AddThwomp(0x082a, 0xf9f2, 0x4000, 1.0f, 5, 0); - gWorldInstance.AddThwomp(0x073a, 0xf9f2, 0x4000, 1.0f, 5, 1); - break; - } - // Handle the big statue's fire breath objectId = indexObjectList2[0]; init_object(objectId, 0); diff --git a/src/engine/courses/DKJungle.cpp b/src/engine/courses/DKJungle.cpp index 941ccdb22..9daf7ad3f 100644 --- a/src/engine/courses/DKJungle.cpp +++ b/src/engine/courses/DKJungle.cpp @@ -9,6 +9,7 @@ #include "engine/objects/BombKart.h" #include "assets/dks_jungle_parkway_data.h" +#include "engine/vehicles/Boat.h" #include "engine/vehicles/Utils.h" extern "C" { @@ -278,7 +279,7 @@ void DKJungle::SpawnVehicles() { // The original game only ran vehicle logic every second frame. // Thus the speed gets divided by two to set speed to match properly - gWorldInstance.AddBoat((0.6666666f)/4, 0); + gWorldInstance.AddVehicle(new ABoat((0.6666666f)/4, 0)); if (gModeSelection == VERSUS) { Vec3f pos = {0, 0, 0}; diff --git a/src/engine/courses/KalimariDesert.cpp b/src/engine/courses/KalimariDesert.cpp index 2440e8b01..8f00441ec 100644 --- a/src/engine/courses/KalimariDesert.cpp +++ b/src/engine/courses/KalimariDesert.cpp @@ -10,6 +10,7 @@ #include "kalimari_desert_data.h" #include "engine/vehicles/Utils.h" +#include "engine/vehicles/Train.h" #include "engine/vehicles/Vehicle.h" extern "C" { @@ -237,7 +238,7 @@ void KalimariDesert::SpawnVehicles() { } } - gWorldInstance.AddTrain(_tender, _numCarriages, 2.5f, waypoint); + gWorldInstance.AddVehicle(new ATrain(_tender, _numCarriages, 2.5f, waypoint)); } if (gModeSelection == VERSUS) { diff --git a/src/engine/courses/KoopaTroopaBeach.cpp b/src/engine/courses/KoopaTroopaBeach.cpp index daaba1ad8..499a62bf7 100644 --- a/src/engine/courses/KoopaTroopaBeach.cpp +++ b/src/engine/courses/KoopaTroopaBeach.cpp @@ -158,6 +158,26 @@ void KoopaTroopaBeach::SpawnActors() { gWorldInstance.AddObject(new OCrab(FVector2D(268, 406), FVector2D(101, 394))); gWorldInstance.AddObject(new OCrab(FVector2D(223, 318), FVector2D(86, 308))); } + + if (gGamestate == CREDITS_SEQUENCE) { + for (size_t i = 0; i < NUM_SEAGULLS; i++) { + //gWorldInstance.AddObject(new OSeagull(FVector(-360.0f, 60.0f, -1300.0f))); + Vec3f pos = {-360.0f, 60.0f, -1300.0f}; + gWorldInstance.AddObject(new OSeagull(pos)); + } + } else { // Normal gameplay + for (size_t i = 0; i < 4; i++) { + Vec3f pos = {-985.0f, 15.0f, 1200.0f}; + gWorldInstance.AddObject(new OSeagull(pos)); + //gWorldInstance.AddObject(new OSeagull(FVector(-985.0f, 15.0f, 1200.0f))); + } + + for (size_t i = 0; i < 6; i++) { + //gWorldInstance.AddObject(new OSeagull(FVector(328.0f, 20.0f, 2541.0f))); + Vec3f pos2 = {328.0f, 20.0f, 2541.0f}; + gWorldInstance.AddObject(new OSeagull(pos2)); + } + } } void KoopaTroopaBeach::SpawnVehicles() { @@ -184,25 +204,6 @@ void KoopaTroopaBeach::MinimapSettings() { } void KoopaTroopaBeach::InitCourseObjects() { - size_t objectId; - size_t i; - - if (gGamestate == CREDITS_SEQUENCE) { - Vec3f pos = {-360.0f, 60.0f, -1300.0f}; - for (size_t i = 0; i < NUM_SEAGULLS; i++) { - gWorldInstance.AddSeagull(pos); - } - } else { // Normal gameplay - Vec3f pos = {-985.0f, 15.0f, 1200.0f}; - for (size_t i = 0; i < 4; i++) { - gWorldInstance.AddSeagull(pos); - } - - Vec3f pos2 = {328.0f, 20.0f, 2541.0f}; - for (size_t i = 0; i < 6; i++) { - gWorldInstance.AddSeagull(pos2); - } - } } void KoopaTroopaBeach::UpdateCourseObjects() { diff --git a/src/engine/courses/KoopaTroopaBeach.h b/src/engine/courses/KoopaTroopaBeach.h index 4dc51313e..8237b7628 100644 --- a/src/engine/courses/KoopaTroopaBeach.h +++ b/src/engine/courses/KoopaTroopaBeach.h @@ -3,6 +3,8 @@ #include #include "Course.h" +#include "World.h" + extern "C" { #include "assets/koopa_troopa_beach_vertices.h" #include "assets/koopa_troopa_beach_displaylists.h" diff --git a/src/engine/courses/SherbetLand.cpp b/src/engine/courses/SherbetLand.cpp index e14b2c7e0..0153bf0a8 100644 --- a/src/engine/courses/SherbetLand.cpp +++ b/src/engine/courses/SherbetLand.cpp @@ -134,6 +134,72 @@ void SherbetLand::SpawnActors() { gWorldInstance.AddActor(new AFinishline()); spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_sherbet_land_item_box_spawns)); + + + +// Originally, multiplayer did not spawn the big penguin +// if (gPlayerCountSelection1 == 1) { + Vec3f pos = {-383.0f, 2.0f, -690.0f}; + gWorldInstance.AddObject(new OPenguin(pos, 0, OPenguin::PenguinType::EMPEROR, OPenguin::Behaviour::STRUT)); +// } + + //! @bug Skip spawning penguins due to animation crash for now + if (gGamestate == CREDITS_SEQUENCE) { + return; + } + + Vec3f pos2 = {-2960.0f, -80.0f, 1521.0f}; + auto penguin = reinterpret_cast(gWorldInstance.AddObject(new OPenguin(pos2, 0x150, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE))); + auto penguin2 = reinterpret_cast(gWorldInstance.AddObject(new OPenguin(pos2, 0x150, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE))); + penguin->Diameter = penguin2->Diameter = 100.0f; + + Vec3f pos3 = {-2490.0f, -80.0f, 1612.0f}; + auto penguin3 = reinterpret_cast(gWorldInstance.AddObject(new OPenguin(pos3, 0x100, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE))); + auto penguin4 = reinterpret_cast(gWorldInstance.AddObject(new OPenguin(pos3, 0x100, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE))); + penguin3->Diameter = penguin4->Diameter = 80.0f; + + Vec3f pos4 = {-2098.0f, -80.0f, 1624.0f}; + auto penguin5 = reinterpret_cast(gWorldInstance.AddObject(new OPenguin(pos4, 0xFF00, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE))); + auto penguin6 = reinterpret_cast(gWorldInstance.AddObject(new OPenguin(pos4, 0xFF00, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE))); + penguin5->Diameter = penguin6->Diameter = 80.0f; + + + Vec3f pos5 = {-2080.0f, -80.0f, 1171.0f}; + auto penguin7 = reinterpret_cast(gWorldInstance.AddObject(new OPenguin(pos5, 0x150, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE))); + auto penguin8 = reinterpret_cast(gWorldInstance.AddObject(new OPenguin(pos5, 0x150, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE))); + penguin7->Diameter = penguin8->Diameter = 80.0f; + + + if (gGamestate == CREDITS_SEQUENCE) { + Vec3f pos6 = {380.0, 0.0f, -535.0f}; + auto penguin9 = reinterpret_cast(gWorldInstance.AddObject(new OPenguin(pos6, 0x9000, OPenguin::PenguinType::CREDITS, OPenguin::Behaviour::SLIDE3))); + penguin9->MirrorModeAngleOffset = -0x4000; + } else { + Vec3f pos6 = {146.0f, 0.0f, -380.0f}; + auto penguin9 = reinterpret_cast(gWorldInstance.AddObject(new OPenguin(pos6, 0x9000, OPenguin::PenguinType::CHICK, OPenguin::Behaviour::SLIDE3))); + penguin9->MirrorModeAngleOffset = -0x4000; + } + + Vec3f pos7 = {380.0f, 0.0f, -766.0f}; + auto penguin10 = reinterpret_cast(gWorldInstance.AddObject(new OPenguin(pos7, 0x5000, OPenguin::PenguinType::CHICK, OPenguin::Behaviour::SLIDE4))); + penguin10->MirrorModeAngleOffset = 0x8000; + + Vec3f pos8 = {-2300.0f, 0.0f, -210.0f}; + auto penguin11 = reinterpret_cast(gWorldInstance.AddObject(new OPenguin(pos8, 0xC000, OPenguin::PenguinType::CHICK, OPenguin::Behaviour::SLIDE6))); + penguin11->MirrorModeAngleOffset = 0x8000; + + Vec3f pos9 = {-2500.0f, 0.0f, -250.0f}; + auto penguin12 = reinterpret_cast(gWorldInstance.AddObject(new OPenguin(pos9, 0x4000, OPenguin::PenguinType::CHICK, OPenguin::Behaviour::SLIDE6))); + penguin12->MirrorModeAngleOffset = 0x8000; + + Vec3f pos10 = {-535.0f, 0.0f, 875.0f}; + auto penguin13 = reinterpret_cast(gWorldInstance.AddObject(new OPenguin(pos10, 0x8000, OPenguin::PenguinType::CHICK, OPenguin::Behaviour::SLIDE6))); + penguin13->MirrorModeAngleOffset = -0x4000; + + Vec3f pos11 = {-250.0f, 0.0f, 953.0f}; + auto penguin14 = reinterpret_cast(gWorldInstance.AddObject(new OPenguin(pos11, 0x9000, OPenguin::PenguinType::CHICK, OPenguin::Behaviour::SLIDE6))); + penguin14->MirrorModeAngleOffset = -0x4000; + } void SherbetLand::SpawnVehicles() { @@ -163,69 +229,6 @@ void SherbetLand::MinimapSettings() { } void SherbetLand::InitCourseObjects() { - //! @bug Skip spawning penguins due to animation crash for now - if (gGamestate == CREDITS_SEQUENCE) { - return; - } - -// Originally, multiplayer did not spawn the big penguin -// if (gPlayerCountSelection1 == 1) { - Vec3f pos = {-383.0f, 2.0f, -690.0f}; - gWorldInstance.AddPenguin(pos, 0, OPenguin::PenguinType::EMPEROR, OPenguin::Behaviour::STRUT); -// } - - - Vec3f pos2 = {-2960.0f, -80.0f, 1521.0f}; - auto penguin = gWorldInstance.AddPenguin(pos2, 0x150, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE); - auto penguin2 = gWorldInstance.AddPenguin(pos2, 0x150, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE); - penguin->Diameter = penguin2->Diameter = 100.0f; - - Vec3f pos3 = {-2490.0f, -80.0f, 1612.0f}; - auto penguin3 = gWorldInstance.AddPenguin(pos3, 0x100, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE); - auto penguin4 = gWorldInstance.AddPenguin(pos3, 0x100, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE); - penguin3->Diameter = penguin4->Diameter = 80.0f; - - Vec3f pos4 = {-2098.0f, -80.0f, 1624.0f}; - auto penguin5 = gWorldInstance.AddPenguin(pos4, 0xFF00, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE); - auto penguin6 = gWorldInstance.AddPenguin(pos4, 0xFF00, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE); - penguin5->Diameter = penguin6->Diameter = 80.0f; - - - Vec3f pos5 = {-2080.0f, -80.0f, 1171.0f}; - auto penguin7 = gWorldInstance.AddPenguin(pos5, 0x150, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE); - auto penguin8 = gWorldInstance.AddPenguin(pos5, 0x150, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE); - penguin7->Diameter = penguin8->Diameter = 80.0f; - - - if (gGamestate == CREDITS_SEQUENCE) { - Vec3f pos6 = {380.0, 0.0f, -535.0f}; - auto penguin9 = gWorldInstance.AddPenguin(pos6, 0x9000, OPenguin::PenguinType::CREDITS, OPenguin::Behaviour::SLIDE3); - penguin9->MirrorModeAngleOffset = -0x4000; - } else { - Vec3f pos6 = {146.0f, 0.0f, -380.0f}; - auto penguin9 = gWorldInstance.AddPenguin(pos6, 0x9000, OPenguin::PenguinType::CHICK, OPenguin::Behaviour::SLIDE3); - penguin9->MirrorModeAngleOffset = -0x4000; - } - - Vec3f pos7 = {380.0f, 0.0f, -766.0f}; - auto penguin10 = gWorldInstance.AddPenguin(pos7, 0x5000, OPenguin::PenguinType::CHICK, OPenguin::Behaviour::SLIDE4); - penguin10->MirrorModeAngleOffset = 0x8000; - - Vec3f pos8 = {-2300.0f, 0.0f, -210.0f}; - auto penguin11 = gWorldInstance.AddPenguin(pos8, 0xC000, OPenguin::PenguinType::CHICK, OPenguin::Behaviour::SLIDE6); - penguin11->MirrorModeAngleOffset = 0x8000; - - Vec3f pos9 = {-2500.0f, 0.0f, -250.0f}; - auto penguin12 = gWorldInstance.AddPenguin(pos9, 0x4000, OPenguin::PenguinType::CHICK, OPenguin::Behaviour::SLIDE6); - penguin12->MirrorModeAngleOffset = 0x8000; - - Vec3f pos10 = {-535.0f, 0.0f, 875.0f}; - auto penguin13 = gWorldInstance.AddPenguin(pos10, 0x8000, OPenguin::PenguinType::CHICK, OPenguin::Behaviour::SLIDE6); - penguin13->MirrorModeAngleOffset = -0x4000; - - Vec3f pos11 = {-250.0f, 0.0f, 953.0f}; - auto penguin14 = gWorldInstance.AddPenguin(pos11, 0x9000, OPenguin::PenguinType::CHICK, OPenguin::Behaviour::SLIDE6); - penguin14->MirrorModeAngleOffset = -0x4000; } void SherbetLand::UpdateCourseObjects() { diff --git a/src/engine/courses/ToadsTurnpike.cpp b/src/engine/courses/ToadsTurnpike.cpp index 4acdcd466..47ed10111 100644 --- a/src/engine/courses/ToadsTurnpike.cpp +++ b/src/engine/courses/ToadsTurnpike.cpp @@ -8,6 +8,10 @@ #include "engine/objects/BombKart.h" #include "assets/toads_turnpike_data.h" #include "engine/actors/AFinishline.h" +#include "engine/vehicles/Bus.h" +#include "engine/vehicles/Car.h" +#include "engine/vehicles/Truck.h" +#include "engine/vehicles/TankerTruck.h" #include "engine/vehicles/Utils.h" @@ -257,22 +261,22 @@ void ToadsTurnpike::SpawnVehicles() { for (size_t i = 0; i < _numTrucks; i++) { waypoint = CalculateWaypointDistribution(i, _numTrucks, gWaypointCountByPathIndex[0], 0); - gWorldInstance.AddTruck(a, b, &D_80164550[0][0], waypoint); + gWorldInstance.AddVehicle(new ATruck(a, b, &D_80164550[0][0], waypoint)); } for (size_t i = 0; i < _numBuses; i++) { waypoint = CalculateWaypointDistribution(i, _numBuses, gWaypointCountByPathIndex[0], 75); - gWorldInstance.AddBus(a, b,&D_80164550[0][0], waypoint); + gWorldInstance.AddVehicle(new ABus(a, b,&D_80164550[0][0], waypoint)); } for (size_t i = 0; i < _numTankerTrucks; i++) { waypoint = CalculateWaypointDistribution(i, _numTankerTrucks, gWaypointCountByPathIndex[0], 50); - gWorldInstance.AddTankerTruck(a, b, &D_80164550[0][0], waypoint); + gWorldInstance.AddVehicle(new ATankerTruck(a, b, &D_80164550[0][0], waypoint)); } for (size_t i = 0; i < _numCars; i++) { waypoint = CalculateWaypointDistribution(i, _numCars, gWaypointCountByPathIndex[0], 25); - gWorldInstance.AddCar(a, b, &D_80164550[0][0], waypoint); + gWorldInstance.AddVehicle(new ACar(a, b, &D_80164550[0][0], waypoint)); } if (gModeSelection == VERSUS) { diff --git a/src/engine/objects/BombKart.cpp b/src/engine/objects/BombKart.cpp index 42506f826..c33b4b107 100644 --- a/src/engine/objects/BombKart.cpp +++ b/src/engine/objects/BombKart.cpp @@ -26,8 +26,10 @@ extern "C" { extern s8 gPlayerCount; } -OBombKart::OBombKart(Vec3f pos, TrackWaypoint* waypoint, uint16_t waypointIndex, uint16_t state, f32 unk_3C) { +size_t OBombKart::_count = 0; +OBombKart::OBombKart(Vec3f pos, TrackWaypoint* waypoint, uint16_t waypointIndex, uint16_t state, f32 unk_3C) { + _idx = _count; Vec3f _pos = {0, 0, 0}; if (waypoint) { // Spawn kart on waypoint @@ -68,6 +70,8 @@ OBombKart::OBombKart(Vec3f pos, TrackWaypoint* waypoint, uint16_t waypointIndex, WheelPos[3][1] = _pos[1]; WheelPos[3][2] = _pos[2]; check_bounding_collision(&_Collision, 2.0f, _pos[0], _pos[1], _pos[2]); + + _count++; } void OBombKart::Spawn() { @@ -334,9 +338,7 @@ void OBombKart::Draw(s32 cameraId) { } if (GetCourse() == GetPodiumCeremony()) { - // This isn't functionally equivallent. - // Technicaly it should be if (kart[0].WaypointIndex < 16) - if (WaypointIndex < 16) { + if ((_idx == 0) && (WaypointIndex < 16)) { return; } else { cameraId = PLAYER_FOUR; diff --git a/src/engine/objects/BombKart.h b/src/engine/objects/BombKart.h index 4500e41c2..7ceba7ecb 100644 --- a/src/engine/objects/BombKart.h +++ b/src/engine/objects/BombKart.h @@ -5,6 +5,8 @@ #include #include "engine/Matrix.h" +#include "World.h" + extern "C" { #include "macros.h" #include "main.h" @@ -53,16 +55,26 @@ public: // Set waypoint to NULL if using a spawn position and not a waypoint. explicit OBombKart(Vec3f pos, TrackWaypoint* waypoint, uint16_t waypointIndex, uint16_t state, f32 unk_3C); + ~OBombKart() { + _count--; + } + + static size_t GetCount() { + return _count; + } + void Spawn(); void BeginPlay(); void Tick(); - void Draw(s32 playerId); + void Draw(s32 cameraId); void DrawBattle(s32 cameraId); void Collision(s32 playerId, Player* player); void SomeRender(Vec3f arg1); void LoadMtx(); void Waypoint(s32 screenId); private: + static size_t _count; + s32 _idx; Player* FindTarget(); void Chase(Player*, Vec3f pos); diff --git a/src/engine/objects/Hedgehog.h b/src/engine/objects/Hedgehog.h index dab8cf15a..2057d894d 100644 --- a/src/engine/objects/Hedgehog.h +++ b/src/engine/objects/Hedgehog.h @@ -4,7 +4,7 @@ #include #include "Object.h" -#include "World.h" +#include "engine/World.h" extern "C" { #include "macros.h" diff --git a/src/engine/objects/Penguin.cpp b/src/engine/objects/Penguin.cpp index c126174a1..c690e1ef2 100644 --- a/src/engine/objects/Penguin.cpp +++ b/src/engine/objects/Penguin.cpp @@ -33,16 +33,19 @@ extern "C" { extern s8 gPlayerCount; } -OPenguin::OPenguin(s32 i, Vec3f pos, u16 direction, PenguinType type, Behaviour behaviour) { - if (i >= 32) { - printf("MAX penguin REACHED (32), skipping\n"); - return; - } - _idx = i; +size_t OPenguin::_count = 0; + +OPenguin::OPenguin(Vec3f pos, u16 direction, PenguinType type, Behaviour behaviour) { + _idx = _count; _type = type; _bhv = behaviour; - s32 objectIndex = indexObjectList1[i]; + if (_idx >= 32) { + printf("MAX penguin REACHED (32), skipping\n"); + return; + } + + s32 objectIndex = indexObjectList1[_idx]; init_object(objectIndex, 0); Object *object = &gObjectList[objectIndex]; @@ -73,6 +76,7 @@ OPenguin::OPenguin(s32 i, Vec3f pos, u16 direction, PenguinType type, Behaviour break; } + _count++; } void OPenguin::Tick(void) { diff --git a/src/engine/objects/Penguin.h b/src/engine/objects/Penguin.h index 0e9c36f49..63c2207c1 100644 --- a/src/engine/objects/Penguin.h +++ b/src/engine/objects/Penguin.h @@ -2,6 +2,8 @@ #include #include +#include "engine/World.h" +#include "engine/objects/Object.h" extern "C" { #include "macros.h" @@ -13,7 +15,7 @@ extern "C" { #include "course_offsets.h" } -class OPenguin { +class OPenguin : public OObject { public: enum PenguinType : uint32_t { CHICK, @@ -36,10 +38,19 @@ public: f32 Diameter = 0.0f; // Waddle in a circle around the spawn point at this diameter. uint16_t MirrorModeAngleOffset; - explicit OPenguin(s32 i, Vec3f pos, u16 direction, PenguinType type, Behaviour behaviour); + explicit OPenguin(Vec3f pos, u16 direction, PenguinType type, Behaviour behaviour); - void Tick(); - void Draw(s32 playerId); + ~OPenguin() { + _count--; + } + + static size_t GetCount() { + return _count; + } + + + virtual void Tick() override; + virtual void Draw(s32 cameraId) override; private: void Behaviours(s32 objectIndex, s32 arg1); void EmperorPenguin(s32 objectIndex); @@ -51,7 +62,7 @@ private: void OtherPenguin(s32 objectIndex); void InitOtherPenguin(s32 objectIndex); - + static size_t _count; s32 _idx; PenguinType _type; Behaviour _bhv; diff --git a/src/engine/objects/Seagull.cpp b/src/engine/objects/Seagull.cpp index 5f0b12a7e..cced70348 100644 --- a/src/engine/objects/Seagull.cpp +++ b/src/engine/objects/Seagull.cpp @@ -1,8 +1,8 @@ #include #include #include "Seagull.h" -#include "engine/Actor.h" #include +#include "World.h" #include "port/Game.h" @@ -29,9 +29,14 @@ extern SplineData D_800E6280; SplineData* D_800E633C[] = { &D_800E6034, &D_800E60F0, &D_800E61B4, &D_800E6280 }; -OSeagull::OSeagull(s32 i, Vec3f pos) { - size_t objectId; - _idx = i; +size_t OSeagull::_count = 0; + +OSeagull::OSeagull(Vec3f pos) { + size_t objectIndex; + _idx = _count; + _pos[0] = pos[0]; + _pos[1] = pos[1]; + _pos[2] = pos[2]; s16 randZ; s16 randX; @@ -40,60 +45,48 @@ OSeagull::OSeagull(s32 i, Vec3f pos) { randY = random_int(20); randZ = random_int(200) + -100.0; - SpawnPos[0] = pos[0] + randX; - SpawnPos[1] = pos[1] + randY; - SpawnPos[2] = pos[2] + randZ; - //for (i = 0; i < NUM_SEAGULLS; i++) { - //objectId = indexObjectList2[i]; - //init_object(objectId, 0); + objectIndex = indexObjectList2[_idx]; + init_object(objectIndex, 0); - //set_obj_origin_pos(objectId, pos[0], pos[1], pos[2]); - //if (i < (NUM_SEAGULLS / 2)) { - //gObjectList[objectId].unk_0D5 = 0; - //} else { - // gObjectList[objectId].unk_0D5 = 1; - //} - //} + set_obj_origin_pos(objectIndex, pos[0], pos[1], pos[2]); + if (_idx < (NUM_SEAGULLS / 2)) { + gObjectList[objectIndex].unk_0D5 = 0; + } else { + gObjectList[objectIndex].unk_0D5 = 1; + } + + _count++; } -bool OSeagull::IsMod() { return true; } - void OSeagull::Tick() { Object* object; - UNUSED s32* var_s4; - s32 temp_s0; + s32 objectIndex = indexObjectList2[_idx]; - //for (var_s3 = 0; var_s3 < NUM_SEAGULLS; var_s3++) { - //temp_s0 = indexObjectList2[_idx]; - - //object = &gObjectList[temp_s0]; - if (_state == 0) { + object = &gObjectList[objectIndex]; + if (object->state == 0) { return; } - OSeagull::func_80082714(temp_s0, _idx); - OSeagull::func_8008275C(temp_s0); - if (_toggle) { - _toggle = false; + OSeagull::func_80082714(objectIndex, _idx); + OSeagull::func_8008275C(objectIndex); + if (func_80072320(objectIndex, 2) != 0) { + func_800722CC(objectIndex, 2); if (D_80165A90 != 0) { D_80165A90 = 0; D_80183E40[0] = 0.0f; D_80183E40[1] = 0.0f; D_80183E40[2] = 0.0f; if (gGamestate != CREDITS_SEQUENCE) { - func_800C98B8(Pos, D_80183E40, SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x43)); + func_800C98B8(object->pos, D_80183E40, SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x43)); } else { - //temp_s0 = indexObjectList2[1]; - //! @todo confirm this is equivallent to indexObjectList2[1]; - if (_idx == 1) { - if (gCutsceneShotTimer <= 150) { - //object = &gObjectList[temp_s0]; - func_800C98B8(Pos, D_80183E40, SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x43)); - } + objectIndex = indexObjectList2[1]; + if (gCutsceneShotTimer <= 150) { + object = &gObjectList[objectIndex]; + func_800C98B8(object->pos, D_80183E40, SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x43)); } } } @@ -114,19 +107,16 @@ void OSeagull::Tick() { D_80165908 = 0; } -void OSeagull::Draw(Camera* camera) { // render_object_seagulls - s32 var_s1; - //for (i = 0; i < NUM_SEAGULLS; i++) { - var_s1 = indexObjectList2[_idx]; - //! @todo: Quick hack to let seagull work in actor system. Should be cameraId not camera->playerId - //if (func_8008A364(var_s1, camera->playerId, 0x5555U, 0x000005DC) < 0x9C401 && CVarGetInteger("gNoCulling", 0) == 0) { - D_80165908 = 1; - _toggle = true; - //} - //if (is_obj_flag_status_active(var_s1, VISIBLE) != 0) { - OSeagull::func_800552BC(var_s1); - //} - //} +void OSeagull::Draw(s32 cameraId) { // render_object_seagulls + s32 objectIndex = indexObjectList2[_idx]; + + if (func_8008A364(objectIndex, cameraId, 0x5555U, 0x000005DC) < 0x9C401 && CVarGetInteger("gNoCulling", 0) == 0) { + D_80165908 = 1; + _toggle = true; + } + if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) { + OSeagull::func_800552BC(objectIndex); + } } void OSeagull::func_800552BC(s32 objectIndex) { @@ -155,11 +145,11 @@ void OSeagull::func_8008275C(s32 objectIndex) { case 2: func_8008B78C(objectIndex); vec3f_copy(gObjectList[objectIndex].unk_01C, gObjectList[objectIndex].pos); - func_8000D940(SpawnPos, (s16*) &gObjectList[objectIndex].unk_0C6, + func_8000D940(gObjectList[objectIndex].origin_pos, (s16*) &gObjectList[objectIndex].unk_0C6, gObjectList[objectIndex].unk_034, 0.0f, 0); - Offset[0] *= 2.0; - Offset[1] *= 2.5; - Offset[2] *= 2.0; + gObjectList[objectIndex].offset[0] *= 2.0; + gObjectList[objectIndex].offset[1] *= 2.5; + gObjectList[objectIndex].offset[2] *= 2.0; object_calculate_new_pos_offset(objectIndex); gObjectList[objectIndex].direction_angle[1] = get_angle_between_two_vectors(gObjectList[objectIndex].unk_01C, gObjectList[objectIndex].pos); @@ -169,31 +159,26 @@ void OSeagull::func_8008275C(s32 objectIndex) { } void OSeagull::func_8008241C(s32 objectIndex, s32 arg1) { - UNUSED s16 stackPadding0; + s16 randZ; + s16 randX; + s16 randY; gObjectList[objectIndex].unk_0D8 = 1; gObjectList[objectIndex].model = (Gfx*) d_course_koopa_troopa_beach_unk4; gObjectList[objectIndex].vertex = (Vtx*) d_course_koopa_troopa_beach_unk_data5; gObjectList[objectIndex].sizeScaling = 0.2f; gObjectList[objectIndex].unk_0DD = 1; - // if (gGamestate == CREDITS_SEQUENCE) { - // set_obj_origin_pos(objectIndex, randX + -360.0, randY + 60.0, randZ + -1300.0); - // } else if (gObjectList[objectIndex].unk_0D5 != 0) { - // set_obj_origin_pos(objectIndex, (randX + 328.0) * xOrientation, randY + 20.0, randZ + 2541.0); - // } else { - // set_obj_origin_pos(objectIndex, (randX + -985.0) * xOrientation, randY + 15.0, randZ + 1200.0); - // } + randX = random_int(0x00C8) + -100.0; + randY = random_int(0x0014); + randZ = random_int(0x00C8) + -100.0; + + set_obj_origin_pos(objectIndex, (randX + _pos[0]) * xOrientation, randY + _pos[1], randZ + _pos[2]); set_obj_direction_angle(objectIndex, 0U, 0U, 0U); gObjectList[objectIndex].unk_034 = 1.0f; func_80086EF0(objectIndex); - //gObjectList[objectIndex].spline = D_800E633C[arg1 % 4]; - spline = D_800E633C[arg1 % 4]; - //set_object_flag(objectIndex, 0x800); - //object_next_state(objectIndex); - _status |= 0x800; - _timer = 0; - _status &= ~0x2000; - _state++; + gObjectList[objectIndex].spline = D_800E633C[arg1 % 4]; + set_object_flag(objectIndex, 0x00000800); + object_next_state(objectIndex); } diff --git a/src/engine/objects/Seagull.h b/src/engine/objects/Seagull.h index 528da0708..d575e3721 100644 --- a/src/engine/objects/Seagull.h +++ b/src/engine/objects/Seagull.h @@ -2,7 +2,9 @@ #include #include -#include "engine/Actor.h" +#include "Object.h" + +#include "engine/World.h" extern "C" { #include "macros.h" @@ -11,34 +13,34 @@ extern "C" { #include "waypoints.h" #include "common_structs.h" #include "objects.h" -#include "course_offsets.h" -#include "some_data.h" +#include "camera.h" } -class OSeagull : public AActor { +class OSeagull : public OObject { public: - enum Behaviour : uint16_t { - }; + explicit OSeagull(Vec3f pos); -public: - explicit OSeagull(s32 i, Vec3f pos); + ~OSeagull() { + _count--; + } + + static size_t GetCount() { + return _count; + } virtual void Tick() override; - virtual void Draw(Camera*) override; + virtual void Draw(s32 cameraId) override; + void func_800552BC(s32 objectIndex); void func_8008275C(s32 objectIndex); void func_8008241C(s32 objectIndex, s32 arg1); void func_80082714(s32 objectIndex, s32 arg1); - virtual bool IsMod() override; - Vec3f Offset; - Vec3f SpawnPos; private: + Vec3f _pos; + static size_t _count; s32 _idx; - s32 _state; - s32 _timer; - s32 _status; bool _toggle; SplineData *spline; diff --git a/src/engine/objects/Thwomp.cpp b/src/engine/objects/Thwomp.cpp index 87d670cfd..afa12b03b 100644 --- a/src/engine/objects/Thwomp.cpp +++ b/src/engine/objects/Thwomp.cpp @@ -44,16 +44,19 @@ f32 D_800E594C[][2] = { s16 D_800E597C[] = { 0x0000, 0x0000, 0x4000, 0x8000, 0x8000, 0xc000 }; -OThwomp::OThwomp(s32 i, s16 x, s16 z, s16 direction, f32 scale, s16 behaviour, s16 primAlpha, u16 boundingBoxSize) { - if (i >= 32) { - printf("MAX THWOMPS REACHED (32), skipping\n"); - return; - } - _idx = i; +size_t OThwomp::_count = 0; + +OThwomp::OThwomp(s16 x, s16 z, s16 direction, f32 scale, s16 behaviour, s16 primAlpha, u16 boundingBoxSize) { + _idx = _count; _faceDirection = direction; _boundingBoxSize = boundingBoxSize; State = (States)behaviour; - s32 objectId = indexObjectList1[i]; + + if (_idx >= 32) { + printf("MAX THWOMPS REACHED (32), skipping\n"); + return; + } + s32 objectId = indexObjectList1[_idx]; init_object(objectId, 0); gObjectList[objectId].origin_pos[0] = x * xOrientation; gObjectList[objectId].origin_pos[2] = z; @@ -66,9 +69,11 @@ OThwomp::OThwomp(s32 i, s16 x, s16 z, s16 direction, f32 scale, s16 behaviour, s } gObjectList[objectId].sizeScaling = scale; + + _count++; } -void OThwomp::Tick() { // func_80081210 +void OThwomp::Tick60fps() { // func_80081210 Player* player; s32 objectIndex; s32 var_s2_3; @@ -80,6 +85,13 @@ void OThwomp::Tick() { // func_80081210 OThwomp::func_8007F8D8(); + // Tick lights only one time. This gets applied to every thwomp. + // Running this more than once per frame will result in the lights moving at a high rate of speed. + if (_idx == 0) { + D_80165834[0] += 0x100; + D_80165834[1] += 0x200; + } + objectIndex = indexObjectList1[_idx]; if (gObjectList[objectIndex].state != 0) { switch (State) { diff --git a/src/engine/objects/Thwomp.h b/src/engine/objects/Thwomp.h index f64318e4d..22c674bb5 100644 --- a/src/engine/objects/Thwomp.h +++ b/src/engine/objects/Thwomp.h @@ -3,6 +3,9 @@ #include #include +#include "engine/World.h" +#include "engine/objects/Object.h" + extern "C" { #include "macros.h" #include "main.h" @@ -27,7 +30,7 @@ extern "C" { * @arg primAlpha unknown * @arg boundingBoxSize optional. The size of the bounding box for the thwomp. Default value is 12 */ -class OThwomp { +class OThwomp : public OObject { private: enum States : uint16_t { DISABLED, @@ -42,12 +45,20 @@ private: public: States State = States::DISABLED; - explicit OThwomp(s32 i, s16 x, s16 z, s16 direction, f32 scale, s16 behaviour, s16 primAlpha, u16 boundingBoxSize); + explicit OThwomp(s16 x, s16 z, s16 direction, f32 scale, s16 behaviour, s16 primAlpha, u16 boundingBoxSize = 7); - void Tick(); + ~OThwomp() { + _count--; + } + + static size_t GetCount() { + return _count; + } + + virtual void Tick60fps() override; + virtual void Draw(s32 cameraId) override; void SetVisibility(s32 objectIndex); void func_80080B28(s32 objectIndex, s32 playerId); - void Draw(s32 playerId); void DrawModel(s32); void TranslateThwompLights(); void ThwompLights(s32 objectIndex); @@ -100,6 +111,7 @@ public: void func_8007E63C(s32 objectIndex); private: + static size_t _count; s32 _idx; s16 _faceDirection; //! @todo Write this better. This effects the squish size and the bounding box size. diff --git a/src/engine/vehicles/Boat.cpp b/src/engine/vehicles/Boat.cpp index c1d7803bb..6a3c2beb1 100644 --- a/src/engine/vehicles/Boat.cpp +++ b/src/engine/vehicles/Boat.cpp @@ -14,10 +14,12 @@ extern "C" { extern s8 gPlayerCount; } -ABoat::ABoat(size_t idx, f32 speed, u32 waypoint) { +size_t ABoat::_count = 0; + +ABoat::ABoat(f32 speed, u32 waypoint) { Path2D* temp_a2; u16 waypointOffset; - Index = idx; + Index = _count; Speed = speed; // Set to the default value @@ -36,6 +38,8 @@ ABoat::ABoat(size_t idx, f32 speed, u32 waypoint) { Velocity[0] = 0.0f; Velocity[1] = 0.0f; Velocity[2] = 0.0f; + + _count++; } void ABoat::Spawn() { diff --git a/src/engine/vehicles/Boat.h b/src/engine/vehicles/Boat.h index 988f498ab..4a1e2d124 100644 --- a/src/engine/vehicles/Boat.h +++ b/src/engine/vehicles/Boat.h @@ -30,7 +30,15 @@ class ABoat : public AVehicle { int16_t AnotherSmokeTimer = 0; int16_t SmokeTimer = 0; - explicit ABoat(size_t idx, f32 speed, uint32_t waypoint); + explicit ABoat(f32 speed, uint32_t waypoint); + + ~ABoat() { + _count--; + } + + static size_t GetCount() { + return _count; + } virtual void Spawn() override; virtual void BeginPlay() override; @@ -38,5 +46,7 @@ class ABoat : public AVehicle { virtual void Draw(s32 playerId) override; virtual void Collision(s32 playerId, Player* player) override; virtual s32 AddSmoke(size_t, Vec3f, f32); +private: + static size_t _count; }; \ No newline at end of file diff --git a/src/engine/vehicles/Bus.cpp b/src/engine/vehicles/Bus.cpp index 36bb576c6..c8b81b4c5 100644 --- a/src/engine/vehicles/Bus.cpp +++ b/src/engine/vehicles/Bus.cpp @@ -16,12 +16,14 @@ extern "C" { extern s8 gPlayerCount; } -ABus::ABus(size_t idx, f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint) { +size_t ABus::_count = 0; + +ABus::ABus(f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint) { TrackWaypoint* temp_v0; u16 waypointOffset; s32 numWaypoints = gWaypointCountByPathIndex[0]; - Index = idx; + Index = _count; waypointOffset = waypoint; temp_v0 = &path[waypointOffset]; @@ -54,6 +56,8 @@ ABus::ABus(size_t idx, f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t way func_8000D940(Position, (s16*) &WaypointIndex, Speed, SomeMultiplierTheSequel, 0); } D_801631C8 = 10; + + _count++; } void ABus::Spawn() { diff --git a/src/engine/vehicles/Bus.h b/src/engine/vehicles/Bus.h index ff75d5aff..a7ba3d3e5 100644 --- a/src/engine/vehicles/Bus.h +++ b/src/engine/vehicles/Bus.h @@ -33,11 +33,22 @@ class ABus : public AVehicle { 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); + explicit ABus(f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint); + + ~ABus() { + _count--; + } + + static size_t GetCount() { + return _count; + } 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; + +private: + static size_t _count; }; \ No newline at end of file diff --git a/src/engine/vehicles/Car.cpp b/src/engine/vehicles/Car.cpp index 604fe5f2f..8f8d24d1f 100644 --- a/src/engine/vehicles/Car.cpp +++ b/src/engine/vehicles/Car.cpp @@ -16,12 +16,14 @@ extern "C" { extern s8 gPlayerCount; } -ACar::ACar(size_t idx, f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint) { +size_t ACar::_count = 0; + +ACar::ACar(f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint) { TrackWaypoint* temp_v0; u16 waypointOffset; s32 numWaypoints = gWaypointCountByPathIndex[0]; - Index = idx; + Index = _count; waypointOffset = waypoint; temp_v0 = &path[waypointOffset]; @@ -54,6 +56,8 @@ ACar::ACar(size_t idx, f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t way func_8000D940(Position, (s16*) &WaypointIndex, Speed, SomeMultiplierTheSequel, 0); } D_801631C8 = 10; + + _count++; } void ACar::Spawn() { diff --git a/src/engine/vehicles/Car.h b/src/engine/vehicles/Car.h index 8ac7421aa..6613e4c56 100644 --- a/src/engine/vehicles/Car.h +++ b/src/engine/vehicles/Car.h @@ -16,7 +16,15 @@ class AVehicle; // Forward declare class ACar : public AVehicle { public: - explicit ACar(size_t idx, f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint); + explicit ACar(f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint); + + ~ACar() { + _count--; + } + + static size_t GetCount() { + return _count; + } const char* Type; size_t Index; @@ -40,4 +48,6 @@ class ACar : public AVehicle { virtual void Tick() override; virtual void Draw(s32 playerId) override; virtual void Collision(s32 playerId, Player* player) override; +private: + static size_t _count; }; \ No newline at end of file diff --git a/src/engine/vehicles/TankerTruck.cpp b/src/engine/vehicles/TankerTruck.cpp index 8acd7984c..2c32d5bd6 100644 --- a/src/engine/vehicles/TankerTruck.cpp +++ b/src/engine/vehicles/TankerTruck.cpp @@ -16,12 +16,14 @@ extern "C" { extern s8 gPlayerCount; } -ATankerTruck::ATankerTruck(size_t idx, f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint) { +size_t ATankerTruck::_count = 0; + +ATankerTruck::ATankerTruck(f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint) { TrackWaypoint* temp_v0; u16 waypointOffset; s32 numWaypoints = gWaypointCountByPathIndex[0]; - Index = idx; + Index = _count; waypointOffset = waypoint; temp_v0 = &path[waypointOffset]; @@ -54,6 +56,8 @@ ATankerTruck::ATankerTruck(size_t idx, f32 speedA, f32 speedB, TrackWaypoint* pa func_8000D940(Position, (s16*) &WaypointIndex, Speed, SomeMultiplierTheSequel, 0); } D_801631C8 = 10; + + _count++; } void ATankerTruck::Spawn() { diff --git a/src/engine/vehicles/TankerTruck.h b/src/engine/vehicles/TankerTruck.h index 961d5a0fb..fdf838d99 100644 --- a/src/engine/vehicles/TankerTruck.h +++ b/src/engine/vehicles/TankerTruck.h @@ -33,11 +33,22 @@ class ATankerTruck : public AVehicle { 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); + explicit ATankerTruck(f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint); + + ~ATankerTruck() { + _count--; + } + + static size_t GetCount() { + return _count; + } 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; + +private: + static size_t _count; }; \ No newline at end of file diff --git a/src/engine/vehicles/Train.cpp b/src/engine/vehicles/Train.cpp index c34ac1cf3..0e9af21ed 100644 --- a/src/engine/vehicles/Train.cpp +++ b/src/engine/vehicles/Train.cpp @@ -22,12 +22,14 @@ extern "C" { // #include "common_structs.h" } -ATrain::ATrain(size_t idx, ATrain::TenderStatus tender, size_t numCarriages, f32 speed, uint32_t waypoint) { +size_t ATrain::_count = 0; + +ATrain::ATrain(ATrain::TenderStatus tender, size_t numCarriages, f32 speed, uint32_t waypoint) { u16 waypointOffset; TrainCarStuff* ptr1; Path2D* pos; - Index = idx; + Index = _count; Speed = speed; // Set to the default value @@ -73,6 +75,8 @@ ATrain::ATrain(size_t idx, ATrain::TenderStatus tender, size_t numCarriages, f32 NumCars = NUM_TENDERS + numCarriages; AnotherSmokeTimer = 0; + + _count++; } void ATrain::Spawn() { diff --git a/src/engine/vehicles/Train.h b/src/engine/vehicles/Train.h index 0964c8cf9..e2c1d89f4 100644 --- a/src/engine/vehicles/Train.h +++ b/src/engine/vehicles/Train.h @@ -11,6 +11,10 @@ extern "C" { class AVehicle; // Forward declare +/** + * Note that you can only remove the tender if there are no carriages + * @arg waypoint initial waypoint to spawn at. + */ class ATrain : public AVehicle { public: @@ -35,7 +39,15 @@ class ATrain : public AVehicle { int16_t AnotherSmokeTimer = 0; int16_t SmokeTimer = 0; - explicit ATrain(size_t idx, ATrain::TenderStatus tender, size_t numCarriages, f32 speed, uint32_t waypoint); + explicit ATrain(ATrain::TenderStatus tender, size_t numCarriages, f32 speed, uint32_t waypoint); + + ~ATrain() { + _count--; + } + + static size_t GetCount() { + return _count; + } virtual void Spawn() override; virtual void BeginPlay() override; @@ -44,4 +56,7 @@ class ATrain : public AVehicle { virtual void Collision(s32 playerId, Player* player) override; s32 AddSmoke(s32 trainIndex, Vec3f pos, f32 velocity); void SyncComponents(TrainCarStuff* trainCar, s16 orientationY); + +private: + static size_t _count; }; \ No newline at end of file diff --git a/src/engine/vehicles/Truck.cpp b/src/engine/vehicles/Truck.cpp index 139edc644..c865fed70 100644 --- a/src/engine/vehicles/Truck.cpp +++ b/src/engine/vehicles/Truck.cpp @@ -16,12 +16,14 @@ extern "C" { extern s8 gPlayerCount; } -ATruck::ATruck(size_t idx, f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint) { +size_t ATruck::_count = 0; + +ATruck::ATruck(f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint) { TrackWaypoint* temp_v0; u16 waypointOffset; s32 numWaypoints = gWaypointCountByPathIndex[0]; - Index = idx; + Index = _count; waypointOffset = waypoint; temp_v0 = &path[waypointOffset]; @@ -54,6 +56,8 @@ ATruck::ATruck(size_t idx, f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t func_8000D940(Position, (s16*) &WaypointIndex, Speed, SomeMultiplierTheSequel, 0); } D_801631C8 = 10; + + _count++; } void ATruck::Spawn() { diff --git a/src/engine/vehicles/Truck.h b/src/engine/vehicles/Truck.h index 8781feaad..f9f65b2fc 100644 --- a/src/engine/vehicles/Truck.h +++ b/src/engine/vehicles/Truck.h @@ -33,11 +33,22 @@ class ATruck : public AVehicle { 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); + explicit ATruck(f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint); + + ~ATruck() { + _count--; + } + + static size_t GetCount() { + return _count; + } 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; + +private: + static size_t _count; }; \ No newline at end of file diff --git a/src/port/Game.cpp b/src/port/Game.cpp index 90869508e..70634713a 100644 --- a/src/port/Game.cpp +++ b/src/port/Game.cpp @@ -301,8 +301,6 @@ extern "C" { gWorldInstance.ClearVehicles(); gWorldInstance.Crossings.clear(); gWorldInstance.BombKarts.clear(); - gWorldInstance.Thwomps.clear(); - gWorldInstance.Penguins.clear(); } void CourseManager_CrossingTrigger() { @@ -570,61 +568,6 @@ extern "C" { gWorldInstance.Lakitus[playerId]->Activate(OLakitu::LakituType::REVERSE); } - extern Vec3su D_80165834; - void CourseManager_TickThwomps() { - // TickLights - if (gWorldInstance.Thwomps.size()) { - D_80165834[0] += 0x100; - D_80165834[1] += 0x200; - } - - for (auto& thwomp : gWorldInstance.Thwomps) { - if (thwomp) { - thwomp->Tick(); - } - } - } - - void CourseManager_DrawThwomps(s32 cameraId) { - for (auto& thwomp : gWorldInstance.Thwomps) { - if (thwomp) { - thwomp->Draw(cameraId); - } - } - } - - void CourseManager_TickPenguins(void) { - for (auto& penguin : gWorldInstance.Penguins) { - if (penguin) { - penguin->Tick(); - } - } - } - - void CourseManager_DrawSeagulls(s32 cameraId) { - for (auto& seagull : gWorldInstance.Seagulls) { - if (seagull) { - // seagull->Draw(cameraId); - } - } - } - - void CourseManager_TickSeagulls(void) { - for (auto& seagull : gWorldInstance.Seagulls) { - if (seagull) { - //seagull->Tick(); - } - } - } - - void CourseManager_DrawPenguins(s32 cameraId) { - for (auto& penguin : gWorldInstance.Penguins) { - if (penguin) { - penguin->Draw(cameraId); - } - } - } - size_t GetCupCursorPosition() { return gWorldInstance.CurrentCup->CursorPosition; } diff --git a/src/port/Game.h b/src/port/Game.h index 76ae4ac2d..ba4e1d359 100644 --- a/src/port/Game.h +++ b/src/port/Game.h @@ -109,18 +109,6 @@ void CourseManager_ClearVehicles(void); void CourseManager_DrawVehicles(s32 playerId); -void CourseManager_DrawThwomps(s32 cameraId); - -void CourseManager_TickThwomps(); - -void CourseManager_DrawSeagulls(s32 cameraId); - -void CourseManager_TickSeagulls(); - -void CourseManager_DrawPenguins(s32 cameraId); - -void CourseManager_TickPenguins(); - void CourseManager_CrossingTrigger(); void CourseManager_VehiclesCollision(s32 playerId, Player* player);