From 64fc76009a8abed02a347ac75382e159dbaca1c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Sat, 21 Jan 2017 01:21:10 +0100 Subject: [PATCH] Strip ghost flag from elements on loading Ghost elements are notoriously a reason of network desyncs, because they don't get transferred over network. They are meant to be local only and disregarded by any logic, but it is not yet the case in many places. Upon saving, we *remove* all the ghost elements (by calling `scenario_fix_ghosts`), based on assumption they can only be caused by local interaction. Testing has shown there are `sv6`s in the wild that have elements marked as ghosts and this could lead to a situation where we strip away parts of the park. This also causes network desyncs for reason stated above. As we strip elements with ghost flag from saves anyway, it should be safe to assume none of our saves introduce ghosts and this issue is limited to hacked parks only. One example of such park is [Cocopa Bay](http://www.nedesigns.com/park/3473/cocopa-bay/). This change removes the flag on all map elements while importing. This is much less invasive than removing all ghost elements on importing, as they may contain some actual data. This ~~fixes~~ hides the desync that could be seen in the Cocopa Bay park. As this doesn't change any in-game logic, no network version update is necessary. #5094 --- src/openrct2/rct2/S6Importer.cpp | 1 + src/openrct2/world/map.c | 17 +++++++++++++++++ src/openrct2/world/map.h | 1 + 3 files changed, 19 insertions(+) diff --git a/src/openrct2/rct2/S6Importer.cpp b/src/openrct2/rct2/S6Importer.cpp index 1815ad1d62..49c4dd825b 100644 --- a/src/openrct2/rct2/S6Importer.cpp +++ b/src/openrct2/rct2/S6Importer.cpp @@ -364,6 +364,7 @@ void S6Importer::Import() { throw ObjectLoadException(); } + map_strip_ghost_flag_from_elements(); map_update_tile_pointers(); game_convert_strings_to_utf8(); map_count_remaining_land_rights(); diff --git a/src/openrct2/world/map.c b/src/openrct2/world/map.c index 87b79f8c5a..067dd02185 100644 --- a/src/openrct2/world/map.c +++ b/src/openrct2/world/map.c @@ -429,6 +429,23 @@ void map_count_remaining_land_rights() } } +/** + * This is meant to strip MAP_ELEMENT_FLAG_GHOST flag from all elements when + * importing a park. + * + * This can only exist in hacked parks, as we remove ghost elements while saving. + * + * This is less invasive than removing ghost elements themselves, as they can + * contain valid data. + */ +void map_strip_ghost_flag_from_elements() +{ + rct_map_element *mapElement = gMapElements; + do { + mapElement->flags &= ~MAP_ELEMENT_FLAG_GHOST; + } while (++mapElement < gMapElements + 0x30000); +} + /** * * rct2: 0x0068AFFD diff --git a/src/openrct2/world/map.h b/src/openrct2/world/map.h index 188acb5e8f..c9829a59bd 100644 --- a/src/openrct2/world/map.h +++ b/src/openrct2/world/map.h @@ -394,6 +394,7 @@ extern uint8 gUnk9E2E28; void map_init(sint32 size); void map_count_remaining_land_rights(); +void map_strip_ghost_flag_from_elements(); void map_update_tile_pointers(); rct_map_element *map_get_first_element_at(sint32 x, sint32 y); void map_set_tile_elements(sint32 x, sint32 y, rct_map_element *elements);