diff --git a/src/engine/World.cpp b/src/engine/World.cpp index a5bbd6cdf..5bdc9e05a 100644 --- a/src/engine/World.cpp +++ b/src/engine/World.cpp @@ -46,8 +46,8 @@ 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(trains, numCarriages, speed, waypoint)); +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++; } diff --git a/src/engine/World.h b/src/engine/World.h index ee562118b..e4e381e08 100644 --- a/src/engine/World.h +++ b/src/engine/World.h @@ -7,6 +7,7 @@ #include "vehicles/Train.h" #include "vehicles/Car.h" #include "vehicles/OBombKart.h" +#include "vehicles/Train.h" #include "TrainCrossing.h" #include #include "Actor.h" @@ -127,7 +128,7 @@ public: /** Actors */ void AddBoat(f32 speed, uint32_t waypoint); - void AddTrain(size_t numCarriages, 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); diff --git a/src/engine/courses/KalimariDesert.cpp b/src/engine/courses/KalimariDesert.cpp index df6b4237d..b982dad68 100644 --- a/src/engine/courses/KalimariDesert.cpp +++ b/src/engine/courses/KalimariDesert.cpp @@ -12,6 +12,7 @@ #include "engine/vehicles/Utils.h" #include "engine/vehicles/Vehicle.h" +#include "engine/vehicles/Train.h" extern "C" { #include "main.h" @@ -202,13 +203,30 @@ void KalimariDesert::SpawnVehicles() { generate_train_waypoints(); s32 numTrains = 2; + s32 numCars = 5; + ATrain::TenderStatus tender = ATrain::TenderStatus::HAS_TENDER; s32 centerWaypoint = 160; // Spawn two trains for (size_t i = 0; i < numTrains; ++i) { uint32_t waypoint = CalculateWaypointDistribution(i, numTrains, gVehicle2DWaypointLength, centerWaypoint); - gWorldInstance.AddTrain(5, 2.5f, waypoint); + + if (CVarGetInteger("gMultiplayerNoFeatureCuts", 0) == false) { + // Multiplayer modes have no tender and no carriages + if (gActiveScreenMode != SCREEN_MODE_1P) { + tender = ATrain::TenderStatus::NO_TENDER; + numCars = 0; + } + + // 2 player versus mode has a tender and a carriage + if ((gModeSelection == VERSUS) && (gPlayerCountSelection1 == 2)) { + tender = ATrain::TenderStatus::HAS_TENDER; + numCars = 1; + } + } + + gWorldInstance.AddTrain(tender, numCars, 2.5f, waypoint); } if (gModeSelection == VERSUS) { diff --git a/src/engine/courses/TestCourse.cpp b/src/engine/courses/TestCourse.cpp index b3383a3b0..2a8787d23 100644 --- a/src/engine/courses/TestCourse.cpp +++ b/src/engine/courses/TestCourse.cpp @@ -12,8 +12,8 @@ #include "assets/bowsers_castle_data.h" #include "assets/bowsers_castle_displaylists.h" #include "engine/actors/ATree.h" - #include "engine/actors/ACloud.h" +#include "engine/vehicles/Train.h" extern "C" { #include "main.h" @@ -265,8 +265,8 @@ void TestCourse::SpawnVehicles() { gVehicle2DWaypointLength = 53; D_80162EB0 = spawn_actor_on_surface(test_course_path2D[0].x, 2000.0f, test_course_path2D[0].z); - gWorldInstance.AddTrain(5, 2.5f, 0); - gWorldInstance.AddTrain(5, 2.5f, 8); + gWorldInstance.AddTrain(ATrain::TenderStatus::HAS_TENDER, 5, 2.5f, 0); + gWorldInstance.AddTrain(ATrain::TenderStatus::HAS_TENDER, 5, 2.5f, 8); Vec3f pos = {0, 0, 0}; diff --git a/src/engine/vehicles/Train.cpp b/src/engine/vehicles/Train.cpp index a16b8b5f9..c34ac1cf3 100644 --- a/src/engine/vehicles/Train.cpp +++ b/src/engine/vehicles/Train.cpp @@ -22,7 +22,7 @@ extern "C" { // #include "common_structs.h" } -ATrain::ATrain(size_t idx, size_t numCarriages, f32 speed, uint32_t waypoint) { +ATrain::ATrain(size_t idx, ATrain::TenderStatus tender, size_t numCarriages, f32 speed, uint32_t waypoint) { u16 waypointOffset; TrainCarStuff* ptr1; Path2D* pos; @@ -59,30 +59,19 @@ ATrain::ATrain(size_t idx, size_t numCarriages, f32 speed, uint32_t waypoint) { // 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; + // Fall back in-case someone tries to spawn a train with carriages but no tender; not allowed. + if (numCarriages > 0) { + tender = HAS_TENDER; } + Tender.isActive = static_cast(tender); + + for (size_t i = 0; i < numCarriages; i++) { + PassengerCars[i].isActive = 1; + } + + NumCars = NUM_TENDERS + numCarriages; + AnotherSmokeTimer = 0; } diff --git a/src/engine/vehicles/Train.h b/src/engine/vehicles/Train.h index 9b733bad3..0964c8cf9 100644 --- a/src/engine/vehicles/Train.h +++ b/src/engine/vehicles/Train.h @@ -14,6 +14,11 @@ class AVehicle; // Forward declare class ATrain : public AVehicle { public: + enum TenderStatus { + NO_TENDER, + HAS_TENDER, + }; + TrainCarStuff Locomotive; TrainCarStuff Tender; std::vector PassengerCars; @@ -30,7 +35,7 @@ class ATrain : public AVehicle { int16_t AnotherSmokeTimer = 0; int16_t SmokeTimer = 0; - explicit ATrain(size_t idx, size_t numCarriages, f32 speed, uint32_t waypoint); + explicit ATrain(size_t idx, ATrain::TenderStatus tender, size_t numCarriages, f32 speed, uint32_t waypoint); virtual void Spawn() override; virtual void BeginPlay() override; diff --git a/src/port/ui/ImguiUI.cpp b/src/port/ui/ImguiUI.cpp index 3ce6ed934..3548325d5 100644 --- a/src/port/ui/ImguiUI.cpp +++ b/src/port/ui/ImguiUI.cpp @@ -475,8 +475,8 @@ void DrawEnhancementsMenu() { "No Level of Detail (LOD)", "gDisableLod", { .tooltip = "Disable Level of Detail (LOD) to avoid models using lower poly versions at a distance" }); - UIWidgets::CVarCheckbox("Select any star from menu", "gCompletedGame", - { .tooltip = "Unlocks extra mode and sets all gold cups." }); + UIWidgets::CVarCheckbox("No multiplayer feature cuts", "gMultiplayerNoFeatureCuts", + { .tooltip = "Allows full train and jumbotron in multiplayer, etc." }); UIWidgets::CVarCheckbox("Disable Culling", "gNoCulling", { .tooltip = "Disable original culling of mk64" }); UIWidgets::CVarSliderFloat(