File diff r23022:731ae1300799 → r23023:7b8669afd1db
src/autoreplace_cmd.cpp
Show inline comments
 
/* $Id$ */
 

	
 
/*
 
 * This file is part of OpenTTD.
 
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @file autoreplace_cmd.cpp Deals with autoreplace execution but not the setup */
 

	
 
#include "stdafx.h"
 
#include "company_func.h"
 
#include "train.h"
 
#include "command_func.h"
 
#include "engine_func.h"
 
#include "vehicle_func.h"
 
#include "autoreplace_func.h"
 
#include "autoreplace_gui.h"
 
#include "articulated_vehicles.h"
 
#include "core/random_func.hpp"
 

	
 
#include "table/strings.h"
 

	
 
#include "safeguards.h"
 

	
 
extern void ChangeVehicleViewports(VehicleID from_index, VehicleID to_index);
 
extern void ChangeVehicleNews(VehicleID from_index, VehicleID to_index);
 
extern void ChangeVehicleViewWindow(VehicleID from_index, VehicleID to_index);
 

	
 
/**
 
 * 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 EnginesHaveCargoInCommon(EngineID engine_a, EngineID engine_b)
 
{
 
	CargoTypes available_cargoes_a = GetUnionOfArticulatedRefitMasks(engine_a, true);
 
	CargoTypes available_cargoes_b = GetUnionOfArticulatedRefitMasks(engine_b, true);
 
	return (available_cargoes_a == 0 || available_cargoes_b == 0 || (available_cargoes_a & available_cargoes_b) != 0);
 
}
 

	
 
/**
 
 * Checks some basic properties whether autoreplace is allowed
 
 * @param from Origin engine
 
 * @param to Destination engine
 
 * @param company Company to check for
 
 * @return true if autoreplace is allowed
 
 */
 
bool CheckAutoreplaceValidity(EngineID from, EngineID to, CompanyID company)
 
{
 
	assert(Engine::IsValidID(from) && Engine::IsValidID(to));
 

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

	
 
	const Engine *e_from = Engine::Get(from);
 
	const Engine *e_to = Engine::Get(to);
 
	VehicleType type = e_from->type;
 

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

	
 
	switch (type) {
 
		case VEH_TRAIN: {
 
			/* make sure the railtypes are compatible */
 
			if ((GetRailTypeInfo(e_from->u.rail.railtype)->compatible_railtypes & GetRailTypeInfo(e_to->u.rail.railtype)->compatible_railtypes) == 0) return false;
 

	
 
			/* make sure we do not replace wagons with engines or vice versa */
 
			if ((e_from->u.rail.railveh_type == RAILVEH_WAGON) != (e_to->u.rail.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 vice versa */
 
			if (HasBit(e_from->info.misc_flags, EF_ROAD_TRAM) != HasBit(e_to->info.misc_flags, EF_ROAD_TRAM)) return false;
 
			break;
 

	
 
		case VEH_AIRCRAFT:
 
			/* make sure that we do not replace a plane with a helicopter or vice versa */
 
			if ((e_from->u.air.subtype & AIR_CTOL) != (e_to->u.air.subtype & AIR_CTOL)) return false;