Rework rankings of losing clans: Rank them in the reverse order they died
authorWuzzy <Wuzzy2@mail.ru>
Tue, 04 Sep 2018 14:20:15 +0200
changeset 13756 a0d6404a80a2
parent 13755 6908d1e65cdc
child 13757 f0cb47f0bfaf
Rework rankings of losing clans: Rank them in the reverse order they died New ranking rule: - The clan that survived is ranked 1st. - The clan that died last is ranked 2nd. - The clan that died second last is ranked 3rd. - The clan that died third last is ranked 4th. - And so on ... Old ranking rule: - The clan that survived is ranked 1st. - The losing teams are ranked in the order they started with, which isn't fair. Draws are not handled properly in rankings yet.
hedgewars/uStats.pas
hedgewars/uTeams.pas
hedgewars/uTypes.pas
--- a/hedgewars/uStats.pas	Mon Sep 03 22:14:46 2018 +0200
+++ b/hedgewars/uStats.pas	Tue Sep 04 14:20:15 2018 +0200
@@ -29,6 +29,7 @@
     SendRankingStatsOn : boolean = true;
     SendAchievementsStatsOn : boolean = true;
     SendHealthStatsOn : boolean = true;
+    ClanDeathLog : PClanDeathLogEntry;
 
 procedure initModule;
 procedure freeModule;
@@ -138,6 +139,8 @@
 
 procedure TurnStats;
 var i, t: LongInt;
+    c: Longword;
+    newEntry: PClanDeathLogEntry;
 begin
 inc(FinishedTurnsTotal);
 
@@ -161,12 +164,38 @@
                 StepDied:= false;
                 end;
 
-if SendHealthStatsOn then
-    for t:= 0 to Pred(ClansCount) do
-        with ClansArray[t]^ do
+// Remember which clans died in this turn
+c:= 0;
+newEntry:= nil;
+for t:= 0 to Pred(ClansCount) do
+    with ClansArray[t]^ do
+        begin
+        if (ClanHealth = 0) and (ClansArray[t]^.DiedThisTurn = false) then
             begin
+            ClansArray[t]^.DiedThisTurn:= true;
+            if c = 0 then
+                begin
+                new(newEntry);
+                newEntry^.Turn := FinishedTurnsTotal;
+                newEntry^.NextEntry := nil;
+                end;
+
+            newEntry^.KilledClans[c]:= ClansArray[t];
+            inc(c);
+            newEntry^.KilledClansCount := c;
+            end;
+
+        if SendHealthStatsOn then
             SendStat(siClanHealth, IntToStr(Color) + ' ' + IntToStr(ClanHealth));
-            end;
+        end;
+if newEntry <> nil then
+    begin
+    if ClanDeathLog <> nil then
+        begin
+        newEntry^.NextEntry:= ClanDeathLog;
+        end;
+    ClanDeathLog:= newEntry;
+    end;
 
 Kills:= 0;
 KillsClan:= 0;
@@ -272,7 +301,7 @@
 end;
 
 procedure SendStats;
-var i, t: LongInt;
+var i, t, c: LongInt;
     msd, msk: Longword; msdhh, mskhh: PHedgehog;
     mskcnt: Longword;
     maxTeamKills : Longword;
@@ -282,6 +311,7 @@
     maxTeamDamage : Longword;
     maxTeamDamageName : shortstring;
     winnersClan : PClan;
+    deathEntry : PClanDeathLogEntry;
 begin
 if SendHealthStatsOn then
     msd:= 0; msdhh:= nil;
@@ -315,7 +345,8 @@
                         end;
             end;
 
-            { send player stats for winner teams }
+            { Send player stats for winner clans/teams.
+            The clan that survived is ranked 1st. }
             if Clan^.ClanHealth > 0 then
                 begin
                 winnersClan:= Clan;
@@ -343,19 +374,28 @@
 
         end;
 
-    { now send player stats for loser teams }
+    { Now send player stats for loser teams/clans.
+    The losing clans are ranked in the reverse order they died.
+    The clan that died last is ranked 2nd,
+    the clan that died second to last is ranked 3rd,
+    and so on. }
+    deathEntry := ClanDeathLog;
     if SendRankingStatsOn then
-        for t:= 0 to Pred(TeamsCount) do
+        while (deathEntry <> nil) do
             begin
-            with TeamsArray[t]^ do
-                begin
-                if Clan^.ClanHealth = 0 then
+            for c:= 0 to Pred(deathEntry^.KilledClansCount) do
+                if ((deathEntry^.KilledClans[c]^.ClanHealth) = 0) and (not deathEntry^.KilledClans[c]^.StatsHandled) then
                     begin
-                    SendStat(siPlayerKills, IntToStr(Clan^.Color) + ' ' +
-                        IntToStr(stats.Kills) + ' ' + TeamName);
-                end;
+                    for t:= 0 to Pred(TeamsCount) do
+                        if TeamsArray[t]^.Clan^.ClanIndex = deathEntry^.KilledClans[c]^.ClanIndex then
+                            begin
+                            SendStat(siPlayerKills, IntToStr(deathEntry^.killedClans[c]^.Color) + ' ' +
+                                IntToStr(TeamsArray[t]^.stats.Kills) + ' ' + TeamsArray[t]^.TeamName);
+                            end;
+                    deathEntry^.KilledClans[c]^.StatsHandled:= true;
+                    end;
+            deathEntry:= deathEntry^.NextEntry;
             end;
-        end;
 
     // “Achievements” / Details part of stats screen
     if SendAchievementsStatsOn then
@@ -432,6 +472,7 @@
     TotalRoundsPre:= -1;
     TotalRoundsReal:= -1;
     FinishedTurnsTotal:= -1;
+    ClanDeathLog:= nil;
 end;
 
 procedure freeModule;
--- a/hedgewars/uTeams.pas	Mon Sep 03 22:14:46 2018 +0200
+++ b/hedgewars/uTeams.pas	Tue Sep 04 14:20:15 2018 +0200
@@ -308,7 +308,10 @@
         begin
         for i:= 0 to ClansCount do
             if ClansArray[i] <> nil then
+                begin
                 ClansArray[i]^.TurnNumber:= 0;
+                ClansArray[i]^.DiedThisTurn:= false;
+                end;
         ResetWeapons
         end;
 
@@ -471,7 +474,9 @@
         ClanIndex:= Pred(ClansCount);
         Color:= TeamColor;
         TagTeamIndex:= 0;
-        Flawless:= true
+        Flawless:= true;
+        DiedThisTurn:= false;
+        StatsHandled:= false;
         end
     end
 else
--- a/hedgewars/uTypes.pas	Mon Sep 03 22:14:46 2018 +0200
+++ b/hedgewars/uTypes.pas	Tue Sep 04 14:20:15 2018 +0200
@@ -350,6 +350,16 @@
         TeamDamage : Longword;
         end;
 
+    PClanDeathLogEntry = ^TClanDeathLogEntry;
+
+    TClanDeathLogEntry = record
+        Turn : Longword; // turn in which the clans were killed
+        KilledClans : array[0..Pred(cMaxTeams)] of PClan; // array of clans that have died
+        KilledClansCount: Longword; // number of clans that died
+        NextEntry : PClanDeathLogEntry; // linked list
+        end;
+
+
     TBinds = record
                  indices: array[0..cKbdMaxIndex] of byte;
                  // zeroth element is reserved, indices[i] == 0 means no binding
@@ -443,6 +453,8 @@
             ClanHealth: LongInt;
             ClanIndex: LongInt;
             TurnNumber: LongWord;
+            DiedThisTurn: boolean; // true if clan died in current turn
+            StatsHandled : boolean; // true if clan has been handled for stats screen
             Flawless: boolean;
             end;