1
0
Fork 0

Change: Adapt VehicleEnter_Track and handle trains entering extended depots.

# Conflicts:
#	src/vehicle.cpp
pull/8480/head
J0anJosep 2023-04-22 21:18:59 +02:00
parent 2b259442f1
commit b6946fb17f
4 changed files with 94 additions and 15 deletions

View File

@ -33,6 +33,7 @@
#include "object_map.h" #include "object_map.h"
#include "rail_cmd.h" #include "rail_cmd.h"
#include "landscape_cmd.h" #include "landscape_cmd.h"
#include "platform_func.h"
#include "table/strings.h" #include "table/strings.h"
#include "table/railtypes.h" #include "table/railtypes.h"
@ -3076,6 +3077,38 @@ static VehicleEnterTileStatus VehicleEnter_Track(Vehicle *u, TileIndex tile, int
/* This routine applies only to trains in depot tiles. */ /* This routine applies only to trains in depot tiles. */
if (u->type != VEH_TRAIN || !IsRailDepotTile(tile)) return VETSB_CONTINUE; if (u->type != VEH_TRAIN || !IsRailDepotTile(tile)) return VETSB_CONTINUE;
Train *v = Train::From(u);
if (IsExtendedRailDepot(tile)) {
DepotID depot_id = GetDepotIndex(tile);
if (!v->current_order.ShouldStopAtDepot(depot_id)) return VETSB_CONTINUE;
/* Stop position on platform is half the front vehicle length of the train. */
int stop_pos = v->gcache.cached_veh_length / 2;
int depot_ahead = (GetPlatformLength(tile, DirToDiagDir(v->direction)) - 1) * TILE_SIZE;
if (depot_ahead > stop_pos) return VETSB_CONTINUE;
DiagDirection dir = DirToDiagDir(v->direction);
x &= 0xF;
y &= 0xF;
if (DiagDirToAxis(dir) != AXIS_X) Swap(x, y);
if (y == TILE_SIZE / 2) {
if (dir == DIAGDIR_SE || dir == DIAGDIR_SW) x = TILE_SIZE - 1 - x;
if (stop_pos == x) {
return VETSB_ENTERED_DEPOT_PLATFORM;
} else if (stop_pos < x) {
v->vehstatus |= VS_TRAIN_SLOWING;
uint16_t spd = std::max(0, stop_pos * 20 - 15);
if (spd < v->cur_speed) v->cur_speed = spd;
}
}
return VETSB_CONTINUE;
}
/* Depot direction. */ /* Depot direction. */
DiagDirection dir = GetRailDepotDirection(tile); DiagDirection dir = GetRailDepotDirection(tile);
@ -3084,8 +3117,6 @@ static VehicleEnterTileStatus VehicleEnter_Track(Vehicle *u, TileIndex tile, int
/* Make sure a train is not entering the tile from behind. */ /* Make sure a train is not entering the tile from behind. */
if (_fractcoords_behind[dir] == fract_coord) return VETSB_CANNOT_ENTER; if (_fractcoords_behind[dir] == fract_coord) return VETSB_CANNOT_ENTER;
Train *v = Train::From(u);
/* Leaving depot? */ /* Leaving depot? */
if (v->direction == DiagDirToDir(dir)) { if (v->direction == DiagDirToDir(dir)) {
/* Calculate the point where the following wagon should be activated. */ /* Calculate the point where the following wagon should be activated. */
@ -3110,7 +3141,7 @@ static VehicleEnterTileStatus VehicleEnter_Track(Vehicle *u, TileIndex tile, int
v->track = TRACK_BIT_DEPOT, v->track = TRACK_BIT_DEPOT,
v->vehstatus |= VS_HIDDEN; v->vehstatus |= VS_HIDDEN;
v->direction = ReverseDir(v->direction); v->direction = ReverseDir(v->direction);
if (v->Next() == nullptr) VehicleEnterDepot(v->First()); if (v->Next() == nullptr) HandleTrainEnterDepot(v->First());
v->tile = tile; v->tile = tile;
InvalidateWindowData(WC_VEHICLE_DEPOT, GetDepotIndex(v->tile)); InvalidateWindowData(WC_VEHICLE_DEPOT, GetDepotIndex(v->tile));

View File

@ -354,5 +354,6 @@ protected: // These functions should not be called outside acceleration code.
}; };
bool HasCompatibleDepotTile(TileIndex tile, const Train *t); bool HasCompatibleDepotTile(TileIndex tile, const Train *t);
bool HandleTrainEnterDepot(Train *v);
#endif /* TRAIN_H */ #endif /* TRAIN_H */

View File

@ -2411,6 +2411,31 @@ static void CheckNextTrainTile(Train *v)
} }
} }
bool HandleTrainEnterDepot(Train *v)
{
assert(IsRailDepotTile(v->tile));
if (IsExtendedRailDepot(v->tile)) {
v->cur_speed = 0;
Train *t = Train::From(v);
for (Train *u = t; u != nullptr; u = u->Next()) u->track |= TRACK_BIT_DEPOT;
t->force_proceed = TFP_NONE;
ClrBit(t->flags, VRF_TOGGLE_REVERSE);
v->UpdateViewport(true, true);
SetWindowClassesDirty(WC_TRAINS_LIST);
SetWindowDirty(WC_VEHICLE_VIEW, v->index);
InvalidateWindowData(WC_VEHICLE_DEPOT, GetDepotIndex(v->tile));
v->StartService();
} else {
/* Clear path reservation */
SetDepotReservation(v->tile, false);
VehicleEnterDepot(v);
}
return true;
}
/** /**
* Will the train stay in the depot the next tick? * Will the train stay in the depot the next tick?
* @param v %Train to check. * @param v %Train to check.
@ -2419,15 +2444,30 @@ static void CheckNextTrainTile(Train *v)
static bool CheckTrainStayInDepot(Train *v) static bool CheckTrainStayInDepot(Train *v)
{ {
/* bail out if not all wagons are in the same depot or not in a depot at all */ /* bail out if not all wagons are in the same depot or not in a depot at all */
for (const Train *u = v; u != nullptr; u = u->Next()) { if (!v->IsInDepot()) return false;
if (!u->IsInDepot() || u->tile != v->tile) return false; assert(IsRailDepotTile(v->tile));
}
/* if the train got no power, then keep it in the depot */ DepotID depot_id = GetDepotIndex(v->tile);
if (v->gcache.cached_power == 0) { if (IsExtendedRailDepot(v->tile)) {
v->vehstatus |= VS_STOPPED; for (Train *u = v; u != nullptr; u = u->Next()) u->track &= ~TRACK_BIT_DEPOT;
SetWindowDirty(WC_VEHICLE_DEPOT, GetDepotIndex(v->tile)); v->cur_speed = 0;
return true;
v->UpdatePosition();
v->UpdateViewport(true, true);
v->UpdateAcceleration();
InvalidateWindowData(WC_VEHICLE_DEPOT, depot_id);
return false;
} else {
for (const Train *u = v; u != nullptr; u = u->Next()) {
if (!u->IsInDepot() || u->tile != v->tile) return false;
}
/* if the train got no power, then keep it in the depot */
if (v->gcache.cached_power == 0) {
v->vehstatus |= VS_STOPPED;
SetWindowDirty(WC_VEHICLE_DEPOT, depot_id);
return true;
}
} }
/* Check if we should wait here for unbunching. */ /* Check if we should wait here for unbunching. */
@ -2459,7 +2499,7 @@ static bool CheckTrainStayInDepot(Train *v)
IsRailDepotTile(v->tile) && IsRailDepotTile(v->tile) &&
v->current_order.GetDestination() == GetDepotIndex(v->tile)) { v->current_order.GetDestination() == GetDepotIndex(v->tile)) {
/* Service when depot has no reservation. */ /* Service when depot has no reservation. */
if (!HasDepotReservation(v->tile)) VehicleEnterDepot(v); if (!HasDepotReservation(v->tile)) HandleTrainEnterDepot(v);
return true; return true;
} }
@ -2489,7 +2529,7 @@ static bool CheckTrainStayInDepot(Train *v)
v->UpdatePosition(); v->UpdatePosition();
UpdateSignalsOnSegment(v->tile, INVALID_DIAGDIR, v->owner); UpdateSignalsOnSegment(v->tile, INVALID_DIAGDIR, v->owner);
v->UpdateAcceleration(); v->UpdateAcceleration();
InvalidateWindowData(WC_VEHICLE_DEPOT, GetDepotIndex(v->tile)); InvalidateWindowData(WC_VEHICLE_DEPOT, depot_id);
return false; return false;
} }
@ -3442,6 +3482,12 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
if (HasBit(r, VETS_ENTERED_STATION)) { if (HasBit(r, VETS_ENTERED_STATION)) {
/* The new position is the end of the platform */ /* The new position is the end of the platform */
TrainEnterStation(v, r >> VETS_STATION_ID_OFFSET); TrainEnterStation(v, r >> VETS_STATION_ID_OFFSET);
} else if (HasBit(r, VETS_ENTERED_DEPOT_PLATFORM)) {
if (HandleTrainEnterDepot(first)) {
v->UpdatePosition();
v->UpdateViewport(true, true);
return false;
}
} }
} }
} else { } else {
@ -4098,6 +4144,8 @@ static bool TrainLocoHandler(Train *v, bool mode)
/* exit if train is stopped */ /* exit if train is stopped */
if ((v->vehstatus & VS_STOPPED) && v->cur_speed == 0) return true; if ((v->vehstatus & VS_STOPPED) && v->cur_speed == 0) return true;
if (v->ContinueServicing()) return true;
bool valid_order = !v->current_order.IsType(OT_NOTHING) && v->current_order.GetType() != OT_CONDITIONAL; bool valid_order = !v->current_order.IsType(OT_NOTHING) && v->current_order.GetType() != OT_CONDITIONAL;
if (ProcessOrders(v) && CheckReverseTrain(v)) { if (ProcessOrders(v) && CheckReverseTrain(v)) {
v->wait_counter = 0; v->wait_counter = 0;

View File

@ -1201,6 +1201,7 @@ void CallVehicleTicks()
if (it.second) { if (it.second) {
v->vehstatus &= ~VS_STOPPED; v->vehstatus &= ~VS_STOPPED;
} else if (IsExtendedDepotTile(v->tile)){ } else if (IsExtendedDepotTile(v->tile)){
if (v->type == VEH_TRAIN) FreeTrainTrackReservation(Train::From(v));
UpdateExtendedDepotReservation(v, true); UpdateExtendedDepotReservation(v, true);
} }
@ -1683,8 +1684,6 @@ void VehicleEnterDepot(Vehicle *v)
case VEH_TRAIN: { case VEH_TRAIN: {
Train *t = Train::From(v); Train *t = Train::From(v);
SetWindowClassesDirty(WC_TRAINS_LIST); SetWindowClassesDirty(WC_TRAINS_LIST);
/* Clear path reservation */
SetDepotReservation(t->tile, false);
if (_settings_client.gui.show_track_reservation) MarkTileDirtyByTile(t->tile); if (_settings_client.gui.show_track_reservation) MarkTileDirtyByTile(t->tile);
UpdateSignalsOnSegment(t->tile, INVALID_DIAGDIR, t->owner); UpdateSignalsOnSegment(t->tile, INVALID_DIAGDIR, t->owner);