Changeset - r4850:7a78073de588
[Not reviewed]
master
0 15 0
Darkvater - 18 years ago 2006-10-14 22:31:18
darkvater@openttd.org
(svn r6776) -Codechange: Use IsValidPlayer() function to determine of a PlayerID is an
actual playable player (< MAX_PLAYERS) or not.
15 files changed with 49 insertions and 48 deletions:
0 comments (0 inline, 0 general)
ai/ai.c
Show inline comments
 
@@ -204,25 +204,25 @@ void AI_RunGameLoop(void)
 
			}
 
		}
 
	}
 

	
 
	_current_player = OWNER_NONE;
 
}
 

	
 
/**
 
 * A new AI sees the day of light. You can do here what ever you think is needed.
 
 */
 
void AI_StartNewAI(PlayerID player)
 
{
 
	assert(player < MAX_PLAYERS);
 
	assert(IsValidPlayer(player));
 

	
 
	/* Called if a new AI is booted */
 
	_ai_player[player].active = true;
 
}
 

	
 
/**
 
 * This AI player died. Give it some chance to make a final puf.
 
 */
 
void AI_PlayerDied(PlayerID player)
 
{
 
	if (_ai.network_client && _ai.network_playas == player) {
 
		_ai.network_playas = PLAYER_SPECTATOR;
command.c
Show inline comments
 
@@ -374,37 +374,37 @@ int32 DoCommand(TileIndex tile, uint32 p
 
	if (CmdFailed(res)) {
 
		if (res & 0xFFFF) _error_message = res & 0xFFFF;
 
error:
 
		_docommand_recursive--;
 
		_cmd_text = NULL;
 
		return CMD_ERROR;
 
	}
 

	
 
	// if toplevel, subtract the money.
 
	if (--_docommand_recursive == 0) {
 
		SubtractMoneyFromPlayer(res);
 
		// XXX - Old AI hack which doesn't use DoCommandDP; update last build coord of player
 
		if (tile != 0 && _current_player < MAX_PLAYERS) {
 
		if (tile != 0 && IsValidPlayer(_current_player)) {
 
			GetPlayer(_current_player)->last_build_coordinate = tile;
 
		}
 
	}
 

	
 
	_cmd_text = NULL;
 
	return res;
 
}
 

	
 
int32 GetAvailableMoneyForCommand(void)
 
{
 
	PlayerID pid = _current_player;
 
	if (pid >= MAX_PLAYERS) return 0x7FFFFFFF; // max int
 
	if (!IsValidPlayer(pid)) return 0x7FFFFFFF; // max int
 
	return GetPlayer(pid)->player_money;
 
}
 

	
 
// toplevel network safe docommand function for the current player. must not be called recursively.
 
// the callback is called when the command succeeded or failed.
 
bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, CommandCallback *callback, uint32 cmd)
 
{
 
	int32 res = 0,res2;
 
	CommandProc *proc;
 
	uint32 flags;
 
	bool notest;
 
	StringID error_part1;
 
@@ -499,25 +499,25 @@ bool DoCommandP(TileIndex tile, uint32 p
 
	 */
 
	if (_networking && !(cmd & CMD_NETWORK_COMMAND)) {
 
		if (_network_dedicated) _local_player = 0;
 
		NetworkSend_Command(tile, p1, p2, cmd, callback);
 
		if (_network_dedicated) _local_player = PLAYER_SPECTATOR;
 
		_docommand_recursive = 0;
 
		_cmd_text = NULL;
 
		return true;
 
	}
 
#endif /* ENABLE_NETWORK */
 

	
 
	// update last build coordinate of player.
 
	if (tile != 0 && _current_player < MAX_PLAYERS) {
 
	if (tile != 0 && IsValidPlayer(_current_player)) {
 
		GetPlayer(_current_player)->last_build_coordinate = tile;
 
	}
 

	
 
	/* Actually try and execute the command. If no cost-type is given
 
	 * use the construction one */
 
	_yearly_expenses_type = EXPENSES_CONSTRUCTION;
 
	res2 = proc(tile, flags | DC_EXEC, p1, p2);
 

	
 
	// If notest is on, it means the result of the test can be different than
 
	//   the real command.. so ignore the test
 
	if (!notest && !((cmd & CMD_NO_TEST_IF_IN_NETWORK) && _networking)) {
 
		assert(res == res2); // sanity check
console_cmds.c
Show inline comments
 
@@ -1281,30 +1281,30 @@ DEF_CONSOLE_HOOK(ConHookRconPW)
 
	if (strcmp(_network_rcon_password, "*") == 0)
 
		_network_rcon_password[0] = '\0';
 

	
 
	ttd_strlcpy(_network_game_info.rcon_password, _network_rcon_password, sizeof(_network_game_info.rcon_password));
 

	
 
	return true;
 
}
 

	
 
/* Also use from within player_gui to change the password graphically */
 
bool NetworkChangeCompanyPassword(byte argc, char *argv[])
 
{
 
	if (argc == 0) {
 
		if (_local_player >= MAX_PLAYERS) return true; // dedicated server
 
		if (!IsValidPlayer(_local_player)) return true; // dedicated server
 
		IConsolePrintF(_icolour_warn, "Current value for 'company_pw': %s", _network_player_info[_local_player].password);
 
		return true;
 
	}
 

	
 
	if (_local_player >= MAX_PLAYERS) {
 
	if (!IsValidPlayer(_local_player)) {
 
		IConsoleError("You have to own a company to make use of this command.");
 
		return false;
 
	}
 

	
 
	if (argc != 1) return false;
 

	
 
	if (strcmp(argv[0], "*") == 0) argv[0][0] = '\0';
 

	
 
	ttd_strlcpy(_network_player_info[_local_player].password, argv[0], sizeof(_network_player_info[_local_player].password));
 

	
 
	if (!_network_server)
 
		SEND_COMMAND(PACKET_CLIENT_SET_PASSWORD)(_network_player_info[_local_player].password);
economy.c
Show inline comments
 
@@ -1534,25 +1534,25 @@ extern int GetAmountOwnedBy(Player *p, b
 

	
 
/** Acquire shares in an opposing company.
 
 * @param tile unused
 
 * @param p1 player to buy the shares from
 
 * @param p2 unused
 
 */
 
int32 CmdBuyShareInCompany(TileIndex tile, 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;
 
	if (!IsValidPlayer((PlayerID)p1) || !_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, PLAYER_SPECTATOR) == 0) return 0;
 

	
 
	/* We can not buy out a real player (temporarily). TODO: well, enable it obviously */
 
	if (GetAmountOwnedBy(p, PLAYER_SPECTATOR) == 1 && !p->is_ai) return 0;
 
@@ -1579,25 +1579,25 @@ int32 CmdBuyShareInCompany(TileIndex til
 

	
 
/** Sell shares in an opposing company.
 
 * @param tile unused
 
 * @param p1 player to sell the shares from
 
 * @param p2 unused
 
 */
 
int32 CmdSellShareInCompany(TileIndex tile, 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;
 
	if (!IsValidPlayer((PlayerID)p1) || !_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) {
 
@@ -1613,25 +1613,25 @@ int32 CmdSellShareInCompany(TileIndex ti
 
 * When a competing company is gone bankrupt you get the chance to purchase
 
 * that company.
 
 * @todo currently this only works for AI players
 
 * @param tile unused
 
 * @param p1 player/company to buy up
 
 * @param p2 unused
 
 */
 
int32 CmdBuyCompany(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	Player *p;
 

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

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

	
 
	if (!p->is_ai) return CMD_ERROR;
 

	
 
	if (flags & DC_EXEC) {
 
		DoAcquireCompany(p);
 
	}
 
	return p->bankrupt_value;
 
}
 

	
misc_cmd.c
Show inline comments
 
@@ -282,25 +282,25 @@ int32 CmdMoneyCheat(TileIndex tile, uint
 
 * @param p1 the amount of money to transfer; max 20.000.000
 
 * @param p2 the player to transfer the money to
 
 */
 
int32 CmdGiveMoney(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	const Player *p = GetPlayer(_current_player);
 
	int32 amount = min((int32)p1, 20000000);
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_OTHER);
 

	
 
	/* You can only transfer funds that is in excess of your loan */
 
	if (p->money64 - p->current_loan < amount || amount <= 0) return CMD_ERROR;
 
	if (!_networking || p2 >= MAX_PLAYERS) return CMD_ERROR;
 
	if (!_networking || !IsValidPlayer((PlayerID)p2)) return CMD_ERROR;
 

	
 
	if (flags & DC_EXEC) {
 
		/* Add money to player */
 
		PlayerID old_cp = _current_player;
 
		_current_player = p2;
 
		SubtractMoneyFromPlayer(-amount);
 
		_current_player = old_cp;
 
	}
 

	
 
	/* Subtract money from local-player */
 
	return amount;
 
}
misc_gui.c
Show inline comments
 
@@ -146,25 +146,25 @@ static void Place_LandInfo(TileIndex til
 
	static LandInfoData lid;
 
	Window *w;
 
	int64 old_money;
 

	
 
	DeleteWindowById(WC_LAND_INFO, 0);
 

	
 
	w = AllocateWindowDesc(&_land_info_desc);
 
	WP(w,void_d).data = &lid;
 

	
 
	lid.tile = tile;
 
	lid.town = ClosestTownFromTile(tile, _patches.dist_local_authority);
 

	
 
	p = GetPlayer(_local_player < MAX_PLAYERS ? _local_player : 0);
 
	p = GetPlayer(IsValidPlayer(_local_player) ? _local_player : 0);
 

	
 
	old_money = p->money64;
 
	p->money64 = p->player_money = 0x7fffffff;
 
	lid.costclear = DoCommand(tile, 0, 0, 0, CMD_LANDSCAPE_CLEAR);
 
	p->money64 = old_money;
 
	UpdatePlayerMoney32(p);
 

	
 
	// Becuase build_date is not set yet in every TileDesc, we make sure it is empty
 
	lid.td.build_date = 0;
 

	
 
	GetAcceptedCargo(tile, lid.ac);
 
	GetTileDesc(tile, &lid.td);
 
@@ -1297,25 +1297,25 @@ static void MakeSortedSaveGameList(void)
 
		}
 
	}
 

	
 
	s_amount = _fios_num - sort_start - sort_end;
 
	if (s_amount > 0)
 
		qsort(_fios_list + sort_start, s_amount, sizeof(FiosItem), compare_FiosItems);
 
}
 

	
 
static void GenerateFileName(void)
 
{
 
	/* Check if we are not a specatator who wants to generate a name..
 
	    Let's use the name of player #0 for now. */
 
	const Player *p = GetPlayer(_local_player < MAX_PLAYERS ? _local_player : 0);
 
	const Player *p = GetPlayer(IsValidPlayer(_local_player) ? _local_player : 0);
 

	
 
	SetDParam(0, p->name_1);
 
	SetDParam(1, p->name_2);
 
	SetDParam(2, _date);
 
	GetString(_edit_str_buf, STR_4004);
 
}
 

	
 
extern void StartupEngines(void);
 

	
 
static void SaveLoadDlgWndProc(Window *w, WindowEvent *e)
 
{
 
	static FiosItem o_dir;
 
@@ -1627,27 +1627,27 @@ void SetFiosType(const byte fiostype)
 
	}
 
}
 

	
 
static int32 ClickMoneyCheat(int32 p1, int32 p2)
 
{
 
		DoCommandP(0, -10000000, 0, NULL, CMD_MONEY_CHEAT);
 
		return true;
 
}
 

	
 
// p1 player to set to, p2 is -1 or +1 (down/up)
 
static int32 ClickChangePlayerCheat(int32 p1, int32 p2)
 
{
 
	while (p1 >= 0 && p1 < MAX_PLAYERS) {
 
	while (IsValidPlayer((PlayerID)p1)) {
 
		if (_players[p1].is_active) {
 
			_local_player = p1;
 
			_local_player = (PlayerID)p1;
 
			MarkWholeScreenDirty();
 
			return _local_player;
 
		}
 
		p1 += p2;
 
	}
 

	
 
	return _local_player;
 
}
 

	
 
// p1 -1 or +1 (down/up)
 
static int32 ClickChangeClimateCheat(int32 p1, int32 p2)
 
{
network_server.c
Show inline comments
 
@@ -1223,25 +1223,25 @@ void NetworkPopulateCompanyInfo(void)
 
			}
 
		}
 

	
 
		// Set some general stuff
 
		_network_player_info[p->index].inaugurated_year = p->inaugurated_year;
 
		_network_player_info[p->index].company_value = p->old_economy[0].company_value;
 
		_network_player_info[p->index].money = p->money64;
 
		_network_player_info[p->index].performance = p->old_economy[0].performance_history;
 
	}
 

	
 
	// Go through all vehicles and count the type of vehicles
 
	FOR_ALL_VEHICLES(v) {
 
		if (v->owner >= MAX_PLAYERS) continue;
 
		if (!IsValidPlayer(v->owner)) continue;
 
		switch (v->type) {
 
			case VEH_Train:
 
				if (IsFrontEngine(v)) {
 
					_network_player_info[v->owner].num_vehicle[0]++;
 
				}
 
				break;
 

	
 
			case VEH_Road:
 
				if (v->cargo_type != CT_PASSENGERS) {
 
					_network_player_info[v->owner].num_vehicle[1]++;
 
				} else {
 
					_network_player_info[v->owner].num_vehicle[2]++;
 
@@ -1257,25 +1257,25 @@ void NetworkPopulateCompanyInfo(void)
 
			case VEH_Ship:
 
				_network_player_info[v->owner].num_vehicle[4]++;
 
				break;
 

	
 
			case VEH_Special:
 
			case VEH_Disaster:
 
				break;
 
		}
 
	}
 

	
 
	// Go through all stations and count the types of stations
 
	FOR_ALL_STATIONS(s) {
 
		if (s->owner < MAX_PLAYERS) {
 
		if (IsValidPlayer(s->owner)) {
 
			NetworkPlayerInfo* npi = &_network_player_info[s->owner];
 

	
 
			if (s->facilities & FACIL_TRAIN)      npi->num_station[0]++;
 
			if (s->facilities & FACIL_TRUCK_STOP) npi->num_station[1]++;
 
			if (s->facilities & FACIL_BUS_STOP)   npi->num_station[2]++;
 
			if (s->facilities & FACIL_AIRPORT)    npi->num_station[3]++;
 
			if (s->facilities & FACIL_DOCK)       npi->num_station[4]++;
 
		}
 
	}
 

	
 
	ci = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX);
 
	// Register local player (if not dedicated)
openttd.c
Show inline comments
 
@@ -1248,25 +1248,25 @@ bool AfterLoadGame(void)
 
		FOR_ALL_TOWNS(t) UpdateTownMaxPass(t);
 
	}
 

	
 
	/* From version 16.0, we included autorenew on engines, which are now saved, but
 
	 *  of course, we do need to initialize them for older savegames. */
 
	if (CheckSavegameVersion(16)) {
 
		FOR_ALL_PLAYERS(p) {
 
			p->engine_renew_list = NULL;
 
			p->engine_renew = false;
 
			p->engine_renew_months = -6;
 
			p->engine_renew_money = 100000;
 
		}
 
		if (_local_player < MAX_PLAYERS) {
 
		if (IsValidPlayer(_local_player)) {
 
			// Set the human controlled player to the patch settings
 
			// Scenario editor do not have any companies
 
			p = GetPlayer(_local_player);
 
			p->engine_renew = _patches.autorenew;
 
			p->engine_renew_months = _patches.autorenew_months;
 
			p->engine_renew_money = _patches.autorenew_money;
 
		}
 
	}
 

	
 
	/* Elrails got added in rev 24 */
 
	if (CheckSavegameVersion(24)) {
 
		Vehicle *v;
player.h
Show inline comments
 
@@ -236,24 +236,29 @@ static inline byte ActivePlayerCount(voi
 

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

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

	
 
static inline bool IsValidPlayer(PlayerID pi)
 
{
 
	return pi < MAX_PLAYERS;
 
}
 

	
 
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)
 
{
 
	return HASBIT(p->avail_railtypes, Railtype);
 
}
 

	
 
static inline bool IsHumanPlayer(PlayerID pi)
 
{
 
	return !GetPlayer(pi)->is_ai;
players.c
Show inline comments
 
@@ -195,25 +195,25 @@ void DrawPlayerFace(uint32 face, int col
 
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) {
 
		PlayerID pid = _current_player;
 
		if (pid < MAX_PLAYERS && cost > GetPlayer(pid)->player_money) {
 
		if (IsValidPlayer(pid) && 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);
 
@@ -224,25 +224,25 @@ static void SubtractMoneyFromAnyPlayer(P
 
		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);
 
	if (IsValidPlayer(pid)) 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);
 
}
 
@@ -255,25 +255,25 @@ void UpdatePlayerMoney32(Player *p)
 
	} else if (p->money64 > 2000000000) {
 
		p->player_money = 2000000000;
 
	} else {
 
		p->player_money = (int32)p->money64;
 
	}
 
}
 

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

	
 
	if (owner != OWNER_TOWN) {
 
		if (owner >= MAX_PLAYERS) {
 
		if (!IsValidPlayer(owner)) {
 
			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);
 
@@ -575,25 +575,25 @@ void OnTick_Players(void)
 

	
 
	p = GetPlayer(_cur_player_tick_index);
 
	_cur_player_tick_index = (_cur_player_tick_index + 1) % MAX_PLAYERS;
 
	if (p->name_1 != 0) GenerateCompanyName(p);
 

	
 
	if (AI_AllowNewAI() && _game_mode != GM_MENU && !--_next_competitor_start)
 
		MaybeStartNewPlayer();
 
}
 

	
 
// index is the next parameter in _decode_parameters to set up
 
StringID GetPlayerNameString(PlayerID player, uint index)
 
{
 
	if (IsHumanPlayer(player) && player < MAX_PLAYERS) {
 
	if (IsHumanPlayer(player) && IsValidPlayer(player)) {
 
		SetDParam(index, player+1);
 
		return STR_7002_PLAYER;
 
	}
 
	return STR_EMPTY;
 
}
 

	
 
extern void ShowPlayerFinances(int player);
 

	
 
void PlayersYearlyLoop(void)
 
{
 
	Player *p;
 

	
 
@@ -682,26 +682,25 @@ static void DeletePlayerStuff(PlayerID p
 
 * - p2 bits  0-15 = old engine type
 
 * - p2 bits 16-31 = new engine type
 
 * if p1 = 4, then:
 
 * - p1 bit     15 = enable engine renewal
 
 * - p1 bits 16-31 = months left before engine expires to replace it
 
 * - p2 bits  0-31 = minimum amount of money available
 
 * if p1 = 5, then
 
 * - p2 = enable renew_keep_length
 
 */
 
int32 CmdSetAutoReplace(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	Player *p;
 
	if (!(_current_player < MAX_PLAYERS))
 
		return CMD_ERROR;
 
	if (!IsValidPlayer(_current_player)) return CMD_ERROR;
 

	
 
	p = GetPlayer(_current_player);
 
	switch (GB(p1, 0, 3)) {
 
		case 0:
 
			if (p->engine_renew == (bool)GB(p2, 0, 1))
 
				return CMD_ERROR;
 

	
 
			if (flags & DC_EXEC) {
 
				p->engine_renew = (bool)GB(p2, 0, 1);
 
				if (IsLocalPlayer()) {
 
					_patches.autorenew = p->engine_renew;
 
					InvalidateWindow(WC_GAME_OPTIONS, 0);
 
@@ -815,25 +814,25 @@ int32 CmdSetAutoReplace(TileIndex tile, 
 
 * @arg - network_server.c:838 DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_COMMAND)@n
 
 * @arg - network_client.c:536 DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_MAP) from where the map has been received
 
 */
 
int32 CmdPlayerCtrl(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	if (flags & DC_EXEC) _current_player = OWNER_NONE;
 

	
 
	switch (p1) {
 
	case 0: { /* Create a new player */
 
		Player *p;
 
		PlayerID pid = p2;
 

	
 
		if (!(flags & DC_EXEC) || pid >= MAX_PLAYERS) return 0;
 
		if (!(flags & DC_EXEC) || !IsValidPlayer(pid)) return 0;
 

	
 
		p = DoStartupNewPlayer(false);
 

	
 
#ifdef ENABLE_NETWORK
 
		if (_networking && !_network_server && _local_player == PLAYER_SPECTATOR) {
 
			/* In case we are a client joining a server... */
 
			DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0);
 
		}
 
#endif /* ENABLE_NETWORK */
 

	
 
		if (p != NULL) {
 
			if (_local_player == PLAYER_SPECTATOR &&
 
@@ -901,25 +900,25 @@ int32 CmdPlayerCtrl(TileIndex tile, uint
 
		}
 
	} break;
 

	
 
	case 1: /* Make a new AI player */
 
		if (!(flags & DC_EXEC)) return 0;
 

	
 
		DoStartupNewPlayer(true);
 
		break;
 

	
 
	case 2: { /* Delete a player */
 
		Player *p;
 

	
 
		if (p2 >= MAX_PLAYERS) return CMD_ERROR;
 
		if (!IsValidPlayer(p2)) return CMD_ERROR;
 

	
 
		if (!(flags & DC_EXEC)) return 0;
 

	
 
		p = GetPlayer(p2);
 

	
 
		/* Only allow removal of HUMAN companies */
 
		if (IsHumanPlayer(p->index)) {
 
			/* Delete any open window of the company */
 
			DeletePlayerWindows(p->index);
 

	
 
			/* Show the bankrupt news */
 
			SetDParam(0, p->name_1);
 
@@ -929,25 +928,25 @@ int32 CmdPlayerCtrl(TileIndex tile, uint
 
			/* Remove the company */
 
			ChangeOwnershipOfPlayerItems(p->index, PLAYER_SPECTATOR);
 
			p->is_active = false;
 
		}
 
		RemoveAllEngineReplacementForPlayer(p);
 

	
 
	} break;
 

	
 
	case 3: { /* Merge a company (#1) into another company (#2), elimination company #1 */
 
		PlayerID pid_old = GB(p2,  0, 16);
 
		PlayerID pid_new = GB(p2, 16, 16);
 

	
 
		if (pid_old >= MAX_PLAYERS || pid_new >= MAX_PLAYERS) return CMD_ERROR;
 
		if (!IsValidPlayer(pid_old) || !IsValidPlayer(pid_new)) return CMD_ERROR;
 

	
 
		if (!(flags & DC_EXEC)) return CMD_ERROR;
 

	
 
		ChangeOwnershipOfPlayerItems(pid_old, pid_new);
 
		DeletePlayerStuff(pid_old);
 
	} break;
 
	default: return CMD_ERROR;
 
	}
 

	
 
	return 0;
 
}
 

	
road_cmd.c
Show inline comments
 
@@ -36,25 +36,25 @@ static uint CountRoadBits(RoadBits r)
 

	
 

	
 
static bool CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, bool* edge_road)
 
{
 
	RoadBits present;
 
	RoadBits n;
 
	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;
 
	if (!IsValidPlayer(_current_player)) 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 (_cheats.magic_bulldozer.value) return true;
 

	
 
	// Get a bitmask of which neighbouring roads has a tile
 
	n = 0;
 
	present = GetAnyRoadBits(tile);
 
@@ -280,25 +280,25 @@ static uint32 CheckRoadSlope(Slope tileh
 
int32 CmdBuildRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	int32 cost = 0;
 
	int32 ret;
 
	RoadBits existing = 0;
 
	RoadBits pieces;
 
	Slope tileh;
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 

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

	
 
	tileh = GetTileSlope(tile, NULL);
 

	
 
	switch (GetTileType(tile)) {
 
		case MP_STREET:
 
			switch (GetRoadTileType(tile)) {
 
				case ROAD_TILE_NORMAL:
 
					if (HasRoadWorks(tile)) return_cmd_error(STR_ROAD_WORKS_IN_PROGRESS);
 

	
 
					existing = GetRoadBits(tile);
 
					if ((existing & pieces) == pieces) {
station_cmd.c
Show inline comments
 
@@ -1015,25 +1015,25 @@ int32 CmdBuildRailroadStation(TileIndex 
 
			if (!CanExpandRailroadStation(st, finalvalues, axis))
 
				return CMD_ERROR;
 
		}
 

	
 
		//XXX can't we pack this in the "else" part of the if above?
 
		if (!CheckStationSpreadOut(st, tile_org, w_org, h_org)) return CMD_ERROR;
 
	} else {
 
		// Create a new station
 
		st = AllocateStation();
 
		if (st == NULL) return CMD_ERROR;
 

	
 
		st->town = ClosestTownFromTile(tile_org, (uint)-1);
 
		if (_current_player < MAX_PLAYERS && flags & DC_EXEC)
 
		if (IsValidPlayer(_current_player) && (flags & DC_EXEC))
 
			SETBIT(st->town->have_ratings, _current_player);
 

	
 
		if (!GenerateStationName(st, tile_org, 0)) return CMD_ERROR;
 

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

	
 
	/* Check if the given station class is valid */
 
	if (GB(p2, 8, 8) >= STAT_CLASS_MAX) return CMD_ERROR;
 

	
 
	/* Check if we can allocate a custom stationspec to this station */
 
	statspec = GetCustomStationSpec(GB(p2, 8, 8), GB(p2, 16, 8));
 
@@ -1443,25 +1443,25 @@ int32 CmdBuildRoadStop(TileIndex tile, u
 

	
 
		FindRoadStopSpot(type, st, &currstop, &prev);
 
	} else {
 
		Town *t;
 

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

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

	
 
		FindRoadStopSpot(type, st, &currstop, &prev);
 

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

	
 
		st->sign.width_1 = 0;
 

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

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

	
 
	cost += (type) ? _price.build_truck_station : _price.build_bus_station;
 

	
 
@@ -1689,25 +1689,25 @@ int32 CmdBuildAirport(TileIndex tile, ui
 
			return CMD_ERROR;
 

	
 
		if (st->airport_tile != 0)
 
			return_cmd_error(STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT);
 
	} else {
 
		airport_upgrade = false;
 

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

	
 
		st->town = t;
 

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

	
 
		st->sign.width_1 = 0;
 

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

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

	
 
@@ -1850,28 +1850,26 @@ static bool CheckShipsOnBuoy(Station *st
 
					return true;
 
				}
 
			}
 
		}
 
	}
 
	return false;
 
}
 

	
 
static int32 RemoveBuoy(Station *st, uint32 flags)
 
{
 
	TileIndex tile;
 

	
 
	if (_current_player >= MAX_PLAYERS) {
 
		/* XXX: strange stuff */
 
		return_cmd_error(INVALID_STRING_ID);
 
	}
 
	if (!IsValidPlayer(_current_player))  return_cmd_error(INVALID_STRING_ID);
 

	
 
	tile = st->dock_tile;
 

	
 
	if (CheckShipsOnBuoy(st))   return_cmd_error(STR_BUOY_IS_IN_USE);
 
	if (!EnsureNoVehicle(tile)) return CMD_ERROR;
 

	
 
	if (flags & DC_EXEC) {
 
		st->dock_tile = 0;
 
		/* Buoys are marked in the Station struct by this flag. Yes, it is this
 
		 * braindead.. */
 
		st->facilities &= ~FACIL_DOCK;
 
		st->had_vehicle_of_type &= ~HVOT_BUOY;
 
@@ -1958,25 +1956,25 @@ int32 CmdBuildDock(TileIndex tile, uint3
 

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

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

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

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

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

	
 
		st->sign.width_1 = 0;
 

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

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

	
 
	if (flags & DC_EXEC) {
 
		st->dock_tile = tile;
 
		if (!st->facilities) st->xy = tile;
 
@@ -2035,25 +2033,25 @@ static void DrawTile_Station(TileInfo *t
 
{
 
	uint32 image;
 
	const DrawTileSeqStruct *dtss;
 
	const DrawTileSprites *t = NULL;
 
	RailType railtype = GetRailType(ti->tile);
 
	const RailtypeInfo *rti = GetRailTypeInfo(railtype);
 
	uint32 relocation = 0;
 
	const Station *st = NULL;
 
	const StationSpec *statspec = NULL;
 
	PlayerID owner = GetTileOwner(ti->tile);
 
	uint32 palette;
 

	
 
	if (owner < MAX_PLAYERS) {
 
	if (IsValidPlayer(owner)) {
 
		palette = PLAYER_SPRITE_COLOR(owner);
 
	} else {
 
		// Some stations are not owner by a player, namely oil rigs
 
		palette = PALETTE_TO_GREY;
 
	}
 

	
 
	// don't show foundation for docks
 
	if (ti->tileh != SLOPE_FLAT && !IsDock(ti->tile))
 
		DrawFoundation(ti, ti->tileh);
 

	
 
	if (IsCustomStationSpecIndex(ti->tile)) {
 
		// look for customization
 
@@ -2391,25 +2389,25 @@ void DestroyStation(Station *st)
 

	
 
	//Subsidies need removal as well
 
	DeleteSubsidyWithStation(index);
 

	
 
	free(st->speclist);
 
}
 

	
 
void DeleteAllPlayerStations(void)
 
{
 
	Station *st;
 

	
 
	FOR_ALL_STATIONS(st) {
 
		if (st->owner < MAX_PLAYERS) DeleteStation(st);
 
		if (IsValidPlayer(st->owner)) DeleteStation(st);
 
	}
 
}
 

	
 
/* this function is called for one station each tick */
 
static void StationHandleBigTick(Station *st)
 
{
 
	UpdateStationAcceptance(st, true);
 

	
 
	if (st->facilities == 0 && ++st->delete_ctr >= 8) DeleteStation(st);
 

	
 
}
 

	
 
@@ -2439,26 +2437,25 @@ static void UpdateStationRating(Station 
 
				if ((b-=85) >= 0)
 
					rating += b >> 2;
 
			}
 

	
 
			{
 
				byte age = ge->last_age;
 
				(age >= 3) ||
 
				(rating += 10, age >= 2) ||
 
				(rating += 10, age >= 1) ||
 
				(rating += 13, true);
 
			}
 

	
 
			if (st->owner < MAX_PLAYERS && HASBIT(st->town->statues, st->owner))
 
				rating += 26;
 
			if (IsValidPlayer(st->owner) && HASBIT(st->town->statues, st->owner)) rating += 26;
 

	
 
			{
 
				byte days = ge->days_since_pickup;
 
				if (st->last_vehicle_type == VEH_Ship)
 
							days >>= 2;
 
				(days > 21) ||
 
				(rating += 25, days > 12) ||
 
				(rating += 25, days > 6) ||
 
				(rating += 45, days > 3) ||
 
				(rating += 35, true);
 
			}
 

	
town_cmd.c
Show inline comments
 
@@ -346,25 +346,25 @@ static int32 ClearTile_Town(TileIndex ti
 

	
 
	// safety checks
 
	if (!EnsureNoVehicle(tile)) return CMD_ERROR;
 
	if (flags&DC_AUTO && !(flags&DC_AI_BUILDING)) return_cmd_error(STR_2004_BUILDING_MUST_BE_DEMOLISHED);
 

	
 
	house = GetHouseType(tile);
 
	cost = _price.remove_house * _housetype_remove_cost[house] >> 8;
 

	
 
	rating = _housetype_remove_ratingmod[house];
 
	_cleared_town_rating += rating;
 
	_cleared_town = t = GetTownByTile(tile);
 

	
 
	if (_current_player < MAX_PLAYERS) {
 
	if (IsValidPlayer(_current_player)) {
 
		if (rating > t->ratings[_current_player] && !(flags & DC_NO_TOWN_RATING) && !_cheats.magic_bulldozer.value) {
 
			SetDParam(0, t->index);
 
			return_cmd_error(STR_2009_LOCAL_AUTHORITY_REFUSES);
 
		}
 
	}
 

	
 
	if (flags & DC_EXEC) {
 
		ChangeTownRating(t, -rating, RATING_HOUSE_MINIMUM);
 
		ClearTownHouse(t, tile);
 
	}
 

	
 
	return cost;
 
@@ -1621,28 +1621,28 @@ static void UpdateTownGrowRate(Town *t)
 
	// Reset player ratings if they're low
 
	FOR_ALL_PLAYERS(p) {
 
		if (p->is_active && t->ratings[p->index] <= 200) {
 
			t->ratings[p->index] += 5;
 
		}
 
	}
 

	
 
	n = 0;
 
	FOR_ALL_STATIONS(st) {
 
		if (DistanceSquare(st->xy, t->xy) <= t->radius[0]) {
 
			if (st->time_since_load <= 20 || st->time_since_unload <= 20) {
 
				n++;
 
				if (st->owner < MAX_PLAYERS && t->ratings[st->owner] <= 1000-12)
 
				if (IsValidPlayer(st->owner) && t->ratings[st->owner] <= 1000-12)
 
					t->ratings[st->owner] += 12;
 
			} else {
 
				if (st->owner < MAX_PLAYERS && t->ratings[st->owner] >= -1000+15)
 
				if (IsValidPlayer(st->owner) && t->ratings[st->owner] >= -1000+15)
 
					t->ratings[st->owner] -= 15;
 
			}
 
		}
 
	}
 

	
 
	CLRBIT(t->flags12, TOWN_IS_FUNDED);
 

	
 
	if (t->fund_buildings_months != 0) {
 
		static const byte _grow_count_values[6] = {
 
			60, 60, 60, 50, 40, 30
 
		};
 
		m = _grow_count_values[min(n, 5)];
 
@@ -1695,25 +1695,25 @@ static void UpdateTownUnwanted(Town *t)
 
{
 
	const Player* p;
 

	
 
	FOR_ALL_PLAYERS(p) {
 
		if (t->unwanted[p->index] > 0) t->unwanted[p->index]--;
 
	}
 
}
 

	
 
bool CheckIfAuthorityAllows(TileIndex tile)
 
{
 
	Town *t;
 

	
 
	if (_current_player >= MAX_PLAYERS) return true;
 
	if (!IsValidPlayer(_current_player)) return true;
 

	
 
	t = ClosestTownFromTile(tile, _patches.dist_local_authority);
 
	if (t == NULL) return true;
 

	
 
	if (t->ratings[_current_player] > -200) return true;
 

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

	
 
	return false;
 
}
 

	
 
@@ -1746,25 +1746,25 @@ Town *ClosestTownFromTile(TileIndex tile
 
	} else {
 
		return CalcClosestTownFromTile(tile, threshold);
 
	}
 
}
 

	
 

	
 
void ChangeTownRating(Town *t, int add, int max)
 
{
 
	int rating;
 

	
 
	// if magic_bulldozer cheat is active, town doesn't penaltize for removing stuff
 
	if (t == NULL ||
 
			_current_player >= MAX_PLAYERS ||
 
			!IsValidPlayer(_current_player) ||
 
			(_cheats.magic_bulldozer.value && add < 0)) {
 
		return;
 
	}
 

	
 
	SETBIT(t->have_ratings, _current_player);
 

	
 
	rating = t->ratings[_current_player];
 

	
 
	if (add < 0) {
 
		if (rating > max) {
 
			rating += add;
 
			if (rating < max) rating = max;
 
@@ -1782,25 +1782,25 @@ void ChangeTownRating(Town *t, int add, 
 
static const int _default_rating_settings [3][3] = {
 
	// ROAD_REMOVE, TUNNELBRIDGE_REMOVE, INDUSTRY_REMOVE
 
	{  0, 128, 384}, // Permissive
 
	{ 48, 192, 480}, // Neutral
 
	{ 96, 384, 768}, // Hostile
 
};
 

	
 
bool CheckforTownRating(uint32 flags, Town *t, byte type)
 
{
 
	int modemod;
 

	
 
	// if magic_bulldozer cheat is active, town doesn't restrict your destructive actions
 
	if (t == NULL || _current_player >= MAX_PLAYERS || _cheats.magic_bulldozer.value)
 
	if (t == NULL || !IsValidPlayer(_current_player) || _cheats.magic_bulldozer.value)
 
		return true;
 

	
 
	/* check if you're allowed to remove the street/bridge/tunnel/industry
 
	 * owned by a town no removal if rating is lower than ... depends now on
 
	 * difficulty setting. Minimum town rating selected by difficulty level
 
	 */
 
	modemod = _default_rating_settings[_opt.diff.town_council_tolerance][type];
 

	
 
	if (t->ratings[_current_player] < 16 + modemod && !(flags & DC_NO_TOWN_RATING)) {
 
		SetDParam(0, t->index);
 
		_error_message = STR_2009_LOCAL_AUTHORITY_REFUSES;
 
		return false;
tree_cmd.c
Show inline comments
 
@@ -256,25 +256,25 @@ int32 CmdPlantTree(TileIndex tile, uint3
 
					}
 

	
 
					switch (GetClearGround(tile)) {
 
						case CLEAR_FIELDS: cost += _price.clear_3; break;
 
						case CLEAR_ROCKS:  cost += _price.clear_2; break;
 
						default: break;
 
					}
 

	
 
					if (flags & DC_EXEC) {
 
						TreeType treetype;
 
						uint growth;
 

	
 
						if (_game_mode != GM_EDITOR && _current_player < MAX_PLAYERS) {
 
						if (_game_mode != GM_EDITOR && IsValidPlayer(_current_player)) {
 
							Town *t = ClosestTownFromTile(tile, _patches.dist_local_authority);
 
							if (t != NULL)
 
								ChangeTownRating(t, RATING_TREE_UP_STEP, RATING_TREE_MAXIMUM);
 
						}
 

	
 
						treetype = p1;
 
						if (treetype == TREE_INVALID) {
 
							treetype = GetRandomTreeType(tile, GB(Random(), 24, 8));
 
							if (treetype == TREE_INVALID) treetype = TREE_CACTUS;
 
						}
 

	
 
						growth = _game_mode == GM_EDITOR ? 3 : 0;
 
@@ -406,25 +406,25 @@ static uint GetSlopeZ_Trees(TileIndex ti
 
	return z + GetPartialZ(x & 0xF, y & 0xF, tileh);
 
}
 

	
 
static Slope GetSlopeTileh_Trees(TileIndex tile, Slope tileh)
 
{
 
	return tileh;
 
}
 

	
 
static int32 ClearTile_Trees(TileIndex tile, byte flags)
 
{
 
	uint num;
 

	
 
	if (flags & DC_EXEC && _current_player < MAX_PLAYERS) {
 
	if ((flags & DC_EXEC) && IsValidPlayer(_current_player)) {
 
		Town *t = ClosestTownFromTile(tile, _patches.dist_local_authority);
 
		if (t != NULL)
 
			ChangeTownRating(t, RATING_TREE_DOWN_STEP, RATING_TREE_MINIMUM);
 
	}
 

	
 
	num = GetTreeCount(tile) + 1;
 
	if (IS_INT_INSIDE(GetTreeType(tile), TREE_RAINFOREST, TREE_CACTUS)) num *= 4;
 

	
 
	if (flags & DC_EXEC) DoClearSquare(tile);
 

	
 
	return num * _price.remove_trees;
 
}
tunnelbridge_cmd.c
Show inline comments
 
@@ -414,25 +414,25 @@ not_valid_below:;
 
	SetSignalsOnBothDir(tile_start, AxisToTrack(direction));
 
	YapfNotifyTrackLayoutChange(tile_start, AxisToTrack(direction));
 

	
 
	/* for human player that builds the bridge he gets a selection to choose from bridges (DC_QUERY_COST)
 
	 * It's unnecessary to execute this command every time for every bridge. So it is done only
 
	 * and cost is computed in "bridge_gui.c". For AI, Towns this has to be of course calculated
 
	 */
 
	if (!(flags & DC_QUERY_COST)) {
 
		const Bridge *b = &_bridge[bridge_type];
 

	
 
		bridge_len += 2; // begin and end tiles/ramps
 

	
 
		if (_current_player < MAX_PLAYERS && !_is_old_ai_player)
 
		if (IsValidPlayer(_current_player) && !_is_old_ai_player)
 
			bridge_len = CalcBridgeLenCostFactor(bridge_len);
 

	
 
		cost += (int64)bridge_len * _price.build_bridge * b->price >> 8;
 
	}
 

	
 
	return cost;
 
}
 

	
 

	
 
/** Build Tunnel.
 
 * @param tile start tile of tunnel
 
 * @param p1 railtype, 0x200 for road tunnel
0 comments (0 inline, 0 general)