summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/train_cmd.cpp6
-rw-r--r--src/tunnelbridge_cmd.cpp74
-rw-r--r--src/vehicle.cpp35
-rw-r--r--src/vehicle.h1
4 files changed, 49 insertions, 67 deletions
diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp
index 6b71962a1..401e9ab49 100644
--- a/src/train_cmd.cpp
+++ b/src/train_cmd.cpp
@@ -3026,8 +3026,6 @@ reverse_train_direction:
ReverseTrainDirection(v);
}
-extern TileIndex CheckTunnelBusy(TileIndex tile, uint *length);
-
/**
* Deletes/Clears the last wagon of a crashed train. It takes the engine of the
* train, then goes to the last wagon and deletes that. Each call to this function
@@ -3062,9 +3060,9 @@ static void DeleteLastWagon(Vehicle *v)
DisableTrainCrossing(v->tile);
if ((v->u.rail.track == TRACK_BIT_WORMHOLE && v->vehstatus & VS_HIDDEN)) { // inside a tunnel
- TileIndex endtile = CheckTunnelBusy(v->tile, NULL);
+ TileIndex endtile = GetOtherTunnelEnd(v->tile);
- if (endtile == INVALID_TILE) return; // tunnel is busy (error returned)
+ if (GetVehicleTunnelBridge(v->tile, endtile) != NULL) return; // tunnel is busy (error returned)
switch (v->direction) {
case 1:
diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp
index 5c4933b68..008f8a1fa 100644
--- a/src/tunnelbridge_cmd.cpp
+++ b/src/tunnelbridge_cmd.cpp
@@ -561,34 +561,6 @@ CommandCost CmdBuildTunnel(TileIndex start_tile, uint32 flags, uint32 p1, uint32
return cost;
}
-TileIndex CheckTunnelBusy(TileIndex tile, uint *length)
-{
- uint z = GetTileZ(tile);
- DiagDirection dir = GetTunnelDirection(tile);
- TileIndexDiff delta = TileOffsByDiagDir(dir);
- uint len = 0;
- TileIndex starttile = tile;
- Vehicle *v;
-
- do {
- tile += delta;
- len++;
- } while (
- !IsTunnelTile(tile) ||
- ReverseDiagDir(GetTunnelDirection(tile)) != dir ||
- GetTileZ(tile) != z
- );
-
- v = FindVehicleBetween(starttile, tile, z);
- if (v != NULL) {
- _error_message = v->type == VEH_TRAIN ?
- STR_5000_TRAIN_IN_TUNNEL : STR_5001_ROAD_VEHICLE_IN_TUNNEL;
- return INVALID_TILE;
- }
-
- if (length != NULL) *length = len;
- return tile;
-}
static inline bool CheckAllowRemoveTunnelBridge(TileIndex tile)
{
@@ -605,14 +577,14 @@ static CommandCost DoClearTunnel(TileIndex tile, uint32 flags)
{
Town *t = NULL;
TileIndex endtile;
- uint length;
SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
if (!CheckAllowRemoveTunnelBridge(tile)) return CMD_ERROR;
- endtile = CheckTunnelBusy(tile, &length);
- if (endtile == INVALID_TILE) return CMD_ERROR;
+ endtile = GetOtherTunnelEnd(tile);
+
+ if (GetVehicleTunnelBridge(tile, endtile) != NULL) return CMD_ERROR;
_build_tunnel_endtile = endtile;
@@ -645,22 +617,10 @@ static CommandCost DoClearTunnel(TileIndex tile, uint32 flags)
YapfNotifyTrackLayoutChange(tile, track);
YapfNotifyTrackLayoutChange(endtile, track);
}
- return CommandCost(_price.clear_tunnel * (length + 1));
+ return CommandCost(_price.clear_tunnel * (DistanceManhattan(tile, endtile) + 1));
}
-static bool IsVehicleOnBridge(TileIndex starttile, TileIndex endtile, uint z)
-{
- const Vehicle *v;
- FOR_ALL_VEHICLES(v) {
- if ((v->tile == starttile || v->tile == endtile) && v->z_pos == z) {
- _error_message = VehicleInTheWayErrMsg(v);
- return true;
- }
- }
- return false;
-}
-
static CommandCost DoClearBridge(TileIndex tile, uint32 flags)
{
DiagDirection direction;
@@ -673,13 +633,8 @@ static CommandCost DoClearBridge(TileIndex tile, uint32 flags)
if (!CheckAllowRemoveTunnelBridge(tile)) return CMD_ERROR;
endtile = GetOtherBridgeEnd(tile);
- byte bridge_height = GetBridgeHeight(tile);
- if (FindVehicleOnTileZ(tile, bridge_height) != NULL ||
- FindVehicleOnTileZ(endtile, bridge_height) != NULL ||
- IsVehicleOnBridge(tile, endtile, bridge_height)) {
- return CMD_ERROR;
- }
+ if (GetVehicleTunnelBridge(tile, endtile) != NULL) return CMD_ERROR;
direction = GetBridgeRampDirection(tile);
delta = TileOffsByDiagDir(direction);
@@ -747,16 +702,12 @@ static CommandCost ClearTile_TunnelBridge(TileIndex tile, byte flags)
CommandCost DoConvertTunnelBridgeRail(TileIndex tile, RailType totype, bool exec)
{
if (IsTunnel(tile) && GetTunnelTransportType(tile) == TRANSPORT_RAIL) {
- uint length;
- TileIndex endtile;
+ TileIndex endtile = GetOtherTunnelEnd(tile);
/* If not coverting rail <-> el. rail, any vehicle cannot be in tunnel */
- if (!IsCompatibleRail(GetRailType(tile), totype)) {
- endtile = CheckTunnelBusy(tile, &length);
- if (endtile == INVALID_TILE) return CMD_ERROR;
- } else {
- endtile = GetOtherTunnelEnd(tile);
- length = DistanceManhattan(tile, endtile);
+ if (!IsCompatibleRail(GetRailType(tile), totype) &&
+ GetVehicleTunnelBridge(tile, endtile) != NULL) {
+ return CMD_ERROR;
}
if (exec) {
@@ -774,15 +725,12 @@ CommandCost DoConvertTunnelBridgeRail(TileIndex tile, RailType totype, bool exec
VehicleFromPos(endtile, &endtile, UpdateTrainPowerProc);
}
- return CommandCost((length + 1) * RailConvertCost(GetRailType(tile), totype));
+ return CommandCost((DistanceManhattan(tile, endtile) + 1) * RailConvertCost(GetRailType(tile), totype));
} else if (IsBridge(tile) && GetBridgeTransportType(tile) == TRANSPORT_RAIL) {
TileIndex endtile = GetOtherBridgeEnd(tile);
- byte bridge_height = GetBridgeHeight(tile);
if (!IsCompatibleRail(GetRailType(tile), totype) &&
- (FindVehicleOnTileZ(tile, bridge_height) != NULL ||
- FindVehicleOnTileZ(endtile, bridge_height) != NULL ||
- IsVehicleOnBridge(tile, endtile, bridge_height))) {
+ GetVehicleTunnelBridge(tile, endtile) != NULL) {
return CMD_ERROR;
}
diff --git a/src/vehicle.cpp b/src/vehicle.cpp
index 7f4e16d98..693b2e269 100644
--- a/src/vehicle.cpp
+++ b/src/vehicle.cpp
@@ -175,6 +175,41 @@ Vehicle *FindVehicleBetween(TileIndex from, TileIndex to, byte z, bool without_c
}
+/** Struct used for GetVehicleTunnelBridge() */
+struct TunnelBridgeInfo {
+ TileIndex tile; ///< tile
+};
+
+/** Procedure called for every vehicle found in tunnel/bridge in the hash map */
+static void *GetVehicleTunnelBridgeProc(Vehicle *v, void *data)
+{
+ TunnelBridgeInfo *tbi = (TunnelBridgeInfo*)data;
+
+ if (v->tile != tbi->tile || (v->type != VEH_TRAIN && v->type != VEH_ROAD)) return NULL;
+
+ _error_message = VehicleInTheWayErrMsg(v);
+ return v;
+}
+
+/**
+ * Finds vehicle in tunnel / bridge
+ * @param tile first end
+ * @param endtile second end
+ * @return pointer to vehicle found
+ */
+Vehicle *GetVehicleTunnelBridge(TileIndex tile, TileIndex endtile)
+{
+ TunnelBridgeInfo tbi = {tile};
+
+ Vehicle *v = (Vehicle*)VehicleFromPos(tile, &tbi, &GetVehicleTunnelBridgeProc);
+ if (v != NULL) return v;
+
+ tbi.tile = endtile;
+
+ return (Vehicle*)VehicleFromPos(endtile, &tbi, &GetVehicleTunnelBridgeProc);
+}
+
+
static void UpdateVehiclePosHash(Vehicle* v, int x, int y);
void VehiclePositionChanged(Vehicle *v)
diff --git a/src/vehicle.h b/src/vehicle.h
index eb3f3ad4f..ef27294b0 100644
--- a/src/vehicle.h
+++ b/src/vehicle.h
@@ -610,6 +610,7 @@ uint32 VehicleEnterTile(Vehicle *v, TileIndex tile, int x, int y);
StringID VehicleInTheWayErrMsg(const Vehicle* v);
Vehicle *FindVehicleBetween(TileIndex from, TileIndex to, byte z, bool without_crashed = false);
+Vehicle *GetVehicleTunnelBridge(TileIndex tile, TileIndex endtile);
bool UpdateSignalsOnSegment(TileIndex tile, DiagDirection direction);
void SetSignalsOnBothDir(TileIndex tile, byte track);