Enable bridge/tunnel exit signals to be one-way PBS.
Add signal conversion support.
This commit is contained in:
@@ -125,6 +125,7 @@ bool TryReserveRailTrack(TileIndex tile, Track t, bool trigger_stations)
|
|||||||
case MP_TUNNELBRIDGE:
|
case MP_TUNNELBRIDGE:
|
||||||
if (GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL && !GetTunnelBridgeReservationTrackBits(tile)) {
|
if (GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL && !GetTunnelBridgeReservationTrackBits(tile)) {
|
||||||
SetTunnelBridgeReservation(tile, true);
|
SetTunnelBridgeReservation(tile, true);
|
||||||
|
if (IsTunnelBridgeExit(tile) && IsTunnelBridgePBS(tile)) SetTunnelBridgeExitGreen(tile, true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -177,7 +178,10 @@ void UnreserveRailTrack(TileIndex tile, Track t)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case MP_TUNNELBRIDGE:
|
case MP_TUNNELBRIDGE:
|
||||||
if (GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL) SetTunnelBridgeReservation(tile, false);
|
if (GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL) {
|
||||||
|
SetTunnelBridgeReservation(tile, false);
|
||||||
|
if (IsTunnelBridgeExit(tile) && IsTunnelBridgePBS(tile)) SetTunnelBridgeExitGreen(tile, false);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@@ -1057,12 +1057,12 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1,
|
|||||||
TileIndex tile_exit = GetOtherTunnelBridgeEnd(tile);
|
TileIndex tile_exit = GetOtherTunnelBridgeEnd(tile);
|
||||||
cost = CommandCost();
|
cost = CommandCost();
|
||||||
bool flip_variant = false;
|
bool flip_variant = false;
|
||||||
|
bool is_pbs = (sigtype == SIGTYPE_PBS) || (sigtype == SIGTYPE_PBS_ONEWAY);
|
||||||
if (!HasWormholeSignals(tile)) { // toggle signal zero costs.
|
if (!HasWormholeSignals(tile)) { // toggle signal zero costs.
|
||||||
if (convert_signal) return_cmd_error(STR_ERROR_THERE_ARE_NO_SIGNALS);
|
if (convert_signal) return_cmd_error(STR_ERROR_THERE_ARE_NO_SIGNALS);
|
||||||
if (p2 != 12) cost = CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_SIGNALS] * ((GetTunnelBridgeLength(tile, tile_exit) + 4) >> 2)); // minimal 1
|
if (p2 != 12) cost = CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_SIGNALS] * ((GetTunnelBridgeLength(tile, tile_exit) + 4) >> 2)); // minimal 1
|
||||||
} else {
|
} else {
|
||||||
if (HasBit(p1, 17)) return CommandCost();
|
if (HasBit(p1, 17)) return CommandCost();
|
||||||
if (ctrl_pressed && !convert_signal) return CommandCost();
|
|
||||||
if ((p2 != 0 && (sigvar == SIG_SEMAPHORE) != IsTunnelBridgeSemaphore(tile)) ||
|
if ((p2 != 0 && (sigvar == SIG_SEMAPHORE) != IsTunnelBridgeSemaphore(tile)) ||
|
||||||
(convert_signal && (ctrl_pressed || (sigvar == SIG_SEMAPHORE) != IsTunnelBridgeSemaphore(tile)))) {
|
(convert_signal && (ctrl_pressed || (sigvar == SIG_SEMAPHORE) != IsTunnelBridgeSemaphore(tile)))) {
|
||||||
flip_variant = true;
|
flip_variant = true;
|
||||||
@@ -1075,8 +1075,15 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1,
|
|||||||
if (convert_signal) {
|
if (convert_signal) {
|
||||||
if (flip_variant) {
|
if (flip_variant) {
|
||||||
SetTunnelBridgeSemaphore(tile, !IsTunnelBridgeSemaphore(tile));
|
SetTunnelBridgeSemaphore(tile, !IsTunnelBridgeSemaphore(tile));
|
||||||
SetTunnelBridgeSemaphore(tile_exit, !IsTunnelBridgeSemaphore(tile_exit));
|
SetTunnelBridgeSemaphore(tile_exit, IsTunnelBridgeSemaphore(tile));
|
||||||
}
|
}
|
||||||
|
if (!ctrl_pressed) {
|
||||||
|
SetTunnelBridgePBS(tile, is_pbs);
|
||||||
|
SetTunnelBridgePBS(tile_exit, is_pbs);
|
||||||
|
}
|
||||||
|
} else if (ctrl_pressed) {
|
||||||
|
SetTunnelBridgePBS(tile, !IsTunnelBridgePBS(tile));
|
||||||
|
SetTunnelBridgePBS(tile_exit, IsTunnelBridgePBS(tile));
|
||||||
} else {
|
} else {
|
||||||
if (IsTunnelBridgeEntrance(tile)) {
|
if (IsTunnelBridgeEntrance(tile)) {
|
||||||
ClrBitTunnelBridgeSignal(tile);
|
ClrBitTunnelBridgeSignal(tile);
|
||||||
@@ -1113,7 +1120,11 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1,
|
|||||||
}
|
}
|
||||||
SetTunnelBridgeSemaphore(tile, sigvar == SIG_SEMAPHORE);
|
SetTunnelBridgeSemaphore(tile, sigvar == SIG_SEMAPHORE);
|
||||||
SetTunnelBridgeSemaphore(tile_exit, sigvar == SIG_SEMAPHORE);
|
SetTunnelBridgeSemaphore(tile_exit, sigvar == SIG_SEMAPHORE);
|
||||||
|
SetTunnelBridgePBS(tile, is_pbs);
|
||||||
|
SetTunnelBridgePBS(tile_exit, is_pbs);
|
||||||
}
|
}
|
||||||
|
if (IsTunnelBridgeExit(tile) && IsTunnelBridgePBS(tile) && !HasTunnelBridgeReservation(tile)) SetTunnelBridgeExitGreen(tile, false);
|
||||||
|
if (IsTunnelBridgeExit(tile_exit) && IsTunnelBridgePBS(tile_exit) && !HasTunnelBridgeReservation(tile_exit)) SetTunnelBridgeExitGreen(tile_exit, false);
|
||||||
MarkBridgeOrTunnelDirty(tile);
|
MarkBridgeOrTunnelDirty(tile);
|
||||||
AddSideToSignalBuffer(tile, INVALID_DIAGDIR, GetTileOwner(tile));
|
AddSideToSignalBuffer(tile, INVALID_DIAGDIR, GetTileOwner(tile));
|
||||||
AddSideToSignalBuffer(tile_exit, INVALID_DIAGDIR, GetTileOwner(tile));
|
AddSideToSignalBuffer(tile_exit, INVALID_DIAGDIR, GetTileOwner(tile));
|
||||||
|
@@ -398,8 +398,12 @@ static SigFlags ExploreSegment(Owner owner)
|
|||||||
tile += TileOffsByDiagDir(exitdir); // just skip to next tile
|
tile += TileOffsByDiagDir(exitdir); // just skip to next tile
|
||||||
} else { // NOT incoming from the wormhole!
|
} else { // NOT incoming from the wormhole!
|
||||||
if (ReverseDiagDir(enterdir) != dir) continue;
|
if (ReverseDiagDir(enterdir) != dir) continue;
|
||||||
if (IsTunnelBridgeExit(tile) && !_tbuset.Add(tile, INVALID_TRACKDIR)) {
|
if (IsTunnelBridgeExit(tile)) {
|
||||||
return flags | SF_FULL;
|
if (IsTunnelBridgePBS(tile)) {
|
||||||
|
flags |= SF_PBS;
|
||||||
|
} else if (!_tbuset.Add(tile, INVALID_TRACKDIR)) {
|
||||||
|
return flags | SF_FULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!(flags & SF_TRAIN)) {
|
if (!(flags & SF_TRAIN)) {
|
||||||
if (HasVehicleOnPos(tile, &tile, &TrainInWormholeTileEnum)) flags |= SF_TRAIN;
|
if (HasVehicleOnPos(tile, &tile, &TrainInWormholeTileEnum)) flags |= SF_TRAIN;
|
||||||
@@ -450,6 +454,7 @@ static void UpdateSignalsAroundSegment(SigFlags flags)
|
|||||||
|
|
||||||
while (_tbuset.Get(&tile, &trackdir)) {
|
while (_tbuset.Get(&tile, &trackdir)) {
|
||||||
if (IsTileType(tile, MP_TUNNELBRIDGE) && IsTunnelBridgeExit(tile)) {
|
if (IsTileType(tile, MP_TUNNELBRIDGE) && IsTunnelBridgeExit(tile)) {
|
||||||
|
if (IsTunnelBridgePBS(tile)) continue;
|
||||||
bool old_state = IsTunnelBridgeExitGreen(tile);
|
bool old_state = IsTunnelBridgeExitGreen(tile);
|
||||||
bool new_state = !(flags & SF_TRAIN);
|
bool new_state = !(flags & SF_TRAIN);
|
||||||
if (old_state != new_state) {
|
if (old_state != new_state) {
|
||||||
|
@@ -2244,6 +2244,12 @@ static void HandleLastTunnelBridgeSignals(TileIndex tile, TileIndex end, DiagDir
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void UnreserveBridgeTunnelTile(TileIndex tile)
|
||||||
|
{
|
||||||
|
SetTunnelBridgeReservation(tile, false);
|
||||||
|
if (IsTunnelBridgeExit(tile) && IsTunnelBridgePBS(tile)) SetTunnelBridgeExitGreen(tile, false);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear the reservation of \a tile that was just left by a wagon on \a track_dir.
|
* Clear the reservation of \a tile that was just left by a wagon on \a track_dir.
|
||||||
* @param v %Train owning the reservation.
|
* @param v %Train owning the reservation.
|
||||||
@@ -2261,15 +2267,15 @@ static void ClearPathReservation(const Train *v, TileIndex tile, Trackdir track_
|
|||||||
|
|
||||||
bool free = TunnelBridgeIsFree(tile, end, v).Succeeded();
|
bool free = TunnelBridgeIsFree(tile, end, v).Succeeded();
|
||||||
if (HasWormholeSignals(tile)) {
|
if (HasWormholeSignals(tile)) {
|
||||||
SetTunnelBridgeReservation(tile, false);
|
UnreserveBridgeTunnelTile(tile);
|
||||||
HandleLastTunnelBridgeSignals(tile, end, dir, free);
|
HandleLastTunnelBridgeSignals(tile, end, dir, free);
|
||||||
if (_settings_client.gui.show_track_reservation) {
|
if (_settings_client.gui.show_track_reservation) {
|
||||||
MarkTileDirtyByTile(tile);
|
MarkTileDirtyByTile(tile);
|
||||||
}
|
}
|
||||||
} else if (free) {
|
} else if (free) {
|
||||||
/* Free the reservation only if no other train is on the tiles. */
|
/* Free the reservation only if no other train is on the tiles. */
|
||||||
SetTunnelBridgeReservation(tile, false);
|
UnreserveBridgeTunnelTile(tile);
|
||||||
SetTunnelBridgeReservation(end, false);
|
UnreserveBridgeTunnelTile(end);
|
||||||
|
|
||||||
if (_settings_client.gui.show_track_reservation) {
|
if (_settings_client.gui.show_track_reservation) {
|
||||||
if (IsBridge(tile)) {
|
if (IsBridge(tile)) {
|
||||||
@@ -2282,7 +2288,7 @@ static void ClearPathReservation(const Train *v, TileIndex tile, Trackdir track_
|
|||||||
}
|
}
|
||||||
} else if (GetTunnelBridgeDirection(tile) == dir && HasWormholeSignals(tile)) {
|
} else if (GetTunnelBridgeDirection(tile) == dir && HasWormholeSignals(tile)) {
|
||||||
/* cancelling reservation of entry ramp, due to reverse */
|
/* cancelling reservation of entry ramp, due to reverse */
|
||||||
SetTunnelBridgeReservation(tile, false);
|
UnreserveBridgeTunnelTile(tile);
|
||||||
if (_settings_client.gui.show_track_reservation) {
|
if (_settings_client.gui.show_track_reservation) {
|
||||||
MarkTileDirtyByTile(tile);
|
MarkTileDirtyByTile(tile);
|
||||||
}
|
}
|
||||||
@@ -3012,7 +3018,7 @@ uint Train::Crash(bool flooded)
|
|||||||
if (IsTileType(v->tile, MP_TUNNELBRIDGE)) {
|
if (IsTileType(v->tile, MP_TUNNELBRIDGE)) {
|
||||||
/* ClearPathReservation will not free the wormhole exit
|
/* ClearPathReservation will not free the wormhole exit
|
||||||
* if the train has just entered the wormhole. */
|
* if the train has just entered the wormhole. */
|
||||||
SetTunnelBridgeReservation(GetOtherTunnelBridgeEnd(v->tile), false);
|
UnreserveBridgeTunnelTile(GetOtherTunnelBridgeEnd(v->tile));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3229,7 +3235,7 @@ static bool CheckTrainStayInWormHole(Train *t, TileIndex tile)
|
|||||||
ToggleBit(t->flags, VRF_REVERSING);
|
ToggleBit(t->flags, VRF_REVERSING);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
SigSegState seg_state = _settings_game.pf.reserve_paths ? SIGSEG_PBS : UpdateSignalsOnSegment(tile, INVALID_DIAGDIR, t->owner);
|
SigSegState seg_state = (_settings_game.pf.reserve_paths || IsTunnelBridgePBS(tile)) ? SIGSEG_PBS : UpdateSignalsOnSegment(tile, INVALID_DIAGDIR, t->owner);
|
||||||
if (seg_state == SIGSEG_FULL || (seg_state == SIGSEG_PBS && !CheckTrainStayInWormHolePathReserve(t, tile))) {
|
if (seg_state == SIGSEG_FULL || (seg_state == SIGSEG_PBS && !CheckTrainStayInWormHolePathReserve(t, tile))) {
|
||||||
t->vehstatus |= VS_TRAIN_SLOWING;
|
t->vehstatus |= VS_TRAIN_SLOWING;
|
||||||
t->cur_speed = 0;
|
t->cur_speed = 0;
|
||||||
@@ -3558,7 +3564,7 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
|
|||||||
v->x_pos = gp.x;
|
v->x_pos = gp.x;
|
||||||
v->y_pos = gp.y;
|
v->y_pos = gp.y;
|
||||||
UpdateSignalsOnSegment(old_tile, INVALID_DIAGDIR, v->owner);
|
UpdateSignalsOnSegment(old_tile, INVALID_DIAGDIR, v->owner);
|
||||||
SetTunnelBridgeReservation(old_tile, false);
|
UnreserveBridgeTunnelTile(old_tile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (distance == 0) v->load_unload_ticks++;
|
if (distance == 0) v->load_unload_ticks++;
|
||||||
|
@@ -1164,12 +1164,15 @@ static void DrawTunnelBridgeRampSignal(const TileInfo *ti)
|
|||||||
case DIAGDIR_NW: position = 3; break;
|
case DIAGDIR_NW: position = 3; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SignalType type = SIGTYPE_NORMAL;
|
||||||
|
|
||||||
bool is_green;
|
bool is_green;
|
||||||
bool show_exit;
|
bool show_exit;
|
||||||
if (IsTunnelBridgeExit(ti->tile)) {
|
if (IsTunnelBridgeExit(ti->tile)) {
|
||||||
is_green = IsTunnelBridgeExitGreen(ti->tile);
|
is_green = IsTunnelBridgeExitGreen(ti->tile);
|
||||||
show_exit = true;
|
show_exit = true;
|
||||||
position ^= 1;
|
position ^= 1;
|
||||||
|
if (IsTunnelBridgePBS(ti->tile)) type = SIGTYPE_PBS_ONEWAY;
|
||||||
} else {
|
} else {
|
||||||
is_green = IsTunnelBridgeWithSignGreen(ti->tile);
|
is_green = IsTunnelBridgeWithSignGreen(ti->tile);
|
||||||
show_exit = false;
|
show_exit = false;
|
||||||
@@ -1186,19 +1189,19 @@ static void DrawTunnelBridgeRampSignal(const TileInfo *ti)
|
|||||||
SignalVariant variant = IsTunnelBridgeSemaphore(ti->tile) ? SIG_SEMAPHORE : SIG_ELECTRIC;
|
SignalVariant variant = IsTunnelBridgeSemaphore(ti->tile) ? SIG_SEMAPHORE : SIG_ELECTRIC;
|
||||||
|
|
||||||
SpriteID sprite;
|
SpriteID sprite;
|
||||||
if (variant == SIG_ELECTRIC) {
|
if (variant == SIG_ELECTRIC && type == SIGTYPE_NORMAL) {
|
||||||
/* Normal electric signals are picked from original sprites. */
|
/* Normal electric signals are picked from original sprites. */
|
||||||
sprite = SPR_ORIGINAL_SIGNALS_BASE + ((position << 1) + is_green);
|
sprite = SPR_ORIGINAL_SIGNALS_BASE + ((position << 1) + is_green);
|
||||||
} else {
|
} else {
|
||||||
/* All other signals are picked from add on sprites. */
|
/* All other signals are picked from add on sprites. */
|
||||||
sprite = SPR_SIGNALS_BASE + ((SIGTYPE_NORMAL - 1) * 16 + variant * 64 + (position << 1) + is_green);
|
sprite = SPR_SIGNALS_BASE + ((type - 1) * 16 + variant * 64 + (position << 1) + is_green) + (type > SIGTYPE_LAST_NOPBS ? 64 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
AddSortableSpriteToDraw(sprite, PAL_NONE, x, y, 1, 1, TILE_HEIGHT, z, false, 0, 0, BB_Z_SEPARATOR);
|
AddSortableSpriteToDraw(sprite, PAL_NONE, x, y, 1, 1, TILE_HEIGHT, z, false, 0, 0, BB_Z_SEPARATOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draws a signal on tunnel / bridge entrance tile. */
|
/* Draws a signal on tunnel / bridge entrance tile. */
|
||||||
static void DrawBrigeSignalOnMiddelPart(const TileInfo *ti, TileIndex bridge_start_tile, uint z)
|
static void DrawBrigeSignalOnMiddlePart(const TileInfo *ti, TileIndex bridge_start_tile, uint z)
|
||||||
{
|
{
|
||||||
|
|
||||||
uint bridge_signal_position = 0;
|
uint bridge_signal_position = 0;
|
||||||
@@ -1628,7 +1631,7 @@ void DrawBridgeMiddle(const TileInfo *ti)
|
|||||||
DrawCatenaryOnBridge(ti);
|
DrawCatenaryOnBridge(ti);
|
||||||
}
|
}
|
||||||
if (HasWormholeSignals(rampsouth)) {
|
if (HasWormholeSignals(rampsouth)) {
|
||||||
IsTunnelBridgeExit(rampsouth) ? DrawBrigeSignalOnMiddelPart(ti, rampnorth, z): DrawBrigeSignalOnMiddelPart(ti, rampsouth, z);
|
IsTunnelBridgeExit(rampsouth) ? DrawBrigeSignalOnMiddlePart(ti, rampnorth, z): DrawBrigeSignalOnMiddlePart(ti, rampsouth, z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -237,4 +237,16 @@ static inline void SetTunnelBridgeSemaphore(TileIndex t, bool is_semaphore)
|
|||||||
SB(_me[t].m6, 1, 1, is_semaphore ? 1 : 0);
|
SB(_me[t].m6, 1, 1, is_semaphore ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool IsTunnelBridgePBS(TileIndex t)
|
||||||
|
{
|
||||||
|
assert(IsTileType(t, MP_TUNNELBRIDGE) && HasWormholeSignals(t));
|
||||||
|
return HasBit(_me[t].m6, 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void SetTunnelBridgePBS(TileIndex t, bool is_pbs)
|
||||||
|
{
|
||||||
|
assert(IsTileType(t, MP_TUNNELBRIDGE) && HasWormholeSignals(t));
|
||||||
|
SB(_me[t].m6, 6, 1, is_pbs ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* TUNNELBRIDGE_MAP_H */
|
#endif /* TUNNELBRIDGE_MAP_H */
|
||||||
|
Reference in New Issue
Block a user