ground_vehicle.hpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #ifndef GROUND_VEHICLE_HPP
00013 #define GROUND_VEHICLE_HPP
00014
00015 #include "vehicle_base.h"
00016 #include "landscape.h"
00017
00019 enum AccelStatus {
00020 AS_ACCEL,
00021 AS_BRAKE
00022 };
00023
00028 struct GroundVehicleCache {
00029
00030 uint32 cached_weight;
00031 uint32 cached_slope_resistance;
00032 uint32 cached_max_te;
00033 uint16 cached_axle_resistance;
00034
00035
00036 uint16 cached_max_track_speed;
00037 uint32 cached_power;
00038 uint32 cached_air_drag;
00039
00040
00041 uint16 cached_total_length;
00042 EngineID first_engine;
00043 uint8 cached_veh_length;
00044 };
00045
00047 enum GroundVehicleFlags {
00048 GVF_GOINGUP_BIT = 0,
00049 GVF_GOINGDOWN_BIT = 1,
00050 };
00051
00073 template <class T, VehicleType Type>
00074 struct GroundVehicle : public SpecializedVehicle<T, Type> {
00075 GroundVehicleCache gcache;
00076 uint16 gv_flags;
00077
00081 GroundVehicle() : SpecializedVehicle<T, Type>() {}
00082
00083 void PowerChanged();
00084 void CargoChanged();
00085 int GetAcceleration() const;
00086
00091 FORCEINLINE int32 GetSlopeResistance() const
00092 {
00093 int32 incl = 0;
00094
00095 for (const T *u = T::From(this); u != NULL; u = u->Next()) {
00096 if (HasBit(u->gv_flags, GVF_GOINGUP_BIT)) {
00097 incl += u->gcache.cached_slope_resistance;
00098 } else if (HasBit(u->gv_flags, GVF_GOINGDOWN_BIT)) {
00099 incl -= u->gcache.cached_slope_resistance;
00100 }
00101 }
00102
00103 return incl;
00104 }
00105
00112 FORCEINLINE byte UpdateInclination(bool new_tile, bool turned)
00113 {
00114 byte old_z = this->z_pos;
00115 this->z_pos = GetSlopeZ(this->x_pos, this->y_pos);
00116
00117 if (new_tile) {
00118 ClrBit(this->gv_flags, GVF_GOINGUP_BIT);
00119 ClrBit(this->gv_flags, GVF_GOINGDOWN_BIT);
00120
00121 if (T::From(this)->TileMayHaveSlopedTrack()) {
00122
00123
00124
00125
00126 static const int HALF_TILE_SIZE = TILE_SIZE / 2;
00127 static const int INV_TILE_SIZE_MASK = ~(TILE_SIZE - 1);
00128
00129 byte middle_z = GetSlopeZ((this->x_pos & INV_TILE_SIZE_MASK) | HALF_TILE_SIZE, (this->y_pos & INV_TILE_SIZE_MASK) | HALF_TILE_SIZE);
00130
00131 if (middle_z != this->z_pos) {
00132 SetBit(this->gv_flags, (middle_z > old_z) ? GVF_GOINGUP_BIT : GVF_GOINGDOWN_BIT);
00133 }
00134 }
00135 }
00136
00137 this->UpdateViewport(true, turned);
00138 return old_z;
00139 }
00140 };
00141
00142 #endif