mirror of
https://github.com/wesnoth/wesnoth
synced 2025-04-15 17:20:57 +00:00
split gold_carryover into smaller functions
this way the functions can easily be reused for alternative carryover implementations.
This commit is contained in:
parent
f29f8fb368
commit
06d1fade32
|
@ -9,7 +9,7 @@ wesnoth.dofile 'lua/wml-tags.lua'
|
|||
wesnoth.dofile 'lua/feeding.lua'
|
||||
wesnoth.dofile 'lua/diversion.lua'
|
||||
wesnoth.dofile 'lua/stun.lua'
|
||||
wesnoth.dofile 'lua/carryover_gold.lua'
|
||||
wesnoth.dofile 'lua/scenario_end_events.lua'
|
||||
>>
|
||||
[/lua]
|
||||
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
local _ = wesnoth.textdomain "wesnoth"
|
||||
local carryover = {}
|
||||
|
||||
local function get_is_observer()
|
||||
--- Returns true iff there is not a single side that is controlled by the local human player.
|
||||
---@return boolean
|
||||
function carryover.get_is_observer()
|
||||
for _, side in ipairs(wesnoth.sides) do
|
||||
if side.controller == "human" and side.is_local then
|
||||
return false
|
||||
|
@ -9,7 +12,9 @@ local function get_is_observer()
|
|||
return true
|
||||
end
|
||||
|
||||
local function get_num_persistent_teams()
|
||||
--- Returns the numbner of sides which carry over to a next scenario.
|
||||
---@return integer
|
||||
function carryover.get_num_persistent_teams()
|
||||
local res = 0
|
||||
for _, side in ipairs(wesnoth.sides) do
|
||||
if side.persistent then
|
||||
|
@ -19,17 +24,85 @@ local function get_num_persistent_teams()
|
|||
return res
|
||||
end
|
||||
|
||||
local function get_num_villages()
|
||||
--- Gets the number of villages on the map.
|
||||
---@return integer
|
||||
function carryover.get_num_villages()
|
||||
return #(wesnoth.map.find{ gives_income = true })
|
||||
end
|
||||
|
||||
local function half_signed_value(num)
|
||||
return tostring(num)
|
||||
---@return boolean #whether there is another scenario after this one ends.
|
||||
function carryover.has_next_scenario()
|
||||
return wesnoth.scenario.next ~= "" and wesnoth.scenario.next ~= "null" and wesnoth.scenario.end_level_data.proceed_to_next_level
|
||||
end
|
||||
|
||||
local function get_popup_text_basic()
|
||||
---@return number #number fo turns left in the scenario
|
||||
function carryover.turns_left()
|
||||
return math.max(0, wesnoth.scenario.turns - wesnoth.current.turn)
|
||||
end
|
||||
|
||||
local is_observer = get_is_observer()
|
||||
--- Like tostring(num) but uses a prettier minus sign, to be used in the UI.
|
||||
---@return string
|
||||
function carryover.half_signed_value(num)
|
||||
if num < 0 then
|
||||
return "-" .. tostring(math.abs(num))
|
||||
else
|
||||
return tostring(num)
|
||||
end
|
||||
end
|
||||
|
||||
--- Calculates the amount of carryover gold.
|
||||
---@param side side
|
||||
---@param turns_left integer
|
||||
---@return number #total finishing bonus
|
||||
---@return number #finishing bonus per turn
|
||||
function carryover.calculate_finishing_bonus(side, turns_left)
|
||||
local num_villages = carryover.get_num_villages()
|
||||
|
||||
local finishing_bonus_per_turn = num_villages * side.village_gold + side.base_income
|
||||
local finishing_bonus = math.ceil(side.carryover_bonus * finishing_bonus_per_turn * turns_left)
|
||||
return finishing_bonus, finishing_bonus_per_turn
|
||||
end
|
||||
|
||||
---@return boolean #whether we should show the carryover report
|
||||
function carryover.get_report_visible()
|
||||
local is_observer = carryover.get_is_observer()
|
||||
local is_replay = wesnoth.current.user_is_replaying
|
||||
return wesnoth.scenario.end_level_data.carryover_report and (not is_observer) and (not is_replay)
|
||||
end
|
||||
|
||||
--- Whether to show the sides' names in the scenario end report.
|
||||
---@return boolean
|
||||
function carryover.get_show_side_names()
|
||||
local num_persistent_teams = carryover.get_num_persistent_teams()
|
||||
return num_persistent_teams > 1
|
||||
end
|
||||
|
||||
---@class side_carryover_info
|
||||
---@field turns_left? number number of turns left
|
||||
---@field finishing_bonus number early finishing bonus gold
|
||||
---@field finishing_bonus_per_turn number early finishing bonus gold per turn
|
||||
|
||||
--- sets the sides carryover gold and returns information that is used in the report message
|
||||
---@param side side
|
||||
---@return side_carryover_info
|
||||
function carryover.set_side_carryover_gold(side)
|
||||
local turns_left = carryover.turns_left()
|
||||
local finishing_bonus, finishing_bonus_per_turn = carryover.calculate_finishing_bonus(side, turns_left)
|
||||
|
||||
side.carryover_gold = math.ceil((side.gold + finishing_bonus) * side.carryover_percentage / 100)
|
||||
|
||||
return {
|
||||
turns_left = turns_left,
|
||||
finishing_bonus = finishing_bonus,
|
||||
finishing_bonus_per_turn = finishing_bonus_per_turn,
|
||||
}
|
||||
end
|
||||
|
||||
--- returns a stub to show in the scenario end dialog.
|
||||
---@return string #title
|
||||
---@return string #report
|
||||
function carryover.get_popup_text_basic()
|
||||
local is_observer = carryover.get_is_observer()
|
||||
local is_victory = wesnoth.scenario.end_level_data.is_victory
|
||||
|
||||
local report = ""
|
||||
|
@ -47,84 +120,126 @@ local function get_popup_text_basic()
|
|||
return title, report
|
||||
end
|
||||
|
||||
local function do_carryover_gold()
|
||||
---@param side side
|
||||
---@param info side_carryover_info
|
||||
---@return string #A string to be used in the carryover dialog, describing the remainling gold
|
||||
function carryover.remaining_gold_message(side, info)
|
||||
return "<small>\n" .. _("Remaining gold: ") .. carryover.half_signed_value(side.gold) .. "</small>"
|
||||
end
|
||||
|
||||
local endlevel_data = wesnoth.scenario.end_level_data
|
||||
local has_next_scenario = wesnoth.scenario.next ~= "" and wesnoth.scenario.next ~= "null" and endlevel_data.proceed_to_next_level
|
||||
local is_victory = endlevel_data.is_victory
|
||||
local is_observer = get_is_observer()
|
||||
local is_replay = wesnoth.current.iser_is_replaying
|
||||
local show_report = endlevel_data.carryover_report and (not is_observer) and (not is_replay)
|
||||
---@param side side
|
||||
---@param info side_carryover_info
|
||||
---@return string #A string to be used in the carryover dialog, describing the bonus gold
|
||||
function carryover.bonus_gold_message(side, info)
|
||||
local res = ""
|
||||
if info.turns_left ~= nil then
|
||||
res = res .. "<b>" .. _("Turns finished early: ") .. info.turns_left .. "</b>\n"
|
||||
end
|
||||
if info.finishing_bonus_per_turn ~= nil then
|
||||
res = res .. "<small>" .. _("Early finish bonus: ") .. info.finishing_bonus_per_turn .. _(" per turn") .. "</small>\n"
|
||||
end
|
||||
res = res .. "<small>" .. _("Total bonus: ") .. info.finishing_bonus .. "</small>"
|
||||
|
||||
local num_villages = get_num_villages()
|
||||
local turns_left = math.max(0, wesnoth.scenario.turns - wesnoth.current.turn)
|
||||
local num_persistent_teams = get_num_persistent_teams()
|
||||
return res
|
||||
end
|
||||
|
||||
local title, report = get_popup_text_basic()
|
||||
---@param side side
|
||||
---@param info side_carryover_info
|
||||
---@return string #A string to be used in the carryover dialog, describing the total gold
|
||||
function carryover.total_gold_message(side, info)
|
||||
return "<small>" .. _("Total gold: ") .. carryover.half_signed_value(side.gold + info.finishing_bonus) .. "</small>"
|
||||
end
|
||||
|
||||
---@param side side
|
||||
---@param info side_carryover_info
|
||||
---@return string #A string to be used in the carryover dialog, describing the percentage of gold carried over
|
||||
function carryover.percentage_remaining_message(side, info)
|
||||
return "<small>" .. _("Carryover percentage: ") .. side.carryover_percentage .. "</small>"
|
||||
end
|
||||
--- returns the last part of the gold report for a single side, describing how much gold is added in the next scenario.
|
||||
---@param side side
|
||||
---@param info side_carryover_info
|
||||
---@return string
|
||||
function carryover.carryover_mesage(side, info)
|
||||
local goldmsg = ""
|
||||
if side.carryover_add then
|
||||
goldmsg = goldmsg .. "<big><b>" .. _("Bonus gold: ") .. carryover.half_signed_value(side.carryover_gold) .. "</b></big>"
|
||||
else
|
||||
goldmsg = goldmsg .. "<big><b>" .. _("Retained gold: ") .. carryover.half_signed_value(side.carryover_gold) .. "</b></big>"
|
||||
end
|
||||
goldmsg = goldmsg .. "\n"
|
||||
-- Note that both strings are the same in English, but some languages will
|
||||
-- want to translate them differently.
|
||||
if side.carryover_add then
|
||||
if side.carryover_gold > 0 then
|
||||
goldmsg = goldmsg .. _("You will start the next scenario with $gold on top of the defined minimum starting gold.",
|
||||
"You will start the next scenario with $gold on top of the defined minimum starting gold.", side.carryover_gold)
|
||||
|
||||
else
|
||||
goldmsg = goldmsg .. _("You will start the next scenario with the defined minimum starting gold.")
|
||||
end
|
||||
else
|
||||
goldmsg = goldmsg .. _(
|
||||
"You will start the next scenario with $gold or its defined minimum starting gold, whichever is higher.",
|
||||
"You will start the next scenario with $gold or its defined minimum starting gold, whichever is higher.",
|
||||
side.carryover_gold)
|
||||
end
|
||||
|
||||
return goldmsg:vformat{ gold = tostring(side.carryover_gold) }
|
||||
end
|
||||
|
||||
--- returns the default gold report for a single side.
|
||||
---@param side side
|
||||
---@param info side_carryover_info
|
||||
---@return string
|
||||
function carryover.get_side_gold_report(side, info)
|
||||
|
||||
local report = ""
|
||||
|
||||
report = report .. carryover.remaining_gold_message(side, info)
|
||||
|
||||
if side.carryover_bonus ~= 0 then
|
||||
report = report .. "\n\n" .. carryover.bonus_gold_message(side, info) .. "\n" .. carryover.total_gold_message(side, info)
|
||||
end
|
||||
|
||||
if side.carryover_gold > 0 then
|
||||
report = report .. "\n" .. carryover.percentage_remaining_message(side, info)
|
||||
end
|
||||
|
||||
|
||||
report = report .. "\n\n" .. carryover.carryover_mesage(side, info)
|
||||
return report
|
||||
end
|
||||
|
||||
|
||||
--- the main function that set every sides carryover gold amount and shows the correct carryover report dialog.
|
||||
function carryover.do_carryover_gold()
|
||||
|
||||
local has_next_scenario = carryover.has_next_scenario()
|
||||
local show_report = carryover.get_report_visible()
|
||||
|
||||
local show_side_names = carryover.get_show_side_names()
|
||||
|
||||
local title, report = carryover.get_popup_text_basic()
|
||||
|
||||
if has_next_scenario then
|
||||
for __, side in ipairs(wesnoth.sides) do
|
||||
if (not side.persistent) or side.lost then
|
||||
goto continue
|
||||
end
|
||||
local finishing_bonus_per_turn = num_villages * side.village_gold + side.base_income
|
||||
local finishing_bonus = side.carryover_bonus * finishing_bonus_per_turn * turns_left
|
||||
|
||||
side.carryover_gold = math.ceil((side.gold + finishing_bonus) * side.carryover_percentage / 100)
|
||||
local data = carryover.set_side_carryover_gold(side)
|
||||
|
||||
local is_human = side.controller == "human"
|
||||
if (not side.is_local) or (not is_human) then
|
||||
goto continue
|
||||
end
|
||||
|
||||
if num_persistent_teams > 1 then
|
||||
if show_side_names then
|
||||
report = report .. "\n\n<b>" .. side.side_name .. "</b>"
|
||||
end
|
||||
|
||||
report = report .. "<small>\n" .. _("Remaining gold: ") .. half_signed_value(side.gold) .. "</small>"
|
||||
|
||||
if side.carryover_bonus ~= 0 then
|
||||
if turns_left > -1 then
|
||||
report = report .. "\n\n<b>" ..
|
||||
_("Turns finished early: ") .. turns_left .. "</b>\n" .. "<small>" ..
|
||||
_("Early finish bonus: ") .. finishing_bonus_per_turn .. _(" per turn") .. "</small>\n" .. "<small>" ..
|
||||
_("Total bonus: ") .. finishing_bonus .. "</small>\n"
|
||||
end
|
||||
|
||||
report = report .. "<small>" .. _("Total gold: ") .. half_signed_value(side.gold + finishing_bonus) .. "</small>"
|
||||
end
|
||||
|
||||
if side.gold > 0 then
|
||||
report = report .. "\n<small>" .. _("Carryover percentage: ") .. side.carryover_percentage .. "</small>"
|
||||
end
|
||||
|
||||
if side.carryover_add then
|
||||
report = report .. "\n\n<big><b>" .. _("Bonus gold: ") .. half_signed_value(side.carryover_gold) .. "</b></big>"
|
||||
else
|
||||
report = report .. "\n\n<big><b>" .. _("Retained gold: ") .. half_signed_value(side.carryover_gold) .. "</b></big>"
|
||||
end
|
||||
|
||||
local goldmsg = ""
|
||||
-- Note that both strings are the same in English, but some languages will
|
||||
-- want to translate them differently.
|
||||
if side.carryover_add then
|
||||
if side.carryover_gold > 0 then
|
||||
goldmsg = _("You will start the next scenario with $gold on top of the defined minimum starting gold.",
|
||||
"You will start the next scenario with $gold on top of the defined minimum starting gold.", side.carryover_gold)
|
||||
|
||||
else
|
||||
goldmsg = _("You will start the next scenario with the defined minimum starting gold.",
|
||||
"You will start the next scenario with the defined minimum starting gold.", side.carryover_gold)
|
||||
end
|
||||
else
|
||||
goldmsg = _(
|
||||
"You will start the next scenario with $gold or its defined minimum starting gold, whichever is higher.",
|
||||
"You will start the next scenario with $gold or its defined minimum starting gold, whichever is higher.",
|
||||
side.carryover_gold)
|
||||
end
|
||||
|
||||
-- xgettext:no-c-format
|
||||
report = report .. "\n" .. goldmsg:vformat{ gold = tostring(side.carryover_gold) }
|
||||
report = report .. carryover.get_side_gold_report(side, data)
|
||||
|
||||
::continue::
|
||||
end
|
||||
|
@ -135,13 +250,4 @@ local function do_carryover_gold()
|
|||
end
|
||||
end
|
||||
|
||||
|
||||
wesnoth.game_events.add {
|
||||
name = "scenario_end",
|
||||
id = "carryover_gold",
|
||||
first_time_only = false,
|
||||
--priority = -1000,
|
||||
action = function()
|
||||
do_carryover_gold()
|
||||
end
|
||||
}
|
||||
return carryover
|
||||
|
|
11
data/lua/scenario_end_events.lua
Normal file
11
data/lua/scenario_end_events.lua
Normal file
|
@ -0,0 +1,11 @@
|
|||
local carryover = wesnoth.require("carryover_gold.lua")
|
||||
|
||||
wesnoth.game_events.add {
|
||||
name = "scenario_end",
|
||||
id = "carryover_gold",
|
||||
first_time_only = false,
|
||||
priority = -1000,
|
||||
action = function()
|
||||
carryover.do_carryover_gold()
|
||||
end
|
||||
}
|
Loading…
Reference in New Issue
Block a user