File diff r26828:fa6e2fa4b68c → r26829:f1ebd010c392
src/train_cmd.cpp
Show inline comments
 
@@ -1181,49 +1181,49 @@ static void NormaliseTrainHead(Train *he
 
 * @param src_veh source vehicle index
 
 * @param dest_veh what wagon to put the source wagon AFTER, XXX - INVALID_VEHICLE to make a new line
 
 * @param move_chain move all vehicles following the source vehicle
 
 * @return the cost of this operation or an error
 
 */
 
CommandCost CmdMoveRailVehicle(DoCommandFlag flags, VehicleID src_veh, VehicleID dest_veh, bool move_chain)
 
{
 
	Train *src = Train::GetIfValid(src_veh);
 
	if (src == nullptr) return CMD_ERROR;
 

	
 
	CommandCost ret = CheckOwnership(src->owner);
 
	if (ret.Failed()) return ret;
 

	
 
	/* Do not allow moving crashed vehicles inside the depot, it is likely to cause asserts later */
 
	if (src->vehstatus & VS_CRASHED) return CMD_ERROR;
 

	
 
	/* if nothing is selected as destination, try and find a matching vehicle to drag to. */
 
	Train *dst;
 
	if (dest_veh == INVALID_VEHICLE) {
 
		dst = (src->IsEngine() || (flags & DC_AUTOREPLACE)) ? nullptr : FindGoodVehiclePos(src);
 
	} else {
 
		dst = Train::GetIfValid(dest_veh);
 
		if (dst == nullptr) return CMD_ERROR;
 

	
 
		CommandCost ret = CheckOwnership(dst->owner);
 
		ret = CheckOwnership(dst->owner);
 
		if (ret.Failed()) return ret;
 

	
 
		/* Do not allow appending to crashed vehicles, too */
 
		if (dst->vehstatus & VS_CRASHED) return CMD_ERROR;
 
	}
 

	
 
	/* if an articulated part is being handled, deal with its parent vehicle */
 
	src = src->GetFirstEnginePart();
 
	if (dst != nullptr) {
 
		dst = dst->GetFirstEnginePart();
 
	}
 

	
 
	/* don't move the same vehicle.. */
 
	if (src == dst) return CommandCost();
 

	
 
	/* locate the head of the two chains */
 
	Train *src_head = src->First();
 
	Train *dst_head;
 
	if (dst != nullptr) {
 
		dst_head = dst->First();
 
		if (dst_head->tile != src_head->tile) return CMD_ERROR;
 
		/* Now deal with articulated part of destination wagon */
 
		dst = dst->GetLastEnginePart();
 
	} else {
 
@@ -1250,49 +1250,49 @@ CommandCost CmdMoveRailVehicle(DoCommand
 
	TrainList original_dst;
 

	
 
	MakeTrainBackup(original_src, src_head);
 
	MakeTrainBackup(original_dst, dst_head);
 

	
 
	/* Also make backup of the original heads as ArrangeTrains can change them.
 
	 * For the destination head we do not care if it is the same as the source
 
	 * head because in that case it's just a copy. */
 
	Train *original_src_head = src_head;
 
	Train *original_dst_head = (dst_head == src_head ? nullptr : dst_head);
 

	
 
	/* We want this information from before the rearrangement, but execute this after the validation.
 
	 * original_src_head can't be nullptr; src is by definition != nullptr, so src_head can't be nullptr as
 
	 * src->GetFirst() always yields non-nullptr, so eventually original_src_head != nullptr as well. */
 
	bool original_src_head_front_engine = original_src_head->IsFrontEngine();
 
	bool original_dst_head_front_engine = original_dst_head != nullptr && original_dst_head->IsFrontEngine();
 

	
 
	/* (Re)arrange the trains in the wanted arrangement. */
 
	ArrangeTrains(&dst_head, dst, &src_head, src, move_chain);
 

	
 
	if ((flags & DC_AUTOREPLACE) == 0) {
 
		/* If the autoreplace flag is set we do not need to test for the validity
 
		 * because we are going to revert the train to its original state. As we
 
		 * assume the original state was correct autoreplace can skip this. */
 
		CommandCost ret = ValidateTrains(original_dst_head, dst_head, original_src_head, src_head, true);
 
		ret = ValidateTrains(original_dst_head, dst_head, original_src_head, src_head, true);
 
		if (ret.Failed()) {
 
			/* Restore the train we had. */
 
			RestoreTrainBackup(original_src);
 
			RestoreTrainBackup(original_dst);
 
			return ret;
 
		}
 
	}
 

	
 
	/* do it? */
 
	if (flags & DC_EXEC) {
 
		/* Remove old heads from the statistics */
 
		if (original_src_head_front_engine) GroupStatistics::CountVehicle(original_src_head, -1);
 
		if (original_dst_head_front_engine) GroupStatistics::CountVehicle(original_dst_head, -1);
 

	
 
		/* First normalise the sub types of the chains. */
 
		NormaliseSubtypes(src_head);
 
		NormaliseSubtypes(dst_head);
 

	
 
		/* There are 14 different cases:
 
		 *  1) front engine gets moved to a new train, it stays a front engine.
 
		 *     a) the 'next' part is a wagon that becomes a free wagon chain.
 
		 *     b) the 'next' part is an engine that becomes a front engine.
 
		 *     c) there is no 'next' part, nothing else happens
 
		 *  2) front engine gets moved to another train, it is not a front engine anymore