mirror of https://github.com/OpenTTD/OpenTTD
Fix: [NewGRF] Plurals and genders did not work in strings with cases. (#13853)
parent
d4ae0f70da
commit
af49320637
|
@ -128,7 +128,7 @@ struct UnmappedChoiceList {
|
||||||
* @param lm The current language mapping.
|
* @param lm The current language mapping.
|
||||||
* @param dest Target to write to.
|
* @param dest Target to write to.
|
||||||
*/
|
*/
|
||||||
void Flush(const LanguageMap *lm, std::ostringstream &dest)
|
void Flush(const LanguageMap *lm, std::stringstream &dest)
|
||||||
{
|
{
|
||||||
if (this->strings.find(0) == this->strings.end()) {
|
if (this->strings.find(0) == this->strings.end()) {
|
||||||
/* In case of a (broken) NewGRF without a default,
|
/* In case of a (broken) NewGRF without a default,
|
||||||
|
@ -251,10 +251,11 @@ std::string TranslateTTDPatchCodes(uint32_t grfid, uint8_t language_id, bool all
|
||||||
src += len;
|
src += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Helper variable for a possible (string) mapping. */
|
/* Helper variable for a possible (string) mapping of plural/gender and cases. */
|
||||||
std::optional<UnmappedChoiceList> mapping;
|
std::optional<UnmappedChoiceList> mapping_pg, mapping_c;
|
||||||
|
std::optional<std::reference_wrapper<std::stringstream>> dest_c;
|
||||||
|
|
||||||
std::ostringstream dest;
|
std::stringstream dest;
|
||||||
std::ostreambuf_iterator<char> d(dest);
|
std::ostreambuf_iterator<char> d(dest);
|
||||||
while (src != str.cend()) {
|
while (src != str.cend()) {
|
||||||
char32_t c;
|
char32_t c;
|
||||||
|
@ -381,37 +382,44 @@ std::string TranslateTTDPatchCodes(uint32_t grfid, uint8_t language_id, bool all
|
||||||
case 0x10:
|
case 0x10:
|
||||||
case 0x11:
|
case 0x11:
|
||||||
if (str[0] == '\0') goto string_end;
|
if (str[0] == '\0') goto string_end;
|
||||||
if (!mapping.has_value()) {
|
if (!mapping_pg.has_value() && !mapping_c.has_value()) {
|
||||||
if (code == 0x10) src++; // Skip the index
|
if (code == 0x10) src++; // Skip the index
|
||||||
GrfMsg(1, "choice list {} marker found when not expected", code == 0x10 ? "next" : "default");
|
GrfMsg(1, "choice list {} marker found when not expected", code == 0x10 ? "next" : "default");
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
|
auto &mapping = mapping_pg ? mapping_pg : mapping_c;
|
||||||
int index = (code == 0x10 ? *src++ : 0);
|
int index = (code == 0x10 ? *src++ : 0);
|
||||||
if (mapping->strings.find(index) != mapping->strings.end()) {
|
if (mapping->strings.find(index) != mapping->strings.end()) {
|
||||||
GrfMsg(1, "duplicate choice list string, ignoring");
|
GrfMsg(1, "duplicate choice list string, ignoring");
|
||||||
} else {
|
} else {
|
||||||
d = std::ostreambuf_iterator<char>(mapping->strings[index]);
|
d = std::ostreambuf_iterator<char>(mapping->strings[index]);
|
||||||
|
if (!mapping_pg) dest_c = mapping->strings[index];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x12:
|
case 0x12:
|
||||||
if (!mapping.has_value()) {
|
if (!mapping_pg.has_value() && !mapping_c.has_value()) {
|
||||||
GrfMsg(1, "choice list end marker found when not expected");
|
GrfMsg(1, "choice list end marker found when not expected");
|
||||||
} else {
|
} else {
|
||||||
|
auto &mapping = mapping_pg ? mapping_pg : mapping_c;
|
||||||
|
auto &new_dest = mapping_pg && dest_c ? dest_c->get() : dest;
|
||||||
/* Now we can start flushing everything and clean everything up. */
|
/* Now we can start flushing everything and clean everything up. */
|
||||||
mapping->Flush(LanguageMap::GetLanguageMap(grfid, language_id), dest);
|
mapping->Flush(LanguageMap::GetLanguageMap(grfid, language_id), new_dest);
|
||||||
|
if (!mapping_pg) dest_c.reset();
|
||||||
mapping.reset();
|
mapping.reset();
|
||||||
|
|
||||||
d = std::ostreambuf_iterator<char>(dest);
|
d = std::ostreambuf_iterator<char>(new_dest);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x13:
|
case 0x13:
|
||||||
case 0x14:
|
case 0x14:
|
||||||
case 0x15:
|
case 0x15: {
|
||||||
|
auto &mapping = code == 0x14 ? mapping_c : mapping_pg;
|
||||||
if (src[0] == '\0') goto string_end;
|
if (src[0] == '\0') goto string_end;
|
||||||
if (mapping.has_value()) {
|
/* Case mapping can have nested plural/gender mapping. Otherwise nesting is invalid. */
|
||||||
|
if (mapping.has_value() || mapping_pg.has_value()) {
|
||||||
GrfMsg(1, "choice lists can't be stacked, it's going to get messy now...");
|
GrfMsg(1, "choice lists can't be stacked, it's going to get messy now...");
|
||||||
if (code != 0x14) src++;
|
if (code != 0x14) src++;
|
||||||
} else {
|
} else {
|
||||||
|
@ -419,6 +427,7 @@ std::string TranslateTTDPatchCodes(uint32_t grfid, uint8_t language_id, bool all
|
||||||
mapping.emplace(mp[code - 0x13], code == 0x14 ? 0 : *src++);
|
mapping.emplace(mp[code - 0x13], code == 0x14 ? 0 : *src++);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 0x16:
|
case 0x16:
|
||||||
case 0x17:
|
case 0x17:
|
||||||
|
@ -468,7 +477,7 @@ std::string TranslateTTDPatchCodes(uint32_t grfid, uint8_t language_id, bool all
|
||||||
}
|
}
|
||||||
|
|
||||||
string_end:
|
string_end:
|
||||||
if (mapping.has_value()) {
|
if (mapping_pg.has_value() || mapping_c.has_value()) {
|
||||||
GrfMsg(1, "choice list was incomplete, the whole list is ignored");
|
GrfMsg(1, "choice list was incomplete, the whole list is ignored");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue