--- a/src/tunnelbridge_cmd.cpp Sun Jun 17 21:31:00 2007 +0000
+++ b/src/tunnelbridge_cmd.cpp Tue Jun 26 23:40:58 2007 +0000
@@ -110,32 +110,32 @@
* - rest is invalid
*/
#define M(x) (1 << (x))
-static int32 CheckBridgeSlopeNorth(Axis axis, Slope tileh)
+static CommandCost CheckBridgeSlopeNorth(Axis axis, Slope tileh)
{
uint32 valid;
valid = M(SLOPE_FLAT) | (axis == AXIS_X ? M(SLOPE_NE) : M(SLOPE_NW));
- if (HASBIT(valid, tileh)) return 0;
+ if (HASBIT(valid, tileh)) return CommandCost();
valid =
BRIDGE_FULL_LEVELED_FOUNDATION | M(SLOPE_N) | M(SLOPE_STEEP_N) |
(axis == AXIS_X ? M(SLOPE_E) | M(SLOPE_STEEP_E) : M(SLOPE_W) | M(SLOPE_STEEP_W));
- if (HASBIT(valid, tileh)) return _price.terraform;
+ if (HASBIT(valid, tileh)) return CommandCost(_price.terraform);
return CMD_ERROR;
}
-static int32 CheckBridgeSlopeSouth(Axis axis, Slope tileh)
+static CommandCost CheckBridgeSlopeSouth(Axis axis, Slope tileh)
{
uint32 valid;
valid = M(SLOPE_FLAT) | (axis == AXIS_X ? M(SLOPE_SW) : M(SLOPE_SE));
- if (HASBIT(valid, tileh)) return 0;
+ if (HASBIT(valid, tileh)) return CommandCost();
valid =
BRIDGE_FULL_LEVELED_FOUNDATION | M(SLOPE_S) | M(SLOPE_STEEP_S) |
(axis == AXIS_X ? M(SLOPE_W) | M(SLOPE_STEEP_W) : M(SLOPE_E) | M(SLOPE_STEEP_E));
- if (HASBIT(valid, tileh)) return _price.terraform;
+ if (HASBIT(valid, tileh)) return CommandCost(_price.terraform);
return CMD_ERROR;
}
@@ -175,7 +175,7 @@
* - p2 = (bit 8-..) - rail type or road types.
* - p2 = (bit 15 ) - set means road bridge.
*/
-int32 CmdBuildBridge(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p2)
+CommandCost CmdBuildBridge(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p2)
{
uint bridge_type;
RailType railtype;
@@ -194,7 +194,7 @@
TileIndexDiff delta;
uint bridge_len;
Axis direction;
- int32 cost, terraformcost, ret;
+ CommandCost cost, terraformcost, ret;
bool allow_on_slopes;
bool replace_bridge = false;
uint replaced_bridge_type;
@@ -300,7 +300,7 @@
return_cmd_error(STR_1024_AREA_IS_OWNED_BY_ANOTHER);
}
- cost = (bridge_len + 1) * _price.clear_bridge; // The cost of clearing the current bridge.
+ cost.AddCost((bridge_len + 1) * _price.clear_bridge); // The cost of clearing the current bridge.
replace_bridge = true;
replaced_bridge_type = GetBridgeType(tile_start);
@@ -315,20 +315,20 @@
cost = ret;
terraformcost = CheckBridgeSlopeNorth(direction, tileh_start);
- if (CmdFailed(terraformcost) || (terraformcost != 0 && !allow_on_slopes))
+ if (CmdFailed(terraformcost) || (terraformcost.GetCost() != 0 && !allow_on_slopes))
return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
- cost += terraformcost;
+ cost.AddCost(terraformcost);
/* Try and clear the end landscape */
ret = DoCommand(tile_end, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
if (CmdFailed(ret)) return ret;
- cost += ret;
+ cost.AddCost(ret);
/* false - end tile slope check */
terraformcost = CheckBridgeSlopeSouth(direction, tileh_end);
- if (CmdFailed(terraformcost) || (terraformcost != 0 && !allow_on_slopes))
+ if (CmdFailed(terraformcost) || (terraformcost.GetCost() != 0 && !allow_on_slopes))
return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
- cost += terraformcost;
+ cost.AddCost(terraformcost);
}
if (!replace_bridge) {
@@ -411,7 +411,7 @@
/* try and clear the middle landscape */
ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
if (CmdFailed(ret)) return ret;
- cost += ret;
+ cost.AddCost(ret);
break;
}
@@ -439,7 +439,7 @@
if (IsValidPlayer(_current_player))
bridge_len = CalcBridgeLenCostFactor(bridge_len);
- cost += (int64)bridge_len * _price.build_bridge * b->price >> 8;
+ cost.AddCost((int64)bridge_len * _price.build_bridge * b->price >> 8);
}
return cost;
@@ -452,7 +452,7 @@
* @param p1 railtype or roadtypes. bit 9 set means road tunnel
* @param p2 unused
*/
-int32 CmdBuildTunnel(TileIndex start_tile, uint32 flags, uint32 p1, uint32 p2)
+CommandCost CmdBuildTunnel(TileIndex start_tile, uint32 flags, uint32 p1, uint32 p2)
{
TileIndexDiff delta;
TileIndex end_tile;
@@ -461,8 +461,8 @@
Slope end_tileh;
uint start_z;
uint end_z;
- int32 cost;
- int32 ret;
+ CommandCost cost;
+ CommandCost ret;
_build_tunnel_endtile = 0;
if (!HASBIT(p1, 9)) {
@@ -488,8 +488,15 @@
* for the clearing of the entrance of the tunnel. Assigning it to
* cost before the loop will yield different costs depending on start-
* position, because of increased-cost-by-length: 'cost += cost >> 3' */
- cost = 0;
+
delta = TileOffsByDiagDir(direction);
+ DiagDirection tunnel_in_way_dir;
+ if (OtherAxis(DiagDirToAxis(direction)) == AXIS_X) {
+ tunnel_in_way_dir = (TileX(start_tile) < (MapMaxX() / 2)) ? DIAGDIR_SW : DIAGDIR_NE;
+ } else {
+ tunnel_in_way_dir = (TileY(start_tile) < (MapMaxX() / 2)) ? DIAGDIR_SE : DIAGDIR_NW;
+ }
+
end_tile = start_tile;
for (;;) {
end_tile += delta;
@@ -497,30 +504,40 @@
if (start_z == end_z) break;
- if (!_cheats.crossing_tunnels.value && IsTunnelInWay(end_tile, start_z)) {
+ if (!_cheats.crossing_tunnels.value && IsTunnelInWayDir(end_tile, start_z, tunnel_in_way_dir)) {
return_cmd_error(STR_5003_ANOTHER_TUNNEL_IN_THE_WAY);
}
- cost += _price.build_tunnel;
- cost += cost >> 3; // add a multiplier for longer tunnels
- if (cost >= 400000000) cost = 400000000;
+ cost.AddCost(_price.build_tunnel);
+ cost.AddCost(cost.GetCost() >> 3); // add a multiplier for longer tunnels
}
/* Add the cost of the entrance */
- cost += _price.build_tunnel + ret;
+ cost.AddCost(_price.build_tunnel);
+ cost.AddCost(ret);
/* if the command fails from here on we want the end tile to be highlighted */
_build_tunnel_endtile = end_tile;
/* slope of end tile must be complementary to the slope of the start tile */
if (end_tileh != ComplementSlope(start_tileh)) {
+ /* Some (rail) track bits might be terraformed into the correct direction,
+ * but that would still leave tracks on foundation. Therefor excavation will
+ * always fail for rail tiles. On the other hand, for road tiles it might
+ * succeed when there is only one road bit on the tile, but then that road
+ * bit is removed leaving a clear tile.
+ * This therefor preserves the behaviour that half road tiles are always removable.
+ */
+ if (IsTileType(end_tile, MP_RAILWAY)) return_cmd_error(STR_1008_MUST_REMOVE_RAILROAD_TRACK);
+
ret = DoCommand(end_tile, end_tileh & start_tileh, 0, flags, CMD_TERRAFORM_LAND);
if (CmdFailed(ret)) return_cmd_error(STR_5005_UNABLE_TO_EXCAVATE_LAND);
} else {
ret = DoCommand(end_tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
if (CmdFailed(ret)) return ret;
}
- cost += _price.build_tunnel + ret;
+ cost.AddCost(_price.build_tunnel);
+ cost.AddCost(ret);
if (flags & DC_EXEC) {
if (GB(p1, 9, 1) == TRANSPORT_RAIL) {
@@ -577,7 +594,7 @@
return false;
}
-static int32 DoClearTunnel(TileIndex tile, uint32 flags)
+static CommandCost DoClearTunnel(TileIndex tile, uint32 flags)
{
Town *t = NULL;
TileIndex endtile;
@@ -621,7 +638,7 @@
YapfNotifyTrackLayoutChange(tile, track);
YapfNotifyTrackLayoutChange(endtile, track);
}
- return _price.clear_tunnel * (length + 1);
+ return CommandCost(_price.clear_tunnel * (length + 1));
}
@@ -637,7 +654,7 @@
return false;
}
-static int32 DoClearBridge(TileIndex tile, uint32 flags)
+static CommandCost DoClearBridge(TileIndex tile, uint32 flags)
{
DiagDirection direction;
TileIndexDiff delta;
@@ -694,10 +711,10 @@
YapfNotifyTrackLayoutChange(endtile, track);
}
- return (DistanceManhattan(tile, endtile) + 1) * _price.clear_bridge;
+ return CommandCost((DistanceManhattan(tile, endtile) + 1) * _price.clear_bridge);
}
-static int32 ClearTile_TunnelBridge(TileIndex tile, byte flags)
+static CommandCost ClearTile_TunnelBridge(TileIndex tile, byte flags)
{
if (IsTunnel(tile)) {
if (flags & DC_AUTO) return_cmd_error(STR_5006_MUST_DEMOLISH_TUNNEL_FIRST);
@@ -720,7 +737,7 @@
* @return The cost and state of the operation
* @retval CMD_ERROR An error occured during the operation.
*/
-int32 DoConvertTunnelBridgeRail(TileIndex tile, RailType totype, bool exec)
+CommandCost DoConvertTunnelBridgeRail(TileIndex tile, RailType totype, bool exec)
{
TileIndex endtile;
@@ -748,7 +765,7 @@
YapfNotifyTrackLayoutChange(tile, track);
YapfNotifyTrackLayoutChange(endtile, track);
}
- return (length + 1) * (_price.build_rail / 2);
+ return CommandCost((length + 1) * (_price.build_rail / 2));
} else if (IsBridge(tile) && GetBridgeTransportType(tile) == TRANSPORT_RAIL) {
if (!CheckTileOwnership(tile)) return CMD_ERROR;
@@ -783,7 +800,7 @@
}
}
- return (DistanceManhattan(tile, endtile) + 1) * (_price.build_rail / 2);
+ return CommandCost((DistanceManhattan(tile, endtile) + 1) * (_price.build_rail / 2));
} else {
return CMD_ERROR;
}
@@ -1008,6 +1025,8 @@
}
DrawBridgeMiddle(ti);
+ } else {
+ NOT_REACHED();
}
}