Changeset - r12290:442d5d533a57
[Not reviewed]
master
0 17 0
smatz - 15 years ago 2009-07-01 22:22:01
smatz@openttd.org
(svn r16717) -Codechange: make IsFrontEngine() member of Train
17 files changed with 118 insertions and 110 deletions:
0 comments (0 inline, 0 general)
src/autoreplace_cmd.cpp
Show inline comments
 
@@ -614,15 +614,16 @@ CommandCost CmdAutoreplaceVehicle(TileIn
 
	if (!CheckOwnership(v->owner)) return CMD_ERROR;
 
	if (!v->IsInDepot()) return CMD_ERROR;
 
	if (v->vehstatus & VS_CRASHED) return CMD_ERROR;
 

	
 
	bool free_wagon = false;
 
	if (v->type == VEH_TRAIN) {
 
		if (IsArticulatedPart(v) || IsRearDualheaded(v)) return CMD_ERROR;
 
		free_wagon = !IsFrontEngine(v);
 
		if (free_wagon && IsFrontEngine(v->First())) return CMD_ERROR;
 
		Train *t = Train::From(v);
 
		if (IsArticulatedPart(t) || IsRearDualheaded(t)) return CMD_ERROR;
 
		free_wagon = !t->IsFrontEngine();
 
		if (free_wagon && t->First()->IsFrontEngine()) return CMD_ERROR;
 
	} else {
 
		if (!v->IsPrimaryVehicle()) return CMD_ERROR;
 
	}
 

	
 
	const Company *c = Company::Get(_current_company);
 
	bool wagon_removal = c->settings.renew_keep_length;
src/depot_gui.cpp
Show inline comments
 
@@ -434,26 +434,26 @@ struct DepotWindow : Window {
 
			/* free wagons don't have an initial loco. */
 
			x -= _traininfo_vehicle_width;
 
		}
 

	
 
		switch (this->type) {
 
			case VEH_TRAIN: {
 
				const Vehicle *v = *veh;
 
				const Train *v = Train::From(*veh);
 
				d->head = d->wagon = v;
 

	
 
				/* either pressed the flag or the number, but only when it's a loco */
 
				if (x < 0 && IsFrontEngine(v)) return (x >= -10) ? MODE_START_STOP : MODE_SHOW_VEHICLE;
 
				if (x < 0 && v->IsFrontEngine()) return (x >= -10) ? MODE_START_STOP : MODE_SHOW_VEHICLE;
 

	
 
				skip = (skip * 8) / _traininfo_vehicle_width;
 
				x = (x * 8) / _traininfo_vehicle_width;
 

	
 
				/* Skip vehicles that are scrolled off the list */
 
				x += skip;
 

	
 
				/* find the vehicle in this row that was clicked */
 
				while (v != NULL && (x -= Train::From(v)->tcache.cached_veh_length) >= 0) v = v->Next();
 
				while (v != NULL && (x -= v->tcache.cached_veh_length) >= 0) v = v->Next();
 

	
 
				/* if an articulated part was selected, find its parent */
 
				while (v != NULL && IsArticulatedPart(v)) v = v->Previous();
 

	
 
				d->wagon = v;
 

	
 
@@ -561,13 +561,13 @@ struct DepotWindow : Window {
 

	
 
		if (v == NULL) return;
 

	
 
		if (!v->IsPrimaryVehicle()) {
 
			v = v->First();
 
			/* Do nothing when clicking on a train in depot with no loc attached */
 
			if (v->type == VEH_TRAIN && !IsFrontEngine(v)) return;
 
			if (v->type == VEH_TRAIN && !Train::From(v)->IsFrontEngine()) return;
 
		}
 

	
 
		switch (v->type) {
 
			case VEH_TRAIN:    error_str = STR_ERROR_CAN_T_BUILD_RAILROAD_VEHICLE; break;
 
			case VEH_ROAD:     error_str = STR_ERROR_CAN_T_BUILD_ROAD_VEHICLE;     break;
 
			case VEH_SHIP:     error_str = STR_ERROR_CAN_T_BUILD_SHIP;             break;
 
@@ -947,13 +947,13 @@ struct DepotWindow : Window {
 
					if (this->GetVehicleFromDepotWndPt(pt.x, pt.y, &v, &gdvp) == MODE_DRAG_VEHICLE &&
 
						sel != INVALID_VEHICLE) {
 
						if (gdvp.wagon != NULL && gdvp.wagon->index == sel && _ctrl_pressed) {
 
							DoCommandP(Vehicle::Get(sel)->tile, Vehicle::Get(sel)->index, true, CMD_REVERSE_TRAIN_DIRECTION | CMD_MSG(STR_ERROR_CAN_T_MAKE_VEHICLE_TURN));
 
						} else if (gdvp.wagon == NULL || gdvp.wagon->index != sel) {
 
							TrainDepotMoveVehicle(gdvp.wagon, sel, gdvp.head);
 
						} else if (gdvp.head != NULL && IsFrontEngine(gdvp.head)) {
 
						} else if (gdvp.head != NULL && Train::From(gdvp.head)->IsFrontEngine()) {
 
							ShowVehicleViewWindow(gdvp.head);
 
						}
 
					}
 
				} else if (this->GetVehicleFromDepotWndPt(pt.x, pt.y, &v, NULL) == MODE_DRAG_VEHICLE &&
 
					v != NULL &&
 
					sel == v->index) {
 
@@ -974,13 +974,13 @@ struct DepotWindow : Window {
 
					const Vehicle *v = Vehicle::Get(this->sel);
 
					this->sel = INVALID_VEHICLE;
 
					this->SetDirty();
 

	
 
					int sell_cmd = (v->type == VEH_TRAIN && (widget == DEPOT_WIDGET_SELL_CHAIN || _ctrl_pressed)) ? 1 : 0;
 

	
 
					bool is_engine = (!(v->type == VEH_TRAIN && !IsFrontEngine(v)));
 
					bool is_engine = (v->type != VEH_TRAIN || Train::From(v)->IsFrontEngine());
 

	
 
					if (is_engine) {
 
						_backup_orders_tile = v->tile;
 
						BackupVehicleOrders(v);
 
					}
 

	
src/elrail.cpp
Show inline comments
 
@@ -565,13 +565,13 @@ bool SettingsDisableElrail(int32 p1)
 
		}
 
	}
 

	
 
	/* Fix the total power and acceleration for trains */
 
	FOR_ALL_TRAINS(t) {
 
		/* power and acceleration is cached only for front engines */
 
		if (IsFrontEngine(t)) {
 
		if (t->IsFrontEngine()) {
 
			TrainPowerChanged(t);
 
			UpdateTrainAcceleration(t);
 
		}
 
	}
 

	
 
	FOR_ALL_COMPANIES(c) c->avail_railtypes = GetCompanyRailtypes(c->index);
src/group.h
Show inline comments
 
@@ -80,14 +80,14 @@ static inline void DecreaseGroupNumVehic
 
	Group *g = Group::GetIfValid(id_g);
 
	if (g != NULL) g->num_vehicle--;
 
}
 

	
 

	
 
void InitializeGroup();
 
void SetTrainGroupID(Vehicle *v, GroupID grp);
 
void UpdateTrainGroupID(Vehicle *v);
 
void SetTrainGroupID(Train *v, GroupID grp);
 
void UpdateTrainGroupID(Train *v);
 
void RemoveVehicleFromGroup(const Vehicle *v);
 
void RemoveAllGroupsForCompany(const CompanyID company);
 

	
 
extern GroupID _new_group_id;
 

	
 
#endif /* GROUP_H */
src/group_cmd.cpp
Show inline comments
 
@@ -207,13 +207,13 @@ CommandCost CmdAddVehicleGroup(TileIndex
 
		DecreaseGroupNumVehicle(v->group_id);
 
		IncreaseGroupNumVehicle(new_g);
 

	
 
		switch (v->type) {
 
			default: NOT_REACHED();
 
			case VEH_TRAIN:
 
				SetTrainGroupID(v, new_g);
 
				SetTrainGroupID(Train::From(v), new_g);
 
				break;
 
			case VEH_ROAD:
 
			case VEH_SHIP:
 
			case VEH_AIRCRAFT:
 
				if (IsEngineCountable(v)) UpdateNumEngineGroup(v->engine_type, v->group_id, new_g);
 
				v->group_id = new_g;
 
@@ -339,17 +339,17 @@ void RemoveVehicleFromGroup(const Vehicl
 
/**
 
 * Affect the groupID of a train to new_g.
 
 * @note called in CmdAddVehicleGroup and CmdMoveRailVehicle
 
 * @param v     First vehicle of the chain.
 
 * @param new_g index of array group
 
 */
 
void SetTrainGroupID(Vehicle *v, GroupID new_g)
 
void SetTrainGroupID(Train *v, GroupID new_g)
 
{
 
	if (!Group::IsValidID(new_g) && !IsDefaultGroupID(new_g)) return;
 

	
 
	assert(v->type == VEH_TRAIN && IsFrontEngine(v));
 
	assert(v->IsFrontEngine());
 

	
 
	for (Vehicle *u = v; u != NULL; u = u->Next()) {
 
		if (IsEngineCountable(u)) UpdateNumEngineGroup(u->engine_type, u->group_id, new_g);
 

	
 
		u->group_id = new_g;
 
	}
 
@@ -363,17 +363,17 @@ void SetTrainGroupID(Vehicle *v, GroupID
 
 * Recalculates the groupID of a train. Should be called each time a vehicle is added
 
 * to/removed from the chain,.
 
 * @note this needs to be called too for 'wagon chains' (in the depot, without an engine)
 
 * @note Called in CmdBuildRailVehicle, CmdBuildRailWagon, CmdMoveRailVehicle, CmdSellRailWagon
 
 * @param v First vehicle of the chain.
 
 */
 
void UpdateTrainGroupID(Vehicle *v)
 
void UpdateTrainGroupID(Train *v)
 
{
 
	assert(v->type == VEH_TRAIN && (IsFrontEngine(v) || IsFreeWagon(v)));
 
	assert(v->IsFrontEngine() || IsFreeWagon(v));
 

	
 
	GroupID new_g = IsFrontEngine(v) ? v->group_id : (GroupID)DEFAULT_GROUP;
 
	GroupID new_g = v->IsFrontEngine() ? v->group_id : (GroupID)DEFAULT_GROUP;
 
	for (Vehicle *u = v; u != NULL; u = u->Next()) {
 
		if (IsEngineCountable(u)) UpdateNumEngineGroup(u->engine_type, u->group_id, new_g);
 

	
 
		u->group_id = new_g;
 
	}
 

	
src/industry_cmd.cpp
Show inline comments
 
@@ -2020,13 +2020,13 @@ int WhoCanServiceIndustry(Industry *ind)
 
		/* Is it worthwhile to try this vehicle? */
 
		if (v->owner != _local_company && result != 0) continue;
 

	
 
		/* Check whether it accepts the right kind of cargo */
 
		bool c_accepts = false;
 
		bool c_produces = false;
 
		if (v->type == VEH_TRAIN && IsFrontEngine(v)) {
 
		if (v->type == VEH_TRAIN && Train::From(v)->IsFrontEngine()) {
 
			for (const Vehicle *u = v; u != NULL; u = u->Next()) {
 
				CanCargoServiceIndustry(u->cargo_type, ind, &c_accepts, &c_produces);
 
			}
 
		} else if (v->type == VEH_ROAD || v->type == VEH_SHIP || v->type == VEH_AIRCRAFT) {
 
			CanCargoServiceIndustry(v->cargo_type, ind, &c_accepts, &c_produces);
 
		} else {
src/saveload/afterload.cpp
Show inline comments
 
@@ -982,13 +982,13 @@ bool AfterLoadGame()
 
				default:
 
					break;
 
			}
 
		}
 

	
 
		FOR_ALL_TRAINS(v) {
 
			if (IsFrontEngine(v) || IsFreeWagon(v)) TrainConsistChanged(v, true);
 
			if (v->IsFrontEngine() || IsFreeWagon(v)) TrainConsistChanged(v, true);
 
		}
 

	
 
	}
 

	
 
	/* In version 16.1 of the savegame a company can decide if trains, which get
 
	 * replaced, shall keep their old length. In all prior versions, just default
 
@@ -1341,13 +1341,13 @@ bool AfterLoadGame()
 
	}
 

	
 
	if (CheckSavegameVersion(57)) {
 
		Vehicle *v;
 
		/* Added a FIFO queue of vehicles loading at stations */
 
		FOR_ALL_VEHICLES(v) {
 
			if ((v->type != VEH_TRAIN || IsFrontEngine(v)) &&  // for all locs
 
			if ((v->type != VEH_TRAIN || Train::From(v)->IsFrontEngine()) &&  // for all locs
 
					!(v->vehstatus & (VS_STOPPED | VS_CRASHED)) && // not stopped or crashed
 
					v->current_order.IsType(OT_LOADING)) {         // loading
 
				Station::Get(v->last_station_visited)->loading_vehicles.push_back(v);
 

	
 
				/* The loading finished flag is *only* set when actually completely
 
				 * finished. Because the vehicle is loading, it is not finished. */
src/saveload/vehicle_sl.cpp
Show inline comments
 
@@ -25,13 +25,13 @@ void ConnectMultiheadedTrains()
 

	
 
	FOR_ALL_TRAINS(v) {
 
		v->other_multiheaded_part = NULL;
 
	}
 

	
 
	FOR_ALL_TRAINS(v) {
 
		if (IsFrontEngine(v) || IsFreeWagon(v)) {
 
		if (v->IsFrontEngine() || IsFreeWagon(v)) {
 
			/* Two ways to associate multiheaded parts to each other:
 
			 * sequential-matching: Trains shall be arranged to look like <..>..<..>..<..>..
 
			 * bracket-matching:    Free vehicle chains shall be arranged to look like ..<..<..>..<..>..>..
 
			 *
 
			 * Note: Old savegames might contain chains which do not comply with these rules, e.g.
 
			 *   - the front and read parts have invalid orders
 
@@ -39,13 +39,13 @@ void ConnectMultiheadedTrains()
 
			 *   - there might be different amounts of front and rear parts.
 
			 *
 
			 * Note: The multiheaded parts need to be matched exactly like they are matched on the server, else desyncs will occur.
 
			 *   This is why two matching strategies are needed.
 
			 */
 

	
 
			bool sequential_matching = IsFrontEngine(v);
 
			bool sequential_matching = v->IsFrontEngine();
 

	
 
			for (Train *u = v; u != NULL; u = GetNextVehicle(u)) {
 
				if (u->other_multiheaded_part != NULL) continue; // we already linked this one
 

	
 
				if (IsMultiheaded(u)) {
 
					if (!IsTrainEngine(u)) {
 
@@ -305,24 +305,27 @@ void AfterLoadVehicles(bool part_of_load
 

	
 
	CheckValidVehicles();
 

	
 
	FOR_ALL_VEHICLES(v) {
 
		assert(v->first != NULL);
 

	
 
		if (v->type == VEH_TRAIN && (IsFrontEngine(v) || IsFreeWagon(v))) {
 
			if (IsFrontEngine(v)) Train::From(v)->tcache.last_speed = v->cur_speed; // update displayed train speed
 
			TrainConsistChanged(Train::From(v), false);
 
		if (v->type == VEH_TRAIN) {
 
			Train *t = Train::From(v);
 
			if (t->IsFrontEngine() || IsFreeWagon(t)) {
 
				t->tcache.last_speed = t->cur_speed; // update displayed train speed
 
				TrainConsistChanged(t, false);
 
			}
 
		} else if (v->type == VEH_ROAD && IsRoadVehFront(v)) {
 
			RoadVehUpdateCache(RoadVehicle::From(v));
 
		}
 
	}
 

	
 
	/* Stop non-front engines */
 
	if (CheckSavegameVersion(112)) {
 
		FOR_ALL_VEHICLES(v) {
 
			if (v->type == VEH_TRAIN && !IsFrontEngine(v)) {
 
			if (v->type == VEH_TRAIN && !Train::From(v)->IsFrontEngine()) {
 
				if (IsTrainEngine(v)) v->vehstatus |= VS_STOPPED;
 
				/* cur_speed is now relevant for non-front parts - nonzero breaks
 
				 * moving-wagons-inside-depot- and autoreplace- code */
 
				v->cur_speed = 0;
 
			}
 
			/* trains weren't stopping gradually in old OTTD versions (and TTO/TTD)
src/settings.cpp
Show inline comments
 
@@ -697,13 +697,13 @@ static bool DeleteSelectStationWindow(in
 

	
 
static bool UpdateConsists(int32 p1)
 
{
 
	Train *t;
 
	FOR_ALL_TRAINS(t) {
 
		/* Update the consist of all trains so the maximum speed is set correctly. */
 
		if (IsFrontEngine(t) || IsFreeWagon(t)) TrainConsistChanged(t, true);
 
		if (t->IsFrontEngine() || IsFreeWagon(t)) TrainConsistChanged(t, true);
 
	}
 
	return true;
 
}
 

	
 
/* Check service intervals of vehicles, p1 is value of % or day based servicing */
 
static bool CheckInterval(int32 p1)
 
@@ -733,13 +733,13 @@ static bool CheckInterval(int32 p1)
 
}
 

	
 
static bool TrainAccelerationModelChanged(int32 p1)
 
{
 
	Train *t;
 
	FOR_ALL_TRAINS(t) {
 
		if (IsFrontEngine(t)) {
 
		if (t->IsFrontEngine()) {
 
			t->tcache.cached_max_curve_speed = GetTrainCurveSpeedLimit(t);
 
			UpdateTrainAcceleration(t);
 
		}
 
	}
 

	
 
	return true;
src/station_cmd.cpp
Show inline comments
 
@@ -2505,13 +2505,13 @@ static bool ClickTile_Station(TileIndex 
 
static VehicleEnterTileStatus VehicleEnter_Station(Vehicle *v, TileIndex tile, int x, int y)
 
{
 
	StationID station_id = GetStationIndex(tile);
 

	
 
	if (v->type == VEH_TRAIN) {
 
		if (!v->current_order.ShouldStopAtStation(v, station_id)) return VETSB_CONTINUE;
 
		if (!IsRailwayStation(tile) || !IsFrontEngine(v)) return VETSB_CONTINUE;
 
		if (!IsRailwayStation(tile) || !Train::From(v)->IsFrontEngine()) return VETSB_CONTINUE;
 

	
 
		int station_ahead;
 
		int station_length;
 
		int stop = GetTrainStopLocation(station_id, tile, Train::From(v), &station_ahead, &station_length);
 

	
 
		/* Stop whenever that amount of station ahead + the distance from the
src/train.h
Show inline comments
 
@@ -48,23 +48,12 @@ enum TrainSubtype {
 
	TS_WAGON             = 2, ///< Wagon
 
	TS_ENGINE            = 3, ///< Engine, that can be front engines, but might be placed behind another engine
 
	TS_FREE_WAGON        = 4, ///< First in a wagon chain (in depot)
 
	TS_MULTIHEADED       = 5, ///< Engine is a multiheaded
 
};
 

	
 

	
 
/** Check if a vehicle is front engine
 
 * @param v vehicle to check
 
 * @return Returns true if vehicle is a front engine
 
 */
 
static inline bool IsFrontEngine(const Vehicle *v)
 
{
 
	assert(v->type == VEH_TRAIN);
 
	return HasBit(v->subtype, TS_FRONT);
 
}
 

	
 
/** Set front engine state
 
 * @param v vehicle to change
 
 */
 
static inline void SetFrontEngine(Vehicle *v)
 
{
 
	assert(v->type == VEH_TRAIN);
 
@@ -321,24 +310,31 @@ struct Train : public SpecializedVehicle
 

	
 
	const char *GetTypeString() const { return "train"; }
 
	void MarkDirty();
 
	void UpdateDeltaXY(Direction direction);
 
	ExpensesType GetExpenseType(bool income) const { return income ? EXPENSES_TRAIN_INC : EXPENSES_TRAIN_RUN; }
 
	void PlayLeaveStationSound() const;
 
	bool IsPrimaryVehicle() const { return IsFrontEngine(this); }
 
	bool IsPrimaryVehicle() const { return this->IsFrontEngine(); }
 
	SpriteID GetImage(Direction direction) const;
 
	int GetDisplaySpeed() const { return this->tcache.last_speed; }
 
	int GetDisplayMaxSpeed() const { return this->tcache.cached_max_speed; }
 
	Money GetRunningCost() const;
 
	bool IsInDepot() const { return CheckTrainInDepot(this, false) != -1; }
 
	bool IsStoppedInDepot() const { return CheckTrainStoppedInDepot(this) >= 0; }
 
	bool Tick();
 
	void OnNewDay();
 
	Trackdir GetVehicleTrackdir() const;
 
	TileIndex GetOrderStationLocation(StationID station);
 
	bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse);
 

	
 
	/**
 
	 * Check if a vehicle is front engine
 
	 * @param v vehicle to check
 
	 * @return Returns true if vehicle is a front engine
 
	 */
 
	FORCEINLINE bool IsFrontEngine() const { return HasBit(this->subtype, TS_FRONT); }
 
};
 

	
 
#define FOR_ALL_TRAINS(var) FOR_ALL_VEHICLES_OF_TYPE(Train, var)
 

	
 
/**
 
 * Get the next part of a multi-part engine.
src/train_cmd.cpp
Show inline comments
 
@@ -214,17 +214,16 @@ void CheckTrainsLengths()
 
 * @param same_length should length of vehicles stay the same?
 
 */
 
void TrainConsistChanged(Train *v, bool same_length)
 
{
 
	uint16 max_speed = UINT16_MAX;
 

	
 
	assert(v->type == VEH_TRAIN);
 
	assert(IsFrontEngine(v) || IsFreeWagon(v));
 
	assert(v->IsFrontEngine() || IsFreeWagon(v));
 

	
 
	const RailVehicleInfo *rvi_v = RailVehInfo(v->engine_type);
 
	EngineID first_engine = IsFrontEngine(v) ? v->engine_type : INVALID_ENGINE;
 
	EngineID first_engine = v->IsFrontEngine() ? v->engine_type : INVALID_ENGINE;
 
	v->tcache.cached_total_length = 0;
 
	v->compatible_railtypes = RAILTYPES_NONE;
 

	
 
	bool train_can_tilt = true;
 

	
 
	for (Train *u = v; u != NULL; u = u->Next()) {
 
@@ -344,13 +343,13 @@ void TrainConsistChanged(Train *v, bool 
 
	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);
 

	
 
	if (IsFrontEngine(v)) {
 
	if (v->IsFrontEngine()) {
 
		UpdateTrainAcceleration(v);
 
		InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 
	}
 
}
 

	
 
enum AccelType {
 
@@ -480,13 +479,13 @@ int GetTrainCurveSpeedLimit(Train *v)
 
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)) {
 
	if (IsTileType(v->tile, MP_STATION) && v->IsFrontEngine()) {
 
		StationID sid = GetStationIndex(v->tile);
 
		if (v->current_order.ShouldStopAtStation(v, sid)) {
 
			int station_ahead;
 
			int station_length;
 
			int stop_at = GetTrainStopLocation(sid, v->tile, v, &station_ahead, &station_length);
 

	
 
@@ -574,13 +573,13 @@ static int GetTrainAcceleration(Train *v
 
		return min(-force - resistance, -10000) / mass;
 
	}
 
}
 

	
 
void UpdateTrainAcceleration(Train *v)
 
{
 
	assert(IsFrontEngine(v));
 
	assert(v->IsFrontEngine());
 

	
 
	v->max_speed = v->tcache.cached_max_speed;
 

	
 
	uint power = v->tcache.cached_power;
 
	uint weight = v->tcache.cached_weight;
 
	assert(weight != 0);
 
@@ -936,13 +935,13 @@ int CheckTrainInDepot(const Train *v, bo
 
		 * in the consist. Exclude articulated parts so that autoreplacing to
 
		 * engines with more articulated parts than before works correctly.
 
		 *
 
		 * Also skip counting rear ends of multiheaded engines */
 
		if (!IsArticulatedPart(v) && !IsRearDualheaded(v)) count++;
 
		if (v->track != TRACK_BIT_DEPOT || v->tile != tile ||
 
				(IsFrontEngine(v) && needs_to_be_stopped && !(v->vehstatus & VS_STOPPED))) {
 
				(v->IsFrontEngine() && needs_to_be_stopped && !(v->vehstatus & VS_STOPPED))) {
 
			return -1;
 
		}
 
	}
 

	
 
	return count;
 
}
 
@@ -1030,13 +1029,13 @@ static void AddWagonToConsist(Train *v, 
 
 * always call with the front engine
 
 */
 
static void NormaliseTrainConsist(Train *v)
 
{
 
	if (IsFreeWagon(v)) return;
 

	
 
	assert(IsFrontEngine(v));
 
	assert(v->IsFrontEngine());
 

	
 
	for (; v != NULL; v = GetNextVehicle(v)) {
 
		if (!IsMultiheaded(v) || !IsTrainEngine(v)) continue;
 

	
 
		/* make sure that there are no free cars before next engine */
 
		Train *u;
 
@@ -1133,34 +1132,34 @@ CommandCost CmdMoveRailVehicle(TileIndex
 
				/* If moving only one vehicle, just count that. */
 
				src_len = 1;
 
			}
 

	
 
			if (src_len + dst_len > max_len) {
 
				/* Abort if we're adding too many wagons to a train. */
 
				if (dst_head != NULL && IsFrontEngine(dst_head)) return_cmd_error(STR_ERROR_TRAIN_TOO_LONG);
 
				if (dst_head != NULL && dst_head->IsFrontEngine()) return_cmd_error(STR_ERROR_TRAIN_TOO_LONG);
 
				/* Abort if we're making a train on a new row. */
 
				if (dst_head == NULL && IsTrainEngine(src)) return_cmd_error(STR_ERROR_TRAIN_TOO_LONG);
 
			}
 
		} else {
 
			/* Abort if we're creating a new train on an existing row. */
 
			if (src_len > max_len && src == src_head && IsTrainEngine(GetNextVehicle(src_head)))
 
				return_cmd_error(STR_ERROR_TRAIN_TOO_LONG);
 
		}
 
	}
 

	
 
	/* moving a loco to a new line?, then we need to assign a unitnumber. */
 
	if (dst == NULL && !IsFrontEngine(src) && IsTrainEngine(src)) {
 
	if (dst == NULL && !src->IsFrontEngine() && IsTrainEngine(src)) {
 
		UnitID unit_num = ((flags & DC_AUTOREPLACE) != 0 ? 0 : GetFreeUnitNumber(VEH_TRAIN));
 
		if (unit_num > _settings_game.vehicle.max_trains)
 
			return_cmd_error(STR_ERROR_TOO_MANY_VEHICLES_IN_GAME);
 

	
 
		if (flags & DC_EXEC) src->unitnumber = unit_num;
 
	}
 

	
 
	/* When we move the front vehicle, the second vehicle might need a unitnumber */
 
	if (!HasBit(p2, 0) && (IsFreeWagon(src) || (IsFrontEngine(src) && dst == NULL)) && (flags & DC_AUTOREPLACE) == 0) {
 
	if (!HasBit(p2, 0) && (IsFreeWagon(src) || (src->IsFrontEngine() && dst == NULL)) && (flags & DC_AUTOREPLACE) == 0) {
 
		Vehicle *second = GetNextUnit(src);
 
		if (second != NULL && IsTrainEngine(second) && GetFreeUnitNumber(VEH_TRAIN) > _settings_game.vehicle.max_trains) {
 
			return_cmd_error(STR_ERROR_TOO_MANY_VEHICLES_IN_GAME);
 
		}
 
	}
 

	
 
@@ -1265,13 +1264,13 @@ CommandCost CmdMoveRailVehicle(TileIndex
 
	}
 

	
 
	/* do it? */
 
	if (flags & DC_EXEC) {
 
		/* If we move the front Engine and if the second vehicle is not an engine
 
		   add the whole vehicle to the DEFAULT_GROUP */
 
		if (IsFrontEngine(src) && !IsDefaultGroupID(src->group_id)) {
 
		if (src->IsFrontEngine() && !IsDefaultGroupID(src->group_id)) {
 
			Vehicle *v = GetNextVehicle(src);
 

	
 
			if (v != NULL && IsTrainEngine(v)) {
 
				v->group_id   = src->group_id;
 
				src->group_id = DEFAULT_GROUP;
 
			}
 
@@ -1298,13 +1297,13 @@ CommandCost CmdMoveRailVehicle(TileIndex
 
		if (dst == NULL) {
 
			/* We make a new line in the depot, so we know already that we invalidate the window data */
 
			InvalidateWindowData(WC_VEHICLE_DEPOT, src->tile);
 

	
 
			/* move the train to an empty line. for locomotives, we set the type to TS_Front. for wagons, 4. */
 
			if (IsTrainEngine(src)) {
 
				if (!IsFrontEngine(src)) {
 
				if (!src->IsFrontEngine()) {
 
					/* setting the type to 0 also involves setting up the orders field. */
 
					SetFrontEngine(src);
 
					assert(src->orders.list == NULL);
 

	
 
					/* Decrease the engines number of the src engine_type */
 
					if (!IsDefaultGroupID(src->group_id) && Group::IsValidID(src->group_id)) {
 
@@ -1316,24 +1315,24 @@ CommandCost CmdMoveRailVehicle(TileIndex
 
				}
 
			} else {
 
				SetFreeWagon(src);
 
			}
 
			dst_head = src;
 
		} else {
 
			if (IsFrontEngine(src)) {
 
			if (src->IsFrontEngine()) {
 
				/* the vehicle was previously a loco. need to free the order list and delete vehicle windows etc. */
 
				DeleteWindowById(WC_VEHICLE_VIEW, src->index);
 
				DeleteWindowById(WC_VEHICLE_ORDERS, src->index);
 
				DeleteWindowById(WC_VEHICLE_REFIT, src->index);
 
				DeleteWindowById(WC_VEHICLE_DETAILS, src->index);
 
				DeleteWindowById(WC_VEHICLE_TIMETABLE, src->index);
 
				DeleteVehicleOrders(src);
 
				RemoveVehicleFromGroup(src);
 
			}
 

	
 
			if (IsFrontEngine(src) || IsFreeWagon(src)) {
 
			if (src->IsFrontEngine() || IsFreeWagon(src)) {
 
				InvalidateWindowData(WC_VEHICLE_DEPOT, src->tile);
 
				ClearFrontEngine(src);
 
				ClearFreeWagon(src);
 
				src->unitnumber = 0; // doesn't occupy a unitnumber anymore.
 
			}
 

	
 
@@ -1354,39 +1353,39 @@ CommandCost CmdMoveRailVehicle(TileIndex
 
			AddWagonToConsist(src->other_multiheaded_part, src);
 
		}
 

	
 
		/* If there is an engine behind first_engine we moved away, it should become new first_engine
 
		 * To do this, CmdMoveRailVehicle must be called once more
 
		 * we can't loop forever here because next time we reach this line we will have a front engine */
 
		if (src_head != NULL && !IsFrontEngine(src_head) && IsTrainEngine(src_head)) {
 
		if (src_head != NULL && !src_head->IsFrontEngine() && IsTrainEngine(src_head)) {
 
			/* As in CmdMoveRailVehicle src_head->group_id will be equal to DEFAULT_GROUP
 
			 * we need to save the group and reaffect it to src_head */
 
			const GroupID tmp_g = src_head->group_id;
 
			CmdMoveRailVehicle(0, flags, src_head->index | (INVALID_VEHICLE << 16), 1, text);
 
			SetTrainGroupID(src_head, tmp_g);
 
			src_head = NULL; // don't do anything more to this train since the new call will do it
 
		}
 

	
 
		if (src_head != NULL) {
 
			NormaliseTrainConsist(src_head);
 
			TrainConsistChanged(src_head, false);
 
			UpdateTrainGroupID(src_head);
 
			if (IsFrontEngine(src_head)) {
 
			if (src_head->IsFrontEngine()) {
 
				/* Update the refit button and window */
 
				InvalidateWindow(WC_VEHICLE_REFIT, src_head->index);
 
				InvalidateWindowWidget(WC_VEHICLE_VIEW, src_head->index, VVW_WIDGET_REFIT_VEH);
 
			}
 
			/* Update the depot window */
 
			InvalidateWindow(WC_VEHICLE_DEPOT, src_head->tile);
 
		}
 

	
 
		if (dst_head != NULL) {
 
			NormaliseTrainConsist(dst_head);
 
			TrainConsistChanged(dst_head, false);
 
			UpdateTrainGroupID(dst_head);
 
			if (IsFrontEngine(dst_head)) {
 
			if (dst_head->IsFrontEngine()) {
 
				/* Update the refit button and window */
 
				InvalidateWindowWidget(WC_VEHICLE_VIEW, dst_head->index, VVW_WIDGET_REFIT_VEH);
 
				InvalidateWindow(WC_VEHICLE_REFIT, dst_head->index);
 
			}
 
			/* Update the depot window */
 
			InvalidateWindow(WC_VEHICLE_DEPOT, dst_head->tile);
 
@@ -1426,13 +1425,13 @@ CommandCost CmdSellRailWagon(TileIndex t
 
		return_cmd_error(STR_ERROR_TRAINS_CAN_ONLY_BE_ALTERED_INSIDE_A_DEPOT);
 
	}
 

	
 
	if (IsRearDualheaded(v)) return_cmd_error(STR_ERROR_REAR_ENGINE_FOLLOW_FRONT);
 

	
 
	if (flags & DC_EXEC) {
 
		if (v == first && IsFrontEngine(first)) {
 
		if (v == first && first->IsFrontEngine()) {
 
			DeleteWindowById(WC_VEHICLE_VIEW, first->index);
 
			DeleteWindowById(WC_VEHICLE_ORDERS, first->index);
 
			DeleteWindowById(WC_VEHICLE_REFIT, first->index);
 
			DeleteWindowById(WC_VEHICLE_DETAILS, first->index);
 
			DeleteWindowById(WC_VEHICLE_TIMETABLE, first->index);
 
		}
 
@@ -1509,13 +1508,13 @@ CommandCost CmdSellRailWagon(TileIndex t
 

	
 
				/* 5. If the train still exists, update its acceleration, window, etc. */
 
				if (first != NULL) {
 
					NormaliseTrainConsist(first);
 
					TrainConsistChanged(first, false);
 
					UpdateTrainGroupID(first);
 
					if (IsFrontEngine(first)) InvalidateWindow(WC_VEHICLE_REFIT, first->index);
 
					if (first->IsFrontEngine()) InvalidateWindow(WC_VEHICLE_REFIT, first->index);
 
				}
 

	
 
			}
 
		} break;
 
		case 1: { // Delete wagon and all wagons after it given certain criteria
 
			/* Start deleting every vehicle after the selected one
 
@@ -1717,20 +1716,22 @@ static Vehicle *TrainOnTileEnum(Vehicle 
 
 * @param v vehicle on tile
 
 * @param data tile with crossing we are testing
 
 * @return v if it is approaching a crossing, NULL otherwise
 
 */
 
static Vehicle *TrainApproachingCrossingEnum(Vehicle *v, void *data)
 
{
 
	/* not a train || not front engine || crashed */
 
	if (v->type != VEH_TRAIN || !IsFrontEngine(v) || (v->vehstatus & VS_CRASHED)) return NULL;
 

	
 
	TileIndex tile = *(TileIndex*)data;
 

	
 
	if (TrainApproachingCrossingTile(Train::From(v)) != tile) return NULL;
 

	
 
	return v;
 
	if (v->type != VEH_TRAIN || (v->vehstatus & VS_CRASHED)) return NULL;
 

	
 
	Train *t = Train::From(v);
 
	if (!t->IsFrontEngine()) return NULL;
 

	
 
	TileIndex tile = *(TileIndex *)data;
 

	
 
	if (TrainApproachingCrossingTile(t) != tile) return NULL;
 

	
 
	return t;
 
}
 

	
 

	
 
/**
 
 * Finds a vehicle approaching rail-road crossing
 
 * @param tile tile to test
 
@@ -2509,13 +2510,13 @@ static void ClearPathReservation(const T
 
	}
 
}
 

	
 
/** Free the reserved path in front of a vehicle. */
 
void FreeTrainTrackReservation(const Train *v, TileIndex origin, Trackdir orig_td)
 
{
 
	assert(IsFrontEngine(v));
 
	assert(v->IsFrontEngine());
 

	
 
	TileIndex tile = origin != INVALID_TILE ? origin : v->tile;
 
	Trackdir  td = orig_td != INVALID_TRACKDIR ? orig_td : v->GetVehicleTrackdir();
 
	bool      free_tile = tile != v->tile || !(IsRailwayStationTile(v->tile) || IsTileType(v->tile, MP_TUNNELBRIDGE));
 
	StationID station_id = IsRailwayStationTile(v->tile) ? GetStationIndex(v->tile) : INVALID_STATION;
 

	
 
@@ -3095,13 +3096,13 @@ static Track ChooseTrainTrack(Train *v, 
 
 * @param mark_as_stuck Should the train be marked as stuck on a failed reservation?
 
 * @param first_tile_okay True if no path should be reserved if the current tile is a safe position.
 
 * @return True if a path could be reserved.
 
 */
 
bool TryPathReserve(Train *v, bool mark_as_stuck, bool first_tile_okay)
 
{
 
	assert(v->type == VEH_TRAIN && IsFrontEngine(v));
 
	assert(v->IsFrontEngine());
 

	
 
	/* We have to handle depots specially as the track follower won't look
 
	 * at the depot tile itself but starts from the next tile. If we are still
 
	 * inside the depot, a depot reservation can never be ours. */
 
	if (v->track == TRACK_BIT_DEPOT) {
 
		if (GetDepotWaypointReservation(v->tile)) {
 
@@ -3416,13 +3417,13 @@ static byte AfterSetTrainPos(Train *v, b
 

	
 
/* Check if the vehicle is compatible with the specified tile */
 
static inline bool CheckCompatibleRail(const Train *v, TileIndex tile)
 
{
 
	return
 
		IsTileOwner(tile, v->owner) && (
 
			!IsFrontEngine(v) ||
 
			!v->IsFrontEngine() ||
 
			HasBit(v->compatible_railtypes, GetRailType(tile))
 
		);
 
}
 

	
 
struct RailtypeSlowdownParams {
 
	byte small_turn, large_turn;
 
@@ -3470,13 +3471,13 @@ static bool TrainMovedChangeSignals(Tile
 

	
 
static void SetVehicleCrashed(Train *v)
 
{
 
	if (v->crash_anim_pos != 0) return;
 

	
 
	/* Free a possible path reservation and try to mark all tiles occupied by the train reserved. */
 
	if (IsFrontEngine(v)) {
 
	if (v->IsFrontEngine()) {
 
		/* Remove all reservations, also the ones currently under the train
 
		 * and any railway station paltform reservation. */
 
		FreeTrainTrackReservation(v);
 
		for (const Train *u = v; u != NULL; u = u->Next()) {
 
			ClearPathReservation(u, u->tile, u->GetVehicleTrackdir());
 
			if (IsTileType(u->tile, MP_TUNNELBRIDGE)) {
 
@@ -3628,22 +3629,25 @@ static bool CheckTrainCollision(Train *v
 

	
 
	ModifyStationRatingAround(v->tile, v->owner, -160, 30);
 
	SndPlayVehicleFx(SND_13_BIG_CRASH, v);
 
	return true;
 
}
 

	
 
static Vehicle *CheckVehicleAtSignal(Vehicle *v, void *data)
 
static Vehicle *CheckTrainAtSignal(Vehicle *v, void *data)
 
{
 
	if (v->type != VEH_TRAIN || (v->vehstatus & VS_CRASHED)) return NULL;
 

	
 
	Train *t = Train::From(v);
 
	DiagDirection exitdir = *(DiagDirection *)data;
 

	
 
	/* front engine of a train, not inside wormhole or depot, not crashed */
 
	if (v->type == VEH_TRAIN && IsFrontEngine(v) && (Train::From(v)->track & TRACK_BIT_MASK) && !(v->vehstatus & VS_CRASHED)) {
 
		if (v->cur_speed <= 5 && TrainExitDir(v->direction, Train::From(v)->track) == exitdir) return v;
 
	}
 

	
 
	return NULL;
 
	/* not front engine of a train, inside wormhole or depot, crashed */
 
	if (!t->IsFrontEngine() || !(t->track & TRACK_BIT_MASK)) return NULL;
 

	
 
	if (t->cur_speed > 5 || TrainExitDir(t->direction, t->track) != exitdir) return NULL;
 

	
 
	return t;
 
}
 

	
 
static void TrainController(Train *v, Vehicle *nomove)
 
{
 
	Train *first = v->First();
 
	Train *prev;
 
@@ -3664,13 +3668,13 @@ static void TrainController(Train *v, Ve
 
					gp.x = v->x_pos;
 
					gp.y = v->y_pos;
 
				} else {
 
					/* Not inside depot */
 

	
 
					/* Reverse when we are at the end of the track already, do not move to the new position */
 
					if (IsFrontEngine(v) && !TrainCheckIfLineEnds(v)) return;
 
					if (v->IsFrontEngine() && !TrainCheckIfLineEnds(v)) return;
 

	
 
					uint32 r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
 
					if (HasBit(r, VETS_CANNOT_ENTER)) {
 
						goto invalid_rail;
 
					}
 
					if (HasBit(r, VETS_ENTERED_STATION)) {
 
@@ -3734,13 +3738,13 @@ static void TrainController(Train *v, Ve
 
								DiagDirection exitdir = TrackdirToExitdir(i);
 
								TileIndex o_tile = TileAddByDiagDir(gp.new_tile, exitdir);
 

	
 
								exitdir = ReverseDiagDir(exitdir);
 

	
 
								/* check if a train is waiting on the other side */
 
								if (!HasVehicleOnPos(o_tile, &exitdir, &CheckVehicleAtSignal)) return;
 
								if (!HasVehicleOnPos(o_tile, &exitdir, &CheckTrainAtSignal)) return;
 
							}
 
						}
 

	
 
						/* If we would reverse but are currently in a PBS block and
 
						 * reversing of stuck trains is disabled, don't reverse. */
 
						if (_settings_game.pf.wait_for_pbs_path == 255 && UpdateSignalsOnSegment(v->tile, enterdir, v->owner) == SIGSEG_PBS) {
 
@@ -3802,13 +3806,13 @@ static void TrainController(Train *v, Ve
 
					goto invalid_rail;
 
				}
 

	
 
				if (!HasBit(r, VETS_ENTERED_WORMHOLE)) {
 
					Track track = FindFirstTrack(chosen_track);
 
					Trackdir tdir = TrackDirectionToTrackdir(track, chosen_dir);
 
					if (IsFrontEngine(v) && HasPbsSignalOnTrackdir(gp.new_tile, tdir)) {
 
					if (v->IsFrontEngine() && HasPbsSignalOnTrackdir(gp.new_tile, tdir)) {
 
						SetSignalStateByTrackdir(gp.new_tile, tdir, SIGNAL_STATE_RED);
 
						MarkTileDirtyByTile(gp.new_tile);
 
					}
 

	
 
					/* Clear any track reservation when the last vehicle leaves the tile */
 
					if (v->Next() == NULL) ClearPathReservation(v, v->tile, v->GetVehicleTrackdir());
 
@@ -3834,13 +3838,13 @@ static void TrainController(Train *v, Ve
 
						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)) {
 
				if (v->IsFrontEngine()) {
 
					v->load_unload_time_rem = 0;
 

	
 
					/* If we are approching a crossing that is reserved, play the sound now. */
 
					TileIndex crossing = TrainApproachingCrossingTile(v);
 
					if (crossing != INVALID_TILE && GetCrossingReservation(crossing)) SndPlayTileFx(SND_0E_LEVEL_CROSSING, crossing);
 

	
 
@@ -3861,13 +3865,13 @@ static void TrainController(Train *v, Ve
 
				v->cur_speed =
 
					min(v->cur_speed, GetBridgeSpec(GetBridgeType(v->tile))->speed);
 
			}
 

	
 
			if (IsTileType(gp.new_tile, MP_TUNNELBRIDGE) && HasBit(VehicleEnterTile(v, gp.new_tile, gp.x, gp.y), VETS_ENTERED_WORMHOLE)) {
 
				/* Perform look-ahead on tunnel exit. */
 
				if (IsFrontEngine(v)) {
 
				if (v->IsFrontEngine()) {
 
					TryReserveRailTrack(gp.new_tile, DiagDirToDiagTrack(GetTunnelBridgeDirection(gp.new_tile)));
 
					CheckNextTrainTile(v);
 
				}
 
			} else {
 
				v->x_pos = gp.x;
 
				v->y_pos = gp.y;
 
@@ -3888,13 +3892,13 @@ static void TrainController(Train *v, Ve
 
		if (prev == NULL) {
 
			/* This is the first vehicle in the train */
 
			AffectSpeedByZChange(v, old_z);
 
		}
 

	
 
		if (update_signals_crossing) {
 
			if (IsFrontEngine(v)) {
 
			if (v->IsFrontEngine()) {
 
				if (TrainMovedChangeSignals(gp.new_tile, enterdir)) {
 
					/* We are entering a block with PBS signals right now, but
 
					 * not through a PBS signal. This means we don't have a
 
					 * reservation right now. As a conventional signal will only
 
					 * ever be green if no other train is in the block, getting
 
					 * a path should always be possible. If the player built
 
@@ -3915,13 +3919,13 @@ static void TrainController(Train *v, Ve
 
				TrainMovedChangeSignals(gp.old_tile, ReverseDiagDir(enterdir));
 
				if (IsLevelCrossingTile(gp.old_tile)) UpdateLevelCrossing(gp.old_tile);
 
			}
 
		}
 

	
 
		/* 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 (v->IsFrontEngine() && v->tick_counter % _settings_game.pf.path_backoff_interval == 0) CheckNextTrainTile(v);
 
	}
 

	
 
	if (direction_changed) first->tcache.cached_max_curve_speed = GetTrainCurveSpeedLimit(first);
 

	
 
	return;
 

	
 
@@ -4199,13 +4203,13 @@ static bool TrainCanLeaveTile(const Trai
 
 * @param v front engine of train
 
 * @return TileIndex of crossing the train is approaching, else INVALID_TILE
 
 * @pre v in non-crashed front engine
 
 */
 
static TileIndex TrainApproachingCrossingTile(const Train *v)
 
{
 
	assert(IsFrontEngine(v));
 
	assert(v->IsFrontEngine());
 
	assert(!(v->vehstatus & VS_CRASHED));
 

	
 
	if (!TrainCanLeaveTile(v)) return INVALID_TILE;
 

	
 
	DiagDirection dir = TrainExitDir(v->direction, v->track);
 
	TileIndex tile = v->tile + TileOffsByDiagDir(dir);
 
@@ -4444,13 +4448,13 @@ Money Train::GetRunningCost() const
 
bool Train::Tick()
 
{
 
	if (_age_cargo_skip_counter == 0) this->cargo.AgeCargo();
 

	
 
	this->tick_counter++;
 

	
 
	if (IsFrontEngine(this)) {
 
	if (this->IsFrontEngine()) {
 
		if (!(this->vehstatus & VS_STOPPED)) this->running_ticks++;
 

	
 
		this->current_order_time++;
 

	
 
		if (!TrainLocoHandler(this, false)) return false;
 

	
 
@@ -4503,13 +4507,13 @@ static void CheckIfTrainNeedsService(Tra
 
}
 

	
 
void Train::OnNewDay()
 
{
 
	if ((++this->day_counter & 7) == 0) DecreaseVehicleValue(this);
 

	
 
	if (IsFrontEngine(this)) {
 
	if (this->IsFrontEngine()) {
 
		CheckVehicleBreakdown(this);
 
		AgeVehicle(this);
 

	
 
		CheckIfTrainNeedsService(this);
 

	
 
		CheckOrders(this);
src/train_gui.cpp
Show inline comments
 
@@ -23,13 +23,13 @@ void CcBuildWagon(bool success, TileInde
 
	if (!success) return;
 

	
 
	/* find a locomotive in the depot. */
 
	const Vehicle *found = NULL;
 
	const Train *t;
 
	FOR_ALL_TRAINS(t) {
 
		if (IsFrontEngine(t) && t->tile == tile &&
 
		if (t->IsFrontEngine() && t->tile == tile &&
 
				t->track == TRACK_BIT_DEPOT) {
 
			if (found != NULL) return; // must be exactly one.
 
			found = t;
 
		}
 
	}
 

	
src/tunnelbridge_cmd.cpp
Show inline comments
 
@@ -1371,13 +1371,13 @@ static VehicleEnterTileStatus VehicleEnt
 
			Train *t = Train::From(v);
 
			fc = (x & 0xF) + (y << 4);
 

	
 
			vdir = DirToDiagDir(t->direction);
 

	
 
			if (t->track != TRACK_BIT_WORMHOLE && dir == vdir) {
 
				if (IsFrontEngine(t) && fc == _tunnel_fractcoord_1[dir]) {
 
				if (t->IsFrontEngine() && fc == _tunnel_fractcoord_1[dir]) {
 
					if (!PlayVehicleSound(t, VSE_TUNNEL) && RailVehInfo(t->engine_type)->engclass == 0) {
 
						SndPlayVehicleFx(SND_05_TRAIN_THROUGH_TUNNEL, v);
 
					}
 
					return VETSB_CONTINUE;
 
				}
 
				if (fc == _tunnel_fractcoord_2[dir]) {
src/vehicle.cpp
Show inline comments
 
@@ -515,13 +515,13 @@ void Vehicle::PreDestructor()
 
		if (st != NULL) {
 
			const AirportFTA *layout = st->Airport()->layout;
 
			CLRBITS(st->airport_flags, layout[a->previous_pos].block | layout[a->pos].block);
 
		}
 
	}
 

	
 
	if (this->type != VEH_TRAIN || (this->type == VEH_TRAIN && (IsFrontEngine(this) || IsFreeWagon(this)))) {
 
	if (this->type != VEH_TRAIN || (this->type == VEH_TRAIN && (Train::From(this)->IsFrontEngine() || IsFreeWagon(this)))) {
 
		InvalidateWindowData(WC_VEHICLE_DEPOT, this->tile);
 
	}
 

	
 
	if (this->IsPrimaryVehicle()) {
 
		DeleteWindowById(WC_VEHICLE_VIEW, this->index);
 
		DeleteWindowById(WC_VEHICLE_ORDERS, this->index);
 
@@ -956,24 +956,26 @@ uint8 CalcPercentVehicleFilled(const Veh
 
	return (count * 100) / max;
 
}
 

	
 
void VehicleEnterDepot(Vehicle *v)
 
{
 
	switch (v->type) {
 
		case VEH_TRAIN:
 
		case VEH_TRAIN: {
 
			Train *t = Train::From(v);
 
			InvalidateWindowClasses(WC_TRAINS_LIST);
 
			/* Clear path reservation */
 
			SetDepotWaypointReservation(v->tile, false);
 
			if (_settings_client.gui.show_track_reservation) MarkTileDirtyByTile(v->tile);
 
			SetDepotWaypointReservation(t->tile, false);
 
			if (_settings_client.gui.show_track_reservation) MarkTileDirtyByTile(t->tile);
 

	
 
			if (!IsFrontEngine(v)) v = v->First();
 
			UpdateSignalsOnSegment(v->tile, INVALID_DIAGDIR, v->owner);
 
			v->load_unload_time_rem = 0;
 
			ClrBit(Train::From(v)->flags, VRF_TOGGLE_REVERSE);
 
			TrainConsistChanged(Train::From(v), true);
 
			if (!t->IsFrontEngine()) t = t->First();
 
			UpdateSignalsOnSegment(t->tile, INVALID_DIAGDIR, t->owner);
 
			t->load_unload_time_rem = 0;
 
			ClrBit(t->flags, VRF_TOGGLE_REVERSE);
 
			TrainConsistChanged(t, true);
 
			break;
 
		}
 

	
 
		case VEH_ROAD:
 
			InvalidateWindowClasses(WC_ROADVEH_LIST);
 
			if (!IsRoadVehFront(v)) v = v->First();
 
			break;
 

	
src/vehicle_cmd.cpp
Show inline comments
 
@@ -347,13 +347,13 @@ CommandCost CmdCloneVehicle(TileIndex ti
 
	 * w is the car/vehicle currently being cloned
 
	 * w_rear is the rear end of the cloned train. It's used to add more cars and is only used by trains
 
	 */
 

	
 
	if (!CheckOwnership(v->owner)) return CMD_ERROR;
 

	
 
	if (v->type == VEH_TRAIN && (!IsFrontEngine(v) || Train::From(v)->crash_anim_pos >= 4400)) return CMD_ERROR;
 
	if (v->type == VEH_TRAIN && (!Train::From(v)->IsFrontEngine() || Train::From(v)->crash_anim_pos >= 4400)) return CMD_ERROR;
 

	
 
	/* check that we can allocate enough vehicles */
 
	if (!(flags & DC_EXEC)) {
 
		int veh_counter = 0;
 
		do {
 
			veh_counter++;
 
@@ -383,13 +383,13 @@ CommandCost CmdCloneVehicle(TileIndex ti
 
			w = Vehicle::Get(_new_vehicle_id);
 

	
 
			if (v->type == VEH_TRAIN && HasBit(Train::From(v)->flags, VRF_REVERSE_DIRECTION)) {
 
				SetBit(Train::From(w)->flags, VRF_REVERSE_DIRECTION);
 
			}
 

	
 
			if (v->type == VEH_TRAIN && !IsFrontEngine(v)) {
 
			if (v->type == VEH_TRAIN && !Train::From(v)->IsFrontEngine()) {
 
				/* this s a train car
 
				 * add this unit to the end of the train */
 
				CommandCost result = DoCommand(0, (w_rear->index << 16) | w->index, 1, flags, CMD_MOVE_RAIL_VEHICLE);
 
				if (CmdFailed(result)) {
 
					/* The train can't be joined to make the same consist as the original.
 
					 * Sell what we already made (clean up) and return an error.           */
src/water_cmd.cpp
Show inline comments
 
@@ -795,24 +795,26 @@ static void FloodVehicle(Vehicle *v)
 
				u->vehstatus |= VS_CRASHED;
 
				MarkSingleVehicleDirty(u);
 
			}
 

	
 
			switch (v->type) {
 
				default: NOT_REACHED();
 
				case VEH_TRAIN:
 
					if (IsFrontEngine(v)) {
 
				case VEH_TRAIN: {
 
					Train *t = Train::From(v);
 
					if (t->IsFrontEngine()) {
 
						pass += 4; // driver
 
						/* FreeTrainTrackReservation() calls GetVehicleTrackdir() that doesn't like crashed vehicles.
 
						 * In this case, v->direction matches v->u.rail.track, so we can do this (it wasn't crashed before) */
 
						v->vehstatus &= ~VS_CRASHED;
 
						FreeTrainTrackReservation(Train::From(v));
 
						v->vehstatus |= VS_CRASHED;
 
						t->vehstatus &= ~VS_CRASHED;
 
						FreeTrainTrackReservation(t);
 
						t->vehstatus |= VS_CRASHED;
 
					}
 
					Train::From(v)->crash_anim_pos = 4000; // max 4440, disappear pretty fast
 
					t->crash_anim_pos = 4000; // max 4440, disappear pretty fast
 
					InvalidateWindowClassesData(WC_TRAINS_LIST, 0);
 
					break;
 
				}
 

	
 
				case VEH_ROAD:
 
					if (IsRoadVehFront(v)) pass += 1; // driver
 
					RoadVehicle::From(v)->crashed_ctr = 2000; // max 2220, disappear pretty fast
 
					InvalidateWindowClassesData(WC_ROADVEH_LIST, 0);
 
					break;
0 comments (0 inline, 0 general)