Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions language/en/interface.json
Original file line number Diff line number Diff line change
Expand Up @@ -1669,6 +1669,8 @@
"smartselect_includebuildings_descr": "When rectangle-drag-selecting an area, include building units too?\n\nDisabled: non-mobile units will be excluded (hold Shift to override)\nNote: Construction Turrets will always be selected",
"smartselect_includebuilders": "include builders (if above is off)",
"smartselect_includebuilders_descr": "When rectangle-drag-selecting an area, exclude builder units (hold Shift to override)",
"smartselect_includeantinuke": "include antinuke units (if above is off)",
"smartselect_includeantinuke_descr": "When rectangle-drag-selecting an area, exclude antinuke units (hold Shift to override)",
"onlyfighterspatrol": "Only fighters patrol",
"onlyfighterspatrol_descr": "Only fighters obey a factory's patrol route after leaving airlab.",
"fightersfly": "Set fighters on Fly mode",
Expand Down
9 changes: 9 additions & 0 deletions luaui/Widgets/gui_options.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4597,6 +4597,13 @@ function init()
saveOptionValue('SmartSelect', 'smartselect', 'setIncludeBuilders', { 'includeBuilders' }, value)
end,
},
{ id = "smartselect_includeantinuke", group = "game", category = types.basic, name = widgetOptionColor .. " " .. Spring.I18N('ui.settings.option.smartselect_includeantinuke'), type = "bool", value = false, description = Spring.I18N('ui.settings.option.smartselect_includeantinuke_descr'),
onload = function(i)
end,
onchange = function(i, value)
saveOptionValue('SmartSelect', 'smartselect', 'setIncludeAntinuke', { 'includeAntinuke' }, value)
end,
},


{ id = "prioconturrets", group = "game", category = types.basic, widget = "Priority Construction Turrets", name = Spring.I18N('ui.settings.option.prioconturrets'), type = "bool", value = GetWidgetToggleValue("Priority Construction Turrets"), description = Spring.I18N('ui.settings.option.prioconturrets_descr') },
Expand Down Expand Up @@ -6417,9 +6424,11 @@ function init()
if WG['smartselect'] == nil then
options[getOptionByID('smartselect_includebuildings')] = nil
options[getOptionByID('smartselect_includebuilders')] = nil
options[getOptionByID('smartselect_includeantinuke')] = nil
else
options[getOptionByID('smartselect_includebuildings')].value = WG['smartselect'].getIncludeBuildings()
options[getOptionByID('smartselect_includebuilders')].value = WG['smartselect'].getIncludeBuilders()
options[getOptionByID('smartselect_includeantinuke')].value = WG['smartselect'].getIncludeAntinuke()
end

if WG['snow'] ~= nil and WG['snow'].getSnowMap ~= nil then
Expand Down
20 changes: 17 additions & 3 deletions luaui/Widgets/unit_smart_select.lua
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ local referenceX, referenceY
local selectBuildingsWithMobile = false -- whether to select buildings when mobile units are inside selection rectangle
local includeNanosAsMobile = true
local includeBuilders = false
local includeAntinuke = false

-- selection modifiers
local mods = {
Expand Down Expand Up @@ -78,6 +79,7 @@ local combatFilter = {}
local builderFilter = {}
local buildingFilter = {}
local mobileFilter = {}
local antinukeFilter = {}
local customFilter = {}

for udid, udef in pairs(UnitDefs) do
Expand All @@ -89,6 +91,7 @@ for udid, udef in pairs(UnitDefs) do
local builder = (udef.canReclaim and udef.reclaimSpeed > 0) or (udef.canResurrect and udef.resurrectSpeed > 0) or (udef.canRepair and udef.repairSpeed > 0) or (udef.buildOptions and udef.buildOptions[1])
local building = (isMobile == false)
local combat = (not builder) and isMobile and (#udef.weapons > 0)
local antinuke = udef.customParams and udef.customParams.unitgroup == "antinuke"

if string.find(udef.name, 'armspid') or string.find(udef.name, 'leginfestor') then
builder = false
Expand All @@ -97,6 +100,7 @@ for udid, udef in pairs(UnitDefs) do
builderFilter[udid] = builder
buildingFilter[udid] = building
mobileFilter[udid] = isMobile
antinukeFilter[udid] = antinuke
end

local dualScreen
Expand Down Expand Up @@ -375,7 +379,7 @@ function widget:Update(dt)
uid = mouseSelection[i]
udid = spGetUnitDefID(uid)
if buildingFilter[udid] == false then
if includeBuilders or not builderFilter[udid] then
if (includeBuilders or not builderFilter[udid]) and (includeAntinuke or not antinukeFilter[udid]) then
tmp[#tmp + 1] = uid
else
tmp2[#tmp2 + 1] = uid
Expand Down Expand Up @@ -592,7 +596,7 @@ function widget:Initialize()
uid = mouseSelection[i]
udid = spGetUnitDefID(uid)
if buildingFilter[udid] == false then
if includeBuilders or not builderFilter[udid] then
if (includeBuilders or not builderFilter[udid]) and (includeAntinuke or not antinukeFilter[udid]) then
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't even merged and has already set a bad precedent (see #6309), but this would've been fine in isolation so let's let it be.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe instead of checking if this and if this and if this, make a table of all exclusions and have a single key lookup?

Copy link

@GTGalaxi GTGalaxi Nov 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just commented on my PR but will put here too, happy to refactor this if preferred before merging future tech debt 😅

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure! Steal whatever code you need I'll close this one. Marking as draft for now.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have included these in my PR now, thanks @SethDGamre ❤️

tmp[#tmp + 1] = uid
else
tmp2[#tmp2 + 1] = uid
Expand Down Expand Up @@ -656,6 +660,12 @@ function widget:Initialize()
WG['smartselect'].setIncludeBuilders = function(value)
includeBuilders = value
end
WG['smartselect'].getIncludeAntinuke = function()
return includeAntinuke
end
WG['smartselect'].setIncludeAntinuke = function(value)
includeAntinuke = value
end

widget:ViewResize()
end
Expand All @@ -664,7 +674,8 @@ function widget:GetConfigData()
return {
selectBuildingsWithMobile = selectBuildingsWithMobile,
includeNanosAsMobile = includeNanosAsMobile,
includeBuilders = includeBuilders
includeBuilders = includeBuilders,
includeAntinuke = includeAntinuke
}
end

Expand All @@ -678,4 +689,7 @@ function widget:SetConfigData(data)
if data.includeBuilders ~= nil then
includeBuilders = data.includeBuilders
end
if data.includeAntinuke ~= nil then
includeAntinuke = data.includeAntinuke
end
end
Loading