Changeset - r4849:41dc3967353a
[Not reviewed]
master
0 8 0
Darkvater - 18 years ago 2006-10-14 22:22:48
darkvater@openttd.org
(svn r6775) -Codechange: Use some more proper types, especially Owner and PlayerID as
these are used intermixed often.
8 files changed with 15 insertions and 16 deletions:
0 comments (0 inline, 0 general)
functions.h
Show inline comments
 
@@ -7,97 +7,97 @@ void DoClearSquare(TileIndex tile);
 
void RunTileLoop(void);
 

	
 
uint GetPartialZ(int x, int y, Slope corners);
 
uint GetSlopeZ(int x, int y);
 
uint32 GetTileTrackStatus(TileIndex tile, TransportType mode);
 
void GetAcceptedCargo(TileIndex tile, AcceptedCargo ac);
 
void ChangeTileOwner(TileIndex tile, byte old_player, byte new_player);
 
void AnimateTile(TileIndex tile);
 
void ClickTile(TileIndex tile);
 
void GetTileDesc(TileIndex tile, TileDesc *td);
 
void UpdateTownMaxPass(Town *t);
 

	
 
bool IsValidTile(TileIndex tile);
 

	
 
static inline Point RemapCoords(int x, int y, int z)
 
{
 
#if !defined(NEW_ROTATION)
 
	Point pt;
 
	pt.x = (y - x) * 2;
 
	pt.y = y + x - z;
 
#else
 
	Point pt;
 
	pt.x = (x + y) * 2;
 
	pt.y = x - y - z;
 
#endif
 
	return pt;
 
}
 

	
 
static inline Point RemapCoords2(int x, int y)
 
{
 
	return RemapCoords(x, y, GetSlopeZ(x, y));
 
}
 

	
 

	
 
/* clear_land.c */
 
void DrawHillyLandTile(const TileInfo *ti);
 
void DrawClearLandTile(const TileInfo *ti, byte set);
 
void DrawClearLandFence(const TileInfo *ti);
 
void TileLoopClearHelper(TileIndex tile);
 

	
 
/* water_land.c */
 
void DrawShipDepotSprite(int x, int y, int image);
 
void TileLoop_Water(TileIndex tile);
 

	
 
/* players.c */
 
bool CheckPlayerHasMoney(int32 cost);
 
void SubtractMoneyFromPlayer(int32 cost);
 
void SubtractMoneyFromPlayerFract(PlayerID player, int32 cost);
 
bool CheckOwnership(PlayerID owner);
 
bool CheckOwnership(Owner owner);
 
bool CheckTileOwnership(TileIndex tile);
 
StringID GetPlayerNameString(PlayerID player, uint index);
 

	
 
/* standard */
 
void ShowInfo(const char *str);
 
void CDECL ShowInfoF(const char *str, ...);
 
void NORETURN CDECL error(const char *str, ...);
 

	
 
/* openttd.c */
 

	
 
/**************
 
 * Warning: DO NOT enable this unless you understand what it does
 
 *
 
 * If enabled, in a network game all randoms will be dumped to the
 
 *  stdout if the first client joins (or if you are a client). This
 
 *  is to help finding desync problems.
 
 *
 
 * Warning: DO NOT enable this unless you understand what it does
 
 **************/
 

	
 
//#define RANDOM_DEBUG
 

	
 

	
 
// Enable this to produce higher quality random numbers.
 
// Doesn't work with network yet.
 
//#define MERSENNE_TWISTER
 

	
 
// Mersenne twister functions
 
void SeedMT(uint32 seed);
 
uint32 RandomMT(void);
 

	
 

	
 
#ifdef MERSENNE_TWISTER
 
	static inline uint32 Random(void) { return RandomMT(); }
 
	uint RandomRange(uint max);
 
#else
 

	
 
#ifdef RANDOM_DEBUG
 
	#define Random() DoRandom(__LINE__, __FILE__)
 
	uint32 DoRandom(int line, const char *file);
 
	#define RandomRange(max) DoRandomRange(max, __LINE__, __FILE__)
 
	uint DoRandomRange(uint max, int line, const char *file);
 
#else
 
	uint32 Random(void);
 
	uint RandomRange(uint max);
 
#endif
 
#endif // MERSENNE_TWISTER
 

	
map.h
Show inline comments
 
@@ -22,102 +22,103 @@ typedef struct Tile {
 
	uint16 m2;
 
	byte m3;
 
	byte m4;
 
	byte m5;
 
	byte extra;
 
} Tile;
 

	
 
extern Tile* _m;
 

	
 
void AllocateMap(uint size_x, uint size_y);
 

	
 
// binary logarithm of the map size, try to avoid using this one
 
static inline uint MapLogX(void)  { return _map_log_x; }
 
/* The size of the map */
 
static inline uint MapSizeX(void) { return _map_size_x; }
 
static inline uint MapSizeY(void) { return _map_size_y; }
 
/* The maximum coordinates */
 
static inline uint MapMaxX(void) { return _map_size_x - 1; }
 
static inline uint MapMaxY(void) { return _map_size_y - 1; }
 
/* The number of tiles in the map */
 
static inline uint MapSize(void) { return _map_size; }
 

	
 
// Scale a number relative to the map size
 
uint ScaleByMapSize(uint); // Scale relative to the number of tiles
 
uint ScaleByMapSize1D(uint); // Scale relative to the circumference of the map
 

	
 
typedef uint32 TileIndex;
 
typedef int32 TileIndexDiff;
 

	
 
static inline TileIndex TileXY(uint x, uint y)
 
{
 
	return (y * MapSizeX()) + x;
 
}
 

	
 
static inline TileIndexDiff TileDiffXY(int x, int y)
 
{
 
	// Multiplication gives much better optimization on MSVC than shifting.
 
	// 0 << shift isn't optimized to 0 properly.
 
	// Typically x and y are constants, and then this doesn't result
 
	// in any actual multiplication in the assembly code..
 
	return (y * MapSizeX()) + x;
 
}
 

	
 
static inline TileIndex TileVirtXY(uint x, uint y)
 
{
 
	return (y >> 4 << MapLogX()) + (x >> 4);
 
}
 

	
 
typedef enum Owner {
 
typedef byte Owner;
 
enum Owners {
 
	OWNER_TOWN      = 0x0F, // a town owns the tile
 
	OWNER_NONE      = 0x10, // nobody owns the tile
 
	OWNER_WATER     = 0x11, // "water" owns the tile
 
	OWNER_END       = 0x12,
 
} Owner;
 
};
 

	
 
enum {
 
	INVALID_TILE = (TileIndex)-1
 
};
 

	
 
enum {
 
	TILE_SIZE   = 16,   /* Tiles are 16x16 "units" in size */
 
	TILE_PIXELS = 32,   /* a tile is 32x32 pixels */
 
	TILE_HEIGHT =  8,   /* The standard height-difference between tiles on two levels is 8 (z-diff 8) */
 
};
 

	
 

	
 
static inline uint TileX(TileIndex tile)
 
{
 
	return tile & MapMaxX();
 
}
 

	
 
static inline uint TileY(TileIndex tile)
 
{
 
	return tile >> MapLogX();
 
}
 

	
 

	
 
typedef struct TileIndexDiffC {
 
	int16 x;
 
	int16 y;
 
} TileIndexDiffC;
 

	
 
static inline TileIndexDiff ToTileIndexDiff(TileIndexDiffC tidc)
 
{
 
	return (tidc.y << MapLogX()) + tidc.x;
 
}
 

	
 

	
 
#ifndef _DEBUG
 
	#define TILE_ADD(x,y) ((x) + (y))
 
#else
 
	extern TileIndex TileAdd(TileIndex tile, TileIndexDiff add,
 
		const char *exp, const char *file, int line);
 
	#define TILE_ADD(x, y) (TileAdd((x), (y), #x " + " #y, __FILE__, __LINE__))
 
#endif
 

	
 
#define TILE_ADDXY(tile, x, y) TILE_ADD(tile, TileDiffXY(x, y))
 

	
 
uint TileAddWrap(TileIndex tile, int addx, int addy);
 

	
 
static inline TileIndexDiffC TileIndexDiffCByDiagDir(uint dir) {
 
	extern const TileIndexDiffC _tileoffs_by_diagdir[4];
openttd.h
Show inline comments
 
@@ -247,97 +247,97 @@ enum {
 
	CT_COAL         =  1,
 
	CT_MAIL         =  2,
 
	CT_OIL          =  3,
 
	CT_LIVESTOCK    =  4,
 
	CT_GOODS        =  5,
 
	CT_GRAIN        =  6,
 
	CT_WOOD         =  7,
 
	CT_IRON_ORE     =  8,
 
	CT_STEEL        =  9,
 
	CT_VALUABLES    = 10,
 
	CT_FOOD         = 11,
 

	
 
	// Arctic
 
	CT_WHEAT        =  6,
 
	CT_HILLY_UNUSED =  8,
 
	CT_PAPER        =  9,
 
	CT_GOLD         = 10,
 

	
 
	// Tropic
 
	CT_RUBBER       =  1,
 
	CT_FRUIT        =  4,
 
	CT_MAIZE        =  6,
 
	CT_COPPER_ORE   =  8,
 
	CT_WATER        =  9,
 
	CT_DIAMONDS     = 10,
 

	
 
	// Toyland
 
	CT_SUGAR        =  1,
 
	CT_TOYS         =  3,
 
	CT_BATTERIES    =  4,
 
	CT_CANDY        =  5,
 
	CT_TOFFEE       =  6,
 
	CT_COLA         =  7,
 
	CT_COTTON_CANDY =  8,
 
	CT_BUBBLES      =  9,
 
	CT_PLASTIC      = 10,
 
	CT_FIZZY_DRINKS = 11,
 

	
 
	NUM_CARGO       = 12,
 

	
 
	CT_NO_REFIT     = 0xFE,
 
	CT_INVALID      = 0xFF
 
};
 

	
 
typedef uint AcceptedCargo[NUM_CARGO];
 

	
 
typedef struct TileDesc {
 
	StringID str;
 
	byte owner;
 
	Owner owner;
 
	Date build_date;
 
	uint32 dparam[2];
 
} TileDesc;
 

	
 
typedef struct {
 
	int32 left;
 
	int32 top;
 
	byte width_1, width_2;
 
} ViewportSign;
 

	
 

	
 
typedef void DrawTileProc(TileInfo *ti);
 
typedef uint GetSlopeZProc(TileIndex tile, uint x, uint y);
 
typedef int32 ClearTileProc(TileIndex tile, byte flags);
 
typedef void GetAcceptedCargoProc(TileIndex tile, AcceptedCargo res);
 
typedef void GetTileDescProc(TileIndex tile, TileDesc *td);
 
/* GetTileTrackStatusProcs return a value that contains the possible tracks
 
 * that can be taken on a given tile by a given transport. The return value is
 
 * composed as follows: 0xaabbccdd. ccdd and aabb are bitmasks of trackdirs,
 
 * where bit n corresponds to trackdir n. ccdd are the trackdirs that are
 
 * present in the tile (1==present, 0==not present), aabb is the signal
 
 * status, if applicable (0==green/no signal, 1==red, note that this is
 
 * reversed from map3/2[tile] for railway signals).
 
 *
 
 * The result (let's call it ts) is often used as follows:
 
 * tracks = (byte)(ts | ts >>8)
 
 * This effectively converts the present part of the result (ccdd) to a
 
 * track bitmask, which disregards directions. Normally, this is the same as just
 
 * doing (byte)ts I think, although I am not really sure
 
 *
 
 * A trackdir is combination of a track and a dir, where the lower three bits
 
 * are a track, the fourth bit is the direction. these give 12 (or 14)
 
 * possible options: 0-5 and 8-13, so we need 14 bits for a trackdir bitmask
 
 * above.
 
 */
 
typedef uint32 GetTileTrackStatusProc(TileIndex tile, TransportType mode);
 
typedef void GetProducedCargoProc(TileIndex tile, CargoID *b);
 
typedef void ClickTileProc(TileIndex tile);
 
typedef void AnimateTileProc(TileIndex tile);
 
typedef void TileLoopProc(TileIndex tile);
 
typedef void ChangeTileOwnerProc(TileIndex tile, PlayerID old_player, PlayerID new_player);
 
/* Return value has bit 0x2 set, when the vehicle enters a station. Then,
 
 * result << 8 contains the id of the station entered. If the return value has
 
 * bit 0x8 set, the vehicle could not and did not enter the tile. Are there
 
 * other bits that can be set? */
 
typedef uint32 VehicleEnterTileProc(Vehicle *v, TileIndex tile, int x, int y);
 
typedef Slope GetSlopeTilehProc(TileIndex, Slope tileh);
 

	
player.h
Show inline comments
 
@@ -157,97 +157,97 @@ typedef struct Player {
 

	
 
	uint32 face;
 

	
 
	int32 player_money;
 
	int32 current_loan;
 
	int64 money64; // internal 64-bit version of the money. the 32-bit field will be clamped to plus minus 2 billion
 

	
 
	byte player_color;
 
	Livery livery[LS_END];
 
	byte player_money_fraction;
 
	byte avail_railtypes;
 
	byte block_preview;
 
	PlayerID index;
 

	
 
	uint16 cargo_types; /* which cargo types were transported the last year */
 

	
 
	TileIndex location_of_house;
 
	TileIndex last_build_coordinate;
 

	
 
	PlayerID share_owners[4];
 

	
 
	Year inaugurated_year;
 
	byte num_valid_stat_ent;
 

	
 
	byte quarters_of_bankrupcy;
 
	byte bankrupt_asked; // which players were asked about buying it?
 
	int16 bankrupt_timeout;
 
	int32 bankrupt_value;
 

	
 
	bool is_active;
 
	bool is_ai;
 
	PlayerAI ai;
 
	PlayerAiNew ainew;
 

	
 
	int64 yearly_expenses[3][13];
 
	PlayerEconomyEntry cur_economy;
 
	PlayerEconomyEntry old_economy[24];
 
	EngineRenewList engine_renew_list; // Defined later
 
	bool engine_renew;
 
	bool renew_keep_length;
 
	int16 engine_renew_months;
 
	uint32 engine_renew_money;
 
	uint16 num_engines[TOTAL_NUM_ENGINES]; // caches the number of engines of each type the player owns (no need to save this)
 
} Player;
 

	
 
uint16 GetDrawStringPlayerColor(PlayerID player);
 

	
 
void ChangeOwnershipOfPlayerItems(PlayerID old_player, PlayerID new_player);
 
void GetNameOfOwner(PlayerID owner, TileIndex tile);
 
void GetNameOfOwner(Owner owner, TileIndex tile);
 
int64 CalculateCompanyValue(const Player* p);
 
void InvalidatePlayerWindows(const Player* p);
 
void UpdatePlayerMoney32(Player *p);
 
#define FOR_ALL_PLAYERS(p) for (p = _players; p != endof(_players); p++)
 

	
 
VARDEF PlayerID _local_player;
 
VARDEF PlayerID _current_player;
 

	
 
/* Player identifiers All players below MAX_PLAYERS are playable
 
 * players, above, they are special, computer controlled players */
 
enum {
 
	PLAYER_SPECTATOR   = 255, ///< Spectator in Multiplayer or the player in the scenario editor
 
	MAX_PLAYERS        = 8,
 
};
 

	
 
VARDEF Player _players[MAX_PLAYERS];
 
// NOSAVE: can be determined from player structs
 
VARDEF byte _player_colors[MAX_PLAYERS];
 

	
 
static inline byte ActivePlayerCount(void)
 
{
 
	const Player *p;
 
	byte count = 0;
 

	
 
	FOR_ALL_PLAYERS(p) {
 
		if (p->is_active) count++;
 
	}
 

	
 
	return count;
 
}
 

	
 
static inline Player* GetPlayer(PlayerID i)
 
{
 
	assert(i < lengthof(_players));
 
	return &_players[i];
 
}
 

	
 
static inline bool IsLocalPlayer(void)
 
{
 
	return _local_player == _current_player;
 
}
 

	
 
void DeletePlayerWindows(PlayerID pi);
 
byte GetPlayerRailtypes(PlayerID p);
 

	
 
/** Finds out if a Player has a certain railtype available */
 
static inline bool HasRailtypeAvail(const Player *p, RailType Railtype)
 
{
players.c
Show inline comments
 
@@ -214,133 +214,133 @@ bool CheckPlayerHasMoney(int32 cost)
 
}
 

	
 
static void SubtractMoneyFromAnyPlayer(Player *p, int32 cost)
 
{
 
	p->money64 -= cost;
 
	UpdatePlayerMoney32(p);
 

	
 
	p->yearly_expenses[0][_yearly_expenses_type] += cost;
 

	
 
	if (HASBIT(1<<7|1<<8|1<<9|1<<10, _yearly_expenses_type)) {
 
		p->cur_economy.income -= cost;
 
	} else if (HASBIT(1<<2|1<<3|1<<4|1<<5|1<<6|1<<11, _yearly_expenses_type)) {
 
		p->cur_economy.expenses -= cost;
 
	}
 

	
 
	InvalidatePlayerWindows(p);
 
}
 

	
 
void SubtractMoneyFromPlayer(int32 cost)
 
{
 
	PlayerID pid = _current_player;
 

	
 
	if (pid < MAX_PLAYERS) SubtractMoneyFromAnyPlayer(GetPlayer(pid), cost);
 
}
 

	
 
void SubtractMoneyFromPlayerFract(PlayerID player, int32 cost)
 
{
 
	Player *p = GetPlayer(player);
 
	byte m = p->player_money_fraction;
 

	
 
	p->player_money_fraction = m - (byte)cost;
 
	cost >>= 8;
 
	if (p->player_money_fraction > m) cost++;
 
	if (cost != 0) SubtractMoneyFromAnyPlayer(p, cost);
 
}
 

	
 
// the player_money field is kept as it is, but money64 contains the actual amount of money.
 
void UpdatePlayerMoney32(Player *p)
 
{
 
	if (p->money64 < -2000000000) {
 
		p->player_money = -2000000000;
 
	} else if (p->money64 > 2000000000) {
 
		p->player_money = 2000000000;
 
	} else {
 
		p->player_money = (int32)p->money64;
 
	}
 
}
 

	
 
void GetNameOfOwner(PlayerID owner, TileIndex tile)
 
void GetNameOfOwner(Owner owner, TileIndex tile)
 
{
 
	SetDParam(2, owner);
 

	
 
	if (owner != OWNER_TOWN) {
 
		if (owner >= MAX_PLAYERS) {
 
			SetDParam(0, STR_0150_SOMEONE);
 
		} else {
 
			const Player* p = GetPlayer(owner);
 

	
 
			SetDParam(0, p->name_1);
 
			SetDParam(1, p->name_2);
 
		}
 
	} else {
 
		const Town* t = ClosestTownFromTile(tile, (uint)-1);
 

	
 
		SetDParam(0, STR_TOWN);
 
		SetDParam(1, t->index);
 
	}
 
}
 

	
 

	
 
bool CheckOwnership(PlayerID owner)
 
{
 
	assert(owner <= OWNER_WATER);
 
	assert(owner < OWNER_END);
 

	
 
	if (owner == _current_player) return true;
 
	_error_message = STR_013B_OWNED_BY;
 
	GetNameOfOwner(owner, 0);
 
	return false;
 
}
 

	
 
bool CheckTileOwnership(TileIndex tile)
 
{
 
	PlayerID owner = GetTileOwner(tile);
 
	Owner owner = GetTileOwner(tile);
 

	
 
	assert(owner <= OWNER_WATER);
 
	assert(owner < OWNER_END);
 

	
 
	if (owner == _current_player) return true;
 
	_error_message = STR_013B_OWNED_BY;
 

	
 
	// no need to get the name of the owner unless we're the local player (saves some time)
 
	if (IsLocalPlayer()) GetNameOfOwner(owner, tile);
 
	return false;
 
}
 

	
 
static void GenerateCompanyName(Player *p)
 
{
 
	TileIndex tile;
 
	Town *t;
 
	StringID str;
 
	Player *pp;
 
	uint32 strp;
 
	char buffer[100];
 

	
 
	if (p->name_1 != STR_SV_UNNAMED) return;
 

	
 
	tile = p->last_build_coordinate;
 
	if (tile == 0) return;
 

	
 
	t = ClosestTownFromTile(tile, (uint)-1);
 

	
 
	if (IS_INT_INSIDE(t->townnametype, SPECSTR_TOWNNAME_START, SPECSTR_TOWNNAME_LAST+1)) {
 
		str = t->townnametype - SPECSTR_TOWNNAME_START + SPECSTR_PLAYERNAME_START;
 
		strp = t->townnameparts;
 

	
 
verify_name:;
 
		// No player must have this name already
 
		FOR_ALL_PLAYERS(pp) {
 
			if (pp->name_1 == str && pp->name_2 == strp) goto bad_town_name;
 
		}
 

	
 
		GetString(buffer, str);
 
		if (strlen(buffer) >= 32 || GetStringBoundingBox(buffer).width >= 150)
 
			goto bad_town_name;
 

	
 
set_name:;
 
		p->name_1 = str;
 
		p->name_2 = strp;
 

	
 
		MarkWholeScreenDirty();
 

	
 
		if (!IsHumanPlayer(p->index)) {
 
			SetDParam(0, t->index);
 
			AddNewsItem(p->index + (4 << 4), NEWS_FLAGS(NM_CALLBACK, NF_TILE, NT_COMPANY_INFO, DNC_BANKRUPCY), p->last_build_coordinate, 0);
road_cmd.c
Show inline comments
 
/* $Id$ */
 

	
 
#include "stdafx.h"
 
#include "openttd.h"
 
#include "bridge_map.h"
 
#include "rail_map.h"
 
#include "road_map.h"
 
#include "sprite.h"
 
#include "table/sprites.h"
 
#include "table/strings.h"
 
#include "functions.h"
 
#include "map.h"
 
#include "tile.h"
 
#include "town_map.h"
 
#include "vehicle.h"
 
#include "viewport.h"
 
#include "command.h"
 
#include "player.h"
 
#include "town.h"
 
#include "gfx.h"
 
#include "sound.h"
 
#include "yapf/yapf.h"
 
#include "depot.h"
 

	
 

	
 
static uint CountRoadBits(RoadBits r)
 
{
 
	uint count = 0;
 

	
 
	if (r & ROAD_NW) ++count;
 
	if (r & ROAD_SW) ++count;
 
	if (r & ROAD_SE) ++count;
 
	if (r & ROAD_NE) ++count;
 
	return count;
 
}
 

	
 

	
 
static bool CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, bool* edge_road)
 
{
 
	RoadBits present;
 
	RoadBits n;
 
	byte owner;
 
	Owner owner;
 
	*edge_road = true;
 

	
 
	if (_game_mode == GM_EDITOR) return true;
 

	
 
	// Only do the special processing for actual players.
 
	if (_current_player >= MAX_PLAYERS) return true;
 

	
 
	owner = IsLevelCrossingTile(tile) ? GetCrossingRoadOwner(tile) : GetTileOwner(tile);
 

	
 
	// Only do the special processing if the road is owned
 
	// by a town
 
	if (owner != OWNER_TOWN) {
 
		return owner == OWNER_NONE || CheckOwnership(owner);
 
	}
 
	if (owner != OWNER_TOWN) return (owner == OWNER_NONE) || CheckOwnership(owner);
 

	
 
	if (_cheats.magic_bulldozer.value) return true;
 

	
 
	// Get a bitmask of which neighbouring roads has a tile
 
	n = 0;
 
	present = GetAnyRoadBits(tile);
 
	if (present & ROAD_NE && GetAnyRoadBits(TILE_ADDXY(tile,-1, 0)) & ROAD_SW) n |= ROAD_NE;
 
	if (present & ROAD_SE && GetAnyRoadBits(TILE_ADDXY(tile, 0, 1)) & ROAD_NW) n |= ROAD_SE;
 
	if (present & ROAD_SW && GetAnyRoadBits(TILE_ADDXY(tile, 1, 0)) & ROAD_NE) n |= ROAD_SW;
 
	if (present & ROAD_NW && GetAnyRoadBits(TILE_ADDXY(tile, 0,-1)) & ROAD_SE) n |= ROAD_NW;
 

	
 
	// If 0 or 1 bits are set in n, or if no bits that match the bits to remove,
 
	// then allow it
 
	if ((n & (n - 1)) != 0 && (n & remove) != 0) {
 
		Town *t;
 
		*edge_road = false;
 
		// you can remove all kind of roads with extra dynamite
 
		if (_patches.extra_dynamite) return true;
 

	
 
		t = ClosestTownFromTile(tile, _patches.dist_local_authority);
 

	
 
		SetDParam(0, t->index);
 
		_error_message = STR_2009_LOCAL_AUTHORITY_REFUSES;
 
		return false;
 
	}
 

	
 
	return true;
 
}
 

	
 

	
 
/** Delete a piece of road.
 
 * @param tile tile where to remove road from
 
 * @param p1 road piece flags
 
 * @param p2 unused
 
 */
 
int32 CmdRemoveRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	// cost for removing inner/edge -roads
 
	static const uint16 road_remove_cost[2] = {50, 18};
 

	
 
	PlayerID owner;
 
	Owner owner;
 
	Town *t;
 
	/* true if the roadpiece was always removeable,
 
	 * false if it was a center piece. Affects town ratings drop */
 
	bool edge_road;
 
	RoadBits pieces;
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 

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

	
 
	if (!IsTileType(tile, MP_STREET) && !IsTileType(tile, MP_TUNNELBRIDGE)) return CMD_ERROR;
 

	
 
	owner = IsLevelCrossingTile(tile) ? GetCrossingRoadOwner(tile) : GetTileOwner(tile);
 

	
 
	if (owner == OWNER_TOWN && _game_mode != GM_EDITOR) {
 
		if (IsTileType(tile, MP_TUNNELBRIDGE)) { // index of town is not saved for bridge (no space)
 
			t = ClosestTownFromTile(tile, _patches.dist_local_authority);
 
		} else {
 
			t = GetTownByTile(tile);
 
		}
 
	} else {
 
		t = NULL;
 
	}
 

	
 
	if (!CheckAllowRemoveRoad(tile, pieces, &edge_road)) return CMD_ERROR;
 

	
 
	switch (GetTileType(tile)) {
 
		case MP_TUNNELBRIDGE:
 
			if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR;
 

	
 
			if (!IsBridge(tile) ||
 
					!IsBridgeMiddle(tile) ||
 
					!IsTransportUnderBridge(tile) ||
 
					GetTransportTypeUnderBridge(tile) != TRANSPORT_ROAD ||
 
					(pieces & ComplementRoadBits(GetRoadBitsUnderBridge(tile))) != 0) {
 
				return CMD_ERROR;
 
			}
 

	
 
			if (flags & DC_EXEC) {
 
				ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM);
 
				SetClearUnderBridge(tile);
 
				MarkTileDirtyByTile(tile);
 
			}
 
			return _price.remove_road * 2;
 

	
 
		case MP_STREET:
road_map.h
Show inline comments
 
@@ -133,81 +133,81 @@ static inline bool HasRoadWorks(TileInde
 
static inline bool IncreaseRoadWorksCounter(TileIndex t)
 
{
 
	AB(_m[t].m4, 0, 4, 1);
 

	
 
	return GB(_m[t].m4, 0, 4) == 15;
 
}
 

	
 
static inline void StartRoadWorks(TileIndex t)
 
{
 
	assert(!HasRoadWorks(t));
 
	/* Remove any trees or lamps in case or roadwork */
 
	switch (GetRoadside(t)) {
 
		case ROADSIDE_BARREN:
 
		case ROADSIDE_GRASS:  SetRoadside(t, ROADSIDE_GRASS_ROAD_WORKS); break;
 
		default:              SetRoadside(t, ROADSIDE_PAVED_ROAD_WORKS); break;
 
	}
 
}
 

	
 
static inline void TerminateRoadWorks(TileIndex t)
 
{
 
	assert(HasRoadWorks(t));
 
	SetRoadside(t, (Roadside)(GetRoadside(t) - ROADSIDE_GRASS_ROAD_WORKS + ROADSIDE_GRASS));
 
	/* Stop the counter */
 
	SB(_m[t].m4, 0, 4, 0);
 
}
 

	
 

	
 
static inline DiagDirection GetRoadDepotDirection(TileIndex t)
 
{
 
	assert(GetRoadTileType(t) == ROAD_TILE_DEPOT);
 
	return (DiagDirection)GB(_m[t].m5, 0, 2);
 
}
 

	
 

	
 
/**
 
 * Returns the RoadBits on an arbitrary tile
 
 * Special behavior:
 
 * - road depots: entrance is treated as road piece
 
 * - road tunnels: entrance is treated as road piece
 
 * - bridge ramps: start of the ramp is treated as road piece
 
 * - bridge middle parts: bridge itself is ignored
 
 */
 
RoadBits GetAnyRoadBits(TileIndex);
 

	
 

	
 
TrackBits GetAnyRoadTrackBits(TileIndex tile);
 

	
 

	
 
static inline void MakeRoadNormal(TileIndex t, Owner owner, RoadBits bits, uint town)
 
static inline void MakeRoadNormal(TileIndex t, Owner owner, RoadBits bits, TownID town)
 
{
 
	SetTileType(t, MP_STREET);
 
	SetTileOwner(t, owner);
 
	_m[t].m2 = town;
 
	_m[t].m3 = 0;
 
	_m[t].m4 = 0 << 7 | 0 << 4 | 0;
 
	_m[t].m5 = ROAD_TILE_NORMAL << 4 | bits;
 
}
 

	
 

	
 
static inline void MakeRoadCrossing(TileIndex t, Owner road, Owner rail, Axis roaddir, RailType rt, uint town)
 
{
 
	SetTileType(t, MP_STREET);
 
	SetTileOwner(t, rail);
 
	_m[t].m2 = town;
 
	_m[t].m3 = road;
 
	_m[t].m4 = 0 << 7 | 0 << 4 | rt;
 
	_m[t].m5 = ROAD_TILE_CROSSING << 4 | roaddir << 3 | 0 << 2;
 
}
 

	
 

	
 
static inline void MakeRoadDepot(TileIndex t, Owner owner, DiagDirection dir)
 
{
 
	SetTileType(t, MP_STREET);
 
	SetTileOwner(t, owner);
 
	_m[t].m2 = 0;
 
	_m[t].m3 = 0;
 
	_m[t].m4 = 0;
 
	_m[t].m5 = ROAD_TILE_DEPOT << 4 | dir;
 
}
 

	
 
#endif /* ROAD_MAP_H */
tunnelbridge_cmd.c
Show inline comments
 
@@ -663,97 +663,97 @@ static int32 DoClearBridge(TileIndex til
 
	// floods, scenario editor can always destroy bridges
 
	if (_current_player != OWNER_WATER && _game_mode != GM_EDITOR && !CheckTileOwnership(tile)) {
 
		if (!(_patches.extra_dynamite || _cheats.magic_bulldozer.value) || !IsTileOwner(tile, OWNER_TOWN))
 
			return CMD_ERROR;
 
	}
 

	
 
	endtile = GetOtherBridgeEnd(tile);
 

	
 
	if (!EnsureNoVehicle(tile) || !EnsureNoVehicle(endtile)) return CMD_ERROR;
 

	
 
	direction = GetBridgeRampDirection(tile);
 
	delta = TileOffsByDiagDir(direction);
 

	
 
	/* Make sure there's no vehicle on the bridge
 
	 * Omit tile and endtile, since these are already checked, thus solving the
 
	 * problem of bridges over water, or higher bridges, where z is not increased,
 
	 * eg level bridge
 
	 */
 
	v = FindVehicleBetween(
 
		tile    + delta,
 
		endtile - delta,
 
		GetBridgeHeightRamp(tile)
 
	);
 
	if (v != NULL) return_cmd_error(VehicleInTheWayErrMsg(v));
 

	
 
	t = ClosestTownFromTile(tile, (uint)-1); //needed for town rating penalty
 
	// check if you're allowed to remove the bridge owned by a town.
 
	// removal allowal depends on difficulty settings
 
	if (IsTileOwner(tile, OWNER_TOWN) && _game_mode != GM_EDITOR) {
 
		if (!CheckforTownRating(flags, t, TUNNELBRIDGE_REMOVE)) return CMD_ERROR;
 
	}
 

	
 
	if (flags & DC_EXEC) {
 
		TileIndex c;
 
		Track track;
 

	
 
		//checks if the owner is town then decrease town rating by RATING_TUNNEL_BRIDGE_DOWN_STEP until
 
		// you have a "Poor" (0) town rating
 
		if (IsTileOwner(tile, OWNER_TOWN) && _game_mode != GM_EDITOR)
 
			ChangeTownRating(t, RATING_TUNNEL_BRIDGE_DOWN_STEP, RATING_TUNNEL_BRIDGE_MINIMUM);
 

	
 
		DoClearSquare(tile);
 
		DoClearSquare(endtile);
 
		for (c = tile + delta; c != endtile; c += delta) {
 
			if (IsTransportUnderBridge(c)) {
 
				if (GetTransportTypeUnderBridge(c) == TRANSPORT_RAIL) {
 
					MakeRailNormal(c, GetTileOwner(c), GetRailBitsUnderBridge(c), GetRailType(c));
 
				} else {
 
					uint town = IsTileOwner(c, OWNER_TOWN) ? ClosestTownFromTile(c, (uint)-1)->index : 0;
 
					TownID town = IsTileOwner(c, OWNER_TOWN) ? ClosestTownFromTile(c, (uint)-1)->index : 0;
 
					MakeRoadNormal(c, GetTileOwner(c), GetRoadBitsUnderBridge(c), town);
 
				}
 
				MarkTileDirtyByTile(c);
 
			} else {
 
				if (IsClearUnderBridge(c)) {
 
					DoClearSquare(c);
 
				} else {
 
					if (GetTileSlope(c, NULL) == SLOPE_FLAT) {
 
						if (IsTileOwner(c, OWNER_WATER)) {
 
							MakeWater(c);
 
						} else {
 
							MakeCanal(c, GetTileOwner(c));
 
						}
 
					} else {
 
						MakeShore(c);
 
					}
 
					MarkTileDirtyByTile(c);
 
				}
 
			}
 
		}
 

	
 
		UpdateSignalsOnSegment(tile, ReverseDiagDir(direction));
 
		UpdateSignalsOnSegment(endtile, direction);
 
		track = AxisToTrack(DiagDirToAxis(direction));
 
		YapfNotifyTrackLayoutChange(tile, track);
 
		YapfNotifyTrackLayoutChange(endtile, track);
 
	}
 

	
 
	return (DistanceManhattan(tile, endtile) + 1) * _price.clear_bridge;
 
}
 

	
 
static int32 ClearTile_TunnelBridge(TileIndex tile, byte flags)
 
{
 
	if (IsTunnel(tile)) {
 
		if (flags & DC_AUTO) return_cmd_error(STR_5006_MUST_DEMOLISH_TUNNEL_FIRST);
 
		return DoClearTunnel(tile, flags);
 
	} else if (IsBridge(tile)) { // XXX Is this necessary?
 
		if (flags & DC_AUTO) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
 
		return DoClearBridge(tile, flags);
 
	}
 

	
 
	return CMD_ERROR;
 
}
 

	
 
int32 DoConvertTunnelBridgeRail(TileIndex tile, RailType totype, bool exec)
 
{
 
	TileIndex endtile;
 

	
0 comments (0 inline, 0 general)