src/autoreplace_cmd.cpp
author rubidium
Thu, 18 Dec 2008 12:23:08 +0000
changeset 10436 8d3a9fbe8f19
parent 10219 85fcab58a95e
permissions -rw-r--r--
(svn r14689) -Change: make configure die on commonly made user mistakes, like not having SDL development files or zlib headers installed; you can still compile a dedicated server or a binary without zlib, but you have to explicitly force it.
2186
db48cf29b983 (svn r2701) Insert Id tags into all source files
tron
parents: 2163
diff changeset
     1
/* $Id$ */
db48cf29b983 (svn r2701) Insert Id tags into all source files
tron
parents: 2163
diff changeset
     2
8999
43af94f84514 (svn r12794) -Doc: added missing doxygen comment in autoreplace_cmd.cpp
bjarni
parents: 8997
diff changeset
     3
/** @file autoreplace_cmd.cpp Deals with autoreplace execution but not the setup */
43af94f84514 (svn r12794) -Doc: added missing doxygen comment in autoreplace_cmd.cpp
bjarni
parents: 8997
diff changeset
     4
0
29654efe3188 (svn r1) Import of revision 975 of old (crashed) SVN
truelight
parents:
diff changeset
     5
#include "stdafx.h"
1891
862800791170 (svn r2397) - CodeChange: rename all "ttd" files to "openttd" files.
Darkvater
parents: 1881
diff changeset
     6
#include "openttd.h"
10208
72c00af5c95d (svn r14422) -Codechange: also reflect the changes of r14421 in the filenames.
rubidium
parents: 10207
diff changeset
     7
#include "company_func.h"
1601
83fbe3bfb847 (svn r2105) -Codechange: Added a cache for the first vehicle of a chain to increase performance, especially with many long trains
celestar
parents: 1600
diff changeset
     8
#include "debug.h"
1752
d65cd19f7117 (svn r2256) - Fix: Trains cannot find a depot when they are in a tunnel. (glx)
matthijs
parents: 1735
diff changeset
     9
#include "vehicle_gui.h"
2676
59b65b4fb480 (svn r3218) -Feature: Multiheaded train engines will now stay in the same train
bjarni
parents: 2666
diff changeset
    10
#include "train.h"
10193
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
    11
#include "aircraft.h"
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
    12
#include "roadveh.h"
9936
5e219d21d69e (svn r14091) -Cleanup (r14083): Remove superfluous '#include's.
frosch
parents: 9930
diff changeset
    13
#include "rail.h"
8116
8da76dcb3287 (svn r11677) -Codechange: move price and command related types/functions to their respective places.
rubidium
parents: 8114
diff changeset
    14
#include "command_func.h"
9936
5e219d21d69e (svn r14091) -Cleanup (r14083): Remove superfluous '#include's.
frosch
parents: 9930
diff changeset
    15
#include "engine_base.h"
5e219d21d69e (svn r14091) -Cleanup (r14083): Remove superfluous '#include's.
frosch
parents: 9930
diff changeset
    16
#include "engine_func.h"
8144
65cec0877b78 (svn r11706) -Codechange: split vehicle.h and remove another bunch of useless includes.
rubidium
parents: 8131
diff changeset
    17
#include "vehicle_func.h"
8131
160939e24ed3 (svn r11692) -Codechange: move some functions from 'functions.h' to a more logical place and remove about 50% of the includes of 'functions.h'
rubidium
parents: 8116
diff changeset
    18
#include "functions.h"
8212
cf3fce5c7464 (svn r11775) -Codechange: move all autoreplace/autorenew functions to a single location.
rubidium
parents: 8211
diff changeset
    19
#include "autoreplace_func.h"
8363
dd6cae395a9b (svn r11929) -Fix (r9981)[FS#1624]: [autoreplace] fixed a case where a single headed locomotive caused an assert when being replaced to a dualheaded one
bjarni
parents: 8362
diff changeset
    20
#include "articulated_vehicles.h"
10122
c524226103f1 (svn r14306) -Codechange: unify the code to draw the vehicle list.
rubidium
parents: 10015
diff changeset
    21
#include "core/alloc_func.hpp"
2244
417a472e7cb5 (svn r2764) -Feature: Clone vehicles
bjarni
parents: 2186
diff changeset
    22
8264
b1e85998c7d3 (svn r11828) -Codechange: include table/* as the last includes and remove an unneeded include from openttd.h.
rubidium
parents: 8258
diff changeset
    23
#include "table/strings.h"
b1e85998c7d3 (svn r11828) -Codechange: include table/* as the last includes and remove an unneeded include from openttd.h.
rubidium
parents: 8258
diff changeset
    24
9889
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    25
/** Figure out if two engines got at least one type of cargo in common (refitting if needed)
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    26
 * @param engine_a one of the EngineIDs
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    27
 * @param engine_b the other EngineID
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    28
 * @param type the type of the engines
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    29
 * @return true if they can both carry the same type of cargo (or at least one of them got no capacity at all)
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    30
 */
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    31
static bool EnginesGotCargoInCommon(EngineID engine_a, EngineID engine_b, VehicleType type)
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    32
{
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    33
	uint32 available_cargos_a = GetUnionOfArticulatedRefitMasks(engine_a, type, true);
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    34
	uint32 available_cargos_b = GetUnionOfArticulatedRefitMasks(engine_b, type, true);
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    35
	return (available_cargos_a == 0 || available_cargos_b == 0 || (available_cargos_a & available_cargos_b) != 0);
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    36
}
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    37
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    38
/**
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    39
 * Checks some basic properties whether autoreplace is allowed
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    40
 * @param from Origin engine
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    41
 * @param to Destination engine
10207
c291a21b304e (svn r14421) -Codechange: rename all player variables/types to company *or* client so it is immediatelly clear which one you are working with.
rubidium
parents: 10198
diff changeset
    42
 * @param company Company to check for
9889
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    43
 * @return true if autoreplace is allowed
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    44
 */
10207
c291a21b304e (svn r14421) -Codechange: rename all player variables/types to company *or* client so it is immediatelly clear which one you are working with.
rubidium
parents: 10198
diff changeset
    45
bool CheckAutoreplaceValidity(EngineID from, EngineID to, CompanyID company)
9889
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    46
{
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    47
	/* First we make sure that it's a valid type the user requested
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    48
	 * check that it's an engine that is in the engine array */
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    49
	if (!IsEngineIndex(from) || !IsEngineIndex(to)) return false;
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    50
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    51
	/* we can't replace an engine into itself (that would be autorenew) */
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    52
	if (from == to) return false;
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    53
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    54
	VehicleType type = GetEngine(from)->type;
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    55
10207
c291a21b304e (svn r14421) -Codechange: rename all player variables/types to company *or* client so it is immediatelly clear which one you are working with.
rubidium
parents: 10198
diff changeset
    56
	/* check that the new vehicle type is available to the company and its type is the same as the original one */
c291a21b304e (svn r14421) -Codechange: rename all player variables/types to company *or* client so it is immediatelly clear which one you are working with.
rubidium
parents: 10198
diff changeset
    57
	if (!IsEngineBuildable(to, type, company)) return false;
9889
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    58
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    59
	switch (type) {
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    60
		case VEH_TRAIN: {
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    61
			const RailVehicleInfo *rvi_from = RailVehInfo(from);
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    62
			const RailVehicleInfo *rvi_to   = RailVehInfo(to);
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    63
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    64
			/* make sure the railtypes are compatible */
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    65
			if ((GetRailTypeInfo(rvi_from->railtype)->compatible_railtypes & GetRailTypeInfo(rvi_to->railtype)->compatible_railtypes) == 0) return false;
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    66
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    67
			/* make sure we do not replace wagons with engines or vise versa */
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    68
			if ((rvi_from->railveh_type == RAILVEH_WAGON) != (rvi_to->railveh_type == RAILVEH_WAGON)) return false;
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    69
			break;
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    70
		}
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    71
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    72
		case VEH_ROAD:
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    73
			/* make sure that we do not replace a tram with a normal road vehicles or vise versa */
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    74
			if (HasBit(EngInfo(from)->misc_flags, EF_ROAD_TRAM) != HasBit(EngInfo(to)->misc_flags, EF_ROAD_TRAM)) return false;
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    75
			break;
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    76
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    77
		case VEH_AIRCRAFT:
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    78
			/* make sure that we do not replace a plane with a helicopter or vise versa */
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    79
			if ((AircraftVehInfo(from)->subtype & AIR_CTOL) != (AircraftVehInfo(to)->subtype & AIR_CTOL)) return false;
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    80
			break;
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    81
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    82
		default: break;
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    83
	}
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    84
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    85
	/* the engines needs to be able to carry the same cargo */
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    86
	return EnginesGotCargoInCommon(from, to, type);
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    87
}
8628
2e7e4cdfe96f (svn r12230) -Codechange: [autoreplace] made a function to detect if a vehicle needs autorenewing
bjarni
parents: 8469
diff changeset
    88
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
    89
/** Transfer cargo from a single (articulated )old vehicle to the new vehicle chain
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
    90
 * @param old_veh Old vehicle that will be sold
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
    91
 * @param new_head Head of the completely constructed new vehicle chain
10193
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
    92
 * @param part_of_chain The vehicle is part of a train
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
    93
 */
10193
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
    94
static void TransferCargo(Vehicle *old_veh, Vehicle *new_head, bool part_of_chain)
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
    95
{
10198
75f7455a4d4a (svn r14411) -Fix (r14406): IsFrontEngine() is only valid for trains.
frosch
parents: 10194
diff changeset
    96
	assert(!part_of_chain || new_head->IsPrimaryVehicle());
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
    97
	/* Loop through source parts */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
    98
	for (Vehicle *src = old_veh; src != NULL; src = src->Next()) {
10193
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
    99
		if (!part_of_chain && src->type == VEH_TRAIN && src != old_veh && src != old_veh->u.rail.other_multiheaded_part && !IsArticulatedPart(src)) {
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   100
			/* Skip vehicles, which do not belong to old_veh */
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   101
			src = GetLastEnginePart(src);
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   102
			continue;
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   103
		}
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   104
		if (src->cargo_type >= NUM_CARGO || src->cargo.Count() == 0) continue;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   105
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   106
		/* Find free space in the new chain */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   107
		for (Vehicle *dest = new_head; dest != NULL && src->cargo.Count() > 0; dest = dest->Next()) {
10219
85fcab58a95e (svn r14442) -Fix (r14406): Typo causing problems in rare cases.
frosch
parents: 10208
diff changeset
   108
			if (!part_of_chain && dest->type == VEH_TRAIN && dest != new_head && dest != new_head->u.rail.other_multiheaded_part && !IsArticulatedPart(dest)) {
10193
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   109
				/* Skip vehicles, which do not belong to new_head */
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   110
				dest = GetLastEnginePart(dest);
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   111
				continue;
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   112
			}
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   113
			if (dest->cargo_type != src->cargo_type) continue;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   114
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   115
			uint amount = min(src->cargo.Count(), dest->cargo_cap - dest->cargo.Count());
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   116
			if (amount <= 0) continue;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   117
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   118
			src->cargo.MoveTo(&dest->cargo, amount);
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   119
		}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   120
	}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   121
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   122
	/* Update train weight etc., the old vehicle will be sold anyway */
10193
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   123
	if (part_of_chain && new_head->type == VEH_TRAIN) TrainConsistChanged(new_head, true);
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   124
}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   125
9725
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   126
/**
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   127
 * Tests whether refit orders that applied to v will also apply to the new vehicle type
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   128
 * @param v The vehicle to be replaced
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   129
 * @param engine_type The type we want to replace with
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   130
 * @return true iff all refit orders stay valid
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   131
 */
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   132
static bool VerifyAutoreplaceRefitForOrders(const Vehicle *v, EngineID engine_type)
4741
2828a02d6f26 (svn r6653) -Fix r6624: [autoreplace] autoreplace will no longer replace a vehicle if the old type can refit to the cargo types being used in the refit orders and the new one lacks one or more of those refit capabilities
bjarni
parents: 4739
diff changeset
   133
{
2828a02d6f26 (svn r6653) -Fix r6624: [autoreplace] autoreplace will no longer replace a vehicle if the old type can refit to the cargo types being used in the refit orders and the new one lacks one or more of those refit capabilities
bjarni
parents: 4739
diff changeset
   134
	const Order *o;
2828a02d6f26 (svn r6653) -Fix r6624: [autoreplace] autoreplace will no longer replace a vehicle if the old type can refit to the cargo types being used in the refit orders and the new one lacks one or more of those refit capabilities
bjarni
parents: 4739
diff changeset
   135
	const Vehicle *u;
2828a02d6f26 (svn r6653) -Fix r6624: [autoreplace] autoreplace will no longer replace a vehicle if the old type can refit to the cargo types being used in the refit orders and the new one lacks one or more of those refit capabilities
bjarni
parents: 4739
diff changeset
   136
9725
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   137
	uint32 union_refit_mask_a = GetUnionOfArticulatedRefitMasks(v->engine_type, v->type, false);
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   138
	uint32 union_refit_mask_b = GetUnionOfArticulatedRefitMasks(engine_type, v->type, false);
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   139
6259
471b91a4b1d8 (svn r9068) -Codechange: capitalize the VEH_Train etc. enums to match the coding style (and rest of the code).
rubidium
parents: 6248
diff changeset
   140
	if (v->type == VEH_TRAIN) {
7497
40e457c0a8ac (svn r11011) -Fix [FS#1129]: GetFirstVehicleInChain did change the game state while being marked const.
rubidium
parents: 7492
diff changeset
   141
		u = v->First();
4741
2828a02d6f26 (svn r6653) -Fix r6624: [autoreplace] autoreplace will no longer replace a vehicle if the old type can refit to the cargo types being used in the refit orders and the new one lacks one or more of those refit capabilities
bjarni
parents: 4739
diff changeset
   142
	} else {
2828a02d6f26 (svn r6653) -Fix r6624: [autoreplace] autoreplace will no longer replace a vehicle if the old type can refit to the cargo types being used in the refit orders and the new one lacks one or more of those refit capabilities
bjarni
parents: 4739
diff changeset
   143
		u = v;
2828a02d6f26 (svn r6653) -Fix r6624: [autoreplace] autoreplace will no longer replace a vehicle if the old type can refit to the cargo types being used in the refit orders and the new one lacks one or more of those refit capabilities
bjarni
parents: 4739
diff changeset
   144
	}
2828a02d6f26 (svn r6653) -Fix r6624: [autoreplace] autoreplace will no longer replace a vehicle if the old type can refit to the cargo types being used in the refit orders and the new one lacks one or more of those refit capabilities
bjarni
parents: 4739
diff changeset
   145
2828a02d6f26 (svn r6653) -Fix r6624: [autoreplace] autoreplace will no longer replace a vehicle if the old type can refit to the cargo types being used in the refit orders and the new one lacks one or more of those refit capabilities
bjarni
parents: 4739
diff changeset
   146
	FOR_VEHICLE_ORDERS(u, o) {
8838
068d63397dc3 (svn r12586) -Codechange: do not access an order's refit variables directly.
rubidium
parents: 8786
diff changeset
   147
		if (!o->IsRefit()) continue;
9725
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   148
		CargoID cargo_type = o->GetRefitCargo();
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   149
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   150
		if (!HasBit(union_refit_mask_a, cargo_type)) continue;
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   151
		if (!HasBit(union_refit_mask_b, cargo_type)) return false;
4741
2828a02d6f26 (svn r6653) -Fix r6624: [autoreplace] autoreplace will no longer replace a vehicle if the old type can refit to the cargo types being used in the refit orders and the new one lacks one or more of those refit capabilities
bjarni
parents: 4739
diff changeset
   152
	}
2828a02d6f26 (svn r6653) -Fix r6624: [autoreplace] autoreplace will no longer replace a vehicle if the old type can refit to the cargo types being used in the refit orders and the new one lacks one or more of those refit capabilities
bjarni
parents: 4739
diff changeset
   153
2828a02d6f26 (svn r6653) -Fix r6624: [autoreplace] autoreplace will no longer replace a vehicle if the old type can refit to the cargo types being used in the refit orders and the new one lacks one or more of those refit capabilities
bjarni
parents: 4739
diff changeset
   154
	return true;
2828a02d6f26 (svn r6653) -Fix r6624: [autoreplace] autoreplace will no longer replace a vehicle if the old type can refit to the cargo types being used in the refit orders and the new one lacks one or more of those refit capabilities
bjarni
parents: 4739
diff changeset
   155
}
2828a02d6f26 (svn r6653) -Fix r6624: [autoreplace] autoreplace will no longer replace a vehicle if the old type can refit to the cargo types being used in the refit orders and the new one lacks one or more of those refit capabilities
bjarni
parents: 4739
diff changeset
   156
4554
8342a6d0a366 (svn r6393) -Fix: [autoreplace] now refit costs are added to the estimated costs (could spend more than allowed when estimate and actual cost were not the same)
bjarni
parents: 4551
diff changeset
   157
/**
8342a6d0a366 (svn r6393) -Fix: [autoreplace] now refit costs are added to the estimated costs (could spend more than allowed when estimate and actual cost were not the same)
bjarni
parents: 4551
diff changeset
   158
 * Function to find what type of cargo to refit to when autoreplacing
8342a6d0a366 (svn r6393) -Fix: [autoreplace] now refit costs are added to the estimated costs (could spend more than allowed when estimate and actual cost were not the same)
bjarni
parents: 4551
diff changeset
   159
 * @param *v Original vehicle, that is being replaced
8342a6d0a366 (svn r6393) -Fix: [autoreplace] now refit costs are added to the estimated costs (could spend more than allowed when estimate and actual cost were not the same)
bjarni
parents: 4551
diff changeset
   160
 * @param engine_type The EngineID of the vehicle that is being replaced to
10193
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   161
 * @param part_of_chain The vehicle is part of a train
4554
8342a6d0a366 (svn r6393) -Fix: [autoreplace] now refit costs are added to the estimated costs (could spend more than allowed when estimate and actual cost were not the same)
bjarni
parents: 4551
diff changeset
   162
 * @return The cargo type to replace to
8342a6d0a366 (svn r6393) -Fix: [autoreplace] now refit costs are added to the estimated costs (could spend more than allowed when estimate and actual cost were not the same)
bjarni
parents: 4551
diff changeset
   163
 *    CT_NO_REFIT is returned if no refit is needed
8342a6d0a366 (svn r6393) -Fix: [autoreplace] now refit costs are added to the estimated costs (could spend more than allowed when estimate and actual cost were not the same)
bjarni
parents: 4551
diff changeset
   164
 *    CT_INVALID is returned when both old and new vehicle got cargo capacity and refitting the new one to the old one's cargo type isn't possible
8342a6d0a366 (svn r6393) -Fix: [autoreplace] now refit costs are added to the estimated costs (could spend more than allowed when estimate and actual cost were not the same)
bjarni
parents: 4551
diff changeset
   165
 */
10193
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   166
static CargoID GetNewCargoTypeForReplace(Vehicle *v, EngineID engine_type, bool part_of_chain)
4554
8342a6d0a366 (svn r6393) -Fix: [autoreplace] now refit costs are added to the estimated costs (could spend more than allowed when estimate and actual cost were not the same)
bjarni
parents: 4551
diff changeset
   167
{
9725
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   168
	CargoID cargo_type;
4554
8342a6d0a366 (svn r6393) -Fix: [autoreplace] now refit costs are added to the estimated costs (could spend more than allowed when estimate and actual cost were not the same)
bjarni
parents: 4551
diff changeset
   169
9725
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   170
	if (GetUnionOfArticulatedRefitMasks(engine_type, v->type, true) == 0) return CT_NO_REFIT; // Don't try to refit an engine with no cargo capacity
4554
8342a6d0a366 (svn r6393) -Fix: [autoreplace] now refit costs are added to the estimated costs (could spend more than allowed when estimate and actual cost were not the same)
bjarni
parents: 4551
diff changeset
   171
9725
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   172
	if (IsArticulatedVehicleCarryingDifferentCargos(v, &cargo_type)) return CT_INVALID; // We cannot refit to mixed cargos in an automated way
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   173
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   174
	uint32 available_cargo_types = GetIntersectionOfArticulatedRefitMasks(engine_type, v->type, true);
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   175
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   176
	if (cargo_type == CT_INVALID) {
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   177
		if (v->type != VEH_TRAIN) return CT_NO_REFIT; // If the vehicle does not carry anything at all, every replacement is fine.
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   178
10193
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   179
		if (!part_of_chain) return CT_NO_REFIT;
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   180
9725
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   181
		/* the old engine didn't have cargo capacity, but the new one does
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   182
		 * now we will figure out what cargo the train is carrying and refit to fit this */
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   183
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   184
		for (v = v->First(); v != NULL; v = v->Next()) {
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   185
			if (v->cargo_cap == 0) continue;
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   186
			/* Now we found a cargo type being carried on the train and we will see if it is possible to carry to this one */
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   187
			if (HasBit(available_cargo_types, v->cargo_type)) {
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   188
				/* Do we have to refit the vehicle, or is it already carrying the right cargo? */
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   189
				uint16 *default_capacity = GetCapacityOfArticulatedParts(engine_type, v->type);
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   190
				for (CargoID cid = 0; cid < NUM_CARGO; cid++) {
9883
77893558228d (svn r14031) -Fix (r13850): Determining the refit cargo did not work, when the old vehicle did not carry anything but the new one did.
frosch
parents: 9725
diff changeset
   191
					if (cid != v->cargo_type && default_capacity[cid] > 0) return v->cargo_type;
9725
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   192
				}
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   193
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   194
				return CT_NO_REFIT;
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   195
			}
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   196
		}
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   197
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   198
		return CT_NO_REFIT; // We failed to find a cargo type on the old vehicle and we will not refit the new one
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   199
	} else {
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   200
		if (!HasBit(available_cargo_types, cargo_type)) return CT_INVALID; // We can't refit the vehicle to carry the cargo we want
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   201
10193
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   202
		if (part_of_chain && !VerifyAutoreplaceRefitForOrders(v, engine_type)) return CT_INVALID; // Some refit orders lose their effect
9725
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   203
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   204
		/* Do we have to refit the vehicle, or is it already carrying the right cargo? */
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   205
		uint16 *default_capacity = GetCapacityOfArticulatedParts(engine_type, v->type);
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   206
		for (CargoID cid = 0; cid < NUM_CARGO; cid++) {
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   207
			if (cid != cargo_type && default_capacity[cid] > 0) return cargo_type;
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   208
		}
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   209
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   210
		return CT_NO_REFIT;
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   211
	}
4554
8342a6d0a366 (svn r6393) -Fix: [autoreplace] now refit costs are added to the estimated costs (could spend more than allowed when estimate and actual cost were not the same)
bjarni
parents: 4551
diff changeset
   212
}
8342a6d0a366 (svn r6393) -Fix: [autoreplace] now refit costs are added to the estimated costs (could spend more than allowed when estimate and actual cost were not the same)
bjarni
parents: 4551
diff changeset
   213
8997
3ee8e18dff23 (svn r12792) -Codechange: [autoreplace] added a function to figure out if a replacement is needed and if so, to which EngineID
bjarni
parents: 8996
diff changeset
   214
/** Get the EngineID of the replacement for a vehicle
3ee8e18dff23 (svn r12792) -Codechange: [autoreplace] added a function to figure out if a replacement is needed and if so, to which EngineID
bjarni
parents: 8996
diff changeset
   215
 * @param v The vehicle to find a replacement for
10207
c291a21b304e (svn r14421) -Codechange: rename all player variables/types to company *or* client so it is immediatelly clear which one you are working with.
rubidium
parents: 10198
diff changeset
   216
 * @param c The vehicle's owner (it's faster to forward the pointer than refinding it)
8997
3ee8e18dff23 (svn r12792) -Codechange: [autoreplace] added a function to figure out if a replacement is needed and if so, to which EngineID
bjarni
parents: 8996
diff changeset
   217
 * @return the EngineID of the replacement. INVALID_ENGINE if no buildable replacement is found
3ee8e18dff23 (svn r12792) -Codechange: [autoreplace] added a function to figure out if a replacement is needed and if so, to which EngineID
bjarni
parents: 8996
diff changeset
   218
 */
10207
c291a21b304e (svn r14421) -Codechange: rename all player variables/types to company *or* client so it is immediatelly clear which one you are working with.
rubidium
parents: 10198
diff changeset
   219
static EngineID GetNewEngineType(const Vehicle *v, const Company *c)
8997
3ee8e18dff23 (svn r12792) -Codechange: [autoreplace] added a function to figure out if a replacement is needed and if so, to which EngineID
bjarni
parents: 8996
diff changeset
   220
{
9725
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   221
	assert(v->type != VEH_TRAIN || !IsArticulatedPart(v));
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   222
8997
3ee8e18dff23 (svn r12792) -Codechange: [autoreplace] added a function to figure out if a replacement is needed and if so, to which EngineID
bjarni
parents: 8996
diff changeset
   223
	if (v->type == VEH_TRAIN && IsRearDualheaded(v)) {
3ee8e18dff23 (svn r12792) -Codechange: [autoreplace] added a function to figure out if a replacement is needed and if so, to which EngineID
bjarni
parents: 8996
diff changeset
   224
		/* we build the rear ends of multiheaded trains with the front ones */
3ee8e18dff23 (svn r12792) -Codechange: [autoreplace] added a function to figure out if a replacement is needed and if so, to which EngineID
bjarni
parents: 8996
diff changeset
   225
		return INVALID_ENGINE;
3ee8e18dff23 (svn r12792) -Codechange: [autoreplace] added a function to figure out if a replacement is needed and if so, to which EngineID
bjarni
parents: 8996
diff changeset
   226
	}
3ee8e18dff23 (svn r12792) -Codechange: [autoreplace] added a function to figure out if a replacement is needed and if so, to which EngineID
bjarni
parents: 8996
diff changeset
   227
10207
c291a21b304e (svn r14421) -Codechange: rename all player variables/types to company *or* client so it is immediatelly clear which one you are working with.
rubidium
parents: 10198
diff changeset
   228
	EngineID e = EngineReplacementForCompany(c, v->engine_type, v->group_id);
8997
3ee8e18dff23 (svn r12792) -Codechange: [autoreplace] added a function to figure out if a replacement is needed and if so, to which EngineID
bjarni
parents: 8996
diff changeset
   229
10207
c291a21b304e (svn r14421) -Codechange: rename all player variables/types to company *or* client so it is immediatelly clear which one you are working with.
rubidium
parents: 10198
diff changeset
   230
	if (e != INVALID_ENGINE && IsEngineBuildable(e, v->type, _current_company)) {
8997
3ee8e18dff23 (svn r12792) -Codechange: [autoreplace] added a function to figure out if a replacement is needed and if so, to which EngineID
bjarni
parents: 8996
diff changeset
   231
		return e;
3ee8e18dff23 (svn r12792) -Codechange: [autoreplace] added a function to figure out if a replacement is needed and if so, to which EngineID
bjarni
parents: 8996
diff changeset
   232
	}
3ee8e18dff23 (svn r12792) -Codechange: [autoreplace] added a function to figure out if a replacement is needed and if so, to which EngineID
bjarni
parents: 8996
diff changeset
   233
10207
c291a21b304e (svn r14421) -Codechange: rename all player variables/types to company *or* client so it is immediatelly clear which one you are working with.
rubidium
parents: 10198
diff changeset
   234
	if (v->NeedsAutorenewing(c) && // replace if engine is too old
c291a21b304e (svn r14421) -Codechange: rename all player variables/types to company *or* client so it is immediatelly clear which one you are working with.
rubidium
parents: 10198
diff changeset
   235
	    IsEngineBuildable(v->engine_type, v->type, _current_company)) { // engine can still be build
8997
3ee8e18dff23 (svn r12792) -Codechange: [autoreplace] added a function to figure out if a replacement is needed and if so, to which EngineID
bjarni
parents: 8996
diff changeset
   236
		return v->engine_type;
3ee8e18dff23 (svn r12792) -Codechange: [autoreplace] added a function to figure out if a replacement is needed and if so, to which EngineID
bjarni
parents: 8996
diff changeset
   237
	}
3ee8e18dff23 (svn r12792) -Codechange: [autoreplace] added a function to figure out if a replacement is needed and if so, to which EngineID
bjarni
parents: 8996
diff changeset
   238
3ee8e18dff23 (svn r12792) -Codechange: [autoreplace] added a function to figure out if a replacement is needed and if so, to which EngineID
bjarni
parents: 8996
diff changeset
   239
	return INVALID_ENGINE;
3ee8e18dff23 (svn r12792) -Codechange: [autoreplace] added a function to figure out if a replacement is needed and if so, to which EngineID
bjarni
parents: 8996
diff changeset
   240
}
3ee8e18dff23 (svn r12792) -Codechange: [autoreplace] added a function to figure out if a replacement is needed and if so, to which EngineID
bjarni
parents: 8996
diff changeset
   241
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   242
/** Builds and refits a replacement vehicle
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   243
 * Important: The old vehicle is still in the original vehicle chain (used for determining the cargo when the old vehicle did not carry anything, but the new one does)
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   244
 * @param old_veh A single (articulated/multiheaded) vehicle that shall be replaced.
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   245
 * @param new_vehicle Returns the newly build and refittet vehicle
10193
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   246
 * @param part_of_chain The vehicle is part of a train
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   247
 * @return cost or error
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   248
 */
10193
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   249
static CommandCost BuildReplacementVehicle(Vehicle *old_veh, Vehicle **new_vehicle, bool part_of_chain)
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   250
{
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   251
	*new_vehicle = NULL;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   252
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   253
	/* Shall the vehicle be replaced? */
10207
c291a21b304e (svn r14421) -Codechange: rename all player variables/types to company *or* client so it is immediatelly clear which one you are working with.
rubidium
parents: 10198
diff changeset
   254
	const Company *c = GetCompany(_current_company);
c291a21b304e (svn r14421) -Codechange: rename all player variables/types to company *or* client so it is immediatelly clear which one you are working with.
rubidium
parents: 10198
diff changeset
   255
	EngineID e = GetNewEngineType(old_veh, c);
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   256
	if (e == INVALID_ENGINE) return CommandCost(); // neither autoreplace is set, nor autorenew is triggered
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   257
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   258
	/* Does it need to be refitted */
10193
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   259
	CargoID refit_cargo = GetNewCargoTypeForReplace(old_veh, e, part_of_chain);
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   260
	if (refit_cargo == CT_INVALID) return CommandCost(); // incompatible cargos
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   261
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   262
	/* Build the new vehicle */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   263
	CommandCost cost = DoCommand(old_veh->tile, e, 0, DC_EXEC | DC_AUTOREPLACE, GetCmdBuildVeh(old_veh));
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   264
	if (cost.Failed()) return cost;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   265
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   266
	Vehicle *new_veh = GetVehicle(_new_vehicle_id);
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   267
	*new_vehicle = new_veh;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   268
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   269
	/* Refit the vehicle if needed */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   270
	if (refit_cargo != CT_NO_REFIT) {
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   271
		cost.AddCost(DoCommand(0, new_veh->index, refit_cargo, DC_EXEC, GetCmdRefitVeh(new_veh)));
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   272
		assert(cost.Succeeded()); // This should be ensured by GetNewCargoTypeForReplace()
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   273
	}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   274
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   275
	/* Try to reverse the vehicle, but do not care if it fails as the new type might not be reversible */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   276
	if (new_veh->type == VEH_TRAIN && HasBit(old_veh->u.rail.flags, VRF_REVERSE_DIRECTION)) {
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   277
		DoCommand(0, new_veh->index, true, DC_EXEC, CMD_REVERSE_TRAIN_DIRECTION);
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   278
	}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   279
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   280
	return cost;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   281
}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   282
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   283
/** Issue a start/stop command
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   284
 * @param v a vehicle
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   285
 * @param evaluate_callback shall the start/stop callback be evaluated?
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   286
 * @return success or error
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   287
 */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   288
static inline CommandCost StartStopVehicle(const Vehicle *v, bool evaluate_callback)
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   289
{
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   290
	return DoCommand(0, v->index, evaluate_callback ? 1 : 0, DC_EXEC | DC_AUTOREPLACE, CMD_START_STOP_VEHICLE);
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   291
}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   292
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   293
/** Issue a train vehicle move command
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   294
 * @param v The vehicle to move
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   295
 * @param after The vehicle to insert 'v' after, or NULL to start new chain
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   296
 * @param whole_chain move all vehicles following 'v' (true), or only 'v' (false)
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   297
 * @return success or error
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   298
 */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   299
static inline CommandCost MoveVehicle(const Vehicle *v, const Vehicle *after, uint32 flags, bool whole_chain)
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   300
{
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   301
	return DoCommand(0, v->index | (after != NULL ? after->index : INVALID_VEHICLE) << 16, whole_chain ? 1 : 0, flags, CMD_MOVE_RAIL_VEHICLE);
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   302
}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   303
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   304
/** Copy head specific things to the new vehicle chain after it was successfully constructed
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   305
 * @param old_head The old front vehicle (no wagons attached anymore)
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   306
 * @param new_head The new head of the completely replaced vehicle chain
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   307
 * @param flags the command flags to use
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   308
 */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   309
static CommandCost CopyHeadSpecificThings(Vehicle *old_head, Vehicle *new_head, uint32 flags)
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   310
{
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   311
	CommandCost cost = CommandCost();
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   312
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   313
	/* Share orders */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   314
	if (cost.Succeeded() && old_head != new_head) cost.AddCost(DoCommand(0, (old_head->index << 16) | new_head->index, CO_SHARE, DC_EXEC, CMD_CLONE_ORDER));
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   315
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   316
	/* Copy group membership */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   317
	if (cost.Succeeded() && old_head != new_head) cost.AddCost(DoCommand(0, old_head->group_id, new_head->index, DC_EXEC, CMD_ADD_VEHICLE_GROUP));
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   318
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   319
	/* Perform start/stop check whether the new vehicle suits newgrf restrictions etc. */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   320
	if (cost.Succeeded()) {
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   321
		/* Start the vehicle, might be denied by certain things */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   322
		assert((new_head->vehstatus & VS_STOPPED) != 0);
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   323
		cost.AddCost(StartStopVehicle(new_head, true));
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   324
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   325
		/* Stop the vehicle again, but do not care about evil newgrfs allowing starting but not stopping :p */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   326
		if (cost.Succeeded()) cost.AddCost(StartStopVehicle(new_head, false));
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   327
	}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   328
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   329
	/* Last do those things which do never fail (resp. we do not care about), but which are not undo-able */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   330
	if (cost.Succeeded() && old_head != new_head && (flags & DC_EXEC) != 0) {
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   331
		/* Copy vehicle name */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   332
		if (old_head->name != NULL) {
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   333
			_cmd_text = old_head->name;
10151
0dd6c35bf0cc (svn r14337) -Codechange: use CmdRename* and CMD_RENAME_* for vehicle, president and company renaming commands, too
smatz
parents: 10122
diff changeset
   334
			DoCommand(0, new_head->index, 0, DC_EXEC | DC_AUTOREPLACE, CMD_RENAME_VEHICLE);
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   335
			_cmd_text = NULL;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   336
		}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   337
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   338
		/* Copy other things which cannot be copied by a command and which shall not stay resetted from the build vehicle command */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   339
		new_head->CopyVehicleConfigAndStatistics(old_head);
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   340
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   341
		/* Switch vehicle windows to the new vehicle, so they are not closed when the old vehicle is sold */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   342
		ChangeVehicleViewWindow(old_head->index, new_head->index);
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   343
	}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   344
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   345
	return cost;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   346
}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   347
10193
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   348
/** Replace a single unit in a free wagon chain
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   349
 * @param single_unit vehicle to let autoreplace/renew operator on
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   350
 * @param flags command flags
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   351
 * @param wagon_removal remove wagons when the resulting chain occupies more tiles than the old did
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   352
 * @param nothing_to_do is set to 'false' when something was done (only valid when not failed)
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   353
 * @return cost or error
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   354
 */
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   355
static CommandCost ReplaceFreeUnit(Vehicle **single_unit, uint32 flags, bool *nothing_to_do)
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   356
{
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   357
	Vehicle *old_v = *single_unit;
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   358
	assert(old_v->type == VEH_TRAIN && !IsArticulatedPart(old_v) && !IsRearDualheaded(old_v));
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   359
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   360
	CommandCost cost = CommandCost(EXPENSES_NEW_VEHICLES, 0);
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   361
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   362
	/* Build and refit replacement vehicle */
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   363
	Vehicle *new_v = NULL;
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   364
	cost.AddCost(BuildReplacementVehicle(old_v, &new_v, false));
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   365
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   366
	/* Was a new vehicle constructed? */
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   367
	if (cost.Succeeded() && new_v != NULL) {
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   368
		*nothing_to_do = false;
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   369
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   370
		if ((flags & DC_EXEC) != 0) {
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   371
			/* Move the new vehicle behind the old */
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   372
			MoveVehicle(new_v, old_v, DC_EXEC, false);
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   373
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   374
			/* Take over cargo
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   375
			 * Note: We do only transfer cargo from the old to the new vehicle.
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   376
			 *       I.e. we do not transfer remaining cargo to other vehicles.
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   377
			 *       Else you would also need to consider moving cargo to other free chains,
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   378
			 *       or doing the same in ReplaceChain(), which would be quite troublesome.
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   379
			 */
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   380
			TransferCargo(old_v, new_v, false);
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   381
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   382
			*single_unit = new_v;
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   383
		}
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   384
10194
64a3dd322cd2 (svn r14407) -Cleanup (r14406): Remove a redundant test. (thanks SmatZ)
frosch
parents: 10193
diff changeset
   385
		/* Sell the old vehicle */
64a3dd322cd2 (svn r14407) -Cleanup (r14406): Remove a redundant test. (thanks SmatZ)
frosch
parents: 10193
diff changeset
   386
		cost.AddCost(DoCommand(0, old_v->index, 0, flags, GetCmdSellVeh(old_v)));
10193
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   387
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   388
		/* If we are not in DC_EXEC undo everything */
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   389
		if ((flags & DC_EXEC) == 0) {
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   390
			DoCommand(0, new_v->index, 0, DC_EXEC, GetCmdSellVeh(new_v));
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   391
		}
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   392
	}
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   393
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   394
	return cost;
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   395
}
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   396
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   397
/** Replace a whole vehicle chain
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   398
 * @param chain vehicle chain to let autoreplace/renew operator on
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   399
 * @param flags command flags
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   400
 * @param wagon_removal remove wagons when the resulting chain occupies more tiles than the old did
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   401
 * @param nothing_to_do is set to 'false' when something was done (only valid when not failed)
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   402
 * @return cost or error
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   403
 */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   404
static CommandCost ReplaceChain(Vehicle **chain, uint32 flags, bool wagon_removal, bool *nothing_to_do)
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   405
{
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   406
	Vehicle *old_head = *chain;
10193
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   407
	assert(old_head->IsPrimaryVehicle());
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   408
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   409
	CommandCost cost = CommandCost(EXPENSES_NEW_VEHICLES, 0);
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   410
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   411
	if (old_head->type == VEH_TRAIN) {
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   412
		/* Store the length of the old vehicle chain, rounded up to whole tiles */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   413
		uint16 old_total_length = (old_head->u.rail.cached_total_length + TILE_SIZE - 1) / TILE_SIZE * TILE_SIZE;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   414
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   415
		int num_units = 0; ///< Number of units in the chain
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   416
		for (Vehicle *w = old_head; w != NULL; w = GetNextUnit(w)) num_units++;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   417
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   418
		Vehicle **old_vehs = CallocT<Vehicle *>(num_units); ///< Will store vehicles of the old chain in their order
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   419
		Vehicle **new_vehs = CallocT<Vehicle *>(num_units); ///< New vehicles corresponding to old_vehs or NULL if no replacement
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   420
		Money *new_costs = MallocT<Money>(num_units);       ///< Costs for buying and refitting the new vehicles
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   421
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   422
		/* Collect vehicles and build replacements
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   423
		 * Note: The replacement vehicles can only successfully build as long as the old vehicles are still in their chain */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   424
		int i;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   425
		Vehicle *w;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   426
		for (w = old_head, i = 0; w != NULL; w = GetNextUnit(w), i++) {
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   427
			assert(i < num_units);
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   428
			old_vehs[i] = w;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   429
10193
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   430
			CommandCost ret = BuildReplacementVehicle(old_vehs[i], &new_vehs[i], true);
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   431
			cost.AddCost(ret);
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   432
			if (cost.Failed()) break;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   433
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   434
			new_costs[i] = ret.GetCost();
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   435
			if (new_vehs[i] != NULL) *nothing_to_do = false;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   436
		}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   437
		Vehicle *new_head = (new_vehs[0] != NULL ? new_vehs[0] : old_vehs[0]);
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   438
9968
47c45e129a26 (svn r14125) -Fix [FS#2237]: Segfault when autoreplace failed very early.
frosch
parents: 9936
diff changeset
   439
		/* Note: When autoreplace has already failed here, old_vehs[] is not completely initialized. But it is also not needed. */
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   440
		if (cost.Succeeded()) {
9968
47c45e129a26 (svn r14125) -Fix [FS#2237]: Segfault when autoreplace failed very early.
frosch
parents: 9936
diff changeset
   441
			/* Separate the head, so we can start constructing the new chain */
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   442
			Vehicle *second = GetNextUnit(old_head);
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   443
			if (second != NULL) cost.AddCost(MoveVehicle(second, NULL, DC_EXEC | DC_AUTOREPLACE, true));
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   444
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   445
			assert(GetNextUnit(new_head) == NULL);
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   446
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   447
			/* Append engines to the new chain
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   448
			 * We do this from back to front, so that the head of the temporary vehicle chain does not change all the time.
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   449
			 * OTOH the vehicle attach callback is more expensive this way :s */
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   450
			Vehicle *last_engine = NULL; ///< Shall store the last engine unit after this step
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   451
			if (cost.Succeeded()) {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   452
				for (int i = num_units - 1; i > 0; i--) {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   453
					Vehicle *append = (new_vehs[i] != NULL ? new_vehs[i] : old_vehs[i]);
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   454
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   455
					if (RailVehInfo(append->engine_type)->railveh_type == RAILVEH_WAGON) continue;
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   456
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   457
					if (last_engine == NULL) last_engine = append;
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   458
					cost.AddCost(MoveVehicle(append, new_head, DC_EXEC, false));
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   459
					if (cost.Failed()) break;
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   460
				}
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   461
				if (last_engine == NULL) last_engine = new_head;
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   462
			}
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   463
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   464
			/* When wagon removal is enabled and the new engines without any wagons are already longer than the old, we have to fail */
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   465
			if (cost.Succeeded() && wagon_removal && new_head->u.rail.cached_total_length > old_total_length) cost = CommandCost(STR_TRAIN_TOO_LONG_AFTER_REPLACEMENT);
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   466
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   467
			/* Append/insert wagons into the new vehicle chain
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   468
			 * We do this from back to front, so we can stop when wagon removal or maximum train length (i.e. from mammoth-train setting) is triggered.
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   469
			 */
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   470
			if (cost.Succeeded()) {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   471
				for (int i = num_units - 1; i > 0; i--) {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   472
					assert(last_engine != NULL);
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   473
					Vehicle *append = (new_vehs[i] != NULL ? new_vehs[i] : old_vehs[i]);
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   474
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   475
					if (RailVehInfo(append->engine_type)->railveh_type == RAILVEH_WAGON) {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   476
						/* Insert wagon after 'last_engine' */
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   477
						CommandCost res = MoveVehicle(append, last_engine, DC_EXEC, false);
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   478
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   479
						if (res.Succeeded() && wagon_removal && new_head->u.rail.cached_total_length > old_total_length) {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   480
							MoveVehicle(append, NULL, DC_EXEC | DC_AUTOREPLACE, false);
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   481
							break;
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   482
						}
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   483
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   484
						cost.AddCost(res);
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   485
						if (cost.Failed()) break;
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   486
					} else {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   487
						/* We have reached 'last_engine', continue with the next engine towards the front */
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   488
						assert(append == last_engine);
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   489
						last_engine = GetPrevUnit(last_engine);
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   490
					}
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   491
				}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   492
			}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   493
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   494
			/* Sell superfluous new vehicles that could not be inserted. */
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   495
			if (cost.Succeeded() && wagon_removal) {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   496
				for (int i = 1; i < num_units; i++) {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   497
					Vehicle *wagon = new_vehs[i];
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   498
					if (wagon == NULL) continue;
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   499
					if (wagon->First() == new_head) break;
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   500
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   501
					assert(RailVehInfo(wagon->engine_type)->railveh_type == RAILVEH_WAGON);
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   502
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   503
					/* Sell wagon */
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   504
					CommandCost ret = DoCommand(0, wagon->index, 0, DC_EXEC, GetCmdSellVeh(wagon));
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   505
					assert(ret.Succeeded());
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   506
					new_vehs[i] = NULL;
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   507
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   508
					/* Revert the money subtraction when the vehicle was built.
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   509
					 * This value is different from the sell value, esp. because of refitting */
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   510
					cost.AddCost(-new_costs[i]);
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   511
				}
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   512
			}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   513
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   514
			/* The new vehicle chain is constructed, now take over orders and everything... */
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   515
			if (cost.Succeeded()) cost.AddCost(CopyHeadSpecificThings(old_head, new_head, flags));
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   516
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   517
			if (cost.Succeeded()) {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   518
				/* Success ! */
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   519
				if ((flags & DC_EXEC) != 0 && new_head != old_head) {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   520
					*chain = new_head;
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   521
				}
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   522
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   523
				/* Transfer cargo of old vehicles and sell them*/
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   524
				for (int i = 0; i < num_units; i++) {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   525
					Vehicle *w = old_vehs[i];
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   526
					/* Is the vehicle again part of the new chain?
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   527
					 * Note: We cannot test 'new_vehs[i] != NULL' as wagon removal might cause to remove both */
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   528
					if (w->First() == new_head) continue;
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   529
10193
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   530
					if ((flags & DC_EXEC) != 0) TransferCargo(w, new_head, true);
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   531
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   532
					cost.AddCost(DoCommand(0, w->index, 0, flags, GetCmdSellVeh(w)));
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   533
					if ((flags & DC_EXEC) != 0) {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   534
						old_vehs[i] = NULL;
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   535
						if (i == 0) old_head = NULL;
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   536
					}
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   537
				}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   538
			}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   539
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   540
			/* If we are not in DC_EXEC undo everything, i.e. rearrange old vehicles.
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   541
			 * We do this from back to front, so that the head of the temporary vehicle chain does not change all the time.
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   542
			 * Note: The vehicle attach callback is disabled here :) */
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   543
			if ((flags & DC_EXEC) == 0) {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   544
				/* Separate the head, so we can reattach the old vehicles */
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   545
				Vehicle *second = GetNextUnit(old_head);
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   546
				if (second != NULL) MoveVehicle(second, NULL, DC_EXEC | DC_AUTOREPLACE, true);
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   547
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   548
				assert(GetNextUnit(old_head) == NULL);
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   549
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   550
				for (int i = num_units - 1; i > 0; i--) {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   551
					CommandCost ret = MoveVehicle(old_vehs[i], old_head, DC_EXEC | DC_AUTOREPLACE, false);
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   552
					assert(ret.Succeeded());
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   553
				}
9968
47c45e129a26 (svn r14125) -Fix [FS#2237]: Segfault when autoreplace failed very early.
frosch
parents: 9936
diff changeset
   554
			}
47c45e129a26 (svn r14125) -Fix [FS#2237]: Segfault when autoreplace failed very early.
frosch
parents: 9936
diff changeset
   555
		}
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   556
9968
47c45e129a26 (svn r14125) -Fix [FS#2237]: Segfault when autoreplace failed very early.
frosch
parents: 9936
diff changeset
   557
		/* Finally undo buying of new vehicles */
47c45e129a26 (svn r14125) -Fix [FS#2237]: Segfault when autoreplace failed very early.
frosch
parents: 9936
diff changeset
   558
		if ((flags & DC_EXEC) == 0) {
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   559
			for (int i = num_units - 1; i >= 0; i--) {
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   560
				if (new_vehs[i] != NULL) {
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   561
					DoCommand(0, new_vehs[i]->index, 0, DC_EXEC, GetCmdSellVeh(new_vehs[i]));
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   562
					new_vehs[i] = NULL;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   563
				}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   564
			}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   565
		}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   566
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   567
		free(old_vehs);
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   568
		free(new_vehs);
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   569
		free(new_costs);
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   570
	} else {
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   571
		/* Build and refit replacement vehicle */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   572
		Vehicle *new_head = NULL;
10193
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   573
		cost.AddCost(BuildReplacementVehicle(old_head, &new_head, true));
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   574
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   575
		/* Was a new vehicle constructed? */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   576
		if (cost.Succeeded() && new_head != NULL) {
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   577
			*nothing_to_do = false;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   578
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   579
			/* The new vehicle is constructed, now take over orders and everything... */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   580
			cost.AddCost(CopyHeadSpecificThings(old_head, new_head, flags));
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   581
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   582
			if (cost.Succeeded()) {
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   583
				/* The new vehicle is constructed, now take over cargo */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   584
				if ((flags & DC_EXEC) != 0) {
10193
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   585
					TransferCargo(old_head, new_head, true);
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   586
					*chain = new_head;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   587
				}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   588
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   589
				/* Sell the old vehicle */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   590
				cost.AddCost(DoCommand(0, old_head->index, 0, flags, GetCmdSellVeh(old_head)));
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   591
			}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   592
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   593
			/* If we are not in DC_EXEC undo everything */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   594
			if ((flags & DC_EXEC) == 0) {
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   595
				DoCommand(0, new_head->index, 0, DC_EXEC, GetCmdSellVeh(new_head));
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   596
			}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   597
		}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   598
	}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   599
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   600
	return cost;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   601
}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   602
10193
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   603
/** Autoreplaces a vehicle
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   604
 * Trains are replaced as a whole chain, free wagons in depot are replaced on their own
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   605
 * @param tile not used
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   606
 * @param flags type of operation
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   607
 * @param p1 Index of vehicle
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   608
 * @param p2 not used
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   609
 */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   610
CommandCost CmdAutoreplaceVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   611
{
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   612
	CommandCost cost = CommandCost(EXPENSES_NEW_VEHICLES, 0);
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   613
	bool nothing_to_do = true;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   614
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   615
	if (!IsValidVehicleID(p1)) return CMD_ERROR;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   616
	Vehicle *v = GetVehicle(p1);
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   617
	if (!CheckOwnership(v->owner)) return CMD_ERROR;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   618
	if (!v->IsInDepot()) return CMD_ERROR;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   619
	if (HASBITS(v->vehstatus, VS_CRASHED)) return CMD_ERROR;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   620
10193
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   621
	bool free_wagon = false;
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   622
	if (v->type == VEH_TRAIN) {
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   623
		if (IsArticulatedPart(v) || IsRearDualheaded(v)) return CMD_ERROR;
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   624
		free_wagon = !IsFrontEngine(v);
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   625
		if (free_wagon && IsFrontEngine(v->First())) return CMD_ERROR;
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   626
	} else {
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   627
		if (!v->IsPrimaryVehicle()) return CMD_ERROR;
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   628
	}
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   629
10207
c291a21b304e (svn r14421) -Codechange: rename all player variables/types to company *or* client so it is immediatelly clear which one you are working with.
rubidium
parents: 10198
diff changeset
   630
	const Company *c = GetCompany(_current_company);
c291a21b304e (svn r14421) -Codechange: rename all player variables/types to company *or* client so it is immediatelly clear which one you are working with.
rubidium
parents: 10198
diff changeset
   631
	bool wagon_removal = c->renew_keep_length;
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   632
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   633
	/* Test whether any replacement is set, before issuing a whole lot of commands that would end in nothing changed */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   634
	Vehicle *w = v;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   635
	bool any_replacements = false;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   636
	while (w != NULL && !any_replacements) {
10207
c291a21b304e (svn r14421) -Codechange: rename all player variables/types to company *or* client so it is immediatelly clear which one you are working with.
rubidium
parents: 10198
diff changeset
   637
		any_replacements = (GetNewEngineType(w, c) != INVALID_ENGINE);
10193
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   638
		w = (!free_wagon && w->type == VEH_TRAIN ? GetNextUnit(w) : NULL);
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   639
	}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   640
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   641
	if (any_replacements) {
10193
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   642
		bool was_stopped = free_wagon || ((v->vehstatus & VS_STOPPED) != 0);
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   643
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   644
		/* Stop the vehicle */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   645
		if (!was_stopped) cost.AddCost(StartStopVehicle(v, true));
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   646
		if (cost.Failed()) return cost;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   647
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   648
		assert(v->IsStoppedInDepot());
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   649
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   650
		/* We have to construct the new vehicle chain to test whether it is valid.
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   651
		 * Vehicle construction needs random bits, so we have to save the random seeds
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   652
		 * to prevent desyncs and to replay newgrf callbacks during DC_EXEC */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   653
		SavedRandomSeeds saved_seeds;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   654
		SaveRandomSeeds(&saved_seeds);
10193
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   655
		if (free_wagon) {
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   656
			cost.AddCost(ReplaceFreeUnit(&v, flags & ~DC_EXEC, &nothing_to_do));
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   657
		} else {
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   658
			cost.AddCost(ReplaceChain(&v, flags & ~DC_EXEC, wagon_removal, &nothing_to_do));
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   659
		}
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   660
		RestoreRandomSeeds(saved_seeds);
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   661
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   662
		if (cost.Succeeded() && (flags & DC_EXEC) != 0) {
10193
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   663
			CommandCost ret;
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   664
			if (free_wagon) {
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   665
				ret = ReplaceFreeUnit(&v, flags, &nothing_to_do);
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   666
			} else {
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   667
				ret = ReplaceChain(&v, flags, wagon_removal, &nothing_to_do);
ae0dc7f699bf (svn r14406) -Fix [FS#Eddi]: Autoreplace did not work for vehicles in free wagon chains.
frosch
parents: 10151
diff changeset
   668
			}
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   669
			assert(ret.Succeeded() && ret.GetCost() == cost.GetCost());
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   670
		}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   671
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   672
		/* Restart the vehicle */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   673
		if (!was_stopped) cost.AddCost(StartStopVehicle(v, false));
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   674
	}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   675
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   676
	if (cost.Succeeded() && nothing_to_do) cost = CommandCost(STR_AUTOREPLACE_NOTHING_TO_DO);
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   677
	return cost;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   678
}