MCPcopy Create free account
hub / github.com/OpenTTD/OpenTTD / CmdFoundTown

Function CmdFoundTown

src/town_cmd.cpp:2197–2287  ·  view source on GitHub ↗

* Create a new town. * @param flags The type of operation. * @param tile The coordinates where town is built. * @param size The size of the town (@see TownSize). * @param city Should we build a city? * @param layout The town road layout (@see TownLayout). * @param random_location Should we use a random location? (randomize \c tile ) * @param townnameparts Town name parts. * @param text Cus

Source from the content-addressed store, hash-verified

2195 * @return The cost of this operation or an error.
2196 */
2197std::tuple<CommandCost, Money, TownID> CmdFoundTown(DoCommandFlags flags, TileIndex tile, TownSize size, bool city, TownLayout layout, bool random_location, uint32_t townnameparts, const std::string &text)
2198{
2199 TownNameParams par(_settings_game.game_creation.town_name);
2200
2201 if (size >= TSZ_END) return { CMD_ERROR, 0, TownID::Invalid() };
2202 if (layout >= NUM_TLS) return { CMD_ERROR, 0, TownID::Invalid() };
2203
2204 /* Some things are allowed only in the scenario editor and for game scripts. */
2205 if (_game_mode != GM_EDITOR && _current_company != OWNER_DEITY) {
2206 if (_settings_game.economy.found_town == TF_FORBIDDEN) return { CMD_ERROR, 0, TownID::Invalid() };
2207 if (size == TSZ_LARGE) return { CMD_ERROR, 0, TownID::Invalid() };
2208 if (random_location) return { CMD_ERROR, 0, TownID::Invalid() };
2209 if (_settings_game.economy.found_town != TF_CUSTOM_LAYOUT && layout != _settings_game.economy.town_layout) {
2210 return { CMD_ERROR, 0, TownID::Invalid() };
2211 }
2212 } else if (_current_company == OWNER_DEITY && random_location) {
2213 /* Random parameter is not allowed for Game Scripts. */
2214 return { CMD_ERROR, 0, TownID::Invalid() };
2215 }
2216
2217 if (text.empty()) {
2218 /* If supplied name is empty, townnameparts has to generate unique automatic name */
2219 if (!VerifyTownName(townnameparts, &par)) return { CommandCost(STR_ERROR_NAME_MUST_BE_UNIQUE), 0, TownID::Invalid() };
2220 } else {
2221 /* If name is not empty, it has to be unique custom name */
2222 if (Utf8StringLength(text) >= MAX_LENGTH_TOWN_NAME_CHARS) return { CMD_ERROR, 0, TownID::Invalid() };
2223 if (!IsUniqueTownName(text)) return { CommandCost(STR_ERROR_NAME_MUST_BE_UNIQUE), 0, TownID::Invalid() };
2224 }
2225
2226 /* Allocate town struct */
2227 if (!Town::CanAllocateItem()) return { CommandCost(STR_ERROR_TOO_MANY_TOWNS), 0, TownID::Invalid() };
2228
2229 if (!random_location) {
2230 CommandCost ret = TownCanBePlacedHere(tile, false);
2231 if (ret.Failed()) return { ret, 0, TownID::Invalid() };
2232 }
2233
2234 static const uint8_t price_mult[][TSZ_RANDOM + 1] = {{ 15, 25, 40, 25 }, { 20, 35, 55, 35 }};
2235 /* multidimensional arrays have to have defined length of non-first dimension */
2236 static_assert(lengthof(price_mult[0]) == 4);
2237
2238 CommandCost cost(EXPENSES_OTHER, _price[PR_BUILD_TOWN]);
2239 uint8_t mult = price_mult[city][size];
2240
2241 cost.MultiplyCost(mult);
2242
2243 /* Create the town */
2244 TownID new_town = TownID::Invalid();
2245 if (flags.Test(DoCommandFlag::Execute)) {
2246 if (cost.GetCost() > GetAvailableMoneyForCommand()) {
2247 return { CommandCost(EXPENSES_OTHER), cost.GetCost(), TownID::Invalid() };
2248 }
2249
2250 Backup<bool> old_generating_world(_generating_world, true);
2251 UpdateNearestTownForRoadTiles(true);
2252 Town *t;
2253 if (random_location) {
2254 t = CreateRandomTown(20, townnameparts, size, city, layout);

Callers

nothing calls this directly

Calls 15

InvalidFunction · 0.85
VerifyTownNameFunction · 0.85
CommandCostClass · 0.85
Utf8StringLengthFunction · 0.85
IsUniqueTownNameFunction · 0.85
TownCanBePlacedHereFunction · 0.85
CreateRandomTownFunction · 0.85
DoCreateTownFunction · 0.85
AddTileNewsItemFunction · 0.85
FailedMethod · 0.80

Tested by

no test coverage detected