(svn r23290) -Fix [FS#2379,FS#3569]: Change the centre of train vehicles to depend on the vehicle length instead of being fixed at 4/8th of the original vehicle length to make sure shortened vehicles don't block tiles they shouldn't block.
This commit is contained in:
@@ -249,8 +249,6 @@ void AfterLoadVehicles(bool part_of_load)
|
||||
if (v->Next() != NULL) v->Next()->previous = v;
|
||||
if (v->NextShared() != NULL) v->NextShared()->previous_shared = v;
|
||||
|
||||
v->UpdateDeltaXY(v->direction);
|
||||
|
||||
if (part_of_load) v->fill_percent_te_id = INVALID_TE_ID;
|
||||
v->first = NULL;
|
||||
if (v->IsGroundVehicle()) v->GetGroundVehicleCache()->first_engine = INVALID_ENGINE;
|
||||
@@ -442,11 +440,99 @@ void AfterLoadVehicles(bool part_of_load)
|
||||
default: break;
|
||||
}
|
||||
|
||||
v->UpdateDeltaXY(v->direction);
|
||||
v->coord.left = INVALID_COORD;
|
||||
VehicleMove(v, false);
|
||||
}
|
||||
}
|
||||
|
||||
bool TrainController(Train *v, Vehicle *nomove, bool reverse = true); // From train_cmd.cpp
|
||||
void ReverseTrainDirection(Train *v);
|
||||
void ReverseTrainSwapVeh(Train *v, int l, int r);
|
||||
|
||||
/** Fixup old train spacing. */
|
||||
void FixupTrainLengths()
|
||||
{
|
||||
/* Vehicle center was moved from 4 units behind the front to half the length
|
||||
* behind the front. Move vehicles so they end up on the same spot. */
|
||||
Vehicle *v;
|
||||
FOR_ALL_VEHICLES(v) {
|
||||
if (v->type == VEH_TRAIN && v->IsPrimaryVehicle()) {
|
||||
/* The vehicle center is now more to the front depending on vehicle length,
|
||||
* so we need to move all vehicles forward to cover the difference to the
|
||||
* old center, otherwise wagon spacing in trains would be broken upon load. */
|
||||
for (Train *u = Train::From(v); u != NULL; u = u->Next()) {
|
||||
if (u->track == TRACK_BIT_DEPOT || (u->vehstatus & VS_CRASHED)) continue;
|
||||
|
||||
Train *next = u->Next();
|
||||
|
||||
/* Try to pull the vehicle half its length forward. */
|
||||
int diff = (VEHICLE_LENGTH - u->gcache.cached_veh_length) / 2;
|
||||
int done;
|
||||
for (done = 0; done < diff; done++) {
|
||||
if (!TrainController(u, next, false)) break;
|
||||
}
|
||||
|
||||
if (next != NULL && done < diff && u->IsFrontEngine()) {
|
||||
/* Pulling the front vehicle forwards failed, we either encountered a dead-end
|
||||
* or a red signal. To fix this, we try to move the whole train the required
|
||||
* space backwards and re-do the fix up of the front vehicle. */
|
||||
|
||||
/* Ignore any signals when backtracking. */
|
||||
TrainForceProceeding old_tfp = u->force_proceed;
|
||||
u->force_proceed = TFP_SIGNAL;
|
||||
|
||||
/* Swap start<>end, start+1<>end-1, ... */
|
||||
int r = CountVehiclesInChain(u) - 1; // number of vehicles - 1
|
||||
int l = 0;
|
||||
do ReverseTrainSwapVeh(u, l++, r--); while (l <= r);
|
||||
|
||||
/* We moved the first vehicle which is now the last. Move it back to the
|
||||
* original position as we will fix up the last vehicle later in the loop. */
|
||||
for (int i = 0; i < done; i++) TrainController(u->Last(), NULL);
|
||||
|
||||
/* Move the train backwards to get space for the first vehicle. As the stopping
|
||||
* distance from a line end is rounded up, move the train one unit more to cater
|
||||
* for front vehicles with odd lengths. */
|
||||
int moved;
|
||||
for (moved = 0; moved < diff + 1; moved++) {
|
||||
if (!TrainController(u, NULL, false)) break;
|
||||
}
|
||||
|
||||
/* Swap start<>end, start+1<>end-1, ... again. */
|
||||
r = CountVehiclesInChain(u) - 1; // number of vehicles - 1
|
||||
l = 0;
|
||||
do ReverseTrainSwapVeh(u, l++, r--); while (l <= r);
|
||||
|
||||
u->force_proceed = old_tfp;
|
||||
|
||||
/* Tracks are too short to fix the train length. The player has to fix the
|
||||
* train in a depot. Bail out so we don't damage the vehicle chain any more. */
|
||||
if (moved < diff + 1) break;
|
||||
|
||||
/* Re-do the correction for the first vehicle. */
|
||||
for (done = 0; done < diff; done++) TrainController(u, next, false);
|
||||
|
||||
/* We moved one unit more backwards than needed for even-length front vehicles,
|
||||
* try to move that unit forward again. We don't care if this step fails. */
|
||||
TrainController(u, NULL, false);
|
||||
}
|
||||
|
||||
/* If the next wagon is still in a depot, check if it shouldn't be outside already. */
|
||||
if (next != NULL && next->track == TRACK_BIT_DEPOT) {
|
||||
int d = TicksToLeaveDepot(u);
|
||||
if (d <= 0) {
|
||||
/* Next vehicle should have left the depot already, show it and pull forward. */
|
||||
next->vehstatus &= ~VS_HIDDEN;
|
||||
next->track = TrackToTrackBits(GetRailDepotTrack(next->tile));
|
||||
for (int i = 0; i >= d; i--) TrainController(next, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static uint8 _cargo_days;
|
||||
static uint16 _cargo_source;
|
||||
static uint32 _cargo_source_xy;
|
||||
|
Reference in New Issue
Block a user