Fix #3852: Desync constructing path with scenery in its way.

This commit is contained in:
ZehMatt 2017-08-05 18:59:11 +02:00 committed by Michał Janiszewski
parent 6b48f4344e
commit 304a7f3f45
5 changed files with 30 additions and 20 deletions

View File

@ -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

View File

@ -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

View File

@ -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(

View File

@ -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);

View File

@ -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();