diff --git a/src/strings.cpp b/src/strings.cpp index eabeb09990..5a3f9295b3 100644 --- a/src/strings.cpp +++ b/src/strings.cpp @@ -851,7 +851,7 @@ static std::vector _game_script_raw_strings; */ static void FormatString(StringBuilder &builder, const char *str_arg, StringParameters &args, uint case_index, bool game_script, bool dry_run) { - size_t orig_offset = args.offset; + size_t orig_offset = args.GetOffset(); if (!dry_run && args.HasTypeInformation()) { /* @@ -876,7 +876,7 @@ static void FormatString(StringBuilder &builder, const char *str_arg, StringPara FormatString(dry_run_builder, str_arg, args, case_index, game_script, true); } /* We have to restore the original offset here to to read the correct values. */ - args.offset = orig_offset; + args.SetOffset(orig_offset); } WChar b = '\0'; uint next_substr_case_index = 0; @@ -1070,7 +1070,7 @@ static void FormatString(StringBuilder &builder, const char *str_arg, StringPara } case SCC_ARG_INDEX: { // Move argument pointer - args.offset = orig_offset + (byte)*str++; + args.SetOffset(orig_offset + (byte)*str++); break; } diff --git a/src/strings_internal.h b/src/strings_internal.h index 2feb282aa4..208f082a9d 100644 --- a/src/strings_internal.h +++ b/src/strings_internal.h @@ -20,9 +20,9 @@ protected: WChar *type; ///< Array with type information about the data. Can be nullptr when no type information is needed. See #StringControlCode. WChar next_type = 0; ///< The type of the next data that is retrieved. + size_t offset = 0; ///< Current offset in the data/type arrays. public: - size_t offset = 0; ///< Current offset in the data/type arrays. size_t num_param; ///< Length of the data array. /** Create a new StringParameters instance. */ @@ -60,6 +60,31 @@ public: void PrepareForNextRun(); void SetTypeOfNextParameter(WChar type) { this->next_type = type; } + /** + * Get the current offset, so it can be backed up for certain processing + * steps, or be used to offset the argument index within sub strings. + * @return The current offset. + */ + size_t GetOffset() { return this->offset; } + + /** + * Set the offset within the string from where to return the next result of + * \c GetInt64 or \c GetInt32. + * @param offset The offset. + */ + void SetOffset(size_t offset) + { + /* + * The offset must be fewer than the number of parameters when it is + * being set. Unless restoring a backup, then the original value is + * correct as well as long as the offset was not changed. In other + * words, when the offset was already at the end of the parameters and + * the string did not consume any parameters. + */ + assert(offset < this->num_param || this->offset == offset); + this->offset = offset; + } + int64 GetInt64(); /** Read an int32 from the argument array. @see GetInt64. */