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