From 1b47bdd1801a652af27d9844f7dce2404e7ccc8a Mon Sep 17 00:00:00 2001 From: zsilencer Date: Wed, 26 Oct 2016 15:00:05 -0600 Subject: [PATCH] Fix desync caused by provisional track piece peep interaction --- src/game.c | 3 - src/ride/ride.c | 105 +++++++++++++++++++------------- src/ride/ride.h | 2 + src/windows/ride_construction.c | 28 ++++----- src/world/footpath.c | 2 +- src/world/map.c | 14 +++-- 6 files changed, 90 insertions(+), 64 deletions(-) diff --git a/src/game.c b/src/game.c index b5b246d913..3e207ba8c5 100644 --- a/src/game.c +++ b/src/game.c @@ -373,12 +373,9 @@ void game_logic_update() map_update_tiles(); // Temporarily remove provisional paths to prevent peep from interacting with them map_remove_provisional_elements(); - ride_remove_provisional_entrance_or_exit(); map_update_path_wide_flags(); peep_update_all(); - ride_restore_provisional_entrance_or_exit(); map_restore_provisional_elements(); - // vehicle_update_all(); sprite_misc_update_all(); ride_update_all(); diff --git a/src/ride/ride.c b/src/ride/ride.c index 455d21aaa1..972743a1eb 100644 --- a/src/ride/ride.c +++ b/src/ride/ride.c @@ -218,6 +218,8 @@ static void ride_set_vehicle_colours_to_random_preset(rct_ride *ride, uint8 pres static void maze_entrance_hedge_removal(int x, int y, rct_map_element *mapElement); void loc_6DDF9C(rct_ride *ride, rct_map_element *mapElement); static void maze_entrance_hedge_replacement(int x, int y, rct_map_element *mapElement); +bool sub_6CA2DF(int *trackType, int *trackDirection, int *rideIndex, int *edxRS16, int *x, int *y, int *z, int *properties); +money32 sub_6CA162(int rideIndex, int trackType, int trackDirection, int edxRS16, int x, int y, int z); rct_ride *get_ride(int index) { @@ -1347,7 +1349,7 @@ int sub_6C683D(int* x, int* y, int* z, int direction, int type, uint16 extra_par void ride_restore_provisional_entrance_or_exit() { if (_currentTrackSelectionFlags & (1 << 2)) { - money32 result = game_do_command( + game_do_command( _unkF440BF.x, (GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5 | GAME_COMMAND_FLAG_GHOST) | (_unkF440BF.direction << 8), _unkF440BF.y, @@ -1374,54 +1376,75 @@ void ride_remove_provisional_entrance_or_exit() } } +void ride_restore_provisional_track_piece() +{ + if (_currentTrackSelectionFlags & (1 << 1)) { + int x, y, z, direction, type, rideIndex, edxRS16; + if (sub_6CA2DF(&type, &direction, &rideIndex, &edxRS16, &x, &y, &z, NULL)) { + sub_6C96C0(); + } else { + _currentTrackPrice = sub_6CA162(rideIndex, type, direction, edxRS16, x, y, z); + sub_6C84CE(); + } + } +} + +void ride_remove_provisional_track_piece() +{ + if (!(_currentTrackSelectionFlags & (1 << 1))) { + return; + } + rct_ride *ride; + int rideIndex, x, y, z, direction; + + rideIndex = _currentRideIndex; + + x = _unkF440C5.x; + y = _unkF440C5.y; + z = _unkF440C5.z; + + ride = get_ride(rideIndex); + if (ride->type == RIDE_TYPE_MAZE) { + game_do_command(x , 41 | (0 << 8), y , rideIndex | (2 << 8), GAME_COMMAND_SET_MAZE_TRACK, z, 0); + game_do_command(x , 41 | (1 << 8), y + 16, rideIndex | (2 << 8), GAME_COMMAND_SET_MAZE_TRACK, z, 0); + game_do_command(x + 16, 41 | (2 << 8), y + 16, rideIndex | (2 << 8), GAME_COMMAND_SET_MAZE_TRACK, z, 0); + game_do_command(x + 16, 41 | (3 << 8), y , rideIndex | (2 << 8), GAME_COMMAND_SET_MAZE_TRACK, z, 0); + } else { + direction = _unkF440C5.direction; + if (!(direction & 4)) { + x -= TileDirectionDelta[direction].x; + y -= TileDirectionDelta[direction].y; + } + rct_xy_element next_track; + + if (track_block_get_next_from_zero(x, y, z, rideIndex, direction, &next_track, &z, &direction)) { + game_do_command( + next_track.x, + 105 | ((direction & 3) << 8), + next_track.y, + next_track.element->properties.track.type | ((next_track.element->properties.track.sequence & 0x0F) << 8), + GAME_COMMAND_REMOVE_TRACK, + z, + 0 + ); + } + } +} + /** * * rct2: 0x006C96C0 */ void sub_6C96C0() { - rct_ride *ride; - int rideIndex, x, y, z, direction; if (_currentTrackSelectionFlags & (1 << 2)) { ride_remove_provisional_entrance_or_exit(); _currentTrackSelectionFlags &= ~(1 << 2); } - if (_currentTrackSelectionFlags & 2) { - _currentTrackSelectionFlags &= ~2; - - rideIndex = _currentRideIndex; - - x = _unkF440C5.x; - y = _unkF440C5.y; - z = _unkF440C5.z; - - ride = get_ride(rideIndex); - if (ride->type == RIDE_TYPE_MAZE) { - game_do_command(x , 41 | (0 << 8), y , rideIndex | (2 << 8), GAME_COMMAND_SET_MAZE_TRACK, z, 0); - game_do_command(x , 41 | (1 << 8), y + 16, rideIndex | (2 << 8), GAME_COMMAND_SET_MAZE_TRACK, z, 0); - game_do_command(x + 16, 41 | (2 << 8), y + 16, rideIndex | (2 << 8), GAME_COMMAND_SET_MAZE_TRACK, z, 0); - game_do_command(x + 16, 41 | (3 << 8), y , rideIndex | (2 << 8), GAME_COMMAND_SET_MAZE_TRACK, z, 0); - } else { - direction = _unkF440C5.direction; - if (!(direction & 4)) { - x -= TileDirectionDelta[direction].x; - y -= TileDirectionDelta[direction].y; - } - rct_xy_element next_track; - - if (track_block_get_next_from_zero(x, y, z, rideIndex, direction, &next_track, &z, &direction)) { - game_do_command( - next_track.x, - 105 | ((direction & 3) << 8), - next_track.y, - next_track.element->properties.track.type | ((next_track.element->properties.track.sequence & 0x0F) << 8), - GAME_COMMAND_REMOVE_TRACK, - z, - 0 - ); - } - } + if (_currentTrackSelectionFlags & (1 << 1)) { + ride_remove_provisional_track_piece(); + _currentTrackSelectionFlags &= ~(1 << 1); } } @@ -1448,7 +1471,7 @@ void sub_6C9627() case RIDE_CONSTRUCTION_STATE_MAZE_BUILD: case RIDE_CONSTRUCTION_STATE_MAZE_MOVE: case RIDE_CONSTRUCTION_STATE_MAZE_FILL: - if (_currentTrackSelectionFlags & 1) { + if (_currentTrackSelectionFlags & (1 << 0)) { map_invalidate_tile_full( _currentTrackBeginX & 0xFFE0, _currentTrackBeginY & 0xFFE0 @@ -1457,8 +1480,8 @@ void sub_6C9627() } break; default: - if (_currentTrackSelectionFlags & 1) { - _currentTrackSelectionFlags &= ~1; + if (_currentTrackSelectionFlags & (1 << 0)) { + _currentTrackSelectionFlags &= ~(1 << 0); gMapSelectFlags &= ~MAP_SELECT_FLAG_ENABLE_ARROW; map_invalidate_tile_full(_currentTrackBeginX, _currentTrackBeginY); } diff --git a/src/ride/ride.h b/src/ride/ride.h index 8b5a185ac8..99827b3866 100644 --- a/src/ride/ride.h +++ b/src/ride/ride.h @@ -1060,6 +1060,8 @@ money32 ride_create_command(int type, int subType, int flags, uint8 *outRideInde void ride_clear_for_construction(int rideIndex); void ride_restore_provisional_entrance_or_exit(); void ride_remove_provisional_entrance_or_exit(); +void ride_restore_provisional_track_piece(); +void ride_remove_provisional_track_piece(); void set_vehicle_type_image_max_sizes(rct_ride_entry_vehicle* vehicle_type, int num_images); void invalidate_test_results(int rideIndex); diff --git a/src/windows/ride_construction.c b/src/windows/ride_construction.c index 0c7eb71005..830c367b6a 100644 --- a/src/windows/ride_construction.c +++ b/src/windows/ride_construction.c @@ -482,7 +482,7 @@ static void window_ride_construction_draw_track_piece( int width, int height ); static void window_ride_construction_update_enabled_track_pieces(); -static bool sub_6CA2DF(int *trackType, int *trackDirection, int *rideIndex, int *edxRS16, int *x, int *y, int *z, int *properties); +bool sub_6CA2DF(int *trackType, int *trackDirection, int *rideIndex, int *edxRS16, int *x, int *y, int *z, int *properties); static void sub_6CBCE2( int rideIndex, int trackType, int trackDirection, int edx, int originX, int originY, int originZ @@ -2546,7 +2546,7 @@ static bool sub_6CA2DF_get_track_element(uint8 *trackElement) { * @param[out] _properties (edirs16) * @return (CF) */ -static bool sub_6CA2DF(int *_trackType, int *_trackDirection, int *_rideIndex, int *_edxRS16, int *_x, int *_y, int *_z, int *_properties) { +bool sub_6CA2DF(int *_trackType, int *_trackDirection, int *_rideIndex, int *_edxRS16, int *_x, int *_y, int *_z, int *_properties) { uint8 trackType, trackDirection, rideIndex; uint16 z, x, y, edxRS16, properties; @@ -2722,7 +2722,7 @@ money32 sub_6CA162(int rideIndex, int trackType, int trackDirection, int edxRS16 _unkF440C5.y = y; _unkF440C5.z = z; _unkF440C5.direction = trackDirection; - _currentTrackSelectionFlags |= 2; + _currentTrackSelectionFlags |= (1 << 1); viewport_set_visibility(gTrackGroundFlags & TRACK_ELEMENT_LOCATION_IS_UNDERGROUND ? 1 : 3); if (_currentTrackSlopeEnd != 0) viewport_set_visibility(2); @@ -2741,7 +2741,7 @@ money32 sub_6CA162(int rideIndex, int trackType, int trackDirection, int edxRS16 _unkF440C5.z = z; _unkF440C5.direction = trackDirection; - _currentTrackSelectionFlags |= 2; + _currentTrackSelectionFlags |= (1 << 1); viewport_set_visibility(gTrackGroundFlags & TRACK_ELEMENT_LOCATION_IS_UNDERGROUND ? 1 : 3); if (_currentTrackSlopeEnd != 0) viewport_set_visibility(2); @@ -2760,15 +2760,15 @@ void sub_6C94D8() // Recheck if area is fine for new track. // Set by footpath placement - if (_currentTrackSelectionFlags & 8) { + if (_currentTrackSelectionFlags & (1 << 3)) { sub_6C9627(); - _currentTrackSelectionFlags &= ~8; + _currentTrackSelectionFlags &= ~(1 << 3); } switch (_rideConstructionState) { case RIDE_CONSTRUCTION_STATE_FRONT: case RIDE_CONSTRUCTION_STATE_BACK: - if (!(_currentTrackSelectionFlags & 2)) { + if (!(_currentTrackSelectionFlags & (1 << 1))) { if (sub_6CA2DF(&type, &direction, &rideIndex, &edxRS16, &x, &y, &z, NULL)) { sub_6C96C0(); } else { @@ -2781,7 +2781,7 @@ void sub_6C94D8() break; _rideConstructionArrowPulseTime = 5; - _currentTrackSelectionFlags ^= 1; + _currentTrackSelectionFlags ^= (1 << 0); x = _currentTrackBeginX; y = _currentTrackBeginY; z = _currentTrackBeginZ; @@ -2796,7 +2796,7 @@ void sub_6C94D8() direction ^= 2; gMapSelectArrowDirection = direction; gMapSelectFlags &= ~MAP_SELECT_FLAG_ENABLE_ARROW; - if (_currentTrackSelectionFlags & 1) + if (_currentTrackSelectionFlags & (1 << 0)) gMapSelectFlags |= MAP_SELECT_FLAG_ENABLE_ARROW; map_invalidate_tile_full(x, y); break; @@ -2806,13 +2806,13 @@ void sub_6C94D8() break; _rideConstructionArrowPulseTime = 5; - _currentTrackSelectionFlags ^= 1; + _currentTrackSelectionFlags ^= (1 << 0); x = _currentTrackBeginX; y = _currentTrackBeginY; z = _currentTrackBeginZ; direction = _currentTrackPieceDirection & 3; type = _currentTrackPieceType; - if (sub_6C683D(&x, &y, &z, direction, type, 0, NULL, _currentTrackSelectionFlags & 1 ? 2 : 1)) { + if (sub_6C683D(&x, &y, &z, direction, type, 0, NULL, _currentTrackSelectionFlags & (1 << 0) ? 2 : 1)) { sub_6C96C0(); _rideConstructionState = RIDE_CONSTRUCTION_STATE_0; } @@ -2825,7 +2825,7 @@ void sub_6C94D8() break; _rideConstructionArrowPulseTime = 5; - _currentTrackSelectionFlags ^= 1; + _currentTrackSelectionFlags ^= (1 << 0); x = _currentTrackBeginX & 0xFFE0; y = _currentTrackBeginY & 0xFFE0; z = _currentTrackBeginZ + 15; @@ -2842,7 +2842,7 @@ void sub_6C94D8() } } gMapSelectFlags &= ~MAP_SELECT_FLAG_ENABLE_ARROW; - if (_currentTrackSelectionFlags & 1) + if (_currentTrackSelectionFlags & (1 << 0)) gMapSelectFlags |= MAP_SELECT_FLAG_ENABLE_ARROW; map_invalidate_tile_full(x, y); break; @@ -3653,7 +3653,7 @@ void ride_construction_toolupdate_construct(int screenX, int screenY) _currentTrackBeginY = y; _currentTrackBeginZ = z; if ( - (_currentTrackSelectionFlags & 2) && + (_currentTrackSelectionFlags & (1 << 1)) && x == _previousTrackPieceX && y == _previousTrackPieceY && z == _previousTrackPieceZ diff --git a/src/world/footpath.c b/src/world/footpath.c index daa36dcddc..cfa5c102da 100644 --- a/src/world/footpath.c +++ b/src/world/footpath.c @@ -383,7 +383,7 @@ static money32 footpath_place_real(int type, int x, int y, int z, int slope, int } // Force ride construction to recheck area - _currentTrackSelectionFlags |= 8; + _currentTrackSelectionFlags |= (1 << 3); if (gGameCommandNestLevel == 1 && !(flags & GAME_COMMAND_FLAG_GHOST)) { rct_xyz16 coord; diff --git a/src/world/map.c b/src/world/map.c index b35d640e35..7b419ab1e9 100644 --- a/src/world/map.c +++ b/src/world/map.c @@ -1969,7 +1969,7 @@ static money32 raise_land(int flags, int x, int y, int z, int ax, int ay, int bx } // Force ride construction to recheck area - _currentTrackSelectionFlags |= 8; + _currentTrackSelectionFlags |= (1 << 3); gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; gCommandPosition.x = x; @@ -2042,7 +2042,7 @@ static money32 lower_land(int flags, int x, int y, int z, int ax, int ay, int bx } // Force ride construction to recheck area - _currentTrackSelectionFlags |= 8; + _currentTrackSelectionFlags |= (1 << 3); gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; gCommandPosition.x = x; @@ -2127,7 +2127,7 @@ money32 raise_water(sint16 x0, sint16 y0, sint16 x1, sint16 y1, uint8 flags) } // Force ride construction to recheck area - _currentTrackSelectionFlags |= 8; + _currentTrackSelectionFlags |= (1 << 3); return cost; } @@ -2203,7 +2203,7 @@ money32 lower_water(sint16 x0, sint16 y0, sint16 x1, sint16 y1, uint8 flags) } // Force ride construction to recheck area - _currentTrackSelectionFlags |= 8; + _currentTrackSelectionFlags |= (1 << 3); return cost; } @@ -3863,7 +3863,7 @@ void game_command_place_large_scenery(int* eax, int* ebx, int* ecx, int* edx, in } // Force ride construction to recheck area - _currentTrackSelectionFlags |= 8; + _currentTrackSelectionFlags |= (1 << 3); *ebx = (scenery_entry->large_scenery.price * 10) + supportsCost; if(gParkFlags & PARK_FLAGS_NO_MONEY){ @@ -4452,6 +4452,8 @@ void map_remove_provisional_elements() footpath_provisional_remove(); gFootpathProvisionalFlags |= PROVISIONAL_PATH_FLAG_1; } + ride_remove_provisional_track_piece(); + ride_remove_provisional_entrance_or_exit(); } void map_restore_provisional_elements() @@ -4465,6 +4467,8 @@ void map_restore_provisional_elements() gFootpathProvisionalPosition.z, gFootpathProvisionalSlope); } + ride_restore_provisional_track_piece(); + ride_restore_provisional_entrance_or_exit(); } int map_element_get_banner_index(rct_map_element *mapElement)