|
@@ -761,100 +761,110 @@ int32 CmdReplaceVehicle(int x, int y, ui
|
|
|
InvalidateWindow(WC_REPLACE_VEHICLE, VEH_Train);
|
|
|
}
|
|
|
}
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
/** Control the players: add, delete, etc.
|
|
|
* @param x,y unused
|
|
|
* @param p1 various functionality
|
|
|
* - p1 = 0 - create a new player, Which player (network) it will be is in p2
|
|
|
* - p1 = 1 - create a new AI player
|
|
|
* - p1 = 2 - delete a player. Player is identified by p2
|
|
|
* - p1 = 3 - merge two companies together. Player to merge #1 with player #2. Identified by p2
|
|
|
* @param p2 various functionality, dictated by p1
|
|
|
* - p1 = 0 - ClientID of the newly created player
|
|
|
* - p1 = 2 - PlayerID of the that is getting deleted
|
|
|
* - p1 = 3 - #1 p2 = (bit 0-15) - player to merge (p2 & 0xFFFF)
|
|
|
* - #2 p2 = (bit 16-31) - player to be merged into ((p2>>16)&0xFFFF)
|
|
|
* @todo In the case of p1=0, create new player, the clientID of the new player is in parameter
|
|
|
* p2. This parameter is passed in at function DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_COMMAND)
|
|
|
* on the server itself. First of all this is unbelievably ugly; second of all, well,
|
|
|
* it IS ugly! <b>Someone fix this up :)</b> So where to fix?@n
|
|
|
* @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(int x, int y, 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;
|
|
|
|
|
|
p = DoStartupNewPlayer(false);
|
|
|
|
|
|
#ifdef ENABLE_NETWORK
|
|
|
if (_networking && !_network_server && _local_player == OWNER_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 == OWNER_SPECTATOR) {
|
|
|
if (_local_player == OWNER_SPECTATOR && (!_ai.network_client || _ai.network_playas == OWNER_SPECTATOR)) {
|
|
|
/* Check if we do not want to be a spectator in network */
|
|
|
if (!_networking || (_network_server && !_network_dedicated) || _network_playas != OWNER_SPECTATOR) {
|
|
|
_local_player = p->index;
|
|
|
if (!_networking || (_network_server && !_network_dedicated) || _network_playas != OWNER_SPECTATOR || _ai.network_client) {
|
|
|
if (_ai.network_client) {
|
|
|
/* As ai-network-client, we have our own rulez (disable GUI and stuff) */
|
|
|
_ai.network_playas = p->index;
|
|
|
_local_player = OWNER_SPECTATOR;
|
|
|
if (_ai.network_playas != OWNER_SPECTATOR) {
|
|
|
/* If we didn't join the game as a spectator, activate the AI */
|
|
|
AI_StartNewAI(_ai.network_playas);
|
|
|
}
|
|
|
} else {
|
|
|
_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_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) */
|
|
|
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;
|
|
|
_network_player_info[p->index].months_empty = 0;
|
|
|
|
|
|
/* XXX - When a client joins, we automatically set its name to the
|
|
|
* player's name (for some reason). As it stands now only the server
|
|
|
* knows the client's name, so it needs to send out a "broadcast" to
|
|
|
* do this. To achieve this we send a network command. However, it
|
|
|
* uses _local_player to execute the command as. To prevent abuse
|
|
|
* (eg. only yourself can change your name/company), we 'cheat' by
|
|
|
* impersonation _local_player as the server. Not the best solution;
|
|
|
* but it works.
|
|
|
* TODO: Perhaps this could be improved by when the client is ready
|
|
|
* with joining to let it send itself the command, and not the server?
|
|
|
* For example in network_client.c:534? */
|
|
|
_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) {
|
|
|
/* 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);
|
|
|
}
|
|
|
#else
|
|
|
}
|
|
|
#endif /* ENABLE_NETWORK */
|
|
|
} break;
|
|
|
|
|
|
case 1: /* Make a new AI player */
|
|
|
if (!(flags & DC_EXEC)) return 0;
|