[WoF] Avoid code duplication and fix a non-translatable string (#8384)
Instead of copy-pasting the multiplayer turns over advantage function, just use that function directly. This required making some changes to the function to better support this specific use-case, but I think it's still better than copy-pasting it. I split the primary functionality out into two separate pieces – calculation and display. Thus, the main function is technically unchanged, while WoF can avoid the weird things it does and just calculate and display how it wants. This fixes #8368.
This commit is contained in:
parent
0e99d4b38b
commit
8d30761ca8
3 changed files with 84 additions and 125 deletions
|
@ -1,79 +0,0 @@
|
|||
-- from multiplayer/eras.lua, slightly modified for use in a campaign and to return a result
|
||||
|
||||
local function determine_advantage()
|
||||
local _ = wesnoth.textdomain "wesnoth-multiplayer"
|
||||
local function all_sides()
|
||||
local function f(s, i)
|
||||
i = i + 1
|
||||
local t = wesnoth.sides[i]
|
||||
return t and i, t
|
||||
end
|
||||
return f, nil, 0
|
||||
end
|
||||
|
||||
local income_factor = 5
|
||||
|
||||
local winning_sides = {}
|
||||
local total_score = -1
|
||||
local side_comparison = ""
|
||||
local winners_color = "#000000"
|
||||
for side, team in all_sides() do
|
||||
if not team.__cfg.hidden then
|
||||
local side_color = wesnoth.colors[team.color].pango_color
|
||||
if # wesnoth.units.find_on_map( { side = side } ) == 0 then
|
||||
-- po: In the end-of-match summary, a side which has no units left and therefore lost. In English the loss is shown by displaying it with the text struck through.
|
||||
local side_text = _ "<span strikethrough='true' foreground='$side_color'>Side $side_number</span>: Has lost all units"
|
||||
-- The double new-line here is to balance with the other sides getting a line for "Grand total"
|
||||
side_comparison = side_comparison .. side_text:vformat{side_color = side_color, side_number = side} .. "\n\n"
|
||||
else
|
||||
local income = team.total_income * income_factor
|
||||
local units = 0
|
||||
-- Calc the total unit-score here
|
||||
for i, unit in ipairs( wesnoth.units.find_on_map { side = side } ) do
|
||||
if not unit.__cfg.canrecruit then
|
||||
wml.fire("unit_worth", { id = unit.id })
|
||||
units = units + wml.variables["unit_worth"]
|
||||
end
|
||||
end
|
||||
-- Up to here
|
||||
local total = units + team.gold + income
|
||||
-- po: In the end-of-match summary, any side that still has units left
|
||||
local side_text = _ "<span foreground='$side_color'>Side $side_number</span>: Income score = $income Unit score = $units Gold = $gold\nGrand total: <b>$total</b>"
|
||||
side_comparison = side_comparison .. side_text:vformat{side_color = side_color, side_number = side, income = income, units = units, gold = team.gold, total = total} .. "\n"
|
||||
if total > total_score then
|
||||
winners_color = side_color
|
||||
winning_sides = {side}
|
||||
total_score = total
|
||||
elseif total == total_score then
|
||||
table.insert(winning_sides, side)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local result = nil
|
||||
|
||||
if #winning_sides == 1 then
|
||||
-- po: In the end-of-match summary, there's a single side that's won.
|
||||
local comparison_text = _ "<span foreground='$side_color'>Side $side_number</span> has the advantage."
|
||||
side_comparison = side_comparison .. "\n" .. comparison_text:vformat{side_number = winning_sides[1], side_color = winners_color}
|
||||
result = winning_sides[1]
|
||||
else -- #winning_sides == 2, a tie (or both sides have no units or a negative score which should be impossible here)
|
||||
-- po: In the end-of-match summary, there's a two-way tie (this is only used for exactly two winning teams)
|
||||
local comparison_text = _ "Sides $side_number and $other_side_number are tied."
|
||||
side_comparison = side_comparison .. "\n" .. comparison_text:vformat{side_number = winning_sides[1], other_side_number = winning_sides[2]}
|
||||
result = "tie"
|
||||
end
|
||||
if dialog_type == "turnsover" then
|
||||
-- po: "Turns Over", meaning "turn limit reached" is the title of the end-of-match summary dialog
|
||||
local a, b = gui.show_popup(_ "dialog^Turns Over", side_comparison)
|
||||
else
|
||||
local a, b = gui.show_popup(_ "dialog^Advantage", side_comparison)
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
arg={...}
|
||||
-- There need to be two different dialog titles, but the title is not passed directly as a string because it wouldn't be translatable in that case.
|
||||
dialog_type=arg[1]
|
||||
return determine_advantage()
|
|
@ -362,7 +362,14 @@ You shall learn a pivotal lesson in humility!"
|
|||
image="icons/advantage.png"
|
||||
[command]
|
||||
[lua]
|
||||
code = << wml.variables["result"] = wesnoth.dofile("campaigns/Winds_of_Fate/lua/lua.lua", "advantage") >>
|
||||
code = <<
|
||||
local eras = wesnoth.require("multiplayer/eras.lua")
|
||||
local winning_sides, scores = eras.calc_turns_over_advantage()
|
||||
eras.show_turns_over_advantage(winning_sides, scores, (...).title)
|
||||
>>
|
||||
[args]
|
||||
title=_ "dialog^Advantage"
|
||||
[/args]
|
||||
[/lua]
|
||||
[/command]
|
||||
[/set_menu_item]
|
||||
|
@ -380,33 +387,21 @@ You shall learn a pivotal lesson in humility!"
|
|||
first_time_only=no
|
||||
# Determine which side has the advantage.
|
||||
[lua]
|
||||
code = << wml.variables["result"] = wesnoth.dofile("campaigns/Winds_of_Fate/lua/lua.lua", "turnsover") >>
|
||||
code = <<
|
||||
local eras = wesnoth.require("multiplayer/eras.lua")
|
||||
local winning_sides, scores = eras.calc_turns_over_advantage()
|
||||
eras.show_turns_over_advantage(winning_sides, scores)
|
||||
if #winning_sides == 1 then
|
||||
if winning_sides[1] == 1 then
|
||||
wml.fire.endlevel{result = 'victory'}
|
||||
elseif winning_sides[1] == 2 then
|
||||
wml.fire.endlevel{result = 'defeat'}
|
||||
end
|
||||
elseif #winning_sides == 2 then
|
||||
wml.fire.modify_turns{add = 2}
|
||||
end
|
||||
>>
|
||||
[/lua]
|
||||
[switch]
|
||||
variable=result
|
||||
[case]
|
||||
value=1
|
||||
[endlevel]
|
||||
result=victory
|
||||
[/endlevel]
|
||||
[/case]
|
||||
[case]
|
||||
value=2
|
||||
[endlevel]
|
||||
result=defeat
|
||||
[/endlevel]
|
||||
[/case]
|
||||
[case]
|
||||
value=tie
|
||||
[modify_turns]
|
||||
add=2
|
||||
[/modify_turns]
|
||||
[/case]
|
||||
[else]
|
||||
# Error, do nothing and end in defeat.
|
||||
[/else]
|
||||
[/switch]
|
||||
{CLEAR_VARIABLE result}
|
||||
[/event]
|
||||
|
||||
[event]
|
||||
|
|
|
@ -21,7 +21,7 @@ res.quick_4mp_leaders = function(args)
|
|||
end
|
||||
end
|
||||
|
||||
res.turns_over_advantage = function()
|
||||
function res.turns_over_advantage()
|
||||
local show_turns_over_advantage = wml.variables["show_turns_over_advantage"]
|
||||
if show_turns_over_advantage == nil then
|
||||
show_turns_over_advantage = wesnoth.scenario.mp_settings and (wesnoth.scenario.mp_settings.mp_campaign == "")
|
||||
|
@ -29,7 +29,23 @@ res.turns_over_advantage = function()
|
|||
if not show_turns_over_advantage then
|
||||
return
|
||||
end
|
||||
local _ = wesnoth.textdomain "wesnoth-multiplayer"
|
||||
local winning_sides, side_results = res.calc_turns_over_advantage()
|
||||
res.show_turns_over_advantage(winning_sides, side_results)
|
||||
end
|
||||
|
||||
---@class side_result
|
||||
---@field income integer
|
||||
---@field num_units integer
|
||||
---@field gold integer
|
||||
---@field total integer
|
||||
|
||||
---@alias sides_score_table table<integer, side_result|false>
|
||||
|
||||
---Calculate the turns over advantage.
|
||||
---@param income_factor? integer Indicates how important income is in the calculation.
|
||||
---@return integer[]
|
||||
---@return sides_score_table
|
||||
function res.calc_turns_over_advantage(income_factor)
|
||||
local function all_sides()
|
||||
local function f(s, i)
|
||||
i = i + 1
|
||||
|
@ -39,37 +55,36 @@ res.turns_over_advantage = function()
|
|||
return f, nil, 0
|
||||
end
|
||||
|
||||
local income_factor = 5
|
||||
income_factor = income_factor or 5
|
||||
|
||||
local winning_sides = {}
|
||||
local total_score = -1
|
||||
local side_comparison = ""
|
||||
local winners_color = "#000000"
|
||||
|
||||
---@type sides_score_table
|
||||
local side_outcomes = {}
|
||||
for side, team in all_sides() do
|
||||
if not team.__cfg.hidden then
|
||||
local side_color = wesnoth.colors[team.color].pango_color
|
||||
if # wesnoth.units.find_on_map( { side = side } ) == 0 then
|
||||
-- po: In the end-of-match summary, a side which has no units left and therefore lost. In English the loss is shown by displaying it with the text struck through.
|
||||
local side_text = _ "<span strikethrough='true' foreground='$side_color'>Side $side_number</span>: Has lost all units"
|
||||
-- The double new-line here is to balance with the other sides getting a line for "Grand total"
|
||||
side_comparison = side_comparison .. side_text:vformat{side_color = side_color, side_number = side} .. "\n\n"
|
||||
side_outcomes[side] = false
|
||||
else
|
||||
local income = team.total_income * income_factor
|
||||
local units = 0
|
||||
-- Calc the total unit-score here
|
||||
for i, unit in ipairs( wesnoth.units.find_on_map { side = side } ) do
|
||||
if not unit.__cfg.canrecruit then
|
||||
wml.fire("unit_worth", { id = unit.id })
|
||||
units = units + wml.variables["unit_worth"]
|
||||
wml.fire.unit_worth{ id = unit.id }
|
||||
units = units + wml.variables.unit_worth
|
||||
end
|
||||
end
|
||||
-- Up to here
|
||||
local total = units + team.gold + income
|
||||
-- po: In the end-of-match summary, any side that still has units left
|
||||
local side_text = _ "<span foreground='$side_color'>Side $side_number</span>: Income score = $income Unit score = $units Gold = $gold\nGrand total: <b>$total</b>"
|
||||
side_comparison = side_comparison .. side_text:vformat{side_color = side_color, side_number = side, income = income, units = units, gold = team.gold, total = total} .. "\n"
|
||||
side_outcomes[side] = {
|
||||
income = income,
|
||||
num_units = units,
|
||||
gold = team.gold,
|
||||
total = total
|
||||
}
|
||||
if total > total_score then
|
||||
winners_color = side_color
|
||||
winning_sides = {side}
|
||||
total_score = total
|
||||
elseif total == total_score then
|
||||
|
@ -79,10 +94,38 @@ res.turns_over_advantage = function()
|
|||
end
|
||||
end
|
||||
|
||||
return winning_sides, side_outcomes
|
||||
end
|
||||
|
||||
---Show the turns over advantage popup.
|
||||
---@param winning_sides integer[] The list of sides who tied for first place
|
||||
---@param side_results sides_score_table The table of each side's score calculations
|
||||
---@param title? tstring The title to display in the popup
|
||||
function res.show_turns_over_advantage(winning_sides, side_results, title)
|
||||
local _ = wesnoth.textdomain "wesnoth-multiplayer"
|
||||
---@type tstring
|
||||
local side_comparison = ""
|
||||
for side = 1, #wesnoth.sides do
|
||||
local outcome = side_results[side]
|
||||
local side_color = wesnoth.colors[wesnoth.sides[side].color].pango_color
|
||||
if outcome == false then
|
||||
-- po: In the end-of-match summary, a side which has no units left and therefore lost. In English the loss is shown by displaying it with the text struck through.
|
||||
local side_text = _ "<span strikethrough='true' foreground='$side_color'>Side $side_number</span>: Has lost all units"
|
||||
-- The double new-line here is to balance with the other sides getting a line for "Grand total"
|
||||
side_comparison = side_comparison .. side_text:vformat{side_color = side_color, side_number = side} .. "\n\n"
|
||||
elseif outcome ~= nil then
|
||||
-- po: In the end-of-match summary, any side that still has units left
|
||||
local side_text = _ "<span foreground='$side_color'>Side $side_number</span>: Income score = $income Unit score = $units Gold = $gold\nGrand total: <b>$total</b>"
|
||||
side_comparison = side_comparison .. side_text:vformat{side_color = side_color, side_number = side, income = outcome.income, units = outcome.num_units, gold = outcome.gold, total = outcome.total} .. "\n"
|
||||
end
|
||||
end
|
||||
|
||||
if #winning_sides == 1 then
|
||||
local side = winning_sides[1]
|
||||
local side_color = wesnoth.colors[wesnoth.sides[side].color].pango_color
|
||||
-- po: In the end-of-match summary, there's a single side that's won.
|
||||
local comparison_text = _ "<span foreground='$side_color'>Side $side_number</span> has the advantage."
|
||||
side_comparison = side_comparison .. "\n" .. comparison_text:vformat{side_number = winning_sides[1], side_color = winners_color}
|
||||
side_comparison = side_comparison .. "\n" .. comparison_text:vformat{side_number = winning_sides[1], side_color = side_color}
|
||||
elseif #winning_sides == 2 then
|
||||
-- po: In the end-of-match summary, there's a two-way tie (this is only used for exactly two winning teams)
|
||||
-- Separated from the three-or-more text in case a language differentiates "two sides" vs "three sides".
|
||||
|
@ -95,8 +138,8 @@ res.turns_over_advantage = function()
|
|||
side_comparison = side_comparison .. "\n" .. comparison_text:vformat{winners = winners}
|
||||
end
|
||||
-- if #winning_sides==0, then every side either has no units or has a negative score
|
||||
|
||||
-- po: "Turns Over", meaning "turn limit reached" is the title of the end-of-match summary dialog
|
||||
local a, b = gui.show_popup(_ "dialog^Turns Over", side_comparison)
|
||||
title = title or _ "dialog^Turns Over"
|
||||
gui.show_popup(title, side_comparison)
|
||||
end
|
||||
return res
|
||||
|
|
Loading…
Add table
Reference in a new issue