|
@@ -286,54 +286,54 @@ public:
|
|
|
* Determines the effective direction-specific vehicle movement speed.
|
|
|
*
|
|
|
* This method belongs to the old vehicle movement method:
|
|
|
* A vehicle moves a step every 256 progress units.
|
|
|
* The vehicle speed is scaled by 3/4 when moving in X or Y direction due to the longer distance.
|
|
|
*
|
|
|
* However, this method is slightly wrong in corners, as the leftover progress is not scaled correctly
|
|
|
* when changing movement direction. #GetAdvanceSpeed() and #GetAdvanceDistance() are better wrt. this.
|
|
|
*
|
|
|
* @param speed Direction-independent unscaled speed.
|
|
|
* @return speed scaled by movement direction. 256 units are required for each movement step.
|
|
|
*/
|
|
|
FORCEINLINE uint GetOldAdvanceSpeed(uint speed)
|
|
|
inline uint GetOldAdvanceSpeed(uint speed)
|
|
|
{
|
|
|
return (this->direction & 1) ? speed : speed * 3 / 4;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Determines the effective vehicle movement speed.
|
|
|
*
|
|
|
* Together with #GetAdvanceDistance() this function is a replacement for #GetOldAdvanceSpeed().
|
|
|
*
|
|
|
* A vehicle progresses independent of it's movement direction.
|
|
|
* However different amounts of "progress" are needed for moving a step in a specific direction.
|
|
|
* That way the leftover progress does not need any adaption when changing movement direction.
|
|
|
*
|
|
|
* @param speed Direction-independent unscaled speed.
|
|
|
* @return speed, scaled to match #GetAdvanceDistance().
|
|
|
*/
|
|
|
static FORCEINLINE uint GetAdvanceSpeed(uint speed)
|
|
|
static inline uint GetAdvanceSpeed(uint speed)
|
|
|
{
|
|
|
return speed * 3 / 4;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Determines the vehicle "progress" needed for moving a step.
|
|
|
*
|
|
|
* Together with #GetAdvanceSpeed() this function is a replacement for #GetOldAdvanceSpeed().
|
|
|
*
|
|
|
* @return distance to drive for a movement step on the map.
|
|
|
*/
|
|
|
FORCEINLINE uint GetAdvanceDistance()
|
|
|
inline uint GetAdvanceDistance()
|
|
|
{
|
|
|
return (this->direction & 1) ? 192 : 256;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Sets the expense type associated to this vehicle type
|
|
|
* @param income whether this is income or (running) expenses of the vehicle
|
|
|
*/
|
|
|
virtual ExpensesType GetExpenseType(bool income) const { return EXPENSES_OTHER; }
|
|
|
|
|
|
/**
|
|
|
* Play the sound associated with leaving the station
|
|
@@ -352,45 +352,45 @@ public:
|
|
|
* @param direction the direction the vehicle is facing
|
|
|
* @return the sprite for the given vehicle in the given direction
|
|
|
*/
|
|
|
virtual SpriteID GetImage(Direction direction, EngineImageType image_type) const { return 0; }
|
|
|
|
|
|
const GRFFile *GetGRF() const;
|
|
|
uint32 GetGRFID() const;
|
|
|
|
|
|
/**
|
|
|
* Invalidates cached NewGRF variables
|
|
|
* @see InvalidateNewGRFCacheOfChain
|
|
|
*/
|
|
|
FORCEINLINE void InvalidateNewGRFCache()
|
|
|
inline void InvalidateNewGRFCache()
|
|
|
{
|
|
|
this->grf_cache.cache_valid = 0;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Invalidates cached NewGRF variables of all vehicles in the chain (after the current vehicle)
|
|
|
* @see InvalidateNewGRFCache
|
|
|
*/
|
|
|
FORCEINLINE void InvalidateNewGRFCacheOfChain()
|
|
|
inline void InvalidateNewGRFCacheOfChain()
|
|
|
{
|
|
|
for (Vehicle *u = this; u != NULL; u = u->Next()) {
|
|
|
u->InvalidateNewGRFCache();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Check if the vehicle is a ground vehicle.
|
|
|
* @return True iff the vehicle is a train or a road vehicle.
|
|
|
*/
|
|
|
FORCEINLINE bool IsGroundVehicle() const
|
|
|
inline bool IsGroundVehicle() const
|
|
|
{
|
|
|
return this->type == VEH_TRAIN || this->type == VEH_ROAD;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Gets the speed in km-ish/h that can be sent into SetDParam for string processing.
|
|
|
* @return the vehicle's speed
|
|
|
*/
|
|
|
virtual int GetDisplaySpeed() const { return 0; }
|
|
|
|
|
|
/**
|
|
|
* Gets the maximum speed in km-ish/h that can be sent into SetDParam for string processing.
|
|
@@ -730,109 +730,109 @@ public:
|
|
|
return (this->orders.list == NULL) ? NULL : this->orders.list->GetLastOrder();
|
|
|
}
|
|
|
|
|
|
bool IsEngineCountable() const;
|
|
|
bool HasEngineType() const;
|
|
|
bool HasDepotOrder() const;
|
|
|
void HandlePathfindingResult(bool path_found);
|
|
|
|
|
|
/**
|
|
|
* Check if the vehicle is a front engine.
|
|
|
* @return Returns true if the vehicle is a front engine.
|
|
|
*/
|
|
|
FORCEINLINE bool IsFrontEngine() const
|
|
|
inline bool IsFrontEngine() const
|
|
|
{
|
|
|
return this->IsGroundVehicle() && HasBit(this->subtype, GVSF_FRONT);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Check if the vehicle is an articulated part of an engine.
|
|
|
* @return Returns true if the vehicle is an articulated part.
|
|
|
*/
|
|
|
FORCEINLINE bool IsArticulatedPart() const
|
|
|
inline bool IsArticulatedPart() const
|
|
|
{
|
|
|
return this->IsGroundVehicle() && HasBit(this->subtype, GVSF_ARTICULATED_PART);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Check if an engine has an articulated part.
|
|
|
* @return True if the engine has an articulated part.
|
|
|
*/
|
|
|
FORCEINLINE bool HasArticulatedPart() const
|
|
|
inline bool HasArticulatedPart() const
|
|
|
{
|
|
|
return this->Next() != NULL && this->Next()->IsArticulatedPart();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Get the next part of an articulated engine.
|
|
|
* @return Next part of the articulated engine.
|
|
|
* @pre The vehicle is an articulated engine.
|
|
|
*/
|
|
|
FORCEINLINE Vehicle *GetNextArticulatedPart() const
|
|
|
inline Vehicle *GetNextArticulatedPart() const
|
|
|
{
|
|
|
assert(this->HasArticulatedPart());
|
|
|
return this->Next();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Get the first part of an articulated engine.
|
|
|
* @return First part of the engine.
|
|
|
*/
|
|
|
FORCEINLINE Vehicle *GetFirstEnginePart()
|
|
|
inline Vehicle *GetFirstEnginePart()
|
|
|
{
|
|
|
Vehicle *v = this;
|
|
|
while (v->IsArticulatedPart()) v = v->Previous();
|
|
|
return v;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Get the first part of an articulated engine.
|
|
|
* @return First part of the engine.
|
|
|
*/
|
|
|
FORCEINLINE const Vehicle *GetFirstEnginePart() const
|
|
|
inline const Vehicle *GetFirstEnginePart() const
|
|
|
{
|
|
|
const Vehicle *v = this;
|
|
|
while (v->IsArticulatedPart()) v = v->Previous();
|
|
|
return v;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Get the last part of an articulated engine.
|
|
|
* @return Last part of the engine.
|
|
|
*/
|
|
|
FORCEINLINE Vehicle *GetLastEnginePart()
|
|
|
inline Vehicle *GetLastEnginePart()
|
|
|
{
|
|
|
Vehicle *v = this;
|
|
|
while (v->HasArticulatedPart()) v = v->GetNextArticulatedPart();
|
|
|
return v;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Get the next real (non-articulated part) vehicle in the consist.
|
|
|
* @return Next vehicle in the consist.
|
|
|
*/
|
|
|
FORCEINLINE Vehicle *GetNextVehicle() const
|
|
|
inline Vehicle *GetNextVehicle() const
|
|
|
{
|
|
|
const Vehicle *v = this;
|
|
|
while (v->HasArticulatedPart()) v = v->GetNextArticulatedPart();
|
|
|
|
|
|
/* v now contains the last articulated part in the engine */
|
|
|
return v->Next();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Get the previous real (non-articulated part) vehicle in the consist.
|
|
|
* @return Previous vehicle in the consist.
|
|
|
*/
|
|
|
FORCEINLINE Vehicle *GetPrevVehicle() const
|
|
|
inline Vehicle *GetPrevVehicle() const
|
|
|
{
|
|
|
Vehicle *v = this->Previous();
|
|
|
while (v != NULL && v->IsArticulatedPart()) v = v->Previous();
|
|
|
|
|
|
return v;
|
|
|
}
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* Iterate over all vehicles from a given point.
|
|
|
* @param var The variable used to iterate over.
|
|
|
* @param start The vehicle to start the iteration at.
|
|
@@ -849,156 +849,156 @@ 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
|
|
|
|
|
|
typedef SpecializedVehicle<T, Type> SpecializedVehicleBase; ///< Our type
|
|
|
|
|
|
/**
|
|
|
* Set vehicle type correctly
|
|
|
*/
|
|
|
FORCEINLINE SpecializedVehicle<T, Type>() : Vehicle(Type) { }
|
|
|
inline SpecializedVehicle<T, Type>() : Vehicle(Type) { }
|
|
|
|
|
|
/**
|
|
|
* Get the first vehicle in the chain
|
|
|
* @return first vehicle in the chain
|
|
|
*/
|
|
|
FORCEINLINE T *First() const { return (T *)this->Vehicle::First(); }
|
|
|
inline T *First() const { return (T *)this->Vehicle::First(); }
|
|
|
|
|
|
/**
|
|
|
* Get the last vehicle in the chain
|
|
|
* @return last vehicle in the chain
|
|
|
*/
|
|
|
FORCEINLINE T *Last() { return (T *)this->Vehicle::Last(); }
|
|
|
inline T *Last() { return (T *)this->Vehicle::Last(); }
|
|
|
|
|
|
/**
|
|
|
* Get the last vehicle in the chain
|
|
|
* @return last vehicle in the chain
|
|
|
*/
|
|
|
FORCEINLINE const T *Last() const { return (const T *)this->Vehicle::Last(); }
|
|
|
inline const T *Last() const { return (const T *)this->Vehicle::Last(); }
|
|
|
|
|
|
/**
|
|
|
* Get next vehicle in the chain
|
|
|
* @return next vehicle in the chain
|
|
|
*/
|
|
|
FORCEINLINE T *Next() const { return (T *)this->Vehicle::Next(); }
|
|
|
inline 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(); }
|
|
|
inline T *Previous() const { return (T *)this->Vehicle::Previous(); }
|
|
|
|
|
|
/**
|
|
|
* Get the next part of an articulated engine.
|
|
|
* @return Next part of the articulated engine.
|
|
|
* @pre The vehicle is an articulated engine.
|
|
|
*/
|
|
|
FORCEINLINE T *GetNextArticulatedPart() { return (T *)this->Vehicle::GetNextArticulatedPart(); }
|
|
|
inline T *GetNextArticulatedPart() { return (T *)this->Vehicle::GetNextArticulatedPart(); }
|
|
|
|
|
|
/**
|
|
|
* Get the next part of an articulated engine.
|
|
|
* @return Next part of the articulated engine.
|
|
|
* @pre The vehicle is an articulated engine.
|
|
|
*/
|
|
|
FORCEINLINE T *GetNextArticulatedPart() const { return (T *)this->Vehicle::GetNextArticulatedPart(); }
|
|
|
inline T *GetNextArticulatedPart() const { return (T *)this->Vehicle::GetNextArticulatedPart(); }
|
|
|
|
|
|
/**
|
|
|
* Get the first part of an articulated engine.
|
|
|
* @return First part of the engine.
|
|
|
*/
|
|
|
FORCEINLINE T *GetFirstEnginePart() { return (T *)this->Vehicle::GetFirstEnginePart(); }
|
|
|
inline T *GetFirstEnginePart() { return (T *)this->Vehicle::GetFirstEnginePart(); }
|
|
|
|
|
|
/**
|
|
|
* Get the first part of an articulated engine.
|
|
|
* @return First part of the engine.
|
|
|
*/
|
|
|
FORCEINLINE const T *GetFirstEnginePart() const { return (const T *)this->Vehicle::GetFirstEnginePart(); }
|
|
|
inline const T *GetFirstEnginePart() const { return (const T *)this->Vehicle::GetFirstEnginePart(); }
|
|
|
|
|
|
/**
|
|
|
* Get the last part of an articulated engine.
|
|
|
* @return Last part of the engine.
|
|
|
*/
|
|
|
FORCEINLINE T *GetLastEnginePart() { return (T *)this->Vehicle::GetLastEnginePart(); }
|
|
|
inline T *GetLastEnginePart() { return (T *)this->Vehicle::GetLastEnginePart(); }
|
|
|
|
|
|
/**
|
|
|
* Get the next real (non-articulated part) vehicle in the consist.
|
|
|
* @return Next vehicle in the consist.
|
|
|
*/
|
|
|
FORCEINLINE T *GetNextVehicle() const { return (T *)this->Vehicle::GetNextVehicle(); }
|
|
|
inline T *GetNextVehicle() const { return (T *)this->Vehicle::GetNextVehicle(); }
|
|
|
|
|
|
/**
|
|
|
* Get the previous real (non-articulated part) vehicle in the consist.
|
|
|
* @return Previous vehicle in the consist.
|
|
|
*/
|
|
|
FORCEINLINE T *GetPrevVehicle() const { return (T *)this->Vehicle::GetPrevVehicle(); }
|
|
|
inline T *GetPrevVehicle() const { return (T *)this->Vehicle::GetPrevVehicle(); }
|
|
|
|
|
|
/**
|
|
|
* 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)
|
|
|
static inline 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)
|
|
|
static inline 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)
|
|
|
static inline T *GetIfValid(size_t index)
|
|
|
{
|
|
|
return IsValidID(index) ? Get(index) : NULL;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Converts a Vehicle to SpecializedVehicle with type checking.
|
|
|
* @param v Vehicle pointer
|
|
|
* @return pointer to SpecializedVehicle
|
|
|
*/
|
|
|
static FORCEINLINE T *From(Vehicle *v)
|
|
|
static inline T *From(Vehicle *v)
|
|
|
{
|
|
|
assert(v->type == Type);
|
|
|
return (T *)v;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Converts a const Vehicle to const SpecializedVehicle with type checking.
|
|
|
* @param v Vehicle pointer
|
|
|
* @return pointer to SpecializedVehicle
|
|
|
*/
|
|
|
static FORCEINLINE const T *From(const Vehicle *v)
|
|
|
static inline const T *From(const Vehicle *v)
|
|
|
{
|
|
|
assert(v->type == Type);
|
|
|
return (const T *)v;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Update vehicle sprite- and position caches
|
|
|
* @param moved Was the vehicle moved?
|
|
|
* @param turned Did the vehicle direction change?
|
|
|
*/
|
|
|
FORCEINLINE void UpdateViewport(bool moved, bool turned)
|
|
|
inline void UpdateViewport(bool moved, bool turned)
|
|
|
{
|
|
|
extern void VehicleMove(Vehicle *v, bool update_viewport);
|
|
|
|
|
|
/* Explicitly choose method to call to prevent vtable dereference -
|
|
|
* it gives ~3% runtime improvements in games with many vehicles */
|
|
|
if (turned) ((T *)this)->T::UpdateDeltaXY(this->direction);
|
|
|
SpriteID old_image = this->cur_image;
|
|
|
this->cur_image = ((T *)this)->T::GetImage(this->direction, EIT_ON_MAP);
|
|
|
if (moved || this->cur_image != old_image) VehicleMove(this, true);
|
|
|
}
|
|
|
};
|
|
|
|