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:
@@ -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);
|
||||
|
Reference in New Issue
Block a user