mirror of https://github.com/OpenTTD/OpenTTD
(svn r16857) -Fix [FS#3036](r16652): crash when train partially in depot crashed
parent
b9cf3f880b
commit
57d3d4ce5e
|
@ -1708,18 +1708,9 @@ bool AfterLoadGame()
|
||||||
|
|
||||||
/* Reserve all tracks trains are currently on. */
|
/* Reserve all tracks trains are currently on. */
|
||||||
if (CheckSavegameVersion(101)) {
|
if (CheckSavegameVersion(101)) {
|
||||||
Train *t;
|
const Train *t;
|
||||||
FOR_ALL_TRAINS(t) {
|
FOR_ALL_TRAINS(t) {
|
||||||
switch (t->track) {
|
if (t->First() == t) t->ReserveTrackUnderConsist();
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -134,6 +134,7 @@ struct Train : public SpecializedVehicle<Train, VEH_TRAIN> {
|
||||||
TileIndex GetOrderStationLocation(StationID station);
|
TileIndex GetOrderStationLocation(StationID station);
|
||||||
bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse);
|
bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse);
|
||||||
|
|
||||||
|
void ReserveTrackUnderConsist() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* enum to handle train subtypes
|
* enum to handle train subtypes
|
||||||
|
|
|
@ -3470,6 +3470,24 @@ static bool TrainMovedChangeSignals(TileIndex tile, DiagDirection dir)
|
||||||
return false;
|
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)
|
static void SetVehicleCrashed(Train *v)
|
||||||
{
|
{
|
||||||
|
@ -3532,24 +3550,20 @@ static uint CountPassengersInTrain(const Train *v)
|
||||||
*/
|
*/
|
||||||
static uint TrainCrashed(Train *v)
|
static uint TrainCrashed(Train *v)
|
||||||
{
|
{
|
||||||
/* Try to re-reserve track under already crashed train too */
|
uint num = 0;
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* do not crash train twice */
|
/* 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 */
|
SetVehicleCrashed(v);
|
||||||
uint num = 2 + CountPassengersInTrain(v);
|
AI::NewEvent(v->owner, new AIEventVehicleCrashed(v->index, v->tile, AIEventVehicleCrashed::CRASH_TRAIN));
|
||||||
|
}
|
||||||
|
|
||||||
SetVehicleCrashed(v);
|
/* Try to re-reserve track under already crashed train too.
|
||||||
AI::NewEvent(v->owner, new AIEventVehicleCrashed(v->index, v->tile, AIEventVehicleCrashed::CRASH_TRAIN));
|
* SetVehicleCrashed() clears the reservation! */
|
||||||
|
v->ReserveTrackUnderConsist();
|
||||||
|
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue