summaryrefslogtreecommitdiff
path: root/src/autoreplace_cmd.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/autoreplace_cmd.cpp')
-rw-r--r--src/autoreplace_cmd.cpp31
1 files changed, 30 insertions, 1 deletions
diff --git a/src/autoreplace_cmd.cpp b/src/autoreplace_cmd.cpp
index ea4124e1f..264354085 100644
--- a/src/autoreplace_cmd.cpp
+++ b/src/autoreplace_cmd.cpp
@@ -90,6 +90,33 @@ bool CheckAutoreplaceValidity(EngineID from, EngineID to, CompanyID company)
}
/**
+ * Check the capacity of all vehicles in a chain and spread cargo if needed.
+ * @param v The vehicle to check.
+ */
+void CheckCargoCapacity(Vehicle *v)
+{
+ assert(v == NULL || v->First() == v);
+
+ for (Vehicle *src = v; src != NULL; src = src->Next()) {
+ /* Do we need to more cargo away? */
+ if (src->cargo.Count() <= src->cargo_cap) continue;
+
+ /* We need to move a particular amount. Try that on the other vehicles. */
+ uint to_spread = src->cargo.Count() - src->cargo_cap;
+ for (Vehicle *dest = v; dest != NULL && to_spread != 0; dest = dest->Next()) {
+ if (dest->cargo.Count() >= dest->cargo_cap || dest->cargo_type != src->cargo_type) continue;
+
+ uint amount = min(to_spread, dest->cargo_cap - dest->cargo.Count());
+ src->cargo.MoveTo(&dest->cargo, amount, VehicleCargoList::MTA_UNLOAD, NULL);
+ to_spread -= amount;
+ }
+
+ /* Any left-overs will be thrown away, but not their feeder share. */
+ src->cargo.Truncate(src->cargo_cap);
+ }
+}
+
+/**
* Transfer cargo from a single (articulated )old vehicle to the new vehicle chain
* @param old_veh Old vehicle that will be sold
* @param new_head Head of the completely constructed new vehicle chain
@@ -297,7 +324,7 @@ static inline CommandCost CmdStartStopVehicle(const Vehicle *v, bool evaluate_ca
*/
static inline CommandCost CmdMoveVehicle(const Vehicle *v, const Vehicle *after, DoCommandFlag flags, bool whole_chain)
{
- return DoCommand(0, v->index | (whole_chain ? 1 : 0) << 20, after != NULL ? after->index : INVALID_VEHICLE, flags, CMD_MOVE_RAIL_VEHICLE);
+ return DoCommand(0, v->index | (whole_chain ? 1 : 0) << 20, after != NULL ? after->index : INVALID_VEHICLE, flags | DC_NO_CARGO_CAP_CHECK, CMD_MOVE_RAIL_VEHICLE);
}
/**
@@ -551,6 +578,8 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
if (i == 0) old_head = NULL;
}
}
+
+ if ((flags & DC_EXEC) != 0) CheckCargoCapacity(new_head);
}
/* If we are not in DC_EXEC undo everything, i.e. rearrange old vehicles.