18 #include "strings_internal.h"
30 grfid(t->townnamegrfid),
33 if (t->townnamegrfid != 0 && GetGRFTownName(t->townnamegrfid) ==
nullptr) {
36 this->
type = SPECSTR_TOWNNAME_ENGLISH;
50 if (par->
grfid == 0) {
51 auto tmp_params = MakeParameters(townnameparts);
56 GRFTownNameGenerate(builder, par->
grfid, par->
type, townnameparts);
110 if (town_names !=
nullptr) {
111 if (town_names->find(name) != town_names->end())
return false;
112 town_names->insert(name);
117 if (t->name.empty()) {
120 if (name == t->name)
return false;
149 for (
int i = 1000; i != 0; i--) {
150 uint32_t r = randomizer.
Next();
169 static inline uint32_t
SeedChance(
byte shift_by,
int max, uint32_t seed)
171 return (
GB(seed, shift_by, 16) * max) >> 16;
193 return (seed >> shift_by) % max;
205 static inline int32_t
SeedChanceBias(
byte shift_by,
int max, uint32_t seed,
int bias)
207 return SeedChance(shift_by, max + bias, seed) - bias;
220 assert(strlen(org) == 4 && strlen(rep) == 4 && builder.
CurrentIndex() - start >= 4);
221 if (strncmp(&builder[start], org, 4) == 0) memcpy(&builder[start], rep, 4);
236 if (!original)
ReplaceWords(
"Fart",
"Boot", builder, start);
242 ReplaceWords(
"Wrar", original ?
"Inve" :
"Stan", builder, start);
256 if (i >= 0) builder += _name_original_english_1[i];
259 builder += _name_original_english_2[
SeedChance(4,
lengthof(_name_original_english_2), seed)];
260 builder += _name_original_english_3[
SeedChance(7,
lengthof(_name_original_english_3), seed)];
261 builder += _name_original_english_4[
SeedChance(10,
lengthof(_name_original_english_4), seed)];
262 builder += _name_original_english_5[
SeedChance(13,
lengthof(_name_original_english_5), seed)];
266 if (i >= 0) builder += _name_original_english_6[i];
269 if (builder[start] ==
'C' && (builder[start + 1] ==
'e' || builder[start + 1] ==
'i')) {
270 builder[start] =
'K';
289 if (i >= 0) builder += _name_additional_english_prefix[i];
292 builder += _name_additional_english_1a[
SeedChance(6,
lengthof(_name_additional_english_1a), seed)];
294 builder += _name_additional_english_1b1[
SeedChance(6,
lengthof(_name_additional_english_1b1), seed)];
295 builder += _name_additional_english_1b2[
SeedChance(9,
lengthof(_name_additional_english_1b2), seed)];
297 builder += _name_additional_english_1b3a[
SeedChance(12,
lengthof(_name_additional_english_1b3a), seed)];
299 builder += _name_additional_english_1b3b[
SeedChance(12,
lengthof(_name_additional_english_1b3b), seed)];
303 builder += _name_additional_english_2[
SeedChance(14,
lengthof(_name_additional_english_2), seed)];
307 if (i >= 0) builder += _name_additional_english_3[i];
323 if (i >= 0) builder += _name_austrian_a1[i];
347 }
else if (i >= 2 - j) {
362 uint seed_derivative =
SeedChance(7, 28, seed);
365 if (seed_derivative == 12 || seed_derivative == 19) {
367 builder += _name_german_pre[i];
372 if (i <
lengthof(_name_german_real)) {
373 builder += _name_german_real[i];
375 builder += _name_german_1[i -
lengthof(_name_german_real)];
378 builder += _name_german_2[i];
382 if (seed_derivative == 24) {
384 if (i <
lengthof(_name_german_4_an_der)) {
385 builder += _name_german_3_an_der[0];
386 builder += _name_german_4_an_der[i];
388 builder += _name_german_3_am[0];
389 builder += _name_german_4_am[i -
lengthof(_name_german_4_an_der)];
438 if (i >= 0) builder += _name_swedish_1[i];
462 if (i >= 0) builder += _name_dutch_1[i];
496 builder += _name_finnish_1[sel];
498 if (builder[last] ==
'i') builder[last] =
'e';
500 std::string_view view(&builder[start], builder.
CurrentIndex() - start);
501 if (view.find_first_of(
"aouAOU") != std::string_view::npos) {
504 builder +=
"l\u00e4";
512 if (sel >=
lengthof(_name_finnish_1)) {
513 builder += _name_finnish_2[sel -
lengthof(_name_finnish_1)];
515 builder += _name_finnish_1[sel];
537 if (i <
lengthof(_name_polish_2_o)) {
549 if (j >= 4 && j < 16) {
563 if (j >= 4 && j < 16) {
576 if (j >= 4 && j < 16) {
600 bool do_prefix = prob_tails < 12;
601 bool do_suffix = prob_tails > 11 && prob_tails < 17;
605 int prefix = 0, ending = 0, suffix = 0;
620 if (stem <
lengthof(_name_czech_subst_full)) {
622 dynamic_subst =
false;
623 gender = _name_czech_subst_full[stem].gender;
624 choose = _name_czech_subst_full[stem].choose;
625 allow = _name_czech_subst_full[stem].allow;
627 uint map[
lengthof(_name_czech_subst_ending)];
628 int ending_start = -1, ending_stop = -1;
631 dynamic_subst =
true;
632 stem -=
lengthof(_name_czech_subst_full);
633 stem %=
lengthof(_name_czech_subst_stem);
634 gender = _name_czech_subst_stem[stem].gender;
635 choose = _name_czech_subst_stem[stem].choose;
636 allow = _name_czech_subst_stem[stem].allow;
641 if (choose & CZC_POSTFIX) {
643 postfix %=
lengthof(_name_czech_subst_postfix);
645 if (choose & CZC_NOPOSTFIX) {
647 postfix +=
lengthof(_name_czech_subst_postfix);
649 if (postfix <
lengthof(_name_czech_subst_postfix)) {
650 choose |= CZC_POSTFIX;
652 choose |= CZC_NOPOSTFIX;
656 for (ending = 0; ending < (int)
lengthof(_name_czech_subst_ending); ending++) {
659 if (gender == CZG_FREE ||
660 (gender == CZG_NFREE && e->gender != CZG_SNEUT && e->gender != CZG_PNEUT) ||
661 gender == e->gender) {
662 if (ending_start < 0) {
663 ending_start = ending;
665 }
else if (ending_start >= 0) {
666 ending_stop = ending - 1;
670 if (ending_stop < 0) {
672 ending_stop = ending - 1;
677 for (ending = ending_start; ending <= ending_stop; ending++) {
680 if ((e->choose & choose) == choose && (e->allow & allow) != 0) {
690 gender = _name_czech_subst_ending[ending].gender;
691 assert(gender != CZG_FREE && gender != CZG_NFREE);
694 if (do_prefix && (_name_czech_adj[prefix].choose & choose) != choose) {
701 CzechPattern pattern = _name_czech_adj[prefix].pattern;
703 builder += _name_czech_adj[prefix].name;
707 while (
GB(builder[endpos], 6, 2) == 2) endpos--;
710 if (gender == CZG_SMASC && pattern == CZP_PRIVL) {
712 builder[endpos - 2] =
'u';
714 builder += _name_czech_patmod[gender][pattern];
721 builder += _name_czech_subst_stem[stem].name;
722 if (postfix <
lengthof(_name_czech_subst_postfix)) {
723 const char *poststr = _name_czech_subst_postfix[postfix];
724 const char *endstr = _name_czech_subst_ending[ending].name;
726 size_t postlen = strlen(poststr);
727 size_t endlen = strlen(endstr);
728 assert(postlen > 0 && endlen > 0);
731 if (postlen < 2 || postlen > endlen ||
732 ((poststr[1] !=
'v' || poststr[1] != endstr[1]) &&
733 poststr[2] != endstr[1])) {
737 if (endstr[0] ==
'i') {
739 switch (builder[last]) {
740 case 'k': builder[last] =
'c';
break;
741 case 'h': builder[last] =
'z';
break;
747 builder += _name_czech_subst_ending[ending].name;
749 builder += _name_czech_subst_full[stem].name;
754 builder += _name_czech_suffix[suffix];
817 if (i <
lengthof(_name_hungarian_1)) builder += _name_hungarian_1[i];
825 if (i <
lengthof(_name_hungarian_4)) {
826 builder += _name_hungarian_4[i];
851 if (i >= 0) builder += _name_danish_1[i];
905 static const char *
const mascul_femin_italian[] = {
923 builder += mascul_femin_italian[i];