diff --git a/distribution/changelog.txt b/distribution/changelog.txt index dd15e14505..e1eb1c1fda 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -7,6 +7,7 @@ - Feature: [#5991] Allow all tracked rides that can be tested without guests to the Track Designer - Fix: [#2127, #2229, #5586] Mountain tool cost calculation - Fix: [#3589] Crash due to invalid footpathEntry in path_paint +- Fix: [#3852] Constructing path not clearing scenery on server. - Fix: [#4455] Crash in window_sign_invalidate due to original bug - Fix: [#4715] Fix OpenGL rendering of water when zoomed. See #5890. - Fix: [#4931] Crash in path_paint - footpathentry was null diff --git a/src/openrct2/network/network.h b/src/openrct2/network/network.h index 7de38ade5d..93ec07fb99 100644 --- a/src/openrct2/network/network.h +++ b/src/openrct2/network/network.h @@ -55,7 +55,7 @@ extern "C" { // This define 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 "16" +#define NETWORK_STREAM_VERSION "17" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION #ifdef __cplusplus diff --git a/src/openrct2/windows/footpath.c b/src/openrct2/windows/footpath.c index 79fc79d579..cb40c187a2 100644 --- a/src/openrct2/windows/footpath.c +++ b/src/openrct2/windows/footpath.c @@ -887,24 +887,8 @@ static void window_footpath_construct() sint32 type, x, y, z, slope; footpath_get_next_path_info(&type, &x, &y, &z, &slope); - // Try to place the path at the desired location gGameCommandErrorTitle = STR_CANT_BUILD_FOOTPATH_HERE; - money32 cost = footpath_place(type, x, y, z, slope, 0); - - if (cost != MONEY32_UNDEFINED && !gCheatsDisableClearanceChecks) { - // It is possible, let's remove walls between the old and new piece of path - uint8 direction = gFootpathConstructDirection; - wall_remove_intersecting_walls(x, y, z, z + 4 + ((slope & 0xf) ? 2 : 0), direction ^ 2); - wall_remove_intersecting_walls( - x - TileDirectionDelta[direction].x, - y - TileDirectionDelta[direction].y, - z, z + 4, direction - ); - } - - // Actually place the path now - gGameCommandErrorTitle = STR_CANT_BUILD_FOOTPATH_HERE; - cost = footpath_place(type, x, y, z, slope, GAME_COMMAND_FLAG_APPLY); + money32 cost = footpath_place_remove_intersecting(type, x, y, z, slope, GAME_COMMAND_FLAG_APPLY, gFootpathConstructDirection); if (cost != MONEY32_UNDEFINED) { audio_play_sound_at_location( diff --git a/src/openrct2/world/footpath.c b/src/openrct2/world/footpath.c index 3b22c79426..a2f8cbb880 100644 --- a/src/openrct2/world/footpath.c +++ b/src/openrct2/world/footpath.c @@ -333,7 +333,7 @@ static money32 footpath_element_update(sint32 x, sint32 y, rct_map_element *mapE return gParkFlags & PARK_FLAGS_NO_MONEY ? 0 : gFootpathPrice; } -static money32 footpath_place_real(sint32 type, sint32 x, sint32 y, sint32 z, sint32 slope, sint32 flags, uint8 pathItemType) +static money32 footpath_place_real(sint32 type, sint32 x, sint32 y, sint32 z, sint32 slope, sint32 flags, uint8 pathItemType, bool clearDirection, sint32 direction) { rct_map_element *mapElement; @@ -385,6 +385,18 @@ static money32 footpath_place_real(sint32 type, sint32 x, sint32 y, sint32 z, si coord.y = y + 16; coord.z = map_element_height(coord.x, coord.y); network_set_player_last_action_coord(network_get_player_index(game_command_playerid), coord); + + if (clearDirection && !gCheatsDisableClearanceChecks) + { + direction = direction & 0xF; + // It is possible, let's remove walls between the old and new piece of path + wall_remove_intersecting_walls(x, y, z, z + 4 + ((slope & 0xf) ? 2 : 0), direction ^ 2); + wall_remove_intersecting_walls( + x - TileDirectionDelta[direction].x, + y - TileDirectionDelta[direction].y, + z, z + 4, direction + ); + } } footpath_provisional_remove(); @@ -493,7 +505,9 @@ void game_command_place_footpath(sint32 *eax, sint32 *ebx, sint32 *ecx, sint32 * *edx & 0xFF, (*ebx >> 8) & 0xFF, *ebx & 0xFF, - *edi & 0xFF + *edi & 0xFF, + (*ebp & FOOTPATH_CLEAR_DIRECTIONAL) >> 8, + *ebp & 0xFF ); } @@ -620,6 +634,11 @@ money32 footpath_place(sint32 type, sint32 x, sint32 y, sint32 z, sint32 slope, return game_do_command(x, (slope << 8) | flags, y, (type << 8) | z, GAME_COMMAND_PLACE_PATH, 0, 0); } +money32 footpath_place_remove_intersecting(sint32 type, sint32 x, sint32 y, sint32 z, sint32 slope, sint32 flags, sint32 direction) +{ + return game_do_command(x, (slope << 8) | flags, y, (type << 8) | z, GAME_COMMAND_PLACE_PATH, 0, FOOTPATH_CLEAR_DIRECTIONAL | direction); +} + void footpath_remove(sint32 x, sint32 y, sint32 z, sint32 flags) { game_do_command(x, flags, y, z, GAME_COMMAND_REMOVE_PATH, 0, 0); diff --git a/src/openrct2/world/footpath.h b/src/openrct2/world/footpath.h index 88f0b7fe63..1c2fba1637 100644 --- a/src/openrct2/world/footpath.h +++ b/src/openrct2/world/footpath.h @@ -58,6 +58,11 @@ enum { FOOTPATH_SEARCH_TOO_COMPLEX }; +enum +{ + FOOTPATH_CLEAR_DIRECTIONAL = (1 << 8), // Flag set when direction is used. +}; + extern uint8 gFootpathProvisionalFlags; extern rct_xyz16 gFootpathProvisionalPosition; extern uint8 gFootpathProvisionalType; @@ -79,6 +84,7 @@ void game_command_place_footpath(sint32 *eax, sint32 *ebx, sint32 *ecx, sint32 * void game_command_place_footpath_from_track(sint32 *eax, sint32 *ebx, sint32 *ecx, sint32 *edx, sint32 *esi, sint32 *edi, sint32 *ebp); void game_command_remove_footpath(sint32 *eax, sint32 *ebx, sint32 *ecx, sint32 *edx, sint32 *esi, sint32 *edi, sint32 *ebp); money32 footpath_place(sint32 type, sint32 x, sint32 y, sint32 z, sint32 slope, sint32 flags); +money32 footpath_place_remove_intersecting(sint32 type, sint32 x, sint32 y, sint32 z, sint32 slope, sint32 flags, sint32 direction); void footpath_remove(sint32 x, sint32 y, sint32 z, sint32 flags); money32 footpath_provisional_set(sint32 type, sint32 x, sint32 y, sint32 z, sint32 slope); void footpath_provisional_remove();