From bd51c7ed808f5fe3686e829f55c587e1689e00c1 Mon Sep 17 00:00:00 2001 From: nightroan Date: Mon, 21 Sep 2015 03:01:01 -0700 Subject: [PATCH] Fixed #1939 by adding a callback to delay selection of the next piece until the server sends back the placement command. --- src/game.c | 2 + src/ride/ride.c | 75 +++++++++++++++++++++++++++++++++ src/ride/ride.h | 2 + src/windows/ride_construction.c | 16 +++++++ 4 files changed, 95 insertions(+) diff --git a/src/game.c b/src/game.c index 50ee37673d..788100d360 100644 --- a/src/game.c +++ b/src/game.c @@ -65,6 +65,8 @@ GAME_COMMAND_CALLBACK_POINTER* game_command_callback = 0; GAME_COMMAND_CALLBACK_POINTER* game_command_callback_table[] = { 0, game_command_callback_ride_construct_new, + game_command_callback_ride_construct_placed_front, + game_command_callback_ride_construct_placed_back, }; int game_command_callback_get_index(GAME_COMMAND_CALLBACK_POINTER* callback) diff --git a/src/ride/ride.c b/src/ride/ride.c index e9feb8dce6..b8637b9dcf 100644 --- a/src/ride/ride.c +++ b/src/ride/ride.c @@ -5308,6 +5308,81 @@ void game_command_callback_ride_construct_new(int eax, int ebx, int ecx, int edx ride_construct(rideIndex); } +/** + * + * Network client callback when placing ride pieces + * Client does execute placing the piece on the same tick as mouse_up - waits for server command + * Re-executes function from ride_construction - window_ride_construction_construct() + * Only uses part that deals with construction state + */ + +void game_command_callback_ride_construct_placed_back(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp) +{ + int trackType, trackDirection, rideIndex, edxRS16, x, y, z, properties; + track_begin_end trackBeginEnd; + + RCT2_GLOBAL(0x00F441D2, uint8) = _currentRideIndex; + trackDirection = _currentTrackPieceDirection ^ 2; + x = _currentTrackBeginX; + y = _currentTrackBeginY; + z = _currentTrackBeginZ; + if (!(trackDirection & 4)) { + x += TileDirectionDelta[trackDirection].x; + y += TileDirectionDelta[trackDirection].y; + } + + if (track_block_get_previous_from_zero(x, y, z, _currentRideIndex, trackDirection, &trackBeginEnd)) { + _currentTrackBeginX = trackBeginEnd.begin_x; + _currentTrackBeginY = trackBeginEnd.begin_y; + _currentTrackBeginZ = trackBeginEnd.begin_z; + _currentTrackPieceDirection = trackBeginEnd.begin_direction; + _currentTrackPieceType = trackBeginEnd.begin_element->properties.track.type; + _currentTrackSelectionFlags = 0; + _rideConstructionArrowPulseTime = 0; + _rideConstructionState = RIDE_CONSTRUCTION_STATE_SELECTED; + ride_select_previous_section(); + } + else { + _rideConstructionState = RIDE_CONSTRUCTION_STATE_0; + } + + sub_6C84CE(); +} + +void game_command_callback_ride_construct_placed_front(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp) +{ + int trackType, trackDirection, rideIndex, edxRS16, x, y, z, properties; + track_begin_end trackBeginEnd; + + RCT2_GLOBAL(0x00F441D2, uint8) = _currentRideIndex; + trackDirection = _currentTrackPieceDirection; + x = _currentTrackBeginX; + y = _currentTrackBeginY; + z = _currentTrackBeginZ; + if (!(trackDirection & 4)) { + x -= TileDirectionDelta[trackDirection].x; + y -= TileDirectionDelta[trackDirection].y; + } + + rct_xy_element next_track; + if (track_block_get_next_from_zero(x, y, z, _currentRideIndex, trackDirection, &next_track, &z, &trackDirection)) { + _currentTrackBeginX = next_track.x; + _currentTrackBeginY = next_track.y; + _currentTrackBeginZ = z; + _currentTrackPieceDirection = next_track.element->type & MAP_ELEMENT_DIRECTION_MASK; + _currentTrackPieceType = next_track.element->properties.track.type; + _currentTrackSelectionFlags = 0; + _rideConstructionArrowPulseTime = 0; + _rideConstructionState = RIDE_CONSTRUCTION_STATE_SELECTED; + ride_select_next_section(); + } + else { + _rideConstructionState = RIDE_CONSTRUCTION_STATE_0; + } + + sub_6C84CE(); +} + /** * * rct2: 0x006B49D9 diff --git a/src/ride/ride.h b/src/ride/ride.h index 517f006b28..cba6689fc4 100644 --- a/src/ride/ride.h +++ b/src/ride/ride.h @@ -967,6 +967,8 @@ void game_command_set_ride_setting(int *eax, int *ebx, int *ecx, int *edx, int * int ride_get_refund_price(int ride_id); void game_command_create_ride(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp); void game_command_callback_ride_construct_new(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp); +void game_command_callback_ride_construct_placed_front(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp); +void game_command_callback_ride_construct_placed_back(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp); void game_command_demolish_ride(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp); void game_command_set_ride_appearance(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp); void game_command_set_ride_price(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp); diff --git a/src/windows/ride_construction.c b/src/windows/ride_construction.c index 4cdeccae80..a175f38231 100644 --- a/src/windows/ride_construction.c +++ b/src/windows/ride_construction.c @@ -1563,6 +1563,15 @@ static void window_ride_construction_construct(rct_window *w) return; } + // If client, then we can't update 'next piece selection' code until server sends back command + if (network_get_mode() == NETWORK_MODE_CLIENT) { + if (_rideConstructionState == RIDE_CONSTRUCTION_STATE_BACK) { + game_command_callback = game_command_callback_ride_construct_placed_back; + } else if (_rideConstructionState == RIDE_CONSTRUCTION_STATE_FRONT) { + game_command_callback = game_command_callback_ride_construct_placed_front; + } + } + RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TITLE, rct_string_id) = STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE; RCT2_GLOBAL(0x00F44074, money32) = game_do_command( x, @@ -1592,6 +1601,9 @@ static void window_ride_construction_construct(rct_window *w) viewport_set_visibility(2); } + // *************** + // NOTE: the rest of this function (minus the network condition) is copied to game_command_callback_ride_construct_placed_front/back + // Please update both ends if there are any changes here if (_rideConstructionState == RIDE_CONSTRUCTION_STATE_BACK) { RCT2_GLOBAL(0x00F441D2, uint8) = _currentRideIndex; trackDirection = _currentTrackPieceDirection ^ 2; @@ -1643,6 +1655,10 @@ static void window_ride_construction_construct(rct_window *w) } } + // returning early here makes it so that the construction window doesn't blink + if (network_get_mode() == NETWORK_MODE_CLIENT) + return; + sub_6C84CE(); }