src/autoreplace_cmd.cpp
author smatz
Wed, 24 Sep 2008 16:40:06 +0000
changeset 10184 bf4e3ff4cf16
parent 10151 0dd6c35bf0cc
child 10193 ae0dc7f699bf
permissions -rw-r--r--
(svn r14395) -Fix [FS#2285]: crashes and GUI desyncs when order is deleted/modified while the timetable window is open
-Fix: close any dropdown and child windows in the Order and Timetable windows when selected order is deselected, deleted, ...
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"
10122
c524226103f1 (svn r14306) -Codechange: unify the code to draw the vehicle list.
rubidium
parents: 10015
diff changeset
    19
#include "core/alloc_func.hpp"
2244
417a472e7cb5 (svn r2764) -Feature: Clone vehicles
bjarni
parents: 2186
diff changeset
    20
8264
b1e85998c7d3 (svn r11828) -Codechange: include table/* as the last includes and remove an unneeded include from openttd.h.
rubidium
parents: 8258
diff changeset
    21
#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
    22
9889
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    23
/** 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
    24
 * @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
    25
 * @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
    26
 * @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
    27
 * @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
    28
 */
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    29
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
    30
{
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    31
	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
    32
	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
    33
	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
    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
/**
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    37
 * 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
    38
 * @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
    39
 * @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
    40
 * @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
    41
 * @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
    42
 */
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    43
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
    44
{
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    45
	/* 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
    46
	 * 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
    47
	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
    48
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    49
	/* 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
    50
	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
    51
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    52
	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
    53
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    54
	/* 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
    55
	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
    56
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    57
	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
    58
		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
    59
			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
    60
			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
    61
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    62
			/* 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
    63
			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
    64
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    65
			/* 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
    66
			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
    67
			break;
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
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    70
		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
    71
			/* 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
    72
			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
    73
			break;
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    74
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    75
		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
    76
			/* 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
    77
			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
    78
			break;
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    79
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    80
		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
    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
1aaf71e958cc (svn r14037) -Fix (r8610): The autoreplace gui showed vehicle types for replacement which CmdSetAutoReplace() did not accept.
frosch
parents: 9883
diff changeset
    83
	/* 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
    84
	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
    85
}
8628
2e7e4cdfe96f (svn r12230) -Codechange: [autoreplace] made a function to detect if a vehicle needs autorenewing
bjarni
parents: 8469
diff changeset
    86
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
    87
/** 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
    88
 * @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
    89
 * @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
    90
 */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
    91
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
    92
{
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
    93
	/* 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
    94
	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
    95
		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
    96
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
    97
		/* 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
    98
		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
    99
			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
   100
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   101
			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
   102
			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
   103
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   104
			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
   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
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   108
	/* 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
   109
	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
   110
}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   111
9725
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   112
/**
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   113
 * 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
   114
 * @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
   115
 * @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
   116
 * @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
   117
 */
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   118
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
   119
{
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 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
   121
	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
   122
9725
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_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
   124
	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
   125
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
   126
	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
   127
		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
   128
	} 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
   129
		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
   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
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
   132
	FOR_VEHICLE_ORDERS(u, o) {
8838
068d63397dc3 (svn r12586) -Codechange: do not access an order's refit variables directly.
rubidium
parents: 8786
diff changeset
   133
		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
   134
		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
   135
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_a, cargo_type)) continue;
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   137
		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
   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
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
	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
   141
}
2828a02d6f26 (svn r6653) -Fix r6624: [autoreplace] autoreplace will no longer replace a vehicle if the old type can refit to the cargo types being used in the refit orders and the new one lacks one or more of those refit capabilities
bjarni
parents: 4739
diff changeset
   142
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
   143
/**
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
 * 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
   145
 * @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
   146
 * @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
   147
 * @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
   148
 *    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
   149
 *    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
   150
 */
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
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
   152
{
9725
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   153
	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
   154
9725
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   155
	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
   156
9725
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   157
	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
   158
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   159
	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
   160
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   161
	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
   162
		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
   163
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   164
		/* 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
   165
		 * 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
   166
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   167
		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
   168
			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
   169
			/* 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
   170
			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
   171
				/* 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
   172
				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
   173
				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
   174
					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
   175
				}
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   176
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   177
				return CT_NO_REFIT;
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
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   181
		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
   182
	} else {
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   183
		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
   184
10015
2b721243365f (svn r14174) -Fix: since now, we are 'losing' things, not 'loosing'
smatz
parents: 9969
diff changeset
   185
		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
   186
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   187
		/* 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
   188
		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
   189
		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
   190
			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
   191
		}
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   192
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   193
		return CT_NO_REFIT;
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   194
	}
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
   195
}
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
   196
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
   197
/** 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
   198
 * @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
   199
 * @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
   200
 * @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
   201
 */
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
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
   203
{
9725
982452c3357e (svn r13850) -Fix [FS#2146]: Fix resp. implement refitting of articulated vehicles during autoreplace.
frosch
parents: 9704
diff changeset
   204
	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
   205
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
   206
	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
   207
		/* 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
   208
		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
   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
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
	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
   212
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
	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
   214
		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
   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
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
	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
   218
	    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
   219
		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
   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
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
	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
   223
}
3ee8e18dff23 (svn r12792) -Codechange: [autoreplace] added a function to figure out if a replacement is needed and if so, to which EngineID
bjarni
parents: 8996
diff changeset
   224
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   225
/** 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
   226
 * 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
   227
 * @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
   228
 * @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
   229
 * @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
   230
 */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   231
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
   232
{
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   233
	*new_vehicle = NULL;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   234
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   235
	/* 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
   236
	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
   237
	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
   238
	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
   239
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   240
	/* 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
   241
	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
   242
	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
   243
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   244
	/* 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
   245
	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
   246
	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
   247
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   248
	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
   249
	*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
   250
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   251
	/* 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
   252
	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
   253
		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
   254
		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
   255
	}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   256
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   257
	/* 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
   258
	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
   259
		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
   260
	}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   261
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   262
	return cost;
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
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   265
/** 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
   266
 * @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
   267
 * @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
   268
 * @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
   269
 */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   270
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
   271
{
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   272
	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
   273
}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   274
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   275
/** 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
   276
 * @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
   277
 * @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
   278
 * @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
   279
 * @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
   280
 */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   281
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
   282
{
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   283
	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
   284
}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   285
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   286
/** 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
   287
 * @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
   288
 * @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
   289
 * @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
   290
 */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   291
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
   292
{
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   293
	CommandCost cost = CommandCost();
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   294
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   295
	/* Share orders */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   296
	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
   297
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   298
	/* Copy group membership */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   299
	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
   300
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   301
	/* 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
   302
	if (cost.Succeeded()) {
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   303
		/* 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
   304
		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
   305
		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
   306
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   307
		/* 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
   308
		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
   309
	}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   310
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   311
	/* 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
   312
	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
   313
		/* Copy vehicle name */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   314
		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
   315
			_cmd_text = old_head->name;
10151
0dd6c35bf0cc (svn r14337) -Codechange: use CmdRename* and CMD_RENAME_* for vehicle, president and company renaming commands, too
smatz
parents: 10122
diff changeset
   316
			DoCommand(0, new_head->index, 0, DC_EXEC | DC_AUTOREPLACE, CMD_RENAME_VEHICLE);
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   317
			_cmd_text = NULL;
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
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   320
		/* 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
   321
		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
   322
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   323
		/* 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
   324
		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
   325
	}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   326
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   327
	return cost;
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
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   330
/** 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
   331
 * @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
   332
 * @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
   333
 * @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
   334
 * @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
   335
 * @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
   336
 */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   337
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
   338
{
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   339
	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
   340
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   341
	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
   342
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   343
	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
   344
		/* 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
   345
		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
   346
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   347
		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
   348
		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
   349
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   350
		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
   351
		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
   352
		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
   353
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   354
		/* 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
   355
		 * 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
   356
		int i;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   357
		Vehicle *w;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   358
		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
   359
			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
   360
			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
   361
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   362
			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
   363
			cost.AddCost(ret);
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   364
			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
   365
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   366
			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
   367
			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
   368
		}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   369
		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
   370
9968
47c45e129a26 (svn r14125) -Fix [FS#2237]: Segfault when autoreplace failed very early.
frosch
parents: 9936
diff changeset
   371
		/* 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
   372
		if (cost.Succeeded()) {
9968
47c45e129a26 (svn r14125) -Fix [FS#2237]: Segfault when autoreplace failed very early.
frosch
parents: 9936
diff changeset
   373
			/* 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
   374
			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
   375
			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
   376
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   377
			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
   378
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   379
			/* Append engines to the new chain
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   380
			 * 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
   381
			 * OTOH the vehicle attach callback is more expensive this way :s */
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   382
			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
   383
			if (cost.Succeeded()) {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   384
				for (int i = num_units - 1; i > 0; i--) {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   385
					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
   386
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   387
					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
   388
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   389
					if (last_engine == NULL) last_engine = append;
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   390
					cost.AddCost(MoveVehicle(append, new_head, DC_EXEC, false));
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   391
					if (cost.Failed()) break;
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   392
				}
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   393
				if (last_engine == NULL) last_engine = new_head;
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   394
			}
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   395
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   396
			/* 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
   397
			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
   398
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   399
			/* Append/insert wagons into the new vehicle chain
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   400
			 * 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
   401
			 */
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   402
			if (cost.Succeeded()) {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   403
				for (int i = num_units - 1; i > 0; i--) {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   404
					assert(last_engine != NULL);
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   405
					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
   406
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   407
					if (RailVehInfo(append->engine_type)->railveh_type == RAILVEH_WAGON) {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   408
						/* Insert wagon after 'last_engine' */
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   409
						CommandCost res = MoveVehicle(append, last_engine, DC_EXEC, false);
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   410
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   411
						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
   412
							MoveVehicle(append, NULL, DC_EXEC | DC_AUTOREPLACE, false);
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   413
							break;
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
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   416
						cost.AddCost(res);
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   417
						if (cost.Failed()) break;
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   418
					} else {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   419
						/* 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
   420
						assert(append == last_engine);
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   421
						last_engine = GetPrevUnit(last_engine);
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   422
					}
9928
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
			}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   425
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   426
			/* Sell superfluous new vehicles that could not be inserted. */
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   427
			if (cost.Succeeded() && wagon_removal) {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   428
				for (int i = 1; i < num_units; i++) {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   429
					Vehicle *wagon = new_vehs[i];
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   430
					if (wagon == NULL) continue;
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   431
					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
   432
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   433
					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
   434
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   435
					/* Sell wagon */
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   436
					CommandCost ret = DoCommand(0, wagon->index, 0, DC_EXEC, GetCmdSellVeh(wagon));
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   437
					assert(ret.Succeeded());
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   438
					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
   439
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   440
					/* Revert the money subtraction when the vehicle was built.
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   441
					 * 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
   442
					cost.AddCost(-new_costs[i]);
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   443
				}
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   444
			}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   445
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   446
			/* 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
   447
			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
   448
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   449
			if (cost.Succeeded()) {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   450
				/* Success ! */
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   451
				if ((flags & DC_EXEC) != 0 && new_head != old_head) {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   452
					*chain = new_head;
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   453
				}
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   454
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   455
				/* Transfer cargo of old vehicles and sell them*/
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   456
				for (int i = 0; i < num_units; i++) {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   457
					Vehicle *w = old_vehs[i];
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   458
					/* Is the vehicle again part of the new chain?
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   459
					 * 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
   460
					if (w->First() == new_head) continue;
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   461
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   462
					if ((flags & DC_EXEC) != 0) TransferCargo(w, new_head);
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   463
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   464
					cost.AddCost(DoCommand(0, w->index, 0, flags, GetCmdSellVeh(w)));
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   465
					if ((flags & DC_EXEC) != 0) {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   466
						old_vehs[i] = NULL;
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   467
						if (i == 0) old_head = NULL;
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   468
					}
9928
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
			}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   471
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   472
			/* 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
   473
			 * 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
   474
			 * Note: The vehicle attach callback is disabled here :) */
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   475
			if ((flags & DC_EXEC) == 0) {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   476
				/* Separate the head, so we can reattach the old vehicles */
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   477
				Vehicle *second = GetNextUnit(old_head);
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   478
				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
   479
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   480
				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
   481
9969
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   482
				for (int i = num_units - 1; i > 0; i--) {
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   483
					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
   484
					assert(ret.Succeeded());
42def43d1267 (svn r14126) -Codechange (r14125): Add some tabs.
frosch
parents: 9968
diff changeset
   485
				}
9968
47c45e129a26 (svn r14125) -Fix [FS#2237]: Segfault when autoreplace failed very early.
frosch
parents: 9936
diff changeset
   486
			}
47c45e129a26 (svn r14125) -Fix [FS#2237]: Segfault when autoreplace failed very early.
frosch
parents: 9936
diff changeset
   487
		}
9928
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   488
9968
47c45e129a26 (svn r14125) -Fix [FS#2237]: Segfault when autoreplace failed very early.
frosch
parents: 9936
diff changeset
   489
		/* Finally undo buying of new vehicles */
47c45e129a26 (svn r14125) -Fix [FS#2237]: Segfault when autoreplace failed very early.
frosch
parents: 9936
diff changeset
   490
		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
   491
			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
   492
				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
   493
					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
   494
					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
   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
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   499
		free(old_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_vehs);
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   501
		free(new_costs);
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   502
	} else {
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   503
		/* 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
   504
		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
   505
		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
   506
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   507
		/* 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
   508
		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
   509
			*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
   510
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   511
			/* 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
   512
			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
   513
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   514
			if (cost.Succeeded()) {
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   515
				/* 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
   516
				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
   517
					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
   518
					*chain = new_head;
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
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   521
				/* 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
   522
				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
   523
			}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   524
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   525
			/* 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
   526
			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
   527
				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
   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
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   532
	return cost;
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
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   535
/** Autoreplace a vehicles
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   536
 * @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
   537
 * @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
   538
 * @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
   539
 * @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
   540
 */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   541
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
   542
{
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   543
	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
   544
	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
   545
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   546
	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
   547
	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
   548
	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
   549
	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
   550
	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
   551
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   552
	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
   553
	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
   554
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   555
	/* 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
   556
	Vehicle *w = v;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   557
	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
   558
	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
   559
		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
   560
		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
   561
	}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   562
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   563
	if (any_replacements) {
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   564
		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
   565
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   566
		/* Stop the vehicle */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   567
		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
   568
		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
   569
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   570
		assert(v->IsStoppedInDepot());
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   571
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   572
		/* 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
   573
		 * 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
   574
		 * 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
   575
		SavedRandomSeeds saved_seeds;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   576
		SaveRandomSeeds(&saved_seeds);
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   577
		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
   578
		RestoreRandomSeeds(saved_seeds);
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   579
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   580
		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
   581
			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
   582
			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
   583
		}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   584
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   585
		/* Restart the vehicle */
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   586
		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
   587
	}
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   588
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   589
	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
   590
	return cost;
fa24e759e11d (svn r14083) -Fix [FS#1264, FS#2037, FS#2038, FS#2110]: Rewrite the autoreplace kernel.
frosch
parents: 9889
diff changeset
   591
}