(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!
This commit is contained in:
		
							
								
								
									
										57
									
								
								economy.c
									
									
									
									
									
								
							
							
						
						
									
										57
									
								
								economy.c
									
									
									
									
									
								
							@@ -1200,6 +1200,59 @@ static int32 DeliverGoods(int num_pieces, byte cargo_type, byte source, byte des
 | 
				
			|||||||
	return profit;
 | 
						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 LoadUnloadVehicle(Vehicle *v)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int profit = 0;
 | 
						int profit = 0;
 | 
				
			||||||
@@ -1279,6 +1332,10 @@ int LoadUnloadVehicle(Vehicle *v)
 | 
				
			|||||||
			if (v->cargo_count == 0)
 | 
								if (v->cargo_count == 0)
 | 
				
			||||||
				TriggerVehicle(v, VEHICLE_TRIGGER_NEW_CARGO);
 | 
									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
 | 
								/* TODO: Regarding this, when we do gradual loading, we
 | 
				
			||||||
			 * should first unload all vehicles and then start
 | 
								 * should first unload all vehicles and then start
 | 
				
			||||||
			 * loading them. Since this will cause
 | 
								 * loading them. Since this will cause
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -978,6 +978,7 @@ STR_CONFIG_PATCHES_MAMMOTHTRAINS		:{LTBLUE}Enable building very long trains: {OR
 | 
				
			|||||||
STR_CONFIG_PATCHES_REALISTICACCEL		:{LTBLUE}Enable realistic acceleration for trains: {ORANGE}{STRING}
 | 
					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_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_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_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_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}
 | 
					STR_CONFIG_PATCHES_LONGBRIDGES			:{LTBLUE}Allow building very long bridges: {ORANGE}{STRING}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -796,6 +796,7 @@ static const SettingDesc patch_settings[] = {
 | 
				
			|||||||
	{"join_stations",				SDT_BOOL,		(void*)true,	(void*)offsetof(Patches, join_stations),				NULL},
 | 
						{"join_stations",				SDT_BOOL,		(void*)true,	(void*)offsetof(Patches, join_stations),				NULL},
 | 
				
			||||||
	{"station_spread",			SDT_UINT8,	(void*)12,		(void*)offsetof(Patches, station_spread),				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},
 | 
						{"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},
 | 
						{"order_review_system", SDT_UINT8,	(void*)2,			(void*)offsetof(Patches, order_review_system),	NULL},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{"inflation",						SDT_BOOL,		(void*)true,	(void*)offsetof(Patches, inflation),						NULL},
 | 
						{"inflation",						SDT_BOOL,		(void*)true,	(void*)offsetof(Patches, inflation),						NULL},
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -621,6 +621,7 @@ static const PatchEntry _patches_vehicles[] = {
 | 
				
			|||||||
static const PatchEntry _patches_stations[] = {
 | 
					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_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_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_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_NEW_NONSTOP,			&_patches.new_nonstop,							0,  0,  0, NULL},
 | 
				
			||||||
	{PE_BOOL,		0, STR_CONFIG_PATCHES_NONUNIFORM_STATIONS, &_patches.nonuniform_stations,		0,  0,  0, NULL},
 | 
						{PE_BOOL,		0, STR_CONFIG_PATCHES_NONUNIFORM_STATIONS, &_patches.nonuniform_stations,		0,  0,  0, NULL},
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -87,6 +87,7 @@ typedef struct Patches {
 | 
				
			|||||||
	bool mammoth_trains;		// allow very long trains
 | 
						bool mammoth_trains;		// allow very long trains
 | 
				
			||||||
	bool join_stations;			// allow joining of train stations
 | 
						bool join_stations;			// allow joining of train stations
 | 
				
			||||||
	bool full_load_any;			// new full load calculation, any cargo must be full
 | 
						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
 | 
						byte station_spread;		// amount a station may spread
 | 
				
			||||||
	bool inflation;					// disable inflation
 | 
						bool inflation;					// disable inflation
 | 
				
			||||||
	bool selectgoods;       // only send the goods to station if a train has been there
 | 
						bool selectgoods;       // only send the goods to station if a train has been there
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user