summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfonsinchen <fonsinchen@openttd.org>2013-06-23 08:29:28 +0000
committerfonsinchen <fonsinchen@openttd.org>2013-06-23 08:29:28 +0000
commit930c19dae292d5863b201ded98444c9fb2e7b20a (patch)
tree952bc05730d25b4aa32622d07b75aba7f9a28b7b
parent3dd811e1794bc9247d5ace0bad7ade5998a7b54f (diff)
downloadopenttd-930c19dae292d5863b201ded98444c9fb2e7b20a.tar.xz
(svn r25435) -Fix: reroute cargo in vehicles if station is deleted
-rw-r--r--src/station.cpp21
-rw-r--r--src/station_cmd.cpp36
-rw-r--r--src/station_func.h1
3 files changed, 37 insertions, 21 deletions
diff --git a/src/station.cpp b/src/station.cpp
index 555c6369c..00c6a6d2a 100644
--- a/src/station.cpp
+++ b/src/station.cpp
@@ -92,18 +92,19 @@ Station::~Station()
for (CargoID c = 0; c < NUM_CARGO; ++c) {
LinkGraph *lg = LinkGraph::GetIfValid(this->goods[c].link_graph);
- if (lg != NULL) {
- lg->RemoveNode(this->goods[c].node);
- if (lg->Size() == 0) {
- LinkGraphSchedule::Instance()->Unqueue(lg);
- delete lg;
+ if (lg == NULL) continue;
+
+ for (NodeID node = 0; node < lg->Size(); ++node) {
+ if ((*lg)[node][this->goods[c].node].LastUpdate() != INVALID_DATE) {
+ Station *st = Station::Get((*lg)[node].Station());
+ st->goods[c].flows.DeleteFlows(this->index);
+ RerouteCargo(st, c, this->index, st->index);
}
}
- Station *st;
- FOR_ALL_STATIONS(st) {
- GoodsEntry *ge = &st->goods[c];
- ge->flows.DeleteFlows(this->index);
- ge->cargo.Reroute(UINT_MAX, &ge->cargo, this->index, st->index, ge);
+ lg->RemoveNode(this->goods[c].node);
+ if (lg->Size() == 0) {
+ LinkGraphSchedule::Instance()->Unqueue(lg);
+ delete lg;
}
}
diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp
index 2335d8151..75c473e22 100644
--- a/src/station_cmd.cpp
+++ b/src/station_cmd.cpp
@@ -3378,6 +3378,30 @@ static void UpdateStationRating(Station *st)
}
/**
+ * Reroute cargo of type c at station st or in any vehicles unloading there.
+ * Make sure the cargo's new next hop is neither "avoid" nor "avoid2".
+ * @param st Station to be rerouted at.
+ * @param c Type of cargo.
+ * @param avoid Original next hop of cargo, avoid this.
+ * @param avoid2 Another station to be avoided when rerouting.
+ */
+void RerouteCargo(Station *st, CargoID c, StationID avoid, StationID avoid2)
+{
+ GoodsEntry &ge = st->goods[c];
+
+ /* Reroute cargo in station. */
+ ge.cargo.Reroute(UINT_MAX, &ge.cargo, avoid, avoid2, &ge);
+
+ /* Reroute cargo staged to be transfered. */
+ for (std::list<Vehicle *>::iterator it(st->loading_vehicles.begin()); it != st->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, avoid, avoid2, &ge);
+ }
+ }
+}
+
+/**
* Check all next hops of cargo packets in this station for existance of a
* a valid link they may use to travel on. Reroute any cargo not having a valid
* link and remove timed out links found like this from the linkgraph. We're
@@ -3402,17 +3426,7 @@ void DeleteStaleLinks(Station *from)
(DistanceManhattan(from->xy, to->xy) >> 2)) {
node.RemoveEdge(to->goods[c].node);
ge.flows.DeleteFlows(to->index);
-
- /* Reroute cargo in station. */
- 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);
- }
- }
+ RerouteCargo(from, c, to->index, from->index);
}
}
assert(_date >= lg->LastCompression());
diff --git a/src/station_func.h b/src/station_func.h
index 8efa3c2f1..39b8f5bb3 100644
--- a/src/station_func.h
+++ b/src/station_func.h
@@ -50,6 +50,7 @@ bool SplitGroundSpriteForOverlay(const TileInfo *ti, SpriteID *ground, RailTrack
void IncreaseStats(Station *st, const Vehicle *v, StationID next_station_id);
void IncreaseStats(Station *st, CargoID cargo, StationID next_station_id, uint capacity, uint usage);
+void RerouteCargo(Station *st, CargoID c, StationID avoid, StationID avoid2);
/**
* Calculates the maintenance cost of a number of station tiles.