summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsmatz <smatz@openttd.org>2009-06-01 13:14:56 +0000
committersmatz <smatz@openttd.org>2009-06-01 13:14:56 +0000
commitde25de7a60145d53d3faada9470d4f12589ab942 (patch)
tree2ccc3c4dc4df30dbb211b3bd75b37bfebf890620
parent765c65b738c3ec956aad5faaaa8fef388fe68ddf (diff)
downloadopenttd-de25de7a60145d53d3faada9470d4f12589ab942.tar.xz
(svn r16494) -Codechange: cache train's speed limit caused by curves
-rw-r--r--src/settings.cpp5
-rw-r--r--src/train.h6
-rw-r--r--src/train_cmd.cpp61
3 files changed, 47 insertions, 25 deletions
diff --git a/src/settings.cpp b/src/settings.cpp
index c842ff5fa..73606af18 100644
--- a/src/settings.cpp
+++ b/src/settings.cpp
@@ -735,7 +735,10 @@ static bool TrainAccelerationModelChanged(int32 p1)
{
Train *t;
FOR_ALL_TRAINS(t) {
- if (IsFrontEngine(t)) UpdateTrainAcceleration(t);
+ if (IsFrontEngine(t)) {
+ t->tcache.cached_max_curve_speed = GetTrainCurveSpeedLimit(t);
+ UpdateTrainAcceleration(t);
+ }
}
return true;
diff --git a/src/train.h b/src/train.h
index c1f9f120d..bcf005472 100644
--- a/src/train.h
+++ b/src/train.h
@@ -257,6 +257,7 @@ int GetTrainStopLocation(StationID station_id, TileIndex tile, const Train *v, i
void TrainConsistChanged(Train *v, bool same_length);
void TrainPowerChanged(Train *v);
+int GetTrainCurveSpeedLimit(Train *v);
Money GetTrainRunningCost(const Train *v);
/** Variables that are cached to improve performance and such */
@@ -268,7 +269,6 @@ struct TrainCache {
/* cached values, recalculated on load and each time a vehicle is added to/removed from the consist. */
uint32 cached_power; ///< total power of the consist.
- uint16 cached_max_speed; ///< max speed of the consist. (minimum of the max speed of all vehicles in the consist)
uint16 cached_total_length; ///< Length of the whole train, valid only for first engine.
uint8 cached_veh_length; ///< length of this vehicle in units of 1/8 of normal length, cached because this can be set by a callback
bool cached_tilt; ///< train can tilt; feature provides a bonus in curves
@@ -278,6 +278,10 @@ struct TrainCache {
uint32 cached_veh_weight; ///< weight of the vehicle.
uint32 cached_max_te; ///< max tractive effort of consist
+ /* cached max. speed / acceleration data */
+ uint16 cached_max_speed; ///< max speed of the consist. (minimum of the max speed of all vehicles in the consist)
+ int cached_max_curve_speed; ///< max consist speed limited by curves
+
/**
* Position/type of visual effect.
* bit 0 - 3 = position of effect relative to vehicle. (0 = front, 8 = centre, 15 = rear)
diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp
index eb75b2388..6ad8707c6 100644
--- a/src/train_cmd.cpp
+++ b/src/train_cmd.cpp
@@ -342,6 +342,7 @@ void TrainConsistChanged(Train *v, bool same_length)
/* store consist weight/max speed in cache */
v->tcache.cached_max_speed = max_speed;
v->tcache.cached_tilt = train_can_tilt;
+ v->tcache.cached_max_curve_speed = GetTrainCurveSpeedLimit(v);
/* recalculate cached weights and power too (we do this *after* the rest, so it is known which wagons are powered and need extra weight added) */
TrainCargoChanged(v);
@@ -406,12 +407,19 @@ int GetTrainStopLocation(StationID station_id, TileIndex tile, const Train *v, i
return stop - (v->tcache.cached_veh_length + 1) / 2;
}
-/** new acceleration*/
-static int GetTrainAcceleration(Train *v, bool mode)
+
+/**
+ * Computes train speed limit caused by curves
+ * @param v first vehicle of consist
+ * @return imposed speed limit
+ */
+int GetTrainCurveSpeedLimit(Train *v)
{
static const int absolute_max_speed = UINT16_MAX;
int max_speed = absolute_max_speed;
- int speed = v->cur_speed * 10 / 16; // km-ish/h -> mp/h
+
+ if (_settings_game.vehicle.train_acceleration_model == TAM_ORIGINAL) return max_speed;
+
int curvecount[2] = {0, 0};
/* first find the curve speed limit */
@@ -445,13 +453,11 @@ static int GetTrainAcceleration(Train *v, bool mode)
}
}
- if ((curvecount[0] != 0 || curvecount[1] != 0) && max_speed > 88) {
- int total = curvecount[0] + curvecount[1];
-
+ if (numcurve > 0 && max_speed > 88) {
if (curvecount[0] == 1 && curvecount[1] == 1) {
max_speed = absolute_max_speed;
- } else if (total > 1) {
- if (numcurve > 0) sum /= numcurve;
+ } else {
+ sum /= numcurve;
max_speed = 232 - (13 - Clamp(sum, 1, 12)) * (13 - Clamp(sum, 1, 12));
}
}
@@ -467,6 +473,16 @@ static int GetTrainAcceleration(Train *v, bool mode)
}
}
+ return max_speed;
+}
+
+/** new acceleration*/
+static int GetTrainAcceleration(Train *v, bool mode)
+{
+ int max_speed = v->tcache.cached_max_curve_speed;
+ assert(max_speed == GetTrainCurveSpeedLimit(v)); // safety check, will be removed later
+ int speed = v->cur_speed * 10 / 16; // km-ish/h -> mp/h
+
if (IsTileType(v->tile, MP_STATION) && IsFrontEngine(v)) {
StationID sid = GetStationIndex(v->tile);
if (v->current_order.ShouldStopAtStation(v, sid)) {
@@ -3425,18 +3441,6 @@ static const RailtypeSlowdownParams _railtype_slowdown[] = {
{0, 256 / 2, 256 / 4, 2}, ///< maglev
};
-/** Modify the speed of the vehicle due to a turn */
-static inline void AffectSpeedByDirChange(Train *v, Direction new_dir)
-{
- if (_settings_game.vehicle.train_acceleration_model != TAM_ORIGINAL) return;
-
- DirDiff diff = DirDifference(v->direction, new_dir);
- if (diff == DIRDIFF_SAME) return;
-
- const RailtypeSlowdownParams *rsp = &_railtype_slowdown[v->railtype];
- v->cur_speed -= (diff == DIRDIFF_45RIGHT || diff == DIRDIFF_45LEFT ? rsp->small_turn : rsp->large_turn) * v->cur_speed >> 8;
-}
-
/** Modify the speed of the vehicle due to a change in altitude */
static inline void AffectSpeedByZChange(Train *v, byte old_z)
{
@@ -3637,7 +3641,9 @@ static Vehicle *CheckVehicleAtSignal(Vehicle *v, void *data)
static void TrainController(Train *v, Vehicle *nomove)
{
+ Train *first = v->First();
Train *prev;
+ bool direction_changed = false; // has direction of any part changed?
/* For every vehicle after and including the given vehicle */
for (prev = v->Previous(); v != nomove; prev = v, v = v->Next()) {
@@ -3817,9 +3823,15 @@ static void TrainController(Train *v, Vehicle *nomove)
* has been updated by AfterSetTrainPos() */
update_signals_crossing = true;
- if (prev == NULL) AffectSpeedByDirChange(v, chosen_dir);
-
- v->direction = chosen_dir;
+ if (chosen_dir != v->direction) {
+ if (prev == NULL && _settings_game.vehicle.train_acceleration_model == TAM_ORIGINAL) {
+ const RailtypeSlowdownParams *rsp = &_railtype_slowdown[v->railtype];
+ DirDiff diff = DirDifference(v->direction, chosen_dir);
+ v->cur_speed -= (diff == DIRDIFF_45RIGHT || diff == DIRDIFF_45LEFT ? rsp->small_turn : rsp->large_turn) * v->cur_speed >> 8;
+ }
+ direction_changed = true;
+ v->direction = chosen_dir;
+ }
if (IsFrontEngine(v)) {
v->load_unload_time_rem = 0;
@@ -3904,6 +3916,9 @@ static void TrainController(Train *v, Vehicle *nomove)
/* Do not check on every tick to save some computing time. */
if (IsFrontEngine(v) && v->tick_counter % _settings_game.pf.path_backoff_interval == 0) CheckNextTrainTile(v);
}
+
+ if (direction_changed) first->tcache.cached_max_curve_speed = GetTrainCurveSpeedLimit(first);
+
return;
invalid_rail: