mirror of https://github.com/OpenRCT2/OpenRCT2.git
1290 lines
58 KiB
C++
1290 lines
58 KiB
C++
/*****************************************************************************
|
|
* Copyright (c) 2014-2024 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.
|
|
*****************************************************************************/
|
|
|
|
#include "../interface/Dropdown.h"
|
|
#include "../interface/Widget.h"
|
|
#include "../interface/Window.h"
|
|
#include "Window.h"
|
|
|
|
#include <algorithm>
|
|
#include <openrct2/Context.h>
|
|
#include <openrct2/Editor.h>
|
|
#include <openrct2/Game.h>
|
|
#include <openrct2/GameState.h>
|
|
#include <openrct2/OpenRCT2.h>
|
|
#include <openrct2/actions/ClimateSetAction.h>
|
|
#include <openrct2/actions/ScenarioSetSettingAction.h>
|
|
#include <openrct2/drawing/Drawing.h>
|
|
#include <openrct2/entity/Peep.h>
|
|
#include <openrct2/interface/Colour.h>
|
|
#include <openrct2/localisation/Formatter.h>
|
|
#include <openrct2/localisation/StringIds.h>
|
|
#include <openrct2/management/Finance.h>
|
|
#include <openrct2/sprites.h>
|
|
#include <openrct2/world/Climate.h>
|
|
#include <openrct2/world/Park.h>
|
|
|
|
namespace OpenRCT2::Ui::Windows
|
|
{
|
|
static constexpr int32_t WW_FINANCIAL = 280;
|
|
static constexpr int32_t WH_FINANCIAL = 149;
|
|
|
|
static constexpr int32_t WW_GUESTS = 380;
|
|
static constexpr int32_t WH_GUESTS = 149;
|
|
|
|
static constexpr int32_t WW_PARK = 400;
|
|
static constexpr int32_t WH_PARK = 200;
|
|
|
|
#pragma region Widgets
|
|
|
|
// clang-format off
|
|
enum {
|
|
WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_FINANCIAL,
|
|
WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_GUESTS,
|
|
WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_PARK,
|
|
WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_COUNT
|
|
};
|
|
|
|
static constexpr StringId ClimateNames[] = {
|
|
STR_CLIMATE_COOL_AND_WET,
|
|
STR_CLIMATE_WARM,
|
|
STR_CLIMATE_HOT_AND_DRY,
|
|
STR_CLIMATE_COLD,
|
|
};
|
|
|
|
enum {
|
|
WIDX_BACKGROUND,
|
|
WIDX_TITLE,
|
|
WIDX_CLOSE,
|
|
WIDX_PAGE_BACKGROUND,
|
|
WIDX_TAB_1,
|
|
WIDX_TAB_2,
|
|
WIDX_TAB_3,
|
|
WIDX_PAGE_START,
|
|
|
|
// Financial tab
|
|
WIDX_NO_MONEY = WIDX_PAGE_START,
|
|
WIDX_INITIAL_CASH,
|
|
WIDX_INITIAL_CASH_INCREASE,
|
|
WIDX_INITIAL_CASH_DECREASE,
|
|
WIDX_INITIAL_LOAN,
|
|
WIDX_INITIAL_LOAN_INCREASE,
|
|
WIDX_INITIAL_LOAN_DECREASE,
|
|
WIDX_MAXIMUM_LOAN,
|
|
WIDX_MAXIMUM_LOAN_INCREASE,
|
|
WIDX_MAXIMUM_LOAN_DECREASE,
|
|
WIDX_INTEREST_RATE,
|
|
WIDX_INTEREST_RATE_INCREASE,
|
|
WIDX_INTEREST_RATE_DECREASE,
|
|
WIDX_FORBID_MARKETING,
|
|
WIDX_RCT1_INTEREST,
|
|
|
|
// Guests tab
|
|
WIDX_CASH_PER_GUEST = WIDX_PAGE_START,
|
|
WIDX_CASH_PER_GUEST_INCREASE,
|
|
WIDX_CASH_PER_GUEST_DECREASE,
|
|
WIDX_GUEST_INITIAL_HAPPINESS,
|
|
WIDX_GUEST_INITIAL_HAPPINESS_INCREASE,
|
|
WIDX_GUEST_INITIAL_HAPPINESS_DECREASE,
|
|
WIDX_GUEST_INITIAL_HUNGER,
|
|
WIDX_GUEST_INITIAL_HUNGER_INCREASE,
|
|
WIDX_GUEST_INITIAL_HUNGER_DECREASE,
|
|
WIDX_GUEST_INITIAL_THIRST,
|
|
WIDX_GUEST_INITIAL_THIRST_INCREASE,
|
|
WIDX_GUEST_INITIAL_THIRST_DECREASE,
|
|
WIDX_GUEST_PREFER_LESS_INTENSE_RIDES,
|
|
WIDX_GUEST_PREFER_MORE_INTENSE_RIDES,
|
|
|
|
// Park tab
|
|
WIDX_LAND_COST = WIDX_PAGE_START,
|
|
WIDX_LAND_COST_INCREASE,
|
|
WIDX_LAND_COST_DECREASE,
|
|
WIDX_CONSTRUCTION_RIGHTS_COST,
|
|
WIDX_CONSTRUCTION_RIGHTS_COST_INCREASE,
|
|
WIDX_CONSTRUCTION_RIGHTS_COST_DECREASE,
|
|
WIDX_PAY_FOR_PARK_OR_RIDES,
|
|
WIDX_PAY_FOR_PARK_OR_RIDES_DROPDOWN,
|
|
WIDX_ENTRY_PRICE,
|
|
WIDX_ENTRY_PRICE_INCREASE,
|
|
WIDX_ENTRY_PRICE_DECREASE,
|
|
WIDX_CLIMATE,
|
|
WIDX_CLIMATE_DROPDOWN,
|
|
WIDX_FORBID_TREE_REMOVAL,
|
|
WIDX_FORBID_LANDSCAPE_CHANGES,
|
|
WIDX_FORBID_HIGH_CONSTRUCTION,
|
|
WIDX_HARD_PARK_RATING,
|
|
WIDX_HARD_GUEST_GENERATION
|
|
};
|
|
|
|
static Widget window_editor_scenario_options_financial_widgets[] = {
|
|
WINDOW_SHIM(STR_SCENARIO_OPTIONS_FINANCIAL, WW_FINANCIAL, WH_FINANCIAL),
|
|
MakeWidget ({ 0, 43}, { WW_FINANCIAL, 106}, WindowWidgetType::Resize, WindowColour::Secondary ),
|
|
MakeTab ({ 3, 17}, STR_SCENARIO_OPTIONS_FINANCIAL_TIP),
|
|
MakeTab ({ 34, 17}, STR_SCENARIO_OPTIONS_GUESTS_TIP ),
|
|
MakeTab ({ 65, 17}, STR_SCENARIO_OPTIONS_PARK_TIP ),
|
|
MakeWidget ({ 8, 48}, {WW_FINANCIAL - 16, 12}, WindowWidgetType::Checkbox, WindowColour::Secondary, STR_MAKE_PARK_NO_MONEY, STR_MAKE_PARK_NO_MONEY_TIP ),
|
|
MakeSpinnerWidgets({168, 65}, { 100, 12}, WindowWidgetType::Spinner, WindowColour::Secondary ), // NB: 3 widgets
|
|
MakeSpinnerWidgets({168, 82}, { 100, 12}, WindowWidgetType::Spinner, WindowColour::Secondary ), // NB: 3 widgets
|
|
MakeSpinnerWidgets({168, 99}, { 100, 12}, WindowWidgetType::Spinner, WindowColour::Secondary ), // NB: 3 widgets
|
|
MakeSpinnerWidgets({168, 116}, { 70, 12}, WindowWidgetType::Spinner, WindowColour::Secondary ), // NB: 3 widgets
|
|
MakeWidget ({ 8, 133}, {WW_FINANCIAL - 16, 12}, WindowWidgetType::Checkbox, WindowColour::Secondary, STR_FORBID_MARKETING, STR_FORBID_MARKETING_TIP ),
|
|
MakeWidget ({ 8, 116}, {WW_FINANCIAL - 16, 12}, WindowWidgetType::Checkbox, WindowColour::Secondary, STR_RCT1_INTEREST, STR_RCT1_INTEREST_TIP ),
|
|
kWidgetsEnd,
|
|
};
|
|
|
|
static Widget window_editor_scenario_options_guests_widgets[] = {
|
|
WINDOW_SHIM(STR_SCENARIO_OPTIONS_GUESTS, WW_GUESTS, WH_GUESTS),
|
|
MakeWidget ({ 0, 43}, { WW_GUESTS, 106}, WindowWidgetType::Resize, WindowColour::Secondary),
|
|
MakeRemapWidget ({ 3, 17}, { 31, 27}, WindowWidgetType::Tab, WindowColour::Secondary, SPR_TAB, STR_SCENARIO_OPTIONS_FINANCIAL_TIP ),
|
|
MakeRemapWidget ({ 34, 17}, { 31, 30}, WindowWidgetType::Tab, WindowColour::Secondary, SPR_TAB, STR_SCENARIO_OPTIONS_GUESTS_TIP ),
|
|
MakeRemapWidget ({ 65, 17}, { 31, 27}, WindowWidgetType::Tab, WindowColour::Secondary, SPR_TAB, STR_SCENARIO_OPTIONS_PARK_TIP ),
|
|
MakeSpinnerWidgets({268, 48}, { 70, 12}, WindowWidgetType::Spinner, WindowColour::Secondary ), // NB: 3 widgets
|
|
MakeSpinnerWidgets({268, 65}, { 70, 12}, WindowWidgetType::Spinner, WindowColour::Secondary ), // NB: 3 widgets
|
|
MakeSpinnerWidgets({268, 82}, { 70, 12}, WindowWidgetType::Spinner, WindowColour::Secondary ), // NB: 3 widgets
|
|
MakeSpinnerWidgets({268, 99}, { 70, 12}, WindowWidgetType::Spinner, WindowColour::Secondary ), // NB: 3 widgets
|
|
MakeWidget ({ 8, 116}, {WW_GUESTS - 16, 12}, WindowWidgetType::Checkbox, WindowColour::Secondary, STR_GUESTS_PREFER_LESS_INTENSE_RIDES, STR_GUESTS_PREFER_LESS_INTENSE_RIDES_TIP),
|
|
MakeWidget ({ 8, 133}, {WW_GUESTS - 16, 12}, WindowWidgetType::Checkbox, WindowColour::Secondary, STR_GUESTS_PREFER_MORE_INTENSE_RIDES, STR_GUESTS_PREFER_MORE_INTENSE_RIDES_TIP),
|
|
kWidgetsEnd,
|
|
};
|
|
|
|
static Widget window_editor_scenario_options_park_widgets[] = {
|
|
WINDOW_SHIM(STR_SCENARIO_OPTIONS_PARK, WW_PARK, WH_PARK),
|
|
MakeWidget ({ 0, 43}, { WW_PARK, 106}, WindowWidgetType::Resize, WindowColour::Secondary ),
|
|
MakeRemapWidget ({ 3, 17}, { 31, 27}, WindowWidgetType::Tab, WindowColour::Secondary, SPR_TAB, STR_SCENARIO_OPTIONS_FINANCIAL_TIP),
|
|
MakeRemapWidget ({ 34, 17}, { 31, 30}, WindowWidgetType::Tab, WindowColour::Secondary, SPR_TAB, STR_SCENARIO_OPTIONS_GUESTS_TIP ),
|
|
MakeRemapWidget ({ 65, 17}, { 31, 27}, WindowWidgetType::Tab, WindowColour::Secondary, SPR_TAB, STR_SCENARIO_OPTIONS_PARK_TIP ),
|
|
MakeSpinnerWidgets({188, 48}, { 70, 12}, WindowWidgetType::Spinner, WindowColour::Secondary ), // NB: 3 widgets
|
|
MakeSpinnerWidgets({188, 65}, { 70, 12}, WindowWidgetType::Spinner, WindowColour::Secondary ), // NB: 3 widgets
|
|
MakeWidget ({ 8, 82}, { 210, 12}, WindowWidgetType::DropdownMenu, WindowColour::Secondary, STR_NONE, STR_PAY_FOR_PARK_PAY_FOR_RIDES_TIP),
|
|
MakeWidget ({206, 83}, { 11, 10}, WindowWidgetType::Button, WindowColour::Secondary, STR_DROPDOWN_GLYPH, STR_PAY_FOR_PARK_PAY_FOR_RIDES_TIP),
|
|
MakeSpinnerWidgets({328, 82}, { 67, 12}, WindowWidgetType::Spinner, WindowColour::Secondary ), // NB: 3 widgets
|
|
MakeWidget ({188, 99}, { 207, 12}, WindowWidgetType::DropdownMenu, WindowColour::Secondary, STR_NONE, STR_SELECT_CLIMATE_TIP ),
|
|
MakeWidget ({383, 100}, { 11, 10}, WindowWidgetType::Button, WindowColour::Secondary, STR_DROPDOWN_GLYPH, STR_SELECT_CLIMATE_TIP ),
|
|
MakeWidget ({ 8, 116}, {WW_PARK - 16, 12}, WindowWidgetType::Checkbox, WindowColour::Secondary, STR_FORBID_TREE_REMOVAL, STR_FORBID_TREE_REMOVAL_TIP ),
|
|
MakeWidget ({ 8, 133}, {WW_PARK - 16, 12}, WindowWidgetType::Checkbox, WindowColour::Secondary, STR_FORBID_LANDSCAPE_CHANGES, STR_FORBID_LANDSCAPE_CHANGES_TIP ),
|
|
MakeWidget ({ 8, 150}, {WW_PARK - 16, 12}, WindowWidgetType::Checkbox, WindowColour::Secondary, STR_FORBID_HIGH_CONSTRUCTION, STR_FORBID_HIGH_CONSTRUCTION_TIP ),
|
|
MakeWidget ({ 8, 167}, {WW_PARK - 16, 12}, WindowWidgetType::Checkbox, WindowColour::Secondary, STR_HARD_PARK_RATING, STR_HARD_PARK_RATING_TIP ),
|
|
MakeWidget ({ 8, 184}, {WW_PARK - 16, 12}, WindowWidgetType::Checkbox, WindowColour::Secondary, STR_HARD_GUEST_GENERATION, STR_HARD_GUEST_GENERATION_TIP ),
|
|
kWidgetsEnd,
|
|
};
|
|
|
|
static Widget *window_editor_scenario_options_widgets[] = {
|
|
window_editor_scenario_options_financial_widgets,
|
|
window_editor_scenario_options_guests_widgets,
|
|
window_editor_scenario_options_park_widgets,
|
|
};
|
|
|
|
#pragma endregion
|
|
|
|
#pragma region Enabled widgets
|
|
|
|
static uint32_t window_editor_scenario_options_page_hold_down_widgets[] = {
|
|
(1uLL << WIDX_INITIAL_CASH_INCREASE) |
|
|
(1uLL << WIDX_INITIAL_CASH_DECREASE) |
|
|
(1uLL << WIDX_INITIAL_LOAN_INCREASE) |
|
|
(1uLL << WIDX_INITIAL_LOAN_DECREASE) |
|
|
(1uLL << WIDX_MAXIMUM_LOAN_INCREASE) |
|
|
(1uLL << WIDX_MAXIMUM_LOAN_DECREASE) |
|
|
(1uLL << WIDX_INTEREST_RATE_INCREASE) |
|
|
(1uLL << WIDX_INTEREST_RATE_DECREASE),
|
|
(1uLL << WIDX_CASH_PER_GUEST_INCREASE) |
|
|
(1uLL << WIDX_CASH_PER_GUEST_DECREASE) |
|
|
(1uLL << WIDX_GUEST_INITIAL_HAPPINESS_INCREASE) |
|
|
(1uLL << WIDX_GUEST_INITIAL_HAPPINESS_DECREASE) |
|
|
(1uLL << WIDX_GUEST_INITIAL_HUNGER_INCREASE) |
|
|
(1uLL << WIDX_GUEST_INITIAL_HUNGER_DECREASE) |
|
|
(1uLL << WIDX_GUEST_INITIAL_THIRST_INCREASE) |
|
|
(1uLL << WIDX_GUEST_INITIAL_THIRST_DECREASE),
|
|
(1uLL << WIDX_LAND_COST_INCREASE) |
|
|
(1uLL << WIDX_LAND_COST_DECREASE) |
|
|
(1uLL << WIDX_CONSTRUCTION_RIGHTS_COST_INCREASE) |
|
|
(1uLL << WIDX_CONSTRUCTION_RIGHTS_COST_DECREASE) |
|
|
(1uLL << WIDX_ENTRY_PRICE_INCREASE) |
|
|
(1uLL << WIDX_ENTRY_PRICE_DECREASE),
|
|
};
|
|
// clang-format on
|
|
|
|
#pragma endregion
|
|
|
|
class EditorScenarioOptionsWindow final : public Window
|
|
{
|
|
public:
|
|
void OnOpen() override
|
|
{
|
|
widgets = window_editor_scenario_options_widgets[WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_FINANCIAL];
|
|
hold_down_widgets = window_editor_scenario_options_page_hold_down_widgets
|
|
[WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_FINANCIAL];
|
|
WindowInitScrollWidgets(*this);
|
|
page = 0;
|
|
}
|
|
|
|
void OnMouseUp(WidgetIndex widgetIndex) override
|
|
{
|
|
switch (page)
|
|
{
|
|
case WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_FINANCIAL:
|
|
return FinancialMouseUp(widgetIndex);
|
|
case WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_GUESTS:
|
|
return GuestsMouseUp(widgetIndex);
|
|
case WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_PARK:
|
|
return ParkMouseUp(widgetIndex);
|
|
}
|
|
}
|
|
|
|
void OnResize() override
|
|
{
|
|
switch (page)
|
|
{
|
|
case WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_FINANCIAL:
|
|
return FinancialResize();
|
|
case WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_GUESTS:
|
|
return GuestsResize();
|
|
case WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_PARK:
|
|
return ParkResize();
|
|
}
|
|
}
|
|
|
|
void OnMouseDown(WidgetIndex widgetIndex) override
|
|
{
|
|
switch (page)
|
|
{
|
|
case WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_FINANCIAL:
|
|
return FinancialMouseDown(widgetIndex);
|
|
case WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_GUESTS:
|
|
return GuestsMouseDown(widgetIndex);
|
|
case WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_PARK:
|
|
return ParkMouseDown(widgetIndex);
|
|
}
|
|
}
|
|
|
|
void OnUpdate() override
|
|
{
|
|
switch (page)
|
|
{
|
|
case WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_FINANCIAL:
|
|
return FinancialUpdate();
|
|
case WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_GUESTS:
|
|
return GuestsUpdate();
|
|
case WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_PARK:
|
|
return ParkUpdate();
|
|
}
|
|
}
|
|
|
|
void OnPrepareDraw() override
|
|
{
|
|
switch (page)
|
|
{
|
|
case WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_FINANCIAL:
|
|
return FinancialPrepareDraw();
|
|
case WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_GUESTS:
|
|
return GuestsPrepareDraw();
|
|
case WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_PARK:
|
|
return ParkPrepareDraw();
|
|
}
|
|
}
|
|
|
|
void OnDraw(DrawPixelInfo& dpi) override
|
|
{
|
|
switch (page)
|
|
{
|
|
case WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_FINANCIAL:
|
|
return FinancialDraw(dpi);
|
|
case WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_GUESTS:
|
|
return GuestsDraw(dpi);
|
|
case WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_PARK:
|
|
return ParkDraw(dpi);
|
|
}
|
|
}
|
|
|
|
void OnDropdown(WidgetIndex widgetIndex, int32_t selectedIndex) override
|
|
{
|
|
switch (page)
|
|
{
|
|
case WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_PARK:
|
|
return ParkDropdown(widgetIndex, selectedIndex);
|
|
}
|
|
}
|
|
|
|
private:
|
|
void SetPressedTab()
|
|
{
|
|
int32_t i;
|
|
for (i = 0; i < WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_COUNT; i++)
|
|
SetWidgetPressed(WIDX_TAB_1 + i, false);
|
|
SetWidgetPressed(WIDX_TAB_1 + page, true);
|
|
}
|
|
|
|
void AnchorBorderWidgets()
|
|
{
|
|
ResizeFrameWithPage();
|
|
}
|
|
|
|
void DrawTabImages(DrawPixelInfo& dpi)
|
|
{
|
|
Widget* widget;
|
|
int32_t spriteIndex;
|
|
|
|
// Tab 1
|
|
widget = &widgets[WIDX_TAB_1];
|
|
spriteIndex = SPR_TAB_FINANCES_SUMMARY_0;
|
|
if (page == WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_FINANCIAL)
|
|
spriteIndex += (frame_no / 2) % 8;
|
|
|
|
GfxDrawSprite(dpi, ImageId(spriteIndex), windowPos + ScreenCoordsXY{ widget->left, widget->top });
|
|
|
|
// Tab 2
|
|
widget = &widgets[WIDX_TAB_2];
|
|
spriteIndex = SPR_TAB_GUESTS_0;
|
|
if (page == WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_GUESTS)
|
|
spriteIndex += (frame_no / 4) % 8;
|
|
|
|
GfxDrawSprite(dpi, ImageId(spriteIndex), windowPos + ScreenCoordsXY{ widget->left, widget->top });
|
|
|
|
// Tab 3
|
|
widget = &widgets[WIDX_TAB_3];
|
|
spriteIndex = SPR_TAB_PARK;
|
|
GfxDrawSprite(dpi, ImageId(spriteIndex), windowPos + ScreenCoordsXY{ widget->left, widget->top });
|
|
}
|
|
|
|
void SetPage(int32_t newPage)
|
|
{
|
|
if (page == newPage)
|
|
return;
|
|
|
|
page = newPage;
|
|
frame_no = 0;
|
|
hold_down_widgets = window_editor_scenario_options_page_hold_down_widgets[page];
|
|
widgets = window_editor_scenario_options_widgets[page];
|
|
Invalidate();
|
|
OnResize();
|
|
OnPrepareDraw();
|
|
WindowInitScrollWidgets(*this);
|
|
Invalidate();
|
|
}
|
|
|
|
#pragma region Financial
|
|
|
|
void FinancialMouseUp(WidgetIndex widgetIndex)
|
|
{
|
|
auto& gameState = GetGameState();
|
|
switch (widgetIndex)
|
|
{
|
|
case WIDX_CLOSE:
|
|
WindowClose(*this);
|
|
break;
|
|
case WIDX_TAB_1:
|
|
case WIDX_TAB_2:
|
|
case WIDX_TAB_3:
|
|
SetPage(widgetIndex - WIDX_TAB_1);
|
|
break;
|
|
case WIDX_NO_MONEY:
|
|
{
|
|
auto newMoneySetting = (gameState.Park.Flags & PARK_FLAGS_NO_MONEY) ? 0 : 1;
|
|
auto scenarioSetSetting = ScenarioSetSettingAction(ScenarioSetSetting::NoMoney, newMoneySetting);
|
|
GameActions::Execute(&scenarioSetSetting);
|
|
Invalidate();
|
|
break;
|
|
}
|
|
case WIDX_FORBID_MARKETING:
|
|
{
|
|
auto scenarioSetSetting = ScenarioSetSettingAction(
|
|
ScenarioSetSetting::ForbidMarketingCampaigns,
|
|
gameState.Park.Flags & PARK_FLAGS_FORBID_MARKETING_CAMPAIGN ? 0 : 1);
|
|
GameActions::Execute(&scenarioSetSetting);
|
|
Invalidate();
|
|
break;
|
|
}
|
|
case WIDX_RCT1_INTEREST:
|
|
{
|
|
auto scenarioSetSetting = ScenarioSetSettingAction(
|
|
ScenarioSetSetting::UseRCT1Interest, gameState.Park.Flags & PARK_FLAGS_RCT1_INTEREST ? 0 : 1);
|
|
GameActions::Execute(&scenarioSetSetting);
|
|
Invalidate();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void FinancialResize()
|
|
{
|
|
WindowSetResize(*this, 280, 149, 280, 149);
|
|
}
|
|
|
|
void ShowClimateDropdown()
|
|
{
|
|
int32_t i;
|
|
|
|
const auto& dropdownWidget = widgets[WIDX_CLIMATE];
|
|
|
|
for (i = 0; i < static_cast<uint8_t>(ClimateType::Count); i++)
|
|
{
|
|
gDropdownItems[i].Format = STR_DROPDOWN_MENU_LABEL;
|
|
gDropdownItems[i].Args = ClimateNames[i];
|
|
}
|
|
WindowDropdownShowTextCustomWidth(
|
|
{ windowPos.x + dropdownWidget.left, windowPos.y + dropdownWidget.top }, dropdownWidget.height() + 1,
|
|
colours[1], 0, Dropdown::Flag::StayOpen, static_cast<uint8_t>(ClimateType::Count), dropdownWidget.width() - 3);
|
|
Dropdown::SetChecked(static_cast<uint8_t>(GetGameState().Climate), true);
|
|
}
|
|
|
|
void FinancialMouseDown(WidgetIndex widgetIndex)
|
|
{
|
|
auto& gameState = GetGameState();
|
|
switch (widgetIndex)
|
|
{
|
|
case WIDX_INITIAL_CASH_INCREASE:
|
|
if (gameState.InitialCash < 1000000.00_GBP)
|
|
{
|
|
auto scenarioSetSetting = ScenarioSetSettingAction(
|
|
ScenarioSetSetting::InitialCash, gameState.InitialCash + 500.00_GBP);
|
|
GameActions::Execute(&scenarioSetSetting);
|
|
}
|
|
else
|
|
{
|
|
ContextShowError(STR_CANT_INCREASE_CASH, STR_NONE, {});
|
|
}
|
|
Invalidate();
|
|
break;
|
|
case WIDX_INITIAL_CASH_DECREASE:
|
|
if (gameState.InitialCash > 0.00_GBP)
|
|
{
|
|
auto scenarioSetSetting = ScenarioSetSettingAction(
|
|
ScenarioSetSetting::InitialCash, gameState.InitialCash - 500.00_GBP);
|
|
GameActions::Execute(&scenarioSetSetting);
|
|
}
|
|
else
|
|
{
|
|
ContextShowError(STR_CANT_REDUCE_CASH, STR_NONE, {});
|
|
}
|
|
Invalidate();
|
|
break;
|
|
case WIDX_INITIAL_LOAN_INCREASE:
|
|
if (gameState.BankLoan < 5000000.00_GBP)
|
|
{
|
|
auto scenarioSetSetting = ScenarioSetSettingAction(
|
|
ScenarioSetSetting::InitialLoan, gameState.BankLoan + 1000.00_GBP);
|
|
GameActions::Execute(&scenarioSetSetting);
|
|
}
|
|
else
|
|
{
|
|
ContextShowError(STR_CANT_INCREASE_INIT_LOAN, STR_NONE, {});
|
|
}
|
|
Invalidate();
|
|
break;
|
|
case WIDX_INITIAL_LOAN_DECREASE:
|
|
if (gameState.BankLoan > 0.00_GBP)
|
|
{
|
|
auto scenarioSetSetting = ScenarioSetSettingAction(
|
|
ScenarioSetSetting::InitialLoan, gameState.BankLoan - 1000.00_GBP);
|
|
GameActions::Execute(&scenarioSetSetting);
|
|
}
|
|
else
|
|
{
|
|
ContextShowError(STR_CANT_REDUCE_INIT_LOAN, STR_NONE, {});
|
|
}
|
|
Invalidate();
|
|
break;
|
|
case WIDX_MAXIMUM_LOAN_INCREASE:
|
|
if (gameState.MaxBankLoan < 5000000.00_GBP)
|
|
{
|
|
auto scenarioSetSetting = ScenarioSetSettingAction(
|
|
ScenarioSetSetting::MaximumLoanSize, gameState.MaxBankLoan + 1000.00_GBP);
|
|
GameActions::Execute(&scenarioSetSetting);
|
|
}
|
|
else
|
|
{
|
|
ContextShowError(STR_CANT_INCREASE_MAX_LOAN, STR_NONE, {});
|
|
}
|
|
Invalidate();
|
|
break;
|
|
case WIDX_MAXIMUM_LOAN_DECREASE:
|
|
if (gameState.MaxBankLoan > 0.00_GBP)
|
|
{
|
|
auto scenarioSetSetting = ScenarioSetSettingAction(
|
|
ScenarioSetSetting::MaximumLoanSize, gameState.MaxBankLoan - 1000.00_GBP);
|
|
GameActions::Execute(&scenarioSetSetting);
|
|
}
|
|
else
|
|
{
|
|
ContextShowError(STR_CANT_REDUCE_MAX_LOAN, STR_NONE, {});
|
|
}
|
|
Invalidate();
|
|
break;
|
|
case WIDX_INTEREST_RATE_INCREASE:
|
|
if (gameState.BankLoanInterestRate < MaxBankLoanInterestRate)
|
|
{
|
|
auto scenarioSetSetting = ScenarioSetSettingAction(
|
|
ScenarioSetSetting::AnnualInterestRate, gameState.BankLoanInterestRate + 1);
|
|
GameActions::Execute(&scenarioSetSetting);
|
|
}
|
|
else
|
|
{
|
|
ContextShowError(STR_CANT_INCREASE_INTEREST_RATE, STR_NONE, {});
|
|
}
|
|
Invalidate();
|
|
break;
|
|
case WIDX_INTEREST_RATE_DECREASE:
|
|
if (gameState.BankLoanInterestRate > 0)
|
|
{
|
|
auto interest = std::min<uint8_t>(MaxBankLoanInterestRate, gameState.BankLoanInterestRate - 1);
|
|
auto scenarioSetSetting = ScenarioSetSettingAction(ScenarioSetSetting::AnnualInterestRate, interest);
|
|
GameActions::Execute(&scenarioSetSetting);
|
|
}
|
|
else
|
|
{
|
|
ContextShowError(STR_CANT_REDUCE_INTEREST_RATE, STR_NONE, {});
|
|
}
|
|
Invalidate();
|
|
break;
|
|
}
|
|
|
|
if (gScreenFlags == SCREEN_FLAGS_PLAYING)
|
|
{
|
|
WindowInvalidateByClass(WindowClass::Finances);
|
|
WindowInvalidateByClass(WindowClass::BottomToolbar);
|
|
}
|
|
}
|
|
|
|
void FinancialUpdate()
|
|
{
|
|
frame_no++;
|
|
FinancialPrepareDraw();
|
|
WidgetInvalidate(*this, WIDX_TAB_1);
|
|
}
|
|
|
|
void FinancialPrepareDraw()
|
|
{
|
|
Widget* newWidgets = window_editor_scenario_options_widgets[page];
|
|
if (widgets != newWidgets)
|
|
{
|
|
widgets = newWidgets;
|
|
WindowInitScrollWidgets(*this);
|
|
}
|
|
|
|
SetPressedTab();
|
|
|
|
auto& gameState = GetGameState();
|
|
if (gameState.Park.Flags & PARK_FLAGS_NO_MONEY)
|
|
{
|
|
SetWidgetPressed(WIDX_NO_MONEY, true);
|
|
for (int32_t i = WIDX_INITIAL_CASH; i <= WIDX_RCT1_INTEREST; i++)
|
|
widgets[i].type = WindowWidgetType::Empty;
|
|
}
|
|
else
|
|
{
|
|
SetWidgetPressed(WIDX_NO_MONEY, false);
|
|
widgets[WIDX_INITIAL_CASH].type = WindowWidgetType::Spinner;
|
|
widgets[WIDX_INITIAL_CASH_INCREASE].type = WindowWidgetType::Button;
|
|
widgets[WIDX_INITIAL_CASH_DECREASE].type = WindowWidgetType::Button;
|
|
widgets[WIDX_INITIAL_LOAN].type = WindowWidgetType::Spinner;
|
|
widgets[WIDX_INITIAL_LOAN_INCREASE].type = WindowWidgetType::Button;
|
|
widgets[WIDX_INITIAL_LOAN_DECREASE].type = WindowWidgetType::Button;
|
|
widgets[WIDX_MAXIMUM_LOAN].type = WindowWidgetType::Spinner;
|
|
widgets[WIDX_MAXIMUM_LOAN_INCREASE].type = WindowWidgetType::Button;
|
|
widgets[WIDX_MAXIMUM_LOAN_DECREASE].type = WindowWidgetType::Button;
|
|
widgets[WIDX_FORBID_MARKETING].type = WindowWidgetType::Checkbox;
|
|
|
|
if (gameState.Park.Flags & PARK_FLAGS_RCT1_INTEREST)
|
|
{
|
|
widgets[WIDX_INTEREST_RATE].type = WindowWidgetType::Empty;
|
|
widgets[WIDX_INTEREST_RATE_INCREASE].type = WindowWidgetType::Empty;
|
|
widgets[WIDX_INTEREST_RATE_DECREASE].type = WindowWidgetType::Empty;
|
|
widgets[WIDX_RCT1_INTEREST].type = WindowWidgetType::Checkbox;
|
|
SetWidgetPressed(WIDX_RCT1_INTEREST, true);
|
|
}
|
|
else
|
|
{
|
|
widgets[WIDX_INTEREST_RATE].type = WindowWidgetType::Spinner;
|
|
widgets[WIDX_INTEREST_RATE_INCREASE].type = WindowWidgetType::Button;
|
|
widgets[WIDX_INTEREST_RATE_DECREASE].type = WindowWidgetType::Button;
|
|
widgets[WIDX_RCT1_INTEREST].type = WindowWidgetType::Empty;
|
|
}
|
|
}
|
|
|
|
SetWidgetPressed(WIDX_FORBID_MARKETING, gameState.Park.Flags & PARK_FLAGS_FORBID_MARKETING_CAMPAIGN);
|
|
|
|
widgets[WIDX_CLOSE].type = (gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) ? WindowWidgetType::Empty
|
|
: WindowWidgetType::CloseBox;
|
|
|
|
AnchorBorderWidgets();
|
|
}
|
|
|
|
void FinancialDraw(DrawPixelInfo& dpi)
|
|
{
|
|
ScreenCoordsXY screenCoords{};
|
|
|
|
WindowDrawWidgets(*this, dpi);
|
|
DrawTabImages(dpi);
|
|
|
|
auto& gameState = GetGameState();
|
|
|
|
const auto& initialCashWidget = widgets[WIDX_INITIAL_CASH];
|
|
if (initialCashWidget.type != WindowWidgetType::Empty)
|
|
{
|
|
screenCoords = windowPos + ScreenCoordsXY{ 8, initialCashWidget.top };
|
|
DrawTextBasic(dpi, screenCoords, STR_INIT_CASH_LABEL);
|
|
|
|
screenCoords = windowPos + ScreenCoordsXY{ initialCashWidget.left + 1, initialCashWidget.top };
|
|
auto ft = Formatter();
|
|
ft.Add<money64>(GetGameState().InitialCash);
|
|
DrawTextBasic(dpi, screenCoords, STR_CURRENCY_FORMAT_LABEL, ft);
|
|
}
|
|
|
|
const auto& initialLoanWidget = widgets[WIDX_INITIAL_LOAN];
|
|
if (initialLoanWidget.type != WindowWidgetType::Empty)
|
|
{
|
|
screenCoords = windowPos + ScreenCoordsXY{ 8, initialLoanWidget.top };
|
|
DrawTextBasic(dpi, screenCoords, STR_INIT_LOAN_LABEL);
|
|
|
|
screenCoords = windowPos + ScreenCoordsXY{ initialLoanWidget.left + 1, initialLoanWidget.top };
|
|
auto ft = Formatter();
|
|
ft.Add<money64>(gameState.BankLoan);
|
|
DrawTextBasic(dpi, screenCoords, STR_CURRENCY_FORMAT_LABEL, ft);
|
|
}
|
|
|
|
const auto& maximumLoanWidget = widgets[WIDX_MAXIMUM_LOAN];
|
|
if (maximumLoanWidget.type != WindowWidgetType::Empty)
|
|
{
|
|
screenCoords = windowPos + ScreenCoordsXY{ 8, maximumLoanWidget.top };
|
|
DrawTextBasic(dpi, screenCoords, STR_MAX_LOAN_LABEL);
|
|
|
|
screenCoords = windowPos + ScreenCoordsXY{ maximumLoanWidget.left + 1, maximumLoanWidget.top };
|
|
auto ft = Formatter();
|
|
ft.Add<money64>(GetGameState().MaxBankLoan);
|
|
DrawTextBasic(dpi, screenCoords, STR_CURRENCY_FORMAT_LABEL, ft);
|
|
}
|
|
|
|
const auto& interestRateWidget = widgets[WIDX_INTEREST_RATE];
|
|
if (interestRateWidget.type != WindowWidgetType::Empty)
|
|
{
|
|
screenCoords = windowPos + ScreenCoordsXY{ 8, interestRateWidget.top };
|
|
DrawTextBasic(dpi, screenCoords, STR_INTEREST_RATE_LABEL);
|
|
|
|
screenCoords = windowPos + ScreenCoordsXY{ interestRateWidget.left + 1, interestRateWidget.top };
|
|
|
|
auto ft = Formatter();
|
|
ft.Add<int16_t>(
|
|
std::clamp<int16_t>(static_cast<int16_t>(gameState.BankLoanInterestRate), INT16_MIN, INT16_MAX));
|
|
DrawTextBasic(dpi, screenCoords, STR_PERCENT_FORMAT_LABEL, ft);
|
|
}
|
|
}
|
|
|
|
#pragma endregion
|
|
|
|
#pragma region Guests
|
|
|
|
void GuestsMouseUp(WidgetIndex widgetIndex)
|
|
{
|
|
auto& gameState = GetGameState();
|
|
switch (widgetIndex)
|
|
{
|
|
case WIDX_CLOSE:
|
|
WindowClose(*this);
|
|
break;
|
|
case WIDX_TAB_1:
|
|
case WIDX_TAB_2:
|
|
case WIDX_TAB_3:
|
|
SetPage(widgetIndex - WIDX_TAB_1);
|
|
break;
|
|
case WIDX_GUEST_PREFER_LESS_INTENSE_RIDES:
|
|
{
|
|
auto scenarioSetSetting = ScenarioSetSettingAction(
|
|
ScenarioSetSetting::GuestsPreferLessIntenseRides,
|
|
gameState.Park.Flags & PARK_FLAGS_PREF_LESS_INTENSE_RIDES ? 0 : 1);
|
|
GameActions::Execute(&scenarioSetSetting);
|
|
Invalidate();
|
|
break;
|
|
}
|
|
case WIDX_GUEST_PREFER_MORE_INTENSE_RIDES:
|
|
{
|
|
auto scenarioSetSetting = ScenarioSetSettingAction(
|
|
ScenarioSetSetting::GuestsPreferMoreIntenseRides,
|
|
gameState.Park.Flags & PARK_FLAGS_PREF_MORE_INTENSE_RIDES ? 0 : 1);
|
|
GameActions::Execute(&scenarioSetSetting);
|
|
Invalidate();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void GuestsResize()
|
|
{
|
|
WindowSetResize(*this, 380, 149, 380, 149);
|
|
}
|
|
|
|
void GuestsMouseDown(WidgetIndex widgetIndex)
|
|
{
|
|
auto& gameState = GetGameState();
|
|
|
|
switch (widgetIndex)
|
|
{
|
|
case WIDX_CASH_PER_GUEST_INCREASE:
|
|
if (gameState.GuestInitialCash < 1000.00_GBP)
|
|
{
|
|
auto scenarioSetSetting = ScenarioSetSettingAction(
|
|
ScenarioSetSetting::AverageCashPerGuest, gameState.GuestInitialCash + 1.00_GBP);
|
|
GameActions::Execute(&scenarioSetSetting);
|
|
}
|
|
else
|
|
{
|
|
ContextShowError(STR_CANT_INCREASE_FURTHER, STR_NONE, {});
|
|
}
|
|
Invalidate();
|
|
break;
|
|
case WIDX_CASH_PER_GUEST_DECREASE:
|
|
if (gameState.GuestInitialCash > 0.00_GBP)
|
|
{
|
|
auto scenarioSetSetting = ScenarioSetSettingAction(
|
|
ScenarioSetSetting::AverageCashPerGuest, gameState.GuestInitialCash - 1.00_GBP);
|
|
GameActions::Execute(&scenarioSetSetting);
|
|
}
|
|
else
|
|
{
|
|
ContextShowError(STR_CANT_REDUCE_FURTHER, STR_NONE, {});
|
|
}
|
|
Invalidate();
|
|
break;
|
|
case WIDX_GUEST_INITIAL_HAPPINESS_INCREASE:
|
|
if (gameState.GuestInitialHappiness < 250)
|
|
{
|
|
auto scenarioSetSetting = ScenarioSetSettingAction(
|
|
ScenarioSetSetting::GuestInitialHappiness, gameState.GuestInitialHappiness + 4);
|
|
GameActions::Execute(&scenarioSetSetting);
|
|
}
|
|
else
|
|
{
|
|
ContextShowError(STR_CANT_INCREASE_FURTHER, STR_NONE, {});
|
|
}
|
|
Invalidate();
|
|
break;
|
|
case WIDX_GUEST_INITIAL_HAPPINESS_DECREASE:
|
|
if (gameState.GuestInitialHappiness > 40)
|
|
{
|
|
auto scenarioSetSetting = ScenarioSetSettingAction(
|
|
ScenarioSetSetting::GuestInitialHappiness, gameState.GuestInitialHappiness - 4);
|
|
GameActions::Execute(&scenarioSetSetting);
|
|
}
|
|
else
|
|
{
|
|
ContextShowError(STR_CANT_REDUCE_FURTHER, STR_NONE, {});
|
|
}
|
|
Invalidate();
|
|
break;
|
|
case WIDX_GUEST_INITIAL_HUNGER_INCREASE:
|
|
if (gameState.GuestInitialHunger > 40)
|
|
{
|
|
auto scenarioSetSetting = ScenarioSetSettingAction(
|
|
ScenarioSetSetting::GuestInitialHunger, gameState.GuestInitialHunger - 4);
|
|
GameActions::Execute(&scenarioSetSetting);
|
|
}
|
|
else
|
|
{
|
|
ContextShowError(STR_CANT_INCREASE_FURTHER, STR_NONE, {});
|
|
}
|
|
Invalidate();
|
|
break;
|
|
case WIDX_GUEST_INITIAL_HUNGER_DECREASE:
|
|
if (gameState.GuestInitialHunger < 250)
|
|
{
|
|
auto scenarioSetSetting = ScenarioSetSettingAction(
|
|
ScenarioSetSetting::GuestInitialHunger, gameState.GuestInitialHunger + 4);
|
|
GameActions::Execute(&scenarioSetSetting);
|
|
}
|
|
else
|
|
{
|
|
ContextShowError(STR_CANT_REDUCE_FURTHER, STR_NONE, {});
|
|
}
|
|
Invalidate();
|
|
break;
|
|
case WIDX_GUEST_INITIAL_THIRST_INCREASE:
|
|
if (gameState.GuestInitialThirst > 40)
|
|
{
|
|
auto scenarioSetSetting = ScenarioSetSettingAction(
|
|
ScenarioSetSetting::GuestInitialThirst, gameState.GuestInitialThirst - 4);
|
|
GameActions::Execute(&scenarioSetSetting);
|
|
}
|
|
else
|
|
{
|
|
ContextShowError(STR_CANT_INCREASE_FURTHER, STR_NONE, {});
|
|
}
|
|
Invalidate();
|
|
break;
|
|
case WIDX_GUEST_INITIAL_THIRST_DECREASE:
|
|
if (gameState.GuestInitialThirst < 250)
|
|
{
|
|
auto scenarioSetSetting = ScenarioSetSettingAction(
|
|
ScenarioSetSetting::GuestInitialThirst, gameState.GuestInitialThirst + 4);
|
|
GameActions::Execute(&scenarioSetSetting);
|
|
}
|
|
else
|
|
{
|
|
ContextShowError(STR_CANT_REDUCE_FURTHER, STR_NONE, {});
|
|
}
|
|
Invalidate();
|
|
break;
|
|
}
|
|
}
|
|
|
|
void GuestsUpdate()
|
|
{
|
|
frame_no++;
|
|
GuestsPrepareDraw();
|
|
WidgetInvalidate(*this, WIDX_TAB_2);
|
|
}
|
|
|
|
void GuestsPrepareDraw()
|
|
{
|
|
Widget* newWidgets = window_editor_scenario_options_widgets[page];
|
|
if (widgets != newWidgets)
|
|
{
|
|
widgets = newWidgets;
|
|
WindowInitScrollWidgets(*this);
|
|
}
|
|
|
|
SetPressedTab();
|
|
|
|
auto& gameState = GetGameState();
|
|
if (gameState.Park.Flags & PARK_FLAGS_NO_MONEY)
|
|
{
|
|
widgets[WIDX_CASH_PER_GUEST].type = WindowWidgetType::Empty;
|
|
widgets[WIDX_CASH_PER_GUEST_INCREASE].type = WindowWidgetType::Empty;
|
|
widgets[WIDX_CASH_PER_GUEST_DECREASE].type = WindowWidgetType::Empty;
|
|
}
|
|
else
|
|
{
|
|
widgets[WIDX_CASH_PER_GUEST].type = WindowWidgetType::Spinner;
|
|
widgets[WIDX_CASH_PER_GUEST_INCREASE].type = WindowWidgetType::Button;
|
|
widgets[WIDX_CASH_PER_GUEST_DECREASE].type = WindowWidgetType::Button;
|
|
}
|
|
|
|
SetWidgetPressed(WIDX_GUEST_PREFER_LESS_INTENSE_RIDES, gameState.Park.Flags & PARK_FLAGS_PREF_LESS_INTENSE_RIDES);
|
|
SetWidgetPressed(WIDX_GUEST_PREFER_MORE_INTENSE_RIDES, gameState.Park.Flags & PARK_FLAGS_PREF_MORE_INTENSE_RIDES);
|
|
|
|
widgets[WIDX_CLOSE].type = (gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) ? WindowWidgetType::Empty
|
|
: WindowWidgetType::CloseBox;
|
|
|
|
AnchorBorderWidgets();
|
|
}
|
|
|
|
void GuestsDraw(DrawPixelInfo& dpi)
|
|
{
|
|
ScreenCoordsXY screenCoords{};
|
|
|
|
WindowDrawWidgets(*this, dpi);
|
|
DrawTabImages(dpi);
|
|
auto& gameState = GetGameState();
|
|
|
|
const auto& cashPerGuestWidget = widgets[WIDX_CASH_PER_GUEST];
|
|
if (cashPerGuestWidget.type != WindowWidgetType::Empty)
|
|
{
|
|
// Cash per guest label
|
|
screenCoords = windowPos + ScreenCoordsXY{ 8, cashPerGuestWidget.top };
|
|
DrawTextBasic(dpi, screenCoords, STR_CASH_PER_GUEST_LABEL);
|
|
|
|
// Cash per guest value
|
|
screenCoords = windowPos + ScreenCoordsXY{ cashPerGuestWidget.left + 1, cashPerGuestWidget.top };
|
|
auto ft = Formatter();
|
|
ft.Add<money64>(gameState.GuestInitialCash);
|
|
DrawTextBasic(dpi, screenCoords, STR_CURRENCY_FORMAT_LABEL, ft);
|
|
}
|
|
|
|
// Guest initial happiness label
|
|
const auto& initialHappinessWidget = widgets[WIDX_GUEST_INITIAL_HAPPINESS];
|
|
screenCoords = windowPos + ScreenCoordsXY{ 8, initialHappinessWidget.top };
|
|
DrawTextBasic(dpi, screenCoords, STR_GUEST_INIT_HAPPINESS);
|
|
|
|
// Guest initial happiness value
|
|
screenCoords = windowPos + ScreenCoordsXY{ initialHappinessWidget.left + 1, initialHappinessWidget.top };
|
|
auto ft = Formatter();
|
|
ft.Add<uint16_t>((gameState.GuestInitialHappiness * 100) / 255);
|
|
DrawTextBasic(dpi, screenCoords, STR_PERCENT_FORMAT_LABEL, ft);
|
|
|
|
// Guest initial hunger label
|
|
const auto& initialHungerWidget = widgets[WIDX_GUEST_INITIAL_HUNGER];
|
|
screenCoords = windowPos + ScreenCoordsXY{ 8, initialHungerWidget.top };
|
|
DrawTextBasic(dpi, screenCoords, STR_GUEST_INIT_HUNGER);
|
|
|
|
// Guest initial hunger value
|
|
screenCoords = windowPos + ScreenCoordsXY{ initialHungerWidget.left + 1, initialHungerWidget.top };
|
|
ft = Formatter();
|
|
ft.Add<uint16_t>(((255 - gameState.GuestInitialHunger) * 100) / 255);
|
|
DrawTextBasic(dpi, screenCoords, STR_PERCENT_FORMAT_LABEL, ft);
|
|
|
|
// Guest initial thirst label
|
|
const auto& initialThirstWidget = widgets[WIDX_GUEST_INITIAL_THIRST];
|
|
screenCoords = windowPos + ScreenCoordsXY{ 8, initialThirstWidget.top };
|
|
DrawTextBasic(dpi, screenCoords, STR_GUEST_INIT_THIRST);
|
|
|
|
// Guest initial thirst value
|
|
screenCoords = windowPos + ScreenCoordsXY{ initialThirstWidget.left + 1, initialThirstWidget.top };
|
|
ft = Formatter();
|
|
ft.Add<uint16_t>(((255 - gameState.GuestInitialThirst) * 100) / 255);
|
|
DrawTextBasic(dpi, screenCoords, STR_PERCENT_FORMAT_LABEL, ft);
|
|
}
|
|
|
|
#pragma endregion
|
|
|
|
#pragma region Park
|
|
|
|
void ParkMouseUp(WidgetIndex widgetIndex)
|
|
{
|
|
auto& gameState = GetGameState();
|
|
switch (widgetIndex)
|
|
{
|
|
case WIDX_CLOSE:
|
|
WindowClose(*this);
|
|
break;
|
|
case WIDX_TAB_1:
|
|
case WIDX_TAB_2:
|
|
case WIDX_TAB_3:
|
|
SetPage(widgetIndex - WIDX_TAB_1);
|
|
break;
|
|
case WIDX_FORBID_TREE_REMOVAL:
|
|
{
|
|
auto scenarioSetSetting = ScenarioSetSettingAction(
|
|
ScenarioSetSetting::ForbidTreeRemoval, gameState.Park.Flags & PARK_FLAGS_FORBID_TREE_REMOVAL ? 0 : 1);
|
|
GameActions::Execute(&scenarioSetSetting);
|
|
Invalidate();
|
|
break;
|
|
}
|
|
case WIDX_FORBID_LANDSCAPE_CHANGES:
|
|
{
|
|
auto scenarioSetSetting = ScenarioSetSettingAction(
|
|
ScenarioSetSetting::ForbidLandscapeChanges,
|
|
gameState.Park.Flags & PARK_FLAGS_FORBID_LANDSCAPE_CHANGES ? 0 : 1);
|
|
GameActions::Execute(&scenarioSetSetting);
|
|
Invalidate();
|
|
break;
|
|
}
|
|
case WIDX_FORBID_HIGH_CONSTRUCTION:
|
|
{
|
|
auto scenarioSetSetting = ScenarioSetSettingAction(
|
|
ScenarioSetSetting::ForbidHighConstruction,
|
|
gameState.Park.Flags & PARK_FLAGS_FORBID_HIGH_CONSTRUCTION ? 0 : 1);
|
|
GameActions::Execute(&scenarioSetSetting);
|
|
Invalidate();
|
|
break;
|
|
}
|
|
case WIDX_HARD_PARK_RATING:
|
|
{
|
|
auto scenarioSetSetting = ScenarioSetSettingAction(
|
|
ScenarioSetSetting::ParkRatingHigherDifficultyLevel,
|
|
gameState.Park.Flags & PARK_FLAGS_DIFFICULT_PARK_RATING ? 0 : 1);
|
|
GameActions::Execute(&scenarioSetSetting);
|
|
Invalidate();
|
|
break;
|
|
}
|
|
case WIDX_HARD_GUEST_GENERATION:
|
|
{
|
|
auto scenarioSetSetting = ScenarioSetSettingAction(
|
|
ScenarioSetSetting::GuestGenerationHigherDifficultyLevel,
|
|
gameState.Park.Flags & PARK_FLAGS_DIFFICULT_GUEST_GENERATION ? 0 : 1);
|
|
GameActions::Execute(&scenarioSetSetting);
|
|
Invalidate();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void ParkResize()
|
|
{
|
|
WindowSetResize(*this, 400, 200, 400, 200);
|
|
}
|
|
|
|
void ParkMouseDown(WidgetIndex widgetIndex)
|
|
{
|
|
Widget* dropdownWidget;
|
|
Widget* widget = &widgets[widgetIndex];
|
|
|
|
auto& gameState = GetGameState();
|
|
switch (widgetIndex)
|
|
{
|
|
case WIDX_LAND_COST_INCREASE:
|
|
if (gameState.LandPrice < 200.00_GBP)
|
|
{
|
|
auto scenarioSetSetting = ScenarioSetSettingAction(
|
|
ScenarioSetSetting::CostToBuyLand, gameState.LandPrice + 1.00_GBP);
|
|
GameActions::Execute(&scenarioSetSetting);
|
|
}
|
|
else
|
|
{
|
|
ContextShowError(STR_CANT_INCREASE_FURTHER, STR_NONE, {});
|
|
}
|
|
Invalidate();
|
|
break;
|
|
case WIDX_LAND_COST_DECREASE:
|
|
if (gameState.LandPrice > 5.00_GBP)
|
|
{
|
|
auto scenarioSetSetting = ScenarioSetSettingAction(
|
|
ScenarioSetSetting::CostToBuyLand, gameState.LandPrice - 1.00_GBP);
|
|
GameActions::Execute(&scenarioSetSetting);
|
|
}
|
|
else
|
|
{
|
|
ContextShowError(STR_CANT_REDUCE_FURTHER, STR_NONE, {});
|
|
}
|
|
Invalidate();
|
|
break;
|
|
case WIDX_CONSTRUCTION_RIGHTS_COST_INCREASE:
|
|
if (gameState.ConstructionRightsPrice < 200.00_GBP)
|
|
{
|
|
auto scenarioSetSetting = ScenarioSetSettingAction(
|
|
ScenarioSetSetting::CostToBuyConstructionRights, gameState.ConstructionRightsPrice + 1.00_GBP);
|
|
GameActions::Execute(&scenarioSetSetting);
|
|
}
|
|
else
|
|
{
|
|
ContextShowError(STR_CANT_INCREASE_FURTHER, STR_NONE, {});
|
|
}
|
|
Invalidate();
|
|
break;
|
|
case WIDX_CONSTRUCTION_RIGHTS_COST_DECREASE:
|
|
if (gameState.ConstructionRightsPrice > 5.00_GBP)
|
|
{
|
|
auto scenarioSetSetting = ScenarioSetSettingAction(
|
|
ScenarioSetSetting::CostToBuyConstructionRights, gameState.ConstructionRightsPrice - 1.00_GBP);
|
|
GameActions::Execute(&scenarioSetSetting);
|
|
}
|
|
else
|
|
{
|
|
ContextShowError(STR_CANT_REDUCE_FURTHER, STR_NONE, {});
|
|
}
|
|
Invalidate();
|
|
break;
|
|
case WIDX_ENTRY_PRICE_INCREASE:
|
|
if (gameState.Park.EntranceFee < MAX_ENTRANCE_FEE)
|
|
{
|
|
auto scenarioSetSetting = ScenarioSetSettingAction(
|
|
ScenarioSetSetting::ParkChargeEntryFee, gameState.Park.EntranceFee + 1.00_GBP);
|
|
GameActions::Execute(&scenarioSetSetting);
|
|
}
|
|
else
|
|
{
|
|
ContextShowError(STR_CANT_INCREASE_FURTHER, STR_NONE, {});
|
|
}
|
|
Invalidate();
|
|
break;
|
|
case WIDX_ENTRY_PRICE_DECREASE:
|
|
if (gameState.Park.EntranceFee > 0.00_GBP)
|
|
{
|
|
auto scenarioSetSetting = ScenarioSetSettingAction(
|
|
ScenarioSetSetting::ParkChargeEntryFee, gameState.Park.EntranceFee - 1.00_GBP);
|
|
GameActions::Execute(&scenarioSetSetting);
|
|
}
|
|
else
|
|
{
|
|
ContextShowError(STR_CANT_REDUCE_FURTHER, STR_NONE, {});
|
|
}
|
|
Invalidate();
|
|
break;
|
|
case WIDX_PAY_FOR_PARK_OR_RIDES_DROPDOWN:
|
|
dropdownWidget = widget - 1;
|
|
|
|
gDropdownItems[0].Format = STR_DROPDOWN_MENU_LABEL;
|
|
gDropdownItems[0].Args = STR_FREE_PARK_ENTER;
|
|
gDropdownItems[1].Format = STR_DROPDOWN_MENU_LABEL;
|
|
gDropdownItems[1].Args = STR_PAY_PARK_ENTER;
|
|
gDropdownItems[2].Format = STR_DROPDOWN_MENU_LABEL;
|
|
gDropdownItems[2].Args = STR_PAID_ENTRY_PAID_RIDES;
|
|
|
|
WindowDropdownShowTextCustomWidth(
|
|
{ windowPos.x + dropdownWidget->left, windowPos.y + dropdownWidget->top }, dropdownWidget->height() - 1,
|
|
colours[1], 0, Dropdown::Flag::StayOpen, 3, dropdownWidget->width() - 3);
|
|
|
|
if (gameState.Park.Flags & PARK_FLAGS_UNLOCK_ALL_PRICES)
|
|
Dropdown::SetChecked(2, true);
|
|
else if (gameState.Park.Flags & PARK_FLAGS_PARK_FREE_ENTRY)
|
|
Dropdown::SetChecked(0, true);
|
|
else
|
|
Dropdown::SetChecked(1, true);
|
|
|
|
break;
|
|
case WIDX_CLIMATE_DROPDOWN:
|
|
ShowClimateDropdown();
|
|
break;
|
|
}
|
|
}
|
|
|
|
void ParkDropdown(WidgetIndex widgetIndex, int32_t dropdownIndex)
|
|
{
|
|
if (dropdownIndex == -1)
|
|
{
|
|
return;
|
|
}
|
|
|
|
switch (widgetIndex)
|
|
{
|
|
case WIDX_PAY_FOR_PARK_OR_RIDES_DROPDOWN:
|
|
{
|
|
auto scenarioSetSetting = ScenarioSetSettingAction(ScenarioSetSetting::ParkChargeMethod, dropdownIndex);
|
|
GameActions::Execute(&scenarioSetSetting);
|
|
Invalidate();
|
|
break;
|
|
}
|
|
case WIDX_CLIMATE_DROPDOWN:
|
|
if (static_cast<uint8_t>(GetGameState().Climate) != static_cast<uint8_t>(dropdownIndex))
|
|
{
|
|
auto gameAction = ClimateSetAction(ClimateType{ static_cast<uint8_t>(dropdownIndex) });
|
|
GameActions::Execute(&gameAction);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
void ParkUpdate()
|
|
{
|
|
frame_no++;
|
|
ParkPrepareDraw();
|
|
WidgetInvalidate(*this, WIDX_TAB_3);
|
|
}
|
|
|
|
void ParkPrepareDraw()
|
|
{
|
|
Widget* newWidgets = window_editor_scenario_options_widgets[page];
|
|
if (widgets != newWidgets)
|
|
{
|
|
widgets = newWidgets;
|
|
WindowInitScrollWidgets(*this);
|
|
}
|
|
|
|
SetPressedTab();
|
|
|
|
auto& gameState = GetGameState();
|
|
if (gameState.Park.Flags & PARK_FLAGS_NO_MONEY)
|
|
{
|
|
for (int32_t i = WIDX_LAND_COST; i <= WIDX_ENTRY_PRICE_DECREASE; i++)
|
|
widgets[i].type = WindowWidgetType::Empty;
|
|
}
|
|
else
|
|
{
|
|
widgets[WIDX_LAND_COST].type = WindowWidgetType::Spinner;
|
|
widgets[WIDX_LAND_COST_INCREASE].type = WindowWidgetType::Button;
|
|
widgets[WIDX_LAND_COST_DECREASE].type = WindowWidgetType::Button;
|
|
widgets[WIDX_CONSTRUCTION_RIGHTS_COST].type = WindowWidgetType::Spinner;
|
|
widgets[WIDX_CONSTRUCTION_RIGHTS_COST_INCREASE].type = WindowWidgetType::Button;
|
|
widgets[WIDX_CONSTRUCTION_RIGHTS_COST_DECREASE].type = WindowWidgetType::Button;
|
|
widgets[WIDX_PAY_FOR_PARK_OR_RIDES].type = WindowWidgetType::DropdownMenu;
|
|
widgets[WIDX_PAY_FOR_PARK_OR_RIDES_DROPDOWN].type = WindowWidgetType::Button;
|
|
|
|
if (!Park::EntranceFeeUnlocked())
|
|
{
|
|
widgets[WIDX_ENTRY_PRICE].type = WindowWidgetType::Empty;
|
|
widgets[WIDX_ENTRY_PRICE_INCREASE].type = WindowWidgetType::Empty;
|
|
widgets[WIDX_ENTRY_PRICE_DECREASE].type = WindowWidgetType::Empty;
|
|
}
|
|
else
|
|
{
|
|
widgets[WIDX_ENTRY_PRICE].type = WindowWidgetType::Spinner;
|
|
widgets[WIDX_ENTRY_PRICE_INCREASE].type = WindowWidgetType::Button;
|
|
widgets[WIDX_ENTRY_PRICE_DECREASE].type = WindowWidgetType::Button;
|
|
}
|
|
}
|
|
|
|
SetWidgetPressed(WIDX_FORBID_TREE_REMOVAL, gameState.Park.Flags & PARK_FLAGS_FORBID_TREE_REMOVAL);
|
|
SetWidgetPressed(WIDX_FORBID_LANDSCAPE_CHANGES, gameState.Park.Flags & PARK_FLAGS_FORBID_LANDSCAPE_CHANGES);
|
|
SetWidgetPressed(WIDX_FORBID_HIGH_CONSTRUCTION, gameState.Park.Flags & PARK_FLAGS_FORBID_HIGH_CONSTRUCTION);
|
|
SetWidgetPressed(WIDX_HARD_PARK_RATING, gameState.Park.Flags & PARK_FLAGS_DIFFICULT_PARK_RATING);
|
|
SetWidgetPressed(WIDX_HARD_GUEST_GENERATION, gameState.Park.Flags & PARK_FLAGS_DIFFICULT_GUEST_GENERATION);
|
|
|
|
widgets[WIDX_CLOSE].type = (gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) ? WindowWidgetType::Empty
|
|
: WindowWidgetType::CloseBox;
|
|
|
|
AnchorBorderWidgets();
|
|
}
|
|
|
|
void ParkDraw(DrawPixelInfo& dpi)
|
|
{
|
|
ScreenCoordsXY screenCoords{};
|
|
|
|
WindowDrawWidgets(*this, dpi);
|
|
DrawTabImages(dpi);
|
|
|
|
const auto& gameState = GetGameState();
|
|
const auto& landCostWidget = widgets[WIDX_LAND_COST];
|
|
if (landCostWidget.type != WindowWidgetType::Empty)
|
|
{
|
|
// Cost to buy land label
|
|
screenCoords = windowPos + ScreenCoordsXY{ 8, landCostWidget.top };
|
|
DrawTextBasic(dpi, screenCoords, STR_LAND_COST_LABEL);
|
|
|
|
// Cost to buy land value
|
|
screenCoords = windowPos + ScreenCoordsXY{ landCostWidget.left + 1, landCostWidget.top };
|
|
auto ft = Formatter();
|
|
ft.Add<money64>(gameState.LandPrice);
|
|
DrawTextBasic(dpi, screenCoords, STR_CURRENCY_FORMAT_LABEL, ft);
|
|
}
|
|
|
|
const auto& constructionRightsCostWidget = widgets[WIDX_CONSTRUCTION_RIGHTS_COST];
|
|
if (constructionRightsCostWidget.type != WindowWidgetType::Empty)
|
|
{
|
|
// Cost to buy construction rights label
|
|
screenCoords = windowPos + ScreenCoordsXY{ 8, constructionRightsCostWidget.top };
|
|
DrawTextBasic(dpi, screenCoords, STR_RIGHTS_COST_LABEL);
|
|
|
|
// Cost to buy construction rights value
|
|
screenCoords = windowPos
|
|
+ ScreenCoordsXY{ constructionRightsCostWidget.left + 1, constructionRightsCostWidget.top };
|
|
auto ft = Formatter();
|
|
ft.Add<money64>(gameState.ConstructionRightsPrice);
|
|
DrawTextBasic(dpi, screenCoords, STR_CURRENCY_FORMAT_LABEL, ft);
|
|
}
|
|
|
|
const auto& payForParkOrRidesWidget = widgets[WIDX_PAY_FOR_PARK_OR_RIDES];
|
|
if (payForParkOrRidesWidget.type != WindowWidgetType::Empty)
|
|
{
|
|
// Pay for park or rides label
|
|
screenCoords = windowPos + ScreenCoordsXY{ payForParkOrRidesWidget.left + 1, payForParkOrRidesWidget.top };
|
|
|
|
auto ft = Formatter();
|
|
// Pay for park and/or rides value
|
|
if (gameState.Park.Flags & PARK_FLAGS_UNLOCK_ALL_PRICES)
|
|
ft.Add<StringId>(STR_PAID_ENTRY_PAID_RIDES);
|
|
else if (gameState.Park.Flags & PARK_FLAGS_PARK_FREE_ENTRY)
|
|
ft.Add<StringId>(STR_FREE_PARK_ENTER);
|
|
else
|
|
ft.Add<StringId>(STR_PAY_PARK_ENTER);
|
|
|
|
DrawTextBasic(dpi, screenCoords, STR_WINDOW_COLOUR_2_STRINGID, ft);
|
|
}
|
|
|
|
const auto& entryPriceWidget = widgets[WIDX_ENTRY_PRICE];
|
|
if (entryPriceWidget.type != WindowWidgetType::Empty)
|
|
{
|
|
// Entry price label
|
|
screenCoords = windowPos + ScreenCoordsXY{ payForParkOrRidesWidget.right + 8, entryPriceWidget.top };
|
|
DrawTextBasic(dpi, screenCoords, STR_ENTRY_PRICE_LABEL);
|
|
|
|
// Entry price value
|
|
screenCoords = windowPos + ScreenCoordsXY{ entryPriceWidget.left + 1, entryPriceWidget.top };
|
|
auto ft = Formatter();
|
|
ft.Add<money64>(gameState.Park.EntranceFee);
|
|
DrawTextBasic(dpi, screenCoords, STR_CURRENCY_FORMAT_LABEL, ft);
|
|
}
|
|
|
|
// Climate label
|
|
const auto& climateWidget = widgets[WIDX_CLIMATE];
|
|
screenCoords = windowPos + ScreenCoordsXY{ 8, climateWidget.top };
|
|
DrawTextBasic(dpi, screenCoords, STR_CLIMATE_LABEL);
|
|
|
|
// Climate value
|
|
screenCoords = windowPos + ScreenCoordsXY{ climateWidget.left + 1, climateWidget.top };
|
|
auto ft = Formatter();
|
|
ft.Add<StringId>(ClimateNames[EnumValue(gameState.Climate)]);
|
|
DrawTextBasic(dpi, screenCoords, STR_WINDOW_COLOUR_2_STRINGID, ft);
|
|
}
|
|
|
|
#pragma endregion
|
|
};
|
|
|
|
WindowBase* EditorScenarioOptionsOpen()
|
|
{
|
|
return WindowFocusOrCreate<EditorScenarioOptionsWindow>(WindowClass::EditorScenarioOptions, 280, 148, WF_NO_SCROLLING);
|
|
}
|
|
} // namespace OpenRCT2::Ui::Windows
|