22 template <
class T, VehicleType Type>
 
   25   assert(this->First() == 
this);
 
   26   const T *v = T::From(
this);
 
   28   uint32 total_power = 0;
 
   30   uint32 number_of_parts = 0;
 
   31   uint16 max_track_speed = v->GetDisplayMaxSpeed();
 
   33   for (
const T *u = v; u != NULL; u = u->Next()) {
 
   34     uint32 current_power = u->GetPower() + u->GetPoweredPartPower(u);
 
   35     total_power += current_power;
 
   38     if (current_power > 0) max_te += u->GetWeight() * u->GetTractiveEffort();
 
   42     uint16 track_speed = u->GetMaxTrackSpeed();
 
   43     if (track_speed > 0) max_track_speed = 
min(max_track_speed, track_speed);
 
   47   byte air_drag_value = v->GetAirDrag();
 
   50   if (air_drag_value == 0) {
 
   51     uint16 max_speed = v->GetDisplayMaxSpeed();
 
   53     air_drag = (max_speed <= 10) ? 192 : 
max(2048 / max_speed, 1);
 
   56     air_drag = (air_drag_value == 1) ? 0 : air_drag_value;
 
   59   this->gcache.cached_air_drag = air_drag + 3 * air_drag * number_of_parts / 20;
 
   63   if (this->gcache.cached_power != total_power || this->gcache.cached_max_te != max_te) {
 
   65     if (total_power == 0) this->vehstatus |= 
VS_STOPPED;
 
   67     this->gcache.cached_power = total_power;
 
   68     this->gcache.cached_max_te = max_te;
 
   73   this->gcache.cached_max_track_speed = max_track_speed;
 
   80 template <
class T, VehicleType Type>
 
   83   assert(this->First() == 
this);
 
   86   for (T *u = T::From(
this); u != NULL; u = u->Next()) {
 
   87     uint32 current_weight = u->GetWeight();
 
   88     weight += current_weight;
 
   90     u->gcache.cached_slope_resistance = current_weight * u->GetSlopeSteepness() * 100;
 
   94   this->gcache.cached_weight = max<uint32>(1, weight);
 
   96   this->gcache.cached_axle_resistance = 10 * weight;
 
  106 template <
class T, VehicleType Type>
 
  110   const T *v = T::From(
this);
 
  112   int64 speed = v->GetCurrentSpeed(); 
 
  115   int32 mass = this->gcache.cached_weight;
 
  121   int64 power = this->gcache.cached_power * 746ll;
 
  134   int64 resistance = 0;
 
  136   bool maglev = v->GetAccelerationType() == 2;
 
  138   const int area = v->GetAirDragArea();
 
  141     resistance = this->gcache.cached_axle_resistance;
 
  142     resistance += mass * v->GetRollingFriction();
 
  146   resistance += (area * this->gcache.cached_air_drag * speed * speed) / 1000;
 
  148   resistance += this->GetSlopeResistance();
 
  153   const int max_te = this->gcache.cached_max_te; 
 
  160       force = power * 18 / (speed * 5);
 
  161       if (mode == 
AS_ACCEL && force > max_te) force = max_te;
 
  167     force = (mode == 
AS_ACCEL && !maglev) ? 
min(max_te, power) : power;
 
  168     force = 
max(force, (mass * 8) + resistance);
 
  173     if (force == resistance) 
return 0;
 
  180     int accel = 
ClampToI32((force - resistance) / (mass * 4));
 
  181     return force < resistance ? 
min(-1, accel) : 
max(1, accel);
 
  191 template <
class T, VehicleType Type>
 
  194   const T *v = this->First();
 
  201   for (; v != NULL; v = v->Next()) {
 
  202     if (!v->T::IsInDepot() || v->tile != this->tile) 
return false;