Add reverse at waypoint orders.

The train will reverse when its tail is within the waypoint tile.
This is useful for reversing on train en-route, without creating
dedicated reversing sidings or platforms.
This commit is contained in:
Jonathan G Rennison
2015-10-28 23:50:22 +00:00
parent 78f8627c34
commit 7bcd090a0f
13 changed files with 81 additions and 5 deletions

View File

@@ -624,6 +624,7 @@ static CommandCost CmdBuildRailWagon(TileIndex tile, DoCommandFlag flags, const
v->owner = _current_company;
v->track = TRACK_BIT_DEPOT;
v->vehstatus = VS_HIDDEN | VS_DEFPAL;
v->reverse_distance = 0;
v->SetWagon();
@@ -756,6 +757,7 @@ CommandCost CmdBuildRailVehicle(TileIndex tile, DoCommandFlag flags, const Engin
v->refit_cap = 0;
v->last_station_visited = INVALID_STATION;
v->last_loading_station = INVALID_STATION;
v->reverse_distance = 0;
v->engine_type = e->index;
v->gcache.first_engine = INVALID_ENGINE; // needs to be set before first callback
@@ -1811,6 +1813,8 @@ void ReverseTrainDirection(Train *v)
InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
}
v->reverse_distance = 0;
/* Clear path reservation in front if train is not stuck. */
if (!HasBit(v->flags, VRF_TRAIN_STUCK)) FreeTrainTrackReservation(v);
@@ -3104,6 +3108,22 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
Train *prev;
bool direction_changed = false; // has direction of any part changed?
if (reverse && v->reverse_distance == 1) {
goto reverse_train_direction;
}
if (v->reverse_distance > 1) {
v->vehstatus |= VS_TRAIN_SLOWING;
int target_speed;
if (_settings_game.vehicle.train_acceleration_model == AM_REALISTIC) {
target_speed = ((v->reverse_distance - 1) * 5) / 2;
} else {
target_speed = (v->reverse_distance - 1) * 10 - 5;
}
uint16 spd = max(0, target_speed);
if (spd < v->cur_speed) v->cur_speed = spd;
}
/* For every vehicle after and including the given vehicle */
for (prev = v->Previous(); v != nomove; prev = v, v = v->Next()) {
DiagDirection enterdir = DIAGDIR_BEGIN;
@@ -3118,6 +3138,7 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
/* Inside depot */
gp.x = v->x_pos;
gp.y = v->y_pos;
v->reverse_distance = 0;
} else {
/* Not inside depot */
@@ -3354,6 +3375,9 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
v->x_pos = gp.x;
v->y_pos = gp.y;
v->UpdatePosition();
if (v->reverse_distance > 1) {
v->reverse_distance--;
}
/* update the Z position of the vehicle */
int old_z = v->UpdateInclination(gp.new_tile != gp.old_tile, false);