mirror of https://github.com/OpenTTD/OpenTTD
Change: Adapt VehicleEnter_Track and handle trains entering extended depots.
# Conflicts: # src/vehicle.cpppull/8480/head
parent
2b259442f1
commit
b6946fb17f
|
@ -33,6 +33,7 @@
|
|||
#include "object_map.h"
|
||||
#include "rail_cmd.h"
|
||||
#include "landscape_cmd.h"
|
||||
#include "platform_func.h"
|
||||
|
||||
#include "table/strings.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. */
|
||||
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. */
|
||||
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. */
|
||||
if (_fractcoords_behind[dir] == fract_coord) return VETSB_CANNOT_ENTER;
|
||||
|
||||
Train *v = Train::From(u);
|
||||
|
||||
/* Leaving depot? */
|
||||
if (v->direction == DiagDirToDir(dir)) {
|
||||
/* 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->vehstatus |= VS_HIDDEN;
|
||||
v->direction = ReverseDir(v->direction);
|
||||
if (v->Next() == nullptr) VehicleEnterDepot(v->First());
|
||||
if (v->Next() == nullptr) HandleTrainEnterDepot(v->First());
|
||||
v->tile = tile;
|
||||
|
||||
InvalidateWindowData(WC_VEHICLE_DEPOT, GetDepotIndex(v->tile));
|
||||
|
|
|
@ -354,5 +354,6 @@ protected: // These functions should not be called outside acceleration code.
|
|||
};
|
||||
|
||||
bool HasCompatibleDepotTile(TileIndex tile, const Train *t);
|
||||
bool HandleTrainEnterDepot(Train *v);
|
||||
|
||||
#endif /* TRAIN_H */
|
||||
|
|
|
@ -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?
|
||||
* @param v %Train to check.
|
||||
|
@ -2419,15 +2444,30 @@ static void CheckNextTrainTile(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 */
|
||||
for (const Train *u = v; u != nullptr; u = u->Next()) {
|
||||
if (!u->IsInDepot() || u->tile != v->tile) return false;
|
||||
}
|
||||
if (!v->IsInDepot()) return false;
|
||||
assert(IsRailDepotTile(v->tile));
|
||||
|
||||
/* 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, GetDepotIndex(v->tile));
|
||||
return true;
|
||||
DepotID depot_id = GetDepotIndex(v->tile);
|
||||
if (IsExtendedRailDepot(v->tile)) {
|
||||
for (Train *u = v; u != nullptr; u = u->Next()) u->track &= ~TRACK_BIT_DEPOT;
|
||||
v->cur_speed = 0;
|
||||
|
||||
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. */
|
||||
|
@ -2459,7 +2499,7 @@ static bool CheckTrainStayInDepot(Train *v)
|
|||
IsRailDepotTile(v->tile) &&
|
||||
v->current_order.GetDestination() == GetDepotIndex(v->tile)) {
|
||||
/* Service when depot has no reservation. */
|
||||
if (!HasDepotReservation(v->tile)) VehicleEnterDepot(v);
|
||||
if (!HasDepotReservation(v->tile)) HandleTrainEnterDepot(v);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2489,7 +2529,7 @@ static bool CheckTrainStayInDepot(Train *v)
|
|||
v->UpdatePosition();
|
||||
UpdateSignalsOnSegment(v->tile, INVALID_DIAGDIR, v->owner);
|
||||
v->UpdateAcceleration();
|
||||
InvalidateWindowData(WC_VEHICLE_DEPOT, GetDepotIndex(v->tile));
|
||||
InvalidateWindowData(WC_VEHICLE_DEPOT, depot_id);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -3442,6 +3482,12 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
|
|||
if (HasBit(r, VETS_ENTERED_STATION)) {
|
||||
/* The new position is the end of the platform */
|
||||
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 {
|
||||
|
@ -4098,6 +4144,8 @@ static bool TrainLocoHandler(Train *v, bool mode)
|
|||
/* exit if train is stopped */
|
||||
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;
|
||||
if (ProcessOrders(v) && CheckReverseTrain(v)) {
|
||||
v->wait_counter = 0;
|
||||
|
|
|
@ -1201,6 +1201,7 @@ void CallVehicleTicks()
|
|||
if (it.second) {
|
||||
v->vehstatus &= ~VS_STOPPED;
|
||||
} else if (IsExtendedDepotTile(v->tile)){
|
||||
if (v->type == VEH_TRAIN) FreeTrainTrackReservation(Train::From(v));
|
||||
UpdateExtendedDepotReservation(v, true);
|
||||
}
|
||||
|
||||
|
@ -1683,8 +1684,6 @@ void VehicleEnterDepot(Vehicle *v)
|
|||
case VEH_TRAIN: {
|
||||
Train *t = Train::From(v);
|
||||
SetWindowClassesDirty(WC_TRAINS_LIST);
|
||||
/* Clear path reservation */
|
||||
SetDepotReservation(t->tile, false);
|
||||
if (_settings_client.gui.show_track_reservation) MarkTileDirtyByTile(t->tile);
|
||||
|
||||
UpdateSignalsOnSegment(t->tile, INVALID_DIAGDIR, t->owner);
|
||||
|
|
Loading…
Reference in New Issue