Fix #11225: Track design replays.

The replay state was not being passed to all sub actions this prevented the replay from working. Note replays made before this still work its just they couldn't be replayed.

name the flag

Update changelog
This commit is contained in:
duncanspumpkin 2020-04-05 08:28:07 +01:00
parent 1199295099
commit de7051d940
4 changed files with 52 additions and 11 deletions

View File

@ -13,6 +13,7 @@
- Fix: [#11126] Cannot place Frightmare track design.
- Fix: [#11208] Cannot export parks with RCT2 DLC objects.
- Fix: [#11230] Seat Rotation not imported correctly for hacked rides.
- Fix: [#11225] Replay manager cannot handle track designs.
- Fix: Small red gardens in RCT1 saves are imported in the wrong colour.
- Improved: [#11157] Slimmer virtual floor lines.

View File

@ -211,7 +211,10 @@ GameActionResult::Ptr TrackDesignAction::Execute() const
{
operation = PTD_OPERATION_PLACE;
}
if (GetFlags() & GAME_COMMAND_FLAG_REPLAY)
{
operation |= PTD_OPERATION_FLAG_IS_REPLAY;
}
cost = place_virtual_track(_td, operation, placeScenery, ride, _loc);
}

View File

@ -91,6 +91,7 @@ static bool _trackDesignPlaceStateEntranceExitPlaced = false;
bool _trackDesignPlaceStateSceneryUnavailable = false;
static bool _trackDesignPlaceStateHasScenery = false;
static bool _trackDesignPlaceStatePlaceScenery = true;
static bool _trackDesignPlaceIsReplay = false;
static map_backup* track_design_preview_backup_map();
@ -1036,7 +1037,10 @@ static bool TrackDesignPlaceSceneryElement(
{
flags = GAME_COMMAND_FLAG_PATH_SCENERY;
}
if (_trackDesignPlaceIsReplay)
{
flags |= GAME_COMMAND_FLAG_REPLAY;
}
gGameCommandErrorTitle = STR_CANT_POSITION_THIS_HERE;
auto smallSceneryPlace = SmallSceneryPlaceAction(
@ -1081,12 +1085,15 @@ static bool TrackDesignPlaceSceneryElement(
{
flags = GAME_COMMAND_FLAG_PATH_SCENERY;
}
if (_trackDesignPlaceIsReplay)
{
flags |= GAME_COMMAND_FLAG_REPLAY;
}
auto sceneryPlaceAction = LargeSceneryPlaceAction(
{ mapCoord.x, mapCoord.y, z, rotation }, entry_index, scenery.primary_colour, scenery.secondary_colour);
sceneryPlaceAction.SetFlags(flags);
auto res = flags & GAME_COMMAND_FLAG_APPLY ? GameActions::Execute(&sceneryPlaceAction)
: GameActions::Query(&sceneryPlaceAction);
auto res = flags & GAME_COMMAND_FLAG_APPLY ? GameActions::ExecuteNested(&sceneryPlaceAction)
: GameActions::QueryNested(&sceneryPlaceAction);
cost = res->Cost;
break;
@ -1121,7 +1128,10 @@ static bool TrackDesignPlaceSceneryElement(
{
flags = 0;
}
if (_trackDesignPlaceIsReplay)
{
flags |= GAME_COMMAND_FLAG_REPLAY;
}
auto wallPlaceAction = WallPlaceAction(
entry_index, { mapCoord.x, mapCoord.y, z }, rotation, scenery.primary_colour, scenery.secondary_colour,
(scenery.flags & 0xFC) >> 2);
@ -1169,7 +1179,10 @@ static bool TrackDesignPlaceSceneryElement(
{
flags = 0;
}
if (_trackDesignPlaceIsReplay)
{
flags |= GAME_COMMAND_FLAG_REPLAY;
}
uint8_t slope = ((bh >> 5) & 0x3) | ((bh >> 2) & 0x4);
uint8_t edges = bh & 0xF;
auto footpathPlaceAction = FootpathPlaceFromTrackAction(
@ -1207,7 +1220,10 @@ static bool TrackDesignPlaceSceneryElement(
flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND
| GAME_COMMAND_FLAG_GHOST;
}
if (_trackDesignPlaceIsReplay)
{
flags |= GAME_COMMAND_FLAG_REPLAY;
}
footpath_connect_edges(mapCoord, reinterpret_cast<TileElement*>(pathElement), flags);
footpath_update_queue_chains();
return true;
@ -1337,6 +1353,10 @@ static int32_t track_design_place_maze(TrackDesign* td6, int16_t x, int16_t y, i
flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND
| GAME_COMMAND_FLAG_GHOST;
}
if (_trackDesignPlaceIsReplay)
{
flags |= GAME_COMMAND_FLAG_REPLAY;
}
auto rideEntranceExitPlaceAction = RideEntranceExitPlaceAction(mapCoord, rotation, ride->id, 0, false);
rideEntranceExitPlaceAction.SetFlags(flags);
auto res = GameActions::ExecuteNested(&rideEntranceExitPlaceAction);
@ -1372,6 +1392,10 @@ static int32_t track_design_place_maze(TrackDesign* td6, int16_t x, int16_t y, i
flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND
| GAME_COMMAND_FLAG_GHOST;
}
if (_trackDesignPlaceIsReplay)
{
flags |= GAME_COMMAND_FLAG_REPLAY;
}
auto rideEntranceExitPlaceAction = RideEntranceExitPlaceAction(mapCoord, rotation, ride->id, 0, true);
rideEntranceExitPlaceAction.SetFlags(flags);
auto res = GameActions::ExecuteNested(&rideEntranceExitPlaceAction);
@ -1402,7 +1426,10 @@ static int32_t track_design_place_maze(TrackDesign* td6, int16_t x, int16_t y, i
{
flags = GAME_COMMAND_FLAG_APPLY;
}
if (_trackDesignPlaceIsReplay)
{
flags |= GAME_COMMAND_FLAG_REPLAY;
}
gGameCommandErrorTitle = STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE;
auto mazePlace = MazePlaceTrackAction({ mapCoord, z }, ride->id, maze_entry);
@ -1560,7 +1587,10 @@ static bool track_design_place_ride(TrackDesign* td6, int16_t x, int16_t y, int1
{
flags = 0;
}
if (_trackDesignPlaceIsReplay)
{
flags |= GAME_COMMAND_FLAG_REPLAY;
}
gGameCommandErrorTitle = STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE;
auto trackPlaceAction = TrackPlaceAction(
_currentRideIndex, trackType, { x, y, tempZ, static_cast<uint8_t>(rotation) }, brakeSpeed, trackColour,
@ -1701,7 +1731,10 @@ static bool track_design_place_ride(TrackDesign* td6, int16_t x, int16_t y, int1
{
flags = 0;
}
if (_trackDesignPlaceIsReplay)
{
flags |= GAME_COMMAND_FLAG_REPLAY;
}
gGameCommandErrorTitle = STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE;
auto rideEntranceExitPlaceAction = RideEntranceExitPlaceAction(
{ x, y }, rotation, ride->id, stationIndex, entrance.isExit);
@ -1772,6 +1805,8 @@ int32_t place_virtual_track(
_trackDesignPlaceStateSceneryUnavailable = false;
_trackDesignPlaceStateHasScenery = false;
_trackDesignPlaceIsReplay = ptdOperation & PTD_OPERATION_FLAG_IS_REPLAY;
ptdOperation &= ~PTD_OPERATION_FLAG_IS_REPLAY;
_trackDesignPlaceOperation = ptdOperation;
if (gTrackDesignSceneryToggle)
{

View File

@ -183,6 +183,8 @@ enum
PTD_OPERATION_REMOVE_GHOST,
};
static constexpr uint8_t PTD_OPERATION_FLAG_IS_REPLAY = (1 << 7);
enum
{
MAZE_ELEMENT_TYPE_MAZE_TRACK = 0,