Guest User

Untitled

a guest
Apr 25th, 2018
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 14.49 KB | None | 0 0
  1. function widget:GetInfo()
  2.   return {
  3.     name      = "1944 Selection Buttons",
  4.     desc      = "Buttons for the current selection or transport passengers",
  5.     author    = "trepan (D. Rodgers), edited for S44 by FLOZi (C. Lawrence)",
  6.     date      = "Jan 8, 2007",
  7.     license   = "GNU GPL, v2 or later",
  8.     layer     = 0,
  9.     enabled   = true  --  loaded by default?
  10.   }
  11. end
  12.  
  13. --------------------------------------------------------------------------------
  14. --------------------------------------------------------------------------------
  15.  
  16. -- localisations
  17. -- OpenGL
  18. local glBeginEnd               = gl.BeginEnd
  19. local glBlending               = gl.Blending
  20. local glClear                  = gl.Clear
  21. local glColor                  = gl.Color
  22. local glDepthMask              = gl.DepthMask
  23. local glDepthTest              = gl.DepthTest
  24. local glLighting               = gl.Lighting
  25. local glLineWidth              = gl.LineWidth
  26. local glMaterial               = gl.Material
  27. local glPolygonMode            = gl.PolygonMode
  28. local glPolygonOffset          = gl.PolygonOffset
  29. local glPopMatrix              = gl.PopMatrix
  30. local glPushMatrix             = gl.PushMatrix
  31. local glRect                   = gl.Rect
  32. local glRotate                 = gl.Rotate
  33. local glScale                  = gl.Scale
  34. local glScissor                = gl.Scissor
  35. local glTexRect                = gl.TexRect
  36. local glText                   = gl.Text
  37. local glTexture                = gl.Texture
  38. local glTranslate              = gl.Translate
  39. local glUnitDef                = gl.UnitDef
  40. local glUnitShape              = gl.UnitShape
  41. local glVertex                 = gl.Vertex
  42.  
  43. -- Synced Read
  44. local spGetTeamUnitsSorted     = Spring.GetTeamUnitsSorted
  45. local spGetUnitDefDimensions   = Spring.GetUnitDefDimensions
  46. local spGetUnitDefID           = Spring.GetUnitDefID
  47. local spGetUnitIsTransporting  = Spring.GetUnitIsTransporting
  48.  
  49. -- Unsynced Read
  50. local spGetModKeyState         = Spring.GetModKeyState
  51. local spGetMouseState          = Spring.GetMouseState
  52. local spGetMyTeamID            = Spring.GetMyTeamID
  53. local spGetSelectedUnits       = Spring.GetSelectedUnits
  54. local spGetSelectedUnitsCounts = Spring.GetSelectedUnitsCounts
  55. local spGetSelectedUnitsSorted = Spring.GetSelectedUnitsSorted
  56.  
  57. -- Unsynced Ctrl
  58. local spSelectUnitArray        = Spring.SelectUnitArray
  59. local spSelectUnitMap          = Spring.SelectUnitMap
  60. local spSendCommands           = Spring.SendCommands
  61.  
  62. -- Constants
  63. local GL_DEPTH_BUFFER_BIT      = GL.DEPTH_BUFFER_BIT
  64. local GL_FILL                  = GL.FILL
  65. local GL_FRONT_AND_BACK        = GL.FRONT_AND_BACK
  66. local GL_LINE                  = GL.LINE
  67. local GL_LINE_LOOP             = GL.LINE_LOOP
  68. local GL_ONE                   = GL.ONE
  69. local GL_ONE_MINUS_SRC_ALPHA   = GL.ONE_MINUS_SRC_ALPHA
  70. local GL_SRC_ALPHA             = GL.SRC_ALPHA
  71.  
  72. -- Variables
  73. include("colors.h.lua")
  74.  
  75. local vsx, vsy = widgetHandler:GetViewSizes()
  76.  
  77. local useModels = false
  78.  
  79. local unitTypes = 0
  80. local countsTable = {}
  81. local activePress = false
  82. local mouseIcon = -1
  83. local currentDef = nil
  84.  
  85. local iconSizeX = math.floor(useModels and 80 or 640)
  86. local iconSizeY = math.floor(iconSizeX * 1.0)
  87. local fontSize = iconSizeY * 0.25
  88.  
  89. local rectMinX = 0
  90. local rectMaxX = 0
  91. local rectMinY = 0
  92. local rectMaxY = 0
  93.  
  94.  
  95. -- Local Functions
  96. local function SortedUnits()
  97.   local selUnits = spGetSelectedUnits()
  98.   if (#selUnits ~= 1) then
  99.     return spGetSelectedUnitsCounts() --{ n = 0 }
  100.   end
  101.   local transID = selUnits[1]
  102.   local units = spGetUnitIsTransporting(transID)
  103.   if (units == nil) then
  104.     return spGetSelectedUnitsCounts() --{ n = 0 }
  105.   end
  106.   local typed = {}
  107.   local typeCount = 0
  108.   for _,uid in ipairs(units) do
  109.     local udid = spGetUnitDefID(uid)
  110.     if (udid) then
  111.       if (typed[udid] == nil) then
  112.         typed[udid] = 1
  113.         typeCount = typeCount + 1
  114.       else
  115.         typed[udid] = typed[udid] + 1
  116.       end
  117.     end
  118.   end
  119.   typed.n = typeCount
  120.   return typed, transID
  121. end
  122.  
  123. -- Setup Functions
  124. function SetupDimensions(count)
  125.   local xmid = vsx * 0.5
  126.   local width = math.floor(iconSizeX * count)
  127.   rectMinX = math.floor(xmid - (0.5 * width))
  128.   rectMaxX = math.floor(xmid + (0.5 * width))
  129.   rectMinY = math.floor(0) --floor(0 + iconSizeY * 2)
  130.   rectMaxY = math.floor(rectMinY + iconSizeY)
  131. end
  132.  
  133.  
  134. function CenterUnitDef(unitDefID)
  135.   local ud = UnitDefs[unitDefID]
  136.   if (not ud) then
  137.     return
  138.   end
  139.   if (not ud.dimensions) then
  140.     ud.dimensions = spGetUnitDefDimensions(unitDefID)
  141.   end
  142.   if (not ud.dimensions) then
  143.     return
  144.   end
  145.    
  146.   local d = ud.dimensions
  147.   local xSize = (d.maxx - d.minx)
  148.   local ySize = (d.maxy - d.miny)
  149.   local zSize = (d.maxz - d.minz)
  150.  
  151.   local hSize -- maximum horizontal dimension
  152.   if (xSize > zSize) then hSize = xSize else hSize = zSize end
  153.  
  154.   -- aspect ratios
  155.   local mAspect = hSize / ySize
  156.   local vAspect = iconSizeX / iconSizeY
  157.  
  158.   -- scale the unit to the box (maxspect)
  159.   local scale
  160.   if (mAspect > vAspect) then
  161.     scale = (iconSizeX / hSize)
  162.   else
  163.     scale = (iconSizeY / ySize)
  164.   end
  165.   scale = scale * 0.8
  166.   glScale(scale, scale, scale)
  167.  
  168.   -- translate to the unit's midpoint
  169.   local xMid = 0.5 * (d.maxx + d.minx)
  170.   local yMid = 0.5 * (d.maxy + d.miny)
  171.   local zMid = 0.5 * (d.maxz + d.minz)
  172.   glTranslate(-xMid, -yMid, -zMid)
  173. end
  174.  
  175.  
  176. local function SetupModelDrawing()
  177.   glDepthTest(true)
  178.   glDepthMask(true)
  179.   glLighting(true)
  180.   glBlending(false)
  181.   glMaterial({
  182.     ambient  = { 0.2, 0.2, 0.2, 1.0 },
  183.     diffuse  = { 1.0, 1.0, 1.0, 1.0 },
  184.     emission = { 0.0, 0.0, 0.0, 1.0 },
  185.     specular = { 0.2, 0.2, 0.2, 1.0 },
  186.     shininess = 16.0
  187.   })
  188. end
  189.  
  190.  
  191. local function RevertModelDrawing()
  192.   glBlending(true)
  193.   glLighting(false)
  194.   glDepthMask(false)
  195.   glDepthTest(false)
  196. end
  197.  
  198.  
  199. local function SetupBackgroundColor(ud)
  200.   local alpha = 0.95
  201.   if (ud.canFly) then
  202.     glColor(0.5, 0.5, 0.0, alpha)
  203.   elseif (ud.floater) then
  204.     glColor(0.0, 0.0, 0.5, alpha)
  205.   elseif (ud.builder) then
  206.     glColor(0.0, 0.5, 0.0, alpha)
  207.   else
  208.     glColor(.5, .5, .5, alpha)
  209.   end
  210. end
  211.  
  212. -- Draw Functions
  213. function DrawUnitDefModel(unitDefID, iconPos, count)
  214.   local xmin = math.floor(rectMinX + (iconSizeX * iconPos))
  215.   local xmax = xmin + iconSizeX
  216.   if ((xmax < 0) or (xmin > vsx)) then return end  -- bail
  217.  
  218.   local ymin = rectMinY
  219.   local ymax = rectMaxY
  220.   local xmid = (xmin + xmax) * 0.5
  221.   local ymid = (ymin + ymax) * 0.5
  222.  
  223.   local ud = UnitDefs[unitDefID]
  224.  
  225.   -- draw background quad
  226. --  glColor(0.3, 0.3, 0.3, 1.0)
  227. --  glTexture('#'..unitDefID)
  228.   glTexture(false)
  229.   --SetupBackgroundColor(ud)
  230.   glRect(xmin + 1, ymin + 1, xmax, ymax)
  231.  
  232.  
  233.   -- draw the 3D unit
  234.     --[[SetupModelDrawing()
  235.  
  236.   glPushMatrix()
  237.   glScissor(xmin, ymin, xmax - xmin, ymax - ymin)
  238.   glTranslate(xmid, ymid, 0)
  239.   glRotate(15.0, 1, 0, 0)
  240.   local timer = 1.5 * widgetHandler:GetHourTimer()
  241.   glRotate(math.cos(0.5 * math.pi * timer) * 60.0, 0, 1, 0)
  242.  
  243.   CenterUnitDef(unitDefID)
  244.  
  245.   local scribe = false
  246.   if (scribe) then
  247.     glLighting(false)
  248.     glColor(0,0,0,1)
  249.   end
  250.  
  251.   glUnitShape(unitDefID, spGetMyTeamID())
  252.  
  253.   if (scribe) then
  254. --    glLineWidth(0.1)
  255.     glLighting(false)
  256.     glDepthMask(false)
  257.     glColor(1,1,1,1)
  258.     glPolygonOffset(-4, -4)
  259.     glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
  260.     glUnitDef(unitDefID, spGetMyTeamID())
  261.     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)
  262.     glPolygonOffset(false)
  263. --    glLineWidth(1.0)
  264.   end
  265.  
  266.   glScissor(false)
  267.   glPopMatrix()
  268.  
  269.     RevertModelDrawing()]]
  270.  
  271.   -- draw the count text
  272.   glText(count, (xmin + xmax) * 0.5, ymax + 2, fontSize, "oc")
  273.  
  274.   -- draw the border  (note the half pixel shift for drawing lines)
  275.   glColor(1, 1, 1)
  276.   glBeginEnd(GL_LINE_LOOP, function()
  277.     glVertex(xmin + 0.5, ymin + 0.5)
  278.     glVertex(xmax + 0.5, ymin + 0.5)
  279.     glVertex(xmax + 0.5, ymax + 0.5)
  280.     glVertex(xmin + 0.5, ymax + 0.5)
  281.   end)
  282. end
  283.  
  284.  
  285. function DrawUnitDefTexture(unitDefID, iconPos, count)
  286.   local xmin = math.floor(rectMinX + (iconSizeX * iconPos))
  287.   local xmax = xmin + iconSizeX
  288.   if ((xmax < 0) or (xmin > vsx)) then return end  -- bail
  289.  
  290.   local ymin = rectMinY
  291.   local ymax = rectMaxY
  292.   local xmid = (xmin + xmax) * 0.5
  293.   local ymid = (ymin + ymax) * 0.5
  294.  
  295.   local ud = UnitDefs[unitDefID]
  296.  
  297.   --glColor(1, 1, 1)
  298.   gl.Blending(false)
  299.   glTexture('%' .. unitDefID .. ":0")
  300.   glTexRect(xmin, ymin, xmax, ymax)
  301.   glTexture(false)
  302.  
  303.   -- draw the count text
  304.   glText(count, (xmin + xmax) * 0.5, ymax + 2, fontSize, "oc")
  305.  
  306.   -- draw the border  (note the half pixel shift for drawing lines)
  307.   glBeginEnd(GL_LINE_LOOP, function()
  308.     glVertex(xmin + 0.5, ymin + 0.5)
  309.     glVertex(xmax + 0.5, ymin + 0.5)
  310.     glVertex(xmax + 0.5, ymax + 0.5)
  311.     glVertex(xmin + 0.5, ymax + 0.5)
  312.   end)
  313. end
  314.  
  315.  
  316. function DrawIconQuad(iconPos, color)
  317.   local xmin = rectMinX + (iconSizeX * iconPos)
  318.   local xmax = xmin + iconSizeX
  319.   local ymin = rectMinY
  320.   local ymax = rectMaxY
  321.   glColor(color)
  322.   glBlending(GL_SRC_ALPHA, GL_ONE)
  323.   glRect(xmin, ymin, xmax, ymax)
  324.   glBlending(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
  325. end
  326.  
  327. -- Mouse functions
  328. local function LeftMouseButton(unitDefID, unitTable)
  329.   local alt, ctrl, meta, shift = spGetModKeyState()
  330.   if (not ctrl) then
  331.     -- select units of icon type
  332.     if (alt or meta) then
  333.       spSelectUnitArray({ unitTable[1] })  -- only 1
  334.     else
  335.       spSelectUnitArray(unitTable)
  336.     end
  337.   else
  338.     -- select all units of the icon type
  339.     local sorted = spGetTeamUnitsSorted(spGetMyTeamID())
  340.     local units = sorted[unitDefID]
  341.     if (units) then
  342.       spSelectUnitArray(units, shift)
  343.     end
  344.   end
  345. end
  346.  
  347.  
  348. local function MiddleMouseButton(unitDefID, unitTable)
  349.   local alt, ctrl, meta, shift = spGetModKeyState()
  350.   -- center the view
  351.   if (ctrl) then
  352.     -- center the view on the entire selection
  353.     spSendCommands({"viewselection"})
  354.   else
  355.     -- center the view on this type on unit
  356.     local selUnits = spGetSelectedUnits()
  357.     spSelectUnitArray(unitTable)
  358.     spSendCommands({"viewselection"})
  359.     spSelectUnitArray(selUnits)
  360.   end
  361. end
  362.  
  363.  
  364. local function RightMouseButton(unitDefID, unitTable)
  365.   local alt, ctrl, meta, shift = spGetModKeyState()
  366.   -- remove selected units of icon type
  367.   local selUnits = spGetSelectedUnits()
  368.   local map = {}
  369.   for _,uid in ipairs(selUnits) do map[uid] = true end
  370.   for _,uid in ipairs(unitTable) do
  371.     map[uid] = nil
  372.     if (ctrl) then break end -- only remove 1 unit
  373.   end
  374.   spSelectUnitMap(map)
  375. end
  376.  
  377.  
  378. function MouseOverIcon(x, y)
  379.   if (unitTypes <= 0) then return -1 end
  380.   if (x < rectMinX)   then return -1 end
  381.   if (x > rectMaxX)   then return -1 end
  382.   if (y < rectMinY)   then return -1 end
  383.   if (y > rectMaxY)   then return -1 end
  384.  
  385.   local icon = math.floor((x - rectMinX) / iconSizeX)
  386.   -- clamp the icon range
  387.   if (icon < 0) then
  388.     icon = 0
  389.   end
  390.   if (icon >= unitTypes) then
  391.     icon = (unitTypes - 1)
  392.   end
  393.   return icon
  394. end
  395.  
  396.  
  397. -- Call Ins
  398.  
  399. function widget:DrawScreen()
  400.   unitCounts, transID = SortedUnits()--spGetSelectedUnitsCounts()
  401.   unitTypes = unitCounts.n;
  402.   if transID then unitTypes = unitTypes + 1 end
  403.   if (unitTypes <= 0) then
  404.     countsTable = {}
  405.     activePress = false
  406.     currentDef  = nil
  407.     return
  408.   end
  409.  
  410.   SetupDimensions(unitTypes)
  411.  
  412.   -- unit model rendering uses the depth-buffer
  413.   glClear(GL_DEPTH_BUFFER_BIT)
  414.  
  415.   local x,y,lb,mb,rb = spGetMouseState()
  416.   local mouseIcon = MouseOverIcon(x, y)
  417.  
  418.   -- draw the buildpics
  419.   unitCounts.n = nil  
  420.   local icon = 0
  421.   -- draw transporter first
  422.   if transID then
  423.     local udid = spGetUnitDefID(transID)
  424.     if (useModels) then
  425.       DrawUnitDefModel(udid, icon, 1)
  426.     else
  427.       DrawUnitDefTexture(udid, icon, 1)
  428.     end
  429.    
  430.     if (icon == mouseIcon) then
  431.       currentDef = UnitDefs[udid]
  432.     end
  433.     icon = icon + 1
  434.     glColor(0.5, 0.5, 0.5, 0.8)
  435.   else -- This block is all rather ugly
  436.     local transCount = {}
  437.     local units = spGetSelectedUnits()
  438.     for _,uid in ipairs(units) do
  439.       local udid = spGetUnitDefID(uid)
  440.       if (udid) then
  441.         local transported = spGetUnitIsTransporting(uid)
  442.         if transported then
  443.             if not transCount[udid] then
  444.               transCount[udid] = #transported
  445.             else
  446.               transCount[udid] = transCount[udid] + #transported
  447.             end
  448.         end
  449.       end
  450.     end
  451.     for udid,count in pairs(unitCounts) do
  452.       if transCount[udid] and transCount[udid] > 0 then
  453.         unitCounts[udid] = count .. "(+" .. transCount[udid] .. ")"
  454.       end
  455.     end
  456.   end
  457.   for udid,count in pairs(unitCounts) do
  458.     if (useModels) then
  459.       DrawUnitDefModel(udid, icon, count)
  460.     else
  461.       DrawUnitDefTexture(udid, icon, count)
  462.     end
  463.      
  464.     if (icon == mouseIcon) then
  465.       currentDef = UnitDefs[udid]
  466.     end
  467.     icon = icon + 1
  468.   end
  469.   glColor(1,1,1,1)
  470.   -- draw the highlights
  471.   if (not widgetHandler:InTweakMode() and (mouseIcon >= 0)) then
  472.     if (lb or mb or rb) then
  473.       DrawIconQuad(mouseIcon, { 1, 0, 0, 0.333 })  --  red highlight
  474.     else
  475.       DrawIconQuad(mouseIcon, { 0, 0, 1, 0.333 })  --  blue highlight
  476.     end
  477.   end
  478. end
  479.  
  480.  
  481. function widget:IsAbove(x, y)
  482.   local icon = MouseOverIcon(x, y)
  483.   if (icon < 0) then
  484.     return false
  485.   end
  486.   return true
  487. end
  488.  
  489.  
  490. function widget:GetTooltip(x, y)
  491.   local ud = currentDef
  492.   if (not ud) then
  493.     return ''
  494.   end
  495.   return ud.humanName .. ' - ' .. ud.tooltip
  496. end
  497.  
  498.  
  499. function widget:MousePress(x, y, button)
  500.   mouseIcon = MouseOverIcon(x, y)
  501.   activePress = (mouseIcon >= 0)
  502.   return activePress
  503. end
  504.  
  505.  
  506. function widget:MouseRelease(x, y, button)
  507.   if (not activePress) then
  508.     return -1
  509.   end
  510.   activePress = false
  511.   local icon = MouseOverIcon(x, y)
  512.  
  513.   local units = spGetSelectedUnitsSorted()
  514.   if (units.n ~= unitTypes) then
  515.     return -1  -- discard this click
  516.   end
  517.   units.n = nil
  518.  
  519.   local unitDefID = -1
  520.   local unitTable = nil
  521.   local index = 0
  522.   for udid,uTable in pairs(units) do
  523.     if (index == icon) then
  524.       unitDefID = udid
  525.       unitTable = uTable
  526.       break
  527.     end
  528.     index = index + 1
  529.   end
  530.   if (unitTable == nil) then
  531.     return -1
  532.   end
  533.  
  534.   local alt, ctrl, meta, shift = spGetModKeyState()
  535.  
  536.   if (button == 1) then
  537.     LeftMouseButton(unitDefID, unitTable)
  538.   elseif (button == 2) then
  539.     MiddleMouseButton(unitDefID, unitTable)
  540.   elseif (button == 3) then
  541.     RightMouseButton(unitDefID, unitTable)
  542.   end
  543.  
  544.   return -1
  545. end
  546.  
  547.  
  548. function widget:ViewResize(viewSizeX, viewSizeY)
  549.   vsx = viewSizeX
  550.   vsy = viewSizeY
  551. end
  552. -------------------------------------------------------------------------------
  553. -------------------------------------------------------------------------------
Add Comment
Please, Sign In to add comment