summaryrefslogtreecommitdiff
path: root/disengage_damaged_units.lua
blob: 032561ce00ec1c93d2b8383db7f17ef48f6916f4 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
function widget:GetInfo()
  return {
    name = "DisengageDamagedUnits",
    desc = "Disengages damaged units from the battle",
    author = "UnicodeSnowman",
    date = "May 2023",
    license = "GPL v2",
    layer = 0,
    enabled = true
  }
end

-- Some defines to make the language server happier.
widgetHandler = assert(widgetHandler)
widget = assert(widget)
Spring = assert(Spring)
WG = assert(WG)

-- Units below this damage threshold will be disengaged. TODO make this
-- configurable.
local damageThreshold = 0.3

-- Spring commands for more speed.
local spGetSelectedUnits = Spring.GetSelectedUnits
local spGetUnitHealth = Spring.GetUnitHealth
local spGiveOrderToUnit = Spring.GiveOrderToUnit
local spSelectUnitArray = Spring.SelectUnitArray

local function disengageDamagedUnits()
  local newSelection = {}

  for _, uid in pairs(spGetSelectedUnits()) do
    local health, maxHealth, _, _, _ = spGetUnitHealth(uid)
    local percent = health / maxHealth

    if percent < damageThreshold then
      spGiveOrderToUnit(uid, WG.CMD_DISENGAGE, {}, 0)
    else
      table.insert(newSelection, uid)
    end
  end

  spSelectUnitArray(newSelection)
end

function widget:Initialize()
  -- The units with health below the health threshold will be disegaged from
  -- combat and be sent back to the fallback position.
  widgetHandler:AddAction(
    "disengage_damaged_units", disengageDamagedUnits, nil, "p")
end