Changeset - r2498:8dfa040ed505
[Not reviewed]
master
0 22 0
tron - 19 years ago 2005-10-07 07:35:15
tron@openttd.org
(svn r3024) -Codechange: Another batch of replacements of int/uint/int16/byte/-1 with proper types and constants
22 files changed with 84 insertions and 85 deletions:
0 comments (0 inline, 0 general)
aircraft_gui.c
Show inline comments
 
@@ -108,89 +108,89 @@ static void NewAircraftWndProc(Window *w
 
			SETBIT(w->disabled_state, 5);
 

	
 
		{
 
			int count = 0;
 
			int num = NUM_AIRCRAFT_ENGINES;
 
			const Engine* e = GetEngine(AIRCRAFT_ENGINES_INDEX);
 

	
 
			do {
 
				if (HASBIT(e->player_avail, _local_player))
 
					count++;
 
			} while (++e,--num);
 
			SetVScrollCount(w, count);
 
		}
 

	
 
		DrawWindowWidgets(w);
 

	
 
		{
 
			int num = NUM_AIRCRAFT_ENGINES;
 
			const Engine* e = GetEngine(AIRCRAFT_ENGINES_INDEX);
 
			int x = 2;
 
			int y = 15;
 
			int sel = WP(w,buildtrain_d).sel_index;
 
			int pos = w->vscroll.pos;
 
			EngineID engine_id = AIRCRAFT_ENGINES_INDEX;
 
			int selected_id = -1;
 
			EngineID selected_id = INVALID_ENGINE;
 

	
 
			do {
 
				if (HASBIT(e->player_avail, _local_player)) {
 
					if (sel==0) selected_id = engine_id;
 
					if (IS_INT_INSIDE(--pos, -w->vscroll.cap, 0)) {
 
						DrawString(x+62, y+7, GetCustomEngineName(engine_id), sel==0 ? 0xC : 0x10);
 
						DrawAircraftEngine(x+29, y+10, engine_id, SPRITE_PALETTE(PLAYER_SPRITE_COLOR(_local_player)));
 
						y += 24;
 
					}
 
					sel--;
 
				}
 
			} while (++engine_id, ++e,--num);
 

	
 
			WP(w,buildtrain_d).sel_engine = selected_id;
 

	
 
			if (selected_id != -1) {
 
			if (selected_id != INVALID_ENGINE) {
 
				DrawAircraftPurchaseInfo(2, w->widget[4].top + 1, selected_id);
 
			}
 
		}
 
	} break;
 

	
 
	case WE_CLICK:
 
		switch(e->click.widget) {
 
		case 2: { /* listbox */
 
			uint i = (e->click.pt.y - 14) / 24;
 
			if (i < w->vscroll.cap) {
 
				WP(w,buildtrain_d).sel_index = i + w->vscroll.pos;
 
				SetWindowDirty(w);
 
			}
 
		} break;
 

	
 
		case 5: { /* build */
 
			int sel_eng = WP(w,buildtrain_d).sel_engine;
 
			if (sel_eng != -1)
 
			EngineID sel_eng = WP(w,buildtrain_d).sel_engine;
 
			if (sel_eng != INVALID_ENGINE)
 
				DoCommandP(w->window_number, sel_eng, 0, CcBuildAircraft, CMD_BUILD_AIRCRAFT | CMD_MSG(STR_A008_CAN_T_BUILD_AIRCRAFT));
 
		} break;
 

	
 
		case 6:	{ /* rename */
 
			int sel_eng = WP(w,buildtrain_d).sel_engine;
 
			if (sel_eng != -1) {
 
			EngineID sel_eng = WP(w,buildtrain_d).sel_engine;
 
			if (sel_eng != INVALID_ENGINE) {
 
				WP(w,buildtrain_d).rename_engine = sel_eng;
 
				ShowQueryString(GetCustomEngineName(sel_eng),
 
					STR_A039_RENAME_AIRCRAFT_TYPE, 31, 160, w->window_class, w->window_number);
 
			}
 
		} break;
 
		}
 
		break;
 

	
 
	case WE_4:
 
		if (w->window_number != 0 && !FindWindowById(WC_VEHICLE_DEPOT, w->window_number)) {
 
			DeleteWindow(w);
 
		}
 
		break;
 

	
 
	case WE_ON_EDIT_TEXT: {
 
		if (e->edittext.str[0] != '\0') {
 
			_cmd_text = e->edittext.str;
 
			DoCommandP(0, WP(w, buildtrain_d).rename_engine, 0, NULL,
 
				CMD_RENAME_ENGINE | CMD_MSG(STR_A03A_CAN_T_RENAME_AIRCRAFT_TYPE));
 
		}
 
	} break;
 

	
 
	case WE_RESIZE:
 
		w->vscroll.cap += e->sizing.diff.y / 24;
economy.c
Show inline comments
 
@@ -1302,49 +1302,49 @@ static bool LoadWait(const Vehicle *v, c
 

	
 
			if (has_space_for_same_type) {
 
				if (other_has_same_type) return true;
 
				if (other_has_any_cargo && !has_any_cargo) return true;
 
			}
 
		}
 
	}
 

	
 
	return false;
 
}
 

	
 
int LoadUnloadVehicle(Vehicle *v)
 
{
 
	int profit = 0;
 
	int v_profit; //virtual profit for feeder systems
 
	int v_profit_total = 0;
 
	int unloading_time = 20;
 
	Vehicle *u = v;
 
	int result = 0;
 
	uint16 last_visited;
 
	Station *st;
 
	GoodsEntry *ge;
 
	int t;
 
	uint count, cap;
 
	byte old_player;
 
	PlayerID old_player;
 
	bool completely_empty = true;
 

	
 
	assert(v->current_order.type == OT_LOADING);
 

	
 
	v->cur_speed = 0;
 

	
 
	old_player = _current_player;
 
	_current_player = v->owner;
 

	
 
	st = GetStation(last_visited = v->last_station_visited);
 

	
 
	for (; v != NULL; v = v->next) {
 
		if (v->cargo_cap == 0) continue;
 

	
 
		ge = &st->goods[v->cargo_type];
 

	
 
		/* unload? */
 
		if (v->cargo_count != 0) {
 
			if ( v->cargo_source != last_visited && ge->waiting_acceptance & 0x8000 && !(u->current_order.flags & OF_TRANSFER) ) {
 
				// deliver goods to the station
 
				st->time_since_unload = 0;
 

	
 
				unloading_time += v->cargo_count; /* TTDBUG: bug in original TTD */
 
				profit += DeliverGoods(v->cargo_count, v->cargo_type, v->cargo_source, last_visited, v->cargo_days);
 
@@ -1539,91 +1539,91 @@ extern int GetAmountOwnedBy(Player *p, b
 
 * @param p2 unused
 
 */
 
int32 CmdBuyShareInCompany(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	Player *p;
 
	int64 cost;
 

	
 
	/* Check if buying shares is allowed (protection against modified clients */
 
	if (p1 >= MAX_PLAYERS || !_patches.allow_shares) return CMD_ERROR;
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_OTHER);
 
	p = GetPlayer(p1);
 

	
 
	/* Protect new companies from hostile takeovers */
 
	if (_cur_year - p->inaugurated_year < 6) return_cmd_error(STR_7080_PROTECTED);
 

	
 
	/* Those lines are here for network-protection (clients can be slow) */
 
	if (GetAmountOwnedBy(p, OWNER_SPECTATOR) == 0) return 0;
 

	
 
	/* We can not buy out a real player (temporarily). TODO: well, enable it obviously */
 
	if (GetAmountOwnedBy(p, OWNER_SPECTATOR) == 1 && !p->is_ai) return 0;
 

	
 
	cost = CalculateCompanyValue(p) >> 2;
 
	if (flags & DC_EXEC) {
 
		PlayerID* b = p->share_owners;
 
		int i;
 
		byte *b = p->share_owners;
 

	
 
		while (*b != OWNER_SPECTATOR) b++; /* share owners is guaranteed to contain at least one OWNER_SPECTATOR */
 
		*b = _current_player;
 

	
 
		for (i = 0; p->share_owners[i] == _current_player;) {
 
			if (++i == 4) {
 
				p->bankrupt_value = 0;
 
				DoAcquireCompany(p);
 
				break;
 
			}
 
		}
 
		InvalidateWindow(WC_COMPANY, (int)p1);
 
	}
 
	return cost;
 
}
 

	
 
/** Sell shares in an opposing company.
 
 * @param x,y unused
 
 * @param p1 player to sell the shares from
 
 * @param p2 unused
 
 */
 
int32 CmdSellShareInCompany(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	Player *p;
 
	int64 cost;
 

	
 
	/* Check if buying shares is allowed (protection against modified clients */
 
	if (p1 >= MAX_PLAYERS || !_patches.allow_shares) return CMD_ERROR;
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_OTHER);
 
	p = GetPlayer(p1);
 

	
 
	/* Those lines are here for network-protection (clients can be slow) */
 
	if (GetAmountOwnedBy(p, _current_player) == 0) return 0;
 

	
 
	/* adjust it a little to make it less profitable to sell and buy */
 
	cost = CalculateCompanyValue(p) >> 2;
 
	cost = -(cost - (cost >> 7));
 

	
 
	if (flags & DC_EXEC) {
 
		byte *b = p->share_owners;
 
		PlayerID* b = p->share_owners;
 
		while (*b != _current_player) b++; /* share owners is guaranteed to contain player */
 
		*b = OWNER_SPECTATOR;
 
		InvalidateWindow(WC_COMPANY, (int)p1);
 
	}
 
	return cost;
 
}
 

	
 
/** Buy up another company.
 
 * When a competing company is gone bankrupt you get the chance to purchase
 
 * that company.
 
 * @todo currently this only works for AI players
 
 * @param x,y unused
 
 * @param p1 player/company to buy up
 
 * @param p2 unused
 
 */
 
int32 CmdBuyCompany(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	Player *p;
 

	
 
	/* Disable takeovers in multiplayer games */
 
	if (p1 >= MAX_PLAYERS || _networking) return CMD_ERROR;
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_OTHER);
 
	p = GetPlayer(p1);
industry_cmd.c
Show inline comments
 
@@ -1021,49 +1021,49 @@ static void MaybePlantFarmField(Industry
 
}
 

	
 
static void ChopLumberMillTrees(Industry *i)
 
{
 
	static const TileIndexDiffC _chop_dir[] = {
 
		{ 0,  1},
 
		{ 1,  0},
 
		{ 0, -1},
 
		{-1,  0}
 
	};
 

	
 
	TileIndex tile = i->xy;
 
	int dir, a, j;
 

	
 
	if ((_m[tile].m1 & 0x80) == 0)
 
		return;
 

	
 
	/* search outwards as a rectangular spiral */
 
	for(a=1; a!=41; a+=2) {
 
		for(dir=0; dir!=4; dir++) {
 
			j = a;
 
			do {
 
				tile = TILE_MASK(tile);
 
				if (IsTileType(tile, MP_TREES)) {
 
					uint old_player = _current_player;
 
					PlayerID old_player = _current_player;
 
					/* found a tree */
 

	
 
					_current_player = OWNER_NONE;
 
					_industry_sound_ctr = 1;
 
					_industry_sound_tile = tile;
 
					SndPlayTileFx(SND_38_CHAINSAW, tile);
 

	
 
					DoCommandByTile(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
 
					SetMapExtraBits(tile, 0);
 

	
 
					i->cargo_waiting[0] = min(0xffff, i->cargo_waiting[0] + 45);
 

	
 
					_current_player = old_player;
 
					return;
 
				}
 
				tile += ToTileIndexDiff(_chop_dir[dir]);
 
			} while (--j);
 
		}
 
		tile -= TileDiffXY(1, 1);
 
	}
 
}
 

	
 
static const byte _industry_sounds[37][2] = {
 
	{0},
 
@@ -1641,49 +1641,49 @@ Industry *CreateNewIndustry(TileIndex ti
 

	
 
	return i;
 
}
 

	
 
static const byte _numof_industry_table[4][12] = {
 
	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
 
	{0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5},
 
	{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
 
	{0, 2, 3, 4, 6, 7, 8, 9, 10, 10, 10},
 
};
 

	
 
static void PlaceInitialIndustry(byte type, int amount)
 
{
 
	int num = _numof_industry_table[_opt.diff.number_industries][amount];
 

	
 
	if (type == IT_OIL_REFINERY || type == IT_OIL_RIG) {
 
		// These are always placed next to the coastline, so we scale by the perimeter instead.
 
		num = ScaleByMapSize1D(num);
 
	} else {
 
		num = ScaleByMapSize(num);
 
	}
 

	
 
	if (_opt.diff.number_industries != 0)
 
	{
 
		byte old_player = _current_player;
 
		PlayerID old_player = _current_player;
 
		_current_player = OWNER_NONE;
 
		assert(num > 0);
 

	
 
		do {
 
			int i = 2000;
 
			do {
 
				if (CreateNewIndustry(RandomTile(), type) != NULL)
 
					break;
 
			} while (--i != 0);
 
		} while (--num);
 

	
 
		_current_player = old_player;
 
	}
 
}
 

	
 
void GenerateIndustries(void)
 
{
 
	const byte *b;
 

	
 
	b = _industry_create_table[_opt.landscape];
 
	do {
 
		PlaceInitialIndustry(b[1], b[0]);
 
	} while ( (b+=2)[0] != 0);
 
}
 
@@ -1881,49 +1881,49 @@ static void ChangeIndustryProduction(Ind
 
						str = _industry_prod_down_strings[type];
 
					}
 
				}
 
			}
 
			break;
 

	
 
		case INDUSTRY_CLOSABLE:
 
			/* maybe close */
 
			if ( (byte)(_cur_year - i->last_prod_year) >= 5 && CHANCE16(1,2)) {
 
				i->prod_level = 0;
 
				str = _industry_close_strings[type];
 
			}
 
			break;
 
	}
 

	
 
	if (str != STR_NULL) {
 
		SetDParam(0, i->index);
 
		AddNewsItem(str, NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_TILE, NT_ECONOMY, 0), i->xy + TileDiffXY(1, 1), 0);
 
	}
 
}
 

	
 
void IndustryMonthlyLoop(void)
 
{
 
	Industry *i;
 
	byte old_player = _current_player;
 
	PlayerID old_player = _current_player;
 
	_current_player = OWNER_NONE;
 

	
 
	FOR_ALL_INDUSTRIES(i) {
 
		if (i->xy != 0)
 
			UpdateIndustryStatistics(i);
 
	}
 

	
 
	/* 3% chance that we start a new industry */
 
	if (CHANCE16(3, 100)) {
 
		MaybeNewIndustry(Random());
 
	} else if (!_patches.smooth_economy && _total_industries > 0) {
 
		i = GetIndustry(RandomRange(_total_industries));
 
		if (i->xy != 0)
 
			ChangeIndustryProduction(i);
 
	}
 

	
 
	_current_player = old_player;
 

	
 
	// production-change
 
	_industry_sort_dirty = true;
 
	InvalidateWindow(WC_INDUSTRY_DIRECTORY, 0);
 
}
 

	
 

	
landscape.c
Show inline comments
 
@@ -359,49 +359,49 @@ void CDECL ModifyTile(TileIndex tile, ui
 

	
 
	if ((i = GB(flags, 8, 4)) != 0) {
 
		SetTileType(tile, i - 1);
 
	}
 

	
 
	if (flags & (MP_MAP2_CLEAR | MP_MAP2)) {
 
		int x = 0;
 
		if (flags & MP_MAP2) x = va_arg(va, int);
 
		_m[tile].m2 = x;
 
	}
 

	
 
	if (flags & (MP_MAP3LO_CLEAR | MP_MAP3LO)) {
 
		int x = 0;
 
		if (flags & MP_MAP3LO) x = va_arg(va, int);
 
		_m[tile].m3 = x;
 
	}
 

	
 
	if (flags & (MP_MAP3HI_CLEAR | MP_MAP3HI)) {
 
		int x = 0;
 
		if (flags & MP_MAP3HI) x = va_arg(va, int);
 
		_m[tile].m4 = x;
 
	}
 

	
 
	if (flags & (MP_MAPOWNER|MP_MAPOWNER_CURRENT)) {
 
		byte x = _current_player;
 
		PlayerID x = _current_player;
 
		if (flags & MP_MAPOWNER) x = va_arg(va, int);
 
		_m[tile].m1 = x;
 
	}
 

	
 
	if (flags & MP_MAP5) {
 
		_m[tile].m5 = va_arg(va, int);
 
	}
 

	
 
	va_end(va);
 

	
 
	if (!(flags & MP_NODIRTY))
 
		MarkTileDirtyByTile(tile);
 
}
 

	
 

	
 
#define TILELOOP_BITS 4
 
#define TILELOOP_SIZE (1 << TILELOOP_BITS)
 
#define TILELOOP_ASSERTMASK ((TILELOOP_SIZE-1) + ((TILELOOP_SIZE-1) << MapLogX()))
 
#define TILELOOP_CHKMASK (((1 << (MapLogX() - TILELOOP_BITS))-1) << TILELOOP_BITS)
 

	
 
void RunTileLoop(void)
 
{
 
	TileIndex tile;
 
	uint count;
misc_gui.c
Show inline comments
 
@@ -562,61 +562,61 @@ void ShowErrorMessage(StringID msg_1, St
 
			pt.x = (_screen.width - 240) >> 1;
 
			pt.y = (_screen.height - 46) >> 1;
 
		}
 
		w = AllocateWindow(pt.x, pt.y, 240, 46, ErrmsgWndProc, WC_ERRMSG, _errmsg_widgets);
 
	} else {
 
		if ( (x|y) != 0) {
 
			pt = RemapCoords2(x, y);
 
			for(w=_windows; w->window_class != WC_MAIN_WINDOW; w++) {}
 
			vp = w->viewport;
 
			pt.x = clamp(((pt.x - vp->virtual_left) >> vp->zoom) + vp->left - (334/2), 0, _screen.width - 334);
 
			pt.y = clamp(((pt.y - vp->virtual_top) >> vp->zoom) + vp->top - (137/2), 22, _screen.height - 137);
 
		} else {
 
			pt.x = (_screen.width - 334) >> 1;
 
			pt.y = (_screen.height - 137) >> 1;
 
		}
 
		w = AllocateWindow(pt.x, pt.y, 334, 137, ErrmsgWndProc, WC_ERRMSG, _errmsg_face_widgets);
 
	}
 

	
 
	w->desc_flags = WDF_STD_BTN | WDF_DEF_WIDGET;
 
}
 

	
 

	
 
void ShowEstimatedCostOrIncome(int32 cost, int x, int y)
 
{
 
	int msg = STR_0805_ESTIMATED_COST;
 
	StringID msg = STR_0805_ESTIMATED_COST;
 

	
 
	if (cost < 0) {
 
		cost = -cost;
 
		msg = STR_0807_ESTIMATED_INCOME;
 
	}
 
	SetDParam(0, cost);
 
	ShowErrorMessage(-1, msg, x, y);
 
	ShowErrorMessage(INVALID_STRING_ID, msg, x, y);
 
}
 

	
 
void ShowCostOrIncomeAnimation(int x, int y, int z, int32 cost)
 
{
 
	int msg;
 
	StringID msg;
 
	Point pt = RemapCoords(x,y,z);
 

	
 
	msg = STR_0801_COST;
 
	if (cost < 0) {
 
		cost = -cost;
 
		msg = STR_0803_INCOME;
 
	}
 
	SetDParam(0, cost);
 
	AddTextEffect(msg, pt.x, pt.y, 0x250);
 
}
 

	
 
void ShowFeederIncomeAnimation(int x, int y, int z, int32 cost)
 
{
 
	Point pt = RemapCoords(x,y,z);
 

	
 
	SetDParam(0, cost);
 
	AddTextEffect(STR_FEEDER, pt.x, pt.y, 0x250);
 
}
 

	
 
static const Widget _tooltips_widgets[] = {
 
{      WWT_PANEL,   RESIZE_NONE,    14,     0,   199,     0,    31, 0x0, STR_NULL},
 
{   WIDGETS_END},
 
};
 

	
 
@@ -691,49 +691,49 @@ static void DrawStationCoverageText(cons
 

	
 
	b = InlineString(b, STR_000D_ACCEPTS);
 

	
 
	for (i = 0; i != NUM_CARGO; i++, mask >>= 1) {
 
		if (accepts[i] >= 8 && mask & 1) {
 
			b = InlineString(b, _cargoc.names_s[i]);
 
			*b++ = ',';
 
			*b++ = ' ';
 
		}
 
	}
 

	
 
	if (b == &_userstring[3]) {
 
		b = InlineString(b, STR_00D0_NOTHING);
 
		*b++ = '\0';
 
	} else {
 
		b[-2] = '\0';
 
	}
 

	
 
	DrawStringMultiLine(str_x, str_y, STR_SPEC_USERSTRING, 144);
 
}
 

	
 
void DrawStationCoverageAreaText(int sx, int sy, uint mask, int rad) {
 
	int x = _thd.pos.x;
 
	int y = _thd.pos.y;
 
	uint accepts[NUM_CARGO];
 
	AcceptedCargo accepts;
 
	if (x != -1) {
 
		GetAcceptanceAroundTiles(accepts, TileVirtXY(x, y), _thd.size.x / 16, _thd.size.y / 16 , rad);
 
		DrawStationCoverageText(accepts, sx, sy, mask);
 
	}
 
}
 

	
 
void CheckRedrawStationCoverage(Window *w)
 
{
 
	if (_thd.dirty&1) {
 
		_thd.dirty&=~1;
 
		SetWindowDirty(w);
 
	}
 
}
 

	
 

	
 
void UnclickSomeWindowButtons(Window *w, uint32 mask)
 
{
 
	uint32 x = w->click_state & mask;
 
	int i = 0;
 
	w->click_state ^= x;
 
	do {
 
		if (x&1) InvalidateWidget(w,i);
 
	} while(i++,x>>=1);
 
}
network_data.h
Show inline comments
 
@@ -14,49 +14,49 @@
 
#define MAX_TEXT_MSG_LEN 1024 /* long long long long sentences :-) */
 

	
 
// The client-info-server-index is always 1
 
#define NETWORK_SERVER_INDEX 1
 
#define NETWORK_EMPTY_INDEX 0
 

	
 
// What version of game-info do we use?
 
#define NETWORK_GAME_INFO_VERSION 1
 
// What version of company info is this?
 
#define NETWORK_COMPANY_INFO_VERSION 3
 
// What version of master-server-protocol do we use?
 
#define NETWORK_MASTER_SERVER_VERSION 1
 

	
 
typedef uint16 PacketSize;
 

	
 
typedef struct Packet {
 
	struct Packet *next;
 
	PacketSize size;
 
	PacketSize pos;
 
	byte buffer[SEND_MTU];
 
} Packet;
 

	
 
typedef struct CommandPacket {
 
	struct CommandPacket *next;
 
	byte player;   /// player that is executing the command (PlayerID)
 
	PlayerID player; /// player that is executing the command
 
	uint32 cmd;    /// command being executed
 
	uint32 p1;     /// parameter p1
 
	uint32 p2;     /// parameter p2
 
	TileIndex tile; /// tile command being executed on
 
	char text[80];
 
	uint32 frame;  /// the frame in which this packet is executed
 
	byte callback; /// any callback function executed upon successful completion of the command
 
} CommandPacket;
 

	
 
typedef enum {
 
	STATUS_INACTIVE,
 
	STATUS_AUTH, // This means that the client is authorized
 
	STATUS_MAP_WAIT, // This means that the client is put on hold because someone else is getting the map
 
	STATUS_MAP,
 
	STATUS_DONE_MAP,
 
	STATUS_PRE_ACTIVE,
 
	STATUS_ACTIVE,
 
} ClientStatus;
 

	
 
typedef enum {
 
	MAP_PACKET_START,
 
	MAP_PACKET_NORMAL,
 
	MAP_PACKET_PATCH,
 
	MAP_PACKET_END,
news_gui.c
Show inline comments
 
@@ -352,49 +352,49 @@ static const SoundFx _news_sounds[] = {
 
static inline byte GetNewsDisplayValue(byte item)
 
{
 
	assert(item < 10 && ((_news_display_opt >> (item * 2)) & 0x3) <= 2);
 
	return (_news_display_opt >> (item * 2)) & 0x3;
 
}
 

	
 
/** Set the value of an item in the news-display settings. This is
 
 * a little tricky since on/off/summary must use 2 bits to store the value
 
 * @param item the item whose value is being set
 
 * @param val new value
 
 */
 
static inline void SetNewsDisplayValue(byte item, byte val)
 
{
 
	assert(item < 10 && val <= 2);
 
	item *= 2;
 
	CLRBIT(_news_display_opt, item);
 
	CLRBIT(_news_display_opt, item + 1);
 
	_news_display_opt |= val << item;
 
}
 

	
 
// open up an own newspaper window for the news item
 
static void ShowNewspaper(NewsItem *ni)
 
{
 
	Window *w;
 
	int sound;
 
	SoundFx sound;
 
	int top;
 
	ni->flags &= ~(NF_NOEXPIRE | NF_FORCE_BIG);
 
	ni->duration = 555;
 

	
 
	sound = _news_sounds[ni->type];
 
	if (sound != 0)
 
		SndPlayFx(sound);
 

	
 
	top = _screen.height;
 
	switch (ni->display_mode) {
 
		case NM_NORMAL:
 
		case NM_CALLBACK: {
 
			_news_type13_desc.top = top;
 
			w = AllocateWindowDesc(&_news_type13_desc);
 
			if (ni->flags & NF_VIEWPORT)
 
				AssignWindowViewport(w, 2, 58, 0x1AA, 0x6E,
 
					ni->data_a | (ni->flags & NF_VEHICLE ? 0x80000000 : 0), 0);
 
			break;
 
		}
 

	
 
		case NM_THIN: {
 
			_news_type2_desc.top = top;
 
			w = AllocateWindowDesc(&_news_type2_desc);
 
			if (ni->flags & NF_VIEWPORT)
oldloader.c
Show inline comments
 
@@ -768,49 +768,49 @@ static const OldChunks industry_chunk[] 
 
	OCL_SVAR(  OC_UINT8, Industry, was_cargo_delivered ),
 

	
 
	OCL_NULL( 9 ), // Random junk at the end of this chunk
 

	
 
	OCL_END()
 
};
 
static bool LoadOldIndustry(LoadgameState *ls, int num)
 
{
 
	Industry *i;
 

	
 
	if (!AddBlockIfNeeded(&_industry_pool, num))
 
		error("Industries: failed loading savegame: too many industries");
 

	
 
	i = GetIndustry(num);
 
	if (!LoadChunk(ls, i, industry_chunk))
 
		return false;
 

	
 
	if (i->xy != 0) {
 
		i->town = GetTown(REMAP_TOWN_IDX(_old_town_index));
 
	}
 

	
 
	return true;
 
}
 

	
 
static uint _current_player_id;
 
static PlayerID _current_player_id;
 
static uint16 _old_inaugurated_year;
 
static int32 _old_yearly;
 

	
 
static const OldChunks player_yearly_chunk[] = {
 
	OCL_VAR(  OC_INT32,   1, &_old_yearly ),
 
	OCL_END()
 
};
 
static bool OldPlayerYearly(LoadgameState *ls, int num)
 
{
 
	int i;
 
	Player *p = GetPlayer(_current_player_id);
 

	
 
	for (i = 0; i < 13; i++) {
 
		if (!LoadChunk(ls, NULL, player_yearly_chunk))
 
			return false;
 

	
 
		p->yearly_expenses[num][i] = _old_yearly;
 
	}
 

	
 
	return true;
 
}
 

	
 
static const OldChunks player_economy_chunk[] = {
 
	OCL_SVAR( OC_INT32, PlayerEconomyEntry, income ),
openttd.c
Show inline comments
 
@@ -846,49 +846,49 @@ void StateGameLoop(void)
 
	if (_pause) return;
 

	
 
	// _frame_counter is increased somewhere else when in network-mode
 
	//  Sidenote: _frame_counter is ONLY used for _savedump in non-MP-games
 
	//    Should that not be deleted? If so, the next 2 lines can also be deleted
 
	if (!_networking)
 
		_frame_counter++;
 

	
 
	if (_savedump_path[0] && (uint)_frame_counter >= _savedump_first && (uint)(_frame_counter -_savedump_first) % _savedump_freq == 0 ) {
 
		char buf[100];
 
		sprintf(buf, "%s%.5d.sav", _savedump_path, _frame_counter);
 
		SaveOrLoad(buf, SL_SAVE);
 
		if ((uint)_frame_counter >= _savedump_last) exit(1);
 
	}
 

	
 
	if (_game_mode == GM_EDITOR) {
 
		RunTileLoop();
 
		CallVehicleTicks();
 
		CallLandscapeTick();
 
		CallWindowTickEvent();
 
		NewsLoop();
 
	} else {
 
		// All these actions has to be done from OWNER_NONE
 
		//  for multiplayer compatibility
 
		uint p = _current_player;
 
		PlayerID p = _current_player;
 
		_current_player = OWNER_NONE;
 

	
 
		AnimateAnimatedTiles();
 
		IncreaseDate();
 
		RunTileLoop();
 
		CallVehicleTicks();
 
		CallLandscapeTick();
 

	
 
		AI_RunGameLoop();
 

	
 
		CallWindowTickEvent();
 
		NewsLoop();
 
		_current_player = p;
 
	}
 
}
 

	
 
static void DoAutosave(void)
 
{
 
	char buf[200];
 

	
 
	if (_patches.keep_all_autosave && _local_player != OWNER_SPECTATOR) {
 
		const Player *p = GetPlayer(_local_player);
 
		char *s;
 
		sprintf(buf, "%s%s", _path.autosave_dir, PATHSEP);
player_gui.c
Show inline comments
 
@@ -670,49 +670,49 @@ static void PlayerCompanyWndProc(Window 
 

	
 
	}
 
}
 

	
 

	
 
static const WindowDesc _my_player_company_desc = {
 
	-1,-1, 360, 170,
 
	WC_COMPANY,0,
 
	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
 
	_my_player_company_widgets,
 
	PlayerCompanyWndProc
 
};
 

	
 
static const WindowDesc _other_player_company_desc = {
 
	-1,-1, 360, 170,
 
	WC_COMPANY,0,
 
	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
 
	_other_player_company_widgets,
 
	PlayerCompanyWndProc
 
};
 

	
 
void ShowPlayerCompany(PlayerID player)
 
{
 
	Window *w;
 
	w = AllocateWindowDescFront((byte)player == _local_player ? &_my_player_company_desc : &_other_player_company_desc,  player);
 
	w = AllocateWindowDescFront(player == _local_player ? &_my_player_company_desc : &_other_player_company_desc,  player);
 
	if (w)
 
		w->caption_color = w->window_number;
 
}
 

	
 

	
 

	
 
static void BuyCompanyWndProc(Window *w, WindowEvent *e)
 
{
 
	switch(e->event) {
 
	case WE_PAINT: {
 
		Player *p = GetPlayer(w->window_number);
 
		SetDParam(0, p->name_1);
 
		SetDParam(1, p->name_2);
 
		DrawWindowWidgets(w);
 

	
 
		DrawPlayerFace(p->face, p->player_color, 2, 16);
 

	
 
		SetDParam(0, p->name_1);
 
		SetDParam(1, p->name_2);
 
		SetDParam(2, p->bankrupt_value);
 
		DrawStringMultiCenter(214, 65, STR_705B_WE_ARE_LOOKING_FOR_A_TRANSPORT, 238);
 
		break;
 
	}
 

	
players.c
Show inline comments
 
@@ -175,49 +175,49 @@ void DrawPlayerFace(uint32 face, int col
 

	
 
		if (!(flag&2)) {
 
			if (val<=1) {
 
				DrawSprite(0x347 + val, x, y);
 
			}
 
		} else {
 
			if (val<=1) {
 
				DrawSprite(0x3AE + val, x, y);
 
			}
 
		}
 
	}
 
}
 

	
 
void InvalidatePlayerWindows(const Player *p)
 
{
 
	PlayerID pid = p->index;
 

	
 
	if (pid == _local_player) InvalidateWindow(WC_STATUS_BAR, 0);
 
	InvalidateWindow(WC_FINANCES, pid);
 
}
 

	
 
bool CheckPlayerHasMoney(int32 cost)
 
{
 
	if (cost > 0) {
 
		uint pid = _current_player;
 
		PlayerID pid = _current_player;
 
		if (pid < MAX_PLAYERS && cost > GetPlayer(pid)->player_money) {
 
			SetDParam(0, cost);
 
			_error_message = STR_0003_NOT_ENOUGH_CASH_REQUIRES;
 
			return false;
 
		}
 
	}
 
	return true;
 
}
 

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

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

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

	
 
	InvalidatePlayerWindows(p);
 
}
 

	
 
@@ -263,49 +263,49 @@ void GetNameOfOwner(PlayerID owner, Tile
 
			SetDParam(0, p->name_1);
 
			SetDParam(1, p->name_2);
 
		}
 
	} else {
 
		Town *t = ClosestTownFromTile(tile, (uint)-1);
 
		SetDParam(0, STR_TOWN);
 
		SetDParam(1, t->index);
 
	}
 
}
 

	
 

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

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

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

	
 
	assert(owner <= OWNER_WATER);
 

	
 
	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;
 

	
roadveh_gui.c
Show inline comments
 
@@ -391,109 +391,109 @@ static void DrawNewRoadVehWindow(Window 
 

	
 
	// setup scroller
 
	{
 
		int count = 0;
 
		int num = NUM_ROAD_ENGINES;
 
		const Engine* e = GetEngine(ROAD_ENGINES_INDEX);
 

	
 
		do {
 
			if (HASBIT(e->player_avail, _local_player))
 
				count++;
 
		} while (++e,--num);
 
		SetVScrollCount(w, count);
 
	}
 

	
 
	DrawWindowWidgets(w);
 

	
 
	{
 
		int num = NUM_ROAD_ENGINES;
 
		const Engine* e = GetEngine(ROAD_ENGINES_INDEX);
 
		int x = 1;
 
		int y = 15;
 
		int sel = WP(w,buildtrain_d).sel_index;
 
		int pos = w->vscroll.pos;
 
		EngineID engine_id = ROAD_ENGINES_INDEX;
 
		int selected_id = -1;
 
		EngineID selected_id = INVALID_ENGINE;
 

	
 
		do {
 
			if (HASBIT(e->player_avail, _local_player)) {
 
				if (sel==0) selected_id = engine_id;
 
				if (IS_INT_INSIDE(--pos, -w->vscroll.cap, 0)) {
 
					DrawString(x+59, y+2, GetCustomEngineName(engine_id), sel==0 ? 0xC : 0x10);
 
					DrawRoadVehEngine(x+29, y+6, engine_id, SPRITE_PALETTE(PLAYER_SPRITE_COLOR(_local_player)));
 
					y += 14;
 
				}
 
				sel--;
 
			}
 
		} while (++engine_id, ++e,--num);
 

	
 
		WP(w,buildtrain_d).sel_engine = selected_id;
 
		if (selected_id != -1) {
 
		if (selected_id != INVALID_ENGINE) {
 
			DrawRoadVehPurchaseInfo(2, w->widget[4].top + 1, selected_id);
 
		}
 
	}
 
}
 

	
 
void CcBuildRoadVeh(bool success, TileIndex tile, uint32 p1, uint32 p2)
 
{
 
	Vehicle *v;
 

	
 
	if (!success) return;
 

	
 
	v = GetVehicle(_new_roadveh_id);
 
	if (v->tile == _backup_orders_tile) {
 
		_backup_orders_tile = 0;
 
		RestoreVehicleOrders(v, _backup_orders_data);
 
	}
 
	ShowRoadVehViewWindow(v);
 
}
 

	
 
static void NewRoadVehWndProc(Window *w, WindowEvent *e)
 
{
 
	switch(e->event) {
 
	case WE_PAINT:
 
		DrawNewRoadVehWindow(w);
 
		break;
 

	
 
	case WE_CLICK:
 
		switch(e->click.widget) {
 
		case 2: { /* listbox */
 
			uint i = (e->click.pt.y - 14) / 14;
 
			if (i < w->vscroll.cap) {
 
				WP(w,buildtrain_d).sel_index = i + w->vscroll.pos;
 
				SetWindowDirty(w);
 
			}
 
		} break;
 

	
 
		case 5: { /* build */
 
			int sel_eng = WP(w,buildtrain_d).sel_engine;
 
			if (sel_eng != -1)
 
			EngineID sel_eng = WP(w,buildtrain_d).sel_engine;
 
			if (sel_eng != INVALID_ENGINE)
 
				DoCommandP(w->window_number, sel_eng, 0, CcBuildRoadVeh, CMD_BUILD_ROAD_VEH | CMD_MSG(STR_9009_CAN_T_BUILD_ROAD_VEHICLE));
 
		} break;
 

	
 
		case 6: { /* rename */
 
			int sel_eng = WP(w,buildtrain_d).sel_engine;
 
			if (sel_eng != -1) {
 
			EngineID sel_eng = WP(w,buildtrain_d).sel_engine;
 
			if (sel_eng != INVALID_ENGINE) {
 
				WP(w,buildtrain_d).rename_engine = sel_eng;
 
				ShowQueryString(GetCustomEngineName(sel_eng),
 
					STR_9036_RENAME_ROAD_VEHICLE_TYPE, 31, 160, w->window_class, w->window_number);
 
			}
 
		}	break;
 
		}
 
		break;
 

	
 
	case WE_4:
 
		if (w->window_number != 0 && !FindWindowById(WC_VEHICLE_DEPOT, w->window_number)) {
 
			DeleteWindow(w);
 
		}
 
		break;
 

	
 
	case WE_ON_EDIT_TEXT: {
 
		if (e->edittext.str[0] != '\0') {
 
			_cmd_text = e->edittext.str;
 
			DoCommandP(0, WP(w, buildtrain_d).rename_engine, 0, NULL,
 
				CMD_RENAME_ENGINE | CMD_MSG(STR_9037_CAN_T_RENAME_ROAD_VEHICLE));
 
		}
 
	} break;
 

	
 
	case WE_RESIZE: {
 
		if (e->sizing.diff.y == 0)
ship_gui.c
Show inline comments
 
@@ -331,88 +331,88 @@ static void NewShipWndProc(Window *w, Wi
 

	
 
		// Setup scroll count
 
		{
 
			int count = 0;
 
			int num = NUM_SHIP_ENGINES;
 
			const Engine* e = GetEngine(SHIP_ENGINES_INDEX);
 

	
 
			do {
 
				if (HASBIT(e->player_avail, _local_player))
 
					count++;
 
			} while (++e,--num);
 
			SetVScrollCount(w, count);
 
		}
 

	
 
		DrawWindowWidgets(w);
 

	
 
		{
 
			int num = NUM_SHIP_ENGINES;
 
			const Engine* e = GetEngine(SHIP_ENGINES_INDEX);
 
			int x = 2;
 
			int y = 15;
 
			int sel = WP(w,buildtrain_d).sel_index;
 
			int pos = w->vscroll.pos;
 
			EngineID engine_id = SHIP_ENGINES_INDEX;
 
			int selected_id = -1;
 
			EngineID selected_id = INVALID_ENGINE;
 

	
 
			do {
 
				if (HASBIT(e->player_avail, _local_player)) {
 
					if (sel==0) selected_id = engine_id;
 
					if (IS_INT_INSIDE(--pos, -w->vscroll.cap, 0)) {
 
						DrawString(x+75, y+7, GetCustomEngineName(engine_id), sel==0 ? 0xC : 0x10);
 
						DrawShipEngine(x+35, y+10, engine_id, SPRITE_PALETTE(PLAYER_SPRITE_COLOR(_local_player)));
 
						y += 24;
 
					}
 
					sel--;
 
				}
 
			} while (++engine_id, ++e,--num);
 

	
 
			WP(w,buildtrain_d).sel_engine = selected_id;
 

	
 
			if (selected_id != -1) {
 
			if (selected_id != INVALID_ENGINE) {
 
				DrawShipPurchaseInfo(2, w->widget[4].top + 1, selected_id);
 
			}
 
		}
 
		break;
 

	
 
	case WE_CLICK:
 
		switch(e->click.widget) {
 
		case 2: { /* listbox */
 
			uint i = (e->click.pt.y - 14) / 24;
 
			if (i < w->vscroll.cap) {
 
				WP(w,buildtrain_d).sel_index = i + w->vscroll.pos;
 
				SetWindowDirty(w);
 
			}
 
		} break;
 
		case 5: { /* build */
 
			int sel_eng = WP(w,buildtrain_d).sel_engine;
 
			if (sel_eng != -1)
 
			EngineID sel_eng = WP(w,buildtrain_d).sel_engine;
 
			if (sel_eng != INVALID_ENGINE)
 
				DoCommandP(w->window_number, sel_eng, 0, CcBuildShip, CMD_BUILD_SHIP | CMD_MSG(STR_980D_CAN_T_BUILD_SHIP));
 
		} break;
 

	
 
		case 6:	{ /* rename */
 
			int sel_eng = WP(w,buildtrain_d).sel_engine;
 
			if (sel_eng != -1) {
 
			EngineID sel_eng = WP(w,buildtrain_d).sel_engine;
 
			if (sel_eng != INVALID_ENGINE) {
 
				WP(w,buildtrain_d).rename_engine = sel_eng;
 
				ShowQueryString(GetCustomEngineName(sel_eng),
 
					STR_9838_RENAME_SHIP_TYPE, 31, 160, w->window_class, w->window_number);
 
			}
 
		}	break;
 
		}
 
		break;
 

	
 
	case WE_4:
 
		if (w->window_number != 0 && !FindWindowById(WC_VEHICLE_DEPOT, w->window_number)) {
 
			DeleteWindow(w);
 
		}
 
		break;
 

	
 
	case WE_ON_EDIT_TEXT: {
 
		if (e->edittext.str[0] != '\0') {
 
			_cmd_text = e->edittext.str;
 
			DoCommandP(0, WP(w, buildtrain_d).rename_engine, 0, NULL,
 
				CMD_RENAME_ENGINE | CMD_MSG(STR_9839_CAN_T_RENAME_SHIP_TYPE));
 
		}
 
	} break;
 

	
 
	case WE_RESIZE:
 
		w->vscroll.cap += e->sizing.diff.y / 24;
signs.h
Show inline comments
 
/* $Id$ */
 

	
 
#ifndef SIGNS_H
 
#define SIGNS_H
 

	
 
#include "pool.h"
 

	
 
typedef struct SignStruct {
 
	StringID     str;
 
	ViewportSign sign;
 
	int32        x;
 
	int32        y;
 
	byte         z;
 
	byte owner; // placed by this player. Anyone can delete them though.
 
	PlayerID owner; // placed by this player. Anyone can delete them though.
 
							// OWNER_NONE for gray signs from old games.
 

	
 
	uint16       index;
 
} SignStruct;
 

	
 
extern MemoryPool _sign_pool;
 

	
 
/**
 
 * Check if a Sign really exists.
 
 */
 
static inline bool IsValidSign(const SignStruct* ss)
 
{
 
	return ss->str != 0;
 
}
 

	
 
/**
 
 * Get the pointer to the sign with index 'index'
 
 */
 
static inline SignStruct *GetSign(uint index)
 
{
 
	return (SignStruct*)GetItemFromPool(&_sign_pool, index);
 
}
 

	
 
/**
station.h
Show inline comments
 
@@ -102,53 +102,53 @@ enum {
 
//	HVOT_PENDING_DELETE = 1<<0, // not needed anymore
 
	HVOT_TRAIN = 1<<1,
 
	HVOT_BUS = 1 << 2,
 
	HVOT_TRUCK = 1 << 3,
 
	HVOT_AIRCRAFT = 1 << 4,
 
	HVOT_SHIP = 1 << 5,
 
	/* This bit is used to mark stations. No, it does not belong here, but what
 
	 * can we do? ;-) */
 
	HVOT_BUOY = 1 << 6
 
};
 

	
 
enum {
 
	CA_BUS = 3,
 
	CA_TRUCK = 3,
 
	CA_AIR_OILPAD = 3,
 
	CA_TRAIN = 4,
 
	CA_AIR_HELIPORT = 4,
 
	CA_AIR_SMALL = 4,
 
	CA_AIR_LARGE = 5,
 
	CA_DOCK = 5,
 
	CA_AIR_METRO = 6,
 
	CA_AIR_INTER = 8,
 
};
 

	
 
void ModifyStationRatingAround(TileIndex tile, byte owner, int amount, uint radius);
 
void ModifyStationRatingAround(TileIndex tile, PlayerID owner, int amount, uint radius);
 

	
 
TileIndex GetStationTileForVehicle(const Vehicle *v, const Station *st);
 

	
 
void ShowStationViewWindow(int station);
 
void ShowStationViewWindow(StationID station);
 
void UpdateAllStationVirtCoord(void);
 

	
 
VARDEF SortStruct *_station_sort;
 

	
 
extern MemoryPool _station_pool;
 

	
 
/**
 
 * Get the pointer to the station with index 'index'
 
 */
 
static inline Station *GetStation(StationID index)
 
{
 
	return (Station*)GetItemFromPool(&_station_pool, index);
 
}
 

	
 
/**
 
 * Get the current size of the StationPool
 
 */
 
static inline uint16 GetStationPoolSize(void)
 
{
 
	return _station_pool.total_items;
 
}
 

	
 
static inline bool IsStationIndex(uint index)
 
{
station_cmd.c
Show inline comments
 
@@ -158,71 +158,70 @@ static byte FindCatchmentRadius(Station 
 
{
 
	byte ret = 0;
 

	
 
	if (st->bus_stops != NULL)   ret = max(ret, CA_BUS);
 
	if (st->truck_stops != NULL) ret = max(ret, CA_TRUCK);
 
	if (st->train_tile) ret = max(ret, CA_TRAIN);
 
	if (st->dock_tile)  ret = max(ret, CA_DOCK);
 

	
 
	if (st->airport_tile) {
 
		switch (st->airport_type) {
 
			case AT_OILRIG:        ret = max(ret, CA_AIR_OILPAD);   break;
 
			case AT_SMALL:         ret = max(ret, CA_AIR_SMALL);    break;
 
			case AT_HELIPORT:      ret = max(ret, CA_AIR_HELIPORT); break;
 
			case AT_LARGE:         ret = max(ret, CA_AIR_LARGE);    break;
 
			case AT_METROPOLITAN:  ret = max(ret, CA_AIR_METRO);    break;
 
			case AT_INTERNATIONAL: ret = max(ret, CA_AIR_INTER);    break;
 
		}
 
	}
 

	
 
	return ret;
 
}
 

	
 
#define CHECK_STATIONS_ERR ((Station*)-1)
 

	
 
static Station *GetStationAround(TileIndex tile, int w, int h, int closest_station)
 
static Station* GetStationAround(TileIndex tile, int w, int h, StationID closest_station)
 
{
 
	// check around to see if there's any stations there
 
	BEGIN_TILE_LOOP(tile_cur, w + 2, h + 2, tile - TileDiffXY(1, 1))
 
		if (IsTileType(tile_cur, MP_STATION)) {
 
			int t;
 
			t = _m[tile_cur].m2;
 
			StationID t = _m[tile_cur].m2;
 
			{
 
				Station *st = GetStation(t);
 
				// you cannot take control of an oilrig!!
 
				if (st->airport_type == AT_OILRIG && st->facilities == (FACIL_AIRPORT|FACIL_DOCK))
 
					continue;
 
			}
 

	
 
			if (closest_station == -1) {
 
			if (closest_station == INVALID_STATION) {
 
				closest_station = t;
 
			} else if (closest_station != t) {
 
				_error_message = STR_3006_ADJOINS_MORE_THAN_ONE_EXISTING;
 
				return CHECK_STATIONS_ERR;
 
			}
 
		}
 
	END_TILE_LOOP(tile_cur, w + 2, h + 2, tile - TileDiffXY(1, 1))
 
	return (closest_station == -1) ? NULL : GetStation(closest_station);
 
	return (closest_station == INVALID_STATION) ? NULL : GetStation(closest_station);
 
}
 

	
 
TileIndex GetStationTileForVehicle(const Vehicle *v, const Station *st)
 
{
 
	switch (v->type) {
 
		case VEH_Train: 		return st->train_tile;
 
		case VEH_Aircraft:	return st->airport_tile;
 
		case VEH_Ship:			return st->dock_tile;
 
		case VEH_Road:
 
			if (v->cargo_type == CT_PASSENGERS) {
 
				if (st->bus_stops != NULL)
 
					return st->bus_stops->xy;
 
				else
 
					return 0;
 
			} else {
 
				if (st->truck_stops != NULL)
 
					return st->truck_stops->xy;
 
				else
 
					return 0;
 
			}
 
		default:
 
			assert(false);
 
			return 0;
 
	}
 
@@ -403,49 +402,49 @@ static bool GenerateStationName(Station 
 
			~( (1<<M(STR_SV_STNAME_WEST)) | (1<<M(STR_SV_STNAME_EAST)) | (1<<M(STR_SV_STNAME_NORTH)) ),
 
			~( (1<<M(STR_SV_STNAME_SOUTH)) | (1<<M(STR_SV_STNAME_WEST)) | (1<<M(STR_SV_STNAME_NORTH)) ),
 
			~( (1<<M(STR_SV_STNAME_SOUTH)) | (1<<M(STR_SV_STNAME_EAST)) | (1<<M(STR_SV_STNAME_NORTH)) ),
 
			~( (1<<M(STR_SV_STNAME_SOUTH)) | (1<<M(STR_SV_STNAME_WEST)) | (1<<M(STR_SV_STNAME_EAST)) ),
 
		};
 

	
 
		free_names &= _direction_and_table[
 
			(TileX(tile) < TileX(t->xy)) +
 
			(TileY(tile) < TileY(t->xy)) * 2];
 
	}
 

	
 
	tmp = free_names & ((1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<6)|(1<<7)|(1<<12)|(1<<26)|(1<<27)|(1<<28)|(1<<29)|(1<<30));
 
	if (tmp == 0) {
 
		_error_message = STR_3007_TOO_MANY_STATIONS_LOADING;
 
		return false;
 
	}
 
	found = FindFirstBit(tmp);
 

	
 
done:
 
	st->string_id = found + STR_SV_STNAME;
 
	return true;
 
}
 
#undef M
 

	
 
static Station *GetClosestStationFromTile(TileIndex tile, uint threshold, byte owner)
 
static Station* GetClosestStationFromTile(TileIndex tile, uint threshold, PlayerID owner)
 
{
 
	Station* best_station = NULL;
 
	Station* st;
 

	
 
	FOR_ALL_STATIONS(st) {
 
		if (st->xy != 0 && (owner == OWNER_SPECTATOR || st->owner == owner)) {
 
			uint cur_dist = DistanceManhattan(tile, st->xy);
 

	
 
			if (cur_dist < threshold) {
 
				threshold = cur_dist;
 
				best_station = st;
 
			}
 
		}
 
	}
 

	
 
	return best_station;
 
}
 

	
 
static void StationInitialize(Station *st, TileIndex tile)
 
{
 
	GoodsEntry *ge;
 

	
 
	st->xy = tile;
 
	st->airport_tile = st->dock_tile = st->train_tile = 0;
 
@@ -734,49 +733,49 @@ static void UpdateStationAcceptance(Stat
 
		} while (str++,(new_acc>>=1) != (old_acc>>=1));
 

	
 
		ShowRejectOrAcceptNews(st, accept, STR_3040_NOW_ACCEPTS);
 
		ShowRejectOrAcceptNews(st, reject, STR_303E_NO_LONGER_ACCEPTS);
 
	}
 

	
 
	// redraw the station view since acceptance changed
 
	InvalidateWindowWidget(WC_STATION_VIEW, st->index, 4);
 
}
 

	
 
// This is called right after a station was deleted.
 
// It checks if the whole station is free of substations, and if so, the station will be
 
// deleted after a little while.
 
static void DeleteStationIfEmpty(Station *st) {
 
	if (st->facilities == 0) {
 
		st->delete_ctr = 0;
 
		InvalidateWindow(WC_STATION_LIST, st->owner);
 
	}
 
}
 

	
 
static int32 ClearTile_Station(TileIndex tile, byte flags);
 

	
 
// Tries to clear the given area. Returns the cost in case of success.
 
// Or an error code if it failed.
 
int32 CheckFlatLandBelow(TileIndex tile, uint w, uint h, uint flags, uint invalid_dirs, int *station)
 
int32 CheckFlatLandBelow(TileIndex tile, uint w, uint h, uint flags, uint invalid_dirs, StationID* station)
 
{
 
	int32 cost = 0, ret;
 

	
 
	uint tileh;
 
	uint z;
 
	int allowed_z = -1;
 
	int flat_z;
 

	
 
	BEGIN_TILE_LOOP(tile_cur, w, h, tile)
 
		if (!EnsureNoVehicle(tile_cur))
 
			return CMD_ERROR;
 

	
 
		tileh = GetTileSlope(tile_cur, &z);
 

	
 
		/* Prohibit building if
 
			1) The tile is "steep" (i.e. stretches two height levels)
 
			-OR-
 
			2) The tile is non-flat if
 
				a) the player building is an "old-school" AI
 
				-OR-
 
				b) the build_on_slopes switch is disabled
 
		*/
 
		if (IsSteepTileh(tileh) ||
 
			((_is_old_ai_player || !_patches.build_on_slopes)
 
@@ -789,59 +788,59 @@ int32 CheckFlatLandBelow(TileIndex tile,
 
		flat_z = z;
 
		if (tileh) {
 
			// need to check so the entrance to the station is not pointing at a slope.
 
			if ((invalid_dirs&1 && !(tileh & 0xC) && (uint)w_cur == w) ||
 
					(invalid_dirs&2 && !(tileh & 6) &&	h_cur == 1) ||
 
					(invalid_dirs&4 && !(tileh & 3) && w_cur == 1) ||
 
					(invalid_dirs&8 && !(tileh & 9) && (uint)h_cur == h)) {
 
				_error_message = STR_0007_FLAT_LAND_REQUIRED;
 
				return CMD_ERROR;
 
			}
 
			cost += _price.terraform;
 
			flat_z += 8;
 
		}
 

	
 
		// get corresponding flat level and make sure that all parts of the station have the same level.
 
		if (allowed_z == -1) {
 
			// first tile
 
			allowed_z = flat_z;
 
		} else if (allowed_z != flat_z) {
 
			_error_message = STR_0007_FLAT_LAND_REQUIRED;
 
			return CMD_ERROR;
 
		}
 

	
 
		// if station is set, then we have special handling to allow building on top of already existing stations.
 
		// so station points to -1 if we can build on any station. or it points to a station if we're only allowed to build
 
		// so station points to INVALID_STATION if we can build on any station. or it points to a station if we're only allowed to build
 
		// on exactly that station.
 
		if (station != NULL && IsTileType(tile_cur, MP_STATION)) {
 
			if (_m[tile_cur].m5 >= 8) {
 
				_error_message = ClearTile_Station(tile_cur, DC_AUTO); // get error message
 
				return CMD_ERROR;
 
			} else {
 
				int st = _m[tile_cur].m2;
 
				if (*station == -1)
 
				StationID st = _m[tile_cur].m2;
 
				if (*station == INVALID_STATION) {
 
					*station = st;
 
				else if (*station != st) {
 
				} else if (*station != st) {
 
					_error_message = STR_3006_ADJOINS_MORE_THAN_ONE_EXISTING;
 
					return CMD_ERROR;
 
				}
 
			}
 
		} else {
 
			ret = DoCommandByTile(tile_cur, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 
			if (ret == CMD_ERROR) return CMD_ERROR;
 
			cost += ret;
 
		}
 
	END_TILE_LOOP(tile_cur, w, h, tile)
 

	
 
	return cost;
 
}
 

	
 
static bool CanExpandRailroadStation(Station *st, uint *fin, int direction)
 
{
 
	uint curw = st->trainst_w, curh = st->trainst_h;
 
	TileIndex tile = fin[0];
 
	uint w = fin[1];
 
	uint h = fin[2];
 

	
 
	if (_patches.nonuniform_stations) {
 
		// determine new size of train station region..
 
		int x = min(TileX(st->train_tile), TileX(tile));
 
@@ -931,83 +930,83 @@ static void GetStationLayout(byte *layou
 
		while (--numtracks >= 0) {
 
			layout = CreateMulti(layout, plat_len, 4);
 
			layout = CreateMulti(layout, plat_len, 6);
 
		}
 
	}
 
}
 

	
 
/** Build railroad station
 
 * @param x,y starting position of station dragging/placement
 
 * @param p1 various bitstuffed elements
 
 * - p1 = (bit  0)    - orientation (p1 & 1)
 
 * - p1 = (bit  8-15) - number of tracks
 
 * - p1 = (bit 16-23) - platform length
 
 * @param p2 various bitstuffed elements
 
 * - p2 = (bit  0- 3) - railtype (p2 & 0xF)
 
 * - p2 = (bit  4)    - set for custom station (p2 & 0x10)
 
 * - p2 = (bit  8-..) - custom station id (p2 >> 8)
 
 */
 
int32 CmdBuildRailroadStation(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	Station *st;
 
	TileIndex tile_org;
 
	int w_org, h_org;
 
	int32 cost, ret;
 
	int est;
 
	StationID est;
 
	int plat_len, numtracks;
 
	int direction;
 
	uint finalvalues[3];
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 

	
 
	tile_org = TileVirtXY(x, y);
 

	
 
	/* Does the authority allow this? */
 
	if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile_org)) return CMD_ERROR;
 
	if (!ValParamRailtype(p2 & 0xF)) return CMD_ERROR;
 

	
 
	/* unpack parameters */
 
	direction = p1 & 1;
 
	numtracks = GB(p1,  8, 8);
 
	plat_len  = GB(p1, 16, 8);
 
	/* w = length, h = num_tracks */
 
	if (direction) {
 
		h_org = plat_len;
 
		w_org = numtracks;
 
	} else {
 
		w_org = plat_len;
 
		h_org = numtracks;
 
	}
 

	
 
	if (h_org > _patches.station_spread || w_org > _patches.station_spread) return CMD_ERROR;
 

	
 
	// these values are those that will be stored in train_tile and station_platforms
 
	finalvalues[0] = tile_org;
 
	finalvalues[1] = w_org;
 
	finalvalues[2] = h_org;
 

	
 
	// Make sure the area below consists of clear tiles. (OR tiles belonging to a certain rail station)
 
	est = -1;
 
	est = INVALID_STATION;
 
	// If DC_EXEC is in flag, do not want to pass it to CheckFlatLandBelow, because of a nice bug
 
	//  for detail info, see: https://sourceforge.net/tracker/index.php?func=detail&aid=1029064&group_id=103924&atid=636365
 
	if (CmdFailed(ret = CheckFlatLandBelow(tile_org, w_org, h_org, flags&~DC_EXEC, 5 << direction, _patches.nonuniform_stations ? &est : NULL))) return CMD_ERROR;
 
	cost = ret + (numtracks * _price.train_station_track + _price.train_station_length) * plat_len;
 

	
 
	// Make sure there are no similar stations around us.
 
	st = GetStationAround(tile_org, w_org, h_org, est);
 
	if (st == CHECK_STATIONS_ERR) return CMD_ERROR;
 

	
 
	// See if there is a deleted station close to us.
 
	if (st == NULL) {
 
		st = GetClosestStationFromTile(tile_org, 8, _current_player);
 
		if (st != NULL && st->facilities) st = NULL;
 
	}
 

	
 
	if (st != NULL) {
 
		// Reuse an existing station.
 
		if (st->owner != OWNER_NONE && st->owner != _current_player)
 
			return_cmd_error(STR_3009_TOO_CLOSE_TO_ANOTHER_STATION);
 

	
 
		if (st->train_tile != 0) {
 
			// check if we want to expanding an already existing station?
 
			if (_is_old_ai_player || !_patches.join_stations)
 
				return_cmd_error(STR_3005_TOO_CLOSE_TO_ANOTHER_RAILROAD);
 
@@ -1169,50 +1168,51 @@ int32 CmdRemoveFromRailroadStation(int x
 
	if (!IsTileType(tile, MP_STATION) || _m[tile].m5 >= 8 || !_patches.nonuniform_stations) return CMD_ERROR;
 
	st = GetStation(_m[tile].m2);
 
	if (_current_player != OWNER_WATER && (!CheckOwnership(st->owner) || !EnsureNoVehicle(tile))) return CMD_ERROR;
 

	
 
	// if we reached here, it means we can actually delete it. do that.
 
	if (flags & DC_EXEC) {
 
		DoClearSquare(tile);
 
		// now we need to make the "spanned" area of the railway station smaller if we deleted something at the edges.
 
		// we also need to adjust train_tile.
 
		MakeRailwayStationAreaSmaller(st);
 

	
 
		// if we deleted the whole station, delete the train facility.
 
		if (st->train_tile == 0) {
 
			st->facilities &= ~FACIL_TRAIN;
 
			UpdateStationVirtCoordDirty(st);
 
			DeleteStationIfEmpty(st);
 
		}
 
	}
 
	return _price.remove_rail_station;
 
}
 

	
 
// determine the number of platforms for the station
 
uint GetStationPlatforms(const Station *st, TileIndex tile)
 
{
 
	uint t;
 
	int dir,delta;
 
	TileIndex t;
 
	TileIndexDiff delta;
 
	int dir;
 
	int len;
 
	assert(TileBelongsToRailStation(st, tile));
 

	
 
	len = 0;
 
	dir = _m[tile].m5&1;
 
	delta = dir ? TileDiffXY(0, 1) : TileDiffXY(1, 0);
 

	
 
	// find starting tile..
 
	t = tile;
 
	do { t -= delta; len++; } while (TileBelongsToRailStation(st, t) && (_m[t].m5&1) == dir);
 

	
 
	// find ending tile
 
	t = tile;
 
	do { t += delta; len++; }while (TileBelongsToRailStation(st, t) && (_m[t].m5&1) == dir);
 

	
 
	return len - 1;
 
}
 

	
 

	
 
/* TODO: Custom classes! */
 
/* Indexed by class, just STAT_CLASS_DFLT and STAT_CLASS_WAYP supported. */
 
static int _statspec_highest_id[2] = {-1, -1};
 
static StationSpec _station_spec[2][256];
 

	
 
@@ -2116,49 +2116,49 @@ static int32 RemoveDock(Station *st, uin
 
		UpdateStationVirtCoordDirty(st);
 
		DeleteStationIfEmpty(st);
 
	}
 

	
 
	return _price.remove_dock;
 
}
 

	
 
#include "table/station_land.h"
 

	
 

	
 
extern uint16 _custom_sprites_base;
 

	
 
static void DrawTile_Station(TileInfo *ti)
 
{
 
	uint32 image_or_modificator;
 
	uint32 image;
 
	const DrawTileSeqStruct *dtss;
 
	const DrawTileSprites *t = NULL;
 
	byte railtype = GB(_m[ti->tile].m3, 0, 4);
 
	const RailtypeInfo *rti = GetRailTypeInfo(railtype);
 
	SpriteID offset;
 
	uint32 relocation = 0;
 

	
 
	{
 
		uint owner = GetTileOwner(ti->tile);
 
		PlayerID owner = GetTileOwner(ti->tile);
 
		image_or_modificator = PALETTE_TO_GREY; /* NOTE: possible bug in ttd here? */
 
		if (owner < MAX_PLAYERS)
 
			image_or_modificator = PLAYER_SPRITE_COLOR(owner);
 
	}
 

	
 
	// don't show foundation for docks (docks are between 76 (0x4C) and 81 (0x51))
 
	if (ti->tileh != 0 && (ti->map5 < 0x4C || ti->map5 > 0x51))
 
		DrawFoundation(ti, ti->tileh);
 

	
 
	if (_m[ti->tile].m3 & 0x10) {
 
		// look for customization
 
		StationSpec *statspec = GetCustomStation(STAT_CLASS_DFLT, _m[ti->tile].m4);
 

	
 
		//debug("Cust-o-mized %p", statspec);
 

	
 
		if (statspec != NULL) {
 
			Station *st = GetStation(_m[ti->tile].m2);
 

	
 
			relocation = GetCustomStationRelocation(statspec, st, 0);
 
			//debug("Relocation %d", relocation);
 
			t = &statspec->renderdata[ti->map5];
 
		}
 
	}
 

	
 
@@ -2659,49 +2659,49 @@ void OnTick_Station(void)
 

	
 
	if (_game_mode == GM_EDITOR)
 
		return;
 

	
 
	i = _station_tick_ctr;
 
	if (++_station_tick_ctr == GetStationPoolSize())
 
		_station_tick_ctr = 0;
 

	
 
	st = GetStation(i);
 
	if (st->xy != 0)
 
		StationHandleBigTick(st);
 

	
 
	FOR_ALL_STATIONS(st) {
 
		if (st->xy != 0)
 
			StationHandleSmallTick(st);
 
	}
 

	
 
}
 

	
 
void StationMonthlyLoop(void)
 
{
 
}
 

	
 

	
 
void ModifyStationRatingAround(TileIndex tile, byte owner, int amount, uint radius)
 
void ModifyStationRatingAround(TileIndex tile, PlayerID owner, int amount, uint radius)
 
{
 
	Station *st;
 
	GoodsEntry *ge;
 
	int i;
 

	
 
	FOR_ALL_STATIONS(st) {
 
		if (st->xy != 0 && st->owner == owner &&
 
				DistanceManhattan(tile, st->xy) <= radius) {
 
			ge = st->goods;
 
			for(i=0; i!=NUM_CARGO; i++,ge++) {
 
				if (ge->enroute_from != INVALID_STATION) {
 
					ge->rating = clamp(ge->rating + amount, 0, 255);
 
				}
 
			}
 
		}
 
	}
 
}
 

	
 
static void UpdateStationWaiting(Station *st, int type, uint amount)
 
{
 
	st->goods[type].waiting_acceptance =
 
		(st->goods[type].waiting_acceptance & ~0xFFF) +
 
			min(0xFFF, (st->goods[type].waiting_acceptance & 0xFFF) + amount);
 

	
station_gui.c
Show inline comments
 
@@ -91,147 +91,147 @@ static void GlobalSortStationList(void)
 
		error("Could not allocate memory for the station-sorting-list");
 

	
 
	FOR_ALL_STATIONS(st) {
 
		if(st->xy && st->owner != OWNER_NONE) {
 
			_station_sort[n].index = st->index;
 
			_station_sort[n++].owner = st->owner;
 
			_num_station_sort[st->owner]++; // add number of stations of player
 
		}
 
	}
 

	
 
	// create cumulative station-ownership
 
	// stations are stored as a cummulative index, eg 25, 41, 43. This means
 
	// Player0: 25; Player1: (41-25) 16; Player2: (43-41) 2
 
	for (i = &_num_station_sort[1]; i != endof(_num_station_sort); i++) {*i += *(i-1);}
 

	
 
	qsort(_station_sort, n, sizeof(_station_sort[0]), GeneralOwnerSorter); // sort by owner
 

	
 
	// since indexes are messed up after adding/removing a station, mark all lists dirty
 
	memset(_station_sort_dirty, true, sizeof(_station_sort_dirty));
 
	_global_station_sort_dirty = false;
 

	
 
	DEBUG(misc, 1) ("Resorting global station list...");
 
}
 

	
 
static void MakeSortedStationList(byte owner)
 
static void MakeSortedStationList(PlayerID owner)
 
{
 
	SortStruct *firstelement;
 
	uint32 n = 0;
 

	
 
	if (owner == 0) { // first element starts at 0th element and has n elements as described above
 
		firstelement = &_station_sort[0];
 
		n = _num_station_sort[0];
 
	} else { // nth element starts at the end of the previous one, and has n elements as described above
 
		firstelement = &_station_sort[_num_station_sort[owner - 1]];
 
		n = _num_station_sort[owner] - _num_station_sort[owner - 1];
 
	}
 

	
 
	_last_station_idx = 0; // used for "cache" in namesorting
 
	qsort(firstelement, n, sizeof(_station_sort[0]), StationNameSorter); // sort by name
 

	
 
	_station_sort_dirty[owner] = false;
 

	
 
	DEBUG(misc, 1) ("Resorting Stations list player %d...", owner+1);
 
}
 

	
 
static void PlayerStationsWndProc(Window *w, WindowEvent *e)
 
{
 
	switch(e->event) {
 
	case WE_PAINT: {
 
		const PlayerID owner = w->window_number;
 
		uint32 i;
 
		const byte window_number = (byte)w->window_number;
 

	
 
		// resort station window if stations have been added/removed
 
		if (_global_station_sort_dirty)
 
			GlobalSortStationList();
 

	
 
		if (_station_sort_dirty[window_number]) { // resort in case of a station rename.
 
			MakeSortedStationList(window_number);
 
		if (_station_sort_dirty[owner]) { // resort in case of a station rename.
 
			MakeSortedStationList(owner);
 
		}
 

	
 
		// stations are stored as a cummulative index, eg 25, 41, 43. This means
 
		// Player0: 25; Player1: (41-25) 16; Player2: (43-41) 2 stations
 
		i = (window_number == 0) ? 0 : _num_station_sort[window_number-1];
 
		SetVScrollCount(w, _num_station_sort[window_number] - i);
 
		i = (owner == 0) ? 0 : _num_station_sort[owner - 1];
 
		SetVScrollCount(w, _num_station_sort[owner] - i);
 

	
 
		/* draw widgets, with player's name in the caption */
 
		{
 
			Player *p = GetPlayer(window_number);
 
			const Player* p = GetPlayer(owner);
 
			SetDParam(0, p->name_1);
 
			SetDParam(1, p->name_2);
 
			SetDParam(2, w->vscroll.count);
 
			DrawWindowWidgets(w);
 
		}
 

	
 
		{
 
			byte p = 0;
 
			Station *st;
 
			int x,xb = 2;
 
			int y = 16; // offset from top of widget
 
			int j;
 

	
 
			if (w->vscroll.count == 0) { // player has no stations
 
				DrawString(xb, y, STR_304A_NONE, 0);
 
				return;
 
			}
 

	
 
			i += w->vscroll.pos; // offset from sorted station list of current player
 
			assert(i < _num_station_sort[window_number]); // at least one station must exist
 
			assert(i < _num_station_sort[owner]); // at least one station must exist
 

	
 
			while (i < _num_station_sort[window_number]) { // do until max number of stations of owner
 
			while (i < _num_station_sort[owner]) { // do until max number of stations of owner
 
				st = GetStation(_station_sort[i].index);
 

	
 
				assert(st->xy && st->owner == window_number);
 
				assert(st->xy && st->owner == owner);
 

	
 
				SetDParam(0, st->index);
 
				SetDParam(1, st->facilities);
 
				x = DrawString(xb, y, STR_3049_0, 0) + 5;
 

	
 
				// show cargo waiting and station ratings
 
				for(j=0; j!=NUM_CARGO; j++) {
 
					int acc = (st->goods[j].waiting_acceptance & 0xFFF);
 
					if (acc != 0) {
 
						StationsWndShowStationRating(x, y, j, acc, st->goods[j].rating);
 
						x += 10;
 
					}
 
				}
 
				y += 10;
 
				i++; // next station
 
				if (++p == w->vscroll.cap) { break;} // max number of stations in 1 window
 
			}
 
		}
 
	} break;
 
	case WE_CLICK: {
 
		switch(e->click.widget) {
 
		case 3: {
 
			uint32 id_v = (e->click.pt.y - 15) / 10;
 

	
 
			if (id_v >= w->vscroll.cap) { return;} // click out of bounds
 

	
 
			id_v += w->vscroll.pos;
 

	
 
			{
 
				const byte owner = (byte)w->window_number;
 
				const PlayerID owner = w->window_number;
 
				Station *st;
 
				id_v += (owner == 0) ? 0 : _num_station_sort[owner - 1]; // first element in list
 

	
 
				if (id_v >= _num_station_sort[owner]) { return;} // click out of station bound
 

	
 
				st = GetStation(_station_sort[id_v].index);
 

	
 
				assert(st->xy && st->owner == owner);
 

	
 
				ScrollMainWindowToTile(st->xy);
 
			}
 
		} break;
 
		}
 
	} break;
 

	
 
	case WE_4:
 
		WP(w,plstations_d).refresh_counter++;
 
		if (WP(w,plstations_d).refresh_counter==5) {
 
			WP(w,plstations_d).refresh_counter = 0;
 
			SetWindowDirty(w);
 
		}
 
		break;
 

	
 
	case WE_RESIZE:
 
@@ -295,53 +295,53 @@ static const Widget _station_view_widget
 
{    WWT_CAPTION,   RESIZE_NONE,    14,    11,   236,     0,    13, STR_300A_0,	STR_018C_WINDOW_TITLE_DRAG_THIS},
 
{  WWT_STICKYBOX,   RESIZE_NONE,    14,   237,   248,     0,    13, 0x0,         STR_STICKY_BUTTON},
 
{     WWT_IMGBTN,   RESIZE_NONE,    14,     0,   236,    14,    65, 0x0,					STR_NULL},
 
{  WWT_SCROLLBAR,   RESIZE_NONE,    14,   237,   248,    14,    65, 0x0,					STR_0190_SCROLL_BAR_SCROLLS_LIST},
 
{     WWT_IMGBTN,   RESIZE_NONE,    14,     0,   248,    66,    97, 0x0,					STR_NULL},
 
{      WWT_EMPTY,   RESIZE_NONE,     0,     0,     0,     0,     0, 0x0,					STR_NULL},
 
{ WWT_PUSHTXTBTN,   RESIZE_NONE,    14,     0,    63,    98,   109, STR_00E4_LOCATION,	STR_3053_CENTER_MAIN_VIEW_ON_STATION},
 
{ WWT_PUSHTXTBTN,   RESIZE_NONE,    14,    64,   128,    98,   109, STR_3032_RATINGS,	STR_3054_SHOW_STATION_RATINGS},
 
{ WWT_PUSHTXTBTN,   RESIZE_NONE,    14,   129,   192,    98,   109, STR_0130_RENAME,		STR_3055_CHANGE_NAME_OF_STATION},
 
{ WWT_PUSHTXTBTN,   RESIZE_NONE,    14,   193,   206,    98,   109, STR_TRAIN, STR_SCHEDULED_TRAINS_TIP },
 
{ WWT_PUSHTXTBTN,   RESIZE_NONE,    14,   207,   220,    98,   109, STR_LORRY, STR_SCHEDULED_ROAD_VEHICLES_TIP },
 
{ WWT_PUSHTXTBTN,   RESIZE_NONE,    14,   221,   234,    98,   109, STR_PLANE, STR_SCHEDULED_AIRCRAFT_TIP },
 
{ WWT_PUSHTXTBTN,   RESIZE_NONE,    14,   235,   248,    98,   109, STR_SHIP, STR_SCHEDULED_SHIPS_TIP },
 
{   WIDGETS_END},
 
};
 

	
 
static void DrawStationViewWindow(Window *w)
 
{
 
	Station *st;
 
	int i;
 
	int num;
 
	int x,y;
 
	int pos;
 
	StringID str;
 
	uint16 station_id;
 
	StationID station_id;
 

	
 
	station_id = w->window_number;
 

	
 
	st = GetStation(w->window_number);
 
	st = GetStation(station_id);
 

	
 
	num = 1;
 
	for(i=0; i!=NUM_CARGO; i++) {
 
		if ((st->goods[i].waiting_acceptance & 0xFFF) != 0) {
 
			num++;
 
			if (st->goods[i].enroute_from != station_id)
 
				num++;
 
		}
 
	}
 
	SetVScrollCount(w, num);
 

	
 
	w->disabled_state = st->owner == _local_player ? 0 : (1 << 9);
 

	
 
	if (!(st->facilities & FACIL_TRAIN)) SETBIT(w->disabled_state,  10);
 
	if (!(st->facilities & FACIL_TRUCK_STOP) &&
 
			!(st->facilities & FACIL_BUS_STOP)) SETBIT(w->disabled_state, 11);
 
	if (!(st->facilities & FACIL_AIRPORT)) SETBIT(w->disabled_state, 12);
 
	if (!(st->facilities & FACIL_DOCK)) SETBIT(w->disabled_state, 13);
 

	
 
	SetDParam(0, st->index);
 
	SetDParam(1, st->facilities);
 
	DrawWindowWidgets(w);
 

	
 
	x = 2;
 
@@ -512,37 +512,37 @@ static void StationViewWndProc(Window *w
 
	} break;
 

	
 
	case WE_DESTROY: {
 
		WindowNumber wno =
 
			(w->window_number << 16) | GetStation(w->window_number)->owner;
 

	
 
		DeleteWindowById(WC_TRAINS_LIST, wno);
 
		DeleteWindowById(WC_ROADVEH_LIST, wno);
 
		DeleteWindowById(WC_SHIPS_LIST, wno);
 
		DeleteWindowById(WC_AIRCRAFT_LIST, wno);
 
		break;
 
	}
 
	}
 
}
 

	
 

	
 
static const WindowDesc _station_view_desc = {
 
	-1, -1, 249, 110,
 
	WC_STATION_VIEW,0,
 
	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON,
 
	_station_view_widgets,
 
	StationViewWndProc
 
};
 

	
 
void ShowStationViewWindow(int station)
 
void ShowStationViewWindow(StationID station)
 
{
 
	Window *w;
 
	byte color;
 

	
 
	w = AllocateWindowDescFront(&_station_view_desc, station);
 
	if (w) {
 
		color = GetStation(w->window_number)->owner;
 
		if (color != 0x10)
 
			w->caption_color = color;
 
		w->vscroll.cap = 5;
 
	}
 
}
town.h
Show inline comments
 
@@ -11,49 +11,49 @@ struct Town {
 

	
 
	// Current population of people and amount of houses.
 
	uint16 num_houses;
 
	uint32 population;
 

	
 
	// Town name
 
	uint16 townnametype;
 
	uint32 townnameparts;
 

	
 
	// NOSAVE: Location of name sign, UpdateTownVirtCoord updates this.
 
	ViewportSign sign;
 

	
 
	// Makes sure we don't build certain house types twice.
 
	byte flags12;
 

	
 
	// Which players have a statue?
 
	byte statues;
 

	
 
	// Sort index in listings
 
	byte sort_index_obsolete;
 

	
 
	// Player ratings as well as a mask that determines which players have a rating.
 
	byte have_ratings;
 
	uint8 unwanted[MAX_PLAYERS]; // how many months companies aren't wanted by towns (bribe)
 
	uint8 exclusivity;	     // which player has exslusivity
 
	PlayerID exclusivity;        // which player has exslusivity
 
	uint8 exclusive_counter;     // months till the exclusivity expires
 
	int16 ratings[MAX_PLAYERS];
 

	
 
	// Maximum amount of passengers and mail that can be transported.
 
	uint32 max_pass;
 
	uint32 max_mail;
 
	uint32 new_max_pass;
 
	uint32 new_max_mail;
 
	uint32 act_pass;
 
	uint32 act_mail;
 
	uint32 new_act_pass;
 
	uint32 new_act_mail;
 

	
 
	// Amount of passengers that were transported.
 
	byte pct_pass_transported;
 
	byte pct_mail_transported;
 

	
 
	// Amount of food and paper that was transported. Actually a bit mask would be enough.
 
	uint16 act_food;
 
	uint16 act_water;
 
	uint16 new_act_food;
 
	uint16 new_act_water;
 

	
 
	// Time until we rebuild a house.
town_cmd.c
Show inline comments
 
@@ -761,49 +761,49 @@ static int GrowTownAtRoad(Town *t, TileI
 
	} while (--_grow_town_result >= 0);
 

	
 
	return (_grow_town_result == -2);
 
}
 

	
 
// Generate a random road block
 
// The probability of a straight road
 
// is somewhat higher than a curved.
 
static int GenRandomRoadBits(void)
 
{
 
	uint32 r = Random();
 
	uint a = GB(r, 0, 2);
 
	uint b = GB(r, 8, 2);
 
	if (a == b) b ^= 2;
 
	return (1 << a) + (1 << b);
 
}
 

	
 
// Grow the town
 
// Returns true if a house was built, or no if the build failed.
 
bool GrowTown(Town *t)
 
{
 
	TileIndex tile;
 
	const TileIndexDiffC *ptr;
 
	TileInfo ti;
 
	byte old_player;
 
	PlayerID old_player;
 

	
 
	static const TileIndexDiffC _town_coord_mod[] = {
 
		{-1,  0},
 
		{ 1,  1},
 
		{ 1, -1},
 
		{-1, -1},
 
		{-1,  0},
 
		{ 0,  2},
 
		{ 2,  0},
 
		{ 0, -2},
 
		{-1, -1},
 
		{-2,  2},
 
		{ 2,  2},
 
		{ 2, -2},
 
		{ 0,  0}
 
	};
 

	
 
	// Current player is a town
 
	old_player = _current_player;
 
	_current_player = OWNER_TOWN;
 

	
 
	// Find a road that we can base the construction on.
 
	tile = t->xy;
 
	for (ptr = _town_coord_mod; ptr != endof(_town_coord_mod); ++ptr) {
 
@@ -1557,49 +1557,49 @@ static void TownActionAdvertise(Town *t,
 
	ModifyStationRatingAround(t->xy, _current_player,
 
		_advertising_amount[action],
 
		_advertising_radius[action]);
 
}
 

	
 
static void TownActionRoadRebuild(Town *t, int action)
 
{
 
	Player *p;
 

	
 
	t->road_build_months = 6;
 

	
 
	SetDParam(0, t->index);
 

	
 
	p = GetPlayer(_current_player);
 
	SetDParam(1, p->name_1);
 
	SetDParam(2, p->name_2);
 

	
 
	AddNewsItem(STR_2055_TRAFFIC_CHAOS_IN_ROAD_REBUILDING,
 
		NEWS_FLAGS(NM_NORMAL, NF_TILE, NT_GENERAL, 0), t->xy, 0);
 
}
 

	
 
static bool DoBuildStatueOfCompany(TileIndex tile)
 
{
 
	TileInfo ti;
 
	byte old;
 
	PlayerID old;
 
	int32 r;
 

	
 
	FindLandscapeHeightByTile(&ti, tile);
 
	if (ti.tileh != 0)
 
		return false;
 

	
 
	if (ti.type != MP_HOUSE && ti.type != MP_CLEAR && ti.type != MP_TREES)
 
		return false;
 

	
 

	
 
	old = _current_player;
 
	_current_player = OWNER_NONE;
 
	r = DoCommandByTile(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
 
	_current_player = old;
 

	
 
	if (r == CMD_ERROR)
 
		return false;
 

	
 
	ModifyTile(tile, MP_SETTYPE(MP_UNMOVABLE) | MP_MAPOWNER_CURRENT | MP_MAP5,
 
		2 /* map5 */
 
	);
 

	
 
	return true;
 
}
train_gui.c
Show inline comments
 
@@ -152,49 +152,49 @@ void CcBuildLoco(bool success, TileIndex
 

	
 
	if (!success)
 
		return;
 

	
 
	v = GetVehicle(_new_train_id);
 
	if (tile == _backup_orders_tile) {
 
		_backup_orders_tile = 0;
 
		RestoreVehicleOrders(v, _backup_orders_data);
 
	}
 
	ShowTrainViewWindow(v);
 
}
 

	
 
void CcCloneTrain(bool success, uint tile, uint32 p1, uint32 p2)
 
{
 
	Vehicle *v;
 

	
 
	if (!success)
 
		return;
 

	
 
	v = GetVehicle(_new_train_id);
 
	ShowTrainViewWindow(v);
 
}
 

	
 
static void engine_drawing_loop(int *x, int *y, int *pos, int *sel,
 
	int *selected_id, byte railtype, byte show_max, bool is_engine)
 
	EngineID* selected_id, byte railtype, byte show_max, bool is_engine)
 
{
 
	EngineID i;
 

	
 
	for (i = 0; i < NUM_TRAIN_ENGINES; i++) {
 
		const Engine *e = GetEngine(i);
 
		const RailVehicleInfo *rvi = RailVehInfo(i);
 

	
 
		if (!IsCompatibleRail(railtype, e->railtype) || !(rvi->flags & RVI_WAGON) != is_engine ||
 
				!HASBIT(e->player_avail, _local_player))
 
			continue;
 

	
 
		if (*sel == 0)
 
			*selected_id = i;
 

	
 
		if (IS_INT_INSIDE(--*pos, -show_max, 0)) {
 
			DrawString(*x + 59, *y + 2, GetCustomEngineName(i), *sel == 0 ? 0xC : 0x10);
 
			DrawTrainEngine(*x + 29, *y + 6 + _traininfo_vehicle_pitch, i,
 
				SPRITE_PALETTE(PLAYER_SPRITE_COLOR(_local_player)));
 
			*y += 14;
 
		}
 
		--*sel;
 
	}
 
}
 

	
 
@@ -208,92 +208,91 @@ static void NewRailVehicleWndProc(Window
 

	
 
		{
 
			int count = 0;
 
			byte railtype = WP(w,buildtrain_d).railtype;
 
			EngineID i;
 

	
 
			for (i = 0; i < NUM_TRAIN_ENGINES; i++) {
 
				const Engine *e = GetEngine(i);
 
				if (IsCompatibleRail(railtype, e->railtype)
 
				    && HASBIT(e->player_avail, _local_player))
 
					count++;
 
			}
 
			SetVScrollCount(w, count);
 
		}
 

	
 
		SetDParam(0, WP(w,buildtrain_d).railtype + STR_881C_NEW_RAIL_VEHICLES);
 
		DrawWindowWidgets(w);
 

	
 
		{
 
			byte railtype = WP(w,buildtrain_d).railtype;
 
			int sel = WP(w,buildtrain_d).sel_index;
 
			int pos = w->vscroll.pos;
 
			int x = 1;
 
			int y = 15;
 
			int selected_id = -1;
 
			EngineID selected_id = INVALID_ENGINE;
 

	
 
			/* Ensure that custom engines which substituted wagons
 
			 * are sorted correctly.
 
			 * XXX - DO NOT EVER DO THIS EVER AGAIN! GRRR hacking in wagons as
 
			 * engines to get more types.. Stays here until we have our own format
 
			 * then it is exit!!! */
 
			engine_drawing_loop(&x, &y, &pos, &sel, &selected_id, railtype, w->vscroll.cap, true); // True engines
 
			engine_drawing_loop(&x, &y, &pos, &sel, &selected_id, railtype, w->vscroll.cap, false); // Feeble wagons
 

	
 
			WP(w,buildtrain_d).sel_engine = selected_id;
 

	
 
			if (selected_id != -1) {
 
			if (selected_id != INVALID_ENGINE) {
 
				const RailVehicleInfo *rvi = RailVehInfo(selected_id);
 

	
 
				if (!(rvi->flags & RVI_WAGON)) {
 
					/* it's an engine */
 
					DrawTrainEnginePurchaseInfo(2, w->widget[4].top + 1,selected_id);
 
				} else {
 
					/* it's a wagon */
 
					DrawTrainWagonPurchaseInfo(2, w->widget[4].top + 1, selected_id);
 
				}
 
			}
 
		}
 
	break;
 

	
 
	case WE_CLICK: {
 
		switch(e->click.widget) {
 
		case 2: {
 
			uint i = (e->click.pt.y - 14) / 14;
 
			if (i < w->vscroll.cap) {
 
				WP(w,buildtrain_d).sel_index = i + w->vscroll.pos;
 
				SetWindowDirty(w);
 
			}
 
		} break;
 
		case 5: {
 
			int sel_eng;
 
			sel_eng = WP(w,buildtrain_d).sel_engine;
 
			if (sel_eng != -1)
 
			EngineID sel_eng = WP(w,buildtrain_d).sel_engine;
 
			if (sel_eng != INVALID_ENGINE)
 
				DoCommandP(w->window_number, sel_eng, 0, (RailVehInfo(sel_eng)->flags & RVI_WAGON) ? CcBuildWagon : CcBuildLoco, CMD_BUILD_RAIL_VEHICLE | CMD_MSG(STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE));
 
		}	break;
 
		case 6: { /* rename */
 
			int sel_eng = WP(w,buildtrain_d).sel_engine;
 
			if (sel_eng != -1) {
 
			EngineID sel_eng = WP(w,buildtrain_d).sel_engine;
 
			if (sel_eng != INVALID_ENGINE) {
 
				WP(w,buildtrain_d).rename_engine = sel_eng;
 
				ShowQueryString(GetCustomEngineName(sel_eng),
 
					STR_886A_RENAME_TRAIN_VEHICLE_TYPE, 31, 160, w->window_class, w->window_number);
 
			}
 
		} break;
 
		}
 
	} break;
 

	
 
	case WE_4:
 
		if (w->window_number != 0 && !FindWindowById(WC_VEHICLE_DEPOT, w->window_number)) {
 
			DeleteWindow(w);
 
		}
 
		break;
 

	
 
	case WE_ON_EDIT_TEXT: {
 
		if (e->edittext.str[0] != '\0') {
 
			_cmd_text = e->edittext.str;
 
			DoCommandP(0, WP(w,buildtrain_d).rename_engine, 0, NULL,
 
				CMD_RENAME_ENGINE | CMD_MSG(STR_886B_CAN_T_RENAME_TRAIN_VEHICLE));
 
		}
 
	} break;
 

	
 
	case WE_RESIZE: {
 
		if (e->sizing.diff.y == 0)
vehicle.c
Show inline comments
 
@@ -313,49 +313,49 @@ void *VehicleFromPos(TileIndex tile, voi
 

	
 
		y = (y + 0x40) & ((0x3F) << 6);
 
	}
 
	return NULL;
 
}
 

	
 

	
 

	
 
void UpdateVehiclePosHash(Vehicle *v, int x, int y)
 
{
 
	VehicleID *old_hash, *new_hash;
 
	int old_x = v->left_coord;
 
	int old_y = v->top_coord;
 
	Vehicle *u;
 

	
 
	new_hash = (x == INVALID_COORD) ? NULL : &_vehicle_position_hash[GEN_HASH(x,y)];
 
	old_hash = (old_x == INVALID_COORD) ? NULL : &_vehicle_position_hash[GEN_HASH(old_x, old_y)];
 

	
 
	if (old_hash == new_hash)
 
		return;
 

	
 
	/* remove from hash table? */
 
	if (old_hash != NULL) {
 
		Vehicle *last = NULL;
 
		int idx = *old_hash;
 
		VehicleID idx = *old_hash;
 
		while ((u = GetVehicle(idx)) != v) {
 
			idx = u->next_hash;
 
			assert(idx != INVALID_VEHICLE);
 
			last = u;
 
		}
 

	
 
		if (last == NULL)
 
			*old_hash = v->next_hash;
 
		else
 
			last->next_hash = v->next_hash;
 
	}
 

	
 
	/* insert into hash table? */
 
	if (new_hash != NULL) {
 
		v->next_hash = *new_hash;
 
		*new_hash = v->index;
 
	}
 
}
 

	
 
void InitializeVehicles(void)
 
{
 
	int i;
 

	
 
	/* Clean the vehicle pool, and reserve enough blocks
 
@@ -1437,49 +1437,49 @@ int32 ReplaceVehicle(Vehicle *v)
 
				if ( first->engine_type != new_engine_type ) return CMD_ERROR;
 
			}
 

	
 
			// checks if the engine is the first one
 
			if ( v->u.rail.first_engine == INVALID_VEHICLE ) {
 
				if ( RailVehInfo(new_engine_type)->flags & RVI_MULTIHEAD ) {
 
					if ( u->engine_type == old_engine_type && v->next != NULL) {
 
						rear_engine_cost = build_cost - u->value;
 
					} else {
 
						rear_engine_cost = build_cost;
 
					}
 
				} else {
 
					if ( u->engine_type == old_engine_type && RailVehInfo(old_engine_type)->flags & RVI_MULTIHEAD) {
 
						if (v->next != NULL) rear_engine_cost = -(int32)u->value;
 
					}
 
				}
 
			 }
 
		}
 
	}
 

	
 
	/* Check if there is money for the upgrade.. if not, give a nice news-item
 
	    (that is needed, because this CMD is called automaticly) */
 
	if ( p->money64 < (int32)(p->engine_renew_money + build_cost + rear_engine_cost - v->value)) {
 
		if (( _local_player == v->owner ) && ( v->unitnumber != 0 )) {  //v->unitnumber = 0 for train cars
 
			int message;
 
			StringID message;
 
			SetDParam(0, v->unitnumber);
 
			switch (v->type) {
 
				case VEH_Train:    message = STR_TRAIN_AUTORENEW_FAILED;       break;
 
				case VEH_Road:     message = STR_ROADVEHICLE_AUTORENEW_FAILED; break;
 
				case VEH_Ship:     message = STR_SHIP_AUTORENEW_FAILED;        break;
 
				case VEH_Aircraft: message = STR_AIRCRAFT_AUTORENEW_FAILED;    break;
 
				// This should never happen
 
				default: message = 0; break;
 
			}
 

	
 
			AddNewsItem(message, NEWS_FLAGS(NM_SMALL, NF_VIEWPORT|NF_VEHICLE, NT_ADVICE, 0), v->index, 0);
 
		}
 

	
 
		return CMD_ERROR;
 
	}
 
	cost = build_cost - v->value + rear_engine_cost;
 

	
 
	/* We do not really buy a new vehicle, we upgrade the old one */
 
	e = GetEngine(new_engine_type);
 

	
 
	v->reliability = e->reliability;
 
	v->reliability_spd_dec = e->reliability_spd_dec;
 
	v->age = 0;
 

	
window.h
Show inline comments
 
@@ -331,50 +331,50 @@ assert_compile(WINDOW_CUSTOM_SIZE >= siz
 
typedef struct {
 
	void *data;
 
} void_d;
 
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(void_d));
 

	
 
typedef struct {
 
	uint16 base; /* follow_vehicle */
 
	uint16 count;/* scrollpos_x */
 
} tree_d;
 
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(tree_d));
 

	
 
typedef struct {
 
	byte refresh_counter; /* follow_vehicle */
 
} plstations_d;
 
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(plstations_d));
 

	
 
typedef struct {
 
	StringID string_id;
 
} tooltips_d;
 
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(tooltips_d));
 

	
 
typedef struct {
 
	byte railtype;
 
	byte sel_index;
 
	int16 sel_engine;
 
	int16 rename_engine;
 
	EngineID sel_engine;
 
	EngineID rename_engine;
 
} buildtrain_d;
 
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(buildtrain_d));
 

	
 
typedef struct {
 
	byte vehicletype;
 
	byte sel_index[2];
 
	int16 sel_engine[2];
 
	uint16 count[2];
 
} replaceveh_d;
 
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(replaceveh_d));
 

	
 
typedef struct {
 
	VehicleID sel;
 
} traindepot_d;
 
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(traindepot_d));
 

	
 
typedef struct {
 
	int sel;
 
} order_d;
 
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(order_d));
 

	
 
typedef struct {
 
	byte tab;
 
} traindetails_d;
0 comments (0 inline, 0 general)