diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index 09ca7cee97..fd380a8271 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -1901,6 +1901,7 @@ bool GenerateTowns(TownLayout layout) uint total = (difficulty == (uint)CUSTOM_TOWN_NUMBER_DIFFICULTY) ? _settings_game.game_creation.custom_town_number : ScaleByMapSize(_num_initial_towns[difficulty] + (Random() & 7)); total = min(TownPool::MAX_SIZE, total); uint32 townnameparts; + TownNames town_names; SetGeneratingWorldProgress(GWP_TOWN, total); @@ -1919,11 +1920,13 @@ bool GenerateTowns(TownLayout layout) bool city = (_settings_game.economy.larger_towns != 0 && Chance16(1, _settings_game.economy.larger_towns)); IncreaseGeneratingWorldProgress(GWP_TOWN); /* Get a unique name for the town. */ - if (!GenerateTownName(&townnameparts)) continue; + if (!GenerateTownName(&townnameparts, &town_names)) continue; /* try 20 times to create a random-sized town for the first loop. */ if (CreateRandomTown(20, townnameparts, TSZ_RANDOM, city, layout) != NULL) current_number++; // If creation was successful, raise a flag. } while (--total); + town_names.clear(); + if (current_number != 0) return true; /* If current_number is still zero at this point, it means that not a single town has been created. diff --git a/src/townname.cpp b/src/townname.cpp index 495fde4b45..136882103a 100644 --- a/src/townname.cpp +++ b/src/townname.cpp @@ -75,9 +75,10 @@ char *GetTownName(char *buff, const Town *t, const char *last) * Verifies the town name is valid and unique. * @param r random bits * @param par town name parameters + * @param town_names if a name is generated, check its uniqueness with the set * @return true iff name is valid and unique */ -bool VerifyTownName(uint32 r, const TownNameParams *par) +bool VerifyTownName(uint32 r, const TownNameParams *par, TownNames *town_names) { /* reserve space for extra unicode character and terminating '\0' */ char buf1[(MAX_LENGTH_TOWN_NAME_CHARS + 1) * MAX_CHAR_LENGTH]; @@ -88,16 +89,21 @@ bool VerifyTownName(uint32 r, const TownNameParams *par) /* Check size and width */ if (Utf8StringLength(buf1) >= MAX_LENGTH_TOWN_NAME_CHARS) return false; - const Town *t; - FOR_ALL_TOWNS(t) { - /* We can't just compare the numbers since - * several numbers may map to a single name. */ - const char *buf = t->name; - if (buf == NULL) { - GetTownName(buf2, t, lastof(buf2)); - buf = buf2; + if (town_names != NULL) { + if (town_names->find(buf1) != town_names->end()) return false; + town_names->insert(buf1); + } else { + const Town *t; + FOR_ALL_TOWNS(t) { + /* We can't just compare the numbers since + * several numbers may map to a single name. */ + const char *buf = t->name; + if (buf == NULL) { + GetTownName(buf2, t, lastof(buf2)); + buf = buf2; + } + if (strcmp(buf1, buf) == 0) return false; } - if (strcmp(buf1, buf) == 0) return false; } return true; @@ -107,9 +113,10 @@ bool VerifyTownName(uint32 r, const TownNameParams *par) /** * Generates valid town name. * @param townnameparts if a name is generated, it's stored there + * @param town_names if a name is generated, check its uniqueness with the set * @return true iff a name was generated */ -bool GenerateTownName(uint32 *townnameparts) +bool GenerateTownName(uint32 *townnameparts, TownNames *town_names) { /* Do not set too low tries, since when we run out of names, we loop * for #tries only one time anyway - then we stop generating more @@ -120,7 +127,7 @@ bool GenerateTownName(uint32 *townnameparts) for (int i = 1000; i != 0; i--) { uint32 r = _generating_world ? Random() : InteractiveRandom(); - if (!VerifyTownName(r, &par)) continue; + if (!VerifyTownName(r, &par, town_names)) continue; *townnameparts = r; return true; diff --git a/src/townname_func.h b/src/townname_func.h index 0925569786..409993e42a 100644 --- a/src/townname_func.h +++ b/src/townname_func.h @@ -17,7 +17,7 @@ char *GenerateTownNameString(char *buf, const char *last, size_t lang, uint32 seed); char *GetTownName(char *buff, const TownNameParams *par, uint32 townnameparts, const char *last); char *GetTownName(char *buff, const Town *t, const char *last); -bool VerifyTownName(uint32 r, const TownNameParams *par); -bool GenerateTownName(uint32 *townnameparts); +bool VerifyTownName(uint32 r, const TownNameParams *par, TownNames *town_names = NULL); +bool GenerateTownName(uint32 *townnameparts, TownNames *town_names = NULL); #endif /* TOWNNAME_FUNC_H */ diff --git a/src/townname_type.h b/src/townname_type.h index 8a4b12b8bf..0177294d99 100644 --- a/src/townname_type.h +++ b/src/townname_type.h @@ -17,6 +17,10 @@ #include "newgrf_townname.h" #include "town_type.h" +#include +#include + +typedef std::set TownNames; /** * Struct holding a parameters used to generate town name.