|
|
|
@ -819,34 +819,50 @@ int32 CmdPlayerCtrl(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|
|
|
|
|
|
|
|
|
switch (p1) {
|
|
|
|
|
case 0: { /* Create a new player */
|
|
|
|
|
/* Joining Client:
|
|
|
|
|
* _local_player: PLAYER_SPECTATOR
|
|
|
|
|
* _network_playas/cid = requested company/player
|
|
|
|
|
*
|
|
|
|
|
* Other client(s)/server:
|
|
|
|
|
* _local_player/_network_playas: what they play as
|
|
|
|
|
* cid = requested company/player of joining client */
|
|
|
|
|
Player *p;
|
|
|
|
|
uint16 cid = p2; // ClientID
|
|
|
|
|
|
|
|
|
|
/* This command is only executed in a multiplayer game */
|
|
|
|
|
if (!_networking) return CMD_ERROR;
|
|
|
|
|
|
|
|
|
|
/* ClientID would be valid up to MAX_CLIENT_INFO, but as it has to be a
|
|
|
|
|
* new player, its valid range is restricted to that of players */
|
|
|
|
|
if (!(flags & DC_EXEC) || !IsValidPlayer((PlayerID)cid)) return 0;
|
|
|
|
|
|
|
|
|
|
/* Delete multiplayer progress bar */
|
|
|
|
|
DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0);
|
|
|
|
|
|
|
|
|
|
p = DoStartupNewPlayer(false);
|
|
|
|
|
|
|
|
|
|
/* A new player could not be created, revert to being a spectator */
|
|
|
|
|
if (p == NULL) {
|
|
|
|
|
#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);
|
|
|
|
|
}
|
|
|
|
|
if (_network_server) {
|
|
|
|
|
NetworkClientInfo *ci = &_network_client_info[cid];
|
|
|
|
|
ci->client_playas = PLAYER_SPECTATOR;
|
|
|
|
|
NetworkUpdateClientInfo(ci->client_index);
|
|
|
|
|
} else
|
|
|
|
|
#endif /* ENABLE_NETWORK */
|
|
|
|
|
{
|
|
|
|
|
_local_player = _network_playas = PLAYER_SPECTATOR;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (p != NULL) {
|
|
|
|
|
if (_local_player == PLAYER_SPECTATOR) {
|
|
|
|
|
/* Check if we do not want to be a spectator in network */
|
|
|
|
|
if (!_networking ||
|
|
|
|
|
(_network_server && !_network_dedicated) ||
|
|
|
|
|
_network_playas != PLAYER_SPECTATOR) {
|
|
|
|
|
/* This is the joining client who wants a new company */
|
|
|
|
|
if (_local_player != _network_playas) {
|
|
|
|
|
assert(_local_player == PLAYER_SPECTATOR && _network_playas == p->index);
|
|
|
|
|
_local_player = p->index;
|
|
|
|
|
MarkWholeScreenDirty();
|
|
|
|
|
}
|
|
|
|
|
} else if (p->index == _local_player) {
|
|
|
|
|
DoCommandP(0, (_patches.autorenew << 15 ) | (_patches.autorenew_months << 16) | 4, _patches.autorenew_money, NULL, CMD_SET_AUTOREPLACE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef ENABLE_NETWORK
|
|
|
|
|
if (_network_server) {
|
|
|
|
|
/* XXX - UGLY! p2 (pid) is mis-used to fetch the client-id, done at
|
|
|
|
@ -877,16 +893,7 @@ int32 CmdPlayerCtrl(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|
|
|
|
_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) */
|
|
|
|
|
NetworkClientInfo *ci = &_network_client_info[cid];
|
|
|
|
|
ci->client_playas = PLAYER_SPECTATOR;
|
|
|
|
|
NetworkUpdateClientInfo(ci->client_index);
|
|
|
|
|
#endif /* ENABLE_NETWORK */
|
|
|
|
|
}
|
|
|
|
|
} break;
|
|
|
|
|
|
|
|
|
|
case 1: /* Make a new AI player */
|
|
|
|
@ -933,6 +940,7 @@ int32 CmdPlayerCtrl(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|
|
|
|
ChangeOwnershipOfPlayerItems(pid_old, pid_new);
|
|
|
|
|
DeletePlayerStuff(pid_old);
|
|
|
|
|
} break;
|
|
|
|
|
|
|
|
|
|
default: return CMD_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|