Changeset - r11689:154feeb8fd54
[Not reviewed]
master
0 2 0
rubidium - 15 years ago 2009-04-18 13:43:05
rubidium@openttd.org
(svn r16079) -Fix [FS#2824]: insanely fast trains would not stop in time for stations
-Fix: insanely fast trains would sometimes 'jump' over waypoints/via stations within a tick, which would cause the order not to be processed causing the train to go in loops until (with luck) it 'hit' the tile
2 files changed with 18 insertions and 2 deletions:
0 comments (0 inline, 0 general)
src/train_cmd.cpp
Show inline comments
 
@@ -4354,52 +4354,67 @@ static void TrainLocoHandler(Vehicle *v,
 

	
 
	if (v->current_order.IsType(OT_LEAVESTATION)) {
 
		v->current_order.Free();
 
		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
		return;
 
	}
 

	
 
	int j = UpdateTrainSpeed(v);
 

	
 
	/* we need to invalidate the widget if we are stopping from 'Stopping 0 km/h' to 'Stopped' */
 
	if (v->cur_speed == 0 && v->u.rail.last_speed == 0 && v->vehstatus & VS_STOPPED) {
 
		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
	}
 

	
 
	int adv_spd = (v->direction & 1) ? 192 : 256;
 
	if (j < adv_spd) {
 
		/* if the vehicle has speed 0, update the last_speed field. */
 
		if (v->cur_speed == 0) SetLastSpeed(v, v->cur_speed);
 
	} else {
 
		TrainCheckIfLineEnds(v);
 
		/* Loop until the train has finished moving. */
 
		do {
 
			j -= adv_spd;
 
			TrainController(v, NULL);
 
			/* Don't continue to move if the train crashed. */
 
			if (CheckTrainCollision(v)) break;
 

	
 
			/* 192 spd used for going straight, 256 for going diagonally. */
 
			adv_spd = (v->direction & 1) ? 192 : 256;
 

	
 
			if (j >= adv_spd) {
 
				/* Don't continue to move if the train crashed or isn't moving. */
 
				if (CheckTrainCollision(v) || v->cur_speed == 0) break;
 

	
 
				OrderType order_type = v->current_order.GetType();
 
				/* Do not skip waypoints (incl. 'via' stations) when passing through at full speed. */
 
				if ((order_type == OT_GOTO_WAYPOINT &&
 
							v->dest_tile == v->tile) ||
 
						(order_type == OT_GOTO_STATION &&
 
							(v->current_order.GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) &&
 
							IsTileType(v->tile, MP_STATION) &&
 
							v->current_order.GetDestination() == GetStationIndex(v->tile))) {
 
					ProcessOrders(v);
 
				}
 
			}
 
		} while (j >= adv_spd);
 
		SetLastSpeed(v, v->cur_speed);
 
	}
 

	
 
	for (Vehicle *u = v; u != NULL; u = u->Next()) {
 
		if ((u->vehstatus & VS_HIDDEN) != 0) continue;
 

	
 
		uint16 old_image = u->cur_image;
 
		u->cur_image = u->GetImage(u->direction);
 
		if (old_image != u->cur_image) VehicleMove(u, true);
 
	}
 

	
 
	if (v->progress == 0) v->progress = j; // Save unused spd for next time, if TrainController didn't set progress
 
}
 

	
 

	
 

	
 
Money Train::GetRunningCost() const
 
{
 
	Money cost = 0;
 
	const Vehicle *v = this;
 

	
 
	do {
 
		const RailVehicleInfo *rvi = RailVehInfo(v->engine_type);
src/vehicle.cpp
Show inline comments
 
@@ -1493,48 +1493,49 @@ void Vehicle::BeginLoading()
 
		current_order.MakeLoading(true);
 
		UpdateVehicleTimetable(this, true);
 

	
 
		/* Furthermore add the Non Stop flag to mark that this station
 
		 * is the actual destination of the vehicle, which is (for example)
 
		 * necessary to be known for HandleTrainLoading to determine
 
		 * whether the train is lost or not; not marking a train lost
 
		 * that arrives at random stations is bad. */
 
		this->current_order.SetNonStopType(ONSF_NO_STOP_AT_ANY_STATION);
 

	
 
	} else {
 
		current_order.MakeLoading(false);
 
	}
 

	
 
	GetStation(this->last_station_visited)->loading_vehicles.push_back(this);
 

	
 
	VehiclePayment(this);
 

	
 
	InvalidateWindow(GetWindowClassForVehicleType(this->type), this->owner);
 
	InvalidateWindowWidget(WC_VEHICLE_VIEW, this->index, VVW_WIDGET_START_STOP_VEH);
 
	InvalidateWindow(WC_VEHICLE_DETAILS, this->index);
 
	InvalidateWindow(WC_STATION_VIEW, this->last_station_visited);
 

	
 
	GetStation(this->last_station_visited)->MarkTilesDirty(true);
 
	this->cur_speed = 0;
 
	this->MarkDirty();
 
}
 

	
 
void Vehicle::LeaveStation()
 
{
 
	assert(current_order.IsType(OT_LOADING));
 

	
 
	/* Only update the timetable if the vehicle was supposed to stop here. */
 
	if (current_order.GetNonStopType() != ONSF_STOP_EVERYWHERE) UpdateVehicleTimetable(this, false);
 

	
 
	current_order.MakeLeaveStation();
 
	Station *st = GetStation(this->last_station_visited);
 
	st->loading_vehicles.remove(this);
 

	
 
	HideFillingPercent(&this->fill_percent_te_id);
 

	
 
	if (this->type == VEH_TRAIN) {
 
		/* Trigger station animation (trains only) */
 
		if (IsTileType(this->tile, MP_STATION)) StationAnimationTrigger(st, this->tile, STAT_ANIM_TRAIN_DEPARTS);
 

	
 
		/* Try to reserve a path when leaving the station as we
 
		 * might not be marked as wanting a reservation, e.g.
 
		 * when an overlength train gets turned around in a station. */
 
		if (UpdateSignalsOnSegment(this->tile, TrackdirToExitdir(GetVehicleTrackdir(this)), this->owner) == SIGSEG_PBS || _settings_game.pf.reserve_paths) {
0 comments (0 inline, 0 general)