From ab94c8b511b0bcf635cb502f9149ae75031b7c88 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 17 Mar 2024 09:34:28 +0000 Subject: [PATCH 1/5] Codechange: Iterate order lists instead of vehicles to find if any vehicle visits a station. (#12315) This reduces the search time as shared orders are only searched once and non-front vehicles are skipped. --- src/station_cmd.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 9f79a1ef4d..75367ce5b6 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -2620,12 +2620,14 @@ CommandCost CmdOpenCloseAirport(DoCommandFlag flags, StationID station_id) */ bool HasStationInUse(StationID station, bool include_company, CompanyID company) { - for (const Vehicle *v : Vehicle::Iterate()) { - if ((v->owner == company) == include_company) { - for (const Order *order : v->Orders()) { - if ((order->IsType(OT_GOTO_STATION) || order->IsType(OT_GOTO_WAYPOINT)) && order->GetDestination() == station) { - return true; - } + for (const OrderList *orderlist : OrderList::Iterate()) { + const Vehicle *v = orderlist->GetFirstSharedVehicle(); + assert(v != nullptr); + if ((v->owner == company) != include_company) continue; + + for (const Order *order = orderlist->GetFirstOrder(); order != nullptr; order = order->next) { + if (order->GetDestination() == station && (order->IsType(OT_GOTO_STATION) || order->IsType(OT_GOTO_WAYPOINT))) { + return true; } } } From f08da1d37398e69104e0a1b5e810b9559553f6c7 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Sun, 17 Mar 2024 14:17:35 +0100 Subject: [PATCH 2/5] Codechange: the "no revision detected" string is with four zeros (norev0000) (#12328) --- src/network/core/tcp_game.h | 2 +- src/rev.cpp.in | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/core/tcp_game.h b/src/network/core/tcp_game.h index 7aed964d51..14310f0017 100644 --- a/src/network/core/tcp_game.h +++ b/src/network/core/tcp_game.h @@ -165,7 +165,7 @@ protected: /** * Try to join the server: - * string OpenTTD revision (norev000 if no revision). + * string OpenTTD revision (norev0000 if no revision). * uint32_t NewGRF version (added in 1.2). * string Name of the client (max NETWORK_NAME_LENGTH) (removed in 15). * uint8_t ID of the company to play as (1..MAX_COMPANIES) (removed in 15). diff --git a/src/rev.cpp.in b/src/rev.cpp.in index 1df8b84898..50e2ee0347 100644 --- a/src/rev.cpp.in +++ b/src/rev.cpp.in @@ -28,7 +28,7 @@ bool IsReleasedVersion() * - "", like "..[-RC]", * - "-g" in "master", * - "--g" in other branches, or - * - "norev000", if the version is unknown. + * - "norev0000", if the version is unknown. * * The major, minor and build are the numbers that describe releases of * OpenTTD (like 0.5.3). "-RC" is used to flag release candidates. From 3fc7b3b9a0a4cc34ae45a75a89a799b665a7bb09 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Thu, 14 Mar 2024 20:40:32 +0000 Subject: [PATCH 3/5] Codechange: Cache train curve speed limit can be stored in 16 bits. Cache curve speed modifier and max curve speed are both 16 bit values so can be stored in 16 bit types instead of 32 bit types. --- src/train.h | 10 ++++------ src/train_cmd.cpp | 6 +++--- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/train.h b/src/train.h index d637d92d37..75fd0e259d 100644 --- a/src/train.h +++ b/src/train.h @@ -75,12 +75,10 @@ struct TrainCache { /* cached values, recalculated on load and each time a vehicle is added to/removed from the consist. */ bool cached_tilt; ///< train can tilt; feature provides a bonus in curves - int cached_curve_speed_mod; ///< curve speed modifier of the entire train - uint8_t user_def_data; ///< Cached property 0x25. Can be set by Callback 0x36. - /* cached max. speed / acceleration data */ - int cached_max_curve_speed; ///< max consist speed limited by curves + int16_t cached_curve_speed_mod; ///< curve speed modifier of the entire train + uint16_t cached_max_curve_speed; ///< max consist speed limited by curves }; /** @@ -132,7 +130,7 @@ struct Train final : public GroundVehicle { void ReserveTrackUnderConsist() const; - int GetCurveSpeedLimit() const; + uint16_t GetCurveSpeedLimit() const; void ConsistChanged(ConsistChangeFlags allowed_changes); @@ -328,7 +326,7 @@ protected: // These functions should not be called outside acceleration code. * Returns the curve speed modifier of this vehicle. * @return Current curve speed modifier, in fixed-point binary representation with 8 fractional bits. */ - inline int GetCurveSpeedModifier() const + inline int16_t GetCurveSpeedModifier() const { return GetVehicleProperty(this, PROP_TRAIN_CURVE_SPEED_MOD, RailVehInfo(this->engine_type)->curve_speed_mod, true); } diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index f969f0203e..4413a2e777 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -120,7 +120,7 @@ void Train::ConsistChanged(ConsistChangeFlags allowed_changes) this->compatible_railtypes = RAILTYPES_NONE; bool train_can_tilt = true; - int min_curve_speed_mod = INT_MAX; + int16_t min_curve_speed_mod = INT16_MAX; for (Train *u = this; u != nullptr; u = u->Next()) { const RailVehicleInfo *rvi_u = RailVehInfo(u->engine_type); @@ -305,7 +305,7 @@ int GetTrainStopLocation(StationID station_id, TileIndex tile, const Train *v, i * Computes train speed limit caused by curves * @return imposed speed limit */ -int Train::GetCurveSpeedLimit() const +uint16_t Train::GetCurveSpeedLimit() const { assert(this->First() == this); @@ -372,7 +372,7 @@ int Train::GetCurveSpeedLimit() const max_speed = Clamp(max_speed, 2, absolute_max_speed); } - return max_speed; + return static_cast(max_speed); } /** From 322ca6ef54c935fb6e17d2ed1162b591e67b0a6a Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Thu, 14 Mar 2024 20:40:33 +0000 Subject: [PATCH 4/5] Codechange: Shuffle members of Vehicle to reduce size. This reduces space wasted due to member alignment. --- src/roadveh.h | 5 ++--- src/ship.h | 2 +- src/train.h | 13 ++++++------- src/vehicle_base.h | 14 +++++++------- 4 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/roadveh.h b/src/roadveh.h index 47e333999e..0907d2f3bd 100644 --- a/src/roadveh.h +++ b/src/roadveh.h @@ -113,10 +113,9 @@ struct RoadVehicle final : public GroundVehicle { uint16_t crashed_ctr; ///< Animation counter when the vehicle has crashed. @see RoadVehIsCrashed uint8_t reverse_ctr; - RoadType roadtype; //!< Roadtype of this vehicle. - RoadTypes compatible_roadtypes; //!< Roadtypes this consist is powered on. - + RoadType roadtype; ///< NOSAVE: Roadtype of this vehicle. VehicleID disaster_vehicle = INVALID_VEHICLE; ///< NOSAVE: Disaster vehicle targetting this vehicle. + RoadTypes compatible_roadtypes; ///< NOSAVE: Roadtypes this consist is powered on. /** We don't want GCC to zero our struct! It already is zeroed and has an index! */ RoadVehicle() : GroundVehicleBase() {} diff --git a/src/ship.h b/src/ship.h index 5335deefeb..c47be05436 100644 --- a/src/ship.h +++ b/src/ship.h @@ -22,8 +22,8 @@ typedef std::deque ShipPathCache; * All ships have this type. */ struct Ship final : public SpecializedVehicle { - TrackBits state; ///< The "track" the ship is following. ShipPathCache path; ///< Cached path. + TrackBits state; ///< The "track" the ship is following. Direction rotation; ///< Visible direction. int16_t rotation_x_pos; ///< NOSAVE: X Position before rotation. int16_t rotation_y_pos; ///< NOSAVE: Y Position before rotation. diff --git a/src/train.h b/src/train.h index 75fd0e259d..fd7b5f7656 100644 --- a/src/train.h +++ b/src/train.h @@ -85,21 +85,20 @@ struct TrainCache { * 'Train' is either a loco or a wagon. */ struct Train final : public GroundVehicle { + uint16_t flags; + uint16_t crash_anim_pos; ///< Crash animation counter. + uint16_t wait_counter; ///< Ticks waiting in front of a signal, ticks being stuck or a counter for forced proceeding through signals. + TrainCache tcache; /* Link between the two ends of a multiheaded engine */ Train *other_multiheaded_part; - uint16_t crash_anim_pos; ///< Crash animation counter. + RailTypes compatible_railtypes; + RailType railtype; - uint16_t flags; TrackBits track; TrainForceProceeding force_proceed; - RailType railtype; - RailTypes compatible_railtypes; - - /** Ticks waiting in front of a signal, ticks being stuck or a counter for forced proceeding through signals. */ - uint16_t wait_counter; /** We don't want GCC to zero our struct! It already is zeroed and has an index! */ Train() : GroundVehicleBase() {} diff --git a/src/vehicle_base.h b/src/vehicle_base.h index adf2c0d610..3c4e2ea65f 100644 --- a/src/vehicle_base.h +++ b/src/vehicle_base.h @@ -191,8 +191,8 @@ struct VehicleSpriteSeq { struct MutableSpriteCache { Direction last_direction; ///< Last direction we obtained sprites for bool revalidate_before_draw; ///< We need to do a GetImage() and check bounds before drawing this sprite - Rect old_coord; ///< Co-ordinates from the last valid bounding box bool is_viewport_candidate; ///< This vehicle can potentially be drawn on a viewport + Rect old_coord; ///< Co-ordinates from the last valid bounding box VehicleSpriteSeq sprite_seq; ///< Vehicle appearance. }; @@ -327,26 +327,28 @@ public: uint32_t motion_counter; ///< counter to occasionally play a vehicle sound. uint8_t progress; ///< The percentage (if divided by 256) this vehicle already crossed the tile unit. - uint16_t random_bits; ///< Bits used for randomized variational spritegroups. uint8_t waiting_triggers; ///< Triggers to be yet matched before rerandomizing the random bits. + uint16_t random_bits; ///< Bits used for randomized variational spritegroups. StationID last_station_visited; ///< The last station we stopped at. StationID last_loading_station; ///< Last station the vehicle has stopped at and could possibly leave from with any cargo loaded. TimerGameTick::TickCounter last_loading_tick; ///< Last TimerGameTick::counter tick that the vehicle has stopped at a station and could possibly leave with any cargo loaded. + VehicleCargoList cargo; ///< The cargo this vehicle is carrying CargoID cargo_type; ///< type of cargo this vehicle is carrying uint8_t cargo_subtype; ///< Used for livery refits (NewGRF variations) uint16_t cargo_cap; ///< total capacity uint16_t refit_cap; ///< Capacity left over from before last refit. - VehicleCargoList cargo; ///< The cargo this vehicle is carrying uint16_t cargo_age_counter; ///< Ticks till cargo is aged next. int8_t trip_occupancy; ///< NOSAVE: Occupancy of vehicle of the current trip (updated after leaving a station). uint8_t day_counter; ///< Increased by one for each day uint8_t tick_counter; ///< Increased by one for each tick uint8_t running_ticks; ///< Number of ticks this vehicle was not stopped this day + uint16_t load_unload_ticks; ///< Ticks to wait before starting next cycle. uint8_t vehstatus; ///< Status + uint8_t subtype; ///< subtype (Filled with values from #AircraftSubType/#DisasterSubType/#EffectVehicleType/#GroundVehicleSubtypeFlags) Order current_order; ///< The current order (+ status, like: loading) union { @@ -354,13 +356,11 @@ public: Order *old_orders; ///< Only used during conversion of old save games }; - uint16_t load_unload_ticks; ///< Ticks to wait before starting next cycle. - GroupID group_id; ///< Index of group Pool array - uint8_t subtype; ///< subtype (Filled with values from #AircraftSubType/#DisasterSubType/#EffectVehicleType/#GroundVehicleSubtypeFlags) - NewGRFCache grf_cache; ///< Cache of often used calculated NewGRF values VehicleCache vcache; ///< Cache of often used vehicle values. + GroupID group_id; ///< Index of group Pool array + mutable MutableSpriteCache sprite_cache; ///< Cache of sprites and values related to recalculating them, see #MutableSpriteCache /** From 88cf99017a26f887230d2c14d057a97bbf077f7c Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 17 Mar 2024 16:23:14 +0000 Subject: [PATCH 5/5] Fix #12302: Allow empty train engines to use an invalid cargo type. (#12325) The cargo type will be forced to the first available type (usually passengers) instead of the engine being disabled. --- src/newgrf.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 9f558a1a5e..20ac05431a 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -9161,6 +9161,14 @@ static void CalculateRefitMasks() ei->cargo_type = (CargoID)FindFirstBit(ei->refit_mask); } } + if (!IsValidCargoID(ei->cargo_type) && e->type == VEH_TRAIN && e->u.rail.railveh_type != RAILVEH_WAGON && e->u.rail.capacity == 0) { + /* For train engines which do not carry cargo it does not matter if their cargo type is invalid. + * Fallback to the first available instead, if the cargo type has not been changed (as indicated by + * cargo_label not being CT_INVALID). */ + if (GetActiveCargoLabel(ei->cargo_label) != CT_INVALID) { + ei->cargo_type = static_cast(FindFirstBit(_standard_cargo_mask)); + } + } if (!IsValidCargoID(ei->cargo_type)) ei->climates = 0; /* Clear refit_mask for not refittable ships */