Changeset - r10696:8dfe83e30d01
[Not reviewed]
master
9 60 188
truebrain - 15 years ago 2009-01-12 17:11:45
truebrain@openttd.org
(svn r15027) -Merge: tomatos and bananas left to be, here is NoAI for all to see.
NoAI is an API (a framework) to build your own AIs in. See:
http://wiki.openttd.org/wiki/index.php/AI:Main_Page
With many thanks to:
- glx and Rubidium for their syncing, feedback and hard work
- Yexo for his feedback, patches, and AIs which tested the system very deep
- Morloth for his feedback and patches
- TJIP for hosting a challenge which kept NoAI on track
- All AI authors for testing our AI API, and all other people who helped in one way or another
-Remove: all old AIs and their cheats/hacks
257 files changed with 34649 insertions and 7605 deletions:
source.list
167
10
0 comments (0 inline, 0 general)
Makefile.bundle.in
Show inline comments
 
@@ -39,6 +39,7 @@ bundle: all
 
	$(Q)mkdir -p "$(BUNDLE_DIR)/scenario"
 
	$(Q)mkdir -p "$(BUNDLE_DIR)/scenario/heightmap"
 
	$(Q)mkdir -p "$(BUNDLE_DIR)/media"
 
	$(Q)mkdir -p "$(BUNDLE_DIR)/ai"
 
	$(Q)mkdir -p "$(BUNDLE_DIR)/scripts"
 
	$(Q)mkdir -p "$(TTD_DIR)"
 
	$(Q)mkdir -p "$(DATA_DIR)"
 
@@ -75,6 +76,10 @@ ifdef MENU_DIR
 
	$(Q)cp "$(ROOT_DIR)/media/openttd.desktop" "$(BUNDLE_DIR)/media/"
 
	$(Q)cat "$(ROOT_DIR)/media/openttd.desktop" | sed s/=openttd/=$(BINARY_NAME)/g > "$(ROOT_DIR)/media/openttd.desktop.install"
 
endif
 
ifeq ($(shell if test -n "`ls -l \"$(BIN_DIR)/ai/\"* 2>/dev/null`"; then echo 1; fi), 1)
 
	$(Q)cp -R "$(BIN_DIR)/ai/"*               "$(BUNDLE_DIR)/ai/"
 
	$(Q)find $(BUNDLE_DIR)/ai/ -depth -iname '*.svn' -exec rm -Rf {} \; || find $(BUNDLE_DIR)/ai/ -d -iname '*.svn' -exec rm -Rf {} \;
 
endif
 
ifeq ($(shell if test -n "`ls -l \"$(BIN_DIR)/scenario/\"*.scn 2> /dev/null`"; then echo 1; fi), 1)
 
	$(Q)cp "$(BIN_DIR)/scenario/"*.scn        "$(BUNDLE_DIR)/scenario/"
 
endif
Makefile.in
Show inline comments
 
@@ -141,6 +141,9 @@ run-gdb: all
 
run-prof: all
 
	$(Q)cd !!BIN_DIR!! && ./!!TTD!! $(OPENTTD_ARGS) && gprof !!TTD!! | less
 

	
 
regression: all
 
	$(Q)cd !!BIN_DIR!! && sh ai/regression/run.sh
 

	
 
%.o:
 
	@for dir in $(SRC_DIRS); do \
 
		$(MAKE) -C $$dir $(@:src/%=%); \
Makefile.src.in
Show inline comments
 
@@ -15,6 +15,7 @@ LANG_DIR     = !!LANG_DIR!!
 
SRC_OBJS_DIR = !!SRC_OBJS_DIR!!
 
LANG_OBJS_DIR= !!LANG_OBJS_DIR!!
 
SRC_DIR      = !!SRC_DIR!!
 
SCRIPT_SRC_DIR=!!SCRIPT_SRC_DIR!!
 
MEDIA_DIR    = !!MEDIA_DIR!!
 
TTD          = !!TTD!!
 
STRGEN       = !!STRGEN!!
 
@@ -48,7 +49,7 @@ RES      := $(shell mkdir -p $(BIN_DIR) 
 

	
 
# Make sure endian_target.h is reasable as if it was in the src/ dir
 
CFLAGS += -I $(SRC_OBJS_DIR) -I $(LANG_OBJS_DIR)
 
CFLAGS_MAKEDEP += -I $(SRC_OBJS_DIR) -I $(LANG_OBJS_DIR)
 
CFLAGS_MAKEDEP += -I $(SRC_OBJS_DIR) -I $(LANG_OBJS_DIR) -I $(SCRIPT_SRC_DIR)
 

	
 
ENDIAN_TARGETS := endian_target.h $(ENDIAN_CHECK)
 

	
 
@@ -216,10 +217,10 @@ endif
 

	
 
endif
 

	
 
# Avoid problems with deps if a .h/.hpp file is deleted without the deps
 
# Avoid problems with deps if a .h/.hpp/.hpp.sq file is deleted without the deps
 
#  being updated. Now the Makefile continues, the deps are recreated
 
#  and all will be fine.
 
%.h %.hpp:
 
%.h %.hpp %.hpp.sq:
 
	@true
 

	
 

	
bin/ai/library/graph/aystar/library.nut
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
class AyStar extends AILibrary {
 
	function GetAuthor()      { return "OpenTTD NoAI Developers Team"; }
 
	function GetName()        { return "AyStar"; }
 
	function GetDescription() { return "An implementation of AyStar"; }
 
	function GetVersion()     { return 4; }
 
	function GetDate()        { return "2008-06-11"; }
 
	function CreateInstance() { return "AyStar"; }
 
}
 

	
 
RegisterLibrary(AyStar());
bin/ai/library/graph/aystar/main.nut
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/**
 
 * An AyStar implementation.
 
 *  It solves graphs by finding the fastest route from one point to the other.
 
 */
 
class AyStar
 
{
 
	_queue_class = import("queue.binary_heap", "", 1);
 
	_cost_callback = null;
 
	_estimate_callback = null;
 
	_neighbours_callback = null;
 
	_check_direction_callback = null;
 
	_cost_callback_param = null;
 
	_estimate_callback_param = null;
 
	_neighbours_callback_param = null;
 
	_check_direction_callback_param = null;
 
	_open = null;
 
	_closed = null;
 
	_goals = null;
 

	
 
	/**
 
	 * @param cost_callback A function that returns the cost of a path. It
 
	 *  should accept four parameters, old_path, new_tile, new_direction and
 
	 *  cost_callback_param. old_path is an instance of AyStar.Path, and
 
	 *  new_node is the new node that is added to that path. It should return
 
	 *  the cost of the path including new_node.
 
	 * @param estimate_callback A function that returns an estimate from a node
 
	 *  to the goal node. It should accept four parameters, tile, direction,
 
	 *  goal_nodes and estimate_callback_param. It should return an estimate to
 
	 *  the cost from the lowest cost between node and any node out of goal_nodes.
 
	 *  Note that this estimate is not allowed to be higher than the real cost
 
	 *  between node and any of goal_nodes. A lower value is fine, however the
 
	 *  closer it is to the real value, the better the performance.
 
	 * @param neighbours_callback A function that returns all neighbouring nodes
 
	 *  from a given node. It should accept three parameters, current_path, node
 
	 *  and neighbours_callback_param. It should return an array containing all
 
	 *  neighbouring nodes, which are an array in the form [tile, direction].
 
	 * @param check_direction_callback A function that returns either false or
 
	 *  true. It should accept four parameters, tile, existing_direction,
 
	 *  new_direction and check_direction_callback_param. It should check
 
	 *  if both directions can go together on a single tile.
 
	 * @param cost_callback_param This parameters will be passed to cost_callback
 
	 *  as fourth parameter. Useful to send is an instance of an object.
 
	 * @param estimate_callback_param This parameters will be passed to
 
	 *  estimate_callback as fourth parameter. Useful to send is an instance of an
 
	 *  object.
 
	 * @param neighbours_callback_param This parameters will be passed to
 
	 *  neighbours_callback as third parameter. Useful to send is an instance of
 
	 *  an object.
 
	 * @param check_direction_callback_param This parameters will be passed to
 
	 *  check_direction_callback as fourth parameter. Useful to send is an
 
	 *  instance of an object.
 
	 */
 
	constructor(cost_callback, estimate_callback, neighbours_callback, check_direction_callback, cost_callback_param = null,
 
	            estimate_callback_param = null, neighbours_callback_param = null, check_direction_callback_param = null)
 
	{
 
		if (typeof(cost_callback) != "function") throw("'cost_callback' has to be a function-pointer.");
 
		if (typeof(estimate_callback) != "function") throw("'estimate_callback' has to be a function-pointer.");
 
		if (typeof(neighbours_callback) != "function") throw("'neighbours_callback' has to be a function-pointer.");
 
		if (typeof(check_direction_callback) != "function") throw("'check_direction_callback' has to be a function-pointer.");
 

	
 
		this._cost_callback = cost_callback;
 
		this._estimate_callback = estimate_callback;
 
		this._neighbours_callback = neighbours_callback;
 
		this._check_direction_callback = check_direction_callback;
 
		this._cost_callback_param = cost_callback_param;
 
		this._estimate_callback_param = estimate_callback_param;
 
		this._neighbours_callback_param = neighbours_callback_param;
 
		this._check_direction_callback_param = check_direction_callback_param;
 
	}
 

	
 
	/**
 
	 * Initialize a path search between sources and goals.
 
	 * @param sources The source nodes. This can an array of either [tile, direction]-pairs or AyStar.Path-instances.
 
	 * @param goals The target tiles. This can be an array of either tiles or [tile, next_tile]-pairs.
 
	 * @param ignored_tiles An array of tiles that cannot occur in the final path.
 
	 */
 
	function InitializePath(sources, goals, ignored_tiles = []);
 

	
 
	/**
 
	 * Try to find the path as indicated with InitializePath with the lowest cost.
 
	 * @param iterations After how many iterations it should abort for a moment.
 
	 *  This value should either be -1 for infinite, or > 0. Any other value
 
	 *  aborts immediatly and will never find a path.
 
	 * @return A route if one was found, or false if the amount of iterations was
 
	 *  reached, or null if no path was found.
 
	 *  You can call this function over and over as long as it returns false,
 
	 *  which is an indication it is not yet done looking for a route.
 
	 */
 
	function FindPath(iterations);
 
};
 

	
 
function AyStar::InitializePath(sources, goals, ignored_tiles = [])
 
{
 
	if (typeof(sources) != "array" || sources.len() == 0) throw("sources has be a non-empty array.");
 
	if (typeof(goals) != "array" || goals.len() == 0) throw("goals has be a non-empty array.");
 

	
 
	this._open = this._queue_class();
 
	this._closed = AIList();
 

	
 
	foreach (node in sources) {
 
		if (typeof(node) == "array") {
 
			if (node[1] <= 0) throw("directional value should never be zero or negative.");
 

	
 
			local new_path = this.Path(null, node[0], node[1], this._cost_callback, this._cost_callback_param);
 
			this._open.Insert(new_path, new_path.GetCost() + this._estimate_callback(node[0], node[1], goals, this._estimate_callback_param));
 
		} else {
 
			this._open.Insert(node, node.GetCost());
 
		}
 
	}
 

	
 
	this._goals = goals;
 

	
 
	foreach (tile in ignored_tiles) {
 
		this._closed.AddItem(tile, ~0);
 
	}
 
}
 

	
 
function AyStar::FindPath(iterations)
 
{
 
	if (this._open == null) throw("can't execute over an uninitialized path");
 

	
 
	while (this._open.Count() > 0 && (iterations == -1 || iterations-- > 0)) {
 
		/* Get the path with the best score so far */
 
		local path = this._open.Pop();
 
		local cur_tile = path.GetTile();
 
		/* Make sure we didn't already passed it */
 
		if (this._closed.HasItem(cur_tile)) {
 
			/* If the direction is already on the list, skip this entry */
 
			if ((this._closed.GetValue(cur_tile) & path.GetDirection()) != 0) continue;
 

	
 
			/* Scan the path for a possible collision */
 
			local scan_path = path.GetParent();
 

	
 
			local mismatch = false;
 
			while (scan_path != null) {
 
				if (scan_path.GetTile() == cur_tile) {
 
					if (!this._check_direction_callback(cur_tile, scan_path.GetDirection(), path.GetDirection(), this._check_direction_callback_param)) {
 
						mismatch = true;
 
						break;
 
					}
 
				}
 
				scan_path = scan_path.GetParent();
 
			}
 
			if (mismatch) continue;
 

	
 
			/* Add the new direction */
 
			this._closed.SetValue(cur_tile, this._closed.GetValue(cur_tile) | path.GetDirection());
 
		} else {
 
			/* New entry, make sure we don't check it again */
 
			this._closed.AddItem(cur_tile, path.GetDirection());
 
		}
 
		/* Check if we found the end */
 
		foreach (goal in this._goals) {
 
			if (typeof(goal) == "array") {
 
				if (cur_tile == goal[0]) {
 
					local neighbours = this._neighbours_callback(path, cur_tile, this._neighbours_callback_param);
 
					foreach (node in neighbours) {
 
						if (node[0] == goal[1]) {
 
							this._CleanPath();
 
							return path;
 
						}
 
					}
 
					continue;
 
				}
 
			} else {
 
				if (cur_tile == goal) {
 
					this._CleanPath();
 
					return path;
 
				}
 
			}
 
		}
 
		/* Scan all neighbours */
 
		local neighbours = this._neighbours_callback(path, cur_tile, this._neighbours_callback_param);
 
		foreach (node in neighbours) {
 
			if (node[1] <= 0) throw("directional value should never be zero or negative.");
 

	
 
			if ((this._closed.GetValue(node[0]) & node[1]) != 0) continue;
 
			/* Calculate the new paths and add them to the open list */
 
			local new_path = this.Path(path, node[0], node[1], this._cost_callback, this._cost_callback_param);
 
			this._open.Insert(new_path, new_path.GetCost() + this._estimate_callback(node[0], node[1], this._goals, this._estimate_callback_param));
 
		}
 
	}
 

	
 
	if (this._open.Count() > 0) return false;
 
	this._CleanPath();
 
	return null;
 
}
 

	
 
function AyStar::_CleanPath()
 
{
 
	this._closed = null;
 
	this._open = null;
 
	this._goals = null;
 
}
 

	
 
/**
 
 * The path of the AyStar algorithm.
 
 *  It is reversed, that is, the first entry is more close to the goal-nodes
 
 *  than his GetParent(). You can walk this list to find the whole path.
 
 *  The last entry has a GetParent() of null.
 
 */
 
class AyStar.Path
 
{
 
	_prev = null;
 
	_tile = null;
 
	_direction = null;
 
	_cost = null;
 

	
 
	constructor(old_path, new_tile, new_direction, cost_callback, cost_callback_param)
 
	{
 
		this._prev = old_path;
 
		this._tile = new_tile;
 
		this._direction = new_direction;
 
		this._cost = cost_callback(old_path, new_tile, new_direction, cost_callback_param);
 
	};
 

	
 
	/**
 
	 * Return the tile where this (partial-)path ends.
 
	 */
 
	function GetTile() { return this._tile; }
 

	
 
	/**
 
	 * Return the direction from which we entered the tile in this (partial-)path.
 
	 */
 
	function GetDirection() { return this._direction; }
 

	
 
	/**
 
	 * Return an instance of this class leading to the previous node.
 
	 */
 
	function GetParent() { return this._prev; }
 

	
 
	/**
 
	 * Return the cost of this (partial-)path from the beginning up to this node.
 
	 */
 
	function GetCost() { return this._cost; }
 
};
bin/ai/library/pathfinder/rail/library.nut
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
class Rail extends AILibrary {
 
	function GetAuthor()      { return "OpenTTD NoAI Developers Team"; }
 
	function GetName()        { return "Rail"; }
 
	function GetDescription() { return "An implementation of a rail pathfinder"; }
 
	function GetVersion()     { return 1; }
 
	function GetDate()        { return "2008-09-22"; }
 
	function CreateInstance() { return "Rail"; }
 
}
 

	
 
RegisterLibrary(Rail());
bin/ai/library/pathfinder/rail/main.nut
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/**
 
 * A Rail Pathfinder.
 
 */
 
class Rail
 
{
 
	_aystar_class = import("graph.aystar", "", 4);
 
	_max_cost = null;              ///< The maximum cost for a route.
 
	_cost_tile = null;             ///< The cost for a single tile.
 
	_cost_diagonal_tile = null;    ///< The cost for a diagonal tile.
 
	_cost_turn = null;             ///< The cost that is added to _cost_tile if the direction changes.
 
	_cost_slope = null;            ///< The extra cost if a rail tile is sloped.
 
	_cost_bridge_per_tile = null;  ///< The cost per tile of a new bridge, this is added to _cost_tile.
 
	_cost_tunnel_per_tile = null;  ///< The cost per tile of a new tunnel, this is added to _cost_tile.
 
	_cost_coast = null;            ///< The extra cost for a coast tile.
 
	_pathfinder = null;            ///< A reference to the used AyStar object.
 
	_max_bridge_length = null;     ///< The maximum length of a bridge that will be build.
 
	_max_tunnel_length = null;     ///< The maximum length of a tunnel that will be build.
 

	
 
	cost = null;                   ///< Used to change the costs.
 
	_running = null;
 
	_goals = null;
 

	
 
	constructor()
 
	{
 
		this._max_cost = 10000000;
 
		this._cost_tile = 100;
 
		this._cost_diagonal_tile = 70;
 
		this._cost_turn = 50;
 
		this._cost_slope = 100;
 
		this._cost_bridge_per_tile = 150;
 
		this._cost_tunnel_per_tile = 120;
 
		this._cost_coast = 20;
 
		this._max_bridge_length = 6;
 
		this._max_tunnel_length = 6;
 
		this._pathfinder = this._aystar_class(this._Cost, this._Estimate, this._Neighbours, this._CheckDirection, this, this, this, this);
 

	
 
		this.cost = this.Cost(this);
 
		this._running = false;
 
	}
 

	
 
	/**
 
	 * Initialize a path search between sources and goals.
 
	 * @param sources The source tiles.
 
	 * @param goals The target tiles.
 
	 * @param ignored_tiles An array of tiles that cannot occur in the final path.
 
	 * @see AyStar::InitializePath()
 
	 */
 
	function InitializePath(sources, goals, ignored_tiles = []) {
 
		local nsources = [];
 

	
 
		foreach (node in sources) {
 
			local path = this._pathfinder.Path(null, node[1], 0xFF, this._Cost, this);
 
			path = this._pathfinder.Path(path, node[0], 0xFF, this._Cost, this);
 
			nsources.push(path);
 
		}
 
		this._goals = goals;
 
		this._pathfinder.InitializePath(nsources, goals, ignored_tiles);
 
	}
 

	
 
	/**
 
	 * Try to find the path as indicated with InitializePath with the lowest cost.
 
	 * @param iterations After how many iterations it should abort for a moment.
 
	 *  This value should either be -1 for infinite, or > 0. Any other value
 
	 *  aborts immediatly and will never find a path.
 
	 * @return A route if one was found, or false if the amount of iterations was
 
	 *  reached, or null if no path was found.
 
	 *  You can call this function over and over as long as it returns false,
 
	 *  which is an indication it is not yet done looking for a route.
 
	 * @see AyStar::FindPath()
 
	 */
 
	function FindPath(iterations);
 
};
 

	
 
class Rail.Cost
 
{
 
	_main = null;
 

	
 
	function _set(idx, val)
 
	{
 
		if (this._main._running) throw("You are not allowed to change parameters of a running pathfinder.");
 

	
 
		switch (idx) {
 
			case "max_cost":          this._main._max_cost = val; break;
 
			case "tile":              this._main._cost_tile = val; break;
 
			case "diagonal_tile":     this._cost_diagonal_tile = val; break;
 
			case "turn":              this._main._cost_turn = val; break;
 
			case "slope":             this._main._cost_slope = val; break;
 
			case "bridge_per_tile":   this._main._cost_bridge_per_tile = val; break;
 
			case "tunnel_per_tile":   this._main._cost_tunnel_per_tile = val; break;
 
			case "coast":             this._main._cost_coast = val; break;
 
			case "max_bridge_length": this._main._max_bridge_length = val; break;
 
			case "max_tunnel_length": this._main._max_tunnel_length = val; break;
 
			default: throw("the index '" + idx + "' does not exist");
 
		}
 

	
 
		return val;
 
	}
 

	
 
	function _get(idx)
 
	{
 
		switch (idx) {
 
			case "max_cost":          return this._main._max_cost;
 
			case "tile":              return this._main._cost_tile;
 
			case "diagonal_tile":     return this._cost_diagonal_tile;
 
			case "turn":              return this._main._cost_turn;
 
			case "slope":             return this._main._cost_slope;
 
			case "bridge_per_tile":   return this._main._cost_bridge_per_tile;
 
			case "tunnel_per_tile":   return this._main._cost_tunnel_per_tile;
 
			case "coast":             return this._main._cost_coast;
 
			case "max_bridge_length": return this._main._max_bridge_length;
 
			case "max_tunnel_length": return this._main._max_tunnel_length;
 
			default: throw("the index '" + idx + "' does not exist");
 
		}
 
	}
 

	
 
	constructor(main)
 
	{
 
		this._main = main;
 
	}
 
};
 

	
 
function Rail::FindPath(iterations)
 
{
 
	local test_mode = AITestMode();
 
	local ret = this._pathfinder.FindPath(iterations);
 
	this._running = (ret == false) ? true : false;
 
	if (!this._running && ret != null) {
 
		foreach (goal in this._goals) {
 
			if (goal[0] == ret.GetTile()) {
 
				return this._pathfinder.Path(ret, goal[1], 0, this._Cost, this);
 
			}
 
		}
 
	}
 
	return ret;
 
}
 

	
 
function Rail::_GetBridgeNumSlopes(end_a, end_b)
 
{
 
	local slopes = 0;
 
	local direction = (end_b - end_a) / AIMap.DistanceManhattan(end_a, end_b);
 
	local slope = AITile.GetSlope(end_a);
 
	if (!((slope == AITile.SLOPE_NE && direction == 1) || (slope == AITile.SLOPE_SE && direction == -AIMap.GetMapSizeX()) ||
 
		(slope == AITile.SLOPE_SW && direction == -1) || (slope == AITile.SLOPE_NW && direction == AIMap.GetMapSizeX()) ||
 
		 slope == AITile.SLOPE_N || slope == AITile.SLOPE_E || slope == AITile.SLOPE_S || slope == AITile.SLOPE_W)) {
 
		slopes++;
 
	}
 

	
 
	local slope = AITile.GetSlope(end_b);
 
	direction = -direction;
 
	if (!((slope == AITile.SLOPE_NE && direction == 1) || (slope == AITile.SLOPE_SE && direction == -AIMap.GetMapSizeX()) ||
 
		(slope == AITile.SLOPE_SW && direction == -1) || (slope == AITile.SLOPE_NW && direction == AIMap.GetMapSizeX()) ||
 
		 slope == AITile.SLOPE_N || slope == AITile.SLOPE_E || slope == AITile.SLOPE_S || slope == AITile.SLOPE_W)) {
 
		slopes++;
 
	}
 
	return slopes;
 
}
 

	
 
function Rail::_nonzero(a, b)
 
{
 
	return a != 0 ? a : b;
 
}
 

	
 
function Rail::_Cost(path, new_tile, new_direction, self)
 
{
 
	/* path == null means this is the first node of a path, so the cost is 0. */
 
	if (path == null) return 0;
 

	
 
	local prev_tile = path.GetTile();
 

	
 
	/* If the new tile is a bridge / tunnel tile, check whether we came from the other
 
	 *  end of the bridge / tunnel or if we just entered the bridge / tunnel. */
 
	if (AIBridge.IsBridgeTile(new_tile)) {
 
		if (AIBridge.GetOtherBridgeEnd(new_tile) != prev_tile) {
 
			local cost = path.GetCost() + self._cost_tile;
 
			if (path.GetParent() != null && path.GetParent().GetTile() - prev_tile != prev_tile - new_tile) cost += self._cost_turn;
 
			return cost;
 
		}
 
		return path.GetCost() + AIMap.DistanceManhattan(new_tile, prev_tile) * self._cost_tile + self._GetBridgeNumSlopes(new_tile, prev_tile) * self._cost_slope;
 
	}
 
	if (AITunnel.IsTunnelTile(new_tile)) {
 
		if (AITunnel.GetOtherTunnelEnd(new_tile) != prev_tile) {
 
			local cost = path.GetCost() + self._cost_tile;
 
			if (path.GetParent() != null && path.GetParent().GetTile() - prev_tile != prev_tile - new_tile) cost += self._cost_turn;
 
			return cost;
 
		}
 
		return path.GetCost() + AIMap.DistanceManhattan(new_tile, prev_tile) * self._cost_tile;
 
	}
 

	
 
	/* If the two tiles are more then 1 tile apart, the pathfinder wants a bridge or tunnel
 
	 *  to be build. It isn't an existing bridge / tunnel, as that case is already handled. */
 
	if (AIMap.DistanceManhattan(new_tile, prev_tile) > 1) {
 
		/* Check if we should build a bridge or a tunnel. */
 
		local cost = path.GetCost();
 
		if (AITunnel.GetOtherTunnelEnd(new_tile) == prev_tile) {
 
			cost += AIMap.DistanceManhattan(new_tile, prev_tile) * (self._cost_tile + self._cost_tunnel_per_tile);
 
		} else {
 
			cost += AIMap.DistanceManhattan(new_tile, prev_tile) * (self._cost_tile + self._cost_bridge_per_tile) + self._GetBridgeNumSlopes(new_tile, prev_tile) * self._cost_slope;
 
		}
 
		if (path.GetParent() != null && path.GetParent().GetParent() != null &&
 
				path.GetParent().GetParent().GetTile() - path.GetParent().GetTile() != max(AIMap.GetTileX(prev_tile) - AIMap.GetTileX(new_tile), AIMap.GetTileY(prev_tile) - AIMap.GetTileY(new_tile)) / AIMap.DistanceManhattan(new_tile, prev_tile)) {
 
			cost += self._cost_turn;
 
		}
 
		return cost;
 
	}
 

	
 
	/* Check for a turn. We do this by substracting the TileID of the current
 
	 *  node from the TileID of the previous node and comparing that to the
 
	 *  difference between the tile before the previous node and the node before
 
	 *  that. */
 
	local cost = self._cost_tile;
 
	if (path.GetParent() != null && AIMap.DistanceManhattan(path.GetParent().GetTile(), prev_tile) == 1 && path.GetParent().GetTile() - prev_tile != prev_tile - new_tile) cost = self._cost_diagonal_tile;
 
	if (path.GetParent() != null && path.GetParent().GetParent() != null &&
 
			AIMap.DistanceManhattan(new_tile, path.GetParent().GetParent().GetTile()) == 3 &&
 
			path.GetParent().GetParent().GetTile() - path.GetParent().GetTile() != prev_tile - new_tile) {
 
		cost += self._cost_turn;
 
	}
 

	
 
	/* Check if the new tile is a coast tile. */
 
	if (AITile.IsCoastTile(new_tile)) {
 
		cost += self._cost_coast;
 
	}
 

	
 
	/* Check if the last tile was sloped. */
 
	if (path.GetParent() != null && !AIBridge.IsBridgeTile(prev_tile) && !AITunnel.IsTunnelTile(prev_tile) &&
 
			self._IsSlopedRail(path.GetParent().GetTile(), prev_tile, new_tile)) {
 
		cost += self._cost_slope;
 
	}
 

	
 
	/* We don't use already existing rail, so the following code is unused. It
 
	 *  assigns if no rail exists along the route. */
 
	/*
 
	if (path.GetParent() != null && !AIRail.AreTilesConnected(path.GetParent().GetTile(), prev_tile, new_tile)) {
 
		cost += self._cost_no_existing_rail;
 
	}
 
	*/
 

	
 
	return path.GetCost() + cost;
 
}
 

	
 
function Rail::_Estimate(cur_tile, cur_direction, goal_tiles, self)
 
{
 
	local min_cost = self._max_cost;
 
	/* As estimate we multiply the lowest possible cost for a single tile with
 
	 *  with the minimum number of tiles we need to traverse. */
 
	foreach (tile in goal_tiles) {
 
		local dx = abs(AIMap.GetTileX(cur_tile) - AIMap.GetTileX(tile[0]));
 
		local dy = abs(AIMap.GetTileY(cur_tile) - AIMap.GetTileY(tile[0]));
 
		min_cost = min(min_cost, min(dx, dy) * self._cost_diagonal_tile * 2 + (max(dx, dy) - min(dx, dy)) * self._cost_tile);
 
	}
 
	return min_cost;
 
}
 

	
 
function Rail::_Neighbours(path, cur_node, self)
 
{
 
	if (AITile.HasTransportType(cur_node, AITile.TRANSPORT_RAIL)) return [];
 
	/* self._max_cost is the maximum path cost, if we go over it, the path isn't valid. */
 
	if (path.GetCost() >= self._max_cost) return [];
 
	local tiles = [];
 
	local offsets = [AIMap.GetTileIndex(0, 1), AIMap.GetTileIndex(0, -1),
 
	                 AIMap.GetTileIndex(1, 0), AIMap.GetTileIndex(-1, 0)];
 

	
 
	/* Check if the current tile is part of a bridge or tunnel. */
 
	if (AIBridge.IsBridgeTile(cur_node) || AITunnel.IsTunnelTile(cur_node)) {
 
		/* We don't use existing rails, so neither existing bridges / tunnels. */
 
	} else if (path.GetParent() != null && AIMap.DistanceManhattan(cur_node, path.GetParent().GetTile()) > 1) {
 
		local other_end = path.GetParent().GetTile();
 
		local next_tile = cur_node + (cur_node - other_end) / AIMap.DistanceManhattan(cur_node, other_end);
 
		foreach (offset in offsets) {
 
			if (AIRail.BuildRail(cur_node, next_tile, next_tile + offset)) {
 
				tiles.push([next_tile, self._GetDirection(other_end, cur_node, next_tile, true)]);
 
			}
 
		}
 
	} else {
 
		/* Check all tiles adjacent to the current tile. */
 
		foreach (offset in offsets) {
 
			local next_tile = cur_node + offset;
 
			/* Don't turn back */
 
			if (path.GetParent() != null && next_tile == path.GetParent().GetTile()) continue;
 
			/* Disallow 90 degree turns */
 
			if (path.GetParent() != null && path.GetParent().GetParent() != null &&
 
				next_tile - cur_node == path.GetParent().GetParent().GetTile() - path.GetParent().GetTile()) continue;
 
			/* We add them to the to the neighbours-list if we can build a rail to
 
			 *  them and no rail exists there. */
 
			if ((path.GetParent() == null || AIRail.BuildRail(path.GetParent().GetTile(), cur_node, next_tile))) {
 
				if (path.GetParent() != null) {
 
					tiles.push([next_tile, self._GetDirection(path.GetParent().GetTile(), cur_node, next_tile, false)]);
 
				} else {
 
					tiles.push([next_tile, self._GetDirection(null, cur_node, next_tile, false)]);
 
				}
 
			}
 
		}
 
		if (path.GetParent() != null && path.GetParent().GetParent() != null) {
 
			local bridges = self._GetTunnelsBridges(path.GetParent().GetTile(), cur_node, self._GetDirection(path.GetParent().GetParent().GetTile(), path.GetParent().GetTile(), cur_node, true));
 
			foreach (tile in bridges) {
 
				tiles.push(tile);
 
			}
 
		}
 
	}
 
	return tiles;
 
}
 

	
 
function Rail::_CheckDirection(tile, existing_direction, new_direction, self)
 
{
 
	return false;
 
}
 

	
 
function Rail::_dir(from, to)
 
{
 
	if (from - to == 1) return 0;
 
	if (from - to == -1) return 1;
 
	if (from - to == AIMap.GetMapSizeX()) return 2;
 
	if (from - to == -AIMap.GetMapSizeX()) return 3;
 
	throw("Shouldn't come here in _dir");
 
}
 

	
 
function Rail::_GetDirection(pre_from, from, to, is_bridge)
 
{
 
	if (is_bridge) {
 
		if (from - to == 1) return 1;
 
		if (from - to == -1) return 2;
 
		if (from - to == AIMap.GetMapSizeX()) return 4;
 
		if (from - to == -AIMap.GetMapSizeX()) return 8;
 
	}
 
	return 1 << (4 + (pre_from == null ? 0 : 4 * this._dir(pre_from, from)) + this._dir(from, to));
 
}
 

	
 
/**
 
 * Get a list of all bridges and tunnels that can be build from the
 
 *  current tile. Bridges will only be build starting on non-flat tiles
 
 *  for performance reasons. Tunnels will only be build if no terraforming
 
 *  is needed on both ends.
 
 */
 
function Rail::_GetTunnelsBridges(last_node, cur_node, bridge_dir)
 
{
 
	local slope = AITile.GetSlope(cur_node);
 
	if (slope == AITile.SLOPE_FLAT && AITile.IsBuildable(cur_node + (cur_node - last_node))) return [];
 
	local tiles = [];
 

	
 
	for (local i = 2; i < this._max_bridge_length; i++) {
 
		local bridge_list = AIBridgeList_Length(i + 1);
 
		local target = cur_node + i * (cur_node - last_node);
 
		if (!bridge_list.IsEmpty() && AIBridge.BuildBridge(AIVehicle.VEHICLE_RAIL, bridge_list.Begin(), cur_node, target)) {
 
			tiles.push([target, bridge_dir]);
 
		}
 
	}
 

	
 
	if (slope != AITile.SLOPE_SW && slope != AITile.SLOPE_NW && slope != AITile.SLOPE_SE && slope != AITile.SLOPE_NE) return tiles;
 
	local other_tunnel_end = AITunnel.GetOtherTunnelEnd(cur_node);
 
	if (!AIMap.IsValidTile(other_tunnel_end)) return tiles;
 

	
 
	local tunnel_length = AIMap.DistanceManhattan(cur_node, other_tunnel_end);
 
	local prev_tile = cur_node + (cur_node - other_tunnel_end) / tunnel_length;
 
	if (AITunnel.GetOtherTunnelEnd(other_tunnel_end) == cur_node && tunnel_length >= 2 &&
 
			prev_tile == last_node && tunnel_length < _max_tunnel_length && AITunnel.BuildTunnel(AIVehicle.VEHICLE_RAIL, cur_node)) {
 
		tiles.push([other_tunnel_end, bridge_dir]);
 
	}
 
	return tiles;
 
}
 

	
 
function Rail::_IsSlopedRail(start, middle, end)
 
{
 
	local NW = 0; // Set to true if we want to build a rail to / from the north-west
 
	local NE = 0; // Set to true if we want to build a rail to / from the north-east
 
	local SW = 0; // Set to true if we want to build a rail to / from the south-west
 
	local SE = 0; // Set to true if we want to build a rail to / from the south-east
 

	
 
	if (middle - AIMap.GetMapSizeX() == start || middle - AIMap.GetMapSizeX() == end) NW = 1;
 
	if (middle - 1 == start || middle - 1 == end) NE = 1;
 
	if (middle + AIMap.GetMapSizeX() == start || middle + AIMap.GetMapSizeX() == end) SE = 1;
 
	if (middle + 1 == start || middle + 1 == end) SW = 1;
 

	
 
	/* If there is a turn in the current tile, it can't be sloped. */
 
	if ((NW || SE) && (NE || SW)) return false;
 

	
 
	local slope = AITile.GetSlope(middle);
 
	/* A rail on a steep slope is always sloped. */
 
	if (AITile.IsSteepSlope(slope)) return true;
 

	
 
	/* If only one corner is raised, the rail is sloped. */
 
	if (slope == AITile.SLOPE_N || slope == AITile.SLOPE_W) return true;
 
	if (slope == AITile.SLOPE_S || slope == AITile.SLOPE_E) return true;
 

	
 
	if (NW && (slope == AITile.SLOPE_NW || slope == AITile.SLOPE_SE)) return true;
 
	if (NE && (slope == AITile.SLOPE_NE || slope == AITile.SLOPE_SW)) return true;
 

	
 
	return false;
 
}
bin/ai/library/pathfinder/road/library.nut
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
class Road extends AILibrary {
 
	function GetAuthor()      { return "OpenTTD NoAI Developers Team"; }
 
	function GetName()        { return "Road"; }
 
	function GetDescription() { return "An implementation of a road pathfinder"; }
 
	function GetVersion()     { return 3; }
 
	function GetDate()        { return "2008-06-18"; }
 
	function CreateInstance() { return "Road"; }
 
}
 

	
 
RegisterLibrary(Road());
bin/ai/library/pathfinder/road/main.nut
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/**
 
 * A Road Pathfinder.
 
 *  This road pathfinder tries to find a buildable / existing route for
 
 *  road vehicles. You can changes the costs below using for example
 
 *  roadpf.cost.turn = 30. Note that it's not allowed to change the cost
 
 *  between consecutive calls to FindPath. You can change the cost before
 
 *  the first call to FindPath and after FindPath has returned an actual
 
 *  route. To use only existing roads, set cost.no_existing_road to
 
 *  cost.max_cost.
 
 */
 
class Road
 
{
 
	_aystar_class = import("graph.aystar", "", 4);
 
	_max_cost = null;              ///< The maximum cost for a route.
 
	_cost_tile = null;             ///< The cost for a single tile.
 
	_cost_no_existing_road = null; ///< The cost that is added to _cost_tile if no road exists yet.
 
	_cost_turn = null;             ///< The cost that is added to _cost_tile if the direction changes.
 
	_cost_slope = null;            ///< The extra cost if a road tile is sloped.
 
	_cost_bridge_per_tile = null;  ///< The cost per tile of a new bridge, this is added to _cost_tile.
 
	_cost_tunnel_per_tile = null;  ///< The cost per tile of a new tunnel, this is added to _cost_tile.
 
	_cost_coast = null;            ///< The extra cost for a coast tile.
 
	_pathfinder = null;            ///< A reference to the used AyStar object.
 
	_max_bridge_length = null;     ///< The maximum length of a bridge that will be build.
 
	_max_tunnel_length = null;     ///< The maximum length of a tunnel that will be build.
 

	
 
	cost = null;                   ///< Used to change the costs.
 
	_running = null;
 

	
 
	constructor()
 
	{
 
		this._max_cost = 10000000;
 
		this._cost_tile = 100;
 
		this._cost_no_existing_road = 40;
 
		this._cost_turn = 100;
 
		this._cost_slope = 200;
 
		this._cost_bridge_per_tile = 150;
 
		this._cost_tunnel_per_tile = 120;
 
		this._cost_coast = 20;
 
		this._max_bridge_length = 10;
 
		this._max_tunnel_length = 20;
 
		this._pathfinder = this._aystar_class(this._Cost, this._Estimate, this._Neighbours, this._CheckDirection, this, this, this, this);
 

	
 
		this.cost = this.Cost(this);
 
		this._running = false;
 
	}
 

	
 
	/**
 
	 * Initialize a path search between sources and goals.
 
	 * @param sources The source tiles.
 
	 * @param goals The target tiles.
 
	 * @see AyStar::InitializePath()
 
	 */
 
	function InitializePath(sources, goals) {
 
		local nsources = [];
 

	
 
		foreach (node in sources) {
 
			nsources.push([node, 0xFF]);
 
		}
 
		this._pathfinder.InitializePath(nsources, goals);
 
	}
 

	
 
	/**
 
	 * Try to find the path as indicated with InitializePath with the lowest cost.
 
	 * @param iterations After how many iterations it should abort for a moment.
 
	 *  This value should either be -1 for infinite, or > 0. Any other value
 
	 *  aborts immediatly and will never find a path.
 
	 * @return A route if one was found, or false if the amount of iterations was
 
	 *  reached, or null if no path was found.
 
	 *  You can call this function over and over as long as it returns false,
 
	 *  which is an indication it is not yet done looking for a route.
 
	 * @see AyStar::FindPath()
 
	 */
 
	function FindPath(iterations);
 
};
 

	
 
class Road.Cost
 
{
 
	_main = null;
 

	
 
	function _set(idx, val)
 
	{
 
		if (this._main._running) throw("You are not allowed to change parameters of a running pathfinder.");
 

	
 
		switch (idx) {
 
			case "max_cost":          this._main._max_cost = val; break;
 
			case "tile":              this._main._cost_tile = val; break;
 
			case "no_existing_road":  this._main._cost_no_existing_road = val; break;
 
			case "turn":              this._main._cost_turn = val; break;
 
			case "slope":             this._main._cost_slope = val; break;
 
			case "bridge_per_tile":   this._main._cost_bridge_per_tile = val; break;
 
			case "tunnel_per_tile":   this._main._cost_tunnel_per_tile = val; break;
 
			case "coast":             this._main._cost_coast = val; break;
 
			case "max_bridge_length": this._main._max_bridge_length = val; break;
 
			case "max_tunnel_length": this._main._max_tunnel_length = val; break;
 
			default: throw("the index '" + idx + "' does not exist");
 
		}
 

	
 
		return val;
 
	}
 

	
 
	function _get(idx)
 
	{
 
		switch (idx) {
 
			case "max_cost":          return this._main._max_cost;
 
			case "tile":              return this._main._cost_tile;
 
			case "no_existing_road":  return this._main._cost_no_existing_road;
 
			case "turn":              return this._main._cost_turn;
 
			case "slope":             return this._main._cost_slope;
 
			case "bridge_per_tile":   return this._main._cost_bridge_per_tile;
 
			case "tunnel_per_tile":   return this._main._cost_tunnel_per_tile;
 
			case "coast":             return this._main._cost_coast;
 
			case "max_bridge_length": return this._main._max_bridge_length;
 
			case "max_tunnel_length": return this._main._max_tunnel_length;
 
			default: throw("the index '" + idx + "' does not exist");
 
		}
 
	}
 

	
 
	constructor(main)
 
	{
 
		this._main = main;
 
	}
 
};
 

	
 
function Road::FindPath(iterations)
 
{
 
	local test_mode = AITestMode();
 
	local ret = this._pathfinder.FindPath(iterations);
 
	this._running = (ret == false) ? true : false;
 
	return ret;
 
}
 

	
 
function Road::_GetBridgeNumSlopes(end_a, end_b)
 
{
 
	local slopes = 0;
 
	local direction = (end_b - end_a) / AIMap.DistanceManhattan(end_a, end_b);
 
	local slope = AITile.GetSlope(end_a);
 
	if (!((slope == AITile.SLOPE_NE && direction == 1) || (slope == AITile.SLOPE_SE && direction == -AIMap.GetMapSizeX()) ||
 
		(slope == AITile.SLOPE_SW && direction == -1) || (slope == AITile.SLOPE_NW && direction == AIMap.GetMapSizeX()) ||
 
		 slope == AITile.SLOPE_N || slope == AITile.SLOPE_E || slope == AITile.SLOPE_S || slope == AITile.SLOPE_W)) {
 
		slopes++;
 
	}
 

	
 
	local slope = AITile.GetSlope(end_b);
 
	direction = -direction;
 
	if (!((slope == AITile.SLOPE_NE && direction == 1) || (slope == AITile.SLOPE_SE && direction == -AIMap.GetMapSizeX()) ||
 
		(slope == AITile.SLOPE_SW && direction == -1) || (slope == AITile.SLOPE_NW && direction == AIMap.GetMapSizeX()) ||
 
		 slope == AITile.SLOPE_N || slope == AITile.SLOPE_E || slope == AITile.SLOPE_S || slope == AITile.SLOPE_W)) {
 
		slopes++;
 
	}
 
	return slopes;
 
}
 

	
 
function Road::_Cost(path, new_tile, new_direction, self)
 
{
 
	/* path == null means this is the first node of a path, so the cost is 0. */
 
	if (path == null) return 0;
 

	
 
	local prev_tile = path.GetTile();
 

	
 
	/* If the new tile is a bridge / tunnel tile, check whether we came from the other
 
	 * end of the bridge / tunnel or if we just entered the bridge / tunnel. */
 
	if (AIBridge.IsBridgeTile(new_tile)) {
 
		if (AIBridge.GetOtherBridgeEnd(new_tile) != prev_tile) return path.GetCost() + self._cost_tile;
 
		return path.GetCost() + AIMap.DistanceManhattan(new_tile, prev_tile) * self._cost_tile + self._GetBridgeNumSlopes(new_tile, prev_tile) * self._cost_slope;
 
	}
 
	if (AITunnel.IsTunnelTile(new_tile)) {
 
		if (AITunnel.GetOtherTunnelEnd(new_tile) != prev_tile) return path.GetCost() + self._cost_tile;
 
		return path.GetCost() + AIMap.DistanceManhattan(new_tile, prev_tile) * self._cost_tile;
 
	}
 

	
 
	/* If the two tiles are more then 1 tile apart, the pathfinder wants a bridge or tunnel
 
	 * to be build. It isn't an existing bridge / tunnel, as that case is already handled. */
 
	if (AIMap.DistanceManhattan(new_tile, prev_tile) > 1) {
 
		/* Check if we should build a bridge or a tunnel. */
 
		if (AITunnel.GetOtherTunnelEnd(new_tile) == prev_tile) {
 
			return path.GetCost() + AIMap.DistanceManhattan(new_tile, prev_tile) * (self._cost_tile + self._cost_tunnel_per_tile);
 
		} else {
 
			return path.GetCost() + AIMap.DistanceManhattan(new_tile, prev_tile) * (self._cost_tile + self._cost_bridge_per_tile) + self._GetBridgeNumSlopes(new_tile, prev_tile) * self._cost_slope;
 
		}
 
	}
 

	
 
	/* Check for a turn. We do this by substracting the TileID of the current node from
 
	 * the TileID of the previous node and comparing that to the difference between the
 
	 * previous node and the node before that. */
 
	local cost = self._cost_tile;
 
	if (path.GetParent() != null && (prev_tile - path.GetParent().GetTile()) != (new_tile - prev_tile) &&
 
		AIMap.DistanceManhattan(path.GetParent().GetTile(), prev_tile) == 1) {
 
		cost += self._cost_turn;
 
	}
 

	
 
	/* Check if the new tile is a coast tile. */
 
	if (AITile.IsCoastTile(new_tile)) {
 
		cost += self._cost_coast;
 
	}
 

	
 
	/* Check if the last tile was sloped. */
 
	if (path.GetParent() != null && !AIBridge.IsBridgeTile(prev_tile) && !AITunnel.IsTunnelTile(prev_tile) &&
 
	    self._IsSlopedRoad(path.GetParent().GetTile(), prev_tile, new_tile)) {
 
		cost += self._cost_slope;
 
	}
 

	
 
	if (!AIRoad.AreRoadTilesConnected(prev_tile, new_tile)) {
 
		cost += self._cost_no_existing_road;
 
	}
 

	
 
	return path.GetCost() + cost;
 
}
 

	
 
function Road::_Estimate(cur_tile, cur_direction, goal_tiles, self)
 
{
 
	local min_cost = self._max_cost;
 
	/* As estimate we multiply the lowest possible cost for a single tile with
 
	 * with the minimum number of tiles we need to traverse. */
 
	foreach (tile in goal_tiles) {
 
		min_cost = min(AIMap.DistanceManhattan(cur_tile, tile) * self._cost_tile, min_cost);
 
	}
 
	return min_cost;
 
}
 

	
 
function Road::_Neighbours(path, cur_node, self)
 
{
 
	/* self._max_cost is the maximum path cost, if we go over it, the path isn't valid. */
 
	if (path.GetCost() >= self._max_cost) return [];
 
	local tiles = [];
 

	
 
	/* Check if the current tile is part of a bridge or tunnel. */
 
	if ((AIBridge.IsBridgeTile(cur_node) || AITunnel.IsTunnelTile(cur_node)) &&
 
	     AITile.HasTransportType(cur_node, AITile.TRANSPORT_ROAD)) {
 
		local other_end = AIBridge.IsBridgeTile(cur_node) ? AIBridge.GetOtherBridgeEnd(cur_node) : AITunnel.GetOtherTunnelEnd(cur_node);
 
		local next_tile = cur_node + (cur_node - other_end) / AIMap.DistanceManhattan(cur_node, other_end);
 
		if (AIRoad.AreRoadTilesConnected(cur_node, next_tile) || AITile.IsBuildable(next_tile) || AIRoad.IsRoadTile(next_tile)) {
 
			tiles.push([next_tile, self._GetDirection(cur_node, next_tile, false)]);
 
		}
 
		/* The other end of the bridge / tunnel is a neighbour. */
 
		tiles.push([other_end, self._GetDirection(next_tile, cur_node, true) << 4]);
 
	} else if (path.GetParent() != null && AIMap.DistanceManhattan(cur_node, path.GetParent().GetTile()) > 1) {
 
		local other_end = path.GetParent().GetTile();
 
		local next_tile = cur_node + (cur_node - other_end) / AIMap.DistanceManhattan(cur_node, other_end);
 
		if (AIRoad.AreRoadTilesConnected(cur_node, next_tile) || AIRoad.BuildRoad(cur_node, next_tile)) {
 
			tiles.push([next_tile, self._GetDirection(cur_node, next_tile, false)]);
 
		}
 
	} else {
 
		local offsets = [AIMap.GetTileIndex(0, 1), AIMap.GetTileIndex(0, -1),
 
		                 AIMap.GetTileIndex(1, 0), AIMap.GetTileIndex(-1, 0)];
 
		/* Check all tiles adjacent to the current tile. */
 
		foreach (offset in offsets) {
 
			local next_tile = cur_node + offset;
 
			/* We add them to the to the neighbours-list if one of the following applies:
 
			 * 1) There already is a connections between the current tile and the next tile.
 
			 * 2) We can build a road to the next tile.
 
			 * 3) The next tile is the entrance of a tunnel / bridge in the correct direction. */
 
			if (AIRoad.AreRoadTilesConnected(cur_node, next_tile)) {
 
				tiles.push([next_tile, self._GetDirection(cur_node, next_tile, false)]);
 
			} else if ((AITile.IsBuildable(next_tile) || AIRoad.IsRoadTile(next_tile)) &&
 
					(path.GetParent() == null || AIRoad.CanBuildConnectedRoadPartsHere(cur_node, path.GetParent().GetTile(), next_tile)) &&
 
					AIRoad.BuildRoad(cur_node, next_tile)) {
 
				tiles.push([next_tile, self._GetDirection(cur_node, next_tile, false)]);
 
			} else if (self._CheckTunnelBridge(cur_node, next_tile)) {
 
				tiles.push([next_tile, self._GetDirection(cur_node, next_tile, false)]);
 
			}
 
		}
 
		if (path.GetParent() != null) {
 
			local bridges = self._GetTunnelsBridges(path.GetParent().GetTile(), cur_node, self._GetDirection(path.GetParent().GetTile(), cur_node, true) << 4);
 
			foreach (tile in bridges) {
 
				tiles.push(tile);
 
			}
 
		}
 
	}
 
	return tiles;
 
}
 

	
 
function Road::_CheckDirection(tile, existing_direction, new_direction, self)
 
{
 
	return false;
 
}
 

	
 
function Road::_GetDirection(from, to, is_bridge)
 
{
 
	if (!is_bridge && AITile.GetSlope(to) == AITile.SLOPE_FLAT) return 0xFF;
 
	if (from - to == 1) return 1;
 
	if (from - to == -1) return 2;
 
	if (from - to == AIMap.GetMapSizeX()) return 4;
 
	if (from - to == -AIMap.GetMapSizeX()) return 8;
 
}
 

	
 
/**
 
 * Get a list of all bridges and tunnels that can be build from the
 
 * current tile. Bridges will only be build starting on non-flat tiles
 
 * for performance reasons. Tunnels will only be build if no terraforming
 
 * is needed on both ends.
 
 */
 
function Road::_GetTunnelsBridges(last_node, cur_node, bridge_dir)
 
{
 
	local slope = AITile.GetSlope(cur_node);
 
	if (slope == AITile.SLOPE_FLAT) return [];
 
	local tiles = [];
 

	
 
	for (local i = 2; i < this._max_bridge_length; i++) {
 
		local bridge_list = AIBridgeList_Length(i + 1);
 
		local target = cur_node + i * (cur_node - last_node);
 
		if (!bridge_list.IsEmpty() && AIBridge.BuildBridge(AIVehicle.VEHICLE_ROAD, bridge_list.Begin(), cur_node, target)) {
 
			tiles.push([target, bridge_dir]);
 
		}
 
	}
 

	
 
	if (slope != AITile.SLOPE_SW && slope != AITile.SLOPE_NW && slope != AITile.SLOPE_SE && slope != AITile.SLOPE_NE) return tiles;
 
	local other_tunnel_end = AITunnel.GetOtherTunnelEnd(cur_node);
 
	if (!AIMap.IsValidTile(other_tunnel_end)) return tiles;
 

	
 
	local tunnel_length = AIMap.DistanceManhattan(cur_node, other_tunnel_end);
 
	local prev_tile = cur_node + (cur_node - other_tunnel_end) / tunnel_length;
 
	if (AITunnel.GetOtherTunnelEnd(other_tunnel_end) == cur_node && tunnel_length >= 2 &&
 
			prev_tile == last_node && tunnel_length < _max_tunnel_length && AITunnel.BuildTunnel(AIVehicle.VEHICLE_ROAD, cur_node)) {
 
		tiles.push([other_tunnel_end, bridge_dir]);
 
	}
 
	return tiles;
 
}
 

	
 
function Road::_IsSlopedRoad(start, middle, end)
 
{
 
	local NW = 0; //Set to true if we want to build a road to / from the north-west
 
	local NE = 0; //Set to true if we want to build a road to / from the north-east
 
	local SW = 0; //Set to true if we want to build a road to / from the south-west
 
	local SE = 0; //Set to true if we want to build a road to / from the south-east
 

	
 
	if (middle - AIMap.GetMapSizeX() == start || middle - AIMap.GetMapSizeX() == end) NW = 1;
 
	if (middle - 1 == start || middle - 1 == end) NE = 1;
 
	if (middle + AIMap.GetMapSizeX() == start || middle + AIMap.GetMapSizeX() == end) SE = 1;
 
	if (middle + 1 == start || middle + 1 == end) SW = 1;
 

	
 
	/* If there is a turn in the current tile, it can't be sloped. */
 
	if ((NW || SE) && (NE || SW)) return false;
 

	
 
	local slope = AITile.GetSlope(middle);
 
	/* A road on a steep slope is always sloped. */
 
	if (AITile.IsSteepSlope(slope)) return true;
 

	
 
	/* If only one corner is raised, the road is sloped. */
 
	if (slope == AITile.SLOPE_N || slope == AITile.SLOPE_W) return true;
 
	if (slope == AITile.SLOPE_S || slope == AITile.SLOPE_E) return true;
 

	
 
	if (NW && (slope == AITile.SLOPE_NW || slope == AITile.SLOPE_SE)) return true;
 
	if (NE && (slope == AITile.SLOPE_NE || slope == AITile.SLOPE_SW)) return true;
 

	
 
	return false;
 
}
 

	
 
function Road::_CheckTunnelBridge(current_tile, new_tile)
 
{
 
	if (!AIBridge.IsBridgeTile(new_tile) && !AITunnel.IsTunnelTile(new_tile)) return false;
 
	local dir = new_tile - current_tile;
 
	local other_end = AIBridge.IsBridgeTile(new_tile) ? AIBridge.GetOtherBridgeEnd(new_tile) : AITunnel.GetOtherTunnelEnd(new_tile);
 
	local dir2 = other_end - new_tile;
 
	if ((dir < 0 && dir2 > 0) || (dir > 0 && dir2 < 0)) return false;
 
	dir = abs(dir);
 
	dir2 = abs(dir2);
 
	if ((dir >= AIMap.GetMapSizeX() && dir2 < AIMap.GetMapSizeX()) ||
 
	    (dir < AIMap.GetMapSizeX() && dir2 >= AIMap.GetMapSizeX())) return false;
 

	
 
	return true;
 
}
bin/ai/library/queue/binary_heap/library.nut
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
class BinaryHeap extends AILibrary {
 
	function GetAuthor()      { return "OpenTTD NoAI Developers Team"; }
 
	function GetName()        { return "Binary Heap"; }
 
	function GetDescription() { return "An implementation of a Binary Heap"; }
 
	function GetVersion()     { return 1; }
 
	function GetDate()        { return "2008-06-10"; }
 
	function CreateInstance() { return "BinaryHeap"; }
 
}
 

	
 
RegisterLibrary(BinaryHeap());
bin/ai/library/queue/binary_heap/main.nut
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/**
 
 * Binary Heap.
 
 *  Peek and Pop always return the current lowest value in the list.
 
 *  Sort is done on insertion and on deletion.
 
 */
 
class BinaryHeap
 
{
 
	_queue = null;
 
	_count = 0;
 

	
 
	constructor()
 
	{
 
		_queue = [];
 
	}
 

	
 
	/**
 
	 * Insert a new entry in the list.
 
	 *  The complexity of this operation is O(ln n).
 
	 * @param item The item to add to the list.
 
	 * @param priority The priority this item has.
 
	 */
 
	function Insert(item, priority);
 

	
 
	/**
 
	 * Pop the first entry of the list.
 
	 *  This is always the item with the lowest priority.
 
	 *  The complexity of this operation is O(ln n).
 
	 * @return The item of the entry with the lowest priority.
 
	 */
 
	function Pop();
 

	
 
	/**
 
	 * Peek the first entry of the list.
 
	 *  This is always the item with the lowest priority.
 
	 *  The complexity of this operation is O(1).
 
	 * @return The item of the entry with the lowest priority.
 
	 */
 
	function Peek();
 

	
 
	/**
 
	 * Get the amount of current items in the list.
 
	 *  The complexity of this operation is O(1).
 
	 * @return The amount of items currently in the list.
 
	 */
 
	function Count();
 

	
 
	/**
 
	 * Check if an item exists in the list.
 
	 *  The complexity of this operation is O(n).
 
	 * @param item The item to check for.
 
	 * @return True if the item is already in the list.
 
	 */
 
	function Exists(item);
 
};
 

	
 
function BinaryHeap::Insert(item, priority)
 
{
 
	/* Append dummy entry */
 
	_queue.append(0);
 
	_count++;
 

	
 
	local hole;
 
	/* Find the point of insertion */
 
	for (hole = _count - 1; hole > 0 && priority <= _queue[hole / 2][1]; hole /= 2)
 
		_queue[hole] = _queue[hole / 2];
 
	/* Insert new pair */
 
	_queue[hole] = [item, priority];
 

	
 
	return true;
 
}
 

	
 
function BinaryHeap::Pop()
 
{
 
	if (_count == 0) return null;
 

	
 
	local node = _queue[0];
 
	/* Remove the item from the list by putting the last value on top */
 
	_queue[0] = _queue[_count - 1];
 
	_queue.pop();
 
	_count--;
 
	/* Bubble down the last value to correct the tree again */
 
	_BubbleDown();
 

	
 
	return node[0];
 
}
 

	
 
function BinaryHeap::Peek()
 
{
 
	if (_count == 0) return null;
 

	
 
	return _queue[0][0];
 
}
 

	
 
function BinaryHeap::Count()
 
{
 
	return _count;
 
}
 

	
 
function BinaryHeap::Exists(item)
 
{
 
	/* Brute-force find the item (there is no faster way, as we don't have the priority number) */
 
	foreach (node in _queue) {
 
		if (node[0] == item) return true;
 
	}
 

	
 
	return false;
 
}
 

	
 

	
 

	
 
function BinaryHeap::_BubbleDown()
 
{
 
	if (_count == 0) return;
 

	
 
	local hole = 1;
 
	local tmp = _queue[0];
 

	
 
	/* Start switching parent and child until the tree is restored */
 
	while (hole * 2 < _count + 1) {
 
		local child = hole * 2;
 
		if (child != _count && _queue[child][1] <= _queue[child - 1][1]) child++;
 
		if (_queue[child - 1][1] > tmp[1]) break;
 

	
 
		_queue[hole - 1] = _queue[child - 1];
 
		hole = child;
 
	}
 
	/* The top value is now at his new place */
 
	_queue[hole - 1] = tmp;
 
}
bin/ai/library/queue/fibonacci_heap/library.nut
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
class FibonacciHeap extends AILibrary {
 
	function GetAuthor()      { return "OpenTTD NoAI Developers Team"; }
 
	function GetName()        { return "Fibonacci Heap"; }
 
	function GetDescription() { return "An implementation of a Fibonacci Heap"; }
 
	function GetVersion()     { return 1; }
 
	function GetDate()        { return "2008-08-22"; }
 
	function CreateInstance() { return "FibonacciHeap"; }
 
}
 

	
 
RegisterLibrary(FibonacciHeap());
bin/ai/library/queue/fibonacci_heap/main.nut
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/**
 
 * Fibonacci heap.
 
 *  This heap is heavily optimized for the Insert and Pop functions.
 
 *  Peek and Pop always return the current lowest value in the list.
 
 *  Insert is implemented as a lazy insert, as it will simply add the new
 
 *  node to the root list. Sort is done on every Pop operation.
 
 */
 
class FibonacciHeap {
 
	_min = null;
 
	_min_index = 0;
 
	_min_priority = 0;
 
	_count = 0;
 
	_root_list = null;
 

	
 
	/**
 
	 * Create a new fibonacci heap.
 
	 * http://en.wikipedia.org/wiki/Fibonacci_heap
 
	 */
 
	constructor() {
 
		_count = 0;
 
		_min = Node();
 
		_min.priority = 0x7FFFFFFF;
 
		_min_index = 0;
 
		_min_priority = 0x7FFFFFFF;
 
		_root_list = [];
 
	}
 

	
 
	/**
 
	 * Insert a new entry in the heap.
 
	 *  The complexity of this operation is O(1).
 
	 * @param item The item to add to the list.
 
	 * @param priority The priority this item has.
 
	 */
 
	function Insert(item, priority);
 

	
 
	/**
 
	 * Pop the first entry of the list.
 
	 *  This is always the item with the lowest priority.
 
	 *  The complexity of this operation is O(ln n).
 
	 * @return The item of the entry with the lowest priority.
 
	 */
 
	function Pop();
 

	
 
	/**
 
	 * Peek the first entry of the list.
 
	 *  This is always the item with the lowest priority.
 
	 *  The complexity of this operation is O(1).
 
	 * @return The item of the entry with the lowest priority.
 
	 */
 
	function Peek();
 

	
 
	/**
 
	 * Get the amount of current items in the list.
 
	 *  The complexity of this operation is O(1).
 
	 * @return The amount of items currently in the list.
 
	 */
 
	function Count();
 

	
 
	/**
 
	 * Check if an item exists in the list.
 
	 *  The complexity of this operation is O(n).
 
	 * @param item The item to check for.
 
	 * @return True if the item is already in the list.
 
	 */
 
	function Exists(item);
 
};
 

	
 
function FibonacciHeap::Insert(item, priority) {
 
	/* Create a new node instance to add to the heap. */
 
	local node = Node();
 
	/* Changing params is faster than using constructor values */
 
	node.item = item;
 
	node.priority = priority;
 

	
 
	/* Update the reference to the minimum node if this node has a
 
	 * smaller priority. */
 
	if (_min_priority > priority) {
 
		_min = node;
 
		_min_index = _root_list.len();
 
		_min_priority = priority;
 
	}
 

	
 
	_root_list.append(node);
 
	_count++;
 
}
 

	
 
function FibonacciHeap::Pop() {
 

	
 
	if (_count == 0) return null;
 

	
 
	/* Bring variables from the class scope to this scope explicitly to
 
	 * optimize variable lookups by Squirrel. */
 
	local z = _min;
 
	local tmp_root_list = _root_list;
 

	
 
	/* If there are any children, bring them all to the root level. */
 
	tmp_root_list.extend(z.child);
 

	
 
	/* Remove the minimum node from the rootList. */
 
	tmp_root_list.remove(_min_index);
 
	local root_cache = {};
 

	
 
	/* Now we decrease the number of nodes on the root level by
 
	 * merging nodes which have the same degree. The node with
 
	 * the lowest priority value will become the parent. */
 
	foreach(x in tmp_root_list) {
 
		local y;
 

	
 
		/* See if we encountered a node with the same degree already. */
 
		while (y = root_cache.rawdelete(x.degree)) {
 
			/* Check the priorities. */
 
			if (x.priority > y.priority) {
 
				local tmp = x;
 
				x = y;
 
				y = tmp;
 
			}
 

	
 
			/* Make y a child of x. */
 
			x.child.append(y);
 
			x.degree++;
 
		}
 

	
 
		root_cache[x.degree] <- x;
 
	}
 

	
 
	/* The root_cache contains all the nodes which will form the
 
	 *  new rootList. We reset the priority to the maximum number
 
	 *  for a 32 signed integer to find a new minumum. */
 
	tmp_root_list.resize(root_cache.len());
 
	local i = 0;
 
	local tmp_min_priority = 0x7FFFFFFF;
 

	
 
	/* Now we need to find the new minimum among the root nodes. */
 
	foreach (val in root_cache) {
 
		if (val.priority < tmp_min_priority) {
 
			_min = val;
 
			_min_index = i;
 
			tmp_min_priority = val.priority;
 
		}
 

	
 
		tmp_root_list[i++] = val;
 
	}
 

	
 
	/* Update global variables. */
 
	_min_priority = tmp_min_priority;
 

	
 
	_count--;
 
	return z.item;
 
}
 

	
 
function FibonacciHeap::Peek() {
 
	if (_count == 0) return null;
 
	return _min.item;
 
}
 

	
 
function FibonacciHeap::Count() {
 
	return _count;
 
}
 

	
 
function FibonacciHeap::Exists(item) {
 
	return ExistsIn(_root_list, item);
 
}
 

	
 
/**
 
 * Auxilary function to search through the whole heap.
 
 * @param list The list of nodes to look through.
 
 * @param item The item to search for.
 
 * @return True if the item is found, false otherwise.
 
 */
 
function FibonacciHeap::ExistsIn(list, item) {
 

	
 
	foreach (val in list) {
 
		if (val.item == item) {
 
			return true;
 
		}
 

	
 
		foreach (c in val.child) {
 
			if (ExistsIn(c, item)) {
 
				return true;
 
			}
 
		}
 
	}
 

	
 
	/* No luck, item doesn't exists in the tree rooted under list. */
 
	return false;
 
}
 

	
 
/**
 
 * Basic class the fibonacci heap is composed of.
 
 */
 
class FibonacciHeap.Node {
 
	degree = null;
 
	child = null;
 

	
 
	item = null;
 
	priority = null;
 

	
 
	constructor() {
 
		child = [];
 
		degree = 0;
 
	}
 
};
bin/ai/library/queue/priority_queue/library.nut
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
class PriorityQueue extends AILibrary {
 
	function GetAuthor()      { return "OpenTTD NoAI Developers Team"; }
 
	function GetName()        { return "Priority Queue"; }
 
	function GetDescription() { return "An implementation of a Priority Queue"; }
 
	function GetVersion()     { return 2; }
 
	function GetDate()        { return "2008-06-10"; }
 
	function CreateInstance() { return "PriorityQueue"; }
 
}
 

	
 
RegisterLibrary(PriorityQueue());
bin/ai/library/queue/priority_queue/main.nut
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/**
 
 * Priority Queue.
 
 *  Peek and Pop always return the current lowest value in the list.
 
 *  Sort is done on insertion only.
 
 */
 
class PriorityQueue
 
{
 
	_queue = null;
 
	_count = 0;
 

	
 
	constructor()
 
	{
 
		_count = 0;
 
		_queue = [];
 
	}
 

	
 
	/**
 
	 * Insert a new entry in the list.
 
	 *  The complexity of this operation is O(n).
 
	 * @param item The item to add to the list.
 
	 * @param priority The priority this item has.
 
	 */
 
	function Insert(item, priority);
 

	
 
	/**
 
	 * Pop the first entry of the list.
 
	 *  This is always the item with the lowest priority.
 
	 *  The complexity of this operation is O(1).
 
	 * @return The item of the entry with the lowest priority.
 
	 */
 
	function Pop();
 

	
 
	/**
 
	 * Peek the first entry of the list.
 
	 *  This is always the item with the lowest priority.
 
	 *  The complexity of this operation is O(1).
 
	 * @return The item of the entry with the lowest priority.
 
	 */
 
	function Peek();
 

	
 
	/**
 
	 * Get the amount of current items in the list.
 
	 *  The complexity of this operation is O(1).
 
	 * @return The amount of items currently in the list.
 
	 */
 
	function Count();
 

	
 
	/**
 
	 * Check if an item exists in the list.
 
	 *  The complexity of this operation is O(n).
 
	 * @param item The item to check for.
 
	 * @return True if the item is already in the list.
 
	 */
 
	function Exists(item);
 
};
 

	
 
function PriorityQueue::Insert(item, priority)
 
{
 
	/* Append dummy entry */
 
	_queue.append(0);
 
	_count++;
 

	
 
	local i;
 
	/* Find the point of insertion */
 
	for (i = _count - 2; i >= 0; i--) {
 
		if (priority > _queue[i][1]) {
 
			/* All items bigger move one place to the right */
 
			_queue[i + 1] = _queue[i];
 
		} else if (item == _queue[i][0]) {
 
			/* Same item, ignore insertion */
 
			return false;
 
		} else {
 
			/* Found place to insert at */
 
			break;
 
		}
 
	}
 
	/* Insert new pair */
 
	_queue[i + 1] = [item, priority];
 

	
 
	return true;
 
}
 

	
 
function PriorityQueue::Pop()
 
{
 
	if (_count == 0) return null;
 

	
 
	local node = _queue.pop();
 
	_count--;
 

	
 
	return node[0];
 
}
 

	
 
function PriorityQueue::Peek()
 
{
 
	if (_count == 0) return null;
 

	
 
	return _queue[_count - 1][0];
 
}
 

	
 
function PriorityQueue::Count()
 
{
 
	return _count;
 
}
 

	
 
function PriorityQueue::Exists(item)
 
{
 
	/* Brute-force find the item (there is no faster way, as we don't have the priority number) */
 
	foreach (node in _queue) {
 
		if (node[0] == item) return true;
 
	}
 

	
 
	return false;
 
}
bin/ai/regression/completeness.sh
Show inline comments
 
new file 100644
 
#!/bin/sh
 

	
 
if ! [ -f ai/regression/regression.nut ]; then
 
	echo "Make sure you are in the root of OpenTTD before starting this script."
 
	exit 1
 
fi
 

	
 
cat ai/regression/regression.nut | tr ';' '\n' | awk '
 
/^function/ {
 
	for (local in locals) {
 
		delete locals[local]
 
	}
 
	if (match($0, "function Regression::Start") || match($0, "function Regression::Stop")) next
 
	locals["this"] = "AIControllerSquirrel"
 
}
 

	
 
/local/ {
 
	gsub(".*local", "local")
 
	if (match($4, "^AI")) {
 
		sub("\\(.*", "", $4)
 
		locals[$2] = $4
 
	}
 
}
 

	
 
/Valuate/ {
 
	gsub(".*Valuate\\(", "")
 
	gsub("\\).*", "")
 
	gsub(",.*", "")
 
	gsub("\\.", "::")
 
	print $0
 
}
 

	
 
/\./ {
 
	for (local in locals) {
 
		if (match($0, local ".")) {
 
			fname = substr($0, index($0, local "."))
 
			sub("\\(.*", "", fname)
 
			sub("\\.", "::", fname)
 
			sub(local, locals[local], fname)
 
			print fname
 
			if (match(locals[local], "List")) {
 
				sub(locals[local], "AIAbstractList", fname)
 
				print fname
 
			}
 
		}
 
	}
 
	# We want to remove everything before the FIRST occurence of AI.
 
	# If we do not remove any other occurences of AI from the string
 
	# we will remove everything before the LAST occurence of AI, so
 
	# do some little magic to make it work the way we want.
 
	sub("AI", "AXXXXY")
 
	gsub("AI", "AXXXXX")
 
	sub(".*AXXXXY", "AI")
 
	if (match($0, "^AI") && match($0, ".")) {
 
		sub("\\(.*", "", $0)
 
		sub("\\.", "::", $0)
 
		print $0
 
	}
 
}
 
' | sed 's/	//g' | sort | uniq > tmp.in_regression
 

	
 
grep 'DefSQ.*Method' ../src/ai/api/*.hpp.sq | grep -v 'AIError::' | grep -v 'AIAbstractList::Valuate' | grep -v '::GetClassName' | sed 's/^[^,]*, &//g;s/,[^,]*//g' | sort > tmp.in_api
 

	
 
diff -u tmp.in_regression tmp.in_api | grep -v '^+++' | grep '^+' | sed 's/^+//'
 

	
 
rm -f tmp.in_regression tmp.in_api
 

	
bin/ai/regression/regression.cfg
Show inline comments
 
new file 100644
 
[misc]
 
display_opt = SHOW_TOWN_NAMES|SHOW_STATION_NAMES|SHOW_SIGNS|WAYPOINTS
 
language = english.lng
 

	
 
[gui]
 
autosave = off
 

	
 
[game_creation]
 
town_name = english
 

	
 
[ai_players]
 
none =
 
regression =
 

	
 
[vehicle]
 
road_side = right
 
plane_speed = 2
bin/ai/regression/regression.nut
Show inline comments
 
new file 100644
 
import("queue.priority_queue", "PQ", 2);
 
import("queue.binary_heap", "BH", 1);
 
import("queue.fibonacci_heap", "FH", 1);
 
import("graph.aystar", "AS", 4);
 
import("pathfinder.road", "RPF", 3);
 

	
 
class Regression extends AIController {
 
	function Start();
 
};
 

	
 

	
 

	
 
function Regression::TestInit()
 
{
 
	print("");
 
	print("--TestInit--");
 
	print(" TickTest: " + this.GetTick());
 
	this.Sleep(1);
 
	print(" TickTest: " + this.GetTick());
 
	print(" SetCommandDelay: " + AIController.SetCommandDelay(1));
 
	print(" IsValid(vehicle.plane_speed): " + AIGameSettings.IsValid("vehicle.plane_speed"));
 
	print(" vehicle.plane_speed: " + AIGameSettings.GetValue("vehicle.plane_speed"));
 
	require("require.nut");
 
	print(" min(6, 3): " + min(6, 3));
 
	print(" min(3, 6): " + min(3, 6));
 
	print(" max(6, 3): " + max(6, 3));
 
	print(" max(3, 6): " + max(3, 6));
 

	
 
	print(" AIList Consistency Tests");
 
	print("");
 
	print(" Value Descending");
 
	local list = AIList();
 
	list.AddItem( 5, 10);
 
	list.AddItem(10, 10);
 
	list.AddItem(15, 20);
 
	list.AddItem(20, 20);
 
	list.AddItem(25, 30);
 
	list.AddItem(30, 30);
 
	list.AddItem(35, 40);
 
	list.AddItem(40, 40);
 

	
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		list.RemoveItem(i - 10);
 
		list.RemoveItem(i - 5);
 
		list.RemoveItem(i);
 
		print("   " + i);
 
	}
 

	
 
	list.AddItem(10, 10);
 
	list.AddItem(20, 20);
 
	list.AddItem(30, 30);
 
	list.AddItem(40, 40);
 

	
 
	print("");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		list.SetValue(i, 2);
 
		print("   " + i);
 
	}
 
	print("");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("   " + i);
 
	}
 

	
 
	list = AIList();
 
	list.Sort(AIAbstractList.SORT_BY_VALUE, true);
 
	print("");
 
	print(" Value Ascending");
 
	list.AddItem( 5, 10);
 
	list.AddItem(10, 10);
 
	list.AddItem(15, 20);
 
	list.AddItem(20, 20);
 
	list.AddItem(25, 30);
 
	list.AddItem(30, 30);
 
	list.AddItem(35, 40);
 
	list.AddItem(40, 40);
 

	
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		list.RemoveItem(i + 10);
 
		list.RemoveItem(i + 5);
 
		list.RemoveItem(i);
 
		print("   " + i);
 
	}
 

	
 
	list.AddItem(10, 10);
 
	list.AddItem(20, 20);
 
	list.AddItem(30, 30);
 
	list.AddItem(40, 40);
 

	
 
	print("");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		list.SetValue(i, 50);
 
		print("   " + i);
 
	}
 
	print("");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("   " + i);
 
	}
 

	
 
	list = AIList();
 
	list.Sort(AIAbstractList.SORT_BY_ITEM, false);
 
	print("");
 
	print(" Item Descending");
 
	list.AddItem( 5, 10);
 
	list.AddItem(10, 10);
 
	list.AddItem(15, 20);
 
	list.AddItem(20, 20);
 
	list.AddItem(25, 30);
 
	list.AddItem(30, 30);
 
	list.AddItem(35, 40);
 
	list.AddItem(40, 40);
 

	
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		list.RemoveItem(i - 10);
 
		list.RemoveItem(i - 5);
 
		list.RemoveItem(i);
 
		print("   " + i);
 
	}
 

	
 
	list.AddItem(10, 10);
 
	list.AddItem(20, 20);
 
	list.AddItem(30, 30);
 
	list.AddItem(40, 40);
 

	
 
	print("");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		list.SetValue(i, 2);
 
		print("   " + i);
 
	}
 
	print("");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("   " + i);
 
	}
 

	
 
	list = AIList();
 
	list.Sort(AIAbstractList.SORT_BY_ITEM, true);
 
	print("");
 
	print(" Item Ascending");
 
	list.AddItem( 5, 10);
 
	list.AddItem(10, 10);
 
	list.AddItem(15, 20);
 
	list.AddItem(20, 20);
 
	list.AddItem(25, 30);
 
	list.AddItem(30, 30);
 
	list.AddItem(35, 40);
 
	list.AddItem(40, 40);
 

	
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		list.RemoveItem(i + 10);
 
		list.RemoveItem(i + 5);
 
		list.RemoveItem(i);
 
		print("   " + i);
 
	}
 

	
 
	list.AddItem(10, 10);
 
	list.AddItem(20, 20);
 
	list.AddItem(30, 30);
 
	list.AddItem(40, 40);
 

	
 
	print("");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		list.SetValue(i, 50);
 
		print("   " + i);
 
	}
 
	print("");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("   " + i);
 
	}
 

	
 
	list.Clear();
 
	foreach (idx, val in list) {
 
		print("   " + idx);
 
	}
 
}
 

	
 
function Regression::Std()
 
{
 
	print("");
 
	print("--Std--");
 
	print(" abs(-21): " + abs(-21));
 
	print(" abs( 21): " + abs(21));
 
}
 

	
 
function Regression::Base()
 
{
 
	print("");
 
	print("--AIBase--");
 
	print("  Rand():       " + AIBase.Rand());
 
	print("  Rand():       " + AIBase.Rand());
 
	print("  Rand():       " + AIBase.Rand());
 
	print("  RandRange(0): " + AIBase.RandRange(0));
 
	print("  RandRange(0): " + AIBase.RandRange(0));
 
	print("  RandRange(0): " + AIBase.RandRange(0));
 
	print("  RandRange(1): " + AIBase.RandRange(1));
 
	print("  RandRange(1): " + AIBase.RandRange(1));
 
	print("  RandRange(1): " + AIBase.RandRange(1));
 
	print("  RandRange(2): " + AIBase.RandRange(2));
 
	print("  RandRange(2): " + AIBase.RandRange(2));
 
	print("  RandRange(2): " + AIBase.RandRange(2));
 
	print("  RandRange(9): " + AIBase.RandRange(9));
 
	print("  RandRange(9): " + AIBase.RandRange(9));
 
	print("  RandRange(9): " + AIBase.RandRange(9));
 
	print("  Chance(1, 2): " + AIBase.Chance(1, 2));
 
	print("  Chance(1, 2): " + AIBase.Chance(1, 2));
 
	print("  Chance(1, 2): " + AIBase.Chance(1, 2));
 

	
 
	AIRoad.SetCurrentRoadType(AIRoad.ROADTYPE_ROAD);
 
}
 

	
 
function Regression::Airport()
 
{
 
	print("");
 
	print("--AIAirport--");
 

	
 
	print("  IsHangarTile():       " + AIAirport.IsHangarTile(32116));
 
	print("  IsAirportTile():      " + AIAirport.IsAirportTile(32116));
 
	print("  GetHangarOfAirport(): " + AIAirport.GetHangarOfAirport(32116));
 
	print("  GetAirportType():     " + AIAirport.GetAirportType(32116));
 

	
 
	for (local i = -1; i < 10; i++) {
 
		print("  IsValidAirportType(" + i + "):       " + AIAirport.IsValidAirportType(i));
 
		print("  AirportAvailable(" + i + "):         " + AIAirport.AirportAvailable(i));
 
		print("  GetAirportWidth(" + i + "):          " + AIAirport.GetAirportWidth(i));
 
		print("  GetAirportHeight(" + i + "):         " + AIAirport.GetAirportHeight(i));
 
		print("  GetAirportCoverageRadius(" + i + "): " + AIAirport.GetAirportCoverageRadius(i));
 
	}
 

	
 
	print("  GetBankBalance():     " + AICompany.GetBankBalance(AICompany.MY_COMPANY));
 
	print("  BuildAirport():       " + AIAirport.BuildAirport(32116, 0, true));
 
	print("  IsHangarTile():       " + AIAirport.IsHangarTile(32116));
 
	print("  IsAirportTile():      " + AIAirport.IsAirportTile(32116));
 
	print("  GetAirportType():     " + AIAirport.GetAirportType(32119));
 
	print("  GetHangarOfAirport(): " + AIAirport.GetHangarOfAirport(32116));
 
	print("  IsHangarTile():       " + AIAirport.IsHangarTile(32119));
 
	print("  IsAirportTile():      " + AIAirport.IsAirportTile(32119));
 
	print("  GetAirportType():     " + AIAirport.GetAirportType(32119));
 
	print("  GetBankBalance():     " + AICompany.GetBankBalance(AICompany.MY_COMPANY));
 

	
 
	print("  RemoveAirport():      " + AIAirport.RemoveAirport(32118));
 
	print("  IsHangarTile():       " + AIAirport.IsHangarTile(32119));
 
	print("  IsAirportTile():      " + AIAirport.IsAirportTile(32119));
 
	print("  GetBankBalance():     " + AICompany.GetBankBalance(AICompany.MY_COMPANY));
 
	print("  BuildAirport():       " + AIAirport.BuildAirport(32116, 0, true));
 
}
 

	
 
function Regression::Bridge()
 
{
 
	local j = 0;
 

	
 
	print("");
 
	print("--Bridge--");
 
	for (local i = -1; i < 14; i++) {
 
		if (AIBridge.IsValidBridge(i)) j++;
 
		print("  Bridge " + i);
 
		print("    IsValidBridge():    " + AIBridge.IsValidBridge(i));
 
		print("    GetName():          " + AIBridge.GetName(i));
 
		print("    GetMaxSpeed():      " + AIBridge.GetMaxSpeed(i));
 
		print("    GetPrice():         " + AIBridge.GetPrice(i, 5));
 
		print("    GetMaxLength():     " + AIBridge.GetMaxLength(i));
 
		print("    GetMinLength():     " + AIBridge.GetMinLength(i));
 
		print("    GetYearAvailable(): " + AIBridge.GetYearAvailable(i));
 
	}
 
	print("  Valid Bridges:        " + j);
 

	
 
	print("  IsBridgeTile():       " + AIBridge.IsBridgeTile(33160));
 
	print("  RemoveBridge():       " + AIBridge.RemoveBridge(33155));
 
	print("  GetLastErrorString(): " + AIError.GetLastErrorString());
 
	print("  GetOtherBridgeEnd():  " + AIBridge.GetOtherBridgeEnd(33160));
 
	print("  BuildBridge():        " + AIBridge.BuildBridge(AIVehicle.VEHICLE_ROAD, 5, 33160, 33155));
 
	print("  IsBridgeTile():       " + AIBridge.IsBridgeTile(33160));
 
	print("  IsBridgeTile():       " + AIBridge.IsBridgeTile(33155));
 
	print("  GetOtherBridgeEnd():  " + AIBridge.GetOtherBridgeEnd(33160));
 
	print("  BuildBridge():        " + AIBridge.BuildBridge(AIVehicle.VEHICLE_ROAD, 5, 33160, 33155));
 
	print("  GetLastErrorString(): " + AIError.GetLastErrorString());
 
	print("  RemoveBridge():       " + AIBridge.RemoveBridge(33155));
 
	print("  IsBridgeTile():       " + AIBridge.IsBridgeTile(33160));
 
}
 

	
 
function Regression::BridgeList()
 
{
 
	local list = AIBridgeList();
 

	
 
	print("");
 
	print("--BridgeList--");
 
	print("  Count():             " + list.Count());
 
	list.Valuate(AIBridge.GetMaxSpeed);
 
	print("  MaxSpeed ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AIBridge.GetPrice, 5);
 
	print("  Price ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AIBridge.GetMaxLength);
 
	print("  MaxLength ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AIBridge.GetMinLength);
 
	print("  MinLength ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AIBridge.GetYearAvailable);
 
	print("  YearAvailable ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 

	
 
	list = AIBridgeList_Length(14);
 

	
 
	print("");
 
	print("--BridgeList_Length--");
 
	print("  Count():             " + list.Count());
 
	list.Valuate(AIBridge.GetMaxSpeed);
 
	print("  MaxSpeed ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AIBridge.GetPrice, 14);
 
	print("  Price ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
}
 

	
 
function Regression::Cargo()
 
{
 
	print("");
 
	print("--AICargo--");
 
	for (local i = -1; i < 15; i++) {
 
		print("  Cargo " + i);
 
		print("    IsValidCargo():          " + AICargo.IsValidCargo(i));
 
		print("    GetCargoLabel():         '" + AICargo.GetCargoLabel(i)+ "'");
 
		print("    IsFreight():             " + AICargo.IsFreight(i));
 
		print("    HasCargoClass():         " + AICargo.HasCargoClass(i, AICargo.CC_PASSENGERS));
 
		print("    GetTownEffect():         " + AICargo.GetTownEffect(i));
 
		print("    GetCargoIncome(0, 0):    " + AICargo.GetCargoIncome(i, 0, 0));
 
		print("    GetCargoIncome(10, 10):  " + AICargo.GetCargoIncome(i, 10, 10));
 
		print("    GetCargoIncome(100, 10): " + AICargo.GetCargoIncome(i, 100, 10));
 
		print("    GetCargoIncome(10, 100): " + AICargo.GetCargoIncome(i, 10, 100));
 
	}
 
}
 

	
 
function Regression::CargoList()
 
{
 
	local list = AICargoList();
 

	
 
	print("");
 
	print("--CargoList--");
 
	print("  Count():            " + list.Count());
 
	list.Valuate(AICargo.IsFreight);
 
	print("  IsFreight ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 

	
 
	list.Valuate(AICargo.GetCargoIncome, 100, 100);
 
	print("  CargoIncomes(100, 100) ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 

	
 
	list = AICargoList_IndustryAccepting(8);
 
	print("");
 
	print("--CargoList_IndustryAccepting--");
 
	print("  Count():            " + list.Count());
 
	print("  ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i);
 
	}
 

	
 
	list = AICargoList_IndustryProducing(4);
 
	print("");
 
	print("--CargoList_IndustryProducing--");
 
	print("  Count():            " + list.Count());
 
	print("  ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i);
 
	}
 
}
 

	
 
function Regression::Company()
 
{
 
	print("");
 
	print("--Company--");
 

	
 
	/* Test AIXXXMode() in scopes */
 
	{
 
		local test = AITestMode();
 
		print("  SetName():            " + AICompany.SetName("Regression"));
 
		print("  SetName():            " + AICompany.SetName("Regression"));
 
		{
 
			local exec = AIExecMode();
 
			print("  SetName():            " + AICompany.SetName("Regression"));
 
			print("  SetName():            " + AICompany.SetName("Regression"));
 
			print("  GetLastErrorString(): " + AIError.GetLastErrorString());
 
		}
 
	}
 

	
 
	print("  GetName():                   " + AICompany.GetName(AICompany.MY_COMPANY));
 
	print("  GetPresidentName():          " + AICompany.GetPresidentName(AICompany.MY_COMPANY));
 
	print("  SetPresidentName():          " + AICompany.SetPresidentName("Regression AI"));
 
	print("  GetPresidentName():          " + AICompany.GetPresidentName(AICompany.MY_COMPANY));
 
	print("  GetCompanyValue():           " + AICompany.GetCompanyValue(AICompany.MY_COMPANY));
 
	print("  GetBankBalance():            " + AICompany.GetBankBalance(AICompany.MY_COMPANY));
 
	print("  GetName():                   " + AICompany.GetName(240));
 
	print("  GetLoanAmount():             " + AICompany.GetLoanAmount());
 
	print("  GetMaxLoanAmount():          " + AICompany.GetMaxLoanAmount());
 
	print("  GetLoanInterval():           " + AICompany.GetLoanInterval());
 
	print("  SetLoanAmount(1):            " + AICompany.SetLoanAmount(1));
 
	print("  SetLoanAmount(100):          " + AICompany.SetLoanAmount(100));
 
	print("  SetLoanAmount(10000):        " + AICompany.SetLoanAmount(10000));
 
	print("  GetLastErrorString():        " + AIError.GetLastErrorString());
 
	print("  GetBankBalance():            " + AICompany.GetBankBalance(AICompany.MY_COMPANY));
 
	print("  GetLoanAmount():             " + AICompany.GetLoanAmount());
 
	print("  SetMinimumLoanAmount(31337): " + AICompany.SetMinimumLoanAmount(31337));
 
	print("  GetBankBalance():            " + AICompany.GetBankBalance(AICompany.MY_COMPANY));
 
	print("  GetLoanAmount():             " + AICompany.GetLoanAmount());
 
	print("  SetLoanAmount(10000):        " + AICompany.SetLoanAmount(AICompany.GetMaxLoanAmount()));
 
	print("  GetBankBalance():            " + AICompany.GetBankBalance(AICompany.MY_COMPANY));
 
	print("  GetLoanAmount():             " + AICompany.GetLoanAmount());
 
	print("  GetCompanyHQ():              " + AICompany.GetCompanyHQ(AICompany.MY_COMPANY));
 
	print("  BuildCompanyHQ():            " + AICompany.BuildCompanyHQ(AIMap.GetTileIndex(127, 129)));
 
	print("  GetCompanyHQ():              " + AICompany.GetCompanyHQ(AICompany.MY_COMPANY));
 
	print("  BuildCompanyHQ():            " + AICompany.BuildCompanyHQ(AIMap.GetTileIndex(129, 129)));
 
	print("  GetCompanyHQ():              " + AICompany.GetCompanyHQ(AICompany.MY_COMPANY));
 
	print("  BuildCompanyHQ():            " + AICompany.BuildCompanyHQ(AIMap.GetTileIndex(129, 128)));
 
	print("  GetLastErrorString():        " + AIError.GetLastErrorString());
 
	print("  GetAutoRenewStatus();        " + AICompany.GetAutoRenewStatus(AICompany.MY_COMPANY));
 
	print("  SetAutoRenewStatus(true);    " + AICompany.SetAutoRenewStatus(true));
 
	print("  GetAutoRenewStatus();        " + AICompany.GetAutoRenewStatus(AICompany.MY_COMPANY));
 
	print("  SetAutoRenewStatus(true);    " + AICompany.SetAutoRenewStatus(true));
 
	print("  SetAutoRenewStatus(false);   " + AICompany.SetAutoRenewStatus(false));
 
	print("  GetAutoRenewMonths();        " + AICompany.GetAutoRenewMonths(AICompany.MY_COMPANY));
 
	print("  SetAutoRenewMonths(-12);     " + AICompany.SetAutoRenewMonths(-12));
 
	print("  GetAutoRenewMonths();        " + AICompany.GetAutoRenewMonths(AICompany.MY_COMPANY));
 
	print("  SetAutoRenewMonths(-12);     " + AICompany.SetAutoRenewMonths(-12));
 
	print("  SetAutoRenewMonths(6);       " + AICompany.SetAutoRenewMonths(6));
 
	print("  GetAutoRenewMoney();         " + AICompany.GetAutoRenewMoney(AICompany.MY_COMPANY));
 
	print("  SetAutoRenewMoney(200000);   " + AICompany.SetAutoRenewMoney(200000));
 
	print("  GetAutoRenewMoney();         " + AICompany.GetAutoRenewMoney(AICompany.MY_COMPANY));
 
	print("  SetAutoRenewMoney(200000);   " + AICompany.SetAutoRenewMoney(200000));
 
	print("  SetAutoRenewMoney(100000);   " + AICompany.SetAutoRenewMoney(100000));
 
}
 

	
 
function Regression::Engine()
 
{
 
	local j = 0;
 

	
 
	print("");
 
	print("--Engine--");
 
	for (local i = -1; i < 257; i++) {
 
		if (AIEngine.IsValidEngine(i)) j++;
 
		print("  Engine " + i);
 
		print("    IsValidEngine():    " + AIEngine.IsValidEngine(i));
 
		print("    GetName():          " + AIEngine.GetName(i));
 
		print("    GetCargoType():     " + AIEngine.GetCargoType(i));
 
		print("    CanRefitCargo():    " + AIEngine.CanRefitCargo(i, 1));
 
		print("    GetCapacity():      " + AIEngine.GetCapacity(i));
 
		print("    GetReliability():   " + AIEngine.GetReliability(i));
 
		print("    GetMaxSpeed():      " + AIEngine.GetMaxSpeed(i));
 
		print("    GetPrice():         " + AIEngine.GetPrice(i));
 
		print("    GetMaxAge():        " + AIEngine.GetMaxAge(i));
 
		print("    GetRunningCost():   " + AIEngine.GetRunningCost(i));
 
		print("    GetVehicleType():   " + AIEngine.GetVehicleType(i));
 
		print("    GetRailType():      " + AIEngine.GetRailType(i));
 
		print("    GetRoadType():      " + AIEngine.GetRoadType(i));
 
		print("    GetPlaneType():     " + AIEngine.GetPlaneType(i));
 
	}
 
	print("  Valid Engines:        " + j);
 
}
 

	
 
function Regression::EngineList()
 
{
 
	local list = AIEngineList(AIVehicle.VEHICLE_ROAD);
 

	
 
	print("");
 
	print("--EngineList--");
 
	print("  Count():             " + list.Count());
 
	list.Valuate(AIEngine.GetCargoType);
 
	print("  CargoType ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AIEngine.GetCapacity);
 
	print("  Capacity ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AIEngine.GetReliability);
 
	print("  Reliability ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AIEngine.GetMaxSpeed);
 
	print("  MaxSpeed ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AIEngine.GetPrice);
 
	print("  Price ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
}
 

	
 
function cost_callback(old_path, new_tile, new_direction, self) { if (old_path == null) return 0; return old_path.GetCost() + 1; }
 
function estimate_callback(tile, direction, goals, self) { return goals[0] - tile; }
 
function neighbours_callback(path, cur_tile, self) { return [[cur_tile + 1, 1]]; }
 
function check_direction_callback(tile, existing_direction, new_direction, self) { return false; }
 

	
 
function Regression::Graph()
 
{
 
	print("--AyStar--");
 
	print("  Fastest path:");
 
	local as = AS(cost_callback, estimate_callback, neighbours_callback, check_direction_callback);
 

	
 
	local path = false;
 
	as.InitializePath([[1, 1]], [10]);
 
	while (path == false) path = as.FindPath(5);
 

	
 
	while (path != null) {
 
		print("    Tile " + path.GetTile());
 
		path = path.GetParent();
 
	}
 
}
 

	
 
function Regression::Group()
 
{
 
	print ("");
 
	print("--Group--");
 
	print("  SetAutoReplace():         " + AIGroup.SetAutoReplace(AIGroup.ALL_GROUP, 116, 117));
 
	print("  GetEngineReplacement():   " + AIGroup.GetEngineReplacement(AIGroup.ALL_GROUP, 116));
 
	print("  GetNumEngines():          " + AIGroup.GetNumEngines(AIGroup.ALL_GROUP, 116));
 
	print("  AIRoad.BuildRoadDepot():  " + AIRoad.BuildRoadDepot(10000, 10001));
 
	local vehicle = AIVehicle.BuildVehicle(10000, 116);
 
	print("  AIVehicle.BuildVehicle(): " + vehicle);
 
	print("  GetNumEngines():          " + AIGroup.GetNumEngines(AIGroup.ALL_GROUP, 116));
 
	local group = AIGroup.CreateGroup(AIVehicle.VEHICLE_ROAD);
 
	print("  CreateGroup():            " + group);
 
	print("  MoveVehicle():            " + AIGroup.MoveVehicle(group, vehicle));
 
	print("  GetNumEngines():          " + AIGroup.GetNumEngines(group, 116));
 
	print("  GetNumEngines():          " + AIGroup.GetNumEngines(AIGroup.ALL_GROUP, 116));
 
	print("  GetNumEngines():          " + AIGroup.GetNumEngines(AIGroup.DEFAULT_GROUP, 116));
 
	print("  GetName():                " + AIGroup.GetName(0));
 
	print("  GetName():                " + AIGroup.GetName(1));
 
	print("  AIVehicle.SellVehicle():  " + AIVehicle.SellVehicle(vehicle));
 
	print("  AITile.DemolishTile():    " + AITile.DemolishTile(10000));
 
	print("  HasWagonRemoval():        " + AIGroup.HasWagonRemoval());
 
	print("  EnableWagonRemoval():     " + AIGroup.EnableWagonRemoval(true));
 
	print("  HasWagonRemoval():        " + AIGroup.HasWagonRemoval());
 
	print("  EnableWagonRemoval():     " + AIGroup.EnableWagonRemoval(false));
 
	print("  EnableWagonRemoval():     " + AIGroup.EnableWagonRemoval(false));
 
	print("  HasWagonRemoval():        " + AIGroup.HasWagonRemoval());
 
}
 

	
 
function Regression::Industry()
 
{
 
	local j = 0;
 

	
 
	print("");
 
	print("--Industry--");
 
	print("  GetMaxIndustryID():  " + AIIndustry.GetMaxIndustryID());
 
	print("  GetIndustryCount():  " + AIIndustry.GetIndustryCount());
 
	for (local i = -1; i < AIIndustry.GetMaxIndustryID() + 1; i++) {
 
		if (AIIndustry.IsValidIndustry(i)) j++;
 
		print("  Industry " + i);
 
		print("    IsValidIndustry(): " + AIIndustry.IsValidIndustry(i));
 
		print("    GetName():         " + AIIndustry.GetName(i));
 
		print("    GetLocation():     " + AIIndustry.GetLocation(i));
 
		print("    GetProduction():   " + AIIndustry.GetProduction(i, 1));
 
		print("    IsCargoAccepted(): " + AIIndustry.IsCargoAccepted(i, 1));
 

	
 
		local cargo_list = AICargoList();
 
		for (local j = cargo_list.Begin(); cargo_list.HasNext(); j = cargo_list.Next()) {
 
			if (AIIndustry.GetProduction(i, j) > 0) {
 
				print("	   GetLastMonthProduction():  " + AIIndustry.GetLastMonthProduction(i, j));
 
				print("	   GetLastMonthTransported(): " + AIIndustry.GetLastMonthTransported(i, j));
 
				print("	   GetStockpiledCargo():      " + AIIndustry.GetStockpiledCargo(i, j));
 
			}
 
		}
 
	}
 
	print("  Valid Industries:    " + j);
 
	print("  GetIndustryCount():  " + AIIndustry.GetIndustryCount());
 
}
 

	
 
function Regression::IndustryList()
 
{
 
	local list = AIIndustryList();
 

	
 
	print("");
 
	print("--IndustryList--");
 
	print("  Count():             " + list.Count());
 
	list.Valuate(AIIndustry.GetLocation);
 
	print("  Location ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AIIndustry.GetDistanceManhattanToTile, 30000);
 
	print("  DistanceManhattanToTile(30000) ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AIIndustry.GetDistanceSquareToTile, 30000);
 
	print("  DistanceSquareToTile(30000) ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AIIndustry.GetAmountOfStationsAround);
 
	print("  GetAmountOfStationsAround(30000) ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AIIndustry.IsCargoAccepted, 1);
 
	print("  CargoAccepted(1) ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AIIndustry.GetProduction, 1);
 
	list.KeepAboveValue(50);
 
	print("  KeepAboveValue(50): done");
 
	print("  Count():             " + list.Count());
 
	print("  Production ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 

	
 
	list = AIIndustryList_CargoAccepting(1);
 
	print("--IndustryList_CargoAccepting--");
 
	print("  Count():             " + list.Count());
 
	list.Valuate(AIIndustry.GetLocation);
 
	print("  Location ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 

	
 
	list = AIIndustryList_CargoProducing(1);
 
	print("--IndustryList_CargoProducing--");
 
	print("  Count():             " + list.Count());
 
	list.Valuate(AIIndustry.GetLocation);
 
	print("  Location ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
}
 

	
 
function Regression::IndustryTypeList()
 
{
 
	local list = AIIndustryTypeList();
 

	
 
	print("");
 
	print("--IndustryTypeList--");
 
	print("  Count():             " + list.Count());
 
	list.Valuate(AIIndustry.GetLocation);
 
	print("  Location ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    Id:                      " + i);
 
		print("    IsRawIndustry():         " + AIIndustryType.IsRawIndustry(i));
 
		print("    ProductionCanIncrease(): " + AIIndustryType.ProductionCanIncrease(i));
 
		print("    GetConstructionCost():   " + AIIndustryType.GetConstructionCost(i));
 
		print("    GetName():               " + AIIndustryType.GetName(i));
 
		print("    CanBuildIndustry():      " + AIIndustryType.CanBuildIndustry(i));
 
		print("    CanProspectIndustry():   " + AIIndustryType.CanProspectIndustry(i));
 
	}
 
}
 

	
 
function CustomValuator(list_id)
 
{
 
	return list_id * 4343;
 
}
 

	
 
function Regression::List()
 
{
 
	local list = AIList();
 

	
 
	print("");
 
	print("--List--");
 

	
 
	print("  IsEmpty():     " + list.IsEmpty());
 
	list.AddItem(1, 1);
 
	list.AddItem(2, 2);
 
	for (local i = 1000; i < 1100; i++) {
 
		list.AddItem(i, i);
 
	}
 
	list.RemoveItem(1050);
 
	list.RemoveItem(1150);
 
	list.ChangeItem(1051, 12);
 
	print("  Count():       " + list.Count());
 
	print("  HasItem(1050): " + list.HasItem(1050));
 
	print("  HasItem(1051): " + list.HasItem(1051));
 
	print("  IsEmpty():     " + list.IsEmpty());
 
	list.Sort(AIAbstractList.SORT_BY_ITEM, true);
 
	print("  List Dump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(CustomValuator);
 
	print("  Custom ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(function (a) { return a * 42; });
 
	print("  Custom ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AIBase.RandItem);
 
	print("  Randomize ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 

	
 
	list.KeepTop(10);
 
	print("  KeepTop(10):");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.KeepBottom(8);
 
	print("  KeepBottom(8):");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.RemoveBottom(2);
 
	print("  RemoveBottom(2):");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.RemoveTop(2);
 
	print("  RemoveTop(2):");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 

	
 
	local list2 = AIList();
 
	list2.AddItem(1003, 0);
 
	list2.AddItem(1004, 0);
 
	list.RemoveList(list2);
 
	print("  RemoveList({1003, 1004}):");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list2.AddItem(1005, 0);
 
	list.KeepList(list2);
 
	print("  KeepList({1003, 1004, 1005}):");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list2.Clear();
 
	for (local i = 4000; i < 4003; i++) {
 
		list2.AddItem(i, i * 2);
 
	}
 
	list2.AddItem(1005, 1005);
 
	list.AddList(list2);
 
	print("  AddList({1005, 4000, 4001, 4002}):");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list[4000] = 50;
 
	list[4006] = 12;
 

	
 
	print("  foreach():");
 
	foreach (idx, val in list) {
 
		print("    " + idx + " => " + val);
 
	}
 
	print("  []:");
 
	print("    4000 => " + list[4000]);
 

	
 
	list.Clear();
 
	print("  IsEmpty():     " + list.IsEmpty());
 
}
 

	
 
function Regression::Map()
 
{
 
	print("");
 
	print("--Map--");
 
	print("  GetMapSize():     " + AIMap.GetMapSize());
 
	print("  GetMapSizeX():    " + AIMap.GetMapSizeX());
 
	print("  GetMapSizeY():    " + AIMap.GetMapSizeY());
 
	print("  GetTileX(123):    " + AIMap.GetTileX(123));
 
	print("  GetTileY(123):    " + AIMap.GetTileY(123));
 
	print("  GetTileIndex():   " + AIMap.GetTileIndex(123, 0));
 
	print("  GetTileIndex():   " + AIMap.GetTileIndex(0, 123));
 
	print("  GetTileIndex():   " + AIMap.GetTileIndex(0, 0));
 
	print("  GetTileIndex():   " + AIMap.GetTileIndex(-1, -1));
 
	print("  GetTileIndex():   " + AIMap.GetTileIndex(10000, 10000));
 
	print("  IsValidTile(123): " + AIMap.IsValidTile(123));
 
	print("  GetTileX(124):    " + AIMap.GetTileX(124));
 
	print("  GetTileY(124):    " + AIMap.GetTileY(124));
 
	print("  IsValidTile(124): " + AIMap.IsValidTile(124));
 
	print("  IsValidTile(0):   " + AIMap.IsValidTile(0));
 
	print("  IsValidTile(-1):  " + AIMap.IsValidTile(-1));
 
	print("  IsValidTile():    " + AIMap.IsValidTile(AIMap.GetMapSize()));
 
	print("  IsValidTile():    " + AIMap.IsValidTile(AIMap.GetMapSize() - AIMap.GetMapSizeX() - 2));
 
	print("  DemolishTile():   " + AITile.DemolishTile(19592));
 
	print("  DemolishTile():   " + AITile.DemolishTile(19335));
 
	print("  Distance");
 
	print("    DistanceManhattan(): " + AIMap.DistanceManhattan(1, 10000));
 
	print("    DistanceMax():       " + AIMap.DistanceMax(1, 10000));
 
	print("    DistanceSquare():    " + AIMap.DistanceSquare(1, 10000));
 
	print("    DistanceFromEdge():  " + AIMap.DistanceFromEdge(10000));
 
}
 

	
 
function Regression::Marine()
 
{
 
	print("");
 
	print("--AIMarine--");
 

	
 
	print("  IsWaterDepotTile():   " + AIMarine.IsWaterDepotTile(32116));
 
	print("  IsDockTile():         " + AIMarine.IsDockTile(32116));
 
	print("  IsBuoyTile():         " + AIMarine.IsBuoyTile(32116));
 
	print("  IsLockTile():         " + AIMarine.IsLockTile(32116));
 
	print("  IsCanalTile():        " + AIMarine.IsCanalTile(32116));
 

	
 
	print("  GetBankBalance():     " + AICompany.GetBankBalance(AICompany.MY_COMPANY));
 
	print("  BuildWaterDepot():    " + AIMarine.BuildWaterDepot(28479, false));
 
	print("  BuildDock():          " + AIMarine.BuildDock(29253, true));
 
	print("  BuildBuoy():          " + AIMarine.BuildBuoy(28481));
 
	print("  BuildLock():          " + AIMarine.BuildLock(28487));
 
	print("  HasTransportType():   " + AITile.HasTransportType(32127, AITile.TRANSPORT_WATER));
 
	print("  BuildCanal():         " + AIMarine.BuildCanal(32127));
 
	print("  HasTransportType():   " + AITile.HasTransportType(32127, AITile.TRANSPORT_WATER));
 
	print("  IsWaterDepotTile():   " + AIMarine.IsWaterDepotTile(28479));
 
	print("  IsDockTile():         " + AIMarine.IsDockTile(29253));
 
	print("  IsBuoyTile():         " + AIMarine.IsBuoyTile(28481));
 
	print("  IsLockTile():         " + AIMarine.IsLockTile(28487));
 
	print("  IsCanalTile():        " + AIMarine.IsCanalTile(32127));
 
	print("  GetBankBalance():     " + AICompany.GetBankBalance(AICompany.MY_COMPANY));
 

	
 
	print("  RemoveWaterDepot():   " + AIMarine.RemoveWaterDepot(28479));
 
	print("  RemoveDock():         " + AIMarine.RemoveDock(29253));
 
	print("  RemoveBuoy():         " + AIMarine.RemoveBuoy(28481));
 
	print("  RemoveLock():         " + AIMarine.RemoveLock(28487));
 
	print("  RemoveCanal():        " + AIMarine.RemoveCanal(32127));
 
	print("  IsWaterDepotTile():   " + AIMarine.IsWaterDepotTile(28479));
 
	print("  IsDockTile():         " + AIMarine.IsDockTile(29253));
 
	print("  IsBuoyTile():         " + AIMarine.IsBuoyTile(28481));
 
	print("  IsLockTile():         " + AIMarine.IsLockTile(28487));
 
	print("  IsCanalTile():        " + AIMarine.IsCanalTile(32127));
 
	print("  GetBankBalance():     " + AICompany.GetBankBalance(AICompany.MY_COMPANY));
 

	
 
	print("  BuildWaterDepot():    " + AIMarine.BuildWaterDepot(28479, false));
 
	print("  BuildDock():          " + AIMarine.BuildDock(29253, true));
 
}
 

	
 
function Regression::Order()
 
{
 
	print("");
 
	print("--Order--");
 
	print("  GetOrderCount():       " + AIOrder.GetOrderCount(12));
 
	print("  GetOrderDestination(): " + AIOrder.GetOrderDestination(12, 1));
 
	print("  AreOrderFlagsValid():  " + AIOrder.AreOrderFlagsValid(33416, AIOrder.AIOF_TRANSFER));
 
	print("  IsValidVehicleOrder(): " + AIOrder.IsValidVehicleOrder(12, 1));
 
	print("  GetOrderFlags():       " + AIOrder.GetOrderFlags(12, 1));
 
	print("  AppendOrder():         " + AIOrder.AppendOrder(12, 33416, AIOrder.AIOF_TRANSFER));
 
	print("  InsertOrder():         " + AIOrder.InsertOrder(12, 0, 33416, AIOrder.AIOF_TRANSFER));
 
	print("  GetOrderCount():       " + AIOrder.GetOrderCount(12));
 
	print("  IsValidVehicleOrder(): " + AIOrder.IsValidVehicleOrder(12, 1));
 
	print("  RemoveOrder():         " + AIOrder.RemoveOrder(12, 0));
 
	print("  ChangeOrder():         " + AIOrder.ChangeOrder(12, 0, AIOrder.AIOF_FULL_LOAD));
 
	print("  GetOrderDestination(): " + AIOrder.GetOrderDestination(12, 0));
 
	print("  CopyOrders():          " + AIOrder.CopyOrders(12, 1));
 
	print("  CopyOrders():          " + AIOrder.CopyOrders(13, 12));
 
	print("  ShareOrders():         " + AIOrder.ShareOrders(13, 1));
 
	print("  ShareOrders():         " + AIOrder.ShareOrders(13, 12));
 
	print("  UnshareOrders():       " + AIOrder.UnshareOrders(13));
 
	print("  AppendOrder():         " + AIOrder.AppendOrder(12, 33421, AIOrder.AIOF_NONE));
 

	
 
	local list = AIStationList_Vehicle(12);
 

	
 
	print("");
 
	print("--StationList_Vehicle--");
 
	print("  Count():             " + list.Count());
 
	list.Valuate(AIStation.GetLocation);
 
	print("  Location ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AIStation.GetCargoWaiting, 0);
 
	print("  CargoWaiting(0) ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AIStation.GetCargoWaiting, 1);
 
	print("  CargoWaiting(1) ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AIStation.GetCargoRating, 1);
 
	print("  CargoRating(1) ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AIStation.GetDistanceManhattanToTile, 30000);
 
	print("  DistanceManhattanToTile(30000) ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AIStation.GetDistanceSquareToTile, 30000);
 
	print("  DistanceSquareToTile(30000) ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AIStation.IsWithinTownInfluence, 0);
 
	print("  IsWithinTownInfluence(0) ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 

	
 
	list = AIVehicleList_Station(3);
 

	
 
	print("");
 
	print("--VehicleList_Station--");
 
	print("  Count():             " + list.Count());
 
	list.Valuate(AIVehicle.GetLocation);
 
	print("  Location ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	print("  foreach():");
 
	foreach (idx, val in list) {
 
		print("    " + idx + " => " + val);
 
	}
 
}
 

	
 
function Regression::Pathfinder()
 
{
 
	print("");
 
	print("--PathFinder--");
 
	print("  Road Between Towns:");
 

	
 
	local pathfinder = RPF();
 

	
 
	local path = false;
 
	pathfinder.InitializePath([AITown.GetLocation(0)], [AITown.GetLocation(1)]);
 
	while (path == false) path = pathfinder.FindPath(1000);
 

	
 
	while (path != null) {
 
		print("    Tile " + path.GetTile());
 
		path = path.GetParent();
 
	}
 
}
 

	
 
function Regression::QueueTest(queue)
 
{
 
	print("  Count(): " + queue.Count());
 
	print("  Peek():  " + queue.Peek());
 
	print("  Pop():   " + queue.Pop());
 
	queue.Insert(6, 20);
 
	queue.Insert(7, 40);
 
	queue.Insert(2, 10);
 
	queue.Insert(5, 15);
 
	queue.Insert(8, 60);
 
	queue.Insert(1,  5);
 
	queue.Insert(3, 10);
 
	queue.Insert(9, 90);
 
	queue.Insert(4, 10);
 
	print("  Count(): " + queue.Count());
 
	print("  Peek():  " + queue.Peek());
 
	for (local i = 4; i > 0; i--) {
 
		print("  Pop():   " + queue.Pop());
 
	}
 
	queue.Insert(1, 5);
 
	queue.Insert(10, 100);
 
	for (local i = queue.Count(); i > 0; i--) {
 
		print("  Pop():   " + queue.Pop());
 
	}
 
	print("  Peek():  " + queue.Peek());
 
	print("  Pop():   " + queue.Pop());
 
	print("  Count(): " + queue.Count());
 
}
 

	
 
function Regression::Queues()
 
{
 
	print("");
 
	print("--PriorityQueue--");
 
	QueueTest(PQ());
 
	print("");
 
	print("--BinaryHeap--");
 
	QueueTest(BH());
 
	print("");
 
	print("--FibonacciHeap--");
 
	QueueTest(FH());
 
}
 

	
 
function Regression::RailTypeList()
 
{
 
	local list = AIRailTypeList();
 

	
 
	print("");
 
	print("--RailTypeList--");
 
	print("  Count():             " + list.Count());
 
	print("  ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    RailType:                " + i);
 
		print("    IsRailTypeAvailable():   " + AIRail.IsRailTypeAvailable(i));
 
	}
 
}
 

	
 
function Regression::Rail()
 
{
 
	AIRail.SetCurrentRailType(0);
 

	
 
	print("");
 
	print("--Rail--");
 
	print("    IsRailTile():                  " + AIRail.IsRailTile(10002));
 
	print("    BuildRailTrack():              " + AIRail.BuildRailTrack(10002, AIRail.RAILTRACK_NW_SE));
 
	print("    BuildSignal():                 " + AIRail.BuildSignal(10002, 10258, AIRail.SIGNALTYPE_PBS));
 
	print("    RemoveRailTrack():             " + AIRail.RemoveRailTrack(10002, AIRail.RAILTRACK_NW_NE));
 
	print("    RemoveRailTrack():             " + AIRail.RemoveRailTrack(10002, AIRail.RAILTRACK_NW_SE));
 
	print("    BuildRail():                   " + AIRail.BuildRail(10002, 10003, 10006));
 
	print("    HasTransportType():            " + AITile.HasTransportType(10005, AITile.TRANSPORT_RAIL));
 
	print("    HasTransportType():            " + AITile.HasTransportType(10006, AITile.TRANSPORT_RAIL));
 
	print("    RemoveRail():                  " + AIRail.RemoveRail(10005, 10004, 10001));
 

	
 
	print("  Depot");
 
	print("    IsRailTile():                  " + AIRail.IsRailTile(33411));
 
	print("    BuildRailDepot():              " + AIRail.BuildRailDepot(0, 1));
 
	print("    BuildRailDepot():              " + AIRail.BuildRailDepot(33411, 33411));
 
	print("    BuildRailDepot():              " + AIRail.BuildRailDepot(33411, 33414));
 
	print("    BuildRailDepot():              " + AIRail.BuildRailDepot(33411, 33412));
 
	print("    GetRailDepotFrontTile():       " + AIRail.GetRailDepotFrontTile(33411));
 
	print("    IsBuildable():                 " + AITile.IsBuildable(33411));
 
	local list = AIDepotList(AITile.TRANSPORT_RAIL);
 
	print("    DepotList");
 
	print("      Count():                     " + list.Count());
 
	list.Valuate(AITile.GetDistanceManhattanToTile, 0);
 
	print("      Depot distance from (0,0) ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("        " + i + " => " + list.GetValue(i));
 
	}
 
	print("    RemoveDepot():                 " + AITile.DemolishTile(33411));
 

	
 
	print("  Station");
 
	print("    BuildRailStation():            " + AIRail.BuildRailStation(0, AIRail.RAILTRACK_NE_SW, 1, 1, false));
 
	print("    BuildRailStation():            " + AIRail.BuildRailStation(7958, AIRail.RAILTRACK_NE_SW, 4, 5, false));
 
	print("    IsRailStationTile():           " + AIRail.IsRailStationTile(7957));
 
	print("    IsRailStationTile():           " + AIRail.IsRailStationTile(7958));
 
	print("    IsRailStationTile():           " + AIRail.IsRailStationTile(7959));
 
	print("    RemoveRailStationTileRect():   " + AIRail.RemoveRailStationTileRect(7959, 7959));
 
	print("    IsRailStationTile():           " + AIRail.IsRailStationTile(7957));
 
	print("    IsRailStationTile():           " + AIRail.IsRailStationTile(7958));
 
	print("    IsRailStationTile():           " + AIRail.IsRailStationTile(7959));
 
	print("    DemolishTile():                " + AITile.DemolishTile(7960));
 
	print("    IsRailStationTile():           " + AIRail.IsRailStationTile(7957));
 
	print("    IsRailStationTile():           " + AIRail.IsRailStationTile(7958));
 
	print("    IsRailStationTile():           " + AIRail.IsRailStationTile(7959));
 
}
 

	
 
function Regression::Road()
 
{
 
	print("");
 
	print("--Road--");
 
	print("  Road");
 
	print("    IsRoadTile():                  " + AIRoad.IsRoadTile(33411));
 
	print("    BuildRoad():                   " + AIRoad.BuildRoad(0, 1));
 
	print("    BuildRoad():                   " + AIRoad.BuildRoad(33411, 33411));
 
	print("    HasTransportType():            " + AITile.HasTransportType(33413, AITile.TRANSPORT_ROAD));
 
	print("    BuildRoad():                   " + AIRoad.BuildRoad(33411, 33414));
 
	print("    HasTransportType():            " + AITile.HasTransportType(33413, AITile.TRANSPORT_ROAD));
 
	print("    AreRoadTilesConnected():       " + AIRoad.AreRoadTilesConnected(33412, 33413));
 
	print("    IsRoadTile():                  " + AIRoad.IsRoadTile(33411));
 
	print("    HasRoadType(Road):             " + AIRoad.HasRoadType(33411, AIRoad.ROADTYPE_ROAD));
 
	print("    HasRoadType(Tram):             " + AIRoad.HasRoadType(33411, AIRoad.ROADTYPE_TRAM));
 
	print("    GetNeighbourRoadCount():       " + AIRoad.GetNeighbourRoadCount(33412));
 
	print("    RemoveRoad():                  " + AIRoad.RemoveRoad(33411, 33411));
 
	print("    RemoveRoad():                  " + AIRoad.RemoveRoad(33411, 33412));
 
	print("    RemoveRoad():                  " + AIRoad.RemoveRoad(19590, 19590));
 
	print("    RemoveRoad():                  " + AIRoad.RemoveRoad(33411, 33414));
 
	print("    BuildOneWayRoad():             " + AIRoad.BuildOneWayRoad(33411, 33414));
 
	print("    AreRoadTilesConnected():       " + AIRoad.AreRoadTilesConnected(33412, 33413));
 
	print("    AreRoadTilesConnected():       " + AIRoad.AreRoadTilesConnected(33413, 33412));
 
	print("    BuildOneWayRoad():             " + AIRoad.BuildOneWayRoad(33413, 33412));
 
	print("    AreRoadTilesConnected():       " + AIRoad.AreRoadTilesConnected(33412, 33413));
 
	print("    AreRoadTilesConnected():       " + AIRoad.AreRoadTilesConnected(33413, 33412));
 
	print("    BuildOneWayRoad():             " + AIRoad.BuildOneWayRoad(33412, 33413));
 
	print("    BuildOneWayRoad():             " + AIRoad.BuildOneWayRoad(33413, 33412));
 
	print("    AreRoadTilesConnected():       " + AIRoad.AreRoadTilesConnected(33412, 33413));
 
	print("    AreRoadTilesConnected():       " + AIRoad.AreRoadTilesConnected(33413, 33412));
 
	print("    RemoveRoad():                  " + AIRoad.RemoveRoad(33411, 33412));
 
	print("    IsRoadTypeAvailable(Road):     " + AIRoad.IsRoadTypeAvailable(AIRoad.ROADTYPE_ROAD));
 
	print("    IsRoadTypeAvailable(Tram):     " + AIRoad.IsRoadTypeAvailable(AIRoad.ROADTYPE_TRAM));
 
	print("    SetCurrentRoadType(Tram):      " + AIRoad.SetCurrentRoadType(AIRoad.ROADTYPE_TRAM));
 
	print("    GetCurrentRoadType():          " + AIRoad.GetCurrentRoadType());
 

	
 
	print("  Depot");
 
	print("    IsRoadTile():                  " + AIRoad.IsRoadTile(33411));
 
	print("    BuildRoadDepot():              " + AIRoad.BuildRoadDepot(0, 1));
 
	print("    BuildRoadDepot():              " + AIRoad.BuildRoadDepot(33411, 33411));
 
	print("    BuildRoadDepot():              " + AIRoad.BuildRoadDepot(33411, 33414));
 
	print("    BuildRoadDepot():              " + AIRoad.BuildRoadDepot(33411, 33412));
 
	print("    HasRoadType(Road):             " + AIRoad.HasRoadType(33411, AIRoad.ROADTYPE_ROAD));
 
	print("    HasRoadType(Tram):             " + AIRoad.HasRoadType(33411, AIRoad.ROADTYPE_TRAM));
 
	print("    GetLastError():                " + AIError.GetLastError());
 
	print("    GetLastErrorString():          " + AIError.GetLastErrorString());
 
	print("    GetErrorCategory():            " + AIError.GetErrorCategory());
 
	print("    IsRoadTile():                  " + AIRoad.IsRoadTile(33411));
 
	print("    GetRoadDepotFrontTile():       " + AIRoad.GetRoadDepotFrontTile(33411));
 
	print("    IsRoadDepotTile():             " + AIRoad.IsRoadDepotTile(33411));
 
	print("    IsBuildable():                 " + AITile.IsBuildable(33411));
 
	local list = AIDepotList(AITile.TRANSPORT_ROAD);
 
	print("    DepotList");
 
	print("      Count():                     " + list.Count());
 
	list.Valuate(AITile.GetDistanceManhattanToTile, 0);
 
	print("      Depot distance from (0,0) ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("        " + i + " => " + list.GetValue(i));
 
	}
 
	print("    RemoveRoadDepot():             " + AIRoad.RemoveRoadDepot(33411));
 
	print("    RemoveRoadDepot():             " + AIRoad.RemoveRoadDepot(33411));
 

	
 
	print("  Station");
 
	print("    IsRoadTile():                  " + AIRoad.IsRoadTile(33411));
 
	print("    BuildRoadStation():            " + AIRoad.BuildRoadStation(0, 1, false, false, true));
 
	print("    BuildRoadStation():            " + AIRoad.BuildRoadStation(33411, 33411, false, false, true));
 
	print("    BuildRoadStation():            " + AIRoad.BuildRoadStation(33411, 33414, false, false, true));
 
	print("    BuildRoadStation():            " + AIRoad.BuildRoadStation(33411, 33412, false, false, true));
 
	print("    IsStationTile():               " + AITile.IsStationTile(33411));
 
	print("    IsStationTile():               " + AITile.IsStationTile(33412));
 
	print("    HasRoadType(Road):             " + AIRoad.HasRoadType(33411, AIRoad.ROADTYPE_ROAD));
 
	print("    HasRoadType(Tram):             " + AIRoad.HasRoadType(33411, AIRoad.ROADTYPE_TRAM));
 
	print("    IsRoadTile():                  " + AIRoad.IsRoadTile(33411));
 
	print("    GetDriveThroughBackTile():     " + AIRoad.GetDriveThroughBackTile(33411));
 
	print("    GetRoadStationFrontTile():     " + AIRoad.GetRoadStationFrontTile(33411));
 
	print("    IsRoadStationTile():           " + AIRoad.IsRoadStationTile(33411));
 
	print("    IsDriveThroughRoadStationTile: " + AIRoad.IsDriveThroughRoadStationTile(33411));
 
	print("    RemoveRoadStation():           " + AIRoad.RemoveRoadStation(33411));
 
	print("    RemoveRoadStation():           " + AIRoad.RemoveRoadStation(33411));
 

	
 
	print("  Station Types");
 
	print("    BuildRoadStation(bus):         " + AIRoad.BuildRoadStation(33411, 33410, false, false, true));
 
	print("    BuildRoadStation(truck):       " + AIRoad.BuildRoadStation(33421, 33422, true,  false, true));
 
	print("    BuildRoadStation(truck):       " + AIRoad.BuildRoadStation(33412, 33413, true,  false, true));
 
	print("    BuildRoadStation(bus):         " + AIRoad.BuildRoadStation(33411 + 256, 33411, false, false, true));
 
	print("    BuildRoadStation(truck):       " + AIRoad.BuildRoadStation(33412 + 256, 33412 + 256 + 256, true,  false, true));
 
	print("    BuildRoadStation(bus-drive):   " + AIRoad.BuildRoadStation(33413, 33412, false, true, true));
 
	print("    BuildRoadStation(truck-drive): " + AIRoad.BuildRoadStation(33414, 33413, true,  true, true));
 
	print("    BuildRoadStation(bus-drive):   " + AIRoad.BuildRoadStation(33415, 33414, false, true, true));
 
	print("    BuildRoadStation(truck-drive): " + AIRoad.BuildRoadStation(33416, 33415, true,  true, true));
 
	print("    BuildRoadDepot():              " + AIRoad.BuildRoadDepot(33417, 33418));
 
	print("    GetRoadStationFrontTile():     " + AIRoad.GetRoadStationFrontTile(33411 + 256));
 
	print("    GetRoadStationFrontTile():     " + AIRoad.GetRoadStationFrontTile(33412 + 256));
 
	print("    IsDriveThroughRoadStationTile: " + AIRoad.IsDriveThroughRoadStationTile(33415));
 
	print("    IsBuildable():                 " + AITile.IsBuildable(33415));
 
	print("    GetDriveThroughBackTile():     " + AIRoad.GetDriveThroughBackTile(33415));
 
	print("    GetRoadStationFrontTile():     " + AIRoad.GetRoadStationFrontTile(33415));
 
	print("    IsRoadTile():                  " + AIRoad.IsRoadTile(33415));
 
}
 

	
 
function Regression::Sign()
 
{
 
	local j = 0;
 

	
 
	print("");
 
	print("--Sign--");
 
	print("  BuildSign(33410, 'Some Sign'):       " + AISign.BuildSign(33410, "Some Sign"));
 
	print("  BuildSign(33411, 'Test'):            " + AISign.BuildSign(33411, "Test"));
 
	print("  SetName(1, 'Test2'):                 " + AISign.SetName(1, "Test2"));
 
	local sign_id = AISign.BuildSign(33409, "Some other Sign");
 
	print("  BuildSign(33409, 'Some other Sign'): " + sign_id);
 
	print("  RemoveSign(" + sign_id + "):                       " + AISign.RemoveSign(sign_id));
 
	print("");
 
	print("  GetMaxSignID():    " + AISign.GetMaxSignID());
 
	for (local i = -1; i < AISign.GetMaxSignID() + 1; i++) {
 
		if (AISign.IsValidSign(i)) j++;
 
		print("  Sign " + i);
 
		print("    IsValidSign():   " + AISign.IsValidSign(i));
 
		print("    GetName():       " + AISign.GetName(i));
 
		print("    GetLocation():   " + AISign.GetLocation(i));
 
	}
 
	print("  Valid Signs:       " + j);
 
}
 

	
 
function Regression::Station()
 
{
 
	print("");
 
	print("--Station--");
 
	print("  IsValidStation(0):        " + AIStation.IsValidStation(0));
 
	print("  IsValidStation(1000):     " + AIStation.IsValidStation(1000));
 
	print("  GetName(0):               " + AIStation.GetName(0));
 
	print("  SetName(0):               " + AIStation.SetName(0, "Look, a station"));
 
	print("  GetName(0):               " + AIStation.GetName(0));
 
	print("  GetLocation(1):           " + AIStation.GetLocation(1));
 
	print("  GetLocation(1000):        " + AIStation.GetLocation(1000));
 
	print("  GetStationID(33411):      " + AIStation.GetStationID(33411));
 
	print("  GetStationID(34411):      " + AIStation.GetStationID(34411));
 
	print("  GetCargoWaiting(0, 0):    " + AIStation.GetCargoWaiting(0, 0));
 
	print("  GetCargoWaiting(1000, 0): " + AIStation.GetCargoWaiting(1000, 0));
 
	print("  GetCargoWaiting(0, 1000): " + AIStation.GetCargoWaiting(0, 1000));
 

	
 
	print("  GetStationID(33411):      " + AIStation.GetStationID(33411));
 
	print("  HasRoadType(3, TRAM):     " + AIStation.HasRoadType(3, AIRoad.ROADTYPE_TRAM));
 
	print("  HasRoadType(3, ROAD):     " + AIStation.HasRoadType(3, AIRoad.ROADTYPE_ROAD));
 
	print("  HasRoadType(33411, TRAM): " + AIRoad.HasRoadType(33411, AIRoad.ROADTYPE_TRAM));
 
	print("  HasRoadType(33411, ROAD): " + AIRoad.HasRoadType(33411, AIRoad.ROADTYPE_ROAD));
 
	print("  HasStationType(3, BUS):   " + AIStation.HasStationType(3, AIStation.STATION_BUS_STOP));
 
	print("  HasStationType(3, TRAIN): " + AIStation.HasStationType(3, AIStation.STATION_TRAIN));
 

	
 
	print("  GetCoverageRadius(BUS):   " + AIStation.GetCoverageRadius(AIStation.STATION_BUS_STOP));
 
	print("  GetCoverageRadius(TRUCK): " + AIStation.GetCoverageRadius(AIStation.STATION_TRUCK_STOP));
 
	print("  GetCoverageRadius(TRAIN): " + AIStation.GetCoverageRadius(AIStation.STATION_TRAIN));
 

	
 
	print("  GetNearestTown():         " + AIStation.GetNearestTown(0));
 
	print("  GetNearestTown():         " + AIStation.GetNearestTown(10000));
 
	print("  GetNearestTown():         " + AIStation.GetNearestTown(3));
 

	
 
	local list = AIStationList(AIStation.STATION_BUS_STOP + AIStation.STATION_TRUCK_STOP);
 

	
 
	print("");
 
	print("--StationList--");
 
	print("  Count():             " + list.Count());
 
	list.Valuate(AIStation.GetLocation);
 
	print("  Location ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AIStation.GetCargoWaiting, 0);
 
	print("  CargoWaiting(0) ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AIStation.GetCargoWaiting, 1);
 
	print("  CargoWaiting(1) ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
}
 

	
 
function Regression::Tile()
 
{
 
	print("");
 
	print("--Tile--");
 
	print("  HasTreeOnTile():      " + AITile.HasTreeOnTile(33148));
 
	print("  IsFarmTile():         " + AITile.IsFarmTile(32892));
 
	print("  IsRockTile():         " + AITile.IsRockTile(31606));
 
	print("  IsRoughTile():        " + AITile.IsRoughTile(33674));
 
	print("  HasTreeOnTile():      " + AITile.HasTreeOnTile(33404));
 
	print("  IsFarmTile():         " + AITile.IsFarmTile(33404));
 
	print("  IsRockTile():         " + AITile.IsRockTile(33404));
 
	print("  IsRoughTile():        " + AITile.IsRoughTile(33404));
 
	print("  IsSnowTile():         " + AITile.IsSnowTile(33404));
 
	print("  IsDesertTile():       " + AITile.IsDesertTile(33404));
 
	print("  PlantTree():          " + AITile.PlantTree(33404));
 
	print("  HasTreeOnTile():      " + AITile.HasTreeOnTile(33404));
 
	print("  PlantTree():          " + AITile.PlantTree(33404));
 
	print("  HasTreeOnTile():      " + AITile.HasTreeOnTile(33661));
 
	print("  PlantTreeRectangle(): " + AITile.PlantTreeRectangle(33404, 2, 2));
 
	print("  HasTreeOnTile():      " + AITile.HasTreeOnTile(33661));
 
}
 

	
 
function Regression::TileList()
 
{
 
	local list = AITileList();
 

	
 
	print("");
 
	print("--TileList--");
 
	print("  Count():             " + list.Count());
 
	list.AddRectangle(27631 - 256 * 1, 256 * 1 + 27631 + 2);
 
	print("  Count():             " + list.Count());
 

	
 
	list.Valuate(AITile.GetSlope);
 
	print("  Slope():             done");
 
	print("  Count():             " + list.Count());
 
	print("  ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
		print("    " + i + " => " + AITile.GetComplementSlope(list.GetValue(i)));
 
		print("    " + i + " => " + AITile.IsSteepSlope(list.GetValue(i)));
 
		print("    " + i + " => " + AITile.IsHalftileSlope(list.GetValue(i)));
 
	}
 
	list.Clear();
 

	
 
	print("");
 
	print("--TileList--");
 
	print("  Count():             " + list.Count());
 
	list.AddRectangle(41895 - 256 * 2, 256 * 2 + 41895 + 8);
 
	print("  Count():             " + list.Count());
 

	
 
	list.Valuate(AITile.GetHeight);
 
	print("  Height():            done");
 
	print("  Count():             " + list.Count());
 
	print("  ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 

	
 
	list.Valuate(AITile.GetSlope);
 
	list.KeepValue(0);
 
	print("  Slope():             done");
 
	print("  KeepValue(0):        done");
 
	print("  Count():             " + list.Count());
 
	print("  ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 

	
 
	list.Valuate(AITile.IsBuildable);
 
	list.KeepValue(1);
 
	print("  Buildable():         done");
 
	print("  KeepValue(1):        done");
 
	print("  Count():             " + list.Count());
 

	
 
	list.Valuate(AITile.IsBuildableRectangle, 3, 3);
 
	print("  BuildableRectangle(3, 3) ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AITile.GetDistanceManhattanToTile, 30000);
 
	print("  DistanceManhattanToTile(30000) ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AITile.GetDistanceSquareToTile, 30000);
 
	print("  DistanceSquareToTile(30000) ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AITile.GetOwner);
 
	print("  GetOwner() ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AITile.GetClosestTown);
 
	print("  GetClosestTown() ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 

	
 
	list.Valuate(AITile.GetCargoAcceptance, 0, 1, 1, 3);
 
	list.KeepAboveValue(10);
 
	print("  CargoAcceptance():   done");
 
	print("  KeepAboveValue(10):  done");
 
	print("  Count():             " + list.Count());
 
	print("  ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 

	
 
	list.Valuate(AIRoad.IsRoadTile);
 
	list.KeepValue(1);
 
	print("  RoadTile():          done");
 
	print("  KeepValue(1):        done");
 
	print("  Count():             " + list.Count());
 
	print("  ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 

	
 
	list.Valuate(AIRoad.GetNeighbourRoadCount);
 
	list.KeepValue(1);
 
	print("  NeighbourRoadCount():done");
 
	print("  KeepValue(1):        done");
 
	print("  Count():             " + list.Count());
 
	print("  ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 

	
 
	list.AddRectangle(54421 - 256 * 2, 256 * 2 + 54421 + 8);
 
	list.Valuate(AITile.IsWaterTile);
 
	print("  Water():             done");
 
	print("  Count():             " + list.Count());
 
	print("  ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 

	
 
	list = AITileList_IndustryAccepting(0, 3);
 
	print("");
 
	print("--TileList_IndustryAccepting--");
 
	print("  Count():             " + list.Count());
 
	list.Valuate(AITile.GetCargoAcceptance, 3, 1, 1, 3);
 
	print("  Location ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 

	
 
	list = AITileList_IndustryProducing(1, 3);
 
	print("");
 
	print("--TileList_IndustryProducing--");
 
	print("  Count():             " + list.Count());
 
	list.Valuate(AITile.GetCargoProduction, 7, 1, 1, 3);
 
	print("  Location ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 

	
 
	list = AITileList_StationType(4, AIStation.STATION_BUS_STOP);
 
	print("");
 
	print("--TileList_StationType--");
 
	print("  Count():             " + list.Count());
 
	print("  Location ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
}
 

	
 
function Regression::Town()
 
{
 
	local j = 0;
 

	
 
	print("");
 
	print("--Town--");
 
	print("  GetMaxTownID():    " + AITown.GetMaxTownID());
 
	print("  GetTownCount():    " + AITown.GetTownCount());
 
	for (local i = -1; i < AITown.GetMaxTownID() + 1; i++) {
 
		if (AITown.IsValidTown(i)) j++;
 
		print("  Town " + i);
 
		print("    IsValidTown():   " + AITown.IsValidTown(i));
 
		print("    GetName():       " + AITown.GetName(i));
 
		print("    GetPopulation(): " + AITown.GetPopulation(i));
 
		print("    GetLocation():   " + AITown.GetLocation(i));
 
		print("    GetHouseCount(): " + AITown.GetHouseCount(i));
 
		print("    GetRating():     " + AITown.GetRating(i, AICompany.MY_COMPANY));
 
	}
 
	print("  Valid Towns:       " + j);
 
	print("  GetTownCount():    " + AITown.GetTownCount());
 
}
 

	
 
function Regression::TownList()
 
{
 
	local list = AITownList();
 

	
 
	print("");
 
	print("--TownList--");
 
	print("  Count():             " + list.Count());
 
	list.Valuate(AITown.GetLocation);
 
	print("  Location ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AITown.GetDistanceManhattanToTile, 30000);
 
	print("  DistanceManhattanToTile(30000) ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AITown.GetDistanceSquareToTile, 30000);
 
	print("  DistanceSquareToTile(30000) ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AITown.IsWithinTownInfluence, AITown.GetLocation(0));
 
	print("  IsWithinTownInfluence(" + AITown.GetLocation(0) + ") ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AITown.GetAllowedNoise);
 
	print("  GetAllowedNoise() ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AITown.GetPopulation);
 
	list.KeepAboveValue(500);
 
	print("  KeepAboveValue(500): done");
 
	print("  Count():             " + list.Count());
 
	print("  Population ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 

	
 
	print("  HasStatue():                     " + AITown.HasStatue(list.Begin()));
 
	print("  GetRoadReworkDuration():         " + AITown.GetRoadReworkDuration(list.Begin()));
 
	print("  GetExclusiveRightsCompany():     " + AITown.GetExclusiveRightsCompany(list.Begin()));
 
	print("  GetExclusiveRightsDuration():    " + AITown.GetExclusiveRightsDuration(list.Begin()));
 
	print("  IsActionAvailable(BUILD_STATUE): " + AITown.IsActionAvailable(list.Begin(), AITown.TOWN_ACTION_BUILD_STATUE));
 
	print("  PerformTownAction(BUILD_STATUE): " + AITown.PerformTownAction(list.Begin(), AITown.TOWN_ACTION_BUILD_STATUE));
 
	print("  IsActionAvailable(BUILD_STATUE): " + AITown.IsActionAvailable(list.Begin(), AITown.TOWN_ACTION_BUILD_STATUE));
 
	print("  HasStatue():                     " + AITown.HasStatue(list.Begin()));
 
}
 

	
 
function Regression::Tunnel()
 
{
 
	print("");
 
	print("--Tunnel--");
 
	print("  IsTunnelTile():       " + AITunnel.IsTunnelTile(29050));
 
	print("  RemoveTunnel():       " + AITunnel.RemoveTunnel(29050));
 
	print("  GetOtherTunnelEnd():  " + AITunnel.GetOtherTunnelEnd(29050));
 
	print("  BuildTunnel():        " + AITunnel.BuildTunnel(AIVehicle.VEHICLE_ROAD, 29050));
 
	print("  GetOtherTunnelEnd():  " + AITunnel.GetOtherTunnelEnd(29050));
 
	print("  IsTunnelTile():       " + AITunnel.IsTunnelTile(29050));
 
	print("  IsTunnelTile():       " + AITunnel.IsTunnelTile(28026));
 
	print("  RemoveTunnel():       " + AITunnel.RemoveTunnel(29050));
 
	print("  IsTunnelTile():       " + AITunnel.IsTunnelTile(29050));
 

	
 
	print("  --Errors--");
 
	print("  BuildTunnel():        " + AITunnel.BuildTunnel(AIVehicle.VEHICLE_ROAD, 7529));
 
	print("  BuildTunnel():        " + AITunnel.BuildTunnel(AIVehicle.VEHICLE_ROAD, 8043));
 
	print("  GetLastErrorString(): " + AIError.GetLastErrorString());
 
	print("  RemoveTunnel():       " + AITunnel.RemoveTunnel(7529));
 
}
 

	
 
function Regression::Vehicle()
 
{
 
	local accounting = AIAccounting();
 

	
 
	print("");
 
	print("--Vehicle--");
 
	print("  IsValidVehicle(-1):   " + AIVehicle.IsValidVehicle(-1));
 
	print("  IsValidVehicle(0):    " + AIVehicle.IsValidVehicle(0));
 
	print("  IsValidVehicle(12):   " + AIVehicle.IsValidVehicle(12));
 
	print("  ISValidVehicle(9999): " + AIVehicle.IsValidVehicle(9999));
 

	
 
	local bank = AICompany.GetBankBalance(AICompany.MY_COMPANY);
 

	
 
	print("  BuildVehicle():       " + AIVehicle.BuildVehicle(33417, 153));
 
	print("  IsValidVehicle(12):   " + AIVehicle.IsValidVehicle(12));
 
	print("  CloneVehicle():       " + AIVehicle.CloneVehicle(33417, 12, true));
 

	
 
	local bank_after = AICompany.GetBankBalance(AICompany.MY_COMPANY);
 

	
 
	print("  --Accounting--");
 
	print("    GetCosts():         " + accounting.GetCosts());
 
	print("    Should be:          " + (bank - bank_after));
 
	print("    ResetCosts():       " + accounting.ResetCosts());
 

	
 
	bank = AICompany.GetBankBalance(AICompany.MY_COMPANY);
 

	
 
	print("  SellVehicle(13):      " + AIVehicle.SellVehicle(13));
 
	print("  IsInDepot():          " + AIVehicle.IsInDepot(12));
 
	print("  IsStoppedInDepot():   " + AIVehicle.IsStoppedInDepot(12));
 
	print("  StartStopVehicle():   " + AIVehicle.StartStopVehicle(12));
 
	print("  IsInDepot():          " + AIVehicle.IsInDepot(12));
 
	print("  IsStoppedInDepot():   " + AIVehicle.IsStoppedInDepot(12));
 
	print("  SendVehicleToDepot(): " + AIVehicle.SendVehicleToDepot(12));
 
	print("  IsInDepot():          " + AIVehicle.IsInDepot(12));
 
	print("  IsStoppedInDepot():   " + AIVehicle.IsStoppedInDepot(12));
 

	
 
	bank_after = AICompany.GetBankBalance(AICompany.MY_COMPANY);
 

	
 
	print("  --Accounting--");
 
	print("    GetCosts():         " + accounting.GetCosts());
 
	print("    Should be:          " + (bank - bank_after));
 

	
 
	print("  GetName():            " + AIVehicle.GetName(12));
 
	print("  SetName():            " + AIVehicle.SetName(12, "MyVehicleName"));
 
	print("  GetName():            " + AIVehicle.GetName(12));
 
	print("  CloneVehicle():       " + AIVehicle.CloneVehicle(33417, 12, true));
 

	
 
	print("  --VehicleData--");
 
	print("    GetLocation():       " + AIVehicle.GetLocation(12));
 
	print("    GetEngineType():     " + AIVehicle.GetEngineType(12));
 
	print("    GetUnitNumber():     " + AIVehicle.GetUnitNumber(12));
 
	print("    GetAge():            " + AIVehicle.GetAge(12));
 
	print("    GetMaxAge():         " + AIVehicle.GetMaxAge(12));
 
	print("    GetAgeLeft():        " + AIVehicle.GetAgeLeft(12));
 
	print("    GetCurrentSpeed():   " + AIVehicle.GetCurrentSpeed(12));
 
	print("    GetRunningCost():    " + AIVehicle.GetRunningCost(12));
 
	print("    GetProfitThisYear(): " + AIVehicle.GetProfitThisYear(12));
 
	print("    GetProfitLastYear(): " + AIVehicle.GetProfitLastYear(12));
 
	print("    GetCurrentValue():   " + AIVehicle.GetCurrentValue(12));
 
	print("    GetVehicleType():    " + AIVehicle.GetVehicleType(12));
 
	print("    GetRoadType():       " + AIVehicle.GetRoadType(12));
 
	print("    GetCapacity():       " + AIVehicle.GetCapacity(12, 10));
 
	print("    GetCargoLoad():      " + AIVehicle.GetCargoLoad(12, 10));
 
	print("    IsInDepot():         " + AIVehicle.IsInDepot(12));
 
	print("    GetNumWagons():      " + AIVehicle.GetNumWagons(12));
 
	print("    GetWagonEngineType(): " + AIVehicle.GetWagonEngineType(12, 0));
 
	print("    GetWagonAge():       " + AIVehicle.GetWagonAge(12, 0));
 
	print("    GetLength():         " + AIVehicle.GetLength(12));
 

	
 
	print("  GetOwner():           " + AITile.GetOwner(32119));
 
	print("  BuildVehicle():       " + AIVehicle.BuildVehicle(32119, 219));
 
	print("  IsValidVehicle(14):   " + AIVehicle.IsValidVehicle(14));
 
	print("  IsInDepot(14):        " + AIVehicle.IsInDepot(14));
 
	print("  IsStoppedInDepot(14): " + AIVehicle.IsStoppedInDepot(14));
 
	print("  IsValidVehicle(15):   " + AIVehicle.IsValidVehicle(15));
 
	print("  IsInDepot(15):        " + AIVehicle.IsInDepot(15));
 
	print("  IsStoppedInDepot(15): " + AIVehicle.IsStoppedInDepot(15));
 

	
 
	print("  BuildVehicle():       " + AIVehicle.BuildVehicle(28479, 204));
 
	print("  IsValidVehicle(16):   " + AIVehicle.IsValidVehicle(16));
 
	print("  IsInDepot(16):        " + AIVehicle.IsInDepot(16));
 
	print("  IsStoppedInDepot(16): " + AIVehicle.IsStoppedInDepot(16));
 

	
 
	print("  BuildRailDepot():     " + AIRail.BuildRailDepot(10008, 10000));
 
	print("  BuildVehicle():       " + AIVehicle.BuildVehicle(10008, 9));
 
	print("  BuildVehicle():       " + AIVehicle.BuildVehicle(10008, 27));
 
	print("  BuildVehicle():       " + AIVehicle.BuildVehicle(10008, 27));
 
	print("  MoveWagon():          " + AIVehicle.MoveWagon(18, 0, true, 17, 0));
 
	print("  GetNumWagons():       " + AIVehicle.GetNumWagons(17));
 
	print("  GetLength():          " + AIVehicle.GetLength(17));
 
	print("  GetWagonEngineType(): " + AIVehicle.GetWagonEngineType(17, 0));
 
	print("  GetWagonAge():        " + AIVehicle.GetWagonAge(17, 0));
 
	print("  GetWagonEngineType(): " + AIVehicle.GetWagonEngineType(17, 1));
 
	print("  GetWagonAge():        " + AIVehicle.GetWagonAge(17, 1));
 
	print("  GetWagonEngineType(): " + AIVehicle.GetWagonEngineType(17 2));
 
	print("  GetWagonAge():        " + AIVehicle.GetWagonAge(17, 2));
 
	print("  GetWagonEngineType(): " + AIVehicle.GetWagonEngineType(17 3));
 
	print("  GetWagonAge():        " + AIVehicle.GetWagonAge(17, 3));
 

	
 
	print("  --Errors--");
 
	print("    RefitVehicle():        " + AIVehicle.RefitVehicle(12, 0));
 
	print("    GetLastErrorString():  " + AIError.GetLastErrorString());
 
	print("    SellVehicle():         " + AIVehicle.SellVehicle(12));
 
	print("    GetLastErrorString():  " + AIError.GetLastErrorString());
 
	print("    SendVehicleToDepot():  " + AIVehicle.SendVehicleToDepot(13));
 
	print("    GetLastErrorString():  " + AIError.GetLastErrorString());
 

	
 
	local list = AIVehicleList();
 

	
 
	print("");
 
	print("--VehicleList--");
 
	print("  Count():             " + list.Count());
 
	list.Valuate(AIVehicle.GetLocation);
 
	print("  Location ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AIVehicle.GetEngineType);
 
	print("  EngineType ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AIVehicle.GetUnitNumber);
 
	print("  UnitNumber ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AIVehicle.GetAge);
 
	print("  Age ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AIVehicle.GetMaxAge);
 
	print("  MaxAge ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AIVehicle.GetAgeLeft);
 
	print("  AgeLeft ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AIVehicle.GetCurrentSpeed);
 
	print("  CurrentSpeed ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AIVehicle.GetRunningCost);
 
	print("  RunningCost ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AIVehicle.GetProfitThisYear);
 
	print("  ProfitThisYear ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AIVehicle.GetProfitLastYear);
 
	print("  ProfitLastYear ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AIVehicle.GetCurrentValue);
 
	print("  CurrentValue ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AIVehicle.GetVehicleType);
 
	print("  VehicleType ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AIVehicle.GetRoadType);
 
	print("  RoadType ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AIVehicle.GetCapacity, 10);
 
	print("  VehicleType ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
	list.Valuate(AIVehicle.GetCargoLoad, 10);
 
	print("  VehicleType ListDump:");
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		print("    " + i + " => " + list.GetValue(i));
 
	}
 
}
 

	
 
function Regression::PrintSubsidy(subsidy_id)
 
{
 
	print("      --Subsidy (" + subsidy_id + ") --");
 
	print("        IsValidSubsidy():     " + AISubsidy.IsValidSubsidy(subsidy_id));
 
	print("        IsAwarded():          " + AISubsidy.IsAwarded(subsidy_id));
 
	print("        GetAwardedTo():       " + AISubsidy.GetAwardedTo(subsidy_id));
 
	print("        GetExpireDate():      " + AISubsidy.GetExpireDate(subsidy_id));
 
	print("        SourceIsTown():       " + AISubsidy.SourceIsTown(subsidy_id));
 
	print("        GetSource():          " + AISubsidy.GetSource(subsidy_id));
 
	print("        DestionationIsTown(): " + AISubsidy.DestinationIsTown(subsidy_id));
 
	print("        GetDestionation():    " + AISubsidy.GetDestination(subsidy_id));
 
	print("        GetCargoType():       " + AISubsidy.GetCargoType(subsidy_id));
 
}
 

	
 

	
 
function Regression::Start()
 
{
 
	this.TestInit();
 
	this.Std();
 
	this.Base();
 
	this.List();
 
	this.Airport();
 
	this.Bridge();
 
	this.BridgeList();
 
	this.Cargo();
 
	this.CargoList();
 
	this.Company();
 
	this.Engine();
 
	this.EngineList();
 
	this.Graph();
 
	this.Group();
 
	this.Industry();
 
	this.IndustryList();
 
	this.IndustryTypeList();
 
	this.Map();
 
	this.Marine();
 
	this.Pathfinder();
 
	this.Queues();
 
	this.Rail();
 
	this.RailTypeList();
 
	this.Road();
 
	this.Sign();
 
	this.Station();
 
	this.Tile();
 
	this.TileList();
 
	this.Town();
 
	this.TownList();
 
	this.Tunnel();
 
	this.Vehicle();
 
	/* Order has to be after Vehicle */
 
	this.Order();
 
	print("");
 
	print("  First Subsidy Test");
 
	PrintSubsidy(0);
 

	
 
	while (AIEventController.IsEventWaiting()) {
 
		local e = AIEventController.GetNextEvent();
 
		print("  GetNextEvent:          " + (e == null ? "null" : "instance"));
 
		print("    GetEventType:        " + e.GetEventType());
 
		switch (e.GetEventType()) {
 
			case AIEvent.AI_ET_SUBSIDY_OFFER: {
 
				local c = AIEventSubsidyOffer.Convert(e);
 
				print("      EventName:         SubsidyOffer");
 
				PrintSubsidy(c.GetSubsidyID());
 
			} break;
 

	
 
			case AIEvent.AI_ET_VEHICLE_WAITING_IN_DEPOT: {
 
				local c = AIEventVehicleWaitingInDepot.Convert(e);
 
				print("      EventName:         VehicleWaitingInDepot");
 
				print("      VehicleID:         " + c.GetVehicleID());
 
			} break;
 

	
 
			default:
 
				print("      Unknown Event");
 
				break;
 
		}
 
	}
 
	print("  IsEventWaiting:        false");
 
}
 

	
bin/ai/regression/regression.sav
Show inline comments
 
new file 100644
 
binary diff not shown
bin/ai/regression/regression.txt
Show inline comments
 
new file 100644
 

	
 
--TestInit--
 
 TickTest: 1
 
 TickTest: 2
 
 SetCommandDelay: (null : 0x00000000)
 
 IsValid(vehicle.plane_speed): true
 
 vehicle.plane_speed: 2
 
  Required this file
 
 min(6, 3): 3
 
 min(3, 6): 3
 
 max(6, 3): 6
 
 max(3, 6): 6
 
 AIList Consistency Tests
 

	
 
 Value Descending
 
   40
 
   25
 
   10
 

	
 
   40
 
   30
 
   20
 
   10
 
   40
 
   30
 
   20
 
   10
 

	
 
   40
 
   30
 
   20
 
   10
 

	
 
 Value Ascending
 
   5
 
   20
 
   35
 

	
 
   10
 
   20
 
   30
 
   40
 
   10
 
   20
 
   30
 
   40
 

	
 
   10
 
   20
 
   30
 
   40
 

	
 
 Item Descending
 
   40
 
   25
 
   10
 

	
 
   40
 
   30
 
   20
 
   10
 

	
 
   40
 
   30
 
   20
 
   10
 

	
 
 Item Ascending
 
   5
 
   20
 
   35
 

	
 
   10
 
   20
 
   30
 
   40
 

	
 
   10
 
   20
 
   30
 
   40
 

	
 
--Std--
 
 abs(-21): 21
 
 abs( 21): 21
 

	
 
--AIBase--
 
  Rand():       -394267821
 
  Rand():       -1103663825
 
  Rand():       158728217
 
  RandRange(0): 0
 
  RandRange(0): 0
 
  RandRange(0): 0
 
  RandRange(1): 0
 
  RandRange(1): 0
 
  RandRange(1): 0
 
  RandRange(2): 1
 
  RandRange(2): 0
 
  RandRange(2): 1
 
  RandRange(9): 6
 
  RandRange(9): 0
 
  RandRange(9): 5
 
  Chance(1, 2): true
 
  Chance(1, 2): true
 
  Chance(1, 2): false
 

	
 
--List--
 
  IsEmpty():     true
 
  Count():       101
 
  HasItem(1050): false
 
  HasItem(1051): true
 
  IsEmpty():     false
 
  List Dump:
 
    1 => 1
 
    2 => 2
 
    1000 => 1000
 
    1001 => 1001
 
    1002 => 1002
 
    1003 => 1003
 
    1004 => 1004
 
    1005 => 1005
 
    1006 => 1006
 
    1007 => 1007
 
    1008 => 1008
 
    1009 => 1009
 
    1010 => 1010
 
    1011 => 1011
 
    1012 => 1012
 
    1013 => 1013
 
    1014 => 1014
 
    1015 => 1015
 
    1016 => 1016
 
    1017 => 1017
 
    1018 => 1018
 
    1019 => 1019
 
    1020 => 1020
 
    1021 => 1021
 
    1022 => 1022
 
    1023 => 1023
 
    1024 => 1024
 
    1025 => 1025
 
    1026 => 1026
 
    1027 => 1027
 
    1028 => 1028
 
    1029 => 1029
 
    1030 => 1030
 
    1031 => 1031
 
    1032 => 1032
 
    1033 => 1033
 
    1034 => 1034
 
    1035 => 1035
 
    1036 => 1036
 
    1037 => 1037
 
    1038 => 1038
 
    1039 => 1039
 
    1040 => 1040
 
    1041 => 1041
 
    1042 => 1042
 
    1043 => 1043
 
    1044 => 1044
 
    1045 => 1045
 
    1046 => 1046
 
    1047 => 1047
 
    1048 => 1048
 
    1049 => 1049
 
    1051 => 12
 
    1052 => 1052
 
    1053 => 1053
 
    1054 => 1054
 
    1055 => 1055
 
    1056 => 1056
 
    1057 => 1057
 
    1058 => 1058
 
    1059 => 1059
 
    1060 => 1060
 
    1061 => 1061
 
    1062 => 1062
 
    1063 => 1063
 
    1064 => 1064
 
    1065 => 1065
 
    1066 => 1066
 
    1067 => 1067
 
    1068 => 1068
 
    1069 => 1069
 
    1070 => 1070
 
    1071 => 1071
 
    1072 => 1072
 
    1073 => 1073
 
    1074 => 1074
 
    1075 => 1075
 
    1076 => 1076
 
    1077 => 1077
 
    1078 => 1078
 
    1079 => 1079
 
    1080 => 1080
 
    1081 => 1081
 
    1082 => 1082
 
    1083 => 1083
 
    1084 => 1084
 
    1085 => 1085
 
    1086 => 1086
 
    1087 => 1087
 
    1088 => 1088
 
    1089 => 1089
 
    1090 => 1090
 
    1091 => 1091
 
    1092 => 1092
 
    1093 => 1093
 
    1094 => 1094
 
    1095 => 1095
 
    1096 => 1096
 
    1097 => 1097
 
    1098 => 1098
 
    1099 => 1099
 
  Custom ListDump:
 
    1 => 4343
 
    2 => 8686
 
    1000 => 4343000
 
    1001 => 4347343
 
    1002 => 4351686
 
    1003 => 4356029
 
    1004 => 4360372
 
    1005 => 4364715
 
    1006 => 4369058
 
    1007 => 4373401
 
    1008 => 4377744
 
    1009 => 4382087
 
    1010 => 4386430
 
    1011 => 4390773
 
    1012 => 4395116
 
    1013 => 4399459
 
    1014 => 4403802
 
    1015 => 4408145
 
    1016 => 4412488
 
    1017 => 4416831
 
    1018 => 4421174
 
    1019 => 4425517
 
    1020 => 4429860
 
    1021 => 4434203
 
    1022 => 4438546
 
    1023 => 4442889
 
    1024 => 4447232
 
    1025 => 4451575
 
    1026 => 4455918
 
    1027 => 4460261
 
    1028 => 4464604
 
    1029 => 4468947
 
    1030 => 4473290
 
    1031 => 4477633
 
    1032 => 4481976
 
    1033 => 4486319
 
    1034 => 4490662
 
    1035 => 4495005
 
    1036 => 4499348
 
    1037 => 4503691
 
    1038 => 4508034
 
    1039 => 4512377
 
    1040 => 4516720
 
    1041 => 4521063
 
    1042 => 4525406
 
    1043 => 4529749
 
    1044 => 4534092
 
    1045 => 4538435
 
    1046 => 4542778
 
    1047 => 4547121
 
    1048 => 4551464
 
    1049 => 4555807
 
    1051 => 4564493
 
    1052 => 4568836
 
    1053 => 4573179
 
    1054 => 4577522
 
    1055 => 4581865
 
    1056 => 4586208
 
    1057 => 4590551
 
    1058 => 4594894
 
    1059 => 4599237
 
    1060 => 4603580
 
    1061 => 4607923
 
    1062 => 4612266
 
    1063 => 4616609
 
    1064 => 4620952
 
    1065 => 4625295
 
    1066 => 4629638
 
    1067 => 4633981
 
    1068 => 4638324
 
    1069 => 4642667
 
    1070 => 4647010
 
    1071 => 4651353
 
    1072 => 4655696
 
    1073 => 4660039
 
    1074 => 4664382
 
    1075 => 4668725
 
    1076 => 4673068
 
    1077 => 4677411
 
    1078 => 4681754
 
    1079 => 4686097
 
    1080 => 4690440
 
    1081 => 4694783
 
    1082 => 4699126
 
    1083 => 4703469
 
    1084 => 4707812
 
    1085 => 4712155
 
    1086 => 4716498
 
    1087 => 4720841
 
    1088 => 4725184
 
    1089 => 4729527
 
    1090 => 4733870
 
    1091 => 4738213
 
    1092 => 4742556
 
    1093 => 4746899
 
    1094 => 4751242
 
    1095 => 4755585
 
    1096 => 4759928
 
    1097 => 4764271
 
    1098 => 4768614
 
    1099 => 4772957
 
  Custom ListDump:
 
    1 => 42
 
    2 => 84
 
    1000 => 42000
 
    1001 => 42042
 
    1002 => 42084
 
    1003 => 42126
 
    1004 => 42168
 
    1005 => 42210
 
    1006 => 42252
 
    1007 => 42294
 
    1008 => 42336
 
    1009 => 42378
 
    1010 => 42420
 
    1011 => 42462
 
    1012 => 42504
 
    1013 => 42546
 
    1014 => 42588
 
    1015 => 42630
 
    1016 => 42672
 
    1017 => 42714
 
    1018 => 42756
 
    1019 => 42798
 
    1020 => 42840
 
    1021 => 42882
 
    1022 => 42924
 
    1023 => 42966
 
    1024 => 43008
 
    1025 => 43050
 
    1026 => 43092
 
    1027 => 43134
 
    1028 => 43176
 
    1029 => 43218
 
    1030 => 43260
 
    1031 => 43302
 
    1032 => 43344
 
    1033 => 43386
 
    1034 => 43428
 
    1035 => 43470
 
    1036 => 43512
 
    1037 => 43554
 
    1038 => 43596
 
    1039 => 43638
 
    1040 => 43680
 
    1041 => 43722
 
    1042 => 43764
 
    1043 => 43806
 
    1044 => 43848
 
    1045 => 43890
 
    1046 => 43932
 
    1047 => 43974
 
    1048 => 44016
 
    1049 => 44058
 
    1051 => 44142
 
    1052 => 44184
 
    1053 => 44226
 
    1054 => 44268
 
    1055 => 44310
 
    1056 => 44352
 
    1057 => 44394
 
    1058 => 44436
 
    1059 => 44478
 
    1060 => 44520
 
    1061 => 44562
 
    1062 => 44604
 
    1063 => 44646
 
    1064 => 44688
 
    1065 => 44730
 
    1066 => 44772
 
    1067 => 44814
 
    1068 => 44856
 
    1069 => 44898
 
    1070 => 44940
 
    1071 => 44982
 
    1072 => 45024
 
    1073 => 45066
 
    1074 => 45108
 
    1075 => 45150
 
    1076 => 45192
 
    1077 => 45234
 
    1078 => 45276
 
    1079 => 45318
 
    1080 => 45360
 
    1081 => 45402
 
    1082 => 45444
 
    1083 => 45486
 
    1084 => 45528
 
    1085 => 45570
 
    1086 => 45612
 
    1087 => 45654
 
    1088 => 45696
 
    1089 => 45738
 
    1090 => 45780
 
    1091 => 45822
 
    1092 => 45864
 
    1093 => 45906
 
    1094 => 45948
 
    1095 => 45990
 
    1096 => 46032
 
    1097 => 46074
 
    1098 => 46116
 
    1099 => 46158
 
  Randomize ListDump:
 
    1 => -453900829
 
    2 => -1311244773
 
    1000 => -1189761104
 
    1001 => -767645542
 
    1002 => 1177121049
 
    1003 => 530150361
 
    1004 => -114394334
 
    1005 => 1655826028
 
    1006 => -634606345
 
    1007 => -16200093
 
    1008 => -1589979998
 
    1009 => -931781688
 
    1010 => -1612519575
 
    1011 => 232355847
 
    1012 => 1937567155
 
    1013 => 293923071
 
    1014 => 77413166
 
    1015 => -996268195
 
    1016 => 954454457
 
    1017 => -2120647595
 
    1018 => -1826344393
 
    1019 => 1036590466
 
    1020 => 1340694939
 
    1021 => 1328898286
 
    1022 => 1212995644
 
    1023 => 212080778
 
    1024 => -1116031315
 
    1025 => 2059557569
 
    1026 => -1351733639
 
    1027 => -16225284
 
    1028 => 12042907
 
    1029 => -2118970966
 
    1030 => -625495409
 
    1031 => -803433375
 
    1032 => 206484827
 
    1033 => -1275117685
 
    1034 => -1660494268
 
    1035 => 439308575
 
    1036 => 689118657
 
    1037 => 18162819
 
    1038 => 279178838
 
    1039 => -811026766
 
    1040 => -102146912
 
    1041 => 761316313
 
    1042 => -446973157
 
    1043 => 1860931649
 
    1044 => -936809412
 
    1045 => 2009637934
 
    1046 => 146746237
 
    1047 => -1122456903
 
    1048 => 496979353
 
    1049 => 1330321624
 
    1051 => 1221526431
 
    1052 => 312894323
 
    1053 => -1967316408
 
    1054 => -306362667
 
    1055 => 463694131
 
    1056 => 1180912503
 
    1057 => 962965831
 
    1058 => -1686452466
 
    1059 => 1770363784
 
    1060 => -974655700
 
    1061 => 1137105824
 
    1062 => -1195585394
 
    1063 => 814828850
 
    1064 => -319033517
 
    1065 => -1069246310
 
    1066 => 730090633
 
    1067 => -453449540
 
    1068 => -1568189245
 
    1069 => 1938098163
 
    1070 => 582038708
 
    1071 => -1513512696
 
    1072 => 2023080545
 
    1073 => 1451475423
 
    1074 => 2115922500
 
    1075 => 1714395178
 
    1076 => -1794465095
 
    1077 => 711436717
 
    1078 => 2080995690
 
    1079 => 1888980586
 
    1080 => 1441996214
 
    1081 => 2068563628
 
    1082 => 1839052927
 
    1083 => -1569187741
 
    1084 => 1117258463
 
    1085 => -373025294
 
    1086 => 836256008
 
    1087 => 894909721
 
    1088 => 320878623
 
    1089 => -324398855
 
    1090 => -2069211627
 
    1091 => 1181351335
 
    1092 => 1628415271
 
    1093 => 1998896274
 
    1094 => 1296141199
 
    1095 => 144363466
 
    1096 => -2068665023
 
    1097 => 301553896
 
    1098 => -509674842
 
    1099 => -1486885398
 
  KeepTop(10):
 
    1 => -453900829
 
    2 => -1311244773
 
    1000 => -1189761104
 
    1001 => -767645542
 
    1002 => 1177121049
 
    1003 => 530150361
 
    1004 => -114394334
 
    1005 => 1655826028
 
    1006 => -634606345
 
    1007 => -16200093
 
  KeepBottom(8):
 
    1000 => -1189761104
 
    1001 => -767645542
 
    1002 => 1177121049
 
    1003 => 530150361
 
    1004 => -114394334
 
    1005 => 1655826028
 
    1006 => -634606345
 
    1007 => -16200093
 
  RemoveBottom(2):
 
    1000 => -1189761104
 
    1001 => -767645542
 
    1002 => 1177121049
 
    1003 => 530150361
 
    1004 => -114394334
 
    1005 => 1655826028
 
  RemoveTop(2):
 
    1002 => 1177121049
 
    1003 => 530150361
 
    1004 => -114394334
 
    1005 => 1655826028
 
  RemoveList({1003, 1004}):
 
    1002 => 1177121049
 
    1005 => 1655826028
 
  KeepList({1003, 1004, 1005}):
 
    1005 => 1655826028
 
  AddList({1005, 4000, 4001, 4002}):
 
    1005 => 1005
 
    4000 => 8000
 
    4001 => 8002
 
    4002 => 8004
 
  foreach():
 
    1005 => 1005
 
    4000 => 50
 
    4001 => 8002
 
    4002 => 8004
 
    4006 => 12
 
  []:
 
    4000 => 50
 
  IsEmpty():     true
 

	
 
--AIAirport--
 
  IsHangarTile():       false
 
  IsAirportTile():      false
 
  GetHangarOfAirport(): -1
 
  GetAirportType():     255
 
  IsValidAirportType(-1):       false
 
  AirportAvailable(-1):         false
 
  GetAirportWidth(-1):          -1
 
  GetAirportHeight(-1):         -1
 
  GetAirportCoverageRadius(-1): -1
 
  IsValidAirportType(0):       true
 
  AirportAvailable(0):         true
 
  GetAirportWidth(0):          4
 
  GetAirportHeight(0):         3
 
  GetAirportCoverageRadius(0): 4
 
  IsValidAirportType(1):       true
 
  AirportAvailable(1):         false
 
  GetAirportWidth(1):          6
 
  GetAirportHeight(1):         6
 
  GetAirportCoverageRadius(1): 5
 
  IsValidAirportType(2):       true
 
  AirportAvailable(2):         false
 
  GetAirportWidth(2):          1
 
  GetAirportHeight(2):         1
 
  GetAirportCoverageRadius(2): 4
 
  IsValidAirportType(3):       true
 
  AirportAvailable(3):         false
 
  GetAirportWidth(3):          6
 
  GetAirportHeight(3):         6
 
  GetAirportCoverageRadius(3): 6
 
  IsValidAirportType(4):       true
 
  AirportAvailable(4):         false
 
  GetAirportWidth(4):          7
 
  GetAirportHeight(4):         7
 
  GetAirportCoverageRadius(4): 8
 
  IsValidAirportType(5):       true
 
  AirportAvailable(5):         false
 
  GetAirportWidth(5):          5
 
  GetAirportHeight(5):         4
 
  GetAirportCoverageRadius(5): 4
 
  IsValidAirportType(6):       true
 
  AirportAvailable(6):         false
 
  GetAirportWidth(6):          2
 
  GetAirportHeight(6):         2
 
  GetAirportCoverageRadius(6): 4
 
  IsValidAirportType(7):       true
 
  AirportAvailable(7):         false
 
  GetAirportWidth(7):          9
 
  GetAirportHeight(7):         11
 
  GetAirportCoverageRadius(7): 10
 
  IsValidAirportType(8):       true
 
  AirportAvailable(8):         false
 
  GetAirportWidth(8):          4
 
  GetAirportHeight(8):         2
 
  GetAirportCoverageRadius(8): 4
 
  IsValidAirportType(9):       false
 
  AirportAvailable(9):         false
 
  GetAirportWidth(9):          -1
 
  GetAirportHeight(9):         -1
 
  GetAirportCoverageRadius(9): -1
 
  GetBankBalance():     100000
 
  BuildAirport():       true
 
  IsHangarTile():       false
 
  IsAirportTile():      true
 
  GetAirportType():     0
 
  GetHangarOfAirport(): 32119
 
  IsHangarTile():       true
 
  IsAirportTile():      true
 
  GetAirportType():     0
 
  GetBankBalance():     199108
 
  RemoveAirport():      true
 
  IsHangarTile():       false
 
  IsAirportTile():      false
 
  GetBankBalance():     298300
 
  BuildAirport():       true
 

	
 
--Bridge--
 
  Bridge -1
 
    IsValidBridge():    false
 
    GetName():          (null : 0x00000000)
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxLength():     -1
 
    GetMinLength():     -1
 
    GetYearAvailable(): -1
 
  Bridge 0
 
    IsValidBridge():    true
 
    GetName():          Wooden rail bridge
 
    GetMaxSpeed():      32
 
    GetPrice():         10
 
    GetMaxLength():     102
 
    GetMinLength():     2
 
    GetYearAvailable(): 0
 
  Bridge 1
 
    IsValidBridge():    true
 
    GetName():          Concrete rail bridge
 
    GetMaxSpeed():      48
 
    GetPrice():         15
 
    GetMaxLength():     4
 
    GetMinLength():     2
 
    GetYearAvailable(): 0
 
  Bridge 2
 
    IsValidBridge():    true
 
    GetName():          Steel girder rail bridge
 
    GetMaxSpeed():      64
 
    GetPrice():         19
 
    GetMaxLength():     7
 
    GetMinLength():     2
 
    GetYearAvailable(): 1930
 
  Bridge 3
 
    IsValidBridge():    true
 
    GetName():          Reinforced concrete suspension rail bridge
 
    GetMaxSpeed():      80
 
    GetPrice():         22
 
    GetMaxLength():     12
 
    GetMinLength():     4
 
    GetYearAvailable(): 0
 
  Bridge 4
 
    IsValidBridge():    true
 
    GetName():          Steel suspension rail bridge
 
    GetMaxSpeed():      96
 
    GetPrice():         25
 
    GetMaxLength():     102
 
    GetMinLength():     5
 
    GetYearAvailable(): 1930
 
  Bridge 5
 
    IsValidBridge():    true
 
    GetName():          Steel suspension rail bridge
 
    GetMaxSpeed():      112
 
    GetPrice():         26
 
    GetMaxLength():     102
 
    GetMinLength():     5
 
    GetYearAvailable(): 1930
 
  Bridge 6
 
    IsValidBridge():    true
 
    GetName():          Steel cantilever rail bridge
 
    GetMaxSpeed():      160
 
    GetPrice():         30
 
    GetMaxLength():     9
 
    GetMinLength():     5
 
    GetYearAvailable(): 1930
 
  Bridge 7
 
    IsValidBridge():    true
 
    GetName():          Steel cantilever rail bridge
 
    GetMaxSpeed():      208
 
    GetPrice():         31
 
    GetMaxLength():     10
 
    GetMinLength():     5
 
    GetYearAvailable(): 1930
 
  Bridge 8
 
    IsValidBridge():    true
 
    GetName():          Steel cantilever rail bridge
 
    GetMaxSpeed():      240
 
    GetPrice():         33
 
    GetMaxLength():     11
 
    GetMinLength():     5
 
    GetYearAvailable(): 1930
 
  Bridge 9
 
    IsValidBridge():    true
 
    GetName():          Steel girder rail bridge
 
    GetMaxSpeed():      256
 
    GetPrice():         32
 
    GetMaxLength():     4
 
    GetMinLength():     2
 
    GetYearAvailable(): 1930
 
  Bridge 10
 
    IsValidBridge():    true
 
    GetName():          Tubular rail bridge
 
    GetMaxSpeed():      320
 
    GetPrice():         34
 
    GetMaxLength():     102
 
    GetMinLength():     4
 
    GetYearAvailable(): 1995
 
  Bridge 11
 
    IsValidBridge():    true
 
    GetName():          Tubular rail bridge
 
    GetMaxSpeed():      512
 
    GetPrice():         51
 
    GetMaxLength():     102
 
    GetMinLength():     4
 
    GetYearAvailable(): 2005
 
  Bridge 12
 
    IsValidBridge():    true
 
    GetName():          Tubular rail bridge
 
    GetMaxSpeed():      608
 
    GetPrice():         69
 
    GetMaxLength():     102
 
    GetMinLength():     4
 
    GetYearAvailable(): 2010
 
  Bridge 13
 
    IsValidBridge():    false
 
    GetName():          (null : 0x00000000)
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxLength():     -1
 
    GetMinLength():     -1
 
    GetYearAvailable(): -1
 
  Valid Bridges:        13
 
  IsBridgeTile():       false
 
  RemoveBridge():       false
 
  GetLastErrorString(): ERR_PRECONDITION_FAILED
 
  GetOtherBridgeEnd():  -1
 
  BuildBridge():        true
 
  IsBridgeTile():       true
 
  IsBridgeTile():       true
 
  GetOtherBridgeEnd():  33155
 
  BuildBridge():        false
 
  GetLastErrorString(): ERR_ALREADY_BUILT
 
  RemoveBridge():       true
 
  IsBridgeTile():       false
 

	
 
--BridgeList--
 
  Count():             10
 
  MaxSpeed ListDump:
 
    9 => 256
 
    8 => 240
 
    7 => 208
 
    6 => 160
 
    5 => 112
 
    4 => 96
 
    3 => 80
 
    2 => 64
 
    1 => 48
 
    0 => 32
 
  Price ListDump:
 
    8 => 33
 
    9 => 32
 
    7 => 31
 
    6 => 30
 
    5 => 26
 
    4 => 25
 
    3 => 22
 
    2 => 19
 
    1 => 15
 
    0 => 10
 
  MaxLength ListDump:
 
    5 => 102
 
    4 => 102
 
    0 => 102
 
    3 => 12
 
    8 => 11
 
    7 => 10
 
    6 => 9
 
    2 => 7
 
    9 => 4
 
    1 => 4
 
  MinLength ListDump:
 
    8 => 5
 
    7 => 5
 
    6 => 5
 
    5 => 5
 
    4 => 5
 
    3 => 4
 
    9 => 2
 
    2 => 2
 
    1 => 2
 
    0 => 2
 
  YearAvailable ListDump:
 
    9 => 1930
 
    8 => 1930
 
    7 => 1930
 
    6 => 1930
 
    5 => 1930
 
    4 => 1930
 
    2 => 1930
 
    3 => 0
 
    1 => 0
 
    0 => 0
 

	
 
--BridgeList_Length--
 
  Count():             3
 
  MaxSpeed ListDump:
 
    5 => 112
 
    4 => 96
 
    0 => 32
 
  Price ListDump:
 
    5 => 73
 
    4 => 70
 
    0 => 30
 

	
 
--AICargo--
 
  Cargo -1
 
    IsValidCargo():          false
 
    GetCargoLabel():         '(null : 0x00000000)'
 
    IsFreight():             false
 
    HasCargoClass():         false
 
    GetTownEffect():         0
 
    GetCargoIncome(0, 0):    -1
 
    GetCargoIncome(10, 10):  -1
 
    GetCargoIncome(100, 10): -1
 
    GetCargoIncome(10, 100): -1
 
  Cargo 0
 
    IsValidCargo():          true
 
    GetCargoLabel():         'PASS'
 
    IsFreight():             false
 
    HasCargoClass():         true
 
    GetTownEffect():         1
 
    GetCargoIncome(0, 0):    0
 
    GetCargoIncome(10, 10):  4
 
    GetCargoIncome(100, 10): 40
 
    GetCargoIncome(10, 100): 3
 
  Cargo 1
 
    IsValidCargo():          true
 
    GetCargoLabel():         'COAL'
 
    IsFreight():             true
 
    HasCargoClass():         false
 
    GetTownEffect():         0
 
    GetCargoIncome(0, 0):    0
 
    GetCargoIncome(10, 10):  7
 
    GetCargoIncome(100, 10): 75
 
    GetCargoIncome(10, 100): 6
 
  Cargo 2
 
    IsValidCargo():          true
 
    GetCargoLabel():         'MAIL'
 
    IsFreight():             false
 
    HasCargoClass():         false
 
    GetTownEffect():         2
 
    GetCargoIncome(0, 0):    0
 
    GetCargoIncome(10, 10):  5
 
    GetCargoIncome(100, 10): 58
 
    GetCargoIncome(10, 100): 5
 
  Cargo 3
 
    IsValidCargo():          true
 
    GetCargoLabel():         'OIL_'
 
    IsFreight():             true
 
    HasCargoClass():         false
 
    GetTownEffect():         0
 
    GetCargoIncome(0, 0):    0
 
    GetCargoIncome(10, 10):  5
 
    GetCargoIncome(100, 10): 56
 
    GetCargoIncome(10, 100): 5
 
  Cargo 4
 
    IsValidCargo():          true
 
    GetCargoLabel():         'LVST'
 
    IsFreight():             true
 
    HasCargoClass():         false
 
    GetTownEffect():         0
 
    GetCargoIncome(0, 0):    0
 
    GetCargoIncome(10, 10):  5
 
    GetCargoIncome(100, 10): 55
 
    GetCargoIncome(10, 100): 4
 
  Cargo 5
 
    IsValidCargo():          true
 
    GetCargoLabel():         'GOOD'
 
    IsFreight():             true
 
    HasCargoClass():         false
 
    GetTownEffect():         3
 
    GetCargoIncome(0, 0):    0
 
    GetCargoIncome(10, 10):  7
 
    GetCargoIncome(100, 10): 78
 
    GetCargoIncome(10, 100): 6
 
  Cargo 6
 
    IsValidCargo():          true
 
    GetCargoLabel():         'GRAI'
 
    IsFreight():             true
 
    HasCargoClass():         false
 
    GetTownEffect():         0
 
    GetCargoIncome(0, 0):    0
 
    GetCargoIncome(10, 10):  6
 
    GetCargoIncome(100, 10): 60
 
    GetCargoIncome(10, 100): 5
 
  Cargo 7
 
    IsValidCargo():          true
 
    GetCargoLabel():         'WOOD'
 
    IsFreight():             true
 
    HasCargoClass():         false
 
    GetTownEffect():         0
 
    GetCargoIncome(0, 0):    0
 
    GetCargoIncome(10, 10):  6
 
    GetCargoIncome(100, 10): 63
 
    GetCargoIncome(10, 100): 5
 
  Cargo 8
 
    IsValidCargo():          true
 
    GetCargoLabel():         'IORE'
 
    IsFreight():             true
 
    HasCargoClass():         false
 
    GetTownEffect():         0
 
    GetCargoIncome(0, 0):    0
 
    GetCargoIncome(10, 10):  6
 
    GetCargoIncome(100, 10): 65
 
    GetCargoIncome(10, 100): 5
 
  Cargo 9
 
    IsValidCargo():          true
 
    GetCargoLabel():         'STEL'
 
    IsFreight():             true
 
    HasCargoClass():         false
 
    GetTownEffect():         0
 
    GetCargoIncome(0, 0):    0
 
    GetCargoIncome(10, 10):  7
 
    GetCargoIncome(100, 10): 72
 
    GetCargoIncome(10, 100): 6
 
  Cargo 10
 
    IsValidCargo():          true
 
    GetCargoLabel():         'VALU'
 
    IsFreight():             true
 
    HasCargoClass():         false
 
    GetTownEffect():         0
 
    GetCargoIncome(0, 0):    0
 
    GetCargoIncome(10, 10):  9
 
    GetCargoIncome(100, 10): 94
 
    GetCargoIncome(10, 100): 7
 
  Cargo 11
 
    IsValidCargo():          false
 
    GetCargoLabel():         '(null : 0x00000000)'
 
    IsFreight():             false
 
    HasCargoClass():         false
 
    GetTownEffect():         0
 
    GetCargoIncome(0, 0):    -1
 
    GetCargoIncome(10, 10):  -1
 
    GetCargoIncome(100, 10): -1
 
    GetCargoIncome(10, 100): -1
 
  Cargo 12
 
    IsValidCargo():          false
 
    GetCargoLabel():         '(null : 0x00000000)'
 
    IsFreight():             false
 
    HasCargoClass():         false
 
    GetTownEffect():         0
 
    GetCargoIncome(0, 0):    -1
 
    GetCargoIncome(10, 10):  -1
 
    GetCargoIncome(100, 10): -1
 
    GetCargoIncome(10, 100): -1
 
  Cargo 13
 
    IsValidCargo():          false
 
    GetCargoLabel():         '(null : 0x00000000)'
 
    IsFreight():             false
 
    HasCargoClass():         false
 
    GetTownEffect():         0
 
    GetCargoIncome(0, 0):    -1
 
    GetCargoIncome(10, 10):  -1
 
    GetCargoIncome(100, 10): -1
 
    GetCargoIncome(10, 100): -1
 
  Cargo 14
 
    IsValidCargo():          false
 
    GetCargoLabel():         '(null : 0x00000000)'
 
    IsFreight():             false
 
    HasCargoClass():         false
 
    GetTownEffect():         0
 
    GetCargoIncome(0, 0):    -1
 
    GetCargoIncome(10, 10):  -1
 
    GetCargoIncome(100, 10): -1
 
    GetCargoIncome(10, 100): -1
 

	
 
--CargoList--
 
  Count():            11
 
  IsFreight ListDump:
 
    10 => 1
 
    9 => 1
 
    8 => 1
 
    7 => 1
 
    6 => 1
 
    5 => 1
 
    4 => 1
 
    3 => 1
 
    1 => 1
 
    2 => 0
 
    0 => 0
 
  CargoIncomes(100, 100) ListDump:
 
    10 => 78
 
    5 => 65
 
    1 => 65
 
    9 => 63
 
    8 => 57
 
    7 => 57
 
    3 => 53
 
    2 => 53
 
    6 => 52
 
    4 => 43
 
    0 => 31
 

	
 
--CargoList_IndustryAccepting--
 
  Count():            1
 
  ListDump:
 
    7
 

	
 
--CargoList_IndustryProducing--
 
  Count():            1
 
  ListDump:
 
    7
 

	
 
--Company--
 
  SetName():            true
 
  SetName():            true
 
  SetName():            true
 
  SetName():            false
 
  GetLastErrorString(): ERR_NAME_IS_NOT_UNIQUE
 
  GetName():                   Regression
 
  GetPresidentName():          K. O'Donnell
 
  SetPresidentName():          true
 
  GetPresidentName():          Regression AI
 
  GetCompanyValue():           355454
 
  GetBankBalance():            455204
 
  GetName():                   (null : 0x00000000)
 
  GetLoanAmount():             100000
 
  GetMaxLoanAmount():          300000
 
  GetLoanInterval():           10000
 
  SetLoanAmount(1):            false
 
  SetLoanAmount(100):          false
 
  SetLoanAmount(10000):        true
 
  GetLastErrorString():        ERR_NONE
 
  GetBankBalance():            365204
 
  GetLoanAmount():             10000
 
  SetMinimumLoanAmount(31337): true
 
  GetBankBalance():            395204
 
  GetLoanAmount():             40000
 
  SetLoanAmount(10000):        true
 
  GetBankBalance():            655204
 
  GetLoanAmount():             300000
 
  GetCompanyHQ():              -1
 
  BuildCompanyHQ():            true
 
  GetCompanyHQ():              33151
 
  BuildCompanyHQ():            true
 
  GetCompanyHQ():              33153
 
  BuildCompanyHQ():            false
 
  GetLastErrorString():        ERR_AREA_NOT_CLEAR
 
  GetAutoRenewStatus();        false
 
  SetAutoRenewStatus(true);    true
 
  GetAutoRenewStatus();        true
 
  SetAutoRenewStatus(true);    false
 
  SetAutoRenewStatus(false);   true
 
  GetAutoRenewMonths();        -6
 
  SetAutoRenewMonths(-12);     true
 
  GetAutoRenewMonths();        -12
 
  SetAutoRenewMonths(-12);     false
 
  SetAutoRenewMonths(6);       true
 
  GetAutoRenewMoney();         100000
 
  SetAutoRenewMoney(200000);   true
 
  GetAutoRenewMoney();         200000
 
  SetAutoRenewMoney(200000);   false
 
  SetAutoRenewMoney(100000);   true
 

	
 
--Engine--
 
  Engine -1
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 0
 
    IsValidEngine():    true
 
    GetName():          Kirby Paul Tank (Steam)
 
    GetCargoType():     0
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   74
 
    GetMaxSpeed():      64
 
    GetPrice():         22
 
    GetMaxAge():        5490
 
    GetRunningCost():   7
 
    GetVehicleType():   0
 
    GetRailType():      0
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 1
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 2
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 3
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 4
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 5
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 6
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 7
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 8
 
    IsValidEngine():    true
 
    GetName():          Chaney 'Jubilee' (Steam)
 
    GetCargoType():     0
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   79
 
    GetMaxSpeed():      112
 
    GetPrice():         41
 
    GetMaxAge():        7686
 
    GetRunningCost():   18
 
    GetVehicleType():   0
 
    GetRailType():      0
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 9
 
    IsValidEngine():    true
 
    GetName():          Ginzu 'A4' (Steam)
 
    GetCargoType():     0
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   83
 
    GetMaxSpeed():      128
 
    GetPrice():         61
 
    GetMaxAge():        7320
 
    GetRunningCost():   21
 
    GetVehicleType():   0
 
    GetRailType():      0
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 10
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 11
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 12
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 13
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 14
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 15
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 16
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 17
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 18
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 19
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 20
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 21
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 22
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 23
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 24
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 25
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 26
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 27
 
    IsValidEngine():    true
 
    GetName():          Passenger Carriage
 
    GetCargoType():     0
 
    CanRefitCargo():    false
 
    GetCapacity():      40
 
    GetReliability():   0
 
    GetMaxSpeed():      0
 
    GetPrice():         795
 
    GetMaxAge():        7320
 
    GetRunningCost():   0
 
    GetVehicleType():   0
 
    GetRailType():      0
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 28
 
    IsValidEngine():    true
 
    GetName():          Mail Van
 
    GetCargoType():     2
 
    CanRefitCargo():    false
 
    GetCapacity():      30
 
    GetReliability():   0
 
    GetMaxSpeed():      0
 
    GetPrice():         733
 
    GetMaxAge():        7320
 
    GetRunningCost():   0
 
    GetVehicleType():   0
 
    GetRailType():      0
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 29
 
    IsValidEngine():    true
 
    GetName():          Coal Truck
 
    GetCargoType():     1
 
    CanRefitCargo():    true
 
    GetCapacity():      30
 
    GetReliability():   0
 
    GetMaxSpeed():      0
 
    GetPrice():         566
 
    GetMaxAge():        7320
 
    GetRunningCost():   0
 
    GetVehicleType():   0
 
    GetRailType():      0
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 30
 
    IsValidEngine():    true
 
    GetName():          Oil Tanker
 
    GetCargoType():     3
 
    CanRefitCargo():    false
 
    GetCapacity():      30
 
    GetReliability():   0
 
    GetMaxSpeed():      0
 
    GetPrice():         643
 
    GetMaxAge():        7320
 
    GetRunningCost():   0
 
    GetVehicleType():   0
 
    GetRailType():      0
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 31
 
    IsValidEngine():    true
 
    GetName():          Livestock Van
 
    GetCargoType():     4
 
    CanRefitCargo():    false
 
    GetCapacity():      25
 
    GetReliability():   0
 
    GetMaxSpeed():      0
 
    GetPrice():         618
 
    GetMaxAge():        7320
 
    GetRunningCost():   0
 
    GetVehicleType():   0
 
    GetRailType():      0
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 32
 
    IsValidEngine():    true
 
    GetName():          Goods Van
 
    GetCargoType():     5
 
    CanRefitCargo():    false
 
    GetCapacity():      25
 
    GetReliability():   0
 
    GetMaxSpeed():      0
 
    GetPrice():         611
 
    GetMaxAge():        7320
 
    GetRunningCost():   0
 
    GetVehicleType():   0
 
    GetRailType():      0
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 33
 
    IsValidEngine():    true
 
    GetName():          Grain Hopper
 
    GetCargoType():     6
 
    CanRefitCargo():    false
 
    GetCapacity():      30
 
    GetReliability():   0
 
    GetMaxSpeed():      0
 
    GetPrice():         585
 
    GetMaxAge():        7320
 
    GetRunningCost():   0
 
    GetVehicleType():   0
 
    GetRailType():      0
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 34
 
    IsValidEngine():    true
 
    GetName():          Wood Truck
 
    GetCargoType():     7
 
    CanRefitCargo():    false
 
    GetCapacity():      30
 
    GetReliability():   0
 
    GetMaxSpeed():      0
 
    GetPrice():         582
 
    GetMaxAge():        7320
 
    GetRunningCost():   0
 
    GetVehicleType():   0
 
    GetRailType():      0
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 35
 
    IsValidEngine():    true
 
    GetName():          Iron Ore Hopper
 
    GetCargoType():     8
 
    CanRefitCargo():    false
 
    GetCapacity():      30
 
    GetReliability():   0
 
    GetMaxSpeed():      0
 
    GetPrice():         576
 
    GetMaxAge():        7320
 
    GetRunningCost():   0
 
    GetVehicleType():   0
 
    GetRailType():      0
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 36
 
    IsValidEngine():    true
 
    GetName():          Steel Truck
 
    GetCargoType():     9
 
    CanRefitCargo():    false
 
    GetCapacity():      20
 
    GetReliability():   0
 
    GetMaxSpeed():      0
 
    GetPrice():         630
 
    GetMaxAge():        7320
 
    GetRunningCost():   0
 
    GetVehicleType():   0
 
    GetRailType():      0
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 37
 
    IsValidEngine():    true
 
    GetName():          Armoured Van
 
    GetCargoType():     10
 
    CanRefitCargo():    false
 
    GetCapacity():      20
 
    GetReliability():   0
 
    GetMaxSpeed():      0
 
    GetPrice():         820
 
    GetMaxAge():        7320
 
    GetRunningCost():   0
 
    GetVehicleType():   0
 
    GetRailType():      0
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 38
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 39
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 40
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 41
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 42
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 43
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 44
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 45
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 46
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 47
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 48
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 49
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 50
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 51
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 52
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 53
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 54
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 55
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 56
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 57
 
    IsValidEngine():    true
 
    GetName():          Passenger Carriage
 
    GetCargoType():     0
 
    CanRefitCargo():    false
 
    GetCapacity():      45
 
    GetReliability():   0
 
    GetMaxSpeed():      0
 
    GetPrice():         795
 
    GetMaxAge():        7320
 
    GetRunningCost():   0
 
    GetVehicleType():   0
 
    GetRailType():      2
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 58
 
    IsValidEngine():    true
 
    GetName():          Mail Van
 
    GetCargoType():     2
 
    CanRefitCargo():    false
 
    GetCapacity():      35
 
    GetReliability():   0
 
    GetMaxSpeed():      0
 
    GetPrice():         733
 
    GetMaxAge():        7320
 
    GetRunningCost():   0
 
    GetVehicleType():   0
 
    GetRailType():      2
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 59
 
    IsValidEngine():    true
 
    GetName():          Coal Truck
 
    GetCargoType():     1
 
    CanRefitCargo():    true
 
    GetCapacity():      35
 
    GetReliability():   0
 
    GetMaxSpeed():      0
 
    GetPrice():         566
 
    GetMaxAge():        7320
 
    GetRunningCost():   0
 
    GetVehicleType():   0
 
    GetRailType():      2
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 60
 
    IsValidEngine():    true
 
    GetName():          Oil Tanker
 
    GetCargoType():     3
 
    CanRefitCargo():    false
 
    GetCapacity():      35
 
    GetReliability():   0
 
    GetMaxSpeed():      0
 
    GetPrice():         643
 
    GetMaxAge():        7320
 
    GetRunningCost():   0
 
    GetVehicleType():   0
 
    GetRailType():      2
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 61
 
    IsValidEngine():    true
 
    GetName():          Livestock Van
 
    GetCargoType():     4
 
    CanRefitCargo():    false
 
    GetCapacity():      30
 
    GetReliability():   0
 
    GetMaxSpeed():      0
 
    GetPrice():         618
 
    GetMaxAge():        7320
 
    GetRunningCost():   0
 
    GetVehicleType():   0
 
    GetRailType():      2
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 62
 
    IsValidEngine():    true
 
    GetName():          Goods Van
 
    GetCargoType():     5
 
    CanRefitCargo():    false
 
    GetCapacity():      30
 
    GetReliability():   0
 
    GetMaxSpeed():      0
 
    GetPrice():         611
 
    GetMaxAge():        7320
 
    GetRunningCost():   0
 
    GetVehicleType():   0
 
    GetRailType():      2
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 63
 
    IsValidEngine():    true
 
    GetName():          Grain Hopper
 
    GetCargoType():     6
 
    CanRefitCargo():    false
 
    GetCapacity():      35
 
    GetReliability():   0
 
    GetMaxSpeed():      0
 
    GetPrice():         585
 
    GetMaxAge():        7320
 
    GetRunningCost():   0
 
    GetVehicleType():   0
 
    GetRailType():      2
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 64
 
    IsValidEngine():    true
 
    GetName():          Wood Truck
 
    GetCargoType():     7
 
    CanRefitCargo():    false
 
    GetCapacity():      35
 
    GetReliability():   0
 
    GetMaxSpeed():      0
 
    GetPrice():         582
 
    GetMaxAge():        7320
 
    GetRunningCost():   0
 
    GetVehicleType():   0
 
    GetRailType():      2
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 65
 
    IsValidEngine():    true
 
    GetName():          Iron Ore Hopper
 
    GetCargoType():     8
 
    CanRefitCargo():    false
 
    GetCapacity():      35
 
    GetReliability():   0
 
    GetMaxSpeed():      0
 
    GetPrice():         576
 
    GetMaxAge():        7320
 
    GetRunningCost():   0
 
    GetVehicleType():   0
 
    GetRailType():      2
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 66
 
    IsValidEngine():    true
 
    GetName():          Steel Truck
 
    GetCargoType():     9
 
    CanRefitCargo():    false
 
    GetCapacity():      25
 
    GetReliability():   0
 
    GetMaxSpeed():      0
 
    GetPrice():         630
 
    GetMaxAge():        7320
 
    GetRunningCost():   0
 
    GetVehicleType():   0
 
    GetRailType():      2
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 67
 
    IsValidEngine():    true
 
    GetName():          Armoured Van
 
    GetCargoType():     10
 
    CanRefitCargo():    false
 
    GetCapacity():      25
 
    GetReliability():   0
 
    GetMaxSpeed():      0
 
    GetPrice():         820
 
    GetMaxAge():        7320
 
    GetRunningCost():   0
 
    GetVehicleType():   0
 
    GetRailType():      2
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 68
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 69
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 70
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 71
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 72
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 73
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 74
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 75
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 76
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 77
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 78
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 79
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 80
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 81
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 82
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 83
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 84
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 85
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 86
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 87
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 88
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 89
 
    IsValidEngine():    true
 
    GetName():          Passenger Carriage
 
    GetCargoType():     0
 
    CanRefitCargo():    false
 
    GetCapacity():      47
 
    GetReliability():   0
 
    GetMaxSpeed():      0
 
    GetPrice():         795
 
    GetMaxAge():        7320
 
    GetRunningCost():   0
 
    GetVehicleType():   0
 
    GetRailType():      3
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 90
 
    IsValidEngine():    true
 
    GetName():          Mail Van
 
    GetCargoType():     2
 
    CanRefitCargo():    false
 
    GetCapacity():      37
 
    GetReliability():   0
 
    GetMaxSpeed():      0
 
    GetPrice():         733
 
    GetMaxAge():        7320
 
    GetRunningCost():   0
 
    GetVehicleType():   0
 
    GetRailType():      3
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 91
 
    IsValidEngine():    true
 
    GetName():          Coal Truck
 
    GetCargoType():     1
 
    CanRefitCargo():    true
 
    GetCapacity():      37
 
    GetReliability():   0
 
    GetMaxSpeed():      0
 
    GetPrice():         566
 
    GetMaxAge():        7320
 
    GetRunningCost():   0
 
    GetVehicleType():   0
 
    GetRailType():      3
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 92
 
    IsValidEngine():    true
 
    GetName():          Oil Tanker
 
    GetCargoType():     3
 
    CanRefitCargo():    false
 
    GetCapacity():      37
 
    GetReliability():   0
 
    GetMaxSpeed():      0
 
    GetPrice():         643
 
    GetMaxAge():        7320
 
    GetRunningCost():   0
 
    GetVehicleType():   0
 
    GetRailType():      3
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 93
 
    IsValidEngine():    true
 
    GetName():          Livestock Van
 
    GetCargoType():     4
 
    CanRefitCargo():    false
 
    GetCapacity():      32
 
    GetReliability():   0
 
    GetMaxSpeed():      0
 
    GetPrice():         618
 
    GetMaxAge():        7320
 
    GetRunningCost():   0
 
    GetVehicleType():   0
 
    GetRailType():      3
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 94
 
    IsValidEngine():    true
 
    GetName():          Goods Van
 
    GetCargoType():     5
 
    CanRefitCargo():    false
 
    GetCapacity():      32
 
    GetReliability():   0
 
    GetMaxSpeed():      0
 
    GetPrice():         611
 
    GetMaxAge():        7320
 
    GetRunningCost():   0
 
    GetVehicleType():   0
 
    GetRailType():      3
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 95
 
    IsValidEngine():    true
 
    GetName():          Grain Hopper
 
    GetCargoType():     6
 
    CanRefitCargo():    false
 
    GetCapacity():      37
 
    GetReliability():   0
 
    GetMaxSpeed():      0
 
    GetPrice():         585
 
    GetMaxAge():        7320
 
    GetRunningCost():   0
 
    GetVehicleType():   0
 
    GetRailType():      3
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 96
 
    IsValidEngine():    true
 
    GetName():          Wood Truck
 
    GetCargoType():     7
 
    CanRefitCargo():    false
 
    GetCapacity():      37
 
    GetReliability():   0
 
    GetMaxSpeed():      0
 
    GetPrice():         582
 
    GetMaxAge():        7320
 
    GetRunningCost():   0
 
    GetVehicleType():   0
 
    GetRailType():      3
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 97
 
    IsValidEngine():    true
 
    GetName():          Iron Ore Hopper
 
    GetCargoType():     8
 
    CanRefitCargo():    false
 
    GetCapacity():      37
 
    GetReliability():   0
 
    GetMaxSpeed():      0
 
    GetPrice():         576
 
    GetMaxAge():        7320
 
    GetRunningCost():   0
 
    GetVehicleType():   0
 
    GetRailType():      3
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 98
 
    IsValidEngine():    true
 
    GetName():          Steel Truck
 
    GetCargoType():     9
 
    CanRefitCargo():    false
 
    GetCapacity():      27
 
    GetReliability():   0
 
    GetMaxSpeed():      0
 
    GetPrice():         630
 
    GetMaxAge():        7320
 
    GetRunningCost():   0
 
    GetVehicleType():   0
 
    GetRailType():      3
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 99
 
    IsValidEngine():    true
 
    GetName():          Armoured Van
 
    GetCargoType():     10
 
    CanRefitCargo():    false
 
    GetCapacity():      27
 
    GetReliability():   0
 
    GetMaxSpeed():      0
 
    GetPrice():         820
 
    GetMaxAge():        7320
 
    GetRunningCost():   0
 
    GetVehicleType():   0
 
    GetRailType():      3
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 100
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 101
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 102
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 103
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 104
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 105
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 106
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 107
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 108
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 109
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 110
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 111
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 112
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 113
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 114
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 115
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 116
 
    IsValidEngine():    true
 
    GetName():          MPS Regal Bus
 
    GetCargoType():     0
 
    CanRefitCargo():    false
 
    GetCapacity():      31
 
    GetReliability():   78
 
    GetMaxSpeed():      56
 
    GetPrice():         386
 
    GetMaxAge():        4392
 
    GetRunningCost():   14
 
    GetVehicleType():   1
 
    GetRailType():      255
 
    GetRoadType():      0
 
    GetPlaneType():     -1
 
  Engine 117
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 118
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 119
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 120
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 121
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 122
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 123
 
    IsValidEngine():    true
 
    GetName():          Balogh Coal Truck
 
    GetCargoType():     1
 
    CanRefitCargo():    true
 
    GetCapacity():      20
 
    GetReliability():   76
 
    GetMaxSpeed():      48
 
    GetPrice():         347
 
    GetMaxAge():        5490
 
    GetRunningCost():   14
 
    GetVehicleType():   1
 
    GetRailType():      255
 
    GetRoadType():      0
 
    GetPlaneType():     -1
 
  Engine 124
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 125
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 126
 
    IsValidEngine():    true
 
    GetName():          MPS Mail Truck
 
    GetCargoType():     2
 
    CanRefitCargo():    false
 
    GetCapacity():      22
 
    GetReliability():   91
 
    GetMaxSpeed():      48
 
    GetPrice():         370
 
    GetMaxAge():        5490
 
    GetRunningCost():   14
 
    GetVehicleType():   1
 
    GetRailType():      255
 
    GetRoadType():      0
 
    GetPlaneType():     -1
 
  Engine 127
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 128
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 129
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 130
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 131
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 132
 
    IsValidEngine():    true
 
    GetName():          Witcombe Oil Tanker
 
    GetCargoType():     3
 
    CanRefitCargo():    false
 
    GetCapacity():      21
 
    GetReliability():   97
 
    GetMaxSpeed():      48
 
    GetPrice():         354
 
    GetMaxAge():        5490
 
    GetRunningCost():   14
 
    GetVehicleType():   1
 
    GetRailType():      255
 
    GetRoadType():      0
 
    GetPlaneType():     -1
 
  Engine 133
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 134
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 135
 
    IsValidEngine():    true
 
    GetName():          Talbott Livestock Van
 
    GetCargoType():     4
 
    CanRefitCargo():    false
 
    GetCapacity():      14
 
    GetReliability():   96
 
    GetMaxSpeed():      48
 
    GetPrice():         337
 
    GetMaxAge():        5490
 
    GetRunningCost():   14
 
    GetVehicleType():   1
 
    GetRailType():      255
 
    GetRoadType():      0
 
    GetPlaneType():     -1
 
  Engine 136
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 137
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 138
 
    IsValidEngine():    true
 
    GetName():          Balogh Goods Truck
 
    GetCargoType():     5
 
    CanRefitCargo():    false
 
    GetCapacity():      14
 
    GetReliability():   86
 
    GetMaxSpeed():      48
 
    GetPrice():         344
 
    GetMaxAge():        5490
 
    GetRunningCost():   14
 
    GetVehicleType():   1
 
    GetRailType():      255
 
    GetRoadType():      0
 
    GetPlaneType():     -1
 
  Engine 139
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 140
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 141
 
    IsValidEngine():    true
 
    GetName():          Hereford Grain Truck
 
    GetCargoType():     6
 
    CanRefitCargo():    false
 
    GetCapacity():      20
 
    GetReliability():   96
 
    GetMaxSpeed():      48
 
    GetPrice():         366
 
    GetMaxAge():        5490
 
    GetRunningCost():   14
 
    GetVehicleType():   1
 
    GetRailType():      255
 
    GetRoadType():      0
 
    GetPlaneType():     -1
 
  Engine 142
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 143
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 144
 
    IsValidEngine():    true
 
    GetName():          Witcombe Wood Truck
 
    GetCargoType():     7
 
    CanRefitCargo():    false
 
    GetCapacity():      20
 
    GetReliability():   97
 
    GetMaxSpeed():      48
 
    GetPrice():         379
 
    GetMaxAge():        5490
 
    GetRunningCost():   14
 
    GetVehicleType():   1
 
    GetRailType():      255
 
    GetRoadType():      0
 
    GetPlaneType():     -1
 
  Engine 145
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 146
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 147
 
    IsValidEngine():    true
 
    GetName():          MPS Iron Ore Truck
 
    GetCargoType():     8
 
    CanRefitCargo():    false
 
    GetCapacity():      22
 
    GetReliability():   96
 
    GetMaxSpeed():      48
 
    GetPrice():         389
 
    GetMaxAge():        5490
 
    GetRunningCost():   14
 
    GetVehicleType():   1
 
    GetRailType():      255
 
    GetRoadType():      0
 
    GetPlaneType():     -1
 
  Engine 148
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 149
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 150
 
    IsValidEngine():    true
 
    GetName():          Balogh Steel Truck
 
    GetCargoType():     9
 
    CanRefitCargo():    false
 
    GetCapacity():      15
 
    GetReliability():   81
 
    GetMaxSpeed():      48
 
    GetPrice():         360
 
    GetMaxAge():        5490
 
    GetRunningCost():   14
 
    GetVehicleType():   1
 
    GetRailType():      255
 
    GetRoadType():      0
 
    GetPlaneType():     -1
 
  Engine 151
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 152
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 153
 
    IsValidEngine():    true
 
    GetName():          Balogh Armoured Truck
 
    GetCargoType():     10
 
    CanRefitCargo():    false
 
    GetCapacity():      12
 
    GetReliability():   75
 
    GetMaxSpeed():      48
 
    GetPrice():         466
 
    GetMaxAge():        5490
 
    GetRunningCost():   14
 
    GetVehicleType():   1
 
    GetRailType():      255
 
    GetRoadType():      0
 
    GetPlaneType():     -1
 
  Engine 154
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 155
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 156
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 157
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 158
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 159
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 160
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 161
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 162
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 163
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 164
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 165
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 166
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 167
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 168
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 169
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 170
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 171
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 172
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 173
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 174
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 175
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 176
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 177
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 178
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 179
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 180
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 181
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 182
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 183
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 184
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 185
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 186
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 187
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 188
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 189
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 190
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 191
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 192
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 193
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 194
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 195
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 196
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 197
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 198
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 199
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 200
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 201
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 202
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 203
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 204
 
    IsValidEngine():    true
 
    GetName():          MPS Oil Tanker
 
    GetCargoType():     3
 
    CanRefitCargo():    false
 
    GetCapacity():      220
 
    GetReliability():   98
 
    GetMaxSpeed():      24
 
    GetPrice():         515
 
    GetMaxAge():        10980
 
    GetRunningCost():   21
 
    GetVehicleType():   2
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 205
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 206
 
    IsValidEngine():    true
 
    GetName():          MPS Passenger Ferry
 
    GetCargoType():     0
 
    CanRefitCargo():    false
 
    GetCapacity():      100
 
    GetReliability():   87
 
    GetMaxSpeed():      32
 
    GetPrice():         309
 
    GetMaxAge():        10980
 
    GetRunningCost():   14
 
    GetVehicleType():   2
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 207
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 208
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 209
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 210
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 211
 
    IsValidEngine():    true
 
    GetName():          Yate Cargo ship
 
    GetCargoType():     5
 
    CanRefitCargo():    true
 
    GetCapacity():      160
 
    GetReliability():   81
 
    GetMaxSpeed():      24
 
    GetPrice():         412
 
    GetMaxAge():        10980
 
    GetRunningCost():   23
 
    GetVehicleType():   2
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 212
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 213
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 214
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 215
 
    IsValidEngine():    true
 
    GetName():          Sampson U52
 
    GetCargoType():     0
 
    CanRefitCargo():    false
 
    GetCapacity():      25
 
    GetReliability():   58
 
    GetMaxSpeed():      238
 
    GetPrice():         45
 
    GetMaxAge():        7320
 
    GetRunningCost():   13
 
    GetVehicleType():   3
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     1
 
  Engine 216
 
    IsValidEngine():    true
 
    GetName():          Coleman Count
 
    GetCargoType():     0
 
    CanRefitCargo():    false
 
    GetCapacity():      65
 
    GetReliability():   95
 
    GetMaxSpeed():      238
 
    GetPrice():         48
 
    GetMaxAge():        8784
 
    GetRunningCost():   15
 
    GetVehicleType():   3
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     1
 
  Engine 217
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 218
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 219
 
    IsValidEngine():    true
 
    GetName():          Bakewell Cotswald LB-3
 
    GetCargoType():     0
 
    CanRefitCargo():    false
 
    GetCapacity():      30
 
    GetReliability():   76
 
    GetMaxSpeed():      238
 
    GetPrice():         48
 
    GetMaxAge():        10980
 
    GetRunningCost():   15
 
    GetVehicleType():   3
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     1
 
  Engine 220
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 221
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 222
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 223
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 224
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 225
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 226
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 227
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 228
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 229
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 230
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 231
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 232
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 233
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 234
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 235
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 236
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 237
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 238
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 239
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 240
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 241
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 242
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 243
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 244
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 245
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 246
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 247
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 248
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 249
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 250
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 251
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 252
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 253
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 254
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 255
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Engine 256
 
    IsValidEngine():    false
 
    GetName():          (null : 0x00000000)
 
    GetCargoType():     255
 
    CanRefitCargo():    false
 
    GetCapacity():      -1
 
    GetReliability():   -1
 
    GetMaxSpeed():      -1
 
    GetPrice():         -1
 
    GetMaxAge():        -1
 
    GetRunningCost():   -1
 
    GetVehicleType():   255
 
    GetRailType():      255
 
    GetRoadType():      -1
 
    GetPlaneType():     -1
 
  Valid Engines:        53
 

	
 
--EngineList--
 
  Count():             11
 
  CargoType ListDump:
 
    153 => 10
 
    150 => 9
 
    147 => 8
 
    144 => 7
 
    141 => 6
 
    138 => 5
 
    135 => 4
 
    132 => 3
 
    126 => 2
 
    123 => 1
 
    116 => 0
 
  Capacity ListDump:
 
    116 => 31
 
    147 => 22
 
    126 => 22
 
    132 => 21
 
    144 => 20
 
    141 => 20
 
    123 => 20
 
    150 => 15
 
    138 => 14
 
    135 => 14
 
    153 => 12
 
  Reliability ListDump:
 
    144 => 97
 
    132 => 97
 
    147 => 96
 
    141 => 96
 
    135 => 96
 
    126 => 91
 
    138 => 86
 
    150 => 81
 
    116 => 78
 
    123 => 76
 
    153 => 75
 
  MaxSpeed ListDump:
 
    116 => 56
 
    153 => 48
 
    150 => 48
 
    147 => 48
 
    144 => 48
 
    141 => 48
 
    138 => 48
 
    135 => 48
 
    132 => 48
 
    126 => 48
 
    123 => 48
 
  Price ListDump:
 
    153 => 466
 
    147 => 389
 
    116 => 386
 
    144 => 379
 
    126 => 370
 
    141 => 366
 
    150 => 360
 
    132 => 354
 
    123 => 347
 
    138 => 344
 
    135 => 337
 
--AyStar--
 
  Fastest path:
 
    Tile 10
 
    Tile 9
 
    Tile 8
 
    Tile 7
 
    Tile 6
 
    Tile 5
 
    Tile 4
 
    Tile 3
 
    Tile 2
 
    Tile 1
 

	
 
--Group--
 
  SetAutoReplace():         false
 
  GetEngineReplacement():   65535
 
  GetNumEngines():          0
 
  AIRoad.BuildRoadDepot():  true
 
  AIVehicle.BuildVehicle(): 12
 
  GetNumEngines():          1
 
  CreateGroup():            0
 
  MoveVehicle():            true
 
  GetNumEngines():          1
 
  GetNumEngines():          1
 
  GetNumEngines():          0
 
  GetName():                Group 0
 
  GetName():                (null : 0x00000000)
 
  AIVehicle.SellVehicle():  true
 
  AITile.DemolishTile():    true
 
  HasWagonRemoval():        false
 
  EnableWagonRemoval():     true
 
  HasWagonRemoval():        true
 
  EnableWagonRemoval():     true
 
  EnableWagonRemoval():     true
 
  HasWagonRemoval():        false
 

	
 
--Industry--
 
  GetMaxIndustryID():  71
 
  GetIndustryCount():  71
 
  Industry -1
 
    IsValidIndustry(): false
 
    GetName():         (null : 0x00000000)
 
    GetLocation():     -1
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
  Industry 0
 
    IsValidIndustry(): true
 
    GetName():         Kennville Oil Refinery
 
    GetLocation():     19695
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
  Industry 1
 
    IsValidIndustry(): true
 
    GetName():         Sadtown Forest
 
    GetLocation():     45122
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
	   GetLastMonthProduction():  72
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
  Industry 2
 
    IsValidIndustry(): true
 
    GetName():         Fudinghattan Forest
 
    GetLocation():     41929
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
	   GetLastMonthProduction():  72
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
  Industry 3
 
    IsValidIndustry(): true
 
    GetName():         Benville Forest
 
    GetLocation():     44640
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
	   GetLastMonthProduction():  80
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
  Industry 4
 
    IsValidIndustry(): true
 
    GetName():         Netfingbridge Forest
 
    GetLocation():     8793
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
	   GetLastMonthProduction():  135
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
  Industry 5
 
    IsValidIndustry(): true
 
    GetName():         Hutfingford Forest
 
    GetLocation():     55429
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
	   GetLastMonthProduction():  99
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
  Industry 6
 
    IsValidIndustry(): true
 
    GetName():         Great Hinninghall Forest
 
    GetLocation():     6533
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
	   GetLastMonthProduction():  72
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
  Industry 7
 
    IsValidIndustry(): true
 
    GetName():         Tondston Forest
 
    GetLocation():     27609
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
	   GetLastMonthProduction():  117
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
  Industry 8
 
    IsValidIndustry(): true
 
    GetName():         Planfield Sawmill
 
    GetLocation():     17318
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
  Industry 9
 
    IsValidIndustry(): true
 
    GetName():         Hutfingford Sawmill
 
    GetLocation():     60050
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
  Industry 10
 
    IsValidIndustry(): true
 
    GetName():         Naborough Sawmill
 
    GetLocation():     54184
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
  Industry 11
 
    IsValidIndustry(): true
 
    GetName():         Prundinghall Sawmill
 
    GetLocation():     48499
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
  Industry 12
 
    IsValidIndustry(): true
 
    GetName():         Fraston Sawmill
 
    GetLocation():     51419
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
  Industry 13
 
    IsValidIndustry(): true
 
    GetName():         Fort Frindston Sawmill
 
    GetLocation():     15950
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
  Industry 14
 
    IsValidIndustry(): true
 
    GetName():         Grinnway Sawmill
 
    GetLocation():     20001
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
  Industry 15
 
    IsValidIndustry(): true
 
    GetName():         Trenningville Coal Mine
 
    GetLocation():     51854
 
    GetProduction():   104
 
    IsCargoAccepted(): false
 
	   GetLastMonthProduction():  117
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
  Industry 16
 
    IsValidIndustry(): true
 
    GetName():         Kennville Coal Mine
 
    GetLocation():     11734
 
    GetProduction():   96
 
    IsCargoAccepted(): false
 
	   GetLastMonthProduction():  99
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
  Industry 17
 
    IsValidIndustry(): true
 
    GetName():         Great Hinninghall Coal Mine
 
    GetLocation():     13947
 
    GetProduction():   152
 
    IsCargoAccepted(): false
 
	   GetLastMonthProduction():  152
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
  Industry 18
 
    IsValidIndustry(): true
 
    GetName():         Little Fruford Coal Mine
 
    GetLocation():     23682
 
    GetProduction():   112
 
    IsCargoAccepted(): false
 
	   GetLastMonthProduction():  126
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
  Industry 19
 
    IsValidIndustry(): true
 
    GetName():         Hutfingford Coal Mine
 
    GetLocation():     57429
 
    GetProduction():   88
 
    IsCargoAccepted(): false
 
	   GetLastMonthProduction():  88
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
  Industry 20
 
    IsValidIndustry(): true
 
    GetName():         Mendingston Coal Mine
 
    GetLocation():     8562
 
    GetProduction():   152
 
    IsCargoAccepted(): false
 
	   GetLastMonthProduction():  171
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
  Industry 21
 
    IsValidIndustry(): true
 
    GetName():         Tondston Coal Mine
 
    GetLocation():     29147
 
    GetProduction():   104
 
    IsCargoAccepted(): false
 
	   GetLastMonthProduction():  117
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
  Industry 22
 
    IsValidIndustry(): true
 
    GetName():         Quartfingfield Coal Mine
 
    GetLocation():     27822
 
    GetProduction():   136
 
    IsCargoAccepted(): false
 
	   GetLastMonthProduction():  136
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
  Industry 23
 
    IsValidIndustry(): true
 
    GetName():         Muningville Coal Mine
 
    GetLocation():     43035
 
    GetProduction():   80
 
    IsCargoAccepted(): false
 
	   GetLastMonthProduction():  90
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
  Industry 24
 
    IsValidIndustry(): true
 
    GetName():         Grinnway Coal Mine
 
    GetLocation():     17943
 
    GetProduction():   32
 
    IsCargoAccepted(): false
 
	   GetLastMonthProduction():  32
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
  Industry 25
 
    IsValidIndustry(): true
 
    GetName():         Sadtown Power Station
 
    GetLocation():     48182
 
    GetProduction():   -1
 
    IsCargoAccepted(): true
 
  Industry 26
 
    IsValidIndustry(): true
 
    GetName():         Tunford Power Station
 
    GetLocation():     33934
 
    GetProduction():   -1
 
    IsCargoAccepted(): true
 
  Industry 27
 
    IsValidIndustry(): true
 
    GetName():         Quartfingfield Power Station
 
    GetLocation():     23714
 
    GetProduction():   -1
 
    IsCargoAccepted(): true
 
  Industry 28
 
    IsValidIndustry(): true
 
    GetName():         Kennville Power Station
 
    GetLocation():     20170
 
    GetProduction():   -1
 
    IsCargoAccepted(): true
 
  Industry 29
 
    IsValidIndustry(): true
 
    GetName():         Nuntfingburg Power Station
 
    GetLocation():     6685
 
    GetProduction():   -1
 
    IsCargoAccepted(): true
 
  Industry 30
 
    IsValidIndustry(): true
 
    GetName():         Bedburg Power Station
 
    GetLocation():     29022
 
    GetProduction():   -1
 
    IsCargoAccepted(): true
 
  Industry 31
 
    IsValidIndustry(): true
 
    GetName():         Benville Power Station
 
    GetLocation():     44160
 
    GetProduction():   -1
 
    IsCargoAccepted(): true
 
  Industry 32
 
    IsValidIndustry(): true
 
    GetName():         Fort Frindston Oil Wells
 
    GetLocation():     14701
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
	   GetLastMonthProduction():  108
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
  Industry 33
 
    IsValidIndustry(): true
 
    GetName():         Nuntfingburg Oil Wells
 
    GetLocation():     5659
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
	   GetLastMonthProduction():  50
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
  Industry 34
 
    IsValidIndustry(): true
 
    GetName():         Benville Oil Wells
 
    GetLocation():     36728
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
	   GetLastMonthProduction():  72
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
  Industry 35
 
    IsValidIndustry(): true
 
    GetName():         Grinnway Oil Wells
 
    GetLocation():     14361
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
	   GetLastMonthProduction():  56
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
  Industry 36
 
    IsValidIndustry(): true
 
    GetName():         Muningville Oil Wells
 
    GetLocation():     36908
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
	   GetLastMonthProduction():  64
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
  Industry 37
 
    IsValidIndustry(): true
 
    GetName():         Tondston Oil Wells
 
    GetLocation():     34237
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
	   GetLastMonthProduction():  96
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
  Industry 38
 
    IsValidIndustry(): true
 
    GetName():         Fort Frindston Iron Ore Mine
 
    GetLocation():     17742
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
	   GetLastMonthProduction():  108
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
  Industry 39
 
    IsValidIndustry(): true
 
    GetName():         Tondston Iron Ore Mine
 
    GetLocation():     25545
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
	   GetLastMonthProduction():  24
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
  Industry 40
 
    IsValidIndustry(): true
 
    GetName():         Fudinghattan Iron Ore Mine
 
    GetLocation():     47838
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
	   GetLastMonthProduction():  64
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
  Industry 41
 
    IsValidIndustry(): true
 
    GetName():         Nuntfingburg Iron Ore Mine
 
    GetLocation():     8763
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
	   GetLastMonthProduction():  72
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
  Industry 42
 
    IsValidIndustry(): true
 
    GetName():         Lardborough Iron Ore Mine
 
    GetLocation():     60866
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
	   GetLastMonthProduction():  72
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
  Industry 43
 
    IsValidIndustry(): true
 
    GetName():         Tunford Iron Ore Mine
 
    GetLocation():     41155
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
	   GetLastMonthProduction():  96
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
  Industry 44
 
    IsValidIndustry(): true
 
    GetName():         Chentfingbourne Iron Ore Mine
 
    GetLocation():     19529
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
	   GetLastMonthProduction():  120
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
  Industry 45
 
    IsValidIndustry(): true
 
    GetName():         Naborough Farm
 
    GetLocation():     52931
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
	   GetLastMonthProduction():  81
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
	   GetLastMonthProduction():  81
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
  Industry 46
 
    IsValidIndustry(): true
 
    GetName():         Lardborough Farm
 
    GetLocation():     59604
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
	   GetLastMonthProduction():  72
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
	   GetLastMonthProduction():  40
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
  Industry 47
 
    IsValidIndustry(): true
 
    GetName():         Chentfingbourne Farm
 
    GetLocation():     24366
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
	   GetLastMonthProduction():  56
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
	   GetLastMonthProduction():  24
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
  Industry 48
 
    IsValidIndustry(): true
 
    GetName():         Wrundtown Farm
 
    GetLocation():     36847
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
	   GetLastMonthProduction():  72
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
	   GetLastMonthProduction():  126
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
  Industry 49
 
    IsValidIndustry(): true
 
    GetName():         Little Fruford Farm
 
    GetLocation():     28287
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
	   GetLastMonthProduction():  90
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
	   GetLastMonthProduction():  40
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
  Industry 50
 
    IsValidIndustry(): true
 
    GetName():         Hutfingford Farm
 
    GetLocation():     57432
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
	   GetLastMonthProduction():  117
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
	   GetLastMonthProduction():  90
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
  Industry 51
 
    IsValidIndustry(): true
 
    GetName():         Tondston Farm
 
    GetLocation():     23519
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
	   GetLastMonthProduction():  72
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
	   GetLastMonthProduction():  48
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
  Industry 52
 
    IsValidIndustry(): true
 
    GetName():         Nuntfingburg Farm
 
    GetLocation():     10773
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
	   GetLastMonthProduction():  126
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
	   GetLastMonthProduction():  63
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
  Industry 53
 
    IsValidIndustry(): true
 
    GetName():         Sadtown Farm
 
    GetLocation():     48206
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
	   GetLastMonthProduction():  50
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
	   GetLastMonthProduction():  50
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
  Industry 54
 
    IsValidIndustry(): true
 
    GetName():         Quartfingfield Farm
 
    GetLocation():     24005
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
	   GetLastMonthProduction():  64
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
	   GetLastMonthProduction():  72
 
	   GetLastMonthTransported(): 0
 
	   GetStockpiledCargo():      -1
 
  Industry 55
 
    IsValidIndustry(): true
 
    GetName():         Little Fruford Steel Mill
 
    GetLocation():     21107
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
  Industry 56
 
    IsValidIndustry(): true
 
    GetName():         Quartfingfield Steel Mill
 
    GetLocation():     23727
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
  Industry 57
 
    IsValidIndustry(): true
 
    GetName():         Bedburg Steel Mill
 
    GetLocation():     41813
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
  Industry 58
 
    IsValidIndustry(): true
 
    GetName():         Franinghead Steel Mill
 
    GetLocation():     8852
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
  Industry 59
 
    IsValidIndustry(): true
 
    GetName():         Lardborough Steel Mill
 
    GetLocation():     59867
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
  Industry 60
 
    IsValidIndustry(): true
 
    GetName():         Sadtown Steel Mill
 
    GetLocation():     55360
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
  Industry 61
 
    IsValidIndustry(): true
 
    GetName():         Fraston Steel Mill
 
    GetLocation():     52953
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
  Industry 62
 
    IsValidIndustry(): true
 
    GetName():         Chentfingbourne Factory
 
    GetLocation():     24893
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
  Industry 63
 
    IsValidIndustry(): true
 
    GetName():         Fort Frindston Factory
 
    GetLocation():     20819
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
  Industry 64
 
    IsValidIndustry(): true
 
    GetName():         Fudinghattan Factory
 
    GetLocation():     46278
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
  Industry 65
 
    IsValidIndustry(): true
 
    GetName():         Prundinghall Factory
 
    GetLocation():     53096
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
  Industry 66
 
    IsValidIndustry(): true
 
    GetName():         Kennville Factory
 
    GetLocation():     14818
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
  Industry 67
 
    IsValidIndustry(): true
 
    GetName():         Muningville Factory
 
    GetLocation():     34375
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
  Industry 68
 
    IsValidIndustry(): true
 
    GetName():         Trenningville Factory
 
    GetLocation():     44181
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
  Industry 69
 
    IsValidIndustry(): true
 
    GetName():         Wrundtown Oil Refinery
 
    GetLocation():     39663
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
  Industry 70
 
    IsValidIndustry(): true
 
    GetName():         Mendingston Power Station
 
    GetLocation():     6498
 
    GetProduction():   -1
 
    IsCargoAccepted(): true
 
  Industry 71
 
    IsValidIndustry(): false
 
    GetName():         (null : 0x00000000)
 
    GetLocation():     -1
 
    GetProduction():   -1
 
    IsCargoAccepted(): false
 
  Valid Industries:    71
 
  GetIndustryCount():  71
 

	
 
--IndustryList--
 
  Count():             71
 
  Location ListDump:
 
    42 => 60866
 
    9 => 60050
 
    59 => 59867
 
    46 => 59604
 
    50 => 57432
 
    19 => 57429
 
    5 => 55429
 
    60 => 55360
 
    10 => 54184
 
    65 => 53096
 
    61 => 52953
 
    45 => 52931
 
    15 => 51854
 
    12 => 51419
 
    11 => 48499
 
    53 => 48206
 
    25 => 48182
 
    40 => 47838
 
    64 => 46278
 
    1 => 45122
 
    3 => 44640
 
    68 => 44181
 
    31 => 44160
 
    23 => 43035
 
    2 => 41929
 
    57 => 41813
 
    43 => 41155
 
    69 => 39663
 
    36 => 36908
 
    48 => 36847
 
    34 => 36728
 
    67 => 34375
 
    37 => 34237
 
    26 => 33934
 
    21 => 29147
 
    30 => 29022
 
    49 => 28287
 
    22 => 27822
 
    7 => 27609
 
    39 => 25545
 
    62 => 24893
 
    47 => 24366
 
    54 => 24005
 
    56 => 23727
 
    27 => 23714
 
    18 => 23682
 
    51 => 23519
 
    55 => 21107
 
    63 => 20819
 
    28 => 20170
 
    14 => 20001
 
    0 => 19695
 
    44 => 19529
 
    24 => 17943
 
    38 => 17742
 
    8 => 17318
 
    13 => 15950
 
    66 => 14818
 
    32 => 14701
 
    35 => 14361
 
    17 => 13947
 
    16 => 11734
 
    52 => 10773
 
    58 => 8852
 
    4 => 8793
 
    41 => 8763
 
    20 => 8562
 
    29 => 6685
 
    6 => 6533
 
    70 => 6498
 
    33 => 5659
 
  DistanceManhattanToTile(30000) ListDump:
 
    59 => 287
 
    46 => 279
 
    42 => 266
 
    61 => 258
 
    12 => 254
 
    40 => 243
 
    66 => 238
 
    16 => 238
 
    45 => 236
 
    0 => 232
 
    69 => 228
 
    48 => 217
 
    9 => 215
 
    10 => 214
 
    64 => 213
 
    51 => 201
 
    2 => 199
 
    28 => 193
 
    43 => 190
 
    5 => 184
 
    58 => 183
 
    15 => 179
 
    7 => 179
 
    6 => 177
 
    21 => 175
 
    54 => 173
 
    39 => 171
 
    8 => 168
 
    37 => 157
 
    68 => 156
 
    56 => 152
 
    20 => 150
 
    50 => 147
 
    65 => 146
 
    19 => 144
 
    70 => 142
 
    27 => 139
 
    11 => 139
 
    17 => 138
 
    31 => 135
 
    22 => 135
 
    4 => 124
 
    32 => 121
 
    33 => 116
 
    60 => 115
 
    29 => 110
 
    26 => 109
 
    18 => 107
 
    3 => 105
 
    55 => 102
 
    52 => 102
 
    53 => 101
 
    34 => 98
 
    41 => 94
 
    49 => 86
 
    13 => 85
 
    35 => 84
 
    57 => 83
 
    38 => 78
 
    25 => 77
 
    1 => 77
 
    24 => 72
 
    23 => 72
 
    63 => 71
 
    44 => 66
 
    14 => 54
 
    30 => 50
 
    67 => 40
 
    62 => 33
 
    36 => 31
 
    47 => 24
 
  DistanceSquareToTile(30000) ListDump:
 
    59 => 42697
 
    46 => 40121
 
    0 => 38162
 
    69 => 37850
 
    48 => 37157
 
    61 => 36482
 
    12 => 36130
 
    42 => 35716
 
    66 => 35284
 
    40 => 35037
 
    16 => 32740
 
    51 => 31301
 
    45 => 29530
 
    21 => 29257
 
    7 => 28661
 
    64 => 26469
 
    2 => 25525
 
    28 => 25237
 
    39 => 23733
 
    43 => 23458
 
    9 => 23293
 
    10 => 23236
 
    54 => 22777
 
    37 => 20137
 
    5 => 17026
 
    58 => 16889
 
    56 => 16754
 
    8 => 16424
 
    15 => 16061
 
    22 => 15957
 
    6 => 15689
 
    27 => 13621
 
    68 => 13226
 
    50 => 13049
 
    19 => 12818
 
    20 => 11412
 
    65 => 11236
 
    70 => 10964
 
    60 => 10057
 
    11 => 9673
 
    17 => 9594
 
    33 => 9466
 
    31 => 9425
 
    26 => 9061
 
    29 => 8642
 
    4 => 8570
 
    18 => 7349
 
    32 => 7321
 
    41 => 7010
 
    52 => 6354
 
    49 => 6290
 
    53 => 5941
 
    34 => 5860
 
    55 => 5714
 
    3 => 5553
 
    25 => 5077
 
    35 => 4250
 
    13 => 3925
 
    1 => 3805
 
    57 => 3485
 
    38 => 3204
 
    23 => 3042
 
    24 => 2834
 
    63 => 2521
 
    44 => 2306
 
    30 => 2132
 
    14 => 1746
 
    67 => 818
 
    36 => 745
 
    62 => 569
 
    47 => 488
 
  GetAmountOfStationsAround(30000) ListDump:
 
    70 => 0
 
    69 => 0
 
    68 => 0
 
    67 => 0
 
    66 => 0
 
    65 => 0
 
    64 => 0
 
    63 => 0
 
    62 => 0
 
    61 => 0
 
    60 => 0
 
    59 => 0
 
    58 => 0
 
    57 => 0
 
    56 => 0
 
    55 => 0
 
    54 => 0
 
    53 => 0
 
    52 => 0
 
    51 => 0
 
    50 => 0
 
    49 => 0
 
    48 => 0
 
    47 => 0
 
    46 => 0
 
    45 => 0
 
    44 => 0
 
    43 => 0
 
    42 => 0
 
    41 => 0
 
    40 => 0
 
    39 => 0
 
    38 => 0
 
    37 => 0
 
    36 => 0
 
    35 => 0
 
    34 => 0
 
    33 => 0
 
    32 => 0
 
    31 => 0
 
    30 => 0
 
    29 => 0
 
    28 => 0
 
    27 => 0
 
    26 => 0
 
    25 => 0
 
    24 => 0
 
    23 => 0
 
    22 => 0
 
    21 => 0
 
    20 => 0
 
    19 => 0
 
    18 => 0
 
    17 => 0
 
    16 => 0
 
    15 => 0
 
    14 => 0
 
    13 => 0
 
    12 => 0
 
    11 => 0
 
    10 => 0
 
    9 => 0
 
    8 => 0
 
    7 => 0
 
    6 => 0
 
    5 => 0
 
    4 => 0
 
    3 => 0
 
    2 => 0
 
    1 => 0
 
    0 => 0
 
  CargoAccepted(1) ListDump:
 
    70 => 1
 
    31 => 1
 
    30 => 1
 
    29 => 1
 
    28 => 1
 
    27 => 1
 
    26 => 1
 
    25 => 1
 
    69 => 0
 
    68 => 0
 
    67 => 0
 
    66 => 0
 
    65 => 0
 
    64 => 0
 
    63 => 0
 
    62 => 0
 
    61 => 0
 
    60 => 0
 
    59 => 0
 
    58 => 0
 
    57 => 0
 
    56 => 0
 
    55 => 0
 
    54 => 0
 
    53 => 0
 
    52 => 0
 
    51 => 0
 
    50 => 0
 
    49 => 0
 
    48 => 0
 
    47 => 0
 
    46 => 0
 
    45 => 0
 
    44 => 0
 
    43 => 0
 
    42 => 0
 
    41 => 0
 
    40 => 0
 
    39 => 0
 
    38 => 0
 
    37 => 0
 
    36 => 0
 
    35 => 0
 
    34 => 0
 
    33 => 0
 
    32 => 0
 
    24 => 0
 
    23 => 0
 
    22 => 0
 
    21 => 0
 
    20 => 0
 
    19 => 0
 
    18 => 0
 
    17 => 0
 
    16 => 0
 
    15 => 0
 
    14 => 0
 
    13 => 0
 
    12 => 0
 
    11 => 0
 
    10 => 0
 
    9 => 0
 
    8 => 0
 
    7 => 0
 
    6 => 0
 
    5 => 0
 
    4 => 0
 
    3 => 0
 
    2 => 0
 
    1 => 0
 
    0 => 0
 
  KeepAboveValue(50): done
 
  Count():             9
 
  Production ListDump:
 
    20 => 152
 
    17 => 152
 
    22 => 136
 
    18 => 112
 
    21 => 104
 
    15 => 104
 
    16 => 96
 
    19 => 88
 
    23 => 80
 
--IndustryList_CargoAccepting--
 
  Count():             8
 
  Location ListDump:
 
    25 => 48182
 
    31 => 44160
 
    26 => 33934
 
    30 => 29022
 
    27 => 23714
 
    28 => 20170
 
    29 => 6685
 
    70 => 6498
 
--IndustryList_CargoProducing--
 
  Count():             10
 
  Location ListDump:
 
    19 => 57429
 
    15 => 51854
 
    23 => 43035
 
    21 => 29147
 
    22 => 27822
 
    18 => 23682
 
    24 => 17943
 
    17 => 13947
 
    16 => 11734
 
    20 => 8562
 

	
 
--IndustryTypeList--
 
  Count():             12
 
  Location ListDump:
 
    Id:                      9
 
    IsRawIndustry():         true
 
    ProductionCanIncrease(): true
 
    GetConstructionCost():   823289
 
    GetName():               Farm
 
    CanBuildIndustry():      false
 
    CanProspectIndustry():   false
 
    Id:                      5
 
    IsRawIndustry():         true
 
    ProductionCanIncrease(): true
 
    GetConstructionCost():   823289
 
    GetName():               Oil Rig
 
    CanBuildIndustry():      false
 
    CanProspectIndustry():   false
 
    Id:                      12
 
    IsRawIndustry():         false
 
    ProductionCanIncrease(): true
 
    GetConstructionCost():   823289
 
    GetName():               Bank
 
    CanBuildIndustry():      true
 
    CanProspectIndustry():   false
 
    Id:                      11
 
    IsRawIndustry():         true
 
    ProductionCanIncrease(): false
 
    GetConstructionCost():   823289
 
    GetName():               Oil Wells
 
    CanBuildIndustry():      false
 
    CanProspectIndustry():   false
 
    Id:                      1
 
    IsRawIndustry():         false
 
    ProductionCanIncrease(): true
 
    GetConstructionCost():   774860
 
    GetName():               Power Station
 
    CanBuildIndustry():      true
 
    CanProspectIndustry():   false
 
    Id:                      3
 
    IsRawIndustry():         true
 
    ProductionCanIncrease(): true
 
    GetConstructionCost():   823289
 
    GetName():               Forest
 
    CanBuildIndustry():      false
 
    CanProspectIndustry():   false
 
    Id:                      2
 
    IsRawIndustry():         false
 
    ProductionCanIncrease(): true
 
    GetConstructionCost():   723203
 
    GetName():               Sawmill
 
    CanBuildIndustry():      true
 
    CanProspectIndustry():   false
 
    Id:                      18
 
    IsRawIndustry():         true
 
    ProductionCanIncrease(): true
 
    GetConstructionCost():   823289
 
    GetName():               Iron Ore Mine
 
    CanBuildIndustry():      false
 
    CanProspectIndustry():   false
 
    Id:                      0
 
    IsRawIndustry():         true
 
    ProductionCanIncrease(): true
 
    GetConstructionCost():   823289
 
    GetName():               Coal Mine
 
    CanBuildIndustry():      false
 
    CanProspectIndustry():   false
 
    Id:                      8
 
    IsRawIndustry():         false
 
    ProductionCanIncrease(): true
 
    GetConstructionCost():   694145
 
    GetName():               Steel Mill
 
    CanBuildIndustry():      true
 
    CanProspectIndustry():   false
 
    Id:                      4
 
    IsRawIndustry():         false
 
    ProductionCanIncrease(): true
 
    GetConstructionCost():   787774
 
    GetName():               Oil Refinery
 
    CanBuildIndustry():      true
 
    CanProspectIndustry():   false
 
    Id:                      6
 
    IsRawIndustry():         false
 
    ProductionCanIncrease(): true
 
    GetConstructionCost():   671545
 
    GetName():               Factory
 
    CanBuildIndustry():      true
 
    CanProspectIndustry():   false
 

	
 
--Map--
 
  GetMapSize():     65536
 
  GetMapSizeX():    256
 
  GetMapSizeY():    256
 
  GetTileX(123):    123
 
  GetTileY(123):    0
 
  GetTileIndex():   123
 
  GetTileIndex():   31488
 
  GetTileIndex():   0
 
  GetTileIndex():   -257
 
  GetTileIndex():   2570000
 
  IsValidTile(123): true
 
  GetTileX(124):    124
 
  GetTileY(124):    0
 
  IsValidTile(124): true
 
  IsValidTile(0):   true
 
  IsValidTile(-1):  false
 
  IsValidTile():    false
 
  IsValidTile():    true
 
  DemolishTile():   false
 
  DemolishTile():   true
 
  Distance
 
    DistanceManhattan(): 54
 
    DistanceMax():       39
 
    DistanceSquare():    1746
 
    DistanceFromEdge():  16
 

	
 
--AIMarine--
 
  IsWaterDepotTile():   false
 
  IsDockTile():         false
 
  IsBuoyTile():         false
 
  IsLockTile():         false
 
  IsCanalTile():        false
 
  GetBankBalance():     766678
 
  BuildWaterDepot():    true
 
  BuildDock():          true
 
  BuildBuoy():          true
 
  BuildLock():          true
 
  HasTransportType():   false
 
  BuildCanal():         true
 
  HasTransportType():   true
 
  IsWaterDepotTile():   true
 
  IsDockTile():         true
 
  IsBuoyTile():         true
 
  IsLockTile():         true
 
  IsCanalTile():        true
 
  GetBankBalance():     805921
 
  RemoveWaterDepot():   true
 
  RemoveDock():         true
 
  RemoveBuoy():         true
 
  RemoveLock():         true
 
  RemoveCanal():        true
 
  IsWaterDepotTile():   false
 
  IsDockTile():         false
 
  IsBuoyTile():         false
 
  IsLockTile():         false
 
  IsCanalTile():        false
 
  GetBankBalance():     855517
 
  BuildWaterDepot():    true
 
  BuildDock():          true
 

	
 
--PathFinder--
 
  Road Between Towns:
 
    Tile 46751
 
    Tile 46495
 
    Tile 46239
 
    Tile 45983
 
    Tile 45727
 
    Tile 45471
 
    Tile 45470
 
    Tile 45469
 
    Tile 45468
 
    Tile 45467
 
    Tile 45466
 
    Tile 45210
 
    Tile 44954
 
    Tile 44698
 
    Tile 44442
 
    Tile 44186
 
    Tile 43930
 
    Tile 43929
 
    Tile 43928
 
    Tile 43927
 
    Tile 43926
 
    Tile 43925
 
    Tile 43669
 
    Tile 43413
 
    Tile 43157
 
    Tile 42901
 
    Tile 42645
 
    Tile 42389
 
    Tile 42133
 
    Tile 41877
 
    Tile 41621
 
    Tile 41365
 
    Tile 41109
 
    Tile 40853
 
    Tile 40597
 
    Tile 40341
 
    Tile 40085
 
    Tile 39829
 
    Tile 39573
 
    Tile 39317
 
    Tile 39061
 
    Tile 38805
 
    Tile 38549
 
    Tile 38293
 
    Tile 38037
 
    Tile 37781
 
    Tile 37525
 
    Tile 37269
 
    Tile 37013
 
    Tile 36757
 
    Tile 36501
 
    Tile 36245
 
    Tile 35989
 
    Tile 35733
 
    Tile 35477
 
    Tile 35221
 
    Tile 34965
 
    Tile 34709
 
    Tile 34453
 
    Tile 34197
 
    Tile 33941
 
    Tile 33685
 
    Tile 33429
 
    Tile 33173
 
    Tile 32917
 
    Tile 32661
 
    Tile 32405
 
    Tile 32149
 
    Tile 31893
 
    Tile 31637
 
    Tile 31381
 
    Tile 31125
 
    Tile 30869
 
    Tile 30613
 
    Tile 30357
 
    Tile 30101
 
    Tile 29845
 
    Tile 29589
 
    Tile 29333
 
    Tile 29077
 
    Tile 28821
 
    Tile 28565
 
    Tile 28309
 
    Tile 28053
 
    Tile 27797
 
    Tile 27541
 
    Tile 27285
 
    Tile 27029
 
    Tile 26773
 
    Tile 26517
 
    Tile 26261
 
    Tile 26005
 
    Tile 25749
 
    Tile 25493
 
    Tile 25237
 
    Tile 24981
 
    Tile 24725
 
    Tile 24469
 
    Tile 24213
 
    Tile 23957
 
    Tile 23701
 
    Tile 23445
 
    Tile 23189
 
    Tile 22933
 
    Tile 22677
 
    Tile 22421
 
    Tile 22165
 
    Tile 21909
 
    Tile 21653
 
    Tile 21397
 
    Tile 21141
 
    Tile 20885
 
    Tile 20629
 
    Tile 20373
 
    Tile 20117
 
    Tile 19861
 
    Tile 19605
 
    Tile 19349
 
    Tile 19093
 
    Tile 18837
 
    Tile 18581
 
    Tile 18325
 
    Tile 18069
 
    Tile 17813
 
    Tile 17557
 
    Tile 17301
 
    Tile 17045
 
    Tile 16789
 
    Tile 16533
 
    Tile 16277
 
    Tile 16021
 
    Tile 15765
 
    Tile 15509
 
    Tile 15508
 

	
 
--PriorityQueue--
 
  Count(): 0
 
  Peek():  (null : 0x00000000)
 
  Pop():   (null : 0x00000000)
 
  Count(): 9
 
  Peek():  1
 
  Pop():   1
 
  Pop():   4
 
  Pop():   3
 
  Pop():   2
 
  Pop():   1
 
  Pop():   5
 
  Pop():   6
 
  Pop():   7
 
  Pop():   8
 
  Pop():   9
 
  Pop():   10
 
  Peek():  (null : 0x00000000)
 
  Pop():   (null : 0x00000000)
 
  Count(): 0
 

	
 
--BinaryHeap--
 
  Count(): 0
 
  Peek():  (null : 0x00000000)
 
  Pop():   (null : 0x00000000)
 
  Count(): 9
 
  Peek():  1
 
  Pop():   1
 
  Pop():   3
 
  Pop():   4
 
  Pop():   2
 
  Pop():   1
 
  Pop():   5
 
  Pop():   6
 
  Pop():   7
 
  Pop():   8
 
  Pop():   9
 
  Pop():   10
 
  Peek():  (null : 0x00000000)
 
  Pop():   (null : 0x00000000)
 
  Count(): 0
 

	
 
--FibonacciHeap--
 
  Count(): 0
 
  Peek():  (null : 0x00000000)
 
  Pop():   (null : 0x00000000)
 
  Count(): 9
 
  Peek():  1
 
  Pop():   1
 
  Pop():   4
 
  Pop():   3
 
  Pop():   2
 
  Pop():   1
 
  Pop():   5
 
  Pop():   6
 
  Pop():   7
 
  Pop():   8
 
  Pop():   9
 
  Pop():   10
 
  Peek():  (null : 0x00000000)
 
  Pop():   (null : 0x00000000)
 
  Count(): 0
 

	
 
--Rail--
 
    IsRailTile():                  false
 
    BuildRailTrack():              true
 
    BuildSignal():                 true
 
    RemoveRailTrack():             false
 
    RemoveRailTrack():             true
 
    BuildRail():                   true
 
    HasTransportType():            true
 
    HasTransportType():            false
 
    RemoveRail():                  true
 
  Depot
 
    IsRailTile():                  false
 
    BuildRailDepot():              false
 
    BuildRailDepot():              false
 
    BuildRailDepot():              true
 
    BuildRailDepot():              false
 
    GetRailDepotFrontTile():       33412
 
    IsBuildable():                 false
 
    DepotList
 
      Count():                     1
 
      Depot distance from (0,0) ListDump:
 
        33411 => 261
 
    RemoveDepot():                 true
 
  Station
 
    BuildRailStation():            false
 
    BuildRailStation():            true
 
    IsRailStationTile():           false
 
    IsRailStationTile():           true
 
    IsRailStationTile():           true
 
    RemoveRailStationTileRect():   true
 
    IsRailStationTile():           false
 
    IsRailStationTile():           true
 
    IsRailStationTile():           false
 
    DemolishTile():                true
 
    IsRailStationTile():           false
 
    IsRailStationTile():           false
 
    IsRailStationTile():           false
 

	
 
--RailTypeList--
 
  Count():             1
 
  ListDump:
 
    RailType:                0
 
    IsRailTypeAvailable():   true
 

	
 
--Road--
 
  Road
 
    IsRoadTile():                  false
 
    BuildRoad():                   false
 
    BuildRoad():                   false
 
    HasTransportType():            false
 
    BuildRoad():                   true
 
    HasTransportType():            true
 
    AreRoadTilesConnected():       true
 
    IsRoadTile():                  true
 
    HasRoadType(Road):             true
 
    HasRoadType(Tram):             false
 
    GetNeighbourRoadCount():       2
 
    RemoveRoad():                  true
 
    RemoveRoad():                  true
 
    RemoveRoad():                  false
 
    RemoveRoad():                  true
 
    BuildOneWayRoad():             true
 
    AreRoadTilesConnected():       true
 
    AreRoadTilesConnected():       false
 
    BuildOneWayRoad():             true
 
    AreRoadTilesConnected():       false
 
    AreRoadTilesConnected():       false
 
    BuildOneWayRoad():             true
 
    BuildOneWayRoad():             true
 
    AreRoadTilesConnected():       true
 
    AreRoadTilesConnected():       true
 
    RemoveRoad():                  true
 
    IsRoadTypeAvailable(Road):     true
 
    IsRoadTypeAvailable(Tram):     false
 
    SetCurrentRoadType(Tram):      (null : 0x00000000)
 
    GetCurrentRoadType():          0
 
  Depot
 
    IsRoadTile():                  false
 
    BuildRoadDepot():              false
 
    BuildRoadDepot():              false
 
    BuildRoadDepot():              true
 
    BuildRoadDepot():              false
 
    HasRoadType(Road):             true
 
    HasRoadType(Tram):             false
 
    GetLastError():                260
 
    GetLastErrorString():          ERR_AREA_NOT_CLEAR
 
    GetErrorCategory():            1
 
    IsRoadTile():                  false
 
    GetRoadDepotFrontTile():       33412
 
    IsRoadDepotTile():             true
 
    IsBuildable():                 false
 
    DepotList
 
      Count():                     1
 
      Depot distance from (0,0) ListDump:
 
        33411 => 261
 
    RemoveRoadDepot():             true
 
    RemoveRoadDepot():             false
 
  Station
 
    IsRoadTile():                  false
 
    BuildRoadStation():            false
 
    BuildRoadStation():            false
 
    BuildRoadStation():            true
 
    BuildRoadStation():            false
 
    IsStationTile():               true
 
    IsStationTile():               false
 
    HasRoadType(Road):             true
 
    HasRoadType(Tram):             false
 
    IsRoadTile():                  false
 
    GetDriveThroughBackTile():     -1
 
    GetRoadStationFrontTile():     33412
 
    IsRoadStationTile():           true
 
    IsDriveThroughRoadStationTile: false
 
    RemoveRoadStation():           true
 
    RemoveRoadStation():           false
 
  Station Types
 
    BuildRoadStation(bus):         true
 
    BuildRoadStation(truck):       true
 
    BuildRoadStation(truck):       true
 
    BuildRoadStation(bus):         true
 
    BuildRoadStation(truck):       true
 
    BuildRoadStation(bus-drive):   true
 
    BuildRoadStation(truck-drive): true
 
    BuildRoadStation(bus-drive):   true
 
    BuildRoadStation(truck-drive): true
 
    BuildRoadDepot():              true
 
    GetRoadStationFrontTile():     33411
 
    GetRoadStationFrontTile():     33924
 
    IsDriveThroughRoadStationTile: true
 
    IsBuildable():                 false
 
    GetDriveThroughBackTile():     33416
 
    GetRoadStationFrontTile():     33414
 
    IsRoadTile():                  true
 

	
 
--Sign--
 
  BuildSign(33410, 'Some Sign'):       0
 
  BuildSign(33411, 'Test'):            1
 
  SetName(1, 'Test2'):                 true
 
  BuildSign(33409, 'Some other Sign'): 2
 
  RemoveSign(2):                       true
 

	
 
  GetMaxSignID():    3
 
  Sign -1
 
    IsValidSign():   false
 
    GetName():       (null : 0x00000000)
 
    GetLocation():   -1
 
  Sign 0
 
    IsValidSign():   true
 
    GetName():       Some Sign
 
    GetLocation():   33410
 
  Sign 1
 
    IsValidSign():   true
 
    GetName():       Test2
 
    GetLocation():   33411
 
  Sign 2
 
    IsValidSign():   false
 
    GetName():       (null : 0x00000000)
 
    GetLocation():   -1
 
  Sign 3
 
    IsValidSign():   false
 
    GetName():       (null : 0x00000000)
 
    GetLocation():   -1
 
  Valid Signs:       2
 

	
 
--Station--
 
  IsValidStation(0):        true
 
  IsValidStation(1000):     false
 
  GetName(0):               Benville Airport
 
  SetName(0):               true
 
  GetName(0):               Look, a station
 
  GetLocation(1):           29253
 
  GetLocation(1000):        -1
 
  GetStationID(33411):      3
 
  GetStationID(34411):      65535
 
  GetCargoWaiting(0, 0):    0
 
  GetCargoWaiting(1000, 0): -1
 
  GetCargoWaiting(0, 1000): -1
 
  GetStationID(33411):      3
 
  HasRoadType(3, TRAM):     false
 
  HasRoadType(3, ROAD):     true
 
  HasRoadType(33411, TRAM): false
 
  HasRoadType(33411, ROAD): true
 
  HasStationType(3, BUS):   true
 
  HasStationType(3, TRAIN): false
 
  GetCoverageRadius(BUS):   3
 
  GetCoverageRadius(TRUCK): 3
 
  GetCoverageRadius(TRAIN): 4
 
  GetNearestTown():         15
 
  GetNearestTown():         65535
 
  GetNearestTown():         24
 

	
 
--StationList--
 
  Count():             2
 
  Location ListDump:
 
    4 => 33421
 
    3 => 33411
 
  CargoWaiting(0) ListDump:
 
    4 => 0
 
    3 => 0
 
  CargoWaiting(1) ListDump:
 
    4 => 0
 
    3 => 0
 

	
 
--Tile--
 
  HasTreeOnTile():      false
 
  IsFarmTile():         true
 
  IsRockTile():         true
 
  IsRoughTile():        true
 
  HasTreeOnTile():      true
 
  IsFarmTile():         false
 
  IsRockTile():         false
 
  IsRoughTile():        false
 
  IsSnowTile():         false
 
  IsDesertTile():       false
 
  PlantTree():          true
 
  HasTreeOnTile():      true
 
  PlantTree():          false
 
  HasTreeOnTile():      true
 
  PlantTreeRectangle(): true
 
  HasTreeOnTile():      true
 

	
 
--TileList--
 
  Count():             0
 
  Count():             9
 
  Slope():             done
 
  Count():             9
 
  ListDump:
 
    27631 => 29
 
    27631 => 255
 
    27631 => true
 
    27631 => false
 
    27888 => 13
 
    27888 => 2
 
    27888 => false
 
    27888 => false
 
    27376 => 12
 
    27376 => 3
 
    27376 => false
 
    27376 => false
 
    27375 => 12
 
    27375 => 3
 
    27375 => false
 
    27375 => false
 
    27889 => 9
 
    27889 => 6
 
    27889 => false
 
    27889 => false
 
    27887 => 8
 
    27887 => 7
 
    27887 => false
 
    27887 => false
 
    27632 => 8
 
    27632 => 7
 
    27632 => false
 
    27632 => false
 
    27633 => 0
 
    27633 => 15
 
    27633 => false
 
    27633 => false
 
    27377 => 0
 
    27377 => 15
 
    27377 => false
 
    27377 => false
 

	
 
--TileList--
 
  Count():             0
 
  Count():             45
 
  Height():            done
 
  Count():             45
 
  ListDump:
 
    42411 => 2
 
    42410 => 2
 
    42409 => 2
 
    42408 => 2
 
    42407 => 2
 
    42154 => 2
 
    42153 => 2
 
    42152 => 2
 
    42151 => 2
 
    41898 => 2
 
    41897 => 2
 
    41896 => 2
 
    41895 => 2
 
    41642 => 2
 
    41641 => 2
 
    41640 => 2
 
    41639 => 2
 
    41386 => 2
 
    41385 => 2
 
    41384 => 2
 
    41383 => 2
 
    42415 => 1
 
    42414 => 1
 
    42413 => 1
 
    42412 => 1
 
    42159 => 1
 
    42158 => 1
 
    42157 => 1
 
    42156 => 1
 
    42155 => 1
 
    41903 => 1
 
    41902 => 1
 
    41901 => 1
 
    41900 => 1
 
    41899 => 1
 
    41647 => 1
 
    41646 => 1
 
    41645 => 1
 
    41644 => 1
 
    41643 => 1
 
    41391 => 1
 
    41390 => 1
 
    41389 => 1
 
    41388 => 1
 
    41387 => 1
 
  Slope():             done
 
  KeepValue(0):        done
 
  Count():             38
 
  ListDump:
 
    42415 => 0
 
    42414 => 0
 
    42413 => 0
 
    42410 => 0
 
    42409 => 0
 
    42408 => 0
 
    42407 => 0
 
    42159 => 0
 
    42158 => 0
 
    42157 => 0
 
    42156 => 0
 
    42153 => 0
 
    42152 => 0
 
    42151 => 0
 
    41903 => 0
 
    41902 => 0
 
    41901 => 0
 
    41900 => 0
 
    41899 => 0
 
    41897 => 0
 
    41896 => 0
 
    41895 => 0
 
    41647 => 0
 
    41646 => 0
 
    41645 => 0
 
    41644 => 0
 
    41643 => 0
 
    41641 => 0
 
    41640 => 0
 
    41639 => 0
 
    41391 => 0
 
    41390 => 0
 
    41389 => 0
 
    41388 => 0
 
    41387 => 0
 
    41385 => 0
 
    41384 => 0
 
    41383 => 0
 
  Buildable():         done
 
  KeepValue(1):        done
 
  Count():             28
 
  BuildableRectangle(3, 3) ListDump:
 
    42415 => 1
 
    42414 => 1
 
    42413 => 1
 
    42410 => 1
 
    42159 => 1
 
    42158 => 1
 
    42157 => 1
 
    42156 => 1
 
    41903 => 1
 
    41902 => 1
 
    41901 => 1
 
    41900 => 1
 
    41899 => 1
 
    41647 => 1
 
    41646 => 1
 
    41645 => 1
 
    41644 => 1
 
    41643 => 1
 
    41641 => 1
 
    41391 => 1
 
    41390 => 1
 
    41389 => 1
 
    41388 => 1
 
    41387 => 1
 
    41385 => 1
 
    42153 => 0
 
    41897 => 0
 
    41384 => 0
 
  DistanceManhattanToTile(30000) ListDump:
 
    42415 => 175
 
    42414 => 174
 
    42159 => 174
 
    42413 => 173
 
    42158 => 173
 
    41903 => 173
 
    42157 => 172
 
    41902 => 172
 
    41647 => 172
 
    42156 => 171
 
    41901 => 171
 
    41646 => 171
 
    41391 => 171
 
    42410 => 170
 
    41900 => 170
 
    41645 => 170
 
    41390 => 170
 
    41899 => 169
 
    41644 => 169
 
    41389 => 169
 
    42153 => 168
 
    41643 => 168
 
    41388 => 168
 
    41897 => 167
 
    41387 => 167
 
    41641 => 166
 
    41385 => 165
 
    41384 => 164
 
  DistanceSquareToTile(30000) ListDump:
 
    42415 => 18433
 
    42159 => 18338
 
    41903 => 18245
 
    42414 => 18180
 
    41647 => 18154
 
    42158 => 18085
 
    41391 => 18065
 
    41902 => 17992
 
    42413 => 17929
 
    41646 => 17901
 
    42157 => 17834
 
    41390 => 17812
 
    41901 => 17741
 
    41645 => 17650
 
    42156 => 17585
 
    41389 => 17561
 
    41900 => 17492
 
    41644 => 17401
 
    41388 => 17312
 
    41899 => 17245
 
    42410 => 17188
 
    41643 => 17154
 
    41387 => 17065
 
    42153 => 16850
 
    41897 => 16757
 
    41641 => 16666
 
    41385 => 16577
 
    41384 => 16336
 
  GetOwner() ListDump:
 
    42415 => -1
 
    42414 => -1
 
    42413 => -1
 
    42410 => -1
 
    42159 => -1
 
    42158 => -1
 
    42157 => -1
 
    42156 => -1
 
    42153 => -1
 
    41903 => -1
 
    41902 => -1
 
    41901 => -1
 
    41900 => -1
 
    41899 => -1
 
    41897 => -1
 
    41647 => -1
 
    41646 => -1
 
    41645 => -1
 
    41644 => -1
 
    41643 => -1
 
    41641 => -1
 
    41391 => -1
 
    41390 => -1
 
    41389 => -1
 
    41388 => -1
 
    41387 => -1
 
    41385 => -1
 
    41384 => -1
 
  GetClosestTown() ListDump:
 
    42415 => 3
 
    42414 => 3
 
    42413 => 3
 
    42410 => 3
 
    42159 => 3
 
    42158 => 3
 
    42157 => 3
 
    42156 => 3
 
    42153 => 3
 
    41903 => 3
 
    41902 => 3
 
    41901 => 3
 
    41900 => 3
 
    41899 => 3
 
    41897 => 3
 
    41647 => 3
 
    41646 => 3
 
    41645 => 3
 
    41644 => 3
 
    41643 => 3
 
    41641 => 3
 
    41391 => 3
 
    41390 => 3
 
    41389 => 3
 
    41388 => 3
 
    41387 => 3
 
    41385 => 3
 
    41384 => 3
 
  CargoAcceptance():   done
 
  KeepAboveValue(10):  done
 
  Count():             9
 
  ListDump:
 
    41897 => 29
 
    41385 => 26
 
    41384 => 26
 
    42153 => 25
 
    41641 => 23
 
    41899 => 17
 
    41387 => 17
 
    41643 => 14
 
    42410 => 13
 
  RoadTile():          done
 
  KeepValue(1):        done
 
  Count():             0
 
  ListDump:
 
  NeighbourRoadCount():done
 
  KeepValue(1):        done
 
  Count():             0
 
  ListDump:
 
  Water():             done
 
  Count():             45
 
  ListDump:
 
    54941 => 1
 
    54940 => 1
 
    54939 => 1
 
    54938 => 1
 
    54937 => 1
 
    54936 => 1
 
    54935 => 1
 
    54934 => 1
 
    54933 => 1
 
    54685 => 1
 
    54684 => 1
 
    54683 => 1
 
    54682 => 1
 
    54681 => 1
 
    54680 => 1
 
    54679 => 1
 
    54678 => 1
 
    54677 => 1
 
    54429 => 1
 
    54428 => 1
 
    54427 => 1
 
    54426 => 1
 
    54425 => 1
 
    54424 => 1
 
    54423 => 1
 
    54422 => 1
 
    54421 => 1
 
    54173 => 1
 
    54172 => 1
 
    54171 => 1
 
    54170 => 1
 
    54169 => 1
 
    54168 => 0
 
    54167 => 0
 
    54166 => 0
 
    54165 => 0
 
    53917 => 0
 
    53916 => 0
 
    53915 => 0
 
    53914 => 0
 
    53913 => 0
 
    53912 => 0
 
    53911 => 0
 
    53910 => 0
 
    53909 => 0
 

	
 
--TileList_IndustryAccepting--
 
  Count():             47
 
  Location ListDump:
 
    21234 => 16
 
    21233 => 16
 
    21232 => 16
 
    21231 => 16
 
    21230 => 16
 
    21229 => 16
 
    20978 => 16
 
    20977 => 16
 
    20976 => 16
 
    20975 => 16
 
    20974 => 16
 
    20973 => 16
 
    20722 => 16
 
    20718 => 16
 
    20717 => 16
 
    20466 => 16
 
    20462 => 16
 
    20461 => 16
 
    20210 => 16
 
    20206 => 16
 
    20205 => 16
 
    19954 => 16
 
    19950 => 16
 
    19949 => 16
 
    21490 => 8
 
    21489 => 8
 
    21488 => 8
 
    21487 => 8
 
    21486 => 8
 
    21485 => 8
 
    21484 => 8
 
    21235 => 8
 
    21228 => 8
 
    20979 => 8
 
    20972 => 8
 
    20723 => 8
 
    20716 => 8
 
    20467 => 8
 
    20460 => 8
 
    20211 => 8
 
    20204 => 8
 
    19955 => 8
 
    19948 => 8
 
    19699 => 8
 
    19698 => 8
 
    19694 => 8
 
    19693 => 8
 

	
 
--TileList_IndustryProducing--
 
  Count():             90
 
  Location ListDump:
 
    46149 => 14
 
    46146 => 14
 
    45894 => 14
 
    45889 => 14
 
    45638 => 14
 
    45633 => 14
 
    45382 => 14
 
    45377 => 14
 
    45126 => 12
 
    45121 => 12
 
    44869 => 12
 
    44868 => 12
 
    44867 => 12
 
    44866 => 12
 
    46150 => 11
 
    46145 => 11
 
    46405 => 10
 
    46404 => 10
 
    46403 => 10
 
    46402 => 10
 
    45895 => 9
 
    45888 => 9
 
    45639 => 9
 
    45632 => 9
 
    45383 => 9
 
    45376 => 9
 
    44870 => 9
 
    44865 => 9
 
    46406 => 8
 
    46401 => 8
 
    45127 => 8
 
    45120 => 8
 
    44613 => 8
 
    44612 => 8
 
    44611 => 8
 
    44610 => 8
 
    46151 => 7
 
    46144 => 7
 
    46661 => 6
 
    46660 => 6
 
    46659 => 6
 
    46658 => 6
 
    44871 => 6
 
    44864 => 6
 
    44614 => 6
 
    44609 => 6
 
    46662 => 5
 
    46657 => 5
 
    46407 => 5
 
    46400 => 5
 
    45896 => 4
 
    45887 => 4
 
    45640 => 4
 
    45631 => 4
 
    45384 => 4
 
    45375 => 4
 
    45128 => 4
 
    45119 => 4
 
    44615 => 4
 
    44608 => 4
 
    44357 => 4
 
    44356 => 4
 
    44355 => 4
 
    44354 => 4
 
    46663 => 3
 
    46656 => 3
 
    46152 => 3
 
    46143 => 3
 
    44872 => 3
 
    44863 => 3
 
    44358 => 3
 
    44353 => 3
 
    46918 => 2
 
    46917 => 2
 
    46916 => 2
 
    46915 => 2
 
    46914 => 2
 
    46913 => 2
 
    46408 => 2
 
    46399 => 2
 
    44616 => 2
 
    44607 => 2
 
    44359 => 2
 
    44352 => 2
 
    46919 => 1
 
    46912 => 1
 
    46664 => 1
 
    46655 => 1
 
    44360 => 1
 
    44351 => 1
 

	
 
--TileList_StationType--
 
  Count():             0
 
  Location ListDump:
 

	
 
--Town--
 
  GetMaxTownID():    31
 
  GetTownCount():    28
 
  Town -1
 
    IsValidTown():   false
 
    GetName():       (null : 0x00000000)
 
    GetPopulation(): -1
 
    GetLocation():   -1
 
    GetHouseCount(): -1
 
    GetRating():     -1
 
  Town 0
 
    IsValidTown():   true
 
    GetName():       Planfield
 
    GetPopulation(): 757
 
    GetLocation():   15508
 
    GetHouseCount(): 30
 
    GetRating():     5
 
  Town 1
 
    IsValidTown():   true
 
    GetName():       Trenningville
 
    GetPopulation(): 343
 
    GetLocation():   46751
 
    GetHouseCount(): 17
 
    GetRating():     5
 
  Town 2
 
    IsValidTown():   true
 
    GetName():       Tondston
 
    GetPopulation(): 380
 
    GetLocation():   28365
 
    GetHouseCount(): 19
 
    GetRating():     0
 
  Town 3
 
    IsValidTown():   true
 
    GetName():       Tunford
 
    GetPopulation(): 176
 
    GetLocation():   41895
 
    GetHouseCount(): 11
 
    GetRating():     5
 
  Town 4
 
    IsValidTown():   true
 
    GetName():       Wrundtown
 
    GetPopulation(): 426
 
    GetLocation():   41450
 
    GetHouseCount(): 18
 
    GetRating():     0
 
  Town 5
 
    IsValidTown():   true
 
    GetName():       Fraston
 
    GetPopulation(): 205
 
    GetLocation():   55007
 
    GetHouseCount(): 11
 
    GetRating():     0
 
  Town 6
 
    IsValidTown():   true
 
    GetName():       Muningville
 
    GetPopulation(): 679
 
    GetLocation():   38200
 
    GetHouseCount(): 28
 
    GetRating():     0
 
  Town 7
 
    IsValidTown():   true
 
    GetName():       Hutfingford
 
    GetPopulation(): 1006
 
    GetLocation():   59234
 
    GetHouseCount(): 33
 
    GetRating():     0
 
  Town 8
 
    IsValidTown():   true
 
    GetName():       Sadtown
 
    GetPopulation(): 358
 
    GetLocation():   51267
 
    GetHouseCount(): 20
 
    GetRating():     0
 
  Town 9
 
    IsValidTown():   true
 
    GetName():       Frindinghattan
 
    GetPopulation(): 478
 
    GetLocation():   5825
 
    GetHouseCount(): 18
 
    GetRating():     0
 
  Town 10
 
    IsValidTown():   true
 
    GetName():       Nuntfingburg
 
    GetPopulation(): 737
 
    GetLocation():   6446
 
    GetHouseCount(): 26
 
    GetRating():     5
 
  Town 11
 
    IsValidTown():   true
 
    GetName():       Fort Frindston
 
    GetPopulation(): 180
 
    GetLocation():   14935
 
    GetHouseCount(): 13
 
    GetRating():     5
 
  Town 12
 
    IsValidTown():   true
 
    GetName():       Ginborough
 
    GetPopulation(): 982
 
    GetLocation():   32740
 
    GetHouseCount(): 28
 
    GetRating():     0
 
  Town 13
 
    IsValidTown():   true
 
    GetName():       Great Hinninghall
 
    GetPopulation(): 310
 
    GetLocation():   9595
 
    GetHouseCount(): 14
 
    GetRating():     5
 
  Town 14
 
    IsValidTown():   true
 
    GetName():       Prundinghall
 
    GetPopulation(): 432
 
    GetLocation():   51298
 
    GetHouseCount(): 18
 
    GetRating():     0
 
  Town 15
 
    IsValidTown():   true
 
    GetName():       Benville
 
    GetPopulation(): 807
 
    GetLocation():   42338
 
    GetHouseCount(): 33
 
    GetRating():     5
 
  Town 16
 
    IsValidTown():   true
 
    GetName():       Kennville
 
    GetPopulation(): 767
 
    GetLocation():   17345
 
    GetHouseCount(): 33
 
    GetRating():     5
 
  Town 17
 
    IsValidTown():   true
 
    GetName():       Quartfingfield
 
    GetPopulation(): 218
 
    GetLocation():   24252
 
    GetHouseCount(): 13
 
    GetRating():     5
 
  Town 18
 
    IsValidTown():   true
 
    GetName():       Netfingbridge
 
    GetPopulation(): 262
 
    GetLocation():   10574
 
    GetHouseCount(): 13
 
    GetRating():     5
 
  Town 19
 
    IsValidTown():   true
 
    GetName():       Mendingston
 
    GetPopulation(): 243
 
    GetLocation():   6511
 
    GetHouseCount(): 14
 
    GetRating():     0
 
  Town 20
 
    IsValidTown():   true
 
    GetName():       Chentfingbourne
 
    GetPopulation(): 437
 
    GetLocation():   22585
 
    GetHouseCount(): 15
 
    GetRating():     5
 
  Town 21
 
    IsValidTown():   true
 
    GetName():       Franinghead
 
    GetPopulation(): 772
 
    GetLocation():   9634
 
    GetHouseCount(): 27
 
    GetRating():     5
 
  Town 22
 
    IsValidTown():   true
 
    GetName():       Naborough
 
    GetPopulation(): 221
 
    GetLocation():   51891
 
    GetHouseCount(): 12
 
    GetRating():     0
 
  Town 23
 
    IsValidTown():   true
 
    GetName():       Lardborough
 
    GetPopulation(): 752
 
    GetLocation():   59622
 
    GetHouseCount(): 27
 
    GetRating():     0
 
  Town 24
 
    IsValidTown():   true
 
    GetName():       Little Fruford
 
    GetPopulation(): 668
 
    GetLocation():   19596
 
    GetHouseCount(): 34
 
    GetRating():     4
 
  Town 25
 
    IsValidTown():   true
 
    GetName():       Grinnway
 
    GetPopulation(): 563
 
    GetLocation():   16433
 
    GetHouseCount(): 15
 
    GetRating():     5
 
  Town 26
 
    IsValidTown():   true
 
    GetName():       Bedburg
 
    GetPopulation(): 362
 
    GetLocation():   39505
 
    GetHouseCount(): 18
 
    GetRating():     0
 
  Town 27
 
    IsValidTown():   true
 
    GetName():       Fudinghattan
 
    GetPopulation(): 390
 
    GetLocation():   45525
 
    GetHouseCount(): 19
 
    GetRating():     0
 
  Town 28
 
    IsValidTown():   false
 
    GetName():       (null : 0x00000000)
 
    GetPopulation(): -1
 
    GetLocation():   -1
 
    GetHouseCount(): -1
 
    GetRating():     -1
 
  Town 29
 
    IsValidTown():   false
 
    GetName():       (null : 0x00000000)
 
    GetPopulation(): -1
 
    GetLocation():   -1
 
    GetHouseCount(): -1
 
    GetRating():     -1
 
  Town 30
 
    IsValidTown():   false
 
    GetName():       (null : 0x00000000)
 
    GetPopulation(): -1
 
    GetLocation():   -1
 
    GetHouseCount(): -1
 
    GetRating():     -1
 
  Town 31
 
    IsValidTown():   false
 
    GetName():       (null : 0x00000000)
 
    GetPopulation(): -1
 
    GetLocation():   -1
 
    GetHouseCount(): -1
 
    GetRating():     -1
 
  Valid Towns:       28
 
  GetTownCount():    28
 

	
 
--TownList--
 
  Count():             28
 
  Location ListDump:
 
    23 => 59622
 
    7 => 59234
 
    5 => 55007
 
    22 => 51891
 
    14 => 51298
 
    8 => 51267
 
    1 => 46751
 
    27 => 45525
 
    15 => 42338
 
    3 => 41895
 
    4 => 41450
 
    26 => 39505
 
    6 => 38200
 
    12 => 32740
 
    2 => 28365
 
    17 => 24252
 
    20 => 22585
 
    24 => 19596
 
    16 => 17345
 
    25 => 16433
 
    0 => 15508
 
    11 => 14935
 
    18 => 10574
 
    21 => 9634
 
    13 => 9595
 
    19 => 6511
 
    10 => 6446
 
    9 => 5825
 
  DistanceManhattanToTile(30000) ListDump:
 
    23 => 297
 
    5 => 272
 
    9 => 240
 
    4 => 230
 
    27 => 225
 
    22 => 216
 
    16 => 195
 
    21 => 194
 
    12 => 190
 
    1 => 176
 
    3 => 165
 
    7 => 164
 
    2 => 164
 
    17 => 163
 
    0 => 157
 
    19 => 155
 
    13 => 155
 
    24 => 133
 
    14 => 133
 
    18 => 106
 
    8 => 102
 
    15 => 98
 
    11 => 98
 
    10 => 94
 
    26 => 70
 
    25 => 54
 
    6 => 40
 
    20 => 38
 
  DistanceSquareToTile(30000) ListDump:
 
    23 => 46349
 
    5 => 40034
 
    4 => 36532
 
    12 => 32500
 
    27 => 30825
 
    9 => 30050
 
    2 => 24698
 
    22 => 24386
 
    16 => 23525
 
    17 => 20129
 
    21 => 19396
 
    1 => 16546
 
    3 => 16277
 
    7 => 15496
 
    0 => 13249
 
    19 => 12433
 
    13 => 12025
 
    24 => 10145
 
    14 => 9389
 
    10 => 8468
 
    8 => 7250
 
    18 => 6676
 
    11 => 5002
 
    15 => 4804
 
    25 => 2810
 
    26 => 2458
 
    6 => 1088
 
    20 => 922
 
  IsWithinTownInfluence(15508) ListDump:
 
    0 => 1
 
    27 => 0
 
    26 => 0
 
    25 => 0
 
    24 => 0
 
    23 => 0
 
    22 => 0
 
    21 => 0
 
    20 => 0
 
    19 => 0
 
    18 => 0
 
    17 => 0
 
    16 => 0
 
    15 => 0
 
    14 => 0
 
    13 => 0
 
    12 => 0
 
    11 => 0
 
    10 => 0
 
    9 => 0
 
    8 => 0
 
    7 => 0
 
    6 => 0
 
    5 => 0
 
    4 => 0
 
    3 => 0
 
    2 => 0
 
    1 => 0
 
  GetAllowedNoise() ListDump:
 
    27 => 2
 
    26 => 2
 
    25 => 2
 
    24 => 2
 
    23 => 2
 
    22 => 2
 
    21 => 2
 
    20 => 2
 
    19 => 2
 
    18 => 2
 
    17 => 2
 
    16 => 2
 
    14 => 2
 
    13 => 2
 
    12 => 2
 
    11 => 2
 
    10 => 2
 
    9 => 2
 
    8 => 2
 
    7 => 2
 
    6 => 2
 
    5 => 2
 
    4 => 2
 
    3 => 2
 
    2 => 2
 
    1 => 2
 
    0 => 2
 
    15 => 1
 
  KeepAboveValue(500): done
 
  Count():             11
 
  Population ListDump:
 
    7 => 1006
 
    12 => 982
 
    15 => 807
 
    21 => 772
 
    16 => 767
 
    0 => 757
 
    23 => 752
 
    10 => 737
 
    6 => 679
 
    24 => 668
 
    25 => 563
 
  HasStatue():                     false
 
  GetRoadReworkDuration():         0
 
  GetExclusiveRightsCompany():     -1
 
  GetExclusiveRightsDuration():    0
 
  IsActionAvailable(BUILD_STATUE): true
 
  PerformTownAction(BUILD_STATUE): true
 
  IsActionAvailable(BUILD_STATUE): false
 
  HasStatue():                     true
 

	
 
--Tunnel--
 
  IsTunnelTile():       false
 
  RemoveTunnel():       false
 
  GetOtherTunnelEnd():  28026
 
  BuildTunnel():        true
 
  GetOtherTunnelEnd():  28026
 
  IsTunnelTile():       true
 
  IsTunnelTile():       true
 
  RemoveTunnel():       true
 
  IsTunnelTile():       false
 
  --Errors--
 
  BuildTunnel():        true
 
  BuildTunnel():        false
 
  GetLastErrorString(): ERR_TUNNEL_ANOTHER_TUNNEL_IN_THE_WAY
 
  RemoveTunnel():       true
 

	
 
--Vehicle--
 
  IsValidVehicle(-1):   false
 
  IsValidVehicle(0):    false
 
  IsValidVehicle(12):   false
 
  ISValidVehicle(9999): false
 
  BuildVehicle():       12
 
  IsValidVehicle(12):   true
 
  CloneVehicle():       13
 
  --Accounting--
 
    GetCosts():         932
 
    Should be:          932
 
    ResetCosts():       (null : 0x00000000)
 
  SellVehicle(13):      true
 
  IsInDepot():          true
 
  IsStoppedInDepot():   true
 
  StartStopVehicle():   true
 
  IsInDepot():          false
 
  IsStoppedInDepot():   false
 
  SendVehicleToDepot(): true
 
  IsInDepot():          false
 
  IsStoppedInDepot():   false
 
  --Accounting--
 
    GetCosts():         -466
 
    Should be:          -466
 
  GetName():            Road Vehicle 1
 
  SetName():            true
 
  GetName():            MyVehicleName
 
  CloneVehicle():       13
 
  --VehicleData--
 
    GetLocation():       33417
 
    GetEngineType():     153
 
    GetUnitNumber():     1
 
    GetAge():            0
 
    GetMaxAge():         5490
 
    GetAgeLeft():        5490
 
    GetCurrentSpeed():   4
 
    GetRunningCost():    14
 
    GetProfitThisYear(): 0
 
    GetProfitLastYear(): 0
 
    GetCurrentValue():   466
 
    GetVehicleType():    1
 
    GetRoadType():       0
 
    GetCapacity():       12
 
    GetCargoLoad():      0
 
    IsInDepot():         false
 
    GetNumWagons():      1
 
    GetWagonEngineType(): 153
 
    GetWagonAge():       0
 
    GetLength():         8
 
  GetOwner():           1
 
  BuildVehicle():       14
 
  IsValidVehicle(14):   true
 
  IsInDepot(14):        true
 
  IsStoppedInDepot(14): true
 
  IsValidVehicle(15):   false
 
  IsInDepot(15):        false
 
  IsStoppedInDepot(15): false
 
  BuildVehicle():       16
 
  IsValidVehicle(16):   true
 
  IsInDepot(16):        true
 
  IsStoppedInDepot(16): true
 
  BuildRailDepot():     true
 
  BuildVehicle():       17
 
  BuildVehicle():       18
 
  BuildVehicle():       19
 
  MoveWagon():          true
 
  GetNumWagons():       3
 
  GetLength():          24
 
  GetWagonEngineType(): 9
 
  GetWagonAge():        0
 
  GetWagonEngineType(): 27
 
  GetWagonAge():        0
 
  GetWagonEngineType(): 27
 
  GetWagonAge():        0
 
  GetWagonEngineType(): 65535
 
  GetWagonAge():        -1
 
  --Errors--
 
    RefitVehicle():        false
 
    GetLastErrorString():  ERR_VEHICLE_NOT_IN_DEPOT
 
    SellVehicle():         false
 
    GetLastErrorString():  ERR_VEHICLE_NOT_IN_DEPOT
 
    SendVehicleToDepot():  false
 
    GetLastErrorString():  ERR_UNKNOWN
 

	
 
--VehicleList--
 
  Count():             5
 
  Location ListDump:
 
    13 => 33417
 
    12 => 33417
 
    14 => 32119
 
    16 => 28479
 
    17 => 10008
 
  EngineType ListDump:
 
    14 => 219
 
    16 => 204
 
    13 => 153
 
    12 => 153
 
    17 => 9
 
  UnitNumber ListDump:
 
    13 => 2
 
    17 => 1
 
    16 => 1
 
    14 => 1
 
    12 => 1
 
  Age ListDump:
 
    17 => 0
 
    16 => 0
 
    14 => 0
 
    13 => 0
 
    12 => 0
 
  MaxAge ListDump:
 
    16 => 10980
 
    14 => 10980
 
    17 => 7320
 
    13 => 5490
 
    12 => 5490
 
  AgeLeft ListDump:
 
    16 => 10980
 
    14 => 10980
 
    17 => 7320
 
    13 => 5490
 
    12 => 5490
 
  CurrentSpeed ListDump:
 
    12 => 13
 
    17 => 0
 
    16 => 0
 
    14 => 0
 
    13 => 0
 
  RunningCost ListDump:
 
    17 => 21
 
    16 => 21
 
    14 => 15
 
    13 => 14
 
    12 => 14
 
  ProfitThisYear ListDump:
 
    17 => 0
 
    16 => 0
 
    14 => 0
 
    13 => 0
 
    12 => 0
 
  ProfitLastYear ListDump:
 
    17 => 0
 
    16 => 0
 
    14 => 0
 
    13 => 0
 
    12 => 0
 
  CurrentValue ListDump:
 
    16 => 515
 
    13 => 466
 
    12 => 466
 
    17 => 61
 
    14 => 48
 
  VehicleType ListDump:
 
    14 => 3
 
    16 => 2
 
    13 => 1
 
    12 => 1
 
    17 => 0
 
  RoadType ListDump:
 
    13 => 0
 
    12 => 0
 
    17 => -1
 
    16 => -1
 
    14 => -1
 
  VehicleType ListDump:
 
    13 => 12
 
    12 => 12
 
    17 => 0
 
    16 => 0
 
    14 => 0
 
  VehicleType ListDump:
 
    17 => 0
 
    16 => 0
 
    14 => 0
 
    13 => 0
 
    12 => 0
 

	
 
--Order--
 
  GetOrderCount():       0
 
  GetOrderDestination(): -1
 
  AreOrderFlagsValid():  true
 
  IsValidVehicleOrder(): false
 
  GetOrderFlags():       65535
 
  AppendOrder():         true
 
  InsertOrder():         true
 
  GetOrderCount():       2
 
  IsValidVehicleOrder(): true
 
  RemoveOrder():         true
 
  ChangeOrder():         true
 
  GetOrderDestination(): 33411
 
  CopyOrders():          false
 
  CopyOrders():          true
 
  ShareOrders():         false
 
  ShareOrders():         true
 
  UnshareOrders():       true
 
  AppendOrder():         true
 

	
 
--StationList_Vehicle--
 
  Count():             2
 
  Location ListDump:
 
    4 => 33421
 
    3 => 33411
 
  CargoWaiting(0) ListDump:
 
    4 => 0
 
    3 => 0
 
  CargoWaiting(1) ListDump:
 
    4 => 0
 
    3 => 0
 
  CargoRating(1) ListDump:
 
    4 => 69
 
    3 => 69
 
  DistanceManhattanToTile(30000) ListDump:
 
    4 => 106
 
    3 => 96
 
  DistanceSquareToTile(30000) ListDump:
 
    4 => 8818
 
    3 => 7058
 
  IsWithinTownInfluence(0) ListDump:
 
    4 => 0
 
    3 => 0
 

	
 
--VehicleList_Station--
 
  Count():             1
 
  Location ListDump:
 
    12 => 33417
 
  foreach():
 
    12 => 33417
 

	
 
  First Subsidy Test
 
      --Subsidy (0) --
 
        IsValidSubsidy():     false
 
        IsAwarded():          false
 
        GetAwardedTo():       -1
 
        GetExpireDate():      -1
 
        SourceIsTown():       false
 
        GetSource():          65535
 
        DestionationIsTown(): false
 
        GetDestionation():    65535
 
        GetCargoType():       255
 
  GetNextEvent:          instance
 
    GetEventType:        2
 
      EventName:         SubsidyOffer
 
      --Subsidy (4) --
 
        IsValidSubsidy():     true
 
        IsAwarded():          false
 
        GetAwardedTo():       -1
 
        GetExpireDate():      714414
 
        SourceIsTown():       true
 
        GetSource():          10
 
        DestionationIsTown(): true
 
        GetDestionation():    25
 
        GetCargoType():       0
 
  GetNextEvent:          instance
 
    GetEventType:        6
 
      Unknown Event
 
  GetNextEvent:          instance
 
    GetEventType:        3
 
      Unknown Event
 
  GetNextEvent:          instance
 
    GetEventType:        3
 
      Unknown Event
 
  IsEventWaiting:        false
 
ERROR: The AI died unexpectedly.
bin/ai/regression/regression_info.nut
Show inline comments
 
new file 100644
 
class Regression extends AIInfo {
 
	function GetAuthor()      { return "OpenTTD NoAI Developers Team"; }
 
	function GetName()        { return "Regression"; }
 
	function GetDescription() { return "This runs regression-tests on all commands. On the same map the result should always be the same."; }
 
	function GetVersion()     { return 1; }
 
	function GetDate()        { return "2007-03-18"; }
 
	function CreateInstance() { return "Regression"; }
 
}
 

	
 
RegisterAI(Regression());
 

	
bin/ai/regression/require.nut
Show inline comments
 
new file 100644
 

	
 
print("  Required this file");
 

	
bin/ai/regression/run.sh
Show inline comments
 
new file 100644
 
#!/bin/sh
 

	
 
if ! [ -f ai/regression/regression.nut ]; then
 
	echo "Make sure you are in the root of OpenTTD before starting this script."
 
	exit 1
 
fi
 

	
 
cp ai/regression/regression.nut ai/regression/main.nut
 
cp ai/regression/regression_info.nut ai/regression/info.nut
 

	
 
if [ -f scripts/game_start.scr ]; then
 
	mv scripts/game_start.scr scripts/game_start.src.regression
 
fi
 

	
 
params=""
 
gdb=""
 
if [ "$1" != "-r" ]; then
 
	params="-snull -mnull -vnull:ticks=30000"
 
fi
 
if [ "$1" = "-g" ]; then
 
	gdb="gdb --ex run --args "
 
fi
 
if [ -n "$gdb" ]; then
 
	$gdb ./openttd -x -c ai/regression/regression.cfg $params -g ai/regression/regression.sav
 
else
 
	./openttd -x -c ai/regression/regression.cfg $params -g ai/regression/regression.sav -d ai=2 2>&1 | awk '{ gsub("0x\\(nil\\)", "0x00000000", $0); gsub("^dbg: \\[ai\\]", "", $0); gsub("^ ", "ERROR: ", $0); gsub("ERROR: \\[1\\] ", "", $0); gsub("\\[P\\] ", "", $0); print $0; }' > tmp.regression
 
fi
 

	
 
if [ -z "$gdb" ]; then
 
	res="`diff -ub ai/regression/regression.txt tmp.regression`"
 
	if [ -z "$res" ]; then
 
		echo "Regression test passed!"
 
	else
 
		echo "Regression test failed! Difference:"
 
		echo "$res"
 
	fi
 
	echo ""
 
	echo "Regression test done"
 
fi
 

	
 
rm -f ai/regression/main.nut ai/regression/info.nut
 

	
 
if [ -f scripts/game_start.scr.regression ]; then
 
	mv scripts/game_start.scr.regression scripts/game_start.src
 
fi
 

	
 
if [ "$1" != "-k" ]; then
 
	rm -f tmp.regression
 
fi
bin/ai/wrightai/info.nut
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
class WrightAI extends AIInfo {
 
	function GetAuthor()      { return "OpenTTD NoAI Developers Team"; }
 
	function GetName()        { return "WrightAI"; }
 
	function GetDescription() { return "A simple AI that tries to beat you with only aircrafts"; }
 
	function GetVersion()     { return 2; }
 
	function GetDate()        { return "2008-02-24"; }
 
	function CreateInstance() { return "WrightAI"; }
 
	function GetSettings() {
 
		AddSetting({name = "min_town_size", description = "The minimal size of towns to work on", min_value = 100, max_value = 1000, easy_value = 500, medium_value = 400, hard_value = 300, custom_value = 500, flags = 0});
 
	}
 
}
 

	
 
RegisterAI(WrightAI());
bin/ai/wrightai/main.nut
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
class WrightAI extends AIController {
 
	name = null;
 
	towns_used = null;
 
	route_1 = null;
 
	route_2 = null;
 
	distance_of_route = {};
 
	vehicle_to_depot = {};
 
	delay_build_airport_route = 1000;
 
	passenger_cargo_id = -1;
 

	
 
	function Start();
 

	
 
	constructor() {
 
		this.towns_used = AIList();
 
		this.route_1 = AIList();
 
		this.route_2 = AIList();
 

	
 
		local list = AICargoList();
 
		for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
			if (AICargo.HasCargoClass(i, AICargo.CC_PASSENGERS)) {
 
				this.passenger_cargo_id = i;
 
				break;
 
			}
 
		}
 
	}
 
};
 

	
 
/**
 
 * Check if we have enough money (via loan and on bank).
 
 */
 
function WrightAI::HasMoney(money)
 
{
 
	if (AICompany.GetBankBalance(AICompany.MY_COMPANY) + (AICompany.GetMaxLoanAmount() - AICompany.GetLoanAmount()) > money) return true;
 
	return false;
 
}
 

	
 
/**
 
 * Get the amount of money requested, loan if needed.
 
 */
 
function WrightAI::GetMoney(money)
 
{
 
	if (!this.HasMoney(money)) return;
 
	if (AICompany.GetBankBalance(AICompany.MY_COMPANY) > money) return;
 

	
 
	local loan = money - AICompany.GetBankBalance(AICompany.MY_COMPANY) + AICompany.GetLoanInterval() + AICompany.GetLoanAmount();
 
	loan = loan - loan % AICompany.GetLoanInterval();
 
	AILog.Info("Need a loan to get " + money + ": " + loan);
 
	AICompany.SetLoanAmount(loan);
 
}
 

	
 
/**
 
 * Build an airport route. Find 2 cities that are big enough and try to build airport in both cities.
 
 *  Then we can build an aircraft and make some money.
 
 */
 
function WrightAI::BuildAirportRoute()
 
{
 
	local airport_type = (AIAirport.AirportAvailable(AIAirport.AT_SMALL) ? AIAirport.AT_SMALL : AIAirport.AT_LARGE);
 

	
 
	/* Get enough money to work with */
 
	this.GetMoney(150000);
 

	
 
	AILog.Info("Trying to build an airport route");
 

	
 
	local tile_1 = this.FindSuitableAirportSpot(airport_type, 0);
 
	if (tile_1 < 0) return -1;
 
	local tile_2 = this.FindSuitableAirportSpot(airport_type, tile_1);
 
	if (tile_2 < 0) {
 
		this.towns_used.RemoveValue(tile_1);
 
		return -2;
 
	}
 

	
 
	/* Build the airports for real */
 
	if (!AIAirport.BuildAirport(tile_1, airport_type, true)) {
 
		AILog.Error("Although the testing told us we could build 2 airports, it still failed on the first airport at tile " + tile_1 + ".");
 
		this.towns_used.RemoveValue(tile_1);
 
		this.towns_used.RemoveValue(tile_2);
 
		return -3;
 
	}
 
	if (!AIAirport.BuildAirport(tile_2, airport_type, true)) {
 
		AILog.Error("Although the testing told us we could build 2 airports, it still failed on the second airport at tile " + tile_2 + ".");
 
		AIAirport.RemoveAirport(tile_1);
 
		this.towns_used.RemoveValue(tile_1);
 
		this.towns_used.RemoveValue(tile_2);
 
		return -4;
 
	}
 

	
 
	local ret = this.BuildAircraft(tile_1, tile_2);
 
	if (ret < 0) {
 
		AIAirport.RemoveAirport(tile_1);
 
		AIAirport.RemoveAirport(tile_2);
 
		this.towns_used.RemoveValue(tile_1);
 
		this.towns_used.RemoveValue(tile_2);
 
		return ret;
 
	}
 

	
 
	AILog.Info("Done building a route");
 
	return ret;
 
}
 

	
 
/**
 
 * Build an aircraft with orders from tile_1 to tile_2.
 
 *  The best available aircraft of that time will be bought.
 
 */
 
function WrightAI::BuildAircraft(tile_1, tile_2)
 
{
 
	/* Build an aircraft */
 
	local hangar = AIAirport.GetHangarOfAirport(tile_1);
 
	local engine = null;
 

	
 
	local engine_list = AIEngineList(AIVehicle.VEHICLE_AIR);
 

	
 
	/* When bank balance < 300000, buy cheaper planes */
 
	local balance = AICompany.GetBankBalance(AICompany.MY_COMPANY);
 
	engine_list.Valuate(AIEngine.GetPrice);
 
	engine_list.KeepBelowValue(balance < 300000 ? 50000 : (balance < 1000000 ? 300000 : 1000000));
 

	
 
	engine_list.Valuate(AIEngine.GetCargoType);
 
	engine_list.KeepValue(this.passenger_cargo_id);
 

	
 
	engine_list.Valuate(AIEngine.GetCapacity);
 
	engine_list.KeepTop(1);
 

	
 
	engine = engine_list.Begin();
 

	
 
	if (!AIEngine.IsValidEngine(engine)) {
 
		AILog.Error("Couldn't find a suitable engine");
 
		return -5;
 
	}
 
	local vehicle = AIVehicle.BuildVehicle(hangar, engine);
 
	if (!AIVehicle.IsValidVehicle(vehicle)) {
 
		AILog.Error("Couldn't build the aircraft");
 
		return -6;
 
	}
 
	/* Send him on his way */
 
	AIOrder.AppendOrder(vehicle, tile_1, AIOrder.AIOF_NONE);
 
	AIOrder.AppendOrder(vehicle, tile_2, AIOrder.AIOF_NONE);
 
	AIVehicle.StartStopVehicle(vehicle);
 
	this.distance_of_route.rawset(vehicle, AIMap.DistanceManhattan(tile_1, tile_2));
 
	this.route_1.AddItem(vehicle, tile_1);
 
	this.route_2.AddItem(vehicle, tile_2);
 

	
 
	AILog.Info("Done building an aircraft");
 

	
 
	return 0;
 
}
 

	
 
/**
 
 * Find a suitable spot for an airport, walking all towns hoping to find one.
 
 *  When a town is used, it is marked as such and not re-used.
 
 */
 
function WrightAI::FindSuitableAirportSpot(airport_type, center_tile)
 
{
 
	local airport_x, airport_y, airport_rad;
 

	
 
	airport_x = AIAirport.GetAirportWidth(airport_type);
 
	airport_y = AIAirport.GetAirportHeight(airport_type);
 
	airport_rad = AIAirport.GetAirportCoverageRadius(airport_type);
 

	
 
	local town_list = AITownList();
 
	/* Remove all the towns we already used */
 
	town_list.RemoveList(this.towns_used);
 

	
 
	town_list.Valuate(AITown.GetPopulation);
 
	town_list.KeepAboveValue(GetSetting("min_town_size"));
 
	/* Keep the best 10, if we can't find 2 stations in there, just leave it anyway */
 
	town_list.KeepTop(10);
 
	town_list.Valuate(AIBase.RandItem);
 

	
 
	/* Now find 2 suitable towns */
 
	for (local town = town_list.Begin(); town_list.HasNext(); town = town_list.Next()) {
 
		/* Don't make this a CPU hog */
 
		Sleep(1);
 

	
 
		local tile = AITown.GetLocation(town);
 

	
 
		/* Create a 30x30 grid around the core of the town and see if we can find a spot for a small airport */
 
		local list = AITileList();
 
		/* XXX -- We assume we are more than 15 tiles away from the border! */
 
		list.AddRectangle(tile - AIMap.GetTileIndex(15, 15), tile + AIMap.GetTileIndex(15, 15));
 
		list.Valuate(AITile.IsBuildableRectangle, airport_x, airport_y);
 
		list.KeepValue(1);
 
		if (center_tile != 0) {
 
			/* If we have a tile defined, we don't want to be within 25 tiles of this tile */
 
			list.Valuate(AITile.GetDistanceSquareToTile, center_tile);
 
			list.KeepAboveValue(625);
 
		}
 
		/* Sort on acceptance, remove places that don't have acceptance */
 
		list.Valuate(AITile.GetCargoAcceptance, this.passenger_cargo_id, airport_x, airport_y, airport_rad);
 
		list.RemoveBelowValue(10);
 

	
 
		/* Couldn't find a suitable place for this town, skip to the next */
 
		if (list.Count() == 0) continue;
 
		/* Walk all the tiles and see if we can build the airport at all */
 
		{
 
			local test = AITestMode();
 
			local good_tile = 0;
 

	
 
			for (tile = list.Begin(); list.HasNext(); tile = list.Next()) {
 
				Sleep(1);
 
				if (!AIAirport.BuildAirport(tile, airport_type, true)) continue;
 
				good_tile = tile;
 
				break;
 
			}
 

	
 
			/* Did we found a place to build the airport on? */
 
			if (good_tile == 0) continue;
 
		}
 

	
 
		AILog.Info("Found a good spot for an airport in town " + town + " at tile " + tile);
 

	
 
		/* Make the town as used, so we don't use it again */
 
		this.towns_used.AddItem(town, tile);
 

	
 
		return tile;
 
	}
 

	
 
	AILog.Info("Couldn't find a suitable town to build an airport in");
 
	return -1;
 
}
 

	
 
function WrightAI::ManageAirRoutes()
 
{
 
	local list = AIVehicleList();
 
	list.Valuate(AIVehicle.GetAge);
 
	/* Give the plane at least 2 years to make a difference */
 
	list.KeepAboveValue(365 * 2);
 
	list.Valuate(AIVehicle.GetProfitLastYear);
 

	
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		local profit = list.GetValue(i);
 
		/* Profit last year and this year bad? Let's sell the vehicle */
 
		if (profit < 10000 && AIVehicle.GetProfitThisYear(i) < 10000) {
 
			/* Send the vehicle to depot if we didn't do so yet */
 
			if (!vehicle_to_depot.rawin(i) || vehicle_to_depot.rawget(i) != true) {
 
				AILog.Info("Sending " + i + " to depot as profit is: " + profit + " / " + AIVehicle.GetProfitThisYear(i));
 
				AIVehicle.SendVehicleToDepot(i);
 
				vehicle_to_depot.rawset(i, true);
 
			}
 
		}
 
		/* Try to sell it over and over till it really is in the depot */
 
		if (vehicle_to_depot.rawin(i) && vehicle_to_depot.rawget(i) == true) {
 
			if (AIVehicle.SellVehicle(i)) {
 
				AILog.Info("Selling " + i + " as it finally is in a depot.");
 
				/* Check if we are the last one serving those airports; else sell the airports */
 
				local list2 = AIVehicleList_Station(AIStation.GetStationID(this.route_1.GetValue(i)));
 
				if (list2.Count() == 0) this.SellAirports(i);
 
				vehicle_to_depot.rawdelete(i);
 
			}
 
		}
 
	}
 

	
 
	/* Don't try to add planes when we are short on cash */
 
	if (!this.HasMoney(50000)) return;
 

	
 
	list = AIStationList(AIStation.STATION_AIRPORT);
 
	list.Valuate(AIStation.GetCargoWaiting, this.passenger_cargo_id);
 
	list.KeepAboveValue(250);
 

	
 
	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 
		local list2 = AIVehicleList_Station(i);
 
		/* No vehicles going to this station, abort and sell */
 
		if (list2.Count() == 0) {
 
			this.SellAirports(i);
 
			continue;
 
		};
 

	
 
		/* Find the first vehicle that is going to this station */
 
		local v = list2.Begin();
 
		local dist = this.distance_of_route.rawget(v);
 

	
 
		list2.Valuate(AIVehicle.GetAge);
 
		list2.KeepBelowValue(dist);
 
		/* Do not build a new vehicle if we bought a new one in the last DISTANCE days */
 
		if (list2.Count() != 0) continue;
 

	
 
		AILog.Info("Station " + i + " (" + AIStation.GetLocation(i) + ") has too many cargo, adding a new vehicle for the route.");
 

	
 
		/* Make sure we have enough money */
 
		this.GetMoney(50000);
 

	
 
		return this.BuildAircraft(this.route_1.GetValue(v), this.route_2.GetValue(v));
 
	}
 
}
 

	
 
/**
 
  * Sells the airports from route index i
 
  * Removes towns from towns_used list too
 
  */
 
function WrightAI::SellAirports(i) {
 
	/* Remove the airports */
 
	AILog.Info("Removing airports as nobody serves them anymore.");
 
	AIAirport.RemoveAirport(this.route_1.GetValue(i));
 
	AIAirport.RemoveAirport(this.route_2.GetValue(i));
 
	/* Free the towns_used entries */
 
	this.towns_used.RemoveValue(this.route_1.GetValue(i));
 
	this.towns_used.RemoveValue(this.route_2.GetValue(i));
 
	/* Remove the route */
 
	this.route_1.RemoveItem(i);
 
	this.route_2.RemoveItem(i);
 
}
 

	
 
function WrightAI::HandleEvents()
 
{
 
	while (AIEventController.IsEventWaiting()) {
 
		local e = AIEventController.GetNextEvent();
 
		switch (e.GetEventType()) {
 
			case AIEvent.AI_ET_VEHICLE_CRASHED: {
 
				local ec = AIEventVehicleCrashed.Convert(e);
 
				local v = ec.GetVehicleID();
 
				AILog.Info("We have a crashed vehicle (" + v + "), buying a new one as replacement");
 
				this.BuildAircraft(this.route_1.GetValue(v), this.route_2.GetValue(v));
 
				this.route_1.RemoveItem(v);
 
				this.route_2.RemoveItem(v);
 
			} break;
 

	
 
			default:
 
				break;
 
		}
 
	}
 
}
 

	
 
function WrightAI::Start()
 
{
 
	if (this.passenger_cargo_id == -1) {
 
		AILog.Error("WrightAI could not find the passenger cargo");
 
		return;
 
	}
 

	
 
	/* Give the boy a name */
 
	if (!AICompany.SetName("WrightAI")) {
 
		local i = 2;
 
		while (!AICompany.SetName("WrightAI #" + i)) {
 
			i++;
 
		}
 
	}
 
	this.name = AICompany.GetName(AICompany.MY_COMPANY);
 
	/* Say hello to the user */
 
	AILog.Info("Welcome to WrightAI. I will be building airports all day long.");
 
	AILog.Info("  - Minimum Town Size: " + GetSetting("min_town_size"));
 

	
 
	/* We start with almost no loan, and we take a loan when we want to build something */
 
	AICompany.SetLoanAmount(AICompany.GetLoanInterval());
 

	
 
	/* We need our local ticker, as GetTick() will skip ticks */
 
	local ticker = 0;
 
	/* Determine time we may sleep */
 
	local sleepingtime = 100;
 
	if (this.delay_build_airport_route < sleepingtime)
 
		sleepingtime = this.delay_build_airport_route;
 

	
 
	/* Let's go on for ever */
 
	while (true) {
 
		/* Once in a while, with enough money, try to build something */
 
		if ((ticker % this.delay_build_airport_route == 0 || ticker == 0) && this.HasMoney(100000)) {
 
			local ret = this.BuildAirportRoute();
 
			if (ret == -1 && ticker != 0) {
 
				/* No more route found, delay even more before trying to find an other */
 
				this.delay_build_airport_route = 10000;
 
			}
 
			else if (ret < 0 && ticker == 0) {
 
				/* The AI failed to build a first airport and is deemed */
 
				AICompany.SetName("Failed " + this.name);
 
				AILog.Error("Failed to build first airport route, now giving up building. Repaying loan. Have a nice day!");
 
				AICompany.SetLoanAmount(0);
 
				return;
 
			}
 
		}
 
		/* Manage the routes once in a while */
 
		if (ticker % 2000 == 0) {
 
			this.ManageAirRoutes();
 
		}
 
		/* Try to get ride of our loan once in a while */
 
		if (ticker % 5000 == 0) {
 
			AICompany.SetLoanAmount(0);
 
		}
 
		/* Check for events once in a while */
 
		if (ticker % 100 == 0) {
 
			this.HandleEvents();
 
		}
 
		/* Make sure we do not create infinite loops */
 
		Sleep(sleepingtime);
 
		ticker += sleepingtime;
 
	}
 
}
 

	
bin/scripts/game_start.scr.example
Show inline comments
 
new file 100644
 
start_ai MyAI
 

	
config.lib
Show inline comments
 
@@ -1228,6 +1228,14 @@ make_cflags_and_ldflags() {
 
		CFLAGS="$CFLAGS -DWITH_ZLIB"
 
	fi
 

	
 
	# 64bit machines need -D_SQ64
 
	if [ "$cpu_type" = "64" ]; then
 
		CFLAGS="$CFLAGS -D_SQ64"
 
	fi
 
	SCRIPT_SRC_DIR="$ROOT_DIR/src/3rdparty/squirrel/include"
 
	CFLAGS="$CFLAGS -I$SCRIPT_SRC_DIR"
 
	CFLAGS="$CFLAGS -DNO_GARBAGE_COLLECTOR"
 

	
 
	if [ -n "$png_config" ]; then
 
		CFLAGS="$CFLAGS -DWITH_PNG"
 
		CFLAGS="$CFLAGS `$png_config --cppflags --I_opts | tr '\n\r' '  '`"
 
@@ -2541,6 +2549,7 @@ make_sed() {
 
		s~!!SRC_OBJS_DIR!!~$SRC_OBJS_DIR~g;
 
		s~!!LANG_OBJS_DIR!!~$LANG_OBJS_DIR~g;
 
		s~!!SRC_DIR!!~$SRC_DIR~g;
 
		s~!!SCRIPT_SRC_DIR!!~$SCRIPT_SRC_DIR~g;
 
		s~!!OSXAPP!!~$OSXAPP~g;
 
		s~!!LANG_DIR!!~$LANG_DIR~g;
 
		s~!!TTD!!~$TTD~g;
projects/openttd_vs80.sln
Show inline comments
 
Microsoft Visual Studio Solution File, Format Version 9.00
 
# Visual Studio 2005
 
# Visual C++ Express 2005
 
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "openttd", "openttd_vs80.vcproj", "{668328A0-B40E-4CDB-BD72-D0064424414A}"
 
	ProjectSection(ProjectDependencies) = postProject
 
		{0F066B23-18DF-4284-8265-F4A5E7E3B966} = {0F066B23-18DF-4284-8265-F4A5E7E3B966}
 
@@ -26,12 +26,10 @@ Global
 
	GlobalSection(ProjectConfigurationPlatforms) = postSolution
 
		{668328A0-B40E-4CDB-BD72-D0064424414A}.Debug|Win32.ActiveCfg = Debug|Win32
 
		{668328A0-B40E-4CDB-BD72-D0064424414A}.Debug|Win32.Build.0 = Debug|Win32
 
		{668328A0-B40E-4CDB-BD72-D0064424414A}.Debug|x64.ActiveCfg = Debug|x64
 
		{668328A0-B40E-4CDB-BD72-D0064424414A}.Debug|x64.Build.0 = Debug|x64
 
		{668328A0-B40E-4CDB-BD72-D0064424414A}.Debug|x64.ActiveCfg = Debug|Win32
 
		{668328A0-B40E-4CDB-BD72-D0064424414A}.Release|Win32.ActiveCfg = Release|Win32
 
		{668328A0-B40E-4CDB-BD72-D0064424414A}.Release|Win32.Build.0 = Release|Win32
 
		{668328A0-B40E-4CDB-BD72-D0064424414A}.Release|x64.ActiveCfg = Release|x64
 
		{668328A0-B40E-4CDB-BD72-D0064424414A}.Release|x64.Build.0 = Release|x64
 
		{668328A0-B40E-4CDB-BD72-D0064424414A}.Release|x64.ActiveCfg = Release|Win32
 
		{A133A442-BD0A-4ADE-B117-AD7545E4BDD1}.Debug|Win32.ActiveCfg = Debug|Win32
 
		{A133A442-BD0A-4ADE-B117-AD7545E4BDD1}.Debug|Win32.Build.0 = Debug|Win32
 
		{A133A442-BD0A-4ADE-B117-AD7545E4BDD1}.Debug|x64.ActiveCfg = Debug|Win32
projects/openttd_vs80.vcproj
Show inline comments
 
@@ -59,8 +59,8 @@
 
				EnableIntrinsicFunctions="true"
 
				FavorSizeOrSpeed="2"
 
				OmitFramePointers="true"
 
				AdditionalIncludeDirectories="..\objs\langs"
 
				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;WIN32_EXCEPTION_TRACKER;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_ZLIB;WITH_PNG;WITH_FREETYPE;WITH_ICU;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR=\&quot;OpenTTD\&quot;;WITH_ASSERT"
 
				AdditionalIncludeDirectories="..\objs\langs;..\src\3rdparty\squirrel\include"
 
				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;WIN32_EXCEPTION_TRACKER;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_ZLIB;WITH_PNG;WITH_FREETYPE;WITH_ICU;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR=\&quot;OpenTTD\&quot;;NO_GARBAGE_COLLECTOR;WITH_ASSERT"
 
				StringPooling="true"
 
				ExceptionHandling="1"
 
				RuntimeLibrary="0"
 
@@ -166,8 +166,8 @@
 
				Name="VCCLCompilerTool"
 
				AdditionalOptions="/MP"
 
				Optimization="0"
 
				AdditionalIncludeDirectories="..\objs\langs"
 
				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_ZLIB;WITH_PNG;WITH_FREETYPE;WITH_ICU;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR=\&quot;OpenTTD\&quot;"
 
				AdditionalIncludeDirectories="..\objs\langs;..\src\3rdparty\squirrel\include"
 
				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_ZLIB;WITH_PNG;WITH_FREETYPE;WITH_ICU;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR=\&quot;OpenTTD\&quot;;NO_GARBAGE_COLLECTOR"
 
				BasicRuntimeChecks="3"
 
				RuntimeLibrary="1"
 
				UsePrecompiledHeader="0"
 
@@ -268,8 +268,8 @@
 
				EnableIntrinsicFunctions="true"
 
				FavorSizeOrSpeed="2"
 
				OmitFramePointers="true"
 
				AdditionalIncludeDirectories="..\objs\langs"
 
				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;WIN32_EXCEPTION_TRACKER;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_ZLIB;WITH_PNG;WITH_FREETYPE;WITH_ICU;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR=\&quot;OpenTTD\&quot;;WITH_ASSERT"
 
				AdditionalIncludeDirectories="..\objs\langs;..\src\3rdparty\squirrel\include"
 
				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;WIN32_EXCEPTION_TRACKER;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_ZLIB;WITH_PNG;WITH_FREETYPE;WITH_ICU;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR=\&quot;OpenTTD\&quot;;NO_GARBAGE_COLLECTOR;_SQ64;WITH_ASSERT"
 
				StringPooling="true"
 
				ExceptionHandling="1"
 
				RuntimeLibrary="0"
 
@@ -376,8 +376,8 @@
 
				Name="VCCLCompilerTool"
 
				AdditionalOptions="/MP"
 
				Optimization="0"
 
				AdditionalIncludeDirectories="..\objs\langs"
 
				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_ZLIB;WITH_PNG;WITH_FREETYPE;WITH_ICU;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR=\&quot;OpenTTD\&quot;"
 
				AdditionalIncludeDirectories="..\objs\langs;..\src\3rdparty\squirrel\include"
 
				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_ZLIB;WITH_PNG;WITH_FREETYPE;WITH_ICU;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR=\&quot;OpenTTD\&quot;;NO_GARBAGE_COLLECTOR;_SQ64"
 
				BasicRuntimeChecks="3"
 
				RuntimeLibrary="1"
 
				UsePrecompiledHeader="0"
 
@@ -776,10 +776,6 @@
 
			Name="Header Files"
 
			>
 
			<File
 
				RelativePath=".\..\src\ai\ai.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\aircraft.h"
 
				>
 
			</File>
 
@@ -924,10 +920,6 @@
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\default\default.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\depot_base.h"
 
				>
 
			</File>
 
@@ -1544,10 +1536,6 @@
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\trolly\trolly.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\tunnelbridge.h"
 
				>
 
			</File>
 
@@ -2241,30 +2229,642 @@
 
			</File>
 
		</Filter>
 
		<Filter
 
			Name="AI Files"
 
			Name="Script"
 
			>
 
			<File
 
				RelativePath=".\..\src\script\squirrel.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\script\squirrel.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\script\squirrel_class.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\script\squirrel_helper.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\script\squirrel_helper_type.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\script\squirrel_std.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\script\squirrel_std.hpp"
 
				>
 
			</File>
 
		</Filter>
 
		<Filter
 
			Name="Squirrel"
 
			>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqapi.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqbaselib.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqclass.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqcompiler.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqdebug.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqfuncstate.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqlexer.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqmem.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqobject.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqstate.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\sqstdlib\sqstdaux.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqtable.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqvm.cpp"
 
				>
 
			</File>
 
		</Filter>
 
		<Filter
 
			Name="Squirrel headers"
 
			>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqarray.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqclass.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqclosure.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqcompiler.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqfuncproto.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqfuncstate.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqlexer.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqobject.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqopcodes.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqpcheader.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqstate.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\include\sqstdaux.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\include\sqstdblob.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\sqstdlib\sqstdblobimpl.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\include\sqstdio.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\include\sqstdmath.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\sqstdlib\sqstdstream.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\include\sqstdstring.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\include\sqstdsystem.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqstring.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqtable.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\include\squirrel.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\squserdata.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\squtils.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqvm.h"
 
				>
 
			</File>
 
		</Filter>
 
		<Filter
 
			Name="AI Core"
 
			>
 
			<File
 
				RelativePath=".\..\src\ai\ai.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\ai_config.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\ai_config.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\ai_core.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\ai_gui.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\ai_gui.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\ai_info.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\ai_info.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\ai_info_dummy.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\ai_instance.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\ai_instance.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\ai_scanner.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\ai_scanner.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\ai_storage.hpp"
 
				>
 
			</File>
 
		</Filter>
 
		<Filter
 
			Name="AI API"
 
			>
 
			<File
 
				RelativePath=".\..\src\ai\ai.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\trolly\build.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\default\default.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\trolly\pathfinder.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\trolly\shared.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\trolly\trolly.cpp"
 
				RelativePath=".\..\src\ai\api\ai_abstractlist.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_accounting.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_airport.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_base.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_bridge.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_bridgelist.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_cargo.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_cargolist.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_company.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_controller.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_date.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_depotlist.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_engine.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_enginelist.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_error.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_event.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_event_types.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_execmode.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_gamesettings.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_group.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_grouplist.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_industry.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_industrylist.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_industrytype.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_industrytypelist.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_list.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_log.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_map.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_marine.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_object.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_order.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_rail.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_railtypelist.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_road.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_sign.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_station.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_stationlist.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_subsidy.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_subsidylist.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_testmode.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_tile.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_tilelist.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_town.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_townlist.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_tunnel.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_types.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_vehicle.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_vehiclelist.hpp"
 
				>
 
			</File>
 
		</Filter>
 
		<Filter
 
			Name="AI API Implementation"
 
			>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_abstractlist.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_accounting.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_airport.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_base.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_bridge.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_bridgelist.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_cargo.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_cargolist.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_company.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_controller.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_date.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_depotlist.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_engine.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_enginelist.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_error.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_event.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_event_types.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_execmode.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_gamesettings.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_group.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_grouplist.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_industry.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_industrylist.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_industrytype.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_industrytypelist.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_list.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_log.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_map.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_marine.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_object.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_order.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_rail.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_railtypelist.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_road.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_sign.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_station.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_stationlist.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_subsidy.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_subsidylist.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_testmode.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_tile.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_tilelist.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_town.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_townlist.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_tunnel.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_vehicle.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_vehiclelist.cpp"
 
				>
 
			</File>
 
		</Filter>
projects/openttd_vs80.vcproj.in
Show inline comments
 
@@ -59,8 +59,8 @@
 
				EnableIntrinsicFunctions="true"
 
				FavorSizeOrSpeed="2"
 
				OmitFramePointers="true"
 
				AdditionalIncludeDirectories="..\objs\langs"
 
				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;WIN32_EXCEPTION_TRACKER;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_ZLIB;WITH_PNG;WITH_FREETYPE;WITH_ICU;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR=\&quot;OpenTTD\&quot;;WITH_ASSERT"
 
				AdditionalIncludeDirectories="..\objs\langs;..\src\3rdparty\squirrel\include"
 
				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;WIN32_EXCEPTION_TRACKER;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_ZLIB;WITH_PNG;WITH_FREETYPE;WITH_ICU;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR=\&quot;OpenTTD\&quot;;NO_GARBAGE_COLLECTOR;WITH_ASSERT"
 
				StringPooling="true"
 
				ExceptionHandling="1"
 
				RuntimeLibrary="0"
 
@@ -166,8 +166,8 @@
 
				Name="VCCLCompilerTool"
 
				AdditionalOptions="/MP"
 
				Optimization="0"
 
				AdditionalIncludeDirectories="..\objs\langs"
 
				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_ZLIB;WITH_PNG;WITH_FREETYPE;WITH_ICU;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR=\&quot;OpenTTD\&quot;"
 
				AdditionalIncludeDirectories="..\objs\langs;..\src\3rdparty\squirrel\include"
 
				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_ZLIB;WITH_PNG;WITH_FREETYPE;WITH_ICU;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR=\&quot;OpenTTD\&quot;;NO_GARBAGE_COLLECTOR"
 
				BasicRuntimeChecks="3"
 
				RuntimeLibrary="1"
 
				UsePrecompiledHeader="0"
 
@@ -268,8 +268,8 @@
 
				EnableIntrinsicFunctions="true"
 
				FavorSizeOrSpeed="2"
 
				OmitFramePointers="true"
 
				AdditionalIncludeDirectories="..\objs\langs"
 
				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;WIN32_EXCEPTION_TRACKER;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_ZLIB;WITH_PNG;WITH_FREETYPE;WITH_ICU;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR=\&quot;OpenTTD\&quot;;WITH_ASSERT"
 
				AdditionalIncludeDirectories="..\objs\langs;..\src\3rdparty\squirrel\include"
 
				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;WIN32_EXCEPTION_TRACKER;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_ZLIB;WITH_PNG;WITH_FREETYPE;WITH_ICU;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR=\&quot;OpenTTD\&quot;;NO_GARBAGE_COLLECTOR;_SQ64;WITH_ASSERT"
 
				StringPooling="true"
 
				ExceptionHandling="1"
 
				RuntimeLibrary="0"
 
@@ -376,8 +376,8 @@
 
				Name="VCCLCompilerTool"
 
				AdditionalOptions="/MP"
 
				Optimization="0"
 
				AdditionalIncludeDirectories="..\objs\langs"
 
				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_ZLIB;WITH_PNG;WITH_FREETYPE;WITH_ICU;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR=\&quot;OpenTTD\&quot;"
 
				AdditionalIncludeDirectories="..\objs\langs;..\src\3rdparty\squirrel\include"
 
				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_ZLIB;WITH_PNG;WITH_FREETYPE;WITH_ICU;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR=\&quot;OpenTTD\&quot;;NO_GARBAGE_COLLECTOR;_SQ64"
 
				BasicRuntimeChecks="3"
 
				RuntimeLibrary="1"
 
				UsePrecompiledHeader="0"
projects/openttd_vs90.vcproj
Show inline comments
 
@@ -60,8 +60,8 @@
 
				EnableIntrinsicFunctions="true"
 
				FavorSizeOrSpeed="2"
 
				OmitFramePointers="true"
 
				AdditionalIncludeDirectories="..\objs\langs"
 
				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;WIN32_EXCEPTION_TRACKER;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_ZLIB;WITH_PNG;WITH_FREETYPE;WITH_ICU;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR=\&quot;OpenTTD\&quot;;WITH_ASSERT"
 
				AdditionalIncludeDirectories="..\objs\langs;..\src\3rdparty\squirrel\include"
 
				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;WIN32_EXCEPTION_TRACKER;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_ZLIB;WITH_PNG;WITH_FREETYPE;WITH_ICU;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR=\&quot;OpenTTD\&quot;;NO_GARBAGE_COLLECTOR;WITH_ASSERT"
 
				StringPooling="true"
 
				ExceptionHandling="1"
 
				RuntimeLibrary="0"
 
@@ -165,8 +165,8 @@
 
				Name="VCCLCompilerTool"
 
				AdditionalOptions="/MP"
 
				Optimization="0"
 
				AdditionalIncludeDirectories="..\objs\langs"
 
				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_ZLIB;WITH_PNG;WITH_FREETYPE;WITH_ICU;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR=\&quot;OpenTTD\&quot;"
 
				AdditionalIncludeDirectories="..\objs\langs;..\src\3rdparty\squirrel\include"
 
				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_ZLIB;WITH_PNG;WITH_FREETYPE;WITH_ICU;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR=\&quot;OpenTTD\&quot;;NO_GARBAGE_COLLECTOR"
 
				BasicRuntimeChecks="3"
 
				RuntimeLibrary="1"
 
				UsePrecompiledHeader="0"
 
@@ -266,8 +266,8 @@
 
				EnableIntrinsicFunctions="true"
 
				FavorSizeOrSpeed="2"
 
				OmitFramePointers="true"
 
				AdditionalIncludeDirectories="..\objs\langs"
 
				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;WIN32_EXCEPTION_TRACKER;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_ZLIB;WITH_PNG;WITH_FREETYPE;WITH_ICU;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR=\&quot;OpenTTD\&quot;;WITH_ASSERT"
 
				AdditionalIncludeDirectories="..\objs\langs;..\src\3rdparty\squirrel\include"
 
				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;WIN32_EXCEPTION_TRACKER;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_ZLIB;WITH_PNG;WITH_FREETYPE;WITH_ICU;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR=\&quot;OpenTTD\&quot;;NO_GARBAGE_COLLECTOR;_SQ64;WITH_ASSERT"
 
				StringPooling="true"
 
				ExceptionHandling="1"
 
				RuntimeLibrary="0"
 
@@ -373,8 +373,8 @@
 
				Name="VCCLCompilerTool"
 
				AdditionalOptions="/MP"
 
				Optimization="0"
 
				AdditionalIncludeDirectories="..\objs\langs"
 
				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_ZLIB;WITH_PNG;WITH_FREETYPE;WITH_ICU;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR=\&quot;OpenTTD\&quot;"
 
				AdditionalIncludeDirectories="..\objs\langs;..\src\3rdparty\squirrel\include"
 
				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_ZLIB;WITH_PNG;WITH_FREETYPE;WITH_ICU;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR=\&quot;OpenTTD\&quot;;NO_GARBAGE_COLLECTOR;_SQ64"
 
				BasicRuntimeChecks="3"
 
				RuntimeLibrary="1"
 
				UsePrecompiledHeader="0"
 
@@ -773,10 +773,6 @@
 
			Name="Header Files"
 
			>
 
			<File
 
				RelativePath=".\..\src\ai\ai.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\aircraft.h"
 
				>
 
			</File>
 
@@ -921,10 +917,6 @@
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\default\default.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\depot_base.h"
 
				>
 
			</File>
 
@@ -1541,10 +1533,6 @@
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\trolly\trolly.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\tunnelbridge.h"
 
				>
 
			</File>
 
@@ -2238,30 +2226,642 @@
 
			</File>
 
		</Filter>
 
		<Filter
 
			Name="AI Files"
 
			Name="Script"
 
			>
 
			<File
 
				RelativePath=".\..\src\script\squirrel.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\script\squirrel.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\script\squirrel_class.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\script\squirrel_helper.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\script\squirrel_helper_type.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\script\squirrel_std.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\script\squirrel_std.hpp"
 
				>
 
			</File>
 
		</Filter>
 
		<Filter
 
			Name="Squirrel"
 
			>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqapi.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqbaselib.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqclass.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqcompiler.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqdebug.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqfuncstate.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqlexer.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqmem.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqobject.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqstate.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\sqstdlib\sqstdaux.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqtable.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqvm.cpp"
 
				>
 
			</File>
 
		</Filter>
 
		<Filter
 
			Name="Squirrel headers"
 
			>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqarray.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqclass.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqclosure.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqcompiler.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqfuncproto.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqfuncstate.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqlexer.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqobject.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqopcodes.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqpcheader.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqstate.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\include\sqstdaux.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\include\sqstdblob.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\sqstdlib\sqstdblobimpl.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\include\sqstdio.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\include\sqstdmath.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\sqstdlib\sqstdstream.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\include\sqstdstring.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\include\sqstdsystem.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqstring.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqtable.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\include\squirrel.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\squserdata.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\squtils.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\3rdparty\squirrel\squirrel\sqvm.h"
 
				>
 
			</File>
 
		</Filter>
 
		<Filter
 
			Name="AI Core"
 
			>
 
			<File
 
				RelativePath=".\..\src\ai\ai.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\ai_config.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\ai_config.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\ai_core.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\ai_gui.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\ai_gui.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\ai_info.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\ai_info.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\ai_info_dummy.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\ai_instance.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\ai_instance.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\ai_scanner.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\ai_scanner.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\ai_storage.hpp"
 
				>
 
			</File>
 
		</Filter>
 
		<Filter
 
			Name="AI API"
 
			>
 
			<File
 
				RelativePath=".\..\src\ai\ai.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\trolly\build.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\default\default.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\trolly\pathfinder.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\trolly\shared.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\trolly\trolly.cpp"
 
				RelativePath=".\..\src\ai\api\ai_abstractlist.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_accounting.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_airport.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_base.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_bridge.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_bridgelist.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_cargo.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_cargolist.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_company.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_controller.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_date.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_depotlist.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_engine.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_enginelist.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_error.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_event.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_event_types.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_execmode.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_gamesettings.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_group.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_grouplist.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_industry.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_industrylist.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_industrytype.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_industrytypelist.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_list.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_log.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_map.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_marine.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_object.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_order.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_rail.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_railtypelist.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_road.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_sign.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_station.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_stationlist.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_subsidy.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_subsidylist.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_testmode.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_tile.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_tilelist.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_town.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_townlist.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_tunnel.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_types.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_vehicle.hpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_vehiclelist.hpp"
 
				>
 
			</File>
 
		</Filter>
 
		<Filter
 
			Name="AI API Implementation"
 
			>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_abstractlist.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_accounting.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_airport.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_base.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_bridge.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_bridgelist.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_cargo.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_cargolist.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_company.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_controller.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_date.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_depotlist.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_engine.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_enginelist.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_error.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_event.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_event_types.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_execmode.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_gamesettings.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_group.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_grouplist.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_industry.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_industrylist.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_industrytype.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_industrytypelist.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_list.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_log.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_map.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_marine.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_object.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_order.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_rail.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_railtypelist.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_road.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_sign.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_station.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_stationlist.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_subsidy.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_subsidylist.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_testmode.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_tile.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_tilelist.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_town.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_townlist.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_tunnel.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_vehicle.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\ai\api\ai_vehiclelist.cpp"
 
				>
 
			</File>
 
		</Filter>
projects/openttd_vs90.vcproj.in
Show inline comments
 
@@ -60,8 +60,8 @@
 
				EnableIntrinsicFunctions="true"
 
				FavorSizeOrSpeed="2"
 
				OmitFramePointers="true"
 
				AdditionalIncludeDirectories="..\objs\langs"
 
				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;WIN32_EXCEPTION_TRACKER;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_ZLIB;WITH_PNG;WITH_FREETYPE;WITH_ICU;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR=\&quot;OpenTTD\&quot;;WITH_ASSERT"
 
				AdditionalIncludeDirectories="..\objs\langs;..\src\3rdparty\squirrel\include"
 
				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;WIN32_EXCEPTION_TRACKER;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_ZLIB;WITH_PNG;WITH_FREETYPE;WITH_ICU;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR=\&quot;OpenTTD\&quot;;NO_GARBAGE_COLLECTOR;WITH_ASSERT"
 
				StringPooling="true"
 
				ExceptionHandling="1"
 
				RuntimeLibrary="0"
 
@@ -165,8 +165,8 @@
 
				Name="VCCLCompilerTool"
 
				AdditionalOptions="/MP"
 
				Optimization="0"
 
				AdditionalIncludeDirectories="..\objs\langs"
 
				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_ZLIB;WITH_PNG;WITH_FREETYPE;WITH_ICU;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR=\&quot;OpenTTD\&quot;"
 
				AdditionalIncludeDirectories="..\objs\langs;..\src\3rdparty\squirrel\include"
 
				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_ZLIB;WITH_PNG;WITH_FREETYPE;WITH_ICU;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR=\&quot;OpenTTD\&quot;;NO_GARBAGE_COLLECTOR"
 
				BasicRuntimeChecks="3"
 
				RuntimeLibrary="1"
 
				UsePrecompiledHeader="0"
 
@@ -266,8 +266,8 @@
 
				EnableIntrinsicFunctions="true"
 
				FavorSizeOrSpeed="2"
 
				OmitFramePointers="true"
 
				AdditionalIncludeDirectories="..\objs\langs"
 
				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;WIN32_EXCEPTION_TRACKER;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_ZLIB;WITH_PNG;WITH_FREETYPE;WITH_ICU;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR=\&quot;OpenTTD\&quot;;WITH_ASSERT"
 
				AdditionalIncludeDirectories="..\objs\langs;..\src\3rdparty\squirrel\include"
 
				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;WIN32_EXCEPTION_TRACKER;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_ZLIB;WITH_PNG;WITH_FREETYPE;WITH_ICU;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR=\&quot;OpenTTD\&quot;;NO_GARBAGE_COLLECTOR;_SQ64;WITH_ASSERT"
 
				StringPooling="true"
 
				ExceptionHandling="1"
 
				RuntimeLibrary="0"
 
@@ -373,8 +373,8 @@
 
				Name="VCCLCompilerTool"
 
				AdditionalOptions="/MP"
 
				Optimization="0"
 
				AdditionalIncludeDirectories="..\objs\langs"
 
				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_ZLIB;WITH_PNG;WITH_FREETYPE;WITH_ICU;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR=\&quot;OpenTTD\&quot;"
 
				AdditionalIncludeDirectories="..\objs\langs;..\src\3rdparty\squirrel\include"
 
				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_ZLIB;WITH_PNG;WITH_FREETYPE;WITH_ICU;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR=\&quot;OpenTTD\&quot;;NO_GARBAGE_COLLECTOR;_SQ64"
 
				BasicRuntimeChecks="3"
 
				RuntimeLibrary="1"
 
				UsePrecompiledHeader="0"
source.list
Show inline comments
 
@@ -124,7 +124,6 @@ window.cpp
 
	sound/allegro_s.h
 
	video/allegro_v.h
 
#end
 
ai/ai.h
 
aircraft.h
 
airport.h
 
airport_movement.h
 
@@ -161,7 +160,6 @@ date_func.h
 
date_type.h
 
debug.h
 
video/dedicated_v.h
 
ai/default/default.h
 
depot_base.h
 
depot_func.h
 
depot_map.h
 
@@ -316,7 +314,6 @@ train.h
 
transparency.h
 
transparency_gui.h
 
transport_type.h
 
ai/trolly/trolly.h
 
tunnelbridge.h
 
unmovable.h
 
variables.h
 
@@ -511,13 +508,173 @@ table/unicode.h
 
table/unmovable_land.h
 
table/water_land.h
 

	
 
# AI Files
 
ai/ai.cpp
 
ai/trolly/build.cpp
 
ai/default/default.cpp
 
ai/trolly/pathfinder.cpp
 
ai/trolly/shared.cpp
 
ai/trolly/trolly.cpp
 
# Script
 
script/squirrel.cpp
 
script/squirrel.hpp
 
script/squirrel_class.hpp
 
script/squirrel_helper.hpp
 
script/squirrel_helper_type.hpp
 
script/squirrel_std.cpp
 
script/squirrel_std.hpp
 

	
 
# Squirrel
 
3rdparty/squirrel/squirrel/sqapi.cpp
 
3rdparty/squirrel/squirrel/sqbaselib.cpp
 
3rdparty/squirrel/squirrel/sqclass.cpp
 
3rdparty/squirrel/squirrel/sqcompiler.cpp
 
3rdparty/squirrel/squirrel/sqdebug.cpp
 
3rdparty/squirrel/squirrel/sqfuncstate.cpp
 
3rdparty/squirrel/squirrel/sqlexer.cpp
 
3rdparty/squirrel/squirrel/sqmem.cpp
 
3rdparty/squirrel/squirrel/sqobject.cpp
 
3rdparty/squirrel/squirrel/sqstate.cpp
 
3rdparty/squirrel/sqstdlib/sqstdaux.cpp
 
3rdparty/squirrel/squirrel/sqtable.cpp
 
3rdparty/squirrel/squirrel/sqvm.cpp
 

	
 
# Squirrel headers
 
3rdparty/squirrel/squirrel/sqarray.h
 
3rdparty/squirrel/squirrel/sqclass.h
 
3rdparty/squirrel/squirrel/sqclosure.h
 
3rdparty/squirrel/squirrel/sqcompiler.h
 
3rdparty/squirrel/squirrel/sqfuncproto.h
 
3rdparty/squirrel/squirrel/sqfuncstate.h
 
3rdparty/squirrel/squirrel/sqlexer.h
 
3rdparty/squirrel/squirrel/sqobject.h
 
3rdparty/squirrel/squirrel/sqopcodes.h
 
3rdparty/squirrel/squirrel/sqpcheader.h
 
3rdparty/squirrel/squirrel/sqstate.h
 
3rdparty/squirrel/include/sqstdaux.h
 
3rdparty/squirrel/include/sqstdblob.h
 
3rdparty/squirrel/sqstdlib/sqstdblobimpl.h
 
3rdparty/squirrel/include/sqstdio.h
 
3rdparty/squirrel/include/sqstdmath.h
 
3rdparty/squirrel/sqstdlib/sqstdstream.h
 
3rdparty/squirrel/include/sqstdstring.h
 
3rdparty/squirrel/include/sqstdsystem.h
 
3rdparty/squirrel/squirrel/sqstring.h
 
3rdparty/squirrel/squirrel/sqtable.h
 
3rdparty/squirrel/include/squirrel.h
 
3rdparty/squirrel/squirrel/squserdata.h
 
3rdparty/squirrel/squirrel/squtils.h
 
3rdparty/squirrel/squirrel/sqvm.h
 

	
 
# AI Core
 
ai/ai.hpp
 
#if HAVE_THREAD
 
ai/ai_config.cpp
 
ai/ai_config.hpp
 
ai/ai_core.cpp
 
ai/ai_gui.cpp
 
ai/ai_gui.hpp
 
ai/ai_info.cpp
 
ai/ai_info.hpp
 
ai/ai_info_dummy.cpp
 
ai/ai_instance.cpp
 
ai/ai_instance.hpp
 
ai/ai_scanner.cpp
 
ai/ai_scanner.hpp
 
ai/ai_storage.hpp
 

	
 
# AI API
 
ai/api/ai_abstractlist.hpp
 
ai/api/ai_accounting.hpp
 
ai/api/ai_airport.hpp
 
ai/api/ai_base.hpp
 
ai/api/ai_bridge.hpp
 
ai/api/ai_bridgelist.hpp
 
ai/api/ai_cargo.hpp
 
ai/api/ai_cargolist.hpp
 
ai/api/ai_company.hpp
 
ai/api/ai_controller.hpp
 
ai/api/ai_date.hpp
 
ai/api/ai_depotlist.hpp
 
ai/api/ai_engine.hpp
 
ai/api/ai_enginelist.hpp
 
ai/api/ai_error.hpp
 
ai/api/ai_event.hpp
 
ai/api/ai_event_types.hpp
 
ai/api/ai_execmode.hpp
 
ai/api/ai_gamesettings.hpp
 
ai/api/ai_group.hpp
 
ai/api/ai_grouplist.hpp
 
ai/api/ai_industry.hpp
 
ai/api/ai_industrylist.hpp
 
ai/api/ai_industrytype.hpp
 
ai/api/ai_industrytypelist.hpp
 
ai/api/ai_list.hpp
 
ai/api/ai_log.hpp
 
ai/api/ai_map.hpp
 
ai/api/ai_marine.hpp
 
ai/api/ai_object.hpp
 
ai/api/ai_order.hpp
 
ai/api/ai_rail.hpp
 
ai/api/ai_railtypelist.hpp
 
ai/api/ai_road.hpp
 
ai/api/ai_sign.hpp
 
ai/api/ai_station.hpp
 
ai/api/ai_stationlist.hpp
 
ai/api/ai_subsidy.hpp
 
ai/api/ai_subsidylist.hpp
 
ai/api/ai_testmode.hpp
 
ai/api/ai_tile.hpp
 
ai/api/ai_tilelist.hpp
 
ai/api/ai_town.hpp
 
ai/api/ai_townlist.hpp
 
ai/api/ai_tunnel.hpp
 
ai/api/ai_types.hpp
 
ai/api/ai_vehicle.hpp
 
ai/api/ai_vehiclelist.hpp
 

	
 
# AI API Implementation
 
ai/api/ai_abstractlist.cpp
 
ai/api/ai_accounting.cpp
 
ai/api/ai_airport.cpp
 
ai/api/ai_base.cpp
 
ai/api/ai_bridge.cpp
 
ai/api/ai_bridgelist.cpp
 
ai/api/ai_cargo.cpp
 
ai/api/ai_cargolist.cpp
 
ai/api/ai_company.cpp
 
ai/api/ai_controller.cpp
 
ai/api/ai_date.cpp
 
ai/api/ai_depotlist.cpp
 
ai/api/ai_engine.cpp
 
ai/api/ai_enginelist.cpp
 
ai/api/ai_error.cpp
 
ai/api/ai_event.cpp
 
ai/api/ai_event_types.cpp
 
ai/api/ai_execmode.cpp
 
ai/api/ai_gamesettings.cpp
 
ai/api/ai_group.cpp
 
ai/api/ai_grouplist.cpp
 
ai/api/ai_industry.cpp
 
ai/api/ai_industrylist.cpp
 
ai/api/ai_industrytype.cpp
 
ai/api/ai_industrytypelist.cpp
 
ai/api/ai_list.cpp
 
ai/api/ai_log.cpp
 
ai/api/ai_map.cpp
 
ai/api/ai_marine.cpp
 
ai/api/ai_object.cpp
 
ai/api/ai_order.cpp
 
ai/api/ai_rail.cpp
 
ai/api/ai_railtypelist.cpp
 
ai/api/ai_road.cpp
 
ai/api/ai_sign.cpp
 
ai/api/ai_station.cpp
 
ai/api/ai_stationlist.cpp
 
ai/api/ai_subsidy.cpp
 
ai/api/ai_subsidylist.cpp
 
ai/api/ai_testmode.cpp
 
ai/api/ai_tile.cpp
 
ai/api/ai_tilelist.cpp
 
ai/api/ai_town.cpp
 
ai/api/ai_townlist.cpp
 
ai/api/ai_tunnel.cpp
 
ai/api/ai_vehicle.cpp
 
ai/api/ai_vehiclelist.cpp
 
#end
 

	
 
# Blitters
 
#if DEDICATED
src/ai/ai.cpp
Show inline comments
 
deleted file
src/ai/ai.h
Show inline comments
 
deleted file
src/ai/ai.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai.hpp Base functions for all AIs. */
 

	
 
#ifndef AI_HPP
 
#define AI_HPP
 

	
 
#include "api/ai_event_types.hpp"
 

	
 
#ifndef AI_CONFIG_HPP
 
struct ltstr { bool operator()(const char *s1, const char *s2) const { return strcmp(s1, s2) < 0; } };
 
#endif /* AI_CONFIG_HPP */
 
typedef std::map<const char *, class AIInfo *, ltstr> AIInfoList;
 

	
 

	
 
void CcAI(bool success, TileIndex tile, uint32 p1, uint32 p2);
 

	
 
class AI {
 
public:
 
	/**
 
	 * Is it possible to start a new AI company?
 
	 * @return True if a new AI company can be started.
 
	 */
 
	static bool CanStartNew();
 

	
 
	/**
 
	 * Start a new AI company.
 
	 * @param company At which slot the AI company should start.
 
	 */
 
	static void StartNew(CompanyID company);
 

	
 
	/**
 
	 * Called every game-tick to let AIs do something.
 
	 */
 
	static void GameLoop();
 

	
 
	/**
 
	 * Get the current AI tick.
 
	 */
 
	static uint GetTick();
 

	
 
	/**
 
	 * Stop a company to be controlled by an AI.
 
	 * @param company The company from which the AI needs to detach.
 
	 * @pre !IsHumanCompany(company).
 
	 */
 
	static void Stop(CompanyID company);
 

	
 
	/**
 
	 * Kill any and all AIs we manage.
 
	 */
 
	static void KillAll();
 

	
 
	/**
 
	 * Initialize the AI system.
 
	 */
 
	static void Initialize();
 

	
 
	/**
 
	 * Uninitialize the AI system
 
	 * @param keepConfig Should we keep AIConfigs, or can we free that memory?
 
	 */
 
	static void Uninitialize(bool keepConfig);
 

	
 
	/**
 
	 * Reset all AIConfigs, and make them reload their AIInfo.
 
	 * If the AIInfo could no longer be found, an error is reported to the user.
 
	 */
 
	static void ResetConfig();
 

	
 
	/**
 
	 * Queue a new event for an AI.
 
	 */
 
	static void NewEvent(CompanyID company, AIEvent *event);
 

	
 
	/**
 
	 * Broadcast a new event to all active AIs.
 
	 */
 
	static void BroadcastNewEvent(AIEvent *event, CompanyID skip_company = MAX_COMPANIES);
 

	
 
	/**
 
	 * Save data from an AI to a savegame.
 
	 */
 
	static void Save(CompanyID company);
 

	
 
	/**
 
	 * Load data for an AI from a savegame.
 
	 */
 
	static void Load(CompanyID company);
 

	
 
	static char *GetConsoleList(char *p, const char *last);
 
	static const AIInfoList *GetInfoList();
 
	static AIInfo *GetCompanyInfo(const char *name);
 
	static bool ImportLibrary(const char *library, const char *class_name, int version, HSQUIRRELVM vm);
 
	static void Rescan();
 

	
 
private:
 
	static uint frame_counter;
 
	static class AIScanner *ai_scanner;
 
};
 

	
 
#endif /* AI_HPP */
src/ai/ai_config.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_config.cpp Implementation of AIConfig. */
 

	
 
#include "../stdafx.h"
 
#include "../openttd.h"
 
#include "../settings_type.h"
 
#include "ai.hpp"
 
#include "ai_config.hpp"
 
#include "ai_info.hpp"
 

	
 
void AIConfig::ChangeAI(const char *name)
 
{
 
	free((void *)this->name);
 
	this->name = (name == NULL) ? NULL : strdup(name);
 
	this->info = (name == NULL) ? NULL : AI::GetCompanyInfo(this->name);
 

	
 
	for (SettingValueList::iterator it = this->settings.begin(); it != this->settings.end(); it++) {
 
		free((void*)(*it).first);
 
	}
 
	this->settings.clear();
 
}
 

	
 
AIConfig::AIConfig(const AIConfig *config) :
 
	name(NULL),
 
	info(NULL)
 
{
 
	this->name = (config->name == NULL) ? NULL : strdup(config->name);
 
	this->info = config->info;
 

	
 
	for (SettingValueList::const_iterator it = config->settings.begin(); it != config->settings.end(); it++) {
 
		this->settings[strdup((*it).first)] = (*it).second;
 
	}
 
}
 

	
 
AIConfig::~AIConfig()
 
{
 
	this->ChangeAI(NULL);
 
}
 

	
 
AIInfo *AIConfig::GetInfo()
 
{
 
	return this->info;
 
}
 

	
 
bool AIConfig::ResetInfo()
 
{
 
	 this->info = AI::GetCompanyInfo(this->name);
 
	 return this->info != NULL;
 
}
 

	
 
AIConfig *AIConfig::GetConfig(CompanyID company, bool forceNewgameSetting)
 
{
 
	AIConfig **config;
 
	if (!forceNewgameSetting) {
 
		config = (_game_mode == GM_MENU) ? &_settings_newgame.ai_config[company] : &_settings_game.ai_config[company];
 
	} else {
 
		config = &_settings_newgame.ai_config[company];
 
	}
 
	if (*config == NULL) *config = new AIConfig();
 
	return *config;
 
}
 

	
 
int AIConfig::GetSetting(const char *name)
 
{
 
	assert(this->info != NULL);
 

	
 
	SettingValueList::iterator it = this->settings.find(name);
 
	/* Return the default value if the setting is not set, or if we are in a not-custom difficult level */
 
	if (it == this->settings.end() || ((_game_mode == GM_MENU) ? _settings_newgame.difficulty.diff_level : _settings_game.difficulty.diff_level) != 3) {
 
		return this->info->GetSettingDefaultValue(name);
 
	}
 
	return (*it).second;
 
}
 

	
 
void AIConfig::SetSetting(const char *name, int value)
 
{
 
	/* You can only set ai specific settings if an AI is selected. */
 
	assert(strcmp(name, "start_date") == 0 || this->info != NULL);
 

	
 
	SettingValueList::iterator it = this->settings.find(name);
 
	if (it != this->settings.end()) {
 
		(*it).second = value;
 
	} else {
 
		this->settings[strdup(name)] = value;
 
	}
 
}
 

	
 
bool AIConfig::HasAI()
 
{
 
	return this->info != NULL;
 
}
 

	
 
const char *AIConfig::GetName()
 
{
 
	return this->name;
 
}
 

	
 
void AIConfig::StringToSettings(const char *value)
 
{
 
	char *value_copy = strdup(value);
 
	char *s = value_copy;
 

	
 
	while (s != NULL) {
 
		/* Analyze the string ('name=value,name=value\0') */
 
		char *item_name = s;
 
		s = strchr(s, '=');
 
		if (s == NULL) break;
 
		if (*s == '\0') break;
 
		*s = '\0';
 
		s++;
 

	
 
		char *item_value = s;
 
		s = strchr(s, ',');
 
		if (s != NULL) {
 
			*s = '\0';
 
			s++;
 
		}
 

	
 
		this->SetSetting(item_name, atoi(item_value));
 
	}
 
	free(value_copy);
 
}
 

	
 
void AIConfig::SettingsToString(char *string, int size)
 
{
 
	string[0] = '\0';
 
	for (SettingValueList::iterator it = this->settings.begin(); it != this->settings.end(); it++) {
 
		char no[10];
 
		snprintf(no, sizeof(no), "%d", (*it).second);
 

	
 
		/* Check if the string would fit in the destination */
 
		size -= strlen((*it).first) - 1 - strlen(no) - 1;
 
		/* If it doesn't fit, skip the next settings */
 
		if (size <= 0) return;
 

	
 
		strcat(string, (*it).first);
 
		strcat(string, "=");
 
		strcat(string, no);
 
		strcat(string, ",");
 
	}
 
	string[strlen(string) - 1] = '\0';
 
}
src/ai/ai_config.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_config.hpp AIConfig stores the configuration settings of every AI. */
 

	
 
#ifndef AI_CONFIG_HPP
 
#define AI_CONFIG_HPP
 

	
 
#include <map>
 

	
 
#ifndef AI_HPP
 
struct ltstr { bool operator()(const char *s1, const char *s2) const { return strcmp(s1, s2) < 0; } };
 
#endif /* AI_HPP */
 

	
 
class AIConfig {
 
private:
 
	typedef std::map<const char *, int, ltstr> SettingValueList;
 

	
 
public:
 
	AIConfig() :
 
		name(NULL),
 
		info(NULL)
 
	{}
 
	AIConfig(const AIConfig *config);
 
	~AIConfig();
 

	
 
	/**
 
	 * Set another AI to be loaded in this slot.
 
	 */
 
	void ChangeAI(const char *name);
 

	
 
	/**
 
	 * When ever the AI Scanner is reloaded, all infos become invalid. This
 
	 *  function tells AIConfig about this.
 
	 * @return True if the reset was successfull, false if the AI was no longer
 
	 *  found.
 
	 */
 
	bool ResetInfo();
 

	
 
	/**
 
	 * Get the AIInfo linked to this AIConfig.
 
	 */
 
	class AIInfo *GetInfo();
 

	
 
	/**
 
	 * Get the config of a company.
 
	 */
 
	static AIConfig *GetConfig(CompanyID company, bool forceNewgameSetting = false);
 

	
 
	/**
 
	 * Get the value of a setting for this config. It might fallback to his
 
	 *  'info' to find the default value (if not set or if not-custom difficulty
 
	 *  level).
 
	 * @return The (default) value of the setting, or -1 if the setting was not
 
	 *  found.
 
	 */
 
	int GetSetting(const char *name);
 

	
 
	/**
 
	 * Set the value of a setting for this config.
 
	 */
 
	void SetSetting(const char *name, int value);
 

	
 
	/**
 
	 * Is this config attached to an AI?
 
	 */
 
	bool HasAI();
 

	
 
	/**
 
	 * Get the name of the AI.
 
	 */
 
	const char *GetName();
 

	
 
	/**
 
	 * Convert a string which is stored in the config file or savegames to
 
	 *  custom settings of this AI.
 
	 */
 
	void StringToSettings(const char *value);
 

	
 
	/**
 
	 * Convert the custom settings to a string that can be stored in the config
 
	 *  file or savegames.
 
	 */
 
	void SettingsToString(char *string, int size);
 

	
 
private:
 
	const char *name;
 
	class AIInfo *info;
 
	SettingValueList settings;
 
};
 

	
 
#endif /* AI_CONFIG_HPP */
src/ai/ai_core.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_core.cpp Implementation of AI. */
 

	
 
#include "../stdafx.h"
 
#include "../openttd.h"
 
#include "../company_type.h"
 
#include "../company_base.h"
 
#include "../company_func.h"
 
#include "../debug.h"
 
#include "../network/network.h"
 
#include "../settings_type.h"
 
#include "../window_type.h"
 
#include "../window_func.h"
 
#include "../command_func.h"
 
#include "ai.hpp"
 
#include "ai_info.hpp"
 
#include "ai_scanner.hpp"
 
#include "ai_instance.hpp"
 
#include "ai_config.hpp"
 

	
 
/* static */ uint AI::frame_counter = 0;
 
/* static */ AIScanner *AI::ai_scanner = NULL;
 

	
 
/* static */ bool AI::CanStartNew()
 
{
 
	/* Only allow new AIs on the server and only when that is allowed in multiplayer */
 
	return !_networking || (_network_server && _settings_game.ai.ai_in_multiplayer);
 
}
 

	
 
/* static */ void AI::StartNew(CompanyID company)
 
{
 
	assert(IsValidCompanyID(company));
 

	
 
	/* Clients shouldn't start AIs */
 
	if (_networking && !_network_server) return;
 

	
 
	AIInfo *info = AIConfig::GetConfig(company)->GetInfo();
 
	if (info == NULL) {
 
		info = AI::ai_scanner->SelectRandomAI();
 
		assert(info != NULL);
 
		/* Load default data and store the name in the settings */
 
		AIConfig::GetConfig(company)->ChangeAI(info->GetDirName());
 
	}
 

	
 
	_current_company = company;
 
	Company *c = GetCompany(company);
 

	
 
	c->ai_info = info;
 
	c->ai_instance = new AIInstance(info);
 

	
 
	InvalidateWindowData(WC_AI_DEBUG, 0, -1);
 
	return;
 
}
 

	
 
/* static */ void AI::GameLoop()
 
{
 
	/* If we are in networking, only servers run this function, and that only if it is allowed */
 
	if (_networking && (!_network_server || !_settings_game.ai.ai_in_multiplayer)) return;
 

	
 
	/* The speed with which AIs go, is limited by the 'competitor_speed' */
 
	AI::frame_counter++;
 
	assert(_settings_game.difficulty.competitor_speed <= 4);
 
	if ((AI::frame_counter & ((1 << (4 - _settings_game.difficulty.competitor_speed)) - 1)) != 0) return;
 

	
 
	const Company *c;
 
	FOR_ALL_COMPANIES(c) {
 
		if (!IsHumanCompany(c->index)) {
 
			_current_company = c->index;
 
			c->ai_instance->GameLoop();
 
		}
 
	}
 

	
 
	_current_company = OWNER_NONE;
 
}
 

	
 
/* static */ uint AI::GetTick()
 
{
 
	return AI::frame_counter;
 
}
 

	
 
/* static */ void AI::Stop(CompanyID company)
 
{
 
	if (_networking && !_network_server) return;
 

	
 
	_current_company = company;
 
	Company *c = GetCompany(company);
 

	
 
	delete c->ai_instance;
 
	c->ai_instance = NULL;
 

	
 
	InvalidateWindowData(WC_AI_DEBUG, 0, -1);
 
}
 

	
 
/* static */ void AI::KillAll()
 
{
 
	/* It might happen there are no companies .. than we have nothing to loop */
 
	if (GetCompanyPoolSize() == 0) return;
 

	
 
	const Company *c;
 
	FOR_ALL_COMPANIES(c) {
 
		if (!IsHumanCompany(c->index)) AI::Stop(c->index);
 
	}
 
}
 

	
 
/* static */ void AI::Initialize()
 
{
 
	if (AI::ai_scanner != NULL) AI::Uninitialize(true);
 

	
 
	AI::frame_counter = 0;
 
	if (AI::ai_scanner == NULL) AI::ai_scanner = new AIScanner();
 
}
 

	
 
/* static */ void AI::Uninitialize(bool keepConfig)
 
{
 
	AI::KillAll();
 

	
 
	if (keepConfig) {
 
		/* Run a rescan, which indexes all AIInfos again, and check if we can
 
		 *  still load all the AIS, while keeping the configs in place */
 
		Rescan();
 
	} else {
 
		delete AI::ai_scanner;
 
		AI::ai_scanner = NULL;
 

	
 
		for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) {
 
			if (_settings_game.ai_config[c] != NULL) {
 
				delete _settings_game.ai_config[c];
 
				_settings_game.ai_config[c] = NULL;
 
			}
 
			if (_settings_newgame.ai_config[c] != NULL) {
 
				delete _settings_newgame.ai_config[c];
 
				_settings_newgame.ai_config[c] = NULL;
 
			}
 
		}
 
	}
 
}
 

	
 
/* static */ void AI::ResetConfig()
 
{
 
	/* Check for both newgame as current game if we can reload the AIInfo insde
 
	 *  the AIConfig. If not, remove the AI from the list (which will assign
 
	 *  a random new AI on reload). */
 
	for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) {
 
		if (_settings_game.ai_config[c] != NULL && _settings_game.ai_config[c]->HasAI()) {
 
			if (!_settings_game.ai_config[c]->ResetInfo()) {
 
				DEBUG(ai, 0, "After a reload, the AI by the name '%s' was no longer found, and removed from the list.", _settings_game.ai_config[c]->GetName());
 
				_settings_game.ai_config[c]->ChangeAI(NULL);
 
			}
 
		}
 
		if (_settings_newgame.ai_config[c] != NULL && _settings_newgame.ai_config[c]->HasAI()) {
 
			if (!_settings_newgame.ai_config[c]->ResetInfo()) {
 
				DEBUG(ai, 0, "After a reload, the AI by the name '%s' was no longer found, and removed from the list.", _settings_newgame.ai_config[c]->GetName());
 
				_settings_newgame.ai_config[c]->ChangeAI(NULL);
 
			}
 
		}
 
	}
 
}
 

	
 
/* static */ void AI::NewEvent(CompanyID company, AIEvent *event)
 
{
 
	/* Clients should ignore events */
 
	if (_networking && !_network_server) return;
 

	
 
	/* Only AIs can have an event-queue */
 
	if (!IsValidCompanyID(company) || IsHumanCompany(company)) return;
 

	
 
	/* Queue the event */
 
	CompanyID old_company = _current_company;
 
	_current_company = company;
 
	AIEventController::InsertEvent(event);
 
	_current_company = old_company;
 
}
 

	
 
/* static */ void AI::BroadcastNewEvent(AIEvent *event, CompanyID skip_company)
 
{
 
	/* Clients should ignore events */
 
	if (_networking && !_network_server) return;
 

	
 
	/* Try to send the event to all AIs */
 
	for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) {
 
		if (c != skip_company) AI::NewEvent(c, event);
 
	}
 
}
 

	
 
void CcAI(bool success, TileIndex tile, uint32 p1, uint32 p2)
 
{
 
	AIObject::SetLastCommandRes(success);
 

	
 
	if (!success) {
 
		AIObject::SetLastError(AIError::StringToError(_error_message));
 
	} else {
 
		AIObject::IncreaseDoCommandCosts(AIObject::GetLastCost());
 
	}
 

	
 
	GetCompany(_current_company)->ai_instance->Continue();
 
}
 

	
 
/* static */ void AI::Save(CompanyID company)
 
{
 
	if (!_networking || _network_server) {
 
		assert(IsValidCompanyID(company));
 
		assert(GetCompany(company)->ai_instance != NULL);
 

	
 
		CompanyID old_company = _current_company;
 
		_current_company = company;
 
		GetCompany(company)->ai_instance->Save();
 
		_current_company = old_company;
 
	} else {
 
		AIInstance::SaveEmpty();
 
	}
 
}
 

	
 
/* static */ void AI::Load(CompanyID company)
 
{
 
	if (!_networking || _network_server) {
 
		assert(IsValidCompanyID(company));
 
		assert(GetCompany(company)->ai_instance != NULL);
 

	
 
		CompanyID old_company = _current_company;
 
		_current_company = company;
 
		GetCompany(company)->ai_instance->Load();
 
		_current_company = old_company;
 
	} else {
 
		/* Read, but ignore, the load data */
 
		AIInstance::LoadEmpty();
 
	}
 
}
 

	
 
/* static */ char *AI::GetConsoleList(char *p, const char *last)
 
{
 
	return AI::ai_scanner->GetAIConsoleList(p, last);
 
}
 

	
 
/* static */ const AIInfoList *AI::GetInfoList()
 
{
 
	return AI::ai_scanner->GetAIInfoList();
 
}
 

	
 
/* static */ AIInfo *AI::GetCompanyInfo(const char *name)
 
{
 
	return AI::ai_scanner->FindAI(name);
 
}
 

	
 
/* static */ bool AI::ImportLibrary(const char *library, const char *class_name, int version, HSQUIRRELVM vm)
 
{
 
	return AI::ai_scanner->ImportLibrary(library, class_name, version, vm, GetCompany(_current_company)->ai_instance->GetController());
 
}
 

	
 
/* static */ void AI::Rescan()
 
{
 
	AI::ai_scanner->RescanAIDir();
 
	ResetConfig();
 
}
src/ai/ai_gui.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_gui.cpp Window for configuring the AIs */
 

	
 
#include "../stdafx.h"
 
#include "../openttd.h"
 
#include "../gui.h"
 
#include "../window_gui.h"
 
#include "../company_func.h"
 
#include "../company_base.h"
 
#include "../company_gui.h"
 
#include "../economy_func.h"
 
#include "../variables.h"
 
#include "../cargotype.h"
 
#include "../strings_func.h"
 
#include "../core/alloc_func.hpp"
 
#include "../window_func.h"
 
#include "../date_func.h"
 
#include "../gfx_func.h"
 
#include "../debug.h"
 
#include "../command_func.h"
 
#include "../network/network.h"
 

	
 
#include "ai.hpp"
 
#include "api/ai_types.hpp"
 
#include "api/ai_controller.hpp"
 
#include "api/ai_object.hpp"
 
#include "api/ai_log.hpp"
 
#include "ai_info.hpp"
 

	
 
#include "table/strings.h"
 
#include "../table/sprites.h"
 

	
 
struct AIDebugWindow : public Window {
 
	enum AIDebugWindowWidgets {
 
		AID_WIDGET_CLOSEBOX = 0,
 
		AID_WIDGET_CAPTION,
 
		AID_WIDGET_VIEW,
 
		AID_WIDGET_NAME_TEXT,
 
		AID_WIDGET_RELOAD_TOGGLE,
 
		AID_WIDGET_LOG_PANEL,
 
		AID_WIDGET_SCROLLBAR,
 
		AID_WIDGET_UNUSED_1,
 
		AID_WIDGET_UNUSED_2,
 
		AID_WIDGET_UNUSED_3,
 
		AID_WIDGET_UNUSED_4,
 
		AID_WIDGET_UNUSED_5,
 
		AID_WIDGET_UNUSED_6,
 
		AID_WIDGET_UNUSED_7,
 

	
 
		AID_WIDGET_COMPANY_BUTTON_START,
 
		AID_WIDGET_COMPANY_BUTTON_END = AID_WIDGET_COMPANY_BUTTON_START + 14,
 
	};
 

	
 
	static CompanyID ai_debug_company;
 
	int redraw_timer;
 

	
 
	AIDebugWindow(const WindowDesc *desc, WindowNumber number) : Window(desc, number)
 
	{
 
		/* Disable the companies who are not active or not an AI */
 
		for (CompanyID i = COMPANY_FIRST; i < MAX_COMPANIES; i++) {
 
			this->SetWidgetDisabledState(i + AID_WIDGET_COMPANY_BUTTON_START, !IsValidCompanyID(i) || !GetCompany(i)->is_ai);
 
		}
 
		this->DisableWidget(AID_WIDGET_RELOAD_TOGGLE);
 

	
 
		this->vscroll.cap = 14;
 
		this->vscroll.pos = 0;
 
		this->resize.step_height = 12;
 

	
 
		if (ai_debug_company != INVALID_COMPANY) this->LowerWidget(ai_debug_company + AID_WIDGET_COMPANY_BUTTON_START);
 

	
 
		this->FindWindowPlacementAndResize(desc);
 
	}
 

	
 
	virtual void OnPaint()
 
	{
 
		/* Check if the currently selected company is still active. */
 
		if (ai_debug_company == INVALID_COMPANY || !IsValidCompanyID(ai_debug_company)) {
 
			if (ai_debug_company != INVALID_COMPANY) {
 
				/* Raise and disable the widget for the previous selection. */
 
				this->RaiseWidget(ai_debug_company + AID_WIDGET_COMPANY_BUTTON_START);
 
				this->DisableWidget(ai_debug_company + AID_WIDGET_COMPANY_BUTTON_START);
 

	
 
				ai_debug_company = INVALID_COMPANY;
 
			}
 

	
 
			for (CompanyID i = COMPANY_FIRST; i < MAX_COMPANIES; i++) {
 
				if (IsValidCompanyID(i) && GetCompany(i)->is_ai) {
 
					/* Lower the widget corresponding to this company. */
 
					this->LowerWidget(i + AID_WIDGET_COMPANY_BUTTON_START);
 

	
 
					ai_debug_company = i;
 
					break;
 
				}
 
			}
 
		}
 

	
 
		/* Update "Reload AI" button */
 
		this->SetWidgetDisabledState(AID_WIDGET_RELOAD_TOGGLE, ai_debug_company == INVALID_COMPANY);
 

	
 
		/* Draw standard stuff */
 
		this->DrawWidgets();
 

	
 
		/* If there are no active companies, don't display anything else. */
 
		if (ai_debug_company == INVALID_COMPANY) return;
 

	
 
		/* Paint the company icons */
 
		for (CompanyID i = COMPANY_FIRST; i < MAX_COMPANIES; i++) {
 
			if (!IsValidCompanyID(i) || !GetCompany(i)->is_ai) {
 
				/* Check if we have the company as an active company */
 
				if (!this->IsWidgetDisabled(i + AID_WIDGET_COMPANY_BUTTON_START)) {
 
					/* Bah, company gone :( */
 
					this->DisableWidget(i + AID_WIDGET_COMPANY_BUTTON_START);
 

	
 
					/* We need a repaint */
 
					this->SetDirty();
 
				}
 
				continue;
 
			}
 

	
 
			/* Check if we have the company marked as inactive */
 
			if (this->IsWidgetDisabled(i + AID_WIDGET_COMPANY_BUTTON_START)) {
 
				/* New AI! Yippie :p */
 
				this->EnableWidget(i + AID_WIDGET_COMPANY_BUTTON_START);
 

	
 
				/* We need a repaint */
 
				this->SetDirty();
 
			}
 

	
 
			byte x = (i == ai_debug_company) ? 1 : 0;
 
			DrawCompanyIcon(i, (i % 8) * 37 + 13 + x, (i < 8 ? 0 : 13) + 16 + x);
 
		}
 

	
 
		/* Draw the AI name */
 
		AIInfo *info = GetCompany(ai_debug_company)->ai_info;
 
		assert(info != NULL);
 
		DoDrawString(info->GetName(), 7, 47, TC_BLACK);
 

	
 
		CompanyID old_company = _current_company;
 
		_current_company = ai_debug_company;
 
		AILog::LogData *log = (AILog::LogData *)AIObject::GetLogPointer();
 
		_current_company = old_company;
 

	
 
		SetVScrollCount(this, (log == NULL) ? 0 : log->used);
 
		this->InvalidateWidget(AID_WIDGET_SCROLLBAR);
 
		if (log == NULL) return;
 

	
 
		int y = 6;
 
		for (int i = this->vscroll.pos; i < (this->vscroll.cap + this->vscroll.pos); i++) {
 
			uint pos = (log->count + log->pos - i) % log->count;
 
			if (log->lines[pos] == NULL) break;
 

	
 
			uint colour;
 
			switch (log->type[pos]) {
 
				case AILog::LOG_SQ_INFO:  colour = TC_BLACK;  break;
 
				case AILog::LOG_SQ_ERROR: colour = TC_RED;    break;
 
				case AILog::LOG_INFO:     colour = TC_BLACK;  break;
 
				case AILog::LOG_WARNING:  colour = TC_YELLOW; break;
 
				case AILog::LOG_ERROR:    colour = TC_RED;    break;
 
				default:                  colour = TC_BLACK;  break;
 
			}
 

	
 
			DoDrawStringTruncated(log->lines[pos], 7, this->widget[AID_WIDGET_LOG_PANEL].top + y, colour, this->widget[AID_WIDGET_LOG_PANEL].right - this->widget[AID_WIDGET_LOG_PANEL].left - 14);
 
			y += 12;
 
		}
 
	}
 

	
 
	virtual void OnClick(Point pt, int widget)
 
	{
 
		/* Check which button is clicked */
 
		if (IsInsideMM(widget, AID_WIDGET_COMPANY_BUTTON_START, AID_WIDGET_COMPANY_BUTTON_END + 1)) {
 
			/* Is it no on disable? */
 
			if (!this->IsWidgetDisabled(widget)) {
 
				this->RaiseWidget(ai_debug_company + AID_WIDGET_COMPANY_BUTTON_START);
 
				ai_debug_company = (CompanyID)(widget - AID_WIDGET_COMPANY_BUTTON_START);
 
				this->LowerWidget(ai_debug_company + AID_WIDGET_COMPANY_BUTTON_START);
 
				this->SetDirty();
 
			}
 
		}
 
		if (widget == AID_WIDGET_RELOAD_TOGGLE && !this->IsWidgetDisabled(widget)) {
 
			/* First kill the company of the AI, then start a new one. This should start the current AI again */
 
			DoCommandP(0, 2, ai_debug_company, CMD_COMPANY_CTRL);
 
			DoCommandP(0, 1, 0, CMD_COMPANY_CTRL);
 
		}
 
	}
 

	
 
	virtual void OnTimeout()
 
	{
 
		this->RaiseWidget(AID_WIDGET_RELOAD_TOGGLE);
 
		this->SetDirty();
 
	}
 

	
 
	virtual void OnInvalidateData(int data = 0)
 
	{
 
		if (data == -1 || ai_debug_company == data) this->SetDirty();
 
	}
 

	
 
	virtual void OnResize(Point new_size, Point delta)
 
	{
 
		this->vscroll.cap += delta.y / (int)this->resize.step_height;
 
	}
 
};
 

	
 
CompanyID AIDebugWindow::ai_debug_company = INVALID_COMPANY;
 

	
 
static const Widget _ai_debug_widgets[] = {
 
{   WWT_CLOSEBOX,   RESIZE_NONE,  COLOUR_GREY,     0,    10,     0,    13, STR_00C5,                   STR_018B_CLOSE_WINDOW},                 // AID_WIDGET_CLOSEBOX
 
{    WWT_CAPTION,  RESIZE_RIGHT,  COLOUR_GREY,    11,   298,     0,    13, STR_AI_DEBUG,               STR_018C_WINDOW_TITLE_DRAG_THIS},       // AID_WIDGET_CAPTION
 
{      WWT_PANEL,  RESIZE_RIGHT,  COLOUR_GREY,     0,   298,    14,    40, 0x0,                        STR_NULL},                              // AID_WIDGET_VIEW
 

	
 
{      WWT_PANEL,  RESIZE_RIGHT,  COLOUR_GREY,     0,   149,    41,    60, 0x0,                        STR_AI_DEBUG_NAME_TIP},                 // AID_WIDGET_NAME_TEXT
 
{ WWT_PUSHTXTBTN,     RESIZE_LR,  COLOUR_GREY,   150,   298,    41,    60, STR_AI_DEBUG_RELOAD,        STR_AI_DEBUG_RELOAD_TIP},               // AID_WIDGET_RELOAD_TOGGLE
 
{      WWT_PANEL,     RESIZE_RB,  COLOUR_GREY,     0,   286,    61,   240, 0x0,                        STR_NULL},                              // AID_WIDGET_LOG_PANEL
 
{  WWT_SCROLLBAR,    RESIZE_LRB,  COLOUR_GREY,   287,   298,    61,   228, STR_NULL,                   STR_0190_SCROLL_BAR_SCROLLS_LIST},      // AID_WIDGET_SCROLLBAR
 
/* As this is WIP, leave the next few so we can work a bit with the GUI */
 
{      WWT_EMPTY,   RESIZE_NONE,  COLOUR_GREY,     0,   298,   101,   120, 0x0,                        STR_NULL},                              // AID_WIDGET_UNUSED_1
 
{      WWT_EMPTY,   RESIZE_NONE,  COLOUR_GREY,     0,   298,   121,   140, 0x0,                        STR_NULL},                              // AID_WIDGET_UNUSED_2
 
{      WWT_EMPTY,   RESIZE_NONE,  COLOUR_GREY,     0,   298,   141,   160, 0x0,                        STR_NULL},                              // AID_WIDGET_UNUSED_3
 
{      WWT_EMPTY,   RESIZE_NONE,  COLOUR_GREY,     0,   298,   161,   180, 0x0,                        STR_NULL},                              // AID_WIDGET_UNUSED_4
 
{      WWT_EMPTY,   RESIZE_NONE,  COLOUR_GREY,     0,   298,   181,   200, 0x0,                        STR_NULL},                              // AID_WIDGET_UNUSED_5
 
{      WWT_EMPTY,   RESIZE_NONE,  COLOUR_GREY,     0,   298,   201,   220, 0x0,                        STR_NULL},                              // AID_WIDGET_UNUSED_6
 
{      WWT_EMPTY,   RESIZE_NONE,  COLOUR_GREY,     0,   298,   221,   240, 0x0,                        STR_NULL},                              // AID_WIDGET_UNUSED_7
 

	
 
{      WWT_PANEL,   RESIZE_NONE,  COLOUR_GREY,     2,    38,    14,    26, 0x0,                        STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY}, // AID_WIDGET_COMPANY_BUTTON_START
 
{      WWT_PANEL,   RESIZE_NONE,  COLOUR_GREY,    39,    75,    14,    26, 0x0,                        STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY},
 
{      WWT_PANEL,   RESIZE_NONE,  COLOUR_GREY,    76,   112,    14,    26, 0x0,                        STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY},
 
{      WWT_PANEL,   RESIZE_NONE,  COLOUR_GREY,   113,   149,    14,    26, 0x0,                        STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY},
 
{      WWT_PANEL,   RESIZE_NONE,  COLOUR_GREY,   150,   186,    14,    26, 0x0,                        STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY},
 
{      WWT_PANEL,   RESIZE_NONE,  COLOUR_GREY,   187,   223,    14,    26, 0x0,                        STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY},
 
{      WWT_PANEL,   RESIZE_NONE,  COLOUR_GREY,   224,   260,    14,    26, 0x0,                        STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY},
 
{      WWT_PANEL,   RESIZE_NONE,  COLOUR_GREY,   261,   297,    14,    26, 0x0,                        STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY},
 
{      WWT_PANEL,   RESIZE_NONE,  COLOUR_GREY,     2,    38,    27,    39, 0x0,                        STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY},
 
{      WWT_PANEL,   RESIZE_NONE,  COLOUR_GREY,    39,    75,    27,    39, 0x0,                        STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY},
 
{      WWT_PANEL,   RESIZE_NONE,  COLOUR_GREY,    76,   112,    27,    39, 0x0,                        STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY},
 
{      WWT_PANEL,   RESIZE_NONE,  COLOUR_GREY,   113,   149,    27,    39, 0x0,                        STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY},
 
{      WWT_PANEL,   RESIZE_NONE,  COLOUR_GREY,   150,   186,    27,    39, 0x0,                        STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY},
 
{      WWT_PANEL,   RESIZE_NONE,  COLOUR_GREY,   187,   223,    27,    39, 0x0,                        STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY},
 
{      WWT_PANEL,   RESIZE_NONE,  COLOUR_GREY,   224,   260,    27,    39, 0x0,                        STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY}, // AID_WIDGET_COMPANY_BUTTON_END
 
{  WWT_RESIZEBOX,   RESIZE_LRTB,  COLOUR_GREY,   287,   298,   229,   240, STR_NULL,                   STR_RESIZE_BUTTON},
 
{   WIDGETS_END},
 
};
 

	
 
static const WindowDesc _ai_debug_desc = {
 
	WDP_AUTO, WDP_AUTO, 299, 241, 299, 241,
 
	WC_AI_DEBUG, WC_NONE,
 
	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_RESIZABLE,
 
	_ai_debug_widgets
 
};
 

	
 
void ShowAIDebugWindow()
 
{
 
	if (!_networking || _network_server) {
 
		AllocateWindowDescFront<AIDebugWindow>(&_ai_debug_desc, 0);
 
	} else {
 
		ShowErrorMessage(INVALID_STRING_ID, STR_AI_DEBUG_SERVER_ONLY, 0, 0);
 
	}
 
}
src/ai/ai_gui.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_gui.hpp Window for configuring the AIs  */
 

	
 
#ifndef AI_GUI_HPP
 
#define AI_GUI_HPP
 

	
 
void ShowAIDebugWindow();
 

	
 
#endif /* AI_GUI_HPP */
src/ai/ai_info.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_info.cpp Implementation of AIFileInfo */
 

	
 
#include "../stdafx.h"
 
#include "../core/alloc_func.hpp"
 

	
 
#include <squirrel.h>
 
#include "../script/squirrel.hpp"
 
#include "../script/squirrel_helper.hpp"
 
#include "../script/squirrel_class.hpp"
 
#include "../script/squirrel_std.hpp"
 
#include "ai.hpp"
 
#include "ai_info.hpp"
 
#include "ai_scanner.hpp"
 
#include "api/ai_controller.hpp"
 
#include "../settings_type.h"
 
#include "../openttd.h"
 

	
 
AIFileInfo::~AIFileInfo()
 
{
 
	this->engine->ReleaseObject(this->SQ_instance);
 
	free((void *)this->author);
 
	free((void *)this->name);
 
	free((void *)this->description);
 
	free((void *)this->date);
 
	free((void *)this->instance_name);
 
	free(this->script_name);
 
	free(this->dir_name);
 
	free(this->SQ_instance);
 
}
 

	
 
const char *AIFileInfo::GetAuthor()
 
{
 
	if (this->author == NULL) this->author = this->engine->CallStringMethodStrdup(*this->SQ_instance, "GetAuthor");
 
	return this->author;
 
}
 

	
 
const char *AIFileInfo::GetName()
 
{
 
	if (this->name == NULL) this->name = this->engine->CallStringMethodStrdup(*this->SQ_instance, "GetName");
 
	return this->name;
 
}
 

	
 
const char *AIFileInfo::GetDescription()
 
{
 
	if (this->description == NULL) this->description = this->engine->CallStringMethodStrdup(*this->SQ_instance, "GetDescription");
 
	return this->description;
 
}
 

	
 
int AIFileInfo::GetVersion()
 
{
 
	return this->engine->CallIntegerMethod(*this->SQ_instance, "GetVersion");
 
}
 

	
 
void AIFileInfo::GetSettings()
 
{
 
	this->engine->CallMethod(*this->SQ_instance, "GetSettings", NULL, -1);
 
}
 

	
 
const char *AIFileInfo::GetDate()
 
{
 
	if (this->date == NULL) this->date = this->engine->CallStringMethodStrdup(*this->SQ_instance, "GetDate");
 
	return this->date;
 
}
 

	
 
const char *AIFileInfo::GetInstanceName()
 
{
 
	if (this->instance_name == NULL) this->instance_name = this->engine->CallStringMethodStrdup(*this->SQ_instance, "CreateInstance");
 
	return this->instance_name;
 
}
 

	
 
bool AIFileInfo::AllowStartup()
 
{
 
	return true;
 
}
 

	
 
const char *AIFileInfo::GetDirName()
 
{
 
	return this->dir_name;
 
}
 

	
 
const char *AIFileInfo::GetScriptName()
 
{
 
	return this->script_name;
 
}
 

	
 
void AIFileInfo::CheckMethods(SQInteger *res, const char *name)
 
{
 
	if (!this->engine->MethodExists(*this->SQ_instance, name)) {
 
		char error[1024];
 
		snprintf(error, sizeof(error), "your AIFileInfo doesn't have the method '%s'", name);
 
		this->engine->ThrowError(error);
 
		*res = SQ_ERROR;
 
	}
 
}
 

	
 
/* static */ SQInteger AIFileInfo::Constructor(HSQUIRRELVM vm, AIFileInfo *info)
 
{
 
	SQInteger res = 0;
 

	
 
	/* Set some basic info from the parent */
 
	info->SQ_instance = MallocT<SQObject>(1);
 
	Squirrel::GetInstance(vm, info->SQ_instance, 2);
 
	/* Make sure the instance stays alive over time */
 
	sq_addref(vm, info->SQ_instance);
 
	info->base = ((AIScanner *)Squirrel::GetGlobalPointer(vm));
 
	info->engine = info->base->GetEngine();
 

	
 
	/* Check if all needed fields are there */
 
	info->CheckMethods(&res, "GetAuthor");
 
	info->CheckMethods(&res, "GetName");
 
	info->CheckMethods(&res, "GetDescription");
 
	info->CheckMethods(&res, "GetVersion");
 
	info->CheckMethods(&res, "GetDate");
 
	info->CheckMethods(&res, "CreateInstance");
 

	
 
	/* Abort if one method was missing */
 
	if (res != 0) return res;
 

	
 
	info->script_name = strdup(info->base->GetCurrentScript());
 
	info->dir_name = strdup(info->base->GetCurrentDirName());
 

	
 
	return 0;
 
}
 

	
 
/* static */ SQInteger AIInfo::Constructor(HSQUIRRELVM vm)
 
{
 
	/* Get the AIInfo */
 
	SQUserPointer instance;
 
	sq_getinstanceup(vm, 2, &instance, 0);
 
	AIInfo *info = (AIInfo *)instance;
 

	
 
	SQInteger res = AIFileInfo::Constructor(vm, info);
 
	if (res != 0) return res;
 

	
 
	AIConfigItem config;
 
	config.name = strdup("start_date");
 
	config.description = strdup("The amount of months after the start of the last AI, this AI will start (give or take).");
 
	config.min_value = 0;
 
	config.max_value = 120;
 
	config.easy_value = 48;
 
	config.medium_value = 24;
 
	config.hard_value = 12;
 
	config.custom_value = 24;
 
	config.flags = AICONFIG_NONE;
 
	info->config_list.push_back(config);
 

	
 
	/* Check if we have settings */
 
	if (info->engine->MethodExists(*info->SQ_instance, "GetSettings")) {
 
		info->GetSettings();
 
	}
 

	
 
	/* Remove the link to the real instance, else it might get deleted by RegisterAI() */
 
	sq_setinstanceup(vm, 2, NULL);
 
	/* Register the AI to the base system */
 
	info->base->RegisterAI(info);
 
	return 0;
 
}
 

	
 
/* static */ SQInteger AIInfo::DummyConstructor(HSQUIRRELVM vm)
 
{
 
	/* Get the AIInfo */
 
	SQUserPointer instance;
 
	sq_getinstanceup(vm, 2, &instance, 0);
 
	AIInfo *info = (AIInfo *)instance;
 

	
 
	SQInteger res = AIFileInfo::Constructor(vm, info);
 
	if (res != 0) return res;
 

	
 
	/* Remove the link to the real instance, else it might get deleted by RegisterAI() */
 
	sq_setinstanceup(vm, 2, NULL);
 
	/* Register the AI to the base system */
 
	info->base->SetDummyAI(info);
 
	return 0;
 
}
 

	
 
AIInfo::~AIInfo()
 
{
 
	/* Free all allocated strings */
 
	for (AIConfigItemList::iterator it = this->config_list.begin(); it != this->config_list.end(); it++) {
 
		free((char *)(*it).name);
 
	}
 
	this->config_list.clear();
 
}
 

	
 
SQInteger AIInfo::AddSetting(HSQUIRRELVM vm)
 
{
 
	AIConfigItem config;
 
	memset(&config, 0, sizeof(config));
 
	int items = 0;
 

	
 
	/* Read the table, and find all properties we care about */
 
	sq_pushnull(vm);
 
	while (SQ_SUCCEEDED(sq_next(vm, -2))) {
 
		const SQChar *sqkey;
 
		sq_getstring(vm, -2, &sqkey);
 
		const char *key = FS2OTTD(sqkey);
 

	
 
		if (strcmp(key, "name") == 0) {
 
			const SQChar *sqvalue;
 
			sq_getstring(vm, -1, &sqvalue);
 
			config.name = strdup(FS2OTTD(sqvalue));
 
			char *s;
 
			/* Don't allow '=' and ',' in configure setting names, as we need those
 
			 *  2 chars to nicely store the settings as a string. */
 
			while ((s = (char *)strchr(config.name, '=')) != NULL) *s = '_';
 
			while ((s = (char *)strchr(config.name, ',')) != NULL) *s = '_';
 
			items |= 0x001;
 
		} else if (strcmp(key, "description") == 0) {
 
			const SQChar *sqdescription;
 
			sq_getstring(vm, -1, &sqdescription);
 
			config.description = strdup(FS2OTTD(sqdescription));
 
			items |= 0x002;
 
		} else if (strcmp(key, "min_value") == 0) {
 
			SQInteger res;
 
			sq_getinteger(vm, -1, &res);
 
			config.min_value = res;
 
			items |= 0x004;
 
		} else if (strcmp(key, "max_value") == 0) {
 
			SQInteger res;
 
			sq_getinteger(vm, -1, &res);
 
			config.max_value = res;
 
			items |= 0x008;
 
		} else if (strcmp(key, "easy_value") == 0) {
 
			SQInteger res;
 
			sq_getinteger(vm, -1, &res);
 
			config.easy_value = res;
 
			items |= 0x010;
 
		} else if (strcmp(key, "medium_value") == 0) {
 
			SQInteger res;
 
			sq_getinteger(vm, -1, &res);
 
			config.medium_value = res;
 
			items |= 0x020;
 
		} else if (strcmp(key, "hard_value") == 0) {
 
			SQInteger res;
 
			sq_getinteger(vm, -1, &res);
 
			config.hard_value = res;
 
			items |= 0x040;
 
		} else if (strcmp(key, "custom_value") == 0) {
 
			SQInteger res;
 
			sq_getinteger(vm, -1, &res);
 
			config.custom_value = res;
 
			items |= 0x080;
 
		} else if (strcmp(key, "flags") == 0) {
 
			SQInteger res;
 
			sq_getinteger(vm, -1, &res);
 
			config.flags = (AIConfigFlags)res;
 
			items |= 0x100;
 
		} else {
 
			char error[1024];
 
			snprintf(error, sizeof(error), "unknown setting property '%s'", key);
 
			this->engine->ThrowError(error);
 
			return SQ_ERROR;
 
		}
 

	
 
		sq_pop(vm, 2);
 
	}
 
	sq_pop(vm, 1);
 

	
 
	/* Make sure all properties are defined */
 
	if (items != 0x1FF) {
 
		char error[1024];
 
		snprintf(error, sizeof(error), "please define all properties of a setting");
 
		this->engine->ThrowError(error);
 
		return SQ_ERROR;
 
	}
 

	
 
	this->config_list.push_back(config);
 
	return 0;
 
}
 

	
 
const AIConfigItemList *AIInfo::GetConfigList()
 
{
 
	return &this->config_list;
 
}
 

	
 
int AIInfo::GetSettingDefaultValue(const char *name)
 
{
 
	for (AIConfigItemList::iterator it = this->config_list.begin(); it != this->config_list.end(); it++) {
 
		if (strcmp((*it).name, name) != 0) continue;
 
		/* The default value depends on the difficulty level */
 
		switch ((_game_mode == GM_MENU) ? _settings_newgame.difficulty.diff_level : _settings_game.difficulty.diff_level) {
 
			case 0: return (*it).easy_value;
 
			case 1: return (*it).medium_value;
 
			case 2: return (*it).hard_value;
 
			case 3: return (*it).custom_value;
 
			default: NOT_REACHED();
 
		}
 
	}
 

	
 
	/* There is no such setting */
 
	return -1;
 
}
 

	
 
/* static */ SQInteger AILibrary::Constructor(HSQUIRRELVM vm)
 
{
 
	/* Create a new AIFileInfo */
 
	AILibrary *library = new AILibrary();
 

	
 
	SQInteger res = AIFileInfo::Constructor(vm, library);
 
	if (res != 0) return res;
 

	
 
	/* Register the Library to the base system */
 
	library->base->RegisterLibrary(library);
 

	
 
	return 0;
 
}
 

	
 
/* static */ SQInteger AILibrary::Import(HSQUIRRELVM vm)
 
{
 
	SQConvert::SQAutoFreePointers ptr;
 
	const char *library = GetParam(SQConvert::ForceType<const char *>(), vm, 2, &ptr);
 
	const char *class_name = GetParam(SQConvert::ForceType<const char *>(), vm, 3, &ptr);
 
	int version = GetParam(SQConvert::ForceType<int>(), vm, 4, &ptr);
 

	
 
	if (!AI::ImportLibrary(library, class_name, version, vm)) return -1;
 
	return 1;
 
}
src/ai/ai_info.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_info.hpp AIInfo keeps track of all information of an AI, like Author, Description, ... */
 

	
 
#ifndef AI_INFO
 
#define AI_INFO
 

	
 
#include <list>
 
#include "api/ai_object.hpp"
 

	
 
enum AIConfigFlags {
 
	AICONFIG_NONE    = 0x0,
 
	AICONFIG_RANDOM  = 0x1, //!< When randomizing the AI, pick any value between min_value and max_value when on custom difficulty setting.
 
	AICONFIG_BOOLEAN = 0x2, //!< This value is a boolean (either 0 (false) or 1 (true) ).
 
};
 

	
 
struct AIConfigItem {
 
	const char *name;        //!< The name of the configuration setting.
 
	const char *description; //!< The description of the configuration setting.
 
	int min_value;           //!< The minimal value this configuration setting can have.
 
	int max_value;           //!< The maximal value this configuration setting can have.
 
	int custom_value;        //!< The default value on custom difficulty setting.
 
	int easy_value;          //!< The default value on easy difficulty setting.
 
	int medium_value;        //!< The default value on medium difficulty setting.
 
	int hard_value;          //!< The default value on hard difficulty setting.
 
	AIConfigFlags flags;     //!< Flags for the configuration setting.
 
};
 

	
 
typedef std::list<AIConfigItem> AIConfigItemList;
 

	
 
class AIFileInfo : public AIObject {
 
public:
 
	friend class AIInfo;
 
	friend class AILibrary;
 

	
 
	AIFileInfo() : author(NULL), name(NULL), description(NULL), date(NULL), instance_name(NULL) {};
 
	~AIFileInfo();
 

	
 
	/**
 
	 * Get the Author of the AI.
 
	 */
 
	const char *GetAuthor();
 

	
 
	/**
 
	 * Get the Name of the AI.
 
	 */
 
	const char *GetName();
 

	
 
	/**
 
	 * Get the description of the AI.
 
	 */
 
	const char *GetDescription();
 

	
 
	/**
 
	 * Get the version of the AI.
 
	 */
 
	int GetVersion();
 

	
 
	/**
 
	 * Get the settings of the AI.
 
	 */
 
	void GetSettings();
 

	
 
	/**
 
	 * Get the date of the AI.
 
	 */
 
	const char *GetDate();
 

	
 
	/**
 
	 * Get the name of the instance of the AI to create.
 
	 */
 
	const char *GetInstanceName();
 

	
 
	/**
 
	 * Check if we can start this AI.
 
	 */
 
	bool AllowStartup();
 

	
 
	/**
 
	 * Get the name of the dir this AI is in.
 
	 */
 
	const char *GetDirName();
 

	
 
	/**
 
	 * Get the complete script name of this AI.
 
	 */
 
	const char *GetScriptName();
 

	
 
	/**
 
	 * Check if a given method exists.
 
	 */
 
	void CheckMethods(SQInteger *res, const char *name);
 

	
 
	/**
 
	 * Process the creation of a FileInfo object.
 
	 */
 
	static SQInteger Constructor(HSQUIRRELVM vm, AIFileInfo *info);
 

	
 
private:
 
	class Squirrel *engine;
 
	HSQOBJECT *SQ_instance;
 
	char *script_name;
 
	char *dir_name;
 
	class AIScanner *base;
 
	const char *author;
 
	const char *name;
 
	const char *description;
 
	const char *date;
 
	const char *instance_name;
 
};
 

	
 
class AIInfo : public AIFileInfo {
 
public:
 
	static const char *GetClassName() { return "AIInfo"; }
 

	
 
	~AIInfo();
 

	
 
	/**
 
	 * Create an AI, using this AIInfo as start-template.
 
	 */
 
	static SQInteger Constructor(HSQUIRRELVM vm);
 
	static SQInteger DummyConstructor(HSQUIRRELVM vm);
 

	
 
	/**
 
	 * Get the config list for this AI.
 
	 */
 
	const AIConfigItemList *GetConfigList();
 

	
 
	/**
 
	 * Set a setting.
 
	 */
 
	SQInteger AddSetting(HSQUIRRELVM vm);
 

	
 
	/**
 
	 * Get the default value for a setting.
 
	 */
 
	int GetSettingDefaultValue(const char *name);
 

	
 
private:
 
	AIConfigItemList config_list;
 
};
 

	
 
class AILibrary : public AIFileInfo {
 
public:
 
	/**
 
	 * Create an AI, using this AIInfo as start-template.
 
	 */
 
	static SQInteger Constructor(HSQUIRRELVM vm);
 

	
 
	static SQInteger Import(HSQUIRRELVM vm);
 
};
 

	
 
#endif /* AI_INFO */
src/ai/ai_info_dummy.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
#include <squirrel.h>
 
#include "../stdafx.h"
 

	
 
/* The reason this exists in C++, is that a user can trash his ai/ dir,
 
 *  leaving no AIs available. The complexity to solve this is insane, and
 
 *  therefor the alternative is used, and make sure there is always an AI
 
 *  available, no matter what the situation is. By defining it in C++, there
 
 *  is simply now way a user can delete it, and therefor safe to use. It has
 
 *  to be noted that this AI is complete invisible for the user, and impossible
 
 *  to select manual. It is a fail-over in case no AIs are available.
 
 */
 

	
 
const SQChar dummy_script_info[] = _SC("                                                        \n\
 
class DummyAI extends AIInfo {                                                                  \n\
 
  function GetAuthor()      { return \"OpenTTD NoAI Developers Team\"; }                        \n\
 
  function GetName()        { return \"DummyAI\"; }                                             \n\
 
  function GetDescription() { return \"A Dummy AI that is loaded when your ai/ dir is empty\"; }\n\
 
  function GetVersion()     { return 1; }                                                       \n\
 
  function GetDate()        { return \"2008-07-26\"; }                                          \n\
 
  function CreateInstance() { return \"DummyAI\"; }                                             \n\
 
}                                                                                               \n\
 
                                                                                                \n\
 
RegisterDummyAI(DummyAI());                                                                     \n\
 
");
 

	
 
const SQChar dummy_script[] = _SC("                                                             \n\
 
class DummyAI extends AIController {                                                            \n\
 
  function Start() {                                                                            \n\
 
    AILog.Error(\"No suitable AI found to load.\");                                             \n\
 
    AILog.Error(\"This AI is a dummy AI and won't do anything.\");                              \n\
 
    AILog.Error(\"Please add one or several AIs in your ai/ directory.\");                      \n\
 
  }                                                                                             \n\
 
}                                                                                               \n\
 
");
 

	
 
void AI_CreateAIInfoDummy(HSQUIRRELVM vm)
 
{
 
	sq_pushroottable(vm);
 

	
 
	/* Load and run the script */
 
	if (SQ_SUCCEEDED(sq_compilebuffer(vm, dummy_script_info, scstrlen(dummy_script_info), _SC("dummy"), SQTrue))) {
 
		sq_push(vm, -2);
 
		if (SQ_SUCCEEDED(sq_call(vm, 1, SQFalse, SQTrue))) {
 
			sq_pop(vm, 1);
 
			return;
 
		}
 
	}
 
	NOT_REACHED();
 
}
 

	
 
void AI_CreateAIDummy(HSQUIRRELVM vm)
 
{
 
	sq_pushroottable(vm);
 

	
 
	/* Load and run the script */
 
	if (SQ_SUCCEEDED(sq_compilebuffer(vm, dummy_script, scstrlen(dummy_script), _SC("dummy"), SQTrue))) {
 
		sq_push(vm, -2);
 
		if (SQ_SUCCEEDED(sq_call(vm, 1, SQFalse, SQTrue))) {
 
			sq_pop(vm, 1);
 
			return;
 
		}
 
	}
 
	NOT_REACHED();
 
}
src/ai/ai_instance.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_instance.cpp Implementation of AIInstance. */
 

	
 
#include "../stdafx.h"
 
#include "../openttd.h"
 
#include "../debug.h"
 
#include "../company_func.h"
 
#include "../core/alloc_func.hpp"
 
#include "../string_func.h"
 
#include "../settings_type.h"
 
#include "../company_base.h"
 
#include "../saveload/saveload.h"
 
#include "table/strings.h"
 

	
 
#include <squirrel.h>
 
#include "../script/squirrel.hpp"
 
#include "../script/squirrel_helper.hpp"
 
#include "../script/squirrel_class.hpp"
 
#include "../script/squirrel_std.hpp"
 
#include "ai.hpp"
 
#include "api/ai_controller.hpp"
 
#include "ai_info.hpp"
 
#include "ai_storage.hpp"
 
#include "ai_instance.hpp"
 

	
 
/* Convert all AI related classes to Squirrel data.
 
 * Note: this line a marker in squirrel_export.sh. Do not change! */
 
#include "api/ai_abstractlist.hpp.sq"
 
#include "api/ai_accounting.hpp.sq"
 
#include "api/ai_airport.hpp.sq"
 
#include "api/ai_base.hpp.sq"
 
#include "api/ai_bridge.hpp.sq"
 
#include "api/ai_bridgelist.hpp.sq"
 
#include "api/ai_cargo.hpp.sq"
 
#include "api/ai_cargolist.hpp.sq"
 
#include "api/ai_company.hpp.sq"
 
#include "api/ai_controller.hpp.sq"
 
#include "api/ai_date.hpp.sq"
 
#include "api/ai_depotlist.hpp.sq"
 
#include "api/ai_engine.hpp.sq"
 
#include "api/ai_enginelist.hpp.sq"
 
#include "api/ai_error.hpp.sq"
 
#include "api/ai_event.hpp.sq"
 
#include "api/ai_event_types.hpp.sq"
 
#include "api/ai_execmode.hpp.sq"
 
#include "api/ai_gamesettings.hpp.sq"
 
#include "api/ai_group.hpp.sq"
 
#include "api/ai_grouplist.hpp.sq"
 
#include "api/ai_industry.hpp.sq"
 
#include "api/ai_industrylist.hpp.sq"
 
#include "api/ai_industrytype.hpp.sq"
 
#include "api/ai_industrytypelist.hpp.sq"
 
#include "api/ai_list.hpp.sq"
 
#include "api/ai_log.hpp.sq"
 
#include "api/ai_map.hpp.sq"
 
#include "api/ai_marine.hpp.sq"
 
#include "api/ai_order.hpp.sq"
 
#include "api/ai_rail.hpp.sq"
 
#include "api/ai_railtypelist.hpp.sq"
 
#include "api/ai_road.hpp.sq"
 
#include "api/ai_sign.hpp.sq"
 
#include "api/ai_station.hpp.sq"
 
#include "api/ai_stationlist.hpp.sq"
 
#include "api/ai_subsidy.hpp.sq"
 
#include "api/ai_subsidylist.hpp.sq"
 
#include "api/ai_testmode.hpp.sq"
 
#include "api/ai_tile.hpp.sq"
 
#include "api/ai_tilelist.hpp.sq"
 
#include "api/ai_town.hpp.sq"
 
#include "api/ai_townlist.hpp.sq"
 
#include "api/ai_tunnel.hpp.sq"
 
#include "api/ai_vehicle.hpp.sq"
 
#include "api/ai_vehiclelist.hpp.sq"
 

	
 
/* static */ AIInstance *AIInstance::current_instance = NULL;
 

	
 
AIStorage::~AIStorage()
 
{
 
	/* Free our pointers */
 
	if (event_data != NULL) AIEventController::FreeEventPointer();
 
	if (log_data != NULL) AILog::FreeLogPointer();
 
}
 

	
 
static void PrintFunc(bool error_msg, const SQChar *message)
 
{
 
	/* Convert to OpenTTD internal capable string */
 
	AIController::Print(error_msg, FS2OTTD(message));
 
}
 

	
 
AIInstance::AIInstance(AIInfo *info) :
 
	controller(NULL),
 
	storage(NULL),
 
	engine(NULL),
 
	instance(NULL),
 
	is_started(false),
 
	is_dead(false),
 
	suspend(0),
 
	callback(NULL)
 
{
 
	/* Set the instance already, so we can use AIObject::Set commands */
 
	GetCompany(_current_company)->ai_instance = this;
 
	AIInstance::current_instance = this;
 

	
 
	this->controller = new AIController();
 
	this->storage    = new AIStorage();
 
	this->engine     = new Squirrel();
 
	this->engine->SetPrintFunction(&PrintFunc);
 

	
 
	/* The import method is available at a very early stage */
 
	this->engine->AddMethod("import", &AILibrary::Import, 4, "?ssi");
 

	
 
	/* Register the AIController */
 
	SQAIController_Register(this->engine);
 

	
 
	/* Load and execute the script for this AI */
 
	const char *script_name = info->GetScriptName();
 
	if (strcmp(script_name, "%_dummy") == 0) {
 
		extern void AI_CreateAIDummy(HSQUIRRELVM vm);
 
		AI_CreateAIDummy(this->engine->GetVM());
 
	} else if (!this->engine->LoadScript(script_name)) {
 
		this->Died();
 
		return;
 
	}
 

	
 
	/* Create the main-class */
 
	this->instance = MallocT<SQObject>(1);
 
	if (!this->engine->CreateClassInstance(info->GetInstanceName(), this->controller, this->instance)) {
 
		this->Died();
 
		return;
 
	}
 

	
 
	/* Register the API functions and classes */
 
	this->RegisterAPI();
 

	
 
	/* Run the constructor if it exists. Don't allow any DoCommands in it. */
 
	if (this->engine->MethodExists(*this->instance, "constructor")) {
 
		AIObject::SetAllowDoCommand(false);
 
		this->engine->CallMethod(*this->instance, "constructor");
 
		AIObject::SetAllowDoCommand(true);
 
	}
 
}
 

	
 
AIInstance::~AIInstance()
 
{
 
	if (engine != NULL) delete this->engine;
 
	delete this->storage;
 
	delete this->controller;
 
	free(this->instance);
 
}
 

	
 
void AIInstance::RegisterAPI()
 
{
 
/* Register all classes */
 
	squirrel_register_std(this->engine);
 
	SQAIAbstractList_Register(this->engine);
 
	SQAIAccounting_Register(this->engine);
 
	SQAIAirport_Register(this->engine);
 
	SQAIBase_Register(this->engine);
 
	SQAIBridge_Register(this->engine);
 
	SQAIBridgeList_Register(this->engine);
 
	SQAIBridgeList_Length_Register(this->engine);
 
	SQAICargo_Register(this->engine);
 
	SQAICargoList_Register(this->engine);
 
	SQAICargoList_IndustryAccepting_Register(this->engine);
 
	SQAICargoList_IndustryProducing_Register(this->engine);
 
	SQAICompany_Register(this->engine);
 
	SQAIDate_Register(this->engine);
 
	SQAIDepotList_Register(this->engine);
 
	SQAIEngine_Register(this->engine);
 
	SQAIEngineList_Register(this->engine);
 
	SQAIError_Register(this->engine);
 
	SQAIEvent_Register(this->engine);
 
	SQAIEventCompanyBankrupt_Register(this->engine);
 
	SQAIEventCompanyInTrouble_Register(this->engine);
 
	SQAIEventCompanyMerger_Register(this->engine);
 
	SQAIEventCompanyNew_Register(this->engine);
 
	SQAIEventController_Register(this->engine);
 
	SQAIEventEngineAvailable_Register(this->engine);
 
	SQAIEventEnginePreview_Register(this->engine);
 
	SQAIEventIndustryClose_Register(this->engine);
 
	SQAIEventIndustryOpen_Register(this->engine);
 
	SQAIEventStationFirstVehicle_Register(this->engine);
 
	SQAIEventSubsidyAwarded_Register(this->engine);
 
	SQAIEventSubsidyExpired_Register(this->engine);
 
	SQAIEventSubsidyOffer_Register(this->engine);
 
	SQAIEventSubsidyOfferExpired_Register(this->engine);
 
	SQAIEventTest_Register(this->engine);
 
	SQAIEventVehicleCrashed_Register(this->engine);
 
	SQAIEventVehicleLost_Register(this->engine);
 
	SQAIEventVehicleUnprofitable_Register(this->engine);
 
	SQAIEventVehicleWaitingInDepot_Register(this->engine);
 
	SQAIExecMode_Register(this->engine);
 
	SQAIGameSettings_Register(this->engine);
 
	SQAIGroup_Register(this->engine);
 
	SQAIGroupList_Register(this->engine);
 
	SQAIIndustry_Register(this->engine);
 
	SQAIIndustryList_Register(this->engine);
 
	SQAIIndustryList_CargoAccepting_Register(this->engine);
 
	SQAIIndustryList_CargoProducing_Register(this->engine);
 
	SQAIIndustryType_Register(this->engine);
 
	SQAIIndustryTypeList_Register(this->engine);
 
	SQAIList_Register(this->engine);
 
	SQAILog_Register(this->engine);
 
	SQAIMap_Register(this->engine);
 
	SQAIMarine_Register(this->engine);
 
	SQAIOrder_Register(this->engine);
 
	SQAIRail_Register(this->engine);
 
	SQAIRailTypeList_Register(this->engine);
 
	SQAIRoad_Register(this->engine);
 
	SQAISign_Register(this->engine);
 
	SQAIStation_Register(this->engine);
 
	SQAIStationList_Register(this->engine);
 
	SQAIStationList_Vehicle_Register(this->engine);
 
	SQAISubsidy_Register(this->engine);
 
	SQAISubsidyList_Register(this->engine);
 
	SQAITestMode_Register(this->engine);
 
	SQAITile_Register(this->engine);
 
	SQAITileList_Register(this->engine);
 
	SQAITileList_IndustryAccepting_Register(this->engine);
 
	SQAITileList_IndustryProducing_Register(this->engine);
 
	SQAITileList_StationType_Register(this->engine);
 
	SQAITown_Register(this->engine);
 
	SQAITownList_Register(this->engine);
 
	SQAITunnel_Register(this->engine);
 
	SQAIVehicle_Register(this->engine);
 
	SQAIVehicleList_Register(this->engine);
 
	SQAIVehicleList_Station_Register(this->engine);
 

	
 
	this->engine->SetGlobalPointer(this->engine);
 
}
 

	
 
void AIInstance::Continue()
 
{
 
	assert(this->suspend < 0);
 
	this->suspend = -this->suspend - 1;
 
}
 

	
 
void AIInstance::Died()
 
{
 
	DEBUG(ai, 0, "The AI died unexpectedly.");
 
	this->is_dead = true;
 

	
 
	delete this->engine;
 
	this->engine = NULL;
 
}
 

	
 
void AIInstance::GameLoop()
 
{
 
	if (this->is_dead) return;
 
	this->controller->ticks++;
 

	
 
	if (this->suspend   < -1) this->suspend++; // Multiplayer suspend, increase up to -1.
 
	if (this->suspend   < 0)  return;          // Multiplayer suspend, wait for Continue().
 
	if (--this->suspend > 0)  return;          // Singleplayer suspend, decrease to 0.
 

	
 
	/* If there is a callback to call, call that first */
 
	if (this->callback != NULL) {
 
		try {
 
			this->callback(this);
 
		} catch (AI_VMSuspend e) {
 
			this->suspend  = e.GetSuspendTime();
 
			this->callback = e.GetSuspendCallback();
 

	
 
			return;
 
		}
 
	}
 

	
 
	this->suspend  = 0;
 
	this->callback = NULL;
 

	
 
	if (!this->is_started) {
 
		/* Start the AI by calling Start() */
 
		try {
 
			if (!this->engine->CallMethod(*this->instance, "Start",  _settings_game.ai.ai_max_opcode_till_suspend)) this->Died();
 
		} catch (AI_VMSuspend e) {
 
			this->suspend  = e.GetSuspendTime();
 
			this->callback = e.GetSuspendCallback();
 
		}
 

	
 
		this->is_started = true;
 
		return;
 
	}
 

	
 
	/* Continue the VM */
 
	try {
 
		if (!this->engine->Resume(_settings_game.ai.ai_max_opcode_till_suspend)) this->Died();
 
	} catch (AI_VMSuspend e) {
 
		this->suspend  = e.GetSuspendTime();
 
		this->callback = e.GetSuspendCallback();
 
	}
 
}
 

	
 
/* static */ void AIInstance::DoCommandReturn(AIInstance *instance)
 
{
 
	instance->engine->InsertResult(AIObject::GetLastCommandRes());
 
}
 

	
 
/* static */ void AIInstance::DoCommandReturnVehicleID(AIInstance *instance)
 
{
 
	instance->engine->InsertResult(AIObject::GetNewVehicleID());
 
}
 

	
 
/* static */ void AIInstance::DoCommandReturnSignID(AIInstance *instance)
 
{
 
	instance->engine->InsertResult(AIObject::GetNewSignID());
 
}
 

	
 
/* static */ void AIInstance::DoCommandReturnGroupID(AIInstance *instance)
 
{
 
	instance->engine->InsertResult(AIObject::GetNewGroupID());
 
}
 

	
 
/* static */ AIStorage *AIInstance::GetStorage()
 
{
 
	assert(IsValidCompanyID(_current_company) && !IsHumanCompany(_current_company));
 
	return GetCompany(_current_company)->ai_instance->storage;
 
}
 

	
 
/*
 
 * All data is stored in the following format:
 
 * First 1 byte indicating if there is a data blob at all.
 
 * 1 byte indicating the type of data.
 
 * The data itself, this differs per type:
 
 *  - integer: a binary representation of the integer (int32).
 
 *  - string:  First one byte with the string length, then a 0-terminated char
 
 *             array. The string can't be longer then 255 bytes (including
 
 *             terminating '\0').
 
 *  - array:   All data-elements of the array are saved recursive in this
 
 *             format, and ended with an element of the type
 
 *             SQSL_ARRAY_TABLE_END.
 
 *  - table:   All key/value pairs are saved in this format (first key 1, then
 
 *             value 1, then key 2, etc.). All keys and values can have an
 
 *             arbitrary type (as long as it is supported by the save function
 
 *             of course). The table is ended with an element of the type
 
 *             SQSL_ARRAY_TABLE_END.
 
 *  - bool:    A single byte with value 1 representing true and 0 false.
 
 *  - null:    No data.
 
 */
 

	
 
/** The type of the data that follows in the savegame. */
 
enum SQSaveLoadType {
 
	SQSL_INT             = 0x00, ///< The following data is an integer.
 
	SQSL_STRING          = 0x01, ///< The following data is an string.
 
	SQSL_ARRAY           = 0x02, ///< The following data is an array.
 
	SQSL_TABLE           = 0x03, ///< The following data is an table.
 
	SQSL_BOOL            = 0x04, ///< The following data is a boolean.
 
	SQSL_NULL            = 0x05, ///< A null variable.
 
	SQSL_ARRAY_TABLE_END = 0xFF, ///< Marks the end of an array or table, no data follows.
 
};
 

	
 
static byte _ai_sl_byte;
 

	
 
static const SaveLoad _ai_byte[] = {
 
	SLEG_VAR(_ai_sl_byte, SLE_UINT8),
 
	SLE_END()
 
};
 

	
 
enum {
 
	AISAVE_MAX_DEPTH = 25, ///< The maximum recursive depth for items stored in the savegame.
 
};
 

	
 
/* static */ bool AIInstance::SaveObject(HSQUIRRELVM vm, SQInteger index, int max_depth, bool test)
 
{
 
	if (max_depth == 0) {
 
		AILog::Error("Savedata can only be nested to 5 deep. No data saved.");
 
		return false;
 
	}
 

	
 
	switch (sq_gettype(vm, index)) {
 
		case OT_INTEGER: {
 
			if (!test) {
 
				_ai_sl_byte = SQSL_INT;
 
				SlObject(NULL, _ai_byte);
 
			}
 
			SQInteger res;
 
			sq_getinteger(vm, index, &res);
 
			if (!test) {
 
				int value = (int)res;
 
				SlArray(&value, 1, SLE_INT32);
 
			}
 
			return true;
 
		}
 

	
 
		case OT_STRING: {
 
			if (!test) {
 
				_ai_sl_byte = SQSL_STRING;
 
				SlObject(NULL, _ai_byte);
 
			}
 
			const SQChar *res;
 
			sq_getstring(vm, index, &res);
 
			/* @bug if a string longer than 512 characters is given to FS2OTTD, the
 
			 *  internal buffer overflows. */
 
			const char *buf = FS2OTTD(res);
 
			size_t len = strlen(buf) + 1;
 
			if (len >= 255) {
 
				AILog::Error("Maximum string length is 254 chars. No data saved.");
 
				return false;
 
			}
 
			if (!test) {
 
				_ai_sl_byte = (byte)len;
 
				SlObject(NULL, _ai_byte);
 
				SlArray((void*)buf, len, SLE_CHAR);
 
			}
 
			return true;
 
		}
 

	
 
		case OT_ARRAY: {
 
			if (!test) {
 
				_ai_sl_byte = SQSL_ARRAY;
 
				SlObject(NULL, _ai_byte);
 
			}
 
			sq_pushnull(vm);
 
			while (SQ_SUCCEEDED(sq_next(vm, index - 1))) {
 
				/* Store the value */
 
				bool res = SaveObject(vm, -1, max_depth - 1, test);
 
				sq_pop(vm, 2);
 
				if (!res) {
 
					sq_pop(vm, 1);
 
					return false;
 
				}
 
			}
 
			sq_pop(vm, 1);
 
			if (!test) {
 
				_ai_sl_byte = SQSL_ARRAY_TABLE_END;
 
				SlObject(NULL, _ai_byte);
 
			}
 
			return true;
 
		}
 

	
 
		case OT_TABLE: {
 
			if (!test) {
 
				_ai_sl_byte = SQSL_TABLE;
 
				SlObject(NULL, _ai_byte);
 
			}
 
			sq_pushnull(vm);
 
			while (SQ_SUCCEEDED(sq_next(vm, index - 1))) {
 
				/* Store the key + value */
 
				bool res = SaveObject(vm, -2, max_depth - 1, test) && SaveObject(vm, -1, max_depth - 1, test);
 
				sq_pop(vm, 2);
 
				if (!res) {
 
					sq_pop(vm, 1);
 
					return false;
 
				}
 
			}
 
			sq_pop(vm, 1);
 
			if (!test) {
 
				_ai_sl_byte = SQSL_ARRAY_TABLE_END;
 
				SlObject(NULL, _ai_byte);
 
			}
 
			return true;
 
		}
 

	
 
		case OT_BOOL: {
 
			if (!test) {
 
				_ai_sl_byte = SQSL_BOOL;
 
				SlObject(NULL, _ai_byte);
 
			}
 
			SQBool res;
 
			sq_getbool(vm, index, &res);
 
			if (!test) {
 
				_ai_sl_byte = res ? 1 : 0;
 
				SlObject(NULL, _ai_byte);
 
			}
 
			return true;
 
		}
 

	
 
		case OT_NULL: {
 
			if (!test) {
 
				_ai_sl_byte = SQSL_NULL;
 
				SlObject(NULL, _ai_byte);
 
			}
 
			return true;
 
		}
 

	
 
		default:
 
			AILog::Error("You tried to save unsupported type. No data saved.");
 
			return false;
 
	}
 
}
 

	
 
/* static */ void AIInstance::SaveEmpty()
 
{
 
	_ai_sl_byte = 0;
 
	SlObject(NULL, _ai_byte);
 
}
 

	
 
void AIInstance::Save()
 
{
 
	/* Don't save data if the AI didn't start yet. */
 
	if (this->engine == NULL) {
 
		SaveEmpty();
 
		return;
 
	}
 

	
 
	/* We don't want to be interrupted during the save function. */
 
	AIObject::SetAllowDoCommand(false);
 

	
 
	HSQOBJECT savedata;
 
	if (this->engine->MethodExists(*this->instance, "Save")) {
 
		this->engine->CallMethod(*this->instance, "Save", &savedata);
 
		if (!sq_istable(savedata)) {
 
			AILog::Error("Save function should return a table.");
 
			_ai_sl_byte = 0;
 
			SlObject(NULL, _ai_byte);
 
			AIObject::SetAllowDoCommand(true);
 
			return;
 
		}
 
		HSQUIRRELVM vm = this->engine->GetVM();
 
		sq_pushobject(vm, savedata);
 
		if (SaveObject(vm, -1, AISAVE_MAX_DEPTH, true)) {
 
			_ai_sl_byte = 1;
 
			SlObject(NULL, _ai_byte);
 
			SaveObject(vm, -1, AISAVE_MAX_DEPTH, false);
 
		} else {
 
			_ai_sl_byte = 0;
 
			SlObject(NULL, _ai_byte);
 
		}
 
		sq_pop(vm, 1);
 
	} else {
 
		AILog::Warning("Save function is not implemented");
 
		_ai_sl_byte = 0;
 
		SlObject(NULL, _ai_byte);
 
	}
 

	
 
	AIObject::SetAllowDoCommand(true);
 
}
 

	
 
/* static */ bool AIInstance::LoadObjects(HSQUIRRELVM vm)
 
{
 
	SlObject(NULL, _ai_byte);
 
	switch (_ai_sl_byte) {
 
		case SQSL_INT: {
 
			int value;
 
			SlArray(&value, 1, SLE_INT32);
 
			if (vm != NULL) sq_pushinteger(vm, (SQInteger)value);
 
			return true;
 
		}
 

	
 
		case SQSL_STRING: {
 
			SlObject(NULL, _ai_byte);
 
			static char buf[256];
 
			SlArray(buf, _ai_sl_byte, SLE_CHAR);
 
			if (vm != NULL) sq_pushstring(vm, OTTD2FS(buf), -1);
 
			return true;
 
		}
 

	
 
		case SQSL_ARRAY: {
 
			if (vm != NULL) sq_newarray(vm, 0);
 
			while (LoadObjects(vm)) {
 
				if (vm != NULL) sq_arrayappend(vm, -2);
 
				/* The value is popped from the stack by squirrel. */
 
			}
 
			return true;
 
		}
 

	
 
		case SQSL_TABLE: {
 
			if (vm != NULL) sq_newtable(vm);
 
			while (LoadObjects(vm)) {
 
				LoadObjects(vm);
 
				if (vm != NULL) sq_rawset(vm, -3);
 
				/* The key (-2) and value (-1) are popped from the stack by squirrel. */
 
			}
 
			return true;
 
		}
 

	
 
		case SQSL_BOOL: {
 
			SlObject(NULL, _ai_byte);
 
			if (vm != NULL) sq_pushinteger(vm, (SQBool)(_ai_sl_byte != 0));
 
			return true;
 
		}
 

	
 
		case SQSL_NULL: {
 
			if (vm != NULL) sq_pushnull(vm);
 
			return true;
 
		}
 

	
 
		case SQSL_ARRAY_TABLE_END: {
 
			return false;
 
		}
 

	
 
		default: NOT_REACHED();
 
	}
 
}
 

	
 
/* static */ void AIInstance::LoadEmpty()
 
{
 
	SlObject(NULL, _ai_byte);
 
	/* Check if there was anything saved at all. */
 
	if (_ai_sl_byte == 0) return;
 

	
 
	LoadObjects(NULL);
 
}
 

	
 
bool AIInstance::Load()
 
{
 
	HSQUIRRELVM vm = (this->engine == NULL) ? NULL : this->engine->GetVM();
 

	
 
	SlObject(NULL, _ai_byte);
 
	/* Check if there was anything saved at all. */
 
	if (_ai_sl_byte == 0) return true;
 
	AIObject::SetAllowDoCommand(false);
 

	
 
	if (vm != NULL) {
 
		/* Go to the instance-root */
 
		sq_pushobject(vm, *this->instance);
 
		/* Find the function-name inside the script */
 
		sq_pushstring(vm, OTTD2FS("Load"), -1);
 
		if (SQ_FAILED(sq_get(vm, -2))) sq_pushnull(vm);
 
		sq_pushobject(vm, *this->instance);
 
	}
 

	
 
	LoadObjects(vm);
 

	
 
	if (this->engine != NULL) {
 
		if (this->engine->MethodExists(*this->instance, "Load")) {
 
			sq_call(vm, 2, SQFalse, SQFalse);
 
		} else {
 
			AILog::Warning("Loading failed: there was data for the AI to load, but the AI does not have a Load() function.");
 
		}
 
	}
 

	
 
	/* Pop 1) the object instance, 2) the function name, 3) the instance again, 4) the table. */
 
	if (vm != NULL) sq_pop(vm, 4);
 

	
 
	AIObject::SetAllowDoCommand(true);
 
	return true;
 
}
src/ai/ai_instance.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_instance.hpp The AIInstance tracks an AI. */
 

	
 
#ifndef AI_INSTANCE_HPP
 
#define AI_INSTANCE_HPP
 

	
 
/**
 
 * The callback function when an AI suspends.
 
 */
 
typedef void (AISuspendCallbackProc)(class AIInstance *instance);
 

	
 
/**
 
 * A throw-class that is given when the VM wants to suspend.
 
 */
 
class AI_VMSuspend {
 
public:
 
	AI_VMSuspend(int time, AISuspendCallbackProc *callback) :
 
		time(time),
 
		callback(callback)
 
		{}
 

	
 
	int GetSuspendTime() { return time; }
 
	AISuspendCallbackProc *GetSuspendCallback() { return callback; }
 

	
 
private:
 
	int time;
 
	AISuspendCallbackProc *callback;
 
};
 

	
 
class AIInstance {
 
public:
 
	AIInstance(class AIInfo *info);
 
	~AIInstance();
 

	
 
	/**
 
	 * An AI in multiplayer waits for the server to handle his DoCommand.
 
	 *  It keeps waiting for this until this function is called.
 
	 */
 
	void Continue();
 

	
 
	/**
 
	 * Run the GameLoop of an AI.
 
	 */
 
	void GameLoop();
 

	
 
	/**
 
	 * Get the storage of this AI.
 
	 */
 
	static class AIStorage *GetStorage();
 

	
 
	/**
 
	 * Return a true/false reply for a DoCommand.
 
	 */
 
	static void DoCommandReturn(AIInstance *instance);
 

	
 
	/**
 
	 * Return a VehicleID reply for a DoCommand.
 
	 */
 
	static void DoCommandReturnVehicleID(AIInstance *instance);
 

	
 
	/**
 
	 * Return a SignID reply for a DoCommand.
 
	 */
 
	static void DoCommandReturnSignID(AIInstance *instance);
 

	
 
	/**
 
	 * Return a GroupID reply for a DoCommand.
 
	 */
 
	static void DoCommandReturnGroupID(AIInstance *instance);
 

	
 
	/**
 
	 * Get the controller attached to the instance.
 
	 */
 
	class AIController *GetController() { return controller; }
 

	
 
	/**
 
	 * Call the AI Save function and save all data in the savegame.
 
	 */
 
	void Save();
 

	
 
	/**
 
	 * Don't save any data in the savegame.
 
	 */
 
	static void SaveEmpty();
 

	
 
	/**
 
	 * Load data from a savegame and call the AI Load function if it
 
	 *   exists.
 
	 * @return True if the loading was successfull.
 
	 */
 
	bool Load();
 

	
 
	/**
 
	 * Load and discard data from a savegame.
 
	 */
 
	static void LoadEmpty();
 

	
 
private:
 
	static class AIInstance *current_instance; //!< Static current AIInstance, so we can register AIs.
 

	
 
	class AIController *controller;
 
	class AIStorage *storage;
 
	class Squirrel *engine;
 
	SQObject *instance;
 

	
 
	bool is_started;
 
	bool is_dead;
 
	int suspend;
 
	AISuspendCallbackProc *callback;
 

	
 
	/**
 
	 * Register all API functions to the VM.
 
	 */
 
	void RegisterAPI();
 

	
 
	/**
 
	 * Tell the AI it died.
 
	 */
 
	void Died();
 

	
 
	/**
 
	 * Save one object (int / string / arrray / table) to the savegame.
 
	 * @param index The index on the squirrel stack of the element to save.
 
	 * @param max_depth The maximum depth recursive arrays / tables will be stored
 
	 *   with before an error is returned.
 
	 * @param test If true, don't really store the data but only check if it is
 
	 *   valid.
 
	 * @return True if the saving was successfull.
 
	 */
 
	static bool SaveObject(HSQUIRRELVM vm, SQInteger index, int max_depth, bool test);
 

	
 
	/**
 
	 * Load all objects from a savegame.
 
	 * @return True if the loading was successfull.
 
	 */
 
	static bool LoadObjects(HSQUIRRELVM vm);
 
};
 

	
 
#endif /* AI_INSTANCE_HPP */
src/ai/ai_scanner.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_scanner.cpp allows scanning AI scripts */
 

	
 
#include "../stdafx.h"
 
#include "../debug.h"
 
#include "../openttd.h"
 
#include "../string_func.h"
 
#include "../fileio_func.h"
 
#include "../fios.h"
 
#include "../network/network.h"
 
#include "../core/random_func.hpp"
 
#include <sys/types.h>
 
#include <sys/stat.h>
 

	
 
#include <squirrel.h>
 
#include "../script/squirrel.hpp"
 
#include "../script/squirrel_helper.hpp"
 
#include "../script/squirrel_class.hpp"
 
#include "ai.hpp"
 
#include "ai_info.hpp"
 
#include "ai_scanner.hpp"
 
#include "api/ai_controller.hpp"
 

	
 
void AIScanner::ScanDir(const char *dirname, bool library_dir, char *library_depth)
 
{
 
	extern bool FiosIsValidFile(const char *path, const struct dirent *ent, struct stat *sb);
 
	extern bool FiosIsHiddenFile(const struct dirent *ent);
 

	
 
	struct stat sb;
 
	struct dirent *dirent;
 
	DIR *dir;
 
	char d_name[MAX_PATH];
 
	char script_name[MAX_PATH];
 
	dir = ttd_opendir(dirname);
 
	/* Dir not found, so do nothing */
 
	if (dir == NULL) return;
 

	
 
	/* Walk all dirs trying to find a dir in which 'main.nut' exists */
 
	while ((dirent = readdir(dir)) != NULL) {
 
		ttd_strlcpy(d_name, FS2OTTD(dirent->d_name), sizeof(d_name));
 

	
 
		/* Valid file, not '.' or '..', not hidden */
 
		if (!FiosIsValidFile(dirname, dirent, &sb)) continue;
 
		if (strcmp(d_name, ".") == 0 || strcmp(d_name, "..") == 0) continue;
 
		if (FiosIsHiddenFile(dirent) && strncasecmp(d_name, PERSONAL_DIR, strlen(d_name)) != 0) continue;
 

	
 
		if (S_ISDIR(sb.st_mode)) {
 
			/* Create the full-length script-name */
 
			ttd_strlcpy(script_name, dirname, sizeof(script_name));
 
			ttd_strlcat(script_name, d_name, sizeof(script_name));
 
			ttd_strlcat(script_name, PATHSEP, sizeof(script_name));
 

	
 
			if (library_dir && library_depth == NULL) {
 
				ScanDir(script_name, library_dir, d_name);
 
				continue;
 
			}
 
		}
 
		if (S_ISREG(sb.st_mode)) {
 
			if (library_dir) continue;
 

	
 
			char *ext = strrchr(d_name, '.');
 
			if (ext == NULL || strcasecmp(ext, ".tar") != 0) continue;
 

	
 
			/* Create the full path to the tarfile */
 
			char tarname[MAX_PATH];
 
			ttd_strlcpy(tarname, dirname, sizeof(tarname));
 
			ttd_strlcat(tarname, d_name, sizeof(tarname));
 

	
 
			/* Now the script-name starts with the first dir in the tar */
 
			if (FioTarFirstDir(tarname) == NULL) continue;
 
			ttd_strlcpy(script_name, "%aitar%", sizeof(tarname));
 
			ttd_strlcat(script_name, FioTarFirstDir(tarname), sizeof(script_name));
 
			FioTarAddLink(script_name, FioTarFirstDir(tarname));
 

	
 
			/* The name of the AI is the name of the tar minus the .tar */
 
			*ext = '\0';
 
		}
 

	
 
		if (!library_dir) {
 
			/* We look for the file 'info.nut' inside the AI dir.. if it doesn't exists, it isn't an AI */
 
			ttd_strlcat(script_name, "info.nut", sizeof(script_name));
 
			if (FioCheckFileExists(script_name, AI_DIR)) {
 
				char load_script[MAX_PATH];
 
				ttd_strlcpy(load_script, script_name, sizeof(load_script));
 

	
 
				/* Remove the 'info.nut' part and replace it with 'main.nut' */
 
				script_name[strlen(script_name) - 8] = '\0';
 
				ttd_strlcat(script_name, "main.nut", sizeof(script_name));
 

	
 
				DEBUG(ai, 6, "[script] Loading script '%s' for AI handling", load_script);
 
				this->current_script = script_name;
 
				this->current_dir = d_name;
 
				this->engine->LoadScript(load_script);
 
			}
 
		} else {
 
			/* We look for the file 'library.nut' inside the library dir.. */
 
			ttd_strlcat(script_name, "library.nut", sizeof(script_name));
 
			if (FioCheckFileExists(script_name, AI_DIR)) {
 
				char load_script[MAX_PATH];
 
				char dir_name[MAX_PATH];
 
				char d_name_2[MAX_PATH];
 
				/* In case the directory has a dot in it, ignore it, as that is the
 
				 *  indicator for multiple versions of the same library */
 
				ttd_strlcpy(d_name_2, d_name, sizeof(d_name_2));
 
				char *e = strrchr(d_name_2, '.');
 
				if (e != NULL) *e = '\0';
 

	
 
				ttd_strlcpy(load_script, script_name, sizeof(load_script));
 
				ttd_strlcpy(dir_name, library_depth, sizeof(dir_name));
 
				ttd_strlcat(dir_name, ".", sizeof(dir_name));
 
				ttd_strlcat(dir_name, d_name_2, sizeof(dir_name));
 

	
 
				/* Remove the 'library.nut' part and replace it with 'main.nut' */
 
				script_name[strlen(script_name) - 11] = '\0';
 
				ttd_strlcat(script_name, "main.nut", sizeof(script_name));
 

	
 
				DEBUG(ai, 6, "[script] Loading script '%s' for Squirrel library", load_script);
 
				this->current_script = script_name;
 
				this->current_dir = dir_name;
 
				this->engine->LoadScript(load_script);
 
			}
 
		}
 
	}
 
	closedir(dir);
 
}
 

	
 
void AIScanner::ScanAIDir()
 
{
 
	char buf[MAX_PATH];
 
	Searchpath sp;
 

	
 
	FOR_ALL_SEARCHPATHS(sp) {
 
		FioAppendDirectory(buf, MAX_PATH, sp, AI_DIR);
 
		if (FileExists(buf)) this->ScanDir(buf, false);
 
		ttd_strlcat(buf, "library" PATHSEP, MAX_PATH);
 
		if (FileExists(buf)) this->ScanDir(buf, true);
 
	}
 
}
 

	
 
void AIScanner::RescanAIDir()
 
{
 
	extern void ScanForTarFiles();
 
	ScanForTarFiles();
 
	this->ScanAIDir();
 
}
 

	
 
AIScanner::AIScanner()
 
{
 
	this->engine = new Squirrel();
 

	
 
	/* Create the AIInfo class, and add the RegisterAI function */
 
	DefSQClass <AIInfo> SQAIInfo("AIInfo");
 
	SQAIInfo.PreRegister(engine);
 
	SQAIInfo.AddConstructor<void (AIInfo::*)(), 1>(engine, "x");
 
	SQAIInfo.DefSQAdvancedMethod(this->engine, &AIInfo::AddSetting, "AddSetting");
 
	SQAIInfo.PostRegister(engine);
 
	this->engine->AddMethod("RegisterAI", &AIInfo::Constructor, 2, "tx");
 
	/* Create the AILibrary class, and add the RegisterLibrary function */
 
	this->engine->AddClassBegin("AILibrary");
 
	this->engine->AddClassEnd();
 
	this->engine->AddMethod("RegisterLibrary", &AILibrary::Constructor, 2, "tx");
 

	
 
	/* Mark this class as global pointer */
 
	this->engine->SetGlobalPointer(this);
 

	
 
	/* Scan the AI dir for scripts */
 
	this->ScanAIDir();
 

	
 
	/* Create the dummy AI */
 
	this->engine->AddMethod("RegisterDummyAI", &AIInfo::DummyConstructor, 2, "tx");
 
	this->current_script = (char *)"%_dummy";
 
	this->current_dir = (char *)"%_dummy";
 
	extern void AI_CreateAIInfoDummy(HSQUIRRELVM vm);
 
	AI_CreateAIInfoDummy(this->engine->GetVM());
 
}
 

	
 
AIScanner::~AIScanner()
 
{
 
	AIInfoList::iterator it = this->info_list.begin();
 
	for (; it != this->info_list.end(); it++) {
 
		AIInfo *i = (*it).second;
 
		delete i;
 
	}
 

	
 
	delete this->engine;
 
}
 

	
 
bool AIScanner::ImportLibrary(const char *library, const char *class_name, int version, HSQUIRRELVM vm, AIController *controller)
 
{
 
	/* Internally we store libraries as 'library.version' */
 
	char library_name[1024];
 
	snprintf(library_name, sizeof(library_name), "%s.%d", library, version);
 

	
 
	/* Check if the library + version exists */
 
	AILibraryList::iterator iter = this->library_list.find(library_name);
 
	if (iter == this->library_list.end()) {
 
		char error[1024];
 

	
 
		/* Now see if the version doesn't exist, or the library */
 
		iter = this->library_list.find(library);
 
		if (iter == this->library_list.end()) {
 
			snprintf(error, sizeof(error), "couldn't find library '%s'", library);
 
		} else {
 
			snprintf(error, sizeof(error), "this AI is expecting library '%s' to be version %d, but the latest available is version %d", library, version, (*iter).second->GetVersion());
 
		}
 
		sq_throwerror(vm, OTTD2FS(error));
 
		return false;
 
	}
 

	
 
	/* Get the current table/class we belong to */
 
	HSQOBJECT parent;
 
	sq_getstackobj(vm, 1, &parent);
 

	
 
	char fake_class[1024];
 
	int next_number;
 
	/* Check if we already have this library loaded.. if so, fill fake_class
 
	 *  with the class-name it is nested in */
 
	if (!controller->LoadedLibrary(library_name, &next_number, &fake_class[0], sizeof(fake_class))) {
 
		/* Create a new fake internal name */
 
		snprintf(fake_class, sizeof(fake_class), "_internalNA%d", next_number);
 

	
 
		/* Load the library in a 'fake' namespace, so we can link it to the name the user requested */
 
		sq_pushroottable(vm);
 
		sq_pushstring(vm, OTTD2FS(fake_class), -1);
 
		sq_newclass(vm, SQFalse);
 
		/* Load the library */
 
		if (!Squirrel::LoadScript(vm, (*iter).second->GetScriptName(), false)) {
 
			char error[1024];
 
			snprintf(error, sizeof(error), "there was a compile error when importing '%s' version %d", library, version);
 
			sq_throwerror(vm, OTTD2FS(error));
 
			return false;
 
		}
 
		/* Create the fake class */
 
		sq_newslot(vm, -3, SQFalse);
 
		sq_pop(vm, 1);
 

	
 
		controller->AddLoadedLibrary(library_name, fake_class);
 
	}
 

	
 
	/* Find the real class inside the fake class (like 'sets.Vector') */
 
	sq_pushroottable(vm);
 
	sq_pushstring(vm, OTTD2FS(fake_class), -1);
 
	if (SQ_FAILED(sq_get(vm, -2))) {
 
		sq_throwerror(vm, _SC("internal error assigning library class"));
 
		return false;
 
	}
 
	sq_pushstring(vm, OTTD2FS((*iter).second->GetInstanceName()), -1);
 
	if (SQ_FAILED(sq_get(vm, -2))) {
 
		char error[1024];
 
		snprintf(error, sizeof(error), "unable to find class '%s' in the library '%s' version %d", (*iter).second->GetInstanceName(), library, version);
 
		sq_throwerror(vm, OTTD2FS(error));
 
		return false;
 
	}
 
	HSQOBJECT obj;
 
	sq_getstackobj(vm, -1, &obj);
 
	sq_pop(vm, 3);
 

	
 
	if (StrEmpty(class_name)) {
 
		sq_pushobject(vm, obj);
 
		return true;
 
	}
 

	
 
	/* Now link the name the user wanted to our 'fake' class */
 
	sq_pushobject(vm, parent);
 
	sq_pushstring(vm, OTTD2FS(class_name), -1);
 
	sq_pushobject(vm, obj);
 
	sq_newclass(vm, SQTrue);
 
	sq_newslot(vm, -3, SQFalse);
 
	sq_pop(vm, 1);
 

	
 
	sq_pushobject(vm, obj);
 
	return true;
 
}
 

	
 
void AIScanner::RegisterLibrary(AILibrary *library)
 
{
 
	const char *ai_name_without_version = library->GetDirName();
 
	char ai_name[1024];
 
	snprintf(ai_name, sizeof(ai_name), "%s.%d", library->GetDirName(), library->GetVersion());
 

	
 
	/* Check if we register twice; than the first always wins */
 
	if (this->library_list.find(ai_name) != this->library_list.end()) {
 
		/* In case they are not the same dir, give a warning */
 
		if (strcasecmp(library->GetScriptName(), this->library_list[ai_name]->GetScriptName()) != 0) {
 
			DEBUG(ai, 0, "Registering two libraries with the same name");
 
			DEBUG(ai, 0, "  1: %s", this->library_list[ai_name]->GetScriptName());
 
			DEBUG(ai, 0, "  2: %s", library->GetScriptName());
 
			DEBUG(ai, 0, "The first is taking precedence");
 
		}
 
		/* Delete the new AILibrary, as we will be using the old one */
 
		delete library;
 
		return;
 
	}
 

	
 
	this->library_list[strdup(ai_name)] = library;
 
	/* Insert the global name too, so we if the library is known at all */
 
	if (this->library_list.find(ai_name_without_version) == this->library_list.end()) {
 
		this->library_list[strdup(ai_name_without_version)] = library;
 
	} else if (this->library_list[ai_name_without_version]->GetVersion() < library->GetVersion()) {
 
		this->library_list[ai_name_without_version] = library;
 
	}
 
}
 

	
 
void AIScanner::RegisterAI(AIInfo *info)
 
{
 
	const char *ai_name = info->GetDirName();
 

	
 
	/* Check if we register twice; than the first always wins */
 
	if (this->info_list.find(ai_name) != this->info_list.end()) {
 
		/* In case they are not the same dir, give a warning */
 
		if (strcasecmp(info->GetScriptName(), this->info_list[ai_name]->GetScriptName()) != 0) {
 
			DEBUG(ai, 0, "Registering two AIs with the same name");
 
			DEBUG(ai, 0, "  1: %s", this->info_list[ai_name]->GetScriptName());
 
			DEBUG(ai, 0, "  2: %s", info->GetScriptName());
 
			DEBUG(ai, 0, "The first is taking precedence");
 
		}
 
		/* Delete the new AIInfo, as we will be using the old one */
 
		delete info;
 
		return;
 
	}
 

	
 
	this->info_list[strdup(ai_name)] = info;
 
}
 

	
 
void AIScanner::UnregisterAI(AIInfo *info)
 
{
 
	this->info_list.erase(info->GetDirName());
 
}
 

	
 
AIInfo *AIScanner::SelectRandomAI()
 
{
 
	if (this->info_list.size() == 0) {
 
		DEBUG(ai, 0, "No suitable AI found, loading 'dummy' AI.");
 
		return this->info_dummy;
 
	}
 

	
 
	/* Find a random AI */
 
	uint pos;
 
	if (_networking) pos = InteractiveRandomRange((uint16)this->info_list.size());
 
	else             pos =            RandomRange((uint16)this->info_list.size());
 

	
 
	/* Find the Nth item from the array */
 
	AIInfoList::iterator it = this->info_list.begin();
 
	for (; pos > 0; pos--) it++;
 
	AIInfoList::iterator first_it = it;
 
	AIInfo *i = (*it).second;
 

	
 
	if (!i->AllowStartup()) {
 
		/* We can't start this AI, try to find the next best */
 
		do {
 
			it++;
 
			if (it == this->info_list.end()) it = this->info_list.begin();
 
			/* Back at the beginning? We can't start an AI. */
 
			if (first_it == it) {
 
				DEBUG(ai, 0, "No suitable AI found, loading 'dummy' AI.");
 
				return this->info_dummy;
 
			}
 

	
 
			i = (*it).second;
 
		} while (!i->AllowStartup());
 
	}
 
	return i;
 
}
 

	
 
AIInfo *AIScanner::FindAI(const char *name)
 
{
 
	if (this->info_list.size() == 0) return NULL;
 
	if (name == NULL) return NULL;
 

	
 
	AIInfoList::iterator it = this->info_list.begin();
 
	for (; it != this->info_list.end(); it++) {
 
		AIInfo *i = (*it).second;
 

	
 
		if (strcasecmp(name, (*it).first) == 0 && i->AllowStartup()) {
 
			return i;
 
		}
 
	}
 

	
 
	return NULL;
 
}
 

	
 
char *AIScanner::GetAIConsoleList(char *p, const char *last)
 
{
 
	p += seprintf(p, last, "List of AIs:\n");
 
	AIInfoList::iterator it = this->info_list.begin();
 
	for (; it != this->info_list.end(); it++) {
 
		AIInfo *i = (*it).second;
 
		if (!i->AllowStartup()) continue;
 
		p += seprintf(p, last, "%10s: %s\n", (*it).first, i->GetDescription());
 
	}
 
	p += seprintf(p, last, "\n");
 

	
 
	return p;
 
}
src/ai/ai_scanner.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_scanner.hpp declarations of the class for AI scanner */
 

	
 
#ifndef AI_SCANNER_HPP
 
#define AI_SCANNER_HPP
 

	
 
#include <map>
 

	
 
class AIScanner {
 
public:
 
	AIScanner();
 
	~AIScanner();
 

	
 
	/**
 
	 * Import a library inside the Squirrel VM.
 
	 */
 
	bool ImportLibrary(const char *library, const char *class_name, int version, HSQUIRRELVM vm, class AIController *controller);
 

	
 
	/**
 
	 * Register a library to be put in the available list.
 
	 */
 
	void RegisterLibrary(class AILibrary *library);
 

	
 
	/**
 
	 * Register an AI to be put in the available list.
 
	 */
 
	void RegisterAI(class AIInfo *info);
 

	
 
	void SetDummyAI(class AIInfo *info) { this->info_dummy = info; }
 

	
 
	/**
 
	 * Remove an AI from the available list.
 
	 */
 
	void UnregisterAI(class AIInfo *info);
 

	
 
	/**
 
	 * Select a Random AI.
 
	 */
 
	class AIInfo *SelectRandomAI();
 

	
 
	/**
 
	 * Find an AI by name.
 
	 */
 
	class AIInfo *FindAI(const char *name);
 

	
 
	/**
 
	 * Get the list of available AIs for the console.
 
	 */
 
	char *GetAIConsoleList(char *p, const char *last);
 

	
 
	/**
 
	 * Get the list of all registered AIs.
 
	 */
 
	const AIInfoList *GetAIInfoList() { return &this->info_list; }
 

	
 
	/**
 
	 * Get the engine of the main squirrel handler (it indexes all avialable squirrels).
 
	 */
 
	class Squirrel *GetEngine() { return this->engine; }
 

	
 
	/**
 
	 * Get the current script the ScanDir is looking at.
 
	 */
 
	const char *GetCurrentScript() { return this->current_script; }
 

	
 
	/**
 
	 * Get the directory of the current script the ScanDir is looking at.
 
	 */
 
	const char *GetCurrentDirName() { return this->current_dir; }
 

	
 
	/**
 
	 * Rescan the AI dir for scripts.
 
	 */
 
	void RescanAIDir();
 

	
 
private:
 
	typedef std::map<const char *, class AILibrary *, ltstr> AILibraryList;
 

	
 
	/**
 
	 * Scan the AI dir for scripts.
 
	 */
 
	void ScanAIDir();
 

	
 
	/**
 
	 * Scan a dir for AIs.
 
	 *  For non-library-scan, if an AI is found, AIInfo is created, and the AI
 
	 *    is registered to the central system.
 
	 *  For library-scan, if a library is found, AILibrary is created, and the
 
	 *    library is registered to the central system.
 
	 */
 
	void ScanDir(const char *dirname, bool library_dir, char *library_depth = NULL);
 

	
 
	AIInfoList info_list;
 
	AIInfo *info_dummy;
 
	AILibraryList library_list;
 
	class Squirrel *engine;
 
	char *current_script;
 
	char *current_dir;
 
};
 

	
 
#endif /* AI_SCANNER_HPP */
src/ai/ai_storage.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_storage.hpp Defines AIStorage and includes all files required for it. */
 

	
 
#ifndef AI_STORAGE_HPP
 
#define AI_STORAGE_HPP
 

	
 
#include "../command_func.h"
 
#include "../map_func.h"
 
#include "../network/network.h"
 
#include "../company_func.h"
 
#include "../signs_func.h"
 
#include "../tunnelbridge.h"
 
#include "../vehicle_func.h"
 
#include "../group.h"
 

	
 
#include <vector>
 

	
 
/**
 
 * The callback function for Mode-classes.
 
 */
 
typedef bool (AIModeProc)(TileIndex tile, uint32 p1, uint32 p2, uint procc, CommandCost costs);
 

	
 
/**
 
 * The storage for each AI. It keeps track of important information.
 
 */
 
class AIStorage {
 
friend class AIObject;
 
private:
 
	AIModeProc *mode;                //!< The current build mode we are int.
 
	class AIObject *mode_instance;   //!< The instance belonging to the current build mode.
 

	
 
	uint delay;                      //!< The ticks of delay each DoCommand has.
 
	bool allow_do_command;           //!< Is the usage of DoCommands restricted?
 

	
 
	CommandCost costs;               //!< The costs the AI is tracking.
 
	Money last_cost;                 //!< The last cost of the command.
 
	uint last_error;                 //!< The last error of the command.
 
	bool last_command_res;           //!< The last result of the command.
 

	
 
	VehicleID new_vehicle_id;        //!< The ID of the new Vehicle.
 
	SignID new_sign_id;              //!< The ID of the new Sign.
 
	TileIndex new_tunnel_endtile;    //!< The TileIndex of the new Tunnel.
 
	GroupID new_group_id;            //!< The ID of the new Group.
 

	
 
	std::vector<int> callback_value; //!< The values which need to survive a callback.
 

	
 
	RoadType road_type;              //!< The current roadtype we build.
 
	RailType rail_type;              //!< The current railtype we build.
 

	
 
	void *event_data;                //!< Pointer to the event data storage.
 
	void *log_data;                  //!< Pointer to the log data storage.
 

	
 
public:
 
	AIStorage() :
 
		mode              (NULL),
 
		mode_instance     (NULL),
 
		delay             (1),
 
		allow_do_command  (true),
 
		/* costs (can't be set) */
 
		last_cost         (0),
 
		last_error        (STR_NULL),
 
		last_command_res  (true),
 
		new_vehicle_id    (0),
 
		new_sign_id       (0),
 
		new_tunnel_endtile(INVALID_TILE),
 
		new_group_id      (0),
 
		/* calback_value (can't be set) */
 
		road_type         (INVALID_ROADTYPE),
 
		rail_type         (INVALID_RAILTYPE),
 
		event_data        (NULL),
 
		log_data          (NULL)
 
	{ }
 

	
 
	~AIStorage();
 
};
 

	
 
#endif /* AI_STORAGE_HPP */
src/ai/api/Doxyfile
Show inline comments
 
new file 100644
 
# Doxyfile 1.5.4
 

	
 
#---------------------------------------------------------------------------
 
# Project related configuration options
 
#---------------------------------------------------------------------------
 
DOXYFILE_ENCODING      = UTF-8
 
PROJECT_NAME           = "OpenTTD NoAI API "
 
PROJECT_NUMBER         =
 
OUTPUT_DIRECTORY       = ../../../docs/aidocs/
 
CREATE_SUBDIRS         = NO
 
OUTPUT_LANGUAGE        = English
 
BRIEF_MEMBER_DESC      = YES
 
REPEAT_BRIEF           = YES
 
ABBREVIATE_BRIEF       = "The $name class " \
 
                         "The $name widget " \
 
                         "The $name file " \
 
                         is \
 
                         provides \
 
                         specifies \
 
                         contains \
 
                         represents \
 
                         a \
 
                         an \
 
                         the
 
ALWAYS_DETAILED_SEC    = NO
 
INLINE_INHERITED_MEMB  = NO
 
FULL_PATH_NAMES        = YES
 
STRIP_FROM_PATH        = ./
 
STRIP_FROM_INC_PATH    =
 
SHORT_NAMES            = NO
 
JAVADOC_AUTOBRIEF      = YES
 
QT_AUTOBRIEF           = NO
 
MULTILINE_CPP_IS_BRIEF = NO
 
DETAILS_AT_TOP         = NO
 
INHERIT_DOCS           = YES
 
SEPARATE_MEMBER_PAGES  = NO
 
TAB_SIZE               = 2
 
ALIASES                =
 
OPTIMIZE_OUTPUT_FOR_C  = YES
 
OPTIMIZE_OUTPUT_JAVA   = NO
 
BUILTIN_STL_SUPPORT    = NO
 
CPP_CLI_SUPPORT        = NO
 
SIP_SUPPORT            = NO
 
DISTRIBUTE_GROUP_DOC   = NO
 
SUBGROUPING            = YES
 
TYPEDEF_HIDES_STRUCT   = NO
 
#---------------------------------------------------------------------------
 
# Build related configuration options
 
#---------------------------------------------------------------------------
 
EXTRACT_ALL            = NO
 
EXTRACT_PRIVATE        = NO
 
EXTRACT_STATIC         = YES
 
EXTRACT_LOCAL_CLASSES  = YES
 
EXTRACT_LOCAL_METHODS  = YES
 
EXTRACT_ANON_NSPACES   = NO
 
HIDE_UNDOC_MEMBERS     = NO
 
HIDE_UNDOC_CLASSES     = NO
 
HIDE_FRIEND_COMPOUNDS  = NO
 
HIDE_IN_BODY_DOCS      = YES
 
INTERNAL_DOCS          = YES
 
CASE_SENSE_NAMES       = YES
 
HIDE_SCOPE_NAMES       = NO
 
SHOW_INCLUDE_FILES     = NO
 
INLINE_INFO            = YES
 
SORT_MEMBER_DOCS       = YES
 
SORT_BRIEF_DOCS        = NO
 
SORT_BY_SCOPE_NAME     = NO
 
GENERATE_TODOLIST      = NO
 
GENERATE_TESTLIST      = NO
 
GENERATE_BUGLIST       = NO
 
GENERATE_DEPRECATEDLIST= NO
 
ENABLED_SECTIONS       =
 
MAX_INITIALIZER_LINES  = 30
 
SHOW_USED_FILES        = NO
 
SHOW_DIRECTORIES       = NO
 
FILE_VERSION_FILTER    =
 
#---------------------------------------------------------------------------
 
# configuration options related to warning and progress messages
 
#---------------------------------------------------------------------------
 
QUIET                  = NO
 
WARNINGS               = YES
 
WARN_IF_UNDOCUMENTED   = YES
 
WARN_IF_DOC_ERROR      = YES
 
WARN_NO_PARAMDOC       = YES
 
WARN_FORMAT            = "$file:$line: $text "
 
WARN_LOGFILE           =
 
#---------------------------------------------------------------------------
 
# configuration options related to the input files
 
#---------------------------------------------------------------------------
 
INPUT                  = .
 
INPUT_ENCODING         = UTF-8
 
FILE_PATTERNS          = *.h \
 
                         *.hpp
 
RECURSIVE              = YES
 
EXCLUDE                =
 
EXCLUDE_SYMLINKS       = NO
 
EXCLUDE_PATTERNS       =
 
EXCLUDE_SYMBOLS        = GetClassName DECLARE_ENUM_AS_BIT_SET DECLARE_POSTFIX_INCREMENT
 
EXAMPLE_PATH           =
 
EXAMPLE_PATTERNS       = *
 
EXAMPLE_RECURSIVE      = NO
 
IMAGE_PATH             =
 
INPUT_FILTER           =
 
FILTER_PATTERNS        =
 
FILTER_SOURCE_FILES    = NO
 
#---------------------------------------------------------------------------
 
# configuration options related to source browsing
 
#---------------------------------------------------------------------------
 
SOURCE_BROWSER         = NO
 
INLINE_SOURCES         = NO
 
STRIP_CODE_COMMENTS    = YES
 
REFERENCED_BY_RELATION = NO
 
REFERENCES_RELATION    = NO
 
REFERENCES_LINK_SOURCE = YES
 
USE_HTAGS              = NO
 
VERBATIM_HEADERS       = NO
 
#---------------------------------------------------------------------------
 
# configuration options related to the alphabetical class index
 
#---------------------------------------------------------------------------
 
ALPHABETICAL_INDEX     = NO
 
COLS_IN_ALPHA_INDEX    = 5
 
IGNORE_PREFIX          =
 
#---------------------------------------------------------------------------
 
# configuration options related to the HTML output
 
#---------------------------------------------------------------------------
 
GENERATE_HTML          = YES
 
HTML_OUTPUT            = html
 
HTML_FILE_EXTENSION    = .html
 
HTML_HEADER            =
 
HTML_FOOTER            =
 
HTML_STYLESHEET        =
 
HTML_ALIGN_MEMBERS     = YES
 
GENERATE_HTMLHELP      = NO
 
HTML_DYNAMIC_SECTIONS  = NO
 
CHM_FILE               =
 
HHC_LOCATION           =
 
GENERATE_CHI           = NO
 
BINARY_TOC             = NO
 
TOC_EXPAND             = NO
 
DISABLE_INDEX          = NO
 
ENUM_VALUES_PER_LINE   = 1
 
GENERATE_TREEVIEW      = NO
 
TREEVIEW_WIDTH         = 250
 
#---------------------------------------------------------------------------
 
# configuration options related to the LaTeX output
 
#---------------------------------------------------------------------------
 
GENERATE_LATEX         = NO
 
LATEX_OUTPUT           = latex
 
LATEX_CMD_NAME         = latex
 
MAKEINDEX_CMD_NAME     = makeindex
 
COMPACT_LATEX          = NO
 
PAPER_TYPE             = a4wide
 
EXTRA_PACKAGES         =
 
LATEX_HEADER           =
 
PDF_HYPERLINKS         = NO
 
USE_PDFLATEX           = NO
 
LATEX_BATCHMODE        = NO
 
LATEX_HIDE_INDICES     = NO
 
#---------------------------------------------------------------------------
 
# configuration options related to the RTF output
 
#---------------------------------------------------------------------------
 
GENERATE_RTF           = NO
 
RTF_OUTPUT             = rtf
 
COMPACT_RTF            = NO
 
RTF_HYPERLINKS         = NO
 
RTF_STYLESHEET_FILE    =
 
RTF_EXTENSIONS_FILE    =
 
#---------------------------------------------------------------------------
 
# configuration options related to the man page output
 
#---------------------------------------------------------------------------
 
GENERATE_MAN           = NO
 
MAN_OUTPUT             = man
 
MAN_EXTENSION          = .3
 
MAN_LINKS              = NO
 
#---------------------------------------------------------------------------
 
# configuration options related to the XML output
 
#---------------------------------------------------------------------------
 
GENERATE_XML           = NO
 
XML_OUTPUT             = xml
 
XML_SCHEMA             =
 
XML_DTD                =
 
XML_PROGRAMLISTING     = YES
 
#---------------------------------------------------------------------------
 
# configuration options for the AutoGen Definitions output
 
#---------------------------------------------------------------------------
 
GENERATE_AUTOGEN_DEF   = NO
 
#---------------------------------------------------------------------------
 
# configuration options related to the Perl module output
 
#---------------------------------------------------------------------------
 
GENERATE_PERLMOD       = NO
 
PERLMOD_LATEX          = NO
 
PERLMOD_PRETTY         = YES
 
PERLMOD_MAKEVAR_PREFIX =
 
#---------------------------------------------------------------------------
 
# Configuration options related to the preprocessor
 
#---------------------------------------------------------------------------
 
ENABLE_PREPROCESSING   = YES
 
MACRO_EXPANSION        = YES
 
EXPAND_ONLY_PREDEF     = YES
 
SEARCH_INCLUDES        = YES
 
INCLUDE_PATH           =
 
INCLUDE_FILE_PATTERNS  =
 
PREDEFINED             = DOXYGEN_SKIP
 
EXPAND_AS_DEFINED      = DEF_COMMAND
 
SKIP_FUNCTION_MACROS   = YES
 
#---------------------------------------------------------------------------
 
# Configuration::additions related to external references
 
#---------------------------------------------------------------------------
 
TAGFILES               =
 
GENERATE_TAGFILE       = openttd.tag
 
ALLEXTERNALS           = NO
 
EXTERNAL_GROUPS        = YES
 
PERL_PATH              = /usr/bin/perl
 
#---------------------------------------------------------------------------
 
# Configuration options related to the dot tool
 
#---------------------------------------------------------------------------
 
CLASS_DIAGRAMS         = YES
 
MSCGEN_PATH            =
 
HIDE_UNDOC_RELATIONS   = YES
 
HAVE_DOT               = NO
 
CLASS_GRAPH            = YES
 
COLLABORATION_GRAPH    = YES
 
GROUP_GRAPHS           = YES
 
UML_LOOK               = NO
 
TEMPLATE_RELATIONS     = NO
 
INCLUDE_GRAPH          = YES
 
INCLUDED_BY_GRAPH      = YES
 
CALL_GRAPH             = NO
 
CALLER_GRAPH           = NO
 
GRAPHICAL_HIERARCHY    = YES
 
DIRECTORY_GRAPH        = YES
 
DOT_IMAGE_FORMAT       = png
 
DOT_PATH               =
 
DOTFILE_DIRS           =
 
DOT_GRAPH_MAX_NODES    = 50
 
MAX_DOT_GRAPH_DEPTH    = 1000
 
DOT_TRANSPARENT        = NO
 
DOT_MULTI_TARGETS      = NO
 
GENERATE_LEGEND        = NO
 
DOT_CLEANUP            = YES
 
#---------------------------------------------------------------------------
 
# Configuration::additions related to the search engine
 
#---------------------------------------------------------------------------
 
SEARCHENGINE           = NO
src/ai/api/ai_abstractlist.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_abstractlist.cpp Implementation of AIAbstractList. */
 

	
 
#include <squirrel.h>
 
#include "ai_abstractlist.hpp"
 
#include "../../debug.h"
 
#include "../../core/alloc_func.hpp"
 

	
 
/**
 
 * Base class for any AIAbstractList sorter.
 
 */
 
class AIAbstractListSorter {
 
protected:
 
	AIAbstractList *list;
 

	
 
public:
 
	/**
 
	 * Virtual dtor, needed to mute warnings.
 
	 */
 
	virtual ~AIAbstractListSorter() { }
 

	
 
	/**
 
	 * Get the first item of the sorter.
 
	 */
 
	virtual int32 Begin() = 0;
 

	
 
	/**
 
	 * Stop iterating a sorter.
 
	 */
 
	virtual void End() = 0;
 

	
 
	/**
 
	 * Get the next item of the sorter.
 
	 */
 
	virtual int32 Next() = 0;
 

	
 
	/**
 
	 * See if there is a next item of the sorter.
 
	 */
 
	virtual bool HasNext() = 0;
 

	
 
	/**
 
	 * Callback from the list if an item gets removed.
 
	 */
 
	virtual void Remove(int item) = 0;
 
};
 

	
 
/**
 
 * Sort by value, ascending.
 
 */
 
class AIAbstractListSorterValueAscending : public AIAbstractListSorter {
 
private:
 
	AIAbstractList::AIAbstractListBucket::iterator bucket_iter;
 
	AIAbstractList::AIItemList *bucket_list;
 
	AIAbstractList::AIItemList::iterator bucket_list_iter;
 
	bool has_no_more_items;
 
	int32 item_next;
 

	
 
public:
 
	AIAbstractListSorterValueAscending(AIAbstractList *list)
 
	{
 
		this->list = list;
 
		this->End();
 
	}
 

	
 
	int32 Begin()
 
	{
 
		if (this->list->buckets.empty()) return 0;
 
		this->has_no_more_items = false;
 

	
 
		this->bucket_iter = this->list->buckets.begin();
 
		this->bucket_list = &(*this->bucket_iter).second;
 
		this->bucket_list_iter = this->bucket_list->begin();
 
		this->item_next = *this->bucket_list_iter;
 

	
 
		int32 item_current = this->item_next;
 
		FindNext();
 
		return item_current;
 
	}
 

	
 
	void End()
 
	{
 
		this->bucket_list = NULL;
 
		this->has_no_more_items = true;
 
		this->item_next = 0;
 
	}
 

	
 
	void FindNext()
 
	{
 
		if (this->bucket_list == NULL) {
 
			this->has_no_more_items = true;
 
			return;
 
		}
 

	
 
		this->bucket_list_iter++;
 
		if (this->bucket_list_iter == this->bucket_list->end()) {
 
			this->bucket_iter++;
 
			if (this->bucket_iter == this->list->buckets.end()) {
 
				this->bucket_list = NULL;
 
				return;
 
			}
 
			this->bucket_list = &(*this->bucket_iter).second;
 
			this->bucket_list_iter = this->bucket_list->begin();
 
		}
 
		this->item_next = *this->bucket_list_iter;
 
	}
 

	
 
	int32 Next()
 
	{
 
		if (!this->HasNext()) return 0;
 

	
 
		int32 item_current = this->item_next;
 
		FindNext();
 
		return item_current;
 
	}
 

	
 
	void Remove(int item)
 
	{
 
		if (!this->HasNext()) return;
 

	
 
		/* If we remove the 'next' item, skip to the next */
 
		if (item == this->item_next) {
 
			FindNext();
 
			return;
 
		}
 
	}
 

	
 
	bool HasNext()
 
	{
 
		return !(this->list->buckets.empty() || this->has_no_more_items);
 
	}
 
};
 

	
 
/**
 
 * Sort by value, descending.
 
 */
 
class AIAbstractListSorterValueDescending : public AIAbstractListSorter {
 
private:
 
	AIAbstractList::AIAbstractListBucket::iterator bucket_iter;
 
	AIAbstractList::AIItemList *bucket_list;
 
	AIAbstractList::AIItemList::iterator bucket_list_iter;
 
	bool has_no_more_items;
 
	int32 item_next;
 

	
 
public:
 
	AIAbstractListSorterValueDescending(AIAbstractList *list)
 
	{
 
		this->list = list;
 
		this->End();
 
	}
 

	
 
	int32 Begin()
 
	{
 
		if (this->list->buckets.empty()) return 0;
 
		this->has_no_more_items = false;
 

	
 
		/* Go to the end of the bucket-list */
 
		this->bucket_iter = this->list->buckets.begin();
 
		for (size_t i = this->list->buckets.size(); i > 1; i--) this->bucket_iter++;
 
		this->bucket_list = &(*this->bucket_iter).second;
 

	
 
		/* Go to the end of the items in the bucket */
 
		this->bucket_list_iter = this->bucket_list->begin();
 
		for (size_t i = this->bucket_list->size(); i > 1; i--) this->bucket_list_iter++;
 
		this->item_next = *this->bucket_list_iter;
 

	
 
		int32 item_current = this->item_next;
 
		FindNext();
 
		return item_current;
 
	}
 

	
 
	void End() {
 
		this->bucket_list = NULL;
 
		this->has_no_more_items = true;
 
		this->item_next = 0;
 
	}
 

	
 
	void FindNext()
 
	{
 
		if (this->bucket_list == NULL) {
 
			this->has_no_more_items = true;
 
			return;
 
		}
 

	
 
		if (this->bucket_list_iter == this->bucket_list->begin()) {
 
			if (this->bucket_iter == this->list->buckets.begin()) {
 
				this->bucket_list = NULL;
 
				return;
 
			}
 
			this->bucket_iter--;
 
			this->bucket_list = &(*this->bucket_iter).second;
 
			/* Go to the end of the items in the bucket */
 
			this->bucket_list_iter = this->bucket_list->begin();
 
			for (size_t i = this->bucket_list->size(); i > 1; i--) this->bucket_list_iter++;
 
		} else {
 
			this->bucket_list_iter--;
 
		}
 
		this->item_next = *this->bucket_list_iter;
 
	}
 

	
 
	int32 Next()
 
	{
 
		if (!this->HasNext()) return 0;
 

	
 
		int32 item_current = this->item_next;
 
		FindNext();
 
		return item_current;
 
	}
 

	
 
	void Remove(int item)
 
	{
 
		if (!this->HasNext()) return;
 

	
 
		/* If we remove the 'next' item, skip to the next */
 
		if (item == this->item_next) {
 
			FindNext();
 
			return;
 
		}
 
	}
 

	
 
	bool HasNext()
 
	{
 
		return !(this->list->buckets.empty() || this->has_no_more_items);
 
	}
 
};
 

	
 
/**
 
 * Sort by item, ascending.
 
 */
 
class AIAbstractListSorterItemAscending : public AIAbstractListSorter {
 
private:
 
	AIAbstractList::AIAbstractListMap::iterator item_iter;
 
	bool has_no_more_items;
 
	int32 item_next;
 

	
 
public:
 
	AIAbstractListSorterItemAscending(AIAbstractList *list)
 
	{
 
		this->list = list;
 
		this->End();
 
	}
 

	
 
	int32 Begin()
 
	{
 
		if (this->list->items.empty()) return 0;
 
		this->has_no_more_items = false;
 

	
 
		this->item_iter = this->list->items.begin();
 
		this->item_next = (*this->item_iter).first;
 

	
 
		int32 item_current = this->item_next;
 
		FindNext();
 
		return item_current;
 
	}
 

	
 
	void End()
 
	{
 
		this->has_no_more_items = true;
 
	}
 

	
 
	void FindNext()
 
	{
 
		if (this->item_iter == this->list->items.end()) {
 
			this->has_no_more_items = true;
 
			return;
 
		}
 
		this->item_iter++;
 
		if (this->item_iter != this->list->items.end()) item_next = (*this->item_iter).first;
 
	}
 

	
 
	int32 Next()
 
	{
 
		if (!this->HasNext()) return 0;
 

	
 
		int32 item_current = this->item_next;
 
		FindNext();
 
		return item_current;
 
	}
 

	
 
	void Remove(int item) {
 
		if (!this->HasNext()) return;
 

	
 
		/* If we remove the 'next' item, skip to the next */
 
		if (item == this->item_next) {
 
			FindNext();
 
			return;
 
		}
 
	}
 

	
 
	bool HasNext()
 
	{
 
		return !(this->list->items.empty() || this->has_no_more_items);
 
	}
 
};
 

	
 
/**
 
 * Sort by item, descending.
 
 */
 
class AIAbstractListSorterItemDescending : public AIAbstractListSorter {
 
private:
 
	AIAbstractList::AIAbstractListMap::iterator item_iter;
 
	bool has_no_more_items;
 
	int32 item_next;
 

	
 
public:
 
	AIAbstractListSorterItemDescending(AIAbstractList *list)
 
	{
 
		this->list = list;
 
		this->End();
 
	}
 

	
 
	int32 Begin()
 
	{
 
		if (this->list->items.empty()) return 0;
 
		this->has_no_more_items = false;
 

	
 
		this->item_iter = this->list->items.begin();
 
		for (size_t i = this->list->items.size(); i > 1; i--) this->item_iter++;
 
		this->item_next = (*this->item_iter).first;
 

	
 
		int32 item_current = this->item_next;
 
		FindNext();
 
		return item_current;
 
	}
 

	
 
	void End()
 
	{
 
		this->has_no_more_items = true;
 
	}
 

	
 
	void FindNext()
 
	{
 
		if (this->item_iter == this->list->items.end()) {
 
			this->has_no_more_items = true;
 
			return;
 
		}
 
		this->item_iter--;
 
		if (this->item_iter != this->list->items.end()) item_next = (*this->item_iter).first;
 
	}
 

	
 
	int32 Next()
 
	{
 
		if (!this->HasNext()) return 0;
 

	
 
		int32 item_current = this->item_next;
 
		FindNext();
 
		return item_current;
 
	}
 

	
 
	void Remove(int item)
 
	{
 
		if (!this->HasNext()) return;
 

	
 
		/* If we remove the 'next' item, skip to the next */
 
		if (item == this->item_next) {
 
			FindNext();
 
			return;
 
		}
 
	}
 

	
 
	bool HasNext()
 
	{
 
		return !(this->list->items.empty() || this->has_no_more_items);
 
	}
 
};
 

	
 

	
 

	
 
AIAbstractList::AIAbstractList()
 
{
 
	/* Default sorter */
 
	this->sorter         = new AIAbstractListSorterValueDescending(this);
 
	this->sorter_type    = SORT_BY_VALUE;
 
	this->sort_ascending = false;
 
	this->initialized    = false;
 
}
 

	
 
AIAbstractList::~AIAbstractList()
 
{
 
	delete this->sorter;
 
}
 

	
 
bool AIAbstractList::HasItem(int32 item)
 
{
 
	return this->items.count(item) == 1;
 
}
 

	
 
void AIAbstractList::Clear()
 
{
 
	this->items.clear();
 
	this->buckets.clear();
 
	this->sorter->End();
 
}
 

	
 
void AIAbstractList::AddItem(int32 item)
 
{
 
	if (this->HasItem(item)) return;
 

	
 
	this->items[item] = 0;
 
	this->buckets[0].insert(item);
 
}
 

	
 
void AIAbstractList::RemoveItem(int32 item)
 
{
 
	if (!this->HasItem(item)) return;
 

	
 
	int32 value = this->GetValue(item);
 

	
 
	this->sorter->Remove(item);
 
	this->buckets[value].erase(item);
 
	if (this->buckets[value].empty()) this->buckets.erase(value);
 
	this->items.erase(item);
 
}
 

	
 
int32 AIAbstractList::Begin()
 
{
 
	this->initialized = true;
 
	return this->sorter->Begin();
 
}
 

	
 
int32 AIAbstractList::Next()
 
{
 
	if (this->initialized == false) {
 
		DEBUG(ai, 0, "ERROR: Next() is invalid as Begin() is never called");
 
		return false;
 
	}
 
	return this->sorter->Next();
 
}
 

	
 
bool AIAbstractList::IsEmpty()
 
{
 
	return this->items.empty();
 
}
 

	
 
bool AIAbstractList::HasNext()
 
{
 
	if (this->initialized == false) {
 
		DEBUG(ai, 0, "ERROR: HasNext() is invalid as Begin() is never called");
 
		return false;
 
	}
 
	return this->sorter->HasNext();
 
}
 

	
 
int32 AIAbstractList::Count()
 
{
 
	return (int32)this->items.size();
 
}
 

	
 
int32 AIAbstractList::GetValue(int32 item)
 
{
 
	if (!this->HasItem(item)) return 0;
 

	
 
	return this->items[item];
 
}
 

	
 
bool AIAbstractList::SetValue(int32 item, int32 value)
 
{
 
	if (!this->HasItem(item)) return false;
 

	
 
	int32 value_old = this->GetValue(item);
 

	
 
	this->sorter->Remove(item);
 
	this->buckets[value_old].erase(item);
 
	if (this->buckets[value_old].empty()) this->buckets.erase(value_old);
 
	this->items[item] = value;
 
	this->buckets[value].insert(item);
 

	
 
	return true;
 
}
 

	
 
void AIAbstractList::Sort(SorterType sorter, bool ascending)
 
{
 
	if (sorter != SORT_BY_VALUE && sorter != SORT_BY_ITEM) return;
 
	if (sorter == this->sorter_type && ascending == this->sort_ascending) return;
 

	
 
	delete this->sorter;
 
	switch (sorter) {
 
		case SORT_BY_ITEM:
 
			if (ascending) this->sorter = new AIAbstractListSorterItemAscending(this);
 
			else           this->sorter = new AIAbstractListSorterItemDescending(this);
 
			break;
 

	
 
		case SORT_BY_VALUE:
 
			if (ascending) this->sorter = new AIAbstractListSorterValueAscending(this);
 
			else           this->sorter = new AIAbstractListSorterValueDescending(this);
 
			break;
 

	
 
		default:
 
			this->Sort(SORT_BY_ITEM, false);
 
			return;
 
	}
 
	this->sorter_type    = sorter;
 
	this->sort_ascending = ascending;
 
}
 

	
 
void AIAbstractList::AddList(AIAbstractList *list)
 
{
 
	AIAbstractListMap *list_items = &list->items;
 
	for (AIAbstractListMap::iterator iter = list_items->begin(); iter != list_items->end(); iter++) {
 
		this->AddItem((*iter).first);
 
		this->SetValue((*iter).first, (*iter).second);
 
	}
 
}
 

	
 
void AIAbstractList::RemoveAboveValue(int32 value)
 
{
 
	for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) {
 
		next_iter = iter; next_iter++;
 
		if ((*iter).second > value) this->items.erase(iter);
 
	}
 

	
 
	for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) {
 
		next_iter = iter; next_iter++;
 
		if ((*iter).first > value) this->buckets.erase(iter);
 
	}
 
}
 

	
 
void AIAbstractList::RemoveBelowValue(int32 value)
 
{
 
	for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) {
 
		next_iter = iter; next_iter++;
 
		if ((*iter).second < value) this->items.erase(iter);
 
	}
 

	
 
	for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) {
 
		next_iter = iter; next_iter++;
 
		if ((*iter).first < value) this->buckets.erase(iter);
 
	}
 
}
 

	
 
void AIAbstractList::RemoveBetweenValue(int32 start, int32 end)
 
{
 
	for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) {
 
		next_iter = iter; next_iter++;
 
		if ((*iter).second > start && (*iter).second < end) this->items.erase(iter);
 
	}
 

	
 
	for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) {
 
		next_iter = iter; next_iter++;
 
		if ((*iter).first > start && (*iter).first < end) this->buckets.erase(iter);
 
	}
 
}
 

	
 
void AIAbstractList::RemoveValue(int32 value)
 
{
 
	for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) {
 
		next_iter = iter; next_iter++;
 
		if ((*iter).second == value) this->items.erase(iter);
 
	}
 

	
 
	for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) {
 
		next_iter = iter; next_iter++;
 
		if ((*iter).first == value) this->buckets.erase(iter);
 
	}
 
}
 

	
 
void AIAbstractList::RemoveTop(int32 count)
 
{
 
	if (!this->sort_ascending) {
 
		this->Sort(this->sorter_type, !this->sort_ascending);
 
		this->RemoveBottom(count);
 
		this->Sort(this->sorter_type, !this->sort_ascending);
 
		return;
 
	}
 

	
 
	switch (this->sorter_type) {
 
		default: NOT_REACHED();
 
		case SORT_BY_VALUE:
 
			for (AIAbstractListBucket::iterator iter = this->buckets.begin(); iter != this->buckets.end(); iter = this->buckets.begin()) {
 
				AIItemList *items = &(*iter).second;
 
				size_t size = items->size();
 
				for (AIItemList::iterator iter = items->begin(); iter != items->end(); iter = items->begin()) {
 
					if (--count < 0) return;
 
					this->RemoveItem(*iter);
 
					/* When the last item is removed from the bucket, the bucket itself is removed.
 
					 * This means that the iterators can be invalid after a call to RemoveItem.
 
					 */
 
					if (--size == 0) break;
 
				}
 
			}
 
			break;
 

	
 
		case SORT_BY_ITEM:
 
			for (AIAbstractListMap::iterator iter = this->items.begin(); iter != this->items.end(); iter = this->items.begin()) {
 
				if (--count < 0) return;
 
				this->RemoveItem((*iter).first);
 
			}
 
			break;
 
	}
 
}
 

	
 
void AIAbstractList::RemoveBottom(int32 count)
 
{
 
	if (!this->sort_ascending) {
 
		this->Sort(this->sorter_type, !this->sort_ascending);
 
		this->RemoveTop(count);
 
		this->Sort(this->sorter_type, !this->sort_ascending);
 
		return;
 
	}
 

	
 
	switch (this->sorter_type) {
 
		default: NOT_REACHED();
 
		case SORT_BY_VALUE:
 
			for (AIAbstractListBucket::reverse_iterator iter = this->buckets.rbegin(); iter != this->buckets.rend(); iter = this->buckets.rbegin()) {
 
				AIItemList *items = &(*iter).second;
 
				size_t size = items->size();
 
				for (AIItemList::reverse_iterator iter = items->rbegin(); iter != items->rend(); iter = items->rbegin()) {
 
					if (--count < 0) return;
 
					this->RemoveItem(*iter);
 
					/* When the last item is removed from the bucket, the bucket itself is removed.
 
					 * This means that the iterators can be invalid after a call to RemoveItem.
 
					 */
 
					if (--size == 0) break;
 
				}
 
			}
 

	
 
		case SORT_BY_ITEM:
 
			for (AIAbstractListMap::reverse_iterator iter = this->items.rbegin(); iter != this->items.rend(); iter = this->items.rbegin()) {
 
				if (--count < 0) return;
 
				this->RemoveItem((*iter).first);
 
			}
 
			break;
 
	}
 
}
 

	
 
void AIAbstractList::RemoveList(AIAbstractList *list)
 
{
 
	AIAbstractListMap *list_items = &list->items;
 
	for (AIAbstractListMap::iterator iter = list_items->begin(); iter != list_items->end(); iter++) {
 
		this->RemoveItem((*iter).first);
 
	}
 
}
 

	
 
void AIAbstractList::KeepAboveValue(int32 value)
 
{
 
	for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) {
 
		next_iter = iter; next_iter++;
 
		if ((*iter).second <= value) this->items.erase(iter);
 
	}
 

	
 
	for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) {
 
		next_iter = iter; next_iter++;
 
		if ((*iter).first <= value) this->buckets.erase(iter);
 
	}
 
}
 

	
 
void AIAbstractList::KeepBelowValue(int32 value)
 
{
 
	for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) {
 
		next_iter = iter; next_iter++;
 
		if ((*iter).second >= value) this->items.erase(iter);
 
	}
 

	
 
	for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) {
 
		next_iter = iter; next_iter++;
 
		if ((*iter).first >= value) this->buckets.erase(iter);
 
	}
 
}
 

	
 
void AIAbstractList::KeepBetweenValue(int32 start, int32 end)
 
{
 
	for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) {
 
		next_iter = iter; next_iter++;
 
		if ((*iter).second <= start || (*iter).second >= end) this->items.erase(iter);
 
	}
 

	
 
	for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) {
 
		next_iter = iter; next_iter++;
 
		if ((*iter).first <= start || (*iter).first >= end) this->buckets.erase(iter);
 
	}
 
}
 

	
 
void AIAbstractList::KeepValue(int32 value)
 
{
 
	for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) {
 
		next_iter = iter; next_iter++;
 
		if ((*iter).second != value) this->items.erase(iter);
 
	}
 

	
 
	for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) {
 
		next_iter = iter; next_iter++;
 
		if ((*iter).first != value) this->buckets.erase(iter);
 
	}
 
}
 

	
 
void AIAbstractList::KeepTop(int32 count)
 
{
 
	this->RemoveBottom(this->Count() - count);
 
}
 

	
 
void AIAbstractList::KeepBottom(int32 count)
 
{
 
	this->RemoveTop(this->Count() - count);
 
}
 

	
 
void AIAbstractList::KeepList(AIAbstractList *list)
 
{
 
	AIAbstractList tmp;
 
	for (AIAbstractListMap::iterator iter = this->items.begin(); iter != this->items.end(); iter++) {
 
		tmp.AddItem((*iter).first);
 
		tmp.SetValue((*iter).first, (*iter).second);
 
	}
 

	
 
	tmp.RemoveList(list);
 
	this->RemoveList(&tmp);
 
}
 

	
 
SQInteger AIAbstractList::_get(HSQUIRRELVM vm) {
 
	if (sq_gettype(vm, 2) != OT_INTEGER) return SQ_ERROR;
 

	
 
	SQInteger idx;
 
	sq_getinteger(vm, 2, &idx);
 

	
 
	if (!this->HasItem(idx)) return SQ_ERROR;
 

	
 
	sq_pushinteger(vm, this->GetValue(idx));
 
	return 1;
 
}
 

	
 
SQInteger AIAbstractList::_nexti(HSQUIRRELVM vm) {
 
	if (sq_gettype(vm, 2) == OT_NULL) {
 
		if (this->IsEmpty()) {
 
			sq_pushnull(vm);
 
			return 1;
 
		}
 
		sq_pushinteger(vm, this->Begin());
 
		return 1;
 
	}
 

	
 
	SQInteger idx;
 
	sq_getinteger(vm, 2, &idx);
 

	
 
	int val = this->Next();
 
	if (!this->HasNext()) {
 
		sq_pushnull(vm);
 
		return 1;
 
	}
 

	
 
	sq_pushinteger(vm, val);
 
	return 1;
 
}
 

	
 
SQInteger AIAbstractList::Valuate(HSQUIRRELVM vm) {
 
	int nparam = sq_gettop(vm) - 2;
 

	
 
	/* Get the list instance and the function to call */
 
	HSQOBJECT obj_list, obj_func;
 
	sq_getstackobj(vm, 1, &obj_list);
 
	sq_getstackobj(vm, 2, &obj_func);
 

	
 
	if (sq_isclass(obj_list)) {
 
		return sq_throwerror(vm, _SC("parameter 1 has an invalid type (expected instance)"));
 
	}
 
	if (sq_isfunction(obj_func)) {
 
		return sq_throwerror(vm, _SC("parameter 2 has an invalid type (expected function)"));
 
	}
 

	
 
	sq_addref(vm, &obj_func);
 

	
 
	/* Read the params */
 
	HSQOBJECT *obj_params = AllocaM(HSQOBJECT, nparam);
 
	for (int i = 0; i < nparam; i++) {
 
		sq_getstackobj(vm, i + 3, &obj_params[i]);
 
		sq_addref(vm, &obj_params[i]);
 
	}
 
	/* Remove all unneeded stuff */
 
	sq_pop(vm, nparam + 1);
 

	
 
	/* Walk all items, and query the result */
 
	this->buckets.clear();
 
	for (AIAbstractListMap::iterator iter = this->items.begin(); iter != this->items.end(); iter++) {
 
		/* The function to call */
 
		sq_pushobject(vm, obj_func);
 
		/* The 'list' instance; this is most likely wrong, but we need to send something ;) */
 
		sq_pushobject(vm, obj_list);
 

	
 
		/* Now send the params */
 
		sq_pushinteger(vm, (*iter).first);
 
		for (int i = 0; i < nparam; i++) {
 
			sq_pushobject(vm, obj_params[i]);
 
		}
 

	
 
		/* Call the function */
 
		if (SQ_FAILED(sq_call(vm, nparam + 2, SQTrue, SQTrue))) return SQ_ERROR;
 

	
 
		/* Retreive the return value */
 
		SQInteger value;
 
		switch (sq_gettype(vm, -1)) {
 
			case OT_INTEGER: {
 
				sq_getinteger(vm, -1, &value);
 
			} break;
 

	
 
			case OT_BOOL: {
 
				SQBool v;
 
				sq_getbool(vm, -1, &v);
 
				value = v ? 1 : 0;
 
			} break;
 

	
 
			default: {
 
				sq_pop(vm, 3);
 
				sq_release(vm, &obj_func);
 
				for (int i = 0; i < nparam; i++) sq_release(vm, &obj_params[i]);
 

	
 
				return sq_throwerror(vm, _SC("return value of valuator is not valid (not integer/bool)"));
 
			}
 
		}
 
		/* Remove junk */
 
		sq_pop(vm, 2);
 

	
 
		(*iter).second = (int32)value;
 
		this->buckets[(int32)value].insert((*iter).first);
 
	}
 

	
 
	sq_release(vm, &obj_func);
 
	for (int i = 0; i < nparam; i++) sq_release(vm, &obj_params[i]);
 
	return 0;
 
}
src/ai/api/ai_abstractlist.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_abstractlist.hpp A list which can keep item/value pairs, which you can walk. */
 
/** @defgroup AIList Classes that create a list of items. */
 

	
 
#ifndef AI_ABSTRACTLIST_HPP
 
#define AI_ABSTRACTLIST_HPP
 

	
 
#include "ai_object.hpp"
 
#include <map>
 
#include <set>
 

	
 
class AIAbstractListSorter;
 

	
 
/**
 
 * Class that creates a list which can keep item/value pairs, which you can walk.
 
 */
 
class AIAbstractList : public AIObject {
 
public:
 
	static const char *GetClassName() { return "AIAbstractList"; }
 

	
 
	/** Type of sorter */
 
	enum SorterType {
 
		SORT_BY_VALUE, ///< Sort the list based on the value of the item.
 
		SORT_BY_ITEM, ///< Sort the list based on the item itself.
 
	};
 

	
 
private:
 
	AIAbstractListSorter *sorter;
 
	SorterType sorter_type;
 
	bool sort_ascending;
 
	bool initialized;
 

	
 
public:
 
	typedef std::set<int32> AIItemList;                       //!< The list of items inside the bucket
 
	typedef std::map<int32, AIItemList> AIAbstractListBucket; //!< The bucket list per value
 
	typedef std::map<int32, int32> AIAbstractListMap;         //!< List per item
 

	
 
	AIAbstractListMap items;           //!< The items in the list
 
	AIAbstractListBucket buckets;      //!< The items in the list, sorted by value
 

	
 
protected:
 
	/**
 
	 * Add a single item to the list.
 
	 * @param item the item to add. Should be unique, otherwise it is ignored.
 
	 * @note the value is set to 0 by default.
 
	 */
 
	void AddItem(int32 item);
 

	
 
	/**
 
	 * Remove a single item from the list.
 
	 * @param item the item to remove. If not existing, it is ignored.
 
	 */
 
	void RemoveItem(int32 item);
 

	
 
public:
 
	AIAbstractList();
 
	~AIAbstractList();
 

	
 
	/**
 
	 * Clear the list, making Count() returning 0 and IsEmpty() returning true.
 
	 */
 
	void Clear();
 

	
 
	/**
 
	 * Check if an item is in the list.
 
	 * @param item the item to check for.
 
	 * @return true if the item is in the list.
 
	 */
 
	bool HasItem(int32 item);
 

	
 
	/**
 
	 * Go to the beginning of the list.
 
	 * @return the item value of the first item.
 
	 */
 
	int32 Begin();
 

	
 
	/**
 
	 * Go to the next item in the list.
 
	 * @return the item value of the next item.
 
	 * @note returns 0 if beyond end-of-list. Use HasNext() to check for end-of-list.
 
	 */
 
	int32 Next();
 

	
 
	/**
 
	 * Check if a list is empty.
 
	 * @return true if the list is empty.
 
	 */
 
	bool IsEmpty();
 

	
 
	/**
 
	 * Check if there is a next element. In other words, if this is true,
 
	 *   Next() will return a valid item.
 
	 * @return true if there is a next item.
 
	 */
 
	bool HasNext();
 

	
 
	/**
 
	 * Returns the amount of items in the list.
 
	 * @return amount of items in the list.
 
	 */
 
	int32 Count();
 

	
 
	/**
 
	 * Get the value that belongs to this item.
 
	 * @param item the item to get the value from
 
	 * @return the value that belongs to this item.
 
	 */
 
	int32 GetValue(int32 item);
 

	
 
	/**
 
	 * Set a value of an item directly.
 
	 * @param item the item to set the value for.
 
	 * @param value the value to give to the item
 
	 * @return true if we could set the item to value, false otherwise.
 
	 * @note Changing values of items while looping through a list might cause
 
	 *  entries to be skipped. Be very careful with such operations.
 
	 */
 
	bool SetValue(int32 item, int32 value);
 

	
 
	/**
 
	 * Sort this list by the given sorter and direction.
 
	 * @param sorter    the type of sorter to use
 
	 * @param ascending if true, lowest value is on top, else at bottom.
 
	 * @note the current item stays at the same place.
 
	 */
 
	void Sort(SorterType sorter, bool ascending);
 

	
 
	/**
 
	 * Add one list to an other one.
 
	 * @param list The list that will be added to the caller.
 
	 * @post The list to be added ('list') stays unmodified.
 
	 * @note All added items keep their value as it was in 'list'.
 
	 * @note If the item already exists inside the caller, the value of the
 
	 *  list that is added is set on the item.
 
	 */
 
	void AddList(AIAbstractList *list);
 

	
 
	/**
 
	 * Removes all items with a higher value than 'value'.
 
	 * @param value the value above which all items are removed.
 
	 */
 
	void RemoveAboveValue(int32 value);
 

	
 
	/**
 
	 * Removes all items with a lower value than 'value'.
 
	 * @param value the value below which all items are removed.
 
	 */
 
	void RemoveBelowValue(int32 value);
 

	
 
	/**
 
	 * Removes all items with a value above start and below end.
 
	 * @param start the lower bound of the to be removed values (exclusive).
 
	 * @param end   the upper bound of the to be removed valuens (exclusive).
 
	 */
 
	void RemoveBetweenValue(int32 start, int32 end);
 

	
 
	/**
 
	 * Remove all items with this value.
 
	 * @param value the value to remove.
 
	 */
 
	void RemoveValue(int32 value);
 

	
 
	/**
 
	 * Remove the first count items.
 
	 * @param count the amount of items to remove.
 
	 */
 
	void RemoveTop(int32 count);
 

	
 
	/**
 
	 * Remove the last count items.
 
	 * @param count the amount of items to remove.
 
	 */
 
	void RemoveBottom(int32 count);
 

	
 
	/**
 
	 * Remove everything that is in the given list from this list (same item index that is).
 
	 * @param list the list of items to remove.
 
	 * @pre list != NULL
 
	 */
 
	void RemoveList(AIAbstractList *list);
 

	
 
	/**
 
	 * Keep all items with a higher value than 'value'.
 
	 * @param value the value above which all items are kept.
 
	 */
 
	void KeepAboveValue(int32 value);
 

	
 
	/**
 
	 * Keep all items with a lower value than 'value'.
 
	 * @param value the value below which all items are kept.
 
	 */
 
	void KeepBelowValue(int32 value);
 

	
 
	/**
 
	 * Keep all items with a value above start and below end.
 
	 * @param start the lower bound of the to be kept values (exclusive).
 
	 * @param end   the upper bound of the to be kept values (exclusive).
 
	 */
 
	void KeepBetweenValue(int32 start, int32 end);
 

	
 
	/**
 
	 * Keep all items with this value.
 
	 * @param value the value to keep.
 
	 **/
 
	void KeepValue(int32 value);
 

	
 
	/**
 
	 * Keep the first count items, i.e. remove everything except the first count items.
 
	 * @param count the amount of items to keep.
 
	 */
 
	void KeepTop(int32 count);
 

	
 
	/**
 
	 * Keep the last count items, i.e. remove everything except the last count items.
 
	 * @param count the amount of items to keep.
 
	 */
 
	void KeepBottom(int32 count);
 

	
 
	/**
 
	 * Keeps everything that is in the given list from this list (same item index that is).
 
	 * @param list the list of items to keep.
 
	 * @pre list != NULL
 
	 */
 
	void KeepList(AIAbstractList *list);
 

	
 
#ifndef DOXYGEN_SKIP
 
	/**
 
	 * Used for 'foreach()' and [] get from Squirrel.
 
	 */
 
	SQInteger _get(HSQUIRRELVM vm);
 

	
 
	/**
 
	 * Used for 'foreach()' from Squirrel.
 
	 */
 
	SQInteger _nexti(HSQUIRRELVM vm);
 

	
 
	/**
 
	 * The Valuate() wrapper from Squirrel.
 
	 */
 
	SQInteger Valuate(HSQUIRRELVM vm);
 
#else
 
	/**
 
	 * Give all items a value defined by the valuator you give.
 
	 * @param valuator_function The function which will be doing the valuation.
 
	 * @param params The params to give to the valuators (minus the first param,
 
	 *  which is always the index-value we are valuating).
 
	 * @note You can write your own valuators and use them. Just remember that
 
	 *  the first parameter should be the index-value, and it should return
 
	 *  an integer.
 
	 * @note Example:
 
	 *  list.Valuate(AIBridge.GetPrice, 5);
 
	 *  list.Valuate(AIBridge.GetMaxLength);
 
	 *  function MyVal(bridge_id, myparam) {
 
	 *    return myparam * bridge_id; // This is silly
 
	 *  }
 
	 *  list.Valuate(MyVal, 12);
 
	 */
 
	void Valuate(void *valuator_function, int params, ...);
 
#endif /* DOXYGEN_SKIP */
 
};
 

	
 
#endif /* AI_LIST_HPP */
src/ai/api/ai_abstractlist.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_abstractlist.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow enums to be used as Squirrel parameters */
 
	template <> AIAbstractList::SorterType GetParam(ForceType<AIAbstractList::SorterType>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AIAbstractList::SorterType)tmp; }
 
	template <> int Return<AIAbstractList::SorterType>(HSQUIRRELVM vm, AIAbstractList::SorterType res) { sq_pushinteger(vm, (int32)res); return 1; }
 

	
 
	/* Allow AIAbstractList to be used as Squirrel parameter */
 
	template <> AIAbstractList *GetParam(ForceType<AIAbstractList *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIAbstractList *)instance; }
 
	template <> AIAbstractList &GetParam(ForceType<AIAbstractList &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIAbstractList *)instance; }
 
	template <> const AIAbstractList *GetParam(ForceType<const AIAbstractList *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIAbstractList *)instance; }
 
	template <> const AIAbstractList &GetParam(ForceType<const AIAbstractList &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIAbstractList *)instance; }
 
	template <> int Return<AIAbstractList *>(HSQUIRRELVM vm, AIAbstractList *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIAbstractList", res, NULL, DefSQDestructorCallback<AIAbstractList>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIAbstractList_Register(Squirrel *engine) {
 
	DefSQClass <AIAbstractList> SQAIAbstractList("AIAbstractList");
 
	SQAIAbstractList.PreRegister(engine);
 
	SQAIAbstractList.AddConstructor<void (AIAbstractList::*)(), 1>(engine, "x");
 

	
 
	SQAIAbstractList.DefSQConst(engine, AIAbstractList::SORT_BY_VALUE, "SORT_BY_VALUE");
 
	SQAIAbstractList.DefSQConst(engine, AIAbstractList::SORT_BY_ITEM,  "SORT_BY_ITEM");
 

	
 
	SQAIAbstractList.DefSQStaticMethod(engine, &AIAbstractList::GetClassName, "GetClassName", 1, "x");
 

	
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::Clear,              "Clear",              1, "x");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::HasItem,            "HasItem",            2, "xi");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::Begin,              "Begin",              1, "x");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::Next,               "Next",               1, "x");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::IsEmpty,            "IsEmpty",            1, "x");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::HasNext,            "HasNext",            1, "x");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::Count,              "Count",              1, "x");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::GetValue,           "GetValue",           2, "xi");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::SetValue,           "SetValue",           3, "xii");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::Sort,               "Sort",               3, "xib");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::AddList,            "AddList",            2, "xx");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::RemoveAboveValue,   "RemoveAboveValue",   2, "xi");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::RemoveBelowValue,   "RemoveBelowValue",   2, "xi");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::RemoveBetweenValue, "RemoveBetweenValue", 3, "xii");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::RemoveValue,        "RemoveValue",        2, "xi");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::RemoveTop,          "RemoveTop",          2, "xi");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::RemoveBottom,       "RemoveBottom",       2, "xi");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::RemoveList,         "RemoveList",         2, "xx");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::KeepAboveValue,     "KeepAboveValue",     2, "xi");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::KeepBelowValue,     "KeepBelowValue",     2, "xi");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::KeepBetweenValue,   "KeepBetweenValue",   3, "xii");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::KeepValue,          "KeepValue",          2, "xi");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::KeepTop,            "KeepTop",            2, "xi");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::KeepBottom,         "KeepBottom",         2, "xi");
 
	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::KeepList,           "KeepList",           2, "xx");
 
	SQAIAbstractList.DefSQAdvancedMethod(engine, &AIAbstractList::_get,       "_get");
 
	SQAIAbstractList.DefSQAdvancedMethod(engine, &AIAbstractList::_nexti,     "_nexti");
 
	SQAIAbstractList.DefSQAdvancedMethod(engine, &AIAbstractList::Valuate,    "Valuate");
 

	
 
	SQAIAbstractList.PostRegister(engine);
 
}
src/ai/api/ai_accounting.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_accounting.cpp Implementation of AIAccounting. */
 

	
 
#include "ai_accounting.hpp"
 

	
 
Money AIAccounting::GetCosts()
 
{
 
	return this->GetDoCommandCosts();
 
}
 

	
 
void AIAccounting::ResetCosts()
 
{
 
	this->SetDoCommandCosts(0);
 
}
 

	
 
AIAccounting::AIAccounting()
 
{
 
	this->last_costs = this->GetDoCommandCosts();
 
	this->SetDoCommandCosts(0);
 
}
 

	
 
AIAccounting::~AIAccounting()
 
{
 
	this->SetDoCommandCosts(this->last_costs);
 
}
src/ai/api/ai_accounting.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_accounting.hpp Everything to handle AI accounting things. */
 

	
 
#ifndef AI_ACCOUNTING_HPP
 
#define AI_ACCOUNTING_HPP
 

	
 
#include "ai_object.hpp"
 

	
 
/**
 
 * Class that keeps track of the costs, so you can request how much a block of
 
 *  commands did cost in total. Works in both Execute as in Test mode.
 
 * Example:
 
 *   {
 
 *     local costs = AIAccounting();
 
 *     BuildRoad(from_here, to_here);
 
 *     BuildRoad(from_there, to_there);
 
 *     print("Costs for route is: " + costs.GetCosts());
 
 *   }
 
 */
 
class AIAccounting : public AIObject {
 
public:
 
	static const char *GetClassName() { return "AIAccounting"; }
 

	
 
	/**
 
	 * Creating instance of this class starts counting the costs of commands
 
	 *   from zero.
 
	 * @note when the instance is destroyed, he restores the costs that was
 
	 *   current when the instance was created!
 
	 */
 
	AIAccounting();
 

	
 
	/**
 
	 * Destroying this instance reset the costs to the value it was
 
	 *   in when the instance was created.
 
	 */
 
	~AIAccounting();
 

	
 
	/**
 
	 * Get the current value of the costs.
 
	 * @return The current costs.
 
	 */
 
	Money GetCosts();
 

	
 
	/**
 
	 * Reset the costs to zero.
 
	 */
 
	void ResetCosts();
 

	
 
private:
 
	Money last_costs;
 
};
 

	
 
#endif /* AI_ACCOUNTING_HPP */
src/ai/api/ai_accounting.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_accounting.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow AIAccounting to be used as Squirrel parameter */
 
	template <> AIAccounting *GetParam(ForceType<AIAccounting *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIAccounting *)instance; }
 
	template <> AIAccounting &GetParam(ForceType<AIAccounting &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIAccounting *)instance; }
 
	template <> const AIAccounting *GetParam(ForceType<const AIAccounting *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIAccounting *)instance; }
 
	template <> const AIAccounting &GetParam(ForceType<const AIAccounting &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIAccounting *)instance; }
 
	template <> int Return<AIAccounting *>(HSQUIRRELVM vm, AIAccounting *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIAccounting", res, NULL, DefSQDestructorCallback<AIAccounting>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIAccounting_Register(Squirrel *engine) {
 
	DefSQClass <AIAccounting> SQAIAccounting("AIAccounting");
 
	SQAIAccounting.PreRegister(engine);
 
	SQAIAccounting.AddConstructor<void (AIAccounting::*)(), 1>(engine, "x");
 

	
 
	SQAIAccounting.DefSQStaticMethod(engine, &AIAccounting::GetClassName, "GetClassName", 1, "x");
 

	
 
	SQAIAccounting.DefSQMethod(engine, &AIAccounting::GetCosts,   "GetCosts",   1, "x");
 
	SQAIAccounting.DefSQMethod(engine, &AIAccounting::ResetCosts, "ResetCosts", 1, "x");
 

	
 
	SQAIAccounting.PostRegister(engine);
 
}
src/ai/api/ai_airport.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_airport.cpp Implementation of AIAirport. */
 

	
 
#include "ai_airport.hpp"
 
#include "ai_station.hpp"
 
#include "ai_error.hpp"
 
#include "../../openttd.h"
 
#include "../../variables.h"
 
#include "../../station_map.h"
 
#include "../../company_func.h"
 
#include "../../settings_type.h"
 
#include "../../command_type.h"
 
#include "../../town.h"
 

	
 
/* static */ bool AIAirport::IsValidAirportType(AirportType type)
 
{
 
	return type >= AT_SMALL && type <= AT_HELISTATION;
 
}
 

	
 
/* static */ bool AIAirport::IsHangarTile(TileIndex tile)
 
{
 
	if (!::IsValidTile(tile)) return false;
 

	
 
	return ::IsTileType(tile, MP_STATION) && ::IsHangar(tile);
 
}
 

	
 
/* static */ bool AIAirport::IsAirportTile(TileIndex tile)
 
{
 
	if (!::IsValidTile(tile)) return false;
 

	
 
	return ::IsTileType(tile, MP_STATION) && ::IsAirport(tile);
 
}
 

	
 
/* static */ bool AIAirport::AirportAvailable(AirportType type)
 
{
 
	if (!IsValidAirportType(type)) return false;
 

	
 
	return HasBit(::GetValidAirports(), type);
 
}
 

	
 
/* static */ int32 AIAirport::GetAirportWidth(AirportType type)
 
{
 
	if (!IsValidAirportType(type)) return -1;
 

	
 
	return ::GetAirport(type)->size_x;
 
}
 

	
 
/* static */ int32 AIAirport::GetAirportHeight(AirportType type)
 
{
 
	if (!IsValidAirportType(type)) return -1;
 

	
 
	return ::GetAirport(type)->size_y;
 
}
 

	
 
/* static */ int32 AIAirport::GetAirportCoverageRadius(AirportType type)
 
{
 
	if (!IsValidAirportType(type)) return -1;
 

	
 
	return _settings_game.station.modified_catchment ? ::GetAirport(type)->catchment : (uint)CA_UNMODIFIED;
 
}
 

	
 
/* static */ bool AIAirport::BuildAirport(TileIndex tile, AirportType type, bool join_adjacent)
 
{
 
	EnforcePrecondition(false, ::IsValidTile(tile));
 
	EnforcePrecondition(false, IsValidAirportType(type));
 

	
 
	return AIObject::DoCommand(tile, type, (INVALID_STATION << 16) | (join_adjacent ? 0 : 1), CMD_BUILD_AIRPORT);
 
}
 

	
 
/* static */ bool AIAirport::RemoveAirport(TileIndex tile)
 
{
 
	EnforcePrecondition(false, ::IsValidTile(tile))
 
	EnforcePrecondition(false, IsAirportTile(tile) || IsHangarTile(tile));
 

	
 
	return AIObject::DoCommand(tile, 0, 0, CMD_LANDSCAPE_CLEAR);
 
}
 

	
 
/* static */ int32 AIAirport::GetNumHangars(TileIndex tile)
 
{
 
	if (!::IsValidTile(tile)) return -1;
 
	if (!::IsTileType(tile, MP_STATION)) return -1;
 

	
 
	const Station *st = ::GetStationByTile(tile);
 
	if (st->owner != _current_company) return -1;
 
	if ((st->facilities & FACIL_AIRPORT) == 0) return -1;
 

	
 
	return st->Airport()->nof_depots;
 
}
 

	
 
/* static */ TileIndex AIAirport::GetHangarOfAirport(TileIndex tile)
 
{
 
	if (!::IsValidTile(tile)) return INVALID_TILE;
 
	if (!::IsTileType(tile, MP_STATION)) return INVALID_TILE;
 
	if (GetNumHangars(tile) < 1) return INVALID_TILE;
 

	
 
	const Station *st = ::GetStationByTile(tile);
 
	if (st->owner != _current_company) return INVALID_TILE;
 
	if ((st->facilities & FACIL_AIRPORT) == 0) return INVALID_TILE;
 

	
 
	return ::ToTileIndexDiff(st->Airport()->airport_depots[0]) + st->xy;
 
}
 

	
 
/* static */ AIAirport::AirportType AIAirport::GetAirportType(TileIndex tile)
 
{
 
	if (!AITile::IsStationTile(tile)) return AT_INVALID;
 

	
 
	StationID station_id = ::GetStationIndex(tile);
 

	
 
	if (!AIStation::HasStationType(station_id, AIStation::STATION_AIRPORT)) return AT_INVALID;
 

	
 
	return (AirportType)::GetStation(station_id)->airport_type;
 
}
 

	
 

	
 
/* static */ int AIAirport::GetNoiseLevelIncrease(TileIndex tile, AirportType type)
 
{
 
	extern uint8 GetAirportNoiseLevelForTown(const AirportFTAClass *afc, TileIndex town_tile, TileIndex tile);
 

	
 
	if (!::IsValidTile(tile)) return -1;
 
	if (!IsValidAirportType(type)) return -1;
 

	
 
	if (_settings_game.economy.station_noise_level) {
 
		const AirportFTAClass *afc = ::GetAirport(type);
 
		const Town *t = ::ClosestTownFromTile(tile, UINT_MAX);
 
		return GetAirportNoiseLevelForTown(afc, t->xy, tile);
 
	}
 

	
 
	return 1;
 
}
src/ai/api/ai_airport.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_airport.hpp Everything to query and build airports. */
 

	
 
#ifndef AI_AIRPORT_HPP
 
#define AI_AIRPORT_HPP
 

	
 
#include "ai_object.hpp"
 

	
 
/**
 
 * Class that handles all airport related functions.
 
 */
 
class AIAirport : public AIObject {
 
public:
 
	static const char *GetClassName() { return "AIAirport"; }
 

	
 
	/**
 
	 * The types of airports available in the game.
 
	 */
 
	enum AirportType {
 
		/* Note: the values _are_ important as they represent an in-game value */
 
		AT_SMALL         =   0, //!< The small airport.
 
		AT_LARGE         =   1, //!< The large airport.
 
		AT_METROPOLITAN  =   3, //!< The metropolitan airport.
 
		AT_INTERNATIONAL =   4, //!< The international airport.
 
		AT_COMMUTER      =   5, //!< The commuter airport.
 
		AT_INTERCON      =   7, //!< The intercontinental airport.
 

	
 
		/* Next are the airports which only have helicopter platforms */
 
		AT_HELIPORT      =   2, //!< The heliport.
 
		AT_HELISTATION   =   8, //!< The helistation.
 
		AT_HELIDEPOT     =   6, //!< The helidepot.
 

	
 
		AT_INVALID       = 255, //!< Invalid airport.
 
	};
 

	
 
	/**
 
	 * All plane types available.
 
	 */
 
	enum PlaneType {
 
		/* Note: the values _are_ important as they represent an in-game value */
 
		PT_HELICOPTER    =   0, //!< A helicopter.
 
		PT_SMALL_PLANE   =   1, //!< A small plane.
 
		PT_BIG_PLANE     =   3, //!< A big plane.
 

	
 
		PT_INVALID       =  -1, //!< An invalid PlaneType
 
	};
 

	
 
	/**
 
	 * Checks whether the given AirportType is valid.
 
	 * @param type The AirportType to check.
 
	 * @return True if and only if the AirportTypeis valid.
 
	 */
 
	static bool IsValidAirportType(AirportType type);
 

	
 
	/**
 
	 * Checks whether the given tile is actually a tile with a hangar.
 
	 * @param tile The tile to check.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @return True if and only if the tile has a hangar.
 
	 */
 
	static bool IsHangarTile(TileIndex tile);
 

	
 
	/**
 
	 * Checks whether the given tile is actually a tile with a airport.
 
	 * @param tile The tile to check.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @return True if and only if the tile has a airport.
 
	 */
 
	static bool IsAirportTile(TileIndex tile);
 

	
 
	/**
 
	 * Check if a certain airport type is already available.
 
	 * @param type The type of airport to check.
 
	 */
 
	static bool AirportAvailable(AirportType type);
 

	
 
	/**
 
	 * Get the width of this type of airport.
 
	 * @param type The type of airport.
 
	 * @return The width in tiles.
 
	 */
 
	static int32 GetAirportWidth(AirportType type);
 

	
 
	/**
 
	 * Get the height of this type of airport.
 
	 * @param type The type of airport.
 
	 * @return The height in tiles.
 
	 */
 
	static int32 GetAirportHeight(AirportType type);
 

	
 
	/**
 
	 * Get the coverage radius of this type of airport.
 
	 * @param type The type of airport.
 
	 * @return The radius in tiles.
 
	 */
 
	static int32 GetAirportCoverageRadius(AirportType type);
 

	
 
	/**
 
	 * Get the number of hangars of the airport.
 
	 * @param tile Any tile of the airport.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @return The number of hangars of the airport.
 
	 */
 
	static int32 GetNumHangars(TileIndex tile);
 

	
 
	/**
 
	 * Get the first hanger tile of the airport.
 
	 * @param tile Any tile of the airport.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @pre GetNumHangars(tile) > 0.
 
	 * @return The first hanger tile of the airport.
 
	 * @note Possible there are more hangars, but you won't be able to find them
 
	 *  without walking over all the tiles of the airport and using
 
	 *  IsHangarTile() on them.
 
	 */
 
	static TileIndex GetHangarOfAirport(TileIndex tile);
 

	
 
	/**
 
	 * Builds a airport with tile at the topleft corner.
 
	 * @param tile The topleft corner of the airport.
 
	 * @param type The type of airport to build.
 
	 * @param join_adjacent When building next to an other station, don't create a new station when this flag is true.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @pre AirportAvailable(type).
 
	 * @exception AIError::ERR_AREA_NOT_CLEAR
 
	 * @exception AIError::ERR_FLAT_LAND_REQUIRED
 
	 * @exception AIError::ERR_LOCAL_AUTHORITY_REFUSES
 
	 * @exception AIStation::ERR_STATION_TOO_LARGE
 
	 * @exception AIStation::ERR_STATION_TOO_CLOSE_TO_OTHER_STATION
 
	 * @return Whether the airport has been/can be build or not.
 
	 */
 
	static bool BuildAirport(TileIndex tile, AirportType type, bool join_adjacent);
 

	
 
	/**
 
	 * Removes a airport.
 
	 * @param tile Any tile of the airport.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @exception AIError::ERR_OWNED_BY_ANOTHER_COMPANY
 
	 * @return Whether the airport has been/can be removed or not.
 
	 */
 
	static bool RemoveAirport(TileIndex tile);
 

	
 
	/**
 
	 * Get the AirportType of an existing airport.
 
	 * @param tile Any tile of the airport.
 
	 * @pre AITile::IsStationTile(tile).
 
	 * @pre AIStation::HasStationType(AIStation.GetStationID(tile), AIStation::STATION_AIRPORT).
 
	 * @return The AirportType of the airport.
 
	 */
 
	static AirportType GetAirportType(TileIndex tile);
 

	
 
	/**
 
	 * Get the noise that will be added to the nearest town if an airport was
 
	 *  built at this tile.
 
	 * @param tile The tile to check.
 
	 * @param type The AirportType to check.
 
	 * @return The TownID of the town closest to the tile.
 
	 * @note The noise will be added to the town with TownID AITile.GetClosestTown(tile).
 
	 */
 
	static int GetNoiseLevelIncrease(TileIndex tile, AirportType type);
 
};
 

	
 
#endif /* AI_AIRPORT_HPP */
src/ai/api/ai_airport.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_airport.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow enums to be used as Squirrel parameters */
 
	template <> AIAirport::AirportType GetParam(ForceType<AIAirport::AirportType>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AIAirport::AirportType)tmp; }
 
	template <> int Return<AIAirport::AirportType>(HSQUIRRELVM vm, AIAirport::AirportType res) { sq_pushinteger(vm, (int32)res); return 1; }
 
	template <> AIAirport::PlaneType GetParam(ForceType<AIAirport::PlaneType>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AIAirport::PlaneType)tmp; }
 
	template <> int Return<AIAirport::PlaneType>(HSQUIRRELVM vm, AIAirport::PlaneType res) { sq_pushinteger(vm, (int32)res); return 1; }
 

	
 
	/* Allow AIAirport to be used as Squirrel parameter */
 
	template <> AIAirport *GetParam(ForceType<AIAirport *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIAirport *)instance; }
 
	template <> AIAirport &GetParam(ForceType<AIAirport &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIAirport *)instance; }
 
	template <> const AIAirport *GetParam(ForceType<const AIAirport *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIAirport *)instance; }
 
	template <> const AIAirport &GetParam(ForceType<const AIAirport &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIAirport *)instance; }
 
	template <> int Return<AIAirport *>(HSQUIRRELVM vm, AIAirport *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIAirport", res, NULL, DefSQDestructorCallback<AIAirport>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIAirport_Register(Squirrel *engine) {
 
	DefSQClass <AIAirport> SQAIAirport("AIAirport");
 
	SQAIAirport.PreRegister(engine);
 
	SQAIAirport.AddConstructor<void (AIAirport::*)(), 1>(engine, "x");
 

	
 
	SQAIAirport.DefSQConst(engine, AIAirport::AT_SMALL,         "AT_SMALL");
 
	SQAIAirport.DefSQConst(engine, AIAirport::AT_LARGE,         "AT_LARGE");
 
	SQAIAirport.DefSQConst(engine, AIAirport::AT_METROPOLITAN,  "AT_METROPOLITAN");
 
	SQAIAirport.DefSQConst(engine, AIAirport::AT_INTERNATIONAL, "AT_INTERNATIONAL");
 
	SQAIAirport.DefSQConst(engine, AIAirport::AT_COMMUTER,      "AT_COMMUTER");
 
	SQAIAirport.DefSQConst(engine, AIAirport::AT_INTERCON,      "AT_INTERCON");
 
	SQAIAirport.DefSQConst(engine, AIAirport::AT_HELIPORT,      "AT_HELIPORT");
 
	SQAIAirport.DefSQConst(engine, AIAirport::AT_HELISTATION,   "AT_HELISTATION");
 
	SQAIAirport.DefSQConst(engine, AIAirport::AT_HELIDEPOT,     "AT_HELIDEPOT");
 
	SQAIAirport.DefSQConst(engine, AIAirport::AT_INVALID,       "AT_INVALID");
 
	SQAIAirport.DefSQConst(engine, AIAirport::PT_HELICOPTER,    "PT_HELICOPTER");
 
	SQAIAirport.DefSQConst(engine, AIAirport::PT_SMALL_PLANE,   "PT_SMALL_PLANE");
 
	SQAIAirport.DefSQConst(engine, AIAirport::PT_BIG_PLANE,     "PT_BIG_PLANE");
 
	SQAIAirport.DefSQConst(engine, AIAirport::PT_INVALID,       "PT_INVALID");
 

	
 
	SQAIAirport.DefSQStaticMethod(engine, &AIAirport::GetClassName,             "GetClassName",             1, "x");
 
	SQAIAirport.DefSQStaticMethod(engine, &AIAirport::IsValidAirportType,       "IsValidAirportType",       2, "xi");
 
	SQAIAirport.DefSQStaticMethod(engine, &AIAirport::IsHangarTile,             "IsHangarTile",             2, "xi");
 
	SQAIAirport.DefSQStaticMethod(engine, &AIAirport::IsAirportTile,            "IsAirportTile",            2, "xi");
 
	SQAIAirport.DefSQStaticMethod(engine, &AIAirport::AirportAvailable,         "AirportAvailable",         2, "xi");
 
	SQAIAirport.DefSQStaticMethod(engine, &AIAirport::GetAirportWidth,          "GetAirportWidth",          2, "xi");
 
	SQAIAirport.DefSQStaticMethod(engine, &AIAirport::GetAirportHeight,         "GetAirportHeight",         2, "xi");
 
	SQAIAirport.DefSQStaticMethod(engine, &AIAirport::GetAirportCoverageRadius, "GetAirportCoverageRadius", 2, "xi");
 
	SQAIAirport.DefSQStaticMethod(engine, &AIAirport::GetNumHangars,            "GetNumHangars",            2, "xi");
 
	SQAIAirport.DefSQStaticMethod(engine, &AIAirport::GetHangarOfAirport,       "GetHangarOfAirport",       2, "xi");
 
	SQAIAirport.DefSQStaticMethod(engine, &AIAirport::BuildAirport,             "BuildAirport",             4, "xiib");
 
	SQAIAirport.DefSQStaticMethod(engine, &AIAirport::RemoveAirport,            "RemoveAirport",            2, "xi");
 
	SQAIAirport.DefSQStaticMethod(engine, &AIAirport::GetAirportType,           "GetAirportType",           2, "xi");
 
	SQAIAirport.DefSQStaticMethod(engine, &AIAirport::GetNoiseLevelIncrease,    "GetNoiseLevelIncrease",    3, "xii");
 

	
 
	SQAIAirport.PostRegister(engine);
 
}
src/ai/api/ai_base.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_base.cpp Implementation of AIBase. */
 

	
 
#include "ai_base.hpp"
 
#include "../../network/network.h"
 
#include "../../core/random_func.hpp"
 

	
 
/* static */ uint32 AIBase::Rand()
 
{
 
	/* We pick RandomRange if we are in SP (so when saved, we do the same over and over)
 
	 *   but we pick InteractiveRandomRange if we are a network_server or network-client. */
 
	if (_networking) return ::InteractiveRandom();
 
	return ::Random();
 
}
 

	
 
/* static */ uint32 AIBase::RandItem(int unused_param)
 
{
 
	return AIBase::Rand();
 
}
 

	
 
/* static */ uint AIBase::RandRange(uint max)
 
{
 
	/* We pick RandomRange if we are in SP (so when saved, we do the same over and over)
 
	 *   but we pick InteractiveRandomRange if we are a network_server or network-client. */
 
	if (_networking) return ::InteractiveRandomRange(max);
 
	return ::RandomRange(max);
 
}
 

	
 
/* static */ uint32 AIBase::RandRangeItem(int unused_param, uint max)
 
{
 
	return AIBase::RandRange(max);
 
}
 

	
 
/* static */ bool AIBase::Chance(uint out, uint max)
 
{
 
	return (uint16)Rand() <= (uint16)((65536 * out) / max);
 
}
 

	
 
/* static */ bool AIBase::ChanceItem(int unused_param, uint out, uint max)
 
{
 
	return AIBase::Chance(out, max);
 
}
src/ai/api/ai_base.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_base.hpp Everything to query basic things. */
 

	
 
#ifndef AI_BASE_HPP
 
#define AI_BASE_HPP
 

	
 
#include "ai_object.hpp"
 

	
 
/**
 
 * Class that handles some basic functions.
 
 *
 
 * @note The random functions are not called Random and RandomRange, because
 
 *        RANDOM_DEBUG does some tricky stuff, which messes with those names.
 
 * @note In MP we cannot use Random because that will cause desyncs (AIs are
 
 *        ran on the server only, not on all clients). This means that
 
 *        we use InteractiveRandom in MP. Rand() takes care of this for you.
 
 */
 
class AIBase : public AIObject {
 
public:
 
	static const char *GetClassName() { return "AIBase"; }
 

	
 
	/**
 
	 * Get a random value.
 
	 * @return A random value between 0 and MAX(uint32).
 
	 */
 
	static uint32 Rand();
 

	
 
	/**
 
	 * Get a random value.
 
	 * @param unused_param This param is not used, but is needed to work with lists.
 
	 * @return A random value between 0 and MAX(uint32).
 
	 */
 
	static uint32 RandItem(int unused_param);
 

	
 
	/**
 
	 * Get a random value in a range.
 
	 * @param max The first number this function will never return (the maximum it returns is max - 1).
 
	 * @return A random value between 0 .. max - 1.
 
	 */
 
	static uint RandRange(uint max);
 

	
 
	/**
 
	 * Get a random value in a range.
 
	 * @param unused_param This param is not used, but is needed to work with lists.
 
	 * @param max The first number this function will never return (the maximum it returns is max - 1).
 
	 * @return A random value between 0 .. max - 1.
 
	 */
 
	static uint RandRangeItem(int unused_param, uint max);
 

	
 
	/**
 
	 * Returns approximatelly 'out' times true when called 'max' times.
 
	 *   After all, it is a random function.
 
	 * @param out How many times it should return true.
 
	 * @param max Out of this many times.
 
	 * @return True if the chance worked out.
 
	 */
 
	static bool Chance(uint out, uint max);
 

	
 
	/**
 
	 * Returns approximatelly 'out' times true when called 'max' times.
 
	 *   After all, it is a random function.
 
	 * @param unused_param This param is not used, but is needed to work with lists.
 
	 * @param out How many times it should return true.
 
	 * @param max Out of this many times.
 
	 * @return True if the chance worked out.
 
	 */
 
	static bool ChanceItem(int unused_param, uint out, uint max);
 
};
 

	
 
#endif /* AI_BASE_HPP */
src/ai/api/ai_base.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_base.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow AIBase to be used as Squirrel parameter */
 
	template <> AIBase *GetParam(ForceType<AIBase *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIBase *)instance; }
 
	template <> AIBase &GetParam(ForceType<AIBase &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIBase *)instance; }
 
	template <> const AIBase *GetParam(ForceType<const AIBase *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIBase *)instance; }
 
	template <> const AIBase &GetParam(ForceType<const AIBase &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIBase *)instance; }
 
	template <> int Return<AIBase *>(HSQUIRRELVM vm, AIBase *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIBase", res, NULL, DefSQDestructorCallback<AIBase>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIBase_Register(Squirrel *engine) {
 
	DefSQClass <AIBase> SQAIBase("AIBase");
 
	SQAIBase.PreRegister(engine);
 
	SQAIBase.AddConstructor<void (AIBase::*)(), 1>(engine, "x");
 

	
 
	SQAIBase.DefSQStaticMethod(engine, &AIBase::GetClassName,  "GetClassName",  1, "x");
 
	SQAIBase.DefSQStaticMethod(engine, &AIBase::Rand,          "Rand",          1, "x");
 
	SQAIBase.DefSQStaticMethod(engine, &AIBase::RandItem,      "RandItem",      2, "xi");
 
	SQAIBase.DefSQStaticMethod(engine, &AIBase::RandRange,     "RandRange",     2, "xi");
 
	SQAIBase.DefSQStaticMethod(engine, &AIBase::RandRangeItem, "RandRangeItem", 3, "xii");
 
	SQAIBase.DefSQStaticMethod(engine, &AIBase::Chance,        "Chance",        3, "xii");
 
	SQAIBase.DefSQStaticMethod(engine, &AIBase::ChanceItem,    "ChanceItem",    4, "xiii");
 

	
 
	SQAIBase.PostRegister(engine);
 
}
src/ai/api/ai_bridge.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_bridge.cpp Implementation of AIBridge. */
 

	
 
#include "ai_bridge.hpp"
 
#include "ai_rail.hpp"
 
#include "../ai_instance.hpp"
 
#include "../../openttd.h"
 
#include "../../bridge_map.h"
 
#include "../../strings_func.h"
 
#include "../../core/alloc_func.hpp"
 
#include "../../economy_func.h"
 
#include "../../settings_type.h"
 
#include "../../road_map.h"
 
#include "table/strings.h"
 

	
 
/* static */ bool AIBridge::IsValidBridge(BridgeID bridge_id)
 
{
 
	return bridge_id < MAX_BRIDGES;
 
}
 

	
 
/* static */ bool AIBridge::IsBridgeTile(TileIndex tile)
 
{
 
	if (!::IsValidTile(tile)) return false;
 
	return ::IsBridgeTile(tile);
 
}
 

	
 
static void _DoCommandReturnBuildBridge2(class AIInstance *instance)
 
{
 
	if (!AIBridge::_BuildBridgeRoad2()) {
 
		AIObject::SetLastCommandRes(false);
 
		AIInstance::DoCommandReturn(instance);
 
		return;
 
	}
 

	
 
	/* This can never happen, as in test-mode this callback is never executed,
 
	*  and in execute-mode, the other callback is called. */
 
	NOT_REACHED();
 
}
 

	
 
static void _DoCommandReturnBuildBridge1(class AIInstance *instance)
 
{
 
	if (!AIBridge::_BuildBridgeRoad1()) {
 
		AIObject::SetLastCommandRes(false);
 
		AIInstance::DoCommandReturn(instance);
 
		return;
 
	}
 

	
 
	/* This can never happen, as in test-mode this callback is never executed,
 
	*  and in execute-mode, the other callback is called. */
 
	NOT_REACHED();
 
}
 

	
 
/* static */ bool AIBridge::BuildBridge(AIVehicle::VehicleType vehicle_type, BridgeID bridge_id, TileIndex start, TileIndex end)
 
{
 
	EnforcePrecondition(false, start != end);
 
	EnforcePrecondition(false, ::IsValidTile(start) && ::IsValidTile(end));
 
	EnforcePrecondition(false, TileX(start) == TileX(end) || TileY(start) == TileY(end));
 
	EnforcePrecondition(false, vehicle_type == AIVehicle::VEHICLE_ROAD || vehicle_type == AIVehicle::VEHICLE_RAIL || vehicle_type == AIVehicle::VEHICLE_WATER);
 
	EnforcePrecondition(false, vehicle_type != AIVehicle::VEHICLE_RAIL || AIRail::IsRailTypeAvailable(AIRail::GetCurrentRailType()));
 

	
 
	uint type = 0;
 
	switch (vehicle_type) {
 
		case AIVehicle::VEHICLE_ROAD:
 
			type |= (TRANSPORT_ROAD << 15);
 
			type |= (RoadTypeToRoadTypes((::RoadType)AIObject::GetRoadType()) << 8);
 
			break;
 
		case AIVehicle::VEHICLE_RAIL:
 
			type |= (TRANSPORT_RAIL << 15);
 
			type |= (AIRail::GetCurrentRailType() << 8);
 
			break;
 
		case AIVehicle::VEHICLE_WATER:
 
			type |= (TRANSPORT_WATER << 15);
 
			break;
 
		default: NOT_REACHED();
 
	}
 

	
 
	/* For rail and water we do nothing special */
 
	if (vehicle_type == AIVehicle::VEHICLE_RAIL || vehicle_type == AIVehicle::VEHICLE_WATER) {
 
		return AIObject::DoCommand(end, start, type | bridge_id, CMD_BUILD_BRIDGE);
 
	}
 

	
 
	AIObject::SetCallbackVariable(0, start);
 
	if (!AIObject::DoCommand(end, start, type | bridge_id, CMD_BUILD_BRIDGE, NULL, &_DoCommandReturnBuildBridge1)) return false;
 

	
 
	/* In case of test-mode, test if we can build both road pieces */
 
	return _BuildBridgeRoad1();
 
}
 

	
 
/* static */ bool AIBridge::_BuildBridgeRoad1()
 
{
 
	/* Build the piece of road on the 'start' side of the bridge */
 
	TileIndex end = AIObject::GetCallbackVariable(0);
 
	TileIndex start = AIBridge::GetOtherBridgeEnd(end);
 

	
 
	DiagDirection dir_1 = (DiagDirection)((::TileX(start) == ::TileX(end)) ? (::TileY(start) < ::TileY(end) ? DIAGDIR_NW : DIAGDIR_SE) : (::TileX(start) < ::TileX(end) ? DIAGDIR_NE : DIAGDIR_SW));
 
	DiagDirection dir_2 = ::ReverseDiagDir(dir_1);
 

	
 
	if (!AIObject::DoCommand(start + ::TileOffsByDiagDir(dir_1), ::DiagDirToRoadBits(dir_2) | (AIObject::GetRoadType() << 4), 0, CMD_BUILD_ROAD, NULL, &_DoCommandReturnBuildBridge2)) return false;
 

	
 
	/* In case of test-mode, test the other road piece too */
 
	return _BuildBridgeRoad2();
 
}
 

	
 
/* static */ bool AIBridge::_BuildBridgeRoad2()
 
{
 
	/* Build the piece of road on the 'end' side of the bridge */
 
	TileIndex end = AIObject::GetCallbackVariable(0);
 
	TileIndex start = AIBridge::GetOtherBridgeEnd(end);
 

	
 
	DiagDirection dir_1 = (DiagDirection)((::TileX(start) == ::TileX(end)) ? (::TileY(start) < ::TileY(end) ? DIAGDIR_NW : DIAGDIR_SE) : (::TileX(start) < ::TileX(end) ? DIAGDIR_NE : DIAGDIR_SW));
 
	DiagDirection dir_2 = ::ReverseDiagDir(dir_1);
 

	
 
	return AIObject::DoCommand(end + ::TileOffsByDiagDir(dir_2), ::DiagDirToRoadBits(dir_1) | (AIObject::GetRoadType() << 4), 0, CMD_BUILD_ROAD);
 
}
 

	
 
/* static */ bool AIBridge::RemoveBridge(TileIndex tile)
 
{
 
	EnforcePrecondition(false, IsBridgeTile(tile));
 
	return AIObject::DoCommand(tile, 0, 0, CMD_LANDSCAPE_CLEAR);
 
}
 

	
 
/* static */ const char *AIBridge::GetName(BridgeID bridge_id)
 
{
 
	if (!IsValidBridge(bridge_id)) return NULL;
 

	
 
	static const int len = 64;
 
	char *bridge_name = MallocT<char>(len);
 

	
 
	::GetString(bridge_name, ::GetBridgeSpec(bridge_id)->transport_name[0], &bridge_name[len - 1]);
 
	return bridge_name;
 
}
 

	
 
/* static */ int32 AIBridge::GetMaxSpeed(BridgeID bridge_id)
 
{
 
	if (!IsValidBridge(bridge_id)) return -1;
 

	
 
	return ::GetBridgeSpec(bridge_id)->speed;
 
}
 

	
 
/* static */ Money AIBridge::GetPrice(BridgeID bridge_id, uint length)
 
{
 
	if (!IsValidBridge(bridge_id)) return -1;
 

	
 
	return length * _price.build_bridge * ::GetBridgeSpec(bridge_id)->price >> 8;
 
}
 

	
 
/* static */ int32 AIBridge::GetMaxLength(BridgeID bridge_id)
 
{
 
	if (!IsValidBridge(bridge_id)) return -1;
 

	
 
	uint max = ::GetBridgeSpec(bridge_id)->max_length;
 
	if (max >= 16 && _settings_game.construction.longbridges) max = 100;
 
	return max + 2;
 
}
 

	
 
/* static */ int32 AIBridge::GetMinLength(BridgeID bridge_id)
 
{
 
	if (!IsValidBridge(bridge_id)) return -1;
 

	
 
	return ::GetBridgeSpec(bridge_id)->min_length + 2;
 
}
 

	
 
/* static */ int32 AIBridge::GetYearAvailable(BridgeID bridge_id)
 
{
 
	if (!IsValidBridge(bridge_id)) return -1;
 

	
 
	return ::GetBridgeSpec(bridge_id)->avail_year;
 
}
 

	
 
/* static */ TileIndex AIBridge::GetOtherBridgeEnd(TileIndex tile)
 
{
 
	if (!::IsValidTile(tile)) return INVALID_TILE;
 
	if (!IsBridgeTile(tile)) return INVALID_TILE;
 

	
 
	return ::GetOtherBridgeEnd(tile);
 
}
src/ai/api/ai_bridge.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_bridge.hpp Everything to query and build bridges. */
 

	
 
#ifndef AI_BRIDGE_HPP
 
#define AI_BRIDGE_HPP
 

	
 
#include "ai_object.hpp"
 
#include "ai_vehicle.hpp"
 
#include "ai_error.hpp"
 

	
 
/**
 
 * Class that handles all bridge related functions.
 
 */
 
class AIBridge : public AIObject {
 
public:
 
	/**
 
	 * All bridge related error messages.
 
	 */
 
	enum ErrorMessages {
 
		/** Base for bridge related errors */
 
		ERR_BRIDGE_BASE = AIError::ERR_CAT_BRIDGE << AIError::ERR_CAT_BIT_SIZE,
 

	
 
		/**
 
		 * The bridge you want to build is not available yet,
 
		 * or it is not available for the requested length.
 
		 */
 
		ERR_BRIDGE_TYPE_UNAVAILABLE,         // [STR_5015_CAN_T_BUILD_BRIDGE_HERE]
 

	
 
		/** One (or more) of the bridge head(s) ends in water. */
 
		ERR_BRIDGE_CANNOT_END_IN_WATER,      // [STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH]
 

	
 
		/** The bride heads need to be on the same height */
 
		ERR_BRIDGE_HEADS_NOT_ON_SAME_HEIGHT, // [STR_BRIDGEHEADS_NOT_SAME_HEIGHT]
 
	};
 

	
 
	static const char *GetClassName() { return "AIBridge"; }
 

	
 
	/**
 
	 * Checks whether the given bridge type is valid.
 
	 * @param bridge_id The bridge to check.
 
	 * @return True if and only if the bridge type is valid.
 
	 */
 
	static bool IsValidBridge(BridgeID bridge_id);
 

	
 
	/**
 
	 * Checks whether the given tile is actually a bridge start or end tile.
 
	 * @param tile The tile to check.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @return True if and only if the tile is the beginning or end of a bridge.
 
	 */
 
	static bool IsBridgeTile(TileIndex tile);
 

	
 
	/**
 
	 * Get the name of a bridge.
 
	 * @param bridge_id The bridge to get the name of.
 
	 * @pre IsValidBridge(bridge_id).
 
	 * @return The name the bridge has.
 
	 */
 
	static const char *GetName(BridgeID bridge_id);
 

	
 
	/**
 
	 * Get the maximum speed of a bridge (in km/h).
 
	 * @param bridge_id The bridge to get the maximum speed of.
 
	 * @pre IsValidBridge(bridge_id).
 
	 * @return The maximum speed the bridge has.
 
	 */
 
	static int32 GetMaxSpeed(BridgeID bridge_id);
 

	
 
	/**
 
	 * Get the new cost of a bridge.
 
	 * @param bridge_id The bridge to get the new cost of.
 
	 * @param length The length of the bridge.
 
	 * @pre IsValidBridge(bridge_id).
 
	 * @return The new cost the bridge has.
 
	 */
 
	static Money GetPrice(BridgeID bridge_id, uint length);
 

	
 
	/**
 
	 * Get the maximum length of a bridge.
 
	 * @param bridge_id The bridge to get the maximum length of.
 
	 * @pre IsValidBridge(bridge_id).
 
	 * @returns The maximum length the bridge has.
 
	 */
 
	static int32 GetMaxLength(BridgeID bridge_id);
 

	
 
	/**
 
	 * Get the minimum length of a bridge.
 
	 * @param bridge_id The bridge to get the minimum length of.
 
	 * @pre IsValidBridge(bridge_id).
 
	 * @returns The minimum length the bridge has.
 
	 */
 
	static int32 GetMinLength(BridgeID bridge_id);
 

	
 
	/**
 
	 * Get the year in which a bridge becomes available.
 
	 * @param bridge_id The bridge to get the year of availability of.
 
	 * @pre IsValidBridge(bridge_id).
 
	 * @returns The year of availability the bridge has.
 
	 * @note Years are like 2010, -10 (10 B.C.), 1950, ..
 
	 */
 
	static int32 GetYearAvailable(BridgeID bridge_id);
 

	
 
#ifndef DOXYGEN_SKIP
 
	/**
 
	 * Internal function to help BuildBridge in case of road.
 
	 */
 
	static bool _BuildBridgeRoad1();
 

	
 
	/**
 
	 * Internal function to help BuildBridge in case of road.
 
	 */
 
	static bool _BuildBridgeRoad2();
 
#endif
 

	
 
	/**
 
	 * Build a bridge from one tile to the other.
 
	 * As an extra for road, this functions builds two half-pieces of road on
 
	 *  each end of the bridge, making it easier for you to connect it to your
 
	 *  network.
 
	 * @param vehicle_type The vehicle-type of bridge to build.
 
	 * @param bridge_id The bridge-type to build.
 
	 * @param start Where to start the bridge.
 
	 * @param end Where to end the bridge.
 
	 * @pre AIMap::IsValidTile(start).
 
	 * @pre AIMap::IsValidTile(end).
 
	 * @pre 'start' and 'end' are in a straight line, i.e.
 
	 *  AIMap::GetTileX(start) == AIMap::GetTileX(end) or
 
	 *  AIMap::GetTileY(start) == AIMap::GetTileY(end).
 
	 * @pre vehicle_type == AIVehicle::VEHICLE_ROAD || (vehicle_type == AIVehicle::VEHICLE_RAIL &&
 
	 *   AIRail::IsRailTypeAvailable(AIRail::GetCurrentRailType())) || vehicle_type == AIVehicle::VEHICLE_WATER.
 
	 * @exception AIError::ERR_ALREADY_BUILT
 
	 * @exception AIError::ERR_AREA_NOT_CLEAR
 
	 * @exception AIError::ERR_LAND_SLOPED_WRONG
 
	 * @exception AIError::ERR_VEHICLE_IN_THE_WAY
 
	 * @exception AIBridge::ERR_BRIDGE_TYPE_UNAVAILABLE
 
	 * @exception AIBridge::ERR_BRIDGE_CANNOT_END_IN_WATER
 
	 * @exception AIBridge::ERR_BRIDGE_HEADS_NOT_ON_SAME_HEIGHT
 
	 * @return Whether the bridge has been/can be build or not.
 
	 * @note No matter if the road pieces were build or not, if building the
 
	 *  bridge succeeded, this function returns true.
 
	 */
 
	static bool BuildBridge(AIVehicle::VehicleType vehicle_type, BridgeID bridge_id, TileIndex start, TileIndex end);
 

	
 
	/**
 
	 * Removes a bridge, by executing it on either the start or end tile.
 
	 * @param tile An end or start tile of the bridge.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @exception AIError::ERR_OWNED_BY_ANOTHER_COMPANY
 
	 * @return Whether the bridge has been/can be removed or not.
 
	 */
 
	static bool RemoveBridge(TileIndex tile);
 

	
 
	/**
 
	 * Get the tile that is on the other end of a bridge starting at tile.
 
	 * @param tile The tile that is an end of a bridge.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @pre IsBridgeTile(tile).
 
	 * @return The TileIndex that is the other end of the bridge.
 
	 */
 
	static TileIndex GetOtherBridgeEnd(TileIndex tile);
 
};
 

	
 
#endif /* AI_BRIDGE_HPP */
src/ai/api/ai_bridge.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_bridge.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow enums to be used as Squirrel parameters */
 
	template <> AIBridge::ErrorMessages GetParam(ForceType<AIBridge::ErrorMessages>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AIBridge::ErrorMessages)tmp; }
 
	template <> int Return<AIBridge::ErrorMessages>(HSQUIRRELVM vm, AIBridge::ErrorMessages res) { sq_pushinteger(vm, (int32)res); return 1; }
 

	
 
	/* Allow AIBridge to be used as Squirrel parameter */
 
	template <> AIBridge *GetParam(ForceType<AIBridge *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIBridge *)instance; }
 
	template <> AIBridge &GetParam(ForceType<AIBridge &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIBridge *)instance; }
 
	template <> const AIBridge *GetParam(ForceType<const AIBridge *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIBridge *)instance; }
 
	template <> const AIBridge &GetParam(ForceType<const AIBridge &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIBridge *)instance; }
 
	template <> int Return<AIBridge *>(HSQUIRRELVM vm, AIBridge *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIBridge", res, NULL, DefSQDestructorCallback<AIBridge>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIBridge_Register(Squirrel *engine) {
 
	DefSQClass <AIBridge> SQAIBridge("AIBridge");
 
	SQAIBridge.PreRegister(engine);
 
	SQAIBridge.AddConstructor<void (AIBridge::*)(), 1>(engine, "x");
 

	
 
	SQAIBridge.DefSQConst(engine, AIBridge::ERR_BRIDGE_BASE,                     "ERR_BRIDGE_BASE");
 
	SQAIBridge.DefSQConst(engine, AIBridge::ERR_BRIDGE_TYPE_UNAVAILABLE,         "ERR_BRIDGE_TYPE_UNAVAILABLE");
 
	SQAIBridge.DefSQConst(engine, AIBridge::ERR_BRIDGE_CANNOT_END_IN_WATER,      "ERR_BRIDGE_CANNOT_END_IN_WATER");
 
	SQAIBridge.DefSQConst(engine, AIBridge::ERR_BRIDGE_HEADS_NOT_ON_SAME_HEIGHT, "ERR_BRIDGE_HEADS_NOT_ON_SAME_HEIGHT");
 

	
 
	AIError::RegisterErrorMap(STR_5015_CAN_T_BUILD_BRIDGE_HERE,  AIBridge::ERR_BRIDGE_TYPE_UNAVAILABLE);
 
	AIError::RegisterErrorMap(STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH, AIBridge::ERR_BRIDGE_CANNOT_END_IN_WATER);
 
	AIError::RegisterErrorMap(STR_BRIDGEHEADS_NOT_SAME_HEIGHT,   AIBridge::ERR_BRIDGE_HEADS_NOT_ON_SAME_HEIGHT);
 

	
 
	AIError::RegisterErrorMapString(AIBridge::ERR_BRIDGE_TYPE_UNAVAILABLE,         "ERR_BRIDGE_TYPE_UNAVAILABLE");
 
	AIError::RegisterErrorMapString(AIBridge::ERR_BRIDGE_CANNOT_END_IN_WATER,      "ERR_BRIDGE_CANNOT_END_IN_WATER");
 
	AIError::RegisterErrorMapString(AIBridge::ERR_BRIDGE_HEADS_NOT_ON_SAME_HEIGHT, "ERR_BRIDGE_HEADS_NOT_ON_SAME_HEIGHT");
 

	
 
	SQAIBridge.DefSQStaticMethod(engine, &AIBridge::GetClassName,      "GetClassName",      1, "x");
 
	SQAIBridge.DefSQStaticMethod(engine, &AIBridge::IsValidBridge,     "IsValidBridge",     2, "xi");
 
	SQAIBridge.DefSQStaticMethod(engine, &AIBridge::IsBridgeTile,      "IsBridgeTile",      2, "xi");
 
	SQAIBridge.DefSQStaticMethod(engine, &AIBridge::GetName,           "GetName",           2, "xi");
 
	SQAIBridge.DefSQStaticMethod(engine, &AIBridge::GetMaxSpeed,       "GetMaxSpeed",       2, "xi");
 
	SQAIBridge.DefSQStaticMethod(engine, &AIBridge::GetPrice,          "GetPrice",          3, "xii");
 
	SQAIBridge.DefSQStaticMethod(engine, &AIBridge::GetMaxLength,      "GetMaxLength",      2, "xi");
 
	SQAIBridge.DefSQStaticMethod(engine, &AIBridge::GetMinLength,      "GetMinLength",      2, "xi");
 
	SQAIBridge.DefSQStaticMethod(engine, &AIBridge::GetYearAvailable,  "GetYearAvailable",  2, "xi");
 
	SQAIBridge.DefSQStaticMethod(engine, &AIBridge::BuildBridge,       "BuildBridge",       5, "xiiii");
 
	SQAIBridge.DefSQStaticMethod(engine, &AIBridge::RemoveBridge,      "RemoveBridge",      2, "xi");
 
	SQAIBridge.DefSQStaticMethod(engine, &AIBridge::GetOtherBridgeEnd, "GetOtherBridgeEnd", 2, "xi");
 

	
 
	SQAIBridge.PostRegister(engine);
 
}
src/ai/api/ai_bridgelist.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_bridgelist.cpp Implementation of AIBridgeList and friends. */
 

	
 
#include "ai_bridgelist.hpp"
 
#include "ai_bridge.hpp"
 
#include "../../openttd.h"
 
#include "../../bridge.h"
 
#include "../../date_func.h"
 

	
 
AIBridgeList::AIBridgeList()
 
{
 
	/* Add all bridges, no matter if they are available or not */
 
	for (byte j = 0; j < MAX_BRIDGES; j++)
 
		if (::GetBridgeSpec(j)->avail_year <= _cur_year)
 
			this->AddItem(j);
 
}
 

	
 
AIBridgeList_Length::AIBridgeList_Length(uint length)
 
{
 
	for (byte j = 0; j < MAX_BRIDGES; j++)
 
		if (::GetBridgeSpec(j)->avail_year <= _cur_year)
 
			if (length >= (uint)AIBridge::GetMinLength(j) && length <= (uint)AIBridge::GetMaxLength(j))
 
				this->AddItem(j);
 
}
src/ai/api/ai_bridgelist.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_bridgelist.hpp List all the bridges. */
 

	
 
#ifndef AI_BRIDGELIST_HPP
 
#define AI_BRIDGELIST_HPP
 

	
 
#include "ai_abstractlist.hpp"
 

	
 
/**
 
 * Create a list of bridges.
 
 * @ingroup AIList
 
 */
 
class AIBridgeList : public AIAbstractList {
 
public:
 
	static const char *GetClassName() { return "AIBridgeList"; }
 
	AIBridgeList();
 
};
 

	
 
/**
 
 * Create a list of bridges that can be built on a specific length.
 
 * @ingroup AIList
 
 */
 
class AIBridgeList_Length : public AIAbstractList {
 
public:
 
	static const char *GetClassName() { return "AIBridgeList_Length"; }
 

	
 
	/**
 
	 * @param length The length of the bridge you want to build.
 
	 */
 
	AIBridgeList_Length(uint length);
 
};
 

	
 
#endif /* AI_BRIDGELIST_HPP */
src/ai/api/ai_bridgelist.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_bridgelist.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow AIBridgeList to be used as Squirrel parameter */
 
	template <> AIBridgeList *GetParam(ForceType<AIBridgeList *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIBridgeList *)instance; }
 
	template <> AIBridgeList &GetParam(ForceType<AIBridgeList &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIBridgeList *)instance; }
 
	template <> const AIBridgeList *GetParam(ForceType<const AIBridgeList *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIBridgeList *)instance; }
 
	template <> const AIBridgeList &GetParam(ForceType<const AIBridgeList &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIBridgeList *)instance; }
 
	template <> int Return<AIBridgeList *>(HSQUIRRELVM vm, AIBridgeList *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIBridgeList", res, NULL, DefSQDestructorCallback<AIBridgeList>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIBridgeList_Register(Squirrel *engine) {
 
	DefSQClass <AIBridgeList> SQAIBridgeList("AIBridgeList");
 
	SQAIBridgeList.PreRegister(engine, "AIAbstractList");
 
	SQAIBridgeList.AddConstructor<void (AIBridgeList::*)(), 1>(engine, "x");
 

	
 
	SQAIBridgeList.DefSQStaticMethod(engine, &AIBridgeList::GetClassName, "GetClassName", 1, "x");
 

	
 
	SQAIBridgeList.PostRegister(engine);
 
}
 

	
 
namespace SQConvert {
 
	/* Allow AIBridgeList_Length to be used as Squirrel parameter */
 
	template <> AIBridgeList_Length *GetParam(ForceType<AIBridgeList_Length *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIBridgeList_Length *)instance; }
 
	template <> AIBridgeList_Length &GetParam(ForceType<AIBridgeList_Length &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIBridgeList_Length *)instance; }
 
	template <> const AIBridgeList_Length *GetParam(ForceType<const AIBridgeList_Length *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIBridgeList_Length *)instance; }
 
	template <> const AIBridgeList_Length &GetParam(ForceType<const AIBridgeList_Length &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIBridgeList_Length *)instance; }
 
	template <> int Return<AIBridgeList_Length *>(HSQUIRRELVM vm, AIBridgeList_Length *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIBridgeList_Length", res, NULL, DefSQDestructorCallback<AIBridgeList_Length>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIBridgeList_Length_Register(Squirrel *engine) {
 
	DefSQClass <AIBridgeList_Length> SQAIBridgeList_Length("AIBridgeList_Length");
 
	SQAIBridgeList_Length.PreRegister(engine, "AIAbstractList");
 
	SQAIBridgeList_Length.AddConstructor<void (AIBridgeList_Length::*)(uint length), 2>(engine, "xi");
 

	
 
	SQAIBridgeList_Length.DefSQStaticMethod(engine, &AIBridgeList_Length::GetClassName, "GetClassName", 1, "x");
 

	
 
	SQAIBridgeList_Length.PostRegister(engine);
 
}
src/ai/api/ai_cargo.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_cargo.cpp Implementation of AICargo. */
 

	
 
#include "ai_cargo.hpp"
 
#include "../../openttd.h"
 
#include "../../cargotype.h"
 
#include "../../economy_func.h"
 
#include "../../core/alloc_func.hpp"
 
#include "../../core/bitmath_func.hpp"
 
#include "../../newgrf_cargo.h"
 

	
 
/* static */ bool AICargo::IsValidCargo(CargoID cargo_type)
 
{
 
	return (cargo_type < NUM_CARGO && ::GetCargo(cargo_type)->IsValid());
 
}
 

	
 
/* static */ const char *AICargo::GetCargoLabel(CargoID cargo_type)
 
{
 
	if (!IsValidCargo(cargo_type)) return NULL;
 
	const CargoSpec *cargo = ::GetCargo(cargo_type);
 

	
 
	/* cargo->label is a uint32 packing a 4 character non-terminated string,
 
	 * like "PASS", "COAL", "OIL_". New ones can be defined by NewGRFs */
 
	char *cargo_label = MallocT<char>(sizeof(cargo->label) + 1);
 
	for (uint i = 0; i < sizeof(cargo->label); i++) {
 
		cargo_label[i] = GB(cargo->label, (uint8)(sizeof(cargo->label) - i - 1) * 8, 8);
 
	}
 
	cargo_label[sizeof(cargo->label)] = '\0';
 
	return cargo_label;
 
}
 

	
 
/* static */ bool AICargo::IsFreight(CargoID cargo_type)
 
{
 
	if (!IsValidCargo(cargo_type)) return false;
 
	const CargoSpec *cargo = ::GetCargo(cargo_type);
 
	return cargo->is_freight;
 
}
 

	
 
/* static */ bool AICargo::HasCargoClass(CargoID cargo_type, CargoClass cargo_class)
 
{
 
	if (!IsValidCargo(cargo_type)) return false;
 
	return ::IsCargoInClass(cargo_type, (::CargoClass)cargo_class);
 
}
 

	
 
/* static */ AICargo::TownEffect AICargo::GetTownEffect(CargoID cargo_type)
 
{
 
	if (!IsValidCargo(cargo_type)) return TE_NONE;
 

	
 
	return (AICargo::TownEffect)GetCargo(cargo_type)->town_effect;
 
}
 

	
 
/* static */ Money AICargo::GetCargoIncome(CargoID cargo_type, uint32 distance, uint32 days_in_transit)
 
{
 
	if (!IsValidCargo(cargo_type)) return -1;
 
	return ::GetTransportedGoodsIncome(1, distance, Clamp(days_in_transit * 2 / 5, 0, 255), cargo_type);
 
}
src/ai/api/ai_cargo.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_cargo.hpp Everything to query cargos. */
 

	
 
#ifndef AI_CARGO_HPP
 
#define AI_CARGO_HPP
 

	
 
#include "ai_object.hpp"
 

	
 
/**
 
 * Class that handles all cargo related functions.
 
 */
 
class AICargo : public AIObject {
 
public:
 
	static const char *GetClassName() { return "AICargo"; }
 

	
 
	/**
 
	 * The classes of cargo (from newgrf_cargo.h).
 
	 */
 
	enum CargoClass {
 
		CC_PASSENGERS   = 1 <<  0, ///< Passengers
 
		CC_MAIL         = 1 <<  1, ///< Mail
 
		CC_EXPRESS      = 1 <<  2, ///< Express cargo (Goods, Food, Candy, but also possible for passengers)
 
		CC_ARMOURED     = 1 <<  3, ///< Armoured cargo (Valuables, Gold, Diamonds)
 
		CC_BULK         = 1 <<  4, ///< Bulk cargo (Coal, Grain etc., Ores, Fruit)
 
		CC_PIECE_GOODS  = 1 <<  5, ///< Piece goods (Livestock, Wood, Steel, Paper)
 
		CC_LIQUID       = 1 <<  6, ///< Liquids (Oil, Water, Rubber)
 
		CC_REFRIGERATED = 1 <<  7, ///< Refrigerated cargo (Food, Fruit)
 
		CC_HAZARDOUS    = 1 <<  8, ///< Hazardous cargo (Nuclear Fuel, Explosives, etc.)
 
		CC_COVERED      = 1 <<  9, ///< Covered/Sheltered Freight (Transporation in Box Vans, Silo Wagons, etc.)
 
	};
 

	
 
	/**
 
	 * The effects a cargo can have on a town.
 
	 */
 
	enum TownEffect {
 
		TE_NONE       = 0, ///< This cargo has no effect on a town
 
		TE_PASSENGERS = 1, ///< This cargo supplies passengers to a town
 
		TE_MAIL       = 2, ///< This cargo supplies mail to a town
 
		TE_GOODS      = 3, ///< This cargo supplies goods to a town
 
		TE_WATER      = 4, ///< This cargo supplies water to a town
 
		TE_FOOD       = 5, ///< This cargo supplies food to a town
 
	};
 

	
 
	/**
 
	 * Checks whether the given cargo type is valid.
 
	 * @param cargo_type The cargo to check.
 
	 * @return True if and only if the cargo type is valid.
 
	 */
 
	static bool IsValidCargo(CargoID cargo_type);
 

	
 
	/**
 
	 * Gets the string representation of the cargo label.
 
	 * @param cargo_type The cargo to get the string representation of.
 
	 * @return The cargo label.
 
	 * @note Never use this to check if it is a certain cargo. NewGRF can
 
	 *  redefine all of the names.
 
	 */
 
	static const char *GetCargoLabel(CargoID cargo_type);
 

	
 
	/**
 
	 * Checks whether the give cargo is a freight or not.
 
	 * @param cargo_type The cargo to check on.
 
	 * @return True if and only if the cargo is freight.
 
	 */
 
	static bool IsFreight(CargoID cargo_type);
 

	
 
	/**
 
	 * Check if this cargo is in the requested cargo class.
 
	 * @param cargo_type The cargo to check on.
 
	 * @param cargo_class The class to check for.
 
	 * @return True if and only if the cargo is in the cargo class.
 
	 */
 
	static bool HasCargoClass(CargoID cargo_type, CargoClass cargo_class);
 

	
 
	/**
 
	 * Get the effect this cargo has on a town.
 
	 * @param cargo_type The cargo to check on.
 
	 * @return The effect this cargo has on a town, or TE_NONE if it has no effect.
 
	 */
 
	static TownEffect GetTownEffect(CargoID cargo_type);
 

	
 
	/**
 
	 * Get the income for transporting a piece of cargo over the
 
	 *   given distance within the specified time.
 
	 * @param cargo_type The cargo to transport.
 
	 * @param distance The distance the cargo travels from begin to end.
 
	 * @param days_in_transit Amount of (game) days the cargo is in transit. The max value of this variable is 637. Any value higher returns the same as 637 would.
 
	 * @return The amount of money that would be earned by this trip.
 
	 */
 
	static Money GetCargoIncome(CargoID cargo_type, uint32 distance, uint32 days_in_transit);
 
};
 

	
 
#endif /* AI_CARGO_HPP */
src/ai/api/ai_cargo.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_cargo.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow enums to be used as Squirrel parameters */
 
	template <> AICargo::CargoClass GetParam(ForceType<AICargo::CargoClass>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AICargo::CargoClass)tmp; }
 
	template <> int Return<AICargo::CargoClass>(HSQUIRRELVM vm, AICargo::CargoClass res) { sq_pushinteger(vm, (int32)res); return 1; }
 
	template <> AICargo::TownEffect GetParam(ForceType<AICargo::TownEffect>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AICargo::TownEffect)tmp; }
 
	template <> int Return<AICargo::TownEffect>(HSQUIRRELVM vm, AICargo::TownEffect res) { sq_pushinteger(vm, (int32)res); return 1; }
 

	
 
	/* Allow AICargo to be used as Squirrel parameter */
 
	template <> AICargo *GetParam(ForceType<AICargo *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AICargo *)instance; }
 
	template <> AICargo &GetParam(ForceType<AICargo &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AICargo *)instance; }
 
	template <> const AICargo *GetParam(ForceType<const AICargo *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AICargo *)instance; }
 
	template <> const AICargo &GetParam(ForceType<const AICargo &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AICargo *)instance; }
 
	template <> int Return<AICargo *>(HSQUIRRELVM vm, AICargo *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AICargo", res, NULL, DefSQDestructorCallback<AICargo>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAICargo_Register(Squirrel *engine) {
 
	DefSQClass <AICargo> SQAICargo("AICargo");
 
	SQAICargo.PreRegister(engine);
 
	SQAICargo.AddConstructor<void (AICargo::*)(), 1>(engine, "x");
 

	
 
	SQAICargo.DefSQConst(engine, AICargo::CC_PASSENGERS,   "CC_PASSENGERS");
 
	SQAICargo.DefSQConst(engine, AICargo::CC_MAIL,         "CC_MAIL");
 
	SQAICargo.DefSQConst(engine, AICargo::CC_EXPRESS,      "CC_EXPRESS");
 
	SQAICargo.DefSQConst(engine, AICargo::CC_ARMOURED,     "CC_ARMOURED");
 
	SQAICargo.DefSQConst(engine, AICargo::CC_BULK,         "CC_BULK");
 
	SQAICargo.DefSQConst(engine, AICargo::CC_PIECE_GOODS,  "CC_PIECE_GOODS");
 
	SQAICargo.DefSQConst(engine, AICargo::CC_LIQUID,       "CC_LIQUID");
 
	SQAICargo.DefSQConst(engine, AICargo::CC_REFRIGERATED, "CC_REFRIGERATED");
 
	SQAICargo.DefSQConst(engine, AICargo::CC_HAZARDOUS,    "CC_HAZARDOUS");
 
	SQAICargo.DefSQConst(engine, AICargo::CC_COVERED,      "CC_COVERED");
 
	SQAICargo.DefSQConst(engine, AICargo::TE_NONE,         "TE_NONE");
 
	SQAICargo.DefSQConst(engine, AICargo::TE_PASSENGERS,   "TE_PASSENGERS");
 
	SQAICargo.DefSQConst(engine, AICargo::TE_MAIL,         "TE_MAIL");
 
	SQAICargo.DefSQConst(engine, AICargo::TE_GOODS,        "TE_GOODS");
 
	SQAICargo.DefSQConst(engine, AICargo::TE_WATER,        "TE_WATER");
 
	SQAICargo.DefSQConst(engine, AICargo::TE_FOOD,         "TE_FOOD");
 

	
 
	SQAICargo.DefSQStaticMethod(engine, &AICargo::GetClassName,   "GetClassName",   1, "x");
 
	SQAICargo.DefSQStaticMethod(engine, &AICargo::IsValidCargo,   "IsValidCargo",   2, "xi");
 
	SQAICargo.DefSQStaticMethod(engine, &AICargo::GetCargoLabel,  "GetCargoLabel",  2, "xi");
 
	SQAICargo.DefSQStaticMethod(engine, &AICargo::IsFreight,      "IsFreight",      2, "xi");
 
	SQAICargo.DefSQStaticMethod(engine, &AICargo::HasCargoClass,  "HasCargoClass",  3, "xii");
 
	SQAICargo.DefSQStaticMethod(engine, &AICargo::GetTownEffect,  "GetTownEffect",  2, "xi");
 
	SQAICargo.DefSQStaticMethod(engine, &AICargo::GetCargoIncome, "GetCargoIncome", 4, "xiii");
 

	
 
	SQAICargo.PostRegister(engine);
 
}
src/ai/api/ai_cargolist.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_cargolist.cpp Implementation of AICargoList and friends. */
 

	
 
#include "ai_cargolist.hpp"
 
#include "ai_industry.hpp"
 
#include "../../openttd.h"
 
#include "../../cargotype.h"
 
#include "../../tile_type.h"
 
#include "../../industry.h"
 

	
 
AICargoList::AICargoList()
 
{
 
	for (byte i = 0; i < NUM_CARGO; i++) {
 
		const CargoSpec *c = ::GetCargo(i);
 
		if (c->IsValid()) {
 
			this->AddItem(i);
 
		}
 
	}
 
}
 

	
 
AICargoList_IndustryAccepting::AICargoList_IndustryAccepting(IndustryID industry_id)
 
{
 
	if (!AIIndustry::IsValidIndustry(industry_id)) return;
 

	
 
	Industry *ind = ::GetIndustry(industry_id);
 
	for (uint i = 0; i < lengthof(ind->accepts_cargo); i++) {
 
		CargoID cargo_id = ind->accepts_cargo[i];
 
		if (cargo_id != CT_INVALID) {
 
			this->AddItem(cargo_id);
 
		}
 
	}
 
}
 

	
 
AICargoList_IndustryProducing::AICargoList_IndustryProducing(IndustryID industry_id)
 
{
 
	if (!AIIndustry::IsValidIndustry(industry_id)) return;
 

	
 
	Industry *ind = ::GetIndustry(industry_id);
 
	for (uint i = 0; i < lengthof(ind->produced_cargo); i++) {
 
		CargoID cargo_id = ind->produced_cargo[i];
 
		if (cargo_id != CT_INVALID) {
 
			this->AddItem(cargo_id);
 
		}
 
	}
 
}
src/ai/api/ai_cargolist.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_cargolist.hpp List all the cargos. */
 

	
 
#ifndef AI_CARGOLIST_HPP
 
#define AI_CARGOLIST_HPP
 

	
 
#include "ai_abstractlist.hpp"
 

	
 
/**
 
 * Creates a list of cargos that can be produced in the current game.
 
 * @ingroup AIList
 
 */
 
class AICargoList : public AIAbstractList {
 
public:
 
	static const char *GetClassName() { return "AICargoList"; }
 
	AICargoList();
 
};
 

	
 
/**
 
 * Creates a list of cargos that the given industry accepts.
 
 * @ingroup AIList
 
 */
 
class AICargoList_IndustryAccepting : public AIAbstractList {
 
public:
 
	static const char *GetClassName() { return "AICargoList_IndustryAccepting"; }
 

	
 
	/**
 
	 * @param industry_id The industry to get the list of cargos it accepts from.
 
	 */
 
	AICargoList_IndustryAccepting(IndustryID industry_id);
 
};
 

	
 
/**
 
 * Creates a list of cargos that the given industry can produce.
 
 * @ingroup AIList
 
 */
 
class AICargoList_IndustryProducing : public AIAbstractList {
 
public:
 
	static const char *GetClassName() { return "AICargoList_IndustryProducing"; }
 

	
 
	/**
 
	 * @param industry_id The industry to get the list of cargos it produces from.
 
	 */
 
	AICargoList_IndustryProducing(IndustryID industry_id);
 
};
 

	
 
#endif /* AI_CARGOLIST_HPP */
src/ai/api/ai_cargolist.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_cargolist.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow AICargoList to be used as Squirrel parameter */
 
	template <> AICargoList *GetParam(ForceType<AICargoList *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AICargoList *)instance; }
 
	template <> AICargoList &GetParam(ForceType<AICargoList &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AICargoList *)instance; }
 
	template <> const AICargoList *GetParam(ForceType<const AICargoList *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AICargoList *)instance; }
 
	template <> const AICargoList &GetParam(ForceType<const AICargoList &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AICargoList *)instance; }
 
	template <> int Return<AICargoList *>(HSQUIRRELVM vm, AICargoList *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AICargoList", res, NULL, DefSQDestructorCallback<AICargoList>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAICargoList_Register(Squirrel *engine) {
 
	DefSQClass <AICargoList> SQAICargoList("AICargoList");
 
	SQAICargoList.PreRegister(engine, "AIAbstractList");
 
	SQAICargoList.AddConstructor<void (AICargoList::*)(), 1>(engine, "x");
 

	
 
	SQAICargoList.DefSQStaticMethod(engine, &AICargoList::GetClassName, "GetClassName", 1, "x");
 

	
 
	SQAICargoList.PostRegister(engine);
 
}
 

	
 
namespace SQConvert {
 
	/* Allow AICargoList_IndustryAccepting to be used as Squirrel parameter */
 
	template <> AICargoList_IndustryAccepting *GetParam(ForceType<AICargoList_IndustryAccepting *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AICargoList_IndustryAccepting *)instance; }
 
	template <> AICargoList_IndustryAccepting &GetParam(ForceType<AICargoList_IndustryAccepting &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AICargoList_IndustryAccepting *)instance; }
 
	template <> const AICargoList_IndustryAccepting *GetParam(ForceType<const AICargoList_IndustryAccepting *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AICargoList_IndustryAccepting *)instance; }
 
	template <> const AICargoList_IndustryAccepting &GetParam(ForceType<const AICargoList_IndustryAccepting &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AICargoList_IndustryAccepting *)instance; }
 
	template <> int Return<AICargoList_IndustryAccepting *>(HSQUIRRELVM vm, AICargoList_IndustryAccepting *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AICargoList_IndustryAccepting", res, NULL, DefSQDestructorCallback<AICargoList_IndustryAccepting>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAICargoList_IndustryAccepting_Register(Squirrel *engine) {
 
	DefSQClass <AICargoList_IndustryAccepting> SQAICargoList_IndustryAccepting("AICargoList_IndustryAccepting");
 
	SQAICargoList_IndustryAccepting.PreRegister(engine, "AIAbstractList");
 
	SQAICargoList_IndustryAccepting.AddConstructor<void (AICargoList_IndustryAccepting::*)(IndustryID industry_id), 2>(engine, "xi");
 

	
 
	SQAICargoList_IndustryAccepting.DefSQStaticMethod(engine, &AICargoList_IndustryAccepting::GetClassName, "GetClassName", 1, "x");
 

	
 
	SQAICargoList_IndustryAccepting.PostRegister(engine);
 
}
 

	
 
namespace SQConvert {
 
	/* Allow AICargoList_IndustryProducing to be used as Squirrel parameter */
 
	template <> AICargoList_IndustryProducing *GetParam(ForceType<AICargoList_IndustryProducing *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AICargoList_IndustryProducing *)instance; }
 
	template <> AICargoList_IndustryProducing &GetParam(ForceType<AICargoList_IndustryProducing &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AICargoList_IndustryProducing *)instance; }
 
	template <> const AICargoList_IndustryProducing *GetParam(ForceType<const AICargoList_IndustryProducing *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AICargoList_IndustryProducing *)instance; }
 
	template <> const AICargoList_IndustryProducing &GetParam(ForceType<const AICargoList_IndustryProducing &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AICargoList_IndustryProducing *)instance; }
 
	template <> int Return<AICargoList_IndustryProducing *>(HSQUIRRELVM vm, AICargoList_IndustryProducing *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AICargoList_IndustryProducing", res, NULL, DefSQDestructorCallback<AICargoList_IndustryProducing>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAICargoList_IndustryProducing_Register(Squirrel *engine) {
 
	DefSQClass <AICargoList_IndustryProducing> SQAICargoList_IndustryProducing("AICargoList_IndustryProducing");
 
	SQAICargoList_IndustryProducing.PreRegister(engine, "AIAbstractList");
 
	SQAICargoList_IndustryProducing.AddConstructor<void (AICargoList_IndustryProducing::*)(IndustryID industry_id), 2>(engine, "xi");
 

	
 
	SQAICargoList_IndustryProducing.DefSQStaticMethod(engine, &AICargoList_IndustryProducing::GetClassName, "GetClassName", 1, "x");
 

	
 
	SQAICargoList_IndustryProducing.PostRegister(engine);
 
}
src/ai/api/ai_company.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_company.cpp Implementation of AICompany. */
 

	
 
#include "ai_company.hpp"
 
#include "ai_error.hpp"
 
#include "ai_log.hpp"
 
#include "../../openttd.h"
 
#include "../../command_func.h"
 
#include "../../company_func.h"
 
#include "../../company_base.h"
 
#include "../../economy_func.h"
 
#include "../../strings_func.h"
 
#include "../../tile_map.h"
 
#include "../../variables.h"
 
#include "../../core/alloc_func.hpp"
 
#include "../../string_func.h"
 
#include "table/strings.h"
 

	
 
/* static */ AICompany::CompanyID AICompany::ResolveCompanyID(AICompany::CompanyID company)
 
{
 
	if (company == MY_COMPANY) return (CompanyID)((byte)_current_company);
 

	
 
	return ::IsValidCompanyID((::CompanyID)company) ? company : INVALID_COMPANY;
 
}
 

	
 
/* static */ bool AICompany::IsMine(AICompany::CompanyID company)
 
{
 
	return ResolveCompanyID(company) == ResolveCompanyID(MY_COMPANY);
 
}
 

	
 
/* static */ bool AICompany::SetCompanyName(const char *name)
 
{
 
	AILog::Error("AICompany::SetCompanyName is obsolete. Use AICompany::SetName instead.");
 
	return AICompany::SetName(name);
 
}
 

	
 
/* static */ bool AICompany::SetName(const char *name)
 
{
 
	EnforcePrecondition(false, !::StrEmpty(name));
 
	EnforcePreconditionCustomError(false, ::strlen(name) < MAX_LENGTH_COMPANY_NAME_BYTES, AIError::ERR_PRECONDITION_STRING_TOO_LONG);
 

	
 
	return AIObject::DoCommand(0, 0, 0, CMD_RENAME_COMPANY, name);
 
}
 

	
 
/* static */ const char *AICompany::GetCompanyName(AICompany::CompanyID company)
 
{
 
	AILog::Error("AICompany::GetCompanyName is obsolete. Use AICompany::GetName instead.");
 
	return AICompany::GetName(company);
 
}
 

	
 
/* static */ const char *AICompany::GetName(AICompany::CompanyID company)
 
{
 
	company = ResolveCompanyID(company);
 
	if (company == INVALID_COMPANY) return NULL;
 

	
 
	static const int len = 64;
 
	char *company_name = MallocT<char>(len);
 

	
 
	::SetDParam(0, company);
 
	::GetString(company_name, STR_COMPANY_NAME, &company_name[len - 1]);
 
	return company_name;
 
}
 

	
 
/* static */ bool AICompany::SetPresidentName(const char *name)
 
{
 
	EnforcePrecondition(false, !::StrEmpty(name));
 

	
 
	return AIObject::DoCommand(0, 0, 0, CMD_RENAME_PRESIDENT, name);
 
}
 

	
 
/* static */ const char *AICompany::GetPresidentName(AICompany::CompanyID company)
 
{
 
	company = ResolveCompanyID(company);
 

	
 
	static const int len = 64;
 
	char *president_name = MallocT<char>(len);
 
	if (company != INVALID_COMPANY) {
 
		::SetDParam(0, company);
 
		::GetString(president_name, STR_PRESIDENT_NAME, &president_name[len - 1]);
 
	} else {
 
		*president_name = '\0';
 
	}
 

	
 
	return president_name;
 
}
 

	
 
/* static */ Money AICompany::GetCompanyValue(AICompany::CompanyID company)
 
{
 
	company = ResolveCompanyID(company);
 
	if (company == INVALID_COMPANY) return -1;
 

	
 
	return ::CalculateCompanyValue(::GetCompany((CompanyID)company));
 
}
 

	
 
/* static */ Money AICompany::GetBankBalance(AICompany::CompanyID company)
 
{
 
	company = ResolveCompanyID(company);
 
	if (company == INVALID_COMPANY) return -1;
 

	
 
	return ::GetCompany((CompanyID)company)->money;
 
}
 

	
 
/* static */ Money AICompany::GetLoanAmount()
 
{
 
	return ::GetCompany(_current_company)->current_loan;
 
}
 

	
 
/* static */ Money AICompany::GetMaxLoanAmount()
 
{
 
	return _economy.max_loan;
 
}
 

	
 
/* static */ Money AICompany::GetLoanInterval()
 
{
 
	return LOAN_INTERVAL;
 
}
 

	
 
/* static */ bool AICompany::SetLoanAmount(int32 loan)
 
{
 
	EnforcePrecondition(false, loan >= 0);
 
	EnforcePrecondition(false, (loan % GetLoanInterval()) == 0);
 
	EnforcePrecondition(false, loan <= GetMaxLoanAmount());
 
	EnforcePrecondition(false, (loan - GetLoanAmount() + GetBankBalance(MY_COMPANY)) >= 0);
 

	
 
	if (loan == GetLoanAmount()) return true;
 

	
 
	return AIObject::DoCommand(0,
 
			abs(loan - GetLoanAmount()), 2,
 
			(loan > GetLoanAmount()) ? CMD_INCREASE_LOAN : CMD_DECREASE_LOAN);
 
}
 

	
 
/* static */ bool AICompany::SetMinimumLoanAmount(int32 loan)
 
{
 
	EnforcePrecondition(false, loan >= 0);
 

	
 
	int32 over_interval = loan % GetLoanInterval();
 
	if (over_interval != 0) loan += GetLoanInterval() - over_interval;
 

	
 
	EnforcePrecondition(false, loan <= GetMaxLoanAmount());
 

	
 
	SetLoanAmount(loan);
 

	
 
	return GetLoanAmount() == loan;
 
}
 

	
 
/* static */ bool AICompany::BuildCompanyHQ(TileIndex tile)
 
{
 
	EnforcePrecondition(false, ::IsValidTile(tile));
 

	
 
	return AIObject::DoCommand(tile, 0, 0, CMD_BUILD_COMPANY_HQ);
 
}
 

	
 
/* static */ TileIndex AICompany::GetCompanyHQ(CompanyID company)
 
{
 
	company = ResolveCompanyID(company);
 
	if (company == INVALID_COMPANY) return INVALID_TILE;
 

	
 
	TileIndex loc = ::GetCompany((CompanyID)company)->location_of_HQ;
 
	return (loc == 0) ? INVALID_TILE : loc;
 
}
 

	
 
/* static */ bool AICompany::SetAutoRenewStatus(bool autorenew)
 
{
 
	return AIObject::DoCommand(0, 0, autorenew ? 1 : 0, CMD_SET_AUTOREPLACE);
 
}
 

	
 
/* static */ bool AICompany::GetAutoRenewStatus(CompanyID company)
 
{
 
	company = ResolveCompanyID(company);
 
	if (company == INVALID_COMPANY) return false;
 

	
 
	return ::GetCompany((CompanyID)company)->engine_renew;
 
}
 

	
 
/* static */ bool AICompany::SetAutoRenewMonths(int16 months)
 
{
 
	return AIObject::DoCommand(0, 1, months, CMD_SET_AUTOREPLACE);
 
}
 

	
 
/* static */ int16 AICompany::GetAutoRenewMonths(CompanyID company)
 
{
 
	company = ResolveCompanyID(company);
 
	if (company == INVALID_COMPANY) return 0;
 

	
 
	return ::GetCompany((CompanyID)company)->engine_renew_months;
 
}
 

	
 
/* static */ bool AICompany::SetAutoRenewMoney(uint32 money)
 
{
 
	return AIObject::DoCommand(0, 2, money, CMD_SET_AUTOREPLACE);
 
}
 

	
 
/* static */ uint32 AICompany::GetAutoRenewMoney(CompanyID company)
 
{
 
	company = ResolveCompanyID(company);
 
	if (company == INVALID_COMPANY) return 0;
 

	
 
	return ::GetCompany((CompanyID)company)->engine_renew_money;
 
}
src/ai/api/ai_company.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_company.hpp Everything to query a company's financials and statistics or build company related buildings. */
 

	
 
#ifndef AI_COMPANY_HPP
 
#define AI_COMPANY_HPP
 

	
 
#include "ai_object.hpp"
 

	
 
/**
 
 * Class that handles all company related functions.
 
 */
 
class AICompany : public AIObject {
 
public:
 
	static const char *GetClassName() { return "AICompany"; }
 

	
 
	/** Different constants related to CompanyID. */
 
	enum CompanyID {
 
		INVALID_COMPANY = -1, //!< An invalid company.
 
		FIRST_COMPANY   = 0, //!< The first available company.
 
		LAST_COMPANY    = 7, //!< The last available company.
 
		MY_COMPANY      = 8, //!< Constant that gets resolved to the correct company index for your company.
 
	};
 

	
 
	/**
 
	 * Resolved the given company index to the correct index for the company. If
 
	 *  the company index was MY_COMPANY it will be resolved to the index of
 
	 *  your company. If the company with the given index does not exist it will
 
	 *  return INVALID_COMPANY.
 
	 * @param company The company index to resolve.
 
	 * @return The resolved company index.
 
	 */
 
	static CompanyID ResolveCompanyID(CompanyID company);
 

	
 
	/**
 
	 * Check if a CompanyID is your CompanyID, to ease up checks.
 
	 * @param company The company index to check.
 
	 * @return True if and only if this company is your CompanyID.
 
	 */
 
	static bool IsMine(CompanyID company);
 

	
 
	/**
 
	 * Obsolete, use AICompany::SetName instead.
 
	 */
 
	static bool SetCompanyName(const char *name);
 

	
 
	/**
 
	 * Set the name of your company.
 
	 * @param name The new name of the company.
 
	 * @pre 'name' must have at least one character.
 
	 * @pre 'name' must have at most 30 characters.
 
	 * @exception AIError::ERR_NAME_IS_NOT_UNIQUE
 
	 * @return True if the name was changed.
 
	 */
 
	static bool SetName(const char *name);
 

	
 
	/**
 
	 * Obsolete, use AICompany::GetName instead.
 
	 */
 
	static const char *GetCompanyName(CompanyID company);
 

	
 
	/**
 
	 * Get the name of the given company.
 
	 * @param company The company to get the name for.
 
	 * @pre ResolveCompanyID(company) != INVALID_COMPANY
 
	 * @return The name of the given company.
 
	 */
 
	static const char *GetName(CompanyID company);
 

	
 
	/**
 
	 * Set the name of your president.
 
	 * @param name The new name of the president.
 
	 * @pre 'name' must have at least one character.
 
	 * @exception AIError::ERR_NAME_IS_NOT_UNIQUE
 
	 * @return True if the name was changed.
 
	 */
 
	static bool SetPresidentName(const char *name);
 

	
 
	/**
 
	 * Get the name of the president of the given company.
 
	 * @param company The company to get the president's name for.
 
	 * @pre ResolveCompanyID(company) != INVALID_COMPANY
 
	 * @return The name of the president of the given company.
 
	 */
 
	static const char *GetPresidentName(CompanyID company);
 

	
 
	/**
 
	 * Sets the amount to loan.
 
	 * @param loan The amount to loan (multiplier of GetLoanInterval()).
 
	 * @pre 'loan' must be non-negative.
 
	 * @pre GetLoanInterval() must be a multiplier of GetLoanInterval().
 
	 * @pre 'loan' must be below GetMaxLoanAmount().
 
	 * @pre 'loan' - GetLoanAmount() + GetBankBalance() must be non-negative.
 
	 * @return True if the loan could be set to your requested amount.
 
	 */
 
	static bool SetLoanAmount(int32 loan);
 

	
 
	/**
 
	 * Sets the minimum amount to loan, i.e. the given amount of loan rounded up.
 
	 * @param loan The amount to loan (any positive number).
 
	 * @pre 'loan' must be non-negative.
 
	 * @pre 'loan' must be below GetMaxLoanAmount().
 
	 * @return True if we could allocate a minimum of "loan" loan.
 
	 */
 
	static bool SetMinimumLoanAmount(int32 loan);
 

	
 
	/**
 
	 * Gets the amount your company have loaned.
 
	 * @return The amount loaned money.
 
	 * @post The return value is always non-negative.
 
	 * @post GetLoanInterval() is always a multiplier of the return value.
 
	 */
 
	static Money GetLoanAmount();
 

	
 
	/**
 
	 * Gets the maximum amount your company can loan.
 
	 * @return The maximum amount your company can loan.
 
	 * @post The return value is always non-negative.
 
	 * @post GetLoanInterval() is always a multiplier of the return value.
 
	 */
 
	static Money GetMaxLoanAmount();
 

	
 
	/**
 
	 * Gets the interval/loan step.
 
	 * @return The loan step.
 
	 * @post Return value is always positive.
 
	 */
 
	static Money GetLoanInterval();
 

	
 
	/**
 
	 * Gets the current value of the given company.
 
	 * @param company The company to get the company value of.
 
	 * @pre ResolveCompanyID(company) != INVALID_COMPANY
 
	 * @return The current value of the given company.
 
	 */
 
	static Money GetCompanyValue(CompanyID company);
 

	
 
	/**
 
	 * Gets the bank balance. In other words, the amount of money the given company can spent.
 
	 * @param company The company to get the bank balance of.
 
	 * @pre ResolveCompanyID(company) != INVALID_COMPANY
 
	 * @return The actual bank balance.
 
	 */
 
	static Money GetBankBalance(CompanyID company);
 

	
 
	/**
 
	 * Build your company's HQ on the given tile.
 
	 * @param tile The tile to build your HQ on, this tile is the most nothern tile of your HQ.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @exception AIError::ERR_AREA_NOT_CLEAR
 
	 * @exception AIError::ERR_FLAT_LAND_REQUIRED
 
	 * @return True if the HQ could be build.
 
	 * @note An HQ can not be removed, only by water or rebuilding; If an HQ is
 
	 *  build again, the old one is removed.
 
	 */
 
	static bool BuildCompanyHQ(TileIndex tile);
 

	
 
	/**
 
	 * Return the location of a company's HQ.
 
	 * @param company The company the get the HQ of.
 
	 * @pre ResolveCompanyID(company) != INVALID_COMPANY.
 
	 * @return The tile of the company's HQ, this tile is the most nothern tile of that HQ, or INVALID_TILE if there is no HQ yet.
 
	 */
 
	static TileIndex GetCompanyHQ(CompanyID company);
 

	
 
	/**
 
	 * Set whether autorenew is enabled for your company.
 
	 * @param autorenew The new autorenew status.
 
	 * @return True if autorenew status has been modified.
 
	 */
 
	static bool SetAutoRenewStatus(bool autorenew);
 

	
 
	/**
 
	 * Return whether autorenew is enabled for a company.
 
	 * @param company The company to get the autorenew status of.
 
	 * @pre ResolveCompanyID(company) != INVALID_COMPANY.
 
	 * @return True if autorenew is enabled.
 
	 */
 
	static bool GetAutoRenewStatus(CompanyID company);
 

	
 
	/**
 
	 * Set the number of months before/after max age to autorenew an engine for your company.
 
	 * @param months The new months between autorenew.
 
	 * @return True if autorenew months has been modified.
 
	 */
 
	static bool SetAutoRenewMonths(int16 months);
 

	
 
	/**
 
	 * Return the number of months before/after max age to autorenew an engine for a company.
 
	 * @param company The company to get the autorenew months of.
 
	 * @pre ResolveCompanyID(company) != INVALID_COMPANY.
 
	 * @return The months before/after max age of engine.
 
	 */
 
	static int16 GetAutoRenewMonths(CompanyID company);
 

	
 
	/**
 
	 * Set the minimum money needed to autorenew an engine for your company.
 
	 * @param money The new minimum required money for autorenew to work.
 
	 * @return True if autorenew money has been modified.
 
	 */
 
	static bool SetAutoRenewMoney(uint32 money);
 

	
 
	/**
 
	 * Return the minimum money needed to autorenew an engine for a company.
 
	 * @param company The company to get the autorenew money of.
 
	 * @pre ResolveCompanyID(company) != INVALID_COMPANY.
 
	 * @return The minimum required money for autorenew to work.
 
	 */
 
	static uint32 GetAutoRenewMoney(CompanyID company);
 
};
 

	
 
DECLARE_POSTFIX_INCREMENT(AICompany::CompanyID);
 

	
 
#endif /* AI_COMPANY_HPP */
src/ai/api/ai_company.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_company.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow enums to be used as Squirrel parameters */
 
	template <> AICompany::CompanyID GetParam(ForceType<AICompany::CompanyID>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AICompany::CompanyID)tmp; }
 
	template <> int Return<AICompany::CompanyID>(HSQUIRRELVM vm, AICompany::CompanyID res) { sq_pushinteger(vm, (int32)res); return 1; }
 

	
 
	/* Allow AICompany to be used as Squirrel parameter */
 
	template <> AICompany *GetParam(ForceType<AICompany *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AICompany *)instance; }
 
	template <> AICompany &GetParam(ForceType<AICompany &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AICompany *)instance; }
 
	template <> const AICompany *GetParam(ForceType<const AICompany *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AICompany *)instance; }
 
	template <> const AICompany &GetParam(ForceType<const AICompany &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AICompany *)instance; }
 
	template <> int Return<AICompany *>(HSQUIRRELVM vm, AICompany *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AICompany", res, NULL, DefSQDestructorCallback<AICompany>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAICompany_Register(Squirrel *engine) {
 
	DefSQClass <AICompany> SQAICompany("AICompany");
 
	SQAICompany.PreRegister(engine);
 
	SQAICompany.AddConstructor<void (AICompany::*)(), 1>(engine, "x");
 

	
 
	SQAICompany.DefSQConst(engine, AICompany::INVALID_COMPANY, "INVALID_COMPANY");
 
	SQAICompany.DefSQConst(engine, AICompany::FIRST_COMPANY,   "FIRST_COMPANY");
 
	SQAICompany.DefSQConst(engine, AICompany::LAST_COMPANY,    "LAST_COMPANY");
 
	SQAICompany.DefSQConst(engine, AICompany::MY_COMPANY,      "MY_COMPANY");
 

	
 
	SQAICompany.DefSQStaticMethod(engine, &AICompany::GetClassName,         "GetClassName",         1, "x");
 
	SQAICompany.DefSQStaticMethod(engine, &AICompany::ResolveCompanyID,     "ResolveCompanyID",     2, "xi");
 
	SQAICompany.DefSQStaticMethod(engine, &AICompany::IsMine,               "IsMine",               2, "xi");
 
	SQAICompany.DefSQStaticMethod(engine, &AICompany::SetCompanyName,       "SetCompanyName",       2, "xs");
 
	SQAICompany.DefSQStaticMethod(engine, &AICompany::SetName,              "SetName",              2, "xs");
 
	SQAICompany.DefSQStaticMethod(engine, &AICompany::GetCompanyName,       "GetCompanyName",       2, "xi");
 
	SQAICompany.DefSQStaticMethod(engine, &AICompany::GetName,              "GetName",              2, "xi");
 
	SQAICompany.DefSQStaticMethod(engine, &AICompany::SetPresidentName,     "SetPresidentName",     2, "xs");
 
	SQAICompany.DefSQStaticMethod(engine, &AICompany::GetPresidentName,     "GetPresidentName",     2, "xi");
 
	SQAICompany.DefSQStaticMethod(engine, &AICompany::SetLoanAmount,        "SetLoanAmount",        2, "xi");
 
	SQAICompany.DefSQStaticMethod(engine, &AICompany::SetMinimumLoanAmount, "SetMinimumLoanAmount", 2, "xi");
 
	SQAICompany.DefSQStaticMethod(engine, &AICompany::GetLoanAmount,        "GetLoanAmount",        1, "x");
 
	SQAICompany.DefSQStaticMethod(engine, &AICompany::GetMaxLoanAmount,     "GetMaxLoanAmount",     1, "x");
 
	SQAICompany.DefSQStaticMethod(engine, &AICompany::GetLoanInterval,      "GetLoanInterval",      1, "x");
 
	SQAICompany.DefSQStaticMethod(engine, &AICompany::GetCompanyValue,      "GetCompanyValue",      2, "xi");
 
	SQAICompany.DefSQStaticMethod(engine, &AICompany::GetBankBalance,       "GetBankBalance",       2, "xi");
 
	SQAICompany.DefSQStaticMethod(engine, &AICompany::BuildCompanyHQ,       "BuildCompanyHQ",       2, "xi");
 
	SQAICompany.DefSQStaticMethod(engine, &AICompany::GetCompanyHQ,         "GetCompanyHQ",         2, "xi");
 
	SQAICompany.DefSQStaticMethod(engine, &AICompany::SetAutoRenewStatus,   "SetAutoRenewStatus",   2, "xb");
 
	SQAICompany.DefSQStaticMethod(engine, &AICompany::GetAutoRenewStatus,   "GetAutoRenewStatus",   2, "xi");
 
	SQAICompany.DefSQStaticMethod(engine, &AICompany::SetAutoRenewMonths,   "SetAutoRenewMonths",   2, "xi");
 
	SQAICompany.DefSQStaticMethod(engine, &AICompany::GetAutoRenewMonths,   "GetAutoRenewMonths",   2, "xi");
 
	SQAICompany.DefSQStaticMethod(engine, &AICompany::SetAutoRenewMoney,    "SetAutoRenewMoney",    2, "xi");
 
	SQAICompany.DefSQStaticMethod(engine, &AICompany::GetAutoRenewMoney,    "GetAutoRenewMoney",    2, "xi");
 

	
 
	SQAICompany.PostRegister(engine);
 
}
src/ai/api/ai_controller.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_controller.cpp Implementation of AIControler. */
 

	
 
#include "../../stdafx.h"
 
#include "../../openttd.h"
 
#include "../../company_func.h"
 
#include "../../core/alloc_func.hpp"
 
#include "../../string_func.h"
 
#include "../../settings_type.h"
 
#include "../../company_base.h"
 
#include "../../saveload/saveload.h"
 
#include "table/strings.h"
 

	
 
#include "../ai.hpp"
 
#include "ai_controller.hpp"
 
#include "../ai_info.hpp"
 
#include "../ai_storage.hpp"
 
#include "../ai_instance.hpp"
 
#include "../ai_config.hpp"
 
#include "ai_log.hpp"
 

	
 
/* static */ void AIController::SetCommandDelay(int ticks)
 
{
 
	if (ticks <= 0) return;
 
	AIObject::SetDoCommandDelay(ticks);
 
}
 

	
 
/* static */ void AIController::Sleep(int ticks)
 
{
 
	if (ticks <= 0) {
 
		AILog::Warning("Sleep() value should be > 0. Assuming value 1.");
 
		ticks = 1;
 
	}
 

	
 
	throw AI_VMSuspend(ticks, NULL);
 
}
 

	
 
/* static */ void AIController::Print(bool error_msg, const char *message)
 
{
 
	AILog::Log(error_msg ? AILog::LOG_SQ_ERROR : AILog::LOG_SQ_INFO, message);
 
}
 

	
 
AIController::AIController() :
 
	ticks(0),
 
	loaded_library_count(0)
 
{
 
}
 

	
 
AIController::~AIController()
 
{
 
	for (LoadedLibraryList::iterator iter = this->loaded_library.begin(); iter != this->loaded_library.end(); iter++) {
 
		free((void *)(*iter).second);
 
		free((void *)(*iter).first);
 
	}
 

	
 
	this->loaded_library.clear();
 
}
 

	
 
uint AIController::GetTick()
 
{
 
	return this->ticks;
 
}
 

	
 
int AIController::GetSetting(const char *name)
 
{
 
	return AIConfig::GetConfig(_current_company)->GetSetting(name);
 
}
 

	
 
bool AIController::LoadedLibrary(const char *library_name, int *next_number, char *fake_class_name, int fake_class_name_len)
 
{
 
	LoadedLibraryList::iterator iter = this->loaded_library.find(library_name);
 
	if (iter == this->loaded_library.end()) {
 
		*next_number = ++this->loaded_library_count;
 
		return false;
 
	}
 

	
 
	ttd_strlcpy(fake_class_name, (*iter).second, fake_class_name_len);
 
	return true;
 
}
 

	
 
void AIController::AddLoadedLibrary(const char *library_name, const char *fake_class_name)
 
{
 
	this->loaded_library[strdup(library_name)] = strdup(fake_class_name);
 
}
src/ai/api/ai_controller.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_controller.hpp The controller of the AI. */
 

	
 
#ifndef AI_CONTROLLER_HPP
 
#define AI_CONTROLLER_HPP
 

	
 
#include <map>
 
#ifndef AI_HPP
 
struct ltstr { bool operator()(const char *s1, const char *s2) const { return strcmp(s1, s2) < 0; } };
 
#endif /* AI_HPP */
 

	
 
/**
 
 * The Controller, the class each AI should extend. It creates the AI, makes
 
 *  sure the logic kicks in correctly, and that GetTick() has a valid value.
 
 */
 
class AIController {
 
	friend class AIScanner;
 
	friend class AIInstance;
 

	
 
public:
 
	static const char *GetClassName() { return "AIController"; }
 

	
 
	/**
 
	 * Initializer of the AIController.
 
	 */
 
	AIController();
 

	
 
	/**
 
	 * Destructor of the AIController.
 
	 */
 
	~AIController();
 

	
 
	/**
 
	 * This function is called to start your AI. Your AI starts here. If you
 
	 *   return from this function, your AI dies, so make sure that doesn't
 
	 *   happen.
 
	 * @note Cannot be called from within your AI.
 
	 */
 
	void Start();
 

	
 
	/**
 
	 * Find at which tick your AI currently is.
 
	 * @return returns the current tick.
 
	 */
 
	uint GetTick();
 

	
 
	/**
 
	 * Get the value of one of your settings you set via info.nut.
 
	 * @param name The name of the setting.
 
	 * @return the value for the setting, or -1 if the setting is not known.
 
	 */
 
	int GetSetting(const char *name);
 

	
 
	/**
 
	 * Change the minimum amount of time the AI should be put in suspend mode
 
	 *   when you execute a command. Normally in SP this is 1, and in MP it is
 
	 *   what ever delay the server has been programmed to delay commands
 
	 *   (normally between 1 and 5). To give a more 'real' effect to your AI,
 
	 *   you can control that number here.
 
	 * @param ticks The minimum amount of ticks to wait.
 
	 * @pre Ticks should be positive. Too big values will influence performance of the AI.
 
	 * @note If the number is lower then the MP setting, the MP setting wins.
 
	 */
 
	static void SetCommandDelay(int ticks);
 

	
 
	/**
 
	 * Sleep for X ticks. The code continues after this line when the X AI ticks
 
	 *   are passed. Mind that an AI tick is different from in-game ticks and
 
	 *   differ per AI speed.
 
	 * @param ticks the ticks to wait
 
	 * @pre ticks > 0.
 
	 * @post the value of GetTick() will be changed exactly 'ticks' in value after
 
	 *   calling this.
 
	 */
 
	static void Sleep(int ticks);
 

	
 
	/**
 
	 * When Squirrel triggers a print, this function is called.
 
	 *  Squirrel calls this when 'print' is used, or when the script made an error.
 
	 * @param error_msg If true, it is a Squirrel error message.
 
	 * @param message The message Squirrel logged.
 
	 * @note Use AILog.Info/Warning/Error instead of 'print'.
 
	 */
 
	static void Print(bool error_msg, const char *message);
 

	
 
private:
 
	typedef std::map<const char *, const char *, ltstr> LoadedLibraryList;
 

	
 
	uint ticks;
 
	LoadedLibraryList loaded_library;
 
	int loaded_library_count;
 

	
 
	/**
 
	 * Register all classes that are known inside the NoAI API.
 
	 */
 
	void RegisterClasses();
 

	
 
	/**
 
	 * Check if a library is already loaded. If found, fake_class_name is filled
 
	 *  with the fake class name as given via AddLoadedLibrary. If not found,
 
	 *  next_number is set to the next number available for the fake namespace.
 
	 * @param library_name The library to check if already loaded.
 
	 * @param next_number The next available number for a library if not already loaded.
 
	 * @param fake_class_name The name the library has if already loaded.
 
	 * @param fake_class_name_len The maximum length of fake_class_name.
 
	 * @return True if the library is already loaded.
 
	 */
 
	bool LoadedLibrary(const char *library_name, int *next_number, char *fake_class_name, int fake_class_name_len);
 

	
 
	/**
 
	 * Add a library as loaded.
 
	 */
 
	void AddLoadedLibrary(const char *library_name, const char *fake_class_name);
 
};
 

	
 
#endif /* AI_CONTROLLER_HPP */
src/ai/api/ai_controller.hpp.sq
Show inline comments
 
new file 100644
 
#include "ai_controller.hpp"
 

	
 
void SQAIController_Register(Squirrel *engine) {
 
	DefSQClass <AIController> SQAIController("AIController");
 
	SQAIController.PreRegister(engine);
 
	SQAIController.DefSQMethod(engine, &AIController::GetTick,               "GetTick",         1, "x");
 
	SQAIController.DefSQStaticMethod(engine, &AIController::SetCommandDelay, "SetCommandDelay", 2, "xi");
 
	SQAIController.DefSQStaticMethod(engine, &AIController::Sleep,           "Sleep",           2, "xi");
 
	SQAIController.DefSQStaticMethod(engine, &AIController::GetSetting,      "GetSetting",      2, "xs");
 
	SQAIController.DefSQStaticMethod(engine, &AIController::Print,           "Print",           3, "xbs");
 
	SQAIController.PostRegister(engine);
 
}
src/ai/api/ai_date.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_date.cpp Implementation of AIDate. */
 

	
 
#include "ai_date.hpp"
 
#include "../../date_func.h"
 

	
 
/* static */ int32 AIDate::GetCurrentDate()
 
{
 
	return ::_date;
 
}
 

	
 
/* static */ int32 AIDate::GetYear(int32 date)
 
{
 
	if (date < 0) return -1;
 

	
 
	::YearMonthDay ymd;
 
	::ConvertDateToYMD(date, &ymd);
 
	return ymd.year;
 
}
 

	
 
/* static */ int32 AIDate::GetMonth(int32 date)
 
{
 
	if (date < 0) return -1;
 

	
 
	::YearMonthDay ymd;
 
	::ConvertDateToYMD(date, &ymd);
 
	return ymd.month + 1;
 
}
 

	
 
/* static */ int32 AIDate::GetDayOfMonth(int32 date)
 
{
 
	if (date < 0) return -1;
 

	
 
	::YearMonthDay ymd;
 
	::ConvertDateToYMD(date, &ymd);
 
	return ymd.day;
 
}
 

	
 
/* static */ int32 AIDate::GetDate(int32 year, int32 month, int32 day_of_month)
 
{
 
	if (month < 1 || month > 12) return -1;
 
	if (day_of_month < 1 || day_of_month > 31) return -1;
 
	if (year < 0 || year > MAX_YEAR) return -1;
 

	
 
	return ::ConvertYMDToDate(year, month - 1, day_of_month);
 
}
src/ai/api/ai_date.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_date.hpp Everything to query and manipulate date related information. */
 

	
 
#ifndef AI_DATE_HPP
 
#define AI_DATE_HPP
 

	
 
#include "ai_object.hpp"
 

	
 
/**
 
 * Class that handles all date related (calculation) functions.
 
 *
 
 * @note Months and days of month are 1-based; the first month of the
 
 *       year is 1 and the first day of the month is also 1.
 
 * @note Years are zero based; they start with the year 0.
 
 * @note Dates can be used to determine the number of days between
 
 *       two different moments in time because they count the number
 
 *       of days since the year 0.
 
 */
 
class AIDate : public AIObject {
 
public:
 
	static const char *GetClassName() { return "AIDate"; }
 

	
 
	/**
 
	 * Get the current date.
 
	 * This is the number of days since epoch under the assumption that
 
	 *  there is a leap year every 4 years, except when dividable by
 
	 *  100 but not by 400.
 
	 * @return The current date.
 
	 */
 
	static int32 GetCurrentDate();
 

	
 
	/**
 
	 * Get the year of the given date.
 
	 * @param date The date to get the year of.
 
	 * @return The year.
 
	 */
 
	static int32 GetYear(int32 date);
 

	
 
	/**
 
	 * Get the month of the given date.
 
	 * @param date The date to get the month of.
 
	 * @return The month.
 
	 */
 
	static int32 GetMonth(int32 date);
 

	
 
	/**
 
	 * Get the day (of the month) of the given date.
 
	 * @param date The date to get the day of.
 
	 * @return The day.
 
	 */
 
	static int32 GetDayOfMonth(int32 date);
 

	
 
	/**
 
	 * Get the date given a year, month and day of month.
 
	 * @param year The year of the to-be determined date.
 
	 * @param month The month of the to-be determined date.
 
	 * @param day_of_month The day of month of the to-be determined date.
 
	 * @return The date.
 
	 */
 
	static int32 GetDate(int32 year, int32 month, int32 day_of_month);
 
};
 

	
 
#endif /* AI_DATE_HPP */
src/ai/api/ai_date.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_date.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow AIDate to be used as Squirrel parameter */
 
	template <> AIDate *GetParam(ForceType<AIDate *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIDate *)instance; }
 
	template <> AIDate &GetParam(ForceType<AIDate &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIDate *)instance; }
 
	template <> const AIDate *GetParam(ForceType<const AIDate *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIDate *)instance; }
 
	template <> const AIDate &GetParam(ForceType<const AIDate &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIDate *)instance; }
 
	template <> int Return<AIDate *>(HSQUIRRELVM vm, AIDate *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIDate", res, NULL, DefSQDestructorCallback<AIDate>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIDate_Register(Squirrel *engine) {
 
	DefSQClass <AIDate> SQAIDate("AIDate");
 
	SQAIDate.PreRegister(engine);
 
	SQAIDate.AddConstructor<void (AIDate::*)(), 1>(engine, "x");
 

	
 
	SQAIDate.DefSQStaticMethod(engine, &AIDate::GetClassName,   "GetClassName",   1, "x");
 
	SQAIDate.DefSQStaticMethod(engine, &AIDate::GetCurrentDate, "GetCurrentDate", 1, "x");
 
	SQAIDate.DefSQStaticMethod(engine, &AIDate::GetYear,        "GetYear",        2, "xi");
 
	SQAIDate.DefSQStaticMethod(engine, &AIDate::GetMonth,       "GetMonth",       2, "xi");
 
	SQAIDate.DefSQStaticMethod(engine, &AIDate::GetDayOfMonth,  "GetDayOfMonth",  2, "xi");
 
	SQAIDate.DefSQStaticMethod(engine, &AIDate::GetDate,        "GetDate",        4, "xiii");
 

	
 
	SQAIDate.PostRegister(engine);
 
}
src/ai/api/ai_depotlist.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_depotlist.cpp Implementation of AIDepotList and friends. */
 

	
 
#include "ai_depotlist.hpp"
 
#include "../../core/math_func.hpp"
 
#include "../../tile_map.h"
 
#include "../../company_func.h"
 
#include "../../depot_base.h"
 
#include "../../station_base.h"
 

	
 
AIDepotList::AIDepotList(AITile::TransportType transport_type)
 
{
 
	::TileType tile_type;
 
	switch (transport_type) {
 
		default: return;
 

	
 
		case AITile::TRANSPORT_ROAD:  tile_type = ::MP_ROAD; break;
 
		case AITile::TRANSPORT_RAIL:  tile_type = ::MP_RAILWAY; break;
 
		case AITile::TRANSPORT_WATER: tile_type = ::MP_WATER; break;
 

	
 
		case AITile::TRANSPORT_AIR: {
 
			/* Hangars are not seen as real depots by the depot code. */
 
			const Station *st;
 
			FOR_ALL_STATIONS(st) {
 
				if (st->owner == ::_current_company) {
 
					const AirportFTAClass *afc = st->Airport();
 
					for (uint i = 0; i < afc->nof_depots; i++) {
 
						this->AddItem(st->xy + ToTileIndexDiff(afc->airport_depots[i]));
 
					}
 
				}
 
			}
 
			return;
 
		}
 
	}
 

	
 
	/* Handle 'standard' depots. */
 
	const Depot *depot;
 
	FOR_ALL_DEPOTS(depot) {
 
		if (::GetTileOwner(depot->xy) == ::_current_company && ::IsTileType(depot->xy, tile_type)) this->AddItem(depot->xy);
 
	}
 
}
src/ai/api/ai_depotlist.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_depotlist.hpp List all the depots (you own). */
 

	
 
#ifndef AI_DEPOTLIST_HPP
 
#define AI_DEPOTLIST_HPP
 

	
 
#include "ai_abstractlist.hpp"
 
#include "ai_tile.hpp"
 

	
 
/**
 
 * Creates a list of the locations of the depots (and hangars) of which you are the owner.
 
 * @ingroup AIList
 
 */
 
class AIDepotList : public AIAbstractList {
 
public:
 
	static const char *GetClassName() { return "AIDepotList"; }
 

	
 
	/**
 
	 * @param transport_type The type of transport to make a list of depots for.
 
	 */
 
	AIDepotList(AITile::TransportType transport_type);
 
};
 

	
 
#endif /* AI_DEPOTLIST_HPP */
src/ai/api/ai_depotlist.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_depotlist.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow AIDepotList to be used as Squirrel parameter */
 
	template <> AIDepotList *GetParam(ForceType<AIDepotList *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIDepotList *)instance; }
 
	template <> AIDepotList &GetParam(ForceType<AIDepotList &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIDepotList *)instance; }
 
	template <> const AIDepotList *GetParam(ForceType<const AIDepotList *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIDepotList *)instance; }
 
	template <> const AIDepotList &GetParam(ForceType<const AIDepotList &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIDepotList *)instance; }
 
	template <> int Return<AIDepotList *>(HSQUIRRELVM vm, AIDepotList *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIDepotList", res, NULL, DefSQDestructorCallback<AIDepotList>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIDepotList_Register(Squirrel *engine) {
 
	DefSQClass <AIDepotList> SQAIDepotList("AIDepotList");
 
	SQAIDepotList.PreRegister(engine, "AIAbstractList");
 
	SQAIDepotList.AddConstructor<void (AIDepotList::*)(AITile::TransportType transport_type), 2>(engine, "xi");
 

	
 
	SQAIDepotList.DefSQStaticMethod(engine, &AIDepotList::GetClassName, "GetClassName", 1, "x");
 

	
 
	SQAIDepotList.PostRegister(engine);
 
}
src/ai/api/ai_engine.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_engine.cpp Implementation of AIEngine. */
 

	
 
#include "ai_engine.hpp"
 
#include "ai_cargo.hpp"
 
#include "ai_rail.hpp"
 
#include "../../openttd.h"
 
#include "../../company_func.h"
 
#include "../../strings_func.h"
 
#include "../../roadveh.h"
 
#include "../../train.h"
 
#include "../../ship.h"
 
#include "../../aircraft.h"
 
#include "../../vehicle_func.h"
 
#include "../../core/alloc_func.hpp"
 
#include "../../economy_func.h"
 
#include "../../core/bitmath_func.hpp"
 
#include "../../settings_type.h"
 
#include "../../articulated_vehicles.h"
 
#include "table/strings.h"
 

	
 
/* static */ bool AIEngine::IsValidEngine(EngineID engine_id)
 
{
 
	return ::IsEngineIndex(engine_id) && HasBit(::GetEngine(engine_id)->company_avail, _current_company);
 
}
 

	
 
/* static */ const char *AIEngine::GetName(EngineID engine_id)
 
{
 
	if (!IsValidEngine(engine_id)) return NULL;
 

	
 
	static const int len = 64;
 
	char *engine_name = MallocT<char>(len);
 

	
 
	::SetDParam(0, engine_id);
 
	::GetString(engine_name, STR_ENGINE_NAME, &engine_name[len - 1]);
 
	return engine_name;
 
}
 

	
 
/* static */ CargoID AIEngine::GetCargoType(EngineID engine_id)
 
{
 
	if (!IsValidEngine(engine_id)) return CT_INVALID;
 

	
 
	switch (::GetEngine(engine_id)->type) {
 
		case VEH_ROAD: {
 
			const RoadVehicleInfo *vi = ::RoadVehInfo(engine_id);
 
			return vi->cargo_type;
 
		} break;
 

	
 
		case VEH_TRAIN: {
 
			const RailVehicleInfo *vi = ::RailVehInfo(engine_id);
 
			return vi->cargo_type;
 
		} break;
 

	
 
		case VEH_SHIP: {
 
			const ShipVehicleInfo *vi = ::ShipVehInfo(engine_id);
 
			return vi->cargo_type;
 
		} break;
 

	
 
		case VEH_AIRCRAFT: {
 
			return CT_PASSENGERS;
 
		} break;
 

	
 
		default: NOT_REACHED();
 
	}
 
}
 

	
 
/* static */ bool AIEngine::CanRefitCargo(EngineID engine_id, CargoID cargo_id)
 
{
 
	if (!IsValidEngine(engine_id)) return false;
 
	if (!AICargo::IsValidCargo(cargo_id)) return false;
 

	
 
	if (GetCargoType(engine_id) == cargo_id) return true;
 
	if (cargo_id == CT_MAIL && ::GetEngine(engine_id)->type == VEH_AIRCRAFT) return true;
 
	if (::GetEngine(engine_id)->type == VEH_SHIP && !ShipVehInfo(engine_id)->refittable) return false;
 
	return ::CanRefitTo(engine_id, cargo_id);
 
}
 

	
 
/* static */ bool AIEngine::CanPullCargo(EngineID engine_id, CargoID cargo_id)
 
{
 
	if (!IsValidEngine(engine_id)) return false;
 
	if (GetVehicleType(engine_id) != AIVehicle::VEHICLE_RAIL) return false;
 
	if (!AICargo::IsValidCargo(cargo_id)) return false;
 

	
 
	return (::RailVehInfo(engine_id)->ai_passenger_only != 1) || AICargo::HasCargoClass(cargo_id, AICargo::CC_PASSENGERS);
 
}
 

	
 

	
 
/* static */ int32 AIEngine::GetCapacity(EngineID engine_id)
 
{
 
	if (!IsValidEngine(engine_id)) return -1;
 

	
 
	switch (::GetEngine(engine_id)->type) {
 
		case VEH_ROAD:
 
		case VEH_TRAIN: {
 
			uint16 *capacities = GetCapacityOfArticulatedParts(engine_id, ::GetEngine(engine_id)->type);
 
			for (CargoID c = 0; c < NUM_CARGO; c++) {
 
				if (capacities[c] == 0) continue;
 
				return capacities[c];
 
			}
 
			return -1;
 
		} break;
 

	
 
		case VEH_SHIP: {
 
			const ShipVehicleInfo *vi = ::ShipVehInfo(engine_id);
 
			return vi->capacity;
 
		} break;
 

	
 
		case VEH_AIRCRAFT: {
 
			const AircraftVehicleInfo *vi = ::AircraftVehInfo(engine_id);
 
			return vi->passenger_capacity;
 
		} break;
 

	
 
		default: NOT_REACHED();
 
	}
 
}
 

	
 
/* static */ int32 AIEngine::GetReliability(EngineID engine_id)
 
{
 
	if (!IsValidEngine(engine_id)) return -1;
 

	
 
	return (::GetEngine(engine_id)->reliability * 100 >> 16);
 
}
 

	
 
/* static */ int32 AIEngine::GetMaxSpeed(EngineID engine_id)
 
{
 
	if (!IsValidEngine(engine_id)) return -1;
 

	
 
	switch (::GetEngine(engine_id)->type) {
 
		case VEH_ROAD: {
 
			const RoadVehicleInfo *vi = ::RoadVehInfo(engine_id);
 
			/* Internal speeds are km/h * 2 */
 
			return vi->max_speed / 2;
 
		} break;
 

	
 
		case VEH_TRAIN: {
 
			const RailVehicleInfo *vi = ::RailVehInfo(engine_id);
 
			return vi->max_speed;
 
		} break;
 

	
 
		case VEH_SHIP: {
 
			const ShipVehicleInfo *vi = ::ShipVehInfo(engine_id);
 
			/* Internal speeds are km/h * 2 */
 
			return vi->max_speed / 2;
 
		} break;
 

	
 
		case VEH_AIRCRAFT: {
 
			const AircraftVehicleInfo *vi = ::AircraftVehInfo(engine_id);
 
			return vi->max_speed / _settings_game.vehicle.plane_speed;
 
		} break;
 

	
 
		default: NOT_REACHED();
 
	}
 
}
 

	
 
/* static */ Money AIEngine::GetPrice(EngineID engine_id)
 
{
 
	if (!IsValidEngine(engine_id)) return -1;
 

	
 
	switch (::GetEngine(engine_id)->type) {
 
		case VEH_ROAD: {
 
			const RoadVehicleInfo *vi = ::RoadVehInfo(engine_id);
 
			return (_price.roadveh_base >> 3) * vi->cost_factor >> 5;
 
		} break;
 

	
 
		case VEH_TRAIN: {
 
			const RailVehicleInfo *vi = ::RailVehInfo(engine_id);
 
			return (_price.build_railvehicle >> 3) * vi->cost_factor >> 5;
 
		} break;
 

	
 
		case VEH_SHIP: {
 
			const ShipVehicleInfo *vi = ::ShipVehInfo(engine_id);
 
			return (_price.ship_base >> 3) * vi->cost_factor >> 5;
 
		} break;
 

	
 
		case VEH_AIRCRAFT: {
 
			const AircraftVehicleInfo *vi = ::AircraftVehInfo(engine_id);
 
			return (_price.aircraft_base >> 3) * vi->cost_factor >> 5;
 
		} break;
 

	
 
		default: NOT_REACHED();
 
	}
 
}
 

	
 
/* static */ int32 AIEngine::GetMaxAge(EngineID engine_id)
 
{
 
	if (!IsValidEngine(engine_id)) return -1;
 

	
 
	return ::GetEngine(engine_id)->lifelength * 366;
 
}
 

	
 
/* static */ Money AIEngine::GetRunningCost(EngineID engine_id)
 
{
 
	if (!IsValidEngine(engine_id)) return -1;
 

	
 
	/* We need to create an instance in order to obtain GetRunningCost.
 
	 *  This means we temporary allocate a vehicle in the pool, but
 
	 *  there is no other way.. */
 
	Vehicle *vehicle;
 
	switch (::GetEngine(engine_id)->type) {
 
		case VEH_ROAD: {
 
			vehicle = new RoadVehicle();
 
		} break;
 

	
 
		case VEH_TRAIN: {
 
			vehicle = new Train();
 
		} break;
 

	
 
		case VEH_SHIP: {
 
			vehicle = new Ship();
 
		} break;
 

	
 
		case VEH_AIRCRAFT: {
 
			vehicle = new Aircraft();
 
		} break;
 

	
 
		default: NOT_REACHED();
 
	}
 

	
 
	vehicle->engine_type = engine_id;
 
	Money runningCost = vehicle->GetRunningCost();
 
	delete vehicle;
 
	return runningCost >> 8;
 
}
 

	
 
/* static */ AIVehicle::VehicleType AIEngine::GetVehicleType(EngineID engine_id)
 
{
 
	if (!IsValidEngine(engine_id)) return AIVehicle::VEHICLE_INVALID;
 

	
 
	switch (::GetEngine(engine_id)->type) {
 
		case VEH_ROAD:     return AIVehicle::VEHICLE_ROAD;
 
		case VEH_TRAIN:    return AIVehicle::VEHICLE_RAIL;
 
		case VEH_SHIP:     return AIVehicle::VEHICLE_WATER;
 
		case VEH_AIRCRAFT: return AIVehicle::VEHICLE_AIR;
 
		default: NOT_REACHED();
 
	}
 
}
 

	
 
/* static */ bool AIEngine::IsWagon(EngineID engine_id)
 
{
 
	if (!IsValidEngine(engine_id)) return false;
 
	if (GetVehicleType(engine_id) != AIVehicle::VEHICLE_RAIL) return false;
 

	
 
	return ::RailVehInfo(engine_id)->power == 0;
 
}
 

	
 
/* static */ bool AIEngine::CanRunOnRail(EngineID engine_id, AIRail::RailType track_rail_type)
 
{
 
	if (!IsValidEngine(engine_id)) return false;
 
	if (GetVehicleType(engine_id) != AIVehicle::VEHICLE_RAIL) return false;
 
	if (!AIRail::IsRailTypeAvailable(track_rail_type)) return false;
 

	
 
	return ::IsCompatibleRail((::RailType)::RailVehInfo(engine_id)->railtype, (::RailType)track_rail_type);
 
}
 

	
 
/* static */ bool AIEngine::HasPowerOnRail(EngineID engine_id, AIRail::RailType track_rail_type)
 
{
 
	if (!IsValidEngine(engine_id)) return false;
 
	if (GetVehicleType(engine_id) != AIVehicle::VEHICLE_RAIL) return false;
 
	if (!AIRail::IsRailTypeAvailable(track_rail_type)) return false;
 

	
 
	return ::HasPowerOnRail((::RailType)::RailVehInfo(engine_id)->railtype, (::RailType)track_rail_type);
 
}
 

	
 
/* static */ AIRoad::RoadType AIEngine::GetRoadType(EngineID engine_id)
 
{
 
	if (!IsValidEngine(engine_id)) return AIRoad::ROADTYPE_INVALID;
 
	if (GetVehicleType(engine_id) != AIVehicle::VEHICLE_ROAD) return AIRoad::ROADTYPE_INVALID;
 

	
 
	return HasBit(::EngInfo(engine_id)->misc_flags, EF_ROAD_TRAM) ? AIRoad::ROADTYPE_TRAM : AIRoad::ROADTYPE_ROAD;
 
}
 

	
 
/* static */ AIRail::RailType AIEngine::GetRailType(EngineID engine_id)
 
{
 
	if (!IsValidEngine(engine_id)) return AIRail::RAILTYPE_INVALID;
 
	if (GetVehicleType(engine_id) != AIVehicle::VEHICLE_RAIL) return AIRail::RAILTYPE_INVALID;
 

	
 
	return (AIRail::RailType)(uint)::RailVehInfo(engine_id)->railtype;
 
}
 

	
 
/* static */ bool AIEngine::IsArticulated(EngineID engine_id)
 
{
 
	if (!IsValidEngine(engine_id)) return false;
 
	if (GetVehicleType(engine_id) != AIVehicle::VEHICLE_ROAD && GetVehicleType(engine_id) != AIVehicle::VEHICLE_RAIL) return false;
 

	
 
	return CountArticulatedParts(engine_id, true) != 0;
 
}
 

	
 
/* static */ AIAirport::PlaneType AIEngine::GetPlaneType(EngineID engine_id)
 
{
 
	if (!IsValidEngine(engine_id)) return AIAirport::PT_INVALID;
 
	if (GetVehicleType(engine_id) != AIVehicle::VEHICLE_AIR) return AIAirport::PT_INVALID;
 

	
 
	return (AIAirport::PlaneType)::AircraftVehInfo(engine_id)->subtype;
 
}
src/ai/api/ai_engine.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_engine.hpp Everything to query and build engines. */
 

	
 
#ifndef AI_ENGINE_HPP
 
#define AI_ENGINE_HPP
 

	
 
#include "ai_object.hpp"
 
#include "ai_vehicle.hpp"
 
#include "ai_road.hpp"
 
#include "ai_rail.hpp"
 
#include "ai_airport.hpp"
 

	
 
/**
 
 * Class that handles all engine related functions.
 
 */
 
class AIEngine : public AIObject {
 
public:
 
	static const char *GetClassName() { return "AIEngine"; }
 

	
 
	/**
 
	 * Checks whether the given engine type is valid and buildable by you.
 
	 * @param engine_id The engine to check.
 
	 * @return True if and only if the engine type is valid.
 
	 */
 
	static bool IsValidEngine(EngineID engine_id);
 

	
 
	/**
 
	 * Get the name of an engine.
 
	 * @param engine_id The engine to get the name of.
 
	 * @pre IsValidEngine(engine_id).
 
	 * @return The name the engine has.
 
	 */
 
	static const char *GetName(EngineID engine_id);
 

	
 
	/**
 
	 * Get the cargo-type of an engine. In case it can transport 2 cargos, it
 
	 *  returns the first.
 
	 * @param engine_id The engine to get the cargo-type of.
 
	 * @pre IsValidEngine(engine_id).
 
	 * @return The cargo-type of the engine.
 
	 */
 
	static CargoID GetCargoType(EngineID engine_id);
 

	
 
	/**
 
	 * Check if the cargo of an engine can be refitted to your requested. If
 
	 *  the engine already allows this cargo, the function also returns true.
 
	 * @param engine_id The engine to check for refitting.
 
	 * @param cargo_id The cargo to check for refitting.
 
	 * @pre IsValidEngine(engine_id).
 
	 * @pre AICargo::IsValidCargo(cargo_id).
 
	 * @return True if the engine can carry this cargo, either via refit, or
 
	 *  by default.
 
	 */
 
	static bool CanRefitCargo(EngineID engine_id, CargoID cargo_id);
 

	
 
	/**
 
	 * Check if the engine can pull a wagon with the given cargo.
 
	 * @param engine_id The engine to check.
 
	 * @param cargo_id The cargo to check.
 
	 * @pre IsValidEngine(engine_id).
 
	 * @pre GetVehicleType(engine_id) == AIVehicle.VEHICLE_RAIL.
 
	 * @pre AICargo::IsValidCargo(cargo_id).
 
	 * @return True if the engine can pull wagons carrying this cargo.
 
	 * @note This function is not exhaustive; a true here does not mean
 
	 *  that the vehicle can pull the wagons, a false does mean it can't.
 
	 */
 
	static bool CanPullCargo(EngineID engine_id, CargoID cargo_id);
 

	
 
	/**
 
	 * Get the capacity of an engine. In case it can transport 2 cargos, it
 
	 *  returns the first.
 
	 * @param engine_id The engine to get the capacity of.
 
	 * @pre IsValidEngine(engine_id).
 
	 * @return The capacity of the engine.
 
	 */
 
	static int32 GetCapacity(EngineID engine_id);
 

	
 
	/**
 
	 * Get the reliability of an engine. The value is between 0 and 100, where
 
	 *  100 means 100% reliability (never breaks down) and 0 means 0%
 
	 *  reliability (you most likely don't want to buy it).
 
	 * @param engine_id The engine to get the reliability of.
 
	 * @pre IsValidEngine(engine_id).
 
	 * @return The reliability the engine has.
 
	 */
 
	static int32 GetReliability(EngineID engine_id);
 

	
 
	/**
 
	 * Get the maximum speed of an engine.
 
	 * @param engine_id The engine to get the maximum speed of.
 
	 * @pre IsValidEngine(engine_id).
 
	 * @return The maximum speed the engine has.
 
	 * @note The speed is in km/h.
 
	 */
 
	static int32 GetMaxSpeed(EngineID engine_id);
 

	
 
	/**
 
	 * Get the new cost of an engine.
 
	 * @param engine_id The engine to get the new cost of.
 
	 * @pre IsValidEngine(engine_id).
 
	 * @return The new cost the engine has.
 
	 */
 
	static Money GetPrice(EngineID engine_id);
 

	
 
	/**
 
	 * Get the maximum age of a brand new engine.
 
	 * @param engine_id The engine to get the maximum age of.
 
	 * @pre IsValidEngine(engine_id).
 
	 * @returns The maximum age of a new engine in days.
 
	 * @note Age is in days; divide by 366 to get per year.
 
	 */
 
	static int32 GetMaxAge(EngineID engine_id);
 

	
 
	/**
 
	 * Get the running cost of an engine.
 
	 * @param engine_id The engine to get the running cost of.
 
	 * @pre IsValidEngine(engine_id).
 
	 * @return The running cost of a vehicle per year.
 
	 * @note Cost is per year; divide by 364 to get per day.
 
	 */
 
	static Money GetRunningCost(EngineID engine_id);
 

	
 
	/**
 
	 * Get the type of an engine.
 
	 * @param engine_id The engine to get the type of.
 
	 * @pre IsValidEngine(engine_id).
 
	 * @return The type the engine has.
 
	 */
 
	static AIVehicle::VehicleType GetVehicleType(EngineID engine_id);
 

	
 
	/**
 
	 * Check if an engine is a wagon.
 
	 * @param engine_id The engine to check.
 
	 * @pre IsValidEngine(engine_id).
 
	 * @pre GetVehicleType(engine_id) == AIVehicle.VEHICLE_RAIL.
 
	 * @return Whether or not the engine is a wagon.
 
	 */
 
	static bool IsWagon(EngineID engine_id);
 

	
 
	/**
 
	 * Check if a train vehicle can run on a RailType.
 
	 * @param engine_id The engine to check.
 
	 * @param track_rail_type The type you want to check.
 
	 * @pre IsValidEngine(engine_id).
 
	 * @pre GetVehicleType(engine_id) == AIVehicle::VEHICLE_RAIL.
 
	 * @pre AIRail::IsRailTypeAvailable(track_rail_type).
 
	 * @return Whether an engine of type 'engine_id' can run on 'track_rail_type'.
 
	 * @note Even if a train can run on a RailType that doesn't mean that it'll be
 
	 *   able to power the train. Use HasPowerOnRail for that.
 
	 */
 
	static bool CanRunOnRail(EngineID engine_id, AIRail::RailType track_rail_type);
 

	
 
	/**
 
	 * Check if a train engine has power on a RailType.
 
	 * @param engine_id The engine to check.
 
	 * @param track_rail_type Another RailType.
 
	 * @pre IsValidEngine(engine_id).
 
	 * @pre GetVehicleType(engine_id) == AIVehicle::VEHICLE_RAIL.
 
	 * @pre AIRail::IsRailTypeAvailable(track_rail_type).
 
	 * @return Whether an engine of type 'engine_id' has power on 'track_rail_type'.
 
	 */
 
	static bool HasPowerOnRail(EngineID engine_id, AIRail::RailType track_rail_type);
 

	
 
	/**
 
	 * Get the RoadType of the engine.
 
	 * @param engine_id The engine to get the RoadType of.
 
	 * @pre IsValidEngine(engine_id).
 
	 * @pre GetVehicleType(engine_id) == AIVehicle.VEHICLE_ROAD.
 
	 * @return The RoadType the engine has.
 
	 */
 
	static AIRoad::RoadType GetRoadType(EngineID engine_id);
 

	
 
	/**
 
	 * Get the RailType of the engine.
 
	 * @param engine_id The engine to get the RailType of.
 
	 * @pre IsValidEngine(engine_id).
 
	 * @pre GetVehicleType(engine_id) == AIVehicle.VEHICLE_RAIL.
 
	 * @return The RailType the engine has.
 
	 */
 
	static AIRail::RailType GetRailType(EngineID engine_id);
 

	
 
	/**
 
	 * Check if the engine is articulated.
 
	 * @param engine_id The engine to check.
 
	 * @pre IsValidEngine(engine_id).
 
	 * @pre GetVehicleType(engine_id) == AIVehicle.VEHICLE_ROAD || GetVehicleType(engine_id) == AIVehicle.VEHICLE_RAIL.
 
	 * @return True if the engine is articulated.
 
	 */
 
	static bool IsArticulated(EngineID engine_id);
 

	
 
	/**
 
	 * Get the PlaneType of the engine.
 
	 * @param engine_id The engine to get the PlaneType of.
 
	 * @pre IsValidEngine(engine_id).
 
	 * @pre GetVehicleType(engine_id) == AIVehicle.VEHICLE_AIR.
 
	 * @return The PlaneType the engine has.
 
	 */
 
	static AIAirport::PlaneType GetPlaneType(EngineID engine_id);
 
};
 

	
 
#endif /* AI_ENGINE_HPP */
src/ai/api/ai_engine.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_engine.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow AIEngine to be used as Squirrel parameter */
 
	template <> AIEngine *GetParam(ForceType<AIEngine *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEngine *)instance; }
 
	template <> AIEngine &GetParam(ForceType<AIEngine &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEngine *)instance; }
 
	template <> const AIEngine *GetParam(ForceType<const AIEngine *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEngine *)instance; }
 
	template <> const AIEngine &GetParam(ForceType<const AIEngine &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEngine *)instance; }
 
	template <> int Return<AIEngine *>(HSQUIRRELVM vm, AIEngine *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIEngine", res, NULL, DefSQDestructorCallback<AIEngine>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIEngine_Register(Squirrel *engine) {
 
	DefSQClass <AIEngine> SQAIEngine("AIEngine");
 
	SQAIEngine.PreRegister(engine);
 
	SQAIEngine.AddConstructor<void (AIEngine::*)(), 1>(engine, "x");
 

	
 
	SQAIEngine.DefSQStaticMethod(engine, &AIEngine::GetClassName,   "GetClassName",   1, "x");
 
	SQAIEngine.DefSQStaticMethod(engine, &AIEngine::IsValidEngine,  "IsValidEngine",  2, "xi");
 
	SQAIEngine.DefSQStaticMethod(engine, &AIEngine::GetName,        "GetName",        2, "xi");
 
	SQAIEngine.DefSQStaticMethod(engine, &AIEngine::GetCargoType,   "GetCargoType",   2, "xi");
 
	SQAIEngine.DefSQStaticMethod(engine, &AIEngine::CanRefitCargo,  "CanRefitCargo",  3, "xii");
 
	SQAIEngine.DefSQStaticMethod(engine, &AIEngine::CanPullCargo,   "CanPullCargo",   3, "xii");
 
	SQAIEngine.DefSQStaticMethod(engine, &AIEngine::GetCapacity,    "GetCapacity",    2, "xi");
 
	SQAIEngine.DefSQStaticMethod(engine, &AIEngine::GetReliability, "GetReliability", 2, "xi");
 
	SQAIEngine.DefSQStaticMethod(engine, &AIEngine::GetMaxSpeed,    "GetMaxSpeed",    2, "xi");
 
	SQAIEngine.DefSQStaticMethod(engine, &AIEngine::GetPrice,       "GetPrice",       2, "xi");
 
	SQAIEngine.DefSQStaticMethod(engine, &AIEngine::GetMaxAge,      "GetMaxAge",      2, "xi");
 
	SQAIEngine.DefSQStaticMethod(engine, &AIEngine::GetRunningCost, "GetRunningCost", 2, "xi");
 
	SQAIEngine.DefSQStaticMethod(engine, &AIEngine::GetVehicleType, "GetVehicleType", 2, "xi");
 
	SQAIEngine.DefSQStaticMethod(engine, &AIEngine::IsWagon,        "IsWagon",        2, "xi");
 
	SQAIEngine.DefSQStaticMethod(engine, &AIEngine::CanRunOnRail,   "CanRunOnRail",   3, "xii");
 
	SQAIEngine.DefSQStaticMethod(engine, &AIEngine::HasPowerOnRail, "HasPowerOnRail", 3, "xii");
 
	SQAIEngine.DefSQStaticMethod(engine, &AIEngine::GetRoadType,    "GetRoadType",    2, "xi");
 
	SQAIEngine.DefSQStaticMethod(engine, &AIEngine::GetRailType,    "GetRailType",    2, "xi");
 
	SQAIEngine.DefSQStaticMethod(engine, &AIEngine::IsArticulated,  "IsArticulated",  2, "xi");
 
	SQAIEngine.DefSQStaticMethod(engine, &AIEngine::GetPlaneType,   "GetPlaneType",   2, "xi");
 

	
 
	SQAIEngine.PostRegister(engine);
 
}
src/ai/api/ai_enginelist.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_enginelist.cpp Implementation of AIEngineList and friends. */
 

	
 
#include "ai_enginelist.hpp"
 
#include "../../company_func.h"
 
#include "../../engine_base.h"
 
#include "../../core/bitmath_func.hpp"
 

	
 
AIEngineList::AIEngineList(AIVehicle::VehicleType vehicle_type)
 
{
 
	Engine *e;
 
	FOR_ALL_ENGINES_OF_TYPE(e, (::VehicleType)vehicle_type) {
 
		if (HasBit(e->company_avail, _current_company)) this->AddItem(e->index);
 
	}
 
}
src/ai/api/ai_enginelist.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_enginelist.hpp List all the engines. */
 

	
 
#ifndef AI_ENGINELIST_HPP
 
#define AI_ENGINELIST_HPP
 

	
 
#include "ai_abstractlist.hpp"
 
#include "ai_vehicle.hpp"
 

	
 
/**
 
 * Create a list of engines based on a vehicle type.
 
 * @ingroup AIList
 
 */
 
class AIEngineList : public AIAbstractList {
 
public:
 
	static const char *GetClassName() { return "AIEngineList"; }
 

	
 
	/**
 
	 * @param vehicle_type The type of vehicle to make a list of engines for.
 
	 */
 
	AIEngineList(AIVehicle::VehicleType vehicle_type);
 
};
 

	
 
#endif /* AI_ENGINELIST_HPP */
src/ai/api/ai_enginelist.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_enginelist.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow AIEngineList to be used as Squirrel parameter */
 
	template <> AIEngineList *GetParam(ForceType<AIEngineList *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEngineList *)instance; }
 
	template <> AIEngineList &GetParam(ForceType<AIEngineList &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEngineList *)instance; }
 
	template <> const AIEngineList *GetParam(ForceType<const AIEngineList *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEngineList *)instance; }
 
	template <> const AIEngineList &GetParam(ForceType<const AIEngineList &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEngineList *)instance; }
 
	template <> int Return<AIEngineList *>(HSQUIRRELVM vm, AIEngineList *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIEngineList", res, NULL, DefSQDestructorCallback<AIEngineList>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIEngineList_Register(Squirrel *engine) {
 
	DefSQClass <AIEngineList> SQAIEngineList("AIEngineList");
 
	SQAIEngineList.PreRegister(engine, "AIAbstractList");
 
	SQAIEngineList.AddConstructor<void (AIEngineList::*)(AIVehicle::VehicleType vehicle_type), 2>(engine, "xi");
 

	
 
	SQAIEngineList.DefSQStaticMethod(engine, &AIEngineList::GetClassName, "GetClassName", 1, "x");
 

	
 
	SQAIEngineList.PostRegister(engine);
 
}
src/ai/api/ai_error.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_error.cpp Implementation of AIError. */
 

	
 
#include "ai_error.hpp"
 
#include "table/strings.h"
 
#include "../../core/bitmath_func.hpp"
 

	
 
AIError::AIErrorMap AIError::error_map = AIError::AIErrorMap();
 
AIError::AIErrorMapString AIError::error_map_string = AIError::AIErrorMapString();
 

	
 
/* static */ AIErrorType AIError::GetLastError()
 
{
 
	return AIObject::GetLastError();
 
}
 

	
 
/* static */ const char *AIError::GetLastErrorString()
 
{
 
	return (*error_map_string.find(AIError::GetLastError())).second;
 
}
 

	
 
/* static */ AIErrorType AIError::StringToError(StringID internal_string_id)
 
{
 
	uint index = GB(internal_string_id, 11, 5);
 
	switch (GB(internal_string_id, 11, 5)) {
 
		case 26: case 28: case 29: case 30: // NewGRF strings.
 
			return ERR_NEWGRF_SUPPLIED_ERROR;
 

	
 
		/* DO NOT SWAP case 14 and 4 because that will break StringToError due
 
		 * to the index dependency that relies on FALL THROUGHs. */
 
		case 14: if (index < 0xE4) break; // Player name
 
		case 4:  if (index < 0xC0) break; // Town name
 
		case 15: // Custom name
 
		case 31: // Dynamic strings
 
			/* These strings are 'random' and have no meaning.
 
			 * They actually shouldn't even be returned as error messages. */
 
			return ERR_UNKNOWN;
 

	
 
		default:
 
			break;
 
	}
 

	
 
	AIErrorMap::iterator it = error_map.find(internal_string_id);
 
	if (it == error_map.end()) return ERR_UNKNOWN;
 
	return (*it).second;
 
}
 

	
 
/* static */ void AIError::RegisterErrorMap(StringID internal_string_id, AIErrorType ai_error_msg)
 
{
 
	error_map[internal_string_id] = ai_error_msg;
 
}
 

	
 
/* static */ void AIError::RegisterErrorMapString(AIErrorType ai_error_msg, const char *message)
 
{
 
	error_map_string[ai_error_msg] = message;
 
}
 

	
 
/* static */ AIError::ErrorCategories AIError::GetErrorCategory() {
 
	return (AIError::ErrorCategories)(GetLastError() >> (uint)ERR_CAT_BIT_SIZE);
 
}
src/ai/api/ai_error.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_error.hpp Everything to query errors. */
 

	
 
#ifndef AI_ERROR_HPP
 
#define AI_ERROR_HPP
 

	
 
#include "ai_object.hpp"
 
#include <map>
 

	
 
/**
 
 * Helper to write precondition enforcers for the AI API in an abbreviated manner.
 
 * @param returnval The value to return on failure.
 
 * @param condition The condition that must be obeyed.
 
 */
 
#define EnforcePrecondition(returnval, condition)               \
 
	if (!(condition)) {                                           \
 
		AIObject::SetLastError(AIError::ERR_PRECONDITION_FAILED);   \
 
		return returnval;                                           \
 
	}
 

	
 
/**
 
 * Helper to write precondition enforcers for the AI API in an abbreviated manner.
 
 * @param returnval The value to return on failure.
 
 * @param condition The condition that must be obeyed.
 
 * @param error_code The error code passed to AIObject::SetLastError.
 
 */
 
#define EnforcePreconditionCustomError(returnval, condition, error_code)   \
 
	if (!(condition)) {                                                      \
 
		AIObject::SetLastError(error_code);                                    \
 
		return returnval;                                                      \
 
	}
 

	
 
/**
 
 * Class that handles all error related functions.
 
 */
 
class AIError : public AIObject {
 
public:
 
	static const char *GetClassName() { return "AIError"; }
 

	
 
	/**
 
	 * All categories errors can be divided in.
 
	 */
 
	enum ErrorCategories {
 
		ERR_CAT_NONE = 0, //!< Error messages not related to any category.
 
		ERR_CAT_GENERAL,  //!< Error messages related to general things.
 
		ERR_CAT_VEHICLE,  //!< Error messages related to building / maintaining vehicles.
 
		ERR_CAT_STATION,  //!< Error messages related to building / maintaining stations.
 
		ERR_CAT_BRIDGE,   //!< Error messages related to building / removing bridges.
 
		ERR_CAT_TUNNEL,   //!< Error messages related to building / removing tunnels.
 
		ERR_CAT_TILE,     //!< Error messages related to raising / lowering and demolishing tiles.
 
		ERR_CAT_SIGN,     //!< Error messages related to building / removing signs.
 
		ERR_CAT_RAIL,     //!< Error messages related to building / maintaining rails.
 
		ERR_CAT_ROAD,     //!< Error messages related to building / maintaining roads.
 
		ERR_CAT_ORDER,    //!< Error messages related to managing orders.
 
		ERR_CAT_MARINE,   //!< Error messages related to building / removing ships, docks and channels.
 

	
 
		/**
 
		 * DO NOT USE! The error bitsize determines how many errors can be stored in
 
		 *  a category and what the offsets are of all categories.
 
		 */
 
		ERR_CAT_BIT_SIZE = 8,
 
	};
 

	
 
	/**
 
	 * All general related error messages.
 
	 */
 
	enum ErrorMessages {
 
		/** Initial error value */
 
		ERR_NONE = ERR_CAT_NONE << ERR_CAT_BIT_SIZE,  // []
 
		/** If an error occured and the error wasn't mapped */
 
		ERR_UNKNOWN,                                  // []
 
		/** If a precondition is not met */
 
		ERR_PRECONDITION_FAILED,                      // []
 
		/** A string supplied was too long */
 
		ERR_PRECONDITION_STRING_TOO_LONG,             // []
 
		/** An error returned by a NewGRF. No possibility to get the exact error in an AI readable format */
 
		ERR_NEWGRF_SUPPLIED_ERROR,                    // []
 

	
 
		/** Base for general errors */
 
		ERR_GENERAL_BASE = ERR_CAT_GENERAL << ERR_CAT_BIT_SIZE,
 

	
 
		/** Not enough cash to perform the previous action */
 
		ERR_NOT_ENOUGH_CASH,                          // [STR_0003_NOT_ENOUGH_CASH_REQUIRES]
 

	
 
		/** Local authority won't allow the previous action */
 
		ERR_LOCAL_AUTHORITY_REFUSES,                  // [STR_2009_LOCAL_AUTHORITY_REFUSES]
 

	
 
		/** The piece of infrastructure you tried to build is already in place */
 
		ERR_ALREADY_BUILT,                            // [STR_1007_ALREADY_BUILT, STR_5007_MUST_DEMOLISH_BRIDGE_FIRST]
 

	
 
		/** Area isn't clear, try to demolish the building on it */
 
		ERR_AREA_NOT_CLEAR,                           // [STR_2004_BUILDING_MUST_BE_DEMOLISHED, STR_5007_MUST_DEMOLISH_BRIDGE_FIRST, STR_300B_MUST_DEMOLISH_RAILROAD, STR_300E_MUST_DEMOLISH_AIRPORT_FIRST, STR_MUST_DEMOLISH_CARGO_TRAM_STATION, STR_3047_MUST_DEMOLISH_TRUCK_STATION, STR_MUST_DEMOLISH_PASSENGER_TRAM_STATION, STR_3046_MUST_DEMOLISH_BUS_STATION, STR_306A_BUOY_IN_THE_WAY, STR_304D_MUST_DEMOLISH_DOCK_FIRST, STR_4800_IN_THE_WAY, STR_5804_COMPANY_HEADQUARTERS_IN, STR_5800_OBJECT_IN_THE_WAY, STR_1801_MUST_REMOVE_ROAD_FIRST, STR_1008_MUST_REMOVE_RAILROAD_TRACK, STR_5007_MUST_DEMOLISH_BRIDGE_FIRST, STR_5006_MUST_DEMOLISH_TUNNEL_FIRST, STR_1002_EXCAVATION_WOULD_DAMAGE]
 

	
 
		/** Area / property is owned by another company */
 
		ERR_OWNED_BY_ANOTHER_COMPANY,                 // [STR_1024_AREA_IS_OWNED_BY_ANOTHER, STR_013B_OWNED_BY]
 

	
 
		/** The name given is not unique for the object type */
 
		ERR_NAME_IS_NOT_UNIQUE,                       // [STR_NAME_MUST_BE_UNIQUE]
 

	
 
		/** The building you want to build requires flat land */
 
		ERR_FLAT_LAND_REQUIRED,                       // [STR_0007_FLAT_LAND_REQUIRED]
 

	
 
		/** Land is sloped in the wrong direction for this build action */
 
		ERR_LAND_SLOPED_WRONG,                        // [STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION]
 

	
 
		/** A vehicle is in the way */
 
		ERR_VEHICLE_IN_THE_WAY,                       // [STR_8803_TRAIN_IN_THE_WAY, STR_9000_ROAD_VEHICLE_IN_THE_WAY, STR_980E_SHIP_IN_THE_WAY, STR_A015_AIRCRAFT_IN_THE_WAY]
 

	
 
		/** Site is unsuitable */
 
		ERR_SITE_UNSUITABLE,                          // [STR_0239_SITE_UNSUITABLE, STR_304B_SITE_UNSUITABLE]
 

	
 
		/** Too close to the edge of the map */
 
		ERR_TOO_CLOSE_TO_EDGE,                        // [STR_0002_TOO_CLOSE_TO_EDGE_OF_MAP]
 

	
 
		/** Station is too spread out */
 
		ERR_STATION_TOO_SPREAD_OUT,                   // [STR_306C_STATION_TOO_SPREAD_OUT]
 
	};
 

	
 
	/**
 
	 * Check the membership of the last thrown error.
 
	 * @return The category the error belongs to.
 
	 * @note The last throw error can be aquired by calling GetLastError().
 
	 */
 
	static ErrorCategories GetErrorCategory();
 

	
 
	/**
 
	 * Get the last error.
 
	 * @return An ErrorMessages enum value.
 
	 */
 
	static AIErrorType GetLastError();
 

	
 
	/**
 
	 * Get the last error in string format (for human readability).
 
	 * @return An ErrorMessage enum item, as string.
 
	 */
 
	static const char *GetLastErrorString();
 

	
 
	/**
 
	 * Get the error based on the OpenTTD StringID.
 
	 * @note DO NOT INVOKE THIS METHOD YOURSELF!
 
	 * @param internal_string_id The string to convert.
 
	 * @return The NoAI equivalent error message.
 
	 */
 
	static AIErrorType StringToError(StringID internal_string_id);
 

	
 
	/**
 
	 * Map an internal OpenTTD error message to it's NoAI equivalent.
 
	 * @note DO NOT INVOKE THIS METHOD YOURSELF! The calls are autogenerated.
 
	 * @param internal_string_id The OpenTTD StringID used for an error.
 
	 * @param ai_error_msg The NoAI equivalent error message.
 
	 */
 
	static void RegisterErrorMap(StringID internal_string_id, AIErrorType ai_error_msg);
 

	
 
	/**
 
	 * Map an internal OpenTTD error message to it's NoAI equivalent.
 
	 * @note DO NOT INVOKE THIS METHOD YOURSELF! The calls are autogenerated.
 
	 * @param ai_error_msg The NoAI error message representation.
 
	 * @param message The string representation of this error message, used for debug purposes.
 
	 */
 
	static void RegisterErrorMapString(AIErrorType ai_error_msg, const char *message);
 

	
 
private:
 
	typedef std::map<StringID, AIErrorType> AIErrorMap;
 
	typedef std::map<AIErrorType, const char *> AIErrorMapString;
 

	
 
	static AIErrorMap error_map;
 
	static AIErrorMapString error_map_string;
 
};
 

	
 
#endif /* AI_ERROR_HPP */
src/ai/api/ai_error.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_error.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow enums to be used as Squirrel parameters */
 
	template <> AIError::ErrorCategories GetParam(ForceType<AIError::ErrorCategories>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AIError::ErrorCategories)tmp; }
 
	template <> int Return<AIError::ErrorCategories>(HSQUIRRELVM vm, AIError::ErrorCategories res) { sq_pushinteger(vm, (int32)res); return 1; }
 
	template <> AIError::ErrorMessages GetParam(ForceType<AIError::ErrorMessages>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AIError::ErrorMessages)tmp; }
 
	template <> int Return<AIError::ErrorMessages>(HSQUIRRELVM vm, AIError::ErrorMessages res) { sq_pushinteger(vm, (int32)res); return 1; }
 

	
 
	/* Allow AIError to be used as Squirrel parameter */
 
	template <> AIError *GetParam(ForceType<AIError *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIError *)instance; }
 
	template <> AIError &GetParam(ForceType<AIError &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIError *)instance; }
 
	template <> const AIError *GetParam(ForceType<const AIError *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIError *)instance; }
 
	template <> const AIError &GetParam(ForceType<const AIError &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIError *)instance; }
 
	template <> int Return<AIError *>(HSQUIRRELVM vm, AIError *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIError", res, NULL, DefSQDestructorCallback<AIError>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIError_Register(Squirrel *engine) {
 
	DefSQClass <AIError> SQAIError("AIError");
 
	SQAIError.PreRegister(engine);
 
	SQAIError.AddConstructor<void (AIError::*)(), 1>(engine, "x");
 

	
 
	SQAIError.DefSQConst(engine, AIError::ERR_CAT_NONE,                     "ERR_CAT_NONE");
 
	SQAIError.DefSQConst(engine, AIError::ERR_CAT_GENERAL,                  "ERR_CAT_GENERAL");
 
	SQAIError.DefSQConst(engine, AIError::ERR_CAT_VEHICLE,                  "ERR_CAT_VEHICLE");
 
	SQAIError.DefSQConst(engine, AIError::ERR_CAT_STATION,                  "ERR_CAT_STATION");
 
	SQAIError.DefSQConst(engine, AIError::ERR_CAT_BRIDGE,                   "ERR_CAT_BRIDGE");
 
	SQAIError.DefSQConst(engine, AIError::ERR_CAT_TUNNEL,                   "ERR_CAT_TUNNEL");
 
	SQAIError.DefSQConst(engine, AIError::ERR_CAT_TILE,                     "ERR_CAT_TILE");
 
	SQAIError.DefSQConst(engine, AIError::ERR_CAT_SIGN,                     "ERR_CAT_SIGN");
 
	SQAIError.DefSQConst(engine, AIError::ERR_CAT_RAIL,                     "ERR_CAT_RAIL");
 
	SQAIError.DefSQConst(engine, AIError::ERR_CAT_ROAD,                     "ERR_CAT_ROAD");
 
	SQAIError.DefSQConst(engine, AIError::ERR_CAT_ORDER,                    "ERR_CAT_ORDER");
 
	SQAIError.DefSQConst(engine, AIError::ERR_CAT_MARINE,                   "ERR_CAT_MARINE");
 
	SQAIError.DefSQConst(engine, AIError::ERR_CAT_BIT_SIZE,                 "ERR_CAT_BIT_SIZE");
 
	SQAIError.DefSQConst(engine, AIError::ERR_NONE,                         "ERR_NONE");
 
	SQAIError.DefSQConst(engine, AIError::ERR_UNKNOWN,                      "ERR_UNKNOWN");
 
	SQAIError.DefSQConst(engine, AIError::ERR_PRECONDITION_FAILED,          "ERR_PRECONDITION_FAILED");
 
	SQAIError.DefSQConst(engine, AIError::ERR_PRECONDITION_STRING_TOO_LONG, "ERR_PRECONDITION_STRING_TOO_LONG");
 
	SQAIError.DefSQConst(engine, AIError::ERR_NEWGRF_SUPPLIED_ERROR,        "ERR_NEWGRF_SUPPLIED_ERROR");
 
	SQAIError.DefSQConst(engine, AIError::ERR_GENERAL_BASE,                 "ERR_GENERAL_BASE");
 
	SQAIError.DefSQConst(engine, AIError::ERR_NOT_ENOUGH_CASH,              "ERR_NOT_ENOUGH_CASH");
 
	SQAIError.DefSQConst(engine, AIError::ERR_LOCAL_AUTHORITY_REFUSES,      "ERR_LOCAL_AUTHORITY_REFUSES");
 
	SQAIError.DefSQConst(engine, AIError::ERR_ALREADY_BUILT,                "ERR_ALREADY_BUILT");
 
	SQAIError.DefSQConst(engine, AIError::ERR_AREA_NOT_CLEAR,               "ERR_AREA_NOT_CLEAR");
 
	SQAIError.DefSQConst(engine, AIError::ERR_OWNED_BY_ANOTHER_COMPANY,     "ERR_OWNED_BY_ANOTHER_COMPANY");
 
	SQAIError.DefSQConst(engine, AIError::ERR_NAME_IS_NOT_UNIQUE,           "ERR_NAME_IS_NOT_UNIQUE");
 
	SQAIError.DefSQConst(engine, AIError::ERR_FLAT_LAND_REQUIRED,           "ERR_FLAT_LAND_REQUIRED");
 
	SQAIError.DefSQConst(engine, AIError::ERR_LAND_SLOPED_WRONG,            "ERR_LAND_SLOPED_WRONG");
 
	SQAIError.DefSQConst(engine, AIError::ERR_VEHICLE_IN_THE_WAY,           "ERR_VEHICLE_IN_THE_WAY");
 
	SQAIError.DefSQConst(engine, AIError::ERR_SITE_UNSUITABLE,              "ERR_SITE_UNSUITABLE");
 
	SQAIError.DefSQConst(engine, AIError::ERR_TOO_CLOSE_TO_EDGE,            "ERR_TOO_CLOSE_TO_EDGE");
 
	SQAIError.DefSQConst(engine, AIError::ERR_STATION_TOO_SPREAD_OUT,       "ERR_STATION_TOO_SPREAD_OUT");
 

	
 
	AIError::RegisterErrorMap(STR_0003_NOT_ENOUGH_CASH_REQUIRES,        AIError::ERR_NOT_ENOUGH_CASH);
 
	AIError::RegisterErrorMap(STR_2009_LOCAL_AUTHORITY_REFUSES,         AIError::ERR_LOCAL_AUTHORITY_REFUSES);
 
	AIError::RegisterErrorMap(STR_1007_ALREADY_BUILT,                   AIError::ERR_ALREADY_BUILT);
 
	AIError::RegisterErrorMap(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST,      AIError::ERR_ALREADY_BUILT);
 
	AIError::RegisterErrorMap(STR_2004_BUILDING_MUST_BE_DEMOLISHED,     AIError::ERR_AREA_NOT_CLEAR);
 
	AIError::RegisterErrorMap(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST,      AIError::ERR_AREA_NOT_CLEAR);
 
	AIError::RegisterErrorMap(STR_300B_MUST_DEMOLISH_RAILROAD,          AIError::ERR_AREA_NOT_CLEAR);
 
	AIError::RegisterErrorMap(STR_300E_MUST_DEMOLISH_AIRPORT_FIRST,     AIError::ERR_AREA_NOT_CLEAR);
 
	AIError::RegisterErrorMap(STR_MUST_DEMOLISH_CARGO_TRAM_STATION,     AIError::ERR_AREA_NOT_CLEAR);
 
	AIError::RegisterErrorMap(STR_3047_MUST_DEMOLISH_TRUCK_STATION,     AIError::ERR_AREA_NOT_CLEAR);
 
	AIError::RegisterErrorMap(STR_MUST_DEMOLISH_PASSENGER_TRAM_STATION, AIError::ERR_AREA_NOT_CLEAR);
 
	AIError::RegisterErrorMap(STR_3046_MUST_DEMOLISH_BUS_STATION,       AIError::ERR_AREA_NOT_CLEAR);
 
	AIError::RegisterErrorMap(STR_306A_BUOY_IN_THE_WAY,                 AIError::ERR_AREA_NOT_CLEAR);
 
	AIError::RegisterErrorMap(STR_304D_MUST_DEMOLISH_DOCK_FIRST,        AIError::ERR_AREA_NOT_CLEAR);
 
	AIError::RegisterErrorMap(STR_4800_IN_THE_WAY,                      AIError::ERR_AREA_NOT_CLEAR);
 
	AIError::RegisterErrorMap(STR_5804_COMPANY_HEADQUARTERS_IN,         AIError::ERR_AREA_NOT_CLEAR);
 
	AIError::RegisterErrorMap(STR_5800_OBJECT_IN_THE_WAY,               AIError::ERR_AREA_NOT_CLEAR);
 
	AIError::RegisterErrorMap(STR_1801_MUST_REMOVE_ROAD_FIRST,          AIError::ERR_AREA_NOT_CLEAR);
 
	AIError::RegisterErrorMap(STR_1008_MUST_REMOVE_RAILROAD_TRACK,      AIError::ERR_AREA_NOT_CLEAR);
 
	AIError::RegisterErrorMap(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST,      AIError::ERR_AREA_NOT_CLEAR);
 
	AIError::RegisterErrorMap(STR_5006_MUST_DEMOLISH_TUNNEL_FIRST,      AIError::ERR_AREA_NOT_CLEAR);
 
	AIError::RegisterErrorMap(STR_1002_EXCAVATION_WOULD_DAMAGE,         AIError::ERR_AREA_NOT_CLEAR);
 
	AIError::RegisterErrorMap(STR_1024_AREA_IS_OWNED_BY_ANOTHER,        AIError::ERR_OWNED_BY_ANOTHER_COMPANY);
 
	AIError::RegisterErrorMap(STR_013B_OWNED_BY,                        AIError::ERR_OWNED_BY_ANOTHER_COMPANY);
 
	AIError::RegisterErrorMap(STR_NAME_MUST_BE_UNIQUE,                  AIError::ERR_NAME_IS_NOT_UNIQUE);
 
	AIError::RegisterErrorMap(STR_0007_FLAT_LAND_REQUIRED,              AIError::ERR_FLAT_LAND_REQUIRED);
 
	AIError::RegisterErrorMap(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION,  AIError::ERR_LAND_SLOPED_WRONG);
 
	AIError::RegisterErrorMap(STR_8803_TRAIN_IN_THE_WAY,                AIError::ERR_VEHICLE_IN_THE_WAY);
 
	AIError::RegisterErrorMap(STR_9000_ROAD_VEHICLE_IN_THE_WAY,         AIError::ERR_VEHICLE_IN_THE_WAY);
 
	AIError::RegisterErrorMap(STR_980E_SHIP_IN_THE_WAY,                 AIError::ERR_VEHICLE_IN_THE_WAY);
 
	AIError::RegisterErrorMap(STR_A015_AIRCRAFT_IN_THE_WAY,             AIError::ERR_VEHICLE_IN_THE_WAY);
 
	AIError::RegisterErrorMap(STR_0239_SITE_UNSUITABLE,                 AIError::ERR_SITE_UNSUITABLE);
 
	AIError::RegisterErrorMap(STR_304B_SITE_UNSUITABLE,                 AIError::ERR_SITE_UNSUITABLE);
 
	AIError::RegisterErrorMap(STR_0002_TOO_CLOSE_TO_EDGE_OF_MAP,        AIError::ERR_TOO_CLOSE_TO_EDGE);
 
	AIError::RegisterErrorMap(STR_306C_STATION_TOO_SPREAD_OUT,          AIError::ERR_STATION_TOO_SPREAD_OUT);
 

	
 
	AIError::RegisterErrorMapString(AIError::ERR_NONE,                         "ERR_NONE");
 
	AIError::RegisterErrorMapString(AIError::ERR_UNKNOWN,                      "ERR_UNKNOWN");
 
	AIError::RegisterErrorMapString(AIError::ERR_PRECONDITION_FAILED,          "ERR_PRECONDITION_FAILED");
 
	AIError::RegisterErrorMapString(AIError::ERR_PRECONDITION_STRING_TOO_LONG, "ERR_PRECONDITION_STRING_TOO_LONG");
 
	AIError::RegisterErrorMapString(AIError::ERR_NEWGRF_SUPPLIED_ERROR,        "ERR_NEWGRF_SUPPLIED_ERROR");
 
	AIError::RegisterErrorMapString(AIError::ERR_NOT_ENOUGH_CASH,              "ERR_NOT_ENOUGH_CASH");
 
	AIError::RegisterErrorMapString(AIError::ERR_LOCAL_AUTHORITY_REFUSES,      "ERR_LOCAL_AUTHORITY_REFUSES");
 
	AIError::RegisterErrorMapString(AIError::ERR_ALREADY_BUILT,                "ERR_ALREADY_BUILT");
 
	AIError::RegisterErrorMapString(AIError::ERR_AREA_NOT_CLEAR,               "ERR_AREA_NOT_CLEAR");
 
	AIError::RegisterErrorMapString(AIError::ERR_OWNED_BY_ANOTHER_COMPANY,     "ERR_OWNED_BY_ANOTHER_COMPANY");
 
	AIError::RegisterErrorMapString(AIError::ERR_NAME_IS_NOT_UNIQUE,           "ERR_NAME_IS_NOT_UNIQUE");
 
	AIError::RegisterErrorMapString(AIError::ERR_FLAT_LAND_REQUIRED,           "ERR_FLAT_LAND_REQUIRED");
 
	AIError::RegisterErrorMapString(AIError::ERR_LAND_SLOPED_WRONG,            "ERR_LAND_SLOPED_WRONG");
 
	AIError::RegisterErrorMapString(AIError::ERR_VEHICLE_IN_THE_WAY,           "ERR_VEHICLE_IN_THE_WAY");
 
	AIError::RegisterErrorMapString(AIError::ERR_SITE_UNSUITABLE,              "ERR_SITE_UNSUITABLE");
 
	AIError::RegisterErrorMapString(AIError::ERR_TOO_CLOSE_TO_EDGE,            "ERR_TOO_CLOSE_TO_EDGE");
 
	AIError::RegisterErrorMapString(AIError::ERR_STATION_TOO_SPREAD_OUT,       "ERR_STATION_TOO_SPREAD_OUT");
 

	
 
	SQAIError.DefSQStaticMethod(engine, &AIError::GetClassName,           "GetClassName",           1, "x");
 
	SQAIError.DefSQStaticMethod(engine, &AIError::GetErrorCategory,       "GetErrorCategory",       1, "x");
 
	SQAIError.DefSQStaticMethod(engine, &AIError::GetLastError,           "GetLastError",           1, "x");
 
	SQAIError.DefSQStaticMethod(engine, &AIError::GetLastErrorString,     "GetLastErrorString",     1, "x");
 
	SQAIError.DefSQStaticMethod(engine, &AIError::StringToError,          "StringToError",          2, "xi");
 
	SQAIError.DefSQStaticMethod(engine, &AIError::RegisterErrorMap,       "RegisterErrorMap",       3, "xii");
 
	SQAIError.DefSQStaticMethod(engine, &AIError::RegisterErrorMapString, "RegisterErrorMapString", 3, "xis");
 

	
 
	SQAIError.PostRegister(engine);
 
}
src/ai/api/ai_event.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_event.cpp Implementation of AIEvent. */
 

	
 
#include "ai_event.hpp"
 
#include "ai_event_types.hpp"
 

	
 
#include <queue>
 
#include <set>
 

	
 
struct AIEventData {
 
	std::queue<AIEvent *> stack;
 
};
 

	
 
/* static */ void AIEventController::CreateEventPointer()
 
{
 
	assert(AIObject::GetEventPointer() == NULL);
 

	
 
	AIObject::GetEventPointer() = new AIEventData();
 
}
 

	
 
/* static */ void AIEventController::FreeEventPointer()
 
{
 
	AIEventData *data = (AIEventData *)AIObject::GetEventPointer();
 

	
 
	/* Free all waiting events (if any) */
 
	while (!data->stack.empty()) {
 
		AIEvent *e = data->stack.front();
 
		data->stack.pop();
 
		e->Release();
 
	}
 

	
 
	/* Now kill our data pointer */
 
	delete data;
 
}
 

	
 
/* static */ bool AIEventController::IsEventWaiting()
 
{
 
	if (AIObject::GetEventPointer() == NULL) AIEventController::CreateEventPointer();
 
	AIEventData *data = (AIEventData *)AIObject::GetEventPointer();
 

	
 
	return !data->stack.empty();
 
}
 

	
 
/* static */ AIEvent *AIEventController::GetNextEvent()
 
{
 
	if (AIObject::GetEventPointer() == NULL) AIEventController::CreateEventPointer();
 
	AIEventData *data = (AIEventData *)AIObject::GetEventPointer();
 

	
 
	if (data->stack.empty()) return NULL;
 

	
 
	AIEvent *e = data->stack.front();
 
	data->stack.pop();
 
	return e;
 
}
 

	
 
/* static */ void AIEventController::InsertEvent(AIEvent *event)
 
{
 
	if (AIObject::GetEventPointer() == NULL) AIEventController::CreateEventPointer();
 
	AIEventData *data = (AIEventData *)AIObject::GetEventPointer();
 

	
 
	event->AddRef();
 
	data->stack.push(event);
 
}
 

	
src/ai/api/ai_event.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_event.hpp Everything to handle events from the game. */
 

	
 
#ifndef AI_EVENT_HPP
 
#define AI_EVENT_HPP
 

	
 
#include "ai_object.hpp"
 

	
 
/**
 
 * Class that handles all event related functions.
 
 * You can lookup the type, and than convert it to the real event-class.
 
 * That way you can request more detailed information about the event.
 
 */
 
class AIEvent : public AIObject {
 
public:
 
	static const char *GetClassName() { return "AIEvent"; }
 

	
 
	/**
 
	 * The type of event. Needed to lookup the detailed class.
 
	 */
 
	enum AIEventType {
 
		AI_ET_INVALID = 0,
 
		AI_ET_TEST,
 
		AI_ET_SUBSIDY_OFFER,
 
		AI_ET_SUBSIDY_OFFER_EXPIRED,
 
		AI_ET_SUBSIDY_AWARDED,
 
		AI_ET_SUBSIDY_EXPIRED,
 
		AI_ET_ENGINE_PREVIEW,
 
		AI_ET_COMPANY_NEW,
 
		AI_ET_COMPANY_IN_TROUBLE,
 
		AI_ET_COMPANY_MERGER,
 
		AI_ET_COMPANY_BANKRUPT,
 
		AI_ET_VEHICLE_CRASHED,
 
		AI_ET_VEHICLE_LOST,
 
		AI_ET_VEHICLE_WAITING_IN_DEPOT,
 
		AI_ET_VEHICLE_UNPROFITABLE,
 
		AI_ET_INDUSTRY_OPEN,
 
		AI_ET_INDUSTRY_CLOSE,
 
		AI_ET_ENGINE_AVAILABLE,
 
		AI_ET_STATION_FIRST_VEHICLE,
 
	};
 

	
 
	/**
 
	 * Constructor of AIEvent, to get the type of event.
 
	 */
 
	AIEvent(AIEvent::AIEventType type) :
 
		type(type)
 
	{}
 

	
 
	/**
 
	 * Get the event-type.
 
	 * @return The @c AIEventType.
 
	 */
 
	AIEventType GetEventType() { return this->type; }
 

	
 
protected:
 
	/**
 
	 * The type of this event.
 
	 */
 
	AIEventType type;
 
};
 

	
 
/**
 
 * Class that handles all event related functions.
 
 * @note it is not needed to create an instance of AIEvent to access it, as
 
 *  all members are static, and all data is stored AI-wide.
 
 */
 
class AIEventController : public AIObject {
 
public:
 
	/**
 
	 * The name of the class, needed by several sub-processes.
 
	 */
 
	static const char *GetClassName() { return "AIEventController"; }
 

	
 
	/**
 
	 * Check if there is an event waiting.
 
	 * @return true if there is an event on the stack.
 
	 */
 
	static bool IsEventWaiting();
 

	
 
	/**
 
	 * Get the next event.
 
	 * @return a class of the event-child issues.
 
	 */
 
	static AIEvent *GetNextEvent();
 

	
 
	/**
 
	 * Insert an event to the queue for the company.
 
	 * @param event The event to insert.
 
	 */
 
	static void InsertEvent(AIEvent *event);
 

	
 
	/**
 
	 * Free the event pointer.
 
	 * @note DO NOT CALL YOURSELF; leave it to the internal AI programming.
 
	 */
 
	static void FreeEventPointer();
 

	
 
private:
 
	/**
 
	 * Create the event pointer.
 
	 */
 
	static void CreateEventPointer();
 
};
 

	
 
#endif /* AI_EVENT_HPP */
src/ai/api/ai_event.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_event.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow enums to be used as Squirrel parameters */
 
	template <> AIEvent::AIEventType GetParam(ForceType<AIEvent::AIEventType>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AIEvent::AIEventType)tmp; }
 
	template <> int Return<AIEvent::AIEventType>(HSQUIRRELVM vm, AIEvent::AIEventType res) { sq_pushinteger(vm, (int32)res); return 1; }
 

	
 
	/* Allow AIEvent to be used as Squirrel parameter */
 
	template <> AIEvent *GetParam(ForceType<AIEvent *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEvent *)instance; }
 
	template <> AIEvent &GetParam(ForceType<AIEvent &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEvent *)instance; }
 
	template <> const AIEvent *GetParam(ForceType<const AIEvent *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEvent *)instance; }
 
	template <> const AIEvent &GetParam(ForceType<const AIEvent &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEvent *)instance; }
 
	template <> int Return<AIEvent *>(HSQUIRRELVM vm, AIEvent *res) { if (res == NULL) { sq_pushnull(vm); return 1; } Squirrel::CreateClassInstanceVM(vm, "AIEvent", res, NULL, DefSQDestructorCallback<AIEvent>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIEvent_Register(Squirrel *engine) {
 
	DefSQClass <AIEvent> SQAIEvent("AIEvent");
 
	SQAIEvent.PreRegister(engine);
 
	SQAIEvent.AddConstructor<void (AIEvent::*)(AIEvent::AIEventType type), 2>(engine, "xi");
 

	
 
	SQAIEvent.DefSQConst(engine, AIEvent::AI_ET_INVALID,                  "AI_ET_INVALID");
 
	SQAIEvent.DefSQConst(engine, AIEvent::AI_ET_TEST,                     "AI_ET_TEST");
 
	SQAIEvent.DefSQConst(engine, AIEvent::AI_ET_SUBSIDY_OFFER,            "AI_ET_SUBSIDY_OFFER");
 
	SQAIEvent.DefSQConst(engine, AIEvent::AI_ET_SUBSIDY_OFFER_EXPIRED,    "AI_ET_SUBSIDY_OFFER_EXPIRED");
 
	SQAIEvent.DefSQConst(engine, AIEvent::AI_ET_SUBSIDY_AWARDED,          "AI_ET_SUBSIDY_AWARDED");
 
	SQAIEvent.DefSQConst(engine, AIEvent::AI_ET_SUBSIDY_EXPIRED,          "AI_ET_SUBSIDY_EXPIRED");
 
	SQAIEvent.DefSQConst(engine, AIEvent::AI_ET_ENGINE_PREVIEW,           "AI_ET_ENGINE_PREVIEW");
 
	SQAIEvent.DefSQConst(engine, AIEvent::AI_ET_COMPANY_NEW,              "AI_ET_COMPANY_NEW");
 
	SQAIEvent.DefSQConst(engine, AIEvent::AI_ET_COMPANY_IN_TROUBLE,       "AI_ET_COMPANY_IN_TROUBLE");
 
	SQAIEvent.DefSQConst(engine, AIEvent::AI_ET_COMPANY_MERGER,           "AI_ET_COMPANY_MERGER");
 
	SQAIEvent.DefSQConst(engine, AIEvent::AI_ET_COMPANY_BANKRUPT,         "AI_ET_COMPANY_BANKRUPT");
 
	SQAIEvent.DefSQConst(engine, AIEvent::AI_ET_VEHICLE_CRASHED,          "AI_ET_VEHICLE_CRASHED");
 
	SQAIEvent.DefSQConst(engine, AIEvent::AI_ET_VEHICLE_LOST,             "AI_ET_VEHICLE_LOST");
 
	SQAIEvent.DefSQConst(engine, AIEvent::AI_ET_VEHICLE_WAITING_IN_DEPOT, "AI_ET_VEHICLE_WAITING_IN_DEPOT");
 
	SQAIEvent.DefSQConst(engine, AIEvent::AI_ET_VEHICLE_UNPROFITABLE,     "AI_ET_VEHICLE_UNPROFITABLE");
 
	SQAIEvent.DefSQConst(engine, AIEvent::AI_ET_INDUSTRY_OPEN,            "AI_ET_INDUSTRY_OPEN");
 
	SQAIEvent.DefSQConst(engine, AIEvent::AI_ET_INDUSTRY_CLOSE,           "AI_ET_INDUSTRY_CLOSE");
 
	SQAIEvent.DefSQConst(engine, AIEvent::AI_ET_ENGINE_AVAILABLE,         "AI_ET_ENGINE_AVAILABLE");
 
	SQAIEvent.DefSQConst(engine, AIEvent::AI_ET_STATION_FIRST_VEHICLE,    "AI_ET_STATION_FIRST_VEHICLE");
 

	
 
	SQAIEvent.DefSQStaticMethod(engine, &AIEvent::GetClassName, "GetClassName", 1, "x");
 

	
 
	SQAIEvent.DefSQMethod(engine, &AIEvent::GetEventType, "GetEventType", 1, "x");
 

	
 
	SQAIEvent.PostRegister(engine);
 
}
 

	
 
namespace SQConvert {
 
	/* Allow AIEventController to be used as Squirrel parameter */
 
	template <> AIEventController *GetParam(ForceType<AIEventController *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEventController *)instance; }
 
	template <> AIEventController &GetParam(ForceType<AIEventController &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventController *)instance; }
 
	template <> const AIEventController *GetParam(ForceType<const AIEventController *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEventController *)instance; }
 
	template <> const AIEventController &GetParam(ForceType<const AIEventController &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventController *)instance; }
 
	template <> int Return<AIEventController *>(HSQUIRRELVM vm, AIEventController *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIEventController", res, NULL, DefSQDestructorCallback<AIEventController>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIEventController_Register(Squirrel *engine) {
 
	DefSQClass <AIEventController> SQAIEventController("AIEventController");
 
	SQAIEventController.PreRegister(engine);
 
	SQAIEventController.AddConstructor<void (AIEventController::*)(), 1>(engine, "x");
 

	
 
	SQAIEventController.DefSQStaticMethod(engine, &AIEventController::GetClassName,     "GetClassName",     1, "x");
 
	SQAIEventController.DefSQStaticMethod(engine, &AIEventController::IsEventWaiting,   "IsEventWaiting",   1, "x");
 
	SQAIEventController.DefSQStaticMethod(engine, &AIEventController::GetNextEvent,     "GetNextEvent",     1, "x");
 
	SQAIEventController.DefSQStaticMethod(engine, &AIEventController::InsertEvent,      "InsertEvent",      2, "xx");
 
	SQAIEventController.DefSQStaticMethod(engine, &AIEventController::FreeEventPointer, "FreeEventPointer", 1, "x");
 

	
 
	SQAIEventController.PostRegister(engine);
 
}
src/ai/api/ai_event_types.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_event_types.cpp Implementation of all EventTypes. */
 

	
 
#include "ai_event_types.hpp"
 
#include "../../openttd.h"
 
#include "../../core/alloc_func.hpp"
 
#include "../../strings_func.h"
 
#include "../../roadveh.h"
 
#include "../../train.h"
 
#include "../../ship.h"
 
#include "../../aircraft.h"
 
#include "../../settings_type.h"
 
#include "../../articulated_vehicles.h"
 
#include "table/strings.h"
 

	
 
bool AIEventVehicleCrashed::CloneCrashedVehicle(TileIndex depot)
 
{
 
	return false;
 
}
 

	
 
const char *AIEventEnginePreview::GetName()
 
{
 
	static const int len = 64;
 
	char *engine_name = MallocT<char>(len);
 

	
 
	::SetDParam(0, engine);
 
	::GetString(engine_name, STR_ENGINE_NAME, &engine_name[len - 1]);
 
	return engine_name;
 
}
 

	
 
CargoID AIEventEnginePreview::GetCargoType()
 
{
 
	switch (::GetEngine(engine)->type) {
 
		case VEH_ROAD: {
 
			const RoadVehicleInfo *vi = ::RoadVehInfo(engine);
 
			return vi->cargo_type;
 
		} break;
 

	
 
		case VEH_TRAIN: {
 
			const RailVehicleInfo *vi = ::RailVehInfo(engine);
 
			return vi->cargo_type;
 
		} break;
 

	
 
		case VEH_SHIP: {
 
			const ShipVehicleInfo *vi = ::ShipVehInfo(engine);
 
			return vi->cargo_type;
 
		} break;
 

	
 
		case VEH_AIRCRAFT: {
 
			return CT_PASSENGERS;
 
		} break;
 

	
 
		default: NOT_REACHED();
 
	}
 
}
 

	
 
int32 AIEventEnginePreview::GetCapacity()
 
{
 
	switch (::GetEngine(engine)->type) {
 
		case VEH_ROAD:
 
		case VEH_TRAIN: {
 
			uint16 *capacities = GetCapacityOfArticulatedParts(engine, ::GetEngine(engine)->type);
 
			for (CargoID c = 0; c < NUM_CARGO; c++) {
 
				if (capacities[c] == 0) continue;
 
				return capacities[c];
 
			}
 
			return -1;
 
		} break;
 

	
 
		case VEH_SHIP: {
 
			const ShipVehicleInfo *vi = ::ShipVehInfo(engine);
 
			return vi->capacity;
 
		} break;
 

	
 
		case VEH_AIRCRAFT: {
 
			const AircraftVehicleInfo *vi = ::AircraftVehInfo(engine);
 
			return vi->passenger_capacity;
 
		} break;
 

	
 
		default: NOT_REACHED();
 
	}
 
}
 

	
 
int32 AIEventEnginePreview::GetMaxSpeed()
 
{
 
	switch (::GetEngine(engine)->type) {
 
		case VEH_ROAD: {
 
			const RoadVehicleInfo *vi = ::RoadVehInfo(engine);
 
			/* Internal speeds are km/h * 2 */
 
			return vi->max_speed / 2;
 
		} break;
 

	
 
		case VEH_TRAIN: {
 
			const RailVehicleInfo *vi = ::RailVehInfo(engine);
 
			return vi->max_speed;
 
		} break;
 

	
 
		case VEH_SHIP: {
 
			const ShipVehicleInfo *vi = ::ShipVehInfo(engine);
 
			/* Internal speeds are km/h * 2 */
 
			return vi->max_speed / 2;
 
		} break;
 

	
 
		case VEH_AIRCRAFT: {
 
			const AircraftVehicleInfo *vi = ::AircraftVehInfo(engine);
 
			return vi->max_speed / _settings_game.vehicle.plane_speed;
 
		} break;
 

	
 
		default: NOT_REACHED();
 
	}
 
}
 

	
 
Money AIEventEnginePreview::GetPrice()
 
{
 
	switch (::GetEngine(engine)->type) {
 
		case VEH_ROAD: {
 
			const RoadVehicleInfo *vi = ::RoadVehInfo(engine);
 
			return (_price.roadveh_base >> 3) * vi->cost_factor >> 5;
 
		} break;
 

	
 
		case VEH_TRAIN: {
 
			const RailVehicleInfo *vi = ::RailVehInfo(engine);
 
			return (_price.build_railvehicle >> 3) * vi->cost_factor >> 5;
 
		} break;
 

	
 
		case VEH_SHIP: {
 
			const ShipVehicleInfo *vi = ::ShipVehInfo(engine);
 
			return (_price.ship_base >> 3) * vi->cost_factor >> 5;
 
		} break;
 

	
 
		case VEH_AIRCRAFT: {
 
			const AircraftVehicleInfo *vi = ::AircraftVehInfo(engine);
 
			return (_price.aircraft_base >> 3) * vi->cost_factor >> 5;
 
		} break;
 

	
 
		default: NOT_REACHED();
 
	}
 
}
 

	
 
Money AIEventEnginePreview::GetRunningCost()
 
{
 
	/* We need to create an instance in order to obtain GetRunningCost.
 
	 *  This means we temporary allocate a vehicle in the pool, but
 
	 *  there is no other way.. */
 
	Vehicle *vehicle;
 
	switch (::GetEngine(engine)->type) {
 
		case VEH_ROAD: {
 
			vehicle = new RoadVehicle();
 
		} break;
 

	
 
		case VEH_TRAIN: {
 
			vehicle = new Train();
 
		} break;
 

	
 
		case VEH_SHIP: {
 
			vehicle = new Ship();
 
		} break;
 

	
 
		case VEH_AIRCRAFT: {
 
			vehicle = new Aircraft();
 
		} break;
 

	
 
		default: NOT_REACHED();
 
	}
 

	
 
	vehicle->engine_type = engine;
 
	Money runningCost = vehicle->GetRunningCost();
 
	delete vehicle;
 
	return runningCost >> 8;
 
}
 

	
 
AIVehicle::VehicleType AIEventEnginePreview::GetVehicleType()
 
{
 
	switch (::GetEngine(engine)->type) {
 
		case VEH_ROAD:     return AIVehicle::VEHICLE_ROAD;
 
		case VEH_TRAIN:    return AIVehicle::VEHICLE_RAIL;
 
		case VEH_SHIP:     return AIVehicle::VEHICLE_WATER;
 
		case VEH_AIRCRAFT: return AIVehicle::VEHICLE_AIR;
 
		default: NOT_REACHED();
 
	}
 
}
 

	
 
bool AIEventEnginePreview::AcceptPreview()
 
{
 
	return AIObject::DoCommand(0, engine, 0, CMD_WANT_ENGINE_PREVIEW);
 
}
src/ai/api/ai_event_types.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_event_types.hpp The detailed types of all events. */
 

	
 
#ifndef AI_EVENT_TYPES_HPP
 
#define AI_EVENT_TYPES_HPP
 

	
 
#include "ai_object.hpp"
 
#include "ai_event.hpp"
 
#include "ai_town.hpp"
 
#include "ai_industry.hpp"
 
#include "ai_engine.hpp"
 
#include "ai_subsidy.hpp"
 

	
 
/**
 
 * Event Test: a simple test event, to see if the event system is working.
 
 *  Triggered via AIEventController::Test();
 
 */
 
class AIEventTest : public AIEvent {
 
public:
 
	static const char *GetClassName() { return "AIEventTest"; }
 

	
 
	/**
 
	 * @param test A test value.
 
	 */
 
	AIEventTest(uint test) :
 
		AIEvent(AI_ET_TEST),
 
		test(test)
 
	{}
 

	
 
	/**
 
	 * Convert an AIEvent to the real instance.
 
	 * @param instance The instance to convert.
 
	 * @return The converted instance.
 
	 */
 
	static AIEventTest *Convert(AIEvent *instance) { return (AIEventTest *)instance; }
 

	
 
	/**
 
	 * Return the test value.
 
	 * @return The test value.
 
	 */
 
	uint GetTest() { return this->test; }
 

	
 
private:
 
	uint test;
 
};
 

	
 
/**
 
 * Event Vehicle Crash, indicating a vehicle of yours is crashed.
 
 *  It contains both the crash site as the vehicle crashed. It has a nice
 
 *  helper that creates a new vehicle in a depot with the same type
 
 *  and orders as the crashed one. In case the vehicle type isn't available
 
 *  anymore, it will find the next best.
 
 */
 
class AIEventVehicleCrashed : public AIEvent {
 
public:
 
	static const char *GetClassName() { return "AIEventVehicleCrashed"; }
 

	
 
	/**
 
	 * @param vehicle The vehicle that crashed.
 
	 * @param crash_site Where the vehicle crashed.
 
	 */
 
	AIEventVehicleCrashed(VehicleID vehicle, TileIndex crash_site) :
 
		AIEvent(AI_ET_VEHICLE_CRASHED),
 
		crash_site(crash_site),
 
		vehicle(vehicle)
 
	{}
 

	
 
	/**
 
	 * Convert an AIEvent to the real instance.
 
	 * @param instance The instance to convert.
 
	 * @return The converted instance.
 
	 */
 
	static AIEventVehicleCrashed *Convert(AIEvent *instance) { return (AIEventVehicleCrashed *)instance; }
 

	
 
	/**
 
	 * Get the VehicleID of the crashed vehicle.
 
	 * @return The crashed vehicle.
 
	 */
 
	VehicleID GetVehicleID() { return vehicle; }
 

	
 
	/**
 
	 * Find the tile the vehicle crashed.
 
	 * @return The crash site.
 
	 */
 
	TileIndex GetCrashSite() { return crash_site; }
 

	
 
	/**
 
	 * Clone the crashed vehicle and send it on its way again.
 
	 * @param depot the depot to build the vehicle in.
 
	 * @return True when the cloning succeeded.
 
	 * @note This function isn't implemented yet.
 
	 */
 
	bool CloneCrashedVehicle(TileIndex depot);
 

	
 
private:
 
	TileIndex crash_site;
 
	VehicleID vehicle;
 
};
 

	
 
/**
 
 * Event Subsidy Offered, indicating someone offered a subsidy.
 
 */
 
class AIEventSubsidyOffer : public AIEvent {
 
public:
 
	static const char *GetClassName() { return "AIEventSubsidyOffer"; }
 

	
 
	/**
 
	 * @param subsidy_id The index of this subsidy in the _subsidies array.
 
	 */
 
	AIEventSubsidyOffer(SubsidyID subsidy_id) :
 
		AIEvent(AI_ET_SUBSIDY_OFFER),
 
		subsidy_id(subsidy_id)
 
	{}
 

	
 
	/**
 
	 * Convert an AIEvent to the real instance.
 
	 * @param instance The instance to convert.
 
	 * @return The converted instance.
 
	 */
 
	static AIEventSubsidyOffer *Convert(AIEvent *instance) { return (AIEventSubsidyOffer *)instance; }
 

	
 
	/**
 
	 * Get the SubsidyID of the subsidy.
 
	 * @return The subsidy id.
 
	 */
 
	SubsidyID GetSubsidyID() { return subsidy_id; }
 

	
 
private:
 
	SubsidyID subsidy_id;
 
};
 

	
 
/**
 
 * Event Subsidy Offer Expired, indicating a subsidy will no longer be awarded.
 
 */
 
class AIEventSubsidyOfferExpired : public AIEvent {
 
public:
 
	static const char *GetClassName() { return "AIEventSubsidyOfferExpired"; }
 

	
 
	/**
 
	 * @param subsidy_id The index of this subsidy in the _subsidies array.
 
	 */
 
	AIEventSubsidyOfferExpired(SubsidyID subsidy_id) :
 
		AIEvent(AI_ET_SUBSIDY_OFFER_EXPIRED),
 
		subsidy_id(subsidy_id)
 
	{}
 

	
 
	/**
 
	 * Convert an AIEvent to the real instance.
 
	 * @param instance The instance to convert.
 
	 * @return The converted instance.
 
	 */
 
	static AIEventSubsidyOfferExpired *Convert(AIEvent *instance) { return (AIEventSubsidyOfferExpired *)instance; }
 

	
 
	/**
 
	 * Get the SubsidyID of the subsidy.
 
	 * @return The subsidy id.
 
	 */
 
	SubsidyID GetSubsidyID() { return subsidy_id; }
 

	
 
private:
 
	SubsidyID subsidy_id;
 
};
 

	
 
/**
 
 * Event Subidy Awarded, indicating a subsidy is awarded to some company.
 
 */
 
class AIEventSubsidyAwarded : public AIEvent {
 
public:
 
	static const char *GetClassName() { return "AIEventSubsidyAwarded"; }
 

	
 
	/**
 
	 * @param subsidy_id The index of this subsidy in the _subsidies array.
 
	 */
 
	AIEventSubsidyAwarded(SubsidyID subsidy_id) :
 
		AIEvent(AI_ET_SUBSIDY_AWARDED),
 
		subsidy_id(subsidy_id)
 
	{}
 

	
 
	/**
 
	 * Convert an AIEvent to the real instance.
 
	 * @param instance The instance to convert.
 
	 * @return The converted instance.
 
	 */
 
	static AIEventSubsidyAwarded *Convert(AIEvent *instance) { return (AIEventSubsidyAwarded *)instance; }
 

	
 
	/**
 
	 * Get the SubsidyID of the subsidy.
 
	 * @return The subsidy id.
 
	 */
 
	SubsidyID GetSubsidyID() { return subsidy_id; }
 

	
 
private:
 
	SubsidyID subsidy_id;
 
};
 

	
 
/**
 
 * Event Subsidy Expired, indicating a route that was once subsidized no longer is.
 
 */
 
class AIEventSubsidyExpired : public AIEvent {
 
public:
 
	static const char *GetClassName() { return "AIEventSubsidyExpired"; }
 

	
 
	/**
 
	 * @param subsidy_id The index of this subsidy in the _subsidies array.
 
	 */
 
	AIEventSubsidyExpired(SubsidyID subsidy_id) :
 
		AIEvent(AI_ET_SUBSIDY_EXPIRED),
 
		subsidy_id(subsidy_id)
 
	{}
 

	
 
	/**
 
	 * Convert an AIEvent to the real instance.
 
	 * @param instance The instance to convert.
 
	 * @return The converted instance.
 
	 */
 
	static AIEventSubsidyExpired *Convert(AIEvent *instance) { return (AIEventSubsidyExpired *)instance; }
 

	
 
	/**
 
	 * Get the SubsidyID of the subsidy.
 
	 * @return The subsidy id.
 
	 */
 
	 SubsidyID GetSubsidyID() { return subsidy_id; }
 

	
 
private:
 
	SubsidyID subsidy_id;
 
};
 

	
 
/**
 
 * Event Engine Preview, indicating a manufacturer offer you to test a new engine.
 
 *  You can get the same information about the offered engine as a real user
 
 *  would see in the offer window. And you can also accept the offer.
 
 */
 
class AIEventEnginePreview : public AIEvent {
 
public:
 
	static const char *GetClassName() { return "AIEventEnginePreview"; }
 

	
 
	/**
 
	 * @param engine The engine offered to test.
 
	 */
 
	AIEventEnginePreview(EngineID engine) :
 
		AIEvent(AI_ET_ENGINE_PREVIEW),
 
		engine(engine)
 
	{}
 

	
 
	/**
 
	 * Convert an AIEvent to the real instance.
 
	 * @param instance The instance to convert.
 
	 * @return The converted instance.
 
	 */
 
	static AIEventEnginePreview *Convert(AIEvent *instance) { return (AIEventEnginePreview *)instance; }
 

	
 
	/**
 
	 * Get the name of the offered engine.
 
	 * @return The name the engine has.
 
	 */
 
	const char *GetName();
 

	
 
	/**
 
	 * Get the cargo-type of the offered engine. In case it can transport 2 cargos, it
 
	 *  returns the first.
 
	 * @return The cargo-type of the engine.
 
	 */
 
	CargoID GetCargoType();
 

	
 
	/**
 
	 * Get the capacity of the offered engine. In case it can transport 2 cargos, it
 
	 *  returns the first.
 
	 * @return The capacity of the engine.
 
	 */
 
	int32 GetCapacity();
 

	
 
	/**
 
	 * Get the maximum speed of the offered engine.
 
	 * @return The maximum speed the engine has.
 
	 * @note The speed is in km/h.
 
	 */
 
	int32 GetMaxSpeed();
 

	
 
	/**
 
	 * Get the new cost of the offered engine.
 
	 * @return The new cost the engine has.
 
	 */
 
	Money GetPrice();
 

	
 
	/**
 
	 * Get the running cost of the offered engine.
 
	 * @return The running cost of the vehicle per year.
 
	 * @note Cost is per year; divide by 364 to get per day.
 
	 */
 
	Money GetRunningCost();
 

	
 
	/**
 
	 * Get the type of the offered engine.
 
	 * @return The type the engine has.
 
	 */
 
	AIVehicle::VehicleType GetVehicleType();
 

	
 
	/**
 
	 * Accept the engine preview.
 
	 * @return True when the accepting succeeded.
 
	 */
 
	bool AcceptPreview();
 

	
 
private:
 
	EngineID engine;
 
};
 

	
 
/**
 
 * Event Company New, indicating a new company has been created.
 
 */
 
class AIEventCompanyNew : public AIEvent {
 
public:
 
	static const char *GetClassName() { return "AIEventCompanyNew"; }
 

	
 
	/**
 
	 * @param owner The new company.
 
	 */
 
	AIEventCompanyNew(Owner owner) :
 
		AIEvent(AI_ET_COMPANY_NEW),
 
		owner((AICompany::CompanyID)(byte)owner)
 
	{}
 

	
 
	/**
 
	 * Convert an AIEvent to the real instance.
 
	 * @param instance The instance to convert.
 
	 * @return The converted instance.
 
	 */
 
	static AIEventCompanyNew *Convert(AIEvent *instance) { return (AIEventCompanyNew *)instance; }
 

	
 
	/**
 
	 * Get the CompanyID of the company that has been created.
 
	 * @return The CompanyID of the company.
 
	 */
 
	AICompany::CompanyID GetCompanyID() { return owner; }
 

	
 
private:
 
	AICompany::CompanyID owner;
 
};
 

	
 
/**
 
 * Event Company In Trouble, indicating a company is in trouble and might go
 
 *  bankrupt soon.
 
 */
 
class AIEventCompanyInTrouble : public AIEvent {
 
public:
 
	static const char *GetClassName() { return "AIEventCompanyInTrouble"; }
 

	
 
	/**
 
	 * @param owner The company that is in trouble.
 
	 */
 
	AIEventCompanyInTrouble(Owner owner) :
 
		AIEvent(AI_ET_COMPANY_IN_TROUBLE),
 
		owner((AICompany::CompanyID)(byte)owner)
 
	{}
 

	
 
	/**
 
	 * Convert an AIEvent to the real instance.
 
	 * @param instance The instance to convert.
 
	 * @return The converted instance.
 
	 */
 
	static AIEventCompanyInTrouble *Convert(AIEvent *instance) { return (AIEventCompanyInTrouble *)instance; }
 

	
 
	/**
 
	 * Get the CompanyID of the company that is in trouble.
 
	 * @return The CompanyID of the company in trouble.
 
	 */
 
	AICompany::CompanyID GetCompanyID() { return owner; }
 

	
 
private:
 
	AICompany::CompanyID owner;
 
};
 

	
 
/**
 
 * Event Company Merger, indicating a company has been bought by another
 
 *  company.
 
 */
 
class AIEventCompanyMerger : public AIEvent {
 
public:
 
	static const char *GetClassName() { return "AIEventCompanyMerger"; }
 

	
 
	/**
 
	 * @param old_owner The company bought off.
 
	 * @param new_owner The company that bougth owner.
 
	 */
 
	AIEventCompanyMerger(Owner old_owner, Owner new_owner) :
 
		AIEvent(AI_ET_COMPANY_MERGER),
 
		old_owner((AICompany::CompanyID)(byte)old_owner),
 
		new_owner((AICompany::CompanyID)(byte)new_owner)
 
	{}
 

	
 
	/**
 
	 * Convert an AIEvent to the real instance.
 
	 * @param instance The instance to convert.
 
	 * @return The converted instance.
 
	 */
 
	static AIEventCompanyMerger *Convert(AIEvent *instance) { return (AIEventCompanyMerger *)instance; }
 

	
 
	/**
 
	 * Get the CompanyID of the company that has been bought.
 
	 * @return The CompanyID of the company that has been bought.
 
	 * @note: The value below is not valid anymore as CompanyID, and
 
	 *  AICompany::ResolveCompanyID will return INVALID_COMPANY. It's
 
	 *  only usefull if you're keeping track of company's yourself.
 
	 */
 
	AICompany::CompanyID GetOldCompanyID() { return old_owner; }
 

	
 
	/**
 
	 * Get the CompanyID of the new owner.
 
	 * @return The CompanyID of the new owner.
 
	 */
 
	AICompany::CompanyID GetNewCompanyID() { return new_owner; }
 

	
 
private:
 
	AICompany::CompanyID old_owner;
 
	AICompany::CompanyID new_owner;
 
};
 

	
 
/**
 
 * Event Company Bankrupt, indicating a company has gone bankrupt.
 
 */
 
class AIEventCompanyBankrupt : public AIEvent {
 
public:
 
	static const char *GetClassName() { return "AIEventCompanyBankrupt"; }
 

	
 
	/**
 
	 * @param owner The company that has gone bankrupt.
 
	 */
 
	AIEventCompanyBankrupt(Owner owner) :
 
		AIEvent(AI_ET_COMPANY_BANKRUPT),
 
		owner((AICompany::CompanyID)(byte)owner)
 
	{}
 

	
 
	/**
 
	 * Convert an AIEvent to the real instance.
 
	 * @param instance The instance to convert.
 
	 * @return The converted instance.
 
	 */
 
	static AIEventCompanyBankrupt *Convert(AIEvent *instance) { return (AIEventCompanyBankrupt *)instance; }
 

	
 
	/**
 
	 * Get the CompanyID of the company that has gone bankrupt.
 
	 * @return The CompanyID of the company that has gone bankrupt.
 
	 */
 
	AICompany::CompanyID GetCompanyID() { return owner; }
 

	
 
private:
 
	AICompany::CompanyID owner;
 
};
 

	
 
/**
 
 * Event Vehicle Lost, indicating a vehicle can't find its way to its destination.
 
 */
 
class AIEventVehicleLost : public AIEvent {
 
public:
 
	static const char *GetClassName() { return "AIEventVehicleLost"; }
 

	
 
	/**
 
	 * @param vehicle_id The vehicle that is lost.
 
	 */
 
	AIEventVehicleLost(VehicleID vehicle_id) :
 
		AIEvent(AI_ET_VEHICLE_LOST),
 
		vehicle_id(vehicle_id)
 
	{}
 

	
 
	/**
 
	 * Convert an AIEvent to the real instance.
 
	 * @param instance The instance to convert.
 
	 * @return The converted instance.
 
	 */
 
	static AIEventVehicleLost *Convert(AIEvent *instance) { return (AIEventVehicleLost *)instance; }
 

	
 
	/**
 
	 * Get the VehicleID of the vehicle that is lost.
 
	 * @return The VehicleID of the vehicle that is lost.
 
	 */
 
	VehicleID GetVehicleID() { return vehicle_id; }
 

	
 
private:
 
	VehicleID vehicle_id;
 
};
 

	
 
/**
 
 * Event VehicleWaitingInDepot, indicating a vehicle has arrived a depot and is now waiting there.
 
 */
 
class AIEventVehicleWaitingInDepot : public AIEvent {
 
public:
 
	static const char *GetClassName() { return "AIEventVehicleWaitingInDepot"; }
 

	
 
	/**
 
	 * @param vehicle_id The vehicle that is waiting in a depot.
 
	 */
 
	AIEventVehicleWaitingInDepot(VehicleID vehicle_id) :
 
		AIEvent(AI_ET_VEHICLE_WAITING_IN_DEPOT),
 
		vehicle_id(vehicle_id)
 
	{}
 

	
 
	/**
 
	 * Convert an AIEvent to the real instance.
 
	 * @param instance The instance to convert.
 
	 * @return The converted instance.
 
	 */
 
	static AIEventVehicleWaitingInDepot *Convert(AIEvent *instance) { return (AIEventVehicleWaitingInDepot *)instance; }
 

	
 
	/**
 
	 * Get the VehicleID of the vehicle that is waiting in a depot.
 
	 * @return The VehicleID of the vehicle that is waiting in a depot.
 
	 */
 
	VehicleID GetVehicleID() { return vehicle_id; }
 

	
 
private:
 
	VehicleID vehicle_id;
 
};
 

	
 
/**
 
 * Event Vehicle Unprofitable, indicating a vehicle lost money last year.
 
 */
 
class AIEventVehicleUnprofitable : public AIEvent {
 
public:
 
	static const char *GetClassName() { return "AIEventVehicleUnprofitable"; }
 

	
 
	/**
 
	 * @param vehicle_id The vehicle that was unprofitable.
 
	 */
 
	AIEventVehicleUnprofitable(VehicleID vehicle_id) :
 
		AIEvent(AI_ET_VEHICLE_UNPROFITABLE),
 
		vehicle_id(vehicle_id)
 
	{}
 

	
 
	/**
 
	 * Convert an AIEvent to the real instance.
 
	 * @param instance The instance to convert.
 
	 * @return The converted instance.
 
	 */
 
	static AIEventVehicleUnprofitable *Convert(AIEvent *instance) { return (AIEventVehicleUnprofitable *)instance; }
 

	
 
	/**
 
	 * Get the VehicleID of the vehicle that lost money.
 
	 * @return The VehicleID of the vehicle that lost money.
 
	 */
 
	VehicleID GetVehicleID() { return vehicle_id; }
 

	
 
private:
 
	VehicleID vehicle_id;
 
};
 

	
 
/**
 
 * Event Industry Open, indicating a new industry has been created.
 
 */
 
class AIEventIndustryOpen : public AIEvent {
 
public:
 
	static const char *GetClassName() { return "AIEventIndustryOpen"; }
 

	
 
	/**
 
	 * @param industry_id The new industry.
 
	 */
 
	AIEventIndustryOpen(IndustryID industry_id) :
 
		AIEvent(AI_ET_INDUSTRY_OPEN),
 
		industry_id(industry_id)
 
	{}
 

	
 
	/**
 
	 * Convert an AIEvent to the real instance.
 
	 * @param instance The instance to convert.
 
	 * @return The converted instance.
 
	 */
 
	static AIEventIndustryOpen *Convert(AIEvent *instance) { return (AIEventIndustryOpen *)instance; }
 

	
 
	/**
 
	 * Get the IndustryID of the new industry.
 
	 * @return The IndustryID of the industry.
 
	 */
 
	IndustryID GetIndustryID() { return industry_id; }
 

	
 
private:
 
	IndustryID industry_id;
 
};
 

	
 
/**
 
 * Event Industry Close, indicating an industry is going to be closed.
 
 */
 
class AIEventIndustryClose : public AIEvent {
 
public:
 
	static const char *GetClassName() { return "AIEventIndustryClose"; }
 

	
 
	/**
 
	 * @param industry_id The new industry.
 
	 */
 
	AIEventIndustryClose(IndustryID industry_id) :
 
		AIEvent(AI_ET_INDUSTRY_CLOSE),
 
		industry_id(industry_id)
 
	{}
 

	
 
	/**
 
	 * Convert an AIEvent to the real instance.
 
	 * @param instance The instance to convert.
 
	 * @return The converted instance.
 
	 */
 
	static AIEventIndustryClose *Convert(AIEvent *instance) { return (AIEventIndustryClose *)instance; }
 

	
 
	/**
 
	 * Get the IndustryID of the closing industry.
 
	 * @return The IndustryID of the industry.
 
	 */
 
	IndustryID GetIndustryID() { return industry_id; }
 

	
 
private:
 
	IndustryID industry_id;
 
};
 

	
 
/**
 
 * Event Engine Available, indicating a new engine is available.
 
 */
 
class AIEventEngineAvailable : public AIEvent {
 
public:
 
	static const char *GetClassName() { return "AIEventEngineAvailable"; }
 

	
 
	/**
 
	 * @param engine The engine that is available.
 
	 */
 
	AIEventEngineAvailable(EngineID engine) :
 
		AIEvent(AI_ET_ENGINE_AVAILABLE),
 
		engine(engine)
 
	{}
 

	
 
	/**
 
	 * Convert an AIEvent to the real instance.
 
	 * @param instance The instance to convert.
 
	 * @return The converted instance.
 
	 */
 
	static AIEventEngineAvailable *Convert(AIEvent *instance) { return (AIEventEngineAvailable *)instance; }
 

	
 
	/**
 
	 * Get the EngineID of the new engine.
 
	 * @return The EngineID of the new engine.
 
	 */
 
	EngineID GetEngineID() { return engine; }
 

	
 
private:
 
	EngineID engine;
 
};
 

	
 
/**
 
 * Event Station First Vehicle, indicating a station has been visited by a vehicle for the first time.
 
 */
 
class AIEventStationFirstVehicle : public AIEvent {
 
public:
 
	static const char *GetClassName() { return "AIEventStationFirstVehicle"; }
 

	
 
	/**
 
	 * @param station The station visited for the first time.
 
	 * @param vehicle The vehicle visiting the station.
 
	 */
 
	AIEventStationFirstVehicle(StationID station, VehicleID vehicle) :
 
		AIEvent(AI_ET_STATION_FIRST_VEHICLE),
 
		station(station),
 
		vehicle(vehicle)
 
	{}
 

	
 
	/**
 
	 * Convert an AIEvent to the real instance.
 
	 * @param instance The instance to convert.
 
	 * @return The converted instance.
 
	 */
 
	static AIEventStationFirstVehicle *Convert(AIEvent *instance) { return (AIEventStationFirstVehicle *)instance; }
 

	
 
	/**
 
	 * Get the StationID of the visited station.
 
	 * @return The StationID of the visited station.
 
	 */
 
	StationID GetStationID() { return station; }
 

	
 
	/**
 
	 * Get the VehicleID of the first vehicle.
 
	 * @return The VehicleID of the first vehicle.
 
	 */
 
	VehicleID GetVehicleID() { return vehicle; }
 

	
 
private:
 
	StationID station;
 
	VehicleID vehicle;
 
};
 

	
 
#endif /* AI_EVENT_TYPES_HPP */
src/ai/api/ai_event_types.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_event_types.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow AIEventTest to be used as Squirrel parameter */
 
	template <> AIEventTest *GetParam(ForceType<AIEventTest *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEventTest *)instance; }
 
	template <> AIEventTest &GetParam(ForceType<AIEventTest &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventTest *)instance; }
 
	template <> const AIEventTest *GetParam(ForceType<const AIEventTest *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEventTest *)instance; }
 
	template <> const AIEventTest &GetParam(ForceType<const AIEventTest &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventTest *)instance; }
 
	template <> int Return<AIEventTest *>(HSQUIRRELVM vm, AIEventTest *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIEventTest", res, NULL, DefSQDestructorCallback<AIEventTest>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIEventTest_Register(Squirrel *engine) {
 
	DefSQClass <AIEventTest> SQAIEventTest("AIEventTest");
 
	SQAIEventTest.PreRegister(engine, "AIEvent");
 

	
 
	SQAIEventTest.DefSQStaticMethod(engine, &AIEventTest::GetClassName, "GetClassName", 1, "x");
 
	SQAIEventTest.DefSQStaticMethod(engine, &AIEventTest::Convert,      "Convert",      2, "xx");
 

	
 
	SQAIEventTest.DefSQMethod(engine, &AIEventTest::GetTest, "GetTest", 1, "x");
 

	
 
	SQAIEventTest.PostRegister(engine);
 
}
 

	
 
namespace SQConvert {
 
	/* Allow AIEventVehicleCrashed to be used as Squirrel parameter */
 
	template <> AIEventVehicleCrashed *GetParam(ForceType<AIEventVehicleCrashed *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEventVehicleCrashed *)instance; }
 
	template <> AIEventVehicleCrashed &GetParam(ForceType<AIEventVehicleCrashed &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventVehicleCrashed *)instance; }
 
	template <> const AIEventVehicleCrashed *GetParam(ForceType<const AIEventVehicleCrashed *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEventVehicleCrashed *)instance; }
 
	template <> const AIEventVehicleCrashed &GetParam(ForceType<const AIEventVehicleCrashed &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventVehicleCrashed *)instance; }
 
	template <> int Return<AIEventVehicleCrashed *>(HSQUIRRELVM vm, AIEventVehicleCrashed *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIEventVehicleCrashed", res, NULL, DefSQDestructorCallback<AIEventVehicleCrashed>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIEventVehicleCrashed_Register(Squirrel *engine) {
 
	DefSQClass <AIEventVehicleCrashed> SQAIEventVehicleCrashed("AIEventVehicleCrashed");
 
	SQAIEventVehicleCrashed.PreRegister(engine, "AIEvent");
 

	
 
	SQAIEventVehicleCrashed.DefSQStaticMethod(engine, &AIEventVehicleCrashed::GetClassName, "GetClassName", 1, "x");
 
	SQAIEventVehicleCrashed.DefSQStaticMethod(engine, &AIEventVehicleCrashed::Convert,      "Convert",      2, "xx");
 

	
 
	SQAIEventVehicleCrashed.DefSQMethod(engine, &AIEventVehicleCrashed::GetVehicleID,        "GetVehicleID",        1, "x");
 
	SQAIEventVehicleCrashed.DefSQMethod(engine, &AIEventVehicleCrashed::GetCrashSite,        "GetCrashSite",        1, "x");
 
	SQAIEventVehicleCrashed.DefSQMethod(engine, &AIEventVehicleCrashed::CloneCrashedVehicle, "CloneCrashedVehicle", 2, "xi");
 

	
 
	SQAIEventVehicleCrashed.PostRegister(engine);
 
}
 

	
 
namespace SQConvert {
 
	/* Allow AIEventSubsidyOffer to be used as Squirrel parameter */
 
	template <> AIEventSubsidyOffer *GetParam(ForceType<AIEventSubsidyOffer *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEventSubsidyOffer *)instance; }
 
	template <> AIEventSubsidyOffer &GetParam(ForceType<AIEventSubsidyOffer &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventSubsidyOffer *)instance; }
 
	template <> const AIEventSubsidyOffer *GetParam(ForceType<const AIEventSubsidyOffer *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEventSubsidyOffer *)instance; }
 
	template <> const AIEventSubsidyOffer &GetParam(ForceType<const AIEventSubsidyOffer &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventSubsidyOffer *)instance; }
 
	template <> int Return<AIEventSubsidyOffer *>(HSQUIRRELVM vm, AIEventSubsidyOffer *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIEventSubsidyOffer", res, NULL, DefSQDestructorCallback<AIEventSubsidyOffer>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIEventSubsidyOffer_Register(Squirrel *engine) {
 
	DefSQClass <AIEventSubsidyOffer> SQAIEventSubsidyOffer("AIEventSubsidyOffer");
 
	SQAIEventSubsidyOffer.PreRegister(engine, "AIEvent");
 

	
 
	SQAIEventSubsidyOffer.DefSQStaticMethod(engine, &AIEventSubsidyOffer::GetClassName, "GetClassName", 1, "x");
 
	SQAIEventSubsidyOffer.DefSQStaticMethod(engine, &AIEventSubsidyOffer::Convert,      "Convert",      2, "xx");
 

	
 
	SQAIEventSubsidyOffer.DefSQMethod(engine, &AIEventSubsidyOffer::GetSubsidyID, "GetSubsidyID", 1, "x");
 

	
 
	SQAIEventSubsidyOffer.PostRegister(engine);
 
}
 

	
 
namespace SQConvert {
 
	/* Allow AIEventSubsidyOfferExpired to be used as Squirrel parameter */
 
	template <> AIEventSubsidyOfferExpired *GetParam(ForceType<AIEventSubsidyOfferExpired *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEventSubsidyOfferExpired *)instance; }
 
	template <> AIEventSubsidyOfferExpired &GetParam(ForceType<AIEventSubsidyOfferExpired &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventSubsidyOfferExpired *)instance; }
 
	template <> const AIEventSubsidyOfferExpired *GetParam(ForceType<const AIEventSubsidyOfferExpired *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEventSubsidyOfferExpired *)instance; }
 
	template <> const AIEventSubsidyOfferExpired &GetParam(ForceType<const AIEventSubsidyOfferExpired &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventSubsidyOfferExpired *)instance; }
 
	template <> int Return<AIEventSubsidyOfferExpired *>(HSQUIRRELVM vm, AIEventSubsidyOfferExpired *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIEventSubsidyOfferExpired", res, NULL, DefSQDestructorCallback<AIEventSubsidyOfferExpired>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIEventSubsidyOfferExpired_Register(Squirrel *engine) {
 
	DefSQClass <AIEventSubsidyOfferExpired> SQAIEventSubsidyOfferExpired("AIEventSubsidyOfferExpired");
 
	SQAIEventSubsidyOfferExpired.PreRegister(engine, "AIEvent");
 

	
 
	SQAIEventSubsidyOfferExpired.DefSQStaticMethod(engine, &AIEventSubsidyOfferExpired::GetClassName, "GetClassName", 1, "x");
 
	SQAIEventSubsidyOfferExpired.DefSQStaticMethod(engine, &AIEventSubsidyOfferExpired::Convert,      "Convert",      2, "xx");
 

	
 
	SQAIEventSubsidyOfferExpired.DefSQMethod(engine, &AIEventSubsidyOfferExpired::GetSubsidyID, "GetSubsidyID", 1, "x");
 

	
 
	SQAIEventSubsidyOfferExpired.PostRegister(engine);
 
}
 

	
 
namespace SQConvert {
 
	/* Allow AIEventSubsidyAwarded to be used as Squirrel parameter */
 
	template <> AIEventSubsidyAwarded *GetParam(ForceType<AIEventSubsidyAwarded *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEventSubsidyAwarded *)instance; }
 
	template <> AIEventSubsidyAwarded &GetParam(ForceType<AIEventSubsidyAwarded &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventSubsidyAwarded *)instance; }
 
	template <> const AIEventSubsidyAwarded *GetParam(ForceType<const AIEventSubsidyAwarded *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEventSubsidyAwarded *)instance; }
 
	template <> const AIEventSubsidyAwarded &GetParam(ForceType<const AIEventSubsidyAwarded &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventSubsidyAwarded *)instance; }
 
	template <> int Return<AIEventSubsidyAwarded *>(HSQUIRRELVM vm, AIEventSubsidyAwarded *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIEventSubsidyAwarded", res, NULL, DefSQDestructorCallback<AIEventSubsidyAwarded>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIEventSubsidyAwarded_Register(Squirrel *engine) {
 
	DefSQClass <AIEventSubsidyAwarded> SQAIEventSubsidyAwarded("AIEventSubsidyAwarded");
 
	SQAIEventSubsidyAwarded.PreRegister(engine, "AIEvent");
 

	
 
	SQAIEventSubsidyAwarded.DefSQStaticMethod(engine, &AIEventSubsidyAwarded::GetClassName, "GetClassName", 1, "x");
 
	SQAIEventSubsidyAwarded.DefSQStaticMethod(engine, &AIEventSubsidyAwarded::Convert,      "Convert",      2, "xx");
 

	
 
	SQAIEventSubsidyAwarded.DefSQMethod(engine, &AIEventSubsidyAwarded::GetSubsidyID, "GetSubsidyID", 1, "x");
 

	
 
	SQAIEventSubsidyAwarded.PostRegister(engine);
 
}
 

	
 
namespace SQConvert {
 
	/* Allow AIEventSubsidyExpired to be used as Squirrel parameter */
 
	template <> AIEventSubsidyExpired *GetParam(ForceType<AIEventSubsidyExpired *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEventSubsidyExpired *)instance; }
 
	template <> AIEventSubsidyExpired &GetParam(ForceType<AIEventSubsidyExpired &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventSubsidyExpired *)instance; }
 
	template <> const AIEventSubsidyExpired *GetParam(ForceType<const AIEventSubsidyExpired *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEventSubsidyExpired *)instance; }
 
	template <> const AIEventSubsidyExpired &GetParam(ForceType<const AIEventSubsidyExpired &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventSubsidyExpired *)instance; }
 
	template <> int Return<AIEventSubsidyExpired *>(HSQUIRRELVM vm, AIEventSubsidyExpired *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIEventSubsidyExpired", res, NULL, DefSQDestructorCallback<AIEventSubsidyExpired>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIEventSubsidyExpired_Register(Squirrel *engine) {
 
	DefSQClass <AIEventSubsidyExpired> SQAIEventSubsidyExpired("AIEventSubsidyExpired");
 
	SQAIEventSubsidyExpired.PreRegister(engine, "AIEvent");
 

	
 
	SQAIEventSubsidyExpired.DefSQStaticMethod(engine, &AIEventSubsidyExpired::GetClassName, "GetClassName", 1, "x");
 
	SQAIEventSubsidyExpired.DefSQStaticMethod(engine, &AIEventSubsidyExpired::Convert,      "Convert",      2, "xx");
 

	
 
	SQAIEventSubsidyExpired.DefSQMethod(engine, &AIEventSubsidyExpired::GetSubsidyID, "GetSubsidyID", 1, "x");
 

	
 
	SQAIEventSubsidyExpired.PostRegister(engine);
 
}
 

	
 
namespace SQConvert {
 
	/* Allow AIEventEnginePreview to be used as Squirrel parameter */
 
	template <> AIEventEnginePreview *GetParam(ForceType<AIEventEnginePreview *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEventEnginePreview *)instance; }
 
	template <> AIEventEnginePreview &GetParam(ForceType<AIEventEnginePreview &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventEnginePreview *)instance; }
 
	template <> const AIEventEnginePreview *GetParam(ForceType<const AIEventEnginePreview *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEventEnginePreview *)instance; }
 
	template <> const AIEventEnginePreview &GetParam(ForceType<const AIEventEnginePreview &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventEnginePreview *)instance; }
 
	template <> int Return<AIEventEnginePreview *>(HSQUIRRELVM vm, AIEventEnginePreview *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIEventEnginePreview", res, NULL, DefSQDestructorCallback<AIEventEnginePreview>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIEventEnginePreview_Register(Squirrel *engine) {
 
	DefSQClass <AIEventEnginePreview> SQAIEventEnginePreview("AIEventEnginePreview");
 
	SQAIEventEnginePreview.PreRegister(engine, "AIEvent");
 

	
 
	SQAIEventEnginePreview.DefSQStaticMethod(engine, &AIEventEnginePreview::GetClassName, "GetClassName", 1, "x");
 
	SQAIEventEnginePreview.DefSQStaticMethod(engine, &AIEventEnginePreview::Convert,      "Convert",      2, "xx");
 

	
 
	SQAIEventEnginePreview.DefSQMethod(engine, &AIEventEnginePreview::GetName,        "GetName",        1, "x");
 
	SQAIEventEnginePreview.DefSQMethod(engine, &AIEventEnginePreview::GetCargoType,   "GetCargoType",   1, "x");
 
	SQAIEventEnginePreview.DefSQMethod(engine, &AIEventEnginePreview::GetCapacity,    "GetCapacity",    1, "x");
 
	SQAIEventEnginePreview.DefSQMethod(engine, &AIEventEnginePreview::GetMaxSpeed,    "GetMaxSpeed",    1, "x");
 
	SQAIEventEnginePreview.DefSQMethod(engine, &AIEventEnginePreview::GetPrice,       "GetPrice",       1, "x");
 
	SQAIEventEnginePreview.DefSQMethod(engine, &AIEventEnginePreview::GetRunningCost, "GetRunningCost", 1, "x");
 
	SQAIEventEnginePreview.DefSQMethod(engine, &AIEventEnginePreview::GetVehicleType, "GetVehicleType", 1, "x");
 
	SQAIEventEnginePreview.DefSQMethod(engine, &AIEventEnginePreview::AcceptPreview,  "AcceptPreview",  1, "x");
 

	
 
	SQAIEventEnginePreview.PostRegister(engine);
 
}
 

	
 
namespace SQConvert {
 
	/* Allow AIEventCompanyNew to be used as Squirrel parameter */
 
	template <> AIEventCompanyNew *GetParam(ForceType<AIEventCompanyNew *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEventCompanyNew *)instance; }
 
	template <> AIEventCompanyNew &GetParam(ForceType<AIEventCompanyNew &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventCompanyNew *)instance; }
 
	template <> const AIEventCompanyNew *GetParam(ForceType<const AIEventCompanyNew *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEventCompanyNew *)instance; }
 
	template <> const AIEventCompanyNew &GetParam(ForceType<const AIEventCompanyNew &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventCompanyNew *)instance; }
 
	template <> int Return<AIEventCompanyNew *>(HSQUIRRELVM vm, AIEventCompanyNew *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIEventCompanyNew", res, NULL, DefSQDestructorCallback<AIEventCompanyNew>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIEventCompanyNew_Register(Squirrel *engine) {
 
	DefSQClass <AIEventCompanyNew> SQAIEventCompanyNew("AIEventCompanyNew");
 
	SQAIEventCompanyNew.PreRegister(engine, "AIEvent");
 

	
 
	SQAIEventCompanyNew.DefSQStaticMethod(engine, &AIEventCompanyNew::GetClassName, "GetClassName", 1, "x");
 
	SQAIEventCompanyNew.DefSQStaticMethod(engine, &AIEventCompanyNew::Convert,      "Convert",      2, "xx");
 

	
 
	SQAIEventCompanyNew.DefSQMethod(engine, &AIEventCompanyNew::GetCompanyID, "GetCompanyID", 1, "x");
 

	
 
	SQAIEventCompanyNew.PostRegister(engine);
 
}
 

	
 
namespace SQConvert {
 
	/* Allow AIEventCompanyInTrouble to be used as Squirrel parameter */
 
	template <> AIEventCompanyInTrouble *GetParam(ForceType<AIEventCompanyInTrouble *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEventCompanyInTrouble *)instance; }
 
	template <> AIEventCompanyInTrouble &GetParam(ForceType<AIEventCompanyInTrouble &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventCompanyInTrouble *)instance; }
 
	template <> const AIEventCompanyInTrouble *GetParam(ForceType<const AIEventCompanyInTrouble *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEventCompanyInTrouble *)instance; }
 
	template <> const AIEventCompanyInTrouble &GetParam(ForceType<const AIEventCompanyInTrouble &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventCompanyInTrouble *)instance; }
 
	template <> int Return<AIEventCompanyInTrouble *>(HSQUIRRELVM vm, AIEventCompanyInTrouble *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIEventCompanyInTrouble", res, NULL, DefSQDestructorCallback<AIEventCompanyInTrouble>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIEventCompanyInTrouble_Register(Squirrel *engine) {
 
	DefSQClass <AIEventCompanyInTrouble> SQAIEventCompanyInTrouble("AIEventCompanyInTrouble");
 
	SQAIEventCompanyInTrouble.PreRegister(engine, "AIEvent");
 

	
 
	SQAIEventCompanyInTrouble.DefSQStaticMethod(engine, &AIEventCompanyInTrouble::GetClassName, "GetClassName", 1, "x");
 
	SQAIEventCompanyInTrouble.DefSQStaticMethod(engine, &AIEventCompanyInTrouble::Convert,      "Convert",      2, "xx");
 

	
 
	SQAIEventCompanyInTrouble.DefSQMethod(engine, &AIEventCompanyInTrouble::GetCompanyID, "GetCompanyID", 1, "x");
 

	
 
	SQAIEventCompanyInTrouble.PostRegister(engine);
 
}
 

	
 
namespace SQConvert {
 
	/* Allow AIEventCompanyMerger to be used as Squirrel parameter */
 
	template <> AIEventCompanyMerger *GetParam(ForceType<AIEventCompanyMerger *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEventCompanyMerger *)instance; }
 
	template <> AIEventCompanyMerger &GetParam(ForceType<AIEventCompanyMerger &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventCompanyMerger *)instance; }
 
	template <> const AIEventCompanyMerger *GetParam(ForceType<const AIEventCompanyMerger *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEventCompanyMerger *)instance; }
 
	template <> const AIEventCompanyMerger &GetParam(ForceType<const AIEventCompanyMerger &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventCompanyMerger *)instance; }
 
	template <> int Return<AIEventCompanyMerger *>(HSQUIRRELVM vm, AIEventCompanyMerger *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIEventCompanyMerger", res, NULL, DefSQDestructorCallback<AIEventCompanyMerger>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIEventCompanyMerger_Register(Squirrel *engine) {
 
	DefSQClass <AIEventCompanyMerger> SQAIEventCompanyMerger("AIEventCompanyMerger");
 
	SQAIEventCompanyMerger.PreRegister(engine, "AIEvent");
 

	
 
	SQAIEventCompanyMerger.DefSQStaticMethod(engine, &AIEventCompanyMerger::GetClassName, "GetClassName", 1, "x");
 
	SQAIEventCompanyMerger.DefSQStaticMethod(engine, &AIEventCompanyMerger::Convert,      "Convert",      2, "xx");
 

	
 
	SQAIEventCompanyMerger.DefSQMethod(engine, &AIEventCompanyMerger::GetOldCompanyID, "GetOldCompanyID", 1, "x");
 
	SQAIEventCompanyMerger.DefSQMethod(engine, &AIEventCompanyMerger::GetNewCompanyID, "GetNewCompanyID", 1, "x");
 

	
 
	SQAIEventCompanyMerger.PostRegister(engine);
 
}
 

	
 
namespace SQConvert {
 
	/* Allow AIEventCompanyBankrupt to be used as Squirrel parameter */
 
	template <> AIEventCompanyBankrupt *GetParam(ForceType<AIEventCompanyBankrupt *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEventCompanyBankrupt *)instance; }
 
	template <> AIEventCompanyBankrupt &GetParam(ForceType<AIEventCompanyBankrupt &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventCompanyBankrupt *)instance; }
 
	template <> const AIEventCompanyBankrupt *GetParam(ForceType<const AIEventCompanyBankrupt *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEventCompanyBankrupt *)instance; }
 
	template <> const AIEventCompanyBankrupt &GetParam(ForceType<const AIEventCompanyBankrupt &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventCompanyBankrupt *)instance; }
 
	template <> int Return<AIEventCompanyBankrupt *>(HSQUIRRELVM vm, AIEventCompanyBankrupt *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIEventCompanyBankrupt", res, NULL, DefSQDestructorCallback<AIEventCompanyBankrupt>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIEventCompanyBankrupt_Register(Squirrel *engine) {
 
	DefSQClass <AIEventCompanyBankrupt> SQAIEventCompanyBankrupt("AIEventCompanyBankrupt");
 
	SQAIEventCompanyBankrupt.PreRegister(engine, "AIEvent");
 

	
 
	SQAIEventCompanyBankrupt.DefSQStaticMethod(engine, &AIEventCompanyBankrupt::GetClassName, "GetClassName", 1, "x");
 
	SQAIEventCompanyBankrupt.DefSQStaticMethod(engine, &AIEventCompanyBankrupt::Convert,      "Convert",      2, "xx");
 

	
 
	SQAIEventCompanyBankrupt.DefSQMethod(engine, &AIEventCompanyBankrupt::GetCompanyID, "GetCompanyID", 1, "x");
 

	
 
	SQAIEventCompanyBankrupt.PostRegister(engine);
 
}
 

	
 
namespace SQConvert {
 
	/* Allow AIEventVehicleLost to be used as Squirrel parameter */
 
	template <> AIEventVehicleLost *GetParam(ForceType<AIEventVehicleLost *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEventVehicleLost *)instance; }
 
	template <> AIEventVehicleLost &GetParam(ForceType<AIEventVehicleLost &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventVehicleLost *)instance; }
 
	template <> const AIEventVehicleLost *GetParam(ForceType<const AIEventVehicleLost *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEventVehicleLost *)instance; }
 
	template <> const AIEventVehicleLost &GetParam(ForceType<const AIEventVehicleLost &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventVehicleLost *)instance; }
 
	template <> int Return<AIEventVehicleLost *>(HSQUIRRELVM vm, AIEventVehicleLost *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIEventVehicleLost", res, NULL, DefSQDestructorCallback<AIEventVehicleLost>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIEventVehicleLost_Register(Squirrel *engine) {
 
	DefSQClass <AIEventVehicleLost> SQAIEventVehicleLost("AIEventVehicleLost");
 
	SQAIEventVehicleLost.PreRegister(engine, "AIEvent");
 

	
 
	SQAIEventVehicleLost.DefSQStaticMethod(engine, &AIEventVehicleLost::GetClassName, "GetClassName", 1, "x");
 
	SQAIEventVehicleLost.DefSQStaticMethod(engine, &AIEventVehicleLost::Convert,      "Convert",      2, "xx");
 

	
 
	SQAIEventVehicleLost.DefSQMethod(engine, &AIEventVehicleLost::GetVehicleID, "GetVehicleID", 1, "x");
 

	
 
	SQAIEventVehicleLost.PostRegister(engine);
 
}
 

	
 
namespace SQConvert {
 
	/* Allow AIEventVehicleWaitingInDepot to be used as Squirrel parameter */
 
	template <> AIEventVehicleWaitingInDepot *GetParam(ForceType<AIEventVehicleWaitingInDepot *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEventVehicleWaitingInDepot *)instance; }
 
	template <> AIEventVehicleWaitingInDepot &GetParam(ForceType<AIEventVehicleWaitingInDepot &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventVehicleWaitingInDepot *)instance; }
 
	template <> const AIEventVehicleWaitingInDepot *GetParam(ForceType<const AIEventVehicleWaitingInDepot *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEventVehicleWaitingInDepot *)instance; }
 
	template <> const AIEventVehicleWaitingInDepot &GetParam(ForceType<const AIEventVehicleWaitingInDepot &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventVehicleWaitingInDepot *)instance; }
 
	template <> int Return<AIEventVehicleWaitingInDepot *>(HSQUIRRELVM vm, AIEventVehicleWaitingInDepot *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIEventVehicleWaitingInDepot", res, NULL, DefSQDestructorCallback<AIEventVehicleWaitingInDepot>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIEventVehicleWaitingInDepot_Register(Squirrel *engine) {
 
	DefSQClass <AIEventVehicleWaitingInDepot> SQAIEventVehicleWaitingInDepot("AIEventVehicleWaitingInDepot");
 
	SQAIEventVehicleWaitingInDepot.PreRegister(engine, "AIEvent");
 

	
 
	SQAIEventVehicleWaitingInDepot.DefSQStaticMethod(engine, &AIEventVehicleWaitingInDepot::GetClassName, "GetClassName", 1, "x");
 
	SQAIEventVehicleWaitingInDepot.DefSQStaticMethod(engine, &AIEventVehicleWaitingInDepot::Convert,      "Convert",      2, "xx");
 

	
 
	SQAIEventVehicleWaitingInDepot.DefSQMethod(engine, &AIEventVehicleWaitingInDepot::GetVehicleID, "GetVehicleID", 1, "x");
 

	
 
	SQAIEventVehicleWaitingInDepot.PostRegister(engine);
 
}
 

	
 
namespace SQConvert {
 
	/* Allow AIEventVehicleUnprofitable to be used as Squirrel parameter */
 
	template <> AIEventVehicleUnprofitable *GetParam(ForceType<AIEventVehicleUnprofitable *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEventVehicleUnprofitable *)instance; }
 
	template <> AIEventVehicleUnprofitable &GetParam(ForceType<AIEventVehicleUnprofitable &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventVehicleUnprofitable *)instance; }
 
	template <> const AIEventVehicleUnprofitable *GetParam(ForceType<const AIEventVehicleUnprofitable *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEventVehicleUnprofitable *)instance; }
 
	template <> const AIEventVehicleUnprofitable &GetParam(ForceType<const AIEventVehicleUnprofitable &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventVehicleUnprofitable *)instance; }
 
	template <> int Return<AIEventVehicleUnprofitable *>(HSQUIRRELVM vm, AIEventVehicleUnprofitable *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIEventVehicleUnprofitable", res, NULL, DefSQDestructorCallback<AIEventVehicleUnprofitable>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIEventVehicleUnprofitable_Register(Squirrel *engine) {
 
	DefSQClass <AIEventVehicleUnprofitable> SQAIEventVehicleUnprofitable("AIEventVehicleUnprofitable");
 
	SQAIEventVehicleUnprofitable.PreRegister(engine, "AIEvent");
 

	
 
	SQAIEventVehicleUnprofitable.DefSQStaticMethod(engine, &AIEventVehicleUnprofitable::GetClassName, "GetClassName", 1, "x");
 
	SQAIEventVehicleUnprofitable.DefSQStaticMethod(engine, &AIEventVehicleUnprofitable::Convert,      "Convert",      2, "xx");
 

	
 
	SQAIEventVehicleUnprofitable.DefSQMethod(engine, &AIEventVehicleUnprofitable::GetVehicleID, "GetVehicleID", 1, "x");
 

	
 
	SQAIEventVehicleUnprofitable.PostRegister(engine);
 
}
 

	
 
namespace SQConvert {
 
	/* Allow AIEventIndustryOpen to be used as Squirrel parameter */
 
	template <> AIEventIndustryOpen *GetParam(ForceType<AIEventIndustryOpen *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEventIndustryOpen *)instance; }
 
	template <> AIEventIndustryOpen &GetParam(ForceType<AIEventIndustryOpen &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventIndustryOpen *)instance; }
 
	template <> const AIEventIndustryOpen *GetParam(ForceType<const AIEventIndustryOpen *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEventIndustryOpen *)instance; }
 
	template <> const AIEventIndustryOpen &GetParam(ForceType<const AIEventIndustryOpen &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventIndustryOpen *)instance; }
 
	template <> int Return<AIEventIndustryOpen *>(HSQUIRRELVM vm, AIEventIndustryOpen *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIEventIndustryOpen", res, NULL, DefSQDestructorCallback<AIEventIndustryOpen>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIEventIndustryOpen_Register(Squirrel *engine) {
 
	DefSQClass <AIEventIndustryOpen> SQAIEventIndustryOpen("AIEventIndustryOpen");
 
	SQAIEventIndustryOpen.PreRegister(engine, "AIEvent");
 

	
 
	SQAIEventIndustryOpen.DefSQStaticMethod(engine, &AIEventIndustryOpen::GetClassName, "GetClassName", 1, "x");
 
	SQAIEventIndustryOpen.DefSQStaticMethod(engine, &AIEventIndustryOpen::Convert,      "Convert",      2, "xx");
 

	
 
	SQAIEventIndustryOpen.DefSQMethod(engine, &AIEventIndustryOpen::GetIndustryID, "GetIndustryID", 1, "x");
 

	
 
	SQAIEventIndustryOpen.PostRegister(engine);
 
}
 

	
 
namespace SQConvert {
 
	/* Allow AIEventIndustryClose to be used as Squirrel parameter */
 
	template <> AIEventIndustryClose *GetParam(ForceType<AIEventIndustryClose *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEventIndustryClose *)instance; }
 
	template <> AIEventIndustryClose &GetParam(ForceType<AIEventIndustryClose &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventIndustryClose *)instance; }
 
	template <> const AIEventIndustryClose *GetParam(ForceType<const AIEventIndustryClose *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEventIndustryClose *)instance; }
 
	template <> const AIEventIndustryClose &GetParam(ForceType<const AIEventIndustryClose &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventIndustryClose *)instance; }
 
	template <> int Return<AIEventIndustryClose *>(HSQUIRRELVM vm, AIEventIndustryClose *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIEventIndustryClose", res, NULL, DefSQDestructorCallback<AIEventIndustryClose>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIEventIndustryClose_Register(Squirrel *engine) {
 
	DefSQClass <AIEventIndustryClose> SQAIEventIndustryClose("AIEventIndustryClose");
 
	SQAIEventIndustryClose.PreRegister(engine, "AIEvent");
 

	
 
	SQAIEventIndustryClose.DefSQStaticMethod(engine, &AIEventIndustryClose::GetClassName, "GetClassName", 1, "x");
 
	SQAIEventIndustryClose.DefSQStaticMethod(engine, &AIEventIndustryClose::Convert,      "Convert",      2, "xx");
 

	
 
	SQAIEventIndustryClose.DefSQMethod(engine, &AIEventIndustryClose::GetIndustryID, "GetIndustryID", 1, "x");
 

	
 
	SQAIEventIndustryClose.PostRegister(engine);
 
}
 

	
 
namespace SQConvert {
 
	/* Allow AIEventEngineAvailable to be used as Squirrel parameter */
 
	template <> AIEventEngineAvailable *GetParam(ForceType<AIEventEngineAvailable *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEventEngineAvailable *)instance; }
 
	template <> AIEventEngineAvailable &GetParam(ForceType<AIEventEngineAvailable &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventEngineAvailable *)instance; }
 
	template <> const AIEventEngineAvailable *GetParam(ForceType<const AIEventEngineAvailable *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEventEngineAvailable *)instance; }
 
	template <> const AIEventEngineAvailable &GetParam(ForceType<const AIEventEngineAvailable &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventEngineAvailable *)instance; }
 
	template <> int Return<AIEventEngineAvailable *>(HSQUIRRELVM vm, AIEventEngineAvailable *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIEventEngineAvailable", res, NULL, DefSQDestructorCallback<AIEventEngineAvailable>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIEventEngineAvailable_Register(Squirrel *engine) {
 
	DefSQClass <AIEventEngineAvailable> SQAIEventEngineAvailable("AIEventEngineAvailable");
 
	SQAIEventEngineAvailable.PreRegister(engine, "AIEvent");
 

	
 
	SQAIEventEngineAvailable.DefSQStaticMethod(engine, &AIEventEngineAvailable::GetClassName, "GetClassName", 1, "x");
 
	SQAIEventEngineAvailable.DefSQStaticMethod(engine, &AIEventEngineAvailable::Convert,      "Convert",      2, "xx");
 

	
 
	SQAIEventEngineAvailable.DefSQMethod(engine, &AIEventEngineAvailable::GetEngineID, "GetEngineID", 1, "x");
 

	
 
	SQAIEventEngineAvailable.PostRegister(engine);
 
}
 

	
 
namespace SQConvert {
 
	/* Allow AIEventStationFirstVehicle to be used as Squirrel parameter */
 
	template <> AIEventStationFirstVehicle *GetParam(ForceType<AIEventStationFirstVehicle *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEventStationFirstVehicle *)instance; }
 
	template <> AIEventStationFirstVehicle &GetParam(ForceType<AIEventStationFirstVehicle &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventStationFirstVehicle *)instance; }
 
	template <> const AIEventStationFirstVehicle *GetParam(ForceType<const AIEventStationFirstVehicle *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEventStationFirstVehicle *)instance; }
 
	template <> const AIEventStationFirstVehicle &GetParam(ForceType<const AIEventStationFirstVehicle &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventStationFirstVehicle *)instance; }
 
	template <> int Return<AIEventStationFirstVehicle *>(HSQUIRRELVM vm, AIEventStationFirstVehicle *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIEventStationFirstVehicle", res, NULL, DefSQDestructorCallback<AIEventStationFirstVehicle>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIEventStationFirstVehicle_Register(Squirrel *engine) {
 
	DefSQClass <AIEventStationFirstVehicle> SQAIEventStationFirstVehicle("AIEventStationFirstVehicle");
 
	SQAIEventStationFirstVehicle.PreRegister(engine, "AIEvent");
 

	
 
	SQAIEventStationFirstVehicle.DefSQStaticMethod(engine, &AIEventStationFirstVehicle::GetClassName, "GetClassName", 1, "x");
 
	SQAIEventStationFirstVehicle.DefSQStaticMethod(engine, &AIEventStationFirstVehicle::Convert,      "Convert",      2, "xx");
 

	
 
	SQAIEventStationFirstVehicle.DefSQMethod(engine, &AIEventStationFirstVehicle::GetStationID, "GetStationID", 1, "x");
 
	SQAIEventStationFirstVehicle.DefSQMethod(engine, &AIEventStationFirstVehicle::GetVehicleID, "GetVehicleID", 1, "x");
 

	
 
	SQAIEventStationFirstVehicle.PostRegister(engine);
 
}
src/ai/api/ai_execmode.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_execmode.cpp Implementation of AIExecMode. */
 

	
 
#include "ai_execmode.hpp"
 
#include "../../command_type.h"
 

	
 
bool AIExecMode::ModeProc(TileIndex tile, uint32 p1, uint32 p2, uint procc, CommandCost costs)
 
{
 
	/* In execution mode we only return 'true', telling the DoCommand it
 
	 *  should continue with the real execution of the command. */
 
	return true;
 
}
 

	
 
AIExecMode::AIExecMode()
 
{
 
	this->last_mode     = this->GetDoCommandMode();
 
	this->last_instance = this->GetDoCommandModeInstance();
 
	this->SetDoCommandMode(&AIExecMode::ModeProc, this);
 
}
 

	
 
AIExecMode::~AIExecMode()
 
{
 
	assert(this->GetDoCommandModeInstance() == this);
 
	this->SetDoCommandMode(this->last_mode, this->last_instance);
 
}
src/ai/api/ai_execmode.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_execmode.hpp Switch the AI to Execute Mode. */
 

	
 
#ifndef AI_EXECMODE_HPP
 
#define AI_EXECMODE_HPP
 

	
 
#include "ai_object.hpp"
 

	
 
/**
 
 * Class to switch current mode to Execute Mode.
 
 * If you create an instance of this class, the mode will be switched to
 
 *   Execute. The original mode is stored and recovered from when ever the
 
 *   instance is destroyed.
 
 * In Execute mode all commands you do are executed for real.
 
 */
 
class AIExecMode : public AIObject {
 
public:
 
	static const char *GetClassName() { return "AIExecMode"; }
 

	
 
private:
 
	AIModeProc *last_mode;
 
	AIObject *last_instance;
 

	
 
protected:
 
	/**
 
	 * The callback proc for Execute mode.
 
	 */
 
	static bool ModeProc(TileIndex tile, uint32 p1, uint32 p2, uint procc, CommandCost costs);
 

	
 
public:
 
	/**
 
	 * Creating instance of this class switches the build mode to Execute.
 
	 * @note When the instance is destroyed, he restores the mode that was
 
	 *   current when the instance was created!
 
	 */
 
	AIExecMode();
 

	
 
	/**
 
	 * Destroying this instance reset the building mode to the mode it was
 
	 *   in when the instance was created.
 
	 */
 
	~AIExecMode();
 
};
 

	
 
#endif /* AI_EXECMODE_HPP */
src/ai/api/ai_execmode.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_execmode.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow AIExecMode to be used as Squirrel parameter */
 
	template <> AIExecMode *GetParam(ForceType<AIExecMode *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIExecMode *)instance; }
 
	template <> AIExecMode &GetParam(ForceType<AIExecMode &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIExecMode *)instance; }
 
	template <> const AIExecMode *GetParam(ForceType<const AIExecMode *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIExecMode *)instance; }
 
	template <> const AIExecMode &GetParam(ForceType<const AIExecMode &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIExecMode *)instance; }
 
	template <> int Return<AIExecMode *>(HSQUIRRELVM vm, AIExecMode *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIExecMode", res, NULL, DefSQDestructorCallback<AIExecMode>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIExecMode_Register(Squirrel *engine) {
 
	DefSQClass <AIExecMode> SQAIExecMode("AIExecMode");
 
	SQAIExecMode.PreRegister(engine);
 
	SQAIExecMode.AddConstructor<void (AIExecMode::*)(), 1>(engine, "x");
 

	
 
	SQAIExecMode.DefSQStaticMethod(engine, &AIExecMode::GetClassName, "GetClassName", 1, "x");
 

	
 
	SQAIExecMode.PostRegister(engine);
 
}
src/ai/api/ai_gamesettings.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_gamesettings.cpp Implementation of AIGameSettings. */
 

	
 
#include "ai_gamesettings.hpp"
 
#include "../../settings_internal.h"
 
#include "../../saveload/saveload.h"
 

	
 
/* static */ bool AIGameSettings::IsValid(const char *setting)
 
{
 
	uint i;
 
	const SettingDesc *sd = GetPatchFromName(setting, &i);
 
	return sd != NULL && sd->desc.cmd != SDT_STRING;
 
}
 

	
 
/* static */ int32 AIGameSettings::GetValue(const char *setting)
 
{
 
	if (!IsValid(setting)) return -1;
 

	
 
	uint i;
 
	const SettingDesc *sd = GetPatchFromName(setting, &i);
 

	
 
	void *ptr = GetVariableAddress(&_settings_game, &sd->save);
 
	if (sd->desc.cmd == SDT_BOOLX) return *(bool*)ptr;
 

	
 
	return (int32)ReadValue(ptr, sd->save.conv);
 
}
 

	
 
/* static */ bool AIGameSettings::IsDisabledVehicleType(AIVehicle::VehicleType vehicle_type)
 
{
 
	switch (vehicle_type) {
 
		case AIVehicle::VEHICLE_RAIL:  return _settings_game.ai.ai_disable_veh_train;
 
		case AIVehicle::VEHICLE_ROAD:  return _settings_game.ai.ai_disable_veh_roadveh;
 
		case AIVehicle::VEHICLE_WATER: return _settings_game.ai.ai_disable_veh_ship;
 
		case AIVehicle::VEHICLE_AIR:   return _settings_game.ai.ai_disable_veh_aircraft;
 
		default:                       return true;
 
	}
 
}
src/ai/api/ai_gamesettings.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_gamesettings.hpp Everything to read game settings. */
 

	
 
#ifndef AI_GAMESETTINGS_HPP
 
#define AI_GAMESETTINGS_HPP
 

	
 
#include "ai_object.hpp"
 
#include "ai_vehicle.hpp"
 

	
 
/**
 
 * Class that handles all game settings related functions.
 
 *
 
 * @note AIGameSettings::IsValid and AIGameSettings::GetValue are functions
 
 *       that rely on the settings as OpenTTD stores them in savegame and
 
 *       openttd.cfg. No guarantees can be given on the long term validity,
 
 *       consistency and stability of the names, values and value ranges.
 
 *       Using these settings can be dangerous and could cause issues in
 
 *       future versions. To make sure that a setting still exists in the
 
 *       current version you have to run AIGameSettings::IsValid before
 
 *       accessing it.
 
 *
 
 * @note The names of the setting for AIGameSettings::IsValid and
 
 *       AIGameSettings::GetValue are the same ones as those that are shown by
 
 *       the list_patches command in the in-game console. Settings that are
 
 *       string based are NOT supported and AIGAmeSettings::IsValid will return
 
 *       false for them. These settings will not be supported either because
 
 *       they have no relevance for the AI (default client names, server IPs,
 
 *       etc.).
 
 */
 
class AIGameSettings : public AIObject {
 
public:
 
	static const char *GetClassName() { return "AIGameSettings"; }
 

	
 
	/**
 
	 * Is the given game setting a valid setting for this instance of OpenTTD?
 
	 * @param setting The setting to check for existence.
 
	 * @warning Results of this function are not governed by the API. This means
 
	 *          that a setting that previously existed can be gone or has
 
	 *          changed it's name.
 
	 * @note Results achieved in the past offer no gurantee for the future.
 
	 * @return True if and only if the setting is valid.
 
	 */
 
	static bool IsValid(const char *setting);
 

	
 
	/**
 
	 * Gets the value of the game setting.
 
	 * @param setting The setting to get the value of.
 
	 * @pre IsValid(setting).
 
	 * @warning Results of this function are not governed by the API. This means
 
	 *          that the value of settings may be out of the expected range. It
 
	 *          also means that a setting that previously existed can be gone or
 
	 *          has changed it's name/characteristics.
 
	 * @note Results achieved in the past offer no gurantee for the future.
 
	 * @return The value for the setting.
 
	 */
 
	static int32 GetValue(const char *setting);
 

	
 
	/**
 
	 * Checks whether the given vehicle-type is disabled for AIs.
 
	 * @param vehicle_type The vehicle-type to check.
 
	 * @return True if the vehicle-type is disabled.
 
	 */
 
	static bool IsDisabledVehicleType(AIVehicle::VehicleType vehicle_type);
 
};
 

	
 
#endif /* AI_GAMESETTINGS_HPP */
src/ai/api/ai_gamesettings.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_gamesettings.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow AIGameSettings to be used as Squirrel parameter */
 
	template <> AIGameSettings *GetParam(ForceType<AIGameSettings *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIGameSettings *)instance; }
 
	template <> AIGameSettings &GetParam(ForceType<AIGameSettings &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIGameSettings *)instance; }
 
	template <> const AIGameSettings *GetParam(ForceType<const AIGameSettings *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIGameSettings *)instance; }
 
	template <> const AIGameSettings &GetParam(ForceType<const AIGameSettings &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIGameSettings *)instance; }
 
	template <> int Return<AIGameSettings *>(HSQUIRRELVM vm, AIGameSettings *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIGameSettings", res, NULL, DefSQDestructorCallback<AIGameSettings>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIGameSettings_Register(Squirrel *engine) {
 
	DefSQClass <AIGameSettings> SQAIGameSettings("AIGameSettings");
 
	SQAIGameSettings.PreRegister(engine);
 
	SQAIGameSettings.AddConstructor<void (AIGameSettings::*)(), 1>(engine, "x");
 

	
 
	SQAIGameSettings.DefSQStaticMethod(engine, &AIGameSettings::GetClassName,          "GetClassName",          1, "x");
 
	SQAIGameSettings.DefSQStaticMethod(engine, &AIGameSettings::IsValid,               "IsValid",               2, "xs");
 
	SQAIGameSettings.DefSQStaticMethod(engine, &AIGameSettings::GetValue,              "GetValue",              2, "xs");
 
	SQAIGameSettings.DefSQStaticMethod(engine, &AIGameSettings::IsDisabledVehicleType, "IsDisabledVehicleType", 2, "xi");
 

	
 
	SQAIGameSettings.PostRegister(engine);
 
}
src/ai/api/ai_group.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_group.cpp Implementation of AIGroup. */
 

	
 
#include "ai_group.hpp"
 
#include "ai_vehicle.hpp"
 
#include "ai_engine.hpp"
 
#include "../ai_instance.hpp"
 
#include "../../openttd.h"
 
#include "../../company_func.h"
 
#include "../../group.h"
 
#include "../../string_func.h"
 
#include "../../strings_func.h"
 
#include "../../core/alloc_func.hpp"
 
#include "../../command_func.h"
 
#include "../../autoreplace_func.h"
 
#include "table/strings.h"
 

	
 
/* static */ bool AIGroup::IsValidGroup(GroupID group_id)
 
{
 
	return ::IsValidGroupID(group_id) && ::GetGroup(group_id)->owner == _current_company;
 
}
 

	
 
/* static */ AIGroup::GroupID AIGroup::CreateGroup(AIVehicle::VehicleType vehicle_type)
 
{
 
	if (!AIObject::DoCommand(0, (::VehicleType)vehicle_type, 0, CMD_CREATE_GROUP, NULL, &AIInstance::DoCommandReturnGroupID)) return INVALID_GROUP;
 

	
 
	/* In case of test-mode, we return GroupID 0 */
 
	return (AIGroup::GroupID)0;
 
}
 

	
 
/* static */ bool AIGroup::DeleteGroup(GroupID group_id)
 
{
 
	EnforcePrecondition(false, IsValidGroup(group_id));
 

	
 
	return AIObject::DoCommand(0, group_id, 0, CMD_DELETE_GROUP);
 
}
 

	
 
/* static */ AIVehicle::VehicleType AIGroup::GetVehicleType(GroupID group_id)
 
{
 
	if (!IsValidGroup(group_id)) return AIVehicle::VEHICLE_INVALID;
 

	
 
	return (AIVehicle::VehicleType)((::VehicleType)::GetGroup(group_id)->vehicle_type);
 
}
 

	
 
/* static */ bool AIGroup::SetName(GroupID group_id, const char *name)
 
{
 
	EnforcePrecondition(false, IsValidGroup(group_id));
 
	EnforcePrecondition(false, !::StrEmpty(name));
 
	EnforcePreconditionCustomError(false, ::strlen(name) < MAX_LENGTH_GROUP_NAME_BYTES, AIError::ERR_PRECONDITION_STRING_TOO_LONG);
 

	
 
	return AIObject::DoCommand(0, group_id, 0, CMD_RENAME_GROUP, name);
 
}
 

	
 
/* static */ const char *AIGroup::GetName(GroupID group_id)
 
{
 
	if (!IsValidGroup(group_id)) return NULL;
 

	
 
	static const int len = 64;
 
	char *group_name = MallocT<char>(len);
 

	
 
	::SetDParam(0, group_id);
 
	::GetString(group_name, STR_GROUP_NAME, &group_name[len - 1]);
 
	return group_name;
 
}
 

	
 
/* static */ bool AIGroup::EnableAutoReplaceProtection(GroupID group_id, bool enable)
 
{
 
	EnforcePrecondition(false, IsValidGroup(group_id));
 

	
 
	return AIObject::DoCommand(0, group_id, enable ? 1 : 0, CMD_SET_GROUP_REPLACE_PROTECTION);
 
}
 

	
 
/* static */ bool AIGroup::GetAutoReplaceProtection(GroupID group_id)
 
{
 
	if (!IsValidGroup(group_id)) return false;
 

	
 
	return ::GetGroup(group_id)->replace_protection;
 
}
 

	
 
/* static */ int32 AIGroup::GetNumEngines(GroupID group_id, EngineID engine_id)
 
{
 
	if (!IsValidGroup(group_id) && group_id != DEFAULT_GROUP && group_id != ALL_GROUP) return -1;
 

	
 
	return GetGroupNumEngines(_current_company, group_id, engine_id);
 
}
 

	
 
/* static */ bool AIGroup::MoveVehicle(GroupID group_id, VehicleID vehicle_id)
 
{
 
	EnforcePrecondition(false, IsValidGroup(group_id) || group_id == DEFAULT_GROUP);
 
	EnforcePrecondition(false, AIVehicle::IsValidVehicle(vehicle_id));
 

	
 
	return AIObject::DoCommand(0, group_id, vehicle_id, CMD_ADD_VEHICLE_GROUP);
 
}
 

	
 
/* static */ bool AIGroup::EnableWagonRemoval(bool enable_removal)
 
{
 
	if (HasWagonRemoval() == enable_removal) return true;
 

	
 
	return AIObject::DoCommand(0, 5, enable_removal ? 1 : 0, CMD_SET_AUTOREPLACE);
 
}
 

	
 
/* static */ bool AIGroup::HasWagonRemoval()
 
{
 
	return ::GetCompany(_current_company)->renew_keep_length;
 
}
 

	
 
/* static */ bool AIGroup::SetAutoReplace(GroupID group_id, EngineID engine_id_old, EngineID engine_id_new)
 
{
 
	EnforcePrecondition(false, IsValidGroup(group_id) || group_id == ALL_GROUP);
 
	EnforcePrecondition(false, AIEngine::IsValidEngine(engine_id_new));
 

	
 
	return AIObject::DoCommand(0, 3 | (group_id << 16), (engine_id_new << 16) | engine_id_old, CMD_SET_AUTOREPLACE);
 
}
 

	
 
/* static */ EngineID AIGroup::GetEngineReplacement(GroupID group_id, EngineID engine_id)
 
{
 
	if (!IsValidGroup(group_id) && group_id != ALL_GROUP) return ::INVALID_ENGINE;
 

	
 
	return ::EngineReplacementForCompany(GetCompany(_current_company), engine_id, group_id);
 
}
 

	
 
/* static */ bool AIGroup::StopAutoReplace(GroupID group_id, EngineID engine_id)
 
{
 
	EnforcePrecondition(false, IsValidGroup(group_id) || group_id == ALL_GROUP);
 

	
 
	return AIObject::DoCommand(0, 3 | (group_id << 16), (::INVALID_ENGINE << 16) | engine_id, CMD_SET_AUTOREPLACE);
 
}
src/ai/api/ai_group.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_group.hpp Everything to put vehicles into groups. */
 

	
 
#ifndef AI_GROUP_HPP
 
#define AI_GROUP_HPP
 

	
 
#include "ai_object.hpp"
 
#include "ai_vehicle.hpp"
 

	
 
/**
 
 * Class that handles all group related functions.
 
 */
 
class AIGroup : public AIObject {
 
public:
 
	static const char *GetClassName() { return "AIGroup"; }
 

	
 
	/**
 
	 * The group IDs of some special groups.
 
	 */
 
	enum GroupID {
 
		/* Values are important, as they represent the internal state of the game (see group_type.h). */
 
		ALL_GROUP = 0xFFFD,     //!< All vehicles are in this group.
 
		DEFAULT_GROUP = 0xFFFE, //!< Vehicles not put in any other group are in this one.
 
		INVALID_GROUP = 0xFFFF, //!< An invalid group id.
 
	};
 

	
 
	/**
 
	 * Checks whether the given group is valid.
 
	 * @param group_id The group to check.
 
	 * @pre group_id != DEFAULT_GROUP && group_id != ALL_GROUP.
 
	 * @return True if and only if the group is valid.
 
	 */
 
	static bool IsValidGroup(GroupID group_id);
 

	
 
	/**
 
	 * Create a new group.
 
	 * @param vehicle_type The type of vehicle to create a group for.
 
	 * @return The GroupID of the new group, or an invalid GroupID when
 
	 *  it failed. Check the return value using IsValidGroup(). In test-mode
 
	 *  0 is returned if it was successful; any other value indicates failure.
 
	 */
 
	static GroupID CreateGroup(AIVehicle::VehicleType vehicle_type);
 

	
 
	/**
 
	 * Delete the given group. When the deletion succeeds all vehicles in the
 
	 *  given group will move to the DEFAULT_GROUP.
 
	 * @param group_id The group to delete.
 
	 * @pre IsValidGroup(group_id).
 
	 * @return True if and only if the group was succesfully deleted.
 
	 */
 
	static bool DeleteGroup(GroupID group_id);
 

	
 
	/**
 
	 * Get the vehicle type of a group.
 
	 * @param group_id The group to get the type from.
 
	 * @pre IsValidGroup(group_id).
 
	 * @return The vehicletype of the given group.
 
	 */
 
	static AIVehicle::VehicleType GetVehicleType(GroupID group_id);
 

	
 
	/**
 
	 * Set the name of a group.
 
	 * @param group_id The group to set the name for.
 
	 * @param name The name for the group.
 
	 * @pre IsValidGroup(group_id).
 
	 * @pre 'name' must have at least one character.
 
	 * @pre 'name' must have at most 30 characters.
 
	 * @exception AIError::ERR_NAME_IS_NOT_UNIQUE
 
	 * @return True if and only if the name was changed.
 
	 */
 
	static bool SetName(GroupID group_id, const char *name);
 

	
 
	/**
 
	 * Get the name of a group.
 
	 * @param group_id The group to get the name of.
 
	 * @pre IsValidGroup(group_id).
 
	 * @return The name the group has.
 
	 */
 
	static const char *GetName(GroupID group_id);
 

	
 
	/**
 
	 * Enable or disable autoreplace protected. If the protection is
 
	 *  enabled, global autoreplace won't affect vehicles in this group.
 
	 * @param group_id The group to change the protection for.
 
	 * @param enable True if protection should be enabled.
 
	 * @pre IsValidGroup(group_id).
 
	 * @return True if and only if the protection was succesfully changed.
 
	 */
 
	static bool EnableAutoReplaceProtection(GroupID group_id, bool enable);
 

	
 
	/**
 
	 * Get the autoreplace protection status.
 
	 * @param group_id The group to get the protection status for.
 
	 * @pre IsValidGroup(group_id).
 
	 * @return The autoreplace protection status for the given group.
 
	 */
 
	static bool GetAutoReplaceProtection(GroupID group_id);
 

	
 
	/**
 
	 * Get the number of engines in a given group.
 
	 * @param group_id The group to get the number of engines in.
 
	 * @param engine_id The engine id to count.
 
	 * @pre IsValidGroup(group_id) || group_id == ALL_GROUP || group_id == DEFAULT_GROUP.
 
	 * @return The number of engines with id engine_id in the group with id group_id.
 
	 */
 
	static int32 GetNumEngines(GroupID group_id, EngineID engine_id);
 

	
 
	/**
 
	 * Move a vehicle to a group.
 
	 * @param group_id The group to move the vehicel to.
 
	 * @param vehicle_id The vehicle to move to the group.
 
	 * @pre IsValidGroup(group_id) || group_id == DEFAULT_GROUP.
 
	 * @pre AIVehicle::IsValidVehicle(vehicle_id).
 
	 * @return True if and only if the vehicle was succesfully moved to the group.
 
	 * @note A vehicle can be in only one group at the same time. To remove it from
 
	 *  a group, move it to another or to DEFAULT_GROUP. Moving the vehicle to the
 
	 *  given group means removing it from another group.
 
	 */
 
	static bool MoveVehicle(GroupID group_id, VehicleID vehicle_id);
 

	
 
	/**
 
	 * Enable or disable the removal of wagons when a (part of a) vehicle is
 
	 *  (auto)replaced with a longer variant (longer wagons or longer engines)
 
	 *  If enabled, wagons are removed from the end of the vehicle until it
 
	 *  fits in the same number of tiles as it did before.
 
	 * @param keep_length If true, wagons will be removed if the a new engine is longer.
 
	 * @return True if and only if the value was succesfully changed.
 
	 */
 
	static bool EnableWagonRemoval(bool keep_length);
 

	
 
	/**
 
	 * Get the current status of wagon removal.
 
	 * @return Whether or not wagon removal is enabled.
 
	 */
 
	static bool HasWagonRemoval();
 

	
 
	/**
 
	 * Start replacing all vehicles with a specified engine with another engine.
 
	 * @param group_id The group to replace vehicles from. Use ALL_GROUP to replace
 
	 *  vehicles from all groups that haven't set autoreplace protection.
 
	 * @param engine_id_old The engine id to start replacing.
 
	 * @param engine_id_new The engine id to replace with.
 
	 * @pre IsValidGroup(group_id) || group_id == ALL_GROUP.
 
	 * @pre AIEngine.IsValidEngine(engine_id_new).
 
	 * @note To stop autoreplacing engine_id_old, call StopAutoReplace(group_id, engine_id_old).
 
	 */
 
	static bool SetAutoReplace(GroupID group_id, EngineID engine_id_old, EngineID engine_id_new);
 

	
 
	/**
 
	 * Get the EngineID the given EngineID is replaced with.
 
	 * @param group_id The group to get the replacement from.
 
	 * @param engine_id The engine that is being replaced.
 
	 * @pre IsValidGroup(group_id) || group_id == ALL_GROUP.
 
	 * @return The EngineID that is replacing engine_id or an invalid EngineID
 
	 *   in case engine_id is not begin replaced.
 
	 */
 
	static EngineID GetEngineReplacement(GroupID group_id, EngineID engine_id);
 

	
 
	/**
 
	 * Stop replacing a certain engine in the specified group.
 
	 * @param group_id The group to stop replacing the engine in.
 
	 * @param engine_id The engine id to stop replacing with another engine.
 
	 * @pre IsValidGroup(group_id) || group_id == ALL_GROUP.
 
	 * @return True if and if the replacing was succesfully stopped.
 
	 */
 
	static bool StopAutoReplace(GroupID group_id, EngineID engine_id);
 
};
 

	
 
#endif /* AI_GROUP_HPP */
src/ai/api/ai_group.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_group.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow enums to be used as Squirrel parameters */
 
	template <> AIGroup::GroupID GetParam(ForceType<AIGroup::GroupID>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AIGroup::GroupID)tmp; }
 
	template <> int Return<AIGroup::GroupID>(HSQUIRRELVM vm, AIGroup::GroupID res) { sq_pushinteger(vm, (int32)res); return 1; }
 

	
 
	/* Allow AIGroup to be used as Squirrel parameter */
 
	template <> AIGroup *GetParam(ForceType<AIGroup *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIGroup *)instance; }
 
	template <> AIGroup &GetParam(ForceType<AIGroup &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIGroup *)instance; }
 
	template <> const AIGroup *GetParam(ForceType<const AIGroup *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIGroup *)instance; }
 
	template <> const AIGroup &GetParam(ForceType<const AIGroup &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIGroup *)instance; }
 
	template <> int Return<AIGroup *>(HSQUIRRELVM vm, AIGroup *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIGroup", res, NULL, DefSQDestructorCallback<AIGroup>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIGroup_Register(Squirrel *engine) {
 
	DefSQClass <AIGroup> SQAIGroup("AIGroup");
 
	SQAIGroup.PreRegister(engine);
 
	SQAIGroup.AddConstructor<void (AIGroup::*)(), 1>(engine, "x");
 

	
 
	SQAIGroup.DefSQConst(engine, AIGroup::ALL_GROUP,     "ALL_GROUP");
 
	SQAIGroup.DefSQConst(engine, AIGroup::DEFAULT_GROUP, "DEFAULT_GROUP");
 
	SQAIGroup.DefSQConst(engine, AIGroup::INVALID_GROUP, "INVALID_GROUP");
 

	
 
	SQAIGroup.DefSQStaticMethod(engine, &AIGroup::GetClassName,                "GetClassName",                1, "x");
 
	SQAIGroup.DefSQStaticMethod(engine, &AIGroup::IsValidGroup,                "IsValidGroup",                2, "xi");
 
	SQAIGroup.DefSQStaticMethod(engine, &AIGroup::CreateGroup,                 "CreateGroup",                 2, "xi");
 
	SQAIGroup.DefSQStaticMethod(engine, &AIGroup::DeleteGroup,                 "DeleteGroup",                 2, "xi");
 
	SQAIGroup.DefSQStaticMethod(engine, &AIGroup::GetVehicleType,              "GetVehicleType",              2, "xi");
 
	SQAIGroup.DefSQStaticMethod(engine, &AIGroup::SetName,                     "SetName",                     3, "xis");
 
	SQAIGroup.DefSQStaticMethod(engine, &AIGroup::GetName,                     "GetName",                     2, "xi");
 
	SQAIGroup.DefSQStaticMethod(engine, &AIGroup::EnableAutoReplaceProtection, "EnableAutoReplaceProtection", 3, "xib");
 
	SQAIGroup.DefSQStaticMethod(engine, &AIGroup::GetAutoReplaceProtection,    "GetAutoReplaceProtection",    2, "xi");
 
	SQAIGroup.DefSQStaticMethod(engine, &AIGroup::GetNumEngines,               "GetNumEngines",               3, "xii");
 
	SQAIGroup.DefSQStaticMethod(engine, &AIGroup::MoveVehicle,                 "MoveVehicle",                 3, "xii");
 
	SQAIGroup.DefSQStaticMethod(engine, &AIGroup::EnableWagonRemoval,          "EnableWagonRemoval",          2, "xb");
 
	SQAIGroup.DefSQStaticMethod(engine, &AIGroup::HasWagonRemoval,             "HasWagonRemoval",             1, "x");
 
	SQAIGroup.DefSQStaticMethod(engine, &AIGroup::SetAutoReplace,              "SetAutoReplace",              4, "xiii");
 
	SQAIGroup.DefSQStaticMethod(engine, &AIGroup::GetEngineReplacement,        "GetEngineReplacement",        3, "xii");
 
	SQAIGroup.DefSQStaticMethod(engine, &AIGroup::StopAutoReplace,             "StopAutoReplace",             3, "xii");
 

	
 
	SQAIGroup.PostRegister(engine);
 
}
src/ai/api/ai_grouplist.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_grouplist.cpp Implementation of AIGroupList and friends. */
 

	
 
#include "ai_grouplist.hpp"
 
#include "../../openttd.h"
 
#include "../../company_func.h"
 
#include "../../group.h"
 

	
 
AIGroupList::AIGroupList()
 
{
 
	Group *g;
 
	FOR_ALL_GROUPS(g) {
 
		if (g->owner == _current_company) this->AddItem(g->index);
 
	}
 
}
src/ai/api/ai_grouplist.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_grouplist.hpp List all the groups (you own). */
 

	
 
#ifndef AI_GROUPLIST_HPP
 
#define AI_GROUPLIST_HPP
 

	
 
#include "ai_abstractlist.hpp"
 

	
 
/**
 
 * Creates a list of groups of which you are the owner.
 
 * @note Neither AIGroup.ALL_GROUP nor AIGroup.DEFAULT_GROUP is in this list.
 
 * @ingroup AIList
 
 */
 
class AIGroupList : public AIAbstractList {
 
public:
 
	static const char *GetClassName() { return "AIGroupList"; }
 
	AIGroupList();
 
};
 

	
 
#endif /* AI_GROUPLIST_HPP */
src/ai/api/ai_grouplist.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_grouplist.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow AIGroupList to be used as Squirrel parameter */
 
	template <> AIGroupList *GetParam(ForceType<AIGroupList *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIGroupList *)instance; }
 
	template <> AIGroupList &GetParam(ForceType<AIGroupList &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIGroupList *)instance; }
 
	template <> const AIGroupList *GetParam(ForceType<const AIGroupList *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIGroupList *)instance; }
 
	template <> const AIGroupList &GetParam(ForceType<const AIGroupList &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIGroupList *)instance; }
 
	template <> int Return<AIGroupList *>(HSQUIRRELVM vm, AIGroupList *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIGroupList", res, NULL, DefSQDestructorCallback<AIGroupList>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIGroupList_Register(Squirrel *engine) {
 
	DefSQClass <AIGroupList> SQAIGroupList("AIGroupList");
 
	SQAIGroupList.PreRegister(engine, "AIAbstractList");
 
	SQAIGroupList.AddConstructor<void (AIGroupList::*)(), 1>(engine, "x");
 

	
 
	SQAIGroupList.DefSQStaticMethod(engine, &AIGroupList::GetClassName, "GetClassName", 1, "x");
 

	
 
	SQAIGroupList.PostRegister(engine);
 
}
src/ai/api/ai_industry.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_industry.cpp Implementation of AIIndustry. */
 

	
 
#include "ai_industry.hpp"
 
#include "ai_cargo.hpp"
 
#include "ai_map.hpp"
 
#include "../../openttd.h"
 
#include "../../tile_type.h"
 
#include "../../industry.h"
 
#include "../../strings_func.h"
 
#include "../../station_func.h"
 
#include "table/strings.h"
 

	
 
/* static */ IndustryID AIIndustry::GetMaxIndustryID()
 
{
 
	return ::GetMaxIndustryIndex();
 
}
 

	
 
/* static */ int32 AIIndustry::GetIndustryCount()
 
{
 
	return ::GetNumIndustries();
 
}
 

	
 
/* static */ bool AIIndustry::IsValidIndustry(IndustryID industry_id)
 
{
 
	return ::IsValidIndustryID(industry_id);
 
}
 

	
 
/* static */ const char *AIIndustry::GetName(IndustryID industry_id)
 
{
 
	if (!IsValidIndustry(industry_id)) return NULL;
 
	static const int len = 64;
 
	char *industry_name = MallocT<char>(len);
 

	
 
	::SetDParam(0, industry_id);
 
	::GetString(industry_name, STR_INDUSTRY, &industry_name[len - 1]);
 

	
 
	return industry_name;
 
}
 

	
 
/* static */ int32 AIIndustry::GetProduction(IndustryID industry_id, CargoID cargo_id)
 
{
 
	if (!IsValidIndustry(industry_id)) return -1;
 
	if (!AICargo::IsValidCargo(cargo_id)) return -1;
 

	
 
	const Industry *i = ::GetIndustry(industry_id);
 
	const IndustrySpec *indsp = ::GetIndustrySpec(i->type);
 

	
 
	for (byte j = 0; j < lengthof(indsp->produced_cargo); j++)
 
		if (indsp->produced_cargo[j] == cargo_id) return i->production_rate[j] * 8;
 

	
 
	return -1;
 
}
 

	
 
/* static */ bool AIIndustry::IsCargoAccepted(IndustryID industry_id, CargoID cargo_id)
 
{
 
	if (!IsValidIndustry(industry_id)) return false;
 
	if (!AICargo::IsValidCargo(cargo_id)) return false;
 

	
 
	const Industry *i = ::GetIndustry(industry_id);
 
	const IndustrySpec *indsp = ::GetIndustrySpec(i->type);
 

	
 
	for (byte j = 0; j < lengthof(indsp->accepts_cargo); j++)
 
		if (indsp->accepts_cargo[j] == cargo_id) return true;
 

	
 
	return false;
 
}
 

	
 
/* static */ int32 AIIndustry::GetStockpiledCargo(IndustryID industry_id, CargoID cargo_id)
 
{
 
	if (!IsValidIndustry(industry_id)) return -1;
 
	if (!AICargo::IsValidCargo(cargo_id)) return -1;
 

	
 
	Industry *ind = ::GetIndustry(industry_id);
 
	for (uint i = 0; i < lengthof(ind->accepts_cargo); i++) {
 
		CargoID cid = ind->accepts_cargo[i];
 
		if (cid == cargo_id) {
 
			return ind->incoming_cargo_waiting[i];
 
		}
 
	}
 

	
 
	return -1;
 
}
 

	
 
/* static */ int32 AIIndustry::GetLastMonthProduction(IndustryID industry_id, CargoID cargo_id)
 
{
 
	if (!IsValidIndustry(industry_id)) return -1;
 
	if (!AICargo::IsValidCargo(cargo_id)) return -1;
 

	
 
	const Industry *i = ::GetIndustry(industry_id);
 
	const IndustrySpec *indsp = ::GetIndustrySpec(i->type);
 

	
 
	for (byte j = 0; j < lengthof(indsp->produced_cargo); j++)
 
		if (indsp->produced_cargo[j] == cargo_id) return i->last_month_production[j];
 

	
 
	return -1;
 
}
 

	
 
/* static */ int32 AIIndustry::GetLastMonthTransported(IndustryID industry_id, CargoID cargo_id)
 
{
 
	if (!IsValidIndustry(industry_id)) return -1;
 
	if (!AICargo::IsValidCargo(cargo_id)) return -1;
 

	
 
	const Industry *i = ::GetIndustry(industry_id);
 
	const IndustrySpec *indsp = ::GetIndustrySpec(i->type);
 

	
 
	for (byte j = 0; j < lengthof(indsp->produced_cargo); j++)
 
		if (indsp->produced_cargo[j] == cargo_id) return i->last_month_transported[j];
 

	
 
	return -1;
 
}
 

	
 
/* static */ TileIndex AIIndustry::GetLocation(IndustryID industry_id)
 
{
 
	if (!IsValidIndustry(industry_id)) return INVALID_TILE;
 

	
 
	return ::GetIndustry(industry_id)->xy;
 
}
 

	
 
/* static */ int32 AIIndustry::GetAmountOfStationsAround(IndustryID industry_id)
 
{
 
	if (!IsValidIndustry(industry_id)) return -1;
 

	
 
	Industry *ind = ::GetIndustry(industry_id);
 
	return (int32)::FindStationsAroundTiles(ind->xy, ind->width, ind->height).size();
 
}
 

	
 
/* static */ int32 AIIndustry::GetDistanceManhattanToTile(IndustryID industry_id, TileIndex tile)
 
{
 
	if (!IsValidIndustry(industry_id)) return -1;
 

	
 
	return AIMap::DistanceManhattan(tile, GetLocation(industry_id));
 
}
 

	
 
/* static */ int32 AIIndustry::GetDistanceSquareToTile(IndustryID industry_id, TileIndex tile)
 
{
 
	if (!IsValidIndustry(industry_id)) return -1;
 

	
 
	return AIMap::DistanceSquare(tile, GetLocation(industry_id));
 
}
 

	
 
/* static */ bool AIIndustry::IsBuiltOnWater(IndustryID industry_id)
 
{
 
	if (!IsValidIndustry(industry_id)) return false;
 

	
 
	return (::GetIndustrySpec(::GetIndustry(industry_id)->type)->behaviour & INDUSTRYBEH_BUILT_ONWATER) != 0;
 
}
 

	
 
/* static */ bool AIIndustry::HasHeliportAndDock(IndustryID industry_id)
 
{
 
	if (!IsValidIndustry(industry_id)) return false;
 

	
 
	return (::GetIndustrySpec(::GetIndustry(industry_id)->type)->behaviour & INDUSTRYBEH_AI_AIRSHIP_ROUTES) != 0;
 
}
 

	
 
/* static */ TileIndex AIIndustry::GetHeliportAndDockLocation(IndustryID industry_id)
 
{
 
	if (!IsValidIndustry(industry_id)) return INVALID_TILE;
 
	if (!HasHeliportAndDock(industry_id)) return INVALID_TILE;
 

	
 
	return ::GetIndustry(industry_id)->xy;
 
}
 

	
 
/* static */ IndustryType AIIndustry::GetIndustryType(IndustryID industry_id)
 
{
 
	if (!IsValidIndustry(industry_id)) return INVALID_INDUSTRYTYPE;
 

	
 
	return ::GetIndustry(industry_id)->type;
 
}
src/ai/api/ai_industry.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_industry.hpp Everything to query and build industries. */
 

	
 
#ifndef AI_INDUSTRY_HPP
 
#define AI_INDUSTRY_HPP
 

	
 
#include "ai_object.hpp"
 

	
 
/**
 
 * Class that handles all industry related functions.
 
 */
 
class AIIndustry : public AIObject {
 
public:
 
	static const char *GetClassName() { return "AIIndustry"; }
 

	
 
	/**
 
	 * Gets the maximum industry index; there are no valid industries with a
 
	 *   higher index.
 
	 * @return The maximum industry index.
 
	 * @post Return value is always non-negative.
 
	 */
 
	static IndustryID GetMaxIndustryID();
 

	
 
	/**
 
	 * Gets the number of industries. This is different than GetMaxIndustryID()
 
	 *   because of the way OpenTTD works internally.
 
	 * @return The number of industries.
 
	 * @post Return value is always non-negative.
 
	 */
 
	static int32 GetIndustryCount();
 

	
 
	/**
 
	 * Checks whether the given industry index is valid.
 
	 * @param industry_id The index to check.
 
	 * @return True if and only if the industry is valid.
 
	 */
 
	static bool IsValidIndustry(IndustryID industry_id);
 

	
 
	/**
 
	 * Get the name of the industry.
 
	 * @param industry_id The industry to get the name of.
 
	 * @pre IsValidIndustry(industry_id).
 
	 * @return The name of the industry.
 
	 */
 
	static const char *GetName(IndustryID industry_id);
 

	
 
	/**
 
	 * Gets the production of a cargo of the industry.
 
	 * @param industry_id The index of the industry.
 
	 * @param cargo_id The index of the cargo.
 
	 * @pre IsValidIndustry(industry_id).
 
	 * @pre AICargo::IsValidCargo(cargo_id).
 
	 * @return The production of the cargo for this industry, or -1 if
 
	 *   this industry doesn't produce this cargo.
 
	 */
 
	static int32 GetProduction(IndustryID industry_id, CargoID cargo_id);
 

	
 
	/**
 
	 * See if an industry accepts a certain cargo.
 
	 * @param industry_id The index of the industry.
 
	 * @param cargo_id The index of the cargo.
 
	 * @pre IsValidIndustry(industry_id).
 
	 * @pre AICargo::IsValidCargo(cargo_id).
 
	 * @return The production of the cargo for this industry.
 
	 */
 
	static bool IsCargoAccepted(IndustryID industry_id, CargoID cargo_id);
 

	
 
	/**
 
	 * Get the amount of cargo stockpiled for processing.
 
	 * @param industry_id The index of the industry.
 
	 * @param cargo_id The index of the cargo.
 
	 * @pre IsValidIndustry(industry_id).
 
	 * @pre AICargo::IsValidCargo(cargo_id).
 
	 * @return The amount of cargo that is waiting for processing.
 
	 */
 
	static int32 GetStockpiledCargo(IndustryID industry_id, CargoID cargo_id);
 

	
 
	/**
 
	 * Get the total last month's production of the given cargo at an industry.
 
	 * @param industry_id The index of the industry.
 
	 * @param cargo_id The index of the cargo.
 
	 * @pre IsValidIndustry(industry_id).
 
	 * @pre AICargo::IsValidCargo(cargo_id).
 
	 * @return The last month's production of the given cargo for this industry.
 
	 */
 
	static int32 GetLastMonthProduction(IndustryID industry_id, CargoID cargo_id);
 

	
 
	/**
 
	 * Get the total amount of cargo transported from an industry last month.
 
	 * @param industry_id The index of the industry.
 
	 * @param cargo_id The index of the cargo.
 
	 * @pre IsValidIndustry(industry_id).
 
	 * @pre AICargo::IsValidCargo(cargo_id).
 
	 * @return The amount of given cargo transported from this industry last month.
 
	 */
 
	static int32 GetLastMonthTransported(IndustryID industry_id, CargoID cargo_id);
 

	
 
	/**
 
	 * Gets the location of the industry.
 
	 * @param industry_id The index of the industry.
 
	 * @pre IsValidIndustry(industry_id).
 
	 * @return The location of the industry.
 
	 */
 
	static TileIndex GetLocation(IndustryID industry_id);
 

	
 
	/**
 
	 * Get the number of stations around an industry.
 
	 * @param industry_id The index of the industry.
 
	 * @pre IsValidIndustry(industry_id).
 
	 * @return The number of stations around an industry.
 
	 */
 
	static int32 GetAmountOfStationsAround(IndustryID industry_id);
 

	
 
	/**
 
	 * Get the manhattan distance from the tile to the AIIndustry::GetLocation()
 
	 *  of the industry.
 
	 * @param industry_id The industry to get the distance to.
 
	 * @param tile The tile to get the distance to.
 
	 * @pre IsValidIndustry(industry_id).
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @return The distance between industry and tile.
 
	 */
 
	static int32 GetDistanceManhattanToTile(IndustryID industry_id, TileIndex tile);
 

	
 
	/**
 
	 * Get the square distance from the tile to the AIIndustry::GetLocation()
 
	 *  of the industry.
 
	 * @param industry_id The industry to get the distance to.
 
	 * @param tile The tile to get the distance to.
 
	 * @pre IsValidIndustry(industry_id).
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @return The distance between industry and tile.
 
	 */
 
	static int32 GetDistanceSquareToTile(IndustryID industry_id, TileIndex tile);
 

	
 
	/**
 
	 * Is this industry built on water.
 
	 * @param industry_id The index of the industry.
 
	 * @pre IsValidIndustry(industry_id).
 
	 * @return True when the industry is built on water.
 
	 */
 
	static bool IsBuiltOnWater(IndustryID industry_id);
 

	
 
	/**
 
	 * Does this industry have a heliport and dock?
 
	 * @param industry_id The index of the industry.
 
	 * @pre IsValidIndustry(industry_id).
 
	 * @return True when the industry has a heliport and dock.
 
	 */
 
	static bool HasHeliportAndDock(IndustryID industry_id);
 

	
 
	/**
 
	 * Gets the location of the industry's heliport/dock.
 
	 * @param industry_id The index of the industry.
 
	 * @pre IsValidIndustry(industry_id).
 
	 * @pre HasHeliportAndDock(industry_id).
 
	 * @return The location of the industry's heliport/dock.
 
	 */
 
	static TileIndex GetHeliportAndDockLocation(IndustryID industry_id);
 

	
 
	/**
 
	 * Get the IndustryType of the industry.
 
	 * @param industry_id The index of the industry.
 
	 * @pre IsValidIndustry(industry_id).
 
	 * @return The IndustryType of the industry.
 
	 */
 
	static IndustryType GetIndustryType(IndustryID industry_id);
 
};
 

	
 
#endif /* AI_INDUSTRY_HPP */
src/ai/api/ai_industry.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_industry.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow AIIndustry to be used as Squirrel parameter */
 
	template <> AIIndustry *GetParam(ForceType<AIIndustry *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIIndustry *)instance; }
 
	template <> AIIndustry &GetParam(ForceType<AIIndustry &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIIndustry *)instance; }
 
	template <> const AIIndustry *GetParam(ForceType<const AIIndustry *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIIndustry *)instance; }
 
	template <> const AIIndustry &GetParam(ForceType<const AIIndustry &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIIndustry *)instance; }
 
	template <> int Return<AIIndustry *>(HSQUIRRELVM vm, AIIndustry *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIIndustry", res, NULL, DefSQDestructorCallback<AIIndustry>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIIndustry_Register(Squirrel *engine) {
 
	DefSQClass <AIIndustry> SQAIIndustry("AIIndustry");
 
	SQAIIndustry.PreRegister(engine);
 
	SQAIIndustry.AddConstructor<void (AIIndustry::*)(), 1>(engine, "x");
 

	
 
	SQAIIndustry.DefSQStaticMethod(engine, &AIIndustry::GetClassName,               "GetClassName",               1, "x");
 
	SQAIIndustry.DefSQStaticMethod(engine, &AIIndustry::GetMaxIndustryID,           "GetMaxIndustryID",           1, "x");
 
	SQAIIndustry.DefSQStaticMethod(engine, &AIIndustry::GetIndustryCount,           "GetIndustryCount",           1, "x");
 
	SQAIIndustry.DefSQStaticMethod(engine, &AIIndustry::IsValidIndustry,            "IsValidIndustry",            2, "xi");
 
	SQAIIndustry.DefSQStaticMethod(engine, &AIIndustry::GetName,                    "GetName",                    2, "xi");
 
	SQAIIndustry.DefSQStaticMethod(engine, &AIIndustry::GetProduction,              "GetProduction",              3, "xii");
 
	SQAIIndustry.DefSQStaticMethod(engine, &AIIndustry::IsCargoAccepted,            "IsCargoAccepted",            3, "xii");
 
	SQAIIndustry.DefSQStaticMethod(engine, &AIIndustry::GetStockpiledCargo,         "GetStockpiledCargo",         3, "xii");
 
	SQAIIndustry.DefSQStaticMethod(engine, &AIIndustry::GetLastMonthProduction,     "GetLastMonthProduction",     3, "xii");
 
	SQAIIndustry.DefSQStaticMethod(engine, &AIIndustry::GetLastMonthTransported,    "GetLastMonthTransported",    3, "xii");
 
	SQAIIndustry.DefSQStaticMethod(engine, &AIIndustry::GetLocation,                "GetLocation",                2, "xi");
 
	SQAIIndustry.DefSQStaticMethod(engine, &AIIndustry::GetAmountOfStationsAround,  "GetAmountOfStationsAround",  2, "xi");
 
	SQAIIndustry.DefSQStaticMethod(engine, &AIIndustry::GetDistanceManhattanToTile, "GetDistanceManhattanToTile", 3, "xii");
 
	SQAIIndustry.DefSQStaticMethod(engine, &AIIndustry::GetDistanceSquareToTile,    "GetDistanceSquareToTile",    3, "xii");
 
	SQAIIndustry.DefSQStaticMethod(engine, &AIIndustry::IsBuiltOnWater,             "IsBuiltOnWater",             2, "xi");
 
	SQAIIndustry.DefSQStaticMethod(engine, &AIIndustry::HasHeliportAndDock,         "HasHeliportAndDock",         2, "xi");
 
	SQAIIndustry.DefSQStaticMethod(engine, &AIIndustry::GetHeliportAndDockLocation, "GetHeliportAndDockLocation", 2, "xi");
 
	SQAIIndustry.DefSQStaticMethod(engine, &AIIndustry::GetIndustryType,            "GetIndustryType",            2, "xi");
 

	
 
	SQAIIndustry.PostRegister(engine);
 
}
src/ai/api/ai_industrylist.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_industrylist.cpp Implementation of AIIndustryList and friends. */
 

	
 
#include "ai_industrylist.hpp"
 
#include "../../openttd.h"
 
#include "../../tile_type.h"
 
#include "../../industry.h"
 

	
 
AIIndustryList::AIIndustryList()
 
{
 
	Industry *i;
 
	FOR_ALL_INDUSTRIES(i) {
 
		this->AddItem(i->index);
 
	}
 
}
 

	
 
AIIndustryList_CargoAccepting::AIIndustryList_CargoAccepting(CargoID cargo_id)
 
{
 
	const Industry *i;
 
	const IndustrySpec *indsp;
 

	
 
	FOR_ALL_INDUSTRIES(i) {
 
		indsp = ::GetIndustrySpec(i->type);
 

	
 
		for (byte j = 0; j < lengthof(indsp->accepts_cargo); j++)
 
			if (indsp->accepts_cargo[j] == cargo_id) this->AddItem(i->index);
 
	}
 
}
 

	
 
AIIndustryList_CargoProducing::AIIndustryList_CargoProducing(CargoID cargo_id)
 
{
 
	const Industry *i;
 
	const IndustrySpec *indsp;
 

	
 
	FOR_ALL_INDUSTRIES(i) {
 
		indsp = ::GetIndustrySpec(i->type);
 

	
 
		for (byte j = 0; j < lengthof(indsp->produced_cargo); j++)
 
			if (indsp->produced_cargo[j] == cargo_id) this->AddItem(i->index);
 
	}
 
}
src/ai/api/ai_industrylist.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_industrylist.hpp List all the industries. */
 

	
 
#ifndef AI_INDUSTRYLIST_HPP
 
#define AI_INDUSTRYLIST_HPP
 

	
 
#include "ai_abstractlist.hpp"
 

	
 
/**
 
 * Creates a list of industries that are currently on the map.
 
 * @ingroup AIList
 
 */
 
class AIIndustryList : public AIAbstractList {
 
public:
 
	static const char *GetClassName() { return "AIIndustryList"; }
 
	AIIndustryList();
 
};
 

	
 
/**
 
 * Creates a list of industries that accepts a given cargo.
 
 * @ingroup AIList
 
 */
 
class AIIndustryList_CargoAccepting : public AIAbstractList {
 
public:
 
	static const char *GetClassName() { return "AIIndustryList_CargoAccepting"; }
 

	
 
	/**
 
	 * @param cargo_id The cargo this industry should accept.
 
	 */
 
	AIIndustryList_CargoAccepting(CargoID cargo_id);
 
};
 

	
 
/**
 
 * Creates a list of industries that can produce a given cargo.
 
 * @note It also contains industries that currently produces 0 units of the cargo.
 
 * @ingroup AIList
 
 */
 
class AIIndustryList_CargoProducing : public AIAbstractList {
 
public:
 
	static const char *GetClassName() { return "AIIndustryList_CargoProducing"; }
 

	
 
	/**
 
	 * @param cargo_id The cargo this industry should produce.
 
	 */
 
	AIIndustryList_CargoProducing(CargoID cargo_id);
 
};
 

	
 
#endif /* AI_INDUSTRYLIST_HPP */
src/ai/api/ai_industrylist.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_industrylist.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow AIIndustryList to be used as Squirrel parameter */
 
	template <> AIIndustryList *GetParam(ForceType<AIIndustryList *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIIndustryList *)instance; }
 
	template <> AIIndustryList &GetParam(ForceType<AIIndustryList &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIIndustryList *)instance; }
 
	template <> const AIIndustryList *GetParam(ForceType<const AIIndustryList *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIIndustryList *)instance; }
 
	template <> const AIIndustryList &GetParam(ForceType<const AIIndustryList &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIIndustryList *)instance; }
 
	template <> int Return<AIIndustryList *>(HSQUIRRELVM vm, AIIndustryList *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIIndustryList", res, NULL, DefSQDestructorCallback<AIIndustryList>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIIndustryList_Register(Squirrel *engine) {
 
	DefSQClass <AIIndustryList> SQAIIndustryList("AIIndustryList");
 
	SQAIIndustryList.PreRegister(engine, "AIAbstractList");
 
	SQAIIndustryList.AddConstructor<void (AIIndustryList::*)(), 1>(engine, "x");
 

	
 
	SQAIIndustryList.DefSQStaticMethod(engine, &AIIndustryList::GetClassName, "GetClassName", 1, "x");
 

	
 
	SQAIIndustryList.PostRegister(engine);
 
}
 

	
 
namespace SQConvert {
 
	/* Allow AIIndustryList_CargoAccepting to be used as Squirrel parameter */
 
	template <> AIIndustryList_CargoAccepting *GetParam(ForceType<AIIndustryList_CargoAccepting *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIIndustryList_CargoAccepting *)instance; }
 
	template <> AIIndustryList_CargoAccepting &GetParam(ForceType<AIIndustryList_CargoAccepting &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIIndustryList_CargoAccepting *)instance; }
 
	template <> const AIIndustryList_CargoAccepting *GetParam(ForceType<const AIIndustryList_CargoAccepting *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIIndustryList_CargoAccepting *)instance; }
 
	template <> const AIIndustryList_CargoAccepting &GetParam(ForceType<const AIIndustryList_CargoAccepting &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIIndustryList_CargoAccepting *)instance; }
 
	template <> int Return<AIIndustryList_CargoAccepting *>(HSQUIRRELVM vm, AIIndustryList_CargoAccepting *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIIndustryList_CargoAccepting", res, NULL, DefSQDestructorCallback<AIIndustryList_CargoAccepting>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIIndustryList_CargoAccepting_Register(Squirrel *engine) {
 
	DefSQClass <AIIndustryList_CargoAccepting> SQAIIndustryList_CargoAccepting("AIIndustryList_CargoAccepting");
 
	SQAIIndustryList_CargoAccepting.PreRegister(engine, "AIAbstractList");
 
	SQAIIndustryList_CargoAccepting.AddConstructor<void (AIIndustryList_CargoAccepting::*)(CargoID cargo_id), 2>(engine, "xi");
 

	
 
	SQAIIndustryList_CargoAccepting.DefSQStaticMethod(engine, &AIIndustryList_CargoAccepting::GetClassName, "GetClassName", 1, "x");
 

	
 
	SQAIIndustryList_CargoAccepting.PostRegister(engine);
 
}
 

	
 
namespace SQConvert {
 
	/* Allow AIIndustryList_CargoProducing to be used as Squirrel parameter */
 
	template <> AIIndustryList_CargoProducing *GetParam(ForceType<AIIndustryList_CargoProducing *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIIndustryList_CargoProducing *)instance; }
 
	template <> AIIndustryList_CargoProducing &GetParam(ForceType<AIIndustryList_CargoProducing &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIIndustryList_CargoProducing *)instance; }
 
	template <> const AIIndustryList_CargoProducing *GetParam(ForceType<const AIIndustryList_CargoProducing *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIIndustryList_CargoProducing *)instance; }
 
	template <> const AIIndustryList_CargoProducing &GetParam(ForceType<const AIIndustryList_CargoProducing &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIIndustryList_CargoProducing *)instance; }
 
	template <> int Return<AIIndustryList_CargoProducing *>(HSQUIRRELVM vm, AIIndustryList_CargoProducing *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIIndustryList_CargoProducing", res, NULL, DefSQDestructorCallback<AIIndustryList_CargoProducing>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIIndustryList_CargoProducing_Register(Squirrel *engine) {
 
	DefSQClass <AIIndustryList_CargoProducing> SQAIIndustryList_CargoProducing("AIIndustryList_CargoProducing");
 
	SQAIIndustryList_CargoProducing.PreRegister(engine, "AIAbstractList");
 
	SQAIIndustryList_CargoProducing.AddConstructor<void (AIIndustryList_CargoProducing::*)(CargoID cargo_id), 2>(engine, "xi");
 

	
 
	SQAIIndustryList_CargoProducing.DefSQStaticMethod(engine, &AIIndustryList_CargoProducing::GetClassName, "GetClassName", 1, "x");
 

	
 
	SQAIIndustryList_CargoProducing.PostRegister(engine);
 
}
src/ai/api/ai_industrytype.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_industrytype.cpp Implementation of AIIndustryType. */
 

	
 
#include "ai_industrytype.hpp"
 
#include "ai_map.hpp"
 
#include "../../openttd.h"
 
#include "../../command_type.h"
 
#include "../../settings_type.h"
 
#include "../../strings_func.h"
 
#include "../../tile_type.h"
 
#include "../../industry.h"
 

	
 
/* static */ bool AIIndustryType::IsValidIndustryType(IndustryType industry_type)
 
{
 
	if (industry_type >= NUM_INDUSTRYTYPES) return false;
 

	
 
	return ::GetIndustrySpec(industry_type)->enabled;
 
}
 

	
 
/* static */ bool AIIndustryType::IsRawIndustry(IndustryType industry_type)
 
{
 
	if (!IsValidIndustryType(industry_type)) return false;
 

	
 
	return ::GetIndustrySpec(industry_type)->IsRawIndustry();
 
}
 

	
 
/* static */ bool AIIndustryType::ProductionCanIncrease(IndustryType industry_type)
 
{
 
	if (!IsValidIndustryType(industry_type)) return false;
 

	
 
	if (_settings_game.game_creation.landscape != LT_TEMPERATE) return true;
 
	return (::GetIndustrySpec(industry_type)->behaviour & INDUSTRYBEH_DONT_INCR_PROD) == 0;
 
}
 

	
 
/* static */ Money AIIndustryType::GetConstructionCost(IndustryType industry_type)
 
{
 
	if (!IsValidIndustryType(industry_type)) return false;
 

	
 
	return ::GetIndustrySpec(industry_type)->GetConstructionCost();
 
}
 

	
 
/* static */ const char *AIIndustryType::GetName(IndustryType industry_type)
 
{
 
	if (!IsValidIndustryType(industry_type)) return NULL;
 
	static const int len = 64;
 
	char *industrytype_name = MallocT<char>(len);
 

	
 
	::GetString(industrytype_name, ::GetIndustrySpec(industry_type)->name, &industrytype_name[len - 1]);
 

	
 
	return industrytype_name;
 
}
 

	
 
/* static */ AIList *AIIndustryType::GetProducedCargo(IndustryType industry_type)
 
{
 
	if (!IsValidIndustryType(industry_type)) return NULL;
 

	
 
	const IndustrySpec *ins = ::GetIndustrySpec(industry_type);
 

	
 
	AIList *list = new AIList();
 
	for (int i = 0; i < 2; i++) {
 
		if (ins->produced_cargo[i] != CT_INVALID) list->AddItem(ins->produced_cargo[i], 0);
 
	}
 

	
 
	return list;
 
}
 

	
 
/* static */ AIList *AIIndustryType::GetAcceptedCargo(IndustryType industry_type)
 
{
 
	if (!IsValidIndustryType(industry_type)) return NULL;
 

	
 
	const IndustrySpec *ins = ::GetIndustrySpec(industry_type);
 

	
 
	AIList *list = new AIList();
 
	for (int i = 0; i < 3; i++) {
 
		if (ins->accepts_cargo[i] != CT_INVALID) list->AddItem(ins->accepts_cargo[i], 0);
 
	}
 

	
 
	return list;
 
}
 

	
 
/* static */ bool AIIndustryType::CanBuildIndustry(IndustryType industry_type)
 
{
 
	if (!IsValidIndustryType(industry_type)) return false;
 
	if (!::GetIndustrySpec(industry_type)->IsRawIndustry()) return true;
 

	
 
	/* raw_industry_construction == 1 means "Build as other industries" */
 
	return _settings_game.construction.raw_industry_construction == 1;
 
}
 

	
 
/* static */ bool AIIndustryType::CanProspectIndustry(IndustryType industry_type)
 
{
 
	if (!IsValidIndustryType(industry_type)) return false;
 
	if (!::GetIndustrySpec(industry_type)->IsRawIndustry()) return false;
 

	
 
	/* raw_industry_construction == 2 means "prospect" */
 
	return _settings_game.construction.raw_industry_construction == 2;
 
}
 

	
 
/* static */ bool AIIndustryType::BuildIndustry(IndustryType industry_type, TileIndex tile)
 
{
 
	EnforcePrecondition(false, CanBuildIndustry(industry_type));
 
	EnforcePrecondition(false, AIMap::IsValidTile(tile));
 

	
 
	uint32 seed = ::InteractiveRandom();
 
	return AIObject::DoCommand(tile, (::InteractiveRandomRange(::GetIndustrySpec(industry_type)->num_table) << 16) | industry_type, seed, CMD_BUILD_INDUSTRY);
 
}
 

	
 
/* static */ bool AIIndustryType::ProspectIndustry(IndustryType industry_type)
 
{
 
	EnforcePrecondition(false, CanProspectIndustry(industry_type));
 

	
 
	uint32 seed = ::InteractiveRandom();
 
	return AIObject::DoCommand(0, industry_type, seed, CMD_BUILD_INDUSTRY);
 
}
src/ai/api/ai_industrytype.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_industrytype.hpp Everything to query and build industries. */
 

	
 
#ifndef AI_INDUSTRYTYPE_HPP
 
#define AI_INDUSTRYTYPE_HPP
 

	
 
#include "ai_object.hpp"
 
#include "ai_error.hpp"
 
#include "ai_list.hpp"
 

	
 
/**
 
 * Class that handles all industry-type related functions.
 
 */
 
class AIIndustryType : public AIObject {
 
public:
 
	static const char *GetClassName() { return "AIIndustryType"; }
 

	
 
	/**
 
	 * Checks whether the given industry-type is valid.
 
	 * @param industry_type The type check.
 
	 * @return True if and only if the industry-type is valid.
 
	 */
 
	static bool IsValidIndustryType(IndustryType industry_type);
 

	
 
	/**
 
	 * Get the name of an industry-type.
 
	 * @param industry_type The type to get the name for.
 
	 * @pre IsValidIndustryType(industry_type).
 
	 * @return The name of an industry.
 
	 */
 
	static const char *GetName(IndustryType industry_type);
 

	
 
	/**
 
	 * Get a list of CargoID possible produced by this industry-type.
 
	 * @param industry_type The type to get the CargoIDs for.
 
	 * @pre IsValidIndustryType(industry_type).
 
	 * @return The CargoIDs of all cargotypes this industry could produce.
 
	 */
 
	static AIList *GetProducedCargo(IndustryType industry_type);
 

	
 
	/**
 
	 * Get a list of CargoID accepted by this industry-type.
 
	 * @param industry_type The type to get the CargoIDs for.
 
	 * @pre IsValidIndustryType(industry_type).
 
	 * @return The CargoIDs of all cargotypes this industry accepts.
 
	 */
 
	static AIList *GetAcceptedCargo(IndustryType industry_type);
 

	
 
	/**
 
	 * Is this industry type a raw industry?
 
	 * @param industry_type The type of the industry.
 
	 * @pre IsValidIndustryType(industry_type).
 
	 * @return True if it should be handled as a raw industry.
 
	 */
 
	static bool IsRawIndustry(IndustryType industry_type);
 

	
 
	/**
 
	 * Can the production of this industry increase?
 
	 * @param industry_type The type of the industry.
 
	 * @pre IsValidIndustryType(industry_type).
 
	 * @return True if the production of this industry can increase.
 
	 */
 
	static bool ProductionCanIncrease(IndustryType industry_type);
 

	
 
	/**
 
	 * Get the cost for building this industry-type.
 
	 * @param industry_type The type of the industry.
 
	 * @pre IsValidIndustryType(industry_type).
 
	 * @return The cost for building this industry-type.
 
	 */
 
	static Money GetConstructionCost(IndustryType industry_type);
 

	
 
	/**
 
	 * Can you build this type of industry?
 
	 * @param industry_type The type of the industry.
 
	 * @pre IsValidIndustryType(industry_type).
 
	 * @return True if you can prospect this type of industry.
 
	 * @note Returns false if you can only prospect this type of industry.
 
	 */
 
	static bool CanBuildIndustry(IndustryType industry_type);
 

	
 
	/**
 
	 * Can you prospect this type of industry?
 
	 * @param industry_type The type of the industry.
 
	 * @pre IsValidIndustryType(industry_type).
 
	 * @return True if you can prospect this type of industry.
 
	 * @note If the patch setting "Manual primary industry construction method" is set
 
	 * to either "None" or "as other industries" this function always returns false.
 
	 */
 
	static bool CanProspectIndustry(IndustryType industry_type);
 

	
 
	/**
 
	 * Build an industry of the specified type.
 
	 * @param industry_type The type of the industry to build.
 
	 * @param tile The tile to build the industry on.
 
	 * @pre CanBuildIndustry(industry_type).
 
	 * @return True if the industry was succesfully build.
 
	 */
 
	static bool BuildIndustry(IndustryType industry_type, TileIndex tile);
 

	
 
	/**
 
	 * Prospect an industry of this type. Prospecting an industries let the game try to create
 
	 * an industry on a random place on the map.
 
	 * @param industry_type The type of the industry.
 
	 * @pre CanProspectIndustry(industry_type).
 
	 * @return True if no error occured while trying to prospect.
 
	 * @note Even if true is returned there is no guarantee a new industry is build.
 
	 * @note If true is returned the money is paid, whether a new industry was build or not.
 
	 */
 
	static bool ProspectIndustry(IndustryType industry_type);
 
};
 

	
 
#endif /* AI_INDUSTRYTYPE_HPP */
src/ai/api/ai_industrytype.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_industrytype.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow AIIndustryType to be used as Squirrel parameter */
 
	template <> AIIndustryType *GetParam(ForceType<AIIndustryType *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIIndustryType *)instance; }
 
	template <> AIIndustryType &GetParam(ForceType<AIIndustryType &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIIndustryType *)instance; }
 
	template <> const AIIndustryType *GetParam(ForceType<const AIIndustryType *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIIndustryType *)instance; }
 
	template <> const AIIndustryType &GetParam(ForceType<const AIIndustryType &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIIndustryType *)instance; }
 
	template <> int Return<AIIndustryType *>(HSQUIRRELVM vm, AIIndustryType *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIIndustryType", res, NULL, DefSQDestructorCallback<AIIndustryType>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIIndustryType_Register(Squirrel *engine) {
 
	DefSQClass <AIIndustryType> SQAIIndustryType("AIIndustryType");
 
	SQAIIndustryType.PreRegister(engine);
 
	SQAIIndustryType.AddConstructor<void (AIIndustryType::*)(), 1>(engine, "x");
 

	
 
	SQAIIndustryType.DefSQStaticMethod(engine, &AIIndustryType::GetClassName,          "GetClassName",          1, "x");
 
	SQAIIndustryType.DefSQStaticMethod(engine, &AIIndustryType::IsValidIndustryType,   "IsValidIndustryType",   2, "xi");
 
	SQAIIndustryType.DefSQStaticMethod(engine, &AIIndustryType::GetName,               "GetName",               2, "xi");
 
	SQAIIndustryType.DefSQStaticMethod(engine, &AIIndustryType::GetProducedCargo,      "GetProducedCargo",      2, "xi");
 
	SQAIIndustryType.DefSQStaticMethod(engine, &AIIndustryType::GetAcceptedCargo,      "GetAcceptedCargo",      2, "xi");
 
	SQAIIndustryType.DefSQStaticMethod(engine, &AIIndustryType::IsRawIndustry,         "IsRawIndustry",         2, "xi");
 
	SQAIIndustryType.DefSQStaticMethod(engine, &AIIndustryType::ProductionCanIncrease, "ProductionCanIncrease", 2, "xi");
 
	SQAIIndustryType.DefSQStaticMethod(engine, &AIIndustryType::GetConstructionCost,   "GetConstructionCost",   2, "xi");
 
	SQAIIndustryType.DefSQStaticMethod(engine, &AIIndustryType::CanBuildIndustry,      "CanBuildIndustry",      2, "xi");
 
	SQAIIndustryType.DefSQStaticMethod(engine, &AIIndustryType::CanProspectIndustry,   "CanProspectIndustry",   2, "xi");
 
	SQAIIndustryType.DefSQStaticMethod(engine, &AIIndustryType::BuildIndustry,         "BuildIndustry",         3, "xii");
 
	SQAIIndustryType.DefSQStaticMethod(engine, &AIIndustryType::ProspectIndustry,      "ProspectIndustry",      2, "xi");
 

	
 
	SQAIIndustryType.PostRegister(engine);
 
}
src/ai/api/ai_industrytypelist.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_industrytypelist.cpp Implementation of AIIndustryTypeList. */
 

	
 
#include "ai_industrytypelist.hpp"
 
#include "../../openttd.h"
 
#include "../../tile_type.h"
 
#include "../../industry.h"
 

	
 
AIIndustryTypeList::AIIndustryTypeList()
 
{
 
	for (int i = 0; i < NUM_INDUSTRYTYPES; i++) {
 
		if (AIIndustryType::IsValidIndustryType(i)) this->AddItem(i);
 
	}
 
}
src/ai/api/ai_industrytypelist.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_industrytypelist.hpp List all available industry types. */
 

	
 
#ifndef AI_INDUSTRYTYPELIST_HPP
 
#define AI_INDUSTRYTYPELIST_HPP
 

	
 
#include "ai_abstractlist.hpp"
 
#include "ai_industrytype.hpp"
 

	
 
/**
 
 * Creates a list of valid industry types.
 
 * @ingroup AIList
 
 */
 
class AIIndustryTypeList : public AIAbstractList {
 
public:
 
	static const char *GetClassName() { return "AIIndustryTypeList"; }
 
	AIIndustryTypeList();
 
};
 

	
 

	
 
#endif /* AI_INDUSTRYTYPELIST_HPP */
src/ai/api/ai_industrytypelist.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_industrytypelist.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow AIIndustryTypeList to be used as Squirrel parameter */
 
	template <> AIIndustryTypeList *GetParam(ForceType<AIIndustryTypeList *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIIndustryTypeList *)instance; }
 
	template <> AIIndustryTypeList &GetParam(ForceType<AIIndustryTypeList &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIIndustryTypeList *)instance; }
 
	template <> const AIIndustryTypeList *GetParam(ForceType<const AIIndustryTypeList *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIIndustryTypeList *)instance; }
 
	template <> const AIIndustryTypeList &GetParam(ForceType<const AIIndustryTypeList &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIIndustryTypeList *)instance; }
 
	template <> int Return<AIIndustryTypeList *>(HSQUIRRELVM vm, AIIndustryTypeList *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIIndustryTypeList", res, NULL, DefSQDestructorCallback<AIIndustryTypeList>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIIndustryTypeList_Register(Squirrel *engine) {
 
	DefSQClass <AIIndustryTypeList> SQAIIndustryTypeList("AIIndustryTypeList");
 
	SQAIIndustryTypeList.PreRegister(engine, "AIAbstractList");
 
	SQAIIndustryTypeList.AddConstructor<void (AIIndustryTypeList::*)(), 1>(engine, "x");
 

	
 
	SQAIIndustryTypeList.DefSQStaticMethod(engine, &AIIndustryTypeList::GetClassName, "GetClassName", 1, "x");
 

	
 
	SQAIIndustryTypeList.PostRegister(engine);
 
}
src/ai/api/ai_list.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_list.cpp Implementation of AIList. */
 

	
 
#include <squirrel.h>
 
#include "ai_list.hpp"
 

	
 
void AIList::AddItem(int32 item, int32 value)
 
{
 
	AIAbstractList::AddItem(item);
 
	this->SetValue(item, value);
 
}
 

	
 
void AIList::ChangeItem(int32 item, int32 value)
 
{
 
	this->SetValue(item, value);
 
}
 

	
 
void AIList::RemoveItem(int32 item)
 
{
 
	AIAbstractList::RemoveItem(item);
 
}
 

	
 
SQInteger AIList::_set(HSQUIRRELVM vm) {
 
	if (sq_gettype(vm, 2) != OT_INTEGER) return SQ_ERROR;
 
	if (sq_gettype(vm, 3) != OT_INTEGER || sq_gettype(vm, 3) == OT_NULL) {
 
		return sq_throwerror(vm, _SC("you can only assign integers to this list"));
 
	}
 

	
 
	SQInteger idx, val;
 
	sq_getinteger(vm, 2, &idx);
 
	if (sq_gettype(vm, 3) == OT_NULL) {
 
		this->RemoveItem(idx);
 
		return 0;
 
	}
 

	
 
	sq_getinteger(vm, 3, &val);
 
	if (!this->HasItem(idx)) {
 
		this->AddItem(idx, val);
 
		return 0;
 
	}
 

	
 
	this->ChangeItem(idx, val);
 
	return 0;
 
}
src/ai/api/ai_list.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_list.hpp List custom entries. */
 

	
 
#ifndef AI_LIST_HPP
 
#define AI_LIST_HPP
 

	
 
#include "ai_abstractlist.hpp"
 

	
 
/**
 
 * Creates an empty list, in which you can add integers.
 
 * @ingroup AIList
 
 */
 
class AIList : public AIAbstractList {
 
public:
 
	static const char *GetClassName() { return "AIList"; }
 

	
 
public:
 
	/**
 
	 * Add an item to the list.
 
	 * @param item the item to add.
 
	 * @param value the value to assign.
 
	 */
 
	void AddItem(int32 item, int32 value);
 

	
 
	/**
 
	 * Change the value of an item in the list.
 
	 * @param item the item to change
 
	 * @param value the value to assign.
 
	 */
 
	void ChangeItem(int32 item, int32 value);
 

	
 
	/**
 
	 * Remove the item from the list.
 
	 * @param item the item to remove.
 
	 */
 
	void RemoveItem(int32 item);
 

	
 
#ifndef DOXYGEN_SKIP
 
	/**
 
	 * Used for [] set from Squirrel.
 
	 */
 
	SQInteger _set(HSQUIRRELVM vm);
 
#endif /* DOXYGEN_SKIP */
 
};
 

	
 
#endif /* AI_LIST_HPP */
src/ai/api/ai_list.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_list.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow AIList to be used as Squirrel parameter */
 
	template <> AIList *GetParam(ForceType<AIList *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIList *)instance; }
 
	template <> AIList &GetParam(ForceType<AIList &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIList *)instance; }
 
	template <> const AIList *GetParam(ForceType<const AIList *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIList *)instance; }
 
	template <> const AIList &GetParam(ForceType<const AIList &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIList *)instance; }
 
	template <> int Return<AIList *>(HSQUIRRELVM vm, AIList *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIList", res, NULL, DefSQDestructorCallback<AIList>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIList_Register(Squirrel *engine) {
 
	DefSQClass <AIList> SQAIList("AIList");
 
	SQAIList.PreRegister(engine, "AIAbstractList");
 
	SQAIList.AddConstructor<void (AIList::*)(), 1>(engine, "x");
 

	
 
	SQAIList.DefSQStaticMethod(engine, &AIList::GetClassName, "GetClassName", 1, "x");
 

	
 
	SQAIList.DefSQMethod(engine, &AIList::AddItem,    "AddItem",    3, "xii");
 
	SQAIList.DefSQMethod(engine, &AIList::ChangeItem, "ChangeItem", 3, "xii");
 
	SQAIList.DefSQMethod(engine, &AIList::RemoveItem, "RemoveItem", 2, "xi");
 
	SQAIList.DefSQAdvancedMethod(engine, &AIList::_set, "_set");
 

	
 
	SQAIList.PostRegister(engine);
 
}
src/ai/api/ai_log.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_log.cpp Implementation of AILog. */
 

	
 
#include "ai_log.hpp"
 
#include "../../core/alloc_func.hpp"
 
#include "../../company_func.h"
 
#include "../../debug.h"
 
#include "../../window_func.h"
 

	
 
/* static */ void AILog::Info(const char *message)
 
{
 
	AILog::Log(LOG_INFO, message);
 
}
 

	
 
/* static */ void AILog::Warning(const char *message)
 
{
 
	AILog::Log(LOG_WARNING, message);
 
}
 

	
 
/* static */ void AILog::Error(const char *message)
 
{
 
	AILog::Log(LOG_ERROR, message);
 
}
 

	
 
/* static */ void AILog::Log(AILog::AILogType level, const char *message)
 
{
 
	if (AIObject::GetLogPointer() == NULL) {
 
		AIObject::GetLogPointer() = new LogData();
 
		LogData *log = (LogData *)AIObject::GetLogPointer();
 

	
 
		log->lines = CallocT<char *>(80);
 
		log->type = CallocT<AILog::AILogType>(80);
 
		log->count = 80;
 
		log->pos = log->count;
 
		log->used = 0;
 
	}
 
	LogData *log = (LogData *)AIObject::GetLogPointer();
 

	
 
	/* Go to the next log-line */
 
	log->pos = (log->pos + 1) % log->count;
 

	
 
	if (log->used != log->count) log->used++;
 

	
 
	/* Free last message, and write new message */
 
	free(log->lines[log->pos]);
 
	log->lines[log->pos] = strdup(message);
 
	log->type[log->pos] = level;
 

	
 
	/* Cut string after first \n */
 
	char *p;
 
	while ((p = strchr(log->lines[log->pos], '\n')) != NULL) {
 
		*p = '\0';
 
		break;
 
	}
 

	
 
	char logc;
 

	
 
	switch (level) {
 
		case LOG_SQ_ERROR: logc = 'S'; break;
 
		case LOG_ERROR:    logc = 'E'; break;
 
		case LOG_SQ_INFO:  logc = 'P'; break;
 
		case LOG_WARNING:  logc = 'W'; break;
 
		case LOG_INFO:     logc = 'I'; break;
 
		default:           logc = '?'; break;
 
	}
 

	
 
	/* Also still print to debug window */
 
	DEBUG(ai, level, "[%d] [%c] %s", (uint)_current_company, logc, log->lines[log->pos]);
 
	InvalidateWindowData(WC_AI_DEBUG, 0, _current_company);
 
}
 

	
 
/* static */ void AILog::FreeLogPointer()
 
{
 
	LogData *log = (LogData *)AIObject::GetLogPointer();
 

	
 
	for (int i = 0; i < log->count; i++) {
 
		free(log->lines[i]);
 
	}
 

	
 
	free(log->lines);
 
	free(log->type);
 
	delete log;
 
}
src/ai/api/ai_log.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_log.hpp Everything to handle and issue log messages. */
 

	
 
#ifndef AI_LOG_HPP
 
#define AI_LOG_HPP
 

	
 
#include "ai_object.hpp"
 

	
 
/**
 
 * Class that handles all log related functions.
 
 */
 
class AILog : public AIObject {
 
	/* AIController needs access to Enum and Log, in order to keep the flow from
 
	 *  OpenTTD core to NoAI API clear and simple. */
 
	friend class AIController;
 

	
 
public:
 
	static const char *GetClassName() { return "AILog"; }
 

	
 
	/**
 
	 * Log levels; The value is also feed to DEBUG() lvl.
 
	 *  This has no use for you, as AI writer.
 
	 */
 
	enum AILogType {
 
		LOG_SQ_ERROR = 0, //!< Squirrel printed an error.
 
		LOG_ERROR = 1,    //!< User printed an error.
 
		LOG_SQ_INFO = 2,  //!< Squirrel printed some info.
 
		LOG_WARNING = 3,  //!< User printed some warning.
 
		LOG_INFO = 4,     //!< User printed some info.
 
	};
 

	
 
	/**
 
	 * Internal representation of the log-data inside the AI.
 
	 *  This has no use for you, as AI writer.
 
	 */
 
	struct LogData {
 
		char **lines;           //!< The log-lines.
 
		AILog::AILogType *type; //!< Per line, which type of log it was.
 
		int count;              //!< Total amount of log-lines possible.
 
		int pos;                //!< Current position in lines.
 
		int used;               //!< Total amount of used log-lines.
 
	};
 

	
 
	/**
 
	 * Print an Info message to the logs.
 
	 * @param message The message to log.
 
	 */
 
	static void Info(const char *message);
 

	
 
	/**
 
	 * Print a Warning message to the logs.
 
	 * @param message The message to log.
 
	 */
 
	static void Warning(const char *message);
 

	
 
	/**
 
	 * Print an Error message to the logs.
 
	 * @param message The message to log.
 
	 */
 
	static void Error(const char *message);
 

	
 
	/**
 
	 * Free the log pointer.
 
	 * @note DO NOT CALL YOURSELF; leave it to the internal AI programming.
 
	 */
 
	static void FreeLogPointer();
 

	
 
private:
 
	/**
 
	 * Internal command to log the message in a common way.
 
	 */
 
	static void Log(AILog::AILogType level, const char *message);
 
};
 

	
 
#endif /* AI_LOG_HPP */
src/ai/api/ai_log.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_log.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow enums to be used as Squirrel parameters */
 
	template <> AILog::AILogType GetParam(ForceType<AILog::AILogType>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AILog::AILogType)tmp; }
 
	template <> int Return<AILog::AILogType>(HSQUIRRELVM vm, AILog::AILogType res) { sq_pushinteger(vm, (int32)res); return 1; }
 

	
 
	/* Allow AILog to be used as Squirrel parameter */
 
	template <> AILog *GetParam(ForceType<AILog *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AILog *)instance; }
 
	template <> AILog &GetParam(ForceType<AILog &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AILog *)instance; }
 
	template <> const AILog *GetParam(ForceType<const AILog *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AILog *)instance; }
 
	template <> const AILog &GetParam(ForceType<const AILog &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AILog *)instance; }
 
	template <> int Return<AILog *>(HSQUIRRELVM vm, AILog *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AILog", res, NULL, DefSQDestructorCallback<AILog>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAILog_Register(Squirrel *engine) {
 
	DefSQClass <AILog> SQAILog("AILog");
 
	SQAILog.PreRegister(engine);
 
	SQAILog.AddConstructor<void (AILog::*)(), 1>(engine, "x");
 

	
 
	SQAILog.DefSQConst(engine, AILog::LOG_SQ_ERROR, "LOG_SQ_ERROR");
 
	SQAILog.DefSQConst(engine, AILog::LOG_ERROR,    "LOG_ERROR");
 
	SQAILog.DefSQConst(engine, AILog::LOG_SQ_INFO,  "LOG_SQ_INFO");
 
	SQAILog.DefSQConst(engine, AILog::LOG_WARNING,  "LOG_WARNING");
 
	SQAILog.DefSQConst(engine, AILog::LOG_INFO,     "LOG_INFO");
 

	
 
	SQAILog.DefSQStaticMethod(engine, &AILog::GetClassName,   "GetClassName",   1, "x");
 
	SQAILog.DefSQStaticMethod(engine, &AILog::Info,           "Info",           2, "xs");
 
	SQAILog.DefSQStaticMethod(engine, &AILog::Warning,        "Warning",        2, "xs");
 
	SQAILog.DefSQStaticMethod(engine, &AILog::Error,          "Error",          2, "xs");
 
	SQAILog.DefSQStaticMethod(engine, &AILog::FreeLogPointer, "FreeLogPointer", 1, "x");
 

	
 
	SQAILog.PostRegister(engine);
 
}
src/ai/api/ai_map.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_map.cpp Implementation of AIMap. */
 

	
 
#include "ai_map.hpp"
 
#include "../../map_func.h"
 
#include "../../tile_map.h"
 

	
 
/* static */ bool AIMap::IsValidTile(TileIndex t)
 
{
 
	return ::IsValidTile(t);
 
}
 

	
 
/* static */ TileIndex AIMap::GetMapSize()
 
{
 
	return ::MapSize();
 
}
 

	
 
/* static */ uint32 AIMap::GetMapSizeX()
 
{
 
	return ::MapSizeX();
 
}
 

	
 
/* static */ uint32 AIMap::GetMapSizeY()
 
{
 
	return ::MapSizeY();
 
}
 

	
 
/* static */ uint32 AIMap::GetTileX(TileIndex t)
 
{
 
	return ::TileX(t);
 
}
 

	
 
/* static */ uint32 AIMap::GetTileY(TileIndex t)
 
{
 
	return ::TileY(t);
 
}
 

	
 
/* static */ TileIndex AIMap::GetTileIndex(uint32 x, uint32 y)
 
{
 
	return ::TileXY(x, y);
 
}
 

	
 
/* static */ uint32 AIMap::DistanceManhattan(TileIndex t1, TileIndex t2)
 
{
 
	return ::DistanceManhattan(t1, t2);
 
}
 

	
 
/* static */ uint32 AIMap::DistanceMax(TileIndex t1, TileIndex t2)
 
{
 
	return ::DistanceMax(t1, t2);
 
}
 

	
 
/* static */ uint32 AIMap::DistanceSquare(TileIndex t1, TileIndex t2)
 
{
 
	return ::DistanceSquare(t1, t2);
 
}
 

	
 
/* static */ uint32 AIMap::DistanceFromEdge(TileIndex t)
 
{
 
	return ::DistanceFromEdge(t);
 
}
src/ai/api/ai_map.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_map.hpp Everything to query and manipulate map metadata. */
 

	
 
#ifndef AI_MAP_HPP
 
#define AI_MAP_HPP
 

	
 
#include "ai_object.hpp"
 

	
 
/**
 
 * Class that handles all map related functions.
 
 */
 
class AIMap : public AIObject {
 
public:
 
	static const char *GetClassName() { return "AIMap"; }
 

	
 
	/**
 
	 * Checks whether the given tile is valid.
 
	 * @param tile The tile to check.
 
	 * @return True is the tile it within the boundaries of the map.
 
	 */
 
	static bool IsValidTile(TileIndex tile);
 

	
 
	/**
 
	 * Gets the number of tiles in the map.
 
	 * @return The size of the map in tiles.
 
	 * @post Return value is always positive.
 
	 */
 
	static TileIndex GetMapSize();
 

	
 
	/**
 
	 * Gets the amount of tiles along the SW and NE border.
 
	 * @return The length along the SW and NE borders.
 
	 * @post Return value is always positive.
 
	 */
 
	static uint32 GetMapSizeX();
 

	
 
	/**
 
	 * Gets the amount of tiles along the SE and NW border.
 
	 * @return The length along the SE and NW borders.
 
	 * @post Return value is always positive.
 
	 */
 
	static uint32 GetMapSizeY();
 

	
 
	/**
 
	 * Gets the place along the SW/NE border (X-value).
 
	 * @param tile The tile to get the X-value of.
 
	 * @pre IsValidTile(tile).
 
	 * @return The X-value.
 
	 * @post Return value is always lower than GetMapSizeX().
 
	 */
 
	static uint32 GetTileX(TileIndex tile);
 

	
 
	/**
 
	 * Gets the place along the SE/NW border (Y-value).
 
	 * @param tile The tile to get the Y-value of.
 
	 * @pre IsValidTile(tile).
 
	 * @return The Y-value.
 
	 * @post Return value is always lower than GetMapSizeY().
 
	 */
 
	static uint32 GetTileY(TileIndex tile);
 

	
 
	/**
 
	 * Gets the TileIndex given a x,y-coordinate.
 
	 * @param x The X coordinate.
 
	 * @param y The Y coordinate.
 
	 * @pre x < GetMapSizeX().
 
	 * @pre y < GetMapSizeY().
 
	 * @return The TileIndex for the given (x,y) coordinate.
 
	 */
 
	static TileIndex GetTileIndex(uint32 x, uint32 y);
 

	
 
	/**
 
	 * Calculates the Manhattan distance; the difference of
 
	 *  the X and Y added together.
 
	 * @param tile_from The start tile.
 
	 * @param tile_to The destination tile.
 
	 * @pre IsValidTile(tile_from).
 
	 * @pre IsValidTile(tile_to).
 
	 * @return The Manhattan distance between the tiles.
 
	 */
 
	static uint32 DistanceManhattan(TileIndex tile_from, TileIndex tile_to);
 

	
 
	/**
 
	 * Calculates the distance between two tiles via 1D calculation.
 
	 *  This means the distance between X or the distance between Y, depending
 
	 *  on which one is bigger.
 
	 * @param tile_from The start tile.
 
	 * @param tile_to The destination tile.
 
	 * @pre IsValidTile(tile_from).
 
	 * @pre IsValidTile(tile_to).
 
	 * @return The maximum distance between the tiles.
 
	 */
 
	static uint32 DistanceMax(TileIndex tile_from, TileIndex tile_to);
 

	
 
	/**
 
	 * The squared distance between the two tiles.
 
	 *  This is the distance is the length of the shortest straight line
 
	 *  between both points.
 
	 * @param tile_from The start tile.
 
	 * @param tile_to The destination tile.
 
	 * @pre IsValidTile(tile_from).
 
	 * @pre IsValidTile(tile_to).
 
	 * @return The squared distance between the tiles.
 
	 */
 
	static uint32 DistanceSquare(TileIndex tile_from, TileIndex tile_to);
 

	
 
	/**
 
	 * Calculates the shortest distance to the edge.
 
	 * @param tile From where the distance has to be calculated.
 
	 * @pre IsValidTile(tile).
 
	 * @return The distances to the closest edge.
 
	 */
 
	static uint32 DistanceFromEdge(TileIndex tile);
 
};
 

	
 
#endif /* AI_MAP_HPP */
src/ai/api/ai_map.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_map.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow AIMap to be used as Squirrel parameter */
 
	template <> AIMap *GetParam(ForceType<AIMap *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIMap *)instance; }
 
	template <> AIMap &GetParam(ForceType<AIMap &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIMap *)instance; }
 
	template <> const AIMap *GetParam(ForceType<const AIMap *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIMap *)instance; }
 
	template <> const AIMap &GetParam(ForceType<const AIMap &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIMap *)instance; }
 
	template <> int Return<AIMap *>(HSQUIRRELVM vm, AIMap *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIMap", res, NULL, DefSQDestructorCallback<AIMap>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIMap_Register(Squirrel *engine) {
 
	DefSQClass <AIMap> SQAIMap("AIMap");
 
	SQAIMap.PreRegister(engine);
 
	SQAIMap.AddConstructor<void (AIMap::*)(), 1>(engine, "x");
 

	
 
	SQAIMap.DefSQStaticMethod(engine, &AIMap::GetClassName,      "GetClassName",      1, "x");
 
	SQAIMap.DefSQStaticMethod(engine, &AIMap::IsValidTile,       "IsValidTile",       2, "xi");
 
	SQAIMap.DefSQStaticMethod(engine, &AIMap::GetMapSize,        "GetMapSize",        1, "x");
 
	SQAIMap.DefSQStaticMethod(engine, &AIMap::GetMapSizeX,       "GetMapSizeX",       1, "x");
 
	SQAIMap.DefSQStaticMethod(engine, &AIMap::GetMapSizeY,       "GetMapSizeY",       1, "x");
 
	SQAIMap.DefSQStaticMethod(engine, &AIMap::GetTileX,          "GetTileX",          2, "xi");
 
	SQAIMap.DefSQStaticMethod(engine, &AIMap::GetTileY,          "GetTileY",          2, "xi");
 
	SQAIMap.DefSQStaticMethod(engine, &AIMap::GetTileIndex,      "GetTileIndex",      3, "xii");
 
	SQAIMap.DefSQStaticMethod(engine, &AIMap::DistanceManhattan, "DistanceManhattan", 3, "xii");
 
	SQAIMap.DefSQStaticMethod(engine, &AIMap::DistanceMax,       "DistanceMax",       3, "xii");
 
	SQAIMap.DefSQStaticMethod(engine, &AIMap::DistanceSquare,    "DistanceSquare",    3, "xii");
 
	SQAIMap.DefSQStaticMethod(engine, &AIMap::DistanceFromEdge,  "DistanceFromEdge",  2, "xi");
 

	
 
	SQAIMap.PostRegister(engine);
 
}
src/ai/api/ai_marine.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_marine.cpp Implementation of AIMarine. */
 

	
 
#include "ai_marine.hpp"
 
#include "../../openttd.h"
 
#include "../../command_type.h"
 
#include "../../variables.h"
 
#include "../../station_map.h"
 
#include "../../water_map.h"
 
#include "../../tile_cmd.h"
 

	
 

	
 
/* static */ bool AIMarine::IsWaterDepotTile(TileIndex tile)
 
{
 
	if (!::IsValidTile(tile)) return false;
 

	
 
	return ::IsTileType(tile, MP_WATER) && ::GetWaterTileType(tile) == WATER_TILE_DEPOT;
 
}
 

	
 
/* static */ bool AIMarine::IsDockTile(TileIndex tile)
 
{
 
	if (!::IsValidTile(tile)) return false;
 

	
 
	return ::IsTileType(tile, MP_STATION) && ::IsDock(tile);
 
}
 

	
 
/* static */ bool AIMarine::IsBuoyTile(TileIndex tile)
 
{
 
	if (!::IsValidTile(tile)) return false;
 

	
 
	return ::IsTileType(tile, MP_STATION) && ::IsBuoy(tile);
 
}
 

	
 
/* static */ bool AIMarine::IsLockTile(TileIndex tile)
 
{
 
	if (!::IsValidTile(tile)) return false;
 

	
 
	return ::IsTileType(tile, MP_WATER) && ::GetWaterTileType(tile) == WATER_TILE_LOCK;
 
}
 

	
 
/* static */ bool AIMarine::IsCanalTile(TileIndex tile)
 
{
 
	if (!::IsValidTile(tile)) return false;
 

	
 
	return ::IsTileType(tile, MP_WATER) && ::IsCanal(tile);
 
}
 

	
 
/* static */ bool AIMarine::AreWaterTilesConnected(TileIndex t1, TileIndex t2)
 
{
 
	if (!::IsValidTile(t1)) return false;
 
	if (!::IsValidTile(t2)) return false;
 

	
 
	/* Tiles not neighbouring */
 
	if (::DistanceManhattan(t1, t2) != 1) return false;
 
	if (t1 > t2) Swap(t1, t2);
 

	
 
	uint32 gtts1 = ::GetTileTrackStatus(t1, TRANSPORT_WATER, 0);
 
	uint32 gtts2 = ::GetTileTrackStatus(t2, TRANSPORT_WATER, 0);
 

	
 
	/* Ship can't travel on one of the tiles. */
 
	if (gtts1 == 0 || gtts2 == 0) return false;
 

	
 
	DiagDirection to_other_tile = (TileX(t1) == TileX(t2)) ? DIAGDIR_SE : DIAGDIR_SW;
 

	
 
	/* Check whether we can 'leave' the tile at the border and 'enter' the other tile at the border */
 
	return (gtts1 & DiagdirReachesTrackdirs(ReverseDiagDir(to_other_tile))) != 0 && (gtts2 & DiagdirReachesTrackdirs(to_other_tile)) != 0;
 
}
 

	
 
/* static */ bool AIMarine::BuildWaterDepot(TileIndex tile, bool vertical)
 
{
 
	EnforcePrecondition(false, ::IsValidTile(tile));
 

	
 
	return AIObject::DoCommand(tile, vertical, 0, CMD_BUILD_SHIP_DEPOT);
 
}
 

	
 
/* static */ bool AIMarine::BuildDock(TileIndex tile, bool join_adjacent)
 
{
 
	EnforcePrecondition(false, ::IsValidTile(tile));
 

	
 
	return AIObject::DoCommand(tile, join_adjacent ? 0 : 1, INVALID_STATION << 16, CMD_BUILD_DOCK);
 
}
 

	
 
/* static */ bool AIMarine::BuildBuoy(TileIndex tile)
 
{
 
	EnforcePrecondition(false, ::IsValidTile(tile));
 

	
 
	return AIObject::DoCommand(tile, 0, 0, CMD_BUILD_BUOY);
 
}
 

	
 
/* static */ bool AIMarine::BuildLock(TileIndex tile)
 
{
 
	EnforcePrecondition(false, ::IsValidTile(tile));
 

	
 
	return AIObject::DoCommand(tile, 0, 0, CMD_BUILD_LOCK);
 
}
 

	
 
/* static */ bool AIMarine::BuildCanal(TileIndex tile)
 
{
 
	EnforcePrecondition(false, ::IsValidTile(tile));
 

	
 
	return AIObject::DoCommand(tile, tile, 0, CMD_BUILD_CANAL);
 
}
 

	
 
/* static */ bool AIMarine::RemoveWaterDepot(TileIndex tile)
 
{
 
	EnforcePrecondition(false, ::IsValidTile(tile));
 
	EnforcePrecondition(false, IsWaterDepotTile(tile));
 

	
 
	return AIObject::DoCommand(tile, 0, 0, CMD_LANDSCAPE_CLEAR);
 
}
 

	
 
/* static */ bool AIMarine::RemoveDock(TileIndex tile)
 
{
 
	EnforcePrecondition(false, ::IsValidTile(tile));
 
	EnforcePrecondition(false, IsDockTile(tile));
 

	
 
	return AIObject::DoCommand(tile, 0, 0, CMD_LANDSCAPE_CLEAR);
 
}
 

	
 
/* static */ bool AIMarine::RemoveBuoy(TileIndex tile)
 
{
 
	EnforcePrecondition(false, ::IsValidTile(tile));
 
	EnforcePrecondition(false, IsBuoyTile(tile));
 

	
 
	return AIObject::DoCommand(tile, 0, 0, CMD_LANDSCAPE_CLEAR);
 
}
 

	
 
/* static */ bool AIMarine::RemoveLock(TileIndex tile)
 
{
 
	EnforcePrecondition(false, ::IsValidTile(tile));
 
	EnforcePrecondition(false, IsLockTile(tile));
 

	
 
	return AIObject::DoCommand(tile, 0, 0, CMD_LANDSCAPE_CLEAR);
 
}
 

	
 
/* static */ bool AIMarine::RemoveCanal(TileIndex tile)
 
{
 
	EnforcePrecondition(false, ::IsValidTile(tile));
 
	EnforcePrecondition(false, IsCanalTile(tile));
 

	
 
	return AIObject::DoCommand(tile, 0, 0, CMD_LANDSCAPE_CLEAR);
 
}
src/ai/api/ai_marine.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_marine.hpp Everything to query and build marine. */
 

	
 
#ifndef AI_MARINE_HPP
 
#define AI_MARINE_HPP
 

	
 
#include "ai_object.hpp"
 
#include "ai_error.hpp"
 

	
 
/**
 
 * Class that handles all marine related functions.
 
 */
 
class AIMarine : public AIObject {
 
public:
 
	static const char *GetClassName() { return "AIMarine"; }
 

	
 
	/**
 
	 * All marine related error messages.
 
	 */
 
	enum ErrorMessages {
 
		/** Base for marine related errors */
 
		ERR_MARINE_BASE = AIError::ERR_CAT_MARINE << AIError::ERR_CAT_BIT_SIZE,
 

	
 
		/** Infrastructure must be built on water */
 
		ERR_MARINE_MUST_BE_BUILT_ON_WATER,                  // [STR_3801_MUST_BE_BUILT_ON_WATER]
 
	};
 

	
 
	/**
 
	 * Checks whether the given tile is actually a tile with a water depot.
 
	 * @param tile The tile to check.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @return True if and only if the tile has a water depot.
 
	 */
 
	static bool IsWaterDepotTile(TileIndex tile);
 

	
 
	/**
 
	 * Checks whether the given tile is actually a tile with a dock.
 
	 * @param tile The tile to check.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @return True if and only if the tile has a dock.
 
	 */
 
	static bool IsDockTile(TileIndex tile);
 

	
 
	/**
 
	 * Checks whether the given tile is actually a tile with a buoy.
 
	 * @param tile The tile to check.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @return True if and only if the tile has a buoy.
 
	 */
 
	static bool IsBuoyTile(TileIndex tile);
 

	
 
	/**
 
	 * Checks whether the given tile is actually a tile with a lock.
 
	 * @param tile The tile to check.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @return True if and only if the tile has a lock.
 
	 */
 
	static bool IsLockTile(TileIndex tile);
 

	
 
	/**
 
	 * Checks whether the given tile is actually a tile with a canal.
 
	 * @param tile The tile to check.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @return True if and only if the tile has a canal.
 
	 */
 
	static bool IsCanalTile(TileIndex tile);
 

	
 
	/**
 
	 * Checks whether the given tiles are directly connected, i.e. whether
 
	 *  a ship vehicle can travel from the center of the first tile to the
 
	 *  center of the second tile.
 
	 * @param tile_from The source tile.
 
	 * @param tile_to The destination tile.
 
	 * @pre AIMap::IsValidTile(tile_from).
 
	 * @pre AIMap::IsValidTile(tile_to).
 
	 * @pre 'tile_from' and 'tile_to' are directly neighbouring tiles.
 
	 * @return True if and only if a ship can go from tile_from to tile_to.
 
	 */
 
	static bool AreWaterTilesConnected(TileIndex tile_from, TileIndex tile_to);
 

	
 
	/**
 
	 * Builds a water depot on tile.
 
	 * @param tile The tile where the water depot will be build.
 
	 * @param vertical If true, depot will be vertical, else horizontal.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @exception AIError::ERR_AREA_NOT_CLEAR
 
	 * @exception AIError::ERR_SITE_UNSUITABLE
 
	 * @exception AIMarine::ERR_MARINE_MUST_BE_BUILT_ON_WATER
 
	 * @return Whether the water depot has been/can be build or not.
 
	 * @note A WaterDepot is 1 tile in width, and 2 tiles in length.
 
	 */
 
	static bool BuildWaterDepot(TileIndex tile, bool vertical);
 

	
 
	/**
 
	 * Builds a dock where tile is the tile still on land.
 
	 * @param tile The tile still on land of the dock.
 
	 * @param join_adjacent When building next to an other station, don't create a new station when this flag is true.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @exception AIError::ERR_AREA_NOT_CLEAR
 
	 * @exception AIError::ERR_SITE_UNSUITABLE
 
	 * @exception AIStation::ERR_STATION_TOO_CLOSE_TO_ANOTHER_STATION
 
	 * @exception AIStation::ERR_STATION_TOO_MANY_STATIONS
 
	 * @return Whether the dock has been/can be build or not.
 
	 */
 
	static bool BuildDock(TileIndex tile, bool join_adjacent);
 

	
 
	/**
 
	 * Builds a buoy on tile.
 
	 * @param tile The tile where the buoy will be build.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @exception AIError::ERR_AREA_NOT_CLEAR
 
	 * @exception AIError::ERR_SITE_UNSUITABLE
 
	 * @exception AIStation::ERR_STATION_TOO_MANY_STATIONS
 
	 * @return Whether the buoy has been/can be build or not.
 
	 */
 
	static bool BuildBuoy(TileIndex tile);
 

	
 
	/**
 
	 * Builds a lock on tile.
 
	 * @param tile The tile where the lock will be build.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @exception AIError::ERR_LAND_SLOPED_WRONG
 
	 * @exception AIError::ERR_SITE_UNSUITABLE
 
	 * @return Whether the lock has been/can be build or not.
 
	 */
 
	static bool BuildLock(TileIndex tile);
 

	
 
	/**
 
	 * Builds a canal on tile.
 
	 * @param tile The tile where the canal will be build.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @exception AIError::ERR_AREA_NOT_CLEAR
 
	 * @exception AIError::ERR_LAND_SLOPED_WRONG
 
	 * @exception AIError::ERR_OWNED_BY_ANOTHER_COMPANY
 
	 * @exception AIError::ERR_ALREADY_BUILT
 
	 * @return Whether the canal has been/can be build or not.
 
	 */
 
	static bool BuildCanal(TileIndex tile);
 

	
 
	/**
 
	 * Removes a water depot.
 
	 * @param tile Any tile of the water depot.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @exception AIError::ERR_OWNED_BY_ANOTHER_COMPANY
 
	 * @return Whether the water depot has been/can be removed or not.
 
	 */
 
	static bool RemoveWaterDepot(TileIndex tile);
 

	
 
	/**
 
	 * Removes a dock.
 
	 * @param tile Any tile of the dock.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @exception AIError::ERR_OWNED_BY_ANOTHER_COMPANY
 
	 * @return Whether the dock has been/can be removed or not.
 
	 */
 
	static bool RemoveDock(TileIndex tile);
 

	
 
	/**
 
	 * Removes a buoy.
 
	 * @param tile Any tile of the buoy.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @exception AIError::ERR_OWNED_BY_ANOTHER_COMPANY
 
	 * @return Whether the buoy has been/can be removed or not.
 
	 */
 
	static bool RemoveBuoy(TileIndex tile);
 

	
 
	/**
 
	 * Removes a lock.
 
	 * @param tile Any tile of the lock.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @exception AIError::ERR_OWNED_BY_ANOTHER_COMPANY
 
	 * @return Whether the lock has been/can be removed or not.
 
	 */
 
	static bool RemoveLock(TileIndex tile);
 

	
 
	/**
 
	 * Removes a canal.
 
	 * @param tile Any tile of the canal.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @exception AIError::ERR_OWNED_BY_ANOTHER_COMPANY
 
	 * @return Whether the canal has been/can be removed or not.
 
	 */
 
	static bool RemoveCanal(TileIndex tile);
 
};
 

	
 
#endif /* AI_MARINE_HPP */
src/ai/api/ai_marine.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_marine.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow enums to be used as Squirrel parameters */
 
	template <> AIMarine::ErrorMessages GetParam(ForceType<AIMarine::ErrorMessages>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AIMarine::ErrorMessages)tmp; }
 
	template <> int Return<AIMarine::ErrorMessages>(HSQUIRRELVM vm, AIMarine::ErrorMessages res) { sq_pushinteger(vm, (int32)res); return 1; }
 

	
 
	/* Allow AIMarine to be used as Squirrel parameter */
 
	template <> AIMarine *GetParam(ForceType<AIMarine *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIMarine *)instance; }
 
	template <> AIMarine &GetParam(ForceType<AIMarine &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIMarine *)instance; }
 
	template <> const AIMarine *GetParam(ForceType<const AIMarine *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIMarine *)instance; }
 
	template <> const AIMarine &GetParam(ForceType<const AIMarine &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIMarine *)instance; }
 
	template <> int Return<AIMarine *>(HSQUIRRELVM vm, AIMarine *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIMarine", res, NULL, DefSQDestructorCallback<AIMarine>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIMarine_Register(Squirrel *engine) {
 
	DefSQClass <AIMarine> SQAIMarine("AIMarine");
 
	SQAIMarine.PreRegister(engine);
 
	SQAIMarine.AddConstructor<void (AIMarine::*)(), 1>(engine, "x");
 

	
 
	SQAIMarine.DefSQConst(engine, AIMarine::ERR_MARINE_BASE,                   "ERR_MARINE_BASE");
 
	SQAIMarine.DefSQConst(engine, AIMarine::ERR_MARINE_MUST_BE_BUILT_ON_WATER, "ERR_MARINE_MUST_BE_BUILT_ON_WATER");
 

	
 
	AIError::RegisterErrorMap(STR_3801_MUST_BE_BUILT_ON_WATER, AIMarine::ERR_MARINE_MUST_BE_BUILT_ON_WATER);
 

	
 
	AIError::RegisterErrorMapString(AIMarine::ERR_MARINE_MUST_BE_BUILT_ON_WATER, "ERR_MARINE_MUST_BE_BUILT_ON_WATER");
 

	
 
	SQAIMarine.DefSQStaticMethod(engine, &AIMarine::GetClassName,           "GetClassName",           1, "x");
 
	SQAIMarine.DefSQStaticMethod(engine, &AIMarine::IsWaterDepotTile,       "IsWaterDepotTile",       2, "xi");
 
	SQAIMarine.DefSQStaticMethod(engine, &AIMarine::IsDockTile,             "IsDockTile",             2, "xi");
 
	SQAIMarine.DefSQStaticMethod(engine, &AIMarine::IsBuoyTile,             "IsBuoyTile",             2, "xi");
 
	SQAIMarine.DefSQStaticMethod(engine, &AIMarine::IsLockTile,             "IsLockTile",             2, "xi");
 
	SQAIMarine.DefSQStaticMethod(engine, &AIMarine::IsCanalTile,            "IsCanalTile",            2, "xi");
 
	SQAIMarine.DefSQStaticMethod(engine, &AIMarine::AreWaterTilesConnected, "AreWaterTilesConnected", 3, "xii");
 
	SQAIMarine.DefSQStaticMethod(engine, &AIMarine::BuildWaterDepot,        "BuildWaterDepot",        3, "xib");
 
	SQAIMarine.DefSQStaticMethod(engine, &AIMarine::BuildDock,              "BuildDock",              3, "xib");
 
	SQAIMarine.DefSQStaticMethod(engine, &AIMarine::BuildBuoy,              "BuildBuoy",              2, "xi");
 
	SQAIMarine.DefSQStaticMethod(engine, &AIMarine::BuildLock,              "BuildLock",              2, "xi");
 
	SQAIMarine.DefSQStaticMethod(engine, &AIMarine::BuildCanal,             "BuildCanal",             2, "xi");
 
	SQAIMarine.DefSQStaticMethod(engine, &AIMarine::RemoveWaterDepot,       "RemoveWaterDepot",       2, "xi");
 
	SQAIMarine.DefSQStaticMethod(engine, &AIMarine::RemoveDock,             "RemoveDock",             2, "xi");
 
	SQAIMarine.DefSQStaticMethod(engine, &AIMarine::RemoveBuoy,             "RemoveBuoy",             2, "xi");
 
	SQAIMarine.DefSQStaticMethod(engine, &AIMarine::RemoveLock,             "RemoveLock",             2, "xi");
 
	SQAIMarine.DefSQStaticMethod(engine, &AIMarine::RemoveCanal,            "RemoveCanal",            2, "xi");
 

	
 
	SQAIMarine.PostRegister(engine);
 
}
src/ai/api/ai_object.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_object.cpp Implementation of AIObject. */
 

	
 
#include "ai_object.hpp"
 
#include "ai_log.hpp"
 
#include "ai_error.hpp"
 
#include "table/strings.h"
 
#include "../../openttd.h"
 
#include "../../command_func.h"
 
#include "../../map_func.h"
 
#include "../../network/network.h"
 
#include "../../company_func.h"
 
#include "../../signs_func.h"
 
#include "../../tunnelbridge.h"
 
#include "../../vehicle_func.h"
 
#include "../../group.h"
 
#include "../ai.hpp"
 
#include "ai_controller.hpp"
 
#include "../ai_storage.hpp"
 
#include "../ai_instance.hpp"
 

	
 
#include <vector>
 

	
 
static AIStorage *GetStorage()
 
{
 
	return AIInstance::GetStorage();
 
}
 

	
 
void AIObject::SetDoCommandDelay(uint ticks)
 
{
 
	assert(ticks > 0);
 
	GetStorage()->delay = ticks;
 
}
 

	
 
uint AIObject::GetDoCommandDelay()
 
{
 
	return GetStorage()->delay;
 
}
 

	
 
void AIObject::SetDoCommandMode(AIModeProc *proc, AIObject *instance)
 
{
 
	GetStorage()->mode = proc;
 
	GetStorage()->mode_instance = instance;
 
}
 

	
 
AIModeProc *AIObject::GetDoCommandMode()
 
{
 
	return GetStorage()->mode;
 
}
 

	
 
AIObject *AIObject::GetDoCommandModeInstance()
 
{
 
	return GetStorage()->mode_instance;
 
}
 

	
 
void AIObject::SetDoCommandCosts(Money value)
 
{
 
	GetStorage()->costs = CommandCost(value);
 
}
 

	
 
void AIObject::IncreaseDoCommandCosts(Money value)
 
{
 
	GetStorage()->costs.AddCost(value);
 
}
 

	
 
Money AIObject::GetDoCommandCosts()
 
{
 
	return GetStorage()->costs.GetCost();
 
}
 

	
 
void AIObject::SetLastError(AIErrorType last_error)
 
{
 
	GetStorage()->last_error = last_error;
 
}
 

	
 
AIErrorType AIObject::GetLastError()
 
{
 
	return GetStorage()->last_error;
 
}
 

	
 
void AIObject::SetLastCost(Money last_cost)
 
{
 
	GetStorage()->last_cost = last_cost;
 
}
 

	
 
Money AIObject::GetLastCost()
 
{
 
	return GetStorage()->last_cost;
 
}
 

	
 
void AIObject::SetRoadType(RoadType road_type)
 
{
 
	GetStorage()->road_type = road_type;
 
}
 

	
 
RoadType AIObject::GetRoadType()
 
{
 
	return GetStorage()->road_type;
 
}
 

	
 
void AIObject::SetRailType(RailType rail_type)
 
{
 
	GetStorage()->rail_type = rail_type;
 
}
 

	
 
RailType AIObject::GetRailType()
 
{
 
	return GetStorage()->rail_type;
 
}
 

	
 
void AIObject::SetLastCommandRes(bool res)
 
{
 
	GetStorage()->last_command_res = res;
 
	/* Also store the results of various global variables */
 
	SetNewVehicleID(_new_vehicle_id);
 
	SetNewSignID(_new_sign_id);
 
	SetNewTunnelEndtile(_build_tunnel_endtile);
 
	SetNewGroupID(_new_group_id);
 
}
 

	
 
bool AIObject::GetLastCommandRes()
 
{
 
	return GetStorage()->last_command_res;
 
}
 

	
 
void AIObject::SetNewVehicleID(VehicleID vehicle_id)
 
{
 
	GetStorage()->new_vehicle_id = vehicle_id;
 
}
 

	
 
VehicleID AIObject::GetNewVehicleID()
 
{
 
	return GetStorage()->new_vehicle_id;
 
}
 

	
 
void AIObject::SetNewSignID(SignID sign_id)
 
{
 
	GetStorage()->new_sign_id = sign_id;
 
}
 

	
 
SignID AIObject::GetNewSignID()
 
{
 
	return GetStorage()->new_sign_id;
 
}
 

	
 
void AIObject::SetNewTunnelEndtile(TileIndex tile)
 
{
 
	GetStorage()->new_tunnel_endtile = tile;
 
}
 

	
 
TileIndex AIObject::GetNewTunnelEndtile()
 
{
 
	return GetStorage()->new_tunnel_endtile;
 
}
 

	
 
void AIObject::SetNewGroupID(GroupID group_id)
 
{
 
	GetStorage()->new_group_id = group_id;
 
}
 

	
 
GroupID AIObject::GetNewGroupID()
 
{
 
	return GetStorage()->new_group_id;
 
}
 

	
 
void AIObject::SetAllowDoCommand(bool allow)
 
{
 
	GetStorage()->allow_do_command = allow;
 
}
 

	
 
bool AIObject::GetAllowDoCommand()
 
{
 
	return GetStorage()->allow_do_command;
 
}
 

	
 
void *&AIObject::GetEventPointer()
 
{
 
	return GetStorage()->event_data;
 
}
 

	
 
void *&AIObject::GetLogPointer()
 
{
 
	return GetStorage()->log_data;
 
}
 

	
 
void AIObject::SetCallbackVariable(int index, int value)
 
{
 
	if ((size_t)index >= GetStorage()->callback_value.size()) GetStorage()->callback_value.resize(index + 1);
 
	GetStorage()->callback_value[index] = value;
 
}
 

	
 
int AIObject::GetCallbackVariable(int index)
 
{
 
	return GetStorage()->callback_value[index];
 
}
 

	
 
bool AIObject::DoCommand(TileIndex tile, uint32 p1, uint32 p2, uint cmd, const char *text, AISuspendCallbackProc *callback)
 
{
 
	if (AIObject::GetAllowDoCommand() == false) {
 
		AILog::Error("You are not allowed to execute any DoCommand (even indirect) in your constructor, Save(), and Load().\n");
 
		return false;
 
	}
 

	
 
	CompanyID old_company;
 
	CommandCost res;
 

	
 
	/* Set the default callback to return a true/false result of the DoCommand */
 
	if (callback == NULL) callback = &AIInstance::DoCommandReturn;
 

	
 
	/* Make sure the last error is reset, so we don't give faulty warnings */
 
	SetLastError(AIError::ERR_NONE);
 

	
 
	/* First, do a test-run to see if we can do this */
 
	res = ::DoCommand(tile, p1, p2, CommandFlagsToDCFlags(GetCommandFlags(cmd)), cmd, text);
 
	/* The command failed, so return */
 
	if (::CmdFailed(res)) {
 
		SetLastError(AIError::StringToError(_error_message));
 
		return false;
 
	}
 

	
 
	/* Check what the callback wants us to do */
 
	if (GetDoCommandMode() != NULL && !GetDoCommandMode()(tile, p1, p2, cmd, res)) {
 
		IncreaseDoCommandCosts(res.GetCost());
 
		return true;
 
	}
 

	
 
#ifdef ENABLE_NETWORK
 
	/* Send the command */
 
	if (_networking) {
 
		/* NetworkSend_Command needs _local_company to be set correctly, so
 
		 * adjust it, and put it back right after the function */
 
		old_company = _local_company;
 
		_local_company = _current_company;
 
		::NetworkSend_Command(tile, p1, p2, cmd, CcAI, text);
 
		_local_company = old_company;
 
		SetLastCost(res.GetCost());
 

	
 
		/* Suspend the AI till the command is really executed */
 
		throw AI_VMSuspend(-(int)GetDoCommandDelay(), callback);
 
	} else {
 
#else
 
	{
 
#endif
 
		/* For SinglePlayer we execute the command immediatly */
 
		if (!::DoCommandP(tile, p1, p2, cmd, NULL, text)) res = CMD_ERROR;
 
		SetLastCommandRes(!::CmdFailed(res));
 

	
 
		if (::CmdFailed(res)) {
 
			SetLastError(AIError::StringToError(_error_message));
 
			return false;
 
		}
 
		SetLastCost(res.GetCost());
 
		IncreaseDoCommandCosts(res.GetCost());
 

	
 
		/* Suspend the AI player for 1+ ticks, so it simulates multiplayer. This
 
		 *  both avoids confusion when a developer launched his AI in a
 
		 *  multiplayer game, but also gives time for the GUI and human player
 
		 *  to interact with the game. */
 
		throw AI_VMSuspend(GetDoCommandDelay(), callback);
 
	}
 

	
 
	NOT_REACHED();
 
}
src/ai/api/ai_object.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_object.hpp Main object, on which all objects depend. */
 

	
 
#ifndef AI_OBJECT_HPP
 
#define AI_OBJECT_HPP
 

	
 
#include "../../stdafx.h"
 
#include "../../misc/countedptr.hpp"
 
#include "../../road_type.h"
 
#include "../../rail_type.h"
 

	
 
#include "ai_types.hpp"
 

	
 
/**
 
 * The callback function when an AI suspends.
 
 */
 
typedef void (AISuspendCallbackProc)(class AIInstance *instance);
 

	
 
/**
 
 * The callback function for Mode-classes.
 
 */
 
typedef bool (AIModeProc)(TileIndex tile, uint32 p1, uint32 p2, uint cmd, CommandCost costs);
 

	
 
/**
 
 * Uper-parent object of all API classes. You should never use this class in
 
 *   your AI, as it doesn't publish any public functions. It is used
 
 *   internally to have a common place to handle general things, like internal
 
 *   command processing, and command-validation checks.
 
 */
 
class AIObject : public SimpleCountedObject {
 
friend void CcAI(bool success, TileIndex tile, uint32 p1, uint32 p2);
 
friend class AIInstance;
 
friend class AIController;
 
protected:
 
	/**
 
	 * Executes a raw DoCommand for the AI.
 
	 */
 
	static bool DoCommand(TileIndex tile, uint32 p1, uint32 p2, uint cmd, const char *text = NULL, AISuspendCallbackProc *callback = NULL);
 

	
 
	/**
 
	 * Sets the DoCommand costs counter to a value.
 
	 */
 
	static void SetDoCommandCosts(Money value);
 

	
 
	/**
 
	 * Increase the current value of the DoCommand costs counter.
 
	 */
 
	static void IncreaseDoCommandCosts(Money value);
 

	
 
	/**
 
	 * Get the current DoCommand costs counter.
 
	 */
 
	static Money GetDoCommandCosts();
 

	
 
	/**
 
	 * Set the DoCommand last error.
 
	 */
 
	static void SetLastError(AIErrorType last_error);
 

	
 
	/**
 
	 * Get the DoCommand last error.
 
	 */
 
	static AIErrorType GetLastError();
 

	
 
	/**
 
	 * Set the road type.
 
	 */
 
	static void SetRoadType(RoadType road_type);
 

	
 
	/**
 
	 * Get the road type.
 
	 */
 
	static RoadType GetRoadType();
 

	
 
	/**
 
	 * Set the rail type.
 
	 */
 
	static void SetRailType(RailType rail_type);
 

	
 
	/**
 
	 * Get the rail type.
 
	 */
 
	static RailType GetRailType();
 

	
 
	/**
 
	 * Set the current mode of your AI to this proc.
 
	 */
 
	static void SetDoCommandMode(AIModeProc *proc, AIObject *instance);
 

	
 
	/**
 
	 * Get the current mode your AI is currently under.
 
	 */
 
	static AIModeProc *GetDoCommandMode();
 

	
 
	/**
 
	 * Get the instance of the current mode your AI is currently under.
 
	 */
 
	static AIObject *GetDoCommandModeInstance();
 

	
 
	/**
 
	 * Set the delay of the DoCommand.
 
	 */
 
	static void SetDoCommandDelay(uint ticks);
 

	
 
	/**
 
	 * Get the delay of the DoCommand.
 
	 */
 
	static uint GetDoCommandDelay();
 

	
 
	/**
 
	 * Get the latest result of a DoCommand.
 
	 */
 
	static bool GetLastCommandRes();
 

	
 
	/**
 
	 * Get the latest stored new_vehicle_id.
 
	 */
 
	static VehicleID GetNewVehicleID();
 

	
 
	/**
 
	 * Get the latest stored new_sign_id.
 
	 */
 
	static SignID GetNewSignID();
 

	
 
	/**
 
	 * Get the latest stored new_tunnel_endtile.
 
	 */
 
	static TileIndex GetNewTunnelEndtile();
 

	
 
	/**
 
	 * Get the latest stored new_group_id.
 
	 */
 
	static GroupID GetNewGroupID();
 

	
 
	/**
 
	 * Get the latest stored allow_do_command.
 
	 *  If this is false, you are not allowed to do any DoCommands.
 
	 */
 
	static bool GetAllowDoCommand();
 

	
 
	/**
 
	 * Get the pointer to store event data in.
 
	 */
 
	static void *&GetEventPointer();
 

	
 
	static void SetLastCost(Money last_cost);
 
	static Money GetLastCost();
 
	static void SetCallbackVariable(int index, int value);
 
	static int GetCallbackVariable(int index);
 

	
 
public:
 
	/**
 
	 * Store the latest result of a DoCommand per company.
 
	 * @note NEVER use this yourself in your AI!
 
	 * @param res The result of the last command.
 
	 */
 
	static void SetLastCommandRes(bool res);
 

	
 
	/**
 
	 * Store a new_vehicle_id per company.
 
	 * @note NEVER use this yourself in your AI!
 
	 * @param vehicle_id The new VehicleID.
 
	 */
 
	static void SetNewVehicleID(VehicleID vehicle_id);
 

	
 
	/**
 
	 * Store a new_sign_id per company.
 
	 * @note NEVER use this yourself in your AI!
 
	 * @param sign_id The new SignID.
 
	 */
 
	static void SetNewSignID(SignID sign_id);
 

	
 
	/**
 
	 * Store a new_tunnel_endtile per company.
 
	 * @note NEVER use this yourself in your AI!
 
	 * @param tile The new TileIndex.
 
	 */
 
	static void SetNewTunnelEndtile(TileIndex tile);
 

	
 
	/**
 
	 * Store a new_group_id per company.
 
	 * @note NEVER use this yourself in your AI!
 
	 * @param group_id The new GroupID.
 
	 */
 
	static void SetNewGroupID(GroupID group_id);
 

	
 
	/**
 
	 * Store a allow_do_command per company.
 
	 * @note NEVER use this yourself in your AI!
 
	 * @param allow The new allow.
 
	 */
 
	static void SetAllowDoCommand(bool allow);
 

	
 
	/**
 
	 * Get the pointer to store log message in.
 
	 * @note NEVER use this yourself in your AI!
 
	 */
 
	static void *&GetLogPointer();
 
};
 

	
 
#endif /* AI_OBJECT_HPP */
src/ai/api/ai_order.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_order.cpp Implementation of AIOrder. */
 

	
 
#include "ai_order.hpp"
 
#include "ai_map.hpp"
 
#include "ai_vehicle.hpp"
 
#include "../ai_instance.hpp"
 
#include "../../openttd.h"
 
#include "../../debug.h"
 
#include "../../vehicle_base.h"
 
#include "../../depot_base.h"
 
#include "../../landscape.h"
 
#include "../../rail_map.h"
 
#include "../../road_map.h"
 
#include "../../station_map.h"
 
#include "../../water_map.h"
 
#include "../../waypoint.h"
 

	
 
/**
 
 * Gets the order type given a tile
 
 * @param t the tile to get the order from
 
 * @return the order type, or OT_END when there is no order
 
 */
 
static OrderType GetOrderTypeByTile(TileIndex t)
 
{
 
	if (!::IsValidTile(t)) return OT_END;
 

	
 
	switch (::GetTileType(t)) {
 
		default: break;
 
		case MP_STATION: return OT_GOTO_STATION; break;
 
		case MP_WATER:   if (::IsShipDepot(t)) return OT_GOTO_DEPOT; break;
 
		case MP_ROAD:    if (::GetRoadTileType(t) == ROAD_TILE_DEPOT) return OT_GOTO_DEPOT; break;
 
		case MP_RAILWAY:
 
			switch (::GetRailTileType(t)) {
 
				case RAIL_TILE_DEPOT:    return OT_GOTO_DEPOT;
 
				case RAIL_TILE_WAYPOINT: return OT_GOTO_WAYPOINT;
 
				default: break;
 
			}
 
			break;
 
	}
 

	
 
	return OT_END;
 
}
 

	
 
/* static */ bool AIOrder::IsValidVehicleOrder(VehicleID vehicle_id, OrderPosition order_position)
 
{
 
	return AIVehicle::IsValidVehicle(vehicle_id) && order_position >= 0 && (order_position < ::GetVehicle(vehicle_id)->GetNumOrders() || order_position == CURRENT_ORDER);
 
}
 

	
 
/* static */ AIOrder::OrderPosition AIOrder::ResolveOrderPosition(VehicleID vehicle_id, OrderPosition order_position)
 
{
 
	if (!AIVehicle::IsValidVehicle(vehicle_id)) return INVALID_ORDER;
 

	
 
	if (order_position == CURRENT_ORDER) return (AIOrder::OrderPosition)::GetVehicle(vehicle_id)->cur_order_index;
 
	return (order_position >= 0 && order_position < ::GetVehicle(vehicle_id)->GetNumOrders()) ? order_position : INVALID_ORDER;
 
}
 

	
 

	
 
/* static */ bool AIOrder::AreOrderFlagsValid(TileIndex destination, AIOrderFlags order_flags)
 
{
 
	switch (::GetOrderTypeByTile(destination)) {
 
		case OT_GOTO_STATION:
 
			return ((order_flags & ~(AIOF_NON_STOP_FLAGS | AIOF_UNLOAD_FLAGS | AIOF_LOAD_FLAGS)) == 0) &&
 
					/* Test the different mutual exclusive flags. */
 
					(((order_flags & AIOF_TRANSFER)      == 0) || ((order_flags & AIOF_UNLOAD)    == 0)) &&
 
					(((order_flags & AIOF_TRANSFER)      == 0) || ((order_flags & AIOF_NO_UNLOAD) == 0)) &&
 
					(((order_flags & AIOF_UNLOAD)        == 0) || ((order_flags & AIOF_NO_UNLOAD) == 0)) &&
 
					(((order_flags & AIOF_UNLOAD)        == 0) || ((order_flags & AIOF_NO_UNLOAD) == 0)) &&
 
					(((order_flags & AIOF_NO_UNLOAD)     == 0) || ((order_flags & AIOF_NO_LOAD)   == 0)) &&
 
					(((order_flags & AIOF_FULL_LOAD_ANY) == 0) || ((order_flags & AIOF_NO_LOAD)   == 0));
 

	
 
		case OT_GOTO_DEPOT:    return (order_flags & ~(AIOF_NON_STOP_FLAGS | AIOF_SERVICE_IF_NEEDED)) == 0;
 
		case OT_GOTO_WAYPOINT: return (order_flags & ~(AIOF_NON_STOP_FLAGS)) == 0;
 
		default:               return false;
 
	}
 
}
 

	
 
/* static */ int32 AIOrder::GetOrderCount(VehicleID vehicle_id)
 
{
 
	return AIVehicle::IsValidVehicle(vehicle_id) ? ::GetVehicle(vehicle_id)->GetNumOrders() : -1;
 
}
 

	
 
/* static */ TileIndex AIOrder::GetOrderDestination(VehicleID vehicle_id, OrderPosition order_position)
 
{
 
	if (!IsValidVehicleOrder(vehicle_id, order_position)) return INVALID_TILE;
 

	
 
	const Order *order;
 
	const Vehicle *v = ::GetVehicle(vehicle_id);
 
	if (order_position == CURRENT_ORDER) {
 
		order = &v->current_order;
 
	} else {
 
		order = v->GetFirstOrder();
 
		for (int i = 0; i < order_position; i++) order = order->next;
 
	}
 

	
 
	switch (order->GetType()) {
 
		case OT_GOTO_DEPOT:
 
			if (v->type != VEH_AIRCRAFT) return ::GetDepot(order->GetDestination())->xy;
 
			/* FALL THROUGH: aircraft's hangars are referenced by StationID, not DepotID */
 

	
 
		case OT_GOTO_STATION:  return ::GetStation(order->GetDestination())->xy;
 
		case OT_GOTO_WAYPOINT: return ::GetWaypoint(order->GetDestination())->xy;
 
		default:               return INVALID_TILE;
 
	}
 
}
 

	
 
/* static */ AIOrder::AIOrderFlags AIOrder::GetOrderFlags(VehicleID vehicle_id, OrderPosition order_position)
 
{
 
	if (!IsValidVehicleOrder(vehicle_id, order_position)) return AIOF_INVALID;
 

	
 
	const Order *order;
 
	if (order_position == CURRENT_ORDER) {
 
		order = &::GetVehicle(vehicle_id)->current_order;
 
	} else {
 
		order = ::GetVehicle(vehicle_id)->GetFirstOrder();
 
		for (int i = 0; i < order_position; i++) order = order->next;
 
	}
 

	
 
	AIOrderFlags order_flags = AIOF_NONE;
 
	order_flags |= (AIOrderFlags)order->GetNonStopType();
 
	switch (order->GetType()) {
 
		case OT_GOTO_DEPOT:
 
			if (order->GetDepotOrderType() & ODTFB_SERVICE) order_flags |= AIOF_SERVICE_IF_NEEDED;
 
			break;
 

	
 
		case OT_GOTO_STATION:
 
			order_flags |= (AIOrderFlags)(order->GetLoadType()   << 5);
 
			order_flags |= (AIOrderFlags)(order->GetUnloadType() << 2);
 
			break;
 

	
 
		default: break;
 
	}
 

	
 
	return order_flags;
 
}
 

	
 
/* static */ bool AIOrder::AppendOrder(VehicleID vehicle_id, TileIndex destination, AIOrderFlags order_flags)
 
{
 
	EnforcePrecondition(false, AIVehicle::IsValidVehicle(vehicle_id));
 
	return InsertOrder(vehicle_id, (AIOrder::OrderPosition)::GetVehicle(vehicle_id)->GetNumOrders(), destination, order_flags);
 
}
 

	
 
/* static */ bool AIOrder::InsertOrder(VehicleID vehicle_id, OrderPosition order_position, TileIndex destination, AIOrder::AIOrderFlags order_flags)
 
{
 
	/* IsValidVehicleOrder is not good enough because it does not allow appending. */
 
	if (order_position == CURRENT_ORDER) order_position = AIOrder::ResolveOrderPosition(vehicle_id, order_position);
 

	
 
	EnforcePrecondition(false, AIVehicle::IsValidVehicle(vehicle_id));
 
	EnforcePrecondition(false, order_position >= 0 && order_position <= ::GetVehicle(vehicle_id)->GetNumOrders());
 
	EnforcePrecondition(false, AreOrderFlagsValid(destination, order_flags));
 

	
 
	Order order;
 
	switch (::GetOrderTypeByTile(destination)) {
 
		case OT_GOTO_DEPOT:
 
			order.MakeGoToDepot(::GetDepotByTile(destination)->index, (OrderDepotTypeFlags)(ODTFB_PART_OF_ORDERS | ((order_flags & AIOF_SERVICE_IF_NEEDED) ? ODTFB_SERVICE : 0)));
 
			break;
 

	
 
		case OT_GOTO_STATION:
 
			order.MakeGoToStation(::GetStationIndex(destination));
 
			order.SetLoadType((OrderLoadFlags)GB(order_flags, 5, 3));
 
			order.SetUnloadType((OrderUnloadFlags)GB(order_flags, 2, 3));
 
			break;
 

	
 
		case OT_GOTO_WAYPOINT:
 
			order.MakeGoToWaypoint(::GetWaypointIndex(destination));
 
			break;
 

	
 
		default:
 
			return false;
 
	}
 

	
 
	order.SetNonStopType((OrderNonStopFlags)GB(order_flags, 0, 2));
 

	
 
	return AIObject::DoCommand(0, vehicle_id | (order_position << 16), order.Pack(), CMD_INSERT_ORDER);
 
}
 

	
 
/* static */ bool AIOrder::RemoveOrder(VehicleID vehicle_id, OrderPosition order_position)
 
{
 
	order_position = AIOrder::ResolveOrderPosition(vehicle_id, order_position);
 

	
 
	EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, order_position));
 

	
 
	return AIObject::DoCommand(0, vehicle_id, order_position, CMD_DELETE_ORDER);
 
}
 

	
 
/**
 
 * Callback handler as ChangeOrder possibly needs multiple DoCommand calls
 
 * to be able to set all order flags correctly. As we need to wait till the
 
 * command has completed before we know the next bits to change we need to
 
 * call the function multiple times. Each time it'll reduce the difference
 
 * between the wanted and the current order.
 
 * @param instance The AI we are doing the callback for.
 
 */
 
static void _DoCommandReturnChangeOrder(class AIInstance *instance)
 
{
 
	AIObject::SetLastCommandRes(AIOrder::_ChangeOrder());
 
	AIInstance::DoCommandReturn(instance);
 
}
 

	
 
/* static */ bool AIOrder::_ChangeOrder()
 
{
 
	/* Make sure we don't go into an infinite loop */
 
	int retry = AIObject::GetCallbackVariable(3) - 1;
 
	if (retry < 0) {
 
		DEBUG(ai, 0, "Possible infinite loop in ChangeOrder detected");
 
		return false;
 
	}
 
	AIObject::SetCallbackVariable(3, retry);
 

	
 
	VehicleID vehicle_id = (VehicleID)AIObject::GetCallbackVariable(0);
 
	OrderPosition order_position = (OrderPosition)AIObject::GetCallbackVariable(1);
 
	AIOrderFlags order_flags = (AIOrderFlags)AIObject::GetCallbackVariable(2);
 

	
 
	order_position = AIOrder::ResolveOrderPosition(vehicle_id, order_position);
 

	
 
	EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, order_position));
 
	EnforcePrecondition(false, AreOrderFlagsValid(GetOrderDestination(vehicle_id, order_position), order_flags));
 

	
 
	Order *order = ::GetVehicle(vehicle_id)->GetFirstOrder();
 
	for (int i = 0; i < order_position; i++) order = order->next;
 

	
 
	AIOrderFlags current = GetOrderFlags(vehicle_id, order_position);
 

	
 
	if ((current & AIOF_NON_STOP_FLAGS) != (order_flags & AIOF_NON_STOP_FLAGS)) {
 
		return AIObject::DoCommand(0, vehicle_id | (order_position << 16), (order_flags & AIOF_NON_STOP_FLAGS) << 4 | MOF_NON_STOP, CMD_MODIFY_ORDER, NULL, &_DoCommandReturnChangeOrder);
 
	}
 

	
 
	switch (order->GetType()) {
 
		case OT_GOTO_DEPOT:
 
			if ((current & AIOF_SERVICE_IF_NEEDED) != (order_flags & AIOF_SERVICE_IF_NEEDED)) {
 
				return AIObject::DoCommand(0, vehicle_id | (order_position << 16), MOF_DEPOT_ACTION, CMD_MODIFY_ORDER, NULL, &_DoCommandReturnChangeOrder);
 
			}
 
			break;
 

	
 
		case OT_GOTO_STATION:
 
			if ((current & AIOF_UNLOAD_FLAGS) != (order_flags & AIOF_UNLOAD_FLAGS)) {
 
				return AIObject::DoCommand(0, vehicle_id | (order_position << 16), (order_flags & AIOF_UNLOAD_FLAGS) << 2 | MOF_UNLOAD, CMD_MODIFY_ORDER, NULL, &_DoCommandReturnChangeOrder);
 
			}
 
			if ((current & AIOF_LOAD_FLAGS) != (order_flags & AIOF_LOAD_FLAGS)) {
 
				return AIObject::DoCommand(0, vehicle_id | (order_position << 16), (order_flags & AIOF_LOAD_FLAGS) >> 1 | MOF_LOAD, CMD_MODIFY_ORDER, NULL, &_DoCommandReturnChangeOrder);
 
			}
 
			break;
 

	
 
		default: break;
 
	}
 

	
 
	assert(GetOrderFlags(vehicle_id, order_position) == order_flags);
 

	
 
	return true;
 
}
 

	
 
/* static */ bool AIOrder::ChangeOrder(VehicleID vehicle_id, OrderPosition order_position, AIOrder::AIOrderFlags order_flags)
 
{
 
	AIObject::SetCallbackVariable(0, vehicle_id);
 
	AIObject::SetCallbackVariable(1, order_position);
 
	AIObject::SetCallbackVariable(2, order_flags);
 
	/* In case another client(s) change orders at the same time we could
 
	 * end in an infinite loop. This stops that from happening ever. */
 
	AIObject::SetCallbackVariable(3, 8);
 
	return AIOrder::_ChangeOrder();
 
}
 

	
 
/* static */ bool AIOrder::MoveOrder(VehicleID vehicle_id, OrderPosition order_position_move, OrderPosition order_position_target)
 
{
 
	order_position_move   = AIOrder::ResolveOrderPosition(vehicle_id, order_position_move);
 
	order_position_target = AIOrder::ResolveOrderPosition(vehicle_id, order_position_target);
 

	
 
	EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, order_position_move));
 
	EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, order_position_target));
 

	
 
	return AIObject::DoCommand(0, vehicle_id, order_position_move | (order_position_target << 16), CMD_MOVE_ORDER);
 
}
 

	
 
/* static */ bool AIOrder::CopyOrders(VehicleID vehicle_id, VehicleID main_vehicle_id)
 
{
 
	EnforcePrecondition(false, AIVehicle::IsValidVehicle(vehicle_id));
 
	EnforcePrecondition(false, AIVehicle::IsValidVehicle(main_vehicle_id));
 

	
 
	return AIObject::DoCommand(0, vehicle_id | (main_vehicle_id << 16), CO_COPY, CMD_CLONE_ORDER);
 
}
 

	
 
/* static */ bool AIOrder::ShareOrders(VehicleID vehicle_id, VehicleID main_vehicle_id)
 
{
 
	EnforcePrecondition(false, AIVehicle::IsValidVehicle(vehicle_id));
 
	EnforcePrecondition(false, AIVehicle::IsValidVehicle(main_vehicle_id));
 

	
 
	return AIObject::DoCommand(0, vehicle_id | (main_vehicle_id << 16), CO_SHARE, CMD_CLONE_ORDER);
 
}
 

	
 
/* static */ bool AIOrder::UnshareOrders(VehicleID vehicle_id)
 
{
 
	EnforcePrecondition(false, AIVehicle::IsValidVehicle(vehicle_id));
 

	
 
	return AIObject::DoCommand(0, vehicle_id, CO_UNSHARE, CMD_CLONE_ORDER);
 
}
src/ai/api/ai_order.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_order.hpp Everything to query and build orders. */
 

	
 
#ifndef AI_ORDER_HPP
 
#define AI_ORDER_HPP
 

	
 
#include "ai_object.hpp"
 
#include "ai_error.hpp"
 

	
 
/**
 
 * Class that handles all order related functions.
 
 */
 
class AIOrder : public AIObject {
 
public:
 
	static const char *GetClassName() { return "AIOrder"; }
 

	
 
	/**
 
	 * All order related error messages.
 
	 */
 
	enum ErrorMessages {
 
		/** Base for all order related errors */
 
		ERR_ORDER_BASE = AIError::ERR_CAT_ORDER << AIError::ERR_CAT_BIT_SIZE,
 

	
 
		/** No more space for orders */
 
		ERR_ORDER_TOO_MANY,                                  // [STR_8831_NO_MORE_SPACE_FOR_ORDERS]
 

	
 
		/** Destination of new order is to far away from the previous order */
 
		ERR_ORDER_TOO_FAR_AWAY_FROM_PREVIOUS_DESTINATION,    // [STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO]
 
	};
 

	
 
	/**
 
	 * Flags that can be used to modify the behaviour of orders.
 
	 */
 
	enum AIOrderFlags {
 
		/** Just go to the station/depot, stop unload if possible and load if needed. */
 
		AIOF_NONE              = 0,
 

	
 
		/** Do not stop at the stations that are passed when going to the destination. Only for trains and road vehicles. */
 
		AIOF_NON_STOP_INTERMEDIATE = 1 << 0,
 
		/** Do not stop at the destionation station. Only for trains and road vehicles. */
 
		AIOF_NON_STOP_DESTINATION  = 1 << 1,
 

	
 
		/** Always unload the vehicle; only for stations. Cannot be set when AIOF_TRANSFER or AIOF_NO_UNLOAD is set. */
 
		AIOF_UNLOAD            = 1 << 2,
 
		/** Transfer instead of deliver the goods; only for stations. Cannot be set when AIOF_UNLOAD or AIOF_NO_UNLOAD is set. */
 
		AIOF_TRANSFER          = 1 << 3,
 
		/** Never unload the vehicle; only for stations. Cannot be set when AIOF_UNLOAD, AIOF_TRANSFER or AIOF_NO_LOAD is set. */
 
		AIOF_NO_UNLOAD         = 1 << 4,
 

	
 
		/** Wait till the vehicle is fully loaded; only for stations. Cannot be set when AIOF_NO_LOAD is set. */
 
		AIOF_FULL_LOAD         = 2 << 5,
 
		/** Wait till at least one cargo of the vehicle is fully loaded; only for stations. Cannot be set when AIOF_NO_LOAD is set. */
 
		AIOF_FULL_LOAD_ANY     = 3 << 5,
 
		/** Do not load any cargo; only for stations. Cannot be set when AIOF_NO_UNLOAD, AIOF_FULL_LOAD or AIOF_FULL_LOAD_ANY is set. */
 
		AIOF_NO_LOAD           = 1 << 7,
 

	
 
		/** Service the vehicle when needed, otherwise skip this order; only for depots. */
 
		AIOF_SERVICE_IF_NEEDED = 1 << 2,
 

	
 
		/** All flags related to non-stop settings. */
 
		AIOF_NON_STOP_FLAGS    = AIOF_NON_STOP_INTERMEDIATE | AIOF_NON_STOP_DESTINATION,
 
		/** All flags related to unloading. */
 
		AIOF_UNLOAD_FLAGS      = AIOF_TRANSFER | AIOF_UNLOAD | AIOF_NO_UNLOAD,
 
		/** All flags related to loading. */
 
		AIOF_LOAD_FLAGS        = AIOF_FULL_LOAD | AIOF_FULL_LOAD_ANY | AIOF_NO_LOAD,
 

	
 
		/** For marking invalid order flags */
 
		AIOF_INVALID           = 0xFFFF,
 
	};
 

	
 
	/** Different constants related to the OrderPosition */
 
	enum OrderPosition {
 
		CURRENT_ORDER = 0xFF, //!< Constant that gets resolved to the current order.
 
		INVALID_ORDER = -1,   //!< An invalid order.
 
	};
 

	
 
	/**
 
	 * Checks whether the given order id is valid for the given vehicle.
 
	 * @param vehicle_id The vehicle to check the order index for.
 
	 * @param order_position The order index to check.
 
	 * @pre AIVehicle::IsValidVehicle(vehicle_id).
 
	 * @return True if and only if the order_position is valid for the given vehicle.
 
	 */
 
	static bool IsValidVehicleOrder(VehicleID vehicle_id, OrderPosition order_position);
 

	
 
	/**
 
	 * Resolves the given order index to the correct index for the given vehicle.
 
	 *  If the order index was CURRENT_ORDER it will be resolved to the index of
 
	 *  the current order (as shown in the order list). If the order with the
 
	 *  given index does not exist it will return INVALID_ORDER.
 
	 * @param vehicle_id The vehicle to check the order index for.
 
	 * @param order_position The order index to resolve.
 
	 * @pre AIVehicle::IsValidVehicle(vehicle_id).
 
	 * @return The resolved order index.
 
	 */
 
	static OrderPosition ResolveOrderPosition(VehicleID vehicle_id, OrderPosition order_position);
 

	
 
	/**
 
	 * Checks whether the given order flags are valid for the given destination.
 
	 * @param destination The destination of the order.
 
	 * @param order_flags The flags given to the order.
 
	 * @return True if and only if the order_flags are valid for the given location.
 
	 */
 
	static bool AreOrderFlagsValid(TileIndex destination, AIOrderFlags order_flags);
 

	
 
	/**
 
	 * Returns the number of orders for the given vehicle.
 
	 * @param vehicle_id The vehicle to get the order count of.
 
	 * @pre AIVehicle::IsValidVehicle(vehicle_id).
 
	 * @return The number of orders for the given vehicle or a negative
 
	 *   value when the vehicle does not exist.
 
	 */
 
	static int32 GetOrderCount(VehicleID vehicle_id);
 

	
 
	/**
 
	 * Gets the destination of the given order for the given vehicle.
 
	 * @param vehicle_id The vehicle to get the destination for.
 
	 * @param order_position The order to get the destination for.
 
	 * @pre IsValidVehicleOrder(vehicle_id, order_position).
 
	 * @note Giving CURRENT_ORDER as order_position will give the order that is
 
	 *  currently being executed by the vehicle. This is not necessarily the
 
	 *  current order as given by ResolveOrderPosition (the current index in the
 
	 *  order list) as manual or autoservicing depot orders do not show up
 
	 *  in the orderlist, but they can be the current order of a vehicle.
 
	 * @return The destination tile of the order.
 
	 */
 
	static TileIndex GetOrderDestination(VehicleID vehicle_id, OrderPosition order_position);
 

	
 
	/**
 
	 * Gets the AIOrderFlags of the given order for the given vehicle.
 
	 * @param vehicle_id The vehicle to get the destination for.
 
	 * @param order_position The order to get the destination for.
 
	 * @pre IsValidVehicleOrder(vehicle_id, order_position).
 
	 * @note Giving CURRENT_ORDER as order_position will give the order that is
 
	 *  currently being executed by the vehicle. This is not necessarily the
 
	 *  current order as given by ResolveOrderPosition (the current index in the
 
	 *  order list) as manual or autoservicing depot orders do not show up
 
	 *  in the orderlist, but they can be the current order of a vehicle.
 
	 * @return The AIOrderFlags of the order.
 
	 */
 
	static AIOrderFlags GetOrderFlags(VehicleID vehicle_id, OrderPosition order_position);
 

	
 
	/**
 
	 * Appends an order to the end of the vehicle's order list.
 
	 * @param vehicle_id The vehicle to append the order to.
 
	 * @param destination The destination of the order.
 
	 * @param order_flags The flags given to the order.
 
	 * @pre AIVehicle::IsValidVehicle(vehicle_id).
 
	 * @pre AreOrderFlagsValid(destination, order_flags).
 
	 * @exception AIError::ERR_OWNED_BY_ANOTHER_COMPANY
 
	 * @exception AIOrder::ERR_ORDER_NO_MORE_SPACE
 
	 * @exception AIOrder::ERR_ORDER_TOO_FAR_AWAY_FROM_PREVIOUS_DESTINATION
 
	 * @return True if and only if the order was appended.
 
	 */
 
	static bool AppendOrder(VehicleID vehicle_id, TileIndex destination, AIOrderFlags order_flags);
 

	
 
	/**
 
	 * Inserts an order before the given order_position into the vehicle's order list.
 
	 * @param vehicle_id The vehicle to add the order to.
 
	 * @param order_position The order to place the new order before.
 
	 * @param destination The destination of the order.
 
	 * @param order_flags The flags given to the order.
 
	 * @pre IsValidVehicleOrder(vehicle_id, order_position).
 
	 * @pre AreOrderFlagsValid(destination, order_flags).
 
	 * @exception AIError::ERR_OWNED_BY_ANOTHER_COMPANY
 
	 * @exception AIOrder::ERR_ORDER_NO_MORE_SPACE
 
	 * @exception AIOrder::ERR_ORDER_TOO_FAR_AWAY_FROM_PREVIOUS_DESTINATION
 
	 * @return True if and only if the order was inserted.
 
	 */
 
	static bool InsertOrder(VehicleID vehicle_id, OrderPosition order_position, TileIndex destination, AIOrderFlags order_flags);
 

	
 
	/**
 
	 * Removes an order from the vehicle's order list.
 
	 * @param vehicle_id The vehicle to remove the order from.
 
	 * @param order_position The order to remove from the order list.
 
	 * @pre AIVehicle::IsValidVehicleOrder(vehicle_id, order_position).
 
	 * @exception AIError::ERR_OWNED_BY_ANOTHER_COMPANY
 
	 * @return True if and only if the order was removed.
 
	 */
 
	static bool RemoveOrder(VehicleID vehicle_id, OrderPosition order_position);
 

	
 
#ifndef DOXYGEN_SKIP
 
	/**
 
	 * Internal function to help ChangeOrder.
 
	 */
 
	static bool _ChangeOrder();
 
#endif
 

	
 
	/**
 
	 * Changes the order flags of the given order.
 
	 * @param vehicle_id The vehicle to change the order of.
 
	 * @param order_position The order to change.
 
	 * @param order_flags The new flags given to the order.
 
	 * @pre IsValidVehicleOrder(vehicle_id, order_position).
 
	 * @pre AreOrderFlagsValid(GetOrderDestination(vehicle_id, order_position), order_flags).
 
	 * @exception AIError::ERR_OWNED_BY_ANOTHER_COMPANY
 
	 * @return True if and only if the order was changed.
 
	 */
 
	static bool ChangeOrder(VehicleID vehicle_id, OrderPosition order_position, AIOrderFlags order_flags);
 

	
 
	/**
 
	 * Move an order inside the orderlist
 
	 * @param vehicle_id The vehicle to move the orders.
 
	 * @param order_position_move The order to move.
 
	 * @param order_position_target The target order
 
	 * @pre IsValidVehicleOrder(vehicle_id, order_position_move).
 
	 * @pre IsValidVehicleOrder(vehicle_id, order_position_target).
 
	 * @exception AIError::ERR_OWNED_BY_ANOTHER_COMPANY
 
	 * @return True if and only if the order was moved.
 
	 * @note If the order is moved to a lower place (e.g. from 7 to 2)
 
	 *  the target order is moved upwards (e.g. 3). If the order is moved
 
	 *  to a higher place (e.g. from 7 to 9) the target will be moved
 
	 *  downwards (e.g. 8).
 
	 */
 
	static bool MoveOrder(VehicleID vehicle_id, OrderPosition order_position_move, OrderPosition order_position_target);
 

	
 
	/**
 
	 * Copies the orders from another vehicle. The orders of the main vehicle
 
	 *  are going to be the orders of the changed vehicle.
 
	 * @param vehicle_id The vehicle to copy the orders to.
 
	 * @param main_vehicle_id The vehicle to copy the orders from.
 
	 * @pre AIVehicle::IsValidVehicle(vehicle_id).
 
	 * @pre AIVehicle::IsValidVehicle(main_vehicle_id).
 
	 * @exception AIError::ERR_OWNED_BY_ANOTHER_COMPANY
 
	 * @exception AIOrder::ERR_ORDER_NO_MORE_SPACE
 
	 * @return True if and only if the copying succeeded.
 
	 */
 
	static bool CopyOrders(VehicleID vehicle_id, VehicleID main_vehicle_id);
 

	
 
	/**
 
	 * Shares the orders between two vehicles. The orders of the main
 
	 * vehicle are going to be the orders of the changed vehicle.
 
	 * @param vehicle_id The vehicle to add to the shared order list.
 
	 * @param main_vehicle_id The vehicle to share the orders with.
 
	 * @pre AIVehicle::IsValidVehicle(vehicle_id).
 
	 * @pre AIVehicle::IsValidVehicle(main_vehicle_id).
 
	 * @exception AIError::ERR_OWNED_BY_ANOTHER_COMPANY
 
	 * @return True if and only if the sharing succeeded.
 
	 */
 
	static bool ShareOrders(VehicleID vehicle_id, VehicleID main_vehicle_id);
 

	
 
	/**
 
	 * Removes the given vehicle from a shared orders list.
 
	 * @param vehicle_id The vehicle to remove from the shared order list.
 
	 * @pre AIVehicle::IsValidVehicle(vehicle_id).
 
	 * @return True if and only if the unsharing succeeded.
 
	 */
 
	static bool UnshareOrders(VehicleID vehicle_id);
 
};
 
DECLARE_ENUM_AS_BIT_SET(AIOrder::AIOrderFlags);
 

	
 
#endif /* AI_ORDER_HPP */
src/ai/api/ai_order.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_order.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow enums to be used as Squirrel parameters */
 
	template <> AIOrder::ErrorMessages GetParam(ForceType<AIOrder::ErrorMessages>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AIOrder::ErrorMessages)tmp; }
 
	template <> int Return<AIOrder::ErrorMessages>(HSQUIRRELVM vm, AIOrder::ErrorMessages res) { sq_pushinteger(vm, (int32)res); return 1; }
 
	template <> AIOrder::AIOrderFlags GetParam(ForceType<AIOrder::AIOrderFlags>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AIOrder::AIOrderFlags)tmp; }
 
	template <> int Return<AIOrder::AIOrderFlags>(HSQUIRRELVM vm, AIOrder::AIOrderFlags res) { sq_pushinteger(vm, (int32)res); return 1; }
 
	template <> AIOrder::OrderPosition GetParam(ForceType<AIOrder::OrderPosition>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AIOrder::OrderPosition)tmp; }
 
	template <> int Return<AIOrder::OrderPosition>(HSQUIRRELVM vm, AIOrder::OrderPosition res) { sq_pushinteger(vm, (int32)res); return 1; }
 

	
 
	/* Allow AIOrder to be used as Squirrel parameter */
 
	template <> AIOrder *GetParam(ForceType<AIOrder *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIOrder *)instance; }
 
	template <> AIOrder &GetParam(ForceType<AIOrder &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIOrder *)instance; }
 
	template <> const AIOrder *GetParam(ForceType<const AIOrder *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIOrder *)instance; }
 
	template <> const AIOrder &GetParam(ForceType<const AIOrder &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIOrder *)instance; }
 
	template <> int Return<AIOrder *>(HSQUIRRELVM vm, AIOrder *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIOrder", res, NULL, DefSQDestructorCallback<AIOrder>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIOrder_Register(Squirrel *engine) {
 
	DefSQClass <AIOrder> SQAIOrder("AIOrder");
 
	SQAIOrder.PreRegister(engine);
 
	SQAIOrder.AddConstructor<void (AIOrder::*)(), 1>(engine, "x");
 

	
 
	SQAIOrder.DefSQConst(engine, AIOrder::ERR_ORDER_BASE,                                   "ERR_ORDER_BASE");
 
	SQAIOrder.DefSQConst(engine, AIOrder::ERR_ORDER_TOO_MANY,                               "ERR_ORDER_TOO_MANY");
 
	SQAIOrder.DefSQConst(engine, AIOrder::ERR_ORDER_TOO_FAR_AWAY_FROM_PREVIOUS_DESTINATION, "ERR_ORDER_TOO_FAR_AWAY_FROM_PREVIOUS_DESTINATION");
 
	SQAIOrder.DefSQConst(engine, AIOrder::AIOF_NONE,                                        "AIOF_NONE");
 
	SQAIOrder.DefSQConst(engine, AIOrder::AIOF_NON_STOP_INTERMEDIATE,                       "AIOF_NON_STOP_INTERMEDIATE");
 
	SQAIOrder.DefSQConst(engine, AIOrder::AIOF_NON_STOP_DESTINATION,                        "AIOF_NON_STOP_DESTINATION");
 
	SQAIOrder.DefSQConst(engine, AIOrder::AIOF_UNLOAD,                                      "AIOF_UNLOAD");
 
	SQAIOrder.DefSQConst(engine, AIOrder::AIOF_TRANSFER,                                    "AIOF_TRANSFER");
 
	SQAIOrder.DefSQConst(engine, AIOrder::AIOF_NO_UNLOAD,                                   "AIOF_NO_UNLOAD");
 
	SQAIOrder.DefSQConst(engine, AIOrder::AIOF_FULL_LOAD,                                   "AIOF_FULL_LOAD");
 
	SQAIOrder.DefSQConst(engine, AIOrder::AIOF_FULL_LOAD_ANY,                               "AIOF_FULL_LOAD_ANY");
 
	SQAIOrder.DefSQConst(engine, AIOrder::AIOF_NO_LOAD,                                     "AIOF_NO_LOAD");
 
	SQAIOrder.DefSQConst(engine, AIOrder::AIOF_SERVICE_IF_NEEDED,                           "AIOF_SERVICE_IF_NEEDED");
 
	SQAIOrder.DefSQConst(engine, AIOrder::AIOF_NON_STOP_FLAGS,                              "AIOF_NON_STOP_FLAGS");
 
	SQAIOrder.DefSQConst(engine, AIOrder::AIOF_UNLOAD_FLAGS,                                "AIOF_UNLOAD_FLAGS");
 
	SQAIOrder.DefSQConst(engine, AIOrder::AIOF_LOAD_FLAGS,                                  "AIOF_LOAD_FLAGS");
 
	SQAIOrder.DefSQConst(engine, AIOrder::AIOF_INVALID,                                     "AIOF_INVALID");
 
	SQAIOrder.DefSQConst(engine, AIOrder::CURRENT_ORDER,                                    "CURRENT_ORDER");
 
	SQAIOrder.DefSQConst(engine, AIOrder::INVALID_ORDER,                                    "INVALID_ORDER");
 

	
 
	AIError::RegisterErrorMap(STR_8831_NO_MORE_SPACE_FOR_ORDERS,         AIOrder::ERR_ORDER_TOO_MANY);
 
	AIError::RegisterErrorMap(STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO, AIOrder::ERR_ORDER_TOO_FAR_AWAY_FROM_PREVIOUS_DESTINATION);
 

	
 
	AIError::RegisterErrorMapString(AIOrder::ERR_ORDER_TOO_MANY,                               "ERR_ORDER_TOO_MANY");
 
	AIError::RegisterErrorMapString(AIOrder::ERR_ORDER_TOO_FAR_AWAY_FROM_PREVIOUS_DESTINATION, "ERR_ORDER_TOO_FAR_AWAY_FROM_PREVIOUS_DESTINATION");
 

	
 
	SQAIOrder.DefSQStaticMethod(engine, &AIOrder::GetClassName,         "GetClassName",         1, "x");
 
	SQAIOrder.DefSQStaticMethod(engine, &AIOrder::IsValidVehicleOrder,  "IsValidVehicleOrder",  3, "xii");
 
	SQAIOrder.DefSQStaticMethod(engine, &AIOrder::ResolveOrderPosition, "ResolveOrderPosition", 3, "xii");
 
	SQAIOrder.DefSQStaticMethod(engine, &AIOrder::AreOrderFlagsValid,   "AreOrderFlagsValid",   3, "xii");
 
	SQAIOrder.DefSQStaticMethod(engine, &AIOrder::GetOrderCount,        "GetOrderCount",        2, "xi");
 
	SQAIOrder.DefSQStaticMethod(engine, &AIOrder::GetOrderDestination,  "GetOrderDestination",  3, "xii");
 
	SQAIOrder.DefSQStaticMethod(engine, &AIOrder::GetOrderFlags,        "GetOrderFlags",        3, "xii");
 
	SQAIOrder.DefSQStaticMethod(engine, &AIOrder::AppendOrder,          "AppendOrder",          4, "xiii");
 
	SQAIOrder.DefSQStaticMethod(engine, &AIOrder::InsertOrder,          "InsertOrder",          5, "xiiii");
 
	SQAIOrder.DefSQStaticMethod(engine, &AIOrder::RemoveOrder,          "RemoveOrder",          3, "xii");
 
	SQAIOrder.DefSQStaticMethod(engine, &AIOrder::ChangeOrder,          "ChangeOrder",          4, "xiii");
 
	SQAIOrder.DefSQStaticMethod(engine, &AIOrder::MoveOrder,            "MoveOrder",            4, "xiii");
 
	SQAIOrder.DefSQStaticMethod(engine, &AIOrder::CopyOrders,           "CopyOrders",           3, "xii");
 
	SQAIOrder.DefSQStaticMethod(engine, &AIOrder::ShareOrders,          "ShareOrders",          3, "xii");
 
	SQAIOrder.DefSQStaticMethod(engine, &AIOrder::UnshareOrders,        "UnshareOrders",        2, "xi");
 

	
 
	SQAIOrder.PostRegister(engine);
 
}
src/ai/api/ai_rail.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_rail.cpp Implementation of AIRail. */
 

	
 
#include "ai_rail.hpp"
 
#include "ai_object.hpp"
 
#include "ai_map.hpp"
 
#include "../../openttd.h"
 
#include "../../debug.h"
 
#include "../../rail_map.h"
 
#include "../../road_map.h"
 
#include "../../command_type.h"
 
#include "../../station_map.h"
 
#include "../../company_func.h"
 
#include "../../core/math_func.hpp"
 
#include "../../waypoint.h"
 
#include "../../newgrf.h"
 
#include "../../newgrf_generic.h"
 
#include "../../newgrf_station.h"
 
#include "../../newgrf_callbacks.h"
 

	
 
/* static */ bool AIRail::IsRailTile(TileIndex tile)
 
{
 
	if (!::IsValidTile(tile)) return false;
 

	
 
	return (::IsTileType(tile, MP_RAILWAY) && !::IsRailDepot(tile)) ||
 
			(::IsRailwayStationTile(tile) && !::IsStationTileBlocked(tile)) || ::IsLevelCrossingTile(tile);
 
}
 

	
 
/* static */ bool AIRail::IsLevelCrossingTile(TileIndex tile)
 
{
 
	if (!::IsValidTile(tile)) return false;
 

	
 
	return ::IsLevelCrossingTile(tile);
 
}
 

	
 
/* static */ bool AIRail::IsRailDepotTile(TileIndex tile)
 
{
 
	if (!::IsValidTile(tile)) return false;
 

	
 
	return ::IsRailDepotTile(tile);
 
}
 

	
 
/* static */ bool AIRail::IsRailStationTile(TileIndex tile)
 
{
 
	if (!::IsValidTile(tile)) return false;
 

	
 
	return ::IsRailwayStationTile(tile);
 
}
 

	
 
/* static */ bool AIRail::IsRailWaypointTile(TileIndex tile)
 
{
 
	if (!::IsValidTile(tile)) return false;
 

	
 
	return ::IsTileType(tile, MP_RAILWAY) && ::IsRailWaypointTile(tile);
 
}
 

	
 
/* static */ bool AIRail::IsRailTypeAvailable(RailType rail_type)
 
{
 
	if ((::RailType)rail_type < RAILTYPE_BEGIN || (::RailType)rail_type >= RAILTYPE_END) return false;
 

	
 
	return ::HasRailtypeAvail(_current_company, (::RailType)rail_type);
 
}
 

	
 
/* static */ AIRail::RailType AIRail::GetCurrentRailType()
 
{
 
	return (RailType)AIObject::GetRailType();
 
}
 

	
 
/* static */ void AIRail::SetCurrentRailType(RailType rail_type)
 
{
 
	if (!IsRailTypeAvailable(rail_type)) return;
 

	
 
	AIObject::SetRailType((::RailType)rail_type);
 
}
 

	
 
/* static */ bool AIRail::TrainCanRunOnRail(AIRail::RailType engine_rail_type, AIRail::RailType track_rail_type)
 
{
 
	if (!AIRail::IsRailTypeAvailable(engine_rail_type)) return false;
 
	if (!AIRail::IsRailTypeAvailable(track_rail_type)) return false;
 

	
 
	return ::IsCompatibleRail((::RailType)engine_rail_type, (::RailType)track_rail_type);
 
}
 

	
 
/* static */ bool AIRail::TrainHasPowerOnRail(AIRail::RailType engine_rail_type, AIRail::RailType track_rail_type)
 
{\
 
	if (!AIRail::IsRailTypeAvailable(engine_rail_type)) return false;
 
	if (!AIRail::IsRailTypeAvailable(track_rail_type)) return false;
 

	
 
	return ::HasPowerOnRail((::RailType)engine_rail_type, (::RailType)track_rail_type);
 
}
 

	
 
/* static */ AIRail::RailType AIRail::GetRailType(TileIndex tile)
 
{
 
	if (!AITile::HasTransportType(tile, AITile::TRANSPORT_RAIL)) return RAILTYPE_INVALID;
 

	
 
	return (RailType)::GetRailType(tile);
 
}
 

	
 
/* static */ bool AIRail::ConvertRailType(TileIndex start_tile, TileIndex end_tile, AIRail::RailType convert_to)
 
{
 
	EnforcePrecondition(false, ::IsValidTile(start_tile));
 
	EnforcePrecondition(false, ::IsValidTile(end_tile));
 
	EnforcePrecondition(false, IsRailTypeAvailable(convert_to));
 

	
 
	return AIObject::DoCommand(start_tile, end_tile, convert_to, CMD_CONVERT_RAIL);
 
}
 

	
 
/* static */ TileIndex AIRail::GetRailDepotFrontTile(TileIndex depot)
 
{
 
	if (!IsRailDepotTile(depot)) return INVALID_TILE;
 

	
 
	return depot + ::TileOffsByDiagDir(::GetRailDepotDirection(depot));
 
}
 

	
 
/* static */ AIRail::RailTrack AIRail::GetRailStationDirection(TileIndex tile)
 
{
 
	if (!IsRailStationTile(tile)) return RAILTRACK_INVALID;
 

	
 
	return (RailTrack)::GetRailStationTrack(tile);
 
}
 

	
 
/* static */ bool AIRail::BuildRailDepot(TileIndex tile, TileIndex front)
 
{
 
	EnforcePrecondition(false, tile != front);
 
	EnforcePrecondition(false, ::IsValidTile(tile));
 
	EnforcePrecondition(false, ::IsValidTile(front));
 
	EnforcePrecondition(false, ::TileX(tile) == ::TileX(front) || ::TileY(tile) == ::TileY(front));
 
	EnforcePrecondition(false, IsRailTypeAvailable(GetCurrentRailType()));
 

	
 
	uint entrance_dir = (::TileX(tile) == ::TileX(front)) ? (::TileY(tile) < ::TileY(front) ? 1 : 3) : (::TileX(tile) < ::TileX(front) ? 2 : 0);
 

	
 
	return AIObject::DoCommand(tile, AIObject::GetRailType(), entrance_dir, CMD_BUILD_TRAIN_DEPOT);
 
}
 

	
 
/* static */ bool AIRail::BuildRailStation(TileIndex tile, RailTrack direction, uint num_platforms, uint platform_length, bool join_adjacent)
 
{
 
	EnforcePrecondition(false, ::IsValidTile(tile));
 
	EnforcePrecondition(false, direction == RAILTRACK_NW_SE || direction == RAILTRACK_NE_SW);
 
	EnforcePrecondition(false, num_platforms > 0 && num_platforms <= 0xFF);
 
	EnforcePrecondition(false, platform_length > 0 && platform_length <= 0xFF);
 
	EnforcePrecondition(false, IsRailTypeAvailable(GetCurrentRailType()));
 

	
 
	uint32 p1 = GetCurrentRailType() | (platform_length << 16) | (num_platforms << 8);
 
	if (direction == RAILTRACK_NW_SE) p1 |= (1 << 4);
 
	if (!join_adjacent) p1 |= (1 << 24);
 
	return AIObject::DoCommand(tile, p1, INVALID_STATION << 16, CMD_BUILD_RAILROAD_STATION);
 
}
 

	
 
/* static */ bool AIRail::BuildNewGRFRailStation(TileIndex tile, RailTrack direction, uint num_platforms, uint platform_length, bool join_adjacent, CargoID cargo_id, IndustryType source_industry, IndustryType goal_industry, int distance, bool source_station)
 
{
 
	EnforcePrecondition(false, ::IsValidTile(tile));
 
	EnforcePrecondition(false, direction == RAILTRACK_NW_SE || direction == RAILTRACK_NE_SW);
 
	EnforcePrecondition(false, num_platforms > 0 && num_platforms <= 0xFF);
 
	EnforcePrecondition(false, platform_length > 0 && platform_length <= 0xFF);
 
	EnforcePrecondition(false, IsRailTypeAvailable(GetCurrentRailType()));
 

	
 
	uint32 p1 = GetCurrentRailType() | (platform_length << 16) | (num_platforms << 8);
 
	if (direction == RAILTRACK_NW_SE) p1 |= 1 << 4;
 
	if (!join_adjacent) p1 |= (1 << 24);
 

	
 
	const GRFFile *file;
 
	uint16 res = GetAiPurchaseCallbackResult(GSF_STATION, cargo_id, 0, source_industry, goal_industry, min(255, distance / 2), AICE_STATION_GET_STATION_ID, source_station ? 0 : 1, min(15, num_platforms) << 4 | min(15, platform_length), &file);
 
	uint32 p2 = INVALID_STATION << 16;
 
	if (res != CALLBACK_FAILED) {
 
		extern StationClass _station_classes[STAT_CLASS_MAX];
 
		const StationSpec *spec = GetCustomStationSpecByGrf(file->grfid, res);
 
		int index = -1;
 
		for (uint j = 0; j < _station_classes[spec->sclass].stations; j++) {
 
			if (spec == _station_classes[spec->sclass].spec[j]) {
 
				index = j;
 
				break;
 
			}
 
		}
 
		if (index == -1) {
 
			DEBUG(grf, 1, "%s returned an invalid station ID for 'AI construction/purchase selection (18)' callback", file->filename);
 
		} else {
 
			p2 |= spec->sclass | index << 8;
 
		}
 

	
 
	}
 
	return AIObject::DoCommand(tile, p1, p2, CMD_BUILD_RAILROAD_STATION);
 
}
 

	
 
/* static */ bool AIRail::RemoveRailStationTileRect(TileIndex tile, TileIndex tile2)
 
{
 
	EnforcePrecondition(false, ::IsValidTile(tile));
 
	EnforcePrecondition(false, ::IsValidTile(tile2));
 

	
 
	return AIObject::DoCommand(tile, tile2, 0, CMD_REMOVE_FROM_RAILROAD_STATION);
 
}
 

	
 
/* static */ uint AIRail::GetRailTracks(TileIndex tile)
 
{
 
	if (!IsRailTile(tile)) return RAILTRACK_INVALID;
 

	
 
	if (IsRailWaypointTile(tile)) return ::GetRailWaypointBits(tile);
 
	if (IsRailStationTile(tile)) return ::TrackToTrackBits(::GetRailStationTrack(tile));
 
	if (IsLevelCrossingTile(tile)) return ::GetCrossingRailBits(tile);
 
	return ::GetTrackBits(tile);
 
}
 

	
 
/* static */ bool AIRail::BuildRailTrack(TileIndex tile, RailTrack rail_track)
 
{
 
	EnforcePrecondition(false, ::IsValidTile(tile));
 
	EnforcePrecondition(false, rail_track != 0);
 
	EnforcePrecondition(false, (rail_track & ~::TRACK_BIT_ALL) == 0);
 
	EnforcePrecondition(false, KillFirstBit((uint)rail_track) == 0);
 
	EnforcePrecondition(false, IsRailTypeAvailable(GetCurrentRailType()));
 

	
 
	return AIObject::DoCommand(tile, tile, GetCurrentRailType() | (FindFirstTrack((::TrackBits)rail_track) << 4), CMD_BUILD_RAILROAD_TRACK);
 
}
 

	
 
/* static */ bool AIRail::RemoveRailTrack(TileIndex tile, RailTrack rail_track)
 
{
 
	EnforcePrecondition(false, ::IsValidTile(tile));
 
	EnforcePrecondition(false, ::IsTileType(tile, MP_RAILWAY) && ::IsPlainRailTile(tile));
 
	EnforcePrecondition(false, GetRailTracks(tile) & rail_track);
 
	EnforcePrecondition(false, KillFirstBit((uint)rail_track) == 0);
 

	
 
	return AIObject::DoCommand(tile, tile, GetCurrentRailType() | (FindFirstTrack((::TrackBits)rail_track) << 4), CMD_REMOVE_RAILROAD_TRACK);
 
}
 

	
 
/* static */ bool AIRail::AreTilesConnected(TileIndex from, TileIndex tile, TileIndex to)
 
{
 
	if (!IsRailTile(tile)) return false;
 
	if (from == to || AIMap::DistanceManhattan(from, tile) != 1 || AIMap::DistanceManhattan(tile, to) != 1) return false;
 

	
 
	if (to < from) ::Swap(from, to);
 

	
 
	if (tile - from == 1) {
 
		if (to - tile == 1) return (GetRailTracks(tile) & RAILTRACK_NE_SW) != 0;
 
		if (to - tile == ::MapSizeX()) return (GetRailTracks(tile) & RAILTRACK_NE_SE) != 0;
 
	} else if (tile - from == ::MapSizeX()) {
 
		if (tile - to == 1) return (GetRailTracks(tile) & RAILTRACK_NW_NE) != 0;
 
		if (to - tile == 1) return (GetRailTracks(tile) & RAILTRACK_NW_SW) != 0;
 
		if (to - tile == ::MapSizeX()) return (GetRailTracks(tile) & RAILTRACK_NW_SE) != 0;
 
	} else {
 
		return (GetRailTracks(tile) & RAILTRACK_SW_SE) != 0;
 
	}
 

	
 
	NOT_REACHED();
 
}
 

	
 
/**
 
 * Prepare the second parameter for CmdBuildRailroadTrack and CmdRemoveRailroadTrack. The direction
 
 * depends on all three tiles. Sometimes the third tile needs to be adjusted.
 
 */
 
static uint32 SimulateDrag(TileIndex from, TileIndex tile, TileIndex *to)
 
{
 
	int diag_offset = abs(abs((int)::TileX(*to) - (int)::TileX(tile)) - abs((int)::TileY(*to) - (int)::TileY(tile)));
 
	uint32 p2 = AIRail::GetCurrentRailType();
 
	if (::TileY(from) == ::TileY(*to)) {
 
		p2 |= (TRACK_X << 4);
 
		*to -= Clamp((int)::TileX(*to) - (int)::TileX(tile), -1, 1);
 
	} else if (::TileX(from) == ::TileX(*to)) {
 
		p2 |= (TRACK_Y << 4);
 
		*to -= ::MapSizeX() * Clamp((int)::TileY(*to) - (int)::TileY(tile), -1, 1);
 
	} else if (::TileY(from) < ::TileY(tile)) {
 
		if (::TileX(*to) < ::TileX(tile)) {
 
			p2 |= (TRACK_UPPER << 4);
 
		} else {
 
			p2 |= (TRACK_LEFT << 4);
 
		}
 
		if (diag_offset) {
 
			*to -= Clamp((int)::TileX(*to) - (int)::TileX(tile), -1, 1);
 
		} else {
 
			*to -= ::MapSizeX() * Clamp((int)::TileY(*to) - (int)::TileY(tile), -1, 1);
 
		}
 
	} else if (::TileY(from) > ::TileY(tile)) {
 
		if (::TileX(*to) < ::TileX(tile)) {
 
			p2 |= (TRACK_RIGHT << 4);
 
		} else {
 
			p2 |= (TRACK_LOWER << 4);
 
		}
 
		if (diag_offset) {
 
			*to -= Clamp((int)::TileX(*to) - (int)::TileX(tile), -1, 1);
 
		} else {
 
			*to -= ::MapSizeX() * Clamp((int)::TileY(*to) - (int)::TileY(tile), -1, 1);
 
		}
 
	} else if (::TileX(from) < ::TileX(tile)) {
 
		if (::TileY(*to) < ::TileY(tile)) {
 
			p2 |= (TRACK_UPPER << 4);
 
		} else {
 
			p2 |= (TRACK_RIGHT << 4);
 
		}
 
		if (!diag_offset) {
 
			*to -= Clamp((int)::TileX(*to) - (int)::TileX(tile), -1, 1);
 
		} else {
 
			*to -= ::MapSizeX() * Clamp((int)::TileY(*to) - (int)::TileY(tile), -1, 1);
 
		}
 
	} else if (::TileX(from) > ::TileX(tile)) {
 
		if (::TileY(*to) < ::TileY(tile)) {
 
			p2 |= (TRACK_LEFT << 4);
 
		} else {
 
			p2 |= (TRACK_LOWER << 4);
 
		}
 
		if (!diag_offset) {
 
			*to -= Clamp((int)::TileX(*to) - (int)::TileX(tile), -1, 1);
 
		} else {
 
			*to -= ::MapSizeX() * Clamp((int)::TileY(*to) - (int)::TileY(tile), -1, 1);
 
		}
 
	}
 
	return p2;
 
}
 

	
 
/* static */ bool AIRail::BuildRail(TileIndex from, TileIndex tile, TileIndex to)
 
{
 
	EnforcePrecondition(false, ::IsValidTile(from));
 
	EnforcePrecondition(false, ::IsValidTile(tile));
 
	EnforcePrecondition(false, ::IsValidTile(to));
 
	EnforcePrecondition(false, ::DistanceManhattan(from, tile) == 1);
 
	EnforcePrecondition(false, ::DistanceManhattan(tile,to) >= 1);
 
	EnforcePrecondition(false, IsRailTypeAvailable(GetCurrentRailType()));
 
	int diag_offset = abs(abs((int)::TileX(to) - (int)::TileX(tile)) - abs((int)::TileY(to) - (int)::TileY(tile)));
 
	EnforcePrecondition(false, diag_offset <= 1 ||
 
			(::TileX(from) == ::TileX(tile) && ::TileX(tile) == ::TileX(to)) ||
 
			(::TileY(from) == ::TileY(tile) && ::TileY(tile) == ::TileY(to)));
 

	
 
	uint32 p2 = SimulateDrag(from, tile, &to);
 
	return AIObject::DoCommand(tile, to, p2, CMD_BUILD_RAILROAD_TRACK);
 
}
 

	
 
/* static */ bool AIRail::RemoveRail(TileIndex from, TileIndex tile, TileIndex to)
 
{
 
	EnforcePrecondition(false, ::IsValidTile(from));
 
	EnforcePrecondition(false, ::IsValidTile(tile));
 
	EnforcePrecondition(false, ::IsValidTile(to));
 
	EnforcePrecondition(false, ::DistanceManhattan(from, tile) == 1);
 
	EnforcePrecondition(false, ::DistanceManhattan(tile,to) >= 1);
 
	int diag_offset = abs(abs((int)::TileX(to) - (int)::TileX(tile)) - abs((int)::TileY(to) - (int)::TileY(tile)));
 
	EnforcePrecondition(false, diag_offset <= 1 ||
 
			(::TileX(from) == ::TileX(tile) && ::TileX(tile) == ::TileX(to)) ||
 
			(::TileY(from) == ::TileY(tile) && ::TileY(tile) == ::TileY(to)));
 

	
 
	if (!IsRailTypeAvailable(GetCurrentRailType())) SetCurrentRailType(GetRailType(tile));
 
	uint32 p2 = SimulateDrag(from, tile, &to);
 
	return AIObject::DoCommand(tile, to, p2, CMD_REMOVE_RAILROAD_TRACK);
 
}
 

	
 
/**
 
 * Contains information about the trackdir that belongs to a track when entering
 
 *   from a specific direction.
 
 */
 
struct AIRailSignalData {
 
	Track track;        //!< The track that will be taken to travel.
 
	Trackdir trackdir;  //!< The Trackdir belonging to that track.
 
	uint signal_cycles; //!< How many times the signal should be cycled in order to build it in the correct direction.
 
};
 

	
 
static const int NUM_TRACK_DIRECTIONS = 3; //!< The number of directions you can go when entering a tile.
 

	
 
/**
 
 * List information about the trackdir and number of needed cycles for building signals when
 
 *   entering a track from a specific direction. The first index is the difference between the
 
 *   TileIndex of the previous and current tile, where (-)MapSizeX is replaced with -2 / 2 and
 
 *   2 it added.
 
 */
 
static const AIRailSignalData _possible_trackdirs[5][NUM_TRACK_DIRECTIONS] = {
 
	{{TRACK_UPPER,   TRACKDIR_UPPER_E, 0}, {TRACK_Y,       TRACKDIR_Y_SE,    0}, {TRACK_LEFT,    TRACKDIR_LEFT_S,  1}},
 
	{{TRACK_RIGHT,   TRACKDIR_RIGHT_S, 1}, {TRACK_X,       TRACKDIR_X_SW,    1}, {TRACK_UPPER,   TRACKDIR_UPPER_W, 1}},
 
	{{INVALID_TRACK, INVALID_TRACKDIR, 0}, {INVALID_TRACK, INVALID_TRACKDIR, 0}, {INVALID_TRACK, INVALID_TRACKDIR, 0}},
 
	{{TRACK_LOWER,   TRACKDIR_LOWER_E, 0}, {TRACK_X,       TRACKDIR_X_NE,    0}, {TRACK_LEFT,    TRACKDIR_LEFT_N,  0}},
 
	{{TRACK_RIGHT,   TRACKDIR_RIGHT_N, 0}, {TRACK_Y,       TRACKDIR_Y_NW,    1}, {TRACK_LOWER,   TRACKDIR_LOWER_W, 1}}
 
};
 

	
 
/* static */ AIRail::SignalType AIRail::GetSignalType(TileIndex tile, TileIndex front)
 
{
 
	if (AIMap::DistanceManhattan(tile, front) != 1) return SIGNALTYPE_NONE;
 
	if (!::IsTileType(tile, MP_RAILWAY) || !::HasSignals(tile)) return SIGNALTYPE_NONE;
 

	
 
	int data_index = 2 + (::TileX(front) - ::TileX(tile)) + 2 * (::TileY(front) - ::TileY(tile));
 

	
 
	for (int i = 0; i < NUM_TRACK_DIRECTIONS; i++) {
 
		const Track &track = _possible_trackdirs[data_index][i].track;
 
		if (!(::TrackToTrackBits(track) & GetRailTracks(tile))) continue;
 
		if (!HasSignalOnTrack(tile, track)) continue;
 
		if (!HasSignalOnTrackdir(tile, _possible_trackdirs[data_index][i].trackdir)) continue;
 
		SignalType st = (SignalType)::GetSignalType(tile, track);
 
		if (HasSignalOnTrackdir(tile, ::ReverseTrackdir(_possible_trackdirs[data_index][i].trackdir))) st = (SignalType)(st | SIGNALTYPE_TWOWAY);
 
		return st;
 
	}
 

	
 
	return SIGNALTYPE_NONE;
 
}
 

	
 
/**
 
 * Check if signal_type is a valid SignalType.
 
 */
 
static bool IsValidSignalType(int signal_type)
 
{
 
	if (signal_type < AIRail::SIGNALTYPE_NORMAL || signal_type > AIRail::SIGNALTYPE_COMBO_TWOWAY) return false;
 
	if (signal_type > AIRail::SIGNALTYPE_PBS_ONEWAY && signal_type < AIRail::SIGNALTYPE_NORMAL_TWOWAY) return false;
 
	return true;
 
}
 

	
 
/* static */ bool AIRail::BuildSignal(TileIndex tile, TileIndex front, SignalType signal)
 
{
 
	EnforcePrecondition(false, AIMap::DistanceManhattan(tile, front) == 1)
 
	EnforcePrecondition(false, ::IsTileType(tile, MP_RAILWAY) && ::IsPlainRailTile(tile));
 
	EnforcePrecondition(false, ::IsValidSignalType(signal));
 

	
 
	Track track = INVALID_TRACK;
 
	uint signal_cycles;
 

	
 
	int data_index = 2 + (::TileX(front) - ::TileX(tile)) + 2 * (::TileY(front) - ::TileY(tile));
 
	for (int i = 0; i < NUM_TRACK_DIRECTIONS; i++) {
 
		const Track &t = _possible_trackdirs[data_index][i].track;
 
		if (!(::TrackToTrackBits(t) & GetRailTracks(tile))) continue;
 
		track = t;
 
		signal_cycles = _possible_trackdirs[data_index][i].signal_cycles;
 
		break;
 
	}
 
	EnforcePrecondition(false, track != INVALID_TRACK);
 

	
 
	uint p1 = track;
 
	if (signal < SIGNALTYPE_TWOWAY) {
 
		if (signal != SIGNALTYPE_PBS && signal != SIGNALTYPE_PBS_ONEWAY) signal_cycles++;
 
		p1 |= (signal_cycles << 15);
 
	}
 
	p1 |= ((signal >= SIGNALTYPE_TWOWAY ? signal ^ SIGNALTYPE_TWOWAY : signal) << 5);
 

	
 
	return AIObject::DoCommand(tile, p1, 0, CMD_BUILD_SIGNALS);
 
}
 

	
 
/* static */ bool AIRail::RemoveSignal(TileIndex tile, TileIndex front)
 
{
 
	EnforcePrecondition(false, AIMap::DistanceManhattan(tile, front) == 1)
 
	EnforcePrecondition(false, GetSignalType(tile, front) != SIGNALTYPE_NONE);
 

	
 
	Track track = INVALID_TRACK;
 
	int data_index = 2 + (::TileX(front) - ::TileX(tile)) + 2 * (::TileY(front) - ::TileY(tile));
 
	for (int i = 0; i < NUM_TRACK_DIRECTIONS; i++) {
 
		const Track &t = _possible_trackdirs[data_index][i].track;
 
		if (!(::TrackToTrackBits(t) & GetRailTracks(tile))) continue;
 
		track = t;
 
		break;
 
	}
 
	EnforcePrecondition(false, track != INVALID_TRACK);
 

	
 
	return AIObject::DoCommand(tile, track, 0, CMD_REMOVE_SIGNALS);
 
}
src/ai/api/ai_rail.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_rail.hpp Everything to query and build rails. */
 

	
 
#ifndef AI_RAIL_HPP
 
#define AI_RAIL_HPP
 

	
 
#include "ai_object.hpp"
 
#include "ai_error.hpp"
 
#include "ai_tile.hpp"
 

	
 
/**
 
 * Class that handles all rail related functions.
 
 */
 
class AIRail : public AIObject {
 
public:
 
	static const char *GetClassName() { return "AIRail"; }
 

	
 
	/**
 
	 * All rail related error messages.
 
	 */
 
	enum ErrorMessages {
 
		/** Base for rail building / maintaining errors */
 
		ERR_RAIL_BASE = AIError::ERR_CAT_RAIL << AIError::ERR_CAT_BIT_SIZE,
 

	
 
		/** One-way roads cannot have crossings */
 
		ERR_CROSSING_ON_ONEWAY_ROAD,       // [STR_ERR_CROSSING_ON_ONEWAY_ROAD]
 

	
 
		/** Track not suitable for signals */
 
		ERR_UNSUITABLE_TRACK,              // [STR_1005_NO_SUITABLE_RAILROAD_TRACK]
 

	
 
		/** Non-uniform stations is diabled */
 
		ERR_NONUNIFORM_STATIONS_DISABLED,  // [STR_NONUNIFORM_STATIONS_DISALLOWED]
 
	};
 

	
 
	/**
 
	 * Types of rail known to the game.
 
	 */
 
	enum RailType {
 
		/* Note: the values _are_ important as they represent an in-game value */
 
		RAILTYPE_INVALID  = 0xFF, //!< Invalid RailType.
 
	};
 

	
 
	/**
 
	 * A bitmap with all possible rail tracks on a tile.
 
	 */
 
	enum RailTrack {
 
		/* Note: the values _are_ important as they represent an in-game value */
 
		RAILTRACK_NE_SW   = 1 << 0, //!< Track along the x-axis (north-east to south-west).
 
		RAILTRACK_NW_SE   = 1 << 1, //!< Track along the y-axis (north-west to south-east).
 
		RAILTRACK_NW_NE   = 1 << 2, //!< Track in the upper corner of the tile (north).
 
		RAILTRACK_SW_SE   = 1 << 3, //!< Track in the lower corner of the tile (south).
 
		RAILTRACK_NW_SW   = 1 << 4, //!< Track in the left corner of the tile (west).
 
		RAILTRACK_NE_SE   = 1 << 5, //!< Track in the right corner of the tile (east).
 
		RAILTRACK_INVALID = 0xFF,   //!< Flag for an invalid track.
 
	};
 

	
 
	/**
 
	 * Types of signal known to the game.
 
	 */
 
	enum SignalType {
 
		/* Note: the values _are_ important as they represent an in-game value */
 
		SIGNALTYPE_NORMAL        = 0, //!< Normal signal.
 
		SIGNALTYPE_ENTRY         = 1, //!< Entry presignal.
 
		SIGNALTYPE_EXIT          = 2, //!< Exit signal.
 
		SIGNALTYPE_COMBO         = 3, //!< Combo signal.
 
		SIGNALTYPE_PBS           = 4, //!< Normal PBS signal.
 
		SIGNALTYPE_PBS_ONEWAY    = 5, //!< No-entry PBS signal.
 
		SIGNALTYPE_TWOWAY        = 8, //!< Bit mask for twoway signal.
 
		SIGNALTYPE_NORMAL_TWOWAY = SIGNALTYPE_NORMAL | SIGNALTYPE_TWOWAY, //!< Normal twoway signal.
 
		SIGNALTYPE_ENTRY_TWOWAY  = SIGNALTYPE_ENTRY | SIGNALTYPE_TWOWAY,  //!< Entry twoway signal.
 
		SIGNALTYPE_EXIT_TWOWAY   = SIGNALTYPE_EXIT | SIGNALTYPE_TWOWAY,   //!< Exit twoway signal.
 
		SIGNALTYPE_COMBO_TWOWAY  = SIGNALTYPE_COMBO | SIGNALTYPE_TWOWAY,  //!< Combo twoway signal.
 
		SIGNALTYPE_NONE          = 0xFF, //!< No signal.
 
	};
 

	
 
	/**
 
	 * Checks whether the given tile is actually a tile with rail that can be
 
	 *  used to traverse a tile. This excludes rail depots but includes
 
	 *  stations and waypoints.
 
	 * @param tile The tile to check.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @return True if and only if the tile has rail.
 
	 */
 
	static bool IsRailTile(TileIndex tile);
 

	
 
	/**
 
	 * Checks whether there is a road / rail crossing on a tile.
 
	 * @param tile The tile to check.
 
	 * @return True if and only if there is a road / rail crossing.
 
	 */
 
	static bool IsLevelCrossingTile(TileIndex tile);
 

	
 
	/**
 
	 * Checks whether the given tile is actually a tile with a rail depot.
 
	 * @param tile The tile to check.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @return True if and only if the tile has a rail depot.
 
	 */
 
	static bool IsRailDepotTile(TileIndex tile);
 

	
 
	/**
 
	 * Checks whether the given tile is actually a tile with a rail station.
 
	 * @param tile The tile to check.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @return True if and only if the tile has a rail station.
 
	 */
 
	static bool IsRailStationTile(TileIndex tile);
 

	
 
	/**
 
	 * Checks whether the given tile is actually a tile with a rail waypoint.
 
	 * @param tile The tile to check.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @return True if and only if the tile has a rail waypoint.
 
	 */
 
	static bool IsRailWaypointTile(TileIndex tile);
 

	
 
	/**
 
	 * Check if a given RailType is available.
 
	 * @param rail_type The RailType to check for.
 
	 * @return True if this RailType can be used.
 
	 */
 
	static bool IsRailTypeAvailable(RailType rail_type);
 

	
 
	/**
 
	 * Get the current RailType set for all AIRail functions.
 
	 * @return The RailType currently set.
 
	 */
 
	static RailType GetCurrentRailType();
 

	
 
	/**
 
	 * Set the RailType for all further AIRail functions.
 
	 * @param rail_type The RailType to set.
 
	 */
 
	static void SetCurrentRailType(RailType rail_type);
 

	
 
	/**
 
	 * Check if a train build for a rail type can run on another rail type.
 
	 * @param engine_rail_type The rail type the train is build for.
 
	 * @param track_rail_type The type you want to check.
 
	 * @pre AIRail::IsRailTypeAvailable(engine_rail_type).
 
	 * @pre AIRail::IsRailTypeAvailable(track_rail_type).
 
	 * @return Whether a train build for 'engine_rail_type' can run on 'track_rail_type'.
 
	 * @note Even if a train can run on a RailType that doesn't mean that it'll be
 
	 *   able to power the train. Use TrainHasPowerOnRail for that.
 
	 */
 
	static bool TrainCanRunOnRail(AIRail::RailType engine_rail_type, AIRail::RailType track_rail_type);
 

	
 
	/**
 
	 * Check if a train build for a rail type has power on another rail type.
 
	 * @param engine_rail_type The rail type the train is build for.
 
	 * @param track_rail_type The type you want to check.
 
	 * @pre AIRail::IsRailTypeAvailable(engine_rail_type).
 
	 * @pre AIRail::IsRailTypeAvailable(track_rail_type).
 
	 * @return Whether a train build for 'engine_rail_type' has power on 'track_rail_type'.
 
	 */
 
	static bool TrainHasPowerOnRail(AIRail::RailType engine_rail_type, AIRail::RailType track_rail_type);
 

	
 
	/**
 
	 * Get the RailType that is used on a tile.
 
	 * @param tile The tile to check.
 
	 * @pre AITile::HasTransportType(tile, AITile.TRANSPORT_RAIL).
 
	 * @return The RailType that is used on a tile.
 
	 */
 
	static RailType GetRailType(TileIndex tile);
 

	
 
	/**
 
	 * Convert the tracks on all tiles within a rectangle to another RailType.
 
	 * @param start_tile One corner of the rectangle.
 
	 * @param end_tile The opposite corner of the rectangle.
 
	 * @param convert_to The RailType you want to convert the rails to.
 
	 * @pre AIMap::IsValidTile(start_tile).
 
	 * @pre AIMap::IsValidTile(end_tile).
 
	 * @pre IsRailTypeAvailable(convert_to).
 
	 * @exception AIRail::ERR_UNSUITABLE_TRACK
 
	 * @return Whether at least some rail has been converted succesfully.
 
	 */
 
	static bool ConvertRailType(TileIndex start_tile, TileIndex end_tile, AIRail::RailType convert_to);
 

	
 
	/**
 
	 * Gets the tile in front of a rail depot.
 
	 * @param depot The rail depot tile.
 
	 * @pre IsRailDepotTile(depot).
 
	 * @return The tile in front of the depot.
 
	 */
 
	static TileIndex GetRailDepotFrontTile(TileIndex depot);
 

	
 
	/**
 
	 * Gets the direction of a rail station tile.
 
	 * @param tile The rail station tile.
 
	 * @pre IsRailStationTile(tile).
 
	 * @return The direction of the station (either RAILTRACK_NE_SW or RAILTRACK_NW_SE).
 
	 */
 
	static RailTrack GetRailStationDirection(TileIndex tile);
 

	
 
	/**
 
	 * Builds a rail depot.
 
	 * @param tile Place to build the depot.
 
	 * @param front The tile exactly in front of the depot.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @pre AIMap::IsValidTile(front).
 
	 * @pre 'tile' is not equal to 'front', but in a straight line of it.
 
	 * @pre IsRailTypeAvailable(GetCurrentRailType()).
 
	 * @exception AIError::ERR_FLAT_LAND_REQUIRED
 
	 * @exception AIError::ERR_AREA_NOT_CLEAR
 
	 * @return Whether the rail depot has been/can be build or not.
 
	 */
 
	static bool BuildRailDepot(TileIndex tile, TileIndex front);
 

	
 
	/**
 
	 * Build a rail station.
 
	 * @param tile Place to build the station.
 
	 * @param direction The direction to build the station.
 
	 * @param num_platforms The number of platforms to build.
 
	 * @param platform_length The length of each platform.
 
	 * @param join_adjacent When building next to an other station, don't create a new station when this flag is true.
 
	 * @pre IsRailTypeAvailable(GetCurrentRailType()).
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @pre direction == RAILTRACK_NW_SE || direction == RAILTRACK_NE_SW.
 
	 * @pre num_platforms > 0 && num_platforms <= 255.
 
	 * @pre platform_length > 0 && platform_length <= 255.
 
	 * @exception AIError::ERR_OWNED_BY_ANOTHER_COMPANY
 
	 * @exception AIError::ERR_AREA_NOT_CLEAR
 
	 * @exception AIError::ERR_FLAT_LAND_REQUIRED
 
	 * @exception AIStation::ERR_STATION_TOO_CLOSE_TO_ANOTHER_STATION
 
	 * @exception AIStation::ERR_STATION_TOO_MANY_STATIONS
 
	 * @exception AIStation::ERR_STATION_TOO_MANY_STATIONS_IN_TOWN
 
	 * @return Whether the station has been/can be build or not.
 
	 */
 
	static bool BuildRailStation(TileIndex tile, RailTrack direction, uint num_platforms, uint platform_length, bool join_adjacent);
 

	
 
	/**
 
	 * Build a NewGRF rail station. This calls callback 18 to let a NewGRF
 
	 *  provide the station class / id to build, so we don't end up with
 
	 *  only the default stations on the map.
 
	 * @param tile Place to build the station.
 
	 * @param direction The direction to build the station.
 
	 * @param num_platforms The number of platforms to build.
 
	 * @param platform_length The length of each platform.
 
	 * @param join_adjacent When building next to an other station, don't create a new station when this flag is true.
 
	 * @param cargo_id The CargoID of the cargo that will be transported from / to this station.
 
	 * @param source_industry The IndustryType of the industry you'll transport goods from.
 
	 * @param goal_industry The IndustryType of the industry you'll transport goods to.
 
	 * @param distance The manhattan distance you'll transport the cargo over.
 
	 * @param source_station True if this is the source station, false otherwise.
 
	 * @pre IsRailTypeAvailable(GetCurrentRailType()).
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @pre direction == RAILTRACK_NW_SE || direction == RAILTRACK_NE_SW.
 
	 * @pre num_platforms > 0 && num_platforms <= 255.
 
	 * @pre platform_length > 0 && platform_length <= 255.
 
	 * @exception AIError::ERR_OWNED_BY_ANOTHER_COMPANY
 
	 * @exception AIError::ERR_AREA_NOT_CLEAR
 
	 * @exception AIError::ERR_FLAT_LAND_REQUIRED
 
	 * @exception AIStation::ERR_STATION_TOO_CLOSE_TO_ANOTHER_STATION
 
	 * @exception AIStation::ERR_STATION_TOO_MANY_STATIONS
 
	 * @exception AIStation::ERR_STATION_TOO_MANY_STATIONS_IN_TOWN
 
	 * @return Whether the station has been/can be build or not.
 
	 */
 
	static bool BuildNewGRFRailStation(TileIndex tile, RailTrack direction, uint num_platforms, uint platform_length, bool join_adjacent, CargoID cargo_id, IndustryType source_industry, IndustryType goal_industry, int distance, bool source_station);
 

	
 
	/**
 
	 * Remove a rectangle of platform pieces from a rail station.
 
	 * @param tile One corner of the rectangle to clear.
 
	 * @param tile2 The oppposite corner.
 
	 * @pre IsValidTile(tile).
 
	 * @pre IsValidTile(tile2).
 
	 * @return Whether at least one tile has been/can be cleared or not.
 
	 */
 
	static bool RemoveRailStationTileRect(TileIndex tile, TileIndex tile2);
 

	
 
	/**
 
	 * Get all RailTracks on the given tile.
 
	 * @param tile The tile to check.
 
	 * @pre IsRailTile(tile).
 
	 * @return A bitmask of RailTrack with all RailTracks on the tile.
 
	 */
 
	static uint GetRailTracks(TileIndex tile);
 

	
 
	/**
 
	 * Build rail on the given tile.
 
	 * @param tile The tile to build on.
 
	 * @param rail_track The RailTrack to build.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @pre IsRailTypeAvailable(GetCurrentRailType()).
 
	 * @exception AIError::ERR_AREA_NOT_CLEAR
 
	 * @exception AIError::ERR_LAND_SLOPED_WRONG
 
	 * @exception AIRoad::ERR_ROAD_WORKS_IN_PROGRESS
 
	 * @exception AIRail::ERR_CROSSING_ON_ONEWAY_ROAD
 
	 * @exception AIError::ERR_ALREADY_BUILT
 
	 * @return Whether the rail has been/can be build or not.
 
	 * @note You can only build a single track with this function so do not
 
	 *   use the values from RailTrack as bitmask.
 
	 */
 
	static bool BuildRailTrack(TileIndex tile, RailTrack rail_track);
 

	
 
	/**
 
	 * Remove rail on the given tile.
 
	 * @param tile The tile to remove rail from.
 
	 * @param rail_track The RailTrack to remove.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @pre (GetRailTracks(tile) & rail_track) != 0.
 
	 * @return Whether the rail has been/can be removed or not.
 
	 * @note You can only remove a single track with this function so do not
 
	 *   use the values from RailTrack as bitmask.
 
	 */
 
	static bool RemoveRailTrack(TileIndex tile, RailTrack rail_track);
 

	
 
	/**
 
	 * Check if a tile connects two adjacent tiles.
 
	 * @param from The first tile to connect.
 
	 * @param tile The tile that is checked.
 
	 * @param to The second tile to connect.
 
	 * @pre from != to.
 
	 * @pre AIMap::DistanceManhattan(from, tile) == 1.
 
	 * @pre AIMap::DistanceManhattan(to, tile) == 1.
 
	 * @return True if 'tile' connects 'from' and 'to'.
 
	 */
 
	static bool AreTilesConnected(TileIndex from, TileIndex tile, TileIndex to);
 

	
 
	/**
 
	 * Build a rail connection between two tiles.
 
	 * @param from The tile just before the tile to build on.
 
	 * @param tile The first tile to build on.
 
	 * @param to The tile just after the last tile to build on.
 
	 * @pre from != to.
 
	 * @pre AIMap::DistanceManhattan(from, tile) == 1.
 
	 * @pre AIMap::DistanceManhattan(to, tile) >= 1.
 
	 * @pre (abs(abs(AIMap::GetTileX(to) - AIMap::GetTileX(tile)) -
 
	 *          abs(AIMap::GetTileY(to) - AIMap::GetTileY(tile))) <= 1) ||
 
	 *      (AIMap::GetTileX(from) == AIMap::GetTileX(tile) && AIMap::GetTileX(tile) == AIMap::GetTileX(to)) ||
 
	 *      (AIMap::GetTileY(from) == AIMap::GetTileY(tile) && AIMap::GetTileY(tile) == AIMap::GetTileY(to)).
 
	 * @pre IsRailTypeAvailable(GetCurrentRailType()).
 
	 * @exception AIError::ERR_AREA_NOT_CLEAR
 
	 * @exception AIError::ERR_LAND_SLOPED_WRONG
 
	 * @exception AIRail::ERR_CROSSING_ON_ONEWAY_ROAD
 
	 * @exception AIRoad::ERR_ROAD_WORKS_IN_PROGRESS
 
	 * @exception AIError::ERR_ALREADY_BUILT
 
	 * @return Whether the rail has been/can be build or not.
 
	 */
 
	static bool BuildRail(TileIndex from, TileIndex tile, TileIndex to);
 

	
 
	/**
 
	 * Remove a rail connection between two tiles.
 
	 * @param from The tile just before the tile to remove rail from.
 
	 * @param tile The first tile to remove rail from.
 
	 * @param to The tile just after the last tile to remove rail from.
 
	 * @pre from != to.
 
	 * @pre AIMap::DistanceManhattan(from, tile) == 1.
 
	 * @pre AIMap::DistanceManhattan(to, tile) >= 1.
 
	 * @pre (abs(abs(AIMap::GetTileX(to) - AIMap::GetTileX(tile)) -
 
	 *          abs(AIMap::GetTileY(to) - AIMap::GetTileY(tile))) <= 1) ||
 
	 *      (AIMap::GetTileX(from) == AIMap::GetTileX(tile) && AIMap::GetTileX(tile) == AIMap::GetTileX(to)) ||
 
	 *      (AIMap::GetTileY(from) == AIMap::GetTileY(tile) && AIMap::GetTileY(tile) == AIMap::GetTileY(to)).
 
	 * @return Whether the rail has been/can be removed or not.
 
	 */
 
	static bool RemoveRail(TileIndex from, TileIndex tile, TileIndex to);
 

	
 
	/**
 
	 * Get the SignalType of the signal on a tile or SIGNALTYPE_NONE if there is no signal.
 
	 * @pre AIMap::DistanceManhattan(tile, front) == 1.
 
	 * @param tile The tile that might have a signal.
 
	 * @param front The tile in front of 'tile'.
 
	 * @return The SignalType of the signal on 'tile' with it's front to 'front'.
 
	 */
 
	static SignalType GetSignalType(TileIndex tile, TileIndex front);
 

	
 
	/**
 
	 * Build a signal on a tile.
 
	 * @param tile The tile to build on.
 
	 * @param front The tile in front of the signal.
 
	 * @param signal The SignalType to build.
 
	 * @pre AIMap::DistanceManhattan(tile, front) == 1.
 
	 * @pre IsRailTile(tile) && !IsRailStationTile(tile) && !IsRailWaypointTile(tile).
 
	 * @exception AIRail::ERR_UNSUITABLE_TRACK
 
	 * @return Whether the signal has been/can be build or not.
 
	 */
 
	static bool BuildSignal(TileIndex tile, TileIndex front, SignalType signal);
 

	
 
	/**
 
	 * Remove a signal.
 
	 * @param tile The tile to remove the signal from.
 
	 * @param front The tile in front of the signal.
 
	 * @pre AIMap::DistanceManhattan(tile, front) == 1.
 
	 * @pre GetSignalType(tile, front) != SIGNALTYPE_NONE.
 
	 * @return Whether the signal has been/can be removed or not.
 
	 */
 
	static bool RemoveSignal(TileIndex tile, TileIndex front);
 
};
 

	
 
#endif /* AI_RAIL_HPP */
src/ai/api/ai_rail.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_rail.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow enums to be used as Squirrel parameters */
 
	template <> AIRail::ErrorMessages GetParam(ForceType<AIRail::ErrorMessages>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AIRail::ErrorMessages)tmp; }
 
	template <> int Return<AIRail::ErrorMessages>(HSQUIRRELVM vm, AIRail::ErrorMessages res) { sq_pushinteger(vm, (int32)res); return 1; }
 
	template <> AIRail::RailType GetParam(ForceType<AIRail::RailType>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AIRail::RailType)tmp; }
 
	template <> int Return<AIRail::RailType>(HSQUIRRELVM vm, AIRail::RailType res) { sq_pushinteger(vm, (int32)res); return 1; }
 
	template <> AIRail::RailTrack GetParam(ForceType<AIRail::RailTrack>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AIRail::RailTrack)tmp; }
 
	template <> int Return<AIRail::RailTrack>(HSQUIRRELVM vm, AIRail::RailTrack res) { sq_pushinteger(vm, (int32)res); return 1; }
 
	template <> AIRail::SignalType GetParam(ForceType<AIRail::SignalType>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AIRail::SignalType)tmp; }
 
	template <> int Return<AIRail::SignalType>(HSQUIRRELVM vm, AIRail::SignalType res) { sq_pushinteger(vm, (int32)res); return 1; }
 

	
 
	/* Allow AIRail to be used as Squirrel parameter */
 
	template <> AIRail *GetParam(ForceType<AIRail *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIRail *)instance; }
 
	template <> AIRail &GetParam(ForceType<AIRail &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIRail *)instance; }
 
	template <> const AIRail *GetParam(ForceType<const AIRail *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIRail *)instance; }
 
	template <> const AIRail &GetParam(ForceType<const AIRail &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIRail *)instance; }
 
	template <> int Return<AIRail *>(HSQUIRRELVM vm, AIRail *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIRail", res, NULL, DefSQDestructorCallback<AIRail>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIRail_Register(Squirrel *engine) {
 
	DefSQClass <AIRail> SQAIRail("AIRail");
 
	SQAIRail.PreRegister(engine);
 
	SQAIRail.AddConstructor<void (AIRail::*)(), 1>(engine, "x");
 

	
 
	SQAIRail.DefSQConst(engine, AIRail::ERR_RAIL_BASE,                    "ERR_RAIL_BASE");
 
	SQAIRail.DefSQConst(engine, AIRail::ERR_CROSSING_ON_ONEWAY_ROAD,      "ERR_CROSSING_ON_ONEWAY_ROAD");
 
	SQAIRail.DefSQConst(engine, AIRail::ERR_UNSUITABLE_TRACK,             "ERR_UNSUITABLE_TRACK");
 
	SQAIRail.DefSQConst(engine, AIRail::ERR_NONUNIFORM_STATIONS_DISABLED, "ERR_NONUNIFORM_STATIONS_DISABLED");
 
	SQAIRail.DefSQConst(engine, AIRail::RAILTYPE_INVALID,                 "RAILTYPE_INVALID");
 
	SQAIRail.DefSQConst(engine, AIRail::RAILTRACK_NE_SW,                  "RAILTRACK_NE_SW");
 
	SQAIRail.DefSQConst(engine, AIRail::RAILTRACK_NW_SE,                  "RAILTRACK_NW_SE");
 
	SQAIRail.DefSQConst(engine, AIRail::RAILTRACK_NW_NE,                  "RAILTRACK_NW_NE");
 
	SQAIRail.DefSQConst(engine, AIRail::RAILTRACK_SW_SE,                  "RAILTRACK_SW_SE");
 
	SQAIRail.DefSQConst(engine, AIRail::RAILTRACK_NW_SW,                  "RAILTRACK_NW_SW");
 
	SQAIRail.DefSQConst(engine, AIRail::RAILTRACK_NE_SE,                  "RAILTRACK_NE_SE");
 
	SQAIRail.DefSQConst(engine, AIRail::RAILTRACK_INVALID,                "RAILTRACK_INVALID");
 
	SQAIRail.DefSQConst(engine, AIRail::SIGNALTYPE_NORMAL,                "SIGNALTYPE_NORMAL");
 
	SQAIRail.DefSQConst(engine, AIRail::SIGNALTYPE_ENTRY,                 "SIGNALTYPE_ENTRY");
 
	SQAIRail.DefSQConst(engine, AIRail::SIGNALTYPE_EXIT,                  "SIGNALTYPE_EXIT");
 
	SQAIRail.DefSQConst(engine, AIRail::SIGNALTYPE_COMBO,                 "SIGNALTYPE_COMBO");
 
	SQAIRail.DefSQConst(engine, AIRail::SIGNALTYPE_PBS,                   "SIGNALTYPE_PBS");
 
	SQAIRail.DefSQConst(engine, AIRail::SIGNALTYPE_PBS_ONEWAY,            "SIGNALTYPE_PBS_ONEWAY");
 
	SQAIRail.DefSQConst(engine, AIRail::SIGNALTYPE_TWOWAY,                "SIGNALTYPE_TWOWAY");
 
	SQAIRail.DefSQConst(engine, AIRail::SIGNALTYPE_NORMAL_TWOWAY,         "SIGNALTYPE_NORMAL_TWOWAY");
 
	SQAIRail.DefSQConst(engine, AIRail::SIGNALTYPE_ENTRY_TWOWAY,          "SIGNALTYPE_ENTRY_TWOWAY");
 
	SQAIRail.DefSQConst(engine, AIRail::SIGNALTYPE_EXIT_TWOWAY,           "SIGNALTYPE_EXIT_TWOWAY");
 
	SQAIRail.DefSQConst(engine, AIRail::SIGNALTYPE_COMBO_TWOWAY,          "SIGNALTYPE_COMBO_TWOWAY");
 
	SQAIRail.DefSQConst(engine, AIRail::SIGNALTYPE_NONE,                  "SIGNALTYPE_NONE");
 

	
 
	AIError::RegisterErrorMap(STR_ERR_CROSSING_ON_ONEWAY_ROAD,     AIRail::ERR_CROSSING_ON_ONEWAY_ROAD);
 
	AIError::RegisterErrorMap(STR_1005_NO_SUITABLE_RAILROAD_TRACK, AIRail::ERR_UNSUITABLE_TRACK);
 
	AIError::RegisterErrorMap(STR_NONUNIFORM_STATIONS_DISALLOWED,  AIRail::ERR_NONUNIFORM_STATIONS_DISABLED);
 

	
 
	AIError::RegisterErrorMapString(AIRail::ERR_CROSSING_ON_ONEWAY_ROAD,      "ERR_CROSSING_ON_ONEWAY_ROAD");
 
	AIError::RegisterErrorMapString(AIRail::ERR_UNSUITABLE_TRACK,             "ERR_UNSUITABLE_TRACK");
 
	AIError::RegisterErrorMapString(AIRail::ERR_NONUNIFORM_STATIONS_DISABLED, "ERR_NONUNIFORM_STATIONS_DISABLED");
 

	
 
	SQAIRail.DefSQStaticMethod(engine, &AIRail::GetClassName,              "GetClassName",              1, "x");
 
	SQAIRail.DefSQStaticMethod(engine, &AIRail::IsRailTile,                "IsRailTile",                2, "xi");
 
	SQAIRail.DefSQStaticMethod(engine, &AIRail::IsLevelCrossingTile,       "IsLevelCrossingTile",       2, "xi");
 
	SQAIRail.DefSQStaticMethod(engine, &AIRail::IsRailDepotTile,           "IsRailDepotTile",           2, "xi");
 
	SQAIRail.DefSQStaticMethod(engine, &AIRail::IsRailStationTile,         "IsRailStationTile",         2, "xi");
 
	SQAIRail.DefSQStaticMethod(engine, &AIRail::IsRailWaypointTile,        "IsRailWaypointTile",        2, "xi");
 
	SQAIRail.DefSQStaticMethod(engine, &AIRail::IsRailTypeAvailable,       "IsRailTypeAvailable",       2, "xi");
 
	SQAIRail.DefSQStaticMethod(engine, &AIRail::GetCurrentRailType,        "GetCurrentRailType",        1, "x");
 
	SQAIRail.DefSQStaticMethod(engine, &AIRail::SetCurrentRailType,        "SetCurrentRailType",        2, "xi");
 
	SQAIRail.DefSQStaticMethod(engine, &AIRail::TrainCanRunOnRail,         "TrainCanRunOnRail",         3, "xii");
 
	SQAIRail.DefSQStaticMethod(engine, &AIRail::TrainHasPowerOnRail,       "TrainHasPowerOnRail",       3, "xii");
 
	SQAIRail.DefSQStaticMethod(engine, &AIRail::GetRailType,               "GetRailType",               2, "xi");
 
	SQAIRail.DefSQStaticMethod(engine, &AIRail::ConvertRailType,           "ConvertRailType",           4, "xiii");
 
	SQAIRail.DefSQStaticMethod(engine, &AIRail::GetRailDepotFrontTile,     "GetRailDepotFrontTile",     2, "xi");
 
	SQAIRail.DefSQStaticMethod(engine, &AIRail::GetRailStationDirection,   "GetRailStationDirection",   2, "xi");
 
	SQAIRail.DefSQStaticMethod(engine, &AIRail::BuildRailDepot,            "BuildRailDepot",            3, "xii");
 
	SQAIRail.DefSQStaticMethod(engine, &AIRail::BuildRailStation,          "BuildRailStation",          6, "xiiiib");
 
	SQAIRail.DefSQStaticMethod(engine, &AIRail::BuildNewGRFRailStation,    "BuildNewGRFRailStation",    11, "xiiiibiiiib");
 
	SQAIRail.DefSQStaticMethod(engine, &AIRail::RemoveRailStationTileRect, "RemoveRailStationTileRect", 3, "xii");
 
	SQAIRail.DefSQStaticMethod(engine, &AIRail::GetRailTracks,             "GetRailTracks",             2, "xi");
 
	SQAIRail.DefSQStaticMethod(engine, &AIRail::BuildRailTrack,            "BuildRailTrack",            3, "xii");
 
	SQAIRail.DefSQStaticMethod(engine, &AIRail::RemoveRailTrack,           "RemoveRailTrack",           3, "xii");
 
	SQAIRail.DefSQStaticMethod(engine, &AIRail::AreTilesConnected,         "AreTilesConnected",         4, "xiii");
 
	SQAIRail.DefSQStaticMethod(engine, &AIRail::BuildRail,                 "BuildRail",                 4, "xiii");
 
	SQAIRail.DefSQStaticMethod(engine, &AIRail::RemoveRail,                "RemoveRail",                4, "xiii");
 
	SQAIRail.DefSQStaticMethod(engine, &AIRail::GetSignalType,             "GetSignalType",             3, "xii");
 
	SQAIRail.DefSQStaticMethod(engine, &AIRail::BuildSignal,               "BuildSignal",               4, "xiii");
 
	SQAIRail.DefSQStaticMethod(engine, &AIRail::RemoveSignal,              "RemoveSignal",              3, "xii");
 

	
 
	SQAIRail.PostRegister(engine);
 
}
src/ai/api/ai_railtypelist.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_railtypelist.cpp Implementation of AIRailTypeList and friends. */
 

	
 
#include "ai_railtypelist.hpp"
 
#include "../../rail.h"
 
#include "../../company_func.h"
 

	
 
AIRailTypeList::AIRailTypeList()
 
{
 
	for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) {
 
		if (::HasRailtypeAvail(_current_company, rt)) this->AddItem(rt);
 
	}
 
}
src/ai/api/ai_railtypelist.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_railtypelist.hpp List all available railtypes. */
 

	
 
#ifndef AI_RAILTYPELIST_HPP
 
#define AI_RAILTYPELIST_HPP
 

	
 
#include "ai_abstractlist.hpp"
 

	
 
/**
 
 * Creates a list of all available railtypes.
 
 * @ingroup AIList
 
 */
 
class AIRailTypeList : public AIAbstractList {
 
public:
 
	static const char *GetClassName() { return "AIRailTypeList"; }
 
	AIRailTypeList();
 
};
 

	
 
#endif /* AI_RAILTYPELIST_HPP */
src/ai/api/ai_railtypelist.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_railtypelist.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow AIRailTypeList to be used as Squirrel parameter */
 
	template <> AIRailTypeList *GetParam(ForceType<AIRailTypeList *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIRailTypeList *)instance; }
 
	template <> AIRailTypeList &GetParam(ForceType<AIRailTypeList &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIRailTypeList *)instance; }
 
	template <> const AIRailTypeList *GetParam(ForceType<const AIRailTypeList *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIRailTypeList *)instance; }
 
	template <> const AIRailTypeList &GetParam(ForceType<const AIRailTypeList &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIRailTypeList *)instance; }
 
	template <> int Return<AIRailTypeList *>(HSQUIRRELVM vm, AIRailTypeList *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIRailTypeList", res, NULL, DefSQDestructorCallback<AIRailTypeList>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIRailTypeList_Register(Squirrel *engine) {
 
	DefSQClass <AIRailTypeList> SQAIRailTypeList("AIRailTypeList");
 
	SQAIRailTypeList.PreRegister(engine, "AIAbstractList");
 
	SQAIRailTypeList.AddConstructor<void (AIRailTypeList::*)(), 1>(engine, "x");
 

	
 
	SQAIRailTypeList.DefSQStaticMethod(engine, &AIRailTypeList::GetClassName, "GetClassName", 1, "x");
 

	
 
	SQAIRailTypeList.PostRegister(engine);
 
}
src/ai/api/ai_road.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_road.cpp Implementation of AIRoad. */
 

	
 
#include "ai_road.hpp"
 
#include "ai_map.hpp"
 
#include "ai_list.hpp"
 
#include "../../openttd.h"
 
#include "../../road_map.h"
 
#include "../../station_map.h"
 
#include "../../tunnelbridge_map.h"
 
#include "../../command_type.h"
 
#include "../../company_func.h"
 
#include "../../settings_type.h"
 
#include "../../script/squirrel_helper_type.hpp"
 

	
 
/* static */ bool AIRoad::IsRoadTile(TileIndex tile)
 
{
 
	if (!::IsValidTile(tile)) return false;
 

	
 
	return (::IsTileType(tile, MP_ROAD) && ::GetRoadTileType(tile) != ROAD_TILE_DEPOT) ||
 
			IsDriveThroughRoadStationTile(tile);
 
}
 

	
 
/* static */ bool AIRoad::IsRoadDepotTile(TileIndex tile)
 
{
 
	if (!::IsValidTile(tile)) return false;
 

	
 
	return ::IsTileType(tile, MP_ROAD) && ::GetRoadTileType(tile) == ROAD_TILE_DEPOT &&
 
			(::RoadTypeToRoadTypes((::RoadType)GetCurrentRoadType()) & ::GetRoadTypes(tile)) != 0;
 
}
 

	
 
/* static */ bool AIRoad::IsRoadStationTile(TileIndex tile)
 
{
 
	if (!::IsValidTile(tile)) return false;
 

	
 
	return ::IsRoadStopTile(tile) && (::RoadTypeToRoadTypes((::RoadType)GetCurrentRoadType()) & ::GetRoadTypes(tile)) != 0;
 
}
 

	
 
/* static */ bool AIRoad::IsDriveThroughRoadStationTile(TileIndex tile)
 
{
 
	if (!::IsValidTile(tile)) return false;
 

	
 
	return ::IsDriveThroughStopTile(tile) && (::RoadTypeToRoadTypes((::RoadType)GetCurrentRoadType()) & ::GetRoadTypes(tile)) != 0;
 
}
 

	
 
/* static */ bool AIRoad::IsRoadTypeAvailable(RoadType road_type)
 
{
 
	return ::HasRoadTypesAvail(_current_company, ::RoadTypeToRoadTypes((::RoadType)road_type));
 
}
 

	
 
/* static */ AIRoad::RoadType AIRoad::GetCurrentRoadType()
 
{
 
	return (RoadType)AIObject::GetRoadType();
 
}
 

	
 
/* static */ void AIRoad::SetCurrentRoadType(RoadType road_type)
 
{
 
	if (!IsRoadTypeAvailable(road_type)) return;
 

	
 
	AIObject::SetRoadType((::RoadType)road_type);
 
}
 

	
 
/* static */ bool AIRoad::HasRoadType(TileIndex tile, RoadType road_type)
 
{
 
	if (!AIMap::IsValidTile(tile)) return false;
 
	if (!IsRoadTypeAvailable(road_type)) return false;
 
	return ::GetAnyRoadBits(tile, (::RoadType)road_type, false) != ROAD_NONE;
 
}
 

	
 
/* static */ bool AIRoad::AreRoadTilesConnected(TileIndex t1, TileIndex t2)
 
{
 
	if (!::IsValidTile(t1)) return false;
 
	if (!::IsValidTile(t2)) return false;
 

	
 
	/* Tiles not neighbouring */
 
	if ((abs((int)::TileX(t1) - (int)::TileX(t2)) + abs((int)::TileY(t1) - (int)::TileY(t2))) != 1) return false;
 

	
 
	RoadBits r1 = ::GetAnyRoadBits(t1, AIObject::GetRoadType());
 
	RoadBits r2 = ::GetAnyRoadBits(t2, AIObject::GetRoadType());
 

	
 
	uint dir_1 = (::TileX(t1) == ::TileX(t2)) ? (::TileY(t1) < ::TileY(t2) ? 2 : 0) : (::TileX(t1) < ::TileX(t2) ? 1 : 3);
 
	uint dir_2 = 2 ^ dir_1;
 

	
 
	DisallowedRoadDirections drd2 = IsNormalRoadTile(t2) ? GetDisallowedRoadDirections(t2) : DRD_NONE;
 

	
 
	return HasBit(r1, dir_1) && HasBit(r2, dir_2) && drd2 != DRD_BOTH && drd2 != (dir_1 > dir_2 ? DRD_SOUTHBOUND : DRD_NORTHBOUND);
 
}
 

	
 
/* Helper functions for AIRoad::CanBuildConnectedRoadParts(). */
 

	
 
/**
 
 * Check whether the given existing bits the start and end part can be build.
 
 *  As the function assumes the bits being build on a slope that does not
 
 *  allow level foundations all of the existing parts will always be in
 
 *  a straight line. This also needs to hold for the start and end parts,
 
 *  otherwise it is for sure not valid. Finally a check will be done to
 
 *  determine whether the existing road parts match the to-be-build parts.
 
 *  As they can only be placed in one direction, just checking the start
 
 *  part with the first existing part is enough.
 
 * @param existing The existing road parts.
 
 * @param start The part that should be build first.
 
 * @param end The part that will be build second.
 
 * @return True if and only if the road bits can be build.
 
 */
 
static bool CheckAutoExpandedRoadBits(const Array *existing, int32 start, int32 end)
 
{
 
	return (start + end == 0) && (existing->size == 0 || existing->array[0] == start || existing->array[0] == end);
 
}
 

	
 
/**
 
 * Lookup function for building road parts when building on slopes is disabled.
 
 * @param slope The slope of the tile to examine.
 
 * @param existing The existing road parts.
 
 * @param start The part that should be build first.
 
 * @param end The part that will be build second.
 
 * @return 0 when the build parts do not connect, 1 when they do connect once
 
 *         they are build or 2 when building the first part automatically
 
 *         builds the second part.
 
 */
 
static int32 LookupWithoutBuildOnSlopes(::Slope slope, const Array *existing, int32 start, int32 end)
 
{
 
	switch (slope) {
 
		/* Flat slopes can always be build. */
 
		case SLOPE_FLAT:
 
			return 1;
 

	
 
		/* Only 4 of the slopes can be build upon. Testing the existing bits is
 
		 * necessary because these bits can be something else when the settings
 
		 * in the game have been changed.
 
		 */
 
		case SLOPE_NE: case SLOPE_SW:
 
			return (CheckAutoExpandedRoadBits(existing, start, end) && (start == 1 || end == 1)) ? (existing->size == 0 ? 2 : 1) : 0;
 
		case SLOPE_SE: case SLOPE_NW:
 
			return (CheckAutoExpandedRoadBits(existing, start, end) && (start != 1 && end != 1)) ? (existing->size == 0 ? 2 : 1) : 0;
 

	
 
		/* Any other tile cannot be built on. */
 
		default:
 
			return 0;
 
	}
 
}
 

	
 
/**
 
 * Rotate a neighbour bit a single time clockwise.
 
 * @param neighbour The neighbour.
 
 * @return The rotate neighbour data.
 
 */
 
static int32 RotateNeighbour(int32 neighbour)
 
{
 
	switch (neighbour) {
 
		case -2: return -1;
 
		case -1: return  2;
 
		case  1: return -2;
 
		case  2: return  1;
 
		default: NOT_REACHED();
 
	}
 
}
 

	
 
/**
 
 * Convert a neighbour to a road bit representation for easy internal use.
 
 * @param neighbour The neighbour.
 
 * @return The bits representing the direction.
 
 */
 
static RoadBits NeighbourToRoadBits(int32 neighbour)
 
{
 
	switch (neighbour) {
 
		case -2: return ROAD_NW;
 
		case -1: return ROAD_NE;
 
		case  2: return ROAD_SE;
 
		case  1: return ROAD_SW;
 
		default: NOT_REACHED();
 
	}
 
}
 

	
 
/**
 
 * Lookup function for building road parts when building on slopes is enabled.
 
 * @param slope The slope of the tile to examine.
 
 * @param existing The existing neighbours.
 
 * @param start The part that should be build first.
 
 * @param end The part that will be build second.
 
 * @return 0 when the build parts do not connect, 1 when they do connect once
 
 *         they are build or 2 when building the first part automatically
 
 *         builds the second part.
 
 */
 
static int32 LookupWithBuildOnSlopes(::Slope slope, Array *existing, int32 start, int32 end)
 
{
 
	if (::IsSteepSlope(slope)) {
 
		switch (slope) {
 
			/* On steep slopes one can only build straight roads that will be
 
			 * automatically expanded to a straight road. Just check that the existing
 
			 * road parts are in the same direction. */
 
			case SLOPE_STEEP_S:
 
			case SLOPE_STEEP_W:
 
			case SLOPE_STEEP_N:
 
			case SLOPE_STEEP_E:
 
				return CheckAutoExpandedRoadBits(existing, start, end) ? (existing->size == 0 ? 2 : 1) : 0;
 

	
 
			/* All other slopes are invalid slopes!. */
 
			default:
 
				return -1;
 
		}
 
	}
 

	
 
	/* The slope is not steep. Furthermore lots of slopes are generally the
 
	 * same but are only rotated. So to reduce the amount of lookup work that
 
	 * needs to be done the data is made uniform. This means rotating the
 
	 * existing parts and updating the slope. */
 
	static const ::Slope base_slopes[] = {
 
		SLOPE_FLAT, SLOPE_W,   SLOPE_W,   SLOPE_SW,
 
		SLOPE_W,    SLOPE_EW,  SLOPE_SW,  SLOPE_WSE,
 
		SLOPE_W,    SLOPE_SW,  SLOPE_EW,  SLOPE_WSE,
 
		SLOPE_SW,   SLOPE_WSE, SLOPE_WSE};
 
	static const byte base_rotates[] = {0, 0, 1, 0, 2, 0, 1, 0, 3, 3, 2, 3, 2, 2, 1};
 

	
 
	if (slope >= (::Slope)lengthof(base_slopes)) {
 
		/* This slope is an invalid slope, so ignore it. */
 
		return -1;
 
	}
 
	byte base_rotate = base_rotates[slope];
 
	slope = base_slopes[slope];
 

	
 
	/* Some slopes don't need rotating, so return early when we know we do
 
	 * not need to rotate. */
 
	switch (slope) {
 
		case SLOPE_FLAT:
 
			/* Flat slopes can always be build. */
 
			return 1;
 

	
 
		case SLOPE_EW:
 
		case SLOPE_WSE:
 
			/* A slope similar to a SLOPE_EW or SLOPE_WSE will always cause
 
			 * foundations which makes them accessible from all sides. */
 
			return 1;
 

	
 
		case SLOPE_W:
 
		case SLOPE_SW:
 
			/* A slope for which we need perform some calculations. */
 
			break;
 

	
 
		default:
 
			/* An invalid slope. */
 
			return -1;
 
	}
 

	
 
	/* Now perform the actual rotation. */
 
	for (int j = 0; j < base_rotate; j++) {
 
		for (int i = 0; i < existing->size; i++) {
 
			existing->array[i] = RotateNeighbour(existing->array[i]);
 
		}
 
		start = RotateNeighbour(start);
 
		end   = RotateNeighbour(end);
 
	}
 

	
 
	/* Create roadbits out of the data for easier handling. */
 
	RoadBits start_roadbits    = NeighbourToRoadBits(start);
 
	RoadBits new_roadbits      = start_roadbits | NeighbourToRoadBits(end);
 
	RoadBits existing_roadbits = ROAD_NONE;
 
	for (int i = 0; i < existing->size; i++) {
 
		existing_roadbits |= NeighbourToRoadBits(existing->array[i]);
 
	}
 

	
 
	switch (slope) {
 
		case SLOPE_W:
 
			/* A slope similar to a SLOPE_W. */
 
			switch (new_roadbits) {
 
				case  6: // ROAD_SE | ROAD_SW:
 
				case  9: // ROAD_NE | ROAD_NW:
 
				case 12: // ROAD_NE | ROAD_SE:
 
					/* Cannot build anything with a turn from the low side. */
 
					return 0;
 

	
 
				case  5: // ROAD_SE | ROAD_NW:
 
				case 10: // ROAD_NE | ROAD_SW:
 
					/* A 'sloped' tile is going to be build. */
 
					if ((existing_roadbits | new_roadbits) != new_roadbits) {
 
						/* There is already a foundation on the tile, or at least
 
						 * another slope that is not compatible with the new one. */
 
						return 0;
 
					}
 
					/* If the start is in the low part, it is automatically
 
					 * building the second part too. */
 
					return ((start_roadbits & (ROAD_NE | ROAD_SE)) && !(existing_roadbits & (ROAD_SW | ROAD_NW))) ? 2 : 1;
 

	
 
				default:
 
					/* Roadbits causing a foundation are going to be build.
 
					 * When the existing roadbits are slopes (the lower bits
 
					 * are used), this cannot be done. */
 
					if ((existing_roadbits | new_roadbits) == new_roadbits) return 1;
 
					return (existing_roadbits & (ROAD_NE | ROAD_SE)) ? 0 : 1;
 
			}
 

	
 
		case SLOPE_SW:
 
			/* A slope similar to a SLOPE_SW. */
 
			switch (new_roadbits) {
 
				case  9: // ROAD_NE | ROAD_NW:
 
				case 12: // ROAD_NE | ROAD_SE:
 
					/* Cannot build anything with a turn from the low side. */
 
					return 0;
 

	
 
				case 10: // ROAD_NE | ROAD_SW:
 
					/* A 'sloped' tile is going to be build. */
 
					if ((existing_roadbits | new_roadbits) != new_roadbits) {
 
						/* There is already a foundation on the tile, or at least
 
						 * another slope that is not compatible with the new one. */
 
						return 0;
 
					}
 
					/* If the start is in the low part, it is automatically
 
					 * building the second part too. */
 
					return ((start_roadbits & ROAD_NE) && !(existing_roadbits & ROAD_SW)) ? 2 : 1;
 

	
 
				default:
 
					/* Roadbits causing a foundation are going to be build.
 
					 * When the existing roadbits are slopes (the lower bits
 
					 * are used), this cannot be done. */
 
					return (existing_roadbits & ROAD_NE) ? 0 : 1;
 
			}
 

	
 
		default:
 
			NOT_REACHED();
 
	}
 
}
 

	
 
/**
 
 * Normalise all input data so we can easily handle it without needing
 
 * to call the API lots of times or create large if-elseif-elseif-else
 
 * constructs.
 
 * In this case it means that a TileXY(0, -1) becomes -2 and TileXY(0, 1)
 
 * becomes 2. TileXY(-1, 0) and TileXY(1, 0) stay respectively -1 and 1.
 
 * Any other value means that it is an invalid tile offset.
 
 * @param tile The tile to normalise.
 
 * @return True if and only if the tile offset is valid.
 
 */
 
static bool NormaliseTileOffset(int32 *tile)
 
{
 
		if (*tile == 1 || *tile == -1) return true;
 
		if (*tile == ::TileDiffXY(0, -1)) {
 
			*tile = -2;
 
			return true;
 
		}
 
		if (*tile == ::TileDiffXY(0, 1)) {
 
			*tile = 2;
 
			return true;
 
		}
 
		return false;
 
}
 

	
 
/* static */ int32 AIRoad::CanBuildConnectedRoadParts(AITile::Slope slope_, Array *existing, TileIndex start_, TileIndex end_)
 
{
 
	::Slope slope = (::Slope)slope_;
 
	int32 start = start_;
 
	int32 end = end_;
 

	
 
	/* The start tile and end tile cannot be the same tile either. */
 
	if (start == end) return -1;
 

	
 
	for (int i = 0; i < existing->size; i++) {
 
		if (!NormaliseTileOffset(&existing->array[i])) return -1;
 
	}
 

	
 
	if (!NormaliseTileOffset(&start)) return -1;
 
	if (!NormaliseTileOffset(&end)) return -1;
 

	
 
	/* Without build on slopes the characteristics are vastly different, so use
 
	 * a different helper function (one that is much simpler). */
 
	return _settings_game.construction.build_on_slopes ? LookupWithBuildOnSlopes(slope, existing, start, end) : LookupWithoutBuildOnSlopes(slope, existing, start, end);
 
}
 

	
 
/* static */ int32 AIRoad::CanBuildConnectedRoadPartsHere(TileIndex tile, TileIndex start, TileIndex end)
 
{
 
	if (!::IsValidTile(tile) || !::IsValidTile(start) || !::IsValidTile(end)) return -1;
 
	if (::DistanceManhattan(tile, start) != 1 || ::DistanceManhattan(tile, end) != 1) return -1;
 

	
 
	/*                                       ROAD_NW              ROAD_SW             ROAD_SE             ROAD_NE */
 
	static const TileIndex neighbours[] = {::TileDiffXY(0, -1), ::TileDiffXY(1, 0), ::TileDiffXY(0, 1), ::TileDiffXY(-1, 0)};
 
	Array *existing = (Array*)alloca(sizeof(Array) + lengthof(neighbours) * sizeof(int32));
 
	existing->size = 0;
 

	
 
	::RoadBits rb = ::ROAD_NONE;
 
	if (::IsNormalRoadTile(tile)) {
 
		rb = ::GetAllRoadBits(tile);
 
	} else {
 
		for (::RoadType rt = ::ROADTYPE_BEGIN; rt < ::ROADTYPE_END; rt++) rb |= ::GetAnyRoadBits(tile, rt);
 
	}
 
	for (uint i = 0; i < lengthof(neighbours); i++) {
 
		if (HasBit(rb, i)) existing->array[existing->size++] = neighbours[i];
 
	}
 

	
 
	return AIRoad::CanBuildConnectedRoadParts(AITile::GetSlope(tile), existing, start - tile, end - tile);
 
}
 

	
 
/**
 
 * Check whether one can reach (possibly by building) a road piece the center
 
 * of the neighbouring tile. This includes roads and (drive through) stations.
 
 * @param start_tile The tile to "enter" the neighbouring tile.
 
 * @param neighbour The direction to the neighbouring tile to "enter".
 
 * @return true if and only if the tile is reachable.
 
 */
 
static bool NeighbourHasReachableRoad(::RoadTypes rts, TileIndex start_tile, DiagDirection neighbour)
 
{
 
	TileIndex neighbour_tile = ::TileAddByDiagDir(start_tile, neighbour);
 
	if ((rts & ::GetRoadTypes(neighbour_tile)) == 0) return	false;
 

	
 
	switch (::GetTileType(neighbour_tile)) {
 
		case MP_ROAD:
 
			return (::GetRoadTileType(neighbour_tile) != ROAD_TILE_DEPOT);
 

	
 
		case MP_STATION:
 
			if (::IsDriveThroughStopTile(neighbour_tile)) {
 
				return (::DiagDirToAxis(neighbour) == ::DiagDirToAxis(::GetRoadStopDir(neighbour_tile)));
 
			}
 
			return false;
 

	
 
		default:
 
			return false;
 
	}
 
}
 

	
 
/* static */ int32 AIRoad::GetNeighbourRoadCount(TileIndex tile)
 
{
 
	if (!::IsValidTile(tile)) return false;
 

	
 
	::RoadTypes rts = ::RoadTypeToRoadTypes((::RoadType)GetCurrentRoadType());
 
	int32 neighbour = 0;
 

	
 
	if (NeighbourHasReachableRoad(rts, tile, DIAGDIR_NE)) neighbour++;
 
	if (NeighbourHasReachableRoad(rts, tile, DIAGDIR_SE)) neighbour++;
 
	if (NeighbourHasReachableRoad(rts, tile, DIAGDIR_SW)) neighbour++;
 
	if (NeighbourHasReachableRoad(rts, tile, DIAGDIR_NW)) neighbour++;
 

	
 
	return neighbour;
 
}
 

	
 
/* static */ TileIndex AIRoad::GetRoadDepotFrontTile(TileIndex depot)
 
{
 
	if (!IsRoadDepotTile(depot)) return INVALID_TILE;
 

	
 
	return depot + ::TileOffsByDiagDir(::GetRoadDepotDirection(depot));
 
}
 

	
 
/* static */ TileIndex AIRoad::GetRoadStationFrontTile(TileIndex station)
 
{
 
	if (!IsRoadStationTile(station)) return INVALID_TILE;
 

	
 
	return station + ::TileOffsByDiagDir(::GetRoadStopDir(station));
 
}
 

	
 
/* static */ TileIndex AIRoad::GetDriveThroughBackTile(TileIndex station)
 
{
 
	if (!IsDriveThroughRoadStationTile(station)) return INVALID_TILE;
 

	
 
	return station + ::TileOffsByDiagDir(::ReverseDiagDir(::GetRoadStopDir(station)));
 
}
 

	
 
/* static */ bool AIRoad::_BuildRoadInternal(TileIndex start, TileIndex end, bool one_way, bool full)
 
{
 
	EnforcePrecondition(false, start != end);
 
	EnforcePrecondition(false, ::IsValidTile(start));
 
	EnforcePrecondition(false, ::IsValidTile(end));
 
	EnforcePrecondition(false, ::TileX(start) == ::TileX(end) || ::TileY(start) == ::TileY(end));
 
	EnforcePrecondition(false, !one_way || AIObject::GetRoadType() == ::ROADTYPE_ROAD);
 

	
 
	return AIObject::DoCommand(end, start, (::TileY(start) != ::TileY(end) ? 4 : 0) | (((start < end) == !full) ? 1 : 2) | (AIObject::GetRoadType() << 3) | ((one_way ? 1 : 0) << 5), CMD_BUILD_LONG_ROAD);
 
}
 

	
 
/* static */ bool AIRoad::BuildRoad(TileIndex start, TileIndex end)
 
{
 
	return _BuildRoadInternal(start, end, false, false);
 
}
 

	
 
/* static */ bool AIRoad::BuildOneWayRoad(TileIndex start, TileIndex end)
 
{
 
	return _BuildRoadInternal(start, end, true, false);
 
}
 

	
 
/* static */ bool AIRoad::BuildRoadFull(TileIndex start, TileIndex end)
 
{
 
	return _BuildRoadInternal(start, end, false, true);
 
}
 

	
 
/* static */ bool AIRoad::BuildOneWayRoadFull(TileIndex start, TileIndex end)
 
{
 
	return _BuildRoadInternal(start, end, true, true);
 
}
 

	
 
/* static */ bool AIRoad::BuildRoadDepot(TileIndex tile, TileIndex front)
 
{
 
	EnforcePrecondition(false, tile != front);
 
	EnforcePrecondition(false, ::IsValidTile(tile));
 
	EnforcePrecondition(false, ::IsValidTile(front));
 
	EnforcePrecondition(false, ::TileX(tile) == ::TileX(front) || ::TileY(tile) == ::TileY(front));
 

	
 
	uint entrance_dir = (::TileX(tile) == ::TileX(front)) ? (::TileY(tile) < ::TileY(front) ? 1 : 3) : (::TileX(tile) < ::TileX(front) ? 2 : 0);
 

	
 
	return AIObject::DoCommand(tile, entrance_dir | (AIObject::GetRoadType() << 2), 0, CMD_BUILD_ROAD_DEPOT);
 
}
 

	
 
/* static */ bool AIRoad::BuildRoadStation(TileIndex tile, TileIndex front, bool truck, bool drive_through, bool join_adjacent)
 
{
 
	EnforcePrecondition(false, tile != front);
 
	EnforcePrecondition(false, ::IsValidTile(tile));
 
	EnforcePrecondition(false, ::IsValidTile(front));
 
	EnforcePrecondition(false, ::TileX(tile) == ::TileX(front) || ::TileY(tile) == ::TileY(front));
 

	
 
	uint entrance_dir;
 
	if (drive_through) {
 
		entrance_dir = ::TileY(tile) != ::TileY(front);
 
	} else {
 
		entrance_dir = (::TileX(tile) == ::TileX(front)) ? (::TileY(tile) < ::TileY(front) ? 1 : 3) : (::TileX(tile) < ::TileX(front) ? 2 : 0);
 
	}
 

	
 
	return AIObject::DoCommand(tile, entrance_dir, (join_adjacent ? 0 : 32) | (drive_through ? 2 : 0) | (truck ? 1 : 0) | (::RoadTypeToRoadTypes(AIObject::GetRoadType()) << 2) | (INVALID_STATION << 16), CMD_BUILD_ROAD_STOP);
 
}
 

	
 
/* static */ bool AIRoad::RemoveRoad(TileIndex start, TileIndex end)
 
{
 
	EnforcePrecondition(false, ::IsValidTile(start));
 
	EnforcePrecondition(false, ::IsValidTile(end));
 
	EnforcePrecondition(false, ::TileX(start) == ::TileX(end) || ::TileY(start) == ::TileY(end));
 

	
 
	return AIObject::DoCommand(end, start, (::TileY(start) != ::TileY(end) ? 4 : 0) | (start < end ? 1 : 2) | (AIObject::GetRoadType() << 3), CMD_REMOVE_LONG_ROAD);
 
}
 

	
 
/* static */ bool AIRoad::RemoveRoadFull(TileIndex start, TileIndex end)
 
{
 
	EnforcePrecondition(false, ::IsValidTile(start));
 
	EnforcePrecondition(false, ::IsValidTile(end));
 
	EnforcePrecondition(false, ::TileX(start) == ::TileX(end) || ::TileY(start) == ::TileY(end));
 

	
 
	return AIObject::DoCommand(end, start, (::TileY(start) != ::TileY(end) ? 4 : 0) | (start < end ? 2 : 1) | (AIObject::GetRoadType() << 3), CMD_REMOVE_LONG_ROAD);
 
}
 

	
 
/* static */ bool AIRoad::RemoveRoadDepot(TileIndex tile)
 
{
 
	EnforcePrecondition(false, ::IsValidTile(tile));
 
	EnforcePrecondition(false, IsTileType(tile, MP_ROAD))
 
	EnforcePrecondition(false, GetRoadTileType(tile) == ROAD_TILE_DEPOT);
 

	
 
	return AIObject::DoCommand(tile, 0, 0, CMD_LANDSCAPE_CLEAR);
 
}
 

	
 
/* static */ bool AIRoad::RemoveRoadStation(TileIndex tile)
 
{
 
	EnforcePrecondition(false, ::IsValidTile(tile));
 
	EnforcePrecondition(false, IsTileType(tile, MP_STATION));
 
	EnforcePrecondition(false, IsRoadStop(tile));
 

	
 
	return AIObject::DoCommand(tile, 0, GetRoadStopType(tile), CMD_REMOVE_ROAD_STOP);
 
}
src/ai/api/ai_road.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_road.hpp Everything to query and build roads. */
 

	
 
#ifndef AI_ROAD_HPP
 
#define AI_ROAD_HPP
 

	
 
#include "ai_object.hpp"
 
#include "ai_error.hpp"
 
#include "ai_tile.hpp"
 

	
 
/**
 
 * Class that handles all road related functions.
 
 */
 
class AIRoad : public AIObject {
 
public:
 
	static const char *GetClassName() { return "AIRoad"; }
 

	
 
	/**
 
	 * All road related error messages.
 
	 */
 
	enum ErrorMessages {
 
		/** Base for road building / maintaining errors */
 
		ERR_ROAD_BASE = AIError::ERR_CAT_ROAD << AIError::ERR_CAT_BIT_SIZE,
 

	
 
		/** Road works are in progress */
 
		ERR_ROAD_WORKS_IN_PROGRESS,                   // [STR_ROAD_WORKS_IN_PROGRESS]
 

	
 
		/** Drive through is in the wrong direction */
 
		ERR_ROAD_DRIVE_THROUGH_WRONG_DIRECTION,       // [STR_DRIVE_THROUGH_ERROR_DIRECTION]
 

	
 
		/** Drive through roads can't be build on town owned roads */
 
		ERR_ROAD_CANNOT_BUILD_ON_TOWN_ROAD,           // [STR_DRIVE_THROUGH_ERROR_ON_TOWN_ROAD]
 

	
 

	
 
		/** One way roads can't have junctions */
 
		ERR_ROAD_ONE_WAY_ROADS_CANNOT_HAVE_JUNCTIONS, // [STR_ERR_ONEWAY_ROADS_CAN_T_HAVE_JUNCTION]
 
	};
 

	
 
	/**
 
	 * Types of road known to the game.
 
	 */
 
	enum RoadType {
 
		/* Values are important, as they represent the internal state of the game. */
 
		ROADTYPE_ROAD = 0, //!< Build road objects.
 
		ROADTYPE_TRAM = 1, //!< Build tram objects.
 

	
 
		ROADTYPE_INVALID = -1, //!< Invalid RoadType.
 
	};
 

	
 
	/**
 
	 * Checks whether the given tile is actually a tile with road that can be
 
	 *  used to traverse a tile. This excludes road depots and 'normal' road
 
	 *  stations, but includes drive through stations.
 
	 * @param tile The tile to check.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @return True if and only if the tile has road.
 
	 */
 
	static bool IsRoadTile(TileIndex tile);
 

	
 
	/**
 
	 * Checks whether the given tile is actually a tile with a road depot.
 
	 * @param tile The tile to check.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @return True if and only if the tile has a road depot.
 
	 */
 
	static bool IsRoadDepotTile(TileIndex tile);
 

	
 
	/**
 
	 * Checks whether the given tile is actually a tile with a road station.
 
	 * @param tile The tile to check.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @return True if and only if the tile has a road station.
 
	 */
 
	static bool IsRoadStationTile(TileIndex tile);
 

	
 
	/**
 
	 * Checks whether the given tile is actually a tile with a drive through
 
	 *  road station.
 
	 * @param tile The tile to check.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @return True if and only if the tile has a drive through road station.
 
	 */
 
	static bool IsDriveThroughRoadStationTile(TileIndex tile);
 

	
 
	/**
 
	 * Check if a given RoadType is available.
 
	 * @param road_type The RoadType to check for.
 
	 * @return True if this RoadType can be used.
 
	 */
 
	static bool IsRoadTypeAvailable(RoadType road_type);
 

	
 
	/**
 
	 * Get the current RoadType set for all AIRoad functions.
 
	 * @return The RoadType currently set.
 
	 */
 
	static RoadType GetCurrentRoadType();
 

	
 
	/**
 
	 * Set the RoadType for all further AIRoad functions.
 
	 * @param road_type The RoadType to set.
 
	 */
 
	static void SetCurrentRoadType(RoadType road_type);
 

	
 
	/**
 
	 * Check if a given tile has RoadType.
 
	 * @param tile The tile to check.
 
	 * @param road_type The RoadType to check for.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @pre IsRoadTypeAvailable(road_type).
 
	 * @return True if the tile contains a RoadType object.
 
	 */
 
	static bool HasRoadType(TileIndex tile, RoadType road_type);
 

	
 
	/**
 
	 * Checks whether the given tiles are directly connected, i.e. whether
 
	 *  a road vehicle can travel from the center of the first tile to the
 
	  * center of the second tile.
 
	 * @param tile_from The source tile.
 
	 * @param tile_to The destination tile.
 
	 * @pre AIMap::IsValidTile(tile_from).
 
	 * @pre AIMap::IsValidTile(tile_to).
 
	 * @pre 'tile_from' and 'tile_to' are directly neighbouring tiles.
 
	 * @return True if and only if a road vehicle can go from tile_from to tile_to.
 
	 */
 
	static bool AreRoadTilesConnected(TileIndex tile_from, TileIndex tile_to);
 

	
 
	/**
 
	 * Lookup function for building road parts independend on whether the
 
	 *  "building on slopes" setting is enabled or not.
 
	 *  This implementation can be used for abstract reasoning about a tile as
 
	 *  it needs the slope and existing road parts of the tile as information.
 
	 * @param slope The slope of the tile to examine.
 
	 * @param existing An array with the existing neighbours in the same format
 
	 *                 as "start" and "end", e.g. AIMap.GetTileIndex(0, 1).
 
	 *                 As a result of this all values of the existing array
 
	 *                 must be of type integer.
 
	 * @param start The tile from where the 'tile to be considered' will be
 
	 *              entered. This is a relative tile, so valid parameters are:
 
	 *              AIMap.GetTileIndex(0, 1), AIMap.GetTileIndex(0, -1),
 
	 *              AIMap.GetTileIndex(1, 0) and AIMap.GetTileIndex(-1, 0).
 
	 * @param end The tile from where the 'tile to be considered' will be
 
	 *            exited. This is a relative tile, sovalid parameters are:
 
	 *              AIMap.GetTileIndex(0, 1), AIMap.GetTileIndex(0, -1),
 
	 *              AIMap.GetTileIndex(1, 0) and AIMap.GetTileIndex(-1, 0).
 
	 * @pre start != end.
 
	 * @pre slope must be a valid slope, i.e. one specified in AITile::Slope.
 
	 * @note Passing data that would be invalid in-game, e.g. existing containing
 
	 *       road parts that can not be build on a tile with the given slope,
 
	 *       does not necessarily means that -1 is returned, i.e. not all
 
	 *       preconditions written here or assumed by the game are extensively
 
	 *       checked to make sure the data entered is valid.
 
	 * @return 0 when the build parts do not connect, 1 when they do connect once
 
	 *         they are build or 2 when building the first part automatically
 
	 *         builds the second part. -1 means the preconditions are not met.
 
	 */
 
	static int32 CanBuildConnectedRoadParts(AITile::Slope slope, struct Array *existing, TileIndex start, TileIndex end);
 

	
 
	/**
 
	 * Lookup function for building road parts independend on whether the
 
	 *  "building on slopes" setting is enabled or not.
 
	 *  This implementation can be used for reasoning about an existing tile.
 
	 * @param tile The the tile to examine.
 
	 * @param start The tile from where "tile" will be entered.
 
	 * @param end The tile from where "tile" will be exited.
 
	 * @pre start != end.
 
	 * @pre tile != start.
 
	 * @pre tile != end.
 
	 * @pre AIMap.IsValidTile(tile).
 
	 * @pre AIMap.IsValidTile(start).
 
	 * @pre AIMap.IsValidTile(end).
 
	 * @pre AIMap.GetDistanceManhattanToTile(tile, start) == 1.
 
	 * @pre AIMap.GetDistanceManhattanToTile(tile, end) == 1.
 
	 * @return 0 when the build parts do not connect, 1 when they do connect once
 
	 *         they are build or 2 when building the first part automatically
 
	 *         builds the second part. -1 means the preconditions are not met.
 
	 */
 
	static int32 CanBuildConnectedRoadPartsHere(TileIndex tile, TileIndex start, TileIndex end);
 

	
 
	/**
 
	 * Count how many neighbours are road.
 
	 * @param tile The tile to check on.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @return 0 means no neighbour road; max value is 4.
 
	 */
 
	static int32 GetNeighbourRoadCount(TileIndex tile);
 

	
 
	/**
 
	 * Gets the tile in front of a road depot.
 
	 * @param depot The road depot tile.
 
	 * @pre IsRoadDepotTile(depot).
 
	 * @return The tile in front of the depot.
 
	 */
 
	static TileIndex GetRoadDepotFrontTile(TileIndex depot);
 

	
 
	/**
 
	 * Gets the tile in front of a road station.
 
	 * @param station The road station tile.
 
	 * @pre IsRoadStationTile(station).
 
	 * @return The tile in front of the road station.
 
	 */
 
	static TileIndex GetRoadStationFrontTile(TileIndex station);
 

	
 
	/**
 
	 * Gets the tile at the back of a drive through road station.
 
	 *  So, one side of the drive through station is retrieved with
 
	 *  GetTileInFrontOfStation, the other with this function.
 
	 * @param station The road station tile.
 
	 * @pre IsDriveThroughRoadStationTile(station).
 
	 * @return The tile at the back of the drive through road station.
 
	 */
 
	static TileIndex GetDriveThroughBackTile(TileIndex station);
 

	
 
	/**
 
	 * Builds a road from the center of tile start to the center of tile end.
 
	 * @param start The start tile of the road.
 
	 * @param end The end tile of the road.
 
	 * @pre 'start' is not equal to 'end'.
 
	 * @pre AIMap::IsValidTile(start).
 
	 * @pre AIMap::IsValidTile(end).
 
	 * @pre 'start' and 'end' are in a straight line, i.e.
 
	 *  AIMap::GetTileX(start) == AIMap::GetTileX(end) or
 
	 *  AIMap::GetTileY(start) == AIMap::GetTileY(end).
 
	 * @exception AIError::ERR_ALREADY_BUILT
 
	 * @exception AIError::ERR_LAND_SLOPED_WRONG
 
	 * @exception AIError::ERR_AREA_NOT_CLEAR
 
	 * @exception AIRoad::ERR_ROAD_ONE_WAY_ROADS_CANNOT_HAVE_JUNCTIONS
 
	 * @exception AIRoad::ERR_ROAD_WORKS_IN_PROGRESS
 
	 * @exception AIError::ERR_VEHICLE_IN_THE_WAY
 
	 * @return Whether the road has been/can be build or not.
 
	 */
 
	static bool BuildRoad(TileIndex start, TileIndex end);
 

	
 
	/**
 
	 * Builds a one-way road from the center of tile start to the center
 
	 *  of tile end. If the road already exists, it is made one-way road.
 
	 *  If the road already exists and is already one-way in this direction,
 
	 *  the road is made two-way again. If the road already exists but is
 
	 *  one-way in the other direction, it's made a 'no'-way road (it's
 
	 *  forbidden to enter the tile from any direction).
 
	 * @param start The start tile of the road.
 
	 * @param end The end tile of the road.
 
	 * @pre 'start' is not equal to 'end'.
 
	 * @pre AIMap::IsValidTile(start).
 
	 * @pre AIMap::IsValidTile(end).
 
	 * @pre 'start' and 'end' are in a straight line, i.e.
 
	 *  AIMap::GetTileX(start) == AIMap::GetTileX(end) or
 
	 *  AIMap::GetTileY(start) == AIMap::GetTileY(end).
 
	 * @pre GetCurrentRoadType() == ROADTYPE_ROAD.
 
	 * @exception AIError::ERR_ALREADY_BUILT
 
	 * @exception AIError::ERR_LAND_SLOPED_WRONG
 
	 * @exception AIError::ERR_AREA_NOT_CLEAR
 
	 * @exception AIRoad::ERR_ROAD_ONE_WAY_ROADS_CANNOT_HAVE_JUNCTIONS
 
	 * @exception AIRoad::ERR_ROAD_WORKS_IN_PROGRESS
 
	 * @exception AIError::ERR_VEHICLE_IN_THE_WAY
 
	 * @return Whether the road has been/can be build or not.
 
	 */
 
	static bool BuildOneWayRoad(TileIndex start, TileIndex end);
 

	
 
	/**
 
	 * Builds a road from the edge of tile start to the edge of tile end (both
 
	 *  included).
 
	 * @param start The start tile of the road.
 
	 * @param end The end tile of the road.
 
	 * @pre 'start' is not equal to 'end'.
 
	 * @pre AIMap::IsValidTile(start).
 
	 * @pre AIMap::IsValidTile(end).
 
	 * @pre 'start' and 'end' are in a straight line, i.e.
 
	 *  AIMap::GetTileX(start) == AIMap::GetTileX(end) or
 
	 *  AIMap::GetTileY(start) == AIMap::GetTileY(end).
 
	 * @exception AIError::ERR_ALREADY_BUILT
 
	 * @exception AIError::ERR_LAND_SLOPED_WRONG
 
	 * @exception AIError::ERR_AREA_NOT_CLEAR
 
	 * @exception AIRoad::ERR_ROAD_ONE_WAY_ROADS_CANNOT_HAVE_JUNCTIONS
 
	 * @exception AIRoad::ERR_ROAD_WORKS_IN_PROGRESS
 
	 * @exception AIError::ERR_VEHICLE_IN_THE_WAY
 
	 * @return Whether the road has been/can be build or not.
 
	 */
 
	static bool BuildRoadFull(TileIndex start, TileIndex end);
 

	
 
	/**
 
	 * Builds a one-way road from the edge of tile start to the edge of tile end
 
	 *  (both included). If the road already exists, it is made one-way road.
 
	 *  If the road already exists and is already one-way in this direction,
 
	 *  the road is made two-way again. If the road already exists but is
 
	 *  one-way in the other direction, it's made a 'no'-way road (it's
 
	 *  forbidden to enter the tile from any direction).
 
	 * @param start The start tile of the road.
 
	 * @param start The start tile of the road.
 
	 * @param end The end tile of the road.
 
	 * @pre 'start' is not equal to 'end'.
 
	 * @pre AIMap::IsValidTile(start).
 
	 * @pre AIMap::IsValidTile(end).
 
	 * @pre 'start' and 'end' are in a straight line, i.e.
 
	 *  AIMap::GetTileX(start) == AIMap::GetTileX(end) or
 
	 *  AIMap::GetTileY(start) == AIMap::GetTileY(end).
 
	 * @pre GetCurrentRoadType() == ROADTYPE_ROAD.
 
	 * @exception AIError::ERR_ALREADY_BUILT
 
	 * @exception AIError::ERR_LAND_SLOPED_WRONG
 
	 * @exception AIError::ERR_AREA_NOT_CLEAR
 
	 * @exception AIRoad::ERR_ROAD_ONE_WAY_ROADS_CANNOT_HAVE_JUNCTIONS
 
	 * @exception AIRoad::ERR_ROAD_WORKS_IN_PROGRESS
 
	 * @exception AIError::ERR_VEHICLE_IN_THE_WAY
 
	 * @return Whether the road has been/can be build or not.
 
	 */
 
	static bool BuildOneWayRoadFull(TileIndex start, TileIndex end);
 

	
 
	/**
 
	 * Builds a road depot.
 
	 * @param tile Place to build the depot.
 
	 * @param front The tile exactly in front of the depot.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @pre AIMap::IsValidTile(front).
 
	 * @pre 'tile' is not equal to 'front', but in a straight line of it.
 
	 * @exception AIError::ERR_FLAT_LAND_REQUIRED
 
	 * @exception AIError::ERR_AREA_NOT_CLEAR
 
	 * @return Whether the road depot has been/can be build or not.
 
	 */
 
	static bool BuildRoadDepot(TileIndex tile, TileIndex front);
 

	
 
	/**
 
	 * Builds a road bus or truck station.
 
	 * @param tile Place to build the depot.
 
	 * @param front The tile exactly in front of the station.
 
	 *   For drive-through stations either entrance side can be used.
 
	 * @param truck Whether to build a truck (true) or bus (false) station.
 
	 * @param drive_through Whether to make the station drive through or not.
 
	 * @param join_adjacent When building next to an other station, don't create a new station when this flag is true.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @pre AIMap::IsValidTile(front).
 
	 * @pre 'tile' is not equal to 'front', but in a straight line of it.
 
	 * @exception AIError::ERR_OWNED_BY_ANOTHER_COMPANY
 
	 * @exception AIError::ERR_AREA_NOT_CLEAR
 
	 * @exception AIError::ERR_FLAT_LAND_REQUIRED
 
	 * @exception AIRoad::ERR_ROAD_DRIVE_THROUGH_WRONG_DIRECTION
 
	 * @exception AIRoad::ERR_ROAD_CANNOT_BUILD_ON_TOWN_ROAD
 
	 * @exception AIError:ERR_VEHICLE_IN_THE_WAY
 
	 * @exception AIStation::ERR_STATION_TOO_CLOSE_TO_ANOTHER_STATION
 
	 * @exception AIStation::ERR_STATION_TOO_MANY_STATIONS
 
	 * @exception AIStation::ERR_STATION_TOO_MANY_STATIONS_IN_TOWN
 
	 * @return Whether the station has been/can be build or not.
 
	 */
 
	static bool BuildRoadStation(TileIndex tile, TileIndex front, bool truck, bool drive_through, bool join_adjacent);
 

	
 
	/**
 
	 * Removes a road from the center of tile start to the center of tile end.
 
	 * @param start The start tile of the road.
 
	 * @param end The end tile of the road.
 
	 * @pre AIMap::IsValidTile(start).
 
	 * @pre AIMap::IsValidTile(end).
 
	 * @pre 'start' and 'end' are in a straight line, i.e.
 
	 *  AIMap::GetTileX(start) == AIMap::GetTileX(end) or
 
	 *  AIMap::GetTileY(start) == AIMap::GetTileY(end).
 
	 * @exception AIError::ERR_OWNED_BY_ANOTHER_COMPANY
 
	 * @exception AIError::ERR_VEHICLE_IN_THE_WAY
 
	 * @exception AIRoad::ERR_ROAD_WORKS_IN_PROGRESS
 
	 * @return Whether the road has been/can be removed or not.
 
	 */
 
	static bool RemoveRoad(TileIndex start, TileIndex end);
 

	
 
	/**
 
	 * Removes a road from the edge of tile start to the edge of tile end (both
 
	 *  included).
 
	 * @param start The start tile of the road.
 
	 * @param end The end tile of the road.
 
	 * @pre AIMap::IsValidTile(start).
 
	 * @pre AIMap::IsValidTile(end).
 
	 * @pre 'start' and 'end' are in a straight line, i.e.
 
	 *  AIMap::GetTileX(start) == AIMap::GetTileX(end) or
 
	 *  AIMap::GetTileY(start) == AIMap::GetTileY(end).
 
	 * @exception AIError::ERR_OWNED_BY_ANOTHER_COMPANY
 
	 * @exception AIError::ERR_VEHICLE_IN_THE_WAY
 
	 * @exception AIRoad::ERR_ROAD_WORKS_IN_PROGRESS
 
	 * @return Whether the road has been/can be removed or not.
 
	 */
 
	static bool RemoveRoadFull(TileIndex start, TileIndex end);
 

	
 
	/**
 
	 * Removes a road depot.
 
	 * @param tile Place to remove the depot from.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @pre Tile is a road depot.
 
	 * @exception AIError::ERR_OWNED_BY_ANOTHER_COMPANY
 
	 * @exception AIError::ERR_VEHICLE_IN_THE_WAY
 
	 * @return Whether the road depot has been/can be removed or not.
 
	 */
 
	static bool RemoveRoadDepot(TileIndex tile);
 

	
 
	/**
 
	 * Removes a road bus or truck station.
 
	 * @param tile Place to remove the station from.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @pre Tile is a road station.
 
	 * @exception AIError::ERR_OWNED_BY_ANOTHER_COMPANY
 
	 * @exception AIError::ERR_VEHICLE_IN_THE_WAY
 
	 * @return Whether the station has been/can be removed or not.
 
	 */
 
	static bool RemoveRoadStation(TileIndex tile);
 

	
 
private:
 

	
 
	/**
 
	 * Internal function used by Build(OneWay)Road(Full).
 
	 */
 
	static bool _BuildRoadInternal(TileIndex start, TileIndex end, bool one_way, bool full);
 
};
 

	
 
#endif /* AI_ROAD_HPP */
src/ai/api/ai_road.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_road.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow enums to be used as Squirrel parameters */
 
	template <> AIRoad::ErrorMessages GetParam(ForceType<AIRoad::ErrorMessages>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AIRoad::ErrorMessages)tmp; }
 
	template <> int Return<AIRoad::ErrorMessages>(HSQUIRRELVM vm, AIRoad::ErrorMessages res) { sq_pushinteger(vm, (int32)res); return 1; }
 
	template <> AIRoad::RoadType GetParam(ForceType<AIRoad::RoadType>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AIRoad::RoadType)tmp; }
 
	template <> int Return<AIRoad::RoadType>(HSQUIRRELVM vm, AIRoad::RoadType res) { sq_pushinteger(vm, (int32)res); return 1; }
 

	
 
	/* Allow AIRoad to be used as Squirrel parameter */
 
	template <> AIRoad *GetParam(ForceType<AIRoad *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIRoad *)instance; }
 
	template <> AIRoad &GetParam(ForceType<AIRoad &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIRoad *)instance; }
 
	template <> const AIRoad *GetParam(ForceType<const AIRoad *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIRoad *)instance; }
 
	template <> const AIRoad &GetParam(ForceType<const AIRoad &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIRoad *)instance; }
 
	template <> int Return<AIRoad *>(HSQUIRRELVM vm, AIRoad *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIRoad", res, NULL, DefSQDestructorCallback<AIRoad>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIRoad_Register(Squirrel *engine) {
 
	DefSQClass <AIRoad> SQAIRoad("AIRoad");
 
	SQAIRoad.PreRegister(engine);
 
	SQAIRoad.AddConstructor<void (AIRoad::*)(), 1>(engine, "x");
 

	
 
	SQAIRoad.DefSQConst(engine, AIRoad::ERR_ROAD_BASE,                                "ERR_ROAD_BASE");
 
	SQAIRoad.DefSQConst(engine, AIRoad::ERR_ROAD_WORKS_IN_PROGRESS,                   "ERR_ROAD_WORKS_IN_PROGRESS");
 
	SQAIRoad.DefSQConst(engine, AIRoad::ERR_ROAD_DRIVE_THROUGH_WRONG_DIRECTION,       "ERR_ROAD_DRIVE_THROUGH_WRONG_DIRECTION");
 
	SQAIRoad.DefSQConst(engine, AIRoad::ERR_ROAD_CANNOT_BUILD_ON_TOWN_ROAD,           "ERR_ROAD_CANNOT_BUILD_ON_TOWN_ROAD");
 
	SQAIRoad.DefSQConst(engine, AIRoad::ERR_ROAD_ONE_WAY_ROADS_CANNOT_HAVE_JUNCTIONS, "ERR_ROAD_ONE_WAY_ROADS_CANNOT_HAVE_JUNCTIONS");
 
	SQAIRoad.DefSQConst(engine, AIRoad::ROADTYPE_ROAD,                                "ROADTYPE_ROAD");
 
	SQAIRoad.DefSQConst(engine, AIRoad::ROADTYPE_TRAM,                                "ROADTYPE_TRAM");
 
	SQAIRoad.DefSQConst(engine, AIRoad::ROADTYPE_INVALID,                             "ROADTYPE_INVALID");
 

	
 
	AIError::RegisterErrorMap(STR_ROAD_WORKS_IN_PROGRESS,               AIRoad::ERR_ROAD_WORKS_IN_PROGRESS);
 
	AIError::RegisterErrorMap(STR_DRIVE_THROUGH_ERROR_DIRECTION,        AIRoad::ERR_ROAD_DRIVE_THROUGH_WRONG_DIRECTION);
 
	AIError::RegisterErrorMap(STR_DRIVE_THROUGH_ERROR_ON_TOWN_ROAD,     AIRoad::ERR_ROAD_CANNOT_BUILD_ON_TOWN_ROAD);
 
	AIError::RegisterErrorMap(STR_ERR_ONEWAY_ROADS_CAN_T_HAVE_JUNCTION, AIRoad::ERR_ROAD_ONE_WAY_ROADS_CANNOT_HAVE_JUNCTIONS);
 

	
 
	AIError::RegisterErrorMapString(AIRoad::ERR_ROAD_WORKS_IN_PROGRESS,                   "ERR_ROAD_WORKS_IN_PROGRESS");
 
	AIError::RegisterErrorMapString(AIRoad::ERR_ROAD_DRIVE_THROUGH_WRONG_DIRECTION,       "ERR_ROAD_DRIVE_THROUGH_WRONG_DIRECTION");
 
	AIError::RegisterErrorMapString(AIRoad::ERR_ROAD_CANNOT_BUILD_ON_TOWN_ROAD,           "ERR_ROAD_CANNOT_BUILD_ON_TOWN_ROAD");
 
	AIError::RegisterErrorMapString(AIRoad::ERR_ROAD_ONE_WAY_ROADS_CANNOT_HAVE_JUNCTIONS, "ERR_ROAD_ONE_WAY_ROADS_CANNOT_HAVE_JUNCTIONS");
 

	
 
	SQAIRoad.DefSQStaticMethod(engine, &AIRoad::GetClassName,                   "GetClassName",                   1, "x");
 
	SQAIRoad.DefSQStaticMethod(engine, &AIRoad::IsRoadTile,                     "IsRoadTile",                     2, "xi");
 
	SQAIRoad.DefSQStaticMethod(engine, &AIRoad::IsRoadDepotTile,                "IsRoadDepotTile",                2, "xi");
 
	SQAIRoad.DefSQStaticMethod(engine, &AIRoad::IsRoadStationTile,              "IsRoadStationTile",              2, "xi");
 
	SQAIRoad.DefSQStaticMethod(engine, &AIRoad::IsDriveThroughRoadStationTile,  "IsDriveThroughRoadStationTile",  2, "xi");
 
	SQAIRoad.DefSQStaticMethod(engine, &AIRoad::IsRoadTypeAvailable,            "IsRoadTypeAvailable",            2, "xi");
 
	SQAIRoad.DefSQStaticMethod(engine, &AIRoad::GetCurrentRoadType,             "GetCurrentRoadType",             1, "x");
 
	SQAIRoad.DefSQStaticMethod(engine, &AIRoad::SetCurrentRoadType,             "SetCurrentRoadType",             2, "xi");
 
	SQAIRoad.DefSQStaticMethod(engine, &AIRoad::HasRoadType,                    "HasRoadType",                    3, "xii");
 
	SQAIRoad.DefSQStaticMethod(engine, &AIRoad::AreRoadTilesConnected,          "AreRoadTilesConnected",          3, "xii");
 
	SQAIRoad.DefSQStaticMethod(engine, &AIRoad::CanBuildConnectedRoadParts,     "CanBuildConnectedRoadParts",     5, "xiaii");
 
	SQAIRoad.DefSQStaticMethod(engine, &AIRoad::CanBuildConnectedRoadPartsHere, "CanBuildConnectedRoadPartsHere", 4, "xiii");
 
	SQAIRoad.DefSQStaticMethod(engine, &AIRoad::GetNeighbourRoadCount,          "GetNeighbourRoadCount",          2, "xi");
 
	SQAIRoad.DefSQStaticMethod(engine, &AIRoad::GetRoadDepotFrontTile,          "GetRoadDepotFrontTile",          2, "xi");
 
	SQAIRoad.DefSQStaticMethod(engine, &AIRoad::GetRoadStationFrontTile,        "GetRoadStationFrontTile",        2, "xi");
 
	SQAIRoad.DefSQStaticMethod(engine, &AIRoad::GetDriveThroughBackTile,        "GetDriveThroughBackTile",        2, "xi");
 
	SQAIRoad.DefSQStaticMethod(engine, &AIRoad::BuildRoad,                      "BuildRoad",                      3, "xii");
 
	SQAIRoad.DefSQStaticMethod(engine, &AIRoad::BuildOneWayRoad,                "BuildOneWayRoad",                3, "xii");
 
	SQAIRoad.DefSQStaticMethod(engine, &AIRoad::BuildRoadFull,                  "BuildRoadFull",                  3, "xii");
 
	SQAIRoad.DefSQStaticMethod(engine, &AIRoad::BuildOneWayRoadFull,            "BuildOneWayRoadFull",            3, "xii");
 
	SQAIRoad.DefSQStaticMethod(engine, &AIRoad::BuildRoadDepot,                 "BuildRoadDepot",                 3, "xii");
 
	SQAIRoad.DefSQStaticMethod(engine, &AIRoad::BuildRoadStation,               "BuildRoadStation",               6, "xiibbb");
 
	SQAIRoad.DefSQStaticMethod(engine, &AIRoad::RemoveRoad,                     "RemoveRoad",                     3, "xii");
 
	SQAIRoad.DefSQStaticMethod(engine, &AIRoad::RemoveRoadFull,                 "RemoveRoadFull",                 3, "xii");
 
	SQAIRoad.DefSQStaticMethod(engine, &AIRoad::RemoveRoadDepot,                "RemoveRoadDepot",                2, "xi");
 
	SQAIRoad.DefSQStaticMethod(engine, &AIRoad::RemoveRoadStation,              "RemoveRoadStation",              2, "xi");
 

	
 
	SQAIRoad.PostRegister(engine);
 
}
src/ai/api/ai_sign.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_sign.cpp Implementation of AISign. */
 

	
 
#include "ai_sign.hpp"
 
#include "table/strings.h"
 
#include "../ai_instance.hpp"
 
#include "../../openttd.h"
 
#include "../../command_func.h"
 
#include "../../core/alloc_func.hpp"
 
#include "../../signs_base.h"
 
#include "../../string_func.h"
 
#include "../../strings_func.h"
 
#include "../../tile_map.h"
 
#include "../../company_func.h"
 

	
 
/* static */ SignID AISign::GetMaxSignID()
 
{
 
	return ::GetMaxSignIndex();
 
}
 

	
 
/* static */ bool AISign::IsValidSign(SignID sign_id)
 
{
 
	return ::IsValidSignID(sign_id) && ::GetSign(sign_id)->owner == _current_company;
 
}
 

	
 
/* static */ bool AISign::SetName(SignID sign_id, const char *name)
 
{
 
	EnforcePrecondition(false, IsValidSign(sign_id));
 
	EnforcePrecondition(false, !::StrEmpty(name));
 
	EnforcePreconditionCustomError(false, ::strlen(name) < MAX_LENGTH_SIGN_NAME_BYTES, AIError::ERR_PRECONDITION_STRING_TOO_LONG);
 

	
 
	return AIObject::DoCommand(0, sign_id, 0, CMD_RENAME_SIGN, name);
 
}
 

	
 
/* static */ const char *AISign::GetName(SignID sign_id)
 
{
 
	if (!IsValidSign(sign_id)) return NULL;
 

	
 
	static const int len = 64;
 
	char *sign_name = MallocT<char>(len);
 

	
 
	::SetDParam(0, sign_id);
 
	::GetString(sign_name, STR_SIGN_NAME, &sign_name[len - 1]);
 

	
 
	return sign_name;
 
}
 

	
 
/* static */ TileIndex AISign::GetLocation(SignID sign_id)
 
{
 
	if (!IsValidSign(sign_id)) return INVALID_TILE;
 

	
 
	const Sign *sign = ::GetSign(sign_id);
 
	return ::TileVirtXY(sign->x, sign->y);
 
}
 

	
 
/* static */ bool AISign::RemoveSign(SignID sign_id)
 
{
 
	EnforcePrecondition(false, IsValidSign(sign_id));
 
	return AIObject::DoCommand(0, sign_id, 0, CMD_RENAME_SIGN, "");
 
}
 

	
 
/* static */ SignID AISign::BuildSign(TileIndex location, const char *text)
 
{
 
	EnforcePrecondition(INVALID_SIGN, ::IsValidTile(location));
 
	EnforcePrecondition(INVALID_SIGN, !::StrEmpty(text));
 
	EnforcePreconditionCustomError(false, ::strlen(text) < MAX_LENGTH_SIGN_NAME_BYTES, AIError::ERR_PRECONDITION_STRING_TOO_LONG);
 

	
 
	if (!AIObject::DoCommand(location, 0, 0, CMD_PLACE_SIGN, text, &AIInstance::DoCommandReturnSignID)) return INVALID_SIGN;
 

	
 
	/* In case of test-mode, we return SignID 0 */
 
	return 0;
 
}
src/ai/api/ai_sign.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_sign.hpp Everything to query and build signs. */
 

	
 
#ifndef AI_SIGN_HPP
 
#define AI_SIGN_HPP
 

	
 
#include "ai_object.hpp"
 
#include "ai_error.hpp"
 
#include "ai_company.hpp"
 

	
 
/**
 
 * Class that handles all sign related functions.
 
 */
 
class AISign : public AIObject {
 
public:
 
	static const char *GetClassName() { return "AISign"; }
 

	
 
	/**
 
	 * All sign related error messages.
 
	 */
 
	enum ErrorMessages {
 

	
 
		/** Base for sign building related errors */
 
		ERR_SIGN_BASE = AIError::ERR_CAT_SIGN << AIError::ERR_CAT_BIT_SIZE,
 

	
 
		/** Too many signs have been placed */
 
		ERR_SIGN_TOO_MANY_SIGNS,             // [STR_2808_TOO_MANY_SIGNS]
 
	};
 

	
 
	/**
 
	 * Gets the maximum sign index; there are no valid signs with a higher index.
 
	 * @return The maximum sign index.
 
	 * @post Return value is always non-negative.
 
	 */
 
	static SignID GetMaxSignID();
 

	
 
	/**
 
	 * Checks whether the given sign index is valid.
 
	 * @param sign_id The index to check.
 
	 * @return True if and only if the sign is valid.
 
	 */
 
	static bool IsValidSign(SignID sign_id);
 

	
 
	/**
 
	 * Set the name of a sign.
 
	 * @param sign_id The sign to set the name for.
 
	 * @param name The name for the sign.
 
	 * @pre IsValidSign(sign_id).
 
	 * @pre 'name' must have at least one character.
 
	 * @pre 'name' must have at most 30 characters.
 
	 * @exception AIError::ERR_NAME_IS_NOT_UNIQUE
 
	 * @return True if and only if the name was changed.
 
	 */
 
	static bool SetName(SignID sign_id, const char *name);
 

	
 
	/**
 
	 * Get the name of the sign.
 
	 * @param sign_id The sign to get the name of.
 
	 * @pre IsValidSign(sign_id).
 
	 * @return The name of the sign.
 
	 */
 
	static const char *GetName(SignID sign_id);
 

	
 
	/**
 
	 * Gets the location of the sign.
 
	 * @param sign_id The sign to get the location of.
 
	 * @pre IsValidSign(sign_id).
 
	 * @return The location of the sign.
 
	 */
 
	static TileIndex GetLocation(SignID sign_id);
 

	
 
	/**
 
	 * Builds a sign on the map.
 
	 * @param location The place to build the sign.
 
	 * @param text The text to place on the sign.
 
	 * @pre AIMap::IsValidTile(location).
 
	 * @pre 'text' must have at least one character.
 
	 * @pre 'text' must have at most 30 characters.
 
	 * @exception AISign::ERR_SIGN_TOO_MANY_SIGNS
 
	 * @return The SignID of the build sign (use IsValidSign() to check for validity).
 
	 *   In test-mode it returns 0 if successful, or any other value to indicate
 
	 *   failure.
 
	 */
 
	static SignID BuildSign(TileIndex location, const char *text);
 

	
 
	/**
 
	 * Removes a sign from the map.
 
	 * @param sign_id The sign to remove.
 
	 * @pre IsValidSign(sign_id).
 
	 * @return True if and only if the sign has been removed.
 
	 */
 
	static bool RemoveSign(SignID sign_id);
 
};
 

	
 
#endif /* AI_SIGN_HPP */
src/ai/api/ai_sign.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_sign.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow enums to be used as Squirrel parameters */
 
	template <> AISign::ErrorMessages GetParam(ForceType<AISign::ErrorMessages>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AISign::ErrorMessages)tmp; }
 
	template <> int Return<AISign::ErrorMessages>(HSQUIRRELVM vm, AISign::ErrorMessages res) { sq_pushinteger(vm, (int32)res); return 1; }
 

	
 
	/* Allow AISign to be used as Squirrel parameter */
 
	template <> AISign *GetParam(ForceType<AISign *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AISign *)instance; }
 
	template <> AISign &GetParam(ForceType<AISign &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AISign *)instance; }
 
	template <> const AISign *GetParam(ForceType<const AISign *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AISign *)instance; }
 
	template <> const AISign &GetParam(ForceType<const AISign &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AISign *)instance; }
 
	template <> int Return<AISign *>(HSQUIRRELVM vm, AISign *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AISign", res, NULL, DefSQDestructorCallback<AISign>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAISign_Register(Squirrel *engine) {
 
	DefSQClass <AISign> SQAISign("AISign");
 
	SQAISign.PreRegister(engine);
 
	SQAISign.AddConstructor<void (AISign::*)(), 1>(engine, "x");
 

	
 
	SQAISign.DefSQConst(engine, AISign::ERR_SIGN_BASE,           "ERR_SIGN_BASE");
 
	SQAISign.DefSQConst(engine, AISign::ERR_SIGN_TOO_MANY_SIGNS, "ERR_SIGN_TOO_MANY_SIGNS");
 

	
 
	AIError::RegisterErrorMap(STR_2808_TOO_MANY_SIGNS, AISign::ERR_SIGN_TOO_MANY_SIGNS);
 

	
 
	AIError::RegisterErrorMapString(AISign::ERR_SIGN_TOO_MANY_SIGNS, "ERR_SIGN_TOO_MANY_SIGNS");
 

	
 
	SQAISign.DefSQStaticMethod(engine, &AISign::GetClassName, "GetClassName", 1, "x");
 
	SQAISign.DefSQStaticMethod(engine, &AISign::GetMaxSignID, "GetMaxSignID", 1, "x");
 
	SQAISign.DefSQStaticMethod(engine, &AISign::IsValidSign,  "IsValidSign",  2, "xi");
 
	SQAISign.DefSQStaticMethod(engine, &AISign::SetName,      "SetName",      3, "xis");
 
	SQAISign.DefSQStaticMethod(engine, &AISign::GetName,      "GetName",      2, "xi");
 
	SQAISign.DefSQStaticMethod(engine, &AISign::GetLocation,  "GetLocation",  2, "xi");
 
	SQAISign.DefSQStaticMethod(engine, &AISign::BuildSign,    "BuildSign",    3, "xis");
 
	SQAISign.DefSQStaticMethod(engine, &AISign::RemoveSign,   "RemoveSign",   2, "xi");
 

	
 
	SQAISign.PostRegister(engine);
 
}
src/ai/api/ai_station.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_station.cpp Implementation of AIStation. */
 

	
 
#include "ai_station.hpp"
 
#include "ai_cargo.hpp"
 
#include "ai_map.hpp"
 
#include "ai_town.hpp"
 
#include "../../openttd.h"
 
#include "../../command_func.h"
 
#include "../../debug.h"
 
#include "../../station_map.h"
 
#include "../../variables.h"
 
#include "../../string_func.h"
 
#include "../../strings_func.h"
 
#include "../../core/alloc_func.hpp"
 
#include "../../company_func.h"
 
#include "../../settings_type.h"
 
#include "../../town.h"
 
#include "table/strings.h"
 

	
 
/* static */ bool AIStation::IsValidStation(StationID station_id)
 
{
 
	return ::IsValidStationID(station_id) && ::GetStation(station_id)->owner == _current_company;
 
}
 

	
 
/* static */ StationID AIStation::GetStationID(TileIndex tile)
 
{
 
	if (!::IsTileType(tile, MP_STATION)) return INVALID_STATION;
 
	return ::GetStationIndex(tile);
 
}
 

	
 
/* static */ const char *AIStation::GetName(StationID station_id)
 
{
 
	if (!IsValidStation(station_id)) return NULL;
 

	
 
	static const int len = 64;
 
	char *station_name = MallocT<char>(len);
 

	
 
	::SetDParam(0, GetStation(station_id)->index);
 
	::GetString(station_name, STR_STATION, &station_name[len - 1]);
 
	return station_name;
 
}
 

	
 
/* static */ bool AIStation::SetName(StationID station_id, const char *name)
 
{
 
	EnforcePrecondition(false, IsValidStation(station_id));
 
	EnforcePrecondition(false, !::StrEmpty(name));
 
	EnforcePreconditionCustomError(false, ::strlen(name) < MAX_LENGTH_STATION_NAME_BYTES, AIError::ERR_PRECONDITION_STRING_TOO_LONG);
 

	
 
	return AIObject::DoCommand(0, station_id, 0, CMD_RENAME_STATION, name);
 
}
 

	
 
/* static */ TileIndex AIStation::GetLocation(StationID station_id)
 
{
 
	if (!IsValidStation(station_id)) return INVALID_TILE;
 

	
 
	return ::GetStation(station_id)->xy;
 
}
 

	
 
/* static */ int32 AIStation::GetCargoWaiting(StationID station_id, CargoID cargo_id)
 
{
 
	if (!IsValidStation(station_id)) return -1;
 
	if (!AICargo::IsValidCargo(cargo_id)) return -1;
 

	
 
	return ::GetStation(station_id)->goods[cargo_id].cargo.Count();
 
}
 

	
 
/* static */ int32 AIStation::GetCargoRating(StationID station_id, CargoID cargo_id)
 
{
 
	if (!IsValidStation(station_id)) return -1;
 
	if (!AICargo::IsValidCargo(cargo_id)) return -1;
 

	
 
	return ::GetStation(station_id)->goods[cargo_id].rating * 101 >> 8;
 
}
 

	
 
/* static */ int32 AIStation::GetCoverageRadius(AIStation::StationType station_type)
 
{
 
	if (station_type == STATION_AIRPORT) {
 
		DEBUG(ai, 0, "GetCoverageRadius(): coverage radius of airports needs to be requested via AIAirport::GetAirportCoverageRadius(), as it requires AirportType");
 
		return -1;
 
	}
 
	if (CountBits(station_type) != 1) return -1;
 
	if (!_settings_game.station.modified_catchment) return CA_UNMODIFIED;
 

	
 
	switch (station_type) {
 
		case STATION_TRAIN:      return CA_TRAIN;
 
		case STATION_TRUCK_STOP: return CA_TRUCK;
 
		case STATION_BUS_STOP:   return CA_BUS;
 
		case STATION_DOCK:       return CA_DOCK;
 
		default:                 return CA_NONE;
 
	}
 
}
 

	
 
/* static */ int32 AIStation::GetDistanceManhattanToTile(StationID station_id, TileIndex tile)
 
{
 
	if (!IsValidStation(station_id)) return -1;
 

	
 
	return AIMap::DistanceManhattan(tile, GetLocation(station_id));
 
}
 

	
 
/* static */ int32 AIStation::GetDistanceSquareToTile(StationID station_id, TileIndex tile)
 
{
 
	if (!IsValidStation(station_id)) return -1;
 

	
 
	return AIMap::DistanceSquare(tile, GetLocation(station_id));
 
}
 

	
 
/* static */ bool AIStation::IsWithinTownInfluence(StationID station_id, TownID town_id)
 
{
 
	if (!IsValidStation(station_id)) return false;
 

	
 
	return AITown::IsWithinTownInfluence(town_id, GetLocation(station_id));
 
}
 

	
 
/* static */ bool AIStation::HasStationType(StationID station_id, StationType station_type)
 
{
 
	if (!IsValidStation(station_id)) return false;
 
	if (CountBits(station_type) != 1) return false;
 

	
 
	return (::GetStation(station_id)->facilities & station_type) != 0;
 
}
 

	
 
/* static */ bool AIStation::HasRoadType(StationID station_id, AIRoad::RoadType road_type)
 
{
 
	if (!IsValidStation(station_id)) return false;
 
	if (!AIRoad::IsRoadTypeAvailable(road_type)) return false;
 

	
 
	::RoadTypes r = RoadTypeToRoadTypes((::RoadType)road_type);
 

	
 
	for (const RoadStop *rs = ::GetStation(station_id)->GetPrimaryRoadStop(ROADSTOP_BUS); rs != NULL; rs = rs->next) {
 
		if ((::GetRoadTypes(rs->xy) & r) != 0) return true;
 
	}
 
	for (const RoadStop *rs = ::GetStation(station_id)->GetPrimaryRoadStop(ROADSTOP_TRUCK); rs != NULL; rs = rs->next) {
 
		if ((::GetRoadTypes(rs->xy) & r) != 0) return true;
 
	}
 

	
 
	return false;
 
}
 

	
 
/* static */ TownID AIStation::GetNearestTown(StationID station_id)
 
{
 
	if (!IsValidStation(station_id)) return INVALID_TOWN;
 

	
 
	return ::GetStation(station_id)->town->index;
 
}
src/ai/api/ai_station.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_station.hpp Everything to query and build stations. */
 

	
 
#ifndef AI_STATION_HPP
 
#define AI_STATION_HPP
 

	
 
#include "ai_object.hpp"
 
#include "ai_error.hpp"
 
#include "ai_road.hpp"
 

	
 
/**
 
 * Class that handles all station related functions.
 
 */
 
class AIStation : public AIObject {
 
public:
 
	static const char *GetClassName() { return "AIStation"; }
 

	
 
	/**
 
	 * All station related error messages.
 
	 */
 
	enum ErrorMessages {
 
		/** Base for station related errors */
 
		ERR_STATION_BASE = AIError::ERR_CAT_STATION << AIError::ERR_CAT_BIT_SIZE,
 

	
 
		/** The station size exceeds the station spread */
 
		ERR_STATION_TOO_LARGE,                    // [STR_306C_STATION_TOO_SPREAD_OUT]
 

	
 
		/** The station is build too close to another station, airport or dock */
 
		ERR_STATION_TOO_CLOSE_TO_ANOTHER_STATION, // [STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT, STR_3009_TOO_CLOSE_TO_ANOTHER_STATION, STR_304C_TOO_CLOSE_TO_ANOTHER_DOCK]
 

	
 
		/** There are too many stations, airports and docks in the game */
 
		ERR_STATION_TOO_MANY_STATIONS,            // [STR_3008_TOO_MANY_STATIONS_LOADING, STR_TOO_MANY_TRUCK_STOPS, STR_TOO_MANY_BUS_STOPS]
 

	
 
		/** There are too many stations, airports of docks in a town */
 
		ERR_STATION_TOO_MANY_STATIONS_IN_TOWN,    // [STR_3007_TOO_MANY_STATIONS_LOADING]
 
	};
 

	
 
	/**
 
	 * Type of stations known in the game.
 
	 */
 
	enum StationType {
 
		/* Values are important, as they represent the internal state of the game. */
 
		STATION_TRAIN      = 0x01, //!< Train station
 
		STATION_TRUCK_STOP = 0x02, //!< Truck station
 
		STATION_BUS_STOP   = 0x04, //!< Bus station
 
		STATION_AIRPORT    = 0x08, //!< Airport
 
		STATION_DOCK       = 0x10, //!< Dock
 
		STATION_ANY        = 0x1F, //!< All station types
 
	};
 

	
 
	/**
 
	 * Checks whether the given station is valid and owned by you.
 
	 * @param station_id The station to check.
 
	 * @return True if and only if the station is valid.
 
	 */
 
	static bool IsValidStation(StationID station_id);
 

	
 
	/**
 
	 * Get the StationID of a tile, if there is a station.
 
	 * @param tile The tile to find the stationID of
 
	 * @return StationID of the station.
 
	 * @post Use IsValidStation() to see if the station is valid.
 
	 */
 
	static StationID GetStationID(TileIndex tile);
 

	
 
	/**
 
	 * Get the name of a station.
 
	 * @param station_id The station to get the name of.
 
	 * @pre IsValidStation(station_id).
 
	 * @return The name of the station.
 
	 */
 
	static const char *GetName(StationID station_id);
 

	
 
	/**
 
	 * Set the name this station.
 
	 * @param station_id The station to set the name of.
 
	 * @param name The new name of the station.
 
	 * @pre IsValidStation(station_id).
 
	 * @pre 'name' must have at least one character.
 
	 * @pre 'name' must have at most 30 characters.
 
	 * @exception AIError::ERR_NAME_IS_NOT_UNIQUE
 
	 * @return True if the name was changed.
 
	 */
 
	static bool SetName(StationID station_id, const char *name);
 

	
 
	/**
 
	 * Get the current location of a station.
 
	 * @param station_id The station to get the location of.
 
	 * @pre IsValidStation(station_id).
 
	 * @return The tile the station is currently on.
 
	 */
 
	static TileIndex GetLocation(StationID station_id);
 

	
 
	/**
 
	 * See how much cargo there is waiting on a station.
 
	 * @param station_id The station to get the cargo-waiting of.
 
	 * @param cargo_id The cargo to get the cargo-waiting of.
 
	 * @pre IsValidStation(station_id).
 
	 * @pre IsValidCargo(cargo_id).
 
	 * @return The amount of units waiting at the station.
 
	 */
 
	static int32 GetCargoWaiting(StationID station_id, CargoID cargo_id);
 

	
 
	/**
 
	 * See how high the rating is of a cargo on a station.
 
	 * @param station_id The station to get the cargo-rating of.
 
	 * @param cargo_id The cargo to get the cargo-rating of.
 
	 * @pre IsValidStation(station_id).
 
	 * @pre IsValidCargo(cargo_id).
 
	 * @return The rating in percent of the cargo on the station.
 
	 */
 
	static int32 GetCargoRating(StationID station_id, CargoID cargo_id);
 

	
 
	/**
 
	 * Get the coverage radius of this type of station.
 
	 * @param station_type The type of station.
 
	 * @return The radius in tiles.
 
	 */
 
	static int32 GetCoverageRadius(AIStation::StationType station_type);
 

	
 
	/**
 
	 * Get the manhattan distance from the tile to the AIStation::GetLocation()
 
	 *  of the station.
 
	 * @param station_id The station to get the distance to.
 
	 * @param tile The tile to get the distance to.
 
	 * @pre IsValidStation(station_id).
 
	 * @return The distance between station and tile.
 
	 */
 
	static int32 GetDistanceManhattanToTile(StationID station_id, TileIndex tile);
 

	
 
	/**
 
	 * Get the square distance from the tile to the AIStation::GetLocation()
 
	 *  of the station.
 
	 * @param station_id The station to get the distance to.
 
	 * @param tile The tile to get the distance to.
 
	 * @pre IsValidStation(station_id).
 
	 * @return The distance between station and tile.
 
	 */
 
	static int32 GetDistanceSquareToTile(StationID station_id, TileIndex tile);
 

	
 
	/**
 
	 * Find out if this station is within the rating influence of a town.
 
	 *  Stations within the radius influence the rating of the town.
 
	 * @param station_id The station to check.
 
	 * @param town_id The town to check.
 
	 * @return True if the tile is within the rating influence of the town.
 
	 */
 
	static bool IsWithinTownInfluence(StationID station_id, TownID town_id);
 

	
 
	/**
 
	 * Check if any part of the station contains a station of the type
 
	 *  StationType
 
	 * @param station_id The station to look at.
 
	 * @param station_type The StationType to look for.
 
	 * @return True if the station has a station part of the type StationType.
 
	 */
 
	static bool HasStationType(StationID station_id, StationType station_type);
 

	
 
	/**
 
	 * Check if any part of the station contains a station of the type
 
	 *  RoadType.
 
	 * @param station_id The station to look at.
 
	 * @param road_type The RoadType to look for.
 
	 * @return True if the station has a station part of the type RoadType.
 
	 */
 
	static bool HasRoadType(StationID station_id, AIRoad::RoadType road_type);
 

	
 
	/**
 
	 * Get the town that was nearest to the given station when the station was built.
 
	 * @param station_id The station to look at.
 
	 * @return The TownID of the town whose center tile was closest to the station
 
	 *  at the time the station was built.
 
	 * @note There is no guarantee that the station is even near the returned town
 
	 *  nor that the returns town is closest to the station now. A station that was
 
	 *  'walked' to the other end of the map will still return the same town. Also,
 
	 *  towns grow, towns change. So don't depend on this value too much.
 
	 */
 
	static TownID GetNearestTown(StationID station_id);
 
};
 

	
 
DECLARE_ENUM_AS_BIT_SET(AIStation::StationType);
 

	
 
#endif /* AI_STATION_HPP */
src/ai/api/ai_station.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_station.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow enums to be used as Squirrel parameters */
 
	template <> AIStation::ErrorMessages GetParam(ForceType<AIStation::ErrorMessages>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AIStation::ErrorMessages)tmp; }
 
	template <> int Return<AIStation::ErrorMessages>(HSQUIRRELVM vm, AIStation::ErrorMessages res) { sq_pushinteger(vm, (int32)res); return 1; }
 
	template <> AIStation::StationType GetParam(ForceType<AIStation::StationType>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AIStation::StationType)tmp; }
 
	template <> int Return<AIStation::StationType>(HSQUIRRELVM vm, AIStation::StationType res) { sq_pushinteger(vm, (int32)res); return 1; }
 

	
 
	/* Allow AIStation to be used as Squirrel parameter */
 
	template <> AIStation *GetParam(ForceType<AIStation *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIStation *)instance; }
 
	template <> AIStation &GetParam(ForceType<AIStation &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIStation *)instance; }
 
	template <> const AIStation *GetParam(ForceType<const AIStation *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIStation *)instance; }
 
	template <> const AIStation &GetParam(ForceType<const AIStation &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIStation *)instance; }
 
	template <> int Return<AIStation *>(HSQUIRRELVM vm, AIStation *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIStation", res, NULL, DefSQDestructorCallback<AIStation>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIStation_Register(Squirrel *engine) {
 
	DefSQClass <AIStation> SQAIStation("AIStation");
 
	SQAIStation.PreRegister(engine);
 
	SQAIStation.AddConstructor<void (AIStation::*)(), 1>(engine, "x");
 

	
 
	SQAIStation.DefSQConst(engine, AIStation::ERR_STATION_BASE,                         "ERR_STATION_BASE");
 
	SQAIStation.DefSQConst(engine, AIStation::ERR_STATION_TOO_LARGE,                    "ERR_STATION_TOO_LARGE");
 
	SQAIStation.DefSQConst(engine, AIStation::ERR_STATION_TOO_CLOSE_TO_ANOTHER_STATION, "ERR_STATION_TOO_CLOSE_TO_ANOTHER_STATION");
 
	SQAIStation.DefSQConst(engine, AIStation::ERR_STATION_TOO_MANY_STATIONS,            "ERR_STATION_TOO_MANY_STATIONS");
 
	SQAIStation.DefSQConst(engine, AIStation::ERR_STATION_TOO_MANY_STATIONS_IN_TOWN,    "ERR_STATION_TOO_MANY_STATIONS_IN_TOWN");
 
	SQAIStation.DefSQConst(engine, AIStation::STATION_TRAIN,                            "STATION_TRAIN");
 
	SQAIStation.DefSQConst(engine, AIStation::STATION_TRUCK_STOP,                       "STATION_TRUCK_STOP");
 
	SQAIStation.DefSQConst(engine, AIStation::STATION_BUS_STOP,                         "STATION_BUS_STOP");
 
	SQAIStation.DefSQConst(engine, AIStation::STATION_AIRPORT,                          "STATION_AIRPORT");
 
	SQAIStation.DefSQConst(engine, AIStation::STATION_DOCK,                             "STATION_DOCK");
 
	SQAIStation.DefSQConst(engine, AIStation::STATION_ANY,                              "STATION_ANY");
 

	
 
	AIError::RegisterErrorMap(STR_306C_STATION_TOO_SPREAD_OUT,       AIStation::ERR_STATION_TOO_LARGE);
 
	AIError::RegisterErrorMap(STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT, AIStation::ERR_STATION_TOO_CLOSE_TO_ANOTHER_STATION);
 
	AIError::RegisterErrorMap(STR_3009_TOO_CLOSE_TO_ANOTHER_STATION, AIStation::ERR_STATION_TOO_CLOSE_TO_ANOTHER_STATION);
 
	AIError::RegisterErrorMap(STR_304C_TOO_CLOSE_TO_ANOTHER_DOCK,    AIStation::ERR_STATION_TOO_CLOSE_TO_ANOTHER_STATION);
 
	AIError::RegisterErrorMap(STR_3008_TOO_MANY_STATIONS_LOADING,    AIStation::ERR_STATION_TOO_MANY_STATIONS);
 
	AIError::RegisterErrorMap(STR_TOO_MANY_TRUCK_STOPS,              AIStation::ERR_STATION_TOO_MANY_STATIONS);
 
	AIError::RegisterErrorMap(STR_TOO_MANY_BUS_STOPS,                AIStation::ERR_STATION_TOO_MANY_STATIONS);
 
	AIError::RegisterErrorMap(STR_3007_TOO_MANY_STATIONS_LOADING,    AIStation::ERR_STATION_TOO_MANY_STATIONS_IN_TOWN);
 

	
 
	AIError::RegisterErrorMapString(AIStation::ERR_STATION_TOO_LARGE,                    "ERR_STATION_TOO_LARGE");
 
	AIError::RegisterErrorMapString(AIStation::ERR_STATION_TOO_CLOSE_TO_ANOTHER_STATION, "ERR_STATION_TOO_CLOSE_TO_ANOTHER_STATION");
 
	AIError::RegisterErrorMapString(AIStation::ERR_STATION_TOO_MANY_STATIONS,            "ERR_STATION_TOO_MANY_STATIONS");
 
	AIError::RegisterErrorMapString(AIStation::ERR_STATION_TOO_MANY_STATIONS_IN_TOWN,    "ERR_STATION_TOO_MANY_STATIONS_IN_TOWN");
 

	
 
	SQAIStation.DefSQStaticMethod(engine, &AIStation::GetClassName,               "GetClassName",               1, "x");
 
	SQAIStation.DefSQStaticMethod(engine, &AIStation::IsValidStation,             "IsValidStation",             2, "xi");
 
	SQAIStation.DefSQStaticMethod(engine, &AIStation::GetStationID,               "GetStationID",               2, "xi");
 
	SQAIStation.DefSQStaticMethod(engine, &AIStation::GetName,                    "GetName",                    2, "xi");
 
	SQAIStation.DefSQStaticMethod(engine, &AIStation::SetName,                    "SetName",                    3, "xis");
 
	SQAIStation.DefSQStaticMethod(engine, &AIStation::GetLocation,                "GetLocation",                2, "xi");
 
	SQAIStation.DefSQStaticMethod(engine, &AIStation::GetCargoWaiting,            "GetCargoWaiting",            3, "xii");
 
	SQAIStation.DefSQStaticMethod(engine, &AIStation::GetCargoRating,             "GetCargoRating",             3, "xii");
 
	SQAIStation.DefSQStaticMethod(engine, &AIStation::GetCoverageRadius,          "GetCoverageRadius",          2, "xi");
 
	SQAIStation.DefSQStaticMethod(engine, &AIStation::GetDistanceManhattanToTile, "GetDistanceManhattanToTile", 3, "xii");
 
	SQAIStation.DefSQStaticMethod(engine, &AIStation::GetDistanceSquareToTile,    "GetDistanceSquareToTile",    3, "xii");
 
	SQAIStation.DefSQStaticMethod(engine, &AIStation::IsWithinTownInfluence,      "IsWithinTownInfluence",      3, "xii");
 
	SQAIStation.DefSQStaticMethod(engine, &AIStation::HasStationType,             "HasStationType",             3, "xii");
 
	SQAIStation.DefSQStaticMethod(engine, &AIStation::HasRoadType,                "HasRoadType",                3, "xii");
 
	SQAIStation.DefSQStaticMethod(engine, &AIStation::GetNearestTown,             "GetNearestTown",             2, "xi");
 

	
 
	SQAIStation.PostRegister(engine);
 
}
src/ai/api/ai_stationlist.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_stationlist.cpp Implementation of AIStationList and friends. */
 

	
 
#include "ai_stationlist.hpp"
 
#include "ai_vehicle.hpp"
 
#include "../../openttd.h"
 
#include "../../company_func.h"
 
#include "../../station_base.h"
 
#include "../../vehicle_base.h"
 

	
 
AIStationList::AIStationList(AIStation::StationType station_type)
 
{
 
	Station *st;
 
	FOR_ALL_STATIONS(st) {
 
		if (st->owner == _current_company && (st->facilities & station_type) != 0) this->AddItem(st->index);
 
	}
 
}
 

	
 
AIStationList_Vehicle::AIStationList_Vehicle(VehicleID vehicle_id)
 
{
 
	if (!AIVehicle::IsValidVehicle(vehicle_id)) return;
 

	
 
	Vehicle *v = ::GetVehicle(vehicle_id);
 

	
 
	for (Order *o = v->GetFirstOrder(); o != NULL; o = o->next) {
 
		if (o->IsType(OT_GOTO_STATION)) this->AddItem(o->GetDestination());
 
	}
 
}
src/ai/api/ai_stationlist.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_stationlist.hpp List all the stations (you own). */
 

	
 
#ifndef AI_STATIONLIST_HPP
 
#define AI_STATIONLIST_HPP
 

	
 
#include "ai_abstractlist.hpp"
 
#include "ai_station.hpp"
 

	
 
/**
 
 * Creates a list of stations of which you are the owner.
 
 * @ingroup AIList
 
 */
 
class AIStationList : public AIAbstractList {
 
public:
 
	static const char *GetClassName() { return "AIStationList"; }
 

	
 
	/**
 
	 * @param station_type The type of station to make a list of stations for.
 
	 */
 
	AIStationList(AIStation::StationType station_type);
 
};
 

	
 
/**
 
 * Creates a list of stations which the vehicle has in its orders.
 
 * @ingroup AIList
 
 */
 
class AIStationList_Vehicle : public AIAbstractList {
 
public:
 
	static const char *GetClassName() { return "AIStationList_Vehicle"; }
 

	
 
	/**
 
	 * @param vehicle_id The vehicle to get the list of stations he has in its orders from.
 
	 */
 
	AIStationList_Vehicle(VehicleID vehicle_id);
 
};
 

	
 
#endif /* AI_STATIONLIST_HPP */
src/ai/api/ai_stationlist.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_stationlist.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow AIStationList to be used as Squirrel parameter */
 
	template <> AIStationList *GetParam(ForceType<AIStationList *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIStationList *)instance; }
 
	template <> AIStationList &GetParam(ForceType<AIStationList &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIStationList *)instance; }
 
	template <> const AIStationList *GetParam(ForceType<const AIStationList *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIStationList *)instance; }
 
	template <> const AIStationList &GetParam(ForceType<const AIStationList &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIStationList *)instance; }
 
	template <> int Return<AIStationList *>(HSQUIRRELVM vm, AIStationList *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIStationList", res, NULL, DefSQDestructorCallback<AIStationList>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIStationList_Register(Squirrel *engine) {
 
	DefSQClass <AIStationList> SQAIStationList("AIStationList");
 
	SQAIStationList.PreRegister(engine, "AIAbstractList");
 
	SQAIStationList.AddConstructor<void (AIStationList::*)(AIStation::StationType station_type), 2>(engine, "xi");
 

	
 
	SQAIStationList.DefSQStaticMethod(engine, &AIStationList::GetClassName, "GetClassName", 1, "x");
 

	
 
	SQAIStationList.PostRegister(engine);
 
}
 

	
 
namespace SQConvert {
 
	/* Allow AIStationList_Vehicle to be used as Squirrel parameter */
 
	template <> AIStationList_Vehicle *GetParam(ForceType<AIStationList_Vehicle *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIStationList_Vehicle *)instance; }
 
	template <> AIStationList_Vehicle &GetParam(ForceType<AIStationList_Vehicle &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIStationList_Vehicle *)instance; }
 
	template <> const AIStationList_Vehicle *GetParam(ForceType<const AIStationList_Vehicle *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIStationList_Vehicle *)instance; }
 
	template <> const AIStationList_Vehicle &GetParam(ForceType<const AIStationList_Vehicle &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIStationList_Vehicle *)instance; }
 
	template <> int Return<AIStationList_Vehicle *>(HSQUIRRELVM vm, AIStationList_Vehicle *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIStationList_Vehicle", res, NULL, DefSQDestructorCallback<AIStationList_Vehicle>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIStationList_Vehicle_Register(Squirrel *engine) {
 
	DefSQClass <AIStationList_Vehicle> SQAIStationList_Vehicle("AIStationList_Vehicle");
 
	SQAIStationList_Vehicle.PreRegister(engine, "AIAbstractList");
 
	SQAIStationList_Vehicle.AddConstructor<void (AIStationList_Vehicle::*)(VehicleID vehicle_id), 2>(engine, "xi");
 

	
 
	SQAIStationList_Vehicle.DefSQStaticMethod(engine, &AIStationList_Vehicle::GetClassName, "GetClassName", 1, "x");
 

	
 
	SQAIStationList_Vehicle.PostRegister(engine);
 
}
src/ai/api/ai_subsidy.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_subsidy.cpp Implementation of AISubsidy. */
 

	
 
#include "ai_subsidy.hpp"
 
#include "ai_error.hpp"
 
#include "ai_company.hpp"
 
#include "ai_date.hpp"
 
#include "../../openttd.h"
 
#include "../../economy_func.h"
 
#include "../../station_base.h"
 
#include "../../cargotype.h"
 

	
 
/* static */ bool AISubsidy::IsValidSubsidy(SubsidyID subsidy_id)
 
{
 
	return subsidy_id < lengthof(_subsidies) && _subsidies[subsidy_id].cargo_type != CT_INVALID;
 
}
 

	
 
/* static */ bool AISubsidy::IsAwarded(SubsidyID subsidy_id)
 
{
 
	if (!IsValidSubsidy(subsidy_id)) return false;
 

	
 
	return _subsidies[subsidy_id].age >= 12;
 
}
 

	
 
/* static */ AICompany::CompanyID AISubsidy::GetAwardedTo(SubsidyID subsidy_id)
 
{
 
	if (!IsAwarded(subsidy_id)) return AICompany::INVALID_COMPANY;
 

	
 
	return (AICompany::CompanyID)((byte)GetStation(_subsidies[subsidy_id].from)->owner);
 
}
 

	
 
/* static */ int32 AISubsidy::GetExpireDate(SubsidyID subsidy_id)
 
{
 
	if (!IsValidSubsidy(subsidy_id)) return -1;
 

	
 
	int year = AIDate::GetYear(AIDate::GetCurrentDate());
 
	int month = AIDate::GetMonth(AIDate::GetCurrentDate());
 

	
 
	if (IsAwarded(subsidy_id)) {
 
		month += 24 - _subsidies[subsidy_id].age;
 
	} else {
 
		month += 12 - _subsidies[subsidy_id].age;
 
	}
 

	
 
	year += (month - 1) / 12;
 
	month = ((month - 1) % 12) + 1;
 

	
 
	return AIDate::GetDate(year, month, 1);
 
}
 

	
 
/* static */ CargoID AISubsidy::GetCargoType(SubsidyID subsidy_id)
 
{
 
	if (!IsValidSubsidy(subsidy_id)) return CT_INVALID;
 

	
 
	return _subsidies[subsidy_id].cargo_type;
 
}
 

	
 
/* static */ bool AISubsidy::SourceIsTown(SubsidyID subsidy_id)
 
{
 
	if (!IsValidSubsidy(subsidy_id) || IsAwarded(subsidy_id)) return false;
 

	
 
	return GetCargo(GetCargoType(subsidy_id))->town_effect == TE_PASSENGERS ||
 
	       GetCargo(GetCargoType(subsidy_id))->town_effect == TE_MAIL;
 
}
 

	
 
/* static */ int32 AISubsidy::GetSource(SubsidyID subsidy_id)
 
{
 
	if (!IsValidSubsidy(subsidy_id)) return INVALID_STATION;
 

	
 
	return _subsidies[subsidy_id].from;
 
}
 

	
 
/* static */ bool AISubsidy::DestinationIsTown(SubsidyID subsidy_id)
 
{
 
	if (!IsValidSubsidy(subsidy_id) || IsAwarded(subsidy_id)) return false;
 

	
 
	switch (GetCargo(GetCargoType(subsidy_id))->town_effect) {
 
		case TE_PASSENGERS:
 
		case TE_MAIL:
 
		case TE_GOODS:
 
		case TE_FOOD:
 
			return true;
 
		default:
 
			return false;
 
	}
 
}
 

	
 
/* static */ int32 AISubsidy::GetDestination(SubsidyID subsidy_id)
 
{
 
	if (!IsValidSubsidy(subsidy_id)) return INVALID_STATION;
 

	
 
	return _subsidies[subsidy_id].to;
 
}
src/ai/api/ai_subsidy.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_subsidy.hpp Everything to query subsidies. */
 

	
 
#ifndef AI_SUBSIDY_HPP
 
#define AI_SUBSIDY_HPP
 

	
 
#include "ai_object.hpp"
 
#include "ai_company.hpp"
 

	
 
/**
 
 * Class that handles all subsidy related functions.
 
 */
 
class AISubsidy : public AIObject {
 
public:
 
	static const char *GetClassName() { return "AISubsidy"; }
 

	
 
	/**
 
	 * Check whether this is a valid SubsidyID.
 
	 * @param subsidy_id The SubsidyID to check.
 
	 * @return True if and only if this subsidy is still valid.
 
	 */
 
	static bool IsValidSubsidy(SubsidyID subsidy_id);
 

	
 
	/**
 
	 * Checks whether this subsidy is already awarded to some company.
 
	 * @param subsidy_id The SubsidyID to check.
 
	 * @pre IsValidSubsidy(subsidy).
 
	 * @return True if and only if this subsidy is already awarded.
 
	 */
 
	static bool IsAwarded(SubsidyID subsidy_id);
 

	
 
	/**
 
	 * Get the company index of the company this subsidy is awarded to.
 
	 * @param subsidy_id The SubsidyID to check.
 
	 * @pre IsAwarded(subsidy_id).
 
	 * @return The companyindex of the company this subsidy is awarded to.
 
	 */
 
	static AICompany::CompanyID GetAwardedTo(SubsidyID subsidy_id);
 

	
 
	/**
 
	 * Get the date this subsidy expires. In case the subsidy is already
 
	 *  awarded, return the date the subsidy expires, else, return the date the
 
	 *  offer expires.
 
	 * @param subsidy_id The SubsidyID to check.
 
	 * @pre IsValidSubsidy(subsidy_id).
 
	 * @return The last valid date of this subsidy.
 
	 * @note The return value of this function will change if the subsidy is
 
	 *  awarded.
 
	 */
 
	static int32 GetExpireDate(SubsidyID subsidy_id);
 

	
 
	/**
 
	 * Get the cargo type that has to be transported in order to be awarded this
 
	 *  subsidy.
 
	 * @param subsidy_id The SubsidyID to check.
 
	 * @pre IsValidSubsidy(subsidy_id).
 
	 * @return The cargo type to transport.
 
	 */
 
	static CargoID GetCargoType(SubsidyID subsidy_id);
 

	
 
	/**
 
	 * Is the source of the subsidy a town or an industry.
 
	 * @param subsidy_id The SubsidyID to check.
 
	 * @pre IsValidSubsidy(subsidy_id) && !IsAwarded(subsidy_id).
 
	 * @return True if the source is a town, false if it is an industry.
 
	 */
 
	static bool SourceIsTown(SubsidyID subsidy_id);
 

	
 
	/**
 
	 * Return the source TownID/IndustryID/StationID the subsidy is for.
 
	 * 1) IsAwarded(subsidy_id) -> return the StationID the subsidy is awarded to.
 
	 * 2) !IsAwarded(subsidy_id) && SourceIsTown(subsidy_id) -> return the TownID.
 
	 * 3) !IsAwarded(subsidy_id) && !SourceIsTown(subsidy_id) -> return the IndustryID.
 
	 * @param subsidy_id The SubsidyID to check.
 
	 * @pre IsValidSubsidy(subsidy_id).
 
	 * @return One of TownID/IndustryID/StationID.
 
	 */
 
	static int32 GetSource(SubsidyID subsidy_id);
 

	
 
	/**
 
	 * Is the destination of the subsidy a town or an industry.
 
	 * @param subsidy_id The SubsidyID to check.
 
	 * @pre IsValidSubsidy(subsidy_id) && !IsAwarded(subsidy_id).
 
	 * @return True if the destination is a town, false if it is an industry.
 
	 */
 
	static bool DestinationIsTown(SubsidyID subsidy_id);
 

	
 
	/**
 
	 * Return the destination TownID/IndustryID/StationID the subsidy is for.
 
	 * 1) IsAwarded(subsidy_id) -> return the StationID the subsidy is awarded to.
 
	 * 2) !IsAwarded(subsidy_id) && SourceIsTown(subsidy_id) -> return the TownID.
 
	 * 3) !IsAwarded(subsidy_id) && !SourceIsTown(subsidy_id) -> return the IndustryID.
 
	 * @param subsidy_id the SubsidyID to check.
 
	 * @pre IsValidSubsidy(subsidy_id).
 
	 * @return One of TownID/IndustryID/StationID.
 
	 */
 
	static int32 GetDestination(SubsidyID subsidy_id);
 
};
 

	
 
#endif /* AI_SUBSIDY_HPP */
src/ai/api/ai_subsidy.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_subsidy.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow AISubsidy to be used as Squirrel parameter */
 
	template <> AISubsidy *GetParam(ForceType<AISubsidy *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AISubsidy *)instance; }
 
	template <> AISubsidy &GetParam(ForceType<AISubsidy &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AISubsidy *)instance; }
 
	template <> const AISubsidy *GetParam(ForceType<const AISubsidy *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AISubsidy *)instance; }
 
	template <> const AISubsidy &GetParam(ForceType<const AISubsidy &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AISubsidy *)instance; }
 
	template <> int Return<AISubsidy *>(HSQUIRRELVM vm, AISubsidy *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AISubsidy", res, NULL, DefSQDestructorCallback<AISubsidy>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAISubsidy_Register(Squirrel *engine) {
 
	DefSQClass <AISubsidy> SQAISubsidy("AISubsidy");
 
	SQAISubsidy.PreRegister(engine);
 
	SQAISubsidy.AddConstructor<void (AISubsidy::*)(), 1>(engine, "x");
 

	
 
	SQAISubsidy.DefSQStaticMethod(engine, &AISubsidy::GetClassName,      "GetClassName",      1, "x");
 
	SQAISubsidy.DefSQStaticMethod(engine, &AISubsidy::IsValidSubsidy,    "IsValidSubsidy",    2, "xi");
 
	SQAISubsidy.DefSQStaticMethod(engine, &AISubsidy::IsAwarded,         "IsAwarded",         2, "xi");
 
	SQAISubsidy.DefSQStaticMethod(engine, &AISubsidy::GetAwardedTo,      "GetAwardedTo",      2, "xi");
 
	SQAISubsidy.DefSQStaticMethod(engine, &AISubsidy::GetExpireDate,     "GetExpireDate",     2, "xi");
 
	SQAISubsidy.DefSQStaticMethod(engine, &AISubsidy::GetCargoType,      "GetCargoType",      2, "xi");
 
	SQAISubsidy.DefSQStaticMethod(engine, &AISubsidy::SourceIsTown,      "SourceIsTown",      2, "xi");
 
	SQAISubsidy.DefSQStaticMethod(engine, &AISubsidy::GetSource,         "GetSource",         2, "xi");
 
	SQAISubsidy.DefSQStaticMethod(engine, &AISubsidy::DestinationIsTown, "DestinationIsTown", 2, "xi");
 
	SQAISubsidy.DefSQStaticMethod(engine, &AISubsidy::GetDestination,    "GetDestination",    2, "xi");
 

	
 
	SQAISubsidy.PostRegister(engine);
 
}
src/ai/api/ai_subsidylist.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_subsidylist.cpp Implementation of AISubsidyList. */
 

	
 
#include "ai_subsidylist.hpp"
 
#include "ai_subsidy.hpp"
 
#include "../../economy_func.h"
 

	
 
AISubsidyList::AISubsidyList()
 
{
 
	for (uint i = 0; i < lengthof(_subsidies); i++) {
 
		if (AISubsidy::IsValidSubsidy(i)) this->AddItem(i);
 
	}
 
}
src/ai/api/ai_subsidylist.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_subsidylist.hpp List all the subsidies. */
 

	
 
#ifndef AI_SUBSIDYLIST_HPP
 
#define AI_SUBSIDYLIST_HPP
 

	
 
#include "ai_abstractlist.hpp"
 

	
 
/**
 
 * Creates a list of all current subsidies.
 
 * @ingroup AIList
 
 */
 
class AISubsidyList : public AIAbstractList {
 
public:
 
	static const char *GetClassName() { return "AISubsidyList"; }
 
	AISubsidyList();
 
};
 

	
 
#endif /* AI_SUBSIDYLIST_HPP */
src/ai/api/ai_subsidylist.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_subsidylist.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow AISubsidyList to be used as Squirrel parameter */
 
	template <> AISubsidyList *GetParam(ForceType<AISubsidyList *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AISubsidyList *)instance; }
 
	template <> AISubsidyList &GetParam(ForceType<AISubsidyList &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AISubsidyList *)instance; }
 
	template <> const AISubsidyList *GetParam(ForceType<const AISubsidyList *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AISubsidyList *)instance; }
 
	template <> const AISubsidyList &GetParam(ForceType<const AISubsidyList &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AISubsidyList *)instance; }
 
	template <> int Return<AISubsidyList *>(HSQUIRRELVM vm, AISubsidyList *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AISubsidyList", res, NULL, DefSQDestructorCallback<AISubsidyList>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAISubsidyList_Register(Squirrel *engine) {
 
	DefSQClass <AISubsidyList> SQAISubsidyList("AISubsidyList");
 
	SQAISubsidyList.PreRegister(engine, "AIAbstractList");
 
	SQAISubsidyList.AddConstructor<void (AISubsidyList::*)(), 1>(engine, "x");
 

	
 
	SQAISubsidyList.DefSQStaticMethod(engine, &AISubsidyList::GetClassName, "GetClassName", 1, "x");
 

	
 
	SQAISubsidyList.PostRegister(engine);
 
}
src/ai/api/ai_testmode.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_testmode.cpp Implementation of AITestMode. */
 

	
 
#include "ai_testmode.hpp"
 
#include "../../command_type.h"
 

	
 
bool AITestMode::ModeProc(TileIndex tile, uint32 p1, uint32 p2, uint procc, CommandCost costs)
 
{
 
	/* In test mode we only return 'false', telling the DoCommand it
 
		*  should stop after testing the command and return with that result. */
 
	return false;
 
}
 

	
 
AITestMode::AITestMode()
 
{
 
	this->last_mode     = this->GetDoCommandMode();
 
	this->last_instance = this->GetDoCommandModeInstance();
 
	this->SetDoCommandMode(&AITestMode::ModeProc, this);
 
}
 

	
 
AITestMode::~AITestMode()
 
{
 
	assert(this->GetDoCommandModeInstance() == this);
 
	this->SetDoCommandMode(this->last_mode, this->last_instance);
 
}
src/ai/api/ai_testmode.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_testmode.hpp Switch the AI to Test Mode. */
 

	
 
#ifndef AI_TESTMODE_HPP
 
#define AI_TESTMODE_HPP
 

	
 
#include "ai_object.hpp"
 

	
 
/**
 
 * Class to switch current mode to Test Mode.
 
 * If you create an instance of this class, the mode will be switched to
 
 *   Testing. The original mode is stored and recovered from when ever the
 
 *   instance is destroyed.
 
 * In Test mode all the commands you execute aren't really executed. The
 
 *   system only checks if it would be able to execute your requests, and what
 
 *   the cost would be.
 
 */
 
class AITestMode : public AIObject {
 
public:
 
	static const char *GetClassName() { return "AITestMode"; }
 

	
 
private:
 
	AIModeProc *last_mode;
 
	AIObject *last_instance;
 

	
 
protected:
 
	/**
 
	 * The callback proc for Testing mode.
 
	 */
 
	static bool ModeProc(TileIndex tile, uint32 p1, uint32 p2, uint procc, CommandCost costs);
 

	
 
public:
 
	/**
 
	 * Creating instance of this class switches the build mode to Testing.
 
	 * @note When the instance is destroyed, he restores the mode that was
 
	 *   current when the instance was created!
 
	 */
 
	AITestMode();
 

	
 
	/**
 
	 * Destroying this instance reset the building mode to the mode it was
 
	 *   in when the instance was created.
 
	 */
 
	~AITestMode();
 
};
 

	
 
#endif /* AI_TESTMODE_HPP */
src/ai/api/ai_testmode.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_testmode.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow AITestMode to be used as Squirrel parameter */
 
	template <> AITestMode *GetParam(ForceType<AITestMode *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AITestMode *)instance; }
 
	template <> AITestMode &GetParam(ForceType<AITestMode &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AITestMode *)instance; }
 
	template <> const AITestMode *GetParam(ForceType<const AITestMode *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AITestMode *)instance; }
 
	template <> const AITestMode &GetParam(ForceType<const AITestMode &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AITestMode *)instance; }
 
	template <> int Return<AITestMode *>(HSQUIRRELVM vm, AITestMode *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AITestMode", res, NULL, DefSQDestructorCallback<AITestMode>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAITestMode_Register(Squirrel *engine) {
 
	DefSQClass <AITestMode> SQAITestMode("AITestMode");
 
	SQAITestMode.PreRegister(engine);
 
	SQAITestMode.AddConstructor<void (AITestMode::*)(), 1>(engine, "x");
 

	
 
	SQAITestMode.DefSQStaticMethod(engine, &AITestMode::GetClassName, "GetClassName", 1, "x");
 

	
 
	SQAITestMode.PostRegister(engine);
 
}
src/ai/api/ai_tile.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_tile.cpp Implementation of AITile. */
 

	
 
#include "ai_tile.hpp"
 
#include "ai_map.hpp"
 
#include "ai_town.hpp"
 
#include "../../openttd.h"
 
#include "../../tile_map.h"
 
#include "../../tile_cmd.h"
 
#include "../../map_func.h"
 
#include "../../variables.h"
 
#include "../../station_func.h"
 
#include "../../command_type.h"
 
#include "../../settings_type.h"
 
#include "../../company_func.h"
 
#include "../../road_map.h"
 
#include "../../water_map.h"
 
#include "../../clear_map.h"
 
#include "../../town.h"
 

	
 
/* static */ bool AITile::IsBuildable(TileIndex tile)
 
{
 
	if (!::IsValidTile(tile)) return false;
 

	
 
	switch (::GetTileType(tile)) {
 
		default: return false;
 
		case MP_CLEAR: return true;
 
		case MP_TREES: return true;
 
		case MP_WATER: return IsCoast(tile);
 
		case MP_ROAD:
 
			/* Tram bits aren't considered buildable */
 
			if (::GetRoadTypes(tile) != ROADTYPES_ROAD) return false;
 
			/* Depots and crossings aren't considered buildable */
 
			if (::GetRoadTileType(tile) != ROAD_TILE_NORMAL) return false;
 
			if (CountBits(::GetRoadBits(tile, ROADTYPE_ROAD)) != 1) return false;
 
			if (::IsRoadOwner(tile, ROADTYPE_ROAD, OWNER_TOWN)) return true;
 
			if (::IsRoadOwner(tile, ROADTYPE_ROAD, _current_company)) return true;
 
			return false;
 
	}
 
}
 

	
 
/* static */ bool AITile::IsBuildableRectangle(TileIndex tile, uint width, uint height)
 
{
 
	uint tx, ty;
 

	
 
	tx = AIMap::GetTileX(tile);
 
	ty = AIMap::GetTileY(tile);
 

	
 
	for (uint x = tx; x < width + tx; x++) {
 
		for (uint y = ty; y < height + ty; y++) {
 
			if (!IsBuildable(AIMap::GetTileIndex(x, y))) return false;
 
		}
 
	}
 

	
 
	return true;
 
}
 

	
 
/* static */ bool AITile::IsWaterTile(TileIndex tile)
 
{
 
	if (!::IsValidTile(tile)) return false;
 

	
 
	return ::IsTileType(tile, MP_WATER) && !::IsCoast(tile);
 
}
 

	
 
/* static */ bool AITile::IsCoastTile(TileIndex tile)
 
{
 
	if (!::IsValidTile(tile)) return false;
 

	
 
	return ::IsTileType(tile, MP_WATER) && ::IsCoast(tile);
 
}
 

	
 
/* static */ bool AITile::IsStationTile(TileIndex tile)
 
{
 
	if (!::IsValidTile(tile)) return false;
 

	
 
	return ::IsTileType(tile, MP_STATION);
 
}
 

	
 
/* static */ bool AITile::IsSteepSlope(Slope slope)
 
{
 
	if (slope == SLOPE_INVALID) return false;
 

	
 
	return ::IsSteepSlope((::Slope)slope);
 
}
 

	
 
/* static */ bool AITile::IsHalftileSlope(Slope slope)
 
{
 
	if (slope == SLOPE_INVALID) return false;
 

	
 
	return ::IsHalftileSlope((::Slope)slope);
 
}
 

	
 
/* static */ bool AITile::HasTreeOnTile(TileIndex tile)
 
{
 
	return ::IsTileType(tile, MP_TREES);
 
}
 

	
 
/* static */ bool AITile::IsFarmTile(TileIndex tile)
 
{
 
	return (::IsTileType(tile, MP_CLEAR) && ::IsClearGround(tile, CLEAR_FIELDS));
 
}
 

	
 
/* static */ bool AITile::IsRockTile(TileIndex tile)
 
{
 
	return (::IsTileType(tile, MP_CLEAR) && ::IsClearGround(tile, CLEAR_ROCKS));
 
}
 

	
 
/* static */ bool AITile::IsRoughTile(TileIndex tile)
 
{
 
	return (::IsTileType(tile, MP_CLEAR) && ::IsClearGround(tile, CLEAR_ROUGH));
 
}
 

	
 
/* static */ bool AITile::IsSnowTile(TileIndex tile)
 
{
 
	return (::IsTileType(tile, MP_CLEAR) && ::IsClearGround(tile, CLEAR_SNOW));
 
}
 

	
 
/* static */ bool AITile::IsDesertTile(TileIndex tile)
 
{
 
	return (::IsTileType(tile, MP_CLEAR) && ::IsClearGround(tile, CLEAR_DESERT));
 
}
 

	
 
/* static */ AITile::Slope AITile::GetSlope(TileIndex tile)
 
{
 
	if (!::IsValidTile(tile)) return SLOPE_INVALID;
 

	
 
	return (Slope)::GetTileSlope(tile, NULL);
 
}
 

	
 
/* static */ AITile::Slope AITile::GetComplementSlope(Slope slope)
 
{
 
	if (slope == SLOPE_INVALID) return SLOPE_INVALID;
 
	if (IsSteepSlope(slope)) return SLOPE_INVALID;
 
	if (IsHalftileSlope(slope)) return SLOPE_INVALID;
 

	
 
	return (Slope)::ComplementSlope((::Slope)slope);
 
}
 

	
 
/* static */ int32 AITile::GetHeight(TileIndex tile)
 
{
 
	if (!::IsValidTile(tile)) return false;
 

	
 
	return ::TileHeight(tile);
 
}
 

	
 
/* static */ AICompany::CompanyID AITile::GetOwner(TileIndex tile)
 
{
 
	if (!::IsValidTile(tile)) return AICompany::INVALID_COMPANY;
 
	if (::IsTileType(tile, MP_HOUSE)) return AICompany::INVALID_COMPANY;
 
	if (::IsTileType(tile, MP_INDUSTRY)) return AICompany::INVALID_COMPANY;
 

	
 
	return AICompany::ResolveCompanyID((AICompany::CompanyID)(byte)::GetTileOwner(tile));
 
}
 

	
 
/* static */ bool AITile::HasTransportType(TileIndex tile, TransportType transport_type)
 
{
 
	if (!::IsValidTile(tile)) return false;
 

	
 
	return GB(::GetTileTrackStatus(tile, (::TransportType)transport_type, UINT32_MAX), 0, 16) != 0;
 
}
 

	
 
/* static */ int32 AITile::GetCargoAcceptance(TileIndex tile, CargoID cargo_type, uint width, uint height, uint radius)
 
{
 
	if (!::IsValidTile(tile)) return false;
 

	
 
	AcceptedCargo accepts;
 
	::GetAcceptanceAroundTiles(accepts, tile, width, height, _settings_game.station.modified_catchment ? radius : (uint)CA_UNMODIFIED);
 
	return accepts[cargo_type];
 
}
 

	
 
/* static */ int32 AITile::GetCargoProduction(TileIndex tile, CargoID cargo_type, uint width, uint height, uint radius)
 
{
 
	if (!::IsValidTile(tile)) return false;
 

	
 
	AcceptedCargo produced;
 
	::GetProductionAroundTiles(produced, tile, width, height, _settings_game.station.modified_catchment ? radius : (uint)CA_UNMODIFIED);
 
	return produced[cargo_type];
 
}
 

	
 
/* static */ int32 AITile::GetDistanceManhattanToTile(TileIndex tile_from, TileIndex tile_to)
 
{
 
	return AIMap::DistanceManhattan(tile_from, tile_to);
 
}
 

	
 
/* static */ int32 AITile::GetDistanceSquareToTile(TileIndex tile_from, TileIndex tile_to)
 
{
 
	return AIMap::DistanceSquare(tile_from, tile_to);
 
}
 

	
 
/* static */ bool AITile::RaiseTile(TileIndex tile, int32 slope)
 
{
 
	EnforcePrecondition(false, ::IsValidTile(tile));
 

	
 
	return AIObject::DoCommand(tile, slope, 1, CMD_TERRAFORM_LAND);
 
}
 

	
 
/* static */ bool AITile::LowerTile(TileIndex tile, int32 slope)
 
{
 
	EnforcePrecondition(false, ::IsValidTile(tile));
 

	
 
	return AIObject::DoCommand(tile, slope, 0, CMD_TERRAFORM_LAND);
 
}
 

	
 
/* static */ bool AITile::DemolishTile(TileIndex tile)
 
{
 
	EnforcePrecondition(false, ::IsValidTile(tile));
 

	
 
	return AIObject::DoCommand(tile, 0, 0, CMD_LANDSCAPE_CLEAR);
 
}
 

	
 
/* static */ bool AITile::PlantTree(TileIndex tile)
 
{
 
	EnforcePrecondition(false, ::IsValidTile(tile));
 

	
 
	return AIObject::DoCommand(tile, -1, tile, CMD_PLANT_TREE);
 
}
 

	
 
/* static */ bool AITile::PlantTreeRectangle(TileIndex tile, uint width, uint height)
 
{
 
	EnforcePrecondition(false, ::IsValidTile(tile));
 
	EnforcePrecondition(false, width >= 1 && width <= 20);
 
	EnforcePrecondition(false, height >= 1 && height <= 20);
 
	TileIndex end_tile = tile + ::TileDiffXY(width - 1, height - 1);
 

	
 
	return AIObject::DoCommand(tile, -1, end_tile, CMD_PLANT_TREE);
 
}
 

	
 
/* static */ bool AITile::IsWithinTownInfluence(TileIndex tile, TownID town_id)
 
{
 
	return AITown::IsWithinTownInfluence(town_id, tile);
 
}
 

	
 
/* static */ TownID AITile::GetClosestTown(TileIndex tile)
 
{
 
	if (!::IsValidTile(tile)) return INVALID_TOWN;
 

	
 
	return ::ClosestTownFromTile(tile, UINT_MAX)->index;
 
}
src/ai/api/ai_tile.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_tile.hpp Everything to query and manipulate tiles. */
 

	
 
#ifndef AI_TILE_HPP
 
#define AI_TILE_HPP
 

	
 
#include "ai_abstractlist.hpp"
 
#include "ai_error.hpp"
 
#include "ai_company.hpp"
 

	
 
/**
 
 * Class that handles all tile related functions.
 
 */
 
class AITile : public AIObject {
 
public:
 
	static const char *GetClassName() { return "AITile"; }
 

	
 
	/**
 
	 * Error messages related to modifying tiles.
 
	 */
 
	enum ErrorMessages {
 

	
 
		/** Base for tile related errors */
 
		ERR_TILE_BASE = AIError::ERR_CAT_TILE << AIError::ERR_CAT_BIT_SIZE,
 

	
 
		/** Tile can't be raised any higher */
 
		ERR_TILE_TOO_HIGH,                     // [STR_1003_ALREADY_AT_SEA_LEVEL]
 

	
 
		/** Tile can't be lowered any lower */
 
		ERR_TILE_TOO_LOW,                      // [STR_1003_ALREADY_AT_SEA_LEVEL]
 
	};
 

	
 
	/**
 
	 * Enumeration for the slope-type (from slopes.h).
 
	 *
 
	 * This enumeration use the chars N, E, S, W corresponding the
 
	 *  direction North, East, South and West. The top corner of a tile
 
	 *  is the north-part of the tile.
 
	 */
 
	enum Slope {
 
		/* Values are important, as they represent the internal state of the game. */
 
		SLOPE_FLAT     = 0x00,                                  //!< A flat tile
 
		SLOPE_W        = 0x01,                                  //!< The west corner of the tile is raised
 
		SLOPE_S        = 0x02,                                  //!< The south corner of the tile is raised
 
		SLOPE_E        = 0x04,                                  //!< The east corner of the tile is raised
 
		SLOPE_N        = 0x08,                                  //!< The north corner of the tile is raised
 
		SLOPE_STEEP    = 0x10,                                  //!< Indicates the slope is steep
 
		SLOPE_NW       = SLOPE_N | SLOPE_W,                     //!< North and west corner are raised
 
		SLOPE_SW       = SLOPE_S | SLOPE_W,                     //!< South and west corner are raised
 
		SLOPE_SE       = SLOPE_S | SLOPE_E,                     //!< South and east corner are raised
 
		SLOPE_NE       = SLOPE_N | SLOPE_E,                     //!< North and east corner are raised
 
		SLOPE_EW       = SLOPE_E | SLOPE_W,                     //!< East and west corner are raised
 
		SLOPE_NS       = SLOPE_N | SLOPE_S,                     //!< North and south corner are raised
 
		SLOPE_ELEVATED = SLOPE_N | SLOPE_E | SLOPE_S | SLOPE_W, //!< All corner are raised, similar to SLOPE_FLAT
 
		SLOPE_NWS      = SLOPE_N | SLOPE_W | SLOPE_S,           //!< North, west and south corner are raised
 
		SLOPE_WSE      = SLOPE_W | SLOPE_S | SLOPE_E,           //!< West, south and east corner are raised
 
		SLOPE_SEN      = SLOPE_S | SLOPE_E | SLOPE_N,           //!< South, east and north corner are raised
 
		SLOPE_ENW      = SLOPE_E | SLOPE_N | SLOPE_W,           //!< East, north and west corner are raised
 
		SLOPE_STEEP_W  = SLOPE_STEEP | SLOPE_NWS,               //!< A steep slope falling to east (from west)
 
		SLOPE_STEEP_S  = SLOPE_STEEP | SLOPE_WSE,               //!< A steep slope falling to north (from south)
 
		SLOPE_STEEP_E  = SLOPE_STEEP | SLOPE_SEN,               //!< A steep slope falling to west (from east)
 
		SLOPE_STEEP_N  = SLOPE_STEEP | SLOPE_ENW,               //!< A steep slope falling to south (from north)
 

	
 
		SLOPE_INVALID  = 0xFF,                                  //!< An invalid slope
 
	};
 

	
 
	/**
 
	 * The different transport types a tile can have.
 
	 */
 
	enum TransportType {
 
		/* Values are important, as they represent the internal state of the game. */
 
		TRANSPORT_RAIL    =  0, //!< Tile with rail.
 
		TRANSPORT_ROAD    =  1, //!< Tile with road.
 
		TRANSPORT_WATER   =  2, //!< Tile with navigable waterways.
 
		TRANSPORT_AIR     =  3, //!< Tile with airport.
 

	
 
		INVALID_TRANSPORT = -1, //!< Tile without any transport type.
 
	};
 

	
 
	/**
 
	 * Check if this tile is buildable, i.e. no things on it that needs
 
	 *  demolishing.
 
	 * @param tile The tile to check on.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @return True if it is buildable, false if not.
 
	 * @note For trams you also might want to check for AIRoad::IsRoad(),
 
	 *   as you can build tram-rails on road-tiles.
 
	 * @note For rail you also might want to check for AIRoad::IsRoad(),
 
	 *   as in some cases you can build rails on road-tiles.
 
	 */
 
	static bool IsBuildable(TileIndex tile);
 

	
 
	/**
 
	 * Check if this tile is buildable in a rectangle around a tile, with the
 
	 *  entry in the list as top-left.
 
	 * @param tile The tile to check on.
 
	 * @param width The width of the rectangle.
 
	 * @param height The height of the rectangle.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @return True if it is buildable, false if not.
 
	 */
 
	static bool IsBuildableRectangle(TileIndex tile, uint width, uint height);
 

	
 
	/**
 
	 * Checks whether the given tile is actually a water tile.
 
	 * @param tile The tile to check on.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @return True if and only if the tile is a water tile.
 
	 */
 
	static bool IsWaterTile(TileIndex tile);
 

	
 
	/**
 
	 * Checks whether the given tile is actually a coast tile.
 
	 * @param tile The tile to check.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @return True if and only if the tile is a coast tile.
 
	 * @note Building on coast tiles in general is more expensive.
 
	 */
 
	static bool IsCoastTile(TileIndex tile);
 

	
 
	/**
 
	 * Checks whether the given tile is a station tile of any station.
 
	 * @param tile The tile to check.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @return True if and only if the tile is a station tile.
 
	 */
 
	static bool IsStationTile(TileIndex tile);
 

	
 
	/**
 
	 * Check if a tile has a steep slope.
 
	 * @param slope The slope to check on.
 
	 * @pre slope != SLOPE_INVALID.
 
	 * @return True if the slope is a steep slope.
 
	 */
 
	static bool IsSteepSlope(Slope slope);
 

	
 
	/**
 
	 * Check if a tile has a halftile slope.
 
	 * @param slope The slope to check on.
 
	 * @pre slope != SLOPE_INVALID.
 
	 * @return True if the slope is a halftile slope.
 
	 */
 
	static bool IsHalftileSlope(Slope slope);
 

	
 
	/**
 
	 * Check if the tile has any tree on it.
 
	 * @param tile The tile to check on.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @return True if and only if there is a tree on the tile.
 
	 */
 
	static bool HasTreeOnTile(TileIndex tile);
 

	
 
	/**
 
	 * Check if the tile is a farmland tile.
 
	 * @param tile The tile to check on.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @return True if and only if the tile is farmland.
 
	 */
 
	static bool IsFarmTile(TileIndex tile);
 

	
 
	/**
 
	 * Check if the tile is a rock tile.
 
	 * @param tile The tile to check on.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @return True if and only if the tile is rock tile.
 
	 */
 
	static bool IsRockTile(TileIndex tile);
 

	
 
	/**
 
	 * Check if the tile is a rough tile.
 
	 * @param tile The tile to check on.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @return True if and only if the tile is rough tile.
 
	 */
 
	static bool IsRoughTile(TileIndex tile);
 

	
 
	/**
 
	 * Check if the tile is a snow tile.
 
	 * @param tile The tile to check on.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @return True if and only if the tile is snow tile.
 
	 */
 
	static bool IsSnowTile(TileIndex tile);
 

	
 
	/**
 
	 * Check if the tile is a desert tile.
 
	 * @param tile The tile to check on.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @return True if and only if the tile is desert tile.
 
	 */
 
	static bool IsDesertTile(TileIndex tile);
 

	
 
	/**
 
	 * Get the slope of a tile.
 
	 * @param tile The tile to check on.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @return 0 means flat, others indicate internal state of slope.
 
	 */
 
	static Slope GetSlope(TileIndex tile);
 

	
 
	/**
 
	 * Get the complement of the slope.
 
	 * @param slope The slope to get the complement of.
 
	 * @pre slope != SLOPE_INVALID.
 
	 * @pre !IsSteepSlope(slope).
 
	 * @pre !IsHalftileSlope(slope).
 
	 * @return The complement of a slope. This means that all corners that
 
	 *  weren't raised, are raised, and visa versa.
 
	 */
 
	static Slope GetComplementSlope(Slope slope);
 

	
 
	/**
 
	 * Get the height of the tile.
 
	 * @param tile The tile to check on.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @return The height of the tile, ranging from 0 to 15.
 
	 */
 
	static int32 GetHeight(TileIndex tile);
 

	
 
	/**
 
	 * Get the owner of the tile.
 
	 * @param tile The tile to get the owner from.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @return The CompanyID of the owner of the tile, or INVALID_COMPANY if
 
	 *  there is no owner (grass/industry/water tiles, etc.).
 
	 */
 
	static AICompany::CompanyID GetOwner(TileIndex tile);
 

	
 
	/**
 
	 * Checks whether the given tile contains parts suitable for the given
 
	 *  TransportType.
 
	 * @param tile The tile to check.
 
	 * @param transport_type The TransportType to check against.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @note Returns false on tiles with roadworks and on road tiles with only
 
	 *       a single piece of road as these tiles cannot be used to transport
 
	 *       anything on. It furthermore returns true on some coast tile for
 
	 *       TRANSPORT_WATER because ships can navigate over them.
 
	 * @return True if and only if the tile has the given TransportType.
 
	 */
 
	static bool HasTransportType(TileIndex tile, TransportType transport_type);
 

	
 
	/**
 
	 * Check how much cargo this tile accepts.
 
	 *  It creates a radius around the tile, and adds up all acceptance of this
 
	 *   cargo.
 
	 * @param tile The tile to check on.
 
	 * @param cargo_type The cargo to check the acceptance of.
 
	 * @param width The width of the station.
 
	 * @param height The height of the station.
 
	 * @param radius The radius of the station.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @return Value below 8 means no acceptance; the more the better.
 
	 */
 
	static int32 GetCargoAcceptance(TileIndex tile, CargoID cargo_type, uint width, uint height, uint radius);
 

	
 
	/**
 
	 * Checks how many tiles in the radius produces this cargo.
 
	 *  It creates a radius around the tile, and adds up all tiles that produce
 
	 *  this cargo.
 
	 * @param tile The tile to check on.
 
	 * @param cargo_type The cargo to check the production of.
 
	 * @param width The width of the station.
 
	 * @param height The height of the station.
 
	 * @param radius The radius of the station.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @return The tiles that produce this cargo within radius of the tile.
 
	 * @note Town(houses) are not included in the value.
 
	 */
 
	static int32 GetCargoProduction(TileIndex tile, CargoID cargo_type, uint width, uint height, uint radius);
 

	
 
	/**
 
	 * Get the manhattan distance from the tile to the tile.
 
	 * @param tile_from The tile to get the distance to.
 
	 * @param tile_to The tile to get the distance to.
 
	 * @return The distance between the two tiles.
 
	 */
 
	static int32 GetDistanceManhattanToTile(TileIndex tile_from, TileIndex tile_to);
 

	
 
	/**
 
	 * Get the square distance from the tile to the tile.
 
	 * @param tile_from The tile to get the distance to.
 
	 * @param tile_to The tile to get the distance to.
 
	 * @return The distance between the two tiles.
 
	 */
 
	static int32 GetDistanceSquareToTile(TileIndex tile_from, TileIndex tile_to);
 

	
 
	/**
 
	 * Raise the given corners of the tile. The corners can be combined,
 
	 *  for example: SLOPE_N | SLOPE_W (= SLOPE_NW)
 
	 * @param tile The tile to raise.
 
	 * @param slope Corners to raise (SLOPE_xxx).
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @exception AIError::ERR_AREA_NOT_CLEAR
 
	 * @exception AIError::ERR_TOO_CLOSE_TO_EDGE
 
	 * @exception AITile::ERR_TILE_TOO_HIGH
 
	 * @return 0 means failed, 1 means success.
 
	 */
 
	static bool RaiseTile(TileIndex tile, int32 slope);
 

	
 
	/**
 
	 * Lower the given corners of the tile. The corners can be combined,
 
	 *  for example: SLOPE_N | SLOPE_W (= SLOPE_NW)
 
	 * @param tile The tile to lower.
 
	 * @param slope Corners to lower (SLOPE_xxx).
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @exception AIError::ERR_AREA_NOT_CLEAR
 
	 * @exception AIError::ERR_TOO_CLOSE_TO_EDGE
 
	 * @exception AITile::ERR_TILE_TOO_LOW
 
	 * @return 0 means failed, 1 means success.
 
	 */
 
	static bool LowerTile(TileIndex tile, int32 slope);
 

	
 
	/**
 
	 * Destroy everything on the given tile.
 
	 * @param tile The tile to demolish.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @exception AIError::ERR_AREA_NOT_CLEAR
 
	 * @return True if and only if the tile was demolished.
 
	 */
 
	static bool DemolishTile(TileIndex tile);
 

	
 
	/**
 
	 * Create a random tree on a tile.
 
	 * @param tile The tile to build a tree on.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @return True if and only if a tree was added on the tile.
 
	 */
 
	static bool PlantTree(TileIndex tile);
 

	
 
	/**
 
	 * Create a random tree on a rectangle of tiles.
 
	 * @param tile The top left tile of the rectangle.
 
	 * @param width The width of the rectangle.
 
	 * @param height The height of the rectangle.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @pre width >= 1 && width <= 20.
 
	 * @pre height >= 1 && height <= 20.
 
	 * @return True if and only if a tree was added on any of the tiles in the rectangle.
 
	 */
 
	static bool PlantTreeRectangle(TileIndex tile, uint width, uint height);
 

	
 
	/**
 
	 * Find out if this tile is within the rating influence of a town.
 
	 *  Stations on this tile influence the rating of the town.
 
	 * @param tile The tile to check.
 
	 * @param town_id The town to check.
 
	 * @return True if the tile is within the rating influence of the town.
 
	 */
 
	static bool IsWithinTownInfluence(TileIndex tile, TownID town_id);
 

	
 
	/**
 
	 * Find the town that is closest to a tile. Stations you build at this tile
 
	 *  will belong to this town.
 
	 * @param tile The tile to check.
 
	 * @return The TownID of the town closest to the tile.
 
	 */
 
	static TownID GetClosestTown(TileIndex tile);
 
};
 

	
 
#endif /* AI_TILE_HPP */
src/ai/api/ai_tile.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_tile.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow enums to be used as Squirrel parameters */
 
	template <> AITile::ErrorMessages GetParam(ForceType<AITile::ErrorMessages>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AITile::ErrorMessages)tmp; }
 
	template <> int Return<AITile::ErrorMessages>(HSQUIRRELVM vm, AITile::ErrorMessages res) { sq_pushinteger(vm, (int32)res); return 1; }
 
	template <> AITile::Slope GetParam(ForceType<AITile::Slope>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AITile::Slope)tmp; }
 
	template <> int Return<AITile::Slope>(HSQUIRRELVM vm, AITile::Slope res) { sq_pushinteger(vm, (int32)res); return 1; }
 
	template <> AITile::TransportType GetParam(ForceType<AITile::TransportType>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AITile::TransportType)tmp; }
 
	template <> int Return<AITile::TransportType>(HSQUIRRELVM vm, AITile::TransportType res) { sq_pushinteger(vm, (int32)res); return 1; }
 

	
 
	/* Allow AITile to be used as Squirrel parameter */
 
	template <> AITile *GetParam(ForceType<AITile *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AITile *)instance; }
 
	template <> AITile &GetParam(ForceType<AITile &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AITile *)instance; }
 
	template <> const AITile *GetParam(ForceType<const AITile *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AITile *)instance; }
 
	template <> const AITile &GetParam(ForceType<const AITile &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AITile *)instance; }
 
	template <> int Return<AITile *>(HSQUIRRELVM vm, AITile *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AITile", res, NULL, DefSQDestructorCallback<AITile>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAITile_Register(Squirrel *engine) {
 
	DefSQClass <AITile> SQAITile("AITile");
 
	SQAITile.PreRegister(engine);
 
	SQAITile.AddConstructor<void (AITile::*)(), 1>(engine, "x");
 

	
 
	SQAITile.DefSQConst(engine, AITile::ERR_TILE_BASE,     "ERR_TILE_BASE");
 
	SQAITile.DefSQConst(engine, AITile::ERR_TILE_TOO_HIGH, "ERR_TILE_TOO_HIGH");
 
	SQAITile.DefSQConst(engine, AITile::ERR_TILE_TOO_LOW,  "ERR_TILE_TOO_LOW");
 
	SQAITile.DefSQConst(engine, AITile::SLOPE_FLAT,        "SLOPE_FLAT");
 
	SQAITile.DefSQConst(engine, AITile::SLOPE_W,           "SLOPE_W");
 
	SQAITile.DefSQConst(engine, AITile::SLOPE_S,           "SLOPE_S");
 
	SQAITile.DefSQConst(engine, AITile::SLOPE_E,           "SLOPE_E");
 
	SQAITile.DefSQConst(engine, AITile::SLOPE_N,           "SLOPE_N");
 
	SQAITile.DefSQConst(engine, AITile::SLOPE_STEEP,       "SLOPE_STEEP");
 
	SQAITile.DefSQConst(engine, AITile::SLOPE_NW,          "SLOPE_NW");
 
	SQAITile.DefSQConst(engine, AITile::SLOPE_SW,          "SLOPE_SW");
 
	SQAITile.DefSQConst(engine, AITile::SLOPE_SE,          "SLOPE_SE");
 
	SQAITile.DefSQConst(engine, AITile::SLOPE_NE,          "SLOPE_NE");
 
	SQAITile.DefSQConst(engine, AITile::SLOPE_EW,          "SLOPE_EW");
 
	SQAITile.DefSQConst(engine, AITile::SLOPE_NS,          "SLOPE_NS");
 
	SQAITile.DefSQConst(engine, AITile::SLOPE_ELEVATED,    "SLOPE_ELEVATED");
 
	SQAITile.DefSQConst(engine, AITile::SLOPE_NWS,         "SLOPE_NWS");
 
	SQAITile.DefSQConst(engine, AITile::SLOPE_WSE,         "SLOPE_WSE");
 
	SQAITile.DefSQConst(engine, AITile::SLOPE_SEN,         "SLOPE_SEN");
 
	SQAITile.DefSQConst(engine, AITile::SLOPE_ENW,         "SLOPE_ENW");
 
	SQAITile.DefSQConst(engine, AITile::SLOPE_STEEP_W,     "SLOPE_STEEP_W");
 
	SQAITile.DefSQConst(engine, AITile::SLOPE_STEEP_S,     "SLOPE_STEEP_S");
 
	SQAITile.DefSQConst(engine, AITile::SLOPE_STEEP_E,     "SLOPE_STEEP_E");
 
	SQAITile.DefSQConst(engine, AITile::SLOPE_STEEP_N,     "SLOPE_STEEP_N");
 
	SQAITile.DefSQConst(engine, AITile::SLOPE_INVALID,     "SLOPE_INVALID");
 
	SQAITile.DefSQConst(engine, AITile::TRANSPORT_RAIL,    "TRANSPORT_RAIL");
 
	SQAITile.DefSQConst(engine, AITile::TRANSPORT_ROAD,    "TRANSPORT_ROAD");
 
	SQAITile.DefSQConst(engine, AITile::TRANSPORT_WATER,   "TRANSPORT_WATER");
 
	SQAITile.DefSQConst(engine, AITile::TRANSPORT_AIR,     "TRANSPORT_AIR");
 
	SQAITile.DefSQConst(engine, AITile::INVALID_TRANSPORT, "INVALID_TRANSPORT");
 

	
 
	AIError::RegisterErrorMap(STR_1003_ALREADY_AT_SEA_LEVEL, AITile::ERR_TILE_TOO_HIGH);
 
	AIError::RegisterErrorMap(STR_1003_ALREADY_AT_SEA_LEVEL, AITile::ERR_TILE_TOO_LOW);
 

	
 
	AIError::RegisterErrorMapString(AITile::ERR_TILE_TOO_HIGH, "ERR_TILE_TOO_HIGH");
 
	AIError::RegisterErrorMapString(AITile::ERR_TILE_TOO_LOW,  "ERR_TILE_TOO_LOW");
 

	
 
	SQAITile.DefSQStaticMethod(engine, &AITile::GetClassName,               "GetClassName",               1, "x");
 
	SQAITile.DefSQStaticMethod(engine, &AITile::IsBuildable,                "IsBuildable",                2, "xi");
 
	SQAITile.DefSQStaticMethod(engine, &AITile::IsBuildableRectangle,       "IsBuildableRectangle",       4, "xiii");
 
	SQAITile.DefSQStaticMethod(engine, &AITile::IsWaterTile,                "IsWaterTile",                2, "xi");
 
	SQAITile.DefSQStaticMethod(engine, &AITile::IsCoastTile,                "IsCoastTile",                2, "xi");
 
	SQAITile.DefSQStaticMethod(engine, &AITile::IsStationTile,              "IsStationTile",              2, "xi");
 
	SQAITile.DefSQStaticMethod(engine, &AITile::IsSteepSlope,               "IsSteepSlope",               2, "xi");
 
	SQAITile.DefSQStaticMethod(engine, &AITile::IsHalftileSlope,            "IsHalftileSlope",            2, "xi");
 
	SQAITile.DefSQStaticMethod(engine, &AITile::HasTreeOnTile,              "HasTreeOnTile",              2, "xi");
 
	SQAITile.DefSQStaticMethod(engine, &AITile::IsFarmTile,                 "IsFarmTile",                 2, "xi");
 
	SQAITile.DefSQStaticMethod(engine, &AITile::IsRockTile,                 "IsRockTile",                 2, "xi");
 
	SQAITile.DefSQStaticMethod(engine, &AITile::IsRoughTile,                "IsRoughTile",                2, "xi");
 
	SQAITile.DefSQStaticMethod(engine, &AITile::IsSnowTile,                 "IsSnowTile",                 2, "xi");
 
	SQAITile.DefSQStaticMethod(engine, &AITile::IsDesertTile,               "IsDesertTile",               2, "xi");
 
	SQAITile.DefSQStaticMethod(engine, &AITile::GetSlope,                   "GetSlope",                   2, "xi");
 
	SQAITile.DefSQStaticMethod(engine, &AITile::GetComplementSlope,         "GetComplementSlope",         2, "xi");
 
	SQAITile.DefSQStaticMethod(engine, &AITile::GetHeight,                  "GetHeight",                  2, "xi");
 
	SQAITile.DefSQStaticMethod(engine, &AITile::GetOwner,                   "GetOwner",                   2, "xi");
 
	SQAITile.DefSQStaticMethod(engine, &AITile::HasTransportType,           "HasTransportType",           3, "xii");
 
	SQAITile.DefSQStaticMethod(engine, &AITile::GetCargoAcceptance,         "GetCargoAcceptance",         6, "xiiiii");
 
	SQAITile.DefSQStaticMethod(engine, &AITile::GetCargoProduction,         "GetCargoProduction",         6, "xiiiii");
 
	SQAITile.DefSQStaticMethod(engine, &AITile::GetDistanceManhattanToTile, "GetDistanceManhattanToTile", 3, "xii");
 
	SQAITile.DefSQStaticMethod(engine, &AITile::GetDistanceSquareToTile,    "GetDistanceSquareToTile",    3, "xii");
 
	SQAITile.DefSQStaticMethod(engine, &AITile::RaiseTile,                  "RaiseTile",                  3, "xii");
 
	SQAITile.DefSQStaticMethod(engine, &AITile::LowerTile,                  "LowerTile",                  3, "xii");
 
	SQAITile.DefSQStaticMethod(engine, &AITile::DemolishTile,               "DemolishTile",               2, "xi");
 
	SQAITile.DefSQStaticMethod(engine, &AITile::PlantTree,                  "PlantTree",                  2, "xi");
 
	SQAITile.DefSQStaticMethod(engine, &AITile::PlantTreeRectangle,         "PlantTreeRectangle",         4, "xiii");
 
	SQAITile.DefSQStaticMethod(engine, &AITile::IsWithinTownInfluence,      "IsWithinTownInfluence",      3, "xii");
 
	SQAITile.DefSQStaticMethod(engine, &AITile::GetClosestTown,             "GetClosestTown",             2, "xi");
 

	
 
	SQAITile.PostRegister(engine);
 
}
src/ai/api/ai_tilelist.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_tilelist.cpp Implementation of AITileList and friends. */
 

	
 
#include "ai_tilelist.hpp"
 
#include "ai_industry.hpp"
 
#include "../../openttd.h"
 
#include "../../landscape.h"
 
#include "../../settings_type.h"
 
#include "../../station_func.h"
 
#include "../../map_func.h"
 
#include "../../tile_map.h"
 
#include "../../industry_map.h"
 
#include "../../station_base.h"
 
#include "../../station_map.h"
 

	
 
void AITileList::FixRectangleSpan(TileIndex &t1, TileIndex &t2)
 
{
 
	uint x1 = ::TileX(t1);
 
	uint x2 = ::TileX(t2);
 

	
 
	uint y1 = ::TileY(t1);
 
	uint y2 = ::TileY(t2);
 

	
 
	if (x1 >= x2) ::Swap(x1, x2);
 
	if (y1 >= y2) ::Swap(y1, y2);
 

	
 
	t1 = ::TileXY(x1, y1);
 
	t2 = ::TileXY(x2, y2);
 
}
 

	
 
void AITileList::AddRectangle(TileIndex t1, TileIndex t2)
 
{
 
	if (!::IsValidTile(t1)) return;
 
	if (!::IsValidTile(t2)) return;
 

	
 
	this->FixRectangleSpan(t1, t2);
 

	
 
	uint w = TileX(t2) - TileX(t1) + 1;
 
	uint h = TileY(t2) - TileY(t1) + 1;
 

	
 
	BEGIN_TILE_LOOP(t, w, h, t1) {
 
		this->AddItem(t);
 
	} END_TILE_LOOP(t, w, h, t1)
 
}
 

	
 
void AITileList::AddTile(TileIndex tile)
 
{
 
	if (!::IsValidTile(tile)) return;
 

	
 
	this->AddItem(tile);
 
}
 

	
 
void AITileList::RemoveRectangle(TileIndex t1, TileIndex t2)
 
{
 
	if (!::IsValidTile(t1)) return;
 
	if (!::IsValidTile(t2)) return;
 

	
 
	this->FixRectangleSpan(t1, t2);
 

	
 
	uint w = TileX(t2) - TileX(t1) + 1;
 
	uint h = TileY(t2) - TileY(t1) + 1;
 

	
 
	BEGIN_TILE_LOOP(t, w, h, t1) {
 
		this->RemoveItem(t);
 
	} END_TILE_LOOP(t, w, h, t1)
 
}
 

	
 
void AITileList::RemoveTile(TileIndex tile)
 
{
 
	if (!::IsValidTile(tile)) return;
 

	
 
	this->RemoveItem(tile);
 
}
 

	
 
AITileList_IndustryAccepting::AITileList_IndustryAccepting(IndustryID industry_id, uint radius)
 
{
 
	if (!AIIndustry::IsValidIndustry(industry_id)) return;
 

	
 
	const Industry *i = ::GetIndustry(industry_id);
 
	const IndustrySpec *indsp = ::GetIndustrySpec(i->type);
 

	
 
	/* Check if this industry accepts anything */
 
	{
 
		bool cargo_accepts = false;
 
		for (byte j = 0; j < lengthof(indsp->accepts_cargo); j++) {
 
			if (indsp->accepts_cargo[j] != CT_INVALID) cargo_accepts = true;
 
		}
 
		if (!cargo_accepts) return;
 
	}
 

	
 
	if (!_settings_game.station.modified_catchment) radius = CA_UNMODIFIED;
 

	
 
	BEGIN_TILE_LOOP(cur_tile, i->width + radius * 2, i->height + radius * 2, i->xy - ::TileDiffXY(radius, radius)) {
 
		if (!::IsValidTile(cur_tile)) continue;
 
		/* Exclude all tiles that belong to this industry */
 
		if (::IsTileType(cur_tile, MP_INDUSTRY) && ::GetIndustryIndex(cur_tile) == industry_id) continue;
 

	
 
		/* Only add the tile if it accepts the cargo (sometimes just 1 tile of an
 
		 *  industry triggers the acceptance). */
 
		AcceptedCargo accepts;
 
		::GetAcceptanceAroundTiles(accepts, cur_tile, 1, 1, radius);
 
		{
 
			bool cargo_accepts = false;
 
			for (byte j = 0; j < lengthof(indsp->accepts_cargo); j++) {
 
				if (indsp->accepts_cargo[j] != CT_INVALID && accepts[indsp->accepts_cargo[j]] != 0) cargo_accepts = true;
 
			}
 
			if (!cargo_accepts) continue;
 
		}
 

	
 
		this->AddTile(cur_tile);
 
	} END_TILE_LOOP(cur_tile, i->width + radius * 2, i->height + radius * 2, i->xy - ::TileDiffXY(radius, radius))
 
}
 

	
 
AITileList_IndustryProducing::AITileList_IndustryProducing(IndustryID industry_id, uint radius)
 
{
 
	if (!AIIndustry::IsValidIndustry(industry_id)) return;
 

	
 
	const Industry *i = ::GetIndustry(industry_id);
 
	const IndustrySpec *indsp = ::GetIndustrySpec(i->type);
 

	
 
	/* Check if this industry produces anything */
 
	{
 
		bool cargo_produces = false;
 
		for (byte j = 0; j < lengthof(indsp->produced_cargo); j++) {
 
			if (indsp->produced_cargo[j] != CT_INVALID) cargo_produces = true;
 
		}
 
		if (!cargo_produces) return;
 
	}
 

	
 
	if (!_settings_game.station.modified_catchment) radius = CA_UNMODIFIED;
 

	
 
	BEGIN_TILE_LOOP(cur_tile, i->width + radius * 2, i->height + radius * 2, i->xy - ::TileDiffXY(radius, radius)) {
 
		if (!::IsValidTile(cur_tile)) continue;
 
		/* Exclude all tiles that belong to this industry */
 
		if (::IsTileType(cur_tile, MP_INDUSTRY) && ::GetIndustryIndex(cur_tile) == industry_id) continue;
 

	
 
		/* Only add the tile if it produces the cargo (a bug in OpenTTD makes this
 
		 *  inconsitance). */
 
		AcceptedCargo produces;
 
		::GetProductionAroundTiles(produces, cur_tile, 1, 1, radius);
 
		{
 
			bool cargo_produces = false;
 
			for (byte j = 0; j < lengthof(indsp->produced_cargo); j++) {
 
				if (indsp->produced_cargo[j] != CT_INVALID && produces[indsp->produced_cargo[j]] != 0) cargo_produces = true;
 
			}
 
			if (!cargo_produces) continue;
 
		}
 

	
 
		this->AddTile(cur_tile);
 
	} END_TILE_LOOP(cur_tile, i->width + radius * 2, i->height + radius * 2, i->xy - ::TileDiffXY(radius, radius))
 
}
 

	
 
AITileList_StationType::AITileList_StationType(StationID station_id, AIStation::StationType station_type)
 
{
 
	if (!AIStation::IsValidStation(station_id)) return;
 

	
 
	const StationRect *rect = &::GetStation(station_id)->rect;
 

	
 
	uint station_type_value = 0;
 
	/* Convert AIStation::StationType to ::StationType, but do it in a
 
	 *  bitmask, so we can scan for multiple entries at the same time. */
 
	if ((station_type & AIStation::STATION_TRAIN) != 0)      station_type_value |= (1 << ::STATION_RAIL);
 
	if ((station_type & AIStation::STATION_TRUCK_STOP) != 0) station_type_value |= (1 << ::STATION_TRUCK);
 
	if ((station_type & AIStation::STATION_BUS_STOP) != 0)   station_type_value |= (1 << ::STATION_BUS);
 
	if ((station_type & AIStation::STATION_AIRPORT) != 0)    station_type_value |= (1 << ::STATION_AIRPORT) | (1 << ::STATION_OILRIG);
 
	if ((station_type & AIStation::STATION_DOCK) != 0)       station_type_value |= (1 << ::STATION_DOCK)    | (1 << ::STATION_OILRIG);
 

	
 
	BEGIN_TILE_LOOP(cur_tile, rect->right - rect->left + 1, rect->bottom - rect->top + 1, ::TileXY(rect->left, rect->top)) {
 
		if (!::IsTileType(cur_tile, MP_STATION)) continue;
 
		if (::GetStationIndex(cur_tile) != station_id) continue;
 
		if (!HasBit(station_type_value, ::GetStationType(cur_tile))) continue;
 
		this->AddTile(cur_tile);
 
	} END_TILE_LOOP(cur_tile, rect->right - rect->left + 1, rect->bottom - rect->top + 1, ::TileXY(rect->left, rect->top))
 
}
src/ai/api/ai_tilelist.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_tilelist.hpp List tiles. */
 

	
 
#ifndef AI_TILELIST_HPP
 
#define AI_TILELIST_HPP
 

	
 
#include "ai_abstractlist.hpp"
 
#include "ai_station.hpp"
 

	
 
/**
 
 * Creates an empty list, in which you can add tiles.
 
 * @ingroup AIList
 
 */
 
class AITileList : public AIAbstractList {
 
public:
 
	static const char *GetClassName() { return "AITileList"; }
 

	
 
private:
 
	/**
 
	 * Make sure t1.x is smaller than t2.x and t1.y is smaller than t2.y.
 
	 * They are swapped to ensure they are after calling this function.
 
	 * @param t1 one of the corners of the rectangle.
 
	 * @param t2 the other corner of the rectangle.
 
	 */
 
	void FixRectangleSpan(TileIndex &t1, TileIndex &t2);
 

	
 
public:
 
	/**
 
	 * Adds the rectangle between tile_from and tile_to to the to-be-evaluated tiles.
 
	 * @param tile_from One corner of the tiles to add.
 
	 * @param tile_to The other corner of the tiles to add.
 
	 * @pre AIMap::IsValidTile(tile_from).
 
	 * @pre AIMap::IsValidTile(tile_to).
 
	 */
 
	void AddRectangle(TileIndex tile_from, TileIndex tile_to);
 

	
 
	/**
 
	 * Add a tile to the to-be-evaluated tiles.
 
	 * @param tile The tile to add.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 */
 
	void AddTile(TileIndex tile);
 

	
 
	/**
 
	 * Remove the tiles inside the rectangle between tile_from and tile_to form the list.
 
	 * @param tile_from One corner of the tiles to remove.
 
	 * @param tile_to The other corner of the files to remove.
 
	 * @pre AIMap::IsValidTile(tile_from).
 
	 * @pre AIMap::IsValidTile(tile_to).
 
	 */
 
	void RemoveRectangle(TileIndex tile_from, TileIndex tile_to);
 

	
 
	/**
 
	 * Remove a tile from the list.
 
	 * @param tile The tile to remove.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 */
 
	void RemoveTile(TileIndex tile);
 
};
 

	
 
/**
 
 * Creates a list of tiles that will accept cargo for the given industry.
 
 * @note If a simular industry is close, it might happen that this industry receives the cargo.
 
 * @ingroup AIList
 
 */
 
class AITileList_IndustryAccepting : public AITileList {
 
public:
 
	static const char *GetClassName() { return "AITileList_IndustryAccepting"; }
 

	
 
	/**
 
	 * @param industry_id The industry to create the AITileList around.
 
	 * @param radius The radius of the station you will be using.
 
	 */
 
	AITileList_IndustryAccepting(IndustryID industry_id, uint radius);
 
};
 

	
 
/**
 
 * Creates a list of tiles which the industry checks to see if a station is
 
 *  there to receive cargo produced by this industry.
 
 * @ingroup AIList
 
 */
 
class AITileList_IndustryProducing : public AITileList {
 
public:
 
	static const char *GetClassName() { return "AITileList_IndustryProducing"; }
 

	
 
	/**
 
	 * @param industry_id The industry to create the AITileList around.
 
	 * @param radius The radius of the station you will be using.
 
	 */
 
	AITileList_IndustryProducing(IndustryID industry_id, uint radius);
 
};
 

	
 
/**
 
 * Creates a list of tiles which have the requested StationType of the
 
 *  StationID.
 
 * @ingroup AIList
 
 */
 
class AITileList_StationType : public AITileList {
 
public:
 
	static const char *GetClassName() { return "AITileList_StationType"; }
 

	
 
	/**
 
	 * @param station_id The station to create the AITileList for.
 
	 * @param station_type The StationType to create the AIList for.
 
	 */
 
	AITileList_StationType(StationID station_id, AIStation::StationType station_type);
 
};
 

	
 
#endif /* AI_TILELIST_HPP */
src/ai/api/ai_tilelist.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_tilelist.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow AITileList to be used as Squirrel parameter */
 
	template <> AITileList *GetParam(ForceType<AITileList *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AITileList *)instance; }
 
	template <> AITileList &GetParam(ForceType<AITileList &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AITileList *)instance; }
 
	template <> const AITileList *GetParam(ForceType<const AITileList *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AITileList *)instance; }
 
	template <> const AITileList &GetParam(ForceType<const AITileList &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AITileList *)instance; }
 
	template <> int Return<AITileList *>(HSQUIRRELVM vm, AITileList *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AITileList", res, NULL, DefSQDestructorCallback<AITileList>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAITileList_Register(Squirrel *engine) {
 
	DefSQClass <AITileList> SQAITileList("AITileList");
 
	SQAITileList.PreRegister(engine, "AIAbstractList");
 
	SQAITileList.AddConstructor<void (AITileList::*)(), 1>(engine, "x");
 

	
 
	SQAITileList.DefSQStaticMethod(engine, &AITileList::GetClassName, "GetClassName", 1, "x");
 

	
 
	SQAITileList.DefSQMethod(engine, &AITileList::AddRectangle,    "AddRectangle",    3, "xii");
 
	SQAITileList.DefSQMethod(engine, &AITileList::AddTile,         "AddTile",         2, "xi");
 
	SQAITileList.DefSQMethod(engine, &AITileList::RemoveRectangle, "RemoveRectangle", 3, "xii");
 
	SQAITileList.DefSQMethod(engine, &AITileList::RemoveTile,      "RemoveTile",      2, "xi");
 

	
 
	SQAITileList.PostRegister(engine);
 
}
 

	
 
namespace SQConvert {
 
	/* Allow AITileList_IndustryAccepting to be used as Squirrel parameter */
 
	template <> AITileList_IndustryAccepting *GetParam(ForceType<AITileList_IndustryAccepting *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AITileList_IndustryAccepting *)instance; }
 
	template <> AITileList_IndustryAccepting &GetParam(ForceType<AITileList_IndustryAccepting &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AITileList_IndustryAccepting *)instance; }
 
	template <> const AITileList_IndustryAccepting *GetParam(ForceType<const AITileList_IndustryAccepting *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AITileList_IndustryAccepting *)instance; }
 
	template <> const AITileList_IndustryAccepting &GetParam(ForceType<const AITileList_IndustryAccepting &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AITileList_IndustryAccepting *)instance; }
 
	template <> int Return<AITileList_IndustryAccepting *>(HSQUIRRELVM vm, AITileList_IndustryAccepting *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AITileList_IndustryAccepting", res, NULL, DefSQDestructorCallback<AITileList_IndustryAccepting>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAITileList_IndustryAccepting_Register(Squirrel *engine) {
 
	DefSQClass <AITileList_IndustryAccepting> SQAITileList_IndustryAccepting("AITileList_IndustryAccepting");
 
	SQAITileList_IndustryAccepting.PreRegister(engine, "AITileList");
 
	SQAITileList_IndustryAccepting.AddConstructor<void (AITileList_IndustryAccepting::*)(IndustryID industry_id, uint radius), 3>(engine, "xii");
 

	
 
	SQAITileList_IndustryAccepting.DefSQStaticMethod(engine, &AITileList_IndustryAccepting::GetClassName, "GetClassName", 1, "x");
 

	
 
	SQAITileList_IndustryAccepting.PostRegister(engine);
 
}
 

	
 
namespace SQConvert {
 
	/* Allow AITileList_IndustryProducing to be used as Squirrel parameter */
 
	template <> AITileList_IndustryProducing *GetParam(ForceType<AITileList_IndustryProducing *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AITileList_IndustryProducing *)instance; }
 
	template <> AITileList_IndustryProducing &GetParam(ForceType<AITileList_IndustryProducing &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AITileList_IndustryProducing *)instance; }
 
	template <> const AITileList_IndustryProducing *GetParam(ForceType<const AITileList_IndustryProducing *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AITileList_IndustryProducing *)instance; }
 
	template <> const AITileList_IndustryProducing &GetParam(ForceType<const AITileList_IndustryProducing &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AITileList_IndustryProducing *)instance; }
 
	template <> int Return<AITileList_IndustryProducing *>(HSQUIRRELVM vm, AITileList_IndustryProducing *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AITileList_IndustryProducing", res, NULL, DefSQDestructorCallback<AITileList_IndustryProducing>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAITileList_IndustryProducing_Register(Squirrel *engine) {
 
	DefSQClass <AITileList_IndustryProducing> SQAITileList_IndustryProducing("AITileList_IndustryProducing");
 
	SQAITileList_IndustryProducing.PreRegister(engine, "AITileList");
 
	SQAITileList_IndustryProducing.AddConstructor<void (AITileList_IndustryProducing::*)(IndustryID industry_id, uint radius), 3>(engine, "xii");
 

	
 
	SQAITileList_IndustryProducing.DefSQStaticMethod(engine, &AITileList_IndustryProducing::GetClassName, "GetClassName", 1, "x");
 

	
 
	SQAITileList_IndustryProducing.PostRegister(engine);
 
}
 

	
 
namespace SQConvert {
 
	/* Allow AITileList_StationType to be used as Squirrel parameter */
 
	template <> AITileList_StationType *GetParam(ForceType<AITileList_StationType *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AITileList_StationType *)instance; }
 
	template <> AITileList_StationType &GetParam(ForceType<AITileList_StationType &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AITileList_StationType *)instance; }
 
	template <> const AITileList_StationType *GetParam(ForceType<const AITileList_StationType *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AITileList_StationType *)instance; }
 
	template <> const AITileList_StationType &GetParam(ForceType<const AITileList_StationType &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AITileList_StationType *)instance; }
 
	template <> int Return<AITileList_StationType *>(HSQUIRRELVM vm, AITileList_StationType *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AITileList_StationType", res, NULL, DefSQDestructorCallback<AITileList_StationType>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAITileList_StationType_Register(Squirrel *engine) {
 
	DefSQClass <AITileList_StationType> SQAITileList_StationType("AITileList_StationType");
 
	SQAITileList_StationType.PreRegister(engine, "AITileList");
 
	SQAITileList_StationType.AddConstructor<void (AITileList_StationType::*)(StationID station_id, AIStation::StationType station_type), 3>(engine, "xii");
 

	
 
	SQAITileList_StationType.DefSQStaticMethod(engine, &AITileList_StationType::GetClassName, "GetClassName", 1, "x");
 

	
 
	SQAITileList_StationType.PostRegister(engine);
 
}
src/ai/api/ai_town.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_town.cpp Implementation of AITown. */
 

	
 
#include "ai_town.hpp"
 
#include "ai_map.hpp"
 
#include "ai_cargo.hpp"
 
#include "ai_error.hpp"
 
#include "../../command_type.h"
 
#include "../../openttd.h"
 
#include "../../town.h"
 
#include "../../strings_func.h"
 
#include "../../core/alloc_func.hpp"
 
#include "../../company_func.h"
 
#include "../../station_base.h"
 
#include "table/strings.h"
 

	
 
/* static */ TownID AITown::GetMaxTownID()
 
{
 
	return ::GetMaxTownIndex();
 
}
 

	
 
/* static */ int32 AITown::GetTownCount()
 
{
 
	return ::GetNumTowns();
 
}
 

	
 
/* static */ bool AITown::IsValidTown(TownID town_id)
 
{
 
	return ::IsValidTownID(town_id);
 
}
 

	
 
/* static */ const char *AITown::GetName(TownID town_id)
 
{
 
	if (!IsValidTown(town_id)) return NULL;
 
	static const int len = 64;
 
	char *town_name = MallocT<char>(len);
 

	
 
	::SetDParam(0, town_id);
 
	::GetString(town_name, STR_TOWN, &town_name[len - 1]);
 

	
 
	return town_name;
 
}
 

	
 
/* static */ int32 AITown::GetPopulation(TownID town_id)
 
{
 
	if (!IsValidTown(town_id)) return -1;
 
	const Town *t = ::GetTown(town_id);
 
	return t->population;
 
}
 

	
 
/* static */ int32 AITown::GetHouseCount(TownID town_id)
 
{
 
	if (!IsValidTown(town_id)) return -1;
 
	const Town *t = ::GetTown(town_id);
 
	return t->num_houses;
 
}
 

	
 
/* static */ TileIndex AITown::GetLocation(TownID town_id)
 
{
 
	if (!IsValidTown(town_id)) return INVALID_TILE;
 
	const Town *t = ::GetTown(town_id);
 
	return t->xy;
 
}
 

	
 
/* static */ int32 AITown::GetLastMonthProduction(TownID town_id, CargoID cargo_id)
 
{
 
	if (!IsValidTown(town_id)) return -1;
 
	if (!AICargo::IsValidCargo(cargo_id)) return -1;
 

	
 
	const Town *t = ::GetTown(town_id);
 

	
 
	switch(AICargo::GetTownEffect(cargo_id)) {
 
		case AICargo::TE_PASSENGERS: return t->act_pass;
 
		case AICargo::TE_MAIL:       return t->act_mail;
 
		default: return -1;
 
	}
 
}
 

	
 
/* static */ int32 AITown::GetLastMonthTransported(TownID town_id, CargoID cargo_id)
 
{
 
	if (!IsValidTown(town_id)) return -1;
 
	if (!AICargo::IsValidCargo(cargo_id)) return -1;
 

	
 
	const Town *t = ::GetTown(town_id);
 

	
 
	switch(AICargo::GetTownEffect(cargo_id)) {
 
		case AICargo::TE_PASSENGERS: return t->pct_pass_transported;
 
		case AICargo::TE_MAIL:       return t->pct_mail_transported;
 
		default: return -1;
 
	}
 
}
 

	
 
/* static */ int32 AITown::GetMaxProduction(TownID town_id, CargoID cargo_id)
 
{
 
	if (!IsValidTown(town_id)) return -1;
 
	if (!AICargo::IsValidCargo(cargo_id)) return -1;
 

	
 
	const Town *t = ::GetTown(town_id);
 

	
 
	switch(AICargo::GetTownEffect(cargo_id)) {
 
		case AICargo::TE_PASSENGERS: return t->max_pass;
 
		case AICargo::TE_MAIL:       return t->max_mail;
 
		default: return -1;
 
	}
 
}
 

	
 
/* static */ int32 AITown::GetDistanceManhattanToTile(TownID town_id, TileIndex tile)
 
{
 
	return AIMap::DistanceManhattan(tile, GetLocation(town_id));
 
}
 

	
 
/* static */ int32 AITown::GetDistanceSquareToTile(TownID town_id, TileIndex tile)
 
{
 
	return AIMap::DistanceSquare(tile, GetLocation(town_id));
 
}
 

	
 
/* static */ bool AITown::IsWithinTownInfluence(TownID town_id, TileIndex tile)
 
{
 
	if (!IsValidTown(town_id)) return false;
 

	
 
	const Town *t = ::GetTown(town_id);
 
	return ((uint32)GetDistanceSquareToTile(town_id, tile) <= t->squared_town_zone_radius[0]);
 
}
 

	
 
/* static */ bool AITown::HasStatue(TownID town_id)
 
{
 
	if (!IsValidTown(town_id)) return false;
 

	
 
	return ::HasBit(::GetTown(town_id)->statues, _current_company);
 
}
 

	
 
/* static */ int AITown::GetRoadReworkDuration(TownID town_id)
 
{
 
	if (!IsValidTown(town_id)) return -1;
 

	
 
	return ::GetTown(town_id)->road_build_months;
 
}
 

	
 
/* static */ AICompany::CompanyID AITown::GetExclusiveRightsCompany(TownID town_id)
 
{
 
	if (!IsValidTown(town_id)) return AICompany::INVALID_COMPANY;
 

	
 
	return (AICompany::CompanyID)(int8)::GetTown(town_id)->exclusivity;
 
}
 

	
 
/* static */ int32 AITown::GetExclusiveRightsDuration(TownID town_id)
 
{
 
	if (!IsValidTown(town_id)) return -1;
 

	
 
	return ::GetTown(town_id)->exclusive_counter;
 
}
 

	
 
extern uint GetMaskOfTownActions(int *nump, CompanyID cid, const Town *t);
 

	
 
/* static */ bool AITown::IsActionAvailable(TownID town_id, TownAction town_action)
 
{
 
	if (!IsValidTown(town_id)) return false;
 

	
 
	return HasBit(::GetMaskOfTownActions(NULL, _current_company, ::GetTown(town_id)), town_action);
 
}
 

	
 
/* static */ bool AITown::PerformTownAction(TownID town_id, TownAction town_action)
 
{
 
	EnforcePrecondition(false, IsValidTown(town_id));
 
	EnforcePrecondition(false, IsActionAvailable(town_id, town_action));
 

	
 
	return AIObject::DoCommand(::GetTown(town_id)->xy, town_id, town_action, CMD_DO_TOWN_ACTION);
 
}
 

	
 
/* static */ AITown::TownRating AITown::GetRating(TownID town_id, AICompany::CompanyID company_id)
 
{
 
	if (!IsValidTown(town_id)) return INVALID_TOWN_RATING;
 
	AICompany::CompanyID company = AICompany::ResolveCompanyID(company_id);
 
	if (company == AICompany::INVALID_COMPANY) return INVALID_TOWN_RATING;
 

	
 
	const Town *t = ::GetTown(town_id);
 
	if (!HasBit(t->have_ratings, company)) return TOWN_RATING_NONE;
 
	return max(TOWN_RATING_APPALLING, (TownRating)((t->ratings[company] / 200) + 3));
 
}
 

	
 
/* static */ int AITown::GetAllowedNoise(TownID town_id)
 
{
 
	if (!IsValidTown(town_id)) return -1;
 

	
 
	const Town *t = ::GetTown(town_id);
 
	if (_settings_game.economy.station_noise_level) {
 
		return t->MaxTownNoise() - t->noise_reached;
 
	}
 

	
 
	int num = 0;
 
	const Station *st;
 
	FOR_ALL_STATIONS(st) {
 
		if (st->town == t && st->facilities & FACIL_AIRPORT && st->airport_type != AT_OILRIG) num++;
 
	}
 
	return max(0, 2 - num);
 
}
src/ai/api/ai_town.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_town.hpp Everything to query towns. */
 

	
 
#ifndef AI_TOWN_HPP
 
#define AI_TOWN_HPP
 

	
 
#include "ai_object.hpp"
 
#include "ai_company.hpp"
 

	
 
/**
 
 * Class that handles all town related functions.
 
 */
 
class AITown : public AIObject {
 
public:
 
	static const char *GetClassName() { return "AITown"; }
 

	
 
	/**
 
	 * Actions that one can perform on a town.
 
	 */
 
	enum TownAction {
 
		/* Values are important, as they represent the internal state of the game. */
 

	
 
		/**
 
		 * The cargo ratings temporary gains 25% of rating (in
 
		 * absolute percentage, so 10% becomes 35%, with a max of 99%)
 
		 * for all stations within 10 tiles.
 
		 */
 
		TOWN_ACTION_ADVERTISE_SMALL  = 0,
 

	
 
		/**
 
		 * The cargo ratings temporary gains 44% of rating (in
 
		 * absolute percentage, so 10% becomes 54%, with a max of 99%)
 
		 * for all stations within 15 tiles.
 
		 */
 
		TOWN_ACTION_ADVERTISE_MEDIUM = 1,
 

	
 
		/**
 
		 * The cargo ratings temporary gains 63% of rating (in
 
		 * absolute percentage, so 10% becomes 73%, with a max of 99%)
 
		 * for all stations within 20 tiles.
 
		 */
 
		TOWN_ACTION_ADVERTISE_LARGE  = 2,
 

	
 
		/**
 
		 * Rebuild the roads of this town for 6 months.
 
		 */
 
		TOWN_ACTION_ROAD_REBUILD     = 3,
 

	
 
		/**
 
		 * Build a statue in this town.
 
		 */
 
		TOWN_ACTION_BUILD_STATUE     = 4,
 

	
 
		/**
 
		 * Fund the creation of extra buildings for 3 months.
 
		 */
 
		TOWN_ACTION_FUND_BUILDINGS   = 5,
 

	
 
		/**
 
		 * Buy exclusive rights for this town for 12 months.
 
		 */
 
		TOWN_ACTION_BUY_RIGHTS       = 6,
 

	
 
		/**
 
		 * Bribe the town in order to get a higher rating.
 
		 */
 
		TOWN_ACTION_BRIBE            = 7,
 
	};
 

	
 
	/**
 
	 * Different ratings one could have in a town.
 
	 */
 
	enum TownRating {
 
		TOWN_RATING_NONE,         ///< The company got no rating in the town.
 
		TOWN_RATING_APPALLING,    ///< The company got an appalling rating in the town .
 
		TOWN_RATING_VERY_POOR,    ///< The company got an very poor rating in the town.
 
		TOWN_RATING_POOR,         ///< The company got an poor rating in the town.
 
		TOWN_RATING_MEDIOCRE,     ///< The company got an mediocre rating in the town.
 
		TOWN_RATING_GOOD,         ///< The company got an good rating in the town.
 
		TOWN_RATING_VERY_GOOD,    ///< The company got an very good rating in the town.
 
		TOWN_RATING_EXCELLENT,    ///< The company got an excellent rating in the town.
 
		TOWN_RATING_OUTSTANDING,  ///< The company got an outstanding rating in the town.
 
		INVALID_TOWN_RATING = -1, ///< The town rating for invalid towns/companies.
 
	};
 

	
 
	/**
 
	 * Gets the maximum town index; there are no valid towns with a higher index.
 
	 * @return The maximum town index.
 
	 * @post Return value is always non-negative.
 
	 */
 
	static TownID GetMaxTownID();
 

	
 
	/**
 
	 * Gets the number of towns. This is different than GetMaxTownID()
 
	 *   because of the way OpenTTD works internally.
 
	 * @return The number of towns.
 
	 * @post Return value is always non-negative.
 
	 */
 
	static int32 GetTownCount();
 

	
 
	/**
 
	 * Checks whether the given town index is valid.
 
	 * @param town_id The index to check.
 
	 * @return True if and only if the town is valid.
 
	 */
 
	static bool IsValidTown(TownID town_id);
 

	
 
	/**
 
	 * Get the name of the town.
 
	 * @param town_id The town to get the name of.
 
	 * @pre IsValidTown(town_id).
 
	 * @return The name of the town.
 
	 */
 
	static const char *GetName(TownID town_id);
 

	
 
	/**
 
	 * Gets the number of inhabitants in the town.
 
	 * @param town_id The town to get the population of.
 
	 * @pre IsValidTown(town_id).
 
	 * @return The number of inhabitants.
 
	 * @post Return value is always non-negative.
 
	 */
 
	static int32 GetPopulation(TownID town_id);
 

	
 
	/**
 
	 * Gets the number of houses in the town.
 
	 * @param town_id The town to get the number of houses of.
 
	 * @pre IsValidTown(town_id).
 
	 * @return The number of houses.
 
	 * @post Return value is always non-negative.
 
	 */
 
	static int32 GetHouseCount(TownID town_id);
 

	
 
	/**
 
	 * Gets the location of the town.
 
	 * @param town_id The town to get the location of.
 
	 * @pre IsValidTown(town_id).
 
	 * @return The location of the town.
 
	 */
 
	static TileIndex GetLocation(TownID town_id);
 

	
 
	/**
 
	 * Get the total last month's production of the given cargo at a town.
 
	 * @param town_id The index of the town.
 
	 * @param cargo_id The index of the cargo.
 
	 * @pre IsValidTown(town_id).
 
	 * @pre AICargo::IsValidCargo(cargo_id).
 
	 * @pre AICargo::GetTownEffect(cargo_id) == TE_PASSENGERS || AICargo::GetTownEffect(cargo_id) == TE_MAIL.
 
	 * @return The last month's production of the given cargo for this town.
 
	 * @post Return value is always non-negative.
 
	 */
 
	static int32 GetLastMonthProduction(TownID town_id, CargoID cargo_id);
 

	
 
	/**
 
	 * Get the total amount of cargo transported from a town last month.
 
	 * @param town_id The index of the industry.
 
	 * @param cargo_id The index of the cargo.
 
	 * @pre IsValidTown(town_id).
 
	 * @pre AICargo::IsValidCargo(cargo_id).
 
	 * @pre AICargo::GetTownEffect(cargo_id) == TE_PASSENGERS || AICargo::GetTownEffect(cargo_id) == TE_MAIL.
 
	 * @return The amount of given cargo transported from this town last month.
 
	 * @post Return value is always non-negative.
 
	 */
 
	static int32 GetLastMonthTransported(TownID town_id, CargoID cargo_id);
 

	
 
	/**
 
	 * Get the maximum production of the given cargo at a town.
 
	 * @param town_id The index of the town.
 
	 * @param cargo_id The index of the cargo.
 
	 * @pre IsValidTown(town_id).
 
	 * @pre AICargo::IsValidCargo(cargo_id).
 
	 * @pre AICargo::GetTownEffect(cargo_id) == TE_PASSENGERS || AICargo::GetTownEffect(cargo_id) == TE_MAIL.
 
	 * @return The maximum production of the given cargo for this town.
 
	 * @post Return value is always non-negative.
 
	 */
 
	static int32 GetMaxProduction(TownID town_id, CargoID cargo_id);
 

	
 
	/**
 
	 * Get the manhattan distance from the tile to the AITown::GetLocation()
 
	 *  of the town.
 
	 * @param town_id The town to get the distance to.
 
	 * @param tile The tile to get the distance to.
 
	 * @pre IsValidTown(town_id).
 
	 * @return The distance between town and tile.
 
	 */
 
	static int32 GetDistanceManhattanToTile(TownID town_id, TileIndex tile);
 

	
 
	/**
 
	 * Get the square distance from the tile to the AITown::GetLocation()
 
	 *  of the town.
 
	 * @param town_id The town to get the distance to.
 
	 * @param tile The tile to get the distance to.
 
	 * @pre IsValidTown(town_id).
 
	 * @return The distance between town and tile.
 
	 */
 
	static int32 GetDistanceSquareToTile(TownID town_id, TileIndex tile);
 

	
 
	/**
 
	 * Find out if this tile is within the rating influence of a town.
 
	 *  Stations on this tile influence the rating of the town.
 
	 * @param town_id The town to check.
 
	 * @param tile The tile to check.
 
	 * @pre IsValidTown(town_id).
 
	 * @return True if the tile is within the rating influence of the town.
 
	 */
 
	static bool IsWithinTownInfluence(TownID town_id, TileIndex tile);
 

	
 
	/**
 
	 * Find out if this town has a statue for the current company.
 
	 * @param town_id The town to check.
 
	 * @pre IsValidTown(town_id).
 
	 * @return True if the town has a statue.
 
	 */
 
	static bool HasStatue(TownID town_id);
 

	
 
	/**
 
	 * Find out how long the town is undergoing road reconstructions.
 
	 * @param town_id The town to check.
 
	 * @pre IsValidTown(town_id).
 
	 * @return The number of months the road reworks are still going to take.
 
	 *         The value 0 means that there are currently no road reworks.
 
	 */
 
	static int GetRoadReworkDuration(TownID town_id);
 

	
 
	/**
 
	 * Find out which company currently has the exclusive rights of this town.
 
	 * @param town_id The town to check.
 
	 * @pre IsValidTown(town_id).
 
	 * @return The company that has the exclusive rights. The value
 
	 *         AICompany::INVALID_COMPANY means that there are currently no
 
	 *         exclusive rights given out to anyone.
 
	 */
 
	static AICompany::CompanyID GetExclusiveRightsCompany(TownID town_id);
 

	
 
	/**
 
	 * Find out how long the town is under influence of the exclusive rights.
 
	 * @param town_id The town to check.
 
	 * @pre IsValidTown(town_id).
 
	 * @return The number of months the exclusive rights hold.
 
	 *         The value 0 means that there are currently no exclusive rights
 
	 *         given out to anyone.
 
	 */
 
	static int32 GetExclusiveRightsDuration(TownID town_id);
 

	
 
	/**
 
	 * Find out if an action can currently be performed on the town.
 
	 * @param town_id The town to perform the action on.
 
	 * @param town_action The action to perform on the town.
 
	 * @pre IsValidTown(town_id).
 
	 * @return True if and only if the action can performed.
 
	 */
 
	static bool IsActionAvailable(TownID town_id, TownAction town_action);
 

	
 
	/**
 
	 * Perform a town action on this town.
 
	 * @param town_id The town to perform the action on.
 
	 * @param town_action The action to perform on the town.
 
	 * @pre IsValidTown(town_id).
 
	 * @pre IsActionAvailable(town_id, town_action).
 
	 * @return True if the action succeeded.
 
	 */
 
	static bool PerformTownAction(TownID town_id, TownAction town_action);
 

	
 
	/**
 
	 * Get the rating of a company within a town.
 
	 * @param town_id The town to get the rating for.
 
	 * @param company_id The company to get the rating for.
 
	 * @pre IsValidTown(town_id).
 
	 * @pre AICompany.ResolveCompanyID(company) != AICompany::INVALID_COMPANY.
 
	 * @return The rating as shown to humans.
 
	 */
 
	static TownRating GetRating(TownID town_id, AICompany::CompanyID company_id);
 

	
 
	/**
 
	 * Get the maximum level of noise that still can be added by airports
 
	 *  before the town start to refuse building a new airport.
 
	 * @param town_id The town to get the allowed noise from.
 
	 * @return The noise that still can be added.
 
	 */
 
	static int GetAllowedNoise(TownID town_id);
 
};
 

	
 
#endif /* AI_TOWN_HPP */
src/ai/api/ai_town.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_town.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow enums to be used as Squirrel parameters */
 
	template <> AITown::TownAction GetParam(ForceType<AITown::TownAction>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AITown::TownAction)tmp; }
 
	template <> int Return<AITown::TownAction>(HSQUIRRELVM vm, AITown::TownAction res) { sq_pushinteger(vm, (int32)res); return 1; }
 
	template <> AITown::TownRating GetParam(ForceType<AITown::TownRating>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AITown::TownRating)tmp; }
 
	template <> int Return<AITown::TownRating>(HSQUIRRELVM vm, AITown::TownRating res) { sq_pushinteger(vm, (int32)res); return 1; }
 

	
 
	/* Allow AITown to be used as Squirrel parameter */
 
	template <> AITown *GetParam(ForceType<AITown *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AITown *)instance; }
 
	template <> AITown &GetParam(ForceType<AITown &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AITown *)instance; }
 
	template <> const AITown *GetParam(ForceType<const AITown *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AITown *)instance; }
 
	template <> const AITown &GetParam(ForceType<const AITown &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AITown *)instance; }
 
	template <> int Return<AITown *>(HSQUIRRELVM vm, AITown *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AITown", res, NULL, DefSQDestructorCallback<AITown>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAITown_Register(Squirrel *engine) {
 
	DefSQClass <AITown> SQAITown("AITown");
 
	SQAITown.PreRegister(engine);
 
	SQAITown.AddConstructor<void (AITown::*)(), 1>(engine, "x");
 

	
 
	SQAITown.DefSQConst(engine, AITown::TOWN_ACTION_ADVERTISE_SMALL,  "TOWN_ACTION_ADVERTISE_SMALL");
 
	SQAITown.DefSQConst(engine, AITown::TOWN_ACTION_ADVERTISE_MEDIUM, "TOWN_ACTION_ADVERTISE_MEDIUM");
 
	SQAITown.DefSQConst(engine, AITown::TOWN_ACTION_ADVERTISE_LARGE,  "TOWN_ACTION_ADVERTISE_LARGE");
 
	SQAITown.DefSQConst(engine, AITown::TOWN_ACTION_ROAD_REBUILD,     "TOWN_ACTION_ROAD_REBUILD");
 
	SQAITown.DefSQConst(engine, AITown::TOWN_ACTION_BUILD_STATUE,     "TOWN_ACTION_BUILD_STATUE");
 
	SQAITown.DefSQConst(engine, AITown::TOWN_ACTION_FUND_BUILDINGS,   "TOWN_ACTION_FUND_BUILDINGS");
 
	SQAITown.DefSQConst(engine, AITown::TOWN_ACTION_BUY_RIGHTS,       "TOWN_ACTION_BUY_RIGHTS");
 
	SQAITown.DefSQConst(engine, AITown::TOWN_ACTION_BRIBE,            "TOWN_ACTION_BRIBE");
 
	SQAITown.DefSQConst(engine, AITown::TOWN_RATING_NONE,             "TOWN_RATING_NONE");
 
	SQAITown.DefSQConst(engine, AITown::TOWN_RATING_APPALLING,        "TOWN_RATING_APPALLING");
 
	SQAITown.DefSQConst(engine, AITown::TOWN_RATING_VERY_POOR,        "TOWN_RATING_VERY_POOR");
 
	SQAITown.DefSQConst(engine, AITown::TOWN_RATING_POOR,             "TOWN_RATING_POOR");
 
	SQAITown.DefSQConst(engine, AITown::TOWN_RATING_MEDIOCRE,         "TOWN_RATING_MEDIOCRE");
 
	SQAITown.DefSQConst(engine, AITown::TOWN_RATING_GOOD,             "TOWN_RATING_GOOD");
 
	SQAITown.DefSQConst(engine, AITown::TOWN_RATING_VERY_GOOD,        "TOWN_RATING_VERY_GOOD");
 
	SQAITown.DefSQConst(engine, AITown::TOWN_RATING_EXCELLENT,        "TOWN_RATING_EXCELLENT");
 
	SQAITown.DefSQConst(engine, AITown::TOWN_RATING_OUTSTANDING,      "TOWN_RATING_OUTSTANDING");
 
	SQAITown.DefSQConst(engine, AITown::INVALID_TOWN_RATING,          "INVALID_TOWN_RATING");
 

	
 
	SQAITown.DefSQStaticMethod(engine, &AITown::GetClassName,               "GetClassName",               1, "x");
 
	SQAITown.DefSQStaticMethod(engine, &AITown::GetMaxTownID,               "GetMaxTownID",               1, "x");
 
	SQAITown.DefSQStaticMethod(engine, &AITown::GetTownCount,               "GetTownCount",               1, "x");
 
	SQAITown.DefSQStaticMethod(engine, &AITown::IsValidTown,                "IsValidTown",                2, "xi");
 
	SQAITown.DefSQStaticMethod(engine, &AITown::GetName,                    "GetName",                    2, "xi");
 
	SQAITown.DefSQStaticMethod(engine, &AITown::GetPopulation,              "GetPopulation",              2, "xi");
 
	SQAITown.DefSQStaticMethod(engine, &AITown::GetHouseCount,              "GetHouseCount",              2, "xi");
 
	SQAITown.DefSQStaticMethod(engine, &AITown::GetLocation,                "GetLocation",                2, "xi");
 
	SQAITown.DefSQStaticMethod(engine, &AITown::GetLastMonthProduction,     "GetLastMonthProduction",     3, "xii");
 
	SQAITown.DefSQStaticMethod(engine, &AITown::GetLastMonthTransported,    "GetLastMonthTransported",    3, "xii");
 
	SQAITown.DefSQStaticMethod(engine, &AITown::GetMaxProduction,           "GetMaxProduction",           3, "xii");
 
	SQAITown.DefSQStaticMethod(engine, &AITown::GetDistanceManhattanToTile, "GetDistanceManhattanToTile", 3, "xii");
 
	SQAITown.DefSQStaticMethod(engine, &AITown::GetDistanceSquareToTile,    "GetDistanceSquareToTile",    3, "xii");
 
	SQAITown.DefSQStaticMethod(engine, &AITown::IsWithinTownInfluence,      "IsWithinTownInfluence",      3, "xii");
 
	SQAITown.DefSQStaticMethod(engine, &AITown::HasStatue,                  "HasStatue",                  2, "xi");
 
	SQAITown.DefSQStaticMethod(engine, &AITown::GetRoadReworkDuration,      "GetRoadReworkDuration",      2, "xi");
 
	SQAITown.DefSQStaticMethod(engine, &AITown::GetExclusiveRightsCompany,  "GetExclusiveRightsCompany",  2, "xi");
 
	SQAITown.DefSQStaticMethod(engine, &AITown::GetExclusiveRightsDuration, "GetExclusiveRightsDuration", 2, "xi");
 
	SQAITown.DefSQStaticMethod(engine, &AITown::IsActionAvailable,          "IsActionAvailable",          3, "xii");
 
	SQAITown.DefSQStaticMethod(engine, &AITown::PerformTownAction,          "PerformTownAction",          3, "xii");
 
	SQAITown.DefSQStaticMethod(engine, &AITown::GetRating,                  "GetRating",                  3, "xii");
 
	SQAITown.DefSQStaticMethod(engine, &AITown::GetAllowedNoise,            "GetAllowedNoise",            2, "xi");
 

	
 
	SQAITown.PostRegister(engine);
 
}
src/ai/api/ai_townlist.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_townlist.cpp Implementation of AITownList and friends. */
 

	
 
#include "ai_townlist.hpp"
 
#include "../../openttd.h"
 
#include "../../town.h"
 

	
 
AITownList::AITownList()
 
{
 
	Town *t;
 
	FOR_ALL_TOWNS(t) {
 
		this->AddItem(t->index);
 
	}
 
}
src/ai/api/ai_townlist.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_townlist.hpp List all the towns. */
 

	
 
#ifndef AI_TOWNLIST_HPP
 
#define AI_TOWNLIST_HPP
 

	
 
#include "ai_abstractlist.hpp"
 

	
 
/**
 
 * Creates a list of towns that are currently on the map.
 
 * @ingroup AIList
 
 */
 
class AITownList : public AIAbstractList {
 
public:
 
	static const char *GetClassName() { return "AITownList"; }
 
	AITownList();
 
};
 

	
 
#endif /* AI_TOWNLIST_HPP */
src/ai/api/ai_townlist.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_townlist.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow AITownList to be used as Squirrel parameter */
 
	template <> AITownList *GetParam(ForceType<AITownList *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AITownList *)instance; }
 
	template <> AITownList &GetParam(ForceType<AITownList &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AITownList *)instance; }
 
	template <> const AITownList *GetParam(ForceType<const AITownList *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AITownList *)instance; }
 
	template <> const AITownList &GetParam(ForceType<const AITownList &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AITownList *)instance; }
 
	template <> int Return<AITownList *>(HSQUIRRELVM vm, AITownList *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AITownList", res, NULL, DefSQDestructorCallback<AITownList>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAITownList_Register(Squirrel *engine) {
 
	DefSQClass <AITownList> SQAITownList("AITownList");
 
	SQAITownList.PreRegister(engine, "AIAbstractList");
 
	SQAITownList.AddConstructor<void (AITownList::*)(), 1>(engine, "x");
 

	
 
	SQAITownList.DefSQStaticMethod(engine, &AITownList::GetClassName, "GetClassName", 1, "x");
 

	
 
	SQAITownList.PostRegister(engine);
 
}
src/ai/api/ai_tunnel.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_tunnel.cpp Implementation of AITunnel. */
 

	
 
#include "ai_tunnel.hpp"
 
#include "ai_map.hpp"
 
#include "ai_rail.hpp"
 
#include "../ai_instance.hpp"
 
#include "../../openttd.h"
 
#include "../../landscape.h"
 
#include "../../tunnel_map.h"
 
#include "../../road_type.h"
 
#include "../../command_func.h"
 
#include "../../tunnelbridge.h"
 
#include "../../road_func.h"
 

	
 
/* static */ bool AITunnel::IsTunnelTile(TileIndex tile)
 
{
 
	if (!::IsValidTile(tile)) return false;
 
	return ::IsTunnelTile(tile);
 
}
 

	
 
/* static */ TileIndex AITunnel::GetOtherTunnelEnd(TileIndex tile)
 
{
 
	if (!::IsValidTile(tile)) return INVALID_TILE;
 

	
 
	/* If it's a tunnel alread, take the easy way out! */
 
	if (IsTunnelTile(tile)) return ::GetOtherTunnelEnd(tile);
 

	
 
	::DoCommand(tile, 0, 0, DC_AUTO, CMD_BUILD_TUNNEL);
 
	return _build_tunnel_endtile == 0 ? INVALID_TILE : _build_tunnel_endtile;
 
}
 

	
 
static void _DoCommandReturnBuildTunnel2(class AIInstance *instance)
 
{
 
	if (!AITunnel::_BuildTunnelRoad2()) {
 
		AIObject::SetLastCommandRes(false);
 
		AIInstance::DoCommandReturn(instance);
 
		return;
 
	}
 

	
 
	/* This can never happen, as in test-mode this callback is never executed,
 
	 *  and in execute-mode, the other callback is called. */
 
	NOT_REACHED();
 
}
 

	
 
static void _DoCommandReturnBuildTunnel1(class AIInstance *instance)
 
{
 
	if (!AITunnel::_BuildTunnelRoad1()) {
 
		AIObject::SetLastCommandRes(false);
 
		AIInstance::DoCommandReturn(instance);
 
		return;
 
	}
 

	
 
	/* This can never happen, as in test-mode this callback is never executed,
 
	 *  and in execute-mode, the other callback is called. */
 
	NOT_REACHED();
 
}
 

	
 
/* static */ bool AITunnel::BuildTunnel(AIVehicle::VehicleType vehicle_type, TileIndex start)
 
{
 
	EnforcePrecondition(false, ::IsValidTile(start));
 
	EnforcePrecondition(false, vehicle_type == AIVehicle::VEHICLE_RAIL || vehicle_type == AIVehicle::VEHICLE_ROAD);
 
	EnforcePrecondition(false, vehicle_type != AIVehicle::VEHICLE_RAIL || AIRail::IsRailTypeAvailable(AIRail::GetCurrentRailType()));
 

	
 
	uint type = 0;
 
	if (vehicle_type == AIVehicle::VEHICLE_ROAD) {
 
		type |= (TRANSPORT_ROAD << 9);
 
		type |= RoadTypeToRoadTypes((::RoadType)AIObject::GetRoadType());
 
	} else {
 
		type |= (TRANSPORT_RAIL << 9);
 
		type |= AIRail::GetCurrentRailType();
 
	}
 

	
 
	/* For rail we do nothing special */
 
	if (vehicle_type == AIVehicle::VEHICLE_RAIL) {
 
		return AIObject::DoCommand(start, type, 0, CMD_BUILD_TUNNEL);
 
	}
 

	
 
	AIObject::SetCallbackVariable(0, start);
 
	if (!AIObject::DoCommand(start, type, 0, CMD_BUILD_TUNNEL, NULL, &_DoCommandReturnBuildTunnel1)) return false;
 

	
 
	/* In case of test-mode, test if we can build both road pieces */
 
	return _BuildTunnelRoad1();
 
}
 

	
 
/* static */ bool AITunnel::_BuildTunnelRoad1()
 
{
 
	/* Build the piece of road on the 'start' side of the tunnel */
 
	TileIndex end = AIObject::GetCallbackVariable(0);
 
	TileIndex start = AITunnel::GetOtherTunnelEnd(end);
 

	
 
	DiagDirection dir_1 = (DiagDirection)((::TileX(start) == ::TileX(end)) ? (::TileY(start) < ::TileY(end) ? DIAGDIR_NW : DIAGDIR_SE) : (::TileX(start) < ::TileX(end) ? DIAGDIR_NE : DIAGDIR_SW));
 
	DiagDirection dir_2 = ::ReverseDiagDir(dir_1);
 

	
 
	if (!AIObject::DoCommand(start + ::TileOffsByDiagDir(dir_1), ::DiagDirToRoadBits(dir_2) | (AIObject::GetRoadType() << 4), 0, CMD_BUILD_ROAD, NULL, &_DoCommandReturnBuildTunnel2)) return false;
 

	
 
	/* In case of test-mode, test the other road piece too */
 
	return _BuildTunnelRoad2();
 
}
 

	
 
/* static */ bool AITunnel::_BuildTunnelRoad2()
 
{
 
	/* Build the piece of road on the 'end' side of the tunnel */
 
	TileIndex end = AIObject::GetCallbackVariable(0);
 
	TileIndex start = AITunnel::GetOtherTunnelEnd(end);
 

	
 
	DiagDirection dir_1 = (DiagDirection)((::TileX(start) == ::TileX(end)) ? (::TileY(start) < ::TileY(end) ? DIAGDIR_NW : DIAGDIR_SE) : (::TileX(start) < ::TileX(end) ? DIAGDIR_NE : DIAGDIR_SW));
 
	DiagDirection dir_2 = ::ReverseDiagDir(dir_1);
 

	
 
	return AIObject::DoCommand(end + ::TileOffsByDiagDir(dir_2), ::DiagDirToRoadBits(dir_1) | (AIObject::GetRoadType() << 4), 0, CMD_BUILD_ROAD);
 
}
 

	
 
/* static */ bool AITunnel::RemoveTunnel(TileIndex tile)
 
{
 
	EnforcePrecondition(false, IsTunnelTile(tile));
 

	
 
	return AIObject::DoCommand(tile, 0, 0, CMD_LANDSCAPE_CLEAR);
 
}
src/ai/api/ai_tunnel.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_tunnel.hpp Everything to query and build tunnels. */
 

	
 
#ifndef AI_TUNNEL_HPP
 
#define AI_TUNNEL_HPP
 

	
 
#include "ai_object.hpp"
 
#include "ai_vehicle.hpp"
 

	
 
/**
 
 * Class that handles all tunnel related functions.
 
 */
 
class AITunnel : public AIObject {
 
public:
 
	static const char *GetClassName() { return "AITunnel"; }
 

	
 
	/**
 
	 * All tunnel related errors.
 
	 */
 
	enum ErrorMessages {
 

	
 
		/** Base for bridge related errors */
 
		ERR_TUNNEL_BASE = AIError::ERR_CAT_TUNNEL << AIError::ERR_CAT_BIT_SIZE,
 

	
 
		/** Can't build tunnels on water */
 
		ERR_TUNNEL_CANNOT_BUILD_ON_WATER,            // [STR_3807_CAN_T_BUILD_ON_WATER]
 

	
 
		/** The start tile must slope either North, South, West or East */
 
		ERR_TUNNEL_START_SITE_UNSUITABLE,            // [STR_500B_SITE_UNSUITABLE_FOR_TUNNEL]
 

	
 
		/** An other tunnel is in the way */
 
		ERR_TUNNEL_ANOTHER_TUNNEL_IN_THE_WAY,        // [STR_5003_ANOTHER_TUNNEL_IN_THE_WAY]
 

	
 
		/** Unable to excavate land at the end to create the tunnel's exit */
 
		ERR_TUNNEL_END_SITE_UNSUITABLE,              // [STR_5005_UNABLE_TO_EXCAVATE_LAND]
 
	};
 

	
 
	/**
 
	 * Check whether the tile is an entrance to a tunnel.
 
	 * @param tile The tile to check.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @return True if and only if the tile is the beginning or end of a tunnel.
 
	 */
 
	static bool IsTunnelTile(TileIndex tile);
 

	
 
	/**
 
	 * Get the tile that exits on the other end of a (would be) tunnel starting
 
	 *  at tile.
 
	 * @param tile The tile that is an entrance to a tunnel or the tile where you may want to build a tunnel.
 
	 * @pre AIMap::IsValidTile(tile).
 
	 * @return The TileIndex that is the other end of the (would be) tunnel, or
 
	 *  INVALID_TILE if no other end was found (can't build tunnel).
 
	 */
 
	static TileIndex GetOtherTunnelEnd(TileIndex tile);
 

	
 
#ifndef DOXYGEN_SKIP
 
	/**
 
	 * Internal function to help BuildTunnel in case of road.
 
	 */
 
	static bool _BuildTunnelRoad1();
 

	
 
	/**
 
	 * Internal function to help BuildTunnel in case of road.
 
	 */
 
	static bool _BuildTunnelRoad2();
 
#endif
 

	
 
	/**
 
	 * Builds a tunnel starting at start. The direction of the tunnel depends
 
	 *  on the slope of the start tile. Tunnels can be created for either
 
	 *  rails or roads; use the appropriate AIVehicle::VehicleType.
 
	 * As an extra for road, this functions builds two half-pieces of road on
 
	 *  each end of the tunnel, making it easier for you to connect it to your
 
	 *  network.
 
	 * @param start Where to start the tunnel.
 
	 * @param vehicle_type The vehicle-type of tunnel to build.
 
	 * @pre AIMap::IsValidTile(start).
 
	 * @pre vehicle_type == AIVehicle::VEHICLE_ROAD || (vehicle_type == AIVehicle::VEHICLE_RAIL &&
 
	 *   AIRail::IsRailTypeAvailable(AIRail::GetCurrentRailType())).
 
	 * @exception AIError::ERR_AREA_NOT_CLEAR
 
	 * @exception AITunnel::ERR_TUNNEL_CANNOT_BUILD_ON_WATER
 
	 * @exception AITunnel::ERR_TUNNEL_START_SITE_UNSUITABLE
 
	 * @exception AITunnel::ERR_TUNNEL_ANOTHER_TUNNEL_IN_THE_WAY
 
	 * @exception AITunnel::ERR_TUNNEL_END_SITE_UNSUITABLE
 
	 * @return Whether the tunnel has been/can be build or not.
 
	 * @note The slope of a tile can be determined by AITile::GetSlope(TileIndex).
 
	 * @note No matter if the road pieces were build or not, if building the
 
	 *  tunnel succeeded, this function returns true.
 
	 */
 
	static bool BuildTunnel(AIVehicle::VehicleType vehicle_type, TileIndex start);
 

	
 
	/**
 
	 * Remove the tunnel whose entrance is located at tile.
 
	 * @param tile The tile that is an entrance to a tunnel.
 
	 * @pre AIMap::IsValidTile(tile) && IsTunnelTile(tile).
 
	 * @exception AIError::ERR_OWNED_BY_ANOTHER_COMPANY
 
	 * @return Whether the tunnel has been/can be removed or not.
 
	 */
 
	static bool RemoveTunnel(TileIndex tile);
 
};
 

	
 
#endif /* AI_TUNNEL_HPP */
src/ai/api/ai_tunnel.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_tunnel.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow enums to be used as Squirrel parameters */
 
	template <> AITunnel::ErrorMessages GetParam(ForceType<AITunnel::ErrorMessages>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AITunnel::ErrorMessages)tmp; }
 
	template <> int Return<AITunnel::ErrorMessages>(HSQUIRRELVM vm, AITunnel::ErrorMessages res) { sq_pushinteger(vm, (int32)res); return 1; }
 

	
 
	/* Allow AITunnel to be used as Squirrel parameter */
 
	template <> AITunnel *GetParam(ForceType<AITunnel *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AITunnel *)instance; }
 
	template <> AITunnel &GetParam(ForceType<AITunnel &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AITunnel *)instance; }
 
	template <> const AITunnel *GetParam(ForceType<const AITunnel *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AITunnel *)instance; }
 
	template <> const AITunnel &GetParam(ForceType<const AITunnel &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AITunnel *)instance; }
 
	template <> int Return<AITunnel *>(HSQUIRRELVM vm, AITunnel *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AITunnel", res, NULL, DefSQDestructorCallback<AITunnel>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAITunnel_Register(Squirrel *engine) {
 
	DefSQClass <AITunnel> SQAITunnel("AITunnel");
 
	SQAITunnel.PreRegister(engine);
 
	SQAITunnel.AddConstructor<void (AITunnel::*)(), 1>(engine, "x");
 

	
 
	SQAITunnel.DefSQConst(engine, AITunnel::ERR_TUNNEL_BASE,                      "ERR_TUNNEL_BASE");
 
	SQAITunnel.DefSQConst(engine, AITunnel::ERR_TUNNEL_CANNOT_BUILD_ON_WATER,     "ERR_TUNNEL_CANNOT_BUILD_ON_WATER");
 
	SQAITunnel.DefSQConst(engine, AITunnel::ERR_TUNNEL_START_SITE_UNSUITABLE,     "ERR_TUNNEL_START_SITE_UNSUITABLE");
 
	SQAITunnel.DefSQConst(engine, AITunnel::ERR_TUNNEL_ANOTHER_TUNNEL_IN_THE_WAY, "ERR_TUNNEL_ANOTHER_TUNNEL_IN_THE_WAY");
 
	SQAITunnel.DefSQConst(engine, AITunnel::ERR_TUNNEL_END_SITE_UNSUITABLE,       "ERR_TUNNEL_END_SITE_UNSUITABLE");
 

	
 
	AIError::RegisterErrorMap(STR_3807_CAN_T_BUILD_ON_WATER,       AITunnel::ERR_TUNNEL_CANNOT_BUILD_ON_WATER);
 
	AIError::RegisterErrorMap(STR_500B_SITE_UNSUITABLE_FOR_TUNNEL, AITunnel::ERR_TUNNEL_START_SITE_UNSUITABLE);
 
	AIError::RegisterErrorMap(STR_5003_ANOTHER_TUNNEL_IN_THE_WAY,  AITunnel::ERR_TUNNEL_ANOTHER_TUNNEL_IN_THE_WAY);
 
	AIError::RegisterErrorMap(STR_5005_UNABLE_TO_EXCAVATE_LAND,    AITunnel::ERR_TUNNEL_END_SITE_UNSUITABLE);
 

	
 
	AIError::RegisterErrorMapString(AITunnel::ERR_TUNNEL_CANNOT_BUILD_ON_WATER,     "ERR_TUNNEL_CANNOT_BUILD_ON_WATER");
 
	AIError::RegisterErrorMapString(AITunnel::ERR_TUNNEL_START_SITE_UNSUITABLE,     "ERR_TUNNEL_START_SITE_UNSUITABLE");
 
	AIError::RegisterErrorMapString(AITunnel::ERR_TUNNEL_ANOTHER_TUNNEL_IN_THE_WAY, "ERR_TUNNEL_ANOTHER_TUNNEL_IN_THE_WAY");
 
	AIError::RegisterErrorMapString(AITunnel::ERR_TUNNEL_END_SITE_UNSUITABLE,       "ERR_TUNNEL_END_SITE_UNSUITABLE");
 

	
 
	SQAITunnel.DefSQStaticMethod(engine, &AITunnel::GetClassName,      "GetClassName",      1, "x");
 
	SQAITunnel.DefSQStaticMethod(engine, &AITunnel::IsTunnelTile,      "IsTunnelTile",      2, "xi");
 
	SQAITunnel.DefSQStaticMethod(engine, &AITunnel::GetOtherTunnelEnd, "GetOtherTunnelEnd", 2, "xi");
 
	SQAITunnel.DefSQStaticMethod(engine, &AITunnel::BuildTunnel,       "BuildTunnel",       3, "xii");
 
	SQAITunnel.DefSQStaticMethod(engine, &AITunnel::RemoveTunnel,      "RemoveTunnel",      2, "xi");
 

	
 
	SQAITunnel.PostRegister(engine);
 
}
src/ai/api/ai_types.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_types.hpp Defines all the types of the game, like VehicleID, .... */
 

	
 
#ifndef AI_TYPES_HPP
 
#define AI_TYPES_HPP
 

	
 
#include "../../core/overflowsafe_type.hpp"
 
#include "../../company_type.h"
 

	
 
/* Define all types here, so we don't have to include the whole _type.h maze */
 
typedef uint BridgeType;     //!< Internal name, not of any use for you.
 
typedef byte CargoID;        //!< The ID of a cargo.
 
class CommandCost;           //!< The cost of a command.
 
typedef uint16 EngineID;     //!< The ID of an engine.
 
typedef uint16 GroupID;      //!< The ID of a group.
 
typedef uint16 IndustryID;   //!< The ID of an industry.
 
typedef uint8 IndustryType;  //!< The ID of an industry-type.
 
typedef OverflowSafeInt64 Money; //!< Money, stored in a 32bit/64bit safe way. For AIs money is always in pounds.
 
typedef uint16 SignID;       //!< The ID of a sign.
 
typedef uint16 StationID;    //!< The ID of a station.
 
typedef uint16 StringID;     //!< The ID of a string.
 
typedef uint32 TileIndex;    //!< The ID of a tile (just named differently).
 
typedef uint16 TownID;       //!< The ID of a town.
 
typedef uint16 VehicleID;    //!< The ID of a vehicle.
 

	
 
/* Types we defined ourself, as the OpenTTD core doesn't have them (yet) */
 
typedef uint AIErrorType;    //!< The types of errors inside the NoAI framework.
 
typedef BridgeType BridgeID; //!< The ID of a bridge.
 
typedef uint16 SubsidyID;    //!< The ID of a subsidy.
 

	
 
#ifndef _SQUIRREL_H_
 
/* Life becomes easier when we can tell about a function it needs the VM, but
 
 *  without really including 'squirrel.h'. */
 
typedef struct SQVM *HSQUIRRELVM;  //!< Pointer to Squirrel Virtual Machine.
 
typedef int SQInteger;             //!< Squirrel Integer.
 
typedef struct SQObject HSQOBJECT; //!< Squirrel Object (fake declare)
 
#endif
 

	
 
#endif /* AI_TYPES_HPP */
src/ai/api/ai_vehicle.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_vehicle.cpp Implementation of AIVehicle. */
 

	
 
#include "ai_vehicle.hpp"
 
#include "ai_engine.hpp"
 
#include "ai_cargo.hpp"
 
#include "ai_order.hpp"
 
#include "ai_gamesettings.hpp"
 
#include "../ai_instance.hpp"
 
#include "../../openttd.h"
 
#include "../../company_func.h"
 
#include "../../aircraft.h"
 
#include "../../string_func.h"
 
#include "../../strings_func.h"
 
#include "../../core/alloc_func.hpp"
 
#include "../../command_func.h"
 
#include "../../roadveh.h"
 
#include "../../train.h"
 
#include "../../vehicle_func.h"
 
#include "table/strings.h"
 

	
 
/* static */ bool AIVehicle::IsValidVehicle(VehicleID vehicle_id)
 
{
 
	if (!::IsValidVehicleID(vehicle_id)) return false;
 
	const Vehicle *v = ::GetVehicle(vehicle_id);
 
	return v->owner == _current_company && (v->IsPrimaryVehicle() || (v->type == VEH_TRAIN && ::IsFreeWagon(v)));
 
}
 

	
 
/* static */ int32 AIVehicle::GetNumWagons(VehicleID vehicle_id)
 
{
 
	if (!IsValidVehicle(vehicle_id)) return -1;
 

	
 
	int num = 1;
 
	if (::GetVehicle(vehicle_id)->type == VEH_TRAIN) {
 
		const Vehicle *v = ::GetVehicle(vehicle_id);
 
		while ((v = GetNextUnit(v)) != NULL) num++;
 
	}
 

	
 
	return num;
 
}
 

	
 
/* static */ int AIVehicle::GetLength(VehicleID vehicle_id)
 
{
 
	if (!IsValidVehicle(vehicle_id)) return -1;
 

	
 
	const Vehicle *v = ::GetVehicle(vehicle_id);
 
	switch (v->type) {
 
		case VEH_ROAD: return v->u.road.cached_veh_length;
 
		case VEH_TRAIN: return v->u.rail.cached_total_length;
 
		default: return -1;
 
	}
 
}
 

	
 
/* static */ VehicleID AIVehicle::BuildVehicle(TileIndex depot, EngineID engine_id)
 
{
 
	EnforcePrecondition(INVALID_VEHICLE, AIEngine::IsValidEngine(engine_id));
 

	
 
	::VehicleType type = ::GetEngine(engine_id)->type;
 

	
 
	EnforcePreconditionCustomError(INVALID_VEHICLE, !AIGameSettings::IsDisabledVehicleType((AIVehicle::VehicleType)type), AIVehicle::ERR_VEHICLE_BUILD_DISABLED);
 

	
 
	if (!AIObject::DoCommand(depot, engine_id, 0, ::GetCmdBuildVeh(type), NULL, &AIInstance::DoCommandReturnVehicleID)) return INVALID_VEHICLE;
 

	
 
	/* In case of test-mode, we return VehicleID 0 */
 
	return 0;
 
}
 

	
 
/* static */ VehicleID AIVehicle::CloneVehicle(TileIndex depot, VehicleID vehicle_id, bool share_orders)
 
{
 
	EnforcePrecondition(false, IsValidVehicle(vehicle_id));
 

	
 
	if (!AIObject::DoCommand(depot, vehicle_id, share_orders, CMD_CLONE_VEHICLE, NULL, &AIInstance::DoCommandReturnVehicleID)) return INVALID_VEHICLE;
 

	
 
	/* In case of test-mode, we return VehicleID 0 */
 
	return 0;
 
}
 

	
 
/* static */ bool AIVehicle::MoveWagon(VehicleID source_vehicle_id, int source_wagon, bool move_attached_wagons, int dest_vehicle_id, int dest_wagon)
 
{
 
	EnforcePrecondition(false, IsValidVehicle(source_vehicle_id) && source_wagon < GetNumWagons(source_vehicle_id));
 
	EnforcePrecondition(false, dest_vehicle_id == -1 || (IsValidVehicle(dest_vehicle_id) && dest_wagon < GetNumWagons(dest_vehicle_id)));
 
	EnforcePrecondition(false, ::GetVehicle(source_vehicle_id)->type == VEH_TRAIN);
 
	EnforcePrecondition(false, dest_vehicle_id == -1 || ::GetVehicle(dest_vehicle_id)->type == VEH_TRAIN);
 

	
 
	const Vehicle *v = ::GetVehicle(source_vehicle_id);
 
	while (source_wagon-- > 0) v = GetNextUnit(v);
 
	const Vehicle *w = NULL;
 
	if (dest_vehicle_id != -1) {
 
		w = ::GetVehicle(dest_vehicle_id);
 
		while (dest_wagon-- > 0) w = GetNextUnit(w);
 
	}
 

	
 
	return AIObject::DoCommand(0, v->index | ((w == NULL ? INVALID_VEHICLE : w->index) << 16), move_attached_wagons ? 1 : 0, CMD_MOVE_RAIL_VEHICLE);
 
}
 

	
 
/* static */ int AIVehicle::GetRefitCapacity(VehicleID vehicle_id, CargoID cargo)
 
{
 
	if (!IsValidVehicle(vehicle_id)) return -1;
 
	if (!AICargo::IsValidCargo(cargo)) return -1;
 

	
 
	CommandCost res = ::DoCommand(0, vehicle_id, cargo, DC_QUERY_COST, GetCmdRefitVeh(::GetVehicle(vehicle_id)));
 
	return CmdSucceeded(res) ? _returned_refit_capacity : -1;
 
}
 

	
 
/* static */ bool AIVehicle::RefitVehicle(VehicleID vehicle_id, CargoID cargo)
 
{
 
	EnforcePrecondition(false, IsValidVehicle(vehicle_id) && AICargo::IsValidCargo(cargo));
 

	
 
	return AIObject::DoCommand(0, vehicle_id, cargo, GetCmdRefitVeh(::GetVehicle(vehicle_id)));
 
}
 

	
 

	
 
/* static */ bool AIVehicle::SellVehicle(VehicleID vehicle_id)
 
{
 
	EnforcePrecondition(false, IsValidVehicle(vehicle_id));
 

	
 
	const Vehicle *v = ::GetVehicle(vehicle_id);
 
	return AIObject::DoCommand(0, vehicle_id, v->type == VEH_TRAIN ? 1 : 0, GetCmdSellVeh(v));
 
}
 

	
 
/* static */ bool AIVehicle::SellWagon(VehicleID vehicle_id, int wagon, bool sell_attached_wagons)
 
{
 
	EnforcePrecondition(false, IsValidVehicle(vehicle_id) && wagon < GetNumWagons(vehicle_id));
 
	EnforcePrecondition(false, ::GetVehicle(vehicle_id)->type == VEH_TRAIN);
 

	
 
	const Vehicle *v = ::GetVehicle(vehicle_id);
 
	while (wagon-- > 0) v = GetNextUnit(v);
 

	
 
	return AIObject::DoCommand(0, v->index, sell_attached_wagons ? 1 : 0, CMD_SELL_RAIL_WAGON);
 
}
 

	
 
/* static */ bool AIVehicle::SendVehicleToDepot(VehicleID vehicle_id)
 
{
 
	EnforcePrecondition(false, IsValidVehicle(vehicle_id));
 

	
 
	return AIObject::DoCommand(0, vehicle_id, 0, GetCmdSendToDepot(::GetVehicle(vehicle_id)));
 
}
 

	
 
/* static */ bool AIVehicle::IsInDepot(VehicleID vehicle_id)
 
{
 
	if (!IsValidVehicle(vehicle_id)) return false;
 
	return ::GetVehicle(vehicle_id)->IsInDepot();
 
}
 

	
 
/* static */ bool AIVehicle::IsStoppedInDepot(VehicleID vehicle_id)
 
{
 
	if (!IsValidVehicle(vehicle_id)) return false;
 
	return ::GetVehicle(vehicle_id)->IsStoppedInDepot();
 
}
 

	
 
/* static */ bool AIVehicle::StartStopVehicle(VehicleID vehicle_id)
 
{
 
	EnforcePrecondition(false, IsValidVehicle(vehicle_id));
 

	
 
	return AIObject::DoCommand(0, vehicle_id, 0, CMD_START_STOP_VEHICLE);
 
}
 

	
 
/* static */ bool AIVehicle::SkipToVehicleOrder(VehicleID vehicle_id, AIOrder::OrderPosition order_position)
 
{
 
	order_position = AIOrder::ResolveOrderPosition(vehicle_id, order_position);
 

	
 
	EnforcePrecondition(false, AIOrder::IsValidVehicleOrder(vehicle_id, order_position));
 

	
 
	return AIObject::DoCommand(0, vehicle_id, order_position, CMD_SKIP_TO_ORDER);
 
}
 

	
 
/* static */ bool AIVehicle::ReverseVehicle(VehicleID vehicle_id)
 
{
 
	EnforcePrecondition(false, IsValidVehicle(vehicle_id));
 
	EnforcePrecondition(false, ::GetVehicle(vehicle_id)->type == VEH_ROAD || ::GetVehicle(vehicle_id)->type == VEH_TRAIN);
 

	
 
	switch (::GetVehicle(vehicle_id)->type) {
 
		case VEH_ROAD: return AIObject::DoCommand(0, vehicle_id, 0, CMD_TURN_ROADVEH);
 
		case VEH_TRAIN: return AIObject::DoCommand(0, vehicle_id, 0, CMD_REVERSE_TRAIN_DIRECTION);
 
		default: NOT_REACHED();
 
	}
 
}
 

	
 
/* static */ bool AIVehicle::SetName(VehicleID vehicle_id, const char *name)
 
{
 
	EnforcePrecondition(false, IsValidVehicle(vehicle_id));
 
	EnforcePrecondition(false, !::StrEmpty(name));
 
	EnforcePreconditionCustomError(false, ::strlen(name) < MAX_LENGTH_VEHICLE_NAME_BYTES, AIError::ERR_PRECONDITION_STRING_TOO_LONG);
 

	
 
	return AIObject::DoCommand(0, vehicle_id, 0, CMD_RENAME_VEHICLE, name);
 
}
 

	
 
/* static */ TileIndex AIVehicle::GetLocation(VehicleID vehicle_id)
 
{
 
	if (!IsValidVehicle(vehicle_id)) return INVALID_TILE;
 

	
 
	const Vehicle *v = ::GetVehicle(vehicle_id);
 
	if (v->type == VEH_AIRCRAFT) {
 
		uint x = Clamp(v->x_pos / TILE_SIZE, 0, ::MapSizeX() - 2);
 
		uint y = Clamp(v->y_pos / TILE_SIZE, 0, ::MapSizeY() - 2);
 
		return ::TileXY(x, y);
 
	}
 

	
 
	return v->tile;
 
}
 

	
 
/* static */ EngineID AIVehicle::GetEngineType(VehicleID vehicle_id)
 
{
 
	if (!IsValidVehicle(vehicle_id)) return INVALID_ENGINE;
 

	
 
	return ::GetVehicle(vehicle_id)->engine_type;
 
}
 

	
 
/* static */ EngineID AIVehicle::GetWagonEngineType(VehicleID vehicle_id, int wagon)
 
{
 
	if (!IsValidVehicle(vehicle_id)) return INVALID_ENGINE;
 
	if (wagon >= GetNumWagons(vehicle_id)) return INVALID_ENGINE;
 

	
 
	const Vehicle *v = ::GetVehicle(vehicle_id);
 
	if (v->type == VEH_TRAIN) {
 
		while (wagon-- > 0) v = GetNextUnit(v);
 
	}
 
	return v->engine_type;
 
}
 

	
 
/* static */ int32 AIVehicle::GetUnitNumber(VehicleID vehicle_id)
 
{
 
	if (!IsValidVehicle(vehicle_id)) return -1;
 

	
 
	return ::GetVehicle(vehicle_id)->unitnumber;
 
}
 

	
 
/* static */ const char *AIVehicle::GetName(VehicleID vehicle_id)
 
{
 
	if (!IsValidVehicle(vehicle_id)) return NULL;
 

	
 
	static const int len = 64;
 
	char *vehicle_name = MallocT<char>(len);
 

	
 
	::SetDParam(0, vehicle_id);
 
	::GetString(vehicle_name, STR_VEHICLE_NAME, &vehicle_name[len - 1]);
 
	return vehicle_name;
 
}
 

	
 
/* static */ int32 AIVehicle::GetAge(VehicleID vehicle_id)
 
{
 
	if (!IsValidVehicle(vehicle_id)) return -1;
 

	
 
	return ::GetVehicle(vehicle_id)->age;
 
}
 

	
 
/* static */ int32 AIVehicle::GetWagonAge(VehicleID vehicle_id, int wagon)
 
{
 
	if (!IsValidVehicle(vehicle_id)) return -1;
 
	if (wagon >= GetNumWagons(vehicle_id)) return -1;
 

	
 
	const Vehicle *v = ::GetVehicle(vehicle_id);
 
	if (v->type == VEH_TRAIN) {
 
		while (wagon-- > 0) v = GetNextUnit(v);
 
	}
 
	return v->age;
 
}
 

	
 
/* static */ int32 AIVehicle::GetMaxAge(VehicleID vehicle_id)
 
{
 
	if (!IsValidVehicle(vehicle_id)) return -1;
 

	
 
	return ::GetVehicle(vehicle_id)->max_age;
 
}
 

	
 
/* static */ int32 AIVehicle::GetAgeLeft(VehicleID vehicle_id)
 
{
 
	if (!IsValidVehicle(vehicle_id)) return -1;
 

	
 
	return ::GetVehicle(vehicle_id)->max_age - ::GetVehicle(vehicle_id)->age;
 
}
 

	
 
/* static */ int32 AIVehicle::GetCurrentSpeed(VehicleID vehicle_id)
 
{
 
	if (!IsValidVehicle(vehicle_id)) return -1;
 

	
 
	return ::GetVehicle(vehicle_id)->GetDisplaySpeed();
 
}
 

	
 
/* static */ AIVehicle::VehicleState AIVehicle::GetState(VehicleID vehicle_id)
 
{
 
	if (!IsValidVehicle(vehicle_id)) return AIVehicle::VS_INVALID;
 

	
 
	const Vehicle *v = ::GetVehicle(vehicle_id);
 
	byte vehstatus = v->vehstatus;
 

	
 
	if (vehstatus & ::VS_CRASHED) return AIVehicle::VS_CRASHED;
 
	if (v->breakdown_ctr != 0) return AIVehicle::VS_BROKEN;
 
	if (v->IsStoppedInDepot()) return AIVehicle::VS_IN_DEPOT;
 
	if (vehstatus & ::VS_STOPPED) return AIVehicle::VS_STOPPED;
 
	if (v->current_order.IsType(OT_LOADING)) return AIVehicle::VS_AT_STATION;
 
	return AIVehicle::VS_RUNNING;
 
}
 

	
 
/* static */ Money AIVehicle::GetRunningCost(VehicleID vehicle_id)
 
{
 
	if (!IsValidVehicle(vehicle_id)) return -1;
 

	
 
	return ::GetVehicle(vehicle_id)->GetRunningCost() >> 8;
 
}
 

	
 
/* static */ Money AIVehicle::GetProfitThisYear(VehicleID vehicle_id)
 
{
 
	if (!IsValidVehicle(vehicle_id)) return -1;
 

	
 
	return ::GetVehicle(vehicle_id)->GetDisplayProfitThisYear();
 
}
 

	
 
/* static */ Money AIVehicle::GetProfitLastYear(VehicleID vehicle_id)
 
{
 
	if (!IsValidVehicle(vehicle_id)) return -1;
 

	
 
	return ::GetVehicle(vehicle_id)->GetDisplayProfitLastYear();
 
}
 

	
 
/* static */ Money AIVehicle::GetCurrentValue(VehicleID vehicle_id)
 
{
 
	if (!IsValidVehicle(vehicle_id)) return -1;
 

	
 
	return ::GetVehicle(vehicle_id)->value;
 
}
 

	
 
/* static */ AIVehicle::VehicleType AIVehicle::GetVehicleType(VehicleID vehicle_id)
 
{
 
	if (!IsValidVehicle(vehicle_id)) return VEHICLE_INVALID;
 

	
 
	switch (::GetVehicle(vehicle_id)->type) {
 
		case VEH_ROAD:     return VEHICLE_ROAD;
 
		case VEH_TRAIN:    return VEHICLE_RAIL;
 
		case VEH_SHIP:     return VEHICLE_WATER;
 
		case VEH_AIRCRAFT: return VEHICLE_AIR;
 
		default:           return VEHICLE_INVALID;
 
	}
 
}
 

	
 
/* static */ AIRoad::RoadType AIVehicle::GetRoadType(VehicleID vehicle_id)
 
{
 
	if (!IsValidVehicle(vehicle_id)) return AIRoad::ROADTYPE_INVALID;
 
	if (GetVehicleType(vehicle_id) != VEHICLE_ROAD) return AIRoad::ROADTYPE_INVALID;
 

	
 
	return (AIRoad::RoadType)::GetVehicle(vehicle_id)->u.road.roadtype;
 
}
 

	
 
/* static */ int32 AIVehicle::GetCapacity(VehicleID vehicle_id, CargoID cargo)
 
{
 
	if (!IsValidVehicle(vehicle_id)) return -1;
 
	if (!AICargo::IsValidCargo(cargo)) return -1;
 

	
 
	uint32 amount = 0;
 
	for (const Vehicle *v = ::GetVehicle(vehicle_id); v != NULL; v = v->Next()) {
 
		if (v->cargo_type == cargo) amount += v->cargo_cap;
 
	}
 

	
 
	return amount;
 
}
 

	
 
/* static */ int32 AIVehicle::GetCargoLoad(VehicleID vehicle_id, CargoID cargo)
 
{
 
	if (!IsValidVehicle(vehicle_id)) return -1;
 
	if (!AICargo::IsValidCargo(cargo)) return -1;
 

	
 
	uint32 amount = 0;
 
	for (const Vehicle *v = ::GetVehicle(vehicle_id); v != NULL; v = v->Next()) {
 
		if (v->cargo_type == cargo) amount += v->cargo.Count();
 
	}
 

	
 
	return amount;
 
}
 

	
 
/* static */ GroupID AIVehicle::GetGroupID(VehicleID vehicle_id)
 
{
 
	if (!IsValidVehicle(vehicle_id)) return ::INVALID_GROUP;
 

	
 
	return ::GetVehicle(vehicle_id)->group_id;
 
}
 

	
 
/* static */ bool AIVehicle::IsArticulated(VehicleID vehicle_id)
 
{
 
	if (!IsValidVehicle(vehicle_id)) return false;
 
	if (GetVehicleType(vehicle_id) != VEHICLE_ROAD && GetVehicleType(vehicle_id) != VEHICLE_RAIL) return false;
 

	
 
	const Vehicle *v = ::GetVehicle(vehicle_id);
 
	switch (v->type) {
 
		case VEH_ROAD: return RoadVehHasArticPart(v);
 
		case VEH_TRAIN: return EngineHasArticPart(v);
 
		default: NOT_REACHED();
 
	}
 
}
src/ai/api/ai_vehicle.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_vehicle.hpp Everything to query and build vehicles. */
 

	
 
#ifndef AI_VEHICLE_HPP
 
#define AI_VEHICLE_HPP
 

	
 
#include "ai_object.hpp"
 
#include "ai_error.hpp"
 
#include "ai_road.hpp"
 
#include "ai_order.hpp"
 

	
 
/**
 
 * Class that handles all vehicle related functions.
 
 */
 
class AIVehicle : public AIObject {
 
public:
 
	static const char *GetClassName() { return "AIVehicle"; }
 

	
 
	/**
 
	 * All vehicle related error messages.
 
	 */
 
	enum ErrorMessages {
 
		/** Base for vehicle related errors */
 
		ERR_VEHICLE_BASE = AIError::ERR_CAT_VEHICLE << AIError::ERR_CAT_BIT_SIZE,
 

	
 
		/** Too many vehicles in the game, can't build any more. */
 
		ERR_VEHICLE_TOO_MANY,                   // [STR_00E1_TOO_MANY_VEHICLES_IN_GAME]
 

	
 
		/** Vehicle is not available */
 
		ERR_VEHICLE_NOT_AVAILABLE,              // [STR_AIRCRAFT_NOT_AVAILABLE, STR_ROAD_VEHICLE_NOT_AVAILABLE, STR_SHIP_NOT_AVAILABLE, STR_RAIL_VEHICLE_NOT_AVAILABLE]
 

	
 
		/** Vehicle can't be build due to game settigns */
 
		ERR_VEHICLE_BUILD_DISABLED,             // [STR_A008_CAN_T_BUILD_AIRCRAFT, STR_980D_CAN_T_BUILD_SHIP, STR_9009_CAN_T_BUILD_ROAD_VEHICLE, STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE]
 

	
 
		/** Vehicle can't be build in the selected depot */
 
		ERR_VEHICLE_WRONG_DEPOT,                // [STR_DEPOT_WRONG_DEPOT_TYPE]
 

	
 
		/** Vehicle can't return to the depot */
 
		ERR_VEHICLE_CANNOT_SEND_TO_DEPOT,       // [STR_8830_CAN_T_SEND_TRAIN_TO_DEPOT, STR_9018_CAN_T_SEND_VEHICLE_TO_DEPOT, STR_9819_CAN_T_SEND_SHIP_TO_DEPOT, STR_A012_CAN_T_SEND_AIRCRAFT_TO]
 

	
 
		/** Vehicle can't start / stop */
 
		ERR_VEHICLE_CANNOT_START_STOP,          // [STR_883B_CAN_T_STOP_START_TRAIN, STR_9015_CAN_T_STOP_START_ROAD_VEHICLE, STR_9818_CAN_T_STOP_START_SHIP, STR_A016_CAN_T_STOP_START_AIRCRAFT]
 

	
 
		/** Vehicle can't turn */
 
		ERR_VEHICLE_CANNOT_TURN,                // [STR_8869_CAN_T_REVERSE_DIRECTION, STR_9033_CAN_T_MAKE_VEHICLE_TURN]
 

	
 
		/** Vehicle can't be refit */
 
		ERR_VEHICLE_CANNOT_REFIT,               // [STR_RAIL_CAN_T_REFIT_VEHICLE, STR_REFIT_ROAD_VEHICLE_CAN_T, STR_9841_CAN_T_REFIT_SHIP, STR_A042_CAN_T_REFIT_AIRCRAFT]
 

	
 
		/** Vehicle is destroyed */
 
		ERR_VEHICLE_IS_DESTROYED,               // [STR_CAN_T_REFIT_DESTROYED_VEHICLE, STR_CAN_T_SELL_DESTROYED_VEHICLE]
 

	
 
		/** Vehicle is not in a depot */
 
		ERR_VEHICLE_NOT_IN_DEPOT,               // [STR_A01B_AIRCRAFT_MUST_BE_STOPPED, STR_9013_MUST_BE_STOPPED_INSIDE, STR_TRAIN_MUST_BE_STOPPED, STR_980B_SHIP_MUST_BE_STOPPED_IN]
 

	
 
		/** Vehicle is flying */
 
		ERR_VEHICLE_IN_FLIGHT,                  // [STR_A017_AIRCRAFT_IS_IN_FLIGHT]
 

	
 
		/** Vehicle is without power */
 
		ERR_VEHCILE_NO_POWER,                   // [STR_TRAIN_START_NO_CATENARY]
 

	
 
	};
 

	
 
	/**
 
	 * The type of a vehicle available in the game. Trams for example are
 
	 *  road vehicles, as maglev is a rail vehicle.
 
	 */
 
	enum VehicleType {
 
		/* Order IS important, as it now matches the internal state of the game for vehicle type */
 
		VEHICLE_RAIL,           //!< Rail type vehicle.
 
		VEHICLE_ROAD,           //!< Road type vehicle (bus / truck).
 
		VEHICLE_WATER,          //!< Water type vehicle.
 
		VEHICLE_AIR,            //!< Air type vehicle.
 
		VEHICLE_INVALID = 0xFF, //!< Invalid vehicle type.
 
	};
 

	
 
	/**
 
	 * The different states a vehicle can be in.
 
	 */
 
	enum VehicleState {
 
		VS_RUNNING,        //!< The vehicle is currently running.
 
		VS_STOPPED,        //!< The vehicle is stopped manually.
 
		VS_IN_DEPOT,       //!< The vehicle is stopped in the depot.
 
		VS_AT_STATION,     //!< The vehicle is stopped at a station and is currently loading or unloading.
 
		VS_BROKEN,         //!< The vehicle has broken down and will start running again in a while.
 
		VS_CRASHED,        //!< The vehicle is crashed (and will never run again).
 

	
 
		VS_INVALID = 0xFF, //!< An invalid vehicle state.
 
	};
 

	
 
	/**
 
	 * Checks whether the given vehicle is valid and owned by you.
 
	 * @param vehicle_id The vehicle to check.
 
	 * @return True if and only if the vehicle is valid.
 
	 */
 
	static bool IsValidVehicle(VehicleID vehicle_id);
 

	
 
	/**
 
	 * Get the number of wagons a vehicle has.
 
	 * @param vehicle_id The vehicle to get the number of wagons from.
 
	 * @pre IsValidVehicle(vehicle_id).
 
	 * @return The number of wagons the vehicle has.
 
	 */
 
	static int32 GetNumWagons(VehicleID vehicle_id);
 

	
 
	/**
 
	 * Set the name of a vehicle.
 
	 * @param vehicle_id The vehicle to set the name for.
 
	 * @param name The name for the vehicle.
 
	 * @pre IsValidVehicle(vehicle_id).
 
	 * @pre 'name' must have at least one character.
 
	 * @pre 'name' must have at most 30 characters.
 
	 * @exception AIError::ERR_NAME_IS_NOT_UNIQUE
 
	 * @return True if and only if the name was changed.
 
	 */
 
	static bool SetName(VehicleID vehicle_id, const char *name);
 

	
 
	/**
 
	 * Get the name of a vehicle.
 
	 * @param vehicle_id The vehicle to get the name of.
 
	 * @pre IsValidVehicle(vehicle_id).
 
	 * @return The name the vehicle has.
 
	 */
 
	static const char *GetName(VehicleID vehicle_id);
 

	
 
	/**
 
	 * Get the current location of a vehicle.
 
	 * @param vehicle_id The vehicle to get the location of.
 
	 * @pre IsValidVehicle(vehicle_id).
 
	 * @return The tile the vehicle is currently on.
 
	 */
 
	static TileIndex GetLocation(VehicleID vehicle_id);
 

	
 
	/**
 
	 * Get the engine-type of a vehicle.
 
	 * @param vehicle_id The vehicle to get the engine-type of.
 
	 * @pre IsValidVehicle(vehicle_id).
 
	 * @return The engine type the vehicle has.
 
	 */
 
	static EngineID GetEngineType(VehicleID vehicle_id);
 

	
 
	/**
 
	 * Get the engine-type of a wagon.
 
	 * @param vehicle_id The vehicle to get the engine-type of.
 
	 * @param wagon The wagon in the vehicle to get the engine-type of.
 
	 * @pre IsValidVehicle(vehicle_id).
 
	 * @pre wagon < GetNumWagons(vehicle_id).
 
	 * @return The engine type the vehicle has.
 
	 */
 
	static EngineID GetWagonEngineType(VehicleID vehicle_id, int wagon);
 

	
 
	/**
 
	 * Get the unitnumber of a vehicle.
 
	 * @param vehicle_id The vehicle to get the unitnumber of.
 
	 * @pre IsValidVehicle(vehicle_id).
 
	 * @return The unitnumber the vehicle has.
 
	 */
 
	static int32 GetUnitNumber(VehicleID vehicle_id);
 

	
 
	/**
 
	 * Get the current age of a vehicle.
 
	 * @param vehicle_id The vehicle to get the age of.
 
	 * @pre IsValidVehicle(vehicle_id).
 
	 * @return The current age the vehicle has.
 
	 * @note The age is in days.
 
	 */
 
	static int32 GetAge(VehicleID vehicle_id);
 

	
 
	/**
 
	 * Get the current age of a second (or third, etc.) engine in a train vehicle.
 
	 * @param vehicle_id The vehicle to get the age of.
 
	 * @param wagon The wagon in the vehicle to get the age of.
 
	 * @pre IsValidVehicle(vehicle_id).
 
	 * @pre wagon < GetNumWagons(vehicle_id).
 
	 * @return The current age the vehicle has.
 
	 * @note The age is in days.
 
	 */
 
	static int32 GetWagonAge(VehicleID vehicle_id, int wagon);
 

	
 
	/**
 
	 * Get the maximum age of a vehicle.
 
	 * @param vehicle_id The vehicle to get the age of.
 
	 * @pre IsValidVehicle(vehicle_id).
 
	 * @return The maximum age the vehicle has.
 
	 * @note The age is in days.
 
	 */
 
	static int32 GetMaxAge(VehicleID vehicle_id);
 

	
 
	/**
 
	 * Get the age a vehicle has left (maximum - current).
 
	 * @param vehicle_id The vehicle to get the age of.
 
	 * @pre IsValidVehicle(vehicle_id).
 
	 * @return The age the vehicle has left.
 
	 * @note The age is in days.
 
	 */
 
	static int32 GetAgeLeft(VehicleID vehicle_id);
 

	
 
	/**
 
	 * Get the current speed of a vehicle.
 
	 * @param vehicle_id The vehicle to get the age of.
 
	 * @pre IsValidVehicle(vehicle_id).
 
	 * @return The current speed of the vehicle.
 
	 * @note Speed is in km/h.
 
	 */
 
	static int32 GetCurrentSpeed(VehicleID vehicle_id);
 

	
 
	/**
 
	 * Get the current state of a vehicle.
 
	 * @param vehicle_id The vehicle to get the state of.
 
	 * @pre IsValidVehicle(vehicle_id).
 
	 * @return The current state of the vehicle.
 
	 */
 
	static VehicleState GetState(VehicleID vehicle_id);
 

	
 
	/**
 
	 * Get the running cost of this vehicle.
 
	 * @param vehicle_id The vehicle to get the age of.
 
	 * @pre IsValidVehicle(vehicle_id).
 
	 * @return The running cost of the vehicle per year.
 
	 * @note Cost is per year; divide by 364 to get per day.
 
	 * @note This is not equal to AIEngine::GetRunningCost for Trains, because
 
	 *   wagons and second engines can add up in the calculation too.
 
	 */
 
	static Money GetRunningCost(VehicleID vehicle_id);
 

	
 
	/**
 
	 * Get the current profit of a vehicle.
 
	 * @param vehicle_id The vehicle to get the profit of.
 
	 * @pre IsValidVehicle(vehicle_id).
 
	 * @return The current profit the vehicle has.
 
	 */
 
	static Money GetProfitThisYear(VehicleID vehicle_id);
 

	
 
	/**
 
	 * Get the profit of last year of a vehicle.
 
	 * @param vehicle_id The vehicle to get the profit of.
 
	 * @pre IsValidVehicle(vehicle_id).
 
	 * @return The profit the vehicle had last year.
 
	 */
 
	static Money GetProfitLastYear(VehicleID vehicle_id);
 

	
 

	
 
	/**
 
	 * Get the current value of a vehicle.
 
	 * @param vehicle_id The vehicle to get the value of.
 
	 * @pre IsValidVehicle(vehicle_id).
 
	 * @return The value the vehicle currently has (the amount you should get
 
	 *  when you would sell the vehicle right now).
 
	 */
 
	static Money GetCurrentValue(VehicleID vehicle_id);
 

	
 
	/**
 
	 * Get the type of vehicle.
 
	 * @param vehicle_id The vehicle to get the type of.
 
	 * @pre IsValidVehicle(vehicle_id).
 
	 * @return The vehicle type.
 
	 */
 
	static AIVehicle::VehicleType GetVehicleType(VehicleID vehicle_id);
 

	
 
	/**
 
	 * Get the RoadType of the vehicle.
 
	 * @param vehicle_id The vehicle to get the RoadType of.
 
	 * @pre IsValidVehicle(vehicle_id).
 
	 * @pre GetVehicleType(vehicle_id) == VEHICLE_ROAD.
 
	 * @return The RoadType the vehicle has.
 
	 */
 
	static AIRoad::RoadType GetRoadType(VehicleID vehicle_id);
 

	
 
	/**
 
	 * Check if a vehicle is in a depot.
 
	 * @param vehicle_id The vehicle to check.
 
	 * @pre IsValidVehicle(vehicle_id).
 
	 * @return True if and only if the vehicle is in a depot.
 
	 */
 
	static bool IsInDepot(VehicleID vehicle_id);
 

	
 
	/**
 
	 * Check if a vehicle is in a depot and stopped.
 
	 * @param vehicle_id The vehicle to check.
 
	 * @pre IsValidVehicle(vehicle_id).
 
	 * @return True if and only if the vehicle is in a depot and stopped.
 
	 */
 
	static bool IsStoppedInDepot(VehicleID vehicle_id);
 

	
 
	/**
 
	 * Builds a vehicle with the given engine at the given depot.
 
	 * @param depot The depot where the vehicle will be build.
 
	 * @param engine_id The engine to use for this vehicle.
 
	 * @pre The tile at depot has a depot that can build the engine and
 
	 *   is owned by you.
 
	 * @pre IsValidEngine(engine_id).
 
	 * @exception AIVehicle::ERR_VEHICLE_TOO_MANY
 
	 * @exception AIVehicle::ERR_VEHICLE_BUILD_DISABLED
 
	 * @exception AIVehicle::ERR_VEHICLE_WRONG_DEPOT
 
	 * @return The VehicleID of the new vehicle, or an invalid VehicleID when
 
	 *   it failed. Check the return value using IsValidVehicle. In test-mode
 
	 *   0 is returned if it was successful; any other value indicates failure.
 
	 * @note In Test Mode it means you can't assign orders yet to this vehicle,
 
	 *   as the vehicle isn't really built yet. Build it for real first before
 
	 *   assigning orders.
 
	 */
 
	static VehicleID BuildVehicle(TileIndex depot, EngineID engine_id);
 

	
 
	/**
 
	 * Clones a vehicle at the given depot, copying or cloning it's orders.
 
	 * @param depot The depot where the vehicle will be build.
 
	 * @param vehicle_id The vehicle to use as example for the new vehicle.
 
	 * @param share_orders Should the orders be copied or shared?
 
	 * @pre The tile 'depot' has a depot on it, allowing 'vehicle_id'-type vehicles.
 
	 * @pre IsValidVehicle(vehicle_id).
 
	 * @exception AIVehicle::ERR_VEHICLE_TOO_MANY
 
	 * @exception AIVehicle::ERR_VEHICLE_BUILD_DISABLED
 
	 * @exception AIVehicle::ERR_VEHICLE_WRONG_DEPOT
 
	 * @return The VehicleID of the new vehicle, or an invalid VehicleID when
 
	 *   it failed. Check the return value using IsValidVehicle. In test-mode
 
	 *   0 is returned if it was successful; any other value indicates failure.
 
	 */
 
	static VehicleID CloneVehicle(TileIndex depot, VehicleID vehicle_id, bool share_orders);
 

	
 
	/**
 
	 * Move a wagon after another wagon.
 
	 * @param source_vehicle_id The vehicle to move a wagon away from.
 
	 * @param source_wagon The wagon in source_vehicle to move.
 
	 * @param move_attached_wagons Also move all wagons attached to the wagon to move.
 
	 * @param dest_vehicle_id The vehicle to move the wagon to, or -1 to create a new vehicle.
 
	 * @param dest_wagon The wagon in dest_vehicle to place source_wagon after.
 
	 * @pre IsValidVehicle(source_vehicle_id).
 
	 * @pre source_wagon < GetNumWagons(source_vehicle_id).
 
	 * @pre dest_vehicle_id == -1 || (IsValidVehicle(dest_vehicle_id) && dest_wagon < GetNumWagons(dest_vehicle_id)).
 
	 * @pre GetVehicleType(source_vehicle_id) == VEHICLE_RAIL.
 
	 * @pre dest_vehicle_id == -1 || GetVehicleType(dest_vehicle_id) == VEHICLE_RAIL.
 
	 * @return Whether or not moving the wagon(s) succeeded.
 
	 */
 
	static bool MoveWagon(VehicleID source_vehicle_id, int source_wagon, bool move_attached_wagons, int dest_vehicle_id, int dest_wagon);
 

	
 
	/**
 
	 * Gets the capacity of the given vehicle when refited to the given cargo type.
 
	 * @param vehicle_id The vehicle to refit.
 
	 * @param cargo The cargo to refit to.
 
	 * @pre IsValidVehicle(vehicle_id).
 
	 * @pre AICargo::IsValidCargo(cargo).
 
	 * @pre You must own the vehicle.
 
	 * @pre The vehicle must be stopped in the depot.
 
	 * @return The capacity the vehicle will have when refited.
 
	 */
 
	static int GetRefitCapacity(VehicleID vehicle_id, CargoID cargo);
 

	
 
	/**
 
	 * Refits a vehicle to the given cargo type.
 
	 * @param vehicle_id The vehicle to refit.
 
	 * @param cargo The cargo to refit to.
 
	 * @pre IsValidVehicle(vehicle_id).
 
	 * @pre AICargo::IsValidCargo(cargo).
 
	 * @pre You must own the vehicle.
 
	 * @pre The vehicle must be stopped in the depot.
 
	 * @exception AIVehicle::ERR_VEHICLE_CANNOT_REFIT
 
	 * @exception AIVehicle::ERR_VEHICLE_IS_DESTROYED
 
	 * @exception AIVehicle::ERR_VEHICLE_NOT_IN_DEPOT
 
	 * @return True if and only if the refit succeeded.
 
	 */
 
	static bool RefitVehicle(VehicleID vehicle_id, CargoID cargo);
 

	
 
	/**
 
	 * Sells the given vehicle.
 
	 * @param vehicle_id The vehicle to sell.
 
	 * @pre IsValidVehicle(vehicle_id).
 
	 * @pre You must own the vehicle.
 
	 * @pre The vehicle must be stopped in the depot.
 
	 * @exception AIVehicle::ERR_VEHICLE_IS_DESTROYED
 
	 * @exception AIVehicle::ERR_VEHICLE_NOT_IN_DEPOT
 
	 * @return True if and only if the vehicle has been sold.
 
	 */
 
	static bool SellVehicle(VehicleID vehicle_id);
 

	
 
	/**
 
	 * Sells the given wagon from the vehicle.
 
	 * @param vehicle_id The vehicle to sell a wagon from.
 
	 * @param wagon The wagon to sell.
 
	 * @param sell_attached_wagons Sell all wagons attached to the one we want to sell.
 
	 * @pre IsValidVehicle(vehicle_id).
 
	 * @pre wagon < GetNumWagons(vehicle_id).
 
	 * @pre You must own the vehicle.
 
	 * @pre The vehicle must be stopped in the depot.
 
	 * @exception AIVehicle::ERR_VEHICLE_IS_DESTROYED
 
	 * @exception AIVehicle::ERR_VEHICLE_NOT_IN_DEPOT
 
	 * @return True if and only if the wagon(s) has been sold.
 
	 */
 
	static bool SellWagon(VehicleID vehicle_id, int wagon, bool sell_attached_wagons);
 

	
 
	/**
 
	 * Sends the given vehicle to a depot.
 
	 * @param vehicle_id The vehicle to send to a depot.
 
	 * @pre IsValidVehicle(vehicle_id).
 
	 * @exception AIVehicle::ERR_VEHICLE_CANNOT_SEND_TO_DEPOT
 
	 * @return True if and only if the vehicle has been sent to a depot.
 
	 */
 
	static bool SendVehicleToDepot(VehicleID vehicle_id);
 

	
 
	/**
 
	 * Starts or stops the given vehicle depending on the current state.
 
	 * @param vehicle_id The vehicle to start/stop.
 
	 * @pre IsValidVehicle(vehicle_id).
 
	 * @exception AIVehicle::ERR_VEHICLE_CANNOT_START_STOP
 
	 * @exception (For aircraft only): AIVehicle::ERR_VEHICLE_IN_FLIGHT
 
	 * @exception (For trains only): AIVehicle::ERR_VEHICLE_NO_POWER
 
	 * @return True if and only if the vehicle has been started or stopped.
 
	 */
 
	static bool StartStopVehicle(VehicleID vehicle_id);
 

	
 
	/**
 
	 * Skips the current order of the given vehicle.
 
	 * @param vehicle_id The vehicle to skip the order for.
 
	 * @param order_position The selected order to which we want to skip.
 
	 * @pre IsValidVehicleOrder(vehicle_id, order_position).
 
	 * @return True if and only if the order has been skipped.
 
	 */
 
	static bool SkipToVehicleOrder(VehicleID vehicle_id, AIOrder::OrderPosition order_position);
 

	
 
	/**
 
	 * Turn the given vehicle so it'll drive the other way.
 
	 * @param vehicle_id The vehicle to turn.
 
	 * @pre IsValidVehicle(vehicle_id).
 
	 * @pre GetVehicleType(vehicle_id) == VEHICLE_ROAD || GetVehicleType(vehicle_id) == VEHICLE_RAIL.
 
	 * @return True if and only if the vehicle has started to turn.
 
	 * @note Vehicles cannot always be reversed. For example busses and trucks need to be running
 
	 *  and not be inside a depot.
 
	 */
 
	static bool ReverseVehicle(VehicleID vehicle_id);
 

	
 
	/**
 
	 * Get the maximum amount of a specific cargo the given vehicle can transport.
 
	 * @param vehicle_id The vehicle to get the capacity of.
 
	 * @param cargo The cargo to get the capacity for.
 
	 * @pre IsValidVehicle(vehicle_id).
 
	 * @pre AICargo::IsValidCargo(cargo).
 
	 * @return The maximum amount of the given cargo the vehicle can transport.
 
	 */
 
	static int32 GetCapacity(VehicleID vehicle_id, CargoID cargo);
 

	
 
	/**
 
	 * Get the length of a the total vehicle in 1/16's of a tile.
 
	 * @param vehicle_id The vehicle to get the length of.
 
	 * @pre IsValidVehicle(vehicle_id).
 
	 * @pre GetVehicleType(vehicle_id) == AIVehicle.VEHICLE_ROAD || GetVehicleType(vehicle_id) == AIVehicle.VEHICLE_RAIL.
 
	 * @return The length of the engine.
 
	 */
 
	static int GetLength(VehicleID vehicle_id);
 

	
 
	/**
 
	 * Get the amount of a specific cargo the given vehicle transports.
 
	 * @param vehicle_id The vehicle to get the load amount of.
 
	 * @param cargo The cargo to get the load amount for.
 
	 * @pre IsValidVehicle(vehicle_id).
 
	 * @pre AICargo::IsValidCargo(cargo).
 
	 * @return The amount of the given cargo the vehicle currently transports.
 
	 */
 
	static int32 GetCargoLoad(VehicleID vehicle_id, CargoID cargo);
 

	
 
	/**
 
	 * Get the group of a given vehicle.
 
	 * @param vehicle_id The vehicle to get the group from.
 
	 * @return The group of the given vehicle.
 
	 */
 
	static GroupID GetGroupID(VehicleID vehicle_id);
 

	
 
	/**
 
	 * Check if the vehicle is articulated.
 
	 * @param vehicle_id The vehicle to check.
 
	 * @pre IsValidVehicle(vehicle_id).
 
	 * @pre GetVehicleType(vehicle_id) == VEHICLE_ROAD || GetVehicleType(vehicle_id) == VEHICLE_RAIL.
 
	 * @return True if the vehicle is articulated.
 
	 */
 
	static bool IsArticulated(VehicleID vehicle_id);
 
};
 

	
 
#endif /* AI_VEHICLE_HPP */
src/ai/api/ai_vehicle.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_vehicle.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow enums to be used as Squirrel parameters */
 
	template <> AIVehicle::ErrorMessages GetParam(ForceType<AIVehicle::ErrorMessages>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AIVehicle::ErrorMessages)tmp; }
 
	template <> int Return<AIVehicle::ErrorMessages>(HSQUIRRELVM vm, AIVehicle::ErrorMessages res) { sq_pushinteger(vm, (int32)res); return 1; }
 
	template <> AIVehicle::VehicleType GetParam(ForceType<AIVehicle::VehicleType>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AIVehicle::VehicleType)tmp; }
 
	template <> int Return<AIVehicle::VehicleType>(HSQUIRRELVM vm, AIVehicle::VehicleType res) { sq_pushinteger(vm, (int32)res); return 1; }
 
	template <> AIVehicle::VehicleState GetParam(ForceType<AIVehicle::VehicleState>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AIVehicle::VehicleState)tmp; }
 
	template <> int Return<AIVehicle::VehicleState>(HSQUIRRELVM vm, AIVehicle::VehicleState res) { sq_pushinteger(vm, (int32)res); return 1; }
 

	
 
	/* Allow AIVehicle to be used as Squirrel parameter */
 
	template <> AIVehicle *GetParam(ForceType<AIVehicle *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIVehicle *)instance; }
 
	template <> AIVehicle &GetParam(ForceType<AIVehicle &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIVehicle *)instance; }
 
	template <> const AIVehicle *GetParam(ForceType<const AIVehicle *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIVehicle *)instance; }
 
	template <> const AIVehicle &GetParam(ForceType<const AIVehicle &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIVehicle *)instance; }
 
	template <> int Return<AIVehicle *>(HSQUIRRELVM vm, AIVehicle *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIVehicle", res, NULL, DefSQDestructorCallback<AIVehicle>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIVehicle_Register(Squirrel *engine) {
 
	DefSQClass <AIVehicle> SQAIVehicle("AIVehicle");
 
	SQAIVehicle.PreRegister(engine);
 
	SQAIVehicle.AddConstructor<void (AIVehicle::*)(), 1>(engine, "x");
 

	
 
	SQAIVehicle.DefSQConst(engine, AIVehicle::ERR_VEHICLE_BASE,                 "ERR_VEHICLE_BASE");
 
	SQAIVehicle.DefSQConst(engine, AIVehicle::ERR_VEHICLE_TOO_MANY,             "ERR_VEHICLE_TOO_MANY");
 
	SQAIVehicle.DefSQConst(engine, AIVehicle::ERR_VEHICLE_NOT_AVAILABLE,        "ERR_VEHICLE_NOT_AVAILABLE");
 
	SQAIVehicle.DefSQConst(engine, AIVehicle::ERR_VEHICLE_BUILD_DISABLED,       "ERR_VEHICLE_BUILD_DISABLED");
 
	SQAIVehicle.DefSQConst(engine, AIVehicle::ERR_VEHICLE_WRONG_DEPOT,          "ERR_VEHICLE_WRONG_DEPOT");
 
	SQAIVehicle.DefSQConst(engine, AIVehicle::ERR_VEHICLE_CANNOT_SEND_TO_DEPOT, "ERR_VEHICLE_CANNOT_SEND_TO_DEPOT");
 
	SQAIVehicle.DefSQConst(engine, AIVehicle::ERR_VEHICLE_CANNOT_START_STOP,    "ERR_VEHICLE_CANNOT_START_STOP");
 
	SQAIVehicle.DefSQConst(engine, AIVehicle::ERR_VEHICLE_CANNOT_TURN,          "ERR_VEHICLE_CANNOT_TURN");
 
	SQAIVehicle.DefSQConst(engine, AIVehicle::ERR_VEHICLE_CANNOT_REFIT,         "ERR_VEHICLE_CANNOT_REFIT");
 
	SQAIVehicle.DefSQConst(engine, AIVehicle::ERR_VEHICLE_IS_DESTROYED,         "ERR_VEHICLE_IS_DESTROYED");
 
	SQAIVehicle.DefSQConst(engine, AIVehicle::ERR_VEHICLE_NOT_IN_DEPOT,         "ERR_VEHICLE_NOT_IN_DEPOT");
 
	SQAIVehicle.DefSQConst(engine, AIVehicle::ERR_VEHICLE_IN_FLIGHT,            "ERR_VEHICLE_IN_FLIGHT");
 
	SQAIVehicle.DefSQConst(engine, AIVehicle::ERR_VEHCILE_NO_POWER,             "ERR_VEHCILE_NO_POWER");
 
	SQAIVehicle.DefSQConst(engine, AIVehicle::VEHICLE_RAIL,                     "VEHICLE_RAIL");
 
	SQAIVehicle.DefSQConst(engine, AIVehicle::VEHICLE_ROAD,                     "VEHICLE_ROAD");
 
	SQAIVehicle.DefSQConst(engine, AIVehicle::VEHICLE_WATER,                    "VEHICLE_WATER");
 
	SQAIVehicle.DefSQConst(engine, AIVehicle::VEHICLE_AIR,                      "VEHICLE_AIR");
 
	SQAIVehicle.DefSQConst(engine, AIVehicle::VEHICLE_INVALID,                  "VEHICLE_INVALID");
 
	SQAIVehicle.DefSQConst(engine, AIVehicle::VS_RUNNING,                       "VS_RUNNING");
 
	SQAIVehicle.DefSQConst(engine, AIVehicle::VS_STOPPED,                       "VS_STOPPED");
 
	SQAIVehicle.DefSQConst(engine, AIVehicle::VS_IN_DEPOT,                      "VS_IN_DEPOT");
 
	SQAIVehicle.DefSQConst(engine, AIVehicle::VS_AT_STATION,                    "VS_AT_STATION");
 
	SQAIVehicle.DefSQConst(engine, AIVehicle::VS_BROKEN,                        "VS_BROKEN");
 
	SQAIVehicle.DefSQConst(engine, AIVehicle::VS_CRASHED,                       "VS_CRASHED");
 
	SQAIVehicle.DefSQConst(engine, AIVehicle::VS_INVALID,                       "VS_INVALID");
 

	
 
	AIError::RegisterErrorMap(STR_00E1_TOO_MANY_VEHICLES_IN_GAME,     AIVehicle::ERR_VEHICLE_TOO_MANY);
 
	AIError::RegisterErrorMap(STR_AIRCRAFT_NOT_AVAILABLE,             AIVehicle::ERR_VEHICLE_NOT_AVAILABLE);
 
	AIError::RegisterErrorMap(STR_ROAD_VEHICLE_NOT_AVAILABLE,         AIVehicle::ERR_VEHICLE_NOT_AVAILABLE);
 
	AIError::RegisterErrorMap(STR_SHIP_NOT_AVAILABLE,                 AIVehicle::ERR_VEHICLE_NOT_AVAILABLE);
 
	AIError::RegisterErrorMap(STR_RAIL_VEHICLE_NOT_AVAILABLE,         AIVehicle::ERR_VEHICLE_NOT_AVAILABLE);
 
	AIError::RegisterErrorMap(STR_A008_CAN_T_BUILD_AIRCRAFT,          AIVehicle::ERR_VEHICLE_BUILD_DISABLED);
 
	AIError::RegisterErrorMap(STR_980D_CAN_T_BUILD_SHIP,              AIVehicle::ERR_VEHICLE_BUILD_DISABLED);
 
	AIError::RegisterErrorMap(STR_9009_CAN_T_BUILD_ROAD_VEHICLE,      AIVehicle::ERR_VEHICLE_BUILD_DISABLED);
 
	AIError::RegisterErrorMap(STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE,  AIVehicle::ERR_VEHICLE_BUILD_DISABLED);
 
	AIError::RegisterErrorMap(STR_DEPOT_WRONG_DEPOT_TYPE,             AIVehicle::ERR_VEHICLE_WRONG_DEPOT);
 
	AIError::RegisterErrorMap(STR_8830_CAN_T_SEND_TRAIN_TO_DEPOT,     AIVehicle::ERR_VEHICLE_CANNOT_SEND_TO_DEPOT);
 
	AIError::RegisterErrorMap(STR_9018_CAN_T_SEND_VEHICLE_TO_DEPOT,   AIVehicle::ERR_VEHICLE_CANNOT_SEND_TO_DEPOT);
 
	AIError::RegisterErrorMap(STR_9819_CAN_T_SEND_SHIP_TO_DEPOT,      AIVehicle::ERR_VEHICLE_CANNOT_SEND_TO_DEPOT);
 
	AIError::RegisterErrorMap(STR_A012_CAN_T_SEND_AIRCRAFT_TO,        AIVehicle::ERR_VEHICLE_CANNOT_SEND_TO_DEPOT);
 
	AIError::RegisterErrorMap(STR_883B_CAN_T_STOP_START_TRAIN,        AIVehicle::ERR_VEHICLE_CANNOT_START_STOP);
 
	AIError::RegisterErrorMap(STR_9015_CAN_T_STOP_START_ROAD_VEHICLE, AIVehicle::ERR_VEHICLE_CANNOT_START_STOP);
 
	AIError::RegisterErrorMap(STR_9818_CAN_T_STOP_START_SHIP,         AIVehicle::ERR_VEHICLE_CANNOT_START_STOP);
 
	AIError::RegisterErrorMap(STR_A016_CAN_T_STOP_START_AIRCRAFT,     AIVehicle::ERR_VEHICLE_CANNOT_START_STOP);
 
	AIError::RegisterErrorMap(STR_8869_CAN_T_REVERSE_DIRECTION,       AIVehicle::ERR_VEHICLE_CANNOT_TURN);
 
	AIError::RegisterErrorMap(STR_9033_CAN_T_MAKE_VEHICLE_TURN,       AIVehicle::ERR_VEHICLE_CANNOT_TURN);
 
	AIError::RegisterErrorMap(STR_RAIL_CAN_T_REFIT_VEHICLE,           AIVehicle::ERR_VEHICLE_CANNOT_REFIT);
 
	AIError::RegisterErrorMap(STR_REFIT_ROAD_VEHICLE_CAN_T,           AIVehicle::ERR_VEHICLE_CANNOT_REFIT);
 
	AIError::RegisterErrorMap(STR_9841_CAN_T_REFIT_SHIP,              AIVehicle::ERR_VEHICLE_CANNOT_REFIT);
 
	AIError::RegisterErrorMap(STR_A042_CAN_T_REFIT_AIRCRAFT,          AIVehicle::ERR_VEHICLE_CANNOT_REFIT);
 
	AIError::RegisterErrorMap(STR_CAN_T_REFIT_DESTROYED_VEHICLE,      AIVehicle::ERR_VEHICLE_IS_DESTROYED);
 
	AIError::RegisterErrorMap(STR_CAN_T_SELL_DESTROYED_VEHICLE,       AIVehicle::ERR_VEHICLE_IS_DESTROYED);
 
	AIError::RegisterErrorMap(STR_A01B_AIRCRAFT_MUST_BE_STOPPED,      AIVehicle::ERR_VEHICLE_NOT_IN_DEPOT);
 
	AIError::RegisterErrorMap(STR_9013_MUST_BE_STOPPED_INSIDE,        AIVehicle::ERR_VEHICLE_NOT_IN_DEPOT);
 
	AIError::RegisterErrorMap(STR_TRAIN_MUST_BE_STOPPED,              AIVehicle::ERR_VEHICLE_NOT_IN_DEPOT);
 
	AIError::RegisterErrorMap(STR_980B_SHIP_MUST_BE_STOPPED_IN,       AIVehicle::ERR_VEHICLE_NOT_IN_DEPOT);
 
	AIError::RegisterErrorMap(STR_A017_AIRCRAFT_IS_IN_FLIGHT,         AIVehicle::ERR_VEHICLE_IN_FLIGHT);
 
	AIError::RegisterErrorMap(STR_TRAIN_START_NO_CATENARY,            AIVehicle::ERR_VEHCILE_NO_POWER);
 

	
 
	AIError::RegisterErrorMapString(AIVehicle::ERR_VEHICLE_TOO_MANY,             "ERR_VEHICLE_TOO_MANY");
 
	AIError::RegisterErrorMapString(AIVehicle::ERR_VEHICLE_NOT_AVAILABLE,        "ERR_VEHICLE_NOT_AVAILABLE");
 
	AIError::RegisterErrorMapString(AIVehicle::ERR_VEHICLE_BUILD_DISABLED,       "ERR_VEHICLE_BUILD_DISABLED");
 
	AIError::RegisterErrorMapString(AIVehicle::ERR_VEHICLE_WRONG_DEPOT,          "ERR_VEHICLE_WRONG_DEPOT");
 
	AIError::RegisterErrorMapString(AIVehicle::ERR_VEHICLE_CANNOT_SEND_TO_DEPOT, "ERR_VEHICLE_CANNOT_SEND_TO_DEPOT");
 
	AIError::RegisterErrorMapString(AIVehicle::ERR_VEHICLE_CANNOT_START_STOP,    "ERR_VEHICLE_CANNOT_START_STOP");
 
	AIError::RegisterErrorMapString(AIVehicle::ERR_VEHICLE_CANNOT_TURN,          "ERR_VEHICLE_CANNOT_TURN");
 
	AIError::RegisterErrorMapString(AIVehicle::ERR_VEHICLE_CANNOT_REFIT,         "ERR_VEHICLE_CANNOT_REFIT");
 
	AIError::RegisterErrorMapString(AIVehicle::ERR_VEHICLE_IS_DESTROYED,         "ERR_VEHICLE_IS_DESTROYED");
 
	AIError::RegisterErrorMapString(AIVehicle::ERR_VEHICLE_NOT_IN_DEPOT,         "ERR_VEHICLE_NOT_IN_DEPOT");
 
	AIError::RegisterErrorMapString(AIVehicle::ERR_VEHICLE_IN_FLIGHT,            "ERR_VEHICLE_IN_FLIGHT");
 
	AIError::RegisterErrorMapString(AIVehicle::ERR_VEHCILE_NO_POWER,             "ERR_VEHCILE_NO_POWER");
 

	
 
	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::GetClassName,       "GetClassName",       1, "x");
 
	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::IsValidVehicle,     "IsValidVehicle",     2, "xi");
 
	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::GetNumWagons,       "GetNumWagons",       2, "xi");
 
	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::SetName,            "SetName",            3, "xis");
 
	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::GetName,            "GetName",            2, "xi");
 
	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::GetLocation,        "GetLocation",        2, "xi");
 
	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::GetEngineType,      "GetEngineType",      2, "xi");
 
	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::GetWagonEngineType, "GetWagonEngineType", 3, "xii");
 
	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::GetUnitNumber,      "GetUnitNumber",      2, "xi");
 
	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::GetAge,             "GetAge",             2, "xi");
 
	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::GetWagonAge,        "GetWagonAge",        3, "xii");
 
	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::GetMaxAge,          "GetMaxAge",          2, "xi");
 
	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::GetAgeLeft,         "GetAgeLeft",         2, "xi");
 
	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::GetCurrentSpeed,    "GetCurrentSpeed",    2, "xi");
 
	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::GetState,           "GetState",           2, "xi");
 
	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::GetRunningCost,     "GetRunningCost",     2, "xi");
 
	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::GetProfitThisYear,  "GetProfitThisYear",  2, "xi");
 
	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::GetProfitLastYear,  "GetProfitLastYear",  2, "xi");
 
	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::GetCurrentValue,    "GetCurrentValue",    2, "xi");
 
	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::GetVehicleType,     "GetVehicleType",     2, "xi");
 
	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::GetRoadType,        "GetRoadType",        2, "xi");
 
	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::IsInDepot,          "IsInDepot",          2, "xi");
 
	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::IsStoppedInDepot,   "IsStoppedInDepot",   2, "xi");
 
	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::BuildVehicle,       "BuildVehicle",       3, "xii");
 
	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::CloneVehicle,       "CloneVehicle",       4, "xiib");
 
	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::MoveWagon,          "MoveWagon",          6, "xiibii");
 
	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::GetRefitCapacity,   "GetRefitCapacity",   3, "xii");
 
	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::RefitVehicle,       "RefitVehicle",       3, "xii");
 
	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::SellVehicle,        "SellVehicle",        2, "xi");
 
	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::SellWagon,          "SellWagon",          4, "xiib");
 
	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::SendVehicleToDepot, "SendVehicleToDepot", 2, "xi");
 
	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::StartStopVehicle,   "StartStopVehicle",   2, "xi");
 
	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::SkipToVehicleOrder, "SkipToVehicleOrder", 3, "xii");
 
	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::ReverseVehicle,     "ReverseVehicle",     2, "xi");
 
	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::GetCapacity,        "GetCapacity",        3, "xii");
 
	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::GetLength,          "GetLength",          2, "xi");
 
	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::GetCargoLoad,       "GetCargoLoad",       3, "xii");
 
	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::GetGroupID,         "GetGroupID",         2, "xi");
 
	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::IsArticulated,      "IsArticulated",      2, "xi");
 

	
 
	SQAIVehicle.PostRegister(engine);
 
}
src/ai/api/ai_vehiclelist.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_vehiclelist.cpp Implementation of AIVehicleList and friends. */
 

	
 
#include "ai_vehiclelist.hpp"
 
#include "ai_station.hpp"
 
#include "../../openttd.h"
 
#include "../../company_func.h"
 
#include "../../vehicle_base.h"
 

	
 
AIVehicleList::AIVehicleList()
 
{
 
	Vehicle *v;
 
	FOR_ALL_VEHICLES(v) {
 
		if (v->owner == _current_company && v->IsPrimaryVehicle()) this->AddItem(v->index);
 
	}
 
}
 

	
 
AIVehicleList_Station::AIVehicleList_Station(StationID station_id)
 
{
 
	if (!AIStation::IsValidStation(station_id)) return;
 

	
 
	Vehicle *v;
 

	
 
	FOR_ALL_VEHICLES(v) {
 
		if (v->owner == _current_company && v->IsPrimaryVehicle()) {
 
			const Order *order;
 

	
 
			FOR_VEHICLE_ORDERS(v, order) {
 
				if (order->IsType(OT_GOTO_STATION) && order->GetDestination() == station_id) {
 
					this->AddItem(v->index);
 
					break;
 
				}
 
			}
 
		}
 
	}
 
}
src/ai/api/ai_vehiclelist.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file ai_vehiclelist.hpp List all the vehicles (you own). */
 

	
 
#ifndef AI_VEHICLELIST_HPP
 
#define AI_VEHICLELIST_HPP
 

	
 
#include "ai_abstractlist.hpp"
 

	
 
/**
 
 * Creates a list of vehicles of which you are the owner.
 
 * @ingroup AIList
 
 */
 
class AIVehicleList : public AIAbstractList {
 
public:
 
	static const char *GetClassName() { return "AIVehicleList"; }
 
	AIVehicleList();
 
};
 

	
 
/**
 
 * Creates a list of vehicles that have orders to a given station.
 
 * @ingroup AIList
 
 */
 
class AIVehicleList_Station : public AIAbstractList {
 
public:
 
	static const char *GetClassName() { return "AIVehicleList_Station"; }
 

	
 
	/**
 
	 * @param station_id The station to get the list of vehicles that have orders to him from.
 
	 */
 
	AIVehicleList_Station(StationID station_id);
 
};
 

	
 
#endif /* AI_VEHICLELIST_HPP */
src/ai/api/ai_vehiclelist.hpp.sq
Show inline comments
 
new file 100644
 
/* $Id$ */
 
/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
 

	
 
#include "ai_vehiclelist.hpp"
 

	
 
namespace SQConvert {
 
	/* Allow AIVehicleList to be used as Squirrel parameter */
 
	template <> AIVehicleList *GetParam(ForceType<AIVehicleList *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIVehicleList *)instance; }
 
	template <> AIVehicleList &GetParam(ForceType<AIVehicleList &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIVehicleList *)instance; }
 
	template <> const AIVehicleList *GetParam(ForceType<const AIVehicleList *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIVehicleList *)instance; }
 
	template <> const AIVehicleList &GetParam(ForceType<const AIVehicleList &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIVehicleList *)instance; }
 
	template <> int Return<AIVehicleList *>(HSQUIRRELVM vm, AIVehicleList *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIVehicleList", res, NULL, DefSQDestructorCallback<AIVehicleList>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIVehicleList_Register(Squirrel *engine) {
 
	DefSQClass <AIVehicleList> SQAIVehicleList("AIVehicleList");
 
	SQAIVehicleList.PreRegister(engine, "AIAbstractList");
 
	SQAIVehicleList.AddConstructor<void (AIVehicleList::*)(), 1>(engine, "x");
 

	
 
	SQAIVehicleList.DefSQStaticMethod(engine, &AIVehicleList::GetClassName, "GetClassName", 1, "x");
 

	
 
	SQAIVehicleList.PostRegister(engine);
 
}
 

	
 
namespace SQConvert {
 
	/* Allow AIVehicleList_Station to be used as Squirrel parameter */
 
	template <> AIVehicleList_Station *GetParam(ForceType<AIVehicleList_Station *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIVehicleList_Station *)instance; }
 
	template <> AIVehicleList_Station &GetParam(ForceType<AIVehicleList_Station &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIVehicleList_Station *)instance; }
 
	template <> const AIVehicleList_Station *GetParam(ForceType<const AIVehicleList_Station *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIVehicleList_Station *)instance; }
 
	template <> const AIVehicleList_Station &GetParam(ForceType<const AIVehicleList_Station &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIVehicleList_Station *)instance; }
 
	template <> int Return<AIVehicleList_Station *>(HSQUIRRELVM vm, AIVehicleList_Station *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIVehicleList_Station", res, NULL, DefSQDestructorCallback<AIVehicleList_Station>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIVehicleList_Station_Register(Squirrel *engine) {
 
	DefSQClass <AIVehicleList_Station> SQAIVehicleList_Station("AIVehicleList_Station");
 
	SQAIVehicleList_Station.PreRegister(engine, "AIAbstractList");
 
	SQAIVehicleList_Station.AddConstructor<void (AIVehicleList_Station::*)(StationID station_id), 2>(engine, "xi");
 

	
 
	SQAIVehicleList_Station.DefSQStaticMethod(engine, &AIVehicleList_Station::GetClassName, "GetClassName", 1, "x");
 

	
 
	SQAIVehicleList_Station.PostRegister(engine);
 
}
src/ai/api/squirrel_export.awk
Show inline comments
 
new file 100644
 
# $Id$
 
#
 
# Awk script to automatically generate the code needed
 
# to export the AI API to Squirrel.
 
#
 
# Note that arrays are 1 based...
 
#
 

	
 
# Simple insertion sort.
 
function array_sort(ARRAY, ELEMENTS, temp, i, j) {
 
	for (i = 2; i <= ELEMENTS; i++)
 
		for (j = i; ARRAY[j - 1] > ARRAY[j]; --j) {
 
			temp = ARRAY[j]
 
			ARRAY[j] = ARRAY[j - 1]
 
			ARRAY[j - 1] = temp
 
	}
 
	return
 
}
 

	
 
function dump_class_templates(name) {
 
	print "	template <> "       name " *GetParam(ForceType<"       name " *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (" name " *)instance; }"
 
	print "	template <> "       name " &GetParam(ForceType<"       name " &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(" name " *)instance; }"
 
	print "	template <> const " name " *GetParam(ForceType<const " name " *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (" name " *)instance; }"
 
	print "	template <> const " name " &GetParam(ForceType<const " name " &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(" name " *)instance; }"
 
	if (name == "AIEvent") {
 
		print " template <> int Return<" name " *>(HSQUIRRELVM vm, " name " *res) { if (res == NULL) { sq_pushnull(vm); return 1; } Squirrel::CreateClassInstanceVM(vm, \"" name "\", res, NULL, DefSQDestructorCallback<" name ">); return 1; }"
 
	} else {
 
		print "	template <> int Return<" name " *>(HSQUIRRELVM vm, " name " *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, \"" name "\", res, NULL, DefSQDestructorCallback<" name ">); return 1; }"
 
	}
 
}
 

	
 
BEGIN {
 
	enum_size = 0
 
	enum_value_size = 0
 
	enum_string_to_error_size = 0
 
	enum_error_to_string_size = 0
 
	struct_size = 0
 
	method_size = 0
 
	static_method_size = 0
 
	virtual_class = "false"
 
	super_cls = ""
 
	cls = ""
 
	start_squirrel_define_on_next_line = "false"
 
	cls_level = 0
 
	RS = "\r|\n"
 
}
 

	
 
/@file/ {
 
	# Break it in two lines, so SVN doesn't replace it
 
	printf "/* $I"
 
	print "d$ */"
 
	print "/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */"
 
	print ""
 
	print "#include \"" $3 "\""
 
}
 

	
 
# Remove the old squirrel stuff
 
/#ifdef DEFINE_SQUIRREL_CLASS/ { squirrel_stuff = "true";  next; }
 
/^#endif \/\* DEFINE_SQUIRREL_CLASS \*\// { if (squirrel_stuff == "true") { squirrel_stuff = "false"; next; } }
 
{ if (squirrel_stuff == "true") next; }
 

	
 
# Ignore forward declarations of classes
 
/^(	*)class(.*);/ { next; }
 
# We only want to have public functions exported for now
 
/^(	*)class/     {
 
	if (cls_level == 0) {
 
		public = "false"
 
		cls_param[0] = ""
 
		cls_param[1] = 1
 
		cls_param[2] = "x"
 
		cls = $2
 
		if (match($4, "public") || match($4, "protected") || match($4, "private")) {
 
			super_cls = $5
 
		} else {
 
			super_cls = $4
 
		}
 
	} else if (cls_level == 1) {
 
		struct_size++
 
		structs[struct_size] = cls "::" $2
 
	}
 
	cls_level++
 
	next
 
}
 
/^(	*)public/    { if (cls_level == 1) public = "true";  next; }
 
/^(	*)protected/ { if (cls_level == 1) public = "false"; next; }
 
/^(	*)private/   { if (cls_level == 1) public = "false"; next; }
 

	
 
# Ignore special doxygen blocks
 
/^#ifndef DOXYGEN_SKIP/ { doxygen_skip = "next"; next; }
 
/^#ifdef DOXYGEN_SKIP/  { doxygen_skip = "true"; next; }
 
/^#endif/               { doxygen_skip = "false"; next; }
 
/^#else/                {
 
	if (doxygen_skip == "next") {
 
		doxygen_skip = "true";
 
	} else {
 
		doxygen_skip = "false";
 
	}
 
	next;
 
}
 
{ if (doxygen_skip == "true") next }
 

	
 
# Ignore the comments
 
/^#/             { next; }
 
/\/\*.*\*\//     { comment = "false"; next; }
 
/\/\*/           { comment = "true";  next; }
 
/\*\//           { comment = "false"; next; }
 
{ if (comment == "true") next }
 

	
 
# We need to make specialized conversions for structs
 
/^(	*)struct/ {
 
	cls_level++
 
	if (public == "false") next
 
	if (cls_level != 1) next
 
	struct_size++
 
	structs[struct_size] = cls "::" $2
 
	next
 
}
 

	
 
# We need to make specialized conversions for enums
 
/^(	*)enum/ {
 
	cls_level++
 
	if (public == "false") next;
 
	in_enum = "true"
 
	enum_size++
 
	enums[enum_size] = cls "::" $2
 
	next
 
}
 

	
 
# Maybe the end of the class, if so we can start with the Squirrel export pretty soon
 
/};/ {
 
	cls_level--
 
	if (cls_level != 0) {
 
		in_enum = "false";
 
		next;
 
	}
 
	if (cls == "") {
 
		next;
 
	}
 
	start_squirrel_define_on_next_line = "true"
 
	next;
 
}
 

	
 
# Empty/white lines. When we may do the Squirrel export, do that export.
 
/^([ 	]*)$/ {
 
	if (start_squirrel_define_on_next_line == "false") next
 
	spaces = "                                                               ";
 
	public = "false"
 
	namespace_opened = "false"
 

	
 
	print ""
 

	
 
	# First check whether we have enums to print
 
	if (enum_size != 0) {
 
		if (namespace_opened == "false") {
 
			print "namespace SQConvert {"
 
			namespace_opened = "true"
 
		}
 
		print "	/* Allow enums to be used as Squirrel parameters */"
 
		for (i = 1; i <= enum_size; i++) {
 
			print "	template <> " enums[i] " GetParam(ForceType<" enums[i] ">, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (" enums[i] ")tmp; }"
 
			print "	template <> int Return<" enums[i] ">(HSQUIRRELVM vm, " enums[i] " res) { sq_pushinteger(vm, (int32)res); return 1; }"
 
			delete enums[i]
 
		}
 
	}
 

	
 
	# Then check whether we have structs/classes to print
 
	if (struct_size != 0) {
 
		if (namespace_opened == "false") {
 
			print "namespace SQConvert {"
 
			namespace_opened = "true"
 
		}
 
		print "	/* Allow inner classes/structs to be used as Squirrel parameters */"
 
		for (i = 1; i <= struct_size; i++) {
 
			dump_class_templates(structs[i])
 
			delete structs[i]
 
		}
 
	}
 

	
 
	if (namespace_opened == "false") {
 
		print "namespace SQConvert {"
 
		namespace_opened = "true"
 
	} else {
 
		print ""
 
	}
 
	print "	/* Allow " cls " to be used as Squirrel parameter */"
 
	dump_class_templates(cls)
 

	
 
	print "}; // namespace SQConvert"
 

	
 
	print "";
 
	# Then do the registration functions of the class. */
 
	print "void SQ" cls "_Register(Squirrel *engine) {"
 
	print "	DefSQClass <" cls "> SQ" cls "(\"" cls "\");"
 
	if (super_cls == "AIObject" || super_cls == "AIAbstractList::Valuator") {
 
		print "	SQ" cls ".PreRegister(engine);"
 
	} else {
 
		print "	SQ" cls ".PreRegister(engine, \"" super_cls "\");"
 
	}
 
	if (virtual_class == "false" && super_cls != "AIEvent") {
 
		print "	SQ" cls ".AddConstructor<void (" cls "::*)(" cls_param[0] "), " cls_param[1]">(engine, \"" cls_param[2] "\");"
 
	}
 
	print ""
 

	
 
	# Enum values
 
	mlen = 0
 
	for (i = 1; i <= enum_value_size; i++) {
 
		if (mlen <= length(enum_value[i])) mlen = length(enum_value[i])
 
	}
 
	for (i = 1; i <= enum_value_size; i++) {
 
		print "	SQ" cls ".DefSQConst(engine, " cls "::" enum_value[i] ", " substr(spaces, 1, mlen - length(enum_value[i])) "\""  enum_value[i] "\");"
 
		delete enum_value[i]
 
	}
 
	if (enum_value_size != 0) print ""
 

	
 
	# Mapping of OTTD strings to errors
 
	mlen = 0
 
	for (i = 1; i <= enum_string_to_error_size; i++) {
 
		if (mlen <= length(enum_string_to_error_mapping_string[i])) mlen = length(enum_string_to_error_mapping_string[i])
 
	}
 
	for (i = 1; i <= enum_string_to_error_size; i++) {
 
		print "	AIError::RegisterErrorMap(" enum_string_to_error_mapping_string[i] ", " substr(spaces, 1, mlen - length(enum_string_to_error_mapping_string[i]))  cls "::" enum_string_to_error_mapping_error[i] ");"
 

	
 
		delete enum_string_to_error_mapping_string[i]
 
	}
 
	if (enum_string_to_error_size != 0) print ""
 

	
 
	# Mapping of errors to human 'readable' strings.
 
	mlen = 0
 
	for (i = 1; i <= enum_error_to_string_size; i++) {
 
		if (mlen <= length(enum_error_to_string_mapping[i])) mlen = length(enum_error_to_string_mapping[i])
 
	}
 
	for (i = 1; i <= enum_error_to_string_size; i++) {
 
		print "	AIError::RegisterErrorMapString(" cls "::" enum_error_to_string_mapping[i] ", " substr(spaces, 1, mlen - length(enum_error_to_string_mapping[i])) "\"" enum_error_to_string_mapping[i] "\");"
 
		delete enum_error_to_string_mapping[i]
 
	}
 
	if (enum_error_to_string_size != 0) print ""
 

	
 
	# Static methods
 
	mlen = 0
 
	for (i = 1; i <= static_method_size; i++) {
 
		if (mlen <= length(static_methods[i, 0])) mlen = length(static_methods[i, 0])
 
	}
 
	for (i = 1; i <= static_method_size; i++) {
 
		print "	SQ" cls ".DefSQStaticMethod(engine, &" cls "::" static_methods[i, 0] ", " substr(spaces, 1, mlen - length(static_methods[i, 0])) "\""  static_methods[i, 0] "\", " substr(spaces, 1, mlen - length(static_methods[i, 0])) "" static_methods[i, 1] ", \"" static_methods[i, 2] "\");"
 
		delete static_methods[i]
 
	}
 
	if (static_method_size != 0) print ""
 

	
 
	if (virtual_class == "false") {
 
		# Non-static methods
 
		mlen = 0
 
		for (i = 1; i <= method_size; i++) {
 
			if (mlen <= length(methods[i, 0])) mlen = length(methods[i, 0])
 
		}
 
		for (i = 1; i <= method_size; i++) {
 
			if (methods[i, 2] == "v") {
 
				print "	SQ" cls ".DefSQAdvancedMethod(engine, &" cls "::" methods[i, 0] ", " substr(spaces, 1, mlen - length(methods[i, 0]) - 8) "\""  methods[i, 0] "\");"
 
			} else {
 
				print "	SQ" cls ".DefSQMethod(engine, &" cls "::" methods[i, 0] ", " substr(spaces, 1, mlen - length(methods[i, 0])) "\""  methods[i, 0] "\", " substr(spaces, 1, mlen - length(methods[i, 0])) "" methods[i, 1] ", \"" methods[i, 2] "\");"
 
			}
 
			delete methods[i]
 
		}
 
		if (method_size != 0) print ""
 
	}
 
	print "	SQ" cls ".PostRegister(engine);"
 
	print "}"
 

	
 
	enum_size = 0
 
	enum_value_size = 0
 
	enum_string_to_error_size = 0
 
	enum_error_to_string_size = 0
 
	struct_size = 0
 
	method_size = 0
 
	static_method_size = 0
 
	virtual_class = "false"
 
	cls = ""
 
	start_squirrel_define_on_next_line = "false"
 
	cls_level = 0
 
}
 

	
 
# Skip non-public functions
 
{ if (public == "false") next }
 

	
 
# Add enums
 
{
 
	if (in_enum == "true") {
 
		enum_value_size++
 
		sub(",", "", $1)
 
		enum_value[enum_value_size] = $1
 

	
 
		# Check if this a special error enum
 
		if (match(enums[enum_size], ".*::ErrorMessages") != 0) {
 
			# syntax:
 
			# enum ErrorMessages {
 
			#	ERR_SOME_ERROR,	// [STR_ITEM1, STR_ITEM2, ...]
 
			# }
 

	
 
			# Set the mappings
 
			if (match($0, "\\[.*\\]") != 0) {
 
				mappings = substr($0, RSTART, RLENGTH);
 
				gsub("([\\[[:space:]\\]])", "", mappings);
 

	
 
				split(mappings, mapitems, ",");
 
				for (i = 1; i <= length(mapitems); i++) {
 
					enum_string_to_error_size++
 
					enum_string_to_error_mapping_string[enum_string_to_error_size] = mapitems[i]
 
					enum_string_to_error_mapping_error[enum_string_to_error_size] = $1
 
				}
 

	
 
				enum_error_to_string_size++
 
				enum_error_to_string_mapping[enum_error_to_string_size] = $1
 
			}
 
		}
 
		next
 
	}
 
}
 

	
 
# Add a method to the list
 
/^.*\(.*\).*$/ {
 
	if (cls_level != 1) next
 
	if (match($0, "~")) next
 

	
 
	is_static = match($0, "static")
 
	if (match($0, "virtual")) {
 
		virtual_class = "true"
 
	}
 
	gsub("virtual", "", $0)
 
	gsub("static", "", $0)
 
	gsub("const", "", $0)
 
	gsub("{.*", "", $0)
 
	param_s = $0
 
	gsub("\\*", "", $0)
 
	gsub("\\(.*", "", $0)
 

	
 
	sub(".*\\(", "", param_s)
 
	sub("\\).*", "", param_s)
 

	
 
	funcname = $2
 
	if ($1 == cls && funcname == "") {
 
		cls_param[0] = param_s
 
		if (param_s == "") next
 
	} else if (funcname == "") next
 

	
 
	split(param_s, params, ",")
 
	types = "x"
 
	for (len = 1; params[len] != ""; len++) {
 
		sub("^[ 	]*", "", params[len])
 
		if (match(params[len], "\\*") || match(params[len], "&")) {
 
			if (match(params[len], "^char")) {
 
				types = types "s"
 
			} else if (match(params[len], "^void")) {
 
				types = types "p"
 
			} else if (match(params[len], "^Array")) {
 
				types = types "a"
 
			} else if (match(params[len], "^struct Array")) {
 
				types = types "a"
 
			} else {
 
				types = types "x"
 
			}
 
		} else if (match(params[len], "^bool")) {
 
			types = types "b"
 
		} else if (match(params[len], "^HSQUIRRELVM")) {
 
			types = "v"
 
		} else {
 
			types = types "i"
 
		}
 
	}
 

	
 
	if ($1 == cls && funcname == "") {
 
		cls_param[1] = len;
 
		cls_param[2] = types;
 
	} else if (substr(funcname, 0, 1) == "_" && types != "v") {
 
	} else if (is_static) {
 
		static_method_size++
 
		static_methods[static_method_size, 0] = funcname
 
		static_methods[static_method_size, 1] = len
 
		static_methods[static_method_size, 2] = types
 
	} else {
 
		method_size++
 
		methods[method_size, 0] = funcname
 
		methods[method_size, 1] = len
 
		methods[method_size, 2] = types
 
	}
 
	next
 
}
src/ai/api/squirrel_export.sh
Show inline comments
 
new file 100644
 
#!/bin/bash
 

	
 
# This must be called from within the src/ai/api directory.
 

	
 
if [ -z "$1" ]; then
 
	for f in `ls *.hpp`; do
 
		case "${f}" in
 
			# these files should not be changed by this script
 
			"ai_controller.hpp" | "ai_object.hpp" | "ai_types.hpp" ) continue;
 
		esac
 
		awk -f squirrel_export.awk ${f} > ${f}.tmp
 
		if ! [ -f "${f}.sq" ] || [ -n "`diff -I '$Id' -b ${f}.tmp ${f}.sq 2> /dev/null || echo boo`" ]; then
 
			mv ${f}.tmp ${f}.sq
 
			echo "Updated: ${f}.sq"
 
			svn add ${f}.sq > /dev/null 2>&1
 
			svn propset svn:eol-style native ${f}.sq > /dev/null 2>&1
 
			svn propset svn:keywords Id ${f}.sq > /dev/null 2>&1
 
		else
 
			rm -f ${f}.tmp
 
		fi
 
	done
 
else
 
	awk -f squirrel_export.awk $1 > $1.tmp
 
	if ! [ -f "${f}.sq" ] || [ -n "`diff -I '$Id' -b $1.sq $1.tmp 2> /dev/null || echo boo`" ]; then
 
		mv $1.tmp $1.sq
 
		echo "Updated: $1.sq"
 
		svn add $1.sq > /dev/null 2>&1
 
		svn propset svn:eol-style native $1.sq > /dev/null 2>&1
 
		svn propset svn:keywords Id $1.sq > /dev/null 2>&1
 
	else
 
		rm -f $1.tmp
 
	fi
 
fi
 

	
 
# Remove .hpp.sq if .hpp doesn't exist anymore
 
for f in `ls *.hpp.sq`; do
 
	f=`echo ${f} | sed "s/.hpp.sq$/.hpp/"`
 
	if [ ! -f ${f} ];then
 
		echo "Deleted: ${f}.sq"
 
		svn del --force ${f}.sq > /dev/null 2>&1
 
	fi
 
done
 

	
 
# Add stuff to ai_instance.cpp
 
f='../ai_instance.cpp'
 

	
 
functions=``
 

	
 
echo "
 
{ }
 
/.hpp.sq/ { next }
 
/squirrel_register_std/ { next }
 
/SQAIController_Register/ { print \$0; next }
 
/SQAI.*_Register/ { next }
 

	
 
/Note: this line a marker in squirrel_export.sh. Do not change!/ {
 
	print \$0
 
	gsub(\"^.*/\", \"\")
 
	split(\"`grep '^void SQAI.*_Register(Squirrel \*engine) {$' *.hpp.sq | sed 's/:.*$//' | sort | uniq | tr -d '\r' | tr '\n' ' '`\", files, \" \")
 

	
 
	for (i = 1; files[i] != \"\"; i++) {
 
		print \"#include \\\"api/\" files[i] \"\\\"\" \$0
 
	}
 

	
 
	next;
 
}
 

	
 
/\/\* Register all classes \*\// {
 
	print \$0
 
	gsub(\"^.*/\", \"\")
 
	print \"	squirrel_register_std(this->engine);\" \$0
 
	split(\"`grep '^void SQAI.*_Register(Squirrel \*engine) {$' *.hpp.sq | sed 's/^.*void //;s/Squirrel \*/this->/;s/ {/;/;s/_Register/0000Register/g;' | sort | sed 's/0000Register/_Register/g' | tr -d '\r' | tr '\n' ' '`\", regs, \" \")
 

	
 
	for (i = 1; regs[i] != \"\"; i++) {
 
		if (regs[i] == \"SQAIController_Register(this->engine);\") continue
 
		print \"	\" regs[i] \$0
 
	}
 

	
 
	next
 
}
 

	
 
{ print \$0; }
 
" > ${f}.awk
 

	
 
awk -f ${f}.awk ${f} > ${f}.tmp
 

	
 
if ! [ -f "${f}" ] || [ -n "`diff -I '$Id' -b ${f} ${f}.tmp 2> /dev/null || echo boo`" ]; then
 
	mv ${f}.tmp ${f}
 
	echo "Updated: ${f}"
 
else
 
	rm -f ${f}.tmp
 
fi
 
rm -f ${f}.awk
src/ai/default/default.cpp
Show inline comments
 
deleted file
src/ai/default/default.h
Show inline comments
 
deleted file
src/ai/trolly/build.cpp
Show inline comments
 
deleted file
src/ai/trolly/pathfinder.cpp
Show inline comments
 
deleted file
src/ai/trolly/shared.cpp
Show inline comments
 
deleted file
src/ai/trolly/trolly.cpp
Show inline comments
 
deleted file
src/ai/trolly/trolly.h
Show inline comments
 
deleted file
src/aircraft_cmd.cpp
Show inline comments
 
@@ -32,6 +32,7 @@
 
#include "autoreplace_func.h"
 
#include "autoreplace_gui.h"
 
#include "gfx_func.h"
 
#include "ai/ai.hpp"
 
#include "company_func.h"
 
#include "settings_type.h"
 
#include "order_func.h"
 
@@ -1338,6 +1339,8 @@ static void CrashAirplane(Vehicle *v)
 
		newsitem = STR_A034_PLANE_CRASH_DIE_IN_FIREBALL;
 
	}
 

	
 
	AI::NewEvent(v->owner, new AIEventVehicleCrashed(v->index, v->tile));
 

	
 
	AddNewsItem(newsitem,
 
		NS_ACCIDENT_VEHICLE,
 
		v->index,
 
@@ -1388,6 +1391,7 @@ static void AircraftEntersTerminal(Vehic
 
			v->index,
 
			st->index
 
		);
 
		AI::NewEvent(v->owner, new AIEventStationFirstVehicle(st->index, v->index));
 
	}
 

	
 
	v->BeginLoading();
src/autoslope.h
Show inline comments
 
@@ -32,14 +32,14 @@ static inline bool AutoslopeCheckForEntr
 
/**
 
 * Tests if autoslope is enabled for _current_company.
 
 *
 
 * Autoslope is disabled for town/industry construction and old ai companies.
 
 * Autoslope is disabled for town/industry construction.
 
 *
 
 * @return true iff autoslope is enabled.
 
 */
 
static inline bool AutoslopeEnabled()
 
{
 
	return (_settings_game.construction.autoslope &&
 
	        ((_current_company < MAX_COMPANIES && !_is_old_ai_company) ||
 
	        (_current_company < MAX_COMPANIES ||
 
	         (_current_company == OWNER_NONE && _game_mode == GM_EDITOR)));
 
}
 

	
src/callback_table.cpp
Show inline comments
 
@@ -54,6 +54,7 @@ CommandCallback CcBuildShip;
 
CommandCallback CcBuildWagon;
 
CommandCallback CcBuildLoco;
 

	
 
/* ai/ai_core.cpp */
 
CommandCallback CcAI;
 

	
 
CommandCallback *_callback_table[] = {
src/company_base.h
Show inline comments
 
@@ -70,6 +70,10 @@ struct Company : PoolItem<Company, Compa
 
	Money bankrupt_value;
 

	
 
	bool is_ai;
 
	bool is_noai; ///< This is a NoAI player (for loading old savegames properly). Part of the NoAI 'hack' to retain savegame compatability with trunk
 

	
 
	class AIInstance *ai_instance;
 
	class AIInfo *ai_info;
 

	
 
	Money yearly_expenses[3][EXPENSES_END];
 
	CompanyEconomyEntry cur_economy;
src/company_cmd.cpp
Show inline comments
 
@@ -15,7 +15,7 @@
 
#include "network/network_func.h"
 
#include "network/network_base.h"
 
#include "variables.h"
 
#include "ai/ai.h"
 
#include "ai/ai.hpp"
 
#include "company_manager_face.h"
 
#include "group.h"
 
#include "window_func.h"
 
@@ -31,8 +31,6 @@
 
#include "autoreplace_func.h"
 
#include "autoreplace_gui.h"
 
#include "string_func.h"
 
#include "ai/default/default.h"
 
#include "ai/trolly/trolly.h"
 
#include "road_func.h"
 
#include "rail.h"
 
#include "sprite.h"
 
@@ -53,6 +51,7 @@ DEFINE_OLD_POOL_GENERIC(Company, Company
 
Company::Company(uint16 name_1, bool is_ai) : name_1(name_1), location_of_HQ(INVALID_TILE), is_ai(is_ai)
 
{
 
	for (uint j = 0; j < 4; j++) this->share_owners[j] = COMPANY_SPECTATOR;
 
	this->is_noai = true;
 
}
 

	
 
Company::~Company()
 
@@ -293,6 +292,7 @@ set_name:;
 
			SetDParam(3, t->index);
 
			AddNewsItem(STR_02B6, NS_COMPANY_NEW, c->last_build_coordinate, 0, cni);
 
		}
 
		AI::BroadcastNewEvent(new AIEventCompanyNew(c->index), c->index);
 
		return;
 
	}
 
bad_town_name:;
 
@@ -429,9 +429,6 @@ Company *DoStartupNewCompany(bool is_ai)
 

	
 
	Company *c = new Company(STR_SV_UNNAMED, is_ai);
 

	
 
	memset(&_companies_ai[c->index], 0, sizeof(CompanyAI));
 
	memset(&_companies_ainew[c->index], 0, sizeof(CompanyAiNew));
 

	
 
	/* Make a color */
 
	c->colour = GenerateCompanyColour();
 
	ResetCompanyLivery(c);
 
@@ -439,7 +436,6 @@ Company *DoStartupNewCompany(bool is_ai)
 

	
 
	c->money = c->current_loan = 100000;
 

	
 
	_companies_ai[c->index].state = 5; // AIS_WANT_NEW_ROUTE
 
	c->share_owners[0] = c->share_owners[1] = c->share_owners[2] = c->share_owners[3] = INVALID_OWNER;
 

	
 
	c->avail_railtypes = GetCompanyRailtypes(c->index);
 
@@ -460,8 +456,7 @@ Company *DoStartupNewCompany(bool is_ai)
 
	InvalidateWindow(WC_TOOLBAR_MENU, 0);
 
	InvalidateWindow(WC_CLIENT_LIST, 0);
 

	
 
	if (is_ai && (!_networking || _network_server) && _ai.enabled)
 
		AI_StartNewAI(c->index);
 
	if (is_ai && (!_networking || _network_server)) AI::StartNew(c->index);
 

	
 
	c->num_engines = CallocT<uint16>(GetEnginePoolSize());
 

	
 
@@ -516,7 +511,7 @@ void OnTick_Companies()
 
		Company *c = GetCompany((CompanyID)_cur_company_tick_index);
 
		if (c->name_1 != 0) GenerateCompanyName(c);
 

	
 
		if (AI_AllowNewAI() && _game_mode != GM_MENU && !--_next_competitor_start) {
 
		if (AI::CanStartNew() && _game_mode != GM_MENU && !--_next_competitor_start) {
 
			MaybeStartNewCompany();
 
		}
 
	}
 
@@ -829,25 +824,24 @@ CommandCost CmdCompanyCtrl(TileIndex til
 

	
 
			c = GetCompany((CompanyID)p2);
 

	
 
			/* Only allow removal of HUMAN companies */
 
			if (IsHumanCompany(c->index)) {
 
				/* Delete any open window of the company */
 
				DeleteCompanyWindows(c->index);
 

	
 
				CompanyNewsInformation *cni = MallocT<CompanyNewsInformation>(1);
 
				cni->FillData(c);
 
			/* Delete any open window of the company */
 
			DeleteCompanyWindows(c->index);
 
			CompanyNewsInformation *cni = MallocT<CompanyNewsInformation>(1);
 
			cni->FillData(c);
 

	
 
				/* Show the bankrupt news */
 
				SetDParam(0, STR_705C_BANKRUPT);
 
				SetDParam(1, STR_705D_HAS_BEEN_CLOSED_DOWN_BY);
 
				SetDParamStr(2, cni->company_name);
 
				AddNewsItem(STR_02B6, NS_COMPANY_BANKRUPT, 0, 0, cni);
 
			/* Show the bankrupt news */
 
			SetDParam(0, STR_705C_BANKRUPT);
 
			SetDParam(1, STR_705D_HAS_BEEN_CLOSED_DOWN_BY);
 
			SetDParamStr(2, cni->company_name);
 
			AddNewsItem(STR_02B6, NS_COMPANY_BANKRUPT, 0, 0, cni);
 

	
 
				/* Remove the company */
 
				ChangeOwnershipOfCompanyItems(c->index, INVALID_OWNER);
 
			/* Remove the company */
 
			ChangeOwnershipOfCompanyItems(c->index, INVALID_OWNER);
 
			if (!IsHumanCompany(c->index)) AI::Stop(c->index);
 

	
 
				delete c;
 
			}
 
			CompanyID c_index = c->index;
 
			delete c;
 
			AI::BroadcastNewEvent(new AIEventCompanyBankrupt(c_index));
 
		} break;
 

	
 
		case 3: { /* Merge a company (#1) into another company (#2), elimination company #1 */
src/console_cmds.cpp
Show inline comments
 
@@ -31,6 +31,8 @@
 
#include "company_base.h"
 
#include "settings_type.h"
 
#include "gamelog.h"
 
#include "ai/ai.hpp"
 
#include "ai/ai_config.hpp"
 

	
 
#ifdef ENABLE_NETWORK
 
	#include "table/strings.h"
 
@@ -832,6 +834,129 @@ DEF_CONSOLE_CMD(ConRestart)
 
	return true;
 
}
 

	
 
DEF_CONSOLE_CMD(ConListAI)
 
{
 
	char buf[4096];
 
	char *p = &buf[0];
 
	p = AI::GetConsoleList(p, lastof(buf));
 

	
 
	p = &buf[0];
 
	/* Print output line by line */
 
	for (char *p2 = &buf[0]; *p2 != '\0'; p2++) {
 
		if (*p2 == '\n') {
 
			*p2 = '\0';
 
			IConsolePrintF(CC_DEFAULT, "%s", p);
 
			p = p2 + 1;
 
		}
 
	}
 

	
 
	return true;
 
}
 

	
 
DEF_CONSOLE_CMD(ConStartAI)
 
{
 
	if (argc == 0 || argc > 3) {
 
		IConsoleHelp("Start a new AI. Usage: 'start_ai [<AI>] [<settings>]'");
 
		IConsoleHelp("Start a new AI. If <AI> is given, it starts that specific AI (if found).");
 
		IConsoleHelp("If <settings> is given, it is parsed and the AI settings are set to that.");
 
		return true;
 
	}
 

	
 
	if (ActiveCompanyCount() == MAX_COMPANIES) {
 
		IConsoleWarning("Can't start a new AI (no more free slots).");
 
		return true;
 
	}
 
	if (_networking && !_network_server) {
 
		IConsoleWarning("Only the server can start a new AI.");
 
		return true;
 
	}
 
	if (_networking && !_settings_game.ai.ai_in_multiplayer) {
 
		IConsoleWarning("AIs are not allowed in multiplayer by configuration.");
 
		IConsoleWarning("Switch AI -> AI in multiplayer to True.");
 
		return true;
 
	}
 
	if (!AI::CanStartNew()) {
 
		IConsoleWarning("Can't start a new AI.");
 
		return true;
 
	}
 

	
 
	int n = 0;
 
	Company *c;
 
	/* Find the next free slot */
 
	FOR_ALL_COMPANIES(c) {
 
		if (c->index != n) break;
 
		n++;
 
	}
 

	
 
	AIConfig *config = AIConfig::GetConfig((CompanyID)n);
 
	if (argc >= 2) {
 
		class AIInfo *info = AI::GetCompanyInfo(argv[1]);
 
		if (info == NULL) {
 
			IConsoleWarning("Failed to load the specified AI");
 
			return true;
 
		}
 
		config->ChangeAI(argv[1]);
 
		if (argc == 3) {
 
			config->StringToSettings(argv[2]);
 
		}
 
	} else {
 
		config->ChangeAI(NULL);
 
	}
 

	
 
	/* Start a new AI company */
 
	DoCommandP(0, 1, 0, CMD_COMPANY_CTRL);
 

	
 
	return true;
 
}
 

	
 
DEF_CONSOLE_CMD(ConStopAI)
 
{
 
	if (argc != 2) {
 
		IConsoleHelp("Stop an AI. Usage: 'stop_ai <company-id>'");
 
		IConsoleHelp("Stop the AI with the given company id. For company-id's, see the list of companies from the dropdown menu. Company 1 is 1, etc.");
 
		return true;
 
	}
 

	
 
	if (_networking && !_network_server) {
 
		IConsoleWarning("Only the server can stop an AI.");
 
		return true;
 
	}
 

	
 
	CompanyID company_id = (CompanyID)(atoi(argv[1]) - 1);
 
	if (!IsValidCompanyID(company_id)) {
 
		IConsolePrintF(CC_DEFAULT, "Unknown company. Company range is between 1 and %d.", MAX_COMPANIES);
 
		return true;
 
	}
 

	
 
	if (IsHumanCompany(company_id)) {
 
		IConsoleWarning("Company is not controlled by an AI.");
 
		return true;
 
	}
 

	
 
	/* Now kill the company of the AI. */
 
	DoCommandP(0, 2, company_id, CMD_COMPANY_CTRL);
 
	IConsolePrint(CC_DEFAULT, "AI stopped, company deleted.");
 

	
 
	return true;
 
}
 

	
 
DEF_CONSOLE_CMD(ConRescanAI)
 
{
 
	if (argc == 0) {
 
		IConsoleHelp("Rescan the AI dir for scripts. Usage: 'rescan_ai'");
 
		return true;
 
	}
 

	
 
	if (_networking && !_network_server) {
 
		IConsoleWarning("Only the server can rescan the AI dir for scripts.");
 
		return true;
 
	}
 

	
 
	AI::Rescan();
 

	
 
	return true;
 
}
 

	
 
DEF_CONSOLE_CMD(ConGetSeed)
 
{
 
	if (argc == 0) {
 
@@ -1338,6 +1463,7 @@ void IConsoleStdLibRegister()
 
	IConsoleCmdRegister("help",         ConHelp);
 
	IConsoleCmdRegister("info_cmd",     ConInfoCmd);
 
	IConsoleCmdRegister("info_var",     ConInfoVar);
 
	IConsoleCmdRegister("list_ai",      ConListAI);
 
	IConsoleCmdRegister("list_cmds",    ConListCommands);
 
	IConsoleCmdRegister("list_vars",    ConListVariables);
 
	IConsoleCmdRegister("list_aliases", ConListAliases);
 
@@ -1346,6 +1472,7 @@ void IConsoleStdLibRegister()
 
	IConsoleCmdRegister("getseed",      ConGetSeed);
 
	IConsoleCmdRegister("getdate",      ConGetDate);
 
	IConsoleCmdRegister("quit",         ConExit);
 
	IConsoleCmdRegister("rescan_ai",    ConRescanAI);
 
	IConsoleCmdRegister("resetengines", ConResetEngines);
 
	IConsoleCmdRegister("return",       ConReturn);
 
	IConsoleCmdRegister("screenshot",   ConScreenShot);
 
@@ -1356,6 +1483,8 @@ void IConsoleStdLibRegister()
 
	IConsoleCmdRegister("rm",           ConRemove);
 
	IConsoleCmdRegister("save",         ConSave);
 
	IConsoleCmdRegister("saveconfig",   ConSaveConfig);
 
	IConsoleCmdRegister("start_ai",     ConStartAI);
 
	IConsoleCmdRegister("stop_ai",      ConStopAI);
 
	IConsoleCmdRegister("ls",           ConListFiles);
 
	IConsoleCmdRegister("cd",           ConChangeDirectory);
 
	IConsoleCmdRegister("pwd",          ConPrintWorkingDirectory);
src/core/enum_type.hpp
Show inline comments
 
@@ -74,7 +74,8 @@ template <typename Tenum_t> struct TinyE
 

	
 
/** The general declaration of TinyEnumT<> (above) */
 
template <typename Tenum_t>
 
struct TinyEnumT {
 
struct TinyEnumT
 
{
 
	typedef Tenum_t enum_type;                      ///< expose our enumeration type (i.e. Trackdir) to outside
 
	typedef EnumPropsT<Tenum_t> Props;              ///< make easier access to our enumeration propeties
 
	typedef typename Props::storage storage_type;   ///< small storage type
 
@@ -120,31 +121,4 @@ struct TinyEnumT {
 
	}
 
};
 

	
 

	
 
/** Template of struct holding enum types (on most archs, enums are stored in an int32). No math operators are provided. */
 
template <typename enum_type, typename storage_type>
 
struct SimpleTinyEnumT {
 
	storage_type m_val;  ///< here we hold the actual value in small (i.e. byte) form
 

	
 
	/** Cast operator - invoked then the value is assigned to the storage_type */
 
	FORCEINLINE operator enum_type () const
 
	{
 
		return (enum_type)this->m_val;
 
	}
 

	
 
	/** Assignment operator (from enum_type) */
 
	FORCEINLINE SimpleTinyEnumT &operator = (enum_type e)
 
	{
 
		this->m_val = (storage_type)e;
 
		return *this;
 
	}
 

	
 
	/** Assignment operator (from general uint) */
 
	FORCEINLINE SimpleTinyEnumT &operator = (uint u)
 
	{
 
		this->m_val = (storage_type)u;
 
		return *this;
 
	}
 
};
 

	
 
#endif /* ENUM_TYPE_HPP */
 
#endif /* HELPERS_HPP */
src/economy.cpp
Show inline comments
 
@@ -17,7 +17,7 @@
 
#include "network/network_func.h"
 
#include "variables.h"
 
#include "vehicle_gui.h"
 
#include "ai/ai.h"
 
#include "ai/ai.hpp"
 
#include "train.h"
 
#include "roadveh.h"
 
#include "aircraft.h"
 
@@ -480,6 +480,7 @@ static void CompanyCheckBankrupt(Company
 
			SetDParam(1, STR_7057_WILL_BE_SOLD_OFF_OR_DECLARED);
 
			SetDParamStr(2, cni->company_name);
 
			AddNewsItem(STR_02B6, NS_COMPANY_TROUBLE, 0, 0, cni);
 
			AI::BroadcastNewEvent(new AIEventCompanyInTrouble(c->index));
 
			break;
 
		case 3: {
 
			/* XXX - In multiplayer, should we ask other companies if it wants to take
 
@@ -529,12 +530,11 @@ static void CompanyCheckBankrupt(Company
 
			ChangeNetworkOwner(c->index, COMPANY_SPECTATOR);
 
			ChangeOwnershipOfCompanyItems(c->index, INVALID_OWNER);
 

	
 
			/* Register the company as not-active */
 
			if (!IsHumanCompany(c->index) && (!_networking || _network_server) && _ai.enabled) {
 
				AI_CompanyDied(c->index);
 
			}
 
			if (!IsHumanCompany(c->index)) AI::Stop(c->index);
 

	
 
			CompanyID c_index = c->index;
 
			delete c;
 
			AI::BroadcastNewEvent(new AIEventCompanyBankrupt(c_index));
 
	}
 
}
 

	
 
@@ -1065,6 +1065,7 @@ static void SubsidyMonthlyHandler()
 
			AddNewsItem(STR_202E_OFFER_OF_SUBSIDY_EXPIRED, NS_SUBSIDIES, pair.a, pair.b);
 
			s->cargo_type = CT_INVALID;
 
			modified = true;
 
			AI::BroadcastNewEvent(new AIEventSubsidyOfferExpired(s - _subsidies));
 
		} else if (s->age == 2*12-1) {
 
			st = GetStation(s->to);
 
			if (st->owner == _local_company) {
 
@@ -1073,6 +1074,7 @@ static void SubsidyMonthlyHandler()
 
			}
 
			s->cargo_type = CT_INVALID;
 
			modified = true;
 
			AI::BroadcastNewEvent(new AIEventSubsidyExpired(s - _subsidies));
 
		} else {
 
			s->age++;
 
		}
 
@@ -1109,6 +1111,7 @@ static void SubsidyMonthlyHandler()
 
					s->age = 0;
 
					pair = SetupSubsidyDecodeParam(s, 0);
 
					AddNewsItem(STR_2030_SERVICE_SUBSIDY_OFFERED, NS_SUBSIDIES, pair.a, pair.b);
 
					AI::BroadcastNewEvent(new AIEventSubsidyOffer(s - _subsidies));
 
					modified = true;
 
					break;
 
				}
 
@@ -1326,6 +1329,7 @@ static bool CheckSubsidised(Station *fro
 
				NS_SUBSIDIES,
 
				pair.a, pair.b
 
			);
 
			AI::BroadcastNewEvent(new AIEventSubsidyAwarded(s - _subsidies));
 

	
 
			InvalidateWindow(WC_SUBSIDIES_LIST, 0);
 
			return true;
 
@@ -1817,6 +1821,7 @@ static void DoAcquireCompany(Company *c)
 
	Company *owner;
 
	int i;
 
	Money value;
 
	CompanyID ci = c->index;
 

	
 
	CompanyNewsInformation *cni = MallocT<CompanyNewsInformation>(1);
 
	cni->FillData(c, GetCompany(_current_company));
 
@@ -1827,9 +1832,9 @@ static void DoAcquireCompany(Company *c)
 
	SetDParamStr(3, cni->other_company_name);
 
	SetDParam(4, c->bankrupt_value);
 
	AddNewsItem(STR_02B6, NS_COMPANY_MERGER, 0, 0, cni);
 
	AI::BroadcastNewEvent(new AIEventCompanyMerger(ci, _current_company));
 

	
 
	/* original code does this a little bit differently */
 
	CompanyID ci = c->index;
 
	ChangeNetworkOwner(ci, _current_company);
 
	ChangeOwnershipOfCompanyItems(ci, _current_company);
 

	
 
@@ -1848,6 +1853,8 @@ static void DoAcquireCompany(Company *c)
 
	}
 
	_current_company = old_company;
 

	
 
	if (!IsHumanCompany(c->index)) AI::Stop(c->index);
 

	
 
	DeleteCompanyWindows(ci);
 
	InvalidateWindowClassesData(WC_TRAINS_LIST, 0);
 
	InvalidateWindowClassesData(WC_SHIPS_LIST, 0);
src/engine.cpp
Show inline comments
 
@@ -24,6 +24,7 @@
 
#include "string_func.h"
 
#include "settings_type.h"
 
#include "oldpool_func.h"
 
#include "ai/ai.hpp"
 
#include "core/alloc_func.hpp"
 
#include "vehicle_func.h"
 

	
 
@@ -376,14 +377,10 @@ void EnginesDailyLoop()
 
					continue;
 
				}
 

	
 
				if (!IsHumanCompany(best_company)) {
 
					/* XXX - TTDBUG: TTD has a bug here ???? */
 
					AcceptEnginePreview(i, best_company);
 
				} else {
 
					e->flags |= ENGINE_OFFER_WINDOW_OPEN;
 
					e->preview_wait = 20;
 
					if (IsInteractiveCompany(best_company)) ShowEnginePreviewWindow(i);
 
				}
 
				e->flags |= ENGINE_OFFER_WINDOW_OPEN;
 
				e->preview_wait = 20;
 
				AI::NewEvent(best_company, new AIEventEnginePreview(i));
 
				if (IsInteractiveCompany(best_company)) ShowEnginePreviewWindow(i);
 
			}
 
		}
 
	}
 
@@ -460,6 +457,8 @@ static void NewVehicleAvailable(Engine *
 
		FOR_ALL_COMPANIES(c) SetBit(c->avail_roadtypes, HasBit(e->info.misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD);
 
	}
 

	
 
	AI::BroadcastNewEvent(new AIEventEngineAvailable(index));
 

	
 
	SetDParam(0, GetEngineCategoryName(index));
 
	SetDParam(1, index);
 
	AddNewsItem(STR_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE, NS_NEW_VEHICLES, index, 0);
src/fileio.cpp
Show inline comments
 
@@ -216,7 +216,8 @@ const char *_subdirs[NUM_SUBDIRS] = {
 
	"scenario" PATHSEP "heightmap" PATHSEP,
 
	"gm" PATHSEP,
 
	"data" PATHSEP,
 
	"lang" PATHSEP
 
	"lang" PATHSEP,
 
	"ai" PATHSEP,
 
};
 

	
 
const char *_searchpaths[NUM_SEARCHPATHS];
 
@@ -359,7 +360,7 @@ FILE *FioFOpenFile(const char *filename,
 
	}
 

	
 
	/* We can only use .tar in case of data-dir, and read-mode */
 
	if (f == NULL && subdir == DATA_DIR && mode[0] == 'r') {
 
	if (f == NULL && (subdir == DATA_DIR || subdir == AI_DIR) && mode[0] == 'r') {
 
		static const uint MAX_RESOLVED_LENGTH = 2 * (100 + 100 + 155) + 1; // Enough space to hold two filenames plus link. See 'TarHeader'.
 
		char resolved_name[MAX_RESOLVED_LENGTH];
 

	
 
@@ -466,6 +467,33 @@ char *BuildWithFullPath(const char *dir)
 
	return dest;
 
}
 

	
 
const char *FioTarFirstDir(const char *tarname)
 
{
 
	TarList::iterator it = _tar_list.find(tarname);
 
	if (it == _tar_list.end()) return NULL;
 
	return (*it).second.dirname;
 
}
 

	
 
static void TarAddLink(const std::string &src, const std::string &dest)
 
{
 
	TarFileList::iterator dest_file = _tar_filelist.find(dest);
 
	if (dest_file != _tar_filelist.end()) {
 
		/* Link to file. Process the link like the destination file. */
 
		_tar_filelist.insert(TarFileList::value_type(src, dest_file->second));
 
	} else {
 
		/* Destination file not found. Assume 'link to directory' */
 
		/* Append PATHSEPCHAR to 'src' and 'dest' if needed */
 
		const std::string src_path = ((*src.rbegin() == PATHSEPCHAR) ? src : src + PATHSEPCHAR);
 
		const std::string dst_path = (dest.length() == 0 ? "" : ((*dest.rbegin() == PATHSEPCHAR) ? dest : dest + PATHSEPCHAR));
 
		_tar_linklist.insert(TarLinkList::value_type(src_path, dst_path));
 
	}
 
}
 

	
 
void FioTarAddLink(const char *src, const char *dest)
 
{
 
	TarAddLink(src, dest);
 
}
 

	
 
/**
 
 * Simplify filenames from tars.
 
 * Replace '/' by PATHSEPCHAR, and force 'name' to lowercase.
 
@@ -515,6 +543,7 @@ static bool TarListAddFile(const char *f
 

	
 
	const char *dupped_filename = strdup(filename);
 
	_tar_list[filename].filename = dupped_filename;
 
	_tar_list[filename].dirname = NULL;
 

	
 
	TarLinkList links; ///< Temporary list to collect links
 

	
 
@@ -649,6 +678,15 @@ static bool TarListAddFile(const char *f
 
				break;
 
			}
 

	
 
			case '5': // directory
 
				/* Convert to lowercase and our PATHSEPCHAR */
 
				SimplifyFileName(name);
 

	
 
				/* Store the first directory name we detect */
 
				DEBUG(misc, 6, "Found dir in tar: %s", name);
 
				if (_tar_list[filename].dirname == NULL) _tar_list[filename].dirname = strdup(name);
 
				break;
 

	
 
			default:
 
				/* Ignore other types */
 
				break;
 
@@ -675,18 +713,7 @@ static bool TarListAddFile(const char *f
 
	for (TarLinkList::iterator link = links.begin(); link != links.end(); link++) {
 
		const std::string &src = link->first;
 
		const std::string &dest = link->second;
 

	
 
		TarFileList::iterator dest_file = _tar_filelist.find(dest);
 
		if (dest_file != _tar_filelist.end()) {
 
			/* Link to file. Process the link like the destination file. */
 
			_tar_filelist.insert(TarFileList::value_type(src, dest_file->second));
 
		} else {
 
			/* Destination file not found. Assume 'link to directory' */
 
			/* Append PATHSEPCHAR to 'src' and 'dest' */
 
			const std::string src_path = src + PATHSEPCHAR;
 
			const std::string dst_path = (dest.length() == 0 ? "" : dest + PATHSEPCHAR);
 
			_tar_linklist.insert(TarLinkList::value_type(src_path, dst_path));
 
		}
 
		TarAddLink(src, dest);
 
	}
 

	
 
	return true;
 
@@ -742,6 +769,8 @@ void ScanForTarFiles()
 
	FOR_ALL_SEARCHPATHS(sp) {
 
		FioAppendDirectory(path, MAX_PATH, sp, DATA_DIR);
 
		num += ScanPathForTarFiles(path, strlen(path));
 
		FioAppendDirectory(path, MAX_PATH, sp, AI_DIR);
 
		num += ScanPathForTarFiles(path, strlen(path));
 
	}
 
	DEBUG(misc, 1, "Scan complete, found %d files", num);
 
}
src/fileio_func.h
Show inline comments
 
@@ -61,6 +61,8 @@ void AppendPathSeparator(char *buf, size
 
void DeterminePaths(const char *exe);
 
void *ReadFileToMem(const char *filename, size_t *lenp, size_t maxsize);
 
bool FileExists(const char *filename);
 
const char *FioTarFirstDir(const char *tarname);
 
void FioTarAddLink(const char *src, const char *dest);
 

	
 
extern char *_personal_dir; ///< custom directory for personal settings, saves, newgrf, etc.
 

	
src/fileio_type.h
Show inline comments
 
@@ -19,6 +19,7 @@ enum Subdirectory {
 
	GM_DIR,        ///< Subdirectory for all music
 
	DATA_DIR,      ///< Subdirectory for all data (GRFs, sample.cat, intro game)
 
	LANG_DIR,      ///< Subdirectory for all translation files
 
	AI_DIR,        ///< Subdirectory for all AI files
 
	NUM_SUBDIRS,   ///< Number of subdirectories
 
	NO_DIRECTORY,  ///< A path without any base directory
 
};
src/genworld.cpp
Show inline comments
 
@@ -25,6 +25,7 @@
 
#include "settings_type.h"
 
#include "newgrf_storage.h"
 
#include "water.h"
 
#include "blitter/factory.hpp"
 
#include "tilehighlight_func.h"
 
#include "saveload/saveload.h"
 

	
 
@@ -298,7 +299,7 @@ void GenerateWorld(GenerateWorldMode mod
 
		_gw.thread = NULL;
 
	}
 

	
 
	if (_network_dedicated ||
 
	if (BlitterFactoryBase::GetCurrentBlitter()->GetScreenDepth() == 0 ||
 
	    (_gw.thread = ThreadObject::New(&_GenerateWorld, NULL)) == NULL) {
 
		DEBUG(misc, 1, "Cannot create genworld thread, reverting to single-threaded mode");
 
		_gw.threaded = false;
src/genworld_gui.cpp
Show inline comments
 
@@ -45,6 +45,7 @@ enum glwp_modes {
 
};
 

	
 
extern void SwitchMode(int new_mode);
 
extern void MakeNewgameSettingsLive();
 

	
 
static inline void SetNewLandscapeType(byte landscape)
 
{
 
@@ -230,7 +231,7 @@ void StartGeneratingLandscape(glwp_modes
 
	DeleteAllNonVitalWindows();
 

	
 
	/* Copy all XXX_newgame to XXX when coming from outside the editor */
 
	_settings_game = _settings_newgame;
 
	MakeNewgameSettingsLive();
 
	ResetGRFConfig(true);
 

	
 
	SndPlayFx(SND_15_BEEP);
 
@@ -399,7 +400,7 @@ struct GenerateLandscapeWindow : public 
 
				break;
 

	
 
			case GLAND_GENERATE_BUTTON: // Generate
 
				_settings_game = _settings_newgame;
 
				MakeNewgameSettingsLive();
 

	
 
				if (_settings_game.economy.town_layout == TL_NO_ROADS) {
 
					ShowQuery(
src/group.h
Show inline comments
 
@@ -92,4 +92,6 @@ void UpdateTrainGroupID(Vehicle *v);
 
void RemoveVehicleFromGroup(const Vehicle *v);
 
void RemoveAllGroupsForCompany(const CompanyID company);
 

	
 
extern GroupID _new_group_id;
 

	
 
#endif /* GROUP_H */
src/group_cmd.cpp
Show inline comments
 
@@ -25,6 +25,8 @@
 

	
 
#include "table/strings.h"
 

	
 
GroupID _new_group_id;
 

	
 
/**
 
 * Update the num engines of a groupID. Decrease the old one and increase the new one
 
 * @note called in SetTrainGroupID and UpdateTrainGroupID
 
@@ -91,6 +93,8 @@ CommandCost CmdCreateGroup(TileIndex til
 
		g->replace_protection = false;
 
		g->vehicle_type = vt;
 

	
 
		_new_group_id = g->index;
 

	
 
		InvalidateWindowData(GetWindowClassForVehicleType(vt), (vt << 11) | VLW_GROUP_LIST | _current_company);
 
	}
 

	
src/industry_cmd.cpp
Show inline comments
 
@@ -39,6 +39,7 @@
 
#include "oldpool_func.h"
 
#include "animated_tile_func.h"
 
#include "effectvehicle_func.h"
 
#include "ai/ai.hpp"
 

	
 
#include "table/strings.h"
 
#include "table/sprites.h"
 
@@ -432,7 +433,10 @@ static CommandCost ClearTile_Industry(Ti
 
		return_cmd_error(STR_4800_IN_THE_WAY);
 
	}
 

	
 
	if (flags & DC_EXEC) delete i;
 
	if (flags & DC_EXEC) {
 
		AI::BroadcastNewEvent(new AIEventIndustryClose(i->index));
 
		delete i;
 
	}
 
	return CommandCost(EXPENSES_CONSTRUCTION, indspec->GetRemovalCost());
 
}
 

	
 
@@ -1712,6 +1716,7 @@ CommandCost CmdBuildIndustry(TileIndex t
 
			SetDParam(1, ind->town->index);
 
		}
 
		AddNewsItem(indspec->new_industry_text, NS_INDUSTRY_OPEN, ind->xy, 0);
 
		AI::BroadcastNewEvent(new AIEventIndustryOpen(ind->index));
 
	}
 

	
 
	return CommandCost(EXPENSES_OTHER, indspec->GetConstructionCost());
 
@@ -1912,8 +1917,8 @@ static void MaybeNewIndustry(void)
 
	} else {
 
		SetDParam(1, ind->town->index);
 
	}
 
	AddNewsItem(ind_spc->new_industry_text,
 
		NS_INDUSTRY_OPEN, ind->xy, 0);
 
	AddNewsItem(ind_spc->new_industry_text, NS_INDUSTRY_OPEN, ind->xy, 0);
 
	AI::BroadcastNewEvent(new AIEventIndustryOpen(ind->index));
 
}
 

	
 
/**
 
@@ -2232,6 +2237,7 @@ static void ChangeIndustryProduction(Ind
 
		/* Compute news category */
 
		if (closeit) {
 
			ns = NS_INDUSTRY_CLOSE;
 
			AI::BroadcastNewEvent(new AIEventIndustryClose(i->index));
 
		} else {
 
			switch (WhoCanServiceIndustry(i)) {
 
				case 0: ns = NS_INDUSTRY_NOBODY;  break;
src/lang/english.txt
Show inline comments
 
@@ -801,6 +801,7 @@ STR_TRANSPARENT_SIGNS                   
 
STR_02D5_LAND_BLOCK_INFO                                        :Land area information
 
STR_02D6                                                        :
 
STR_CONSOLE_SETTING                                             :Toggle Console
 
STR_AI_DEBUG_MENU                                               :AI Debug
 
STR_02D7_SCREENSHOT_CTRL_S                                      :Screenshot (Ctrl-S)
 
STR_02D8_GIANT_SCREENSHOT_CTRL_G                                :Giant Screenshot (Ctrl-G)
 
STR_02D9_ABOUT_OPENTTD                                          :About 'OpenTTD'
 
@@ -1155,6 +1156,7 @@ STR_CONFIG_PATCHES_AI_BUILDS_SHIPS      
 

	
 
STR_CONFIG_PATCHES_AINEW_ACTIVE                                 :{LTBLUE}Enable new AI (alpha): {ORANGE}{STRING1}
 
STR_CONFIG_PATCHES_AI_IN_MULTIPLAYER                            :{LTBLUE}Allow AIs in multiplayer (experimental): {ORANGE}{STRING1}
 
STR_CONFIG_PATCHES_AI_MAX_OPCODES                               :{LTBLUE}#opcodes before AI is suspended: {ORANGE}{STRING1}
 

	
 
STR_CONFIG_PATCHES_SERVINT_TRAINS                               :{LTBLUE}Default service interval for trains: {ORANGE}{STRING1} days/%
 
STR_CONFIG_PATCHES_SERVINT_TRAINS_DISABLED                      :{LTBLUE}Default service interval for trains: {ORANGE}disabled
 
@@ -3677,6 +3679,14 @@ STR_OSK_KEYBOARD_LAYOUT                 
 
STR_OSK_KEYBOARD_LAYOUT_CAPS                                    :~!@#$%^&*()_+|QWERTYUIOP{{}}ASDFGHJKL:"  ZXCVBNM<>? .
 
########
 

	
 
############ AI GUI
 
STR_AI_DEBUG                                                    :{WHITE}AI Debug
 
STR_AI_DEBUG_NAME_TIP                                           :{BLACK}Name of the AI
 
STR_AI_DEBUG_RELOAD                                             :{BLACK}Reload AI
 
STR_AI_DEBUG_RELOAD_TIP                                         :{BLACK}Kill the AI, reload the script, and restart the AI
 
STR_AI_DEBUG_SERVER_ONLY                                        :{YELLOW}AI Debug window is only available for the server
 
########
 

	
 
############ town controlled noise level
 
STR_CONFIG_PATCHES_NOISE_LEVEL                                  :{LTBLUE}Allow town controlled noise level for airports: {ORANGE}{STRING}
 
STR_NOISE_IN_TOWN                                               :{BLACK}Noise limit in town: {ORANGE}{COMMA}{BLACK}  max: {ORANGE}{COMMA}
src/misc.cpp
Show inline comments
 
@@ -10,7 +10,7 @@
 
#include "vehicle_gui.h"
 
#include "variables.h"
 
#include "cheat_func.h"
 
#include "ai/ai.h"
 
#include "ai/ai.hpp"
 
#include "newgrf_house.h"
 
#include "cargotype.h"
 
#include "group.h"
 
@@ -26,6 +26,7 @@
 
#include "core/alloc_type.hpp"
 
#include "gamelog.h"
 
#include "animated_tile_func.h"
 
#include "settings_type.h"
 
#include "tilehighlight_func.h"
 
#include "core/bitmath_func.hpp"
 
#include "network/network_func.h"
 
@@ -34,6 +35,7 @@
 
#include "table/sprites.h"
 

	
 
extern TileIndex _cur_tileloop_tile;
 
extern void MakeNewgameSettingsLive();
 

	
 
void InitializeVehicles();
 
void InitializeWaypoints();
 
@@ -68,7 +70,7 @@ void InitializeGame(uint size_x, uint si
 
	_realtime_tick = 0;
 
	_date_fract = 0;
 
	_cur_tileloop_tile = 0;
 
	_settings_game = _settings_newgame;
 
	MakeNewgameSettingsLive();
 

	
 
	if (reset_date) {
 
		SetDate(ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1));
 
@@ -101,7 +103,7 @@ void InitializeGame(uint size_x, uint si
 
	InitializeNPF();
 

	
 
	InitializeCompanies();
 
	AI_Initialize();
 
	AI::Initialize();
 
	InitializeCheats();
 

	
 
	InitTextEffects();
src/misc_cmd.cpp
Show inline comments
 
@@ -128,9 +128,10 @@ CommandCost CmdSetCompanyColor(TileIndex
 
/** Increase the loan of your company.
 
 * @param tile unused
 
 * @param flags operation to perform
 
 * @param p1 unused
 
 * @param p1 amount to increase the loan with, multitude of LOAN_INTERVAL. Only used when p2 == 2.
 
 * @param p2 when 0: loans LOAN_INTERVAL
 
 *           when 1: loans the maximum loan permitting money (press CTRL),
 
 *           when 2: loans the amount specified in p1
 
 */
 
CommandCost CmdIncreaseLoan(TileIndex tile, uint32 flags, uint32 p1, uint32 p2, const char *text)
 
{
 
@@ -145,11 +146,15 @@ CommandCost CmdIncreaseLoan(TileIndex ti
 
	switch (p2) {
 
		default: return CMD_ERROR; // Invalid method
 
		case 0: // Take some extra loan
 
			loan = (IsHumanCompany(_current_company) || _settings_game.ai.ainew_active) ? LOAN_INTERVAL : LOAN_INTERVAL_OLD_AI;
 
			loan = LOAN_INTERVAL;
 
			break;
 
		case 1: // Take a loan as big as possible
 
			loan = _economy.max_loan - c->current_loan;
 
			break;
 
		case 2: // Take the given amount of loan
 
			if ((((int32)p1 < LOAN_INTERVAL) || c->current_loan + (int32)p1 > _economy.max_loan || (p1 % LOAN_INTERVAL) != 0)) return CMD_ERROR;
 
			loan = p1;
 
			break;
 
	}
 

	
 
	/* Overflow protection */
 
@@ -167,9 +172,10 @@ CommandCost CmdIncreaseLoan(TileIndex ti
 
/** Decrease the loan of your company.
 
 * @param tile unused
 
 * @param flags operation to perform
 
 * @param p1 unused
 
 * @param p1 amount to decrease the loan with, multitude of LOAN_INTERVAL. Only used when p2 == 2.
 
 * @param p2 when 0: pays back LOAN_INTERVAL
 
 *           when 1: pays back the maximum loan permitting money (press CTRL),
 
 *           when 2: pays back the amount specified in p1
 
 */
 
CommandCost CmdDecreaseLoan(TileIndex tile, uint32 flags, uint32 p1, uint32 p2, const char *text)
 
{
 
@@ -181,12 +187,16 @@ CommandCost CmdDecreaseLoan(TileIndex ti
 
	switch (p2) {
 
		default: return CMD_ERROR; // Invalid method
 
		case 0: // Pay back one step
 
			loan = min(c->current_loan, (Money)(IsHumanCompany(_current_company) || _settings_game.ai.ainew_active) ? LOAN_INTERVAL : LOAN_INTERVAL_OLD_AI);
 
			loan = min(c->current_loan, (Money)LOAN_INTERVAL);
 
			break;
 
		case 1: // Pay back as much as possible
 
			loan = max(min(c->current_loan, c->money), (Money)LOAN_INTERVAL);
 
			loan -= loan % LOAN_INTERVAL;
 
			break;
 
		case 2: // Repay the given amount of loan
 
			if ((p1 % LOAN_INTERVAL != 0) || ((int32)p1 < LOAN_INTERVAL)) return CMD_ERROR; // Invalid amount to loan
 
			loan = p1;
 
			break;
 
	}
 

	
 
	if (c->money < loan) {
src/network/network_client.cpp
Show inline comments
 
@@ -16,7 +16,6 @@
 
#include "../command_func.h"
 
#include "../console_func.h"
 
#include "../variables.h"
 
#include "../ai/ai.h"
 
#include "../core/alloc_func.hpp"
 
#include "../fileio_func.h"
 
#include "../md5.h"
 
@@ -26,6 +25,7 @@
 
#include "../company_func.h"
 
#include "../company_base.h"
 
#include "../company_gui.h"
 
#include "../settings_type.h"
 
#include "../rev.h"
 

	
 
#include "table/strings.h"
src/network/network_gui.cpp
Show inline comments
 
@@ -1170,8 +1170,8 @@ struct NetworkLobbyWindow : public Windo
 
		const NetworkGameInfo *gi = &this->server->info;
 
		int y = NET_PRC__OFFSET_TOP_WIDGET_COMPANY, pos;
 

	
 
		/* Join button is disabled when no company is selected */
 
		this->SetWidgetDisabledState(NLWW_JOIN, this->company == INVALID_COMPANY);
 
		/* Join button is disabled when no company is selected and for AI companies*/
 
		this->SetWidgetDisabledState(NLWW_JOIN, this->company == INVALID_COMPANY || GetLobbyCompanyInfo(this->company)->ai);
 
		/* Cannot start new company if there are too many */
 
		this->SetWidgetDisabledState(NLWW_NEW, gi->companies_on >= gi->companies_max);
 
		/* Cannot spectate if there are too many spectators */
src/network/network_server.cpp
Show inline comments
 
@@ -664,7 +664,7 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT
 
			}
 
			break;
 
		default: /* Join another company (companies 1-8 (index 0-7)) */
 
			if (!IsValidCompanyID(playas)) {
 
			if (!IsValidCompanyID(playas) || !IsHumanCompany(playas)) {
 
				SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_COMPANY_MISMATCH);
 
				return;
 
			}
src/network/network_type.h
Show inline comments
 
@@ -48,6 +48,7 @@ typedef uint8 ClientIndex;
 
struct NetworkCompanyStats {
 
	uint16 num_vehicle[NETWORK_VEHICLE_TYPES];      ///< How many vehicles are there of this type?
 
	uint16 num_station[NETWORK_STATION_TYPES];      ///< How many stations are there of this type?
 
	bool ai;                                        ///< Is this company an AI
 
};
 

	
 
/** Some state information of a company, especially for servers */
src/newgrf_cargo.h
Show inline comments
 
@@ -9,7 +9,7 @@
 
#include "cargo_type.h"
 
#include "gfx_type.h"
 

	
 
enum {
 
enum CargoClass {
 
	CC_NOAVAILABLE  = 0,       ///< No cargo class has been specified
 
	CC_PASSENGERS   = 1 <<  0, ///< Passengers
 
	CC_MAIL         = 1 <<  1, ///< Mail
src/newgrf_station.cpp
Show inline comments
 
@@ -32,7 +32,7 @@
 
#include "table/sprites.h"
 
#include "table/strings.h"
 

	
 
static StationClass _station_classes[STAT_CLASS_MAX];
 
StationClass _station_classes[STAT_CLASS_MAX];
 

	
 
enum {
 
	MAX_SPECLIST = 255,
src/openttd.cpp
Show inline comments
 
@@ -44,7 +44,8 @@
 
#include "signs_base.h"
 
#include "signs_func.h"
 
#include "waypoint.h"
 
#include "ai/ai.h"
 
#include "ai/ai.hpp"
 
#include "ai/ai_config.hpp"
 
#include "train.h"
 
#include "yapf/yapf.h"
 
#include "settings_func.h"
 
@@ -164,7 +165,7 @@ void CDECL ShowInfoF(const char *str, ..
 
 */
 
static void ShowHelp()
 
{
 
	char buf[4096];
 
	char buf[8192];
 
	char *p = buf;
 

	
 
	p += seprintf(p, lastof(buf), "OpenTTD %s\n", _openttd_revision);
 
@@ -176,6 +177,7 @@ static void ShowHelp()
 
		"  -s drv              = Set sound driver (see below) (param bufsize,hz)\n"
 
		"  -m drv              = Set music driver (see below)\n"
 
		"  -b drv              = Set the blitter to use (see below)\n"
 
		"  -a ai               = Force use of specific AI (see below)\n"
 
		"  -r res              = Set resolution (for instance 800x600)\n"
 
		"  -h                  = Display this help text\n"
 
		"  -t year             = Set starting year\n"
 
@@ -211,6 +213,11 @@ static void ShowHelp()
 
	/* List the blitters */
 
	p = BlitterFactoryBase::GetBlittersInfo(p, lastof(buf));
 

	
 
	/* We need to initialize the AI, so it finds the AIs */
 
	AI::Initialize();
 
	p = AI::GetConsoleList(p, lastof(buf));
 
	AI::Uninitialize(true);
 

	
 
	/* ShowInfo put output to stderr, but version information should go
 
	 * to stdout; this is the only exception */
 
#if !defined(WIN32) && !defined(WIN64)
 
@@ -321,7 +328,7 @@ static void InitializeDynamicVariables()
 
static void ShutdownGame()
 
{
 
	/* stop the AI */
 
	AI_Uninitialize();
 
	AI::Uninitialize(false);
 

	
 
	IConsoleFree();
 

	
 
@@ -382,6 +389,24 @@ static void LoadIntroGame()
 
	if (_music_driver->IsSongPlaying()) ResetMusic();
 
}
 

	
 
void MakeNewgameSettingsLive()
 
{
 
	for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) {
 
		if (_settings_game.ai_config[c] != NULL) {
 
			delete _settings_game.ai_config[c];
 
		}
 
	}
 

	
 
	_settings_game = _settings_newgame;
 

	
 
	for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) {
 
		_settings_game.ai_config[c] = NULL;
 
		if (_settings_newgame.ai_config[c] != NULL) {
 
			_settings_game.ai_config[c] = new AIConfig(_settings_newgame.ai_config[c]);
 
		}
 
	}
 
}
 

	
 
byte _savegame_sort_order;
 
#if defined(UNIX) && !defined(__MORPHOS__)
 
extern void DedicatedFork();
 
@@ -531,7 +556,9 @@ int ttd_main(int argc, char *argv[])
 
		DedicatedFork();
 
#endif
 

	
 
	AI::Initialize();
 
	LoadFromConfig();
 
	AI::Uninitialize(true);
 
	CheckConfig();
 
	LoadFromHighScore();
 

	
 
@@ -666,7 +693,7 @@ int ttd_main(int argc, char *argv[])
 
	if (_settings_newgame.difficulty.diff_level == 9) SetDifficultyLevel(0, &_settings_newgame.difficulty);
 

	
 
	/* Make sure _settings is filled with _settings_newgame if we switch to a game directly */
 
	if (_switch_mode != SM_NONE) _settings_game = _settings_newgame;
 
	if (_switch_mode != SM_NONE) MakeNewgameSettingsLive();
 

	
 
	/* initialize the ingame console */
 
	IConsoleInit();
 
@@ -750,14 +777,17 @@ static void MakeNewGameDone()
 
	SettingsDisableElrail(_settings_game.vehicle.disable_elrails);
 

	
 
	/* In a dedicated server, the server does not play */
 
	if (_network_dedicated) {
 
	if (BlitterFactoryBase::GetCurrentBlitter()->GetScreenDepth() == 0) {
 
		SetLocalCompany(COMPANY_SPECTATOR);
 
		IConsoleCmdExec("exec scripts/game_start.scr 0");
 
		return;
 
	}
 

	
 
	/* Create a single company */
 
	DoStartupNewCompany(false);
 

	
 
	IConsoleCmdExec("exec scripts/game_start.scr 0");
 

	
 
	SetLocalCompany(COMPANY_FIRST);
 
	_current_company = _local_company;
 
	DoCommandP(0, (_settings_client.gui.autorenew << 15 ) | (_settings_client.gui.autorenew_months << 16) | 4, _settings_client.gui.autorenew_money, CMD_SET_AUTOREPLACE);
 
@@ -909,7 +939,7 @@ void SwitchMode(int new_mode)
 
				/* check if we should reload the config */
 
				if (_settings_client.network.reload_cfg) {
 
					LoadFromConfig();
 
					_settings_game = _settings_newgame;
 
					MakeNewgameSettingsLive();
 
					ResetGRFConfig(false);
 
				}
 
				NetworkServerStart();
 
@@ -920,6 +950,8 @@ void SwitchMode(int new_mode)
 
		}
 
	}
 
#endif /* ENABLE_NETWORK */
 
	/* Make sure all AI controllers are gone at quiting game */
 
	if (new_mode != SM_SAVE) AI::KillAll();
 

	
 
	switch (new_mode) {
 
		case SM_EDITOR: /* Switch to scenario editor */
 
@@ -959,6 +991,8 @@ void SwitchMode(int new_mode)
 
				/* Update the local company for a loaded game. It is either always
 
				* company #1 (eg 0) or in the case of a dedicated server a spectator */
 
				SetLocalCompany(_network_dedicated ? COMPANY_SPECTATOR : COMPANY_FIRST);
 
				/* Execute the game-start script */
 
				IConsoleCmdExec("exec scripts/game_start.scr 0");
 
				/* Decrease pause counter (was increased from opening load dialog) */
 
				DoCommandP(0, 0, 0, CMD_PAUSE);
 
#ifdef ENABLE_NETWORK
 
@@ -1112,7 +1146,7 @@ void StateGameLoop()
 
		CallLandscapeTick();
 
		ClearStorageChanges(true);
 

	
 
		AI_RunGameLoop();
 
		AI::GameLoop();
 

	
 
		CallWindowTickEvent();
 
		NewsLoop();
src/rail_cmd.cpp
Show inline comments
 
@@ -308,7 +308,7 @@ static CommandCost CheckRailSlope(Slope 
 

	
 
	/* check track/slope combination */
 
	if ((f_new == FOUNDATION_INVALID) ||
 
			((f_new != FOUNDATION_NONE) && (!_settings_game.construction.build_on_slopes || _is_old_ai_company))) {
 
			((f_new != FOUNDATION_NONE) && (!_settings_game.construction.build_on_slopes))) {
 
		return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
 
	}
 

	
 
@@ -790,7 +790,6 @@ CommandCost CmdBuildTrainDepot(TileIndex
 
	 */
 

	
 
	if (tileh != SLOPE_FLAT && (
 
				_is_old_ai_company ||
 
				!_settings_game.construction.build_on_slopes ||
 
				IsSteepSlope(tileh) ||
 
				!CanBuildDepotByTileh(dir, tileh)
src/road_cmd.cpp
Show inline comments
 
@@ -925,10 +925,7 @@ static CommandCost ClearTile_Road(TileIn
 

	
 
			/* Clear the road if only one piece is on the tile OR the AI tries
 
			 * to clear town road OR we are not using the DC_AUTO flag */
 
			if ((CountBits(b) == 1 && GetRoadBits(tile, ROADTYPE_TRAM) == ROAD_NONE) ||
 
			    ((flags & DC_AI_BUILDING) && GetOtherRoadBits(tile, ROADTYPE_ROAD) == ROAD_NONE && IsRoadOwner(tile, ROADTYPE_ROAD, OWNER_TOWN)) ||
 
			    !(flags & DC_AUTO)
 
				) {
 
			if ((CountBits(b) == 1 && GetRoadBits(tile, ROADTYPE_TRAM) == ROAD_NONE) || !(flags & DC_AUTO)) {
 
				RoadTypes rts = GetRoadTypes(tile);
 
				CommandCost ret(EXPENSES_CONSTRUCTION);
 
				for (RoadType rt = ROADTYPE_ROAD; rt < ROADTYPE_END; rt++) {
src/roadveh_cmd.cpp
Show inline comments
 
@@ -38,6 +38,7 @@
 
#include "variables.h"
 
#include "autoreplace_gui.h"
 
#include "gfx_func.h"
 
#include "ai/ai.hpp"
 
#include "settings_type.h"
 
#include "order_func.h"
 
#include "depot_base.h"
 
@@ -617,6 +618,8 @@ static void RoadVehCrash(Vehicle *v)
 

	
 
	InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 

	
 
	AI::NewEvent(v->owner, new AIEventVehicleCrashed(v->index, v->tile));
 

	
 
	SetDParam(0, pass);
 
	AddNewsItem(
 
		(pass == 1) ?
 
@@ -803,6 +806,7 @@ static void RoadVehArrivesAt(const Vehic
 
				v->index,
 
				st->index
 
			);
 
			AI::NewEvent(v->owner, new AIEventStationFirstVehicle(st->index, v->index));
 
		}
 
	} else {
 
		/* Check if station was ever visited before */
 
@@ -815,6 +819,7 @@ static void RoadVehArrivesAt(const Vehic
 
				v->index,
 
				st->index
 
			);
 
			AI::NewEvent(v->owner, new AIEventStationFirstVehicle(st->index, v->index));
 
		}
 
	}
 
}
src/saveload/afterload.cpp
Show inline comments
 
@@ -48,6 +48,7 @@
 
#include "../company_func.h"
 
#include "../command_func.h"
 
#include "../road_cmd.h"
 
#include "../ai/ai.hpp"
 

	
 
#include "table/strings.h"
 

	
 
@@ -468,6 +469,14 @@ bool AfterLoadGame()
 
	/* Update all vehicles */
 
	AfterLoadVehicles(true);
 

	
 
	/* Make sure there is an AI attached to an AI company */
 
	{
 
		Company *c;
 
		FOR_ALL_COMPANIES(c) {
 
			if (c->is_ai && c->ai_instance == NULL) AI::StartNew(c->index);
 
		}
 
	}
 

	
 
	/* Update all waypoints */
 
	if (CheckSavegameVersion(12)) FixOldWaypoints();
 

	
src/saveload/ai_sl.cpp
Show inline comments
 
/* $Id$ */
 

	
 
/** @file ai_sl.cpp Code handling saving and loading of old AI + new AI initialisation after game load */
 
/** @file ai_sl.cpp Handles the saveload part of the AIs */
 

	
 
#include "../stdafx.h"
 
#include "../ai/ai.h"
 
#include "../ai/default/default.h"
 

	
 
#include "../openttd.h"
 
#include "../company_base.h"
 
#include "../company_func.h"
 
#include "../debug.h"
 
#include "saveload.h"
 

	
 
static const SaveLoad _company_ai_desc[] = {
 
	    SLE_VAR(CompanyAI, state,             SLE_UINT8),
 
	    SLE_VAR(CompanyAI, tick,              SLE_UINT8),
 
	SLE_CONDVAR(CompanyAI, state_counter,     SLE_FILE_U16 | SLE_VAR_U32,  0, 12),
 
	SLE_CONDVAR(CompanyAI, state_counter,     SLE_UINT32,                 13, SL_MAX_VERSION),
 
	    SLE_VAR(CompanyAI, timeout_counter,   SLE_UINT16),
 

	
 
	    SLE_VAR(CompanyAI, state_mode,        SLE_UINT8),
 
	    SLE_VAR(CompanyAI, banned_tile_count, SLE_UINT8),
 
	    SLE_VAR(CompanyAI, railtype_to_use,   SLE_UINT8),
 

	
 
	    SLE_VAR(CompanyAI, cargo_type,        SLE_UINT8),
 
	    SLE_VAR(CompanyAI, num_wagons,        SLE_UINT8),
 
	    SLE_VAR(CompanyAI, build_kind,        SLE_UINT8),
 
	    SLE_VAR(CompanyAI, num_build_rec,     SLE_UINT8),
 
	    SLE_VAR(CompanyAI, num_loco_to_build, SLE_UINT8),
 
	    SLE_VAR(CompanyAI, num_want_fullload, SLE_UINT8),
 
#include "../settings_type.h"
 
#include "../string_func.h"
 
#include "../ai/ai.hpp"
 
#include "../ai/ai_config.hpp"
 

	
 
	    SLE_VAR(CompanyAI, route_type_mask,   SLE_UINT8),
 

	
 
	SLE_CONDVAR(CompanyAI, start_tile_a,      SLE_FILE_U16 | SLE_VAR_U32,  0,  5),
 
	SLE_CONDVAR(CompanyAI, start_tile_a,      SLE_UINT32,                  6, SL_MAX_VERSION),
 
	SLE_CONDVAR(CompanyAI, cur_tile_a,        SLE_FILE_U16 | SLE_VAR_U32,  0,  5),
 
	SLE_CONDVAR(CompanyAI, cur_tile_a,        SLE_UINT32,                  6, SL_MAX_VERSION),
 
	    SLE_VAR(CompanyAI, start_dir_a,       SLE_UINT8),
 
	    SLE_VAR(CompanyAI, cur_dir_a,         SLE_UINT8),
 
static char _ai_saveload_ainame[64];
 
static char _ai_company_convert_array[1024];
 

	
 
	SLE_CONDVAR(CompanyAI, start_tile_b,      SLE_FILE_U16 | SLE_VAR_U32,  0,  5),
 
	SLE_CONDVAR(CompanyAI, start_tile_b,      SLE_UINT32,                  6, SL_MAX_VERSION),
 
	SLE_CONDVAR(CompanyAI, cur_tile_b,        SLE_FILE_U16 | SLE_VAR_U32,  0,  5),
 
	SLE_CONDVAR(CompanyAI, cur_tile_b,        SLE_UINT32,                  6, SL_MAX_VERSION),
 
	    SLE_VAR(CompanyAI, start_dir_b,       SLE_UINT8),
 
	    SLE_VAR(CompanyAI, cur_dir_b,         SLE_UINT8),
 

	
 
	    SLE_REF(CompanyAI, cur_veh,           REF_VEHICLE),
 

	
 
	    SLE_ARR(CompanyAI, wagon_list,        SLE_UINT16, 9),
 
	    SLE_ARR(CompanyAI, order_list_blocks, SLE_UINT8, 20),
 
	    SLE_ARR(CompanyAI, banned_tiles,      SLE_UINT16, 16),
 

	
 
	SLE_CONDNULL(64, 2, SL_MAX_VERSION),
 
static const SaveLoad _ai_company[] = {
 
	SLEG_STR(_ai_saveload_ainame,       SLE_STRB),
 
	SLEG_STR(_ai_company_convert_array, SLE_STRB),
 
	SLE_END()
 
};
 

	
 
static const SaveLoad _company_ai_build_rec_desc[] = {
 
	SLE_CONDVAR(AiBuildRec, spec_tile,         SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
 
	SLE_CONDVAR(AiBuildRec, spec_tile,         SLE_UINT32,                 6, SL_MAX_VERSION),
 
	SLE_CONDVAR(AiBuildRec, use_tile,          SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
 
	SLE_CONDVAR(AiBuildRec, use_tile,          SLE_UINT32,                 6, SL_MAX_VERSION),
 
	    SLE_VAR(AiBuildRec, rand_rng,          SLE_UINT8),
 
	    SLE_VAR(AiBuildRec, cur_building_rule, SLE_UINT8),
 
	    SLE_VAR(AiBuildRec, unk6,              SLE_UINT8),
 
	    SLE_VAR(AiBuildRec, unk7,              SLE_UINT8),
 
	    SLE_VAR(AiBuildRec, buildcmd_a,        SLE_UINT8),
 
	    SLE_VAR(AiBuildRec, buildcmd_b,        SLE_UINT8),
 
	    SLE_VAR(AiBuildRec, direction,         SLE_UINT8),
 
	    SLE_VAR(AiBuildRec, cargo,             SLE_UINT8),
 
	SLE_END()
 
};
 
static void SaveReal_AIPL(int *index_ptr)
 
{
 
	CompanyID index = (CompanyID)*index_ptr;
 
	AIConfig *config = AIConfig::GetConfig(index);
 

	
 
	ttd_strlcpy(_ai_saveload_ainame, config->GetName(), lengthof(_ai_saveload_ainame));
 

	
 
	_ai_company_convert_array[0] = '\0';
 
	config->SettingsToString(_ai_company_convert_array, lengthof(_ai_company_convert_array));
 

	
 
	SlObject(NULL, _ai_company);
 
	/* If the AI was active, store his data too */
 
	if (IsValidCompanyID(index) && !IsHumanCompany(index)) AI::Save(index);
 
}
 

	
 
static void Load_AIPL()
 
{
 
	/* Free all current data */
 
	for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) {
 
		AIConfig::GetConfig(c)->ChangeAI(NULL);
 
	}
 

	
 
	CompanyID index;
 
	while ((index = (CompanyID)SlIterateArray()) != (CompanyID)-1) {
 
		AIConfig *config = AIConfig::GetConfig(index);
 
		SlObject(NULL, _ai_company);
 

	
 
void SaveLoad_AI(CompanyID company)
 
{
 
	CompanyAI *cai = &_companies_ai[company];
 
	SlObject(cai, _company_ai_desc);
 
	for (int i = 0; i != cai->num_build_rec; i++) {
 
		SlObject(&cai->src + i, _company_ai_build_rec_desc);
 
		if (_ai_saveload_ainame[0] == '\0' || AI::GetCompanyInfo(_ai_saveload_ainame) == NULL) {
 
			if (strcmp(_ai_saveload_ainame, "%_dummy") != 0) {
 
				DEBUG(ai, 0, "The savegame has an AI by the name '%s' which is no longer available.", _ai_saveload_ainame);
 
				DEBUG(ai, 0, "A random other AI will be loaded in its place.");
 
			} else {
 
				DEBUG(ai, 0, "The savegame had no AIs available at the time of saving.");
 
				DEBUG(ai, 0, "A random available AI will be loaded now.");
 
			}
 
			config->ChangeAI(NULL);
 
		} else {
 
			config->ChangeAI(_ai_saveload_ainame);
 
		}
 

	
 
		config->StringToSettings(_ai_company_convert_array);
 

	
 
		/* Start the AI directly if it was active in the savegame */
 
		if (IsValidCompanyID(index) && !IsHumanCompany(index)) {
 
			AI::StartNew(index);
 
			AI::Load(index);
 
		}
 
	}
 
}
 

	
 
static void Save_AIPL()
 
{
 
	for (int i = COMPANY_FIRST; i < MAX_COMPANIES; i++) {
 
		if (!AIConfig::GetConfig((CompanyID)i)->HasAI()) continue;
 

	
 
		SlSetArrayIndex(i);
 
		SlAutolength((AutolengthProc *)SaveReal_AIPL, &i);
 
	}
 
}
 

	
 
extern const ChunkHandler _ai_chunk_handlers[] = {
 
	{ 'AIPL', Save_AIPL, Load_AIPL, CH_ARRAY | CH_LAST},
 
};
src/saveload/company_sl.cpp
Show inline comments
 
@@ -6,8 +6,7 @@
 
#include "../company_base.h"
 
#include "../company_func.h"
 
#include "../network/network.h"
 
#include "../ai/ai.h"
 
#include "../ai/trolly/trolly.h"
 
#include "../ai/ai.hpp"
 
#include "../company_manager_face.h"
 

	
 
#include "saveload.h"
 
@@ -130,7 +129,8 @@ static const SaveLoad _company_desc[] = 
 
	SLE_CONDARR(Company, yearly_expenses,       SLE_FILE_I32 | SLE_VAR_I64, 3 * 13, 0, 1),
 
	SLE_CONDARR(Company, yearly_expenses,       SLE_INT64, 3 * 13,                  2, SL_MAX_VERSION),
 

	
 
	SLE_CONDVAR(Company, is_ai,                 SLE_BOOL, 2, SL_MAX_VERSION),
 
	SLE_CONDVAR(Company, is_ai,                 SLE_BOOL,                    2, SL_MAX_VERSION),
 
	SLE_CONDVAR(Company, is_noai,               SLE_BOOL,                  107, SL_MAX_VERSION),
 
	SLE_CONDNULL(1, 4, 99),
 

	
 
	/* Engine renewal settings */
 
@@ -141,7 +141,7 @@ static const SaveLoad _company_desc[] = 
 
	SLE_CONDVAR(Company, engine_renew_money,    SLE_UINT32,                 16, SL_MAX_VERSION),
 
	SLE_CONDVAR(Company, renew_keep_length,     SLE_BOOL,                    2, SL_MAX_VERSION), // added with 16.1, but was blank since 2
 

	
 
	/* reserve extra space in savegame here. (currently 63 bytes) */
 
	/* Reserve extra space in savegame here. (currently 63 bytes) */
 
	SLE_CONDNULL(63, 2, SL_MAX_VERSION),
 

	
 
	SLE_END()
 
@@ -162,6 +162,51 @@ static const SaveLoad _company_economy_d
 
	SLE_END()
 
};
 

	
 
/* We do need to read this single value, as the bigger it gets, the more data is stored */
 
struct CompanyOldAI {
 
	uint8 num_build_rec;
 
};
 

	
 
static const SaveLoad _company_ai_desc[] = {
 
	SLE_CONDNULL(2,  0, 106),
 
	SLE_CONDNULL(2,  0, 12),
 
	SLE_CONDNULL(4, 13, 106),
 
	SLE_CONDNULL(8,  0, 106),
 
	 SLE_CONDVAR(CompanyOldAI, num_build_rec, SLE_UINT8, 0, 106),
 
	SLE_CONDNULL(3,  0, 106),
 

	
 
	SLE_CONDNULL(2,  0,  5),
 
	SLE_CONDNULL(4,  6, 106),
 
	SLE_CONDNULL(2,  0,  5),
 
	SLE_CONDNULL(4,  6, 106),
 
	SLE_CONDNULL(2,  0, 106),
 

	
 
	SLE_CONDNULL(2,  0,  5),
 
	SLE_CONDNULL(4,  6, 106),
 
	SLE_CONDNULL(2,  0,  5),
 
	SLE_CONDNULL(4,  6, 106),
 
	SLE_CONDNULL(2,  0, 106),
 

	
 
	SLE_CONDNULL(2,  0, 68),
 
	SLE_CONDNULL(4,  69, 106),
 

	
 
	SLE_CONDNULL(18, 0, 106),
 
	SLE_CONDNULL(20, 0, 106),
 
	SLE_CONDNULL(32, 0, 106),
 

	
 
	SLE_CONDNULL(64, 2, 106),
 
	SLE_END()
 
};
 

	
 
static const SaveLoad _company_ai_build_rec_desc[] = {
 
	SLE_CONDNULL(2, 0, 5),
 
	SLE_CONDNULL(4, 6, 106),
 
	SLE_CONDNULL(2, 0, 5),
 
	SLE_CONDNULL(4, 6, 106),
 
	SLE_CONDNULL(8, 0, 106),
 
	SLE_END()
 
};
 

	
 
static const SaveLoad _company_livery_desc[] = {
 
	SLE_CONDVAR(Livery, in_use,  SLE_BOOL,  34, SL_MAX_VERSION),
 
	SLE_CONDVAR(Livery, colour1, SLE_UINT8, 34, SL_MAX_VERSION),
 
@@ -175,10 +220,15 @@ static void SaveLoad_PLYR(Company *c)
 

	
 
	SlObject(c, _company_desc);
 

	
 
	/* Write AI? */
 
	if (!IsHumanCompany(c->index)) {
 
		extern void SaveLoad_AI(CompanyID company);
 
		SaveLoad_AI(c->index);
 
	/* Keep backwards compatible for savegames, so load the old AI block */
 
	if (!IsHumanCompany(c->index) && !c->is_noai) {
 
		CompanyOldAI old_ai;
 
		char nothing;
 

	
 
		SlObject(&old_ai, _company_ai_desc);
 
		for (i = 0; i != old_ai.num_build_rec; i++) {
 
			SlObject(&nothing, _company_ai_build_rec_desc);
 
		}
 
	}
 

	
 
	/* Write economy */
 
@@ -225,13 +275,7 @@ static void Load_PLYR()
 
		Company *c = new (index) Company();
 
		SaveLoad_PLYR(c);
 
		_company_colours[index] = c->colour;
 

	
 
		/* This is needed so an AI is attached to a loaded AI */
 
		if (c->is_ai && (!_networking || _network_server) && _ai.enabled) {
 
			/* Clear the memory of the new AI, otherwise we might be doing wrong things. */
 
			memset(&_companies_ainew[index], 0, sizeof(CompanyAiNew));
 
			AI_StartNewAI(c->index);
 
		}
 
		c->is_noai = true;
 
	}
 
}
 

	
src/saveload/oldloader.cpp
Show inline comments
 
@@ -17,8 +17,7 @@
 
#include "../debug.h"
 
#include "../depot_base.h"
 
#include "../newgrf_config.h"
 
#include "../ai/ai.h"
 
#include "../ai/default/default.h"
 
#include "../ai/ai.hpp"
 
#include "../zoom_func.h"
 
#include "../functions.h"
 
#include "../date_func.h"
 
@@ -805,145 +804,6 @@ static bool OldCompanyEconomy(LoadgameSt
 
	return true;
 
}
 

	
 
static const OldChunks _company_ai_build_rec_chunk[] = {
 
	OCL_SVAR(   OC_TILE, AiBuildRec, spec_tile ),
 
	OCL_SVAR(   OC_TILE, AiBuildRec, use_tile ),
 
	OCL_SVAR(  OC_UINT8, AiBuildRec, rand_rng ),
 
	OCL_SVAR(  OC_UINT8, AiBuildRec, cur_building_rule ),
 
	OCL_SVAR(  OC_UINT8, AiBuildRec, unk6 ),
 
	OCL_SVAR(  OC_UINT8, AiBuildRec, unk7 ),
 
	OCL_SVAR(  OC_UINT8, AiBuildRec, buildcmd_a ),
 
	OCL_SVAR(  OC_UINT8, AiBuildRec, buildcmd_b ),
 
	OCL_SVAR(  OC_UINT8, AiBuildRec, direction ),
 
	OCL_SVAR(  OC_UINT8, AiBuildRec, cargo ),
 

	
 
	OCL_NULL( 8 ),  ///< Junk...
 

	
 
	OCL_END()
 
};
 

	
 
static bool OldLoadAIBuildRec(LoadgameState *ls, int num)
 
{
 
	Company *c = GetCompany(_current_company_id);
 

	
 
	switch (num) {
 
		case 0: return LoadChunk(ls, &_companies_ai[c->index].src,  _company_ai_build_rec_chunk);
 
		case 1: return LoadChunk(ls, &_companies_ai[c->index].dst,  _company_ai_build_rec_chunk);
 
		case 2: return LoadChunk(ls, &_companies_ai[c->index].mid1, _company_ai_build_rec_chunk);
 
		case 3: return LoadChunk(ls, &_companies_ai[c->index].mid2, _company_ai_build_rec_chunk);
 
	}
 

	
 
	return false;
 
}
 
static const OldChunks _company_ai_chunk[] = {
 
	OCL_SVAR(  OC_UINT8, CompanyAI, state ),
 
	OCL_NULL( 1 ),         ///< Junk
 
	OCL_SVAR(  OC_UINT8, CompanyAI, state_mode ),
 
	OCL_SVAR( OC_UINT16, CompanyAI, state_counter ),
 
	OCL_SVAR( OC_UINT16, CompanyAI, timeout_counter ),
 

	
 
	OCL_CHUNK( 4, OldLoadAIBuildRec ),
 

	
 
	OCL_NULL( 20 ),        ///< More junk
 

	
 
	OCL_SVAR(  OC_UINT8, CompanyAI, cargo_type ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, num_wagons ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, build_kind ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, num_build_rec ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, num_loco_to_build ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, num_want_fullload ),
 

	
 
	OCL_NULL( 14 ),        ///< Oh no more junk :|
 

	
 
	OCL_NULL( 2 ),         ///< Loco-id, not used
 

	
 
	OCL_SVAR( OC_UINT16, CompanyAI, wagon_list[0] ),
 
	OCL_SVAR( OC_UINT16, CompanyAI, wagon_list[1] ),
 
	OCL_SVAR( OC_UINT16, CompanyAI, wagon_list[2] ),
 
	OCL_SVAR( OC_UINT16, CompanyAI, wagon_list[3] ),
 
	OCL_SVAR( OC_UINT16, CompanyAI, wagon_list[4] ),
 
	OCL_SVAR( OC_UINT16, CompanyAI, wagon_list[5] ),
 
	OCL_SVAR( OC_UINT16, CompanyAI, wagon_list[6] ),
 
	OCL_SVAR( OC_UINT16, CompanyAI, wagon_list[7] ),
 
	OCL_SVAR( OC_UINT16, CompanyAI, wagon_list[8] ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[0] ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[1] ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[2] ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[3] ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[4] ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[5] ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[6] ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[7] ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[8] ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[9] ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[10] ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[11] ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[12] ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[13] ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[14] ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[15] ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[16] ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[17] ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[18] ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[19] ),
 

	
 
	OCL_SVAR( OC_UINT16, CompanyAI, start_tile_a ),
 
	OCL_SVAR( OC_UINT16, CompanyAI, start_tile_b ),
 
	OCL_SVAR( OC_UINT16, CompanyAI, cur_tile_a ),
 
	OCL_SVAR( OC_UINT16, CompanyAI, cur_tile_b ),
 

	
 
	OCL_SVAR(  OC_UINT8, CompanyAI, start_dir_a ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, start_dir_b ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, cur_dir_a ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, cur_dir_b ),
 

	
 
	OCL_SVAR(  OC_UINT8, CompanyAI, banned_tile_count ),
 

	
 
	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[0] ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[0] ),
 
	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[1] ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[1] ),
 
	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[2] ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[2] ),
 
	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[3] ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[3] ),
 
	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[4] ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[4] ),
 
	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[5] ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[5] ),
 
	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[6] ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[6] ),
 
	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[7] ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[7] ),
 
	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[8] ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[8] ),
 
	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[9] ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[9] ),
 
	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[10] ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[10] ),
 
	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[11] ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[11] ),
 
	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[12] ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[12] ),
 
	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[13] ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[13] ),
 
	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[14] ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[14] ),
 
	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[15] ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[15] ),
 

	
 
	OCL_SVAR(  OC_UINT8, CompanyAI, railtype_to_use ),
 
	OCL_SVAR(  OC_UINT8, CompanyAI, route_type_mask ),
 

	
 
	OCL_END()
 
};
 

	
 
static bool OldCompanyAI(LoadgameState *ls, int num)
 
{
 
	return LoadChunk(ls, &_companies_ai[_current_company_id], _company_ai_chunk);
 
}
 

	
 
uint8 ai_tick;
 
static const OldChunks _company_chunk[] = {
 
	OCL_VAR ( OC_UINT16,   1, &_old_string_id ),
 
	OCL_SVAR( OC_UINT32, Company, name_2 ),
 
@@ -970,10 +830,10 @@ static const OldChunks _company_chunk[] 
 
	OCL_SVAR(                  OC_TILE, Company, last_build_coordinate ),
 
	OCL_SVAR(                 OC_UINT8, Company, num_valid_stat_ent ),
 

	
 
	OCL_CHUNK( 1, OldCompanyAI ),
 
	OCL_NULL( 230 ),         // Old AI
 

	
 
	OCL_SVAR(  OC_UINT8, Company, block_preview ),
 
	 OCL_VAR(  OC_UINT8,   1, &ai_tick ),
 
	OCL_NULL( 1 ),           // Old AI
 
	OCL_SVAR(  OC_UINT8, Company, avail_railtypes ),
 
	OCL_SVAR(   OC_TILE, Company, location_of_HQ ),
 
	OCL_SVAR(  OC_UINT8, Company, share_owners[0] ),
 
@@ -1001,7 +861,6 @@ static bool LoadOldCompany(LoadgameState
 

	
 
	c->name_1 = RemapOldStringID(_old_string_id);
 
	c->president_name_1 = RemapOldStringID(_old_string_id_2);
 
	_companies_ai[_current_company_id].tick = ai_tick;
 

	
 
	if (num == 0) {
 
		/* If the first company has no name, make sure we call it UNNAMED */
 
@@ -1023,15 +882,6 @@ static bool LoadOldCompany(LoadgameState
 
	_company_colours[num] = c->colour;
 
	c->inaugurated_year -= ORIGINAL_BASE_YEAR;
 

	
 
	/* State 20 for AI companies is sell vehicle. Since the AI struct is not
 
	 * really figured out as of now, _companies_ai[c->index].cur_veh; needed for 'sell vehicle'
 
	 * is NULL and the function will crash. To fix this, just change the state
 
	 * to some harmless state, like 'loop vehicle'; 1 */
 
	if (!IsHumanCompany((CompanyID)num) && _companies_ai[c->index].state == 20) _companies_ai[c->index].state = 1;
 

	
 
	if (c->is_ai && (!_networking || _network_server) && _ai.enabled)
 
		AI_StartNewAI(c->index);
 

	
 
	return true;
 
}
 

	
src/saveload/saveload.cpp
Show inline comments
 
@@ -42,7 +42,7 @@
 

	
 
#include <list>
 

	
 
extern const uint16 SAVEGAME_VERSION = 106;
 
extern const uint16 SAVEGAME_VERSION = 107;
 

	
 
SavegameType _savegame_type; ///< type of savegame we are loading
 

	
 
@@ -1318,6 +1318,7 @@ extern const ChunkHandler _station_chunk
 
extern const ChunkHandler _industry_chunk_handlers[];
 
extern const ChunkHandler _economy_chunk_handlers[];
 
extern const ChunkHandler _subsidy_chunk_handlers[];
 
extern const ChunkHandler _ai_chunk_handlers[];
 
extern const ChunkHandler _animated_tile_chunk_handlers[];
 
extern const ChunkHandler _newgrf_chunk_handlers[];
 
extern const ChunkHandler _group_chunk_handlers[];
 
@@ -1343,6 +1344,7 @@ static const ChunkHandler * const _chunk
 
	_sign_chunk_handlers,
 
	_station_chunk_handlers,
 
	_company_chunk_handlers,
 
	_ai_chunk_handlers,
 
	_animated_tile_chunk_handlers,
 
	_newgrf_chunk_handlers,
 
	_group_chunk_handlers,
src/script/squirrel.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file squirrel.cpp the implementation of the Squirrel class. It handles all Squirrel-stuff and gives a nice API back to work with. */
 

	
 
#include <squirrel.h>
 
#include <stdarg.h>
 
#include "../stdafx.h"
 
#include "../debug.h"
 
#include "squirrel.hpp"
 
#include "squirrel_std.hpp"
 
#include "../fileio_func.h"
 
#include <sqstdaux.h>
 
#include <../squirrel/sqpcheader.h>
 
#include <../squirrel/sqvm.h>
 

	
 
void Squirrel::CompileError(HSQUIRRELVM vm, const SQChar *desc, const SQChar *source, SQInteger line, SQInteger column)
 
{
 
	SQChar buf[1024];
 

	
 
#ifdef _SQ64
 
	scsnprintf(buf, lengthof(buf), _SC("Error %s:%ld/%ld: %s"), source, line, column, desc);
 
#else
 
	scsnprintf(buf, lengthof(buf), _SC("Error %s:%d/%d: %s"), source, line, column, desc);
 
#endif
 

	
 
	/* Check if we have a custom print function */
 
	SQPrintFunc *func = ((Squirrel *)sq_getforeignptr(vm))->print_func;
 
	if (func == NULL) {
 
		scfprintf(stderr, _SC("%s"), buf);
 
	} else {
 
		(*func)(true, buf);
 
	}
 
}
 

	
 
void Squirrel::ErrorPrintFunc(HSQUIRRELVM vm, const SQChar *s, ...)
 
{
 
	va_list arglist;
 
	SQChar buf[1024];
 

	
 
	va_start(arglist, s);
 
	scvsnprintf(buf, lengthof(buf), s, arglist);
 
	va_end(arglist);
 

	
 
	/* Check if we have a custom print function */
 
	SQPrintFunc *func = ((Squirrel *)sq_getforeignptr(vm))->print_func;
 
	if (func == NULL) {
 
		scfprintf(stderr, _SC("%s"), buf);
 
	} else {
 
		(*func)(true, buf);
 
	}
 
}
 

	
 
void Squirrel::RunError(HSQUIRRELVM vm, const SQChar *error)
 
{
 
	/* Set the print function to something that prints to stderr */
 
	SQPRINTFUNCTION pf = sq_getprintfunc(vm);
 
	sq_setprintfunc(vm, &Squirrel::ErrorPrintFunc);
 

	
 
	/* Check if we have a custom print function */
 
	SQChar buf[1024];
 
	scsnprintf(buf, lengthof(buf), _SC("Your script made an error: %s\n"), error);
 
	SQPrintFunc *func = ((Squirrel *)sq_getforeignptr(vm))->print_func;
 
	if (func == NULL) {
 
		scfprintf(stderr, _SC("%s"), buf);
 
	} else {
 
		(*func)(true, buf);
 
	}
 

	
 
	/* Print below the error the stack, so the users knows what is happening */
 
	sqstd_printcallstack(vm);
 
	/* Reset the old print function */
 
	sq_setprintfunc(vm, pf);
 
}
 

	
 
SQInteger Squirrel::_RunError(HSQUIRRELVM vm)
 
{
 
	const SQChar *sErr = 0;
 

	
 
	if (sq_gettop(vm) >= 1) {
 
		if (SQ_SUCCEEDED(sq_getstring(vm, -1, &sErr))) {
 
			Squirrel::RunError(vm, sErr);
 
			return 0;
 
		}
 
	}
 

	
 
	Squirrel::RunError(vm, _SC("unknown error"));
 
	return 0;
 
}
 

	
 
void Squirrel::PrintFunc(HSQUIRRELVM vm, const SQChar *s, ...)
 
{
 
	va_list arglist;
 
	SQChar buf[1024];
 

	
 
	va_start(arglist, s);
 
	scvsnprintf(buf, lengthof(buf) - 2, s, arglist);
 
	va_end(arglist);
 
	scstrcat(buf, _SC("\n"));
 

	
 
	/* Check if we have a custom print function */
 
	SQPrintFunc *func = ((Squirrel *)sq_getforeignptr(vm))->print_func;
 
	if (func == NULL) {
 
		scprintf(_SC("%s"), buf);
 
	} else {
 
		(*func)(false, buf);
 
	}
 
}
 

	
 
void Squirrel::AddMethod(const char *method_name, SQFUNCTION proc, uint nparam, const char *params, void *userdata, int size)
 
{
 
	sq_pushstring(this->vm, OTTD2FS(method_name), -1);
 

	
 
	if (size != 0) {
 
		void *ptr = sq_newuserdata(vm, size);
 
		memcpy(ptr, userdata, size);
 
	}
 

	
 
	sq_newclosure(this->vm, proc, size != 0 ? 1 : 0);
 
	if (nparam != 0) sq_setparamscheck(this->vm, nparam, OTTD2FS(params));
 
	sq_setnativeclosurename(this->vm, -1, OTTD2FS(method_name));
 
	sq_newslot(this->vm, -3, SQFalse);
 
}
 

	
 
void Squirrel::AddConst(const char *var_name, int value)
 
{
 
	sq_pushstring(this->vm, OTTD2FS(var_name), -1);
 
	sq_pushinteger(this->vm, value);
 
	sq_newslot(this->vm, -3, SQTrue);
 
}
 

	
 
void Squirrel::AddClassBegin(const char *class_name)
 
{
 
	sq_pushroottable(this->vm);
 
	sq_pushstring(this->vm, OTTD2FS(class_name), -1);
 
	sq_newclass(this->vm, SQFalse);
 
}
 

	
 
void Squirrel::AddClassBegin(const char *class_name, const char *parent_class)
 
{
 
	sq_pushroottable(this->vm);
 
	sq_pushstring(this->vm, OTTD2FS(class_name), -1);
 
	sq_pushstring(this->vm, OTTD2FS(parent_class), -1);
 
	if (SQ_FAILED(sq_get(this->vm, -3))) {
 
		DEBUG(misc, 0, "[squirrel] Failed to initialize class '%s' based on parent class '%s'", class_name, parent_class);
 
		DEBUG(misc, 0, "[squirrel] Make sure that '%s' exists before trying to define '%s'", parent_class, class_name);
 
		return;
 
	}
 
	sq_newclass(this->vm, SQTrue);
 
}
 

	
 
void Squirrel::AddClassEnd()
 
{
 
	sq_newslot(vm, -3, SQFalse);
 
	sq_pop(vm, 1);
 
}
 

	
 
bool Squirrel::MethodExists(HSQOBJECT instance, const char *method_name)
 
{
 
	int top = sq_gettop(this->vm);
 
	/* Go to the instance-root */
 
	sq_pushobject(this->vm, instance);
 
	/* Find the function-name inside the script */
 
	sq_pushstring(this->vm, OTTD2FS(method_name), -1);
 
	if (SQ_FAILED(sq_get(this->vm, -2))) {
 
		sq_settop(this->vm, top);
 
		return false;
 
	}
 
	sq_settop(this->vm, top);
 
	return true;
 
}
 

	
 
bool Squirrel::Resume(int suspend)
 
{
 
	sq_resumecatch(this->vm, suspend);
 
	return this->vm->_suspended != 0;
 
}
 

	
 
bool Squirrel::CallMethod(HSQOBJECT instance, const char *method_name, HSQOBJECT *ret, int suspend)
 
{
 
	/* Store the current top */
 
	int top = sq_gettop(this->vm);
 
	/* Go to the instance-root */
 
	sq_pushobject(this->vm, instance);
 
	/* Find the function-name inside the script */
 
	sq_pushstring(this->vm, OTTD2FS(method_name), -1);
 
	if (SQ_FAILED(sq_get(this->vm, -2))) {
 
		DEBUG(misc, 0, "[squirrel] Could not find '%s' in the class", method_name);
 
		sq_settop(this->vm, top);
 
		return false;
 
	}
 
	/* Call the method */
 
	sq_pushobject(this->vm, instance);
 
	sq_call(this->vm, 1, ret == NULL ? SQFalse : SQTrue, SQTrue, suspend);
 
	if (ret != NULL) sq_getstackobj(vm, -1, ret);
 
	/* Reset the top */
 
	sq_settop(this->vm, top);
 

	
 
	return this->vm->_suspended != 0;
 
}
 

	
 
/* static */ bool Squirrel::CreateClassInstanceVM(HSQUIRRELVM vm, const char *class_name, void *real_instance, HSQOBJECT *instance, SQRELEASEHOOK release_hook)
 
{
 
	int oldtop = sq_gettop(vm);
 

	
 
	/* First, find the class */
 
	sq_pushroottable(vm);
 
	sq_pushstring(vm, OTTD2FS(class_name), -1);
 
	if (SQ_FAILED(sq_get(vm, -2))) {
 
		DEBUG(misc, 0, "[squirrel] Failed to find class by the name '%s'", class_name);
 
		sq_settop(vm, oldtop);
 
		return false;
 
	}
 

	
 
	/* Create the instance */
 
	if (SQ_FAILED(sq_createinstance(vm, -1))) {
 
		DEBUG(misc, 0, "[squirrel] Failed to create instance for class '%s'", class_name);
 
		sq_settop(vm, oldtop);
 
		return false;
 
	}
 

	
 
	if (instance != NULL) {
 
		/* Find our instance */
 
		sq_getstackobj(vm, -1, instance);
 
		/* Add a reference to it, so it survives for ever */
 
		sq_addref(vm, instance);
 
	}
 
	sq_remove(vm, -2); // Class-name
 
	sq_remove(vm, -2); // Root-table
 

	
 
	/* Store it in the class */
 
	sq_setinstanceup(vm, -1, real_instance);
 
	if (release_hook != NULL) sq_setreleasehook(vm, -1, release_hook);
 

	
 
	if (instance != NULL) sq_settop(vm, oldtop);
 

	
 
	return true;
 
}
 

	
 
bool Squirrel::CreateClassInstance(const char *class_name, void *real_instance, HSQOBJECT *instance)
 
{
 
	return Squirrel::CreateClassInstanceVM(this->vm, class_name, real_instance, instance, NULL);
 
}
 

	
 
Squirrel::Squirrel()
 
{
 
	this->vm = sq_open(1024);
 
	this->print_func = NULL;
 
	this->global_pointer = NULL;
 

	
 
	/* Handle compile-errors ourself, so we can display it nicely */
 
	sq_setcompilererrorhandler(this->vm, &Squirrel::CompileError);
 
	sq_notifyallexceptions(this->vm, SQTrue);
 
	/* Set a good print-function */
 
	sq_setprintfunc(this->vm, &Squirrel::PrintFunc);
 
	/* Handle runtime-errors ourself, so we can display it nicely */
 
	sq_newclosure(this->vm, &Squirrel::_RunError, 0);
 
	sq_seterrorhandler(this->vm);
 

	
 
	/* Set the foreigh pointer, so we can always find this instance from within the VM */
 
	sq_setforeignptr(this->vm, this);
 

	
 
	sq_pushroottable(this->vm);
 
	squirrel_register_global_std(this);
 
}
 

	
 
class SQFile {
 
private:
 
	FILE *file;
 
	size_t size;
 
	size_t pos;
 

	
 
public:
 
	SQFile(FILE *file, size_t size) : file(file), size(size), pos(0) {}
 

	
 
	size_t Read(void *buf, size_t elemsize, size_t count)
 
	{
 
		assert(elemsize != 0);
 
		if (this->pos + (elemsize * count) > this->size) {
 
			count = (this->size - this->pos) / elemsize;
 
		}
 
		if (count == 0) return 0;
 
		size_t ret = fread(buf, elemsize, count, this->file);
 
		this->pos += ret * elemsize;
 
		return ret;
 
	}
 
};
 

	
 
static SQInteger _io_file_lexfeed_ASCII(SQUserPointer file)
 
{
 
	char c;
 
	if (((SQFile *)file)->Read(&c, sizeof(c), 1) > 0) return c;
 
	return 0;
 
}
 

	
 
static SQInteger _io_file_lexfeed_UTF8(SQUserPointer file)
 
{
 
	static const SQInteger utf8_lengths[16] =
 
	{
 
		1, 1, 1, 1, 1, 1, 1, 1, /* 0000 to 0111 : 1 byte (plain ASCII) */
 
		0, 0, 0, 0,             /* 1000 to 1011 : not valid */
 
		2, 2,                   /* 1100, 1101 : 2 bytes */
 
		3,                      /* 1110 : 3 bytes */
 
		4                       /* 1111 : 4 bytes */
 
	};
 
	static unsigned char byte_masks[5] = {0, 0, 0x1F, 0x0F, 0x07};
 
	unsigned char inchar;
 
	SQInteger c = 0;
 
	if (((SQFile *)file)->Read(&inchar, sizeof(inchar), 1) != 1) return 0;
 
	c = inchar;
 

	
 
	if (c >= 0x80) {
 
		SQInteger tmp;
 
		SQInteger codelen = utf8_lengths[c >> 4];
 
		if (codelen == 0) return 0;
 

	
 
		tmp = c & byte_masks[codelen];
 
		for (SQInteger n = 0; n < codelen - 1; n++) {
 
			tmp <<= 6;
 
			if (((SQFile *)file)->Read(&inchar, sizeof(inchar), 1) != 1) return 0;
 
			tmp |= inchar & 0x3F;
 
		}
 
		c = tmp;
 
	}
 
	return c;
 
}
 

	
 
static SQInteger _io_file_lexfeed_UCS2_LE(SQUserPointer file)
 
{
 
	wchar_t c;
 
	if (((SQFile *)file)->Read(&c, sizeof(c), 1) > 0) return (SQChar)c;
 
	return 0;
 
}
 

	
 
static SQInteger _io_file_lexfeed_UCS2_BE(SQUserPointer file)
 
{
 
	unsigned short c;
 
	if (((SQFile *)file)->Read(&c, sizeof(c), 1) > 0) {
 
		c = ((c >> 8) & 0x00FF)| ((c << 8) & 0xFF00);
 
		return (SQChar)c;
 
	}
 
	return 0;
 
}
 

	
 
static SQInteger _io_file_read(SQUserPointer file, SQUserPointer buf, SQInteger size)
 
{
 
	SQInteger ret = ((SQFile *)file)->Read(buf, 1, size);
 
	if (ret == 0) return -1;
 
	return ret;
 
}
 

	
 
/* static */ SQRESULT Squirrel::LoadFile(HSQUIRRELVM vm, const char *filename, SQBool printerror)
 
{
 
	size_t size;
 
	FILE *file = FioFOpenFile(filename, "rb", AI_DIR, &size);
 
	SQInteger ret;
 
	unsigned short us;
 
	unsigned char uc;
 
	SQLEXREADFUNC func;
 

	
 
	if (file != NULL) {
 
		SQFile f(file, size);
 
		ret = fread(&us, 1, sizeof(us), file);
 
		/* Most likely an empty file */
 
		if (ret != 2) us = 0;
 

	
 
		switch (us) {
 
			case SQ_BYTECODE_STREAM_TAG: { // BYTECODE
 
				fseek(file, -2, SEEK_CUR);
 
				if (SQ_SUCCEEDED(sq_readclosure(vm, _io_file_read, &f))) {
 
					FioFCloseFile(file);
 
					return SQ_OK;
 
				}
 
				FioFCloseFile(file);
 
				return sq_throwerror(vm, _SC("Couldn't read bytecode"));
 
			}
 
			case 0xFFFE: func = _io_file_lexfeed_UCS2_BE; break; // UTF-16 little endian
 
			case 0xFEFF: func = _io_file_lexfeed_UCS2_LE; break; // UTF-16 big endian
 
			case 0xBBEF: // UTF-8
 
				if (fread(&uc, 1, sizeof(uc), file) == 0) {
 
					FioFCloseFile(file);
 
					return sq_throwerror(vm, _SC("I/O error"));
 
				}
 
				if (uc != 0xBF) {
 
					FioFCloseFile(file);
 
					return sq_throwerror(vm, _SC("Unrecognized encoding"));
 
				}
 
				func = _io_file_lexfeed_UTF8;
 
				break;
 
			default: func = _io_file_lexfeed_ASCII; fseek(file, -2, SEEK_CUR); break; // ASCII
 
		}
 

	
 
		if (SQ_SUCCEEDED(sq_compile(vm, func, &f, OTTD2FS(filename), printerror))) {
 
			FioFCloseFile(file);
 
			return SQ_OK;
 
		}
 
		FioFCloseFile(file);
 
		return SQ_ERROR;
 
	}
 
	return sq_throwerror(vm, _SC("cannot open the file"));
 
}
 

	
 
/* static */ bool Squirrel::LoadScript(HSQUIRRELVM vm, const char *script, bool in_root)
 
{
 
	/* Make sure we are always in the root-table */
 
	if (in_root) sq_pushroottable(vm);
 

	
 
	/* Load and run the script */
 
	if (SQ_SUCCEEDED(LoadFile(vm, script, SQTrue))) {
 
		sq_push(vm, -2);
 
		if (SQ_SUCCEEDED(sq_call(vm, 1, SQFalse, SQTrue))) {
 
			sq_pop(vm, 1);
 
			return true;
 
		}
 
	}
 

	
 
	DEBUG(misc, 0, "[squirrel] Failed to compile '%s'", script);
 
	return false;
 
}
 

	
 
bool Squirrel::LoadScript(const char *script)
 
{
 
	return LoadScript(this->vm, script);
 
}
 

	
 
Squirrel::~Squirrel()
 
{
 
	/* Clean up the stuff */
 
	sq_pop(this->vm, 1);
 
	sq_close(this->vm);
 
}
 

	
 
void Squirrel::InsertResult(bool result)
 
{
 
	sq_pushbool(this->vm, result);
 
	vm->GetAt(vm->_stackbase + vm->_suspended_target) = vm->GetUp(-1);
 
	vm->Pop();
 
}
 

	
 
void Squirrel::InsertResult(int result)
 
{
 
	sq_pushinteger(this->vm, result);
 
	vm->GetAt(vm->_stackbase + vm->_suspended_target) = vm->GetUp(-1);
 
	vm->Pop();
 
}
src/script/squirrel.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file squirrel.hpp defines the Squirrel class */
 

	
 
#ifndef SQUIRREL_HPP
 
#define SQUIRREL_HPP
 

	
 
class Squirrel {
 
private:
 
	typedef void (SQPrintFunc)(bool error_msg, const SQChar *message);
 

	
 
	HSQUIRRELVM vm;          ///< The VirtualMachine instnace for squirrel
 
	void *global_pointer;    ///< Can be set by who ever initializes Squirrel
 
	SQPrintFunc *print_func; ///< Points to either NULL, or a custom print handler
 

	
 
	/**
 
	 * The internal RunError handler. It looks up the real error and calls RunError with it.
 
	 */
 
	static SQInteger _RunError(HSQUIRRELVM vm);
 

	
 
	/**
 
	 * Get the squirrel VM. Try to avoid using this.
 
	 */
 
	HSQUIRRELVM GetVM() { return this->vm; }
 

	
 
protected:
 
	/**
 
	 * The CompileError handler.
 
	 */
 
	static void CompileError(HSQUIRRELVM vm, const SQChar *desc, const SQChar *source, SQInteger line, SQInteger column);
 

	
 
	/**
 
	 * The RunError handler.
 
	 */
 
	static void RunError(HSQUIRRELVM vm, const SQChar *error);
 

	
 
	/**
 
	 * If a user runs 'print' inside a script, this function gets the params.
 
	 */
 
	static void PrintFunc(HSQUIRRELVM vm, const SQChar *s, ...);
 

	
 
	/**
 
	 * If an error has to be print, this function is called.
 
	 */
 
	static void ErrorPrintFunc(HSQUIRRELVM vm, const SQChar *s, ...);
 

	
 
public:
 
	friend class AIController;
 
	friend class AIScanner;
 
	friend class AIInstance;
 

	
 
	Squirrel();
 
	~Squirrel();
 

	
 
	/**
 
	 * Load a script.
 
	 * @param script The full script-name to load.
 
	 * @return False if loading failed.
 
	 */
 
	bool LoadScript(const char *script);
 
	static bool LoadScript(HSQUIRRELVM vm, const char *script, bool in_root = true);
 

	
 
	/**
 
	 * Load a file to a given VM.
 
	 */
 
	static SQRESULT LoadFile(HSQUIRRELVM vm, const char *filename, SQBool printerror);
 

	
 
	/**
 
	 * Adds a function to the stack. Depending on the current state this means
 
	 *  either a method or a global function.
 
	 */
 
	void AddMethod(const char *method_name, SQFUNCTION proc, uint nparam = 0, const char *params = NULL, void *userdata = NULL, int size = 0);
 

	
 
	/**
 
	 * Adds a const to the stack. Depending on the current state this means
 
	 *  either a const to a class or to the global space.
 
	 */
 
	void AddConst(const char *var_name, int value);
 

	
 
	/**
 
	 * Adds a class to the global scope. Make sure to call AddClassEnd when you
 
	 *  are done adding methods.
 
	 */
 
	void AddClassBegin(const char *class_name);
 

	
 
	/**
 
	 * Adds a class to the global scope, extending 'parent_class'.
 
	 * Make sure to call AddClassEnd when you are done adding methods.
 
	 */
 
	void AddClassBegin(const char *class_name, const char *parent_class);
 

	
 
	/**
 
	 * Finishes adding a class to the global scope. If this isn't called, no
 
	 *  class is really created.
 
	 */
 
	void AddClassEnd();
 

	
 
	/**
 
	 * Resume a VM when it was suspended via a throw.
 
	 */
 
	bool Resume(int suspend = -1);
 

	
 
	void InsertResult(bool result);
 
	void InsertResult(int result);
 

	
 
	/**
 
	 * Call a method of an instance, in various flavors.
 
	 */
 
	bool CallMethod(HSQOBJECT instance, const char *method_name, HSQOBJECT *ret, int suspend = -1);
 
	bool CallMethod(HSQOBJECT instance, const char *method_name, int suspend = -1) { return this->CallMethod(instance, method_name, NULL, suspend); }
 
	const char *CallStringMethodStrdup(HSQOBJECT instance, const char *method_name, int suspend = -1) { HSQOBJECT ret; this->CallMethod(instance, method_name, &ret, suspend); return strdup(ObjectToString(&ret)); }
 
	int CallIntegerMethod(HSQOBJECT instance, const char *method_name, int suspend = -1) { HSQOBJECT ret; this->CallMethod(instance, method_name, &ret, suspend); return ObjectToInteger(&ret); }
 

	
 
	/**
 
	 * Check if a method exists in an instance.
 
	 */
 
	bool MethodExists(HSQOBJECT instance, const char *method_name);
 

	
 
	/**
 
	 * Creates a class instance.
 
	 * @param class_name The name of the class of which we create an instance.
 
	 * @param real_instance The instance to the real class, if it represents a real class.
 
	 * @param instance Returning value with the pointer to the instance.
 
	 * @param release_hook Optional param to give a release hook.
 
	 * @return False if creating failed.
 
	 */
 
	static bool CreateClassInstanceVM(HSQUIRRELVM vm, const char *class_name, void *real_instance, HSQOBJECT *instance, SQRELEASEHOOK release_hook);
 

	
 
	/**
 
	 * Exactly the same as CreateClassInstanceVM, only callable without instance of Squirrel.
 
	 */
 
	bool CreateClassInstance(const char *class_name, void *real_instance, HSQOBJECT *instance);
 

	
 
	/**
 
	 * Get the real-instance pointer.
 
	 * @note This will only work just after a function-call from within Squirrel
 
	 *  to your C++ function.
 
	 */
 
	static bool GetRealInstance(HSQUIRRELVM vm, SQUserPointer *ptr) { return SQ_SUCCEEDED(sq_getinstanceup(vm, 1, ptr, 0)); }
 

	
 
	/**
 
	 * Get the Squirrel-instance pointer.
 
	 * @note This will only work just after a function-call from within Squirrel
 
	 *  to your C++ function.
 
	 */
 
	static bool GetInstance(HSQUIRRELVM vm, HSQOBJECT *ptr, int pos = 1) { sq_getclass(vm, pos); sq_getstackobj(vm, pos, ptr); sq_pop(vm, 1); return true; }
 

	
 
	/**
 
	 * Convert a Squirrel-object to a string.
 
	 */
 
	static const char *ObjectToString(HSQOBJECT *ptr) { return FS2OTTD(sq_objtostring(ptr)); }
 

	
 
	/**
 
	 * Convert a Squirrel-object to an integer.
 
	 */
 
	static int ObjectToInteger(HSQOBJECT *ptr) { return sq_objtointeger(ptr); }
 

	
 
	/**
 
	 * Sets a pointer in the VM that is reachable from where ever you are in SQ.
 
	 *  Useful to keep track of the main instance.
 
	 */
 
	void SetGlobalPointer(void *ptr) { this->global_pointer = ptr; }
 

	
 
	/**
 
	 * Get the pointer as set by SetGlobalPointer.
 
	 */
 
	static void *GetGlobalPointer(HSQUIRRELVM vm) { return ((Squirrel *)sq_getforeignptr(vm))->global_pointer; }
 

	
 
	/**
 
	 * Set a custom print function, so you can handle outputs from SQ yourself.
 
	 */
 
	void SetPrintFunction(SQPrintFunc *func) { this->print_func = func; }
 

	
 
	/**
 
	 * Throw a Squirrel error that will be nicely displayed to the user.
 
	 */
 
	void ThrowError(const char *error) { sq_throwerror(this->vm, OTTD2FS(error)); }
 

	
 
	/**
 
	 * Release a SQ object.
 
	 */
 
	void ReleaseObject(HSQOBJECT *ptr) { sq_release(this->vm, ptr); }
 
};
 

	
 
#endif /* SQUIRREL_HPP */
src/script/squirrel_class.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file squirrel_class.cpp defines templates for converting C++ classes to Squirrel classes */
 

	
 
#ifndef SQUIRREL_CLASS_HPP
 
#define SQUIRREL_CLASS_HPP
 

	
 
#if (__GNUC__ == 2)
 
/* GCC 2.95 doesn't like to have SQConvert::DefSQStaticCallback inside a
 
 *  template (it gives an internal error 373). Above that, it doesn't listen
 
 *  to 'using namespace' inside a function of a template. So for GCC 2.95 we
 
 *  do it in the global space to avoid compiler errors. */
 
using namespace SQConvert;
 
#endif /* __GNUC__ == 2 */
 

	
 
/**
 
 * The template to define classes in Squirrel. It takes care of the creation
 
 *  and calling of such classes, to make the AI Layer cleaner while having a
 
 *  powerful script as possible AI language.
 
 */
 
template <class CL>
 
class DefSQClass {
 
private:
 
	const char *classname;
 

	
 
public:
 
	DefSQClass(const char *_classname) :
 
		classname(_classname)
 
	{}
 

	
 
	/**
 
	 * This defines a method inside a class for Squirrel.
 
	 */
 
	template <typename Func>
 
	void DefSQMethod(Squirrel *engine, Func function_proc, const char *function_name)
 
	{
 
		using namespace SQConvert;
 
		engine->AddMethod(function_name, DefSQNonStaticCallback<CL, Func>, 0, NULL, &function_proc, sizeof(function_proc));
 
	}
 

	
 
	/**
 
	 * This defines a method inside a class for Squirrel, which has access to the 'engine' (experts only!).
 
	 */
 
	template <typename Func>
 
	void DefSQAdvancedMethod(Squirrel *engine, Func function_proc, const char *function_name)
 
	{
 
		using namespace SQConvert;
 
		engine->AddMethod(function_name, DefSQAdvancedNonStaticCallback<CL, Func>, 0, NULL, &function_proc, sizeof(function_proc));
 
	}
 

	
 
	/**
 
	 * This defines a method inside a class for Squirrel with defined params.
 
	 * @note If you define nparam, make sure that he first param is always 'x',
 
	 *  which is the 'this' inside the function. This is hidden from the rest
 
	 *  of the code, but without it calling your function will fail!
 
	 */
 
	template <typename Func>
 
	void DefSQMethod(Squirrel *engine, Func function_proc, const char *function_name, int nparam, const char *params)
 
	{
 
		using namespace SQConvert;
 
		engine->AddMethod(function_name, DefSQNonStaticCallback<CL, Func>, nparam, params, &function_proc, sizeof(function_proc));
 
	}
 

	
 
	/**
 
	 * This defines a static method inside a class for Squirrel.
 
	 */
 
	template <typename Func>
 
	void DefSQStaticMethod(Squirrel *engine, Func function_proc, const char *function_name)
 
	{
 
		using namespace SQConvert;
 
		engine->AddMethod(function_name, DefSQStaticCallback<CL, Func>, 0, NULL, &function_proc, sizeof(function_proc));
 
	}
 

	
 
	/**
 
	 * This defines a static method inside a class for Squirrel with defined params.
 
	 * @note If you define nparam, make sure that he first param is always 'x',
 
	 *  which is the 'this' inside the function. This is hidden from the rest
 
	 *  of the code, but without it calling your function will fail!
 
	 */
 
	template <typename Func>
 
	void DefSQStaticMethod(Squirrel *engine, Func function_proc, const char *function_name, int nparam, const char *params)
 
	{
 
		using namespace SQConvert;
 
		engine->AddMethod(function_name, DefSQStaticCallback<CL, Func>, nparam, params, &function_proc, sizeof(function_proc));
 
	}
 

	
 
	template <typename Var>
 
	void DefSQConst(Squirrel *engine, Var value, const char *var_name)
 
	{
 
		engine->AddConst(var_name, value);
 
	}
 

	
 
	void PreRegister(Squirrel *engine)
 
	{
 
		engine->AddClassBegin(this->classname);
 
	}
 

	
 
	void PreRegister(Squirrel *engine, const char *parent_class)
 
	{
 
		engine->AddClassBegin(this->classname, parent_class);
 
	}
 

	
 
	template <typename Func, int Tnparam>
 
	void AddConstructor(Squirrel *engine, const char *params)
 
	{
 
		using namespace SQConvert;
 
		engine->AddMethod("constructor", DefSQConstructorCallback<CL, Func, Tnparam>, Tnparam, params);
 
	}
 

	
 
	void PostRegister(Squirrel *engine)
 
	{
 
		engine->AddClassEnd();
 
	}
 
};
 

	
 
#endif /* SQUIRREL_CLASS_HPP */
src/script/squirrel_helper.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file squirrel_helper.hpp declarations and parts of the implementation of the class for convert code */
 

	
 
#ifndef SQUIRREL_HELPER_HPP
 
#define SQUIRREL_HELPER_HPP
 

	
 
#include <squirrel.h>
 
#include "../core/math_func.hpp"
 
#include "../core/smallvec_type.hpp"
 
#include "../economy_type.h"
 
#include "squirrel_helper_type.hpp"
 

	
 
/**
 
 * The Squirrel convert routines
 
 */
 
namespace SQConvert {
 
	/**
 
	 * Pointers assigned to this class will be free'd when this instance
 
	 *  comes out of scope. Useful to make sure you can use strdup(),
 
	 *  without leaking memory.
 
	 */
 
	struct SQAutoFreePointers : SmallVector<void *, 1> {
 
		~SQAutoFreePointers()
 
		{
 
			for (uint i = 0; i < this->items; i++) free(this->data[i]);
 
		}
 
	};
 

	
 
	template <bool Y> struct YesT {
 
		static const bool Yes = Y;
 
		static const bool No = !Y;
 
	};
 

	
 
	/**
 
	 * Helper class to recognize if the given type is void. Usage: 'IsVoidT<T>::Yes'
 
	 */
 
	template <typename T> struct IsVoidT : YesT<false> {};
 
	template <> struct IsVoidT<void> : YesT<true> {};
 

	
 
	/**
 
	 * Helper class to recognize if the function/method return type is void.
 
	 */
 
	template <typename Tfunc> struct HasVoidReturnT;
 
	/* functions */
 
	template <typename Tretval> struct HasVoidReturnT<Tretval (*)()> : IsVoidT<Tretval> {};
 
	template <typename Tretval, typename Targ1> struct HasVoidReturnT<Tretval (*)(Targ1)> : IsVoidT<Tretval> {};
 
	template <typename Tretval, typename Targ1, typename Targ2> struct HasVoidReturnT<Tretval (*)(Targ1, Targ2)> : IsVoidT<Tretval> {};
 
	template <typename Tretval, typename Targ1, typename Targ2, typename Targ3> struct HasVoidReturnT<Tretval (*)(Targ1, Targ2, Targ3)> : IsVoidT<Tretval> {};
 
	template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4> struct HasVoidReturnT<Tretval (*)(Targ1, Targ2, Targ3, Targ4)> : IsVoidT<Tretval> {};
 
	template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5> struct HasVoidReturnT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5)> : IsVoidT<Tretval> {};
 
	template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5, typename Targ6, typename Targ7, typename Targ8, typename Targ9, typename Targ10> struct HasVoidReturnT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10)> : IsVoidT<Tretval> {};
 
	/* methods */
 
	template <class Tcls, typename Tretval> struct HasVoidReturnT<Tretval (Tcls::*)()> : IsVoidT<Tretval> {};
 
	template <class Tcls, typename Tretval, typename Targ1> struct HasVoidReturnT<Tretval (Tcls::*)(Targ1)> : IsVoidT<Tretval> {};
 
	template <class Tcls, typename Tretval, typename Targ1, typename Targ2> struct HasVoidReturnT<Tretval (Tcls::*)(Targ1, Targ2)> : IsVoidT<Tretval> {};
 
	template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3> struct HasVoidReturnT<Tretval (Tcls::*)(Targ1, Targ2, Targ3)> : IsVoidT<Tretval> {};
 
	template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4> struct HasVoidReturnT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4)> : IsVoidT<Tretval> {};
 
	template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5> struct HasVoidReturnT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5)> : IsVoidT<Tretval> {};
 
	template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5, typename Targ6, typename Targ7, typename Targ8, typename Targ9, typename Targ10> struct HasVoidReturnT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10)> : IsVoidT<Tretval> {};
 

	
 

	
 
	/**
 
	 * Special class to make it possible for the compiler to pick the correct GetParam().
 
	 */
 
	template <typename T> class ForceType { };
 

	
 
	/**
 
	 * To return a value to squirrel, we call this function. It converts to the right format.
 
	 */
 
	template <typename T> static int Return(HSQUIRRELVM vm, T t);
 

	
 
	template <> inline int Return<uint8>       (HSQUIRRELVM vm, uint8 res)       { sq_pushinteger(vm, (int32)res); return 1; }
 
	template <> inline int Return<uint16>      (HSQUIRRELVM vm, uint16 res)      { sq_pushinteger(vm, (int32)res); return 1; }
 
	template <> inline int Return<uint32>      (HSQUIRRELVM vm, uint32 res)      { sq_pushinteger(vm, (int32)res); return 1; }
 
	template <> inline int Return<int8>        (HSQUIRRELVM vm, int8 res)        { sq_pushinteger(vm, res); return 1; }
 
	template <> inline int Return<int16>       (HSQUIRRELVM vm, int16 res)       { sq_pushinteger(vm, res); return 1; }
 
	template <> inline int Return<int32>       (HSQUIRRELVM vm, int32 res)       { sq_pushinteger(vm, res); return 1; }
 
	template <> inline int Return<int64>       (HSQUIRRELVM vm, int64 res)       { sq_pushinteger(vm, ClampToI32(res)); return 1; }
 
	template <> inline int Return<Money>       (HSQUIRRELVM vm, Money res)       { sq_pushinteger(vm, ClampToI32(res)); return 1; }
 
	template <> inline int Return<bool>        (HSQUIRRELVM vm, bool res)        { sq_pushbool   (vm, res); return 1; }
 
	template <> inline int Return<char *>      (HSQUIRRELVM vm, char *res)       { if (res == NULL) sq_pushnull(vm); else sq_pushstring (vm, OTTD2FS(res), strlen(res)); free(res); return 1; }
 
	template <> inline int Return<const char *>(HSQUIRRELVM vm, const char *res) { if (res == NULL) sq_pushnull(vm); else sq_pushstring (vm, OTTD2FS(res), strlen(res)); return 1; }
 
	template <> inline int Return<void *>      (HSQUIRRELVM vm, void *res)       { sq_pushuserpointer(vm, res); return 1; }
 

	
 
	/**
 
	 * To get a param from squirrel, we call this function. It converts to the right format.
 
	 */
 
	template <typename T> static T GetParam(ForceType<T>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr);
 

	
 
	template <> inline uint8       GetParam(ForceType<uint8>       , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger     tmp; sq_getinteger    (vm, index, &tmp); return tmp; }
 
	template <> inline uint16      GetParam(ForceType<uint16>      , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger     tmp; sq_getinteger    (vm, index, &tmp); return tmp; }
 
	template <> inline uint32      GetParam(ForceType<uint32>      , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger     tmp; sq_getinteger    (vm, index, &tmp); return tmp; }
 
	template <> inline int8        GetParam(ForceType<int8>        , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger     tmp; sq_getinteger    (vm, index, &tmp); return tmp; }
 
	template <> inline int16       GetParam(ForceType<int16>       , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger     tmp; sq_getinteger    (vm, index, &tmp); return tmp; }
 
	template <> inline int32       GetParam(ForceType<int32>       , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger     tmp; sq_getinteger    (vm, index, &tmp); return tmp; }
 
	template <> inline bool        GetParam(ForceType<bool>        , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQBool        tmp; sq_getbool       (vm, index, &tmp); return tmp != 0; }
 
	template <> inline const char *GetParam(ForceType<const char *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { const SQChar *tmp; sq_getstring     (vm, index, &tmp); char *tmp_str = strdup(FS2OTTD(tmp)); *ptr->Append() = (void *)tmp_str; return tmp_str; }
 
	template <> inline void       *GetParam(ForceType<void *>      , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer tmp; sq_getuserpointer(vm, index, &tmp); return tmp; }
 

	
 
	template <> inline Array      *GetParam(ForceType<Array *>,      HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr)
 
	{
 
		SQObject obj;
 
		sq_getstackobj(vm, index, &obj);
 
		sq_pushobject(vm, obj);
 
		sq_pushnull(vm);
 

	
 
		SmallVector<int32, 2> data;
 

	
 
		while (SQ_SUCCEEDED(sq_next(vm, -2))) {
 
			SQInteger tmp;
 
			if (SQ_SUCCEEDED(sq_getinteger(vm, -1, &tmp))) {
 
				*data.Append() = (int32)tmp;
 
			} else {
 
				sq_pop(vm, 4);
 
				throw sq_throwerror(vm, _SC("a member of an array used as parameter to a function is not numeric"));
 
			}
 

	
 
			sq_pop(vm, 2);
 
		}
 
		sq_pop(vm, 2);
 

	
 
		Array *arr = (Array*)MallocT<byte>(sizeof(Array) + sizeof(int32) * data.Length());
 
		arr->size = data.Length();
 
		memcpy(arr->array, data.Begin(), sizeof(int32) * data.Length());
 

	
 
		*ptr->Append() = arr;
 
		return arr;
 
	}
 

	
 
	/**
 
	* Helper class to recognize the function type (retval type, args) and use the proper specialization
 
	* for SQ callback. The partial specializations for the second arg (Tis_void_retval) are not possible
 
	* on the function. Therefore the class is used instead.
 
	*/
 
	template <typename Tfunc, bool Tis_void_retval = HasVoidReturnT<Tfunc>::Yes> struct HelperT;
 

	
 
	/**
 
	 * The real C++ caller for function with return value and 0 params.
 
	 */
 
	template <typename Tretval>
 
	struct HelperT<Tretval (*)(), false> {
 
		static int SQCall(void *instance, Tretval (*func)(), HSQUIRRELVM vm)
 
		{
 
			return Return(vm, (*func)());
 
		}
 
	};
 

	
 
	/**
 
	 * The real C++ caller for function with no return value and 0 params.
 
	 */
 
	template <typename Tretval>
 
	struct HelperT<Tretval (*)(), true> {
 
		static int SQCall(void *instance, Tretval (*func)(), HSQUIRRELVM vm)
 
		{
 
			(*func)();
 
			return 0;
 
		}
 
	};
 

	
 
	/**
 
	 * The real C++ caller for method with return value and 0 params.
 
	 */
 
	template <class Tcls, typename Tretval>
 
	struct HelperT<Tretval (Tcls::*)(), false> {
 
		static int SQCall(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
 
		{
 
			return Return(vm, (instance->*func)());
 
		}
 
	};
 

	
 
	/**
 
	 * The real C++ caller for method with no return value and 0 params.
 
	 */
 
	template <class Tcls, typename Tretval>
 
	struct HelperT<Tretval (Tcls::*)(), true> {
 
		static int SQCall(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
 
		{
 
			(instance->*func)();
 
			return 0;
 
		}
 

	
 
		static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
 
		{
 
			return new Tcls();
 
		}
 
	};
 

	
 
	/**
 
	 * The real C++ caller for function with return value and 1 param.
 
	 */
 
	template <typename Tretval, typename Targ1>
 
	struct HelperT<Tretval (*)(Targ1), false> {
 
		static int SQCall(void *instance, Tretval (*func)(Targ1), HSQUIRRELVM vm)
 
		{
 
			SQAutoFreePointers ptr;
 
			Tretval ret = (*func)(
 
				GetParam(ForceType<Targ1>(), vm, 2, &ptr)
 
			);
 
			sq_pop(vm, 1);
 
			return Return(vm, ret);
 
		}
 
	};
 

	
 
	/**
 
	 * The real C++ caller for function with no return value and 1 param.
 
	 */
 
	template <typename Tretval, typename Targ1>
 
	struct HelperT<Tretval (*)(Targ1), true> {
 
		static int SQCall(void *instance, Tretval (*func)(Targ1), HSQUIRRELVM vm)
 
		{
 
			SQAutoFreePointers ptr;
 
			(*func)(
 
				GetParam(ForceType<Targ1>(), vm, 2, &ptr)
 
			);
 
			sq_pop(vm, 1);
 
			return 0;
 
		}
 
	};
 

	
 
	/**
 
	 * The real C++ caller for method with return value and 1 param.
 
	 */
 
	template <class Tcls, typename Tretval, typename Targ1>
 
	struct HelperT<Tretval (Tcls::*)(Targ1), false> {
 
		static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1), HSQUIRRELVM vm)
 
		{
 
			SQAutoFreePointers ptr;
 
			Tretval ret = (instance->*func)(
 
				GetParam(ForceType<Targ1>(), vm, 2, &ptr)
 
			);
 
			sq_pop(vm, 1);
 
			return Return(vm, ret);
 
		}
 
	};
 

	
 
	/**
 
	 * The real C++ caller for method with no return value and 1 param.
 
	 */
 
	template <class Tcls, typename Tretval, typename Targ1>
 
	struct HelperT<Tretval (Tcls::*)(Targ1), true> {
 
		static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1), HSQUIRRELVM vm)
 
		{
 
			SQAutoFreePointers ptr;
 
			(instance->*func)(
 
				GetParam(ForceType<Targ1>(), vm, 2, &ptr)
 
			);
 
			sq_pop(vm, 1);
 
			return 0;
 
		}
 

	
 
		static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1), HSQUIRRELVM vm)
 
		{
 
			SQAutoFreePointers ptr;
 
			Tcls *inst = new Tcls(
 
				GetParam(ForceType<Targ1>(), vm, 2, &ptr)
 
			);
 

	
 
			return inst;
 
		}
 
	};
 

	
 
	/**
 
	 * The real C++ caller for function with return value and 2 params.
 
	 */
 
	template <typename Tretval, typename Targ1, typename Targ2>
 
	struct HelperT<Tretval (*)(Targ1, Targ2), false> {
 
		static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2), HSQUIRRELVM vm)
 
		{
 
			SQAutoFreePointers ptr;
 
			Tretval ret = (*func)(
 
				GetParam(ForceType<Targ1>(), vm, 2, &ptr),
 
				GetParam(ForceType<Targ2>(), vm, 3, &ptr)
 
			);
 
			sq_pop(vm, 2);
 
			return Return(vm, ret);
 
		}
 
	};
 

	
 
	/**
 
	 * The real C++ caller for function with no return value and 2 params.
 
	 */
 
	template <typename Tretval, typename Targ1, typename Targ2>
 
	struct HelperT<Tretval (*)(Targ1, Targ2), true> {
 
		static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2), HSQUIRRELVM vm)
 
		{
 
			SQAutoFreePointers ptr;
 
			(*func)(
 
				GetParam(ForceType<Targ1>(), vm, 2, &ptr),
 
				GetParam(ForceType<Targ2>(), vm, 3, &ptr)
 
			);
 
			sq_pop(vm, 2);
 
			return 0;
 
		}
 
	};
 

	
 
	/**
 
	 * The real C++ caller for method with return value and 2 params.
 
	 */
 
	template <class Tcls, typename Tretval, typename Targ1, typename Targ2>
 
	struct HelperT<Tretval (Tcls::*)(Targ1, Targ2), false> {
 
		static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2), HSQUIRRELVM vm)
 
		{
 
			SQAutoFreePointers ptr;
 
			Tretval ret = (instance->*func)(
 
				GetParam(ForceType<Targ1>(), vm, 2, &ptr),
 
				GetParam(ForceType<Targ2>(), vm, 3, &ptr)
 
			);
 
			sq_pop(vm, 2);
 
			return Return(vm, ret);
 
		}
 
	};
 

	
 
	/**
 
	 * The real C++ caller for method with no return value and 2 params.
 
	 */
 
	template <class Tcls, typename Tretval, typename Targ1, typename Targ2>
 
	struct HelperT<Tretval (Tcls::*)(Targ1, Targ2), true> {
 
		static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2), HSQUIRRELVM vm)
 
		{
 
			SQAutoFreePointers ptr;
 
			(instance->*func)(
 
				GetParam(ForceType<Targ1>(), vm, 2, &ptr),
 
				GetParam(ForceType<Targ2>(), vm, 3, &ptr)
 
			);
 
			sq_pop(vm, 2);
 
			return 0;
 
		}
 

	
 
		static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2), HSQUIRRELVM vm)
 
		{
 
			SQAutoFreePointers ptr;
 
			Tcls *inst = new Tcls(
 
				GetParam(ForceType<Targ1>(), vm, 2, &ptr),
 
				GetParam(ForceType<Targ2>(), vm, 3, &ptr)
 
			);
 

	
 
			return inst;
 
		}
 
	};
 

	
 
	/**
 
	 * The real C++ caller for function with return value and 3 params.
 
	 */
 
	template <typename Tretval, typename Targ1, typename Targ2, typename Targ3>
 
	struct HelperT<Tretval (*)(Targ1, Targ2, Targ3), false> {
 
		static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
 
		{
 
			SQAutoFreePointers ptr;
 
			Tretval ret = (*func)(
 
				GetParam(ForceType<Targ1>(), vm, 2, &ptr),
 
				GetParam(ForceType<Targ2>(), vm, 3, &ptr),
 
				GetParam(ForceType<Targ3>(), vm, 4, &ptr)
 
			);
 
			sq_pop(vm, 3);
 
			return Return(vm, ret);
 
		}
 
	};
 

	
 
	/**
 
	 * The real C++ caller for function with no return value and 3 params.
 
	 */
 
	template <typename Tretval, typename Targ1, typename Targ2, typename Targ3>
 
	struct HelperT<Tretval (*)(Targ1, Targ2, Targ3), true> {
 
		static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
 
		{
 
			SQAutoFreePointers ptr;
 
			(*func)(
 
				GetParam(ForceType<Targ1>(), vm, 2, &ptr),
 
				GetParam(ForceType<Targ2>(), vm, 3, &ptr),
 
				GetParam(ForceType<Targ3>(), vm, 4, &ptr)
 
			);
 
			sq_pop(vm, 3);
 
			return 0;
 
		}
 
	};
 

	
 
	/**
 
	 * The real C++ caller for method with return value and 3 params.
 
	 */
 
	template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3>
 
	struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3), false> {
 
		static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
 
		{
 
			SQAutoFreePointers ptr;
 
			Tretval ret = (instance->*func)(
 
				GetParam(ForceType<Targ1>(), vm, 2, &ptr),
 
				GetParam(ForceType<Targ2>(), vm, 3, &ptr),
 
				GetParam(ForceType<Targ3>(), vm, 4, &ptr)
 
			);
 
			sq_pop(vm, 3);
 
			return Return(vm, ret);
 
		}
 
	};
 

	
 
	/**
 
	 * The real C++ caller for method with no return value and 3 params.
 
	 */
 
	template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3>
 
	struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3), true> {
 
		static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
 
		{
 
			SQAutoFreePointers ptr;
 
			(instance->*func)(
 
				GetParam(ForceType<Targ1>(), vm, 2, &ptr),
 
				GetParam(ForceType<Targ2>(), vm, 3, &ptr),
 
				GetParam(ForceType<Targ3>(), vm, 4, &ptr)
 
			);
 
			sq_pop(vm, 3);
 
			return 0;
 
		}
 

	
 
		static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
 
		{
 
			SQAutoFreePointers ptr;
 
			Tcls *inst = new Tcls(
 
				GetParam(ForceType<Targ1>(), vm, 2, &ptr),
 
				GetParam(ForceType<Targ2>(), vm, 3, &ptr),
 
				GetParam(ForceType<Targ3>(), vm, 4, &ptr)
 
			);
 

	
 
			return inst;
 
		}
 
	};
 

	
 
	/**
 
	 * The real C++ caller for function with return value and 4 params.
 
	 */
 
	template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4>
 
	struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4), false> {
 
		static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
 
		{
 
			SQAutoFreePointers ptr;
 
			Tretval ret = (*func)(
 
				GetParam(ForceType<Targ1>(), vm, 2, &ptr),
 
				GetParam(ForceType<Targ2>(), vm, 3, &ptr),
 
				GetParam(ForceType<Targ3>(), vm, 4, &ptr),
 
				GetParam(ForceType<Targ4>(), vm, 5, &ptr)
 
			);
 
			sq_pop(vm, 4);
 
			return Return(vm, ret);
 
		}
 
	};
 

	
 
	/**
 
	 * The real C++ caller for function with no return value and 4 params.
 
	 */
 
	template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4>
 
	struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4), true> {
 
		static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
 
		{
 
			SQAutoFreePointers ptr;
 
			(*func)(
 
				GetParam(ForceType<Targ1>(), vm, 2, &ptr),
 
				GetParam(ForceType<Targ2>(), vm, 3, &ptr),
 
				GetParam(ForceType<Targ3>(), vm, 4, &ptr),
 
				GetParam(ForceType<Targ4>(), vm, 5, &ptr)
 
			);
 
			sq_pop(vm, 4);
 
			return 0;
 
		}
 
	};
 

	
 
	/**
 
	 * The real C++ caller for method with return value and 4 params.
 
	 */
 
	template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4>
 
	struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4), false> {
 
		static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
 
		{
 
			SQAutoFreePointers ptr;
 
			Tretval ret = (instance->*func)(
 
				GetParam(ForceType<Targ1>(), vm, 2, &ptr),
 
				GetParam(ForceType<Targ2>(), vm, 3, &ptr),
 
				GetParam(ForceType<Targ3>(), vm, 4, &ptr),
 
				GetParam(ForceType<Targ4>(), vm, 5, &ptr)
 
			);
 
			sq_pop(vm, 4);
 
			return Return(vm, ret);
 
		}
 
	};
 

	
 
	/**
 
	 * The real C++ caller for method with no return value and 4 params.
 
	 */
 
	template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4>
 
	struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4), true> {
 
		static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
 
		{
 
			SQAutoFreePointers ptr;
 
			(instance->*func)(
 
				GetParam(ForceType<Targ1>(), vm, 2, &ptr),
 
				GetParam(ForceType<Targ2>(), vm, 3, &ptr),
 
				GetParam(ForceType<Targ3>(), vm, 4, &ptr),
 
				GetParam(ForceType<Targ4>(), vm, 5, &ptr)
 
			);
 
			sq_pop(vm, 4);
 
			return 0;
 
		}
 

	
 
		static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
 
		{
 
			SQAutoFreePointers ptr;
 
			Tcls *inst = new Tcls(
 
				GetParam(ForceType<Targ1>(), vm, 2, &ptr),
 
				GetParam(ForceType<Targ2>(), vm, 3, &ptr),
 
				GetParam(ForceType<Targ3>(), vm, 4, &ptr),
 
				GetParam(ForceType<Targ4>(), vm, 5, &ptr)
 
			);
 

	
 
			return inst;
 
		}
 
	};
 

	
 
	/**
 
	 * The real C++ caller for function with return value and 5 params.
 
	 */
 
	template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5>
 
	struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5), false> {
 
		static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
 
		{
 
			SQAutoFreePointers ptr;
 
			Tretval ret = (*func)(
 
				GetParam(ForceType<Targ1>(), vm, 2, &ptr),
 
				GetParam(ForceType<Targ2>(), vm, 3, &ptr),
 
				GetParam(ForceType<Targ3>(), vm, 4, &ptr),
 
				GetParam(ForceType<Targ4>(), vm, 5, &ptr),
 
				GetParam(ForceType<Targ5>(), vm, 6, &ptr)
 
			);
 
			sq_pop(vm, 5);
 
			return Return(vm, ret);
 
		}
 
	};
 

	
 
	/**
 
	 * The real C++ caller for function with no return value and 5 params.
 
	 */
 
	template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5>
 
	struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5), true> {
 
		static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
 
		{
 
			SQAutoFreePointers ptr;
 
			(*func)(
 
				GetParam(ForceType<Targ1>(), vm, 2, &ptr),
 
				GetParam(ForceType<Targ2>(), vm, 3, &ptr),
 
				GetParam(ForceType<Targ3>(), vm, 4, &ptr),
 
				GetParam(ForceType<Targ4>(), vm, 5, &ptr),
 
				GetParam(ForceType<Targ5>(), vm, 6, &ptr)
 
			);
 
			sq_pop(vm, 5);
 
			return 0;
 
		}
 
	};
 

	
 
	/**
 
	 * The real C++ caller for method with return value and 5 params.
 
	 */
 
	template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5>
 
	struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5), false> {
 
		static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
 
		{
 
			SQAutoFreePointers ptr;
 
			Tretval ret = (instance->*func)(
 
				GetParam(ForceType<Targ1>(), vm, 2, &ptr),
 
				GetParam(ForceType<Targ2>(), vm, 3, &ptr),
 
				GetParam(ForceType<Targ3>(), vm, 4, &ptr),
 
				GetParam(ForceType<Targ4>(), vm, 5, &ptr),
 
				GetParam(ForceType<Targ5>(), vm, 6, &ptr)
 
			);
 
			sq_pop(vm, 5);
 
			return Return(vm, ret);
 
		}
 
	};
 

	
 
	/**
 
	 * The real C++ caller for method with no return value and 5 params.
 
	 */
 
	template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5>
 
	struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5), true> {
 
		static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
 
		{
 
			SQAutoFreePointers ptr;
 
			(instance->*func)(
 
				GetParam(ForceType<Targ1>(), vm, 2, &ptr),
 
				GetParam(ForceType<Targ2>(), vm, 3, &ptr),
 
				GetParam(ForceType<Targ3>(), vm, 4, &ptr),
 
				GetParam(ForceType<Targ4>(), vm, 5, &ptr),
 
				GetParam(ForceType<Targ5>(), vm, 6, &ptr)
 
			);
 
			sq_pop(vm, 5);
 
			return 0;
 
		}
 

	
 
		static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
 
		{
 
			SQAutoFreePointers ptr;
 
			Tcls *inst = new Tcls(
 
				GetParam(ForceType<Targ1>(), vm, 2, &ptr),
 
				GetParam(ForceType<Targ2>(), vm, 3, &ptr),
 
				GetParam(ForceType<Targ3>(), vm, 4, &ptr),
 
				GetParam(ForceType<Targ4>(), vm, 5, &ptr),
 
				GetParam(ForceType<Targ5>(), vm, 6, &ptr)
 
			);
 

	
 
			return inst;
 
		}
 
	};
 

	
 
	/**
 
	 * The real C++ caller for function with return value and 10 params.
 
	 */
 
	template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5, typename Targ6, typename Targ7, typename Targ8, typename Targ9, typename Targ10>
 
	struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), false> {
 
		static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
 
		{
 
			SQAutoFreePointers ptr;
 
			Tretval ret = (*func)(
 
				GetParam(ForceType<Targ1>(), vm, 2, &ptr),
 
				GetParam(ForceType<Targ2>(), vm, 3, &ptr),
 
				GetParam(ForceType<Targ3>(), vm, 4, &ptr),
 
				GetParam(ForceType<Targ4>(), vm, 5, &ptr),
 
				GetParam(ForceType<Targ5>(), vm, 6, &ptr),
 
				GetParam(ForceType<Targ6>(), vm, 7, &ptr),
 
				GetParam(ForceType<Targ7>(), vm, 8, &ptr),
 
				GetParam(ForceType<Targ8>(), vm, 9, &ptr),
 
				GetParam(ForceType<Targ9>(), vm, 10, &ptr),
 
				GetParam(ForceType<Targ10>(), vm, 11, &ptr)
 
			);
 
			sq_pop(vm, 10);
 
			return Return(vm, ret);
 
		}
 
	};
 

	
 
	/**
 
	 * The real C++ caller for function with no return value and 10 params.
 
	 */
 
	template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5, typename Targ6, typename Targ7, typename Targ8, typename Targ9, typename Targ10>
 
	struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), true> {
 
		static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
 
		{
 
			SQAutoFreePointers ptr;
 
			(*func)(
 
				GetParam(ForceType<Targ1>(), vm, 2, &ptr),
 
				GetParam(ForceType<Targ2>(), vm, 3, &ptr),
 
				GetParam(ForceType<Targ3>(), vm, 4, &ptr),
 
				GetParam(ForceType<Targ4>(), vm, 5, &ptr),
 
				GetParam(ForceType<Targ5>(), vm, 6, &ptr),
 
				GetParam(ForceType<Targ6>(), vm, 7, &ptr),
 
				GetParam(ForceType<Targ7>(), vm, 8, &ptr),
 
				GetParam(ForceType<Targ8>(), vm, 9, &ptr),
 
				GetParam(ForceType<Targ9>(), vm, 10, &ptr),
 
				GetParam(ForceType<Targ10>(), vm, 11, &ptr)
 
			);
 
			sq_pop(vm, 10);
 
			return 0;
 
		}
 
	};
 

	
 
	/**
 
	 * The real C++ caller for method with return value and 10 params.
 
	 */
 
	template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5, typename Targ6, typename Targ7, typename Targ8, typename Targ9, typename Targ10>
 
	struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), false> {
 
		static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
 
		{
 
			SQAutoFreePointers ptr;
 
			Tretval ret = (instance->*func)(
 
				GetParam(ForceType<Targ1>(), vm, 2, &ptr),
 
				GetParam(ForceType<Targ2>(), vm, 3, &ptr),
 
				GetParam(ForceType<Targ3>(), vm, 4, &ptr),
 
				GetParam(ForceType<Targ4>(), vm, 5, &ptr),
 
				GetParam(ForceType<Targ5>(), vm, 6, &ptr),
 
				GetParam(ForceType<Targ6>(), vm, 7, &ptr),
 
				GetParam(ForceType<Targ7>(), vm, 8, &ptr),
 
				GetParam(ForceType<Targ8>(), vm, 9, &ptr),
 
				GetParam(ForceType<Targ9>(), vm, 10, &ptr),
 
				GetParam(ForceType<Targ10>(), vm, 11, &ptr)
 
			);
 
			sq_pop(vm, 10);
 
			return Return(vm, ret);
 
		}
 
	};
 

	
 
	/**
 
	 * The real C++ caller for method with no return value and 10 params.
 
	 */
 
	template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5, typename Targ6, typename Targ7, typename Targ8, typename Targ9, typename Targ10>
 
	struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), true> {
 
		static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
 
		{
 
			SQAutoFreePointers ptr;
 
			(instance->*func)(
 
				GetParam(ForceType<Targ1>(), vm, 2, &ptr),
 
				GetParam(ForceType<Targ2>(), vm, 3, &ptr),
 
				GetParam(ForceType<Targ3>(), vm, 4, &ptr),
 
				GetParam(ForceType<Targ4>(), vm, 5, &ptr),
 
				GetParam(ForceType<Targ5>(), vm, 6, &ptr),
 
				GetParam(ForceType<Targ6>(), vm, 7, &ptr),
 
				GetParam(ForceType<Targ7>(), vm, 8, &ptr),
 
				GetParam(ForceType<Targ8>(), vm, 9, &ptr),
 
				GetParam(ForceType<Targ9>(), vm, 10, &ptr),
 
				GetParam(ForceType<Targ10>(), vm, 11, &ptr)
 
			);
 
			sq_pop(vm, 10);
 
			return 0;
 
		}
 

	
 
		static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
 
		{
 
			SQAutoFreePointers ptr;
 
			Tcls *inst = new Tcls(
 
				GetParam(ForceType<Targ1>(), vm, 2, &ptr),
 
				GetParam(ForceType<Targ2>(), vm, 3, &ptr),
 
				GetParam(ForceType<Targ3>(), vm, 4, &ptr),
 
				GetParam(ForceType<Targ4>(), vm, 5, &ptr),
 
				GetParam(ForceType<Targ5>(), vm, 6, &ptr),
 
				GetParam(ForceType<Targ6>(), vm, 7, &ptr),
 
				GetParam(ForceType<Targ7>(), vm, 8, &ptr),
 
				GetParam(ForceType<Targ8>(), vm, 9, &ptr),
 
				GetParam(ForceType<Targ9>(), vm, 10, &ptr),
 
				GetParam(ForceType<Targ10>(), vm, 11, &ptr)
 
			);
 

	
 
			return inst;
 
		}
 
	};
 

	
 

	
 
	/**
 
	 * A general template for all non-static method callbacks from Squirrel.
 
	 *  In here the function_proc is recovered, and the SQCall is called that
 
	 *  can handle this exact amount of params.
 
	 */
 
	template <typename Tcls, typename Tmethod>
 
	inline SQInteger DefSQNonStaticCallback(HSQUIRRELVM vm)
 
	{
 
		/* Find the amount of params we got */
 
		int nparam = sq_gettop(vm);
 
		SQUserPointer ptr = NULL;
 
		SQUserPointer real_instance = NULL;
 
		HSQOBJECT instance;
 

	
 
		/* Get the 'SQ' instance of this class */
 
		Squirrel::GetInstance(vm, &instance);
 

	
 
		/* Protect against calls to a non-static method in a static way */
 
		sq_pushroottable(vm);
 
		sq_pushstring(vm, OTTD2FS(Tcls::GetClassName()), -1);
 
		sq_get(vm, -2);
 
		sq_pushobject(vm, instance);
 
		if (sq_instanceof(vm) != SQTrue) return sq_throwerror(vm, _SC("class method is non-static"));
 
		sq_pop(vm, 3);
 

	
 
		/* Get the 'real' instance of this class */
 
		sq_getinstanceup(vm, 1, &real_instance, 0);
 
		/* Get the real function pointer */
 
		sq_getuserdata(vm, nparam, &ptr, 0);
 
		if (real_instance == NULL) return sq_throwerror(vm, _SC("couldn't detect real instance of class for non-static call"));
 
		/* Remove the userdata from the stack */
 
		sq_pop(vm, 1);
 

	
 
		try {
 
			/* Delegate it to a template that can handle this specific function */
 
			return HelperT<Tmethod>::SQCall((Tcls *)real_instance, *(Tmethod *)ptr, vm);
 
		} catch (SQInteger e) {
 
			sq_pop(vm, nparam);
 
			return e;
 
		}
 
	}
 

	
 
	/**
 
	 * A general template for all non-static advanced method callbacks from Squirrel.
 
	 *  In here the function_proc is recovered, and the SQCall is called that
 
	 *  can handle this exact amount of params.
 
	 */
 
	template <typename Tcls, typename Tmethod>
 
	inline SQInteger DefSQAdvancedNonStaticCallback(HSQUIRRELVM vm)
 
	{
 
		/* Find the amount of params we got */
 
		int nparam = sq_gettop(vm);
 
		SQUserPointer ptr = NULL;
 
		SQUserPointer real_instance = NULL;
 
		HSQOBJECT instance;
 

	
 
		/* Get the 'SQ' instance of this class */
 
		Squirrel::GetInstance(vm, &instance);
 

	
 
		/* Protect against calls to a non-static method in a static way */
 
		sq_pushroottable(vm);
 
		sq_pushstring(vm, OTTD2FS(Tcls::GetClassName()), -1);
 
		sq_get(vm, -2);
 
		sq_pushobject(vm, instance);
 
		if (sq_instanceof(vm) != SQTrue) return sq_throwerror(vm, _SC("class method is non-static"));
 
		sq_pop(vm, 3);
 

	
 
		/* Get the 'real' instance of this class */
 
		sq_getinstanceup(vm, 1, &real_instance, 0);
 
		/* Get the real function pointer */
 
		sq_getuserdata(vm, nparam, &ptr, 0);
 
		if (real_instance == NULL) return sq_throwerror(vm, _SC("couldn't detect real instance of class for non-static call"));
 
		/* Remove the userdata from the stack */
 
		sq_pop(vm, 1);
 

	
 
		/* Call the function, which its only param is always the VM */
 
		return (SQInteger)(((Tcls *)real_instance)->*(*(Tmethod *)ptr))(vm);
 
	}
 

	
 
	/**
 
	 * A general template for all function/static method callbacks from Squirrel.
 
	 *  In here the function_proc is recovered, and the SQCall is called that
 
	 *  can handle this exact amount of params.
 
	 */
 
	template <typename Tcls, typename Tmethod>
 
	inline SQInteger DefSQStaticCallback(HSQUIRRELVM vm)
 
	{
 
		/* Find the amount of params we got */
 
		int nparam = sq_gettop(vm);
 
		SQUserPointer ptr = NULL;
 

	
 
		/* Get the real function pointer */
 
		sq_getuserdata(vm, nparam, &ptr, 0);
 

	
 
		try {
 
			/* Delegate it to a template that can handle this specific function */
 
			return HelperT<Tmethod>::SQCall((Tcls *)NULL, *(Tmethod *)ptr, vm);
 
		} catch (SQInteger e) {
 
			sq_pop(vm, nparam);
 
			return e;
 
		}
 
	}
 

	
 
	/**
 
	 * A general template for the destructor of SQ instances. This is needed
 
	 *  here as it has to be in the same scope as DefSQConstructorCallback.
 
	 */
 
	template <typename Tcls>
 
	static SQInteger DefSQDestructorCallback(SQUserPointer p, SQInteger size)
 
	{
 
		/* Remove the real instance too */
 
		if (p != NULL) ((Tcls *)p)->Release();
 
		return 0;
 
	}
 

	
 
	/**
 
	 * A general template to handle creating of instance with any amount of
 
	 *  params. It creates the instance in C++, and it sets all the needed
 
	 *  settings in SQ to register the instance.
 
	 */
 
	template <typename Tcls, typename Tmethod, int Tnparam>
 
	inline SQInteger DefSQConstructorCallback(HSQUIRRELVM vm)
 
	{
 
		/* Find the amount of params we got */
 
		int nparam = sq_gettop(vm);
 

	
 
		try {
 
			/* Create the real instance */
 
			Tcls *instance = HelperT<Tmethod>::SQConstruct((Tcls *)NULL, (Tmethod)NULL, vm);
 
			sq_setinstanceup(vm, -Tnparam, instance);
 
			sq_setreleasehook(vm, -Tnparam, DefSQDestructorCallback<Tcls>);
 
			instance->AddRef();
 
			return 0;
 
		} catch (SQInteger e) {
 
			sq_pop(vm, nparam);
 
			return e;
 
		}
 
	}
 

	
 
}; // namespace SQConvert
 

	
 
#endif /* SQUIRREL_HELPER_HPP */
src/script/squirrel_helper_type.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file squirrel_helper_type.hpp Helper structs for converting Squirrel data structures to C++. */
 

	
 
#ifndef SQUIRREL_HELPER_TYPE_HPP
 
#define SQUIRREL_HELPER_TYPE_HPP
 

	
 
struct Array {
 
	int32 size;
 
	int32 array[VARARRAY_SIZE];
 
};
 

	
 
#endif /* SQUIRREL_HELPER_TYPE_HPP */
src/script/squirrel_std.cpp
Show inline comments
 
new file 100644
 

	
 
#include <squirrel.h>
 
#include "../stdafx.h"
 
#include "../debug.h"
 
#include "squirrel.hpp"
 
#include "squirrel_std.hpp"
 
#include "../core/alloc_func.hpp"
 
#include "../core/math_func.hpp"
 

	
 
/* abs() is normally defined to myabs(), which we don't want in this file */
 
#undef abs
 

	
 
SQInteger SquirrelStd::abs(HSQUIRRELVM vm)
 
{
 
	SQInteger tmp;
 

	
 
	sq_getinteger(vm, 2, &tmp);
 
	sq_pushinteger(vm, ::abs(tmp));
 
	return 1;
 
}
 

	
 
SQInteger SquirrelStd::min(HSQUIRRELVM vm)
 
{
 
	SQInteger tmp1, tmp2;
 

	
 
	sq_getinteger(vm, 2, &tmp1);
 
	sq_getinteger(vm, 3, &tmp2);
 
	sq_pushinteger(vm, ::min(tmp1, tmp2));
 
	return 1;
 
}
 

	
 
SQInteger SquirrelStd::max(HSQUIRRELVM vm)
 
{
 
	SQInteger tmp1, tmp2;
 

	
 
	sq_getinteger(vm, 2, &tmp1);
 
	sq_getinteger(vm, 3, &tmp2);
 
	sq_pushinteger(vm, ::max(tmp1, tmp2));
 
	return 1;
 
}
 

	
 
SQInteger SquirrelStd::require(HSQUIRRELVM vm)
 
{
 
	SQInteger top = sq_gettop(vm);
 
	const SQChar *filename;
 
	SQChar *real_filename;
 

	
 
	sq_getstring(vm, 2, &filename);
 

	
 
	/* Get the script-name of the current file, so we can work relative from it */
 
	SQStackInfos si;
 
	sq_stackinfos(vm, 1, &si);
 
	if (si.source == NULL) {
 
		DEBUG(misc, 0, "[squirrel] Couldn't detect the script-name of the 'require'-caller; this should never happen!");
 
		return SQ_ERROR;
 
	}
 
	real_filename = scstrdup(si.source);
 
	/* Keep the dir, remove the rest */
 
	SQChar *s = scstrrchr(real_filename, PATHSEPCHAR);
 
	if (s != NULL) {
 
		/* Keep the PATHSEPCHAR there, remove the rest */
 
		*s++;
 
		*s = '\0';
 
	}
 
	/* And now we concat, so we are relative from the current script
 
	 * First, we have to make sure we have enough space for the full path */
 
	real_filename = ReallocT(real_filename, scstrlen(real_filename) + scstrlen(filename) + 1);
 
	scstrcat(real_filename, filename);
 
	/* Tars dislike opening files with '/' on Windows.. so convert it to '\\' ;) */
 
	char *filen = strdup(FS2OTTD(real_filename));
 
#if (PATHSEPCHAR != '/')
 
	for (char *n = filen; *n != '\0'; n++) if (*n == '/') *n = PATHSEPCHAR;
 
#endif
 

	
 
	bool ret = Squirrel::LoadScript(vm, filen);
 

	
 
	/* Reset the top, so the stack stays correct */
 
	sq_settop(vm, top);
 
	free(real_filename);
 
	free(filen);
 

	
 
	return ret ? 0: SQ_ERROR;
 
}
 

	
 
SQInteger SquirrelStd::notifyallexceptions(HSQUIRRELVM vm)
 
{
 
	SQBool b;
 

	
 
	if (sq_gettop(vm) >= 1) {
 
		if (SQ_SUCCEEDED(sq_getbool(vm, -1, &b))) {
 
			sq_notifyallexceptions(vm, b);
 
			return 0;
 
		}
 
	}
 

	
 
	return SQ_ERROR;
 
}
 

	
 
void squirrel_register_global_std(Squirrel *engine)
 
{
 
	/* We don't use squirrel_helper here, as we want to register to the global
 
	 *  scope and not to a class. */
 
	engine->AddMethod("require",             &SquirrelStd::require,             2, "?s");
 
	engine->AddMethod("notifyallexceptions", &SquirrelStd::notifyallexceptions, 2, "?b");
 
}
 

	
 
void squirrel_register_std(Squirrel *engine)
 
{
 
	/* We don't use squirrel_helper here, as we want to register to the global
 
	 *  scope and not to a class. */
 
	engine->AddMethod("abs", &SquirrelStd::abs, 2, "?i");
 
	engine->AddMethod("min", &SquirrelStd::min, 3, "?ii");
 
	engine->AddMethod("max", &SquirrelStd::max, 3, "?ii");
 
}
src/script/squirrel_std.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file squirrel_std.hpp defines the Squirrel Standard Function class */
 

	
 
#ifndef SQUIRREL_STD_HPP
 
#define SQUIRREL_STD_HPP
 

	
 
#if defined(__APPLE__)
 
/* Which idiotic system makes 'require' a macro? :s Oh well.... */
 
#undef require
 
#endif /* __APPLE__ */
 

	
 
/**
 
 * By default we want to give a set of standard commands to a SQ script.
 
 * Most of them are easy wrappers around internal functions. Of course we
 
 *  could just as easy include things like the stdmath of SQ, but of those
 
 *  functions we are sure they work on all our supported targets.
 
 */
 
class SquirrelStd {
 
public:
 
	/**
 
	 * Make an integer absolute.
 
	 */
 
	static SQInteger abs(HSQUIRRELVM vm);
 

	
 
	/**
 
	 * Get the lowest of two integers.
 
	 */
 
	static SQInteger min(HSQUIRRELVM vm);
 

	
 
	/**
 
	 * Get the highest of two integers.
 
	 */
 
	static SQInteger max(HSQUIRRELVM vm);
 

	
 
	/**
 
	 * Load an other file on runtime.
 
	 * @note This is always loaded on the root-level, no matter where you call this.
 
	 * @note The filename is always relative from the script it is called from. Absolute calls are NOT allowed!
 
	 */
 
	static SQInteger require(HSQUIRRELVM vm);
 

	
 
	/**
 
	 * Enable/disable stack trace showing for handled exceptions.
 
	 */
 
	static SQInteger notifyallexceptions(HSQUIRRELVM vm);
 
};
 

	
 
/**
 
 * Register all standard functions we want to give to a script.
 
 */
 
void squirrel_register_std(Squirrel *engine);
 

	
 
/**
 
 * Register all standard functions that are available on first startup.
 
 * @note this set is very limited, and is only ment to load other scripts and things like that.
 
 */
 
void squirrel_register_global_std(Squirrel *engine);
 

	
 
#endif /* SQUIRREL_STD_HPP */
src/settings.cpp
Show inline comments
 
@@ -64,6 +64,9 @@
 
#include "station_func.h"
 
#include "settings_func.h"
 
#include "ini_type.h"
 
#include "ai/ai.hpp"
 
#include "ai/ai_config.hpp"
 
#include "ai/ai_info.hpp"
 

	
 
#include "table/strings.h"
 

	
 
@@ -827,21 +830,6 @@ static int32 v_PositionMainToolbar(int32
 
	return 0;
 
}
 

	
 
static int32 AiNew_PatchActive_Warning(int32 p1)
 
{
 
	if (p1 == 1) ShowErrorMessage(INVALID_STRING_ID, TEMP_AI_ACTIVATED, 0, 0);
 
	return 0;
 
}
 

	
 
static int32 Ai_In_Multiplayer_Warning(int32 p1)
 
{
 
	if (p1 == 1) {
 
		ShowErrorMessage(INVALID_STRING_ID, TEMP_AI_MULTIPLAYER, 0, 0);
 
		_settings_game.ai.ainew_active = true;
 
	}
 
	return 0;
 
}
 

	
 
static int32 PopulationInLabelActive(int32 p1)
 
{
 
	Town *t;
 
@@ -1330,12 +1318,13 @@ const SettingDesc _patch_settings[] = {
 
	 SDT_CONDVAR(GameSettings, economy.initial_city_size,            SLE_UINT8, 56, SL_MAX_VERSION, 0, 0,     2,     1,      10, 1, STR_CONFIG_PATCHES_CITY_SIZE_MULTIPLIER,   NULL),
 
	SDT_CONDBOOL(GameSettings, economy.mod_road_rebuild,                        77, SL_MAX_VERSION, 0, 0, false,                    STR_CONFIG_MODIFIED_ROAD_REBUILD,          NULL),
 

	
 
	    SDT_BOOL(GameSettings, ai.ainew_active,                                                     0, 0, false,                    STR_CONFIG_PATCHES_AINEW_ACTIVE,           AiNew_PatchActive_Warning),
 
	    SDT_BOOL(GameSettings, ai.ai_in_multiplayer,                                                0, 0, false,                    STR_CONFIG_PATCHES_AI_IN_MULTIPLAYER,      Ai_In_Multiplayer_Warning),
 
	SDT_CONDNULL(1, 0, 106), // previously ai-new setting.
 
	    SDT_BOOL(GameSettings, ai.ai_in_multiplayer,                                                0, 0, true,                     STR_CONFIG_PATCHES_AI_IN_MULTIPLAYER,      NULL),
 
	    SDT_BOOL(GameSettings, ai.ai_disable_veh_train,                                             0, 0, false,                    STR_CONFIG_PATCHES_AI_BUILDS_TRAINS,       NULL),
 
	    SDT_BOOL(GameSettings, ai.ai_disable_veh_roadveh,                                           0, 0, false,                    STR_CONFIG_PATCHES_AI_BUILDS_ROADVEH,      NULL),
 
	    SDT_BOOL(GameSettings, ai.ai_disable_veh_aircraft,                                          0, 0, false,                    STR_CONFIG_PATCHES_AI_BUILDS_AIRCRAFT,     NULL),
 
	    SDT_BOOL(GameSettings, ai.ai_disable_veh_ship,                                              0, 0, false,                    STR_CONFIG_PATCHES_AI_BUILDS_SHIPS,        NULL),
 
	 SDT_CONDVAR(GameSettings, ai.ai_max_opcode_till_suspend,       SLE_UINT32,107, SL_MAX_VERSION, 0, NG, 10000, 5000,250000,2500, STR_CONFIG_PATCHES_AI_MAX_OPCODES,         NULL),
 

	
 
	     SDT_VAR(GameSettings, vehicle.extend_vehicle_life,          SLE_UINT8,                     0, 0,     0,     0,     100, 0, STR_NULL,                                  NULL),
 
	     SDT_VAR(GameSettings, economy.dist_local_authority,         SLE_UINT8,                     0, 0,    20,     5,      60, 0, STR_NULL,                                  NULL),
 
@@ -1635,6 +1624,32 @@ static void NewsDisplayLoadConfig(IniFil
 
	}
 
}
 

	
 
static void AILoadConfig(IniFile *ini, const char *grpname)
 
{
 
	IniGroup *group = ini->GetGroup(grpname);
 
	IniItem *item;
 

	
 
	/* Clean any configured AI */
 
	for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) {
 
		AIConfig::GetConfig(c, true)->ChangeAI(NULL);
 
	}
 

	
 
	/* If no group exists, return */
 
	if (group == NULL) return;
 

	
 
	CompanyID c = COMPANY_FIRST;
 
	for (item = group->item; c < MAX_COMPANIES && item != NULL; c++, item = item->next) {
 
		AIConfig *config = AIConfig::GetConfig(c, true);
 

	
 
		config->ChangeAI(item->name);
 
		if (!config->HasAI()) {
 
			if (strcmp(item->name, "none") != 0) DEBUG(ai, 0, "The AI by the name '%s' was no longer found, and removed from the list.", item->name);
 
			continue;
 
		}
 
		config->StringToSettings(item->value);
 
	}
 
}
 

	
 
/* Load a GRF configuration from the given group name */
 
static GRFConfig *GRFLoadConfig(IniFile *ini, const char *grpname, bool is_static)
 
{
 
@@ -1702,6 +1717,34 @@ static void NewsDisplaySaveConfig(IniFil
 
	}
 
}
 

	
 
static void AISaveConfig(IniFile *ini, const char *grpname)
 
{
 
	IniGroup *group = ini->GetGroup(grpname);
 
	IniItem **item;
 

	
 
	if (group == NULL) return;
 
	group->item = NULL;
 
	item = &group->item;
 

	
 
	for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) {
 
		AIConfig *config = AIConfig::GetConfig(c, true);
 
		const char *name;
 
		char value[1024];
 

	
 
		if (config->HasAI()) {
 
			config->SettingsToString(value, lengthof(value));
 
			name = config->GetName();
 
		} else {
 
			value[0] = '\0';
 
			name = "none";
 
		}
 

	
 
		*item = new IniItem(group, name);
 
		(*item)->value = strdup(value);
 
		item = &(*item)->next;
 
	}
 
}
 

	
 
/**
 
 * Save the version of OpenTTD to the ini file.
 
 * @param ini the ini to write to
 
@@ -1777,6 +1820,7 @@ void LoadFromConfig()
 
	_grfconfig_newgame = GRFLoadConfig(ini, "newgrf", false);
 
	_grfconfig_static  = GRFLoadConfig(ini, "newgrf-static", true);
 
	NewsDisplayLoadConfig(ini, "news_display");
 
	AILoadConfig(ini, "ai_players");
 
	CheckDifficultyLevels();
 
	delete ini;
 
}
 
@@ -1795,6 +1839,7 @@ void SaveToConfig()
 
	GRFSaveConfig(ini, "newgrf", _grfconfig_newgame);
 
	GRFSaveConfig(ini, "newgrf-static", _grfconfig_static);
 
	NewsDisplaySaveConfig(ini, "news_display");
 
	AISaveConfig(ini, "ai_players");
 
	SaveVersionInConfig(ini);
 
	ini->SaveToDisk(_config_file);
 
	delete ini;
src/settings_gui.cpp
Show inline comments
 
@@ -1117,12 +1117,12 @@ static PatchEntry _patches_economy[] = {
 
static PatchPage _patches_economy_page = {_patches_economy, lengthof(_patches_economy)};
 

	
 
static PatchEntry _patches_ai_npc[] = {
 
	PatchEntry("ai.ainew_active"),
 
	PatchEntry("ai.ai_in_multiplayer"),
 
	PatchEntry("ai.ai_disable_veh_train"),
 
	PatchEntry("ai.ai_disable_veh_roadveh"),
 
	PatchEntry("ai.ai_disable_veh_aircraft"),
 
	PatchEntry("ai.ai_disable_veh_ship"),
 
	PatchEntry("ai.ai_max_opcode_till_suspend"),
 
};
 
/** Computer players sub-page */
 
static PatchPage _patches_ai_npc_page = {_patches_ai_npc, lengthof(_patches_ai_npc)};
src/settings_type.h
Show inline comments
 
@@ -9,6 +9,7 @@
 
#include "town_type.h"
 
#include "transport_type.h"
 
#include "network/core/config.h"
 
#include "company_type.h"
 

	
 
/** Settings related to the difficulty of the game */
 
struct DifficultySettings {
 
@@ -170,12 +171,12 @@ struct ConstructionSettings {
 

	
 
/** Settings related to the AI. */
 
struct AISettings {
 
	bool   ainew_active;                     ///< is the new AI active?
 
	bool   ai_in_multiplayer;                ///< so we allow AIs in multiplayer
 
	bool   ai_disable_veh_train;             ///< disable types for AI
 
	bool   ai_disable_veh_roadveh;           ///< disable types for AI
 
	bool   ai_disable_veh_aircraft;          ///< disable types for AI
 
	bool   ai_disable_veh_ship;              ///< disable types for AI
 
	uint32 ai_max_opcode_till_suspend;       ///< max opcode calls till AI will suspend
 
};
 

	
 
/** Settings related to the old pathfinder. */
 
@@ -339,6 +340,7 @@ struct GameSettings {
 
	GameCreationSettings game_creation;      ///< settings used during the creation of a game (map)
 
	ConstructionSettings construction;       ///< construction of things in-game
 
	AISettings           ai;                 ///< what may the AI do?
 
	class AIConfig      *ai_config[MAX_COMPANIES]; ///< settings per company
 
	PathfinderSettings   pf;                 ///< settings for all pathfinders
 
	OrderSettings        order;              ///< settings related to orders
 
	VehicleSettings      vehicle;            ///< options for vehicles
src/ship_cmd.cpp
Show inline comments
 
@@ -41,6 +41,7 @@
 
#include "settings_type.h"
 
#include "order_func.h"
 
#include "effectvehicle_func.h"
 
#include "ai/ai.hpp"
 

	
 
#include "table/strings.h"
 

	
 
@@ -353,6 +354,7 @@ static void ShipArrivesAt(const Vehicle 
 
			v->index,
 
			st->index
 
		);
 
		AI::NewEvent(v->owner, new AIEventStationFirstVehicle(st->index, v->index));
 
	}
 
}
 

	
src/signs.cpp
Show inline comments
 
@@ -97,6 +97,9 @@ CommandCost CmdPlaceSign(TileIndex tile,
 
	/* Try to locate a new sign */
 
	if (!Sign::CanAllocateItem()) return_cmd_error(STR_2808_TOO_MANY_SIGNS);
 

	
 
	/* Check sign text length if any */
 
	if (!StrEmpty(text) && strlen(text) >= MAX_LENGTH_SIGN_NAME_BYTES) return CMD_ERROR;
 

	
 
	/* When we execute, really make the sign */
 
	if (flags & DC_EXEC) {
 
		Sign *si = new Sign(_current_company);
 
@@ -106,6 +109,9 @@ CommandCost CmdPlaceSign(TileIndex tile,
 
		si->x = x;
 
		si->y = y;
 
		si->z = GetSlopeZ(x, y);
 
		if (!StrEmpty(text)) {
 
			si->name = strdup(text);
 
		}
 
		UpdateSignVirtCoords(si);
 
		MarkSignDirty(si);
 
		InvalidateWindowData(WC_SIGN_LIST, 0, 0);
src/spritecache.cpp
Show inline comments
 
@@ -17,14 +17,12 @@
 
#endif /* WITH_PNG */
 
#include "blitter/factory.hpp"
 
#include "core/math_func.hpp"
 
#include "core/enum_type.hpp"
 

	
 
#include "table/sprites.h"
 

	
 
/* Default of 4MB spritecache */
 
uint _sprite_cache_size = 4;
 

	
 
typedef SimpleTinyEnumT<SpriteType, byte> SpriteTypeByte;
 

	
 
struct SpriteCache {
 
	void *ptr;
 
@@ -32,8 +30,8 @@ struct SpriteCache {
 
	uint32 id;
 
	uint16 file_slot;
 
	int16 lru;
 
	SpriteTypeByte type; ///< In some cases a single sprite is misused by two NewGRFs. Once as real sprite and once as recolour sprite. If the recolour sprite gets into the cache it might be drawn as real sprite which causes enormous trouble.
 
	bool warned;         ///< True iff the user has been warned about incorrect use of this sprite
 
	SpriteType type; ///< In some cases a single sprite is misused by two NewGRFs. Once as real sprite and once as recolour sprite. If the recolour sprite gets into the cache it might be drawn as real sprite which causes enormous trouble.
 
	bool warned;     ///< True iff the user has been warned about incorrect use of this sprite
 
};
 

	
 

	
src/station_cmd.cpp
Show inline comments
 
@@ -746,7 +746,7 @@ CommandCost CheckFlatLandBelow(TileIndex
 
		 *     b) the build_on_slopes switch is disabled
 
		 */
 
		if (IsSteepSlope(tileh) ||
 
				((_is_old_ai_company || !_settings_game.construction.build_on_slopes) && tileh != SLOPE_FLAT)) {
 
				((!_settings_game.construction.build_on_slopes) && tileh != SLOPE_FLAT)) {
 
			return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
 
		}
 

	
 
@@ -1001,7 +1001,7 @@ CommandCost CmdBuildRailroadStation(Tile
 

	
 
		if (st->train_tile != INVALID_TILE) {
 
			/* check if we want to expanding an already existing station? */
 
			if (_is_old_ai_company || !_settings_game.station.join_stations)
 
			if (!_settings_game.station.join_stations)
 
				return_cmd_error(STR_3005_TOO_CLOSE_TO_ANOTHER_RAILROAD);
 
			if (!CanExpandRailroadStation(st, finalvalues, axis))
 
				return CMD_ERROR;
 
@@ -1764,7 +1764,7 @@ static const byte * const _airport_secti
 
 * @param tile TileIndex of northern tile of an airport (present or to-be-built), NOT the station tile
 
 * @return the noise that will be generated, according to distance
 
 */
 
static uint8 GetAirportNoiseLevelForTown(const AirportFTAClass *afc, TileIndex town_tile, TileIndex tile)
 
uint8 GetAirportNoiseLevelForTown(const AirportFTAClass *afc, TileIndex town_tile, TileIndex tile)
 
{
 
	struct TileIndexDistance {
 
		TileIndex index;
src/tar_type.h
Show inline comments
 
@@ -11,12 +11,13 @@
 
/** The define of a TarList. */
 
struct TarListEntry {
 
	const char *filename;
 
	const char *dirname;
 

	
 
	/* MSVC goes copying around this struct after initialisation, so it tries
 
	 * to free filename, which isn't set at that moment... but because it
 
	 * initializes the variable with garbage, it's going to segfault. */
 
	TarListEntry() : filename(NULL) {}
 
	~TarListEntry() { free((void*)this->filename); }
 
	TarListEntry() : filename(NULL), dirname(NULL) {}
 
	~TarListEntry() { free((void*)this->filename); free((void*)this->dirname); }
 
};
 

	
 
struct TarFileListEntry {
src/toolbar_gui.cpp
Show inline comments
 
@@ -37,6 +37,7 @@
 
#include "functions.h"
 
#include "console_gui.h"
 
#include "news_gui.h"
 
#include "ai/ai_gui.hpp"
 
#include "tilehighlight_func.h"
 
#include "rail.h"
 
#include "widgets/dropdown_func.h"
 
@@ -702,7 +703,7 @@ static void MenuClickNewspaper(int index
 

	
 
static void ToolbarHelpClick(Window *w)
 
{
 
	PopupMainToolbMenu(w, TBN_HELP, STR_02D5_LAND_BLOCK_INFO, 6);
 
	PopupMainToolbMenu(w, TBN_HELP, STR_02D5_LAND_BLOCK_INFO, 7);
 
}
 

	
 
static void MenuClickSmallScreenshot()
 
@@ -720,9 +721,10 @@ static void MenuClickHelp(int index)
 
	switch (index) {
 
		case 0: PlaceLandBlockInfo();       break;
 
		case 2: IConsoleSwitch();           break;
 
		case 3: MenuClickSmallScreenshot(); break;
 
		case 4: MenuClickWorldScreenshot(); break;
 
		case 5: ShowAboutWindow();          break;
 
		case 3: ShowAIDebugWindow();        break;
 
		case 4: MenuClickSmallScreenshot(); break;
 
		case 5: MenuClickWorldScreenshot(); break;
 
		case 6: ShowAboutWindow();          break;
 
	}
 
}
 

	
src/town_cmd.cpp
Show inline comments
 
@@ -529,7 +529,7 @@ static bool ClickTile_Town(TileIndex til
 

	
 
static CommandCost ClearTile_Town(TileIndex tile, byte flags)
 
{
 
	if ((flags & DC_AUTO) && !(flags & DC_AI_BUILDING)) return_cmd_error(STR_2004_BUILDING_MUST_BE_DEMOLISHED);
 
	if (flags & DC_AUTO) return_cmd_error(STR_2004_BUILDING_MUST_BE_DEMOLISHED);
 
	if (!CanDeleteHouse(tile)) return CMD_ERROR;
 

	
 
	const HouseSpec *hs = GetHouseSpecs(GetHouseType(tile));
src/train_cmd.cpp
Show inline comments
 
@@ -48,6 +48,7 @@
 
#include "variables.h"
 
#include "autoreplace_gui.h"
 
#include "gfx_func.h"
 
#include "ai/ai.hpp"
 
#include "settings_type.h"
 
#include "order_func.h"
 
#include "newgrf_station.h"
 
@@ -1376,15 +1377,13 @@ CommandCost CmdMoveRailVehicle(TileIndex
 
 * - p2 = 0: only sell the single dragged wagon/engine (and any belonging rear-engines)
 
 * - p2 = 1: sell the vehicle and all vehicles following it in the chain
 
 *           if the wagon is dragged, don't delete the possibly belonging rear-engine to some front
 
 * - p2 = 2: when selling attached locos, rearrange all vehicles after it to separate lines;
 
 *           all wagons of the same type will go on the same line. Used by the AI currently
 
 */
 
CommandCost CmdSellRailWagon(TileIndex tile, uint32 flags, uint32 p1, uint32 p2, const char *text)
 
{
 
	/* Check if we deleted a vehicle window */
 
	Window *w = NULL;
 

	
 
	if (!IsValidVehicleID(p1) || p2 > 2) return CMD_ERROR;
 
	if (!IsValidVehicleID(p1) || p2 > 1) return CMD_ERROR;
 

	
 
	Vehicle *v = GetVehicle(p1);
 

	
 
@@ -1416,9 +1415,8 @@ CommandCost CmdSellRailWagon(TileIndex t
 

	
 
	CommandCost cost(EXPENSES_NEW_VEHICLES);
 
	switch (p2) {
 
		case 0: case 2: { /* Delete given wagon */
 
		case 0: { /* Delete given wagon */
 
			bool switch_engine = false;    // update second wagon to engine?
 
			byte ori_subtype = v->subtype; // backup subtype of deleted wagon in case DeleteVehicle() changes
 

	
 
			/* 1. Delete the engine, if it is dualheaded also delete the matching
 
			 * rear engine of the loco (from the point of deletion onwards) */
 
@@ -1490,18 +1488,6 @@ CommandCost CmdSellRailWagon(TileIndex t
 
					if (IsFrontEngine(first)) InvalidateWindow(WC_VEHICLE_REFIT, first->index);
 
				}
 

	
 

	
 
				/* (6.) Borked AI. If it sells an engine it expects all wagons lined
 
				 * up on a new line to be added to the newly built loco. Replace it is.
 
				 * Totally braindead cause building a new engine adds all loco-less
 
				 * engines to its train anyways */
 
				if (p2 == 2 && HasBit(ori_subtype, TS_FRONT)) {
 
					for (v = first; v != NULL;) {
 
						Vehicle *tmp = GetNextVehicle(v);
 
						DoCommand(v->tile, v->index | INVALID_VEHICLE << 16, 0, DC_EXEC, CMD_MOVE_RAIL_VEHICLE);
 
						v = tmp;
 
					}
 
				}
 
			}
 
		} break;
 
		case 1: { /* Delete wagon and all wagons after it given certain criteria */
 
@@ -2729,6 +2715,7 @@ static PBSTileInfo ExtendTrainReservatio
 
		if (KillFirstBit(ft.m_new_td_bits) == TRACKDIR_BIT_NONE) {
 
			/* Possible signal tile. */
 
			if (HasOnewaySignalBlockingTrackdir(ft.m_new_tile, FindFirstTrackdir(ft.m_new_td_bits))) break;
 
			AI::NewEvent(v->owner, new AIEventVehicleLost(v->index));
 
		}
 

	
 
		if (no_90deg_turns) {
 
@@ -3352,6 +3339,7 @@ static void TrainEnterStation(Vehicle *v
 
			v->index,
 
			st->index
 
		);
 
		AI::NewEvent(v->owner, new AIEventStationFirstVehicle(st->index, v->index));
 
	}
 

	
 
	v->BeginLoading();
 
@@ -3627,6 +3615,7 @@ static bool CheckTrainCollision(Vehicle 
 
	/* any dead -> no crash */
 
	if (tcc.num == 0) return false;
 

	
 
	AI::NewEvent(v->owner, new AIEventVehicleCrashed(v->index, v->tile));
 
	SetDParam(0, tcc.num);
 
	AddNewsItem(STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL,
 
		NS_ACCIDENT_VEHICLE,
src/tunnelbridge_cmd.cpp
Show inline comments
 
@@ -318,7 +318,7 @@ CommandCost CmdBuildBridge(TileIndex end
 
	} else {
 
		/* Build a new bridge. */
 

	
 
		bool allow_on_slopes = (!_is_old_ai_company && _settings_game.construction.build_on_slopes && transport_type != TRANSPORT_WATER);
 
		bool allow_on_slopes = (_settings_game.construction.build_on_slopes && transport_type != TRANSPORT_WATER);
 

	
 
		/* Try and clear the start landscape */
 
		ret = DoCommand(tile_start, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 
@@ -454,7 +454,7 @@ not_valid_below:;
 
	if (!(flags & DC_QUERY_COST) || (IsValidCompanyID(_current_company) && GetCompany(_current_company)->is_ai)) {
 
		bridge_len += 2; // begin and end tiles/ramps
 

	
 
		if (IsValidCompanyID(_current_company) && !_is_old_ai_company)
 
		if (IsValidCompanyID(_current_company))
 
			bridge_len = CalcBridgeLenCostFactor(bridge_len);
 

	
 
		cost.AddCost((int64)bridge_len * _price.build_bridge * GetBridgeSpec(bridge_type)->price >> 8);
src/variables.h
Show inline comments
 
@@ -38,8 +38,6 @@ VARDEF int _palette_animation_counter;
 

	
 
VARDEF uint32 _realtime_tick;
 

	
 
VARDEF bool _is_old_ai_company; // current company is an oldAI company? (enables a lot of cheats..)
 

	
 
VARDEF bool _do_autosave;
 
VARDEF int _autosave_ctr;
 

	
src/vehicle.cpp
Show inline comments
 
@@ -51,6 +51,7 @@
 
#include "depot_map.h"
 
#include "animated_tile_func.h"
 
#include "effectvehicle_base.h"
 
#include "ai/ai.hpp"
 
#include "core/alloc_func.hpp"
 
#include "core/smallmap_type.hpp"
 
#include "vehiclelist.h"
 
@@ -1518,6 +1519,7 @@ void VehicleEnterDepot(Vehicle *v)
 
				SetDParam(0, v->index);
 
				AddNewsItem(string, NS_ADVICE, v->index, 0);
 
			}
 
			AI::NewEvent(v->owner, new AIEventVehicleWaitingInDepot(v->index));
 
		}
 
	}
 
}
 
@@ -2213,9 +2215,9 @@ void VehiclesYearlyLoop()
 
	FOR_ALL_VEHICLES(v) {
 
		if (v->IsPrimaryVehicle()) {
 
			/* show warning if vehicle is not generating enough income last 2 years (corresponds to a red icon in the vehicle list) */
 
			if (_settings_client.gui.vehicle_income_warn && v->owner == _local_company && v->age >= 730) {
 
				Money profit = v->GetDisplayProfitThisYear();
 
				if (profit < 0) {
 
			Money profit = v->GetDisplayProfitThisYear();
 
			if (v->age >= 730 && profit < 0) {
 
				if (_settings_client.gui.vehicle_income_warn && v->owner == _local_company) {
 
					SetDParam(0, v->index);
 
					SetDParam(1, profit);
 
					AddNewsItem(
 
@@ -2224,6 +2226,7 @@ void VehiclesYearlyLoop()
 
						v->index,
 
						0);
 
				}
 
				AI::NewEvent(v->owner, new AIEventVehicleUnprofitable(v->index));
 
			}
 

	
 
			v->profit_last_year = v->profit_this_year;
src/window_type.h
Show inline comments
 
@@ -96,6 +96,7 @@ enum WindowClass {
 
	WC_OSK,
 
	WC_WAYPOINT_VIEW,
 
	WC_SELECT_STATION,
 
	WC_AI_DEBUG,
 

	
 
	WC_INVALID = 0xFFFF
 
};
0 comments (0 inline, 0 general)