Merge pull request #286 from VacuumBreather/vehicle_more_info
Show more details on train max speed when loaded
This commit is contained in:
@@ -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_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_DETAILS_TRAIN_CARGO_TOOLTIP :{BLACK}Show details of cargo carried
|
||||
STR_VEHICLE_DETAIL_TAB_INFORMATION :{BLACK}Information
|
||||
|
||||
@@ -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_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_DETAILS_TRAIN_CARGO_TOOLTIP :{BLACK}Zeige Einzelheiten zur geladenen Fracht
|
||||
STR_VEHICLE_DETAIL_TAB_INFORMATION :{BLACK}Information
|
||||
|
||||
62
src/train.h
62
src/train.h
@@ -267,7 +267,7 @@ public:
|
||||
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) {
|
||||
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.
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @return Weight value from the engine in tonnes.
|
||||
|
||||
@@ -390,7 +390,12 @@ int GetTrainDetailsWndVScroll(VehicleID veh_id, TrainDetailsWindowTabs det_tab)
|
||||
for (CargoID i = 0; i < NUM_CARGO; i++) {
|
||||
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 {
|
||||
for (const Train *v = Train::Get(veh_id); v != nullptr; v = v->GetNextVehicle()) {
|
||||
GetCargoSummaryOfArticulatedVehicle(v, &_cargo_summary);
|
||||
@@ -405,6 +410,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
|
||||
*
|
||||
@@ -512,19 +576,49 @@ void DrawTrainDetails(const Train *v, int left, int right, int y, int vscroll_po
|
||||
CargoArray act_cargo;
|
||||
CargoArray max_cargo;
|
||||
Money feeder_share = 0;
|
||||
int empty_weight = 0;
|
||||
int loaded_weight = 0;
|
||||
|
||||
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();
|
||||
max_cargo[u->cargo_type] += u->cargo_cap;
|
||||
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) {
|
||||
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);
|
||||
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++) {
|
||||
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(1, act_cargo[i]); // {CARGO} #2
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user