Fix #6123: Cannot build some track designs with 4 stations (#11031)

This commit is contained in:
Michael Steenbeek 2020-03-25 14:20:29 +01:00 committed by GitHub
parent 766339d771
commit 3f473ec3f0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 27 additions and 20 deletions

View file

@ -1,5 +1,6 @@
0.2.5+ (in development)
------------------------------------------------------------------------
- Fix: [#6123, #7907, #9472, #11028] Cannot build some track designs with 4 stations.
- Fix: [#11027] Third color on walls becomes black when saving.
0.2.5 (2020-03-24)

View file

@ -1810,7 +1810,7 @@ static void window_ride_construction_construct(rct_window* w)
auto trackPlaceAction = TrackPlaceAction(
rideIndex, trackType, { x, y, z, static_cast<uint8_t>(trackDirection) }, (properties)&0xFF, (properties >> 8) & 0x0F,
(properties >> 12) & 0x0F, liftHillAndAlternativeState);
(properties >> 12) & 0x0F, liftHillAndAlternativeState, false);
if (_rideConstructionState == RIDE_CONSTRUCTION_STATE_BACK)
{
trackPlaceAction.SetCallback(RideConstructPlacedBackwardGameActionCallback);

View file

@ -52,6 +52,7 @@ private:
int32_t _colour;
int32_t _seatRotation;
int32_t _trackPlaceFlags;
bool _fromTrackDesign;
public:
TrackPlaceAction()
@ -60,7 +61,7 @@ public:
TrackPlaceAction(
NetworkRideId_t rideIndex, int32_t trackType, const CoordsXYZD& origin, int32_t brakeSpeed, int32_t colour,
int32_t seatRotation, int32_t liftHillAndAlternativeState)
int32_t seatRotation, int32_t liftHillAndAlternativeState, bool fromTrackDesign)
: _rideIndex(rideIndex)
, _trackType(trackType)
, _origin(origin)
@ -68,6 +69,7 @@ public:
, _colour(colour)
, _seatRotation(seatRotation)
, _trackPlaceFlags(liftHillAndAlternativeState)
, _fromTrackDesign(fromTrackDesign)
{
_origin.direction &= 3;
}
@ -348,7 +350,7 @@ public:
}
if ((entranceDirections & TRACK_SEQUENCE_FLAG_ORIGIN) && trackBlock->index == 0)
{
if (!track_add_station_element({ mapLoc, baseZ, _origin.direction }, _rideIndex, 0))
if (!track_add_station_element({ mapLoc, baseZ, _origin.direction }, _rideIndex, 0, _fromTrackDesign))
{
return std::make_unique<TrackPlaceActionResult>(GA_ERROR::UNKNOWN, gGameCommandErrorText);
}
@ -665,7 +667,8 @@ public:
{
if (trackBlock->index == 0)
{
track_add_station_element({ mapLoc, _origin.direction }, _rideIndex, GAME_COMMAND_FLAG_APPLY);
track_add_station_element(
{ mapLoc, _origin.direction }, _rideIndex, GAME_COMMAND_FLAG_APPLY, _fromTrackDesign);
}
sub_6CB945(ride);
ride->UpdateMaxVehicles();

View file

@ -31,7 +31,7 @@
// This string specifies which version of network stream current build uses.
// It is used for making sure only compatible builds get connected, even within
// single OpenRCT2 version.
#define NETWORK_STREAM_VERSION "0"
#define NETWORK_STREAM_VERSION "1"
#define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION
static Peep* _pickup_peep = nullptr;

View file

@ -637,14 +637,14 @@ static void ride_remove_station(Ride* ride, const CoordsXYZ& location)
*
* rct2: 0x006C4D89
*/
bool track_add_station_element(CoordsXYZD loc, ride_id_t rideIndex, int32_t flags)
bool track_add_station_element(CoordsXYZD loc, ride_id_t rideIndex, int32_t flags, bool fromTrackDesign)
{
auto ride = get_ride(rideIndex);
if (ride == nullptr)
return false;
CoordsXY stationLoc0 = loc;
CoordsXY stationLoc1 = loc;
CoordsXY stationBackLoc = loc;
CoordsXY stationFrontLoc = loc;
int32_t stationLength = 1;
if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_HAS_SINGLE_PIECE_STATION))
@ -672,7 +672,7 @@ bool track_add_station_element(CoordsXYZD loc, ride_id_t rideIndex, int32_t flag
TileElement* stationElement;
// Search backwards for more station
loc = { stationLoc0, loc.z, loc.direction };
loc = { stationBackLoc, loc.z, loc.direction };
do
{
loc -= CoordsDirectionDelta[loc.direction];
@ -688,13 +688,13 @@ bool track_add_station_element(CoordsXYZD loc, ride_id_t rideIndex, int32_t flag
}
}
stationLoc0 = loc;
stationBackLoc = loc;
stationLength++;
}
} while (stationElement != nullptr);
// Search forwards for more station
loc = { stationLoc1, loc.z, loc.direction };
loc = { stationFrontLoc, loc.z, loc.direction };
do
{
loc += CoordsDirectionDelta[loc.direction];
@ -710,12 +710,14 @@ bool track_add_station_element(CoordsXYZD loc, ride_id_t rideIndex, int32_t flag
}
}
stationLoc1 = loc;
stationFrontLoc = loc;
stationLength++;
}
} while (stationElement != nullptr);
if (stationLoc0 == stationLoc1 && ride->num_stations >= MAX_STATIONS)
// When attempting to place a track design, it sometimes happens that the front and back of station 0 are built,
// but the middle is not. Allow this, so the track place function can actually finish building all 4 stations.
if (stationBackLoc == stationFrontLoc && ride->num_stations >= MAX_STATIONS && !fromTrackDesign)
{
gGameCommandErrorText = STR_NO_MORE_STATIONS_ALLOWED_ON_THIS_RIDE;
return false;
@ -729,7 +731,7 @@ bool track_add_station_element(CoordsXYZD loc, ride_id_t rideIndex, int32_t flag
if (flags & GAME_COMMAND_FLAG_APPLY)
{
loc = { stationLoc1, loc.z, loc.direction };
loc = { stationFrontLoc, loc.z, loc.direction };
bool finaliseStationDone;
do
@ -740,7 +742,7 @@ bool track_add_station_element(CoordsXYZD loc, ride_id_t rideIndex, int32_t flag
if (stationElement != nullptr)
{
int32_t targetTrackType;
if (stationLoc1 == loc)
if (stationFrontLoc == loc)
{
auto stationIndex = ride_get_first_empty_station_start(ride);
if (stationIndex == STATION_INDEX_NULL)
@ -758,7 +760,7 @@ bool track_add_station_element(CoordsXYZD loc, ride_id_t rideIndex, int32_t flag
targetTrackType = TRACK_ELEM_END_STATION;
}
else if (stationLoc0 == loc)
else if (stationBackLoc == loc)
{
targetTrackType = TRACK_ELEM_BEGIN_STATION;
}
@ -770,7 +772,7 @@ bool track_add_station_element(CoordsXYZD loc, ride_id_t rideIndex, int32_t flag
map_invalidate_element(loc, stationElement);
if (stationLoc0 != loc)
if (stationBackLoc != loc)
{
loc -= CoordsDirectionDelta[loc.direction];
finaliseStationDone = false;

View file

@ -553,7 +553,7 @@ int32_t track_get_actual_bank(TileElement* tileElement, int32_t bank);
int32_t track_get_actual_bank_2(int32_t rideType, bool isInverted, int32_t bank);
int32_t track_get_actual_bank_3(Vehicle* vehicle, TileElement* tileElement);
bool track_add_station_element(CoordsXYZD loc, ride_id_t rideIndex, int32_t flags);
bool track_add_station_element(CoordsXYZD loc, ride_id_t rideIndex, int32_t flags, bool fromTrackDesign);
bool track_remove_station_element(int32_t x, int32_t y, int32_t z, Direction direction, ride_id_t rideIndex, int32_t flags);
money32 maze_set_track(

View file

@ -1564,7 +1564,7 @@ static bool track_design_place_ride(TrackDesign* td6, int16_t x, int16_t y, int1
gGameCommandErrorTitle = STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE;
auto trackPlaceAction = TrackPlaceAction(
_currentRideIndex, trackType, { x, y, tempZ, static_cast<uint8_t>(rotation) }, brakeSpeed, trackColour,
seatRotation, liftHillAndAlternativeState);
seatRotation, liftHillAndAlternativeState, true);
trackPlaceAction.SetFlags(flags);
auto res = flags & GAME_COMMAND_FLAG_APPLY ? GameActions::ExecuteNested(&trackPlaceAction)

View file

@ -82,7 +82,8 @@ money32 place_provisional_track_piece(
else
{
auto trackPlaceAction = TrackPlaceAction(
rideIndex, trackType, { x, y, z, static_cast<uint8_t>(trackDirection) }, 0, 0, 0, liftHillAndAlternativeState);
rideIndex, trackType, { x, y, z, static_cast<uint8_t>(trackDirection) }, 0, 0, 0, liftHillAndAlternativeState,
false);
trackPlaceAction.SetFlags(GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND | GAME_COMMAND_FLAG_GHOST);
// This command must not be sent over the network
auto res = GameActions::Execute(&trackPlaceAction);