2014-05-08 22:48:31 +02:00
|
|
|
/*****************************************************************************
|
2020-07-21 15:04:34 +02:00
|
|
|
* Copyright (c) 2014-2020 OpenRCT2 developers
|
2016-05-04 19:24:41 +02:00
|
|
|
*
|
2018-06-15 14:07:34 +02:00
|
|
|
* For a complete list of all authors, please refer to contributors.md
|
|
|
|
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
|
2016-05-04 19:24:41 +02:00
|
|
|
*
|
2018-06-15 14:07:34 +02:00
|
|
|
* OpenRCT2 is licensed under the GNU General Public License version 3.
|
2016-05-04 19:24:41 +02:00
|
|
|
*****************************************************************************/
|
2014-05-08 22:48:31 +02:00
|
|
|
|
2018-08-12 13:50:40 +02:00
|
|
|
#include <algorithm>
|
2018-11-21 23:16:04 +01:00
|
|
|
#include <iterator>
|
2018-05-16 22:22:17 +02:00
|
|
|
#include <limits>
|
2018-06-22 23:21:44 +02:00
|
|
|
#include <openrct2-ui/interface/Widget.h>
|
2017-10-07 01:28:00 +02:00
|
|
|
#include <openrct2-ui/windows/Window.h>
|
2018-06-22 23:21:44 +02:00
|
|
|
#include <openrct2/Context.h>
|
|
|
|
#include <openrct2/Game.h>
|
|
|
|
#include <openrct2/OpenRCT2.h>
|
|
|
|
#include <openrct2/audio/audio.h>
|
2017-10-07 01:28:00 +02:00
|
|
|
#include <openrct2/config/Config.h>
|
2017-12-07 16:12:37 +01:00
|
|
|
#include <openrct2/core/String.hpp>
|
2018-01-06 18:32:25 +01:00
|
|
|
#include <openrct2/localisation/Localisation.h>
|
2017-10-11 21:38:26 +02:00
|
|
|
#include <openrct2/management/NewsItem.h>
|
2018-01-04 16:43:55 +01:00
|
|
|
#include <openrct2/management/Research.h>
|
2018-06-22 23:21:44 +02:00
|
|
|
#include <openrct2/network/network.h>
|
2018-01-02 20:36:42 +01:00
|
|
|
#include <openrct2/object/ObjectLimits.h>
|
2020-03-20 18:07:31 +01:00
|
|
|
#include <openrct2/object/ObjectManager.h>
|
2018-01-09 10:40:42 +01:00
|
|
|
#include <openrct2/rct1/RCT1.h>
|
2018-01-10 00:00:09 +01:00
|
|
|
#include <openrct2/ride/RideData.h>
|
2017-10-16 12:02:23 +02:00
|
|
|
#include <openrct2/ride/TrackData.h>
|
2018-06-22 23:21:44 +02:00
|
|
|
#include <openrct2/ride/TrackDesignRepository.h>
|
2017-10-07 01:28:00 +02:00
|
|
|
#include <openrct2/sprites.h>
|
2017-12-13 13:02:24 +01:00
|
|
|
#include <openrct2/util/Util.h>
|
2017-10-21 16:37:30 +02:00
|
|
|
#include <openrct2/windows/Intent.h>
|
2018-03-19 23:28:40 +01:00
|
|
|
#include <openrct2/world/Park.h>
|
2014-05-08 22:48:31 +02:00
|
|
|
|
2020-05-05 22:26:14 +02:00
|
|
|
static constexpr const rct_string_id WINDOW_TITLE = STR_NONE;
|
2019-10-24 05:38:13 +02:00
|
|
|
constexpr size_t AVAILABILITY_STRING_SIZE = 256;
|
2020-05-09 17:05:01 +02:00
|
|
|
static constexpr const int32_t WH = 382;
|
|
|
|
static constexpr const int32_t WW = 601;
|
2017-11-20 14:25:07 +01:00
|
|
|
|
2018-06-20 17:28:51 +02:00
|
|
|
static uint8_t _windowNewRideCurrentTab;
|
2020-04-27 16:26:35 +02:00
|
|
|
static RideSelection _windowNewRideHighlightedItem[6];
|
|
|
|
static RideSelection _windowNewRideListItems[384];
|
2014-08-19 22:33:05 +02:00
|
|
|
|
2014-08-20 08:50:01 +02:00
|
|
|
#pragma region Ride type view order
|
2014-08-20 01:05:40 +02:00
|
|
|
|
2018-05-16 20:41:29 +02:00
|
|
|
// clang-format off
|
2014-08-20 08:50:01 +02:00
|
|
|
/**
|
|
|
|
* The order of ride types shown in the new ride window so that the order stays consistent across games and rides of the same
|
|
|
|
* type are kept together.
|
|
|
|
*/
|
2018-01-11 14:50:31 +01:00
|
|
|
static constexpr const char RideTypeViewOrder[] = {
|
2017-06-06 23:24:18 +02:00
|
|
|
// Transport rides
|
|
|
|
RIDE_TYPE_MINIATURE_RAILWAY,
|
|
|
|
RIDE_TYPE_MONORAIL,
|
|
|
|
RIDE_TYPE_SUSPENDED_MONORAIL,
|
|
|
|
RIDE_TYPE_CHAIRLIFT,
|
|
|
|
RIDE_TYPE_LIFT,
|
|
|
|
|
|
|
|
// Roller Coasters
|
|
|
|
RIDE_TYPE_SIDE_FRICTION_ROLLER_COASTER,
|
|
|
|
RIDE_TYPE_VIRGINIA_REEL,
|
|
|
|
RIDE_TYPE_REVERSER_ROLLER_COASTER,
|
|
|
|
RIDE_TYPE_WOODEN_ROLLER_COASTER,
|
|
|
|
RIDE_TYPE_WOODEN_WILD_MOUSE,
|
2017-12-08 07:59:44 +01:00
|
|
|
RIDE_TYPE_STEEL_WILD_MOUSE,
|
2020-06-20 02:32:52 +02:00
|
|
|
RIDE_TYPE_SPINNING_WILD_MOUSE,
|
2017-06-06 23:24:18 +02:00
|
|
|
RIDE_TYPE_INVERTED_HAIRPIN_COASTER,
|
|
|
|
RIDE_TYPE_JUNIOR_ROLLER_COASTER,
|
2020-06-20 02:32:52 +02:00
|
|
|
RIDE_TYPE_CLASSIC_MINI_ROLLER_COASTER,
|
2017-06-06 23:24:18 +02:00
|
|
|
RIDE_TYPE_MINI_ROLLER_COASTER,
|
|
|
|
RIDE_TYPE_SPIRAL_ROLLER_COASTER,
|
|
|
|
RIDE_TYPE_MINE_TRAIN_COASTER,
|
|
|
|
RIDE_TYPE_LOOPING_ROLLER_COASTER,
|
|
|
|
RIDE_TYPE_STAND_UP_ROLLER_COASTER,
|
|
|
|
RIDE_TYPE_CORKSCREW_ROLLER_COASTER,
|
2020-06-20 02:32:52 +02:00
|
|
|
RIDE_TYPE_HYPERCOASTER,
|
2017-06-06 23:24:18 +02:00
|
|
|
RIDE_TYPE_LIM_LAUNCHED_ROLLER_COASTER,
|
|
|
|
RIDE_TYPE_TWISTER_ROLLER_COASTER,
|
2020-06-20 02:32:52 +02:00
|
|
|
RIDE_TYPE_HYPER_TWISTER,
|
2017-06-06 23:24:18 +02:00
|
|
|
RIDE_TYPE_GIGA_COASTER,
|
|
|
|
RIDE_TYPE_SUSPENDED_SWINGING_COASTER,
|
|
|
|
RIDE_TYPE_COMPACT_INVERTED_COASTER,
|
|
|
|
RIDE_TYPE_INVERTED_ROLLER_COASTER,
|
|
|
|
RIDE_TYPE_INVERTED_IMPULSE_COASTER,
|
|
|
|
RIDE_TYPE_MINI_SUSPENDED_COASTER,
|
|
|
|
RIDE_TYPE_STEEPLECHASE,
|
|
|
|
RIDE_TYPE_BOBSLEIGH_COASTER,
|
|
|
|
RIDE_TYPE_MINE_RIDE,
|
|
|
|
RIDE_TYPE_HEARTLINE_TWISTER_COASTER,
|
|
|
|
RIDE_TYPE_LAY_DOWN_ROLLER_COASTER,
|
|
|
|
RIDE_TYPE_FLYING_ROLLER_COASTER,
|
|
|
|
RIDE_TYPE_MULTI_DIMENSION_ROLLER_COASTER,
|
|
|
|
RIDE_TYPE_REVERSE_FREEFALL_COASTER,
|
|
|
|
RIDE_TYPE_VERTICAL_DROP_ROLLER_COASTER,
|
|
|
|
RIDE_TYPE_AIR_POWERED_VERTICAL_COASTER,
|
2020-10-10 21:27:12 +02:00
|
|
|
RIDE_TYPE_HYBRID_COASTER,
|
2021-01-06 21:10:15 +01:00
|
|
|
RIDE_TYPE_SINGLE_RAIL_ROLLER_COASTER,
|
2017-06-06 23:24:18 +02:00
|
|
|
|
|
|
|
// Gentle rides
|
|
|
|
RIDE_TYPE_MONORAIL_CYCLES,
|
|
|
|
RIDE_TYPE_CROOKED_HOUSE,
|
|
|
|
RIDE_TYPE_HAUNTED_HOUSE,
|
|
|
|
RIDE_TYPE_FERRIS_WHEEL,
|
|
|
|
RIDE_TYPE_MAZE,
|
|
|
|
RIDE_TYPE_MERRY_GO_ROUND,
|
|
|
|
RIDE_TYPE_MINI_GOLF,
|
|
|
|
RIDE_TYPE_OBSERVATION_TOWER,
|
|
|
|
RIDE_TYPE_CAR_RIDE,
|
2020-06-20 02:32:52 +02:00
|
|
|
RIDE_TYPE_MONSTER_TRUCKS,
|
2017-06-06 23:24:18 +02:00
|
|
|
RIDE_TYPE_MINI_HELICOPTERS,
|
|
|
|
RIDE_TYPE_SPIRAL_SLIDE,
|
|
|
|
RIDE_TYPE_DODGEMS,
|
|
|
|
RIDE_TYPE_SPACE_RINGS,
|
2017-12-08 07:59:44 +01:00
|
|
|
RIDE_TYPE_CIRCUS,
|
2017-06-06 23:24:18 +02:00
|
|
|
RIDE_TYPE_GHOST_TRAIN,
|
|
|
|
RIDE_TYPE_FLYING_SAUCERS,
|
|
|
|
|
|
|
|
// Thrill rides
|
|
|
|
RIDE_TYPE_TWIST,
|
|
|
|
RIDE_TYPE_MAGIC_CARPET,
|
|
|
|
RIDE_TYPE_LAUNCHED_FREEFALL,
|
2017-12-08 07:59:44 +01:00
|
|
|
RIDE_TYPE_SWINGING_SHIP,
|
2017-06-06 23:24:18 +02:00
|
|
|
RIDE_TYPE_GO_KARTS,
|
|
|
|
RIDE_TYPE_SWINGING_INVERTER_SHIP,
|
|
|
|
RIDE_TYPE_MOTION_SIMULATOR,
|
|
|
|
RIDE_TYPE_3D_CINEMA,
|
|
|
|
RIDE_TYPE_TOP_SPIN,
|
|
|
|
RIDE_TYPE_ROTO_DROP,
|
|
|
|
RIDE_TYPE_ENTERPRISE,
|
|
|
|
|
|
|
|
// Water rides
|
|
|
|
RIDE_TYPE_DINGHY_SLIDE,
|
|
|
|
RIDE_TYPE_LOG_FLUME,
|
|
|
|
RIDE_TYPE_RIVER_RAPIDS,
|
|
|
|
RIDE_TYPE_SPLASH_BOATS,
|
|
|
|
RIDE_TYPE_SUBMARINE_RIDE,
|
2017-12-05 10:23:36 +01:00
|
|
|
RIDE_TYPE_BOAT_HIRE,
|
2017-06-06 23:24:18 +02:00
|
|
|
RIDE_TYPE_RIVER_RAFTS,
|
|
|
|
RIDE_TYPE_WATER_COASTER,
|
|
|
|
|
|
|
|
// Shops / stalls
|
|
|
|
RIDE_TYPE_FOOD_STALL,
|
|
|
|
RIDE_TYPE_1D,
|
|
|
|
RIDE_TYPE_DRINK_STALL,
|
|
|
|
RIDE_TYPE_1F,
|
|
|
|
RIDE_TYPE_SHOP,
|
|
|
|
RIDE_TYPE_22,
|
|
|
|
RIDE_TYPE_INFORMATION_KIOSK,
|
|
|
|
RIDE_TYPE_FIRST_AID,
|
|
|
|
RIDE_TYPE_CASH_MACHINE,
|
|
|
|
RIDE_TYPE_TOILETS
|
2014-08-20 01:05:40 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
#pragma endregion
|
|
|
|
|
2014-05-08 22:48:31 +02:00
|
|
|
enum {
|
2017-06-06 23:24:18 +02:00
|
|
|
WINDOW_NEW_RIDE_PAGE_TRANSPORT,
|
|
|
|
WINDOW_NEW_RIDE_PAGE_GENTLE,
|
|
|
|
WINDOW_NEW_RIDE_PAGE_ROLLER_COASTER,
|
|
|
|
WINDOW_NEW_RIDE_PAGE_THRILL,
|
|
|
|
WINDOW_NEW_RIDE_PAGE_WATER,
|
|
|
|
WINDOW_NEW_RIDE_PAGE_SHOP,
|
|
|
|
WINDOW_NEW_RIDE_PAGE_RESEARCH,
|
|
|
|
WINDOW_NEW_RIDE_PAGE_COUNT
|
2014-08-19 22:33:05 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
#pragma region Widgets
|
2014-05-08 22:48:31 +02:00
|
|
|
|
2014-08-18 00:57:41 +02:00
|
|
|
enum {
|
2017-06-06 23:24:18 +02:00
|
|
|
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_RIDE_LIST,
|
|
|
|
|
|
|
|
WIDX_CURRENTLY_IN_DEVELOPMENT_GROUP,
|
|
|
|
WIDX_LAST_DEVELOPMENT_GROUP,
|
|
|
|
WIDX_LAST_DEVELOPMENT_BUTTON,
|
|
|
|
WIDX_RESEARCH_FUNDING_BUTTON
|
2014-08-19 22:33:05 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
static rct_widget window_new_ride_widgets[] = {
|
2020-05-09 16:44:21 +02:00
|
|
|
WINDOW_SHIM(WINDOW_TITLE, WW, WH),
|
2020-11-27 04:14:20 +01:00
|
|
|
MakeWidget({ 0, 43}, {601, 339}, WindowWidgetType::Resize, WindowColour::Secondary ),
|
2020-08-29 04:31:31 +02:00
|
|
|
MakeTab ({ 3, 17}, STR_TRANSPORT_RIDES_TIP ),
|
|
|
|
MakeTab ({ 34, 17}, STR_GENTLE_RIDES_TIP ),
|
|
|
|
MakeTab ({ 65, 17}, STR_ROLLER_COASTERS_TIP ),
|
|
|
|
MakeTab ({ 96, 17}, STR_THRILL_RIDES_TIP ),
|
|
|
|
MakeTab ({127, 17}, STR_WATER_RIDES_TIP ),
|
|
|
|
MakeTab ({158, 17}, STR_SHOPS_STALLS_TIP ),
|
|
|
|
MakeTab ({189, 17}, STR_RESEARCH_AND_DEVELOPMENT_TIP),
|
2020-11-27 04:14:20 +01:00
|
|
|
MakeWidget({ 3, 46}, {595, 272}, WindowWidgetType::Scroll, WindowColour::Secondary, SCROLL_VERTICAL ),
|
|
|
|
MakeWidget({ 3, 47}, {290, 70}, WindowWidgetType::Groupbox, WindowColour::Tertiary , STR_CURRENTLY_IN_DEVELOPMENT ),
|
|
|
|
MakeWidget({ 3, 124}, {290, 65}, WindowWidgetType::Groupbox, WindowColour::Tertiary , STR_LAST_DEVELOPMENT ),
|
|
|
|
MakeWidget({265, 161}, { 24, 24}, WindowWidgetType::FlatBtn, WindowColour::Tertiary , 0xFFFFFFFF, STR_RESEARCH_SHOW_DETAILS_TIP ),
|
|
|
|
MakeWidget({265, 68}, { 24, 24}, WindowWidgetType::FlatBtn, WindowColour::Tertiary , SPR_FINANCE, STR_FINANCES_RESEARCH_TIP ),
|
2017-06-06 23:24:18 +02:00
|
|
|
{ WIDGETS_END },
|
2014-08-18 00:57:41 +02:00
|
|
|
};
|
|
|
|
|
2014-08-19 22:33:05 +02:00
|
|
|
#pragma endregion
|
|
|
|
|
|
|
|
#pragma region Events
|
|
|
|
|
2017-05-01 15:41:45 +02:00
|
|
|
static void window_new_ride_mouseup(rct_window *w, rct_widgetindex widgetIndex);
|
2017-07-03 23:09:46 +02:00
|
|
|
static void window_new_ride_mousedown(rct_window *w, rct_widgetindex widgetIndex, rct_widget *widget);
|
2014-08-19 22:33:05 +02:00
|
|
|
static void window_new_ride_update(rct_window *w);
|
2018-06-20 17:28:51 +02:00
|
|
|
static void window_new_ride_scrollgetsize(rct_window *w, int32_t scrollIndex, int32_t *width, int32_t *height);
|
2020-02-29 03:43:29 +01:00
|
|
|
static void window_new_ride_scrollmousedown(rct_window *w, int32_t scrollIndex, const ScreenCoordsXY& screenCoords);
|
|
|
|
static void window_new_ride_scrollmouseover(rct_window *w, int32_t scrollIndex, const ScreenCoordsXY& screenCoords);
|
2015-07-10 02:39:16 +02:00
|
|
|
static void window_new_ride_invalidate(rct_window *w);
|
|
|
|
static void window_new_ride_paint(rct_window *w, rct_drawpixelinfo *dpi);
|
2018-06-20 17:28:51 +02:00
|
|
|
static void window_new_ride_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, int32_t scrollIndex);
|
2020-03-20 18:07:31 +01:00
|
|
|
static void window_new_ride_list_vehicles_for(uint8_t rideType, const rct_ride_entry* rideEntry, char* buffer, size_t bufferLen);
|
2014-08-19 22:33:05 +02:00
|
|
|
|
|
|
|
// 0x0098E354
|
2020-09-28 20:36:15 +02:00
|
|
|
static rct_window_event_list window_new_ride_events([](auto& events)
|
|
|
|
{
|
|
|
|
events.mouse_up = &window_new_ride_mouseup;
|
|
|
|
events.mouse_down = &window_new_ride_mousedown;
|
|
|
|
events.update = &window_new_ride_update;
|
|
|
|
events.get_scroll_size = &window_new_ride_scrollgetsize;
|
|
|
|
events.scroll_mousedown = &window_new_ride_scrollmousedown;
|
|
|
|
events.scroll_mouseover = &window_new_ride_scrollmouseover;
|
|
|
|
events.invalidate = &window_new_ride_invalidate;
|
|
|
|
events.paint = &window_new_ride_paint;
|
|
|
|
events.scroll_paint = &window_new_ride_scrollpaint;
|
|
|
|
});
|
2014-08-19 22:33:05 +02:00
|
|
|
|
|
|
|
#pragma endregion
|
|
|
|
|
2018-01-11 14:50:31 +01:00
|
|
|
static constexpr const rct_string_id window_new_ride_titles[WINDOW_NEW_RIDE_PAGE_COUNT] = {
|
2017-06-06 23:24:18 +02:00
|
|
|
STR_NEW_TRANSPORT_RIDES,
|
|
|
|
STR_NEW_GENTLE_RIDES,
|
|
|
|
STR_NEW_ROLLER_COASTERS,
|
|
|
|
STR_NEW_THRILL_RIDES,
|
|
|
|
STR_NEW_WATER_RIDES,
|
|
|
|
STR_NEW_SHOPS_STALLS,
|
|
|
|
STR_RESEARCH_AND_DEVELOPMENT,
|
2016-07-14 14:07:49 +02:00
|
|
|
};
|
|
|
|
|
2018-06-20 17:28:51 +02:00
|
|
|
static constexpr const int32_t window_new_ride_tab_animation_loops[] = { 20, 32, 10, 72, 24, 28, 16 };
|
|
|
|
static constexpr const int32_t window_new_ride_tab_animation_divisor[] = { 4, 8, 2, 4, 4, 4, 2 };
|
2018-05-16 20:41:29 +02:00
|
|
|
// clang-format on
|
2014-08-19 22:33:05 +02:00
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
static void window_new_ride_set_page(rct_window* w, int32_t page);
|
|
|
|
static void window_new_ride_refresh_widget_sizing(rct_window* w);
|
2020-04-27 16:26:35 +02:00
|
|
|
static RideSelection window_new_ride_scroll_get_ride_list_item_at(rct_window* w, const ScreenCoordsXY& screenCoords);
|
2018-06-22 23:21:44 +02:00
|
|
|
static void window_new_ride_paint_ride_information(
|
2020-06-11 15:11:12 +02:00
|
|
|
rct_window* w, rct_drawpixelinfo* dpi, RideSelection item, const ScreenCoordsXY& screenPos, int32_t width);
|
2018-06-22 23:21:44 +02:00
|
|
|
static void window_new_ride_select(rct_window* w);
|
2020-06-20 02:32:52 +02:00
|
|
|
static RideSelection* window_new_ride_iterate_over_ride_type(uint8_t rideType, RideSelection* nextListItem);
|
2014-08-19 22:33:05 +02:00
|
|
|
|
2020-04-27 16:26:35 +02:00
|
|
|
static RideSelection _lastTrackDesignCountRideType;
|
2018-06-20 17:28:51 +02:00
|
|
|
static int32_t _lastTrackDesignCount;
|
2014-08-21 22:48:23 +02:00
|
|
|
|
2014-05-08 22:48:31 +02:00
|
|
|
/**
|
2018-06-22 23:21:44 +02:00
|
|
|
*
|
|
|
|
* rct2: 0x006ACA58
|
|
|
|
*/
|
2016-09-06 00:20:08 +02:00
|
|
|
void window_new_ride_init_vars()
|
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
// If we are in the track designer, default to the Roller Coaster tab
|
2018-06-22 23:21:44 +02:00
|
|
|
if (gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER)
|
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
_windowNewRideCurrentTab = WINDOW_NEW_RIDE_PAGE_ROLLER_COASTER;
|
2018-06-22 23:21:44 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
_windowNewRideCurrentTab = WINDOW_NEW_RIDE_PAGE_TRANSPORT;
|
|
|
|
}
|
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
for (int16_t i = 0; i < 6; i++)
|
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
/*
|
|
|
|
Reset what is highlighted in each tab.
|
|
|
|
Each 16bit number represents the item in its respective tab.
|
|
|
|
*/
|
2017-08-06 02:26:14 +02:00
|
|
|
_windowNewRideHighlightedItem[i] = { 255, 255 };
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
2014-08-18 00:57:41 +02:00
|
|
|
}
|
|
|
|
|
2014-08-20 01:05:40 +02:00
|
|
|
/**
|
2017-06-06 23:24:18 +02:00
|
|
|
* rct2: 0x006B6F3E
|
2014-08-20 01:05:40 +02:00
|
|
|
*
|
2018-06-22 23:21:44 +02:00
|
|
|
* Note: When the user has selection by track type enabled, the categories are determined by the track type, not those in the
|
|
|
|
* rct_ride_entry.
|
2014-08-20 01:05:40 +02:00
|
|
|
*/
|
|
|
|
static void window_new_ride_populate_list()
|
|
|
|
{
|
2018-06-20 17:28:51 +02:00
|
|
|
uint8_t currentCategory = _windowNewRideCurrentTab;
|
2020-04-27 16:26:35 +02:00
|
|
|
RideSelection* nextListItem = _windowNewRideListItems;
|
2017-06-06 23:24:18 +02:00
|
|
|
|
|
|
|
// For each ride type in the view order list
|
2020-04-18 13:32:48 +02:00
|
|
|
for (int32_t i = 0; i < static_cast<int32_t>(std::size(RideTypeViewOrder)); i++)
|
2018-06-22 23:21:44 +02:00
|
|
|
{
|
2018-06-20 17:28:51 +02:00
|
|
|
uint8_t rideType = RideTypeViewOrder[i];
|
2017-06-06 23:24:18 +02:00
|
|
|
if (rideType == RIDE_TYPE_NULL)
|
|
|
|
continue;
|
|
|
|
|
2020-04-18 15:19:45 +02:00
|
|
|
if (RideTypeDescriptors[rideType].Category != currentCategory)
|
2017-12-07 16:12:37 +01:00
|
|
|
continue;
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2020-06-20 02:32:52 +02:00
|
|
|
nextListItem = window_new_ride_iterate_over_ride_type(rideType, nextListItem);
|
2017-06-14 13:31:27 +02:00
|
|
|
}
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2020-04-27 16:26:35 +02:00
|
|
|
nextListItem->Type = RIDE_TYPE_NULL;
|
|
|
|
nextListItem->EntryIndex = RIDE_ENTRY_INDEX_NULL;
|
2017-06-14 13:31:27 +02:00
|
|
|
}
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2020-06-20 02:32:52 +02:00
|
|
|
static RideSelection* window_new_ride_iterate_over_ride_type(uint8_t rideType, RideSelection* nextListItem)
|
2017-06-14 13:31:27 +02:00
|
|
|
{
|
|
|
|
bool buttonForRideTypeCreated = false;
|
|
|
|
bool allowDrawingOverLastButton = false;
|
|
|
|
|
2020-06-17 20:01:22 +02:00
|
|
|
uint8_t highestVehiclePriority = 0;
|
2017-06-14 13:31:27 +02:00
|
|
|
|
|
|
|
// For each ride entry for this ride type
|
2020-03-20 18:07:31 +01:00
|
|
|
auto& objManager = OpenRCT2::GetContext()->GetObjectManager();
|
|
|
|
auto& rideEntries = objManager.GetAllRideEntries(rideType);
|
|
|
|
for (auto rideEntryIndex : rideEntries)
|
2017-12-07 16:12:37 +01:00
|
|
|
{
|
2017-06-14 13:31:27 +02:00
|
|
|
// Skip if vehicle type is not invented yet
|
2017-07-23 12:09:29 +02:00
|
|
|
if (!ride_entry_is_invented(rideEntryIndex) && !gCheatsIgnoreResearchStatus)
|
2017-06-14 13:31:27 +02:00
|
|
|
continue;
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2017-06-14 13:31:27 +02:00
|
|
|
// Ride entries
|
2018-06-22 23:21:44 +02:00
|
|
|
rct_ride_entry* rideEntry = get_ride_entry(rideEntryIndex);
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2017-06-14 13:31:27 +02:00
|
|
|
// Skip if the vehicle isn't the preferred vehicle for this generic track type
|
2020-06-17 20:01:22 +02:00
|
|
|
if (!RideTypeDescriptors[rideType].HasFlag(RIDE_TYPE_FLAG_LIST_VEHICLES_SEPARATELY)
|
|
|
|
&& highestVehiclePriority > rideEntry->BuildMenuPriority)
|
2017-11-20 14:25:07 +01:00
|
|
|
{
|
2020-06-17 20:01:22 +02:00
|
|
|
continue;
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
2020-06-17 20:01:22 +02:00
|
|
|
highestVehiclePriority = rideEntry->BuildMenuPriority;
|
2017-06-14 13:31:27 +02:00
|
|
|
|
|
|
|
// Determines how and where to draw a button for this ride type/vehicle.
|
2020-04-18 15:19:45 +02:00
|
|
|
if (RideTypeDescriptors[rideType].HasFlag(RIDE_TYPE_FLAG_LIST_VEHICLES_SEPARATELY))
|
2017-12-07 16:12:37 +01:00
|
|
|
{
|
|
|
|
// Separate, draw apart
|
2017-06-14 13:31:27 +02:00
|
|
|
allowDrawingOverLastButton = false;
|
2020-04-27 16:26:35 +02:00
|
|
|
nextListItem->Type = rideType;
|
|
|
|
nextListItem->EntryIndex = rideEntryIndex;
|
2017-06-14 13:31:27 +02:00
|
|
|
nextListItem++;
|
2017-12-07 16:12:37 +01:00
|
|
|
}
|
|
|
|
else if (!buttonForRideTypeCreated)
|
|
|
|
{
|
|
|
|
// Non-separate, draw-apart
|
2017-06-14 13:31:27 +02:00
|
|
|
buttonForRideTypeCreated = true;
|
|
|
|
allowDrawingOverLastButton = true;
|
2020-04-27 16:26:35 +02:00
|
|
|
nextListItem->Type = rideType;
|
|
|
|
nextListItem->EntryIndex = rideEntryIndex;
|
2017-06-14 13:31:27 +02:00
|
|
|
nextListItem++;
|
2017-12-07 16:12:37 +01:00
|
|
|
}
|
|
|
|
else if (allowDrawingOverLastButton)
|
|
|
|
{
|
|
|
|
// Non-separate, draw over previous
|
|
|
|
if (rideType == rideEntry->ride_type[0])
|
|
|
|
{
|
2017-06-14 13:31:27 +02:00
|
|
|
nextListItem--;
|
2020-04-27 16:26:35 +02:00
|
|
|
nextListItem->Type = rideType;
|
|
|
|
nextListItem->EntryIndex = rideEntryIndex;
|
2017-06-14 13:31:27 +02:00
|
|
|
nextListItem++;
|
|
|
|
}
|
|
|
|
}
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
|
|
|
|
2017-06-14 13:31:27 +02:00
|
|
|
return nextListItem;
|
2014-08-20 01:05:40 +02:00
|
|
|
}
|
|
|
|
|
2014-08-20 21:18:17 +02:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006B7220
|
|
|
|
*/
|
2018-06-22 23:21:44 +02:00
|
|
|
static void window_new_ride_scroll_to_focused_ride(rct_window* w)
|
2014-08-20 21:18:17 +02:00
|
|
|
{
|
2018-06-20 17:28:51 +02:00
|
|
|
int32_t scrollWidth = 0;
|
|
|
|
int32_t scrollHeight = 0;
|
2017-06-06 23:24:18 +02:00
|
|
|
window_get_scroll_size(w, 0, &scrollWidth, &scrollHeight);
|
|
|
|
|
|
|
|
// Find row index of the focused ride type
|
2018-06-22 23:21:44 +02:00
|
|
|
rct_widget* listWidget = &window_new_ride_widgets[WIDX_RIDE_LIST];
|
2018-11-21 23:16:04 +01:00
|
|
|
assert(_windowNewRideCurrentTab < std::size(_windowNewRideHighlightedItem));
|
2020-04-27 16:26:35 +02:00
|
|
|
auto focusRideType = _windowNewRideHighlightedItem[_windowNewRideCurrentTab];
|
2018-06-20 17:28:51 +02:00
|
|
|
int32_t count = 0, row = 0;
|
2020-04-27 16:26:35 +02:00
|
|
|
RideSelection* listItem = _windowNewRideListItems;
|
|
|
|
while (listItem->Type != RIDE_TYPE_NULL || listItem->EntryIndex != RIDE_ENTRY_INDEX_NULL)
|
2018-06-22 23:21:44 +02:00
|
|
|
{
|
2020-04-27 16:26:35 +02:00
|
|
|
if (listItem->Type == focusRideType.Type)
|
2018-06-22 23:21:44 +02:00
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
row = count / 5;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
count++;
|
|
|
|
listItem++;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Update the Y scroll position
|
2018-06-20 17:28:51 +02:00
|
|
|
int32_t listWidgetHeight = listWidget->bottom - listWidget->top - 1;
|
2018-06-20 17:11:35 +02:00
|
|
|
scrollHeight = std::max(0, scrollHeight - listWidgetHeight);
|
|
|
|
w->scrolls[0].v_top = std::min(row * 116, scrollHeight);
|
2020-11-03 22:29:22 +01:00
|
|
|
WidgetScrollUpdateThumbs(w, WIDX_RIDE_LIST);
|
2014-08-20 21:18:17 +02:00
|
|
|
}
|
|
|
|
|
2014-08-18 00:57:41 +02:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006B3CFF
|
|
|
|
*/
|
2018-06-22 23:21:44 +02:00
|
|
|
rct_window* window_new_ride_open()
|
2014-08-18 00:57:41 +02:00
|
|
|
{
|
2018-06-22 23:21:44 +02:00
|
|
|
rct_window* w;
|
2017-06-06 23:24:18 +02:00
|
|
|
|
|
|
|
w = window_bring_to_front_by_class(WC_CONSTRUCT_RIDE);
|
2017-08-15 10:07:44 +02:00
|
|
|
if (w != nullptr)
|
2017-06-06 23:24:18 +02:00
|
|
|
return w;
|
|
|
|
|
|
|
|
// Not sure what these windows are
|
|
|
|
window_close_by_class(WC_TRACK_DESIGN_LIST);
|
|
|
|
window_close_by_class(WC_TRACK_DESIGN_PLACE);
|
|
|
|
|
2020-11-04 05:52:23 +01:00
|
|
|
w = WindowCreateAutoPos(WW, WH, &window_new_ride_events, WC_CONSTRUCT_RIDE, WF_10);
|
2017-06-06 23:24:18 +02:00
|
|
|
w->widgets = window_new_ride_widgets;
|
2018-06-22 23:21:44 +02:00
|
|
|
w->enabled_widgets = (1 << WIDX_CLOSE) | (1 << WIDX_TAB_1) | (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_LAST_DEVELOPMENT_BUTTON)
|
|
|
|
| (1 << WIDX_RESEARCH_FUNDING_BUTTON);
|
2017-06-06 23:24:18 +02:00
|
|
|
window_new_ride_populate_list();
|
2020-11-04 05:52:23 +01:00
|
|
|
WindowInitScrollWidgets(w);
|
2017-06-06 23:24:18 +02:00
|
|
|
|
|
|
|
w->frame_no = 0;
|
2020-04-27 16:26:35 +02:00
|
|
|
w->new_ride.SelectedRide = { RIDE_TYPE_NULL, RIDE_ENTRY_INDEX_NULL };
|
|
|
|
_lastTrackDesignCountRideType.Type = RIDE_TYPE_NULL;
|
|
|
|
_lastTrackDesignCountRideType.EntryIndex = RIDE_ENTRY_INDEX_NULL;
|
|
|
|
w->new_ride.HighlightedRide = _windowNewRideHighlightedItem[_windowNewRideCurrentTab];
|
|
|
|
if (w->new_ride.HighlightedRide.Type == RIDE_TYPE_NULL)
|
|
|
|
w->new_ride.HighlightedRide = _windowNewRideListItems[0];
|
2017-06-06 23:24:18 +02:00
|
|
|
|
|
|
|
w->width = 1;
|
|
|
|
window_new_ride_refresh_widget_sizing(w);
|
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
if (_windowNewRideCurrentTab != WINDOW_NEW_RIDE_PAGE_RESEARCH)
|
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
window_new_ride_scroll_to_focused_ride(w);
|
|
|
|
}
|
|
|
|
|
|
|
|
return w;
|
2015-03-31 03:21:30 +02:00
|
|
|
}
|
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
rct_window* window_new_ride_open_research()
|
2015-03-31 03:21:30 +02:00
|
|
|
{
|
2018-06-22 23:21:44 +02:00
|
|
|
rct_window* w;
|
2015-10-20 20:16:30 +02:00
|
|
|
|
2017-06-06 23:24:18 +02:00
|
|
|
w = window_new_ride_open();
|
|
|
|
window_new_ride_set_page(w, WINDOW_NEW_RIDE_PAGE_RESEARCH);
|
|
|
|
return w;
|
2014-08-19 22:33:05 +02:00
|
|
|
}
|
|
|
|
|
2014-10-08 23:11:50 +02:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006B3EBA
|
|
|
|
*/
|
2020-04-27 16:26:35 +02:00
|
|
|
void window_new_ride_focus(RideSelection rideItem)
|
2014-10-08 23:11:50 +02:00
|
|
|
{
|
2018-06-22 23:21:44 +02:00
|
|
|
rct_window* w;
|
|
|
|
rct_ride_entry* rideEntry;
|
2017-06-14 13:31:27 +02:00
|
|
|
bool entryFound = false;
|
|
|
|
// Find the first non-null ride type index.
|
2017-06-06 23:24:18 +02:00
|
|
|
|
|
|
|
w = window_find_by_class(WC_CONSTRUCT_RIDE);
|
2017-08-15 10:07:44 +02:00
|
|
|
if (w == nullptr)
|
2017-06-06 23:24:18 +02:00
|
|
|
return;
|
|
|
|
|
2020-04-27 16:26:35 +02:00
|
|
|
rideEntry = get_ride_entry(rideItem.EntryIndex);
|
2018-06-20 17:28:51 +02:00
|
|
|
uint8_t rideTypeIndex = ride_entry_get_first_non_null_ride_type(rideEntry);
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2020-04-18 15:19:45 +02:00
|
|
|
window_new_ride_set_page(w, RideTypeDescriptors[rideTypeIndex].Category);
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2020-04-27 16:26:35 +02:00
|
|
|
for (RideSelection* listItem = _windowNewRideListItems; listItem->Type != RIDE_TYPE_NULL; listItem++)
|
2018-06-22 23:21:44 +02:00
|
|
|
{
|
2020-04-27 16:26:35 +02:00
|
|
|
if (listItem->Type == rideItem.Type && listItem->EntryIndex == rideItem.EntryIndex)
|
2018-06-22 23:21:44 +02:00
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
_windowNewRideHighlightedItem[0] = rideItem;
|
2020-04-27 16:26:35 +02:00
|
|
|
w->new_ride.HighlightedRide = rideItem;
|
2017-06-06 23:24:18 +02:00
|
|
|
window_new_ride_scroll_to_focused_ride(w);
|
2017-06-14 13:31:27 +02:00
|
|
|
entryFound = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// If this entry was not found it was most likely hidden due to it not being the preferential type.
|
|
|
|
// In this case, select the first entry that belongs to the same ride group.
|
2017-12-07 16:12:37 +01:00
|
|
|
if (!entryFound)
|
2017-06-14 13:31:27 +02:00
|
|
|
{
|
2020-04-27 16:26:35 +02:00
|
|
|
for (RideSelection* listItem = _windowNewRideListItems; listItem->Type != RIDE_TYPE_NULL; listItem++)
|
2018-06-22 23:21:44 +02:00
|
|
|
{
|
2020-04-27 16:26:35 +02:00
|
|
|
if (listItem->Type == rideItem.Type)
|
2018-06-22 23:21:44 +02:00
|
|
|
{
|
2020-06-20 02:32:52 +02:00
|
|
|
_windowNewRideHighlightedItem[0] = rideItem;
|
|
|
|
w->new_ride.HighlightedRide = rideItem;
|
|
|
|
window_new_ride_scroll_to_focused_ride(w);
|
|
|
|
break;
|
2017-06-14 13:31:27 +02:00
|
|
|
}
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
|
|
|
}
|
2014-10-08 23:11:50 +02:00
|
|
|
}
|
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
static void window_new_ride_set_page(rct_window* w, int32_t page)
|
2014-10-08 23:11:50 +02:00
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
_windowNewRideCurrentTab = page;
|
|
|
|
w->frame_no = 0;
|
2020-04-27 16:26:35 +02:00
|
|
|
w->new_ride.HighlightedRide = { RIDE_TYPE_NULL, RIDE_ENTRY_INDEX_NULL };
|
2018-06-20 17:28:51 +02:00
|
|
|
w->new_ride.selected_ride_countdown = std::numeric_limits<uint16_t>::max();
|
2017-06-06 23:24:18 +02:00
|
|
|
window_new_ride_populate_list();
|
2018-06-22 23:21:44 +02:00
|
|
|
if (page < WINDOW_NEW_RIDE_PAGE_RESEARCH)
|
|
|
|
{
|
2020-04-27 16:26:35 +02:00
|
|
|
w->new_ride.HighlightedRide = _windowNewRideHighlightedItem[page];
|
|
|
|
if (w->new_ride.HighlightedRide.Type == RIDE_TYPE_NULL)
|
|
|
|
w->new_ride.HighlightedRide = _windowNewRideListItems[0];
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
window_new_ride_refresh_widget_sizing(w);
|
2019-06-15 17:20:16 +02:00
|
|
|
w->Invalidate();
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
if (page < WINDOW_NEW_RIDE_PAGE_RESEARCH)
|
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
window_new_ride_scroll_to_focused_ride(w);
|
|
|
|
}
|
2014-10-08 23:11:50 +02:00
|
|
|
}
|
|
|
|
|
2014-08-19 22:33:05 +02:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006B3DF1
|
|
|
|
*/
|
2018-06-22 23:21:44 +02:00
|
|
|
static void window_new_ride_refresh_widget_sizing(rct_window* w)
|
2014-08-19 22:33:05 +02:00
|
|
|
{
|
2018-06-20 17:28:51 +02:00
|
|
|
int32_t width, height;
|
2017-06-06 23:24:18 +02:00
|
|
|
|
|
|
|
// Show or hide unrelated widgets
|
2018-06-22 23:21:44 +02:00
|
|
|
if (_windowNewRideCurrentTab != WINDOW_NEW_RIDE_PAGE_RESEARCH)
|
|
|
|
{
|
2020-11-27 04:14:20 +01:00
|
|
|
window_new_ride_widgets[WIDX_RIDE_LIST].type = WindowWidgetType::Scroll;
|
|
|
|
window_new_ride_widgets[WIDX_CURRENTLY_IN_DEVELOPMENT_GROUP].type = WindowWidgetType::Empty;
|
|
|
|
window_new_ride_widgets[WIDX_LAST_DEVELOPMENT_GROUP].type = WindowWidgetType::Empty;
|
|
|
|
window_new_ride_widgets[WIDX_LAST_DEVELOPMENT_BUTTON].type = WindowWidgetType::Empty;
|
|
|
|
window_new_ride_widgets[WIDX_RESEARCH_FUNDING_BUTTON].type = WindowWidgetType::Empty;
|
2017-06-06 23:24:18 +02:00
|
|
|
|
|
|
|
width = 601;
|
2017-11-20 14:25:07 +01:00
|
|
|
height = WH;
|
2018-06-22 23:21:44 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-11-27 04:14:20 +01:00
|
|
|
window_new_ride_widgets[WIDX_RIDE_LIST].type = WindowWidgetType::Empty;
|
|
|
|
window_new_ride_widgets[WIDX_CURRENTLY_IN_DEVELOPMENT_GROUP].type = WindowWidgetType::Groupbox;
|
|
|
|
window_new_ride_widgets[WIDX_LAST_DEVELOPMENT_GROUP].type = WindowWidgetType::Groupbox;
|
|
|
|
window_new_ride_widgets[WIDX_LAST_DEVELOPMENT_BUTTON].type = WindowWidgetType::FlatBtn;
|
2017-06-06 23:24:18 +02:00
|
|
|
if (!(gParkFlags & PARK_FLAGS_NO_MONEY))
|
2020-11-27 04:14:20 +01:00
|
|
|
window_new_ride_widgets[WIDX_RESEARCH_FUNDING_BUTTON].type = WindowWidgetType::FlatBtn;
|
2017-06-06 23:24:18 +02:00
|
|
|
|
|
|
|
width = 300;
|
|
|
|
height = 196;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Handle new window size
|
2018-06-22 23:21:44 +02:00
|
|
|
if (w->width != width || w->height != height)
|
|
|
|
{
|
2019-06-15 17:20:16 +02:00
|
|
|
w->Invalidate();
|
2017-06-06 23:24:18 +02:00
|
|
|
|
|
|
|
// Resize widgets to new window size
|
|
|
|
window_new_ride_widgets[WIDX_BACKGROUND].right = width - 1;
|
|
|
|
window_new_ride_widgets[WIDX_BACKGROUND].bottom = height - 1;
|
|
|
|
window_new_ride_widgets[WIDX_PAGE_BACKGROUND].right = width - 1;
|
|
|
|
window_new_ride_widgets[WIDX_PAGE_BACKGROUND].bottom = height - 1;
|
|
|
|
window_new_ride_widgets[WIDX_TITLE].right = width - 2;
|
2020-05-05 22:31:04 +02:00
|
|
|
window_new_ride_widgets[WIDX_CLOSE].left = width - 13;
|
|
|
|
window_new_ride_widgets[WIDX_CLOSE].right = width - 3;
|
2017-06-06 23:24:18 +02:00
|
|
|
|
|
|
|
w->width = width;
|
|
|
|
w->height = height;
|
2019-06-15 17:20:16 +02:00
|
|
|
w->Invalidate();
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
|
|
|
|
2020-11-04 05:52:23 +01:00
|
|
|
WindowInitScrollWidgets(w);
|
2014-08-19 22:33:05 +02:00
|
|
|
}
|
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
static void window_new_ride_set_pressed_tab(rct_window* w)
|
2014-08-19 22:33:05 +02:00
|
|
|
{
|
2018-06-20 17:28:51 +02:00
|
|
|
int32_t i;
|
2017-06-06 23:24:18 +02:00
|
|
|
for (i = 0; i < WINDOW_NEW_RIDE_PAGE_COUNT; i++)
|
|
|
|
w->pressed_widgets &= ~(1 << (WIDX_TAB_1 + i));
|
|
|
|
w->pressed_widgets |= 1LL << (WIDX_TAB_1 + _windowNewRideCurrentTab);
|
2014-08-19 22:33:05 +02:00
|
|
|
}
|
|
|
|
|
2018-07-21 11:50:45 +02:00
|
|
|
static constexpr const int32_t ThrillRidesTabAnimationSequence[] = { 5, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0,
|
|
|
|
0, 0, 0, 1, 2, 3, 4, 0, 0, 0 };
|
2014-08-19 22:33:05 +02:00
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
static void window_new_ride_draw_tab_image(rct_drawpixelinfo* dpi, rct_window* w, int32_t page, int32_t spriteIndex)
|
2014-08-19 22:33:05 +02:00
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
rct_widgetindex widgetIndex = WIDX_TAB_1 + page;
|
2014-08-19 22:33:05 +02:00
|
|
|
|
2020-11-27 04:14:20 +01:00
|
|
|
if (w->widgets[widgetIndex].type != WindowWidgetType::Empty && !(w->disabled_widgets & (1LL << widgetIndex)))
|
2018-06-22 23:21:44 +02:00
|
|
|
{
|
2018-06-20 17:28:51 +02:00
|
|
|
int32_t frame = 0;
|
2017-06-06 23:24:18 +02:00
|
|
|
if (_windowNewRideCurrentTab == page)
|
|
|
|
frame = w->frame_no / window_new_ride_tab_animation_divisor[page];
|
2014-08-19 22:33:05 +02:00
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
spriteIndex += page == WINDOW_NEW_RIDE_PAGE_THRILL ? ThrillRidesTabAnimationSequence[frame] : frame;
|
2014-08-19 22:33:05 +02:00
|
|
|
|
2017-06-06 23:24:18 +02:00
|
|
|
spriteIndex |= w->colours[1] << 19;
|
2014-08-19 22:33:05 +02:00
|
|
|
|
2020-03-01 20:32:35 +01:00
|
|
|
gfx_draw_sprite(
|
2020-06-24 17:48:17 +02:00
|
|
|
dpi, spriteIndex, w->windowPos + ScreenCoordsXY{ w->widgets[widgetIndex].left, w->widgets[widgetIndex].top }, 0);
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
2014-08-19 22:33:05 +02:00
|
|
|
}
|
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
static void window_new_ride_draw_tab_images(rct_drawpixelinfo* dpi, rct_window* w)
|
2014-08-19 22:33:05 +02:00
|
|
|
{
|
2017-07-20 20:56:29 +02:00
|
|
|
window_new_ride_draw_tab_image(dpi, w, WINDOW_NEW_RIDE_PAGE_TRANSPORT, IMAGE_TYPE_REMAP | SPR_TAB_RIDES_TRANSPORT_0);
|
2017-06-06 23:24:18 +02:00
|
|
|
window_new_ride_draw_tab_image(dpi, w, WINDOW_NEW_RIDE_PAGE_GENTLE, SPR_TAB_RIDES_GENTLE_0);
|
2018-06-22 23:21:44 +02:00
|
|
|
window_new_ride_draw_tab_image(
|
|
|
|
dpi, w, WINDOW_NEW_RIDE_PAGE_ROLLER_COASTER, IMAGE_TYPE_REMAP | SPR_TAB_RIDES_ROLLER_COASTERS_0);
|
2017-06-06 23:24:18 +02:00
|
|
|
window_new_ride_draw_tab_image(dpi, w, WINDOW_NEW_RIDE_PAGE_THRILL, SPR_TAB_RIDES_THRILL_0);
|
|
|
|
window_new_ride_draw_tab_image(dpi, w, WINDOW_NEW_RIDE_PAGE_WATER, SPR_TAB_RIDES_WATER_0);
|
|
|
|
window_new_ride_draw_tab_image(dpi, w, WINDOW_NEW_RIDE_PAGE_SHOP, SPR_TAB_RIDES_SHOP_0);
|
|
|
|
window_new_ride_draw_tab_image(dpi, w, WINDOW_NEW_RIDE_PAGE_RESEARCH, SPR_TAB_FINANCES_RESEARCH_0);
|
2014-08-19 22:33:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006B6B38
|
|
|
|
*/
|
2018-06-22 23:21:44 +02:00
|
|
|
static void window_new_ride_mouseup(rct_window* w, rct_widgetindex widgetIndex)
|
2014-08-19 22:33:05 +02:00
|
|
|
{
|
2018-06-22 23:21:44 +02:00
|
|
|
switch (widgetIndex)
|
|
|
|
{
|
|
|
|
case WIDX_CLOSE:
|
|
|
|
window_close(w);
|
|
|
|
break;
|
|
|
|
case WIDX_LAST_DEVELOPMENT_BUTTON:
|
2020-08-03 04:14:00 +02:00
|
|
|
News::OpenSubject(News::ItemType::Research, gResearchLastItem->rawValue);
|
2018-06-22 23:21:44 +02:00
|
|
|
break;
|
|
|
|
case WIDX_RESEARCH_FUNDING_BUTTON:
|
|
|
|
context_open_window_view(WV_FINANCES_RESEARCH);
|
|
|
|
break;
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
2014-08-19 22:33:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006B6B4F
|
|
|
|
*/
|
2018-06-22 23:21:44 +02:00
|
|
|
static void window_new_ride_mousedown(rct_window* w, rct_widgetindex widgetIndex, rct_widget* widget)
|
2014-08-19 22:33:05 +02:00
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
if (widgetIndex >= WIDX_TAB_1 && widgetIndex <= WIDX_TAB_7)
|
|
|
|
window_new_ride_set_page(w, widgetIndex - WIDX_TAB_1);
|
2014-08-19 22:33:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006B6CE7
|
|
|
|
*/
|
2018-06-22 23:21:44 +02:00
|
|
|
static void window_new_ride_update(rct_window* w)
|
2014-08-19 22:33:05 +02:00
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
w->frame_no++;
|
|
|
|
if (w->frame_no >= window_new_ride_tab_animation_loops[_windowNewRideCurrentTab])
|
|
|
|
w->frame_no = 0;
|
2014-08-19 22:33:05 +02:00
|
|
|
|
2017-06-06 23:24:18 +02:00
|
|
|
widget_invalidate(w, WIDX_TAB_1 + _windowNewRideCurrentTab);
|
2014-08-19 22:33:05 +02:00
|
|
|
|
2020-04-27 16:26:35 +02:00
|
|
|
if (w->new_ride.SelectedRide.Type != RIDE_TYPE_NULL && w->new_ride.selected_ride_countdown-- == 0)
|
2017-06-06 23:24:18 +02:00
|
|
|
window_new_ride_select(w);
|
2016-01-23 15:01:17 +01:00
|
|
|
|
2017-12-07 16:12:37 +01:00
|
|
|
window_new_ride_populate_list();
|
2018-06-22 23:21:44 +02:00
|
|
|
// widget_invalidate(w, WIDX_RIDE_LIST);
|
2014-08-19 22:33:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006B6BC9
|
|
|
|
*/
|
2018-06-22 23:21:44 +02:00
|
|
|
static void window_new_ride_scrollgetsize(rct_window* w, int32_t scrollIndex, int32_t* width, int32_t* height)
|
2014-08-19 22:33:05 +02:00
|
|
|
{
|
2020-04-27 16:26:35 +02:00
|
|
|
RideSelection* listItem = _windowNewRideListItems;
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2018-06-20 17:28:51 +02:00
|
|
|
int32_t count = 0;
|
2020-04-27 16:26:35 +02:00
|
|
|
while (listItem->Type != RIDE_TYPE_NULL || listItem->EntryIndex != RIDE_ENTRY_INDEX_NULL)
|
2018-06-22 23:21:44 +02:00
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
count++;
|
|
|
|
listItem++;
|
|
|
|
}
|
|
|
|
*height = ((count + 4) / 5) * 116;
|
2014-08-19 22:33:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006B6C89
|
|
|
|
*/
|
2020-02-29 03:43:29 +01:00
|
|
|
static void window_new_ride_scrollmousedown(rct_window* w, int32_t scrollIndex, const ScreenCoordsXY& screenCoords)
|
2014-08-19 22:33:05 +02:00
|
|
|
{
|
2020-04-27 16:26:35 +02:00
|
|
|
RideSelection item;
|
2014-08-20 23:06:47 +02:00
|
|
|
|
2019-11-14 12:40:40 +01:00
|
|
|
item = window_new_ride_scroll_get_ride_list_item_at(w, screenCoords);
|
2020-04-27 16:26:35 +02:00
|
|
|
if (item.Type == RIDE_TYPE_NULL && item.EntryIndex == RIDE_ENTRY_INDEX_NULL)
|
2017-06-06 23:24:18 +02:00
|
|
|
return;
|
2014-08-20 23:06:47 +02:00
|
|
|
|
2017-06-06 23:24:18 +02:00
|
|
|
_windowNewRideHighlightedItem[_windowNewRideCurrentTab] = item;
|
2020-04-27 16:26:35 +02:00
|
|
|
w->new_ride.SelectedRide = item;
|
2014-08-20 23:06:47 +02:00
|
|
|
|
2020-10-06 23:34:42 +02:00
|
|
|
OpenRCT2::Audio::Play(OpenRCT2::Audio::SoundId::Click1, 0, w->windowPos.x + (w->width / 2));
|
2017-06-06 23:24:18 +02:00
|
|
|
w->new_ride.selected_ride_countdown = 8;
|
2019-06-15 17:20:16 +02:00
|
|
|
w->Invalidate();
|
2014-08-19 22:33:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
2014-08-20 23:06:47 +02:00
|
|
|
* rct2: 0x006B6C51
|
2014-08-19 22:33:05 +02:00
|
|
|
*/
|
2020-02-29 03:43:29 +01:00
|
|
|
static void window_new_ride_scrollmouseover(rct_window* w, int32_t scrollIndex, const ScreenCoordsXY& screenCoords)
|
2014-08-19 22:33:05 +02:00
|
|
|
{
|
2020-04-27 16:26:35 +02:00
|
|
|
RideSelection item;
|
2014-08-20 23:06:47 +02:00
|
|
|
|
2020-04-27 16:26:35 +02:00
|
|
|
if (w->new_ride.SelectedRide.Type != RIDE_TYPE_NULL)
|
2017-06-06 23:24:18 +02:00
|
|
|
return;
|
2014-08-20 23:06:47 +02:00
|
|
|
|
2019-11-14 12:40:40 +01:00
|
|
|
item = window_new_ride_scroll_get_ride_list_item_at(w, screenCoords);
|
2014-08-23 14:27:54 +02:00
|
|
|
|
2020-04-27 16:26:35 +02:00
|
|
|
if (w->new_ride.HighlightedRide == item)
|
2017-06-06 23:24:18 +02:00
|
|
|
return;
|
2014-08-19 22:33:05 +02:00
|
|
|
|
2020-04-27 16:26:35 +02:00
|
|
|
w->new_ride.HighlightedRide = item;
|
2017-06-06 23:24:18 +02:00
|
|
|
_windowNewRideHighlightedItem[_windowNewRideCurrentTab] = item;
|
2019-06-15 17:20:16 +02:00
|
|
|
w->Invalidate();
|
2014-08-19 22:33:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006B6819
|
|
|
|
*/
|
2018-06-22 23:21:44 +02:00
|
|
|
static void window_new_ride_invalidate(rct_window* w)
|
2014-08-19 22:33:05 +02:00
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
window_new_ride_set_pressed_tab(w);
|
|
|
|
|
|
|
|
window_new_ride_widgets[WIDX_TITLE].text = window_new_ride_titles[_windowNewRideCurrentTab];
|
2020-11-27 04:14:20 +01:00
|
|
|
window_new_ride_widgets[WIDX_TAB_7].type = WindowWidgetType::Tab;
|
2017-06-06 23:24:18 +02:00
|
|
|
if (gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER)
|
2020-11-27 04:14:20 +01:00
|
|
|
window_new_ride_widgets[WIDX_TAB_7].type = WindowWidgetType::Empty;
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
if (_windowNewRideCurrentTab == WINDOW_NEW_RIDE_PAGE_RESEARCH)
|
|
|
|
{
|
2020-11-27 04:14:20 +01:00
|
|
|
window_new_ride_widgets[WIDX_LAST_DEVELOPMENT_BUTTON].type = WindowWidgetType::Empty;
|
2020-01-22 20:51:40 +01:00
|
|
|
if (gResearchLastItem.has_value())
|
2018-01-04 16:43:55 +01:00
|
|
|
{
|
2020-07-22 15:25:05 +02:00
|
|
|
auto type = gResearchLastItem->type;
|
2020-11-27 04:14:20 +01:00
|
|
|
window_new_ride_widgets[WIDX_LAST_DEVELOPMENT_BUTTON].type = WindowWidgetType::FlatBtn;
|
2020-07-22 15:25:05 +02:00
|
|
|
window_new_ride_widgets[WIDX_LAST_DEVELOPMENT_BUTTON].image = (type == Research::EntryType::Ride) ? SPR_NEW_RIDE
|
|
|
|
: SPR_NEW_SCENERY;
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
|
|
|
}
|
2014-08-19 22:33:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006B689B
|
|
|
|
*/
|
2018-06-22 23:21:44 +02:00
|
|
|
static void window_new_ride_paint(rct_window* w, rct_drawpixelinfo* dpi)
|
2014-08-19 22:33:05 +02:00
|
|
|
{
|
2020-11-04 05:52:23 +01:00
|
|
|
WindowDrawWidgets(w, dpi);
|
2017-06-06 23:24:18 +02:00
|
|
|
window_new_ride_draw_tab_images(dpi, w);
|
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
if (_windowNewRideCurrentTab != WINDOW_NEW_RIDE_PAGE_RESEARCH)
|
|
|
|
{
|
2020-04-27 16:26:35 +02:00
|
|
|
RideSelection item;
|
|
|
|
item = w->new_ride.HighlightedRide;
|
|
|
|
if (item.Type != RIDE_TYPE_NULL || item.EntryIndex != RIDE_ENTRY_INDEX_NULL)
|
2020-03-01 20:32:35 +01:00
|
|
|
window_new_ride_paint_ride_information(
|
2020-06-11 15:11:12 +02:00
|
|
|
w, dpi, item, w->windowPos + ScreenCoordsXY{ 3, w->height - 64 }, w->width - 6);
|
2018-06-22 23:21:44 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
window_research_development_page_paint(w, dpi, WIDX_CURRENTLY_IN_DEVELOPMENT_GROUP);
|
|
|
|
}
|
2014-08-19 22:33:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006B6ABF
|
|
|
|
*/
|
2018-06-22 23:21:44 +02:00
|
|
|
static void window_new_ride_scrollpaint(rct_window* w, rct_drawpixelinfo* dpi, int32_t scrollIndex)
|
2014-08-19 22:33:05 +02:00
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
if (_windowNewRideCurrentTab == WINDOW_NEW_RIDE_PAGE_RESEARCH)
|
|
|
|
return;
|
|
|
|
|
|
|
|
gfx_clear(dpi, ColourMapA[w->colours[1]].mid_light);
|
|
|
|
|
2020-09-16 05:02:22 +02:00
|
|
|
ScreenCoordsXY coords{ 1, 1 };
|
2020-04-27 16:26:35 +02:00
|
|
|
RideSelection* listItem = _windowNewRideListItems;
|
|
|
|
while (listItem->Type != RIDE_TYPE_NULL || listItem->EntryIndex != RIDE_ENTRY_INDEX_NULL)
|
2018-06-22 23:21:44 +02:00
|
|
|
{
|
|
|
|
rct_ride_entry* rideEntry;
|
2017-06-06 23:24:18 +02:00
|
|
|
// Draw flat button rectangle
|
2018-06-20 17:28:51 +02:00
|
|
|
int32_t flags = 0;
|
2020-04-27 16:26:35 +02:00
|
|
|
if (w->new_ride.SelectedRide == *listItem)
|
2017-06-06 23:24:18 +02:00
|
|
|
flags |= INSET_RECT_FLAG_BORDER_INSET;
|
2020-04-27 16:26:35 +02:00
|
|
|
if (w->new_ride.HighlightedRide == *listItem || flags != 0)
|
2020-09-16 05:02:22 +02:00
|
|
|
gfx_fill_rect_inset(
|
|
|
|
dpi, { coords, coords + ScreenCoordsXY{ 115, 115 } }, w->colours[1], INSET_RECT_FLAG_FILL_MID_LIGHT | flags);
|
2017-06-06 23:24:18 +02:00
|
|
|
|
|
|
|
// Draw ride image with feathered border
|
2020-04-27 16:26:35 +02:00
|
|
|
rideEntry = get_ride_entry(listItem->EntryIndex);
|
2018-06-20 17:28:51 +02:00
|
|
|
int32_t imageId = rideEntry->images_offset;
|
2017-12-04 14:04:32 +01:00
|
|
|
|
|
|
|
for (size_t i = 0; i < MAX_RIDE_TYPES_PER_RIDE_ENTRY; i++)
|
|
|
|
{
|
2020-04-27 16:26:35 +02:00
|
|
|
if (rideEntry->ride_type[i] == listItem->Type)
|
2017-12-04 14:04:32 +01:00
|
|
|
break;
|
|
|
|
else
|
|
|
|
imageId++;
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
2017-12-04 14:04:32 +01:00
|
|
|
|
2020-09-16 05:02:22 +02:00
|
|
|
gfx_draw_sprite_raw_masked(dpi, coords + ScreenCoordsXY{ 2, 2 }, SPR_NEW_RIDE_MASK, imageId);
|
2017-06-06 23:24:18 +02:00
|
|
|
|
|
|
|
// Next position
|
2020-09-16 05:02:22 +02:00
|
|
|
coords.x += 116;
|
|
|
|
if (coords.x >= 116 * 5 + 1)
|
2018-06-22 23:21:44 +02:00
|
|
|
{
|
2020-09-16 05:02:22 +02:00
|
|
|
coords.x = 1;
|
|
|
|
coords.y += 116;
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Next item
|
|
|
|
listItem++;
|
|
|
|
}
|
2014-08-20 23:06:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006B6D3C
|
|
|
|
*/
|
2020-04-27 16:26:35 +02:00
|
|
|
static RideSelection window_new_ride_scroll_get_ride_list_item_at(rct_window* w, const ScreenCoordsXY& screenCoords)
|
2014-08-20 23:06:47 +02:00
|
|
|
{
|
2020-04-27 16:26:35 +02:00
|
|
|
RideSelection result;
|
|
|
|
result.Type = RIDE_TYPE_NULL;
|
|
|
|
result.EntryIndex = RIDE_ENTRY_INDEX_NULL;
|
2014-08-20 23:06:47 +02:00
|
|
|
|
2020-02-29 03:43:29 +01:00
|
|
|
if (screenCoords.x <= 0 || screenCoords.y <= 0)
|
2017-06-06 23:24:18 +02:00
|
|
|
return result;
|
2014-08-20 23:06:47 +02:00
|
|
|
|
2019-11-14 12:40:40 +01:00
|
|
|
int32_t column = screenCoords.x / 116;
|
|
|
|
int32_t row = screenCoords.y / 116;
|
2017-06-06 23:24:18 +02:00
|
|
|
if (column >= 5)
|
|
|
|
return result;
|
2014-08-20 23:06:47 +02:00
|
|
|
|
2018-06-20 17:28:51 +02:00
|
|
|
int32_t index = column + (row * 5);
|
2014-08-20 23:06:47 +02:00
|
|
|
|
2020-04-27 16:26:35 +02:00
|
|
|
RideSelection* listItem = _windowNewRideListItems;
|
|
|
|
while (listItem->Type != RIDE_TYPE_NULL || listItem->EntryIndex != RIDE_ENTRY_INDEX_NULL)
|
2018-06-22 23:21:44 +02:00
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
if (index-- == 0)
|
|
|
|
return *listItem;
|
|
|
|
listItem++;
|
|
|
|
}
|
2014-08-20 23:06:47 +02:00
|
|
|
|
2017-06-06 23:24:18 +02:00
|
|
|
return result;
|
2014-08-20 23:06:47 +02:00
|
|
|
}
|
|
|
|
|
2020-04-27 16:26:35 +02:00
|
|
|
static int32_t get_num_track_designs(RideSelection item)
|
2014-08-21 22:48:23 +02:00
|
|
|
{
|
2019-08-03 19:55:24 +02:00
|
|
|
std::string entryName;
|
2017-06-14 13:31:27 +02:00
|
|
|
|
2020-04-27 16:26:35 +02:00
|
|
|
if (item.Type < 0x80)
|
2017-12-07 16:12:37 +01:00
|
|
|
{
|
2020-04-27 16:26:35 +02:00
|
|
|
if (RideTypeDescriptors[item.Type].HasFlag(RIDE_TYPE_FLAG_LIST_VEHICLES_SEPARATELY))
|
2017-11-20 14:25:07 +01:00
|
|
|
{
|
2020-04-27 16:26:35 +02:00
|
|
|
entryName = get_ride_entry_name(item.EntryIndex);
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-03 19:55:24 +02:00
|
|
|
auto repo = OpenRCT2::GetContext()->GetTrackDesignRepository();
|
2020-04-27 16:26:35 +02:00
|
|
|
return static_cast<int32_t>(repo->GetCountForObjectEntry(item.Type, entryName));
|
2014-08-21 22:48:23 +02:00
|
|
|
}
|
|
|
|
|
2014-08-20 23:06:47 +02:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006B701C
|
|
|
|
*/
|
2018-06-22 23:21:44 +02:00
|
|
|
static void window_new_ride_paint_ride_information(
|
2020-06-11 15:11:12 +02:00
|
|
|
rct_window* w, rct_drawpixelinfo* dpi, RideSelection item, const ScreenCoordsXY& screenPos, int32_t width)
|
2014-08-20 23:06:47 +02:00
|
|
|
{
|
2020-04-27 16:26:35 +02:00
|
|
|
rct_ride_entry* rideEntry = get_ride_entry(item.EntryIndex);
|
2020-06-16 22:50:58 +02:00
|
|
|
RideNaming rideNaming;
|
2017-06-06 23:24:18 +02:00
|
|
|
|
|
|
|
// Ride name and description
|
2020-04-27 16:26:35 +02:00
|
|
|
rideNaming = get_ride_naming(item.Type, rideEntry);
|
2020-09-30 23:42:04 +02:00
|
|
|
auto ft = Formatter();
|
2020-06-16 22:50:58 +02:00
|
|
|
ft.Add<rct_string_id>(rideNaming.Name);
|
|
|
|
ft.Add<rct_string_id>(rideNaming.Description);
|
2020-09-30 23:42:04 +02:00
|
|
|
gfx_draw_string_left_wrapped(dpi, ft.Data(), screenPos, width, STR_NEW_RIDE_NAME_AND_DESCRIPTION, COLOUR_BLACK);
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2017-12-29 21:50:43 +01:00
|
|
|
char availabilityString[AVAILABILITY_STRING_SIZE];
|
2020-04-27 16:26:35 +02:00
|
|
|
window_new_ride_list_vehicles_for(item.Type, rideEntry, availabilityString, sizeof(availabilityString));
|
2017-11-20 14:25:07 +01:00
|
|
|
|
2017-12-29 21:50:43 +01:00
|
|
|
if (availabilityString[0] != 0)
|
|
|
|
{
|
2018-06-22 23:21:44 +02:00
|
|
|
const char* drawString = availabilityString;
|
2020-09-30 23:42:04 +02:00
|
|
|
ft = Formatter();
|
2020-08-28 22:33:36 +02:00
|
|
|
ft.Add<const char*>(drawString);
|
|
|
|
DrawTextEllipsised(dpi, screenPos + ScreenCoordsXY{ 0, 39 }, WW - 2, STR_AVAILABLE_VEHICLES, ft, COLOUR_BLACK);
|
2017-12-29 21:50:43 +01:00
|
|
|
}
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2020-09-30 23:42:04 +02:00
|
|
|
ft = Formatter();
|
2020-04-27 16:26:35 +02:00
|
|
|
if (item.Type != _lastTrackDesignCountRideType.Type || item.EntryIndex != _lastTrackDesignCountRideType.EntryIndex)
|
2018-06-22 23:21:44 +02:00
|
|
|
{
|
2017-12-29 21:50:43 +01:00
|
|
|
_lastTrackDesignCountRideType = item;
|
|
|
|
_lastTrackDesignCount = get_num_track_designs(item);
|
|
|
|
}
|
2020-10-01 09:57:46 +02:00
|
|
|
ft.Add<int32_t>(_lastTrackDesignCount);
|
2017-11-20 14:25:07 +01:00
|
|
|
|
2017-12-29 21:50:43 +01:00
|
|
|
rct_string_id designCountStringId;
|
2018-06-22 23:21:44 +02:00
|
|
|
switch (_lastTrackDesignCount)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
designCountStringId = STR_CUSTOM_DESIGNED_LAYOUT;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
designCountStringId = STR_1_DESIGN_AVAILABLE;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
designCountStringId = STR_X_DESIGNS_AVAILABLE;
|
|
|
|
break;
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
|
|
|
|
2020-09-30 23:42:04 +02:00
|
|
|
gfx_draw_string_left(dpi, designCountStringId, ft.Data(), COLOUR_BLACK, screenPos + ScreenCoordsXY{ 0, 51 });
|
2017-12-29 21:50:43 +01:00
|
|
|
|
2017-06-06 23:24:18 +02:00
|
|
|
// Price
|
2018-06-22 23:21:44 +02:00
|
|
|
if (!(gParkFlags & PARK_FLAGS_NO_MONEY))
|
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
// Get price of ride
|
2020-04-27 16:26:35 +02:00
|
|
|
int32_t unk2 = RideTypeDescriptors[item.Type].StartTrackPiece;
|
2020-06-12 21:19:34 +02:00
|
|
|
money32 price = RideTypeDescriptors[item.Type].BuildCosts.TrackPrice;
|
2021-02-08 21:28:41 +01:00
|
|
|
price *= TrackPricing[unk2];
|
2020-06-12 21:19:34 +02:00
|
|
|
price = (price >> 17) * 10 * RideTypeDescriptors[item.Type].BuildCosts.PriceEstimateMultiplier;
|
2017-06-06 23:24:18 +02:00
|
|
|
|
|
|
|
//
|
|
|
|
rct_string_id stringId = STR_NEW_RIDE_COST;
|
2021-02-26 09:49:09 +01:00
|
|
|
if (!GetRideTypeDescriptor(item.Type).HasFlag(RIDE_TYPE_FLAG_HAS_NO_TRACK))
|
2017-06-06 23:24:18 +02:00
|
|
|
stringId = STR_NEW_RIDE_COST_FROM;
|
|
|
|
|
2020-09-19 02:39:00 +02:00
|
|
|
ft = Formatter();
|
|
|
|
ft.Add<money32>(price);
|
|
|
|
DrawTextBasic(dpi, screenPos + ScreenCoordsXY{ width, 51 }, stringId, ft, COLOUR_BLACK, TextAlignment::RIGHT);
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
2014-08-20 23:06:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006B6B78
|
|
|
|
*/
|
2018-06-22 23:21:44 +02:00
|
|
|
static void window_new_ride_select(rct_window* w)
|
2014-08-20 23:06:47 +02:00
|
|
|
{
|
2020-04-27 16:26:35 +02:00
|
|
|
RideSelection item = w->new_ride.SelectedRide;
|
|
|
|
if (item.Type == RIDE_TYPE_NULL)
|
2017-06-06 23:24:18 +02:00
|
|
|
return;
|
2014-08-21 23:50:06 +02:00
|
|
|
|
2017-06-06 23:24:18 +02:00
|
|
|
window_close(w);
|
|
|
|
window_close_construction_windows();
|
2014-08-21 23:50:06 +02:00
|
|
|
|
2019-11-02 16:48:23 +01:00
|
|
|
if (_lastTrackDesignCount > 0)
|
2017-12-29 21:50:43 +01:00
|
|
|
{
|
|
|
|
auto intent = Intent(WC_TRACK_DESIGN_LIST);
|
2020-04-27 16:26:35 +02:00
|
|
|
intent.putExtra(INTENT_EXTRA_RIDE_TYPE, item.Type);
|
|
|
|
intent.putExtra(INTENT_EXTRA_RIDE_ENTRY_INDEX, item.EntryIndex);
|
2017-12-29 21:50:43 +01:00
|
|
|
context_open_intent(&intent);
|
|
|
|
return;
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
2014-08-21 23:50:06 +02:00
|
|
|
|
2017-06-06 23:24:18 +02:00
|
|
|
ride_construct_new(item);
|
2014-09-02 17:52:23 +02:00
|
|
|
}
|
2017-11-20 14:25:07 +01:00
|
|
|
|
2020-03-20 18:07:31 +01:00
|
|
|
static void window_new_ride_list_vehicles_for(uint8_t rideType, const rct_ride_entry* rideEntry, char* buffer, size_t bufferLen)
|
2017-11-20 14:25:07 +01:00
|
|
|
{
|
2020-03-20 18:07:31 +01:00
|
|
|
std::fill_n(buffer, bufferLen, 0);
|
2020-04-18 15:19:45 +02:00
|
|
|
if (RideTypeDescriptors[rideType].HasFlag(RIDE_TYPE_FLAG_LIST_VEHICLES_SEPARATELY))
|
2017-11-20 14:25:07 +01:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-03-20 18:07:31 +01:00
|
|
|
auto& objManager = OpenRCT2::GetContext()->GetObjectManager();
|
|
|
|
auto& rideEntries = objManager.GetAllRideEntries(rideType);
|
|
|
|
auto isFirst = true;
|
|
|
|
for (auto rideEntryIndex : rideEntries)
|
2017-11-20 14:25:07 +01:00
|
|
|
{
|
2020-03-20 18:07:31 +01:00
|
|
|
auto currentRideEntry = get_ride_entry(rideEntryIndex);
|
2017-11-20 14:25:07 +01:00
|
|
|
|
|
|
|
// Skip if vehicle type is not invented yet
|
|
|
|
if (!ride_entry_is_invented(rideEntryIndex) && !gCheatsIgnoreResearchStatus)
|
|
|
|
continue;
|
|
|
|
|
2020-03-20 18:07:31 +01:00
|
|
|
// Append comma if not the first iteration
|
|
|
|
if (!isFirst)
|
2017-11-20 14:25:07 +01:00
|
|
|
{
|
2020-03-20 18:07:31 +01:00
|
|
|
safe_strcat(buffer, ", ", bufferLen);
|
2017-11-20 14:25:07 +01:00
|
|
|
}
|
|
|
|
|
2020-03-20 18:07:31 +01:00
|
|
|
// Append vehicle name
|
2020-06-16 22:50:58 +02:00
|
|
|
auto vehicleName = language_get_string(currentRideEntry->naming.Name);
|
2020-03-20 18:07:31 +01:00
|
|
|
safe_strcat(buffer, vehicleName, bufferLen);
|
2017-11-20 14:25:07 +01:00
|
|
|
|
2020-03-20 18:07:31 +01:00
|
|
|
isFirst = false;
|
2017-11-20 14:25:07 +01:00
|
|
|
}
|
|
|
|
}
|