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 "core/alloc_func.hpp"
00017 #include "strings_func.h"
00018 #include "core/random_func.hpp"
00019
00020 #include "table/townname.h"
00021
00022
00027 TownNameParams::TownNameParams(const Town *t) :
00028 grfid(t->townnamegrfid),
00029 type(t->townnametype)
00030 {
00031 if (t->townnamegrfid != 0 && GetGRFTownName(t->townnamegrfid) == NULL) {
00032
00033 this->grfid = 0;
00034 this->type = SPECSTR_TOWNNAME_ENGLISH;
00035 return;
00036 }
00037 }
00038
00039
00048 char *GetTownName(char *buff, const TownNameParams *par, uint32 townnameparts, const char *last)
00049 {
00050 if (par->grfid == 0) {
00051 int64 temp[1] = { townnameparts };
00052 return GetStringWithArgs(buff, par->type, temp, last);
00053 }
00054
00055 return GRFTownNameGenerate(buff, par->grfid, par->type, townnameparts, last);
00056 }
00057
00058
00066 char *GetTownName(char *buff, const Town *t, const char *last)
00067 {
00068 TownNameParams par(t);
00069 return GetTownName(buff, &par, t->townnameparts, last);
00070 }
00071
00072
00079 bool VerifyTownName(uint32 r, const TownNameParams *par)
00080 {
00081
00082 char buf1[MAX_LENGTH_TOWN_NAME_BYTES + MAX_CHAR_LENGTH];
00083 char buf2[MAX_LENGTH_TOWN_NAME_BYTES + MAX_CHAR_LENGTH];
00084
00085 GetTownName(buf1, par, r, lastof(buf1));
00086
00087
00088 if (strlen(buf1) >= MAX_LENGTH_TOWN_NAME_BYTES) return false;
00089
00090 const Town *t;
00091 FOR_ALL_TOWNS(t) {
00092
00093
00094 const char *buf = t->name;
00095 if (buf == NULL) {
00096 GetTownName(buf2, t, lastof(buf2));
00097 buf = buf2;
00098 }
00099 if (strcmp(buf1, buf2) == 0) return false;
00100 }
00101
00102 return true;
00103 }
00104
00105
00111 bool GenerateTownName(uint32 *townnameparts)
00112 {
00113
00114
00115
00116
00117
00118 TownNameParams par(_settings_game.game_creation.town_name);
00119
00120 for (int i = 1000; i != 0; i--) {
00121 uint32 r = InteractiveRandom();
00122 if (!VerifyTownName(r, &par)) continue;
00123
00124 *townnameparts = r;
00125 return true;
00126 }
00127
00128 return false;
00129 }
00130
00131
00132
00140 static inline uint32 SeedChance(byte shift_by, int max, uint32 seed)
00141 {
00142 return (GB(seed, shift_by, 16) * max) >> 16;
00143 }
00144
00145
00153 static inline uint32 SeedModChance(byte shift_by, int max, uint32 seed)
00154 {
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164 return (seed >> shift_by) % max;
00165 }
00166
00167
00176 static inline int32 SeedChanceBias(byte shift_by, int max, uint32 seed, int bias)
00177 {
00178 return SeedChance(shift_by, max + bias, seed) - bias;
00179 }
00180
00181
00188 static void ReplaceWords(const char *org, const char *rep, char *buf)
00189 {
00190 if (strncmp(buf, org, 4) == 0) strncpy(buf, rep, 4);
00191 }
00192
00193
00199 static void ReplaceEnglishWords(char *buf, bool original)
00200 {
00201 ReplaceWords("Cunt", "East", buf);
00202 ReplaceWords("Slag", "Pits", buf);
00203 ReplaceWords("Slut", "Edin", buf);
00204 if (!original) ReplaceWords("Fart", "Boot", buf);
00205 ReplaceWords("Drar", "Quar", buf);
00206 ReplaceWords("Dreh", "Bash", buf);
00207 ReplaceWords("Frar", "Shor", buf);
00208 ReplaceWords("Grar", "Aber", buf);
00209 ReplaceWords("Brar", "Over", buf);
00210 ReplaceWords("Wrar", original ? "Inve" : "Stan", buf);
00211 }
00212
00219 static char *MakeEnglishOriginalTownName(char *buf, const char *last, uint32 seed)
00220 {
00221 char *orig = buf;
00222
00223
00224 int i = SeedChanceBias(0, lengthof(_name_original_english_1), seed, 50);
00225 if (i >= 0) buf = strecpy(buf, _name_original_english_1[i], last);
00226
00227
00228 buf = strecpy(buf, _name_original_english_2[SeedChance(4, lengthof(_name_original_english_2), seed)], last);
00229 buf = strecpy(buf, _name_original_english_3[SeedChance(7, lengthof(_name_original_english_3), seed)], last);
00230 buf = strecpy(buf, _name_original_english_4[SeedChance(10, lengthof(_name_original_english_4), seed)], last);
00231 buf = strecpy(buf, _name_original_english_5[SeedChance(13, lengthof(_name_original_english_5), seed)], last);
00232
00233
00234 i = SeedChanceBias(15, lengthof(_name_original_english_6), seed, 60);
00235 if (i >= 0) buf = strecpy(buf, _name_original_english_6[i], last);
00236
00237
00238 if (orig[0] == 'C' && (orig[1] == 'e' || orig[1] == 'i')) {
00239 orig[0] = 'K';
00240 }
00241
00242 assert(buf - orig >= 4);
00243 ReplaceEnglishWords(orig, true);
00244
00245 return buf;
00246 }
00247
00248
00255 static char *MakeEnglishAdditionalTownName(char *buf, const char *last, uint32 seed)
00256 {
00257 char *orig = buf;
00258
00259
00260 int i = SeedChanceBias(0, lengthof(_name_additional_english_prefix), seed, 50);
00261 if (i >= 0) buf = strecpy(buf, _name_additional_english_prefix[i], last);
00262
00263 if (SeedChance(3, 20, seed) >= 14) {
00264 buf = strecpy(buf, _name_additional_english_1a[SeedChance(6, lengthof(_name_additional_english_1a), seed)], last);
00265 } else {
00266 buf = strecpy(buf, _name_additional_english_1b1[SeedChance(6, lengthof(_name_additional_english_1b1), seed)], last);
00267 buf = strecpy(buf, _name_additional_english_1b2[SeedChance(9, lengthof(_name_additional_english_1b2), seed)], last);
00268 if (SeedChance(11, 20, seed) >= 4) {
00269 buf = strecpy(buf, _name_additional_english_1b3a[SeedChance(12, lengthof(_name_additional_english_1b3a), seed)], last);
00270 } else {
00271 buf = strecpy(buf, _name_additional_english_1b3b[SeedChance(12, lengthof(_name_additional_english_1b3b), seed)], last);
00272 }
00273 }
00274
00275 buf = strecpy(buf, _name_additional_english_2[SeedChance(14, lengthof(_name_additional_english_2), seed)], last);
00276
00277
00278 i = SeedChanceBias(15, lengthof(_name_additional_english_3), seed, 60);
00279 if (i >= 0) buf = strecpy(buf, _name_additional_english_3[i], last);
00280
00281 assert(buf - orig >= 4);
00282 ReplaceEnglishWords(orig, false);
00283
00284 return buf;
00285 }
00286
00287
00294 static char *MakeAustrianTownName(char *buf, const char *last, uint32 seed)
00295 {
00296
00297 int i = SeedChanceBias(0, lengthof(_name_austrian_a1), seed, 15);
00298 if (i >= 0) buf = strecpy(buf, _name_austrian_a1[i], last);
00299
00300 int j = 0;
00301
00302 i = SeedChance(4, 6, seed);
00303 if (i >= 4) {
00304
00305 buf = strecpy(buf, _name_austrian_a2[SeedChance( 7, lengthof(_name_austrian_a2), seed)], last);
00306 buf = strecpy(buf, _name_austrian_a3[SeedChance(13, lengthof(_name_austrian_a3), seed)], last);
00307 } else if (i >= 2) {
00308
00309 buf = strecpy(buf, _name_austrian_a5[SeedChance( 7, lengthof(_name_austrian_a5), seed)], last);
00310 buf = strecpy(buf, _name_austrian_a6[SeedChance( 9, lengthof(_name_austrian_a6), seed)], last);
00311 j = 1;
00312 } else {
00313
00314 buf = strecpy(buf, _name_austrian_a4[SeedChance( 7, lengthof(_name_austrian_a4), seed)], last);
00315 }
00316
00317 i = SeedChance(1, 6, seed);
00318 if (i >= 4 - j) {
00319
00320 buf = strecpy(buf, _name_austrian_f1[SeedChance(4, lengthof(_name_austrian_f1), seed)], last);
00321 buf = strecpy(buf, _name_austrian_f2[SeedChance(5, lengthof(_name_austrian_f2), seed)], last);
00322 } else if (i >= 2 - j) {
00323
00324 buf = strecpy(buf, _name_austrian_b1[SeedChance(4, lengthof(_name_austrian_b1), seed)], last);
00325 buf = strecpy(buf, _name_austrian_b2[SeedChance(5, lengthof(_name_austrian_b2), seed)], last);
00326 }
00327
00328 return buf;
00329 }
00330
00331
00338 static char *MakeGermanTownName(char *buf, const char *last, uint32 seed)
00339 {
00340 uint seed_derivative = SeedChance(7, 28, seed);
00341
00342
00343 if (seed_derivative == 12 || seed_derivative == 19) {
00344 uint i = SeedChance(2, lengthof(_name_german_pre), seed);
00345 buf = strecpy(buf, _name_german_pre[i], last);
00346 }
00347
00348
00349 uint i = SeedChance(3, lengthof(_name_german_real) + lengthof(_name_german_1), seed);
00350 if (i < lengthof(_name_german_real)) {
00351 buf = strecpy(buf, _name_german_real[i], last);
00352 } else {
00353 buf = strecpy(buf, _name_german_1[i - lengthof(_name_german_real)], last);
00354
00355 i = SeedChance(5, lengthof(_name_german_2), seed);
00356 buf = strecpy(buf, _name_german_2[i], last);
00357 }
00358
00359
00360 if (seed_derivative == 24) {
00361 i = SeedChance(9, lengthof(_name_german_4_an_der) + lengthof(_name_german_4_am), seed);
00362 if (i < lengthof(_name_german_4_an_der)) {
00363 buf = strecpy(buf, _name_german_3_an_der[0], last);
00364 buf = strecpy(buf, _name_german_4_an_der[i], last);
00365 } else {
00366 buf = strecpy(buf, _name_german_3_am[0], last);
00367 buf = strecpy(buf, _name_german_4_am[i - lengthof(_name_german_4_an_der)], last);
00368 }
00369 }
00370
00371 return buf;
00372 }
00373
00374
00381 static char *MakeSpanishTownName(char *buf, const char *last, uint32 seed)
00382 {
00383 return strecpy(buf, _name_spanish_real[SeedChance(0, lengthof(_name_spanish_real), seed)], last);
00384 }
00385
00386
00393 static char *MakeFrenchTownName(char *buf, const char *last, uint32 seed)
00394 {
00395 return strecpy(buf, _name_french_real[SeedChance(0, lengthof(_name_french_real), seed)], last);
00396 }
00397
00398
00405 static char *MakeSillyTownName(char *buf, const char *last, uint32 seed)
00406 {
00407 buf = strecpy(buf, _name_silly_1[SeedChance( 0, lengthof(_name_silly_1), seed)], last);
00408 buf = strecpy(buf, _name_silly_2[SeedChance(16, lengthof(_name_silly_2), seed)], last);
00409
00410 return buf;
00411 }
00412
00413
00420 static char *MakeSwedishTownName(char *buf, const char *last, uint32 seed)
00421 {
00422
00423 int i = SeedChanceBias(0, lengthof(_name_swedish_1), seed, 50);
00424 if (i >= 0) buf = strecpy(buf, _name_swedish_1[i], last);
00425
00426
00427 if (SeedChance(4, 5, seed) >= 3) {
00428 buf = strecpy(buf, _name_swedish_2[SeedChance( 7, lengthof(_name_swedish_2), seed)], last);
00429 } else {
00430 buf = strecpy(buf, _name_swedish_2a[SeedChance( 7, lengthof(_name_swedish_2a), seed)], last);
00431 buf = strecpy(buf, _name_swedish_2b[SeedChance(10, lengthof(_name_swedish_2b), seed)], last);
00432 buf = strecpy(buf, _name_swedish_2c[SeedChance(13, lengthof(_name_swedish_2c), seed)], last);
00433 }
00434
00435 buf = strecpy(buf, _name_swedish_3[SeedChance(16, lengthof(_name_swedish_3), seed)], last);
00436
00437 return buf;
00438 }
00439
00440
00447 static char *MakeDutchTownName(char *buf, const char *last, uint32 seed)
00448 {
00449
00450 int i = SeedChanceBias(0, lengthof(_name_dutch_1), seed, 50);
00451 if (i >= 0) buf = strecpy(buf, _name_dutch_1[i], last);
00452
00453
00454 if (SeedChance(6, 9, seed) > 4) {
00455 buf = strecpy(buf, _name_dutch_2[SeedChance( 9, lengthof(_name_dutch_2), seed)], last);
00456 } else {
00457 buf = strecpy(buf, _name_dutch_3[SeedChance( 9, lengthof(_name_dutch_3), seed)], last);
00458 buf = strecpy(buf, _name_dutch_4[SeedChance(12, lengthof(_name_dutch_4), seed)], last);
00459 }
00460
00461 buf = strecpy(buf, _name_dutch_5[SeedChance(15, lengthof(_name_dutch_5), seed)], last);
00462
00463 return buf;
00464 }
00465
00466
00473 static char *MakeFinnishTownName(char *buf, const char *last, uint32 seed)
00474 {
00475 char *orig = buf;
00476
00477
00478 if (SeedChance(0, 15, seed) >= 10) {
00479 return strecpy(buf, _name_finnish_real[SeedChance(2, lengthof(_name_finnish_real), seed)], last);
00480 }
00481
00482 if (SeedChance(0, 15, seed) >= 5) {
00483
00484
00485
00486 uint sel = SeedChance( 0, lengthof(_name_finnish_1), seed);
00487 buf = strecpy(buf, _name_finnish_1[sel], last);
00488 char *end = buf - 1;
00489 assert(end >= orig);
00490 if (*end == 'i') *end = 'e';
00491 if (strstr(orig, "a") != NULL || strstr(orig, "o") != NULL || strstr(orig, "u") != NULL ||
00492 strstr(orig, "A") != NULL || strstr(orig, "O") != NULL || strstr(orig, "U") != NULL) {
00493 buf = strecpy(buf, "la", last);
00494 } else {
00495 buf = strecpy(buf, "l\xC3\xA4", last);
00496 }
00497 return buf;
00498 }
00499
00500
00501
00502 uint sel = SeedChance(2, lengthof(_name_finnish_1) + lengthof(_name_finnish_2), seed);
00503 if (sel >= lengthof(_name_finnish_1)) {
00504 buf = strecpy(buf, _name_finnish_2[sel - lengthof(_name_finnish_1)], last);
00505 } else {
00506 buf = strecpy(buf, _name_finnish_1[sel], last);
00507 }
00508
00509 buf = strecpy(buf, _name_finnish_3[SeedChance(10, lengthof(_name_finnish_3), seed)], last);
00510
00511 return buf;
00512 }
00513
00514
00521 static char *MakePolishTownName(char *buf, const char *last, uint32 seed)
00522 {
00523
00524 uint i = SeedChance(0,
00525 lengthof(_name_polish_2_o) + lengthof(_name_polish_2_m) +
00526 lengthof(_name_polish_2_f) + lengthof(_name_polish_2_n),
00527 seed);
00528 uint j = SeedChance(2, 20, seed);
00529
00530
00531 if (i < lengthof(_name_polish_2_o)) {
00532 return strecpy(buf, _name_polish_2_o[SeedChance(3, lengthof(_name_polish_2_o), seed)], last);
00533 }
00534
00535 if (i < lengthof(_name_polish_2_m) + lengthof(_name_polish_2_o)) {
00536 if (j < 4) {
00537 buf = strecpy(buf, _name_polish_1_m[SeedChance(5, lengthof(_name_polish_1_m), seed)], last);
00538 }
00539
00540 buf = strecpy(buf, _name_polish_2_m[SeedChance(7, lengthof(_name_polish_2_m), seed)], last);
00541
00542 if (j >= 4 && j < 16) {
00543 buf = strecpy(buf, _name_polish_3_m[SeedChance(10, lengthof(_name_polish_3_m), seed)], last);
00544 }
00545
00546 return buf;
00547 }
00548
00549 if (i < lengthof(_name_polish_2_f) + lengthof(_name_polish_2_m) + lengthof(_name_polish_2_o)) {
00550 if (j < 4) {
00551 buf = strecpy(buf, _name_polish_1_f[SeedChance(5, lengthof(_name_polish_1_f), seed)], last);
00552 }
00553
00554 buf = strecpy(buf, _name_polish_2_f[SeedChance(7, lengthof(_name_polish_2_f), seed)], last);
00555
00556 if (j >= 4 && j < 16) {
00557 buf = strecpy(buf, _name_polish_3_f[SeedChance(10, lengthof(_name_polish_3_f), seed)], last);
00558 }
00559
00560 return buf;
00561 }
00562
00563 if (j < 4) {
00564 buf = strecpy(buf, _name_polish_1_n[SeedChance(5, lengthof(_name_polish_1_n), seed)], last);
00565 }
00566
00567 buf = strecpy(buf, _name_polish_2_n[SeedChance(7, lengthof(_name_polish_2_n), seed)], last);
00568
00569 if (j >= 4 && j < 16) {
00570 buf = strecpy(buf, _name_polish_3_n[SeedChance(10, lengthof(_name_polish_3_n), seed)], last);
00571 }
00572
00573 return buf;
00574 }
00575
00576
00583 static char *MakeCzechTownName(char *buf, const char *last, uint32 seed)
00584 {
00585
00586 if (SeedModChance(0, 4, seed) == 0) {
00587 return strecpy(buf, _name_czech_real[SeedModChance(4, lengthof(_name_czech_real), seed)], last);
00588 }
00589
00590 const char *orig = buf;
00591
00592
00593
00594 int prob_tails = SeedModChance(2, 32, seed);
00595 bool do_prefix = prob_tails < 12;
00596 bool do_suffix = prob_tails > 11 && prob_tails < 17;
00597 bool dynamic_subst;
00598
00599
00600 int prefix = 0, ending = 0, suffix = 0;
00601 uint postfix = 0;
00602 uint stem;
00603
00604
00605 CzechGender gender;
00606 CzechChoose choose;
00607 CzechAllow allow;
00608
00609 if (do_prefix) prefix = SeedModChance(5, lengthof(_name_czech_adj) * 12, seed) / 12;
00610 if (do_suffix) suffix = SeedModChance(7, lengthof(_name_czech_suffix), seed);
00611
00612 stem = SeedModChance(9,
00613 lengthof(_name_czech_subst_full) + 3 * lengthof(_name_czech_subst_stem),
00614 seed);
00615 if (stem < lengthof(_name_czech_subst_full)) {
00616
00617 dynamic_subst = false;
00618 gender = _name_czech_subst_full[stem].gender;
00619 choose = _name_czech_subst_full[stem].choose;
00620 allow = _name_czech_subst_full[stem].allow;
00621 } else {
00622 unsigned int map[lengthof(_name_czech_subst_ending)];
00623 int ending_start = -1, ending_stop = -1;
00624
00625
00626 dynamic_subst = true;
00627 stem -= lengthof(_name_czech_subst_full);
00628 stem %= lengthof(_name_czech_subst_stem);
00629 gender = _name_czech_subst_stem[stem].gender;
00630 choose = _name_czech_subst_stem[stem].choose;
00631 allow = _name_czech_subst_stem[stem].allow;
00632
00633
00634 postfix = SeedModChance(14, lengthof(_name_czech_subst_postfix) * 2, seed);
00635
00636 if (choose & CZC_POSTFIX) {
00637
00638 postfix %= lengthof(_name_czech_subst_postfix);
00639 }
00640 if (choose & CZC_NOPOSTFIX) {
00641
00642 postfix += lengthof(_name_czech_subst_postfix);
00643 }
00644 if (postfix < lengthof(_name_czech_subst_postfix)) {
00645 choose |= CZC_POSTFIX;
00646 } else {
00647 choose |= CZC_NOPOSTFIX;
00648 }
00649
00650
00651 for (ending = 0; ending < (int)lengthof(_name_czech_subst_ending); ending++) {
00652 const CzechNameSubst *e = &_name_czech_subst_ending[ending];
00653
00654 if (gender == CZG_FREE ||
00655 (gender == CZG_NFREE && e->gender != CZG_SNEUT && e->gender != CZG_PNEUT) ||
00656 gender == e->gender) {
00657 if (ending_start < 0) {
00658 ending_start = ending;
00659 }
00660 } else if (ending_start >= 0) {
00661 ending_stop = ending - 1;
00662 break;
00663 }
00664 }
00665 if (ending_stop < 0) {
00666
00667 ending_stop = ending - 1;
00668 }
00669
00670
00671 size_t i = 0;
00672 for (ending = ending_start; ending <= ending_stop; ending++) {
00673 const CzechNameSubst *e = &_name_czech_subst_ending[ending];
00674
00675 if ((e->choose & choose) == choose && (e->allow & allow) != 0) {
00676 map[i++] = ending;
00677 }
00678 }
00679 assert(i > 0);
00680
00681
00682 ending = map[SeedModChance(16, (int)i, seed)];
00683
00684
00685 gender = _name_czech_subst_ending[ending].gender;
00686 assert(gender != CZG_FREE && gender != CZG_NFREE);
00687 }
00688
00689 if (do_prefix && (_name_czech_adj[prefix].choose & choose) != choose) {
00690
00691 do_prefix = false;
00692 }
00693
00694
00695 if (do_prefix) {
00696 CzechPattern pattern = _name_czech_adj[prefix].pattern;
00697
00698 buf = strecpy(buf, _name_czech_adj[prefix].name, last);
00699
00700 char *endpos = buf - 1;
00701
00702 while (GB(*endpos, 6, 2) == 2) endpos--;
00703
00704 if (gender == CZG_SMASC && pattern == CZP_PRIVL) {
00705 assert(endpos >= orig + 2);
00706
00707 *(endpos - 2) = 'u';
00708 assert(*(endpos - 1) == 'v');
00709 *endpos = '\0';
00710 } else {
00711 assert(endpos >= orig);
00712 endpos = strecpy(endpos, _name_czech_patmod[gender][pattern], last);
00713 }
00714
00715 buf = strecpy(endpos, " ", last);
00716 }
00717
00718 if (dynamic_subst) {
00719 buf = strecpy(buf, _name_czech_subst_stem[stem].name, last);
00720 if (postfix < lengthof(_name_czech_subst_postfix)) {
00721 const char *poststr = _name_czech_subst_postfix[postfix];
00722 const char *endstr = _name_czech_subst_ending[ending].name;
00723
00724 size_t postlen = strlen(poststr);
00725 size_t endlen = strlen(endstr);
00726 assert(postlen > 0 && endlen > 0);
00727
00728
00729 if (postlen < 2 || postlen > endlen ||
00730 ((poststr[1] != 'v' || poststr[1] != endstr[1]) &&
00731 poststr[2] != endstr[1])) {
00732 buf = strecpy(buf, poststr, last);
00733
00734
00735 if (endstr[0] == 'i') {
00736 switch (*(buf - 1)) {
00737 case 'k': *(buf - 1) = 'c'; break;
00738 case 'h': *(buf - 1) = 'z'; break;
00739 default: break;
00740 }
00741 }
00742 }
00743 }
00744 buf = strecpy(buf, _name_czech_subst_ending[ending].name, last);
00745 } else {
00746 buf = strecpy(buf, _name_czech_subst_full[stem].name, last);
00747 }
00748
00749 if (do_suffix) {
00750 buf = strecpy(buf, " ", last);
00751 buf = strecpy(buf, _name_czech_suffix[suffix], last);
00752 }
00753
00754 return buf;
00755 }
00756
00757
00764 static char *MakeRomanianTownName(char *buf, const char *last, uint32 seed)
00765 {
00766 return strecpy(buf, _name_romanian_real[SeedChance(0, lengthof(_name_romanian_real), seed)], last);
00767 }
00768
00769
00776 static char *MakeSlovakTownName(char *buf, const char *last, uint32 seed)
00777 {
00778 return strecpy(buf, _name_slovak_real[SeedChance(0, lengthof(_name_slovak_real), seed)], last);
00779 }
00780
00781
00788 static char *MakeNorwegianTownName(char *buf, const char *last, uint32 seed)
00789 {
00790
00791
00792 if (SeedChance(0, 15, seed) < 3) {
00793
00794 return strecpy(buf, _name_norwegian_real[SeedChance(4, lengthof(_name_norwegian_real), seed)], last);
00795 }
00796
00797
00798 buf = strecpy(buf, _name_norwegian_1[SeedChance(4, lengthof(_name_norwegian_1), seed)], last);
00799
00800 buf = strecpy(buf, _name_norwegian_2[SeedChance(11, lengthof(_name_norwegian_2), seed)], last);
00801
00802 return buf;
00803 }
00804
00805
00812 static char *MakeHungarianTownName(char *buf, const char *last, uint32 seed)
00813 {
00814 if (SeedChance(12, 15, seed) < 3) {
00815 return strecpy(buf, _name_hungarian_real[SeedChance(0, lengthof(_name_hungarian_real), seed)], last);
00816 }
00817
00818
00819 uint i = SeedChance(3, lengthof(_name_hungarian_1) * 3, seed);
00820 if (i < lengthof(_name_hungarian_1)) buf = strecpy(buf, _name_hungarian_1[i], last);
00821
00822
00823 buf = strecpy(buf, _name_hungarian_2[SeedChance(3, lengthof(_name_hungarian_2), seed)], last);
00824 buf = strecpy(buf, _name_hungarian_3[SeedChance(6, lengthof(_name_hungarian_3), seed)], last);
00825
00826
00827 i = SeedChance(10, lengthof(_name_hungarian_4) * 3, seed);
00828 if (i < lengthof(_name_hungarian_4)) {
00829 buf = strecpy(buf, _name_hungarian_4[i], last);
00830 }
00831
00832 return buf;
00833 }
00834
00835
00842 static char *MakeSwissTownName(char *buf, const char *last, uint32 seed)
00843 {
00844 return strecpy(buf, _name_swiss_real[SeedChance(0, lengthof(_name_swiss_real), seed)], last);
00845 }
00846
00847
00854 static char *MakeDanishTownName(char *buf, const char *last, uint32 seed)
00855 {
00856
00857 int i = SeedChanceBias(0, lengthof(_name_danish_1), seed, 50);
00858 if (i >= 0) buf = strecpy(buf, _name_danish_1[i], last);
00859
00860
00861 buf = strecpy(buf, _name_danish_2[SeedChance( 7, lengthof(_name_danish_2), seed)], last);
00862 buf = strecpy(buf, _name_danish_3[SeedChance(16, lengthof(_name_danish_3), seed)], last);
00863
00864 return buf;
00865 }
00866
00867
00874 static char *MakeTurkishTownName(char *buf, const char *last, uint32 seed)
00875 {
00876 uint i = SeedModChance(0, 5, seed);
00877
00878 switch (i) {
00879 case 0:
00880 buf = strecpy(buf, _name_turkish_prefix[SeedModChance( 2, lengthof(_name_turkish_prefix), seed)], last);
00881
00882
00883 buf = strecpy(buf, _name_turkish_middle[SeedModChance( 4, lengthof(_name_turkish_middle), seed)], last);
00884
00885
00886 if (SeedModChance(0, 7, seed) == 0) {
00887 buf = strecpy(buf, _name_turkish_suffix[SeedModChance( 10, lengthof(_name_turkish_suffix), seed)], last);
00888 }
00889 break;
00890
00891 case 1: case 2:
00892 buf = strecpy(buf, _name_turkish_prefix[SeedModChance( 2, lengthof(_name_turkish_prefix), seed)], last);
00893 buf = strecpy(buf, _name_turkish_suffix[SeedModChance( 4, lengthof(_name_turkish_suffix), seed)], last);
00894 break;
00895
00896 default:
00897 buf = strecpy(buf, _name_turkish_real[SeedModChance( 4, lengthof(_name_turkish_real), seed)], last);
00898 break;
00899 }
00900
00901 return buf;
00902 }
00903
00904
00911 static char *MakeItalianTownName(char *buf, const char *last, uint32 seed)
00912 {
00913 if (SeedModChance(0, 6, seed) == 0) {
00914 return strecpy(buf, _name_italian_real[SeedModChance(4, lengthof(_name_italian_real), seed)], last);
00915 }
00916
00917 static const char * const mascul_femin_italian[] = {
00918 "o",
00919 "a",
00920 };
00921
00922 if (SeedModChance(0, 8, seed) == 0) {
00923 buf = strecpy(buf, _name_italian_pref[SeedModChance(11, lengthof(_name_italian_pref), seed)], last);
00924 }
00925
00926 uint i = SeedChance(0, 2, seed);
00927 if (i == 0) {
00928 buf = strecpy(buf, _name_italian_1m[SeedModChance(4, lengthof(_name_italian_1m), seed)], last);
00929 } else {
00930 buf = strecpy(buf, _name_italian_1f[SeedModChance(4, lengthof(_name_italian_1f), seed)], last);
00931 }
00932
00933 if (SeedModChance(3, 3, seed) == 0) {
00934 buf = strecpy(buf, _name_italian_2[SeedModChance(11, lengthof(_name_italian_2), seed)], last);
00935 buf = strecpy(buf, mascul_femin_italian[i], last);
00936 } else {
00937 buf = strecpy(buf, _name_italian_2i[SeedModChance(16, lengthof(_name_italian_2i), seed)], last);
00938 }
00939
00940 if (SeedModChance(15, 4, seed) == 0) {
00941 if (SeedModChance(5, 2, seed) == 0) {
00942 buf = strecpy(buf, _name_italian_3[SeedModChance(4, lengthof(_name_italian_3), seed)], last);
00943 } else {
00944 buf = strecpy(buf, _name_italian_river1[SeedModChance(4, lengthof(_name_italian_river1), seed)], last);
00945 buf = strecpy(buf, _name_italian_river2[SeedModChance(16, lengthof(_name_italian_river2), seed)], last);
00946 }
00947 }
00948
00949 return buf;
00950 }
00951
00952
00959 static char *MakeCatalanTownName(char *buf, const char *last, uint32 seed)
00960 {
00961 if (SeedModChance(0, 3, seed) == 0) {
00962 return strecpy(buf, _name_catalan_real[SeedModChance(4, lengthof(_name_catalan_real), seed)], last);
00963 }
00964
00965 if (SeedModChance(0, 2, seed) == 0) {
00966 buf = strecpy(buf, _name_catalan_pref[SeedModChance(11, lengthof(_name_catalan_pref), seed)], last);
00967 }
00968
00969 uint i = SeedChance(0, 2, seed);
00970 if (i == 0) {
00971 buf = strecpy(buf, _name_catalan_1m[SeedModChance(4, lengthof(_name_catalan_1m), seed)], last);
00972 buf = strecpy(buf, _name_catalan_2m[SeedModChance(11, lengthof(_name_catalan_2m), seed)], last);
00973 } else {
00974 buf = strecpy(buf, _name_catalan_1f[SeedModChance(4, lengthof(_name_catalan_1f), seed)], last);
00975 buf = strecpy(buf, _name_catalan_2f[SeedModChance(11, lengthof(_name_catalan_2f), seed)], last);
00976 }
00977
00978 if (SeedModChance(15, 5, seed) == 0) {
00979 if (SeedModChance(5, 2, seed) == 0) {
00980 buf = strecpy(buf, _name_catalan_3[SeedModChance(4, lengthof(_name_catalan_3), seed)], last);
00981 } else {
00982 buf = strecpy(buf, _name_catalan_river1[SeedModChance(4, lengthof(_name_catalan_river1), seed)], last);
00983 }
00984 }
00985
00986 return buf;
00987 }
00988
00989
00990 typedef char *TownNameGenerator(char *buf, const char *last, uint32 seed);
00991
00993 struct TownNameGeneratorParams {
00994 byte min;
00995 TownNameGenerator *proc;
00996 };
00997
00999 static const TownNameGeneratorParams _town_name_generators[] = {
01000 { 4, MakeEnglishOriginalTownName},
01001 { 0, MakeFrenchTownName},
01002 { 0, MakeGermanTownName},
01003 { 4, MakeEnglishAdditionalTownName},
01004 { 0, MakeSpanishTownName},
01005 { 0, MakeSillyTownName},
01006 { 0, MakeSwedishTownName},
01007 { 0, MakeDutchTownName},
01008 { 8, MakeFinnishTownName},
01009 { 0, MakePolishTownName},
01010 { 0, MakeSlovakTownName},
01011 { 0, MakeNorwegianTownName},
01012 { 0, MakeHungarianTownName},
01013 { 0, MakeAustrianTownName},
01014 { 0, MakeRomanianTownName},
01015 { 28, MakeCzechTownName},
01016 { 0, MakeSwissTownName},
01017 { 0, MakeDanishTownName},
01018 { 0, MakeTurkishTownName},
01019 { 0, MakeItalianTownName},
01020 { 0, MakeCatalanTownName},
01021 };
01022
01023
01032 char *GenerateTownNameString(char *buf, const char *last, size_t lang, uint32 seed)
01033 {
01034 assert(lang < lengthof(_town_name_generators));
01035
01036
01037
01038
01039
01040
01041
01042 const TownNameGeneratorParams *par = &_town_name_generators[lang];
01043 if (last >= buf + par->min) return par->proc(buf, last, seed);
01044
01045 char *buffer = AllocaM(char, par->min + 1);
01046 par->proc(buffer, buffer + par->min, seed);
01047
01048 return strecpy(buf, buffer, last);
01049 }