Mercurial > hg > openttd
changeset 18894:45d08c0d06e8 draft
(svn r23743) -Fix [FS#4906]: Call CB 15E for all vehicles before actually executing any refit.
author | frosch <frosch@openttd.org> |
---|---|
date | Tue, 03 Jan 2012 22:04:12 +0000 |
parents | 7e608ea7c5da |
children | d0ca24721a85 |
files | src/vehicle_cmd.cpp |
diffstat | 1 files changed, 38 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/src/vehicle_cmd.cpp +++ b/src/vehicle_cmd.cpp @@ -283,6 +283,13 @@ } } +/** Helper structure for RefitVehicle() */ +struct RefitResult { + Vehicle *v; ///< Vehicle to refit + uint capacity; ///< New capacity of vehicle + uint mail_capacity; ///< New mail capacity of aircraft +}; + /** * Refits a vehicle (chain). * This is the vehicle-type independent part of the CmdRefitXXX functions. @@ -309,6 +316,9 @@ v = v->First(); } + static SmallVector<RefitResult, 16> refit_result; + refit_result.Clear(); + v->InvalidateNewGRFCacheOfChain(); for (; v != NULL; v = (only_this ? NULL : v->Next())) { if (v->type == VEH_TRAIN && !vehicles_to_refit.Contains(v->index) && !only_this) continue; @@ -351,19 +361,38 @@ } cost.AddCost(refit_cost); - if (flags & DC_EXEC) { - v->cargo.Truncate((v->cargo_type == new_cid) ? amount : 0); - v->cargo_type = new_cid; - v->cargo_cap = amount; - v->cargo_subtype = new_subtype; - if (v->type == VEH_AIRCRAFT) { - Vehicle *u = v->Next(); - u->cargo_cap = mail_capacity; - u->cargo.Truncate(mail_capacity); + /* Record the refitting. + * Do not execute the refitting immediately, so DetermineCapacity and GetRefitCost do the same in test and exec run. + * (weird NewGRFs) + * Note: + * - If the capacity of vehicles depends on other vehicles in the chain, the actual capacity is + * set after RefitVehicle() via ConsistChanged() and friends. The estimation via _returned_refit_capacity will be wrong. + * - We have to call the refit cost callback with the pre-refit configuration of the chain because we want refit and + * autorefit to behave the same, and we need its result for auto_refit_allowed. + */ + RefitResult *result = refit_result.Append(); + result->v = v; + result->capacity = amount; + result->mail_capacity = mail_capacity; + } + + if (flags & DC_EXEC) { + /* Store the result */ + for (RefitResult *result = refit_result.Begin(); result != refit_result.End(); result++) { + Vehicle *u = result->v; + u->cargo.Truncate((u->cargo_type == new_cid) ? result->capacity : 0); + u->cargo_type = new_cid; + u->cargo_cap = result->capacity; + u->cargo_subtype = new_subtype; + if (u->type == VEH_AIRCRAFT) { + Vehicle *w = u->Next(); + w->cargo_cap = result->mail_capacity; + w->cargo.Truncate(result->mail_capacity); } } } + refit_result.Clear(); _returned_refit_capacity = total_capacity; _returned_mail_refit_capacity = total_mail_capacity; return cost;