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