(svn r16719) -Codechange: make IsArticulatedPart(), IsTrainEngine(), IsTrainWagon(), IsMultiheaded(), EngineHasArticPart() and IsRearDualheaded() members of Train

This commit is contained in:
smatz 2009-07-01 23:57:20 +00:00
parent ecfaa0564d
commit d86e17d65a
15 changed files with 140 additions and 171 deletions

View File

@ -413,7 +413,7 @@
const Vehicle *v = ::Vehicle::Get(vehicle_id); const Vehicle *v = ::Vehicle::Get(vehicle_id);
switch (v->type) { switch (v->type) {
case VEH_ROAD: return ::RoadVehHasArticPart(v); case VEH_ROAD: return ::RoadVehHasArticPart(v);
case VEH_TRAIN: return ::EngineHasArticPart(v); case VEH_TRAIN: return ::Train::From(v)->EngineHasArticPart();
default: NOT_REACHED(); default: NOT_REACHED();
} }
} }

View File

@ -207,7 +207,7 @@ bool IsArticulatedVehicleCarryingDifferentCargos(const Vehicle *v, CargoID *carg
switch (v->type) { switch (v->type) {
case VEH_TRAIN: case VEH_TRAIN:
v = (EngineHasArticPart(Train::From(v)) ? GetNextArticPart(Train::From(v)) : NULL); v = Train::From(v)->EngineHasArticPart() ? GetNextArticPart(Train::From(v)) : NULL;
break; break;
case VEH_ROAD: case VEH_ROAD:
@ -254,7 +254,7 @@ void CheckConsistencyOfArticulatedVehicle(const Vehicle *v)
switch (v->type) { switch (v->type) {
case VEH_TRAIN: case VEH_TRAIN:
v = (EngineHasArticPart(Train::From(v)) ? GetNextArticPart(Train::From(v)) : NULL); v = Train::From(v)->EngineHasArticPart() ? GetNextArticPart(Train::From(v)) : NULL;
break; break;
case VEH_ROAD: case VEH_ROAD:

View File

@ -92,7 +92,7 @@ static void TransferCargo(Vehicle *old_veh, Vehicle *new_head, bool part_of_chai
assert(!part_of_chain || new_head->IsPrimaryVehicle()); assert(!part_of_chain || new_head->IsPrimaryVehicle());
/* Loop through source parts */ /* Loop through source parts */
for (Vehicle *src = old_veh; src != NULL; src = src->Next()) { for (Vehicle *src = old_veh; src != NULL; src = src->Next()) {
if (!part_of_chain && src->type == VEH_TRAIN && src != old_veh && src != Train::From(old_veh)->other_multiheaded_part && !IsArticulatedPart(src)) { if (!part_of_chain && src->type == VEH_TRAIN && src != old_veh && src != Train::From(old_veh)->other_multiheaded_part && !Train::From(src)->IsArticulatedPart()) {
/* Skip vehicles, which do not belong to old_veh */ /* Skip vehicles, which do not belong to old_veh */
src = GetLastEnginePart(Train::From(src)); src = GetLastEnginePart(Train::From(src));
continue; continue;
@ -101,7 +101,7 @@ static void TransferCargo(Vehicle *old_veh, Vehicle *new_head, bool part_of_chai
/* Find free space in the new chain */ /* Find free space in the new chain */
for (Vehicle *dest = new_head; dest != NULL && src->cargo.Count() > 0; dest = dest->Next()) { for (Vehicle *dest = new_head; dest != NULL && src->cargo.Count() > 0; dest = dest->Next()) {
if (!part_of_chain && dest->type == VEH_TRAIN && dest != new_head && dest != Train::From(new_head)->other_multiheaded_part && !IsArticulatedPart(dest)) { if (!part_of_chain && dest->type == VEH_TRAIN && dest != new_head && dest != Train::From(new_head)->other_multiheaded_part && !Train::From(dest)->IsArticulatedPart()) {
/* Skip vehicles, which do not belong to new_head */ /* Skip vehicles, which do not belong to new_head */
dest = GetLastEnginePart(Train::From(dest)); dest = GetLastEnginePart(Train::From(dest));
continue; continue;
@ -214,9 +214,9 @@ static CargoID GetNewCargoTypeForReplace(Vehicle *v, EngineID engine_type, bool
*/ */
static EngineID GetNewEngineType(const Vehicle *v, const Company *c) static EngineID GetNewEngineType(const Vehicle *v, const Company *c)
{ {
assert(v->type != VEH_TRAIN || !IsArticulatedPart(v)); assert(v->type != VEH_TRAIN || !Train::From(v)->IsArticulatedPart());
if (v->type == VEH_TRAIN && IsRearDualheaded(v)) { if (v->type == VEH_TRAIN && Train::From(v)->IsRearDualheaded()) {
/* we build the rear ends of multiheaded trains with the front ones */ /* we build the rear ends of multiheaded trains with the front ones */
return INVALID_ENGINE; return INVALID_ENGINE;
} }
@ -347,8 +347,8 @@ static CommandCost CopyHeadSpecificThings(Vehicle *old_head, Vehicle *new_head,
*/ */
static CommandCost ReplaceFreeUnit(Vehicle **single_unit, DoCommandFlag flags, bool *nothing_to_do) static CommandCost ReplaceFreeUnit(Vehicle **single_unit, DoCommandFlag flags, bool *nothing_to_do)
{ {
Vehicle *old_v = *single_unit; Train *old_v = Train::From(*single_unit);
assert(old_v->type == VEH_TRAIN && !IsArticulatedPart(old_v) && !IsRearDualheaded(old_v)); assert(!old_v->IsArticulatedPart() && !old_v->IsRearDualheaded());
CommandCost cost = CommandCost(EXPENSES_NEW_VEHICLES, 0); CommandCost cost = CommandCost(EXPENSES_NEW_VEHICLES, 0);
@ -618,7 +618,7 @@ CommandCost CmdAutoreplaceVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1
bool free_wagon = false; bool free_wagon = false;
if (v->type == VEH_TRAIN) { if (v->type == VEH_TRAIN) {
Train *t = Train::From(v); Train *t = Train::From(v);
if (IsArticulatedPart(t) || IsRearDualheaded(t)) return CMD_ERROR; if (t->IsArticulatedPart() || t->IsRearDualheaded()) return CMD_ERROR;
free_wagon = !t->IsFrontEngine(); free_wagon = !t->IsFrontEngine();
if (free_wagon && t->First()->IsFrontEngine()) return CMD_ERROR; if (free_wagon && t->First()->IsFrontEngine()) return CMD_ERROR;
} else { } else {

View File

@ -453,7 +453,7 @@ struct DepotWindow : Window {
while (v != NULL && (x -= 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 */ /* if an articulated part was selected, find its parent */
while (v != NULL && IsArticulatedPart(v)) v = v->Previous(); while (v != NULL && v->IsArticulatedPart()) v = v->Previous();
d->wagon = v; d->wagon = v;
@ -860,7 +860,7 @@ struct DepotWindow : Window {
loaded [w->cargo_type] += w->cargo.Count(); loaded [w->cargo_type] += w->cargo.Count();
} }
if (w->type == VEH_TRAIN && !EngineHasArticPart(w)) { if (w->type == VEH_TRAIN && !Train::From(w)->EngineHasArticPart()) {
num++; num++;
if (!whole_chain) break; if (!whole_chain) break;
} }

View File

@ -134,7 +134,7 @@ static int MapOldSubType(const Vehicle *v)
{ {
switch (v->type) { switch (v->type) {
case VEH_TRAIN: case VEH_TRAIN:
if (IsTrainEngine(v)) return 0; if (Train::From(v)->IsEngine()) return 0;
if (Train::From(v)->IsFreeWagon()) return 4; if (Train::From(v)->IsFreeWagon()) return 4;
return 2; return 2;
case VEH_ROAD: case VEH_ROAD:
@ -679,9 +679,9 @@ static uint32 VehicleGetVariable(const ResolverObject *object, byte variable, by
if (v->type == VEH_TRAIN) { if (v->type == VEH_TRAIN) {
const Train *t = Train::From(v); const Train *t = Train::From(v);
const Train *u = IsTrainWagon(v) && HasBit(v->vehicle_flags, VRF_POWEREDWAGON) ? t->First() : t; const Train *u = t->IsWagon() && HasBit(t->vehicle_flags, VRF_POWEREDWAGON) ? t->First() : t;
RailType railtype = GetRailType(v->tile); RailType railtype = GetRailType(v->tile);
bool powered = IsTrainEngine(v) || (IsTrainWagon(v) && HasBit(v->vehicle_flags, VRF_POWEREDWAGON)); bool powered = t->IsEngine() || (t->IsWagon() && HasBit(t->vehicle_flags, VRF_POWEREDWAGON));
bool has_power = powered && HasPowerOnRail(u->railtype, railtype); bool has_power = powered && HasPowerOnRail(u->railtype, railtype);
bool is_electric = powered && u->railtype == RAILTYPE_ELECTRIC; bool is_electric = powered && u->railtype == RAILTYPE_ELECTRIC;

View File

@ -1232,12 +1232,15 @@ CommandCost CmdRemoveSignalTrack(TileIndex tile, DoCommandFlag flags, uint32 p1,
/** Update power of train under which is the railtype being converted */ /** Update power of train under which is the railtype being converted */
Vehicle *UpdateTrainPowerProc(Vehicle *v, void *data) Vehicle *UpdateTrainPowerProc(Vehicle *v, void *data)
{ {
if (v->type != VEH_TRAIN) return NULL;
/* Similiar checks as in TrainPowerChanged() */ /* Similiar checks as in TrainPowerChanged() */
if (v->type == VEH_TRAIN && !IsArticulatedPart(v)) { Train *t = Train::From(v);
const RailVehicleInfo *rvi = RailVehInfo(v->engine_type); if (t->IsArticulatedPart()) return NULL;
if (GetVehicleProperty(v, 0x0B, rvi->power) != 0) TrainPowerChanged(Train::From(v)->First());
} const RailVehicleInfo *rvi = RailVehInfo(t->engine_type);
if (GetVehicleProperty(t, 0x0B, rvi->power) != 0) TrainPowerChanged(t->First());
return NULL; return NULL;
} }

View File

@ -47,8 +47,8 @@ void ConnectMultiheadedTrains()
for (Train *u = v; u != NULL; u = GetNextVehicle(u)) { for (Train *u = v; u != NULL; u = GetNextVehicle(u)) {
if (u->other_multiheaded_part != NULL) continue; // we already linked this one if (u->other_multiheaded_part != NULL) continue; // we already linked this one
if (IsMultiheaded(u)) { if (u->IsMultiheaded()) {
if (!IsTrainEngine(u)) { if (!u->IsEngine()) {
/* we got a rear car without a front car. We will convert it to a front one */ /* we got a rear car without a front car. We will convert it to a front one */
SetTrainEngine(u); SetTrainEngine(u);
u->spritenum--; u->spritenum--;
@ -59,10 +59,10 @@ void ConnectMultiheadedTrains()
Train *w; Train *w;
if (sequential_matching) { if (sequential_matching) {
for (w = GetNextVehicle(u); w != NULL; w = GetNextVehicle(w)) { for (w = GetNextVehicle(u); w != NULL; w = GetNextVehicle(w)) {
if (w->engine_type != eid || w->other_multiheaded_part != NULL || !IsMultiheaded(w)) continue; if (w->engine_type != eid || w->other_multiheaded_part != NULL || !w->IsMultiheaded()) continue;
/* we found a car to partner with this engine. Now we will make sure it face the right way */ /* we found a car to partner with this engine. Now we will make sure it face the right way */
if (IsTrainEngine(w)) { if (w->IsEngine()) {
ClearTrainEngine(w); ClearTrainEngine(w);
w->spritenum++; w->spritenum++;
} }
@ -71,9 +71,9 @@ void ConnectMultiheadedTrains()
} else { } else {
uint stack_pos = 0; uint stack_pos = 0;
for (w = GetNextVehicle(u); w != NULL; w = GetNextVehicle(w)) { for (w = GetNextVehicle(u); w != NULL; w = GetNextVehicle(w)) {
if (w->engine_type != eid || w->other_multiheaded_part != NULL || !IsMultiheaded(w)) continue; if (w->engine_type != eid || w->other_multiheaded_part != NULL || !w->IsMultiheaded()) continue;
if (IsTrainEngine(w)) { if (w->IsEngine()) {
stack_pos++; stack_pos++;
} else { } else {
if (stack_pos == 0) break; if (stack_pos == 0) break;
@ -310,7 +310,7 @@ void AfterLoadVehicles(bool part_of_load)
if (v->type == VEH_TRAIN) { if (v->type == VEH_TRAIN) {
Train *t = Train::From(v); Train *t = Train::From(v);
if (t->IsFrontEngine() || IsFreeWagon(t)) { if (t->IsFrontEngine() || t->IsFreeWagon()) {
t->tcache.last_speed = t->cur_speed; // update displayed train speed t->tcache.last_speed = t->cur_speed; // update displayed train speed
TrainConsistChanged(t, false); TrainConsistChanged(t, false);
} }
@ -322,11 +322,14 @@ void AfterLoadVehicles(bool part_of_load)
/* Stop non-front engines */ /* Stop non-front engines */
if (CheckSavegameVersion(112)) { if (CheckSavegameVersion(112)) {
FOR_ALL_VEHICLES(v) { FOR_ALL_VEHICLES(v) {
if (v->type == VEH_TRAIN && !Train::From(v)->IsFrontEngine()) { if (v->type == VEH_TRAIN) {
if (IsTrainEngine(v)) v->vehstatus |= VS_STOPPED; Train *t = Train::From(v);
/* cur_speed is now relevant for non-front parts - nonzero breaks if (!t->IsFrontEngine()) {
* moving-wagons-inside-depot- and autoreplace- code */ if (t->IsEngine()) t->vehstatus |= VS_STOPPED;
v->cur_speed = 0; /* cur_speed is now relevant for non-front parts - nonzero breaks
* moving-wagons-inside-depot- and autoreplace- code */
t->cur_speed = 0;
}
} }
/* trains weren't stopping gradually in old OTTD versions (and TTO/TTD) /* trains weren't stopping gradually in old OTTD versions (and TTO/TTD)
* other vehicle types didn't have zero speed while stopped (even in 'recent' OTTD versions) */ * other vehicle types didn't have zero speed while stopped (even in 'recent' OTTD versions) */

View File

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

View File

@ -69,16 +69,6 @@ static inline void ClearFrontEngine(Vehicle *v)
ClrBit(v->subtype, TS_FRONT); ClrBit(v->subtype, TS_FRONT);
} }
/** Check if a vehicle is an articulated part of an engine
* @param v vehicle to check
* @return Returns true if vehicle is an articulated part
*/
static inline bool IsArticulatedPart(const Vehicle *v)
{
assert(v->type == VEH_TRAIN);
return HasBit(v->subtype, TS_ARTICULATED_PART);
}
/** Set a vehicle to be an articulated part /** Set a vehicle to be an articulated part
* @param v vehicle to change * @param v vehicle to change
*/ */
@ -97,16 +87,6 @@ static inline void ClearArticulatedPart(Vehicle *v)
ClrBit(v->subtype, TS_ARTICULATED_PART); ClrBit(v->subtype, TS_ARTICULATED_PART);
} }
/** Check if a vehicle is a wagon
* @param v vehicle to check
* @return Returns true if vehicle is a wagon
*/
static inline bool IsTrainWagon(const Vehicle *v)
{
assert(v->type == VEH_TRAIN);
return HasBit(v->subtype, TS_WAGON);
}
/** Set a vehicle to be a wagon /** Set a vehicle to be a wagon
* @param v vehicle to change * @param v vehicle to change
*/ */
@ -125,16 +105,6 @@ static inline void ClearTrainWagon(Vehicle *v)
ClrBit(v->subtype, TS_WAGON); ClrBit(v->subtype, TS_WAGON);
} }
/** Check if a vehicle is an engine (can be first in a train)
* @param v vehicle to check
* @return Returns true if vehicle is an engine
*/
static inline bool IsTrainEngine(const Vehicle *v)
{
assert(v->type == VEH_TRAIN);
return HasBit(v->subtype, TS_ENGINE);
}
/** Set engine status /** Set engine status
* @param v vehicle to change * @param v vehicle to change
*/ */
@ -153,16 +123,6 @@ static inline void ClearTrainEngine(Vehicle *v)
ClrBit(v->subtype, TS_ENGINE); ClrBit(v->subtype, TS_ENGINE);
} }
/** Check if a vehicle is a free wagon (got no engine in front of it)
* @param v vehicle to check
* @return Returns true if vehicle is a free wagon
*/
static inline bool IsFreeWagon(const Vehicle *v)
{
assert(v->type == VEH_TRAIN);
return HasBit(v->subtype, TS_FREE_WAGON);
}
/** Set if a vehicle is a free wagon /** Set if a vehicle is a free wagon
* @param v vehicle to change * @param v vehicle to change
*/ */
@ -181,15 +141,6 @@ static inline void ClearFreeWagon(Vehicle *v)
ClrBit(v->subtype, TS_FREE_WAGON); ClrBit(v->subtype, TS_FREE_WAGON);
} }
/** Check if a vehicle is a multiheaded engine
* @param v vehicle to check
* @return Returns true if vehicle is a multiheaded engine
*/
static inline bool IsMultiheaded(const Vehicle *v)
{
assert(v->type == VEH_TRAIN);
return HasBit(v->subtype, TS_MULTIHEADED);
}
/** Set if a vehicle is a multiheaded engine /** Set if a vehicle is a multiheaded engine
* @param v vehicle to change * @param v vehicle to change
@ -209,26 +160,6 @@ static inline void ClearMultiheaded(Vehicle *v)
ClrBit(v->subtype, TS_MULTIHEADED); ClrBit(v->subtype, TS_MULTIHEADED);
} }
/** Check if an engine has an articulated part.
* @param v Vehicle.
* @return True if the engine has an articulated part.
*/
static inline bool EngineHasArticPart(const Vehicle *v)
{
assert(v->type == VEH_TRAIN);
return (v->Next() != NULL && IsArticulatedPart(v->Next()));
}
/** Tell if we are dealing with the rear end of a multiheaded engine.
* @param v Vehicle.
* @return True if the engine is the rear part of a dualheaded engine.
*/
static inline bool IsRearDualheaded(const Vehicle *v)
{
assert(v->type == VEH_TRAIN);
return (IsMultiheaded(v) && !IsTrainEngine(v));
}
void CcBuildLoco(bool success, TileIndex tile, uint32 p1, uint32 p2); void CcBuildLoco(bool success, TileIndex tile, uint32 p1, uint32 p2);
void CcBuildWagon(bool success, TileIndex tile, uint32 p1, uint32 p2); void CcBuildWagon(bool success, TileIndex tile, uint32 p1, uint32 p2);
@ -337,18 +268,56 @@ struct Train : public SpecializedVehicle<Train, VEH_TRAIN> {
* @return Returns true if train is a free wagon * @return Returns true if train is a free wagon
*/ */
FORCEINLINE bool IsFreeWagon() const { return HasBit(this->subtype, TS_FREE_WAGON); } FORCEINLINE bool IsFreeWagon() const { return HasBit(this->subtype, TS_FREE_WAGON); }
/**
* Check if a vehicle is an engine (can be first in a train)
* @return Returns true if vehicle is an engine
*/
FORCEINLINE bool IsEngine() const { return HasBit(this->subtype, TS_ENGINE); }
/**
* Check if a train is a wagon
* @param v vehicle to check
* @return Returns true if vehicle is a wagon
*/
FORCEINLINE bool IsWagon() const { return HasBit(this->subtype, TS_WAGON); }
/**
* Check if train is a multiheaded engine
* @return Returns true if vehicle is a multiheaded engine
*/
FORCEINLINE bool IsMultiheaded() const { return HasBit(this->subtype, TS_MULTIHEADED); }
/**
* Tell if we are dealing with the rear end of a multiheaded engine.
* @return True if the engine is the rear part of a dualheaded engine.
*/
FORCEINLINE bool IsRearDualheaded() const { return this->IsMultiheaded() && !this->IsEngine(); }
/**
* Check if train is an articulated part of an engine
* @return Returns true if train is an articulated part
*/
FORCEINLINE bool IsArticulatedPart() const { return HasBit(this->subtype, TS_ARTICULATED_PART); }
/**
* Check if an engine has an articulated part.
* @return True if the engine has an articulated part.
*/
FORCEINLINE bool EngineHasArticPart() const { return this->Next() != NULL && this->Next()->IsArticulatedPart(); }
}; };
#define FOR_ALL_TRAINS(var) FOR_ALL_VEHICLES_OF_TYPE(Train, var) #define FOR_ALL_TRAINS(var) FOR_ALL_VEHICLES_OF_TYPE(Train, var)
/** /**
* Get the next part of a multi-part engine. * Get the next part of a multi-part engine.
* Will only work on a multi-part engine (EngineHasArticPart(v) == true), * Will only work on a multi-part engine (v->EngineHasArticPart() == true),
* Result is undefined for normal engine. * Result is undefined for normal engine.
*/ */
static inline Train *GetNextArticPart(const Train *v) static inline Train *GetNextArticPart(const Train *v)
{ {
assert(EngineHasArticPart(v)); assert(v->EngineHasArticPart());
return v->Next(); return v->Next();
} }
@ -358,8 +327,7 @@ static inline Train *GetNextArticPart(const Train *v)
*/ */
static inline Train *GetLastEnginePart(Train *v) static inline Train *GetLastEnginePart(Train *v)
{ {
assert(v->type == VEH_TRAIN); while (v->EngineHasArticPart()) v = GetNextArticPart(v);
while (EngineHasArticPart(v)) v = GetNextArticPart(v);
return v; return v;
} }
@ -369,8 +337,7 @@ static inline Train *GetLastEnginePart(Train *v)
*/ */
static inline Train *GetNextVehicle(const Train *v) static inline Train *GetNextVehicle(const Train *v)
{ {
assert(v->type == VEH_TRAIN); while (v->EngineHasArticPart()) v = GetNextArticPart(v);
while (EngineHasArticPart(v)) v = GetNextArticPart(v);
/* v now contains the last artic part in the engine */ /* v now contains the last artic part in the engine */
return v->Next(); return v->Next();
@ -382,10 +349,8 @@ static inline Train *GetNextVehicle(const Train *v)
*/ */
static inline Train *GetPrevVehicle(const Train *w) static inline Train *GetPrevVehicle(const Train *w)
{ {
assert(w->type == VEH_TRAIN);
Train *v = w->Previous(); Train *v = w->Previous();
while (v != NULL && IsArticulatedPart(v)) v = v->Previous(); while (v != NULL && v->IsArticulatedPart()) v = v->Previous();
return v; return v;
} }
@ -396,9 +361,8 @@ static inline Train *GetPrevVehicle(const Train *w)
*/ */
static inline Train *GetNextUnit(const Train *v) static inline Train *GetNextUnit(const Train *v)
{ {
assert(v->type == VEH_TRAIN);
Train *w = GetNextVehicle(v); Train *w = GetNextVehicle(v);
if (w != NULL && IsRearDualheaded(w)) w = GetNextVehicle(w); if (w != NULL && w->IsRearDualheaded()) w = GetNextVehicle(w);
return w; return w;
} }
@ -409,9 +373,8 @@ static inline Train *GetNextUnit(const Train *v)
*/ */
static inline Train *GetPrevUnit(const Train *v) static inline Train *GetPrevUnit(const Train *v)
{ {
assert(v->type == VEH_TRAIN);
Train *w = GetPrevVehicle(v); Train *w = GetPrevVehicle(v);
if (w != NULL && IsRearDualheaded(w)) w = GetPrevVehicle(w); if (w != NULL && w->IsRearDualheaded()) w = GetPrevVehicle(w);
return w; return w;
} }

View File

@ -94,7 +94,7 @@ void TrainPowerChanged(Train *v)
RailType railtype = GetRailType(u->tile); RailType railtype = GetRailType(u->tile);
/* Power is not added for articulated parts */ /* Power is not added for articulated parts */
if (!IsArticulatedPart(u)) { if (!u->IsArticulatedPart()) {
bool engine_has_power = HasPowerOnRail(u->railtype, railtype); bool engine_has_power = HasPowerOnRail(u->railtype, railtype);
const RailVehicleInfo *rvi_u = RailVehInfo(u->engine_type); const RailVehicleInfo *rvi_u = RailVehInfo(u->engine_type);
@ -103,7 +103,7 @@ void TrainPowerChanged(Train *v)
uint16 power = GetVehicleProperty(u, 0x0B, rvi_u->power); uint16 power = GetVehicleProperty(u, 0x0B, rvi_u->power);
if (power != 0) { if (power != 0) {
/* Halve power for multiheaded parts */ /* Halve power for multiheaded parts */
if (IsMultiheaded(u)) power /= 2; if (u->IsMultiheaded()) power /= 2;
total_power += power; total_power += power;
/* Tractive effort in (tonnes * 1000 * 10 =) N */ /* Tractive effort in (tonnes * 1000 * 10 =) N */
@ -142,7 +142,7 @@ static void TrainCargoChanged(Train *v)
uint32 vweight = GetCargo(u->cargo_type)->weight * u->cargo.Count() * FreightWagonMult(u->cargo_type) / 16; uint32 vweight = GetCargo(u->cargo_type)->weight * u->cargo.Count() * FreightWagonMult(u->cargo_type) / 16;
/* Vehicle weight is not added for articulated parts. */ /* Vehicle weight is not added for articulated parts. */
if (!IsArticulatedPart(u)) { if (!u->IsArticulatedPart()) {
/* vehicle weight is the sum of the weight of the vehicle and the weight of its cargo */ /* vehicle weight is the sum of the weight of the vehicle and the weight of its cargo */
vweight += GetVehicleProperty(u, 0x16, RailVehInfo(u->engine_type)->weight); vweight += GetVehicleProperty(u, 0x16, RailVehInfo(u->engine_type)->weight);
} }
@ -236,7 +236,7 @@ void TrainConsistChanged(Train *v, bool same_length)
u->tcache.first_engine = v == u ? INVALID_ENGINE : first_engine; u->tcache.first_engine = v == u ? INVALID_ENGINE : first_engine;
u->railtype = rvi_u->railtype; u->railtype = rvi_u->railtype;
if (IsTrainEngine(u)) first_engine = u->engine_type; if (u->IsEngine()) first_engine = u->engine_type;
/* Set user defined data to its default value */ /* Set user defined data to its default value */
u->tcache.user_def_data = rvi_u->user_def_data; u->tcache.user_def_data = rvi_u->user_def_data;
@ -266,7 +266,7 @@ void TrainConsistChanged(Train *v, bool same_length)
if (rvi_u->visual_effect != 0) { if (rvi_u->visual_effect != 0) {
u->tcache.cached_vis_effect = rvi_u->visual_effect; u->tcache.cached_vis_effect = rvi_u->visual_effect;
} else { } else {
if (IsTrainWagon(u) || IsArticulatedPart(u)) { if (u->IsWagon() || u->IsArticulatedPart()) {
/* Wagons and articulated parts have no effect by default */ /* Wagons and articulated parts have no effect by default */
u->tcache.cached_vis_effect = 0x40; u->tcache.cached_vis_effect = 0x40;
} else if (rvi_u->engclass == 0) { } else if (rvi_u->engclass == 0) {
@ -293,7 +293,7 @@ void TrainConsistChanged(Train *v, bool same_length)
ClrBit(u->flags, VRF_POWEREDWAGON); ClrBit(u->flags, VRF_POWEREDWAGON);
} }
if (!IsArticulatedPart(u)) { if (!u->IsArticulatedPart()) {
/* Do not count powered wagons for the compatible railtypes, as wagons always /* Do not count powered wagons for the compatible railtypes, as wagons always
have railtype normal */ have railtype normal */
if (rvi_u->power > 0) { if (rvi_u->power > 0) {
@ -675,7 +675,7 @@ static CommandCost CmdBuildRailWagon(EngineID engine, TileIndex tile, DoCommandF
Train *w; Train *w;
FOR_ALL_TRAINS(w) { FOR_ALL_TRAINS(w) {
/* do not connect new wagon with crashed/flooded consists */ /* do not connect new wagon with crashed/flooded consists */
if (w->tile == tile && IsFreeWagon(w) && if (w->tile == tile && w->IsFreeWagon() &&
w->engine_type == engine && w->engine_type == engine &&
!(w->vehstatus & VS_CRASHED)) { !(w->vehstatus & VS_CRASHED)) {
u = GetLastVehicleInChain(w); u = GetLastVehicleInChain(w);
@ -936,7 +936,7 @@ int CheckTrainInDepot(const Train *v, bool needs_to_be_stopped)
* engines with more articulated parts than before works correctly. * engines with more articulated parts than before works correctly.
* *
* Also skip counting rear ends of multiheaded engines */ * Also skip counting rear ends of multiheaded engines */
if (!IsArticulatedPart(v) && !IsRearDualheaded(v)) count++; if (!v->IsArticulatedPart() && !v->IsRearDualheaded()) count++;
if (v->track != TRACK_BIT_DEPOT || v->tile != tile || if (v->track != TRACK_BIT_DEPOT || v->tile != tile ||
(v->IsFrontEngine() && needs_to_be_stopped && !(v->vehstatus & VS_STOPPED))) { (v->IsFrontEngine() && needs_to_be_stopped && !(v->vehstatus & VS_STOPPED))) {
return -1; return -1;
@ -971,7 +971,7 @@ static Train *UnlinkWagon(Train *v, Train *first)
v = GetNextVehicle(v); v = GetNextVehicle(v);
if (v == NULL) return NULL; if (v == NULL) return NULL;
if (IsTrainWagon(v)) SetFreeWagon(v); if (v->IsWagon()) SetFreeWagon(v);
/* First can be an articulated engine, meaning GetNextVehicle() isn't /* First can be an articulated engine, meaning GetNextVehicle() isn't
* v->Next(). Thus set the next vehicle of the last articulated part * v->Next(). Thus set the next vehicle of the last articulated part
@ -994,7 +994,7 @@ static Train *FindGoodVehiclePos(const Train *src)
Train *dst; Train *dst;
FOR_ALL_TRAINS(dst) { FOR_ALL_TRAINS(dst) {
if (IsFreeWagon(dst) && dst->tile == tile && !(dst->vehstatus & VS_CRASHED)) { if (dst->IsFreeWagon() && dst->tile == tile && !(dst->vehstatus & VS_CRASHED)) {
/* check so all vehicles in the line have the same engine. */ /* check so all vehicles in the line have the same engine. */
Train *t = dst; Train *t = dst;
while (t->engine_type == eng) { while (t->engine_type == eng) {
@ -1035,11 +1035,11 @@ static void NormaliseTrainConsist(Train *v)
assert(v->IsFrontEngine()); assert(v->IsFrontEngine());
for (; v != NULL; v = GetNextVehicle(v)) { for (; v != NULL; v = GetNextVehicle(v)) {
if (!IsMultiheaded(v) || !IsTrainEngine(v)) continue; if (!v->IsMultiheaded() || !v->IsEngine()) continue;
/* make sure that there are no free cars before next engine */ /* make sure that there are no free cars before next engine */
Train *u; Train *u;
for (u = v; u->Next() != NULL && !IsTrainEngine(u->Next()); u = u->Next()) {} for (u = v; u->Next() != NULL && !u->Next()->IsEngine(); u = u->Next()) {}
if (u == v->other_multiheaded_part) continue; if (u == v->other_multiheaded_part) continue;
AddWagonToConsist(v->other_multiheaded_part, u); AddWagonToConsist(v->other_multiheaded_part, u);
@ -1069,7 +1069,7 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u
/* if nothing is selected as destination, try and find a matching vehicle to drag to. */ /* if nothing is selected as destination, try and find a matching vehicle to drag to. */
Train *dst; Train *dst;
if (d == INVALID_VEHICLE) { if (d == INVALID_VEHICLE) {
dst = IsTrainEngine(src) ? NULL : FindGoodVehiclePos(src); dst = src->IsEngine() ? NULL : FindGoodVehiclePos(src);
} else { } else {
dst = Train::GetIfValid(d); dst = Train::GetIfValid(d);
if (dst == NULL || !CheckOwnership(dst->owner)) return CMD_ERROR; if (dst == NULL || !CheckOwnership(dst->owner)) return CMD_ERROR;
@ -1079,9 +1079,9 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u
} }
/* if an articulated part is being handled, deal with its parent vehicle */ /* if an articulated part is being handled, deal with its parent vehicle */
while (IsArticulatedPart(src)) src = src->Previous(); while (src->IsArticulatedPart()) src = src->Previous();
if (dst != NULL) { if (dst != NULL) {
while (IsArticulatedPart(dst)) dst = dst->Previous(); while (dst->IsArticulatedPart()) dst = dst->Previous();
} }
/* don't move the same vehicle.. */ /* don't move the same vehicle.. */
@ -1099,7 +1099,7 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u
dst_head = NULL; dst_head = NULL;
} }
if (IsRearDualheaded(src)) return_cmd_error(STR_ERROR_REAR_ENGINE_FOLLOW_FRONT); if (src->IsRearDualheaded()) return_cmd_error(STR_ERROR_REAR_ENGINE_FOLLOW_FRONT);
/* when moving all wagons, we can't have the same src_head and dst_head */ /* when moving all wagons, we can't have the same src_head and dst_head */
if (HasBit(p2, 0) && src_head == dst_head) return CommandCost(); if (HasBit(p2, 0) && src_head == dst_head) return CommandCost();
@ -1137,17 +1137,17 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u
/* Abort if we're adding too many wagons to a train. */ /* Abort if we're adding too many wagons to a train. */
if (dst_head != NULL && dst_head->IsFrontEngine()) 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. */ /* 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); if (dst_head == NULL && src->IsEngine()) return_cmd_error(STR_ERROR_TRAIN_TOO_LONG);
} }
} else { } else {
/* Abort if we're creating a new train on an existing row. */ /* Abort if we're creating a new train on an existing row. */
if (src_len > max_len && src == src_head && IsTrainEngine(GetNextVehicle(src_head))) if (src_len > max_len && src == src_head && GetNextVehicle(src_head)->IsEngine())
return_cmd_error(STR_ERROR_TRAIN_TOO_LONG); return_cmd_error(STR_ERROR_TRAIN_TOO_LONG);
} }
} }
/* moving a loco to a new line?, then we need to assign a unitnumber. */ /* moving a loco to a new line?, then we need to assign a unitnumber. */
if (dst == NULL && !src->IsFrontEngine() && IsTrainEngine(src)) { if (dst == NULL && !src->IsFrontEngine() && src->IsEngine()) {
UnitID unit_num = ((flags & DC_AUTOREPLACE) != 0 ? 0 : GetFreeUnitNumber(VEH_TRAIN)); UnitID unit_num = ((flags & DC_AUTOREPLACE) != 0 ? 0 : GetFreeUnitNumber(VEH_TRAIN));
if (unit_num > _settings_game.vehicle.max_trains) if (unit_num > _settings_game.vehicle.max_trains)
return_cmd_error(STR_ERROR_TOO_MANY_VEHICLES_IN_GAME); return_cmd_error(STR_ERROR_TOO_MANY_VEHICLES_IN_GAME);
@ -1156,9 +1156,9 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u
} }
/* When we move the front vehicle, the second vehicle might need a unitnumber */ /* When we move the front vehicle, the second vehicle might need a unitnumber */
if (!HasBit(p2, 0) && (IsFreeWagon(src) || (src->IsFrontEngine() && dst == NULL)) && (flags & DC_AUTOREPLACE) == 0) { if (!HasBit(p2, 0) && (src->IsFreeWagon() || (src->IsFrontEngine() && dst == NULL)) && (flags & DC_AUTOREPLACE) == 0) {
Vehicle *second = GetNextUnit(src); Train *second = GetNextUnit(src);
if (second != NULL && IsTrainEngine(second) && GetFreeUnitNumber(VEH_TRAIN) > _settings_game.vehicle.max_trains) { if (second != NULL && second->IsEngine() && GetFreeUnitNumber(VEH_TRAIN) > _settings_game.vehicle.max_trains) {
return_cmd_error(STR_ERROR_TOO_MANY_VEHICLES_IN_GAME); return_cmd_error(STR_ERROR_TOO_MANY_VEHICLES_IN_GAME);
} }
} }
@ -1200,7 +1200,7 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u
while (next_to_attach != NULL) { while (next_to_attach != NULL) {
/* Don't check callback for articulated or rear dual headed parts */ /* Don't check callback for articulated or rear dual headed parts */
if (!IsArticulatedPart(next_to_attach) && !IsRearDualheaded(next_to_attach)) { if (!next_to_attach->IsArticulatedPart() && !next_to_attach->IsRearDualheaded()) {
/* Back up and clear the first_engine data to avoid using wagon override group */ /* Back up and clear the first_engine data to avoid using wagon override group */
EngineID first_engine = next_to_attach->tcache.first_engine; EngineID first_engine = next_to_attach->tcache.first_engine;
next_to_attach->tcache.first_engine = INVALID_ENGINE; next_to_attach->tcache.first_engine = INVALID_ENGINE;
@ -1268,9 +1268,9 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u
/* If we move the front Engine and if the second vehicle is not an engine /* If we move the front Engine and if the second vehicle is not an engine
add the whole vehicle to the DEFAULT_GROUP */ add the whole vehicle to the DEFAULT_GROUP */
if (src->IsFrontEngine() && !IsDefaultGroupID(src->group_id)) { if (src->IsFrontEngine() && !IsDefaultGroupID(src->group_id)) {
Vehicle *v = GetNextVehicle(src); Train *v = GetNextVehicle(src);
if (v != NULL && IsTrainEngine(v)) { if (v != NULL && v->IsEngine()) {
v->group_id = src->group_id; v->group_id = src->group_id;
src->group_id = DEFAULT_GROUP; src->group_id = DEFAULT_GROUP;
} }
@ -1299,7 +1299,7 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u
InvalidateWindowData(WC_VEHICLE_DEPOT, src->tile); 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. */ /* move the train to an empty line. for locomotives, we set the type to TS_Front. for wagons, 4. */
if (IsTrainEngine(src)) { if (src->IsEngine()) {
if (!src->IsFrontEngine()) { if (!src->IsFrontEngine()) {
/* setting the type to 0 also involves setting up the orders field. */ /* setting the type to 0 also involves setting up the orders field. */
SetFrontEngine(src); SetFrontEngine(src);
@ -1329,7 +1329,7 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u
RemoveVehicleFromGroup(src); RemoveVehicleFromGroup(src);
} }
if (src->IsFrontEngine() || IsFreeWagon(src)) { if (src->IsFrontEngine() || src->IsFreeWagon()) {
InvalidateWindowData(WC_VEHICLE_DEPOT, src->tile); InvalidateWindowData(WC_VEHICLE_DEPOT, src->tile);
ClearFrontEngine(src); ClearFrontEngine(src);
ClearFreeWagon(src); ClearFreeWagon(src);
@ -1356,7 +1356,7 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u
/* If there is an engine behind first_engine we moved away, it should become new first_engine /* 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 * 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 */ * we can't loop forever here because next time we reach this line we will have a front engine */
if (src_head != NULL && !src_head->IsFrontEngine() && IsTrainEngine(src_head)) { if (src_head != NULL && !src_head->IsFrontEngine() && src_head->IsEngine()) {
/* As in CmdMoveRailVehicle src_head->group_id will be equal to DEFAULT_GROUP /* 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 */ * we need to save the group and reaffect it to src_head */
const GroupID tmp_g = src_head->group_id; const GroupID tmp_g = src_head->group_id;
@ -1417,7 +1417,7 @@ CommandCost CmdSellRailWagon(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
if (v->vehstatus & VS_CRASHED) return_cmd_error(STR_CAN_T_SELL_DESTROYED_VEHICLE); if (v->vehstatus & VS_CRASHED) return_cmd_error(STR_CAN_T_SELL_DESTROYED_VEHICLE);
while (IsArticulatedPart(v)) v = v->Previous(); while (v->IsArticulatedPart()) v = v->Previous();
Train *first = v->First(); Train *first = v->First();
/* make sure the vehicle is stopped in the depot */ /* make sure the vehicle is stopped in the depot */
@ -1425,7 +1425,7 @@ CommandCost CmdSellRailWagon(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
return_cmd_error(STR_ERROR_TRAINS_CAN_ONLY_BE_ALTERED_INSIDE_A_DEPOT); 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 (v->IsRearDualheaded()) return_cmd_error(STR_ERROR_REAR_ENGINE_FOLLOW_FRONT);
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
if (v == first && first->IsFrontEngine()) { if (v == first && first->IsFrontEngine()) {
@ -1446,8 +1446,8 @@ CommandCost CmdSellRailWagon(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
/* 1. Delete the engine, if it is dualheaded also delete the matching /* 1. Delete the engine, if it is dualheaded also delete the matching
* rear engine of the loco (from the point of deletion onwards) */ * rear engine of the loco (from the point of deletion onwards) */
Train *rear = (IsMultiheaded(v) && Train *rear = (v->IsMultiheaded() &&
IsTrainEngine(v)) ? v->other_multiheaded_part : NULL; v->IsEngine()) ? v->other_multiheaded_part : NULL;
if (rear != NULL) { if (rear != NULL) {
cost.AddCost(-rear->value); cost.AddCost(-rear->value);
@ -1465,8 +1465,8 @@ CommandCost CmdSellRailWagon(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
/* 2.2 If there are wagons present after the deleted front engine, check /* 2.2 If there are wagons present after the deleted front engine, check
* if the second wagon (which will be first) is an engine. If it is one, * if the second wagon (which will be first) is an engine. If it is one,
* promote it as a new train, retaining the unitnumber, orders */ * promote it as a new train, retaining the unitnumber, orders */
if (new_f != NULL && IsTrainEngine(new_f)) { if (new_f != NULL && new_f->IsEngine()) {
if (IsTrainEngine(first)) { if (first->IsEngine()) {
/* Let the new front engine take over the setup of the old engine */ /* Let the new front engine take over the setup of the old engine */
switch_engine = true; switch_engine = true;
@ -1523,8 +1523,8 @@ CommandCost CmdSellRailWagon(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
for (Train *tmp; v != NULL; v = tmp) { for (Train *tmp; v != NULL; v = tmp) {
tmp = GetNextVehicle(v); tmp = GetNextVehicle(v);
if (IsMultiheaded(v)) { if (v->IsMultiheaded()) {
if (IsTrainEngine(v)) { if (v->IsEngine()) {
/* We got a front engine of a multiheaded set. Now we will sell the rear end too */ /* We got a front engine of a multiheaded set. Now we will sell the rear end too */
Train *rear = v->other_multiheaded_part; Train *rear = v->other_multiheaded_part;
@ -1974,7 +1974,7 @@ CommandCost CmdReverseTrainDirection(TileIndex tile, DoCommandFlag flags, uint32
if (p2 != 0) { if (p2 != 0) {
/* turn a single unit around */ /* turn a single unit around */
if (IsMultiheaded(v) || HasBit(EngInfo(v->engine_type)->callbackmask, CBM_VEHICLE_ARTIC_ENGINE)) { if (v->IsMultiheaded() || HasBit(EngInfo(v->engine_type)->callbackmask, CBM_VEHICLE_ARTIC_ENGINE)) {
return_cmd_error(STR_ONLY_TURN_SINGLE_UNIT); return_cmd_error(STR_ONLY_TURN_SINGLE_UNIT);
} }
@ -4436,7 +4436,7 @@ Money Train::GetRunningCost() const
if (cost_factor == 0) continue; if (cost_factor == 0) continue;
/* Halve running cost for multiheaded parts */ /* Halve running cost for multiheaded parts */
if (IsMultiheaded(v)) cost_factor /= 2; if (v->IsMultiheaded()) cost_factor /= 2;
cost += cost_factor * GetPriceByIndex(rvi->running_cost_class); cost += cost_factor * GetPriceByIndex(rvi->running_cost_class);
} while ((v = GetNextVehicle(v)) != NULL); } while ((v = GetNextVehicle(v)) != NULL);
@ -4536,7 +4536,7 @@ void Train::OnNewDay()
InvalidateWindow(WC_VEHICLE_DETAILS, this->index); InvalidateWindow(WC_VEHICLE_DETAILS, this->index);
InvalidateWindowClasses(WC_TRAINS_LIST); InvalidateWindowClasses(WC_TRAINS_LIST);
} }
} else if (IsTrainEngine(this)) { } else if (this->IsEngine()) {
/* Also age engines that aren't front engines */ /* Also age engines that aren't front engines */
AgeVehicle(this); AgeVehicle(this);
} }

View File

@ -200,8 +200,8 @@ int GetTrainDetailsWndVScroll(VehicleID veh_id, TrainDetailsWindowTabs det_tab)
} }
num++; // needs one more because first line is description string num++; // needs one more because first line is description string
} else { } else {
for (const Vehicle *v = Vehicle::Get(veh_id) ; v != NULL ; v = v->Next()) { for (const Train *v = Train::Get(veh_id) ; v != NULL ; v = v->Next()) {
if (!IsArticulatedPart(v) || v->cargo_cap != 0) num++; if (!v->IsArticulatedPart() || v->cargo_cap != 0) num++;
} }
} }
@ -219,11 +219,11 @@ int GetTrainDetailsWndVScroll(VehicleID veh_id, TrainDetailsWindowTabs det_tab)
* @param vscroll_cap Number of lines currently displayed * @param vscroll_cap Number of lines currently displayed
* @param det_tab Selected details tab * @param det_tab Selected details tab
*/ */
void DrawTrainDetails(const Vehicle *v, int left, int right, int y, int vscroll_pos, uint16 vscroll_cap, TrainDetailsWindowTabs det_tab) void DrawTrainDetails(const Train *v, int left, int right, int y, int vscroll_pos, uint16 vscroll_cap, TrainDetailsWindowTabs det_tab)
{ {
/* draw the first 3 details tabs */ /* draw the first 3 details tabs */
if (det_tab != TDW_TAB_TOTALS) { if (det_tab != TDW_TAB_TOTALS) {
const Vehicle *u = v; const Train *u = v;
int x = 1; int x = 1;
for (;;) { for (;;) {
if (--vscroll_pos < 0 && vscroll_pos >= -vscroll_cap) { if (--vscroll_pos < 0 && vscroll_pos >= -vscroll_cap) {
@ -235,7 +235,7 @@ void DrawTrainDetails(const Vehicle *v, int left, int right, int y, int vscroll_
DrawSprite(u->GetImage(DIR_W), pal, x + WagonLengthToPixels(4 + dx), y + 6 + (is_custom_sprite(RailVehInfo(u->engine_type)->image_index) ? _traininfo_vehicle_pitch : 0)); DrawSprite(u->GetImage(DIR_W), pal, x + WagonLengthToPixels(4 + dx), y + 6 + (is_custom_sprite(RailVehInfo(u->engine_type)->image_index) ? _traininfo_vehicle_pitch : 0));
dx += Train::From(u)->tcache.cached_veh_length; dx += Train::From(u)->tcache.cached_veh_length;
u = u->Next(); u = u->Next();
} while (u != NULL && IsArticulatedPart(u) && u->cargo_cap == 0); } while (u != NULL && u->IsArticulatedPart() && u->cargo_cap == 0);
int px = x + WagonLengthToPixels(dx) + 2; int px = x + WagonLengthToPixels(dx) + 2;
int py = y + 2; int py = y + 2;
@ -248,7 +248,7 @@ void DrawTrainDetails(const Vehicle *v, int left, int right, int y, int vscroll_
case TDW_TAB_INFO: case TDW_TAB_INFO:
/* Only show name and value for the 'real' part */ /* Only show name and value for the 'real' part */
if (!IsArticulatedPart(v)) { if (!v->IsArticulatedPart()) {
TrainDetailsInfoTab(v, px, right, py); TrainDetailsInfoTab(v, px, right, py);
} }
break; break;
@ -264,7 +264,7 @@ void DrawTrainDetails(const Vehicle *v, int left, int right, int y, int vscroll_
/* Move to the next line */ /* Move to the next line */
do { do {
v = v->Next(); v = v->Next();
} while (v != NULL && IsArticulatedPart(v) && v->cargo_cap == 0); } while (v != NULL && v->IsArticulatedPart() && v->cargo_cap == 0);
} }
if (v == NULL) return; if (v == NULL) return;
} }

View File

@ -481,8 +481,8 @@ bool IsEngineCountable(const Vehicle *v)
switch (v->type) { switch (v->type) {
case VEH_AIRCRAFT: return IsNormalAircraft(v); // don't count plane shadows and helicopter rotors case VEH_AIRCRAFT: return IsNormalAircraft(v); // don't count plane shadows and helicopter rotors
case VEH_TRAIN: case VEH_TRAIN:
return !IsArticulatedPart(v) && // tenders and other articulated parts return !Train::From(v)->IsArticulatedPart() && // tenders and other articulated parts
!IsRearDualheaded(v); // rear parts of multiheaded engines !Train::From(v)->IsRearDualheaded(); // rear parts of multiheaded engines
case VEH_ROAD: return IsRoadVehFront(v); case VEH_ROAD: return IsRoadVehFront(v);
case VEH_SHIP: return true; case VEH_SHIP: return true;
default: return false; // Only count company buildable vehicles default: return false; // Only count company buildable vehicles
@ -518,7 +518,7 @@ void Vehicle::PreDestructor()
} }
} }
if (this->type != VEH_TRAIN || (this->type == VEH_TRAIN && (Train::From(this)->IsFrontEngine() || IsFreeWagon(this)))) { if (this->Previous() == NULL) {
InvalidateWindowData(WC_VEHICLE_DEPOT, this->tile); InvalidateWindowData(WC_VEHICLE_DEPOT, this->tile);
} }
@ -601,7 +601,7 @@ void CallVehicleTicks()
case VEH_ROAD: case VEH_ROAD:
case VEH_AIRCRAFT: case VEH_AIRCRAFT:
case VEH_SHIP: case VEH_SHIP:
if (v->type == VEH_TRAIN && IsTrainWagon(v)) continue; if (v->type == VEH_TRAIN && Train::From(v)->IsWagon()) continue;
if (v->type == VEH_AIRCRAFT && v->subtype != AIR_HELICOPTER) continue; if (v->type == VEH_AIRCRAFT && v->subtype != AIR_HELICOPTER) continue;
if (v->type == VEH_ROAD && !IsRoadVehFront(v)) continue; if (v->type == VEH_ROAD && !IsRoadVehFront(v)) continue;
@ -1277,7 +1277,7 @@ const Livery *GetEngineLivery(EngineID engine_type, CompanyID company, EngineID
default: NOT_REACHED(); default: NOT_REACHED();
case VEH_TRAIN: { case VEH_TRAIN: {
const RailVehicleInfo *rvi = RailVehInfo(engine_type); const RailVehicleInfo *rvi = RailVehInfo(engine_type);
if (v != NULL && parent_engine_type != INVALID_ENGINE && (UsesWagonOverride(v) || (IsArticulatedPart(v) && rvi->railveh_type != RAILVEH_WAGON))) { if (v != NULL && parent_engine_type != INVALID_ENGINE && (UsesWagonOverride(v) || (Train::From(v)->IsArticulatedPart() && rvi->railveh_type != RAILVEH_WAGON))) {
/* Wagonoverrides use the coloir scheme of the front engine. /* Wagonoverrides use the coloir scheme of the front engine.
* Articulated parts use the colour scheme of the first part. (Not supported for articulated wagons) */ * Articulated parts use the colour scheme of the first part. (Not supported for articulated wagons) */
engine_type = parent_engine_type; engine_type = parent_engine_type;

View File

@ -367,7 +367,7 @@ CommandCost CmdCloneVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint
v = v_front; v = v_front;
do { do {
if (v->type == VEH_TRAIN && IsRearDualheaded(v)) { if (v->type == VEH_TRAIN && Train::From(v)->IsRearDualheaded()) {
/* we build the rear ends of multiheaded trains with the front ones */ /* we build the rear ends of multiheaded trains with the front ones */
continue; continue;
} }
@ -437,7 +437,7 @@ CommandCost CmdCloneVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint
if (CmdSucceeded(cost)) total_cost.AddCost(cost); if (CmdSucceeded(cost)) total_cost.AddCost(cost);
} }
if (w->type == VEH_TRAIN && EngineHasArticPart(w)) { if (w->type == VEH_TRAIN && Train::From(w)->EngineHasArticPart()) {
w = GetNextArticPart(Train::From(w)); w = GetNextArticPart(Train::From(w));
} else if (w->type == VEH_ROAD && RoadVehHasArticPart(w)) { } else if (w->type == VEH_ROAD && RoadVehHasArticPart(w)) {
w = w->Next(); w = w->Next();
@ -453,7 +453,7 @@ CommandCost CmdCloneVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint
} }
} }
if (v->type == VEH_TRAIN && EngineHasArticPart(v)) { if (v->type == VEH_TRAIN && Train::From(v)->EngineHasArticPart()) {
v = GetNextArticPart(Train::From(v)); v = GetNextArticPart(Train::From(v));
} else if (v->type == VEH_ROAD && RoadVehHasArticPart(v)) { } else if (v->type == VEH_ROAD && RoadVehHasArticPart(v)) {
v = v->Next(); v = v->Next();

View File

@ -1327,7 +1327,7 @@ static const NWidgetPart _nested_vehicle_details_widgets[] = {
extern int GetTrainDetailsWndVScroll(VehicleID veh_id, TrainDetailsWindowTabs det_tab); extern int GetTrainDetailsWndVScroll(VehicleID veh_id, TrainDetailsWindowTabs det_tab);
extern void DrawTrainDetails(const Vehicle *v, int left, int right, int y, int vscroll_pos, uint16 vscroll_cap, TrainDetailsWindowTabs det_tab); extern void DrawTrainDetails(const Train *v, int left, int right, int y, int vscroll_pos, uint16 vscroll_cap, TrainDetailsWindowTabs det_tab);
extern void DrawRoadVehDetails(const Vehicle *v, int left, int right, int y); extern void DrawRoadVehDetails(const Vehicle *v, int left, int right, int y);
extern void DrawShipDetails(const Vehicle *v, int left, int right, int y); extern void DrawShipDetails(const Vehicle *v, int left, int right, int y);
extern void DrawAircraftDetails(const Vehicle *v, int left, int right, int y); extern void DrawAircraftDetails(const Vehicle *v, int left, int right, int y);
@ -1420,7 +1420,7 @@ struct VehicleDetailsWindow : Window {
static void DrawVehicleDetails(const Vehicle *v, int left, int right, int y, int vscroll_pos, uint vscroll_cap, TrainDetailsWindowTabs det_tab) static void DrawVehicleDetails(const Vehicle *v, int left, int right, int y, int vscroll_pos, uint vscroll_cap, TrainDetailsWindowTabs det_tab)
{ {
switch (v->type) { switch (v->type) {
case VEH_TRAIN: DrawTrainDetails(v, left, right, y, vscroll_pos, vscroll_cap, det_tab); break; case VEH_TRAIN: DrawTrainDetails(Train::From(v), left, right, y, vscroll_pos, vscroll_cap, det_tab); break;
case VEH_ROAD: DrawRoadVehDetails(v, left, right, y); break; case VEH_ROAD: DrawRoadVehDetails(v, left, right, y); break;
case VEH_SHIP: DrawShipDetails(v, left, right, y); break; case VEH_SHIP: DrawShipDetails(v, left, right, y); break;
case VEH_AIRCRAFT: DrawAircraftDetails(v, left, right, y); break; case VEH_AIRCRAFT: DrawAircraftDetails(v, left, right, y); break;

View File

@ -29,7 +29,7 @@ void BuildDepotVehicleList(VehicleType type, TileIndex tile, VehicleList *engine
switch (type) { switch (type) {
case VEH_TRAIN: { case VEH_TRAIN: {
const Train *t = Train::From(v); const Train *t = Train::From(v);
if (IsArticulatedPart(t) || IsRearDualheaded(t)) continue; if (t->IsArticulatedPart() || t->IsRearDualheaded()) continue;
if (t->track != TRACK_BIT_DEPOT) continue; if (t->track != TRACK_BIT_DEPOT) continue;
if (wagons != NULL && t->First()->IsFreeWagon()) { if (wagons != NULL && t->First()->IsFreeWagon()) {
if (individual_wagons || t->IsFreeWagon()) *wagons->Append() = t; if (individual_wagons || t->IsFreeWagon()) *wagons->Append() = t;