Merge branch 'signal_tunnels_bridges' into jgrpp
# Conflicts: # src/pbs.cpp # src/saveload/extended_ver_sl.cpp # src/settings_gui.cpp # src/settings_type.h # src/signal.cpp # src/table/settings.ini # src/train_cmd.cpp # src/tunnelbridge.h
This commit is contained in:
@@ -1607,12 +1607,18 @@
|
||||
<td><tt>2</tt> </td>
|
||||
<td>signal simulation exit (bit 6 set)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><tt>3</tt> </td>
|
||||
<td>signal simulation bidirectional entrance and exit (bits 5 and 6 set)</td>
|
||||
</tr>
|
||||
</table>
|
||||
If signal simulation entrance or exit:
|
||||
<ul>
|
||||
<li>m6 bit 7: set = exit signal shows green, clear = exit signal shows red</li>
|
||||
<li>m6 bit 6: set = PBS signals, clear = block signals</li>
|
||||
<li>m6 bit 1: set = semaphore signals, clear = light signals</li>
|
||||
<li>m6 bit 0: set = signal shows green, clear = signal shows red</li>
|
||||
<li>m6 bit 0: set = entrance signal shows green, clear = entrance signal shows red</li>
|
||||
<li>m2 bit 15: for bridge entrances only: storage for visual red/green state of signals starting from 15 is allocated outside the map array</li>
|
||||
<li>m2 bits 14..0: for bridge entrances only: for signals 0..14 on bridge, signal is visually red if corresponding bit in 0..14 is set</li>
|
||||
</ul>
|
||||
|
@@ -337,7 +337,7 @@ the array so you can quickly see what is used and what is not.
|
||||
<td class="bits">XXXX XXXX</td>
|
||||
<td class="bits"><span class="free">OOOO OOOO</span></td>
|
||||
<td class="bits">X<span class="used_p">PP</span>X XXXX</td>
|
||||
<td class="bits"><span class="free">O</span><span class="used_p">P</span><span class="free">OO OO</span><span class="used_p">PP</span></td>
|
||||
<td class="bits"><span class="used_p">PP</span><span class="free">OO OO</span><span class="used_p">PP</span></td>
|
||||
<td class="bits">XXXX XXXX</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@@ -1328,6 +1328,9 @@ STR_CONFIG_SETTING_SHOW_ADV_LOADING_MODE_FEATURES_HELPTEXT :Show advanced l
|
||||
STR_CONFIG_SETTING_DISABLE_TOP_VEH_LIST_MASS_ACTIONS :Disable mass action buttons for top-level vehicle lists
|
||||
STR_CONFIG_SETTING_DISABLE_TOP_VEH_LIST_MASS_ACTIONS_HELPTEXT :This disables depot/service and start/stop buttons for all vehicle and all ungrouped vehicle lists. This is intended to help avoid the negative impact of accidentally pressing one of these buttons.
|
||||
|
||||
STR_CONFIG_SETTING_ADV_SIG_BRIDGE_TUN_MODES :Enable signals on bridges/tunnels advanced modes: {STRING2}
|
||||
STR_CONFIG_SETTING_ADV_SIG_BRIDGE_TUN_MODES_HELPTEXT :Enables use of advanced modes of signal simulation on bridges and tunnels. When disabled, bridges/tunnels which are not already in an advanced mode cannot be changed to an advanced mode, however other players may choose to enable this setting and use an advanced mode.
|
||||
|
||||
STR_CONFIG_SETTING_LANDSCAPE :Landscape: {STRING2}
|
||||
STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :Landscapes define basic gameplay scenarios with different cargos and town growth requirements. NewGRF and Game Scripts allow finer control though
|
||||
STR_CONFIG_SETTING_LAND_GENERATOR :Land generator: {STRING2}
|
||||
|
@@ -942,7 +942,7 @@ static void NPFFollowTrack(AyStar *aystar, OpenListNode *current)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (IsTileType(dst_tile, MP_TUNNELBRIDGE) && IsTunnelBridgeSignalSimulationExit(dst_tile) && DiagDirToDiagTrackdir(GetTunnelBridgeDirection(dst_tile)) == dst_trackdir) {
|
||||
if (IsTileType(dst_tile, MP_TUNNELBRIDGE) && IsTunnelBridgeSignalSimulationExitOnly(dst_tile) && DiagDirToDiagTrackdir(GetTunnelBridgeDirection(dst_tile)) == dst_trackdir) {
|
||||
/* Entering a signalled bridge/tunnel from the wrong side, equivalent to encountering a one-way signal from the wrong side */
|
||||
break;
|
||||
}
|
||||
|
@@ -378,7 +378,7 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
if (IsTileType(tile, MP_TUNNELBRIDGE) && IsTunnelBridgeSignalSimulationExit(tile) && DiagDirToDiagTrackdir(GetTunnelBridgeDirection(tile)) == trackdir) {
|
||||
if (IsTileType(tile, MP_TUNNELBRIDGE) && IsTunnelBridgeSignalSimulationExitOnly(tile) && DiagDirToDiagTrackdir(GetTunnelBridgeDirection(tile)) == trackdir) {
|
||||
/* Entering a signalled bridge/tunnel from the wrong side, equivalent to encountering a one-way signal from the wrong side */
|
||||
n.m_segment->m_end_segment_reason |= ESRB_DEAD_END;
|
||||
}
|
||||
|
19
src/pbs.cpp
19
src/pbs.cpp
@@ -155,7 +155,6 @@ bool TryReserveRailTrack(TileIndex tile, Track t, bool trigger_stations)
|
||||
case MP_TUNNELBRIDGE:
|
||||
if (GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL && !GetTunnelBridgeReservationTrackBits(tile)) {
|
||||
SetTunnelBridgeReservation(tile, true);
|
||||
if (IsTunnelBridgeSignalSimulationExit(tile) && IsTunnelBridgePBS(tile)) SetTunnelBridgeSignalState(tile, SIGNAL_STATE_GREEN);
|
||||
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
|
||||
return true;
|
||||
}
|
||||
@@ -225,7 +224,7 @@ void UnreserveRailTrack(TileIndex tile, Track t)
|
||||
case MP_TUNNELBRIDGE:
|
||||
if (GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL) {
|
||||
SetTunnelBridgeReservation(tile, false);
|
||||
if (IsTunnelBridgeSignalSimulationExit(tile) && IsTunnelBridgePBS(tile)) SetTunnelBridgeSignalState(tile, SIGNAL_STATE_RED);
|
||||
if (IsTunnelBridgeSignalSimulationExit(tile) && IsTunnelBridgePBS(tile)) SetTunnelBridgeExitSignalState(tile, SIGNAL_STATE_RED);
|
||||
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
|
||||
}
|
||||
break;
|
||||
@@ -534,7 +533,7 @@ bool IsSafeWaitingPosition(const Train *v, TileIndex tile, Trackdir trackdir, bo
|
||||
return include_line_end;
|
||||
}
|
||||
if (IsTileType(ft.m_new_tile, MP_TUNNELBRIDGE) && GetTunnelBridgeTransportType(ft.m_new_tile) == TRANSPORT_RAIL &&
|
||||
IsTunnelBridgeSignalSimulationExit(ft.m_new_tile) && IsTunnelBridgePBS(ft.m_new_tile)) {
|
||||
IsTunnelBridgeSignalSimulationExitOnly(ft.m_new_tile) && IsTunnelBridgePBS(ft.m_new_tile)) {
|
||||
return include_line_end;
|
||||
}
|
||||
}
|
||||
@@ -562,7 +561,19 @@ bool IsWaitingPositionFree(const Train *v, TileIndex tile, Trackdir trackdir, bo
|
||||
/* Not reserved and depot or not a pbs signal -> free. */
|
||||
if (IsRailDepotTile(tile)) return true;
|
||||
if (IsTileType(tile, MP_RAILWAY) && HasSignalOnTrackdir(tile, trackdir) && !IsPbsSignal(GetSignalType(tile, track))) return true;
|
||||
if (IsTileType(tile, MP_TUNNELBRIDGE) && GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL && IsTunnelBridgeSignalSimulationEntrance(tile)) return true;
|
||||
if (IsTileType(tile, MP_TUNNELBRIDGE) && GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL && IsTunnelBridgeSignalSimulationEntrance(tile)) {
|
||||
if (IsTunnelBridgeSignalSimulationBidirectional(tile)) {
|
||||
TileIndex other_end = GetOtherTunnelBridgeEnd(tile);
|
||||
if (HasTunnelBridgeReservation(other_end) && GetTunnelBridgeExitSignalState(other_end) == SIGNAL_STATE_RED) return false;
|
||||
Direction dir = DiagDirToDir(GetTunnelBridgeDirection(other_end));
|
||||
if (HasVehicleOnPos(other_end, &dir, [](Vehicle *v, void *data) -> Vehicle * {
|
||||
if (v->type != VEH_TRAIN) return nullptr;
|
||||
if (v->direction != *((Direction *) data)) return nullptr;
|
||||
return v;
|
||||
})) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Check the next tile, if it's a PBS signal, it has to be free as well. */
|
||||
CFollowTrackRail ft(v, GetRailTypeInfo(v->railtype)->compatible_railtypes);
|
||||
|
@@ -1045,7 +1045,7 @@ static void ClearBridgeTunnelSignalSimulation(TileIndex entrance, TileIndex exit
|
||||
static void SetupBridgeTunnelSignalSimulation(TileIndex entrance, TileIndex exit)
|
||||
{
|
||||
SetTunnelBridgeSignalSimulationEntrance(entrance);
|
||||
SetTunnelBridgeSignalState(entrance, SIGNAL_STATE_GREEN);
|
||||
SetTunnelBridgeEntranceSignalState(entrance, SIGNAL_STATE_GREEN);
|
||||
SetTunnelBridgeSignalSimulationExit(exit);
|
||||
}
|
||||
|
||||
@@ -1064,6 +1064,7 @@ static void SetupBridgeTunnelSignalSimulation(TileIndex entrance, TileIndex exit
|
||||
* - p1 = (bit 9-14)- cycle through which signal set?
|
||||
* - p1 = (bit 15-16)-cycle the signal direction this many times
|
||||
* - p1 = (bit 17) - 1 = don't modify an existing signal but don't fail either, 0 = always set new signal type
|
||||
* - p1 = (bit 18) - permit creation of/conversion to bidirectionally signalled bridges/tunnels
|
||||
* @param p2 used for CmdBuildManySignals() to copy direction of first signal
|
||||
* @param text unused
|
||||
* @return the cost of this operation or an error
|
||||
@@ -1099,22 +1100,47 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1,
|
||||
CommandCost cost;
|
||||
/* handle signals simulation on tunnel/bridge. */
|
||||
if (IsTileType(tile, MP_TUNNELBRIDGE)) {
|
||||
bool bidirectional = HasBit(p1, 18) && (sigtype == SIGTYPE_PBS);
|
||||
TileIndex tile_exit = GetOtherTunnelBridgeEnd(tile);
|
||||
cost = CommandCost();
|
||||
bool flip_variant = false;
|
||||
bool is_pbs = (sigtype == SIGTYPE_PBS) || (sigtype == SIGTYPE_PBS_ONEWAY);
|
||||
if (!IsTunnelBridgeWithSignalSimulation(tile)) { // toggle signal zero costs.
|
||||
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) * (bidirectional ? 2 : 1)); // minimal 1
|
||||
} else {
|
||||
if (HasBit(p1, 17)) return CommandCost();
|
||||
bool is_bidi = IsTunnelBridgeSignalSimulationBidirectional(tile);
|
||||
bool will_be_bidi = is_bidi;
|
||||
if (p2 == 0) {
|
||||
if (convert_signal) {
|
||||
will_be_bidi = bidirectional && !ctrl_pressed;
|
||||
} else if (ctrl_pressed) {
|
||||
will_be_bidi = false;
|
||||
}
|
||||
} else if (!is_pbs) {
|
||||
will_be_bidi = false;
|
||||
}
|
||||
if ((p2 != 0 && (sigvar == SIG_SEMAPHORE) != IsTunnelBridgeSemaphore(tile)) ||
|
||||
(convert_signal && (ctrl_pressed || (sigvar == SIG_SEMAPHORE) != IsTunnelBridgeSemaphore(tile)))) {
|
||||
flip_variant = true;
|
||||
cost = CommandCost(EXPENSES_CONSTRUCTION, (_price[PR_BUILD_SIGNALS] + _price[PR_CLEAR_SIGNALS]) *
|
||||
cost = CommandCost(EXPENSES_CONSTRUCTION, ((_price[PR_BUILD_SIGNALS] * (will_be_bidi ? 2 : 1)) + (_price[PR_CLEAR_SIGNALS] * (is_bidi ? 2 : 1))) *
|
||||
((GetTunnelBridgeLength(tile, tile_exit) + 4) >> 2)); // minimal 1
|
||||
} else if (is_bidi != will_be_bidi) {
|
||||
cost = CommandCost(EXPENSES_CONSTRUCTION, _price[will_be_bidi ? PR_BUILD_SIGNALS : PR_CLEAR_SIGNALS] * ((GetTunnelBridgeLength(tile, tile_exit) + 4) >> 2)); // minimal 1
|
||||
}
|
||||
}
|
||||
auto remove_pbs_bidi = [&]() {
|
||||
if (IsTunnelBridgeSignalSimulationBidirectional(tile)) {
|
||||
ClrTunnelBridgeSignalSimulationExit(tile);
|
||||
ClrTunnelBridgeSignalSimulationEntrance(tile_exit);
|
||||
}
|
||||
};
|
||||
auto set_bidi = [&](TileIndex t) {
|
||||
SetTunnelBridgeSignalSimulationEntrance(t);
|
||||
SetTunnelBridgeEntranceSignalState(t, SIGNAL_STATE_GREEN);
|
||||
SetTunnelBridgeSignalSimulationExit(t);
|
||||
};
|
||||
if (flags & DC_EXEC) {
|
||||
Company * const c = Company::Get(GetTileOwner(tile));
|
||||
if (IsTunnelBridgeWithSignalSimulation(tile)) c->infrastructure.signal -= GetTunnelBridgeSignalSimulationSignalCount(tile, tile_exit);
|
||||
@@ -1127,11 +1153,18 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1,
|
||||
if (!ctrl_pressed) {
|
||||
SetTunnelBridgePBS(tile, is_pbs);
|
||||
SetTunnelBridgePBS(tile_exit, is_pbs);
|
||||
if (bidirectional) {
|
||||
set_bidi(tile);
|
||||
set_bidi(tile_exit);
|
||||
} else {
|
||||
remove_pbs_bidi();
|
||||
}
|
||||
}
|
||||
} else if (ctrl_pressed) {
|
||||
SetTunnelBridgePBS(tile, !IsTunnelBridgePBS(tile));
|
||||
SetTunnelBridgePBS(tile_exit, IsTunnelBridgePBS(tile));
|
||||
} else {
|
||||
if (!IsTunnelBridgePBS(tile)) remove_pbs_bidi();
|
||||
} else if (!IsTunnelBridgeSignalSimulationBidirectional(tile)) {
|
||||
if (IsTunnelBridgeSignalSimulationEntrance(tile)) {
|
||||
ClearBridgeTunnelSignalSimulation(tile, tile_exit);
|
||||
SetupBridgeTunnelSignalSimulation(tile_exit, tile);
|
||||
@@ -1143,7 +1176,12 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1,
|
||||
} else {
|
||||
/* Create one direction tunnel/bridge if required. */
|
||||
if (p2 == 0) {
|
||||
SetupBridgeTunnelSignalSimulation(tile, tile_exit);
|
||||
if (bidirectional) {
|
||||
set_bidi(tile);
|
||||
set_bidi(tile_exit);
|
||||
} else {
|
||||
SetupBridgeTunnelSignalSimulation(tile, tile_exit);
|
||||
}
|
||||
} else if (p2 == 4 || p2 == 8) {
|
||||
DiagDirection tbdir = GetTunnelBridgeDirection(tile);
|
||||
/* If signal only on one side build accoringly one-way tunnel/bridge. */
|
||||
@@ -1161,10 +1199,11 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1,
|
||||
SetTunnelBridgeSemaphore(tile_exit, sigvar == SIG_SEMAPHORE);
|
||||
SetTunnelBridgePBS(tile, is_pbs);
|
||||
SetTunnelBridgePBS(tile_exit, is_pbs);
|
||||
if (!IsTunnelBridgePBS(tile)) remove_pbs_bidi();
|
||||
}
|
||||
}
|
||||
if (IsTunnelBridgeSignalSimulationExit(tile) && IsTunnelBridgePBS(tile) && !HasTunnelBridgeReservation(tile)) SetTunnelBridgeSignalState(tile, SIGNAL_STATE_RED);
|
||||
if (IsTunnelBridgeSignalSimulationExit(tile_exit) && IsTunnelBridgePBS(tile_exit) && !HasTunnelBridgeReservation(tile_exit)) SetTunnelBridgeSignalState(tile_exit, SIGNAL_STATE_RED);
|
||||
if (IsTunnelBridgeSignalSimulationExit(tile) && IsTunnelBridgePBS(tile) && !HasTunnelBridgeReservation(tile)) SetTunnelBridgeExitSignalState(tile, SIGNAL_STATE_RED);
|
||||
if (IsTunnelBridgeSignalSimulationExit(tile_exit) && IsTunnelBridgePBS(tile_exit) && !HasTunnelBridgeReservation(tile_exit)) SetTunnelBridgeExitSignalState(tile_exit, SIGNAL_STATE_RED);
|
||||
MarkBridgeOrTunnelDirty(tile);
|
||||
AddSideToSignalBuffer(tile, INVALID_DIAGDIR, GetTileOwner(tile));
|
||||
AddSideToSignalBuffer(tile_exit, INVALID_DIAGDIR, GetTileOwner(tile));
|
||||
@@ -1604,6 +1643,7 @@ CommandCost CmdRemoveSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1
|
||||
if (!IsTunnelBridgeWithSignalSimulation(tile)) return_cmd_error(STR_ERROR_THERE_ARE_NO_SIGNALS);
|
||||
|
||||
cost *= ((GetTunnelBridgeLength(tile, end) + 4) >> 2);
|
||||
if (IsTunnelBridgeSignalSimulationBidirectional(tile)) cost *= 2;
|
||||
|
||||
CommandCost ret = EnsureNoTrainOnTrack(GetOtherTunnelBridgeEnd(tile), track);
|
||||
if (ret.Failed()) return ret;
|
||||
|
@@ -284,6 +284,7 @@ static void GenericPlaceSignals(TileIndex tile)
|
||||
SB(p1, 8, 1, 0);
|
||||
SB(p1, 9, 6, _settings_client.gui.cycle_signal_types);
|
||||
}
|
||||
SB(p1, 18, 1, _settings_client.gui.adv_sig_bridge_tun_modes);
|
||||
|
||||
DoCommandP(tile, p1, 0, CMD_BUILD_SIGNALS |
|
||||
CMD_MSG((w != NULL && _convert_signal_button) ? STR_ERROR_SIGNAL_CAN_T_CONVERT_SIGNALS_HERE : STR_ERROR_CAN_T_BUILD_SIGNALS_HERE),
|
||||
|
@@ -485,7 +485,7 @@ static inline bool HasOnewaySignalBlockingTrackdir(TileIndex tile, Trackdir td)
|
||||
!HasSignalOnTrackdir(tile, td) && IsOnewaySignal(tile, TrackdirToTrack(td))) {
|
||||
return true;
|
||||
}
|
||||
if (IsTileType(tile, MP_TUNNELBRIDGE) && IsTunnelBridgeSignalSimulationExit(tile) &&
|
||||
if (IsTileType(tile, MP_TUNNELBRIDGE) && IsTunnelBridgeSignalSimulationExitOnly(tile) &&
|
||||
DiagDirToDiagTrackdir(GetTunnelBridgeDirection(tile)) == td) {
|
||||
return true;
|
||||
}
|
||||
|
@@ -3351,7 +3351,7 @@ bool AfterLoadGame()
|
||||
/* signalled tunnel entrance */
|
||||
SignalState state = HasBit(_m[t].m5, 6) ? SIGNAL_STATE_RED : SIGNAL_STATE_GREEN;
|
||||
ClrBit(_m[t].m5, 6);
|
||||
SetTunnelBridgeSignalState(t, state);
|
||||
SetTunnelBridgeEntranceSignalState(t, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3367,6 +3367,14 @@ bool AfterLoadGame()
|
||||
}
|
||||
}
|
||||
}
|
||||
if (SlXvIsFeaturePresent(XSLFI_SIG_TUNNEL_BRIDGE, 1, 5)) {
|
||||
/* entrance and exit signal red/green states now have separate bits */
|
||||
for (TileIndex t = 0; t < map_size; t++) {
|
||||
if (IsTileType(t, MP_TUNNELBRIDGE) && GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL && IsTunnelBridgeSignalSimulationExit(t)) {
|
||||
SetTunnelBridgeExitSignalState(t, HasBit(_me[t].m6, 0) ? SIGNAL_STATE_GREEN : SIGNAL_STATE_RED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (SlXvIsFeatureMissing(XSLFI_CUSTOM_BRIDGE_HEADS)) {
|
||||
/* ensure that previously unused custom bridge-head bits are cleared */
|
||||
|
@@ -56,7 +56,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
|
||||
{ XSLFI_DEPARTURE_BOARDS, XSCF_IGNORABLE_UNKNOWN, 1, 1, "departure_boards", NULL, NULL, NULL },
|
||||
{ XSLFI_TIMETABLES_START_TICKS, XSCF_NULL, 2, 2, "timetable_start_ticks", NULL, NULL, NULL },
|
||||
{ XSLFI_TOWN_CARGO_ADJ, XSCF_IGNORABLE_UNKNOWN, 2, 2, "town_cargo_adj", NULL, NULL, NULL },
|
||||
{ XSLFI_SIG_TUNNEL_BRIDGE, XSCF_NULL, 5, 5, "signal_tunnel_bridge", NULL, NULL, "XBSS" },
|
||||
{ XSLFI_SIG_TUNNEL_BRIDGE, XSCF_NULL, 6, 6, "signal_tunnel_bridge", NULL, NULL, "XBSS" },
|
||||
{ XSLFI_IMPROVED_BREAKDOWNS, XSCF_NULL, 6, 6, "improved_breakdowns", NULL, NULL, NULL },
|
||||
{ XSLFI_TT_WAIT_IN_DEPOT, XSCF_NULL, 1, 1, "tt_wait_in_depot", NULL, NULL, NULL },
|
||||
{ XSLFI_AUTO_TIMETABLE, XSCF_NULL, 4, 4, "auto_timetables", NULL, NULL, NULL },
|
||||
|
@@ -1616,6 +1616,7 @@ static SettingsContainer &GetSettingsTree()
|
||||
interface->Add(new SettingEntry("gui.show_veh_list_cargo_filter"));
|
||||
interface->Add(new SettingEntry("gui.show_adv_load_mode_features"));
|
||||
interface->Add(new SettingEntry("gui.disable_top_veh_list_mass_actions"));
|
||||
interface->Add(new SettingEntry("gui.adv_sig_bridge_tun_modes"));
|
||||
}
|
||||
|
||||
SettingsPage *advisors = main->Add(new SettingsPage(STR_CONFIG_SETTING_ADVISORS));
|
||||
|
@@ -190,6 +190,7 @@ struct GUISettings {
|
||||
bool enable_single_veh_shared_order_gui; ///< enable showing a single vehicle in the shared order GUI window
|
||||
bool show_adv_load_mode_features; ///< enable advanced loading mode features in UI
|
||||
bool disable_top_veh_list_mass_actions; ///< disable mass actions buttons for non-group vehicle lists
|
||||
bool adv_sig_bridge_tun_modes; ///< Enable advanced modes for signals on bridges/tunnels.
|
||||
|
||||
uint16 console_backlog_timeout; ///< the minimum amount of time items should be in the console backlog before they will be removed in ~3 seconds granularity.
|
||||
uint16 console_backlog_length; ///< the minimum amount of items in the console backlog before items will be removed.
|
||||
|
@@ -484,10 +484,10 @@ static void UpdateSignalsAroundSegment(SigInfo info)
|
||||
while (_tbuset.Get(&tile, &trackdir)) {
|
||||
if (IsTileType(tile, MP_TUNNELBRIDGE) && IsTunnelBridgeSignalSimulationExit(tile)) {
|
||||
if (IsTunnelBridgePBS(tile)) continue;
|
||||
SignalState old_state = GetTunnelBridgeSignalState(tile);
|
||||
SignalState old_state = GetTunnelBridgeExitSignalState(tile);
|
||||
SignalState new_state = (info.flags & SF_TRAIN) ? SIGNAL_STATE_RED : SIGNAL_STATE_GREEN;
|
||||
if (old_state != new_state) {
|
||||
SetTunnelBridgeSignalState(tile, new_state);
|
||||
SetTunnelBridgeExitSignalState(tile, new_state);
|
||||
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
|
||||
}
|
||||
continue;
|
||||
|
@@ -4169,6 +4169,14 @@ strhelp = STR_CONFIG_SETTING_DISABLE_TOP_VEH_LIST_MASS_ACTIONS_HELPTEXT
|
||||
proc = RedrawScreen
|
||||
cat = SC_EXPERT
|
||||
|
||||
[SDTC_BOOL]
|
||||
var = gui.adv_sig_bridge_tun_modes
|
||||
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
|
||||
def = false
|
||||
str = STR_CONFIG_SETTING_ADV_SIG_BRIDGE_TUN_MODES
|
||||
strhelp = STR_CONFIG_SETTING_ADV_SIG_BRIDGE_TUN_MODES_HELPTEXT
|
||||
cat = SC_EXPERT
|
||||
|
||||
; For the dedicated build we'll enable dates in logs by default.
|
||||
[SDTC_BOOL]
|
||||
ifdef = DEDICATED
|
||||
|
@@ -2202,10 +2202,10 @@ void ReverseTrainDirection(Train *v)
|
||||
return;
|
||||
}
|
||||
|
||||
/* We are inside tunnel/bidge with signals, reversing will close the entrance. */
|
||||
/* We are inside tunnel/bridge with signals, reversing will close the entrance. */
|
||||
if (IsTunnelBridgeWithSignalSimulation(v->tile)) {
|
||||
/* Flip signal on tunnel entrance tile red. */
|
||||
SetTunnelBridgeSignalState(v->tile, SIGNAL_STATE_RED);
|
||||
SetTunnelBridgeEntranceSignalState(v->tile, SIGNAL_STATE_RED);
|
||||
MarkTileDirtyByTile(v->tile);
|
||||
/* Clear counters. */
|
||||
v->wait_counter = 0;
|
||||
@@ -2601,14 +2601,16 @@ static void HandleLastTunnelBridgeSignals(TileIndex tile, TileIndex end, DiagDir
|
||||
if (free) {
|
||||
/* Open up the wormhole and clear m2. */
|
||||
if (IsBridge(end)) {
|
||||
SetAllBridgeEntranceSimulatedSignalsGreen(end);
|
||||
if (IsTunnelBridgeSignalSimulationEntrance(tile)) SetAllBridgeEntranceSimulatedSignalsGreen(tile);
|
||||
if (IsTunnelBridgeSignalSimulationEntrance(end)) SetAllBridgeEntranceSimulatedSignalsGreen(end);
|
||||
}
|
||||
|
||||
if (IsTunnelBridgeSignalSimulationEntrance(end) && GetTunnelBridgeSignalState(end) == SIGNAL_STATE_RED) {
|
||||
SetTunnelBridgeSignalState(end, SIGNAL_STATE_GREEN);
|
||||
if (IsTunnelBridgeSignalSimulationEntrance(end) && GetTunnelBridgeEntranceSignalState(end) == SIGNAL_STATE_RED) {
|
||||
SetTunnelBridgeEntranceSignalState(end, SIGNAL_STATE_GREEN);
|
||||
MarkTileDirtyByTile(end);
|
||||
} else if (IsTunnelBridgeSignalSimulationEntrance(tile) && GetTunnelBridgeSignalState(tile) == SIGNAL_STATE_RED) {
|
||||
SetTunnelBridgeSignalState(tile, SIGNAL_STATE_GREEN);
|
||||
}
|
||||
if (IsTunnelBridgeSignalSimulationEntrance(tile) && GetTunnelBridgeEntranceSignalState(tile) == SIGNAL_STATE_RED) {
|
||||
SetTunnelBridgeEntranceSignalState(tile, SIGNAL_STATE_GREEN);
|
||||
MarkTileDirtyByTile(tile);
|
||||
}
|
||||
}
|
||||
@@ -2617,7 +2619,7 @@ static void HandleLastTunnelBridgeSignals(TileIndex tile, TileIndex end, DiagDir
|
||||
static void UnreserveBridgeTunnelTile(TileIndex tile)
|
||||
{
|
||||
SetTunnelBridgeReservation(tile, false);
|
||||
if (IsTunnelBridgeSignalSimulationExit(tile) && IsTunnelBridgePBS(tile)) SetTunnelBridgeSignalState(tile, SIGNAL_STATE_RED);
|
||||
if (IsTunnelBridgeSignalSimulationExit(tile) && IsTunnelBridgePBS(tile)) SetTunnelBridgeExitSignalState(tile, SIGNAL_STATE_RED);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3197,7 +3199,7 @@ bool TryPathReserve(Train *v, bool mark_as_stuck, bool first_tile_okay)
|
||||
}
|
||||
}
|
||||
|
||||
if (IsTileType(v->tile, MP_TUNNELBRIDGE) && IsTunnelBridgeSignalSimulationExit(v->tile) &&
|
||||
if (IsTileType(v->tile, MP_TUNNELBRIDGE) && IsTunnelBridgeSignalSimulationExitOnly(v->tile) &&
|
||||
DiagDirToDiagTrackBits(GetTunnelBridgeDirection(v->tile)) == v->track) {
|
||||
// prevent any attempt to reserve the wrong way onto a tunnel/bridge exit
|
||||
return false;
|
||||
@@ -3707,7 +3709,7 @@ static bool CheckTrainStayInWormHolePathReserve(Train *t, TileIndex tile)
|
||||
}
|
||||
bool ok = TryPathReserve(t);
|
||||
t->tile = veh_orig;
|
||||
if (ok && IsTunnelBridgePBS(tile)) SetTunnelBridgeSignalState(tile, SIGNAL_STATE_GREEN);
|
||||
if (ok && IsTunnelBridgePBS(tile)) SetTunnelBridgeExitSignalState(tile, SIGNAL_STATE_GREEN);
|
||||
return ok;
|
||||
}
|
||||
|
||||
@@ -3755,8 +3757,8 @@ static void HandleSignalBehindTrain(Train *v, int signal_number)
|
||||
|
||||
if(tile == v->tile) {
|
||||
/* Flip signal on ramp. */
|
||||
if (IsTunnelBridgeSignalSimulationEntrance(tile) && GetTunnelBridgeSignalState(tile) == SIGNAL_STATE_RED) {
|
||||
SetTunnelBridgeSignalState(tile, SIGNAL_STATE_GREEN);
|
||||
if (IsTunnelBridgeSignalSimulationEntrance(tile) && GetTunnelBridgeEntranceSignalState(tile) == SIGNAL_STATE_RED) {
|
||||
SetTunnelBridgeEntranceSignalState(tile, SIGNAL_STATE_GREEN);
|
||||
MarkTileDirtyByTile(tile);
|
||||
}
|
||||
} else if (IsBridge(v->tile) && signal_number >= 0) {
|
||||
@@ -3987,18 +3989,24 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
|
||||
if (IsTunnelBridgeWithSignalSimulation(gp.new_tile)) {
|
||||
/* If red signal stop. */
|
||||
if (v->IsFrontEngine() && v->force_proceed == 0) {
|
||||
if (IsTunnelBridgeSignalSimulationEntrance(gp.new_tile) && GetTunnelBridgeSignalState(gp.new_tile) == SIGNAL_STATE_RED) {
|
||||
if (IsTunnelBridgeSignalSimulationEntrance(gp.new_tile) && GetTunnelBridgeEntranceSignalState(gp.new_tile) == SIGNAL_STATE_RED) {
|
||||
v->cur_speed = 0;
|
||||
v->vehstatus |= VS_TRAIN_SLOWING;
|
||||
return false;
|
||||
}
|
||||
if (IsTunnelBridgeSignalSimulationExit(gp.new_tile)) {
|
||||
if (IsTunnelBridgeSignalSimulationExitOnly(gp.new_tile)) {
|
||||
v->cur_speed = 0;
|
||||
goto invalid_rail;
|
||||
}
|
||||
/* Flip signal on tunnel entrance tile red. */
|
||||
SetTunnelBridgeSignalState(gp.new_tile, SIGNAL_STATE_RED);
|
||||
SetTunnelBridgeEntranceSignalState(gp.new_tile, SIGNAL_STATE_RED);
|
||||
MarkTileDirtyByTile(gp.new_tile);
|
||||
if (IsTunnelBridgeSignalSimulationBidirectional(gp.new_tile)) {
|
||||
/* Set incoming signal in other direction to red as well */
|
||||
TileIndex other_end = GetOtherTunnelBridgeEnd(gp.new_tile);
|
||||
SetTunnelBridgeEntranceSignalState(other_end, SIGNAL_STATE_RED);
|
||||
MarkTileDirtyByTile(other_end);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4058,7 +4066,7 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
|
||||
TileIndex old_tile = TileVirtXY(v->x_pos, v->y_pos);
|
||||
if (old_tile != gp.new_tile && IsTunnelBridgeWithSignalSimulation(v->tile) && (v->IsFrontEngine() || v->Next() == NULL)) {
|
||||
if (old_tile == v->tile) {
|
||||
if (v->IsFrontEngine() && v->force_proceed == 0 && IsTunnelBridgeSignalSimulationExit(v->tile)) goto invalid_rail;
|
||||
if (v->IsFrontEngine() && v->force_proceed == 0 && IsTunnelBridgeSignalSimulationExitOnly(v->tile)) goto invalid_rail;
|
||||
/* Entered wormhole set counters. */
|
||||
v->wait_counter = (TILE_SIZE * _settings_game.construction.simulated_wormhole_signals) - TILE_SIZE;
|
||||
v->tunnel_bridge_signal_num = 0;
|
||||
@@ -4365,17 +4373,21 @@ static void DeleteLastWagon(Train *v)
|
||||
if (IsTunnelBridgeWithSignalSimulation(tile)) {
|
||||
TileIndex end = GetOtherTunnelBridgeEnd(tile);
|
||||
UpdateSignalsOnSegment(end, INVALID_DIAGDIR, owner);
|
||||
bool is_entrance = IsTunnelBridgeSignalSimulationEntrance(tile);
|
||||
TileIndex entrance = is_entrance ? tile : end;
|
||||
if (TunnelBridgeIsFree(tile, end, nullptr).Succeeded()) {
|
||||
if (IsBridge(entrance)) {
|
||||
SetAllBridgeEntranceSimulatedSignalsGreen(entrance);
|
||||
MarkBridgeDirty(entrance, ZOOM_LVL_DRAW_MAP);
|
||||
}
|
||||
if (IsTunnelBridgeSignalSimulationEntrance(entrance) && GetTunnelBridgeSignalState(entrance) == SIGNAL_STATE_RED) {
|
||||
SetTunnelBridgeSignalState(entrance, SIGNAL_STATE_GREEN);
|
||||
MarkTileDirtyByTile(entrance);
|
||||
}
|
||||
auto process_tile = [](TileIndex t) {
|
||||
if (IsTunnelBridgeSignalSimulationEntrance(t)) {
|
||||
if (IsBridge(t)) {
|
||||
SetAllBridgeEntranceSimulatedSignalsGreen(t);
|
||||
MarkBridgeDirty(t, ZOOM_LVL_DRAW_MAP);
|
||||
}
|
||||
if (IsTunnelBridgeSignalSimulationEntrance(t) && GetTunnelBridgeEntranceSignalState(t) == SIGNAL_STATE_RED) {
|
||||
SetTunnelBridgeEntranceSignalState(t, SIGNAL_STATE_GREEN);
|
||||
MarkTileDirtyByTile(t, ZOOM_LVL_DRAW_MAP);
|
||||
}
|
||||
}
|
||||
};
|
||||
process_tile(tile);
|
||||
process_tile(end);
|
||||
}
|
||||
}
|
||||
} else if (IsRailDepotTile(tile)) {
|
||||
@@ -4615,7 +4627,7 @@ static bool TrainCheckIfLineEnds(Train *v, bool reverse)
|
||||
if (IsLevelCrossingTile(tile)) MaybeBarCrossingWithSound(tile);
|
||||
|
||||
if (IsTileType(tile, MP_TUNNELBRIDGE) && GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL &&
|
||||
IsTunnelBridgeSignalSimulationEntrance(tile) && GetTunnelBridgeSignalState(tile) == SIGNAL_STATE_RED) {
|
||||
IsTunnelBridgeSignalSimulationEntrance(tile) && GetTunnelBridgeEntranceSignalState(tile) == SIGNAL_STATE_RED) {
|
||||
return TrainApproachingLineEnd(v, true, reverse);
|
||||
}
|
||||
|
||||
|
@@ -17,7 +17,7 @@
|
||||
void MarkBridgeDirty(TileIndex begin, TileIndex end, DiagDirection direction, uint bridge_height, const ZoomLevel mark_dirty_if_zoomlevel_is_below = ZOOM_LVL_END);
|
||||
void MarkBridgeDirty(TileIndex tile, const ZoomLevel mark_dirty_if_zoomlevel_is_below = ZOOM_LVL_END);
|
||||
void MarkBridgeOrTunnelDirty(TileIndex tile, const ZoomLevel mark_dirty_if_zoomlevel_is_below = ZOOM_LVL_END);
|
||||
uint GetTunnelBridgeSignalSimulationSignalCount(uint length);
|
||||
uint GetTunnelBridgeSignalSimulationSignalCount(TileIndex begin, TileIndex end);
|
||||
|
||||
/**
|
||||
* Calculates the length of a tunnel or a bridge (without end tiles)
|
||||
@@ -35,17 +35,6 @@ static inline uint GetTunnelBridgeLength(TileIndex begin, TileIndex end)
|
||||
return abs(x2 + y2 - x1 - y1) - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get number of signals on bridge or tunnel with signal simulation.
|
||||
* @param begin The begin of the tunnel or bridge.
|
||||
* @param end The end of the tunnel or bridge.
|
||||
* @pre IsTunnelBridgeWithSignalSimulation(begin)
|
||||
*/
|
||||
static inline uint GetTunnelBridgeSignalSimulationSignalCount(TileIndex begin, TileIndex end)
|
||||
{
|
||||
return GetTunnelBridgeSignalSimulationSignalCount(GetTunnelBridgeLength(begin, end));
|
||||
}
|
||||
|
||||
extern TileIndex _build_tunnel_endtile;
|
||||
|
||||
#endif /* TUNNELBRIDGE_H */
|
||||
|
@@ -104,12 +104,15 @@ void MarkBridgeOrTunnelDirty(TileIndex tile, const ZoomLevel mark_dirty_if_zooml
|
||||
|
||||
/**
|
||||
* Get number of signals on bridge or tunnel with signal simulation.
|
||||
* @param length Length of bridge/tunnel middle
|
||||
* @return Number of signals on signalled bridge/tunnel of this length
|
||||
* @param begin The begin of the tunnel or bridge.
|
||||
* @param end The end of the tunnel or bridge.
|
||||
* @pre IsTunnelBridgeWithSignalSimulation(begin)
|
||||
*/
|
||||
uint GetTunnelBridgeSignalSimulationSignalCount(uint length)
|
||||
uint GetTunnelBridgeSignalSimulationSignalCount(TileIndex begin, TileIndex end)
|
||||
{
|
||||
return 2 + (length / _settings_game.construction.simulated_wormhole_signals);
|
||||
uint result = 2 + (GetTunnelBridgeLength(begin, end) / _settings_game.construction.simulated_wormhole_signals);
|
||||
if (IsTunnelBridgeSignalSimulationBidirectional(begin)) result *= 2;
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Reset the data been eventually changed by the grf loaded. */
|
||||
@@ -1282,10 +1285,10 @@ static void DrawBridgeTramBits(int x, int y, int z, int offset, bool overlay, bo
|
||||
}
|
||||
}
|
||||
|
||||
/* Draws a signal on tunnel / bridge entrance tile. */
|
||||
static void DrawTunnelBridgeRampSignal(const TileInfo *ti)
|
||||
static void DrawTunnelBridgeRampSingleSignal(const TileInfo *ti, bool is_green, uint position, SignalType type, bool show_exit)
|
||||
{
|
||||
bool side = (_settings_game.vehicle.road_side != 0) &&_settings_game.construction.train_signal_side;
|
||||
DiagDirection dir = GetTunnelBridgeDirection(ti->tile);
|
||||
|
||||
static const Point SignalPositions[2][4] = {
|
||||
{ /* X X Y Y Signals on the left side */
|
||||
@@ -1295,29 +1298,6 @@ static void DrawTunnelBridgeRampSignal(const TileInfo *ti)
|
||||
}
|
||||
};
|
||||
|
||||
uint position;
|
||||
DiagDirection dir = GetTunnelBridgeDirection(ti->tile);
|
||||
|
||||
switch (dir) {
|
||||
default: NOT_REACHED();
|
||||
case DIAGDIR_NE: position = 0; break;
|
||||
case DIAGDIR_SE: position = 2; break;
|
||||
case DIAGDIR_SW: position = 1; break;
|
||||
case DIAGDIR_NW: position = 3; break;
|
||||
}
|
||||
|
||||
SignalType type = SIGTYPE_NORMAL;
|
||||
|
||||
bool is_green = (GetTunnelBridgeSignalState(ti->tile) == SIGNAL_STATE_GREEN);
|
||||
bool show_exit;
|
||||
if (IsTunnelBridgeSignalSimulationExit(ti->tile)) {
|
||||
show_exit = true;
|
||||
position ^= 1;
|
||||
if (IsTunnelBridgePBS(ti->tile)) type = SIGTYPE_PBS_ONEWAY;
|
||||
} else {
|
||||
show_exit = false;
|
||||
}
|
||||
|
||||
uint x = TileX(ti->tile) * TILE_SIZE + SignalPositions[side != show_exit][position ^ show_exit].x;
|
||||
uint y = TileY(ti->tile) * TILE_SIZE + SignalPositions[side != show_exit][position ^ show_exit].y;
|
||||
uint z = ti->z;
|
||||
@@ -1348,7 +1328,33 @@ static void DrawTunnelBridgeRampSignal(const TileInfo *ti)
|
||||
}
|
||||
|
||||
/* Draws a signal on tunnel / bridge entrance tile. */
|
||||
static void DrawBrigeSignalOnMiddlePart(const TileInfo *ti, TileIndex bridge_start_tile, uint z)
|
||||
static void DrawTunnelBridgeRampSignal(const TileInfo *ti)
|
||||
{
|
||||
DiagDirection dir = GetTunnelBridgeDirection(ti->tile);
|
||||
|
||||
uint position;
|
||||
switch (dir) {
|
||||
default: NOT_REACHED();
|
||||
case DIAGDIR_NE: position = 0; break;
|
||||
case DIAGDIR_SE: position = 2; break;
|
||||
case DIAGDIR_SW: position = 1; break;
|
||||
case DIAGDIR_NW: position = 3; break;
|
||||
}
|
||||
|
||||
if (IsTunnelBridgeSignalSimulationExit(ti->tile)) {
|
||||
SignalType type = SIGTYPE_NORMAL;
|
||||
if (IsTunnelBridgePBS(ti->tile)) {
|
||||
type = IsTunnelBridgeSignalSimulationEntrance(ti->tile) ? SIGTYPE_PBS : SIGTYPE_PBS_ONEWAY;
|
||||
}
|
||||
DrawTunnelBridgeRampSingleSignal(ti, (GetTunnelBridgeExitSignalState(ti->tile) == SIGNAL_STATE_GREEN), position ^ 1, type, true);
|
||||
}
|
||||
if (IsTunnelBridgeSignalSimulationEntrance(ti->tile)) {
|
||||
DrawTunnelBridgeRampSingleSignal(ti, (GetTunnelBridgeEntranceSignalState(ti->tile) == SIGNAL_STATE_GREEN), position, SIGTYPE_NORMAL, false);
|
||||
}
|
||||
}
|
||||
|
||||
/* Draws a signal on tunnel / bridge entrance tile. */
|
||||
static void DrawBridgeSignalOnMiddlePart(const TileInfo *ti, TileIndex bridge_start_tile, uint z)
|
||||
{
|
||||
|
||||
uint bridge_signal_position = 0;
|
||||
@@ -1791,9 +1797,8 @@ void DrawBridgeMiddle(const TileInfo *ti)
|
||||
if (HasRailCatenaryDrawn(GetRailType(rampsouth))) {
|
||||
DrawRailCatenaryOnBridge(ti);
|
||||
}
|
||||
if (IsTunnelBridgeWithSignalSimulation(rampsouth)) {
|
||||
IsTunnelBridgeSignalSimulationExit(rampsouth) ? DrawBrigeSignalOnMiddlePart(ti, rampnorth, z): DrawBrigeSignalOnMiddlePart(ti, rampsouth, z);
|
||||
}
|
||||
if (IsTunnelBridgeSignalSimulationEntrance(rampsouth)) DrawBridgeSignalOnMiddlePart(ti, rampsouth, z);
|
||||
if (IsTunnelBridgeSignalSimulationEntrance(rampnorth)) DrawBridgeSignalOnMiddlePart(ti, rampnorth, z);
|
||||
}
|
||||
|
||||
/* draw roof, the component of the bridge which is logically between the vehicle and the camera */
|
||||
|
@@ -197,7 +197,7 @@ static inline bool IsTunnelBridgeWithSignalSimulation(TileIndex t)
|
||||
static inline bool IsTunnelBridgeSignalSimulationEntrance(TileIndex t)
|
||||
{
|
||||
assert(IsTileType(t, MP_TUNNELBRIDGE));
|
||||
return HasBit(_m[t].m5, 5) && !HasBit(_m[t].m5, 6);
|
||||
return HasBit(_m[t].m5, 5);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -207,35 +207,83 @@ static inline bool IsTunnelBridgeSignalSimulationEntrance(TileIndex t)
|
||||
* @return true if and only if this tile is a tunnel/bridge exit.
|
||||
*/
|
||||
static inline bool IsTunnelBridgeSignalSimulationExit(TileIndex t)
|
||||
{
|
||||
assert(IsTileType(t, MP_TUNNELBRIDGE));
|
||||
return HasBit(_m[t].m5, 6);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this a tunnel/bridge exit only?
|
||||
* @param t the tile that might be a tunnel/bridge.
|
||||
* @pre IsTileType(t, MP_TUNNELBRIDGE)
|
||||
* @return true if and only if this tile is a tunnel/bridge exit only.
|
||||
*/
|
||||
static inline bool IsTunnelBridgeSignalSimulationExitOnly(TileIndex t)
|
||||
{
|
||||
assert(IsTileType(t, MP_TUNNELBRIDGE));
|
||||
return !HasBit(_m[t].m5, 5) && HasBit(_m[t].m5, 6);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the signal state for a tunnel/bridge entrance or exit with signal simulation
|
||||
* Is this a tunnel/bridge entrance and exit?
|
||||
* @param t the tile that might be a tunnel/bridge.
|
||||
* @pre IsTileType(t, MP_TUNNELBRIDGE)
|
||||
* @return true if and only if this tile is a tunnel/bridge entrance and exit.
|
||||
*/
|
||||
static inline bool IsTunnelBridgeSignalSimulationBidirectional(TileIndex t)
|
||||
{
|
||||
assert(IsTileType(t, MP_TUNNELBRIDGE));
|
||||
return HasBit(_m[t].m5, 5) && HasBit(_m[t].m5, 6);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the signal state for a tunnel/bridge entrance with signal simulation
|
||||
* @param t the tunnel/bridge entrance or exit tile with signal simulation
|
||||
* @pre IsTunnelBridgeWithSignalSimulation(t)
|
||||
* @return signal state
|
||||
*/
|
||||
static inline SignalState GetTunnelBridgeSignalState(TileIndex t)
|
||||
static inline SignalState GetTunnelBridgeEntranceSignalState(TileIndex t)
|
||||
{
|
||||
assert(IsTunnelBridgeWithSignalSimulation(t));
|
||||
assert(IsTunnelBridgeSignalSimulationEntrance(t));
|
||||
return HasBit(_me[t].m6, 0) ? SIGNAL_STATE_GREEN : SIGNAL_STATE_RED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the signal state for a tunnel/bridge exit with signal simulation
|
||||
* @param t the tunnel/bridge entrance or exit tile with signal simulation
|
||||
* @pre IsTunnelBridgeWithSignalSimulation(t)
|
||||
* @return signal state
|
||||
*/
|
||||
static inline SignalState GetTunnelBridgeExitSignalState(TileIndex t)
|
||||
{
|
||||
assert(IsTunnelBridgeSignalSimulationExit(t));
|
||||
return HasBit(_me[t].m6, 7) ? SIGNAL_STATE_GREEN : SIGNAL_STATE_RED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the signal state for a tunnel/bridge entrance or exit with signal simulation
|
||||
* @param t the tunnel/bridge entrance or exit tile with signal simulation
|
||||
* @pre IsTunnelBridgeWithSignalSimulation(t)
|
||||
* @param state signal state
|
||||
*/
|
||||
static inline void SetTunnelBridgeSignalState(TileIndex t, SignalState state)
|
||||
static inline void SetTunnelBridgeEntranceSignalState(TileIndex t, SignalState state)
|
||||
{
|
||||
assert(IsTunnelBridgeWithSignalSimulation(t));
|
||||
assert(IsTunnelBridgeSignalSimulationEntrance(t));
|
||||
SB(_me[t].m6, 0, 1, (state == SIGNAL_STATE_GREEN) ? 1 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the signal state for a tunnel/bridge entrance or exit with signal simulation
|
||||
* @param t the tunnel/bridge entrance or exit tile with signal simulation
|
||||
* @pre IsTunnelBridgeWithSignalSimulation(t)
|
||||
* @param state signal state
|
||||
*/
|
||||
static inline void SetTunnelBridgeExitSignalState(TileIndex t, SignalState state)
|
||||
{
|
||||
assert(IsTunnelBridgeSignalSimulationExit(t));
|
||||
SB(_me[t].m6, 7, 1, (state == SIGNAL_STATE_GREEN) ? 1 : 0);
|
||||
}
|
||||
|
||||
static inline bool IsTunnelBridgeSemaphore(TileIndex t)
|
||||
{
|
||||
assert(IsTunnelBridgeWithSignalSimulation(t));
|
||||
|
Reference in New Issue
Block a user