mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-02-01 19:25:12 +01:00
Merge pull request #21304 from Gymnasiast/refactor/gresearch-to-gamestate
Move gResearch* globals to GameState_t
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
- Feature: [#21062] [Plugin] Add API for managing a guest's items.
|
||||
- Improved: [#18632] Land ownership and construction rights are now shown on top of the water.
|
||||
- Improved: [#20951] Activate OpenRCT2 window after using native file dialog on macOS.
|
||||
- Improved: [#21184] The construction marker for rides, paths and large scenery is not shown on top of the water.
|
||||
- Improved: [#21184] The construction marker for rides, paths and large scenery is now shown on top of the water.
|
||||
- Improved: [#21227] Entrance style dropdown is now sorted alphabetically everywhere.
|
||||
- Change: [#21200] Raise maximum lift speeds of the Reverser Coaster, Side Friction Coaster, and Virginia Reel for RCT1 parity.
|
||||
- Change: [#21225] Raise maximum allowed misc entities to 1600.
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <openrct2-ui/interface/Widget.h>
|
||||
#include <openrct2-ui/windows/Window.h>
|
||||
#include <openrct2/Editor.h>
|
||||
#include <openrct2/GameState.h>
|
||||
#include <openrct2/Input.h>
|
||||
#include <openrct2/OpenRCT2.h>
|
||||
#include <openrct2/interface/Cursors.h>
|
||||
@@ -27,6 +28,8 @@
|
||||
|
||||
#pragma region Widgets
|
||||
|
||||
using namespace OpenRCT2;
|
||||
|
||||
static constexpr int32_t WW = 600;
|
||||
static constexpr int32_t WH = 400;
|
||||
static constexpr StringId WINDOW_TITLE = STR_INVENTION_LIST;
|
||||
@@ -220,14 +223,15 @@ public:
|
||||
|
||||
ScreenSize OnScrollGetSize(int32_t scrollIndex) override
|
||||
{
|
||||
const auto& gameState = GetGameState();
|
||||
ScreenSize size{};
|
||||
if (scrollIndex == 0)
|
||||
{
|
||||
size.height = static_cast<int32_t>(gResearchItemsInvented.size()) * SCROLLABLE_ROW_HEIGHT;
|
||||
size.height = static_cast<int32_t>(gameState.ResearchItemsInvented.size()) * SCROLLABLE_ROW_HEIGHT;
|
||||
}
|
||||
else
|
||||
{
|
||||
size.height = static_cast<int32_t>(gResearchItemsUninvented.size()) * SCROLLABLE_ROW_HEIGHT;
|
||||
size.height = static_cast<int32_t>(gameState.ResearchItemsUninvented.size()) * SCROLLABLE_ROW_HEIGHT;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
@@ -265,6 +269,8 @@ public:
|
||||
|
||||
void OnScrollDraw(int32_t scrollIndex, DrawPixelInfo& dpi) override
|
||||
{
|
||||
const auto& gameState = GetGameState();
|
||||
|
||||
// Draw background
|
||||
uint8_t paletteIndex = ColourMapA[colours[1]].mid_light;
|
||||
GfxClear(&dpi, paletteIndex);
|
||||
@@ -273,7 +279,7 @@ public:
|
||||
int32_t itemY = -SCROLLABLE_ROW_HEIGHT;
|
||||
auto* dragItem = WindowEditorInventionsListDragGetItem();
|
||||
|
||||
const auto& researchList = scrollIndex == 0 ? gResearchItemsInvented : gResearchItemsUninvented;
|
||||
const auto& researchList = scrollIndex == 0 ? gameState.ResearchItemsInvented : gameState.ResearchItemsUninvented;
|
||||
for (const auto& researchItem : researchList)
|
||||
{
|
||||
itemY += SCROLLABLE_ROW_HEIGHT;
|
||||
@@ -512,6 +518,7 @@ public:
|
||||
|
||||
void MoveResearchItem(const ResearchItem& item, ResearchItem* beforeItem, bool isInvented)
|
||||
{
|
||||
auto& gameState = GetGameState();
|
||||
_selectedResearchItem = nullptr;
|
||||
Invalidate();
|
||||
|
||||
@@ -524,7 +531,7 @@ public:
|
||||
|
||||
ResearchRemove(item);
|
||||
|
||||
auto& researchList = isInvented ? gResearchItemsInvented : gResearchItemsUninvented;
|
||||
auto& researchList = isInvented ? gameState.ResearchItemsInvented : gameState.ResearchItemsUninvented;
|
||||
if (beforeItem != nullptr)
|
||||
{
|
||||
for (size_t i = 0; i < researchList.size(); i++)
|
||||
@@ -544,7 +551,8 @@ public:
|
||||
private:
|
||||
ResearchItem* GetItemFromScrollY(bool isInvented, int32_t y) const
|
||||
{
|
||||
auto& researchList = isInvented ? gResearchItemsInvented : gResearchItemsUninvented;
|
||||
auto& gameState = GetGameState();
|
||||
auto& researchList = isInvented ? gameState.ResearchItemsInvented : gameState.ResearchItemsUninvented;
|
||||
for (auto& researchItem : researchList)
|
||||
{
|
||||
y -= SCROLLABLE_ROW_HEIGHT;
|
||||
@@ -559,7 +567,8 @@ private:
|
||||
|
||||
ResearchItem* GetItemFromScrollYIncludeSeps(bool isInvented, int32_t y) const
|
||||
{
|
||||
auto& researchList = isInvented ? gResearchItemsInvented : gResearchItemsUninvented;
|
||||
auto& gameState = GetGameState();
|
||||
auto& researchList = isInvented ? gameState.ResearchItemsInvented : gameState.ResearchItemsUninvented;
|
||||
for (auto& researchItem : researchList)
|
||||
{
|
||||
y -= SCROLLABLE_ROW_HEIGHT;
|
||||
|
||||
@@ -329,24 +329,26 @@ static WidgetIndex GetWidgetIndexOffset(WidgetIndex baseWidgetIndex, WidgetIndex
|
||||
|
||||
void WindowResearchDevelopmentMouseUp(WidgetIndex widgetIndex, WidgetIndex baseWidgetIndex)
|
||||
{
|
||||
const auto& gameState = GetGameState();
|
||||
auto widgetOffset = GetWidgetIndexOffset(baseWidgetIndex, WIDX_CURRENTLY_IN_DEVELOPMENT_GROUP);
|
||||
|
||||
if (widgetIndex == (WIDX_LAST_DEVELOPMENT_BUTTON + widgetOffset))
|
||||
{
|
||||
News::OpenSubject(News::ItemType::Research, gResearchLastItem->rawValue);
|
||||
News::OpenSubject(News::ItemType::Research, gameState.ResearchLastItem->rawValue);
|
||||
}
|
||||
}
|
||||
|
||||
void WindowResearchDevelopmentPrepareDraw(WindowBase* w, WidgetIndex baseWidgetIndex)
|
||||
{
|
||||
const auto& gameState = GetGameState();
|
||||
// Offset the widget index to allow reuse from other windows
|
||||
auto widgetOffset = GetWidgetIndexOffset(baseWidgetIndex, WIDX_CURRENTLY_IN_DEVELOPMENT_GROUP);
|
||||
w->widgets[WIDX_LAST_DEVELOPMENT_BUTTON + widgetOffset].type = WindowWidgetType::Empty;
|
||||
|
||||
// Display button to link to the last development, if there is one
|
||||
if (gResearchLastItem.has_value())
|
||||
if (gameState.ResearchLastItem.has_value())
|
||||
{
|
||||
auto type = gResearchLastItem->type;
|
||||
auto type = gameState.ResearchLastItem->type;
|
||||
w->widgets[WIDX_LAST_DEVELOPMENT_BUTTON + widgetOffset].type = WindowWidgetType::FlatBtn;
|
||||
const auto image = type == Research::EntryType::Ride ? SPR_NEW_RIDE : SPR_NEW_SCENERY;
|
||||
w->widgets[WIDX_LAST_DEVELOPMENT_BUTTON + widgetOffset].image = ImageId(image);
|
||||
@@ -355,11 +357,13 @@ void WindowResearchDevelopmentPrepareDraw(WindowBase* w, WidgetIndex baseWidgetI
|
||||
|
||||
void WindowResearchDevelopmentDraw(WindowBase* w, DrawPixelInfo& dpi, WidgetIndex baseWidgetIndex)
|
||||
{
|
||||
const auto& gameState = GetGameState();
|
||||
|
||||
auto widgetOffset = GetWidgetIndexOffset(baseWidgetIndex, WIDX_CURRENTLY_IN_DEVELOPMENT_GROUP);
|
||||
auto screenCoords = w->windowPos
|
||||
+ ScreenCoordsXY{ 10, w->widgets[WIDX_CURRENTLY_IN_DEVELOPMENT_GROUP + widgetOffset].top + 12 };
|
||||
|
||||
if (gResearchProgressStage == RESEARCH_STAGE_FINISHED_ALL)
|
||||
if (gameState.ResearchProgressStage == RESEARCH_STAGE_FINISHED_ALL)
|
||||
{
|
||||
// Research type
|
||||
auto ft = Formatter();
|
||||
@@ -383,53 +387,53 @@ void WindowResearchDevelopmentDraw(WindowBase* w, DrawPixelInfo& dpi, WidgetInde
|
||||
// Research type
|
||||
auto ft = Formatter();
|
||||
StringId label = STR_RESEARCH_TYPE_LABEL;
|
||||
if (gResearchProgressStage == RESEARCH_STAGE_INITIAL_RESEARCH)
|
||||
if (gameState.ResearchProgressStage == RESEARCH_STAGE_INITIAL_RESEARCH)
|
||||
{
|
||||
ft.Add<StringId>(STR_RESEARCH_UNKNOWN);
|
||||
}
|
||||
else if (gResearchProgressStage == RESEARCH_STAGE_DESIGNING)
|
||||
else if (gameState.ResearchProgressStage == RESEARCH_STAGE_DESIGNING)
|
||||
{
|
||||
ft.Add<StringId>(gResearchNextItem->GetCategoryName());
|
||||
ft.Add<StringId>(gameState.ResearchNextItem->GetCategoryName());
|
||||
}
|
||||
else if (gResearchNextItem->type == Research::EntryType::Ride)
|
||||
else if (gameState.ResearchNextItem->type == Research::EntryType::Ride)
|
||||
{
|
||||
const auto& rtd = GetRideTypeDescriptor(gResearchNextItem->baseRideType);
|
||||
const auto& rtd = GetRideTypeDescriptor(gameState.ResearchNextItem->baseRideType);
|
||||
if (rtd.HasFlag(RIDE_TYPE_FLAG_LIST_VEHICLES_SEPARATELY))
|
||||
{
|
||||
ft.Add<StringId>(gResearchNextItem->GetName());
|
||||
ft.Add<StringId>(gameState.ResearchNextItem->GetName());
|
||||
}
|
||||
else if (gResearchNextItem->flags & RESEARCH_ENTRY_FLAG_FIRST_OF_TYPE)
|
||||
else if (gameState.ResearchNextItem->flags & RESEARCH_ENTRY_FLAG_FIRST_OF_TYPE)
|
||||
{
|
||||
ft.Add<StringId>(rtd.Naming.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ft.Add<StringId>(gResearchNextItem->GetName());
|
||||
ft.Add<StringId>(gameState.ResearchNextItem->GetName());
|
||||
ft.Add<StringId>(rtd.Naming.Name);
|
||||
label = STR_RESEARCH_TYPE_LABEL_VEHICLE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ft.Add<StringId>(gResearchNextItem->GetName());
|
||||
ft.Add<StringId>(gameState.ResearchNextItem->GetName());
|
||||
}
|
||||
DrawTextWrapped(dpi, screenCoords, 296, label, ft);
|
||||
screenCoords.y += 25;
|
||||
|
||||
// Progress
|
||||
ft = Formatter();
|
||||
ft.Add<StringId>(ResearchStageNames[gResearchProgressStage]);
|
||||
ft.Add<StringId>(ResearchStageNames[gameState.ResearchProgressStage]);
|
||||
DrawTextWrapped(dpi, screenCoords, 296, STR_RESEARCH_PROGRESS_LABEL, ft);
|
||||
screenCoords.y += 15;
|
||||
|
||||
// Expected
|
||||
ft = Formatter();
|
||||
if (gResearchProgressStage != RESEARCH_STAGE_INITIAL_RESEARCH && gResearchExpectedDay != 255)
|
||||
if (gameState.ResearchProgressStage != RESEARCH_STAGE_INITIAL_RESEARCH && gameState.ResearchExpectedDay != 255)
|
||||
{
|
||||
// TODO: Should probably use game date format setting
|
||||
ft.Add<StringId>(STR_RESEARCH_EXPECTED_FORMAT);
|
||||
ft.Add<StringId>(DateDayNames[gResearchExpectedDay]);
|
||||
ft.Add<StringId>(DateGameMonthNames[gResearchExpectedMonth]);
|
||||
ft.Add<StringId>(DateDayNames[gameState.ResearchExpectedDay]);
|
||||
ft.Add<StringId>(DateGameMonthNames[gameState.ResearchExpectedMonth]);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -441,30 +445,30 @@ void WindowResearchDevelopmentDraw(WindowBase* w, DrawPixelInfo& dpi, WidgetInde
|
||||
// Last development
|
||||
screenCoords = w->windowPos + ScreenCoordsXY{ 10, w->widgets[WIDX_LAST_DEVELOPMENT_GROUP + widgetOffset].top + 12 };
|
||||
|
||||
if (gResearchLastItem.has_value())
|
||||
if (gameState.ResearchLastItem.has_value())
|
||||
{
|
||||
StringId lastDevelopmentFormat = STR_EMPTY;
|
||||
auto ft = Formatter();
|
||||
if (gResearchLastItem->type == Research::EntryType::Scenery)
|
||||
if (gameState.ResearchLastItem->type == Research::EntryType::Scenery)
|
||||
{
|
||||
lastDevelopmentFormat = STR_RESEARCH_SCENERY_LABEL;
|
||||
ft.Add<StringId>(gResearchLastItem->GetName());
|
||||
ft.Add<StringId>(gameState.ResearchLastItem->GetName());
|
||||
}
|
||||
else
|
||||
{
|
||||
lastDevelopmentFormat = STR_RESEARCH_RIDE_LABEL;
|
||||
const auto& rtd = GetRideTypeDescriptor(gResearchLastItem->baseRideType);
|
||||
const auto& rtd = GetRideTypeDescriptor(gameState.ResearchLastItem->baseRideType);
|
||||
if (rtd.HasFlag(RIDE_TYPE_FLAG_LIST_VEHICLES_SEPARATELY))
|
||||
{
|
||||
ft.Add<StringId>(gResearchLastItem->GetName());
|
||||
ft.Add<StringId>(gameState.ResearchLastItem->GetName());
|
||||
}
|
||||
else if (gResearchLastItem->flags & RESEARCH_ENTRY_FLAG_FIRST_OF_TYPE)
|
||||
else if (gameState.ResearchLastItem->flags & RESEARCH_ENTRY_FLAG_FIRST_OF_TYPE)
|
||||
{
|
||||
ft.Add<StringId>(rtd.Naming.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ft.Add<StringId>(gResearchLastItem->GetName());
|
||||
ft.Add<StringId>(gameState.ResearchLastItem->GetName());
|
||||
ft.Add<StringId>(rtd.Naming.Name);
|
||||
lastDevelopmentFormat = STR_RESEARCH_VEHICLE_LABEL;
|
||||
}
|
||||
@@ -480,6 +484,7 @@ void WindowResearchDevelopmentDraw(WindowBase* w, DrawPixelInfo& dpi, WidgetInde
|
||||
|
||||
void WindowResearchFundingMouseDown(WindowBase* w, WidgetIndex widgetIndex, WidgetIndex baseWidgetIndex)
|
||||
{
|
||||
const auto& gameState = GetGameState();
|
||||
auto widgetOffset = GetWidgetIndexOffset(baseWidgetIndex, WIDX_RESEARCH_FUNDING);
|
||||
|
||||
if (widgetIndex != (WIDX_RESEARCH_FUNDING_DROPDOWN_BUTTON + widgetOffset))
|
||||
@@ -496,12 +501,13 @@ void WindowResearchFundingMouseDown(WindowBase* w, WidgetIndex widgetIndex, Widg
|
||||
{ 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;
|
||||
int32_t currentResearchLevel = gameState.ResearchFundingLevel;
|
||||
Dropdown::SetChecked(currentResearchLevel, true);
|
||||
}
|
||||
|
||||
void WindowResearchFundingMouseUp(WidgetIndex widgetIndex, WidgetIndex baseWidgetIndex)
|
||||
{
|
||||
const auto& gameState = GetGameState();
|
||||
auto widgetOffset = GetWidgetIndexOffset(baseWidgetIndex, WIDX_RESEARCH_FUNDING);
|
||||
|
||||
switch (widgetIndex - widgetOffset)
|
||||
@@ -514,9 +520,9 @@ void WindowResearchFundingMouseUp(WidgetIndex widgetIndex, WidgetIndex baseWidge
|
||||
case WIDX_SHOPS_AND_STALLS:
|
||||
case WIDX_SCENERY_AND_THEMING:
|
||||
{
|
||||
auto activeResearchTypes = gResearchPriorities;
|
||||
auto activeResearchTypes = gameState.ResearchPriorities;
|
||||
activeResearchTypes ^= 1uLL << (widgetIndex - (WIDX_TRANSPORT_RIDES + widgetOffset));
|
||||
auto gameAction = ParkSetResearchFundingAction(activeResearchTypes, gResearchFundingLevel);
|
||||
auto gameAction = ParkSetResearchFundingAction(activeResearchTypes, gameState.ResearchFundingLevel);
|
||||
GameActions::Execute(&gameAction);
|
||||
break;
|
||||
}
|
||||
@@ -525,20 +531,22 @@ void WindowResearchFundingMouseUp(WidgetIndex widgetIndex, WidgetIndex baseWidge
|
||||
|
||||
void WindowResearchFundingDropdown(WidgetIndex widgetIndex, int32_t selectedIndex, WidgetIndex baseWidgetIndex)
|
||||
{
|
||||
const auto& gameState = GetGameState();
|
||||
auto widgetOffset = GetWidgetIndexOffset(baseWidgetIndex, WIDX_RESEARCH_FUNDING);
|
||||
|
||||
if (widgetIndex != (WIDX_RESEARCH_FUNDING_DROPDOWN_BUTTON + widgetOffset) || selectedIndex == -1)
|
||||
return;
|
||||
|
||||
auto gameAction = ParkSetResearchFundingAction(gResearchPriorities, selectedIndex);
|
||||
auto gameAction = ParkSetResearchFundingAction(gameState.ResearchPriorities, selectedIndex);
|
||||
GameActions::Execute(&gameAction);
|
||||
}
|
||||
|
||||
void WindowResearchFundingPrepareDraw(WindowBase* w, WidgetIndex baseWidgetIndex)
|
||||
{
|
||||
const auto& gameState = GetGameState();
|
||||
auto widgetOffset = GetWidgetIndexOffset(baseWidgetIndex, WIDX_RESEARCH_FUNDING);
|
||||
|
||||
if ((GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY) || gResearchProgressStage == RESEARCH_STAGE_FINISHED_ALL)
|
||||
if ((GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY) || gameState.ResearchProgressStage == RESEARCH_STAGE_FINISHED_ALL)
|
||||
{
|
||||
w->widgets[WIDX_RESEARCH_FUNDING + widgetOffset].type = WindowWidgetType::Empty;
|
||||
w->widgets[WIDX_RESEARCH_FUNDING_DROPDOWN_BUTTON + widgetOffset].type = WindowWidgetType::Empty;
|
||||
@@ -550,12 +558,12 @@ void WindowResearchFundingPrepareDraw(WindowBase* w, WidgetIndex baseWidgetIndex
|
||||
}
|
||||
|
||||
// Current funding
|
||||
int32_t currentResearchLevel = gResearchFundingLevel;
|
||||
int32_t currentResearchLevel = gameState.ResearchFundingLevel;
|
||||
w->widgets[WIDX_RESEARCH_FUNDING + widgetOffset].text = ResearchFundingLevelNames[currentResearchLevel];
|
||||
|
||||
// Checkboxes
|
||||
uint8_t activeResearchTypes = gResearchPriorities;
|
||||
int32_t uncompletedResearchTypes = gResearchUncompletedCategories;
|
||||
uint8_t activeResearchTypes = gameState.ResearchPriorities;
|
||||
int32_t uncompletedResearchTypes = gameState.ResearchUncompletedCategories;
|
||||
for (int32_t i = 0; i < 7; i++)
|
||||
{
|
||||
int32_t mask = 1 << i;
|
||||
@@ -585,7 +593,8 @@ void WindowResearchFundingDraw(WindowBase* w, DrawPixelInfo& dpi)
|
||||
if (GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY)
|
||||
return;
|
||||
|
||||
int32_t currentResearchLevel = gResearchFundingLevel;
|
||||
const auto& gameState = GetGameState();
|
||||
int32_t currentResearchLevel = gameState.ResearchFundingLevel;
|
||||
auto ft = Formatter();
|
||||
ft.Add<money64>(research_cost_table[currentResearchLevel]);
|
||||
DrawTextBasic(dpi, w->windowPos + ScreenCoordsXY{ 10, 77 }, STR_RESEARCH_COST_PER_MONTH, ft);
|
||||
|
||||
@@ -68,6 +68,19 @@ namespace OpenRCT2
|
||||
colour_t StaffHandymanColour;
|
||||
colour_t StaffMechanicColour;
|
||||
colour_t StaffSecurityColour;
|
||||
|
||||
uint8_t ResearchFundingLevel;
|
||||
uint8_t ResearchPriorities;
|
||||
uint16_t ResearchProgress;
|
||||
uint8_t ResearchProgressStage;
|
||||
uint8_t ResearchExpectedMonth;
|
||||
uint8_t ResearchExpectedDay;
|
||||
std::optional<ResearchItem> ResearchLastItem;
|
||||
std::optional<ResearchItem> ResearchNextItem;
|
||||
|
||||
std::vector<ResearchItem> ResearchItemsUninvented;
|
||||
std::vector<ResearchItem> ResearchItemsInvented;
|
||||
uint8_t ResearchUncompletedCategories;
|
||||
};
|
||||
|
||||
GameState_t& GetGameState();
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "ParkSetResearchFundingAction.h"
|
||||
|
||||
#include "../Context.h"
|
||||
#include "../GameState.h"
|
||||
#include "../core/MemoryStream.h"
|
||||
#include "../localisation/StringIds.h"
|
||||
#include "../management/Research.h"
|
||||
@@ -17,6 +18,8 @@
|
||||
#include "../ui/WindowManager.h"
|
||||
#include "../windows/Intent.h"
|
||||
|
||||
using namespace OpenRCT2;
|
||||
|
||||
ParkSetResearchFundingAction::ParkSetResearchFundingAction(uint32_t priorities, uint8_t fundingAmount)
|
||||
: _priorities(priorities)
|
||||
, _fundingAmount(fundingAmount)
|
||||
@@ -52,8 +55,9 @@ GameActions::Result ParkSetResearchFundingAction::Query() const
|
||||
|
||||
GameActions::Result ParkSetResearchFundingAction::Execute() const
|
||||
{
|
||||
gResearchPriorities = _priorities;
|
||||
gResearchFundingLevel = _fundingAmount;
|
||||
auto& gameState = GetGameState();
|
||||
gameState.ResearchPriorities = _priorities;
|
||||
gameState.ResearchFundingLevel = _fundingAmount;
|
||||
|
||||
auto windowManager = OpenRCT2::GetContext()->GetUiContext()->GetWindowManager();
|
||||
windowManager->BroadcastIntent(Intent(INTENT_ACTION_UPDATE_RESEARCH));
|
||||
|
||||
@@ -123,12 +123,13 @@ void FinancePayWages()
|
||||
**/
|
||||
void FinancePayResearch()
|
||||
{
|
||||
if (GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY)
|
||||
const auto& gameState = GetGameState();
|
||||
if (gameState.ParkFlags & PARK_FLAGS_NO_MONEY)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const uint8_t level = gResearchFundingLevel;
|
||||
const uint8_t level = gameState.ResearchFundingLevel;
|
||||
FinancePayment(research_cost_table[level] / 4, ExpenditureType::Research);
|
||||
}
|
||||
|
||||
@@ -266,7 +267,7 @@ void FinanceUpdateDailyProfit()
|
||||
}
|
||||
|
||||
// Research costs
|
||||
uint8_t level = gResearchFundingLevel;
|
||||
uint8_t level = gameState.ResearchFundingLevel;
|
||||
current_profit -= research_cost_table[level];
|
||||
|
||||
// Loan costs
|
||||
|
||||
@@ -51,21 +51,6 @@ static constexpr int32_t _researchRate[] = {
|
||||
400,
|
||||
};
|
||||
|
||||
uint8_t gResearchFundingLevel;
|
||||
uint8_t gResearchPriorities;
|
||||
uint16_t gResearchProgress;
|
||||
uint8_t gResearchProgressStage;
|
||||
std::optional<ResearchItem> gResearchLastItem;
|
||||
uint8_t gResearchExpectedMonth;
|
||||
uint8_t gResearchExpectedDay;
|
||||
std::optional<ResearchItem> gResearchNextItem;
|
||||
|
||||
std::vector<ResearchItem> gResearchItemsUninvented;
|
||||
std::vector<ResearchItem> gResearchItemsInvented;
|
||||
|
||||
// 0x00EE787C
|
||||
uint8_t gResearchUncompletedCategories;
|
||||
|
||||
static bool _researchedRideTypes[RIDE_TYPE_COUNT];
|
||||
static bool _researchedRideEntries[MAX_RIDE_OBJECTS];
|
||||
static bool _researchedSceneryItems[SCENERY_TYPE_COUNT][UINT16_MAX];
|
||||
@@ -76,10 +61,10 @@ bool gSilentResearch = false;
|
||||
*
|
||||
* rct2: 0x006671AD, part of 0x00667132
|
||||
*/
|
||||
void ResearchResetItems()
|
||||
void ResearchResetItems(GameState_t& gameState)
|
||||
{
|
||||
gResearchItemsUninvented.clear();
|
||||
gResearchItemsInvented.clear();
|
||||
gameState.ResearchItemsUninvented.clear();
|
||||
gameState.ResearchItemsInvented.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -88,14 +73,15 @@ void ResearchResetItems()
|
||||
*/
|
||||
void ResearchUpdateUncompletedTypes()
|
||||
{
|
||||
auto& gameState = GetGameState();
|
||||
int32_t uncompletedResearchTypes = 0;
|
||||
|
||||
for (auto const& researchItem : gResearchItemsUninvented)
|
||||
for (auto const& researchItem : gameState.ResearchItemsUninvented)
|
||||
{
|
||||
uncompletedResearchTypes |= EnumToFlag(researchItem.category);
|
||||
}
|
||||
|
||||
gResearchUncompletedCategories = uncompletedResearchTypes;
|
||||
gameState.ResearchUncompletedCategories = uncompletedResearchTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -104,17 +90,19 @@ void ResearchUpdateUncompletedTypes()
|
||||
*/
|
||||
static void ResearchCalculateExpectedDate()
|
||||
{
|
||||
if (gResearchProgressStage == RESEARCH_STAGE_INITIAL_RESEARCH || gResearchFundingLevel == RESEARCH_FUNDING_NONE)
|
||||
auto& gameState = GetGameState();
|
||||
if (gameState.ResearchProgressStage == RESEARCH_STAGE_INITIAL_RESEARCH
|
||||
|| gameState.ResearchFundingLevel == RESEARCH_FUNDING_NONE)
|
||||
{
|
||||
gResearchExpectedDay = 255;
|
||||
gameState.ResearchExpectedDay = 255;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto& date = GetDate();
|
||||
|
||||
int32_t progressRemaining = gResearchProgressStage == RESEARCH_STAGE_COMPLETING_DESIGN ? 0x10000 : 0x20000;
|
||||
progressRemaining -= gResearchProgress;
|
||||
int32_t daysRemaining = (progressRemaining / _researchRate[gResearchFundingLevel]) * 128;
|
||||
int32_t progressRemaining = gameState.ResearchProgressStage == RESEARCH_STAGE_COMPLETING_DESIGN ? 0x10000 : 0x20000;
|
||||
progressRemaining -= gameState.ResearchProgress;
|
||||
int32_t daysRemaining = (progressRemaining / _researchRate[gameState.ResearchFundingLevel]) * 128;
|
||||
|
||||
int32_t expectedDay = date.GetMonthTicks() + (daysRemaining & 0xFFFF);
|
||||
int32_t dayQuotient = expectedDay / 0x10000;
|
||||
@@ -123,8 +111,8 @@ static void ResearchCalculateExpectedDate()
|
||||
int32_t expectedMonth = DateGetMonth(date.GetMonthsElapsed() + dayQuotient + (daysRemaining >> 16));
|
||||
expectedDay = (dayRemainder * Date::GetDaysInMonth(expectedMonth)) >> 16;
|
||||
|
||||
gResearchExpectedDay = expectedDay;
|
||||
gResearchExpectedMonth = expectedMonth;
|
||||
gameState.ResearchExpectedDay = expectedDay;
|
||||
gameState.ResearchExpectedMonth = expectedMonth;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,11 +124,12 @@ static void ResearchInvalidateRelatedWindows()
|
||||
|
||||
static void ResearchMarkAsFullyCompleted()
|
||||
{
|
||||
gResearchProgress = 0;
|
||||
gResearchProgressStage = RESEARCH_STAGE_FINISHED_ALL;
|
||||
auto& gameState = GetGameState();
|
||||
gameState.ResearchProgress = 0;
|
||||
gameState.ResearchProgressStage = RESEARCH_STAGE_FINISHED_ALL;
|
||||
ResearchInvalidateRelatedWindows();
|
||||
// Reset funding to 0 if no more rides.
|
||||
auto gameAction = ParkSetResearchFundingAction(gResearchPriorities, 0);
|
||||
auto gameAction = ParkSetResearchFundingAction(gameState.ResearchPriorities, 0);
|
||||
GameActions::Execute(&gameAction);
|
||||
}
|
||||
|
||||
@@ -150,37 +139,40 @@ static void ResearchMarkAsFullyCompleted()
|
||||
*/
|
||||
static void ResearchNextDesign()
|
||||
{
|
||||
if (gResearchItemsUninvented.empty())
|
||||
auto& gameState = GetGameState();
|
||||
if (gameState.ResearchItemsUninvented.empty())
|
||||
{
|
||||
ResearchMarkAsFullyCompleted();
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to find a research item of a matching type, if none found, use any first item
|
||||
auto it = std::find_if(gResearchItemsUninvented.begin(), gResearchItemsUninvented.end(), [](const auto& e) {
|
||||
return (gResearchPriorities & EnumToFlag(e.category)) != 0;
|
||||
});
|
||||
if (it == gResearchItemsUninvented.end())
|
||||
auto it = std::find_if(
|
||||
gameState.ResearchItemsUninvented.begin(), gameState.ResearchItemsUninvented.end(),
|
||||
[&gameState](const auto& e) { return (gameState.ResearchPriorities & EnumToFlag(e.category)) != 0; });
|
||||
if (it == gameState.ResearchItemsUninvented.end())
|
||||
{
|
||||
it = gResearchItemsUninvented.begin();
|
||||
it = gameState.ResearchItemsUninvented.begin();
|
||||
}
|
||||
|
||||
gResearchNextItem = *it;
|
||||
gResearchProgress = 0;
|
||||
gResearchProgressStage = RESEARCH_STAGE_DESIGNING;
|
||||
gameState.ResearchNextItem = *it;
|
||||
gameState.ResearchProgress = 0;
|
||||
gameState.ResearchProgressStage = RESEARCH_STAGE_DESIGNING;
|
||||
|
||||
ResearchInvalidateRelatedWindows();
|
||||
}
|
||||
|
||||
static void MarkResearchItemInvented(const ResearchItem& researchItem)
|
||||
{
|
||||
gResearchItemsUninvented.erase(
|
||||
std::remove(gResearchItemsUninvented.begin(), gResearchItemsUninvented.end(), researchItem),
|
||||
gResearchItemsUninvented.end());
|
||||
auto& gameState = GetGameState();
|
||||
gameState.ResearchItemsUninvented.erase(
|
||||
std::remove(gameState.ResearchItemsUninvented.begin(), gameState.ResearchItemsUninvented.end(), researchItem),
|
||||
gameState.ResearchItemsUninvented.end());
|
||||
|
||||
if (std::find(gResearchItemsInvented.begin(), gResearchItemsInvented.end(), researchItem) == gResearchItemsInvented.end())
|
||||
if (std::find(gameState.ResearchItemsInvented.begin(), gameState.ResearchItemsInvented.end(), researchItem)
|
||||
== gameState.ResearchItemsInvented.end())
|
||||
{
|
||||
gResearchItemsInvented.push_back(researchItem);
|
||||
gameState.ResearchItemsInvented.push_back(researchItem);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,7 +182,8 @@ static void MarkResearchItemInvented(const ResearchItem& researchItem)
|
||||
*/
|
||||
void ResearchFinishItem(const ResearchItem& researchItem)
|
||||
{
|
||||
gResearchLastItem = researchItem;
|
||||
auto& gameState = GetGameState();
|
||||
gameState.ResearchLastItem = researchItem;
|
||||
ResearchInvalidateRelatedWindows();
|
||||
|
||||
if (researchItem.type == Research::EntryType::Ride)
|
||||
@@ -213,7 +206,7 @@ void ResearchFinishItem(const ResearchItem& researchItem)
|
||||
RideEntrySetInvented(rideEntryIndex);
|
||||
|
||||
bool seenRideEntry[MAX_RIDE_OBJECTS]{};
|
||||
for (auto const& researchItem3 : gResearchItemsUninvented)
|
||||
for (auto const& researchItem3 : gameState.ResearchItemsUninvented)
|
||||
{
|
||||
ObjectEntryIndex index = researchItem3.entryIndex;
|
||||
seenRideEntry[index] = true;
|
||||
@@ -322,46 +315,46 @@ void ResearchUpdate()
|
||||
return;
|
||||
}
|
||||
|
||||
if ((gameState.ParkFlags & PARK_FLAGS_NO_MONEY) && gResearchFundingLevel == RESEARCH_FUNDING_NONE)
|
||||
if ((gameState.ParkFlags & PARK_FLAGS_NO_MONEY) && gameState.ResearchFundingLevel == RESEARCH_FUNDING_NONE)
|
||||
{
|
||||
researchLevel = RESEARCH_FUNDING_NORMAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
researchLevel = gResearchFundingLevel;
|
||||
researchLevel = gameState.ResearchFundingLevel;
|
||||
}
|
||||
|
||||
currentResearchProgress = gResearchProgress;
|
||||
currentResearchProgress = gameState.ResearchProgress;
|
||||
currentResearchProgress += _researchRate[researchLevel];
|
||||
if (currentResearchProgress <= 0xFFFF)
|
||||
{
|
||||
gResearchProgress = currentResearchProgress;
|
||||
gameState.ResearchProgress = currentResearchProgress;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (gResearchProgressStage)
|
||||
switch (gameState.ResearchProgressStage)
|
||||
{
|
||||
case RESEARCH_STAGE_INITIAL_RESEARCH:
|
||||
ResearchNextDesign();
|
||||
ResearchCalculateExpectedDate();
|
||||
break;
|
||||
case RESEARCH_STAGE_DESIGNING:
|
||||
gResearchProgress = 0;
|
||||
gResearchProgressStage = RESEARCH_STAGE_COMPLETING_DESIGN;
|
||||
gameState.ResearchProgress = 0;
|
||||
gameState.ResearchProgressStage = RESEARCH_STAGE_COMPLETING_DESIGN;
|
||||
ResearchCalculateExpectedDate();
|
||||
ResearchInvalidateRelatedWindows();
|
||||
break;
|
||||
case RESEARCH_STAGE_COMPLETING_DESIGN:
|
||||
MarkResearchItemInvented(*gResearchNextItem);
|
||||
ResearchFinishItem(*gResearchNextItem);
|
||||
gResearchProgress = 0;
|
||||
gResearchProgressStage = RESEARCH_STAGE_INITIAL_RESEARCH;
|
||||
MarkResearchItemInvented(*gameState.ResearchNextItem);
|
||||
ResearchFinishItem(*gameState.ResearchNextItem);
|
||||
gameState.ResearchProgress = 0;
|
||||
gameState.ResearchProgressStage = RESEARCH_STAGE_INITIAL_RESEARCH;
|
||||
ResearchCalculateExpectedDate();
|
||||
ResearchUpdateUncompletedTypes();
|
||||
ResearchInvalidateRelatedWindows();
|
||||
break;
|
||||
case RESEARCH_STAGE_FINISHED_ALL:
|
||||
gResearchFundingLevel = RESEARCH_FUNDING_NONE;
|
||||
gameState.ResearchFundingLevel = RESEARCH_FUNDING_NONE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -373,6 +366,7 @@ void ResearchUpdate()
|
||||
*/
|
||||
void ResearchResetCurrentItem()
|
||||
{
|
||||
auto& gameState = GetGameState();
|
||||
SetEveryRideTypeNotInvented();
|
||||
SetEveryRideEntryNotInvented();
|
||||
|
||||
@@ -380,14 +374,14 @@ void ResearchResetCurrentItem()
|
||||
SetAllSceneryItemsInvented();
|
||||
SetAllSceneryGroupsNotInvented();
|
||||
|
||||
for (const auto& researchItem : gResearchItemsInvented)
|
||||
for (const auto& researchItem : gameState.ResearchItemsInvented)
|
||||
{
|
||||
ResearchFinishItem(researchItem);
|
||||
}
|
||||
|
||||
gResearchLastItem = std::nullopt;
|
||||
gResearchProgressStage = RESEARCH_STAGE_INITIAL_RESEARCH;
|
||||
gResearchProgress = 0;
|
||||
gameState.ResearchLastItem = std::nullopt;
|
||||
gameState.ResearchProgressStage = RESEARCH_STAGE_INITIAL_RESEARCH;
|
||||
gameState.ResearchProgress = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -396,13 +390,14 @@ void ResearchResetCurrentItem()
|
||||
*/
|
||||
static void ResearchInsertUnresearched(ResearchItem&& item)
|
||||
{
|
||||
auto& gameState = GetGameState();
|
||||
// First check to make sure that entry is not already accounted for
|
||||
if (item.Exists())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
gResearchItemsUninvented.push_back(std::move(item));
|
||||
gameState.ResearchItemsUninvented.push_back(std::move(item));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -411,13 +406,14 @@ static void ResearchInsertUnresearched(ResearchItem&& item)
|
||||
*/
|
||||
static void ResearchInsertResearched(ResearchItem&& item)
|
||||
{
|
||||
auto& gameState = GetGameState();
|
||||
// First check to make sure that entry is not already accounted for
|
||||
if (item.Exists())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
gResearchItemsInvented.push_back(std::move(item));
|
||||
gameState.ResearchItemsInvented.push_back(std::move(item));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -426,11 +422,13 @@ static void ResearchInsertResearched(ResearchItem&& item)
|
||||
*/
|
||||
void ResearchRemove(const ResearchItem& researchItem)
|
||||
{
|
||||
gResearchItemsUninvented.erase(
|
||||
std::remove(gResearchItemsUninvented.begin(), gResearchItemsUninvented.end(), researchItem),
|
||||
gResearchItemsUninvented.end());
|
||||
gResearchItemsInvented.erase(
|
||||
std::remove(gResearchItemsInvented.begin(), gResearchItemsInvented.end(), researchItem), gResearchItemsInvented.end());
|
||||
auto& gameState = GetGameState();
|
||||
gameState.ResearchItemsUninvented.erase(
|
||||
std::remove(gameState.ResearchItemsUninvented.begin(), gameState.ResearchItemsUninvented.end(), researchItem),
|
||||
gameState.ResearchItemsUninvented.end());
|
||||
gameState.ResearchItemsInvented.erase(
|
||||
std::remove(gameState.ResearchItemsInvented.begin(), gameState.ResearchItemsInvented.end(), researchItem),
|
||||
gameState.ResearchItemsInvented.end());
|
||||
}
|
||||
|
||||
void ResearchInsert(ResearchItem&& item, bool researched)
|
||||
@@ -451,7 +449,8 @@ void ResearchInsert(ResearchItem&& item, bool researched)
|
||||
*/
|
||||
void ResearchPopulateListRandom()
|
||||
{
|
||||
ResearchResetItems();
|
||||
auto& gameState = GetGameState();
|
||||
ResearchResetItems(gameState);
|
||||
|
||||
// Rides
|
||||
for (int32_t i = 0; i < MAX_RIDE_OBJECTS; i++)
|
||||
@@ -615,6 +614,7 @@ void ScenerySetNotInvented(const ScenerySelection& sceneryItem)
|
||||
|
||||
bool SceneryGroupIsInvented(int32_t sgIndex)
|
||||
{
|
||||
auto& gameState = GetGameState();
|
||||
const auto sgEntry = OpenRCT2::ObjectManager::GetObjectEntry<SceneryGroupEntry>(sgIndex);
|
||||
if (sgEntry == nullptr || sgEntry->SceneryEntries.empty())
|
||||
{
|
||||
@@ -633,7 +633,8 @@ bool SceneryGroupIsInvented(int32_t sgIndex)
|
||||
}
|
||||
|
||||
return std::none_of(
|
||||
std::begin(gResearchItemsUninvented), std::end(gResearchItemsUninvented), [sgIndex](const ResearchItem& item) {
|
||||
std::begin(gameState.ResearchItemsUninvented), std::end(gameState.ResearchItemsUninvented),
|
||||
[sgIndex](const ResearchItem& item) {
|
||||
return item.type == Research::EntryType::Scenery && item.entryIndex == sgIndex;
|
||||
});
|
||||
}
|
||||
@@ -737,11 +738,12 @@ StringId ResearchItem::GetName() const
|
||||
*/
|
||||
void ResearchRemoveFlags()
|
||||
{
|
||||
for (auto& researchItem : gResearchItemsUninvented)
|
||||
auto& gameState = GetGameState();
|
||||
for (auto& researchItem : gameState.ResearchItemsUninvented)
|
||||
{
|
||||
researchItem.flags &= ~(RESEARCH_ENTRY_FLAG_RIDE_ALWAYS_RESEARCHED | RESEARCH_ENTRY_FLAG_SCENERY_SET_ALWAYS_RESEARCHED);
|
||||
}
|
||||
for (auto& researchItem : gResearchItemsInvented)
|
||||
for (auto& researchItem : gameState.ResearchItemsInvented)
|
||||
{
|
||||
researchItem.flags &= ~(RESEARCH_ENTRY_FLAG_RIDE_ALWAYS_RESEARCHED | RESEARCH_ENTRY_FLAG_SCENERY_SET_ALWAYS_RESEARCHED);
|
||||
}
|
||||
@@ -794,16 +796,18 @@ static void ResearchMarkItemAsResearched(const ResearchItem& item)
|
||||
|
||||
static void ResearchRebuildInventedTables()
|
||||
{
|
||||
auto& gameState = GetGameState();
|
||||
SetEveryRideTypeNotInvented();
|
||||
SetEveryRideEntryInvented();
|
||||
SetEveryRideEntryNotInvented();
|
||||
SetAllSceneryItemsNotInvented();
|
||||
for (const auto& item : gResearchItemsInvented)
|
||||
for (const auto& item : gameState.ResearchItemsInvented)
|
||||
{
|
||||
// Ignore item, if the research of it is in progress
|
||||
if (gResearchProgressStage == RESEARCH_STAGE_DESIGNING || gResearchProgressStage == RESEARCH_STAGE_COMPLETING_DESIGN)
|
||||
if (gameState.ResearchProgressStage == RESEARCH_STAGE_DESIGNING
|
||||
|| gameState.ResearchProgressStage == RESEARCH_STAGE_COMPLETING_DESIGN)
|
||||
{
|
||||
if (item == gResearchNextItem)
|
||||
if (item == gameState.ResearchNextItem)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -816,9 +820,10 @@ static void ResearchRebuildInventedTables()
|
||||
|
||||
static void ResearchAddAllMissingItems(bool isResearched)
|
||||
{
|
||||
auto& gameState = GetGameState();
|
||||
// Mark base ridetypes as seen if they exist in the invented research list.
|
||||
bool seenBaseEntry[MAX_RIDE_OBJECTS]{};
|
||||
for (auto const& researchItem : gResearchItemsInvented)
|
||||
for (auto const& researchItem : gameState.ResearchItemsInvented)
|
||||
{
|
||||
ObjectEntryIndex index = researchItem.baseRideType;
|
||||
seenBaseEntry[index] = true;
|
||||
@@ -843,7 +848,7 @@ static void ResearchAddAllMissingItems(bool isResearched)
|
||||
}
|
||||
|
||||
// Mark base ridetypes as seen if they exist in the uninvented research list.
|
||||
for (auto const& researchItem : gResearchItemsUninvented)
|
||||
for (auto const& researchItem : gameState.ResearchItemsUninvented)
|
||||
{
|
||||
ObjectEntryIndex index = researchItem.baseRideType;
|
||||
seenBaseEntry[index] = true;
|
||||
@@ -884,13 +889,14 @@ static void ResearchAddAllMissingItems(bool isResearched)
|
||||
|
||||
void ResearchFix()
|
||||
{
|
||||
auto& gameState = GetGameState();
|
||||
// Remove null entries from the research list
|
||||
ResearchRemoveNullItems(gResearchItemsInvented);
|
||||
ResearchRemoveNullItems(gResearchItemsUninvented);
|
||||
ResearchRemoveNullItems(gameState.ResearchItemsInvented);
|
||||
ResearchRemoveNullItems(gameState.ResearchItemsUninvented);
|
||||
|
||||
// Add missing entries to the research list
|
||||
// If research is complete, mark all the missing items as available
|
||||
ResearchAddAllMissingItems(gResearchProgressStage == RESEARCH_STAGE_FINISHED_ALL);
|
||||
ResearchAddAllMissingItems(gameState.ResearchProgressStage == RESEARCH_STAGE_FINISHED_ALL);
|
||||
|
||||
// Now rebuild all the tables that say whether a ride or scenery item is invented
|
||||
ResearchRebuildInventedTables();
|
||||
@@ -899,18 +905,20 @@ void ResearchFix()
|
||||
|
||||
void ResearchItemsMakeAllUnresearched()
|
||||
{
|
||||
gResearchItemsUninvented.insert(
|
||||
gResearchItemsUninvented.end(), std::make_move_iterator(gResearchItemsInvented.begin()),
|
||||
std::make_move_iterator(gResearchItemsInvented.end()));
|
||||
gResearchItemsInvented.clear();
|
||||
auto& gameState = GetGameState();
|
||||
gameState.ResearchItemsUninvented.insert(
|
||||
gameState.ResearchItemsUninvented.end(), std::make_move_iterator(gameState.ResearchItemsInvented.begin()),
|
||||
std::make_move_iterator(gameState.ResearchItemsInvented.end()));
|
||||
gameState.ResearchItemsInvented.clear();
|
||||
}
|
||||
|
||||
void ResearchItemsMakeAllResearched()
|
||||
{
|
||||
gResearchItemsInvented.insert(
|
||||
gResearchItemsInvented.end(), std::make_move_iterator(gResearchItemsUninvented.begin()),
|
||||
std::make_move_iterator(gResearchItemsUninvented.end()));
|
||||
gResearchItemsUninvented.clear();
|
||||
auto& gameState = GetGameState();
|
||||
gameState.ResearchItemsInvented.insert(
|
||||
gameState.ResearchItemsInvented.end(), std::make_move_iterator(gameState.ResearchItemsUninvented.begin()),
|
||||
std::make_move_iterator(gameState.ResearchItemsUninvented.end()));
|
||||
gameState.ResearchItemsUninvented.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -919,7 +927,10 @@ void ResearchItemsMakeAllResearched()
|
||||
*/
|
||||
void ResearchItemsShuffle()
|
||||
{
|
||||
std::shuffle(std::begin(gResearchItemsUninvented), std::end(gResearchItemsUninvented), std::default_random_engine{});
|
||||
auto& gameState = GetGameState();
|
||||
std::shuffle(
|
||||
std::begin(gameState.ResearchItemsUninvented), std::end(gameState.ResearchItemsUninvented),
|
||||
std::default_random_engine{});
|
||||
}
|
||||
|
||||
bool ResearchItem::IsAlwaysResearched() const
|
||||
@@ -939,14 +950,15 @@ void ResearchItem::SetNull()
|
||||
|
||||
bool ResearchItem::Exists() const
|
||||
{
|
||||
for (auto const& researchItem : gResearchItemsUninvented)
|
||||
auto& gameState = GetGameState();
|
||||
for (auto const& researchItem : gameState.ResearchItemsUninvented)
|
||||
{
|
||||
if (researchItem == *this)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (auto const& researchItem : gResearchItemsInvented)
|
||||
for (auto const& researchItem : gameState.ResearchItemsInvented)
|
||||
{
|
||||
if (researchItem == *this)
|
||||
{
|
||||
@@ -1039,9 +1051,10 @@ static void ResearchMarkRideTypeAsSeen(const ResearchItem& researchItem)
|
||||
|
||||
void ResearchDetermineFirstOfType()
|
||||
{
|
||||
auto& gameState = GetGameState();
|
||||
_seenRideType.reset();
|
||||
|
||||
for (const auto& researchItem : gResearchItemsInvented)
|
||||
for (const auto& researchItem : gameState.ResearchItemsInvented)
|
||||
{
|
||||
if (researchItem.type != Research::EntryType::Ride)
|
||||
continue;
|
||||
@@ -1054,37 +1067,40 @@ void ResearchDetermineFirstOfType()
|
||||
if (rtd.HasFlag(RIDE_TYPE_FLAG_LIST_VEHICLES_SEPARATELY))
|
||||
continue;
|
||||
|
||||
// The last research item will also be present in gResearchItemsInvented.
|
||||
// The last research item will also be present in gameState.ResearchItemsInvented.
|
||||
// Avoid marking its ride type as "invented" prematurely.
|
||||
if (gResearchLastItem.has_value() && !gResearchLastItem->IsNull() && researchItem == gResearchLastItem.value())
|
||||
if (gameState.ResearchLastItem.has_value() && !gameState.ResearchLastItem->IsNull()
|
||||
&& researchItem == gameState.ResearchLastItem.value())
|
||||
continue;
|
||||
|
||||
// The next research item is (sometimes?) also present in gResearchItemsInvented, even though it isn't invented yet(!)
|
||||
if (gResearchNextItem.has_value() && !gResearchNextItem->IsNull() && researchItem == gResearchNextItem.value())
|
||||
// The next research item is (sometimes?) also present in gameState.ResearchItemsInvented, even though it isn't invented
|
||||
// yet(!)
|
||||
if (gameState.ResearchNextItem.has_value() && !gameState.ResearchNextItem->IsNull()
|
||||
&& researchItem == gameState.ResearchNextItem.value())
|
||||
continue;
|
||||
|
||||
ResearchMarkRideTypeAsSeen(researchItem);
|
||||
}
|
||||
|
||||
if (gResearchLastItem.has_value())
|
||||
if (gameState.ResearchLastItem.has_value())
|
||||
{
|
||||
ResearchUpdateFirstOfType(&gResearchLastItem.value());
|
||||
ResearchMarkRideTypeAsSeen(gResearchLastItem.value());
|
||||
ResearchUpdateFirstOfType(&gameState.ResearchLastItem.value());
|
||||
ResearchMarkRideTypeAsSeen(gameState.ResearchLastItem.value());
|
||||
}
|
||||
if (gResearchNextItem.has_value())
|
||||
if (gameState.ResearchNextItem.has_value())
|
||||
{
|
||||
ResearchUpdateFirstOfType(&gResearchNextItem.value());
|
||||
ResearchMarkRideTypeAsSeen(gResearchNextItem.value());
|
||||
ResearchUpdateFirstOfType(&gameState.ResearchNextItem.value());
|
||||
ResearchMarkRideTypeAsSeen(gameState.ResearchNextItem.value());
|
||||
}
|
||||
|
||||
for (auto& researchItem : gResearchItemsUninvented)
|
||||
for (auto& researchItem : gameState.ResearchItemsUninvented)
|
||||
{
|
||||
// The next research item is (sometimes?) also present in gResearchItemsUninvented
|
||||
if (gResearchNextItem.has_value() && !gResearchNextItem->IsNull()
|
||||
&& researchItem.baseRideType == gResearchNextItem.value().baseRideType)
|
||||
// The next research item is (sometimes?) also present in gameState.ResearchItemsUninvented
|
||||
if (gameState.ResearchNextItem.has_value() && !gameState.ResearchNextItem->IsNull()
|
||||
&& researchItem.baseRideType == gameState.ResearchNextItem.value().baseRideType)
|
||||
{
|
||||
// Copy the "first of type" flag.
|
||||
researchItem.flags = gResearchNextItem->flags;
|
||||
researchItem.flags = gameState.ResearchNextItem->flags;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,11 @@
|
||||
struct RideObjectEntry;
|
||||
struct ScenerySelection;
|
||||
|
||||
namespace OpenRCT2
|
||||
{
|
||||
struct GameState_t;
|
||||
}
|
||||
|
||||
namespace Research
|
||||
{
|
||||
enum class EntryType : uint8_t
|
||||
@@ -110,21 +115,9 @@ enum
|
||||
RESEARCH_STAGE_FINISHED_ALL
|
||||
};
|
||||
|
||||
extern uint8_t gResearchFundingLevel;
|
||||
extern uint8_t gResearchPriorities;
|
||||
extern uint16_t gResearchProgress;
|
||||
extern uint8_t gResearchProgressStage;
|
||||
extern uint8_t gResearchExpectedMonth;
|
||||
extern uint8_t gResearchExpectedDay;
|
||||
extern std::optional<ResearchItem> gResearchLastItem;
|
||||
extern std::optional<ResearchItem> gResearchNextItem;
|
||||
|
||||
extern std::vector<ResearchItem> gResearchItemsUninvented;
|
||||
extern std::vector<ResearchItem> gResearchItemsInvented;
|
||||
extern uint8_t gResearchUncompletedCategories;
|
||||
extern bool gSilentResearch;
|
||||
|
||||
void ResearchResetItems();
|
||||
void ResearchResetItems(OpenRCT2::GameState_t& gameState);
|
||||
void ResearchUpdateUncompletedTypes();
|
||||
void ResearchUpdate();
|
||||
void ResearchResetCurrentItem();
|
||||
|
||||
@@ -944,20 +944,22 @@ namespace OpenRCT2
|
||||
|
||||
void ReadWriteResearchChunk(GameState_t& gameState, OrcaStream& os)
|
||||
{
|
||||
os.ReadWriteChunk(ParkFileChunkType::RESEARCH, [](OrcaStream::ChunkStream& cs) {
|
||||
os.ReadWriteChunk(ParkFileChunkType::RESEARCH, [&gameState](OrcaStream::ChunkStream& cs) {
|
||||
// Research status
|
||||
cs.ReadWrite(gResearchFundingLevel);
|
||||
cs.ReadWrite(gResearchPriorities);
|
||||
cs.ReadWrite(gResearchProgressStage);
|
||||
cs.ReadWrite(gResearchProgress);
|
||||
cs.ReadWrite(gResearchExpectedMonth);
|
||||
cs.ReadWrite(gResearchExpectedDay);
|
||||
ReadWriteResearchItem(cs, gResearchLastItem);
|
||||
ReadWriteResearchItem(cs, gResearchNextItem);
|
||||
cs.ReadWrite(gameState.ResearchFundingLevel);
|
||||
cs.ReadWrite(gameState.ResearchPriorities);
|
||||
cs.ReadWrite(gameState.ResearchProgressStage);
|
||||
cs.ReadWrite(gameState.ResearchProgress);
|
||||
cs.ReadWrite(gameState.ResearchExpectedMonth);
|
||||
cs.ReadWrite(gameState.ResearchExpectedDay);
|
||||
ReadWriteResearchItem(cs, gameState.ResearchLastItem);
|
||||
ReadWriteResearchItem(cs, gameState.ResearchNextItem);
|
||||
|
||||
// Invention list
|
||||
cs.ReadWriteVector(gResearchItemsUninvented, [&cs](ResearchItem& item) { ReadWriteResearchItem(cs, item); });
|
||||
cs.ReadWriteVector(gResearchItemsInvented, [&cs](ResearchItem& item) { ReadWriteResearchItem(cs, item); });
|
||||
cs.ReadWriteVector(
|
||||
gameState.ResearchItemsUninvented, [&cs](ResearchItem& item) { ReadWriteResearchItem(cs, item); });
|
||||
cs.ReadWriteVector(
|
||||
gameState.ResearchItemsInvented, [&cs](ResearchItem& item) { ReadWriteResearchItem(cs, item); });
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -181,7 +181,7 @@ namespace RCT1
|
||||
ImportTileElements();
|
||||
ImportPeepSpawns();
|
||||
ImportFinance(gameState);
|
||||
ImportResearch();
|
||||
ImportResearch(gameState);
|
||||
ImportParkName();
|
||||
ImportParkFlags(gameState);
|
||||
ImportClimate(gameState);
|
||||
@@ -1862,12 +1862,12 @@ namespace RCT1
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ImportResearch()
|
||||
void ImportResearch(GameState_t& gameState)
|
||||
{
|
||||
// All available objects must be loaded before this method is called as it
|
||||
// requires them to correctly insert objects into the research list
|
||||
|
||||
ResearchResetItems();
|
||||
ResearchResetItems(gameState);
|
||||
|
||||
size_t researchListCount;
|
||||
const RCT1::ResearchItem* researchList = GetResearchList(&researchListCount);
|
||||
@@ -2024,41 +2024,41 @@ namespace RCT1
|
||||
{
|
||||
activeResearchTypes |= EnumToFlag(ResearchCategory::SceneryGroup);
|
||||
}
|
||||
gResearchPriorities = activeResearchTypes;
|
||||
gResearchFundingLevel = _s4.ResearchLevel;
|
||||
gameState.ResearchPriorities = activeResearchTypes;
|
||||
gameState.ResearchFundingLevel = _s4.ResearchLevel;
|
||||
|
||||
// This will mark items as researched/unresearched according to the research list.
|
||||
// This needs to be called before importing progress, as it will reset it.
|
||||
ResearchResetCurrentItem();
|
||||
|
||||
// Research history
|
||||
gResearchProgress = _s4.ResearchProgress;
|
||||
gResearchProgressStage = _s4.ResearchProgressStage;
|
||||
gResearchExpectedDay = _s4.NextResearchExpectedDay;
|
||||
gResearchExpectedMonth = _s4.NextResearchExpectedMonth;
|
||||
gameState.ResearchProgress = _s4.ResearchProgress;
|
||||
gameState.ResearchProgressStage = _s4.ResearchProgressStage;
|
||||
gameState.ResearchExpectedDay = _s4.NextResearchExpectedDay;
|
||||
gameState.ResearchExpectedMonth = _s4.NextResearchExpectedMonth;
|
||||
|
||||
if (_s4.LastResearchFlags == 0xFF)
|
||||
{
|
||||
gResearchLastItem = std::nullopt;
|
||||
gameState.ResearchLastItem = std::nullopt;
|
||||
}
|
||||
else
|
||||
{
|
||||
::ResearchItem researchItem = {};
|
||||
ConvertResearchEntry(&researchItem, _s4.LastResearchItem, _s4.LastResearchType);
|
||||
gResearchLastItem = researchItem;
|
||||
gameState.ResearchLastItem = researchItem;
|
||||
}
|
||||
|
||||
if (_s4.NextResearchFlags == 0xFF)
|
||||
{
|
||||
gResearchNextItem = std::nullopt;
|
||||
gResearchProgressStage = RESEARCH_STAGE_INITIAL_RESEARCH;
|
||||
gResearchProgress = 0;
|
||||
gameState.ResearchNextItem = std::nullopt;
|
||||
gameState.ResearchProgressStage = RESEARCH_STAGE_INITIAL_RESEARCH;
|
||||
gameState.ResearchProgress = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
::ResearchItem researchItem = {};
|
||||
ConvertResearchEntry(&researchItem, _s4.NextResearchItem, _s4.NextResearchType);
|
||||
gResearchNextItem = researchItem;
|
||||
gameState.ResearchNextItem = researchItem;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -283,7 +283,7 @@ namespace RCT2
|
||||
ImportPeepSpawns();
|
||||
|
||||
gGuestChangeModifier = _s6.GuestCountChangeModifier;
|
||||
gResearchFundingLevel = _s6.CurrentResearchLevel;
|
||||
gameState.ResearchFundingLevel = _s6.CurrentResearchLevel;
|
||||
// Pad01357400
|
||||
// _s6.ResearchedTrackTypesA
|
||||
// _s6.ResearchedTrackTypesB
|
||||
@@ -318,22 +318,24 @@ namespace RCT2
|
||||
}
|
||||
}
|
||||
|
||||
gResearchPriorities = _s6.ActiveResearchTypes;
|
||||
gResearchProgressStage = _s6.ResearchProgressStage;
|
||||
gameState.ResearchPriorities = _s6.ActiveResearchTypes;
|
||||
gameState.ResearchProgressStage = _s6.ResearchProgressStage;
|
||||
if (_s6.LastResearchedItemSubject != RCT12_RESEARCHED_ITEMS_SEPARATOR)
|
||||
gResearchLastItem = RCT12ResearchItem{ _s6.LastResearchedItemSubject, EnumValue(ResearchCategory::Transport) }
|
||||
.ToResearchItem();
|
||||
gameState.ResearchLastItem = RCT12ResearchItem{ _s6.LastResearchedItemSubject,
|
||||
EnumValue(ResearchCategory::Transport) }
|
||||
.ToResearchItem();
|
||||
else
|
||||
gResearchLastItem = std::nullopt;
|
||||
gameState.ResearchLastItem = std::nullopt;
|
||||
// Pad01357CF8
|
||||
if (_s6.NextResearchItem != RCT12_RESEARCHED_ITEMS_SEPARATOR)
|
||||
gResearchNextItem = RCT12ResearchItem{ _s6.NextResearchItem, _s6.NextResearchCategory }.ToResearchItem();
|
||||
gameState.ResearchNextItem = RCT12ResearchItem{ _s6.NextResearchItem, _s6.NextResearchCategory }
|
||||
.ToResearchItem();
|
||||
else
|
||||
gResearchNextItem = std::nullopt;
|
||||
gameState.ResearchNextItem = std::nullopt;
|
||||
|
||||
gResearchProgress = _s6.ResearchProgress;
|
||||
gResearchExpectedDay = _s6.NextResearchExpectedDay;
|
||||
gResearchExpectedMonth = _s6.NextResearchExpectedMonth;
|
||||
gameState.ResearchProgress = _s6.ResearchProgress;
|
||||
gameState.ResearchExpectedDay = _s6.NextResearchExpectedDay;
|
||||
gameState.ResearchExpectedMonth = _s6.NextResearchExpectedMonth;
|
||||
gameState.GuestInitialHappiness = _s6.GuestInitialHappiness;
|
||||
gameState.ParkSize = _s6.ParkSize;
|
||||
_guestGenerationProbability = _s6.GuestGenerationProbability;
|
||||
@@ -407,7 +409,7 @@ namespace RCT2
|
||||
gLastEntranceStyle = _s6.LastEntranceStyle;
|
||||
// rct1_water_colour
|
||||
// Pad01358842
|
||||
ImportResearchList();
|
||||
ImportResearchList(gameState);
|
||||
gMapBaseZ = _s6.MapBaseZ;
|
||||
gBankLoanInterestRate = _s6.CurrentInterestRate;
|
||||
// Pad0135934B
|
||||
@@ -1638,7 +1640,7 @@ namespace RCT2
|
||||
}
|
||||
}
|
||||
|
||||
void ImportResearchList()
|
||||
void ImportResearchList(GameState_t gameState)
|
||||
{
|
||||
bool invented = true;
|
||||
for (const auto& researchItem : _s6.ResearchItems)
|
||||
@@ -1654,9 +1656,9 @@ namespace RCT2
|
||||
}
|
||||
|
||||
if (invented)
|
||||
gResearchItemsInvented.emplace_back(researchItem.ToResearchItem());
|
||||
gameState.ResearchItemsInvented.emplace_back(researchItem.ToResearchItem());
|
||||
else
|
||||
gResearchItemsUninvented.emplace_back(researchItem.ToResearchItem());
|
||||
gameState.ResearchItemsUninvented.emplace_back(researchItem.ToResearchItem());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
# include "ScResearch.hpp"
|
||||
|
||||
# include "../../../Context.h"
|
||||
# include "../../../GameState.h"
|
||||
# include "../../../common.h"
|
||||
# include "../../../core/String.hpp"
|
||||
# include "../../../management/Research.h"
|
||||
@@ -20,6 +21,8 @@
|
||||
# include "../../ScriptEngine.h"
|
||||
# include "../object/ScObject.hpp"
|
||||
|
||||
using namespace OpenRCT2;
|
||||
|
||||
namespace OpenRCT2::Scripting
|
||||
{
|
||||
static const DukEnumMap<uint8_t> ResearchStageMap({
|
||||
@@ -92,13 +95,13 @@ namespace OpenRCT2::Scripting
|
||||
|
||||
uint8_t ScResearch::funding_get() const
|
||||
{
|
||||
return gResearchFundingLevel;
|
||||
return GetGameState().ResearchFundingLevel;
|
||||
}
|
||||
|
||||
void ScResearch::funding_set(uint8_t value)
|
||||
{
|
||||
ThrowIfGameStateNotMutable();
|
||||
gResearchFundingLevel = std::clamp<uint8_t>(value, RESEARCH_FUNDING_NONE, RESEARCH_FUNDING_MAXIMUM);
|
||||
GetGameState().ResearchFundingLevel = std::clamp<uint8_t>(value, RESEARCH_FUNDING_NONE, RESEARCH_FUNDING_MAXIMUM);
|
||||
}
|
||||
|
||||
std::vector<std::string> ScResearch::priorities_get() const
|
||||
@@ -107,7 +110,7 @@ namespace OpenRCT2::Scripting
|
||||
for (auto i = EnumValue(ResearchCategory::Transport); i <= EnumValue(ResearchCategory::SceneryGroup); i++)
|
||||
{
|
||||
auto category = static_cast<ResearchCategory>(i);
|
||||
if (gResearchPriorities & EnumToFlag(category))
|
||||
if (GetGameState().ResearchPriorities & EnumToFlag(category))
|
||||
{
|
||||
result.emplace_back(ResearchCategoryMap[category]);
|
||||
}
|
||||
@@ -128,12 +131,12 @@ namespace OpenRCT2::Scripting
|
||||
priorities |= EnumToFlag(*category);
|
||||
}
|
||||
}
|
||||
gResearchPriorities = priorities;
|
||||
GetGameState().ResearchPriorities = priorities;
|
||||
}
|
||||
|
||||
std::string ScResearch::stage_get() const
|
||||
{
|
||||
return std::string(ResearchStageMap[gResearchProgressStage]);
|
||||
return std::string(ResearchStageMap[GetGameState().ResearchProgressStage]);
|
||||
}
|
||||
|
||||
void ScResearch::stage_set(const std::string& value)
|
||||
@@ -142,53 +145,57 @@ namespace OpenRCT2::Scripting
|
||||
auto it = ResearchStageMap.find(value);
|
||||
if (it != ResearchStageMap.end())
|
||||
{
|
||||
gResearchProgressStage = it->second;
|
||||
GetGameState().ResearchProgressStage = it->second;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t ScResearch::progress_get() const
|
||||
{
|
||||
return gResearchProgress;
|
||||
return GetGameState().ResearchProgress;
|
||||
}
|
||||
|
||||
void ScResearch::progress_set(uint16_t value)
|
||||
{
|
||||
ThrowIfGameStateNotMutable();
|
||||
gResearchProgress = value;
|
||||
GetGameState().ResearchProgress = value;
|
||||
}
|
||||
|
||||
DukValue ScResearch::expectedMonth_get() const
|
||||
{
|
||||
if (gResearchProgressStage == RESEARCH_STAGE_INITIAL_RESEARCH || gResearchExpectedDay == 255)
|
||||
const auto& gameState = GetGameState();
|
||||
if (gameState.ResearchProgressStage == RESEARCH_STAGE_INITIAL_RESEARCH || gameState.ResearchExpectedDay == 255)
|
||||
return ToDuk(_context, nullptr);
|
||||
return ToDuk(_context, gResearchExpectedMonth);
|
||||
return ToDuk(_context, gameState.ResearchExpectedMonth);
|
||||
}
|
||||
|
||||
DukValue ScResearch::expectedDay_get() const
|
||||
{
|
||||
if (gResearchProgressStage == RESEARCH_STAGE_INITIAL_RESEARCH || gResearchExpectedDay == 255)
|
||||
const auto& gameState = GetGameState();
|
||||
if (gameState.ResearchProgressStage == RESEARCH_STAGE_INITIAL_RESEARCH || gameState.ResearchExpectedDay == 255)
|
||||
return ToDuk(_context, nullptr);
|
||||
return ToDuk(_context, gResearchExpectedDay + 1);
|
||||
return ToDuk(_context, gameState.ResearchExpectedDay + 1);
|
||||
}
|
||||
|
||||
DukValue ScResearch::lastResearchedItem_get() const
|
||||
{
|
||||
if (!gResearchLastItem)
|
||||
const auto& gameState = GetGameState();
|
||||
if (!gameState.ResearchLastItem)
|
||||
return ToDuk(_context, nullptr);
|
||||
return ToDuk(_context, *gResearchLastItem);
|
||||
return ToDuk(_context, *gameState.ResearchLastItem);
|
||||
}
|
||||
|
||||
DukValue ScResearch::expectedItem_get() const
|
||||
{
|
||||
if (gResearchProgressStage == RESEARCH_STAGE_INITIAL_RESEARCH || !gResearchNextItem)
|
||||
const auto& gameState = GetGameState();
|
||||
if (gameState.ResearchProgressStage == RESEARCH_STAGE_INITIAL_RESEARCH || !gameState.ResearchNextItem)
|
||||
return ToDuk(_context, nullptr);
|
||||
return ToDuk(_context, *gResearchNextItem);
|
||||
return ToDuk(_context, *gameState.ResearchNextItem);
|
||||
}
|
||||
|
||||
std::vector<DukValue> ScResearch::inventedItems_get() const
|
||||
{
|
||||
std::vector<DukValue> result;
|
||||
for (auto& item : gResearchItemsInvented)
|
||||
for (auto& item : GetGameState().ResearchItemsInvented)
|
||||
{
|
||||
result.push_back(ToDuk(_context, item));
|
||||
}
|
||||
@@ -199,14 +206,14 @@ namespace OpenRCT2::Scripting
|
||||
{
|
||||
ThrowIfGameStateNotMutable();
|
||||
auto list = ConvertResearchList(value);
|
||||
gResearchItemsInvented = std::move(list);
|
||||
GetGameState().ResearchItemsInvented = std::move(list);
|
||||
ResearchFix();
|
||||
}
|
||||
|
||||
std::vector<DukValue> ScResearch::uninventedItems_get() const
|
||||
{
|
||||
std::vector<DukValue> result;
|
||||
for (auto& item : gResearchItemsUninvented)
|
||||
for (auto& item : GetGameState().ResearchItemsUninvented)
|
||||
{
|
||||
result.push_back(ToDuk(_context, item));
|
||||
}
|
||||
@@ -217,7 +224,7 @@ namespace OpenRCT2::Scripting
|
||||
{
|
||||
ThrowIfGameStateNotMutable();
|
||||
auto list = ConvertResearchList(value);
|
||||
gResearchItemsUninvented = std::move(list);
|
||||
GetGameState().ResearchItemsUninvented = std::move(list);
|
||||
ResearchFix();
|
||||
}
|
||||
|
||||
|
||||
@@ -266,10 +266,10 @@ void Park::Initialise()
|
||||
_guestGenerationProbability = 0;
|
||||
gTotalRideValueForMoney = 0;
|
||||
_suggestedGuestMaximum = 0;
|
||||
gResearchLastItem = std::nullopt;
|
||||
gameState.ResearchLastItem = std::nullopt;
|
||||
gMarketingCampaigns.clear();
|
||||
|
||||
ResearchResetItems();
|
||||
ResearchResetItems(gameState);
|
||||
FinanceInit();
|
||||
|
||||
SetEveryRideTypeNotInvented();
|
||||
@@ -281,10 +281,10 @@ void Park::Initialise()
|
||||
gPeepSpawns.clear();
|
||||
ParkEntranceReset();
|
||||
|
||||
gResearchPriorities = EnumsToFlags(
|
||||
gameState.ResearchPriorities = EnumsToFlags(
|
||||
ResearchCategory::Transport, ResearchCategory::Gentle, ResearchCategory::Rollercoaster, ResearchCategory::Thrill,
|
||||
ResearchCategory::Water, ResearchCategory::Shop, ResearchCategory::SceneryGroup);
|
||||
gResearchFundingLevel = RESEARCH_FUNDING_NORMAL;
|
||||
gameState.ResearchFundingLevel = RESEARCH_FUNDING_NORMAL;
|
||||
|
||||
gameState.GuestInitialCash = 50.00_GBP;
|
||||
gameState.GuestInitialHappiness = CalculateGuestInitialHappiness(50);
|
||||
|
||||
Reference in New Issue
Block a user