1-------------------------------------------------------------------------------- 2-------------------------------------------------------------------------------- 3-- 4-- file: minimap_startbox.lua 5-- brief: shows the startboxes in the minimap 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 return { 16 name = "MiniMap Start Boxes", 17 desc = "MiniMap Start Boxes", 18 author = "trepan, jK", 19 date = "2007-2009", 20 license = "GNU GPL, v2 or later", 21 layer = 0, 22 enabled = true -- loaded by default? 23 } 24end 25 26-------------------------------------------------------------------------------- 27-------------------------------------------------------------------------------- 28 29if (Game.startPosType ~= 2) then 30 return false 31end 32 33if (Spring.GetGameFrame() > 1) then 34 widgetHandler:RemoveWidget() 35end 36 37-------------------------------------------------------------------------------- 38-------------------------------------------------------------------------------- 39-- 40-- config options 41-- 42 43-- enable simple version by default though 44local drawGroundQuads = true 45 46 47-------------------------------------------------------------------------------- 48-------------------------------------------------------------------------------- 49 50local gl = gl -- use a local copy for faster access 51 52local msx = Game.mapSizeX 53local msz = Game.mapSizeZ 54 55local xformList = 0 56local coneList = 0 57local startboxDListStencil = 0 58local startboxDListColor = 0 59 60local gaiaTeamID 61local gaiaAllyTeamID 62 63local teamStartPositions = {} 64local startTimer = Spring.GetTimer() 65 66local texName = LUAUI_DIRNAME .. 'Images/highlight_strip.png' 67local texScale = 512 68 69-------------------------------------------------------------------------------- 70 71GL.KEEP = 0x1E00 72GL.INCR_WRAP = 0x8507 73GL.DECR_WRAP = 0x8508 74GL.INCR = 0x1E02 75GL.DECR = 0x1E03 76GL.INVERT = 0x150A 77 78local stencilBit1 = 0x01 79local stencilBit2 = 0x10 80 81-------------------------------------------------------------------------------- 82-------------------------------------------------------------------------------- 83 84local function DrawMyBox(minX,minY,minZ, maxX,maxY,maxZ) 85 gl.BeginEnd(GL.QUADS, function() 86 --// top 87 gl.Vertex(minX, maxY, minZ); 88 gl.Vertex(maxX, maxY, minZ); 89 gl.Vertex(maxX, maxY, maxZ); 90 gl.Vertex(minX, maxY, maxZ); 91 --// bottom 92 gl.Vertex(minX, minY, minZ); 93 gl.Vertex(minX, minY, maxZ); 94 gl.Vertex(maxX, minY, maxZ); 95 gl.Vertex(maxX, minY, minZ); 96 end); 97 gl.BeginEnd(GL.QUAD_STRIP, function() 98 --// sides 99 gl.Vertex(minX, minY, minZ); 100 gl.Vertex(minX, maxY, minZ); 101 gl.Vertex(minX, minY, maxZ); 102 gl.Vertex(minX, maxY, maxZ); 103 gl.Vertex(maxX, minY, maxZ); 104 gl.Vertex(maxX, maxY, maxZ); 105 gl.Vertex(maxX, minY, minZ); 106 gl.Vertex(maxX, maxY, minZ); 107 gl.Vertex(minX, minY, minZ); 108 gl.Vertex(minX, maxY, minZ); 109 end); 110end 111 112-------------------------------------------------------------------------------- 113-------------------------------------------------------------------------------- 114 115function widget:Initialize() 116 -- only show at the beginning 117 if (Spring.GetGameFrame() > 1) then 118 widgetHandler:RemoveWidget() 119 return 120 end 121 122 -- get the gaia teamID and allyTeamID 123 gaiaTeamID = Spring.GetGaiaTeamID() 124 if (gaiaTeamID) then 125 local _,_,_,_,_,atid = Spring.GetTeamInfo(gaiaTeamID) 126 gaiaAllyTeamID = atid 127 end 128 129 -- flip and scale (using x & y for gl.Rect()) 130 xformList = gl.CreateList(function() 131 gl.LoadIdentity() 132 gl.Translate(0, 1, 0) 133 gl.Scale(1 / msx, -1 / msz, 1) 134 end) 135 136 -- cone list for world start positions 137 coneList = gl.CreateList(function() 138 local h = 100 139 local r = 25 140 local divs = 32 141 gl.BeginEnd(GL.TRIANGLE_FAN, function() 142 gl.Vertex( 0, h, 0) 143 for i = 0, divs do 144 local a = i * ((math.pi * 2) / divs) 145 local cosval = math.cos(a) 146 local sinval = math.sin(a) 147 gl.Vertex(r * sinval, 0, r * cosval) 148 end 149 end) 150 end) 151 152 if (drawGroundQuads) then 153 startboxDListStencil = gl.CreateList(function() 154 local minY,maxY = Spring.GetGroundExtremes() 155 minY = minY - 200; maxY = maxY + 100; 156 for _,at in ipairs(Spring.GetAllyTeamList()) do 157 if (true or at ~= gaiaAllyTeamID) then 158 local xn, zn, xp, zp = Spring.GetAllyTeamStartBox(at) 159 if (xn and ((xn ~= 0) or (zn ~= 0) or (xp ~= msx) or (zp ~= msz))) then 160 161 if (at == Spring.GetMyAllyTeamID()) then 162 gl.StencilMask(stencilBit2); 163 gl.StencilFunc(GL.ALWAYS, 0, stencilBit2); 164 else 165 gl.StencilMask(stencilBit1); 166 gl.StencilFunc(GL.ALWAYS, 0, stencilBit1); 167 end 168 DrawMyBox(xn,minY,zn, xp,maxY,zp) 169 170 end 171 end 172 end 173 end) 174 175 startboxDListColor = gl.CreateList(function() 176 local minY,maxY = Spring.GetGroundExtremes() 177 minY = minY - 200; maxY = maxY + 100; 178 for _,at in ipairs(Spring.GetAllyTeamList()) do 179 if (true or at ~= gaiaAllyTeamID) then 180 local xn, zn, xp, zp = Spring.GetAllyTeamStartBox(at) 181 if (xn and ((xn ~= 0) or (zn ~= 0) or (xp ~= msx) or (zp ~= msz))) then 182 183 if (at == Spring.GetMyAllyTeamID()) then 184 gl.Color( 0, 1, 0, 0.3 ) -- green 185 gl.StencilMask(stencilBit2); 186 gl.StencilFunc(GL.NOTEQUAL, 0, stencilBit2); 187 else 188 gl.Color( 1, 0, 0, 0.3 ) -- red 189 gl.StencilMask(stencilBit1); 190 gl.StencilFunc(GL.NOTEQUAL, 0, stencilBit1); 191 end 192 DrawMyBox(xn,minY,zn, xp,maxY,zp) 193 194 end 195 end 196 end 197 end) 198 end 199end 200 201 202function widget:Shutdown() 203 gl.DeleteList(xformList) 204 gl.DeleteList(coneList) 205 gl.DeleteList(startboxDListStencil) 206 gl.DeleteList(startboxDListColor) 207end 208 209 210-------------------------------------------------------------------------------- 211-------------------------------------------------------------------------------- 212 213local teamColors = {} 214 215local function GetTeamColor(teamID) 216 local color = teamColors[teamID] 217 if (color) then 218 return color 219 end 220 local r,g,b = Spring.GetTeamColor(teamID) 221 222 color = { r, g, b } 223 teamColors[teamID] = color 224 return color 225end 226 227 228-------------------------------------------------------------------------------- 229-------------------------------------------------------------------------------- 230 231local teamColorStrs = {} 232 233 234local function GetTeamColorStr(teamID) 235 local colorSet = teamColorStrs[teamID] 236 if (colorSet) then 237 return colorSet[1], colorSet[2] 238 end 239 240 local outlineChar = '' 241 local r,g,b = Spring.GetTeamColor(teamID) 242 if (r and g and b) then 243 local function ColorChar(x) 244 local c = math.floor(x * 255) 245 c = ((c <= 1) and 1) or ((c >= 255) and 255) or c 246 return string.char(c) 247 end 248 local colorStr 249 colorStr = '\255' 250 colorStr = colorStr .. ColorChar(r) 251 colorStr = colorStr .. ColorChar(g) 252 colorStr = colorStr .. ColorChar(b) 253 local i = (r * 0.299) + (g * 0.587) + (b * 0.114) 254 outlineChar = ((i > 0.25) and 'o') or 'O' 255 teamColorStrs[teamID] = { colorStr, outlineChar } 256 return colorStr, "s",outlineChar 257 end 258end 259 260-------------------------------------------------------------------------------- 261-------------------------------------------------------------------------------- 262 263local function DrawStartboxes3dWithStencil() 264 gl.DepthMask(false); 265 if (gl.DepthClamp) then gl.DepthClamp(true); end 266 267 gl.DepthTest(true); 268 gl.StencilTest(true); 269 gl.ColorMask(false, false, false, false); 270 gl.Culling(false); 271 272 gl.StencilOp(GL.KEEP, GL.INVERT, GL.KEEP); 273 274 gl.CallList(startboxDListStencil); --// draw 275 276 gl.Culling(GL.BACK); 277 gl.DepthTest(false); 278 279 gl.ColorMask(true, true, true, true); 280 281 gl.CallList(startboxDListColor); --// draw 282 283 if (gl.DepthClamp) then gl.DepthClamp(false); end 284 gl.StencilTest(false); 285 gl.DepthTest(true); 286 gl.Culling(false); 287end 288 289-------------------------------------------------------------------------------- 290-------------------------------------------------------------------------------- 291 292function widget:DrawWorld() 293 gl.Fog(false) 294 295 local time = Spring.DiffTimers(Spring.GetTimer(), startTimer) 296 297 -- show the ally startboxes 298 DrawStartboxes3dWithStencil() 299 300 -- show the team start positions 301 for _, teamID in ipairs(Spring.GetTeamList()) do 302 local _,leader = Spring.GetTeamInfo(teamID) 303 local name,_,spec = Spring.GetPlayerInfo(leader) 304 if ((not spec) and (teamID ~= gaiaTeamID)) then 305 local newx, newy, newz = Spring.GetTeamStartPosition(teamID) 306 307 if (teamStartPositions[teamID] == nil) then 308 teamStartPositions[teamID] = {newx, newy, newz} 309 end 310 311 local oldx, oldy, oldz = 312 teamStartPositions[teamID][1], 313 teamStartPositions[teamID][2], 314 teamStartPositions[teamID][3] 315 316 if (newx ~= oldx or newy ~= oldy or newz ~= oldz) then 317 Spring.PlaySoundFile("MapPoint") 318 Spring.MarkerErasePosition(oldx, oldy, oldz) 319 Spring.MarkerAddPoint(newx, newy, newz, "Start " .. teamID .. " (" .. name .. ")", 1) 320 teamStartPositions[teamID][1] = newx 321 teamStartPositions[teamID][2] = newy 322 teamStartPositions[teamID][3] = newz 323 end 324 325 if (newx ~= nil and newx ~= 0 and newz ~= 0 and newy > -500.0) then 326 local color = GetTeamColor(teamID) 327 local alpha = 0.5 + math.abs(((time * 3) % 1) - 0.5) 328 gl.PushMatrix() 329 gl.Translate(newx, newy, newz) 330 gl.Color(color[1], color[2], color[3], alpha) 331 gl.CallList(coneList) 332 gl.PopMatrix() 333 end 334 end 335 end 336 337 gl.Fog(true) 338end 339 340-------------------------------------------------------------------------------- 341-------------------------------------------------------------------------------- 342 343function widget:DrawScreenEffects() 344 -- show the names over the team start positions 345 gl.Fog(false) 346 gl.BeginText() 347 for _, teamID in ipairs(Spring.GetTeamList()) do 348 local _,leader = Spring.GetTeamInfo(teamID) 349 local name,_,spec = Spring.GetPlayerInfo(leader) 350 if ((not spec) and (teamID ~= gaiaTeamID)) then 351 local colorStr, outlineStr = GetTeamColorStr(teamID) 352 local x, y, z = Spring.GetTeamStartPosition(teamID) 353 if (x ~= nil and x > 0 and z > 0 and y > -500) then 354 local sx, sy, sz = Spring.WorldToScreenCoords(x, y + 120, z) 355 if (sz < 1) then 356 gl.Text(colorStr .. name, sx, sy, 18, 'cs') 357 end 358 end 359 end 360 end 361 gl.EndText() 362 gl.Fog(true) 363end 364 365-------------------------------------------------------------------------------- 366-------------------------------------------------------------------------------- 367 368function widget:DrawInMiniMap(sx, sz) 369 -- only show at the beginning 370 if (Spring.GetGameFrame() > 1) then 371 widgetHandler:RemoveWidget() 372 end 373 374 gl.PushMatrix() 375 gl.CallList(xformList) 376 377 gl.LineWidth(1.49) 378 379 local gaiaAllyTeamID 380 local gaiaTeamID = Spring.GetGaiaTeamID() 381 if (gaiaTeamID) then 382 local _,_,_,_,_,atid = Spring.GetTeamInfo(gaiaTeamID) 383 gaiaAllyTeamID = atid 384 end 385 386 -- show all start boxes 387 for _,at in ipairs(Spring.GetAllyTeamList()) do 388 if (at ~= gaiaAllyTeamID) then 389 local xn, zn, xp, zp = Spring.GetAllyTeamStartBox(at) 390 if (xn and ((xn ~= 0) or (zn ~= 0) or (xp ~= msx) or (zp ~= msz))) then 391 local color 392 if (at == Spring.GetMyAllyTeamID()) then 393 color = { 0, 1, 0, 0.1 } -- green 394 else 395 color = { 1, 0, 0, 0.1 } -- red 396 end 397 gl.Color(color) 398 gl.Rect(xn, zn, xp, zp) 399 color[4] = 0.5 -- pump up the volume 400 gl.Color(color) 401 gl.PolygonMode(GL.FRONT_AND_BACK, GL.LINE) 402 gl.Rect(xn, zn, xp, zp) 403 gl.PolygonMode(GL.FRONT_AND_BACK, GL.FILL) 404 end 405 end 406 end 407 408 gl.PushAttrib(GL_HINT_BIT) 409 gl.Smoothing(true) --enable point smoothing 410 411 -- show the team start positions 412 for _, teamID in ipairs(Spring.GetTeamList()) do 413 local _,leader = Spring.GetTeamInfo(teamID) 414 local _,_,spec = Spring.GetPlayerInfo(leader) 415 if ((not spec) and (teamID ~= gaiaTeamID)) then 416 local x, y, z = Spring.GetTeamStartPosition(teamID) 417 if (x ~= nil and x > 0 and z > 0 and y > -500) then 418 local color = GetTeamColor(teamID) 419 local r, g, b = color[1], color[2], color[3] 420 local time = Spring.DiffTimers(Spring.GetTimer(), startTimer) 421 local i = 2 * math.abs(((time * 3) % 1) - 0.5) 422 gl.PointSize(11) 423 gl.Color(i, i, i) 424 gl.BeginEnd(GL.POINTS, gl.Vertex, x, z) 425 gl.PointSize(7.5) 426 gl.Color(r, g, b) 427 gl.BeginEnd(GL.POINTS, gl.Vertex, x, z) 428 end 429 end 430 end 431 432 gl.LineWidth(1.0) 433 gl.PointSize(1.0) 434 gl.PopAttrib() --reset point smoothing 435 gl.PopMatrix() 436end 437 438 439-------------------------------------------------------------------------------- 440-------------------------------------------------------------------------------- 441