(svn r16494) -Codechange: cache train's speed limit caused by curves

This commit is contained in:
smatz 2009-06-01 13:14:56 +00:00
parent 765c65b738
commit de25de7a60
3 changed files with 47 additions and 25 deletions

View File

@ -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;

View File

@ -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)

View File

@ -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: