diff --git a/contributors.md b/contributors.md index 95d071b7d3..b019e53a51 100644 --- a/contributors.md +++ b/contributors.md @@ -73,6 +73,7 @@ The following people are not part of the project team, but have been contributin * Harrison Gentry (hgentry) - Date-changing command, misc. * Joshua Moerman (Jaxan) - Misc. * Nicolas Hawrysh (xp4xbox) - Misc. +* Albert Morgese (Fusxfaranto) - Misc. ## Bug fixes * (halfbro) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 8ae021dc93..ebe5217672 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -1,5 +1,6 @@ 0.1.3 (in development) ------------------------------------------------------------------------ +- Feature: [#1675] Auto-rotate shops to face footpaths. - Feature: [#7187] Option for early scenario completion. - Feature: [#7266] Make headless instances use an interactive terminal with access to the in-game console API. - Feature: [#7267] Leverage more historical data in Finances window. diff --git a/src/openrct2-ui/windows/RideConstruction.cpp b/src/openrct2-ui/windows/RideConstruction.cpp index 4954b2447d..84632a65dd 100644 --- a/src/openrct2-ui/windows/RideConstruction.cpp +++ b/src/openrct2-ui/windows/RideConstruction.cpp @@ -454,6 +454,7 @@ static sint32 _trackPlaceShiftZ; static sint32 _trackPlaceZ; static money32 _trackPlaceCost; static bool _autoOpeningShop; +static bool _autoRotatingShop; static uint8 _currentlyShowingBrakeOrBoosterSpeed; static bool _boosterTrackSelected; @@ -613,6 +614,7 @@ rct_window *window_ride_construction_open() _currentTrackSelectionFlags = 0; _rideConstructionArrowPulseTime = 0; _autoOpeningShop = false; + _autoRotatingShop = true; _trackPlaceCtrlState = false; _trackPlaceShiftState = false; return w; @@ -1866,6 +1868,7 @@ static void window_ride_construction_mouseup_demolish(rct_window* w) */ static void window_ride_construction_rotate(rct_window *w) { + _autoRotatingShop = false; _currentTrackPieceDirection = (_currentTrackPieceDirection + 1) & 3; ride_construction_invalidate_current_track(); _currentTrackPrice = MONEY32_UNDEFINED; @@ -3425,6 +3428,70 @@ void ride_construction_toolupdate_construct(sint32 screenX, sint32 screenY) _currentTrackBeginZ += 16; } + if (_autoRotatingShop && + _rideConstructionState == RIDE_CONSTRUCTION_STATE_PLACE && + ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_IS_SHOP)) + { + rct_tile_element *pathsByDir[4]; + constexpr sLocationXY8 DirOffsets[4] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; + + bool keepOrientation = false; + for (sint8 i = 0; i < 4; i++) + { + pathsByDir[i] = map_get_footpath_element( + (x >> 5) + DirOffsets[i].x, + (y >> 5) + DirOffsets[i].y, + z >> 3 + ); + + if (pathsByDir[i] && + footpath_element_is_sloped(pathsByDir[i]) && + footpath_element_get_slope_direction(pathsByDir[i]) != i) + { + pathsByDir[i] = nullptr; + } + + // Sloped path on the level below + if (!pathsByDir[i]) + { + pathsByDir[i] = map_get_footpath_element( + (x >> 5) + DirOffsets[i].x, + (y >> 5) + DirOffsets[i].y, + (z >> 3) - 2 + ); + + if (pathsByDir[i] && + (!footpath_element_is_sloped(pathsByDir[i]) || + footpath_element_get_slope_direction(pathsByDir[i]) != (i ^ 2))) + { + pathsByDir[i] = nullptr; + } + } + + if (pathsByDir[i] && i == _currentTrackPieceDirection) + { + keepOrientation = true; + break; + } + } + + if (!keepOrientation) + { + for (sint8 i = 0; i < 4; i++) + { + if (pathsByDir[i]) + { + _currentTrackPieceDirection = i; + + window_ride_construction_update_state(&trackType, &trackDirection, &rideIndex, &liftHillAndAlternativeState, &x, &y, &z, nullptr); + place_provisional_track_piece(rideIndex, trackType, trackDirection, liftHillAndAlternativeState, x, y, z); + gMapSelectArrowDirection = _currentTrackPieceDirection; + break; + } + } + } + } + window_ride_construction_update_active_elements(); map_invalidate_map_selection_tiles(); } diff --git a/src/openrct2/world/Footpath.cpp b/src/openrct2/world/Footpath.cpp index b521212d11..bffb3ddb58 100644 --- a/src/openrct2/world/Footpath.cpp +++ b/src/openrct2/world/Footpath.cpp @@ -129,7 +129,7 @@ static void automatically_set_peep_spawn(CoordsXYZ location) peepSpawn->z = location.z; } -static rct_tile_element *map_get_footpath_element(sint32 x, sint32 y, sint32 z) +rct_tile_element *map_get_footpath_element(sint32 x, sint32 y, sint32 z) { rct_tile_element *tileElement; diff --git a/src/openrct2/world/Footpath.h b/src/openrct2/world/Footpath.h index 0234de34a3..00d7ef9ac6 100644 --- a/src/openrct2/world/Footpath.h +++ b/src/openrct2/world/Footpath.h @@ -128,6 +128,7 @@ extern uint8 gFootpathGroundFlags; extern const LocationXY16 word_981D6C[4]; +rct_tile_element *map_get_footpath_element(sint32 x, sint32 y, sint32 z); money32 footpath_remove_real(sint32 x, sint32 y, sint32 z, sint32 flags); void game_command_place_footpath(sint32 * eax, sint32 * ebx, sint32 * ecx, sint32 * edx, sint32 * esi, sint32 * edi, sint32 * ebp); void game_command_place_footpath_from_track(sint32 * eax, sint32 * ebx, sint32 * ecx, sint32 * edx, sint32 * esi, sint32 * edi, sint32 * ebp);