Fix scores usually being displayed as 0 in multiplayer.

Scores were 0 due to some complicated score synchronisation code.
Fixed mainly by removing a lot of the score synchronisation code.
master
Cyp 2011-02-24 22:40:31 +01:00
parent 00cece64ae
commit a01cc343c5
5 changed files with 35 additions and 106 deletions

View File

@ -1,7 +1,7 @@
/*
This file is part of Warzone 2100.
Copyright (C) 1999-2004 Eidos Interactive
Copyright (C) 2005-2010 Warzone 2100 Project
Copyright (C) 2005-2011 Warzone 2100 Project
Warzone 2100 is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -220,7 +220,7 @@ extern BOOL addTemplateToList(DROID_TEMPLATE *psNew, DROID_TEMPLATE **ppList);
void addTemplateBack(unsigned player, DROID_TEMPLATE *psNew);
// syncing.
extern BOOL sendCheck (void); //send/recv check info
void sendCheck(); //send/recv check info
extern BOOL sendScoreCheck (void); //score check only(frontend)
extern BOOL sendPing (void); // allow game to request pings.

View File

@ -1,7 +1,7 @@
/*
This file is part of Warzone 2100.
Copyright (C) 1999-2004 Eidos Interactive
Copyright (C) 2005-2010 Warzone 2100 Project
Copyright (C) 2005-2011 Warzone 2100 Project
Warzone 2100 is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -48,17 +48,15 @@ PLAYERSTATS getMultiStats(UDWORD player)
// ////////////////////////////////////////////////////////////////////////////
// Set Player's stats
// send stats to all players when bLocal is false
BOOL setMultiStats(SDWORD player, PLAYERSTATS plStats, BOOL bLocal)
bool setMultiStats(uint32_t playerIndex, PLAYERSTATS plStats, bool bLocal)
{
uint32_t playerIndex = (uint32_t)player;
if (playerIndex >= MAX_PLAYERS)
{
return true;
}
// First copy over the data into our local array
memcpy(&playerStats[playerIndex], &plStats, sizeof(plStats));
playerStats[playerIndex] = plStats;
if (!bLocal)
{
@ -75,8 +73,6 @@ BOOL setMultiStats(SDWORD player, PLAYERSTATS plStats, BOOL bLocal)
NETuint32_t(&playerStats[playerIndex].totalScore);
NETuint32_t(&playerStats[playerIndex].recentKills);
NETuint32_t(&playerStats[playerIndex].recentScore);
NETuint32_t(&playerStats[playerIndex].killsToAdd);
NETuint32_t(&playerStats[playerIndex].scoreToAdd);
NETend();
}
@ -108,8 +104,6 @@ void recvMultiStats(NETQUEUE queue)
NETuint32_t(&playerStats[playerIndex].totalScore);
NETuint32_t(&playerStats[playerIndex].recentKills);
NETuint32_t(&playerStats[playerIndex].recentScore);
NETuint32_t(&playerStats[playerIndex].killsToAdd);
NETuint32_t(&playerStats[playerIndex].scoreToAdd);
}
NETend();
}
@ -165,8 +159,6 @@ BOOL loadMultiStats(char *sPlayerName, PLAYERSTATS *st)
// reset recent scores
st->recentKills = 0;
st->recentScore = 0;
st->killsToAdd = 0;
st->scoreToAdd = 0;
// clear any skirmish stats.
for(size = 0;size<MAX_PLAYERS;size++)
@ -202,55 +194,35 @@ BOOL saveMultiStats(const char *sFileName, const char *sPlayerName, const PLAYER
// 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)
if (NetPlay.bComms)
{
st = getMultiStats(attacker); // get stats
if (NetPlay.bComms)
{
st.scoreToAdd += (2 * inflicted);
}
else
{
st.recentScore += (2 * inflicted);
}
setMultiStats(attacker, st, true);
playerStats[attacker].totalScore += 2 * inflicted;
playerStats[attacker].recentScore += 2 * inflicted;
}
else
{
ingame.skScores[attacker][0] += (2 * inflicted); // increment skirmish players rough score.
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)
if (NetPlay.bComms)
{
st = getMultiStats(defender); // get stats
if (NetPlay.bComms)
{
st.scoreToAdd -= inflicted;
}
else
{
st.recentScore -= inflicted;
}
setMultiStats(defender, st, true);
playerStats[defender].totalScore -= inflicted;
playerStats[defender].recentScore -= inflicted;
}
else
{
ingame.skScores[defender][0] -= inflicted; // increment skirmish players rough score.
ingame.skScores[defender][0] -= inflicted; // increment skirmish players rough score.
}
}
}
@ -258,67 +230,45 @@ void updateMultiStatsDamage(UDWORD attacker, UDWORD defender, UDWORD inflicted)
// update games played.
void updateMultiStatsGames(void)
{
PLAYERSTATS st;
if (Cheated)
if (Cheated || selectedPlayer >= MAX_PLAYERS)
{
return;
}
st = getMultiStats(selectedPlayer);
st.played ++;
setMultiStats(selectedPlayer, st, true);
++playerStats[selectedPlayer].played;
}
// games won
void updateMultiStatsWins(void)
{
PLAYERSTATS st;
if (Cheated)
if (Cheated || selectedPlayer >= MAX_PLAYERS)
{
return;
}
st = getMultiStats(selectedPlayer);
st.wins ++;
setMultiStats(selectedPlayer, st, true);
++playerStats[selectedPlayer].wins;
}
//games lost.
void updateMultiStatsLoses(void)
{
PLAYERSTATS st;
if (Cheated)
if (Cheated || selectedPlayer >= MAX_PLAYERS)
{
return;
}
st = getMultiStats(selectedPlayer);
++st.losses;
setMultiStats(selectedPlayer, st, true);
++playerStats[selectedPlayer].losses;
}
// update kills
void updateMultiStatsKills(BASE_OBJECT *psKilled,UDWORD player)
{
PLAYERSTATS st;
if (Cheated)
if (Cheated || player > MAX_PLAYERS)
{
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)
if (NetPlay.bComms)
{
st = getMultiStats(player);
if(NetPlay.bComms)
{
st.killsToAdd++; // increase kill count;
}
else
{
st.recentKills++;
}
setMultiStats(player, st, true);
++playerStats[player].totalKills;
++playerStats[player].recentKills;
}
else
{

View File

@ -1,7 +1,7 @@
/*
This file is part of Warzone 2100.
Copyright (C) 1999-2004 Eidos Interactive
Copyright (C) 2005-2010 Warzone 2100 Project
Copyright (C) 2005-2011 Warzone 2100 Project
Warzone 2100 is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -27,7 +27,7 @@
#include "lib/netplay/netplay.h"
typedef struct
struct PLAYERSTATS
{
uint32_t played; /// propogated stats.
uint32_t wins;
@ -37,15 +37,12 @@ typedef struct
uint32_t recentKills; // score/kills in last game.
uint32_t recentScore;
uint32_t killsToAdd; // things to add next time score is updated.
uint32_t scoreToAdd;
} PLAYERSTATS;
};
BOOL saveMultiStats(const char *sFName, const char *sPlayerName, const PLAYERSTATS *playerStats); // to disk
BOOL loadMultiStats(char *sPlayerName, PLAYERSTATS *playerStats); // form disk
PLAYERSTATS getMultiStats(UDWORD player); // get from net
BOOL setMultiStats(SDWORD player, PLAYERSTATS plStats,BOOL bLocal); // send to net.
bool setMultiStats(uint32_t player, PLAYERSTATS plStats, bool bLocal); // send to net.
void updateMultiStatsDamage(UDWORD attacker, UDWORD defender, UDWORD inflicted);
void updateMultiStatsGames(void);
void updateMultiStatsWins(void);

View File

@ -1,7 +1,7 @@
/*
This file is part of Warzone 2100.
Copyright (C) 1999-2004 Eidos Interactive
Copyright (C) 2005-2010 Warzone 2100 Project
Copyright (C) 2005-2011 Warzone 2100 Project
Warzone 2100 is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -113,21 +113,19 @@ static BOOL okToSend(void)
// ////////////////////////////////////////////////////////////////////////////
// Droid checking info. keep position and damage in sync.
BOOL sendCheck(void)
void sendCheck()
{
UDWORD i;
NETgetBytesSent(); // update stats.
NETgetBytesRecvd();
NETgetPacketsSent();
NETgetPacketsRecvd();
// dont send checks till all players are present.
for(i=0;i<MAX_PLAYERS;i++)
for (unsigned i = 0; i < MAX_PLAYERS; ++i)
{
if(isHumanPlayer(i) && ingame.JoiningInProgress[i])
{
return true;
return;
}
}
@ -158,8 +156,6 @@ BOOL sendCheck(void)
{
sync_counter.unsentPing++;
}
return true;
}
// ////////////////////////////////////////////////////////////////////////////
@ -789,25 +785,11 @@ BOOL sendScoreCheck(void)
for (i = 0; i < game.maxPlayers; 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);
setMultiStats(i, getMultiStats(i), false);
}
}
}

View File

@ -1126,7 +1126,7 @@ static void proj_ImpactFunc( PROJECTILE *psObj )
unsigned int damage = calcDamage(weaponDamage(psStats, psObj->player), psStats->weaponEffect, psObj->psDest);
// If we are in a multi-player game and the attacker is our responsibility
if (bMultiPlayer && psObj->psSource && myResponsibility(psObj->psSource->player))
if (bMultiPlayer && psObj->psSource)
{
updateMultiStatsDamage(psObj->psSource->player, psObj->psDest->player, damage);
}
@ -1206,7 +1206,7 @@ static void proj_ImpactFunc( PROJECTILE *psObj )
if (bMultiPlayer)
{
if (psObj->psSource && myResponsibility(psObj->psSource->player))
if (psObj->psSource)
{
updateMultiStatsDamage(psObj->psSource->player, psCurrD->player, damage);
}
@ -1249,7 +1249,7 @@ static void proj_ImpactFunc( PROJECTILE *psObj )
if (bMultiPlayer)
{
if (psObj->psSource && myResponsibility(psObj->psSource->player))
if (psObj->psSource)
{
updateMultiStatsDamage(psObj->psSource->player, psCurrS->player,damage);
}