1
0
Fork 0

(svn r24497) -Feature [FS#5106]: When using autorefit only load/refit vehicles if other wagons cannot already take all cargo without refitting. This way the consist preserves its refit potential as long as possible, in case other cargo arrives at the station.

release/1.3
frosch 2012-08-25 14:26:14 +00:00
parent c9bcc42aa6
commit be150d3ad0
1 changed files with 46 additions and 8 deletions

View File

@ -1236,6 +1236,16 @@ static void LoadUnloadVehicle(Vehicle *front, int *cargo_left)
return; return;
} }
bool use_autorefit = front->current_order.IsRefit() && front->current_order.GetRefitCargo() == CT_AUTO_REFIT;
CargoArray consist_capleft;
if (use_autorefit) {
/* Sum cargo, that can be loaded without refitting */
for (Vehicle *v = front; v != NULL; v = v->Next()) {
int cap_left = v->cargo_cap - v->cargo.Count();
if (cap_left > 0) consist_capleft[v->cargo_type] += cap_left;
}
}
int unloading_time = 0; int unloading_time = 0;
bool dirty_vehicle = false; bool dirty_vehicle = false;
bool dirty_station = false; bool dirty_station = false;
@ -1352,6 +1362,13 @@ static void LoadUnloadVehicle(Vehicle *front, int *cargo_left)
CargoID new_cid = front->current_order.GetRefitCargo(); CargoID new_cid = front->current_order.GetRefitCargo();
byte new_subtype = front->current_order.GetRefitSubtype(); byte new_subtype = front->current_order.GetRefitSubtype();
/* Remove old capacity from consist capacity */
consist_capleft[v_start->cargo_type] -= v_start->cargo_cap;
for (Vehicle *w = v_start; w->HasArticulatedPart(); ) {
w = w->GetNextArticulatedPart();
consist_capleft[w->cargo_type] -= w->cargo_cap;
}
Backup<CompanyByte> cur_company(_current_company, front->owner, FILE_LINE); Backup<CompanyByte> cur_company(_current_company, front->owner, FILE_LINE);
/* Check if all articulated parts are empty and collect refit mask. */ /* Check if all articulated parts are empty and collect refit mask. */
@ -1368,13 +1385,15 @@ static void LoadUnloadVehicle(Vehicle *front, int *cargo_left)
int amount = 0; int amount = 0;
CargoID cid; CargoID cid;
FOR_EACH_SET_CARGO_ID(cid, refit_mask) { FOR_EACH_SET_CARGO_ID(cid, refit_mask) {
if (cargo_left[cid] > amount) { /* Consider refitting to this cargo, if other vehicles of the consist cannot
* already take the cargo without refitting */
if (cargo_left[cid] > (int)consist_capleft[cid] + amount) {
/* Try to find out if auto-refitting would succeed. In case the refit is allowed, /* Try to find out if auto-refitting would succeed. In case the refit is allowed,
* the returned refit capacity will be greater than zero. */ * the returned refit capacity will be greater than zero. */
new_subtype = GetBestFittingSubType(v, v, cid); new_subtype = GetBestFittingSubType(v, v, cid);
DoCommand(v_start->tile, v_start->index, cid | 1U << 6 | new_subtype << 8 | 1U << 16, DC_QUERY_COST, GetCmdRefitVeh(v_start)); // Auto-refit and only this vehicle including artic parts. DoCommand(v_start->tile, v_start->index, cid | 1U << 6 | new_subtype << 8 | 1U << 16, DC_QUERY_COST, GetCmdRefitVeh(v_start)); // Auto-refit and only this vehicle including artic parts.
if (_returned_refit_capacity > 0) { if (_returned_refit_capacity > 0) {
amount = cargo_left[cid]; amount = cargo_left[cid] - consist_capleft[cid];
new_cid = cid; new_cid = cid;
} }
} }
@ -1388,6 +1407,13 @@ static void LoadUnloadVehicle(Vehicle *front, int *cargo_left)
ge = &st->goods[v->cargo_type]; ge = &st->goods[v->cargo_type];
} }
/* Add new capacity to consist capacity */
consist_capleft[v_start->cargo_type] += v_start->cargo_cap;
for (Vehicle *w = v_start; w->HasArticulatedPart(); ) {
w = w->GetNextArticulatedPart();
consist_capleft[w->cargo_type] += w->cargo_cap;
}
cur_company.Restore(); cur_company.Restore();
} }
@ -1438,8 +1464,18 @@ static void LoadUnloadVehicle(Vehicle *front, int *cargo_left)
/* Don't load stuff that is already 'reserved' for other vehicles */ /* Don't load stuff that is already 'reserved' for other vehicles */
cap = min((uint)cargo_left[v->cargo_type], cap); cap = min((uint)cargo_left[v->cargo_type], cap);
count = cargo_left[v->cargo_type]; count = cargo_left[v->cargo_type];
if (use_autorefit) {
/* When using autorefit, reserve all cargo for this wagon to prevent other wagons
* from feeling the need to refit. */
int total_cap_left = v->cargo_cap - v->cargo.Count();
cargo_left[v->cargo_type] -= total_cap_left;
consist_capleft[v->cargo_type] -= total_cap_left;
} else {
/* Update cargo left; but don't reserve everything yet, so other wagons
* of the same consist load in parallel. */
cargo_left[v->cargo_type] -= cap; cargo_left[v->cargo_type] -= cap;
} }
}
/* Store whether the maximum possible load amount was loaded or not.*/ /* Store whether the maximum possible load amount was loaded or not.*/
if (count >= (uint)cap_left) { if (count >= (uint)cap_left) {
@ -1489,11 +1525,13 @@ static void LoadUnloadVehicle(Vehicle *front, int *cargo_left)
/* Only set completely_emptied, if we just unloaded all remaining cargo */ /* Only set completely_emptied, if we just unloaded all remaining cargo */
completely_emptied &= anything_unloaded; completely_emptied &= anything_unloaded;
/* We update these variables here, so gradual loading still fills /* For consists without autorefit-order we adjust the reserved cargo at the station after loading,
* all wagons at the same time instead of using the same 'improved' * so that all wagons start loading if the consist is the first consist.
* loading algorithm for the wagons (only fill wagon when there is *
* enough to fill the previous wagons) */ * If we use autorefit otoh, we only want to load/refit a vehicle if the other wagons cannot already hold the cargo,
if (_settings_game.order.improved_load && (front->current_order.GetLoadType() & OLFB_FULL_LOAD)) { * to keep the option to still refit the vehicle when new cargo of different type shows up.
*/
if (_settings_game.order.improved_load && (front->current_order.GetLoadType() & OLFB_FULL_LOAD) && !use_autorefit) {
/* Update left cargo */ /* Update left cargo */
for (Vehicle *v = front; v != NULL; v = v->Next()) { for (Vehicle *v = front; v != NULL; v = v->Next()) {
int cap_left = v->cargo_cap - v->cargo.Count(); int cap_left = v->cargo_cap - v->cargo.Count();