File diff r5586:c50e3258a19f → r5587:034e5e185dc2
src/economy.cpp
Show inline comments
 
@@ -38,25 +38,25 @@ const ScoreInfo _score_info[] = {
 
	{ SCORE_VEHICLES,        120, 100 },
 
	{ SCORE_STATIONS,         80, 100 },
 
	{ SCORE_MIN_PROFIT,    10000, 100 },
 
	{ SCORE_MIN_INCOME,    50000,  50 },
 
	{ SCORE_MAX_INCOME,   100000, 100 },
 
	{ SCORE_DELIVERED,     40000, 400 },
 
	{ SCORE_CARGO,             8,  50 },
 
	{ SCORE_MONEY,      10000000,  50 },
 
	{ SCORE_LOAN,         250000,  50 },
 
	{ SCORE_TOTAL,             0,   0 }
 
};
 

	
 
int _score_part[MAX_PLAYERS][NUM_SCORE];
 
int _score_part[MAX_PLAYERS][SCORE_END];
 

	
 
int64 CalculateCompanyValue(const Player* p)
 
{
 
	PlayerID owner = p->index;
 
	int64 value;
 

	
 
	{
 
		Station *st;
 
		uint num = 0;
 

	
 
		FOR_ALL_STATIONS(st) {
 
			if (st->owner == owner) {
 
@@ -200,29 +200,28 @@ int UpdateCompanyRatingAndValue(Player *
 
		if (money > 0) {
 
			_score_part[owner][SCORE_MONEY] = money;
 
		}
 
	}
 

	
 
/* Generate score for loan */
 
	{
 
		_score_part[owner][SCORE_LOAN] = _score_info[SCORE_LOAN].needed - p->current_loan;
 
	}
 

	
 
	// Now we calculate the score for each item..
 
	{
 
		int i;
 
		int total_score = 0;
 
		int s;
 
		score = 0;
 
		for (i = 0; i < NUM_SCORE; i++) {
 
		for (ScoreID i = SCORE_BEGIN; i < SCORE_END; i++) {
 
			// Skip the total
 
			if (i == SCORE_TOTAL) continue;
 
			// Check the score
 
			s = (_score_part[owner][i] >= _score_info[i].needed) ?
 
				_score_info[i].score :
 
				_score_part[owner][i] * _score_info[i].score / _score_info[i].needed;
 
			if (s < 0) s = 0;
 
			score += s;
 
			total_score += _score_info[i].score;
 
		}
 

	
 
		_score_part[owner][SCORE_TOTAL] = score;
 
@@ -458,25 +457,25 @@ static void PlayersCheckBankrupt(Player 
 
			if (!IsHumanPlayer(owner) && (!_networking || _network_server) && _ai.enabled)
 
				AI_PlayerDied(owner);
 
		}
 
	}
 
}
 

	
 
void DrawNewsBankrupcy(Window *w)
 
{
 
	Player *p;
 

	
 
	DrawNewsBorder(w);
 

	
 
	p = GetPlayer(GB(WP(w,news_d).ni->string_id, 0, 4));
 
	p = GetPlayer((PlayerID)GB(WP(w,news_d).ni->string_id, 0, 4));
 
	DrawPlayerFace(p->face, p->player_color, 2, 23);
 
	GfxFillRect(3, 23, 3+91, 23+118, 0x323 | USE_COLORTABLE);
 

	
 
	SetDParam(0, p->president_name_1);
 
	SetDParam(1, p->president_name_2);
 

	
 
	DrawStringMultiCenter(49, 148, STR_7058_PRESIDENT, 94);
 

	
 
	switch (WP(w,news_d).ni->string_id & 0xF0) {
 
	case NB_BTROUBLE:
 
		DrawStringCentered(w->width>>1, 1, STR_7056_TRANSPORT_COMPANY_IN_TROUBLE, 0);
 

	
 
@@ -527,25 +526,25 @@ void DrawNewsBankrupcy(Window *w)
 
			90,
 
			STR_705F_STARTS_CONSTRUCTION_NEAR,
 
			w->width - 101);
 
		break;
 

	
 
	default:
 
		NOT_REACHED();
 
	}
 
}
 

	
 
StringID GetNewsStringBankrupcy(const NewsItem *ni)
 
{
 
	const Player *p = GetPlayer(GB(ni->string_id, 0, 4));
 
	const Player *p = GetPlayer((PlayerID)GB(ni->string_id, 0, 4));
 

	
 
	switch (ni->string_id & 0xF0) {
 
	case NB_BTROUBLE:
 
		SetDParam(0, STR_7056_TRANSPORT_COMPANY_IN_TROUBLE);
 
		SetDParam(1, STR_7057_WILL_BE_SOLD_OFF_OR_DECLARED);
 
		SetDParam(2, p->name_1);
 
		SetDParam(3, p->name_2);
 
		return STR_02B6;
 
	case NB_BMERGER:
 
		SetDParam(0, STR_7059_TRANSPORT_COMPANY_MERGER);
 
		SetDParam(1, STR_705A_HAS_BEEN_SOLD_TO_FOR);
 
		COPY_IN_DPARAM(2,ni->params, 2);
 
@@ -1553,87 +1552,87 @@ void PlayersMonthlyLoop(void)
 
	if (_patches.inflation && _cur_year < MAX_YEAR)
 
		AddInflation();
 
	PlayersPayInterest();
 
	// Reset the _current_player flag
 
	_current_player = OWNER_NONE;
 
	HandleEconomyFluctuations();
 
	SubsidyMonthlyHandler();
 
}
 

	
 
static void DoAcquireCompany(Player *p)
 
{
 
	Player *owner;
 
	int i,pi;
 
	int i;
 
	int64 value;
 

	
 
	SetDParam(0, p->name_1);
 
	SetDParam(1, p->name_2);
 
	SetDParam(2, p->bankrupt_value);
 
	AddNewsItem( (StringID)(_current_player | NB_BMERGER), NEWS_FLAGS(NM_CALLBACK, 0, NT_COMPANY_INFO, DNC_BANKRUPCY),0,0);
 

	
 
	// original code does this a little bit differently
 
	pi = p->index;
 
	PlayerID pi = p->index;
 
	ChangeOwnershipOfPlayerItems(pi, _current_player);
 

	
 
	if (p->bankrupt_value == 0) {
 
		owner = GetPlayer(_current_player);
 
		owner->current_loan += p->current_loan;
 
	}
 

	
 
	value = CalculateCompanyValue(p) >> 2;
 
	for (i = 0; i != 4; i++) {
 
		if (p->share_owners[i] != PLAYER_SPECTATOR) {
 
			owner = GetPlayer(p->share_owners[i]);
 
			owner->money64 += value;
 
			owner->yearly_expenses[0][EXPENSES_OTHER] += value;
 
			UpdatePlayerMoney32(owner);
 
		}
 
	}
 

	
 
	p->is_active = false;
 

	
 
	DeletePlayerWindows(pi);
 
	RebuildVehicleLists(); //Updates the open windows to add the newly acquired vehicles to the lists
 
}
 

	
 
extern int GetAmountOwnedBy(Player *p, byte owner);
 
extern int GetAmountOwnedBy(const Player *p, PlayerID owner);
 

	
 
/** 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 (!IsValidPlayer((PlayerID)p1) || !_patches.allow_shares) return CMD_ERROR;
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_OTHER);
 
	p = GetPlayer(p1);
 
	p = GetPlayer((PlayerID)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;
 

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

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

	
 
		for (i = 0; p->share_owners[i] == _current_player;) {
 
			if (++i == 4) {
 
				p->bankrupt_value = 0;
 
				DoAcquireCompany(p);
 
				break;
 
			}
 
		}
 
@@ -1647,59 +1646,59 @@ int32 CmdBuyShareInCompany(TileIndex til
 
 * @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 (!IsValidPlayer((PlayerID)p1) || !_patches.allow_shares) return CMD_ERROR;
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_OTHER);
 
	p = GetPlayer(p1);
 
	p = GetPlayer((PlayerID)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) {
 
		PlayerID* b = p->share_owners;
 
		PlayerByte* b = p->share_owners;
 
		while (*b != _current_player) b++; /* share owners is guaranteed to contain player */
 
		*b = PLAYER_SPECTATOR;
 
		InvalidateWindow(WC_COMPANY, 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 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 (!IsValidPlayer((PlayerID)p1) || _networking) return CMD_ERROR;
 

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

	
 
	if (!p->is_ai) return CMD_ERROR;
 

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

	
 
// Prices
 
static void SaveLoad_PRIC(void)
 
{
 
@@ -1721,18 +1720,18 @@ static const SaveLoad _economy_desc[] = 
 
	SLE_VAR(Economy, interest_rate,    SLE_UINT8),
 
	SLE_VAR(Economy, infl_amount,      SLE_UINT8),
 
	SLE_VAR(Economy, infl_amount_pr,   SLE_UINT8),
 
	SLE_END()
 
};
 

	
 
// Economy variables
 
static void SaveLoad_ECMY(void)
 
{
 
	SlObject(&_economy, _economy_desc);
 
}
 

	
 
const ChunkHandler _economy_chunk_handlers[] = {
 
extern const ChunkHandler _economy_chunk_handlers[] = {
 
	{ 'PRIC', SaveLoad_PRIC, SaveLoad_PRIC, CH_RIFF | CH_AUTO_LENGTH},
 
	{ 'CAPR', SaveLoad_CAPR, SaveLoad_CAPR, CH_RIFF | CH_AUTO_LENGTH},
 
	{ 'SUBS', Save_SUBS,     Load_SUBS,     CH_ARRAY},
 
	{ 'ECMY', SaveLoad_ECMY, SaveLoad_ECMY, CH_RIFF | CH_LAST},
 
};