Implement train speed adaptation on signalled tunnels/bridges
See: #373
This commit is contained in:
@@ -156,7 +156,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
|
|||||||
{ XSLFI_MORE_HOUSES, XSCF_NULL, 2, 2, "more_houses", nullptr, nullptr, nullptr },
|
{ XSLFI_MORE_HOUSES, XSCF_NULL, 2, 2, "more_houses", nullptr, nullptr, nullptr },
|
||||||
{ XSLFI_CUSTOM_TOWN_ZONE, XSCF_IGNORABLE_UNKNOWN, 1, 1, "custom_town_zone", nullptr, nullptr, nullptr },
|
{ XSLFI_CUSTOM_TOWN_ZONE, XSCF_IGNORABLE_UNKNOWN, 1, 1, "custom_town_zone", nullptr, nullptr, nullptr },
|
||||||
{ XSLFI_STATION_CARGO_HISTORY, XSCF_NULL, 1, 1, "station_cargo_history", nullptr, nullptr, nullptr },
|
{ XSLFI_STATION_CARGO_HISTORY, XSCF_NULL, 1, 1, "station_cargo_history", nullptr, nullptr, nullptr },
|
||||||
{ XSLFI_TRAIN_SPEED_ADAPTATION, XSCF_NULL, 1, 1, "train_speed_adaptation", nullptr, nullptr, "TSAS" },
|
{ XSLFI_TRAIN_SPEED_ADAPTATION, XSCF_NULL, 2, 2, "train_speed_adaptation", nullptr, nullptr, "TSAS" },
|
||||||
{ XSLFI_EXTRA_STATION_NAMES, XSCF_NULL, 1, 1, "extra_station_names", nullptr, nullptr, nullptr },
|
{ XSLFI_EXTRA_STATION_NAMES, XSCF_NULL, 1, 1, "extra_station_names", nullptr, nullptr, nullptr },
|
||||||
{ XSLFI_DEPOT_ORDER_EXTRA_FLAGS,XSCF_IGNORABLE_UNKNOWN, 1, 1, "depot_order_extra_flags", nullptr, nullptr, nullptr },
|
{ XSLFI_DEPOT_ORDER_EXTRA_FLAGS,XSCF_IGNORABLE_UNKNOWN, 1, 1, "depot_order_extra_flags", nullptr, nullptr, nullptr },
|
||||||
{ XSLFI_EXTRA_SIGNAL_TYPES, XSCF_NULL, 1, 1, "extra_signal_types", nullptr, nullptr, nullptr },
|
{ XSLFI_EXTRA_SIGNAL_TYPES, XSCF_NULL, 1, 1, "extra_signal_types", nullptr, nullptr, nullptr },
|
||||||
|
@@ -14,35 +14,42 @@
|
|||||||
using SignalSpeedType = std::pair<const SignalSpeedKey, SignalSpeedValue>;
|
using SignalSpeedType = std::pair<const SignalSpeedKey, SignalSpeedValue>;
|
||||||
|
|
||||||
static const SaveLoad _train_speed_adaptation_map_desc[] = {
|
static const SaveLoad _train_speed_adaptation_map_desc[] = {
|
||||||
SLE_VAR(SignalSpeedType, first.signal_track, SLE_UINT8),
|
SLE_CONDVAR_X(SignalSpeedType, first.signal_track, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TRAIN_SPEED_ADAPTATION, 1, 1)),
|
||||||
|
SLE_CONDVAR_X(SignalSpeedType, first.signal_track, SLE_UINT16, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TRAIN_SPEED_ADAPTATION, 2)),
|
||||||
SLE_VAR(SignalSpeedType, first.last_passing_train_dir, SLE_UINT8),
|
SLE_VAR(SignalSpeedType, first.last_passing_train_dir, SLE_UINT8),
|
||||||
SLE_VAR(SignalSpeedType, second.train_speed, SLE_UINT16),
|
SLE_VAR(SignalSpeedType, second.train_speed, SLE_UINT16),
|
||||||
SLE_VAR(SignalSpeedType, second.time_stamp, SLE_UINT64),
|
SLE_VAR(SignalSpeedType, second.time_stamp, SLE_UINT64),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static std::vector<SaveLoad> _filtered_train_speed_adaptation_map_desc = SlFilterObject(_train_speed_adaptation_map_desc);
|
||||||
|
|
||||||
static void Load_TSAS()
|
static void Load_TSAS()
|
||||||
{
|
{
|
||||||
|
_filtered_train_speed_adaptation_map_desc = SlFilterObject(_train_speed_adaptation_map_desc);
|
||||||
int index;
|
int index;
|
||||||
SignalSpeedType data;
|
SignalSpeedType data;
|
||||||
while ((index = SlIterateArray()) != -1) {
|
while ((index = SlIterateArray()) != -1) {
|
||||||
const_cast<SignalSpeedKey &>(data.first).signal_tile = index;
|
const_cast<SignalSpeedKey &>(data.first).signal_tile = index;
|
||||||
SlObject(&data, _train_speed_adaptation_map_desc);
|
SlObjectLoadFiltered(&data, _filtered_train_speed_adaptation_map_desc);
|
||||||
_signal_speeds.insert(data);
|
_signal_speeds.insert(data);
|
||||||
}
|
}
|
||||||
|
_filtered_train_speed_adaptation_map_desc.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void RealSave_TSAS(SignalSpeedType *data)
|
static void RealSave_TSAS(SignalSpeedType *data)
|
||||||
{
|
{
|
||||||
SlObject(data, _train_speed_adaptation_map_desc);
|
SlObjectSaveFiltered(data, _filtered_train_speed_adaptation_map_desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Save_TSAS()
|
static void Save_TSAS()
|
||||||
{
|
{
|
||||||
|
_filtered_train_speed_adaptation_map_desc = SlFilterObject(_train_speed_adaptation_map_desc);
|
||||||
for (auto &it : _signal_speeds) {
|
for (auto &it : _signal_speeds) {
|
||||||
SlSetArrayIndex(it.first.signal_tile);
|
SlSetArrayIndex(it.first.signal_tile);
|
||||||
SignalSpeedType *data = ⁢
|
SignalSpeedType *data = ⁢
|
||||||
SlAutolength((AutolengthProc*) RealSave_TSAS, data);
|
SlAutolength((AutolengthProc*) RealSave_TSAS, data);
|
||||||
}
|
}
|
||||||
|
_filtered_train_speed_adaptation_map_desc.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern const ChunkHandler train_speed_adaptation_chunk_handlers[] = {
|
extern const ChunkHandler train_speed_adaptation_chunk_handlers[] = {
|
||||||
|
@@ -5610,8 +5610,9 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
|
|||||||
v->wait_counter = (TILE_SIZE * simulated_wormhole_signals) - TILE_SIZE;
|
v->wait_counter = (TILE_SIZE * simulated_wormhole_signals) - TILE_SIZE;
|
||||||
v->tunnel_bridge_signal_num = 0;
|
v->tunnel_bridge_signal_num = 0;
|
||||||
|
|
||||||
if (v->IsFrontEngine() && IsTunnelBridgeSignalSimulationEntrance(old_tile) && IsTunnelBridgeRestrictedSignal(old_tile)) {
|
if (v->IsFrontEngine() && IsTunnelBridgeSignalSimulationEntrance(old_tile) && (IsTunnelBridgeRestrictedSignal(old_tile) || _settings_game.vehicle.train_speed_adaptation)) {
|
||||||
const Trackdir trackdir = GetTunnelBridgeEntranceTrackdir(old_tile);
|
const Trackdir trackdir = GetTunnelBridgeEntranceTrackdir(old_tile);
|
||||||
|
if (IsTunnelBridgeRestrictedSignal(old_tile)) {
|
||||||
const TraceRestrictProgram *prog = GetExistingTraceRestrictProgram(old_tile, TrackdirToTrack(trackdir));
|
const TraceRestrictProgram *prog = GetExistingTraceRestrictProgram(old_tile, TrackdirToTrack(trackdir));
|
||||||
if (prog && prog->actions_used_flags & (TRPAUF_SLOT_ACQUIRE | TRPAUF_SLOT_RELEASE_FRONT | TRPAUF_SPEED_RESTRICTION | TRPAUF_CHANGE_COUNTER)) {
|
if (prog && prog->actions_used_flags & (TRPAUF_SLOT_ACQUIRE | TRPAUF_SLOT_RELEASE_FRONT | TRPAUF_SPEED_RESTRICTION | TRPAUF_CHANGE_COUNTER)) {
|
||||||
TraceRestrictProgramResult out;
|
TraceRestrictProgramResult out;
|
||||||
@@ -5621,11 +5622,16 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
|
|||||||
HandleTraceRestrictSpeedRestrictionAction(out, v, trackdir);
|
HandleTraceRestrictSpeedRestrictionAction(out, v, trackdir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (_settings_game.vehicle.train_speed_adaptation) {
|
||||||
|
SetSignalTrainAdaptationSpeed(v, old_tile, TrackdirToTrack(trackdir));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (v->Next() == nullptr && IsTunnelBridgeSignalSimulationEntrance(old_tile) && IsTunnelBridgeRestrictedSignal(old_tile)) {
|
if (v->Next() == nullptr && IsTunnelBridgeSignalSimulationEntrance(old_tile) && (IsTunnelBridgeRestrictedSignal(old_tile) || _settings_game.vehicle.train_speed_adaptation)) {
|
||||||
const Trackdir trackdir = GetTunnelBridgeEntranceTrackdir(old_tile);
|
const Trackdir trackdir = GetTunnelBridgeEntranceTrackdir(old_tile);
|
||||||
const Track track = TrackdirToTrack(trackdir);
|
const Track track = TrackdirToTrack(trackdir);
|
||||||
|
|
||||||
|
if (IsTunnelBridgeRestrictedSignal(old_tile)) {
|
||||||
const TraceRestrictProgram *prog = GetExistingTraceRestrictProgram(old_tile, track);
|
const TraceRestrictProgram *prog = GetExistingTraceRestrictProgram(old_tile, track);
|
||||||
if (prog && prog->actions_used_flags & TRPAUF_SLOT_RELEASE_BACK) {
|
if (prog && prog->actions_used_flags & TRPAUF_SLOT_RELEASE_BACK) {
|
||||||
TraceRestrictProgramResult out;
|
TraceRestrictProgramResult out;
|
||||||
@@ -5634,6 +5640,10 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
|
|||||||
prog->Execute(first, input, out);
|
prog->Execute(first, input, out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (_settings_game.vehicle.train_speed_adaptation) {
|
||||||
|
ApplySignalTrainAdaptationSpeed(v, old_tile, track);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint distance = v->wait_counter;
|
uint distance = v->wait_counter;
|
||||||
@@ -5672,10 +5682,18 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
|
|||||||
SetBridgeEntranceSimulatedSignalState(v->tile, v->tunnel_bridge_signal_num, SIGNAL_STATE_RED);
|
SetBridgeEntranceSimulatedSignalState(v->tile, v->tunnel_bridge_signal_num, SIGNAL_STATE_RED);
|
||||||
MarkSingleBridgeSignalDirty(gp.new_tile, v->tile);
|
MarkSingleBridgeSignalDirty(gp.new_tile, v->tile);
|
||||||
}
|
}
|
||||||
|
if (_settings_game.vehicle.train_speed_adaptation && distance == 0 && IsTunnelBridgeSignalSimulationEntrance(v->tile)) {
|
||||||
|
ApplySignalTrainAdaptationSpeed(v, v->tile, 0x100 + v->tunnel_bridge_signal_num);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (v->Next() == nullptr) {
|
if (v->Next() == nullptr) {
|
||||||
if (v->tunnel_bridge_signal_num > 0 && distance == (TILE_SIZE * simulated_wormhole_signals) - TILE_SIZE) HandleSignalBehindTrain(v, v->tunnel_bridge_signal_num - 2);
|
if (v->tunnel_bridge_signal_num > 0 && distance == (TILE_SIZE * simulated_wormhole_signals) - TILE_SIZE) {
|
||||||
|
HandleSignalBehindTrain(v, v->tunnel_bridge_signal_num - 2);
|
||||||
|
if (_settings_game.vehicle.train_speed_adaptation) {
|
||||||
|
SetSignalTrainAdaptationSpeed(v, v->tile, 0x100 + v->tunnel_bridge_signal_num - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
DiagDirection tunnel_bridge_dir = GetTunnelBridgeDirection(v->tile);
|
DiagDirection tunnel_bridge_dir = GetTunnelBridgeDirection(v->tile);
|
||||||
Axis axis = DiagDirToAxis(tunnel_bridge_dir);
|
Axis axis = DiagDirToAxis(tunnel_bridge_dir);
|
||||||
DiagDirection axial_dir = DirToDiagDirAlongAxis(v->direction, axis);
|
DiagDirection axial_dir = DirToDiagDirAlongAxis(v->direction, axis);
|
||||||
@@ -5803,25 +5821,13 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
|
|||||||
const TrackdirBits rev_tracks = TrackBitsToTrackdirBits(GetTrackBits(gp.old_tile)) & DiagdirReachesTrackdirs(ReverseDiagDir(enterdir));
|
const TrackdirBits rev_tracks = TrackBitsToTrackdirBits(GetTrackBits(gp.old_tile)) & DiagdirReachesTrackdirs(ReverseDiagDir(enterdir));
|
||||||
const Trackdir rev_trackdir = FindFirstTrackdir(rev_tracks);
|
const Trackdir rev_trackdir = FindFirstTrackdir(rev_tracks);
|
||||||
if (HasSignalOnTrackdir(gp.old_tile, ReverseTrackdir(rev_trackdir))) {
|
if (HasSignalOnTrackdir(gp.old_tile, ReverseTrackdir(rev_trackdir))) {
|
||||||
const Track track = TrackdirToTrack(rev_trackdir);
|
ApplySignalTrainAdaptationSpeed(v, gp.old_tile, TrackdirToTrack(rev_trackdir));
|
||||||
SignalSpeedKey speed_key = {
|
|
||||||
speed_key.signal_tile = gp.old_tile,
|
|
||||||
speed_key.signal_track = track,
|
|
||||||
speed_key.last_passing_train_dir = v->GetVehicleTrackdir()
|
|
||||||
};
|
|
||||||
const auto found_speed_restriction = _signal_speeds.find(speed_key);
|
|
||||||
|
|
||||||
if (found_speed_restriction != _signal_speeds.end()) {
|
|
||||||
if (IsOutOfDate(found_speed_restriction->second)) {
|
|
||||||
_signal_speeds.erase(found_speed_restriction);
|
|
||||||
v->signal_speed_restriction = 0;
|
|
||||||
} else {
|
|
||||||
v->signal_speed_restriction = std::max<uint16>(25, found_speed_restriction->second.train_speed);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
v->signal_speed_restriction = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (_settings_game.vehicle.train_speed_adaptation && IsTileType(gp.old_tile, MP_TUNNELBRIDGE) && IsTunnelBridgeSignalSimulationExit(gp.old_tile)) {
|
||||||
|
const TrackdirBits rev_tracks = TrackBitsToTrackdirBits(GetTunnelBridgeTrackBits(gp.old_tile)) & DiagdirReachesTrackdirs(ReverseDiagDir(enterdir));
|
||||||
|
const Trackdir rev_trackdir = FindFirstTrackdir(rev_tracks);
|
||||||
|
ApplySignalTrainAdaptationSpeed(v, gp.old_tile, TrackdirToTrack(rev_trackdir));
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (TrainMovedChangeSignal(v, gp.new_tile, enterdir, true)) {
|
switch (TrainMovedChangeSignal(v, gp.new_tile, enterdir, true)) {
|
||||||
@@ -5867,16 +5873,7 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
|
|||||||
const Track track = TrackdirToTrack(rev_trackdir);
|
const Track track = TrackdirToTrack(rev_trackdir);
|
||||||
|
|
||||||
if (_settings_game.vehicle.train_speed_adaptation && HasSignalOnTrackdir(gp.old_tile, ReverseTrackdir(rev_trackdir))) {
|
if (_settings_game.vehicle.train_speed_adaptation && HasSignalOnTrackdir(gp.old_tile, ReverseTrackdir(rev_trackdir))) {
|
||||||
SignalSpeedKey speed_key = {
|
SetSignalTrainAdaptationSpeed(v, gp.old_tile, track);
|
||||||
speed_key.signal_tile = gp.old_tile,
|
|
||||||
speed_key.signal_track = track,
|
|
||||||
speed_key.last_passing_train_dir = v->GetVehicleTrackdir()
|
|
||||||
};
|
|
||||||
SignalSpeedValue speed_value = {
|
|
||||||
speed_value.train_speed = v->First()->cur_speed,
|
|
||||||
speed_value.time_stamp = GetSpeedRestrictionTimeout(v->First())
|
|
||||||
};
|
|
||||||
_signal_speeds[speed_key] = speed_value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HasSignalOnTrack(gp.old_tile, track)) {
|
if (HasSignalOnTrack(gp.old_tile, track)) {
|
||||||
@@ -5892,12 +5889,13 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsTileType(gp.old_tile, MP_TUNNELBRIDGE) && IsTunnelBridgeSignalSimulationExit(gp.old_tile) && IsTunnelBridgeRestrictedSignal(gp.old_tile)) {
|
if (IsTileType(gp.old_tile, MP_TUNNELBRIDGE) && IsTunnelBridgeSignalSimulationExit(gp.old_tile) && (IsTunnelBridgeRestrictedSignal(gp.old_tile) || _settings_game.vehicle.train_speed_adaptation)) {
|
||||||
const TrackdirBits rev_tracks = TrackBitsToTrackdirBits(GetTunnelBridgeTrackBits(gp.old_tile)) & DiagdirReachesTrackdirs(ReverseDiagDir(enterdir));
|
const TrackdirBits rev_tracks = TrackBitsToTrackdirBits(GetTunnelBridgeTrackBits(gp.old_tile)) & DiagdirReachesTrackdirs(ReverseDiagDir(enterdir));
|
||||||
const Trackdir rev_trackdir = FindFirstTrackdir(rev_tracks);
|
const Trackdir rev_trackdir = FindFirstTrackdir(rev_tracks);
|
||||||
const Track track = TrackdirToTrack(rev_trackdir);
|
const Track track = TrackdirToTrack(rev_trackdir);
|
||||||
|
|
||||||
if (TrackdirEntersTunnelBridge(gp.old_tile, rev_trackdir)) {
|
if (TrackdirEntersTunnelBridge(gp.old_tile, rev_trackdir)) {
|
||||||
|
if (IsTunnelBridgeRestrictedSignal(gp.old_tile)) {
|
||||||
const TraceRestrictProgram *prog = GetExistingTraceRestrictProgram(gp.old_tile, track);
|
const TraceRestrictProgram *prog = GetExistingTraceRestrictProgram(gp.old_tile, track);
|
||||||
if (prog && prog->actions_used_flags & TRPAUF_SLOT_RELEASE_BACK) {
|
if (prog && prog->actions_used_flags & TRPAUF_SLOT_RELEASE_BACK) {
|
||||||
TraceRestrictProgramResult out;
|
TraceRestrictProgramResult out;
|
||||||
@@ -5906,6 +5904,10 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
|
|||||||
prog->Execute(first, input, out);
|
prog->Execute(first, input, out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (_settings_game.vehicle.train_speed_adaptation) {
|
||||||
|
SetSignalTrainAdaptationSpeed(v, gp.old_tile, track);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7271,3 +7273,38 @@ int GetTrainEstimatedMaxAchievableSpeed(const Train *train, const int mass, cons
|
|||||||
|
|
||||||
return max_speed;
|
return max_speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetSignalTrainAdaptationSpeed(const Train *v, TileIndex tile, uint16 track)
|
||||||
|
{
|
||||||
|
SignalSpeedKey speed_key = {
|
||||||
|
speed_key.signal_tile = tile,
|
||||||
|
speed_key.signal_track = track,
|
||||||
|
speed_key.last_passing_train_dir = v->GetVehicleTrackdir()
|
||||||
|
};
|
||||||
|
SignalSpeedValue speed_value = {
|
||||||
|
speed_value.train_speed = v->First()->cur_speed,
|
||||||
|
speed_value.time_stamp = GetSpeedRestrictionTimeout(v->First())
|
||||||
|
};
|
||||||
|
_signal_speeds[speed_key] = speed_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApplySignalTrainAdaptationSpeed(Train *v, TileIndex tile, uint16 track)
|
||||||
|
{
|
||||||
|
SignalSpeedKey speed_key = {
|
||||||
|
speed_key.signal_tile = tile,
|
||||||
|
speed_key.signal_track = track,
|
||||||
|
speed_key.last_passing_train_dir = v->GetVehicleTrackdir()
|
||||||
|
};
|
||||||
|
const auto found_speed_restriction = _signal_speeds.find(speed_key);
|
||||||
|
|
||||||
|
if (found_speed_restriction != _signal_speeds.end()) {
|
||||||
|
if (IsOutOfDate(found_speed_restriction->second)) {
|
||||||
|
_signal_speeds.erase(found_speed_restriction);
|
||||||
|
v->signal_speed_restriction = 0;
|
||||||
|
} else {
|
||||||
|
v->signal_speed_restriction = std::max<uint16>(25, found_speed_restriction->second.train_speed);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
v->signal_speed_restriction = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -19,7 +19,7 @@
|
|||||||
struct SignalSpeedKey
|
struct SignalSpeedKey
|
||||||
{
|
{
|
||||||
TileIndex signal_tile;
|
TileIndex signal_tile;
|
||||||
Track signal_track;
|
uint16 signal_track;
|
||||||
Trackdir last_passing_train_dir;
|
Trackdir last_passing_train_dir;
|
||||||
|
|
||||||
bool operator==(const SignalSpeedKey& other) const
|
bool operator==(const SignalSpeedKey& other) const
|
||||||
@@ -42,7 +42,7 @@ struct SignalSpeedKeyHashFunc
|
|||||||
{
|
{
|
||||||
const std::size_t h1 = std::hash<TileIndex>()(key.signal_tile);
|
const std::size_t h1 = std::hash<TileIndex>()(key.signal_tile);
|
||||||
const std::size_t h2 = std::hash<Trackdir>()(key.last_passing_train_dir);
|
const std::size_t h2 = std::hash<Trackdir>()(key.last_passing_train_dir);
|
||||||
const std::size_t h3 = std::hash<Track>()(key.signal_track);
|
const std::size_t h3 = std::hash<uint16>()(key.signal_track);
|
||||||
|
|
||||||
return (h1 ^ h2) ^ h3;
|
return (h1 ^ h2) ^ h3;
|
||||||
}
|
}
|
||||||
@@ -50,4 +50,8 @@ struct SignalSpeedKeyHashFunc
|
|||||||
|
|
||||||
extern std::unordered_map<SignalSpeedKey, SignalSpeedValue, SignalSpeedKeyHashFunc> _signal_speeds;
|
extern std::unordered_map<SignalSpeedKey, SignalSpeedValue, SignalSpeedKeyHashFunc> _signal_speeds;
|
||||||
|
|
||||||
|
struct Train;
|
||||||
|
void SetSignalTrainAdaptationSpeed(const Train *v, TileIndex tile, uint16 track);
|
||||||
|
void ApplySignalTrainAdaptationSpeed(Train *v, TileIndex tile, uint16 track);
|
||||||
|
|
||||||
#endif /* TRAIN_SPEED_ADAPTATION_H */
|
#endif /* TRAIN_SPEED_ADAPTATION_H */
|
||||||
|
Reference in New Issue
Block a user