mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-24 07:14:31 +01:00
`typedef struct/union/enum name { ... } name_again;` is not needed whe compiling C++, moving the name at the back to be in front of the object and removing `typedef` makes it usable the very same way.
This also replaces typedefs with the using keyword. They have better readability, especially for function pointer types, and would allow more flexibility when used with templates.
6425 lines
230 KiB
C++
6425 lines
230 KiB
C++
#pragma region Copyright (c) 2014-2017 OpenRCT2 Developers
|
|
/*****************************************************************************
|
|
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
|
|
*
|
|
* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
|
|
* For more information, visit https://github.com/OpenRCT2/OpenRCT2
|
|
*
|
|
* OpenRCT2 is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* A full copy of the GNU General Public License can be found in licence.txt
|
|
*****************************************************************************/
|
|
#pragma endregion
|
|
|
|
#include <limits>
|
|
|
|
#include <openrct2-ui/windows/Window.h>
|
|
|
|
#include <openrct2/audio/audio.h>
|
|
#include <openrct2/Cheats.h>
|
|
#include <openrct2/config/Config.h>
|
|
#include <openrct2/Context.h>
|
|
#include <openrct2/core/Math.hpp>
|
|
#include <openrct2/core/Util.hpp>
|
|
#include <openrct2/Game.h>
|
|
#include <openrct2/Input.h>
|
|
#include <openrct2/interface/themes.h>
|
|
#include <openrct2-ui/interface/Viewport.h>
|
|
#include <openrct2-ui/interface/Widget.h>
|
|
#include <openrct2/localisation/Date.h>
|
|
#include <openrct2/localisation/Localisation.h>
|
|
#include <openrct2/localisation/StringIds.h>
|
|
#include <openrct2/network/network.h>
|
|
#include <openrct2/object/ObjectManager.h>
|
|
#include <openrct2/object/ObjectRepository.h>
|
|
#include <openrct2/OpenRCT2.h>
|
|
#include <openrct2/peep/Staff.h>
|
|
#include <openrct2/rct1/RCT1.h>
|
|
#include <openrct2/ride/RideGroupManager.h>
|
|
#include <openrct2/ride/RideData.h>
|
|
#include <openrct2/ride/Track.h>
|
|
#include <openrct2/ride/TrackData.h>
|
|
#include <openrct2/sprites.h>
|
|
#include <openrct2-ui/interface/Dropdown.h>
|
|
#include <openrct2/windows/Intent.h>
|
|
|
|
enum {
|
|
WINDOW_RIDE_PAGE_MAIN,
|
|
WINDOW_RIDE_PAGE_VEHICLE,
|
|
WINDOW_RIDE_PAGE_OPERATING,
|
|
WINDOW_RIDE_PAGE_MAINTENANCE,
|
|
WINDOW_RIDE_PAGE_COLOUR,
|
|
WINDOW_RIDE_PAGE_MUSIC,
|
|
WINDOW_RIDE_PAGE_MEASUREMENTS,
|
|
WINDOW_RIDE_PAGE_GRAPHS,
|
|
WINDOW_RIDE_PAGE_INCOME,
|
|
WINDOW_RIDE_PAGE_CUSTOMER,
|
|
WINDOW_RIDE_PAGE_COUNT
|
|
};
|
|
|
|
#pragma region Widgets
|
|
|
|
enum {
|
|
WIDX_BACKGROUND,
|
|
WIDX_TITLE,
|
|
WIDX_CLOSE,
|
|
WIDX_PAGE_BACKGROUND,
|
|
WIDX_TAB_1,
|
|
WIDX_TAB_2,
|
|
WIDX_TAB_3,
|
|
WIDX_TAB_4,
|
|
WIDX_TAB_5,
|
|
WIDX_TAB_6,
|
|
WIDX_TAB_7,
|
|
WIDX_TAB_8,
|
|
WIDX_TAB_9,
|
|
WIDX_TAB_10,
|
|
|
|
WIDX_VIEWPORT = 14,
|
|
WIDX_VIEW,
|
|
WIDX_VIEW_DROPDOWN,
|
|
WIDX_STATUS,
|
|
WIDX_OPEN,
|
|
WIDX_CONSTRUCTION,
|
|
WIDX_RENAME,
|
|
WIDX_LOCATE,
|
|
WIDX_DEMOLISH,
|
|
WIDX_CLOSE_LIGHT,
|
|
WIDX_TEST_LIGHT,
|
|
WIDX_OPEN_LIGHT,
|
|
WIDX_RIDE_TYPE,
|
|
WIDX_RIDE_TYPE_INCREASE,
|
|
WIDX_RIDE_TYPE_DECREASE,
|
|
WIDX_RIDE_TYPE_APPLY,
|
|
|
|
WIDX_VEHICLE_TYPE = 14,
|
|
WIDX_VEHICLE_TYPE_DROPDOWN,
|
|
WIDX_VEHICLE_TRAINS_PREVIEW,
|
|
WIDX_VEHICLE_TRAINS,
|
|
WIDX_VEHICLE_TRAINS_INCREASE,
|
|
WIDX_VEHICLE_TRAINS_DECREASE,
|
|
WIDX_VEHICLE_CARS_PER_TRAIN,
|
|
WIDX_VEHICLE_CARS_PER_TRAIN_INCREASE,
|
|
WIDX_VEHICLE_CARS_PER_TRAIN_DECREASE,
|
|
|
|
WIDX_MODE_TWEAK = 14,
|
|
WIDX_MODE_TWEAK_INCREASE,
|
|
WIDX_MODE_TWEAK_DECREASE,
|
|
WIDX_LIFT_HILL_SPEED,
|
|
WIDX_LIFT_HILL_SPEED_INCREASE,
|
|
WIDX_LIFT_HILL_SPEED_DECREASE,
|
|
WIDX_LOAD_CHECKBOX,
|
|
WIDX_LEAVE_WHEN_ANOTHER_ARRIVES_CHECKBOX,
|
|
WIDX_MINIMUM_LENGTH_CHECKBOX,
|
|
WIDX_MINIMUM_LENGTH,
|
|
WIDX_MINIMUM_LENGTH_INCREASE,
|
|
WIDX_MINIMUM_LENGTH_DECREASE,
|
|
WIDX_MAXIMUM_LENGTH_CHECKBOX,
|
|
WIDX_MAXIMUM_LENGTH,
|
|
WIDX_MAXIMUM_LENGTH_INCREASE,
|
|
WIDX_MAXIMUM_LENGTH_DECREASE,
|
|
WIDX_SYNCHRONISE_WITH_ADJACENT_STATIONS_CHECKBOX,
|
|
WIDX_MODE_TWEAK_LABEL,
|
|
WIDX_LIFT_HILL_SPEED_LABEL,
|
|
WIDX_MODE,
|
|
WIDX_MODE_DROPDOWN,
|
|
WIDX_LOAD,
|
|
WIDX_LOAD_DROPDOWN,
|
|
WIDX_OPERATE_NUMBER_OF_CIRCUITS_LABEL,
|
|
WIDX_OPERATE_NUMBER_OF_CIRCUITS,
|
|
WIDX_OPERATE_NUMBER_OF_CIRCUITS_INCREASE,
|
|
WIDX_OPERATE_NUMBER_OF_CIRCUITS_DECREASE,
|
|
|
|
WIDX_INSPECTION_INTERVAL = 14,
|
|
WIDX_INSPECTION_INTERVAL_DROPDOWN,
|
|
WIDX_LOCATE_MECHANIC,
|
|
WIDX_FORCE_BREAKDOWN,
|
|
|
|
WIDX_TRACK_PREVIEW = 14,
|
|
WIDX_TRACK_COLOUR_SCHEME,
|
|
WIDX_TRACK_COLOUR_SCHEME_DROPDOWN,
|
|
WIDX_TRACK_MAIN_COLOUR,
|
|
WIDX_TRACK_ADDITIONAL_COLOUR,
|
|
WIDX_TRACK_SUPPORT_COLOUR,
|
|
WIDX_MAZE_STYLE,
|
|
WIDX_MAZE_STYLE_DROPDOWN,
|
|
WIDX_PAINT_INDIVIDUAL_AREA,
|
|
WIDX_ENTRANCE_PREVIEW,
|
|
WIDX_ENTRANCE_STYLE,
|
|
WIDX_ENTRANCE_STYLE_DROPDOWN,
|
|
WIDX_VEHICLE_PREVIEW,
|
|
WIDX_VEHICLE_COLOUR_SCHEME,
|
|
WIDX_VEHICLE_COLOUR_SCHEME_DROPDOWN,
|
|
WIDX_VEHICLE_COLOUR_INDEX,
|
|
WIDX_VEHICLE_COLOUR_INDEX_DROPDOWN,
|
|
WIDX_VEHICLE_MAIN_COLOUR,
|
|
WIDX_VEHICLE_ADDITIONAL_COLOUR_1,
|
|
WIDX_VEHICLE_ADDITIONAL_COLOUR_2,
|
|
|
|
WIDX_PLAY_MUSIC = 14,
|
|
WIDX_MUSIC,
|
|
WIDX_MUSIC_DROPDOWN,
|
|
|
|
WIDX_SAVE_TRACK_DESIGN = 14,
|
|
WIDX_SELECT_NEARBY_SCENERY,
|
|
WIDX_RESET_SELECTION,
|
|
WIDX_SAVE_DESIGN,
|
|
WIDX_CANCEL_DESIGN,
|
|
|
|
WIDX_GRAPH = 14,
|
|
WIDX_GRAPH_VELOCITY,
|
|
WIDX_GRAPH_ALTITUDE,
|
|
WIDX_GRAPH_VERTICAL,
|
|
WIDX_GRAPH_LATERAL,
|
|
|
|
WIDX_PRIMARY_PRICE_LABEL = 14,
|
|
WIDX_PRIMARY_PRICE,
|
|
WIDX_PRIMARY_PRICE_INCREASE,
|
|
WIDX_PRIMARY_PRICE_DECREASE,
|
|
WIDX_PRIMARY_PRICE_SAME_THROUGHOUT_PARK,
|
|
WIDX_SECONDARY_PRICE_LABEL,
|
|
WIDX_SECONDARY_PRICE,
|
|
WIDX_SECONDARY_PRICE_INCREASE,
|
|
WIDX_SECONDARY_PRICE_DECREASE,
|
|
WIDX_SECONDARY_PRICE_SAME_THROUGHOUT_PARK,
|
|
|
|
WIDX_SHOW_GUESTS_THOUGHTS = 14,
|
|
WIDX_SHOW_GUESTS_ON_RIDE,
|
|
WIDX_SHOW_GUESTS_QUEUING
|
|
};
|
|
|
|
#define RCT1_LIGHT_OFFSET 4
|
|
|
|
#define MAIN_RIDE_WIDGETS \
|
|
{ WWT_FRAME, 0, 0, 315, 0, 206, 0xFFFFFFFF, STR_NONE }, \
|
|
{ WWT_CAPTION, 0, 1, 314, 1, 14, STR_RIDE_WINDOW_TITLE, STR_WINDOW_TITLE_TIP }, \
|
|
{ WWT_CLOSEBOX, 0, 303, 313, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP }, \
|
|
{ WWT_RESIZE, 1, 0, 315, 43, 179, 0xFFFFFFFF, STR_NONE }, \
|
|
{ WWT_TAB, 1, 3, 33, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_VIEW_OF_RIDE_ATTRACTION_TIP }, \
|
|
{ WWT_TAB, 1, 34, 64, 17, 46, IMAGE_TYPE_REMAP | SPR_TAB, STR_VEHICLE_DETAILS_AND_OPTIONS_TIP }, \
|
|
{ WWT_TAB, 1, 65, 95, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_OPERATING_OPTIONS_TIP }, \
|
|
{ WWT_TAB, 1, 96, 126, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_MAINTENANCE_OPTIONS_TIP }, \
|
|
{ WWT_TAB, 1, 127, 157, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_COLOUR_SCHEME_OPTIONS_TIP }, \
|
|
{ WWT_TAB, 1, 158, 188, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_SOUND_AND_MUSIC_OPTIONS_TIP }, \
|
|
{ WWT_TAB, 1, 189, 219, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_MEASUREMENTS_AND_TEST_DATA_TIP }, \
|
|
{ WWT_TAB, 1, 220, 250, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_GRAPHS_TIP }, \
|
|
{ WWT_TAB, 1, 251, 281, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_INCOME_AND_COSTS_TIP }, \
|
|
{ WWT_TAB, 1, 282, 312, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_CUSTOMER_INFORMATION_TIP }
|
|
|
|
// 0x009ADC34
|
|
static rct_widget window_ride_main_widgets[] = {
|
|
MAIN_RIDE_WIDGETS,
|
|
{ WWT_VIEWPORT, 1, 3, 290, 60, 166, STR_VIEWPORT, STR_NONE },
|
|
{ WWT_DROPDOWN, 1, 35, 256, 46, 57, 0xFFFFFFFF, STR_VIEW_SELECTION },
|
|
{ WWT_BUTTON, 1, 245, 255, 47, 56, STR_DROPDOWN_GLYPH, STR_VIEW_SELECTION },
|
|
{ WWT_LABEL_CENTRED, 1, 3, 290, 167, 177, 0xFFFFFFFF, STR_NONE },
|
|
{ WWT_FLATBTN, 1, 291, 314, 46, 69, 0xFFFFFFFF, STR_OPEN_CLOSE_OR_TEST_RIDE },
|
|
{ WWT_FLATBTN, 1, 291, 314, 70, 93, SPR_CONSTRUCTION, STR_CONSTRUCTION },
|
|
{ WWT_FLATBTN, 1, 291, 314, 94, 117, SPR_RENAME, STR_NAME_RIDE_TIP },
|
|
{ WWT_FLATBTN, 1, 291, 314, 118, 141, SPR_LOCATE, STR_LOCATE_SUBJECT_TIP },
|
|
{ WWT_FLATBTN, 1, 291, 314, 142, 165, SPR_DEMOLISH, STR_DEMOLISH_RIDE_TIP },
|
|
{ WWT_IMGBTN, 1, 296, 309, 48, 61, SPR_G2_RCT1_CLOSE_BUTTON_0, STR_CLOSE_RIDE_TIP },
|
|
{ WWT_IMGBTN, 1, 296, 309, 62, 75, SPR_G2_RCT1_TEST_BUTTON_0, STR_TEST_RIDE_TIP },
|
|
{ WWT_IMGBTN, 1, 296, 309, 76, 89, SPR_G2_RCT1_OPEN_BUTTON_0, STR_OPEN_RIDE_TIP },
|
|
|
|
// Ride type spinner + apply button
|
|
{ WWT_SPINNER, 1, 3, 253, 180, 191, STR_ARG_6_STRINGID, STR_NONE },
|
|
{ WWT_BUTTON, 1, 242, 252, 181, 185, STR_NUMERIC_UP, STR_NONE },
|
|
{ WWT_BUTTON, 1, 242, 252, 186, 190, STR_NUMERIC_DOWN, STR_NONE },
|
|
{ WWT_BUTTON, 1, 260, 307, 180, 191, STR_APPLY, STR_NONE },
|
|
{ WIDGETS_END },
|
|
};
|
|
|
|
// 0x009ADDA8
|
|
static rct_widget window_ride_vehicle_widgets[] = {
|
|
MAIN_RIDE_WIDGETS,
|
|
{ WWT_DROPDOWN, 1, 7, 308, 50, 61, 0xFFFFFFFF, STR_NONE },
|
|
{ WWT_BUTTON, 1, 297, 307, 51, 60, STR_DROPDOWN_GLYPH, STR_NONE },
|
|
{ WWT_SCROLL, 1, 7, 308, 147, 189, 0, STR_NONE },
|
|
{ WWT_SPINNER, 1, 7, 151, 196, 207, STR_RIDE_VEHICLE_COUNT, STR_MAX_VEHICLES_TIP },
|
|
{ WWT_BUTTON, 1, 140, 150, 197, 201, STR_NUMERIC_UP, STR_NONE },
|
|
{ WWT_BUTTON, 1, 140, 150, 202, 206, STR_NUMERIC_DOWN, STR_NONE },
|
|
{ WWT_SPINNER, 1, 164, 308, 196, 207, STR_1_CAR_PER_TRAIN, STR_MAX_CARS_PER_TRAIN_TIP },
|
|
{ WWT_BUTTON, 1, 297, 307, 197, 201, STR_NUMERIC_UP, STR_NONE },
|
|
{ WWT_BUTTON, 1, 297, 307, 202, 206, STR_NUMERIC_DOWN, STR_NONE },
|
|
{ WIDGETS_END },
|
|
};
|
|
|
|
// 0x009ADEFC
|
|
static rct_widget window_ride_operating_widgets[] = {
|
|
MAIN_RIDE_WIDGETS,
|
|
{ WWT_SPINNER, 1, 157, 308, 61, 72, STR_ARG_18_STRINGID, STR_NONE },
|
|
{ WWT_BUTTON, 1, 297, 307, 62, 66, STR_NUMERIC_UP, STR_NONE },
|
|
{ WWT_BUTTON, 1, 297, 307, 67, 71, STR_NUMERIC_DOWN, STR_NONE },
|
|
{ WWT_SPINNER, 1, 157, 308, 75, 86, STR_LIFT_HILL_CHAIN_SPEED_VALUE, STR_NONE },
|
|
{ WWT_BUTTON, 1, 297, 307, 76, 80, STR_NUMERIC_UP, STR_SELECT_LIFT_HILL_CHAIN_SPEED_TIP },
|
|
{ WWT_BUTTON, 1, 297, 307, 81, 85, STR_NUMERIC_DOWN, STR_SELECT_LIFT_HILL_CHAIN_SPEED_TIP },
|
|
{ WWT_CHECKBOX, 1, 7, 86, 109, 120, STR_WAIT_FOR, STR_WAIT_FOR_PASSENGERS_BEFORE_DEPARTING_TIP },
|
|
{ WWT_CHECKBOX, 1, 7, 308, 124, 135, 0xFFFFFFFF, STR_NONE },
|
|
{ WWT_CHECKBOX, 1, 7, 156, 139, 150, STR_MINIMUM_WAITING_TIME, STR_MINIMUM_LENGTH_BEFORE_DEPARTING_TIP },
|
|
{ WWT_SPINNER, 1, 157, 308, 139, 150, STR_ARG_10_STRINGID, STR_NONE },
|
|
{ WWT_BUTTON, 1, 297, 307, 140, 144, STR_NUMERIC_UP, STR_NONE },
|
|
{ WWT_BUTTON, 1, 297, 307, 145, 149, STR_NUMERIC_DOWN, STR_NONE },
|
|
{ WWT_CHECKBOX, 1, 7, 156, 154, 165, STR_MAXIMUM_WAITING_TIME, STR_MAXIMUM_LENGTH_BEFORE_DEPARTING_TIP },
|
|
{ WWT_SPINNER, 1, 157, 308, 154, 165, STR_ARG_14_STRINGID, STR_NONE },
|
|
{ WWT_BUTTON, 1, 297, 307, 155, 159, STR_NUMERIC_UP, STR_NONE },
|
|
{ WWT_BUTTON, 1, 297, 307, 160, 164, STR_NUMERIC_DOWN, STR_NONE },
|
|
{ WWT_CHECKBOX, 1, 7, 308, 169, 180, STR_SYNCHRONISE_WITH_ADJACENT_STATIONS, STR_SYNCHRONISE_WITH_ADJACENT_STATIONS_TIP },
|
|
{ WWT_LABEL, 1, 21, 149, 61, 72, 0xFFFFFFFF, STR_NONE },
|
|
{ WWT_LABEL, 1, 21, 149, 75, 86, STR_LIFT_HILL_CHAIN_SPEED, STR_NONE },
|
|
{ WWT_DROPDOWN, 1, 7, 308, 47, 58, 0xFFFFFFFF, STR_SELECT_OPERATING_MODE },
|
|
{ WWT_BUTTON, 1, 297, 307, 48, 57, STR_DROPDOWN_GLYPH, STR_SELECT_OPERATING_MODE },
|
|
{ WWT_DROPDOWN, 1, 87, 308, 109, 120, 0xFFFFFFFF, STR_NONE },
|
|
{ WWT_BUTTON, 1, 297, 307, 110, 119, STR_DROPDOWN_GLYPH, STR_NONE },
|
|
{ WWT_LABEL, 1, 21, 149, 89, 100, STR_NUMBER_OF_CIRCUITS, STR_NUMBER_OF_CIRCUITS_TIP },
|
|
{ WWT_SPINNER, 1, 157, 308, 89, 100, STR_NUMBER_OF_CIRCUITS_VALUE, STR_NONE },
|
|
{ WWT_BUTTON, 1, 297, 307, 90, 94, STR_NUMERIC_UP, STR_SELECT_NUMBER_OF_CIRCUITS_TIP },
|
|
{ WWT_BUTTON, 1, 297, 307, 95, 99, STR_NUMERIC_DOWN, STR_SELECT_NUMBER_OF_CIRCUITS_TIP },
|
|
{ WIDGETS_END },
|
|
};
|
|
|
|
// 0x009AE190
|
|
static rct_widget window_ride_maintenance_widgets[] = {
|
|
MAIN_RIDE_WIDGETS,
|
|
{ WWT_DROPDOWN, 1, 107, 308, 71, 82, 0, STR_SELECT_HOW_OFTEN_A_MECHANIC_SHOULD_CHECK_THIS_RIDE },
|
|
{ WWT_BUTTON, 1, 297, 307, 72, 81, STR_DROPDOWN_GLYPH, STR_SELECT_HOW_OFTEN_A_MECHANIC_SHOULD_CHECK_THIS_RIDE },
|
|
{ WWT_FLATBTN, 1, 289, 312, 108, 131, 0xFFFFFFFF, STR_LOCATE_NEAREST_AVAILABLE_MECHANIC_TIP },
|
|
{ WWT_FLATBTN, 1, 265, 288, 108, 131, SPR_NO_ENTRY, STR_DEBUG_FORCE_BREAKDOWN_TIP },
|
|
{ WIDGETS_END },
|
|
};
|
|
|
|
// 0x009AE2A4
|
|
static rct_widget window_ride_colour_widgets[] = {
|
|
MAIN_RIDE_WIDGETS,
|
|
{ WWT_SPINNER, 1, 3, 70, 47, 93, 0xFFFFFFFF, STR_NONE },
|
|
{ WWT_DROPDOWN, 1, 74, 312, 49, 60, STR_ARG_14_STRINGID, STR_NONE },
|
|
{ WWT_BUTTON, 1, 301, 311, 50, 59, STR_DROPDOWN_GLYPH, STR_COLOUR_SCHEME_TO_CHANGE_TIP },
|
|
{ WWT_COLOURBTN, 1, 79, 90, 74, 85, 0xFFFFFFFF, STR_SELECT_MAIN_COLOUR_TIP },
|
|
{ WWT_COLOURBTN, 1, 99, 110, 74, 85, 0xFFFFFFFF, STR_SELECT_ADDITIONAL_COLOUR_1_TIP },
|
|
{ WWT_COLOURBTN, 1, 119, 130, 74, 85, 0xFFFFFFFF, STR_SELECT_SUPPORT_STRUCTURE_COLOUR_TIP },
|
|
{ WWT_DROPDOWN, 1, 74, 312, 49, 60, 0xFFFFFFFF, STR_NONE },
|
|
{ WWT_BUTTON, 1, 301, 311, 50, 59, STR_DROPDOWN_GLYPH, STR_NONE },
|
|
{ WWT_FLATBTN, 1, 289, 312, 68, 91, SPR_PAINTBRUSH, STR_PAINT_INDIVIDUAL_AREA_TIP },
|
|
{ WWT_SPINNER, 1, 245, 312, 101, 147, 0xFFFFFFFF, STR_NONE },
|
|
{ WWT_DROPDOWN, 1, 3, 241, 103, 114, 0, STR_NONE },
|
|
{ WWT_BUTTON, 1, 230, 240, 104, 113, STR_DROPDOWN_GLYPH, STR_SELECT_STYLE_OF_ENTRANCE_EXIT_STATION_TIP },
|
|
{ WWT_SCROLL, 1, 3, 70, 157, 203, 0, STR_NONE },
|
|
{ WWT_DROPDOWN, 1, 74, 312, 157, 168, STR_ARG_6_STRINGID, STR_NONE },
|
|
{ WWT_BUTTON, 1, 301, 311, 158, 167, STR_DROPDOWN_GLYPH, STR_SELECT_VEHICLE_COLOUR_SCHEME_TIP },
|
|
{ WWT_DROPDOWN, 1, 74, 312, 173, 184, 0xFFFFFFFF, STR_NONE },
|
|
{ WWT_BUTTON, 1, 301, 311, 174, 183, STR_DROPDOWN_GLYPH, STR_SELECT_VEHICLE_TO_MODIFY_TIP },
|
|
{ WWT_COLOURBTN, 1, 79, 90, 190, 201, 0xFFFFFFFF, STR_SELECT_MAIN_COLOUR_TIP },
|
|
{ WWT_COLOURBTN, 1, 99, 110, 190, 201, 0xFFFFFFFF, STR_SELECT_ADDITIONAL_COLOUR_1_TIP },
|
|
{ WWT_COLOURBTN, 1, 119, 130, 190, 201, 0xFFFFFFFF, STR_SELECT_ADDITIONAL_COLOUR_2_TIP },
|
|
{ WIDGETS_END },
|
|
};
|
|
|
|
// 0x009AE4C8
|
|
static rct_widget window_ride_music_widgets[] = {
|
|
MAIN_RIDE_WIDGETS,
|
|
{ WWT_CHECKBOX, 1, 7, 308, 47, 58, STR_PLAY_MUSIC, STR_SELECT_MUSIC_TIP },
|
|
{ WWT_DROPDOWN, 1, 7, 308, 62, 73, 0, STR_NONE },
|
|
{ WWT_BUTTON, 1, 297, 307, 63, 72, STR_DROPDOWN_GLYPH, STR_SELECT_MUSIC_STYLE_TIP },
|
|
{ WIDGETS_END },
|
|
};
|
|
|
|
// 0x009AE5DC
|
|
static rct_widget window_ride_measurements_widgets[] = {
|
|
MAIN_RIDE_WIDGETS,
|
|
{ WWT_FLATBTN, 1, 288, 311, 194, 217, SPR_FLOPPY, STR_SAVE_TRACK_DESIGN },
|
|
{ WWT_BUTTON, 1, 4, 157, 128, 139, STR_SELECT_NEARBY_SCENERY, STR_NONE },
|
|
{ WWT_BUTTON, 1, 158, 311, 128, 139, STR_RESET_SELECTION, STR_NONE },
|
|
{ WWT_BUTTON, 1, 4, 157, 178, 189, STR_DESIGN_SAVE, STR_NONE },
|
|
{ WWT_BUTTON, 1, 158, 311, 178, 189, STR_DESIGN_CANCEL, STR_NONE },
|
|
{ WIDGETS_END },
|
|
};
|
|
|
|
// 0x009AE710
|
|
static rct_widget window_ride_graphs_widgets[] = {
|
|
MAIN_RIDE_WIDGETS,
|
|
{ WWT_SCROLL, 1, 3, 308, 46, 157, SCROLL_HORIZONTAL, STR_LOGGING_DATA_FROM_TIP },
|
|
{ WWT_BUTTON, 1, 3, 75, 163, 176, STR_RIDE_STATS_VELOCITY, STR_SHOW_GRAPH_OF_VELOCITY_AGAINST_TIME_TIP },
|
|
{ WWT_BUTTON, 1, 76, 148, 163, 176, STR_RIDE_STATS_ALTITUDE, STR_SHOW_GRAPH_OF_ALTITUDE_AGAINST_TIME_TIP },
|
|
{ WWT_BUTTON, 1, 149, 221, 163, 176, STR_RIDE_STATS_VERT_G, STR_SHOW_GRAPH_OF_VERTICAL_ACCELERATION_AGAINST_TIME_TIP },
|
|
{ WWT_BUTTON, 1, 222, 294, 163, 176, STR_RIDE_STATS_LAT_G, STR_SHOW_GRAPH_OF_LATERAL_ACCELERATION_AGAINST_TIME_TIP },
|
|
{ WIDGETS_END },
|
|
};
|
|
|
|
// 0x009AE844
|
|
static rct_widget window_ride_income_widgets[] = {
|
|
MAIN_RIDE_WIDGETS,
|
|
{ WWT_LABEL, 1, 19, 144, 50, 61, 0xFFFFFFFF, STR_NONE },
|
|
{ WWT_SPINNER, 1, 147, 308, 50, 61, STR_ARG_6_CURRENCY2DP, STR_NONE },
|
|
{ WWT_BUTTON, 1, 297, 307, 51, 55, STR_NUMERIC_UP, STR_NONE },
|
|
{ WWT_BUTTON, 1, 297, 307, 56, 60, STR_NUMERIC_DOWN, STR_NONE },
|
|
{ WWT_CHECKBOX, 1, 5, 310, 61, 72, STR_SAME_PRICE_THROUGHOUT_PARK, STR_SAME_PRICE_THROUGHOUT_PARK_TIP },
|
|
{ WWT_LABEL, 1, 19, 144, 89, 100, 0xFFFFFFFF, STR_NONE },
|
|
{ WWT_SPINNER, 1, 147, 308, 89, 100, STR_RIDE_SECONDARY_PRICE_VALUE, STR_NONE },
|
|
{ WWT_BUTTON, 1, 297, 307, 90, 94, STR_NUMERIC_UP, STR_NONE },
|
|
{ WWT_BUTTON, 1, 297, 307, 95, 99, STR_NUMERIC_DOWN, STR_NONE },
|
|
{ WWT_CHECKBOX, 1, 5, 310, 100, 111, STR_SAME_PRICE_THROUGHOUT_PARK, STR_SAME_PRICE_THROUGHOUT_PARK_TIP },
|
|
{ WIDGETS_END },
|
|
};
|
|
|
|
// 0x009AE9C8
|
|
static rct_widget window_ride_customer_widgets[] = {
|
|
MAIN_RIDE_WIDGETS,
|
|
{ WWT_FLATBTN, 1, 289, 312, 54, 77, SPR_SHOW_GUESTS_THOUGHTS_ABOUT_THIS_RIDE_ATTRACTION, STR_SHOW_GUESTS_THOUGHTS_ABOUT_THIS_RIDE_ATTRACTION_TIP },
|
|
{ WWT_FLATBTN, 1, 289, 312, 78, 101, SPR_SHOW_GUESTS_ON_THIS_RIDE_ATTRACTION, STR_SHOW_GUESTS_ON_THIS_RIDE_ATTRACTION_TIP },
|
|
{ WWT_FLATBTN, 1, 289, 312, 102, 125, SPR_SHOW_GUESTS_QUEUING_FOR_THIS_RIDE_ATTRACTION, STR_SHOW_GUESTS_QUEUING_FOR_THIS_RIDE_ATTRACTION_TIP },
|
|
{ WIDGETS_END },
|
|
};
|
|
|
|
static rct_widget *window_ride_page_widgets[] = {
|
|
window_ride_main_widgets,
|
|
window_ride_vehicle_widgets,
|
|
window_ride_operating_widgets,
|
|
window_ride_maintenance_widgets,
|
|
window_ride_colour_widgets,
|
|
window_ride_music_widgets,
|
|
window_ride_measurements_widgets,
|
|
window_ride_graphs_widgets,
|
|
window_ride_income_widgets,
|
|
window_ride_customer_widgets
|
|
};
|
|
|
|
#define MAIN_RIDE_ENABLED_WIDGETS \
|
|
(1ULL << WIDX_CLOSE) | \
|
|
(1ULL << WIDX_TAB_1) | \
|
|
(1ULL << WIDX_TAB_2) | \
|
|
(1ULL << WIDX_TAB_3) | \
|
|
(1ULL << WIDX_TAB_4) | \
|
|
(1ULL << WIDX_TAB_5) | \
|
|
(1ULL << WIDX_TAB_6) | \
|
|
(1ULL << WIDX_TAB_7) | \
|
|
(1ULL << WIDX_TAB_8) | \
|
|
(1ULL << WIDX_TAB_9) | \
|
|
(1ULL << WIDX_TAB_10)
|
|
|
|
static constexpr const uint64 window_ride_page_enabled_widgets[] = {
|
|
MAIN_RIDE_ENABLED_WIDGETS |
|
|
(1ULL << WIDX_VIEW) |
|
|
(1ULL << WIDX_VIEW_DROPDOWN) |
|
|
(1ULL << WIDX_OPEN) |
|
|
(1ULL << WIDX_CONSTRUCTION) |
|
|
(1ULL << WIDX_RENAME) |
|
|
(1ULL << WIDX_LOCATE) |
|
|
(1ULL << WIDX_DEMOLISH) |
|
|
(1ULL << WIDX_CLOSE_LIGHT) |
|
|
(1ULL << WIDX_TEST_LIGHT) |
|
|
(1ULL << WIDX_OPEN_LIGHT) |
|
|
(1ULL << WIDX_RIDE_TYPE) |
|
|
(1ULL << WIDX_RIDE_TYPE_INCREASE) |
|
|
(1ULL << WIDX_RIDE_TYPE_DECREASE) |
|
|
(1ULL << WIDX_RIDE_TYPE_APPLY),
|
|
MAIN_RIDE_ENABLED_WIDGETS |
|
|
(1ULL << WIDX_VEHICLE_TYPE) |
|
|
(1ULL << WIDX_VEHICLE_TYPE_DROPDOWN) |
|
|
(1ULL << WIDX_VEHICLE_TRAINS) |
|
|
(1ULL << WIDX_VEHICLE_TRAINS_INCREASE) |
|
|
(1ULL << WIDX_VEHICLE_TRAINS_DECREASE) |
|
|
(1ULL << WIDX_VEHICLE_CARS_PER_TRAIN) |
|
|
(1ULL << WIDX_VEHICLE_CARS_PER_TRAIN_INCREASE) |
|
|
(1ULL << WIDX_VEHICLE_CARS_PER_TRAIN_DECREASE),
|
|
MAIN_RIDE_ENABLED_WIDGETS |
|
|
(1ULL << WIDX_MODE_TWEAK_INCREASE) |
|
|
(1ULL << WIDX_MODE_TWEAK_DECREASE) |
|
|
(1ULL << WIDX_LIFT_HILL_SPEED_INCREASE) |
|
|
(1ULL << WIDX_LIFT_HILL_SPEED_DECREASE) |
|
|
(1ULL << WIDX_LOAD_CHECKBOX) |
|
|
(1ULL << WIDX_LEAVE_WHEN_ANOTHER_ARRIVES_CHECKBOX) |
|
|
(1ULL << WIDX_MINIMUM_LENGTH_CHECKBOX) |
|
|
(1ULL << WIDX_MINIMUM_LENGTH_INCREASE) |
|
|
(1ULL << WIDX_MINIMUM_LENGTH_DECREASE) |
|
|
(1ULL << WIDX_MAXIMUM_LENGTH_CHECKBOX) |
|
|
(1ULL << WIDX_MAXIMUM_LENGTH_INCREASE) |
|
|
(1ULL << WIDX_MAXIMUM_LENGTH_DECREASE) |
|
|
(1ULL << WIDX_SYNCHRONISE_WITH_ADJACENT_STATIONS_CHECKBOX) |
|
|
(1ULL << WIDX_MODE) |
|
|
(1ULL << WIDX_MODE_DROPDOWN) |
|
|
(1ULL << WIDX_LOAD) |
|
|
(1ULL << WIDX_LOAD_DROPDOWN) |
|
|
(1ULL << WIDX_OPERATE_NUMBER_OF_CIRCUITS_INCREASE) |
|
|
(1ULL << WIDX_OPERATE_NUMBER_OF_CIRCUITS_DECREASE),
|
|
MAIN_RIDE_ENABLED_WIDGETS |
|
|
(1ULL << WIDX_INSPECTION_INTERVAL) |
|
|
(1ULL << WIDX_INSPECTION_INTERVAL_DROPDOWN) |
|
|
(1ULL << WIDX_LOCATE_MECHANIC) |
|
|
(1ULL << WIDX_FORCE_BREAKDOWN),
|
|
MAIN_RIDE_ENABLED_WIDGETS |
|
|
(1ULL << WIDX_TRACK_COLOUR_SCHEME_DROPDOWN) |
|
|
(1ULL << WIDX_TRACK_MAIN_COLOUR) |
|
|
(1ULL << WIDX_TRACK_ADDITIONAL_COLOUR) |
|
|
(1ULL << WIDX_TRACK_SUPPORT_COLOUR) |
|
|
(1ULL << WIDX_MAZE_STYLE) |
|
|
(1ULL << WIDX_MAZE_STYLE_DROPDOWN) |
|
|
(1ULL << WIDX_PAINT_INDIVIDUAL_AREA) |
|
|
(1ULL << WIDX_ENTRANCE_STYLE) |
|
|
(1ULL << WIDX_ENTRANCE_STYLE_DROPDOWN) |
|
|
(1ULL << WIDX_VEHICLE_COLOUR_SCHEME_DROPDOWN) |
|
|
(1ULL << WIDX_VEHICLE_COLOUR_INDEX) |
|
|
(1ULL << WIDX_VEHICLE_COLOUR_INDEX_DROPDOWN) |
|
|
(1ULL << WIDX_VEHICLE_MAIN_COLOUR) |
|
|
(1ULL << WIDX_VEHICLE_ADDITIONAL_COLOUR_1) |
|
|
(1ULL << WIDX_VEHICLE_ADDITIONAL_COLOUR_2),
|
|
MAIN_RIDE_ENABLED_WIDGETS |
|
|
(1ULL << WIDX_PLAY_MUSIC) |
|
|
(1ULL << WIDX_MUSIC) |
|
|
(1ULL << WIDX_MUSIC_DROPDOWN),
|
|
MAIN_RIDE_ENABLED_WIDGETS |
|
|
(1ULL << WIDX_SAVE_TRACK_DESIGN) |
|
|
(1ULL << WIDX_SELECT_NEARBY_SCENERY) |
|
|
(1ULL << WIDX_RESET_SELECTION) |
|
|
(1ULL << WIDX_SAVE_DESIGN) |
|
|
(1ULL << WIDX_CANCEL_DESIGN),
|
|
MAIN_RIDE_ENABLED_WIDGETS |
|
|
(1ULL << WIDX_GRAPH_VELOCITY) |
|
|
(1ULL << WIDX_GRAPH_ALTITUDE) |
|
|
(1ULL << WIDX_GRAPH_VERTICAL) |
|
|
(1ULL << WIDX_GRAPH_LATERAL),
|
|
MAIN_RIDE_ENABLED_WIDGETS |
|
|
(1ULL << WIDX_PRIMARY_PRICE_INCREASE) |
|
|
(1ULL << WIDX_PRIMARY_PRICE_DECREASE) |
|
|
(1ULL << WIDX_PRIMARY_PRICE_SAME_THROUGHOUT_PARK) |
|
|
(1ULL << WIDX_SECONDARY_PRICE_INCREASE) |
|
|
(1ULL << WIDX_SECONDARY_PRICE_DECREASE) |
|
|
(1ULL << WIDX_SECONDARY_PRICE_SAME_THROUGHOUT_PARK),
|
|
MAIN_RIDE_ENABLED_WIDGETS |
|
|
(1ULL << WIDX_SHOW_GUESTS_THOUGHTS) |
|
|
(1ULL << WIDX_SHOW_GUESTS_ON_RIDE) |
|
|
(1ULL << WIDX_SHOW_GUESTS_QUEUING),
|
|
};
|
|
|
|
static constexpr const uint64 window_ride_page_hold_down_widgets[] = {
|
|
(1ULL << WIDX_RIDE_TYPE_INCREASE) |
|
|
(1ULL << WIDX_RIDE_TYPE_DECREASE),
|
|
(1ULL << WIDX_VEHICLE_TRAINS_INCREASE) |
|
|
(1ULL << WIDX_VEHICLE_TRAINS_DECREASE) |
|
|
(1ULL << WIDX_VEHICLE_CARS_PER_TRAIN_INCREASE) |
|
|
(1ULL << WIDX_VEHICLE_CARS_PER_TRAIN_DECREASE),
|
|
(1ULL << WIDX_MODE_TWEAK_INCREASE) |
|
|
(1ULL << WIDX_MODE_TWEAK_DECREASE) |
|
|
(1ULL << WIDX_LIFT_HILL_SPEED_INCREASE) |
|
|
(1ULL << WIDX_LIFT_HILL_SPEED_DECREASE) |
|
|
(1ULL << WIDX_MINIMUM_LENGTH_INCREASE) |
|
|
(1ULL << WIDX_MINIMUM_LENGTH_DECREASE) |
|
|
(1ULL << WIDX_MAXIMUM_LENGTH_INCREASE) |
|
|
(1ULL << WIDX_MAXIMUM_LENGTH_DECREASE),
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
(1ULL << WIDX_PRIMARY_PRICE_INCREASE) |
|
|
(1ULL << WIDX_PRIMARY_PRICE_DECREASE) |
|
|
(1ULL << WIDX_SECONDARY_PRICE_INCREASE) |
|
|
(1ULL << WIDX_SECONDARY_PRICE_DECREASE),
|
|
0
|
|
};
|
|
|
|
#pragma endregion
|
|
|
|
#pragma region Events
|
|
|
|
static void window_ride_init_viewport(rct_window *w);
|
|
|
|
static void window_ride_main_mouseup(rct_window *w, rct_widgetindex widgetIndex);
|
|
static void window_ride_main_resize(rct_window *w);
|
|
static void window_ride_main_mousedown(rct_window *w, rct_widgetindex widgetIndex, rct_widget *widget);
|
|
static void window_ride_main_dropdown(rct_window *w, rct_widgetindex widgetIndex, sint32 dropdownIndex);
|
|
static void window_ride_main_update(rct_window *w);
|
|
static void window_ride_main_textinput(rct_window *w, rct_widgetindex widgetIndex, char *text);
|
|
static void window_ride_main_viewport_rotate(rct_window *w);
|
|
static void window_ride_main_invalidate(rct_window *w);
|
|
static void window_ride_main_paint(rct_window *w, rct_drawpixelinfo *dpi);
|
|
|
|
static void window_ride_vehicle_mouseup(rct_window *w, rct_widgetindex widgetIndex);
|
|
static void window_ride_vehicle_resize(rct_window *w);
|
|
static void window_ride_vehicle_mousedown(rct_window *w, rct_widgetindex widgetIndex, rct_widget *widget);
|
|
static void window_ride_vehicle_dropdown(rct_window *w, rct_widgetindex widgetIndex, sint32 dropdownIndex);
|
|
static void window_ride_vehicle_update(rct_window *w);
|
|
static void window_ride_vehicle_invalidate(rct_window *w);
|
|
static void window_ride_vehicle_paint(rct_window *w, rct_drawpixelinfo *dpi);
|
|
static void window_ride_vehicle_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, sint32 scrollIndex);
|
|
|
|
static void window_ride_operating_mouseup(rct_window *w, rct_widgetindex widgetIndex);
|
|
static void window_ride_operating_resize(rct_window *w);
|
|
static void window_ride_operating_mousedown(rct_window *w, rct_widgetindex widgetIndex, rct_widget *widget);
|
|
static void window_ride_operating_dropdown(rct_window *w, rct_widgetindex widgetIndex, sint32 dropdownIndex);
|
|
static void window_ride_operating_update(rct_window *w);
|
|
static void window_ride_operating_invalidate(rct_window *w);
|
|
static void window_ride_operating_paint(rct_window *w, rct_drawpixelinfo *dpi);
|
|
|
|
static void window_ride_maintenance_mouseup(rct_window *w, rct_widgetindex widgetIndex);
|
|
static void window_ride_maintenance_resize(rct_window *w);
|
|
static void window_ride_maintenance_mousedown(rct_window *w, rct_widgetindex widgetIndex, rct_widget *widget);
|
|
static void window_ride_maintenance_dropdown(rct_window *w, rct_widgetindex widgetIndex, sint32 dropdownIndex);
|
|
static void window_ride_maintenance_update(rct_window *w);
|
|
static void window_ride_maintenance_invalidate(rct_window *w);
|
|
static void window_ride_maintenance_paint(rct_window *w, rct_drawpixelinfo *dpi);
|
|
|
|
static void window_ride_colour_close(rct_window *w);
|
|
static void window_ride_colour_mouseup(rct_window *w, rct_widgetindex widgetIndex);
|
|
static void window_ride_colour_resize(rct_window *w);
|
|
static void window_ride_colour_mousedown(rct_window *w, rct_widgetindex widgetIndex, rct_widget *widget);
|
|
static void window_ride_colour_dropdown(rct_window *w, rct_widgetindex widgetIndex, sint32 dropdownIndex);
|
|
static void window_ride_colour_update(rct_window *w);
|
|
static void window_ride_colour_tooldown(rct_window *w, rct_widgetindex widgetIndex, sint32 x, sint32 y);
|
|
static void window_ride_colour_tooldrag(rct_window *w, rct_widgetindex widgetIndex, sint32 x, sint32 y);
|
|
static void window_ride_colour_invalidate(rct_window *w);
|
|
static void window_ride_colour_paint(rct_window *w, rct_drawpixelinfo *dpi);
|
|
static void window_ride_colour_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, sint32 scrollIndex);
|
|
|
|
static void window_ride_music_mouseup(rct_window *w, rct_widgetindex widgetIndex);
|
|
static void window_ride_music_resize(rct_window *w);
|
|
static void window_ride_music_mousedown(rct_window *w, rct_widgetindex widgetIndex, rct_widget *widget);
|
|
static void window_ride_music_dropdown(rct_window *w, rct_widgetindex widgetIndex, sint32 dropdownIndex);
|
|
static void window_ride_music_update(rct_window *w);
|
|
static void window_ride_music_invalidate(rct_window *w);
|
|
static void window_ride_music_paint(rct_window *w, rct_drawpixelinfo *dpi);
|
|
|
|
static void window_ride_measurements_close(rct_window *w);
|
|
static void window_ride_measurements_mouseup(rct_window *w, rct_widgetindex widgetIndex);
|
|
static void window_ride_measurements_resize(rct_window *w);
|
|
static void window_ride_measurements_mousedown(rct_window *w, rct_widgetindex widgetIndex, rct_widget *widget);
|
|
static void window_ride_measurements_dropdown(rct_window *w, rct_widgetindex widgetIndex, sint32 dropdownIndex);
|
|
static void window_ride_measurements_update(rct_window *w);
|
|
static void window_ride_measurements_tooldown(rct_window *w, rct_widgetindex widgetIndex, sint32 x, sint32 y);
|
|
static void window_ride_measurements_tooldrag(rct_window *w, rct_widgetindex widgetIndex, sint32 x, sint32 y);
|
|
static void window_ride_measurements_toolabort(rct_window *w, rct_widgetindex widgetIndex);
|
|
static void window_ride_measurements_invalidate(rct_window *w);
|
|
static void window_ride_measurements_paint(rct_window *w, rct_drawpixelinfo *dpi);
|
|
|
|
static void window_ride_graphs_mouseup(rct_window *w, rct_widgetindex widgetIndex);
|
|
static void window_ride_graphs_resize(rct_window *w);
|
|
static void window_ride_graphs_mousedown(rct_window *w, rct_widgetindex widgetIndex, rct_widget *widget);
|
|
static void window_ride_graphs_update(rct_window *w);
|
|
static void window_ride_graphs_scrollgetheight(rct_window *w, sint32 scrollIndex, sint32 *width, sint32 *height);
|
|
static void window_ride_graphs_15(rct_window *w, sint32 scrollIndex, sint32 scrollAreaType);
|
|
static void window_ride_graphs_tooltip(rct_window* w, rct_widgetindex widgetIndex, rct_string_id *stringId);
|
|
static void window_ride_graphs_invalidate(rct_window *w);
|
|
static void window_ride_graphs_paint(rct_window *w, rct_drawpixelinfo *dpi);
|
|
static void window_ride_graphs_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, sint32 scrollIndex);
|
|
|
|
static void window_ride_income_mouseup(rct_window *w, rct_widgetindex widgetIndex);
|
|
static void window_ride_income_resize(rct_window *w);
|
|
static void window_ride_income_mousedown(rct_window *w, rct_widgetindex widgetIndex, rct_widget *widget);
|
|
static void window_ride_income_update(rct_window *w);
|
|
static void window_ride_income_invalidate(rct_window *w);
|
|
static void window_ride_income_paint(rct_window *w, rct_drawpixelinfo *dpi);
|
|
|
|
static void window_ride_customer_mouseup(rct_window *w, rct_widgetindex widgetIndex);
|
|
static void window_ride_customer_resize(rct_window *w);
|
|
static void window_ride_customer_update(rct_window *w);
|
|
static void window_ride_customer_invalidate(rct_window *w);
|
|
static void window_ride_customer_paint(rct_window *w, rct_drawpixelinfo *dpi);
|
|
|
|
static void window_ride_set_colours();
|
|
static void window_ride_set_page(rct_window *w, sint32 page);
|
|
|
|
// 0x0098DFD4
|
|
static rct_window_event_list window_ride_main_events = {
|
|
nullptr,
|
|
window_ride_main_mouseup,
|
|
window_ride_main_resize,
|
|
window_ride_main_mousedown,
|
|
window_ride_main_dropdown,
|
|
nullptr,
|
|
window_ride_main_update,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
window_ride_main_textinput,
|
|
window_ride_main_viewport_rotate,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
window_ride_main_invalidate,
|
|
window_ride_main_paint,
|
|
nullptr
|
|
};
|
|
|
|
// 0x0098E204
|
|
static rct_window_event_list window_ride_vehicle_events = {
|
|
nullptr,
|
|
window_ride_vehicle_mouseup,
|
|
window_ride_vehicle_resize,
|
|
window_ride_vehicle_mousedown,
|
|
window_ride_vehicle_dropdown,
|
|
nullptr,
|
|
window_ride_vehicle_update,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
window_ride_vehicle_invalidate,
|
|
window_ride_vehicle_paint,
|
|
window_ride_vehicle_scrollpaint
|
|
};
|
|
|
|
// 0x0098E0B4
|
|
static rct_window_event_list window_ride_operating_events = {
|
|
nullptr,
|
|
window_ride_operating_mouseup,
|
|
window_ride_operating_resize,
|
|
window_ride_operating_mousedown,
|
|
window_ride_operating_dropdown,
|
|
nullptr,
|
|
window_ride_operating_update,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
window_ride_operating_invalidate,
|
|
window_ride_operating_paint,
|
|
nullptr
|
|
};
|
|
|
|
// 0x0098E124
|
|
static rct_window_event_list window_ride_maintenance_events = {
|
|
nullptr,
|
|
window_ride_maintenance_mouseup,
|
|
window_ride_maintenance_resize,
|
|
window_ride_maintenance_mousedown,
|
|
window_ride_maintenance_dropdown,
|
|
nullptr,
|
|
window_ride_maintenance_update,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
window_ride_maintenance_invalidate,
|
|
window_ride_maintenance_paint,
|
|
nullptr
|
|
};
|
|
|
|
// 0x0098E044
|
|
static rct_window_event_list window_ride_colour_events = {
|
|
window_ride_colour_close,
|
|
window_ride_colour_mouseup,
|
|
window_ride_colour_resize,
|
|
window_ride_colour_mousedown,
|
|
window_ride_colour_dropdown,
|
|
nullptr,
|
|
window_ride_colour_update,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
window_ride_colour_tooldown,
|
|
window_ride_colour_tooldrag,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
window_ride_colour_invalidate,
|
|
window_ride_colour_paint,
|
|
window_ride_colour_scrollpaint
|
|
};
|
|
|
|
// 0x0098E194
|
|
static rct_window_event_list window_ride_music_events = {
|
|
nullptr,
|
|
window_ride_music_mouseup,
|
|
window_ride_music_resize,
|
|
window_ride_music_mousedown,
|
|
window_ride_music_dropdown,
|
|
nullptr,
|
|
window_ride_music_update,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
window_ride_music_invalidate,
|
|
window_ride_music_paint,
|
|
nullptr
|
|
};
|
|
|
|
// 0x0098DE14
|
|
static rct_window_event_list window_ride_measurements_events = {
|
|
window_ride_measurements_close,
|
|
window_ride_measurements_mouseup,
|
|
window_ride_measurements_resize,
|
|
window_ride_measurements_mousedown,
|
|
window_ride_measurements_dropdown,
|
|
nullptr,
|
|
window_ride_measurements_update,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
window_ride_measurements_tooldown,
|
|
window_ride_measurements_tooldrag,
|
|
nullptr,
|
|
window_ride_measurements_toolabort,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
window_ride_measurements_invalidate,
|
|
window_ride_measurements_paint,
|
|
nullptr
|
|
};
|
|
|
|
// 0x0098DF64
|
|
static rct_window_event_list window_ride_graphs_events = {
|
|
nullptr,
|
|
window_ride_graphs_mouseup,
|
|
window_ride_graphs_resize,
|
|
window_ride_graphs_mousedown,
|
|
nullptr,
|
|
nullptr,
|
|
window_ride_graphs_update,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
window_ride_graphs_scrollgetheight,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
window_ride_graphs_15,
|
|
window_ride_graphs_tooltip,
|
|
nullptr,
|
|
nullptr,
|
|
window_ride_graphs_invalidate,
|
|
window_ride_graphs_paint,
|
|
window_ride_graphs_scrollpaint
|
|
};
|
|
|
|
// 0x0098DEF4
|
|
static rct_window_event_list window_ride_income_events = {
|
|
nullptr,
|
|
window_ride_income_mouseup,
|
|
window_ride_income_resize,
|
|
window_ride_income_mousedown,
|
|
nullptr,
|
|
nullptr,
|
|
window_ride_income_update,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
window_ride_income_invalidate,
|
|
window_ride_income_paint,
|
|
nullptr
|
|
};
|
|
|
|
// 0x0098DE84
|
|
static rct_window_event_list window_ride_customer_events = {
|
|
nullptr,
|
|
window_ride_customer_mouseup,
|
|
window_ride_customer_resize,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
window_ride_customer_update,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
window_ride_customer_invalidate,
|
|
window_ride_customer_paint,
|
|
nullptr
|
|
};
|
|
|
|
static rct_window_event_list *window_ride_page_events[] = {
|
|
&window_ride_main_events,
|
|
&window_ride_vehicle_events,
|
|
&window_ride_operating_events,
|
|
&window_ride_maintenance_events,
|
|
&window_ride_colour_events,
|
|
&window_ride_music_events,
|
|
&window_ride_measurements_events,
|
|
&window_ride_graphs_events,
|
|
&window_ride_income_events,
|
|
&window_ride_customer_events
|
|
};
|
|
|
|
#pragma endregion
|
|
|
|
static uint8 _rideType;
|
|
static bool _collectTrackDesignScenery = false;
|
|
static sint32 _lastSceneryX = 0;
|
|
static sint32 _lastSceneryY = 0;
|
|
|
|
static void set_operating_setting(sint32 rideNumber, uint8 setting, uint8 value);
|
|
|
|
// Cached overall view for each ride
|
|
// (Re)calculated when the ride window is opened
|
|
struct ride_overall_view {
|
|
sint16 x, y, z;
|
|
uint8 zoom;
|
|
};
|
|
|
|
static ride_overall_view ride_overall_views[MAX_RIDES] = {0};
|
|
|
|
static constexpr const sint32 window_ride_tab_animation_divisor[] = { 0, 0, 2, 2, 4, 2, 8, 8, 2, 0 };
|
|
static constexpr const sint32 window_ride_tab_animation_frames[] = { 0, 0, 4, 16, 8, 16, 8, 8, 8, 0 };
|
|
|
|
static constexpr const rct_string_id RatingNames[] = {
|
|
STR_RATING_LOW,
|
|
STR_RATING_MEDIUM,
|
|
STR_RATING_HIGH,
|
|
STR_RATING_VERY_HIGH,
|
|
STR_RATING_EXTREME,
|
|
STR_RATING_ULTRA_EXTREME,
|
|
};
|
|
|
|
static constexpr const rct_string_id RideBreakdownReasonNames[] = {
|
|
STR_RIDE_BREAKDOWN_SAFETY_CUT_OUT ,
|
|
STR_RIDE_BREAKDOWN_RESTRAINTS_STUCK_CLOSED,
|
|
STR_RIDE_BREAKDOWN_RESTRAINTS_STUCK_OPEN,
|
|
STR_RIDE_BREAKDOWN_DOORS_STUCK_CLOSED,
|
|
STR_RIDE_BREAKDOWN_DOORS_STUCK_OPEN,
|
|
STR_RIDE_BREAKDOWN_VEHICLE_MALFUNCTION,
|
|
STR_RIDE_BREAKDOWN_BRAKES_FAILURE,
|
|
STR_RIDE_BREAKDOWN_CONTROL_FAILURE
|
|
};
|
|
|
|
static constexpr const rct_string_id ColourSchemeNames[] = {
|
|
STR_MAIN_COLOUR_SCHEME,
|
|
STR_ALTERNATIVE_COLOUR_SCHEME_1,
|
|
STR_ALTERNATIVE_COLOUR_SCHEME_2,
|
|
STR_ALTERNATIVE_COLOUR_SCHEME_3,
|
|
};
|
|
|
|
static constexpr const rct_string_id VehicleLoadNames[] = {
|
|
STR_QUARTER_LOAD,
|
|
STR_HALF_LOAD,
|
|
STR_THREE_QUARTER_LOAD,
|
|
STR_FULL_LOAD,
|
|
STR_ANY_LOAD,
|
|
};
|
|
|
|
static constexpr const rct_string_id VehicleColourSchemeNames[] = {
|
|
STR_ALL_VEHICLES_IN_SAME_COLOURS ,
|
|
STR_DIFFERENT_COLOURS_PER ,
|
|
STR_DIFFERENT_COLOURS_PER_VEHICLE ,
|
|
};
|
|
|
|
static constexpr const rct_string_id VehicleStatusNames[] = {
|
|
STR_MOVING_TO_END_OF, // VEHICLE_STATUS_MOVING_TO_END_OF_STATION
|
|
STR_WAITING_FOR_PASSENGERS_AT, // VEHICLE_STATUS_WAITING_FOR_PASSENGERS
|
|
STR_WAITING_TO_DEPART, // VEHICLE_STATUS_WAITING_TO_DEPART
|
|
STR_DEPARTING, // VEHICLE_STATUS_DEPARTING
|
|
STR_TRAVELLING_AT_0, // VEHICLE_STATUS_TRAVELLING
|
|
STR_ARRIVING_AT, // VEHICLE_STATUS_ARRIVING
|
|
STR_UNLOADING_PASSENGERS_AT, // VEHICLE_STATUS_UNLOADING_PASSENGERS
|
|
STR_TRAVELLING_AT_1, // VEHICLE_STATUS_TRAVELLING_BOAT
|
|
STR_CRASHING, // VEHICLE_STATUS_CRASHING
|
|
STR_CRASHED_0, // VEHICLE_STATUS_CRASHED
|
|
STR_TRAVELLING_AT_2, // VEHICLE_STATUS_TRAVELLING_DODGEMS
|
|
STR_SWINGING, // VEHICLE_STATUS_SWINGING
|
|
STR_ROTATING_0, // VEHICLE_STATUS_ROTATING
|
|
STR_ROTATING_1, // VEHICLE_STATUS_FERRIS_WHEEL_ROTATING
|
|
STR_OPERATING_0, // VEHICLE_STATUS_SIMULATOR_OPERATING
|
|
STR_SHOWING_FILM, // VEHICLE_STATUS_SHOWING_FILM
|
|
STR_ROTATING_2, // VEHICLE_STATUS_SPACE_RINGS_OPERATING
|
|
STR_OPERATING_1, // VEHICLE_STATUS_TOP_SPIN_OPERATING
|
|
STR_OPERATING_2, // VEHICLE_STATUS_HAUNTED_HOUSE_OPERATING
|
|
STR_DOING_CIRCUS_SHOW, // VEHICLE_STATUS_DOING_CIRCUS_SHOW
|
|
STR_OPERATING_3, // VEHICLE_STATUS_CROOKED_HOUSE_OPERATING
|
|
STR_WAITING_FOR_CABLE_LIFT, // VEHICLE_STATUS_WAITING_FOR_CABLE_LIFT
|
|
STR_TRAVELLING_AT_3, // VEHICLE_STATUS_TRAVELLING_CABLE_LIFT
|
|
STR_STOPPING_0, // VEHICLE_STATUS_STOPPING
|
|
STR_WAITING_FOR_PASSENGERS, // VEHICLE_STATUS_WAITING_FOR_PASSENGERS_17
|
|
STR_WAITING_TO_START, // VEHICLE_STATUS_WAITING_TO_START
|
|
STR_STARTING, // VEHICLE_STATUS_STARTING
|
|
STR_OPERATING, // VEHICLE_STATUS_OPERATING_1A
|
|
STR_STOPPING_1, // VEHICLE_STATUS_STOPPING_1B
|
|
STR_UNLOADING_PASSENGERS, // VEHICLE_STATUS_UNLOADING_PASSENGERS_1C
|
|
STR_STOPPED_BY_BLOCK_BRAKES, // VEHICLE_STATUS_STOPPED_BY_BLOCK_BRAKES
|
|
};
|
|
|
|
static constexpr const rct_string_id SingleSessionVehicleStatusNames[] = {
|
|
STR_STOPPING_0, // VEHICLE_STATUS_MOVING_TO_END_OF_STATION
|
|
STR_WAITING_FOR_PASSENGERS, // VEHICLE_STATUS_WAITING_FOR_PASSENGERS
|
|
STR_WAITING_TO_START, // VEHICLE_STATUS_WAITING_TO_DEPART
|
|
STR_STARTING, // VEHICLE_STATUS_DEPARTING
|
|
STR_OPERATING, // VEHICLE_STATUS_TRAVELLING
|
|
STR_STOPPING_1, // VEHICLE_STATUS_ARRIVING
|
|
STR_UNLOADING_PASSENGERS, // VEHICLE_STATUS_UNLOADING_PASSENGERS
|
|
};
|
|
|
|
static constexpr const rct_string_id MusicStyleNames[] = {
|
|
STR_MUSIC_STYLE_DODGEMS_BEAT,
|
|
STR_MUSIC_STYLE_FAIRGROUND_ORGAN,
|
|
STR_MUSIC_STYLE_ROMAN_FANFARE,
|
|
STR_MUSIC_STYLE_ORIENTAL,
|
|
STR_MUSIC_STYLE_MARTIAN,
|
|
STR_MUSIC_STYLE_JUNGLE_DRUMS,
|
|
STR_MUSIC_STYLE_EGYPTIAN,
|
|
STR_MUSIC_STYLE_TOYLAND,
|
|
STR_MUSIC_STYLE_CIRCUS_SHOW,
|
|
STR_MUSIC_STYLE_SPACE,
|
|
STR_MUSIC_STYLE_HORROR,
|
|
STR_MUSIC_STYLE_TECHNO,
|
|
STR_MUSIC_STYLE_GENTLE,
|
|
STR_MUSIC_STYLE_SUMMER,
|
|
STR_MUSIC_STYLE_WATER,
|
|
STR_MUSIC_STYLE_WILD_WEST,
|
|
STR_MUSIC_STYLE_JURASSIC,
|
|
STR_MUSIC_STYLE_ROCK,
|
|
STR_MUSIC_STYLE_RAGTIME,
|
|
STR_MUSIC_STYLE_FANTASY,
|
|
STR_MUSIC_STYLE_ROCK_STYLE_2,
|
|
STR_MUSIC_STYLE_ICE,
|
|
STR_MUSIC_STYLE_SNOW,
|
|
STR_MUSIC_STYLE_CUSTOM_MUSIC_1,
|
|
STR_MUSIC_STYLE_CUSTOM_MUSIC_2,
|
|
STR_MUSIC_STYLE_MEDIEVAL,
|
|
STR_MUSIC_STYLE_URBAN,
|
|
STR_MUSIC_STYLE_ORGAN,
|
|
STR_MUSIC_STYLE_MECHANICAL,
|
|
STR_MUSIC_STYLE_MODERN,
|
|
STR_MUSIC_STYLE_PIRATES,
|
|
STR_MUSIC_STYLE_ROCK_STYLE_3,
|
|
STR_MUSIC_STYLE_CANDY_STYLE,
|
|
};
|
|
|
|
struct window_ride_maze_design_option {
|
|
rct_string_id text;
|
|
uint32 sprite;
|
|
};
|
|
|
|
static constexpr const window_ride_maze_design_option MazeOptions[] = {
|
|
{ STR_RIDE_DESIGN_MAZE_BRICK_WALLS, SPR_RIDE_DESIGN_PREVIEW_MAZE_BRICK_WALLS },
|
|
{ STR_RIDE_DESIGN_MAZE_HEDGES, SPR_RIDE_DESIGN_PREVIEW_MAZE_HEDGES },
|
|
{ STR_RIDE_DESIGN_MAZE_ICE_BLOCKS, SPR_RIDE_DESIGN_PREVIEW_MAZE_ICE_BLOCKS },
|
|
{ STR_RIDE_DESIGN_MAZE_WOODEN_FENCES, SPR_RIDE_DESIGN_PREVIEW_MAZE_WOODEN_FENCES },
|
|
};
|
|
|
|
struct window_ride_colour_preview
|
|
{
|
|
uint32 track;
|
|
uint32 supports;
|
|
};
|
|
|
|
static constexpr const window_ride_colour_preview TrackColourPreviews[] = {
|
|
{ SPR_RIDE_DESIGN_PREVIEW_SPIRAL_ROLLER_COASTER_TRACK, SPR_RIDE_DESIGN_PREVIEW_SPIRAL_ROLLER_COASTER_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_STAND_UP_ROLLER_COASTER_TRACK, SPR_RIDE_DESIGN_PREVIEW_STAND_UP_ROLLER_COASTER_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_SUSPENDED_SWINGING_COASTER_TRACK, SPR_RIDE_DESIGN_PREVIEW_SUSPENDED_SWINGING_COASTER_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_INVERTED_ROLLER_COASTER_TRACK, SPR_RIDE_DESIGN_PREVIEW_INVERTED_ROLLER_COASTER_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_JUNIOR_ROLLER_COASTER_TRACK, SPR_RIDE_DESIGN_PREVIEW_JUNIOR_ROLLER_COASTER_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_MINIATURE_RAILWAY_TRACK, SPR_RIDE_DESIGN_PREVIEW_MINIATURE_RAILWAY_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_MONORAIL_TRACK, SPR_RIDE_DESIGN_PREVIEW_MONORAIL_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_MINI_SUSPENDED_COASTER_TRACK, SPR_RIDE_DESIGN_PREVIEW_MINI_SUSPENDED_COASTER_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_BOAT_HIRE_TRACK, SPR_RIDE_DESIGN_PREVIEW_BOAT_HIRE_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_WOODEN_WILD_MOUSE_TRACK, SPR_RIDE_DESIGN_PREVIEW_WOODEN_WILD_MOUSE_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_STEEPLECHASE_TRACK, SPR_RIDE_DESIGN_PREVIEW_STEEPLECHASE_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_CAR_RIDE_TRACK, SPR_RIDE_DESIGN_PREVIEW_CAR_RIDE_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_LAUNCHED_FREEFALL_TRACK, SPR_RIDE_DESIGN_PREVIEW_LAUNCHED_FREEFALL_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_BOBSLEIGH_COASTER_TRACK, SPR_RIDE_DESIGN_PREVIEW_BOBSLEIGH_COASTER_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_OBSERVATION_TOWER_TRACK, SPR_RIDE_DESIGN_PREVIEW_OBSERVATION_TOWER_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_LOOPING_ROLLER_COASTER_TRACK, SPR_RIDE_DESIGN_PREVIEW_LOOPING_ROLLER_COASTER_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_DINGHY_SLIDE_TRACK, SPR_RIDE_DESIGN_PREVIEW_DINGHY_SLIDE_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_MINE_TRAIN_COASTER_TRACK, SPR_RIDE_DESIGN_PREVIEW_MINE_TRAIN_COASTER_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_CHAIRLIFT_TRACK, SPR_RIDE_DESIGN_PREVIEW_CHAIRLIFT_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_CORKSCREW_ROLLER_COASTER_TRACK, SPR_RIDE_DESIGN_PREVIEW_CORKSCREW_ROLLER_COASTER_SUPPORTS},
|
|
{ 0, 0 }, // MAZE
|
|
{ SPR_RIDE_DESIGN_PREVIEW_SPIRAL_SLIDE_TRACK, 0},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_GO_KARTS_TRACK, SPR_RIDE_DESIGN_PREVIEW_GO_KARTS_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_LOG_FLUME_TRACK, SPR_RIDE_DESIGN_PREVIEW_LOG_FLUME_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_RIVER_RAPIDS_TRACK, SPR_RIDE_DESIGN_PREVIEW_RIVER_RAPIDS_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_DODGEMS_TRACK, SPR_RIDE_DESIGN_PREVIEW_DODGEMS_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_PIRATE_SHIP_TRACK, SPR_RIDE_DESIGN_PREVIEW_PIRATE_SHIP_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_SWINGING_INVERTER_SHIP_TRACK, SPR_RIDE_DESIGN_PREVIEW_SWINGING_INVERTER_SHIP_SUPPORTS},
|
|
{ 0, 0 }, // FOOD_STALL
|
|
{ 0, 0 }, // 1D
|
|
{ 0, 0 }, // DRINK_STALL
|
|
{ 0, 0 }, // 1F
|
|
{ 0, 0 }, // SHOP
|
|
{ 0, 0 }, // MERRY_GO_ROUND
|
|
{ 0, 0 }, // 22
|
|
{ 0, 0 }, // INFORMATION_KIOSK
|
|
{ 0, 0 }, // TOILETS
|
|
{ SPR_RIDE_DESIGN_PREVIEW_FERRIS_WHEEL_TRACK, 0},
|
|
{ 0, 0 }, // MOTION_SIMULATOR
|
|
{ 0, 0 }, // 3D_CINEMA
|
|
{ SPR_RIDE_DESIGN_PREVIEW_TOP_SPIN_TRACK, 0},
|
|
{ 0, 0 }, // SPACE_RINGS
|
|
{ SPR_RIDE_DESIGN_PREVIEW_REVERSE_FREEFALL_COASTER_TRACK, SPR_RIDE_DESIGN_PREVIEW_REVERSE_FREEFALL_COASTER_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_LIFT_TRACK, 0},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_VERTICAL_DROP_ROLLER_COASTER_TRACK, SPR_RIDE_DESIGN_PREVIEW_VERTICAL_DROP_ROLLER_COASTER_SUPPORTS},
|
|
{ 0, 0 }, // CASH_MACHINE
|
|
{ 0, 0 }, // TWIST_TRACK
|
|
{ 0, 0 }, // HAUNTED_HOUSE
|
|
{ 0, 0 }, // FIRST_AID
|
|
{ 0, 0 }, // CIRCUS_SHOW
|
|
{ SPR_RIDE_DESIGN_PREVIEW_GHOST_TRAIN_TRACK, SPR_RIDE_DESIGN_PREVIEW_GHOST_TRAIN_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_TWISTER_ROLLER_COASTER_TRACK, SPR_RIDE_DESIGN_PREVIEW_TWISTER_ROLLER_COASTER_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_WOODEN_ROLLER_COASTER_TRACK, SPR_RIDE_DESIGN_PREVIEW_WOODEN_ROLLER_COASTER_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_SIDE_FRICTION_ROLLER_COASTER_TRACK, SPR_RIDE_DESIGN_PREVIEW_SIDE_FRICTION_ROLLER_COASTER_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_WILD_MOUSE_TRACK, SPR_RIDE_DESIGN_PREVIEW_WILD_MOUSE_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_MULTI_DIMENSION_ROLLER_COASTER_TRACK, SPR_RIDE_DESIGN_PREVIEW_MULTI_DIMENSION_ROLLER_COASTER_SUPPORTS},
|
|
{ 0, 0 }, // 38
|
|
{ SPR_RIDE_DESIGN_PREVIEW_FLYING_ROLLER_COASTER_TRACK, SPR_RIDE_DESIGN_PREVIEW_FLYING_ROLLER_COASTER_SUPPORTS},
|
|
{ 0, 0 }, // 3A
|
|
{ SPR_RIDE_DESIGN_PREVIEW_VIRGINIA_REEL_TRACK, SPR_RIDE_DESIGN_PREVIEW_VIRGINIA_REEL_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_SPLASH_BOATS_TRACK, SPR_RIDE_DESIGN_PREVIEW_SPLASH_BOATS_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_MINI_HELICOPTERS_TRACK, SPR_RIDE_DESIGN_PREVIEW_MINI_HELICOPTERS_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_LAY_DOWN_ROLLER_COASTER_TRACK, SPR_RIDE_DESIGN_PREVIEW_LAY_DOWN_ROLLER_COASTER_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_SUSPENDED_MONORAIL_TRACK, SPR_RIDE_DESIGN_PREVIEW_SUSPENDED_MONORAIL_SUPPORTS},
|
|
{ 0, 0 }, // 40
|
|
{ SPR_RIDE_DESIGN_PREVIEW_REVERSER_ROLLER_COASTER_TRACK, SPR_RIDE_DESIGN_PREVIEW_REVERSER_ROLLER_COASTER_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_HEARTLINE_TWISTER_COASTER_TRACK, SPR_RIDE_DESIGN_PREVIEW_HEARTLINE_TWISTER_COASTER_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_MINI_GOLF_TRACK, SPR_RIDE_DESIGN_PREVIEW_MINI_GOLF_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_GIGA_COASTER_TRACK, SPR_RIDE_DESIGN_PREVIEW_GIGA_COASTER_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_ROTO_DROP_TRACK, SPR_RIDE_DESIGN_PREVIEW_ROTO_DROP_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_FLYING_SAUCERS_TRACK, 0},
|
|
{ 0, 0 }, // CROOKED_HOUSE
|
|
{ SPR_RIDE_DESIGN_PREVIEW_MONORAIL_CYCLES_TRACK, SPR_RIDE_DESIGN_PREVIEW_MONORAIL_CYCLES_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_COMPACT_INVERTED_COASTER_TRACK, SPR_RIDE_DESIGN_PREVIEW_COMPACT_INVERTED_COASTER_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_WATER_COASTER_TRACK, SPR_RIDE_DESIGN_PREVIEW_WATER_COASTER_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_AIR_POWERED_VERTICAL_COASTER_TRACK, SPR_RIDE_DESIGN_PREVIEW_AIR_POWERED_VERTICAL_COASTER_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_INVERTED_HAIRPIN_COASTER_TRACK, SPR_RIDE_DESIGN_PREVIEW_INVERTED_HAIRPIN_COASTER_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_MAGIC_CARPET_TRACK, SPR_RIDE_DESIGN_PREVIEW_MAGIC_CARPET_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_SUBMARINE_RIDE_TRACK, SPR_RIDE_DESIGN_PREVIEW_SUBMARINE_RIDE_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_RIVER_RAFTS_TRACK, SPR_RIDE_DESIGN_PREVIEW_RIVER_RAFTS_SUPPORTS},
|
|
{ 0, 0 }, // 50
|
|
{ 0, 0 }, // ENTERPRISE
|
|
{ 0, 0 }, // 52
|
|
{ 0, 0 }, // 53
|
|
{ 0, 0 }, // 54
|
|
{ 0, 0 }, // 55
|
|
{ SPR_RIDE_DESIGN_PREVIEW_INVERTED_IMPULSE_COASTER_TRACK, SPR_RIDE_DESIGN_PREVIEW_INVERTED_IMPULSE_COASTER_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_MINI_ROLLER_COASTER_TRACK, SPR_RIDE_DESIGN_PREVIEW_MINI_ROLLER_COASTER_SUPPORTS},
|
|
{ SPR_RIDE_DESIGN_PREVIEW_MINE_RIDE_TRACK, SPR_RIDE_DESIGN_PREVIEW_MINE_RIDE_SUPPORTS},
|
|
{ 0, 0 }, // 59
|
|
{ SPR_RIDE_DESIGN_PREVIEW_LIM_LAUNCHED_ROLLER_COASTER_TRACK, SPR_RIDE_DESIGN_PREVIEW_LIM_LAUNCHED_ROLLER_COASTER_SUPPORTS},
|
|
};
|
|
|
|
struct rct_window_graphs_y_axis {
|
|
uint8 interval;
|
|
sint8 unit;
|
|
sint8 unit_interval;
|
|
rct_string_id label;
|
|
};
|
|
|
|
/** rct2: 0x0098DD98 */
|
|
static constexpr const rct_window_graphs_y_axis window_graphs_y_axi[] = {
|
|
{11, 0, 10, STR_RIDE_STATS_VELOCITY_FORMAT}, // GRAPH_VELOCITY
|
|
{10, 0, 15, STR_RIDE_STATS_ALTITUDE_FORMAT}, // GRAPH_ALTITUDE
|
|
{13, -3, 1, STR_RIDE_STATS_G_FORCE_FORMAT}, // GRAPH_VERTICAL
|
|
{13, -4, 1, STR_RIDE_STATS_G_FORCE_FORMAT}, // GRAPH_LATERAL
|
|
};
|
|
|
|
static void window_ride_draw_tab_image(rct_drawpixelinfo *dpi, rct_window *w, sint32 page, sint32 spriteIndex)
|
|
{
|
|
rct_widgetindex widgetIndex = WIDX_TAB_1 + page;
|
|
|
|
if (!(w->disabled_widgets & (1LL << widgetIndex))) {
|
|
if (w->page == page) {
|
|
sint32 frame = w->frame_no / window_ride_tab_animation_divisor[w->page];
|
|
spriteIndex += (frame % window_ride_tab_animation_frames[w->page]);
|
|
}
|
|
|
|
gfx_draw_sprite(dpi, spriteIndex, w->x + w->widgets[widgetIndex].left, w->y + w->widgets[widgetIndex].top, 0);
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B2E88
|
|
*/
|
|
static void window_ride_draw_tab_main(rct_drawpixelinfo *dpi, rct_window *w)
|
|
{
|
|
rct_widgetindex widgetIndex = WIDX_TAB_1 + WINDOW_RIDE_PAGE_MAIN;
|
|
|
|
if (!(w->disabled_widgets & (1LL << widgetIndex))) {
|
|
sint32 spriteIndex = 0;
|
|
sint32 rideType = get_ride(w->number)->type;
|
|
|
|
switch (gRideClassifications[rideType]) {
|
|
case RIDE_CLASS_RIDE:
|
|
spriteIndex = SPR_TAB_RIDE_0;
|
|
if (w->page == WINDOW_RIDE_PAGE_MAIN)
|
|
spriteIndex += (w->frame_no / 4) % 16;
|
|
break;
|
|
case RIDE_CLASS_SHOP_OR_STALL:
|
|
spriteIndex = SPR_TAB_SHOPS_AND_STALLS_0;
|
|
if (w->page == WINDOW_RIDE_PAGE_MAIN)
|
|
spriteIndex += (w->frame_no / 4) % 16;
|
|
break;
|
|
case RIDE_CLASS_KIOSK_OR_FACILITY:
|
|
spriteIndex = SPR_TAB_KIOSKS_AND_FACILITIES_0;
|
|
if (w->page == WINDOW_RIDE_PAGE_MAIN)
|
|
spriteIndex += (w->frame_no / 4) % 8;
|
|
break;
|
|
}
|
|
|
|
gfx_draw_sprite(dpi, spriteIndex, w->x + w->widgets[widgetIndex].left, w->y + w->widgets[widgetIndex].top, 0);
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B2B68
|
|
*/
|
|
static void window_ride_draw_tab_vehicle(rct_drawpixelinfo *dpi, rct_window *w)
|
|
{
|
|
rct_widgetindex widgetIndex = WIDX_TAB_1 + WINDOW_RIDE_PAGE_VEHICLE;
|
|
rct_widget *widget = &w->widgets[widgetIndex];
|
|
|
|
if (!(w->disabled_widgets & (1LL << widgetIndex))) {
|
|
sint32 x = widget->left + 1;
|
|
sint32 y = widget->top + 1;
|
|
sint32 width = widget->right - x;
|
|
sint32 height = widget->bottom - 3 - y;
|
|
if (w->page == WINDOW_RIDE_PAGE_VEHICLE)
|
|
height += 4;
|
|
|
|
x += w->x;
|
|
y += w->y;
|
|
|
|
rct_drawpixelinfo clipDPI;
|
|
if (!clip_drawpixelinfo(&clipDPI, dpi, x, y, width, height)) {
|
|
return;
|
|
}
|
|
|
|
x = (widget->right - widget->left) / 2;
|
|
y = (widget->bottom - widget->top) - 12;
|
|
|
|
Ride *ride = get_ride(w->number);
|
|
|
|
rct_ride_entry *rideEntry = get_ride_entry_by_ride(ride);
|
|
if (rideEntry->flags & RIDE_ENTRY_FLAG_VEHICLE_TAB_SCALE_HALF) {
|
|
clipDPI.zoom_level = 1;
|
|
clipDPI.width *= 2;
|
|
clipDPI.height *= 2;
|
|
x *= 2;
|
|
y *= 2;
|
|
clipDPI.x *= 2;
|
|
clipDPI.y *= 2;
|
|
}
|
|
|
|
// For any suspended rides, move image higher in the vehicle tab on the rides window
|
|
if (ride->type == RIDE_TYPE_COMPACT_INVERTED_COASTER
|
|
|| ride->type == RIDE_TYPE_INVERTED_ROLLER_COASTER
|
|
|| ride->type == RIDE_TYPE_INVERTED_IMPULSE_COASTER
|
|
|| ride->type == RIDE_TYPE_INVERTED_HAIRPIN_COASTER
|
|
|| ride->type == RIDE_TYPE_SUSPENDED_SWINGING_COASTER
|
|
|| ride->type == RIDE_TYPE_CHAIRLIFT
|
|
|| ride->type == RIDE_TYPE_MINI_SUSPENDED_COASTER
|
|
|| ride->type == RIDE_TYPE_SUSPENDED_MONORAIL)
|
|
{
|
|
y /= 4;
|
|
}
|
|
|
|
const uint8 vehicle = ride_entry_get_vehicle_at_position(ride->subtype, ride->num_cars_per_train, rideEntry->tab_vehicle);
|
|
rct_ride_entry_vehicle* rideVehicleEntry = &rideEntry->vehicles[vehicle];
|
|
|
|
vehicle_colour vehicleColour = ride_get_vehicle_colour(ride, 0);
|
|
sint32 spriteIndex = 32;
|
|
if (w->page == WINDOW_RIDE_PAGE_VEHICLE)
|
|
spriteIndex += w->frame_no;
|
|
spriteIndex /= (rideVehicleEntry->flags & VEHICLE_ENTRY_FLAG_11) ? 4 : 2;
|
|
spriteIndex &= rideVehicleEntry->rotation_frame_mask;
|
|
spriteIndex *= rideVehicleEntry->base_num_frames;
|
|
spriteIndex += rideVehicleEntry->base_image_id;
|
|
spriteIndex |= (vehicleColour.additional_1 << 24) | (vehicleColour.main << 19);
|
|
spriteIndex |= IMAGE_TYPE_REMAP_2_PLUS;
|
|
|
|
gfx_draw_sprite(&clipDPI, spriteIndex, x, y, vehicleColour.additional_2);
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B2F42
|
|
*/
|
|
static void window_ride_draw_tab_customer(rct_drawpixelinfo *dpi, rct_window *w)
|
|
{
|
|
rct_widgetindex widgetIndex = WIDX_TAB_1 + WINDOW_RIDE_PAGE_CUSTOMER;
|
|
|
|
if (!(w->disabled_widgets & (1LL << widgetIndex))) {
|
|
rct_widget *widget = &w->widgets[widgetIndex];
|
|
sint32 spriteIndex = 0;
|
|
if (w->page == WINDOW_RIDE_PAGE_CUSTOMER)
|
|
spriteIndex = w->var_492 & ~3;
|
|
|
|
spriteIndex += g_peep_animation_entries[PEEP_SPRITE_TYPE_NORMAL].sprite_animation->base_image;
|
|
spriteIndex += 1;
|
|
spriteIndex |= 0xA9E00000;
|
|
|
|
gfx_draw_sprite(dpi, spriteIndex, w->x + (widget->left + widget->right) / 2, w->y + widget->bottom - 6, 0);
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B2B35
|
|
*/
|
|
static void window_ride_draw_tab_images(rct_drawpixelinfo *dpi, rct_window *w)
|
|
{
|
|
window_ride_draw_tab_vehicle(dpi, w);
|
|
window_ride_draw_tab_image(dpi, w, WINDOW_RIDE_PAGE_OPERATING, SPR_TAB_GEARS_0);
|
|
window_ride_draw_tab_image(dpi, w, WINDOW_RIDE_PAGE_MAINTENANCE, SPR_TAB_WRENCH_0);
|
|
window_ride_draw_tab_image(dpi, w, WINDOW_RIDE_PAGE_INCOME, SPR_TAB_ADMISSION_0);
|
|
window_ride_draw_tab_main(dpi, w);
|
|
window_ride_draw_tab_image(dpi, w, WINDOW_RIDE_PAGE_MEASUREMENTS, SPR_TAB_TIMER_0);
|
|
window_ride_draw_tab_image(dpi, w, WINDOW_RIDE_PAGE_COLOUR, SPR_TAB_PAINT_0);
|
|
window_ride_draw_tab_image(dpi, w, WINDOW_RIDE_PAGE_GRAPHS, SPR_TAB_GRAPH_A_0);
|
|
window_ride_draw_tab_customer(dpi, w);
|
|
window_ride_draw_tab_image(dpi, w, WINDOW_RIDE_PAGE_MUSIC, SPR_TAB_MUSIC_0);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AEB9F
|
|
*/
|
|
static void window_ride_disable_tabs(rct_window *w)
|
|
{
|
|
uint32 disabled_tabs = 0;
|
|
Ride *ride = get_ride(w->number & 0xFF);
|
|
|
|
uint8 ride_type = ride->type; // ecx
|
|
|
|
if (!ride_type_has_flag(ride_type, RIDE_TYPE_FLAG_HAS_DATA_LOGGING))
|
|
disabled_tabs |= (1 << WIDX_TAB_8); // 0x800
|
|
|
|
if (ride_type == RIDE_TYPE_MINI_GOLF)
|
|
disabled_tabs |= (1 << WIDX_TAB_2 | 1 << WIDX_TAB_3 | 1 << WIDX_TAB_4); // 0xE0
|
|
|
|
if (ride_type_has_flag(ride_type, RIDE_TYPE_FLAG_NO_VEHICLES))
|
|
disabled_tabs |= (1 << WIDX_TAB_2); // 0x20
|
|
|
|
if (
|
|
!ride_type_has_flag(ride_type, RIDE_TYPE_FLAG_HAS_TRACK_COLOUR_MAIN) &&
|
|
!ride_type_has_flag(ride_type, RIDE_TYPE_FLAG_HAS_TRACK_COLOUR_ADDITIONAL) &&
|
|
!ride_type_has_flag(ride_type, RIDE_TYPE_FLAG_HAS_TRACK_COLOUR_SUPPORTS) &&
|
|
!ride_type_has_flag(ride_type, RIDE_TYPE_FLAG_HAS_VEHICLE_COLOURS) &&
|
|
!(RideData4[ride->type].flags & RIDE_TYPE_FLAG4_HAS_ENTRANCE_EXIT)
|
|
) {
|
|
disabled_tabs |= (1 << WIDX_TAB_5); // 0x100
|
|
}
|
|
|
|
if (ride_type_has_flag(ride_type, RIDE_TYPE_FLAG_IS_SHOP))
|
|
disabled_tabs |= (1 << WIDX_TAB_3 | 1 << WIDX_TAB_4 | 1 << WIDX_TAB_7); // 0x4C0
|
|
|
|
if (!(RideData4[ride->type].flags & RIDE_TYPE_FLAG4_ALLOW_MUSIC)) {
|
|
disabled_tabs |= (1 << WIDX_TAB_6); // 0x200
|
|
}
|
|
|
|
if (ride_type == RIDE_TYPE_CASH_MACHINE ||
|
|
ride_type == RIDE_TYPE_FIRST_AID ||
|
|
(gParkFlags & PARK_FLAGS_NO_MONEY) != 0)
|
|
disabled_tabs |= (1 << WIDX_TAB_9); // 0x1000
|
|
|
|
if ((gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER) != 0)
|
|
disabled_tabs |= (1 << WIDX_TAB_4 | 1 << WIDX_TAB_6 | 1 << WIDX_TAB_9 | 1 << WIDX_TAB_10); // 0x3280
|
|
|
|
rct_ride_entry * rideEntry = get_ride_entry(ride->subtype);
|
|
|
|
if (rideEntry == nullptr)
|
|
{
|
|
disabled_tabs |= 1 << WIDX_TAB_2 | 1 << WIDX_TAB_3 | 1 << WIDX_TAB_4 | 1 << WIDX_TAB_5 | 1 << WIDX_TAB_6
|
|
| 1 << WIDX_TAB_7 | 1 << WIDX_TAB_8 | 1 << WIDX_TAB_9 | 1 << WIDX_TAB_10;
|
|
}
|
|
else if ((rideEntry->flags & RIDE_ENTRY_FLAG_DISABLE_COLOUR_TAB) != 0)
|
|
{
|
|
disabled_tabs |= (1 << WIDX_TAB_5);
|
|
}
|
|
|
|
w->disabled_widgets = disabled_tabs;
|
|
}
|
|
|
|
static void window_ride_update_overall_view(uint8 ride_index) {
|
|
// Calculate x, y, z bounds of the entire ride using its track elements
|
|
tile_element_iterator it;
|
|
|
|
tile_element_iterator_begin(&it);
|
|
|
|
sint32 minx = std::numeric_limits<sint32>::max(), miny = std::numeric_limits<sint32>::max(), minz = std::numeric_limits<sint32>::max();
|
|
sint32 maxx = std::numeric_limits<sint32>::min(), maxy = std::numeric_limits<sint32>::min(), maxz = std::numeric_limits<sint32>::min();
|
|
|
|
while (tile_element_iterator_next(&it)) {
|
|
if (tile_element_get_type(it.element) != TILE_ELEMENT_TYPE_TRACK)
|
|
continue;
|
|
|
|
if (track_element_get_ride_index(it.element) != ride_index)
|
|
continue;
|
|
|
|
sint32 x = it.x * 32;
|
|
sint32 y = it.y * 32;
|
|
sint32 z1 = it.element->base_height * 8;
|
|
sint32 z2 = it.element->clearance_height * 8;
|
|
|
|
minx = Math::Min(minx, x);
|
|
miny = Math::Min(miny, y);
|
|
minz = Math::Min(minz, z1);
|
|
|
|
maxx = Math::Max(maxx, x);
|
|
maxy = Math::Max(maxy, y);
|
|
maxz = Math::Max(maxz, z2);
|
|
}
|
|
|
|
ride_overall_view *view = &ride_overall_views[ride_index];
|
|
view->x = (minx + maxx) / 2 + 16;
|
|
view->y = (miny + maxy) / 2 + 16;
|
|
view->z = (minz + maxz) / 2 - 8;
|
|
|
|
// Calculate size to determine from how far away to view the ride
|
|
sint32 dx = maxx - minx;
|
|
sint32 dy = maxy - miny;
|
|
sint32 dz = maxz - minz;
|
|
|
|
sint32 size = (sint32) sqrt(dx*dx + dy*dy + dz*dz);
|
|
|
|
if (size >= 80)
|
|
{
|
|
// Each farther zoom level shows twice as many tiles (log)
|
|
// Appropriate zoom is lowered by one to fill the entire view with the ride
|
|
view->zoom = Math::Clamp(0, (sint32) ceil(log(size / 80)) - 1, 3);
|
|
}
|
|
else
|
|
{
|
|
// Small rides or stalls are zoomed in all the way.
|
|
view->zoom = 0;
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AEAB4
|
|
*/
|
|
static rct_window *window_ride_open(sint32 rideIndex)
|
|
{
|
|
rct_window *w;
|
|
Ride *ride;
|
|
|
|
w = window_create_auto_pos(316, 207, window_ride_page_events[0], WC_RIDE, WF_10 | WF_RESIZABLE);
|
|
w->widgets = window_ride_page_widgets[WINDOW_RIDE_PAGE_MAIN];
|
|
w->enabled_widgets = window_ride_page_enabled_widgets[WINDOW_RIDE_PAGE_MAIN];
|
|
w->hold_down_widgets = window_ride_page_hold_down_widgets[WINDOW_RIDE_PAGE_MAIN];
|
|
w->number = rideIndex;
|
|
|
|
w->page = WINDOW_RIDE_PAGE_MAIN;
|
|
w->vehicleIndex = 0;
|
|
w->frame_no = 0;
|
|
w->list_information_type = 0;
|
|
w->var_492 = 0;
|
|
w->ride_colour = 0;
|
|
window_ride_disable_tabs(w);
|
|
w->min_width = 316;
|
|
w->min_height = 180;
|
|
w->max_width = 500;
|
|
w->max_height = 450;
|
|
|
|
ride = get_ride(rideIndex);
|
|
_rideType = ride->type;
|
|
|
|
window_ride_update_overall_view((uint8) rideIndex);
|
|
|
|
return w;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006ACC28
|
|
*/
|
|
rct_window *window_ride_main_open(sint32 rideIndex)
|
|
{
|
|
rct_window *w;
|
|
|
|
w = window_bring_to_front_by_number(WC_RIDE, rideIndex);
|
|
if (w == nullptr) {
|
|
w = window_ride_open(rideIndex);
|
|
w->ride.var_482 = -1;
|
|
}
|
|
|
|
if (input_test_flag(INPUT_FLAG_TOOL_ACTIVE)) {
|
|
if (w->classification == gCurrentToolWidget.window_classification &&
|
|
w->number == gCurrentToolWidget.window_number
|
|
) {
|
|
tool_cancel();
|
|
}
|
|
}
|
|
|
|
if (w->page != WINDOW_RIDE_PAGE_MAIN) {
|
|
window_ride_set_page(w, WINDOW_RIDE_PAGE_MAIN);
|
|
}
|
|
|
|
w->ride.view = 0;
|
|
window_ride_init_viewport(w);
|
|
return w;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006ACCCE
|
|
*/
|
|
static rct_window * window_ride_open_station(sint32 rideIndex, sint32 stationIndex)
|
|
{
|
|
sint32 i;
|
|
Ride *ride;
|
|
rct_window *w;
|
|
|
|
ride = get_ride(rideIndex);
|
|
|
|
if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_NO_VEHICLES))
|
|
return window_ride_main_open(rideIndex);
|
|
|
|
w = window_bring_to_front_by_number(WC_RIDE, rideIndex);
|
|
if (w == nullptr) {
|
|
w = window_ride_open(rideIndex);
|
|
w->ride.var_482 = -1;
|
|
}
|
|
|
|
if (
|
|
input_test_flag(INPUT_FLAG_TOOL_ACTIVE) &&
|
|
gCurrentToolWidget.window_classification == w->classification &&
|
|
gCurrentToolWidget.window_number == w->number
|
|
) {
|
|
tool_cancel();
|
|
}
|
|
_rideType = ride->type;
|
|
|
|
w->page = WINDOW_RIDE_PAGE_MAIN;
|
|
w->width = 316;
|
|
w->height = 180;
|
|
window_invalidate(w);
|
|
|
|
w->widgets = window_ride_page_widgets[w->page];
|
|
w->enabled_widgets = window_ride_page_enabled_widgets[w->page];
|
|
w->hold_down_widgets = window_ride_page_hold_down_widgets[w->page];
|
|
w->event_handlers = window_ride_page_events[w->page];
|
|
w->pressed_widgets = 0;
|
|
window_ride_disable_tabs(w);
|
|
window_init_scroll_widgets(w);
|
|
|
|
// View
|
|
for (i = stationIndex; i >= 0; i--)
|
|
{
|
|
if (ride->station_starts[i].xy == RCT_XY8_UNDEFINED)
|
|
{
|
|
stationIndex--;
|
|
}
|
|
}
|
|
|
|
w->ride.view = 1 + ride->num_vehicles + stationIndex;
|
|
window_ride_init_viewport(w);
|
|
|
|
return w;
|
|
}
|
|
|
|
rct_window *window_ride_open_track(rct_tile_element *tileElement)
|
|
{
|
|
sint32 rideIndex = track_element_get_ride_index(tileElement);
|
|
if (
|
|
(tile_element_get_type(tileElement) == TILE_ELEMENT_TYPE_ENTRANCE) ||
|
|
(TrackSequenceProperties[track_element_get_type(tileElement)][0] & TRACK_SEQUENCE_FLAG_ORIGIN)
|
|
) {
|
|
// Open ride window in station view
|
|
return window_ride_open_station(rideIndex, tile_element_get_station(tileElement));
|
|
} else {
|
|
// Open ride window in overview mode.
|
|
return window_ride_main_open(rideIndex);
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006ACAC2
|
|
*/
|
|
rct_window *window_ride_open_vehicle(rct_vehicle *vehicle)
|
|
{
|
|
rct_vehicle *headVehicle = vehicle_get_head(vehicle);
|
|
uint16 headVehicleSpriteIndex = headVehicle->sprite_index;
|
|
sint32 rideIndex = headVehicle->ride;
|
|
Ride *ride = get_ride(rideIndex);
|
|
|
|
// Get view index
|
|
sint32 view = 1;
|
|
for (sint32 i = 0; i < MAX_VEHICLES_PER_RIDE; i++) {
|
|
if (ride->vehicles[i] == headVehicleSpriteIndex)
|
|
break;
|
|
|
|
view++;
|
|
}
|
|
|
|
|
|
rct_window *w = window_find_by_number(WC_RIDE, rideIndex);
|
|
if (w != nullptr) {
|
|
window_invalidate(w);
|
|
|
|
if (
|
|
input_test_flag(INPUT_FLAG_TOOL_ACTIVE) &&
|
|
gCurrentToolWidget.window_classification == w->classification &&
|
|
gCurrentToolWidget.window_number == w->number
|
|
) {
|
|
tool_cancel();
|
|
}
|
|
|
|
sint32 openedPeepWindow = 0;
|
|
if (w->ride.view == view) {
|
|
sint32 numPeepsLeft = vehicle->num_peeps;
|
|
for (sint32 i = 0; i < 32 && numPeepsLeft > 0; i++) {
|
|
uint16 peepSpriteIndex = vehicle->peep[i];
|
|
if (peepSpriteIndex == SPRITE_INDEX_NULL)
|
|
continue;
|
|
|
|
numPeepsLeft--;
|
|
rct_window *w2 = window_find_by_number(WC_PEEP, peepSpriteIndex);
|
|
if (w2 == nullptr) {
|
|
rct_peep *peep = &(get_sprite(peepSpriteIndex)->peep);
|
|
auto intent = Intent(WC_PEEP);
|
|
intent.putExtra(INTENT_EXTRA_PEEP, peep);
|
|
context_open_intent(&intent);
|
|
openedPeepWindow = 1;
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
w = openedPeepWindow ?
|
|
window_find_by_number(WC_RIDE, rideIndex) :
|
|
window_bring_to_front_by_number(WC_RIDE, rideIndex);
|
|
}
|
|
|
|
if (w == nullptr) {
|
|
w = window_ride_open(rideIndex);
|
|
w->ride.var_482 = -1;
|
|
}
|
|
|
|
_rideType = ride->type;
|
|
w->page = WINDOW_RIDE_PAGE_MAIN;
|
|
w->width = 316;
|
|
w->height = 180;
|
|
window_invalidate(w);
|
|
|
|
w->widgets = window_ride_page_widgets[w->page];
|
|
w->enabled_widgets = window_ride_page_enabled_widgets[w->page];
|
|
w->hold_down_widgets = window_ride_page_hold_down_widgets[w->page];
|
|
w->event_handlers = window_ride_page_events[w->page];
|
|
w->pressed_widgets = 0;
|
|
window_ride_disable_tabs(w);
|
|
window_init_scroll_widgets(w);
|
|
|
|
w->ride.view = view;
|
|
window_ride_init_viewport(w);
|
|
window_invalidate(w);
|
|
|
|
return w;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AF1D2
|
|
*/
|
|
static void window_ride_set_page(rct_window *w, sint32 page)
|
|
{
|
|
sint32 listen;
|
|
|
|
if (input_test_flag(INPUT_FLAG_TOOL_ACTIVE))
|
|
if (w->classification == gCurrentToolWidget.window_classification && w->number == gCurrentToolWidget.window_number)
|
|
tool_cancel();
|
|
|
|
// Set listen only to viewport
|
|
listen = 0;
|
|
if (page == WINDOW_RIDE_PAGE_MAIN && w->page == WINDOW_RIDE_PAGE_MAIN && w->viewport != nullptr && !(w->viewport->flags & VIEWPORT_FLAG_SOUND_ON))
|
|
listen++;
|
|
|
|
w->page = page;
|
|
w->frame_no = 0;
|
|
w->var_492 = 0;
|
|
|
|
//There doesn't seem to be any need for this call, and it can sometimes modify the reported number of cars per train, so I've removed it
|
|
//if (page == WINDOW_RIDE_PAGE_VEHICLE) {
|
|
//ride_update_max_vehicles(w->number);
|
|
//}
|
|
|
|
if (w->viewport != nullptr) {
|
|
w->viewport->width = 0;
|
|
w->viewport = nullptr;
|
|
}
|
|
|
|
w->enabled_widgets = window_ride_page_enabled_widgets[page];
|
|
w->hold_down_widgets = window_ride_page_hold_down_widgets[page];
|
|
w->event_handlers = window_ride_page_events[page];
|
|
w->pressed_widgets = 0;
|
|
w->widgets = window_ride_page_widgets[page];
|
|
window_ride_disable_tabs(w);
|
|
window_invalidate(w);
|
|
|
|
window_event_resize_call(w);
|
|
window_event_invalidate_call(w);
|
|
window_init_scroll_widgets(w);
|
|
window_invalidate(w);
|
|
|
|
if (listen != 0 && w->viewport != nullptr)
|
|
w->viewport->flags |= VIEWPORT_FLAG_SOUND_ON;
|
|
}
|
|
|
|
static void window_ride_set_pressed_tab(rct_window *w)
|
|
{
|
|
sint32 i;
|
|
for (i = 0; i < WINDOW_RIDE_PAGE_COUNT; i++)
|
|
w->pressed_widgets &= ~(1 << (WIDX_TAB_1 + i));
|
|
w->pressed_widgets |= 1LL << (WIDX_TAB_1 + w->page);
|
|
}
|
|
|
|
static void window_ride_anchor_border_widgets(rct_window *w)
|
|
{
|
|
w->widgets[WIDX_BACKGROUND].right = w->width - 1;
|
|
w->widgets[WIDX_BACKGROUND].bottom = w->height - 1;
|
|
w->widgets[WIDX_PAGE_BACKGROUND].right = w->width - 1;
|
|
w->widgets[WIDX_PAGE_BACKGROUND].bottom = w->height - 1;
|
|
w->widgets[WIDX_TITLE].right = w->width - 2;
|
|
w->widgets[WIDX_CLOSE].left = w->width - 13;
|
|
w->widgets[WIDX_CLOSE].right = w->width - 3;
|
|
}
|
|
|
|
#pragma region Main
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AF994
|
|
*/
|
|
static void window_ride_init_viewport(rct_window *w)
|
|
{
|
|
if (w->page != WINDOW_RIDE_PAGE_MAIN) return;
|
|
|
|
Ride* ride = get_ride(w->number);
|
|
sint32 eax = w->viewport_focus_coordinates.var_480 - 1;
|
|
|
|
union{
|
|
sprite_focus sprite;
|
|
coordinate_focus coordinate;
|
|
} focus;
|
|
|
|
focus.coordinate.x = 0;
|
|
focus.coordinate.y = 0;
|
|
focus.coordinate.z = 0;
|
|
focus.sprite.sprite_id = SPRITE_INDEX_NULL;
|
|
focus.coordinate.zoom = 0;
|
|
focus.coordinate.rotation = get_current_rotation();
|
|
focus.coordinate.width = 0;
|
|
focus.coordinate.height = 0;
|
|
|
|
if (eax >= 0 && eax < ride->num_vehicles && ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK){
|
|
focus.sprite.sprite_id = ride->vehicles[eax];
|
|
|
|
rct_ride_entry* ride_entry = get_ride_entry_by_ride(ride);
|
|
if (ride_entry && ride_entry->tab_vehicle != 0){
|
|
rct_vehicle* vehicle = GET_VEHICLE(focus.sprite.sprite_id);
|
|
if (vehicle->next_vehicle_on_train != SPRITE_INDEX_NULL) {
|
|
focus.sprite.sprite_id = vehicle->next_vehicle_on_train;
|
|
}
|
|
}
|
|
if (focus.sprite.sprite_id != SPRITE_INDEX_NULL) {
|
|
focus.sprite.type |= VIEWPORT_FOCUS_TYPE_SPRITE;
|
|
}
|
|
}
|
|
else if (eax >= ride->num_vehicles && eax < (ride->num_vehicles + ride->num_stations)){
|
|
sint32 stationIndex = -1;
|
|
sint32 count = eax - ride->num_vehicles;
|
|
do {
|
|
stationIndex++;
|
|
if (ride->station_starts[stationIndex].xy != RCT_XY8_UNDEFINED)
|
|
{
|
|
count--;
|
|
}
|
|
} while (count >= 0);
|
|
|
|
LocationXY8 location = ride->station_starts[stationIndex];
|
|
|
|
focus.coordinate.x = location.x * 32;
|
|
focus.coordinate.y = location.y * 32;
|
|
focus.coordinate.z = ride->station_heights[stationIndex] << 3;
|
|
focus.sprite.type |= VIEWPORT_FOCUS_TYPE_COORDINATE;
|
|
}
|
|
else{
|
|
if (eax > 0){
|
|
w->viewport_focus_coordinates.var_480 = 0;
|
|
}
|
|
|
|
ride_overall_view *view = &ride_overall_views[w->number];
|
|
|
|
focus.coordinate.x = view->x;
|
|
focus.coordinate.y = view->y;
|
|
focus.coordinate.z = view->z;
|
|
focus.coordinate.zoom = view->zoom;
|
|
|
|
focus.sprite.type |= VIEWPORT_FOCUS_TYPE_COORDINATE;
|
|
}
|
|
focus.coordinate.var_480 = w->viewport_focus_coordinates.var_480;
|
|
|
|
uint16 viewport_flags = 0;
|
|
|
|
if (w->viewport != nullptr) {
|
|
if (focus.coordinate.x == w->viewport_focus_coordinates.x &&
|
|
focus.coordinate.y == w->viewport_focus_coordinates.y &&
|
|
focus.coordinate.z == w->viewport_focus_coordinates.z &&
|
|
focus.coordinate.rotation == w->viewport_focus_coordinates.rotation &&
|
|
focus.coordinate.zoom == w->viewport_focus_coordinates.zoom &&
|
|
focus.coordinate.width == w->width &&
|
|
focus.coordinate.height == w->height
|
|
) {
|
|
return;
|
|
}
|
|
viewport_flags = w->viewport->flags;
|
|
w->viewport->width = 0;
|
|
w->viewport = nullptr;
|
|
|
|
viewport_update_pointers();
|
|
} else if (gConfigGeneral.always_show_gridlines) {
|
|
viewport_flags |= VIEWPORT_FLAG_GRIDLINES;
|
|
}
|
|
|
|
window_event_invalidate_call(w);
|
|
|
|
w->viewport_focus_coordinates.x = focus.coordinate.x;
|
|
w->viewport_focus_coordinates.y = focus.coordinate.y;
|
|
w->viewport_focus_coordinates.z = focus.coordinate.z;
|
|
w->viewport_focus_coordinates.rotation = focus.coordinate.rotation;
|
|
w->viewport_focus_coordinates.zoom = focus.coordinate.zoom;
|
|
w->viewport_focus_coordinates.width = w->width;
|
|
w->viewport_focus_coordinates.height = w->height;
|
|
|
|
//rct2: 0x006aec9c only used here so brought it into the function
|
|
if (!w->viewport && ride->overall_view.xy != RCT_XY8_UNDEFINED){
|
|
rct_widget* view_widget = &w->widgets[WIDX_VIEWPORT];
|
|
|
|
sint32 x = view_widget->left + 1 + w->x;
|
|
sint32 y = view_widget->top + 1 + w->y;
|
|
sint32 width = view_widget->right - view_widget->left - 1;
|
|
sint32 height = view_widget->bottom - view_widget->top - 1;
|
|
viewport_create(
|
|
w,
|
|
x,
|
|
y,
|
|
width,
|
|
height,
|
|
focus.coordinate.zoom,
|
|
focus.coordinate.x,
|
|
focus.coordinate.y & VIEWPORT_FOCUS_Y_MASK,
|
|
focus.coordinate.z,
|
|
focus.sprite.type & VIEWPORT_FOCUS_TYPE_MASK,
|
|
focus.sprite.sprite_id);
|
|
|
|
w->flags |= WF_NO_SCROLLING;
|
|
window_invalidate(w);
|
|
}
|
|
if (w->viewport){
|
|
w->viewport->flags = viewport_flags;
|
|
window_invalidate(w);
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AF315
|
|
*/
|
|
static void window_ride_rename(rct_window *w)
|
|
{
|
|
Ride *ride;
|
|
|
|
ride = get_ride(w->number);
|
|
set_format_arg(16, uint32, ride->name_arguments);
|
|
window_text_input_open(w, WIDX_RENAME, STR_RIDE_ATTRACTION_NAME, STR_ENTER_NEW_NAME_FOR_THIS_RIDE_ATTRACTION, ride->name, ride->name_arguments, 32);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AF17E
|
|
*/
|
|
static void window_ride_main_mouseup(rct_window *w, rct_widgetindex widgetIndex)
|
|
{
|
|
uint8 rideIndex;
|
|
sint32 status;
|
|
|
|
switch (widgetIndex) {
|
|
case WIDX_CLOSE:
|
|
window_close(w);
|
|
break;
|
|
case WIDX_TAB_1:
|
|
case WIDX_TAB_2:
|
|
case WIDX_TAB_3:
|
|
case WIDX_TAB_4:
|
|
case WIDX_TAB_5:
|
|
case WIDX_TAB_6:
|
|
case WIDX_TAB_7:
|
|
case WIDX_TAB_8:
|
|
case WIDX_TAB_9:
|
|
case WIDX_TAB_10:
|
|
window_ride_set_page(w, widgetIndex - WIDX_TAB_1);
|
|
break;
|
|
case WIDX_CONSTRUCTION:
|
|
rideIndex = (uint8)w->number;
|
|
ride_construct(rideIndex);
|
|
if (window_find_by_number(WC_RIDE_CONSTRUCTION, rideIndex) != nullptr) {
|
|
window_close(w);
|
|
}
|
|
break;
|
|
case WIDX_RENAME:
|
|
window_ride_rename(w);
|
|
break;
|
|
case WIDX_LOCATE:
|
|
window_scroll_to_viewport(w);
|
|
break;
|
|
case WIDX_DEMOLISH:
|
|
context_open_detail_window(WD_DEMOLISH_RIDE, w->number);
|
|
break;
|
|
case WIDX_CLOSE_LIGHT:
|
|
case WIDX_TEST_LIGHT:
|
|
case WIDX_OPEN_LIGHT:
|
|
switch (widgetIndex)
|
|
{
|
|
default:
|
|
case WIDX_CLOSE_LIGHT:
|
|
status = RIDE_STATUS_CLOSED;
|
|
break;
|
|
case WIDX_TEST_LIGHT:
|
|
status = RIDE_STATUS_TESTING;
|
|
break;
|
|
case WIDX_OPEN_LIGHT:
|
|
status = RIDE_STATUS_OPEN;
|
|
break;
|
|
}
|
|
|
|
ride_set_status(w->number, status);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AF4A2
|
|
*/
|
|
static void window_ride_main_resize(rct_window *w)
|
|
{
|
|
const sint32 offset = gCheatsAllowArbitraryRideTypeChanges ? 15 : 0;
|
|
w->flags |= WF_RESIZABLE;
|
|
sint32 minHeight = 180 + offset;
|
|
if (theme_get_flags() & UITHEME_FLAG_USE_LIGHTS_RIDE)
|
|
minHeight = 200 + offset + RCT1_LIGHT_OFFSET - (ride_type_has_flag(get_ride(w->number)->type, RIDE_TYPE_FLAG_NO_TEST_MODE) ? 14 : 0);
|
|
window_set_resize(w, 316, minHeight, 500, 450);
|
|
window_ride_init_viewport(w);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AF825
|
|
*/
|
|
static void window_ride_show_view_dropdown(rct_window *w, rct_widget *widget)
|
|
{
|
|
rct_widget *dropdownWidget = widget - 1;
|
|
Ride *ride = get_ride(w->number);
|
|
|
|
sint32 numItems = 1;
|
|
if (!ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_NO_VEHICLES)) {
|
|
numItems += ride->num_stations;
|
|
numItems += ride->num_vehicles;
|
|
}
|
|
|
|
window_dropdown_show_text_custom_width(
|
|
w->x + dropdownWidget->left,
|
|
w->y + dropdownWidget->top,
|
|
dropdownWidget->bottom - dropdownWidget->top + 1,
|
|
w->colours[1],
|
|
0,
|
|
0,
|
|
numItems,
|
|
widget->right - dropdownWidget->left
|
|
);
|
|
|
|
// First item
|
|
gDropdownItemsFormat[0] = STR_DROPDOWN_MENU_LABEL;
|
|
gDropdownItemsArgs[0] = STR_OVERALL_VIEW;
|
|
sint32 currentItem = 1;
|
|
|
|
// Vehicles
|
|
sint32 name = RideComponentNames[RideNameConvention[ride->type].vehicle].number;
|
|
for (sint32 i = 1; i <= ride->num_vehicles; i++) {
|
|
gDropdownItemsFormat[currentItem] = STR_DROPDOWN_MENU_LABEL;
|
|
gDropdownItemsArgs[currentItem] = name | (currentItem << 16);
|
|
currentItem++;
|
|
}
|
|
|
|
// Stations
|
|
name = RideComponentNames[RideNameConvention[ride->type].station].number;
|
|
for (sint32 i = 1; i <= ride->num_stations; i++) {
|
|
gDropdownItemsFormat[currentItem] = STR_DROPDOWN_MENU_LABEL;
|
|
gDropdownItemsArgs[currentItem] = name | (i << 16);
|
|
currentItem++;
|
|
}
|
|
|
|
// Set highlighted item
|
|
if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK))
|
|
{
|
|
for (sint32 i = 0; i < ride->num_vehicles; i++)
|
|
{
|
|
// The +1 is to skip 'Overall view'
|
|
dropdown_set_disabled(i + 1, true);;
|
|
}
|
|
}
|
|
|
|
// Set checked item
|
|
dropdown_set_checked(w->ride.view, true);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AF64C
|
|
*/
|
|
static void window_ride_show_open_dropdown(rct_window *w, rct_widget *widget)
|
|
{
|
|
Ride *ride;
|
|
sint32 numItems, highlightedIndex = 0, checkedIndex;
|
|
|
|
ride = get_ride(w->number);
|
|
|
|
numItems = 0;
|
|
gDropdownItemsFormat[numItems] = STR_DROPDOWN_MENU_LABEL;
|
|
gDropdownItemsArgs[numItems] = STR_CLOSE_RIDE;
|
|
numItems++;
|
|
|
|
if (!ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_NO_TEST_MODE)) {
|
|
gDropdownItemsFormat[numItems] = STR_DROPDOWN_MENU_LABEL;
|
|
gDropdownItemsArgs[numItems] = STR_TEST_RIDE;
|
|
numItems++;
|
|
}
|
|
|
|
gDropdownItemsFormat[numItems] = STR_DROPDOWN_MENU_LABEL;
|
|
gDropdownItemsArgs[numItems] = STR_OPEN_RIDE;
|
|
numItems++;
|
|
|
|
window_dropdown_show_text(
|
|
w->x + widget->left,
|
|
w->y + widget->top,
|
|
widget->bottom - widget->top + 1,
|
|
w->colours[1],
|
|
0,
|
|
numItems
|
|
);
|
|
|
|
checkedIndex = ride->status;
|
|
switch (ride->status) {
|
|
case RIDE_STATUS_CLOSED:
|
|
highlightedIndex = 0;
|
|
if ((ride->lifecycle_flags & RIDE_LIFECYCLE_CRASHED) || (ride->lifecycle_flags & RIDE_LIFECYCLE_HAS_STALLED_VEHICLE))
|
|
break;
|
|
|
|
highlightedIndex = 2;
|
|
if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_NO_TEST_MODE))
|
|
break;
|
|
if (ride->lifecycle_flags & RIDE_LIFECYCLE_TESTED)
|
|
break;
|
|
|
|
highlightedIndex = 1;
|
|
break;
|
|
case RIDE_STATUS_TESTING:
|
|
highlightedIndex = 2;
|
|
if (ride->lifecycle_flags & RIDE_LIFECYCLE_TESTED)
|
|
break;
|
|
|
|
highlightedIndex = 0;
|
|
break;
|
|
case RIDE_STATUS_OPEN:
|
|
highlightedIndex = 0;
|
|
break;
|
|
}
|
|
|
|
if (checkedIndex != RIDE_STATUS_CLOSED)
|
|
checkedIndex = 3 - checkedIndex;
|
|
|
|
if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_NO_TEST_MODE)) {
|
|
if (checkedIndex != 0)
|
|
checkedIndex--;
|
|
if (highlightedIndex != 0)
|
|
highlightedIndex--;
|
|
}
|
|
|
|
dropdown_set_checked(checkedIndex, true);
|
|
gDropdownDefaultIndex = highlightedIndex;
|
|
}
|
|
|
|
static void window_ride_show_ride_type_dropdown(rct_window *w, rct_widget *widget)
|
|
{
|
|
assert(_rideType == Math::Clamp<uint8>(0, _rideType, RIDE_TYPE_COUNT));
|
|
|
|
for (sint32 i = 0; i < RIDE_TYPE_COUNT; i++) {
|
|
gDropdownItemsFormat[i] = STR_DROPDOWN_MENU_LABEL;
|
|
gDropdownItemsArgs[i] = RideNaming[i].name;
|
|
}
|
|
|
|
window_dropdown_show_text(
|
|
w->x + widget->left,
|
|
w->y + widget->top,
|
|
widget->bottom - widget->top + 1,
|
|
w->colours[1],
|
|
DROPDOWN_FLAG_STAY_OPEN,
|
|
RIDE_TYPE_COUNT
|
|
);
|
|
|
|
gDropdownHighlightedIndex = _rideType;
|
|
gDropdownDefaultIndex = _rideType;
|
|
dropdown_set_checked(_rideType, true);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AF1BD
|
|
*/
|
|
static void window_ride_main_mousedown(rct_window *w, rct_widgetindex widgetIndex, rct_widget *widget)
|
|
{
|
|
switch (widgetIndex) {
|
|
case WIDX_VIEW_DROPDOWN:
|
|
window_ride_show_view_dropdown(w, widget);
|
|
break;
|
|
case WIDX_OPEN:
|
|
window_ride_show_open_dropdown(w, widget);
|
|
break;
|
|
case WIDX_RIDE_TYPE:
|
|
window_ride_show_ride_type_dropdown(w, widget);
|
|
break;
|
|
case WIDX_RIDE_TYPE_INCREASE:
|
|
_rideType = Math::Min(RIDE_TYPE_COUNT - 1, _rideType + 1);
|
|
widget_invalidate(w, WIDX_RIDE_TYPE);
|
|
break;
|
|
case WIDX_RIDE_TYPE_DECREASE:
|
|
_rideType = Math::Max(0, _rideType - 1);
|
|
widget_invalidate(w, WIDX_RIDE_TYPE);
|
|
break;
|
|
case WIDX_RIDE_TYPE_APPLY:
|
|
if (_rideType < RIDE_TYPE_COUNT)
|
|
{
|
|
set_operating_setting(w->number, RIDE_SETTING_RIDE_TYPE, _rideType);
|
|
}
|
|
window_invalidate_all();
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AF300
|
|
*/
|
|
static void window_ride_main_dropdown(rct_window *w, rct_widgetindex widgetIndex, sint32 dropdownIndex)
|
|
{
|
|
Ride *ride;
|
|
sint32 status = 0;
|
|
|
|
switch (widgetIndex) {
|
|
case WIDX_VIEW_DROPDOWN:
|
|
if (dropdownIndex == -1) {
|
|
dropdownIndex = w->ride.view;
|
|
ride = get_ride(w->number);
|
|
dropdownIndex++;
|
|
if (dropdownIndex != 0 && dropdownIndex <= ride->num_vehicles && !(ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK))
|
|
dropdownIndex = ride->num_vehicles + 1;
|
|
|
|
if (dropdownIndex >= gDropdownNumItems)
|
|
dropdownIndex = 0;
|
|
}
|
|
|
|
w->ride.view = dropdownIndex;
|
|
window_ride_init_viewport(w);
|
|
window_invalidate(w);
|
|
break;
|
|
case WIDX_OPEN:
|
|
if (dropdownIndex == -1)
|
|
dropdownIndex = gDropdownHighlightedIndex;
|
|
|
|
ride = get_ride(w->number);
|
|
if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_NO_TEST_MODE) && dropdownIndex != 0)
|
|
dropdownIndex++;
|
|
|
|
switch (dropdownIndex) {
|
|
case 0:
|
|
status = RIDE_STATUS_CLOSED;
|
|
break;
|
|
case 1:
|
|
status = RIDE_STATUS_TESTING;
|
|
break;
|
|
case 2:
|
|
status = RIDE_STATUS_OPEN;
|
|
break;
|
|
}
|
|
ride_set_status(w->number, status);
|
|
break;
|
|
case WIDX_RIDE_TYPE:
|
|
if (dropdownIndex != -1 && dropdownIndex < RIDE_TYPE_COUNT) {
|
|
_rideType = Math::Clamp(0, dropdownIndex, RIDE_TYPE_COUNT - 1);
|
|
widget_invalidate(w, WIDX_RIDE_TYPE);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AF40F
|
|
*/
|
|
static void window_ride_main_update(rct_window *w)
|
|
{
|
|
// Update tab animation
|
|
w->frame_no++;
|
|
window_event_invalidate_call(w);
|
|
widget_invalidate(w, WIDX_TAB_1);
|
|
|
|
// Update status
|
|
Ride *ride = get_ride(w->number);
|
|
if (!(ride->window_invalidate_flags & RIDE_INVALIDATE_RIDE_MAIN)) {
|
|
if (w->ride.view == 0)
|
|
return;
|
|
|
|
if (w->ride.view <= ride->num_vehicles) {
|
|
sint32 vehicleIndex = w->ride.view - 1;
|
|
uint16 vehicleSpriteIndex = ride->vehicles[vehicleIndex];
|
|
if (vehicleSpriteIndex == SPRITE_INDEX_NULL)
|
|
return;
|
|
|
|
rct_vehicle *vehicle = &(get_sprite(vehicleSpriteIndex)->vehicle);
|
|
if (
|
|
vehicle->status != 4 &&
|
|
vehicle->status != 22 &&
|
|
vehicle->status != 10 &&
|
|
vehicle->status != 7
|
|
) {
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
ride->window_invalidate_flags &= ~RIDE_INVALIDATE_RIDE_MAIN;
|
|
widget_invalidate(w, WIDX_STATUS);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AF2F9
|
|
*/
|
|
static void window_ride_main_textinput(rct_window *w, rct_widgetindex widgetIndex, char *text)
|
|
{
|
|
if (widgetIndex != WIDX_RENAME || text == nullptr)
|
|
return;
|
|
|
|
ride_set_name(w->number, text);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AF55A
|
|
*/
|
|
static void window_ride_main_viewport_rotate(rct_window *w)
|
|
{
|
|
window_ride_init_viewport(w);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AECF6
|
|
*/
|
|
static void window_ride_main_invalidate(rct_window *w)
|
|
{
|
|
rct_widget *widgets;
|
|
sint32 i, height;
|
|
|
|
widgets = window_ride_page_widgets[w->page];
|
|
if (w->widgets != widgets) {
|
|
w->widgets = widgets;
|
|
window_init_scroll_widgets(w);
|
|
}
|
|
|
|
window_ride_set_pressed_tab(w);
|
|
|
|
Ride *ride = get_ride(w->number);
|
|
w->disabled_widgets &= ~((1 << WIDX_DEMOLISH) | (1 << WIDX_CONSTRUCTION));
|
|
if (ride->lifecycle_flags & (RIDE_LIFECYCLE_INDESTRUCTIBLE | RIDE_LIFECYCLE_INDESTRUCTIBLE_TRACK))
|
|
w->disabled_widgets |= (1 << WIDX_DEMOLISH);
|
|
|
|
set_format_arg(0, rct_string_id, ride->name);
|
|
set_format_arg(2, uint32, ride->name_arguments);
|
|
set_format_arg(6, uint16, RideNaming[_rideType].name);
|
|
uint32 spriteIds[] = {
|
|
SPR_CLOSED,
|
|
SPR_OPEN,
|
|
SPR_TESTING,
|
|
};
|
|
window_ride_main_widgets[WIDX_OPEN].image = spriteIds[ride->status];
|
|
|
|
window_ride_main_widgets[WIDX_CLOSE_LIGHT].image = SPR_G2_RCT1_CLOSE_BUTTON_0 + (ride->status == RIDE_STATUS_CLOSED) * 2 + widget_is_pressed(w, WIDX_CLOSE_LIGHT);
|
|
window_ride_main_widgets[WIDX_TEST_LIGHT].image = SPR_G2_RCT1_TEST_BUTTON_0 + (ride->status == RIDE_STATUS_TESTING) * 2 + widget_is_pressed(w, WIDX_TEST_LIGHT);
|
|
window_ride_main_widgets[WIDX_OPEN_LIGHT].image = SPR_G2_RCT1_OPEN_BUTTON_0 + (ride->status == RIDE_STATUS_OPEN) * 2 + widget_is_pressed(w, WIDX_OPEN_LIGHT);
|
|
|
|
window_ride_anchor_border_widgets(w);
|
|
|
|
const sint32 offset = gCheatsAllowArbitraryRideTypeChanges ? 15 : 0;
|
|
// Anchor main page specific widgets
|
|
window_ride_main_widgets[WIDX_VIEWPORT].right = w->width - 26;
|
|
window_ride_main_widgets[WIDX_VIEWPORT].bottom = w->height - (14 + offset);
|
|
window_ride_main_widgets[WIDX_STATUS].right = w->width - 26;
|
|
window_ride_main_widgets[WIDX_STATUS].top = w->height - (13 + offset);
|
|
window_ride_main_widgets[WIDX_STATUS].bottom = w->height - (3 + offset);
|
|
window_ride_main_widgets[WIDX_VIEW].right = w->width - 60;
|
|
window_ride_main_widgets[WIDX_VIEW_DROPDOWN].right = w->width - 61;
|
|
window_ride_main_widgets[WIDX_VIEW_DROPDOWN].left = w->width - 71;
|
|
window_ride_main_widgets[WIDX_RIDE_TYPE].right = w->width - 87;
|
|
window_ride_main_widgets[WIDX_RIDE_TYPE].top = w->height - 17;
|
|
window_ride_main_widgets[WIDX_RIDE_TYPE].bottom = w->height - 4;
|
|
window_ride_main_widgets[WIDX_RIDE_TYPE_INCREASE].right = w->width - 88;
|
|
window_ride_main_widgets[WIDX_RIDE_TYPE_INCREASE].left = w->width - 98;
|
|
window_ride_main_widgets[WIDX_RIDE_TYPE_INCREASE].top = w->height - 16;
|
|
window_ride_main_widgets[WIDX_RIDE_TYPE_INCREASE].bottom = w->height - 11;
|
|
window_ride_main_widgets[WIDX_RIDE_TYPE_DECREASE].right = w->width - 88;
|
|
window_ride_main_widgets[WIDX_RIDE_TYPE_DECREASE].left = w->width - 98;
|
|
window_ride_main_widgets[WIDX_RIDE_TYPE_DECREASE].top = w->height - 10;
|
|
window_ride_main_widgets[WIDX_RIDE_TYPE_DECREASE].bottom = w->height - 5;
|
|
window_ride_main_widgets[WIDX_RIDE_TYPE_APPLY].left = w->width - 83;
|
|
window_ride_main_widgets[WIDX_RIDE_TYPE_APPLY].right = w->width - 26;
|
|
window_ride_main_widgets[WIDX_RIDE_TYPE_APPLY].top = w->height - 17;
|
|
window_ride_main_widgets[WIDX_RIDE_TYPE_APPLY].bottom = w->height - 4;
|
|
|
|
if (!gCheatsAllowArbitraryRideTypeChanges) {
|
|
window_ride_main_widgets[WIDX_RIDE_TYPE].type = WWT_EMPTY;
|
|
window_ride_main_widgets[WIDX_RIDE_TYPE_INCREASE].type = WWT_EMPTY;
|
|
window_ride_main_widgets[WIDX_RIDE_TYPE_DECREASE].type = WWT_EMPTY;
|
|
window_ride_main_widgets[WIDX_RIDE_TYPE_APPLY].type = WWT_EMPTY;
|
|
} else {
|
|
window_ride_main_widgets[WIDX_RIDE_TYPE].type = WWT_SPINNER;
|
|
window_ride_main_widgets[WIDX_RIDE_TYPE_INCREASE].type = WWT_BUTTON;
|
|
window_ride_main_widgets[WIDX_RIDE_TYPE_DECREASE].type = WWT_BUTTON;
|
|
window_ride_main_widgets[WIDX_RIDE_TYPE_APPLY].type = WWT_BUTTON;
|
|
}
|
|
|
|
window_align_tabs(w, WIDX_TAB_1, WIDX_TAB_10);
|
|
|
|
if (theme_get_flags() & UITHEME_FLAG_USE_LIGHTS_RIDE) {
|
|
window_ride_main_widgets[WIDX_OPEN].type = WWT_EMPTY;
|
|
window_ride_main_widgets[WIDX_CLOSE_LIGHT].type = WWT_IMGBTN;
|
|
window_ride_main_widgets[WIDX_TEST_LIGHT].type = (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_NO_TEST_MODE) ? WWT_EMPTY : WWT_IMGBTN);
|
|
window_ride_main_widgets[WIDX_OPEN_LIGHT].type = WWT_IMGBTN;
|
|
|
|
height = 62;
|
|
if (window_ride_main_widgets[WIDX_TEST_LIGHT].type != WWT_EMPTY) {
|
|
window_ride_main_widgets[WIDX_TEST_LIGHT].top = height;
|
|
window_ride_main_widgets[WIDX_TEST_LIGHT].bottom = height + 13;
|
|
height += 14;
|
|
}
|
|
window_ride_main_widgets[WIDX_OPEN_LIGHT].top = height;
|
|
window_ride_main_widgets[WIDX_OPEN_LIGHT].bottom = height + 13;
|
|
height += 14 - 24 + RCT1_LIGHT_OFFSET;
|
|
|
|
w->min_height = 200 + RCT1_LIGHT_OFFSET - (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_NO_TEST_MODE) ? 14 : 0);
|
|
if (w->height < w->min_height)
|
|
window_event_resize_call(w);
|
|
}
|
|
else {
|
|
window_ride_main_widgets[WIDX_OPEN].type = WWT_FLATBTN;
|
|
window_ride_main_widgets[WIDX_CLOSE_LIGHT].type = WWT_EMPTY;
|
|
window_ride_main_widgets[WIDX_TEST_LIGHT].type = WWT_EMPTY;
|
|
window_ride_main_widgets[WIDX_OPEN_LIGHT].type = WWT_EMPTY;
|
|
height = 46;
|
|
}
|
|
for (i = WIDX_CLOSE_LIGHT; i <= WIDX_OPEN_LIGHT; i++) {
|
|
window_ride_main_widgets[i].left = w->width - 20;
|
|
window_ride_main_widgets[i].right = w->width - 7;
|
|
}
|
|
for (i = WIDX_OPEN; i <= WIDX_DEMOLISH; i++, height += 24) {
|
|
window_ride_main_widgets[i].left = w->width - 25;
|
|
window_ride_main_widgets[i].right = w->width - 2;
|
|
window_ride_main_widgets[i].top = height;
|
|
window_ride_main_widgets[i].bottom = height + 23;
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AF10A
|
|
*/
|
|
static rct_string_id window_ride_get_status_overall_view(rct_window *w, void *arguments)
|
|
{
|
|
sint32 argument;
|
|
rct_string_id formatSecondary, stringId;
|
|
|
|
ride_get_status(w->number, &formatSecondary, &argument);
|
|
*(uint16*)((uintptr_t)arguments + 0) = formatSecondary;
|
|
*(uintptr_t*)((uintptr_t)arguments + 2) = argument;
|
|
stringId = STR_RED_OUTLINED_STRING;
|
|
if (formatSecondary != STR_BROKEN_DOWN && formatSecondary != STR_CRASHED)
|
|
stringId = STR_BLACK_STRING;
|
|
|
|
return stringId;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AEFEF
|
|
*/
|
|
static rct_string_id window_ride_get_status_vehicle(rct_window *w, void *arguments)
|
|
{
|
|
Ride *ride;
|
|
rct_vehicle *vehicle;
|
|
sint32 vehicleIndex;
|
|
uint16 vehicleSpriteIndex;
|
|
rct_string_id stringId;
|
|
|
|
ride = get_ride(w->number);
|
|
|
|
vehicleIndex = w->ride.view - 1;
|
|
vehicleSpriteIndex = ride->vehicles[vehicleIndex];
|
|
if (vehicleSpriteIndex == SPRITE_INDEX_NULL)
|
|
return 0;
|
|
|
|
vehicle = &(get_sprite(vehicleSpriteIndex)->vehicle);
|
|
if (vehicle->status != VEHICLE_STATUS_CRASHING && vehicle->status != VEHICLE_STATUS_CRASHED) {
|
|
sint32 trackType = vehicle->track_type >> 2;
|
|
if (trackType == TRACK_ELEM_BLOCK_BRAKES ||
|
|
trackType == TRACK_ELEM_CABLE_LIFT_HILL ||
|
|
trackType == TRACK_ELEM_25_DEG_UP_TO_FLAT ||
|
|
trackType == TRACK_ELEM_60_DEG_UP_TO_FLAT ||
|
|
trackType == TRACK_ELEM_DIAG_25_DEG_UP_TO_FLAT ||
|
|
trackType == TRACK_ELEM_DIAG_60_DEG_UP_TO_FLAT) {
|
|
if (track_piece_is_available_for_ride_type(ride->type, TRACK_BLOCK_BRAKES) && vehicle->velocity == 0) {
|
|
*(rct_string_id*)(uintptr_t)arguments = STR_STOPPED_BY_BLOCK_BRAKES;
|
|
return STR_BLACK_STRING;
|
|
}
|
|
}
|
|
}
|
|
|
|
stringId = VehicleStatusNames[vehicle->status];
|
|
|
|
// Get speed in mph
|
|
*((uint16*)((uintptr_t)arguments + 2)) = (abs(vehicle->velocity) * 9) >> 18;
|
|
|
|
if (ride->type == RIDE_TYPE_MINI_GOLF)
|
|
return 0;
|
|
|
|
if ((RideData4[ride->type].flags & RIDE_TYPE_FLAG4_SINGLE_SESSION) && vehicle->status <= VEHICLE_STATUS_UNLOADING_PASSENGERS) {
|
|
stringId = SingleSessionVehicleStatusNames[vehicle->status];
|
|
}
|
|
|
|
const ride_component_name stationName = RideComponentNames[RideNameConvention[ride->type].station];
|
|
*(rct_string_id*)((uintptr_t)arguments + 4) = (ride->num_stations > 1) ? stationName.number : stationName.singular;
|
|
*((uint16*)((uintptr_t)arguments + 6)) = vehicle->current_station + 1;
|
|
*(rct_string_id*)((uintptr_t)arguments + 0) = stringId;
|
|
return stringId != STR_CRASHING && stringId != STR_CRASHED_0 ? STR_BLACK_STRING : STR_RED_OUTLINED_STRING;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AEF65
|
|
*/
|
|
static rct_string_id window_ride_get_status_station(rct_window *w, void *arguments)
|
|
{
|
|
Ride *ride = get_ride(w->number);
|
|
sint32 count = w->ride.view - ride->num_vehicles - 1;
|
|
sint32 stationIndex = -1;
|
|
rct_string_id stringId = 0;
|
|
|
|
do {
|
|
stationIndex++;
|
|
if (ride->station_starts[stationIndex].xy != RCT_XY8_UNDEFINED)
|
|
count--;
|
|
} while (count >= 0);
|
|
|
|
// Entrance / exit
|
|
if (ride->status == RIDE_STATUS_CLOSED) {
|
|
if (ride->entrances[stationIndex].xy == RCT_XY8_UNDEFINED)
|
|
stringId = STR_NO_ENTRANCE;
|
|
else if (ride->exits[stationIndex].xy == RCT_XY8_UNDEFINED)
|
|
stringId = STR_NO_EXIT;
|
|
} else {
|
|
if (ride->entrances[stationIndex].xy == RCT_XY8_UNDEFINED)
|
|
stringId = STR_EXIT_ONLY;
|
|
}
|
|
|
|
// Queue length
|
|
if (stringId == 0) {
|
|
sint32 queueLength = ride->queue_length[stationIndex];
|
|
set_format_arg_body(static_cast<uint8 *>(arguments), 2, (uintptr_t)queueLength, sizeof(uint16));
|
|
stringId = STR_QUEUE_EMPTY;
|
|
if (queueLength == 1)
|
|
stringId = STR_QUEUE_ONE_PERSON;
|
|
else if (queueLength > 1)
|
|
stringId = STR_QUEUE_PEOPLE;
|
|
}
|
|
|
|
set_format_arg_body(static_cast<uint8 *>(arguments), 0, (uintptr_t)stringId, sizeof(rct_string_id));
|
|
return STR_BLACK_STRING;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AEE73
|
|
*/
|
|
static rct_string_id window_ride_get_status(rct_window *w, void *arguments)
|
|
{
|
|
Ride *ride = get_ride(w->number);
|
|
|
|
if (w->ride.view == 0)
|
|
return window_ride_get_status_overall_view(w, arguments);
|
|
if (w->ride.view <= ride->num_vehicles)
|
|
return window_ride_get_status_vehicle(w, arguments);
|
|
if (ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN)
|
|
return window_ride_get_status_overall_view(w, arguments);
|
|
return window_ride_get_status_station(w, arguments);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AEE73
|
|
*/
|
|
static void window_ride_main_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
|
{
|
|
Ride *ride;
|
|
rct_widget *widget;
|
|
rct_string_id stringId;
|
|
|
|
window_draw_widgets(w, dpi);
|
|
window_ride_draw_tab_images(dpi, w);
|
|
|
|
// Viewport and ear icon
|
|
if (w->viewport != nullptr) {
|
|
window_draw_viewport(dpi, w);
|
|
if (w->viewport->flags & VIEWPORT_FLAG_SOUND_ON)
|
|
gfx_draw_sprite(dpi, SPR_HEARING_VIEWPORT, w->x + 2, w->y + 2, 0);
|
|
}
|
|
|
|
// View dropdown
|
|
ride = get_ride(w->number);
|
|
stringId = STR_OVERALL_VIEW;
|
|
if (w->ride.view != 0) {
|
|
stringId = RideComponentNames[RideNameConvention[ride->type].vehicle].number;
|
|
if (w->ride.view > ride->num_vehicles) {
|
|
set_format_arg(2, uint16, w->ride.view - ride->num_vehicles);
|
|
stringId = RideComponentNames[RideNameConvention[ride->type].station].number;
|
|
} else {
|
|
set_format_arg(2, uint16, w->ride.view);
|
|
}
|
|
}
|
|
set_format_arg(0, uint16, stringId);
|
|
|
|
widget = &window_ride_main_widgets[WIDX_VIEW];
|
|
gfx_draw_string_centred(
|
|
dpi,
|
|
STR_WINDOW_COLOUR_2_STRINGID,
|
|
w->x + (widget->left + widget->right - 11) / 2,
|
|
w->y + widget->top,
|
|
COLOUR_BLACK,
|
|
gCommonFormatArgs
|
|
);
|
|
|
|
// Status
|
|
widget = &window_ride_main_widgets[WIDX_STATUS];
|
|
gfx_draw_string_centred_clipped(
|
|
dpi,
|
|
window_ride_get_status(w, gCommonFormatArgs),
|
|
gCommonFormatArgs,
|
|
COLOUR_BLACK,
|
|
w->x + (widget->left + widget->right) / 2,
|
|
w->y + widget->top,
|
|
widget->right - widget->left
|
|
);
|
|
}
|
|
|
|
#pragma endregion
|
|
|
|
#pragma region Vehicle
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B272D
|
|
*/
|
|
static void window_ride_vehicle_mouseup(rct_window *w, rct_widgetindex widgetIndex)
|
|
{
|
|
switch (widgetIndex) {
|
|
case WIDX_CLOSE:
|
|
window_close(w);
|
|
break;
|
|
case WIDX_TAB_1:
|
|
case WIDX_TAB_2:
|
|
case WIDX_TAB_3:
|
|
case WIDX_TAB_4:
|
|
case WIDX_TAB_5:
|
|
case WIDX_TAB_6:
|
|
case WIDX_TAB_7:
|
|
case WIDX_TAB_8:
|
|
case WIDX_TAB_9:
|
|
case WIDX_TAB_10:
|
|
window_ride_set_page(w, widgetIndex - WIDX_TAB_1);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B2ABB
|
|
*/
|
|
static void window_ride_vehicle_resize(rct_window *w)
|
|
{
|
|
window_set_resize(w, 316, 214, 316, 214);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B2748
|
|
*/
|
|
static void window_ride_vehicle_mousedown(rct_window *w, rct_widgetindex widgetIndex, rct_widget *widget)
|
|
{
|
|
rct_widget *dropdownWidget = widget - 1;
|
|
Ride *ride;
|
|
rct_ride_entry *rideEntry, *currentRideEntry;
|
|
const RideGroup * rideGroup, * currentRideGroup;
|
|
sint32 numItems, rideEntryIndex, selectedIndex, rideTypeIterator, rideTypeIteratorMax;
|
|
uint8 *rideEntryIndexPtr;
|
|
bool selectionShouldBeExpanded;
|
|
|
|
ride = get_ride(w->number);
|
|
rideEntry = get_ride_entry_by_ride(ride);
|
|
|
|
if(gCheatsShowVehiclesFromOtherTrackTypes && !(ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_FLAT_RIDE) || ride->type==RIDE_TYPE_MAZE || ride->type==RIDE_TYPE_MINI_GOLF)) {
|
|
selectionShouldBeExpanded = true;
|
|
rideTypeIterator = 0;
|
|
rideTypeIteratorMax = RIDE_TYPE_COUNT - 1;
|
|
}
|
|
else {
|
|
selectionShouldBeExpanded = false;
|
|
rideTypeIterator = ride->type;
|
|
rideTypeIteratorMax = ride->type;
|
|
}
|
|
|
|
switch (widgetIndex) {
|
|
case WIDX_VEHICLE_TYPE_DROPDOWN:
|
|
selectedIndex = -1;
|
|
numItems = 0;
|
|
|
|
// Dropdowns with more items start acting weird, so cap it.
|
|
for (; rideTypeIterator <= rideTypeIteratorMax && numItems < DROPDOWN_ITEMS_MAX_SIZE; rideTypeIterator++) {
|
|
|
|
if(selectionShouldBeExpanded && ride_type_has_flag(rideTypeIterator, RIDE_TYPE_FLAG_FLAT_RIDE))
|
|
continue;
|
|
if(selectionShouldBeExpanded && (rideTypeIterator == RIDE_TYPE_MAZE || rideTypeIterator == RIDE_TYPE_MINI_GOLF))
|
|
continue;
|
|
|
|
rideEntryIndexPtr = get_ride_entry_indices_for_ride_type(rideTypeIterator);
|
|
|
|
for (uint8 *currentRideEntryIndex = rideEntryIndexPtr; *currentRideEntryIndex != RIDE_ENTRY_INDEX_NULL && numItems < DROPDOWN_ITEMS_MAX_SIZE; currentRideEntryIndex++) {
|
|
rideEntryIndex = *currentRideEntryIndex;
|
|
currentRideEntry = get_ride_entry(rideEntryIndex);
|
|
|
|
// Skip if vehicle type is not invented yet
|
|
if (!ride_entry_is_invented(rideEntryIndex) && !gCheatsIgnoreResearchStatus)
|
|
continue;
|
|
|
|
// Skip if vehicle does not belong to the same ride group
|
|
if (RideGroupManager::RideTypeHasRideGroups(ride->type) && !selectionShouldBeExpanded)
|
|
{
|
|
rideGroup = RideGroupManager::GetRideGroup(ride->type, rideEntry);
|
|
currentRideGroup = RideGroupManager::GetRideGroup(ride->type, currentRideEntry);
|
|
|
|
if (!RideGroupManager::RideGroupsAreEqual(rideGroup, currentRideGroup))
|
|
continue;
|
|
}
|
|
|
|
if (ride->subtype == rideEntryIndex)
|
|
selectedIndex = numItems;
|
|
|
|
gDropdownItemsFormat[numItems] = STR_DROPDOWN_MENU_LABEL;
|
|
gDropdownItemsArgs[numItems] = (rideEntryIndex << 16) | currentRideEntry->naming.name;
|
|
|
|
numItems++;
|
|
}
|
|
}
|
|
|
|
window_dropdown_show_text_custom_width(
|
|
w->x + dropdownWidget->left,
|
|
w->y + dropdownWidget->top,
|
|
dropdownWidget->bottom - dropdownWidget->top + 1,
|
|
w->colours[1],
|
|
0,
|
|
DROPDOWN_FLAG_STAY_OPEN,
|
|
numItems,
|
|
widget->right - dropdownWidget->left
|
|
);
|
|
|
|
dropdown_set_checked(selectedIndex, true);
|
|
break;
|
|
case WIDX_VEHICLE_TRAINS_INCREASE:
|
|
if (ride->num_vehicles < 32)
|
|
ride_set_num_vehicles(w->number, ride->num_vehicles + 1);
|
|
break;
|
|
case WIDX_VEHICLE_TRAINS_DECREASE:
|
|
if (ride->num_vehicles > 1)
|
|
ride_set_num_vehicles(w->number, ride->num_vehicles - 1);
|
|
break;
|
|
case WIDX_VEHICLE_CARS_PER_TRAIN_INCREASE:
|
|
if (ride->num_cars_per_train < 255)
|
|
ride_set_num_cars_per_vehicle(w->number, ride->num_cars_per_train + 1);
|
|
break;
|
|
case WIDX_VEHICLE_CARS_PER_TRAIN_DECREASE:
|
|
if (ride->num_cars_per_train > rideEntry->zero_cars + 1)
|
|
ride_set_num_cars_per_vehicle(w->number, ride->num_cars_per_train - 1);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B2767
|
|
*/
|
|
static void window_ride_vehicle_dropdown(rct_window *w, rct_widgetindex widgetIndex, sint32 dropdownIndex)
|
|
{
|
|
if (dropdownIndex == -1)
|
|
return;
|
|
|
|
switch (widgetIndex) {
|
|
case WIDX_VEHICLE_TYPE_DROPDOWN:
|
|
dropdownIndex = (gDropdownItemsArgs[dropdownIndex] >> 16) & 0xFFFF;
|
|
ride_set_ride_entry(w->number, dropdownIndex);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B2AA1
|
|
*/
|
|
static void window_ride_vehicle_update(rct_window *w)
|
|
{
|
|
w->frame_no++;
|
|
window_event_invalidate_call(w);
|
|
widget_invalidate(w, WIDX_TAB_2);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B222C
|
|
*/
|
|
static void window_ride_vehicle_invalidate(rct_window *w)
|
|
{
|
|
rct_widget *widgets;
|
|
Ride *ride;
|
|
rct_ride_entry *rideEntry;
|
|
rct_string_id stringId;
|
|
sint32 carsPerTrain;
|
|
|
|
widgets = window_ride_page_widgets[w->page];
|
|
if (w->widgets != widgets) {
|
|
w->widgets = widgets;
|
|
window_init_scroll_widgets(w);
|
|
}
|
|
|
|
window_ride_set_pressed_tab(w);
|
|
|
|
ride = get_ride(w->number);
|
|
rideEntry = get_ride_entry_by_ride(ride);
|
|
|
|
set_format_arg(0, rct_string_id, ride->name);
|
|
set_format_arg(2, uint32, ride->name_arguments);
|
|
|
|
// Widget setup
|
|
carsPerTrain = ride->num_cars_per_train - rideEntry->zero_cars;
|
|
|
|
// Vehicle type
|
|
window_ride_vehicle_widgets[WIDX_VEHICLE_TYPE].text = rideEntry->naming.name;
|
|
|
|
// Trains
|
|
if (rideEntry->cars_per_flat_ride > 1 || gCheatsDisableTrainLengthLimit) {
|
|
window_ride_vehicle_widgets[WIDX_VEHICLE_TRAINS].type = WWT_SPINNER;
|
|
window_ride_vehicle_widgets[WIDX_VEHICLE_TRAINS_INCREASE].type = WWT_BUTTON;
|
|
window_ride_vehicle_widgets[WIDX_VEHICLE_TRAINS_DECREASE].type = WWT_BUTTON;
|
|
|
|
} else {
|
|
window_ride_vehicle_widgets[WIDX_VEHICLE_TRAINS].type = WWT_EMPTY;
|
|
window_ride_vehicle_widgets[WIDX_VEHICLE_TRAINS_INCREASE].type = WWT_EMPTY;
|
|
window_ride_vehicle_widgets[WIDX_VEHICLE_TRAINS_DECREASE].type = WWT_EMPTY;
|
|
}
|
|
|
|
// Cars per train
|
|
if (rideEntry->zero_cars + 1 < rideEntry->max_cars_in_train||gCheatsDisableTrainLengthLimit) {
|
|
window_ride_vehicle_widgets[WIDX_VEHICLE_CARS_PER_TRAIN].type = WWT_SPINNER;
|
|
window_ride_vehicle_widgets[WIDX_VEHICLE_CARS_PER_TRAIN_INCREASE].type = WWT_BUTTON;
|
|
window_ride_vehicle_widgets[WIDX_VEHICLE_CARS_PER_TRAIN_DECREASE].type = WWT_BUTTON;
|
|
} else {
|
|
window_ride_vehicle_widgets[WIDX_VEHICLE_CARS_PER_TRAIN].type = WWT_EMPTY;
|
|
window_ride_vehicle_widgets[WIDX_VEHICLE_CARS_PER_TRAIN_INCREASE].type = WWT_EMPTY;
|
|
window_ride_vehicle_widgets[WIDX_VEHICLE_CARS_PER_TRAIN_DECREASE].type = WWT_EMPTY;
|
|
|
|
}
|
|
|
|
set_format_arg(6, uint16, carsPerTrain);
|
|
RIDE_COMPONENT_TYPE vehicleType = RideNameConvention[ride->type].vehicle;
|
|
stringId = RideComponentNames[vehicleType].count;
|
|
if (ride->num_vehicles > 1) {
|
|
stringId = RideComponentNames[vehicleType].count_plural;
|
|
}
|
|
set_format_arg(8, rct_string_id, stringId);
|
|
set_format_arg(10, uint16, ride->num_vehicles);
|
|
|
|
stringId = RideComponentNames[vehicleType].count;
|
|
if (ride->max_trains > 1) {
|
|
stringId = RideComponentNames[vehicleType].count_plural;
|
|
}
|
|
set_format_arg(12, rct_string_id, stringId);
|
|
set_format_arg(14, uint16, ride->max_trains);
|
|
|
|
set_format_arg(16, uint16, Math::Max(1, ride->min_max_cars_per_train & 0xF) - rideEntry->zero_cars);
|
|
|
|
stringId = RideComponentNames[RIDE_COMPONENT_TYPE_CAR].singular;
|
|
if ((ride->min_max_cars_per_train & 0xF) - rideEntry->zero_cars > 1) {
|
|
stringId = RideComponentNames[RIDE_COMPONENT_TYPE_CAR].plural;
|
|
}
|
|
|
|
set_format_arg(18, rct_string_id, stringId);
|
|
|
|
window_ride_anchor_border_widgets(w);
|
|
window_align_tabs(w, WIDX_TAB_1, WIDX_TAB_10);
|
|
|
|
if (ride->num_cars_per_train > (rideEntry->zero_cars + 1)) {
|
|
window_ride_vehicle_widgets[WIDX_VEHICLE_CARS_PER_TRAIN].text = STR_X_CARS_PER_TRAIN;
|
|
} else {
|
|
window_ride_vehicle_widgets[WIDX_VEHICLE_CARS_PER_TRAIN].text = STR_1_CAR_PER_TRAIN;
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B23DC
|
|
*/
|
|
static void window_ride_vehicle_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
|
{
|
|
Ride *ride;
|
|
rct_ride_entry *rideEntry;
|
|
sint32 x, y;
|
|
sint16 factor;
|
|
|
|
window_draw_widgets(w, dpi);
|
|
window_ride_draw_tab_images(dpi, w);
|
|
|
|
ride = get_ride(w->number);
|
|
rideEntry = get_ride_entry_by_ride(ride);
|
|
|
|
x = w->x + 8;
|
|
y = w->y + 64;
|
|
|
|
// Description
|
|
y += gfx_draw_string_left_wrapped(dpi, &rideEntry->naming.description, x, y, 300, STR_BLACK_STRING, COLOUR_BLACK);
|
|
y += 2;
|
|
|
|
// Capacity
|
|
gfx_draw_string_left(dpi, STR_CAPACITY, &rideEntry->capacity, COLOUR_BLACK, x, y);
|
|
|
|
// Excitement Factor
|
|
factor = rideEntry->excitement_multiplier;
|
|
if (factor > 0)
|
|
{
|
|
y += LIST_ROW_HEIGHT;
|
|
gfx_draw_string_left(dpi, STR_EXCITEMENT_FACTOR, &factor, COLOUR_BLACK, x, y);
|
|
}
|
|
|
|
// Intensity Factor
|
|
factor = rideEntry->intensity_multiplier;
|
|
if (factor > 0)
|
|
{
|
|
sint32 lineHeight = font_get_line_height(FONT_SPRITE_BASE_MEDIUM);
|
|
if (lineHeight != 10)
|
|
x += 150;
|
|
else
|
|
y += LIST_ROW_HEIGHT;
|
|
|
|
gfx_draw_string_left(dpi, STR_INTENSITY_FACTOR, &factor, COLOUR_BLACK, x, y);
|
|
|
|
if (lineHeight != 10)
|
|
x -= 150;
|
|
}
|
|
|
|
// Nausea Factor
|
|
factor = rideEntry->nausea_multiplier;
|
|
if (factor > 0)
|
|
{
|
|
y += LIST_ROW_HEIGHT;
|
|
gfx_draw_string_left(dpi, STR_NAUSEA_FACTOR, &factor, COLOUR_BLACK, x, y);
|
|
}
|
|
}
|
|
|
|
struct rct_vehichle_paintinfo {
|
|
sint16 x;
|
|
sint16 y;
|
|
sint32 sprite_index;
|
|
sint32 tertiary_colour;
|
|
};
|
|
|
|
static rct_vehichle_paintinfo _sprites_to_draw[144];
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B2502
|
|
*/
|
|
static void window_ride_vehicle_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, sint32 scrollIndex)
|
|
{
|
|
Ride *ride = get_ride(w->number);
|
|
rct_ride_entry *rideEntry = get_ride_entry_by_ride(ride);
|
|
|
|
// Background
|
|
gfx_fill_rect(dpi, dpi->x, dpi->y, dpi->x + dpi->width, dpi->y + dpi->height, PALETTE_INDEX_12);
|
|
|
|
rct_widget *widget = &window_ride_vehicle_widgets[WIDX_VEHICLE_TRAINS_PREVIEW];
|
|
sint32 startX = Math::Max(2, ((widget->right - widget->left) - ((ride->num_vehicles - 1) * 36)) / 2 - 25);
|
|
sint32 startY = widget->bottom - widget->top - 4;
|
|
|
|
rct_ride_entry_vehicle* rideVehicleEntry = &rideEntry->vehicles[ride_entry_get_vehicle_at_position(ride->subtype, ride->num_cars_per_train, 0)];
|
|
startY += rideVehicleEntry->tab_height;
|
|
|
|
// For each train
|
|
for (sint32 i = 0; i < ride->num_vehicles; i++) {
|
|
rct_vehichle_paintinfo *nextSpriteToDraw = _sprites_to_draw;
|
|
sint32 x = startX;
|
|
sint32 y = startY;
|
|
|
|
// For each car in train
|
|
for (sint32 j = 0; j < ride->num_cars_per_train; j++) {
|
|
rideVehicleEntry = &rideEntry->vehicles[ride_entry_get_vehicle_at_position(ride->subtype, ride->num_cars_per_train, j)];
|
|
x += rideVehicleEntry->spacing / 17432;
|
|
y -= (rideVehicleEntry->spacing / 2) / 17432;
|
|
|
|
// Get colour of vehicle
|
|
sint32 vehicleColourIndex = 0;
|
|
switch (ride->colour_scheme_type & 3) {
|
|
case VEHICLE_COLOUR_SCHEME_SAME:
|
|
vehicleColourIndex = 0;
|
|
break;
|
|
case VEHICLE_COLOUR_SCHEME_PER_TRAIN:
|
|
vehicleColourIndex = i;
|
|
break;
|
|
case VEHICLE_COLOUR_SCHEME_PER_VEHICLE:
|
|
vehicleColourIndex = j;
|
|
break;
|
|
}
|
|
vehicle_colour vehicleColour = ride_get_vehicle_colour(ride, vehicleColourIndex);
|
|
|
|
sint32 spriteIndex = 16;
|
|
if (rideVehicleEntry->flags & VEHICLE_ENTRY_FLAG_11)
|
|
spriteIndex /= 2;
|
|
|
|
spriteIndex &= rideVehicleEntry->rotation_frame_mask;
|
|
spriteIndex *= rideVehicleEntry->base_num_frames;
|
|
spriteIndex += rideVehicleEntry->base_image_id;
|
|
spriteIndex |= (vehicleColour.additional_1 << 24) | (vehicleColour.main << 19);
|
|
spriteIndex |= IMAGE_TYPE_REMAP_2_PLUS;
|
|
|
|
nextSpriteToDraw->x = x;
|
|
nextSpriteToDraw->y = y;
|
|
nextSpriteToDraw->sprite_index = spriteIndex;
|
|
nextSpriteToDraw->tertiary_colour = vehicleColour.additional_2;
|
|
nextSpriteToDraw++;
|
|
|
|
x += rideVehicleEntry->spacing / 17432;
|
|
y -= (rideVehicleEntry->spacing / 2) / 17432;
|
|
}
|
|
|
|
if (ride->type == RIDE_TYPE_REVERSER_ROLLER_COASTER) {
|
|
rct_vehichle_paintinfo tmp = *(nextSpriteToDraw - 1);
|
|
*(nextSpriteToDraw - 1) = *(nextSpriteToDraw - 2);
|
|
*(nextSpriteToDraw - 2) = tmp;
|
|
}
|
|
|
|
rct_vehichle_paintinfo *current = nextSpriteToDraw;
|
|
while (--current >= _sprites_to_draw)
|
|
gfx_draw_sprite(dpi, current->sprite_index, current->x, current->y, current->tertiary_colour);
|
|
|
|
startX += 36;
|
|
}
|
|
}
|
|
|
|
#pragma endregion
|
|
|
|
#pragma region Operating
|
|
|
|
static void set_operating_setting(sint32 rideNumber, uint8 setting, uint8 value)
|
|
{
|
|
gGameCommandErrorTitle = STR_CANT_CHANGE_OPERATING_MODE;
|
|
game_do_command(0, (value << 8) | 1, 0, (setting << 8) | rideNumber, GAME_COMMAND_SET_RIDE_SETTING, 0, 0);
|
|
}
|
|
|
|
static void window_ride_mode_tweak_set(rct_window *w, uint8 value)
|
|
{
|
|
Ride *ride = get_ride(w->number);
|
|
|
|
gGameCommandErrorTitle = STR_CANT_CHANGE_LAUNCH_SPEED;
|
|
if (ride->mode == RIDE_MODE_STATION_TO_STATION)
|
|
gGameCommandErrorTitle = STR_CANT_CHANGE_SPEED;
|
|
if (ride->mode == RIDE_MODE_RACE)
|
|
gGameCommandErrorTitle = STR_CANT_CHANGE_NUMBER_OF_LAPS;
|
|
if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_NO_VEHICLES))
|
|
gGameCommandErrorTitle = STR_CANT_CHANGE_THIS;
|
|
if (ride->mode == RIDE_MODE_BUMPERCAR)
|
|
gGameCommandErrorTitle = STR_CANT_CHANGE_TIME_LIMIT;
|
|
if (ride->mode == RIDE_MODE_SWING)
|
|
gGameCommandErrorTitle = STR_CANT_CHANGE_NUMBER_OF_SWINGS;
|
|
if (
|
|
ride->mode == RIDE_MODE_ROTATION ||
|
|
ride->mode == RIDE_MODE_FORWARD_ROTATION ||
|
|
ride->mode == RIDE_MODE_BACKWARD_ROTATION
|
|
)
|
|
gGameCommandErrorTitle = STR_CANT_CHANGE_NUMBER_OF_ROTATIONS;
|
|
|
|
set_operating_setting(w->number, RIDE_SETTING_OPERATION_OPTION, value);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B11D5
|
|
*/
|
|
static void window_ride_mode_tweak_increase(rct_window *w)
|
|
{
|
|
Ride *ride = get_ride(w->number);
|
|
|
|
uint8 maxValue = RideProperties[ride->type].max_value;
|
|
uint8 minValue = gCheatsFastLiftHill ? 0 : RideProperties[ride->type].min_value;
|
|
|
|
if (gCheatsFastLiftHill) {
|
|
maxValue = 255;
|
|
}
|
|
|
|
uint8 increment = ride->mode == RIDE_MODE_BUMPERCAR ? 10 : 1;
|
|
|
|
window_ride_mode_tweak_set(w, Math::Clamp<sint16>(minValue, ride->operation_option + increment, maxValue));
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B120A
|
|
*/
|
|
static void window_ride_mode_tweak_decrease(rct_window *w)
|
|
{
|
|
Ride *ride = get_ride(w->number);
|
|
|
|
uint8 maxValue = RideProperties[ride->type].max_value;
|
|
uint8 minValue = gCheatsFastLiftHill ? 0 : RideProperties[ride->type].min_value;
|
|
if (gCheatsFastLiftHill) {
|
|
maxValue = 255;
|
|
}
|
|
|
|
uint8 decrement = ride->mode == RIDE_MODE_BUMPERCAR ? 10 : 1;
|
|
|
|
window_ride_mode_tweak_set(w, Math::Clamp<sint16>(minValue, ride->operation_option - decrement, maxValue));
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B1631
|
|
*/
|
|
static void window_ride_mode_dropdown(rct_window *w, rct_widget *widget)
|
|
{
|
|
rct_widget *dropdownWidget;
|
|
Ride *ride;
|
|
const uint8 *availableModes, *mode;
|
|
sint32 i, numAvailableModes;
|
|
|
|
dropdownWidget = widget - 1;
|
|
ride = get_ride(w->number);
|
|
|
|
// Seek to available modes for this ride
|
|
availableModes = ride_seek_available_modes(ride);
|
|
|
|
// Count number of available modes
|
|
mode = availableModes;
|
|
numAvailableModes = -1;
|
|
do {
|
|
numAvailableModes++;
|
|
} while (*(mode++) != 255);
|
|
|
|
// Create dropdown list
|
|
for (i = 0; i < numAvailableModes; i++) {
|
|
gDropdownItemsFormat[i] = STR_DROPDOWN_MENU_LABEL;
|
|
gDropdownItemsArgs[i] = RideModeNames[availableModes[i]];
|
|
}
|
|
window_dropdown_show_text_custom_width(
|
|
w->x + dropdownWidget->left,
|
|
w->y + dropdownWidget->top,
|
|
dropdownWidget->bottom - dropdownWidget->top + 1,
|
|
w->colours[1],
|
|
0,
|
|
DROPDOWN_FLAG_STAY_OPEN,
|
|
numAvailableModes,
|
|
widget->right - dropdownWidget->left
|
|
);
|
|
|
|
// Set checked item
|
|
for (i = 0; i < numAvailableModes; i++) {
|
|
if (ride->mode == availableModes[i]) {
|
|
dropdown_set_checked(i, true);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B15C0
|
|
*/
|
|
static void window_ride_load_dropdown(rct_window *w, rct_widget *widget)
|
|
{
|
|
rct_widget *dropdownWidget;
|
|
sint32 i;
|
|
|
|
dropdownWidget = widget - 1;
|
|
Ride *ride = get_ride(w->number);
|
|
|
|
for (i = 0; i < 5; i++) {
|
|
gDropdownItemsFormat[i] = STR_DROPDOWN_MENU_LABEL;
|
|
gDropdownItemsArgs[i] = VehicleLoadNames[i];
|
|
}
|
|
window_dropdown_show_text_custom_width(
|
|
w->x + dropdownWidget->left,
|
|
w->y + dropdownWidget->top,
|
|
dropdownWidget->bottom - dropdownWidget->top + 1,
|
|
w->colours[1],
|
|
0,
|
|
DROPDOWN_FLAG_STAY_OPEN,
|
|
5,
|
|
widget->right - dropdownWidget->left
|
|
);
|
|
|
|
dropdown_set_checked(ride->depart_flags & RIDE_DEPART_WAIT_FOR_LOAD_MASK, true);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B10A7
|
|
*/
|
|
static void window_ride_operating_mouseup(rct_window *w, rct_widgetindex widgetIndex)
|
|
{
|
|
Ride *ride;
|
|
|
|
ride = get_ride(w->number);
|
|
|
|
switch (widgetIndex) {
|
|
case WIDX_CLOSE:
|
|
window_close(w);
|
|
break;
|
|
case WIDX_TAB_1:
|
|
case WIDX_TAB_2:
|
|
case WIDX_TAB_3:
|
|
case WIDX_TAB_4:
|
|
case WIDX_TAB_5:
|
|
case WIDX_TAB_6:
|
|
case WIDX_TAB_7:
|
|
case WIDX_TAB_8:
|
|
case WIDX_TAB_9:
|
|
case WIDX_TAB_10:
|
|
window_ride_set_page(w, widgetIndex - WIDX_TAB_1);
|
|
break;
|
|
case WIDX_LOAD_CHECKBOX:
|
|
set_operating_setting(w->number, RIDE_SETTING_DEPARTURE, ride->depart_flags ^ RIDE_DEPART_WAIT_FOR_LOAD);
|
|
break;
|
|
case WIDX_LEAVE_WHEN_ANOTHER_ARRIVES_CHECKBOX:
|
|
set_operating_setting(w->number, RIDE_SETTING_DEPARTURE, ride->depart_flags ^ RIDE_DEPART_LEAVE_WHEN_ANOTHER_ARRIVES);
|
|
break;
|
|
case WIDX_MINIMUM_LENGTH_CHECKBOX:
|
|
set_operating_setting(w->number, RIDE_SETTING_DEPARTURE, ride->depart_flags ^ RIDE_DEPART_WAIT_FOR_MINIMUM_LENGTH);
|
|
break;
|
|
case WIDX_MAXIMUM_LENGTH_CHECKBOX:
|
|
set_operating_setting(w->number, RIDE_SETTING_DEPARTURE, ride->depart_flags ^ RIDE_DEPART_WAIT_FOR_MAXIMUM_LENGTH);
|
|
break;
|
|
case WIDX_SYNCHRONISE_WITH_ADJACENT_STATIONS_CHECKBOX:
|
|
set_operating_setting(w->number, RIDE_SETTING_DEPARTURE, ride->depart_flags ^ RIDE_DEPART_SYNCHRONISE_WITH_ADJACENT_STATIONS);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B1715
|
|
*/
|
|
static void window_ride_operating_resize(rct_window *w)
|
|
{
|
|
window_set_resize(w, 316, 186, 316, 186);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B10F4
|
|
*/
|
|
static void window_ride_operating_mousedown(rct_window *w, rct_widgetindex widgetIndex, rct_widget *widget)
|
|
{
|
|
Ride *ride = get_ride(w->number);
|
|
uint8 upper_bound, lower_bound;
|
|
|
|
switch (widgetIndex) {
|
|
case WIDX_MODE_TWEAK_INCREASE:
|
|
window_ride_mode_tweak_increase(w);
|
|
break;
|
|
case WIDX_MODE_TWEAK_DECREASE:
|
|
window_ride_mode_tweak_decrease(w);
|
|
break;
|
|
case WIDX_LIFT_HILL_SPEED_INCREASE:
|
|
upper_bound = gCheatsFastLiftHill ? 255 : RideLiftData[ride->type].maximum_speed;
|
|
lower_bound = gCheatsFastLiftHill ? 0 : RideLiftData[ride->type].minimum_speed;
|
|
set_operating_setting(w->number, RIDE_SETTING_LIFT_HILL_SPEED, Math::Clamp<sint16>(lower_bound, ride->lift_hill_speed + 1, upper_bound));
|
|
break;
|
|
case WIDX_LIFT_HILL_SPEED_DECREASE:
|
|
upper_bound = gCheatsFastLiftHill ? 255 : RideLiftData[ride->type].maximum_speed;
|
|
lower_bound = gCheatsFastLiftHill ? 0 : RideLiftData[ride->type].minimum_speed;
|
|
set_operating_setting(w->number, RIDE_SETTING_LIFT_HILL_SPEED, Math::Clamp<sint16>(lower_bound, ride->lift_hill_speed - 1, upper_bound));
|
|
break;
|
|
case WIDX_MINIMUM_LENGTH_INCREASE:
|
|
upper_bound = 250;
|
|
lower_bound = 0;
|
|
set_operating_setting(w->number, RIDE_SETTING_MIN_WAITING_TIME, Math::Clamp<sint16>(lower_bound, ride->min_waiting_time + 1, upper_bound));
|
|
break;
|
|
case WIDX_MINIMUM_LENGTH_DECREASE:
|
|
upper_bound = 250;
|
|
lower_bound = 0;
|
|
set_operating_setting(w->number, RIDE_SETTING_MIN_WAITING_TIME, Math::Clamp<sint16>(lower_bound, ride->min_waiting_time - 1, upper_bound));
|
|
break;
|
|
case WIDX_MAXIMUM_LENGTH_INCREASE:
|
|
upper_bound = 250;
|
|
lower_bound = 0;
|
|
set_operating_setting(w->number, RIDE_SETTING_MAX_WAITING_TIME, Math::Clamp<sint16>(lower_bound, ride->max_waiting_time + 1, upper_bound));
|
|
break;
|
|
case WIDX_MAXIMUM_LENGTH_DECREASE:
|
|
upper_bound = 250;
|
|
lower_bound = 0;
|
|
set_operating_setting(w->number, RIDE_SETTING_MAX_WAITING_TIME, Math::Clamp<sint16>(lower_bound, ride->max_waiting_time - 1, upper_bound));
|
|
break;
|
|
case WIDX_MODE_DROPDOWN:
|
|
window_ride_mode_dropdown(w, widget);
|
|
break;
|
|
case WIDX_LOAD_DROPDOWN:
|
|
window_ride_load_dropdown(w, widget);
|
|
break;
|
|
case WIDX_OPERATE_NUMBER_OF_CIRCUITS_INCREASE:
|
|
upper_bound = gCheatsFastLiftHill ? 255 : 20;
|
|
lower_bound = 1;
|
|
set_operating_setting(w->number, RIDE_SETTING_NUM_CIRCUITS, Math::Clamp<sint16>(lower_bound, ride->num_circuits + 1, upper_bound));
|
|
break;
|
|
case WIDX_OPERATE_NUMBER_OF_CIRCUITS_DECREASE:
|
|
upper_bound = gCheatsFastLiftHill ? 255 : 20;
|
|
lower_bound = 1;
|
|
set_operating_setting(w->number, RIDE_SETTING_NUM_CIRCUITS, Math::Clamp<sint16>(lower_bound, ride->num_circuits - 1, upper_bound));
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B1165
|
|
*/
|
|
static void window_ride_operating_dropdown(rct_window *w, rct_widgetindex widgetIndex, sint32 dropdownIndex)
|
|
{
|
|
Ride *ride;
|
|
const uint8 *availableModes;
|
|
|
|
if (dropdownIndex == -1)
|
|
return;
|
|
|
|
ride = get_ride(w->number);
|
|
|
|
switch (widgetIndex) {
|
|
case WIDX_MODE_DROPDOWN:
|
|
// Seek to available modes for this ride
|
|
availableModes = ride_seek_available_modes(ride);
|
|
|
|
set_operating_setting(w->number, RIDE_SETTING_MODE, availableModes[dropdownIndex]);
|
|
break;
|
|
case WIDX_LOAD_DROPDOWN:
|
|
set_operating_setting(w->number, RIDE_SETTING_DEPARTURE, (ride->depart_flags & ~RIDE_DEPART_WAIT_FOR_LOAD_MASK) | dropdownIndex);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B178E
|
|
*/
|
|
static void window_ride_operating_update(rct_window *w)
|
|
{
|
|
Ride *ride;
|
|
|
|
w->frame_no++;
|
|
window_event_invalidate_call(w);
|
|
widget_invalidate(w, WIDX_TAB_3);
|
|
|
|
ride = get_ride(w->number);
|
|
if (ride->window_invalidate_flags & RIDE_INVALIDATE_RIDE_OPERATING) {
|
|
ride->window_invalidate_flags &= ~RIDE_INVALIDATE_RIDE_OPERATING;
|
|
window_invalidate(w);
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B0B30
|
|
*/
|
|
static void window_ride_operating_invalidate(rct_window *w)
|
|
{
|
|
rct_widget *widgets;
|
|
Ride *ride;
|
|
rct_ride_entry *rideEntry;
|
|
rct_string_id format, caption, tooltip;
|
|
|
|
widgets = window_ride_page_widgets[w->page];
|
|
if (w->widgets != widgets) {
|
|
w->widgets = widgets;
|
|
window_init_scroll_widgets(w);
|
|
}
|
|
|
|
window_ride_set_pressed_tab(w);
|
|
|
|
ride = get_ride(w->number);
|
|
rideEntry = get_ride_entry_by_ride(ride);
|
|
|
|
set_format_arg(0, rct_string_id, ride->name);
|
|
set_format_arg(2, uint32, ride->name_arguments);
|
|
|
|
// Widget setup
|
|
w->pressed_widgets &= ~(
|
|
(1ULL << WIDX_LOAD_CHECKBOX) |
|
|
(1ULL << WIDX_LEAVE_WHEN_ANOTHER_ARRIVES_CHECKBOX) |
|
|
(1ULL << WIDX_MINIMUM_LENGTH_CHECKBOX) |
|
|
(1ULL << WIDX_MAXIMUM_LENGTH_CHECKBOX) |
|
|
(1ULL << WIDX_SYNCHRONISE_WITH_ADJACENT_STATIONS_CHECKBOX)
|
|
);
|
|
|
|
// Lift hill speed
|
|
if ((rideEntry->enabledTrackPieces & (1ULL << TRACK_LIFT_HILL)) &&
|
|
track_piece_is_available_for_ride_type(ride->type, TRACK_LIFT_HILL)) {
|
|
window_ride_operating_widgets[WIDX_LIFT_HILL_SPEED_LABEL].type = WWT_LABEL;
|
|
window_ride_operating_widgets[WIDX_LIFT_HILL_SPEED].type = WWT_SPINNER;
|
|
window_ride_operating_widgets[WIDX_LIFT_HILL_SPEED_INCREASE].type = WWT_BUTTON;
|
|
window_ride_operating_widgets[WIDX_LIFT_HILL_SPEED_DECREASE].type = WWT_BUTTON;
|
|
set_format_arg(20, uint16, ride->lift_hill_speed);
|
|
} else {
|
|
window_ride_operating_widgets[WIDX_LIFT_HILL_SPEED_LABEL].type = WWT_EMPTY;
|
|
window_ride_operating_widgets[WIDX_LIFT_HILL_SPEED].type = WWT_EMPTY;
|
|
window_ride_operating_widgets[WIDX_LIFT_HILL_SPEED_INCREASE].type = WWT_EMPTY;
|
|
window_ride_operating_widgets[WIDX_LIFT_HILL_SPEED_DECREASE].type = WWT_EMPTY;
|
|
}
|
|
|
|
// Number of circuits
|
|
if (ride_can_have_multiple_circuits(ride)) {
|
|
window_ride_operating_widgets[WIDX_OPERATE_NUMBER_OF_CIRCUITS_LABEL].type = WWT_LABEL;
|
|
window_ride_operating_widgets[WIDX_OPERATE_NUMBER_OF_CIRCUITS].type = WWT_SPINNER;
|
|
window_ride_operating_widgets[WIDX_OPERATE_NUMBER_OF_CIRCUITS_INCREASE].type = WWT_BUTTON;
|
|
window_ride_operating_widgets[WIDX_OPERATE_NUMBER_OF_CIRCUITS_DECREASE].type = WWT_BUTTON;
|
|
set_format_arg(22, uint16, ride->num_circuits);
|
|
} else {
|
|
window_ride_operating_widgets[WIDX_OPERATE_NUMBER_OF_CIRCUITS_LABEL].type = WWT_EMPTY;
|
|
window_ride_operating_widgets[WIDX_OPERATE_NUMBER_OF_CIRCUITS].type = WWT_EMPTY;
|
|
window_ride_operating_widgets[WIDX_OPERATE_NUMBER_OF_CIRCUITS_INCREASE].type = WWT_EMPTY;
|
|
window_ride_operating_widgets[WIDX_OPERATE_NUMBER_OF_CIRCUITS_DECREASE].type = WWT_EMPTY;
|
|
}
|
|
|
|
// Leave if another vehicle arrives at station
|
|
if (
|
|
ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_HAS_LEAVE_WHEN_ANOTHER_VEHICLE_ARRIVES_AT_STATION) &&
|
|
ride->num_vehicles > 1 &&
|
|
ride->mode != RIDE_MODE_CONTINUOUS_CIRCUIT_BLOCK_SECTIONED &&
|
|
ride->mode != RIDE_MODE_POWERED_LAUNCH_BLOCK_SECTIONED
|
|
) {
|
|
window_ride_operating_widgets[WIDX_LEAVE_WHEN_ANOTHER_ARRIVES_CHECKBOX].type = WWT_CHECKBOX;
|
|
window_ride_operating_widgets[WIDX_LEAVE_WHEN_ANOTHER_ARRIVES_CHECKBOX].tooltip = STR_LEAVE_IF_ANOTHER_VEHICLE_ARRIVES_TIP;
|
|
window_ride_operating_widgets[WIDX_LEAVE_WHEN_ANOTHER_ARRIVES_CHECKBOX].text = RideNameConvention[ride->type].vehicle == RIDE_COMPONENT_TYPE_BOAT ?
|
|
STR_LEAVE_IF_ANOTHER_BOAT_ARRIVES :
|
|
STR_LEAVE_IF_ANOTHER_TRAIN_ARRIVES;
|
|
} else {
|
|
window_ride_operating_widgets[WIDX_LEAVE_WHEN_ANOTHER_ARRIVES_CHECKBOX].type = WWT_EMPTY;
|
|
}
|
|
|
|
// Synchronise with adjacent stations
|
|
if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_CAN_SYNCHRONISE_ADJACENT_STATIONS)) {
|
|
window_ride_operating_widgets[WIDX_SYNCHRONISE_WITH_ADJACENT_STATIONS_CHECKBOX].type = WWT_CHECKBOX;
|
|
window_ride_operating_widgets[WIDX_SYNCHRONISE_WITH_ADJACENT_STATIONS_CHECKBOX].image = STR_SYNCHRONISE_WITH_ADJACENT_STATIONS;
|
|
window_ride_operating_widgets[WIDX_SYNCHRONISE_WITH_ADJACENT_STATIONS_CHECKBOX].tooltip = STR_SYNCHRONISE_WITH_ADJACENT_STATIONS_TIP;
|
|
} else {
|
|
window_ride_operating_widgets[WIDX_SYNCHRONISE_WITH_ADJACENT_STATIONS_CHECKBOX].type = WWT_EMPTY;
|
|
}
|
|
|
|
// Mode
|
|
window_ride_operating_widgets[WIDX_MODE].text = RideModeNames[ride->mode];
|
|
|
|
// Waiting
|
|
window_ride_operating_widgets[WIDX_LOAD].text = VehicleLoadNames[(ride->depart_flags & RIDE_DEPART_WAIT_FOR_LOAD_MASK)];
|
|
if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_HAS_LOAD_OPTIONS)) {
|
|
window_ride_operating_widgets[WIDX_LOAD_CHECKBOX].type = WWT_CHECKBOX;
|
|
window_ride_operating_widgets[WIDX_LOAD].type = WWT_DROPDOWN;
|
|
window_ride_operating_widgets[WIDX_LOAD_DROPDOWN].type = WWT_BUTTON;
|
|
|
|
window_ride_operating_widgets[WIDX_MINIMUM_LENGTH_CHECKBOX].type = WWT_CHECKBOX;
|
|
window_ride_operating_widgets[WIDX_MINIMUM_LENGTH].type = WWT_SPINNER;
|
|
window_ride_operating_widgets[WIDX_MINIMUM_LENGTH_INCREASE].type = WWT_BUTTON;
|
|
window_ride_operating_widgets[WIDX_MINIMUM_LENGTH_DECREASE].type = WWT_BUTTON;
|
|
|
|
window_ride_operating_widgets[WIDX_MAXIMUM_LENGTH_CHECKBOX].type = WWT_CHECKBOX;
|
|
window_ride_operating_widgets[WIDX_MAXIMUM_LENGTH].type = WWT_SPINNER;
|
|
window_ride_operating_widgets[WIDX_MAXIMUM_LENGTH_INCREASE].type = WWT_BUTTON;
|
|
window_ride_operating_widgets[WIDX_MAXIMUM_LENGTH_DECREASE].type = WWT_BUTTON;
|
|
|
|
set_format_arg(10, rct_string_id, STR_FORMAT_SECONDS);
|
|
set_format_arg(12, uint16, ride->min_waiting_time);
|
|
set_format_arg(14, rct_string_id, STR_FORMAT_SECONDS);
|
|
set_format_arg(16, uint16, ride->max_waiting_time);
|
|
|
|
if (ride->depart_flags & RIDE_DEPART_WAIT_FOR_LOAD)
|
|
w->pressed_widgets |= (1 << WIDX_LOAD_CHECKBOX);
|
|
} else {
|
|
window_ride_operating_widgets[WIDX_LOAD_CHECKBOX].type = WWT_EMPTY;
|
|
window_ride_operating_widgets[WIDX_LOAD].type = WWT_EMPTY;
|
|
window_ride_operating_widgets[WIDX_LOAD_DROPDOWN].type = WWT_EMPTY;
|
|
|
|
window_ride_operating_widgets[WIDX_MINIMUM_LENGTH_CHECKBOX].type = WWT_EMPTY;
|
|
window_ride_operating_widgets[WIDX_MINIMUM_LENGTH].type = WWT_EMPTY;
|
|
window_ride_operating_widgets[WIDX_MINIMUM_LENGTH_INCREASE].type = WWT_EMPTY;
|
|
window_ride_operating_widgets[WIDX_MINIMUM_LENGTH_DECREASE].type = WWT_EMPTY;
|
|
|
|
window_ride_operating_widgets[WIDX_MAXIMUM_LENGTH_CHECKBOX].type = WWT_EMPTY;
|
|
window_ride_operating_widgets[WIDX_MAXIMUM_LENGTH].type = WWT_EMPTY;
|
|
window_ride_operating_widgets[WIDX_MAXIMUM_LENGTH_INCREASE].type = WWT_EMPTY;
|
|
window_ride_operating_widgets[WIDX_MAXIMUM_LENGTH_DECREASE].type = WWT_EMPTY;
|
|
}
|
|
|
|
if (ride->depart_flags & RIDE_DEPART_LEAVE_WHEN_ANOTHER_ARRIVES)
|
|
w->pressed_widgets |= (1 << WIDX_LEAVE_WHEN_ANOTHER_ARRIVES_CHECKBOX);
|
|
if (ride->depart_flags & RIDE_DEPART_SYNCHRONISE_WITH_ADJACENT_STATIONS)
|
|
w->pressed_widgets |= (1 << WIDX_SYNCHRONISE_WITH_ADJACENT_STATIONS_CHECKBOX);
|
|
if (ride->depart_flags & RIDE_DEPART_WAIT_FOR_MINIMUM_LENGTH)
|
|
w->pressed_widgets |= (1 << WIDX_MINIMUM_LENGTH_CHECKBOX);
|
|
if (ride->depart_flags & RIDE_DEPART_WAIT_FOR_MAXIMUM_LENGTH)
|
|
w->pressed_widgets |= (1 << WIDX_MAXIMUM_LENGTH_CHECKBOX);
|
|
|
|
// Mode specific functionality
|
|
set_format_arg(18, uint16, ride->operation_option);
|
|
switch (ride->mode) {
|
|
case RIDE_MODE_POWERED_LAUNCH_PASSTROUGH:
|
|
case RIDE_MODE_POWERED_LAUNCH:
|
|
case RIDE_MODE_UPWARD_LAUNCH:
|
|
case RIDE_MODE_POWERED_LAUNCH_BLOCK_SECTIONED:
|
|
set_format_arg(18, uint16, (ride->launch_speed * 9) / 4);
|
|
format = STR_RIDE_MODE_SPEED_VALUE;
|
|
caption = STR_LAUNCH_SPEED;
|
|
tooltip = STR_LAUNCH_SPEED_TIP;
|
|
break;
|
|
case RIDE_MODE_STATION_TO_STATION:
|
|
set_format_arg(18, uint16, (ride->speed * 9) / 4);
|
|
format = STR_RIDE_MODE_SPEED_VALUE;
|
|
caption = STR_SPEED;
|
|
tooltip = STR_SPEED_TIP;
|
|
break;
|
|
case RIDE_MODE_RACE:
|
|
set_format_arg(18, uint16, ride->num_laps);
|
|
format = STR_NUMBER_OF_LAPS_VALUE;
|
|
caption = STR_NUMBER_OF_LAPS;
|
|
tooltip = STR_NUMBER_OF_LAPS_TIP;
|
|
break;
|
|
case RIDE_MODE_BUMPERCAR:
|
|
format = STR_RIDE_MODE_TIME_LIMIT_VALUE;
|
|
caption = STR_TIME_LIMIT;
|
|
tooltip = STR_TIME_LIMIT_TIP;
|
|
break;
|
|
case RIDE_MODE_SWING:
|
|
format = STR_RIDE_MODE_NUMBER_OF_SWINGS_VALUE;
|
|
caption = STR_NUMBER_OF_SWINGS;
|
|
tooltip = STR_NUMBER_OF_SWINGS_TIP;
|
|
break;
|
|
case RIDE_MODE_ROTATION:
|
|
case RIDE_MODE_FORWARD_ROTATION:
|
|
case RIDE_MODE_BACKWARD_ROTATION:
|
|
format = STR_NUMBER_OF_ROTATIONS_VALUE;
|
|
caption = STR_NUMBER_OF_ROTATIONS;
|
|
tooltip = STR_NUMBER_OF_ROTATIONS_TIP;
|
|
break;
|
|
default:
|
|
format = STR_MAX_PEOPLE_ON_RIDE_VALUE;
|
|
caption = STR_MAX_PEOPLE_ON_RIDE;
|
|
tooltip = STR_MAX_PEOPLE_ON_RIDE_TIP;
|
|
if (!ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_NO_VEHICLES))
|
|
format = 0;
|
|
break;
|
|
}
|
|
|
|
if (format != 0) {
|
|
if (ride->type == RIDE_TYPE_TWIST) {
|
|
uint16 arg;
|
|
memcpy(&arg, gCommonFormatArgs + 18, sizeof(uint16));
|
|
set_format_arg(18, uint16, arg * 3);
|
|
}
|
|
|
|
window_ride_operating_widgets[WIDX_MODE_TWEAK_LABEL].type = WWT_LABEL;
|
|
window_ride_operating_widgets[WIDX_MODE_TWEAK_LABEL].text = caption;
|
|
window_ride_operating_widgets[WIDX_MODE_TWEAK_LABEL].tooltip = tooltip;
|
|
window_ride_operating_widgets[WIDX_MODE_TWEAK].type = WWT_SPINNER;
|
|
window_ride_operating_widgets[WIDX_MODE_TWEAK].text = format;
|
|
window_ride_operating_widgets[WIDX_MODE_TWEAK_INCREASE].type = WWT_BUTTON;
|
|
window_ride_operating_widgets[WIDX_MODE_TWEAK_DECREASE].type = WWT_BUTTON;
|
|
w->pressed_widgets &= ~(1 << WIDX_LEAVE_WHEN_ANOTHER_ARRIVES_CHECKBOX);
|
|
} else {
|
|
window_ride_operating_widgets[WIDX_MODE_TWEAK_LABEL].type = WWT_EMPTY;
|
|
window_ride_operating_widgets[WIDX_MODE_TWEAK].type = WWT_EMPTY;
|
|
window_ride_operating_widgets[WIDX_MODE_TWEAK_INCREASE].type = WWT_EMPTY;
|
|
window_ride_operating_widgets[WIDX_MODE_TWEAK_DECREASE].type = WWT_EMPTY;
|
|
}
|
|
|
|
window_ride_anchor_border_widgets(w);
|
|
window_align_tabs(w, WIDX_TAB_1, WIDX_TAB_10);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B1001
|
|
*/
|
|
static void window_ride_operating_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
|
{
|
|
Ride *ride;
|
|
uint16 blockSections;
|
|
|
|
window_draw_widgets(w, dpi);
|
|
window_ride_draw_tab_images(dpi, w);
|
|
|
|
ride = get_ride(w->number);
|
|
|
|
// Horizontal rule between mode settings and depart settings
|
|
gfx_fill_rect_inset(
|
|
dpi,
|
|
w->x + window_ride_operating_widgets[WIDX_PAGE_BACKGROUND].left + 4,
|
|
w->y + 103,
|
|
w->x + window_ride_operating_widgets[WIDX_PAGE_BACKGROUND].right - 5,
|
|
w->y + 104,
|
|
w->colours[1],
|
|
INSET_RECT_FLAG_BORDER_INSET
|
|
);
|
|
|
|
// Number of block sections
|
|
if (ride->mode == RIDE_MODE_CONTINUOUS_CIRCUIT_BLOCK_SECTIONED || ride->mode == RIDE_MODE_POWERED_LAUNCH_BLOCK_SECTIONED) {
|
|
blockSections = ride->num_block_brakes + ride->num_stations;
|
|
gfx_draw_string_left(dpi, STR_BLOCK_SECTIONS, &blockSections, COLOUR_BLACK, w->x + 21,
|
|
ride->mode == RIDE_MODE_POWERED_LAUNCH_BLOCK_SECTIONED ? w->y + 89 : w->y + 61);
|
|
}
|
|
}
|
|
|
|
#pragma endregion
|
|
|
|
#pragma region Maintenance
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B1AE4
|
|
*/
|
|
static void window_ride_locate_mechanic(rct_window *w)
|
|
{
|
|
Ride *ride;
|
|
rct_peep *mechanic;
|
|
|
|
ride = get_ride(w->number);
|
|
|
|
// First check if there is a mechanic assigned
|
|
mechanic = ride_get_assigned_mechanic(ride);
|
|
|
|
// Otherwise find the closest mechanic
|
|
if (mechanic == nullptr)
|
|
mechanic = ride_find_closest_mechanic(ride, 1);
|
|
|
|
if (mechanic == nullptr)
|
|
context_show_error(STR_UNABLE_TO_LOCATE_MECHANIC, STR_NONE);
|
|
else
|
|
{
|
|
auto intent = Intent(WC_PEEP);
|
|
intent.putExtra(INTENT_EXTRA_PEEP, mechanic);
|
|
context_open_intent(&intent);
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B7D08
|
|
*/
|
|
static void window_ride_maintenance_draw_bar(rct_window *w, rct_drawpixelinfo *dpi, sint32 x, sint32 y, sint32 value, sint32 colour)
|
|
{
|
|
gfx_fill_rect_inset(dpi, x, y, x + 149, y + 8, w->colours[1], INSET_RECT_F_30);
|
|
if (colour & BAR_BLINK) {
|
|
colour &= ~BAR_BLINK;
|
|
if (game_is_not_paused() && (gCurrentTicks & 8))
|
|
return;
|
|
}
|
|
|
|
value = ((186 * ((value * 2) & 0xFF)) >> 8) & 0xFF;
|
|
if (value > 2) {
|
|
gfx_fill_rect_inset(dpi, x + 2, y + 1, x + value + 1, y + 7, colour, 0);
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B1AAD
|
|
*/
|
|
static void window_ride_maintenance_mouseup(rct_window *w, rct_widgetindex widgetIndex)
|
|
{
|
|
switch (widgetIndex) {
|
|
case WIDX_CLOSE:
|
|
window_close(w);
|
|
break;
|
|
case WIDX_TAB_1:
|
|
case WIDX_TAB_2:
|
|
case WIDX_TAB_3:
|
|
case WIDX_TAB_4:
|
|
case WIDX_TAB_5:
|
|
case WIDX_TAB_6:
|
|
case WIDX_TAB_7:
|
|
case WIDX_TAB_8:
|
|
case WIDX_TAB_9:
|
|
case WIDX_TAB_10:
|
|
window_ride_set_page(w, widgetIndex - WIDX_TAB_1);
|
|
break;
|
|
case WIDX_LOCATE_MECHANIC:
|
|
window_ride_locate_mechanic(w);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B1D70
|
|
*/
|
|
static void window_ride_maintenance_resize(rct_window *w)
|
|
{
|
|
window_set_resize(w, 316, 135, 316, 135);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B1ACE
|
|
*/
|
|
static void window_ride_maintenance_mousedown(rct_window *w, rct_widgetindex widgetIndex, rct_widget *widget)
|
|
{
|
|
Ride *ride = get_ride(w->number);
|
|
rct_ride_entry * rideEntry = get_ride_entry(ride->subtype);
|
|
if (rideEntry == nullptr)
|
|
{
|
|
return;
|
|
}
|
|
|
|
rct_widget *dropdownWidget = widget;
|
|
sint32 j, num_items;
|
|
|
|
switch (widgetIndex) {
|
|
case WIDX_INSPECTION_INTERVAL_DROPDOWN:
|
|
dropdownWidget--;
|
|
for (sint32 i = 0; i < 7; i++) {
|
|
gDropdownItemsFormat[i] = STR_DROPDOWN_MENU_LABEL;
|
|
gDropdownItemsArgs[i] = RideInspectionIntervalNames[i];
|
|
}
|
|
window_dropdown_show_text_custom_width(
|
|
w->x + dropdownWidget->left,
|
|
w->y + dropdownWidget->top,
|
|
dropdownWidget->bottom - dropdownWidget->top + 1,
|
|
w->colours[1],
|
|
0,
|
|
DROPDOWN_FLAG_STAY_OPEN,
|
|
7,
|
|
widget->right - dropdownWidget->left
|
|
);
|
|
|
|
dropdown_set_checked(ride->inspection_interval, true);
|
|
break;
|
|
|
|
case WIDX_FORCE_BREAKDOWN:
|
|
num_items = 1;
|
|
for (j = 0; j < MAX_RIDE_TYPES_PER_RIDE_ENTRY; j++) {
|
|
if (rideEntry->ride_type[j] != 0xFF)
|
|
break;
|
|
}
|
|
gDropdownItemsFormat[0] = STR_DROPDOWN_MENU_LABEL;
|
|
gDropdownItemsArgs[0] = STR_DEBUG_FIX_RIDE;
|
|
for (sint32 i = 0; i < 8; i++) {
|
|
assert(j < (sint32)Util::CountOf(rideEntry->ride_type));
|
|
if (RideAvailableBreakdowns[rideEntry->ride_type[j]] & (uint8)(1 << i)) {
|
|
if (i == BREAKDOWN_BRAKES_FAILURE && (ride->mode == RIDE_MODE_CONTINUOUS_CIRCUIT_BLOCK_SECTIONED || ride->mode == RIDE_MODE_POWERED_LAUNCH_BLOCK_SECTIONED)) {
|
|
if (ride->num_vehicles != 1)
|
|
continue;
|
|
}
|
|
gDropdownItemsFormat[num_items] = STR_DROPDOWN_MENU_LABEL;
|
|
gDropdownItemsArgs[num_items] = RideBreakdownReasonNames[i];
|
|
num_items++;
|
|
}
|
|
}
|
|
if (num_items == 1) {
|
|
context_show_error(STR_DEBUG_NO_BREAKDOWNS_AVAILABLE, STR_NONE);
|
|
}
|
|
else {
|
|
window_dropdown_show_text(
|
|
w->x + dropdownWidget->left,
|
|
w->y + dropdownWidget->top,
|
|
dropdownWidget->bottom - dropdownWidget->top + 1,
|
|
w->colours[1],
|
|
DROPDOWN_FLAG_STAY_OPEN,
|
|
num_items
|
|
);
|
|
|
|
num_items = 1;
|
|
sint32 breakdownReason = ride->breakdown_reason_pending;
|
|
if (breakdownReason != BREAKDOWN_NONE && (ride->lifecycle_flags & RIDE_LIFECYCLE_BREAKDOWN_PENDING)) {
|
|
for (sint32 i = 0; i < 8; i++) {
|
|
if (RideAvailableBreakdowns[rideEntry->ride_type[j]] & (uint8)(1 << i)) {
|
|
if (i == BREAKDOWN_BRAKES_FAILURE && (ride->mode == RIDE_MODE_CONTINUOUS_CIRCUIT_BLOCK_SECTIONED || ride->mode == RIDE_MODE_POWERED_LAUNCH_BLOCK_SECTIONED)) {
|
|
if (ride->num_vehicles != 1)
|
|
continue;
|
|
}
|
|
if (i == breakdownReason) {
|
|
dropdown_set_checked(num_items, true);
|
|
break;
|
|
}
|
|
gDropdownItemsFormat[num_items] = STR_DROPDOWN_MENU_LABEL;
|
|
gDropdownItemsArgs[num_items] = RideBreakdownReasonNames[i];
|
|
num_items++;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ((ride->lifecycle_flags & RIDE_LIFECYCLE_BREAKDOWN_PENDING) == 0) {
|
|
dropdown_set_disabled(0, true);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B1AD9
|
|
*/
|
|
static void window_ride_maintenance_dropdown(rct_window *w, rct_widgetindex widgetIndex, sint32 dropdownIndex)
|
|
{
|
|
if (dropdownIndex == -1)
|
|
return;
|
|
|
|
rct_vehicle *vehicle;
|
|
Ride *ride = get_ride(w->number);
|
|
rct_ride_entry * rideEntry = get_ride_entry(ride->subtype);
|
|
|
|
switch (widgetIndex) {
|
|
case WIDX_INSPECTION_INTERVAL_DROPDOWN:
|
|
gGameCommandErrorTitle = STR_CANT_CHANGE_OPERATING_MODE;
|
|
game_do_command(0, (dropdownIndex << 8) | 1, 0, (5 << 8) | w->number, GAME_COMMAND_SET_RIDE_SETTING, 0, 0);
|
|
break;
|
|
|
|
case WIDX_FORCE_BREAKDOWN:
|
|
if (dropdownIndex == 0) {
|
|
switch (ride->breakdown_reason_pending) {
|
|
case BREAKDOWN_SAFETY_CUT_OUT:
|
|
if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK))
|
|
break;
|
|
for (sint32 i = 0; i < ride->num_vehicles; ++i) {
|
|
uint16 spriteId = ride->vehicles[i];
|
|
while (spriteId != SPRITE_INDEX_NULL) {
|
|
vehicle = GET_VEHICLE(spriteId);
|
|
vehicle->update_flags &= ~(
|
|
VEHICLE_UPDATE_FLAG_BROKEN_CAR |
|
|
VEHICLE_UPDATE_FLAG_ZERO_VELOCITY |
|
|
VEHICLE_UPDATE_FLAG_BROKEN_TRAIN
|
|
);
|
|
spriteId = vehicle->next_vehicle_on_train;
|
|
}
|
|
}
|
|
break;
|
|
case BREAKDOWN_RESTRAINTS_STUCK_CLOSED:
|
|
case BREAKDOWN_RESTRAINTS_STUCK_OPEN:
|
|
case BREAKDOWN_DOORS_STUCK_CLOSED:
|
|
case BREAKDOWN_DOORS_STUCK_OPEN:
|
|
vehicle = &(get_sprite(ride->vehicles[ride->broken_vehicle])->vehicle);
|
|
vehicle->update_flags &= ~VEHICLE_UPDATE_FLAG_BROKEN_CAR;
|
|
break;
|
|
case BREAKDOWN_VEHICLE_MALFUNCTION:
|
|
vehicle = &(get_sprite(ride->vehicles[ride->broken_vehicle])->vehicle);
|
|
vehicle->update_flags &= ~VEHICLE_UPDATE_FLAG_BROKEN_TRAIN;
|
|
break;
|
|
}
|
|
ride->lifecycle_flags &= ~(RIDE_LIFECYCLE_BREAKDOWN_PENDING | RIDE_LIFECYCLE_BROKEN_DOWN);
|
|
window_invalidate_by_number(WC_RIDE, w->number);
|
|
break;
|
|
}
|
|
if (ride->lifecycle_flags & (RIDE_LIFECYCLE_BREAKDOWN_PENDING | RIDE_LIFECYCLE_BROKEN_DOWN | RIDE_LIFECYCLE_CRASHED)) {
|
|
context_show_error(STR_DEBUG_CANT_FORCE_BREAKDOWN, STR_DEBUG_RIDE_ALREADY_BROKEN);
|
|
}
|
|
else if (ride->status == RIDE_STATUS_CLOSED) {
|
|
context_show_error(STR_DEBUG_CANT_FORCE_BREAKDOWN, STR_DEBUG_RIDE_IS_CLOSED);
|
|
}
|
|
else {
|
|
sint32 j;
|
|
for (j = 0; j < MAX_RIDE_TYPES_PER_RIDE_ENTRY; j++) {
|
|
if (rideEntry->ride_type[j] != RIDE_TYPE_NULL)
|
|
break;
|
|
}
|
|
sint32 i;
|
|
sint32 num_items = 1;
|
|
for (i = 0; i < BREAKDOWN_COUNT; i++) {
|
|
assert(j < (sint32)Util::CountOf(rideEntry->ride_type));
|
|
if (RideAvailableBreakdowns[rideEntry->ride_type[j]] & (uint8)(1 << i)) {
|
|
if (i == BREAKDOWN_BRAKES_FAILURE && (ride->mode == RIDE_MODE_CONTINUOUS_CIRCUIT_BLOCK_SECTIONED || ride->mode == RIDE_MODE_POWERED_LAUNCH_BLOCK_SECTIONED)) {
|
|
if (ride->num_vehicles != 1)
|
|
continue;
|
|
}
|
|
if (num_items == dropdownIndex)
|
|
break;
|
|
num_items++;
|
|
}
|
|
}
|
|
ride_prepare_breakdown(w->number, i);
|
|
}
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B1D37
|
|
*/
|
|
static void window_ride_maintenance_update(rct_window *w)
|
|
{
|
|
Ride *ride;
|
|
|
|
w->frame_no++;
|
|
window_event_invalidate_call(w);
|
|
widget_invalidate(w, WIDX_TAB_4);
|
|
|
|
ride = get_ride(w->number);
|
|
if (ride->window_invalidate_flags & RIDE_INVALIDATE_RIDE_MAINTENANCE) {
|
|
ride->window_invalidate_flags &= ~RIDE_INVALIDATE_RIDE_MAINTENANCE;
|
|
window_invalidate(w);
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B17C8
|
|
*/
|
|
static void window_ride_maintenance_invalidate(rct_window *w)
|
|
{
|
|
rct_widget *widgets;
|
|
|
|
widgets = window_ride_page_widgets[w->page];
|
|
if (w->widgets != widgets) {
|
|
w->widgets = widgets;
|
|
window_init_scroll_widgets(w);
|
|
}
|
|
|
|
window_ride_set_pressed_tab(w);
|
|
|
|
Ride *ride = get_ride(w->number);
|
|
set_format_arg(0, rct_string_id, ride->name);
|
|
set_format_arg(2, uint32, ride->name_arguments);
|
|
|
|
window_ride_maintenance_widgets[WIDX_INSPECTION_INTERVAL].text = RideInspectionIntervalNames[ride->inspection_interval];
|
|
|
|
window_ride_anchor_border_widgets(w);
|
|
window_align_tabs(w, WIDX_TAB_1, WIDX_TAB_10);
|
|
|
|
if (gConfigGeneral.debugging_tools && network_get_mode() == NETWORK_MODE_NONE) {
|
|
window_ride_maintenance_widgets[WIDX_FORCE_BREAKDOWN].type = WWT_FLATBTN;
|
|
}
|
|
else {
|
|
window_ride_maintenance_widgets[WIDX_FORCE_BREAKDOWN].type = WWT_EMPTY;
|
|
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B1877
|
|
*/
|
|
static void window_ride_maintenance_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
|
{
|
|
window_draw_widgets(w, dpi);
|
|
window_ride_draw_tab_images(dpi, w);
|
|
|
|
Ride *ride = get_ride(w->number);
|
|
|
|
// Locate mechanic button image
|
|
rct_widget *widget = &window_ride_maintenance_widgets[WIDX_LOCATE_MECHANIC];
|
|
sint32 x = w->x + widget->left;
|
|
sint32 y = w->y + widget->top;
|
|
gfx_draw_sprite(dpi, (gStaffMechanicColour << 24) | IMAGE_TYPE_REMAP | IMAGE_TYPE_REMAP_2_PLUS | SPR_MECHANIC, x, y, 0);
|
|
|
|
// Inspection label
|
|
widget = &window_ride_maintenance_widgets[WIDX_INSPECTION_INTERVAL];
|
|
x = w->x + 4;
|
|
y = w->y + widget->top + 1;
|
|
gfx_draw_string_left(dpi, STR_INSPECTION, nullptr, COLOUR_BLACK, x, y);
|
|
|
|
// Reliability
|
|
widget = &window_ride_maintenance_widgets[WIDX_PAGE_BACKGROUND];
|
|
x = w->x + widget->left + 4;
|
|
y = w->y + widget->top + 4;
|
|
|
|
uint16 reliability = ride->reliability_percentage;
|
|
gfx_draw_string_left(dpi, STR_RELIABILITY_LABEL_1757, &reliability, COLOUR_BLACK, x, y);
|
|
window_ride_maintenance_draw_bar(w, dpi, x + 103, y, Math::Max<sint32>(10, reliability), COLOUR_BRIGHT_GREEN);
|
|
y += 11;
|
|
|
|
uint16 downTime = ride->downtime;
|
|
gfx_draw_string_left(dpi, STR_DOWN_TIME_LABEL_1889, &downTime, COLOUR_BLACK, x, y);
|
|
window_ride_maintenance_draw_bar(w, dpi, x + 103, y, downTime, COLOUR_BRIGHT_RED);
|
|
y += 26;
|
|
|
|
// Last inspection
|
|
uint16 lastInspection = ride->last_inspection;
|
|
|
|
// Use singular form for 1 minute of time or less
|
|
rct_string_id stringId;
|
|
if (lastInspection <= 1)
|
|
stringId = STR_TIME_SINCE_LAST_INSPECTION_MINUTE;
|
|
else if (lastInspection <= 240)
|
|
stringId = STR_TIME_SINCE_LAST_INSPECTION_MINUTES;
|
|
else
|
|
stringId = STR_TIME_SINCE_LAST_INSPECTION_MORE_THAN_4_HOURS;
|
|
|
|
gfx_draw_string_left(dpi, stringId, &lastInspection, COLOUR_BLACK, x, y);
|
|
y += 12;
|
|
|
|
// Last / current breakdown
|
|
if (ride->breakdown_reason == BREAKDOWN_NONE)
|
|
return;
|
|
|
|
stringId = (ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN) ?
|
|
STR_CURRENT_BREAKDOWN :
|
|
STR_LAST_BREAKDOWN;
|
|
rct_string_id breakdownMessage = RideBreakdownReasonNames[ride->breakdown_reason];
|
|
gfx_draw_string_left(dpi, stringId, &breakdownMessage, COLOUR_BLACK, x, y);
|
|
y += 10;
|
|
|
|
// Mechanic status
|
|
if (ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN) {
|
|
rct_peep *peep;
|
|
uint16 spriteIndex;
|
|
|
|
switch (ride->mechanic_status) {
|
|
case RIDE_MECHANIC_STATUS_CALLING:
|
|
stringId = STR_NO_MECHANICS_ARE_HIRED_MESSAGE;
|
|
|
|
FOR_ALL_STAFF(spriteIndex, peep) {
|
|
if (peep->staff_type == STAFF_TYPE_MECHANIC) {
|
|
stringId = STR_CALLING_MECHANIC;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case RIDE_MECHANIC_STATUS_HEADING:
|
|
stringId = STR_MEHCANIC_IS_HEADING_FOR_THE_RIDE;
|
|
break;
|
|
case RIDE_MECHANIC_STATUS_FIXING:
|
|
case RIDE_MECHANIC_STATUS_HAS_FIXED_STATION_BRAKES:
|
|
stringId = STR_MEHCANIC_IS_FIXING_THE_RIDE;
|
|
break;
|
|
default:
|
|
stringId = STR_EMPTY;
|
|
break;
|
|
}
|
|
|
|
if (stringId != STR_EMPTY) {
|
|
if (stringId == STR_CALLING_MECHANIC || stringId == STR_NO_MECHANICS_ARE_HIRED_MESSAGE) {
|
|
gfx_draw_string_left_wrapped(dpi, nullptr, x + 4, y, 280, stringId, COLOUR_BLACK);
|
|
} else {
|
|
rct_peep *mechanicSprite = &(get_sprite(ride->mechanic)->peep);
|
|
if (peep_is_mechanic(mechanicSprite)) {
|
|
set_format_arg(0, rct_string_id, mechanicSprite->name_string_idx);
|
|
set_format_arg(2, uint32, mechanicSprite->id);
|
|
gfx_draw_string_left_wrapped(dpi, gCommonFormatArgs, x + 4, y, 280, stringId, COLOUR_BLACK);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#pragma endregion
|
|
|
|
#pragma region Colour
|
|
|
|
static constexpr const uint8 window_ride_entrance_style_list[] = {
|
|
RIDE_ENTRANCE_STYLE_PLAIN,
|
|
RIDE_ENTRANCE_STYLE_CANVAS_TENT,
|
|
RIDE_ENTRANCE_STYLE_WOODEN,
|
|
RIDE_ENTRANCE_STYLE_CASTLE_BROWN,
|
|
RIDE_ENTRANCE_STYLE_CASTLE_GREY,
|
|
RIDE_ENTRANCE_STYLE_LOG_CABIN,
|
|
RIDE_ENTRANCE_STYLE_JUNGLE,
|
|
RIDE_ENTRANCE_STYLE_CLASSICAL_ROMAN,
|
|
RIDE_ENTRANCE_STYLE_ABSTRACT,
|
|
RIDE_ENTRANCE_STYLE_SNOW_ICE,
|
|
RIDE_ENTRANCE_STYLE_PAGODA,
|
|
RIDE_ENTRANCE_STYLE_SPACE,
|
|
RIDE_ENTRANCE_STYLE_NONE
|
|
};
|
|
|
|
static uint32 window_ride_get_colour_button_image(sint32 colour)
|
|
{
|
|
return IMAGE_TYPE_TRANSPARENT | SPRITE_ID_PALETTE_COLOUR_1(colour) | SPR_PALETTE_BTN;
|
|
}
|
|
|
|
static sint32 window_ride_has_track_colour(Ride *ride, sint32 trackColour)
|
|
{
|
|
uint16 colourUse = RideEntranceDefinitions[ride->entrance_style].colour_use_flags;
|
|
|
|
switch (trackColour) {
|
|
case 0: return ((colourUse & 1) && !ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_IS_SHOP)) || ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_HAS_TRACK_COLOUR_MAIN);
|
|
case 1: return ((colourUse & 2) && !ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_IS_SHOP)) || ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_HAS_TRACK_COLOUR_ADDITIONAL);
|
|
case 2: return ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_HAS_TRACK_COLOUR_SUPPORTS);
|
|
default: return 0;
|
|
}
|
|
}
|
|
|
|
static void window_ride_set_track_colour_scheme(rct_window *w, sint32 x, sint32 y)
|
|
{
|
|
rct_tile_element *tileElement;
|
|
uint8 newColourScheme;
|
|
sint32 interactionType, z, direction;
|
|
|
|
newColourScheme = (uint8)w->ride_colour;
|
|
|
|
LocationXY16 mapCoord = { 0 };
|
|
get_map_coordinates_from_pos(x, y, VIEWPORT_INTERACTION_MASK_RIDE, &mapCoord.x, &mapCoord.y, &interactionType, &tileElement, nullptr);
|
|
x = mapCoord.x;
|
|
y = mapCoord.y;
|
|
|
|
if (interactionType != VIEWPORT_INTERACTION_ITEM_RIDE)
|
|
return;
|
|
if (track_element_get_ride_index(tileElement) != w->number)
|
|
return;
|
|
if (track_element_get_colour_scheme(tileElement) == newColourScheme)
|
|
return;
|
|
|
|
z = tileElement->base_height * 8;
|
|
direction = tile_element_get_direction(tileElement);
|
|
sub_6C683D(&x, &y, &z, direction, track_element_get_type(tileElement), newColourScheme, nullptr, 4);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B04FA
|
|
*/
|
|
static void window_ride_colour_close(rct_window *w)
|
|
{
|
|
if (!(input_test_flag(INPUT_FLAG_TOOL_ACTIVE)))
|
|
return;
|
|
|
|
if (gCurrentToolWidget.window_classification != w->classification)
|
|
return;
|
|
|
|
if (gCurrentToolWidget.window_number != w->number)
|
|
return;
|
|
|
|
tool_cancel();
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B02A1
|
|
*/
|
|
static void window_ride_colour_mouseup(rct_window *w, rct_widgetindex widgetIndex)
|
|
{
|
|
switch (widgetIndex) {
|
|
case WIDX_CLOSE:
|
|
window_close(w);
|
|
break;
|
|
case WIDX_TAB_1:
|
|
case WIDX_TAB_2:
|
|
case WIDX_TAB_3:
|
|
case WIDX_TAB_4:
|
|
case WIDX_TAB_5:
|
|
case WIDX_TAB_6:
|
|
case WIDX_TAB_7:
|
|
case WIDX_TAB_8:
|
|
case WIDX_TAB_9:
|
|
case WIDX_TAB_10:
|
|
window_ride_set_page(w, widgetIndex - WIDX_TAB_1);
|
|
break;
|
|
case WIDX_PAINT_INDIVIDUAL_AREA:
|
|
tool_set(w, WIDX_PAINT_INDIVIDUAL_AREA, TOOL_PAINT_DOWN);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B0AB6
|
|
*/
|
|
static void window_ride_colour_resize(rct_window *w)
|
|
{
|
|
window_set_resize(w, 316, 207, 316, 207);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B02C6
|
|
*/
|
|
static void window_ride_colour_mousedown(rct_window *w, rct_widgetindex widgetIndex, rct_widget *widget)
|
|
{
|
|
Ride *ride;
|
|
uint16 colourSchemeIndex;
|
|
vehicle_colour vehicleColour;
|
|
rct_widget *dropdownWidget;
|
|
rct_ride_entry *rideEntry;
|
|
sint32 i, numItems, checkedIndex;
|
|
rct_string_id stringId;
|
|
|
|
ride = get_ride(w->number);
|
|
rideEntry = get_ride_entry_by_ride(ride);
|
|
colourSchemeIndex = w->ride_colour;
|
|
dropdownWidget = widget - 1;
|
|
|
|
switch (widgetIndex) {
|
|
case WIDX_TRACK_COLOUR_SCHEME_DROPDOWN:
|
|
for (i = 0; i < NUM_COLOUR_SCHEMES; i++) {
|
|
gDropdownItemsFormat[i] = STR_DROPDOWN_MENU_LABEL;
|
|
gDropdownItemsArgs[i] = ColourSchemeNames[i];
|
|
}
|
|
|
|
window_dropdown_show_text_custom_width(
|
|
w->x + dropdownWidget->left,
|
|
w->y + dropdownWidget->top,
|
|
dropdownWidget->bottom - dropdownWidget->top + 1,
|
|
w->colours[1],
|
|
0,
|
|
DROPDOWN_FLAG_STAY_OPEN,
|
|
4,
|
|
widget->right - dropdownWidget->left
|
|
);
|
|
|
|
dropdown_set_checked(colourSchemeIndex, true);
|
|
break;
|
|
case WIDX_TRACK_MAIN_COLOUR:
|
|
window_dropdown_show_colour(w, widget, w->colours[1], ride->track_colour_main[colourSchemeIndex]);
|
|
break;
|
|
case WIDX_TRACK_ADDITIONAL_COLOUR:
|
|
window_dropdown_show_colour(w, widget, w->colours[1], ride->track_colour_additional[colourSchemeIndex]);
|
|
break;
|
|
case WIDX_TRACK_SUPPORT_COLOUR:
|
|
window_dropdown_show_colour(w, widget, w->colours[1], ride->track_colour_supports[colourSchemeIndex]);
|
|
break;
|
|
case WIDX_MAZE_STYLE_DROPDOWN:
|
|
for (i = 0; i < 4; i++) {
|
|
gDropdownItemsFormat[i] = STR_DROPDOWN_MENU_LABEL;
|
|
gDropdownItemsArgs[i] = MazeOptions[i].text;
|
|
}
|
|
|
|
window_dropdown_show_text_custom_width(
|
|
w->x + dropdownWidget->left,
|
|
w->y + dropdownWidget->top,
|
|
dropdownWidget->bottom - dropdownWidget->top + 1,
|
|
w->colours[1],
|
|
0,
|
|
DROPDOWN_FLAG_STAY_OPEN,
|
|
4,
|
|
widget->right - dropdownWidget->left
|
|
);
|
|
|
|
dropdown_set_checked(ride->track_colour_supports[colourSchemeIndex], true);
|
|
break;
|
|
case WIDX_ENTRANCE_STYLE_DROPDOWN:
|
|
checkedIndex = -1;
|
|
for (i = 0; i < (sint32)Util::CountOf(window_ride_entrance_style_list); i++) {
|
|
gDropdownItemsFormat[i] = STR_DROPDOWN_MENU_LABEL;
|
|
gDropdownItemsArgs[i] = RideEntranceDefinitions[window_ride_entrance_style_list[i]].string_id;
|
|
|
|
if (ride->entrance_style == window_ride_entrance_style_list[i]) {
|
|
checkedIndex = i;
|
|
}
|
|
}
|
|
|
|
window_dropdown_show_text_custom_width(
|
|
w->x + dropdownWidget->left,
|
|
w->y + dropdownWidget->top,
|
|
dropdownWidget->bottom - dropdownWidget->top + 1,
|
|
w->colours[1],
|
|
0,
|
|
DROPDOWN_FLAG_STAY_OPEN,
|
|
Util::CountOf(window_ride_entrance_style_list),
|
|
widget->right - dropdownWidget->left
|
|
);
|
|
|
|
|
|
if (checkedIndex != -1)
|
|
{
|
|
dropdown_set_checked(checkedIndex, true);
|
|
}
|
|
break;
|
|
case WIDX_VEHICLE_COLOUR_SCHEME_DROPDOWN:
|
|
for (i = 0; i < 3; i++) {
|
|
gDropdownItemsFormat[i] = STR_DROPDOWN_MENU_LABEL;
|
|
gDropdownItemsArgs[i] = (RideComponentNames[RideNameConvention[ride->type].vehicle].singular << 16) | VehicleColourSchemeNames[i];
|
|
}
|
|
|
|
window_dropdown_show_text_custom_width(
|
|
w->x + dropdownWidget->left,
|
|
w->y + dropdownWidget->top,
|
|
dropdownWidget->bottom - dropdownWidget->top + 1,
|
|
w->colours[1],
|
|
0,
|
|
DROPDOWN_FLAG_STAY_OPEN,
|
|
rideEntry->max_cars_in_train > 1 ? 3 : 2,
|
|
widget->right - dropdownWidget->left
|
|
);
|
|
|
|
dropdown_set_checked(ride->colour_scheme_type & 3, true);
|
|
break;
|
|
case WIDX_VEHICLE_COLOUR_INDEX_DROPDOWN:
|
|
numItems = ride->num_vehicles;
|
|
if ((ride->colour_scheme_type & 3) != VEHICLE_COLOUR_SCHEME_PER_TRAIN)
|
|
numItems = ride->num_cars_per_train;
|
|
|
|
stringId = (ride->colour_scheme_type & 3) == VEHICLE_COLOUR_SCHEME_PER_TRAIN ? STR_RIDE_COLOUR_TRAIN_OPTION : STR_RIDE_COLOUR_VEHICLE_OPTION;
|
|
for (i = 0; i < 32; i++) {
|
|
gDropdownItemsFormat[i] = STR_DROPDOWN_MENU_LABEL;
|
|
gDropdownItemsArgs[i] = ((sint64)(i + 1) << 32) | ((RideComponentNames[RideNameConvention[ride->type].vehicle].capitalised) << 16) | stringId;
|
|
}
|
|
|
|
window_dropdown_show_text_custom_width(
|
|
w->x + dropdownWidget->left,
|
|
w->y + dropdownWidget->top,
|
|
dropdownWidget->bottom - dropdownWidget->top + 1,
|
|
w->colours[1],
|
|
0,
|
|
DROPDOWN_FLAG_STAY_OPEN,
|
|
numItems,
|
|
widget->right - dropdownWidget->left
|
|
);
|
|
|
|
dropdown_set_checked(w->vehicleIndex, true);
|
|
break;
|
|
case WIDX_VEHICLE_MAIN_COLOUR:
|
|
vehicleColour = ride_get_vehicle_colour(ride, w->vehicleIndex);
|
|
window_dropdown_show_colour(w, widget, w->colours[1], vehicleColour.main);
|
|
break;
|
|
case WIDX_VEHICLE_ADDITIONAL_COLOUR_1:
|
|
vehicleColour = ride_get_vehicle_colour(ride, w->vehicleIndex);
|
|
window_dropdown_show_colour(w, widget, w->colours[1], vehicleColour.additional_1);
|
|
break;
|
|
case WIDX_VEHICLE_ADDITIONAL_COLOUR_2:
|
|
vehicleColour = ride_get_vehicle_colour(ride, w->vehicleIndex);
|
|
window_dropdown_show_colour(w, widget, w->colours[1], vehicleColour.additional_2);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B0331
|
|
*/
|
|
static void window_ride_colour_dropdown(rct_window *w, rct_widgetindex widgetIndex, sint32 dropdownIndex)
|
|
{
|
|
if (dropdownIndex == -1)
|
|
return;
|
|
|
|
switch (widgetIndex) {
|
|
case WIDX_TRACK_COLOUR_SCHEME_DROPDOWN:
|
|
w->ride_colour = (uint16)dropdownIndex;
|
|
window_invalidate(w);
|
|
break;
|
|
case WIDX_TRACK_MAIN_COLOUR:
|
|
game_do_command(0, (0 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_SET_RIDE_APPEARANCE, w->ride_colour, 0);
|
|
break;
|
|
case WIDX_TRACK_ADDITIONAL_COLOUR:
|
|
game_do_command(0, (1 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_SET_RIDE_APPEARANCE, w->ride_colour, 0);
|
|
break;
|
|
case WIDX_TRACK_SUPPORT_COLOUR:
|
|
game_do_command(0, (4 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_SET_RIDE_APPEARANCE, w->ride_colour, 0);
|
|
break;
|
|
case WIDX_MAZE_STYLE_DROPDOWN:
|
|
game_do_command(0, (4 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_SET_RIDE_APPEARANCE, w->ride_colour, 0);
|
|
break;
|
|
case WIDX_ENTRANCE_STYLE_DROPDOWN:
|
|
game_do_command(0, (6 << 8) | 1, 0, (window_ride_entrance_style_list[dropdownIndex] << 8) | w->number, GAME_COMMAND_SET_RIDE_APPEARANCE, 0, 0);
|
|
break;
|
|
case WIDX_VEHICLE_COLOUR_SCHEME_DROPDOWN:
|
|
game_do_command(0, (5 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_SET_RIDE_APPEARANCE, 0, 0);
|
|
w->vehicleIndex = 0;
|
|
break;
|
|
case WIDX_VEHICLE_COLOUR_INDEX_DROPDOWN:
|
|
w->vehicleIndex = dropdownIndex;
|
|
window_invalidate(w);
|
|
break;
|
|
case WIDX_VEHICLE_MAIN_COLOUR:
|
|
game_do_command(0, (2 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_SET_RIDE_APPEARANCE, w->vehicleIndex, 0);
|
|
break;
|
|
case WIDX_VEHICLE_ADDITIONAL_COLOUR_1:
|
|
game_do_command(0, (3 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_SET_RIDE_APPEARANCE, w->vehicleIndex, 0);
|
|
break;
|
|
case WIDX_VEHICLE_ADDITIONAL_COLOUR_2:
|
|
game_do_command(0, (7 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_SET_RIDE_APPEARANCE, w->vehicleIndex, 0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B0A8F
|
|
*/
|
|
static void window_ride_colour_update(rct_window *w)
|
|
{
|
|
w->frame_no++;
|
|
window_event_invalidate_call(w);
|
|
widget_invalidate(w, WIDX_TAB_5);
|
|
widget_invalidate(w, WIDX_VEHICLE_PREVIEW);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B04EC
|
|
*/
|
|
static void window_ride_colour_tooldown(rct_window *w, rct_widgetindex widgetIndex, sint32 x, sint32 y)
|
|
{
|
|
if (widgetIndex == WIDX_PAINT_INDIVIDUAL_AREA)
|
|
window_ride_set_track_colour_scheme(w, x, y);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B04F3
|
|
*/
|
|
static void window_ride_colour_tooldrag(rct_window *w, rct_widgetindex widgetIndex, sint32 x, sint32 y)
|
|
{
|
|
if (widgetIndex == WIDX_PAINT_INDIVIDUAL_AREA)
|
|
window_ride_set_track_colour_scheme(w, x, y);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AFB36
|
|
*/
|
|
static void window_ride_colour_invalidate(rct_window *w)
|
|
{
|
|
rct_widget *widgets;
|
|
rct_ride_entry *rideEntry;
|
|
Ride *ride;
|
|
track_colour trackColour;
|
|
vehicle_colour vehicleColour;
|
|
|
|
widgets = window_ride_page_widgets[w->page];
|
|
if (w->widgets != widgets) {
|
|
w->widgets = widgets;
|
|
window_init_scroll_widgets(w);
|
|
}
|
|
|
|
window_ride_set_pressed_tab(w);
|
|
|
|
ride = get_ride(w->number);
|
|
rideEntry = get_ride_entry_by_ride(ride);
|
|
|
|
set_format_arg(0, rct_string_id, ride->name);
|
|
set_format_arg(2, uint32, ride->name_arguments);
|
|
|
|
// Track colours
|
|
sint32 colourScheme = w->ride_colour;
|
|
trackColour = ride_get_track_colour(ride, colourScheme);
|
|
|
|
// Maze style
|
|
if (ride->type == RIDE_TYPE_MAZE) {
|
|
window_ride_colour_widgets[WIDX_MAZE_STYLE].type = WWT_DROPDOWN;
|
|
window_ride_colour_widgets[WIDX_MAZE_STYLE_DROPDOWN].type = WWT_BUTTON;
|
|
window_ride_colour_widgets[WIDX_MAZE_STYLE].text = MazeOptions[trackColour.supports].text;
|
|
} else {
|
|
window_ride_colour_widgets[WIDX_MAZE_STYLE].type = WWT_EMPTY;
|
|
window_ride_colour_widgets[WIDX_MAZE_STYLE_DROPDOWN].type = WWT_EMPTY;
|
|
}
|
|
|
|
// Track, multiple colour schemes
|
|
if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_SUPPORTS_MULTIPLE_TRACK_COLOUR)) {
|
|
window_ride_colour_widgets[WIDX_TRACK_COLOUR_SCHEME].type = WWT_DROPDOWN;
|
|
window_ride_colour_widgets[WIDX_TRACK_COLOUR_SCHEME_DROPDOWN].type = WWT_BUTTON;
|
|
window_ride_colour_widgets[WIDX_PAINT_INDIVIDUAL_AREA].type = WWT_FLATBTN;
|
|
} else {
|
|
window_ride_colour_widgets[WIDX_TRACK_COLOUR_SCHEME].type = WWT_EMPTY;
|
|
window_ride_colour_widgets[WIDX_TRACK_COLOUR_SCHEME_DROPDOWN].type = WWT_EMPTY;
|
|
window_ride_colour_widgets[WIDX_PAINT_INDIVIDUAL_AREA].type = WWT_EMPTY;
|
|
}
|
|
|
|
// Track main colour
|
|
if (window_ride_has_track_colour(ride, 0)) {
|
|
window_ride_colour_widgets[WIDX_TRACK_MAIN_COLOUR].type = WWT_COLOURBTN;
|
|
window_ride_colour_widgets[WIDX_TRACK_MAIN_COLOUR].image = window_ride_get_colour_button_image(trackColour.main);
|
|
} else {
|
|
window_ride_colour_widgets[WIDX_TRACK_MAIN_COLOUR].type = WWT_EMPTY;
|
|
}
|
|
|
|
// Track additional colour
|
|
if (window_ride_has_track_colour(ride, 1)) {
|
|
window_ride_colour_widgets[WIDX_TRACK_ADDITIONAL_COLOUR].type = WWT_COLOURBTN;
|
|
window_ride_colour_widgets[WIDX_TRACK_ADDITIONAL_COLOUR].image = window_ride_get_colour_button_image(trackColour.additional);
|
|
} else {
|
|
window_ride_colour_widgets[WIDX_TRACK_ADDITIONAL_COLOUR].type = WWT_EMPTY;
|
|
}
|
|
|
|
// Track supports colour
|
|
if (window_ride_has_track_colour(ride, 2) && ride->type != RIDE_TYPE_MAZE) {
|
|
window_ride_colour_widgets[WIDX_TRACK_SUPPORT_COLOUR].type = WWT_COLOURBTN;
|
|
window_ride_colour_widgets[WIDX_TRACK_SUPPORT_COLOUR].image = window_ride_get_colour_button_image(trackColour.supports);
|
|
} else {
|
|
window_ride_colour_widgets[WIDX_TRACK_SUPPORT_COLOUR].type = WWT_EMPTY;
|
|
}
|
|
|
|
// Track preview
|
|
if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_HAS_TRACK_COLOUR_MAIN | RIDE_TYPE_FLAG_HAS_TRACK_COLOUR_ADDITIONAL | RIDE_TYPE_FLAG_HAS_TRACK_COLOUR_SUPPORTS))
|
|
window_ride_colour_widgets[WIDX_TRACK_PREVIEW].type = WWT_SPINNER;
|
|
else
|
|
window_ride_colour_widgets[WIDX_TRACK_PREVIEW].type = WWT_EMPTY;
|
|
|
|
// Entrance style
|
|
if (RideData4[ride->type].flags & RIDE_TYPE_FLAG4_HAS_ENTRANCE_EXIT) {
|
|
window_ride_colour_widgets[WIDX_ENTRANCE_PREVIEW].type = WWT_SPINNER;
|
|
window_ride_colour_widgets[WIDX_ENTRANCE_STYLE].type = WWT_DROPDOWN;
|
|
window_ride_colour_widgets[WIDX_ENTRANCE_STYLE_DROPDOWN].type = WWT_BUTTON;
|
|
|
|
window_ride_colour_widgets[WIDX_ENTRANCE_STYLE].text = RideEntranceDefinitions[ride->entrance_style].string_id;
|
|
} else {
|
|
window_ride_colour_widgets[WIDX_ENTRANCE_PREVIEW].type = WWT_EMPTY;
|
|
window_ride_colour_widgets[WIDX_ENTRANCE_STYLE].type = WWT_EMPTY;
|
|
window_ride_colour_widgets[WIDX_ENTRANCE_STYLE_DROPDOWN].type = WWT_EMPTY;
|
|
}
|
|
|
|
// Vehicle colours
|
|
if (!ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_NO_VEHICLES) && ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_HAS_VEHICLE_COLOURS)) {
|
|
sint32 vehicleColourSchemeType = ride->colour_scheme_type & 3;
|
|
if (vehicleColourSchemeType == 0)
|
|
w->vehicleIndex = 0;
|
|
|
|
vehicleColour = ride_get_vehicle_colour(ride, w->vehicleIndex);
|
|
|
|
window_ride_colour_widgets[WIDX_VEHICLE_PREVIEW].type = WWT_SCROLL;
|
|
window_ride_colour_widgets[WIDX_VEHICLE_MAIN_COLOUR].type = WWT_COLOURBTN;
|
|
window_ride_colour_widgets[WIDX_VEHICLE_MAIN_COLOUR].image = window_ride_get_colour_button_image(vehicleColour.main);
|
|
|
|
bool allowChangingAdditionalColour1 = false;
|
|
bool allowChangingAdditionalColour2 = false;
|
|
|
|
for (sint32 i = 0; i < ride->num_cars_per_train; i++) {
|
|
uint8 vehicleTypeIndex = ride_entry_get_vehicle_at_position(ride->subtype, ride->num_cars_per_train, i);
|
|
|
|
if (rideEntry->vehicles[vehicleTypeIndex].flags & VEHICLE_ENTRY_FLAG_ENABLE_ADDITIONAL_COLOUR_1)
|
|
{
|
|
allowChangingAdditionalColour1 = true;
|
|
}
|
|
if (rideEntry->vehicles[vehicleTypeIndex].flags & VEHICLE_ENTRY_FLAG_ENABLE_ADDITIONAL_COLOUR_2)
|
|
{
|
|
allowChangingAdditionalColour2 = true;
|
|
}
|
|
}
|
|
|
|
// Additional colours
|
|
if (allowChangingAdditionalColour1) {
|
|
window_ride_colour_widgets[WIDX_VEHICLE_ADDITIONAL_COLOUR_1].type = WWT_COLOURBTN;
|
|
window_ride_colour_widgets[WIDX_VEHICLE_ADDITIONAL_COLOUR_1].image = window_ride_get_colour_button_image(vehicleColour.additional_1);
|
|
if (allowChangingAdditionalColour2) {
|
|
window_ride_colour_widgets[WIDX_VEHICLE_ADDITIONAL_COLOUR_2].type = WWT_COLOURBTN;
|
|
window_ride_colour_widgets[WIDX_VEHICLE_ADDITIONAL_COLOUR_2].image = window_ride_get_colour_button_image(vehicleColour.additional_2);
|
|
} else {
|
|
window_ride_colour_widgets[WIDX_VEHICLE_ADDITIONAL_COLOUR_2].type = WWT_EMPTY;
|
|
}
|
|
} else {
|
|
window_ride_colour_widgets[WIDX_VEHICLE_ADDITIONAL_COLOUR_1].type = WWT_EMPTY;
|
|
window_ride_colour_widgets[WIDX_VEHICLE_ADDITIONAL_COLOUR_2].type = WWT_EMPTY;
|
|
}
|
|
|
|
// Vehicle colour scheme type
|
|
if (!ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_16) && (ride->num_cars_per_train | ride->num_vehicles) > 1) {
|
|
window_ride_colour_widgets[WIDX_VEHICLE_COLOUR_SCHEME].type = WWT_DROPDOWN;
|
|
window_ride_colour_widgets[WIDX_VEHICLE_COLOUR_SCHEME_DROPDOWN].type = WWT_BUTTON;
|
|
} else {
|
|
window_ride_colour_widgets[WIDX_VEHICLE_COLOUR_SCHEME].type = WWT_EMPTY;
|
|
window_ride_colour_widgets[WIDX_VEHICLE_COLOUR_SCHEME_DROPDOWN].type = WWT_EMPTY;
|
|
}
|
|
set_format_arg( 6, rct_string_id, VehicleColourSchemeNames[vehicleColourSchemeType]);
|
|
set_format_arg( 8, rct_string_id, RideComponentNames[RideNameConvention[ride->type].vehicle].singular);
|
|
set_format_arg(10, rct_string_id, RideComponentNames[RideNameConvention[ride->type].vehicle].capitalised);
|
|
set_format_arg(12, uint16, w->vehicleIndex + 1);
|
|
// Vehicle index
|
|
if (vehicleColourSchemeType != 0) {
|
|
window_ride_colour_widgets[WIDX_VEHICLE_COLOUR_INDEX].type = WWT_DROPDOWN;
|
|
window_ride_colour_widgets[WIDX_VEHICLE_COLOUR_INDEX_DROPDOWN].type = WWT_BUTTON;
|
|
window_ride_colour_widgets[WIDX_VEHICLE_COLOUR_INDEX].text = vehicleColourSchemeType == 1 ? STR_RIDE_COLOUR_TRAIN_VALUE : STR_RIDE_COLOUR_VEHICLE_VALUE;
|
|
} else {
|
|
window_ride_colour_widgets[WIDX_VEHICLE_COLOUR_INDEX].type = WWT_EMPTY;
|
|
window_ride_colour_widgets[WIDX_VEHICLE_COLOUR_INDEX_DROPDOWN].type = WWT_EMPTY;
|
|
}
|
|
} else {
|
|
window_ride_colour_widgets[WIDX_VEHICLE_PREVIEW].type = WWT_EMPTY;
|
|
window_ride_colour_widgets[WIDX_VEHICLE_COLOUR_SCHEME].type = WWT_EMPTY;
|
|
window_ride_colour_widgets[WIDX_VEHICLE_COLOUR_SCHEME_DROPDOWN].type = WWT_EMPTY;
|
|
window_ride_colour_widgets[WIDX_VEHICLE_COLOUR_INDEX].type = WWT_EMPTY;
|
|
window_ride_colour_widgets[WIDX_VEHICLE_COLOUR_INDEX_DROPDOWN].type = WWT_EMPTY;
|
|
window_ride_colour_widgets[WIDX_VEHICLE_MAIN_COLOUR].type = WWT_EMPTY;
|
|
window_ride_colour_widgets[WIDX_VEHICLE_ADDITIONAL_COLOUR_1].type = WWT_EMPTY;
|
|
window_ride_colour_widgets[WIDX_VEHICLE_ADDITIONAL_COLOUR_2].type = WWT_EMPTY;
|
|
}
|
|
|
|
set_format_arg(14, rct_string_id, ColourSchemeNames[colourScheme]);
|
|
|
|
window_ride_anchor_border_widgets(w);
|
|
window_align_tabs(w, WIDX_TAB_1, WIDX_TAB_10);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AFF3E
|
|
*/
|
|
static void window_ride_colour_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
|
{
|
|
// TODO: This should use lists and identified sprites
|
|
rct_drawpixelinfo clippedDpi;
|
|
rct_widget *widget;
|
|
Ride *ride;
|
|
rct_ride_entry *rideEntry;
|
|
|
|
ride = get_ride(w->number);
|
|
rideEntry = get_ride_entry_by_ride(ride);
|
|
|
|
window_draw_widgets(w, dpi);
|
|
window_ride_draw_tab_images(dpi, w);
|
|
|
|
// Track / shop item preview
|
|
widget = &window_ride_colour_widgets[WIDX_TRACK_PREVIEW];
|
|
if (widget->type != WWT_EMPTY)
|
|
gfx_fill_rect(dpi, w->x + widget->left + 1, w->y + widget->top + 1, w->x + widget->right - 1, w->y + widget->bottom - 1, PALETTE_INDEX_12);
|
|
|
|
track_colour trackColour = ride_get_track_colour(ride, w->ride_colour);
|
|
|
|
//
|
|
if (rideEntry->shop_item == SHOP_ITEM_NONE) {
|
|
sint32 x = w->x + widget->left;
|
|
sint32 y = w->y + widget->top;
|
|
|
|
// Track
|
|
if (ride->type == RIDE_TYPE_MAZE) {
|
|
sint32 spriteIndex = MazeOptions[trackColour.supports].sprite;
|
|
gfx_draw_sprite(dpi, spriteIndex, x, y, 0);
|
|
} else {
|
|
sint32 spriteIndex = TrackColourPreviews[ride->type].track;
|
|
if (spriteIndex != 0) {
|
|
spriteIndex |= SPRITE_ID_PALETTE_COLOUR_2(trackColour.main, trackColour.additional);
|
|
gfx_draw_sprite(dpi, spriteIndex, x, y, 0);
|
|
}
|
|
|
|
// Supports
|
|
spriteIndex = TrackColourPreviews[ride->type].supports;
|
|
if (spriteIndex != 0) {
|
|
spriteIndex |= SPRITE_ID_PALETTE_COLOUR_1(trackColour.supports);
|
|
gfx_draw_sprite(dpi, spriteIndex, x, y, 0);
|
|
}
|
|
}
|
|
} else {
|
|
sint32 x = w->x + (widget->left + widget->right) / 2 - 8;
|
|
sint32 y = w->y + (widget->bottom + widget->top) / 2 - 6;
|
|
|
|
uint8 shopItem = rideEntry->shop_item_secondary == SHOP_ITEM_NONE ? rideEntry->shop_item : rideEntry->shop_item_secondary;
|
|
sint32 spriteIndex = ShopItemImage[shopItem];
|
|
spriteIndex |= SPRITE_ID_PALETTE_COLOUR_1(ride->track_colour_main[0]);
|
|
|
|
gfx_draw_sprite(dpi, spriteIndex, x, y, 0);
|
|
}
|
|
|
|
// Entrance preview
|
|
trackColour = ride_get_track_colour(ride, 0);
|
|
widget = &w->widgets[WIDX_ENTRANCE_PREVIEW];
|
|
if (widget->type != WWT_EMPTY) {
|
|
if (clip_drawpixelinfo(
|
|
&clippedDpi,
|
|
dpi,
|
|
w->x + widget->left + 1,
|
|
w->y + widget->top + 1,
|
|
widget->right - widget->left,
|
|
widget->bottom - widget->top
|
|
)) {
|
|
gfx_clear(&clippedDpi, PALETTE_INDEX_12);
|
|
|
|
if (ride->entrance_style != RIDE_ENTRANCE_STYLE_NONE) {
|
|
const rct_ride_entrance_definition *entranceStyle = &RideEntranceDefinitions[ride->entrance_style];
|
|
|
|
sint32 terniaryColour = 0;
|
|
if (entranceStyle->base_image_id & IMAGE_TYPE_TRANSPARENT) {
|
|
terniaryColour = IMAGE_TYPE_TRANSPARENT | (GlassPaletteIds[trackColour.main] << 19);
|
|
}
|
|
|
|
sint32 spriteIndex = SPRITE_ID_PALETTE_COLOUR_2(trackColour.main, trackColour.additional);
|
|
spriteIndex += RideEntranceDefinitions[ride->entrance_style].sprite_index;
|
|
|
|
// Back
|
|
gfx_draw_sprite(&clippedDpi, spriteIndex, 34, 20, terniaryColour);
|
|
|
|
// Front
|
|
gfx_draw_sprite(&clippedDpi, spriteIndex + 4, 34, 20, terniaryColour);
|
|
|
|
// Glass
|
|
if (terniaryColour != 0)
|
|
gfx_draw_sprite(&clippedDpi, ((spriteIndex + 20) & 0x7FFFF) + terniaryColour, 34, 20, terniaryColour);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B0192
|
|
*/
|
|
static void window_ride_colour_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, sint32 scrollIndex)
|
|
{
|
|
Ride *ride;
|
|
rct_ride_entry *rideEntry;
|
|
rct_widget *vehiclePreviewWidget;
|
|
sint32 trainCarIndex, x, y, spriteIndex;
|
|
vehicle_colour vehicleColour;
|
|
|
|
ride = get_ride(w->number);
|
|
rideEntry = get_ride_entry_by_ride(ride);
|
|
vehiclePreviewWidget = &window_ride_colour_widgets[WIDX_VEHICLE_PREVIEW];
|
|
vehicleColour = ride_get_vehicle_colour(ride, w->vehicleIndex);
|
|
|
|
// Background colour
|
|
gfx_fill_rect(dpi, dpi->x, dpi->y, dpi->x + dpi->width - 1, dpi->y + dpi->height - 1, PALETTE_INDEX_12);
|
|
|
|
// ?
|
|
x = (vehiclePreviewWidget->right - vehiclePreviewWidget->left) / 2;
|
|
y = vehiclePreviewWidget->bottom - vehiclePreviewWidget->top - 15;
|
|
|
|
// ?
|
|
trainCarIndex = (ride->colour_scheme_type & 3) == RIDE_COLOUR_SCHEME_DIFFERENT_PER_CAR ?
|
|
w->vehicleIndex : rideEntry->tab_vehicle;
|
|
|
|
rct_ride_entry_vehicle* rideVehicleEntry = &rideEntry->vehicles[ride_entry_get_vehicle_at_position(ride->subtype, ride->num_cars_per_train, trainCarIndex)];
|
|
|
|
y += rideVehicleEntry->tab_height;
|
|
|
|
// Draw the coloured spinning vehicle
|
|
spriteIndex = (rideVehicleEntry->flags & VEHICLE_ENTRY_FLAG_11) ? w->frame_no / 4 : w->frame_no / 2;
|
|
spriteIndex &= rideVehicleEntry->rotation_frame_mask;
|
|
spriteIndex *= rideVehicleEntry->base_num_frames;
|
|
spriteIndex += rideVehicleEntry->base_image_id;
|
|
spriteIndex |= (vehicleColour.additional_1 << 24) | (vehicleColour.main << 19);
|
|
spriteIndex |= IMAGE_TYPE_REMAP_2_PLUS;
|
|
gfx_draw_sprite(dpi, spriteIndex, x, y, vehicleColour.additional_2);
|
|
}
|
|
|
|
#pragma endregion
|
|
|
|
#pragma region Music
|
|
|
|
static constexpr const uint8 MusicStyleOrder[] = {
|
|
MUSIC_STYLE_GENTLE,
|
|
MUSIC_STYLE_SUMMER,
|
|
MUSIC_STYLE_WATER,
|
|
MUSIC_STYLE_RAGTIME,
|
|
MUSIC_STYLE_TECHNO,
|
|
MUSIC_STYLE_MECHANICAL,
|
|
MUSIC_STYLE_MODERN,
|
|
MUSIC_STYLE_WILD_WEST,
|
|
MUSIC_STYLE_PIRATES,
|
|
MUSIC_STYLE_ROCK,
|
|
MUSIC_STYLE_ROCK_STYLE_2,
|
|
MUSIC_STYLE_ROCK_STYLE_3,
|
|
MUSIC_STYLE_FANTASY,
|
|
MUSIC_STYLE_HORROR,
|
|
MUSIC_STYLE_TOYLAND,
|
|
MUSIC_STYLE_CANDY_STYLE,
|
|
MUSIC_STYLE_ROMAN_FANFARE,
|
|
MUSIC_STYLE_ORIENTAL,
|
|
MUSIC_STYLE_MARTIAN,
|
|
MUSIC_STYLE_SPACE,
|
|
MUSIC_STYLE_JUNGLE_DRUMS,
|
|
MUSIC_STYLE_JURASSIC,
|
|
MUSIC_STYLE_EGYPTIAN,
|
|
MUSIC_STYLE_DODGEMS_BEAT,
|
|
MUSIC_STYLE_SNOW,
|
|
MUSIC_STYLE_ICE,
|
|
MUSIC_STYLE_MEDIEVAL,
|
|
MUSIC_STYLE_URBAN,
|
|
MUSIC_STYLE_ORGAN
|
|
};
|
|
|
|
static uint8 window_ride_current_music_style_order[42];
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B215D
|
|
*/
|
|
static void window_ride_toggle_music(rct_window *w)
|
|
{
|
|
Ride *ride = get_ride(w->number);
|
|
|
|
sint32 activateMusic = (ride->lifecycle_flags & RIDE_LIFECYCLE_MUSIC) ? 0 : 1;
|
|
|
|
gGameCommandErrorTitle = STR_CANT_CHANGE_OPERATING_MODE;
|
|
game_do_command(0, (activateMusic << 8) | 1, 0, (6 << 8) | w->number, GAME_COMMAND_SET_RIDE_SETTING, 0, 0);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B1ED7
|
|
*/
|
|
static void window_ride_music_mouseup(rct_window *w, rct_widgetindex widgetIndex)
|
|
{
|
|
switch (widgetIndex) {
|
|
case WIDX_CLOSE:
|
|
window_close(w);
|
|
break;
|
|
case WIDX_TAB_1:
|
|
case WIDX_TAB_2:
|
|
case WIDX_TAB_3:
|
|
case WIDX_TAB_4:
|
|
case WIDX_TAB_5:
|
|
case WIDX_TAB_6:
|
|
case WIDX_TAB_7:
|
|
case WIDX_TAB_8:
|
|
case WIDX_TAB_9:
|
|
case WIDX_TAB_10:
|
|
window_ride_set_page(w, widgetIndex - WIDX_TAB_1);
|
|
break;
|
|
case WIDX_PLAY_MUSIC:
|
|
window_ride_toggle_music(w);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AF4A2
|
|
*/
|
|
static void window_ride_music_resize(rct_window *w)
|
|
{
|
|
w->flags |= WF_RESIZABLE;
|
|
window_set_resize(w, 316, 81, 316, 81);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B1EFC
|
|
*/
|
|
static void window_ride_music_mousedown(rct_window *w, rct_widgetindex widgetIndex, rct_widget *widget)
|
|
{
|
|
rct_widget *dropdownWidget;
|
|
sint32 i;
|
|
|
|
if (widgetIndex != WIDX_MUSIC_DROPDOWN)
|
|
return;
|
|
|
|
dropdownWidget = widget - 1;
|
|
Ride *ride = get_ride(w->number);
|
|
|
|
sint32 numItems = 0;
|
|
if (ride->type == RIDE_TYPE_MERRY_GO_ROUND) {
|
|
window_ride_current_music_style_order[numItems++] = MUSIC_STYLE_FAIRGROUND_ORGAN;
|
|
} else {
|
|
for (size_t n = 0; n < Util::CountOf(MusicStyleOrder); n++)
|
|
window_ride_current_music_style_order[numItems++] = MusicStyleOrder[n];
|
|
|
|
if (gRideMusicInfoList[36].length != 0)
|
|
window_ride_current_music_style_order[numItems++] = MUSIC_STYLE_CUSTOM_MUSIC_1;
|
|
if (gRideMusicInfoList[37].length != 0)
|
|
window_ride_current_music_style_order[numItems++] = MUSIC_STYLE_CUSTOM_MUSIC_2;
|
|
}
|
|
|
|
for (i = 0; i < numItems; i++) {
|
|
gDropdownItemsFormat[i] = STR_DROPDOWN_MENU_LABEL;
|
|
gDropdownItemsArgs[i] = MusicStyleNames[window_ride_current_music_style_order[i]];
|
|
}
|
|
|
|
window_dropdown_show_text_custom_width(
|
|
w->x + dropdownWidget->left,
|
|
w->y + dropdownWidget->top,
|
|
dropdownWidget->bottom - dropdownWidget->top + 1,
|
|
w->colours[1],
|
|
0,
|
|
DROPDOWN_FLAG_STAY_OPEN,
|
|
numItems,
|
|
widget->right - dropdownWidget->left
|
|
);
|
|
|
|
for (i = 0; i < numItems; i++) {
|
|
if (window_ride_current_music_style_order[i] == ride->music) {
|
|
dropdown_set_checked(i, true);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B1F03
|
|
*/
|
|
static void window_ride_music_dropdown(rct_window *w, rct_widgetindex widgetIndex, sint32 dropdownIndex)
|
|
{
|
|
uint8 musicStyle;
|
|
|
|
if (widgetIndex != WIDX_MUSIC_DROPDOWN || dropdownIndex == -1)
|
|
return;
|
|
|
|
musicStyle = window_ride_current_music_style_order[dropdownIndex];
|
|
gGameCommandErrorTitle = STR_CANT_CHANGE_OPERATING_MODE;
|
|
game_do_command(0, (musicStyle << 8) | 1, 0, (7 << 8) | w->number, GAME_COMMAND_SET_RIDE_SETTING, 0, 0);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B2198
|
|
*/
|
|
static void window_ride_music_update(rct_window *w)
|
|
{
|
|
w->frame_no++;
|
|
window_event_invalidate_call(w);
|
|
widget_invalidate(w, WIDX_TAB_6);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B1DEA
|
|
*/
|
|
static void window_ride_music_invalidate(rct_window *w)
|
|
{
|
|
rct_widget *widgets;
|
|
sint32 isMusicActivated;
|
|
|
|
widgets = window_ride_page_widgets[w->page];
|
|
if (w->widgets != widgets) {
|
|
w->widgets = widgets;
|
|
window_init_scroll_widgets(w);
|
|
}
|
|
|
|
window_ride_set_pressed_tab(w);
|
|
|
|
Ride *ride = get_ride(w->number);
|
|
set_format_arg(0, rct_string_id, ride->name);
|
|
set_format_arg(2, uint32, ride->name_arguments);
|
|
|
|
// Set selected music
|
|
window_ride_music_widgets[WIDX_MUSIC].text = MusicStyleNames[ride->music];
|
|
|
|
// Set music activated
|
|
isMusicActivated = ride->lifecycle_flags & (RIDE_LIFECYCLE_MUSIC);
|
|
if (isMusicActivated) {
|
|
w->pressed_widgets |= (1 << WIDX_PLAY_MUSIC);
|
|
w->disabled_widgets &= ~(1 << WIDX_MUSIC);
|
|
w->disabled_widgets &= ~(1 << WIDX_MUSIC_DROPDOWN);
|
|
} else {
|
|
w->pressed_widgets &= ~(1 << WIDX_PLAY_MUSIC);
|
|
w->disabled_widgets |= (1 << WIDX_MUSIC);
|
|
w->disabled_widgets |= (1 << WIDX_MUSIC_DROPDOWN);
|
|
}
|
|
|
|
window_ride_anchor_border_widgets(w);
|
|
window_align_tabs(w, WIDX_TAB_1, WIDX_TAB_10);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006B1ECC
|
|
*/
|
|
static void window_ride_music_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
|
{
|
|
window_draw_widgets(w, dpi);
|
|
window_ride_draw_tab_images(dpi, w);
|
|
}
|
|
|
|
#pragma endregion
|
|
|
|
#pragma region Measurements
|
|
|
|
static rct_string_id get_rating_name(ride_rating rating)
|
|
{
|
|
sint32 index = Math::Clamp<sint32>(0, rating >> 8, (sint32)Util::CountOf(RatingNames) - 1);
|
|
return RatingNames[index];
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006D2804
|
|
when al == 0*/
|
|
static void cancel_scenery_selection(){
|
|
gGamePaused &= ~GAME_PAUSED_SAVING_TRACK;
|
|
gTrackDesignSaveMode = false;
|
|
audio_unpause_sounds();
|
|
|
|
rct_window* main_w = window_get_main();
|
|
|
|
if (main_w){
|
|
main_w->viewport->flags &= ~(VIEWPORT_FLAG_HIDE_VERTICAL | VIEWPORT_FLAG_HIDE_BASE);
|
|
}
|
|
|
|
gfx_invalidate_screen();
|
|
tool_cancel();
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006D27A3
|
|
*/
|
|
static void setup_scenery_selection(rct_window* w)
|
|
{
|
|
if (gTrackDesignSaveMode){
|
|
cancel_scenery_selection();
|
|
}
|
|
|
|
while (tool_set(w, WIDX_BACKGROUND, TOOL_CROSSHAIR));
|
|
|
|
gTrackDesignSaveRideIndex = (uint8)w->number;
|
|
|
|
track_design_save_init();
|
|
gGamePaused |= GAME_PAUSED_SAVING_TRACK;
|
|
gTrackDesignSaveMode = true;
|
|
|
|
audio_stop_all_music_and_sounds();
|
|
|
|
rct_window* w_main = window_get_main();
|
|
|
|
if (w_main){
|
|
w_main->viewport->flags |= (VIEWPORT_FLAG_HIDE_VERTICAL | VIEWPORT_FLAG_HIDE_BASE);
|
|
}
|
|
|
|
gfx_invalidate_screen();
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006D3026
|
|
*/
|
|
static void window_ride_measurements_design_reset()
|
|
{
|
|
track_design_save_reset_scenery();
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006D303D
|
|
*/
|
|
static void window_ride_measurements_design_select_nearby_scenery()
|
|
{
|
|
track_design_save_select_nearby_scenery(gTrackDesignSaveRideIndex);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AD4DA
|
|
*/
|
|
void window_ride_measurements_design_cancel()
|
|
{
|
|
if (gTrackDesignSaveMode) {
|
|
cancel_scenery_selection();
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AD4CD
|
|
*/
|
|
static void window_ride_measurements_design_save(rct_window *w)
|
|
{
|
|
track_design_save((uint8)w->number);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AD4DA
|
|
*/
|
|
static void window_ride_measurements_close(rct_window *w)
|
|
{
|
|
window_ride_measurements_design_cancel();
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AD478
|
|
*/
|
|
static void window_ride_measurements_mouseup(rct_window *w, rct_widgetindex widgetIndex)
|
|
{
|
|
switch (widgetIndex) {
|
|
case WIDX_CLOSE:
|
|
window_close(w);
|
|
break;
|
|
case WIDX_TAB_1:
|
|
case WIDX_TAB_2:
|
|
case WIDX_TAB_3:
|
|
case WIDX_TAB_4:
|
|
case WIDX_TAB_5:
|
|
case WIDX_TAB_6:
|
|
case WIDX_TAB_7:
|
|
case WIDX_TAB_8:
|
|
case WIDX_TAB_9:
|
|
case WIDX_TAB_10:
|
|
window_ride_set_page(w, widgetIndex - WIDX_TAB_1);
|
|
break;
|
|
case WIDX_SELECT_NEARBY_SCENERY:
|
|
window_ride_measurements_design_select_nearby_scenery();
|
|
break;
|
|
case WIDX_RESET_SELECTION:
|
|
window_ride_measurements_design_reset();
|
|
break;
|
|
case WIDX_SAVE_DESIGN:
|
|
window_ride_measurements_design_save(w);
|
|
break;
|
|
case WIDX_CANCEL_DESIGN:
|
|
window_ride_measurements_design_cancel();
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AD564
|
|
*/
|
|
static void window_ride_measurements_resize(rct_window *w)
|
|
{
|
|
window_set_resize(w, 316, 234, 316, 234);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AD4AB
|
|
*/
|
|
static void window_ride_measurements_mousedown(rct_window *w, rct_widgetindex widgetIndex, rct_widget *widget)
|
|
{
|
|
if (widgetIndex != WIDX_SAVE_TRACK_DESIGN)
|
|
return;
|
|
|
|
gDropdownItemsFormat[0] = STR_SAVE_TRACK_DESIGN_ITEM;
|
|
gDropdownItemsFormat[1] = STR_SAVE_TRACK_DESIGN_WITH_SCENERY_ITEM;
|
|
|
|
window_dropdown_show_text(
|
|
w->x + widget->left,
|
|
w->y + widget->top,
|
|
widget->bottom - widget->top + 1,
|
|
w->colours[1],
|
|
0,
|
|
2
|
|
);
|
|
gDropdownDefaultIndex = 0;
|
|
if (gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER)
|
|
{
|
|
dropdown_set_disabled(1, true);
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AD4B2
|
|
*/
|
|
static void window_ride_measurements_dropdown(rct_window *w, rct_widgetindex widgetIndex, sint32 dropdownIndex)
|
|
{
|
|
if (widgetIndex != WIDX_SAVE_TRACK_DESIGN)
|
|
return;
|
|
|
|
if (dropdownIndex == -1)
|
|
dropdownIndex = gDropdownHighlightedIndex;
|
|
|
|
if (dropdownIndex == 0)
|
|
track_design_save((uint8)w->number);
|
|
else
|
|
setup_scenery_selection(w);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AD5DD
|
|
*/
|
|
static void window_ride_measurements_update(rct_window *w)
|
|
{
|
|
w->frame_no++;
|
|
window_event_invalidate_call(w);
|
|
widget_invalidate(w, WIDX_TAB_7);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006D2AE7
|
|
*/
|
|
static void window_ride_measurements_tooldown(rct_window *w, rct_widgetindex widgetIndex, sint32 x, sint32 y)
|
|
{
|
|
rct_tile_element *tileElement;
|
|
sint16 mapX, mapY;
|
|
sint32 interactionType;
|
|
|
|
_lastSceneryX = x;
|
|
_lastSceneryY = y;
|
|
_collectTrackDesignScenery = true; // Default to true in case user does not select anything valid
|
|
|
|
get_map_coordinates_from_pos(x, y, 0xFCCF, &mapX, &mapY, &interactionType, &tileElement, nullptr);
|
|
switch (interactionType) {
|
|
case VIEWPORT_INTERACTION_ITEM_SCENERY:
|
|
case VIEWPORT_INTERACTION_ITEM_LARGE_SCENERY:
|
|
case VIEWPORT_INTERACTION_ITEM_WALL:
|
|
case VIEWPORT_INTERACTION_ITEM_FOOTPATH:
|
|
_collectTrackDesignScenery = !track_design_save_contains_tile_element(tileElement);
|
|
track_design_save_select_tile_element(interactionType, mapX, mapY, tileElement, _collectTrackDesignScenery);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void window_ride_measurements_tooldrag(rct_window *w, rct_widgetindex widgetIndex, sint32 x, sint32 y)
|
|
{
|
|
if (x == _lastSceneryX && y == _lastSceneryY)
|
|
return;
|
|
_lastSceneryX = x;
|
|
_lastSceneryY = y;
|
|
|
|
rct_tile_element *tileElement;
|
|
sint16 mapX, mapY;
|
|
sint32 interactionType;
|
|
|
|
get_map_coordinates_from_pos(x, y, 0xFCCF, &mapX, &mapY, &interactionType, &tileElement, nullptr);
|
|
switch (interactionType) {
|
|
case VIEWPORT_INTERACTION_ITEM_SCENERY:
|
|
case VIEWPORT_INTERACTION_ITEM_LARGE_SCENERY:
|
|
case VIEWPORT_INTERACTION_ITEM_WALL:
|
|
case VIEWPORT_INTERACTION_ITEM_FOOTPATH:
|
|
track_design_save_select_tile_element(interactionType, mapX, mapY, tileElement, _collectTrackDesignScenery);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AD4DA
|
|
*/
|
|
static void window_ride_measurements_toolabort(rct_window *w, rct_widgetindex widgetIndex)
|
|
{
|
|
window_ride_measurements_design_cancel();
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006ACDBC
|
|
*/
|
|
static void window_ride_measurements_invalidate(rct_window *w)
|
|
{
|
|
rct_widget *widgets;
|
|
|
|
widgets = window_ride_page_widgets[w->page];
|
|
if (w->widgets != widgets) {
|
|
w->widgets = widgets;
|
|
window_init_scroll_widgets(w);
|
|
}
|
|
|
|
window_ride_set_pressed_tab(w);
|
|
|
|
Ride *ride = get_ride(w->number);
|
|
set_format_arg(0, rct_string_id, ride->name);
|
|
set_format_arg(2, uint32, ride->name_arguments);
|
|
|
|
window_ride_measurements_widgets[WIDX_SAVE_TRACK_DESIGN].tooltip = STR_SAVE_TRACK_DESIGN_NOT_POSSIBLE;
|
|
window_ride_measurements_widgets[WIDX_SAVE_TRACK_DESIGN].type = WWT_EMPTY;
|
|
if (gTrackDesignSaveMode && gTrackDesignSaveRideIndex == w->number) {
|
|
window_ride_measurements_widgets[WIDX_SELECT_NEARBY_SCENERY].type = WWT_BUTTON;
|
|
window_ride_measurements_widgets[WIDX_RESET_SELECTION].type = WWT_BUTTON;
|
|
window_ride_measurements_widgets[WIDX_SAVE_DESIGN].type = WWT_BUTTON;
|
|
window_ride_measurements_widgets[WIDX_CANCEL_DESIGN].type = WWT_BUTTON;
|
|
} else {
|
|
window_ride_measurements_widgets[WIDX_SELECT_NEARBY_SCENERY].type = WWT_EMPTY;
|
|
window_ride_measurements_widgets[WIDX_RESET_SELECTION].type = WWT_EMPTY;
|
|
window_ride_measurements_widgets[WIDX_SAVE_DESIGN].type = WWT_EMPTY;
|
|
window_ride_measurements_widgets[WIDX_CANCEL_DESIGN].type = WWT_EMPTY;
|
|
|
|
if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_HAS_TRACK)) {
|
|
window_ride_measurements_widgets[WIDX_SAVE_TRACK_DESIGN].type = WWT_FLATBTN;
|
|
w->disabled_widgets |= (1 << WIDX_SAVE_TRACK_DESIGN);
|
|
if (ride->lifecycle_flags & RIDE_LIFECYCLE_TESTED) {
|
|
if (ride->excitement != RIDE_RATING_UNDEFINED) {
|
|
w->disabled_widgets &= ~(1 << WIDX_SAVE_TRACK_DESIGN);
|
|
window_ride_measurements_widgets[WIDX_SAVE_TRACK_DESIGN].tooltip = STR_SAVE_TRACK_DESIGN;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
window_ride_anchor_border_widgets(w);
|
|
window_align_tabs(w, WIDX_TAB_1, WIDX_TAB_10);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006ACF07
|
|
*/
|
|
static void window_ride_measurements_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
|
{
|
|
sint16 holes, maxSpeed, averageSpeed, drops, highestDropHeight, inversions, time;
|
|
sint32 maxPositiveVerticalGs, maxNegativeVerticalGs, maxLateralGs, totalAirTime, length;
|
|
|
|
window_draw_widgets(w, dpi);
|
|
window_ride_draw_tab_images(dpi, w);
|
|
|
|
if (window_ride_measurements_widgets[WIDX_SAVE_DESIGN].type == WWT_BUTTON) {
|
|
rct_widget *widget = &window_ride_measurements_widgets[WIDX_PAGE_BACKGROUND];
|
|
|
|
sint32 x = w->x + (widget->right - widget->left) / 2;
|
|
sint32 y = w->y + widget->top + 40;
|
|
gfx_draw_string_centred_wrapped(dpi, nullptr, x, y, w->width - 8, STR_CLICK_ITEMS_OF_SCENERY_TO_SELECT, COLOUR_BLACK);
|
|
|
|
x = w->x + 4;
|
|
y = w->y + window_ride_measurements_widgets[WIDX_SELECT_NEARBY_SCENERY].bottom + 17;
|
|
gfx_fill_rect_inset(dpi, x, y, w->x + 312, y + 1, w->colours[1], INSET_RECT_FLAG_BORDER_INSET);
|
|
} else {
|
|
Ride *ride = get_ride(w->number);
|
|
sint32 x = w->x + window_ride_measurements_widgets[WIDX_PAGE_BACKGROUND].left + 4;
|
|
sint32 y = w->y + window_ride_measurements_widgets[WIDX_PAGE_BACKGROUND].top + 4;
|
|
|
|
if (ride->lifecycle_flags & RIDE_LIFECYCLE_TESTED) {
|
|
// Excitement
|
|
rct_string_id ratingName = get_rating_name(ride->excitement);
|
|
set_format_arg(0, uint32, ride->excitement);
|
|
set_format_arg(4, rct_string_id, ratingName);
|
|
rct_string_id stringId = ride->excitement == RIDE_RATING_UNDEFINED ? STR_EXCITEMENT_RATING_NOT_YET_AVAILABLE : STR_EXCITEMENT_RATING;
|
|
gfx_draw_string_left(dpi, stringId, gCommonFormatArgs, COLOUR_BLACK, x, y);
|
|
y += LIST_ROW_HEIGHT;
|
|
|
|
// Intensity
|
|
ratingName = get_rating_name(ride->intensity);
|
|
set_format_arg(0, uint32, ride->intensity);
|
|
set_format_arg(4, rct_string_id, ratingName);
|
|
|
|
stringId = STR_INTENSITY_RATING;
|
|
if (ride->excitement == RIDE_RATING_UNDEFINED)
|
|
stringId = STR_INTENSITY_RATING_NOT_YET_AVAILABLE;
|
|
else if (ride->intensity >= RIDE_RATING(10,00))
|
|
stringId = STR_INTENSITY_RATING_RED;
|
|
|
|
gfx_draw_string_left(dpi, stringId, gCommonFormatArgs, COLOUR_BLACK, x, y);
|
|
y += LIST_ROW_HEIGHT;
|
|
|
|
// Nausea
|
|
ratingName = get_rating_name(ride->nausea);
|
|
set_format_arg(0, uint32, ride->nausea);
|
|
set_format_arg(4, rct_string_id, ratingName);
|
|
stringId = ride->excitement == RIDE_RATING_UNDEFINED ? STR_NAUSEA_RATING_NOT_YET_AVAILABLE : STR_NAUSEA_RATING;
|
|
gfx_draw_string_left(dpi, stringId, gCommonFormatArgs, COLOUR_BLACK, x, y);
|
|
y += 2 * LIST_ROW_HEIGHT;
|
|
|
|
// Horizontal rule
|
|
gfx_fill_rect_inset(dpi, x, y - 6, x + 303, y - 5, w->colours[1], INSET_RECT_FLAG_BORDER_INSET);
|
|
|
|
if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_NO_RAW_STATS)) {
|
|
if (ride->type == RIDE_TYPE_MINI_GOLF) {
|
|
// Holes
|
|
holes = ride->holes & 0x1F;
|
|
gfx_draw_string_left(dpi, STR_HOLES, &holes, COLOUR_BLACK, x, y);
|
|
y += LIST_ROW_HEIGHT;
|
|
} else {
|
|
// Max speed
|
|
maxSpeed = (ride->max_speed * 9) >> 18;
|
|
gfx_draw_string_left(dpi, STR_MAX_SPEED, &maxSpeed, COLOUR_BLACK, x, y);
|
|
y += LIST_ROW_HEIGHT;
|
|
|
|
// Average speed
|
|
averageSpeed = (ride->average_speed * 9) >> 18;
|
|
gfx_draw_string_left(dpi, STR_AVERAGE_SPEED, &averageSpeed, COLOUR_BLACK, x, y);
|
|
y += LIST_ROW_HEIGHT;
|
|
|
|
// Ride time
|
|
sint32 numTimes = 0;
|
|
for (sint32 i = 0; i < ride->num_stations; i++) {
|
|
time = ride->time[numTimes];
|
|
if (time != 0) {
|
|
set_format_arg(0 + (numTimes * 4), uint16, STR_RIDE_TIME_ENTRY_WITH_SEPARATOR);
|
|
set_format_arg(2 + (numTimes * 4), uint16, time);
|
|
numTimes++;
|
|
}
|
|
}
|
|
if (numTimes == 0) {
|
|
set_format_arg(0, rct_string_id, STR_RIDE_TIME_ENTRY);
|
|
set_format_arg(2, uint16, 0);
|
|
numTimes++;
|
|
} else {
|
|
//sadly, STR_RIDE_TIME_ENTRY_WITH_SEPARATOR are defined with the separator AFTER an entry
|
|
//therefore we set the last entry to use the no-separator format now, post-format
|
|
set_format_arg(0 + ((numTimes - 1) * 4), uint16, STR_RIDE_TIME_ENTRY);
|
|
}
|
|
set_format_arg(0 + (numTimes * 4), uint16, 0);
|
|
set_format_arg(2 + (numTimes * 4), uint16, 0);
|
|
set_format_arg(4 + (numTimes * 4), uint16, 0);
|
|
set_format_arg(6 + (numTimes * 4), uint16, 0);
|
|
gfx_draw_string_left_clipped(dpi, STR_RIDE_TIME, gCommonFormatArgs, COLOUR_BLACK, x, y, 308);
|
|
y += LIST_ROW_HEIGHT;
|
|
}
|
|
|
|
// Ride length
|
|
sint32 numLengths = 0;
|
|
for (sint32 i = 0; i < ride->num_stations; i++) {
|
|
length = ride->length[numLengths];
|
|
if (length != 0) {
|
|
length >>= 16;
|
|
set_format_arg(0 + (numLengths * 4), uint16, STR_RIDE_LENGTH_ENTRY_WITH_SEPARATOR);
|
|
set_format_arg(2 + (numLengths * 4), uint16, (length & 0xFFFF));
|
|
numLengths++;
|
|
}
|
|
}
|
|
if (numLengths == 0) {
|
|
set_format_arg(0, rct_string_id, STR_RIDE_LENGTH_ENTRY);
|
|
set_format_arg(2, uint16, 0);
|
|
numLengths++;
|
|
} else {
|
|
//sadly, STR_RIDE_LENGTH_ENTRY_WITH_SEPARATOR are defined with the separator AFTER an entry
|
|
//therefore we set the last entry to use the no-separator format now, post-format
|
|
set_format_arg(0 + ((numLengths - 1) * 4), rct_string_id, STR_RIDE_LENGTH_ENTRY);
|
|
}
|
|
set_format_arg(0 + (numLengths * 4), uint16, 0);
|
|
set_format_arg(2 + (numLengths * 4), uint16, 0);
|
|
set_format_arg(4 + (numLengths * 4), uint16, 0);
|
|
set_format_arg(6 + (numLengths * 4), uint16, 0);
|
|
gfx_draw_string_left_clipped(dpi, STR_RIDE_LENGTH, gCommonFormatArgs, COLOUR_BLACK, x, y, 308);
|
|
y += LIST_ROW_HEIGHT;
|
|
|
|
if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_HAS_G_FORCES)) {
|
|
// Max. positive vertical G's
|
|
maxPositiveVerticalGs = ride->max_positive_vertical_g;
|
|
stringId = maxPositiveVerticalGs >= FIXED_2DP(5,00) ?
|
|
STR_MAX_POSITIVE_VERTICAL_G_RED : STR_MAX_POSITIVE_VERTICAL_G;
|
|
gfx_draw_string_left(dpi, stringId, &maxPositiveVerticalGs, COLOUR_BLACK, x, y);
|
|
y += LIST_ROW_HEIGHT;
|
|
|
|
// Max. negative vertical G's
|
|
maxNegativeVerticalGs = ride->max_negative_vertical_g;
|
|
stringId = maxNegativeVerticalGs <= -FIXED_2DP(2,00) ?
|
|
STR_MAX_NEGATIVE_VERTICAL_G_RED : STR_MAX_NEGATIVE_VERTICAL_G;
|
|
gfx_draw_string_left(dpi, stringId, &maxNegativeVerticalGs, COLOUR_BLACK, x, y);
|
|
y += LIST_ROW_HEIGHT;
|
|
|
|
// Max lateral G's
|
|
maxLateralGs = ride->max_lateral_g;
|
|
stringId = maxLateralGs >= FIXED_2DP(2,80) ?
|
|
STR_MAX_LATERAL_G_RED : STR_MAX_LATERAL_G;
|
|
gfx_draw_string_left(dpi, stringId, &maxLateralGs, COLOUR_BLACK, x, y);
|
|
y += LIST_ROW_HEIGHT;
|
|
|
|
// Total 'air' time
|
|
totalAirTime = ride->total_air_time * 3;
|
|
gfx_draw_string_left(dpi, STR_TOTAL_AIR_TIME, &totalAirTime, COLOUR_BLACK, x, y);
|
|
y += LIST_ROW_HEIGHT;
|
|
}
|
|
|
|
if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_HAS_DROPS)) {
|
|
// Drops
|
|
drops = ride->drops & 0x3F;
|
|
gfx_draw_string_left(dpi, STR_DROPS, &drops, COLOUR_BLACK, x, y);
|
|
y += LIST_ROW_HEIGHT;
|
|
|
|
// Highest drop height
|
|
highestDropHeight = (ride->highest_drop_height * 3) / 4;
|
|
gfx_draw_string_left(dpi, STR_HIGHEST_DROP_HEIGHT, &highestDropHeight, COLOUR_BLACK, x, y);
|
|
y += LIST_ROW_HEIGHT;
|
|
}
|
|
|
|
if (ride->type != RIDE_TYPE_MINI_GOLF) {
|
|
// Inversions
|
|
inversions = ride->inversions & 0x1F;
|
|
if (inversions != 0) {
|
|
gfx_draw_string_left(dpi, STR_INVERSIONS, &inversions, COLOUR_BLACK, x, y);
|
|
y += LIST_ROW_HEIGHT;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
gfx_draw_string_left(dpi, STR_NO_TEST_RESULTS_YET, nullptr, COLOUR_BLACK, x, y);
|
|
}
|
|
}
|
|
}
|
|
|
|
#pragma endregion
|
|
|
|
#pragma region Graphs
|
|
|
|
enum {
|
|
GRAPH_VELOCITY,
|
|
GRAPH_ALTITUDE,
|
|
GRAPH_VERTICAL,
|
|
GRAPH_LATERAL
|
|
};
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AE8A6
|
|
*/
|
|
static void window_ride_set_graph(rct_window *w, sint32 type)
|
|
{
|
|
if ((w->list_information_type & 0xFF) == type) {
|
|
w->list_information_type ^= 0x8000;
|
|
} else {
|
|
w->list_information_type &= 0xFF00;
|
|
w->list_information_type |= type;
|
|
}
|
|
window_invalidate(w);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AE85D
|
|
*/
|
|
static void window_ride_graphs_mouseup(rct_window *w, rct_widgetindex widgetIndex)
|
|
{
|
|
switch (widgetIndex) {
|
|
case WIDX_CLOSE:
|
|
window_close(w);
|
|
break;
|
|
case WIDX_TAB_1:
|
|
case WIDX_TAB_2:
|
|
case WIDX_TAB_3:
|
|
case WIDX_TAB_4:
|
|
case WIDX_TAB_5:
|
|
case WIDX_TAB_6:
|
|
case WIDX_TAB_7:
|
|
case WIDX_TAB_8:
|
|
case WIDX_TAB_9:
|
|
case WIDX_TAB_10:
|
|
window_ride_set_page(w, widgetIndex - WIDX_TAB_1);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AE8DA
|
|
*/
|
|
static void window_ride_graphs_resize(rct_window *w)
|
|
{
|
|
window_set_resize(w, 316, 180, 500, 450);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AE878
|
|
*/
|
|
static void window_ride_graphs_mousedown(rct_window *w, rct_widgetindex widgetIndex, rct_widget *widget)
|
|
{
|
|
switch (widgetIndex) {
|
|
case WIDX_GRAPH_VELOCITY:
|
|
window_ride_set_graph(w, GRAPH_VELOCITY);
|
|
break;
|
|
case WIDX_GRAPH_ALTITUDE:
|
|
window_ride_set_graph(w, GRAPH_ALTITUDE);
|
|
break;
|
|
case WIDX_GRAPH_VERTICAL:
|
|
window_ride_set_graph(w, GRAPH_VERTICAL);
|
|
break;
|
|
case WIDX_GRAPH_LATERAL:
|
|
window_ride_set_graph(w, GRAPH_LATERAL);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AE95D
|
|
*/
|
|
static void window_ride_graphs_update(rct_window *w)
|
|
{
|
|
rct_widget *widget;
|
|
rct_ride_measurement *measurement;
|
|
sint32 x;
|
|
|
|
w->frame_no++;
|
|
window_event_invalidate_call(w);
|
|
widget_invalidate(w, WIDX_TAB_8);
|
|
window_event_invalidate_call(w);
|
|
widget_invalidate(w, WIDX_GRAPH);
|
|
|
|
widget = &window_ride_graphs_widgets[WIDX_GRAPH];
|
|
x = w->scrolls[0].h_left;
|
|
if (!(w->list_information_type & 0x8000)) {
|
|
measurement = ride_get_measurement(w->number, nullptr);
|
|
x = measurement == nullptr ?
|
|
0 :
|
|
measurement->current_item - (((widget->right - widget->left) / 4) * 3);
|
|
}
|
|
|
|
w->scrolls[0].h_left = Math::Clamp(0, x, w->scrolls[0].h_right - ((widget->right - widget->left) - 2));
|
|
widget_scroll_update_thumbs(w, WIDX_GRAPH);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AEA75
|
|
*/
|
|
static void window_ride_graphs_scrollgetheight(rct_window *w, sint32 scrollIndex, sint32 *width, sint32 *height)
|
|
{
|
|
rct_ride_measurement *measurement;
|
|
|
|
window_event_invalidate_call(w);
|
|
|
|
// Set minimum size
|
|
*width = window_ride_graphs_widgets[WIDX_GRAPH].right - window_ride_graphs_widgets[WIDX_GRAPH].left - 2;
|
|
|
|
// Get measurement size
|
|
measurement = ride_get_measurement(w->number, nullptr);
|
|
if (measurement != nullptr)
|
|
*width = Math::Max<sint32>(*width, measurement->num_items);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AE953
|
|
*/
|
|
static void window_ride_graphs_15(rct_window *w, sint32 scrollIndex, sint32 scrollAreaType)
|
|
{
|
|
w->list_information_type |= 0x8000;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AEA05
|
|
*/
|
|
static void window_ride_graphs_tooltip(rct_window* w, rct_widgetindex widgetIndex, rct_string_id *stringId)
|
|
{
|
|
if (widgetIndex == WIDX_GRAPH) {
|
|
set_format_arg(0, rct_string_id, STR_GRAPH);
|
|
rct_string_id message;
|
|
rct_ride_measurement *measurement = ride_get_measurement(w->number, &message);
|
|
if (measurement != nullptr && (measurement->flags & RIDE_MEASUREMENT_FLAG_RUNNING)) {
|
|
set_format_arg(4, uint16, measurement->vehicle_index + 1);
|
|
Ride *ride = get_ride(w->number);
|
|
set_format_arg(2, rct_string_id, RideComponentNames[RideNameConvention[ride->type].vehicle].count);
|
|
} else {
|
|
*stringId = message;
|
|
}
|
|
} else {
|
|
*stringId = STR_NONE;
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AE372
|
|
*/
|
|
static void window_ride_graphs_invalidate(rct_window *w)
|
|
{
|
|
rct_widget *widgets;
|
|
Ride *ride;
|
|
sint32 x, y;
|
|
|
|
widgets = window_ride_page_widgets[w->page];
|
|
if (w->widgets != widgets) {
|
|
w->widgets = widgets;
|
|
window_init_scroll_widgets(w);
|
|
}
|
|
|
|
window_ride_set_pressed_tab(w);
|
|
|
|
ride = get_ride(w->number);
|
|
|
|
set_format_arg(0, rct_string_id, ride->name);
|
|
set_format_arg(2, uint32, ride->name_arguments);
|
|
|
|
// Set pressed graph button type
|
|
w->pressed_widgets &= ~(1 << WIDX_GRAPH_VELOCITY);
|
|
w->pressed_widgets &= ~(1 << WIDX_GRAPH_ALTITUDE);
|
|
w->pressed_widgets &= ~(1 << WIDX_GRAPH_VERTICAL);
|
|
w->pressed_widgets &= ~(1 << WIDX_GRAPH_LATERAL);
|
|
w->pressed_widgets |= (1LL << (WIDX_GRAPH_VELOCITY + (w->list_information_type & 0xFF)));
|
|
|
|
// Hide graph buttons that are not applicable
|
|
if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_HAS_G_FORCES)) {
|
|
window_ride_graphs_widgets[WIDX_GRAPH_VERTICAL].type = WWT_BUTTON;
|
|
window_ride_graphs_widgets[WIDX_GRAPH_LATERAL].type = WWT_BUTTON;
|
|
} else {
|
|
window_ride_graphs_widgets[WIDX_GRAPH_VERTICAL].type = WWT_EMPTY;
|
|
window_ride_graphs_widgets[WIDX_GRAPH_LATERAL].type = WWT_EMPTY;
|
|
}
|
|
|
|
// Anchor graph widget
|
|
x = w->width - 4;
|
|
y = w->height - 18;
|
|
|
|
window_ride_graphs_widgets[WIDX_GRAPH].right = x;
|
|
window_ride_graphs_widgets[WIDX_GRAPH].bottom = y;
|
|
y += 3;
|
|
window_ride_graphs_widgets[WIDX_GRAPH_VELOCITY].top = y;
|
|
window_ride_graphs_widgets[WIDX_GRAPH_ALTITUDE].top = y;
|
|
window_ride_graphs_widgets[WIDX_GRAPH_VERTICAL].top = y;
|
|
window_ride_graphs_widgets[WIDX_GRAPH_LATERAL].top = y;
|
|
y += 11;
|
|
window_ride_graphs_widgets[WIDX_GRAPH_VELOCITY].bottom = y;
|
|
window_ride_graphs_widgets[WIDX_GRAPH_ALTITUDE].bottom = y;
|
|
window_ride_graphs_widgets[WIDX_GRAPH_VERTICAL].bottom = y;
|
|
window_ride_graphs_widgets[WIDX_GRAPH_LATERAL].bottom = y;
|
|
|
|
window_ride_anchor_border_widgets(w);
|
|
window_align_tabs(w, WIDX_TAB_1, WIDX_TAB_10);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AE4BC
|
|
*/
|
|
static void window_ride_graphs_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
|
{
|
|
window_draw_widgets(w, dpi);
|
|
window_ride_draw_tab_images(dpi, w);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AE4C7
|
|
*/
|
|
static void window_ride_graphs_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, sint32 scrollIndex)
|
|
{
|
|
gfx_clear(dpi, ColourMapA[COLOUR_SATURATED_GREEN].darker);
|
|
|
|
rct_widget *widget = &window_ride_graphs_widgets[WIDX_GRAPH];
|
|
rct_string_id stringId;
|
|
rct_ride_measurement *measurement = ride_get_measurement(w->number, &stringId);
|
|
if (measurement == nullptr) {
|
|
// No measurement message
|
|
sint32 x = (widget->right - widget->left) / 2;
|
|
sint32 y = (widget->bottom - widget->top) / 2 - 5;
|
|
sint32 width = widget->right - widget->left - 2;
|
|
gfx_draw_string_centred_wrapped(dpi, gCommonFormatArgs, x, y, width, stringId, COLOUR_BLACK);
|
|
return;
|
|
}
|
|
|
|
// Vertical grid lines
|
|
const uint8 lightColour = ColourMapA[COLOUR_SATURATED_GREEN].mid_light;
|
|
const uint8 darkColour = ColourMapA[COLOUR_SATURATED_GREEN].mid_dark;
|
|
|
|
sint32 time = 0;
|
|
for (sint32 x = 0; x < dpi->x + dpi->width; x += 80) {
|
|
if (x + 80 >= dpi->x) {
|
|
gfx_fill_rect(dpi, x + 0, dpi->y, x + 0, dpi->y + dpi->height - 1, lightColour);
|
|
gfx_fill_rect(dpi, x + 16, dpi->y, x + 16, dpi->y + dpi->height - 1, darkColour);
|
|
gfx_fill_rect(dpi, x + 32, dpi->y, x + 32, dpi->y + dpi->height - 1, darkColour);
|
|
gfx_fill_rect(dpi, x + 48, dpi->y, x + 48, dpi->y + dpi->height - 1, darkColour);
|
|
gfx_fill_rect(dpi, x + 64, dpi->y, x + 64, dpi->y + dpi->height - 1, darkColour);
|
|
}
|
|
time += 5;
|
|
}
|
|
|
|
// Horizontal grid lines
|
|
sint32 listType = w->list_information_type & 0xFF;
|
|
sint16 yUnit = window_graphs_y_axi[listType].unit;
|
|
rct_string_id stringID = window_graphs_y_axi[listType].label;
|
|
sint16 yUnitInterval = window_graphs_y_axi[listType].unit_interval;
|
|
sint16 yInterval = window_graphs_y_axi[listType].interval;
|
|
|
|
// Scale modifier
|
|
if (listType == GRAPH_ALTITUDE) {
|
|
yUnit -= gMapBaseZ * 3;
|
|
}
|
|
|
|
for (sint32 y = widget->bottom - widget->top - 13; y >= 8; y -= yInterval, yUnit += yUnitInterval) {
|
|
// Minor / major line
|
|
sint32 colour = yUnit == 0 ? lightColour : darkColour;
|
|
gfx_fill_rect(dpi, dpi->x, y, dpi->x + dpi->width - 1, y, colour);
|
|
|
|
sint16 scaled_yUnit = yUnit;
|
|
// Scale modifier
|
|
if (listType == GRAPH_ALTITUDE)
|
|
scaled_yUnit /= 2;
|
|
|
|
gfx_draw_string_left(dpi, stringID, &scaled_yUnit, COLOUR_BLACK, w->scrolls[0].h_left + 1, y - 4);
|
|
}
|
|
|
|
// Time marks
|
|
time = 0;
|
|
for (sint32 x = 0; x < dpi->x + dpi->width; x += 80) {
|
|
if (x + 80 >= dpi->x)
|
|
gfx_draw_string_left(dpi, STR_RIDE_STATS_TIME, &time, COLOUR_BLACK, x + 2, 1);
|
|
time += 5;
|
|
}
|
|
|
|
// Plot
|
|
sint32 x = dpi->x;
|
|
sint32 top, bottom;
|
|
for (sint32 width = 0; width < dpi->width; width++, x++) {
|
|
if (x < 0 || x >= measurement->num_items - 1)
|
|
continue;
|
|
|
|
switch (listType) {
|
|
case GRAPH_VELOCITY:
|
|
top = measurement->velocity[x] / 2;
|
|
bottom = measurement->velocity[x + 1] / 2;
|
|
break;
|
|
case GRAPH_ALTITUDE:
|
|
top = measurement->altitude[x];
|
|
bottom = measurement->altitude[x + 1];
|
|
break;
|
|
case GRAPH_VERTICAL:
|
|
top = measurement->vertical[x] + 39;
|
|
bottom = measurement->vertical[x + 1] + 39;
|
|
break;
|
|
case GRAPH_LATERAL:
|
|
top = measurement->lateral[x] + 52;
|
|
bottom = measurement->lateral[x + 1] + 52;
|
|
break;
|
|
default:
|
|
log_error("Wrong graph type %d", listType);
|
|
top = bottom = 0;
|
|
}
|
|
|
|
top = widget->bottom - widget->top - top - 13;
|
|
bottom = widget->bottom - widget->top - bottom - 13;
|
|
if (top > bottom) {
|
|
sint32 tmp = top;
|
|
top = bottom;
|
|
bottom = tmp;
|
|
}
|
|
gfx_fill_rect(dpi, x, top, x, bottom, x > measurement->current_item ? PALETTE_INDEX_17 : PALETTE_INDEX_21);
|
|
}
|
|
}
|
|
|
|
#pragma endregion
|
|
|
|
#pragma region Income
|
|
|
|
static void update_same_price_throughout_flags(uint32 shop_item)
|
|
{
|
|
uint32 newFlags;
|
|
|
|
if (shop_item_is_photo(shop_item)) {
|
|
newFlags = gSamePriceThroughoutParkA;
|
|
newFlags ^= (1 << SHOP_ITEM_PHOTO);
|
|
game_do_command(0, 1, 0, (0x2 << 8), GAME_COMMAND_SET_PARK_OPEN, newFlags, shop_item);
|
|
|
|
newFlags = gSamePriceThroughoutParkB;
|
|
newFlags ^= (1 << (SHOP_ITEM_PHOTO2 - 32)) |
|
|
(1 << (SHOP_ITEM_PHOTO3 - 32)) |
|
|
(1 << (SHOP_ITEM_PHOTO4 - 32));
|
|
game_do_command(0, 1, 0, (0x3 << 8), GAME_COMMAND_SET_PARK_OPEN, newFlags, shop_item);
|
|
}
|
|
else {
|
|
if (shop_item < 32) {
|
|
newFlags = gSamePriceThroughoutParkA;
|
|
newFlags ^= (1u << shop_item);
|
|
game_do_command(0, 1, 0, (0x2 << 8), GAME_COMMAND_SET_PARK_OPEN, newFlags, shop_item);
|
|
}
|
|
else {
|
|
newFlags = gSamePriceThroughoutParkB;
|
|
newFlags ^= (1u << (shop_item - 32));
|
|
game_do_command(0, 1, 0, (0x3 << 8), GAME_COMMAND_SET_PARK_OPEN, newFlags, shop_item);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006ADEFD
|
|
*/
|
|
static void window_ride_income_toggle_primary_price(rct_window *w)
|
|
{
|
|
Ride * ride;
|
|
rct_ride_entry * rideEntry;
|
|
uint32 shop_item;
|
|
money16 price;
|
|
|
|
ride = get_ride(w->number);
|
|
rideEntry = get_ride_entry(ride->subtype);
|
|
|
|
if (ride->type == RIDE_TYPE_TOILETS) {
|
|
shop_item = SHOP_ITEM_ADMISSION;
|
|
}
|
|
else {
|
|
shop_item = rideEntry->shop_item;
|
|
if (shop_item == 0xFFFF)
|
|
return;
|
|
}
|
|
|
|
update_same_price_throughout_flags(shop_item);
|
|
|
|
price = ride->price;
|
|
game_do_command(0, 1, 0, w->number, GAME_COMMAND_SET_RIDE_PRICE, price, 0);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AE06E
|
|
*/
|
|
static void window_ride_income_toggle_secondary_price(rct_window *w)
|
|
{
|
|
Ride * ride;
|
|
rct_ride_entry * rideEntry;
|
|
uint32 shop_item;
|
|
money16 price;
|
|
|
|
ride = get_ride(w->number);
|
|
rideEntry = get_ride_entry(ride->subtype);
|
|
|
|
shop_item = rideEntry->shop_item_secondary;
|
|
if (shop_item == SHOP_ITEM_NONE)
|
|
shop_item = RidePhotoItems[ride->type];
|
|
|
|
update_same_price_throughout_flags(shop_item);
|
|
|
|
price = ride->price_secondary;
|
|
game_do_command(0, 1, 0, (1 << 8) | w->number, GAME_COMMAND_SET_RIDE_PRICE, price, 0);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AE1E4
|
|
*/
|
|
static void window_ride_income_increase_primary_price(rct_window *w)
|
|
{
|
|
Ride * ride;
|
|
rct_ride_entry * rideEntry;
|
|
|
|
ride = get_ride(w->number);
|
|
rideEntry = get_ride_entry(ride->subtype);
|
|
|
|
if (!park_ride_prices_unlocked())
|
|
{
|
|
if (ride->type != RIDE_TYPE_TOILETS && rideEntry->shop_item == SHOP_ITEM_NONE)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
money16 price = ride->price;
|
|
if (price < MONEY(20, 00))
|
|
price++;
|
|
|
|
game_do_command(0, 1, 0, w->number, GAME_COMMAND_SET_RIDE_PRICE, price, 0);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AE237
|
|
*/
|
|
static void window_ride_income_decrease_primary_price(rct_window *w)
|
|
{
|
|
Ride *ride;
|
|
rct_ride_entry *rideEntry;
|
|
|
|
ride = get_ride(w->number);
|
|
rideEntry = get_ride_entry(ride->subtype);
|
|
|
|
if (!park_ride_prices_unlocked())
|
|
{
|
|
if (ride->type != RIDE_TYPE_TOILETS && rideEntry->shop_item == SHOP_ITEM_NONE)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
money16 price = ride->price;
|
|
if (price > MONEY(0, 00))
|
|
price--;
|
|
|
|
game_do_command(0, 1, 0, w->number, GAME_COMMAND_SET_RIDE_PRICE, price, 0);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AE269
|
|
*/
|
|
static void window_ride_income_increase_secondary_price(rct_window *w)
|
|
{
|
|
Ride *ride;
|
|
|
|
ride = get_ride(w->number);
|
|
|
|
money16 price = ride->price_secondary;
|
|
if (price < MONEY(20, 00))
|
|
price++;
|
|
|
|
game_do_command(0, 1, 0, (w->number & 0x00FF) | 0x0100, GAME_COMMAND_SET_RIDE_PRICE, price, 0);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AE28D
|
|
*/
|
|
static void window_ride_income_decrease_secondary_price(rct_window *w)
|
|
{
|
|
Ride *ride;
|
|
|
|
ride = get_ride(w->number);
|
|
|
|
money16 price = ride->price_secondary;
|
|
if (price > MONEY(0, 00))
|
|
price--;
|
|
|
|
game_do_command(0, 1, 0, (w->number & 0x00FF) | 0x0100, GAME_COMMAND_SET_RIDE_PRICE, price, 0);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006ADEA9
|
|
*/
|
|
static void window_ride_income_mouseup(rct_window *w, rct_widgetindex widgetIndex)
|
|
{
|
|
switch (widgetIndex) {
|
|
case WIDX_CLOSE:
|
|
window_close(w);
|
|
break;
|
|
case WIDX_TAB_1:
|
|
case WIDX_TAB_2:
|
|
case WIDX_TAB_3:
|
|
case WIDX_TAB_4:
|
|
case WIDX_TAB_5:
|
|
case WIDX_TAB_6:
|
|
case WIDX_TAB_7:
|
|
case WIDX_TAB_8:
|
|
case WIDX_TAB_9:
|
|
case WIDX_TAB_10:
|
|
window_ride_set_page(w, widgetIndex - WIDX_TAB_1);
|
|
break;
|
|
case WIDX_PRIMARY_PRICE_SAME_THROUGHOUT_PARK:
|
|
window_ride_income_toggle_primary_price(w);
|
|
break;
|
|
case WIDX_SECONDARY_PRICE_SAME_THROUGHOUT_PARK:
|
|
window_ride_income_toggle_secondary_price(w);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AE2F8
|
|
*/
|
|
static void window_ride_income_resize(rct_window *w)
|
|
{
|
|
window_set_resize(w, 316, 183, 316, 183);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006ADED4
|
|
*/
|
|
static void window_ride_income_mousedown(rct_window *w, rct_widgetindex widgetIndex, rct_widget *widget)
|
|
{
|
|
switch (widgetIndex) {
|
|
case WIDX_PRIMARY_PRICE_INCREASE:
|
|
window_ride_income_increase_primary_price(w);
|
|
break;
|
|
case WIDX_PRIMARY_PRICE_DECREASE:
|
|
window_ride_income_decrease_primary_price(w);
|
|
break;
|
|
case WIDX_SECONDARY_PRICE_INCREASE:
|
|
window_ride_income_increase_secondary_price(w);
|
|
break;
|
|
case WIDX_SECONDARY_PRICE_DECREASE:
|
|
window_ride_income_decrease_secondary_price(w);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AE2BF
|
|
*/
|
|
static void window_ride_income_update(rct_window *w)
|
|
{
|
|
Ride *ride;
|
|
|
|
w->frame_no++;
|
|
window_event_invalidate_call(w);
|
|
widget_invalidate(w, WIDX_TAB_9);
|
|
|
|
ride = get_ride(w->number);
|
|
if (ride->window_invalidate_flags & RIDE_INVALIDATE_RIDE_INCOME) {
|
|
ride->window_invalidate_flags &= ~RIDE_INVALIDATE_RIDE_INCOME;
|
|
window_invalidate(w);
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006ADAA3
|
|
*/
|
|
static void window_ride_income_invalidate(rct_window *w)
|
|
{
|
|
rct_widget *widgets;
|
|
rct_ride_entry *rideEntry;
|
|
sint32 primaryItem, secondaryItem;
|
|
|
|
widgets = window_ride_page_widgets[w->page];
|
|
if (w->widgets != widgets) {
|
|
w->widgets = widgets;
|
|
window_init_scroll_widgets(w);
|
|
}
|
|
|
|
window_ride_set_pressed_tab(w);
|
|
|
|
Ride *ride = get_ride(w->number);
|
|
set_format_arg(0, rct_string_id, ride->name);
|
|
set_format_arg(2, uint32, ride->name_arguments);
|
|
|
|
rideEntry = get_ride_entry_by_ride(ride);
|
|
|
|
// Primary item
|
|
w->pressed_widgets &= ~(1 << WIDX_PRIMARY_PRICE_SAME_THROUGHOUT_PARK);
|
|
w->disabled_widgets &= ~(1 << WIDX_PRIMARY_PRICE);
|
|
|
|
window_ride_income_widgets[WIDX_PRIMARY_PRICE_LABEL].tooltip = STR_NONE;
|
|
window_ride_income_widgets[WIDX_PRIMARY_PRICE].tooltip = STR_NONE;
|
|
|
|
// If ride prices are locked, do not allow setting the price, unless we're dealing with a shop or toilet.
|
|
if (!park_ride_prices_unlocked() && rideEntry->shop_item == SHOP_ITEM_NONE && ride->type != RIDE_TYPE_TOILETS)
|
|
{
|
|
w->disabled_widgets |= (1 << WIDX_PRIMARY_PRICE);
|
|
window_ride_income_widgets[WIDX_PRIMARY_PRICE_LABEL].tooltip = STR_RIDE_INCOME_ADMISSION_PAY_FOR_ENTRY_TIP;
|
|
window_ride_income_widgets[WIDX_PRIMARY_PRICE].tooltip = STR_RIDE_INCOME_ADMISSION_PAY_FOR_ENTRY_TIP;
|
|
}
|
|
|
|
window_ride_income_widgets[WIDX_PRIMARY_PRICE_LABEL].text = STR_RIDE_INCOME_ADMISSION_PRICE;
|
|
window_ride_income_widgets[WIDX_SECONDARY_PRICE_LABEL].text = STR_SHOP_ITEM_PRICE_LABEL_ON_RIDE_PHOTO;
|
|
window_ride_income_widgets[WIDX_PRIMARY_PRICE_SAME_THROUGHOUT_PARK].type = WWT_EMPTY;
|
|
|
|
window_ride_income_widgets[WIDX_PRIMARY_PRICE].text = STR_ARG_6_CURRENCY2DP;
|
|
money16 ridePrimaryPrice = ride_get_price(ride);
|
|
set_format_arg(6, money32, ridePrimaryPrice);
|
|
if (ridePrimaryPrice == 0)
|
|
window_ride_income_widgets[WIDX_PRIMARY_PRICE].text = STR_FREE;
|
|
|
|
primaryItem = SHOP_ITEM_ADMISSION;
|
|
if (ride->type == RIDE_TYPE_TOILETS || ((primaryItem = rideEntry->shop_item) != SHOP_ITEM_NONE)) {
|
|
window_ride_income_widgets[WIDX_PRIMARY_PRICE_SAME_THROUGHOUT_PARK].type = WWT_CHECKBOX;
|
|
|
|
if (shop_item_has_common_price(primaryItem))
|
|
w->pressed_widgets |= (1 << WIDX_PRIMARY_PRICE_SAME_THROUGHOUT_PARK);
|
|
|
|
window_ride_income_widgets[WIDX_PRIMARY_PRICE_LABEL].text = ShopItemStringIds[primaryItem].price_label;
|
|
}
|
|
|
|
// Get secondary item
|
|
secondaryItem = RidePhotoItems[ride->type];
|
|
if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_ON_RIDE_PHOTO)) {
|
|
if ((secondaryItem = rideEntry->shop_item_secondary) != SHOP_ITEM_NONE) {
|
|
window_ride_income_widgets[WIDX_SECONDARY_PRICE_LABEL].text = ShopItemStringIds[secondaryItem].price_label;
|
|
}
|
|
}
|
|
|
|
if (secondaryItem == SHOP_ITEM_NONE) {
|
|
// Hide secondary item widgets
|
|
window_ride_income_widgets[WIDX_SECONDARY_PRICE_LABEL].type = WWT_EMPTY;
|
|
window_ride_income_widgets[WIDX_SECONDARY_PRICE].type = WWT_EMPTY;
|
|
window_ride_income_widgets[WIDX_SECONDARY_PRICE_INCREASE].type = WWT_EMPTY;
|
|
window_ride_income_widgets[WIDX_SECONDARY_PRICE_DECREASE].type = WWT_EMPTY;
|
|
window_ride_income_widgets[WIDX_SECONDARY_PRICE_SAME_THROUGHOUT_PARK].type = WWT_EMPTY;
|
|
} else {
|
|
// Set same price throughout park checkbox
|
|
w->pressed_widgets &= ~(1 << WIDX_SECONDARY_PRICE_SAME_THROUGHOUT_PARK);
|
|
if (shop_item_has_common_price(secondaryItem))
|
|
w->pressed_widgets |= (1 << WIDX_SECONDARY_PRICE_SAME_THROUGHOUT_PARK);
|
|
|
|
// Show widgets
|
|
window_ride_income_widgets[WIDX_SECONDARY_PRICE_LABEL].type = WWT_LABEL;
|
|
window_ride_income_widgets[WIDX_SECONDARY_PRICE].type = WWT_SPINNER;
|
|
window_ride_income_widgets[WIDX_SECONDARY_PRICE_INCREASE].type = WWT_BUTTON;
|
|
window_ride_income_widgets[WIDX_SECONDARY_PRICE_DECREASE].type = WWT_BUTTON;
|
|
window_ride_income_widgets[WIDX_SECONDARY_PRICE_SAME_THROUGHOUT_PARK].type = WWT_CHECKBOX;
|
|
|
|
// Set secondary item price
|
|
window_ride_income_widgets[WIDX_SECONDARY_PRICE].text = STR_RIDE_SECONDARY_PRICE_VALUE;
|
|
set_format_arg(10, money32, ride->price_secondary);
|
|
if (ride->price_secondary == 0)
|
|
window_ride_income_widgets[WIDX_SECONDARY_PRICE].text = STR_FREE;
|
|
}
|
|
|
|
window_ride_anchor_border_widgets(w);
|
|
window_align_tabs(w, WIDX_TAB_1, WIDX_TAB_10);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006ADCE5
|
|
*/
|
|
static void window_ride_income_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
|
{
|
|
Ride *ride;
|
|
rct_ride_entry *rideEntry;
|
|
rct_string_id stringId;
|
|
money32 profit, costPerHour;
|
|
sint32 x, y, primaryItem, secondaryItem;
|
|
|
|
window_draw_widgets(w, dpi);
|
|
window_ride_draw_tab_images(dpi, w);
|
|
|
|
ride = get_ride(w->number);
|
|
rideEntry = get_ride_entry_by_ride(ride);
|
|
|
|
x = w->x + window_ride_income_widgets[WIDX_PAGE_BACKGROUND].left + 4;
|
|
y = w->y + window_ride_income_widgets[WIDX_PAGE_BACKGROUND].top + 29;
|
|
|
|
// Primary item profit / loss per item sold
|
|
primaryItem = rideEntry->shop_item;
|
|
if (primaryItem != SHOP_ITEM_NONE) {
|
|
profit = ride->price;
|
|
|
|
stringId = STR_PROFIT_PER_ITEM_SOLD;
|
|
profit -= get_shop_item_cost(primaryItem);
|
|
if (profit < 0) {
|
|
profit *= -1;
|
|
stringId = STR_LOSS_PER_ITEM_SOLD;
|
|
}
|
|
|
|
gfx_draw_string_left(dpi, stringId, &profit, COLOUR_BLACK, x, y);
|
|
}
|
|
y += 39;
|
|
|
|
// Secondary item profit / loss per item sold
|
|
secondaryItem = RidePhotoItems[ride->type];
|
|
if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_ON_RIDE_PHOTO))
|
|
secondaryItem = rideEntry->shop_item_secondary;
|
|
|
|
if (secondaryItem != SHOP_ITEM_NONE) {
|
|
profit = ride->price_secondary;
|
|
|
|
stringId = STR_PROFIT_PER_ITEM_SOLD;
|
|
profit -= get_shop_item_cost(secondaryItem);
|
|
if (profit < 0) {
|
|
profit *= -1;
|
|
stringId = STR_LOSS_PER_ITEM_SOLD;
|
|
}
|
|
|
|
gfx_draw_string_left(dpi, stringId, &profit, COLOUR_BLACK, x, y);
|
|
}
|
|
y += 15;
|
|
|
|
// Income per hour
|
|
if (ride->income_per_hour != MONEY32_UNDEFINED) {
|
|
gfx_draw_string_left(dpi, STR_INCOME_PER_HOUR, &ride->income_per_hour, COLOUR_BLACK, x, y);
|
|
y += LIST_ROW_HEIGHT;
|
|
}
|
|
|
|
// Running cost per hour
|
|
costPerHour = ride->upkeep_cost * 16;
|
|
stringId = ride->upkeep_cost == MONEY16_UNDEFINED ? STR_RUNNING_COST_UNKNOWN : STR_RUNNING_COST_PER_HOUR;
|
|
gfx_draw_string_left(dpi, stringId, &costPerHour, COLOUR_BLACK, x, y);
|
|
y += LIST_ROW_HEIGHT;
|
|
|
|
// Profit per hour
|
|
if (ride->profit != MONEY32_UNDEFINED) {
|
|
gfx_draw_string_left(dpi, STR_PROFIT_PER_HOUR, &ride->profit, COLOUR_BLACK, x, y);
|
|
y += LIST_ROW_HEIGHT;
|
|
}
|
|
y += 5;
|
|
|
|
// Total profit
|
|
gfx_draw_string_left(dpi, STR_TOTAL_PROFIT, &ride->total_profit, COLOUR_BLACK, x, y);
|
|
}
|
|
|
|
#pragma endregion
|
|
|
|
#pragma region Customer
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AD986
|
|
*/
|
|
static void window_ride_customer_mouseup(rct_window *w, rct_widgetindex widgetIndex)
|
|
{
|
|
switch (widgetIndex)
|
|
{
|
|
case WIDX_CLOSE:
|
|
window_close(w);
|
|
break;
|
|
case WIDX_TAB_1:
|
|
case WIDX_TAB_2:
|
|
case WIDX_TAB_3:
|
|
case WIDX_TAB_4:
|
|
case WIDX_TAB_5:
|
|
case WIDX_TAB_6:
|
|
case WIDX_TAB_7:
|
|
case WIDX_TAB_8:
|
|
case WIDX_TAB_9:
|
|
case WIDX_TAB_10:
|
|
window_ride_set_page(w, widgetIndex - WIDX_TAB_1);
|
|
break;
|
|
case WIDX_SHOW_GUESTS_THOUGHTS:
|
|
{
|
|
auto intent = Intent(WC_GUEST_LIST);
|
|
intent.putExtra(INTENT_EXTRA_GUEST_LIST_FILTER, GLFT_GUESTS_THINKING_ABOUT_RIDE);
|
|
intent.putExtra(INTENT_EXTRA_RIDE_ID, w->number);
|
|
context_open_intent(&intent);
|
|
break;
|
|
}
|
|
case WIDX_SHOW_GUESTS_ON_RIDE:
|
|
{
|
|
auto intent = Intent(WC_GUEST_LIST);
|
|
intent.putExtra(INTENT_EXTRA_GUEST_LIST_FILTER, GLFT_GUESTS_ON_RIDE);
|
|
intent.putExtra(INTENT_EXTRA_RIDE_ID, w->number);
|
|
context_open_intent(&intent);
|
|
break;
|
|
}
|
|
case WIDX_SHOW_GUESTS_QUEUING:
|
|
{
|
|
auto intent = Intent(WC_GUEST_LIST);
|
|
intent.putExtra(INTENT_EXTRA_GUEST_LIST_FILTER, GLFT_GUESTS_IN_QUEUE);
|
|
intent.putExtra(INTENT_EXTRA_RIDE_ID, w->number);
|
|
context_open_intent(&intent);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006ADA29
|
|
*/
|
|
static void window_ride_customer_resize(rct_window *w)
|
|
{
|
|
w->flags |= WF_RESIZABLE;
|
|
window_set_resize(w, 316, 163, 316, 163);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AD9DD
|
|
*/
|
|
static void window_ride_customer_update(rct_window *w)
|
|
{
|
|
Ride *ride;
|
|
|
|
w->var_492++;
|
|
if (w->var_492 >= 24)
|
|
w->var_492 = 0;
|
|
|
|
window_event_invalidate_call(w);
|
|
widget_invalidate(w, WIDX_TAB_10);
|
|
|
|
ride = get_ride(w->number);
|
|
if (ride->window_invalidate_flags & RIDE_INVALIDATE_RIDE_CUSTOMER) {
|
|
ride->window_invalidate_flags &= ~RIDE_INVALIDATE_RIDE_CUSTOMER;
|
|
window_invalidate(w);
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AD5F8
|
|
*/
|
|
static void window_ride_customer_invalidate(rct_window *w)
|
|
{
|
|
rct_widget *widgets;
|
|
|
|
widgets = window_ride_page_widgets[w->page];
|
|
if (w->widgets != widgets) {
|
|
w->widgets = widgets;
|
|
window_init_scroll_widgets(w);
|
|
}
|
|
|
|
window_ride_set_pressed_tab(w);
|
|
|
|
Ride *ride = get_ride(w->number);
|
|
set_format_arg(0, rct_string_id, ride->name);
|
|
set_format_arg(2, uint32, ride->name_arguments);
|
|
|
|
window_ride_customer_widgets[WIDX_SHOW_GUESTS_THOUGHTS].type = WWT_FLATBTN;
|
|
if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_IS_SHOP)) {
|
|
window_ride_customer_widgets[WIDX_SHOW_GUESTS_ON_RIDE].type = WWT_EMPTY;
|
|
window_ride_customer_widgets[WIDX_SHOW_GUESTS_QUEUING].type = WWT_EMPTY;
|
|
} else {
|
|
window_ride_customer_widgets[WIDX_SHOW_GUESTS_ON_RIDE].type = WWT_FLATBTN;
|
|
window_ride_customer_widgets[WIDX_SHOW_GUESTS_QUEUING].type = WWT_FLATBTN;
|
|
}
|
|
|
|
window_ride_anchor_border_widgets(w);
|
|
window_align_tabs(w, WIDX_TAB_1, WIDX_TAB_10);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* rct2: 0x006AD6CD
|
|
*/
|
|
static void window_ride_customer_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
|
{
|
|
Ride *ride;
|
|
sint32 x, y;
|
|
uint8 shopItem;
|
|
sint16 popularity, satisfaction, queueTime, age;
|
|
sint32 customersPerHour;
|
|
rct_string_id stringId;
|
|
|
|
window_draw_widgets(w, dpi);
|
|
window_ride_draw_tab_images(dpi, w);
|
|
|
|
ride = get_ride(w->number);
|
|
x = w->x + window_ride_customer_widgets[WIDX_PAGE_BACKGROUND].left + 4;
|
|
y = w->y + window_ride_customer_widgets[WIDX_PAGE_BACKGROUND].top + 4;
|
|
|
|
// Customers currently on ride
|
|
if (gRideClassifications[ride->type] == RIDE_CLASS_RIDE) {
|
|
sint16 customersOnRide = ride->num_riders;
|
|
gfx_draw_string_left(dpi, STR_CUSTOMERS_ON_RIDE, &customersOnRide, COLOUR_BLACK, x, y);
|
|
y += LIST_ROW_HEIGHT;
|
|
}
|
|
|
|
// Customers per hour
|
|
customersPerHour = ride_customers_per_hour(ride);
|
|
gfx_draw_string_left(dpi, STR_CUSTOMERS_PER_HOUR, &customersPerHour, COLOUR_BLACK, x, y);
|
|
y += LIST_ROW_HEIGHT;
|
|
|
|
// Popularity
|
|
popularity = ride->popularity;
|
|
if (popularity == 255) {
|
|
stringId = STR_POPULARITY_UNKNOWN;
|
|
} else {
|
|
stringId = STR_POPULARITY_PERCENT;
|
|
popularity *= 4;
|
|
}
|
|
gfx_draw_string_left(dpi, stringId, &popularity, COLOUR_BLACK, x, y);
|
|
y += LIST_ROW_HEIGHT;
|
|
|
|
// Satisfaction
|
|
satisfaction = ride->satisfaction;
|
|
if (satisfaction == 255) {
|
|
stringId = STR_SATISFACTION_UNKNOWN;
|
|
} else {
|
|
stringId = STR_SATISFACTION_PERCENT;
|
|
satisfaction *= 5;
|
|
}
|
|
gfx_draw_string_left(dpi, stringId, &satisfaction, COLOUR_BLACK, x, y);
|
|
y += LIST_ROW_HEIGHT;
|
|
|
|
// Queue time
|
|
if (gRideClassifications[ride->type] == RIDE_CLASS_RIDE) {
|
|
queueTime = ride_get_max_queue_time(ride);
|
|
stringId = queueTime == 1 ? STR_QUEUE_TIME_MINUTE : STR_QUEUE_TIME_MINUTES;
|
|
y += gfx_draw_string_left_wrapped(dpi, &queueTime, x, y, 308, stringId, COLOUR_BLACK);
|
|
y += 5;
|
|
}
|
|
|
|
// Primary shop items sold
|
|
shopItem = get_ride_entry_by_ride(ride)->shop_item;
|
|
if (shopItem != SHOP_ITEM_NONE) {
|
|
set_format_arg(0, rct_string_id, ShopItemStringIds[shopItem].plural);
|
|
set_format_arg(2, uint32, ride->no_primary_items_sold);
|
|
gfx_draw_string_left(dpi, STR_ITEMS_SOLD, gCommonFormatArgs, COLOUR_BLACK, x, y);
|
|
y += LIST_ROW_HEIGHT;
|
|
}
|
|
|
|
// Secondary shop items sold / on-ride photos sold
|
|
shopItem = (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_RIDE_PHOTO) ?
|
|
RidePhotoItems[ride->type] :
|
|
get_ride_entry_by_ride(ride)->shop_item_secondary;
|
|
if (shopItem != SHOP_ITEM_NONE) {
|
|
set_format_arg(0, rct_string_id, ShopItemStringIds[shopItem].plural);
|
|
set_format_arg(2, uint32, ride->no_secondary_items_sold);
|
|
gfx_draw_string_left(dpi, STR_ITEMS_SOLD, gCommonFormatArgs, COLOUR_BLACK, x, y);
|
|
y += LIST_ROW_HEIGHT;
|
|
}
|
|
|
|
// Total customers
|
|
gfx_draw_string_left(dpi, STR_TOTAL_CUSTOMERS, &ride->total_customers, COLOUR_BLACK, x, y);
|
|
y += LIST_ROW_HEIGHT;
|
|
|
|
// Guests favourite
|
|
if (gRideClassifications[ride->type] == RIDE_CLASS_RIDE) {
|
|
stringId = ride->guests_favourite == 1 ?
|
|
STR_FAVOURITE_RIDE_OF_GUEST :
|
|
STR_FAVOURITE_RIDE_OF_GUESTS;
|
|
gfx_draw_string_left(dpi, stringId, &ride->guests_favourite, COLOUR_BLACK, x, y);
|
|
y += LIST_ROW_HEIGHT;
|
|
}
|
|
y += 2;
|
|
|
|
// Age
|
|
//If the ride has a build date that is in the future, show it as built this year.
|
|
age = Math::Max((gDateMonthsElapsed - ride->build_date) / 8, 0);
|
|
stringId = age == 0 ?
|
|
STR_BUILT_THIS_YEAR :
|
|
age == 1 ?
|
|
STR_BUILT_LAST_YEAR :
|
|
STR_BUILT_YEARS_AGO;
|
|
gfx_draw_string_left(dpi, stringId, &age, COLOUR_BLACK, x, y);
|
|
}
|
|
|
|
#pragma endregion
|