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 "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));
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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,6 +2444,20 @@ 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 */
|
||||||
|
if (!v->IsInDepot()) return false;
|
||||||
|
assert(IsRailDepotTile(v->tile));
|
||||||
|
|
||||||
|
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()) {
|
for (const Train *u = v; u != nullptr; u = u->Next()) {
|
||||||
if (!u->IsInDepot() || u->tile != v->tile) return false;
|
if (!u->IsInDepot() || u->tile != v->tile) return false;
|
||||||
}
|
}
|
||||||
|
@ -2426,9 +2465,10 @@ static bool CheckTrainStayInDepot(Train *v)
|
||||||
/* if the train got no power, then keep it in the depot */
|
/* if the train got no power, then keep it in the depot */
|
||||||
if (v->gcache.cached_power == 0) {
|
if (v->gcache.cached_power == 0) {
|
||||||
v->vehstatus |= VS_STOPPED;
|
v->vehstatus |= VS_STOPPED;
|
||||||
SetWindowDirty(WC_VEHICLE_DEPOT, GetDepotIndex(v->tile));
|
SetWindowDirty(WC_VEHICLE_DEPOT, depot_id);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Check if we should wait here for unbunching. */
|
/* Check if we should wait here for unbunching. */
|
||||||
if (v->IsWaitingForUnbunching()) return true;
|
if (v->IsWaitingForUnbunching()) return true;
|
||||||
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue