2014-04-11 03:42:39 +02:00
/*****************************************************************************
2020-05-01 22:32:41 +02:00
* Copyright ( c ) 2014 - 2020 OpenRCT2 developers
2014-04-11 03:42:39 +02:00
*
2018-06-15 14:07:34 +02:00
* For a complete list of all authors , please refer to contributors . md
* Interested in contributing ? Visit https : //github.com/OpenRCT2/OpenRCT2
2014-04-11 03:42:39 +02:00
*
2018-06-15 14:07:34 +02:00
* OpenRCT2 is licensed under the GNU General Public License version 3.
2014-04-11 03:42:39 +02:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2018-06-22 23:21:44 +02:00
# include "../UiContext.h"
# include "../interface/InGameConsole.h"
2020-02-11 22:26:05 +01:00
# include "../scripting/CustomMenu.h"
2017-10-17 22:31:05 +02:00
2018-08-12 13:50:40 +02:00
# include <algorithm>
2018-11-21 23:16:04 +01:00
# include <iterator>
2018-08-12 11:47:46 +02:00
# include <limits>
2018-06-22 23:21:44 +02:00
# include <openrct2-ui/interface/Dropdown.h>
# include <openrct2-ui/interface/LandTool.h>
# include <openrct2-ui/interface/Viewport.h>
# include <openrct2-ui/interface/Widget.h>
# include <openrct2-ui/windows/Window.h>
2017-12-13 13:02:24 +01:00
# include <openrct2/Cheats.h>
2017-11-11 02:57:45 +01:00
# include <openrct2/Context.h>
# include <openrct2/Editor.h>
2018-11-19 23:10:54 +01:00
# include <openrct2/Game.h>
2017-12-12 14:52:57 +01:00
# include <openrct2/Input.h>
2018-06-22 23:21:44 +02:00
# include <openrct2/OpenRCT2.h>
# include <openrct2/ParkImporter.h>
2019-04-06 10:44:07 +02:00
# include <openrct2/actions/BannerPlaceAction.hpp>
2019-04-07 10:15:41 +02:00
# include <openrct2/actions/BannerSetColourAction.hpp>
2019-01-02 12:59:37 +01:00
# include <openrct2/actions/ClearAction.hpp>
2020-11-03 09:17:29 +01:00
# include <openrct2/actions/FootpathAdditionPlaceAction.hpp>
2019-03-04 17:57:01 +01:00
# include <openrct2/actions/LandLowerAction.hpp>
# include <openrct2/actions/LandRaiseAction.hpp>
2019-03-16 23:04:58 +01:00
# include <openrct2/actions/LandSmoothAction.hpp>
2019-04-05 20:16:23 +02:00
# include <openrct2/actions/LargeSceneryPlaceAction.hpp>
2019-04-07 16:24:07 +02:00
# include <openrct2/actions/LargeScenerySetColourAction.hpp>
2019-02-21 10:34:30 +01:00
# include <openrct2/actions/LoadOrQuitAction.hpp>
2019-02-07 17:54:03 +01:00
# include <openrct2/actions/PauseToggleAction.hpp>
2019-05-04 15:28:38 +02:00
# include <openrct2/actions/SetCheatAction.hpp>
2019-02-26 14:19:17 +01:00
# include <openrct2/actions/SmallSceneryPlaceAction.hpp>
2019-04-06 16:59:40 +02:00
# include <openrct2/actions/SmallScenerySetColourAction.hpp>
2019-03-10 10:15:22 +01:00
# include <openrct2/actions/SurfaceSetStyleAction.hpp>
2019-03-25 20:20:31 +01:00
# include <openrct2/actions/WallPlaceAction.hpp>
2019-04-06 20:36:44 +02:00
# include <openrct2/actions/WallSetColourAction.hpp>
2019-03-04 17:57:01 +01:00
# include <openrct2/actions/WaterLowerAction.hpp>
# include <openrct2/actions/WaterRaiseAction.hpp>
2018-06-22 23:21:44 +02:00
# include <openrct2/audio/audio.h>
# include <openrct2/config/Config.h>
2019-02-03 23:30:34 +01:00
# include <openrct2/interface/Chat.h>
2018-06-01 00:16:53 +02:00
# include <openrct2/interface/InteractiveConsole.h>
2017-11-11 02:57:45 +01:00
# include <openrct2/interface/Screenshot.h>
# include <openrct2/network/network.h>
2018-03-04 17:44:42 +01:00
# include <openrct2/paint/VirtualFloor.h>
2017-11-11 02:57:45 +01:00
# include <openrct2/peep/Staff.h>
2018-06-22 23:21:44 +02:00
# include <openrct2/scenario/Scenario.h>
2017-12-13 13:02:24 +01:00
# include <openrct2/util/Util.h>
2017-11-11 02:57:45 +01:00
# include <openrct2/windows/Intent.h>
2018-01-11 10:59:26 +01:00
# include <openrct2/world/Footpath.h>
2017-11-20 11:13:55 +01:00
# include <openrct2/world/LargeScenery.h>
2018-06-22 23:21:44 +02:00
# include <openrct2/world/Park.h>
2018-01-11 10:59:26 +01:00
# include <openrct2/world/Scenery.h>
2017-11-20 11:13:55 +01:00
# include <openrct2/world/SmallScenery.h>
2018-05-01 16:33:16 +02:00
# include <openrct2/world/Surface.h>
2018-06-22 23:21:44 +02:00
# include <openrct2/world/Wall.h>
# include <string>
2018-03-11 23:25:34 +01:00
2018-06-14 00:29:05 +02:00
using namespace OpenRCT2 ;
2018-03-11 23:25:34 +01:00
using namespace OpenRCT2 : : Ui ;
2014-04-11 03:42:39 +02:00
2018-05-16 20:41:29 +02:00
// clang-format off
2014-04-11 03:42:39 +02:00
enum {
2017-06-06 23:24:18 +02:00
WIDX_PAUSE ,
WIDX_FILE_MENU ,
WIDX_MUTE ,
WIDX_ZOOM_OUT ,
WIDX_ZOOM_IN ,
WIDX_ROTATE ,
WIDX_VIEW_MENU ,
WIDX_MAP ,
WIDX_LAND ,
WIDX_WATER ,
WIDX_SCENERY ,
WIDX_PATH ,
WIDX_CONSTRUCT_RIDE ,
WIDX_RIDES ,
WIDX_PARK ,
WIDX_STAFF ,
WIDX_GUESTS ,
WIDX_CLEAR_SCENERY ,
WIDX_FASTFORWARD ,
WIDX_CHEATS ,
WIDX_DEBUG ,
WIDX_FINANCES ,
WIDX_RESEARCH ,
WIDX_NEWS ,
WIDX_NETWORK ,
2019-02-03 23:30:34 +01:00
WIDX_CHAT ,
2017-06-06 23:24:18 +02:00
WIDX_SEPARATOR ,
2014-04-11 03:42:39 +02:00
} ;
2017-05-02 02:01:29 +02:00
validate_global_widx ( WC_TOP_TOOLBAR , WIDX_PAUSE ) ;
validate_global_widx ( WC_TOP_TOOLBAR , WIDX_LAND ) ;
validate_global_widx ( WC_TOP_TOOLBAR , WIDX_WATER ) ;
validate_global_widx ( WC_TOP_TOOLBAR , WIDX_SCENERY ) ;
validate_global_widx ( WC_TOP_TOOLBAR , WIDX_PATH ) ;
2018-02-14 09:42:26 +01:00
enum FILE_MENU_DDIDX {
2017-06-06 23:24:18 +02:00
DDIDX_NEW_GAME = 0 ,
DDIDX_LOAD_GAME = 1 ,
DDIDX_SAVE_GAME = 2 ,
DDIDX_SAVE_GAME_AS = 3 ,
// separator
DDIDX_ABOUT = 5 ,
DDIDX_OPTIONS = 6 ,
DDIDX_SCREENSHOT = 7 ,
DDIDX_GIANT_SCREENSHOT = 8 ,
// separator
DDIDX_QUIT_TO_MENU = 10 ,
DDIDX_EXIT_OPENRCT2 = 11 ,
2020-08-02 23:38:00 +02:00
// separator
DDIDX_UPDATE_AVAILABLE = 13 ,
2018-02-14 09:42:26 +01:00
} ;
2014-08-10 10:34:27 +02:00
2018-02-14 09:42:26 +01:00
enum TOP_TOOLBAR_VIEW_MENU_DDIDX {
2017-06-06 23:24:18 +02:00
DDIDX_UNDERGROUND_INSIDE = 0 ,
DDIDX_HIDE_BASE = 1 ,
DDIDX_HIDE_VERTICAL = 2 ,
DDIDX_SEETHROUGH_RIDES = 4 ,
DDIDX_SEETHROUGH_SCENARY = 5 ,
DDIDX_SEETHROUGH_PATHS = 6 ,
DDIDX_INVISIBLE_SUPPORTS = 7 ,
DDIDX_INVISIBLE_PEEPS = 8 ,
DDIDX_LAND_HEIGHTS = 10 ,
DDIDX_TRACK_HEIGHTS = 11 ,
DDIDX_PATH_HEIGHTS = 12 ,
// 13 is a separator
DDIDX_VIEW_CLIPPING = 14 ,
2018-01-11 00:26:19 +01:00
DDIDX_HIGHLIGHT_PATH_ISSUES = 15 ,
2017-06-06 23:24:18 +02:00
TOP_TOOLBAR_VIEW_MENU_COUNT
2018-02-14 09:42:26 +01:00
} ;
2015-02-10 15:41:35 +01:00
2018-02-14 09:42:26 +01:00
enum TOP_TOOLBAR_DEBUG_DDIDX {
2017-06-06 23:24:18 +02:00
DDIDX_CONSOLE = 0 ,
2019-03-17 12:52:32 +01:00
DDIDX_DEBUG_PAINT = 1 ,
2017-06-06 23:24:18 +02:00
TOP_TOOLBAR_DEBUG_COUNT
2018-02-14 09:42:26 +01:00
} ;
2015-06-01 03:33:56 +02:00
2018-02-14 09:42:26 +01:00
enum TOP_TOOLBAR_NETWORK_DDIDX {
2019-01-29 19:51:07 +01:00
DDIDX_MULTIPLAYER = 0 ,
DDIDX_NETWORK = 1 ,
2019-02-05 06:57:09 +01:00
DDIDX_MULTIPLAYER_RECONNECT = 2 ,
TOP_TOOLBAR_NETWORK_COUNT
2018-02-14 09:42:26 +01:00
} ;
2015-07-16 19:32:43 +02:00
2015-06-26 23:40:09 +02:00
enum {
2017-06-06 23:24:18 +02:00
DDIDX_CHEATS ,
2019-03-17 12:52:32 +01:00
DDIDX_TILE_INSPECTOR = 1 ,
DDIDX_OBJECT_SELECTION = 2 ,
DDIDX_INVENTIONS_LIST = 3 ,
DDIDX_SCENARIO_OPTIONS = 4 ,
2020-10-11 18:41:23 +02:00
DDIDX_OBJECTIVE_OPTIONS = 5 ,
// 6 is a separator
DDIDX_ENABLE_SANDBOX_MODE = 7 ,
DDIDX_DISABLE_CLEARANCE_CHECKS = 8 ,
DDIDX_DISABLE_SUPPORT_LIMITS = 9 ,
2019-03-17 12:52:32 +01:00
TOP_TOOLBAR_CHEATS_COUNT
2015-06-26 23:40:09 +02:00
} ;
2016-01-18 00:37:14 +01:00
enum {
2017-06-06 23:24:18 +02:00
DDIDX_SHOW_MAP ,
DDIDX_OPEN_VIEWPORT ,
2016-01-18 00:37:14 +01:00
} ;
enum {
2017-06-06 23:24:18 +02:00
DDIDX_ROTATE_CLOCKWISE ,
DDIDX_ROTATE_ANTI_CLOCKWISE ,
2016-01-18 00:37:14 +01:00
} ;
2015-02-05 22:22:35 +01:00
# pragma region Toolbar_widget_ordering
// from left to right
2018-06-20 17:28:51 +02:00
static constexpr const int32_t left_aligned_widgets_order [ ] = {
2017-06-06 23:24:18 +02:00
WIDX_PAUSE ,
WIDX_FASTFORWARD ,
WIDX_FILE_MENU ,
WIDX_MUTE ,
WIDX_NETWORK ,
2019-02-03 23:30:34 +01:00
WIDX_CHAT ,
2017-06-06 23:24:18 +02:00
WIDX_CHEATS ,
WIDX_DEBUG ,
WIDX_SEPARATOR ,
WIDX_ZOOM_OUT ,
WIDX_ZOOM_IN ,
WIDX_ROTATE ,
WIDX_VIEW_MENU ,
WIDX_MAP ,
2015-02-05 22:22:35 +01:00
} ;
// from right to left
2018-06-20 17:28:51 +02:00
static constexpr const int32_t right_aligned_widgets_order [ ] = {
2017-06-06 23:24:18 +02:00
WIDX_NEWS ,
WIDX_GUESTS ,
WIDX_STAFF ,
WIDX_PARK ,
WIDX_RIDES ,
WIDX_RESEARCH ,
WIDX_FINANCES ,
WIDX_SEPARATOR ,
WIDX_CONSTRUCT_RIDE ,
WIDX_PATH ,
WIDX_SCENERY ,
WIDX_WATER ,
WIDX_LAND ,
WIDX_CLEAR_SCENERY
2015-02-05 22:22:35 +01:00
} ;
# pragma endregion
2015-02-09 19:32:58 +01:00
static rct_widget window_top_toolbar_widgets [ ] = {
2020-11-27 04:14:20 +01:00
MakeRemapWidget ( { 0 , 0 } , { 30 , TOP_TOOLBAR_HEIGHT + 1 } , WindowWidgetType : : TrnBtn , WindowColour : : Primary , SPR_TOOLBAR_PAUSE , STR_PAUSE_GAME_TIP ) , // Pause
MakeRemapWidget ( { 60 , 0 } , { 30 , TOP_TOOLBAR_HEIGHT + 1 } , WindowWidgetType : : TrnBtn , WindowColour : : Primary , SPR_TOOLBAR_FILE , STR_DISC_AND_GAME_OPTIONS_TIP ) , // File menu
MakeRemapWidget ( { 250 , 0 } , { 30 , TOP_TOOLBAR_HEIGHT + 1 } , WindowWidgetType : : TrnBtn , WindowColour : : Primary , SPR_G2_TOOLBAR_MUTE , STR_TOOLBAR_MUTE_TIP ) , // Mute
MakeRemapWidget ( { 100 , 0 } , { 30 , TOP_TOOLBAR_HEIGHT + 1 } , WindowWidgetType : : TrnBtn , WindowColour : : Secondary , SPR_TOOLBAR_ZOOM_OUT , STR_ZOOM_OUT_TIP ) , // Zoom out
MakeRemapWidget ( { 130 , 0 } , { 30 , TOP_TOOLBAR_HEIGHT + 1 } , WindowWidgetType : : TrnBtn , WindowColour : : Secondary , SPR_TOOLBAR_ZOOM_IN , STR_ZOOM_IN_TIP ) , // Zoom in
MakeRemapWidget ( { 160 , 0 } , { 30 , TOP_TOOLBAR_HEIGHT + 1 } , WindowWidgetType : : TrnBtn , WindowColour : : Secondary , SPR_TOOLBAR_ROTATE , STR_ROTATE_TIP ) , // Rotate camera
MakeRemapWidget ( { 190 , 0 } , { 30 , TOP_TOOLBAR_HEIGHT + 1 } , WindowWidgetType : : TrnBtn , WindowColour : : Secondary , SPR_TOOLBAR_VIEW , STR_VIEW_OPTIONS_TIP ) , // Transparency menu
MakeRemapWidget ( { 220 , 0 } , { 30 , TOP_TOOLBAR_HEIGHT + 1 } , WindowWidgetType : : TrnBtn , WindowColour : : Secondary , SPR_TOOLBAR_MAP , STR_SHOW_MAP_TIP ) , // Map
MakeRemapWidget ( { 267 , 0 } , { 30 , TOP_TOOLBAR_HEIGHT + 1 } , WindowWidgetType : : TrnBtn , WindowColour : : Tertiary , SPR_TOOLBAR_LAND , STR_ADJUST_LAND_TIP ) , // Land
MakeRemapWidget ( { 297 , 0 } , { 30 , TOP_TOOLBAR_HEIGHT + 1 } , WindowWidgetType : : TrnBtn , WindowColour : : Tertiary , SPR_TOOLBAR_WATER , STR_ADJUST_WATER_TIP ) , // Water
MakeRemapWidget ( { 327 , 0 } , { 30 , TOP_TOOLBAR_HEIGHT + 1 } , WindowWidgetType : : TrnBtn , WindowColour : : Tertiary , SPR_TOOLBAR_SCENERY , STR_PLACE_SCENERY_TIP ) , // Scenery
MakeRemapWidget ( { 357 , 0 } , { 30 , TOP_TOOLBAR_HEIGHT + 1 } , WindowWidgetType : : TrnBtn , WindowColour : : Tertiary , SPR_TOOLBAR_FOOTPATH , STR_BUILD_FOOTPATH_TIP ) , // Path
MakeRemapWidget ( { 387 , 0 } , { 30 , TOP_TOOLBAR_HEIGHT + 1 } , WindowWidgetType : : TrnBtn , WindowColour : : Tertiary , SPR_TOOLBAR_CONSTRUCT_RIDE , STR_BUILD_RIDE_TIP ) , // Construct ride
MakeRemapWidget ( { 490 , 0 } , { 30 , TOP_TOOLBAR_HEIGHT + 1 } , WindowWidgetType : : TrnBtn , WindowColour : : Quaternary , SPR_TOOLBAR_RIDES , STR_RIDES_IN_PARK_TIP ) , // Rides
MakeRemapWidget ( { 520 , 0 } , { 30 , TOP_TOOLBAR_HEIGHT + 1 } , WindowWidgetType : : TrnBtn , WindowColour : : Quaternary , SPR_TOOLBAR_PARK , STR_PARK_INFORMATION_TIP ) , // Park
MakeRemapWidget ( { 550 , 0 } , { 30 , TOP_TOOLBAR_HEIGHT + 1 } , WindowWidgetType : : TrnBtn , WindowColour : : Quaternary , SPR_TAB_TOOLBAR , STR_STAFF_TIP ) , // Staff
MakeRemapWidget ( { 560 , 0 } , { 30 , TOP_TOOLBAR_HEIGHT + 1 } , WindowWidgetType : : TrnBtn , WindowColour : : Quaternary , SPR_TOOLBAR_GUESTS , STR_GUESTS_TIP ) , // Guests
MakeRemapWidget ( { 560 , 0 } , { 30 , TOP_TOOLBAR_HEIGHT + 1 } , WindowWidgetType : : TrnBtn , WindowColour : : Tertiary , SPR_TOOLBAR_CLEAR_SCENERY , STR_CLEAR_SCENERY_TIP ) , // Clear scenery
MakeRemapWidget ( { 30 , 0 } , { 30 , TOP_TOOLBAR_HEIGHT + 1 } , WindowWidgetType : : TrnBtn , WindowColour : : Primary , SPR_TAB_TOOLBAR , STR_GAME_SPEED_TIP ) , // Fast forward
MakeRemapWidget ( { 30 , 0 } , { 30 , TOP_TOOLBAR_HEIGHT + 1 } , WindowWidgetType : : TrnBtn , WindowColour : : Primary , SPR_TAB_TOOLBAR , STR_CHEATS_TIP ) , // Cheats
MakeRemapWidget ( { 30 , 0 } , { 30 , TOP_TOOLBAR_HEIGHT + 1 } , WindowWidgetType : : TrnBtn , WindowColour : : Primary , SPR_TAB_TOOLBAR , STR_DEBUG_TIP ) , // Debug
MakeRemapWidget ( { 30 , 0 } , { 30 , TOP_TOOLBAR_HEIGHT + 1 } , WindowWidgetType : : TrnBtn , WindowColour : : Quaternary , SPR_TAB_TOOLBAR , STR_SCENARIO_OPTIONS_FINANCIAL_TIP ) , // Finances
MakeRemapWidget ( { 30 , 0 } , { 30 , TOP_TOOLBAR_HEIGHT + 1 } , WindowWidgetType : : TrnBtn , WindowColour : : Quaternary , SPR_TAB_TOOLBAR , STR_FINANCES_RESEARCH_TIP ) , // Research
MakeRemapWidget ( { 30 , 0 } , { 30 , TOP_TOOLBAR_HEIGHT + 1 } , WindowWidgetType : : TrnBtn , WindowColour : : Quaternary , SPR_TAB_TOOLBAR , STR_SHOW_RECENT_MESSAGES_TIP ) , // News
MakeRemapWidget ( { 30 , 0 } , { 30 , TOP_TOOLBAR_HEIGHT + 1 } , WindowWidgetType : : TrnBtn , WindowColour : : Primary , SPR_G2_TOOLBAR_MULTIPLAYER , STR_SHOW_MULTIPLAYER_STATUS_TIP ) , // Network
MakeRemapWidget ( { 30 , 0 } , { 30 , TOP_TOOLBAR_HEIGHT + 1 } , WindowWidgetType : : TrnBtn , WindowColour : : Primary , SPR_TAB_TOOLBAR , STR_TOOLBAR_CHAT_TIP ) , // Chat
MakeWidget ( { 0 , 0 } , { 10 , 1 } , WindowWidgetType : : Empty , WindowColour : : Primary ) , // Artificial widget separator
2017-06-06 23:24:18 +02:00
{ WIDGETS_END } ,
2014-04-11 03:42:39 +02:00
} ;
2017-05-01 15:41:45 +02:00
static void window_top_toolbar_mouseup ( rct_window * w , rct_widgetindex widgetIndex ) ;
2017-07-03 23:09:46 +02:00
static void window_top_toolbar_mousedown ( rct_window * w , rct_widgetindex widgetIndex , rct_widget * widget ) ;
2018-06-20 17:28:51 +02:00
static void window_top_toolbar_dropdown ( rct_window * w , rct_widgetindex widgetIndex , int32_t dropdownIndex ) ;
2020-02-29 03:43:29 +01:00
static void window_top_toolbar_tool_update ( rct_window * w , rct_widgetindex widgetIndex , const ScreenCoordsXY & screenCoords ) ;
static void window_top_toolbar_tool_down ( rct_window * w , rct_widgetindex widgetIndex , const ScreenCoordsXY & screenCoords ) ;
static void window_top_toolbar_tool_drag ( rct_window * w , rct_widgetindex widgetIndex , const ScreenCoordsXY & screenCoords ) ;
static void window_top_toolbar_tool_up ( rct_window * w , rct_widgetindex widgetIndex , const ScreenCoordsXY & screenCoordsy ) ;
2017-05-01 15:41:45 +02:00
static void window_top_toolbar_tool_abort ( rct_window * w , rct_widgetindex widgetIndex ) ;
2015-07-10 02:39:16 +02:00
static void window_top_toolbar_invalidate ( rct_window * w ) ;
static void window_top_toolbar_paint ( rct_window * w , rct_drawpixelinfo * dpi ) ;
2020-09-28 20:36:15 +02:00
static rct_window_event_list window_top_toolbar_events ( [ ] ( auto & events )
{
events . mouse_up = & window_top_toolbar_mouseup ;
events . mouse_down = & window_top_toolbar_mousedown ;
events . dropdown = & window_top_toolbar_dropdown ;
events . tool_update = & window_top_toolbar_tool_update ;
events . tool_down = & window_top_toolbar_tool_down ;
events . tool_drag = & window_top_toolbar_tool_drag ;
events . tool_up = & window_top_toolbar_tool_up ;
events . tool_abort = & window_top_toolbar_tool_abort ;
events . invalidate = & window_top_toolbar_invalidate ;
events . paint = & window_top_toolbar_paint ;
} ) ;
2018-05-16 20:41:29 +02:00
// clang-format on
2014-04-11 03:42:39 +02:00
2018-06-22 23:21:44 +02:00
static void top_toolbar_init_view_menu ( rct_window * window , rct_widget * widget ) ;
2018-06-20 17:28:51 +02:00
static void top_toolbar_view_menu_dropdown ( int16_t dropdownIndex ) ;
2020-02-11 22:26:05 +01:00
static void top_toolbar_init_map_menu ( rct_window * window , rct_widget * widget ) ;
static void top_toolbar_map_menu_dropdown ( int16_t dropdownIndex ) ;
2018-06-22 23:21:44 +02:00
static void top_toolbar_init_fastforward_menu ( rct_window * window , rct_widget * widget ) ;
2018-06-20 17:28:51 +02:00
static void top_toolbar_fastforward_menu_dropdown ( int16_t dropdownIndex ) ;
2018-06-22 23:21:44 +02:00
static void top_toolbar_init_rotate_menu ( rct_window * window , rct_widget * widget ) ;
2018-06-20 17:28:51 +02:00
static void top_toolbar_rotate_menu_dropdown ( int16_t dropdownIndex ) ;
2019-03-17 12:52:32 +01:00
static void top_toolbar_init_cheats_menu ( rct_window * window , rct_widget * widget ) ;
static void top_toolbar_cheats_menu_dropdown ( int16_t dropdownIndex ) ;
2018-06-22 23:21:44 +02:00
static void top_toolbar_init_debug_menu ( rct_window * window , rct_widget * widget ) ;
2018-06-20 17:28:51 +02:00
static void top_toolbar_debug_menu_dropdown ( int16_t dropdownIndex ) ;
2018-06-22 23:21:44 +02:00
static void top_toolbar_init_network_menu ( rct_window * window , rct_widget * widget ) ;
2018-06-20 17:28:51 +02:00
static void top_toolbar_network_menu_dropdown ( int16_t dropdownIndex ) ;
2015-02-10 15:41:35 +01:00
2017-08-06 14:41:13 +02:00
static void toggle_footpath_window ( ) ;
2018-06-22 23:21:44 +02:00
static void toggle_land_window ( rct_window * topToolbar , rct_widgetindex widgetIndex ) ;
static void toggle_clear_scenery_window ( rct_window * topToolbar , rct_widgetindex widgetIndex ) ;
static void toggle_water_window ( rct_window * topToolbar , rct_widgetindex widgetIndex ) ;
2015-02-10 15:41:35 +01:00
2018-06-20 17:28:51 +02:00
static money32 selection_lower_land ( uint8_t flags ) ;
static money32 selection_raise_land ( uint8_t flags ) ;
2015-05-26 21:36:05 +02:00
2019-01-02 12:59:37 +01:00
static ClearAction GetClearAction ( ) ;
2020-04-18 00:34:32 +02:00
static bool _landToolBlocked ;
2018-06-22 23:21:44 +02:00
static uint8_t _unkF64F0E ;
static int16_t _unkF64F0A ;
2015-05-25 21:36:40 +02:00
2014-04-11 03:42:39 +02:00
/**
* Creates the main game top toolbar window .
* rct2 : 0x0066B485 ( part of 0x0066B3E8 )
*/
2018-06-22 23:21:44 +02:00
rct_window * window_top_toolbar_open ( )
2014-04-11 03:42:39 +02:00
{
2020-11-04 05:52:23 +01:00
rct_window * window = WindowCreate (
2019-10-19 13:07:03 +02:00
ScreenCoordsXY ( 0 , 0 ) , context_get_width ( ) , TOP_TOOLBAR_HEIGHT + 1 , & window_top_toolbar_events , WC_TOP_TOOLBAR ,
2018-06-22 23:21:44 +02:00
WF_STICK_TO_FRONT | WF_TRANSPARENT | WF_NO_BACKGROUND ) ;
2017-06-06 23:24:18 +02:00
window - > widgets = window_top_toolbar_widgets ;
2020-11-04 05:52:23 +01:00
WindowInitScrollWidgets ( window ) ;
2017-11-11 02:57:45 +01:00
return window ;
2014-04-11 03:42:39 +02:00
}
/**
2015-10-20 20:16:30 +02:00
*
2014-04-11 03:42:39 +02:00
* rct2 : 0x0066C957
*/
2018-06-22 23:21:44 +02:00
static void window_top_toolbar_mouseup ( rct_window * w , rct_widgetindex widgetIndex )
2014-04-11 03:42:39 +02:00
{
2018-06-22 23:21:44 +02:00
rct_window * mainWindow ;
2017-06-06 23:24:18 +02:00
2018-06-22 23:21:44 +02:00
switch ( widgetIndex )
{
case WIDX_PAUSE :
if ( network_get_mode ( ) ! = NETWORK_MODE_CLIENT )
{
2019-02-07 17:54:03 +01:00
auto pauseToggleAction = PauseToggleAction ( ) ;
GameActions : : Execute ( & pauseToggleAction ) ;
2018-06-22 23:21:44 +02:00
}
break ;
case WIDX_ZOOM_OUT :
if ( ( mainWindow = window_get_main ( ) ) ! = nullptr )
window_zoom_out ( mainWindow , false ) ;
break ;
case WIDX_ZOOM_IN :
if ( ( mainWindow = window_get_main ( ) ) ! = nullptr )
window_zoom_in ( mainWindow , false ) ;
break ;
case WIDX_CLEAR_SCENERY :
toggle_clear_scenery_window ( w , WIDX_CLEAR_SCENERY ) ;
break ;
case WIDX_LAND :
toggle_land_window ( w , WIDX_LAND ) ;
break ;
case WIDX_WATER :
toggle_water_window ( w , WIDX_WATER ) ;
break ;
case WIDX_SCENERY :
if ( ! tool_set ( w , WIDX_SCENERY , TOOL_ARROW ) )
{
input_set_flag ( INPUT_FLAG_6 , true ) ;
context_open_window ( WC_SCENERY ) ;
}
break ;
case WIDX_PATH :
toggle_footpath_window ( ) ;
break ;
case WIDX_CONSTRUCT_RIDE :
context_open_window ( WC_CONSTRUCT_RIDE ) ;
break ;
case WIDX_RIDES :
context_open_window ( WC_RIDE_LIST ) ;
break ;
case WIDX_PARK :
context_open_window ( WC_PARK_INFORMATION ) ;
break ;
case WIDX_STAFF :
context_open_window ( WC_STAFF_LIST ) ;
break ;
case WIDX_GUESTS :
context_open_window ( WC_GUEST_LIST ) ;
break ;
case WIDX_FINANCES :
context_open_window ( WC_FINANCES ) ;
break ;
case WIDX_RESEARCH :
context_open_window ( WC_RESEARCH ) ;
break ;
case WIDX_NEWS :
context_open_window ( WC_RECENT_NEWS ) ;
break ;
case WIDX_MUTE :
2020-10-06 23:34:42 +02:00
OpenRCT2 : : Audio : : ToggleAllSounds ( ) ;
2018-06-22 23:21:44 +02:00
break ;
2019-02-03 23:30:34 +01:00
case WIDX_CHAT :
if ( chat_available ( ) )
{
chat_toggle ( ) ;
}
else
{
2020-08-27 00:01:15 +02:00
context_show_error ( STR_CHAT_UNAVAILABLE , STR_NONE , { } ) ;
2019-02-03 23:30:34 +01:00
}
break ;
2017-06-06 23:24:18 +02:00
}
2014-04-11 03:42:39 +02:00
}
/**
2015-10-20 20:16:30 +02:00
*
2014-04-11 03:42:39 +02:00
* rct2 : 0x0066CA3B
*/
2018-06-22 23:21:44 +02:00
static void window_top_toolbar_mousedown ( rct_window * w , rct_widgetindex widgetIndex , rct_widget * widget )
2014-04-11 03:42:39 +02:00
{
2018-06-20 17:28:51 +02:00
int32_t numItems ;
2017-06-06 23:24:18 +02:00
2018-06-22 23:21:44 +02:00
switch ( widgetIndex )
{
case WIDX_FILE_MENU :
if ( gScreenFlags & ( SCREEN_FLAGS_TRACK_DESIGNER | SCREEN_FLAGS_TRACK_MANAGER ) )
{
gDropdownItemsFormat [ 0 ] = STR_ABOUT ;
gDropdownItemsFormat [ 1 ] = STR_OPTIONS ;
gDropdownItemsFormat [ 2 ] = STR_SCREENSHOT ;
gDropdownItemsFormat [ 3 ] = STR_GIANT_SCREENSHOT ;
gDropdownItemsFormat [ 4 ] = STR_EMPTY ;
gDropdownItemsFormat [ 5 ] = STR_QUIT_TRACK_DESIGNS_MANAGER ;
gDropdownItemsFormat [ 6 ] = STR_EXIT_OPENRCT2 ;
if ( gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER )
gDropdownItemsFormat [ 5 ] = STR_QUIT_ROLLERCOASTER_DESIGNER ;
numItems = 7 ;
}
else if ( gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR )
{
gDropdownItemsFormat [ 0 ] = STR_LOAD_LANDSCAPE ;
gDropdownItemsFormat [ 1 ] = STR_SAVE_LANDSCAPE ;
gDropdownItemsFormat [ 2 ] = STR_EMPTY ;
gDropdownItemsFormat [ 3 ] = STR_ABOUT ;
gDropdownItemsFormat [ 4 ] = STR_OPTIONS ;
gDropdownItemsFormat [ 5 ] = STR_SCREENSHOT ;
gDropdownItemsFormat [ 6 ] = STR_GIANT_SCREENSHOT ;
gDropdownItemsFormat [ 7 ] = STR_EMPTY ;
gDropdownItemsFormat [ 8 ] = STR_QUIT_SCENARIO_EDITOR ;
gDropdownItemsFormat [ 9 ] = STR_EXIT_OPENRCT2 ;
numItems = 10 ;
}
else
{
gDropdownItemsFormat [ 0 ] = STR_NEW_GAME ;
gDropdownItemsFormat [ 1 ] = STR_LOAD_GAME ;
gDropdownItemsFormat [ 2 ] = STR_SAVE_GAME ;
gDropdownItemsFormat [ 3 ] = STR_SAVE_GAME_AS ;
gDropdownItemsFormat [ 4 ] = STR_EMPTY ;
gDropdownItemsFormat [ 5 ] = STR_ABOUT ;
gDropdownItemsFormat [ 6 ] = STR_OPTIONS ;
gDropdownItemsFormat [ 7 ] = STR_SCREENSHOT ;
gDropdownItemsFormat [ 8 ] = STR_GIANT_SCREENSHOT ;
gDropdownItemsFormat [ 9 ] = STR_EMPTY ;
gDropdownItemsFormat [ 10 ] = STR_QUIT_TO_MENU ;
gDropdownItemsFormat [ 11 ] = STR_EXIT_OPENRCT2 ;
numItems = 12 ;
2020-08-02 23:38:00 +02:00
if ( OpenRCT2 : : GetContext ( ) - > HasNewVersionInfo ( ) )
{
gDropdownItemsFormat [ 12 ] = STR_EMPTY ;
gDropdownItemsFormat [ 13 ] = STR_UPDATE_AVAILABLE ;
numItems + = 2 ;
}
2018-06-22 23:21:44 +02:00
}
2020-11-03 09:16:06 +01:00
WindowDropdownShowText (
2020-06-25 03:44:00 +02:00
{ w - > windowPos . x + widget - > left , w - > windowPos . y + widget - > top } , widget - > height ( ) + 1 , w - > colours [ 0 ] | 0x80 ,
2020-11-03 09:16:06 +01:00
Dropdown : : Flag : : StayOpen , numItems ) ;
2018-06-22 23:21:44 +02:00
break ;
case WIDX_CHEATS :
2019-03-17 12:52:32 +01:00
top_toolbar_init_cheats_menu ( w , widget ) ;
2018-06-22 23:21:44 +02:00
break ;
case WIDX_VIEW_MENU :
top_toolbar_init_view_menu ( w , widget ) ;
break ;
case WIDX_MAP :
2020-02-11 22:26:05 +01:00
top_toolbar_init_map_menu ( w , widget ) ;
2018-06-22 23:21:44 +02:00
break ;
case WIDX_FASTFORWARD :
top_toolbar_init_fastforward_menu ( w , widget ) ;
break ;
case WIDX_ROTATE :
top_toolbar_init_rotate_menu ( w , widget ) ;
break ;
case WIDX_DEBUG :
top_toolbar_init_debug_menu ( w , widget ) ;
break ;
case WIDX_NETWORK :
top_toolbar_init_network_menu ( w , widget ) ;
break ;
2017-06-06 23:24:18 +02:00
}
2014-04-11 03:42:39 +02:00
}
2018-06-22 23:21:44 +02:00
static void window_top_toolbar_scenarioselect_callback ( const utf8 * path )
2016-02-10 19:44:00 +01:00
{
2018-06-14 00:29:05 +02:00
window_close_by_class ( WC_EDITOR_OBJECT_SELECTION ) ;
2017-08-23 08:04:36 +02:00
context_load_park_from_file ( path ) ;
2016-02-10 19:44:00 +01:00
}
2014-04-11 03:42:39 +02:00
/**
2015-06-26 23:40:09 +02:00
*
2014-04-11 03:42:39 +02:00
* rct2 : 0x0066C9EA
*/
2018-06-22 23:21:44 +02:00
static void window_top_toolbar_dropdown ( rct_window * w , rct_widgetindex widgetIndex , int32_t dropdownIndex )
2014-04-11 03:42:39 +02:00
{
2018-06-22 23:21:44 +02:00
switch ( widgetIndex )
{
case WIDX_FILE_MENU :
2017-06-06 23:24:18 +02:00
2018-06-22 23:21:44 +02:00
// New game is only available in the normal game. Skip one position to avoid incorrect mappings in the menus of the
// other modes.
if ( gScreenFlags & ( SCREEN_FLAGS_SCENARIO_EDITOR ) )
dropdownIndex + = 1 ;
2017-06-06 23:24:18 +02:00
2018-06-22 23:21:44 +02:00
// Quicksave is only available in the normal game. Skip one position to avoid incorrect mappings in the menus of the
// other modes.
if ( gScreenFlags & ( SCREEN_FLAGS_SCENARIO_EDITOR ) & & dropdownIndex > DDIDX_LOAD_GAME )
dropdownIndex + = 1 ;
2017-06-06 23:24:18 +02:00
2018-06-22 23:21:44 +02:00
// Track designer and track designs manager start with About, not Load/save
if ( gScreenFlags & ( SCREEN_FLAGS_TRACK_DESIGNER | SCREEN_FLAGS_TRACK_MANAGER ) )
dropdownIndex + = DDIDX_ABOUT ;
2017-06-06 23:24:18 +02:00
2018-06-22 23:21:44 +02:00
switch ( dropdownIndex )
{
case DDIDX_NEW_GAME :
{
auto intent = Intent ( WC_SCENARIO_SELECT ) ;
2020-04-18 13:32:48 +02:00
intent . putExtra ( INTENT_EXTRA_CALLBACK , reinterpret_cast < void * > ( window_top_toolbar_scenarioselect_callback ) ) ;
2018-06-22 23:21:44 +02:00
context_open_intent ( & intent ) ;
break ;
}
case DDIDX_LOAD_GAME :
2019-02-21 10:34:30 +01:00
{
auto loadOrQuitAction = LoadOrQuitAction ( LoadOrQuitModes : : OpenSavePrompt ) ;
GameActions : : Execute ( & loadOrQuitAction ) ;
2018-06-22 23:21:44 +02:00
break ;
2019-02-21 10:34:30 +01:00
}
2018-06-22 23:21:44 +02:00
case DDIDX_SAVE_GAME :
tool_cancel ( ) ;
save_game ( ) ;
break ;
case DDIDX_SAVE_GAME_AS :
if ( gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR )
{
auto intent = Intent ( WC_LOADSAVE ) ;
intent . putExtra ( INTENT_EXTRA_LOADSAVE_TYPE , LOADSAVETYPE_SAVE | LOADSAVETYPE_LANDSCAPE ) ;
intent . putExtra ( INTENT_EXTRA_PATH , std : : string { gS6Info . name } ) ;
context_open_intent ( & intent ) ;
}
else
{
tool_cancel ( ) ;
save_game_as ( ) ;
}
break ;
case DDIDX_ABOUT :
context_open_window ( WC_ABOUT ) ;
break ;
case DDIDX_OPTIONS :
context_open_window ( WC_OPTIONS ) ;
break ;
case DDIDX_SCREENSHOT :
gScreenshotCountdown = 10 ;
break ;
case DDIDX_GIANT_SCREENSHOT :
screenshot_giant ( ) ;
break ;
case DDIDX_QUIT_TO_MENU :
2019-02-21 10:34:30 +01:00
{
2018-06-22 23:21:44 +02:00
window_close_by_class ( WC_MANAGE_TRACK_DESIGN ) ;
window_close_by_class ( WC_TRACK_DELETE_PROMPT ) ;
2020-10-03 04:04:59 +02:00
auto loadOrQuitAction = LoadOrQuitAction ( LoadOrQuitModes : : OpenSavePrompt , PromptMode : : SaveBeforeQuit ) ;
2019-02-21 10:34:30 +01:00
GameActions : : Execute ( & loadOrQuitAction ) ;
2018-06-22 23:21:44 +02:00
break ;
2019-02-21 10:34:30 +01:00
}
2018-06-22 23:21:44 +02:00
case DDIDX_EXIT_OPENRCT2 :
context_quit ( ) ;
break ;
2020-08-02 23:38:00 +02:00
case DDIDX_UPDATE_AVAILABLE :
2020-08-13 22:57:14 +02:00
context_open_window_view ( WV_NEW_VERSION_INFO ) ;
2020-08-02 23:38:00 +02:00
break ;
2018-06-22 23:21:44 +02:00
}
2017-06-06 23:24:18 +02:00
break ;
2018-06-22 23:21:44 +02:00
case WIDX_CHEATS :
2019-03-17 12:52:32 +01:00
top_toolbar_cheats_menu_dropdown ( dropdownIndex ) ;
2017-06-06 23:24:18 +02:00
break ;
2018-06-22 23:21:44 +02:00
case WIDX_VIEW_MENU :
top_toolbar_view_menu_dropdown ( dropdownIndex ) ;
2017-06-06 23:24:18 +02:00
break ;
2018-06-22 23:21:44 +02:00
case WIDX_MAP :
2020-02-11 22:26:05 +01:00
top_toolbar_map_menu_dropdown ( dropdownIndex ) ;
2017-06-06 23:24:18 +02:00
break ;
2018-06-22 23:21:44 +02:00
case WIDX_FASTFORWARD :
top_toolbar_fastforward_menu_dropdown ( dropdownIndex ) ;
2017-06-06 23:24:18 +02:00
break ;
2018-06-22 23:21:44 +02:00
case WIDX_ROTATE :
top_toolbar_rotate_menu_dropdown ( dropdownIndex ) ;
2017-06-06 23:24:18 +02:00
break ;
2018-06-22 23:21:44 +02:00
case WIDX_DEBUG :
top_toolbar_debug_menu_dropdown ( dropdownIndex ) ;
break ;
case WIDX_NETWORK :
top_toolbar_network_menu_dropdown ( dropdownIndex ) ;
2017-06-06 23:24:18 +02:00
break ;
}
2014-04-11 03:42:39 +02:00
}
/**
2015-10-20 20:16:30 +02:00
*
2014-04-11 03:42:39 +02:00
* rct2 : 0x0066C810
*/
2018-06-22 23:21:44 +02:00
static void window_top_toolbar_invalidate ( rct_window * w )
2014-04-11 03:42:39 +02:00
{
2018-06-20 17:28:51 +02:00
int32_t x , enabledWidgets , widgetIndex , widgetWidth , firstAlignment ;
2018-06-22 23:21:44 +02:00
rct_widget * widget ;
2017-06-06 23:24:18 +02:00
// Enable / disable buttons
2020-11-27 04:14:20 +01:00
window_top_toolbar_widgets [ WIDX_PAUSE ] . type = WindowWidgetType : : TrnBtn ;
window_top_toolbar_widgets [ WIDX_FILE_MENU ] . type = WindowWidgetType : : TrnBtn ;
window_top_toolbar_widgets [ WIDX_ZOOM_OUT ] . type = WindowWidgetType : : TrnBtn ;
window_top_toolbar_widgets [ WIDX_ZOOM_IN ] . type = WindowWidgetType : : TrnBtn ;
window_top_toolbar_widgets [ WIDX_ROTATE ] . type = WindowWidgetType : : TrnBtn ;
window_top_toolbar_widgets [ WIDX_VIEW_MENU ] . type = WindowWidgetType : : TrnBtn ;
window_top_toolbar_widgets [ WIDX_MAP ] . type = WindowWidgetType : : TrnBtn ;
window_top_toolbar_widgets [ WIDX_MUTE ] . type = WindowWidgetType : : TrnBtn ;
window_top_toolbar_widgets [ WIDX_CHAT ] . type = WindowWidgetType : : TrnBtn ;
window_top_toolbar_widgets [ WIDX_LAND ] . type = WindowWidgetType : : TrnBtn ;
window_top_toolbar_widgets [ WIDX_WATER ] . type = WindowWidgetType : : TrnBtn ;
window_top_toolbar_widgets [ WIDX_SCENERY ] . type = WindowWidgetType : : TrnBtn ;
window_top_toolbar_widgets [ WIDX_PATH ] . type = WindowWidgetType : : TrnBtn ;
window_top_toolbar_widgets [ WIDX_CONSTRUCT_RIDE ] . type = WindowWidgetType : : TrnBtn ;
window_top_toolbar_widgets [ WIDX_RIDES ] . type = WindowWidgetType : : TrnBtn ;
window_top_toolbar_widgets [ WIDX_PARK ] . type = WindowWidgetType : : TrnBtn ;
window_top_toolbar_widgets [ WIDX_STAFF ] . type = WindowWidgetType : : TrnBtn ;
window_top_toolbar_widgets [ WIDX_GUESTS ] . type = WindowWidgetType : : TrnBtn ;
window_top_toolbar_widgets [ WIDX_CLEAR_SCENERY ] . type = WindowWidgetType : : TrnBtn ;
window_top_toolbar_widgets [ WIDX_FINANCES ] . type = WindowWidgetType : : TrnBtn ;
window_top_toolbar_widgets [ WIDX_RESEARCH ] . type = WindowWidgetType : : TrnBtn ;
window_top_toolbar_widgets [ WIDX_FASTFORWARD ] . type = WindowWidgetType : : TrnBtn ;
window_top_toolbar_widgets [ WIDX_CHEATS ] . type = WindowWidgetType : : TrnBtn ;
window_top_toolbar_widgets [ WIDX_DEBUG ] . type = gConfigGeneral . debugging_tools ? WindowWidgetType : : TrnBtn
: WindowWidgetType : : Empty ;
window_top_toolbar_widgets [ WIDX_NEWS ] . type = WindowWidgetType : : TrnBtn ;
window_top_toolbar_widgets [ WIDX_NETWORK ] . type = WindowWidgetType : : TrnBtn ;
2017-06-06 23:24:18 +02:00
2017-08-02 22:28:23 +02:00
if ( ! gConfigInterface . toolbar_show_mute )
{
2020-11-27 04:14:20 +01:00
window_top_toolbar_widgets [ WIDX_MUTE ] . type = WindowWidgetType : : Empty ;
2017-08-02 22:28:23 +02:00
}
2019-02-03 23:30:34 +01:00
if ( ! gConfigInterface . toolbar_show_chat )
{
2020-11-27 04:14:20 +01:00
window_top_toolbar_widgets [ WIDX_CHAT ] . type = WindowWidgetType : : Empty ;
2019-02-03 23:30:34 +01:00
}
2020-11-30 17:27:36 +01:00
if ( gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR | | gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER )
2018-06-22 23:21:44 +02:00
{
2020-11-27 04:14:20 +01:00
window_top_toolbar_widgets [ WIDX_PAUSE ] . type = WindowWidgetType : : Empty ;
2020-11-30 17:27:36 +01:00
}
if ( gScreenFlags & SCREEN_FLAGS_EDITOR )
{
2020-11-27 04:14:20 +01:00
window_top_toolbar_widgets [ WIDX_RIDES ] . type = WindowWidgetType : : Empty ;
window_top_toolbar_widgets [ WIDX_PARK ] . type = WindowWidgetType : : Empty ;
window_top_toolbar_widgets [ WIDX_STAFF ] . type = WindowWidgetType : : Empty ;
window_top_toolbar_widgets [ WIDX_GUESTS ] . type = WindowWidgetType : : Empty ;
window_top_toolbar_widgets [ WIDX_FINANCES ] . type = WindowWidgetType : : Empty ;
window_top_toolbar_widgets [ WIDX_RESEARCH ] . type = WindowWidgetType : : Empty ;
window_top_toolbar_widgets [ WIDX_NEWS ] . type = WindowWidgetType : : Empty ;
window_top_toolbar_widgets [ WIDX_NETWORK ] . type = WindowWidgetType : : Empty ;
2017-06-06 23:24:18 +02:00
2018-06-22 23:21:44 +02:00
if ( gS6Info . editor_step ! = EDITOR_STEP_LANDSCAPE_EDITOR )
{
2020-11-27 04:14:20 +01:00
window_top_toolbar_widgets [ WIDX_MAP ] . type = WindowWidgetType : : Empty ;
window_top_toolbar_widgets [ WIDX_LAND ] . type = WindowWidgetType : : Empty ;
window_top_toolbar_widgets [ WIDX_WATER ] . type = WindowWidgetType : : Empty ;
window_top_toolbar_widgets [ WIDX_SCENERY ] . type = WindowWidgetType : : Empty ;
window_top_toolbar_widgets [ WIDX_PATH ] . type = WindowWidgetType : : Empty ;
window_top_toolbar_widgets [ WIDX_CLEAR_SCENERY ] . type = WindowWidgetType : : Empty ;
2017-06-06 23:24:18 +02:00
}
2018-06-22 23:21:44 +02:00
if ( gS6Info . editor_step ! = EDITOR_STEP_ROLLERCOASTER_DESIGNER )
{
2020-11-27 04:14:20 +01:00
window_top_toolbar_widgets [ WIDX_CONSTRUCT_RIDE ] . type = WindowWidgetType : : Empty ;
window_top_toolbar_widgets [ WIDX_FASTFORWARD ] . type = WindowWidgetType : : Empty ;
2017-06-06 23:24:18 +02:00
}
2018-06-22 23:21:44 +02:00
if ( gS6Info . editor_step ! = EDITOR_STEP_LANDSCAPE_EDITOR & & gS6Info . editor_step ! = EDITOR_STEP_ROLLERCOASTER_DESIGNER )
{
2020-11-27 04:14:20 +01:00
window_top_toolbar_widgets [ WIDX_ZOOM_OUT ] . type = WindowWidgetType : : Empty ;
window_top_toolbar_widgets [ WIDX_ZOOM_IN ] . type = WindowWidgetType : : Empty ;
window_top_toolbar_widgets [ WIDX_ROTATE ] . type = WindowWidgetType : : Empty ;
window_top_toolbar_widgets [ WIDX_VIEW_MENU ] . type = WindowWidgetType : : Empty ;
2017-06-06 23:24:18 +02:00
}
2018-06-22 23:21:44 +02:00
}
else
{
2017-06-06 23:24:18 +02:00
if ( ( gParkFlags & PARK_FLAGS_NO_MONEY ) | | ! gConfigInterface . toolbar_show_finances )
2020-11-27 04:14:20 +01:00
window_top_toolbar_widgets [ WIDX_FINANCES ] . type = WindowWidgetType : : Empty ;
2017-06-06 23:24:18 +02:00
if ( ! gConfigInterface . toolbar_show_research )
2020-11-27 04:14:20 +01:00
window_top_toolbar_widgets [ WIDX_RESEARCH ] . type = WindowWidgetType : : Empty ;
2017-06-06 23:24:18 +02:00
if ( ! gConfigInterface . toolbar_show_cheats )
2020-11-27 04:14:20 +01:00
window_top_toolbar_widgets [ WIDX_CHEATS ] . type = WindowWidgetType : : Empty ;
2017-06-06 23:24:18 +02:00
if ( ! gConfigInterface . toolbar_show_news )
2020-11-27 04:14:20 +01:00
window_top_toolbar_widgets [ WIDX_NEWS ] . type = WindowWidgetType : : Empty ;
2017-06-06 23:24:18 +02:00
2018-06-22 23:21:44 +02:00
switch ( network_get_mode ( ) )
{
case NETWORK_MODE_NONE :
2020-11-27 04:14:20 +01:00
window_top_toolbar_widgets [ WIDX_NETWORK ] . type = WindowWidgetType : : Empty ;
window_top_toolbar_widgets [ WIDX_CHAT ] . type = WindowWidgetType : : Empty ;
2018-06-22 23:21:44 +02:00
break ;
case NETWORK_MODE_CLIENT :
2020-11-27 04:14:20 +01:00
window_top_toolbar_widgets [ WIDX_PAUSE ] . type = WindowWidgetType : : Empty ;
2019-01-04 22:26:56 +01:00
[[fallthrough]] ;
2018-06-22 23:21:44 +02:00
case NETWORK_MODE_SERVER :
2020-11-27 04:14:20 +01:00
window_top_toolbar_widgets [ WIDX_FASTFORWARD ] . type = WindowWidgetType : : Empty ;
2018-06-22 23:21:44 +02:00
break ;
2017-06-06 23:24:18 +02:00
}
}
enabledWidgets = 0 ;
2019-02-03 23:30:34 +01:00
for ( int i = WIDX_PAUSE ; i < = WIDX_CHAT ; i + + )
2020-11-27 04:14:20 +01:00
if ( window_top_toolbar_widgets [ i ] . type ! = WindowWidgetType : : Empty )
2017-06-06 23:24:18 +02:00
enabledWidgets | = ( 1 < < i ) ;
w - > enabled_widgets = enabledWidgets ;
// Align left hand side toolbar buttons
firstAlignment = 1 ;
x = 0 ;
2018-11-21 23:16:04 +01:00
for ( size_t i = 0 ; i < std : : size ( left_aligned_widgets_order ) ; + + i )
2018-06-22 23:21:44 +02:00
{
2017-06-06 23:24:18 +02:00
widgetIndex = left_aligned_widgets_order [ i ] ;
widget = & window_top_toolbar_widgets [ widgetIndex ] ;
2020-11-27 04:14:20 +01:00
if ( widget - > type = = WindowWidgetType : : Empty & & widgetIndex ! = WIDX_SEPARATOR )
2017-06-06 23:24:18 +02:00
continue ;
if ( firstAlignment & & widgetIndex = = WIDX_SEPARATOR )
continue ;
2020-06-25 03:44:00 +02:00
widgetWidth = widget - > width ( ) ;
2017-06-06 23:24:18 +02:00
widget - > left = x ;
x + = widgetWidth ;
widget - > right = x ;
x + = 1 ;
firstAlignment = 0 ;
}
// Align right hand side toolbar buttons
2018-06-20 17:28:51 +02:00
int32_t screenWidth = context_get_width ( ) ;
2017-06-06 23:24:18 +02:00
firstAlignment = 1 ;
2018-06-20 17:11:35 +02:00
x = std : : max ( 640 , screenWidth ) ;
2018-11-21 23:16:04 +01:00
for ( size_t i = 0 ; i < std : : size ( right_aligned_widgets_order ) ; + + i )
2018-06-22 23:21:44 +02:00
{
2017-06-06 23:24:18 +02:00
widgetIndex = right_aligned_widgets_order [ i ] ;
widget = & window_top_toolbar_widgets [ widgetIndex ] ;
2020-11-27 04:14:20 +01:00
if ( widget - > type = = WindowWidgetType : : Empty & & widgetIndex ! = WIDX_SEPARATOR )
2017-06-06 23:24:18 +02:00
continue ;
if ( firstAlignment & & widgetIndex = = WIDX_SEPARATOR )
continue ;
2020-06-25 03:44:00 +02:00
widgetWidth = widget - > width ( ) ;
2017-06-06 23:24:18 +02:00
x - = 1 ;
widget - > right = x ;
x - = widgetWidth ;
widget - > left = x ;
firstAlignment = 0 ;
}
// Footpath button pressed down
2017-08-15 10:07:44 +02:00
if ( window_find_by_class ( WC_FOOTPATH ) = = nullptr )
2017-06-06 23:24:18 +02:00
w - > pressed_widgets & = ~ ( 1 < < WIDX_PATH ) ;
else
w - > pressed_widgets | = ( 1 < < WIDX_PATH ) ;
if ( gGamePaused & GAME_PAUSED_NORMAL )
w - > pressed_widgets | = ( 1 < < WIDX_PAUSE ) ;
else
w - > pressed_widgets & = ~ ( 1 < < WIDX_PAUSE ) ;
2020-10-06 23:34:42 +02:00
if ( ! OpenRCT2 : : Audio : : gGameSoundsOff )
2017-07-20 20:56:29 +02:00
window_top_toolbar_widgets [ WIDX_MUTE ] . image = IMAGE_TYPE_REMAP | SPR_G2_TOOLBAR_MUTE ;
2017-06-06 23:24:18 +02:00
else
2017-07-20 20:56:29 +02:00
window_top_toolbar_widgets [ WIDX_MUTE ] . image = IMAGE_TYPE_REMAP | SPR_G2_TOOLBAR_UNMUTE ;
2017-06-06 23:24:18 +02:00
2019-05-02 00:07:20 +02:00
// Set map button to the right image.
2020-11-27 04:14:20 +01:00
if ( window_top_toolbar_widgets [ WIDX_MAP ] . type ! = WindowWidgetType : : Empty )
2019-05-02 00:07:20 +02:00
{
static constexpr uint32_t imageIdByRotation [ ] = {
SPR_G2_MAP_NORTH ,
SPR_G2_MAP_WEST ,
SPR_G2_MAP_SOUTH ,
SPR_G2_MAP_EAST ,
} ;
uint32_t mapImageId = imageIdByRotation [ get_current_rotation ( ) ] ;
window_top_toolbar_widgets [ WIDX_MAP ] . image = IMAGE_TYPE_REMAP | mapImageId ;
}
2017-06-06 23:24:18 +02:00
// Zoomed out/in disable. Not sure where this code is in the original.
2020-02-20 01:18:05 +01:00
if ( window_get_main ( ) - > viewport - > zoom = = ZoomLevel : : min ( ) )
2017-11-30 22:21:25 +01:00
{
2017-06-06 23:24:18 +02:00
w - > disabled_widgets | = ( 1 < < WIDX_ZOOM_IN ) ;
2017-11-30 22:21:25 +01:00
}
2020-02-20 01:18:05 +01:00
else if ( window_get_main ( ) - > viewport - > zoom > = ZoomLevel : : max ( ) )
2017-11-30 22:21:25 +01:00
{
2017-06-06 23:24:18 +02:00
w - > disabled_widgets | = ( 1 < < WIDX_ZOOM_OUT ) ;
2017-11-30 22:21:25 +01:00
}
else
{
2017-06-06 23:24:18 +02:00
w - > disabled_widgets & = ~ ( ( 1 < < WIDX_ZOOM_IN ) | ( 1 < < WIDX_ZOOM_OUT ) ) ;
}
2014-04-11 03:42:39 +02:00
}
/**
2015-10-20 20:16:30 +02:00
*
2014-04-11 03:42:39 +02:00
* rct2 : 0x0066C8EC
*/
2018-06-22 23:21:44 +02:00
static void window_top_toolbar_paint ( rct_window * w , rct_drawpixelinfo * dpi )
2014-04-11 03:42:39 +02:00
{
2020-06-11 15:11:12 +02:00
int32_t imgId ;
2017-06-06 23:24:18 +02:00
2020-11-04 05:52:23 +01:00
WindowDrawWidgets ( w , dpi ) ;
2017-06-06 23:24:18 +02:00
2020-06-11 15:11:12 +02:00
ScreenCoordsXY screenPos { } ;
2017-06-06 23:24:18 +02:00
// Draw staff button image (setting masks to the staff colours)
2020-11-27 04:14:20 +01:00
if ( window_top_toolbar_widgets [ WIDX_STAFF ] . type ! = WindowWidgetType : : Empty )
2018-06-22 23:21:44 +02:00
{
2020-06-11 15:11:12 +02:00
screenPos = { w - > windowPos . x + window_top_toolbar_widgets [ WIDX_STAFF ] . left ,
w - > windowPos . y + window_top_toolbar_widgets [ WIDX_STAFF ] . top } ;
2017-06-06 23:24:18 +02:00
imgId = SPR_TOOLBAR_STAFF ;
2020-11-03 22:29:22 +01:00
if ( WidgetIsPressed ( w , WIDX_STAFF ) )
2017-06-06 23:24:18 +02:00
imgId + + ;
2017-07-20 20:56:29 +02:00
imgId | = SPRITE_ID_PALETTE_COLOUR_2 ( gStaffHandymanColour , gStaffMechanicColour ) ;
2020-06-24 17:48:17 +02:00
gfx_draw_sprite ( dpi , imgId , screenPos , 0 ) ;
2017-06-06 23:24:18 +02:00
}
// Draw fast forward button
2020-11-27 04:14:20 +01:00
if ( window_top_toolbar_widgets [ WIDX_FASTFORWARD ] . type ! = WindowWidgetType : : Empty )
2018-06-22 23:21:44 +02:00
{
2020-06-11 15:11:12 +02:00
screenPos = { w - > windowPos . x + window_top_toolbar_widgets [ WIDX_FASTFORWARD ] . left + 0 ,
w - > windowPos . y + window_top_toolbar_widgets [ WIDX_FASTFORWARD ] . top + 0 } ;
2020-11-03 22:29:22 +01:00
if ( WidgetIsPressed ( w , WIDX_FASTFORWARD ) )
2020-06-11 15:11:12 +02:00
screenPos . y + + ;
2017-06-06 23:24:18 +02:00
imgId = SPR_G2_FASTFORWARD ;
2020-06-24 17:48:17 +02:00
gfx_draw_sprite ( dpi , imgId , screenPos + ScreenCoordsXY { 6 , 3 } , 0 ) ;
2017-06-06 23:24:18 +02:00
2018-06-22 23:21:44 +02:00
for ( int32_t i = 0 ; i < gGameSpeed & & gGameSpeed < = 4 ; i + + )
{
2020-06-24 17:48:17 +02:00
gfx_draw_sprite ( dpi , SPR_G2_SPEED_ARROW , screenPos + ScreenCoordsXY { 5 + i * 5 , 15 } , 0 ) ;
2017-06-06 23:24:18 +02:00
}
2018-06-22 23:21:44 +02:00
for ( int32_t i = 0 ; i < 3 & & i < gGameSpeed - 4 & & gGameSpeed > = 5 ; i + + )
{
2020-06-24 17:48:17 +02:00
gfx_draw_sprite ( dpi , SPR_G2_HYPER_ARROW , screenPos + ScreenCoordsXY { 5 + i * 6 , 15 } , 0 ) ;
2017-06-06 23:24:18 +02:00
}
}
// Draw cheats button
2020-11-27 04:14:20 +01:00
if ( window_top_toolbar_widgets [ WIDX_CHEATS ] . type ! = WindowWidgetType : : Empty )
2018-06-22 23:21:44 +02:00
{
2020-06-24 17:48:17 +02:00
screenPos = w - > windowPos
+ ScreenCoordsXY { window_top_toolbar_widgets [ WIDX_CHEATS ] . left - 1 ,
window_top_toolbar_widgets [ WIDX_CHEATS ] . top - 1 } ;
2020-11-03 22:29:22 +01:00
if ( WidgetIsPressed ( w , WIDX_CHEATS ) )
2020-06-11 15:11:12 +02:00
screenPos . y + + ;
2017-06-06 23:24:18 +02:00
imgId = SPR_G2_SANDBOX ;
2020-06-24 17:48:17 +02:00
gfx_draw_sprite ( dpi , imgId , screenPos , 3 ) ;
2020-05-25 20:18:39 +02:00
2020-05-30 00:12:07 +02:00
// Draw an overlay if clearance checks are disabled
2020-05-30 11:59:54 +02:00
if ( gCheatsDisableClearanceChecks )
2020-05-25 20:18:39 +02:00
{
2020-09-19 02:39:00 +02:00
DrawTextBasic (
dpi , screenPos + ScreenCoordsXY { 26 , 2 } , STR_OVERLAY_CLEARANCE_CHECKS_DISABLED , { } ,
COLOUR_DARK_ORANGE | COLOUR_FLAG_OUTLINE , TextAlignment : : RIGHT ) ;
2020-05-25 20:18:39 +02:00
}
2017-06-06 23:24:18 +02:00
}
2019-02-03 23:30:34 +01:00
// Draw chat button
2020-11-27 04:14:20 +01:00
if ( window_top_toolbar_widgets [ WIDX_CHAT ] . type ! = WindowWidgetType : : Empty )
2019-02-03 23:30:34 +01:00
{
2020-06-24 17:48:17 +02:00
screenPos = w - > windowPos
+ ScreenCoordsXY { window_top_toolbar_widgets [ WIDX_CHAT ] . left , window_top_toolbar_widgets [ WIDX_CHAT ] . top - 2 } ;
2020-11-03 22:29:22 +01:00
if ( WidgetIsPressed ( w , WIDX_CHAT ) )
2020-06-11 15:11:12 +02:00
screenPos . y + + ;
2019-02-03 23:30:34 +01:00
imgId = SPR_G2_CHAT ;
2020-06-24 17:48:17 +02:00
gfx_draw_sprite ( dpi , imgId , screenPos , 3 ) ;
2019-02-03 23:30:34 +01:00
}
2017-06-06 23:24:18 +02:00
// Draw debug button
2020-11-27 04:14:20 +01:00
if ( window_top_toolbar_widgets [ WIDX_DEBUG ] . type ! = WindowWidgetType : : Empty )
2018-06-22 23:21:44 +02:00
{
2020-06-24 17:48:17 +02:00
screenPos = w - > windowPos
+ ScreenCoordsXY { window_top_toolbar_widgets [ WIDX_DEBUG ] . left , window_top_toolbar_widgets [ WIDX_DEBUG ] . top - 1 } ;
2020-11-03 22:29:22 +01:00
if ( WidgetIsPressed ( w , WIDX_DEBUG ) )
2020-06-11 15:11:12 +02:00
screenPos . y + + ;
2017-06-06 23:24:18 +02:00
imgId = SPR_TAB_GEARS_0 ;
2020-06-24 17:48:17 +02:00
gfx_draw_sprite ( dpi , imgId , screenPos , 3 ) ;
2017-06-06 23:24:18 +02:00
}
// Draw research button
2020-11-27 04:14:20 +01:00
if ( window_top_toolbar_widgets [ WIDX_RESEARCH ] . type ! = WindowWidgetType : : Empty )
2018-06-22 23:21:44 +02:00
{
2020-06-24 17:48:17 +02:00
screenPos = w - > windowPos
+ ScreenCoordsXY { window_top_toolbar_widgets [ WIDX_RESEARCH ] . left - 1 ,
window_top_toolbar_widgets [ WIDX_RESEARCH ] . top } ;
2020-11-03 22:29:22 +01:00
if ( WidgetIsPressed ( w , WIDX_RESEARCH ) )
2020-06-11 15:11:12 +02:00
screenPos . y + + ;
2017-06-06 23:24:18 +02:00
imgId = SPR_TAB_FINANCES_RESEARCH_0 ;
2020-06-24 17:48:17 +02:00
gfx_draw_sprite ( dpi , imgId , screenPos , 0 ) ;
2017-06-06 23:24:18 +02:00
}
// Draw finances button
2020-11-27 04:14:20 +01:00
if ( window_top_toolbar_widgets [ WIDX_FINANCES ] . type ! = WindowWidgetType : : Empty )
2018-06-22 23:21:44 +02:00
{
2020-06-24 17:48:17 +02:00
screenPos = w - > windowPos
+ ScreenCoordsXY { window_top_toolbar_widgets [ WIDX_FINANCES ] . left + 3 ,
window_top_toolbar_widgets [ WIDX_FINANCES ] . top + 1 } ;
2020-11-03 22:29:22 +01:00
if ( WidgetIsPressed ( w , WIDX_FINANCES ) )
2020-06-11 15:11:12 +02:00
screenPos . y + + ;
2017-06-06 23:24:18 +02:00
imgId = SPR_FINANCE ;
2020-06-24 17:48:17 +02:00
gfx_draw_sprite ( dpi , imgId , screenPos , 0 ) ;
2017-06-06 23:24:18 +02:00
}
// Draw news button
2020-11-27 04:14:20 +01:00
if ( window_top_toolbar_widgets [ WIDX_NEWS ] . type ! = WindowWidgetType : : Empty )
2018-06-22 23:21:44 +02:00
{
2020-06-24 17:48:17 +02:00
screenPos = w - > windowPos
+ ScreenCoordsXY { window_top_toolbar_widgets [ WIDX_NEWS ] . left + 3 , window_top_toolbar_widgets [ WIDX_NEWS ] . top + 0 } ;
2020-11-03 22:29:22 +01:00
if ( WidgetIsPressed ( w , WIDX_NEWS ) )
2020-06-11 15:11:12 +02:00
screenPos . y + + ;
2017-06-06 23:24:18 +02:00
imgId = SPR_G2_TAB_NEWS ;
2020-06-24 17:48:17 +02:00
gfx_draw_sprite ( dpi , imgId , screenPos , 0 ) ;
2017-06-06 23:24:18 +02:00
}
// Draw network button
2020-11-27 04:14:20 +01:00
if ( window_top_toolbar_widgets [ WIDX_NETWORK ] . type ! = WindowWidgetType : : Empty )
2018-06-22 23:21:44 +02:00
{
2020-06-24 17:48:17 +02:00
screenPos = w - > windowPos
+ ScreenCoordsXY { window_top_toolbar_widgets [ WIDX_NETWORK ] . left + 3 ,
window_top_toolbar_widgets [ WIDX_NETWORK ] . top + 0 } ;
2020-11-03 22:29:22 +01:00
if ( WidgetIsPressed ( w , WIDX_NETWORK ) )
2020-06-11 15:11:12 +02:00
screenPos . y + + ;
2019-05-02 12:32:45 +02:00
// Draw (de)sync icon.
2019-02-05 10:43:27 +01:00
imgId = ( network_is_desynchronised ( ) ? SPR_G2_MULTIPLAYER_DESYNC : SPR_G2_MULTIPLAYER_SYNC ) ;
2020-06-24 17:48:17 +02:00
gfx_draw_sprite ( dpi , imgId , screenPos + ScreenCoordsXY { 3 , 11 } , 0 ) ;
2019-02-05 10:43:27 +01:00
2019-05-02 12:32:45 +02:00
// Draw number of players.
2020-09-19 02:39:00 +02:00
auto ft = Formatter ( ) ;
ft . Add < int32_t > ( network_get_num_players ( ) ) ;
2019-05-02 12:32:45 +02:00
gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM ;
2020-09-19 02:39:00 +02:00
DrawTextBasic (
dpi , screenPos + ScreenCoordsXY { 23 , 1 } , STR_COMMA16 , ft , COLOUR_WHITE | COLOUR_FLAG_OUTLINE ,
TextAlignment : : RIGHT ) ;
2017-06-06 23:24:18 +02:00
}
2014-04-21 11:27:48 +02:00
}
2014-10-21 18:59:47 +02:00
2015-12-11 16:38:37 +01:00
/**
*
* rct2 : 0x006E3158
*/
2020-05-01 17:52:07 +02:00
static void repaint_scenery_tool_down ( const ScreenCoordsXY & windowPos , rct_widgetindex widgetIndex )
2018-06-22 23:21:44 +02:00
{
auto flags = VIEWPORT_INTERACTION_MASK_SCENERY & VIEWPORT_INTERACTION_MASK_WALL & VIEWPORT_INTERACTION_MASK_LARGE_SCENERY
& VIEWPORT_INTERACTION_MASK_BANNER ;
2017-06-06 23:24:18 +02:00
// This is -2 as banner is 12 but flags are offset different
2020-08-02 09:32:59 +02:00
auto info = get_map_coordinates_from_pos ( windowPos , flags ) ;
2017-06-06 23:24:18 +02:00
2020-08-02 09:32:59 +02:00
switch ( info . SpriteType )
2017-06-06 23:24:18 +02:00
{
2018-06-22 23:21:44 +02:00
case VIEWPORT_INTERACTION_ITEM_SCENERY :
{
2020-08-02 09:32:59 +02:00
rct_scenery_entry * scenery_entry = info . Element - > AsSmallScenery ( ) - > GetEntry ( ) ;
2017-06-06 23:24:18 +02:00
2018-06-22 23:21:44 +02:00
// If can't repaint
if ( ! scenery_small_entry_has_flag (
scenery_entry , SMALL_SCENERY_FLAG_HAS_PRIMARY_COLOUR | SMALL_SCENERY_FLAG_HAS_GLASS ) )
return ;
2017-06-06 23:24:18 +02:00
2020-08-02 09:32:59 +02:00
uint8_t quadrant = info . Element - > AsSmallScenery ( ) - > GetSceneryQuadrant ( ) ;
2019-04-06 16:59:40 +02:00
auto repaintScenery = SmallScenerySetColourAction (
2020-08-02 09:32:59 +02:00
{ info . Loc , info . Element - > GetBaseZ ( ) } , quadrant , info . Element - > AsSmallScenery ( ) - > GetEntryIndex ( ) ,
gWindowSceneryPrimaryColour , gWindowScenerySecondaryColour ) ;
2019-04-06 16:59:40 +02:00
GameActions : : Execute ( & repaintScenery ) ;
2018-06-22 23:21:44 +02:00
break ;
}
case VIEWPORT_INTERACTION_ITEM_WALL :
{
2020-08-02 09:32:59 +02:00
rct_scenery_entry * scenery_entry = info . Element - > AsWall ( ) - > GetEntry ( ) ;
2017-06-06 23:24:18 +02:00
2018-06-22 23:21:44 +02:00
// If can't repaint
if ( ! ( scenery_entry - > wall . flags & ( WALL_SCENERY_HAS_PRIMARY_COLOUR | WALL_SCENERY_HAS_GLASS ) ) )
return ;
2017-06-06 23:24:18 +02:00
2019-04-06 20:36:44 +02:00
auto repaintScenery = WallSetColourAction (
2020-08-02 09:32:59 +02:00
{ info . Loc , info . Element - > GetBaseZ ( ) , info . Element - > GetDirection ( ) } , gWindowSceneryPrimaryColour ,
gWindowScenerySecondaryColour , gWindowSceneryTertiaryColour ) ;
2019-04-06 20:36:44 +02:00
GameActions : : Execute ( & repaintScenery ) ;
2018-06-22 23:21:44 +02:00
break ;
}
case VIEWPORT_INTERACTION_ITEM_LARGE_SCENERY :
2017-11-22 23:06:56 +01:00
{
2020-08-02 09:32:59 +02:00
rct_scenery_entry * scenery_entry = info . Element - > AsLargeScenery ( ) - > GetEntry ( ) ;
2018-06-22 23:21:44 +02:00
// If can't repaint
if ( ! ( scenery_entry - > large_scenery . flags & LARGE_SCENERY_FLAG_HAS_PRIMARY_COLOUR ) )
return ;
2019-04-07 09:51:14 +02:00
auto repaintScenery = LargeScenerySetColourAction (
2020-08-02 09:32:59 +02:00
{ info . Loc , info . Element - > GetBaseZ ( ) , info . Element - > GetDirection ( ) } ,
info . Element - > AsLargeScenery ( ) - > GetSequenceIndex ( ) , gWindowSceneryPrimaryColour , gWindowScenerySecondaryColour ) ;
2019-04-07 09:51:14 +02:00
GameActions : : Execute ( & repaintScenery ) ;
2018-06-22 23:21:44 +02:00
break ;
2017-11-22 23:06:56 +01:00
}
2018-06-22 23:21:44 +02:00
case VIEWPORT_INTERACTION_ITEM_BANNER :
{
2020-08-02 09:32:59 +02:00
auto banner = info . Element - > AsBanner ( ) - > GetBanner ( ) ;
2019-07-25 18:51:22 +02:00
if ( banner ! = nullptr )
2018-06-22 23:21:44 +02:00
{
2019-07-25 18:51:22 +02:00
auto scenery_entry = get_banner_entry ( banner - > type ) ;
if ( scenery_entry - > banner . flags & BANNER_ENTRY_FLAG_HAS_PRIMARY_COLOUR )
{
auto repaintScenery = BannerSetColourAction (
2020-08-02 09:32:59 +02:00
{ info . Loc , info . Element - > GetBaseZ ( ) , info . Element - > AsBanner ( ) - > GetPosition ( ) } ,
2019-07-25 18:51:22 +02:00
gWindowSceneryPrimaryColour ) ;
2019-04-07 10:15:41 +02:00
2019-07-25 18:51:22 +02:00
GameActions : : Execute ( & repaintScenery ) ;
}
2018-06-22 23:21:44 +02:00
}
break ;
}
default :
return ;
2017-06-06 23:24:18 +02:00
}
2015-04-15 21:52:19 +02:00
}
2020-05-01 17:52:07 +02:00
static void scenery_eyedropper_tool_down ( const ScreenCoordsXY & windowPos , rct_widgetindex widgetIndex )
2017-03-13 19:05:13 +01:00
{
2018-06-22 23:21:44 +02:00
auto flags = VIEWPORT_INTERACTION_MASK_SCENERY & VIEWPORT_INTERACTION_MASK_WALL & VIEWPORT_INTERACTION_MASK_LARGE_SCENERY
& VIEWPORT_INTERACTION_MASK_BANNER & VIEWPORT_INTERACTION_MASK_FOOTPATH_ITEM ;
2017-06-06 23:24:18 +02:00
2020-08-02 09:32:59 +02:00
auto info = get_map_coordinates_from_pos ( windowPos , flags ) ;
2017-06-06 23:24:18 +02:00
2020-08-02 09:32:59 +02:00
switch ( info . SpriteType )
2017-06-06 23:24:18 +02:00
{
2018-06-22 23:21:44 +02:00
case VIEWPORT_INTERACTION_ITEM_SCENERY :
2017-11-17 17:15:55 +01:00
{
2020-08-02 09:32:59 +02:00
SmallSceneryElement * sceneryElement = info . Element - > AsSmallScenery ( ) ;
2020-03-18 16:22:08 +01:00
auto entryIndex = sceneryElement - > GetEntryIndex ( ) ;
2018-06-22 23:21:44 +02:00
rct_scenery_entry * sceneryEntry = get_small_scenery_entry ( entryIndex ) ;
if ( sceneryEntry ! = nullptr )
2017-11-17 17:15:55 +01:00
{
2020-03-13 14:44:34 +01:00
if ( window_scenery_set_selected_item ( { SCENERY_TYPE_SMALL , entryIndex } ) )
2018-06-22 23:21:44 +02:00
{
2018-09-13 18:12:20 +02:00
gWindowSceneryRotation = sceneryElement - > GetDirectionWithOffset ( get_current_rotation ( ) ) ;
gWindowSceneryPrimaryColour = sceneryElement - > GetPrimaryColour ( ) ;
gWindowScenerySecondaryColour = sceneryElement - > GetSecondaryColour ( ) ;
2018-06-22 23:21:44 +02:00
gWindowSceneryEyedropperEnabled = false ;
}
2017-06-06 23:24:18 +02:00
}
2018-06-22 23:21:44 +02:00
break ;
2017-06-06 23:24:18 +02:00
}
2018-06-22 23:21:44 +02:00
case VIEWPORT_INTERACTION_ITEM_WALL :
2017-11-17 17:15:55 +01:00
{
2020-08-02 09:32:59 +02:00
auto entryIndex = info . Element - > AsWall ( ) - > GetEntryIndex ( ) ;
2018-06-22 23:21:44 +02:00
rct_scenery_entry * sceneryEntry = get_wall_entry ( entryIndex ) ;
if ( sceneryEntry ! = nullptr )
2017-11-17 17:15:55 +01:00
{
2020-03-13 14:44:34 +01:00
if ( window_scenery_set_selected_item ( { SCENERY_TYPE_WALL , entryIndex } ) )
2018-06-22 23:21:44 +02:00
{
2020-08-02 09:32:59 +02:00
gWindowSceneryPrimaryColour = info . Element - > AsWall ( ) - > GetPrimaryColour ( ) ;
gWindowScenerySecondaryColour = info . Element - > AsWall ( ) - > GetSecondaryColour ( ) ;
gWindowSceneryTertiaryColour = info . Element - > AsWall ( ) - > GetTertiaryColour ( ) ;
2018-06-22 23:21:44 +02:00
gWindowSceneryEyedropperEnabled = false ;
}
2017-06-06 23:24:18 +02:00
}
2018-06-22 23:21:44 +02:00
break ;
2017-06-06 23:24:18 +02:00
}
2018-06-22 23:21:44 +02:00
case VIEWPORT_INTERACTION_ITEM_LARGE_SCENERY :
2017-11-17 17:15:55 +01:00
{
2020-08-02 09:32:59 +02:00
auto entryIndex = info . Element - > AsLargeScenery ( ) - > GetEntryIndex ( ) ;
2018-06-22 23:21:44 +02:00
rct_scenery_entry * sceneryEntry = get_large_scenery_entry ( entryIndex ) ;
if ( sceneryEntry ! = nullptr )
2017-11-17 17:15:55 +01:00
{
2020-03-13 14:44:34 +01:00
if ( window_scenery_set_selected_item ( { SCENERY_TYPE_LARGE , entryIndex } ) )
2018-06-22 23:21:44 +02:00
{
2020-08-02 09:32:59 +02:00
gWindowSceneryRotation = ( get_current_rotation ( ) + info . Element - > GetDirection ( ) ) & 3 ;
gWindowSceneryPrimaryColour = info . Element - > AsLargeScenery ( ) - > GetPrimaryColour ( ) ;
gWindowScenerySecondaryColour = info . Element - > AsLargeScenery ( ) - > GetSecondaryColour ( ) ;
2018-06-22 23:21:44 +02:00
gWindowSceneryEyedropperEnabled = false ;
}
2017-06-06 23:24:18 +02:00
}
2018-06-22 23:21:44 +02:00
break ;
2017-06-06 23:24:18 +02:00
}
2018-06-22 23:21:44 +02:00
case VIEWPORT_INTERACTION_ITEM_BANNER :
{
2020-08-02 09:32:59 +02:00
auto banner = info . Element - > AsBanner ( ) - > GetBanner ( ) ;
2019-07-25 18:51:22 +02:00
if ( banner ! = nullptr )
2018-06-22 23:21:44 +02:00
{
2019-07-25 18:51:22 +02:00
auto sceneryEntry = get_banner_entry ( banner - > type ) ;
if ( sceneryEntry ! = nullptr )
2018-06-22 23:21:44 +02:00
{
2020-03-13 14:44:34 +01:00
if ( window_scenery_set_selected_item ( { SCENERY_TYPE_BANNER , banner - > type } ) )
2019-07-25 18:51:22 +02:00
{
gWindowSceneryEyedropperEnabled = false ;
}
2018-06-22 23:21:44 +02:00
}
2017-06-06 23:24:18 +02:00
}
2018-06-22 23:21:44 +02:00
break ;
2017-06-06 23:24:18 +02:00
}
2018-06-22 23:21:44 +02:00
case VIEWPORT_INTERACTION_ITEM_FOOTPATH_ITEM :
{
2020-08-02 09:32:59 +02:00
auto entryIndex = info . Element - > AsPath ( ) - > GetAdditionEntryIndex ( ) ;
2018-06-22 23:21:44 +02:00
rct_scenery_entry * sceneryEntry = get_footpath_item_entry ( entryIndex ) ;
if ( sceneryEntry ! = nullptr )
{
2020-03-13 14:44:34 +01:00
if ( window_scenery_set_selected_item ( { SCENERY_TYPE_PATH_ITEM , entryIndex } ) )
2018-06-22 23:21:44 +02:00
{
gWindowSceneryEyedropperEnabled = false ;
}
2017-06-06 23:24:18 +02:00
}
2018-06-22 23:21:44 +02:00
break ;
2017-06-06 23:24:18 +02:00
}
2020-08-02 09:32:59 +02:00
default :
break ;
2017-06-06 23:24:18 +02:00
}
2017-03-13 19:05:13 +01:00
}
2020-11-15 14:58:36 +01:00
static void sub_6E1F34_update_screen_coords_and_buttons_pressed ( bool canRaiseItem , ScreenCoordsXY & screenPos )
2018-06-22 23:21:44 +02:00
{
2020-11-15 14:58:36 +01:00
if ( ! canRaiseItem & & ! gCheatsDisableSupportLimits )
2018-06-22 23:21:44 +02:00
{
2017-06-06 23:24:18 +02:00
gSceneryCtrlPressed = false ;
gSceneryShiftPressed = false ;
2017-07-15 11:55:20 +02:00
}
2018-06-22 23:21:44 +02:00
else
{
if ( ! gSceneryCtrlPressed )
{
2020-11-02 14:43:35 +01:00
if ( InputTestPlaceObjectModifier ( PLACE_OBJECT_MODIFIER_COPY_Z ) )
2018-06-22 23:21:44 +02:00
{
2017-06-06 23:24:18 +02:00
// CTRL pressed
2018-06-22 23:21:44 +02:00
auto flags = VIEWPORT_INTERACTION_MASK_TERRAIN & VIEWPORT_INTERACTION_MASK_RIDE
& VIEWPORT_INTERACTION_MASK_SCENERY & VIEWPORT_INTERACTION_MASK_FOOTPATH & VIEWPORT_INTERACTION_MASK_WALL
& VIEWPORT_INTERACTION_MASK_LARGE_SCENERY ;
2020-08-02 09:32:59 +02:00
auto info = get_map_coordinates_from_pos ( screenPos , flags ) ;
2017-06-06 23:24:18 +02:00
2020-08-02 09:32:59 +02:00
if ( info . SpriteType ! = VIEWPORT_INTERACTION_ITEM_NONE )
2018-06-22 23:21:44 +02:00
{
2017-06-06 23:24:18 +02:00
gSceneryCtrlPressed = true ;
2020-08-02 09:32:59 +02:00
gSceneryCtrlPressZ = info . Element - > GetBaseZ ( ) ;
2017-06-06 23:24:18 +02:00
}
}
2017-07-15 11:55:20 +02:00
}
2018-06-22 23:21:44 +02:00
else
{
2020-11-02 14:43:35 +01:00
if ( ! ( InputTestPlaceObjectModifier ( PLACE_OBJECT_MODIFIER_COPY_Z ) ) )
2018-06-22 23:21:44 +02:00
{
2017-06-06 23:24:18 +02:00
// CTRL not pressed
gSceneryCtrlPressed = false ;
}
}
2018-06-22 23:21:44 +02:00
if ( ! gSceneryShiftPressed )
{
2020-11-02 14:43:35 +01:00
if ( InputTestPlaceObjectModifier ( PLACE_OBJECT_MODIFIER_SHIFT_Z ) )
2018-06-22 23:21:44 +02:00
{
2017-06-06 23:24:18 +02:00
// SHIFT pressed
gSceneryShiftPressed = true ;
2020-05-01 17:52:07 +02:00
gSceneryShiftPressX = screenPos . x ;
gSceneryShiftPressY = screenPos . y ;
2017-06-06 23:24:18 +02:00
gSceneryShiftPressZOffset = 0 ;
}
}
2018-06-22 23:21:44 +02:00
else
{
2020-11-02 14:43:35 +01:00
if ( InputTestPlaceObjectModifier ( PLACE_OBJECT_MODIFIER_SHIFT_Z ) )
2018-06-22 23:21:44 +02:00
{
2017-06-06 23:24:18 +02:00
// SHIFT pressed
2020-05-01 17:52:07 +02:00
gSceneryShiftPressZOffset = ( gSceneryShiftPressY - screenPos . y + 4 ) ;
2018-08-12 11:47:46 +02:00
// Scale delta by zoom to match mouse position.
auto * mainWnd = window_get_main ( ) ;
if ( mainWnd & & mainWnd - > viewport )
{
2020-02-20 01:18:05 +01:00
gSceneryShiftPressZOffset = gSceneryShiftPressZOffset * mainWnd - > viewport - > zoom ;
2018-08-12 11:47:46 +02:00
}
gSceneryShiftPressZOffset = floor2 ( gSceneryShiftPressZOffset , 8 ) ;
2017-06-06 23:24:18 +02:00
2020-05-01 17:52:07 +02:00
screenPos . x = gSceneryShiftPressX ;
screenPos . y = gSceneryShiftPressY ;
2017-07-15 11:55:20 +02:00
}
2018-06-22 23:21:44 +02:00
else
{
2017-06-06 23:24:18 +02:00
// SHIFT not pressed
gSceneryShiftPressed = false ;
}
}
}
2020-11-15 14:58:36 +01:00
}
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
static void sub_6E1F34_small_scenery (
const ScreenCoordsXY & sourceScreenPos , ObjectEntryIndex sceneryIndex , CoordsXY & gridPos , uint8_t * outQuadrant ,
2020-12-02 12:23:38 +01:00
Direction * outRotation )
2020-11-15 14:58:36 +01:00
{
rct_window * w = window_find_by_class ( WC_SCENERY ) ;
2018-06-22 23:21:44 +02:00
2020-11-15 14:58:36 +01:00
if ( w = = nullptr )
{
gridPos . setNull ( ) ;
return ;
}
2018-06-22 23:21:44 +02:00
2020-11-15 14:58:36 +01:00
auto screenPos = sourceScreenPos ;
uint16_t maxPossibleHeight = ( std : : numeric_limits < decltype ( TileElement : : base_height ) > : : max ( ) - 32 ) * ZoomLevel : : max ( ) ;
bool can_raise_item = false ;
2018-06-22 23:21:44 +02:00
2020-11-15 14:58:36 +01:00
rct_scenery_entry * scenery = get_small_scenery_entry ( sceneryIndex ) ;
maxPossibleHeight - = scenery - > small_scenery . height ;
if ( scenery_small_entry_has_flag ( scenery , SMALL_SCENERY_FLAG_STACKABLE ) )
{
can_raise_item = true ;
}
2019-12-24 21:09:22 +01:00
2020-11-15 14:58:36 +01:00
sub_6E1F34_update_screen_coords_and_buttons_pressed ( can_raise_item , screenPos ) ;
2018-06-22 23:21:44 +02:00
2020-11-15 14:58:36 +01:00
// Small scenery
if ( ! scenery_small_entry_has_flag ( scenery , SMALL_SCENERY_FLAG_FULL_TILE ) )
{
uint8_t quadrant = 0 ;
2018-06-22 23:21:44 +02:00
2020-11-15 14:58:36 +01:00
// If CTRL not pressed
if ( ! gSceneryCtrlPressed )
{
auto gridCoords = screen_get_map_xy_quadrant ( screenPos , & quadrant ) ;
if ( ! gridCoords )
{
gridPos . setNull ( ) ;
return ;
}
gridPos = * gridCoords ;
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
gSceneryPlaceZ = 0 ;
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
// If SHIFT pressed
if ( gSceneryShiftPressed )
{
auto * surfaceElement = map_get_surface_element_at ( gridPos ) ;
2018-06-22 23:21:44 +02:00
2020-11-15 14:58:36 +01:00
if ( surfaceElement = = nullptr )
2018-06-22 23:21:44 +02:00
{
2020-11-15 14:58:36 +01:00
gridPos . setNull ( ) ;
return ;
2018-06-22 23:21:44 +02:00
}
2020-11-15 14:58:36 +01:00
int16_t z = ( surfaceElement - > GetBaseZ ( ) ) & 0xFFF0 ;
z + = gSceneryShiftPressZOffset ;
2018-06-22 23:21:44 +02:00
2020-11-15 14:58:36 +01:00
z = std : : clamp < int16_t > ( z , 16 , maxPossibleHeight ) ;
2018-06-22 23:21:44 +02:00
2020-11-15 14:58:36 +01:00
gSceneryPlaceZ = z ;
}
}
else
{
int16_t z = gSceneryCtrlPressZ ;
2018-06-22 23:21:44 +02:00
2020-11-15 14:58:36 +01:00
auto mapCoords = screen_get_map_xy_quadrant_with_z ( screenPos , z , & quadrant ) ;
if ( ! mapCoords )
{
gridPos . setNull ( ) ;
2018-06-22 23:21:44 +02:00
return ;
}
2020-11-15 14:58:36 +01:00
gridPos = * mapCoords ;
2018-06-22 23:21:44 +02:00
2020-11-15 14:58:36 +01:00
// If SHIFT pressed
if ( gSceneryShiftPressed )
2018-06-22 23:21:44 +02:00
{
2020-11-15 14:58:36 +01:00
z + = gSceneryShiftPressZOffset ;
}
2018-06-22 23:21:44 +02:00
2020-11-15 14:58:36 +01:00
z = std : : clamp < int16_t > ( z , 16 , maxPossibleHeight ) ;
2018-06-22 23:21:44 +02:00
2020-11-15 14:58:36 +01:00
gSceneryPlaceZ = z ;
}
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
if ( gridPos . isNull ( ) )
return ;
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
uint8_t rotation = gWindowSceneryRotation ;
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
if ( ! scenery_small_entry_has_flag ( scenery , SMALL_SCENERY_FLAG_ROTATABLE ) )
{
rotation = util_rand ( ) & 0xFF ;
}
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
rotation - = get_current_rotation ( ) ;
rotation & = 0x3 ;
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
if ( gConfigGeneral . virtual_floor_style ! = VirtualFloorStyles : : Off )
{
virtual_floor_set_height ( gSceneryPlaceZ ) ;
}
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
* outQuadrant = quadrant ^ 2 ;
* outRotation = rotation ;
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
return ;
}
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
// If CTRL not pressed
if ( ! gSceneryCtrlPressed )
{
auto flags = VIEWPORT_INTERACTION_MASK_TERRAIN & VIEWPORT_INTERACTION_MASK_WATER ;
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
auto info = get_map_coordinates_from_pos ( screenPos , flags ) ;
gridPos = info . Loc ;
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
if ( info . SpriteType = = VIEWPORT_INTERACTION_ITEM_NONE )
{
gridPos . setNull ( ) ;
return ;
}
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
// If CTRL and SHIFT not pressed
gSceneryPlaceZ = 0 ;
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
// If SHIFT pressed
if ( gSceneryShiftPressed )
2018-06-22 23:21:44 +02:00
{
2020-11-15 14:58:36 +01:00
auto surfaceElement = map_get_surface_element_at ( gridPos ) ;
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
if ( surfaceElement = = nullptr )
2018-06-22 23:21:44 +02:00
{
2019-12-27 13:33:08 +01:00
gridPos . setNull ( ) ;
2017-06-06 23:24:18 +02:00
return ;
}
2020-11-15 14:58:36 +01:00
int16_t z = ( surfaceElement - > GetBaseZ ( ) ) & 0xFFF0 ;
z + = gSceneryShiftPressZOffset ;
z = std : : clamp < int16_t > ( z , 16 , maxPossibleHeight ) ;
gSceneryPlaceZ = z ;
}
}
else
{
int16_t z = gSceneryCtrlPressZ ;
auto coords = screen_get_map_xy_with_z ( screenPos , z ) ;
if ( coords )
{
gridPos = * coords ;
2017-06-06 23:24:18 +02:00
}
2020-11-15 14:58:36 +01:00
else
2017-12-04 20:09:38 +01:00
{
2020-11-15 14:58:36 +01:00
gridPos . setNull ( ) ;
}
// If SHIFT pressed
if ( gSceneryShiftPressed )
{
z + = gSceneryShiftPressZOffset ;
}
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
z = std : : clamp < int16_t > ( z , 16 , maxPossibleHeight ) ;
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
gSceneryPlaceZ = z ;
}
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
if ( gridPos . isNull ( ) )
return ;
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
gridPos = gridPos . ToTileStart ( ) ;
uint8_t rotation = gWindowSceneryRotation ;
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
if ( ! scenery_small_entry_has_flag ( scenery , SMALL_SCENERY_FLAG_ROTATABLE ) )
{
rotation = util_rand ( ) & 0xFF ;
}
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
rotation - = get_current_rotation ( ) ;
rotation & = 0x3 ;
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
if ( gConfigGeneral . virtual_floor_style ! = VirtualFloorStyles : : Off )
{
virtual_floor_set_height ( gSceneryPlaceZ ) ;
}
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
* outQuadrant = 0 ;
* outRotation = rotation ;
}
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
static void sub_6E1F34_path_item (
const ScreenCoordsXY & sourceScreenPos , ObjectEntryIndex sceneryIndex , CoordsXY & gridPos , int32_t * outZ )
{
rct_window * w = window_find_by_class ( WC_SCENERY ) ;
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
if ( w = = nullptr )
{
gridPos . setNull ( ) ;
return ;
}
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
auto screenPos = sourceScreenPos ;
sub_6E1F34_update_screen_coords_and_buttons_pressed ( false , screenPos ) ;
// Path bits
auto flags = VIEWPORT_INTERACTION_MASK_FOOTPATH & VIEWPORT_INTERACTION_MASK_FOOTPATH_ITEM ;
auto info = get_map_coordinates_from_pos ( screenPos , flags ) ;
gridPos = info . Loc ;
if ( info . SpriteType = = VIEWPORT_INTERACTION_ITEM_NONE )
{
gridPos . setNull ( ) ;
return ;
}
if ( gConfigGeneral . virtual_floor_style ! = VirtualFloorStyles : : Off )
{
virtual_floor_set_height ( gSceneryPlaceZ ) ;
}
* outZ = info . Element - > GetBaseZ ( ) ;
}
static void sub_6E1F34_wall (
2020-12-02 12:23:38 +01:00
const ScreenCoordsXY & sourceScreenPos , ObjectEntryIndex sceneryIndex , CoordsXY & gridPos , uint8_t * outEdges )
2020-11-15 14:58:36 +01:00
{
rct_window * w = window_find_by_class ( WC_SCENERY ) ;
if ( w = = nullptr )
{
gridPos . setNull ( ) ;
return ;
}
auto screenPos = sourceScreenPos ;
uint16_t maxPossibleHeight = ( std : : numeric_limits < decltype ( TileElement : : base_height ) > : : max ( ) - 32 ) * ZoomLevel : : max ( ) ;
rct_scenery_entry * scenery_entry = get_wall_entry ( sceneryIndex ) ;
if ( scenery_entry )
{
maxPossibleHeight - = scenery_entry - > wall . height ;
}
sub_6E1F34_update_screen_coords_and_buttons_pressed ( true , screenPos ) ;
// Walls
uint8_t edge ;
// If CTRL not pressed
if ( ! gSceneryCtrlPressed )
{
auto gridCoords = screen_get_map_xy_side ( screenPos , & edge ) ;
if ( ! gridCoords )
{
gridPos . setNull ( ) ;
return ;
2017-06-06 23:24:18 +02:00
}
2020-11-15 14:58:36 +01:00
gridPos = * gridCoords ;
gSceneryPlaceZ = 0 ;
// If SHIFT pressed
if ( gSceneryShiftPressed )
2018-06-22 23:21:44 +02:00
{
2020-11-15 14:58:36 +01:00
auto * surfaceElement = map_get_surface_element_at ( gridPos ) ;
if ( surfaceElement = = nullptr )
2018-06-22 23:21:44 +02:00
{
2020-11-15 14:58:36 +01:00
gridPos . setNull ( ) ;
return ;
}
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
int16_t z = ( surfaceElement - > GetBaseZ ( ) ) & 0xFFF0 ;
z + = gSceneryShiftPressZOffset ;
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
z = std : : clamp < int16_t > ( z , 16 , maxPossibleHeight ) ;
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
gSceneryPlaceZ = z ;
}
}
else
{
int16_t z = gSceneryCtrlPressZ ;
auto mapCoords = screen_get_map_xy_side_with_z ( screenPos , z , & edge ) ;
if ( ! mapCoords )
{
gridPos . setNull ( ) ;
return ;
}
gridPos = * mapCoords ;
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
// If SHIFT pressed
if ( gSceneryShiftPressed )
{
z + = gSceneryShiftPressZOffset ;
}
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
z = std : : clamp < int16_t > ( z , 16 , maxPossibleHeight ) ;
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
gSceneryPlaceZ = z ;
}
2018-06-22 23:21:44 +02:00
2020-11-15 14:58:36 +01:00
if ( gridPos . isNull ( ) )
return ;
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
if ( gConfigGeneral . virtual_floor_style ! = VirtualFloorStyles : : Off )
{
virtual_floor_set_height ( gSceneryPlaceZ ) ;
}
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
* outEdges = edge ;
}
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
static void sub_6E1F34_large_scenery (
2020-12-02 12:23:38 +01:00
const ScreenCoordsXY & sourceScreenPos , ObjectEntryIndex sceneryIndex , CoordsXY & gridPos , Direction * outDirection )
2020-11-15 14:58:36 +01:00
{
rct_window * w = window_find_by_class ( WC_SCENERY ) ;
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
if ( w = = nullptr )
{
gridPos . setNull ( ) ;
return ;
}
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
auto screenPos = sourceScreenPos ;
uint16_t maxPossibleHeight = ( std : : numeric_limits < decltype ( TileElement : : base_height ) > : : max ( ) - 32 ) * ZoomLevel : : max ( ) ;
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
rct_scenery_entry * scenery_entry = get_large_scenery_entry ( sceneryIndex ) ;
if ( scenery_entry )
{
int16_t maxClearZ = 0 ;
for ( int32_t i = 0 ; scenery_entry - > large_scenery . tiles [ i ] . x_offset ! = - 1 ; + + i )
2018-06-22 23:21:44 +02:00
{
2020-11-15 14:58:36 +01:00
maxClearZ = std : : max < int16_t > ( maxClearZ , scenery_entry - > large_scenery . tiles [ i ] . z_clearance ) ;
}
maxPossibleHeight = std : : max ( 0 , maxPossibleHeight - maxClearZ ) ;
}
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
sub_6E1F34_update_screen_coords_and_buttons_pressed ( true , screenPos ) ;
// Large scenery
// If CTRL not pressed
if ( ! gSceneryCtrlPressed )
{
const CoordsXY mapCoords = ViewportInteractionGetTileStartAtCursor ( screenPos ) ;
gridPos = mapCoords ;
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
if ( gridPos . isNull ( ) )
return ;
gSceneryPlaceZ = 0 ;
// If SHIFT pressed
if ( gSceneryShiftPressed )
{
auto * surfaceElement = map_get_surface_element_at ( gridPos ) ;
if ( surfaceElement = = nullptr )
2018-06-22 23:21:44 +02:00
{
2019-12-27 13:33:08 +01:00
gridPos . setNull ( ) ;
2018-06-22 23:21:44 +02:00
return ;
}
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
int16_t z = ( surfaceElement - > GetBaseZ ( ) ) & 0xFFF0 ;
z + = gSceneryShiftPressZOffset ;
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
z = std : : clamp < int16_t > ( z , 16 , maxPossibleHeight ) ;
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
gSceneryPlaceZ = z ;
}
}
else
{
int16_t z = gSceneryCtrlPressZ ;
auto coords = screen_get_map_xy_with_z ( screenPos , z ) ;
if ( coords )
{
gridPos = * coords ;
}
else
{
gridPos . setNull ( ) ;
}
2017-06-06 23:24:18 +02:00
2020-11-15 14:58:36 +01:00
// If SHIFT pressed
if ( gSceneryShiftPressed )
{
z + = gSceneryShiftPressZOffset ;
2018-06-22 23:21:44 +02:00
}
2020-11-15 14:58:36 +01:00
z = std : : clamp < int16_t > ( z , 16 , maxPossibleHeight ) ;
gSceneryPlaceZ = z ;
2017-06-06 23:24:18 +02:00
}
2017-09-29 04:45:20 +02:00
2020-11-15 14:58:36 +01:00
if ( gridPos . isNull ( ) )
return ;
gridPos = gridPos . ToTileStart ( ) ;
Direction rotation = gWindowSceneryRotation ;
rotation - = get_current_rotation ( ) ;
rotation & = 0x3 ;
2020-08-28 02:06:39 +02:00
if ( gConfigGeneral . virtual_floor_style ! = VirtualFloorStyles : : Off )
2018-01-10 15:05:05 +01:00
{
2018-03-04 17:44:42 +01:00
virtual_floor_set_height ( gSceneryPlaceZ ) ;
2018-01-10 15:05:05 +01:00
}
2020-11-15 14:58:36 +01:00
* outDirection = rotation ;
2015-04-18 13:17:44 +02:00
}
2020-11-15 14:58:36 +01:00
static void sub_6E1F34_banner (
const ScreenCoordsXY & sourceScreenPos , ObjectEntryIndex sceneryIndex , CoordsXY & gridPos , int32_t * outZ ,
Direction * outDirection )
2020-03-13 14:44:34 +01:00
{
2020-11-15 14:58:36 +01:00
rct_window * w = window_find_by_class ( WC_SCENERY ) ;
2020-03-13 14:44:34 +01:00
2020-11-15 14:58:36 +01:00
if ( w = = nullptr )
{
gridPos . setNull ( ) ;
return ;
}
2020-03-13 14:44:34 +01:00
2020-11-15 14:58:36 +01:00
auto screenPos = sourceScreenPos ;
sub_6E1F34_update_screen_coords_and_buttons_pressed ( false , screenPos ) ;
2020-03-13 14:44:34 +01:00
2020-11-15 14:58:36 +01:00
// Banner
auto flags = VIEWPORT_INTERACTION_MASK_FOOTPATH & VIEWPORT_INTERACTION_MASK_FOOTPATH_ITEM ;
2020-03-13 14:44:34 +01:00
2020-11-15 14:58:36 +01:00
auto info = get_map_coordinates_from_pos ( screenPos , flags ) ;
gridPos = info . Loc ;
2020-03-13 14:44:34 +01:00
2020-11-15 14:58:36 +01:00
if ( info . SpriteType = = VIEWPORT_INTERACTION_ITEM_NONE )
{
gridPos . setNull ( ) ;
return ;
}
2020-03-13 14:44:34 +01:00
2020-11-15 14:58:36 +01:00
uint8_t rotation = gWindowSceneryRotation ;
rotation - = get_current_rotation ( ) ;
rotation & = 0x3 ;
2020-03-13 14:44:34 +01:00
2020-11-15 14:58:36 +01:00
auto z = info . Element - > GetBaseZ ( ) ;
2020-03-13 14:44:34 +01:00
2020-11-15 14:58:36 +01:00
if ( info . Element - > AsPath ( ) - > IsSloped ( ) )
{
if ( rotation ! = direction_reverse ( info . Element - > AsPath ( ) - > GetSlopeDirection ( ) ) )
{
z + = ( 2 * COORDS_Z_STEP ) ;
}
}
if ( gConfigGeneral . virtual_floor_style ! = VirtualFloorStyles : : Off )
{
virtual_floor_set_height ( gSceneryPlaceZ ) ;
}
2020-03-13 14:44:34 +01:00
2020-11-15 14:58:36 +01:00
* outDirection = rotation ;
* outZ = z ;
2020-03-13 14:44:34 +01:00
}
2014-10-21 18:59:47 +02:00
/**
2015-10-20 20:16:30 +02:00
*
2015-08-31 00:45:45 +02:00
* rct2 : 0x006E2CC6
2014-10-21 18:59:47 +02:00
*/
2020-05-01 17:52:07 +02:00
static void window_top_toolbar_scenery_tool_down ( const ScreenCoordsXY & windowPos , rct_window * w , rct_widgetindex widgetIndex )
2015-08-31 00:45:45 +02:00
{
2017-06-06 23:24:18 +02:00
scenery_remove_ghost_tool_placement ( ) ;
2018-06-22 23:21:44 +02:00
if ( gWindowSceneryPaintEnabled & 1 )
{
2020-05-01 17:52:07 +02:00
repaint_scenery_tool_down ( windowPos , widgetIndex ) ;
2017-06-06 23:24:18 +02:00
return ;
2018-06-22 23:21:44 +02:00
}
else if ( gWindowSceneryEyedropperEnabled )
{
2020-05-01 17:52:07 +02:00
scenery_eyedropper_tool_down ( windowPos , widgetIndex ) ;
2017-06-06 23:24:18 +02:00
return ;
}
2020-03-13 14:44:34 +01:00
ScenerySelection selectedTab = gWindowSceneryTabSelections [ gWindowSceneryActiveTabIndex ] ;
uint8_t sceneryType = selectedTab . SceneryType ;
uint16_t selectedScenery = selectedTab . EntryIndex ;
2017-06-06 23:24:18 +02:00
2020-03-15 13:19:26 +01:00
if ( selectedTab . IsUndefined ( ) )
2018-06-22 23:21:44 +02:00
return ;
2017-06-06 23:24:18 +02:00
2019-12-24 21:09:22 +01:00
CoordsXY gridPos ;
2017-06-06 23:24:18 +02:00
2018-06-22 23:21:44 +02:00
switch ( sceneryType )
2017-06-06 23:24:18 +02:00
{
2018-06-22 23:21:44 +02:00
case SCENERY_TYPE_SMALL :
{
2020-03-13 14:44:34 +01:00
uint8_t quadrant ;
2020-11-15 14:24:14 +01:00
Direction rotation ;
2020-12-02 12:23:38 +01:00
sub_6E1F34_small_scenery ( windowPos , selectedScenery , gridPos , & quadrant , & rotation ) ;
2020-03-13 14:44:34 +01:00
if ( gridPos . isNull ( ) )
return ;
2018-06-22 23:21:44 +02:00
int32_t quantity = 1 ;
2019-12-12 16:42:19 +01:00
bool isCluster = gWindowSceneryScatterEnabled
2018-06-22 23:21:44 +02:00
& & ( network_get_mode ( ) ! = NETWORK_MODE_CLIENT
| | network_can_perform_command ( network_get_current_player_group_index ( ) , - 2 ) ) ;
2020-02-19 14:05:36 +01:00
2017-12-04 20:09:38 +01:00
if ( isCluster )
{
2020-02-19 14:05:36 +01:00
switch ( gWindowSceneryScatterDensity )
{
case ScatterToolDensity : : LowDensity :
quantity = gWindowSceneryScatterSize ;
break ;
case ScatterToolDensity : : MediumDensity :
quantity = gWindowSceneryScatterSize * 2 ;
break ;
case ScatterToolDensity : : HighDensity :
quantity = gWindowSceneryScatterSize * 3 ;
break ;
}
2018-06-22 23:21:44 +02:00
}
2019-02-26 14:19:17 +01:00
bool forceError = true ;
2020-02-19 14:05:36 +01:00
for ( int32_t q = 0 ; q < quantity ; q + + )
2018-06-22 23:21:44 +02:00
{
int32_t zCoordinate = gSceneryPlaceZ ;
2020-03-13 14:44:34 +01:00
rct_scenery_entry * scenery = get_small_scenery_entry ( selectedScenery ) ;
2018-06-22 23:21:44 +02:00
2019-12-24 21:09:22 +01:00
int16_t cur_grid_x = gridPos . x ;
int16_t cur_grid_y = gridPos . y ;
2018-06-22 23:21:44 +02:00
if ( isCluster )
{
if ( ! scenery_small_entry_has_flag ( scenery , SMALL_SCENERY_FLAG_FULL_TILE ) )
{
2020-03-13 14:44:34 +01:00
quadrant = util_rand ( ) & 3 ;
2018-06-22 23:21:44 +02:00
}
2020-02-20 14:49:27 +01:00
int16_t grid_x_offset = ( util_rand ( ) % gWindowSceneryScatterSize ) - ( gWindowSceneryScatterSize / 2 ) ;
int16_t grid_y_offset = ( util_rand ( ) % gWindowSceneryScatterSize ) - ( gWindowSceneryScatterSize / 2 ) ;
if ( gWindowSceneryScatterSize % 2 = = 0 )
2019-12-12 16:42:19 +01:00
{
2020-02-20 14:49:27 +01:00
grid_x_offset + = 1 ;
grid_y_offset + = 1 ;
2019-12-12 16:42:19 +01:00
}
2020-02-20 14:49:27 +01:00
cur_grid_x + = grid_x_offset * COORDS_XY_STEP ;
cur_grid_y + = grid_y_offset * COORDS_XY_STEP ;
2018-06-22 23:21:44 +02:00
if ( ! scenery_small_entry_has_flag ( scenery , SMALL_SCENERY_FLAG_ROTATABLE ) )
{
gSceneryPlaceRotation = ( gSceneryPlaceRotation + 1 ) & 3 ;
}
}
uint8_t zAttemptRange = 1 ;
if ( gSceneryPlaceZ ! = 0 & & gSceneryShiftPressed )
2017-12-04 20:09:38 +01:00
{
2018-06-22 23:21:44 +02:00
zAttemptRange = 20 ;
2017-06-06 23:24:18 +02:00
}
2020-10-15 03:04:39 +02:00
auto success = GameActions : : Status : : Unknown ;
2019-02-26 14:19:17 +01:00
// Try find a valid z coordinate
2018-06-22 23:21:44 +02:00
for ( ; zAttemptRange ! = 0 ; zAttemptRange - - )
{
2019-02-26 14:19:17 +01:00
auto smallSceneryPlaceAction = SmallSceneryPlaceAction (
2020-03-13 14:44:34 +01:00
{ cur_grid_x , cur_grid_y , gSceneryPlaceZ , gSceneryPlaceRotation } , quadrant , selectedScenery ,
2020-12-02 12:23:38 +01:00
gWindowSceneryPrimaryColour , gWindowScenerySecondaryColour ) ;
2019-02-26 14:19:17 +01:00
auto res = GameActions : : Query ( & smallSceneryPlaceAction ) ;
success = res - > Error ;
2020-10-15 03:04:39 +02:00
if ( res - > Error = = GameActions : : Status : : Ok )
2018-06-22 23:21:44 +02:00
{
break ;
}
2020-10-15 03:04:39 +02:00
if ( res - > Error = = GameActions : : Status : : InsufficientFunds )
2018-06-22 23:21:44 +02:00
{
break ;
}
2019-02-26 14:19:17 +01:00
if ( zAttemptRange ! = 1 )
{
gSceneryPlaceZ + = 8 ;
}
2018-06-22 23:21:44 +02:00
}
2019-02-26 14:19:17 +01:00
// Actually place
2020-10-15 03:04:39 +02:00
if ( success = = GameActions : : Status : : Ok | | ( ( q + 1 = = quantity ) & & forceError ) )
2018-06-22 23:21:44 +02:00
{
2019-02-26 14:19:17 +01:00
auto smallSceneryPlaceAction = SmallSceneryPlaceAction (
2020-03-13 14:44:34 +01:00
{ cur_grid_x , cur_grid_y , gSceneryPlaceZ , gSceneryPlaceRotation } , quadrant , selectedScenery ,
2020-12-02 12:23:38 +01:00
gWindowSceneryPrimaryColour , gWindowScenerySecondaryColour ) ;
2019-02-26 14:19:17 +01:00
2020-10-15 03:04:39 +02:00
smallSceneryPlaceAction . SetCallback ( [ = ] ( const GameAction * ga , const GameActions : : Result * result ) {
if ( result - > Error = = GameActions : : Status : : Ok )
2019-02-26 14:19:17 +01:00
{
2020-10-06 23:34:42 +02:00
OpenRCT2 : : Audio : : Play3D ( OpenRCT2 : : Audio : : SoundId : : PlaceItem , result - > Position ) ;
2019-02-26 14:19:17 +01:00
}
} ) ;
auto res = GameActions : : Execute ( & smallSceneryPlaceAction ) ;
2020-10-15 03:04:39 +02:00
if ( res - > Error = = GameActions : : Status : : Ok )
2019-02-26 14:19:17 +01:00
{
forceError = false ;
}
2020-10-15 03:04:39 +02:00
if ( res - > Error = = GameActions : : Status : : InsufficientFunds )
2018-06-22 23:21:44 +02:00
{
break ;
}
2017-06-06 23:24:18 +02:00
}
2018-06-22 23:21:44 +02:00
gSceneryPlaceZ = zCoordinate ;
2017-06-06 23:24:18 +02:00
}
2018-06-22 23:21:44 +02:00
break ;
}
case SCENERY_TYPE_PATH_ITEM :
{
2020-03-13 14:44:34 +01:00
int32_t z ;
2020-05-01 17:52:07 +02:00
sub_6E1F34_path_item ( windowPos , selectedScenery , gridPos , & z ) ;
2020-03-13 14:44:34 +01:00
if ( gridPos . isNull ( ) )
return ;
2020-11-03 09:17:29 +01:00
auto footpathAdditionPlaceAction = FootpathAdditionPlaceAction ( { gridPos , z } , selectedScenery + 1 ) ;
2018-06-22 23:21:44 +02:00
2020-11-03 09:17:29 +01:00
footpathAdditionPlaceAction . SetCallback ( [ ] ( const GameAction * ga , const GameActions : : Result * result ) {
2020-10-15 03:04:39 +02:00
if ( result - > Error ! = GameActions : : Status : : Ok )
2019-03-01 11:53:52 +01:00
{
return ;
}
2020-10-06 23:34:42 +02:00
OpenRCT2 : : Audio : : Play3D ( OpenRCT2 : : Audio : : SoundId : : PlaceItem , result - > Position ) ;
2019-03-01 11:53:52 +01:00
} ) ;
2020-11-03 09:17:29 +01:00
auto res = GameActions : : Execute ( & footpathAdditionPlaceAction ) ;
2018-06-22 23:21:44 +02:00
break ;
}
case SCENERY_TYPE_WALL :
{
2020-03-13 14:44:34 +01:00
uint8_t edges ;
2020-12-02 12:23:38 +01:00
sub_6E1F34_wall ( windowPos , selectedScenery , gridPos , & edges ) ;
2020-03-13 14:44:34 +01:00
if ( gridPos . isNull ( ) )
return ;
2018-06-20 17:28:51 +02:00
uint8_t zAttemptRange = 1 ;
2018-06-22 23:21:44 +02:00
if ( gSceneryPlaceZ ! = 0 & & gSceneryShiftPressed )
{
2017-06-06 23:24:18 +02:00
zAttemptRange = 20 ;
}
2018-06-22 23:21:44 +02:00
for ( ; zAttemptRange ! = 0 ; zAttemptRange - - )
{
2019-03-25 20:20:31 +01:00
auto wallPlaceAction = WallPlaceAction (
2020-12-02 12:23:38 +01:00
selectedScenery , { gridPos , gSceneryPlaceZ } , edges , gWindowSceneryPrimaryColour ,
gWindowScenerySecondaryColour , gWindowSceneryTertiaryColour ) ;
2019-03-25 20:20:31 +01:00
auto res = GameActions : : Query ( & wallPlaceAction ) ;
2020-10-15 03:04:39 +02:00
if ( res - > Error = = GameActions : : Status : : Ok )
2018-06-22 23:21:44 +02:00
{
2019-03-25 20:20:31 +01:00
break ;
2017-06-06 23:24:18 +02:00
}
2020-04-21 00:30:37 +02:00
if ( auto message = res - > ErrorMessage . AsStringId ( ) )
2018-06-22 23:21:44 +02:00
{
2020-03-03 22:11:26 +01:00
if ( * message = = STR_NOT_ENOUGH_CASH_REQUIRES | | * message = = STR_CAN_ONLY_BUILD_THIS_ON_WATER )
{
break ;
}
2017-06-06 23:24:18 +02:00
}
2019-03-28 18:45:39 +01:00
if ( zAttemptRange ! = 1 )
{
gSceneryPlaceZ + = 8 ;
}
2017-06-06 23:24:18 +02:00
}
2019-03-25 20:20:31 +01:00
auto wallPlaceAction = WallPlaceAction (
2020-12-02 12:23:38 +01:00
selectedScenery , { gridPos , gSceneryPlaceZ } , edges , gWindowSceneryPrimaryColour , gWindowScenerySecondaryColour ,
gWindowSceneryTertiaryColour ) ;
2019-03-25 20:20:31 +01:00
2020-10-15 03:04:39 +02:00
wallPlaceAction . SetCallback ( [ ] ( const GameAction * ga , const GameActions : : Result * result ) {
if ( result - > Error = = GameActions : : Status : : Ok )
2019-03-25 20:20:31 +01:00
{
2020-10-06 23:34:42 +02:00
OpenRCT2 : : Audio : : Play3D ( OpenRCT2 : : Audio : : SoundId : : PlaceItem , result - > Position ) ;
2019-03-25 20:20:31 +01:00
}
} ) ;
auto res = GameActions : : Execute ( & wallPlaceAction ) ;
2018-06-22 23:21:44 +02:00
break ;
2017-06-06 23:24:18 +02:00
}
2018-06-22 23:21:44 +02:00
case SCENERY_TYPE_LARGE :
{
2020-03-13 14:44:34 +01:00
Direction direction ;
2020-12-02 12:23:38 +01:00
sub_6E1F34_large_scenery ( windowPos , selectedScenery , gridPos , & direction ) ;
2020-03-13 14:44:34 +01:00
if ( gridPos . isNull ( ) )
return ;
2018-06-22 23:21:44 +02:00
uint8_t zAttemptRange = 1 ;
if ( gSceneryPlaceZ ! = 0 & & gSceneryShiftPressed )
{
zAttemptRange = 20 ;
}
2017-06-06 23:24:18 +02:00
2018-06-22 23:21:44 +02:00
for ( ; zAttemptRange ! = 0 ; zAttemptRange - - )
{
2019-12-24 21:09:22 +01:00
CoordsXYZD loc = { gridPos , gSceneryPlaceZ , direction } ;
2017-06-06 23:24:18 +02:00
2020-12-02 12:23:38 +01:00
auto sceneryPlaceAction = LargeSceneryPlaceAction (
loc , selectedScenery , gWindowSceneryPrimaryColour , gWindowScenerySecondaryColour ) ;
2017-06-06 23:24:18 +02:00
2019-04-05 20:16:23 +02:00
auto res = GameActions : : Query ( & sceneryPlaceAction ) ;
2020-10-15 03:04:39 +02:00
if ( res - > Error = = GameActions : : Status : : Ok )
2018-06-22 23:21:44 +02:00
{
2019-04-05 20:16:23 +02:00
break ;
2018-06-22 23:21:44 +02:00
}
2017-06-06 23:24:18 +02:00
2020-04-21 00:30:37 +02:00
if ( auto message = res - > ErrorMessage . AsStringId ( ) )
2018-06-22 23:21:44 +02:00
{
2020-03-03 22:11:26 +01:00
if ( * message = = STR_NOT_ENOUGH_CASH_REQUIRES | | * message = = STR_CAN_ONLY_BUILD_THIS_ON_WATER )
{
break ;
}
2018-06-22 23:21:44 +02:00
}
2017-06-06 23:24:18 +02:00
2019-04-05 20:16:23 +02:00
if ( zAttemptRange ! = 1 )
{
gSceneryPlaceZ + = 8 ;
}
2017-06-06 23:24:18 +02:00
}
2020-03-13 14:44:34 +01:00
2019-12-24 21:09:22 +01:00
CoordsXYZD loc = { gridPos , gSceneryPlaceZ , direction } ;
2017-06-06 23:24:18 +02:00
2020-12-02 12:23:38 +01:00
auto sceneryPlaceAction = LargeSceneryPlaceAction (
loc , selectedScenery , gWindowSceneryPrimaryColour , gWindowScenerySecondaryColour ) ;
2020-10-15 03:04:39 +02:00
sceneryPlaceAction . SetCallback ( [ = ] ( const GameAction * ga , const GameActions : : Result * result ) {
if ( result - > Error = = GameActions : : Status : : Ok )
2019-04-05 20:16:23 +02:00
{
2020-10-06 23:34:42 +02:00
OpenRCT2 : : Audio : : Play3D ( OpenRCT2 : : Audio : : SoundId : : PlaceItem , result - > Position ) ;
2019-04-05 20:16:23 +02:00
}
else
{
2020-10-06 23:34:42 +02:00
OpenRCT2 : : Audio : : Play3D ( OpenRCT2 : : Audio : : SoundId : : Error , { loc . x , loc . y , gSceneryPlaceZ } ) ;
2019-04-05 20:16:23 +02:00
}
} ) ;
auto res = GameActions : : Execute ( & sceneryPlaceAction ) ;
2018-06-22 23:21:44 +02:00
break ;
2017-06-06 23:24:18 +02:00
}
2018-06-22 23:21:44 +02:00
case SCENERY_TYPE_BANNER :
{
2020-03-13 14:44:34 +01:00
int32_t z ;
Direction direction ;
2020-05-01 17:52:07 +02:00
sub_6E1F34_banner ( windowPos , selectedScenery , gridPos , & z , & direction ) ;
2020-03-13 14:44:34 +01:00
if ( gridPos . isNull ( ) )
return ;
2019-12-24 21:09:22 +01:00
CoordsXYZD loc { gridPos , z , direction } ;
2019-04-06 10:44:07 +02:00
auto primaryColour = gWindowSceneryPrimaryColour ;
auto bannerIndex = create_new_banner ( 0 ) ;
if ( bannerIndex = = BANNER_INDEX_NULL )
{
2020-08-27 00:01:15 +02:00
context_show_error ( STR_CANT_POSITION_THIS_HERE , STR_TOO_MANY_BANNERS_IN_GAME , { } ) ;
2019-04-06 10:44:07 +02:00
break ;
}
2020-03-13 14:44:34 +01:00
auto bannerPlaceAction = BannerPlaceAction ( loc , selectedScenery , bannerIndex , primaryColour ) ;
2020-10-15 03:04:39 +02:00
bannerPlaceAction . SetCallback ( [ = ] ( const GameAction * ga , const GameActions : : Result * result ) {
if ( result - > Error = = GameActions : : Status : : Ok )
2019-04-06 10:44:07 +02:00
{
2020-10-06 23:34:42 +02:00
OpenRCT2 : : Audio : : Play3D ( OpenRCT2 : : Audio : : SoundId : : PlaceItem , result - > Position ) ;
2019-04-06 10:44:07 +02:00
context_open_detail_window ( WD_BANNER , bannerIndex ) ;
}
} ) ;
GameActions : : Execute ( & bannerPlaceAction ) ;
2018-06-22 23:21:44 +02:00
break ;
2017-06-06 23:24:18 +02:00
}
}
2014-10-21 18:59:47 +02:00
}
2020-05-01 17:52:07 +02:00
static uint8_t top_toolbar_tool_update_land_paint ( const ScreenCoordsXY & screenPos )
2018-06-22 23:21:44 +02:00
{
2019-10-19 15:38:26 +02:00
uint8_t state_changed = 0 ;
2017-06-06 23:24:18 +02:00
map_invalidate_selection_rect ( ) ;
gMapSelectFlags & = ~ MAP_SELECT_FLAG_ENABLE ;
2020-05-01 17:52:07 +02:00
auto mapTile = screen_get_map_xy ( screenPos , nullptr ) ;
2017-06-06 23:24:18 +02:00
2019-11-29 17:17:01 +01:00
if ( ! mapTile )
2018-06-22 23:21:44 +02:00
{
if ( gClearSceneryCost ! = MONEY32_UNDEFINED )
{
2017-06-06 23:24:18 +02:00
gClearSceneryCost = MONEY32_UNDEFINED ;
window_invalidate_by_class ( WC_CLEAR_SCENERY ) ;
}
2019-10-19 15:38:26 +02:00
return state_changed ;
2017-06-06 23:24:18 +02:00
}
2018-06-22 23:21:44 +02:00
if ( ! ( gMapSelectFlags & MAP_SELECT_FLAG_ENABLE ) )
{
2017-06-06 23:24:18 +02:00
gMapSelectFlags | = MAP_SELECT_FLAG_ENABLE ;
state_changed + + ;
}
2018-06-22 23:21:44 +02:00
if ( gMapSelectType ! = MAP_SELECT_TYPE_FULL )
{
2017-06-06 23:24:18 +02:00
gMapSelectType = MAP_SELECT_TYPE_FULL ;
state_changed + + ;
}
2018-06-20 17:28:51 +02:00
int16_t tool_size = std : : max < uint16_t > ( 1 , gLandToolSize ) ;
int16_t tool_length = ( tool_size - 1 ) * 32 ;
2017-06-06 23:24:18 +02:00
// Move to tool bottom left
2019-11-29 17:17:01 +01:00
mapTile - > x - = ( tool_size - 1 ) * 16 ;
mapTile - > y - = ( tool_size - 1 ) * 16 ;
2019-11-30 16:47:23 +01:00
mapTile = mapTile - > ToTileStart ( ) ;
2017-06-06 23:24:18 +02:00
2019-11-29 17:17:01 +01:00
if ( gMapSelectPositionA . x ! = mapTile - > x )
2018-06-22 23:21:44 +02:00
{
2019-11-29 17:17:01 +01:00
gMapSelectPositionA . x = mapTile - > x ;
2017-06-06 23:24:18 +02:00
state_changed + + ;
}
2019-11-29 17:17:01 +01:00
if ( gMapSelectPositionA . y ! = mapTile - > y )
2018-06-22 23:21:44 +02:00
{
2019-11-29 17:17:01 +01:00
gMapSelectPositionA . y = mapTile - > y ;
2017-06-06 23:24:18 +02:00
state_changed + + ;
}
2019-11-29 17:17:01 +01:00
mapTile - > x + = tool_length ;
mapTile - > y + = tool_length ;
2017-06-06 23:24:18 +02:00
2019-11-29 17:17:01 +01:00
if ( gMapSelectPositionB . x ! = mapTile - > x )
2018-06-22 23:21:44 +02:00
{
2019-11-29 17:17:01 +01:00
gMapSelectPositionB . x = mapTile - > x ;
2017-06-06 23:24:18 +02:00
state_changed + + ;
}
2019-11-29 17:17:01 +01:00
if ( gMapSelectPositionB . y ! = mapTile - > y )
2018-06-22 23:21:44 +02:00
{
2019-11-29 17:17:01 +01:00
gMapSelectPositionB . y = mapTile - > y ;
2017-06-06 23:24:18 +02:00
state_changed + + ;
}
map_invalidate_selection_rect ( ) ;
2019-10-19 15:38:26 +02:00
return state_changed ;
}
/**
*
* rct2 : 0x0068E213
*/
2020-05-01 17:52:07 +02:00
static void top_toolbar_tool_update_scenery_clear ( const ScreenCoordsXY & screenPos )
2019-10-19 15:38:26 +02:00
{
2020-05-01 17:52:07 +02:00
if ( ! top_toolbar_tool_update_land_paint ( screenPos ) )
2017-06-06 23:24:18 +02:00
return ;
2019-01-02 12:59:37 +01:00
auto action = GetClearAction ( ) ;
auto result = GameActions : : Query ( & action ) ;
2020-10-15 03:04:39 +02:00
auto cost = ( result - > Error = = GameActions : : Status : : Ok ? result - > Cost : MONEY32_UNDEFINED ) ;
2018-06-22 23:21:44 +02:00
if ( gClearSceneryCost ! = cost )
{
2017-06-06 23:24:18 +02:00
gClearSceneryCost = cost ;
window_invalidate_by_class ( WC_CLEAR_SCENERY ) ;
}
2015-05-25 18:24:18 +02:00
}
2015-05-26 21:36:05 +02:00
/**
2018-06-22 23:21:44 +02:00
*
* rct2 : 0x00664280
*/
2020-05-01 17:52:07 +02:00
static void top_toolbar_tool_update_land ( const ScreenCoordsXY & screenPos )
2017-09-23 23:41:32 +02:00
{
2020-11-02 14:43:35 +01:00
const bool mapCtrlPressed = InputTestPlaceObjectModifier ( PLACE_OBJECT_MODIFIER_COPY_Z ) ;
2017-09-23 23:41:32 +02:00
2017-06-06 23:24:18 +02:00
map_invalidate_selection_rect ( ) ;
2017-09-23 23:41:32 +02:00
if ( gCurrentToolId = = TOOL_UP_DOWN_ARROW )
{
2017-06-06 23:24:18 +02:00
if ( ! ( gMapSelectFlags & MAP_SELECT_FLAG_ENABLE ) )
return ;
money32 lower_cost = selection_lower_land ( 0 ) ;
money32 raise_cost = selection_raise_land ( 0 ) ;
2017-09-23 23:41:32 +02:00
if ( gLandToolRaiseCost ! = raise_cost | | gLandToolLowerCost ! = lower_cost )
{
2017-06-06 23:24:18 +02:00
gLandToolRaiseCost = raise_cost ;
gLandToolLowerCost = lower_cost ;
window_invalidate_by_class ( WC_LAND ) ;
}
return ;
}
2018-06-22 23:21:44 +02:00
int16_t tool_size = gLandToolSize ;
2019-11-29 17:17:01 +01:00
std : : optional < CoordsXY > mapTile ;
2018-06-22 23:21:44 +02:00
uint8_t side ;
2017-06-06 23:24:18 +02:00
gMapSelectFlags & = ~ MAP_SELECT_FLAG_ENABLE ;
2017-09-23 23:41:32 +02:00
if ( tool_size = = 1 )
{
2018-06-20 17:28:51 +02:00
int32_t selectionType ;
2017-09-23 23:41:32 +02:00
// Get selection type and map coordinates from mouse x,y position
2020-05-01 17:52:07 +02:00
screen_pos_to_map_pos ( screenPos , & selectionType ) ;
mapTile = screen_get_map_xy_side ( screenPos , & side ) ;
2017-06-06 23:24:18 +02:00
2019-11-29 17:17:01 +01:00
if ( ! mapTile )
2017-09-23 23:41:32 +02:00
{
2017-06-06 23:24:18 +02:00
money32 lower_cost = MONEY32_UNDEFINED ;
money32 raise_cost = MONEY32_UNDEFINED ;
2017-09-23 23:41:32 +02:00
if ( gLandToolRaiseCost ! = raise_cost | | gLandToolLowerCost ! = lower_cost )
{
2017-06-06 23:24:18 +02:00
gLandToolRaiseCost = raise_cost ;
gLandToolLowerCost = lower_cost ;
window_invalidate_by_class ( WC_LAND ) ;
}
return ;
}
2018-06-20 17:28:51 +02:00
uint8_t state_changed = 0 ;
2017-06-06 23:24:18 +02:00
2017-09-23 23:41:32 +02:00
if ( ! ( gMapSelectFlags & MAP_SELECT_FLAG_ENABLE ) )
{
2017-06-06 23:24:18 +02:00
gMapSelectFlags | = MAP_SELECT_FLAG_ENABLE ;
state_changed + + ;
}
2017-09-23 23:41:32 +02:00
if ( gMapSelectType ! = selectionType )
{
gMapSelectType = selectionType ;
2017-06-06 23:24:18 +02:00
state_changed + + ;
}
2017-09-23 23:41:32 +02:00
if ( ( gMapSelectType ! = MAP_SELECT_TYPE_EDGE_0 + ( side & 0xFF ) ) & & mapCtrlPressed )
{
gMapSelectType = MAP_SELECT_TYPE_EDGE_0 + ( side & 0xFF ) ;
state_changed + + ;
}
2017-06-06 23:24:18 +02:00
2019-11-29 17:17:01 +01:00
if ( gMapSelectPositionA . x ! = mapTile - > x )
2017-09-23 23:41:32 +02:00
{
2019-11-29 17:17:01 +01:00
gMapSelectPositionA . x = mapTile - > x ;
2017-06-06 23:24:18 +02:00
state_changed + + ;
}
2019-11-29 17:17:01 +01:00
if ( gMapSelectPositionA . y ! = mapTile - > y )
2017-09-23 23:41:32 +02:00
{
2019-11-29 17:17:01 +01:00
gMapSelectPositionA . y = mapTile - > y ;
2017-06-06 23:24:18 +02:00
state_changed + + ;
}
2019-11-29 17:17:01 +01:00
if ( gMapSelectPositionB . x ! = mapTile - > x )
2017-09-23 23:41:32 +02:00
{
2019-11-29 17:17:01 +01:00
gMapSelectPositionB . x = mapTile - > x ;
2017-06-06 23:24:18 +02:00
state_changed + + ;
}
2019-11-29 17:17:01 +01:00
if ( gMapSelectPositionB . y ! = mapTile - > y )
2017-09-23 23:41:32 +02:00
{
2019-11-29 17:17:01 +01:00
gMapSelectPositionB . y = mapTile - > y ;
2017-06-06 23:24:18 +02:00
state_changed + + ;
}
map_invalidate_selection_rect ( ) ;
if ( ! state_changed )
return ;
money32 lower_cost = selection_lower_land ( 0 ) ;
money32 raise_cost = selection_raise_land ( 0 ) ;
2018-06-22 23:21:44 +02:00
if ( gLandToolRaiseCost ! = raise_cost | | gLandToolLowerCost ! = lower_cost )
{
2017-06-06 23:24:18 +02:00
gLandToolRaiseCost = raise_cost ;
gLandToolLowerCost = lower_cost ;
window_invalidate_by_class ( WC_LAND ) ;
}
return ;
}
2017-09-23 23:41:32 +02:00
// Get map coordinates and the side of the tile that is being hovered over
2020-05-01 17:52:07 +02:00
mapTile = screen_get_map_xy_side ( screenPos , & side ) ;
2017-06-06 23:24:18 +02:00
2019-11-29 17:17:01 +01:00
if ( ! mapTile )
2018-06-22 23:21:44 +02:00
{
2017-06-06 23:24:18 +02:00
money32 lower_cost = MONEY32_UNDEFINED ;
money32 raise_cost = MONEY32_UNDEFINED ;
2018-06-22 23:21:44 +02:00
if ( gLandToolRaiseCost ! = raise_cost | | gLandToolLowerCost ! = lower_cost )
{
2017-06-06 23:24:18 +02:00
gLandToolRaiseCost = raise_cost ;
gLandToolLowerCost = lower_cost ;
window_invalidate_by_class ( WC_LAND ) ;
}
return ;
}
2018-06-20 17:28:51 +02:00
uint8_t state_changed = 0 ;
2017-06-06 23:24:18 +02:00
2018-06-22 23:21:44 +02:00
if ( ! ( gMapSelectFlags & MAP_SELECT_FLAG_ENABLE ) )
{
2017-06-06 23:24:18 +02:00
gMapSelectFlags | = MAP_SELECT_FLAG_ENABLE ;
state_changed + + ;
}
2018-06-22 23:21:44 +02:00
if ( gMapSelectType ! = MAP_SELECT_TYPE_FULL )
{
2017-06-06 23:24:18 +02:00
gMapSelectType = MAP_SELECT_TYPE_FULL ;
state_changed + + ;
}
2017-09-23 23:41:32 +02:00
if ( ( gMapSelectType ! = MAP_SELECT_TYPE_EDGE_0 + ( side & 0xFF ) ) & & mapCtrlPressed )
{
gMapSelectType = MAP_SELECT_TYPE_EDGE_0 + ( side & 0xFF ) ;
state_changed + + ;
}
2017-06-06 23:24:18 +02:00
if ( tool_size = = 0 )
tool_size = 1 ;
2018-06-20 17:28:51 +02:00
int16_t tool_length = ( tool_size - 1 ) * 32 ;
2017-06-06 23:24:18 +02:00
2017-09-23 23:41:32 +02:00
// Decide on shape of the brush for bigger selection size
switch ( gMapSelectType )
{
2018-06-22 23:21:44 +02:00
case MAP_SELECT_TYPE_EDGE_0 :
case MAP_SELECT_TYPE_EDGE_2 :
// Line
2019-11-29 17:17:01 +01:00
mapTile - > y - = ( tool_size - 1 ) * 16 ;
2019-11-30 16:47:23 +01:00
mapTile - > y = mapTile - > ToTileStart ( ) . y ;
2018-06-22 23:21:44 +02:00
break ;
case MAP_SELECT_TYPE_EDGE_1 :
case MAP_SELECT_TYPE_EDGE_3 :
// Line
2019-11-29 17:17:01 +01:00
mapTile - > x - = ( tool_size - 1 ) * 16 ;
2019-11-30 16:47:23 +01:00
mapTile - > x = mapTile - > ToTileStart ( ) . x ;
2018-06-22 23:21:44 +02:00
break ;
default :
// Move to tool bottom left
2019-11-29 17:17:01 +01:00
mapTile - > x - = ( tool_size - 1 ) * 16 ;
mapTile - > y - = ( tool_size - 1 ) * 16 ;
2019-11-30 16:47:23 +01:00
mapTile = mapTile - > ToTileStart ( ) ;
2018-06-22 23:21:44 +02:00
break ;
2017-09-23 23:41:32 +02:00
}
2017-06-06 23:24:18 +02:00
2019-11-29 17:17:01 +01:00
if ( gMapSelectPositionA . x ! = mapTile - > x )
2017-09-23 23:41:32 +02:00
{
2019-11-29 17:17:01 +01:00
gMapSelectPositionA . x = mapTile - > x ;
2017-06-06 23:24:18 +02:00
state_changed + + ;
}
2019-11-29 17:17:01 +01:00
if ( gMapSelectPositionA . y ! = mapTile - > y )
2017-09-23 23:41:32 +02:00
{
2019-11-29 17:17:01 +01:00
gMapSelectPositionA . y = mapTile - > y ;
2017-06-06 23:24:18 +02:00
state_changed + + ;
}
2017-09-23 23:41:32 +02:00
// Go to other side
switch ( gMapSelectType )
{
2018-06-22 23:21:44 +02:00
case MAP_SELECT_TYPE_EDGE_0 :
case MAP_SELECT_TYPE_EDGE_2 :
// Line
2019-11-29 17:17:01 +01:00
mapTile - > y + = tool_length ;
2018-06-22 23:21:44 +02:00
gMapSelectType = MAP_SELECT_TYPE_FULL ;
break ;
case MAP_SELECT_TYPE_EDGE_1 :
case MAP_SELECT_TYPE_EDGE_3 :
// Line
2019-11-29 17:17:01 +01:00
mapTile - > x + = tool_length ;
2018-06-22 23:21:44 +02:00
gMapSelectType = MAP_SELECT_TYPE_FULL ;
break ;
default :
2019-11-29 17:17:01 +01:00
mapTile - > x + = tool_length ;
mapTile - > y + = tool_length ;
2018-06-22 23:21:44 +02:00
break ;
2017-09-23 23:41:32 +02:00
}
2017-06-06 23:24:18 +02:00
2019-11-29 17:17:01 +01:00
if ( gMapSelectPositionB . x ! = mapTile - > x )
2018-06-22 23:21:44 +02:00
{
2019-11-29 17:17:01 +01:00
gMapSelectPositionB . x = mapTile - > x ;
2017-06-06 23:24:18 +02:00
state_changed + + ;
}
2019-11-29 17:17:01 +01:00
if ( gMapSelectPositionB . y ! = mapTile - > y )
2018-06-22 23:21:44 +02:00
{
2019-11-29 17:17:01 +01:00
gMapSelectPositionB . y = mapTile - > y ;
2017-06-06 23:24:18 +02:00
state_changed + + ;
}
map_invalidate_selection_rect ( ) ;
if ( ! state_changed )
return ;
money32 lower_cost = selection_lower_land ( 0 ) ;
money32 raise_cost = selection_raise_land ( 0 ) ;
2018-06-22 23:21:44 +02:00
if ( gLandToolRaiseCost ! = raise_cost | | gLandToolLowerCost ! = lower_cost )
{
2017-06-06 23:24:18 +02:00
gLandToolRaiseCost = raise_cost ;
gLandToolLowerCost = lower_cost ;
window_invalidate_by_class ( WC_LAND ) ;
}
2015-05-26 21:36:05 +02:00
}
2015-05-27 18:40:57 +02:00
/**
2018-06-22 23:21:44 +02:00
*
* rct2 : 0x006E6BDC
*/
2020-05-01 17:52:07 +02:00
static void top_toolbar_tool_update_water ( const ScreenCoordsXY & screenPos )
2018-06-22 23:21:44 +02:00
{
2017-06-06 23:24:18 +02:00
map_invalidate_selection_rect ( ) ;
2018-06-22 23:21:44 +02:00
if ( gCurrentToolId = = TOOL_UP_DOWN_ARROW )
{
2017-06-06 23:24:18 +02:00
if ( ! ( gMapSelectFlags & MAP_SELECT_FLAG_ENABLE ) )
return ;
2019-03-04 17:57:01 +01:00
auto waterLowerAction = WaterLowerAction (
{ gMapSelectPositionA . x , gMapSelectPositionA . y , gMapSelectPositionB . x , gMapSelectPositionB . y } ) ;
auto waterRaiseAction = WaterRaiseAction (
{ gMapSelectPositionA . x , gMapSelectPositionA . y , gMapSelectPositionB . x , gMapSelectPositionB . y } ) ;
2017-06-06 23:24:18 +02:00
2019-03-04 17:57:01 +01:00
auto res = GameActions : : Query ( & waterLowerAction ) ;
2020-10-15 03:04:39 +02:00
money32 lowerCost = res - > Error = = GameActions : : Status : : Ok ? res - > Cost : MONEY32_UNDEFINED ;
2017-06-06 23:24:18 +02:00
2019-03-04 17:57:01 +01:00
res = GameActions : : Query ( & waterRaiseAction ) ;
2020-10-15 03:04:39 +02:00
money32 raiseCost = res - > Error = = GameActions : : Status : : Ok ? res - > Cost : MONEY32_UNDEFINED ;
2019-03-04 17:57:01 +01:00
if ( gWaterToolRaiseCost ! = raiseCost | | gWaterToolLowerCost ! = lowerCost )
2018-06-22 23:21:44 +02:00
{
2019-03-04 17:57:01 +01:00
gWaterToolRaiseCost = raiseCost ;
gWaterToolLowerCost = lowerCost ;
2017-06-06 23:24:18 +02:00
window_invalidate_by_class ( WC_WATER ) ;
}
return ;
}
gMapSelectFlags & = ~ MAP_SELECT_FLAG_ENABLE ;
2020-08-02 09:32:59 +02:00
auto info = get_map_coordinates_from_pos ( screenPos , VIEWPORT_INTERACTION_MASK_TERRAIN & VIEWPORT_INTERACTION_MASK_WATER ) ;
2017-06-06 23:24:18 +02:00
2020-08-02 09:32:59 +02:00
if ( info . SpriteType = = VIEWPORT_INTERACTION_ITEM_NONE )
2018-06-22 23:21:44 +02:00
{
if ( gWaterToolRaiseCost ! = MONEY32_UNDEFINED | | gWaterToolLowerCost ! = MONEY32_UNDEFINED )
{
2017-06-06 23:24:18 +02:00
gWaterToolRaiseCost = MONEY32_UNDEFINED ;
gWaterToolLowerCost = MONEY32_UNDEFINED ;
window_invalidate_by_class ( WC_WATER ) ;
}
return ;
}
2020-08-02 09:32:59 +02:00
auto mapTile = info . Loc . ToTileCentre ( ) ;
2017-06-06 23:24:18 +02:00
2018-06-20 17:28:51 +02:00
uint8_t state_changed = 0 ;
2017-06-06 23:24:18 +02:00
2018-06-22 23:21:44 +02:00
if ( ! ( gMapSelectFlags & MAP_SELECT_FLAG_ENABLE ) )
{
2017-06-06 23:24:18 +02:00
gMapSelectFlags | = MAP_SELECT_FLAG_ENABLE ;
state_changed + + ;
}
2018-06-22 23:21:44 +02:00
if ( gMapSelectType ! = MAP_SELECT_TYPE_FULL_WATER )
{
2017-06-06 23:24:18 +02:00
gMapSelectType = MAP_SELECT_TYPE_FULL_WATER ;
state_changed + + ;
}
2018-06-20 17:28:51 +02:00
int16_t tool_size = std : : max < uint16_t > ( 1 , gLandToolSize ) ;
int16_t tool_length = ( tool_size - 1 ) * 32 ;
2017-06-06 23:24:18 +02:00
// Move to tool bottom left
mapTile . x - = ( tool_size - 1 ) * 16 ;
mapTile . y - = ( tool_size - 1 ) * 16 ;
mapTile . x & = 0xFFE0 ;
mapTile . y & = 0xFFE0 ;
2018-06-22 23:21:44 +02:00
if ( gMapSelectPositionA . x ! = mapTile . x )
{
2017-06-06 23:24:18 +02:00
gMapSelectPositionA . x = mapTile . x ;
state_changed + + ;
}
2018-06-22 23:21:44 +02:00
if ( gMapSelectPositionA . y ! = mapTile . y )
{
2017-06-06 23:24:18 +02:00
gMapSelectPositionA . y = mapTile . y ;
state_changed + + ;
}
mapTile . x + = tool_length ;
mapTile . y + = tool_length ;
2018-06-22 23:21:44 +02:00
if ( gMapSelectPositionB . x ! = mapTile . x )
{
2017-06-06 23:24:18 +02:00
gMapSelectPositionB . x = mapTile . x ;
state_changed + + ;
}
2018-06-22 23:21:44 +02:00
if ( gMapSelectPositionB . y ! = mapTile . y )
{
2017-06-06 23:24:18 +02:00
gMapSelectPositionB . y = mapTile . y ;
state_changed + + ;
}
map_invalidate_selection_rect ( ) ;
if ( ! state_changed )
return ;
2019-03-04 17:57:01 +01:00
auto waterLowerAction = WaterLowerAction (
{ gMapSelectPositionA . x , gMapSelectPositionA . y , gMapSelectPositionB . x , gMapSelectPositionB . y } ) ;
auto waterRaiseAction = WaterRaiseAction (
{ gMapSelectPositionA . x , gMapSelectPositionA . y , gMapSelectPositionB . x , gMapSelectPositionB . y } ) ;
auto res = GameActions : : Query ( & waterLowerAction ) ;
2020-10-15 03:04:39 +02:00
money32 lowerCost = res - > Error = = GameActions : : Status : : Ok ? res - > Cost : MONEY32_UNDEFINED ;
2018-06-22 23:21:44 +02:00
2019-03-04 17:57:01 +01:00
res = GameActions : : Query ( & waterRaiseAction ) ;
2020-10-15 03:04:39 +02:00
money32 raiseCost = res - > Error = = GameActions : : Status : : Ok ? res - > Cost : MONEY32_UNDEFINED ;
2018-06-22 23:21:44 +02:00
2019-03-04 17:57:01 +01:00
if ( gWaterToolRaiseCost ! = raiseCost | | gWaterToolLowerCost ! = lowerCost )
2018-06-22 23:21:44 +02:00
{
2019-03-04 17:57:01 +01:00
gWaterToolRaiseCost = raiseCost ;
gWaterToolLowerCost = lowerCost ;
2017-06-06 23:24:18 +02:00
window_invalidate_by_class ( WC_WATER ) ;
}
2015-05-27 18:40:57 +02:00
}
2015-12-11 16:38:37 +01:00
/**
*
* rct2 : 0x006E24F6
2015-05-30 08:04:15 +02:00
* On failure returns MONEY32_UNDEFINED
* On success places ghost scenery and returns cost to place proper
*/
2020-11-15 14:24:14 +01:00
static money32 try_place_ghost_small_scenery (
CoordsXYZD loc , uint8_t quadrant , ObjectEntryIndex entryIndex , colour_t primaryColour , colour_t secondaryColour )
2018-06-22 23:21:44 +02:00
{
2017-06-06 23:24:18 +02:00
scenery_remove_ghost_tool_placement ( ) ;
2020-11-15 14:24:14 +01:00
// 6e252b
auto smallSceneryPlaceAction = SmallSceneryPlaceAction ( loc , quadrant , entryIndex , primaryColour , secondaryColour ) ;
smallSceneryPlaceAction . SetFlags ( GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED ) ;
auto res = GameActions : : Execute ( & smallSceneryPlaceAction ) ;
auto sspar = dynamic_cast < SmallSceneryPlaceActionResult * > ( res . get ( ) ) ;
if ( sspar = = nullptr | | res - > Error ! = GameActions : : Status : : Ok )
return MONEY32_UNDEFINED ;
gSceneryPlaceRotation = loc . direction ;
gSceneryPlaceObject . SceneryType = SCENERY_TYPE_SMALL ;
gSceneryPlaceObject . EntryIndex = entryIndex ;
2017-06-06 23:24:18 +02:00
2020-11-15 14:24:14 +01:00
TileElement * tileElement = sspar - > tileElement ;
gSceneryGhostPosition = { loc , tileElement - > GetBaseZ ( ) } ;
gSceneryQuadrant = tileElement - > AsSmallScenery ( ) - > GetSceneryQuadrant ( ) ;
if ( sspar - > GroundFlags & ELEMENT_IS_UNDERGROUND )
2018-06-22 23:21:44 +02:00
{
2020-11-15 14:24:14 +01:00
// Set underground on
viewport_set_visibility ( 4 ) ;
}
else
{
// Set underground off
viewport_set_visibility ( 5 ) ;
}
2017-06-06 23:24:18 +02:00
2020-11-15 14:24:14 +01:00
gSceneryGhostType | = SCENERY_GHOST_FLAG_0 ;
return res - > Cost ;
}
2019-07-23 18:02:46 +02:00
2020-11-15 14:24:14 +01:00
static money32 try_place_ghost_path_addition ( CoordsXYZ loc , ObjectEntryIndex entryIndex )
{
scenery_remove_ghost_tool_placement ( ) ;
// 6e265b
auto footpathAdditionPlaceAction = FootpathAdditionPlaceAction ( loc , entryIndex + 1 ) ;
footpathAdditionPlaceAction . SetFlags ( GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED ) ;
footpathAdditionPlaceAction . SetCallback ( [ = ] ( const GameAction * ga , const GameActions : : Result * result ) {
if ( result - > Error ! = GameActions : : Status : : Ok )
2019-03-25 20:20:31 +01:00
{
2020-11-15 14:24:14 +01:00
return ;
}
gSceneryGhostPosition = loc ;
gSceneryGhostType | = SCENERY_GHOST_FLAG_1 ;
} ) ;
auto res = GameActions : : Execute ( & footpathAdditionPlaceAction ) ;
if ( res - > Error ! = GameActions : : Status : : Ok )
return MONEY32_UNDEFINED ;
return res - > Cost ;
}
2018-06-22 23:21:44 +02:00
2020-12-02 12:23:38 +01:00
static money32 try_place_ghost_wall (
CoordsXYZ loc , uint8_t edge , ObjectEntryIndex entryIndex , colour_t primaryColour , colour_t secondaryColour ,
colour_t tertiaryColour )
2020-11-15 14:24:14 +01:00
{
scenery_remove_ghost_tool_placement ( ) ;
2018-06-22 23:21:44 +02:00
2020-11-15 14:24:14 +01:00
// 6e26b0
2020-12-02 12:23:38 +01:00
auto wallPlaceAction = WallPlaceAction ( entryIndex , loc , edge , primaryColour , secondaryColour , tertiaryColour ) ;
2020-11-15 14:24:14 +01:00
wallPlaceAction . SetFlags ( GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND ) ;
wallPlaceAction . SetCallback ( [ = ] ( const GameAction * ga , const WallPlaceActionResult * result ) {
if ( result - > Error ! = GameActions : : Status : : Ok )
return ;
2018-06-22 23:21:44 +02:00
2020-11-15 14:24:14 +01:00
gSceneryGhostPosition = { loc , result - > tileElement - > GetBaseZ ( ) } ;
gSceneryGhostWallRotation = edge ;
2018-06-22 23:21:44 +02:00
2020-11-15 14:24:14 +01:00
gSceneryGhostType | = SCENERY_GHOST_FLAG_2 ;
} ) ;
2018-06-22 23:21:44 +02:00
2020-11-15 14:24:14 +01:00
auto res = GameActions : : Execute ( & wallPlaceAction ) ;
if ( res - > Error ! = GameActions : : Status : : Ok )
return MONEY32_UNDEFINED ;
2019-04-19 08:18:55 +02:00
2020-11-15 14:24:14 +01:00
return res - > Cost ;
}
2017-06-06 23:24:18 +02:00
2020-11-15 14:24:14 +01:00
static money32 try_place_ghost_large_scenery (
CoordsXYZD loc , ObjectEntryIndex entryIndex , colour_t primaryColour , colour_t secondaryColour )
{
scenery_remove_ghost_tool_placement ( ) ;
// 6e25a7
auto sceneryPlaceAction = LargeSceneryPlaceAction ( loc , entryIndex , primaryColour , secondaryColour ) ;
sceneryPlaceAction . SetFlags ( GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND ) ;
auto res = GameActions : : Execute ( & sceneryPlaceAction ) ;
auto lspar = dynamic_cast < LargeSceneryPlaceActionResult * > ( res . get ( ) ) ;
if ( lspar = = nullptr | | res - > Error ! = GameActions : : Status : : Ok )
return MONEY32_UNDEFINED ;
gSceneryPlaceRotation = loc . direction ;
TileElement * tileElement = lspar - > tileElement ;
gSceneryGhostPosition = { loc , tileElement - > GetBaseZ ( ) } ;
if ( lspar - > GroundFlags & ELEMENT_IS_UNDERGROUND )
{
// Set underground on
viewport_set_visibility ( 4 ) ;
}
else
{
// Set underground off
viewport_set_visibility ( 5 ) ;
2017-06-06 23:24:18 +02:00
}
2020-11-15 14:24:14 +01:00
gSceneryGhostType | = SCENERY_GHOST_FLAG_3 ;
return res - > Cost ;
}
static money32 try_place_ghost_banner ( CoordsXYZD loc , ObjectEntryIndex entryIndex )
{
scenery_remove_ghost_tool_placement ( ) ;
// 6e2612
auto primaryColour = gWindowSceneryPrimaryColour ;
auto bannerIndex = create_new_banner ( 0 ) ;
if ( bannerIndex = = BANNER_INDEX_NULL )
{
// Silently fail as this is just for the ghost
return 0 ;
}
auto bannerPlaceAction = BannerPlaceAction ( loc , entryIndex , bannerIndex , primaryColour ) ;
bannerPlaceAction . SetFlags ( GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND ) ;
auto res = GameActions : : Execute ( & bannerPlaceAction ) ;
if ( res - > Error ! = GameActions : : Status : : Ok )
return MONEY32_UNDEFINED ;
gSceneryGhostPosition = loc ;
gSceneryGhostPosition . z + = PATH_HEIGHT_STEP ;
gSceneryPlaceRotation = loc . direction ;
gSceneryGhostType | = SCENERY_GHOST_FLAG_4 ;
return res - > Cost ;
2015-05-28 23:07:39 +02:00
}
2015-05-28 20:33:09 +02:00
/**
2018-06-22 23:21:44 +02:00
*
* rct2 : 0x006E287B
*/
2020-05-01 17:52:07 +02:00
static void top_toolbar_tool_update_scenery ( const ScreenCoordsXY & screenPos )
2018-06-22 23:21:44 +02:00
{
2017-06-06 23:24:18 +02:00
map_invalidate_selection_rect ( ) ;
map_invalidate_map_selection_tiles ( ) ;
2018-01-10 15:05:05 +01:00
2020-08-28 02:06:39 +02:00
if ( gConfigGeneral . virtual_floor_style ! = VirtualFloorStyles : : Off )
2018-01-10 15:05:05 +01:00
{
2018-03-04 17:44:42 +01:00
virtual_floor_invalidate ( ) ;
2018-01-10 15:05:05 +01:00
}
2017-06-06 23:24:18 +02:00
gMapSelectFlags & = ~ MAP_SELECT_FLAG_ENABLE ;
gMapSelectFlags & = ~ MAP_SELECT_FLAG_ENABLE_CONSTRUCT ;
if ( gWindowSceneryPaintEnabled )
return ;
if ( gWindowSceneryEyedropperEnabled )
return ;
2020-03-18 16:22:08 +01:00
ScenerySelection selection = gWindowSceneryTabSelections [ gWindowSceneryActiveTabIndex ] ;
2017-06-06 23:24:18 +02:00
2020-03-18 16:22:08 +01:00
if ( selection . IsUndefined ( ) )
2018-06-22 23:21:44 +02:00
{
2017-06-06 23:24:18 +02:00
scenery_remove_ghost_tool_placement ( ) ;
return ;
}
money32 cost = 0 ;
2020-11-15 14:24:14 +01:00
switch ( selection . SceneryType )
2018-06-22 23:21:44 +02:00
{
case SCENERY_TYPE_SMALL :
2020-11-15 14:24:14 +01:00
{
CoordsXY mapTile = { } ;
uint8_t quadrant ;
Direction rotation ;
2020-12-02 12:23:38 +01:00
sub_6E1F34_small_scenery ( screenPos , selection . EntryIndex , mapTile , & quadrant , & rotation ) ;
2020-11-15 14:24:14 +01:00
if ( mapTile . isNull ( ) )
{
scenery_remove_ghost_tool_placement ( ) ;
return ;
}
2018-06-22 23:21:44 +02:00
gMapSelectFlags | = MAP_SELECT_FLAG_ENABLE ;
2019-12-12 16:42:19 +01:00
if ( gWindowSceneryScatterEnabled )
2018-06-22 23:21:44 +02:00
{
2020-02-20 14:49:27 +01:00
uint16_t cluster_size = ( gWindowSceneryScatterSize - 1 ) * COORDS_XY_STEP ;
gMapSelectPositionA . x = mapTile . x - cluster_size / 2 ;
gMapSelectPositionA . y = mapTile . y - cluster_size / 2 ;
gMapSelectPositionB . x = mapTile . x + cluster_size / 2 ;
gMapSelectPositionB . y = mapTile . y + cluster_size / 2 ;
if ( gWindowSceneryScatterSize % 2 = = 0 )
2019-12-12 16:42:19 +01:00
{
2020-02-20 14:49:27 +01:00
gMapSelectPositionB . x + = COORDS_XY_STEP ;
gMapSelectPositionB . y + = COORDS_XY_STEP ;
2019-12-12 16:42:19 +01:00
}
2018-06-22 23:21:44 +02:00
}
else
{
gMapSelectPositionA . x = mapTile . x ;
gMapSelectPositionA . y = mapTile . y ;
gMapSelectPositionB . x = mapTile . x ;
gMapSelectPositionB . y = mapTile . y ;
}
2017-06-06 23:24:18 +02:00
2020-11-15 14:24:14 +01:00
rct_scenery_entry * scenery = get_small_scenery_entry ( selection . EntryIndex ) ;
2017-06-06 23:24:18 +02:00
2018-06-22 23:21:44 +02:00
gMapSelectType = MAP_SELECT_TYPE_FULL ;
2019-12-12 16:42:19 +01:00
if ( ! scenery_small_entry_has_flag ( scenery , SMALL_SCENERY_FLAG_FULL_TILE ) & & ! gWindowSceneryScatterEnabled )
2018-06-22 23:21:44 +02:00
{
2020-11-15 14:24:14 +01:00
gMapSelectType = MAP_SELECT_TYPE_QUARTER_0 + ( quadrant ^ 2 ) ;
2018-06-22 23:21:44 +02:00
}
2017-06-06 23:24:18 +02:00
2018-06-22 23:21:44 +02:00
map_invalidate_selection_rect ( ) ;
2017-06-06 23:24:18 +02:00
2018-06-22 23:21:44 +02:00
// If no change in ghost placement
2020-11-15 14:24:14 +01:00
if ( ( gSceneryGhostType & SCENERY_GHOST_FLAG_0 ) & & mapTile = = gSceneryGhostPosition & & quadrant = = _unkF64F0E
& & gSceneryPlaceZ = = _unkF64F0A & & gSceneryPlaceObject . SceneryType = = SCENERY_TYPE_SMALL
& & gSceneryPlaceObject . EntryIndex = = selection . EntryIndex )
2018-06-22 23:21:44 +02:00
{
return ;
}
2017-06-06 23:24:18 +02:00
2018-06-22 23:21:44 +02:00
scenery_remove_ghost_tool_placement ( ) ;
2017-06-06 23:24:18 +02:00
2020-11-15 14:24:14 +01:00
_unkF64F0E = quadrant ;
2018-06-22 23:21:44 +02:00
_unkF64F0A = gSceneryPlaceZ ;
2017-06-06 23:24:18 +02:00
2020-11-15 14:24:14 +01:00
uint8_t attemptsLeft = 1 ;
2018-06-22 23:21:44 +02:00
if ( gSceneryPlaceZ ! = 0 & & gSceneryShiftPressed )
{
2020-11-15 14:24:14 +01:00
attemptsLeft = 20 ;
2018-06-22 23:21:44 +02:00
}
2017-06-06 23:24:18 +02:00
2020-11-15 14:24:14 +01:00
for ( ; attemptsLeft ! = 0 ; attemptsLeft - - )
2018-06-22 23:21:44 +02:00
{
2020-11-15 14:24:14 +01:00
cost = try_place_ghost_small_scenery (
2020-12-02 12:23:38 +01:00
{ mapTile , gSceneryPlaceZ , rotation } , quadrant , selection . EntryIndex , gWindowSceneryPrimaryColour ,
gWindowScenerySecondaryColour ) ;
2017-06-06 23:24:18 +02:00
2018-06-22 23:21:44 +02:00
if ( cost ! = MONEY32_UNDEFINED )
break ;
gSceneryPlaceZ + = 8 ;
}
2017-06-06 23:24:18 +02:00
2018-06-22 23:21:44 +02:00
gSceneryPlaceCost = cost ;
break ;
2020-11-15 14:24:14 +01:00
}
2018-06-22 23:21:44 +02:00
case SCENERY_TYPE_PATH_ITEM :
2020-11-15 14:24:14 +01:00
{
CoordsXY mapTile = { } ;
int32_t z ;
sub_6E1F34_path_item ( screenPos , selection . EntryIndex , mapTile , & z ) ;
if ( mapTile . isNull ( ) )
{
scenery_remove_ghost_tool_placement ( ) ;
return ;
}
2018-06-22 23:21:44 +02:00
gMapSelectFlags | = MAP_SELECT_FLAG_ENABLE ;
gMapSelectPositionA . x = mapTile . x ;
gMapSelectPositionA . y = mapTile . y ;
gMapSelectPositionB . x = mapTile . x ;
gMapSelectPositionB . y = mapTile . y ;
gMapSelectType = MAP_SELECT_TYPE_FULL ;
2017-06-06 23:24:18 +02:00
2018-06-22 23:21:44 +02:00
map_invalidate_selection_rect ( ) ;
2017-06-06 23:24:18 +02:00
2018-06-22 23:21:44 +02:00
// If no change in ghost placement
2020-11-15 14:24:14 +01:00
if ( ( gSceneryGhostType & SCENERY_GHOST_FLAG_1 ) & & mapTile = = gSceneryGhostPosition & & z = = gSceneryGhostPosition . z )
2018-06-22 23:21:44 +02:00
{
return ;
}
2017-06-06 23:24:18 +02:00
2018-06-22 23:21:44 +02:00
scenery_remove_ghost_tool_placement ( ) ;
2017-06-06 23:24:18 +02:00
2020-11-15 14:24:14 +01:00
cost = try_place_ghost_path_addition ( { mapTile , z } , selection . EntryIndex ) ;
2017-06-06 23:24:18 +02:00
2018-06-22 23:21:44 +02:00
gSceneryPlaceCost = cost ;
break ;
2020-11-15 14:24:14 +01:00
}
2018-06-22 23:21:44 +02:00
case SCENERY_TYPE_WALL :
2020-11-15 14:24:14 +01:00
{
CoordsXY mapTile = { } ;
uint8_t edge ;
2020-12-02 12:23:38 +01:00
sub_6E1F34_wall ( screenPos , selection . EntryIndex , mapTile , & edge ) ;
2020-11-15 14:24:14 +01:00
if ( mapTile . isNull ( ) )
{
scenery_remove_ghost_tool_placement ( ) ;
return ;
}
2018-06-22 23:21:44 +02:00
gMapSelectFlags | = MAP_SELECT_FLAG_ENABLE ;
gMapSelectPositionA . x = mapTile . x ;
gMapSelectPositionA . y = mapTile . y ;
gMapSelectPositionB . x = mapTile . x ;
gMapSelectPositionB . y = mapTile . y ;
2020-11-15 14:24:14 +01:00
gMapSelectType = MAP_SELECT_TYPE_EDGE_0 + edge ;
2017-06-06 23:24:18 +02:00
2018-06-22 23:21:44 +02:00
map_invalidate_selection_rect ( ) ;
2017-06-06 23:24:18 +02:00
2018-06-22 23:21:44 +02:00
// If no change in ghost placement
2020-02-18 22:42:38 +01:00
if ( ( gSceneryGhostType & SCENERY_GHOST_FLAG_2 ) & & mapTile = = gSceneryGhostPosition
2020-11-15 14:24:14 +01:00
& & edge = = gSceneryGhostWallRotation & & gSceneryPlaceZ = = _unkF64F0A )
2018-06-22 23:21:44 +02:00
{
return ;
}
scenery_remove_ghost_tool_placement ( ) ;
2020-11-15 14:24:14 +01:00
gSceneryGhostWallRotation = edge ;
2018-06-22 23:21:44 +02:00
_unkF64F0A = gSceneryPlaceZ ;
2020-11-15 14:24:14 +01:00
uint8_t attemptsLeft = 1 ;
2018-06-22 23:21:44 +02:00
if ( gSceneryPlaceZ ! = 0 & & gSceneryShiftPressed )
{
2020-11-15 14:24:14 +01:00
attemptsLeft = 20 ;
2018-06-22 23:21:44 +02:00
}
2017-06-06 23:24:18 +02:00
2018-06-22 23:21:44 +02:00
cost = 0 ;
2020-11-15 14:24:14 +01:00
for ( ; attemptsLeft ! = 0 ; attemptsLeft - - )
2018-06-22 23:21:44 +02:00
{
2020-12-02 12:23:38 +01:00
cost = try_place_ghost_wall (
{ mapTile , gSceneryPlaceZ } , edge , selection . EntryIndex , gWindowSceneryPrimaryColour ,
gWindowScenerySecondaryColour , gWindowSceneryTertiaryColour ) ;
2017-06-06 23:24:18 +02:00
2018-06-22 23:21:44 +02:00
if ( cost ! = MONEY32_UNDEFINED )
break ;
gSceneryPlaceZ + = 8 ;
}
2017-06-06 23:24:18 +02:00
2018-06-22 23:21:44 +02:00
gSceneryPlaceCost = cost ;
break ;
2020-11-15 14:24:14 +01:00
}
2018-06-22 23:21:44 +02:00
case SCENERY_TYPE_LARGE :
{
2020-11-15 14:24:14 +01:00
CoordsXY mapTile = { } ;
Direction direction ;
2020-12-02 12:23:38 +01:00
sub_6E1F34_large_scenery ( screenPos , selection . EntryIndex , mapTile , & direction ) ;
2020-11-15 14:24:14 +01:00
if ( mapTile . isNull ( ) )
{
scenery_remove_ghost_tool_placement ( ) ;
return ;
}
rct_scenery_entry * scenery = get_large_scenery_entry ( selection . EntryIndex ) ;
2019-03-28 19:29:51 +01:00
gMapSelectionTiles . clear ( ) ;
2017-06-06 23:24:18 +02:00
2020-04-18 13:32:48 +02:00
for ( rct_large_scenery_tile * tile = scenery - > large_scenery . tiles ;
tile - > x_offset ! = static_cast < int16_t > ( static_cast < uint16_t > ( 0xFFFF ) ) ; tile + + )
2018-06-22 23:21:44 +02:00
{
2019-12-04 12:39:33 +01:00
CoordsXY tileLocation = { tile - > x_offset , tile - > y_offset } ;
2020-11-15 14:24:14 +01:00
auto rotatedTileCoords = tileLocation . Rotate ( direction ) ;
2017-06-06 23:24:18 +02:00
2019-12-04 12:39:33 +01:00
rotatedTileCoords . x + = mapTile . x ;
rotatedTileCoords . y + = mapTile . y ;
2017-06-06 23:24:18 +02:00
2019-12-04 12:39:33 +01:00
gMapSelectionTiles . push_back ( rotatedTileCoords ) ;
2018-06-22 23:21:44 +02:00
}
2017-06-06 23:24:18 +02:00
2018-06-22 23:21:44 +02:00
gMapSelectFlags | = MAP_SELECT_FLAG_ENABLE_CONSTRUCT ;
map_invalidate_map_selection_tiles ( ) ;
2017-06-06 23:24:18 +02:00
2018-06-22 23:21:44 +02:00
// If no change in ghost placement
2020-02-18 22:42:38 +01:00
if ( ( gSceneryGhostType & SCENERY_GHOST_FLAG_3 ) & & mapTile = = gSceneryGhostPosition & & gSceneryPlaceZ = = _unkF64F0A
2020-11-15 14:24:14 +01:00
& & gSceneryPlaceObject . SceneryType = = SCENERY_TYPE_LARGE
& & gSceneryPlaceObject . EntryIndex = = selection . EntryIndex )
2018-06-22 23:21:44 +02:00
{
return ;
}
2017-06-06 23:24:18 +02:00
2018-06-22 23:21:44 +02:00
scenery_remove_ghost_tool_placement ( ) ;
2017-06-06 23:24:18 +02:00
2020-03-13 14:44:34 +01:00
gSceneryPlaceObject . SceneryType = SCENERY_TYPE_LARGE ;
2020-11-15 14:24:14 +01:00
gSceneryPlaceObject . EntryIndex = selection . EntryIndex ;
2018-06-22 23:21:44 +02:00
_unkF64F0A = gSceneryPlaceZ ;
2017-06-06 23:24:18 +02:00
2020-11-15 14:24:14 +01:00
uint8_t attemptsLeft = 1 ;
2018-06-22 23:21:44 +02:00
if ( gSceneryPlaceZ ! = 0 & & gSceneryShiftPressed )
{
2020-11-15 14:24:14 +01:00
attemptsLeft = 20 ;
2018-06-22 23:21:44 +02:00
}
2017-06-06 23:24:18 +02:00
2018-06-22 23:21:44 +02:00
cost = 0 ;
2020-11-15 14:24:14 +01:00
for ( ; attemptsLeft ! = 0 ; attemptsLeft - - )
2018-06-22 23:21:44 +02:00
{
2020-11-15 14:24:14 +01:00
cost = try_place_ghost_large_scenery (
2020-12-02 12:23:38 +01:00
{ mapTile , gSceneryPlaceZ , direction } , selection . EntryIndex , gWindowSceneryPrimaryColour ,
gWindowScenerySecondaryColour ) ;
2017-06-06 23:24:18 +02:00
2018-06-22 23:21:44 +02:00
if ( cost ! = MONEY32_UNDEFINED )
break ;
2020-11-15 14:24:14 +01:00
gSceneryPlaceZ + = COORDS_Z_STEP ;
2018-06-22 23:21:44 +02:00
}
2017-06-06 23:24:18 +02:00
2018-06-22 23:21:44 +02:00
gSceneryPlaceCost = cost ;
break ;
2017-06-06 23:24:18 +02:00
}
2018-06-22 23:21:44 +02:00
case SCENERY_TYPE_BANNER :
2020-11-15 14:24:14 +01:00
{
CoordsXY mapTile = { } ;
Direction direction ;
int32_t z ;
sub_6E1F34_banner ( screenPos , selection . EntryIndex , mapTile , & z , & direction ) ;
if ( mapTile . isNull ( ) )
{
scenery_remove_ghost_tool_placement ( ) ;
return ;
}
2018-06-22 23:21:44 +02:00
gMapSelectFlags | = MAP_SELECT_FLAG_ENABLE ;
gMapSelectPositionA . x = mapTile . x ;
gMapSelectPositionA . y = mapTile . y ;
gMapSelectPositionB . x = mapTile . x ;
gMapSelectPositionB . y = mapTile . y ;
gMapSelectType = MAP_SELECT_TYPE_FULL ;
2017-06-06 23:24:18 +02:00
2018-06-22 23:21:44 +02:00
map_invalidate_selection_rect ( ) ;
2017-06-06 23:24:18 +02:00
2018-06-22 23:21:44 +02:00
// If no change in ghost placement
2020-11-15 14:24:14 +01:00
if ( ( gSceneryGhostType & SCENERY_GHOST_FLAG_4 ) & & mapTile = = gSceneryGhostPosition & & z = = gSceneryGhostPosition . z
& & direction = = gSceneryPlaceRotation )
2018-06-22 23:21:44 +02:00
{
return ;
}
2017-06-06 23:24:18 +02:00
2018-06-22 23:21:44 +02:00
scenery_remove_ghost_tool_placement ( ) ;
2017-06-06 23:24:18 +02:00
2020-11-15 14:24:14 +01:00
cost = try_place_ghost_banner ( { mapTile , z , direction } , selection . EntryIndex ) ;
2017-06-06 23:24:18 +02:00
2018-06-22 23:21:44 +02:00
gSceneryPlaceCost = cost ;
break ;
2020-11-15 14:24:14 +01:00
}
2017-06-06 23:24:18 +02:00
}
2015-05-28 20:33:09 +02:00
}
2014-11-04 04:34:12 +01:00
/**
*
* rct2 : 0x0066CB25
*/
2020-02-29 03:43:29 +01:00
static void window_top_toolbar_tool_update ( rct_window * w , rct_widgetindex widgetIndex , const ScreenCoordsXY & screenCoords )
2014-11-04 04:34:12 +01:00
{
2018-06-22 23:21:44 +02:00
switch ( widgetIndex )
{
case WIDX_CLEAR_SCENERY :
2020-05-01 17:52:07 +02:00
top_toolbar_tool_update_scenery_clear ( screenCoords ) ;
2018-06-22 23:21:44 +02:00
break ;
case WIDX_LAND :
if ( gLandPaintMode )
2020-05-01 17:52:07 +02:00
top_toolbar_tool_update_land_paint ( screenCoords ) ;
2018-06-22 23:21:44 +02:00
else
2020-05-01 17:52:07 +02:00
top_toolbar_tool_update_land ( screenCoords ) ;
2018-06-22 23:21:44 +02:00
break ;
case WIDX_WATER :
2020-05-01 17:52:07 +02:00
top_toolbar_tool_update_water ( screenCoords ) ;
2018-06-22 23:21:44 +02:00
break ;
case WIDX_SCENERY :
2020-05-01 17:52:07 +02:00
top_toolbar_tool_update_scenery ( screenCoords ) ;
2018-06-22 23:21:44 +02:00
break ;
2020-05-01 22:32:41 +02:00
# ifdef ENABLE_SCRIPTING
default :
auto & customTool = OpenRCT2 : : Scripting : : ActiveCustomTool ;
if ( customTool )
{
customTool - > OnUpdate ( screenCoords ) ;
}
break ;
# endif
2017-06-06 23:24:18 +02:00
}
2014-11-04 04:34:12 +01:00
}
2014-10-21 18:59:47 +02:00
/**
2015-12-11 16:38:37 +01:00
*
* rct2 : 0x0066CB73
2014-10-21 18:59:47 +02:00
*/
2020-02-29 03:43:29 +01:00
static void window_top_toolbar_tool_down ( rct_window * w , rct_widgetindex widgetIndex , const ScreenCoordsXY & screenCoords )
2015-07-10 02:39:16 +02:00
{
2018-06-22 23:21:44 +02:00
switch ( widgetIndex )
{
case WIDX_CLEAR_SCENERY :
2019-01-02 12:59:37 +01:00
if ( gMapSelectFlags & MAP_SELECT_FLAG_ENABLE )
{
auto action = GetClearAction ( ) ;
GameActions : : Execute ( & action ) ;
gCurrentToolId = TOOL_CROSSHAIR ;
}
2018-06-22 23:21:44 +02:00
break ;
case WIDX_LAND :
if ( gMapSelectFlags & MAP_SELECT_FLAG_ENABLE )
{
2019-03-10 10:15:22 +01:00
auto surfaceSetStyleAction = SurfaceSetStyleAction (
{ gMapSelectPositionA . x , gMapSelectPositionA . y , gMapSelectPositionB . x , gMapSelectPositionB . y } ,
gLandToolTerrainSurface , gLandToolTerrainEdge ) ;
GameActions : : Execute ( & surfaceSetStyleAction ) ;
2018-06-22 23:21:44 +02:00
gCurrentToolId = TOOL_UP_DOWN_ARROW ;
}
2020-04-18 00:34:32 +02:00
else
{
_landToolBlocked = true ;
}
2018-06-22 23:21:44 +02:00
break ;
case WIDX_WATER :
if ( gMapSelectFlags & MAP_SELECT_FLAG_ENABLE )
{
gCurrentToolId = TOOL_UP_DOWN_ARROW ;
}
2020-04-18 00:34:32 +02:00
else
{
_landToolBlocked = true ;
}
2018-06-22 23:21:44 +02:00
break ;
case WIDX_SCENERY :
2020-05-01 17:52:07 +02:00
window_top_toolbar_scenery_tool_down ( screenCoords , w , widgetIndex ) ;
2018-06-22 23:21:44 +02:00
break ;
2020-05-01 22:32:41 +02:00
# ifdef ENABLE_SCRIPTING
default :
auto & customTool = OpenRCT2 : : Scripting : : ActiveCustomTool ;
if ( customTool )
{
customTool - > OnDown ( screenCoords ) ;
}
break ;
# endif
2017-06-06 23:24:18 +02:00
}
2014-11-04 04:34:12 +01:00
}
2015-02-19 17:33:26 +01:00
/**
2018-06-22 23:21:44 +02:00
*
* rct2 : 0x006644DD
*/
2018-06-20 17:28:51 +02:00
static money32 selection_raise_land ( uint8_t flags )
2015-06-10 16:41:50 +02:00
{
2018-06-20 17:28:51 +02:00
int32_t centreX = ( gMapSelectPositionA . x + gMapSelectPositionB . x ) / 2 ;
int32_t centreY = ( gMapSelectPositionA . y + gMapSelectPositionB . y ) / 2 ;
2017-06-06 23:24:18 +02:00
centreX + = 16 ;
centreY + = 16 ;
2018-06-22 23:21:44 +02:00
if ( gLandMountainMode )
{
2019-03-16 23:04:58 +01:00
auto landSmoothAction = LandSmoothAction (
{ centreX , centreY } ,
{ gMapSelectPositionA . x , gMapSelectPositionA . y , gMapSelectPositionB . x , gMapSelectPositionB . y } , gMapSelectType ,
false ) ;
auto res = ( flags & GAME_COMMAND_FLAG_APPLY ) ? GameActions : : Execute ( & landSmoothAction )
: GameActions : : Query ( & landSmoothAction ) ;
2020-10-15 03:04:39 +02:00
return res - > Error = = GameActions : : Status : : Ok ? res - > Cost : MONEY32_UNDEFINED ;
2018-06-22 23:21:44 +02:00
}
else
{
2019-03-04 17:57:01 +01:00
auto landRaiseAction = LandRaiseAction (
{ centreX , centreY } ,
{ gMapSelectPositionA . x , gMapSelectPositionA . y , gMapSelectPositionB . x , gMapSelectPositionB . y } , gMapSelectType ) ;
auto res = ( flags & GAME_COMMAND_FLAG_APPLY ) ? GameActions : : Execute ( & landRaiseAction )
: GameActions : : Query ( & landRaiseAction ) ;
2020-10-15 03:04:39 +02:00
return res - > Error = = GameActions : : Status : : Ok ? res - > Cost : MONEY32_UNDEFINED ;
2017-06-06 23:24:18 +02:00
}
2015-02-19 17:33:26 +01:00
}
/**
2018-06-22 23:21:44 +02:00
*
* rct2 : 0x006645B3
*/
2018-06-20 17:28:51 +02:00
static money32 selection_lower_land ( uint8_t flags )
2015-06-10 16:41:50 +02:00
{
2018-06-20 17:28:51 +02:00
int32_t centreX = ( gMapSelectPositionA . x + gMapSelectPositionB . x ) / 2 ;
int32_t centreY = ( gMapSelectPositionA . y + gMapSelectPositionB . y ) / 2 ;
2017-06-06 23:24:18 +02:00
centreX + = 16 ;
centreY + = 16 ;
2018-06-22 23:21:44 +02:00
if ( gLandMountainMode )
{
2019-03-16 23:04:58 +01:00
auto landSmoothAction = LandSmoothAction (
{ centreX , centreY } ,
{ gMapSelectPositionA . x , gMapSelectPositionA . y , gMapSelectPositionB . x , gMapSelectPositionB . y } , gMapSelectType ,
true ) ;
auto res = ( flags & GAME_COMMAND_FLAG_APPLY ) ? GameActions : : Execute ( & landSmoothAction )
: GameActions : : Query ( & landSmoothAction ) ;
2020-10-15 03:04:39 +02:00
return res - > Error = = GameActions : : Status : : Ok ? res - > Cost : MONEY32_UNDEFINED ;
2018-06-22 23:21:44 +02:00
}
else
{
2019-03-04 17:57:01 +01:00
auto landLowerAction = LandLowerAction (
{ centreX , centreY } ,
{ gMapSelectPositionA . x , gMapSelectPositionA . y , gMapSelectPositionB . x , gMapSelectPositionB . y } , gMapSelectType ) ;
auto res = ( flags & GAME_COMMAND_FLAG_APPLY ) ? GameActions : : Execute ( & landLowerAction )
: GameActions : : Query ( & landLowerAction ) ;
2020-10-15 03:04:39 +02:00
return res - > Error = = GameActions : : Status : : Ok ? res - > Cost : MONEY32_UNDEFINED ;
2017-06-06 23:24:18 +02:00
}
2015-02-19 17:33:26 +01:00
}
/**
2018-06-22 23:21:44 +02:00
* part of window_top_toolbar_tool_drag ( 0x0066CB4E )
* rct2 : 0x00664454
*/
2020-05-01 17:52:07 +02:00
static void window_top_toolbar_land_tool_drag ( const ScreenCoordsXY & screenPos )
2015-02-19 17:33:26 +01:00
{
2020-05-01 17:52:07 +02:00
rct_window * window = window_find_from_point ( screenPos ) ;
2017-06-06 23:24:18 +02:00
if ( ! window )
return ;
2020-05-01 17:52:07 +02:00
rct_widgetindex widget_index = window_find_widget_from_point ( window , screenPos ) ;
2017-06-06 23:24:18 +02:00
if ( widget_index = = - 1 )
return ;
2018-06-22 23:21:44 +02:00
rct_widget * widget = & window - > widgets [ widget_index ] ;
2020-11-27 04:14:20 +01:00
if ( widget - > type ! = WindowWidgetType : : Viewport )
2017-06-06 23:24:18 +02:00
return ;
2018-06-22 23:21:44 +02:00
rct_viewport * viewport = window - > viewport ;
2017-06-06 23:24:18 +02:00
if ( ! viewport )
return ;
2020-02-20 01:18:05 +01:00
int16_t tile_height = - 16 / viewport - > zoom ;
2017-06-06 23:24:18 +02:00
2020-05-01 17:52:07 +02:00
int32_t y_diff = screenPos . y - gInputDragLast . y ;
2017-09-23 23:41:32 +02:00
2018-06-22 23:21:44 +02:00
if ( y_diff < = tile_height )
{
2019-12-17 18:38:20 +01:00
gInputDragLast . y + = tile_height ;
2017-06-06 23:24:18 +02:00
selection_raise_land ( GAME_COMMAND_FLAG_APPLY ) ;
gLandToolRaiseCost = MONEY32_UNDEFINED ;
gLandToolLowerCost = MONEY32_UNDEFINED ;
2018-06-22 23:21:44 +02:00
}
else if ( y_diff > = - tile_height )
{
2019-12-17 18:38:20 +01:00
gInputDragLast . y - = tile_height ;
2017-06-06 23:24:18 +02:00
selection_lower_land ( GAME_COMMAND_FLAG_APPLY ) ;
gLandToolRaiseCost = MONEY32_UNDEFINED ;
gLandToolLowerCost = MONEY32_UNDEFINED ;
}
2015-02-19 17:33:26 +01:00
}
2015-02-18 20:26:16 +01:00
/**
2018-06-22 23:21:44 +02:00
* part of window_top_toolbar_tool_drag ( 0x0066CB4E )
* rct2 : 0x006E6D4B
*/
2020-05-01 17:52:07 +02:00
static void window_top_toolbar_water_tool_drag ( const ScreenCoordsXY & screenPos )
2015-02-18 20:26:16 +01:00
{
2020-05-01 17:52:07 +02:00
rct_window * window = window_find_from_point ( screenPos ) ;
2017-06-06 23:24:18 +02:00
if ( ! window )
return ;
2020-05-01 17:52:07 +02:00
rct_widgetindex widget_index = window_find_widget_from_point ( window , screenPos ) ;
2017-06-06 23:24:18 +02:00
if ( widget_index = = - 1 )
return ;
2018-06-22 23:21:44 +02:00
rct_widget * widget = & window - > widgets [ widget_index ] ;
2020-11-27 04:14:20 +01:00
if ( widget - > type ! = WindowWidgetType : : Viewport )
2017-06-06 23:24:18 +02:00
return ;
2018-06-22 23:21:44 +02:00
rct_viewport * viewport = window - > viewport ;
2017-06-06 23:24:18 +02:00
if ( ! viewport )
return ;
2020-02-20 01:18:05 +01:00
int16_t dx = - 16 / viewport - > zoom ;
2017-06-06 23:24:18 +02:00
2020-05-01 17:52:07 +02:00
auto offsetPos = screenPos - ScreenCoordsXY { 0 , gInputDragLast . y } ;
2017-06-06 23:24:18 +02:00
2020-05-01 17:52:07 +02:00
if ( offsetPos . y < = dx )
2018-06-22 23:21:44 +02:00
{
2019-12-17 18:38:20 +01:00
gInputDragLast . y + = dx ;
2017-06-06 23:24:18 +02:00
2019-03-04 17:57:01 +01:00
auto waterRaiseAction = WaterRaiseAction (
{ gMapSelectPositionA . x , gMapSelectPositionA . y , gMapSelectPositionB . x , gMapSelectPositionB . y } ) ;
GameActions : : Execute ( & waterRaiseAction ) ;
2017-06-06 23:24:18 +02:00
gWaterToolRaiseCost = MONEY32_UNDEFINED ;
gWaterToolLowerCost = MONEY32_UNDEFINED ;
return ;
}
dx = - dx ;
2020-05-01 17:52:07 +02:00
if ( offsetPos . y > = dx )
2018-06-22 23:21:44 +02:00
{
2019-12-17 18:38:20 +01:00
gInputDragLast . y + = dx ;
2017-06-06 23:24:18 +02:00
2019-03-04 17:57:01 +01:00
auto waterLowerAction = WaterLowerAction (
{ gMapSelectPositionA . x , gMapSelectPositionA . y , gMapSelectPositionB . x , gMapSelectPositionB . y } ) ;
GameActions : : Execute ( & waterLowerAction ) ;
2017-06-06 23:24:18 +02:00
gWaterToolRaiseCost = MONEY32_UNDEFINED ;
gWaterToolLowerCost = MONEY32_UNDEFINED ;
return ;
}
2015-02-18 20:26:16 +01:00
}
2014-11-04 04:34:12 +01:00
/**
*
* rct2 : 0x0066CB4E
*/
2020-02-29 03:43:29 +01:00
static void window_top_toolbar_tool_drag ( rct_window * w , rct_widgetindex widgetIndex , const ScreenCoordsXY & screenCoords )
2014-11-04 04:34:12 +01:00
{
2018-06-22 23:21:44 +02:00
switch ( widgetIndex )
{
case WIDX_CLEAR_SCENERY :
2019-01-02 12:59:37 +01:00
if ( window_find_by_class ( WC_ERROR ) = = nullptr & & ( gMapSelectFlags & MAP_SELECT_FLAG_ENABLE ) )
{
auto action = GetClearAction ( ) ;
GameActions : : Execute ( & action ) ;
gCurrentToolId = TOOL_CROSSHAIR ;
}
2018-06-22 23:21:44 +02:00
break ;
case WIDX_LAND :
// Custom setting to only change land style instead of raising or lowering land
if ( gLandPaintMode )
{
if ( gMapSelectFlags & MAP_SELECT_FLAG_ENABLE )
{
2019-03-10 10:15:22 +01:00
auto surfaceSetStyleAction = SurfaceSetStyleAction (
{ gMapSelectPositionA . x , gMapSelectPositionA . y , gMapSelectPositionB . x , gMapSelectPositionB . y } ,
gLandToolTerrainSurface , gLandToolTerrainEdge ) ;
GameActions : : Execute ( & surfaceSetStyleAction ) ;
2019-02-21 10:34:30 +01:00
// The tool is set to 12 here instead of 3 so that the dragging cursor is not the elevation change
// cursor
2018-06-22 23:21:44 +02:00
gCurrentToolId = TOOL_CROSSHAIR ;
}
2017-06-06 23:24:18 +02:00
}
2018-06-22 23:21:44 +02:00
else
{
2020-04-18 00:34:32 +02:00
if ( ! _landToolBlocked )
{
2020-05-01 17:52:07 +02:00
window_top_toolbar_land_tool_drag ( screenCoords ) ;
2020-04-18 00:34:32 +02:00
}
2018-06-22 23:21:44 +02:00
}
break ;
case WIDX_WATER :
2020-04-18 00:34:32 +02:00
if ( ! _landToolBlocked )
{
2020-05-01 17:52:07 +02:00
window_top_toolbar_water_tool_drag ( screenCoords ) ;
2020-04-18 00:34:32 +02:00
}
2018-06-22 23:21:44 +02:00
break ;
case WIDX_SCENERY :
if ( gWindowSceneryPaintEnabled & 1 )
2020-05-01 17:52:07 +02:00
window_top_toolbar_scenery_tool_down ( screenCoords , w , widgetIndex ) ;
2018-06-22 23:21:44 +02:00
if ( gWindowSceneryEyedropperEnabled )
2020-05-01 17:52:07 +02:00
window_top_toolbar_scenery_tool_down ( screenCoords , w , widgetIndex ) ;
2018-06-22 23:21:44 +02:00
break ;
2020-05-01 22:32:41 +02:00
# ifdef ENABLE_SCRIPTING
default :
auto & customTool = OpenRCT2 : : Scripting : : ActiveCustomTool ;
if ( customTool )
{
customTool - > OnDrag ( screenCoords ) ;
}
break ;
# endif
2017-06-06 23:24:18 +02:00
}
2015-02-10 15:41:35 +01:00
}
2015-06-26 17:40:37 +02:00
/**
2015-10-20 20:16:30 +02:00
*
2015-06-26 17:40:37 +02:00
* rct2 : 0x0066CC5B
*/
2020-02-29 03:43:29 +01:00
static void window_top_toolbar_tool_up ( rct_window * w , rct_widgetindex widgetIndex , const ScreenCoordsXY & screenCoords )
2015-10-20 20:16:30 +02:00
{
2020-04-18 00:34:32 +02:00
_landToolBlocked = false ;
2018-06-22 23:21:44 +02:00
switch ( widgetIndex )
{
case WIDX_LAND :
map_invalidate_selection_rect ( ) ;
gMapSelectFlags & = ~ MAP_SELECT_FLAG_ENABLE ;
gCurrentToolId = TOOL_DIG_DOWN ;
break ;
case WIDX_WATER :
map_invalidate_selection_rect ( ) ;
gMapSelectFlags & = ~ MAP_SELECT_FLAG_ENABLE ;
gCurrentToolId = TOOL_WATER_DOWN ;
break ;
case WIDX_CLEAR_SCENERY :
map_invalidate_selection_rect ( ) ;
gMapSelectFlags & = ~ MAP_SELECT_FLAG_ENABLE ;
gCurrentToolId = TOOL_CROSSHAIR ;
break ;
2020-05-01 22:32:41 +02:00
# ifdef ENABLE_SCRIPTING
default :
auto & customTool = OpenRCT2 : : Scripting : : ActiveCustomTool ;
if ( customTool )
{
customTool - > OnUp ( screenCoords ) ;
}
break ;
# endif
2017-06-06 23:24:18 +02:00
}
2015-06-26 17:40:37 +02:00
}
/**
2015-10-20 20:16:30 +02:00
*
2015-06-26 17:40:37 +02:00
* rct2 : 0x0066CA58
*/
2018-06-22 23:21:44 +02:00
static void window_top_toolbar_tool_abort ( rct_window * w , rct_widgetindex widgetIndex )
2015-06-26 17:40:37 +02:00
{
2018-06-22 23:21:44 +02:00
switch ( widgetIndex )
{
case WIDX_LAND :
case WIDX_WATER :
case WIDX_CLEAR_SCENERY :
hide_gridlines ( ) ;
break ;
2020-05-01 22:32:41 +02:00
# ifdef ENABLE_SCRIPTING
default :
auto & customTool = OpenRCT2 : : Scripting : : ActiveCustomTool ;
if ( customTool )
{
customTool - > OnAbort ( ) ;
customTool = { } ;
}
break ;
# endif
2017-06-06 23:24:18 +02:00
}
2015-06-26 17:40:37 +02:00
}
2015-05-19 00:16:43 +02:00
2020-02-11 22:26:05 +01:00
static void top_toolbar_init_map_menu ( rct_window * w , rct_widget * widget )
{
auto i = 0 ;
gDropdownItemsFormat [ i + + ] = STR_SHORTCUT_SHOW_MAP ;
gDropdownItemsFormat [ i + + ] = STR_EXTRA_VIEWPORT ;
if ( ( gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR ) & & gS6Info . editor_step = = EDITOR_STEP_LANDSCAPE_EDITOR )
{
gDropdownItemsFormat [ i + + ] = STR_MAPGEN_WINDOW_TITLE ;
}
2020-04-24 16:58:01 +02:00
# ifdef ENABLE_SCRIPTING
2020-02-11 22:26:05 +01:00
const auto & customMenuItems = OpenRCT2 : : Scripting : : CustomMenuItems ;
if ( ! customMenuItems . empty ( ) )
{
gDropdownItemsFormat [ i + + ] = STR_EMPTY ;
for ( const auto & item : customMenuItems )
{
gDropdownItemsFormat [ i ] = STR_STRING ;
2020-04-21 00:41:02 +02:00
auto sz = item . Text . c_str ( ) ;
std : : memcpy ( & gDropdownItemsArgs [ i ] , & sz , sizeof ( const char * ) ) ;
2020-02-11 22:26:05 +01:00
i + + ;
}
}
2020-02-23 13:55:48 +01:00
# endif
2020-02-11 22:26:05 +01:00
2020-11-03 09:16:06 +01:00
WindowDropdownShowText (
2020-06-25 03:44:00 +02:00
{ w - > windowPos . x + widget - > left , w - > windowPos . y + widget - > top } , widget - > height ( ) + 1 , w - > colours [ 1 ] | 0x80 , 0 , i ) ;
2020-02-11 22:26:05 +01:00
gDropdownDefaultIndex = DDIDX_SHOW_MAP ;
}
static void top_toolbar_map_menu_dropdown ( int16_t dropdownIndex )
{
int32_t customStartIndex = 3 ;
if ( ( gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR ) & & gS6Info . editor_step = = EDITOR_STEP_LANDSCAPE_EDITOR )
{
customStartIndex + + ;
}
if ( dropdownIndex < customStartIndex )
{
switch ( dropdownIndex )
{
case 0 :
context_open_window ( WC_MAP ) ;
break ;
case 1 :
context_open_window ( WC_VIEWPORT ) ;
break ;
case 2 :
context_open_window ( WC_MAPGEN ) ;
break ;
}
}
else
{
2020-04-24 16:58:01 +02:00
# ifdef ENABLE_SCRIPTING
2020-02-11 22:26:05 +01:00
const auto & customMenuItems = OpenRCT2 : : Scripting : : CustomMenuItems ;
2020-02-22 19:04:27 +01:00
auto customIndex = static_cast < size_t > ( dropdownIndex - customStartIndex ) ;
2020-02-11 22:26:05 +01:00
if ( customMenuItems . size ( ) > customIndex )
{
customMenuItems [ customIndex ] . Invoke ( ) ;
}
2020-02-23 13:55:48 +01:00
# endif
2020-02-11 22:26:05 +01:00
}
}
2018-06-22 23:21:44 +02:00
static void top_toolbar_init_fastforward_menu ( rct_window * w , rct_widget * widget )
{
2018-06-20 17:28:51 +02:00
int32_t num_items = 4 ;
2017-06-06 23:24:18 +02:00
gDropdownItemsFormat [ 0 ] = STR_TOGGLE_OPTION ;
gDropdownItemsFormat [ 1 ] = STR_TOGGLE_OPTION ;
gDropdownItemsFormat [ 2 ] = STR_TOGGLE_OPTION ;
gDropdownItemsFormat [ 3 ] = STR_TOGGLE_OPTION ;
2018-06-22 23:21:44 +02:00
if ( gConfigGeneral . debugging_tools )
{
2017-06-06 23:24:18 +02:00
gDropdownItemsFormat [ 4 ] = STR_EMPTY ;
gDropdownItemsFormat [ 5 ] = STR_TOGGLE_OPTION ;
gDropdownItemsArgs [ 5 ] = STR_SPEED_HYPER ;
num_items = 6 ;
}
gDropdownItemsArgs [ 0 ] = STR_SPEED_NORMAL ;
gDropdownItemsArgs [ 1 ] = STR_SPEED_QUICK ;
gDropdownItemsArgs [ 2 ] = STR_SPEED_FAST ;
gDropdownItemsArgs [ 3 ] = STR_SPEED_TURBO ;
2020-11-03 09:16:06 +01:00
WindowDropdownShowText (
2020-06-25 03:44:00 +02:00
{ w - > windowPos . x + widget - > left , w - > windowPos . y + widget - > top } , widget - > height ( ) + 1 , w - > colours [ 0 ] | 0x80 , 0 ,
num_items ) ;
2017-06-06 23:24:18 +02:00
// Set checkmarks
2018-06-22 23:21:44 +02:00
if ( gGameSpeed < = 4 )
{
2020-11-03 09:16:06 +01:00
Dropdown : : SetChecked ( gGameSpeed - 1 , true ) ;
2017-06-06 23:24:18 +02:00
}
2018-06-22 23:21:44 +02:00
if ( gGameSpeed = = 8 )
{
2020-11-03 09:16:06 +01:00
Dropdown : : SetChecked ( 5 , true ) ;
2017-06-06 23:24:18 +02:00
}
2018-06-22 23:21:44 +02:00
if ( gConfigGeneral . debugging_tools )
{
2017-06-06 23:24:18 +02:00
gDropdownDefaultIndex = ( gGameSpeed = = 8 ? 0 : gGameSpeed ) ;
2018-06-22 23:21:44 +02:00
}
else
{
2017-06-06 23:24:18 +02:00
gDropdownDefaultIndex = ( gGameSpeed > = 4 ? 0 : gGameSpeed ) ;
}
2018-06-22 23:21:44 +02:00
if ( gDropdownDefaultIndex = = 4 )
{
2017-06-06 23:24:18 +02:00
gDropdownDefaultIndex = 5 ;
}
2015-05-19 00:16:43 +02:00
}
2018-06-20 17:28:51 +02:00
static void top_toolbar_fastforward_menu_dropdown ( int16_t dropdownIndex )
2016-01-18 00:37:14 +01:00
{
2017-06-06 23:24:18 +02:00
rct_window * w = window_get_main ( ) ;
2018-06-22 23:21:44 +02:00
if ( w )
{
if ( dropdownIndex > = 0 & & dropdownIndex < = 5 )
{
2017-06-06 23:24:18 +02:00
gGameSpeed = dropdownIndex + 1 ;
if ( gGameSpeed > = 5 )
gGameSpeed = 8 ;
2019-06-15 17:20:16 +02:00
w - > Invalidate ( ) ;
2017-06-06 23:24:18 +02:00
}
}
2015-05-19 00:16:43 +02:00
}
2017-11-11 02:57:45 +01:00
static void top_toolbar_init_rotate_menu ( rct_window * w , rct_widget * widget )
2016-01-18 00:37:14 +01:00
{
2017-06-06 23:24:18 +02:00
gDropdownItemsFormat [ 0 ] = STR_ROTATE_CLOCKWISE ;
gDropdownItemsFormat [ 1 ] = STR_ROTATE_ANTI_CLOCKWISE ;
2020-11-03 09:16:06 +01:00
WindowDropdownShowText (
2020-06-25 03:44:00 +02:00
{ w - > windowPos . x + widget - > left , w - > windowPos . y + widget - > top } , widget - > height ( ) + 1 , w - > colours [ 1 ] | 0x80 , 0 , 2 ) ;
2017-06-06 23:24:18 +02:00
gDropdownDefaultIndex = DDIDX_ROTATE_CLOCKWISE ;
2015-07-09 12:45:47 +02:00
}
2018-06-20 17:28:51 +02:00
static void top_toolbar_rotate_menu_dropdown ( int16_t dropdownIndex )
2016-01-18 00:37:14 +01:00
{
2017-06-06 23:24:18 +02:00
rct_window * w = window_get_main ( ) ;
2018-06-22 23:21:44 +02:00
if ( w )
{
if ( dropdownIndex = = 0 )
{
2017-06-06 23:24:18 +02:00
window_rotate_camera ( w , 1 ) ;
2019-06-15 17:20:16 +02:00
w - > Invalidate ( ) ;
2017-06-06 23:24:18 +02:00
}
2018-06-22 23:21:44 +02:00
else if ( dropdownIndex = = 1 )
{
2017-06-06 23:24:18 +02:00
window_rotate_camera ( w , - 1 ) ;
2019-06-15 17:20:16 +02:00
w - > Invalidate ( ) ;
2017-06-06 23:24:18 +02:00
}
}
2015-07-09 12:45:47 +02:00
}
2019-03-17 12:52:32 +01:00
static void top_toolbar_init_cheats_menu ( rct_window * w , rct_widget * widget )
2016-01-18 00:37:14 +01:00
{
2020-09-13 22:30:17 +02:00
using namespace Dropdown ;
constexpr Item items [ ] = {
ToggleOption ( DDIDX_CHEATS , STR_CHEAT_TITLE ) ,
ToggleOption ( DDIDX_TILE_INSPECTOR , STR_DEBUG_DROPDOWN_TILE_INSPECTOR ) ,
ToggleOption ( DDIDX_OBJECT_SELECTION , STR_DEBUG_DROPDOWN_OBJECT_SELECTION ) ,
ToggleOption ( DDIDX_INVENTIONS_LIST , STR_DEBUG_DROPDOWN_INVENTIONS_LIST ) ,
ToggleOption ( DDIDX_SCENARIO_OPTIONS , STR_DEBUG_DROPDOWN_SCENARIO_OPTIONS ) ,
2020-10-11 18:41:23 +02:00
ToggleOption ( DDIDX_OBJECTIVE_OPTIONS , STR_CHEATS_MENU_OBJECTIVE_OPTIONS ) ,
2020-09-13 22:30:17 +02:00
Separator ( ) ,
ToggleOption ( DDIDX_ENABLE_SANDBOX_MODE , STR_ENABLE_SANDBOX_MODE ) ,
ToggleOption ( DDIDX_DISABLE_CLEARANCE_CHECKS , STR_DISABLE_CLEARANCE_CHECKS ) ,
ToggleOption ( DDIDX_DISABLE_SUPPORT_LIMITS , STR_DISABLE_SUPPORT_LIMITS ) ,
} ;
static_assert ( ItemIDsMatchIndices ( items ) ) ;
SetItems ( items ) ;
2017-06-06 23:24:18 +02:00
2020-11-03 09:16:06 +01:00
WindowDropdownShowText (
2020-06-25 03:44:00 +02:00
{ w - > windowPos . x + widget - > left , w - > windowPos . y + widget - > top } , widget - > height ( ) + 1 , w - > colours [ 0 ] | 0x80 , 0 ,
TOP_TOOLBAR_CHEATS_COUNT ) ;
2017-06-06 23:24:18 +02:00
// Disable items that are not yet available in multiplayer
2018-06-22 23:21:44 +02:00
if ( network_get_mode ( ) ! = NETWORK_MODE_NONE )
{
2020-11-03 09:16:06 +01:00
Dropdown : : SetDisabled ( DDIDX_OBJECT_SELECTION , true ) ;
Dropdown : : SetDisabled ( DDIDX_INVENTIONS_LIST , true ) ;
2017-06-06 23:24:18 +02:00
}
2019-03-20 20:58:08 +01:00
if ( gScreenFlags & SCREEN_FLAGS_EDITOR )
2019-03-20 20:03:28 +01:00
{
2020-11-03 09:16:06 +01:00
Dropdown : : SetDisabled ( DDIDX_OBJECT_SELECTION , true ) ;
Dropdown : : SetDisabled ( DDIDX_INVENTIONS_LIST , true ) ;
Dropdown : : SetDisabled ( DDIDX_SCENARIO_OPTIONS , true ) ;
Dropdown : : SetDisabled ( DDIDX_OBJECTIVE_OPTIONS , true ) ;
Dropdown : : SetDisabled ( DDIDX_ENABLE_SANDBOX_MODE , true ) ;
2019-03-20 20:03:28 +01:00
}
2019-03-17 12:52:32 +01:00
if ( gCheatsSandboxMode )
{
2020-11-03 09:16:06 +01:00
Dropdown : : SetChecked ( DDIDX_ENABLE_SANDBOX_MODE , true ) ;
2019-03-17 12:52:32 +01:00
}
if ( gCheatsDisableClearanceChecks )
{
2020-11-03 09:16:06 +01:00
Dropdown : : SetChecked ( DDIDX_DISABLE_CLEARANCE_CHECKS , true ) ;
2019-03-17 12:52:32 +01:00
}
if ( gCheatsDisableSupportLimits )
{
2020-11-03 09:16:06 +01:00
Dropdown : : SetChecked ( DDIDX_DISABLE_SUPPORT_LIMITS , true ) ;
2019-03-17 12:52:32 +01:00
}
2020-08-13 13:03:56 +02:00
gDropdownDefaultIndex = DDIDX_CHEATS ;
2019-03-17 12:52:32 +01:00
}
static void top_toolbar_cheats_menu_dropdown ( int16_t dropdownIndex )
{
switch ( dropdownIndex )
{
case DDIDX_CHEATS :
context_open_window ( WC_CHEATS ) ;
break ;
case DDIDX_TILE_INSPECTOR :
context_open_window ( WC_TILE_INSPECTOR ) ;
break ;
case DDIDX_OBJECT_SELECTION :
window_close_all ( ) ;
context_open_window ( WC_EDITOR_OBJECT_SELECTION ) ;
break ;
case DDIDX_INVENTIONS_LIST :
context_open_window ( WC_EDITOR_INVENTION_LIST ) ;
break ;
case DDIDX_SCENARIO_OPTIONS :
context_open_window ( WC_EDITOR_SCENARIO_OPTIONS ) ;
break ;
2020-10-11 18:41:23 +02:00
case DDIDX_OBJECTIVE_OPTIONS :
2020-10-11 18:42:17 +02:00
context_open_window ( WC_EDITOR_OBJECTIVE_OPTIONS ) ;
2020-10-11 18:41:23 +02:00
break ;
2019-03-17 12:52:32 +01:00
case DDIDX_ENABLE_SANDBOX_MODE :
2019-05-04 15:28:38 +02:00
CheatsSet ( CheatType : : SandboxMode , ! gCheatsSandboxMode ) ;
2019-03-17 12:52:32 +01:00
break ;
case DDIDX_DISABLE_CLEARANCE_CHECKS :
2019-05-04 15:28:38 +02:00
CheatsSet ( CheatType : : DisableClearanceChecks , ! gCheatsDisableClearanceChecks ) ;
2019-03-17 12:52:32 +01:00
break ;
case DDIDX_DISABLE_SUPPORT_LIMITS :
2019-05-04 15:28:38 +02:00
CheatsSet ( CheatType : : DisableSupportLimits , ! gCheatsDisableSupportLimits ) ;
2019-03-17 12:52:32 +01:00
break ;
}
}
static void top_toolbar_init_debug_menu ( rct_window * w , rct_widget * widget )
{
gDropdownItemsFormat [ DDIDX_CONSOLE ] = STR_TOGGLE_OPTION ;
gDropdownItemsArgs [ DDIDX_CONSOLE ] = STR_DEBUG_DROPDOWN_CONSOLE ;
gDropdownItemsFormat [ DDIDX_DEBUG_PAINT ] = STR_TOGGLE_OPTION ;
gDropdownItemsArgs [ DDIDX_DEBUG_PAINT ] = STR_DEBUG_DROPDOWN_DEBUG_PAINT ;
2020-11-03 09:16:06 +01:00
WindowDropdownShowText (
2020-06-25 03:44:00 +02:00
{ w - > windowPos . x + widget - > left , w - > windowPos . y + widget - > top } , widget - > height ( ) + 1 , w - > colours [ 0 ] | 0x80 ,
2020-11-03 09:16:06 +01:00
Dropdown : : Flag : : StayOpen , TOP_TOOLBAR_DEBUG_COUNT ) ;
2019-03-17 12:52:32 +01:00
2020-11-03 09:16:06 +01:00
Dropdown : : SetChecked ( DDIDX_DEBUG_PAINT , window_find_by_class ( WC_DEBUG_PAINT ) ! = nullptr ) ;
2015-06-01 03:33:56 +02:00
}
2017-11-11 02:57:45 +01:00
static void top_toolbar_init_network_menu ( rct_window * w , rct_widget * widget )
2016-01-18 00:37:14 +01:00
{
2019-01-29 19:51:07 +01:00
gDropdownItemsFormat [ DDIDX_MULTIPLAYER ] = STR_MULTIPLAYER ;
gDropdownItemsFormat [ DDIDX_NETWORK ] = STR_NETWORK ;
2019-02-05 06:57:09 +01:00
gDropdownItemsFormat [ DDIDX_MULTIPLAYER_RECONNECT ] = STR_MULTIPLAYER_RECONNECT ;
2019-01-29 19:51:07 +01:00
2020-11-03 09:16:06 +01:00
WindowDropdownShowText (
2020-06-25 03:44:00 +02:00
{ w - > windowPos . x + widget - > left , w - > windowPos . y + widget - > top } , widget - > height ( ) + 1 , w - > colours [ 0 ] | 0x80 , 0 ,
TOP_TOOLBAR_NETWORK_COUNT ) ;
2017-06-06 23:24:18 +02:00
2020-11-03 09:16:06 +01:00
Dropdown : : SetDisabled ( DDIDX_MULTIPLAYER_RECONNECT , ! network_is_desynchronised ( ) ) ;
2017-06-06 23:24:18 +02:00
gDropdownDefaultIndex = DDIDX_MULTIPLAYER ;
2015-07-16 19:32:43 +02:00
}
2018-06-20 17:28:51 +02:00
static void top_toolbar_debug_menu_dropdown ( int16_t dropdownIndex )
2016-01-18 00:37:14 +01:00
{
2017-06-06 23:24:18 +02:00
rct_window * w = window_get_main ( ) ;
2018-06-22 23:21:44 +02:00
if ( w )
{
switch ( dropdownIndex )
2018-03-11 23:25:34 +01:00
{
2018-06-22 23:21:44 +02:00
case DDIDX_CONSOLE :
{
auto & console = GetInGameConsole ( ) ;
console . Open ( ) ;
break ;
2017-06-06 23:24:18 +02:00
}
2018-06-22 23:21:44 +02:00
case DDIDX_DEBUG_PAINT :
if ( window_find_by_class ( WC_DEBUG_PAINT ) = = nullptr )
{
context_open_window ( WC_DEBUG_PAINT ) ;
}
else
{
window_close_by_class ( WC_DEBUG_PAINT ) ;
}
break ;
2017-06-06 23:24:18 +02:00
}
}
2015-06-01 03:33:56 +02:00
}
2018-06-20 17:28:51 +02:00
static void top_toolbar_network_menu_dropdown ( int16_t dropdownIndex )
2016-01-18 00:37:14 +01:00
{
2017-06-06 23:24:18 +02:00
rct_window * w = window_get_main ( ) ;
2018-06-22 23:21:44 +02:00
if ( w )
{
switch ( dropdownIndex )
{
case DDIDX_MULTIPLAYER :
context_open_window ( WC_MULTIPLAYER ) ;
break ;
2019-01-29 19:51:07 +01:00
case DDIDX_NETWORK :
context_open_window ( WC_NETWORK ) ;
break ;
2019-02-05 06:57:09 +01:00
case DDIDX_MULTIPLAYER_RECONNECT :
network_reconnect ( ) ;
break ;
2017-06-06 23:24:18 +02:00
}
}
2015-07-16 19:32:43 +02:00
}
2015-02-10 15:41:35 +01:00
/**
*
* rct2 : 0x0066CDE4
*/
2018-06-22 23:21:44 +02:00
static void top_toolbar_init_view_menu ( rct_window * w , rct_widget * widget )
{
2020-09-13 22:30:17 +02:00
using namespace Dropdown ;
constexpr Item items [ ] = {
ToggleOption ( DDIDX_UNDERGROUND_INSIDE , STR_UNDERGROUND_VIEW ) ,
ToggleOption ( DDIDX_HIDE_BASE , STR_REMOVE_BASE_LAND ) ,
ToggleOption ( DDIDX_HIDE_VERTICAL , STR_REMOVE_VERTICAL_FACES ) ,
Separator ( ) ,
ToggleOption ( DDIDX_SEETHROUGH_RIDES , STR_SEE_THROUGH_RIDES ) ,
ToggleOption ( DDIDX_SEETHROUGH_SCENARY , STR_SEE_THROUGH_SCENERY ) ,
ToggleOption ( DDIDX_SEETHROUGH_PATHS , STR_SEE_THROUGH_PATHS ) ,
ToggleOption ( DDIDX_INVISIBLE_SUPPORTS , STR_INVISIBLE_SUPPORTS ) ,
ToggleOption ( DDIDX_INVISIBLE_PEEPS , STR_INVISIBLE_PEOPLE ) ,
Separator ( ) ,
ToggleOption ( DDIDX_LAND_HEIGHTS , STR_HEIGHT_MARKS_ON_LAND ) ,
ToggleOption ( DDIDX_TRACK_HEIGHTS , STR_HEIGHT_MARKS_ON_RIDE_TRACKS ) ,
ToggleOption ( DDIDX_PATH_HEIGHTS , STR_HEIGHT_MARKS_ON_PATHS ) ,
Separator ( ) ,
ToggleOption ( DDIDX_VIEW_CLIPPING , STR_VIEW_CLIPPING_MENU ) ,
ToggleOption ( DDIDX_HIGHLIGHT_PATH_ISSUES , STR_HIGHLIGHT_PATH_ISSUES_MENU ) ,
} ;
static_assert ( ItemIDsMatchIndices ( items ) ) ;
SetItems ( items ) ;
2017-06-06 23:24:18 +02:00
2020-11-03 09:16:06 +01:00
WindowDropdownShowText (
2020-06-25 03:44:00 +02:00
{ w - > windowPos . x + widget - > left , w - > windowPos . y + widget - > top } , widget - > height ( ) + 1 , w - > colours [ 1 ] | 0x80 , 0 ,
TOP_TOOLBAR_VIEW_MENU_COUNT ) ;
2017-06-06 23:24:18 +02:00
// Set checkmarks
rct_viewport * mainViewport = window_get_main ( ) - > viewport ;
if ( mainViewport - > flags & VIEWPORT_FLAG_UNDERGROUND_INSIDE )
2020-11-03 09:16:06 +01:00
Dropdown : : SetChecked ( 0 , true ) ;
2017-06-06 23:24:18 +02:00
if ( mainViewport - > flags & VIEWPORT_FLAG_HIDE_BASE )
2020-11-03 09:16:06 +01:00
Dropdown : : SetChecked ( 1 , true ) ;
2017-06-06 23:24:18 +02:00
if ( mainViewport - > flags & VIEWPORT_FLAG_HIDE_VERTICAL )
2020-11-03 09:16:06 +01:00
Dropdown : : SetChecked ( 2 , true ) ;
2017-06-06 23:24:18 +02:00
if ( mainViewport - > flags & VIEWPORT_FLAG_SEETHROUGH_RIDES )
2020-11-03 09:16:06 +01:00
Dropdown : : SetChecked ( 4 , true ) ;
2017-06-06 23:24:18 +02:00
if ( mainViewport - > flags & VIEWPORT_FLAG_SEETHROUGH_SCENERY )
2020-11-03 09:16:06 +01:00
Dropdown : : SetChecked ( 5 , true ) ;
2017-06-06 23:24:18 +02:00
if ( mainViewport - > flags & VIEWPORT_FLAG_SEETHROUGH_PATHS )
2020-11-03 09:16:06 +01:00
Dropdown : : SetChecked ( 6 , true ) ;
2017-06-06 23:24:18 +02:00
if ( mainViewport - > flags & VIEWPORT_FLAG_INVISIBLE_SUPPORTS )
2020-11-03 09:16:06 +01:00
Dropdown : : SetChecked ( 7 , true ) ;
2017-06-06 23:24:18 +02:00
if ( mainViewport - > flags & VIEWPORT_FLAG_INVISIBLE_PEEPS )
2020-11-03 09:16:06 +01:00
Dropdown : : SetChecked ( 8 , true ) ;
2017-06-06 23:24:18 +02:00
if ( mainViewport - > flags & VIEWPORT_FLAG_LAND_HEIGHTS )
2020-11-03 09:16:06 +01:00
Dropdown : : SetChecked ( 10 , true ) ;
2017-06-06 23:24:18 +02:00
if ( mainViewport - > flags & VIEWPORT_FLAG_TRACK_HEIGHTS )
2020-11-03 09:16:06 +01:00
Dropdown : : SetChecked ( 11 , true ) ;
2017-06-06 23:24:18 +02:00
if ( mainViewport - > flags & VIEWPORT_FLAG_PATH_HEIGHTS )
2020-11-03 09:16:06 +01:00
Dropdown : : SetChecked ( 12 , true ) ;
2018-05-08 01:25:05 +02:00
if ( mainViewport - > flags & VIEWPORT_FLAG_CLIP_VIEW )
2020-11-03 09:16:06 +01:00
Dropdown : : SetChecked ( DDIDX_VIEW_CLIPPING , true ) ;
2018-01-11 00:26:19 +01:00
if ( mainViewport - > flags & VIEWPORT_FLAG_HIGHLIGHT_PATH_ISSUES )
2020-11-03 09:16:06 +01:00
Dropdown : : SetChecked ( DDIDX_HIGHLIGHT_PATH_ISSUES , true ) ;
2017-06-06 23:24:18 +02:00
gDropdownDefaultIndex = DDIDX_UNDERGROUND_INSIDE ;
2015-02-10 15:41:35 +01:00
}
/**
*
* rct2 : 0x0066CF8A
*/
2018-06-20 17:28:51 +02:00
static void top_toolbar_view_menu_dropdown ( int16_t dropdownIndex )
2016-01-18 00:37:14 +01:00
{
2017-06-06 23:24:18 +02:00
rct_window * w = window_get_main ( ) ;
2018-06-22 23:21:44 +02:00
if ( w )
{
switch ( dropdownIndex )
{
case DDIDX_UNDERGROUND_INSIDE :
w - > viewport - > flags ^ = VIEWPORT_FLAG_UNDERGROUND_INSIDE ;
break ;
case DDIDX_HIDE_BASE :
w - > viewport - > flags ^ = VIEWPORT_FLAG_HIDE_BASE ;
break ;
case DDIDX_HIDE_VERTICAL :
w - > viewport - > flags ^ = VIEWPORT_FLAG_HIDE_VERTICAL ;
break ;
case DDIDX_SEETHROUGH_RIDES :
w - > viewport - > flags ^ = VIEWPORT_FLAG_SEETHROUGH_RIDES ;
break ;
case DDIDX_SEETHROUGH_SCENARY :
w - > viewport - > flags ^ = VIEWPORT_FLAG_SEETHROUGH_SCENERY ;
break ;
case DDIDX_SEETHROUGH_PATHS :
w - > viewport - > flags ^ = VIEWPORT_FLAG_SEETHROUGH_PATHS ;
break ;
case DDIDX_INVISIBLE_SUPPORTS :
w - > viewport - > flags ^ = VIEWPORT_FLAG_INVISIBLE_SUPPORTS ;
break ;
case DDIDX_INVISIBLE_PEEPS :
w - > viewport - > flags ^ = VIEWPORT_FLAG_INVISIBLE_PEEPS ;
break ;
case DDIDX_LAND_HEIGHTS :
w - > viewport - > flags ^ = VIEWPORT_FLAG_LAND_HEIGHTS ;
break ;
case DDIDX_TRACK_HEIGHTS :
w - > viewport - > flags ^ = VIEWPORT_FLAG_TRACK_HEIGHTS ;
break ;
case DDIDX_PATH_HEIGHTS :
w - > viewport - > flags ^ = VIEWPORT_FLAG_PATH_HEIGHTS ;
break ;
case DDIDX_VIEW_CLIPPING :
if ( window_find_by_class ( WC_VIEW_CLIPPING ) = = nullptr )
{
context_open_window ( WC_VIEW_CLIPPING ) ;
}
else
{
// If window is already open, toggle the view clipping on/off
w - > viewport - > flags ^ = VIEWPORT_FLAG_CLIP_VIEW ;
}
break ;
case DDIDX_HIGHLIGHT_PATH_ISSUES :
2018-01-11 00:26:19 +01:00
w - > viewport - > flags ^ = VIEWPORT_FLAG_HIGHLIGHT_PATH_ISSUES ;
break ;
2018-06-22 23:21:44 +02:00
default :
return ;
2017-06-06 23:24:18 +02:00
}
2019-06-15 17:20:16 +02:00
w - > Invalidate ( ) ;
2017-06-06 23:24:18 +02:00
}
2015-02-10 15:41:35 +01:00
}
/**
*
* rct2 : 0x0066CCE7
*/
2017-11-11 02:57:45 +01:00
static void toggle_footpath_window ( )
2015-02-10 15:41:35 +01:00
{
2018-06-22 23:21:44 +02:00
if ( window_find_by_class ( WC_FOOTPATH ) = = nullptr )
{
2017-08-12 23:06:12 +02:00
context_open_window ( WC_FOOTPATH ) ;
2018-06-22 23:21:44 +02:00
}
else
{
2017-06-06 23:24:18 +02:00
tool_cancel ( ) ;
window_close_by_class ( WC_FOOTPATH ) ;
}
2015-02-10 15:41:35 +01:00
}
/**
*
2015-12-11 16:38:37 +01:00
* rct2 : 0x0066CD54
2015-02-10 15:41:35 +01:00
*/
2018-06-22 23:21:44 +02:00
static void toggle_land_window ( rct_window * topToolbar , rct_widgetindex widgetIndex )
2015-02-10 15:41:35 +01:00
{
2018-06-22 23:21:44 +02:00
if ( ( input_test_flag ( INPUT_FLAG_TOOL_ACTIVE ) ) & & gCurrentToolWidget . window_classification = = WC_TOP_TOOLBAR
& & gCurrentToolWidget . widget_index = = WIDX_LAND )
{
2017-06-06 23:24:18 +02:00
tool_cancel ( ) ;
2018-06-22 23:21:44 +02:00
}
else
{
2020-04-18 00:34:32 +02:00
_landToolBlocked = false ;
2017-06-06 23:24:18 +02:00
show_gridlines ( ) ;
tool_set ( topToolbar , widgetIndex , TOOL_DIG_DOWN ) ;
input_set_flag ( INPUT_FLAG_6 , true ) ;
2017-08-12 23:06:12 +02:00
context_open_window ( WC_LAND ) ;
2017-06-06 23:24:18 +02:00
}
2015-02-10 15:41:35 +01:00
}
/**
*
2015-12-11 16:38:37 +01:00
* rct2 : 0x0066CD0C
2015-02-10 15:41:35 +01:00
*/
2018-06-22 23:21:44 +02:00
static void toggle_clear_scenery_window ( rct_window * topToolbar , rct_widgetindex widgetIndex )
2015-02-10 15:41:35 +01:00
{
2018-06-22 23:21:44 +02:00
if ( ( input_test_flag ( INPUT_FLAG_TOOL_ACTIVE ) & & gCurrentToolWidget . window_classification = = WC_TOP_TOOLBAR
& & gCurrentToolWidget . widget_index = = WIDX_CLEAR_SCENERY ) )
{
2017-06-06 23:24:18 +02:00
tool_cancel ( ) ;
2018-06-22 23:21:44 +02:00
}
else
{
2017-06-06 23:24:18 +02:00
show_gridlines ( ) ;
tool_set ( topToolbar , widgetIndex , TOOL_CROSSHAIR ) ;
input_set_flag ( INPUT_FLAG_6 , true ) ;
2017-08-12 23:06:12 +02:00
context_open_window ( WC_CLEAR_SCENERY ) ;
2017-06-06 23:24:18 +02:00
}
2015-02-10 15:41:35 +01:00
}
/**
*
2015-12-11 16:38:37 +01:00
* rct2 : 0x0066CD9C
2015-02-10 15:41:35 +01:00
*/
2018-06-22 23:21:44 +02:00
static void toggle_water_window ( rct_window * topToolbar , rct_widgetindex widgetIndex )
2015-02-10 15:41:35 +01:00
{
2018-06-22 23:21:44 +02:00
if ( ( input_test_flag ( INPUT_FLAG_TOOL_ACTIVE ) ) & & gCurrentToolWidget . window_classification = = WC_TOP_TOOLBAR
& & gCurrentToolWidget . widget_index = = WIDX_WATER )
{
2017-06-06 23:24:18 +02:00
tool_cancel ( ) ;
2018-06-22 23:21:44 +02:00
}
else
{
2020-04-18 00:34:32 +02:00
_landToolBlocked = false ;
2017-06-06 23:24:18 +02:00
show_gridlines ( ) ;
tool_set ( topToolbar , widgetIndex , TOOL_WATER_DOWN ) ;
input_set_flag ( INPUT_FLAG_6 , true ) ;
2017-08-12 23:06:12 +02:00
context_open_window ( WC_WATER ) ;
2017-06-06 23:24:18 +02:00
}
2015-05-12 16:13:30 +02:00
}
2015-07-02 18:00:39 +02:00
/**
*
* rct2 : 0x0066D104
*/
bool land_tool_is_active ( )
{
2017-06-06 23:24:18 +02:00
if ( ! ( input_test_flag ( INPUT_FLAG_TOOL_ACTIVE ) ) )
return false ;
if ( gCurrentToolWidget . window_classification ! = WC_TOP_TOOLBAR )
return false ;
if ( gCurrentToolWidget . widget_index ! = WIDX_LAND )
return false ;
return true ;
2015-07-02 18:00:39 +02:00
}
2017-04-30 23:33:19 +02:00
/**
*
* rct2 : 0x0066D125
*/
bool clear_scenery_tool_is_active ( )
{
2017-06-06 23:24:18 +02:00
if ( ! ( input_test_flag ( INPUT_FLAG_TOOL_ACTIVE ) ) )
return false ;
if ( gCurrentToolWidget . window_classification ! = WC_TOP_TOOLBAR )
return false ;
if ( gCurrentToolWidget . widget_index ! = WIDX_CLEAR_SCENERY )
return false ;
return true ;
2017-04-30 23:33:19 +02:00
}
/**
*
* rct2 : 0x0066D125
*/
bool water_tool_is_active ( )
{
2017-06-06 23:24:18 +02:00
if ( ! ( input_test_flag ( INPUT_FLAG_TOOL_ACTIVE ) ) )
return false ;
if ( gCurrentToolWidget . window_classification ! = WC_TOP_TOOLBAR )
return false ;
if ( gCurrentToolWidget . widget_index ! = WIDX_WATER )
return false ;
return true ;
2017-04-30 23:33:19 +02:00
}
2019-01-02 12:59:37 +01:00
static ClearAction GetClearAction ( )
{
auto range = MapRange ( gMapSelectPositionA . x , gMapSelectPositionA . y , gMapSelectPositionB . x , gMapSelectPositionB . y ) ;
ClearableItems itemsToClear = 0 ;
if ( gClearSmallScenery )
itemsToClear | = CLEARABLE_ITEMS : : SCENERY_SMALL ;
if ( gClearLargeScenery )
itemsToClear | = CLEARABLE_ITEMS : : SCENERY_LARGE ;
if ( gClearFootpath )
itemsToClear | = CLEARABLE_ITEMS : : SCENERY_FOOTPATH ;
return ClearAction ( range , itemsToClear ) ;
}