]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Calculate average handicap over a match and send to XonStat 1502/head
authorotta8634 <k9wolf@pm.me>
Sun, 15 Dec 2024 16:47:58 +0000 (00:47 +0800)
committerotta8634 <k9wolf@pm.me>
Sat, 17 May 2025 06:27:42 +0000 (14:27 +0800)
Added .handicap_avg_given_sum and .handicap_avg_taken_sum.
Currently it doesn't include self-damage which *is* influenced by handicap.
- Including this would require minimum 2 but probably 4 more entity fields, so I'm not sure it's really necessary.
The given and taken handicaps are sent to XonStat separately.

qcsrc/common/playerstats.qc
qcsrc/common/playerstats.qh
qcsrc/server/client.qc
qcsrc/server/handicap.qh

index 83b7a87da4e8749e1fe06ed4d105b984e0919e1b..c90d4577cfc138e64528fd6f87a1739d813f16e5 100644 (file)
@@ -56,6 +56,8 @@ void PlayerStats_GameReport_Reset_All()
                strfree(it.playerstats_id);
                PlayerStats_GameReport_AddEvent(sprintf("kills-%d", it.playerid));
                PlayerStats_GameReport_AddPlayer(it);
+               it.handicap_avg_given_sum = 0;
+               it.handicap_avg_taken_sum = 0;
        });
        FOREACH(Scores, true, {
                string label = scores_label(it);
@@ -255,6 +257,12 @@ void PlayerStats_GameReport(bool finished)
                        }
                }
 
+               // handicap
+               const float given = GameRules_scoring_add(it, DMG, 0);
+               const float taken = GameRules_scoring_add(it, DMGTAKEN, 0);
+               PlayerStats_GameReport_Event_Player(it, PLAYERSTATS_HANDICAP_GIVEN, given <= 0 ? 1 : it.handicap_avg_given_sum / given);
+               PlayerStats_GameReport_Event_Player(it, PLAYERSTATS_HANDICAP_TAKEN, taken <= 0 ? 1 : it.handicap_avg_taken_sum / taken);
+
                // collect final player information
                PlayerStats_GameReport_FinalizePlayer(it);
        });
@@ -303,6 +311,8 @@ void PlayerStats_GameReport_Init() // initiated before InitGameplayMode so that
                PlayerStats_GameReport_AddEvent(PLAYERSTATS_SCOREBOARD_VALID);
                PlayerStats_GameReport_AddEvent(PLAYERSTATS_SCOREBOARD_POS);
                PlayerStats_GameReport_AddEvent(PLAYERSTATS_RANK);
+               PlayerStats_GameReport_AddEvent(PLAYERSTATS_HANDICAP_GIVEN);
+               PlayerStats_GameReport_AddEvent(PLAYERSTATS_HANDICAP_TAKEN);
 
                // accuracy stats
                FOREACH(Weapons, it != WEP_Null, {
@@ -390,6 +400,8 @@ void PlayerStats_GameReport_Handler(entity fh, entity pass, float status)
                 *   achievement-<achievementname>: achievement counters (their "count" is usually 1 if nonzero at all)
                 *   kills-<index>: number of kills against the indexed player
                 *   rank <number>: rank of player
+                *   handicapgiven: average handicap on given (dealt) damage throughout the match
+                *   handicaptaken: average handicap on taken (received) damage throughout the match
                 *   acc-<weapon netname>-hit: total damage dealt
                 *   acc-<weapon netname>-fired: total damage that all fired projectiles *could* have dealt
                 *   acc-<weapon netname>-cnt-hit: amount of shots that actually hit
index 9fff940f243ad4025e26ed424810263700c4fdb8..a2d20894f0f1dda1d63ceae4fe7ebbbc37f7b15f 100644 (file)
@@ -37,6 +37,8 @@ const string PLAYERSTATS_JOINS = "joins";
 const string PLAYERSTATS_SCOREBOARD_VALID = "scoreboardvalid";
 const string PLAYERSTATS_RANK = "rank";
 const string PLAYERSTATS_SCOREBOARD_POS = "scoreboardpos";
+const string PLAYERSTATS_HANDICAP_GIVEN = "handicapgiven";
+const string PLAYERSTATS_HANDICAP_TAKEN = "handicaptaken";
 
 const string PLAYERSTATS_TOTAL = "total-";
 const string PLAYERSTATS_SCOREBOARD = "scoreboard-";
index cb38762e6f0f6201195d6a65ea42a9682ceb0eaf..fe4b3e0810015f12a92f805e1ea6506f057d58ec 100644 (file)
@@ -2816,11 +2816,13 @@ void PlayerFrame (entity this)
 
        if (this.score_frame_dmg)
        {
+               this.handicap_avg_given_sum += this.score_frame_dmg * Handicap_GetTotalHandicap(this, false);
                GameRules_scoring_add(this, DMG, this.score_frame_dmg);
                this.score_frame_dmg = 0;
        }
        if (this.score_frame_dmgtaken)
        {
+               this.handicap_avg_taken_sum += this.score_frame_dmgtaken * Handicap_GetTotalHandicap(this, true);
                GameRules_scoring_add(this, DMGTAKEN, this.score_frame_dmgtaken);
                this.score_frame_dmgtaken = 0;
        }
index 39a00e1a5c4f15c0d5334d35f98e2a072fde094a..99c25705a527662e71154fe5e7268f7700f8a33a 100644 (file)
@@ -50,11 +50,17 @@ float Handicap_GetTotalHandicap(entity player, bool receiving);
 /// \param[in] player Player to check.
 void Handicap_UpdateHandicapLevel(entity player);
 
-#define HANDICAP_MAX_LEVEL_EQUIVALENT  2.0
-
-.int handicap_level;
 // This int ranges 0 to 16, 0 meaning no handicap, 1 to 16 representing handicap "levels" mapped
 // from 1.0 to HANDICAP_MAX_LEVEL_EQUIVALENT, using (given + taken)/2 (i.e. both-ways handicap).
 // It is networked to the client.
 // The levels are mostly meaningless, just used to determine the player_handicap icon color.
+.int handicap_level;
+
+#define HANDICAP_MAX_LEVEL_EQUIVALENT  2.0
+
+// These store the player's total "average-sum" given/taken damage handicaps respectively.
+// average-sum refers to the arithmetic sum of damage taken/given, weighted by respective handicap.
+// To calculate the average handicap, divide by damage taken/given.
+.float handicap_avg_given_sum;
+.float handicap_avg_taken_sum;