Skip to content

Commit f3fbabc

Browse files
committed
fix: resource transfer messages, i18n.interpolate can handle too many variables
I believe a rebasing master broke my resource send chat messages because it was attempting to highlight resource text. I fixed this but got irritated at how interpolation works along the way. We can now send many named variables to interpolation and as long as we're using the named paramter pattern instead of the string interpolation pattern we're fine to send too many. This simplifies my comms variable creation (which was all idempotent anyway) and allows me to pass "resourceType" as part of the payload to gui_chat. My main concern here is that I was too precious with the previous implicit key based resourceType determination. Like am I the only caller and all of this code exists for no reason? Whatever it's fine.
1 parent 5d985ad commit f3fbabc

5 files changed

Lines changed: 97 additions & 37 deletions

File tree

common/luaUtilities/team_transfer/resource_transfer_comms.lua

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
local SharedEnums = VFS.Include("sharing_modes/shared_enums.lua")
2+
local Cache = VFS.Include("common/luaUtilities/team_transfer/team_transfer_cache.lua")
3+
local FieldTypes = Cache.FieldTypes
24

35
local Comms = {
46
ResourceCommunicationCase = SharedEnums.ResourceCommunicationCase,
@@ -67,6 +69,22 @@ function Comms.TooltipText(policyResult)
6769
end
6870
end
6971

72+
Comms.SendTransferChatMessageProtocol = {
73+
receivedAmount = FieldTypes.string,
74+
sentAmount = FieldTypes.string,
75+
taxRatePercentage = FieldTypes.string,
76+
sentAmountUntaxed = FieldTypes.string,
77+
resourceShareThreshold = FieldTypes.string,
78+
}
79+
80+
Comms.SendTransferChatMessageProtocolHighlights = {
81+
receivedAmount = true,
82+
sentAmount = true,
83+
taxRatePercentage = false,
84+
sentAmountUntaxed = true,
85+
resourceShareThreshold = true,
86+
}
87+
7088
--- Send chat messages for completed resource transfers
7189
---@param transferResult ResourceTransferResult
7290
---@param policyResult ResourcePolicyResult
@@ -75,30 +93,27 @@ function Comms.SendTransferChatMessages(transferResult, policyResult)
7593
local resourceType = policyResult.resourceType
7694
local pascalResourceType = resourceType == SharedEnums.ResourceType.METAL and "Metal" or "Energy"
7795
local case = Comms.DecideCommunicationCase(policyResult)
96+
local cumulativeUntaxed = math.min(policyResult.resourceShareThreshold, policyResult.cumulativeSent)
97+
local chatParams = {
98+
receivedAmount = math.floor(transferResult.received),
99+
sentAmount = FormatNumberForUI(transferResult.sent),
100+
taxRatePercentage = FormatNumberForUI(policyResult.taxRate * 100 + 0.5),
101+
sentAmountUntaxed = FormatNumberForUI(cumulativeUntaxed),
102+
resourceShareThreshold = FormatNumberForUI(policyResult.resourceShareThreshold),
103+
resourceType = resourceType,
104+
}
78105

106+
local key
79107
if case == SharedEnums.ResourceCommunicationCase.OnTaxFree then
80-
Spring.SendLuaRulesMsg('msg:ui.playersList.chat.sent' ..
81-
pascalResourceType .. ':receivedAmount=' .. math.floor(transferResult.received))
108+
key = 'ui.playersList.chat.sent' .. pascalResourceType
82109
elseif case == SharedEnums.ResourceCommunicationCase.OnTaxed then
83-
Spring.SendLuaRulesMsg('msg:ui.playersList.chat.sent' ..
84-
pascalResourceType ..
85-
'Taxed:receivedAmount=' ..
86-
math.floor(transferResult.received) ..
87-
':sentAmount=' ..
88-
math.floor(transferResult.sent) .. ':taxRatePercentage=' .. math.floor(policyResult.taxRate * 100 + 0.5))
110+
key = 'ui.playersList.chat.sent' .. pascalResourceType .. 'Taxed'
89111
elseif case == SharedEnums.ResourceCommunicationCase.OnTaxedThreshold then
90-
local cumulativeUntaxed = math.min(policyResult.resourceShareThreshold, policyResult.cumulativeSent)
91-
Spring.SendLuaRulesMsg('msg:ui.playersList.chat.sent' ..
92-
pascalResourceType ..
93-
'TaxedThreshold:receivedAmount=' ..
94-
math.floor(transferResult.received) ..
95-
':sentAmount=' ..
96-
math.floor(transferResult.sent) ..
97-
':taxRatePercentage=' ..
98-
math.floor(policyResult.taxRate * 100 + 0.5) ..
99-
':sentAmountUntaxed=' ..
100-
math.floor(cumulativeUntaxed) .. ':resourceShareThreshold=' .. math.floor(policyResult.resourceShareThreshold))
112+
key = 'ui.playersList.chat.sent' .. pascalResourceType .. 'TaxedThreshold'
101113
end
114+
115+
local serialized = Cache.Serialize(Comms.SendTransferChatMessageProtocol, chatParams)
116+
Spring.SendLuaRulesMsg('msg:' .. key .. ':' .. serialized)
102117
end
103118
end
104119

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
local SharedEnums = VFS.Include("sharing_modes/shared_enums.lua")
2-
local UnitShared = VFS.Include("common/luaUtilities/team_transfer/unit_transfer_shared.lua")
32
local ResourceShared = VFS.Include("common/luaUtilities/team_transfer/resource_transfer_shared.lua")
3+
local UnitShared = VFS.Include("common/luaUtilities/team_transfer/unit_transfer_shared.lua")
44

55
local TeamTransfer = {}
66

7-
TeamTransfer.Units = UnitShared
87
TeamTransfer.Resources = ResourceShared
8+
TeamTransfer.Units = UnitShared
99

1010
return TeamTransfer

language/en/interface.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,11 +123,11 @@
123123
"giveMetal": "I sent %{amount} metal to %{name}",
124124
"giveEnergy": "I sent %{amount} energy to %{name}",
125125
"sentMetal": "Sent %{receivedAmount}m",
126-
"sentMetalTaxed": "Sent %{receivedAmount}m, spent %{sentAmount}m at %{taxRatePercentage}% overhead",
127-
"sentMetalTaxedThreshold": "Sent %{receivedAmount}m, spent %{sentAmount}m at %{taxRatePercentage}% overhead (free used %{sentAmountUntaxed}/%{resourceShareThreshold}m)",
126+
"sentMetalTaxed": "Sent %{receivedAmount}m, spent %{sentAmount}m at %{taxRatePercentage}%% overhead",
127+
"sentMetalTaxedThreshold": "Sent %{receivedAmount}m, spent %{sentAmount}m at %{taxRatePercentage}%% overhead (free used %{sentAmountUntaxed}/%{resourceShareThreshold}m)",
128128
"sentEnergy": "Sent %{receivedAmount}e",
129-
"sentEnergyTaxed": "Sent %{receivedAmount}e, spent %{sentAmount}e at %{taxRatePercentage}% overhead",
130-
"sentEnergyTaxedThreshold": "Sent %{receivedAmount}e, spent %{sentAmount}e at %{taxRatePercentage}% overhead (free used %{sentAmountUntaxed}/%{resourceShareThreshold}e)",
129+
"sentEnergyTaxed": "Sent %{receivedAmount}e, spent %{sentAmount}e at %{taxRatePercentage}%% overhead",
130+
"sentEnergyTaxedThreshold": "Sent %{receivedAmount}e, spent %{sentAmount}e at %{taxRatePercentage}%% overhead (free used %{sentAmountUntaxed}/%{resourceShareThreshold}e)",
131131
"takeTeam": "I took %{name}.",
132132
"takeTeamAmount": "I took %{name}: %{units} units, %{energy} energy and %{metal} metal."
133133
}

luaui/Widgets/gui_chat.lua

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ local LineTypes = {
2525
}
2626

2727
local utf8 = VFS.Include('common/luaUtilities/utf8.lua')
28+
local TeamTransfer = VFS.Include("common/luaUtilities/team_transfer/team_transfer_unsynced.lua")
2829

2930
local L_DEPRECATED = LOG.DEPRECATED
3031
local isDevSingle = (Spring.Utilities.IsDevMode() and Spring.Utilities.Gametype.IsSinglePlayer())
@@ -621,18 +622,49 @@ local function addChatLine(gameFrame, lineType, name, nameText, text, orgLineID,
621622
local params = string.split(text, ':')
622623
local t = {}
623624
if params[1] then
624-
for k,v in pairs(params) do
625-
if k > 1 then
626-
local pair = string.split(v, '=')
627-
if pair[2] then
628-
if playernames[pair[2]] then
629-
t[ pair[1] ] = getPlayerColorString(pair[2], gameFrame)..playernames[pair[2]][7]..msgColor
630-
elseif params[1]:lower():find('energy', nil, true) then
631-
t[ pair[1] ] = energyValueColor..pair[2]..msgColor
632-
elseif params[1]:lower():find('metal', nil, true) then
633-
t[ pair[1] ] = metalValueColor..pair[2]..msgColor
625+
local resourceType = nil
626+
if params[1]:lower():find('energy', nil, true) then
627+
resourceType = 'energy'
628+
elseif params[1]:lower():find('metal', nil, true) then
629+
resourceType = 'metal'
630+
end
631+
-- Check for explicit resourceType parameter (overrides key-based detection)
632+
for i = 2, #params, 2 do
633+
local key = params[i]
634+
local value = params[i + 1]
635+
if key == 'resourceType' and value then
636+
resourceType = value
637+
break
638+
end
639+
end
640+
641+
-- Second pass: process key-value pairs with determined resourceType
642+
for i = 2, #params, 2 do
643+
local key = params[i]
644+
local value = params[i + 1]
645+
if key and value then
646+
if key == 'resourceType' then
647+
-- Skip the resourceType parameter itself
648+
elseif playernames[value] then
649+
t[key] = getPlayerColorString(value, gameFrame)..playernames[value][7]..msgColor
650+
else
651+
local shouldHighlight = false
652+
if key:lower():find('energy', nil, true) or key:lower():find('metal', nil, true) then
653+
shouldHighlight = true
654+
else
655+
shouldHighlight = TeamTransfer.Resources.SendTransferChatMessageProtocolHighlights[key] == true
656+
end
657+
658+
if shouldHighlight then
659+
if resourceType == 'energy' then
660+
t[key] = energyValueColor..value..msgColor
661+
elseif resourceType == 'metal' then
662+
t[key] = metalValueColor..value..msgColor
663+
else
664+
t[key] = value
665+
end
634666
else
635-
t[ pair[1] ] = pair[2]
667+
t[key] = value
636668
end
637669
end
638670
end

modules/i18n/i18nlib/i18n/interpolate.lua

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,20 @@ local function interpolate(str, vars)
3030
str = escapeDoublePercent(str)
3131
str = interpolateVariables(str, vars)
3232
str = interpolateFormattedVariables(str, vars)
33-
str = string.format(str, unpack(vars))
33+
-- Handle any remaining % positional placeholders (e.g., %s, %d)
34+
-- Only if they exist and vars can be treated as array
35+
if str:find('%%') and not str:find('%%{') and not str:find('%%<') then
36+
local percentCount = 0
37+
for _ in str:gmatch('%%') do
38+
percentCount = percentCount + 1
39+
end
40+
-- For positional placeholders, assume vars[1], vars[2], etc.
41+
local args = {}
42+
for i = 1, percentCount do
43+
args[i] = vars[i] or vars[tostring(i)] or 'nil'
44+
end
45+
str = string.format(str, unpack(args))
46+
end
3447
str = unescapeDoublePercent(str)
3548
return str
3649
end

0 commit comments

Comments
 (0)