From ae27ce12a755fb9685d96a237f5ef636e8318b69 Mon Sep 17 00:00:00 2001 From: glx22 Date: Thu, 29 Feb 2024 01:15:06 +0100 Subject: [PATCH] Fix 0858377: [Script] Don't output parameters more than once --- src/script/api/script_text.cpp | 26 +++++++++++++++----------- src/script/api/script_text.hpp | 3 ++- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/script/api/script_text.cpp b/src/script/api/script_text.cpp index 272302154f..83869e1216 100644 --- a/src/script/api/script_text.cpp +++ b/src/script/api/script_text.cpp @@ -166,7 +166,7 @@ std::string ScriptText::GetEncodedText() std::string result; auto output = std::back_inserter(result); this->_FillParamList(params, seen_texts); - this->_GetEncodedText(output, param_count, params); + this->_GetEncodedText(output, param_count, params, true); if (param_count > SCRIPT_TEXT_MAX_PARAMETERS) throw Script_FatalError(fmt::format("{}: Too many parameters", GetGameStringName(this->string))); return result; } @@ -191,16 +191,22 @@ void ScriptText::ParamCheck::Encode(std::back_insert_iterator &outp if (this->used) return; if (std::holds_alternative(*this->param)) fmt::format_to(output, ":\"{}\"", std::get(*this->param)); if (std::holds_alternative(*this->param)) fmt::format_to(output, ":{:X}", std::get(*this->param)); - if (std::holds_alternative(*this->param)) fmt::format_to(output, ":{:X}", this->owner); + if (std::holds_alternative(*this->param)) { + fmt::format_to(output, ":"); + Utf8Encode(output, SCC_ENCODED); + fmt::format_to(output, "{:X}", std::get(*this->param)->string); + } this->used = true; } -void ScriptText::_GetEncodedText(std::back_insert_iterator &output, int ¶m_count, ParamSpan args) +void ScriptText::_GetEncodedText(std::back_insert_iterator &output, int ¶m_count, ParamSpan args, bool first) { const std::string &name = GetGameStringName(this->string); - Utf8Encode(output, SCC_ENCODED); - fmt::format_to(output, "{:X}", this->string); + if (first) { + Utf8Encode(output, SCC_ENCODED); + fmt::format_to(output, "{:X}", this->string); + } const StringParams ¶ms = GetGameStringParams(this->string); @@ -221,23 +227,21 @@ void ScriptText::_GetEncodedText(std::back_insert_iterator &output, case StringParam::RAW_STRING: { ParamCheck &p = *get_next_arg(); - if (!std::holds_alternative(*p.param)) ScriptLog::Error(fmt::format("{}({}): {{{}}} expects a raw string", name, param_count + 1, cur_param.cmd)); p.Encode(output); + if (!std::holds_alternative(*p.param)) ScriptLog::Error(fmt::format("{}({}): {{{}}} expects a raw string", name, param_count + 1, cur_param.cmd)); break; } case StringParam::STRING: { ParamCheck &p = *get_next_arg(); + p.Encode(output); if (!std::holds_alternative(*p.param)){ ScriptLog::Error(fmt::format("{}({}): {{{}}} expects a GSText", name, param_count + 1, cur_param.cmd)); - p.Encode(output); break; } int count = 0; - fmt::format_to(output, ":"); ScriptTextRef &ref = std::get(*p.param); - ref->_GetEncodedText(output, count, args.subspan(idx)); - p.used = true; + ref->_GetEncodedText(output, count, args.subspan(idx), false); if (++count != cur_param.consumes) { ScriptLog::Error(fmt::format("{}({}): {{{}}} expects {} to be consumed, but {} consumes {}", name, param_count + 1, cur_param.cmd, cur_param.consumes - 1, GetGameStringName(ref->string), count - 1)); /* Fill missing params if needed. */ @@ -250,8 +254,8 @@ void ScriptText::_GetEncodedText(std::back_insert_iterator &output, default: for (int i = 0; i < cur_param.consumes; i++) { ParamCheck &p = *get_next_arg(); - if (!std::holds_alternative(*p.param)) ScriptLog::Error(fmt::format("{}({}): {{{}}} expects an integer", name, param_count + i + 1, cur_param.cmd)); p.Encode(output); + if (!std::holds_alternative(*p.param)) ScriptLog::Error(fmt::format("{}({}): {{{}}} expects an integer", name, param_count + i + 1, cur_param.cmd)); } } diff --git a/src/script/api/script_text.hpp b/src/script/api/script_text.hpp index e3c9ec6a2f..1b86f8f54b 100644 --- a/src/script/api/script_text.hpp +++ b/src/script/api/script_text.hpp @@ -165,8 +165,9 @@ private: * @param output The output to write the encoded text to. * @param param_count The number of parameters that are consumed by the string. * @param args The parameters to be consumed. + * @param first Whether it's the first call in the recursion. */ - void _GetEncodedText(std::back_insert_iterator &output, int ¶m_count, ParamSpan args); + void _GetEncodedText(std::back_insert_iterator &output, int ¶m_count, ParamSpan args, bool first); /** * Set a parameter, where the value is the first item on the stack.