Advertisement
Guest User

nixtux

a guest
Mar 16th, 2012
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 10.83 KB | None | 0 0
  1.  
  2. function widget:GetInfo()
  3.     return {
  4.         name      = "Unit Stats",
  5.         desc      = "Shows detailed unit stats",
  6.         author    = "Niobium ,Nixtux",
  7.         date      = "Jan 11, 2009",
  8.         version   = 1.3,
  9.         license   = "GNU GPL, v2 or later",
  10.         layer     = 6,
  11.         enabled   = true,  --  loaded by default?
  12.         handler   = true
  13.     }
  14. end
  15.  
  16. ---- v 1.3 changes
  17. -- Updated for engine changes in 0.87
  18.  
  19. ---- v1.2 changes
  20. -- Fixed drains for burst weapons (Removed 0.125 minimum)
  21. -- Show remaining costs for units under construction
  22.  
  23. ---- v1.1 changes
  24. -- Added extra text to help explain numbers
  25. -- Added grouping of duplicate weapons
  26. -- Added sonar radius
  27. -- Fixed radar/jammer detection
  28. -- Fixed stockpiling unit drains
  29. -- Fixed turnrate/acceleration scale
  30. -- Fixed very low reload times
  31.  
  32. ------------------------------------------------------------------------------------
  33. -- Globals
  34. ------------------------------------------------------------------------------------
  35. local fontSize = 16
  36. local xOffset = 25
  37. local yOffset = 25
  38.  
  39. local cX, cY
  40.  
  41. ------------------------------------------------------------------------------------
  42. -- Speedups
  43. ------------------------------------------------------------------------------------
  44. local white = '\255\255\255\255'
  45. local green = '\255\1\255\1'
  46. local yellow = '\255\255\255\1'
  47. local orange = '\255\255\128\1'
  48. local blue = '\255\128\128\255'
  49.  
  50. local metalColor = '\255\196\196\255' -- Light blue
  51. local energyColor = '\255\255\255\128' -- Light yellow
  52. local buildColor = '\255\128\255\128' -- Light green
  53.  
  54. local max = math.max
  55. local floor = math.floor
  56. local format = string.format
  57. local char = string.char
  58.  
  59. local glColor = gl.Color
  60. local glText = gl.Text
  61.  
  62. local spGetMyTeamID = Spring.GetMyTeamID
  63. local spGetTeamResources = Spring.GetTeamResources
  64. local spGetTeamInfo = Spring.GetTeamInfo
  65. local spGetPlayerInfo = Spring.GetPlayerInfo
  66. local spGetTeamColor = Spring.GetTeamColor
  67.  
  68. local spGetModKeyState = Spring.GetModKeyState
  69. local spGetMouseState = Spring.GetMouseState
  70. local spTraceScreenRay = Spring.TraceScreenRay
  71.  
  72. local spGetUnitDefID = Spring.GetUnitDefID
  73. local spGetUnitExp = Spring.GetUnitExperience
  74. local spGetUnitHealth = Spring.GetUnitHealth
  75. local spGetUnitTeam = Spring.GetUnitTeam
  76. local spGetUnitExperience = Spring.GetUnitExperience
  77. local spGetUnitSensorRadius = Spring.GetUnitSensorRadius
  78.  
  79. local uDefs = UnitDefs
  80. local wDefs = WeaponDefs
  81.  
  82. ------------------------------------------------------------------------------------
  83. -- Functions
  84. ------------------------------------------------------------------------------------
  85. local function DrawText(t1, t2)
  86.     glText(t1, cX, cY, fontSize, "o")
  87.     glText(t2, cX + 60, cY, fontSize, "o")
  88.     cY = cY - fontSize
  89. end
  90.  
  91. local function GetTeamColorCode(teamID)
  92.    
  93.     if not teamID then return "\255\255\255\255" end
  94.    
  95.     local R, G, B = spGetTeamColor(teamID)
  96.    
  97.     if not R then return "\255\255\255\255" end
  98.    
  99.     R = floor(R * 255)
  100.     G = floor(G * 255)
  101.     B = floor(B * 255)
  102.    
  103.     if (R < 11) then R = 11 end -- Note: char(10) terminates string
  104.     if (G < 11) then G = 11 end
  105.     if (B < 11) then B = 11 end
  106.    
  107.     return "\255" .. char(R) .. char(G) .. char(B)
  108. end
  109.  
  110. local function GetTeamName(teamID)
  111.    
  112.     if not teamID then return 'Error:NoTeamID' end
  113.    
  114.     local _, teamLeader = spGetTeamInfo(teamID)
  115.     if not teamLeader then return 'Error:NoLeader' end
  116.    
  117.     local leaderName = spGetPlayerInfo(teamLeader)
  118.     return leaderName or 'Error:NoName'
  119. end
  120.  
  121. ------------------------------------------------------------------------------------
  122. -- Code
  123. ------------------------------------------------------------------------------------
  124. function widget:Initialize()
  125.     local highlightWidget = widgetHandler:FindWidget("HighlightUnit")
  126.     if highlightWidget then
  127.         widgetHandler:RemoveWidgetCallIn("DrawScreen", highlightWidget)
  128.     end
  129. end
  130.  
  131. function widget:Shutdown()
  132.     local highlightWidget = widgetHandler:FindWidget("HighlightUnit")
  133.     if highlightWidget then
  134.         widgetHandler:UpdateWidgetCallIn("DrawScreen", highlightWidget)
  135.     end
  136. end
  137.  
  138. function widget:DrawScreen()
  139.    
  140.     local alt, ctrl, meta, shift = spGetModKeyState()
  141.     if not meta then return end
  142.    
  143.     local mx, my = spGetMouseState()
  144.     local rType, uID = spTraceScreenRay(mx, my)
  145.     if rType ~= 'unit' or not uID then return end
  146.    
  147.     local uDefID = spGetUnitDefID(uID)
  148.     if not uDefID then return end
  149.    
  150.     local uDef = uDefs[uDefID]
  151.     local _, _, _, _, buildProg = spGetUnitHealth(uID)
  152.     local uTeam = spGetUnitTeam(uID)
  153.    
  154.     cX = mx + xOffset
  155.     cY = my + yOffset
  156.     glColor(1.0, 1.0, 1.0, 1.0)
  157.    
  158.     ------------------------------------------------------------------------------------
  159.     -- Owner, unit name, unit ID
  160.     ------------------------------------------------------------------------------------
  161.     glText(GetTeamColorCode(uTeam) .. GetTeamName(uTeam) .. "'s " .. yellow .. uDef.humanName .. white .. " (" .. uDef.name .. ", #" .. uID .. ")", cX, cY, fontSize, "o")
  162.     cY = cY - 2 * fontSize
  163.    
  164.     ------------------------------------------------------------------------------------
  165.     -- Units under construction
  166.     ------------------------------------------------------------------------------------
  167.     if buildProg and buildProg < 1 then
  168.        
  169.         local myTeamID = spGetMyTeamID()
  170.         local mCur, mStor, mPull, mInc, mExp, mShare, mSent, mRec = spGetTeamResources(myTeamID, 'metal')
  171.         local eCur, eStor, ePull, eInc, eExp, eShare, eSent, eRec = spGetTeamResources(myTeamID, 'energy')
  172.        
  173.         local mTotal = uDef.metalCost
  174.         local eTotal = uDef.energyCost
  175.         local buildRem = 1 - buildProg
  176.         local mRem = mTotal * buildRem
  177.         local eRem = eTotal * buildRem
  178.         local mEta = (mRem - mCur) / (mInc + mRec)
  179.         local eEta = (eRem - eCur) / (eInc + eRec)
  180.        
  181.         DrawText("Prog:", format("%d%%", 100 * buildProg))
  182.         DrawText("M:", format("%d / %d (" .. yellow .. "%d" .. white .. ", %ds)", mTotal * buildProg, mTotal, mRem, mEta))
  183.         DrawText("E:", format("%d / %d (" .. yellow .. "%d" .. white .. ", %ds)", eTotal * buildProg, eTotal, eRem, eEta))
  184.         --DrawText("MaxBP:", format(white .. '%d', buildRem * uDef.buildTime / math.max(mEta, eEta)))
  185.         cY = cY - fontSize
  186.     end
  187.    
  188.     ------------------------------------------------------------------------------------
  189.     -- Generic information, cost, move, class
  190.     ------------------------------------------------------------------------------------
  191.     DrawText("Cost:", format(metalColor .. '%d' .. white .. ' / ' ..
  192.                             energyColor .. '%d' .. white .. ' / ' ..
  193.                             buildColor .. '%d', uDef.metalCost, uDef.energyCost, uDef.buildTime)
  194.             )
  195.    
  196.     if not (uDef.isBuilding or uDef.isFactory) then
  197.         DrawText("Move:", format("%.1f / %.1f / %.0f (Speed / Accel / Turn)", uDef.speed, 900 * uDef.maxAcc, 30 * uDef.turnRate * (180 / 32767)))
  198.     end
  199.    
  200.     DrawText("Class:", Game.armorTypes[uDef.armorType or 0] or '???')
  201.    
  202.     if uDef.buildSpeed > 0 then DrawText('Build:', yellow .. uDef.buildSpeed) end
  203.    
  204.     cY = cY - fontSize
  205.    
  206.     ------------------------------------------------------------------------------------
  207.     -- Sensors and Jamming
  208.     ------------------------------------------------------------------------------------
  209.     local losRadius = spGetUnitSensorRadius(uID, 'los') or 0
  210.     local airLosRadius = spGetUnitSensorRadius(uID, 'airLos') or 0
  211.     local radarRadius = spGetUnitSensorRadius(uID, 'radar') or 0
  212.     local sonarRadius = spGetUnitSensorRadius(uID, 'sonar') or 0
  213.     local jammingRadius = spGetUnitSensorRadius(uID, 'radarJammer') or 0
  214.     -- local sonarJammingRadius = spGetUnitSensorRadius(uID, 'sonarJammer')
  215.     local seismicRadius = spGetUnitSensorRadius(uID, 'seismic') or 0
  216.    
  217.     DrawText('Los:', losRadius .. (airLosRadius > losRadius and format(' (AirLos: %d)', airLosRadius) or ''))
  218.    
  219.     if radarRadius   > 0 then DrawText('Radar:', '\255\77\255\77' .. radarRadius) end
  220.     if sonarRadius   > 0 then DrawText('Sonar:', '\255\128\128\255' .. sonarRadius) end
  221.     if jammingRadius > 0 then DrawText('Jam:'  , '\255\255\77\77' .. jammingRadius) end
  222.     if seismicRadius > 0 then DrawText('Seis:' , '\255\255\26\255' .. seismicRadius) end
  223.    
  224.     if uDef.stealth then DrawText("Other:", "Stealth") end
  225.    
  226.     cY = cY - fontSize
  227.    
  228.     ------------------------------------------------------------------------------------
  229.     -- Weapons
  230.     ------------------------------------------------------------------------------------
  231.     --[[
  232.     local uExp = spGetUnitExperience(uID)
  233.     if uExp and (uExp > 0.25) then
  234.         uExp = uExp / (1 + uExp)
  235.         DrawText("Exp:", format("+%d%% damage, +%d%% firerate, +%d%% health", 100 * uExp, 100 / (1 - uExp * 0.4) - 100, 70 * uExp))
  236.         cY = cY - fontSize
  237.     end
  238.     ]]--
  239.    
  240.     local wepCounts = {} -- wepCounts[wepDefID] = #
  241.     local wepsCompact = {} -- uWepsCompact[1..n] = wepDefID
  242.    
  243.     local uWeps = uDef.weapons
  244.     for i = 1, #uWeps do
  245.         local wDefID = uWeps[i].weaponDef
  246.         local wCount = wepCounts[wDefID]
  247.         if wCount then
  248.             wepCounts[wDefID] = wCount + 1
  249.         else
  250.             wepCounts[wDefID] = 1
  251.             wepsCompact[#wepsCompact + 1] = wDefID
  252.         end
  253.     end
  254.    
  255.     for i = 1, #wepsCompact do
  256.        
  257.         local wDefId = wepsCompact[i]
  258.         local uWep = wDefs[wDefId]
  259.        
  260.         if uWep.range > 16 then
  261.            
  262.             local oDmg = uWep.damages[0]
  263.             local oBurst = uWep.salvoSize * uWep.projectiles
  264.             local oRld = uWep.stockpile and uWep.stockpileTime or uWep.reload
  265.             local wepCount = wepCounts[wDefId]
  266.            
  267.             if wepCount > 1 then
  268.                 DrawText("Weap:", format(yellow .. "%dx" .. white .. " %s", wepCount, uWep.type))
  269.             else
  270.                 DrawText("Weap:", uWep.type)
  271.             end
  272.            
  273.             DrawText("Info:", format("%d range, %d aoe, %d%% edge", uWep.range, uWep.damageAreaOfEffect, 100 * uWep.edgeEffectiveness))
  274.            
  275.             local dmgString
  276.             if oBurst > 1 then
  277.                 dmgString = format(yellow .. "%d (x%d)" .. white .. " / " .. yellow .. "%.2f" .. white .. " = " .. yellow .. "%.2f", oDmg, oBurst, oRld, oBurst * oDmg / oRld)
  278.             else
  279.                 dmgString = format(yellow .. "%d" .. white .. " / " .. yellow .. "%.2f" .. white .. " = " .. yellow .. "%.2f", oDmg, oRld, oDmg / oRld)
  280.             end
  281.            
  282.             if wepCount > 1 then
  283.                 dmgString = dmgString .. white .. " (Each)"
  284.             end
  285.            
  286.             DrawText("Dmg:", dmgString)
  287.            
  288.             if uWep.metalCost > 0 or uWep.energyCost > 0 then
  289.                
  290.                 -- Stockpiling weapons are weird
  291.                 -- They take the correct amount of resources overall
  292.                 -- They take the correct amount of time
  293.                 -- They drain (32/30) times more resources than they should (And the listed drain is real, having lower income than listed drain WILL stall you)
  294.                 local drainAdjust = uWep.stockpile and 32/30 or 1
  295.                
  296.                 DrawText('Cost:', format(metalColor .. '%d' .. white .. ', ' ..
  297.                                          energyColor .. '%d' .. white .. ' = ' ..
  298.                                          metalColor .. '-%d' .. white .. ', ' ..
  299.                                          energyColor .. '-%d' .. white .. ' per second',
  300.                                          uWep.metalCost,
  301.                                          uWep.energyCost,
  302.                                          drainAdjust * uWep.metalCost / oRld,
  303.                                          drainAdjust * uWep.energyCost / oRld))
  304.             end
  305.            
  306.             cY = cY - fontSize
  307.         end
  308.     end
  309. end
  310.  
  311. ------------------------------------------------------------------------------------
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement