| 256 | } |
| 257 | |
| 258 | void ScriptText::_GetEncodedText(StringBuilder &builder, int ¶m_count, ParamSpan args, bool first) |
| 259 | { |
| 260 | const std::string &name = GetGameStringName(this->string); |
| 261 | |
| 262 | if (first) { |
| 263 | builder.PutUtf8(SCC_ENCODED); |
| 264 | builder.PutIntegerBase(this->string.base(), 16); |
| 265 | } |
| 266 | |
| 267 | const StringParams ¶ms = GetGameStringParams(this->string); |
| 268 | |
| 269 | size_t idx = 0; |
| 270 | auto get_next_arg = [&]() { |
| 271 | if (idx >= args.size()) throw Script_FatalError(fmt::format("{}({}): Not enough parameters", name, param_count + 1)); |
| 272 | ParamCheck &pc = args[idx++]; |
| 273 | if (pc.owner != this->string) ScriptLog::Warning(fmt::format("{}({}): Consumes {}({})", name, param_count + 1, GetGameStringName(pc.owner), pc.idx + 1)); |
| 274 | return &pc; |
| 275 | }; |
| 276 | auto skip_args = [&](size_t nb) { idx += nb; }; |
| 277 | |
| 278 | for (const StringParam &cur_param : params) { |
| 279 | try { |
| 280 | switch (cur_param.type) { |
| 281 | case StringParam::UNUSED: |
| 282 | skip_args(cur_param.consumes); |
| 283 | break; |
| 284 | |
| 285 | case StringParam::RAW_STRING: |
| 286 | { |
| 287 | ParamCheck &p = *get_next_arg(); |
| 288 | p.Encode(builder, cur_param.cmd); |
| 289 | if (p.cmd != cur_param.cmd) throw 1; |
| 290 | if (!std::holds_alternative<std::string>(*p.param)) ScriptLog::Error(fmt::format("{}({}): {{{}}} expects a raw string", name, param_count + 1, cur_param.cmd)); |
| 291 | break; |
| 292 | } |
| 293 | |
| 294 | case StringParam::STRING: |
| 295 | { |
| 296 | ParamCheck &p = *get_next_arg(); |
| 297 | p.Encode(builder, cur_param.cmd); |
| 298 | if (p.cmd != cur_param.cmd) throw 1; |
| 299 | if (!std::holds_alternative<ScriptTextRef>(*p.param)) { |
| 300 | ScriptLog::Error(fmt::format("{}({}): {{{}}} expects a GSText", name, param_count + 1, cur_param.cmd)); |
| 301 | param_count++; |
| 302 | continue; |
| 303 | } |
| 304 | int count = 0; |
| 305 | ScriptTextRef &ref = std::get<ScriptTextRef>(*p.param); |
| 306 | ref->_GetEncodedText(builder, count, args.subspan(idx), false); |
| 307 | if (++count != cur_param.consumes) { |
| 308 | ScriptLog::Warning(fmt::format("{}({}): {{{}}} expects {} to be consumed, but {} consumes {}", name, param_count + 1, cur_param.cmd, cur_param.consumes - 1, GetGameStringName(ref->string), count - 1)); |
| 309 | /* Fill missing params if needed. */ |
| 310 | for (int i = count; i < cur_param.consumes; i++) { |
| 311 | builder.PutUtf8(SCC_RECORD_SEPARATOR); |
| 312 | } |
| 313 | } |
| 314 | skip_args(cur_param.consumes - 1); |
| 315 | break; |
no test coverage detected