Changeset - r1784:15b805156766
[Not reviewed]
master
0 12 0
Darkvater - 19 years ago 2005-05-09 22:33:00
darkvater@openttd.org
(svn r2288) - CodeChange: protected the next batch of commands (41 so far, out of 115).
- CodeChange: changed the airport gui airport-type checking. Added function GetValidAirports() that returns bitmasked availibility, is also used for checking.
- CodeChange: to check tree-planting, 2 const arrays have been moved to table/tree_land.h (type and count)
- CodeChange: added IsTownIndex() in following of IsStationIndex(), etc.
- Fix (regression): road tunnels did not work anymore, forgot that their type was 0x200 (documented now)
12 files changed with 262 insertions and 217 deletions:
0 comments (0 inline, 0 general)
airport.h
Show inline comments
 
@@ -45,7 +45,23 @@ typedef struct AirportFTA {
 
} AirportFTA;
 

	
 
void InitializeAirports(void);
 
void UnInitializeAirports(void);
 
const AirportFTAClass* GetAirport(const byte airport_type);
 

	
 
/** Get buildable airport bitmask.
 
 * @return get all buildable airports at this given time, bitmasked.
 
 * Bit 0 means the small airport is buildable, etc.
 
 * @todo set availability of airports by year, instead of airplane
 
 */
 
static inline uint32 GetValidAirports(void)
 
{
 
	uint32 bytemask = _avail_aircraft; /// sets the first 3 bytes, 0 - 2, @see AdjustAvailAircraft()
 

	
 
	// 1980-1-1 is --> 21915
 
	// 1990-1-1 is --> 25568
 
	if (_date >= 21915) {SETBIT(bytemask, 3);}	// metropilitan airport 1980
 
	if (_date >= 25568) {SETBIT(bytemask, 4);}	// international airport 1990
 
	return bytemask;
 
}
 

	
 
#endif /* AIRPORT_H */
airport_gui.c
Show inline comments
 
@@ -132,30 +132,31 @@ void ShowBuildAirToolbar(void)
 
	DeleteWindowById(WC_BUILD_TOOLBAR, 0);
 
	AllocateWindowDescFront(&_air_toolbar_desc, 0);
 
}
 

	
 
static void BuildAirportPickerWndProc(Window *w, WindowEvent *e)
 
{
 
	switch(e->event) {
 
	switch (e->event) {
 
	case WE_PAINT: {
 
		int sel;
 
		int rad = 4; // default catchment radious
 
		uint32 avail_airports;
 

	
 
		if (WP(w,def_d).close)
 
			return;
 
		w->disabled_state = 0;
 
		if (WP(w,def_d).close) return;
 

	
 
		sel = _selected_airport_type;
 
		// FIXME -- BuildAirportPickerWndProc - set availability of airports by year, instead of airplane
 
		if (!(_avail_aircraft & 1)) { w->disabled_state |= (1<<3); if (sel == AT_SMALL) sel = AT_LARGE; }
 
		if (!(_avail_aircraft & 2)) {	w->disabled_state |= (1<<4); if (sel == AT_LARGE) sel = AT_SMALL; }
 
		if (!(_avail_aircraft & 4)) {	w->disabled_state |= (1<<5); }	// heliport
 
		// 1980-1-1 is --> 21915
 
		// 1990-1-1 is --> 25568
 
		if (_date < 21915) {w->disabled_state |= (1<<6);}	// metropilitan airport 1980
 
		if (_date < 25568) {w->disabled_state |= (1<<7);}	// international airport 1990
 
		avail_airports = GetValidAirports();
 

	
 
		if (!HASBIT(avail_airports, 0) && sel == AT_SMALL) sel = AT_LARGE;
 
		if (!HASBIT(avail_airports, 1) && sel == AT_LARGE) sel = AT_SMALL;
 

	
 
		/* 'Country Airport' starts at widget 3, and if its bit is set, it is available,
 
		 * so take its opposite value to set the disabled_state. There are only 5 available
 
		 * airports, so XOr with 0x1F (1 1111) */
 
		w->disabled_state = (avail_airports ^ 0x1F) << 3;
 

	
 
		_selected_airport_type = sel;
 
		// select default the coverage area to 'Off' (8)
 
		w->click_state = ((1<<3) << sel) | ((1<<8) << _station_show_coverage);
 
		SetTileSelectSize(_airport_size_x[sel],_airport_size_y[sel]);
 

	
 
     if (_patches.modified_catchment) {
command.c
Show inline comments
 
@@ -186,13 +186,12 @@ static CommandProc * const _command_proc
 
	CmdRenameWaypoint,						/* 17 */
 
	CmdRemoveTrainWaypoint,				/* 18 */
 
	NULL,                         /* 19 */
 
	NULL,													/* 20 */
 
	CmdBuildRoadStop,							/* 21 */
 
	NULL,													/* 22 */
 
	/***************************************************/
 
	CmdBuildLongRoad,							/* 23 */
 
	CmdRemoveLongRoad,						/* 24 */
 
	CmdBuildRoad,									/* 25 */
 
	CmdRemoveRoad,								/* 26 */
 
	CmdBuildRoadDepot,						/* 27 */
 
	NULL,													/* 28 */
 
@@ -206,12 +205,13 @@ static CommandProc * const _command_proc
 
	CmdStartStopTrain,						/* 36 */
 
	NULL,													/* 37 */
 
	CmdSellRailWagon,							/* 38 */
 
	CmdTrainGotoDepot,						/* 39 */
 
	CmdForceTrainProceed,					/* 40 */
 
	CmdReverseTrainDirection,			/* 41 */
 
	/***************************************************/
 

	
 
	CmdModifyOrder,								/* 42 */
 
	CmdSkipOrder,									/* 43 */
 
	CmdDeleteOrder,								/* 44 */
 
	CmdInsertOrder,								/* 45 */
 

	
misc_gui.c
Show inline comments
 
@@ -2,12 +2,13 @@
 
#include "ttd.h"
 
#include "debug.h"
 
#include "spritecache.h"
 
#include "strings.h"
 
#include "table/sprites.h"
 
#include "table/strings.h"
 
#include "table/tree_land.h"
 
#include "map.h"
 
#include "window.h"
 
#include "gui.h"
 
#include "viewport.h"
 
#include "gfx.h"
 
#include "station.h"
 
@@ -268,14 +269,12 @@ void ShowAboutWindow(void)
 
	DeleteWindowById(WC_GAME_OPTIONS, 0);
 
	AllocateWindowDesc(&_about_desc);
 
}
 

	
 
static int _tree_to_plant;
 

	
 
static const byte _tree_base_by_landscape[4] = {0, 12, 20, 32};
 
static const byte _tree_count_by_landscape[4] = {12, 8, 12, 9};
 
static const uint32 _tree_sprites[] = {
 
	0x655,0x663,0x678,0x62B,0x647,0x639,0x64E,0x632,0x67F,0x68D,0x69B,0x6A9,
 
	0x6AF,0x6D2,0x6D9,0x6C4,0x6CB,0x6B6,0x6BD,0x6E0,
 
	0x72E,0x734,0x74A,0x74F,0x76B,0x78F,0x788,0x77B,0x75F,0x774,0x720,0x797,
 
	0x79E,0x30D87A5,0x30B87AC,0x7B3,0x7BA,0x30B87C1,0x30887C8,0x30A87CF,0x30B87D6
 
};
road_cmd.c
Show inline comments
 
@@ -121,32 +121,37 @@ static bool CheckAllowRemoveRoad(uint ti
 
uint GetRoadBitsByTile(TileIndex tile)
 
{
 
	uint32 r = GetTileTrackStatus(tile, TRANSPORT_ROAD);
 
	return (byte)(r | (r >> 8));
 
}
 

	
 
/* Delete a piece of road
 
 * p1 = piece type
 
/** Delete a piece of road.
 
 * @param x,y tile coordinates for road construction
 
 * @param p1 road piece flags
 
 * @param p2 unused
 
 */
 
int32 CmdRemoveRoad(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	// cost for removing inner/edge -roads
 
	static const uint16 road_remove_cost[2] = {50, 18};
 

	
 
	TileInfo ti;
 
	int32 cost;
 
	TileIndex tile;
 
	byte owner;
 
	Town *t;
 
	/*	true if the roadpiece was always removeable,
 
			false if it was a center piece. Affects town ratings drop
 
	*/
 
	/* true if the roadpiece was always removeable,
 
	 * false if it was a center piece. Affects town ratings drop */
 
	bool edge_road;
 
	byte pieces = (byte)p1;
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 

	
 
	/* Road pieces are max 4 bitset values (NE, NW, SE, SW) */
 
	if (pieces >> 4) return CMD_ERROR;
 

	
 
	FindLandscapeHeight(&ti, x, y);
 
	tile = ti.tile;
 

	
 
	// owner for railraod crossing is stored somewhere else
 
	// XXX - Fix this so for a given tiletype the owner of the type is in the same variable
 
	if (IsTileType(tile, MP_STREET) && (_map5[tile] & 0xF0) == 0x10) {
 
@@ -166,26 +171,25 @@ int32 CmdRemoveRoad(int x, int y, uint32
 
	if (ti.type != MP_TUNNELBRIDGE && !EnsureNoVehicle(tile))
 
		return CMD_ERROR;
 

	
 
	{
 
		bool b;
 
		_road_special_gettrackstatus = true;
 
		b = CheckAllowRemoveRoad(tile, p1, &edge_road);
 
		b = CheckAllowRemoveRoad(tile, pieces, &edge_road);
 
		_road_special_gettrackstatus = false;
 
		if (!b)
 
			return CMD_ERROR;
 
		if (!b) return CMD_ERROR;
 
	}
 

	
 
	if (ti.type == MP_TUNNELBRIDGE) {
 
		if (!EnsureNoVehicleZ(tile, TilePixelHeight(tile)))
 
			return CMD_ERROR;
 

	
 
		if ((ti.map5 & 0xE9) == 0xE8) {
 
			if (p1 & 10) goto return_error;
 
			if (pieces & 10) goto return_error;
 
		} else if ((ti.map5 & 0xE9) == 0xE9) {
 
			if (p1 & 5) goto return_error;
 
			if (pieces & 5) goto return_error;
 
		} else
 
			goto return_error;
 

	
 
		cost = _price.remove_road * 2;
 

	
 
		if (flags & DC_EXEC) {
 
@@ -199,13 +203,13 @@ int32 CmdRemoveRoad(int x, int y, uint32
 
		// check if you're allowed to remove the street owned by a town
 
		// removal allowance depends on difficulty setting
 
		if (!CheckforTownRating(tile, flags, t, ROAD_REMOVE)) return CMD_ERROR;
 

	
 
		// XXX - change cascading ifs to switch when doing rewrite
 
		if ((ti.map5 & 0xF0) == 0) { // normal road
 
			uint c = p1, t2;
 
			byte c = pieces, t2;
 

	
 
			if (ti.tileh != 0  && (ti.map5 == 5 || ti.map5 == 10)) {
 
				c |= (c & 0xC) >> 2;
 
				c |= (c & 0x3) << 2;
 
			}
 

	
 
@@ -232,16 +236,16 @@ int32 CmdRemoveRoad(int x, int y, uint32
 
			return cost;
 
		} else if ((ti.map5 & 0xE0) == 0) { // railroad crossing
 
			byte c;
 

	
 
			if (!(ti.map5 & 8)) {
 
				c = 2;
 
				if (p1 & 5) goto return_error;
 
				if (pieces & 5) goto return_error;
 
			} else {
 
				c = 1;
 
				if (p1 & 10) goto return_error;
 
				if (pieces & 10) goto return_error;
 
			}
 

	
 
			cost = _price.remove_road * 2;
 
			if (flags & DC_EXEC) {
 
				ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM);
 

	
 
@@ -337,36 +341,39 @@ static uint32 CheckRoadSlope(int tileh, 
 
			return (*pieces == (ROAD_NE|ROAD_SW) || *pieces == (ROAD_SE|ROAD_NW)) ? _price.terraform : CMD_ERROR;
 
		}
 
	}
 
	return CMD_ERROR;
 
}
 

	
 
/* Build a piece of road
 
 * p1 = piece flags
 
 * p2 = town which is building the road
 
/** Build a piece of road.
 
 * @param x,y tile coordinates for road construction
 
 * @param p1 road piece flags
 
 * @param p2 the town that is building the road (0 if not applicable)
 
 */
 

	
 
int32 CmdBuildRoad(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	TileInfo ti;
 
	int32 cost;
 
	byte pieces = (byte)p1, existing = 0;
 
	uint tile;
 
	TileIndex tile;
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 

	
 
	/* Road pieces are max 4 bitset values (NE, NW, SE, SW) and town can only be non-zero
 
	 * if a non-player is building the road */
 
	if ((pieces >> 4) || (_current_player < MAX_PLAYERS && p2 != 0) || !IsTownIndex(p2)) return CMD_ERROR;
 

	
 
	FindLandscapeHeight(&ti, x, y);
 
	tile = ti.tile;
 

	
 
	// allow building road under bridge
 
	if (ti.type != MP_TUNNELBRIDGE && !EnsureNoVehicle(tile))
 
		return CMD_ERROR;
 
	if (ti.type != MP_TUNNELBRIDGE && !EnsureNoVehicle(tile)) return CMD_ERROR;
 

	
 
	if (ti.type == MP_STREET) {
 
		if (!(ti.map5 & 0xF0)) {
 
			if ( ((pieces) & (byte)(ti.map5)) == (pieces))
 
			if ( (pieces & (byte)(ti.map5)) == (pieces))
 
				return_cmd_error(STR_1007_ALREADY_BUILT);
 
			existing = ti.map5;
 
		} else {
 
			if (!(ti.map5 & 0xE0) && pieces != ((ti.map5 & 8) ? 5 : 10))
 
				return_cmd_error(STR_1007_ALREADY_BUILT);
 
			goto do_clear;
 
@@ -430,18 +437,18 @@ int32 CmdBuildRoad(int x, int y, uint32 
 
				(ti.map5 & 0xC7) | 0x28 // map5
 
			);
 
		}
 
		return cost;
 
	} else {
 
do_clear:;
 
		if (DoCommandByTile(tile, 0, 0, flags & ~DC_EXEC, CMD_LANDSCAPE_CLEAR) == CMD_ERROR)
 
		if (CmdFailed(DoCommandByTile(tile, 0, 0, flags & ~DC_EXEC, CMD_LANDSCAPE_CLEAR)))
 
			return CMD_ERROR;
 
	}
 

	
 
	cost = CheckRoadSlope(ti.tileh, &pieces, existing);
 
	if (cost == CMD_ERROR) return_cmd_error(STR_1800_LAND_SLOPED_IN_WRONG_DIRECTION);
 
	if (CmdFailed(cost)) return_cmd_error(STR_1800_LAND_SLOPED_IN_WRONG_DIRECTION);
 

	
 
	if (cost && (!_patches.build_on_slopes || (!_patches.ainew_active && _is_ai_player)))
 
		return CMD_ERROR;
 

	
 
	if (!(ti.type == MP_STREET && (ti.map5 & 0xF0) == 0)) {
 
		cost += DoCommandByTile(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 
@@ -491,129 +498,136 @@ int32 DoConvertStreetRail(uint tile, uin
 
	}
 

	
 
	return _price.build_rail >> 1;
 
}
 

	
 

	
 
// Build a long piece of road.
 
// x,y = end tile
 
// p1 = start tile
 
// p2&1 = start tile starts in the 2nd half
 
// p2&2 = end tile starts in the 2nd half
 
// p2&4 = direction (0 = along x, 1=along y)
 
/** Build a long piece of road.
 
 * @param x,y end tile of drag
 
 * @param p1 start tile of drag
 
 * @param p2 various bitstuffed elements
 
 * - p2 = (bit 0) - start tile starts in the 2nd half of tile (p2 & 1)
 
 * - p2 = (bit 1) - end tile starts in the 2nd half of tile (p2 & 2)
 
 * - p2 = (bit 2) - direction: 0 = along x-axis, 1 = along y-axis (p2 & 4)
 
 */
 
int32 CmdBuildLongRoad(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	uint start_tile, end_tile, tile;
 
	int mode;
 
	int32 cost,ret;
 
	TileIndex start_tile, end_tile, tile;
 
	int32 cost, ret;
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 

	
 
	if (p1 > MapSize()) return CMD_ERROR;
 

	
 
	start_tile = p1;
 
	end_tile = TILE_FROM_XY(x, y);
 

	
 
	if (start_tile > end_tile || (start_tile == end_tile && (p2&1))) {
 
		uint t = start_tile; start_tile = end_tile; end_tile = t;
 
	/* Only drag in X or Y direction dictated by the direction variable */
 
	if (!HASBIT(p2, 2) && TileY(start_tile) != TileY(end_tile)) return CMD_ERROR; // x-axis
 
	if (HASBIT(p2, 2)  && TileX(start_tile) != TileX(end_tile)) return CMD_ERROR; // y-axis
 

	
 
	/* Swap start and ending tile, also the half-tile drag var (bit 0 and 1) */
 
	if (start_tile > end_tile || (start_tile == end_tile && HASBIT(p2, 0))) {
 
		TileIndex t = start_tile;
 
		start_tile = end_tile;
 
		end_tile = t;
 
		p2 ^= IS_INT_INSIDE(p2&3, 1, 3) ? 3 : 0;
 
	}
 

	
 
	cost = 0;
 
	tile = start_tile;
 
	// Start tile is the small number.
 
	for(;;) {
 
		mode = (p2&4) ? 5 : 10;
 

	
 
		if (tile == start_tile && (p2&1))
 
			mode &= (4+2);
 
		else if (tile == end_tile && !(p2&2))
 
			mode &= (1+8);
 
	for (;;) {
 
		uint bits = HASBIT(p2, 2) ? ROAD_SE | ROAD_NW : ROAD_SW | ROAD_NE;
 
		if (tile == end_tile && !HASBIT(p2, 1)) bits &= ROAD_NW | ROAD_NE;
 
		if (tile == start_tile && HASBIT(p2, 0)) bits &= ROAD_SE | ROAD_SW;
 

	
 
		ret = DoCommandByTile(tile, mode, 0, flags, CMD_BUILD_ROAD);
 
		if (ret == CMD_ERROR) {
 
			if (_error_message != STR_1007_ALREADY_BUILT)
 
				return CMD_ERROR;
 
		} else {
 
		ret = DoCommandByTile(tile, bits, 0, flags, CMD_BUILD_ROAD);
 
		if (CmdFailed(ret)) {
 
			if (_error_message != STR_1007_ALREADY_BUILT) return CMD_ERROR;
 
		} else
 
			cost += ret;
 
		}
 

	
 
		if (tile == end_tile)
 
			break;
 
		if (tile == end_tile) break;
 

	
 
		tile += (p2&4)?TILE_XY(0,1):TILE_XY(1,0);
 
		tile += HASBIT(p2, 2) ? TILE_XY(0, 1) : TILE_XY(1, 0);
 
	}
 

	
 
	// already built?
 
	if (cost == 0)
 
		return CMD_ERROR;
 

	
 
	return cost;
 
	return (cost == 0) ? CMD_ERROR : cost;
 
}
 

	
 
// Remove a long piece of road.
 
// x,y = end tile
 
// p1 = start tile
 
// p2&1 = start tile starts in the 2nd half
 
// p2&2 = end tile starts in the 2nd half
 
// p2&4 = direction (0 = along x, 1=along y)
 
/** Remove a long piece of road.
 
 * @param x,y end tile of drag
 
 * @param p1 start tile of drag
 
 * @param p2 various bitstuffed elements
 
 * - p2 = (bit 0) - start tile starts in the 2nd half of tile (p2 & 1)
 
 * - p2 = (bit 1) - end tile starts in the 2nd half of tile (p2 & 2)
 
 * - p2 = (bit 2) - direction: 0 = along x-axis, 1 = along y-axis (p2 & 4)
 
 */
 
int32 CmdRemoveLongRoad(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	uint start_tile, end_tile, tile;
 
	int32 cost,ret;
 
	TileIndex start_tile, end_tile, tile;
 
	int32 cost, ret;
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 

	
 
	if (p1 > MapSize()) return CMD_ERROR;
 

	
 
	start_tile = p1;
 
	end_tile = TILE_FROM_XY(x, y);
 

	
 
	if (start_tile > end_tile || (start_tile == end_tile && (p2&1))) {
 
		uint t = start_tile; start_tile = end_tile; end_tile = t;
 
	/* Only drag in X or Y direction dictated by the direction variable */
 
	if (!HASBIT(p2, 2) && TileY(start_tile) != TileY(end_tile)) return CMD_ERROR; // x-axis
 
	if (HASBIT(p2, 2)  && TileX(start_tile) != TileX(end_tile)) return CMD_ERROR; // y-axis
 

	
 
	/* Swap start and ending tile, also the half-tile drag var (bit 0 and 1) */
 
	if (start_tile > end_tile || (start_tile == end_tile && HASBIT(p2, 0))) {
 
		TileIndex t = start_tile;
 
		start_tile = end_tile;
 
		end_tile = t;
 
		p2 ^= IS_INT_INSIDE(p2&3, 1, 3) ? 3 : 0;
 
	}
 

	
 
	cost = 0;
 
	tile = start_tile;
 
	// Start tile is the small number.
 
	for(;;) {
 
		uint bits = (p2 & 4) ? ROAD_SE | ROAD_NW : ROAD_SW | ROAD_NE;
 
		if (tile == end_tile && !(p2&2)) bits &= ROAD_NW | ROAD_NE;
 
		if (tile == start_tile && (p2&1)) bits &= ROAD_SE | ROAD_SW;
 
	for (;;) {
 
		uint bits = HASBIT(p2, 2) ? ROAD_SE | ROAD_NW : ROAD_SW | ROAD_NE;
 
		if (tile == end_tile && !HASBIT(p2, 1)) bits &= ROAD_NW | ROAD_NE;
 
		if (tile == start_tile && HASBIT(p2, 0)) bits &= ROAD_SE | ROAD_SW;
 

	
 
		// try to remove the halves.
 
		if (bits) {
 
			ret = DoCommandByTile(tile, bits, 0, flags, CMD_REMOVE_ROAD);
 
			if (ret != CMD_ERROR)
 
				cost += ret;
 
			if (!CmdFailed(ret)) cost += ret;
 
		}
 

	
 
		if (tile == end_tile)
 
			break;
 
		if (tile == end_tile) break;
 

	
 
		tile += (p2&4)?TILE_XY(0,1):TILE_XY(1,0);
 
		tile += HASBIT(p2, 2) ? TILE_XY(0, 1) : TILE_XY(1, 0);
 
	}
 

	
 
	// already built?
 
	if (cost == 0)
 
		return CMD_ERROR;
 

	
 
	return cost;
 
	return (cost == 0) ? CMD_ERROR : cost;
 
}
 

	
 
/* Build a road depot
 
 * p1 - direction (0-3)
 
 * p2 - unused
 
/** Build a road depot.
 
 * @param x,y tile coordinates where the depot will be built
 
 * @param p1 depot direction (0 through 3), where 0 is NW, 1 is NE, etc.
 
 * @param p2 unused
 
 */
 

	
 
int32 CmdBuildRoadDepot(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	TileInfo ti;
 
	int32 cost;
 
	Depot *dep;
 
	uint tile;
 
	TileIndex tile;
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 

	
 
	if (p2 > 3) return CMD_ERROR; // check direction
 

	
 
	FindLandscapeHeight(&ti, x, y);
 

	
 
	tile = ti.tile;
 

	
 
	if (!EnsureNoVehicle(tile))
 
		return CMD_ERROR;
 
@@ -621,14 +635,13 @@ int32 CmdBuildRoadDepot(int x, int y, ui
 
	if (ti.tileh != 0) {
 
		if (!_patches.build_on_slopes || (ti.tileh & 0x10 || !((0x4C >> p1) & ti.tileh) ))
 
			return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
 
	}
 

	
 
	cost = DoCommandByTile(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 
	if (cost == CMD_ERROR)
 
		return CMD_ERROR;
 
	if (CmdFailed(cost)) return CMD_ERROR;
 

	
 
	dep = AllocateDepot();
 
	if (dep == NULL)
 
		return CMD_ERROR;
 

	
 
	if (flags & DC_EXEC) {
station_cmd.c
Show inline comments
 
@@ -1429,13 +1429,13 @@ void FindRoadStationSpot(bool truck_stat
 
		}
 
	}
 
}
 

	
 
/** Build a bus station
 
 * @param x,y coordinates to build bus station at
 
 * @param p1 direction the busstop exit is pointing towards
 
 * @param p1 busstop entrance direction (0 through 3), where 0 is NW, 1 is NE, etc.
 
 * @param p2 0 for Bus stops, 1 for truck stops
 
 */
 
int32 CmdBuildRoadStop(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	Station *st;
 
	RoadStop *road_stop;
 
@@ -1652,27 +1652,31 @@ static const byte * const _airport_map5_
 
	_airport_map5_tiles_town,						// City Airport (large)
 
	_airport_map5_tiles_heliport,				// Heliport
 
	_airport_map5_tiles_metropolitan,   // Metropolitain Airport (large)
 
	_airport_map5_tiles_international,	// International Airport (xlarge)
 
};
 

	
 
/* Place an Airport
 
 * p1 - airport type
 
 * p2 - unused
 
/** Place an Airport.
 
 * @param x,y tile coordinates where airport will be built
 
 * @param p1 airport type, @see airport.h
 
 * @param p2 unused
 
 */
 
int32 CmdBuildAirport(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	uint tile;
 
	TileIndex tile;
 
	Town *t;
 
	Station *st;
 
	int32 cost;
 
	int w,h;
 
	int w, h;
 
	bool airport_upgrade = true;
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 

	
 
	/* Check if a valid, buildable airport was chosen for construction */
 
	if (!HASBIT(GetValidAirports(), p1)) return CMD_ERROR;
 

	
 
	tile = TILE_FROM_XY(x,y);
 

	
 
	if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile))
 
		return CMD_ERROR;
 

	
 
	t = ClosestTownFromTile(tile, (uint)-1);
 
@@ -1691,23 +1695,21 @@ int32 CmdBuildAirport(int x, int y, uint
 
	}
 

	
 
	w = _airport_size_x[p1];
 
	h = _airport_size_y[p1];
 

	
 
	cost = CheckFlatLandBelow(tile, w, h, flags, 0, NULL);
 
	if (cost == CMD_ERROR)
 
		return CMD_ERROR;
 
	if (cost == CMD_ERROR) return CMD_ERROR;
 

	
 
	st = GetStationAround(tile, w, h, -1);
 
	if (st == CHECK_STATIONS_ERR)
 
		return CMD_ERROR;
 
	if (st == CHECK_STATIONS_ERR) return CMD_ERROR;
 

	
 
	/* Find a station close to us */
 
	if (st == NULL) {
 
		st = GetClosestStationFromTile(tile, 8, _current_player);
 
		if (st!=NULL && st->facilities) st = NULL;
 
		if (st != NULL && st->facilities) st = NULL;
 
	}
 

	
 
	if (st != NULL) {
 
		if (st->owner != OWNER_NONE && st->owner != _current_player)
 
			return_cmd_error(STR_3009_TOO_CLOSE_TO_ANOTHER_STATION);
 

	
 
@@ -1717,25 +1719,24 @@ int32 CmdBuildAirport(int x, int y, uint
 
		if (st->airport_tile != 0)
 
			return_cmd_error(STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT);
 
	} else {
 
		airport_upgrade = false;
 

	
 
		st = AllocateStation();
 
		if (st == NULL)
 
			return CMD_ERROR;
 
		if (st == NULL) return CMD_ERROR;
 

	
 
		st->town = t;
 

	
 
		if (_current_player < MAX_PLAYERS && flags&DC_EXEC)
 
			SETBIT(t->have_ratings, _current_player);
 

	
 
		st->sign.width_1 = 0;
 

	
 
		// if airport type equals Heliport then generate
 
		// type 5 name, which is heliport, otherwise airport names (1)
 
		if (!GenerateStationName(st, tile, p1 == AT_HELIPORT ? 5 : 1))
 
		if (!GenerateStationName(st, tile, (p1 == AT_HELIPORT) ? 5 : 1))
 
			return CMD_ERROR;
 

	
 
		if (flags & DC_EXEC)
 
			StationInitialize(st, tile);
 
	}
 

	
 
@@ -1825,16 +1826,17 @@ END_TILE_LOOP(tile_cur, w,h,tile)
 
		DeleteStationIfEmpty(st);
 
	}
 

	
 
	return cost;
 
}
 

	
 
/* Build a buoy
 
 * p1,p2 unused
 
/** Build a buoy.
 
 * @param x,y tile coordinates of bouy construction
 
 * @param p1 unused
 
 * @param p2 unused
 
 */
 

	
 
int32 CmdBuildBuoy(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	TileInfo ti;
 
	Station *st;
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 
@@ -1842,20 +1844,18 @@ int32 CmdBuildBuoy(int x, int y, uint32 
 
	FindLandscapeHeight(&ti, x, y);
 

	
 
	if (ti.type != MP_WATER || ti.tileh != 0 || ti.map5 != 0 || ti.tile == 0)
 
		return_cmd_error(STR_304B_SITE_UNSUITABLE);
 

	
 
	st = AllocateStation();
 
	if (st == NULL)
 
		return CMD_ERROR;
 
	if (st == NULL) return CMD_ERROR;
 

	
 
	st->town = ClosestTownFromTile(ti.tile, (uint)-1);
 
	st->sign.width_1 = 0;
 

	
 
	if (!GenerateStationName(st, ti.tile, 4))
 
		return CMD_ERROR;
 
	if (!GenerateStationName(st, ti.tile, 4)) return CMD_ERROR;
 

	
 
	if (flags & DC_EXEC) {
 
		StationInitialize(st, ti.tile);
 
		st->dock_tile = ti.tile;
 
		st->facilities |= FACIL_DOCK;
 
		/* Buoys are marked in the Station struct by this flag. Yes, it is this
 
@@ -1943,93 +1943,88 @@ static const TileIndexDiffC _dock_tileof
 
	{ 0,  0},
 
	{ 0, -1}
 
};
 
static const byte _dock_w_chk[4] = { 2,1,2,1 };
 
static const byte _dock_h_chk[4] = { 1,2,1,2 };
 

	
 
/** Build a dock/haven.
 
 * @param x,y tile coordinates where dock will be built
 
 * @param p1 unused
 
 * @param p2 unused
 
 */
 
int32 CmdBuildDock(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	TileInfo ti;
 
	int direction;
 
	int32 cost;
 
	uint tile, tile_cur;
 
	TileIndex tile, tile_cur;
 
	Station *st;
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 

	
 
	FindLandscapeHeight(&ti, x, y);
 

	
 
	if ((direction=0,ti.tileh) != 3 &&
 
			(direction++,ti.tileh) != 9 &&
 
			(direction++,ti.tileh) != 12 &&
 
			(direction++,ti.tileh) != 6)
 
		return_cmd_error(STR_304B_SITE_UNSUITABLE);
 

	
 
	if (!EnsureNoVehicle(ti.tile))
 
		return CMD_ERROR;
 
	if (!EnsureNoVehicle(ti.tile)) return CMD_ERROR;
 

	
 
	cost = DoCommandByTile(ti.tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 
	if (cost == CMD_ERROR)
 
		return CMD_ERROR;
 
	if (CmdFailed(cost)) return CMD_ERROR;
 

	
 
	tile_cur = (tile=ti.tile) + TileOffsByDir(direction);
 

	
 
	if (!EnsureNoVehicle(tile_cur))
 
		return CMD_ERROR;
 
	if (!EnsureNoVehicle(tile_cur)) return CMD_ERROR;
 

	
 
	FindLandscapeHeightByTile(&ti, tile_cur);
 
	if (ti.tileh != 0 || ti.type != MP_WATER)
 
		return_cmd_error(STR_304B_SITE_UNSUITABLE);
 
	if (ti.tileh != 0 || ti.type != MP_WATER) return_cmd_error(STR_304B_SITE_UNSUITABLE);
 

	
 
	cost = DoCommandByTile(tile_cur, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 
	if (cost == CMD_ERROR)
 
		return CMD_ERROR;
 
	if (CmdFailed(cost)) return CMD_ERROR;
 

	
 
	tile_cur = tile_cur + TileOffsByDir(direction);
 
	FindLandscapeHeightByTile(&ti, tile_cur);
 
	if (ti.tileh != 0 || ti.type != MP_WATER)
 
		return_cmd_error(STR_304B_SITE_UNSUITABLE);
 

	
 
	/* middle */
 
	st = GetStationAround(
 
		tile + ToTileIndexDiff(_dock_tileoffs_chkaround[direction]),
 
		_dock_w_chk[direction], _dock_h_chk[direction], -1);
 
	if (st == CHECK_STATIONS_ERR)
 
		return CMD_ERROR;
 
	if (st == CHECK_STATIONS_ERR) return CMD_ERROR;
 

	
 
	/* Find a station close to us */
 
	if (st == NULL) {
 
		st = GetClosestStationFromTile(tile, 8, _current_player);
 
		if (st!=NULL && st->facilities) st = NULL;
 
	}
 

	
 
	if (st != NULL) {
 
		if (st->owner != OWNER_NONE && st->owner != _current_player)
 
			return_cmd_error(STR_3009_TOO_CLOSE_TO_ANOTHER_STATION);
 

	
 
		if (!CheckStationSpreadOut(st, tile, 1, 1))
 
			return CMD_ERROR;
 

	
 
		if (st->dock_tile != 0)
 
			return_cmd_error(STR_304C_TOO_CLOSE_TO_ANOTHER_DOCK);
 
		if (!CheckStationSpreadOut(st, tile, 1, 1)) return CMD_ERROR;
 

	
 
		if (st->dock_tile != 0) return_cmd_error(STR_304C_TOO_CLOSE_TO_ANOTHER_DOCK);
 
	} else {
 
		Town *t;
 

	
 
		st = AllocateStation();
 
		if (st == NULL)
 
			return CMD_ERROR;
 
		if (st == NULL) return CMD_ERROR;
 

	
 
		st->town = t = ClosestTownFromTile(tile, (uint)-1);
 

	
 
		if (_current_player < MAX_PLAYERS && flags&DC_EXEC)
 
			SETBIT(t->have_ratings, _current_player);
 

	
 
		st->sign.width_1 = 0;
 

	
 
		if (!GenerateStationName(st, tile, 3))
 
			return CMD_ERROR;
 
		if (!GenerateStationName(st, tile, 3)) return CMD_ERROR;
 

	
 
		if (flags & DC_EXEC)
 
			StationInitialize(st, tile);
 
	}
 

	
 
	if (flags & DC_EXEC) {
table/tree_land.h
Show inline comments
 
#ifndef TREE_LAND_H
 
#define TREE_LAND_H
 

	
 
static const SpriteID _tree_sprites_1[4] = {
 
	0x118D,
 
	0x11A0,
 
	0x11B3,
 
	0x11C6,
 
};
 

	
 
static const byte _tree_base_by_landscape[4] = {0, 12, 20, 32};
 
static const byte _tree_count_by_landscape[4] = {12, 8, 12, 9};
 

	
 
static const byte _tree_layout_xy[4][8] = {
 
{9, 3, 1, 8, 0, 0, 8, 9},
 
{4, 4, 9, 1, 6, 9, 0, 9},
 
{9, 1, 0, 9, 6, 6, 3, 0},
 
{3, 9, 8, 2, 9, 9, 1, 5},
 
};
 
@@ -208,6 +214,9 @@ static const PalSpriteID _tree_layout_sp
 
	{     0x6f3,      0x701,      0x6fa,      0x716}, /* 27 */
 
	{     0x716,      0x70f,      0x716,      0x6fa}, /* 28 */
 
	{     0x716,      0x6f3,      0x716,      0x708}, /* 29 */
 
	{     0x716,      0x716,      0x6f3,      0x6ec}, /* 30 */
 
	{     0x716,      0x701,      0x6fa,      0x716}, /* 31 */
 
};
 

	
 
#endif /* TREE_LAND_H */
 

	
town.h
Show inline comments
 
@@ -154,12 +154,17 @@ static inline Town *GetTown(uint index)
 
 */
 
static inline uint16 GetTownPoolSize(void)
 
{
 
	return _town_pool.total_items;
 
}
 

	
 
static inline bool IsTownIndex(uint index)
 
{
 
	return index < GetTownPoolSize();
 
}
 

	
 
#define FOR_ALL_TOWNS_FROM(t, start) for (t = GetTown(start); t != NULL; t = (t->index + 1 < GetTownPoolSize()) ? GetTown(t->index + 1) : NULL)
 
#define FOR_ALL_TOWNS(t) FOR_ALL_TOWNS_FROM(t, 0)
 

	
 
VARDEF uint _total_towns; // For the AI: the amount of towns active
 

	
 
VARDEF bool _town_sort_dirty;
train_cmd.c
Show inline comments
 
@@ -514,41 +514,43 @@ void AddRearEngineToMultiheadedTrain(Veh
 
	u->value = v->value;
 
	u->type = VEH_Train;
 
	u->cur_image = 0xAC2;
 
	VehiclePositionChanged(u);
 
}
 

	
 
/* Build a railroad vehicle
 
 * p1 = vehicle type id
 
/** Build a railroad vehicle.
 
 * @param x,y tile coordinates (depot) where rail-vehicle is built
 
 * @param p1 engine type id
 
 * @param p2 unused
 
 */
 

	
 
int32 CmdBuildRailVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	const RailVehicleInfo *rvi;
 
	int value,dir;
 
	Vehicle *v, *u;
 
	UnitID unit_num;
 
	Engine *e;
 
	TileIndex tile = TILE_FROM_XY(x,y);
 

	
 
	/* Check if the engine-type is valid (for the player) */
 
	if (!IsEngineBuildable(p1, VEH_Train)) return CMD_ERROR;
 

	
 
	/* Check if the train is actually being built in a depot belonging
 
	 * to the player. Doesn't matter if only the cost is queried */
 
	if (!(flags & DC_QUERY_COST)) {
 
		if (!IsTileDepotType(tile, TRANSPORT_RAIL)) return CMD_ERROR;
 
		if (_map_owner[tile] != _current_player) return CMD_ERROR;
 
	}
 

	
 
	_cmd_build_rail_veh_var1 = 0;
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
 

	
 
	rvi = RailVehInfo(p1);
 

	
 
	if (rvi->flags & RVI_WAGON) {
 
		return CmdBuildRailWagon(p1, tile, flags);
 
	}
 
	if (rvi->flags & RVI_WAGON) return CmdBuildRailWagon(p1, tile, flags);
 

	
 
	value = EstimateTrainCost(rvi);
 

	
 
	if (!(flags & DC_QUERY_COST)) {
 
		v = AllocateVehicle();
 
		if (v == NULL || IsOrderPoolFull())
 
@@ -691,16 +693,18 @@ static Vehicle *FindGoodVehiclePos(const
 
		}
 
	}
 

	
 
	return NULL;
 
}
 

	
 
/* p1 & 0xffff = source vehicle index
 
 * p1 & 0xffff0000 = what wagon to put the wagon AFTER,
 
 *   0xffff0000 to make a new line
 
 * p2 & 1 = move all vehicles following the vehicle..
 
/** Move a rail vehicle around inside the depot.
 
 * @param x,y unused
 
 * @param p1 various bitstuffed elements
 
 * - p1 (bit  0 - 15) source vehicle index (p1 & 0xFFFF)
 
 * - p1 (bit 16 - 31) what wagon to put the source wagon AFTER (p1 & 0xFFFF0000) XXX - 0xFFFF0000 to make a new line
 
 * @param p2 (bit 0) move all vehicles following the source vehicle
 
 */
 
int32 CmdMoveRailVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	Vehicle *src, *dst, *src_head, *dst_head;
 
	bool is_loco;
 

	
 
@@ -718,14 +722,13 @@ int32 CmdMoveRailVehicle(int x, int y, u
 
		if (!is_loco) dst = FindGoodVehiclePos(src);
 
	} else {
 
		dst = GetVehicle((int32)p1 >> 16);
 
	}
 

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

	
 
	/* the player must be the owner */
 
	if (!CheckOwnership(src->owner) || (dst!=NULL && !CheckOwnership(dst->owner)))
 
		return CMD_ERROR;
 

	
 
	/* locate the head of the two chains */
 
@@ -738,22 +741,20 @@ int32 CmdMoveRailVehicle(int x, int y, u
 
		Vehicle *u;
 

	
 
		for (u = src_head; u != NULL; u = u->next) u->first = NULL;
 
		for (u = dst_head; u != NULL; u = u->next) u->first = NULL;
 
	}
 

	
 
	/* check if all vehicles in the source train are stopped */
 
	if (CheckTrainStoppedInDepot(src_head) < 0)
 
		return CMD_ERROR;
 
	/* check if all vehicles in the source train are stopped inside a depot */
 
	if (CheckTrainStoppedInDepot(src_head) < 0) return CMD_ERROR;
 

	
 
	/* check if all the vehicles in the dest train are stopped,
 
	 * and that the length of the dest train is no longer than XXX vehicles */
 
	if (dst_head != NULL) {
 
		int num = CheckTrainStoppedInDepot(dst_head);
 
		if (num < 0)
 
			return CMD_ERROR;
 
		if (num < 0) return CMD_ERROR;
 

	
 
		if (num > (_patches.mammoth_trains ? 100 : 9) && dst_head->subtype == TS_Front_Engine )
 
			return_cmd_error(STR_8819_TRAIN_TOO_LONG);
 

	
 
		// if it's a multiheaded vehicle we're dragging to, drag to the vehicle before..
 
		while (IS_CUSTOM_SECONDHEAD_SPRITE(dst->spritenum) || (
 
@@ -765,14 +766,13 @@ int32 CmdMoveRailVehicle(int x, int y, u
 
		}
 

	
 
		assert(dst_head->tile == src_head->tile);
 
	}
 

	
 
	// when moving all wagons, we can't have the same src_head and dst_head
 
	if (p2 & 1 && src_head == dst_head)
 
		return 0;
 
	if (HASBIT(p2, 0) && src_head == dst_head) return 0;
 

	
 
	// moving a loco to a new line?, then we need to assign a unitnumber.
 
	if (dst == NULL && src->subtype != TS_Front_Engine && is_loco) {
 
		UnitID unit_num = GetFreeUnitNumber(VEH_Train);
 
		if (unit_num > _patches.max_trains)
 
			return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
 
@@ -781,13 +781,13 @@ int32 CmdMoveRailVehicle(int x, int y, u
 
			src->unitnumber = unit_num;
 
	}
 

	
 

	
 
	/* do it? */
 
	if (flags & DC_EXEC) {
 
		if (p2 & 1) {
 
		if (HASBIT(p2, 0)) {
 
			// unlink ALL wagons
 
			if (src != src_head) {
 
				Vehicle *v = src_head;
 
				while (v->next != src) v=v->next;
 
				v->next = NULL;
 
			}
 
@@ -856,23 +856,26 @@ int32 CmdMoveRailVehicle(int x, int y, u
 
		RebuildVehicleLists();
 
	}
 

	
 
	return 0;
 
}
 

	
 
/* p1 = train to start / stop */
 
/** Start/Stop a train.
 
 * @param x,y unused
 
 * @param p1 train to start/stop
 
 * @param p2 unused
 
 */
 
int32 CmdStartStopTrain(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	Vehicle *v;
 

	
 
	if (!IsVehicleIndex(p1)) return CMD_ERROR;
 

	
 
	v = GetVehicle(p1);
 

	
 
	if (v->type != VEH_Train || !CheckOwnership(v->owner))
 
		return CMD_ERROR;
 
	if (v->type != VEH_Train || !CheckOwnership(v->owner)) return CMD_ERROR;
 

	
 
	if (flags & DC_EXEC) {
 
		v->u.rail.days_since_order_progr = 0;
 
		v->vehstatus ^= VS_STOPPED;
 
		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
 
		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
 
@@ -898,41 +901,39 @@ static Vehicle *GetRearEngine(const Vehi
 
			if (en_count == 0) return (Vehicle *)u;
 
		}
 
	}
 
	return NULL;
 
}
 

	
 
/**
 
 * Sell a (single) train wagon/engine.
 
/** Sell a (single) train wagon/engine.
 
 * @param x,y unused
 
 * @param p1 the wagon/engine index
 
 * @param p2 the selling mode
 
 * - 0: only sell the single dragged wagon/engine (and any belonging rear-engines)
 
 * - 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
 
 * - 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
 
 * - 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
 
 */
 
int32 CmdSellRailWagon(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	Vehicle *v, *tmp, *first;
 
	int32 cost = 0;
 

	
 
	if (!IsVehicleIndex(p1) || p2 > 2) return CMD_ERROR;
 

	
 
	v = GetVehicle(p1);
 

	
 
	if (v->type != VEH_Train || !CheckOwnership(v->owner))
 
		return CMD_ERROR;
 
	if (v->type != VEH_Train || !CheckOwnership(v->owner)) return CMD_ERROR;
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
 

	
 
	first = GetFirstVehicleInChain(v);
 

	
 
	// make sure the vehicle is stopped in the depot
 
	if (CheckTrainStoppedInDepot(first) < 0)
 
		return CMD_ERROR;
 
	if (CheckTrainStoppedInDepot(first) < 0) return CMD_ERROR;
 

	
 
	if ((flags & DC_EXEC) && v == first && first->subtype == TS_Front_Engine) {
 
		DeleteWindowById(WC_VEHICLE_VIEW, first->index);
 
		InvalidateWindow(WC_REPLACE_VEHICLE, VEH_Train);
 
		InvalidateWindow(WC_VEHICLE_DEPOT, first->tile);
 
		RebuildVehicleLists();
 
@@ -1223,31 +1224,33 @@ static void ReverseTrainDirection(Vehicl
 
	if (IsTileDepotType(v->tile, TRANSPORT_RAIL))
 
		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
 

	
 
	CLRBIT(v->u.rail.flags, VRF_REVERSING);
 
}
 

	
 
/* p1 = vehicle */
 
int32 CmdReverseTrainDirection(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 
/** Reverse train.
 
 * @param x,y unused
 
 * @param p1 train to reverse
 
 * @param p2 unused
 
 */
 
 int32 CmdReverseTrainDirection(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	Vehicle *v;
 

	
 
	if (!IsVehicleIndex(p1)) return CMD_ERROR;
 

	
 
	v = GetVehicle(p1);
 

	
 
	if (v->type != VEH_Train || !CheckOwnership(v->owner))
 
		return CMD_ERROR;
 
	if (v->type != VEH_Train || !CheckOwnership(v->owner)) return CMD_ERROR;
 

	
 
	_error_message = STR_EMPTY;
 

	
 
//	if (v->u.rail.track & 0x80 || IsTileDepotType(v->tile, TRANSPORT_RAIL))
 
//		return CMD_ERROR;
 

	
 
	if (v->u.rail.crash_anim_pos != 0 || v->breakdown_ctr != 0)
 
		return CMD_ERROR;
 
	if (v->u.rail.crash_anim_pos != 0 || v->breakdown_ctr != 0) return CMD_ERROR;
 

	
 
	if (flags & DC_EXEC) {
 
		if (_patches.realistic_acceleration && v->cur_speed != 0) {
 
			TOGGLEBIT(v->u.rail.flags, VRF_REVERSING);
 
		} else {
 
			v->cur_speed = 0;
 
@@ -1255,22 +1258,26 @@ int32 CmdReverseTrainDirection(int x, in
 
			ReverseTrainDirection(v);
 
		}
 
	}
 
	return 0;
 
}
 

	
 
/** Force a train through a red signal
 
 * @param x,y unused
 
 * @param p1 train to ignore the red signal
 
 * @param p2 unused
 
 */
 
int32 CmdForceTrainProceed(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	Vehicle *v;
 

	
 
	if (!IsVehicleIndex(p1)) return CMD_ERROR;
 

	
 
	v = GetVehicle(p1);
 

	
 
	if (v->type != VEH_Train || !CheckOwnership(v->owner))
 
		return CMD_ERROR;
 
	if (v->type != VEH_Train || !CheckOwnership(v->owner)) return CMD_ERROR;
 

	
 
	if (flags & DC_EXEC)
 
		v->u.rail.force_proceed = 0x50;
 

	
 
	return 0;
 
}
 
@@ -1418,26 +1425,29 @@ static TrainFindDepotData FindClosestTra
 
		}
 
	}
 

	
 
	return tfdd;
 
}
 

	
 
/** Send a train to a depot
 
 * @param x,y unused
 
 * @param p1 train to send to the depot
 
 * @param p2 unused
 
 */
 
int32 CmdTrainGotoDepot(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	Vehicle *v;
 
	TrainFindDepotData tfdd;
 

	
 
	if (!IsVehicleIndex(p1)) return CMD_ERROR;
 

	
 
	v = GetVehicle(p1);
 

	
 
	if (v->type != VEH_Train || !CheckOwnership(v->owner))
 
		return CMD_ERROR;
 

	
 
	if (v->vehstatus & VS_CRASHED)
 
		return CMD_ERROR;
 
	if (v->type != VEH_Train || !CheckOwnership(v->owner)) return CMD_ERROR;
 

	
 
	if (v->vehstatus & VS_CRASHED) return CMD_ERROR;
 

	
 
	if (v->current_order.type == OT_GOTO_DEPOT) {
 
		if (flags & DC_EXEC) {
 
			if (HASBIT(v->current_order.flags, OFB_PART_OF_ORDERS)) {
 
				v->u.rail.days_since_order_progr = 0;
 
				v->cur_order_index++;
tree_cmd.c
Show inline comments
 
#include "stdafx.h"
 
#include "ttd.h"
 
#include "table/strings.h"
 
#include "table/tree_land.h"
 
#include "map.h"
 
#include "tile.h"
 
#include "viewport.h"
 
#include "command.h"
 
#include "town.h"
 
#include "sound.h"
 
@@ -139,26 +140,28 @@ void GenerateTrees(void)
 
	i = _opt.landscape == LT_HILLY ? 15 : 6;
 
	do {
 
		PlaceTreesRandomly();
 
	} while (--i);
 
}
 

	
 
/* Plant a tree
 
 * p1 = tree type, -1 means random.
 
 * p2 = end tile
 
/** Plant a tree.
 
 * @param x,y start tile of area-drag of tree plantation
 
 * @param p1 tree type, -1 means random.
 
 * @param p2 end tile of area-drag
 
 */
 

	
 
int32 CmdPlantTree(int ex, int ey, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	int32 cost;
 
	int sx;
 
	int sy;
 
	int x;
 
	int y;
 

	
 
	if (p2 >= MapSize()) return CMD_ERROR;
 
	if (p2 > MapSize()) return CMD_ERROR;
 
	/* Check the tree type. It can be random or some valid value within the current climate */
 
	if (p1 != (uint)-1 && p1 - _tree_base_by_landscape[_opt.landscape] >= _tree_count_by_landscape[_opt.landscape]) return CMD_ERROR;
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_OTHER);
 

	
 
	// make sure sx,sy are smaller than ex,ey
 
	sx = TileX(p2) * 16;
 
	sy = TileY(p2) * 16;
 
@@ -251,25 +254,20 @@ int32 CmdPlantTree(int ex, int ey, uint3
 
					_error_message = STR_2804_SITE_UNSUITABLE;
 
					break;
 
			}
 
		}
 
	}
 

	
 
	if (cost == 0) return CMD_ERROR;
 
	return cost;
 
	return (cost == 0) ? CMD_ERROR : cost;
 
}
 

	
 
typedef struct TreeListEnt {
 
	uint32 image;
 
	byte x,y;
 
} TreeListEnt;
 

	
 

	
 
#include "table/tree_land.h"
 

	
 

	
 
static void DrawTile_Trees(TileInfo *ti)
 
{
 
	uint16 m2;
 
	const uint32 *s;
 
	const byte *d;
 
	byte z;
tunnelbridge_cmd.c
Show inline comments
 
@@ -530,13 +530,13 @@ static int32 DoBuildTunnel(int x, int y,
 

	
 
	return cost + _price.build_tunnel;
 
}
 

	
 
/** Build Tunnel.
 
 * @param x,y start tile coord of tunnel
 
 * @param p1 railtype
 
 * @param p1 railtype, 0x200 for road tunnel
 
 * @param p2 unused (XXX - ptr to uint that recieves end tile; wtf?????)
 
 */
 
int32 CmdBuildTunnel(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	TileInfo ti, tiorg;
 
	int direction;
 
@@ -544,13 +544,13 @@ int32 CmdBuildTunnel(int x, int y, uint3
 
	static const int8 _build_tunnel_coord_mod[4+1] = { -16, 0, 16, 0, -16 };
 
	static const byte _build_tunnel_tileh[4] = {3, 9, 12, 6};
 
	TileIndex excavated_tile;
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 

	
 
	if (!ValParamRailtype(p1)) return CMD_ERROR;
 
	if (p1 != 0x200 && !ValParamRailtype(p1)) return CMD_ERROR;
 

	
 
	_build_tunnel_railtype = (byte)(p1 & 0xFF);
 
	_build_tunnel_bh = (byte)(p1 >> 8);
 

	
 
	_build_tunnel_endtile = 0;
 
	excavated_tile = 0;
water_cmd.c
Show inline comments
 
@@ -19,48 +19,47 @@ static bool IsClearWaterTile(uint tile)
 
{
 
	TileInfo ti;
 
	FindLandscapeHeightByTile(&ti, tile);
 
	return (ti.type == MP_WATER && ti.tileh == 0 && ti.map5 == 0);
 
}
 

	
 
/* Build a ship depot
 
 * p1 - direction
 
/** Build a ship depot.
 
 * @param x,y tile coordinates where ship depot is built
 
 * @param p1 depot direction (0 through 3), where 0 is NW, 1 is NE, etc.
 
 * @param p2 unused
 
 */
 

	
 
int32 CmdBuildShipDepot(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	uint tile, tile2;
 
	TileIndex tile, tile2;
 

	
 
	int32 cost, ret;
 
	Depot *depot;
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 

	
 
	if (p1 > 3) return CMD_ERROR;
 

	
 
	tile = TILE_FROM_XY(x,y);
 
	if (!EnsureNoVehicle(tile))
 
		return CMD_ERROR;
 
	if (!EnsureNoVehicle(tile)) return CMD_ERROR;
 

	
 
	tile2 = tile + (p1 ? TILE_XY(0,1) : TILE_XY(1,0));
 
	if (!EnsureNoVehicle(tile2))
 
		return CMD_ERROR;
 
	if (!EnsureNoVehicle(tile2)) return CMD_ERROR;
 

	
 
	if (!IsClearWaterTile(tile) || !IsClearWaterTile(tile2))
 
		return_cmd_error(STR_3801_MUST_BE_BUILT_ON_WATER);
 

	
 
	ret = DoCommandByTile(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 
	if (ret == CMD_ERROR) return CMD_ERROR;
 
	if (CmdFailed(ret)) return CMD_ERROR;
 
	ret = DoCommandByTile(tile2, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 
	if (ret == CMD_ERROR)
 
		return CMD_ERROR;
 
	if (CmdFailed(ret)) return CMD_ERROR;
 

	
 
	// pretend that we're not making land from the water even though we actually are.
 
	cost = 0;
 

	
 
	depot = AllocateDepot();
 
	if (depot == NULL)
 
		return CMD_ERROR;
 
	if (depot == NULL) return CMD_ERROR;
 

	
 
	if (flags & DC_EXEC) {
 
		depot->xy = tile;
 
		_last_built_ship_depot_tile = tile;
 
		depot->town_index = ClosestTownFromTile(tile, (uint)-1)->index;
 

	
0 comments (0 inline, 0 general)