summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsmatz <smatz@openttd.org>2009-09-22 13:54:54 +0000
committersmatz <smatz@openttd.org>2009-09-22 13:54:54 +0000
commit1da745c9ad04aba82c91a6bf69a8ea5ae57ccba7 (patch)
tree31138e76073053de9304e8b7c53910fc9c4f25ce
parent665864e5b035189c10de1d545650662f5797f5d5 (diff)
downloadopenttd-1da745c9ad04aba82c91a6bf69a8ea5ae57ccba7.tar.xz
(svn r17612) -Feature: possibility to choose (randomise or enter custom) town name before its creation (original patch by Terkhen)
-rw-r--r--projects/openttd_vs80.vcproj4
-rw-r--r--projects/openttd_vs90.vcproj4
-rw-r--r--source.list1
-rw-r--r--src/lang/english.txt6
-rw-r--r--src/strings.cpp19
-rw-r--r--src/strings_func.h1
-rw-r--r--src/town.h1
-rw-r--r--src/town_cmd.cpp129
-rw-r--r--src/town_gui.cpp82
-rw-r--r--src/townname.cpp114
-rw-r--r--src/townname_func.h10
-rw-r--r--src/townname_type.h42
12 files changed, 281 insertions, 132 deletions
diff --git a/projects/openttd_vs80.vcproj b/projects/openttd_vs80.vcproj
index af0c8d057..e2ffffde7 100644
--- a/projects/openttd_vs80.vcproj
+++ b/projects/openttd_vs80.vcproj
@@ -1528,6 +1528,10 @@
>
</File>
<File
+ RelativePath=".\..\src\townname_type.h"
+ >
+ </File>
+ <File
RelativePath=".\..\src\town_type.h"
>
</File>
diff --git a/projects/openttd_vs90.vcproj b/projects/openttd_vs90.vcproj
index 6003f3fce..8d4f8304e 100644
--- a/projects/openttd_vs90.vcproj
+++ b/projects/openttd_vs90.vcproj
@@ -1525,6 +1525,10 @@
>
</File>
<File
+ RelativePath=".\..\src\townname_type.h"
+ >
+ </File>
+ <File
RelativePath=".\..\src\town_type.h"
>
</File>
diff --git a/source.list b/source.list
index 0fb15096e..777d78330 100644
--- a/source.list
+++ b/source.list
@@ -287,6 +287,7 @@ timetable.h
toolbar_gui.h
town.h
townname_func.h
+townname_type.h
town_type.h
track_func.h
track_type.h
diff --git a/src/lang/english.txt b/src/lang/english.txt
index 57288994d..7642db8c6 100644
--- a/src/lang/english.txt
+++ b/src/lang/english.txt
@@ -2033,6 +2033,12 @@ STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}Found to
STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}Many random towns
STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}Cover the map with randomly placed towns
+STR_FOUND_TOWN_NAME_TITLE :{YELLOW}Town name:
+STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}Enter town name
+STR_FOUND_TOWN_NAME_EDITOR_HELP :{BLACK}Click to enter town name
+STR_FOUND_TOWN_NAME_RANDOM_BUTTON :{BLACK}Random name
+STR_FOUND_TOWN_NAME_RANDOM_TOOLTIP :{BLACK}Generate new random name
+
STR_FOUND_TOWN_INITIAL_SIZE_TITLE :{YELLOW}Town size:
STR_FOUND_TOWN_INITIAL_SIZE_SMALL_BUTTON :{BLACK}Small
STR_FOUND_TOWN_INITIAL_SIZE_MEDIUM_BUTTON :{BLACK}Medium
diff --git a/src/strings.cpp b/src/strings.cpp
index 437619480..ecf3b6294 100644
--- a/src/strings.cpp
+++ b/src/strings.cpp
@@ -38,6 +38,7 @@
#include "engine_base.h"
#include "strgen/strgen.h"
#include "gfx_func.h"
+#include "townname_func.h"
#include "table/strings.h"
#include "table/control_codes.h"
@@ -105,7 +106,7 @@ const char *GetStringPtr(StringID string)
* @param last
* @return a formatted string of char
*/
-static char *GetStringWithArgs(char *buffr, uint string, int64 *argv, const char *last)
+char *GetStringWithArgs(char *buffr, uint string, int64 *argv, const char *last)
{
if (GB(string, 0, 16) == 0) return GetStringWithArgs(buffr, STR_UNDEFINED, argv, last);
@@ -913,27 +914,13 @@ static char *FormatString(char *buff, const char *str, int64 *argv, uint casei,
case SCC_TOWN_NAME: { // {TOWN}
const Town *t = Town::Get(GetInt32(&argv));
- int64 temp[1];
assert(t != NULL);
- temp[0] = t->townnameparts;
- uint32 grfid = t->townnamegrfid;
-
if (t->name != NULL) {
buff = strecpy(buff, t->name, last);
- } else if (grfid == 0) {
- /* Original town name */
- buff = GetStringWithArgs(buff, t->townnametype, temp, last);
} else {
- /* Newgrf town name */
- if (GetGRFTownName(grfid) != NULL) {
- /* The grf is loaded */
- buff = GRFTownNameGenerate(buff, t->townnamegrfid, t->townnametype, t->townnameparts, last);
- } else {
- /* Fallback to english original */
- buff = GetStringWithArgs(buff, SPECSTR_TOWNNAME_ENGLISH, temp, last);
- }
+ buff = GetTownName(buff, t, last);
}
break;
}
diff --git a/src/strings_func.h b/src/strings_func.h
index 1cc286f0d..e4b1cd3bd 100644
--- a/src/strings_func.h
+++ b/src/strings_func.h
@@ -16,6 +16,7 @@
char *InlineString(char *buf, StringID string);
char *GetString(char *buffr, StringID string, const char *last);
+char *GetStringWithArgs(char *buffr, uint string, int64 *argv, const char *last);
const char *GetStringPtr(StringID string);
void InjectDParam(uint amount);
diff --git a/src/town.h b/src/town.h
index c2a73f306..ac5b988ec 100644
--- a/src/town.h
+++ b/src/town.h
@@ -212,7 +212,6 @@ HouseZonesBits GetTownRadiusGroup(const Town *t, TileIndex tile);
void SetTownRatingTestMode(bool mode);
uint GetMaskOfTownActions(int *nump, CompanyID cid, const Town *t);
bool GenerateTowns(TownLayout layout);
-bool GenerateTownName(uint32 *townnameparts);
/** Town actions of a company. */
diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp
index b078fe982..6d8a4c31e 100644
--- a/src/town_cmd.cpp
+++ b/src/town_cmd.cpp
@@ -50,6 +50,8 @@
#include "core/smallmap_type.hpp"
#include "core/pool_func.hpp"
#include "town.h"
+#include "townname_func.h"
+#include "townname_type.h"
#include "table/strings.h"
#include "table/town_land.h"
@@ -1392,90 +1394,6 @@ void UpdateTownRadius(Town *t)
}
}
-extern int _nb_orig_names;
-
-/**
- * Struct holding a parameters used to generate town name.
- * Speeds things up a bit because these values are computed only once per name generation.
- */
-struct TownNameParams {
- uint32 grfid; ///< newgrf ID
- uint16 townnametype; ///< town name style
- bool grf; ///< true iff a newgrf is used to generate town name
-
- TownNameParams(byte town_name)
- {
- this->grf = town_name >= _nb_orig_names;
- this->grfid = this->grf ? GetGRFTownNameId(town_name - _nb_orig_names) : 0;
- this->townnametype = this->grf ? GetGRFTownNameType(town_name - _nb_orig_names) : SPECSTR_TOWNNAME_START + town_name;
- }
-};
-
-/**
- * Verifies the town name is valid and unique.
- * @param r random bits
- * @param par town name parameters
- * @return true iff name is valid and unique
- */
-static bool VerifyTownName(uint32 r, const TownNameParams *par)
-{
- /* Reserve space for extra unicode character. We need to do this to be able
- * to detect too long town name. */
- char buf1[MAX_LENGTH_TOWN_NAME_BYTES + MAX_CHAR_LENGTH];
- char buf2[MAX_LENGTH_TOWN_NAME_BYTES + MAX_CHAR_LENGTH];
-
- SetDParam(0, r);
- if (par->grf && par->grfid != 0) {
- GRFTownNameGenerate(buf1, par->grfid, par->townnametype, r, lastof(buf1));
- } else {
- GetString(buf1, par->townnametype, lastof(buf1));
- }
-
- /* Check size and width */
- if (strlen(buf1) >= MAX_LENGTH_TOWN_NAME_BYTES) 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. */
- SetDParam(0, t->index);
- GetString(buf2, STR_TOWN_NAME, lastof(buf2));
- if (strcmp(buf1, buf2) == 0) return false;
- }
-
- return true;
-}
-
-/**
- * Generates valid town name.
- * @param townnameparts if a name is generated, it's stored there
- * @return true iff a name was generated
- */
-bool GenerateTownName(uint32 *townnameparts)
-{
- /* 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
- * towns. Do not show it too high neither, since looping through all
- * the other towns may take considerable amount of time (10000 is
- * too much). */
- int tries = 1000;
- TownNameParams par(_settings_game.game_creation.town_name);
-
- assert(townnameparts != NULL);
-
- for (;;) {
- uint32 r = InteractiveRandom();
-
- if (!VerifyTownName(r, &par)) {
- if (tries-- < 0) return false;
- continue;
- }
-
- *townnameparts = r;
- return true;
- }
-}
-
void UpdateTownMaxPass(Town *t)
{
t->max_pass = t->population >> 3;
@@ -1526,6 +1444,7 @@ static void DoCreateTown(Town *t, TileIndex tile, uint32 townnameparts, TownSize
t->exclusive_counter = 0;
t->statues = 0;
+ extern int _nb_orig_names;
if (_settings_game.game_creation.town_name < _nb_orig_names) {
/* Original town name */
t->townnamegrfid = 0;
@@ -1587,6 +1506,22 @@ static CommandCost TownCanBePlacedHere(TileIndex tile)
return CommandCost(EXPENSES_OTHER);
}
+/**
+ * Verifies this custom name is unique. Only custom names are checked.
+ * @param name name to check
+ * @return is this name unique?
+ */
+static bool IsUniqueTownName(const char *name)
+{
+ const Town *t;
+
+ FOR_ALL_TOWNS(t) {
+ if (t->name != NULL && strcmp(t->name, name) == 0) return false;
+ }
+
+ return true;
+}
+
/** Create a new town.
* This obviously only works in the scenario editor. Function not removed
* as it might be possible in the future to fund your own town :)
@@ -1615,7 +1550,14 @@ CommandCost CmdFoundTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
if (size > TS_RANDOM) return CMD_ERROR;
if (layout > TL_RANDOM) return CMD_ERROR;
- if (!VerifyTownName(townnameparts, &par)) return_cmd_error(STR_ERROR_NAME_MUST_BE_UNIQUE);
+ if (StrEmpty(text)) {
+ /* If supplied name is empty, townnameparts has to generate unique automatic name */
+ if (!VerifyTownName(townnameparts, &par)) return_cmd_error(STR_ERROR_NAME_MUST_BE_UNIQUE);
+ } else {
+ /* If name is not empty, it has to be unique custom name */
+ if (strlen(text) >= MAX_LENGTH_TOWN_NAME_BYTES) return CMD_ERROR;
+ if (!IsUniqueTownName(text)) return_cmd_error(STR_ERROR_NAME_MUST_BE_UNIQUE);
+ }
/* Allocate town struct */
if (!Town::CanAllocateItem()) return_cmd_error(STR_ERROR_TOO_MANY_TOWNS);
@@ -1630,19 +1572,21 @@ CommandCost CmdFoundTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
if (flags & DC_EXEC) {
_generating_world = true;
UpdateNearestTownForRoadTiles(true);
+ Town *t;
if (random) {
- const Town *t = CreateRandomTown(20, townnameparts, size, city, layout);
+ t = CreateRandomTown(20, townnameparts, size, city, layout);
if (t == NULL) {
cost = CommandCost(STR_ERROR_NO_SPACE_FOR_TOWN);
} else {
_new_town_id = t->index;
}
} else {
- Town *t = new Town(tile);
+ t = new Town(tile);
DoCreateTown(t, tile, townnameparts, size, city, layout);
}
UpdateNearestTownForRoadTiles(false);
_generating_world = false;
+ if (t != NULL && !StrEmpty(text)) t->name = strdup(text);
}
return cost;
}
@@ -2312,17 +2256,6 @@ void ClearTownHouse(Town *t, TileIndex tile)
if (eflags & BUILDING_HAS_4_TILES) DoClearTownHouseHelper(tile + TileDiffXY(1, 1), t, ++house);
}
-static bool IsUniqueTownName(const char *name)
-{
- const Town *t;
-
- FOR_ALL_TOWNS(t) {
- if (t->name != NULL && strcmp(t->name, name) == 0) return false;
- }
-
- return true;
-}
-
/** Rename a town (server-only).
* @param tile unused
* @param flags type of operation
diff --git a/src/town_gui.cpp b/src/town_gui.cpp
index f5bce66a4..4a001f1dc 100644
--- a/src/town_gui.cpp
+++ b/src/town_gui.cpp
@@ -34,6 +34,11 @@
#include "landscape.h"
#include "cargotype.h"
#include "tile_map.h"
+#include "querystring_gui.h"
+#include "window_func.h"
+#include "string_func.h"
+#include "townname_func.h"
+#include "townname_type.h"
#include "table/sprites.h"
#include "table/strings.h"
@@ -850,11 +855,7 @@ void CcFoundTown(bool success, TileIndex tile, uint32 p1, uint32 p2)
void CcFoundRandomTown(bool success, TileIndex tile, uint32 p1, uint32 p2)
{
- if (success) {
- tile = Town::Get(_new_town_id)->xy;
- SndPlayTileFx(SND_1F_SPLAT, tile);
- ScrollMainWindowToTile(tile);
- }
+ if (success) ScrollMainWindowToTile(Town::Get(_new_town_id)->xy);
}
/** Widget numbers of town scenario editor window. */
@@ -866,6 +867,9 @@ enum TownScenarioEditorWidgets {
TSEW_NEWTOWN,
TSEW_RANDOMTOWN,
TSEW_MANYRANDOMTOWNS,
+ TSEW_TOWNNAME_TEXT,
+ TSEW_TOWNNAME_EDITBOX,
+ TSEW_TOWNNAME_RANDOM,
TSEW_TOWNSIZE,
TSEW_SIZE_SMALL,
TSEW_SIZE_MEDIUM,
@@ -895,6 +899,14 @@ static const NWidgetPart _nested_found_town_widgets[] = {
SetDataTip(STR_FOUND_TOWN_RANDOM_TOWN_BUTTON, STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP), SetPadding(0, 2, 1, 2),
NWidget(WWT_TEXTBTN, COLOUR_GREY, TSEW_MANYRANDOMTOWNS), SetMinimalSize(156, 12), SetFill(true, false),
SetDataTip(STR_FOUND_TOWN_MANY_RANDOM_TOWNS, STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP), SetPadding(0, 2, 0, 2),
+ /* Town name selection. */
+ NWidget(NWID_VERTICAL),
+ NWidget(WWT_LABEL, COLOUR_DARK_GREEN, TSEW_TOWNSIZE), SetMinimalSize(156, 14), SetDataTip(STR_FOUND_TOWN_NAME_TITLE, STR_NULL),
+ NWidget(WWT_EDITBOX, COLOUR_WHITE, TSEW_TOWNNAME_EDITBOX), SetMinimalSize(156, 12), SetDataTip(STR_FOUND_TOWN_NAME_EDITOR_TITLE, STR_FOUND_TOWN_NAME_EDITOR_HELP),
+ NWidget(NWID_SPACER), SetMinimalSize(0, 3),
+ NWidget(WWT_TEXTBTN, COLOUR_GREY, TSEW_TOWNNAME_RANDOM), SetMinimalSize(78, 12), SetFill(true, false),
+ SetDataTip(STR_FOUND_TOWN_NAME_RANDOM_BUTTON, STR_FOUND_TOWN_NAME_RANDOM_TOOLTIP),
+ EndContainer(),
/* Town size selection. */
NWidget(NWID_HORIZONTAL),
NWidget(NWID_SPACER), SetFill(true, false),
@@ -940,23 +952,41 @@ static const NWidgetPart _nested_found_town_widgets[] = {
};
/** Found a town window class. */
-struct FoundTownWindow : Window {
+struct FoundTownWindow : QueryStringBaseWindow {
private:
TownSize town_size; ///< Selected town size
TownLayout town_layout; ///< Selected town layout
bool city; ///< Are we building a city?
+ bool townnamevalid; ///< Is generated town name valid?
+ uint32 townnameparts; ///< Generated town name
+ TownNameParams params; ///< Town name parameters
public:
FoundTownWindow(const WindowDesc *desc, WindowNumber window_number) :
- Window(),
+ QueryStringBaseWindow(MAX_LENGTH_TOWN_NAME_BYTES),
town_size(TS_MEDIUM),
town_layout(_settings_game.economy.town_layout),
- city(false)
+ params(_settings_game.game_creation.town_name)
{
this->InitNested(desc, window_number);
+ this->RandomTownName();
this->UpdateButtons();
}
+ void RandomTownName()
+ {
+ this->townnamevalid = GenerateTownName(&this->townnameparts);
+
+ if (!this->townnamevalid) {
+ this->edit_str_buf[0] = '\0';
+ } else {
+ GetTownName(this->edit_str_buf, &this->params, this->townnameparts, &this->edit_str_buf[this->edit_str_size - 1]);
+ }
+ InitializeTextBuffer(&this->text, this->edit_str_buf, this->edit_str_size, MAX_LENGTH_TOWN_NAME_PIXELS);
+
+ this->SetFocusedWidget(TSEW_TOWNNAME_EDITBOX);
+ }
+
void UpdateButtons()
{
for (int i = TSEW_SIZE_SMALL; i <= TSEW_SIZE_RANDOM; i++) {
@@ -974,19 +1004,27 @@ public:
void ExecuteFoundTownCommand(TileIndex tile, bool random, StringID errstr, CommandCallback cc)
{
- uint32 townnameparts;
- if (!GenerateTownName(&townnameparts)) {
- ShowErrorMessage(STR_ERROR_TOO_MANY_TOWNS, errstr, 0, 0);
- return;
+ const char *name = NULL;
+
+ if (!this->townnamevalid) {
+ name = this->edit_str_buf;
+ } else {
+ /* If user changed the name, send it */
+ char buf[MAX_LENGTH_TOWN_NAME_BYTES];
+ GetTownName(buf, &this->params, this->townnameparts, lastof(buf));
+ if (strcmp(buf, this->edit_str_buf) != 0) name = this->edit_str_buf;
}
- DoCommandP(tile, this->town_size | this->city << 2 | this->town_layout << 3 | random << 6,
- townnameparts, CMD_FOUND_TOWN | CMD_MSG(errstr), cc);
+ bool success = DoCommandP(tile, this->town_size | this->city << 2 | this->town_layout << 3 | random << 6,
+ townnameparts, CMD_FOUND_TOWN | CMD_MSG(errstr), cc, name);
+
+ if (success) this->RandomTownName();
}
virtual void OnPaint()
{
this->DrawWidgets();
+ this->DrawEditBox(TSEW_TOWNNAME_EDITBOX);
}
virtual void OnClick(Point pt, int widget)
@@ -1001,6 +1039,10 @@ public:
this->ExecuteFoundTownCommand(0, true, STR_ERROR_CAN_T_GENERATE_TOWN, CcFoundRandomTown);
break;
+ case TSEW_TOWNNAME_RANDOM:
+ this->RandomTownName();
+ break;
+
case TSEW_MANYRANDOMTOWNS:
this->HandleButtonClick(TSEW_MANYRANDOMTOWNS);
@@ -1039,6 +1081,18 @@ public:
this->SetDirty();
}
+ virtual void OnMouseLoop()
+ {
+ this->HandleEditBox(TSEW_TOWNNAME_EDITBOX);
+ }
+
+ virtual EventState OnKeyPress(uint16 key, uint16 keycode)
+ {
+ EventState state;
+ this->HandleEditBoxKey(TSEW_TOWNNAME_EDITBOX, key, keycode, state);
+ return state;
+ }
+
virtual void OnPlaceObject(Point pt, TileIndex tile)
{
this->ExecuteFoundTownCommand(tile, false, STR_ERROR_CAN_T_FOUND_TOWN_HERE, CcFoundTown);
diff --git a/src/townname.cpp b/src/townname.cpp
index ec63267b8..e444f2dc6 100644
--- a/src/townname.cpp
+++ b/src/townname.cpp
@@ -12,12 +12,126 @@
#include "stdafx.h"
#include "townname_func.h"
#include "string_func.h"
+#include "townname_func.h"
+#include "townname_type.h"
+#include "town.h"
#include "core/alloc_func.hpp"
+#include "strings_func.h"
#include "table/townname.h"
/**
+ * Initializes this struct from town data
+ * @param t town for which we will be printing name later
+ */
+TownNameParams::TownNameParams(const Town *t) :
+ grfid(t->townnamegrfid), // by default, use supplied data
+ type(t->townnametype)
+{
+ if (t->townnamegrfid != 0 && GetGRFTownName(t->townnamegrfid) == NULL) {
+ /* Fallback to english original */
+ this->grfid = 0;
+ this->type = SPECSTR_TOWNNAME_ENGLISH;
+ return;
+ }
+}
+
+
+/**
+ * Fills buffer with specified town name
+ * @param buff buffer start
+ * @param par town name parameters
+ * @param townnameparts 'encoded' town name
+ * @param last end of buffer
+ * @return pointer to terminating '\0'
+ */
+char *GetTownName(char *buff, const TownNameParams *par, uint32 townnameparts, const char *last)
+{
+ if (par->grfid == 0) {
+ int64 temp[1] = { townnameparts };
+ return GetStringWithArgs(buff, par->type, temp, last);
+ }
+
+ return GRFTownNameGenerate(buff, par->grfid, par->type, townnameparts, last);
+}
+
+
+/**
+ * Fills buffer with town's name
+ * @param buff buffer start
+ * @param t we want to get name of this town
+ * @param last end of buffer
+ * @return pointer to terminating '\0'
+ */
+char *GetTownName(char *buff, const Town *t, const char *last)
+{
+ TownNameParams par(t);
+ return GetTownName(buff, &par, t->townnameparts, last);
+}
+
+
+/**
+ * Verifies the town name is valid and unique.
+ * @param r random bits
+ * @param par town name parameters
+ * @return true iff name is valid and unique
+ */
+bool VerifyTownName(uint32 r, const TownNameParams *par)
+{
+ /* reserve space for extra unicode character and terminating '\0' */
+ char buf1[MAX_LENGTH_TOWN_NAME_BYTES + MAX_CHAR_LENGTH];
+ char buf2[MAX_LENGTH_TOWN_NAME_BYTES + MAX_CHAR_LENGTH];
+
+ GetTownName(buf1, par, r, lastof(buf1));
+
+ /* Check size and width */
+ if (strlen(buf1) >= MAX_LENGTH_TOWN_NAME_BYTES) 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 (strcmp(buf1, buf2) == 0) return false;
+ }
+
+ return true;
+}
+
+
+/**
+ * Generates valid town name.
+ * @param townnameparts if a name is generated, it's stored there
+ * @return true iff a name was generated
+ */
+bool GenerateTownName(uint32 *townnameparts)
+{
+ /* 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
+ * towns. Do not show it too high neither, since looping through all
+ * the other towns may take considerable amount of time (10000 is
+ * too much). */
+ TownNameParams par(_settings_game.game_creation.town_name);
+
+ for (int i = 1000; i != 0; i--) {
+ uint32 r = InteractiveRandom();
+ if (!VerifyTownName(r, &par)) continue;
+
+ *townnameparts = r;
+ return true;
+ }
+
+ return false;
+}
+
+
+
+/**
* Generates a number from given seed.
* @param shift_by number of bits seed is shifted to the right
* @param max generated number is in interval 0...max-1
diff --git a/src/townname_func.h b/src/townname_func.h
index d0e2da77c..39db34b29 100644
--- a/src/townname_func.h
+++ b/src/townname_func.h
@@ -9,9 +9,13 @@
/** @file townname_func.h Town name generator stuff. */
-#ifndef NAMEGEN_FUNC_H
-#define NAMEGEN_FUNC_H
+#ifndef TOWNNAME_FUNC_H
+#define TOWNNAME_FUNC_H
char *GenerateTownNameString(char *buf, const char *last, size_t lang, uint32 seed);
+char *GetTownName(char *buff, const struct TownNameParams *par, uint32 townnameparts, const char *last);
+char *GetTownName(char *buff, const struct Town *t, const char *last);
+bool VerifyTownName(uint32 r, const struct TownNameParams *par);
+bool GenerateTownName(uint32 *townnameparts);
-#endif /* NAMEGEN_FUNC_H */
+#endif /* TOWNNAME_FUNC_H */
diff --git a/src/townname_type.h b/src/townname_type.h
new file mode 100644
index 000000000..a9b59cd7d
--- /dev/null
+++ b/src/townname_type.h
@@ -0,0 +1,42 @@
+/* $Id$ */
+
+/*
+ * This file is part of OpenTTD.
+ * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
+ * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** @file townname_type.h
+ * Definition of structures used for generating town names.
+ */
+
+#ifndef TOWNNAME_TYPE_H
+#define TOWNNAME_TYPE_H
+
+#include "newgrf_townname.h"
+
+/**
+ * Struct holding a parameters used to generate town name.
+ * Speeds things up a bit because these values are computed only once per name generation.
+ */
+struct TownNameParams {
+ uint32 grfid; ///< newgrf ID (0 if not used)
+ uint16 type; ///< town name style
+
+ /**
+ * Initializes this struct from language ID
+ * @param town_name town name 'language' ID
+ */
+ TownNameParams(byte town_name)
+ {
+ extern int _nb_orig_names;
+ bool grf = town_name >= _nb_orig_names;
+ this->grfid = grf ? GetGRFTownNameId(town_name - _nb_orig_names) : 0;
+ this->type = grf ? GetGRFTownNameType(town_name - _nb_orig_names) : SPECSTR_TOWNNAME_START + town_name;
+ }
+
+ TownNameParams(const struct Town *t);
+};
+
+#endif /* TOWNNAME_TYPE_H */