Fixed race selection and slot exclusion ("closed") in gui-started network
game. Don't think this was easy..
This commit is contained in:
parent
0b968efaac
commit
cd172b24fb
3 changed files with 176 additions and 75 deletions
src
|
@ -842,30 +842,85 @@ global void NetworkServerResyncClients(void)
|
|||
global void NetworkServerStartGame(void)
|
||||
{
|
||||
int h, i, j, n;
|
||||
unsigned long u;
|
||||
int num[PlayerMax];
|
||||
int num[PlayerMax], org[PlayerMax], rev[PlayerMax];
|
||||
char buf[1024];
|
||||
InitMessage *msg;
|
||||
InitMessage message, statemsg;
|
||||
|
||||
DebugCheck(ServerSetupState.CompOpt[0] != 0);
|
||||
|
||||
// save it first..
|
||||
LocalSetupState = ServerSetupState;
|
||||
|
||||
// Make a list of the available player slots.
|
||||
for (h = i = 0; i < PlayerMax; i++) {
|
||||
if (ScenSelectPudInfo->PlayerType[i] == PlayerPerson) {
|
||||
rev[i] = h;
|
||||
num[h++] = i;
|
||||
DebugLevel3Fn("Slot %d is available for an interactive player\n", i);
|
||||
DebugLevel0Fn("Slot %d is available for an interactive player (%d)\n", i, rev[i]);
|
||||
}
|
||||
}
|
||||
// Make a list of the available computer slots.
|
||||
n = h;
|
||||
for (i = 0; i < PlayerMax; i++) {
|
||||
if (ScenSelectPudInfo->PlayerType[i] == PlayerComputer) {
|
||||
rev[i] = n++;
|
||||
DebugLevel0Fn("Slot %d is available for an ai computer player (%d)\n", i, rev[i]);
|
||||
}
|
||||
}
|
||||
// Make a list of the remaining slots.
|
||||
for (i = 0; i < PlayerMax; i++) {
|
||||
if (ScenSelectPudInfo->PlayerType[i] != PlayerPerson &&
|
||||
ScenSelectPudInfo->PlayerType[i] != PlayerComputer) {
|
||||
rev[i] = n++;
|
||||
// PlayerNobody - not available to anything..
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
printf("INITIAL ServerSetupState:\n");
|
||||
for (i = 0; i < PlayerMax-1; i++) {
|
||||
printf("%02d: CO: %d Race: %d Host: ", i, ServerSetupState.CompOpt[i], ServerSetupState.Race[i]);
|
||||
if (ServerSetupState.CompOpt[i] == 0) {
|
||||
printf(" %d.%d.%d.%d:%d %s", NIPQUAD(ntohl(Hosts[i].Host)),
|
||||
ntohs(Hosts[i].Port), Hosts[i].PlyName);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
// Reverse to assign slots to menu setup state positions.
|
||||
for (i = 0; i < PlayerMax; i++) {
|
||||
org[i] = -1;
|
||||
for (j = 0; j < PlayerMax; j++) {
|
||||
if (rev[j] == i) {
|
||||
org[i] = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
printf("\n"); for (i=0;i<PlayerMax;i++) printf("% 2d: %d\n", i, org[i]); printf("\n");
|
||||
#endif
|
||||
|
||||
// Compact host list.. (account for computer/closed slots in the middle..)
|
||||
for (i = 1; i < PlayerMax; i++) {
|
||||
for (i = 1; i < h; i++) {
|
||||
if (Hosts[i].PlyNr == 0) {
|
||||
for (j = i + 1; j < PlayerMax - 1; j++) {
|
||||
if (Hosts[j].PlyNr) {
|
||||
DebugLevel0Fn("Compact: Hosts %d -> Hosts %d\n", j, i);
|
||||
Hosts[i] = Hosts[j];
|
||||
DebugLevel3Fn("Compact: Hosts %d -> Hosts %d\n", j, i);
|
||||
Hosts[j].PlyNr = 0;
|
||||
Hosts[j].PlyNr = Hosts[j].Host = Hosts[j].Port = 0;
|
||||
n = LocalSetupState.CompOpt[i];
|
||||
LocalSetupState.CompOpt[i] = LocalSetupState.CompOpt[j];
|
||||
LocalSetupState.CompOpt[j] = n;
|
||||
n = LocalSetupState.Race[i];
|
||||
LocalSetupState.Race[i] = LocalSetupState.Race[j];
|
||||
LocalSetupState.Race[j] = n;
|
||||
n = LocalSetupState.LastFrame[i];
|
||||
LocalSetupState.LastFrame[i] = LocalSetupState.LastFrame[j];
|
||||
LocalSetupState.LastFrame[j] = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -874,67 +929,51 @@ global void NetworkServerStartGame(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
// Randomize the position.
|
||||
for (i = 0; i < NetPlayers; i++) {
|
||||
if (h > 0) {
|
||||
int chosen = MyRand() % h;
|
||||
|
||||
DebugLevel3Fn("Assigning player %d to slot %i\n", i, num[chosen]);
|
||||
Hosts[i].PlyNr = num[chosen];
|
||||
num[chosen] = num[--h];
|
||||
// Randomize the position.
|
||||
j = h;
|
||||
for (i = 0; i < NetPlayers; i++) {
|
||||
if (j > 0) {
|
||||
int k, o, chosen = MyRand() % j;
|
||||
|
||||
n = num[chosen];
|
||||
Hosts[i].PlyNr = n;
|
||||
k = org[i];
|
||||
if (k != n) {
|
||||
for (o = 0; o < PlayerMax; o++) {
|
||||
if (org[o] == n) {
|
||||
org[o] = k;
|
||||
break;
|
||||
}
|
||||
}
|
||||
org[i] = n;
|
||||
}
|
||||
DebugLevel0Fn("Assigning player %d to slot %d (%d)\n", i, n, org[i]);
|
||||
|
||||
num[chosen] = num[--j];
|
||||
} else {
|
||||
DebugCheck(1 == 1);
|
||||
#if 0
|
||||
// ARI: is this code path realy executed? (initially h >= NetPlayers..)
|
||||
// ARI: is this code path really executed? (initially h >= NetPlayers..)
|
||||
Hosts[i].PlyNr = num[0];
|
||||
DebugLevel0Fn("Hosts[%d].PlyNr = %i\n", i, num[0]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// Shuffle setup states to match the assigned Host slots.
|
||||
for (i = 0; i < PlayerMax; i++) {
|
||||
num[i] = 0;
|
||||
}
|
||||
for (i = 0; i < NetPlayers; i++) {
|
||||
num[Hosts[i].PlyNr] = 1;
|
||||
}
|
||||
for (i = 0; i < NetPlayers; i++) {
|
||||
h = Hosts[i].PlyNr;
|
||||
if (ServerSetupState.CompOpt[h]) {
|
||||
for (j = 0; j < PlayerMax; j++) {
|
||||
if (num[j] == 0 && ServerSetupState.CompOpt[j] == 0) {
|
||||
u = ServerSetupState.CompOpt[h];
|
||||
ServerSetupState.CompOpt[h] = ServerSetupState.CompOpt[j];
|
||||
ServerSetupState.CompOpt[j] = u;
|
||||
u = ServerSetupState.Race[h];
|
||||
ServerSetupState.Race[h] = ServerSetupState.Race[j];
|
||||
ServerSetupState.Race[j] = u;
|
||||
u = ServerSetupState.LastFrame[h];
|
||||
ServerSetupState.LastFrame[h] = ServerSetupState.LastFrame[j];
|
||||
ServerSetupState.LastFrame[j] = u;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
for (i = 0; i < PlayerMax-1; i++) {
|
||||
printf("%02d: CO: %d Race: %d Host: ", i, ServerSetupState.CompOpt[i], ServerSetupState.Race[i]);
|
||||
if (ServerSetupState.CompOpt[i] == 0) {
|
||||
for (j = 0; j < NetPlayers; j++) {
|
||||
if (Hosts[j].PlyNr == i) {
|
||||
printf(" %d.%d.%d.%d:%d %s", NIPQUAD(ntohl(Hosts[j].Host)),
|
||||
ntohs(Hosts[j].Port), Hosts[j].PlyName);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
#if 0
|
||||
printf("\n"); for (i=0;i<PlayerMax;i++) printf("% 2d: %d\n", i, org[i]); printf("\n");
|
||||
#endif
|
||||
|
||||
// Complete all setup states for the assigned slots.
|
||||
for (i = 0; i < PlayerMax; i++) {
|
||||
num[i] = 1;
|
||||
n = org[i];
|
||||
ServerSetupState.CompOpt[n] = LocalSetupState.CompOpt[i];
|
||||
ServerSetupState.Race[n] = LocalSetupState.Race[i];
|
||||
ServerSetupState.LastFrame[n] = LocalSetupState.LastFrame[i];
|
||||
}
|
||||
|
||||
/* NOW we have NetPlayers in Hosts array, with ServerSetupState shuffled up to match it.. */
|
||||
|
||||
//
|
||||
|
@ -962,7 +1001,6 @@ global void NetworkServerStartGame(void)
|
|||
message.u.Hosts[i].Port = Hosts[i].Port;
|
||||
memcpy(message.u.Hosts[i].PlyName, Hosts[i].PlyName, 16);
|
||||
message.u.Hosts[i].PlyNr = htons(Hosts[i].PlyNr);
|
||||
// PlayerSetName(&Players[Hosts[i].PlyNr], Hosts[i].PlyName);
|
||||
}
|
||||
|
||||
// Prepare the final state message:
|
||||
|
@ -1207,7 +1245,7 @@ changed:
|
|||
message.SubType = ICMGo;
|
||||
NetworkSendRateLimitedClientMessage(&message, 250);
|
||||
} else {
|
||||
DebugLevel3Fn("ccs_started: Final State Enough ICMGo sent - starting\n");
|
||||
DebugLevel3Fn("ccs_started: Final state enough ICMGo sent - starting\n");
|
||||
NetConnectRunning = 0; // End the menu..
|
||||
}
|
||||
break;
|
||||
|
@ -1409,7 +1447,6 @@ local void NetworkParseMenuPacket(const InitMessage *msg, int size)
|
|||
Hosts[HostsCount].Port = msg->u.Hosts[i].Port;
|
||||
Hosts[HostsCount].PlyNr = ntohs(msg->u.Hosts[i].PlyNr);
|
||||
memcpy(Hosts[HostsCount].PlyName, msg->u.Hosts[i].PlyName, 16);
|
||||
// PlayerSetName(&Players[Hosts[HostsCount].PlyNr], Hosts[HostsCount].PlyName);
|
||||
HostsCount++;
|
||||
DebugLevel0Fn("Client %d = %d.%d.%d.%d:%d [%s]\n",
|
||||
ntohs(ntohs(msg->u.Hosts[i].PlyNr)), NIPQUAD(ntohl(msg->u.Hosts[i].Host)),
|
||||
|
@ -1425,13 +1462,18 @@ local void NetworkParseMenuPacket(const InitMessage *msg, int size)
|
|||
Hosts[HostsCount].Port = NetLastPort;
|
||||
Hosts[HostsCount].PlyNr = ntohs(msg->u.Hosts[i].PlyNr);
|
||||
memcpy(Hosts[HostsCount].PlyName, msg->u.Hosts[i].PlyName, 16);
|
||||
// PlayerSetName(&Players[Hosts[HostsCount].PlyNr], Hosts[HostsCount].PlyName);
|
||||
HostsCount++;
|
||||
NetPlayers = HostsCount + 1;
|
||||
DebugLevel0Fn("Server %d = %d.%d.%d.%d:%d [%s]\n",
|
||||
ntohs(msg->u.Hosts[i].PlyNr), NIPQUAD(ntohl(NetLastHost)),
|
||||
ntohs(NetLastPort), msg->u.Hosts[i].PlyName);
|
||||
|
||||
// put ourselves to the end, like on the server..
|
||||
Hosts[HostsCount].Host = 0;
|
||||
Hosts[HostsCount].Port = 0;
|
||||
Hosts[HostsCount].PlyNr = NetLocalPlayerNumber;
|
||||
memcpy(Hosts[HostsCount].PlyName, NetworkName, 16);
|
||||
|
||||
NetLocalState = ccs_goahead;
|
||||
NetStateMsgCnt = 0;
|
||||
break;
|
||||
|
|
|
@ -645,7 +645,8 @@ global void NetworkEvent(void)
|
|||
}
|
||||
}
|
||||
if (i == HostsCount) {
|
||||
DebugLevel0Fn("Not a host in play\n");
|
||||
DebugLevel0Fn("Not a host in play: %d.%d.%d.%d:%d\n",
|
||||
NIPQUAD(ntohl(NetLastHost)), ntohs(NetLastPort));
|
||||
return;
|
||||
}
|
||||
player = Hosts[i].PlyNr;
|
||||
|
|
|
@ -173,6 +173,7 @@ local void MultiClientRCSAction(Menuitem *mi, int i);
|
|||
|
||||
local void MultiGameStart(void);
|
||||
local void MultiGameCancel(void);
|
||||
local void NetworkGamePrepareGameSettings(void);
|
||||
local void MultiGameSetupInit(Menuitem *mi); // master init
|
||||
local void MultiGameSetupExit(Menuitem *mi); // master exit
|
||||
local void MultiGameDrawFunc(Menuitem *mi);
|
||||
|
@ -3038,6 +3039,7 @@ local void TerminateNetConnect(void)
|
|||
return;
|
||||
|
||||
case ccs_started:
|
||||
NetworkGamePrepareGameSettings();
|
||||
CustomGameStart();
|
||||
return;
|
||||
|
||||
|
@ -3081,6 +3083,7 @@ local void MultiGameStart(void)
|
|||
Invalidate();
|
||||
|
||||
NetworkServerStartGame();
|
||||
NetworkGamePrepareGameSettings();
|
||||
|
||||
CustomGameStart();
|
||||
}
|
||||
|
@ -4010,7 +4013,7 @@ local void GameRCSAction(Menuitem *mi, int i)
|
|||
|
||||
if (mi->d.pulldown.curopt == i) {
|
||||
GameSettings.Presets[0].Race = v[i];
|
||||
ServerSetupState.Race[0] = i;
|
||||
ServerSetupState.Race[0] = 2 - i;
|
||||
NetworkServerResyncClients();
|
||||
}
|
||||
}
|
||||
|
@ -4107,6 +4110,74 @@ local void MultiGameClientDrawFunc(Menuitem *mi)
|
|||
GameDrawFunc(mi);
|
||||
}
|
||||
|
||||
/**
|
||||
** Multiplayer network game final race an player type setup.
|
||||
*/
|
||||
local void NetworkGamePrepareGameSettings(void)
|
||||
{
|
||||
int h, i;
|
||||
int num[PlayerMax];
|
||||
|
||||
DebugCheck(!ScenSelectPudInfo);
|
||||
|
||||
DebugLevel0Fn("NetPlayers = %d\n", NetPlayers);
|
||||
|
||||
#ifdef DEBUG
|
||||
for (i = 0; i < PlayerMax-1; i++) {
|
||||
printf("%02d: CO: %d Race: %d Host: ", i, ServerSetupState.CompOpt[i], ServerSetupState.Race[i]);
|
||||
if (ServerSetupState.CompOpt[i] == 0) {
|
||||
for (h = 0; h < NetPlayers; h++) {
|
||||
if (Hosts[h].PlyNr == i) {
|
||||
printf("%s", Hosts[h].PlyName);
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
// Make a list of the available player slots.
|
||||
for (h = i = 0; i < PlayerMax-1; i++) {
|
||||
if (ScenSelectPudInfo->PlayerType[i] == PlayerPerson) {
|
||||
DebugLevel3Fn("Player slot %i is available for a person\n", i);
|
||||
num[h++] = i;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < h; i++) {
|
||||
switch(ServerSetupState.CompOpt[num[i]]) {
|
||||
case 0:
|
||||
GameSettings.Presets[num[i]].Type = PlayerPerson;
|
||||
DebugLevel3Fn("Settings[%d].Type == Person\n", num[i]);
|
||||
switch (ServerSetupState.Race[num[i]]) {
|
||||
case 1:
|
||||
GameSettings.Presets[num[i]].Race = PlayerRaceOrc;
|
||||
break;
|
||||
case 2:
|
||||
GameSettings.Presets[num[i]].Race = PlayerRaceHuman;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
GameSettings.Presets[num[i]].Type = PlayerComputer;
|
||||
DebugLevel3Fn("Settings[%d].Type == Computer\n", num[i]);
|
||||
break;
|
||||
case 2:
|
||||
GameSettings.Presets[num[i]].Type = PlayerNobody;
|
||||
DebugLevel3Fn("Settings[%d].Type == Closed\n", num[i]);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
for (i = 0; i < NetPlayers; i++) {
|
||||
DebugCheck(GameSettings.Presets[Hosts[i].PlyNr].Type != PlayerPerson);
|
||||
;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
** Player selectors have changed.
|
||||
** Caution: Called by map change (inital = 1)!
|
||||
|
@ -4421,16 +4492,8 @@ local void MultiClientGemAction(Menuitem *mi __attribute__((unused)))
|
|||
|
||||
local void MultiClientRCSAction(Menuitem *mi, int i)
|
||||
{
|
||||
#if 0
|
||||
int v[] = { PlayerRaceHuman, PlayerRaceOrc, SettingsPresetMapDefault };
|
||||
#endif
|
||||
|
||||
if (mi->d.pulldown.curopt == i) {
|
||||
LocalSetupState.Race[NetLocalHostsSlot] = i;
|
||||
#if 0
|
||||
// FIXME: Handle RACES -> Not visible! Delayed to final InitConfig msg...
|
||||
GameSettings.Presets[NetLocalHostsSlot].Race = v[i];
|
||||
#endif
|
||||
LocalSetupState.Race[NetLocalHostsSlot] = 2 - i;
|
||||
MultiClientUpdate(0);
|
||||
}
|
||||
}
|
||||
|
@ -4506,11 +4569,6 @@ global void NetConnectForceDisplayUpdate(void)
|
|||
*/
|
||||
global void NetClientUpdateState(void)
|
||||
{
|
||||
#if 0
|
||||
// FIXME: Handle RACES -> Not visible! Delayed to final InitConfig msg...
|
||||
GameSettings.Presets[0].Race = ServerSetupState.Race[0];
|
||||
#endif
|
||||
|
||||
GameRESAction(NULL, ServerSetupState.ResOpt);
|
||||
NetMultiClientMenuItems[CLIENT_RESOURCE].d.pulldown.curopt =
|
||||
ServerSetupState.ResOpt;
|
||||
|
|
Loading…
Add table
Reference in a new issue