Merge pull request #286 from VacuumBreather/vehicle_more_info

Show more details on train max speed when loaded
This commit is contained in:
Jonathan G Rennison
2021-06-22 23:37:23 +01:00
committed by GitHub
4 changed files with 147 additions and 38 deletions

View File

@@ -4965,6 +4965,9 @@ STR_VEHICLE_DETAILS_CARGO_EMPTY :{LTBLUE}Empty
STR_VEHICLE_DETAILS_CARGO_FROM :{LTBLUE}{CARGO_LONG} from {STATION} STR_VEHICLE_DETAILS_CARGO_FROM :{LTBLUE}{CARGO_LONG} from {STATION}
STR_VEHICLE_DETAILS_CARGO_FROM_MULT :{LTBLUE}{CARGO_LONG} from {STATION} (x{NUM}) STR_VEHICLE_DETAILS_CARGO_FROM_MULT :{LTBLUE}{CARGO_LONG} from {STATION} (x{NUM})
STR_VEHICLE_DETAILS_TRAIN_TOTAL_WEIGHT :{BLACK}Total weight: {LTBLUE}{WEIGHT_SHORT} {BLACK}(empty) - {LTBLUE}{WEIGHT_SHORT} {BLACK}(loaded)
STR_VEHICLE_DETAILS_TRAIN_MAX_SPEED :{BLACK}Max. speed: {LTBLUE}{VELOCITY} {BLACK}(empty) - {LTBLUE}{VELOCITY} {BLACK}(loaded)
STR_VEHICLE_DETAIL_TAB_CARGO :{BLACK}Cargo STR_VEHICLE_DETAIL_TAB_CARGO :{BLACK}Cargo
STR_VEHICLE_DETAILS_TRAIN_CARGO_TOOLTIP :{BLACK}Show details of cargo carried STR_VEHICLE_DETAILS_TRAIN_CARGO_TOOLTIP :{BLACK}Show details of cargo carried
STR_VEHICLE_DETAIL_TAB_INFORMATION :{BLACK}Information STR_VEHICLE_DETAIL_TAB_INFORMATION :{BLACK}Information

View File

@@ -4821,6 +4821,9 @@ STR_VEHICLE_DETAILS_CARGO_EMPTY :{LTBLUE}Leer
STR_VEHICLE_DETAILS_CARGO_FROM :{LTBLUE}{CARGO_LONG} von {STATION} STR_VEHICLE_DETAILS_CARGO_FROM :{LTBLUE}{CARGO_LONG} von {STATION}
STR_VEHICLE_DETAILS_CARGO_FROM_MULT :{LTBLUE}{CARGO_LONG} von {STATION} (x{NUM}) STR_VEHICLE_DETAILS_CARGO_FROM_MULT :{LTBLUE}{CARGO_LONG} von {STATION} (x{NUM})
STR_VEHICLE_DETAILS_TRAIN_TOTAL_WEIGHT :{BLACK}Gesamtgewicht: {LTBLUE}{WEIGHT_SHORT} {BLACK}(leer) {LTBLUE}{WEIGHT_SHORT} {BLACK}(beladen)
STR_VEHICLE_DETAILS_TRAIN_MAX_SPEED :{BLACK}Max. Geschwindigkeit: {LTBLUE}{VELOCITY} {BLACK}(leer) - {LTBLUE}{VELOCITY} {BLACK}(beladen)
STR_VEHICLE_DETAIL_TAB_CARGO :{BLACK}Fracht STR_VEHICLE_DETAIL_TAB_CARGO :{BLACK}Fracht
STR_VEHICLE_DETAILS_TRAIN_CARGO_TOOLTIP :{BLACK}Zeige Einzelheiten zur geladenen Fracht STR_VEHICLE_DETAILS_TRAIN_CARGO_TOOLTIP :{BLACK}Zeige Einzelheiten zur geladenen Fracht
STR_VEHICLE_DETAIL_TAB_INFORMATION :{BLACK}Information STR_VEHICLE_DETAIL_TAB_INFORMATION :{BLACK}Information

View File

@@ -267,7 +267,7 @@ public:
return const_cast<Train *>(const_cast<const Train *>(this)->GetStationLoadingVehicle()); return const_cast<Train *>(const_cast<const Train *>(this)->GetStationLoadingVehicle());
} }
inline uint16 GetCargoWeight(uint cargo_amount) const uint16 GetCargoWeight(uint cargo_amount) const
{ {
if (cargo_amount > 0) { if (cargo_amount > 0) {
return (CargoSpec::Get(this->cargo_type)->weight * cargo_amount * FreightWagonMult(this->cargo_type)) / 16; return (CargoSpec::Get(this->cargo_type)->weight * cargo_amount * FreightWagonMult(this->cargo_type)) / 16;
@@ -276,6 +276,36 @@ public:
} }
} }
/**
* Allows to know the weight value that this vehicle will use (excluding cargo).
* @return Weight value from the engine in tonnes.
*/
uint16 GetWeightWithoutCargo() const
{
uint16 weight = 0;
/* Vehicle weight is not added for articulated parts. */
if (!this->IsArticulatedPart()) {
weight += GetVehicleProperty(this, PROP_TRAIN_WEIGHT, RailVehInfo(this->engine_type)->weight);
}
/* Powered wagons have extra weight added. */
if (HasBit(this->flags, VRF_POWEREDWAGON)) {
weight += RailVehInfo(this->gcache.first_engine)->pow_wag_weight;
}
return weight;
}
/**
* Allows to know the weight value that this vehicle will use (cargo only).
* @return Weight value from the engine in tonnes.
*/
uint16 GetCargoWeight() const
{
return this->GetCargoWeight(this->cargo.StoredCount());
}
protected: // These functions should not be called outside acceleration code. protected: // These functions should not be called outside acceleration code.
/** /**
* Gets the speed a broken down train (low speed breakdown) is limited to. * Gets the speed a broken down train (low speed breakdown) is limited to.
@@ -327,36 +357,6 @@ protected: // These functions should not be called outside acceleration code.
return 0; return 0;
} }
/**
* Allows to know the weight value that this vehicle will use (excluding cargo).
* @return Weight value from the engine in tonnes.
*/
inline uint16 GetWeightWithoutCargo() const
{
uint16 weight = 0;
/* Vehicle weight is not added for articulated parts. */
if (!this->IsArticulatedPart()) {
weight += GetVehicleProperty(this, PROP_TRAIN_WEIGHT, RailVehInfo(this->engine_type)->weight);
}
/* Powered wagons have extra weight added. */
if (HasBit(this->flags, VRF_POWEREDWAGON)) {
weight += RailVehInfo(this->gcache.first_engine)->pow_wag_weight;
}
return weight;
}
/**
* Allows to know the weight value that this vehicle will use (cargo only).
* @return Weight value from the engine in tonnes.
*/
inline uint16 GetCargoWeight() const
{
return this->GetCargoWeight(this->cargo.StoredCount());
}
/** /**
* Allows to know the weight value that this vehicle will use. * Allows to know the weight value that this vehicle will use.
* @return Weight value from the engine in tonnes. * @return Weight value from the engine in tonnes.

View File

@@ -390,7 +390,12 @@ int GetTrainDetailsWndVScroll(VehicleID veh_id, TrainDetailsWindowTabs det_tab)
for (CargoID i = 0; i < NUM_CARGO; i++) { for (CargoID i = 0; i < NUM_CARGO; i++) {
if (max_cargo[i] > 0) num++; // only count carriages that the train has if (max_cargo[i] > 0) num++; // only count carriages that the train has
} }
num++; // needs one more because first line is description string
if (_settings_game.vehicle.train_acceleration_model != AM_ORIGINAL) {
num += 5; // needs five more because first line is description string and we have the weight and speed info and the feeder share
} else {
num += 2; // needs one more because first line is description string and we have the feeder share
}
} else { } else {
for (const Train *v = Train::Get(veh_id); v != nullptr; v = v->GetNextVehicle()) { for (const Train *v = Train::Get(veh_id); v != nullptr; v = v->GetNextVehicle()) {
GetCargoSummaryOfArticulatedVehicle(v, &_cargo_summary); GetCargoSummaryOfArticulatedVehicle(v, &_cargo_summary);
@@ -405,6 +410,65 @@ int GetTrainDetailsWndVScroll(VehicleID veh_id, TrainDetailsWindowTabs det_tab)
return num; 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 * Draw the details for the given vehicle at the given position
* *
@@ -512,19 +576,49 @@ void DrawTrainDetails(const Train *v, int left, int right, int y, int vscroll_po
CargoArray act_cargo; CargoArray act_cargo;
CargoArray max_cargo; CargoArray max_cargo;
Money feeder_share = 0; Money feeder_share = 0;
int empty_weight = 0;
int loaded_weight = 0;
for (const Vehicle *u = v; u != nullptr; u = u->Next()) { for (const Vehicle *u = v; u != nullptr; u = u->Next()) {
const Train *train = Train::From(u);
const auto weight_without_cargo = train->GetWeightWithoutCargo();
act_cargo[u->cargo_type] += u->cargo.StoredCount(); act_cargo[u->cargo_type] += u->cargo.StoredCount();
max_cargo[u->cargo_type] += u->cargo_cap; max_cargo[u->cargo_type] += u->cargo_cap;
feeder_share += u->cargo.FeederShare(); feeder_share += u->cargo.FeederShare();
empty_weight += weight_without_cargo;
loaded_weight += weight_without_cargo + train->GetCargoWeight(train->cargo_cap);
} }
/* draw total cargo tab */ if (_settings_game.vehicle.train_acceleration_model != AM_ORIGINAL) {
DrawString(left, right, y + text_y_offset, STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_TEXT); const int empty_max_speed = GetMaxSpeed(v, empty_weight, v->GetDisplayMaxSpeed());
y += line_height; const int loaded_max_speed = GetMaxSpeed(v, loaded_weight, v->GetDisplayMaxSpeed());
if (--vscroll_pos < 0 && vscroll_pos >= -vscroll_cap) {
SetDParam(0, empty_weight);
SetDParam(1, loaded_weight);
DrawString(left, right, y + text_y_offset, STR_VEHICLE_DETAILS_TRAIN_TOTAL_WEIGHT);
y += line_height;
}
if (--vscroll_pos < 0 && vscroll_pos >= -vscroll_cap) {
SetDParam(0, empty_max_speed);
SetDParam(1, loaded_max_speed);
DrawString(left, right, y + text_y_offset, STR_VEHICLE_DETAILS_TRAIN_MAX_SPEED);
y += line_height;
}
if (--vscroll_pos < 0 && vscroll_pos >= -vscroll_cap) {
y += line_height;
}
}
if (--vscroll_pos < 0 && vscroll_pos >= -vscroll_cap) {
DrawString(left, right, y + text_y_offset, STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_TEXT);
y += line_height;
}
for (CargoID i = 0; i < NUM_CARGO; i++) { for (CargoID i = 0; i < NUM_CARGO; i++) {
if (max_cargo[i] > 0 && --vscroll_pos < 0 && vscroll_pos > -vscroll_cap) { if (max_cargo[i] > 0 && --vscroll_pos < 0 && vscroll_pos >= -vscroll_cap) {
SetDParam(0, i); // {CARGO} #1 SetDParam(0, i); // {CARGO} #1
SetDParam(1, act_cargo[i]); // {CARGO} #2 SetDParam(1, act_cargo[i]); // {CARGO} #2
SetDParam(2, i); // {SHORTCARGO} #1 SetDParam(2, i); // {SHORTCARGO} #1
@@ -534,7 +628,16 @@ void DrawTrainDetails(const Train *v, int left, int right, int y, int vscroll_po
y += line_height; y += line_height;
} }
} }
SetDParam(0, feeder_share);
DrawString(left, right, y + text_y_offset, STR_VEHICLE_INFO_FEEDER_CARGO_VALUE); for (const Vehicle *u = v; u != nullptr; u = u->Next()) {
act_cargo[u->cargo_type] += u->cargo.StoredCount();
max_cargo[u->cargo_type] += u->cargo_cap;
feeder_share += u->cargo.FeederShare();
}
if (--vscroll_pos < 0 && vscroll_pos >= -vscroll_cap) {
SetDParam(0, feeder_share);
DrawString(left, right, y + text_y_offset, STR_VEHICLE_INFO_FEEDER_CARGO_VALUE);
}
} }
} }