OpenRCT2/src/openrct2-ui/windows/Research.cpp

642 lines
23 KiB
C++
Raw Normal View History

/*****************************************************************************
2020-07-21 15:04:34 +02:00
* Copyright (c) 2014-2020 OpenRCT2 developers
*
* For a complete list of all authors, please refer to contributors.md
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
*
* OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/
2018-06-22 23:21:44 +02:00
#include <openrct2-ui/interface/Dropdown.h>
#include <openrct2-ui/interface/Widget.h>
2017-10-07 01:28:00 +02:00
#include <openrct2-ui/windows/Window.h>
2017-11-30 18:17:06 +01:00
#include <openrct2/Game.h>
Split actions hpp files into separate h and cpp files (#13548) * Split up SmallSceneryPlace/Remove Added undo function for Remove Scenery * Refactor: Balloon and Banner actions hpp=>h/cpp * Refactor: rename all action *.hpp files to *.cpp This is preparation for separation in later commits. Note that without the complete set of commits in this branch, the code will not build. * Refactor Clear, Climate, Custom, and Footpath actions hpp=>h/cpp * VSCode: add src subdirectories to includePath * Refactor Guest actions hpp=>h/cpp * Refactor Land actions hpp=>h/cpp * Refactor LargeScenery actions hpp=>h/cpp * Refactor Load, Maze, Network actions hpp=>h/cpp * Refactor Park actions hpp=>h/cpp * Refactor/style: move private function declarations in actions *.h Previous action .h files included private function declarations with private member variables, before public function declarations. This commit re-orders the header files to the following order: - public member variables - private member variables - public functions - private functions * Refactor Pause action hpp=>h/cpp * Refactor Peep, Place, Player actions hpp=>h/cpp * Refactor Ride actions hpp=>h/cpp * Refactor Scenario, Set*, Sign* actions hpp=>h/cpp * Refactor SmallScenerySetColourAction hpp=>h/cpp * Refactor Staff actions hpp=>h/cpp * Refactor Surface, Tile, Track* actions hpp=>h/cpp * Refactor Wall and Water actions hpp=>h/cpp * Fix various includes and other compile errors Update includes for tests. Move static function declarations to .h files Add explicit includes to various files that were previously implicit (the required header was a nested include in an action hpp file, and the action .h file does not include that header) Move RideSetStatus string enum to the cpp file to avoid unused imports * Xcode: modify project file for actions refactor * Cleanup whitespace and end-of-file newlines Co-authored-by: duncanspumpkin <duncans_pumpkin@hotmail.co.uk>
2020-12-10 07:39:10 +01:00
#include <openrct2/actions/ParkSetResearchFundingAction.h>
2018-01-06 18:32:25 +01:00
#include <openrct2/localisation/Localisation.h>
2018-06-22 23:21:44 +02:00
#include <openrct2/management/Finance.h>
2017-10-11 21:38:26 +02:00
#include <openrct2/management/NewsItem.h>
#include <openrct2/management/Research.h>
#include <openrct2/ride/RideData.h>
2017-10-07 01:28:00 +02:00
#include <openrct2/sprites.h>
2018-03-19 23:28:40 +01:00
#include <openrct2/world/Park.h>
2018-06-22 23:21:44 +02:00
#include <openrct2/world/Scenery.h>
2020-05-09 18:02:16 +02:00
static constexpr const int32_t WH_DEVELOPMENT = 196;
static constexpr const int32_t WW_DEVELOPMENT = 300;
static constexpr const int32_t WH_FUNDING = 207;
static constexpr const int32_t WW_FUNDING = 320;
// clang-format off
enum {
WINDOW_RESEARCH_PAGE_DEVELOPMENT,
WINDOW_RESEARCH_PAGE_FUNDING,
WINDOW_RESEARCH_PAGE_COUNT
};
enum {
WIDX_BACKGROUND,
WIDX_TITLE,
WIDX_CLOSE,
WIDX_PAGE_BACKGROUND,
WIDX_TAB_1,
WIDX_TAB_2,
WIDX_CURRENTLY_IN_DEVELOPMENT_GROUP,
WIDX_LAST_DEVELOPMENT_GROUP,
WIDX_LAST_DEVELOPMENT_BUTTON,
WIDX_FUNDING_GROUP = 6,
WIDX_RESEARCH_FUNDING,
WIDX_RESEARCH_FUNDING_DROPDOWN_BUTTON,
WIDX_PRIORITIES_GROUP,
WIDX_TRANSPORT_RIDES,
WIDX_GENTLE_RIDES,
WIDX_ROLLER_COASTERS,
WIDX_THRILL_RIDES,
WIDX_WATER_RIDES,
WIDX_SHOPS_AND_STALLS,
WIDX_SCENERY_AND_THEMING,
};
#pragma region Widgets
static rct_widget window_research_development_widgets[] = {
WINDOW_SHIM(STR_RESEARCH_AND_DEVELOPMENT, WW_DEVELOPMENT, WH_DEVELOPMENT),
MakeWidget({ 0, 43}, { WW_DEVELOPMENT, 153}, WindowWidgetType::Resize, WindowColour::Secondary ),
MakeTab ({ 3, 17}, STR_RESEARCH_AND_DEVELOPMENT_TIP),
MakeTab ({ 34, 17}, STR_FINANCES_RESEARCH_TIP ),
MakeWidget({ 3, 47}, {WW_DEVELOPMENT - 10, 70}, WindowWidgetType::Groupbox, WindowColour::Tertiary , STR_CURRENTLY_IN_DEVELOPMENT ),
MakeWidget({ 3, 124}, {WW_DEVELOPMENT - 10, 65}, WindowWidgetType::Groupbox, WindowColour::Tertiary , STR_LAST_DEVELOPMENT ),
MakeWidget({265, 161}, { 24, 24}, WindowWidgetType::FlatBtn, WindowColour::Tertiary , 0xFFFFFFFF, STR_RESEARCH_SHOW_DETAILS_TIP ),
{ WIDGETS_END },
};
static rct_widget window_research_funding_widgets[] = {
WINDOW_SHIM(STR_RESEARCH_FUNDING, WW_FUNDING, WH_FUNDING),
MakeWidget({ 0, 43}, { WW_FUNDING, 164}, WindowWidgetType::Resize, WindowColour::Secondary ),
MakeTab ({ 3, 17}, STR_RESEARCH_AND_DEVELOPMENT_TIP ),
MakeTab ({ 34, 17}, STR_FINANCES_RESEARCH_TIP ),
MakeWidget({ 3, 47}, { WW_FUNDING - 6, 45}, WindowWidgetType::Groupbox, WindowColour::Tertiary , STR_RESEARCH_FUNDING_ ),
MakeWidget({ 8, 59}, { 160, 14}, WindowWidgetType::DropdownMenu, WindowColour::Tertiary , 0xFFFFFFFF, STR_SELECT_LEVEL_OF_RESEARCH_AND_DEVELOPMENT),
MakeWidget({156, 60}, { 11, 12}, WindowWidgetType::Button, WindowColour::Tertiary , STR_DROPDOWN_GLYPH, STR_SELECT_LEVEL_OF_RESEARCH_AND_DEVELOPMENT),
MakeWidget({ 3, 96}, { WW_FUNDING - 6, 107}, WindowWidgetType::Groupbox, WindowColour::Tertiary , STR_RESEARCH_PRIORITIES ),
MakeWidget({ 8, 108}, {WW_FUNDING - 16, 12}, WindowWidgetType::Checkbox, WindowColour::Tertiary , STR_RESEARCH_NEW_TRANSPORT_RIDES, STR_RESEARCH_NEW_TRANSPORT_RIDES_TIP ),
MakeWidget({ 8, 121}, {WW_FUNDING - 16, 12}, WindowWidgetType::Checkbox, WindowColour::Tertiary , STR_RESEARCH_NEW_GENTLE_RIDES, STR_RESEARCH_NEW_GENTLE_RIDES_TIP ),
MakeWidget({ 8, 134}, {WW_FUNDING - 16, 12}, WindowWidgetType::Checkbox, WindowColour::Tertiary , STR_RESEARCH_NEW_ROLLER_COASTERS, STR_RESEARCH_NEW_ROLLER_COASTERS_TIP ),
MakeWidget({ 8, 147}, {WW_FUNDING - 16, 12}, WindowWidgetType::Checkbox, WindowColour::Tertiary , STR_RESEARCH_NEW_THRILL_RIDES, STR_RESEARCH_NEW_THRILL_RIDES_TIP ),
MakeWidget({ 8, 160}, {WW_FUNDING - 16, 12}, WindowWidgetType::Checkbox, WindowColour::Tertiary , STR_RESEARCH_NEW_WATER_RIDES, STR_RESEARCH_NEW_WATER_RIDES_TIP ),
MakeWidget({ 8, 173}, {WW_FUNDING - 16, 12}, WindowWidgetType::Checkbox, WindowColour::Tertiary , STR_RESEARCH_NEW_SHOPS_AND_STALLS, STR_RESEARCH_NEW_SHOPS_AND_STALLS_TIP ),
MakeWidget({ 8, 186}, {WW_FUNDING - 16, 12}, WindowWidgetType::Checkbox, WindowColour::Tertiary , STR_RESEARCH_NEW_SCENERY_AND_THEMING, STR_RESEARCH_NEW_SCENERY_AND_THEMING_TIP ),
{ WIDGETS_END },
};
static rct_widget *window_research_page_widgets[] = {
window_research_development_widgets,
window_research_funding_widgets
};
#pragma endregion
#pragma region Events
2017-05-01 15:41:45 +02:00
static void window_research_development_mouseup(rct_window *w, rct_widgetindex widgetIndex);
static void window_research_development_update(rct_window *w);
static void window_research_development_invalidate(rct_window *w);
static void window_research_development_paint(rct_window *w, rct_drawpixelinfo *dpi);
2017-05-01 15:41:45 +02:00
static void window_research_funding_mouseup(rct_window *w, rct_widgetindex widgetIndex);
static void window_research_funding_mousedown(rct_window *w, rct_widgetindex widgetIndex, rct_widget* widget);
static void window_research_funding_dropdown(rct_window *w, rct_widgetindex widgetIndex, int32_t dropdownIndex);
static void window_research_funding_update(rct_window *w);
static void window_research_funding_invalidate(rct_window *w);
static void window_research_funding_paint(rct_window *w, rct_drawpixelinfo *dpi);
2015-10-20 20:16:30 +02:00
//
static rct_window_event_list window_research_development_events([](auto& events)
{
events.mouse_up = &window_research_development_mouseup;
events.update = &window_research_development_update;
events.invalidate = &window_research_development_invalidate;
events.paint = &window_research_development_paint;
});
// 0x009890E8
static rct_window_event_list window_research_funding_events([](auto& events)
{
events.mouse_up = &window_research_funding_mouseup;
events.mouse_down = &window_research_funding_mousedown;
events.dropdown = &window_research_funding_dropdown;
events.update = &window_research_funding_update;
events.invalidate = &window_research_funding_invalidate;
events.paint = &window_research_funding_paint;
});
static rct_window_event_list *window_research_page_events[] = {
&window_research_development_events,
&window_research_funding_events
};
#pragma endregion
#pragma region Enabled widgets
static uint32_t window_research_page_enabled_widgets[] = {
(1 << WIDX_CLOSE) |
(1 << WIDX_TAB_1) |
(1 << WIDX_TAB_2) |
(1 << WIDX_LAST_DEVELOPMENT_BUTTON),
(1 << WIDX_CLOSE) |
(1 << WIDX_TAB_1) |
(1 << WIDX_TAB_2) |
(1 << WIDX_RESEARCH_FUNDING) |
(1 << WIDX_RESEARCH_FUNDING_DROPDOWN_BUTTON) |
(1 << WIDX_TRANSPORT_RIDES) |
(1 << WIDX_GENTLE_RIDES) |
(1 << WIDX_ROLLER_COASTERS) |
(1 << WIDX_THRILL_RIDES) |
(1 << WIDX_WATER_RIDES) |
(1 << WIDX_SHOPS_AND_STALLS) |
(1 << WIDX_SCENERY_AND_THEMING)
};
#pragma endregion
const int32_t window_research_tab_animation_loops[] = { 16, 16 };
static constexpr const rct_string_id ResearchStageNames[] = {
STR_RESEARCH_STAGE_INITIAL_RESEARCH,
STR_RESEARCH_STAGE_DESIGNING,
STR_RESEARCH_STAGE_COMPLETING_DESIGN,
STR_RESEARCH_STAGE_UNKNOWN,
};
// clang-format on
2018-06-22 23:21:44 +02:00
static void window_research_set_page(rct_window* w, int32_t page);
static void window_research_set_pressed_tab(rct_window* w);
static void window_research_draw_tab_images(rct_drawpixelinfo* dpi, rct_window* w);
2018-06-22 23:21:44 +02:00
rct_window* window_research_open()
{
2018-06-22 23:21:44 +02:00
rct_window* w;
w = window_bring_to_front_by_class(WC_RESEARCH);
2018-06-22 23:21:44 +02:00
if (w == nullptr)
{
w = WindowCreateAutoPos(WW_FUNDING, WH_FUNDING, window_research_page_events[0], WC_RESEARCH, WF_10);
w->widgets = window_research_page_widgets[0];
w->enabled_widgets = window_research_page_enabled_widgets[0];
w->number = 0;
w->page = 0;
w->frame_no = 0;
w->disabled_widgets = 0;
research_update_uncompleted_types();
}
w->page = 0;
w->Invalidate();
2020-05-09 18:02:16 +02:00
w->width = WW_DEVELOPMENT;
w->height = WH_DEVELOPMENT;
w->Invalidate();
w->widgets = window_research_page_widgets[0];
w->enabled_widgets = window_research_page_enabled_widgets[0];
w->hold_down_widgets = 0;
w->event_handlers = window_research_page_events[0];
w->pressed_widgets = 0;
w->disabled_widgets = 0;
WindowInitScrollWidgets(w);
2017-10-07 01:28:00 +02:00
return w;
}
#pragma region Development page
/**
*
* rct2: 0x006B6B38
*/
2018-06-22 23:21:44 +02:00
static void window_research_development_mouseup(rct_window* w, rct_widgetindex widgetIndex)
{
2018-06-22 23:21:44 +02:00
switch (widgetIndex)
{
case WIDX_CLOSE:
window_close(w);
break;
case WIDX_TAB_1:
case WIDX_TAB_2:
window_research_set_page(w, widgetIndex - WIDX_TAB_1);
break;
case WIDX_LAST_DEVELOPMENT_BUTTON:
News::OpenSubject(News::ItemType::Research, gResearchLastItem->rawValue);
2018-06-22 23:21:44 +02:00
break;
}
}
/**
*
* rct2: 0x0069CBA6
*/
2018-06-22 23:21:44 +02:00
static void window_research_development_update(rct_window* w)
{
// Tab animation
if (++w->frame_no >= window_research_tab_animation_loops[w->page])
w->frame_no = 0;
widget_invalidate(w, WIDX_TAB_1);
}
/**
2015-10-20 20:16:30 +02:00
*
* rct2: 0x006B6819
*/
2018-06-22 23:21:44 +02:00
static void window_research_development_invalidate(rct_window* w)
{
2018-06-22 23:21:44 +02:00
if (w->widgets != window_research_page_widgets[WINDOW_RESEARCH_PAGE_DEVELOPMENT])
{
w->widgets = window_research_page_widgets[WINDOW_RESEARCH_PAGE_DEVELOPMENT];
WindowInitScrollWidgets(w);
}
window_research_set_pressed_tab(w);
window_research_development_widgets[WIDX_LAST_DEVELOPMENT_BUTTON].type = WindowWidgetType::Empty;
if (gResearchLastItem.has_value())
{
auto type = gResearchLastItem->type;
window_research_development_widgets[WIDX_LAST_DEVELOPMENT_BUTTON].type = WindowWidgetType::FlatBtn;
window_research_development_widgets[WIDX_LAST_DEVELOPMENT_BUTTON].image = type == Research::EntryType::Ride
? SPR_NEW_RIDE
: SPR_NEW_SCENERY;
}
}
/**
2015-10-20 20:16:30 +02:00
*
* rct2: 0x006B689B
*/
2018-06-22 23:21:44 +02:00
static void window_research_development_paint(rct_window* w, rct_drawpixelinfo* dpi)
{
WindowDrawWidgets(w, dpi);
window_research_draw_tab_images(dpi, w);
window_research_development_page_paint(w, dpi, WIDX_CURRENTLY_IN_DEVELOPMENT_GROUP);
}
2018-06-22 23:21:44 +02:00
void window_research_development_page_paint(rct_window* w, rct_drawpixelinfo* dpi, rct_widgetindex baseWidgetIndex)
{
baseWidgetIndex = baseWidgetIndex - WIDX_CURRENTLY_IN_DEVELOPMENT_GROUP;
auto screenCoords = w->windowPos
+ ScreenCoordsXY{ 10, w->widgets[WIDX_CURRENTLY_IN_DEVELOPMENT_GROUP + baseWidgetIndex].top + 12 };
rct_string_id stringId;
2018-06-22 23:21:44 +02:00
if (gResearchProgressStage == RESEARCH_STAGE_FINISHED_ALL)
{
{
auto ft = Formatter();
ft.Add<rct_string_id>(STR_RESEARCH_UNKNOWN);
gfx_draw_string_left_wrapped(dpi, ft.Data(), screenCoords, 296, STR_RESEARCH_TYPE_LABEL, COLOUR_BLACK);
screenCoords.y += 25;
}
// Progress
{
auto ft = Formatter();
ft.Add<rct_string_id>(STR_RESEARCH_COMPLETED_AL);
gfx_draw_string_left_wrapped(dpi, ft.Data(), screenCoords, 296, STR_RESEARCH_PROGRESS_LABEL, COLOUR_BLACK);
screenCoords.y += 15;
}
{
auto ft = Formatter();
ft.Add<rct_string_id>(STR_RESEARCH_STAGE_UNKNOWN);
gfx_draw_string_left(dpi, STR_RESEARCH_EXPECTED_LABEL, ft.Data(), COLOUR_BLACK, screenCoords);
}
2018-06-22 23:21:44 +02:00
}
else
{
// Research type
std::array<rct_string_id, 2> strings = { STR_RESEARCH_UNKNOWN, 0 };
rct_string_id label = STR_RESEARCH_TYPE_LABEL;
2017-09-19 12:18:17 +02:00
if (gResearchProgressStage != RESEARCH_STAGE_INITIAL_RESEARCH)
{
strings[0] = gResearchNextItem->GetCategoryName();
2017-09-19 12:18:17 +02:00
if (gResearchProgressStage != RESEARCH_STAGE_DESIGNING)
{
strings[0] = gResearchNextItem->GetName();
if (gResearchNextItem->type == Research::EntryType::Ride)
{
auto rtd = RideTypeDescriptors[gResearchNextItem->baseRideType];
if (!rtd.HasFlag(RIDE_TYPE_FLAG_LIST_VEHICLES_SEPARATELY))
{
if (gResearchNextItem->flags & RESEARCH_ENTRY_FLAG_FIRST_OF_TYPE)
{
strings[0] = rtd.Naming.Name;
}
else
{
strings[1] = rtd.Naming.Name;
label = STR_RESEARCH_TYPE_LABEL_VEHICLE;
}
}
}
}
}
gfx_draw_string_left_wrapped(dpi, &strings, screenCoords, 296, label, COLOUR_BLACK);
screenCoords.y += 25;
// Progress
stringId = ResearchStageNames[gResearchProgressStage];
gfx_draw_string_left_wrapped(dpi, &stringId, screenCoords, 296, STR_RESEARCH_PROGRESS_LABEL, COLOUR_BLACK);
screenCoords.y += 15;
// Expected
auto ft = Formatter();
if (gResearchProgressStage != RESEARCH_STAGE_INITIAL_RESEARCH && gResearchExpectedDay != 255)
2018-06-22 23:21:44 +02:00
{
// TODO: Should probably use game date format setting
ft.Add<rct_string_id>(STR_RESEARCH_EXPECTED_FORMAT);
ft.Add<rct_string_id>(DateDayNames[gResearchExpectedDay]);
ft.Add<rct_string_id>(DateGameMonthNames[gResearchExpectedMonth]);
}
else
{
ft.Add<rct_string_id>(STR_RESEARCH_STAGE_UNKNOWN);
}
gfx_draw_string_left(dpi, STR_RESEARCH_EXPECTED_LABEL, ft.Data(), COLOUR_BLACK, screenCoords);
}
// Last development
screenCoords = w->windowPos + ScreenCoordsXY{ 10, w->widgets[WIDX_LAST_DEVELOPMENT_GROUP + baseWidgetIndex].top + 12 };
if (gResearchLastItem.has_value())
2017-09-19 12:18:17 +02:00
{
rct_string_id lastDevelopmentFormat = STR_EMPTY;
std::array<rct_string_id, 2> strings = { gResearchLastItem->GetName(), 0 };
auto type = gResearchLastItem->type;
if (type == Research::EntryType::Scenery)
{
lastDevelopmentFormat = STR_RESEARCH_SCENERY_LABEL;
}
else
{
lastDevelopmentFormat = STR_RESEARCH_RIDE_LABEL;
auto rtd = RideTypeDescriptors[gResearchLastItem->baseRideType];
if (!rtd.HasFlag(RIDE_TYPE_FLAG_LIST_VEHICLES_SEPARATELY))
{
if (gResearchLastItem->flags & RESEARCH_ENTRY_FLAG_FIRST_OF_TYPE)
{
strings[0] = rtd.Naming.Name;
}
else
{
strings[1] = rtd.Naming.Name;
lastDevelopmentFormat = STR_RESEARCH_VEHICLE_LABEL;
}
}
}
2017-09-19 12:18:17 +02:00
gfx_draw_string_left_wrapped(dpi, &strings, screenCoords, 266, lastDevelopmentFormat, COLOUR_BLACK);
}
}
#pragma endregion
#pragma region Funding page
/**
2015-10-20 20:16:30 +02:00
*
* rct2: 0x0069DB3F
*/
2018-06-22 23:21:44 +02:00
static void window_research_funding_mouseup(rct_window* w, rct_widgetindex widgetIndex)
{
2018-06-22 23:21:44 +02:00
switch (widgetIndex)
{
case WIDX_CLOSE:
window_close(w);
break;
case WIDX_TAB_1:
case WIDX_TAB_2:
window_research_set_page(w, widgetIndex - WIDX_TAB_1);
break;
case WIDX_TRANSPORT_RIDES:
case WIDX_GENTLE_RIDES:
case WIDX_ROLLER_COASTERS:
case WIDX_THRILL_RIDES:
case WIDX_WATER_RIDES:
case WIDX_SHOPS_AND_STALLS:
case WIDX_SCENERY_AND_THEMING:
{
auto activeResearchTypes = gResearchPriorities;
activeResearchTypes ^= 1 << (widgetIndex - WIDX_TRANSPORT_RIDES);
auto gameAction = ParkSetResearchFundingAction(activeResearchTypes, gResearchFundingLevel);
GameActions::Execute(&gameAction);
break;
}
}
}
/**
2015-10-20 20:16:30 +02:00
*
* rct2: 0x0069DB66
*/
2018-06-22 23:21:44 +02:00
static void window_research_funding_mousedown(rct_window* w, rct_widgetindex widgetIndex, rct_widget* widget)
{
2018-06-22 23:21:44 +02:00
rct_widget* dropdownWidget;
int32_t i;
if (widgetIndex != WIDX_RESEARCH_FUNDING_DROPDOWN_BUTTON)
return;
dropdownWidget = widget - 1;
2018-06-22 23:21:44 +02:00
for (i = 0; i < 4; i++)
{
gDropdownItemsFormat[i] = STR_DROPDOWN_MENU_LABEL;
gDropdownItemsArgs[i] = ResearchFundingLevelNames[i];
}
WindowDropdownShowTextCustomWidth(
{ w->windowPos.x + dropdownWidget->left, w->windowPos.y + dropdownWidget->top }, dropdownWidget->height() + 1,
w->colours[1], 0, Dropdown::Flag::StayOpen, 4, dropdownWidget->width() - 3);
int32_t currentResearchLevel = gResearchFundingLevel;
Dropdown::SetChecked(currentResearchLevel, true);
}
/**
2015-10-20 20:16:30 +02:00
*
* rct2: 0x0069DB6D
*/
2018-06-22 23:21:44 +02:00
static void window_research_funding_dropdown(rct_window* w, rct_widgetindex widgetIndex, int32_t dropdownIndex)
{
if (widgetIndex != WIDX_RESEARCH_FUNDING_DROPDOWN_BUTTON || dropdownIndex == -1)
return;
auto gameAction = ParkSetResearchFundingAction(gResearchPriorities, dropdownIndex);
GameActions::Execute(&gameAction);
}
/**
2015-10-20 20:16:30 +02:00
*
* rct2: 0x0069DC23
*/
2018-06-22 23:21:44 +02:00
static void window_research_funding_update(rct_window* w)
{
// Tab animation
if (++w->frame_no >= window_research_tab_animation_loops[w->page])
w->frame_no = 0;
widget_invalidate(w, WIDX_TAB_2);
}
/**
2015-10-20 20:16:30 +02:00
*
* rct2: 0x0069DA64
*/
2018-06-22 23:21:44 +02:00
static void window_research_funding_invalidate(rct_window* w)
{
2018-06-22 23:21:44 +02:00
if (w->widgets != window_research_page_widgets[WINDOW_RESEARCH_PAGE_FUNDING])
{
w->widgets = window_research_page_widgets[WINDOW_RESEARCH_PAGE_FUNDING];
WindowInitScrollWidgets(w);
}
window_research_set_pressed_tab(w);
2018-06-22 23:21:44 +02:00
if ((gParkFlags & PARK_FLAGS_NO_MONEY) || (gResearchProgressStage == RESEARCH_STAGE_FINISHED_ALL))
{
window_research_funding_widgets[WIDX_RESEARCH_FUNDING].type = WindowWidgetType::Empty;
window_research_funding_widgets[WIDX_RESEARCH_FUNDING_DROPDOWN_BUTTON].type = WindowWidgetType::Empty;
2018-06-22 23:21:44 +02:00
}
else
{
window_research_funding_widgets[WIDX_FUNDING_GROUP].type = WindowWidgetType::Groupbox;
window_research_funding_widgets[WIDX_RESEARCH_FUNDING].type = WindowWidgetType::DropdownMenu;
window_research_funding_widgets[WIDX_RESEARCH_FUNDING_DROPDOWN_BUTTON].type = WindowWidgetType::Button;
// Current funding
int32_t currentResearchLevel = gResearchFundingLevel;
window_research_funding_widgets[WIDX_RESEARCH_FUNDING].text = ResearchFundingLevelNames[currentResearchLevel];
}
// Checkboxes
uint8_t activeResearchTypes = gResearchPriorities;
2018-06-22 23:21:44 +02:00
for (int32_t i = 0; i < 7; i++)
{
int32_t mask = 1 << i;
int32_t widgetMask = 1 << (i + WIDX_TRANSPORT_RIDES);
// Set checkbox disabled if research type is complete
2018-06-22 23:21:44 +02:00
if (gResearchUncompletedCategories & mask)
{
w->disabled_widgets &= ~widgetMask;
// Set checkbox ticked if research type is active
if (activeResearchTypes & mask)
w->pressed_widgets |= widgetMask;
else
w->pressed_widgets &= ~widgetMask;
2018-06-22 23:21:44 +02:00
}
else
{
w->disabled_widgets |= widgetMask;
w->pressed_widgets &= ~widgetMask;
}
}
}
/**
2015-10-20 20:16:30 +02:00
*
* rct2: 0x0069DAF0
*/
2018-06-22 23:21:44 +02:00
static void window_research_funding_paint(rct_window* w, rct_drawpixelinfo* dpi)
{
WindowDrawWidgets(w, dpi);
window_research_draw_tab_images(dpi, w);
window_research_funding_page_paint(w, dpi, WIDX_RESEARCH_FUNDING);
}
2018-06-22 23:21:44 +02:00
void window_research_funding_page_paint(rct_window* w, rct_drawpixelinfo* dpi, rct_widgetindex baseWidgetIndex)
{
if (gParkFlags & PARK_FLAGS_NO_MONEY)
return;
int32_t currentResearchLevel = gResearchFundingLevel;
money32 currentResearchCostPerWeek = research_cost_table[currentResearchLevel];
2020-03-01 20:32:35 +01:00
gfx_draw_string_left(
dpi, STR_RESEARCH_COST_PER_MONTH, &currentResearchCostPerWeek, COLOUR_BLACK, w->windowPos + ScreenCoordsXY{ 10, 77 });
}
#pragma endregion
#pragma region Common
/**
*
* rct2: 0x0069CAC5
*/
2018-06-22 23:21:44 +02:00
static void window_research_set_page(rct_window* w, int32_t page)
{
w->page = page;
w->frame_no = 0;
w->RemoveViewport();
w->enabled_widgets = window_research_page_enabled_widgets[page];
w->hold_down_widgets = 0;
w->event_handlers = window_research_page_events[page];
w->widgets = window_research_page_widgets[page];
w->disabled_widgets = 0;
w->pressed_widgets = 0;
w->Invalidate();
2018-06-22 23:21:44 +02:00
if (w->page == WINDOW_RESEARCH_PAGE_DEVELOPMENT)
{
2020-05-09 18:02:16 +02:00
w->width = WW_DEVELOPMENT;
w->height = WH_DEVELOPMENT;
2018-06-22 23:21:44 +02:00
}
else
{
2020-05-09 18:02:16 +02:00
w->width = WW_FUNDING;
w->height = WH_FUNDING;
}
window_event_resize_call(w);
window_event_invalidate_call(w);
WindowInitScrollWidgets(w);
w->Invalidate();
}
2018-06-22 23:21:44 +02:00
static void window_research_set_pressed_tab(rct_window* w)
{
int32_t i;
for (i = 0; i < WINDOW_RESEARCH_PAGE_COUNT; i++)
w->pressed_widgets &= ~(1 << (WIDX_TAB_1 + i));
w->pressed_widgets |= 1LL << (WIDX_TAB_1 + w->page);
}
2018-06-22 23:21:44 +02:00
static void window_research_draw_tab_image(rct_drawpixelinfo* dpi, rct_window* w, int32_t page, int32_t spriteIndex)
{
rct_widgetindex widgetIndex = WIDX_TAB_1 + page;
2018-06-22 23:21:44 +02:00
if (!(w->disabled_widgets & (1LL << widgetIndex)))
{
if (w->page == page)
{
int32_t frame = w->frame_no / 2;
if (page == WINDOW_RESEARCH_PAGE_DEVELOPMENT)
frame %= 8;
spriteIndex += frame;
}
2020-03-01 20:32:35 +01:00
gfx_draw_sprite(
dpi, spriteIndex, w->windowPos + ScreenCoordsXY{ w->widgets[widgetIndex].left, w->widgets[widgetIndex].top }, 0);
}
}
2018-06-22 23:21:44 +02:00
static void window_research_draw_tab_images(rct_drawpixelinfo* dpi, rct_window* w)
{
window_research_draw_tab_image(dpi, w, WINDOW_RESEARCH_PAGE_DEVELOPMENT, SPR_TAB_FINANCES_RESEARCH_0);
window_research_draw_tab_image(dpi, w, WINDOW_RESEARCH_PAGE_FUNDING, SPR_TAB_FINANCES_SUMMARY_0);
}
#pragma endregion