|
|
|
@ -975,7 +975,7 @@ Money GetPrice(Price index, uint cost_factor, const GRFFile *grf_file, int shift
|
|
|
|
|
return cost;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Money GetTransportedGoodsIncome(uint num_pieces, uint dist, uint16 transit_days, CargoID cargo_type)
|
|
|
|
|
Money GetTransportedGoodsIncome(uint num_pieces, uint dist, uint16 transit_periods, CargoID cargo_type)
|
|
|
|
|
{
|
|
|
|
|
const CargoSpec *cs = CargoSpec::Get(cargo_type);
|
|
|
|
|
if (!cs->IsValid()) {
|
|
|
|
@ -985,7 +985,7 @@ Money GetTransportedGoodsIncome(uint num_pieces, uint dist, uint16 transit_days,
|
|
|
|
|
|
|
|
|
|
/* Use callback to calculate cargo profit, if available */
|
|
|
|
|
if (HasBit(cs->callback_mask, CBM_CARGO_PROFIT_CALC)) {
|
|
|
|
|
uint32 var18 = ClampTo<uint16_t>(dist) | (ClampTo<uint8_t>(num_pieces) << 16) | (ClampTo<uint8_t>(transit_days) << 24);
|
|
|
|
|
uint32 var18 = ClampTo<uint16_t>(dist) | (ClampTo<uint8_t>(num_pieces) << 16) | (ClampTo<uint8_t>(transit_periods) << 24);
|
|
|
|
|
uint16 callback = GetCargoCallback(CBID_CARGO_PROFIT_CALC, 0, var18, cs);
|
|
|
|
|
if (callback != CALLBACK_FAILED) {
|
|
|
|
|
int result = GB(callback, 0, 14);
|
|
|
|
@ -1005,17 +1005,20 @@ Money GetTransportedGoodsIncome(uint num_pieces, uint dist, uint16 transit_days,
|
|
|
|
|
static const int TIME_FACTOR_FRAC_BITS = 4;
|
|
|
|
|
static const int TIME_FACTOR_FRAC = 1 << TIME_FACTOR_FRAC_BITS;
|
|
|
|
|
|
|
|
|
|
const int days1 = cs->transit_days[0];
|
|
|
|
|
const int days2 = cs->transit_days[1];
|
|
|
|
|
const int days_over_days1 = std::max( transit_days - days1, 0);
|
|
|
|
|
const int days_over_days2 = std::max(days_over_days1 - days2, 0);
|
|
|
|
|
int days_over_max = MIN_TIME_FACTOR - MAX_TIME_FACTOR;
|
|
|
|
|
if (days2 > -days_over_max) days_over_max += transit_days - days1;
|
|
|
|
|
else days_over_max += 2 * (transit_days - days1) - days2;
|
|
|
|
|
const int periods1 = cs->transit_periods[0];
|
|
|
|
|
const int periods2 = cs->transit_periods[1];
|
|
|
|
|
const int periods_over_periods1 = std::max(transit_periods - periods1, 0);
|
|
|
|
|
const int periods_over_periods2 = std::max(periods_over_periods1 - periods2, 0);
|
|
|
|
|
int periods_over_max = MIN_TIME_FACTOR - MAX_TIME_FACTOR;
|
|
|
|
|
if (periods2 > -periods_over_max) {
|
|
|
|
|
periods_over_max += transit_periods - periods1;
|
|
|
|
|
} else {
|
|
|
|
|
periods_over_max += 2 * (transit_periods - periods1) - periods2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* The time factor is calculated based on the time it took
|
|
|
|
|
* (transit_days) compared two cargo-depending values. The
|
|
|
|
|
* (transit_periods) compared two cargo-depending values. The
|
|
|
|
|
* range is divided into four parts:
|
|
|
|
|
*
|
|
|
|
|
* - constant for fast transits
|
|
|
|
@ -1024,11 +1027,11 @@ Money GetTransportedGoodsIncome(uint num_pieces, uint dist, uint16 transit_days,
|
|
|
|
|
* - after hitting MIN_TIME_FACTOR, the time factor will be asymptotically decreased to a limit of 1 with a scaled 1/(x+1) function.
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
if (days_over_max > 0) {
|
|
|
|
|
const int time_factor = std::max(2 * MIN_TIME_FACTOR * TIME_FACTOR_FRAC * TIME_FACTOR_FRAC / (days_over_max + 2 * TIME_FACTOR_FRAC), 1); // MIN_TIME_FACTOR / (x/(2 * TIME_FACTOR_FRAC) + 1) + 1, expressed as fixed point with TIME_FACTOR_FRAC_BITS.
|
|
|
|
|
if (periods_over_max > 0) {
|
|
|
|
|
const int time_factor = std::max(2 * MIN_TIME_FACTOR * TIME_FACTOR_FRAC * TIME_FACTOR_FRAC / (periods_over_max + 2 * TIME_FACTOR_FRAC), 1); // MIN_TIME_FACTOR / (x/(2 * TIME_FACTOR_FRAC) + 1) + 1, expressed as fixed point with TIME_FACTOR_FRAC_BITS.
|
|
|
|
|
return BigMulS(dist * time_factor * num_pieces, cs->current_payment, 21 + TIME_FACTOR_FRAC_BITS);
|
|
|
|
|
} else {
|
|
|
|
|
const int time_factor = std::max(MAX_TIME_FACTOR - days_over_days1 - days_over_days2, MIN_TIME_FACTOR);
|
|
|
|
|
const int time_factor = std::max(MAX_TIME_FACTOR - periods_over_periods1 - periods_over_periods2, MIN_TIME_FACTOR);
|
|
|
|
|
return BigMulS(dist * time_factor * num_pieces, cs->current_payment, 21);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -1094,14 +1097,14 @@ static uint DeliverGoodsToIndustry(const Station *st, CargoID cargo_type, uint n
|
|
|
|
|
* @param cargo_type the type of cargo that is delivered
|
|
|
|
|
* @param dest Station the cargo has been unloaded
|
|
|
|
|
* @param source_tile The origin of the cargo for distance calculation
|
|
|
|
|
* @param days_in_transit Travel time
|
|
|
|
|
* @param periods_in_transit Travel time in cargo aging periods
|
|
|
|
|
* @param company The company delivering the cargo
|
|
|
|
|
* @param src_type Type of source of cargo (industry, town, headquarters)
|
|
|
|
|
* @param src Index of source of cargo
|
|
|
|
|
* @return Revenue for delivering cargo
|
|
|
|
|
* @note The cargo is just added to the stockpile of the industry. It is due to the caller to trigger the industry's production machinery
|
|
|
|
|
*/
|
|
|
|
|
static Money DeliverGoods(int num_pieces, CargoID cargo_type, StationID dest, TileIndex source_tile, uint16 days_in_transit, Company *company, SourceType src_type, SourceID src)
|
|
|
|
|
static Money DeliverGoods(int num_pieces, CargoID cargo_type, StationID dest, TileIndex source_tile, uint16 periods_in_transit, Company *company, SourceType src_type, SourceID src)
|
|
|
|
|
{
|
|
|
|
|
assert(num_pieces > 0);
|
|
|
|
|
|
|
|
|
@ -1128,7 +1131,7 @@ static Money DeliverGoods(int num_pieces, CargoID cargo_type, StationID dest, Ti
|
|
|
|
|
st->town->received[cs->town_effect].new_act += accepted_total;
|
|
|
|
|
|
|
|
|
|
/* Determine profit */
|
|
|
|
|
Money profit = GetTransportedGoodsIncome(accepted_total, DistanceManhattan(source_tile, st->xy), days_in_transit, cargo_type);
|
|
|
|
|
Money profit = GetTransportedGoodsIncome(accepted_total, DistanceManhattan(source_tile, st->xy), periods_in_transit, cargo_type);
|
|
|
|
|
|
|
|
|
|
/* Update the cargo monitor. */
|
|
|
|
|
AddCargoDelivery(cargo_type, company->index, accepted_total - accepted_ind, src_type, src, st);
|
|
|
|
@ -1230,7 +1233,7 @@ void CargoPayment::PayFinalDelivery(const CargoPacket *cp, uint count)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Handle end of route payment */
|
|
|
|
|
Money profit = DeliverGoods(count, this->ct, this->current_station, cp->SourceStationXY(), cp->DaysInTransit(), this->owner, cp->SourceSubsidyType(), cp->SourceSubsidyID());
|
|
|
|
|
Money profit = DeliverGoods(count, this->ct, this->current_station, cp->SourceStationXY(), cp->PeriodsInTransit(), this->owner, cp->SourceSubsidyType(), cp->SourceSubsidyID());
|
|
|
|
|
this->route_profit += profit;
|
|
|
|
|
|
|
|
|
|
/* The vehicle's profit is whatever route profit there is minus feeder shares. */
|
|
|
|
@ -1250,7 +1253,7 @@ Money CargoPayment::PayTransfer(const CargoPacket *cp, uint count)
|
|
|
|
|
/* pay transfer vehicle the difference between the payment for the journey from
|
|
|
|
|
* the source to the current point, and the sum of the previous transfer payments */
|
|
|
|
|
DistanceManhattan(cp->SourceStationXY(), Station::Get(this->current_station)->xy),
|
|
|
|
|
cp->DaysInTransit(),
|
|
|
|
|
cp->PeriodsInTransit(),
|
|
|
|
|
this->ct);
|
|
|
|
|
|
|
|
|
|
profit = profit * _settings_game.economy.feeder_payment_share / 100;
|
|
|
|
|