wesnoth/data/multiplayer/eras.lua

145 lines
5.7 KiB
Lua

local T = wml.tag
local res = {}
res.quick_4mp_leaders = function(args)
local make_4mp_leaders_quick = wml.variables["make_4mp_leaders_quick"]
if make_4mp_leaders_quick == nil then
make_4mp_leaders_quick = wesnoth.scenario.mp_settings and (wesnoth.scenario.campaign == "")
end
if not make_4mp_leaders_quick then
return
end
local trait_quick = args[1][2]
for i, unit in ipairs(wesnoth.units.find_on_map { canrecruit = true, T.filter_wml { max_moves = 4 } }) do
if not unit.variables.dont_make_me_quick then
unit:add_modification("trait", trait_quick )
unit.moves = unit.max_moves
unit.hitpoints = unit.max_hitpoints
end
end
end
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.campaign == ""
end
if not show_turns_over_advantage then
return
end
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
local t = wesnoth.sides[i]
return t and i, t
end
return f, nil, 0
end
income_factor = income_factor or 5
local winning_sides = {}
local total_score = -1
---@type sides_score_table
local side_outcomes = {}
for side, team in all_sides() do
if not team.__cfg.hidden then
if # wesnoth.units.find_on_map( { side = side } ) == 0 then
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
end
end
-- Up to here
local total = units + team.gold + income
side_outcomes[side] = {
income = income,
num_units = units,
gold = team.gold,
total = total
}
if total > total_score then
winning_sides = {side}
total_score = total
elseif total == total_score then
table.insert(winning_sides, side)
end
end
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 = 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".
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]}
elseif #winning_sides ~= 0 then
local winners = stringx.format_conjunct_list("", winning_sides)
-- po: In the end-of-match summary, three or more teams have all tied for the best score. $winners contains the result of formatting the conjunct list.
local comparison_text = _ "Sides $winners are tied."
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
title = title or _ "dialog^Turns Over"
gui.show_popup(title, side_comparison)
end
return res