Changeset - r12029:5b077ec055c0
[Not reviewed]
master
0 15 0
smatz - 15 years ago 2009-05-26 22:10:13
smatz@openttd.org
(svn r16441) -Codechange: new class SpecializedVehicle used as superclass for all vehicle types
15 files changed with 148 insertions and 133 deletions:
0 comments (0 inline, 0 general)
src/ai/api/ai_vehicle.cpp
Show inline comments
 
@@ -28,8 +28,9 @@
 
	if (!IsValidVehicle(vehicle_id)) return -1;
 

	
 
	int num = 1;
 
	if (::Vehicle::Get(vehicle_id)->type == VEH_TRAIN) {
 
		const Train *v = (Train *)::Vehicle::Get(vehicle_id);
 

	
 
	const Train *v = ::Train::GetIfValid(vehicle_id);
 
	if (v != NULL) {
 
		while ((v = GetNextUnit(v)) != NULL) num++;
 
	}
 

	
src/aircraft.h
Show inline comments
 
@@ -96,7 +96,7 @@ struct AircraftCache {
 
 *
 
 * As side-effect the vehicle type is set correctly.
 
 */
 
struct Aircraft : public Vehicle {
 
struct Aircraft : public SpecializedVehicle<Aircraft, VEH_AIRCRAFT> {
 
	AircraftCache acache; ///< Cache of often used calculated values
 

	
 
	uint16 crashed_counter;
 
@@ -125,10 +125,10 @@ struct Aircraft : public Vehicle {
 
	void OnNewDay();
 
	TileIndex GetOrderStationLocation(StationID station);
 
	bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse);
 
	Aircraft *Next() { return (Aircraft *)this->Vehicle::Next(); }
 
	const Aircraft *Next() const { return (const Aircraft *)this->Vehicle::Next(); }
 
};
 

	
 
#define FOR_ALL_AIRCRAFT(var) FOR_ALL_VEHICLES_OF_TYPE(Aircraft, var)
 

	
 
SpriteID GetRotorImage(const Aircraft *v);
 

	
 
Station *GetTargetAirportIfValid(const Aircraft *v);
src/aircraft_cmd.cpp
Show inline comments
 
@@ -2073,10 +2073,9 @@ void UpdateAirplanesOnNewStation(const S
 
	/* only 1 station is updated per function call, so it is enough to get entry_point once */
 
	const AirportFTAClass *ap = st->Airport();
 

	
 
	Vehicle *u;
 
	FOR_ALL_VEHICLES(u) {
 
		if (u->type == VEH_AIRCRAFT && IsNormalAircraft(u)) {
 
			Aircraft *v = (Aircraft *)u;
 
	Aircraft *v;
 
	FOR_ALL_AIRCRAFT(v) {
 
		if (IsNormalAircraft(v)) {
 
			if (v->targetairport == st->index) { // if heading to this airport
 
				/* update position of airplane. If plane is not flying, landing, or taking off
 
				 * you cannot delete airport, so it doesn't matter */
src/effectvehicle_base.h
Show inline comments
 
@@ -22,7 +22,7 @@
 
 *  - bulldozer (road works)
 
 *  - bubbles (industry)
 
 */
 
struct EffectVehicle : public Vehicle {
 
struct EffectVehicle : public SpecializedVehicle<EffectVehicle, VEH_EFFECT> {
 
	uint16 animation_state;
 
	byte animation_substate;
 

	
src/elrail.cpp
Show inline comments
 
@@ -532,8 +532,8 @@ void DrawCatenary(const TileInfo *ti)
 

	
 
bool SettingsDisableElrail(int32 p1)
 
{
 
	Vehicle *v;
 
	Company *c;
 
	Train *t;
 
	bool disable = (p1 != 0);
 

	
 
	/* we will now walk through all electric train engines and change their railtypes if it is the wrong one*/
 
@@ -554,10 +554,7 @@ bool SettingsDisableElrail(int32 p1)
 
	/* when disabling elrails, make sure that all existing trains can run on
 
	 *  normal rail too */
 
	if (disable) {
 
		FOR_ALL_VEHICLES(v) {
 
			if (v->type != VEH_TRAIN) continue;
 

	
 
			Train *t = (Train *)v;
 
		FOR_ALL_TRAINS(t) {
 
			if (t->railtype == RAILTYPE_ELECTRIC) {
 
				/* this railroad vehicle is now compatible only with elrail,
 
				 *  so add there also normal rail compatibility */
 
@@ -569,10 +566,9 @@ bool SettingsDisableElrail(int32 p1)
 
	}
 

	
 
	/* Fix the total power and acceleration for trains */
 
	FOR_ALL_VEHICLES(v) {
 
	FOR_ALL_TRAINS(t) {
 
		/* power and acceleration is cached only for front engines */
 
		if (v->type == VEH_TRAIN && IsFrontEngine(v)) {
 
			Train *t = (Train *)v;
 
		if (IsFrontEngine(t)) {
 
			TrainPowerChanged(t);
 
			UpdateTrainAcceleration(t);
 
		}
src/roadveh.h
Show inline comments
 
@@ -123,7 +123,7 @@ struct RoadVehicleCache {
 
 *
 
 * As side-effect the vehicle type is set correctly.
 
 */
 
struct RoadVehicle : public Vehicle {
 
struct RoadVehicle : public SpecializedVehicle<RoadVehicle, VEH_ROAD> {
 
	RoadVehicleCache rcache; ///< Cache of often used calculated values
 
	byte state;             ///< @see RoadVehicleStates
 
	byte frame;
 
@@ -160,9 +160,8 @@ struct RoadVehicle : public Vehicle {
 
	Trackdir GetVehicleTrackdir() const;
 
	TileIndex GetOrderStationLocation(StationID station);
 
	bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse);
 
	RoadVehicle *First() { return (RoadVehicle *)this->Vehicle::First(); }
 
	RoadVehicle *Next() { return (RoadVehicle *)this->Vehicle::Next(); }
 
	const RoadVehicle *Next() const { return (const RoadVehicle *)this->Vehicle::Next(); }
 
};
 

	
 
#define FOR_ALL_ROADVEHICLES(var) FOR_ALL_VEHICLES_OF_TYPE(RoadVehicle, var)
 

	
 
#endif /* ROADVEH_H */
src/roadveh_cmd.cpp
Show inline comments
 
@@ -432,10 +432,8 @@ CommandCost CmdSendRoadVehToDepot(TileIn
 
 */
 
CommandCost CmdTurnRoadVeh(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
 
{
 
	Vehicle *u = Vehicle::GetIfValid(p1);
 
	if (u == NULL || u->type != VEH_ROAD || !CheckOwnership(u->owner)) return CMD_ERROR;
 

	
 
	RoadVehicle *v = (RoadVehicle *)u;
 
	RoadVehicle *v = RoadVehicle::GetIfValid(p1);
 
	if (v == NULL || !CheckOwnership(v->owner)) return CMD_ERROR;
 

	
 
	if (v->vehstatus & VS_STOPPED ||
 
			v->vehstatus & VS_CRASHED ||
 
@@ -2065,7 +2063,7 @@ CommandCost CmdRefitRoadVeh(TileIndex ti
 
		}
 
	}
 

	
 
	if (flags & DC_EXEC) RoadVehUpdateCache((RoadVehicle *)Vehicle::Get(p1)->First());
 
	if (flags & DC_EXEC) RoadVehUpdateCache(RoadVehicle::Get(p1)->First());
 

	
 
	_returned_refit_capacity = total_capacity;
 

	
src/saveload/afterload.cpp
Show inline comments
 
@@ -921,17 +921,15 @@ bool AfterLoadGame()
 

	
 
	/* Elrails got added in rev 24 */
 
	if (CheckSavegameVersion(24)) {
 
		Vehicle *v;
 
		RailType min_rail = RAILTYPE_ELECTRIC;
 

	
 
		FOR_ALL_VEHICLES(v) {
 
			if (v->type == VEH_TRAIN) {
 
		Train *v;
 
		FOR_ALL_TRAINS(v) {
 
				RailType rt = RailVehInfo(v->engine_type)->railtype;
 

	
 
				((Train *)v)->railtype = rt;
 
			v->railtype = rt;
 
				if (rt == RAILTYPE_ELECTRIC) min_rail = RAILTYPE_RAIL;
 
			}
 
		}
 

	
 
		/* .. so we convert the entire map from normal to elrail (so maintain "fairness") */
 
		for (TileIndex t = 0; t < map_size; t++) {
 
@@ -963,8 +961,8 @@ bool AfterLoadGame()
 
			}
 
		}
 

	
 
		FOR_ALL_VEHICLES(v) {
 
			if (v->type == VEH_TRAIN && (IsFrontEngine(v) || IsFreeWagon(v))) TrainConsistChanged((Train *)v, true);
 
		FOR_ALL_TRAINS(v) {
 
			if (IsFrontEngine(v) || IsFreeWagon(v)) TrainConsistChanged(v, true);
 
		}
 

	
 
	}
 
@@ -1046,20 +1044,15 @@ bool AfterLoadGame()
 
	}
 

	
 
	if (CheckSavegameVersion(25)) {
 
		Vehicle *v;
 
		FOR_ALL_VEHICLES(v) {
 
			if (v->type == VEH_ROAD) {
 
				RoadVehicle *rv = (RoadVehicle *)v;
 
		RoadVehicle *rv;
 
		FOR_ALL_ROADVEHICLES(rv) {
 
				rv->vehstatus &= ~0x40;
 
				rv->slot = NULL;
 
				rv->slot_age = 0;
 
			}
 
		}
 
	} else {
 
		Vehicle *v;
 
		FOR_ALL_VEHICLES(v) {
 
			if (v->type != VEH_ROAD) continue;
 
			RoadVehicle *rv = (RoadVehicle *)v;
 
		RoadVehicle *rv;
 
		FOR_ALL_ROADVEHICLES(rv) {
 
			if (rv->slot != NULL) rv->slot->num_vehicles++;
 
		}
 
	}
 
@@ -1382,10 +1375,8 @@ bool AfterLoadGame()
 

	
 
	if (CheckSavegameVersion(69)) {
 
		/* In some old savegames a bit was cleared when it should not be cleared */
 
		Vehicle *v;
 
		FOR_ALL_VEHICLES(v) {
 
			if (v->type != VEH_ROAD) continue;
 
			RoadVehicle *rv = (RoadVehicle *)v;
 
		RoadVehicle *rv;
 
		FOR_ALL_ROADVEHICLES(rv) {
 
			if (rv->state == 250 || rv->state == 251) {
 
				SetBit(rv->state, RVS_IS_STOPPING);
 
			}
 
@@ -1708,15 +1699,12 @@ bool AfterLoadGame()
 

	
 
	/* Reserve all tracks trains are currently on. */
 
	if (CheckSavegameVersion(101)) {
 
		Vehicle *u;
 
		FOR_ALL_VEHICLES(u) {
 
			if (u->type == VEH_TRAIN) {
 
				Train *v = (Train *)u;
 
				if ((v->track & TRACK_BIT_WORMHOLE) == TRACK_BIT_WORMHOLE) {
 
					TryReserveRailTrack(v->tile, DiagDirToDiagTrack(GetTunnelBridgeDirection(v->tile)));
 
				} else if ((v->track & TRACK_BIT_MASK) != TRACK_BIT_NONE) {
 
					TryReserveRailTrack(v->tile, TrackBitsToTrack(v->track));
 
				}
 
		Train *t;
 
		FOR_ALL_TRAINS(t) {
 
			if ((t->track & TRACK_BIT_WORMHOLE) == TRACK_BIT_WORMHOLE) {
 
				TryReserveRailTrack(t->tile, DiagDirToDiagTrack(GetTunnelBridgeDirection(t->tile)));
 
			} else if ((t->track & TRACK_BIT_MASK) != TRACK_BIT_NONE) {
 
				TryReserveRailTrack(t->tile, TrackBitsToTrack(t->track));
 
			}
 
		}
 
	}
src/saveload/vehicle_sl.cpp
Show inline comments
 
@@ -20,16 +20,14 @@
 
 */
 
void ConnectMultiheadedTrains()
 
{
 
	Vehicle *v;
 
	Train *v;
 

	
 
	FOR_ALL_VEHICLES(v) {
 
		if (v->type == VEH_TRAIN) {
 
			((Train *)v)->other_multiheaded_part = NULL;
 
		}
 
	FOR_ALL_TRAINS(v) {
 
		v->other_multiheaded_part = NULL;
 
	}
 

	
 
	FOR_ALL_VEHICLES(v) {
 
		if (v->type == VEH_TRAIN && (IsFrontEngine(v) || IsFreeWagon(v))) {
 
	FOR_ALL_TRAINS(v) {
 
		if (IsFrontEngine(v) || 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 ..<..<..>..<..>..>..
 
@@ -45,7 +43,7 @@ void ConnectMultiheadedTrains()
 

	
 
			bool sequential_matching = IsFrontEngine(v);
 

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

	
 
				if (IsMultiheaded(u)) {
 
@@ -167,13 +165,11 @@ void UpdateOldAircraft()
 
		st->airport_flags = 0; // reset airport
 
	}
 

	
 
	Vehicle *v;
 
	FOR_ALL_VEHICLES(v) {
 
	Aircraft *a;
 
	FOR_ALL_AIRCRAFT(a) {
 
		/* airplane has another vehicle with subtype 4 (shadow), helicopter also has 3 (rotor)
 
		 * skip those */
 
		if (v->type == VEH_AIRCRAFT && IsNormalAircraft(v)) {
 
			Aircraft *v_oldstyle = (Aircraft *)v;
 
			Aircraft *a = (Aircraft *)v_oldstyle;
 
		if (IsNormalAircraft(a)) {
 
			/* airplane in terminal stopped doesn't hurt anyone, so goto next */
 
			if (a->vehstatus & VS_STOPPED && a->state == 0) {
 
				a->state = HANGAR;
 
@@ -182,7 +178,7 @@ void UpdateOldAircraft()
 

	
 
			AircraftLeaveHangar(a); // make airplane visible if it was in a depot for example
 
			a->vehstatus &= ~VS_STOPPED; // make airplane moving
 
			a->cur_speed = v_oldstyle->max_speed; // so aircraft don't have zero speed while in air
 
			a->cur_speed = a->max_speed; // so aircraft don't have zero speed while in air
 
			if (!a->current_order.IsType(OT_GOTO_STATION) && !a->current_order.IsType(OT_GOTO_DEPOT)) {
 
				/* reset current order so aircraft doesn't have invalid "station-only" order */
 
				a->current_order.MakeDummy();
src/settings.cpp
Show inline comments
 
@@ -695,10 +695,10 @@ static bool DeleteSelectStationWindow(in
 

	
 
static bool UpdateConsists(int32 p1)
 
{
 
	Vehicle *v;
 
	FOR_ALL_VEHICLES(v) {
 
	Train *t;
 
	FOR_ALL_TRAINS(t) {
 
		/* Update the consist of all trains so the maximum speed is set correctly. */
 
		if (v->type == VEH_TRAIN && (IsFrontEngine(v) || IsFreeWagon(v))) TrainConsistChanged((Train *)v, true);
 
		if (IsFrontEngine(t) || IsFreeWagon(t)) TrainConsistChanged(t, true);
 
	}
 
	return true;
 
}
 
@@ -732,10 +732,9 @@ static bool CheckInterval(int32 p1)
 

	
 
static bool TrainAccelerationModelChanged(int32 p1)
 
{
 
	Vehicle *v;
 

	
 
	FOR_ALL_VEHICLES(v) {
 
		if (v->type == VEH_TRAIN && IsFrontEngine(v)) UpdateTrainAcceleration((Train *)v);
 
	Train *t;
 
	FOR_ALL_TRAINS(t) {
 
		if (IsFrontEngine(t)) UpdateTrainAcceleration(t);
 
	}
 

	
 
	return true;
src/ship.h
Show inline comments
 
@@ -22,7 +22,7 @@ void GetShipSpriteSize(EngineID engine, 
 
 *
 
 * As side-effect the vehicle type is set correctly.
 
 */
 
struct Ship: public Vehicle {
 
struct Ship: public SpecializedVehicle<Ship, VEH_SHIP> {
 
	TrackBitsByte state;
 

	
 
	/** Initializes the Vehicle to a ship */
src/station.cpp
Show inline comments
 
@@ -69,11 +69,9 @@ Station::~Station()
 
		loading_vehicles.front()->LeaveStation();
 
	}
 

	
 
	Vehicle *v;
 
	FOR_ALL_VEHICLES(v) {
 
		if (v->type != VEH_AIRCRAFT || !IsNormalAircraft(v)) continue;
 

	
 
		Aircraft *a = (Aircraft *)v;
 
	Aircraft *a;
 
	FOR_ALL_AIRCRAFT(a) {
 
		if (!IsNormalAircraft(a)) continue;
 
		if (a->targetairport == this->index) a->targetairport = INVALID_STATION;
 
	}
 

	
 
@@ -463,12 +461,8 @@ RoadStop::~RoadStop()
 

	
 
	/* Clear the slot assignment of all vehicles heading for this road stop */
 
	if (num_vehicles != 0) {
 
		Vehicle *v;
 

	
 
		FOR_ALL_VEHICLES(v) {
 
			if (v->type != VEH_ROAD) continue;
 
			RoadVehicle *rv = (RoadVehicle *)v;
 

	
 
		RoadVehicle *rv;
 
		FOR_ALL_ROADVEHICLES(rv) {
 
			if (rv->slot == this) ClearSlot(rv);
 
		}
 
	}
src/train.h
Show inline comments
 
@@ -301,7 +301,7 @@ struct TrainCache {
 
 *
 
 * As side-effect the vehicle type is set correctly.
 
 */
 
struct Train : public Vehicle {
 
struct Train : public SpecializedVehicle<Train, VEH_TRAIN> {
 
	TrainCache tcache;
 

	
 
	/* Link between the two ends of a multiheaded engine */
 
@@ -338,14 +338,10 @@ struct Train : public Vehicle {
 
	Trackdir GetVehicleTrackdir() const;
 
	TileIndex GetOrderStationLocation(StationID station);
 
	bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse);
 
	Train *First() { return (Train *)this->Vehicle::First(); }
 
	Train *First() const { return (Train *)this->Vehicle::First(); }
 
	Train *Next() { return (Train *)this->Vehicle::Next(); }
 
	Train *Next() const { return (Train *)this->Vehicle::Next(); }
 
	Train *Previous() { return (Train *)this->Vehicle::Previous(); }
 
	Train *Previous() const { return (Train *)this->Vehicle::Previous(); }
 
};
 

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

	
 
/**
 
 * Get the next part of a multi-part engine.
 
 * Will only work on a multi-part engine (EngineHasArticPart(v) == true),
src/train_cmd.cpp
Show inline comments
 
@@ -973,18 +973,17 @@ static Train *UnlinkWagon(Train *v, Trai
 

	
 
static Train *FindGoodVehiclePos(const Train *src)
 
{
 
	Vehicle *dst;
 
	EngineID eng = src->engine_type;
 
	TileIndex tile = src->tile;
 

	
 
	FOR_ALL_VEHICLES(dst) {
 
		if (dst->type == VEH_TRAIN && IsFreeWagon(dst) && dst->tile == tile && !HASBITS(dst->vehstatus, VS_CRASHED)) {
 
	Train *dst;
 
	FOR_ALL_TRAINS(dst) {
 
		if (IsFreeWagon(dst) && dst->tile == tile && !HASBITS(dst->vehstatus, VS_CRASHED)) {
 
			/* check so all vehicles in the line have the same engine. */
 
			Vehicle *v = dst;
 

	
 
			while (v->engine_type == eng) {
 
				v = v->Next();
 
				if (v == NULL) return (Train *)dst;
 
			Train *t = dst;
 
			while (t->engine_type == eng) {
 
				t = t->Next();
 
				if (t == NULL) return dst;
 
			}
 
		}
 
	}
 
@@ -1045,25 +1044,22 @@ CommandCost CmdMoveRailVehicle(TileIndex
 
	VehicleID s = GB(p1, 0, 16);
 
	VehicleID d = GB(p1, 16, 16);
 

	
 
	Vehicle *src_v = Vehicle::GetIfValid(s);
 
	if (src_v == NULL || src_v->type != VEH_TRAIN || !CheckOwnership(src_v->owner)) return CMD_ERROR;
 
	Train *src = Train::GetIfValid(s);
 
	if (src == NULL || !CheckOwnership(src->owner)) return CMD_ERROR;
 

	
 
	/* Do not allow moving crashed vehicles inside the depot, it is likely to cause asserts later */
 
	if (HASBITS(src_v->vehstatus, VS_CRASHED)) return CMD_ERROR;
 

	
 
	Train *src = (Train *)src_v;
 
	if (HASBITS(src->vehstatus, VS_CRASHED)) return CMD_ERROR;
 

	
 
	/* if nothing is selected as destination, try and find a matching vehicle to drag to. */
 
	Train *dst;
 
	if (d == INVALID_VEHICLE) {
 
		dst = IsTrainEngine(src) ? NULL : FindGoodVehiclePos(src);
 
	} else {
 
		Vehicle *dst_v = Vehicle::GetIfValid(d);
 
		if (dst_v == NULL || dst_v->type != VEH_TRAIN || !CheckOwnership(dst_v->owner)) return CMD_ERROR;
 
		dst = Train::GetIfValid(d);
 
		if (dst == NULL || !CheckOwnership(dst->owner)) return CMD_ERROR;
 

	
 
		/* Do not allow appending to crashed vehicles, too */
 
		if (HASBITS(dst_v->vehstatus, VS_CRASHED)) return CMD_ERROR;
 
		dst = (Train *)dst_v;
 
		if (HASBITS(dst->vehstatus, VS_CRASHED)) return CMD_ERROR;
 
	}
 

	
 
	/* if an articulated part is being handled, deal with its parent vehicle */
 
@@ -1399,13 +1395,12 @@ CommandCost CmdSellRailWagon(TileIndex t
 
	/* Check if we deleted a vehicle window */
 
	Window *w = NULL;
 

	
 
	Vehicle *vt = Vehicle::GetIfValid(p1);
 
	if (vt == NULL || vt->type != VEH_TRAIN || !CheckOwnership(vt->owner)) return CMD_ERROR;
 
	Train *v = Train::GetIfValid(p1);
 
	if (v == NULL || !CheckOwnership(v->owner)) return CMD_ERROR;
 
	if (p2 > 1) return CMD_ERROR;
 

	
 
	if (HASBITS(vt->vehstatus, VS_CRASHED)) return_cmd_error(STR_CAN_T_SELL_DESTROYED_VEHICLE);
 

	
 
	Train *v = (Train *)vt;
 
	if (HASBITS(v->vehstatus, VS_CRASHED)) return_cmd_error(STR_CAN_T_SELL_DESTROYED_VEHICLE);
 

	
 
	while (IsArticulatedPart(v)) v = v->Previous();
 
	Train *first = v->First();
 

	
 
@@ -1955,10 +1950,8 @@ static void ReverseTrainDirection(Train 
 
 */
 
CommandCost CmdReverseTrainDirection(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
 
{
 
	Vehicle *vt = Vehicle::GetIfValid(p1);
 
	if (vt == NULL || vt->type != VEH_TRAIN || !CheckOwnership(vt->owner)) return CMD_ERROR;
 

	
 
	Train *v = (Train *)vt;
 
	Train *v = Train::GetIfValid(p1);
 
	if (v == NULL || !CheckOwnership(v->owner)) return CMD_ERROR;
 

	
 
	if (p2 != 0) {
 
		/* turn a single unit around */
 
@@ -2015,10 +2008,10 @@ CommandCost CmdReverseTrainDirection(Til
 
 */
 
CommandCost CmdForceTrainProceed(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
 
{
 
	Vehicle *v = Vehicle::GetIfValid(p1);
 
	if (v == NULL || v->type != VEH_TRAIN || !CheckOwnership(v->owner)) return CMD_ERROR;
 

	
 
	if (flags & DC_EXEC) ((Train *)v)->force_proceed = 0x50;
 
	Train *t = Train::GetIfValid(p1);
 
	if (t == NULL || !CheckOwnership(t->owner)) return CMD_ERROR;
 

	
 
	if (flags & DC_EXEC) t->force_proceed = 0x50;
 

	
 
	return CommandCost();
 
}
 
@@ -2039,10 +2032,9 @@ CommandCost CmdRefitRailVehicle(TileInde
 
	byte new_subtype = GB(p2, 8, 8);
 
	bool only_this = HasBit(p2, 16);
 

	
 
	Vehicle *vt = Vehicle::GetIfValid(p1);
 
	if (vt == NULL || vt->type != VEH_TRAIN || !CheckOwnership(vt->owner)) return CMD_ERROR;
 

	
 
	Train *v = (Train *)vt;
 
	Train *v = Train::GetIfValid(p1);
 
	if (v == NULL || !CheckOwnership(v->owner)) return CMD_ERROR;
 

	
 
	if (CheckTrainStoppedInDepot(v) < 0) return_cmd_error(STR_TRAIN_MUST_BE_STOPPED);
 
	if (v->vehstatus & VS_CRASHED) return_cmd_error(STR_CAN_T_REFIT_DESTROYED_VEHICLE);
 

	
 
@@ -2116,7 +2108,7 @@ CommandCost CmdRefitRailVehicle(TileInde
 
	_returned_refit_capacity = num;
 

	
 
	/* Update the train's cached variables */
 
	if (flags & DC_EXEC) TrainConsistChanged((Train *)Vehicle::Get(p1)->First(), false);
 
	if (flags & DC_EXEC) TrainConsistChanged(Train::Get(p1)->First(), false);
 

	
 
	return cost;
 
}
src/vehicle_base.h
Show inline comments
 
@@ -492,6 +492,64 @@ public:
 
};
 

	
 
/**
 
 * Class defining several overloaded accessors so we don't
 
 * have to cast vehicle types that often
 
 */
 
template <class T, VehicleType Type>
 
struct SpecializedVehicle : public Vehicle {
 
	static const VehicleType EXPECTED_TYPE = Type; ///< Specialized type
 

	
 
	/**
 
	 * Get the first vehicle in the chain
 
	 * @return first vehicle in the chain
 
	 */
 
	FORCEINLINE T *First() const { return (T *)this->Vehicle::First(); }
 

	
 
	/**
 
	 * Get next vehicle in the chain
 
	 * @return next vehicle in the chain
 
	 */
 
	FORCEINLINE T *Next() const { return (T *)this->Vehicle::Next(); }
 

	
 
	/**
 
	 * Get previous vehicle in the chain
 
	 * @return previous vehicle in the chain
 
	 */
 
	FORCEINLINE T *Previous() const { return (T *)this->Vehicle::Previous(); }
 

	
 

	
 
	/**
 
	 * Tests whether given index is a valid index for vehicle of this type
 
	 * @param index tested index
 
	 * @return is this index valid index of T?
 
	 */
 
	static FORCEINLINE bool IsValidID(size_t index)
 
	{
 
		return Vehicle::IsValidID(index) && Vehicle::Get(index)->type == Type;
 
	}
 

	
 
	/**
 
	 * Gets vehicle with given index
 
	 * @return pointer to vehicle with given index casted to T *
 
	 */
 
	static FORCEINLINE T *Get(size_t index)
 
	{
 
		return (T *)Vehicle::Get(index);
 
	}
 

	
 
	/**
 
	 * Returns vehicle if the index is a valid index for this vehicle type
 
	 * @return pointer to vehicle with given index if it's a vehicle of this type
 
	 */
 
	static FORCEINLINE T *GetIfValid(size_t index)
 
	{
 
		return IsValidID(index) ? Get(index) : NULL ;
 
	}
 
};
 

	
 
#define FOR_ALL_VEHICLES_OF_TYPE(name, var) FOR_ALL_ITEMS_FROM(name, vehicle_index, var, 0) if (var->type == name::EXPECTED_TYPE)
 

	
 
/**
 
 * This class 'wraps' Vehicle; you do not actually instantiate this class.
 
 * You create a Vehicle using AllocateVehicle, so it is added to the pool
 
 * and you reinitialize that to a Train using:
 
@@ -499,7 +557,7 @@ public:
 
 *
 
 * As side-effect the vehicle type is set correctly.
 
 */
 
struct DisasterVehicle : public Vehicle {
 
struct DisasterVehicle : public SpecializedVehicle<DisasterVehicle, VEH_DISASTER> {
 
	uint16 image_override;
 
	VehicleID big_ufo_destroyer_target;
 

	
 
@@ -512,7 +570,6 @@ struct DisasterVehicle : public Vehicle 
 
	const char *GetTypeString() const { return "disaster vehicle"; }
 
	void UpdateDeltaXY(Direction direction);
 
	bool Tick();
 
	DisasterVehicle *Next() { return (DisasterVehicle*)this->Vehicle::Next(); }
 
};
 

	
 
#define FOR_ALL_VEHICLES_FROM(var, start) FOR_ALL_ITEMS_FROM(Vehicle, vehicle_index, var, start)
0 comments (0 inline, 0 general)