src/road_cmd.cpp
branchnoai
changeset 9723 eee46cb39750
parent 9722 ebf0ece7d8f6
child 9724 b39bc69bb2f2
--- a/src/road_cmd.cpp	Fri Nov 23 16:59:30 2007 +0000
+++ b/src/road_cmd.cpp	Wed Jan 09 18:11:12 2008 +0000
@@ -9,31 +9,33 @@
 #include "cmd_helper.h"
 #include "rail_map.h"
 #include "road_map.h"
+#include "road_internal.h"
 #include "sprite.h"
 #include "table/sprites.h"
 #include "table/strings.h"
-#include "strings.h"
-#include "functions.h"
-#include "window.h"
-#include "map.h"
+#include "tile_cmd.h"
 #include "landscape.h"
-#include "tile.h"
 #include "town_map.h"
-#include "vehicle.h"
-#include "viewport.h"
-#include "command.h"
+#include "viewport_func.h"
+#include "command_func.h"
 #include "player.h"
 #include "town.h"
-#include "gfx.h"
-#include "sound.h"
 #include "yapf/yapf.h"
 #include "depot.h"
 #include "newgrf.h"
 #include "station_map.h"
 #include "tunnel_map.h"
 #include "misc/autoptr.hpp"
+#include "variables.h"
 #include "autoslope.h"
 #include "transparency.h"
+#include "tunnelbridge_map.h"
+#include "window_func.h"
+#include "strings_func.h"
+#include "vehicle_func.h"
+#include "vehicle_base.h"
+#include "sound_func.h"
+
 
 #define M(x) (1 << (x))
 /* Level crossings may only be built on these slopes */
@@ -112,8 +114,6 @@
 	 * false if it was a center piece. Affects town ratings drop */
 	bool edge_road;
 
-	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
-
 	RoadType rt = (RoadType)GB(p1, 4, 2);
 	if (!IsValidRoadType(rt)) return CMD_ERROR;
 
@@ -121,16 +121,19 @@
 	switch (GetTileType(tile)) {
 		case MP_ROAD:
 			if (_game_mode != GM_EDITOR && GetRoadOwner(tile, rt) == OWNER_TOWN) t = GetTownByTile(tile);
+			if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR;
 			break;
 
 		case MP_STATION:
 			if (!IsDriveThroughStopTile(tile)) return CMD_ERROR;
+			if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR;
 			break;
 
 		case MP_TUNNELBRIDGE:
-			if ((IsTunnel(tile) && GetTunnelTransportType(tile) != TRANSPORT_ROAD) ||
-					(IsBridge(tile) && GetBridgeTransportType(tile) != TRANSPORT_ROAD)) return CMD_ERROR;
-			break;
+			{
+				if (GetTunnelBridgeTransportType(tile) != TRANSPORT_ROAD) return CMD_ERROR;
+				if (GetVehicleTunnelBridge(tile, GetOtherTunnelBridgeEnd(tile)) != NULL) return CMD_ERROR;
+			} break;
 
 		default:
 			return CMD_ERROR;
@@ -143,8 +146,6 @@
 
 	if (!CheckAllowRemoveRoad(tile, pieces, &edge_road, rt)) return CMD_ERROR;
 
-	if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR;
-
 	/* check if you're allowed to remove the street owned by a town
 	 * removal allowance depends on difficulty setting */
 	if (!CheckforTownRating(flags, t, ROAD_REMOVE)) return CMD_ERROR;
@@ -153,11 +154,11 @@
 		/* If it's the last roadtype, just clear the whole tile */
 		if (rts == RoadTypeToRoadTypes(rt)) return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 
-		CommandCost cost;
+		CommandCost cost(EXPENSES_CONSTRUCTION);
 		if (IsTileType(tile, MP_TUNNELBRIDGE)) {
-			TileIndex other_end = IsTunnel(tile) ? GetOtherTunnelEnd(tile) : GetOtherBridgeEnd(tile);
+			TileIndex other_end = GetOtherTunnelBridgeEnd(tile);
 			/* Pay for *every* tile of the bridge or tunnel */
-			cost.AddCost((DistanceManhattan(IsTunnel(tile) ? GetOtherTunnelEnd(tile) : GetOtherBridgeEnd(tile), tile) + 1) * _price.remove_road);
+			cost.AddCost((DistanceManhattan(other_end, tile) + 1) * _price.remove_road);
 			if (flags & DC_EXEC) {
 				SetRoadTypes(other_end, GetRoadTypes(other_end) & ~RoadTypeToRoadTypes(rt));
 				SetRoadTypes(tile, GetRoadTypes(tile) & ~RoadTypeToRoadTypes(rt));
@@ -166,7 +167,7 @@
 				MarkTileDirtyByTile(tile);
 				MarkTileDirtyByTile(other_end);
 				if (IsBridge(tile)) {
-					TileIndexDiff delta = TileOffsByDiagDir(GetBridgeRampDirection(tile));
+					TileIndexDiff delta = TileOffsByDiagDir(GetTunnelBridgeDirection(tile));
 
 					for (TileIndex t = tile + delta; t != other_end; t += delta) MarkTileDirtyByTile(t);
 				}
@@ -178,7 +179,7 @@
 				MarkTileDirtyByTile(tile);
 			}
 		}
-		return CommandCost(cost);
+		return cost;
 	}
 
 	switch (GetRoadTileType(tile)) {
@@ -198,9 +199,8 @@
 			c &= present;
 			if (c == ROAD_NONE) return CMD_ERROR;
 
+			ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM);
 			if (flags & DC_EXEC) {
-				ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM);
-
 				present ^= c;
 				if (present == ROAD_NONE) {
 					RoadTypes rts = GetRoadTypes(tile) & ComplementRoadTypes(RoadTypeToRoadTypes(rt));
@@ -221,7 +221,7 @@
 					MarkTileDirtyByTile(tile);
 				}
 			}
-			return CommandCost(CountBits(c) * _price.remove_road);
+			return CommandCost(EXPENSES_CONSTRUCTION, CountBits(c) * _price.remove_road);
 		}
 
 		case ROAD_TILE_CROSSING: {
@@ -233,11 +233,11 @@
 			 * we can't draw the crossing without trambits ;) */
 			if (rt == ROADTYPE_ROAD && HasBit(GetRoadTypes(tile), ROADTYPE_TRAM) && ((flags & DC_EXEC) || !HasBit(p1, 6))) return CMD_ERROR;
 
+			if (rt == ROADTYPE_ROAD) {
+				ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM);
+			}
+
 			if (flags & DC_EXEC) {
-				if (rt == ROADTYPE_ROAD) {
-					ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM);
-				}
-
 				RoadTypes rts = GetRoadTypes(tile) & ComplementRoadTypes(RoadTypeToRoadTypes(rt));
 				if (rts == ROADTYPES_NONE) {
 					MakeRailNormal(tile, GetTileOwner(tile), GetCrossingRailBits(tile), GetRailType(tile));
@@ -247,7 +247,7 @@
 				MarkTileDirtyByTile(tile);
 				YapfNotifyTrackLayoutChange(tile, FindFirstTrack(GetTrackBits(tile)));
 			}
-			return CommandCost(_price.remove_road * 2);
+			return CommandCost(EXPENSES_CONSTRUCTION, _price.remove_road * 2);
 		}
 
 		default:
@@ -343,7 +343,7 @@
 		*pieces |= MirrorRoadBits(*pieces);
 
 		if (existing == ROAD_NONE || existing == *pieces) {
-			if (*pieces == ROAD_X || *pieces == ROAD_Y) return _price.terraform;
+			if (*pieces == ROAD_X || *pieces == ROAD_Y) return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
 		}
 		return CMD_ERROR;
 	}
@@ -355,7 +355,7 @@
 	if (_patches.build_on_slopes &&
 			existing == ROAD_NONE && CountBits(*pieces) == 1 &&
 			(_valid_tileh_slopes_road[2][tileh] & *pieces) == ROAD_NONE) {
-		return CommandCost(_price.terraform);
+		return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
 	}
 
 	/* no special foundation */
@@ -367,7 +367,7 @@
 
 	/* foundation is used. Whole tile is leveled up */
 	if ((~_valid_tileh_slopes_road[1][tileh] & road_bits) == ROAD_NONE) {
-		return CommandCost(existing != ROAD_NONE ? (Money)0 : _price.terraform);
+		return CommandCost(EXPENSES_CONSTRUCTION, existing != ROAD_NONE ? (Money)0 : _price.terraform);
 	}
 
 	/* Force straight roads. */
@@ -375,7 +375,7 @@
 
 	/* partly leveled up tile, only if there's no road on that tile */
 	if ((existing == ROAD_NONE || existing == *pieces) && (tileh == SLOPE_W || tileh == SLOPE_S || tileh == SLOPE_E || tileh == SLOPE_N)) {
-		if (*pieces == ROAD_X || *pieces == ROAD_Y) return _price.terraform;
+		if (*pieces == ROAD_X || *pieces == ROAD_Y) return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
 	}
 	return CMD_ERROR;
 }
@@ -390,14 +390,12 @@
  */
 CommandCost CmdBuildRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
-	CommandCost cost;
+	CommandCost cost(EXPENSES_CONSTRUCTION);
 	CommandCost ret;
 	RoadBits existing = ROAD_NONE;
 	RoadBits all_bits = ROAD_NONE;
 	Slope tileh;
 
-	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
-
 	/* Road pieces are max 4 bitset values (NE, NW, SE, SW) and town can only be non-zero
 	 * if a non-player is building the road */
 	if ((IsValidPlayer(_current_player) && p2 != 0) || (_current_player == OWNER_TOWN && !IsValidTownID(p2))) return CMD_ERROR;
@@ -491,7 +489,7 @@
 				MakeRoadCrossing(tile, _current_player, _current_player, _current_player, GetTileOwner(tile), roaddir, GetRailType(tile), RoadTypeToRoadTypes(rt) | ROADTYPES_ROAD, p2);
 				MarkTileDirtyByTile(tile);
 			}
-			return CommandCost(_price.build_road * (rt == ROADTYPE_ROAD ? 2 : 4));
+			return CommandCost(EXPENSES_CONSTRUCTION, _price.build_road * (rt == ROADTYPE_ROAD ? 2 : 4));
 		}
 
 		case MP_STATION:
@@ -502,12 +500,13 @@
 			break;
 
 		case MP_TUNNELBRIDGE:
-			if ((IsTunnel(tile) && GetTunnelTransportType(tile) != TRANSPORT_ROAD) ||
-					(IsBridge(tile) && GetBridgeTransportType(tile) != TRANSPORT_ROAD)) return CMD_ERROR;
-			if (HasBit(GetRoadTypes(tile), rt)) return_cmd_error(STR_1007_ALREADY_BUILT);
-			/* Don't allow "upgrading" the bridge/tunnel when vehicles are already driving on it */
-			if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR;
-			break;
+			{
+				if (GetTunnelBridgeTransportType(tile) != TRANSPORT_ROAD) return CMD_ERROR;
+				if (HasBit(GetRoadTypes(tile), rt)) return_cmd_error(STR_1007_ALREADY_BUILT);
+
+				/* Don't allow "upgrading" the bridge/tunnel when vehicles are already driving on it */
+				if (GetVehicleTunnelBridge(tile, GetOtherTunnelBridgeEnd(tile)) != NULL) return CMD_ERROR;
+			} break;
 
 		default:
 do_clear:;
@@ -535,7 +534,7 @@
 	cost.AddCost(CountBits(pieces) * _price.build_road);
 	if (IsTileType(tile, MP_TUNNELBRIDGE)) {
 		/* Pay for *every* tile of the bridge or tunnel */
-		cost.MultiplyCost(DistanceManhattan(IsTunnel(tile) ? GetOtherTunnelEnd(tile) : GetOtherBridgeEnd(tile), tile));
+		cost.MultiplyCost(DistanceManhattan(GetOtherTunnelBridgeEnd(tile), tile) + 1);
 	}
 
 	if (flags & DC_EXEC) {
@@ -551,7 +550,7 @@
 			} break;
 
 			case MP_TUNNELBRIDGE: {
-				TileIndex other_end = IsTunnel(tile) ? GetOtherTunnelEnd(tile) : GetOtherBridgeEnd(tile);
+				TileIndex other_end = GetOtherTunnelBridgeEnd(tile);
 
 				SetRoadTypes(other_end, GetRoadTypes(other_end) | RoadTypeToRoadTypes(rt));
 				SetRoadTypes(tile, GetRoadTypes(tile) | RoadTypeToRoadTypes(rt));
@@ -560,7 +559,7 @@
 				MarkTileDirtyByTile(other_end);
 				MarkTileDirtyByTile(tile);
 				if (IsBridge(tile)) {
-					TileIndexDiff delta = TileOffsByDiagDir(GetBridgeRampDirection(tile));
+					TileIndexDiff delta = TileOffsByDiagDir(GetTunnelBridgeDirection(tile));
 
 					for (TileIndex t = tile + delta; t != other_end; t += delta) MarkTileDirtyByTile(t);
 				}
@@ -586,30 +585,6 @@
 	return cost;
 }
 
-/**
- * Switches the rail type on a level crossing.
- * @param tile        The tile on which the railtype is to be convert.
- * @param totype      The railtype we want to convert to
- * @param exec        Switches between test and execute mode
- * @return            The cost and state of the operation
- * @retval CMD_ERROR  An error occured during the operation.
- */
-CommandCost DoConvertStreetRail(TileIndex tile, RailType totype, bool exec)
-{
-	/* not a railroad crossing? */
-	if (!IsLevelCrossing(tile)) return CMD_ERROR;
-
-	if (exec) {
-		SetRailType(tile, totype);
-		MarkTileDirtyByTile(tile);
-		YapfNotifyTrackLayoutChange(tile, FindFirstTrack(GetCrossingRailBits(tile)));
-		VehicleFromPos(tile, &tile, UpdateTrainPowerProc);
-	}
-
-	return CommandCost(RailBuildCost(totype) / 2);
-}
-
-
 /** Build a long piece of road.
  * @param end_tile end tile of drag
  * @param flags operation to perform
@@ -624,14 +599,12 @@
 CommandCost CmdBuildLongRoad(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p2)
 {
 	TileIndex start_tile, tile;
-	CommandCost cost, ret;
+	CommandCost ret, cost(EXPENSES_CONSTRUCTION);
 	bool had_bridge = false;
 	bool had_tunnel = false;
 	bool had_success = false;
 	DisallowedRoadDirections drd = DRD_NORTHBOUND;
 
-	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
-
 	if (p1 >= MapSize()) return CMD_ERROR;
 
 	start_tile = p1;
@@ -647,7 +620,7 @@
 		TileIndex t = start_tile;
 		start_tile = end_tile;
 		end_tile = t;
-		p2 ^= IS_INT_INSIDE(p2 & 3, 1, 3) ? 3 : 0;
+		p2 ^= IsInsideMM(p2 & 3, 1, 3) ? 3 : 0;
 		drd = DRD_SOUTHBOUND;
 	}
 
@@ -675,12 +648,12 @@
 			/* Only pay for the upgrade on one side of the bridges and tunnels */
 			if (IsTileType(tile, MP_TUNNELBRIDGE)) {
 				if (IsBridge(tile)) {
-					if ((!had_bridge || GetBridgeRampDirection(tile) == DIAGDIR_SE || GetBridgeRampDirection(tile) == DIAGDIR_SW)) {
+					if ((!had_bridge || GetTunnelBridgeDirection(tile) == DIAGDIR_SE || GetTunnelBridgeDirection(tile) == DIAGDIR_SW)) {
 						cost.AddCost(ret);
 					}
 					had_bridge = true;
 				} else {
-					if ((!had_tunnel || GetTunnelDirection(tile) == DIAGDIR_SE || GetTunnelDirection(tile) == DIAGDIR_SW)) {
+					if ((!had_tunnel || GetTunnelBridgeDirection(tile) == DIAGDIR_SE || GetTunnelBridgeDirection(tile) == DIAGDIR_SW)) {
 						cost.AddCost(ret);
 					}
 					had_tunnel = true;
@@ -711,9 +684,8 @@
 CommandCost CmdRemoveLongRoad(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p2)
 {
 	TileIndex start_tile, tile;
-	CommandCost cost, ret, money;
-
-	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
+	CommandCost ret, cost(EXPENSES_CONSTRUCTION);
+	Money money;
 
 	if (p1 >= MapSize()) return CMD_ERROR;
 
@@ -730,10 +702,10 @@
 		TileIndex t = start_tile;
 		start_tile = end_tile;
 		end_tile = t;
-		p2 ^= IS_INT_INSIDE(p2 & 3, 1, 3) ? 3 : 0;
+		p2 ^= IsInsideMM(p2 & 3, 1, 3) ? 3 : 0;
 	}
 
-	money.AddCost(GetAvailableMoneyForCommand());
+	money = GetAvailableMoneyForCommand();
 	tile = start_tile;
 	/* Start tile is the small number. */
 	for (;;) {
@@ -747,8 +719,8 @@
 			ret = DoCommand(tile, rt << 4 | bits, 0, flags & ~DC_EXEC, CMD_REMOVE_ROAD);
 			if (CmdSucceeded(ret)) {
 				if (flags & DC_EXEC) {
-					money.AddCost(-ret.GetCost());
-					if (money.GetCost() < 0) {
+					money -= ret.GetCost();
+					if (money < 0) {
 						_additional_cash_required = DoCommand(end_tile, start_tile, p2, flags & ~DC_EXEC, CMD_REMOVE_LONG_ROAD).GetCost();
 						return cost;
 					}
@@ -781,8 +753,6 @@
 	CommandCost cost;
 	Slope tileh;
 
-	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
-
 	DiagDirection dir = Extract<DiagDirection, 0>(p1);
 	RoadType rt = (RoadType)GB(p1, 2, 2);
 
@@ -828,7 +798,7 @@
 		delete GetDepotByTile(tile);
 	}
 
-	return CommandCost(_price.remove_road_depot);
+	return CommandCost(EXPENSES_CONSTRUCTION, _price.remove_road_depot);
 }
 
 static CommandCost ClearTile_Road(TileIndex tile, byte flags)
@@ -843,7 +813,7 @@
 			    IsTileOwner(tile, OWNER_TOWN) || !(flags & DC_AUTO)
 				) {
 				RoadTypes rts = GetRoadTypes(tile);
-				CommandCost ret;
+				CommandCost ret(EXPENSES_CONSTRUCTION);
 				for (RoadType rt = ROADTYPE_ROAD; rt < ROADTYPE_END; rt++) {
 					if (HasBit(rts, rt)) {
 						CommandCost tmp_ret = DoCommand(tile, rt << 4 | GetRoadBits(tile, rt), 0, flags, CMD_REMOVE_ROAD);
@@ -858,7 +828,7 @@
 
 		case ROAD_TILE_CROSSING: {
 			RoadTypes rts = GetRoadTypes(tile);
-			CommandCost ret;
+			CommandCost ret(EXPENSES_CONSTRUCTION);
 
 			if (flags & DC_AUTO) return_cmd_error(STR_1801_MUST_REMOVE_ROAD_FIRST);
 
@@ -1242,7 +1212,7 @@
 			if (t->road_build_months != 0 &&
 					(DistanceManhattan(t->xy, tile) < 8 || grp != 0) &&
 					GetRoadTileType(tile) == ROAD_TILE_NORMAL && CountBits(GetAllRoadBits(tile)) > 1 ) {
-				if (GetTileSlope(tile, NULL) == SLOPE_FLAT && EnsureNoVehicleOnGround(tile) && CHANCE16(1, 40)) {
+				if (GetTileSlope(tile, NULL) == SLOPE_FLAT && EnsureNoVehicleOnGround(tile) && Chance16(1, 40)) {
 					StartRoadWorks(tile);
 
 					SndPlayTileFx(SND_21_JACKHAMMER, tile);
@@ -1369,7 +1339,7 @@
 	TRACKDIR_X_SW, TRACKDIR_Y_NW, TRACKDIR_X_NE, TRACKDIR_Y_SE
 };
 
-static uint32 VehicleEnter_Road(Vehicle *v, TileIndex tile, int x, int y)
+static VehicleEnterTileStatus VehicleEnter_Road(Vehicle *v, TileIndex tile, int x, int y)
 {
 	switch (GetRoadTileType(tile)) {
 		case ROAD_TILE_CROSSING:
@@ -1439,11 +1409,11 @@
 	if (_patches.build_on_slopes && AutoslopeEnabled()) {
 		switch (GetRoadTileType(tile)) {
 			case ROAD_TILE_CROSSING:
-				if (!IsSteepSlope(tileh_new) && (GetTileMaxZ(tile) == z_new + GetSlopeMaxZ(tileh_new)) && HasBit(VALID_LEVEL_CROSSING_SLOPES, tileh_new)) return _price.terraform;
+				if (!IsSteepSlope(tileh_new) && (GetTileMaxZ(tile) == z_new + GetSlopeMaxZ(tileh_new)) && HasBit(VALID_LEVEL_CROSSING_SLOPES, tileh_new)) return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
 				break;
 
 			case ROAD_TILE_DEPOT:
-				if (AutoslopeCheckForEntranceEdge(tile, z_new, tileh_new, GetRoadDepotDirection(tile))) return _price.terraform;
+				if (AutoslopeCheckForEntranceEdge(tile, z_new, tileh_new, GetRoadDepotDirection(tile))) return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
 				break;
 
 			case ROAD_TILE_NORMAL: {
@@ -1461,7 +1431,7 @@
 						z_new += ApplyFoundationToSlope(GetRoadFoundation(tileh_new, bits), &tileh_new);
 
 						/* The surface slope must not be changed */
-						if ((z_old == z_new) && (tileh_old == tileh_new)) return _price.terraform;
+						if ((z_old == z_new) && (tileh_old == tileh_new)) return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
 					}
 				}
 				break;