diff --git a/src/saveload/extended_ver_sl.cpp b/src/saveload/extended_ver_sl.cpp index d890ded0e5..8e9de59144 100644 --- a/src/saveload/extended_ver_sl.cpp +++ b/src/saveload/extended_ver_sl.cpp @@ -97,7 +97,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = { { XSLFI_REVERSE_AT_WAYPOINT, XSCF_NULL, 1, 1, "reverse_at_waypoint", nullptr, nullptr, nullptr }, { XSLFI_VEH_LIFETIME_PROFIT, XSCF_NULL, 1, 1, "veh_lifetime_profit", nullptr, nullptr, nullptr }, { XSLFI_LINKGRAPH_DAY_SCALE, XSCF_NULL, 1, 1, "linkgraph_day_scale", nullptr, nullptr, nullptr }, - { XSLFI_TEMPLATE_REPLACEMENT, XSCF_NULL, 6, 6, "template_replacement", nullptr, nullptr, "TRPL,TMPL" }, + { XSLFI_TEMPLATE_REPLACEMENT, XSCF_NULL, 7, 7, "template_replacement", nullptr, nullptr, "TRPL,TMPL" }, { XSLFI_MORE_RAIL_TYPES, XSCF_NULL, 0, 1, "more_rail_types", nullptr, nullptr, nullptr }, { XSLFI_CARGO_TYPE_ORDERS, XSCF_NULL, 3, 3, "cargo_type_orders", nullptr, nullptr, "ORDX,VEOX" }, { XSLFI_EXTENDED_GAMELOG, XSCF_NULL, 1, 1, "extended_gamelog", nullptr, nullptr, nullptr }, diff --git a/src/saveload/tbtr_template_veh_sl.cpp b/src/saveload/tbtr_template_veh_sl.cpp index ae5bec2a42..58c3c621df 100644 --- a/src/saveload/tbtr_template_veh_sl.cpp +++ b/src/saveload/tbtr_template_veh_sl.cpp @@ -41,6 +41,8 @@ const SaveLoad* GTD() { SLE_CONDVAR_X(TemplateVehicle, full_weight, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TEMPLATE_REPLACEMENT, 6)), SLE_VAR(TemplateVehicle, max_te, SLE_UINT32), + SLE_CONDVAR_X(TemplateVehicle, ctrl_flags, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TEMPLATE_REPLACEMENT, 7)), + SLE_CONDNULL_X(1, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TEMPLATE_REPLACEMENT, 0, 3)), SLE_CONDNULL_X(4, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TEMPLATE_REPLACEMENT, 0, 1)), SLE_CONDNULL_X(36, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TEMPLATE_REPLACEMENT, 2, 3)), diff --git a/src/tbtr_template_vehicle.cpp b/src/tbtr_template_vehicle.cpp index 5357bc3fb5..096ee0c290 100644 --- a/src/tbtr_template_vehicle.cpp +++ b/src/tbtr_template_vehicle.cpp @@ -80,6 +80,7 @@ TemplateVehicle::TemplateVehicle(VehicleType ty, EngineID eid, byte subtypeflag, this->owner = current_owner; this->real_consist_length = 0; + this->ctrl_flags = 0; } TemplateVehicle::~TemplateVehicle() { diff --git a/src/tbtr_template_vehicle.h b/src/tbtr_template_vehicle.h index 910a57ec91..a954411053 100644 --- a/src/tbtr_template_vehicle.h +++ b/src/tbtr_template_vehicle.h @@ -70,6 +70,11 @@ struct TemplateVehicleImageDimensions { } }; +/** Template vehicle control flags. */ +enum TemplateVehicleControlFlags { + TVCF_REVERSED = 0, ///< Vehicle is reversed (VRF_REVERSE_DIRECTION) +}; + struct TemplateVehicle : TemplatePool::PoolItem<&_template_pool>, BaseVehicle { private: TemplateVehicle *next; ///< pointer to the next vehicle in the chain @@ -107,6 +112,8 @@ public: uint32 full_weight; uint32 max_te; + uint32 ctrl_flags; ///< See: TemplateVehicleControlFlags + VehicleSpriteSeq sprite_seq; ///< NOSAVE: Vehicle appearance. TemplateVehicleImageDimensions image_dimensions; ///< NOSAVE: image dimensions SpriteID colourmap; ///< NOSAVE: cached colour mapping diff --git a/src/tbtr_template_vehicle_func.cpp b/src/tbtr_template_vehicle_func.cpp index 41caebe6fa..c95fba89ab 100644 --- a/src/tbtr_template_vehicle_func.cpp +++ b/src/tbtr_template_vehicle_func.cpp @@ -154,6 +154,8 @@ void SetupTemplateVehicleFromVirtual(TemplateVehicle *tmp, TemplateVehicle *prev tmp->cargo_subtype = virt->cargo_subtype; tmp->cargo_cap = virt->cargo_cap; + SB(tmp->ctrl_flags, TVCF_REVERSED, 1, HasBit(virt->flags, VRF_REVERSE_DIRECTION) ? 1 : 0); + if (!virt->Previous()) { uint cargo_weight = 0; uint full_cargo_weight = 0; @@ -315,7 +317,7 @@ bool TrainMatchesTemplateRefit(const Train *t, const TemplateVehicle *tv) } while (t && tv) { - if (t->cargo_type != tv->cargo_type || t->cargo_subtype != tv->cargo_subtype) { + if (t->cargo_type != tv->cargo_type || t->cargo_subtype != tv->cargo_subtype || HasBit(t->flags, VRF_REVERSE_DIRECTION) != HasBit(tv->ctrl_flags, TVCF_REVERSED)) { return false; } t = t->GetNextUnit(); @@ -369,6 +371,10 @@ CommandCost CmdRefitTrainFromTemplate(Train *t, TemplateVehicle *tv, DoCommandFl cost.AddCost(DoCommand(t->tile, t->index, tv->cargo_type | tv->cargo_subtype << 8 | (1 << 16) | (1 << 31), flags, cb)); + if (HasBit(t->flags, VRF_REVERSE_DIRECTION) != HasBit(tv->ctrl_flags, TVCF_REVERSED)) { + cost.AddCost(DoCommand(t->tile, t->index, true, flags, CMD_REVERSE_TRAIN_DIRECTION | CMD_MSG(STR_ERROR_CAN_T_REVERSE_DIRECTION_RAIL_VEHICLE))); + } + // next t = t->GetNextUnit(); tv = tv->GetNextUnit(); diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 55e33ce065..f7edfe77bc 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -5786,6 +5786,9 @@ CommandCost CmdTemplateReplaceVehicle(TileIndex tile, DoCommandFlag flags, uint3 uint32 cb = GetCmdRefitVeh(tmp_chain); DoCommand(tmp_chain->tile, tmp_chain->index, store_refit_ct | (store_refit_csubt << 8) | (1 << 16) | (1 << 31), flags, cb); } + if (HasBit(tmp_chain->flags, VRF_REVERSE_DIRECTION) != HasBit(cur_tmpl->ctrl_flags, TVCF_REVERSED)) { + DoCommand(tmp_chain->tile, tmp_chain->index, true, flags, CMD_REVERSE_TRAIN_DIRECTION | CMD_MSG(STR_ERROR_CAN_T_REVERSE_DIRECTION_RAIL_VEHICLE)); + } } cur_tmpl = cur_tmpl->GetNextUnit(); last_veh = tmp_chain; diff --git a/src/vehicle_cmd.cpp b/src/vehicle_cmd.cpp index e8edef1f5e..82d5d669da 100644 --- a/src/vehicle_cmd.cpp +++ b/src/vehicle_cmd.cpp @@ -1016,6 +1016,7 @@ Train* VirtualTrainFromTemplateVehicle(const TemplateVehicle* tv, StringID &err, for (tv = tv_head, tmp = head; tv != nullptr && tmp != nullptr; tv = tv->Next(), tmp = tmp->Next()) { tmp->cargo_type = tv->cargo_type; tmp->cargo_subtype = tv->cargo_subtype; + SB(tmp->flags, VRF_REVERSE_DIRECTION, 1, HasBit(tv->ctrl_flags, TVCF_REVERSED) ? 1 : 0); } _new_vehicle_id = head->index; @@ -1064,6 +1065,7 @@ CommandCost CmdVirtualTrainFromTrain(TileIndex tile, DoCommandFlag flags, uint32 tmp->cargo_type = train->cargo_type; tmp->cargo_subtype = train->cargo_subtype; + SB(tmp->flags, VRF_REVERSE_DIRECTION, 1, HasBit(train->flags, VRF_REVERSE_DIRECTION) ? 1 : 0); CmdMoveRailVehicle(0, DC_EXEC, (1 << 21) | tmp->index, tail->index, 0); tail = tmp;