From 9f5555041782d22a2c20b894c3e53c8fb05473e4 Mon Sep 17 00:00:00 2001
From: Jonathan G Rennison
Date: Thu, 1 Feb 2024 18:48:07 +0000
Subject: [PATCH] Multi-cargo ships: Sprite group cargo thresholds refer to
entire ship
---
docs/newgrf-additions-nml.html | 2 ++
docs/newgrf-additions.html | 1 +
src/newgrf_engine.cpp | 12 +++++++++++-
src/newgrf_extension.cpp | 2 +-
4 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/docs/newgrf-additions-nml.html b/docs/newgrf-additions-nml.html
index 9818ff6ba9..0c5c923dea 100644
--- a/docs/newgrf-additions-nml.html
+++ b/docs/newgrf-additions-nml.html
@@ -83,6 +83,8 @@
The default graphics chain for the primary vehicle may check the cargo states of the other ship parts if required.
Additional ship parts may be refitted individually.
This requires the multi_part_ships feature.
+
+ From version 3 of the multi_part_ships feature, spritegroup loading/loaded cargo thresholds refer to the entire ship, not just the first vehicle.
Added callback: refit_part_name
diff --git a/docs/newgrf-additions.html b/docs/newgrf-additions.html
index a58adc28ef..19865ccc89 100644
--- a/docs/newgrf-additions.html
+++ b/docs/newgrf-additions.html
@@ -975,6 +975,7 @@
Additional ship parts may be refitted individually.
This is indicated by the feature name: multi_part_ships, version 1
+ From version 3 of the multi_part_ships feature, Action 2 loadtypes/loadingtypes cargo thresholds refer to the entire ship, not just the first vehicle.
Callback EC008002 - Ship part name for refit window
This callback is called on the primary vehicle to get the name of each part of the ship (e.g. the name of each cargo hold) in the refit window.
This is not called for ships of only one part.
diff --git a/src/newgrf_engine.cpp b/src/newgrf_engine.cpp
index f1d50d553a..2c6b9cad5d 100644
--- a/src/newgrf_engine.cpp
+++ b/src/newgrf_engine.cpp
@@ -1151,8 +1151,18 @@ static uint32_t VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *objec
uint totalsets = in_motion ? (uint)group->loaded.size() : (uint)group->loading.size();
if (totalsets == 0) return nullptr;
+ if (totalsets == 1) return in_motion ? group->loaded[0] : group->loading[0];
- uint set = (v->cargo.StoredCount() * totalsets) / std::max(1u, v->cargo_cap);
+ uint stored = v->cargo.StoredCount();
+ uint capacity = v->cargo_cap;
+ if (v->type == VEH_SHIP) {
+ for (const Vehicle *u = v->Next(); u != nullptr; u = u->Next()) {
+ stored += u->cargo.StoredCount();
+ capacity += u->cargo_cap;
+ }
+ }
+
+ uint set = (stored * totalsets) / std::max(1u, capacity);
set = std::min(set, totalsets - 1);
return in_motion ? group->loaded[set] : group->loading[set];
diff --git a/src/newgrf_extension.cpp b/src/newgrf_extension.cpp
index 6c19e29487..a5aebb8030 100644
--- a/src/newgrf_extension.cpp
+++ b/src/newgrf_extension.cpp
@@ -72,7 +72,7 @@ extern const GRFFeatureInfo _grf_feature_list[] = {
GRFFeatureInfo("town_zone_callback", 1, GFTOF_TOWN_ZONE_CALLBACK),
GRFFeatureInfo("varaction2_towns_town_xy", 1),
GRFFeatureInfo("more_varaction2_types", 1, GFTOF_MORE_VARACTION2_TYPES),
- GRFFeatureInfo("multi_part_ships", 2, GFTOF_MULTI_PART_SHIPS),
+ GRFFeatureInfo("multi_part_ships", 3, GFTOF_MULTI_PART_SHIPS),
GRFFeatureInfo("more_stations_per_grf", 1),
GRFFeatureInfo(),
};