ihhub / fheroes2

fheroes2 is a recreation of Heroes of Might and Magic II game engine.
https://ihhub.github.io/fheroes2/
GNU General Public License v2.0
2.6k stars 365 forks source link

Monster::GetPluralName is broken #3929

Closed dimag0g closed 2 years ago

dimag0g commented 2 years ago

There is a problem with Monster::GetPluralName for which I don't see a good fix. Right now it uses _n( ) which is incompatible with Monster::GetName and Monster::GetMultiName which use _( ). It works for most of the monsters where singular and plural forms are next to each other in the .mo file, but e.g. for Goblin/Goblins there will be Goblin Hut in between, so we'll end up with "Goblins" translated as "Goblin Hut" by _n( ). We need to either use _( ) everywhere and hard-code the plural form logic in Monster::GetPluralName, or use _n( ) everywhere.

However, fixing this issue completely with just _n( ) will not be possible for languages like Russian, where "monsters" and "5 monsters" have different forms (the latter is Genitive case). I'm not familiar with Polish, but I expect a similar problem there as well.

One solution would be to use the singular form everywhere except for troop quantities (5 goblins/several goblins), like the original HoMM2 version does. This avoids the problem in Russian there it simply says "goblin" on e.g. troop info pages, regardless of how many goblins you have: homm2_ru

Another solution is to use the form goblins (5) / goblins (several) for troop quantities, like the Polish version does, though it doesn't sound very natural: homm2_pl

AAS commented 2 years ago

Hello. Isn't it already handled by gettext and .po with a header like:

"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);\n"

and string should be like:

msgid "{:d} Goblin"
msgid_plural "{:d} Goblins"
msgstr[0] "{:d} гоблин"
msgstr[1] "{:d} гоблина"
msgstr[2] "{:d} гоблинов"
dimag0g commented 2 years ago

@AAS This will only handle cases like recruit/dismiss 1/2/5 Goblins?. I'm not sure we actually have those.

What we have is:

This IMO leaves us with the following options:

Note that none of the options use the ngettext plural forms. I currently have an open PR (#3913) which essentially implements the third option (or the first one, there is no difference between the two as far as the source code is concerned).

dimag0g commented 2 years ago

I'm closing this for now, feel free to comment and reopen if you think you have a better idea on this matter.