summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbjarni <bjarni@openttd.org>2005-11-04 20:52:03 +0000
committerbjarni <bjarni@openttd.org>2005-11-04 20:52:03 +0000
commit7715deec3d18e01a237d6a8f1dfcf34371269701 (patch)
treef0b7357cde7bfd2bcef2b23568f76a497746e37d
parent170de2019a0cb7dd12dc2f0e24f8b60e49e483f1 (diff)
downloadopenttd-7715deec3d18e01a237d6a8f1dfcf34371269701.tar.xz
(svn r3136) -Fix: [autoreplace] all cargo in engines that consists of more than one vehicle will try to move cargo from all vehicles
currently this applies to planes and multiheaded train engines (no more lost airmail) added GetNextEnginePart() that returns the next vehicle in an engine nomatter what type it is when more types of multivehicle engines are added, they will have to be added here too or autoreplace will not remove all cargo
-rw-r--r--train_cmd.c2
-rw-r--r--vehicle.c71
-rw-r--r--vehicle.h1
3 files changed, 61 insertions, 13 deletions
diff --git a/train_cmd.c b/train_cmd.c
index c85c90540..7ca2ba5db 100644
--- a/train_cmd.c
+++ b/train_cmd.c
@@ -961,7 +961,7 @@ int32 CmdStartStopTrain(int x, int y, uint32 flags, uint32 p1, uint32 p2)
* engine is 'started', first 'close' that before 'closing' our
* searched engine
*/
-static Vehicle *GetRearEngine(const Vehicle *v, EngineID engine)
+Vehicle *GetRearEngine(const Vehicle *v, EngineID engine)
{
Vehicle *u;
int en_count = 1;
diff --git a/vehicle.c b/vehicle.c
index 21742b4bf..ae21c5b19 100644
--- a/vehicle.c
+++ b/vehicle.c
@@ -1446,6 +1446,32 @@ void AgeVehicle(Vehicle *v)
}
}
+/*
+ * This function returns the next vehicle in an engine that consists of more than one vehicle
+ * This is planes, multiheaded train engines and so on. It's NOT whole trains as it is only the engines, that are linked together
+ */
+static Vehicle *GetNextEnginePart(Vehicle *v)
+{
+ switch (v->type) {
+ case VEH_Train:
+ {
+ const RailVehicleInfo *rvi = RailVehInfo(v->engine_type);
+ if (rvi->flags & RVI_MULTIHEAD)
+ return GetRearEngine(v, v->engine_type);
+ }
+ break;
+ case VEH_Aircraft:
+ return v->next;
+ break;
+ case VEH_Road:
+ case VEH_Ship:
+ break;
+ default: NOT_REACHED();
+ }
+ return NULL;
+}
+
+
/** Clone a vehicle. If it is a train, it will clone all the cars too
* @param x,y depot where the cloned vehicle is build
* @param p1 the original vehicle's index
@@ -1525,6 +1551,37 @@ int32 CmdCloneVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2)
return total_cost;
}
+/*
+ * move the cargo from one engine to another if possible
+ */
+static void MoveVehicleCargo(Vehicle *dest, Vehicle *source)
+{
+ Vehicle *v = dest;
+ int units_moved;
+
+ do {
+ do {
+ if (source->cargo_type != dest->cargo_type)
+ continue; // cargo not compatible
+
+ if (dest->cargo_count == dest->cargo_cap)
+ continue; // the destination vehicle is already full
+
+ units_moved = min(source->cargo_count, dest->cargo_cap - dest->cargo_count);
+ source->cargo_count -= units_moved;
+ dest->cargo_count += units_moved;
+ dest->cargo_source = source->cargo_source;
+
+ // copy the age of the cargo
+ dest->cargo_days = source->cargo_days;
+ dest->day_counter = source->day_counter;
+ dest->tick_counter = source->tick_counter;
+
+ } while (source->cargo_count > 0 && (dest = GetNextEnginePart(dest)) != NULL);
+ dest = v;
+ } while ((source = GetNextEnginePart(source)) != NULL);
+}
+
/* Replaces a vehicle (used to be called autorenew)
* This function is only called from MaybeReplaceVehicle(), which is the next one
* Must be called with _current_player set to the owner of the vehicle
@@ -1535,7 +1592,7 @@ int32 CmdCloneVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2)
static int32 ReplaceVehicle(Vehicle **w, byte flags)
{
int32 cost;
- const Vehicle *old_v = *w;
+ Vehicle *old_v = *w;
const Player *p = GetPlayer(old_v->owner);
EngineID new_engine_type;
const UnitID cached_unitnumber = old_v->unitnumber;
@@ -1560,17 +1617,7 @@ static int32 ReplaceVehicle(Vehicle **w, byte flags)
}
}
- /* move the cargo to the new vehicle */
- if (old_v->cargo_type == new_v->cargo_type && old_v->cargo_count != 0) {
- // move the cargo to the new vehicle
- new_v->cargo_count = min(old_v->cargo_count, new_v->cargo_cap);
- new_v->cargo_source = old_v->cargo_source;
-
- // copy the age of the cargo
- new_v->cargo_days = old_v->cargo_days;
- new_v->day_counter = old_v->day_counter;
- new_v->tick_counter = old_v->tick_counter;
- }
+ MoveVehicleCargo(new_v, old_v);
if (old_v->type == VEH_Train && old_v->u.rail.first_engine != INVALID_VEHICLE) {
/* this is a railcar. We need to move the car into the train
diff --git a/vehicle.h b/vehicle.h
index 9954216ff..0773d9231 100644
--- a/vehicle.h
+++ b/vehicle.h
@@ -325,6 +325,7 @@ void DecreaseVehicleValue(Vehicle *v);
void CheckVehicleBreakdown(Vehicle *v);
void AgeVehicle(Vehicle *v);
void VehicleEnteredDepotThisTick(Vehicle *v);
+Vehicle *GetRearEngine(const Vehicle *v, EngineID engine);
void BeginVehicleMove(Vehicle *v);
void EndVehicleMove(Vehicle *v);