00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #include "stdafx.h"
00013 #include "string_func.h"
00014 #include "townname_type.h"
00015 #include "town.h"
00016 #include "strings_func.h"
00017 #include "core/random_func.hpp"
00018 #include "genworld.h"
00019 #include "gfx_layout.h"
00020
00021 #include "table/townname.h"
00022
00023
00028 TownNameParams::TownNameParams(const Town *t) :
00029 grfid(t->townnamegrfid),
00030 type(t->townnametype)
00031 {
00032 if (t->townnamegrfid != 0 && GetGRFTownName(t->townnamegrfid) == NULL) {
00033
00034 this->grfid = 0;
00035 this->type = SPECSTR_TOWNNAME_ENGLISH;
00036 return;
00037 }
00038 }
00039
00040
00049 char *GetTownName(char *buff, const TownNameParams *par, uint32 townnameparts, const char *last)
00050 {
00051 if (par->grfid == 0) {
00052 int64 args_array[1] = { townnameparts };
00053 StringParameters tmp_params(args_array);
00054 return GetStringWithArgs(buff, par->type, &tmp_params, last);
00055 }
00056
00057 return GRFTownNameGenerate(buff, par->grfid, par->type, townnameparts, last);
00058 }
00059
00060
00068 char *GetTownName(char *buff, const Town *t, const char *last)
00069 {
00070 TownNameParams par(t);
00071 return GetTownName(buff, &par, t->townnameparts, last);
00072 }
00073
00074
00082 bool VerifyTownName(uint32 r, const TownNameParams *par, TownNames *town_names)
00083 {
00084
00085 char buf1[(MAX_LENGTH_TOWN_NAME_CHARS + 1) * MAX_CHAR_LENGTH];
00086 char buf2[(MAX_LENGTH_TOWN_NAME_CHARS + 1) * MAX_CHAR_LENGTH];
00087
00088 GetTownName(buf1, par, r, lastof(buf1));
00089
00090
00091 if (Utf8StringLength(buf1) >= MAX_LENGTH_TOWN_NAME_CHARS) return false;
00092
00093 if (town_names != NULL) {
00094 if (town_names->find(buf1) != town_names->end()) return false;
00095 town_names->insert(buf1);
00096 } else {
00097 const Town *t;
00098 FOR_ALL_TOWNS(t) {
00099
00100
00101 const char *buf = t->name;
00102 if (buf == NULL) {
00103 GetTownName(buf2, t, lastof(buf2));
00104 buf = buf2;
00105 }
00106 if (strcmp(buf1, buf) == 0) return false;
00107 }
00108 }
00109
00110 return true;
00111 }
00112
00113
00120 bool GenerateTownName(uint32 *townnameparts, TownNames *town_names)
00121 {
00122
00123
00124
00125
00126
00127 TownNameParams par(_settings_game.game_creation.town_name);
00128
00129
00130
00131 Layouter::ReduceLineCache();
00132
00133 for (int i = 1000; i != 0; i--) {
00134 uint32 r = _generating_world ? Random() : InteractiveRandom();
00135 if (!VerifyTownName(r, &par, town_names)) continue;
00136
00137 *townnameparts = r;
00138 return true;
00139 }
00140
00141 return false;
00142 }
00143
00144
00145
00153 static inline uint32 SeedChance(byte shift_by, int max, uint32 seed)
00154 {
00155 return (GB(seed, shift_by, 16) * max) >> 16;
00156 }
00157
00158
00166 static inline uint32 SeedModChance(byte shift_by, int max, uint32 seed)
00167 {
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177 return (seed >> shift_by) % max;
00178 }
00179
00180
00189 static inline int32 SeedChanceBias(byte shift_by, int max, uint32 seed, int bias)
00190 {
00191 return SeedChance(shift_by, max + bias, seed) - bias;
00192 }
00193
00194
00201 static void ReplaceWords(const char *org, const char *rep, char *buf)
00202 {
00203 if (strncmp(buf, org, 4) == 0) strncpy(buf, rep, 4);
00204 }
00205
00206
00212 static void ReplaceEnglishWords(char *buf, bool original)
00213 {
00214 ReplaceWords("Cunt", "East", buf);
00215 ReplaceWords("Slag", "Pits", buf);
00216 ReplaceWords("Slut", "Edin", buf);
00217 if (!original) ReplaceWords("Fart", "Boot", buf);
00218 ReplaceWords("Drar", "Quar", buf);
00219 ReplaceWords("Dreh", "Bash", buf);
00220 ReplaceWords("Frar", "Shor", buf);
00221 ReplaceWords("Grar", "Aber", buf);
00222 ReplaceWords("Brar", "Over", buf);
00223 ReplaceWords("Wrar", original ? "Inve" : "Stan", buf);
00224 }
00225
00232 static char *MakeEnglishOriginalTownName(char *buf, const char *last, uint32 seed)
00233 {
00234 char *orig = buf;
00235
00236
00237 int i = SeedChanceBias(0, lengthof(_name_original_english_1), seed, 50);
00238 if (i >= 0) buf = strecpy(buf, _name_original_english_1[i], last);
00239
00240
00241 buf = strecpy(buf, _name_original_english_2[SeedChance(4, lengthof(_name_original_english_2), seed)], last);
00242 buf = strecpy(buf, _name_original_english_3[SeedChance(7, lengthof(_name_original_english_3), seed)], last);
00243 buf = strecpy(buf, _name_original_english_4[SeedChance(10, lengthof(_name_original_english_4), seed)], last);
00244 buf = strecpy(buf, _name_original_english_5[SeedChance(13, lengthof(_name_original_english_5), seed)], last);
00245
00246
00247 i = SeedChanceBias(15, lengthof(_name_original_english_6), seed, 60);
00248 if (i >= 0) buf = strecpy(buf, _name_original_english_6[i], last);
00249
00250
00251 if (orig[0] == 'C' && (orig[1] == 'e' || orig[1] == 'i')) {
00252 orig[0] = 'K';
00253 }
00254
00255 assert(buf - orig >= 4);
00256 ReplaceEnglishWords(orig, true);
00257
00258 return buf;
00259 }
00260
00261
00268 static char *MakeEnglishAdditionalTownName(char *buf, const char *last, uint32 seed)
00269 {
00270 char *orig = buf;
00271
00272
00273 int i = SeedChanceBias(0, lengthof(_name_additional_english_prefix), seed, 50);
00274 if (i >= 0) buf = strecpy(buf, _name_additional_english_prefix[i], last);
00275
00276 if (SeedChance(3, 20, seed) >= 14) {
00277 buf = strecpy(buf, _name_additional_english_1a[SeedChance(6, lengthof(_name_additional_english_1a), seed)], last);
00278 } else {
00279 buf = strecpy(buf, _name_additional_english_1b1[SeedChance(6, lengthof(_name_additional_english_1b1), seed)], last);
00280 buf = strecpy(buf, _name_additional_english_1b2[SeedChance(9, lengthof(_name_additional_english_1b2), seed)], last);
00281 if (SeedChance(11, 20, seed) >= 4) {
00282 buf = strecpy(buf, _name_additional_english_1b3a[SeedChance(12, lengthof(_name_additional_english_1b3a), seed)], last);
00283 } else {
00284 buf = strecpy(buf, _name_additional_english_1b3b[SeedChance(12, lengthof(_name_additional_english_1b3b), seed)], last);
00285 }
00286 }
00287
00288 buf = strecpy(buf, _name_additional_english_2[SeedChance(14, lengthof(_name_additional_english_2), seed)], last);
00289
00290
00291 i = SeedChanceBias(15, lengthof(_name_additional_english_3), seed, 60);
00292 if (i >= 0) buf = strecpy(buf, _name_additional_english_3[i], last);
00293
00294 assert(buf - orig >= 4);
00295 ReplaceEnglishWords(orig, false);
00296
00297 return buf;
00298 }
00299
00300
00307 static char *MakeAustrianTownName(char *buf, const char *last, uint32 seed)
00308 {
00309
00310 int i = SeedChanceBias(0, lengthof(_name_austrian_a1), seed, 15);
00311 if (i >= 0) buf = strecpy(buf, _name_austrian_a1[i], last);
00312
00313 int j = 0;
00314
00315 i = SeedChance(4, 6, seed);
00316 if (i >= 4) {
00317
00318 buf = strecpy(buf, _name_austrian_a2[SeedChance( 7, lengthof(_name_austrian_a2), seed)], last);
00319 buf = strecpy(buf, _name_austrian_a3[SeedChance(13, lengthof(_name_austrian_a3), seed)], last);
00320 } else if (i >= 2) {
00321
00322 buf = strecpy(buf, _name_austrian_a5[SeedChance( 7, lengthof(_name_austrian_a5), seed)], last);
00323 buf = strecpy(buf, _name_austrian_a6[SeedChance( 9, lengthof(_name_austrian_a6), seed)], last);
00324 j = 1;
00325 } else {
00326
00327 buf = strecpy(buf, _name_austrian_a4[SeedChance( 7, lengthof(_name_austrian_a4), seed)], last);
00328 }
00329
00330 i = SeedChance(1, 6, seed);
00331 if (i >= 4 - j) {
00332
00333 buf = strecpy(buf, _name_austrian_f1[SeedChance(4, lengthof(_name_austrian_f1), seed)], last);
00334 buf = strecpy(buf, _name_austrian_f2[SeedChance(5, lengthof(_name_austrian_f2), seed)], last);
00335 } else if (i >= 2 - j) {
00336
00337 buf = strecpy(buf, _name_austrian_b1[SeedChance(4, lengthof(_name_austrian_b1), seed)], last);
00338 buf = strecpy(buf, _name_austrian_b2[SeedChance(5, lengthof(_name_austrian_b2), seed)], last);
00339 }
00340
00341 return buf;
00342 }
00343
00344
00351 static char *MakeGermanTownName(char *buf, const char *last, uint32 seed)
00352 {
00353 uint seed_derivative = SeedChance(7, 28, seed);
00354
00355
00356 if (seed_derivative == 12 || seed_derivative == 19) {
00357 uint i = SeedChance(2, lengthof(_name_german_pre), seed);
00358 buf = strecpy(buf, _name_german_pre[i], last);
00359 }
00360
00361
00362 uint i = SeedChance(3, lengthof(_name_german_real) + lengthof(_name_german_1), seed);
00363 if (i < lengthof(_name_german_real)) {
00364 buf = strecpy(buf, _name_german_real[i], last);
00365 } else {
00366 buf = strecpy(buf, _name_german_1[i - lengthof(_name_german_real)], last);
00367
00368 i = SeedChance(5, lengthof(_name_german_2), seed);
00369 buf = strecpy(buf, _name_german_2[i], last);
00370 }
00371
00372
00373 if (seed_derivative == 24) {
00374 i = SeedChance(9, lengthof(_name_german_4_an_der) + lengthof(_name_german_4_am), seed);
00375 if (i < lengthof(_name_german_4_an_der)) {
00376 buf = strecpy(buf, _name_german_3_an_der[0], last);
00377 buf = strecpy(buf, _name_german_4_an_der[i], last);
00378 } else {
00379 buf = strecpy(buf, _name_german_3_am[0], last);
00380 buf = strecpy(buf, _name_german_4_am[i - lengthof(_name_german_4_an_der)], last);
00381 }
00382 }
00383
00384 return buf;
00385 }
00386
00387
00394 static char *MakeSpanishTownName(char *buf, const char *last, uint32 seed)
00395 {
00396 return strecpy(buf, _name_spanish_real[SeedChance(0, lengthof(_name_spanish_real), seed)], last);
00397 }
00398
00399
00406 static char *MakeFrenchTownName(char *buf, const char *last, uint32 seed)
00407 {
00408 return strecpy(buf, _name_french_real[SeedChance(0, lengthof(_name_french_real), seed)], last);
00409 }
00410
00411
00418 static char *MakeSillyTownName(char *buf, const char *last, uint32 seed)
00419 {
00420 buf = strecpy(buf, _name_silly_1[SeedChance( 0, lengthof(_name_silly_1), seed)], last);
00421 buf = strecpy(buf, _name_silly_2[SeedChance(16, lengthof(_name_silly_2), seed)], last);
00422
00423 return buf;
00424 }
00425
00426
00433 static char *MakeSwedishTownName(char *buf, const char *last, uint32 seed)
00434 {
00435
00436 int i = SeedChanceBias(0, lengthof(_name_swedish_1), seed, 50);
00437 if (i >= 0) buf = strecpy(buf, _name_swedish_1[i], last);
00438
00439
00440 if (SeedChance(4, 5, seed) >= 3) {
00441 buf = strecpy(buf, _name_swedish_2[SeedChance( 7, lengthof(_name_swedish_2), seed)], last);
00442 } else {
00443 buf = strecpy(buf, _name_swedish_2a[SeedChance( 7, lengthof(_name_swedish_2a), seed)], last);
00444 buf = strecpy(buf, _name_swedish_2b[SeedChance(10, lengthof(_name_swedish_2b), seed)], last);
00445 buf = strecpy(buf, _name_swedish_2c[SeedChance(13, lengthof(_name_swedish_2c), seed)], last);
00446 }
00447
00448 buf = strecpy(buf, _name_swedish_3[SeedChance(16, lengthof(_name_swedish_3), seed)], last);
00449
00450 return buf;
00451 }
00452
00453
00460 static char *MakeDutchTownName(char *buf, const char *last, uint32 seed)
00461 {
00462
00463 int i = SeedChanceBias(0, lengthof(_name_dutch_1), seed, 50);
00464 if (i >= 0) buf = strecpy(buf, _name_dutch_1[i], last);
00465
00466
00467 if (SeedChance(6, 9, seed) > 4) {
00468 buf = strecpy(buf, _name_dutch_2[SeedChance( 9, lengthof(_name_dutch_2), seed)], last);
00469 } else {
00470 buf = strecpy(buf, _name_dutch_3[SeedChance( 9, lengthof(_name_dutch_3), seed)], last);
00471 buf = strecpy(buf, _name_dutch_4[SeedChance(12, lengthof(_name_dutch_4), seed)], last);
00472 }
00473
00474 buf = strecpy(buf, _name_dutch_5[SeedChance(15, lengthof(_name_dutch_5), seed)], last);
00475
00476 return buf;
00477 }
00478
00479
00486 static char *MakeFinnishTownName(char *buf, const char *last, uint32 seed)
00487 {
00488 char *orig = buf;
00489
00490
00491 if (SeedChance(0, 15, seed) >= 10) {
00492 return strecpy(buf, _name_finnish_real[SeedChance(2, lengthof(_name_finnish_real), seed)], last);
00493 }
00494
00495 if (SeedChance(0, 15, seed) >= 5) {
00496
00497
00498
00499 uint sel = SeedChance( 0, lengthof(_name_finnish_1), seed);
00500 buf = strecpy(buf, _name_finnish_1[sel], last);
00501 char *end = buf - 1;
00502 assert(end >= orig);
00503 if (*end == 'i') *end = 'e';
00504 if (strstr(orig, "a") != NULL || strstr(orig, "o") != NULL || strstr(orig, "u") != NULL ||
00505 strstr(orig, "A") != NULL || strstr(orig, "O") != NULL || strstr(orig, "U") != NULL) {
00506 buf = strecpy(buf, "la", last);
00507 } else {
00508 buf = strecpy(buf, "l\xC3\xA4", last);
00509 }
00510 return buf;
00511 }
00512
00513
00514
00515 uint sel = SeedChance(2, lengthof(_name_finnish_1) + lengthof(_name_finnish_2), seed);
00516 if (sel >= lengthof(_name_finnish_1)) {
00517 buf = strecpy(buf, _name_finnish_2[sel - lengthof(_name_finnish_1)], last);
00518 } else {
00519 buf = strecpy(buf, _name_finnish_1[sel], last);
00520 }
00521
00522 buf = strecpy(buf, _name_finnish_3[SeedChance(10, lengthof(_name_finnish_3), seed)], last);
00523
00524 return buf;
00525 }
00526
00527
00534 static char *MakePolishTownName(char *buf, const char *last, uint32 seed)
00535 {
00536
00537 uint i = SeedChance(0,
00538 lengthof(_name_polish_2_o) + lengthof(_name_polish_2_m) +
00539 lengthof(_name_polish_2_f) + lengthof(_name_polish_2_n),
00540 seed);
00541 uint j = SeedChance(2, 20, seed);
00542
00543
00544 if (i < lengthof(_name_polish_2_o)) {
00545 return strecpy(buf, _name_polish_2_o[SeedChance(3, lengthof(_name_polish_2_o), seed)], last);
00546 }
00547
00548 if (i < lengthof(_name_polish_2_m) + lengthof(_name_polish_2_o)) {
00549 if (j < 4) {
00550 buf = strecpy(buf, _name_polish_1_m[SeedChance(5, lengthof(_name_polish_1_m), seed)], last);
00551 }
00552
00553 buf = strecpy(buf, _name_polish_2_m[SeedChance(7, lengthof(_name_polish_2_m), seed)], last);
00554
00555 if (j >= 4 && j < 16) {
00556 buf = strecpy(buf, _name_polish_3_m[SeedChance(10, lengthof(_name_polish_3_m), seed)], last);
00557 }
00558
00559 return buf;
00560 }
00561
00562 if (i < lengthof(_name_polish_2_f) + lengthof(_name_polish_2_m) + lengthof(_name_polish_2_o)) {
00563 if (j < 4) {
00564 buf = strecpy(buf, _name_polish_1_f[SeedChance(5, lengthof(_name_polish_1_f), seed)], last);
00565 }
00566
00567 buf = strecpy(buf, _name_polish_2_f[SeedChance(7, lengthof(_name_polish_2_f), seed)], last);
00568
00569 if (j >= 4 && j < 16) {
00570 buf = strecpy(buf, _name_polish_3_f[SeedChance(10, lengthof(_name_polish_3_f), seed)], last);
00571 }
00572
00573 return buf;
00574 }
00575
00576 if (j < 4) {
00577 buf = strecpy(buf, _name_polish_1_n[SeedChance(5, lengthof(_name_polish_1_n), seed)], last);
00578 }
00579
00580 buf = strecpy(buf, _name_polish_2_n[SeedChance(7, lengthof(_name_polish_2_n), seed)], last);
00581
00582 if (j >= 4 && j < 16) {
00583 buf = strecpy(buf, _name_polish_3_n[SeedChance(10, lengthof(_name_polish_3_n), seed)], last);
00584 }
00585
00586 return buf;
00587 }
00588
00589
00596 static char *MakeCzechTownName(char *buf, const char *last, uint32 seed)
00597 {
00598
00599 if (SeedModChance(0, 4, seed) == 0) {
00600 return strecpy(buf, _name_czech_real[SeedModChance(4, lengthof(_name_czech_real), seed)], last);
00601 }
00602
00603 const char *orig = buf;
00604
00605
00606
00607 int prob_tails = SeedModChance(2, 32, seed);
00608 bool do_prefix = prob_tails < 12;
00609 bool do_suffix = prob_tails > 11 && prob_tails < 17;
00610 bool dynamic_subst;
00611
00612
00613 int prefix = 0, ending = 0, suffix = 0;
00614 uint postfix = 0;
00615 uint stem;
00616
00617
00618 CzechGender gender;
00619 CzechChoose choose;
00620 CzechAllow allow;
00621
00622 if (do_prefix) prefix = SeedModChance(5, lengthof(_name_czech_adj) * 12, seed) / 12;
00623 if (do_suffix) suffix = SeedModChance(7, lengthof(_name_czech_suffix), seed);
00624
00625 stem = SeedModChance(9,
00626 lengthof(_name_czech_subst_full) + 3 * lengthof(_name_czech_subst_stem),
00627 seed);
00628 if (stem < lengthof(_name_czech_subst_full)) {
00629
00630 dynamic_subst = false;
00631 gender = _name_czech_subst_full[stem].gender;
00632 choose = _name_czech_subst_full[stem].choose;
00633 allow = _name_czech_subst_full[stem].allow;
00634 } else {
00635 unsigned int map[lengthof(_name_czech_subst_ending)];
00636 int ending_start = -1, ending_stop = -1;
00637
00638
00639 dynamic_subst = true;
00640 stem -= lengthof(_name_czech_subst_full);
00641 stem %= lengthof(_name_czech_subst_stem);
00642 gender = _name_czech_subst_stem[stem].gender;
00643 choose = _name_czech_subst_stem[stem].choose;
00644 allow = _name_czech_subst_stem[stem].allow;
00645
00646
00647 postfix = SeedModChance(14, lengthof(_name_czech_subst_postfix) * 2, seed);
00648
00649 if (choose & CZC_POSTFIX) {
00650
00651 postfix %= lengthof(_name_czech_subst_postfix);
00652 }
00653 if (choose & CZC_NOPOSTFIX) {
00654
00655 postfix += lengthof(_name_czech_subst_postfix);
00656 }
00657 if (postfix < lengthof(_name_czech_subst_postfix)) {
00658 choose |= CZC_POSTFIX;
00659 } else {
00660 choose |= CZC_NOPOSTFIX;
00661 }
00662
00663
00664 for (ending = 0; ending < (int)lengthof(_name_czech_subst_ending); ending++) {
00665 const CzechNameSubst *e = &_name_czech_subst_ending[ending];
00666
00667 if (gender == CZG_FREE ||
00668 (gender == CZG_NFREE && e->gender != CZG_SNEUT && e->gender != CZG_PNEUT) ||
00669 gender == e->gender) {
00670 if (ending_start < 0) {
00671 ending_start = ending;
00672 }
00673 } else if (ending_start >= 0) {
00674 ending_stop = ending - 1;
00675 break;
00676 }
00677 }
00678 if (ending_stop < 0) {
00679
00680 ending_stop = ending - 1;
00681 }
00682
00683
00684 size_t i = 0;
00685 for (ending = ending_start; ending <= ending_stop; ending++) {
00686 const CzechNameSubst *e = &_name_czech_subst_ending[ending];
00687
00688 if ((e->choose & choose) == choose && (e->allow & allow) != 0) {
00689 map[i++] = ending;
00690 }
00691 }
00692 assert(i > 0);
00693
00694
00695 ending = map[SeedModChance(16, (int)i, seed)];
00696
00697
00698 gender = _name_czech_subst_ending[ending].gender;
00699 assert(gender != CZG_FREE && gender != CZG_NFREE);
00700 }
00701
00702 if (do_prefix && (_name_czech_adj[prefix].choose & choose) != choose) {
00703
00704 do_prefix = false;
00705 }
00706
00707
00708 if (do_prefix) {
00709 CzechPattern pattern = _name_czech_adj[prefix].pattern;
00710
00711 buf = strecpy(buf, _name_czech_adj[prefix].name, last);
00712
00713 char *endpos = buf - 1;
00714
00715 while (GB(*endpos, 6, 2) == 2) endpos--;
00716
00717 if (gender == CZG_SMASC && pattern == CZP_PRIVL) {
00718 assert(endpos >= orig + 2);
00719
00720 *(endpos - 2) = 'u';
00721 assert(*(endpos - 1) == 'v');
00722 *endpos = '\0';
00723 } else {
00724 assert(endpos >= orig);
00725 endpos = strecpy(endpos, _name_czech_patmod[gender][pattern], last);
00726 }
00727
00728 buf = strecpy(endpos, " ", last);
00729 }
00730
00731 if (dynamic_subst) {
00732 buf = strecpy(buf, _name_czech_subst_stem[stem].name, last);
00733 if (postfix < lengthof(_name_czech_subst_postfix)) {
00734 const char *poststr = _name_czech_subst_postfix[postfix];
00735 const char *endstr = _name_czech_subst_ending[ending].name;
00736
00737 size_t postlen = strlen(poststr);
00738 size_t endlen = strlen(endstr);
00739 assert(postlen > 0 && endlen > 0);
00740
00741
00742 if (postlen < 2 || postlen > endlen ||
00743 ((poststr[1] != 'v' || poststr[1] != endstr[1]) &&
00744 poststr[2] != endstr[1])) {
00745 buf = strecpy(buf, poststr, last);
00746
00747
00748 if (endstr[0] == 'i') {
00749 switch (*(buf - 1)) {
00750 case 'k': *(buf - 1) = 'c'; break;
00751 case 'h': *(buf - 1) = 'z'; break;
00752 default: break;
00753 }
00754 }
00755 }
00756 }
00757 buf = strecpy(buf, _name_czech_subst_ending[ending].name, last);
00758 } else {
00759 buf = strecpy(buf, _name_czech_subst_full[stem].name, last);
00760 }
00761
00762 if (do_suffix) {
00763 buf = strecpy(buf, " ", last);
00764 buf = strecpy(buf, _name_czech_suffix[suffix], last);
00765 }
00766
00767 return buf;
00768 }
00769
00770
00777 static char *MakeRomanianTownName(char *buf, const char *last, uint32 seed)
00778 {
00779 return strecpy(buf, _name_romanian_real[SeedChance(0, lengthof(_name_romanian_real), seed)], last);
00780 }
00781
00782
00789 static char *MakeSlovakTownName(char *buf, const char *last, uint32 seed)
00790 {
00791 return strecpy(buf, _name_slovak_real[SeedChance(0, lengthof(_name_slovak_real), seed)], last);
00792 }
00793
00794
00801 static char *MakeNorwegianTownName(char *buf, const char *last, uint32 seed)
00802 {
00803
00804
00805 if (SeedChance(0, 15, seed) < 3) {
00806
00807 return strecpy(buf, _name_norwegian_real[SeedChance(4, lengthof(_name_norwegian_real), seed)], last);
00808 }
00809
00810
00811 buf = strecpy(buf, _name_norwegian_1[SeedChance(4, lengthof(_name_norwegian_1), seed)], last);
00812
00813 buf = strecpy(buf, _name_norwegian_2[SeedChance(11, lengthof(_name_norwegian_2), seed)], last);
00814
00815 return buf;
00816 }
00817
00818
00825 static char *MakeHungarianTownName(char *buf, const char *last, uint32 seed)
00826 {
00827 if (SeedChance(12, 15, seed) < 3) {
00828 return strecpy(buf, _name_hungarian_real[SeedChance(0, lengthof(_name_hungarian_real), seed)], last);
00829 }
00830
00831
00832 uint i = SeedChance(3, lengthof(_name_hungarian_1) * 3, seed);
00833 if (i < lengthof(_name_hungarian_1)) buf = strecpy(buf, _name_hungarian_1[i], last);
00834
00835
00836 buf = strecpy(buf, _name_hungarian_2[SeedChance(3, lengthof(_name_hungarian_2), seed)], last);
00837 buf = strecpy(buf, _name_hungarian_3[SeedChance(6, lengthof(_name_hungarian_3), seed)], last);
00838
00839
00840 i = SeedChance(10, lengthof(_name_hungarian_4) * 3, seed);
00841 if (i < lengthof(_name_hungarian_4)) {
00842 buf = strecpy(buf, _name_hungarian_4[i], last);
00843 }
00844
00845 return buf;
00846 }
00847
00848
00855 static char *MakeSwissTownName(char *buf, const char *last, uint32 seed)
00856 {
00857 return strecpy(buf, _name_swiss_real[SeedChance(0, lengthof(_name_swiss_real), seed)], last);
00858 }
00859
00860
00867 static char *MakeDanishTownName(char *buf, const char *last, uint32 seed)
00868 {
00869
00870 int i = SeedChanceBias(0, lengthof(_name_danish_1), seed, 50);
00871 if (i >= 0) buf = strecpy(buf, _name_danish_1[i], last);
00872
00873
00874 buf = strecpy(buf, _name_danish_2[SeedChance( 7, lengthof(_name_danish_2), seed)], last);
00875 buf = strecpy(buf, _name_danish_3[SeedChance(16, lengthof(_name_danish_3), seed)], last);
00876
00877 return buf;
00878 }
00879
00880
00887 static char *MakeTurkishTownName(char *buf, const char *last, uint32 seed)
00888 {
00889 uint i = SeedModChance(0, 5, seed);
00890
00891 switch (i) {
00892 case 0:
00893 buf = strecpy(buf, _name_turkish_prefix[SeedModChance( 2, lengthof(_name_turkish_prefix), seed)], last);
00894
00895
00896 buf = strecpy(buf, _name_turkish_middle[SeedModChance( 4, lengthof(_name_turkish_middle), seed)], last);
00897
00898
00899 if (SeedModChance(0, 7, seed) == 0) {
00900 buf = strecpy(buf, _name_turkish_suffix[SeedModChance( 10, lengthof(_name_turkish_suffix), seed)], last);
00901 }
00902 break;
00903
00904 case 1: case 2:
00905 buf = strecpy(buf, _name_turkish_prefix[SeedModChance( 2, lengthof(_name_turkish_prefix), seed)], last);
00906 buf = strecpy(buf, _name_turkish_suffix[SeedModChance( 4, lengthof(_name_turkish_suffix), seed)], last);
00907 break;
00908
00909 default:
00910 buf = strecpy(buf, _name_turkish_real[SeedModChance( 4, lengthof(_name_turkish_real), seed)], last);
00911 break;
00912 }
00913
00914 return buf;
00915 }
00916
00917
00924 static char *MakeItalianTownName(char *buf, const char *last, uint32 seed)
00925 {
00926 if (SeedModChance(0, 6, seed) == 0) {
00927 return strecpy(buf, _name_italian_real[SeedModChance(4, lengthof(_name_italian_real), seed)], last);
00928 }
00929
00930 static const char * const mascul_femin_italian[] = {
00931 "o",
00932 "a",
00933 };
00934
00935 if (SeedModChance(0, 8, seed) == 0) {
00936 buf = strecpy(buf, _name_italian_pref[SeedModChance(11, lengthof(_name_italian_pref), seed)], last);
00937 }
00938
00939 uint i = SeedChance(0, 2, seed);
00940 if (i == 0) {
00941 buf = strecpy(buf, _name_italian_1m[SeedModChance(4, lengthof(_name_italian_1m), seed)], last);
00942 } else {
00943 buf = strecpy(buf, _name_italian_1f[SeedModChance(4, lengthof(_name_italian_1f), seed)], last);
00944 }
00945
00946 if (SeedModChance(3, 3, seed) == 0) {
00947 buf = strecpy(buf, _name_italian_2[SeedModChance(11, lengthof(_name_italian_2), seed)], last);
00948 buf = strecpy(buf, mascul_femin_italian[i], last);
00949 } else {
00950 buf = strecpy(buf, _name_italian_2i[SeedModChance(16, lengthof(_name_italian_2i), seed)], last);
00951 }
00952
00953 if (SeedModChance(15, 4, seed) == 0) {
00954 if (SeedModChance(5, 2, seed) == 0) {
00955 buf = strecpy(buf, _name_italian_3[SeedModChance(4, lengthof(_name_italian_3), seed)], last);
00956 } else {
00957 buf = strecpy(buf, _name_italian_river1[SeedModChance(4, lengthof(_name_italian_river1), seed)], last);
00958 buf = strecpy(buf, _name_italian_river2[SeedModChance(16, lengthof(_name_italian_river2), seed)], last);
00959 }
00960 }
00961
00962 return buf;
00963 }
00964
00965
00972 static char *MakeCatalanTownName(char *buf, const char *last, uint32 seed)
00973 {
00974 if (SeedModChance(0, 3, seed) == 0) {
00975 return strecpy(buf, _name_catalan_real[SeedModChance(4, lengthof(_name_catalan_real), seed)], last);
00976 }
00977
00978 if (SeedModChance(0, 2, seed) == 0) {
00979 buf = strecpy(buf, _name_catalan_pref[SeedModChance(11, lengthof(_name_catalan_pref), seed)], last);
00980 }
00981
00982 uint i = SeedChance(0, 2, seed);
00983 if (i == 0) {
00984 buf = strecpy(buf, _name_catalan_1m[SeedModChance(4, lengthof(_name_catalan_1m), seed)], last);
00985 buf = strecpy(buf, _name_catalan_2m[SeedModChance(11, lengthof(_name_catalan_2m), seed)], last);
00986 } else {
00987 buf = strecpy(buf, _name_catalan_1f[SeedModChance(4, lengthof(_name_catalan_1f), seed)], last);
00988 buf = strecpy(buf, _name_catalan_2f[SeedModChance(11, lengthof(_name_catalan_2f), seed)], last);
00989 }
00990
00991 if (SeedModChance(15, 5, seed) == 0) {
00992 if (SeedModChance(5, 2, seed) == 0) {
00993 buf = strecpy(buf, _name_catalan_3[SeedModChance(4, lengthof(_name_catalan_3), seed)], last);
00994 } else {
00995 buf = strecpy(buf, _name_catalan_river1[SeedModChance(4, lengthof(_name_catalan_river1), seed)], last);
00996 }
00997 }
00998
00999 return buf;
01000 }
01001
01002
01010 typedef char *TownNameGenerator(char *buf, const char *last, uint32 seed);
01011
01013 struct TownNameGeneratorParams {
01014 byte min;
01015 TownNameGenerator *proc;
01016 };
01017
01019 static const TownNameGeneratorParams _town_name_generators[] = {
01020 { 4, MakeEnglishOriginalTownName},
01021 { 0, MakeFrenchTownName},
01022 { 0, MakeGermanTownName},
01023 { 4, MakeEnglishAdditionalTownName},
01024 { 0, MakeSpanishTownName},
01025 { 0, MakeSillyTownName},
01026 { 0, MakeSwedishTownName},
01027 { 0, MakeDutchTownName},
01028 { 8, MakeFinnishTownName},
01029 { 0, MakePolishTownName},
01030 { 0, MakeSlovakTownName},
01031 { 0, MakeNorwegianTownName},
01032 { 0, MakeHungarianTownName},
01033 { 0, MakeAustrianTownName},
01034 { 0, MakeRomanianTownName},
01035 { 28, MakeCzechTownName},
01036 { 0, MakeSwissTownName},
01037 { 0, MakeDanishTownName},
01038 { 0, MakeTurkishTownName},
01039 { 0, MakeItalianTownName},
01040 { 0, MakeCatalanTownName},
01041 };
01042
01043
01052 char *GenerateTownNameString(char *buf, const char *last, size_t lang, uint32 seed)
01053 {
01054 assert(lang < lengthof(_town_name_generators));
01055
01056
01057
01058
01059
01060
01061
01062 const TownNameGeneratorParams *par = &_town_name_generators[lang];
01063 if (last >= buf + par->min) return par->proc(buf, last, seed);
01064
01065 char *buffer = AllocaM(char, par->min + 1);
01066 par->proc(buffer, buffer + par->min, seed);
01067
01068 return strecpy(buf, buffer, last);
01069 }