diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index 1548e11bb5..2ec1d4c04a 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -3582,10 +3582,13 @@ static VehicleEnterTileStatus VehicleEnter_Track(Vehicle *u, TileIndex tile, int if (DiagDirToDir(ReverseDiagDir(dir)) == v->direction) { /* enter the depot */ - if (v->IsFrontEngine() && v->current_order.IsType(OT_LOADING_ADVANCE)) { - abort_load_through(true); - } else if (v->IsFrontEngine() && HasBit(v->flags, VRF_BEYOND_PLATFORM_END)) { - abort_load_through(false); + if (v->IsFrontEngine()) { + if (v->current_order.IsType(OT_LOADING_ADVANCE)) { + abort_load_through(true); + } else if (HasBit(v->flags, VRF_BEYOND_PLATFORM_END)) { + abort_load_through(false); + } + SetBit(v->flags, VRF_CONSIST_SPEED_REDUCTION); } v->track = TRACK_BIT_DEPOT, diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index d800986f7e..2f6ad4e882 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -3588,6 +3588,15 @@ bool AfterLoadGame() } } + if (SlXvIsFeatureMissing(XSLFI_CONSIST_SPEED_RD_FLAG)) { + Train *t; + FOR_ALL_TRAINS(t) { + if ((t->track & TRACK_BIT_WORMHOLE && !(t->vehstatus & VS_HIDDEN)) || t->track == TRACK_BIT_DEPOT) { + SetBit(t->First()->flags, VRF_CONSIST_SPEED_REDUCTION); + } + } + } + /* Road stops is 'only' updating some caches */ AfterLoadRoadStops(); AfterLoadLabelMaps(); diff --git a/src/saveload/extended_ver_sl.cpp b/src/saveload/extended_ver_sl.cpp index ba98de918a..827c369359 100644 --- a/src/saveload/extended_ver_sl.cpp +++ b/src/saveload/extended_ver_sl.cpp @@ -92,6 +92,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = { { XSLFI_SELL_AT_DEPOT_ORDER, XSCF_NULL, 1, 1, "sell_at_depot_order", NULL, NULL, NULL }, { XSLFI_BUY_LAND_RATE_LIMIT, XSCF_NULL, 1, 1, "buy_land_rate_limit", NULL, NULL, NULL }, { XSLFI_DUAL_RAIL_TYPES, XSCF_NULL, 1, 1, "dual_rail_types", NULL, NULL, NULL }, + { XSLFI_CONSIST_SPEED_RD_FLAG, XSCF_NULL, 1, 1, "consist_speed_rd_flag", NULL, NULL, NULL }, { XSLFI_NULL, XSCF_NULL, 0, 0, NULL, NULL, NULL, NULL },// This is the end marker }; diff --git a/src/saveload/extended_ver_sl.h b/src/saveload/extended_ver_sl.h index f7e193a1bc..41d2c58320 100644 --- a/src/saveload/extended_ver_sl.h +++ b/src/saveload/extended_ver_sl.h @@ -66,6 +66,7 @@ enum SlXvFeatureIndex { XSLFI_SELL_AT_DEPOT_ORDER, ///< Sell vehicle on arrival at depot orders XSLFI_BUY_LAND_RATE_LIMIT, ///< Buy land rate limit XSLFI_DUAL_RAIL_TYPES, ///< Two rail-types per tile + XSLFI_CONSIST_SPEED_RD_FLAG, ///< Consist speed reduction flag 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 diff --git a/src/train.h b/src/train.h index ed9242caab..2c865ad3e3 100644 --- a/src/train.h +++ b/src/train.h @@ -45,6 +45,7 @@ enum VehicleRailFlags { VRF_NOT_YET_IN_PLATFORM = 17, VRF_ADVANCE_IN_PLATFORM = 18, VRF_CONSIST_BREAKDOWN = 19,///< one or more vehicles in this consist have a breakdown of some sort (breakdown_ctr != 0) + VRF_CONSIST_SPEED_REDUCTION = 20,///< one or more vehicles in this consist may be in a depot or on a bridge (may be false positive but not false negative) VRF_IS_BROKEN = (1 << VRF_BREAKDOWN_POWER) | (1 << VRF_BREAKDOWN_SPEED) | (1 << VRF_BREAKDOWN_STOPPED), ///< Bitmask of all flags that indicate a broken train (braking is not included) }; diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 8ea25b8564..8afff5d67b 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -591,15 +591,22 @@ int Train::GetCurrentMaxSpeed() const } } - for (const Train *u = this; u != NULL; u = u->Next()) { - if (_settings_game.vehicle.train_acceleration_model == AM_REALISTIC && u->track == TRACK_BIT_DEPOT) { - max_speed = min(max_speed, 61); - break; - } + if (HasBit(this->flags, VRF_CONSIST_SPEED_REDUCTION)) { + ClrBit(const_cast(this)->flags, VRF_CONSIST_SPEED_REDUCTION); + for (const Train *u = this; u != NULL; u = u->Next()) { + if (u->track == TRACK_BIT_DEPOT) { + SetBit(const_cast(this)->flags, VRF_CONSIST_SPEED_REDUCTION); + if (_settings_game.vehicle.train_acceleration_model == AM_REALISTIC) { + max_speed = min(max_speed, 61); + } + continue; + } - /* Vehicle is on the middle part of a bridge. */ - if (u->track & TRACK_BIT_WORMHOLE && !(u->vehstatus & VS_HIDDEN)) { - max_speed = min(max_speed, GetBridgeSpec(GetBridgeType(u->tile))->speed); + /* Vehicle is on the middle part of a bridge. */ + if (u->track & TRACK_BIT_WORMHOLE && !(u->vehstatus & VS_HIDDEN)) { + SetBit(const_cast(this)->flags, VRF_CONSIST_SPEED_REDUCTION); + max_speed = min(max_speed, GetBridgeSpec(GetBridgeType(u->tile))->speed); + } } } @@ -945,6 +952,7 @@ CommandCost CmdBuildRailVehicle(TileIndex tile, DoCommandFlag flags, const Engin v->y_pos = y; v->z_pos = GetSlopePixelZ(x, y); v->track = TRACK_BIT_DEPOT; + SetBit(v->flags, VRF_CONSIST_SPEED_REDUCTION); v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL; v->spritenum = rvi->image_index; v->cargo_type = e->GetDefaultCargoType(); @@ -5167,6 +5175,7 @@ Train* CmdBuildVirtualRailWagon(const Engine *e) v->owner = _current_company; v->track = TRACK_BIT_DEPOT; + SetBit(v->flags, VRF_CONSIST_SPEED_REDUCTION); v->vehstatus = VS_HIDDEN | VS_DEFPAL; v->SetWagon(); @@ -5238,6 +5247,7 @@ Train* CmdBuildVirtualRailVehicle(EngineID eid, bool lax_engine_check, StringID v->tile = 0; // INVALID_TILE; v->owner = _current_company; v->track = TRACK_BIT_DEPOT; + SetBit(v->flags, VRF_CONSIST_SPEED_REDUCTION); v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL; v->spritenum = rvi->image_index; v->cargo_type = e->GetDefaultCargoType(); diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index 2047174a66..b172a965c7 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -2470,6 +2470,7 @@ static VehicleEnterTileStatus VehicleEnter_TunnelBridge(Vehicle *v, TileIndex ti if (frame != TILE_SIZE) return VETSB_CONTINUE; Train *t = Train::From(v); t->track = TRACK_BIT_WORMHOLE; + SetBit(t->First()->flags, VRF_CONSIST_SPEED_REDUCTION); ClrBit(t->gv_flags, GVF_GOINGUP_BIT); ClrBit(t->gv_flags, GVF_GOINGDOWN_BIT); break; @@ -2557,6 +2558,7 @@ static VehicleEnterTileStatus VehicleEnter_TunnelBridge(Vehicle *v, TileIndex ti t->direction = bridge_dir; t->track = TRACK_BIT_WORMHOLE; } + SetBit(t->First()->flags, VRF_CONSIST_SPEED_REDUCTION); ClrBit(t->gv_flags, GVF_GOINGUP_BIT); ClrBit(t->gv_flags, GVF_GOINGDOWN_BIT); return VETSB_ENTERED_WORMHOLE;