src/autoreplace_cmd.cpp
changeset 10207 c291a21b304e
parent 10198 75f7455a4d4a
child 10208 72c00af5c95d
equal deleted inserted replaced
10206:0050610c0368 10207:c291a21b304e
    37 
    37 
    38 /**
    38 /**
    39  * Checks some basic properties whether autoreplace is allowed
    39  * Checks some basic properties whether autoreplace is allowed
    40  * @param from Origin engine
    40  * @param from Origin engine
    41  * @param to Destination engine
    41  * @param to Destination engine
    42  * @param player Player to check for
    42  * @param company Company to check for
    43  * @return true if autoreplace is allowed
    43  * @return true if autoreplace is allowed
    44  */
    44  */
    45 bool CheckAutoreplaceValidity(EngineID from, EngineID to, PlayerID player)
    45 bool CheckAutoreplaceValidity(EngineID from, EngineID to, CompanyID company)
    46 {
    46 {
    47 	/* First we make sure that it's a valid type the user requested
    47 	/* First we make sure that it's a valid type the user requested
    48 	 * check that it's an engine that is in the engine array */
    48 	 * check that it's an engine that is in the engine array */
    49 	if (!IsEngineIndex(from) || !IsEngineIndex(to)) return false;
    49 	if (!IsEngineIndex(from) || !IsEngineIndex(to)) return false;
    50 
    50 
    51 	/* we can't replace an engine into itself (that would be autorenew) */
    51 	/* we can't replace an engine into itself (that would be autorenew) */
    52 	if (from == to) return false;
    52 	if (from == to) return false;
    53 
    53 
    54 	VehicleType type = GetEngine(from)->type;
    54 	VehicleType type = GetEngine(from)->type;
    55 
    55 
    56 	/* check that the new vehicle type is available to the player and its type is the same as the original one */
    56 	/* check that the new vehicle type is available to the company and its type is the same as the original one */
    57 	if (!IsEngineBuildable(to, type, player)) return false;
    57 	if (!IsEngineBuildable(to, type, company)) return false;
    58 
    58 
    59 	switch (type) {
    59 	switch (type) {
    60 		case VEH_TRAIN: {
    60 		case VEH_TRAIN: {
    61 			const RailVehicleInfo *rvi_from = RailVehInfo(from);
    61 			const RailVehicleInfo *rvi_from = RailVehInfo(from);
    62 			const RailVehicleInfo *rvi_to   = RailVehInfo(to);
    62 			const RailVehicleInfo *rvi_to   = RailVehInfo(to);
   211 	}
   211 	}
   212 }
   212 }
   213 
   213 
   214 /** Get the EngineID of the replacement for a vehicle
   214 /** Get the EngineID of the replacement for a vehicle
   215  * @param v The vehicle to find a replacement for
   215  * @param v The vehicle to find a replacement for
   216  * @param p The vehicle's owner (it's faster to forward the pointer than refinding it)
   216  * @param c The vehicle's owner (it's faster to forward the pointer than refinding it)
   217  * @return the EngineID of the replacement. INVALID_ENGINE if no buildable replacement is found
   217  * @return the EngineID of the replacement. INVALID_ENGINE if no buildable replacement is found
   218  */
   218  */
   219 static EngineID GetNewEngineType(const Vehicle *v, const Player *p)
   219 static EngineID GetNewEngineType(const Vehicle *v, const Company *c)
   220 {
   220 {
   221 	assert(v->type != VEH_TRAIN || !IsArticulatedPart(v));
   221 	assert(v->type != VEH_TRAIN || !IsArticulatedPart(v));
   222 
   222 
   223 	if (v->type == VEH_TRAIN && IsRearDualheaded(v)) {
   223 	if (v->type == VEH_TRAIN && IsRearDualheaded(v)) {
   224 		/* we build the rear ends of multiheaded trains with the front ones */
   224 		/* we build the rear ends of multiheaded trains with the front ones */
   225 		return INVALID_ENGINE;
   225 		return INVALID_ENGINE;
   226 	}
   226 	}
   227 
   227 
   228 	EngineID e = EngineReplacementForPlayer(p, v->engine_type, v->group_id);
   228 	EngineID e = EngineReplacementForCompany(c, v->engine_type, v->group_id);
   229 
   229 
   230 	if (e != INVALID_ENGINE && IsEngineBuildable(e, v->type, _current_player)) {
   230 	if (e != INVALID_ENGINE && IsEngineBuildable(e, v->type, _current_company)) {
   231 		return e;
   231 		return e;
   232 	}
   232 	}
   233 
   233 
   234 	if (v->NeedsAutorenewing(p) && // replace if engine is too old
   234 	if (v->NeedsAutorenewing(c) && // replace if engine is too old
   235 	    IsEngineBuildable(v->engine_type, v->type, _current_player)) { // engine can still be build
   235 	    IsEngineBuildable(v->engine_type, v->type, _current_company)) { // engine can still be build
   236 		return v->engine_type;
   236 		return v->engine_type;
   237 	}
   237 	}
   238 
   238 
   239 	return INVALID_ENGINE;
   239 	return INVALID_ENGINE;
   240 }
   240 }
   249 static CommandCost BuildReplacementVehicle(Vehicle *old_veh, Vehicle **new_vehicle, bool part_of_chain)
   249 static CommandCost BuildReplacementVehicle(Vehicle *old_veh, Vehicle **new_vehicle, bool part_of_chain)
   250 {
   250 {
   251 	*new_vehicle = NULL;
   251 	*new_vehicle = NULL;
   252 
   252 
   253 	/* Shall the vehicle be replaced? */
   253 	/* Shall the vehicle be replaced? */
   254 	const Player *p = GetPlayer(_current_player);
   254 	const Company *c = GetCompany(_current_company);
   255 	EngineID e = GetNewEngineType(old_veh, p);
   255 	EngineID e = GetNewEngineType(old_veh, c);
   256 	if (e == INVALID_ENGINE) return CommandCost(); // neither autoreplace is set, nor autorenew is triggered
   256 	if (e == INVALID_ENGINE) return CommandCost(); // neither autoreplace is set, nor autorenew is triggered
   257 
   257 
   258 	/* Does it need to be refitted */
   258 	/* Does it need to be refitted */
   259 	CargoID refit_cargo = GetNewCargoTypeForReplace(old_veh, e, part_of_chain);
   259 	CargoID refit_cargo = GetNewCargoTypeForReplace(old_veh, e, part_of_chain);
   260 	if (refit_cargo == CT_INVALID) return CommandCost(); // incompatible cargos
   260 	if (refit_cargo == CT_INVALID) return CommandCost(); // incompatible cargos
   625 		if (free_wagon && IsFrontEngine(v->First())) return CMD_ERROR;
   625 		if (free_wagon && IsFrontEngine(v->First())) return CMD_ERROR;
   626 	} else {
   626 	} else {
   627 		if (!v->IsPrimaryVehicle()) return CMD_ERROR;
   627 		if (!v->IsPrimaryVehicle()) return CMD_ERROR;
   628 	}
   628 	}
   629 
   629 
   630 	const Player *p = GetPlayer(_current_player);
   630 	const Company *c = GetCompany(_current_company);
   631 	bool wagon_removal = p->renew_keep_length;
   631 	bool wagon_removal = c->renew_keep_length;
   632 
   632 
   633 	/* Test whether any replacement is set, before issuing a whole lot of commands that would end in nothing changed */
   633 	/* Test whether any replacement is set, before issuing a whole lot of commands that would end in nothing changed */
   634 	Vehicle *w = v;
   634 	Vehicle *w = v;
   635 	bool any_replacements = false;
   635 	bool any_replacements = false;
   636 	while (w != NULL && !any_replacements) {
   636 	while (w != NULL && !any_replacements) {
   637 		any_replacements = (GetNewEngineType(w, p) != INVALID_ENGINE);
   637 		any_replacements = (GetNewEngineType(w, c) != INVALID_ENGINE);
   638 		w = (!free_wagon && w->type == VEH_TRAIN ? GetNextUnit(w) : NULL);
   638 		w = (!free_wagon && w->type == VEH_TRAIN ? GetNextUnit(w) : NULL);
   639 	}
   639 	}
   640 
   640 
   641 	if (any_replacements) {
   641 	if (any_replacements) {
   642 		bool was_stopped = free_wagon || ((v->vehstatus & VS_STOPPED) != 0);
   642 		bool was_stopped = free_wagon || ((v->vehstatus & VS_STOPPED) != 0);