|
@@ -4497,149 +4497,6 @@ void TrainsYearlyLoop()
|
|
|
|
|
|
|
|
|
void InitializeTrains()
|
|
|
{
|
|
|
_age_cargo_skip_counter = 1;
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
* Link front and rear multiheaded engines to each other
|
|
|
* This is done when loading a savegame
|
|
|
*/
|
|
|
void ConnectMultiheadedTrains()
|
|
|
{
|
|
|
Vehicle *v;
|
|
|
|
|
|
FOR_ALL_VEHICLES(v) {
|
|
|
if (v->type == VEH_TRAIN) {
|
|
|
v->u.rail.other_multiheaded_part = NULL;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
FOR_ALL_VEHICLES(v) {
|
|
|
if (v->type == VEH_TRAIN && (IsFrontEngine(v) || IsFreeWagon(v))) {
|
|
|
/* Two ways to associate multiheaded parts to each other:
|
|
|
* sequential-matching: Trains shall be arranged to look like <..>..<..>..<..>..
|
|
|
* bracket-matching: Free vehicle chains shall be arranged to look like ..<..<..>..<..>..>..
|
|
|
*
|
|
|
* Note: Old savegames might contain chains which do not comply with these rules, e.g.
|
|
|
* - the front and read parts have invalid orders
|
|
|
* - different engine types might be combined
|
|
|
* - there might be different amounts of front and rear parts.
|
|
|
*
|
|
|
* Note: The multiheaded parts need to be matched exactly like they are matched on the server, else desyncs will occur.
|
|
|
* This is why two matching strategies are needed.
|
|
|
*/
|
|
|
|
|
|
bool sequential_matching = IsFrontEngine(v);
|
|
|
|
|
|
for (Vehicle *u = v; u != NULL; u = GetNextVehicle(u)) {
|
|
|
if (u->u.rail.other_multiheaded_part != NULL) continue; // we already linked this one
|
|
|
|
|
|
if (IsMultiheaded(u)) {
|
|
|
if (!IsTrainEngine(u)) {
|
|
|
/* we got a rear car without a front car. We will convert it to a front one */
|
|
|
SetTrainEngine(u);
|
|
|
u->spritenum--;
|
|
|
}
|
|
|
|
|
|
/* Find a matching back part */
|
|
|
EngineID eid = u->engine_type;
|
|
|
Vehicle *w;
|
|
|
if (sequential_matching) {
|
|
|
for (w = GetNextVehicle(u); w != NULL; w = GetNextVehicle(w)) {
|
|
|
if (w->engine_type != eid || w->u.rail.other_multiheaded_part != NULL || !IsMultiheaded(w)) continue;
|
|
|
|
|
|
/* we found a car to partner with this engine. Now we will make sure it face the right way */
|
|
|
if (IsTrainEngine(w)) {
|
|
|
ClearTrainEngine(w);
|
|
|
w->spritenum++;
|
|
|
}
|
|
|
break;
|
|
|
}
|
|
|
} else {
|
|
|
uint stack_pos = 0;
|
|
|
for (w = GetNextVehicle(u); w != NULL; w = GetNextVehicle(w)) {
|
|
|
if (w->engine_type != eid || w->u.rail.other_multiheaded_part != NULL || !IsMultiheaded(w)) continue;
|
|
|
|
|
|
if (IsTrainEngine(w)) {
|
|
|
stack_pos++;
|
|
|
} else {
|
|
|
if (stack_pos == 0) break;
|
|
|
stack_pos--;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (w != NULL) {
|
|
|
w->u.rail.other_multiheaded_part = u;
|
|
|
u->u.rail.other_multiheaded_part = w;
|
|
|
} else {
|
|
|
/* we got a front car and no rear cars. We will fake this one for forget that it should have been multiheaded */
|
|
|
ClearMultiheaded(u);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Converts all trains to the new subtype format introduced in savegame 16.2
|
|
|
* It also links multiheaded engines or make them forget they are multiheaded if no suitable partner is found
|
|
|
*/
|
|
|
void ConvertOldMultiheadToNew()
|
|
|
{
|
|
|
Vehicle *v;
|
|
|
FOR_ALL_VEHICLES(v) {
|
|
|
if (v->type == VEH_TRAIN) {
|
|
|
SetBit(v->subtype, 7); // indicates that it's the old format and needs to be converted in the next loop
|
|
|
}
|
|
|
}
|
|
|
|
|
|
FOR_ALL_VEHICLES(v) {
|
|
|
if (v->type == VEH_TRAIN) {
|
|
|
if (HasBit(v->subtype, 7) && ((v->subtype & ~0x80) == 0 || (v->subtype & ~0x80) == 4)) {
|
|
|
for (Vehicle *u = v; u != NULL; u = u->Next()) {
|
|
|
const RailVehicleInfo *rvi = RailVehInfo(u->engine_type);
|
|
|
|
|
|
ClrBit(u->subtype, 7);
|
|
|
switch (u->subtype) {
|
|
|
case 0: /* TS_Front_Engine */
|
|
|
if (rvi->railveh_type == RAILVEH_MULTIHEAD) SetMultiheaded(u);
|
|
|
SetFrontEngine(u);
|
|
|
SetTrainEngine(u);
|
|
|
break;
|
|
|
|
|
|
case 1: /* TS_Artic_Part */
|
|
|
u->subtype = 0;
|
|
|
SetArticulatedPart(u);
|
|
|
break;
|
|
|
|
|
|
case 2: /* TS_Not_First */
|
|
|
u->subtype = 0;
|
|
|
if (rvi->railveh_type == RAILVEH_WAGON) {
|
|
|
// normal wagon
|
|
|
SetTrainWagon(u);
|
|
|
break;
|
|
|
}
|
|
|
if (rvi->railveh_type == RAILVEH_MULTIHEAD && rvi->image_index == u->spritenum - 1) {
|
|
|
// rear end of a multiheaded engine
|
|
|
SetMultiheaded(u);
|
|
|
break;
|
|
|
}
|
|
|
if (rvi->railveh_type == RAILVEH_MULTIHEAD) SetMultiheaded(u);
|
|
|
SetTrainEngine(u);
|
|
|
break;
|
|
|
|
|
|
case 4: /* TS_Free_Car */
|
|
|
u->subtype = 0;
|
|
|
SetTrainWagon(u);
|
|
|
SetFreeWagon(u);
|
|
|
break;
|
|
|
default: NOT_REACHED(); break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|