mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-08 23:19:40 +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);
|
void SetTownRatingTestMode(bool mode);
|
||||||
uint GetMaskOfTownActions(int *nump, CompanyID cid, const Town *t);
|
uint GetMaskOfTownActions(int *nump, CompanyID cid, const Town *t);
|
||||||
bool GenerateTowns(TownLayout layout);
|
bool GenerateTowns(TownLayout layout);
|
||||||
|
bool GenerateTownName(uint32 *townnameparts);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate a hash value from a tile position
|
* 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
|
/* 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
|
* for #tries only one time anyway - then we stop generating more
|
||||||
* towns. Do not show it too high neither, since looping through all
|
* towns. Do not show it too high neither, since looping through all
|
||||||
* the other towns may take considerable amount of time (10000 is
|
* the other towns may take considerable amount of time (10000 is
|
||||||
* too much). */
|
* too much). */
|
||||||
int tries = 1000;
|
int tries = 1000;
|
||||||
bool grf = (_settings_game.game_creation.town_name >= _nb_orig_names);
|
TownNameParams par(_settings_game.game_creation.town_name);
|
||||||
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;
|
|
||||||
|
|
||||||
assert(townnameparts != NULL);
|
assert(townnameparts != NULL);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
restart:
|
uint32 r = InteractiveRandom();
|
||||||
r = Random();
|
|
||||||
|
|
||||||
SetDParam(0, r);
|
if (!VerifyTownName(r, &par)) {
|
||||||
if (grf && grfid != 0) {
|
if (tries-- < 0) return false;
|
||||||
GRFTownNameGenerate(buf1, grfid, townnametype, r, lastof(buf1));
|
continue;
|
||||||
} else {
|
|
||||||
GetString(buf1, townnametype, lastof(buf1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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;
|
*townnameparts = r;
|
||||||
return true;
|
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)
|
static void DoCreateTown(Town *t, TileIndex tile, uint32 townnameparts, TownSize size, bool city, TownLayout layout)
|
||||||
{
|
{
|
||||||
extern int _nb_orig_names;
|
|
||||||
|
|
||||||
t->xy = tile;
|
t->xy = tile;
|
||||||
t->num_houses = 0;
|
t->num_houses = 0;
|
||||||
t->time_until_rebuild = 10;
|
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 (size == TS_RANDOM) x = (Random() & 0xF) + 8;
|
||||||
if (city) x *= _settings_game.economy.initial_city_size;
|
if (city) x *= _settings_game.economy.initial_city_size;
|
||||||
|
|
||||||
t->noise_reached = 0;
|
|
||||||
|
|
||||||
t->num_houses += x;
|
t->num_houses += x;
|
||||||
UpdateTownRadius(t);
|
UpdateTownRadius(t);
|
||||||
|
|
||||||
@ -1498,6 +1528,7 @@ static void DoCreateTown(Town *t, TileIndex tile, uint32 townnameparts, TownSize
|
|||||||
t->num_houses -= x;
|
t->num_houses -= x;
|
||||||
UpdateTownRadius(t);
|
UpdateTownRadius(t);
|
||||||
UpdateTownMaxPass(t);
|
UpdateTownMaxPass(t);
|
||||||
|
UpdateAirportsNoise();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Create a new town.
|
/** 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)
|
* @param p1 0..1 size of the town (@see TownSize)
|
||||||
* 2 true iff it should be a city
|
* 2 true iff it should be a city
|
||||||
* 3..5 town road layout (@see TownLayout)
|
* 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)
|
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);
|
TownSize size = (TownSize)GB(p1, 0, 2);
|
||||||
bool city = HasBit(p1, 2);
|
bool city = HasBit(p1, 2);
|
||||||
TownLayout layout = (TownLayout)GB(p1, 3, 3);
|
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 (size > TS_RANDOM) return CMD_ERROR;
|
||||||
if (layout > TL_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 */
|
/* 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);
|
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. */
|
/* Can only build on clear flat areas, possibly with trees. */
|
||||||
if ((!IsTileType(tile, MP_CLEAR) && !IsTileType(tile, MP_TREES)) || GetTileSlope(tile, NULL) != SLOPE_FLAT) {
|
if ((!IsTileType(tile, MP_CLEAR) && !IsTileType(tile, MP_TREES)) || GetTileSlope(tile, NULL) != SLOPE_FLAT) {
|
||||||
return_cmd_error(STR_0239_SITE_UNSUITABLE);
|
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 */
|
/* Allocate town struct */
|
||||||
if (!Town::CanAllocateItem()) return_cmd_error(STR_023A_TOO_MANY_TOWNS);
|
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;
|
uint32 townnameparts;
|
||||||
|
|
||||||
/* Get a unique name for the town. */
|
/* Get a unique name for the town. */
|
||||||
if (!CreateTownName(&townnameparts)) break;
|
if (!GenerateTownName(&townnameparts)) break;
|
||||||
|
|
||||||
/* Allocate a town struct */
|
/* Allocate a town struct */
|
||||||
Town *t = new Town(tile);
|
Town *t = new Town(tile);
|
||||||
|
@ -752,7 +752,13 @@ public:
|
|||||||
|
|
||||||
static void PlaceProc_Town(TileIndex tile)
|
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