From c6893388abb5fce007dc28872ee1a1cb6c522784 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Mon, 19 Feb 2024 00:24:50 +0000 Subject: [PATCH] Fix order flags collision in OT_GOTO_DEPOT Move depot wait is timetabled flag to xflags --- src/order_base.h | 12 +++++++++--- src/saveload/afterload.cpp | 14 ++++++++++++-- src/sl/extended_ver_sl.cpp | 2 +- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/order_base.h b/src/order_base.h index 13644f2db3..e6a1b3ff51 100644 --- a/src/order_base.h +++ b/src/order_base.h @@ -53,7 +53,7 @@ void ClearOrderDestinationRefcountMap(); /* * xflags bits: - * Bit 0: OT_CONDITIONAL: IsWaitTimetabled(): For branch travel time + * Bit 0: OT_CONDITIONAL and OT_GOTO_DEPOT: IsWaitTimetabled(): Depot: wait is timetabled, conditional: branch travel time * Bit 1: IsWaitFixed(): Wait time fixed * Bits 2-3: GetLeaveType(): Order leave type * Bit 4: IsTravelFixed(): Travel time fixed @@ -170,6 +170,11 @@ public: return this->extra->xdata2; } + inline uint16_t GetRawFlags() const + { + return this->flags; + } + Order *next; ///< Pointer to next order. If nullptr, end of list Order() : flags(0), refit_cargo(CARGO_NO_REFIT), max_speed(UINT16_MAX) {} @@ -475,7 +480,7 @@ public: inline bool IsWaitTimetabled() const { if (this->HasNoTimetableTimes()) return true; - return this->IsType(OT_CONDITIONAL) ? HasBit(this->GetXFlags(), 0) : HasBit(this->flags, 3); + return (this->IsType(OT_CONDITIONAL) || this->IsType(OT_GOTO_DEPOT)) ? HasBit(this->GetXFlags(), 0) : HasBit(this->flags, 3); } /** Does this order have an explicit travel time set? */ inline bool IsTravelTimetabled() const @@ -504,7 +509,8 @@ public: inline void SetWaitTimetabled(bool timetabled) { if (this->HasNoTimetableTimes()) return; - if (this->IsType(OT_CONDITIONAL)) { + if (this->IsType(OT_CONDITIONAL) || this->IsType(OT_GOTO_DEPOT)) { + if (this->extra == nullptr && !timetabled) return; SB(this->GetXFlagsRef(), 0, 1, timetabled ? 1 : 0); } else { SB(this->flags, 3, 1, timetabled ? 1 : 0); diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 2ed2fd8813..713457cc4a 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -2153,15 +2153,25 @@ bool AfterLoadGame() } if (IsSavegameVersionBefore(SLV_DEPOT_UNBUNCHING) && SlXvIsFeatureMissing(XSLFI_DEPOT_UNBUNCHING)) { - /* OrderDepotActionFlags were moved, instead of starting at bit 4 they now start at bit 3. */ + /* OrderDepotActionFlags were moved, instead of starting at bit 4 they now start at bit 3, + * this clobbers the wait is timetabled flag of XSLFI_TT_WAIT_IN_DEPOT (version 1). */ for (Order *order : Order::Iterate()) { if (!order->IsType(OT_GOTO_DEPOT)) continue; + if (SlXvIsFeaturePresent(XSLFI_TT_WAIT_IN_DEPOT, 1, 1)) { + /* Bit 3 was previously the wait is timetabled flag, move that to xflags (version 2 of XSLFI_TT_WAIT_IN_DEPOT) */ + order->SetWaitTimetabled(HasBit(order->GetRawFlags(), 3)); + } OrderDepotActionFlags flags = (OrderDepotActionFlags)(order->GetDepotActionType() >> 1); - if (((flags & (1 << 2)) != 0) && SlXvIsFeatureMissing(XSLFI_DEPOT_UNBUNCHING)) { + if (((flags & (1 << 2)) != 0) && !SlXvIsFeatureMissing(XSLFI_DEPOT_UNBUNCHING)) { flags ^= (ODATFB_SELL | ODATFB_UNBUNCH); // Unbunch moved from bit 2 to bit 3 } order->SetDepotActionType(flags); } + } else if (SlXvIsFeaturePresent(XSLFI_TT_WAIT_IN_DEPOT, 1, 1)) { + for (Order *order : Order::Iterate()) { + /* Bit 3 was previously the wait is timetabled flag, move that to xflags (version 2 of XSLFI_TT_WAIT_IN_DEPOT) */ + if (order->IsType(OT_GOTO_DEPOT)) order->SetWaitTimetabled(HasBit(order->GetRawFlags(), 3)); + } } if (SlXvIsFeaturePresent(XSLFI_JOKERPP, 1, SL_JOKER_1_23)) { diff --git a/src/sl/extended_ver_sl.cpp b/src/sl/extended_ver_sl.cpp index 06db27cd25..3129847c21 100644 --- a/src/sl/extended_ver_sl.cpp +++ b/src/sl/extended_ver_sl.cpp @@ -98,7 +98,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = { { XSLFI_SIG_TUNNEL_BRIDGE, XSCF_NULL, 10, 10, "signal_tunnel_bridge", nullptr, nullptr, "XBSS" }, { XSLFI_IMPROVED_BREAKDOWNS, XSCF_NULL, 8, 8, "improved_breakdowns", nullptr, nullptr, nullptr }, { XSLFI_CONSIST_BREAKDOWN_FLAG, XSCF_NULL, 1, 1, "consist_breakdown_flag", nullptr, nullptr, nullptr }, - { XSLFI_TT_WAIT_IN_DEPOT, XSCF_NULL, 1, 1, "tt_wait_in_depot", nullptr, nullptr, nullptr }, + { XSLFI_TT_WAIT_IN_DEPOT, XSCF_NULL, 2, 2, "tt_wait_in_depot", nullptr, nullptr, nullptr }, { XSLFI_AUTO_TIMETABLE, XSCF_NULL, 5, 5, "auto_timetables", nullptr, nullptr, nullptr }, { XSLFI_VEHICLE_REPAIR_COST, XSCF_NULL, 2, 2, "vehicle_repair_cost", nullptr, nullptr, nullptr }, { XSLFI_ENH_VIEWPORT_PLANS, XSCF_IGNORABLE_ALL, 4, 4, "enh_viewport_plans", nullptr, nullptr, "PLAN" },