diff --git a/luaui/Widgets/gui_idle_builders.lua b/luaui/Widgets/gui_idle_builders.lua index 45d48fef667..6eb21f41e08 100644 --- a/luaui/Widgets/gui_idle_builders.lua +++ b/luaui/Widgets/gui_idle_builders.lua @@ -25,6 +25,9 @@ local setHeight = 0.046 local maxIcons = 9 local showRez = true local doUpdateForce = true +local justSelected = false +local listSorted = {} -- listSorted[unitDefID]: set to nil when idle list is updated, set to true when idleList[unitDefID] is sorted +local prevCameraPosition -- {posX, posY, posZ}: camera position for sorting idle units, used to have consistent point of reference when right clicking local leftclick = 'LuaUI/Sounds/buildbar_add.wav' local rightclick = 'LuaUI/Sounds/buildbar_click.wav' @@ -42,12 +45,14 @@ local spGetMouseState = Spring.GetMouseState local spGetUnitCommandCount = Spring.GetUnitCommandCount local spGetFactoryCommands = Spring.GetFactoryCommands local myTeamID = Spring.GetMyTeamID() +local spGetUnitPosition = Spring.GetUnitPosition local floor = math.floor local ceil = math.ceil local min = math.min local max = math.max local math_isInRect = math.isInRect +local math_distance2dSquared = math.distance2dSquared local GL_SRC_ALPHA = GL.SRC_ALPHA local GL_ONE = GL.ONE @@ -294,6 +299,7 @@ local function updateList(force) local prevIdleList = idleList idleList = {} local queue + listSorted = {} for unitID, unitDefID in pairs(unitList) do queue = unitConf[unitDefID] and spGetFactoryCommands(unitID, 0) or spGetUnitCommandCount(unitID, 0) if queue == 0 then @@ -732,12 +738,24 @@ function widget:MousePress(x, y, button) if clicks[unitDefID] then clicks[unitDefID] = clicks[unitDefID] + 1 else - clicks[unitDefID] = 1 + clicks[unitDefID] = 0 end num = (clicks[unitDefID]) % (#idleList[unitDefID]) + 1 end + if not listSorted[unitDefID] then + -- FIXME: should use center of screen rather than camera + local camX, camY, camZ = unpack(prevCameraPosition or {Spring.GetCameraPosition()}) + prevCameraPosition = {camX, camY, camZ} + table.sort(idleList[unitDefID], function (a, b) + local unitAX, _, unitAZ = spGetUnitPosition(a) + local unitBX, _, unitBZ = spGetUnitPosition(b) + return math_distance2dSquared(unitAX, unitAZ, camX, camZ) < math_distance2dSquared(unitBX, unitBZ, camX, camZ) + end) + listSorted[unitDefID] = true + end units = { idleList[unitDefID][num] } end + justSelected = true Spring.SelectUnitArray(units) end if button == 3 then @@ -756,6 +774,13 @@ end function widget:SelectionChanged(sel) selectedUnits = sel or {} + if justSelected then -- ignore selections done by the widget itself + justSelected = false + return + end + prevCameraPosition = nil + listSorted = {} + clicks = {} end