Store tunnel/bridge signal spacing on tile, adjust spacing to fit length
This commit is contained in:
@@ -1741,6 +1741,7 @@
|
||||
<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 = entrance signal shows green, clear = entrance signal shows red</li>
|
||||
<li>m8 bits 15..12: signal simulation spacing</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>m5 bit 4: pbs reservation state for railway (tunnel only)</li>
|
||||
|
@@ -292,7 +292,7 @@ the array so you can quickly see what is used and what is not.
|
||||
<td class="bits"><span class="used" title="Bridge or tunnel bit">O</span><span class="patch" title="Signal simulation mode (rail only)">PP</span><span class="rearrange" title="PBS reservation (rail; a rearrangement can free some of these bits)">X</span> <span class="used" title="Transport type">XX</span> <span class="used" title="Direction of the tunnel/bridge">XX</span></td>
|
||||
<td class="bits"><span class="patch" title="PBS mode, exit signal state">PP</span><span class="free">OO OO</span><span class="patch" title="Semaphore/light mode, entrance signal state">PP</span></td>
|
||||
<td class="bits" rowspan=4><span class="patch" title="Snow/desert present or rail custom bridge head ground type">PPP</span><span class="rearrange" title="Owner of road (road only; a rearrangement can free some of these bits)">X XXXX</span></td>
|
||||
<td class="bits"><span class="free">O</span><span class="patch" title="Road cached one way state">PPP</span> <span class="used" title="Tram type">XXXX XX</span><span class="rearrange" title="Railway type (rail only; a rearrangement can free some of these bits)">XX XXXX</span></td>
|
||||
<td class="bits"><span class="patch" title="Road cached one way state (road only) or signal simulation spacing (rail only)">PPPP</span> <span class="used" title="Tram type">XXXX XX</span><span class="rearrange" title="Railway type (rail only; a rearrangement can free some of these bits)">XX XXXX</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>bridge ramp - rail</td>
|
||||
@@ -300,7 +300,7 @@ the array so you can quickly see what is used and what is not.
|
||||
<td class="bits"><span class="free">OO</span><span class="patch" title="Track pieces">PP PPPP</span></td>
|
||||
<td class="bits"><span class="used" title="Bridge or tunnel bit">1</span><span class="patch" title="Signal simulation mode">PP</span><span class="free">O</span> <span class="used" title="Transport type">00</span> <span class="used" title="Direction of the tunnel/bridge">XX</span></td>
|
||||
<td class="bits"><span class="patch" title="PBS mode, exit signal state">PP</span><span class="used" title="Bridge type: wooden, steel,...">XX XX</span><span class="patch" title="Semaphore/light mode, entrance signal state">PP</span></td>
|
||||
<td class="bits"><span class="free">OOOO</span> <span class="patch" title="Secondary railway type (used for bridge-bypassing track when two parallel tracks on custom bridge head)">PPPP PP</span><span class="rearrange" title="Railway type (a rearrangement can free some of these bits)">XX XXXX</span></td>
|
||||
<td class="bits"><span class="patch" title="Signal simulation spacing">PPPP</span> <span class="patch" title="Secondary railway type (used for bridge-bypassing track when two parallel tracks on custom bridge head)">PPPP PP</span><span class="rearrange" title="Railway type (a rearrangement can free some of these bits)">XX XXXX</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>bridge ramp - road</td>
|
||||
|
@@ -189,6 +189,7 @@ static inline void MakeRailBridgeRamp(TileIndex t, Owner o, BridgeType bridgetyp
|
||||
SB(_me[t].m6, 0, 2, GB(m6_backup, 0, 2));
|
||||
SB(_me[t].m6, 6, 1, GB(m6_backup, 6, 1));
|
||||
SB(_me[t].m8, 6, 6, GB(m8_backup, 6, 6));
|
||||
SB(_me[t].m8, 12, 4, GB(m8_backup, 12, 4));
|
||||
} else {
|
||||
/* Set bridge head tracks to axial track only. */
|
||||
SB(_m[t].m4, 0, 6, DiagDirToDiagTrackBits(d));
|
||||
|
@@ -1879,6 +1879,7 @@ STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES_HELPTEXT :Set the minimum
|
||||
STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE :Percentage of leg profit to pay in feeder systems: {STRING2}
|
||||
STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE_HELPTEXT :Percentage of income given to the intermediate legs in feeder systems, giving more control over the income
|
||||
STR_CONFIG_SETTING_SIMULATE_SIGNALS :Simulate signals in tunnels, bridges every: {STRING2}
|
||||
STR_CONFIG_SETTING_SIMULATE_SIGNALS_HELPTEXT :This sets the target signal spacing for newly signalled bridges and tunnels. The actual spacing may slightly differ from this to avoid uneven spacing. Changing this setting does not re-signal existing signalled bridges and tunnels.
|
||||
STR_CONFIG_SETTING_SIMULATE_SIGNALS_VALUE :{COMMA} tile{P 0 "" s}
|
||||
STR_CONFIG_SETTING_DAY_LENGTH_FACTOR :Day length factor: {STRING2}
|
||||
STR_CONFIG_SETTING_DAY_LENGTH_FACTOR_HELPTEXT :Game pace is slowed by this factor
|
||||
|
@@ -1527,8 +1527,11 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1,
|
||||
Company * const c = Company::Get(GetTileOwner(tile));
|
||||
std::vector<Train *> re_reserve_trains;
|
||||
if (IsTunnelBridgeWithSignalSimulation(tile)) {
|
||||
c->infrastructure.signal -= GetTunnelBridgeSignalSimulationSignalCount(c, tile, tile_exit);
|
||||
c->infrastructure.signal -= GetTunnelBridgeSignalSimulationSignalCount(tile, tile_exit);
|
||||
} else {
|
||||
uint spacing = GetBestTunnelBridgeSignalSimulationSpacing(GetTileOwner(tile), tile, tile_exit);
|
||||
SetTunnelBridgeSignalSimulationSpacing(tile, spacing);
|
||||
SetTunnelBridgeSignalSimulationSpacing(tile_exit, spacing);
|
||||
for (TileIndex t : { tile, tile_exit }) {
|
||||
if (HasAcrossTunnelBridgeReservation(t)) {
|
||||
Train *re_reserve_train = GetTrainForReservation(t, FindFirstTrack(GetAcrossTunnelBridgeReservationTrackBits(t)));
|
||||
@@ -1602,7 +1605,7 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1,
|
||||
AddSideToSignalBuffer(tile_exit, INVALID_DIAGDIR, GetTileOwner(tile));
|
||||
YapfNotifyTrackLayoutChange(tile, track);
|
||||
YapfNotifyTrackLayoutChange(tile_exit, track);
|
||||
if (IsTunnelBridgeWithSignalSimulation(tile)) c->infrastructure.signal += GetTunnelBridgeSignalSimulationSignalCount(c, tile, tile_exit);
|
||||
if (IsTunnelBridgeWithSignalSimulation(tile)) c->infrastructure.signal += GetTunnelBridgeSignalSimulationSignalCount(tile, tile_exit);
|
||||
DirtyCompanyInfrastructureWindows(GetTileOwner(tile));
|
||||
for (Train *re_reserve_train : re_reserve_trains) {
|
||||
ReReserveTrainPath(re_reserve_train);
|
||||
@@ -2095,7 +2098,7 @@ CommandCost CmdRemoveSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1
|
||||
}
|
||||
if (flags & DC_EXEC) {
|
||||
Company *c = Company::Get(GetTileOwner(tile));
|
||||
c->infrastructure.signal -= GetTunnelBridgeSignalSimulationSignalCount(c, tile, end);
|
||||
c->infrastructure.signal -= GetTunnelBridgeSignalSimulationSignalCount(tile, end);
|
||||
ClearBridgeTunnelSignalSimulation(end, tile);
|
||||
ClearBridgeTunnelSignalSimulation(tile, end);
|
||||
MarkBridgeOrTunnelDirty(tile);
|
||||
|
@@ -29,6 +29,7 @@
|
||||
#include "../station_base.h"
|
||||
#include "../waypoint_base.h"
|
||||
#include "../roadstop_base.h"
|
||||
#include "../tunnelbridge.h"
|
||||
#include "../tunnelbridge_map.h"
|
||||
#include "../pathfinder/yapf/yapf_cache.h"
|
||||
#include "../elrail_func.h"
|
||||
@@ -3637,6 +3638,22 @@ bool AfterLoadGame()
|
||||
c->settings.simulated_wormhole_signals = _settings_game.construction.old_simulated_wormhole_signals;
|
||||
}
|
||||
}
|
||||
if (SlXvIsFeaturePresent(XSLFI_SIG_TUNNEL_BRIDGE, 1, 8)) {
|
||||
/* spacing made per tunnel/bridge */
|
||||
for (TileIndex t = 0; t < map_size; t++) {
|
||||
if (IsTileType(t, MP_TUNNELBRIDGE) && GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL && IsTunnelBridgeWithSignalSimulation(t)) {
|
||||
DiagDirection dir = GetTunnelBridgeDirection(t);
|
||||
if (dir == DIAGDIR_NE || dir == DIAGDIR_SE) {
|
||||
TileIndex other = GetOtherTunnelBridgeEnd(t);
|
||||
uint spacing = GetBestTunnelBridgeSignalSimulationSpacing(GetTileOwner(t), t, other);
|
||||
SetTunnelBridgeSignalSimulationSpacing(t, spacing);
|
||||
SetTunnelBridgeSignalSimulationSpacing(other, spacing);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* force aspect re-calculation */
|
||||
_extra_aspects = 0;
|
||||
}
|
||||
|
||||
if (SlXvIsFeatureMissing(XSLFI_CUSTOM_BRIDGE_HEADS)) {
|
||||
/* ensure that previously unused custom bridge-head bits are cleared */
|
||||
|
@@ -85,7 +85,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
|
||||
{ XSLFI_DEPARTURE_BOARDS, XSCF_IGNORABLE_UNKNOWN, 1, 1, "departure_boards", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_TIMETABLES_START_TICKS, XSCF_NULL, 2, 2, "timetable_start_ticks", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_TOWN_CARGO_ADJ, XSCF_IGNORABLE_UNKNOWN, 2, 2, "town_cargo_adj", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_SIG_TUNNEL_BRIDGE, XSCF_NULL, 8, 8, "signal_tunnel_bridge", nullptr, nullptr, "XBSS" },
|
||||
{ XSLFI_SIG_TUNNEL_BRIDGE, XSCF_NULL, 9, 9, "signal_tunnel_bridge", nullptr, nullptr, "XBSS" },
|
||||
{ XSLFI_IMPROVED_BREAKDOWNS, XSCF_NULL, 7, 7, "improved_breakdowns", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_CONSIST_BREAKDOWN_FLAG, XSCF_NULL, 1, 1, "consist_breakdown_flag", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_TT_WAIT_IN_DEPOT, XSCF_NULL, 1, 1, "tt_wait_in_depot", nullptr, nullptr, nullptr },
|
||||
|
@@ -1482,14 +1482,6 @@ static bool InvalidateCompanyWindow(int32 p1)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool SimulatedWormholeSignalsChanged(int32 p1)
|
||||
{
|
||||
extern void AfterLoadCompanyStats();
|
||||
AfterLoadCompanyStats();
|
||||
MarkWholeScreenDirty();
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool EnableSingleVehSharedOrderGuiChanged(int32)
|
||||
{
|
||||
for (VehicleType type = VEH_BEGIN; type < VEH_COMPANY_END; type++) {
|
||||
|
@@ -11,7 +11,6 @@ static bool UpdateIntervalTrains(int32 p1);
|
||||
static bool UpdateIntervalRoadVeh(int32 p1);
|
||||
static bool UpdateIntervalShips(int32 p1);
|
||||
static bool UpdateIntervalAircraft(int32 p1);
|
||||
static bool SimulatedWormholeSignalsChanged(int32 p1);
|
||||
|
||||
static const SettingDesc _company_settings[] = {
|
||||
[post-amble]
|
||||
@@ -269,8 +268,8 @@ def = 4
|
||||
min = 1
|
||||
max = 16
|
||||
str = STR_CONFIG_SETTING_SIMULATE_SIGNALS
|
||||
strhelp = STR_CONFIG_SETTING_SIMULATE_SIGNALS_HELPTEXT
|
||||
strval = STR_CONFIG_SETTING_SIMULATE_SIGNALS_VALUE
|
||||
proc = SimulatedWormholeSignalsChanged
|
||||
cat = SC_ADVANCED
|
||||
patxname = ""simulated_wormhole_signals""
|
||||
|
||||
|
@@ -13,8 +13,9 @@
|
||||
#include "map_func.h"
|
||||
#include "tile_map.h"
|
||||
|
||||
uint GetTunnelBridgeSignalSimulationSpacing(TileIndex tile);
|
||||
uint GetTunnelBridgeSignalSimulationSignalCount(Company *c, TileIndex begin, TileIndex end);
|
||||
uint GetTunnelBridgeSignalSimulationSpacingTarget(Owner owner);
|
||||
uint GetBestTunnelBridgeSignalSimulationSpacing(Owner owner, TileIndex begin, TileIndex end);
|
||||
uint GetTunnelBridgeSignalSimulationSignalCount(TileIndex begin, TileIndex end);
|
||||
|
||||
/**
|
||||
* Calculates the length of a tunnel or a bridge (without end tiles)
|
||||
|
@@ -131,9 +131,8 @@ void MarkBridgeOrTunnelDirtyOnReservationChange(TileIndex tile, ViewportMarkDirt
|
||||
}
|
||||
}
|
||||
|
||||
uint GetTunnelBridgeSignalSimulationSpacing(TileIndex tile)
|
||||
uint GetTunnelBridgeSignalSimulationSpacingTarget(Owner owner)
|
||||
{
|
||||
Owner owner = GetTileOwner(tile);
|
||||
if (Company::IsValidID(owner)) {
|
||||
return Company::Get(owner)->settings.simulated_wormhole_signals;
|
||||
} else {
|
||||
@@ -141,16 +140,37 @@ uint GetTunnelBridgeSignalSimulationSpacing(TileIndex tile)
|
||||
}
|
||||
}
|
||||
|
||||
uint GetBestTunnelBridgeSignalSimulationSpacing(Owner owner, TileIndex begin, TileIndex end)
|
||||
{
|
||||
int target = GetTunnelBridgeSignalSimulationSpacingTarget(owner);
|
||||
if (target <= 2) return target;
|
||||
int length = GetTunnelBridgeLength(begin, end);
|
||||
if (target > length || ((length + 1) % target) == 0) return target;
|
||||
|
||||
int lower = target - (target / 4);
|
||||
int upper = std::min<int>(16, target + (target / 3));
|
||||
|
||||
int best_gap = -1;
|
||||
int best_spacing = 0;
|
||||
for (int i = lower; i <= upper; i++) {
|
||||
int gap = length % i;
|
||||
if (gap > best_gap) {
|
||||
best_gap = gap;
|
||||
best_spacing = i;
|
||||
}
|
||||
}
|
||||
return best_spacing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get number of signals on bridge or tunnel with signal simulation.
|
||||
* @param c Company to use.
|
||||
* @param begin The begin of the tunnel or bridge.
|
||||
* @param end The end of the tunnel or bridge.
|
||||
* @pre IsTunnelBridgeWithSignalSimulation(begin)
|
||||
*/
|
||||
uint GetTunnelBridgeSignalSimulationSignalCount(Company *c, TileIndex begin, TileIndex end)
|
||||
uint GetTunnelBridgeSignalSimulationSignalCount(TileIndex begin, TileIndex end)
|
||||
{
|
||||
uint result = 2 + (GetTunnelBridgeLength(begin, end) / c->settings.simulated_wormhole_signals);
|
||||
uint result = 2 + (GetTunnelBridgeLength(begin, end) / GetTunnelBridgeSignalSimulationSpacing(begin));
|
||||
if (IsTunnelBridgeSignalSimulationBidirectional(begin)) result *= 2;
|
||||
return result;
|
||||
}
|
||||
@@ -1254,7 +1274,7 @@ static CommandCost DoClearTunnel(TileIndex tile, DoCommandFlag flags)
|
||||
Company *c = Company::Get(owner);
|
||||
c->infrastructure.rail[GetRailType(tile)] -= len * TUNNELBRIDGE_TRACKBIT_FACTOR;
|
||||
if (IsTunnelBridgeWithSignalSimulation(tile)) { // handle tunnel/bridge signals.
|
||||
c->infrastructure.signal -= GetTunnelBridgeSignalSimulationSignalCount(c, tile, endtile);
|
||||
c->infrastructure.signal -= GetTunnelBridgeSignalSimulationSignalCount(tile, endtile);
|
||||
}
|
||||
DirtyCompanyInfrastructureWindows(owner);
|
||||
}
|
||||
@@ -2730,9 +2750,9 @@ static void UpdateRailTunnelBridgeInfrastructure(Company *c, TileIndex begin, Ti
|
||||
|
||||
if (IsTunnelBridgeWithSignalSimulation(begin)) {
|
||||
if (add) {
|
||||
c->infrastructure.signal += GetTunnelBridgeSignalSimulationSignalCount(c, begin, end);
|
||||
c->infrastructure.signal += GetTunnelBridgeSignalSimulationSignalCount(begin, end);
|
||||
} else {
|
||||
c->infrastructure.signal -= GetTunnelBridgeSignalSimulationSignalCount(c, begin, end);
|
||||
c->infrastructure.signal -= GetTunnelBridgeSignalSimulationSignalCount(begin, end);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -530,6 +530,18 @@ static inline void SetTunnelBridgeExitSignalAspect(TileIndex t, uint8 aspect)
|
||||
SB(_m[t].m3, 3, 3, aspect);
|
||||
}
|
||||
|
||||
static inline uint GetTunnelBridgeSignalSimulationSpacing(TileIndex t)
|
||||
{
|
||||
assert_tile(IsRailTunnelBridgeTile(t), t);
|
||||
return 1 + GB(_me[t].m8, 12, 4);
|
||||
}
|
||||
|
||||
static inline void SetTunnelBridgeSignalSimulationSpacing(TileIndex t, uint spacing)
|
||||
{
|
||||
assert_tile(IsRailTunnelBridgeTile(t), t);
|
||||
SB(_me[t].m8, 12, 4, spacing - 1);
|
||||
}
|
||||
|
||||
static inline Trackdir GetTunnelBridgeExitTrackdir(TileIndex t, DiagDirection tunnel_bridge_dir)
|
||||
{
|
||||
return TrackEnterdirToTrackdir((Track)FIND_FIRST_BIT(GetAcrossTunnelBridgeTrackBits(t)), ReverseDiagDir(tunnel_bridge_dir));
|
||||
|
Reference in New Issue
Block a user