src/autoreplace_cmd.cpp
changeset 8997 3ee8e18dff23
parent 8996 0873e8d827e7
child 8999 43af94f84514
equal deleted inserted replaced
8996:0873e8d827e7 8997:3ee8e18dff23
   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