1-------------------------------------------------------------------------------- 2-------------------------------------------------------------------------------- 3-- 4-- file: gui_highlight_unit.lua 5-- brief: highlights the unit/feature under the cursor 6-- author: Dave Rodgers 7-- 8-- Copyright (C) 2007. 9-- Licensed under the terms of the GNU GPL, v2 or later. 10-- 11-------------------------------------------------------------------------------- 12-------------------------------------------------------------------------------- 13 14function widget:GetInfo() 15 local grey = "\255\192\192\192" 16 local yellow = "\255\255\255\128" 17 return { 18 name = "HighlightUnit", 19 desc = "Highlights the unit or feature under the cursor\n".. 20 grey.."Hold "..yellow.."META"..grey.. 21 " to show the unit or feature name", 22 author = "trepan", 23 date = "Apr 16, 2007", 24 license = "GNU GPL, v2 or later", 25 layer = 5, 26 enabled = true -- loaded by default? 27 } 28end 29 30-------------------------------------------------------------------------------- 31-------------------------------------------------------------------------------- 32 33-- Automatically generated local definitions 34 35local GL_BACK = GL.BACK 36local GL_EYE_LINEAR = GL.EYE_LINEAR 37local GL_EYE_PLANE = GL.EYE_PLANE 38local GL_FILL = GL.FILL 39local GL_FRONT = GL.FRONT 40local GL_FRONT_AND_BACK = GL.FRONT_AND_BACK 41local GL_INVERT = GL.INVERT 42local GL_LINE = GL.LINE 43local GL_ONE = GL.ONE 44local GL_ONE_MINUS_SRC_ALPHA = GL.ONE_MINUS_SRC_ALPHA 45local GL_POINT = GL.POINT 46local GL_QUAD_STRIP = GL.QUAD_STRIP 47local GL_SRC_ALPHA = GL.SRC_ALPHA 48local GL_T = GL.T 49local GL_TEXTURE_GEN_MODE = GL.TEXTURE_GEN_MODE 50local GL_TRIANGLE_FAN = GL.TRIANGLE_FAN 51local glBeginEnd = gl.BeginEnd 52local glBlending = gl.Blending 53local glCallList = gl.CallList 54local glColor = gl.Color 55local glCreateList = gl.CreateList 56local glCulling = gl.Culling 57local glDeleteList = gl.DeleteList 58local glDeleteTexture = gl.DeleteTexture 59local glDepthTest = gl.DepthTest 60local glFeature = gl.Feature 61local glGetTextWidth = gl.GetTextWidth 62local glLineWidth = gl.LineWidth 63local glLogicOp = gl.LogicOp 64local glPointSize = gl.PointSize 65local glPolygonMode = gl.PolygonMode 66local glPolygonOffset = gl.PolygonOffset 67local glPopMatrix = gl.PopMatrix 68local glPushMatrix = gl.PushMatrix 69local glScale = gl.Scale 70local glSmoothing = gl.Smoothing 71local glTexCoord = gl.TexCoord 72local glTexGen = gl.TexGen 73local glText = gl.Text 74local glTexture = gl.Texture 75local glTranslate = gl.Translate 76local glUnit = gl.Unit 77local glVertex = gl.Vertex 78local spDrawUnitCommands = Spring.DrawUnitCommands 79local spGetFeatureAllyTeam = Spring.GetFeatureAllyTeam 80local spGetFeatureDefID = Spring.GetFeatureDefID 81local spGetFeaturePosition = Spring.GetFeaturePosition 82local spGetFeatureRadius = Spring.GetFeatureRadius 83local spGetFeatureTeam = Spring.GetFeatureTeam 84local spGetModKeyState = Spring.GetModKeyState 85local spGetMouseState = Spring.GetMouseState 86local spGetMyAllyTeamID = Spring.GetMyAllyTeamID 87local spGetMyPlayerID = Spring.GetMyPlayerID 88local spGetMyTeamID = Spring.GetMyTeamID 89local spGetPlayerControlledUnit = Spring.GetPlayerControlledUnit 90local spGetPlayerInfo = Spring.GetPlayerInfo 91local spGetTeamColor = Spring.GetTeamColor 92local spGetTeamInfo = Spring.GetTeamInfo 93local spGetUnitAllyTeam = Spring.GetUnitAllyTeam 94local spGetUnitDefID = Spring.GetUnitDefID 95local spGetUnitIsCloaked = Spring.GetUnitIsCloaked 96local spGetUnitTeam = Spring.GetUnitTeam 97local spIsCheatingEnabled = Spring.IsCheatingEnabled 98local spTraceScreenRay = Spring.TraceScreenRay 99 100 101-------------------------------------------------------------------------------- 102-------------------------------------------------------------------------------- 103 104include("colors.h.lua") 105include("fonts.lua") 106 107local font = 'FreeMonoBold' 108local fontSize = 16 109local fontName = ':n:'..LUAUI_DIRNAME..'Fonts/'..font..'_'..fontSize 110 111 112local showName = (1 > 0) 113 114local customTex = LUAUI_DIRNAME .. 'Images/highlight_strip.png' 115local texName = LUAUI_DIRNAME .. 'Images/highlight_strip.png' 116--local texName = 'bitmaps/laserfalloff.tga' 117 118local cylDivs = 64 119local cylList = 0 120 121local outlineWidth = 3 122 123local vsx, vsy = widgetHandler:GetViewSizes() 124function widget:ViewResize(viewSizeX, viewSizeY) 125 vsx = viewSizeX 126 vsy = viewSizeY 127end 128 129local smoothPolys = (glSmoothing ~= nil) and false 130 131 132-------------------------------------------------------------------------------- 133-------------------------------------------------------------------------------- 134 135function widget:Initialize() 136 cylList = glCreateList(DrawCylinder, cylDivs) 137end 138 139 140function widget:Shutdown() 141 glDeleteList(cylList) 142 glDeleteTexture(customTex) 143end 144 145 146-------------------------------------------------------------------------------- 147-------------------------------------------------------------------------------- 148 149function DrawCylinder(divs) 150 local cos = math.cos 151 local sin = math.sin 152 local divRads = (2.0 * math.pi) / divs 153 -- top 154 glBeginEnd(GL_TRIANGLE_FAN, function() 155 for i = 1, divs do 156 local a = i * divRads 157 glVertex(sin(a), 1.0, cos(a)) 158 end 159 end) 160 -- bottom 161 glBeginEnd(GL_TRIANGLE_FAN, function() 162 for i = 1, divs do 163 local a = -i * divRads 164 glVertex(sin(a), -1.0, cos(a)) 165 end 166 end) 167 -- sides 168 glBeginEnd(GL_QUAD_STRIP, function() 169 for i = 0, divs do 170 local a = i * divRads 171 glVertex(sin(a), 1.0, cos(a)) 172 glVertex(sin(a), -1.0, cos(a)) 173 end 174 end) 175end 176 177 178-------------------------------------------------------------------------------- 179-------------------------------------------------------------------------------- 180 181local function HilightModel(drawFunc, drawData, outline) 182 glDepthTest(true) 183 glPolygonOffset(-2, -2) 184 glBlending(GL_SRC_ALPHA, GL_ONE) 185 186 if (smoothPolys) then 187 glSmoothing(nil, nil, true) 188 end 189 190 local scale = 20 191 local shift = (2 * widgetHandler:GetHourTimer()) % scale 192 glTexCoord(0, 0) 193 glTexGen(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR) 194 glTexGen(GL_T, GL_EYE_PLANE, 0, (1 / scale), 0, shift) 195 glTexture(texName) 196 197 drawFunc(drawData) 198 199 glTexture(false) 200 glTexGen(GL_T, false) 201 202 -- more edge highlighting 203 if (outline) then 204 glLineWidth(outlineWidth) 205 glPointSize(outlineWidth) 206 glPolygonOffset(10, 100) 207 glPolygonMode(GL_FRONT_AND_BACK, GL_POINT) 208 drawFunc(drawData) 209 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) 210 drawFunc(drawData) 211 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) 212 glPointSize(1) 213 glLineWidth(1) 214 end 215 216 if (smoothPolys) then 217 glSmoothing(nil, nil, false) 218 end 219 220 glBlending(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) 221 glPolygonOffset(false) 222 glDepthTest(false) 223end 224 225 226-------------------------------------------------------------------------------- 227 228local function SetUnitColor(unitID, alpha) 229 local teamID = spGetUnitTeam(unitID) 230 if (teamID == nil) then 231 glColor(1.0, 0.0, 0.0, alpha) -- red 232 elseif (teamID == spGetMyTeamID()) then 233 glColor(0.0, 1.0, 1.0, alpha) -- cyan 234 elseif (spGetUnitAllyTeam(unitID) == spGetMyAllyTeamID()) then 235 glColor(0.0, 1.0, 0.0, alpha) -- green 236 else 237 glColor(1.0, 0.0, 0.0, alpha) -- red 238 end 239end 240 241 242local function SetFeatureColor(featureID, alpha) 243 glColor(1.0, 0.0, 1.0, alpha) -- purple 244 do return end -- FIXME -- wait for feature team/allyteam resolution 245 246 local allyTeamID = spGetFeatureAllyTeam(featureID) 247 if ((allyTeamID == nil) or (allyTeamID < 0)) then 248 glColor(1.0, 1.0, 1.0, alpha) -- white 249 elseif (allyTeamID == spGetMyAllyTeamID()) then 250 glColor(0.0, 1.0, 1.0, alpha) -- cyan 251 else 252 glColor(1.0, 0.0, 0.0, alpha) -- red 253 end 254end 255 256 257local function UnitDrawFunc(unitID) 258 glUnit(unitID, true) 259end 260 261 262local function FeatureDrawFunc(featureID) 263 glFeature(featureID, true) 264end 265 266 267local function HilightUnit(unitID) 268 local outline = (spGetUnitIsCloaked(unitID) ~= true) 269 SetUnitColor(unitID, outline and 0.5 or 0.25) 270 HilightModel(UnitDrawFunc, unitID, outline) 271end 272 273 274local function HilightFeatureModel(featureID) 275 SetFeatureColor(featureID, 0.5) 276 HilightModel(FeatureDrawFunc, featureID, true) 277end 278 279 280local function HilightFeature(featureID) 281 local fDefID = spGetFeatureDefID(featureID) 282 local fd = FeatureDefs[fDefID] 283 if (fd == nil) then return end 284 285 if (fd.drawType == 0) then 286 HilightFeatureModel(featureID) 287 return 288 end 289 290 local radius = spGetFeatureRadius(featureID) 291 if (radius == nil) then 292 return 293 end 294 295 local px, py, pz = spGetFeaturePosition(featureID) 296 if (px == nil) then return end 297 298 local yScale = 4 299 glPushMatrix() 300 glTranslate(px, py, pz) 301 glScale(radius, yScale * radius, radius) 302 -- FIXME: needs an 'inside' check 303 304 glDepthTest(true) 305 glLogicOp(GL_INVERT) 306 307 glCulling(GL_FRONT) 308 glCallList(cylList) 309 310 glCulling(GL_BACK) 311 glCallList(cylList) 312 313 glLogicOp(false) 314 glCulling(false) 315 glDepthTest(false) 316 317 glPopMatrix() 318end 319 320 321-------------------------------------------------------------------------------- 322-------------------------------------------------------------------------------- 323 324local GetPlayerControlledUnit = spGetPlayerControlledUnit 325local GetMyPlayerID = spGetMyPlayerID 326local TraceScreenRay = spTraceScreenRay 327local GetMouseState = spGetMouseState 328local GetUnitDefID = spGetUnitDefID 329local GetFeatureDefID = spGetFeatureDefID 330 331 332-------------------------------------------------------------------------------- 333-------------------------------------------------------------------------------- 334 335local type, data -- for the TraceScreenRay() call 336 337 338function widget:Update() 339 local mx, my = GetMouseState() 340 type, data = TraceScreenRay(mx, my) 341end 342 343 344function widget:DrawWorld() 345 if (type == 'feature') then 346 HilightFeature(data) 347 elseif (type == 'unit') then 348 local unitID = GetPlayerControlledUnit(GetMyPlayerID()) 349 if (data ~= unitID) then 350 HilightUnit(data) 351 -- also draw the unit's command queue 352 local a,c,m,s = spGetModKeyState() 353 if (m) then 354 spDrawUnitCommands(data) 355 end 356 end 357 end 358end 359 360 361widget.DrawWorldReflection = widget.DrawWorld 362 363 364widget.DrawWorldRefraction = widget.DrawWorld 365 366 367-------------------------------------------------------------------------------- 368-------------------------------------------------------------------------------- 369 370local teamNames = {} 371 372 373local function GetTeamName(teamID) 374 local name = teamNames[teamID] 375 if (name) then 376 return name 377 end 378 379 local teamNum, teamLeader = spGetTeamInfo(teamID) 380 if (teamLeader == nil) then 381 return '' 382 end 383 384 name = spGetPlayerInfo(teamLeader) 385 teamNames[teamID] = name 386 return name 387end 388 389 390-------------------------------------------------------------------------------- 391-------------------------------------------------------------------------------- 392 393local teamColorStrs = {} 394 395 396local function GetTeamColorStr(teamID) 397 local colorSet = teamColorStrs[teamID] 398 if (colorSet) then 399 return colorSet[1], colorSet[2] 400 end 401 402 local outlineChar = '' 403 local r,g,b = spGetTeamColor(teamID) 404 if (r and g and b) then 405 local function ColorChar(x) 406 local c = math.floor(x * 255) 407 c = ((c <= 1) and 1) or ((c >= 255) and 255) or c 408 return string.char(c) 409 end 410 local colorStr 411 colorStr = '\255' 412 colorStr = colorStr .. ColorChar(r) 413 colorStr = colorStr .. ColorChar(g) 414 colorStr = colorStr .. ColorChar(b) 415 local i = (r * 0.299) + (g * 0.587) + (b * 0.114) 416 outlineChar = ((i > 0.25) and 'o') or 'O' 417 teamColorStrs[teamID] = { colorStr, outlineChar } 418 return colorStr, outlineChar 419 end 420end 421 422 423-------------------------------------------------------------------------------- 424-------------------------------------------------------------------------------- 425 426function widget:DrawScreen() 427 local a,c,m,s = spGetModKeyState() 428 if (not m) then 429 return 430 end 431 432 local mx, my = GetMouseState() 433 local type, data = TraceScreenRay(mx, my) 434 435 local typeStr = '' 436 local teamID = nil 437 438 local cheat = spIsCheatingEnabled() 439 440 if (type == 'unit') then 441 local udid = GetUnitDefID(data) 442 if (udid == nil) then return end 443 local ud = UnitDefs[udid] 444 if (ud == nil) then return end 445 typeStr = YellowStr .. ud.humanName -- .. ' ' .. CyanStr .. ud.tooltip 446 if (cheat) then 447 typeStr = typeStr 448 .. ' \255\255\128\255(' .. ud.name 449 .. ') \255\255\255\255#' .. data 450 end 451 teamID = spGetUnitTeam(data) 452 elseif (type == 'feature') then 453 local fdid = GetFeatureDefID(data) 454 if (fdid == nil) then return end 455 local fd = FeatureDefs[fdid] 456 if (fd == nil) then return end 457 typeStr = '\255\255\128\255' .. fd.tooltip 458 if (cheat) then 459 typeStr = typeStr 460 .. ' \255\255\255\1(' .. fd.name 461 .. ') \255\255\255\255#' .. data 462 end 463 teamID = spGetFeatureTeam(data) 464 end 465 466 local pName = nil 467 local colorStr, outlineChar = nil, nil 468 if (teamID) then 469 pName = GetTeamName(teamID) 470 if (pName) then 471 colorStr, outlineChar = GetTeamColorStr(teamID) 472 if ((colorStr == nil) or (outlineChar == nil)) then 473 pName = nil 474 end 475 end 476 end 477 478 local fh = fontHandler 479 if (fh.UseFont(fontName)) then 480 481 local f = fh.GetFontSize() * 0.5 482 local gx = 12 -- gap x 483 local gy = 8 -- gap y 484 485 local lt = fh.GetTextWidth(typeStr) 486 local lp = pName and fh.GetTextWidth(pName) or 0 487 local lm = (lt > lp) and lt or lp -- max len 488 489 pName = pName and (colorStr .. pName) 490 491 if ((mx + lm + gx) < vsx) then 492 fh.Draw(typeStr, mx + gx, my + gy) 493 if (pName) then 494 fh.Draw(pName, mx + gx, my - gy - f) 495 end 496 else 497 fh.DrawRight(typeStr, mx - gx, my + gy) 498 if (pName) then 499 fh.DrawRight(pName, mx - gx, my - gy - f) 500 end 501 end 502 else 503 local f = 14 504 local gx = 16 505 local gy = 8 506 507 local lt = f * glGetTextWidth(typeStr) 508 local lp = pName and (f * glGetTextWidth(pName)) or 0 509 local lm = (lt > lp) and lt or lp -- max len 510 511 pName = pName and (colorStr .. pName) 512 513 if ((mx + lm + gx) < vsx) then 514 glText(typeStr, mx + gx, my + gy, f, 'o') 515 if (pName) then 516 glText(pName, mx + gx, my - gy - f, f, outlineChar) 517 end 518 else 519 glText(typeStr, mx - gx, my + gy, f, 'or') 520 if (pName) then 521 glText(pName, mx - gx, my - gy - f, f, outlineChar .. 'r') 522 end 523 end 524 end 525end 526 527 528-------------------------------------------------------------------------------- 529-------------------------------------------------------------------------------- 530