mirror of
https://github.com/JGRennison/OpenTTD-patches.git
synced 2024-11-17 21:25:40 +00:00
Fix speed calculation
This commit is contained in:
parent
9a72d741ad
commit
9bd79d03d1
@ -405,6 +405,65 @@ int GetTrainDetailsWndVScroll(VehicleID veh_id, TrainDetailsWindowTabs det_tab)
|
||||
return num;
|
||||
}
|
||||
|
||||
int GetAcceleration(const Train *train, const int speed, const int mass)
|
||||
{
|
||||
const int64 power = train->gcache.cached_power * 746ll;
|
||||
int64 resistance = 0;
|
||||
|
||||
const bool maglev = (GetRailTypeInfo(train->railtype)->acceleration_type == 2);
|
||||
|
||||
if (!maglev) {
|
||||
/* Static resistance plus rolling friction. */
|
||||
resistance = 10 * mass;
|
||||
resistance += mass * (15 * (512 + speed) / 512);
|
||||
}
|
||||
|
||||
const int area = 14;
|
||||
|
||||
resistance += (area * train->gcache.cached_air_drag * speed * speed) / 1000;
|
||||
|
||||
uint32 max_te = train->gcache.cached_max_te; // [N]
|
||||
int64 force;
|
||||
|
||||
if (speed > 0) {
|
||||
if (!maglev) {
|
||||
/* Conversion factor from km/h to m/s is 5/18 to get [N] in the end. */
|
||||
force = power * 18 / (speed * 5);
|
||||
|
||||
if (force > static_cast<int>(max_te)) {
|
||||
force = max_te;
|
||||
}
|
||||
} else {
|
||||
force = power / 25;
|
||||
}
|
||||
} else {
|
||||
force = (!maglev) ? std::min<uint64>(max_te, power) : power;
|
||||
force = std::max(force, (mass * 8) + resistance);
|
||||
}
|
||||
|
||||
/* Easy way out when there is no acceleration. */
|
||||
if (force == resistance) return 0;
|
||||
|
||||
int acceleration = ClampToI32((force - resistance) / (mass * 4));
|
||||
acceleration = force < resistance ? std::min(-1, acceleration) : std::max(1, acceleration);
|
||||
|
||||
return acceleration;
|
||||
}
|
||||
|
||||
int GetMaxSpeed(const Train *train, const int mass, const int speed_cap)
|
||||
{
|
||||
int max_speed = 0;
|
||||
int acceleration;
|
||||
|
||||
do
|
||||
{
|
||||
max_speed++;
|
||||
acceleration = GetAcceleration(train, max_speed, mass);
|
||||
} while (acceleration > 0 && max_speed < speed_cap);
|
||||
|
||||
return max_speed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw the details for the given vehicle at the given position
|
||||
*
|
||||
@ -514,8 +573,6 @@ void DrawTrainDetails(const Train *v, int left, int right, int y, int vscroll_po
|
||||
Money feeder_share = 0;
|
||||
int empty_weight = 0;
|
||||
int loaded_weight = 0;
|
||||
int empty_max_speed = 0;
|
||||
int loaded_max_speed = 0;
|
||||
|
||||
for (const Vehicle *u = v; u != nullptr; u = u->Next()) {
|
||||
const Train *train = Train::From(u);
|
||||
@ -527,13 +584,8 @@ void DrawTrainDetails(const Train *v, int left, int right, int y, int vscroll_po
|
||||
loaded_weight += weight_without_cargo + train->GetCargoWeight(train->cargo_cap);
|
||||
}
|
||||
|
||||
const auto rolling_friction = 15 * (512 + v->GetDisplayMaxSpeed()) / 512;
|
||||
const auto tractive_effort_empty = empty_weight * rolling_friction;
|
||||
const auto tractive_effort_loaded = loaded_weight * rolling_friction;
|
||||
const int power = static_cast<int>(v->gcache.cached_power * 746);
|
||||
const int max_te = static_cast<int>(v->gcache.cached_max_te);
|
||||
empty_max_speed = std::min(v->GetDisplayMaxSpeed(), (tractive_effort_empty == 0 || tractive_effort_empty > max_te) ? 0 : static_cast<int>((3.6 * power) / tractive_effort_empty));
|
||||
loaded_max_speed = std::min(v->GetDisplayMaxSpeed(), (tractive_effort_loaded == 0 || tractive_effort_loaded > max_te) ? 0 : static_cast<int>((3.6 * power) / tractive_effort_loaded));
|
||||
const int empty_max_speed = GetMaxSpeed(v, empty_weight, v->GetDisplayMaxSpeed());
|
||||
const int loaded_max_speed = GetMaxSpeed(v, loaded_weight, v->GetDisplayMaxSpeed());
|
||||
|
||||
if (--vscroll_pos < 0 && vscroll_pos >= -vscroll_cap) {
|
||||
SetDParam(0, empty_weight);
|
||||
|
Loading…
Reference in New Issue
Block a user