// update players damage stats. void updateMultiStatsDamage(UDWORD attacker, UDWORD defender, UDWORD inflicted) { PLAYERSTATS st; if (Cheated) { return; } // FIXME: Why in the world are we using two different structs for stats when we can use only one? // Host controls self + AI, so update the scores for them as well. if (attacker < MAX_PLAYERS) { if (myResponsibility(attacker) && NetPlay.bComms) { st = getMultiStats(attacker); // get stats if (NetPlay.bComms) { st.scoreToAdd += (2 * inflicted); } else { st.recentScore += (2 * inflicted); } setMultiStats(attacker, st, true); } else { ingame.skScores[attacker][0] += (2 * inflicted); // increment skirmish players rough score. } } // FIXME: Why in the world are we using two different structs for stats when we can use only one? // Host controls self + AI, so update the scores for them as well. if (defender < MAX_PLAYERS) { if (myResponsibility(defender) && NetPlay.bComms) { st = getMultiStats(defender); // get stats if (NetPlay.bComms) { st.scoreToAdd -= inflicted; } else { st.recentScore -= inflicted; } setMultiStats(defender, st, true); } else { ingame.skScores[defender][0] -= inflicted; // increment skirmish players rough score. } } }
// //////////////////////////////////////////////////////////////////////////// // Host Campaign. bool hostCampaign(char *sGame, char *sPlayer) { PLAYERSTATS playerStats; UDWORD i; debug(LOG_WZ, "Hosting campaign: '%s', player: '%s'", sGame, sPlayer); freeMessages(); // If we had a single player (i.e. campaign) game before this value will // have been set to 0. So revert back to the default value. if (game.maxPlayers == 0) { game.maxPlayers = 4; } if (!NEThostGame(sGame, sPlayer, game.type, 0, 0, 0, game.maxPlayers)) { return false; } for (i = 0; i < MAX_PLAYERS; i++) { if (NetPlay.bComms) { game.skDiff[i] = 0; // disable AI } setPlayerName(i, ""); //Clear custom names (use default ones instead) } NetPlay.players[selectedPlayer].ready = false; ingame.localJoiningInProgress = true; ingame.JoiningInProgress[selectedPlayer] = true; bMultiPlayer = true; bMultiMessages = true; // enable messages loadMultiStats(sPlayer, &playerStats); // stats stuff setMultiStats(selectedPlayer, playerStats, false); setMultiStats(selectedPlayer, playerStats, true); if (!NetPlay.bComms) { sstrcpy(NetPlay.players[0].name, sPlayer); } return true; }
// //////////////////////////////////////////////////////////////////////////// // Setup Stuff for a new player. void setupNewPlayer(UDWORD player) { UDWORD i; ingame.PingTimes[player] = 0; // Reset ping time ingame.JoiningInProgress[player] = true; // Note that player is now joining ingame.DataIntegrity[player] = false; for (i = 0; i < MAX_PLAYERS; i++) // Set all alliances to broken { alliances[selectedPlayer][i] = ALLIANCE_BROKEN; alliances[i][selectedPlayer] = ALLIANCE_BROKEN; } resetMultiVisibility(player); // set visibility flags. setMultiStats(player, getMultiStats(player), true); // get the players score if (selectedPlayer != player) { char buf[255]; ssprintf(buf, _("%s is joining the game"), getPlayerName(player)); addConsoleMessage(buf, DEFAULT_JUSTIFY, SYSTEM_MESSAGE); } }
// update kills void updateMultiStatsKills(BASE_OBJECT *psKilled,UDWORD player) { PLAYERSTATS st; if (Cheated) { return; } // FIXME: Why in the world are we using two different structs for stats when we can use only one? // Host controls self + AI, so update the scores for them as well. if(myResponsibility(player) && NetPlay.bComms) { st = getMultiStats(player); if(NetPlay.bComms) { st.killsToAdd++; // increase kill count; } else { st.recentKills++; } setMultiStats(player, st, true); } else { ingame.skScores[player][1]++; } }
// //////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////// // Score // We use setMultiStats() to broadcast the score when needed. bool sendScoreCheck(void) { static UDWORD lastsent = 0; if (lastsent > gameTime) { lastsent= 0; } if (gameTime - lastsent < SCORE_FREQUENCY) { return true; } lastsent = gameTime; // Broadcast any changes in other players, but not in FRONTEND!!! if (titleMode != MULTIOPTION && titleMode != MULTILIMIT) { uint8_t i; for (i = 0; i < game.maxPlayers; i++) { // Host controls AI's scores + his own... if (myResponsibility(i)) { // Send score to everyone else setMultiStats(i, getMultiStats(i), false); } } } return true; }
//games lost. void updateMultiStatsLoses(void) { PLAYERSTATS st; if (Cheated) { return; } st = getMultiStats(selectedPlayer); ++st.losses; setMultiStats(selectedPlayer, st, true); }
// games won void updateMultiStatsWins(void) { PLAYERSTATS st; if (Cheated) { return; } st = getMultiStats(selectedPlayer); st.wins ++; setMultiStats(selectedPlayer, st, true); }
BOOL joinCampaign(UDWORD gameNumber, char *sPlayer) { PLAYERSTATS playerStats; if(!ingame.localJoiningInProgress) { if (!NETjoinGame(gameNumber, sPlayer)) // join { return false; } ingame.localJoiningInProgress = true; loadMultiStats(sPlayer,&playerStats); setMultiStats(selectedPlayer, playerStats, false); setMultiStats(selectedPlayer, playerStats, true); return true; } return false; }
// //////////////////////////////////////////////////////////////////////////// // A Remote Player has joined the game. bool MultiPlayerJoin(UDWORD playerIndex) { if(widgGetFromID(psWScreen,IDRET_FORM)) // if ingame. { audio_QueueTrack( ID_CLAN_ENTER ); } if(widgGetFromID(psWScreen,MULTIOP_PLAYERS)) // if in multimenu. { if (!multiRequestUp && (bHosted || ingame.localJoiningInProgress)) { addPlayerBox(true); // update the player box. } } if(NetPlay.isHost) // host responsible for welcoming this player. { // if we've already received a request from this player don't reallocate. if (ingame.JoiningInProgress[playerIndex]) { return true; } ASSERT(NetPlay.playercount <= MAX_PLAYERS, "Too many players!"); // setup data for this player, then broadcast it to the other players. setupNewPlayer(playerIndex); // setup all the guff for that player. if (bHosted) { sendOptions(); } // if skirmish and game full, then kick... if (NetPlay.playercount > game.maxPlayers) { kickPlayer(playerIndex, "the game is already full.", ERROR_FULL); } // send everyone's stats to the new guy { int i; for (i = 0; i < MAX_PLAYERS; i++) { if (NetPlay.players[i].allocated) { setMultiStats(i, getMultiStats(i), false); } } } } return true; }
// //////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////// // Score // We use setMultiStats() to broadcast the score when needed. BOOL sendScoreCheck(void) { static UDWORD lastsent = 0; if (lastsent > gameTime) { lastsent= 0; } if (gameTime - lastsent < SCORE_FREQUENCY) { return true; } lastsent = gameTime; // Broadcast any changes in other players, but not in FRONTEND!!! if (titleMode != MULTIOPTION && titleMode != MULTILIMIT) { uint8_t i; for (i = 0; i < MAX_PLAYERS; i++) { PLAYERSTATS stats; // Host controls AI's scores + his own... if (myResponsibility(i)) { // Update score stats = getMultiStats(i); // Add recently scored points stats.recentKills += stats.killsToAdd; stats.totalKills += stats.killsToAdd; stats.recentScore += stats.scoreToAdd; stats.totalScore += stats.scoreToAdd; // Zero them out stats.killsToAdd = stats.scoreToAdd = 0; // Send score to everyone else setMultiStats(i, stats, false); } } } return true; }
// //////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////// // Score // We use setMultiStats() to broadcast the score when needed. bool sendScoreCheck(void) { // Broadcast any changes in other players, but not in FRONTEND!!! if (titleMode != MULTIOPTION && titleMode != MULTILIMIT) { uint8_t i; for (i = 0; i < game.maxPlayers; i++) { // Host controls AI's scores + his own... if (myResponsibility(i)) { // Send score to everyone else setMultiStats(i, getMultiStats(i), false); } } } return true; }