(svn r853) -Feature: Implement improved vehicle loading algorithm
authortron
Mon, 29 Nov 2004 11:59:09 +0000
changeset 523 8871819c9afd
parent 522 1e76cdcafda9
child 524 bcbcedbf5ccd
(svn r853) -Feature: Implement improved vehicle loading algorithm
It's not FIFO loading, but does the right thing in the common case:
If a vehicle is empty and another vehicle is already loading the same cargo at this station then the vehicle waits.

This is an reworked version of [ 1072211 ] submitted by Hackykid, thanks!
economy.c
lang/english.txt
settings.c
settings_gui.c
variables.h
--- a/economy.c	Sun Nov 28 22:43:46 2004 +0000
+++ b/economy.c	Mon Nov 29 11:59:09 2004 +0000
@@ -1200,6 +1200,59 @@
 	return profit;
 }
 
+/*
+ * Returns true if Vehicle v should wait loading because other vehicle is
+ * already loading the same cargo type
+ * v = vehicle to load, u = GetFirstInChain(v)
+ */
+static bool LoadWait(const Vehicle *v, const Vehicle *u) {
+	const Vehicle *w;
+	const Vehicle *x;
+	bool has_any_cargo = false;
+
+	if (!(u->next_order & OF_FULL_LOAD)) return false;
+
+	for (w = u; w != NULL; w = w->next) {
+		if (w->cargo_count != 0) {
+			if (v->cargo_type == w->cargo_type &&
+					u->last_station_visited == w->cargo_source)
+				return false;
+			has_any_cargo = true;
+		}
+	}
+
+	FOR_ALL_VEHICLES(x) {
+		if ((x->type != VEH_Train || x->subtype == 0) && // for all locs
+				u->last_station_visited == x->last_station_visited && // at the same station
+				!(x->vehstatus & VS_STOPPED) && // not stopped
+				(x->next_order & OT_MASK) == OT_LOADING && // loading
+				u != x) { // not itself
+			bool other_has_any_cargo = false;
+			bool has_space_for_same_type = false;
+			bool other_has_same_type = false;
+
+			for (w = x; w != NULL; w = w->next) {
+				if (w->cargo_count < w->cargo_cap && v->cargo_type == w->cargo_type)
+					has_space_for_same_type = true;
+
+				if (w->cargo_count != 0) {
+					if (v->cargo_type == w->cargo_type &&
+							u->last_station_visited == w->cargo_source)
+						other_has_same_type = true;
+					other_has_any_cargo = true;
+				}
+			}
+
+			if (has_space_for_same_type) {
+				if (other_has_same_type) return true;
+				if (other_has_any_cargo && !has_any_cargo) return true;
+			}
+		}
+	}
+
+	return false;
+}
+
 int LoadUnloadVehicle(Vehicle *v)
 {
 	int profit = 0;
@@ -1279,6 +1332,10 @@
 			if (v->cargo_count == 0)
 				TriggerVehicle(v, VEHICLE_TRIGGER_NEW_CARGO);
 
+			/* Skip loading this vehicle if another train/vehicle is already handling
+			 * the same cargo type at this station */
+			if (_patches.improved_load && LoadWait(v,u)) continue;
+
 			/* TODO: Regarding this, when we do gradual loading, we
 			 * should first unload all vehicles and then start
 			 * loading them. Since this will cause
--- a/lang/english.txt	Sun Nov 28 22:43:46 2004 +0000
+++ b/lang/english.txt	Mon Nov 29 11:59:09 2004 +0000
@@ -978,6 +978,7 @@
 STR_CONFIG_PATCHES_REALISTICACCEL		:{LTBLUE}Enable realistic acceleration for trains: {ORANGE}{STRING}
 STR_CONFIG_PATCHES_JOINSTATIONS			:{LTBLUE}Join train stations built next to each other: {ORANGE}{STRING}
 STR_CONFIG_PATCHES_FULLLOADANY			:{LTBLUE}Leave station when any cargo is full, if 'full load': {ORANGE}{STRING}
+STR_CONFIG_PATCHES_IMPROVEDLOAD 		:{LTBLUE}Use improved loading algorithm: {ORANGE}{STRING}
 STR_CONFIG_PATCHES_INFLATION				:{LTBLUE}Inflation: {ORANGE}{STRING}
 STR_CONFIG_PATCHES_SELECTGOODS			:{LTBLUE}Deliver cargo to a station only when there is a demand: {ORANGE}{STRING}
 STR_CONFIG_PATCHES_LONGBRIDGES			:{LTBLUE}Allow building very long bridges: {ORANGE}{STRING}
--- a/settings.c	Sun Nov 28 22:43:46 2004 +0000
+++ b/settings.c	Mon Nov 29 11:59:09 2004 +0000
@@ -796,6 +796,7 @@
 	{"join_stations",				SDT_BOOL,		(void*)true,	(void*)offsetof(Patches, join_stations),				NULL},
 	{"station_spread",			SDT_UINT8,	(void*)12,		(void*)offsetof(Patches, station_spread),				NULL},
 	{"full_load_any",				SDT_BOOL,		(void*)true,	(void*)offsetof(Patches, full_load_any),				NULL},
+	{"improved_load",				SDT_BOOL,		(void*)false, (void*)offsetof(Patches, improved_load),				NULL},
 	{"order_review_system", SDT_UINT8,	(void*)2,			(void*)offsetof(Patches, order_review_system),	NULL},
 
 	{"inflation",						SDT_BOOL,		(void*)true,	(void*)offsetof(Patches, inflation),						NULL},
--- a/settings_gui.c	Sun Nov 28 22:43:46 2004 +0000
+++ b/settings_gui.c	Mon Nov 29 11:59:09 2004 +0000
@@ -621,6 +621,7 @@
 static const PatchEntry _patches_stations[] = {
 	{PE_BOOL,		0, STR_CONFIG_PATCHES_JOINSTATIONS,			&_patches.join_stations,						0,  0,  0, NULL},
 	{PE_BOOL,		0, STR_CONFIG_PATCHES_FULLLOADANY,			&_patches.full_load_any,						0,  0,  0, NULL},
+	{PE_BOOL,		0, STR_CONFIG_PATCHES_IMPROVEDLOAD,			&_patches.improved_load,						0,  0,  0, NULL},
 	{PE_BOOL,		0, STR_CONFIG_PATCHES_SELECTGOODS,			&_patches.selectgoods,							0,  0,  0, NULL},
 	{PE_BOOL,		0, STR_CONFIG_PATCHES_NEW_NONSTOP,			&_patches.new_nonstop,							0,  0,  0, NULL},
 	{PE_BOOL,		0, STR_CONFIG_PATCHES_NONUNIFORM_STATIONS, &_patches.nonuniform_stations,		0,  0,  0, NULL},
--- a/variables.h	Sun Nov 28 22:43:46 2004 +0000
+++ b/variables.h	Mon Nov 29 11:59:09 2004 +0000
@@ -87,6 +87,7 @@
 	bool mammoth_trains;		// allow very long trains
 	bool join_stations;			// allow joining of train stations
 	bool full_load_any;			// new full load calculation, any cargo must be full
+	bool improved_load;			// improved loading algorithm
 	byte station_spread;		// amount a station may spread
 	bool inflation;					// disable inflation
 	bool selectgoods;       // only send the goods to station if a train has been there