bjarni@2676: /* $Id$ */ bjarni@2676: bjarni@2676: #ifndef TRAIN_H bjarni@2676: #define TRAIN_H bjarni@2676: bjarni@2676: #include "stdafx.h" bjarni@2676: #include "vehicle.h" bjarni@2676: bjarni@2676: bjarni@2676: /* bjarni@2676: * enum to handle train subtypes bjarni@2676: * Do not access it directly unless you have to. Use the access functions below bjarni@2676: * This is an enum to tell what bit to access as it is a bitmask bjarni@2676: */ bjarni@2676: bjarni@2676: typedef enum TrainSubtypes { bjarni@2676: Train_Front = 0, // Leading engine of a train bjarni@2676: Train_Articulated_Part = 1, // Articulated part of an engine bjarni@2676: Train_Wagon = 2, // Wagon bjarni@2676: Train_Engine = 3, // Engine, that can be front engines, but might be placed behind another engine bjarni@2676: Train_Free_Wagon = 4, // First in a wagon chain (in depot) bjarni@2676: Train_Multiheaded = 5, // Engine is a multiheaded bjarni@2676: } TrainSubtype; bjarni@2676: bjarni@2676: bjarni@2676: /** Check if a vehicle is front engine bjarni@2676: * @param v vehicle to check bjarni@2676: * @return Returns true if vehicle is a front engine bjarni@2676: */ bjarni@2676: static inline bool IsFrontEngine(const Vehicle *v) bjarni@2676: { bjarni@2676: return HASBIT(v->subtype, Train_Front); bjarni@2676: } bjarni@2676: bjarni@2676: /** Set front engine state bjarni@2676: * @param v vehicle to change bjarni@2676: */ bjarni@2676: static inline void SetFrontEngine(Vehicle *v) bjarni@2676: { bjarni@2676: SETBIT(v->subtype, Train_Front); bjarni@2676: } bjarni@2676: bjarni@2676: /** Remove the front engine state bjarni@2676: * @param v vehicle to change bjarni@2676: */ bjarni@2676: static inline void ClearFrontEngine(Vehicle *v) bjarni@2676: { bjarni@2676: CLRBIT(v->subtype, Train_Front); bjarni@2676: } bjarni@2676: bjarni@2676: /** Check if a vehicle is an articulated part of an engine bjarni@2676: * @param v vehicle to check bjarni@2676: * @return Returns true if vehicle is an articulated part bjarni@2676: */ bjarni@2676: static inline bool IsArticulatedPart(const Vehicle *v) bjarni@2676: { bjarni@2676: return HASBIT(v->subtype, Train_Articulated_Part); bjarni@2676: } bjarni@2676: bjarni@2676: /** Set a vehicle to be an articulated part bjarni@2676: * @param v vehicle to change bjarni@2676: */ bjarni@2676: static inline void SetArticulatedPart(Vehicle *v) bjarni@2676: { bjarni@2676: SETBIT(v->subtype, Train_Articulated_Part); bjarni@2676: } bjarni@2676: bjarni@2676: /** Clear a vehicle from being an articulated part bjarni@2676: * @param v vehicle to change bjarni@2676: */ bjarni@2676: static inline void ClearArticulatedPart(Vehicle *v) bjarni@2676: { bjarni@2676: CLRBIT(v->subtype, Train_Articulated_Part); bjarni@2676: } bjarni@2676: bjarni@2676: /** Check if a vehicle is a wagon bjarni@2676: * @param v vehicle to check bjarni@2676: * @return Returns true if vehicle is a wagon bjarni@2676: */ bjarni@2676: static inline bool IsTrainWagon(const Vehicle *v) bjarni@2676: { bjarni@2676: return HASBIT(v->subtype, Train_Wagon); bjarni@2676: } bjarni@2676: bjarni@2676: /** Set a vehicle to be a wagon bjarni@2676: * @param v vehicle to change bjarni@2676: */ bjarni@2676: static inline void SetTrainWagon(Vehicle *v) bjarni@2676: { bjarni@2676: SETBIT(v->subtype, Train_Wagon); bjarni@2676: } bjarni@2676: bjarni@2676: /** Clear wagon property bjarni@2676: * @param v vehicle to change bjarni@2676: */ bjarni@2676: static inline void ClearTrainWagon(Vehicle *v) bjarni@2676: { bjarni@2676: CLRBIT(v->subtype, Train_Wagon); bjarni@2676: } bjarni@2676: bjarni@2676: /** Check if a vehicle is an engine (can be first in a train) bjarni@2676: * @param v vehicle to check bjarni@2676: * @return Returns true if vehicle is an engine bjarni@2676: */ bjarni@2676: static inline bool IsTrainEngine(const Vehicle *v) bjarni@2676: { bjarni@2676: return HASBIT(v->subtype, Train_Engine); bjarni@2676: } bjarni@2676: bjarni@2676: /** Set engine status bjarni@2676: * @param v vehicle to change bjarni@2676: */ bjarni@2676: static inline void SetTrainEngine(Vehicle *v) bjarni@2676: { bjarni@2676: SETBIT(v->subtype, Train_Engine); bjarni@2676: } bjarni@2676: bjarni@2676: /** Clear engine status bjarni@2676: * @param v vehicle to change bjarni@2676: */ bjarni@2676: static inline void ClearTrainEngine(Vehicle *v) bjarni@2676: { bjarni@2676: CLRBIT(v->subtype, Train_Engine); bjarni@2676: } bjarni@2676: bjarni@2676: /** Check if a vehicle is a free wagon (got no engine in front of it) bjarni@2676: * @param v vehicle to check bjarni@2676: * @return Returns true if vehicle is a free wagon bjarni@2676: */ bjarni@2676: static inline bool IsFreeWagon(const Vehicle *v) bjarni@2676: { bjarni@2676: return HASBIT(v->subtype, Train_Free_Wagon); bjarni@2676: } bjarni@2676: bjarni@2676: /** Set if a vehicle is a free wagon bjarni@2676: * @param v vehicle to change bjarni@2676: */ bjarni@2676: static inline void SetFreeWagon(Vehicle *v) bjarni@2676: { bjarni@2676: SETBIT(v->subtype, Train_Free_Wagon); bjarni@2676: } bjarni@2676: bjarni@2676: /** Clear a vehicle from being a free wagon bjarni@2676: * @param v vehicle to change bjarni@2676: */ bjarni@2676: static inline void ClearFreeWagon(Vehicle *v) bjarni@2676: { bjarni@2676: CLRBIT(v->subtype, Train_Free_Wagon); bjarni@2676: } bjarni@2676: bjarni@2676: /** Check if a vehicle is a multiheaded engine bjarni@2676: * @param v vehicle to check bjarni@2676: * @return Returns true if vehicle is a multiheaded engine bjarni@2676: */ bjarni@2676: static inline bool IsMultiheaded(const Vehicle *v) bjarni@2676: { bjarni@2676: return HASBIT(v->subtype, Train_Multiheaded); bjarni@2676: } bjarni@2676: bjarni@2676: /** Set if a vehicle is a multiheaded engine bjarni@2676: * @param v vehicle to change bjarni@2676: */ bjarni@2676: static inline void SetMultiheaded(Vehicle *v) bjarni@2676: { bjarni@2676: SETBIT(v->subtype, Train_Multiheaded); bjarni@2676: } bjarni@2676: bjarni@2676: /** Clear multiheaded engine property bjarni@2676: * @param v vehicle to change bjarni@2676: */ bjarni@2676: static inline void ClearMultiheaded(Vehicle *v) bjarni@2676: { bjarni@2676: CLRBIT(v->subtype, Train_Multiheaded); bjarni@2676: } bjarni@2676: bjarni@2676: /** Get the next real (non-articulated part) vehicle in the consist. bjarni@2676: * @param v Vehicle. bjarni@2676: * @return Next vehicle in the consist. bjarni@2676: */ bjarni@2676: static inline Vehicle *GetNextVehicle(const Vehicle *v) bjarni@2676: { bjarni@2676: Vehicle *u = v->next; bjarni@2676: while (u != NULL && IsArticulatedPart(u)) { bjarni@2676: u = u->next; bjarni@2676: } bjarni@2676: return u; bjarni@2676: } bjarni@2676: bjarni@2676: /** Check if an engine has an articulated part. bjarni@2676: * @param v Vehicle. bjarni@2676: * @return True if the engine has an articulated part. bjarni@2676: */ bjarni@2676: static inline bool EngineHasArticPart(const Vehicle *v) bjarni@2676: { bjarni@2676: return (v->next != NULL && IsArticulatedPart(v->next)); bjarni@2676: } bjarni@2676: bjarni@2676: /** Get the last part of a multi-part engine. bjarni@2676: * @param v Vehicle. bjarni@2676: * @return Last part of the engine. bjarni@2676: */ bjarni@2676: static inline Vehicle *GetLastEnginePart(Vehicle *v) bjarni@2676: { bjarni@2676: while (EngineHasArticPart(v)) v = v->next; bjarni@2676: return v; bjarni@2676: } bjarni@2676: bjarni@2855: void ConvertOldMultiheadToNew(void); bjarni@2855: void ConnectMultiheadedTrains(void); bjarni@2855: bjarni@2676: #endif /* TRAIN_H */