Skip to content

Commit

Permalink
Display economy values as decimals in unit viewer (FAForever#6282)
Browse files Browse the repository at this point in the history
## Description of the proposed changes
Displays the mass/energy production of a unit as a decimal value in the
unit viewer, with appropriate precision for the number. This makes the
effects of adjacency more visible.

Idea first popped up on
[Discord](https://discord.com/channels/197033481883222026/1224799508249055395/1226247496112799855),
but this uses the new engine patch for `GetRolloverInfo`
(FAForever/FA-Binary-Patches#75) instead of the
`UserUnit:GetEconData` that I'm assuming was used in that example.

## Testing done on the proposed changes
Before testing, make sure to go to the client and launch a FAF Develop
lobby to download the latest exe.
Spawned an air grid with fabs/radars/storages and moused over the
various buildings and over the factories building different units to
make sure that how the numbers are displayed makes sense.
<details> <summary> Spawn units command </summary>

```
   CreateUnitAtMouse('uab1101', 0,   -8.56,  -19.86, -0.00012)
   CreateUnitAtMouse('xsb1201', 0,   -0.56,   22.14,  0.00000)
   CreateUnitAtMouse('xsb1105', 0,    1.44,  -11.86,  0.00000)
   CreateUnitAtMouse('xsb1101', 0,  -14.56,    4.14,  0.00000)
   CreateUnitAtMouse('xsb1201', 0,  -16.56,    0.14, -0.00003)
   CreateUnitAtMouse('uab1101', 0,   -4.56,  -19.86, -0.00014)
   CreateUnitAtMouse('xsb1105', 0,   -2.56,  -15.86, -0.00002)
   CreateUnitAtMouse('ueb1106', 0,  -24.56,  -11.86, -0.00588)
   CreateUnitAtMouse('xsb1105', 0,   -2.56,  -17.86,  0.00000)
   CreateUnitAtMouse('xsb1105', 0,   -2.56,  -13.86,  0.00000)
   CreateUnitAtMouse('ueb1106', 0,   17.44,   28.14,  0.00000)
   CreateUnitAtMouse('ueb1106', 0,   13.44,   24.14,  0.00000)
   CreateUnitAtMouse('ueb1106', 0,  -12.56,   -3.86, -0.00002)
   CreateUnitAtMouse('xsb1101', 0,   -2.56,  -11.86,  0.00000)
   CreateUnitAtMouse('ueb1104', 0,   -4.56,    6.14,  0.00000)
   CreateUnitAtMouse('xsb1301', 0,    0.44,    9.14,  0.00000)
   CreateUnitAtMouse('ueb1106', 0,   -8.56,   12.14,  0.00000)
   CreateUnitAtMouse('ueb1106', 0,  -20.56,  -11.86, -0.00388)
   CreateUnitAtMouse('uab3101', 0,    3.44,   16.14,  0.00000)
   CreateUnitAtMouse('ueb1106', 0,   19.44,    8.14,  0.00000)
   CreateUnitAtMouse('xsb1303', 0,   -0.56,   16.14,  0.00000)
   CreateUnitAtMouse('xsb1303', 0,   -8.56,    8.14,  0.00000)
   CreateUnitAtMouse('xsb1301', 0,   -7.56,  -14.86, -0.00005)
   CreateUnitAtMouse('xsb1301', 0,    0.44,   -6.86,  0.00000)
   CreateUnitAtMouse('ueb1104', 0,  -12.56,    2.14,  0.00000)
   CreateUnitAtMouse('ueb1106', 0,  -10.56,  -23.86, -0.00107)
   CreateUnitAtMouse('xsb1303', 0,  -22.56,  -15.86, -0.00519)
   CreateUnitAtMouse('ueb1104', 0,   -4.56,   12.14,  0.00000)
   CreateUnitAtMouse('ueb1104', 0,   -4.56,    8.14,  0.00000)
   CreateUnitAtMouse('ueb1104', 0,   -4.56,   10.14,  0.00000)
   CreateUnitAtMouse('xsb1101', 0,  -20.56,  -19.86, -0.00388)
   CreateUnitAtMouse('xsb1303', 0,  -14.56,   -7.86, -0.00024)
   CreateUnitAtMouse('xsb1105', 0,    5.44,   -3.86,  0.00000)
   CreateUnitAtMouse('uab3101', 0,    3.44,   21.14,  0.00000)
   CreateUnitAtMouse('xsb1105', 0,    5.44,   -9.86,  0.00000)
   CreateUnitAtMouse('ueb1106', 0,   19.44,   10.14,  0.00000)
   CreateUnitAtMouse('xsb1303', 0,   17.44,   24.14,  0.00000)
   CreateUnitAtMouse('xsb0302', 0,   -7.56,   -6.86,  0.00000)
   CreateUnitAtMouse('xsb1303', 0,   23.44,   18.14,  0.00000)
   CreateUnitAtMouse('uab3101', 0,   -6.56,  -19.86,  0.00006)
   CreateUnitAtMouse('ueb1106', 0,  -16.56,  -25.86, -0.00452)
   CreateUnitAtMouse('ueb1106', 0,  -12.56,  -25.86, -0.00218)
   CreateUnitAtMouse('ueb1106', 0,  -14.56,  -25.86, -0.00292)
   CreateUnitAtMouse('ueb1106', 0,  -10.56,  -21.86, -0.00043)
   CreateUnitAtMouse('ueb1106', 0,  -10.56,  -19.86, -0.00016)
   CreateUnitAtMouse('ueb1106', 0,   25.44,   14.14,  0.00000)
   CreateUnitAtMouse('xsb1105', 0,   13.44,    2.14,  0.00000)
   CreateUnitAtMouse('xsb1105', 0,   13.44,    0.14,  0.00000)
   CreateUnitAtMouse('ueb1106', 0,   27.44,   16.14,  0.00000)
   CreateUnitAtMouse('ueb1106', 0,   23.44,   14.14,  0.00000)
   CreateUnitAtMouse('ueb1106', 0,   15.44,    6.14,  0.00000)
   CreateUnitAtMouse('xsb1303', 0,    9.44,   16.14,  0.00000)
   CreateUnitAtMouse('ueb1106', 0,   17.44,    6.14,  0.00000)
   CreateUnitAtMouse('ueb1106', 0,   27.44,   18.14,  0.00000)
   CreateUnitAtMouse('xsb1105', 0,   13.44,    4.14,  0.00000)
   CreateUnitAtMouse('ueb1106', 0,   13.44,    6.14,  0.00000)
   CreateUnitAtMouse('xsb1105', 0,    3.44,   14.14,  0.00000)
   CreateUnitAtMouse('xsb1301', 0,    8.44,    1.14,  0.00000)
   CreateUnitAtMouse('xsb1105', 0,   13.44,   -1.86,  0.00000)
   CreateUnitAtMouse('xsb0302', 0,  -15.56,  -14.86,  0.00000)
   CreateUnitAtMouse('ueb1104', 0,  -12.56,    0.14,  0.00000)
   CreateUnitAtMouse('xsb1301', 0,   -7.56,    1.14,  0.00000)
   CreateUnitAtMouse('xsb0302', 0,    0.44,    1.14,  0.00000)
   CreateUnitAtMouse('xsb0302', 0,   24.44,   25.14,  0.00000)
   CreateUnitAtMouse('ueb1104', 0,  -12.56,   -1.86, -0.00002)
   CreateUnitAtMouse('xsb0302', 0,   16.44,   17.14,  0.00000)
   CreateUnitAtMouse('xsb0302', 0,    8.44,    9.14,  0.00000)
   CreateUnitAtMouse('xsb1303', 0,  -14.56,  -21.86, -0.00162)
   CreateUnitAtMouse('xsb1303', 0,   15.44,   10.14,  0.00000)
   CreateUnitAtMouse('ueb1104', 0,  -12.56,    4.14,  0.00000)
   CreateUnitAtMouse('ueb1106', 0,   -6.56,   12.14,  0.00000)
   CreateUnitAtMouse('ueb1106', 0,  -22.56,  -11.86, -0.00524)
   CreateUnitAtMouse('xsb1301', 0,   -5.56,  -24.86, -0.00018)
   CreateUnitAtMouse('xsb1301', 0,   -5.56,  -24.86, -0.00051)
   CreateUnitAtMouse('xsb1201', 0,    9.44,   -5.86,  0.00000)
   CreateUnitAtMouse('uab1101', 0,    5.44,   21.14,  0.00000)
   CreateUnitAtMouse('ueb1106', 0,   -4.56,   14.14,  0.00000)
```
</details>

## Additional context
<!-- Add any other context about the pull request here. -->
A further improvement would be adding how much of the
production/consumption change comes from the adjacency bonus.

## Checklist
- [x] Changes are annotated, including comments where useful
- [x] Changes are documented in the changelog for the next game version
  • Loading branch information
lL1l1 authored Jun 21, 2024
1 parent 1df4a22 commit d114575
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 4 deletions.
1 change: 1 addition & 0 deletions changelog/snippets/features.6282.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- (#6282) The unit viewer that appears when you hover over a unit now shows decimals for mass/energy consumption/production, which helps show adjacency bonuses and other small numbers.
3 changes: 3 additions & 0 deletions engine/User/UserUnit.lua
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ local UserUnit = {}
---@field tacticalSiloMaxStorageCount number
---@field tacticalSiloStorageCount number

-- Thanks to the following engine patches this contains floats instead of ints:
-- - https://github.com/FAForever/FA-Binary-Patches/pull/14
-- - https://github.com/FAForever/FA-Binary-Patches/pull/75
---@class EconData
---@field energyConsumed number
---@field energyProduced number
Expand Down
44 changes: 40 additions & 4 deletions lua/ui/game/unitview.lua
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,30 @@ local function FormatTime(seconds)
end

local statFuncs = {
-- combined stats showing mass trend for own units or army icon + nickname for others' units
function(info)
local massUsed = math.max(info.massRequested, info.massConsumed)
if info.massProduced > 0 or massUsed > 0 then
return string.format('%+d', math.ceil(info.massProduced - massUsed)),
UIUtil.UIFile('/game/unit_view_icons/mass.dds'), '00000000'
local netMass = info.massProduced - massUsed
local absNetMass = math.abs(netMass)
local str
-- Thanks to an engine patch, `GetRolloverInfo` returns floats for economy values:
-- - https://github.com/FAForever/FA-Binary-Patches/pull/75
-- This allows us to show adjacency-affected values better.
if absNetMass < 5 then
str = string.format('%+.3g', netMass)
elseif absNetMass < 10 then
str = string.format('%+.2g', netMass)
elseif absNetMass < 100 then
str = string.format('%+.3g', netMass)
else
str = string.format('%+d', math.round(netMass))
end

return str
, UIUtil.UIFile('/game/unit_view_icons/mass.dds')
, '00000000'

elseif info.armyIndex + 1 ~= GetFocusArmy() and info.kills == 0 and info.shieldRatio <= 0 then
local armyData = GetArmiesTable().armiesTable[info.armyIndex + 1]
local icon = Factions.Factions[armyData.faction + 1].Icon
Expand All @@ -153,14 +172,27 @@ local statFuncs = {
return false
end
end,
-- energy trend
function(info)
local energyUsed = math.max(info.energyRequested, info.energyConsumed)
if info.energyProduced > 0 or energyUsed > 0 then
return string.format('%+d', math.ceil(info.energyProduced - energyUsed))
local netEnergy = info.energyProduced - energyUsed
local absNetEnergy = math.abs(netEnergy)
-- Thanks to an engine patch, `GetRolloverInfo` returns floats for economy values:
-- - https://github.com/FAForever/FA-Binary-Patches/pull/75
-- This allows us to show adjacency-affected values better.
if absNetEnergy < 10 then
return string.format('%+.2g', netEnergy)
elseif absNetEnergy < 100 then
return string.format('%+.3g', netEnergy)
else
return string.format('%+d', math.round(netEnergy))
end
else
return false
end
end,
-- vet xp
function(info)
if UnitData[info.entityId].xp ~= nil then
local nextLevel = 0
Expand All @@ -181,14 +213,15 @@ local statFuncs = {


end,
-- kill count
function(info)
if info.kills > 0 then
return string.format('%d', info.kills)
else
return false
end
end,

-- tactical/strategic missile count
function(info)
if info.tacticalSiloMaxStorageCount > 0 or info.nukeSiloMaxStorageCount > 0 then
if info.userUnit:IsInCategory('VERIFYMISSILEUI') then
Expand Down Expand Up @@ -219,20 +252,23 @@ local statFuncs = {
return false
end
end,
-- shield % HP
function(info, bp)
if info.shieldRatio > 0 then
return string.format('%d%%', math.floor(info.shieldRatio * 100))
else
return false
end
end,
-- fuel remaining time
function(info, bp)
if info.fuelRatio > -1 then
return FormatTime(bp.Physics.FuelUseTime * info.fuelRatio)
else
return false
end
end,
-- buildrate
function(info, bp)
if options.gui_detailed_unitview == 0 then
return false
Expand Down

0 comments on commit d114575

Please sign in to comment.