1local hvictory = "ui/human/victory.png"
2local hdefeat =  "ui/human/defeat.png"
3local ovictory = "ui/orc/victory.png"
4local odefeat =  "ui/orc/defeat.png"
5
6local humanRanks = {
7  0, _("Servant"),
8  2000, _("Peasant"),
9  5000, _("Squire"),
10  8000, _("Footman"),
11  18000, _("Corporal"),
12  28000, _("Sergeant"),
13  40000, _("Lieutenant"),
14  55000, _("Captain"),
15  70000, _("Major"),
16  85000, _("Knight"),
17  105000, _("General"),
18  125000, _("Admiral"),
19  145000, _("Marshall"),
20  165000, _("Lord"),
21  185000, _("Grand Admiral"),
22  205000, _("Highlord"),
23  230000, _("Thundergod"),
24  255000, _("God"),
25  280000, _("Designer"),
26}
27
28local orcRanks = {
29  0, _("Slave"),
30  2000, _("Peon"),
31  5000, _("Rogue"),
32  8000, _("Grunt"),
33  18000, _("Slasher"),
34  28000, _("Marauder"),
35  40000, _("Commander"),
36  55000, _("Captain"),
37  70000, _("Major"),
38  85000, _("Knight"),
39  105000, _("General"),
40  125000, _("Master"),
41  145000, _("Marshall"),
42  165000, _("Chieftain"),
43  185000, _("Overlord"),
44  205000, _("War Chief"),
45  230000, _("Demigod"),
46  255000, _("God"),
47  280000, _("Designer"),
48}
49
50function RunResultsMenu()
51  local background
52  local result
53  local human = (GetPlayerData(GetThisPlayer(), "RaceName") == "human")
54  local ranksTable
55  if (human) then
56	ranksTable = humanRanks
57	--Load("scripts/human/ui.lua")
58  else
59	ranksTable = orcRanks
60	--Load("scripts/orc/ui.lua")
61  end
62  -- background and music
63  if (GameResult == GameVictory) then
64	SetPlayerData(GetThisPlayer(), "Score", GetPlayerData(GetThisPlayer(), "Score") + 500)
65    result = _("Victory!")
66    if (human) then
67      background = hvictory
68      PlayMusic("music/Human Victory" .. wargus.music_extension)
69    else
70      background = ovictory
71      PlayMusic("music/Orc Victory" .. wargus.music_extension)
72    end
73  elseif (GameResult == GameDefeat) then
74    result = _("Defeat!")
75    if (human) then
76      background = hdefeat
77      PlayMusic("music/Human Defeat" .. wargus.music_extension)
78    else
79      background = odefeat
80      PlayMusic("music/Orc Defeat" .. wargus.music_extension)
81    end
82  elseif (GameResult == GameDraw) then
83    result = _("Draw!")
84    if (human) then
85      background = hdefeat
86    else
87      background = odefeat
88    end
89  else
90    return -- quit to menu
91  end
92
93  local top_offset = 20
94  local bottom_offset = 84
95  local description_offset = 30
96
97   -- menu setup
98  local menu = WarMenu(nil, background)
99  local offx = (Video.Width - 640) / 2
100  local offy = (Video.Height - 480) / 2
101
102  -- score and rank
103
104  local results_score = GetPlayerData(GetThisPlayer(), "Score")
105  local currentRank = ranksTable[2]
106  local currentRankNumber = 1
107  if (currentCampaign ~= nil and currentState ~= nil) then
108	local subtable = nil
109	for i = 1, table.getn(wc2.preferences.CampaignBestScores) / 2 do
110		if wc2.preferences.CampaignBestScores[i*2 - 1] == currentCampaign then
111			subtable = wc2.preferences.CampaignBestScores[i*2]
112		end
113	end
114	if (subtable ~= nil) then
115		for i=1,currentState - 1 do
116			if (subtable[i] ~= nil) then
117				results_score = results_score + subtable[i]
118			end
119		end
120	end
121  end
122  if (ischeater == false) then
123	  for i = 1, table.getn(ranksTable) / 2 do
124		if results_score > ranksTable[i*2 - 1] then
125			currentRank = ranksTable[i*2]
126			currentRankNumber = i
127		else
128			break
129		end
130	  end
131  else
132	currentRank = _("Cheater!")
133	currentRankNumber = 1
134  end
135  local currentLevelRanking = StatBoxWidget(100, 10)
136  currentLevelRanking:setCaption("")
137
138  if (currentRank == _("Designer")) then
139	currentLevelRanking:setPercent(100)
140  elseif currentRank == _("Cheater!") then
141	currentLevelRanking:setPercent(0)
142  else
143	currentLevelRanking:setPercent((results_score - ranksTable[currentRankNumber*2-1])*100/(ranksTable[currentRankNumber*2 + 1] - ranksTable[currentRankNumber*2-1]))
144  end
145
146  currentLevelRanking:setBackgroundColor(black)
147  currentLevelRanking:setForegroundColor(Color(0, 0, 215))
148  currentLevelRanking:setVisible(false)
149  currentLevelRanking:setBaseColor(Color(215, 215, 215))
150  menu:add(currentLevelRanking, offx + 280, offy + top_offset + 39)
151
152  local currentOverallRanking = StatBoxWidget(100, 10)
153  currentOverallRanking:setCaption("")
154  currentOverallRanking:setPercent(currentRankNumber*100/ (table.getn(ranksTable) / 2))
155  currentOverallRanking:setBackgroundColor(black)
156  currentOverallRanking:setForegroundColor(Color(215, 0, 0))
157  currentOverallRanking:setVisible(false)
158  currentOverallRanking:setBaseColor(Color(215, 215, 215))
159  menu:add(currentOverallRanking, offx + 280, offy + top_offset + 50)
160  -- player label and color setup
161  local playerCount = 0      -- overall number of players
162  local playerLabels = {}    -- all player name labels
163  local playerColorIndex = {
164	{166, 0, 0},     -- red
165	{0, 36, 150},    -- blue
166	{20, 134, 93},   -- green
167	{130, 16, 77},   -- violet
168	{189, 89, 16},   -- orange
169	{93, 93, 93},    -- black
170	{182, 182, 182}, -- white
171	{195, 195, 0}    -- yellow
172  }
173  local playerColors = {}
174  local playerNumbers = {}
175
176  if (not IsNetworkGame()) then
177      SetDefaultPlayerNames()
178    end
179  for i = 0,7 do
180    if (GetPlayerData(i, "TotalUnits") > 0 and Players[i].Type ~= PlayerRescuePassive and Players[i].Type ~= PlayerRescueActive) then
181		playerCount = playerCount + 1
182		local name = GetPlayerData(i, "Name")
183		if (ThisPlayer.Index == i) then
184			name = name .. _(" - You")
185		  elseif (ThisPlayer:IsAllied(Players[i])) then
186			name = name .. _(" - Ally")
187		  elseif (ThisPlayer:IsEnemy(Players[i])) then
188			name = name .. _(" - Enemy")
189		  else
190			name = name .. _(" - Neutral")
191		  end
192		playerLabels[playerCount] = menu:addLabel(name, offx + 320, offy + 82 + playerCount*42, Fonts["game"], true)
193		playerLabels[playerCount]:setVisible(false)
194		playerColors[playerCount] = Color(playerColorIndex[i+1][1], playerColorIndex[i+1][2], playerColorIndex[i+1][3])
195		playerNumbers[playerCount] = i
196    end
197  end
198
199  local length = 0
200  local captionLabels = {}
201  local captionOffsets = {}
202  -- Label setup part
203  captionLabels[1] = menu:addLabel(_("Units:"), offx + 42, offy + bottom_offset, Fonts["game"], true)
204  captionOffsets[1] = 0
205  length = length + captionLabels[1]:getWidth() + 20
206
207  captionLabels[2] = menu:addLabel(_("Buildings:"), offx + 120, offy + bottom_offset, Fonts["game"], true)
208  captionOffsets[2] = length
209  length = length + captionLabels[2]:getWidth() + 20
210  captionLabels[3] = menu:addLabel(_("Gold:"), offx + 202, offy + bottom_offset, Fonts["game"], true)
211  captionOffsets[3] = length
212  length = length + captionLabels[3]:getWidth() + 20
213  captionLabels[4] = menu:addLabel(_("Lumber:"), offx + 281, offy + bottom_offset, Fonts["game"], true)
214  captionOffsets[4] = length
215  length = length + captionLabels[4]:getWidth() + 20
216  captionLabels[5] = menu:addLabel(_("Oil:"), offx + 361, offy + bottom_offset, Fonts["game"], true)
217  captionOffsets[5] = length
218  length = length + captionLabels[5]:getWidth() + 20
219  captionLabels[6] = menu:addLabel(_("Kills:"), offx + 442, offy + bottom_offset, Fonts["game"], true)
220  captionOffsets[6] = length
221  length = length + captionLabels[6]:getWidth() + 20
222  captionLabels[7] = menu:addLabel(_("Razings:"), offx + 520, offy + bottom_offset, Fonts["game"], true)
223  captionOffsets[7] = length
224  length = length + captionLabels[7]:getWidth() + 20
225  captionLabels[8] = menu:addLabel(_("Score:"), offx + 600, offy + bottom_offset, Fonts["game"], true)
226  captionOffsets[8] = length
227
228  for i=1,table.getn(captionLabels) do
229	captionLabels[i]:setVisible(false)
230  end
231
232  local counterWidgets = {}
233  -- StatBoxWidget setup part
234  for i=1,table.getn(captionLabels) do
235	counterWidgets[i] = {}
236	for j=1,playerCount do
237		counterWidgets[i][j] = StatBoxWidget(70, 20)
238		counterWidgets[i][j]:setCaption("")
239		counterWidgets[i][j]:setPercent(0)
240		counterWidgets[i][j]:setBackgroundColor(black)
241		counterWidgets[i][j]:setForegroundColor(playerColors[j])
242		counterWidgets[i][j]:setVisible(false)
243		counterWidgets[i][j]:setFont(Fonts["game"])
244		counterWidgets[i][j]:setBaseColor(Color(215, 215, 0))
245		menu:add(counterWidgets[i][j], offx + 8 + 80* (i - 1), offy + 60 + 42*j)
246	end
247  end
248
249  local r_stage = 0
250  local r_stats_stage = 0
251  local counter = 0
252  local wait = 24
253  local statStageWait = 0
254  local scoreWait = 24
255
256  local function ResultsShowPlayerStage(stage)
257	captionLabels[stage]:setVisible(true)
258	for j=1,playerCount do
259		counterWidgets[stage][j]:setVisible(true)
260	end
261  end
262
263  -- player tickers
264  local p_counters = {}
265  for i=1,table.getn(captionLabels) do
266	p_counters[i] = {}
267	  for j = 1,playerCount do
268		p_counters[i][j] = 0
269	  end
270  end
271  local playerStatData = {}                                   -- All player data
272  local maxStagePlayer = {1, 1, 1, 1, 1, 1, 1, 1}             -- hold the player earned maximum score of every stat
273  local defaultStatSpeeds = {2, 2, 457, 457, 457, 2, 2, 123}  -- default statbox speeds
274  local statSpeed = {}       -- speed of stat increasing
275  local decrCoeff = 70       -- maximum count of ticks for statbox
276  for i=1,table.getn(captionLabels) do
277	playerStatData[i] = {}
278	for j=1,playerCount do
279		if (i == 1) then
280			playerStatData[i][j] = GetPlayerData(playerNumbers[j], "TotalUnits")
281		elseif (i == 2) then
282			playerStatData[i][j] = GetPlayerData(playerNumbers[j], "TotalBuildings")
283		elseif (i == 3) then
284			playerStatData[i][j] = GetPlayerData(playerNumbers[j], "TotalResources", "gold")
285		elseif (i == 4) then
286			playerStatData[i][j] = GetPlayerData(playerNumbers[j], "TotalResources", "wood")
287		elseif (i == 5) then
288			playerStatData[i][j] = GetPlayerData(playerNumbers[j], "TotalResources", "oil")
289		elseif (i == 6) then
290			playerStatData[i][j] = GetPlayerData(playerNumbers[j], "TotalKills")
291		elseif (i == 7) then
292			playerStatData[i][j] = GetPlayerData(playerNumbers[j], "TotalRazings")
293		elseif (i == 8) then
294			playerStatData[i][j] = GetPlayerData(playerNumbers[j], "Score")
295		end
296	end
297	for j=1,playerCount do
298		if (playerStatData[i][j] > playerStatData[i][(maxStagePlayer[i])]) then
299			maxStagePlayer[i] = j
300		end
301	end
302	statSpeed[i] = math.max(defaultStatSpeeds[i], playerStatData[i][(maxStagePlayer[i])] / decrCoeff)
303  end
304
305  local regenWidget = StatBoxWidget(1, 1)
306  menu:add(regenWidget, -50, -50)
307  local ticking = false
308  local currect_player_score = 0
309  local currect_player_score_label = menu:addLabel(currect_player_score, offx + 530, offy + top_offset + 21, Fonts["small-title"], true)
310  currect_player_score_label:setVisible(false)
311  local function ResultsMainLoop()
312	regenWidget:setPercent(GameCycle)
313	if (statStageWait > 0) then -- waiting
314		statStageWait = statStageWait - 1
315	end
316	if (wait > 0) then -- waiting
317		wait = wait - 1
318		return
319	end
320	if (r_stage == 0) then -- Results
321		menu:addLabel(_("Outcome"), offx + 114, offy + top_offset)
322		menu:addLabel(result, offx + 114, offy + top_offset + 21, Fonts["large-title"])
323		StopAllChannels()
324		PlaySound("statsthump", true)
325		wait = 24
326		r_stage = r_stage + 1 -- next stage
327	elseif (r_stage == 1) then -- Rank
328		menu:addLabel(_("Rank"), offx + 330, offy + top_offset)
329		menu:addLabel(currentRank, offx + 330, offy + top_offset + 21)
330		StopAllChannels()
331		PlaySound("statsthump", true)
332		wait = 24
333		currentLevelRanking:setVisible(true)
334		currentOverallRanking:setVisible(true)
335		r_stage = r_stage + 1 -- next stage
336	elseif (r_stage == 2) then -- Your score
337		if (ticking == false) then
338			menu:addLabel(_("Score"), offx + 546, offy + top_offset)
339			StopAllChannels()
340			PlaySound("statsthump", true)
341			currect_player_score_label:setVisible(true)
342			ticking = true
343		else
344			if currect_player_score < results_score then
345				currect_player_score = currect_player_score + results_score / 10
346				currect_player_score_label:setCaption(tostring(math.floor(currect_player_score)))
347				currect_player_score_label:adjustSize()
348				scoreWait = scoreWait - 2
349				wait = 1
350				PlaySound("highclick", true)
351			else
352				currect_player_score_label:setCaption(tostring(math.floor(results_score)))
353				currect_player_score_label:adjustSize()
354				wait = math.max(scoreWait, 2)
355				r_stage = r_stage + 1 -- next stage
356				ticking = false
357			end
358		end
359	elseif (r_stage == 3) then -- Stats
360		-- show player labels
361		for j=1,playerCount do
362			playerLabels[j]:setVisible(true)
363		end
364		ticking = false
365		if (statStageWait == 0 and r_stats_stage < table.getn(captionLabels)) then
366			-- advance to next stage
367			StopAllChannels()
368			PlaySound("statsthump", true)
369			r_stats_stage = r_stats_stage + 1
370			ResultsShowPlayerStage(r_stats_stage)
371			statStageWait = 24
372		end
373		for i=1, r_stats_stage do
374			for j=1,playerCount do
375				if playerStatData[i][j] > 0 then
376					if  p_counters[i][j] < playerStatData[i][j] then
377						ticking = true
378						p_counters[i][j] = p_counters[i][j] + statSpeed[i]
379						if (p_counters[i][j] > playerStatData[i][j]) then
380							p_counters[i][j] = playerStatData[i][j]
381						end
382						counterWidgets[i][j]:setPercent(math.min(100, p_counters[i][j]*100/playerStatData[i][(maxStagePlayer[i])]))
383						counterWidgets[i][j]:setCaption(math.floor(p_counters[i][j]))
384					end
385				else
386					counterWidgets[i][j]:setCaption("0")
387				end
388			end
389		end
390		if (ticking) then
391			PlaySound("highclick", true)
392		elseif r_stats_stage == table.getn(captionLabels) then
393			r_stage = r_stage + 1 -- exit
394		end
395		wait = 1
396	elseif (r_stage == 4) then -- just stop
397		wait = 24
398	end
399  end
400
401  local screenUpdate = LuaActionListener(ResultsMainLoop)
402
403  menu:addLogicCallback(screenUpdate)
404
405  menu:addFullButton(_("~!Save Replay"), "s", offx + 150, offy + 440,
406    function() RunSaveReplayMenu() end)
407
408  menu:addFullButton(_("~!Continue"), "c", offx + 400, offy + 440,
409    function()
410		StopMusic()
411		menu:stop()
412	end)
413
414  local speed = GetGameSpeed()
415  SetGameSpeed(30)
416
417  menu:run()
418
419  SetGameSpeed(speed)
420end