mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2025-12-17 21:12:34 +01:00
Add award plugin APIs (#24468)
* Add award plugin apis * Address review feedback (use erase_if, extract AwardAdd method) * Address review feedback (remove redundant comments, make AwardAdd static) * Address review feedback (bump plugin api version, add changelog entry)
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
0.4.25 (in development)
|
0.4.25 (in development)
|
||||||
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
|
- Feature: [#24468] [Plugin] Add awards to plugin API.
|
||||||
- Feature: [#24702] [Plugin] Add bindings for missing cheats (forcedParkRating, ignoreRidePrice, makeAllDestructible).
|
- Feature: [#24702] [Plugin] Add bindings for missing cheats (forcedParkRating, ignoreRidePrice, makeAllDestructible).
|
||||||
- Fix: [#24598] Cannot load .park files that use official legacy footpaths by accident.
|
- Fix: [#24598] Cannot load .park files that use official legacy footpaths by accident.
|
||||||
|
|
||||||
|
|||||||
66
distribution/openrct2.d.ts
vendored
66
distribution/openrct2.d.ts
vendored
@@ -4179,6 +4179,53 @@ declare global {
|
|||||||
"scenarioCompleteNameInput" |
|
"scenarioCompleteNameInput" |
|
||||||
"unlockAllPrices";
|
"unlockAllPrices";
|
||||||
|
|
||||||
|
type AwardType =
|
||||||
|
"mostUntidy" |
|
||||||
|
"mostTidy" |
|
||||||
|
"bestRollerCoasters" |
|
||||||
|
"bestValue" |
|
||||||
|
"mostBeautiful" |
|
||||||
|
"worstValue" |
|
||||||
|
"safest" |
|
||||||
|
"bestStaff" |
|
||||||
|
"bestFood" |
|
||||||
|
"worstFood" |
|
||||||
|
"bestToilets" |
|
||||||
|
"mostDisappointing" |
|
||||||
|
"bestWaterRides" |
|
||||||
|
"bestCustomDesignedRides" |
|
||||||
|
"mostDazzlingRideColours" |
|
||||||
|
"mostConfusingLayout" |
|
||||||
|
"bestGentleRides";
|
||||||
|
|
||||||
|
interface Award {
|
||||||
|
/**
|
||||||
|
* The type of the award.
|
||||||
|
*/
|
||||||
|
readonly type: AwardType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The award description.
|
||||||
|
*/
|
||||||
|
readonly text: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of months this award will remain active.
|
||||||
|
* Starts at 5, expires at 0.
|
||||||
|
*/
|
||||||
|
readonly monthsRemaining: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The sprite of the award.
|
||||||
|
*/
|
||||||
|
readonly imageId: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether this is a positive or negative award.
|
||||||
|
*/
|
||||||
|
readonly positive: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
interface Park {
|
interface Park {
|
||||||
cash: number;
|
cash: number;
|
||||||
rating: number;
|
rating: number;
|
||||||
@@ -4326,6 +4373,25 @@ declare global {
|
|||||||
* @param type The type of expenditure to get.
|
* @param type The type of expenditure to get.
|
||||||
*/
|
*/
|
||||||
getMonthlyExpenditure(type: ExpenditureType): number[]
|
getMonthlyExpenditure(type: ExpenditureType): number[]
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current awards of the park.
|
||||||
|
*/
|
||||||
|
readonly awards: Award[]
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear all awards.
|
||||||
|
*/
|
||||||
|
clearAwards(): void
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Grant the given award type to the park.
|
||||||
|
* Does not check eligibility.
|
||||||
|
* If the park already has an active award of the given type, the old award will be removed.
|
||||||
|
* If the park already has 4 active awards, the oldest award will be removed.
|
||||||
|
* @param type the award type to grant
|
||||||
|
*/
|
||||||
|
grantAward(type: AwardType): void
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Research {
|
interface Research {
|
||||||
|
|||||||
@@ -1290,23 +1290,6 @@ namespace OpenRCT2
|
|||||||
// Window: Park
|
// Window: Park
|
||||||
STR_ADMISSION_PRICE = 1756,
|
STR_ADMISSION_PRICE = 1756,
|
||||||
STR_ADMISSION_PRICE_PAY_PER_RIDE_TIP = 6014,
|
STR_ADMISSION_PRICE_PAY_PER_RIDE_TIP = 6014,
|
||||||
STR_AWARD_MOST_UNTIDY = 2814,
|
|
||||||
STR_AWARD_BEST_CUSTOM_DESIGNED_RIDES = STR_AWARD_MOST_UNTIDY + 13,
|
|
||||||
STR_AWARD_BEST_FOOD = STR_AWARD_MOST_UNTIDY + 8,
|
|
||||||
STR_AWARD_BEST_GENTLE_RIDES = STR_AWARD_MOST_UNTIDY + 16,
|
|
||||||
STR_AWARD_BEST_ROLLERCOASTERS = STR_AWARD_MOST_UNTIDY + 2,
|
|
||||||
STR_AWARD_BEST_STAFF = STR_AWARD_MOST_UNTIDY + 7,
|
|
||||||
STR_AWARD_BEST_TOILETS = STR_AWARD_MOST_UNTIDY + 10,
|
|
||||||
STR_AWARD_BEST_VALUE = STR_AWARD_MOST_UNTIDY + 3,
|
|
||||||
STR_AWARD_BEST_WATER_RIDES = STR_AWARD_MOST_UNTIDY + 12,
|
|
||||||
STR_AWARD_MOST_BEAUTIFUL = STR_AWARD_MOST_UNTIDY + 4,
|
|
||||||
STR_AWARD_MOST_CONFUSING_LAYOUT = STR_AWARD_MOST_UNTIDY + 15,
|
|
||||||
STR_AWARD_MOST_DAZZLING_RIDE_COLOURS = STR_AWARD_MOST_UNTIDY + 14,
|
|
||||||
STR_AWARD_MOST_DISAPPOINTING = STR_AWARD_MOST_UNTIDY + 11,
|
|
||||||
STR_AWARD_MOST_TIDY = STR_AWARD_MOST_UNTIDY + 1,
|
|
||||||
STR_AWARD_SAFEST = STR_AWARD_MOST_UNTIDY + 6,
|
|
||||||
STR_AWARD_WORST_FOOD = STR_AWARD_MOST_UNTIDY + 9,
|
|
||||||
STR_AWARD_WORST_VALUE = STR_AWARD_MOST_UNTIDY + 5,
|
|
||||||
STR_BUY_LAND_AND_CONSTRUCTION_RIGHTS_TIP = 5135,
|
STR_BUY_LAND_AND_CONSTRUCTION_RIGHTS_TIP = 5135,
|
||||||
STR_CLOSE_PARK = 1013,
|
STR_CLOSE_PARK = 1013,
|
||||||
STR_CLOSE_PARK_TIP = 5296,
|
STR_CLOSE_PARK_TIP = 5296,
|
||||||
|
|||||||
@@ -164,31 +164,6 @@ namespace OpenRCT2::Ui::Windows
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WindowParkAward {
|
|
||||||
StringId text;
|
|
||||||
uint32_t sprite;
|
|
||||||
};
|
|
||||||
|
|
||||||
static constexpr WindowParkAward _parkAwards[] = {
|
|
||||||
{ STR_AWARD_MOST_UNTIDY, SPR_AWARD_MOST_UNTIDY },
|
|
||||||
{ STR_AWARD_MOST_TIDY, SPR_AWARD_MOST_TIDY },
|
|
||||||
{ STR_AWARD_BEST_ROLLERCOASTERS, SPR_AWARD_BEST_ROLLERCOASTERS },
|
|
||||||
{ STR_AWARD_BEST_VALUE, SPR_AWARD_BEST_VALUE },
|
|
||||||
{ STR_AWARD_MOST_BEAUTIFUL, SPR_AWARD_MOST_BEAUTIFUL },
|
|
||||||
{ STR_AWARD_WORST_VALUE, SPR_AWARD_WORST_VALUE },
|
|
||||||
{ STR_AWARD_SAFEST, SPR_AWARD_SAFEST },
|
|
||||||
{ STR_AWARD_BEST_STAFF, SPR_AWARD_BEST_STAFF },
|
|
||||||
{ STR_AWARD_BEST_FOOD, SPR_AWARD_BEST_FOOD },
|
|
||||||
{ STR_AWARD_WORST_FOOD, SPR_AWARD_WORST_FOOD },
|
|
||||||
{ STR_AWARD_BEST_TOILETS, SPR_AWARD_BEST_TOILETS },
|
|
||||||
{ STR_AWARD_MOST_DISAPPOINTING, SPR_AWARD_MOST_DISAPPOINTING },
|
|
||||||
{ STR_AWARD_BEST_WATER_RIDES, SPR_AWARD_BEST_WATER_RIDES },
|
|
||||||
{ STR_AWARD_BEST_CUSTOM_DESIGNED_RIDES, SPR_AWARD_BEST_CUSTOM_DESIGNED_RIDES },
|
|
||||||
{ STR_AWARD_MOST_DAZZLING_RIDE_COLOURS, SPR_AWARD_MOST_DAZZLING_RIDE_COLOURS },
|
|
||||||
{ STR_AWARD_MOST_CONFUSING_LAYOUT, SPR_AWARD_MOST_CONFUSING_LAYOUT },
|
|
||||||
{ STR_AWARD_BEST_GENTLE_RIDES, SPR_AWARD_BEST_GENTLE_RIDES },
|
|
||||||
};
|
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
class ParkWindow final : public Window
|
class ParkWindow final : public Window
|
||||||
@@ -1164,8 +1139,8 @@ namespace OpenRCT2::Ui::Windows
|
|||||||
|
|
||||||
for (const auto& award : currentAwards)
|
for (const auto& award : currentAwards)
|
||||||
{
|
{
|
||||||
GfxDrawSprite(rt, ImageId(_parkAwards[EnumValue(award.Type)].sprite), screenCoords);
|
GfxDrawSprite(rt, ImageId(AwardGetSprite(award.Type)), screenCoords);
|
||||||
DrawTextWrapped(rt, screenCoords + ScreenCoordsXY{ 34, 6 }, 180, _parkAwards[EnumValue(award.Type)].text);
|
DrawTextWrapped(rt, screenCoords + ScreenCoordsXY{ 34, 6 }, 180, AwardGetText(award.Type));
|
||||||
|
|
||||||
screenCoords.y += 32;
|
screenCoords.y += 32;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -595,6 +595,7 @@
|
|||||||
<ClInclude Include="scripting\bindings\ride\ScRideStation.hpp" />
|
<ClInclude Include="scripting\bindings\ride\ScRideStation.hpp" />
|
||||||
<ClInclude Include="scripting\bindings\ride\ScTrackIterator.h" />
|
<ClInclude Include="scripting\bindings\ride\ScTrackIterator.h" />
|
||||||
<ClInclude Include="scripting\bindings\ride\ScTrackSegment.h" />
|
<ClInclude Include="scripting\bindings\ride\ScTrackSegment.h" />
|
||||||
|
<ClInclude Include="scripting\bindings\world\ScAward.hpp" />
|
||||||
<ClInclude Include="scripting\bindings\world\ScClimate.hpp" />
|
<ClInclude Include="scripting\bindings\world\ScClimate.hpp" />
|
||||||
<ClInclude Include="scripting\bindings\world\ScDate.hpp" />
|
<ClInclude Include="scripting\bindings\world\ScDate.hpp" />
|
||||||
<ClInclude Include="scripting\bindings\world\ScMap.hpp" />
|
<ClInclude Include="scripting\bindings\world\ScMap.hpp" />
|
||||||
@@ -1117,6 +1118,7 @@
|
|||||||
<ClCompile Include="scripting\bindings\ride\ScRideStation.cpp" />
|
<ClCompile Include="scripting\bindings\ride\ScRideStation.cpp" />
|
||||||
<ClCompile Include="scripting\bindings\ride\ScTrackIterator.cpp" />
|
<ClCompile Include="scripting\bindings\ride\ScTrackIterator.cpp" />
|
||||||
<ClCompile Include="scripting\bindings\ride\ScTrackSegment.cpp" />
|
<ClCompile Include="scripting\bindings\ride\ScTrackSegment.cpp" />
|
||||||
|
<ClCompile Include="scripting\bindings\world\ScAward.cpp" />
|
||||||
<ClCompile Include="scripting\bindings\world\ScMap.cpp" />
|
<ClCompile Include="scripting\bindings\world\ScMap.cpp" />
|
||||||
<ClCompile Include="scripting\bindings\world\ScPark.cpp" />
|
<ClCompile Include="scripting\bindings\world\ScPark.cpp" />
|
||||||
<ClCompile Include="scripting\bindings\world\ScParkMessage.cpp" />
|
<ClCompile Include="scripting\bindings\world\ScParkMessage.cpp" />
|
||||||
|
|||||||
@@ -1096,6 +1096,23 @@ enum : StringId
|
|||||||
STR_PEEPS_CANT_FIND_TOILET = 2811,
|
STR_PEEPS_CANT_FIND_TOILET = 2811,
|
||||||
STR_PEEPS_GETTING_LOST_OR_STUCK = 2812,
|
STR_PEEPS_GETTING_LOST_OR_STUCK = 2812,
|
||||||
STR_ENTRANCE_FEE_TOO_HI = 2813,
|
STR_ENTRANCE_FEE_TOO_HI = 2813,
|
||||||
|
STR_AWARD_MOST_UNTIDY = 2814,
|
||||||
|
STR_AWARD_BEST_CUSTOM_DESIGNED_RIDES = STR_AWARD_MOST_UNTIDY + 13,
|
||||||
|
STR_AWARD_BEST_FOOD = STR_AWARD_MOST_UNTIDY + 8,
|
||||||
|
STR_AWARD_BEST_GENTLE_RIDES = STR_AWARD_MOST_UNTIDY + 16,
|
||||||
|
STR_AWARD_BEST_ROLLERCOASTERS = STR_AWARD_MOST_UNTIDY + 2,
|
||||||
|
STR_AWARD_BEST_STAFF = STR_AWARD_MOST_UNTIDY + 7,
|
||||||
|
STR_AWARD_BEST_TOILETS = STR_AWARD_MOST_UNTIDY + 10,
|
||||||
|
STR_AWARD_BEST_VALUE = STR_AWARD_MOST_UNTIDY + 3,
|
||||||
|
STR_AWARD_BEST_WATER_RIDES = STR_AWARD_MOST_UNTIDY + 12,
|
||||||
|
STR_AWARD_MOST_BEAUTIFUL = STR_AWARD_MOST_UNTIDY + 4,
|
||||||
|
STR_AWARD_MOST_CONFUSING_LAYOUT = STR_AWARD_MOST_UNTIDY + 15,
|
||||||
|
STR_AWARD_MOST_DAZZLING_RIDE_COLOURS = STR_AWARD_MOST_UNTIDY + 14,
|
||||||
|
STR_AWARD_MOST_DISAPPOINTING = STR_AWARD_MOST_UNTIDY + 11,
|
||||||
|
STR_AWARD_MOST_TIDY = STR_AWARD_MOST_UNTIDY + 1,
|
||||||
|
STR_AWARD_SAFEST = STR_AWARD_MOST_UNTIDY + 6,
|
||||||
|
STR_AWARD_WORST_FOOD = STR_AWARD_MOST_UNTIDY + 9,
|
||||||
|
STR_AWARD_WORST_VALUE = STR_AWARD_MOST_UNTIDY + 5,
|
||||||
STR_NEWS_ITEM_AWARD_MOST_UNTIDY = 2831,
|
STR_NEWS_ITEM_AWARD_MOST_UNTIDY = 2831,
|
||||||
STR_NEWS_ITEM_MOST_TIDY = STR_NEWS_ITEM_AWARD_MOST_UNTIDY + 1,
|
STR_NEWS_ITEM_MOST_TIDY = STR_NEWS_ITEM_AWARD_MOST_UNTIDY + 1,
|
||||||
STR_NEWS_ITEM_BEST_ROLLERCOASTERS = STR_NEWS_ITEM_AWARD_MOST_UNTIDY + 2,
|
STR_NEWS_ITEM_BEST_ROLLERCOASTERS = STR_NEWS_ITEM_AWARD_MOST_UNTIDY + 2,
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
#include "../config/Config.h"
|
#include "../config/Config.h"
|
||||||
#include "../entity/EntityList.h"
|
#include "../entity/EntityList.h"
|
||||||
#include "../entity/Guest.h"
|
#include "../entity/Guest.h"
|
||||||
#include "../localisation/StringIds.h"
|
|
||||||
#include "../profiling/Profiling.h"
|
#include "../profiling/Profiling.h"
|
||||||
#include "../ride/Ride.h"
|
#include "../ride/Ride.h"
|
||||||
#include "../ride/RideData.h"
|
#include "../ride/RideData.h"
|
||||||
@@ -29,49 +28,55 @@ enum class AwardEffect : uint8_t
|
|||||||
negative,
|
negative,
|
||||||
positive
|
positive
|
||||||
};
|
};
|
||||||
static constexpr AwardEffect kAwardPositiveMap[] = {
|
|
||||||
AwardEffect::negative, // AwardType::MostUntidy
|
struct AwardData_t
|
||||||
AwardEffect::positive, // AwardType::MostTidy
|
{
|
||||||
AwardEffect::positive, // AwardType::BestRollerCoasters
|
StringId text;
|
||||||
AwardEffect::positive, // AwardType::BestValue
|
StringId news;
|
||||||
AwardEffect::positive, // AwardType::MostBeautiful
|
ImageIndex sprite;
|
||||||
AwardEffect::negative, // AwardType::WorstValue
|
AwardEffect effect;
|
||||||
AwardEffect::positive, // AwardType::Safest
|
|
||||||
AwardEffect::positive, // AwardType::BestStaff
|
|
||||||
AwardEffect::positive, // AwardType::BestFood
|
|
||||||
AwardEffect::negative, // AwardType::WorstFood
|
|
||||||
AwardEffect::positive, // AwardType::BestToilets
|
|
||||||
AwardEffect::negative, // AwardType::MostDisappointing
|
|
||||||
AwardEffect::positive, // AwardType::BestWaterRides
|
|
||||||
AwardEffect::positive, // AwardType::BestCustomDesignedRides
|
|
||||||
AwardEffect::positive, // AwardType::MostDazzlingRideColours
|
|
||||||
AwardEffect::negative, // AwardType::MostConfusingLayout
|
|
||||||
AwardEffect::positive, // AwardType::BestGentleRides
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static constexpr StringId AwardNewsStrings[] = {
|
// clang-format off
|
||||||
STR_NEWS_ITEM_AWARD_MOST_UNTIDY,
|
static constexpr AwardData_t AwardData[] = {
|
||||||
STR_NEWS_ITEM_MOST_TIDY,
|
{ STR_AWARD_MOST_UNTIDY, STR_NEWS_ITEM_AWARD_MOST_UNTIDY, SPR_AWARD_MOST_UNTIDY, AwardEffect::negative },
|
||||||
STR_NEWS_ITEM_BEST_ROLLERCOASTERS,
|
{ STR_AWARD_MOST_TIDY, STR_NEWS_ITEM_MOST_TIDY, SPR_AWARD_MOST_TIDY, AwardEffect::positive },
|
||||||
STR_NEWS_ITEM_BEST_VALUE,
|
{ STR_AWARD_BEST_ROLLERCOASTERS, STR_NEWS_ITEM_BEST_ROLLERCOASTERS, SPR_AWARD_BEST_ROLLERCOASTERS, AwardEffect::positive },
|
||||||
STR_NEWS_ITEM_MOST_BEAUTIFUL,
|
{ STR_AWARD_BEST_VALUE, STR_NEWS_ITEM_BEST_VALUE, SPR_AWARD_BEST_VALUE, AwardEffect::positive },
|
||||||
STR_NEWS_ITEM_WORST_VALUE,
|
{ STR_AWARD_MOST_BEAUTIFUL, STR_NEWS_ITEM_MOST_BEAUTIFUL, SPR_AWARD_MOST_BEAUTIFUL, AwardEffect::positive },
|
||||||
STR_NEWS_ITEM_SAFEST,
|
{ STR_AWARD_WORST_VALUE, STR_NEWS_ITEM_WORST_VALUE, SPR_AWARD_WORST_VALUE, AwardEffect::negative },
|
||||||
STR_NEWS_ITEM_BEST_STAFF,
|
{ STR_AWARD_SAFEST, STR_NEWS_ITEM_SAFEST, SPR_AWARD_SAFEST, AwardEffect::positive },
|
||||||
STR_NEWS_ITEM_BEST_FOOD,
|
{ STR_AWARD_BEST_STAFF, STR_NEWS_ITEM_BEST_STAFF, SPR_AWARD_BEST_STAFF, AwardEffect::positive },
|
||||||
STR_NEWS_ITEM_WORST_FOOD,
|
{ STR_AWARD_BEST_FOOD, STR_NEWS_ITEM_BEST_FOOD, SPR_AWARD_BEST_FOOD, AwardEffect::positive },
|
||||||
STR_NEWS_ITEM_BEST_TOILETS,
|
{ STR_AWARD_WORST_FOOD, STR_NEWS_ITEM_WORST_FOOD, SPR_AWARD_WORST_FOOD, AwardEffect::negative },
|
||||||
STR_NEWS_ITEM_MOST_DISAPPOINTING,
|
{ STR_AWARD_BEST_TOILETS, STR_NEWS_ITEM_BEST_TOILETS, SPR_AWARD_BEST_TOILETS, AwardEffect::positive },
|
||||||
STR_NEWS_ITEM_BEST_WATER_RIDES,
|
{ STR_AWARD_MOST_DISAPPOINTING, STR_NEWS_ITEM_MOST_DISAPPOINTING, SPR_AWARD_MOST_DISAPPOINTING, AwardEffect::negative },
|
||||||
STR_NEWS_ITEM_BEST_CUSTOM_DESIGNED_RIDES,
|
{ STR_AWARD_BEST_WATER_RIDES, STR_NEWS_ITEM_BEST_WATER_RIDES, SPR_AWARD_BEST_WATER_RIDES, AwardEffect::positive },
|
||||||
STR_NEWS_ITEM_MOST_DAZZLING_RIDE_COLOURS,
|
{ STR_AWARD_BEST_CUSTOM_DESIGNED_RIDES, STR_NEWS_ITEM_BEST_CUSTOM_DESIGNED_RIDES, SPR_AWARD_BEST_CUSTOM_DESIGNED_RIDES, AwardEffect::positive },
|
||||||
STR_NEWS_ITEM_MOST_CONFUSING_LAYOUT,
|
{ STR_AWARD_MOST_DAZZLING_RIDE_COLOURS, STR_NEWS_ITEM_MOST_DAZZLING_RIDE_COLOURS, SPR_AWARD_MOST_DAZZLING_RIDE_COLOURS, AwardEffect::positive },
|
||||||
STR_NEWS_ITEM_BEST_GENTLE_RIDES,
|
{ STR_AWARD_MOST_CONFUSING_LAYOUT, STR_NEWS_ITEM_MOST_CONFUSING_LAYOUT, SPR_AWARD_MOST_CONFUSING_LAYOUT, AwardEffect::negative },
|
||||||
|
{ STR_AWARD_BEST_GENTLE_RIDES, STR_NEWS_ITEM_BEST_GENTLE_RIDES, SPR_AWARD_BEST_GENTLE_RIDES, AwardEffect::positive },
|
||||||
};
|
};
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
bool AwardIsPositive(AwardType type)
|
bool AwardIsPositive(AwardType type)
|
||||||
{
|
{
|
||||||
return kAwardPositiveMap[EnumValue(type)] == AwardEffect::positive;
|
return AwardData[EnumValue(type)].effect == AwardEffect::positive;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageIndex AwardGetSprite(AwardType type)
|
||||||
|
{
|
||||||
|
return AwardData[EnumValue(type)].sprite;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringId AwardGetText(AwardType type)
|
||||||
|
{
|
||||||
|
return AwardData[EnumValue(type)].text;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringId AwardGetNews(AwardType type)
|
||||||
|
{
|
||||||
|
return AwardData[EnumValue(type)].news;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma region Award checks
|
#pragma region Award checks
|
||||||
@@ -598,6 +603,16 @@ void AwardReset()
|
|||||||
getGameState().currentAwards.clear();
|
getGameState().currentAwards.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void AwardAdd(AwardType type)
|
||||||
|
{
|
||||||
|
getGameState().currentAwards.push_back(Award{ 5u, type });
|
||||||
|
if (Config::Get().notifications.ParkAward)
|
||||||
|
{
|
||||||
|
News::AddItemToQueue(News::ItemType::award, AwardGetNews(type), 0, {});
|
||||||
|
}
|
||||||
|
Ui::GetWindowManager()->InvalidateByClass(WindowClass::ParkInformation);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* rct2: 0x0066A86C
|
* rct2: 0x0066A86C
|
||||||
@@ -648,14 +663,24 @@ void AwardUpdateAll()
|
|||||||
// Check if award is deserved
|
// Check if award is deserved
|
||||||
if (AwardIsDeserved(awardType, activeAwardTypes))
|
if (AwardIsDeserved(awardType, activeAwardTypes))
|
||||||
{
|
{
|
||||||
// Add award
|
AwardAdd(awardType);
|
||||||
currentAwards.push_back(Award{ 5u, awardType });
|
}
|
||||||
if (Config::Get().notifications.ParkAward)
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AwardGrant(AwardType type)
|
||||||
{
|
{
|
||||||
News::AddItemToQueue(News::ItemType::award, AwardNewsStrings[EnumValue(awardType)], 0, {});
|
auto& currentAwards = getGameState().currentAwards;
|
||||||
}
|
|
||||||
windowMgr->InvalidateByClass(WindowClass::ParkInformation);
|
// Remove award type if already granted
|
||||||
}
|
std::erase_if(currentAwards, [type](const Award& award) { return award.Type == type; });
|
||||||
}
|
|
||||||
|
// Ensure there is space for the award
|
||||||
|
if (currentAwards.size() >= OpenRCT2::Limits::kMaxAwards)
|
||||||
|
{
|
||||||
|
currentAwards.erase(currentAwards.begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AwardAdd(type);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,9 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "../SpriteIds.h"
|
||||||
|
#include "../localisation/StringIds.h"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -42,5 +45,9 @@ struct Award
|
|||||||
};
|
};
|
||||||
|
|
||||||
bool AwardIsPositive(AwardType type);
|
bool AwardIsPositive(AwardType type);
|
||||||
|
ImageIndex AwardGetSprite(AwardType type);
|
||||||
|
StringId AwardGetText(AwardType type);
|
||||||
|
StringId AwardGetNews(AwardType type);
|
||||||
|
void AwardGrant(AwardType type);
|
||||||
void AwardReset();
|
void AwardReset();
|
||||||
void AwardUpdateAll();
|
void AwardUpdateAll();
|
||||||
|
|||||||
@@ -51,6 +51,7 @@
|
|||||||
#include "bindings/object/ScObjectManager.h"
|
#include "bindings/object/ScObjectManager.h"
|
||||||
#include "bindings/ride/ScRide.hpp"
|
#include "bindings/ride/ScRide.hpp"
|
||||||
#include "bindings/ride/ScRideStation.hpp"
|
#include "bindings/ride/ScRideStation.hpp"
|
||||||
|
#include "bindings/world/ScAward.hpp"
|
||||||
#include "bindings/world/ScClimate.hpp"
|
#include "bindings/world/ScClimate.hpp"
|
||||||
#include "bindings/world/ScDate.hpp"
|
#include "bindings/world/ScDate.hpp"
|
||||||
#include "bindings/world/ScMap.hpp"
|
#include "bindings/world/ScMap.hpp"
|
||||||
@@ -403,6 +404,7 @@ void ScriptEngine::Initialise()
|
|||||||
throw std::runtime_error("Script engine already initialised.");
|
throw std::runtime_error("Script engine already initialised.");
|
||||||
|
|
||||||
auto ctx = static_cast<duk_context*>(_context);
|
auto ctx = static_cast<duk_context*>(_context);
|
||||||
|
ScAward::Register(ctx);
|
||||||
ScCheats::Register(ctx);
|
ScCheats::Register(ctx);
|
||||||
ScClimate::Register(ctx);
|
ScClimate::Register(ctx);
|
||||||
ScWeatherState::Register(ctx);
|
ScWeatherState::Register(ctx);
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ namespace OpenRCT2
|
|||||||
|
|
||||||
namespace OpenRCT2::Scripting
|
namespace OpenRCT2::Scripting
|
||||||
{
|
{
|
||||||
static constexpr int32_t kPluginApiVersion = 109;
|
static constexpr int32_t kPluginApiVersion = 110;
|
||||||
|
|
||||||
// Versions marking breaking changes.
|
// Versions marking breaking changes.
|
||||||
static constexpr int32_t kApiVersionPeepDeprecation = 33;
|
static constexpr int32_t kApiVersionPeepDeprecation = 33;
|
||||||
|
|||||||
90
src/openrct2/scripting/bindings/world/ScAward.cpp
Normal file
90
src/openrct2/scripting/bindings/world/ScAward.cpp
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Copyright (c) 2014-2025 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.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef ENABLE_SCRIPTING
|
||||||
|
|
||||||
|
#include "ScAward.hpp"
|
||||||
|
|
||||||
|
#include "../../../GameState.h"
|
||||||
|
#include "../../../localisation/Formatting.h"
|
||||||
|
#include "../../../management/Award.h"
|
||||||
|
#include "../../../windows/Intent.h"
|
||||||
|
#include "../../Duktape.hpp"
|
||||||
|
|
||||||
|
namespace OpenRCT2::Scripting
|
||||||
|
{
|
||||||
|
ScAward::ScAward(size_t index)
|
||||||
|
: _index(index)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScAward::Register(duk_context* ctx)
|
||||||
|
{
|
||||||
|
dukglue_register_property(ctx, &ScAward::type_get, nullptr, "type");
|
||||||
|
dukglue_register_property(ctx, &ScAward::text_get, nullptr, "text");
|
||||||
|
dukglue_register_property(ctx, &ScAward::positive_get, nullptr, "positive");
|
||||||
|
dukglue_register_property(ctx, &ScAward::imageId_get, nullptr, "imageId");
|
||||||
|
dukglue_register_property(ctx, &ScAward::monthsRemaining_get, nullptr, "monthsRemaining");
|
||||||
|
}
|
||||||
|
|
||||||
|
Award* ScAward::GetAward() const
|
||||||
|
{
|
||||||
|
return &getGameState().currentAwards[_index];
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ScAward::type_get() const
|
||||||
|
{
|
||||||
|
auto award = GetAward();
|
||||||
|
if (award == nullptr)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
return AwardTypeToString(award->Type).value_or(std::string());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ScAward::text_get() const
|
||||||
|
{
|
||||||
|
auto award = GetAward();
|
||||||
|
if (award == nullptr)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
Formatter ft{};
|
||||||
|
ft.Add<StringId>(AwardGetText(award->Type));
|
||||||
|
return FormatStringIDLegacy(STR_STRINGID, ft.Data());
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t ScAward::monthsRemaining_get() const
|
||||||
|
{
|
||||||
|
auto award = GetAward();
|
||||||
|
if (award == nullptr)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
return award->Time;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ScAward::positive_get() const
|
||||||
|
{
|
||||||
|
auto award = GetAward();
|
||||||
|
if (award == nullptr)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
return AwardIsPositive(award->Type);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ScAward::imageId_get() const
|
||||||
|
{
|
||||||
|
auto award = GetAward();
|
||||||
|
if (award == nullptr)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
return AwardGetSprite(award->Type);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace OpenRCT2::Scripting
|
||||||
|
|
||||||
|
#endif
|
||||||
85
src/openrct2/scripting/bindings/world/ScAward.hpp
Normal file
85
src/openrct2/scripting/bindings/world/ScAward.hpp
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Copyright (c) 2014-2025 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.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef ENABLE_SCRIPTING
|
||||||
|
|
||||||
|
#include "../../../Context.h"
|
||||||
|
#include "../../../management/Award.h"
|
||||||
|
#include "../../Duktape.hpp"
|
||||||
|
#include "../../ScriptEngine.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace OpenRCT2::Scripting
|
||||||
|
{
|
||||||
|
static constexpr const char* AwardTypes[] = {
|
||||||
|
"mostUntidy",
|
||||||
|
"mostTidy",
|
||||||
|
"bestRollerCoasters",
|
||||||
|
"bestValue",
|
||||||
|
"mostBeautiful",
|
||||||
|
"worstValue",
|
||||||
|
"safest",
|
||||||
|
"bestStaff",
|
||||||
|
"bestFood",
|
||||||
|
"worstFood",
|
||||||
|
"bestToilets",
|
||||||
|
"mostDisappointing",
|
||||||
|
"bestWaterRides",
|
||||||
|
"bestCustomDesignedRides",
|
||||||
|
"mostDazzlingRideColours",
|
||||||
|
"mostConfusingLayout",
|
||||||
|
"bestGentleRides",
|
||||||
|
};
|
||||||
|
|
||||||
|
inline std::optional<std::string> AwardTypeToString(AwardType awardType)
|
||||||
|
{
|
||||||
|
auto index = static_cast<size_t>(awardType);
|
||||||
|
if (index < std::size(AwardTypes))
|
||||||
|
{
|
||||||
|
return AwardTypes[index];
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::optional<AwardType> StringToAwardType(std::string_view awardType)
|
||||||
|
{
|
||||||
|
auto it = std::find(std::begin(AwardTypes), std::end(AwardTypes), awardType);
|
||||||
|
if (it != std::end(AwardTypes))
|
||||||
|
{
|
||||||
|
return std::optional(static_cast<AwardType>(std::distance(std::begin(AwardTypes), it)));
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ScAward
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
size_t _index{};
|
||||||
|
|
||||||
|
public:
|
||||||
|
ScAward(size_t index);
|
||||||
|
|
||||||
|
static void Register(duk_context* ctx);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Award* GetAward() const;
|
||||||
|
|
||||||
|
std::string type_get() const;
|
||||||
|
std::string text_get() const;
|
||||||
|
uint16_t monthsRemaining_get() const;
|
||||||
|
bool positive_get() const;
|
||||||
|
uint32_t imageId_get() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace OpenRCT2::Scripting
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -430,6 +430,35 @@ namespace OpenRCT2::Scripting
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<ScAward>> ScPark::awards_get() const
|
||||||
|
{
|
||||||
|
std::vector<std::shared_ptr<ScAward>> result;
|
||||||
|
|
||||||
|
auto& gameState = getGameState();
|
||||||
|
for (size_t i = 0; i < gameState.currentAwards.size(); i++)
|
||||||
|
{
|
||||||
|
result.push_back(std::make_shared<ScAward>(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScPark::clearAwards() const
|
||||||
|
{
|
||||||
|
ThrowIfGameStateNotMutable();
|
||||||
|
AwardReset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScPark::grantAward(const std::string& awardType) const
|
||||||
|
{
|
||||||
|
ThrowIfGameStateNotMutable();
|
||||||
|
auto optType = StringToAwardType(awardType);
|
||||||
|
if (optType.has_value())
|
||||||
|
{
|
||||||
|
AwardGrant(optType.value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ScPark::Register(duk_context* ctx)
|
void ScPark::Register(duk_context* ctx)
|
||||||
{
|
{
|
||||||
dukglue_register_property(ctx, &ScPark::cash_get, &ScPark::cash_set, "cash");
|
dukglue_register_property(ctx, &ScPark::cash_get, &ScPark::cash_set, "cash");
|
||||||
@@ -463,6 +492,9 @@ namespace OpenRCT2::Scripting
|
|||||||
dukglue_register_method(ctx, &ScPark::setFlag, "setFlag");
|
dukglue_register_method(ctx, &ScPark::setFlag, "setFlag");
|
||||||
dukglue_register_method(ctx, &ScPark::postMessage, "postMessage");
|
dukglue_register_method(ctx, &ScPark::postMessage, "postMessage");
|
||||||
dukglue_register_method(ctx, &ScPark::getMonthlyExpenditure, "getMonthlyExpenditure");
|
dukglue_register_method(ctx, &ScPark::getMonthlyExpenditure, "getMonthlyExpenditure");
|
||||||
|
dukglue_register_property(ctx, &ScPark::awards_get, nullptr, "awards");
|
||||||
|
dukglue_register_method(ctx, &ScPark::clearAwards, "clearAwards");
|
||||||
|
dukglue_register_method(ctx, &ScPark::grantAward, "grantAward");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace OpenRCT2::Scripting
|
} // namespace OpenRCT2::Scripting
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#include "../../../Context.h"
|
#include "../../../Context.h"
|
||||||
#include "../../Duktape.hpp"
|
#include "../../Duktape.hpp"
|
||||||
|
#include "ScAward.hpp"
|
||||||
#include "ScParkMessage.hpp"
|
#include "ScParkMessage.hpp"
|
||||||
#include "ScResearch.hpp"
|
#include "ScResearch.hpp"
|
||||||
|
|
||||||
@@ -101,6 +102,12 @@ namespace OpenRCT2::Scripting
|
|||||||
|
|
||||||
std::vector<int32_t> getMonthlyExpenditure(const std::string& expenditureType) const;
|
std::vector<int32_t> getMonthlyExpenditure(const std::string& expenditureType) const;
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<ScAward>> awards_get() const;
|
||||||
|
|
||||||
|
void clearAwards() const;
|
||||||
|
|
||||||
|
void grantAward(const std::string& awardType) const;
|
||||||
|
|
||||||
static void Register(duk_context* ctx);
|
static void Register(duk_context* ctx);
|
||||||
};
|
};
|
||||||
} // namespace OpenRCT2::Scripting
|
} // namespace OpenRCT2::Scripting
|
||||||
|
|||||||
Reference in New Issue
Block a user