cost // running cost of the whole unc_len // lenght of all parts without a running cost cal_cost // running cost of all parts (or single part) with a running cost unc_cost // simulated running cost of all parts (or single part) without a running cost divisor // user defined value for fine tunning the simulated running cost for each part without a running cost cal_cost += cal_cost ind_len // length of current part without running cost ind_cost = (unc_len * cal_cost * ind_len) / (VEHICLE_LENGTH * divisor * 2) unc_cost += ind_cost cost = unc_cost + cal_cost /** * Get running cost for the train consist or only for the current part. * * @param single_part whether to return the running cost of the current part or the whole. * @return Yearly running costs. */ Money Train::GetRunningCost(bool single_part) const { Money cost = 0; // running cost of the whole uint unc_len = 0; // lenght of all parts without a running cost Money cal_cost = 0; // running cost of all parts (or single part) with a running cost Money unc_cost = 0; // simulated running cost of all parts (or single part) without a running cost uint divisor = 0; // user defined value for fine tunning the simulated running cost for each part without a running cost if (_settings_game.vehicle.train_extra_runcost_divisor == 0) { divisor = VEHICLE_LENGTH * 2 * _settings_game.vehicle.max_train_length; } else { divisor = VEHICLE_LENGTH * 2 * _settings_game.vehicle.train_extra_runcost_divisor; } const Train *v = this; const Train *v1 = single_part ? v->First() : v; const Train *v2 = v1; do { const Engine *e = v1->GetEngine(); if (e->u.rail.running_cost_class == INVALID_PRICE) { const Train *a = v1; do { unc_len += a->gcache.cached_veh_length; a = a->HasArticulatedPart() ? a->GetNextArticulatedPart() : NULL; } while (a != NULL); continue; } 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 (_settings_game.vehicle.train_extra_runcost && unc_len > 0 && 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; // length of current part without running cost do { ind_len += a->gcache.cached_veh_length; a = a->HasArticulatedPart() ? a->GetNextArticulatedPart() : NULL; } while (a != NULL); if (ind_len == 0) continue; Money ind_cost = (unc_len * cal_cost * ind_len) / (VEHICLE_LENGTH * divisor * 2); uint cost_factor = GetVehicleProperty(v2, 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) { if (!_settings_game.vehicle.train_extra_runcost) return unc_cost; const Train *a = v; uint ind_len = 0; // length of current part without running cost do { ind_len += a->gcache.cached_veh_length; a = a->HasArticulatedPart() ? a->GetNextArticulatedPart() : NULL; } while (a != NULL); Money ind_cost = (unc_len * cal_cost * ind_len) / (VEHICLE_LENGTH * divisor * 2); uint cost_factor = GetVehicleProperty(v, PROP_TRAIN_RUNNING_COST_FACTOR, ind_cost); /* Halve running cost for multiheaded parts */ if (v->IsMultiheaded()) cost_factor /= 2; 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); /* 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; } }