diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -4500,146 +4500,3 @@ 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; - } - } - } - } - } -}