mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-06 22:28:56 +00:00
(svn r15505) -Codechange: pass name of new town as parameter to CMD_BUILD_TOWN
This commit is contained in:
parent
db0cd46a3f
commit
0878541cf2
@ -360,6 +360,7 @@ 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);
|
||||
|
||||
/**
|
||||
* Calculate a hash value from a tile position
|
||||
|
122
src/town_cmd.cpp
122
src/town_cmd.cpp
@ -1364,49 +1364,83 @@ void UpdateTownRadius(Town *t)
|
||||
}
|
||||
}
|
||||
|
||||
static bool CreateTownName(uint32 *townnameparts)
|
||||
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 {
|
||||
bool grf; ///< true iff a newgrf is used to generate town name
|
||||
uint32 grfid; ///< newgrf ID
|
||||
uint16 townnametype; ///< town name style
|
||||
|
||||
TownNameParams(byte town_name) :
|
||||
grf(town_name >= _nb_orig_names),
|
||||
grfid(this->grf ? GetGRFTownNameId(town_name - _nb_orig_names) : 0),
|
||||
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 and terminating '\0' */
|
||||
char buf1[MAX_LENGTH_TOWN_NAME_BYTES + 4 + 1];
|
||||
char buf2[MAX_LENGTH_TOWN_NAME_BYTES + 4 + 1];
|
||||
|
||||
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, 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)
|
||||
{
|
||||
extern int _nb_orig_names;
|
||||
Town *t2;
|
||||
char buf1[64];
|
||||
char buf2[64];
|
||||
uint32 r;
|
||||
/* 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;
|
||||
bool grf = (_settings_game.game_creation.town_name >= _nb_orig_names);
|
||||
uint32 grfid = grf ? GetGRFTownNameId(_settings_game.game_creation.town_name - _nb_orig_names) : 0;
|
||||
uint16 townnametype = grf ? GetGRFTownNameType(_settings_game.game_creation.town_name - _nb_orig_names) : SPECSTR_TOWNNAME_START + _settings_game.game_creation.town_name;
|
||||
TownNameParams par(_settings_game.game_creation.town_name);
|
||||
|
||||
assert(townnameparts != NULL);
|
||||
|
||||
for (;;) {
|
||||
restart:
|
||||
r = Random();
|
||||
uint32 r = InteractiveRandom();
|
||||
|
||||
SetDParam(0, r);
|
||||
if (grf && grfid != 0) {
|
||||
GRFTownNameGenerate(buf1, grfid, townnametype, r, lastof(buf1));
|
||||
} else {
|
||||
GetString(buf1, townnametype, lastof(buf1));
|
||||
if (!VerifyTownName(r, &par)) {
|
||||
if (tries-- < 0) return false;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check size and width */
|
||||
if (strlen(buf1) >= MAX_LENGTH_TOWN_NAME_BYTES || GetStringBoundingBox(buf1).width > MAX_LENGTH_TOWN_NAME_PIXELS) continue;
|
||||
|
||||
FOR_ALL_TOWNS(t2) {
|
||||
/* We can't just compare the numbers since
|
||||
* several numbers may map to a single name. */
|
||||
SetDParam(0, t2->index);
|
||||
GetString(buf2, STR_TOWN, lastof(buf2));
|
||||
if (strcmp(buf1, buf2) == 0) {
|
||||
if (tries-- < 0) return false;
|
||||
goto restart;
|
||||
}
|
||||
}
|
||||
*townnameparts = r;
|
||||
return true;
|
||||
}
|
||||
@ -1429,8 +1463,6 @@ void UpdateTownMaxPass(Town *t)
|
||||
*/
|
||||
static void DoCreateTown(Town *t, TileIndex tile, uint32 townnameparts, TownSize size, bool city, TownLayout layout)
|
||||
{
|
||||
extern int _nb_orig_names;
|
||||
|
||||
t->xy = tile;
|
||||
t->num_houses = 0;
|
||||
t->time_until_rebuild = 10;
|
||||
@ -1485,8 +1517,6 @@ static void DoCreateTown(Town *t, TileIndex tile, uint32 townnameparts, TownSize
|
||||
if (size == TS_RANDOM) x = (Random() & 0xF) + 8;
|
||||
if (city) x *= _settings_game.economy.initial_city_size;
|
||||
|
||||
t->noise_reached = 0;
|
||||
|
||||
t->num_houses += x;
|
||||
UpdateTownRadius(t);
|
||||
|
||||
@ -1498,6 +1528,7 @@ static void DoCreateTown(Town *t, TileIndex tile, uint32 townnameparts, TownSize
|
||||
t->num_houses -= x;
|
||||
UpdateTownRadius(t);
|
||||
UpdateTownMaxPass(t);
|
||||
UpdateAirportsNoise();
|
||||
}
|
||||
|
||||
/** Create a new town.
|
||||
@ -1508,7 +1539,7 @@ static void DoCreateTown(Town *t, TileIndex tile, uint32 townnameparts, TownSize
|
||||
* @param p1 0..1 size of the town (@see TownSize)
|
||||
* 2 true iff it should be a city
|
||||
* 3..5 town road layout (@see TownLayout)
|
||||
* @param p2 unused
|
||||
* @param p2 town name parts
|
||||
*/
|
||||
CommandCost CmdBuildTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||
{
|
||||
@ -1518,29 +1549,28 @@ CommandCost CmdBuildTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
|
||||
TownSize size = (TownSize)GB(p1, 0, 2);
|
||||
bool city = HasBit(p1, 2);
|
||||
TownLayout layout = (TownLayout)GB(p1, 3, 3);
|
||||
TownNameParams par(_settings_game.game_creation.town_name);
|
||||
uint32 townnameparts = p2;
|
||||
|
||||
if (size > TS_RANDOM) return CMD_ERROR;
|
||||
if (layout > TL_RANDOM) return CMD_ERROR;
|
||||
if (!VerifyTownName(townnameparts, &par)) return_cmd_error(STR_NAME_MUST_BE_UNIQUE);
|
||||
|
||||
/* Check if too close to the edge of map */
|
||||
if (DistanceFromEdge(tile) < 12)
|
||||
if (DistanceFromEdge(tile) < 12) {
|
||||
return_cmd_error(STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP);
|
||||
}
|
||||
|
||||
/* Check distance to all other towns. */
|
||||
if (IsCloseToTown(tile, 20)) {
|
||||
return_cmd_error(STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN);
|
||||
}
|
||||
|
||||
/* Can only build on clear flat areas, possibly with trees. */
|
||||
if ((!IsTileType(tile, MP_CLEAR) && !IsTileType(tile, MP_TREES)) || GetTileSlope(tile, NULL) != SLOPE_FLAT) {
|
||||
return_cmd_error(STR_0239_SITE_UNSUITABLE);
|
||||
}
|
||||
|
||||
/* Check distance to all other towns. */
|
||||
if (IsCloseToTown(tile, 20))
|
||||
return_cmd_error(STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN);
|
||||
|
||||
uint32 townnameparts;
|
||||
|
||||
/* Get a unique name for the town. */
|
||||
if (!CreateTownName(&townnameparts))
|
||||
return_cmd_error(STR_023A_TOO_MANY_TOWNS);
|
||||
|
||||
/* Allocate town struct */
|
||||
if (!Town::CanAllocateItem()) return_cmd_error(STR_023A_TOO_MANY_TOWNS);
|
||||
|
||||
@ -1583,7 +1613,7 @@ Town *CreateRandomTown(uint attempts, TownSize size, bool city, TownLayout layou
|
||||
uint32 townnameparts;
|
||||
|
||||
/* Get a unique name for the town. */
|
||||
if (!CreateTownName(&townnameparts)) break;
|
||||
if (!GenerateTownName(&townnameparts)) break;
|
||||
|
||||
/* Allocate a town struct */
|
||||
Town *t = new Town(tile);
|
||||
|
@ -752,7 +752,13 @@ public:
|
||||
|
||||
static void PlaceProc_Town(TileIndex tile)
|
||||
{
|
||||
DoCommandP(tile, town_size | city << 2 | town_layout << 3, 0, CMD_BUILD_TOWN | CMD_MSG(STR_0236_CAN_T_BUILD_TOWN_HERE), CcBuildTown);
|
||||
uint32 townnameparts;
|
||||
if (!GenerateTownName(&townnameparts)) {
|
||||
ShowErrorMessage(STR_023A_TOO_MANY_TOWNS, STR_0236_CAN_T_BUILD_TOWN_HERE, 0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
DoCommandP(tile, town_size | city << 2 | town_layout << 3, townnameparts, CMD_BUILD_TOWN | CMD_MSG(STR_0236_CAN_T_BUILD_TOWN_HERE), CcBuildTown);
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user