|
@@ -217,89 +217,90 @@ static void SubtractMoneyFromAnyPlayer(P
|
|
|
{
|
|
|
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))
|
|
|
if (HASBIT(1<<7|1<<8|1<<9|1<<10, _yearly_expenses_type)) {
|
|
|
p->cur_economy.income -= cost;
|
|
|
else if (( 1 << _yearly_expenses_type ) & (1<<2|1<<3|1<<4|1<<5|1<<6|1<<11))
|
|
|
} 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 (pid < MAX_PLAYERS) SubtractMoneyFromAnyPlayer(GetPlayer(pid), cost);
|
|
|
}
|
|
|
|
|
|
void SubtractMoneyFromPlayerFract(PlayerID player, int32 cost)
|
|
|
{
|
|
|
Player *p = GetPlayer(player);
|
|
|
byte m = p->player_money_fraction;
|
|
|
|
|
|
p->player_money_fraction = m - (byte)cost;
|
|
|
cost >>= 8;
|
|
|
if (p->player_money_fraction > m)
|
|
|
cost++;
|
|
|
if (cost != 0)
|
|
|
SubtractMoneyFromAnyPlayer(p, cost);
|
|
|
if (p->player_money_fraction > m) cost++;
|
|
|
if (cost != 0) SubtractMoneyFromAnyPlayer(p, cost);
|
|
|
}
|
|
|
|
|
|
// the player_money field is kept as it is, but money64 contains the actual amount of money.
|
|
|
void UpdatePlayerMoney32(Player *p)
|
|
|
{
|
|
|
if (p->money64 < -2000000000)
|
|
|
if (p->money64 < -2000000000) {
|
|
|
p->player_money = -2000000000;
|
|
|
else if (p->money64 > 2000000000)
|
|
|
} else if (p->money64 > 2000000000) {
|
|
|
p->player_money = 2000000000;
|
|
|
else
|
|
|
} else {
|
|
|
p->player_money = (int32)p->money64;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void GetNameOfOwner(PlayerID owner, TileIndex tile)
|
|
|
{
|
|
|
SetDParam(2, owner);
|
|
|
|
|
|
if (owner != OWNER_TOWN) {
|
|
|
if (owner >= 8)
|
|
|
if (owner >= MAX_PLAYERS) {
|
|
|
SetDParam(0, STR_0150_SOMEONE);
|
|
|
else {
|
|
|
} else {
|
|
|
const Player* p = GetPlayer(owner);
|
|
|
|
|
|
SetDParam(0, p->name_1);
|
|
|
SetDParam(1, p->name_2);
|
|
|
}
|
|
|
} else {
|
|
|
Town *t = ClosestTownFromTile(tile, (uint)-1);
|
|
|
const 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;
|
|
|
if (owner == _current_player) return true;
|
|
|
_error_message = STR_013B_OWNED_BY;
|
|
|
GetNameOfOwner(owner, 0);
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
bool CheckTileOwnership(TileIndex tile)
|
|
|
{
|
|
|
PlayerID owner = GetTileOwner(tile);
|
|
|
|
|
|
assert(owner <= OWNER_WATER);
|
|
|
|
|
|
if (owner == _current_player)
|
|
|
return true;
|
|
|
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;
|
|
|
}
|
|
@@ -310,30 +311,27 @@ static void GenerateCompanyName(Player *
|
|
|
Town *t;
|
|
|
StringID str;
|
|
|
Player *pp;
|
|
|
uint32 strp;
|
|
|
char buffer[100];
|
|
|
|
|
|
if (p->name_1 != STR_SV_UNNAMED)
|
|
|
return;
|
|
|
if (p->name_1 != STR_SV_UNNAMED) return;
|
|
|
|
|
|
tile = p->last_build_coordinate;
|
|
|
if (tile == 0)
|
|
|
return;
|
|
|
if (tile == 0) return;
|
|
|
|
|
|
t = ClosestTownFromTile(tile, (uint)-1);
|
|
|
|
|
|
if (IS_INT_INSIDE(t->townnametype, SPECSTR_TOWNNAME_START, SPECSTR_TOWNNAME_LAST+1)) {
|
|
|
str = t->townnametype - SPECSTR_TOWNNAME_START + SPECSTR_PLAYERNAME_START;
|
|
|
strp = t->townnameparts;
|
|
|
|
|
|
verify_name:;
|
|
|
// No player must have this name already
|
|
|
FOR_ALL_PLAYERS(pp) {
|
|
|
if (pp->name_1 == str && pp->name_2 == strp)
|
|
|
goto bad_town_name;
|
|
|
if (pp->name_1 == str && pp->name_2 == strp) goto bad_town_name;
|
|
|
}
|
|
|
|
|
|
GetString(buffer, str);
|
|
|
if (strlen(buffer) >= 32 || GetStringWidth(buffer) >= 150)
|
|
|
goto bad_town_name;
|
|
|
|
|
@@ -420,17 +418,14 @@ static byte GeneratePlayerColor(void)
|
|
|
}
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// Return the first available color
|
|
|
i = 0;
|
|
|
for (;;) {
|
|
|
if (colors[i] != 0xFF)
|
|
|
return colors[i];
|
|
|
i++;
|
|
|
for (i = 0;; i++) {
|
|
|
if (colors[i] != 0xFF) return colors[i];
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static void GeneratePresidentName(Player *p)
|
|
|
{
|
|
|
Player *pp;
|
|
@@ -848,14 +843,15 @@ int32 CmdPlayerCtrl(TileIndex tile, uint
|
|
|
}
|
|
|
} else if (p->index == _local_player) {
|
|
|
DoCommandP(0, (_patches.autorenew << 15 ) | (_patches.autorenew_months << 16) | 4, _patches.autorenew_money, NULL, CMD_REPLACE_VEHICLE);
|
|
|
}
|
|
|
#ifdef ENABLE_NETWORK
|
|
|
if (_network_server) {
|
|
|
/* XXX - UGLY! p2 (pid) is mis-used to fetch the client-id, done at server-side
|
|
|
* in network_server.c:838, function DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_COMMAND) */
|
|
|
/* XXX - UGLY! p2 (pid) is mis-used to fetch the client-id, done at
|
|
|
* server-side in network_server.c:838, function
|
|
|
* DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_COMMAND) */
|
|
|
NetworkClientInfo *ci = &_network_client_info[pid];
|
|
|
ci->client_playas = p->index + 1;
|
|
|
NetworkUpdateClientInfo(ci->client_index);
|
|
|
|
|
|
if (ci->client_playas != 0 && ci->client_playas <= MAX_PLAYERS) {
|
|
|
PlayerID player_backup = _local_player;
|
|
@@ -875,22 +871,22 @@ int32 CmdPlayerCtrl(TileIndex tile, uint
|
|
|
_cmd_text = ci->client_name;
|
|
|
_local_player = ci->client_playas - 1;
|
|
|
NetworkSend_Command(0, 0, 0, CMD_CHANGE_PRESIDENT_NAME, NULL);
|
|
|
_local_player = player_backup;
|
|
|
}
|
|
|
}
|
|
|
} else if (_network_server) { // Creating player failed, defer client to spectator
|
|
|
/* XXX - UGLY! p2 (pid) is mis-used to fetch the client-id, done at server-side
|
|
|
* in network_server.c:838, function DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_COMMAND) */
|
|
|
} else if (_network_server) {
|
|
|
// Creating player failed, defer client to spectator
|
|
|
/* XXX - UGLY! p2 (pid) is mis-used to fetch the client-id, done at
|
|
|
* server-side in network_server.c:838, function
|
|
|
* DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_COMMAND) */
|
|
|
NetworkClientInfo *ci = &_network_client_info[pid];
|
|
|
ci->client_playas = OWNER_SPECTATOR;
|
|
|
NetworkUpdateClientInfo(ci->client_index);
|
|
|
#endif /* ENABLE_NETWORK */
|
|
|
}
|
|
|
#else
|
|
|
}
|
|
|
#endif /* ENABLE_NETWORK */
|
|
|
} break;
|
|
|
|
|
|
case 1: /* Make a new AI player */
|
|
|
if (!(flags & DC_EXEC)) return 0;
|
|
|
|
|
|
DoStartupNewPlayer(true);
|
|
@@ -938,13 +934,13 @@ int32 CmdPlayerCtrl(TileIndex tile, uint
|
|
|
default: return CMD_ERROR;
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
static const StringID _endgame_perf_titles[16] = {
|
|
|
static const StringID _endgame_perf_titles[] = {
|
|
|
STR_0213_BUSINESSMAN,
|
|
|
STR_0213_BUSINESSMAN,
|
|
|
STR_0213_BUSINESSMAN,
|
|
|
STR_0213_BUSINESSMAN,
|
|
|
STR_0213_BUSINESSMAN,
|
|
|
STR_0214_ENTREPRENEUR,
|
|
@@ -954,32 +950,30 @@ static const StringID _endgame_perf_titl
|
|
|
STR_0216_CAPITALIST,
|
|
|
STR_0216_CAPITALIST,
|
|
|
STR_0217_MAGNATE,
|
|
|
STR_0217_MAGNATE,
|
|
|
STR_0218_MOGUL,
|
|
|
STR_0218_MOGUL,
|
|
|
STR_0219_TYCOON_OF_THE_CENTURY,
|
|
|
STR_0219_TYCOON_OF_THE_CENTURY
|
|
|
};
|
|
|
|
|
|
StringID EndGameGetPerformanceTitleFromValue(uint value)
|
|
|
{
|
|
|
value = minu(value, 1000) >> 6;
|
|
|
if (value >= lengthof(_endgame_perf_titles)) value = lengthof(_endgame_perf_titles) - 1;
|
|
|
value = minu(value / 64, lengthof(_endgame_perf_titles) - 1);
|
|
|
|
|
|
return _endgame_perf_titles[value];
|
|
|
}
|
|
|
|
|
|
/* Return true if any cheat has been used, false otherwise */
|
|
|
static bool CheatHasBeenUsed(void)
|
|
|
{
|
|
|
const Cheat* cht = (Cheat*) &_cheats;
|
|
|
const Cheat* cht = (Cheat*)&_cheats;
|
|
|
const Cheat* cht_last = &cht[sizeof(_cheats) / sizeof(Cheat)];
|
|
|
|
|
|
for (; cht != cht_last; cht++) {
|
|
|
if (cht->been_used)
|
|
|
return true;
|
|
|
if (cht->been_used) return true;
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
/* Save the highscore for the player */
|
|
@@ -1106,13 +1100,13 @@ void LoadFromHighScore(void)
|
|
|
}
|
|
|
}
|
|
|
fclose(fp);
|
|
|
}
|
|
|
|
|
|
/* Initialize end of game variable (when to show highscore chart) */
|
|
|
_patches.ending_date = 2051;
|
|
|
_patches.ending_date = 2051;
|
|
|
}
|
|
|
|
|
|
// Save/load of players
|
|
|
static const SaveLoad _player_desc[] = {
|
|
|
SLE_VAR(Player,name_2, SLE_UINT32),
|
|
|
SLE_VAR(Player,name_1, SLE_STRINGID),
|