|
@@ -935,14 +935,14 @@ static bool IsRoadAllowedHere(Town *t, T
|
|
|
/* Check if there already is a road at this point? */
|
|
|
if (GetTownRoadBits(tile) == ROAD_NONE) {
|
|
|
/* No, try if we are able to build a road piece there.
|
|
|
* If that fails clear the land, and if that fails exit.
|
|
|
* This is to make sure that we can build a road here later. */
|
|
|
RoadType rt = GetTownRoadType(t);
|
|
|
if (DoCommand(tile, ((dir == DIAGDIR_NW || dir == DIAGDIR_SE) ? ROAD_Y : ROAD_X) | (rt << 4), 0, DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD).Failed() &&
|
|
|
DoCommand(tile, 0, 0, DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR).Failed()) {
|
|
|
if (DoCommand(DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD, tile, ((dir == DIAGDIR_NW || dir == DIAGDIR_SE) ? ROAD_Y : ROAD_X) | (rt << 4), 0).Failed() &&
|
|
|
DoCommand(DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR, tile, 0, 0).Failed()) {
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
Slope cur_slope = _settings_game.construction.build_on_slopes ? GetFoundationSlope(tile) : GetTileSlope(tile);
|
|
|
bool ret = !IsNeighborRoadTile(tile, dir, t->layout == TL_ORIGINAL ? 1 : 2);
|
|
@@ -953,14 +953,14 @@ static bool IsRoadAllowedHere(Town *t, T
|
|
|
Slope desired_slope = (dir == DIAGDIR_NW || dir == DIAGDIR_SE) ? SLOPE_NW : SLOPE_NE;
|
|
|
if (desired_slope != cur_slope && ComplementSlope(desired_slope) != cur_slope) {
|
|
|
if (Chance16(1, 8)) {
|
|
|
CommandCost res = CMD_ERROR;
|
|
|
if (!_generating_world && Chance16(1, 10)) {
|
|
|
/* Note: Do not replace "^ SLOPE_ELEVATED" with ComplementSlope(). The slope might be steep. */
|
|
|
res = DoCommand(tile, Chance16(1, 16) ? cur_slope : cur_slope ^ SLOPE_ELEVATED, 0,
|
|
|
DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_TERRAFORM_LAND);
|
|
|
res = DoCommand(DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_TERRAFORM_LAND,
|
|
|
tile, Chance16(1, 16) ? cur_slope : cur_slope ^ SLOPE_ELEVATED, 0);
|
|
|
}
|
|
|
if (res.Failed() && Chance16(1, 3)) {
|
|
|
/* We can consider building on the slope, though. */
|
|
|
return ret;
|
|
|
}
|
|
|
}
|
|
@@ -970,15 +970,15 @@ static bool IsRoadAllowedHere(Town *t, T
|
|
|
}
|
|
|
|
|
|
static bool TerraformTownTile(TileIndex tile, int edges, int dir)
|
|
|
{
|
|
|
assert(tile < MapSize());
|
|
|
|
|
|
CommandCost r = DoCommand(tile, edges, dir, DC_AUTO | DC_NO_WATER, CMD_TERRAFORM_LAND);
|
|
|
CommandCost r = DoCommand(DC_AUTO | DC_NO_WATER, CMD_TERRAFORM_LAND, tile, edges, dir);
|
|
|
if (r.Failed() || r.GetCost() >= (_price[PR_TERRAFORM] + 2) * 8) return false;
|
|
|
DoCommand(tile, edges, dir, DC_AUTO | DC_NO_WATER | DC_EXEC, CMD_TERRAFORM_LAND);
|
|
|
DoCommand(DC_AUTO | DC_NO_WATER | DC_EXEC, CMD_TERRAFORM_LAND, tile, edges, dir);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
static void LevelTownLand(TileIndex tile)
|
|
|
{
|
|
|
assert(tile < MapSize());
|
|
@@ -1104,13 +1104,13 @@ static bool GrowTownWithExtraHouse(Town
|
|
|
* @param rcmd The RoadBits we want to build on the tile
|
|
|
* @return true if the RoadBits have been added else false
|
|
|
*/
|
|
|
static bool GrowTownWithRoad(const Town *t, TileIndex tile, RoadBits rcmd)
|
|
|
{
|
|
|
RoadType rt = GetTownRoadType(t);
|
|
|
if (DoCommand(tile, rcmd | (rt << 4), t->index, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD).Succeeded()) {
|
|
|
if (DoCommand(DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD, tile, rcmd | (rt << 4), t->index).Succeeded()) {
|
|
|
_grow_town_result = GROWTH_SUCCEED;
|
|
|
return true;
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
|
|
@@ -1151,13 +1151,13 @@ static bool CanRoadContinueIntoNextTile(
|
|
|
|
|
|
/* If the next tile is a railroad track, check if towns are allowed to build level crossings.
|
|
|
* If level crossing are not allowed, reject the construction. Else allow DoCommand to determine if the rail track is buildable. */
|
|
|
if (IsTileType(next_tile, MP_RAILWAY) && !_settings_game.economy.allow_town_level_crossings) return false;
|
|
|
|
|
|
/* If a road tile can be built, the construction is allowed. */
|
|
|
return DoCommand(next_tile, rcmd | (rt << 4), t->index, DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD).Succeeded();
|
|
|
return DoCommand(DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD, next_tile, rcmd | (rt << 4), t->index).Succeeded();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Grows the town with a bridge.
|
|
|
* At first we check if a bridge is reasonable.
|
|
|
* If so we check if we are able to build it.
|
|
@@ -1219,14 +1219,14 @@ static bool GrowTownWithBridge(const Tow
|
|
|
|
|
|
for (uint8 times = 0; times <= 22; times++) {
|
|
|
byte bridge_type = RandomRange(MAX_BRIDGES - 1);
|
|
|
|
|
|
/* Can we actually build the bridge? */
|
|
|
RoadType rt = GetTownRoadType(t);
|
|
|
if (DoCommand(tile, bridge_tile, bridge_type | rt << 8 | TRANSPORT_ROAD << 15, CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_BRIDGE)), CMD_BUILD_BRIDGE).Succeeded()) {
|
|
|
DoCommand(tile, bridge_tile, bridge_type | rt << 8 | TRANSPORT_ROAD << 15, DC_EXEC | CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_BRIDGE)), CMD_BUILD_BRIDGE);
|
|
|
if (DoCommand(CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_BRIDGE)), CMD_BUILD_BRIDGE, tile, bridge_tile, bridge_type | rt << 8 | TRANSPORT_ROAD << 15).Succeeded()) {
|
|
|
DoCommand(DC_EXEC | CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_BRIDGE)), CMD_BUILD_BRIDGE, tile, bridge_tile, bridge_type | rt << 8 | TRANSPORT_ROAD << 15);
|
|
|
_grow_town_result = GROWTH_SUCCEED;
|
|
|
return true;
|
|
|
}
|
|
|
}
|
|
|
/* Quit if it selecting an appropriate bridge type fails a large number of times. */
|
|
|
return false;
|
|
@@ -1290,14 +1290,14 @@ static bool GrowTownWithTunnel(const Tow
|
|
|
|
|
|
/* Make sure the road can be continued past the tunnel. At this point, tunnel_tile holds the end tile of the tunnel. */
|
|
|
if (!CanRoadContinueIntoNextTile(t, tunnel_tile, tunnel_dir)) return false;
|
|
|
|
|
|
/* Attempt to build the tunnel. Return false if it fails to let the town build a road instead. */
|
|
|
RoadType rt = GetTownRoadType(t);
|
|
|
if (DoCommand(tile, rt | (TRANSPORT_ROAD << 8), 0, CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_TUNNEL)), CMD_BUILD_TUNNEL).Succeeded()) {
|
|
|
DoCommand(tile, rt | (TRANSPORT_ROAD << 8), 0, DC_EXEC | CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_TUNNEL)), CMD_BUILD_TUNNEL);
|
|
|
if (DoCommand(CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_TUNNEL)), CMD_BUILD_TUNNEL, tile, rt | (TRANSPORT_ROAD << 8), 0).Succeeded()) {
|
|
|
DoCommand(DC_EXEC | CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_TUNNEL)), CMD_BUILD_TUNNEL, tile, rt | (TRANSPORT_ROAD << 8), 0);
|
|
|
_grow_town_result = GROWTH_SUCCEED;
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
}
|
|
@@ -1729,15 +1729,15 @@ static bool GrowTown(Town *t)
|
|
|
* clearing some land and then building a road there. */
|
|
|
if (_settings_game.economy.allow_town_roads || _generating_world) {
|
|
|
tile = t->xy;
|
|
|
for (ptr = _town_coord_mod; ptr != endof(_town_coord_mod); ++ptr) {
|
|
|
/* Only work with plain land that not already has a house */
|
|
|
if (!IsTileType(tile, MP_HOUSE) && IsTileFlat(tile)) {
|
|
|
if (DoCommand(tile, 0, 0, DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR).Succeeded()) {
|
|
|
if (DoCommand(DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR, tile, 0, 0).Succeeded()) {
|
|
|
RoadType rt = GetTownRoadType(t);
|
|
|
DoCommand(tile, GenRandomRoadBits() | (rt << 4), t->index, DC_EXEC | DC_AUTO, CMD_BUILD_ROAD);
|
|
|
DoCommand(DC_EXEC | DC_AUTO, CMD_BUILD_ROAD, tile, GenRandomRoadBits() | (rt << 4), t->index);
|
|
|
cur_company.Restore();
|
|
|
return true;
|
|
|
}
|
|
|
}
|
|
|
tile = TILE_ADD(tile, ToTileIndexDiff(*ptr));
|
|
|
}
|
|
@@ -2176,13 +2176,13 @@ static Town *CreateRandomTown(uint attem
|
|
|
|
|
|
/* if the population is still 0 at the point, then the
|
|
|
* placement is so bad it couldn't grow at all */
|
|
|
if (t->cache.population > 0) return t;
|
|
|
|
|
|
Backup<CompanyID> cur_company(_current_company, OWNER_TOWN, FILE_LINE);
|
|
|
[[maybe_unused]] CommandCost rc = DoCommand(t->xy, t->index, 0, DC_EXEC, CMD_DELETE_TOWN);
|
|
|
[[maybe_unused]] CommandCost rc = DoCommand(DC_EXEC, CMD_DELETE_TOWN, t->xy, t->index, 0);
|
|
|
cur_company.Restore();
|
|
|
assert(rc.Succeeded());
|
|
|
|
|
|
/* We already know that we can allocate a single town when
|
|
|
* entering this function. However, we create and delete
|
|
|
* a town which "resets" the allocation checks. As such we
|
|
@@ -2277,13 +2277,13 @@ HouseZonesBits GetTownRadiusGroup(const
|
|
|
* @param type of house. Index into house specs array
|
|
|
* @param random_bits required for newgrf houses
|
|
|
* @pre house can be built here
|
|
|
*/
|
|
|
static inline void ClearMakeHouseTile(TileIndex tile, Town *t, byte counter, byte stage, HouseID type, byte random_bits)
|
|
|
{
|
|
|
[[maybe_unused]] CommandCost cc = DoCommand(tile, 0, 0, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR);
|
|
|
[[maybe_unused]] CommandCost cc = DoCommand(DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR, tile, 0, 0);
|
|
|
assert(cc.Succeeded());
|
|
|
|
|
|
IncreaseBuildingCount(t, type);
|
|
|
MakeHouseTile(tile, t->index, counter, stage, type, random_bits);
|
|
|
if (HouseSpec::Get(type)->building_flags & BUILDING_IS_ANIMATED) AddAnimatedTile(tile);
|
|
|
|
|
@@ -2334,13 +2334,13 @@ static inline bool CanBuildHouseHere(Til
|
|
|
if (!RoadTypesAllowHouseHere(tile)) return false;
|
|
|
|
|
|
/* building under a bridge? */
|
|
|
if (IsBridgeAbove(tile)) return false;
|
|
|
|
|
|
/* can we clear the land? */
|
|
|
return DoCommand(tile, 0, 0, DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR).Succeeded();
|
|
|
return DoCommand(DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR, tile, 0, 0).Succeeded();
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* Checks if a house can be built at this tile, must have the same max z as parameter.
|
|
|
* @param tile tile to check
|
|
@@ -2969,13 +2969,13 @@ CommandCost CmdDeleteTown(TileIndex tile
|
|
|
/* Stations refer to towns. */
|
|
|
for (const Station *st : Station::Iterate()) {
|
|
|
if (st->town == t) {
|
|
|
/* Non-oil rig stations are always a problem. */
|
|
|
if (!(st->facilities & FACIL_AIRPORT) || st->airport.type != AT_OILRIG) return CMD_ERROR;
|
|
|
/* We can only automatically delete oil rigs *if* there's no vehicle on them. */
|
|
|
CommandCost ret = DoCommand(st->airport.tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
|
|
|
CommandCost ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, st->airport.tile, 0, 0);
|
|
|
if (ret.Failed()) return ret;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* Depots refer to towns. */
|
|
|
for (const Depot *d : Depot::Iterate()) {
|
|
@@ -2985,13 +2985,13 @@ CommandCost CmdDeleteTown(TileIndex tile
|
|
|
/* Check all tiles for town ownership. First check for bridge tiles, as
|
|
|
* these do not directly have an owner so we need to check adjacent
|
|
|
* tiles. This won't work correctly in the same loop if the adjacent
|
|
|
* tile was already deleted earlier in the loop. */
|
|
|
for (TileIndex current_tile = 0; current_tile < MapSize(); ++current_tile) {
|
|
|
if (IsTileType(current_tile, MP_TUNNELBRIDGE) && TestTownOwnsBridge(current_tile, t)) {
|
|
|
CommandCost ret = DoCommand(current_tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
|
|
|
CommandCost ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, current_tile, 0, 0);
|
|
|
if (ret.Failed()) return ret;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* Check all remaining tiles for town ownership. */
|
|
|
for (TileIndex current_tile = 0; current_tile < MapSize(); ++current_tile) {
|
|
@@ -3028,13 +3028,13 @@ CommandCost CmdDeleteTown(TileIndex tile
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
if (try_clear) {
|
|
|
CommandCost ret = DoCommand(current_tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
|
|
|
CommandCost ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, current_tile, 0, 0);
|
|
|
if (ret.Failed()) return ret;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* The town destructor will delete the other things related to the town. */
|
|
|
if (flags & DC_EXEC) {
|
|
@@ -3104,13 +3104,13 @@ static CommandCost TownActionRoadRebuild
|
|
|
* @param tile Tile to check.
|
|
|
* @return The tile can be cleared.
|
|
|
*/
|
|
|
static bool TryClearTile(TileIndex tile)
|
|
|
{
|
|
|
Backup<CompanyID> cur_company(_current_company, OWNER_NONE, FILE_LINE);
|
|
|
CommandCost r = DoCommand(tile, 0, 0, DC_NONE, CMD_LANDSCAPE_CLEAR);
|
|
|
CommandCost r = DoCommand(DC_NONE, CMD_LANDSCAPE_CLEAR, tile, 0, 0);
|
|
|
cur_company.Restore();
|
|
|
return r.Succeeded();
|
|
|
}
|
|
|
|
|
|
/** Structure for storing data while searching the best place to build a statue. */
|
|
|
struct StatueBuildSearchData {
|
|
@@ -3176,13 +3176,13 @@ static CommandCost TownActionBuildStatue
|
|
|
TileIndex tile = t->xy;
|
|
|
StatueBuildSearchData statue_data(INVALID_TILE, 0);
|
|
|
if (!CircularTileSearch(&tile, 9, SearchTileForStatue, &statue_data)) return_cmd_error(STR_ERROR_STATUE_NO_SUITABLE_PLACE);
|
|
|
|
|
|
if (flags & DC_EXEC) {
|
|
|
Backup<CompanyID> cur_company(_current_company, OWNER_NONE, FILE_LINE);
|
|
|
DoCommand(statue_data.best_position, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
|
|
|
DoCommand(DC_EXEC, CMD_LANDSCAPE_CLEAR, statue_data.best_position, 0, 0);
|
|
|
cur_company.Restore();
|
|
|
BuildObject(OBJECT_STATUE, statue_data.best_position, _current_company, t);
|
|
|
SetBit(t->statues, _current_company); // Once found and built, "inform" the Town.
|
|
|
MarkTileDirtyByTile(statue_data.best_position);
|
|
|
}
|
|
|
return CommandCost();
|
|
@@ -3783,13 +3783,13 @@ static CommandCost TerraformTile_Town(Ti
|
|
|
}
|
|
|
|
|
|
if (allow_terraform) return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
|
|
|
return DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0);
|
|
|
}
|
|
|
|
|
|
/** Tile callback functions for a town */
|
|
|
extern const TileTypeProcs _tile_type_town_procs = {
|
|
|
DrawTile_Town, // draw_tile_proc
|
|
|
GetSlopePixelZ_Town, // get_slope_z_proc
|