gps-ai/linedrawer.lua

129 lines
3.6 KiB
Lua

local ENABLE_FAILISH_ATTEMPT_AT_ANTI_ALIASING = false
local OVERLAY_WIDTH = 256
local OVERLAY_HEIGHT = 256
local OVERLAY_LINE_WIDTH = 5
local OVERLAY_LINE_COLOR = tocolor ( 0, 200, 0, 255 )
local OVERLAY_LINE_AA = tocolor ( 0, 200, 0, 200 )
local linePoints = { }
local renderStuff = { }
function removeLinePoints ( )
linePoints = { }
for name, data in pairs ( renderStuff ) do
unloadTile ( name )
end
end
function addLinePoint ( posX, posY )
-- Calculate the row and column of the radar tile we will be targeting
local row = 11 - math.floor ( ( posY + 3000 ) / 500 )
local col = math.floor ( ( posX + 3000 ) / 500 )
-- If it's off the map, don't bother
if row < 0 or row > 11 or col < 0 or col > 11 then
return false
end
-- Check the start position of the tile
local startX = col * 500 - 3000
local startY = 3000 - row * 500
-- Now get the tile position (We don't want to calculate this for every point on render)
local tileX = ( posX - startX ) / 500 * OVERLAY_WIDTH
local tileY = ( startY - posY ) / 500 * OVERLAY_HEIGHT
-- Now calulcate the ID and get the name of the tile
local id = col + row * 12
local name = string.format ( "radar%02d", id )
-- Make sure the line point table exists
if not linePoints [ name ] then
linePoints [ name ] = { }
end
-- Now add this point
table.insert ( linePoints[name], { posX = tileX, posY = tileY } )
-- Success!
return true
end
function loadTile ( name )
-- Create our fabulous shader. Abort on failure
local shader = dxCreateShader ( "overlay.fx" )
if not shader then
return false
end
-- Create a render target. Again, abort on failure (don't forget to delete the shader!)
local rt = dxCreateRenderTarget ( OVERLAY_WIDTH, OVERLAY_HEIGHT, true )
if not rt then
destroyElement ( shader )
return false
end
-- Mix 'n match
dxSetShaderValue ( shader, "gOverlay", rt )
-- Start drawing
dxSetRenderTarget ( rt )
-- Get the points involved, and get the starting position
local points = linePoints [ name ]
local prevX, prevY = points [ 1 ].posX, points [ 1 ] .posY
-- Loop through all points we have to draw, and draw them
for index, point in ipairs ( points ) do
local newX = point.posX
local newY = point.posY
if ENABLE_FAILISH_ATTEMPT_AT_ANTI_ALIASING then
dxDrawLine ( prevX - 1, prevY - 1, newX - 1, newY - 1, OVERLAY_LINE_AA, OVERLAY_LINE_WIDTH )
dxDrawLine ( prevX + 1, prevY - 1, newX + 1, newY - 1, OVERLAY_LINE_AA, OVERLAY_LINE_WIDTH )
dxDrawLine ( prevX - 1, prevY + 1, newX - 1, newY + 1, OVERLAY_LINE_AA, OVERLAY_LINE_WIDTH )
dxDrawLine ( prevX + 1, prevY + 1, newX + 1, newY + 1, OVERLAY_LINE_AA, OVERLAY_LINE_WIDTH )
end
dxDrawLine ( prevX, prevY, newX, newY, OVERLAY_LINE_COLOR, OVERLAY_LINE_WIDTH )
prevX = newX
prevY = newY
end
-- Now let's show our fabulous work to the commoners!
engineApplyShaderToWorldTexture ( shader, name )
-- Store the stuff in memories
renderStuff [ name ] = { shader = shader, rt = rt }
-- We won
return true
end
function unloadTile ( name )
destroyElement ( renderStuff[name].shader )
destroyElement ( renderStuff[name].rt )
renderStuff[name] = nil
return true
end
addEventHandler ( "onClientHUDRender", getRootElement ( ),
function ( )
local visibleTileNames = table.merge ( engineGetVisibleTextureNames ( "radar??" ), engineGetVisibleTextureNames ( "radar???" ) )
for name, data in pairs ( renderStuff ) do
if not table.find ( visibleTileNames, name ) then
unloadTile ( name )
end
end
for index, name in ipairs ( visibleTileNames ) do
if linePoints [ name ] and not renderStuff [ name ] then
loadTile ( name )
end
end
end
)