mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2025-12-10 09:32:29 +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)
|
||||
------------------------------------------------------------------------
|
||||
- Feature: [#24468] [Plugin] Add awards to plugin API.
|
||||
- Feature: [#24702] [Plugin] Add bindings for missing cheats (forcedParkRating, ignoreRidePrice, makeAllDestructible).
|
||||
- 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" |
|
||||
"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 {
|
||||
cash: number;
|
||||
rating: number;
|
||||
@@ -4326,6 +4373,25 @@ declare global {
|
||||
* @param type The type of expenditure to get.
|
||||
*/
|
||||
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 {
|
||||
|
||||
@@ -1290,23 +1290,6 @@ namespace OpenRCT2
|
||||
// Window: Park
|
||||
STR_ADMISSION_PRICE = 1756,
|
||||
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_CLOSE_PARK = 1013,
|
||||
STR_CLOSE_PARK_TIP = 5296,
|
||||
|
||||
@@ -164,31 +164,6 @@ namespace OpenRCT2::Ui::Windows
|
||||
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
|
||||
|
||||
class ParkWindow final : public Window
|
||||
@@ -1164,8 +1139,8 @@ namespace OpenRCT2::Ui::Windows
|
||||
|
||||
for (const auto& award : currentAwards)
|
||||
{
|
||||
GfxDrawSprite(rt, ImageId(_parkAwards[EnumValue(award.Type)].sprite), screenCoords);
|
||||
DrawTextWrapped(rt, screenCoords + ScreenCoordsXY{ 34, 6 }, 180, _parkAwards[EnumValue(award.Type)].text);
|
||||
GfxDrawSprite(rt, ImageId(AwardGetSprite(award.Type)), screenCoords);
|
||||
DrawTextWrapped(rt, screenCoords + ScreenCoordsXY{ 34, 6 }, 180, AwardGetText(award.Type));
|
||||
|
||||
screenCoords.y += 32;
|
||||
}
|
||||
|
||||
@@ -595,6 +595,7 @@
|
||||
<ClInclude Include="scripting\bindings\ride\ScRideStation.hpp" />
|
||||
<ClInclude Include="scripting\bindings\ride\ScTrackIterator.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\ScDate.hpp" />
|
||||
<ClInclude Include="scripting\bindings\world\ScMap.hpp" />
|
||||
@@ -1117,6 +1118,7 @@
|
||||
<ClCompile Include="scripting\bindings\ride\ScRideStation.cpp" />
|
||||
<ClCompile Include="scripting\bindings\ride\ScTrackIterator.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\ScPark.cpp" />
|
||||
<ClCompile Include="scripting\bindings\world\ScParkMessage.cpp" />
|
||||
|
||||
@@ -1096,6 +1096,23 @@ enum : StringId
|
||||
STR_PEEPS_CANT_FIND_TOILET = 2811,
|
||||
STR_PEEPS_GETTING_LOST_OR_STUCK = 2812,
|
||||
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_MOST_TIDY = STR_NEWS_ITEM_AWARD_MOST_UNTIDY + 1,
|
||||
STR_NEWS_ITEM_BEST_ROLLERCOASTERS = STR_NEWS_ITEM_AWARD_MOST_UNTIDY + 2,
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include "../config/Config.h"
|
||||
#include "../entity/EntityList.h"
|
||||
#include "../entity/Guest.h"
|
||||
#include "../localisation/StringIds.h"
|
||||
#include "../profiling/Profiling.h"
|
||||
#include "../ride/Ride.h"
|
||||
#include "../ride/RideData.h"
|
||||
@@ -29,49 +28,55 @@ enum class AwardEffect : uint8_t
|
||||
negative,
|
||||
positive
|
||||
};
|
||||
static constexpr AwardEffect kAwardPositiveMap[] = {
|
||||
AwardEffect::negative, // AwardType::MostUntidy
|
||||
AwardEffect::positive, // AwardType::MostTidy
|
||||
AwardEffect::positive, // AwardType::BestRollerCoasters
|
||||
AwardEffect::positive, // AwardType::BestValue
|
||||
AwardEffect::positive, // AwardType::MostBeautiful
|
||||
AwardEffect::negative, // AwardType::WorstValue
|
||||
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
|
||||
|
||||
struct AwardData_t
|
||||
{
|
||||
StringId text;
|
||||
StringId news;
|
||||
ImageIndex sprite;
|
||||
AwardEffect effect;
|
||||
};
|
||||
|
||||
static constexpr StringId AwardNewsStrings[] = {
|
||||
STR_NEWS_ITEM_AWARD_MOST_UNTIDY,
|
||||
STR_NEWS_ITEM_MOST_TIDY,
|
||||
STR_NEWS_ITEM_BEST_ROLLERCOASTERS,
|
||||
STR_NEWS_ITEM_BEST_VALUE,
|
||||
STR_NEWS_ITEM_MOST_BEAUTIFUL,
|
||||
STR_NEWS_ITEM_WORST_VALUE,
|
||||
STR_NEWS_ITEM_SAFEST,
|
||||
STR_NEWS_ITEM_BEST_STAFF,
|
||||
STR_NEWS_ITEM_BEST_FOOD,
|
||||
STR_NEWS_ITEM_WORST_FOOD,
|
||||
STR_NEWS_ITEM_BEST_TOILETS,
|
||||
STR_NEWS_ITEM_MOST_DISAPPOINTING,
|
||||
STR_NEWS_ITEM_BEST_WATER_RIDES,
|
||||
STR_NEWS_ITEM_BEST_CUSTOM_DESIGNED_RIDES,
|
||||
STR_NEWS_ITEM_MOST_DAZZLING_RIDE_COLOURS,
|
||||
STR_NEWS_ITEM_MOST_CONFUSING_LAYOUT,
|
||||
STR_NEWS_ITEM_BEST_GENTLE_RIDES,
|
||||
// clang-format off
|
||||
static constexpr AwardData_t AwardData[] = {
|
||||
{ STR_AWARD_MOST_UNTIDY, STR_NEWS_ITEM_AWARD_MOST_UNTIDY, SPR_AWARD_MOST_UNTIDY, AwardEffect::negative },
|
||||
{ STR_AWARD_MOST_TIDY, STR_NEWS_ITEM_MOST_TIDY, SPR_AWARD_MOST_TIDY, AwardEffect::positive },
|
||||
{ STR_AWARD_BEST_ROLLERCOASTERS, STR_NEWS_ITEM_BEST_ROLLERCOASTERS, SPR_AWARD_BEST_ROLLERCOASTERS, AwardEffect::positive },
|
||||
{ STR_AWARD_BEST_VALUE, STR_NEWS_ITEM_BEST_VALUE, SPR_AWARD_BEST_VALUE, AwardEffect::positive },
|
||||
{ STR_AWARD_MOST_BEAUTIFUL, STR_NEWS_ITEM_MOST_BEAUTIFUL, SPR_AWARD_MOST_BEAUTIFUL, AwardEffect::positive },
|
||||
{ STR_AWARD_WORST_VALUE, STR_NEWS_ITEM_WORST_VALUE, SPR_AWARD_WORST_VALUE, AwardEffect::negative },
|
||||
{ STR_AWARD_SAFEST, STR_NEWS_ITEM_SAFEST, SPR_AWARD_SAFEST, AwardEffect::positive },
|
||||
{ STR_AWARD_BEST_STAFF, STR_NEWS_ITEM_BEST_STAFF, SPR_AWARD_BEST_STAFF, AwardEffect::positive },
|
||||
{ STR_AWARD_BEST_FOOD, STR_NEWS_ITEM_BEST_FOOD, SPR_AWARD_BEST_FOOD, AwardEffect::positive },
|
||||
{ STR_AWARD_WORST_FOOD, STR_NEWS_ITEM_WORST_FOOD, SPR_AWARD_WORST_FOOD, AwardEffect::negative },
|
||||
{ STR_AWARD_BEST_TOILETS, STR_NEWS_ITEM_BEST_TOILETS, SPR_AWARD_BEST_TOILETS, AwardEffect::positive },
|
||||
{ STR_AWARD_MOST_DISAPPOINTING, STR_NEWS_ITEM_MOST_DISAPPOINTING, SPR_AWARD_MOST_DISAPPOINTING, AwardEffect::negative },
|
||||
{ STR_AWARD_BEST_WATER_RIDES, STR_NEWS_ITEM_BEST_WATER_RIDES, SPR_AWARD_BEST_WATER_RIDES, AwardEffect::positive },
|
||||
{ STR_AWARD_BEST_CUSTOM_DESIGNED_RIDES, STR_NEWS_ITEM_BEST_CUSTOM_DESIGNED_RIDES, SPR_AWARD_BEST_CUSTOM_DESIGNED_RIDES, AwardEffect::positive },
|
||||
{ STR_AWARD_MOST_DAZZLING_RIDE_COLOURS, STR_NEWS_ITEM_MOST_DAZZLING_RIDE_COLOURS, SPR_AWARD_MOST_DAZZLING_RIDE_COLOURS, AwardEffect::positive },
|
||||
{ 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)
|
||||
{
|
||||
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
|
||||
@@ -598,6 +603,16 @@ void AwardReset()
|
||||
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
|
||||
@@ -648,14 +663,24 @@ void AwardUpdateAll()
|
||||
// Check if award is deserved
|
||||
if (AwardIsDeserved(awardType, activeAwardTypes))
|
||||
{
|
||||
// Add award
|
||||
currentAwards.push_back(Award{ 5u, awardType });
|
||||
if (Config::Get().notifications.ParkAward)
|
||||
{
|
||||
News::AddItemToQueue(News::ItemType::award, AwardNewsStrings[EnumValue(awardType)], 0, {});
|
||||
}
|
||||
windowMgr->InvalidateByClass(WindowClass::ParkInformation);
|
||||
AwardAdd(awardType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AwardGrant(AwardType type)
|
||||
{
|
||||
auto& currentAwards = getGameState().currentAwards;
|
||||
|
||||
// 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
|
||||
|
||||
#include "../SpriteIds.h"
|
||||
#include "../localisation/StringIds.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
@@ -42,5 +45,9 @@ struct Award
|
||||
};
|
||||
|
||||
bool AwardIsPositive(AwardType type);
|
||||
ImageIndex AwardGetSprite(AwardType type);
|
||||
StringId AwardGetText(AwardType type);
|
||||
StringId AwardGetNews(AwardType type);
|
||||
void AwardGrant(AwardType type);
|
||||
void AwardReset();
|
||||
void AwardUpdateAll();
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
#include "bindings/object/ScObjectManager.h"
|
||||
#include "bindings/ride/ScRide.hpp"
|
||||
#include "bindings/ride/ScRideStation.hpp"
|
||||
#include "bindings/world/ScAward.hpp"
|
||||
#include "bindings/world/ScClimate.hpp"
|
||||
#include "bindings/world/ScDate.hpp"
|
||||
#include "bindings/world/ScMap.hpp"
|
||||
@@ -403,6 +404,7 @@ void ScriptEngine::Initialise()
|
||||
throw std::runtime_error("Script engine already initialised.");
|
||||
|
||||
auto ctx = static_cast<duk_context*>(_context);
|
||||
ScAward::Register(ctx);
|
||||
ScCheats::Register(ctx);
|
||||
ScClimate::Register(ctx);
|
||||
ScWeatherState::Register(ctx);
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace OpenRCT2
|
||||
|
||||
namespace OpenRCT2::Scripting
|
||||
{
|
||||
static constexpr int32_t kPluginApiVersion = 109;
|
||||
static constexpr int32_t kPluginApiVersion = 110;
|
||||
|
||||
// Versions marking breaking changes.
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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::postMessage, "postMessage");
|
||||
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
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include "../../../Context.h"
|
||||
#include "../../Duktape.hpp"
|
||||
#include "ScAward.hpp"
|
||||
#include "ScParkMessage.hpp"
|
||||
#include "ScResearch.hpp"
|
||||
|
||||
@@ -101,6 +102,12 @@ namespace OpenRCT2::Scripting
|
||||
|
||||
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);
|
||||
};
|
||||
} // namespace OpenRCT2::Scripting
|
||||
|
||||
Reference in New Issue
Block a user