Paste #pkeyrhsb0

1. cost      // running cost of the whole
2. unc_len   // lenght of all parts without a running cost
3. cal_cost  // running cost of all parts (or single part) with a running cost
4. unc_cost  // simulated running cost of all parts (or single part) without a running cost
5. divisor   // user defined value for fine tunning the simulated running cost for each part without a running cost
6. cal_cost += cal_cost
7. ind_len   // length of current part without running cost
8. ind_cost = (unc_len * cal_cost * ind_len) / (VEHICLE_LENGTH * divisor * 2)
9. unc_cost += ind_cost
10. cost = unc_cost + cal_cost
11.
12.
13.
14. /**
15.  * Get running cost for the train consist or only for the current part.
16.  *
17.  * @param single_part whether to return the running cost of the current part or the whole.
18.  * @return Yearly running costs.
19.  */
20. Money Train::GetRunningCost(bool single_part) const
21. {
22.     Money cost = 0;     // running cost of the whole
23.     uint unc_len = 0;   // lenght of all parts without a running cost
24.     Money cal_cost = 0; // running cost of all parts (or single part) with a running cost
25.     Money unc_cost = 0; // simulated running cost of all parts (or single part) without a running cost
26.     uint divisor = 0;   // user defined value for fine tunning the simulated running cost for each part without a running cost
27.     if (_settings_game.vehicle.train_extra_runcost_divisor == 0) {
28.         divisor = VEHICLE_LENGTH * 2 * _settings_game.vehicle.max_train_length;
29.     } else {
30.         divisor = VEHICLE_LENGTH * 2 * _settings_game.vehicle.train_extra_runcost_divisor;
31.     }
32.
33.     const Train *v = this;
34.     const Train *v1 = single_part ? v->First() : v;
35.     const Train *v2 = v1;
36.
37.     do {
38.         const Engine *e = v1->GetEngine();
39.         if (e->u.rail.running_cost_class == INVALID_PRICE) {
40.             const Train *a = v1;
41.             do {
42.                 unc_len += a->gcache.cached_veh_length;
43.                 a = a->HasArticulatedPart() ? a->GetNextArticulatedPart() : NULL;
44.             } while (a != NULL);
45.             continue;
46.         }
47.
48.         uint cost_factor = GetVehicleProperty(v1, PROP_TRAIN_RUNNING_COST_FACTOR, e->u.rail.running_cost);
49.         if (cost_factor == 0) continue;
50.
51.         /* Halve running cost for multiheaded parts */
52.         if (v1->IsMultiheaded()) cost_factor /= 2;
53.
54.         cal_cost += GetPrice(e->u.rail.running_cost_class, cost_factor, e->GetGRF());
55.     } while ((v1 = v1->GetNextVehicle()) != NULL);
56.
57.     if (_settings_game.vehicle.train_extra_runcost && unc_len > 0 && cal_cost > 0) {
58.         do {
59.             const Engine *e = v2->GetEngine();
60.             if (e->u.rail.running_cost_class != INVALID_PRICE) continue;
61.
62.             const Train *a = v2;
63.             uint ind_len = 0; // length of current part without running cost
64.             do {
65.                 ind_len += a->gcache.cached_veh_length;
66.                 a = a->HasArticulatedPart() ? a->GetNextArticulatedPart() : NULL;
67.             } while (a != NULL);
68.             if (ind_len == 0) continue;
69.
70.             Money ind_cost = (unc_len * cal_cost * ind_len) / (VEHICLE_LENGTH * divisor * 2);
71.             uint cost_factor = GetVehicleProperty(v2, PROP_TRAIN_RUNNING_COST_FACTOR, ind_cost);
72.
73.             /* Halve running cost for multiheaded parts */
74.             if (v2->IsMultiheaded()) cost_factor /= 2;
75.
76.             unc_cost += GetPrice(PR_RUNNING_TRAIN_STEAM, cost_factor, e->GetGRF()) / _price[PR_RUNNING_TRAIN_STEAM];
77.         } while ((v2 = v2->GetNextVehicle()) != NULL);
78.     }
79.
80.     cost = unc_cost + cal_cost;
81.     if (!single_part) return cost;
82.
83.     const Engine *e = v->GetEngine();
84.     if (e->u.rail.running_cost_class == INVALID_PRICE) {
85.         if (!_settings_game.vehicle.train_extra_runcost) return unc_cost;
86.
87.         const Train *a = v;
88.         uint ind_len = 0; // length of current part without running cost
89.         do {
90.             ind_len += a->gcache.cached_veh_length;
91.             a = a->HasArticulatedPart() ? a->GetNextArticulatedPart() : NULL;
92.         } while (a != NULL);
93.
94.         Money ind_cost = (unc_len * cal_cost * ind_len) / (VEHICLE_LENGTH * divisor * 2);
95.         uint cost_factor = GetVehicleProperty(v, PROP_TRAIN_RUNNING_COST_FACTOR, ind_cost);
96.
97.         /* Halve running cost for multiheaded parts */
98.         if (v->IsMultiheaded()) cost_factor /= 2;
99.
100.         unc_cost = GetPrice(PR_RUNNING_TRAIN_STEAM, cost_factor, e->GetGRF()) / _price[PR_RUNNING_TRAIN_STEAM];
101.         return unc_cost;
102.     } else {
103.         uint cost_factor = GetVehicleProperty(v, PROP_TRAIN_RUNNING_COST_FACTOR, e->u.rail.running_cost);
104.
105.         /* Halve running cost for multiheaded parts */
106.         if (v->IsMultiheaded()) cost_factor /= 2;
107.
108.         cal_cost = GetPrice(e->u.rail.running_cost_class, cost_factor, e->GetGRF());
109.         return cal_cost;
110.     }
111. }