From cd172b24fb10fb3927792ae0f95b24514a961592 Mon Sep 17 00:00:00 2001 From: ariclone <> Date: Thu, 23 May 2002 20:42:33 +0000 Subject: [PATCH] Fixed race selection and slot exclusion ("closed") in gui-started network game. Don't think this was easy.. --- src/network/netconnect.cpp | 160 +++++++++++++++++++++++-------------- src/network/network.cpp | 3 +- src/ui/menus.cpp | 88 ++++++++++++++++---- 3 files changed, 176 insertions(+), 75 deletions(-) diff --git a/src/network/netconnect.cpp b/src/network/netconnect.cpp index 7c2a19071..2552bc8f5 100644 --- a/src/network/netconnect.cpp +++ b/src/network/netconnect.cpp @@ -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; diff --git a/src/network/network.cpp b/src/network/network.cpp index 497c32519..9c3b1ceb5 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -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; diff --git a/src/ui/menus.cpp b/src/ui/menus.cpp index 532a4ecc1..22568827d 100644 --- a/src/ui/menus.cpp +++ b/src/ui/menus.cpp @@ -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;