src/autoreplace_cmd.cpp
author frosch
Thu, 11 Sep 2008 19:44:30 +0000
changeset 10108 0f63f81e09f0
parent 10015 2b721243365f
child 10122 c524226103f1
permissions -rw-r--r--
(svn r14292) -Cleanup (r11128): Move an 'if' out of a loop as it does not need to be iterated. (spotted by smatz)
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"
8254
1496654ca5e7 (svn r11818) -Codechange: split player.h into smaller pieces.
rubidium
parents: 8230
diff changeset
     7
#include "player_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"
9936
5e219d21d69e (svn r14091) -Cleanup (r14083): Remove superfluous '#include's.
frosch
parents: 9930
diff changeset
    11
#include "rail.h"
8116
8da76dcb3287 (svn r11677) -Codechange: move price and command related types/functions to their respective places.
rubidium
parents: 8114
diff changeset
    12
#include "command_func.h"
9936
5e219d21d69e (svn r14091) -Cleanup (r14083): Remove superfluous '#include's.
frosch
parents: 9930
diff changeset
    13
#include "engine_base.h"
5e219d21d69e (svn r14091) -Cleanup (r14083): Remove superfluous '#include's.
frosch
parents: 9930
diff changeset
    14
#include "engine_func.h"
8144
65cec0877b78 (svn r11706) -Codechange: split vehicle.h and remove another bunch of useless includes.
rubidium
parents: 8131
diff changeset
    15
#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
    16
#include "functions.h"
8212
cf3fce5c7464 (svn r11775) -Codechange: move all autoreplace/autorenew functions to a single location.
rubidium
parents: 8211
diff changeset
    17
#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
    18
#include "articulated_vehicles.h"
2244
417a472e7cb5 (svn r2764) -Feature: Clone vehicles
bjarni
parents: 2186
diff changeset
    19
8264
b1e85998c7d3 (svn r11828) -Codechange: include table/* as the last includes and remove an unneeded include from openttd.h.
rubidium
parents: 8258
diff changeset
    20
#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
    21
9889
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    22
/** 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
    23
 * @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
    24
 * @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
    25
 * @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
    26
 * @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
    27
 */
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    28
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
    29
{
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    30
	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
    31
	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
    32
	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
    33
}
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    34
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    35
/**
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    36
 * 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
    37
 * @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
    38
 * @param to Destination engine
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    39
 * @param player Player to check for
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    40
 * @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
    41
 */
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    42
bool CheckAutoreplaceValidity(EngineID from, EngineID to, PlayerID player)
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    43
{
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    44
	/* 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
    45
	 * 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
    46
	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
    47
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    48
	/* 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
    49
	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
    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
	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
    52
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    53
	/* check that the new vehicle type is available to the player and its type is the same as the original one */
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    54
	if (!IsEngineBuildable(to, type, player)) 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
    55
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    56
	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
    57
		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
    58
			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
    59
			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
    60
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    61
			/* 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
    62
			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
    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 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
    65
			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
    66
			break;
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    67
		}
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    68
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    69
		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
    70
			/* 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
    71
			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
    72
			break;
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    73
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    74
		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
    75
			/* 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
    76
			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
    77
			break;
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    78
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    79
		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
    80
	}
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
	/* 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
    83
	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
    84
}
8628
2e7e4cdfe96f (svn r12230) -Codechange: [autoreplace] made a function to detect if a vehicle needs autorenewing
bjarni
parents: 8469
diff changeset
    85
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
    86
/** 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
    87
 * @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
    88
 * @param new_head Head of the completely constructed new vehicle chain
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
    89
 */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
    90
static void TransferCargo(Vehicle *old_veh, Vehicle *new_head)
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
    91
{
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
    92
	/* 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
    93
	for (Vehicle *src = old_veh; src != NULL; src = src->Next()) {
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
    94
		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
    95
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
    96
		/* 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
    97
		for (Vehicle *dest = new_head; dest != NULL && src->cargo.Count() > 0; dest = dest->Next()) {
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
    98
			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
    99
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   100
			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
   101
			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
   102
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   103
			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
   104
		}
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
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   107
	/* Update train weight etc., the old vehicle will be sold anyway */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   108
	if (new_head->type == VEH_TRAIN) TrainConsistChanged(new_head, true);
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   109
}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   110
9725
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   111
/**
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   112
 * 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
   113
 * @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
   114
 * @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
   115
 * @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
   116
 */
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   117
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
   118
{
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
   119
	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
   120
	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
   121
9725
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   122
	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
   123
	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
   124
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
   125
	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
   126
		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
   127
	} 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
   128
		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
   129
	}
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
   130
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
   131
	FOR_VEHICLE_ORDERS(u, o) {
8838
068d63397dc3 (svn r12586) -Codechange: do not access an order's refit variables directly.
rubidium
parents: 8786
diff changeset
   132
		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
   133
		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
   134
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   135
		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
   136
		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
   137
	}
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
   138
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
   139
	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
   140
}
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
   141
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
   142
/**
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
   143
 * 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
   144
 * @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
   145
 * @param engine_type The EngineID of the vehicle that is being replaced 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
   146
 * @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
   147
 *    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
   148
 *    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
   149
 */
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
   150
static CargoID GetNewCargoTypeForReplace(Vehicle *v, EngineID engine_type)
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
   151
{
9725
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   152
	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
   153
9725
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   154
	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
   155
9725
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   156
	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
   157
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   158
	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
   159
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   160
	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
   161
		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
   162
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   163
		/* 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
   164
		 * 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
   165
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   166
		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
   167
			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
   168
			/* 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
   169
			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
   170
				/* 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
   171
				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
   172
				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
   173
					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
   174
				}
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
				return CT_NO_REFIT;
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   177
			}
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   178
		}
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   179
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   180
		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
   181
	} else {
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   182
		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
   183
10015
2b721243365f (svn r14174) -Fix: since now, we are 'losing' things, not 'loosing'
smatz
parents: 9969
diff changeset
   184
		if (!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
   185
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   186
		/* 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
   187
		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
   188
		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
   189
			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
   190
		}
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   191
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   192
		return CT_NO_REFIT;
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   193
	}
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
   194
}
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
   195
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
   196
/** 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
   197
 * @param v The vehicle to find a replacement for
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
   198
 * @param p The vehicle's owner (it's faster to forward the pointer than refinding it)
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
   199
 * @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
   200
 */
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
   201
static EngineID GetNewEngineType(const Vehicle *v, const Player *p)
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
   202
{
9725
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   203
	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
   204
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
   205
	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
   206
		/* 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
   207
		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
   208
	}
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
   209
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
   210
	EngineID e = EngineReplacementForPlayer(p, v->engine_type, v->group_id);
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
   211
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
   212
	if (e != INVALID_ENGINE && IsEngineBuildable(e, v->type, _current_player)) {
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
   213
		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
   214
	}
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
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
   216
	if (v->NeedsAutorenewing(p) && // replace if engine is too old
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
	    IsEngineBuildable(v->engine_type, v->type, _current_player)) { // engine can still be build
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
		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
   219
	}
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
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
   221
	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
   222
}
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
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   224
/** 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
   225
 * 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
   226
 * @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
   227
 * @param new_vehicle Returns the newly build and refittet vehicle
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   228
 * @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
   229
 */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   230
static CommandCost BuildReplacementVehicle(Vehicle *old_veh, Vehicle **new_vehicle)
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   231
{
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   232
	*new_vehicle = NULL;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   233
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   234
	/* Shall the vehicle be replaced? */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   235
	const Player *p = GetPlayer(_current_player);
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   236
	EngineID e = GetNewEngineType(old_veh, p);
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   237
	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
   238
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   239
	/* Does it need to be refitted */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   240
	CargoID refit_cargo = GetNewCargoTypeForReplace(old_veh, e);
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   241
	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
   242
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   243
	/* 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
   244
	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
   245
	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
   246
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   247
	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
   248
	*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
   249
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   250
	/* 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
   251
	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
   252
		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
   253
		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
   254
	}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   255
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   256
	/* 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
   257
	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
   258
		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
   259
	}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   260
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   261
	return cost;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   262
}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   263
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   264
/** 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
   265
 * @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
   266
 * @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
   267
 * @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
   268
 */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   269
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
   270
{
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   271
	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
   272
}
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
/** 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
   275
 * @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
   276
 * @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
   277
 * @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
   278
 * @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
   279
 */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   280
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
   281
{
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   282
	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
   283
}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   284
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   285
/** 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
   286
 * @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
   287
 * @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
   288
 * @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
   289
 */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   290
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
   291
{
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   292
	CommandCost cost = CommandCost();
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   293
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   294
	/* Share orders */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   295
	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
   296
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   297
	/* Copy group membership */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   298
	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
   299
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   300
	/* 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
   301
	if (cost.Succeeded()) {
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   302
		/* 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
   303
		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
   304
		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
   305
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   306
		/* 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
   307
		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
   308
	}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   309
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   310
	/* 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
   311
	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
   312
		/* Copy vehicle name */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   313
		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
   314
			_cmd_text = old_head->name;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   315
			DoCommand(0, new_head->index, 0, DC_EXEC | DC_AUTOREPLACE, CMD_NAME_VEHICLE);
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   316
			_cmd_text = NULL;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   317
		}
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
		/* 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
   320
		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
   321
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   322
		/* 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
   323
		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
   324
	}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   325
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   326
	return cost;
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
/** 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
   330
 * @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
   331
 * @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
   332
 * @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
   333
 * @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
   334
 * @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
   335
 */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   336
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
   337
{
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   338
	Vehicle *old_head = *chain;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   339
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   340
	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
   341
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   342
	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
   343
		/* 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
   344
		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
   345
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   346
		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
   347
		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
   348
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   349
		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
   350
		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
   351
		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
   352
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   353
		/* 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
   354
		 * 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
   355
		int i;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   356
		Vehicle *w;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   357
		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
   358
			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
   359
			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
   360
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   361
			CommandCost ret = BuildReplacementVehicle(old_vehs[i], &new_vehs[i]);
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   362
			cost.AddCost(ret);
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   363
			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
   364
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   365
			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
   366
			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
   367
		}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   368
		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
   369
9968
47c45e129a26 (svn r14125) -Fix [FS#2237]: Segfault when autoreplace failed very early.
frosch
parents: 9936
diff changeset
   370
		/* 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
   371
		if (cost.Succeeded()) {
9968
47c45e129a26 (svn r14125) -Fix [FS#2237]: Segfault when autoreplace failed very early.
frosch
parents: 9936
diff changeset
   372
			/* 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
   373
			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
   374
			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
   375
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   376
			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
   377
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   378
			/* Append engines to the new chain
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   379
			 * 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
   380
			 * OTOH the vehicle attach callback is more expensive this way :s */
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   381
			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
   382
			if (cost.Succeeded()) {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   383
				for (int i = num_units - 1; i > 0; i--) {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   384
					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
   385
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   386
					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
   387
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   388
					if (last_engine == NULL) last_engine = append;
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   389
					cost.AddCost(MoveVehicle(append, new_head, DC_EXEC, false));
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   390
					if (cost.Failed()) break;
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   391
				}
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   392
				if (last_engine == NULL) last_engine = new_head;
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   393
			}
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   394
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   395
			/* 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
   396
			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
   397
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   398
			/* Append/insert wagons into the new vehicle chain
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   399
			 * 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
   400
			 */
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   401
			if (cost.Succeeded()) {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   402
				for (int i = num_units - 1; i > 0; i--) {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   403
					assert(last_engine != NULL);
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   404
					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
   405
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   406
					if (RailVehInfo(append->engine_type)->railveh_type == RAILVEH_WAGON) {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   407
						/* Insert wagon after 'last_engine' */
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   408
						CommandCost res = MoveVehicle(append, last_engine, DC_EXEC, false);
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   409
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   410
						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
   411
							MoveVehicle(append, NULL, DC_EXEC | DC_AUTOREPLACE, false);
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   412
							break;
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   413
						}
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   414
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   415
						cost.AddCost(res);
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   416
						if (cost.Failed()) break;
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   417
					} else {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   418
						/* 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
   419
						assert(append == last_engine);
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   420
						last_engine = GetPrevUnit(last_engine);
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   421
					}
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   422
				}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   423
			}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   424
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   425
			/* Sell superfluous new vehicles that could not be inserted. */
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   426
			if (cost.Succeeded() && wagon_removal) {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   427
				for (int i = 1; i < num_units; i++) {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   428
					Vehicle *wagon = new_vehs[i];
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   429
					if (wagon == NULL) continue;
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   430
					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
   431
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   432
					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
   433
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   434
					/* Sell wagon */
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   435
					CommandCost ret = DoCommand(0, wagon->index, 0, DC_EXEC, GetCmdSellVeh(wagon));
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   436
					assert(ret.Succeeded());
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   437
					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
   438
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   439
					/* Revert the money subtraction when the vehicle was built.
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   440
					 * 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
   441
					cost.AddCost(-new_costs[i]);
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   442
				}
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   443
			}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   444
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   445
			/* 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
   446
			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
   447
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   448
			if (cost.Succeeded()) {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   449
				/* Success ! */
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   450
				if ((flags & DC_EXEC) != 0 && new_head != old_head) {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   451
					*chain = new_head;
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   452
				}
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   453
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   454
				/* Transfer cargo of old vehicles and sell them*/
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   455
				for (int i = 0; i < num_units; i++) {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   456
					Vehicle *w = old_vehs[i];
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   457
					/* Is the vehicle again part of the new chain?
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   458
					 * 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
   459
					if (w->First() == new_head) continue;
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 ((flags & DC_EXEC) != 0) TransferCargo(w, new_head);
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   462
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   463
					cost.AddCost(DoCommand(0, w->index, 0, flags, GetCmdSellVeh(w)));
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   464
					if ((flags & DC_EXEC) != 0) {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   465
						old_vehs[i] = NULL;
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   466
						if (i == 0) old_head = NULL;
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   467
					}
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   468
				}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   469
			}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   470
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   471
			/* 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
   472
			 * 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
   473
			 * Note: The vehicle attach callback is disabled here :) */
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   474
			if ((flags & DC_EXEC) == 0) {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   475
				/* Separate the head, so we can reattach the old vehicles */
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   476
				Vehicle *second = GetNextUnit(old_head);
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   477
				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
   478
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   479
				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
   480
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   481
				for (int i = num_units - 1; i > 0; i--) {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   482
					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
   483
					assert(ret.Succeeded());
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   484
				}
9968
47c45e129a26 (svn r14125) -Fix [FS#2237]: Segfault when autoreplace failed very early.
frosch
parents: 9936
diff changeset
   485
			}
47c45e129a26 (svn r14125) -Fix [FS#2237]: Segfault when autoreplace failed very early.
frosch
parents: 9936
diff changeset
   486
		}
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   487
9968
47c45e129a26 (svn r14125) -Fix [FS#2237]: Segfault when autoreplace failed very early.
frosch
parents: 9936
diff changeset
   488
		/* Finally undo buying of new vehicles */
47c45e129a26 (svn r14125) -Fix [FS#2237]: Segfault when autoreplace failed very early.
frosch
parents: 9936
diff changeset
   489
		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
   490
			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
   491
				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
   492
					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
   493
					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
   494
				}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   495
			}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   496
		}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   497
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   498
		free(old_vehs);
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   499
		free(new_vehs);
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   500
		free(new_costs);
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   501
	} else {
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   502
		/* 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
   503
		Vehicle *new_head = NULL;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   504
		cost.AddCost(BuildReplacementVehicle(old_head, &new_head));
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   505
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   506
		/* 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
   507
		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
   508
			*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
   509
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   510
			/* 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
   511
			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
   512
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   513
			if (cost.Succeeded()) {
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   514
				/* 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
   515
				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
   516
					TransferCargo(old_head, new_head);
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   517
					*chain = new_head;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   518
				}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   519
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   520
				/* 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
   521
				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
   522
			}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   523
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   524
			/* 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
   525
			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
   526
				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
   527
			}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   528
		}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   529
	}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   530
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   531
	return cost;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   532
}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   533
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   534
/** Autoreplace a vehicles
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   535
 * @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
   536
 * @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
   537
 * @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
   538
 * @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
   539
 */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   540
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
   541
{
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   542
	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
   543
	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
   544
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   545
	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
   546
	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
   547
	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
   548
	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
   549
	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
   550
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   551
	const Player *p = GetPlayer(_current_player);
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   552
	bool wagon_removal = p->renew_keep_length;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   553
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   554
	/* 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
   555
	Vehicle *w = v;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   556
	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
   557
	while (w != NULL && !any_replacements) {
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   558
		any_replacements = (GetNewEngineType(w, p) != INVALID_ENGINE);
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   559
		w = (w->type == VEH_TRAIN ? GetNextUnit(w) : NULL);
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   560
	}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   561
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   562
	if (any_replacements) {
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   563
		bool was_stopped = (v->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
   564
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   565
		/* Stop the vehicle */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   566
		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
   567
		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
   568
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   569
		assert(v->IsStoppedInDepot());
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   570
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   571
		/* 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
   572
		 * 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
   573
		 * 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
   574
		SavedRandomSeeds saved_seeds;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   575
		SaveRandomSeeds(&saved_seeds);
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   576
		cost.AddCost(ReplaceChain(&v, flags & ~DC_EXEC, wagon_removal, &nothing_to_do));
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   577
		RestoreRandomSeeds(saved_seeds);
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
		if (cost.Succeeded() && (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
   580
			CommandCost ret = ReplaceChain(&v, flags, wagon_removal, &nothing_to_do);
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   581
			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
   582
		}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   583
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   584
		/* Restart the vehicle */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   585
		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
   586
	}
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
	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
   589
	return cost;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   590
}