115 if (CanRefitTo(engine_type, v->cargo_type)) return v->cargo_type; |
115 if (CanRefitTo(engine_type, v->cargo_type)) return v->cargo_type; |
116 } while ((v = v->Next()) != NULL); |
116 } while ((v = v->Next()) != NULL); |
117 return CT_NO_REFIT; // We failed to find a cargo type on the old vehicle and we will not refit the new one |
117 return CT_NO_REFIT; // We failed to find a cargo type on the old vehicle and we will not refit the new one |
118 } |
118 } |
119 |
119 |
120 /* Replaces a vehicle (used to be called autorenew) |
120 /** Replaces a vehicle (used to be called autorenew) |
121 * This function is only called from MaybeReplaceVehicle() |
121 * This function is only called from MaybeReplaceVehicle() |
122 * Must be called with _current_player set to the owner of the vehicle |
122 * Must be called with _current_player set to the owner of the vehicle |
123 * @param w Vehicle to replace |
123 * @param w Vehicle to replace |
124 * @param flags is the flags to use when calling DoCommand(). Mainly DC_EXEC counts |
124 * @param flags is the flags to use when calling DoCommand(). Mainly DC_EXEC counts |
|
125 * @param p The vehicle owner (faster than refinding the pointer) |
|
126 * @param new_engine_type The EngineID to replace to |
125 * @return value is cost of the replacement or CMD_ERROR |
127 * @return value is cost of the replacement or CMD_ERROR |
126 */ |
128 */ |
127 static CommandCost ReplaceVehicle(Vehicle **w, byte flags, Money total_cost) |
129 static CommandCost ReplaceVehicle(Vehicle **w, byte flags, Money total_cost, const Player *p, EngineID new_engine_type) |
128 { |
130 { |
129 CommandCost cost; |
131 CommandCost cost; |
130 CommandCost sell_value; |
132 CommandCost sell_value; |
131 Vehicle *old_v = *w; |
133 Vehicle *old_v = *w; |
132 const Player *p = GetPlayer(old_v->owner); |
|
133 EngineID new_engine_type; |
|
134 const UnitID cached_unitnumber = old_v->unitnumber; |
134 const UnitID cached_unitnumber = old_v->unitnumber; |
135 bool new_front = false; |
135 bool new_front = false; |
136 Vehicle *new_v = NULL; |
136 Vehicle *new_v = NULL; |
137 char *vehicle_name = NULL; |
137 char *vehicle_name = NULL; |
138 CargoID replacement_cargo_type; |
138 CargoID replacement_cargo_type; |
139 |
|
140 /* Check if there is a autoreplacement set for the vehicle */ |
|
141 new_engine_type = EngineReplacementForPlayer(p, old_v->engine_type, old_v->group_id); |
|
142 /* if not, just renew to the same type */ |
|
143 if (new_engine_type == INVALID_ENGINE) new_engine_type = old_v->engine_type; |
|
144 |
139 |
145 replacement_cargo_type = GetNewCargoTypeForReplace(old_v, new_engine_type); |
140 replacement_cargo_type = GetNewCargoTypeForReplace(old_v, new_engine_type); |
146 |
141 |
147 /* check if we can't refit to the needed type, so no replace takes place to prevent the vehicle from altering cargo type */ |
142 /* check if we can't refit to the needed type, so no replace takes place to prevent the vehicle from altering cargo type */ |
148 if (replacement_cargo_type == CT_INVALID) return CommandCost(); |
143 if (replacement_cargo_type == CT_INVALID) return CommandCost(); |
290 } |
285 } |
291 |
286 |
292 return cost; |
287 return cost; |
293 } |
288 } |
294 |
289 |
|
290 /** Get the EngineID of the replacement for a vehicle |
|
291 * @param v The vehicle to find a replacement for |
|
292 * @param p The vehicle's owner (it's faster to forward the pointer than refinding it) |
|
293 * @return the EngineID of the replacement. INVALID_ENGINE if no buildable replacement is found |
|
294 */ |
|
295 static EngineID GetNewEngineType(const Vehicle *v, const Player *p) |
|
296 { |
|
297 if (v->type == VEH_TRAIN && IsRearDualheaded(v)) { |
|
298 /* we build the rear ends of multiheaded trains with the front ones */ |
|
299 return INVALID_ENGINE; |
|
300 } |
|
301 |
|
302 EngineID e = EngineReplacementForPlayer(p, v->engine_type, v->group_id); |
|
303 |
|
304 if (e != INVALID_ENGINE && IsEngineBuildable(e, v->type, _current_player)) { |
|
305 return e; |
|
306 } |
|
307 |
|
308 if (v->NeedsAutorenewing(p) && // replace if engine is too old |
|
309 IsEngineBuildable(v->engine_type, v->type, _current_player)) { // engine can still be build |
|
310 return v->engine_type; |
|
311 } |
|
312 |
|
313 return INVALID_ENGINE; |
|
314 } |
|
315 |
295 /** replaces a vehicle if it's set for autoreplace or is too old |
316 /** replaces a vehicle if it's set for autoreplace or is too old |
296 * (used to be called autorenew) |
317 * (used to be called autorenew) |
297 * @param v The vehicle to replace |
318 * @param v The vehicle to replace |
298 * if the vehicle is a train, v needs to be the front engine |
319 * if the vehicle is a train, v needs to be the front engine |
299 * @param flags |
320 * @param flags |
346 |
367 |
347 { |
368 { |
348 cost = CommandCost(EXPENSES_NEW_VEHICLES); |
369 cost = CommandCost(EXPENSES_NEW_VEHICLES); |
349 w = v; |
370 w = v; |
350 do { |
371 do { |
351 if (w->type == VEH_TRAIN && IsRearDualheaded(w)) { |
372 EngineID new_engine = GetNewEngineType(w, p); |
352 /* we build the rear ends of multiheaded trains with the front ones */ |
373 if (new_engine == INVALID_ENGINE) continue; |
353 continue; |
|
354 } |
|
355 |
|
356 // check if the vehicle should be replaced |
|
357 if (!w->NeedsAutorenewing(p) || // replace if engine is too old |
|
358 w->max_age == 0) { // rail cars got a max age of 0 |
|
359 if (!EngineHasReplacementForPlayer(p, w->engine_type, w->group_id)) continue; |
|
360 } |
|
361 |
374 |
362 /* Now replace the vehicle */ |
375 /* Now replace the vehicle */ |
363 cost.AddCost(ReplaceVehicle(&w, flags, cost.GetCost())); |
376 cost.AddCost(ReplaceVehicle(&w, flags, cost.GetCost(), p, new_engine)); |
364 |
377 |
365 if (flags & DC_EXEC && |
378 if (flags & DC_EXEC && |
366 (w->type != VEH_TRAIN || w->u.rail.first_engine == INVALID_ENGINE)) { |
379 (w->type != VEH_TRAIN || w->u.rail.first_engine == INVALID_ENGINE)) { |
367 /* now we bought a new engine and sold the old one. We need to fix the |
380 /* now we bought a new engine and sold the old one. We need to fix the |
368 * pointers in order to avoid pointing to the old one for trains: these |
381 * pointers in order to avoid pointing to the old one for trains: these |