/** * Returns max speed of the engine for display purposes * @return max speed in km-ish/h */ uint Engine::GetDisplayMaxSpeed() const { switch (this->type) { case VEH_TRAIN: return GetEngineProperty(this->index, PROP_TRAIN_SPEED, this->u.rail.max_speed); case VEH_ROAD: { uint max_speed = GetEngineProperty(this->index, PROP_ROADVEH_SPEED, 0); return (max_speed != 0) ? max_speed * 2 : this->u.road.max_speed / 2; } case VEH_SHIP: return GetEngineProperty(this->index, PROP_SHIP_SPEED, this->u.ship.max_speed) / 2; case VEH_AIRCRAFT: { uint max_speed = GetEngineProperty(this->index, PROP_AIRCRAFT_SPEED, 0); if (max_speed != 0) { return (max_speed * 128) / 10; } return this->u.air.max_speed; } default: NOT_REACHED(); } }
/** * Return how much a new engine costs. * @return Cost of the engine. */ Money Engine::GetCost() const { Price base_price; uint cost_factor; switch (this->type) { case VEH_ROAD: base_price = PR_BUILD_VEHICLE_ROAD; cost_factor = GetEngineProperty(this->index, PROP_ROADVEH_COST_FACTOR, this->u.road.cost_factor); break; case VEH_TRAIN: if (this->u.rail.railveh_type == RAILVEH_WAGON) { base_price = PR_BUILD_VEHICLE_WAGON; cost_factor = GetEngineProperty(this->index, PROP_TRAIN_COST_FACTOR, this->u.rail.cost_factor); } else { base_price = PR_BUILD_VEHICLE_TRAIN; cost_factor = GetEngineProperty(this->index, PROP_TRAIN_COST_FACTOR, this->u.rail.cost_factor); } break; case VEH_SHIP: base_price = PR_BUILD_VEHICLE_SHIP; cost_factor = GetEngineProperty(this->index, PROP_SHIP_COST_FACTOR, this->u.ship.cost_factor); break; case VEH_AIRCRAFT: base_price = PR_BUILD_VEHICLE_AIRCRAFT; cost_factor = GetEngineProperty(this->index, PROP_AIRCRAFT_COST_FACTOR, this->u.air.cost_factor); break; default: NOT_REACHED(); } return GetPrice(base_price, cost_factor, this->GetGRF(), -8); }
/** * Return how much the running costs of this engine are. * @return Yearly running cost of the engine. */ Money Engine::GetRunningCost() const { Price base_price; uint cost_factor; switch (this->type) { case VEH_ROAD: base_price = this->u.road.running_cost_class; if (base_price == INVALID_PRICE) return 0; cost_factor = GetEngineProperty(this->index, PROP_ROADVEH_RUNNING_COST_FACTOR, this->u.road.running_cost); break; case VEH_TRAIN: base_price = this->u.rail.running_cost_class; if (base_price == INVALID_PRICE) return 0; cost_factor = GetEngineProperty(this->index, PROP_TRAIN_RUNNING_COST_FACTOR, this->u.rail.running_cost); break; case VEH_SHIP: base_price = PR_RUNNING_SHIP; cost_factor = GetEngineProperty(this->index, PROP_SHIP_RUNNING_COST_FACTOR, this->u.ship.running_cost); break; case VEH_AIRCRAFT: base_price = PR_RUNNING_AIRCRAFT; cost_factor = GetEngineProperty(this->index, PROP_AIRCRAFT_RUNNING_COST_FACTOR, this->u.air.running_cost); break; default: NOT_REACHED(); } return GetPrice(base_price, cost_factor, this->GetGRF(), -8); }
/** * Returns the tractive effort of the engine for display purposes. * For dual-headed train-engines this is the tractive effort of both heads * @return tractive effort in display units kN */ uint Engine::GetDisplayMaxTractiveEffort() const { /* Only trains and road vehicles have 'tractive effort'. */ switch (this->type) { case VEH_TRAIN: return (10 * this->GetDisplayWeight() * GetEngineProperty(this->index, PROP_TRAIN_TRACTIVE_EFFORT, this->u.rail.tractive_effort)) / 256; case VEH_ROAD: return (10 * this->GetDisplayWeight() * GetEngineProperty(this->index, PROP_ROADVEH_TRACTIVE_EFFORT, this->u.road.tractive_effort)) / 256; default: NOT_REACHED(); } }
/** * Returns the weight of the engine for display purposes. * For dual-headed train-engines this is the weight of both heads * @return weight in display units metric tons */ uint Engine::GetDisplayWeight() const { /* Only trains and road vehicles have 'weight'. */ switch (this->type) { case VEH_TRAIN: return GetEngineProperty(this->index, PROP_TRAIN_WEIGHT, this->u.rail.weight) << (this->u.rail.railveh_type == RAILVEH_MULTIHEAD ? 1 : 0); case VEH_ROAD: return GetEngineProperty(this->index, PROP_ROADVEH_WEIGHT, this->u.road.weight) / 4; default: NOT_REACHED(); } }
/** * Returns the power of the engine for display * and sorting purposes. * Only trains and road vehicles have power * @return power in display units hp */ uint Engine::GetPower() const { /* Only trains and road vehicles have 'power'. */ switch (this->type) { case VEH_TRAIN: return GetEngineProperty(this->index, PROP_TRAIN_POWER, this->u.rail.power); case VEH_ROAD: return GetEngineProperty(this->index, PROP_ROADVEH_POWER, this->u.road.power) * 10; default: NOT_REACHED(); } }
/** * Get the range of an aircraft type. * @return Range of the aircraft type in tiles or 0 if unlimited range. */ uint16 Engine::GetRange() const { switch (this->type) { case VEH_AIRCRAFT: return GetEngineProperty(this->index, PROP_AIRCRAFT_RANGE, this->u.air.max_range); default: NOT_REACHED(); } }
/** * Return how much a new engine costs. * @return Cost of the engine. */ Money Engine::GetCost() const { Price base_price; uint cost_factor; switch (this->type) { case VEH_ROAD: base_price = PR_BUILD_VEHICLE_ROAD; cost_factor = GetEngineProperty(this->index, PROP_ROADVEH_COST_FACTOR, this->u.road.cost_factor); break; case VEH_TRAIN: if (this->u.rail.railveh_type == RAILVEH_WAGON) { base_price = PR_BUILD_VEHICLE_WAGON; cost_factor = GetEngineProperty(this->index, PROP_TRAIN_COST_FACTOR, this->u.rail.cost_factor); } else { base_price = PR_BUILD_VEHICLE_TRAIN; cost_factor = GetEngineProperty(this->index, PROP_TRAIN_COST_FACTOR, this->u.rail.cost_factor); } break; case VEH_SHIP: base_price = PR_BUILD_VEHICLE_SHIP; cost_factor = GetEngineProperty(this->index, PROP_SHIP_COST_FACTOR, this->u.ship.cost_factor); break; case VEH_AIRCRAFT: base_price = PR_BUILD_VEHICLE_AIRCRAFT; cost_factor = GetEngineProperty(this->index, PROP_AIRCRAFT_COST_FACTOR, this->u.air.cost_factor); break; default: NOT_REACHED(); } /* Multiply showed cost according to day length balance type. */ if (_settings_game.economy.day_length_balance_type == DBT_ALL_COSTS) { return GetPrice(base_price, cost_factor, this->GetGRF(), -8) * _settings_game.economy.day_length_balance_factor; } return GetPrice(base_price, cost_factor, this->GetGRF(), -8); }
/** * Return how much the running costs of this engine are. * @return Yearly running cost of the engine. */ Money Engine::GetRunningCost() const { Price base_price; uint cost_factor; switch (this->type) { case VEH_ROAD: base_price = this->u.road.running_cost_class; if (base_price == INVALID_PRICE) return 0; cost_factor = GetEngineProperty(this->index, PROP_ROADVEH_RUNNING_COST_FACTOR, this->u.road.running_cost); break; case VEH_TRAIN: base_price = this->u.rail.running_cost_class; if (base_price == INVALID_PRICE) return 0; cost_factor = GetEngineProperty(this->index, PROP_TRAIN_RUNNING_COST_FACTOR, this->u.rail.running_cost); break; case VEH_SHIP: base_price = PR_RUNNING_SHIP; cost_factor = GetEngineProperty(this->index, PROP_SHIP_RUNNING_COST_FACTOR, this->u.ship.running_cost); break; case VEH_AIRCRAFT: base_price = PR_RUNNING_AIRCRAFT; cost_factor = GetEngineProperty(this->index, PROP_AIRCRAFT_RUNNING_COST_FACTOR, this->u.air.running_cost); break; default: NOT_REACHED(); } /* Multiply showed running cost according to day length balance type. */ if (_settings_game.economy.day_length_balance_type == DBT_ALL_COSTS || _settings_game.economy.day_length_balance_type == DBT_RUN_COST) { return GetPrice(base_price, cost_factor, this->GetGRF(), -8) * _settings_game.economy.day_length_balance_factor; } return GetPrice(base_price, cost_factor, this->GetGRF(), -8); }
/** * Determines capacity of a given vehicle from scratch. * For aircraft the main capacity is determined. Mail might be present as well. * @param v Vehicle of interest; NULL in purchase list * @param mail_capacity returns secondary cargo (mail) capacity of aircraft * @return Capacity */ uint Engine::DetermineCapacity(const Vehicle *v, uint16 *mail_capacity) const { assert(v == NULL || this->index == v->engine_type); if (mail_capacity != NULL) *mail_capacity = 0; if (!this->CanCarryCargo()) return 0; bool new_multipliers = HasBit(this->info.misc_flags, EF_NO_DEFAULT_CARGO_MULTIPLIER); CargoID default_cargo = this->GetDefaultCargoType(); CargoID cargo_type = (v != NULL) ? v->cargo_type : default_cargo; if (mail_capacity != NULL && this->type == VEH_AIRCRAFT && IsCargoInClass(cargo_type, CC_PASSENGERS)) { *mail_capacity = GetEngineProperty(this->index, PROP_AIRCRAFT_MAIL_CAPACITY, this->u.air.mail_capacity, v); } /* Check the refit capacity callback if we are not in the default configuration, or if we are using the new multiplier algorithm. */ if (HasBit(this->info.callback_mask, CBM_VEHICLE_REFIT_CAPACITY) && (new_multipliers || default_cargo != cargo_type || (v != NULL && v->cargo_subtype != 0))) { uint16 callback = GetVehicleCallback(CBID_VEHICLE_REFIT_CAPACITY, 0, 0, this->index, v); if (callback != CALLBACK_FAILED) return callback; } /* Get capacity according to property resp. CB */ uint capacity; uint extra_mail_cap = 0; switch (this->type) { case VEH_TRAIN: capacity = GetEngineProperty(this->index, PROP_TRAIN_CARGO_CAPACITY, this->u.rail.capacity, v); /* In purchase list add the capacity of the second head. Always use the plain property for this. */ if (v == NULL && this->u.rail.railveh_type == RAILVEH_MULTIHEAD) capacity += this->u.rail.capacity; break; case VEH_ROAD: capacity = GetEngineProperty(this->index, PROP_ROADVEH_CARGO_CAPACITY, this->u.road.capacity, v); break; case VEH_SHIP: capacity = GetEngineProperty(this->index, PROP_SHIP_CARGO_CAPACITY, this->u.ship.capacity, v); break; case VEH_AIRCRAFT: capacity = GetEngineProperty(this->index, PROP_AIRCRAFT_PASSENGER_CAPACITY, this->u.air.passenger_capacity, v); if (!IsCargoInClass(cargo_type, CC_PASSENGERS)) { extra_mail_cap = GetEngineProperty(this->index, PROP_AIRCRAFT_MAIL_CAPACITY, this->u.air.mail_capacity, v); } if (!new_multipliers && cargo_type == CT_MAIL) return capacity + extra_mail_cap; default_cargo = CT_PASSENGERS; // Always use 'passengers' wrt. cargo multipliers break; default: NOT_REACHED(); } if (!new_multipliers) { /* Use the passenger multiplier for mail as well */ capacity += extra_mail_cap; extra_mail_cap = 0; } /* Apply multipliers depending on cargo- and vehicletype. */ if (new_multipliers || (this->type != VEH_SHIP && default_cargo != cargo_type)) { uint16 default_multiplier = new_multipliers ? 0x100 : CargoSpec::Get(default_cargo)->multiplier; uint16 cargo_multiplier = CargoSpec::Get(cargo_type)->multiplier; capacity *= cargo_multiplier; if (extra_mail_cap > 0) { uint mail_multiplier = CargoSpec::Get(CT_MAIL)->multiplier; capacity += (default_multiplier * extra_mail_cap * cargo_multiplier + mail_multiplier / 2) / mail_multiplier; } capacity = (capacity + default_multiplier / 2) / default_multiplier; } return capacity; }