📄 gui_selbuttons.lua
字号:
-------------------------------------------------------------------------------------------------------------------------------------------------------------------- file: gui_selbuttons.lua-- brief: adds a selected units button control panel-- author: Dave Rodgers---- Copyright (C) 2007.-- Licensed under the terms of the GNU GPL, v2 or later.------------------------------------------------------------------------------------------------------------------------------------------------------------------function widget:GetInfo() return { name = "SelectionButtons", desc = "Buttons for the current selection (incomplete)", author = "trepan", date = "Jan 8, 2007", license = "GNU GPL, v2 or later", layer = 0, enabled = false -- loaded by default? }end------------------------------------------------------------------------------------------------------------------------------------------------------------------ Automatically generated local definitionslocal GL_DEPTH_BUFFER_BIT = GL.DEPTH_BUFFER_BITlocal GL_FILL = GL.FILLlocal GL_FRONT_AND_BACK = GL.FRONT_AND_BACKlocal GL_LINE = GL.LINElocal GL_LINE_LOOP = GL.LINE_LOOPlocal GL_ONE = GL.ONElocal GL_ONE_MINUS_SRC_ALPHA = GL.ONE_MINUS_SRC_ALPHAlocal GL_SRC_ALPHA = GL.SRC_ALPHAlocal glBeginEnd = gl.BeginEndlocal glBlending = gl.Blendinglocal glClear = gl.Clearlocal glColor = gl.Colorlocal glDepthMask = gl.DepthMasklocal glDepthTest = gl.DepthTestlocal glLighting = gl.Lightinglocal glLineWidth = gl.LineWidthlocal glMaterial = gl.Materiallocal glPolygonMode = gl.PolygonModelocal glPolygonOffset = gl.PolygonOffsetlocal glPopMatrix = gl.PopMatrixlocal glPushMatrix = gl.PushMatrixlocal glRect = gl.Rectlocal glRotate = gl.Rotatelocal glScale = gl.Scalelocal glScissor = gl.Scissorlocal glTexRect = gl.TexRectlocal glText = gl.Textlocal glTexture = gl.Texturelocal glTranslate = gl.Translatelocal glUnitDef = gl.UnitDeflocal glUnitShape = gl.UnitShapelocal glVertex = gl.Vertexlocal spGetModKeyState = Spring.GetModKeyStatelocal spGetMouseState = Spring.GetMouseStatelocal spGetMyTeamID = Spring.GetMyTeamIDlocal spGetSelectedUnits = Spring.GetSelectedUnitslocal spGetSelectedUnitsCounts = Spring.GetSelectedUnitsCountslocal spGetSelectedUnitsSorted = Spring.GetSelectedUnitsSortedlocal spGetTeamUnitsSorted = Spring.GetTeamUnitsSortedlocal spGetUnitDefDimensions = Spring.GetUnitDefDimensionslocal spSelectUnitArray = Spring.SelectUnitArraylocal spSelectUnitMap = Spring.SelectUnitMaplocal spSendCommands = Spring.SendCommands--------------------------------------------------------------------------------------------------------------------------------------------------------------include("colors.h.lua")local vsx, vsy = widgetHandler:GetViewSizes()function widget:ViewResize(viewSizeX, viewSizeY) vsx = viewSizeX vsy = viewSizeYend------------------------------------------------------------------------------------------------------------------------------------------------------------------ Selection Icons (rough around the edges)--local useModels = falselocal unitTypes = 0local countsTable = {}local activePress = falselocal mouseIcon = -1local currentDef = nillocal iconSizeX = math.floor(useModels and 80 or 64)local iconSizeY = math.floor(iconSizeX * 0.75)local fontSize = iconSizeY * 0.25local rectMinX = 0local rectMaxX = 0local rectMinY = 0local rectMaxY = 0--------------------------------------------------------------------------------------------------------------------------------------------------------------function widget:DrawScreen() unitCounts = spGetSelectedUnitsCounts() unitTypes = unitCounts.n; if (unitTypes <= 0) then countsTable = {} activePress = false currentDef = nil return end SetupDimensions(unitTypes) -- unit model rendering uses the depth-buffer glClear(GL_DEPTH_BUFFER_BIT) local x,y,lb,mb,rb = spGetMouseState() local mouseIcon = MouseOverIcon(x, y) -- draw the buildpics unitCounts.n = nil local icon = 0 for udid,count in pairs(unitCounts) do if (useModels) then DrawUnitDefModel(udid, icon, count) else DrawUnitDefTexture(udid, icon, count) end if (icon == mouseIcon) then currentDef = UnitDefs[udid] end icon = icon + 1 end -- draw the highlights if (not widgetHandler:InTweakMode() and (mouseIcon >= 0)) then if (lb or mb or rb) then DrawIconQuad(mouseIcon, { 1, 0, 0, 0.333 }) -- red highlight else DrawIconQuad(mouseIcon, { 0, 0, 1, 0.333 }) -- blue highlight end endendfunction SetupDimensions(count) local xmid = vsx * 0.5 local width = math.floor(iconSizeX * count) rectMinX = math.floor(xmid - (0.5 * width)) rectMaxX = math.floor(xmid + (0.5 * width)) rectMinY = math.floor(0) rectMaxY = math.floor(rectMinY + iconSizeY)endfunction CenterUnitDef(unitDefID) local ud = UnitDefs[unitDefID] if (not ud) then return end if (not ud.dimensions) then ud.dimensions = spGetUnitDefDimensions(unitDefID) end if (not ud.dimensions) then return end local d = ud.dimensions local xSize = (d.maxx - d.minx) local ySize = (d.maxy - d.miny) local zSize = (d.maxz - d.minz) local hSize -- maximum horizontal dimension if (xSize > zSize) then hSize = xSize else hSize = zSize end -- aspect ratios local mAspect = hSize / ySize local vAspect = iconSizeX / iconSizeY -- scale the unit to the box (maxspect) local scale if (mAspect > vAspect) then scale = (iconSizeX / hSize) else scale = (iconSizeY / ySize) end scale = scale * 0.8 glScale(scale, scale, scale) -- translate to the unit's midpoint local xMid = 0.5 * (d.maxx + d.minx) local yMid = 0.5 * (d.maxy + d.miny) local zMid = 0.5 * (d.maxz + d.minz) glTranslate(-xMid, -yMid, -zMid)endlocal function SetupModelDrawing() glDepthTest(true) glDepthMask(true) glLighting(true) glBlending(false) glMaterial({ ambient = { 0.2, 0.2, 0.2, 1.0 }, diffuse = { 1.0, 1.0, 1.0, 1.0 }, emission = { 0.0, 0.0, 0.0, 1.0 }, specular = { 0.2, 0.2, 0.2, 1.0 }, shininess = 16.0 })endlocal function RevertModelDrawing() glBlending(true) glLighting(false) glDepthMask(false) glDepthTest(false)endlocal function SetupBackgroundColor(ud) local alpha = 0.95 if (ud.canFly) then glColor(0.5, 0.5, 0.0, alpha) elseif (ud.floater) then glColor(0.0, 0.0, 0.5, alpha) elseif (ud.builder) then glColor(0.0, 0.5, 0.0, alpha) else glColor(.5, .5, .5, alpha) endendfunction DrawUnitDefModel(unitDefID, iconPos, count) local xmin = math.floor(rectMinX + (iconSizeX * iconPos)) local xmax = xmin + iconSizeX if ((xmax < 0) or (xmin > vsx)) then return end -- bail local ymin = rectMinY local ymax = rectMaxY local xmid = (xmin + xmax) * 0.5 local ymid = (ymin + ymax) * 0.5 local ud = UnitDefs[unitDefID] -- draw background quad-- glColor(0.3, 0.3, 0.3, 1.0)-- glTexture('#'..unitDefID) glTexture(false) SetupBackgroundColor(ud) glRect(xmin + 1, ymin + 1, xmax, ymax) -- draw the 3D unit SetupModelDrawing() glPushMatrix() glScissor(xmin, ymin, xmax - xmin, ymax - ymin) glTranslate(xmid, ymid, 0) glRotate(15.0, 1, 0, 0) local timer = 1.5 * widgetHandler:GetHourTimer() glRotate(math.cos(0.5 * math.pi * timer) * 60.0, 0, 1, 0) CenterUnitDef(unitDefID) local scribe = false if (scribe) then glLighting(false) glColor(0,0,0,1) end glUnitShape(unitDefID, spGetMyTeamID()) if (scribe) then-- glLineWidth(0.1) glLighting(false) glDepthMask(false) glColor(1,1,1,1) glPolygonOffset(-4, -4) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) glUnitDef(unitDefID, spGetMyTeamID()) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) glPolygonOffset(false)-- glLineWidth(1.0) end glScissor(false) glPopMatrix() RevertModelDrawing() -- draw the count text glText(count, (xmin + xmax) * 0.5, ymax + 2, fontSize, "oc") -- draw the border (note the half pixel shift for drawing lines) glColor(1, 1, 1) glBeginEnd(GL_LINE_LOOP, function() glVertex(xmin + 0.5, ymin + 0.5) glVertex(xmax + 0.5, ymin + 0.5) glVertex(xmax + 0.5, ymax + 0.5) glVertex(xmin + 0.5, ymax + 0.5) end)endfunction DrawUnitDefTexture(unitDefID, iconPos, count) local xmin = math.floor(rectMinX + (iconSizeX * iconPos)) local xmax = xmin + iconSizeX if ((xmax < 0) or (xmin > vsx)) then return end -- bail local ymin = rectMinY local ymax = rectMaxY local xmid = (xmin + xmax) * 0.5 local ymid = (ymin + ymax) * 0.5 local ud = UnitDefs[unitDefID] glColor(1, 1, 1) glTexture('#' .. unitDefID) glTexRect(xmin, ymin, xmax, ymax) glTexture(false) -- draw the count text glText(count, (xmin + xmax) * 0.5, ymax + 2, fontSize, "oc") -- draw the border (note the half pixel shift for drawing lines) glBeginEnd(GL_LINE_LOOP, function() glVertex(xmin + 0.5, ymin + 0.5) glVertex(xmax + 0.5, ymin + 0.5) glVertex(xmax + 0.5, ymax + 0.5) glVertex(xmin + 0.5, ymax + 0.5) end)endfunction DrawIconQuad(iconPos, color) local xmin = rectMinX + (iconSizeX * iconPos) local xmax = xmin + iconSizeX local ymin = rectMinY local ymax = rectMaxY glColor(color) glBlending(GL_SRC_ALPHA, GL_ONE) glRect(xmin, ymin, xmax, ymax) glBlending(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)end--------------------------------------------------------------------------------------------------------------------------------------------------------------function widget:MousePress(x, y, button) mouseIcon = MouseOverIcon(x, y) activePress = (mouseIcon >= 0) return activePressend-------------------------------------------------------------------------------local function LeftMouseButton(unitDefID, unitTable) local alt, ctrl, meta, shift = spGetModKeyState() if (not ctrl) then -- select units of icon type if (alt or meta) then spSelectUnitArray({ unitTable[1] }) -- only 1 else spSelectUnitArray(unitTable) end else -- select all units of the icon type local sorted = spGetTeamUnitsSorted(spGetMyTeamID()) local units = sorted[unitDefID] if (units) then spSelectUnitArray(units, shift) end endendlocal function MiddleMouseButton(unitDefID, unitTable) local alt, ctrl, meta, shift = spGetModKeyState() -- center the view if (ctrl) then -- center the view on the entire selection spSendCommands({"viewselection"}) else -- center the view on this type on unit local selUnits = spGetSelectedUnits() spSelectUnitArray(unitTable) spSendCommands({"viewselection"}) spSelectUnitArray(selUnits) endendlocal function RightMouseButton(unitDefID, unitTable) local alt, ctrl, meta, shift = spGetModKeyState() -- remove selected units of icon type local selUnits = spGetSelectedUnits() local map = {} for _,uid in ipairs(selUnits) do map[uid] = true end for _,uid in ipairs(unitTable) do map[uid] = nil if (ctrl) then break end -- only remove 1 unit end spSelectUnitMap(map)end-------------------------------------------------------------------------------function widget:MouseRelease(x, y, button) if (not activePress) then return -1 end activePress = false local icon = MouseOverIcon(x, y) local units = spGetSelectedUnitsSorted() if (units.n ~= unitTypes) then return -1 -- discard this click end units.n = nil local unitDefID = -1 local unitTable = nil local index = 0 for udid,uTable in pairs(units) do if (index == icon) then unitDefID = udid unitTable = uTable break end index = index + 1 end if (unitTable == nil) then return -1 end local alt, ctrl, meta, shift = spGetModKeyState() if (button == 1) then LeftMouseButton(unitDefID, unitTable) elseif (button == 2) then MiddleMouseButton(unitDefID, unitTable) elseif (button == 3) then RightMouseButton(unitDefID, unitTable) end return -1endfunction MouseOverIcon(x, y) if (unitTypes <= 0) then return -1 end if (x < rectMinX) then return -1 end if (x > rectMaxX) then return -1 end if (y < rectMinY) then return -1 end if (y > rectMaxY) then return -1 end local icon = math.floor((x - rectMinX) / iconSizeX) -- clamp the icon range if (icon < 0) then icon = 0 end if (icon >= unitTypes) then icon = (unitTypes - 1) end return iconend-------------------------------------------------------------------------------function widget:IsAbove(x, y) local icon = MouseOverIcon(x, y) if (icon < 0) then return false end return trueendfunction widget:GetTooltip(x, y) local ud = currentDef if (not ud) then return '' end return ud.humanName .. ' - ' .. ud.tooltipend--------------------------------------------------------------------------------------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -