summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsmatz <smatz@openttd.org>2009-07-17 13:54:06 +0000
committersmatz <smatz@openttd.org>2009-07-17 13:54:06 +0000
commit57d3d4ce5e9f9333c27b47e5a66d2c3604ce8dc9 (patch)
treebfa744e206782c6e53b2c7f58c7ee81c0d7b98e7
parentb9cf3f880b8c25a1db7483356ddaeb1dee83ad0e (diff)
downloadopenttd-57d3d4ce5e9f9333c27b47e5a66d2c3604ce8dc9.tar.xz
(svn r16857) -Fix [FS#3036](r16652): crash when train partially in depot crashed
-rw-r--r--src/saveload/afterload.cpp13
-rw-r--r--src/train.h1
-rw-r--r--src/train_cmd.cpp42
3 files changed, 31 insertions, 25 deletions
diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp
index a26ef0e6b..7879af4e7 100644
--- a/src/saveload/afterload.cpp
+++ b/src/saveload/afterload.cpp
@@ -1708,18 +1708,9 @@ bool AfterLoadGame()
/* Reserve all tracks trains are currently on. */
if (CheckSavegameVersion(101)) {
- Train *t;
+ const Train *t;
FOR_ALL_TRAINS(t) {
- switch (t->track) {
- case TRACK_BIT_WORMHOLE:
- TryReserveRailTrack(t->tile, DiagDirToDiagTrack(GetTunnelBridgeDirection(t->tile)));
- break;
- case TRACK_BIT_DEPOT:
- break;
- default:
- TryReserveRailTrack(t->tile, TrackBitsToTrack(t->track));
- break;
- }
+ if (t->First() == t) t->ReserveTrackUnderConsist();
}
}
diff --git a/src/train.h b/src/train.h
index aba89633d..8dca09f96 100644
--- a/src/train.h
+++ b/src/train.h
@@ -134,6 +134,7 @@ struct Train : public SpecializedVehicle<Train, VEH_TRAIN> {
TileIndex GetOrderStationLocation(StationID station);
bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse);
+ void ReserveTrackUnderConsist() const;
/**
* enum to handle train subtypes
diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp
index 3a4dde6a9..3319f3403 100644
--- a/src/train_cmd.cpp
+++ b/src/train_cmd.cpp
@@ -3470,6 +3470,24 @@ static bool TrainMovedChangeSignals(TileIndex tile, DiagDirection dir)
return false;
}
+/**
+ * Tries to reserve track under whole train consist
+ */
+void Train::ReserveTrackUnderConsist() const
+{
+ for (const Train *u = this; u != NULL; u = u->Next()) {
+ switch (u->track) {
+ case TRACK_BIT_WORMHOLE:
+ TryReserveRailTrack(u->tile, DiagDirToDiagTrack(GetTunnelBridgeDirection(u->tile)));
+ break;
+ case TRACK_BIT_DEPOT:
+ break;
+ default:
+ TryReserveRailTrack(u->tile, TrackBitsToTrack(u->track));
+ break;
+ }
+ }
+}
static void SetVehicleCrashed(Train *v)
{
@@ -3532,24 +3550,20 @@ static uint CountPassengersInTrain(const Train *v)
*/
static uint TrainCrashed(Train *v)
{
- /* Try to re-reserve track under already crashed train too */
- for (const Train *u = v; u != NULL; u = u->Next()) {
- TrackBits trackbits = u->track;
- if (trackbits == TRACK_BIT_WORMHOLE) {
- /* Vehicle is inside a wormhole, v->track contains no useful value then. */
- trackbits = DiagDirToDiagTrackBits(GetTunnelBridgeDirection(u->tile));
- }
- TryReserveRailTrack(u->tile, TrackBitsToTrack(trackbits));
- }
+ uint num = 0;
/* do not crash train twice */
- if (v->vehstatus & VS_CRASHED) return 0;
+ if (!(v->vehstatus & VS_CRASHED)) {
+ /* two drivers + passengers */
+ num = 2 + CountPassengersInTrain(v);
- /* two drivers + passengers */
- uint num = 2 + CountPassengersInTrain(v);
+ SetVehicleCrashed(v);
+ AI::NewEvent(v->owner, new AIEventVehicleCrashed(v->index, v->tile, AIEventVehicleCrashed::CRASH_TRAIN));
+ }
- SetVehicleCrashed(v);
- AI::NewEvent(v->owner, new AIEventVehicleCrashed(v->index, v->tile, AIEventVehicleCrashed::CRASH_TRAIN));
+ /* Try to re-reserve track under already crashed train too.
+ * SetVehicleCrashed() clears the reservation! */
+ v->ReserveTrackUnderConsist();
return num;
}