|
@@ -448,13 +448,13 @@ CommandCost CmdBuildSingleRail(TileIndex
|
|
|
|
|
|
switch (GetTileType(tile)) {
|
|
|
case MP_RAILWAY: {
|
|
|
CommandCost ret = CheckTileOwnership(tile);
|
|
|
if (ret.Failed()) return ret;
|
|
|
|
|
|
if (!IsPlainRail(tile)) return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); // just get appropriate error message
|
|
|
if (!IsPlainRail(tile)) return DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0); // just get appropriate error message
|
|
|
|
|
|
if (!IsCompatibleRail(GetRailType(tile), railtype)) return_cmd_error(STR_ERROR_IMPOSSIBLE_TRACK_COMBINATION);
|
|
|
|
|
|
ret = CheckTrackCombination(tile, trackbit, flags);
|
|
|
if (ret.Succeeded()) ret = EnsureNoTrainOnTrack(tile, track);
|
|
|
if (ret.Failed()) return ret;
|
|
@@ -466,25 +466,25 @@ CommandCost CmdBuildSingleRail(TileIndex
|
|
|
if (HasSignals(tile) && TracksOverlap(GetTrackBits(tile) | TrackToTrackBits(track))) {
|
|
|
/* If adding the new track causes any overlap, all signals must be removed first */
|
|
|
if (!auto_remove_signals) return_cmd_error(STR_ERROR_MUST_REMOVE_SIGNALS_FIRST);
|
|
|
|
|
|
for (Track track_it = TRACK_BEGIN; track_it < TRACK_END; track_it++) {
|
|
|
if (HasTrack(tile, track_it) && HasSignalOnTrack(tile, track_it)) {
|
|
|
CommandCost ret_remove_signals = DoCommand(tile, track_it, 0, flags, CMD_REMOVE_SIGNALS);
|
|
|
CommandCost ret_remove_signals = DoCommand(flags, CMD_REMOVE_SIGNALS, tile, track_it, 0);
|
|
|
if (ret_remove_signals.Failed()) return ret_remove_signals;
|
|
|
cost.AddCost(ret_remove_signals);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* If the rail types don't match, try to convert only if engines of
|
|
|
* the new rail type are not powered on the present rail type and engines of
|
|
|
* the present rail type are powered on the new rail type. */
|
|
|
if (GetRailType(tile) != railtype && !HasPowerOnRail(railtype, GetRailType(tile))) {
|
|
|
if (HasPowerOnRail(GetRailType(tile), railtype)) {
|
|
|
ret = DoCommand(tile, tile, railtype, flags, CMD_CONVERT_RAIL);
|
|
|
ret = DoCommand(flags, CMD_CONVERT_RAIL, tile, tile, railtype);
|
|
|
if (ret.Failed()) return ret;
|
|
|
cost.AddCost(ret);
|
|
|
} else {
|
|
|
return CMD_ERROR;
|
|
|
}
|
|
|
}
|
|
@@ -578,13 +578,13 @@ CommandCost CmdBuildSingleRail(TileIndex
|
|
|
bool water_ground = IsTileType(tile, MP_WATER) && IsSlopeWithOneCornerRaised(tileh);
|
|
|
|
|
|
CommandCost ret = CheckRailSlope(tileh, trackbit, TRACK_BIT_NONE, tile);
|
|
|
if (ret.Failed()) return ret;
|
|
|
cost.AddCost(ret);
|
|
|
|
|
|
ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
|
|
|
ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0);
|
|
|
if (ret.Failed()) return ret;
|
|
|
cost.AddCost(ret);
|
|
|
|
|
|
if (water_ground) {
|
|
|
cost.AddCost(-_price[PR_CLEAR_WATER]);
|
|
|
cost.AddCost(_price[PR_CLEAR_ROUGH]);
|
|
@@ -688,13 +688,13 @@ CommandCost CmdRemoveSingleRail(TileInde
|
|
|
if (present == (TRACK_BIT_X | TRACK_BIT_Y)) crossing = true;
|
|
|
|
|
|
cost.AddCost(RailClearCost(GetRailType(tile)));
|
|
|
|
|
|
/* Charge extra to remove signals on the track, if they are there */
|
|
|
if (HasSignalOnTrack(tile, track)) {
|
|
|
cost.AddCost(DoCommand(tile, track, 0, flags, CMD_REMOVE_SIGNALS));
|
|
|
cost.AddCost(DoCommand(flags, CMD_REMOVE_SIGNALS, tile, track, 0));
|
|
|
}
|
|
|
|
|
|
if (flags & DC_EXEC) {
|
|
|
if (HasReservedTracks(tile, trackbit)) {
|
|
|
v = GetTrainForReservation(tile, track);
|
|
|
if (v != nullptr) FreeTrainTrackReservation(v);
|
|
@@ -781,13 +781,13 @@ bool FloodHalftile(TileIndex t)
|
|
|
if (IsSlopeWithOneCornerRaised(tileh)) {
|
|
|
TrackBits lower_track = CornerToTrackBits(OppositeCorner(GetHighestSlopeCorner(tileh)));
|
|
|
|
|
|
TrackBits to_remove = lower_track & rail_bits;
|
|
|
if (to_remove != 0) {
|
|
|
Backup<CompanyID> cur_company(_current_company, OWNER_WATER, FILE_LINE);
|
|
|
flooded = DoCommand(t, 0, FIND_FIRST_BIT(to_remove), DC_EXEC, CMD_REMOVE_SINGLE_RAIL).Succeeded();
|
|
|
flooded = DoCommand(DC_EXEC, CMD_REMOVE_SINGLE_RAIL, t, 0, FIND_FIRST_BIT(to_remove)).Succeeded();
|
|
|
cur_company.Restore();
|
|
|
if (!flooded) return flooded; // not yet floodable
|
|
|
rail_bits = rail_bits & ~to_remove;
|
|
|
if (rail_bits == 0) {
|
|
|
MakeShore(t);
|
|
|
MarkTileDirtyByTile(t);
|
|
@@ -900,13 +900,13 @@ static CommandCost CmdRailTrackHelper(Ti
|
|
|
CommandCost ret = ValidateAutoDrag(&trackdir, tile, end_tile);
|
|
|
if (ret.Failed()) return ret;
|
|
|
|
|
|
bool had_success = false;
|
|
|
CommandCost last_error = CMD_ERROR;
|
|
|
for (;;) {
|
|
|
CommandCost ret = DoCommand(tile, remove ? 0 : railtype, TrackdirToTrack(trackdir) | (auto_remove_signals << 3), flags, remove ? CMD_REMOVE_SINGLE_RAIL : CMD_BUILD_SINGLE_RAIL);
|
|
|
CommandCost ret = DoCommand(flags, remove ? CMD_REMOVE_SINGLE_RAIL : CMD_BUILD_SINGLE_RAIL, tile, remove ? 0 : railtype, TrackdirToTrack(trackdir) | (auto_remove_signals << 3));
|
|
|
|
|
|
if (ret.Failed()) {
|
|
|
last_error = ret;
|
|
|
if (last_error.GetErrorMessage() != STR_ERROR_ALREADY_BUILT && !remove) {
|
|
|
if (HasBit(p2, 10)) return last_error;
|
|
|
break;
|
|
@@ -1004,13 +1004,13 @@ CommandCost CmdBuildTrainDepot(TileIndex
|
|
|
if (!_settings_game.construction.build_on_slopes || !CanBuildDepotByTileh(dir, tileh)) {
|
|
|
return_cmd_error(STR_ERROR_FLAT_LAND_REQUIRED);
|
|
|
}
|
|
|
cost.AddCost(_price[PR_BUILD_FOUNDATION]);
|
|
|
}
|
|
|
|
|
|
cost.AddCost(DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR));
|
|
|
cost.AddCost(DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0));
|
|
|
if (cost.Failed()) return cost;
|
|
|
|
|
|
if (IsBridgeAbove(tile)) return_cmd_error(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST);
|
|
|
|
|
|
if (!Depot::CanAllocateItem()) return CMD_ERROR;
|
|
|
|
|
@@ -1355,13 +1355,13 @@ static CommandCost CmdSignalTrackHelper(
|
|
|
|
|
|
/* Pick the correct orientation for the track direction */
|
|
|
byte signals = 0;
|
|
|
if (HasBit(signal_dir, 0)) signals |= SignalAlongTrackdir(trackdir);
|
|
|
if (HasBit(signal_dir, 1)) signals |= SignalAgainstTrackdir(trackdir);
|
|
|
|
|
|
CommandCost ret = DoCommand(tile, param1, signals, test_only ? flags & ~DC_EXEC : flags, remove ? CMD_REMOVE_SIGNALS : CMD_BUILD_SIGNALS);
|
|
|
CommandCost ret = DoCommand(test_only ? flags & ~DC_EXEC : flags, remove ? CMD_REMOVE_SIGNALS : CMD_BUILD_SIGNALS, tile, param1, signals);
|
|
|
|
|
|
if (test_only) return ret.Succeeded();
|
|
|
|
|
|
if (ret.Succeeded()) {
|
|
|
had_success = true;
|
|
|
total_cost.AddCost(ret);
|
|
@@ -1875,13 +1875,13 @@ static CommandCost ClearTile_Track(TileI
|
|
|
/* Is there flat water on the lower halftile that gets cleared expensively? */
|
|
|
bool water_ground = (GetRailGroundType(tile) == RAIL_GROUND_WATER && IsSlopeWithOneCornerRaised(tileh));
|
|
|
|
|
|
TrackBits tracks = GetTrackBits(tile);
|
|
|
while (tracks != TRACK_BIT_NONE) {
|
|
|
Track track = RemoveFirstTrack(&tracks);
|
|
|
CommandCost ret = DoCommand(tile, 0, track, flags, CMD_REMOVE_SINGLE_RAIL);
|
|
|
CommandCost ret = DoCommand(flags, CMD_REMOVE_SINGLE_RAIL, tile, 0, track);
|
|
|
if (ret.Failed()) return ret;
|
|
|
cost.AddCost(ret);
|
|
|
}
|
|
|
|
|
|
/* When bankrupting, don't make water dirty, there could be a ship on lower halftile.
|
|
|
* Same holds for non-companies clearing the tile, e.g. disasters. */
|
|
@@ -2949,13 +2949,13 @@ static void ChangeTileOwner_Track(TileIn
|
|
|
Company::Get(old_owner)->infrastructure.signal -= num_sigs;
|
|
|
Company::Get(new_owner)->infrastructure.signal += num_sigs;
|
|
|
}
|
|
|
|
|
|
SetTileOwner(tile, new_owner);
|
|
|
} else {
|
|
|
DoCommand(tile, 0, 0, DC_EXEC | DC_BANKRUPT, CMD_LANDSCAPE_CLEAR);
|
|
|
DoCommand(DC_EXEC | DC_BANKRUPT, CMD_LANDSCAPE_CLEAR, tile, 0, 0);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static const byte _fractcoords_behind[4] = { 0x8F, 0x8, 0x80, 0xF8 };
|
|
|
static const byte _fractcoords_enter[4] = { 0x8A, 0x48, 0x84, 0xA8 };
|
|
|
static const int8 _deltacoord_leaveoffset[8] = {
|
|
@@ -3137,13 +3137,13 @@ static CommandCost TerraformTile_Track(T
|
|
|
/* allow terraforming */
|
|
|
return CommandCost(EXPENSES_CONSTRUCTION, was_water ? _price[PR_CLEAR_WATER] : (Money)0);
|
|
|
} else if (_settings_game.construction.build_on_slopes && AutoslopeEnabled() &&
|
|
|
AutoslopeCheckForEntranceEdge(tile, z_new, tileh_new, GetRailDepotDirection(tile))) {
|
|
|
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);
|
|
|
}
|
|
|
|
|
|
|
|
|
extern const TileTypeProcs _tile_type_rail_procs = {
|
|
|
DrawTile_Track, // draw_tile_proc
|
|
|
GetSlopePixelZ_Track, // get_slope_z_proc
|