Merge pull request #281 from VacuumBreather/train_speed_adaptation

# Conflicts:
#	src/saveload/extended_ver_sl.cpp
#	src/saveload/extended_ver_sl.h
pull/295/head
Jonathan G Rennison 3 years ago
commit 158608442c

@ -479,6 +479,7 @@ add_files(
train.h
train_cmd.cpp
train_gui.cpp
train_speed_adaptation.h
transparency.h
transparency_gui.cpp
transparency_gui.h

@ -39,6 +39,8 @@ YearMonthDay _game_load_cur_date_ymd;
DateFract _game_load_date_fract;
uint8 _game_load_tick_skip_counter;
extern void ClearOutOfDateSignalSpeedRestrictions();
/**
* Set the date.
* @param date New date
@ -283,6 +285,7 @@ static void OnNewDay()
SetWindowWidgetDirty(WC_STATUS_BAR, 0, WID_S_LEFT);
}
EnginesDailyLoop();
ClearOutOfDateSignalSpeedRestrictions();
/* Refresh after possible snowline change */
SetWindowClassesDirty(WC_TOWN_VIEW);

@ -1818,6 +1818,8 @@ STR_CONFIG_SETTING_NOSERVICE :Disable servici
STR_CONFIG_SETTING_NOSERVICE_HELPTEXT :When enabled, vehicles do not get serviced if they cannot break down
STR_CONFIG_SETTING_WAGONSPEEDLIMITS :Enable wagon speed limits: {STRING2}
STR_CONFIG_SETTING_WAGONSPEEDLIMITS_HELPTEXT :When enabled, also use speed limits of wagons for deciding the maximum speed of a train
STR_CONFIG_SETTING_TRAIN_SPEED_ADAPTATION :Enable train speed adaptation: {STRING2}
STR_CONFIG_SETTING_TRAIN_SPEED_ADAPTATION_HELPTEXT :When enabled, faster trains adjust their speed to match slower trains in front.
STR_CONFIG_SETTING_SLOW_ROAD_VEHICLES_IN_CURVES :Road vehicles slow down in curves: {STRING2}
STR_CONFIG_SETTING_SLOW_ROAD_VEHICLES_IN_CURVES_HELPTEXT :When enabled, road vehicles slow down in curves. (Only with realistic acceleration)
STR_CONFIG_SETTING_DISABLE_ELRAILS :Disable electric rails: {STRING2}

@ -1743,6 +1743,10 @@ STR_CONFIG_SETTING_NOSERVICE :Wartung deaktiv
STR_CONFIG_SETTING_NOSERVICE_HELPTEXT :Schicke Fahrzeuge nicht zur Wartung, wenn Pannen ausgeschaltet sind
STR_CONFIG_SETTING_WAGONSPEEDLIMITS :Berücksichtige Waggonhöchstgeschwindigkeit: {STRING}
STR_CONFIG_SETTING_WAGONSPEEDLIMITS_HELPTEXT :Begrenze die Höchstgeschwindigkeit eines Zuges durch die jeweiligen Höchstgeschwindigkeiten der mitgeführten Waggons
STR_CONFIG_SETTING_TRAIN_SPEED_ADAPTATION :Zuggeschwindigkeitsanpassung aktivieren: {STRING}
STR_CONFIG_SETTING_TRAIN_SPEED_ADAPTATION_HELPTEXT :Wenn aktiviert, passen schnellere Züge hinter langsameren Zügen ihre Geschwindigkeit an.
STR_CONFIG_SETTING_SLOW_ROAD_VEHICLES_IN_CURVES :Straßenfahrzeuge werden in Kurven langsamer: {STRING}
STR_CONFIG_SETTING_SLOW_ROAD_VEHICLES_IN_CURVES_HELPTEXT :Wenn aktiviert, verlangsamen Straßenfahrzeuge in Kurven. (Nur im Beschleunigungsmodell „Realistisch“)
STR_CONFIG_SETTING_DISABLE_ELRAILS :Deaktiviere elektrifizierte Strecken: {STRING}
STR_CONFIG_SETTING_DISABLE_ELRAILS_HELPTEXT :Erlaube Elektrolokomotiven das Fahren auf nicht elektrifizierten Gleisen

@ -43,6 +43,7 @@
extern TileIndex _cur_tileloop_tile;
extern void ClearAllSignalSpeedRestrictions();
extern void MakeNewgameSettingsLive();
void InitializeSound();
@ -118,6 +119,8 @@ void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settin
FreeSignalPrograms();
FreeSignalDependencies();
ClearAllSignalSpeedRestrictions();
ClearZoningCaches();
IntialiseOrderDestinationRefcountMap();

@ -439,6 +439,9 @@ static void ShutdownGame()
FreeSignalPrograms();
FreeSignalDependencies();
extern void ClearAllSignalSpeedRestrictions();
ClearAllSignalSpeedRestrictions();
ClearZoningCaches();
ClearOrderDestinationRefcountMap();

@ -48,6 +48,7 @@ add_files(
tbtr_template_veh_sl.cpp
town_sl.cpp
tracerestrict_sl.cpp
train_speed_adaptation.cpp
tunnel_sl.cpp
vehicle_sl.cpp
waypoint_sl.cpp

@ -938,6 +938,10 @@ bool AfterLoadGame()
_settings_game.vehicle.train_braking_model = TBM_ORIGINAL;
}
if (SlXvIsFeatureMissing(XSLFI_TRAIN_SPEED_ADAPTATION)) {
_settings_game.vehicle.train_speed_adaptation = false;
}
AfterLoadEngines();
/* Update all vehicles */

@ -152,6 +152,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
{ 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_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_NULL, XSCF_NULL, 0, 0, nullptr, nullptr, nullptr, nullptr },// This is the end marker
};

@ -106,6 +106,7 @@ enum SlXvFeatureIndex {
XSLFI_MORE_HOUSES, ///< More house types
XSLFI_CUSTOM_TOWN_ZONE, ///< Custom town zones
XSLFI_STATION_CARGO_HISTORY, ///< Station waiting cargo history
XSLFI_TRAIN_SPEED_ADAPTATION, ///< Train speed adaptation
XSLFI_RIFF_HEADER_60_BIT, ///< Size field in RIFF chunk header is 60 bit
XSLFI_HEIGHT_8_BIT, ///< Map tile height is 8 bit instead of 4 bit, but savegame version may be before this became true in trunk

@ -288,6 +288,7 @@ extern const ChunkHandler _template_replacement_chunk_handlers[];
extern const ChunkHandler _template_vehicle_chunk_handlers[];
extern const ChunkHandler _bridge_signal_chunk_handlers[];
extern const ChunkHandler _tunnel_chunk_handlers[];
extern const ChunkHandler _train_speed_adaptation_chunk_handlers[];
extern const ChunkHandler _debug_chunk_handlers[];
/** Array of all chunks in a savegame, \c nullptr terminated. */
@ -333,6 +334,7 @@ static const ChunkHandler * const _chunk_handlers[] = {
_template_vehicle_chunk_handlers,
_bridge_signal_chunk_handlers,
_tunnel_chunk_handlers,
_train_speed_adaptation_chunk_handlers,
_debug_chunk_handlers,
nullptr,
};

@ -0,0 +1,51 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file train_speed_adaptation.cpp Code handling saving and loading of data for train speed adaptation */
#include "../stdafx.h"
#include "../train_speed_adaptation.h"
#include "saveload.h"
using SignalSpeedType = std::pair<const SignalSpeedKey, SignalSpeedValue>;
static const SaveLoad _train_speed_adaptation_map_desc[] = {
SLE_VAR(SignalSpeedType, first.signal_track, SLE_UINT8),
SLE_VAR(SignalSpeedType, first.last_passing_train_dir, SLE_UINT8),
SLE_VAR(SignalSpeedType, second.train_speed, SLE_UINT16),
SLE_VAR(SignalSpeedType, second.time_stamp, SLE_UINT64),
SLE_END()
};
static void Load_TSAS()
{
int index;
SignalSpeedType data;
while ((index = SlIterateArray()) != -1) {
const_cast<SignalSpeedKey &>(data.first).signal_tile = index;
SlObject(&data, _train_speed_adaptation_map_desc);
_signal_speeds.insert(data);
}
}
static void RealSave_TSAS(SignalSpeedType *data)
{
SlObject(data, _train_speed_adaptation_map_desc);
}
static void Save_TSAS()
{
for (auto &it : _signal_speeds) {
SlSetArrayIndex(it.first.signal_tile);
SignalSpeedType *data = &it;
SlAutolength((AutolengthProc*) RealSave_TSAS, data);
}
}
extern const ChunkHandler _train_speed_adaptation_chunk_handlers[] = {
{ 'TSAS', Save_TSAS, Load_TSAS, nullptr, nullptr, CH_SPARSE_ARRAY | CH_LAST},
};

@ -807,6 +807,7 @@ const SaveLoad *GetVehicleDescription(VehicleType vt)
SLE_CONDNULL(11, SLV_2, SLV_144), // old reserved space
SLE_CONDVAR_X(Train, reverse_distance, SLE_UINT16, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_REVERSE_AT_WAYPOINT)),
SLE_CONDVAR_X(Train, speed_restriction, SLE_UINT16, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SPEED_RESTRICTION)),
SLE_CONDVAR_X(Train, signal_speed_restriction, SLE_UINT16, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TRAIN_SPEED_ADAPTATION)),
SLE_CONDVAR_X(Train, critical_breakdown_count, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_IMPROVED_BREAKDOWNS, 2)),
SLE_END()

@ -1541,6 +1541,15 @@ static bool PublicRoadsSettingChange(int32 p1) {
return true;
}
static bool TrainSpeedAdaptationChanged(int32 p1) {
extern void ClearAllSignalSpeedRestrictions();
ClearAllSignalSpeedRestrictions();
for (Train *t : Train::Iterate()) {
t->signal_speed_restriction = 0;
}
return true;
}
/** Checks if any settings are set to incorrect values, and sets them to correct values in that case. */
static void ValidateSettings()
{
@ -1784,7 +1793,12 @@ static bool ImprovedBreakdownsSettingChanged(int32 p1)
static bool DayLengthChanged(int32 p1)
{
const DateTicksScaled old_scaled_date_ticks = _scaled_date_ticks;
SetScaledTickVariables();
extern void AdjustAllSignalSpeedRestrictionTickValues(DateTicksScaled delta);
AdjustAllSignalSpeedRestrictionTickValues(_scaled_date_ticks - old_scaled_date_ticks);
MarkWholeScreenDirty();
return true;
}

@ -1924,6 +1924,7 @@ static SettingsContainer &GetSettingsTree()
physics->Add(new SettingEntry("vehicle.train_braking_model"));
physics->Add(new SettingEntry("vehicle.train_slope_steepness"));
physics->Add(new SettingEntry("vehicle.wagon_speed_limits"));
physics->Add(new SettingEntry("vehicle.train_speed_adaptation"));
physics->Add(new SettingEntry("vehicle.freight_trains"));
physics->Add(new SettingEntry("vehicle.roadveh_acceleration_model"));
physics->Add(new SettingEntry("vehicle.roadveh_slope_steepness"));

@ -573,6 +573,7 @@ struct VehicleSettings {
uint8 train_slope_steepness; ///< Steepness of hills for trains when using realistic acceleration
uint8 roadveh_slope_steepness; ///< Steepness of hills for road vehicles when using realistic acceleration
bool wagon_speed_limits; ///< enable wagon speed limits
bool train_speed_adaptation; ///< Faster trains slow down when behind slower trains
bool slow_road_vehicles_in_curves; ///< Road vehicles slow down in curves.
bool disable_elrails; ///< when true, the elrails are disabled
UnitID max_trains; ///< max trains in game per company

@ -162,8 +162,11 @@ class NIHVehicle : public NIHelper {
seprintf(buffer, lastof(buffer), " T cache: veh weight: %u, user data: %u, curve speed: %u",
t->tcache.cached_veh_weight, t->tcache.user_def_data, t->tcache.cached_max_curve_speed);
print(buffer);
seprintf(buffer, lastof(buffer), " Wait counter: %u, rev distance: %u, TBSN: %u, speed restriction: %u",
t->wait_counter, t->reverse_distance, t->tunnel_bridge_signal_num, t->speed_restriction);
seprintf(buffer, lastof(buffer), " Wait counter: %u, rev distance: %u, TBSN: %u",
t->wait_counter, t->reverse_distance, t->tunnel_bridge_signal_num);
print(buffer);
seprintf(buffer, lastof(buffer), " Speed restriction: %u, signal speed restriction (ATC): %u",
t->speed_restriction, t->signal_speed_restriction);
print(buffer);
seprintf(buffer, lastof(buffer), " Railtype: %u, compatible_railtypes: 0x" OTTD_PRINTFHEX64,
t->railtype, t->compatible_railtypes);

@ -64,6 +64,7 @@ static bool ClimateThresholdModeChanged(int32 p1);
static bool VelocityUnitsChanged(int32 p1);
static bool ChangeTrackTypeSortMode(int32 p1);
static bool PublicRoadsSettingChange(int32 p1);
static bool TrainSpeedAdaptationChanged(int32 p1);
static bool UpdateClientName(int32 p1);
static bool UpdateServerPassword(int32 p1);
@ -1675,10 +1676,19 @@ strhelp = STR_CONFIG_SETTING_SLOW_ROAD_VEHICLES_IN_CURVES_HELPTEXT
cat = SC_BASIC
patxname = ""slow_road_vehicles_in_curves.vehicle.slow_road_vehicles_in_curves""
;; vehicle.train_speed_adaption
[SDT_NULL]
length = 1
[SDT_XREF]
extver = SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP)
xref = ""vehicle.train_speed_adaptation""
[SDT_BOOL]
base = GameSettings
var = vehicle.train_speed_adaptation
def = false
str = STR_CONFIG_SETTING_TRAIN_SPEED_ADAPTATION
strhelp = STR_CONFIG_SETTING_TRAIN_SPEED_ADAPTATION_HELPTEXT
cat = SC_EXPERT
proc = TrainSpeedAdaptationChanged
patxname = ""train_speed_adaptation.vehicle.train_speed_adaptation""
[SDT_BOOL]
base = GameSettings

@ -147,6 +147,7 @@ struct Train FINAL : public GroundVehicle<Train, VEH_TRAIN> {
uint16 reverse_distance;
uint16 tunnel_bridge_signal_num;
uint16 speed_restriction;
uint16 signal_speed_restriction;
/** We don't want GCC to zero our struct! It already is zeroed and has an index! */
Train() : GroundVehicleBase() {}

@ -44,6 +44,7 @@
#include "scope.h"
#include "core/checksum_func.hpp"
#include "debug_settings.h"
#include "train_speed_adaptation.h"
#include "table/strings.h"
#include "table/train_cmd.h"
@ -76,6 +77,8 @@ enum ChooseTrainTrackFlags {
};
DECLARE_ENUM_AS_BIT_SET(ChooseTrainTrackFlags)
std::unordered_map<SignalSpeedKey, SignalSpeedValue, SignalSpeedKeyHashFunc> _signal_speeds(1 << 16);
static void TryLongReserveChooseTrainTrackFromReservationEnd(Train *v, bool no_reserve_vehicle_tile = false);
static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, ChooseTrainTrackFlags flags, bool *p_got_reservation, ChooseTrainTrackLookAheadState lookahead_state = {});
static bool TrainApproachingLineEnd(Train *v, bool signal, bool reverse);
@ -92,6 +95,52 @@ static void TrainEnterStation(Train *v, StationID station);
static void UnreserveBridgeTunnelTile(TileIndex tile);
static bool CheckTrainStayInWormHolePathReserve(Train *t, TileIndex tile);
/** Return the scaled date ticks by which the speed restriction
* at the current position of the train is going to be invalid */
static DateTicksScaled GetSpeedRestrictionTimeout(const Train *t)
{
const int64 velocity = std::max<int64>(25, t->cur_speed);
const int64 look_ahead_distance = Clamp(t->cur_speed / 8, 6, 16); // In tiles, varying between 6 and 16 depending on current speed
// This assumes travel along the X or Y map axis, not diagonally. See GetAdvanceDistance, GetAdvanceSpeed.
const int64 ticks_per_tile = (192 * 16 * 4 / 3) / velocity;
const int64 ticks = ticks_per_tile * look_ahead_distance;
return _scaled_date_ticks + ticks;
}
/** Checks if the timeout of the specified signal speed restriction value has passed */
static bool IsOutOfDate(const SignalSpeedValue& value)
{
return _scaled_date_ticks > value.time_stamp;
}
/** Removes all speed restrictions from all signals */
void ClearAllSignalSpeedRestrictions()
{
_signal_speeds.clear();
}
void AdjustAllSignalSpeedRestrictionTickValues(DateTicksScaled delta)
{
for (auto &it : _signal_speeds) {
it.second.time_stamp += delta;
}
}
/** Removes all speed restrictions which have passed their timeout from all signals */
void ClearOutOfDateSignalSpeedRestrictions()
{
for(auto key_value_pair = _signal_speeds.begin(); key_value_pair != _signal_speeds.end(); ) {
if (IsOutOfDate(key_value_pair->second)) {
key_value_pair = _signal_speeds.erase(key_value_pair);
} else {
++key_value_pair;
}
}
}
inline void ClearLookAheadIfInvalid(Train *v)
{
if (v->lookahead != nullptr && !ValidateLookAhead(v)) v->lookahead.reset();
@ -1024,6 +1073,9 @@ Train::MaxSpeedInfo Train::GetCurrentMaxSpeedInfoInternal(bool update_state) con
if (this->speed_restriction != 0) {
advisory_max_speed = std::min<int>(advisory_max_speed, this->speed_restriction);
}
if (this->signal_speed_restriction != 0 && _settings_game.vehicle.train_speed_adaptation) {
advisory_max_speed = std::min<int>(advisory_max_speed, this->signal_speed_restriction);
}
if (this->reverse_distance > 1) {
advisory_max_speed = std::min<int>(advisory_max_speed, ReversingDistanceTargetSpeed(this));
}
@ -1328,6 +1380,7 @@ static CommandCost CmdBuildRailWagon(TileIndex tile, DoCommandFlag flags, const
v->vehstatus = VS_HIDDEN | VS_DEFPAL;
v->reverse_distance = 0;
v->speed_restriction = 0;
v->signal_speed_restriction = 0;
v->SetWagon();
@ -4444,6 +4497,7 @@ static void TrainEnterStation(Train *v, StationID station)
v->current_order.MakeWaiting();
v->current_order.SetNonStopType(ONSF_NO_STOP_AT_ANY_STATION);
v->cur_speed = 0;
v->signal_speed_restriction = 0;
return;
}
@ -5500,7 +5554,33 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
}
if (update_signals_crossing) {
if (v->IsFrontEngine()) {
if (_settings_game.vehicle.train_speed_adaptation && IsTileType(gp.old_tile, MP_RAILWAY) && HasSignals(gp.old_tile)) {
const TrackdirBits rev_tracks = TrackBitsToTrackdirBits(GetTrackBits(gp.old_tile)) & DiagdirReachesTrackdirs(ReverseDiagDir(enterdir));
const Trackdir rev_trackdir = FindFirstTrackdir(rev_tracks);
if (HasSignalOnTrackdir(gp.old_tile, ReverseTrackdir(rev_trackdir))) {
const Track track = 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;
}
}
}
switch (TrainMovedChangeSignal(v, gp.new_tile, enterdir, true)) {
case CHANGED_NORMAL_TO_PBS_BLOCK:
/* We are entering a block with PBS signals right now, but
@ -5538,17 +5618,33 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
TrainMovedChangeSignal(v, gp.old_tile, ReverseDiagDir(enterdir), false);
if (IsLevelCrossingTile(gp.old_tile)) UpdateLevelCrossing(gp.old_tile);
if (IsTileType(gp.old_tile, MP_RAILWAY) && HasSignals(gp.old_tile) && IsRestrictedSignal(gp.old_tile)) {
if (IsTileType(gp.old_tile, MP_RAILWAY) && HasSignals(gp.old_tile)) {
const TrackdirBits rev_tracks = TrackBitsToTrackdirBits(GetTrackBits(gp.old_tile)) & DiagdirReachesTrackdirs(ReverseDiagDir(enterdir));
const Trackdir rev_trackdir = FindFirstTrackdir(rev_tracks);
const Track track = TrackdirToTrack(rev_trackdir);
if (_settings_game.vehicle.train_speed_adaptation && HasSignalOnTrackdir(gp.old_tile, ReverseTrackdir(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()
};
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)) {
const TraceRestrictProgram *prog = GetExistingTraceRestrictProgram(gp.old_tile, track);
if (prog && prog->actions_used_flags & TRPAUF_SLOT_RELEASE_BACK) {
TraceRestrictProgramResult out;
TraceRestrictProgramInput input(gp.old_tile, ReverseTrackdir(rev_trackdir), nullptr, nullptr);
input.permitted_slot_operations = TRPISP_RELEASE_BACK;
prog->Execute(first, input, out);
if (IsRestrictedSignal(gp.old_tile)) {
const TraceRestrictProgram *prog = GetExistingTraceRestrictProgram(gp.old_tile, track);
if (prog && prog->actions_used_flags & TRPAUF_SLOT_RELEASE_BACK) {
TraceRestrictProgramResult out;
TraceRestrictProgramInput input(gp.old_tile, ReverseTrackdir(rev_trackdir), nullptr, nullptr);
input.permitted_slot_operations = TRPISP_RELEASE_BACK;
prog->Execute(first, input, out);
}
}
}
}

@ -0,0 +1,53 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file train_speed_adaptation.h Train speed adaptation data structures. */
#ifndef TRAIN_SPEED_ADAPTATION_H
#define TRAIN_SPEED_ADAPTATION_H
#include "date_type.h"
#include "track_type.h"
#include "tile_type.h"
#include <unordered_map>
struct SignalSpeedKey
{
TileIndex signal_tile;
Track signal_track;
Trackdir last_passing_train_dir;
bool operator==(const SignalSpeedKey& other) const
{
return signal_tile == other.signal_tile &&
signal_track == other.signal_track &&
last_passing_train_dir == other.last_passing_train_dir;
}
};
struct SignalSpeedValue
{
uint16 train_speed;
DateTicksScaled time_stamp;
};
struct SignalSpeedKeyHashFunc
{
std::size_t operator() (const SignalSpeedKey &key) const
{
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 h3 = std::hash<Track>()(key.signal_track);
return (h1 ^ h2) ^ h3;
}
};
extern std::unordered_map<SignalSpeedKey, SignalSpeedValue, SignalSpeedKeyHashFunc> _signal_speeds;
#endif /* TRAIN_SPEED_ADAPTATION_H */

@ -2417,6 +2417,7 @@ void VehicleEnterDepot(Vehicle *v)
ClrBit(t->flags, VRF_TOGGLE_REVERSE);
t->ConsistChanged(CCF_ARRANGE);
t->reverse_distance = 0;
t->signal_speed_restriction = 0;
t->lookahead.reset();
if (!(t->vehstatus & VS_CRASHED)) {
t->crash_anim_pos = 0;
@ -4309,4 +4310,7 @@ void ShiftVehicleDates(int interval)
for (Vehicle *v : Vehicle::Iterate()) {
v->date_of_last_service += interval;
}
extern void AdjustAllSignalSpeedRestrictionTickValues(DateTicksScaled delta);
AdjustAllSignalSpeedRestrictionTickValues(interval * DAY_TICKS * _settings_game.economy.day_length_factor);
}

Loading…
Cancel
Save