1
0
Fork 0

(svn r11633) -Codechange: merge CheckTunnelEmpty and IsVehicleOnBridge into GetVehicleTunnelBridge

release/0.6
smatz 2007-12-14 23:21:20 +00:00
parent dedb15786c
commit 4b7f8f04a3
4 changed files with 49 additions and 67 deletions

View File

@ -3026,8 +3026,6 @@ reverse_train_direction:
ReverseTrainDirection(v); ReverseTrainDirection(v);
} }
extern TileIndex CheckTunnelBusy(TileIndex tile, uint *length);
/** /**
* Deletes/Clears the last wagon of a crashed train. It takes the engine of the * 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 * 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); DisableTrainCrossing(v->tile);
if ((v->u.rail.track == TRACK_BIT_WORMHOLE && v->vehstatus & VS_HIDDEN)) { // inside a tunnel 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) { switch (v->direction) {
case 1: case 1:

View File

@ -561,34 +561,6 @@ CommandCost CmdBuildTunnel(TileIndex start_tile, uint32 flags, uint32 p1, uint32
return cost; 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) static inline bool CheckAllowRemoveTunnelBridge(TileIndex tile)
{ {
@ -605,14 +577,14 @@ static CommandCost DoClearTunnel(TileIndex tile, uint32 flags)
{ {
Town *t = NULL; Town *t = NULL;
TileIndex endtile; TileIndex endtile;
uint length;
SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION); SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
if (!CheckAllowRemoveTunnelBridge(tile)) return CMD_ERROR; if (!CheckAllowRemoveTunnelBridge(tile)) return CMD_ERROR;
endtile = CheckTunnelBusy(tile, &length); endtile = GetOtherTunnelEnd(tile);
if (endtile == INVALID_TILE) return CMD_ERROR;
if (GetVehicleTunnelBridge(tile, endtile) != NULL) return CMD_ERROR;
_build_tunnel_endtile = endtile; _build_tunnel_endtile = endtile;
@ -645,22 +617,10 @@ static CommandCost DoClearTunnel(TileIndex tile, uint32 flags)
YapfNotifyTrackLayoutChange(tile, track); YapfNotifyTrackLayoutChange(tile, track);
YapfNotifyTrackLayoutChange(endtile, 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) static CommandCost DoClearBridge(TileIndex tile, uint32 flags)
{ {
DiagDirection direction; DiagDirection direction;
@ -673,13 +633,8 @@ static CommandCost DoClearBridge(TileIndex tile, uint32 flags)
if (!CheckAllowRemoveTunnelBridge(tile)) return CMD_ERROR; if (!CheckAllowRemoveTunnelBridge(tile)) return CMD_ERROR;
endtile = GetOtherBridgeEnd(tile); endtile = GetOtherBridgeEnd(tile);
byte bridge_height = GetBridgeHeight(tile);
if (FindVehicleOnTileZ(tile, bridge_height) != NULL || if (GetVehicleTunnelBridge(tile, endtile) != NULL) return CMD_ERROR;
FindVehicleOnTileZ(endtile, bridge_height) != NULL ||
IsVehicleOnBridge(tile, endtile, bridge_height)) {
return CMD_ERROR;
}
direction = GetBridgeRampDirection(tile); direction = GetBridgeRampDirection(tile);
delta = TileOffsByDiagDir(direction); delta = TileOffsByDiagDir(direction);
@ -747,16 +702,12 @@ static CommandCost ClearTile_TunnelBridge(TileIndex tile, byte flags)
CommandCost DoConvertTunnelBridgeRail(TileIndex tile, RailType totype, bool exec) CommandCost DoConvertTunnelBridgeRail(TileIndex tile, RailType totype, bool exec)
{ {
if (IsTunnel(tile) && GetTunnelTransportType(tile) == TRANSPORT_RAIL) { if (IsTunnel(tile) && GetTunnelTransportType(tile) == TRANSPORT_RAIL) {
uint length; TileIndex endtile = GetOtherTunnelEnd(tile);
TileIndex endtile;
/* If not coverting rail <-> el. rail, any vehicle cannot be in tunnel */ /* If not coverting rail <-> el. rail, any vehicle cannot be in tunnel */
if (!IsCompatibleRail(GetRailType(tile), totype)) { if (!IsCompatibleRail(GetRailType(tile), totype) &&
endtile = CheckTunnelBusy(tile, &length); GetVehicleTunnelBridge(tile, endtile) != NULL) {
if (endtile == INVALID_TILE) return CMD_ERROR; return CMD_ERROR;
} else {
endtile = GetOtherTunnelEnd(tile);
length = DistanceManhattan(tile, endtile);
} }
if (exec) { if (exec) {
@ -774,15 +725,12 @@ CommandCost DoConvertTunnelBridgeRail(TileIndex tile, RailType totype, bool exec
VehicleFromPos(endtile, &endtile, UpdateTrainPowerProc); 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) { } else if (IsBridge(tile) && GetBridgeTransportType(tile) == TRANSPORT_RAIL) {
TileIndex endtile = GetOtherBridgeEnd(tile); TileIndex endtile = GetOtherBridgeEnd(tile);
byte bridge_height = GetBridgeHeight(tile);
if (!IsCompatibleRail(GetRailType(tile), totype) && if (!IsCompatibleRail(GetRailType(tile), totype) &&
(FindVehicleOnTileZ(tile, bridge_height) != NULL || GetVehicleTunnelBridge(tile, endtile) != NULL) {
FindVehicleOnTileZ(endtile, bridge_height) != NULL ||
IsVehicleOnBridge(tile, endtile, bridge_height))) {
return CMD_ERROR; return CMD_ERROR;
} }

View File

@ -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); static void UpdateVehiclePosHash(Vehicle* v, int x, int y);
void VehiclePositionChanged(Vehicle *v) void VehiclePositionChanged(Vehicle *v)

View File

@ -610,6 +610,7 @@ uint32 VehicleEnterTile(Vehicle *v, TileIndex tile, int x, int y);
StringID VehicleInTheWayErrMsg(const Vehicle* v); StringID VehicleInTheWayErrMsg(const Vehicle* v);
Vehicle *FindVehicleBetween(TileIndex from, TileIndex to, byte z, bool without_crashed = false); Vehicle *FindVehicleBetween(TileIndex from, TileIndex to, byte z, bool without_crashed = false);
Vehicle *GetVehicleTunnelBridge(TileIndex tile, TileIndex endtile);
bool UpdateSignalsOnSegment(TileIndex tile, DiagDirection direction); bool UpdateSignalsOnSegment(TileIndex tile, DiagDirection direction);
void SetSignalsOnBothDir(TileIndex tile, byte track); void SetSignalsOnBothDir(TileIndex tile, byte track);