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 )