mirror of https://github.com/OpenTTD/OpenTTD
(svn r9838) -Fix: make "improved loading" a proper improved loading instead of loading one (semi-)random vehicle at a time:
- Now it is really FIFO. - When there is enough cargo to fill the first vehicle in the queue, the next vehicle in the queue start loading (and the next when ....).release/0.6
parent
b80e11c44c
commit
72662e15f9
105
src/economy.cpp
105
src/economy.cpp
|
@ -1323,61 +1323,6 @@ static int32 DeliverGoods(int num_pieces, CargoID cargo_type, StationID source,
|
||||||
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;
|
|
||||||
bool has_any_cargo = false;
|
|
||||||
|
|
||||||
if (!(u->current_order.flags & 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const Station *st = GetStation(u->last_station_visited);
|
|
||||||
std::list<Vehicle *>::const_iterator iter;
|
|
||||||
for (iter = st->loading_vehicles.begin(); iter != st->loading_vehicles.end(); ++iter) {
|
|
||||||
const Vehicle *x = *iter;
|
|
||||||
if (!(x->vehstatus & (VS_STOPPED | VS_CRASHED)) && u != x) {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs the vehicle payment _and_ marks the vehicle to be unloaded.
|
* Performs the vehicle payment _and_ marks the vehicle to be unloaded.
|
||||||
* @param front_v the vehicle to be unloaded
|
* @param front_v the vehicle to be unloaded
|
||||||
|
@ -1481,13 +1426,25 @@ void VehiclePayment(Vehicle *front_v)
|
||||||
/**
|
/**
|
||||||
* Loads/unload the vehicle if possible.
|
* Loads/unload the vehicle if possible.
|
||||||
* @param v the vehicle to be (un)loaded
|
* @param v the vehicle to be (un)loaded
|
||||||
|
* @param cargo_left the amount of each cargo type that is
|
||||||
|
* virtually left on the platform to be
|
||||||
|
* picked up by another vehicle when all
|
||||||
|
* previous vehicles have loaded.
|
||||||
*/
|
*/
|
||||||
static void LoadUnloadVehicle(Vehicle *v)
|
static void LoadUnloadVehicle(Vehicle *v, int *cargo_left)
|
||||||
{
|
{
|
||||||
assert(v->current_order.type == OT_LOADING);
|
assert(v->current_order.type == OT_LOADING);
|
||||||
|
|
||||||
/* We have not waited enough time till the next round of loading/unloading */
|
/* We have not waited enough time till the next round of loading/unloading */
|
||||||
if (--v->load_unload_time_rem != 0) return;
|
if (--v->load_unload_time_rem != 0) {
|
||||||
|
if (_patches.improved_load && HASBIT(v->current_order.flags, OFB_FULL_LOAD)) {
|
||||||
|
/* 'Reserve' this cargo for this vehicle, because we were first. */
|
||||||
|
for (; v != NULL; v = v->next) {
|
||||||
|
if (v->cargo_cap != 0) cargo_left[v->cargo_type] -= v->cargo_cap - v->cargo_count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int unloading_time = 0;
|
int unloading_time = 0;
|
||||||
Vehicle *u = v;
|
Vehicle *u = v;
|
||||||
|
@ -1598,15 +1555,23 @@ static void LoadUnloadVehicle(Vehicle *v)
|
||||||
if (count != 0 &&
|
if (count != 0 &&
|
||||||
(cap = v->cargo_cap - v->cargo_count) != 0) {
|
(cap = v->cargo_cap - v->cargo_count) != 0) {
|
||||||
|
|
||||||
if (v->cargo_count == 0) TriggerVehicle(v, VEHICLE_TRIGGER_NEW_CARGO);
|
|
||||||
|
|
||||||
/* Skip loading this vehicle if another train/vehicle is already handling
|
/* Skip loading this vehicle if another train/vehicle is already handling
|
||||||
* the same cargo type at this station */
|
* the same cargo type at this station */
|
||||||
if (_patches.improved_load && (u->current_order.flags & OF_FULL_LOAD) && LoadWait(v,u)) {
|
if (_patches.improved_load && cargo_left[v->cargo_type] < 0) {
|
||||||
SETBIT(cargo_not_full, v->cargo_type);
|
SETBIT(cargo_not_full, v->cargo_type);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cap > count) cap = count;
|
||||||
|
if (_patches.gradual_loading) cap = min(cap, load_amount);
|
||||||
|
if (_patches.improved_load) {
|
||||||
|
/* Don't load stuff that is already 'reserved' for other vehicles */
|
||||||
|
cap = min(cargo_left[v->cargo_type], cap);
|
||||||
|
cargo_left[v->cargo_type] -= cap;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v->cargo_count == 0) TriggerVehicle(v, VEHICLE_TRIGGER_NEW_CARGO);
|
||||||
|
|
||||||
/* 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
|
||||||
|
@ -1617,9 +1582,6 @@ static void LoadUnloadVehicle(Vehicle *v)
|
||||||
completely_empty = false;
|
completely_empty = false;
|
||||||
anything_loaded = true;
|
anything_loaded = true;
|
||||||
|
|
||||||
if (cap > count) cap = count;
|
|
||||||
if (_patches.gradual_loading) cap = min(cap, load_amount);
|
|
||||||
|
|
||||||
/* cargoshare is proportioned by the amount due to unload
|
/* cargoshare is proportioned by the amount due to unload
|
||||||
* Otherwise, with gradual loading, 100% of credits would be taken immediately,
|
* Otherwise, with gradual loading, 100% of credits would be taken immediately,
|
||||||
* even if the cargo volume represents a tiny percent of the whole.
|
* even if the cargo volume represents a tiny percent of the whole.
|
||||||
|
@ -1652,6 +1614,17 @@ static void LoadUnloadVehicle(Vehicle *v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We update these variables here, so gradual loading still fills
|
||||||
|
* all wagons at the same time instead of using the same 'improved'
|
||||||
|
* loading algorithm for the wagons (only fill wagon when there is
|
||||||
|
* enough to fill the previous wagons) */
|
||||||
|
if (_patches.improved_load && HASBIT(u->current_order.flags, OFB_FULL_LOAD)) {
|
||||||
|
/* Update left cargo */
|
||||||
|
for (v = u; v != NULL; v = v->next) {
|
||||||
|
if (v->cargo_cap != 0) cargo_left[v->cargo_type] -= v->cargo_cap - v->cargo_count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
v = u;
|
v = u;
|
||||||
|
|
||||||
v->cargo_feeder_share += total_cargo_feeder_share;
|
v->cargo_feeder_share += total_cargo_feeder_share;
|
||||||
|
@ -1716,10 +1689,14 @@ static void LoadUnloadVehicle(Vehicle *v)
|
||||||
*/
|
*/
|
||||||
void LoadUnloadStation(Station *st)
|
void LoadUnloadStation(Station *st)
|
||||||
{
|
{
|
||||||
|
int cargo_left[NUM_CARGO];
|
||||||
|
|
||||||
|
for (uint i = 0; i < NUM_CARGO; i++) cargo_left[i] = GB(st->goods[i].waiting_acceptance, 0, 12);
|
||||||
|
|
||||||
std::list<Vehicle *>::iterator iter;
|
std::list<Vehicle *>::iterator iter;
|
||||||
for (iter = st->loading_vehicles.begin(); iter != st->loading_vehicles.end(); ++iter) {
|
for (iter = st->loading_vehicles.begin(); iter != st->loading_vehicles.end(); ++iter) {
|
||||||
Vehicle *v = *iter;
|
Vehicle *v = *iter;
|
||||||
if (!(v->vehstatus & (VS_STOPPED | VS_CRASHED))) LoadUnloadVehicle(v);
|
if (!(v->vehstatus & (VS_STOPPED | VS_CRASHED))) LoadUnloadVehicle(v, cargo_left);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue