Changeset - r9889:bd274fe4b267
[Not reviewed]
master
0 4 0
frosch - 16 years ago 2008-08-10 15:02:21
frosch@openttd.org
(svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
4 files changed with 67 insertions and 40 deletions:
0 comments (0 inline, 0 general)
src/autoreplace_cmd.cpp
Show inline comments
 
@@ -24,6 +24,69 @@
 

	
 
#include "table/strings.h"
 

	
 
/** Figure out if two engines got at least one type of cargo in common (refitting if needed)
 
 * @param engine_a one of the EngineIDs
 
 * @param engine_b the other EngineID
 
 * @param type the type of the engines
 
 * @return true if they can both carry the same type of cargo (or at least one of them got no capacity at all)
 
 */
 
static bool EnginesGotCargoInCommon(EngineID engine_a, EngineID engine_b, VehicleType type)
 
{
 
	uint32 available_cargos_a = GetUnionOfArticulatedRefitMasks(engine_a, type, true);
 
	uint32 available_cargos_b = GetUnionOfArticulatedRefitMasks(engine_b, type, true);
 
	return (available_cargos_a == 0 || available_cargos_b == 0 || (available_cargos_a & available_cargos_b) != 0);
 
}
 

	
 
/**
 
 * Checks some basic properties whether autoreplace is allowed
 
 * @param from Origin engine
 
 * @param to Destination engine
 
 * @param player Player to check for
 
 * @return true if autoreplace is allowed
 
 */
 
bool CheckAutoreplaceValidity(EngineID from, EngineID to, PlayerID player)
 
{
 
	/* First we make sure that it's a valid type the user requested
 
	 * check that it's an engine that is in the engine array */
 
	if (!IsEngineIndex(from) || !IsEngineIndex(to)) return false;
 

	
 
	/* we can't replace an engine into itself (that would be autorenew) */
 
	if (from == to) return false;
 

	
 
	VehicleType type = GetEngine(from)->type;
 

	
 
	/* check that the new vehicle type is available to the player and its type is the same as the original one */
 
	if (!IsEngineBuildable(to, type, player)) return false;
 

	
 
	switch (type) {
 
		case VEH_TRAIN: {
 
			const RailVehicleInfo *rvi_from = RailVehInfo(from);
 
			const RailVehicleInfo *rvi_to   = RailVehInfo(to);
 

	
 
			/* make sure the railtypes are compatible */
 
			if ((GetRailTypeInfo(rvi_from->railtype)->compatible_railtypes & GetRailTypeInfo(rvi_to->railtype)->compatible_railtypes) == 0) return false;
 

	
 
			/* make sure we do not replace wagons with engines or vise versa */
 
			if ((rvi_from->railveh_type == RAILVEH_WAGON) != (rvi_to->railveh_type == RAILVEH_WAGON)) return false;
 
			break;
 
		}
 

	
 
		case VEH_ROAD:
 
			/* make sure that we do not replace a tram with a normal road vehicles or vise versa */
 
			if (HasBit(EngInfo(from)->misc_flags, EF_ROAD_TRAM) != HasBit(EngInfo(to)->misc_flags, EF_ROAD_TRAM)) return false;
 
			break;
 

	
 
		case VEH_AIRCRAFT:
 
			/* make sure that we do not replace a plane with a helicopter or vise versa */
 
			if ((AircraftVehInfo(from)->subtype & AIR_CTOL) != (AircraftVehInfo(to)->subtype & AIR_CTOL)) return false;
 
			break;
 

	
 
		default: break;
 
	}
 

	
 
	/* the engines needs to be able to carry the same cargo */
 
	return EnginesGotCargoInCommon(from, to, type);
 
}
 

	
 
/*
 
 * move the cargo from one engine to another if possible
src/autoreplace_func.h
Show inline comments
 
@@ -100,4 +100,6 @@ static inline CommandCost RemoveEngineRe
 
	return RemoveEngineReplacement(&p->engine_renew_list, engine, group, flags);
 
}
 

	
 
bool CheckAutoreplaceValidity(EngineID from, EngineID to, PlayerID player);
 

	
 
#endif /* AUTOREPLACE_FUNC_H */
src/autoreplace_gui.cpp
Show inline comments
 
@@ -23,7 +23,6 @@
 
#include "engine_base.h"
 
#include "window_gui.h"
 
#include "engine_gui.h"
 
#include "articulated_vehicles.h"
 

	
 
#include "table/sprites.h"
 
#include "table/strings.h"
 
@@ -99,19 +98,6 @@ void AddRemoveEngineFromAutoreplaceAndBu
 
	InvalidateWindowClassesData(WC_BUILD_VEHICLE); // The build windows needs updating as well
 
}
 

	
 
/** Figure out if two engines got at least one type of cargo in common (refitting if needed)
 
 * @param engine_a one of the EngineIDs
 
 * @param engine_b the other EngineID
 
 * @param type the type of the engines
 
 * @return true if they can both carry the same type of cargo (or at least one of them got no capacity at all)
 
 */
 
static bool EnginesGotCargoInCommon(EngineID engine_a, EngineID engine_b, VehicleType type)
 
{
 
	uint32 available_cargos_a = GetUnionOfArticulatedRefitMasks(engine_a, type, true);
 
	uint32 available_cargos_b = GetUnionOfArticulatedRefitMasks(engine_b, type, true);
 
	return (available_cargos_a == 0 || available_cargos_b == 0 || (available_cargos_a & available_cargos_b) != 0);
 
}
 

	
 
/**
 
 * Window for the autoreplacing of vehicles.
 
 */
 
@@ -143,10 +129,6 @@ class ReplaceVehicleWindow : public Wind
 
		if (draw_left && show_engines) {
 
			/* Ensure that the railtype is specific to the selected one */
 
			if (rvi->railtype != this->sel_railtype) return false;
 
		} else {
 
			/* Ensure that it's a compatible railtype to the selected one (like electric <-> diesel)
 
			 * The vehicle do not have to have power on the railtype in question, only able to drive (pulled if needed) */
 
			if (!IsCompatibleRail(rvi->railtype, this->sel_railtype)) return false;
 
		}
 
		return true;
 
	}
 
@@ -177,13 +159,7 @@ class ReplaceVehicleWindow : public Wind
 
				/* Skip drawing the engines we don't have any of and haven't set for replacement */
 
				if (num_engines == 0 && EngineReplacementForPlayer(GetPlayer(_local_player), eid, selected_group) == INVALID_ENGINE) continue;
 
			} else {
 
				/* This is for engines we can replace to and they should depend on what we selected to replace from */
 
				if (!IsEngineBuildable(eid, type, _local_player)) continue; // we need to be able to build the engine
 
				if (!EnginesGotCargoInCommon(eid, this->sel_engine[0], type)) continue; // the engines needs to be able to carry the same cargo
 

	
 
				/* Road vehicles can't be replaced by trams and vice-versa */
 
				if (type == VEH_ROAD && HasBit(EngInfo(this->sel_engine[0])->misc_flags, EF_ROAD_TRAM) != HasBit(e->info.misc_flags, EF_ROAD_TRAM)) continue;
 
				if (eid == this->sel_engine[0]) continue; // we can't replace an engine into itself (that would be autorenew)
 
				if (!CheckAutoreplaceValidity(this->sel_engine[0], eid, _local_player)) continue;
 
			}
 

	
 
			*list->Append() = eid;
src/players.cpp
Show inline comments
 
@@ -717,21 +717,7 @@ CommandCost CmdSetAutoReplace(TileIndex 
 

	
 
			if (!IsValidGroupID(id_g) && !IsAllGroupID(id_g) && !IsDefaultGroupID(id_g)) return CMD_ERROR;
 
			if (new_engine_type != INVALID_ENGINE) {
 
				/* First we make sure that it's a valid type the user requested
 
				 * check that it's an engine that is in the engine array */
 
				if (!IsEngineIndex(new_engine_type)) return CMD_ERROR;
 

	
 
				/* check that the new vehicle type is the same as the original one */
 
				if (GetEngine(old_engine_type)->type != GetEngine(new_engine_type)->type) return CMD_ERROR;
 

	
 
				/* make sure that we do not replace a plane with a helicopter or vise versa */
 
				if (GetEngine(new_engine_type)->type == VEH_AIRCRAFT &&
 
						(AircraftVehInfo(old_engine_type)->subtype & AIR_CTOL) != (AircraftVehInfo(new_engine_type)->subtype & AIR_CTOL)) {
 
					return CMD_ERROR;
 
				}
 

	
 
				/* make sure that the player can actually buy the new engine */
 
				if (!HasBit(GetEngine(new_engine_type)->player_avail, _current_player)) return CMD_ERROR;
 
				if (!CheckAutoreplaceValidity(old_engine_type, new_engine_type, _current_player)) return CMD_ERROR;
 

	
 
				cost = AddEngineReplacementForPlayer(p, old_engine_type, new_engine_type, id_g, flags);
 
			} else {
0 comments (0 inline, 0 general)