Add tie handling for Racer and TechRacer
authorWuzzy <Wuzzy2@mail.ru>
Wed, 05 Sep 2018 15:37:50 +0200
changeset 13839 2fceeea62b10
parent 13765 3d2a7c563d8e
child 13840 219c2e588874
Add tie handling for Racer and TechRacer
ChangeLog.txt
share/hedgewars/Data/Scripts/Multiplayer/Racer.lua
share/hedgewars/Data/Scripts/Multiplayer/TechRacer.lua
--- a/ChangeLog.txt	Wed Sep 05 01:53:21 2018 +0200
+++ b/ChangeLog.txt	Wed Sep 05 15:37:50 2018 +0200
@@ -50,8 +50,9 @@
 Highlander:
  * Fix all hogs receiving a free teleport after hog placement phase
 
-TechRacer:
- * Fix rare bug causing crates and other objects to not appear on start of turn
+Racer/TechRacer:
+ * Fix rare bug in TechRacer causing crates and other objects to not appear on start of turn
+ * Fix ranking of teams if teams are tied
 
 Balanced Random Weapon:
  + Can adjust weapon start and crate probabilities
--- a/share/hedgewars/Data/Scripts/Multiplayer/Racer.lua	Wed Sep 05 01:53:21 2018 +0200
+++ b/share/hedgewars/Data/Scripts/Multiplayer/Racer.lua	Wed Sep 05 15:37:50 2018 +0200
@@ -95,7 +95,6 @@
 -- Got Variables?
 ------------------
 
-local fMod = 1000000 -- 1
 local roundLimit = 3
 local roundNumber = 0
 local firstClan = 10
@@ -143,7 +142,7 @@
 local cameraGear = nil -- gear created to center the cameera on
 
 local bestClan = 10
-local bestTime = 1000000
+local bestTime = MAX_TURN_TIME
 
 local gameBegun = false
 local gameOver = false
@@ -286,7 +285,7 @@
                 teamNameArr[i] = " "
                 teamSize[i] = 0
                 teamIndex[i] = 0
-                teamScore[i] = 1000000
+                teamScore[i] = MAX_TURN_TIME
         end
         numTeams = 0
 
@@ -439,7 +438,7 @@
                 end
         end
 
-        if bestTime ~= 1000000 then
+        if bestTime ~= MAX_TURN_TIME then
                 bestTimeComment = string.format(loc("%.1fs"), (bestTime/1000))
         end
 
@@ -465,7 +464,7 @@
         end
 
         for i = 0, (TeamsCount-1) do
-                if teamNameArr[i] ~= " " and teamScore[i] ~= 1000000 then
+                if teamNameArr[i] ~= " " and teamScore[i] ~= MAX_TURN_TIME then
                         SetTeamLabel(teamNameArr[i], string.format(loc("%.1fs"), teamScore[i]/1000))
                 end
         end
@@ -496,7 +495,7 @@
 
         totalComment = ""
         for i = 0, (TeamsCount-1) do
-                        if teamNameArr[i] ~= " " and teamScore[i] ~= 1000000 then
+                        if teamNameArr[i] ~= " " and teamScore[i] ~= MAX_TURN_TIME then
                                 teamComment[i] = string.format(loc("%s: %.1fs"), teamNameArr[i], (teamScore[i]/1000)) .. "|"
                         else
                                 teamComment[i] = string.format(loc("%s: Did not finish"), teamNameArr[i]) .. "|"
@@ -515,33 +514,68 @@
                 local unfinishedArray = {}
                 local sortedTeams = {}
                 local k = 1
+                local c = 1
+                local clanScores = {}
+                local previousClan
                 for i = 0, TeamsCount-1 do
-                        if teamScore[i] ~= 1000000 and teamNameArr[i] ~= " " then
+                        local clan = GetTeamClan(teamNameArr[i])
+                        if not clanScores[clan+1] then
+	                       clanScores[clan+1] = {}
+	                       clanScores[clan+1].index = clan
+	                       clanScores[clan+1].score = teamScore[i]
+                        end
+                        if teamScore[i] ~= MAX_TURN_TIME and teamNameArr[i] ~= " " then
                                sortedTeams[k] = {}
                                sortedTeams[k].name = teamNameArr[i]
                                sortedTeams[k].score = teamScore[i]
+	                       sortedTeams[k].clan = clan
                                k = k + 1
                         else
                                table.insert(unfinishedArray, string.format(loc("%s did not finish the race."), teamNameArr[i]))
                         end
                 end
-                table.sort(sortedTeams, function(team1, team2) return team1.score < team2.score end)
+                table.sort(sortedTeams, function(team1, team2)
+                        if team1.score == team2.score then
+                                return team1.clan < team2.clan
+                        else
+                                return team1.score < team2.score
+                        end
+                end)
+                table.sort(clanScores, function(clan1, clan2) return clan1.score < clan2.score end)
+                local rank = 0
+                local rankPlus = 0
+                local prevScore
+                local clanRanks = {}
+                for c = 1, #clanScores do
+                        rankPlus = rankPlus + 1
+                        if clanScores[c].score ~= prevScore then
+                                rank = rank + rankPlus
+                                rankPlus = 0
+                        end
+                        prevScore = clanScores[c].score
+                        clanRanks[clanScores[c].index] = rank
+                end
 
                 -- Write all the stats!
-
                 for i = 1, #sortedTeams do
                         SendStat(siPointType, loc("milliseconds"))
+			SendStat(siTeamRank, tostring(clanRanks[GetTeamClan(sortedTeams[i].name)]))
                         SendStat(siPlayerKills, sortedTeams[i].score, sortedTeams[i].name)
                 end
 
-                if #sortedTeams >= 1 then
-                        SendStat(siGameResult, string.format(loc("%s wins!"), sortedTeams[1].name))
+		local roundDraw = false
+		if #clanScores >= 2 and clanScores[1].score == clanScores[2].score and clanScores[1].score ~= MAX_TURN_TIME then
+			roundDraw = true
+                        SendStat(siGameResult, loc("Round draw"))
+                        SendStat(siCustomAchievement, loc("The teams are tied for the fastest time."))
+                elseif #sortedTeams >= 1 then
                         SendStat(siGameResult, string.format(loc("%s wins!"), sortedTeams[1].name))
                         SendStat(siCustomAchievement, string.format(loc("%s wins with a best time of %.1fs."), sortedTeams[1].name, (sortedTeams[1].score/1000)))
                         for i=1,#unfinishedArray do
                                  SendStat(siCustomAchievement, unfinishedArray[i])
                         end
                 else
+			roundDraw = true
                         SendStat(siGameResult, loc("Round draw"))
                         SendStat(siCustomAchievement, loc("Nobody managed to finish the race. What a shame!"))
                         if specialPointsCount > 0 then
@@ -553,7 +587,7 @@
 
 		-- Kill all the losers
 		for i = 0, (numhhs-1) do
-			if GetHogClan(hhs[i]) ~= bestClan then
+			if GetHogClan(hhs[i]) ~= bestClan or roundDraw then
 				SetEffect(hhs[i], heResurrectable, 0)
 				SetHealth(hhs[i],0)
 			end
@@ -1061,7 +1095,7 @@
     map = detectMapWithDigest()
 
     for i = 0, (numTeams-1) do
-        if teamScore[i] < 1000000 then
+        if teamScore[i] < MAX_TURN_TIME then
             DeclareAchievement(raceType, teamNameArr[i], map, teamScore[i])
         end
     end
--- a/share/hedgewars/Data/Scripts/Multiplayer/TechRacer.lua	Wed Sep 05 01:53:21 2018 +0200
+++ b/share/hedgewars/Data/Scripts/Multiplayer/TechRacer.lua	Wed Sep 05 15:37:50 2018 +0200
@@ -105,7 +105,6 @@
 local jet = nil
 portalDistance = 5000
 ufoFuel = 0
-local fMod = 1000000
 local roundLimit = 3
 local roundNumber = 0
 local firstClan = 10
@@ -151,7 +150,7 @@
 local cameraGear = nil
 
 local bestClan = 10
-local bestTime = 1000000
+local bestTime = MAX_TURN_TIME
 
 local gameBegun = false
 local gameOver = false
@@ -186,7 +185,7 @@
 		teamNameArr[i] = " " -- = i
 		teamSize[i] = 0
 		teamIndex[i] = 0
-		teamScore[i] = 1000000
+		teamScore[i] = MAX_TURN_TIME
 	end
 	numTeams = 0
 
@@ -332,7 +331,7 @@
 		end
 	end
 
-	if bestTime ~= 1000000 then
+	if bestTime ~= MAX_TURN_TIME then
 		bestTimeComment = string.format(loc("%.1fs"), (bestTime/1000))
 	end
 
@@ -358,7 +357,7 @@
 	end
 
 	for i = 0, (TeamsCount-1) do
-		if teamNameArr[i] ~= " " and teamScore[i] ~= 1000000 then
+		if teamNameArr[i] ~= " " and teamScore[i] ~= MAX_TURN_TIME then
 			SetTeamLabel(teamNameArr[i], string.format(loc("%.1fs"), teamScore[i]/1000))
 		end
 	end
@@ -389,7 +388,7 @@
 	local totalComment = ""
 	for i = 0, (TeamsCount-1) do
 		if teamNameArr[i] ~= " " then
-			if teamScore[i] ~= 1000000 then
+			if teamScore[i] ~= MAX_TURN_TIME then
 				teamComment[i] = string.format(loc("%s: %.1fs"), teamNameArr[i], (teamScore[i]/1000)) .. "|"
 			else
 				teamComment[i] = string.format(loc("%s: Did not finish"), teamNameArr[i]) .. "|"
@@ -413,32 +412,68 @@
 		local unfinishedArray = {}
 		local sortedTeams = {}
 		local k = 1
+		local c = 1
+		local clanScores = {}
+		local previousClan
 		for i = 0, TeamsCount-1 do
-			if teamScore[i] ~= 1000000 and teamNameArr[i] ~= " " then
-			       sortedTeams[k] = {}
-			       sortedTeams[k].name = teamNameArr[i]
-			       sortedTeams[k].score = teamScore[i]
-			       k = k + 1
+			local clan = GetTeamClan(teamNameArr[i])
+			if not clanScores[clan+1] then
+				clanScores[clan+1] = {}
+				clanScores[clan+1].index = clan
+				clanScores[clan+1].score = teamScore[i]
+			end
+			if teamScore[i] ~= MAX_TURN_TIME and teamNameArr[i] ~= " " then
+				sortedTeams[k] = {}
+				sortedTeams[k].name = teamNameArr[i]
+				sortedTeams[k].score = teamScore[i]
+				sortedTeams[k].clan = clan
+				k = k + 1
 			else
-			       table.insert(unfinishedArray, string.format(loc("%s did not finish the race."), teamNameArr[i]))
+				table.insert(unfinishedArray, string.format(loc("%s did not finish the race."), teamNameArr[i]))
 			end
 		end
-		table.sort(sortedTeams, function(team1, team2) return team1.score < team2.score end)
+		table.sort(sortedTeams, function(team1, team2)
+			if team1.score == team2.score then
+				return team1.clan < team2.clan
+			else
+				return team1.score < team2.score
+			end
+		end)
+		table.sort(clanScores, function(clan1, clan2) return clan1.score < clan2.score end)
+		local rank = 0
+		local rankPlus = 0
+		local prevScore
+		local clanRanks = {}
+		for c = 1, #clanScores do
+			rankPlus = rankPlus + 1
+			if clanScores[c].score ~= prevScore then
+				rank = rank + rankPlus
+				rankPlus = 0
+			end
+			prevScore = clanScores[c].score
+			clanRanks[clanScores[c].index] = rank
+		end
 
 		-- Write all the stats!
-
 		for i = 1, #sortedTeams do
 			SendStat(siPointType, loc("milliseconds"))
+			SendStat(siTeamRank, tostring(clanRanks[GetTeamClan(sortedTeams[i].name)]))
 			SendStat(siPlayerKills, sortedTeams[i].score, sortedTeams[i].name)
 		end
 
-		if #sortedTeams >= 1 then
+		local roundDraw = false
+		if #clanScores >= 2 and clanScores[1].score == clanScores[2].score and clanScores[1].score ~= MAX_TURN_TIME then
+			roundDraw = true
+			SendStat(siGameResult, loc("Round draw"))
+			SendStat(siCustomAchievement, loc("The teams are tied for the fastest time."))
+		elseif #sortedTeams >= 1 then
 			SendStat(siGameResult, string.format(loc("%s wins!"), sortedTeams[1].name))
 			SendStat(siCustomAchievement, string.format(loc("%s wins with a best time of %.1fs."), sortedTeams[1].name, (sortedTeams[1].score/1000)))
 			for i=1,#unfinishedArray do
 				 SendStat(siCustomAchievement, unfinishedArray[i])
 			end
 		else
+			roundDraw = true
 			SendStat(siGameResult, loc("Round draw"))
 			SendStat(siCustomAchievement, loc("Nobody managed to finish the race. What a shame!"))
 			SendStat(siCustomAchievement, loc("Maybe you should try an easier TechRacer map."))
@@ -1218,7 +1253,7 @@
 	map = detectMapWithDigest()
 
 	for i = 0, (numTeams-1) do
-		if teamScore[i] < 1000000 then
+		if teamScore[i] < MAX_TURN_TIME then
 			DeclareAchievement(raceType, teamNameArr[i], map, teamScore[i])
 		end
 	end