diff --git a/src/lang/english.txt b/src/lang/english.txt index d9135289a7..9573530567 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -1366,6 +1366,10 @@ STR_CONFIG_SETTING_PERCENTAGE :{COMMA}% STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS :Slope steepness for road vehicles: {STRING2} STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS_HELPTEXT :Steepness of a sloped tile for a road vehicle. Higher values make it more difficult to climb a hill +STR_CONFIG_SETTING_THROUGH_LOAD_SPEED_LIMIT :Through load maximum speed: {STRING2} +STR_CONFIG_SETTING_THROUGH_LOAD_SPEED_LIMIT_HELPTEXT :The maximum allowable speed for through load trains +STR_CONFIG_SETTING_THROUGH_LOAD_SPEED_LIMIT_VAL :{VELOCITY} + STR_CONFIG_SETTING_FORBID_90_DEG :Forbid trains from making 90° turns: {STRING2} STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :90 degree turns occur when a horizontal track is directly followed by a vertical track piece on the adjacent tile, thus making the train turn by 90 degree when traversing the tile edge instead of the usual 45 degrees for other track combinations. STR_CONFIG_SETTING_BACK_ONE_WAY_PBS_SAFE_WAITING :Pathfind up to back of one-way path signals: {STRING2} diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index b34c9da9d7..056330e499 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -3995,6 +3995,10 @@ bool AfterLoadGame() _settings_game.station.station_delivery_mode = SD_NEAREST_FIRST; } + if (SlXvIsFeatureMissing(XSLFI_TL_SPEED_LIMIT)) { + _settings_game.vehicle.through_load_speed_limit = 15; + } + InitializeRoadGUI(); /* This needs to be done after conversion. */ diff --git a/src/saveload/extended_ver_sl.cpp b/src/saveload/extended_ver_sl.cpp index 607ca31c5e..3495637b40 100644 --- a/src/saveload/extended_ver_sl.cpp +++ b/src/saveload/extended_ver_sl.cpp @@ -163,6 +163,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = { { XSLFI_LINKGRAPH_AIRCRAFT, XSCF_NULL, 1, 1, "linkgraph_aircraft", nullptr, nullptr, nullptr }, { XSLFI_COMPANY_PW, XSCF_IGNORABLE_ALL, 1, 1, "company_password", nullptr, nullptr, "PLYP" }, { XSLFI_ST_INDUSTRY_CARGO_MODE, XSCF_IGNORABLE_UNKNOWN, 1, 1, "st_industry_cargo_mode", nullptr, nullptr, nullptr }, + { XSLFI_TL_SPEED_LIMIT, XSCF_IGNORABLE_UNKNOWN, 1, 1, "tl_speed_limit", nullptr, nullptr, nullptr }, { XSLFI_SCRIPT_INT64, XSCF_NULL, 1, 1, "script_int64", nullptr, nullptr, nullptr }, { XSLFI_NULL, XSCF_NULL, 0, 0, nullptr, nullptr, nullptr, nullptr },// This is the end marker }; diff --git a/src/saveload/extended_ver_sl.h b/src/saveload/extended_ver_sl.h index 2900a10507..63a6adf2d6 100644 --- a/src/saveload/extended_ver_sl.h +++ b/src/saveload/extended_ver_sl.h @@ -117,6 +117,7 @@ enum SlXvFeatureIndex { XSLFI_LINKGRAPH_AIRCRAFT, ///< Link graph last aircraft update field and aircraft link scaling setting XSLFI_COMPANY_PW, ///< Company passwords XSLFI_ST_INDUSTRY_CARGO_MODE, ///< Station industry cargo mode setting + XSLFI_TL_SPEED_LIMIT, ///< Through load maximum speed setting XSLFI_SCRIPT_INT64, ///< See: SLV_SCRIPT_INT64 diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index 2f6a129cd8..f20d8f3db5 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -2059,6 +2059,7 @@ static SettingsContainer &GetSettingsTree() limitations->Add(new SettingEntry("vehicle.max_aircraft")); limitations->Add(new SettingEntry("vehicle.max_ships")); limitations->Add(new SettingEntry("vehicle.max_train_length")); + limitations->Add(new SettingEntry("vehicle.through_load_speed_limit")); limitations->Add(new SettingEntry("station.station_spread")); limitations->Add(new SettingEntry("station.distant_join_stations")); limitations->Add(new SettingEntry("construction.road_stop_on_town_road")); diff --git a/src/settings_type.h b/src/settings_type.h index 3ee54e9f58..302088da7d 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -626,6 +626,7 @@ struct VehicleSettings { bool roadveh_articulated_overtaking; ///< enable articulated road vehicles overtaking other vehicles bool roadveh_cant_quantum_tunnel; ///< enable or disable vehicles quantum tunelling through over vehicles when blocked bool drive_through_train_depot; ///< enable drive-through train depot emulation + uint16 through_load_speed_limit; ///< maximum speed for through load }; /** Settings related to the economy. */ diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 5952dd5387..20513663a5 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -3686,7 +3686,7 @@ static VehicleEnterTileStatus VehicleEnter_Station(Vehicle *v, TileIndex tile, i int station_ahead; int station_length; - int stop = GetTrainStopLocation(station_id, tile, Train::From(v), true, &station_ahead, &station_length, x, y); + int stop = GetTrainStopLocation(station_id, tile, Train::From(v), true, &station_ahead, &station_length); /* Stop whenever that amount of station ahead + the distance from the * begin of the platform to the stop location is longer than the length @@ -3722,7 +3722,7 @@ static VehicleEnterTileStatus VehicleEnter_Station(Vehicle *v, TileIndex tile, i } return VETSB_ENTERED_STATION | (VehicleEnterTileStatus)(station_id << VETS_STATION_ID_OFFSET); // enter station } else if (x < stop) { - if (front->UsingRealisticBraking()&& front->cur_speed > 30) { + if (front->UsingRealisticBraking() && front->cur_speed > 30) { /* Travelling too fast, take no action */ return VETSB_CONTINUE; } diff --git a/src/table/settings/settings.ini b/src/table/settings/settings.ini index 5bd847d04f..2837e7790d 100644 --- a/src/table/settings/settings.ini +++ b/src/table/settings/settings.ini @@ -1355,6 +1355,19 @@ strval = STR_CONFIG_SETTING_PERCENTAGE post_cb = RoadVehSlopeSteepnessChanged cat = SC_EXPERT +[SDT_VAR] +var = vehicle.through_load_speed_limit +type = SLE_UINT16 +def = 15 +min = 15 +max = 65535 +interval = 5 +str = STR_CONFIG_SETTING_THROUGH_LOAD_SPEED_LIMIT +strhelp = STR_CONFIG_SETTING_THROUGH_LOAD_SPEED_LIMIT_HELPTEXT +strval = STR_CONFIG_SETTING_THROUGH_LOAD_SPEED_LIMIT_VAL +cat = SC_EXPERT +patxname = ""vehicle.through_load_speed_limit"" + [SDT_BOOL] var = pf.forbid_90_deg def = false diff --git a/src/train.h b/src/train.h index c50b52b9d3..f6b6c551c2 100644 --- a/src/train.h +++ b/src/train.h @@ -507,12 +507,7 @@ inline int GetTileMarginInFrontOfTrain(const Train *v) return GetTileMarginInFrontOfTrain(v, v->x_pos, v->y_pos); } -int GetTrainStopLocation(StationID station_id, TileIndex tile, Train *v, bool update_train_state, int *station_ahead, int *station_length, int x_pos, int y_pos); - -inline int GetTrainStopLocation(StationID station_id, TileIndex tile, Train *v, bool update_train_state, int *station_ahead, int *station_length) -{ - return GetTrainStopLocation(station_id, tile, v, update_train_state, station_ahead, station_length, v->x_pos, v->y_pos); -} +int GetTrainStopLocation(StationID station_id, TileIndex tile, Train *v, bool update_train_state, int *station_ahead, int *station_length); int GetTrainRealisticAccelerationAtSpeed(const int speed, const int mass, const uint32 cached_power, const uint32 max_te, const uint32 air_drag, const RailType railtype); int GetTrainEstimatedMaxAchievableSpeed(const Train *train, const int mass, const int speed_cap); diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 6ae751d07c..2d380d1eff 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -472,11 +472,9 @@ int GetTileMarginInFrontOfTrain(const Train *v, int x_pos, int y_pos) * @param update_train_state whether the state of the train v may be changed * @param station_ahead 'return' the amount of 1/16th tiles in front of the train * @param station_length 'return' the station length in 1/16th tiles - * @param x_pos vehicle x position - * @param y_pos vehicle y position * @return the location, calculated from the begin of the station to stop at. */ -int GetTrainStopLocation(StationID station_id, TileIndex tile, Train *v, bool update_train_state, int *station_ahead, int *station_length, int x_pos, int y_pos) +int GetTrainStopLocation(StationID station_id, TileIndex tile, Train *v, bool update_train_state, int *station_ahead, int *station_length) { Train *front = v->First(); if (IsRailWaypoint(tile)) { @@ -747,27 +745,15 @@ int PredictStationStoppingLocation(const Train *v, const Order *order, int stati } } if (osl == OSL_PLATFORM_THROUGH && overhang > 0) { - /* The train is longer than the station, and we can run through the station to load/unload */ - for (const Train *u = v; u != nullptr; u = u->Next()) { - if (overhang > 0 && !u->IsArticulatedPart()) { - bool skip = true; - for (const Train *part = u; part != nullptr; part = part->HasArticulatedPart() ? part->GetNextArticulatedPart() : nullptr) { - if (part->cargo_cap != 0) { - skip = false; - break; - } - } - if (skip) { - for (const Train *part = u; part != nullptr; part = part->HasArticulatedPart() ? part->GetNextArticulatedPart() : nullptr) { - overhang -= part->gcache.cached_veh_length; - adjust += part->gcache.cached_veh_length; - } - continue; - } - } - break; + /* Compute how much of the train should stop beyond the station */ + int beyond = 0; + for(const Train *u = v ;u != nullptr && HasBit(u->flags, VRF_BEYOND_PLATFORM_END); u = u->Next()) { + beyond += u->gcache.cached_veh_length; } - if (overhang < 0) adjust += overhang; + /* Adjust for the remaining amount of train being less than the station length */ + int overshoot = station_length - std::min(v->gcache.cached_total_length - beyond, station_length); + /* Move the estimated stopping position a bit closer to limit the approach speed */ + adjust = beyond - overshoot - 4; } else if (overhang >= 0) { /* The train is longer than the station, make it stop at the far end of the platform */ osl = OSL_PLATFORM_FAR_END; @@ -1016,7 +1002,7 @@ Train::MaxSpeedInfo Train::GetCurrentMaxSpeedInfoInternal(bool update_state) con this->gcache.cached_max_track_speed : std::min(this->tcache.cached_max_curve_speed, this->gcache.cached_max_track_speed); - if (this->current_order.IsType(OT_LOADING_ADVANCE)) max_speed = std::min(max_speed, 15); + if (this->current_order.IsType(OT_LOADING_ADVANCE)) max_speed = std::min(max_speed, _settings_game.vehicle.through_load_speed_limit); int advisory_max_speed = max_speed;