Store tunnel/bridge signal spacing on tile, adjust spacing to fit length

pull/306/head
Jonathan G Rennison 3 years ago
parent 67c1e0dd11
commit 16f2ef227b

@ -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));

Loading…
Cancel
Save