Index: lang/english.txt
===================================================================
--- lang/english.txt (revision 27764)
+++ lang/english.txt (working copy)
@@ -3689,7 +3689,9 @@
# Extra buttons for train details windows
STR_VEHICLE_DETAILS_TRAIN_ENGINE_BUILT_AND_VALUE :{LTBLUE}{ENGINE}{BLACK} Built: {LTBLUE}{NUM}{BLACK} Value: {LTBLUE}{CURRENCY_LONG}
+STR_VEHICLE_DETAILS_TRAIN_ENGINE_BUILT_VALUE_RUNCOST :{LTBLUE}{ENGINE}{BLACK} Built: {LTBLUE}{NUM}{BLACK} Value: {LTBLUE}{CURRENCY_LONG}{BLACK} Running Cost: {LTBLUE}{CURRENCY_LONG}/yr
STR_VEHICLE_DETAILS_TRAIN_WAGON_VALUE :{LTBLUE}{ENGINE}{BLACK} Value: {LTBLUE}{CURRENCY_LONG}
+STR_VEHICLE_DETAILS_TRAIN_WAGON_VALUE_RUNCOST :{LTBLUE}{ENGINE}{BLACK} Value: {LTBLUE}{CURRENCY_LONG}{BLACK} Running Cost: {LTBLUE}{CURRENCY_LONG}/yr
STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_TEXT :{BLACK}Total cargo capacity of this train:
STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY :{LTBLUE}- {CARGO_LONG} ({CARGO_SHORT})
Index: train.h
===================================================================
--- train.h (revision 27764)
+++ train.h (working copy)
@@ -117,7 +117,7 @@
void GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const;
int GetDisplaySpeed() const { return this->gcache.last_speed; }
int GetDisplayMaxSpeed() const { return this->vcache.cached_max_speed; }
- Money GetRunningCost() const;
+ Money GetRunningCost(bool single_part = false) const;
int GetDisplayImageWidth(Point *offset = NULL) const;
bool IsInDepot() const { return this->track == TRACK_BIT_DEPOT; }
bool Tick();
Index: train_cmd.cpp
===================================================================
--- train_cmd.cpp (revision 27764)
+++ train_cmd.cpp (working copy)
@@ -3897,25 +3897,84 @@
* Get running cost for the train consist.
* @return Yearly running costs.
*/
-Money Train::GetRunningCost() const
+Money Train::GetRunningCost(bool single_part) const
{
Money cost = 0;
const Train *v = this;
+ const Train *v1 = single_part ? v->First() : v;
+ const Train *v2 = v1;
+ bool unc_len = false;
+ uint cal_cost = 0;
+ uint unc_cost = 0;
do {
- const Engine *e = v->GetEngine();
- if (e->u.rail.running_cost_class == INVALID_PRICE) continue;
+ const Engine *e = v1->GetEngine();
+ if (e->u.rail.running_cost_class == INVALID_PRICE) {
+ unc_len = true;
+ continue;
+ }
- uint cost_factor = GetVehicleProperty(v, PROP_TRAIN_RUNNING_COST_FACTOR, e->u.rail.running_cost);
+ uint cost_factor = GetVehicleProperty(v1, PROP_TRAIN_RUNNING_COST_FACTOR, e->u.rail.running_cost);
if (cost_factor == 0) continue;
/* Halve running cost for multiheaded parts */
+ if (v1->IsMultiheaded()) cost_factor /= 2;
+
+ cal_cost += GetPrice(e->u.rail.running_cost_class, cost_factor, e->GetGRF());
+ } while ((v1 = v1->GetNextVehicle()) != NULL);
+
+ if (unc_len && cal_cost > 0) {
+ do {
+ const Engine *e = v2->GetEngine();
+ if (e->u.rail.running_cost_class != INVALID_PRICE) continue;
+
+ const Train *a = v2;
+ uint ind_len = 0;
+ do {
+ ind_len += a->gcache.cached_veh_length;
+ a = a->HasArticulatedPart() ? a->GetNextArticulatedPart() : NULL;
+ } while (a != NULL);
+ if (ind_len == 0) continue;
+
+ uint ind_cost = cal_cost * ind_len / (VEHICLE_LENGTH * 2 * _settings_game.vehicle.max_train_length);
+ uint cost_factor = GetEngineProperty(e->index, PROP_TRAIN_RUNNING_COST_FACTOR, ind_cost);
+
+ /* Halve running cost for multiheaded parts */
+ if (v2->IsMultiheaded()) cost_factor /= 2;
+
+ unc_cost += GetPrice(PR_RUNNING_TRAIN_STEAM, cost_factor, e->GetGRF()) / _price[PR_RUNNING_TRAIN_STEAM];
+ } while ((v2 = v2->GetNextVehicle()) != NULL);
+ }
+
+ cost = unc_cost + cal_cost;
+ if (!single_part) return cost;
+
+ const Engine *e = v->GetEngine();
+ if (e->u.rail.running_cost_class == INVALID_PRICE) {
+ const Train *a = v;
+ uint ind_len = 0;
+ do {
+ ind_len += a->gcache.cached_veh_length;
+ a = a->HasArticulatedPart() ? a->GetNextArticulatedPart() : NULL;
+ } while (a != NULL);
+
+ uint ind_cost = cal_cost * ind_len / (VEHICLE_LENGTH * 2 * _settings_game.vehicle.max_train_length);
+ uint cost_factor = GetEngineProperty(e->index, PROP_TRAIN_RUNNING_COST_FACTOR, ind_cost);
+
+ /* Halve running cost for multiheaded parts */
if (v->IsMultiheaded()) cost_factor /= 2;
- cost += GetPrice(e->u.rail.running_cost_class, cost_factor, e->GetGRF());
- } while ((v = v->GetNextVehicle()) != NULL);
+ unc_cost = GetPrice(PR_RUNNING_TRAIN_STEAM, cost_factor, e->GetGRF()) / _price[PR_RUNNING_TRAIN_STEAM];
+ return unc_cost;
+ } else {
+ uint cost_factor = GetVehicleProperty(v, PROP_TRAIN_RUNNING_COST_FACTOR, e->u.rail.running_cost);
- return cost;
+ /* Halve running cost for multiheaded parts */
+ if (v->IsMultiheaded()) cost_factor /= 2;
+
+ cal_cost = GetPrice(e->u.rail.running_cost_class, cost_factor, e->GetGRF());
+ return cal_cost;
+ }
}
/**
Index: train_gui.cpp
===================================================================
--- train_gui.cpp (revision 27764)
+++ train_gui.cpp (working copy)
@@ -222,12 +222,14 @@
if (RailVehInfo(v->engine_type)->railveh_type == RAILVEH_WAGON) {
SetDParam(0, v->engine_type);
SetDParam(1, v->value);
- DrawString(left, right, y, STR_VEHICLE_DETAILS_TRAIN_WAGON_VALUE);
+ SetDParam(2, v->GetRunningCost(true) >> 8);
+ DrawString(left, right, y, STR_VEHICLE_DETAILS_TRAIN_WAGON_VALUE_RUNCOST);
} else {
SetDParam(0, v->engine_type);
SetDParam(1, v->build_year);
SetDParam(2, v->value);
- DrawString(left, right, y, STR_VEHICLE_DETAILS_TRAIN_ENGINE_BUILT_AND_VALUE);
+ SetDParam(3, v->GetRunningCost(true) >> 8);
+ DrawString(left, right, y, STR_VEHICLE_DETAILS_TRAIN_ENGINE_BUILT_VALUE_RUNCOST);
}
}
Index: vehicle_base.h
===================================================================
--- vehicle_base.h (revision 27764)
+++ vehicle_base.h (working copy)
@@ -495,7 +495,7 @@
* Gets the running cost of a vehicle
* @return the vehicle's running cost
*/
- virtual Money GetRunningCost() const { return 0; }
+ virtual Money GetRunningCost(bool single_part = false) const { return 0; }
/**
* Check whether the vehicle is in the depot.