mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-12 10:30:28 +00:00
(svn r25434) -Fix: reroute cargo staged for unloading if a link breaks
This commit is contained in:
parent
57e5a95b6f
commit
3dd811e179
@ -192,7 +192,7 @@ bool CargoShift::operator()(CargoPacket *cp)
|
|||||||
* @param cp Packet to be rerouted.
|
* @param cp Packet to be rerouted.
|
||||||
* @return True if the packet was completely rerouted, false if part of it was.
|
* @return True if the packet was completely rerouted, false if part of it was.
|
||||||
*/
|
*/
|
||||||
bool CargoReroute::operator()(CargoPacket *cp)
|
bool StationCargoReroute::operator()(CargoPacket *cp)
|
||||||
{
|
{
|
||||||
CargoPacket *cp_new = this->Preprocess(cp);
|
CargoPacket *cp_new = this->Preprocess(cp);
|
||||||
if (cp_new == NULL) cp_new = cp;
|
if (cp_new == NULL) cp_new = cp;
|
||||||
@ -210,6 +210,29 @@ bool CargoReroute::operator()(CargoPacket *cp)
|
|||||||
return cp_new == cp;
|
return cp_new == cp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reroutes some cargo in a VehicleCargoList.
|
||||||
|
* @param cp Packet to be rerouted.
|
||||||
|
* @return True if the packet was completely rerouted, false if part of it was.
|
||||||
|
*/
|
||||||
|
bool VehicleCargoReroute::operator()(CargoPacket *cp)
|
||||||
|
{
|
||||||
|
CargoPacket *cp_new = this->Preprocess(cp);
|
||||||
|
if (cp_new == NULL) cp_new = cp;
|
||||||
|
if (cp_new->NextStation() == this->avoid || cp_new->NextStation() == this->avoid2) {
|
||||||
|
cp->SetNextStation(this->ge->GetVia(cp_new->SourceStation(), this->avoid, this->avoid2));
|
||||||
|
}
|
||||||
|
if (this->source != this->destination) {
|
||||||
|
this->source->RemoveFromMeta(cp_new, VehicleCargoList::MTA_TRANSFER, cp_new->Count());
|
||||||
|
this->source->AddToMeta(cp_new, VehicleCargoList::MTA_TRANSFER);
|
||||||
|
this->destination->action_counts[VehicleCargoList::MTA_TRANSFER] += cp_new->Count();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Legal, as front pushing doesn't invalidate iterators in std::list. */
|
||||||
|
this->destination->packets.push_front(cp_new);
|
||||||
|
return cp_new == cp;
|
||||||
|
}
|
||||||
|
|
||||||
template uint CargoRemoval<VehicleCargoList>::Preprocess(CargoPacket *cp);
|
template uint CargoRemoval<VehicleCargoList>::Preprocess(CargoPacket *cp);
|
||||||
template uint CargoRemoval<StationCargoList>::Preprocess(CargoPacket *cp);
|
template uint CargoRemoval<StationCargoList>::Preprocess(CargoPacket *cp);
|
||||||
template bool CargoRemoval<VehicleCargoList>::Postprocess(CargoPacket *cp, uint remove);
|
template bool CargoRemoval<VehicleCargoList>::Postprocess(CargoPacket *cp, uint remove);
|
||||||
|
@ -112,15 +112,34 @@ public:
|
|||||||
bool operator()(CargoPacket *cp);
|
bool operator()(CargoPacket *cp);
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Action of rerouting cargo between different station cargo lists and/or next hops. */
|
/** Action of rerouting cargo between different cargo lists and/or next hops. */
|
||||||
class CargoReroute : public CargoMovement<StationCargoList, StationCargoList> {
|
template<class Tlist>
|
||||||
|
class CargoReroute : public CargoMovement<Tlist, Tlist> {
|
||||||
protected:
|
protected:
|
||||||
StationID avoid;
|
StationID avoid;
|
||||||
StationID avoid2;
|
StationID avoid2;
|
||||||
const GoodsEntry *ge;
|
const GoodsEntry *ge;
|
||||||
public:
|
public:
|
||||||
CargoReroute(StationCargoList *source, StationCargoList *dest, uint max_move, StationID avoid, StationID avoid2, const GoodsEntry *ge) :
|
CargoReroute(Tlist *source, Tlist *dest, uint max_move, StationID avoid, StationID avoid2, const GoodsEntry *ge) :
|
||||||
CargoMovement<StationCargoList, StationCargoList>(source, dest, max_move), avoid(avoid), avoid2(avoid2), ge(ge) {}
|
CargoMovement<Tlist, Tlist>(source, dest, max_move), avoid(avoid), avoid2(avoid2), ge(ge) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Action of rerouting cargo in a station. */
|
||||||
|
class StationCargoReroute : public CargoReroute<StationCargoList> {
|
||||||
|
public:
|
||||||
|
StationCargoReroute(StationCargoList *source, StationCargoList *dest, uint max_move, StationID avoid, StationID avoid2, const GoodsEntry *ge) :
|
||||||
|
CargoReroute<StationCargoList>(source, dest, max_move, avoid, avoid2, ge) {}
|
||||||
|
bool operator()(CargoPacket *cp);
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Action of rerouting cargo staged for transfer in a vehicle. */
|
||||||
|
class VehicleCargoReroute : public CargoReroute<VehicleCargoList> {
|
||||||
|
public:
|
||||||
|
VehicleCargoReroute(VehicleCargoList *source, VehicleCargoList *dest, uint max_move, StationID avoid, StationID avoid2, const GoodsEntry *ge) :
|
||||||
|
CargoReroute<VehicleCargoList>(source, dest, max_move, avoid, avoid2, ge)
|
||||||
|
{
|
||||||
|
assert(this->max_move <= source->ActionCount(VehicleCargoList::MTA_TRANSFER));
|
||||||
|
}
|
||||||
bool operator()(CargoPacket *cp);
|
bool operator()(CargoPacket *cp);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -580,6 +580,21 @@ uint VehicleCargoList::Truncate(uint max_move)
|
|||||||
return max_move;
|
return max_move;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Routes packets with station "avoid" as next hop to a different place.
|
||||||
|
* @param max_move Maximum amount of cargo to move.
|
||||||
|
* @param dest List to prepend the cargo to.
|
||||||
|
* @param avoid Station to exclude from routing and current next hop of packets to reroute.
|
||||||
|
* @param avoid2 Additional station to exclude from routing.
|
||||||
|
* @oaram ge GoodsEntry to get the routing info from.
|
||||||
|
*/
|
||||||
|
uint VehicleCargoList::Reroute(uint max_move, VehicleCargoList *dest, StationID avoid, StationID avoid2, const GoodsEntry *ge)
|
||||||
|
{
|
||||||
|
max_move = min(this->action_counts[MTA_TRANSFER], max_move);
|
||||||
|
this->ShiftCargo(VehicleCargoReroute(this, dest, max_move, avoid, avoid2, ge));
|
||||||
|
return max_move;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* Station cargo list implementation.
|
* Station cargo list implementation.
|
||||||
@ -759,7 +774,7 @@ uint StationCargoList::Load(uint max_move, VehicleCargoList *dest, TileIndex loa
|
|||||||
*/
|
*/
|
||||||
uint StationCargoList::Reroute(uint max_move, StationCargoList *dest, StationID avoid, StationID avoid2, const GoodsEntry *ge)
|
uint StationCargoList::Reroute(uint max_move, StationCargoList *dest, StationID avoid, StationID avoid2, const GoodsEntry *ge)
|
||||||
{
|
{
|
||||||
return this->ShiftCargo(CargoReroute(this, dest, max_move, avoid, avoid2, ge), avoid, false);
|
return this->ShiftCargo(StationCargoReroute(this, dest, max_move, avoid, avoid2, ge), avoid, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -82,6 +82,12 @@ public:
|
|||||||
*/
|
*/
|
||||||
void SetLoadPlace(TileIndex load_place) { this->loaded_at_xy = load_place; }
|
void SetLoadPlace(TileIndex load_place) { this->loaded_at_xy = load_place; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the station where the packet is supposed to go next.
|
||||||
|
* @param next_station Next station the packet should go to.
|
||||||
|
*/
|
||||||
|
void SetNextStation(StationID next_station) { this->next_station = next_station; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds some feeder share to the packet.
|
* Adds some feeder share to the packet.
|
||||||
* @param new_share Feeder share to be added.
|
* @param new_share Feeder share to be added.
|
||||||
@ -319,6 +325,7 @@ public:
|
|||||||
template<class Tsource>
|
template<class Tsource>
|
||||||
friend class CargoRemoval;
|
friend class CargoRemoval;
|
||||||
friend class CargoReturn;
|
friend class CargoReturn;
|
||||||
|
friend class VehicleCargoReroute;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns source of the first cargo packet in this list.
|
* Returns source of the first cargo packet in this list.
|
||||||
@ -424,6 +431,7 @@ public:
|
|||||||
uint Unload(uint max_move, StationCargoList *dest, CargoPayment *payment);
|
uint Unload(uint max_move, StationCargoList *dest, CargoPayment *payment);
|
||||||
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);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Are two the two CargoPackets mergeable in the context of
|
* Are two the two CargoPackets mergeable in the context of
|
||||||
@ -467,7 +475,7 @@ public:
|
|||||||
friend class CargoRemoval;
|
friend class CargoRemoval;
|
||||||
friend class CargoReservation;
|
friend class CargoReservation;
|
||||||
friend class CargoReturn;
|
friend class CargoReturn;
|
||||||
friend class CargoReroute;
|
friend class StationCargoReroute;
|
||||||
|
|
||||||
static void InvalidateAllFrom(SourceType src_type, SourceID src);
|
static void InvalidateAllFrom(SourceType src_type, SourceID src);
|
||||||
|
|
||||||
|
@ -3402,7 +3402,17 @@ void DeleteStaleLinks(Station *from)
|
|||||||
(DistanceManhattan(from->xy, to->xy) >> 2)) {
|
(DistanceManhattan(from->xy, to->xy) >> 2)) {
|
||||||
node.RemoveEdge(to->goods[c].node);
|
node.RemoveEdge(to->goods[c].node);
|
||||||
ge.flows.DeleteFlows(to->index);
|
ge.flows.DeleteFlows(to->index);
|
||||||
|
|
||||||
|
/* Reroute cargo in station. */
|
||||||
ge.cargo.Reroute(UINT_MAX, &ge.cargo, to->index, from->index, &ge);
|
ge.cargo.Reroute(UINT_MAX, &ge.cargo, to->index, from->index, &ge);
|
||||||
|
|
||||||
|
/* Reroute cargo staged to be transfered. */
|
||||||
|
for (std::list<Vehicle *>::iterator it(from->loading_vehicles.begin()); it != from->loading_vehicles.end(); ++it) {
|
||||||
|
for (Vehicle *v = *it; v != NULL; v = v->Next()) {
|
||||||
|
if (v->cargo_type != c) continue;
|
||||||
|
v->cargo.Reroute(UINT_MAX, &v->cargo, to->index, from->index, &ge);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert(_date >= lg->LastCompression());
|
assert(_date >= lg->LastCompression());
|
||||||
|
Loading…
Reference in New Issue
Block a user