summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/newgrf.cpp14
-rw-r--r--src/newgrf_text.cpp19
-rw-r--r--src/newgrf_text.h1
3 files changed, 26 insertions, 8 deletions
diff --git a/src/newgrf.cpp b/src/newgrf.cpp
index 0b9382732..fca8f96bf 100644
--- a/src/newgrf.cpp
+++ b/src/newgrf.cpp
@@ -1911,7 +1911,8 @@ static ChangeInfoResult GlobalVarChangeInfo(uint gvid, int numinfo, int prop, By
break;
case 0x13: // Gender translation table
- case 0x14: { // Case translation table
+ case 0x14: // Case translation table
+ case 0x15: { // Plural form translation
uint curidx = gvid + i; // The current index, i.e. language.
const LanguageMetadata *lang = curidx < MAX_LANG ? GetLanguage(curidx) : NULL;
if (lang == NULL) {
@@ -1925,6 +1926,16 @@ static ChangeInfoResult GlobalVarChangeInfo(uint gvid, int numinfo, int prop, By
if (_cur_grffile->language_map == NULL) _cur_grffile->language_map = new LanguageMap[MAX_LANG];
+ if (prop == 0x15) {
+ uint plural_form = buf->ReadByte();
+ if (plural_form >= LANGUAGE_MAX_PLURAL) {
+ grfmsg(1, "GlobalVarChanceInfo: Plural form %d is out of range, ignoring", plural_form);
+ } else {
+ _cur_grffile->language_map[curidx].plural_form = plural_form;
+ }
+ break;
+ }
+
byte newgrf_id = buf->ReadByte(); // The NewGRF (custom) identifier.
while (newgrf_id != 0) {
const char *name = buf->ReadString(); // The name for the OpenTTD identifier.
@@ -1975,6 +1986,7 @@ static ChangeInfoResult GlobalVarReserveInfo(uint gvid, int numinfo, int prop, B
for (int i = 0; i < numinfo; i++) {
switch (prop) {
case 0x08: // Cost base factor
+ case 0x15: // Plural form translation
buf->ReadByte();
break;
diff --git a/src/newgrf_text.cpp b/src/newgrf_text.cpp
index 732261c9c..a1045056f 100644
--- a/src/newgrf_text.cpp
+++ b/src/newgrf_text.cpp
@@ -263,7 +263,7 @@ struct UnmappedChoiceList : ZeroedMemoryAllocator {
* Initialise the mapping.
* @param type The type of mapping.
* @param old_d The old begin of the string, i.e. from where to start writing again.
- * @param offset The offset to get the gender from.
+ * @param offset The offset to get the plural/gender from.
*/
UnmappedChoiceList(StringControlCode type, char *old_d, int offset) :
type(type), old_d(old_d), offset(offset)
@@ -272,7 +272,7 @@ struct UnmappedChoiceList : ZeroedMemoryAllocator {
StringControlCode type; ///< The type of choice list.
char *old_d; ///< The old/original location of the "d" local variable.
- int offset; ///< The offset for the gender form.
+ int offset; ///< The offset for the plural/gender form.
/** Mapping of NewGRF supplied ID to the different strings in the choice list. */
SmallMap<byte, char *> strings;
@@ -292,7 +292,7 @@ struct UnmappedChoiceList : ZeroedMemoryAllocator {
}
char *d = old_d;
- if (lm == NULL) {
+ if (lm == NULL && this->type != SCC_PLURAL_LIST) {
NOT_REACHED();
/* In case there is no mapping, just ignore everything but the default. */
int len = strlen(this->strings[0]);
@@ -343,6 +343,10 @@ struct UnmappedChoiceList : ZeroedMemoryAllocator {
d += len;
*d++ = '\0';
} else {
+ if (this->type == SCC_PLURAL_LIST) {
+ *d++ = lm->plural_form;
+ }
+
/*
* Format for choice list:
* <OFFSET> <NUM CHOICES> <LENs> <STRINGs>
@@ -352,12 +356,12 @@ struct UnmappedChoiceList : ZeroedMemoryAllocator {
*d++ = this->offset - 0x80;
/* "<NUM CHOICES>" */
- int count = _current_language->num_genders;
+ int count = (this->type == SCC_GENDER_LIST ? _current_language->num_genders : LANGUAGE_MAX_PLURAL_FORMS);
*d++ = count;
/* "<LENs>" */
for (int i = 0; i < count; i++) {
- int idx = lm->GetReverseMapping(i, true);
+ int idx = (this->type == SCC_GENDER_LIST ? lm->GetReverseMapping(i, true) : i + 1);
const char *str = this->strings[this->strings.Contains(idx) ? idx : 0];
int len = strlen(str) + 1;
if (len > 0xFF) grfmsg(1, "choice list string is too long");
@@ -366,7 +370,7 @@ struct UnmappedChoiceList : ZeroedMemoryAllocator {
/* "<STRINGs>" */
for (int i = 0; i < count; i++) {
- int idx = lm->GetReverseMapping(i, true);
+ int idx = (this->type == SCC_GENDER_LIST ? lm->GetReverseMapping(i, true) : i + 1);
const char *str = this->strings[this->strings.Contains(idx) ? idx : 0];
int len = strlen(str);
memcpy(d, str, len);
@@ -546,11 +550,12 @@ char *TranslateTTDPatchCodes(uint32 grfid, uint8 language_id, const char *str, i
case 0x13:
case 0x14:
+ case 0x15:
if (mapping != NULL) {
grfmsg(1, "choice lists can't be stacked, it's going to get messy now...");
if (code != 0x14) str++;
} else {
- static const StringControlCode mp[] = { SCC_GENDER_LIST, SCC_SWITCH_CASE };
+ static const StringControlCode mp[] = { SCC_GENDER_LIST, SCC_SWITCH_CASE, SCC_PLURAL_LIST };
mapping = new UnmappedChoiceList(mp[code - 0x13], d, code == 0x14 ? 0 : *str++);
}
break;
diff --git a/src/newgrf_text.h b/src/newgrf_text.h
index dc069a93e..a4c5f6123 100644
--- a/src/newgrf_text.h
+++ b/src/newgrf_text.h
@@ -59,6 +59,7 @@ struct LanguageMap {
* both cases. Thus we are basically implementing a multi-map. */
SmallVector<Mapping, 1> gender_map; ///< Mapping of NewGRF and OpenTTD IDs for genders.
SmallVector<Mapping, 1> case_map; ///< Mapping of NewGRF and OpenTTD IDs for cases.
+ int plural_form; ///< The plural form used for this language.
int GetMapping(int newgrf_id, bool gender) const;
int GetReverseMapping(int openttd_id, bool gender) const;