Changeset - r12080:8115dddfc1a2
[Not reviewed]
master
0 3 0
smatz - 15 years ago 2009-06-01 13:14:56
smatz@openttd.org
(svn r16494) -Codechange: cache train's speed limit caused by curves
3 files changed with 47 insertions and 25 deletions:
0 comments (0 inline, 0 general)
src/settings.cpp
Show inline comments
 
@@ -735,7 +735,10 @@ static bool TrainAccelerationModelChange
 
{
 
	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;
src/train.h
Show inline comments
 
@@ -257,6 +257,7 @@ int GetTrainStopLocation(StationID stati
 

	
 
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)
src/train_cmd.cpp
Show inline comments
 
@@ -342,6 +342,7 @@ void TrainConsistChanged(Train *v, bool 
 
	/* 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 stati
 
	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
 
		}
 
	}
 

	
 
	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
 
		}
 
	}
 

	
 
	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 _rai
 
	{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(Veh
 

	
 
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, Ve
 
				 * 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, Ve
 
		/* 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:
0 comments (0 inline, 0 general)