summaryrefslogtreecommitdiff
path: root/src/vehicle_gui.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/vehicle_gui.cpp')
-rw-r--r--src/vehicle_gui.cpp63
1 files changed, 63 insertions, 0 deletions
diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp
index 614259e34..a9401784f 100644
--- a/src/vehicle_gui.cpp
+++ b/src/vehicle_gui.cpp
@@ -159,6 +159,69 @@ static void DrawVehicleProfitButton(const Vehicle *v, int x, int y)
/** Maximum number of refit cycles we try, to prevent infinite loops. */
static const int MAX_REFIT_CYCLE = 16;
+/**
+ * Get the best fitting subtype when 'cloning'/'replacing' v_from with v_for.
+ * Assuming they are going to carry the same cargo ofcourse!
+ * @param v_from the vehicle to match the subtype from
+ * @param v_for the vehicle to get the subtype for
+ * @return the best sub type
+ */
+byte GetBestFittingSubType(Vehicle *v_from, Vehicle *v_for)
+{
+ const Engine *e_from = Engine::Get(v_from->engine_type);
+ const Engine *e_for = Engine::Get(v_for->engine_type);
+
+ /* If one them doesn't carry cargo, there's no need to find a sub type */
+ if (!e_from->CanCarryCargo() || !e_for->CanCarryCargo()) return 0;
+
+ if (!HasBit(e_from->info.callback_mask, CBM_VEHICLE_CARGO_SUFFIX) ||
+ !HasBit(e_for->info.callback_mask, CBM_VEHICLE_CARGO_SUFFIX)) {
+ /* One of the engines doesn't have cargo suffixes, i.e. sub types. */
+ return 0;
+ }
+
+ /* It has to be possible for v_for to carry the cargo of v_from. */
+ assert(HasBit(e_for->info.refit_mask, v_from->cargo_type));
+
+ StringID expected_string = GetCargoSubtypeText(v_from);
+
+ CargoID old_cargo_type = v_for->cargo_type;
+ byte old_cargo_subtype = v_for->cargo_subtype;
+ byte ret_refit_cyc = 0;
+
+ /* Set the 'destination' cargo */
+ v_for->cargo_type = v_from->cargo_type;
+
+ /* Cycle through the refits */
+ for (byte refit_cyc = 0; refit_cyc < MAX_REFIT_CYCLE; refit_cyc++) {
+ v_for->cargo_subtype = refit_cyc;
+
+ /* Make sure we don't pick up anything cached. */
+ v_for->First()->InvalidateNewGRFCache();
+ v_for->InvalidateNewGRFCache();
+ uint16 callback = GetVehicleCallback(CBID_VEHICLE_CARGO_SUFFIX, 0, 0, v_for->engine_type, v_for);
+
+ if (callback == 0xFF) callback = CALLBACK_FAILED;
+ if (callback == CALLBACK_FAILED) break;
+
+ if (GetCargoSubtypeText(v_for) != expected_string) continue;
+
+ /* We found something matching. */
+ ret_refit_cyc = refit_cyc;
+ break;
+ }
+
+ /* Reset the vehicle's cargo type */
+ v_for->cargo_type = old_cargo_type;
+ v_for->cargo_subtype = old_cargo_subtype;
+
+ /* Make sure we don't taint the vehicle. */
+ v_for->First()->InvalidateNewGRFCache();
+ v_for->InvalidateNewGRFCache();
+
+ return ret_refit_cyc;
+}
+
struct RefitOption {
CargoID cargo;
byte subtype;