1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2025-12-24 08:12:53 +01:00

Fix: #13509 [Plugin] Add ability to format strings

This commit is contained in:
Ted John
2020-11-22 23:17:40 +00:00
parent 030713e126
commit be8736ffaa
5 changed files with 62 additions and 1 deletions

View File

@@ -5,6 +5,7 @@
- Feature: [#13376] Open custom window at specified tab.
- Feature: [#13398] Add pause button to the Track Designer.
- Feature: [#13495] [Plugin] Add properties for park value, guests and company value.
- Feature: [#13509] [Plugin] Add ability to format strings using OpenRCT2 string framework.
- Change: [#13346] Change FootpathScenery to FootpathAddition in all occurrences.
- Fix: [#12895] Mechanics are called to repair rides that have already been fixed.
- Fix: [#13257] Rides that are exactly the minimum objective length are not counted.

View File

@@ -183,6 +183,13 @@ declare global {
*/
getRandom(min: number, max: number): number;
/**
* Formats a new string using the given format string and the arguments.
* @param fmt The format string, e.g. "Guests: {COMMA16}"
* @param args The arguments to insert into the string.
*/
formatString(fmt: string, ...args: any[]): string;
/**
* Registers a new game action that allows clients to interact with the game.
* @param action The unique name of the action.

View File

@@ -594,6 +594,10 @@ namespace OpenRCT2
{
ss << arg.c_str();
}
else if constexpr (std::is_same<T, std::string>())
{
ss << arg.c_str();
}
break;
case FormatToken::Sprite:
if constexpr (std::is_integral<T>())
@@ -663,6 +667,10 @@ namespace OpenRCT2
{
FormatArgument(ss, token, std::get<const char*>(value));
}
else if (std::holds_alternative<std::string>(value))
{
FormatArgument(ss, token, std::get<std::string>(value));
}
else
{
throw std::runtime_error("No support for format argument type.");

View File

@@ -23,7 +23,7 @@
namespace OpenRCT2
{
using FormatArg_t = std::variant<uint16_t, int32_t, const char*>;
using FormatArg_t = std::variant<uint16_t, int32_t, const char*, std::string>;
class FmtString
{

View File

@@ -13,6 +13,7 @@
# include "../actions/GameAction.h"
# include "../interface/Screenshot.h"
# include "../localisation/Formatting.h"
# include "../object/ObjectManager.h"
# include "../scenario/Scenario.h"
# include "Duktape.hpp"
@@ -154,6 +155,49 @@ namespace OpenRCT2::Scripting
return min + scenario_rand_max(range);
}
duk_ret_t formatString(duk_context* ctx)
{
auto nargs = duk_get_top(ctx);
if (nargs >= 1)
{
auto dukFmt = DukValue::copy_from_stack(ctx, 0);
if (dukFmt.type() == DukValue::Type::STRING)
{
FmtString fmt(dukFmt.as_string());
std::vector<FormatArg_t> args;
for (duk_idx_t i = 1; i < nargs; i++)
{
auto dukArg = DukValue::copy_from_stack(ctx, i);
switch (dukArg.type())
{
case DukValue::Type::NUMBER:
args.push_back(dukArg.as_int());
break;
case DukValue::Type::STRING:
args.push_back(dukArg.as_string());
break;
default:
duk_error(ctx, DUK_ERR_ERROR, "Invalid format argument.");
break;
}
}
auto result = FormatStringAny(fmt, args);
duk_push_lstring(ctx, result.c_str(), result.size());
}
else
{
duk_error(ctx, DUK_ERR_ERROR, "Invalid format string.");
}
}
else
{
duk_error(ctx, DUK_ERR_ERROR, "Invalid format string.");
}
return 1;
}
std::shared_ptr<ScDisposable> subscribe(const std::string& hook, const DukValue& callback)
{
auto& scriptEngine = GetContext()->GetScriptEngine();
@@ -289,6 +333,7 @@ namespace OpenRCT2::Scripting
dukglue_register_method(ctx, &ScContext::getObject, "getObject");
dukglue_register_method(ctx, &ScContext::getAllObjects, "getAllObjects");
dukglue_register_method(ctx, &ScContext::getRandom, "getRandom");
dukglue_register_method_varargs(ctx, &ScContext::formatString, "formatString");
dukglue_register_method(ctx, &ScContext::subscribe, "subscribe");
dukglue_register_method(ctx, &ScContext::queryAction, "queryAction");
dukglue_register_method(ctx, &ScContext::executeAction, "executeAction");