mirror of https://github.com/OpenTTD/OpenTTD
Fix: Cargo payment can no longer be exploited by "teleportation".
parent
30172fc037
commit
a88d9af15c
|
@ -107,7 +107,7 @@ bool CargoDelivery::operator()(CargoPacket *cp)
|
||||||
{
|
{
|
||||||
uint remove = this->Preprocess(cp);
|
uint remove = this->Preprocess(cp);
|
||||||
this->source->RemoveFromMeta(cp, VehicleCargoList::MTA_DELIVER, remove);
|
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);
|
return this->Postprocess(cp, remove);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,6 +120,7 @@ bool CargoLoad::operator()(CargoPacket *cp)
|
||||||
{
|
{
|
||||||
CargoPacket *cp_new = this->Preprocess(cp);
|
CargoPacket *cp_new = this->Preprocess(cp);
|
||||||
if (cp_new == nullptr) return false;
|
if (cp_new == nullptr) return false;
|
||||||
|
cp_new->TrackLoad(this->location);
|
||||||
this->source->RemoveFromCache(cp_new, cp_new->Count());
|
this->source->RemoveFromCache(cp_new, cp_new->Count());
|
||||||
this->destination->Append(cp_new, VehicleCargoList::MTA_KEEP);
|
this->destination->Append(cp_new, VehicleCargoList::MTA_KEEP);
|
||||||
return cp_new == cp;
|
return cp_new == cp;
|
||||||
|
@ -134,6 +135,7 @@ bool CargoReservation::operator()(CargoPacket *cp)
|
||||||
{
|
{
|
||||||
CargoPacket *cp_new = this->Preprocess(cp);
|
CargoPacket *cp_new = this->Preprocess(cp);
|
||||||
if (cp_new == nullptr) return false;
|
if (cp_new == nullptr) return false;
|
||||||
|
cp_new->TrackLoad(this->location);
|
||||||
this->source->reserved_count += cp_new->Count();
|
this->source->reserved_count += cp_new->Count();
|
||||||
this->source->RemoveFromCache(cp_new, cp_new->Count());
|
this->source->RemoveFromCache(cp_new, cp_new->Count());
|
||||||
this->destination->Append(cp_new, VehicleCargoList::MTA_LOAD);
|
this->destination->Append(cp_new, VehicleCargoList::MTA_LOAD);
|
||||||
|
@ -150,6 +152,7 @@ bool CargoReturn::operator()(CargoPacket *cp)
|
||||||
CargoPacket *cp_new = this->Preprocess(cp);
|
CargoPacket *cp_new = this->Preprocess(cp);
|
||||||
if (cp_new == nullptr) cp_new = cp;
|
if (cp_new == nullptr) cp_new = cp;
|
||||||
assert(cp_new->Count() <= this->destination->reserved_count);
|
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->source->RemoveFromMeta(cp_new, VehicleCargoList::MTA_LOAD, cp_new->Count());
|
||||||
this->destination->reserved_count -= cp_new->Count();
|
this->destination->reserved_count -= cp_new->Count();
|
||||||
this->destination->Append(cp_new, this->next);
|
this->destination->Append(cp_new, this->next);
|
||||||
|
@ -165,6 +168,7 @@ bool CargoTransfer::operator()(CargoPacket *cp)
|
||||||
{
|
{
|
||||||
CargoPacket *cp_new = this->Preprocess(cp);
|
CargoPacket *cp_new = this->Preprocess(cp);
|
||||||
if (cp_new == nullptr) return false;
|
if (cp_new == nullptr) return false;
|
||||||
|
cp_new->TrackUnload(this->location);
|
||||||
this->source->RemoveFromMeta(cp_new, VehicleCargoList::MTA_TRANSFER, cp_new->Count());
|
this->source->RemoveFromMeta(cp_new, VehicleCargoList::MTA_TRANSFER, cp_new->Count());
|
||||||
/* No transfer credits here as they were already granted during Stage(). */
|
/* No transfer credits here as they were already granted during Stage(). */
|
||||||
this->destination->Append(cp_new, cp_new->GetNextStation());
|
this->destination->Append(cp_new, cp_new->GetNextStation());
|
||||||
|
|
|
@ -39,9 +39,10 @@ public:
|
||||||
class CargoDelivery : public CargoRemoval<VehicleCargoList> {
|
class CargoDelivery : public CargoRemoval<VehicleCargoList> {
|
||||||
protected:
|
protected:
|
||||||
CargoPayment *payment; ///< Payment object where payments will be registered.
|
CargoPayment *payment; ///< Payment object where payments will be registered.
|
||||||
|
TileIndex location;
|
||||||
public:
|
public:
|
||||||
CargoDelivery(VehicleCargoList *source, uint max_move, CargoPayment *payment) :
|
CargoDelivery(VehicleCargoList *source, uint max_move, CargoPayment *payment, TileIndex location) :
|
||||||
CargoRemoval<VehicleCargoList>(source, max_move), payment(payment) {}
|
CargoRemoval<VehicleCargoList>(source, max_move), payment(payment), location(location) {}
|
||||||
bool operator()(CargoPacket *cp);
|
bool operator()(CargoPacket *cp);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -69,33 +70,39 @@ public:
|
||||||
|
|
||||||
/** Action of transferring cargo from a vehicle to a station. */
|
/** Action of transferring cargo from a vehicle to a station. */
|
||||||
class CargoTransfer : public CargoMovement<VehicleCargoList, StationCargoList> {
|
class CargoTransfer : public CargoMovement<VehicleCargoList, StationCargoList> {
|
||||||
|
protected:
|
||||||
|
TileIndex location;
|
||||||
public:
|
public:
|
||||||
CargoTransfer(VehicleCargoList *source, StationCargoList *destination, uint max_move) :
|
CargoTransfer(VehicleCargoList *source, StationCargoList *destination, uint max_move, TileIndex location) :
|
||||||
CargoMovement<VehicleCargoList, StationCargoList>(source, destination, max_move) {}
|
CargoMovement<VehicleCargoList, StationCargoList>(source, destination, max_move), location(location) {}
|
||||||
bool operator()(CargoPacket *cp);
|
bool operator()(CargoPacket *cp);
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Action of loading cargo from a station onto a vehicle. */
|
/** Action of loading cargo from a station onto a vehicle. */
|
||||||
class CargoLoad : public CargoMovement<StationCargoList, VehicleCargoList> {
|
class CargoLoad : public CargoMovement<StationCargoList, VehicleCargoList> {
|
||||||
|
protected:
|
||||||
|
TileIndex location;
|
||||||
public:
|
public:
|
||||||
CargoLoad(StationCargoList *source, VehicleCargoList *destination, uint max_move) :
|
CargoLoad(StationCargoList *source, VehicleCargoList *destination, uint max_move, TileIndex location) :
|
||||||
CargoMovement<StationCargoList, VehicleCargoList>(source, destination, max_move) {}
|
CargoMovement<StationCargoList, VehicleCargoList>(source, destination, max_move), location(location) {}
|
||||||
bool operator()(CargoPacket *cp);
|
bool operator()(CargoPacket *cp);
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Action of reserving cargo from a station to be loaded onto a vehicle. */
|
/** Action of reserving cargo from a station to be loaded onto a vehicle. */
|
||||||
class CargoReservation : public CargoLoad {
|
class CargoReservation : public CargoLoad {
|
||||||
public:
|
public:
|
||||||
CargoReservation(StationCargoList *source, VehicleCargoList *destination, uint max_move) :
|
CargoReservation(StationCargoList *source, VehicleCargoList *destination, uint max_move, TileIndex location) :
|
||||||
CargoLoad(source, destination, max_move) {}
|
CargoLoad(source, destination, max_move, location) {}
|
||||||
bool operator()(CargoPacket *cp);
|
bool operator()(CargoPacket *cp);
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Action of returning previously reserved cargo from the vehicle to the station. */
|
/** Action of returning previously reserved cargo from the vehicle to the station. */
|
||||||
class CargoReturn : public CargoMovement<VehicleCargoList, StationCargoList> {
|
class CargoReturn : public CargoMovement<VehicleCargoList, StationCargoList> {
|
||||||
|
protected:
|
||||||
|
TileIndex location;
|
||||||
StationID next;
|
StationID next;
|
||||||
public:
|
public:
|
||||||
CargoReturn(VehicleCargoList *source, StationCargoList *destination, uint max_move, StationID next) :
|
CargoReturn(VehicleCargoList *source, StationCargoList *destination, uint max_move, StationID next, TileIndex location) :
|
||||||
CargoMovement<VehicleCargoList, StationCargoList>(source, destination, max_move), next(next) {}
|
CargoMovement<VehicleCargoList, StationCargoList>(source, destination, max_move), next(next) {}
|
||||||
bool operator()(CargoPacket *cp);
|
bool operator()(CargoPacket *cp);
|
||||||
};
|
};
|
||||||
|
|
|
@ -33,7 +33,7 @@ CargoPacket::CargoPacket()
|
||||||
/**
|
/**
|
||||||
* Creates a new cargo packet.
|
* Creates a new cargo packet.
|
||||||
* @param first_station Source station of the 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 count Number of cargo entities to put in this packet.
|
||||||
* @param source_type 'Type' of source the packet comes from (for subsidies).
|
* @param source_type 'Type' of source the packet comes from (for subsidies).
|
||||||
* @param source_id Actual source of the packet (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'
|
* @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.
|
* 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),
|
count(count),
|
||||||
source_xy(source_xy),
|
movement(movement),
|
||||||
source_id(source_id),
|
source_id(source_id),
|
||||||
source_type(source_type),
|
source_type(source_type),
|
||||||
first_station(first_station)
|
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 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 periods_in_transit Number of cargo aging periods the cargo has been in transit.
|
||||||
* @param first_station Station the cargo was initially loaded.
|
* @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 feeder_share Feeder share the packet has already accumulated.
|
||||||
* @param source_type 'Type' of source the packet comes from (for subsidies).
|
* @param source_type 'Type' of source the packet comes from (for subsidies).
|
||||||
* @param source_id Actual source of the packet (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'
|
* @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.
|
* 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),
|
count(count),
|
||||||
periods_in_transit(periods_in_transit),
|
periods_in_transit(periods_in_transit),
|
||||||
feeder_share(feeder_share),
|
feeder_share(feeder_share),
|
||||||
source_xy(source_xy),
|
movement(movement),
|
||||||
source_id(source_id),
|
source_id(source_id),
|
||||||
source_type(source_type),
|
source_type(source_type),
|
||||||
first_station(first_station)
|
first_station(first_station)
|
||||||
|
@ -86,7 +86,7 @@ CargoPacket *CargoPacket::Split(uint new_size)
|
||||||
if (!CargoPacket::CanAllocateItem()) return nullptr;
|
if (!CargoPacket::CanAllocateItem()) return nullptr;
|
||||||
|
|
||||||
Money fs = this->GetFeederShare(new_size);
|
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->feeder_share -= fs;
|
||||||
this->count -= new_size;
|
this->count -= new_size;
|
||||||
return cp_new;
|
return cp_new;
|
||||||
|
@ -418,9 +418,10 @@ void VehicleCargoList::AgeCargo()
|
||||||
* @param order_flags OrderUnloadFlags that will apply to the unload operation.
|
* @param order_flags OrderUnloadFlags that will apply to the unload operation.
|
||||||
* @param ge GoodsEntry for getting the flows.
|
* @param ge GoodsEntry for getting the flows.
|
||||||
* @param payment Payment object for registering transfers.
|
* @param payment Payment object for registering transfers.
|
||||||
|
* @param location TileIndex if the point cargo is unloaded at.
|
||||||
* return If any cargo will be unloaded.
|
* 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();
|
this->AssertCountConsistency();
|
||||||
assert(this->action_counts[MTA_LOAD] == 0);
|
assert(this->action_counts[MTA_LOAD] == 0);
|
||||||
|
@ -496,7 +497,7 @@ bool VehicleCargoList::Stage(bool accepted, StationID current_station, StationID
|
||||||
case MTA_TRANSFER:
|
case MTA_TRANSFER:
|
||||||
this->packets.push_front(cp);
|
this->packets.push_front(cp);
|
||||||
/* Add feeder share here to allow reusing field for next station. */
|
/* 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);
|
cp->AddFeederShare(share);
|
||||||
this->feeder_share += share;
|
this->feeder_share += share;
|
||||||
cp->next_station = cargo_next;
|
cp->next_station = cargo_next;
|
||||||
|
@ -578,10 +579,10 @@ uint VehicleCargoList::Reassign<VehicleCargoList::MTA_DELIVER, VehicleCargoList:
|
||||||
* @param next ID of the next station the cargo wants to go to.
|
* @param next ID of the next station the cargo wants to go to.
|
||||||
* @return Amount of cargo actually returned.
|
* @return Amount of cargo actually returned.
|
||||||
*/
|
*/
|
||||||
uint VehicleCargoList::Return(uint max_move, StationCargoList *dest, StationID next)
|
uint VehicleCargoList::Return(uint max_move, StationCargoList *dest, StationID next, TileIndex location)
|
||||||
{
|
{
|
||||||
max_move = std::min(this->action_counts[MTA_LOAD], max_move);
|
max_move = std::min(this->action_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;
|
return max_move;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -606,17 +607,17 @@ uint VehicleCargoList::Shift(uint max_move, VehicleCargoList *dest)
|
||||||
* @param payment Payment object to register payments in.
|
* @param payment Payment object to register payments in.
|
||||||
* @return Amount of cargo actually unloaded.
|
* @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;
|
uint moved = 0;
|
||||||
if (this->action_counts[MTA_TRANSFER] > 0) {
|
if (this->action_counts[MTA_TRANSFER] > 0) {
|
||||||
uint move = std::min(this->action_counts[MTA_TRANSFER], max_move);
|
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;
|
moved += move;
|
||||||
}
|
}
|
||||||
if (this->action_counts[MTA_TRANSFER] == 0 && this->action_counts[MTA_DELIVER] > 0 && moved < max_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);
|
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;
|
moved += move;
|
||||||
}
|
}
|
||||||
return moved;
|
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 max_move Maximum amount of cargo to reserve.
|
||||||
* @param dest VehicleCargoList to reserve for.
|
* @param dest VehicleCargoList to reserve for.
|
||||||
* @param next_station Next station(s) the loading vehicle will visit.
|
* @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.
|
* @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 max_move Amount of cargo to load.
|
||||||
* @param dest Vehicle cargo list where the cargo resides.
|
* @param dest Vehicle cargo list where the cargo resides.
|
||||||
* @param next_station Next station(s) the loading vehicle will visit.
|
* @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.
|
* @return Amount of cargo actually loaded.
|
||||||
* @note Vehicles may or may not reserve, depending on their orders. The two
|
* @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
|
* modes of loading are exclusive, though. If cargo is reserved we don't
|
||||||
* need to load unreserved cargo.
|
* 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);
|
uint move = std::min(dest->ActionCount(VehicleCargoList::MTA_LOAD), max_move);
|
||||||
if (move > 0) {
|
if (move > 0) {
|
||||||
|
@ -820,7 +823,7 @@ uint StationCargoList::Load(uint max_move, VehicleCargoList *dest, StationIDStac
|
||||||
dest->Reassign<VehicleCargoList::MTA_LOAD, VehicleCargoList::MTA_KEEP>(move);
|
dest->Reassign<VehicleCargoList::MTA_LOAD, VehicleCargoList::MTA_KEEP>(move);
|
||||||
return move;
|
return move;
|
||||||
} else {
|
} else {
|
||||||
return this->ShiftCargo(CargoLoad(this, dest, max_move), next_station, true);
|
return this->ShiftCargo(CargoLoad(this, dest, max_move, location), next_station, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ private:
|
||||||
|
|
||||||
Money feeder_share{0}; ///< Value of feeder pickup to be paid for on delivery of cargo.
|
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.
|
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.
|
SourceType source_type{SourceType::Industry}; ///< Type of \c source_id.
|
||||||
|
|
||||||
|
@ -62,8 +62,8 @@ public:
|
||||||
static const uint16_t MAX_COUNT = UINT16_MAX;
|
static const uint16_t MAX_COUNT = UINT16_MAX;
|
||||||
|
|
||||||
CargoPacket();
|
CargoPacket();
|
||||||
CargoPacket(StationID first_station, TileIndex source_xy, uint16_t count, SourceType source_type, SourceID source_id);
|
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_xy, Money feeder_share = 0, SourceType source_type = SourceType::Industry, SourceID source_id = INVALID_SOURCE);
|
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. */
|
/** Destroy the packet. */
|
||||||
~CargoPacket() { }
|
~CargoPacket() { }
|
||||||
|
@ -72,6 +72,22 @@ public:
|
||||||
void Merge(CargoPacket *cp);
|
void Merge(CargoPacket *cp);
|
||||||
void Reduce(uint count);
|
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.
|
* Sets the station where the packet is supposed to go next.
|
||||||
* @param next_station Next station the packet should go to.
|
* @param next_station Next station the packet should go to.
|
||||||
|
@ -160,12 +176,12 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the coordinates of the cargo's source.
|
* Gets the accumulated cargo movement vector.
|
||||||
* @return Source coordinates of cargo.
|
* @return TileIndexDiff.
|
||||||
*/
|
*/
|
||||||
inline TileIndex GetSourceXY() const
|
inline TileIndex GetMovement() const
|
||||||
{
|
{
|
||||||
return this->source_xy;
|
return this->movement;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -385,7 +401,7 @@ public:
|
||||||
|
|
||||||
void InvalidateCache();
|
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
|
* Marks all cargo in the vehicle as to be kept. This is mostly useful for
|
||||||
|
@ -404,8 +420,8 @@ public:
|
||||||
|
|
||||||
template<MoveToAction Tfrom, MoveToAction Tto>
|
template<MoveToAction Tfrom, MoveToAction Tto>
|
||||||
uint Reassign(uint max_move, StationID update = INVALID_STATION);
|
uint Reassign(uint max_move, StationID update = INVALID_STATION);
|
||||||
uint Return(uint max_move, StationCargoList *dest, StationID next_station);
|
uint Return(uint max_move, StationCargoList *dest, StationID next_station, TileIndex location);
|
||||||
uint Unload(uint max_move, StationCargoList *dest, CargoPayment *payment);
|
uint Unload(uint max_move, StationCargoList *dest, CargoPayment *payment, TileIndex location);
|
||||||
uint Shift(uint max_move, VehicleCargoList *dest);
|
uint Shift(uint max_move, VehicleCargoList *dest);
|
||||||
uint Truncate(uint max_move = UINT_MAX);
|
uint Truncate(uint max_move = UINT_MAX);
|
||||||
uint Reroute(uint max_move, VehicleCargoList *dest, StationID avoid, StationID avoid2, const GoodsEntry *ge);
|
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)
|
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->periods_in_transit == cp2->periods_in_transit &&
|
||||||
cp1->source_type == cp2->source_type &&
|
cp1->source_type == cp2->source_type &&
|
||||||
cp1->source_id == cp2->source_id;
|
cp1->source_id == cp2->source_id;
|
||||||
|
@ -519,8 +535,8 @@ public:
|
||||||
* amount of cargo to be moved. Second parameter is destination (if
|
* amount of cargo to be moved. Second parameter is destination (if
|
||||||
* applicable), return value is amount of cargo actually moved. */
|
* applicable), return value is amount of cargo actually moved. */
|
||||||
|
|
||||||
uint Reserve(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);
|
uint Load(uint max_move, VehicleCargoList *dest, StationIDStack next, TileIndex location);
|
||||||
uint Truncate(uint max_move = UINT_MAX, StationCargoAmountMap *cargo_per_source = nullptr);
|
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);
|
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)
|
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->periods_in_transit == cp2->periods_in_transit &&
|
||||||
cp1->source_type == cp2->source_type &&
|
cp1->source_type == cp2->source_type &&
|
||||||
cp1->source_id == cp2->source_id;
|
cp1->source_id == cp2->source_id;
|
||||||
|
|
|
@ -1096,7 +1096,7 @@ static uint DeliverGoodsToIndustry(const Station *st, CargoID cargo_type, uint n
|
||||||
* @param num_pieces amount of cargo delivered
|
* @param num_pieces amount of cargo delivered
|
||||||
* @param cargo_type the type of cargo that is delivered
|
* @param cargo_type the type of cargo that is delivered
|
||||||
* @param dest Station the cargo has been unloaded
|
* @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 periods_in_transit Travel time in cargo aging periods
|
||||||
* @param company The company delivering the cargo
|
* @param company The company delivering the cargo
|
||||||
* @param src_type Type of source of cargo (industry, town, headquarters)
|
* @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
|
* @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
|
* @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);
|
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;
|
st->town->received[cs->town_effect].new_act += accepted_total;
|
||||||
|
|
||||||
/* Determine profit */
|
/* 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. */
|
/* Update the cargo monitor. */
|
||||||
AddCargoDelivery(cargo_type, company->index, accepted_total - accepted_ind, src_type, src, st);
|
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.
|
* Handle payment for final delivery of the given cargo packet.
|
||||||
* @param cp The cargo packet to pay for.
|
* @param cp The cargo packet to pay for.
|
||||||
* @param count The number of packets 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) {
|
if (this->owner == nullptr) {
|
||||||
this->owner = Company::Get(this->front->owner);
|
this->owner = Company::Get(this->front->owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle end of route payment */
|
/* 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;
|
this->route_profit += profit;
|
||||||
|
|
||||||
/* The vehicle's profit is whatever route profit there is minus feeder shares. */
|
/* 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.
|
* Handle payment for transfer of the given cargo packet.
|
||||||
* @param cp The cargo packet to pay for; actual payment won't be made!.
|
* @param cp The cargo packet to pay for; actual payment won't be made!.
|
||||||
* @param count The number of packets to pay for.
|
* @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.
|
* @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(
|
Money profit = -cp->GetFeederShare(count) + GetTransportedGoodsIncome(
|
||||||
count,
|
count,
|
||||||
/* pay transfer vehicle the difference between the payment for the journey from
|
/* 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 */
|
* 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(),
|
cp->GetPeriodsInTransit(),
|
||||||
this->ct);
|
this->ct);
|
||||||
|
|
||||||
|
@ -1294,7 +1296,8 @@ void PrepareUnload(Vehicle *front_v)
|
||||||
HasBit(ge->status, GoodsEntry::GES_ACCEPTANCE),
|
HasBit(ge->status, GoodsEntry::GES_ACCEPTANCE),
|
||||||
front_v->last_station_visited, next_station,
|
front_v->last_station_visited, next_station,
|
||||||
front_v->current_order.GetUnloadType(), ge,
|
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);
|
if (v->cargo.UnloadCount() > 0) SetBit(v->vehicle_flags, VF_CARGO_UNLOADING);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1434,7 +1437,7 @@ struct ReturnCargoAction
|
||||||
*/
|
*/
|
||||||
bool operator()(Vehicle *v)
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1469,7 +1472,7 @@ struct FinalizeRefitAction
|
||||||
{
|
{
|
||||||
if (this->do_reserve) {
|
if (this->do_reserve) {
|
||||||
this->st->goods[v->cargo_type].cargo.Reserve(v->cargo_cap - v->cargo.RemainingCount(),
|
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();
|
this->consist_capleft[v->cargo_type] += v->cargo_cap - v->cargo.RemainingCount();
|
||||||
return true;
|
return true;
|
||||||
|
@ -1560,7 +1563,7 @@ struct ReserveCargoAction {
|
||||||
{
|
{
|
||||||
if (v->cargo_cap > v->cargo.RemainingCount() && MayLoadUnderExclusiveRights(st, v)) {
|
if (v->cargo_cap > v->cargo.RemainingCount() && MayLoadUnderExclusiveRights(st, v)) {
|
||||||
st->goods[v->cargo_type].cargo.Reserve(v->cargo_cap - v->cargo.RemainingCount(),
|
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;
|
return true;
|
||||||
|
@ -1694,7 +1697,7 @@ static void LoadUnloadVehicle(Vehicle *front)
|
||||||
uint new_remaining = v->cargo.RemainingCount() + v->cargo.ActionCount(VehicleCargoList::MTA_DELIVER);
|
uint new_remaining = v->cargo.RemainingCount() + v->cargo.ActionCount(VehicleCargoList::MTA_DELIVER);
|
||||||
if (v->cargo_cap < new_remaining) {
|
if (v->cargo_cap < new_remaining) {
|
||||||
/* Return some of the reserved cargo to not overload the vehicle. */
|
/* 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 ...*/
|
/* 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;
|
remaining = v->cargo.UnloadCount() > 0;
|
||||||
if (amount_unloaded > 0) {
|
if (amount_unloaded > 0) {
|
||||||
dirty_vehicle = true;
|
dirty_vehicle = true;
|
||||||
|
@ -1791,7 +1794,7 @@ static void LoadUnloadVehicle(Vehicle *front)
|
||||||
if (v->cargo.StoredCount() == 0) TriggerVehicle(v, VEHICLE_TRIGGER_NEW_CARGO);
|
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));
|
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) {
|
if (v->cargo.ActionCount(VehicleCargoList::MTA_LOAD) > 0) {
|
||||||
/* Remember if there are reservations left so that we don't stop
|
/* Remember if there are reservations left so that we don't stop
|
||||||
* loading before they're loaded. */
|
* loading before they're loaded. */
|
||||||
|
|
|
@ -37,8 +37,8 @@ struct CargoPayment : CargoPaymentPool::PoolItem<&_cargo_payment_pool> {
|
||||||
CargoPayment(Vehicle *front);
|
CargoPayment(Vehicle *front);
|
||||||
~CargoPayment();
|
~CargoPayment();
|
||||||
|
|
||||||
Money PayTransfer(const CargoPacket *cp, uint count);
|
Money PayTransfer(const CargoPacket *cp, uint count, TileIndex location);
|
||||||
void PayFinalDelivery(const CargoPacket *cp, uint count);
|
void PayFinalDelivery(const CargoPacket *cp, uint count, uint distance);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the currently handled cargo type.
|
* Sets the currently handled cargo type.
|
||||||
|
|
|
@ -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();
|
AfterLoadLabelMaps();
|
||||||
AfterLoadCompanyStats();
|
AfterLoadCompanyStats();
|
||||||
AfterLoadStoryBook();
|
AfterLoadStoryBook();
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
{
|
{
|
||||||
if (IsSavegameVersionBefore(SLV_44)) {
|
if (IsSavegameVersionBefore(SLV_44)) {
|
||||||
/* If we remove a station while cargo from it is still en route, payment calculation will assume
|
/* 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
|
* 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
|
* 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
|
* to the current tile of the vehicle to prevent excessive profits
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
const CargoPacketList *packets = v->cargo.Packets();
|
const CargoPacketList *packets = v->cargo.Packets();
|
||||||
for (VehicleCargoList::ConstIterator it(packets->begin()); it != packets->end(); it++) {
|
for (VehicleCargoList::ConstIterator it(packets->begin()); it != packets->end(); it++) {
|
||||||
CargoPacket *cp = *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();
|
const StationCargoPacketMap *packets = ge->cargo.Packets();
|
||||||
for (StationCargoList::ConstIterator it(packets->begin()); it != packets->end(); it++) {
|
for (StationCargoList::ConstIterator it(packets->begin()); it != packets->end(); it++) {
|
||||||
CargoPacket *cp = *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[] = {
|
static const SaveLoad _cargopacket_desc[] = {
|
||||||
SLE_VARNAME(CargoPacket, first_station, "source", SLE_UINT16),
|
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_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_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),
|
SLE_CONDVARNAME(CargoPacket, periods_in_transit, "days_in_transit", SLE_UINT16, SLV_MORE_CARGO_AGE, SLV_PERIODS_IN_TRANSIT_RENAME),
|
||||||
|
|
|
@ -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_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_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_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
|
SL_MAX_VERSION, ///< Highest possible saveload version
|
||||||
};
|
};
|
||||||
|
|
|
@ -4039,7 +4039,7 @@ static uint UpdateStationWaiting(Station *st, CargoID type, uint amount, SourceT
|
||||||
if (amount == 0) return 0;
|
if (amount == 0) return 0;
|
||||||
|
|
||||||
StationID next = ge.GetVia(st->index);
|
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;
|
LinkGraph *lg = nullptr;
|
||||||
if (ge.link_graph == INVALID_LINK_GRAPH) {
|
if (ge.link_graph == INVALID_LINK_GRAPH) {
|
||||||
if (LinkGraph::CanAllocateItem()) {
|
if (LinkGraph::CanAllocateItem()) {
|
||||||
|
|
|
@ -2241,7 +2241,7 @@ void Vehicle::CancelReservation(StationID next, Station *st)
|
||||||
VehicleCargoList &cargo = v->cargo;
|
VehicleCargoList &cargo = v->cargo;
|
||||||
if (cargo.ActionCount(VehicleCargoList::MTA_LOAD) > 0) {
|
if (cargo.ActionCount(VehicleCargoList::MTA_LOAD) > 0) {
|
||||||
Debug(misc, 1, "cancelling cargo reservation");
|
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();
|
cargo.KeepAll();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue