From d701668f50de51f7cac62fda6911135a7332b515 Mon Sep 17 00:00:00 2001 From: tron Date: Mon, 29 Nov 2004 11:59:09 +0000 Subject: [PATCH] (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 | 57 ++++++++++++++++++++++++++++++++++++++++++++++++ lang/english.txt | 1 + settings.c | 1 + settings_gui.c | 1 + variables.h | 1 + 5 files changed, 61 insertions(+) diff --git a/economy.c b/economy.c index b4166562e5..ed30e4bdd6 100644 --- a/economy.c +++ b/economy.c @@ -1200,6 +1200,59 @@ static int32 DeliverGoods(int num_pieces, byte cargo_type, byte source, byte des 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 @@ int LoadUnloadVehicle(Vehicle *v) 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 diff --git a/lang/english.txt b/lang/english.txt index 0d2b79ab9a..a63b9d45b1 100644 --- a/lang/english.txt +++ b/lang/english.txt @@ -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_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} diff --git a/settings.c b/settings.c index 4c0e8a083c..2081cffb88 100644 --- a/settings.c +++ b/settings.c @@ -796,6 +796,7 @@ static const SettingDesc patch_settings[] = { {"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}, diff --git a/settings_gui.c b/settings_gui.c index 476a7f01fb..052296c1bb 100644 --- a/settings_gui.c +++ b/settings_gui.c @@ -621,6 +621,7 @@ static const PatchEntry _patches_vehicles[] = { 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}, diff --git a/variables.h b/variables.h index d96a8bd242..68fb1f3315 100644 --- a/variables.h +++ b/variables.h @@ -87,6 +87,7 @@ typedef struct Patches { 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