static void ReadOnePlayer (FArchive &arc, bool skipload) { int i; char *name = NULL; bool didIt = false; arc << name; for (i = 0; i < MAXPLAYERS; ++i) { if (playeringame[i]) { if (!didIt) { didIt = true; player_t playerTemp; playerTemp.Serialize (arc); if (!skipload) { CopyPlayer (&players[i], &playerTemp, name); } } else { if (players[i].mo != NULL) { players[i].mo->Destroy(); players[i].mo = NULL; } } } } delete[] name; }
static void ReadOnePlayer(FSerializer &arc, bool skipload) { int i; const char *name = NULL; bool didIt = false; if (arc.BeginObject(nullptr)) { arc.StringPtr("playername", name); for (i = 0; i < MAXPLAYERS; ++i) { if (playeringame[i]) { if (!didIt) { didIt = true; player_t playerTemp; playerTemp.Serialize(arc); if (!skipload) { // This temp player has undefined pitch limits, so set them to something // that should leave the pitch stored in the savegame intact when // rendering. The real pitch limits will be set by P_SerializePlayers() // via a net command, but that won't be processed in time for a screen // wipe, so we need something here. playerTemp.MaxPitch = playerTemp.MinPitch = playerTemp.mo->Angles.Pitch; CopyPlayer(&players[i], &playerTemp, name); } else { // we need the player actor, so that G_FinishTravel can destroy it later. players[i].mo = playerTemp.mo; } } else { if (players[i].mo != NULL) { players[i].mo->Destroy(); players[i].mo = NULL; } } } } arc.EndObject(); } }
static void ReadMultiplePlayers(FSerializer &arc, int numPlayers, int numPlayersNow, bool skipload) { // For two or more players, read each player into a temporary array. int i, j; const char **nametemp = new const char *[numPlayers]; player_t *playertemp = new player_t[numPlayers]; BYTE *tempPlayerUsed = new BYTE[numPlayers]; BYTE playerUsed[MAXPLAYERS]; for (i = 0; i < numPlayers; ++i) { nametemp[i] = NULL; if (arc.BeginObject(nullptr)) { arc.StringPtr("playername", nametemp[i]); playertemp[i].Serialize(arc); arc.EndObject(); } tempPlayerUsed[i] = 0; } for (i = 0; i < MAXPLAYERS; ++i) { playerUsed[i] = playeringame[i] ? 0 : 2; } if (!skipload) { // Now try to match players from the savegame with players present // based on their names. If two players in the savegame have the // same name, then they are assigned to players in the current game // on a first-come, first-served basis. for (i = 0; i < numPlayers; ++i) { for (j = 0; j < MAXPLAYERS; ++j) { if (playerUsed[j] == 0 && stricmp(players[j].userinfo.GetName(), nametemp[i]) == 0) { // Found a match, so copy our temp player to the real player Printf("Found player %d (%s) at %d\n", i, nametemp[i], j); CopyPlayer(&players[j], &playertemp[i], nametemp[i]); playerUsed[j] = 1; tempPlayerUsed[i] = 1; break; } } } // Any players that didn't have matching names are assigned to existing // players on a first-come, first-served basis. for (i = 0; i < numPlayers; ++i) { if (tempPlayerUsed[i] == 0) { for (j = 0; j < MAXPLAYERS; ++j) { if (playerUsed[j] == 0) { Printf("Assigned player %d (%s) to %d (%s)\n", i, nametemp[i], j, players[j].userinfo.GetName()); CopyPlayer(&players[j], &playertemp[i], nametemp[i]); playerUsed[j] = 1; tempPlayerUsed[i] = 1; break; } } } } // Make sure any extra players don't have actors spawned yet. Happens if the players // present now got the same slots as they had in the save, but there are not as many // as there were in the save. for (j = 0; j < MAXPLAYERS; ++j) { if (playerUsed[j] == 0) { if (players[j].mo != NULL) { players[j].mo->Destroy(); players[j].mo = NULL; } } } // Remove any temp players that were not used. Happens if there are fewer players // than there were in the save, and they got shuffled. for (i = 0; i < numPlayers; ++i) { if (tempPlayerUsed[i] == 0) { playertemp[i].mo->Destroy(); playertemp[i].mo = NULL; } } } else { for (i = 0; i < MAXPLAYERS; ++i) { players[i].mo = playertemp[i].mo; } } delete[] tempPlayerUsed; delete[] playertemp; delete[] nametemp; }