Fixed race selection and slot exclusion ("closed") in gui-started network

game. Don't think this was easy..
This commit is contained in:
ariclone 2002-05-23 20:42:33 +00:00
parent 0b968efaac
commit cd172b24fb
3 changed files with 176 additions and 75 deletions

View file

@ -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;

View file

@ -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;

View file

@ -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;