Add feature: realistic train braking
Add setting to select train braking model.
This commit is contained in:
@@ -68,6 +68,8 @@
|
||||
#include "string_func.h"
|
||||
#include "debug.h"
|
||||
#include "zoning.h"
|
||||
#include "vehicle_func.h"
|
||||
#include "scope_info.h"
|
||||
|
||||
#include "void_map.h"
|
||||
#include "station_base.h"
|
||||
@@ -958,7 +960,10 @@ static bool UpdateConsists(int32 p1)
|
||||
{
|
||||
for (Train *t : Train::Iterate()) {
|
||||
/* Update the consist of all trains so the maximum speed is set correctly. */
|
||||
if (t->IsFrontEngine() || t->IsFreeWagon()) t->ConsistChanged(CCF_TRACK);
|
||||
if (t->IsFrontEngine() || t->IsFreeWagon()) {
|
||||
t->ConsistChanged(CCF_TRACK);
|
||||
if (t->lookahead != nullptr) SetBit(t->lookahead->flags, TRLF_APPLY_ADVISORY);
|
||||
}
|
||||
}
|
||||
InvalidateWindowClassesData(WC_BUILD_VEHICLE, 0);
|
||||
return true;
|
||||
@@ -1059,6 +1064,7 @@ static bool TrainAccelerationModelChanged(int32 p1)
|
||||
if (t->IsFrontEngine()) {
|
||||
t->tcache.cached_max_curve_speed = t->GetCurveSpeedLimit();
|
||||
t->UpdateAcceleration();
|
||||
if (t->lookahead != nullptr) SetBit(t->lookahead->flags, TRLF_APPLY_ADVISORY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1070,6 +1076,86 @@ static bool TrainAccelerationModelChanged(int32 p1)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool TrainBrakingModelChanged(int32 p1)
|
||||
{
|
||||
for (Train *t : Train::Iterate()) {
|
||||
if (t->IsFrontEngine()) {
|
||||
t->UpdateAcceleration();
|
||||
}
|
||||
}
|
||||
if (p1 == TBM_REALISTIC && (_game_mode == GM_NORMAL || _game_mode == GM_EDITOR)) {
|
||||
for (TileIndex t = 0; t < MapSize(); t++) {
|
||||
if (IsTileType(t, MP_RAILWAY) && GetRailTileType(t) == RAIL_TILE_SIGNALS) {
|
||||
uint signals = GetPresentSignals(t);
|
||||
if ((signals & 0x3) & ((signals & 0x3) - 1) || (signals & 0xC) & ((signals & 0xC) - 1)) {
|
||||
/* Signals in both directions */
|
||||
ShowErrorMessage(STR_CONFIG_SETTING_REALISTIC_BRAKING_SIGNALS_NOT_ALLOWED, INVALID_STRING_ID, WL_ERROR);
|
||||
return false;
|
||||
}
|
||||
if (((signals & 0x3) && IsSignalTypeUnsuitableForRealisticBraking(GetSignalType(t, TRACK_LOWER))) ||
|
||||
((signals & 0xC) && IsSignalTypeUnsuitableForRealisticBraking(GetSignalType(t, TRACK_UPPER)))) {
|
||||
/* Banned signal types present */
|
||||
ShowErrorMessage(STR_CONFIG_SETTING_REALISTIC_BRAKING_SIGNALS_NOT_ALLOWED, INVALID_STRING_ID, WL_ERROR);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (TileIndex t = 0; t < MapSize(); t++) {
|
||||
if (IsTileType(t, MP_RAILWAY) && GetRailTileType(t) == RAIL_TILE_SIGNALS) {
|
||||
TrackBits bits = GetTrackBits(t);
|
||||
do {
|
||||
Track track = RemoveFirstTrack(&bits);
|
||||
if (HasSignalOnTrack(t, track) && GetSignalType(t, track) == SIGTYPE_NORMAL && HasBit(GetRailReservationTrackBits(t), track)) {
|
||||
if (EnsureNoTrainOnTrackBits(t, TrackToTrackBits(track)).Succeeded()) {
|
||||
UnreserveTrack(t, track);
|
||||
}
|
||||
}
|
||||
} while (bits != TRACK_BIT_NONE);
|
||||
}
|
||||
}
|
||||
Train *v_cur = nullptr;
|
||||
SCOPE_INFO_FMT([&v_cur], "TrainBrakingModelChanged: %s", scope_dumper().VehicleInfo(v_cur));
|
||||
extern bool _long_reserve_disabled;
|
||||
_long_reserve_disabled = true;
|
||||
for (Train *v : Train::Iterate()) {
|
||||
v_cur = v;
|
||||
if (!v->IsPrimaryVehicle() || (v->vehstatus & VS_CRASHED) != 0 || HasBit(v->subtype, GVSF_VIRTUAL) || v->track == TRACK_BIT_DEPOT) continue;
|
||||
TryPathReserve(v, v->current_order.GetType() != OT_LOADING, HasStationTileRail(v->tile));
|
||||
}
|
||||
_long_reserve_disabled = false;
|
||||
for (Train *v : Train::Iterate()) {
|
||||
v_cur = v;
|
||||
if (!v->IsPrimaryVehicle() || (v->vehstatus & VS_CRASHED) != 0 || HasBit(v->subtype, GVSF_VIRTUAL) || v->track == TRACK_BIT_DEPOT) continue;
|
||||
TryPathReserve(v, v->current_order.GetType() != OT_LOADING, HasStationTileRail(v->tile));
|
||||
if (v->lookahead != nullptr) SetBit(v->lookahead->flags, TRLF_APPLY_ADVISORY);
|
||||
}
|
||||
} else if (p1 == TBM_ORIGINAL && (_game_mode == GM_NORMAL || _game_mode == GM_EDITOR)) {
|
||||
Train *v_cur = nullptr;
|
||||
SCOPE_INFO_FMT([&v_cur], "TrainBrakingModelChanged: %s", scope_dumper().VehicleInfo(v_cur));
|
||||
for (Train *v : Train::Iterate()) {
|
||||
v_cur = v;
|
||||
if (!v->IsPrimaryVehicle() || (v->vehstatus & VS_CRASHED) != 0 || HasBit(v->subtype, GVSF_VIRTUAL) || v->track == TRACK_BIT_DEPOT) {
|
||||
v->lookahead.reset();
|
||||
continue;
|
||||
}
|
||||
if (!HasBit(v->flags, VRF_TRAIN_STUCK)) {
|
||||
_settings_game.vehicle.train_braking_model = TBM_REALISTIC;
|
||||
FreeTrainTrackReservation(v);
|
||||
_settings_game.vehicle.train_braking_model = p1;
|
||||
TryPathReserve(v, v->current_order.GetType() != OT_LOADING, HasStationTileRail(v->tile));
|
||||
} else {
|
||||
v->lookahead.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UpdateAllBlockSignals();
|
||||
|
||||
InvalidateWindowData(WC_BUILD_SIGNAL, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function updates the train acceleration cache after a steepness change.
|
||||
* @param p1 Callback parameter.
|
||||
@@ -1078,7 +1164,10 @@ static bool TrainAccelerationModelChanged(int32 p1)
|
||||
static bool TrainSlopeSteepnessChanged(int32 p1)
|
||||
{
|
||||
for (Train *t : Train::Iterate()) {
|
||||
if (t->IsFrontEngine()) t->CargoChanged();
|
||||
if (t->IsFrontEngine()) {
|
||||
t->CargoChanged();
|
||||
if (t->lookahead != nullptr) SetBit(t->lookahead->flags, TRLF_APPLY_ADVISORY);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
Reference in New Issue
Block a user