Files @ r24498:e9114d9ab04a
Branch filter:

Location: cpp/openttd-patchpack/source/src/vehiclelist.cpp - annotation

Patric Stout
Fix #6468: don't store version of AIs-started-via-console in name

You can do: "startai myai.3", which starts version 3 of "myai".
This is very useful for testing save/load code between different
versions of your AI.

However, when using this syntax, the AI got saved as "myai.3" as
name of the AI, instead of "myai". This caused several problems,
like indicating to the user the AI could not be found, but still
load the AI. But in all cases, the AI never got the chance to
load the saved data, making the whole reason this exists pointless.

By splitting the name and version already in the console command,
the code becomes simpler and AIs started this way now follow the
normal flow after initialization.
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r10238:f2215d7dd22b
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r21353:433db3a92931
r9396:9c082e37fcdf
r21383:942c32fb8b0e
r21383:942c32fb8b0e
r9396:9c082e37fcdf
r16069:5049a8060a4d
r16069:5049a8060a4d
r16069:5049a8060a4d
r21556:54687a87c1ce
r16069:5049a8060a4d
r19345:0ce699e7c1d3
r19345:0ce699e7c1d3
r16069:5049a8060a4d
r16069:5049a8060a4d
r20912:595943d1a598
r20912:595943d1a598
r16069:5049a8060a4d
r19345:0ce699e7c1d3
r16069:5049a8060a4d
r16069:5049a8060a4d
r16069:5049a8060a4d
r16069:5049a8060a4d
r16069:5049a8060a4d
r16069:5049a8060a4d
r16069:5049a8060a4d
r22470:ad7ada400287
r16069:5049a8060a4d
r19345:0ce699e7c1d3
r19345:0ce699e7c1d3
r16069:5049a8060a4d
r16069:5049a8060a4d
r16069:5049a8060a4d
r16069:5049a8060a4d
r16069:5049a8060a4d
r16069:5049a8060a4d
r16069:5049a8060a4d
r16069:5049a8060a4d
r16069:5049a8060a4d
r16069:5049a8060a4d
r16069:5049a8060a4d
r22470:ad7ada400287
r16069:5049a8060a4d
r22470:ad7ada400287
r22470:ad7ada400287
r16069:5049a8060a4d
r22470:ad7ada400287
r16069:5049a8060a4d
r16069:5049a8060a4d
r16069:5049a8060a4d
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r23607:36c15679007d
r19478:8cc1ec86658e
r9396:9c082e37fcdf
r10193:9b282b96cd44
r9396:9c082e37fcdf
r23517:1a32c3c14728
r23607:36c15679007d
r9396:9c082e37fcdf
r23966:9de0a0960701
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r12291:690f4158878e
r12291:690f4158878e
r12292:c3b6baef441a
r12291:690f4158878e
r23607:36c15679007d
r23532:dc91fcd293f5
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r12291:690f4158878e
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r23532:dc91fcd293f5
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r23518:3531e6987951
r23607:36c15679007d
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r16068:f32ba8cfc408
r16068:f32ba8cfc408
r15029:7607b8c4cbd9
r9396:9c082e37fcdf
r16068:f32ba8cfc408
r9396:9c082e37fcdf
r23517:1a32c3c14728
r9396:9c082e37fcdf
r16068:f32ba8cfc408
r16068:f32ba8cfc408
r23966:9de0a0960701
r16069:5049a8060a4d
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r17683:ed148d83dec5
r16068:f32ba8cfc408
r23532:dc91fcd293f5
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r23966:9de0a0960701
r9942:8032a9a93376
r23966:9de0a0960701
r23607:36c15679007d
r15029:7607b8c4cbd9
r23607:36c15679007d
r23532:dc91fcd293f5
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r23966:9de0a0960701
r9396:9c082e37fcdf
r16073:ea3fc2143f27
r16073:ea3fc2143f27
r23966:9de0a0960701
r16073:ea3fc2143f27
r21353:433db3a92931
r23532:dc91fcd293f5
r16073:ea3fc2143f27
r16073:ea3fc2143f27
r16073:ea3fc2143f27
r16073:ea3fc2143f27
r22672:3473f7daf422
r16073:ea3fc2143f27
r16068:f32ba8cfc408
r23966:9de0a0960701
r16069:5049a8060a4d
r23532:dc91fcd293f5
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r16068:f32ba8cfc408
r23966:9de0a0960701
r16069:5049a8060a4d
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r16068:f32ba8cfc408
r23532:dc91fcd293f5
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r15029:7607b8c4cbd9
r9396:9c082e37fcdf
r9396:9c082e37fcdf
r23518:3531e6987951
r15029:7607b8c4cbd9
r9396:9c082e37fcdf
/*
 * This file is part of OpenTTD.
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 */

/** @file vehiclelist.cpp Lists of vehicles. */

#include "stdafx.h"
#include "train.h"
#include "vehiclelist.h"
#include "group.h"

#include "safeguards.h"

/**
 * Pack a VehicleListIdentifier in a single uint32.
 * @return The packed identifier.
 */
uint32 VehicleListIdentifier::Pack() const
{
	byte c = this->company == OWNER_NONE ? 0xF : (byte)this->company;
	assert(c             < (1 <<  4));
	assert(this->vtype   < (1 <<  2));
	assert(this->index   < (1 << 20));
	assert(this->type    < VLT_END);
	assert_compile(VLT_END <= (1 <<  3));

	return c << 28 | this->type << 23 | this->vtype << 26 | this->index;
}

/**
 * Unpack a VehicleListIdentifier from a single uint32.
 * @param data The data to unpack.
 * @return true iff the data was valid (enough).
 */
bool VehicleListIdentifier::UnpackIfValid(uint32 data)
{
	byte c        = GB(data, 28, 4);
	this->company = c == 0xF ? OWNER_NONE : (CompanyID)c;
	this->type    = (VehicleListType)GB(data, 23, 3);
	this->vtype   = (VehicleType)GB(data, 26, 2);
	this->index   = GB(data, 0, 20);

	return this->type < VLT_END;
}

/**
 * Decode a packed vehicle list identifier into a new one.
 * @param data The data to unpack.
 */
/* static */ VehicleListIdentifier VehicleListIdentifier::UnPack(uint32 data)
{
	VehicleListIdentifier result;
	bool ret = result.UnpackIfValid(data);
	assert(ret);
	return result;
}

/**
 * Generate a list of vehicles inside a depot.
 * @param type    Type of vehicle
 * @param tile    The tile the depot is located on
 * @param engines Pointer to list to add vehicles to
 * @param wagons  Pointer to list to add wagons to (can be nullptr)
 * @param individual_wagons If true add every wagon to \a wagons which is not attached to an engine. If false only add the first wagon of every row.
 */
void BuildDepotVehicleList(VehicleType type, TileIndex tile, VehicleList *engines, VehicleList *wagons, bool individual_wagons)
{
	engines->clear();
	if (wagons != nullptr && wagons != engines) wagons->clear();

	for (const Vehicle *v : Vehicle::Iterate()) {
		/* General tests for all vehicle types */
		if (v->type != type) continue;
		if (v->tile != tile) continue;

		switch (type) {
			case VEH_TRAIN: {
				const Train *t = Train::From(v);
				if (t->IsArticulatedPart() || t->IsRearDualheaded()) continue;
				if (t->track != TRACK_BIT_DEPOT) continue;
				if (wagons != nullptr && t->First()->IsFreeWagon()) {
					if (individual_wagons || t->IsFreeWagon()) wagons->push_back(t);
					continue;
				}
				break;
			}

			default:
				if (!v->IsInDepot()) continue;
				break;
		}

		if (!v->IsPrimaryVehicle()) continue;

		engines->push_back(v);
	}

	/* Ensure the lists are not wasting too much space. If the lists are fresh
	 * (i.e. built within a command) then this will actually do nothing. */
	engines->shrink_to_fit();
	if (wagons != nullptr && wagons != engines) wagons->shrink_to_fit();
}

/**
 * Generate a list of vehicles based on window type.
 * @param list Pointer to list to add vehicles to
 * @param vli  The identifier of this vehicle list.
 * @return false if invalid list is requested
 */
bool GenerateVehicleSortList(VehicleList *list, const VehicleListIdentifier &vli)
{
	list->clear();

	switch (vli.type) {
		case VL_STATION_LIST:
			for (const Vehicle *v : Vehicle::Iterate()) {
				if (v->type == vli.vtype && v->IsPrimaryVehicle()) {
					const Order *order;

					FOR_VEHICLE_ORDERS(v, order) {
						if ((order->IsType(OT_GOTO_STATION) || order->IsType(OT_GOTO_WAYPOINT) || order->IsType(OT_IMPLICIT))
								&& order->GetDestination() == vli.index) {
							list->push_back(v);
							break;
						}
					}
				}
			}
			break;

		case VL_SHARED_ORDERS: {
			/* Add all vehicles from this vehicle's shared order list */
			const Vehicle *v = Vehicle::GetIfValid(vli.index);
			if (v == nullptr || v->type != vli.vtype || !v->IsPrimaryVehicle()) return false;

			for (; v != nullptr; v = v->NextShared()) {
				list->push_back(v);
			}
			break;
		}

		case VL_GROUP_LIST:
			if (vli.index != ALL_GROUP) {
				for (const Vehicle *v : Vehicle::Iterate()) {
					if (v->type == vli.vtype && v->IsPrimaryVehicle() &&
							v->owner == vli.company && GroupIsInGroup(v->group_id, vli.index)) {
						list->push_back(v);
					}
				}
				break;
			}
			FALLTHROUGH;

		case VL_STANDARD:
			for (const Vehicle *v : Vehicle::Iterate()) {
				if (v->type == vli.vtype && v->owner == vli.company && v->IsPrimaryVehicle()) {
					list->push_back(v);
				}
			}
			break;

		case VL_DEPOT_LIST:
			for (const Vehicle *v : Vehicle::Iterate()) {
				if (v->type == vli.vtype && v->IsPrimaryVehicle()) {
					const Order *order;

					FOR_VEHICLE_ORDERS(v, order) {
						if (order->IsType(OT_GOTO_DEPOT) && !(order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) && order->GetDestination() == vli.index) {
							list->push_back(v);
							break;
						}
					}
				}
			}
			break;

		default: return false;
	}

	list->shrink_to_fit();
	return true;
}