mirror of https://github.com/OpenTTD/OpenTTD
Change: Changes related with crashed trains in extended depots.
parent
12862b5df8
commit
d4e89ad573
|
@ -3270,6 +3270,7 @@ static bool TrainMovedChangeSignals(TileIndex tile, DiagDirection dir)
|
||||||
void Train::ReserveTrackUnderConsist() const
|
void Train::ReserveTrackUnderConsist() const
|
||||||
{
|
{
|
||||||
for (const Train *u = this; u != nullptr; u = u->Next()) {
|
for (const Train *u = this; u != nullptr; u = u->Next()) {
|
||||||
|
if (u->vehstatus & VS_HIDDEN) continue;
|
||||||
switch (u->track) {
|
switch (u->track) {
|
||||||
case TRACK_BIT_WORMHOLE:
|
case TRACK_BIT_WORMHOLE:
|
||||||
TryReserveRailTrack(u->tile, DiagDirToDiagTrack(GetTunnelBridgeDirection(u->tile)));
|
TryReserveRailTrack(u->tile, DiagDirToDiagTrack(GetTunnelBridgeDirection(u->tile)));
|
||||||
|
@ -3298,6 +3299,23 @@ uint Train::Crash(bool flooded)
|
||||||
/* Remove the reserved path in front of the train if it is not stuck.
|
/* Remove the reserved path in front of the train if it is not stuck.
|
||||||
* Also clear all reserved tracks the train is currently on. */
|
* Also clear all reserved tracks the train is currently on. */
|
||||||
if (!HasBit(this->flags, VRF_TRAIN_STUCK)) FreeTrainTrackReservation(this);
|
if (!HasBit(this->flags, VRF_TRAIN_STUCK)) FreeTrainTrackReservation(this);
|
||||||
|
|
||||||
|
if (IsExtendedRailDepotTile(this->tile)) {
|
||||||
|
if (this->track & ~TRACK_BIT_DEPOT) {
|
||||||
|
for (Train *v = this; v != nullptr; v = v->Next()) {
|
||||||
|
v->track &= ~TRACK_BIT_DEPOT;
|
||||||
|
}
|
||||||
|
InvalidateWindowData(WC_VEHICLE_DEPOT, GetDepotIndex(this->tile));
|
||||||
|
}
|
||||||
|
/* Remove reserved tracks of platform ahead. */
|
||||||
|
TileIndexDiff diff = TileOffsByDiagDir(TrackdirToExitdir(this->GetVehicleTrackdir()));
|
||||||
|
for (TileIndex pt_tile = this->tile + diff; IsCompatiblePlatformTile(pt_tile, this->tile) && HasDepotReservation(pt_tile); pt_tile += diff) {
|
||||||
|
if (EnsureNoVisibleVehicleOnGround(pt_tile).Failed()) break;
|
||||||
|
SetDepotReservation(pt_tile, false);
|
||||||
|
MarkTileDirtyByTile(pt_tile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (const Train *v = this; v != nullptr; v = v->Next()) {
|
for (const Train *v = this; v != nullptr; v = v->Next()) {
|
||||||
ClearPathReservation(v, v->tile, v->GetVehicleTrackdir());
|
ClearPathReservation(v, v->tile, v->GetVehicleTrackdir());
|
||||||
if (IsTileType(v->tile, MP_TUNNELBRIDGE)) {
|
if (IsTileType(v->tile, MP_TUNNELBRIDGE)) {
|
||||||
|
@ -3305,6 +3323,23 @@ uint Train::Crash(bool flooded)
|
||||||
* if the train has just entered the wormhole. */
|
* if the train has just entered the wormhole. */
|
||||||
SetTunnelBridgeReservation(GetOtherTunnelBridgeEnd(v->tile), false);
|
SetTunnelBridgeReservation(GetOtherTunnelBridgeEnd(v->tile), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (v->Next() == nullptr && (IsRailStationTile(v->tile) || IsExtendedRailDepotTile(v->tile))) {
|
||||||
|
/* Remove reserved tracks of platform tiles behind the train. */
|
||||||
|
TileIndexDiff diff = TileOffsByDiagDir(TrackdirToExitdir(ReverseTrackdir(v->GetVehicleTrackdir())));
|
||||||
|
for (TileIndex pt_tile = v->tile + diff; IsCompatiblePlatformTile(pt_tile, v->tile); pt_tile += diff) {
|
||||||
|
if (IsExtendedRailDepotTile(pt_tile)) {
|
||||||
|
if (!HasDepotReservation(pt_tile)) break;
|
||||||
|
if (EnsureNoVisibleVehicleOnGround(pt_tile).Failed()) break;
|
||||||
|
SetDepotReservation(pt_tile, false);
|
||||||
|
} else {
|
||||||
|
if (!HasStationReservation(pt_tile)) break;
|
||||||
|
if (EnsureNoVisibleVehicleOnGround(pt_tile).Failed()) break;
|
||||||
|
SetRailStationReservation(pt_tile, false);
|
||||||
|
}
|
||||||
|
MarkTileDirtyByTile(pt_tile);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we may need to update crossing we were approaching,
|
/* we may need to update crossing we were approaching,
|
||||||
|
@ -3317,6 +3352,7 @@ uint Train::Crash(bool flooded)
|
||||||
}
|
}
|
||||||
|
|
||||||
pass += this->GroundVehicleBase::Crash(flooded);
|
pass += this->GroundVehicleBase::Crash(flooded);
|
||||||
|
this->ReserveTrackUnderConsist();
|
||||||
|
|
||||||
this->crash_anim_pos = flooded ? 4000 : 1; // max 4440, disappear pretty fast when flooded
|
this->crash_anim_pos = flooded ? 4000 : 1; // max 4440, disappear pretty fast when flooded
|
||||||
return pass;
|
return pass;
|
||||||
|
@ -3339,10 +3375,6 @@ static uint TrainCrashed(Train *v)
|
||||||
Game::NewEvent(new ScriptEventVehicleCrashed(v->index, v->tile, ScriptEventVehicleCrashed::CRASH_TRAIN));
|
Game::NewEvent(new ScriptEventVehicleCrashed(v->index, v->tile, ScriptEventVehicleCrashed::CRASH_TRAIN));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Try to re-reserve track under already crashed train too.
|
|
||||||
* Crash() clears the reservation! */
|
|
||||||
v->ReserveTrackUnderConsist();
|
|
||||||
|
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3395,6 +3427,9 @@ static Vehicle *FindTrainCollideEnum(Vehicle *v, void *data)
|
||||||
tcc->num += TrainCrashed(tcc->v);
|
tcc->num += TrainCrashed(tcc->v);
|
||||||
tcc->num += TrainCrashed(coll);
|
tcc->num += TrainCrashed(coll);
|
||||||
|
|
||||||
|
/* The crashing of the coll train frees reservation of train v: Reserve again for train v. */
|
||||||
|
tcc->v->ReserveTrackUnderConsist();
|
||||||
|
|
||||||
return nullptr; // continue searching
|
return nullptr; // continue searching
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -667,6 +667,24 @@ CommandCost EnsureNoVehicleOnGround(TileIndex tile)
|
||||||
return CommandCost();
|
return CommandCost();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure there is no visible vehicle at the ground at the given position.
|
||||||
|
* @param tile Position to examine.
|
||||||
|
* @return Succeeded command (ground is free) or failed command (a visible vehicle is found).
|
||||||
|
*/
|
||||||
|
CommandCost EnsureNoVisibleVehicleOnGround(TileIndex tile)
|
||||||
|
{
|
||||||
|
int z = GetTileMaxPixelZ(tile);
|
||||||
|
|
||||||
|
/* Value v is not safe in MP games, however, it is used to generate a local
|
||||||
|
* error message only (which may be different for different machines).
|
||||||
|
* Such a message does not affect MP synchronisation.
|
||||||
|
*/
|
||||||
|
Vehicle *v = VehicleFromPos(tile, &z, &EnsureNoVehicleProcZ, true);
|
||||||
|
if (v != nullptr && (v->vehstatus & VS_HIDDEN) == 0) return_cmd_error(STR_ERROR_TRAIN_IN_THE_WAY + v->type);
|
||||||
|
return CommandCost();
|
||||||
|
}
|
||||||
|
|
||||||
/** Procedure called for every vehicle found in tunnel/bridge in the hash map */
|
/** Procedure called for every vehicle found in tunnel/bridge in the hash map */
|
||||||
static Vehicle *GetVehicleTunnelBridgeProc(Vehicle *v, void *data)
|
static Vehicle *GetVehicleTunnelBridgeProc(Vehicle *v, void *data)
|
||||||
{
|
{
|
||||||
|
|
|
@ -165,6 +165,7 @@ inline StringID GetCmdSendToDepotMsg(const BaseVehicle *v)
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandCost EnsureNoVehicleOnGround(TileIndex tile);
|
CommandCost EnsureNoVehicleOnGround(TileIndex tile);
|
||||||
|
CommandCost EnsureNoVisibleVehicleOnGround(TileIndex tile);
|
||||||
CommandCost EnsureNoTrainOnTrackBits(TileIndex tile, TrackBits track_bits);
|
CommandCost EnsureNoTrainOnTrackBits(TileIndex tile, TrackBits track_bits);
|
||||||
|
|
||||||
bool CanVehicleUseStation(EngineID engine_type, const struct Station *st);
|
bool CanVehicleUseStation(EngineID engine_type, const struct Station *st);
|
||||||
|
|
Loading…
Reference in New Issue