diff --git a/src/cargoaction.cpp b/src/cargoaction.cpp index 8601ba81c8..4dbfaf9653 100644 --- a/src/cargoaction.cpp +++ b/src/cargoaction.cpp @@ -107,7 +107,7 @@ bool CargoDelivery::operator()(CargoPacket *cp) { uint remove = this->Preprocess(cp); this->source->RemoveFromMeta(cp, VehicleCargoList::MTA_DELIVER, remove); - this->payment->PayFinalDelivery(cp, remove); + this->payment->PayFinalDelivery(cp, remove, DistanceManhattan(this->location, cp->GetMovement())); return this->Postprocess(cp, remove); } @@ -120,6 +120,7 @@ bool CargoLoad::operator()(CargoPacket *cp) { CargoPacket *cp_new = this->Preprocess(cp); if (cp_new == nullptr) return false; + cp_new->TrackLoad(this->location); this->source->RemoveFromCache(cp_new, cp_new->Count()); this->destination->Append(cp_new, VehicleCargoList::MTA_KEEP); return cp_new == cp; @@ -134,6 +135,7 @@ bool CargoReservation::operator()(CargoPacket *cp) { CargoPacket *cp_new = this->Preprocess(cp); if (cp_new == nullptr) return false; + cp_new->TrackLoad(this->location); this->source->reserved_count += cp_new->Count(); this->source->RemoveFromCache(cp_new, cp_new->Count()); this->destination->Append(cp_new, VehicleCargoList::MTA_LOAD); @@ -150,6 +152,7 @@ bool CargoReturn::operator()(CargoPacket *cp) CargoPacket *cp_new = this->Preprocess(cp); if (cp_new == nullptr) cp_new = cp; assert(cp_new->Count() <= this->destination->reserved_count); + cp_new->TrackUnload(this->location); this->source->RemoveFromMeta(cp_new, VehicleCargoList::MTA_LOAD, cp_new->Count()); this->destination->reserved_count -= cp_new->Count(); this->destination->Append(cp_new, this->next); @@ -165,6 +168,7 @@ bool CargoTransfer::operator()(CargoPacket *cp) { CargoPacket *cp_new = this->Preprocess(cp); if (cp_new == nullptr) return false; + cp_new->TrackUnload(this->location); this->source->RemoveFromMeta(cp_new, VehicleCargoList::MTA_TRANSFER, cp_new->Count()); /* No transfer credits here as they were already granted during Stage(). */ this->destination->Append(cp_new, cp_new->GetNextStation()); diff --git a/src/cargoaction.h b/src/cargoaction.h index 72df5f5789..f8f54668e6 100644 --- a/src/cargoaction.h +++ b/src/cargoaction.h @@ -39,9 +39,10 @@ public: class CargoDelivery : public CargoRemoval { protected: CargoPayment *payment; ///< Payment object where payments will be registered. + TileIndex location; public: - CargoDelivery(VehicleCargoList *source, uint max_move, CargoPayment *payment) : - CargoRemoval(source, max_move), payment(payment) {} + CargoDelivery(VehicleCargoList *source, uint max_move, CargoPayment *payment, TileIndex location) : + CargoRemoval(source, max_move), payment(payment), location(location) {} bool operator()(CargoPacket *cp); }; @@ -69,33 +70,39 @@ public: /** Action of transferring cargo from a vehicle to a station. */ class CargoTransfer : public CargoMovement { +protected: + TileIndex location; public: - CargoTransfer(VehicleCargoList *source, StationCargoList *destination, uint max_move) : - CargoMovement(source, destination, max_move) {} + CargoTransfer(VehicleCargoList *source, StationCargoList *destination, uint max_move, TileIndex location) : + CargoMovement(source, destination, max_move), location(location) {} bool operator()(CargoPacket *cp); }; /** Action of loading cargo from a station onto a vehicle. */ class CargoLoad : public CargoMovement { +protected: + TileIndex location; public: - CargoLoad(StationCargoList *source, VehicleCargoList *destination, uint max_move) : - CargoMovement(source, destination, max_move) {} + CargoLoad(StationCargoList *source, VehicleCargoList *destination, uint max_move, TileIndex location) : + CargoMovement(source, destination, max_move), location(location) {} bool operator()(CargoPacket *cp); }; /** Action of reserving cargo from a station to be loaded onto a vehicle. */ class CargoReservation : public CargoLoad { public: - CargoReservation(StationCargoList *source, VehicleCargoList *destination, uint max_move) : - CargoLoad(source, destination, max_move) {} + CargoReservation(StationCargoList *source, VehicleCargoList *destination, uint max_move, TileIndex location) : + CargoLoad(source, destination, max_move, location) {} bool operator()(CargoPacket *cp); }; /** Action of returning previously reserved cargo from the vehicle to the station. */ class CargoReturn : public CargoMovement { +protected: + TileIndex location; StationID next; public: - CargoReturn(VehicleCargoList *source, StationCargoList *destination, uint max_move, StationID next) : + CargoReturn(VehicleCargoList *source, StationCargoList *destination, uint max_move, StationID next, TileIndex location) : CargoMovement(source, destination, max_move), next(next) {} bool operator()(CargoPacket *cp); }; diff --git a/src/cargopacket.cpp b/src/cargopacket.cpp index 592940d25b..b0373ca2c4 100644 --- a/src/cargopacket.cpp +++ b/src/cargopacket.cpp @@ -33,7 +33,7 @@ CargoPacket::CargoPacket() /** * Creates a new cargo packet. * @param first_station Source station of the packet. - * @param source_xy Source location of the packet. + * @param movement Accumulated movement vector of the packet. * @param count Number of cargo entities to put in this packet. * @param source_type 'Type' of source the packet comes from (for subsidies). * @param source_id Actual source of the packet (for subsidies). @@ -41,9 +41,9 @@ CargoPacket::CargoPacket() * @note We have to zero memory ourselves here because we are using a 'new' * that, in contrary to all other pools, does not memset to 0. */ -CargoPacket::CargoPacket(StationID first_station, TileIndex source_xy, uint16_t count, SourceType source_type, SourceID source_id) : +CargoPacket::CargoPacket(StationID first_station, TileIndex movement, uint16_t count, SourceType source_type, SourceID source_id) : count(count), - source_xy(source_xy), + movement(movement), source_id(source_id), source_type(source_type), first_station(first_station) @@ -57,18 +57,18 @@ CargoPacket::CargoPacket(StationID first_station, TileIndex source_xy, uint16_t * @param count Number of cargo entities to put in this packet. * @param periods_in_transit Number of cargo aging periods the cargo has been in transit. * @param first_station Station the cargo was initially loaded. - * @param source_xy Station location the cargo was initially loaded. + * @param movement Accumulated movement vector of the packet. * @param feeder_share Feeder share the packet has already accumulated. * @param source_type 'Type' of source the packet comes from (for subsidies). * @param source_id Actual source of the packet (for subsidies). * @note We have to zero memory ourselves here because we are using a 'new' * that, in contrary to all other pools, does not memset to 0. */ -CargoPacket::CargoPacket(uint16_t count, uint16_t periods_in_transit, StationID first_station, TileIndex source_xy, Money feeder_share, SourceType source_type, SourceID source_id) : +CargoPacket::CargoPacket(uint16_t count, uint16_t periods_in_transit, StationID first_station, TileIndex movement, Money feeder_share, SourceType source_type, SourceID source_id) : count(count), periods_in_transit(periods_in_transit), feeder_share(feeder_share), - source_xy(source_xy), + movement(movement), source_id(source_id), source_type(source_type), first_station(first_station) @@ -86,7 +86,7 @@ CargoPacket *CargoPacket::Split(uint new_size) if (!CargoPacket::CanAllocateItem()) return nullptr; Money fs = this->GetFeederShare(new_size); - CargoPacket *cp_new = new CargoPacket(new_size, this->periods_in_transit, this->first_station, this->source_xy, fs, this->source_type, this->source_id); + CargoPacket *cp_new = new CargoPacket(new_size, this->periods_in_transit, this->first_station, this->movement, fs, this->source_type, this->source_id); this->feeder_share -= fs; this->count -= new_size; return cp_new; @@ -418,9 +418,10 @@ void VehicleCargoList::AgeCargo() * @param order_flags OrderUnloadFlags that will apply to the unload operation. * @param ge GoodsEntry for getting the flows. * @param payment Payment object for registering transfers. + * @param location TileIndex if the point cargo is unloaded at. * return If any cargo will be unloaded. */ -bool VehicleCargoList::Stage(bool accepted, StationID current_station, StationIDStack next_station, uint8_t order_flags, const GoodsEntry *ge, CargoPayment *payment) +bool VehicleCargoList::Stage(bool accepted, StationID current_station, StationIDStack next_station, uint8_t order_flags, const GoodsEntry *ge, CargoPayment *payment, TileIndex location) { this->AssertCountConsistency(); assert(this->action_counts[MTA_LOAD] == 0); @@ -496,7 +497,7 @@ bool VehicleCargoList::Stage(bool accepted, StationID current_station, StationID case MTA_TRANSFER: this->packets.push_front(cp); /* Add feeder share here to allow reusing field for next station. */ - share = payment->PayTransfer(cp, cp->count); + share = payment->PayTransfer(cp, cp->count, location); cp->AddFeederShare(share); this->feeder_share += share; cp->next_station = cargo_next; @@ -578,10 +579,10 @@ uint VehicleCargoList::Reassignaction_counts[MTA_LOAD], max_move); - this->PopCargo(CargoReturn(this, dest, max_move, next)); + this->PopCargo(CargoReturn(this, dest, max_move, next, location)); return max_move; } @@ -606,17 +607,17 @@ uint VehicleCargoList::Shift(uint max_move, VehicleCargoList *dest) * @param payment Payment object to register payments in. * @return Amount of cargo actually unloaded. */ -uint VehicleCargoList::Unload(uint max_move, StationCargoList *dest, CargoPayment *payment) +uint VehicleCargoList::Unload(uint max_move, StationCargoList *dest, CargoPayment *payment, TileIndex location) { uint moved = 0; if (this->action_counts[MTA_TRANSFER] > 0) { uint move = std::min(this->action_counts[MTA_TRANSFER], max_move); - this->ShiftCargo(CargoTransfer(this, dest, move)); + this->ShiftCargo(CargoTransfer(this, dest, move, location)); moved += move; } if (this->action_counts[MTA_TRANSFER] == 0 && this->action_counts[MTA_DELIVER] > 0 && moved < max_move) { uint move = std::min(this->action_counts[MTA_DELIVER], max_move - moved); - this->ShiftCargo(CargoDelivery(this, move, payment)); + this->ShiftCargo(CargoDelivery(this, move, payment, location)); moved += move; } return moved; @@ -794,11 +795,12 @@ uint StationCargoList::Truncate(uint max_move, StationCargoAmountMap *cargo_per_ * @param max_move Maximum amount of cargo to reserve. * @param dest VehicleCargoList to reserve for. * @param next_station Next station(s) the loading vehicle will visit. + * @param location Tile index of the loading vehicle. * @return Amount of cargo actually reserved. */ -uint StationCargoList::Reserve(uint max_move, VehicleCargoList *dest, StationIDStack next_station) +uint StationCargoList::Reserve(uint max_move, VehicleCargoList *dest, StationIDStack next_station, TileIndex location) { - return this->ShiftCargo(CargoReservation(this, dest, max_move), next_station, true); + return this->ShiftCargo(CargoReservation(this, dest, max_move, location), next_station, true); } /** @@ -807,12 +809,13 @@ uint StationCargoList::Reserve(uint max_move, VehicleCargoList *dest, StationIDS * @param max_move Amount of cargo to load. * @param dest Vehicle cargo list where the cargo resides. * @param next_station Next station(s) the loading vehicle will visit. + * @param location Tile index of the loading vehicle. * @return Amount of cargo actually loaded. * @note Vehicles may or may not reserve, depending on their orders. The two * modes of loading are exclusive, though. If cargo is reserved we don't * need to load unreserved cargo. */ -uint StationCargoList::Load(uint max_move, VehicleCargoList *dest, StationIDStack next_station) +uint StationCargoList::Load(uint max_move, VehicleCargoList *dest, StationIDStack next_station, TileIndex location) { uint move = std::min(dest->ActionCount(VehicleCargoList::MTA_LOAD), max_move); if (move > 0) { @@ -820,7 +823,7 @@ uint StationCargoList::Load(uint max_move, VehicleCargoList *dest, StationIDStac dest->Reassign(move); return move; } else { - return this->ShiftCargo(CargoLoad(this, dest, max_move), next_station, true); + return this->ShiftCargo(CargoLoad(this, dest, max_move, location), next_station, true); } } diff --git a/src/cargopacket.h b/src/cargopacket.h index 12b8babbe9..5d9e6877a2 100644 --- a/src/cargopacket.h +++ b/src/cargopacket.h @@ -44,7 +44,7 @@ private: Money feeder_share{0}; ///< Value of feeder pickup to be paid for on delivery of cargo. - TileIndex source_xy{0}; ///< The origin of the cargo. + TileIndex movement{0}; ///< Vector (tile difference) representing accumulated cargo movement in vehicles. Used to calculate payments. Is calculated as load_tile_1 - unload_tile1 + load_tile_2 - unload_tile_2 + ... SourceID source_id{INVALID_SOURCE}; ///< Index of industry/town/HQ, INVALID_SOURCE if unknown/invalid. SourceType source_type{SourceType::Industry}; ///< Type of \c source_id. @@ -62,8 +62,8 @@ public: static const uint16_t MAX_COUNT = UINT16_MAX; CargoPacket(); - CargoPacket(StationID first_station, TileIndex source_xy, uint16_t count, SourceType source_type, SourceID source_id); - CargoPacket(uint16_t count, uint16_t periods_in_transit, StationID source, TileIndex source_xy, Money feeder_share = 0, SourceType source_type = SourceType::Industry, SourceID source_id = INVALID_SOURCE); + CargoPacket(StationID first_station, TileIndex movement, uint16_t count, SourceType source_type, SourceID source_id); + CargoPacket(uint16_t count, uint16_t periods_in_transit, StationID source, TileIndex source_position, Money feeder_share = 0, SourceType source_type = SourceType::Industry, SourceID source_id = INVALID_SOURCE); /** Destroy the packet. */ ~CargoPacket() { } @@ -72,6 +72,22 @@ public: void Merge(CargoPacket *cp); void Reduce(uint count); + /** + * Updates movement vector on cargo load. + * @param load_tile TileIndex of loading location (vehicle). + */ + void TrackLoad(TileIndex load_tile) { + this->movement += load_tile; + } + + /** + * Updates movement vector on cargo unload. + * @param unload_tile TileIndex of unloading location (vehicle). + */ + void TrackUnload(TileIndex unload_tile) { + this->movement -= unload_tile; + } + /** * Sets the station where the packet is supposed to go next. * @param next_station Next station the packet should go to. @@ -160,12 +176,12 @@ public: } /** - * Gets the coordinates of the cargo's source. - * @return Source coordinates of cargo. + * Gets the accumulated cargo movement vector. + * @return TileIndexDiff. */ - inline TileIndex GetSourceXY() const + inline TileIndex GetMovement() const { - return this->source_xy; + return this->movement; } /** @@ -385,7 +401,7 @@ public: void InvalidateCache(); - bool Stage(bool accepted, StationID current_station, StationIDStack next_station, uint8_t order_flags, const GoodsEntry *ge, CargoPayment *payment); + bool Stage(bool accepted, StationID current_station, StationIDStack next_station, uint8_t order_flags, const GoodsEntry *ge, CargoPayment *payment, TileIndex location); /** * Marks all cargo in the vehicle as to be kept. This is mostly useful for @@ -404,8 +420,8 @@ public: template uint Reassign(uint max_move, StationID update = INVALID_STATION); - uint Return(uint max_move, StationCargoList *dest, StationID next_station); - uint Unload(uint max_move, StationCargoList *dest, CargoPayment *payment); + uint Return(uint max_move, StationCargoList *dest, StationID next_station, TileIndex location); + uint Unload(uint max_move, StationCargoList *dest, CargoPayment *payment, TileIndex location); uint Shift(uint max_move, VehicleCargoList *dest); uint Truncate(uint max_move = UINT_MAX); uint Reroute(uint max_move, VehicleCargoList *dest, StationID avoid, StationID avoid2, const GoodsEntry *ge); @@ -419,7 +435,7 @@ public: */ static bool AreMergable(const CargoPacket *cp1, const CargoPacket *cp2) { - return cp1->source_xy == cp2->source_xy && + return cp1->movement == cp2->movement && cp1->periods_in_transit == cp2->periods_in_transit && cp1->source_type == cp2->source_type && cp1->source_id == cp2->source_id; @@ -519,8 +535,8 @@ public: * amount of cargo to be moved. Second parameter is destination (if * applicable), return value is amount of cargo actually moved. */ - uint Reserve(uint max_move, VehicleCargoList *dest, StationIDStack next); - uint Load(uint max_move, VehicleCargoList *dest, StationIDStack next); + uint Reserve(uint max_move, VehicleCargoList *dest, StationIDStack next, TileIndex location); + uint Load(uint max_move, VehicleCargoList *dest, StationIDStack next, TileIndex location); uint Truncate(uint max_move = UINT_MAX, StationCargoAmountMap *cargo_per_source = nullptr); uint Reroute(uint max_move, StationCargoList *dest, StationID avoid, StationID avoid2, const GoodsEntry *ge); @@ -533,7 +549,7 @@ public: */ static bool AreMergable(const CargoPacket *cp1, const CargoPacket *cp2) { - return cp1->source_xy == cp2->source_xy && + return cp1->movement == cp2->movement && cp1->periods_in_transit == cp2->periods_in_transit && cp1->source_type == cp2->source_type && cp1->source_id == cp2->source_id; diff --git a/src/economy.cpp b/src/economy.cpp index 1dce13e603..659a396538 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -1096,7 +1096,7 @@ static uint DeliverGoodsToIndustry(const Station *st, CargoID cargo_type, uint n * @param num_pieces amount of cargo delivered * @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 distance The distance cargo travelled * @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) @@ -1104,7 +1104,7 @@ static uint DeliverGoodsToIndustry(const Station *st, CargoID cargo_type, uint n * @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_t periods_in_transit, Company *company, SourceType src_type, SourceID src) +static Money DeliverGoods(int num_pieces, CargoID cargo_type, StationID dest, uint distance, uint16_t periods_in_transit, Company *company, SourceType src_type, SourceID src) { assert(num_pieces > 0); @@ -1131,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), periods_in_transit, cargo_type); + Money profit = GetTransportedGoodsIncome(accepted_total, distance, periods_in_transit, cargo_type); /* Update the cargo monitor. */ AddCargoDelivery(cargo_type, company->index, accepted_total - accepted_ind, src_type, src, st); @@ -1225,15 +1225,16 @@ CargoPayment::~CargoPayment() * Handle payment for final delivery of the given cargo packet. * @param cp The cargo packet to pay for. * @param count The number of packets to pay for. + * @param distance The distance cargo travelled. */ -void CargoPayment::PayFinalDelivery(const CargoPacket *cp, uint count) +void CargoPayment::PayFinalDelivery(const CargoPacket *cp, uint count, uint distance) { if (this->owner == nullptr) { this->owner = Company::Get(this->front->owner); } /* Handle end of route payment */ - Money profit = DeliverGoods(count, this->ct, this->current_station, cp->GetSourceXY(), cp->GetPeriodsInTransit(), this->owner, cp->GetSourceType(), cp->GetSourceID()); + Money profit = DeliverGoods(count, this->ct, this->current_station, distance, cp->GetPeriodsInTransit(), this->owner, cp->GetSourceType(), cp->GetSourceID()); this->route_profit += profit; /* The vehicle's profit is whatever route profit there is minus feeder shares. */ @@ -1244,15 +1245,16 @@ void CargoPayment::PayFinalDelivery(const CargoPacket *cp, uint count) * Handle payment for transfer of the given cargo packet. * @param cp The cargo packet to pay for; actual payment won't be made!. * @param count The number of packets to pay for. + * @param location TileIndex if the point packet is unloaded at. * @return The amount of money paid for the transfer. */ -Money CargoPayment::PayTransfer(const CargoPacket *cp, uint count) +Money CargoPayment::PayTransfer(const CargoPacket *cp, uint count, TileIndex location) { Money profit = -cp->GetFeederShare(count) + GetTransportedGoodsIncome( 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->GetSourceXY(), Station::Get(this->current_station)->xy), + DistanceManhattan(cp->GetMovement(), location), cp->GetPeriodsInTransit(), this->ct); @@ -1294,7 +1296,8 @@ void PrepareUnload(Vehicle *front_v) HasBit(ge->status, GoodsEntry::GES_ACCEPTANCE), front_v->last_station_visited, next_station, front_v->current_order.GetUnloadType(), ge, - front_v->cargo_payment); + front_v->cargo_payment, + v->tile); if (v->cargo.UnloadCount() > 0) SetBit(v->vehicle_flags, VF_CARGO_UNLOADING); } } @@ -1434,7 +1437,7 @@ struct ReturnCargoAction */ bool operator()(Vehicle *v) { - v->cargo.Return(UINT_MAX, &this->st->goods[v->cargo_type].cargo, this->next_hop); + v->cargo.Return(UINT_MAX, &this->st->goods[v->cargo_type].cargo, this->next_hop, v->tile); return true; } }; @@ -1469,7 +1472,7 @@ struct FinalizeRefitAction { if (this->do_reserve) { this->st->goods[v->cargo_type].cargo.Reserve(v->cargo_cap - v->cargo.RemainingCount(), - &v->cargo, this->next_station); + &v->cargo, this->next_station, v->tile); } this->consist_capleft[v->cargo_type] += v->cargo_cap - v->cargo.RemainingCount(); return true; @@ -1560,7 +1563,7 @@ struct ReserveCargoAction { { if (v->cargo_cap > v->cargo.RemainingCount() && MayLoadUnderExclusiveRights(st, v)) { st->goods[v->cargo_type].cargo.Reserve(v->cargo_cap - v->cargo.RemainingCount(), - &v->cargo, *next_station); + &v->cargo, *next_station, v->tile); } return true; @@ -1694,7 +1697,7 @@ static void LoadUnloadVehicle(Vehicle *front) uint new_remaining = v->cargo.RemainingCount() + v->cargo.ActionCount(VehicleCargoList::MTA_DELIVER); if (v->cargo_cap < new_remaining) { /* Return some of the reserved cargo to not overload the vehicle. */ - v->cargo.Return(new_remaining - v->cargo_cap, &ge->cargo, INVALID_STATION); + v->cargo.Return(new_remaining - v->cargo_cap, &ge->cargo, INVALID_STATION, v->tile); } /* Keep instead of delivering. This may lead to no cargo being unloaded, so ...*/ @@ -1721,7 +1724,7 @@ static void LoadUnloadVehicle(Vehicle *front) } } - amount_unloaded = v->cargo.Unload(amount_unloaded, &ge->cargo, payment); + amount_unloaded = v->cargo.Unload(amount_unloaded, &ge->cargo, payment, v->tile); remaining = v->cargo.UnloadCount() > 0; if (amount_unloaded > 0) { dirty_vehicle = true; @@ -1791,7 +1794,7 @@ static void LoadUnloadVehicle(Vehicle *front) if (v->cargo.StoredCount() == 0) TriggerVehicle(v, VEHICLE_TRIGGER_NEW_CARGO); if (_settings_game.order.gradual_loading) cap_left = std::min(cap_left, GetLoadAmount(v)); - uint loaded = ge->cargo.Load(cap_left, &v->cargo, next_station); + uint loaded = ge->cargo.Load(cap_left, &v->cargo, next_station, v->tile); if (v->cargo.ActionCount(VehicleCargoList::MTA_LOAD) > 0) { /* Remember if there are reservations left so that we don't stop * loading before they're loaded. */ diff --git a/src/economy_base.h b/src/economy_base.h index 5c9d79b8c8..4c658734af 100644 --- a/src/economy_base.h +++ b/src/economy_base.h @@ -37,8 +37,8 @@ struct CargoPayment : CargoPaymentPool::PoolItem<&_cargo_payment_pool> { CargoPayment(Vehicle *front); ~CargoPayment(); - Money PayTransfer(const CargoPacket *cp, uint count); - void PayFinalDelivery(const CargoPacket *cp, uint count); + Money PayTransfer(const CargoPacket *cp, uint count, TileIndex location); + void PayFinalDelivery(const CargoPacket *cp, uint count, uint distance); /** * Sets the currently handled cargo type. diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index b03ad503d4..2dca95f9ea 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -3241,6 +3241,24 @@ bool AfterLoadGame() } } + if (IsSavegameVersionBefore(SLV_UNPAID_TELEPORTATION)) { + /* Convert source location into a movement vector by calling TrackUnload. + * This emulates transportation by the vehicle from stored source location to the current station. + * Cargo packets in vehicles don't need conversion as movement vector is equivalent + * to the source location when in the vehicle. + */ + for (Station *st : Station::Iterate()) { + for (size_t i = 0; i < NUM_CARGO; i++) { + GoodsEntry *ge = &st->goods[i]; + for (auto it = ge->cargo.Packets()->begin(); it != ge->cargo.Packets()->end(); it++) { + for (CargoPacket *cp : it->second) { + cp->TrackUnload(cp->GetMovement()); + } + } + } + } + } + AfterLoadLabelMaps(); AfterLoadCompanyStats(); AfterLoadStoryBook(); diff --git a/src/saveload/cargopacket_sl.cpp b/src/saveload/cargopacket_sl.cpp index 0332b8a4b9..a3b93acb14 100644 --- a/src/saveload/cargopacket_sl.cpp +++ b/src/saveload/cargopacket_sl.cpp @@ -24,7 +24,7 @@ { if (IsSavegameVersionBefore(SLV_44)) { /* If we remove a station while cargo from it is still en route, payment calculation will assume - * 0, 0 to be the source of the cargo, resulting in very high payments usually. v->source_xy + * 0, 0 to be the source of the cargo, resulting in very high payments usually. v->source_position * stores the coordinates, preserving them even if the station is removed. However, if a game is loaded * where this situation exists, the cargo-source information is lost. in this case, we set the source * to the current tile of the vehicle to prevent excessive profits @@ -33,7 +33,7 @@ const CargoPacketList *packets = v->cargo.Packets(); for (VehicleCargoList::ConstIterator it(packets->begin()); it != packets->end(); it++) { CargoPacket *cp = *it; - cp->source_xy = Station::IsValidID(cp->first_station) ? Station::Get(cp->first_station)->xy : v->tile; + cp->movement = Station::IsValidID(cp->first_station) ? Station::Get(cp->first_station)->xy : v->tile; } } @@ -49,7 +49,7 @@ const StationCargoPacketMap *packets = ge->cargo.Packets(); for (StationCargoList::ConstIterator it(packets->begin()); it != packets->end(); it++) { CargoPacket *cp = *it; - cp->source_xy = Station::IsValidID(cp->first_station) ? Station::Get(cp->first_station)->xy : st->xy; + cp->movement = Station::IsValidID(cp->first_station) ? Station::Get(cp->first_station)->xy : st->xy; } } } @@ -87,7 +87,7 @@ SaveLoadTable GetCargoPacketDesc() { static const SaveLoad _cargopacket_desc[] = { SLE_VARNAME(CargoPacket, first_station, "source", SLE_UINT16), - SLE_VAR(CargoPacket, source_xy, SLE_UINT32), + SLE_VARNAME(CargoPacket, movement, "source_xy", SLE_UINT32), SLE_VAR(CargoPacket, count, SLE_UINT16), SLE_CONDVARNAME(CargoPacket, periods_in_transit, "days_in_transit", SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_MORE_CARGO_AGE), SLE_CONDVARNAME(CargoPacket, periods_in_transit, "days_in_transit", SLE_UINT16, SLV_MORE_CARGO_AGE, SLV_PERIODS_IN_TRANSIT_RENAME), diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h index 71e86aecea..8686db800b 100644 --- a/src/saveload/saveload.h +++ b/src/saveload/saveload.h @@ -360,6 +360,7 @@ enum SaveLoadVersion : uint16_t { SLV_PERIODS_IN_TRANSIT_RENAME, ///< 316 PR#11112 Rename days in transit to (cargo) periods in transit. SLV_NEWGRF_LAST_SERVICE, ///< 317 PR#11124 Added stable date_of_last_service to avoid NewGRF trouble. SLV_REMOVE_LOADED_AT_XY, ///< 318 PR#11276 Remove loaded_at_xy variable from CargoPacket. + SLV_UNPAID_TELEPORTATION, ///< 319 PR#11274 Don't pay for cargo movement outside of the vehicle (teleportation). SL_MAX_VERSION, ///< Highest possible saveload version }; diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 1d5a64d756..304ed78d01 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -4039,7 +4039,7 @@ static uint UpdateStationWaiting(Station *st, CargoID type, uint amount, SourceT if (amount == 0) return 0; StationID next = ge.GetVia(st->index); - ge.cargo.Append(new CargoPacket(st->index, st->xy, amount, source_type, source_id), next); + ge.cargo.Append(new CargoPacket(st->index, 0, amount, source_type, source_id), next); LinkGraph *lg = nullptr; if (ge.link_graph == INVALID_LINK_GRAPH) { if (LinkGraph::CanAllocateItem()) { diff --git a/src/vehicle.cpp b/src/vehicle.cpp index cd47fc9bdb..d2afb76aab 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -2241,7 +2241,7 @@ void Vehicle::CancelReservation(StationID next, Station *st) VehicleCargoList &cargo = v->cargo; if (cargo.ActionCount(VehicleCargoList::MTA_LOAD) > 0) { Debug(misc, 1, "cancelling cargo reservation"); - cargo.Return(UINT_MAX, &st->goods[v->cargo_type].cargo, next); + cargo.Return(UINT_MAX, &st->goods[v->cargo_type].cargo, next, v->tile); } cargo.KeepAll(); }