Files
call-of-duty-tdm/gamemodes/cod_custom/gamemode/client/cl_outline.lua
2026-03-30 10:39:52 +03:00

164 lines
3.7 KiB
Lua

OUTLINE_MODE_BOTH = 0
OUTLINE_MODE_NOTVISIBLE = 1
OUTLINE_MODE_VISIBLE = 2
local istable = istable
local render = render
local LocalPlayer = LocalPlayer
local Material = Material
local CreateMaterial = CreateMaterial
local hook = hook
local cam = cam
local ScrW = ScrW
local ScrH = ScrH
local IsValid = IsValid
local surface = surface
module( "outline", package.seeall )
local List, ListSize = {}, 0
local RenderEnt = NULL
local OutlineMatSettings = {
[ "$ignorez" ] = 1,
[ "$alphatest" ] = 1
}
local CopyMat = Material( "pp/copy" )
local OutlineMat = CreateMaterial( "OutlineMat", "UnlitGeneric", OutlineMatSettings )
local StoreTexture = render.GetScreenEffectTexture( 0 )
local DrawTexture = render.GetScreenEffectTexture( 1 )
local ENTS = 1
local COLOR = 2
local MODE = 3
function Add( ents, color, mode )
if ( ListSize >= 255 ) then return end --Maximum 255 reference values
if ( !istable( ents ) ) then ents = { ents } end --Support for passing Entity as first argument
if ( ents[ 1 ] == nil ) then return end --Do not pass empty tables
local t = {
[ ENTS ] = ents,
[ COLOR ] = color,
[ MODE ] = mode or OUTLINE_MODE_BOTH
}
ListSize = ListSize + 1
List[ ListSize ] = t
end
function RenderedEntity()
return RenderEnt
end
local function Render()
local ply = LocalPlayer()
local IsLineOfSightClear = ply.IsLineOfSightClear
local scene = render.GetRenderTarget()
render.CopyRenderTargetToTexture( StoreTexture )
local w = ScrW()
local h = ScrH()
render.Clear( 0, 0, 0, 0, true, true )
render.SetStencilEnable( true )
cam.IgnoreZ( true )
render.SuppressEngineLighting( true )
render.SetStencilWriteMask( 0xFF )
render.SetStencilTestMask( 0xFF )
render.SetStencilCompareFunction( STENCIL_ALWAYS )
render.SetStencilFailOperation( STENCIL_KEEP )
render.SetStencilZFailOperation( STENCIL_REPLACE )
render.SetStencilPassOperation( STENCIL_REPLACE )
cam.Start3D()
for i = 1, ListSize do
local v = List[ i ]
local mode = v[ MODE ]
local ents = v[ ENTS ]
render.SetStencilReferenceValue( i )
for j = 1, #ents do
local ent = ents[ j ]
if ( !IsValid( ent ) ) then continue end
if ( ( mode == OUTLINE_MODE_NOTVISIBLE && IsLineOfSightClear( ply, ent ) ) || ( mode == OUTLINE_MODE_VISIBLE && !IsLineOfSightClear( ply, ent ) ) ) then
continue
end
RenderEnt = ent
ent:DrawModel()
end
end
RenderEnt = NULL
cam.End3D()
render.SetStencilCompareFunction( STENCIL_EQUAL )
cam.Start2D()
for i = 1, ListSize do
render.SetStencilReferenceValue( i )
surface.SetDrawColor( List[ i ][ COLOR ] )
surface.DrawRect( 0, 0, w, h )
end
cam.End2D()
render.SuppressEngineLighting( false )
cam.IgnoreZ( false )
render.SetStencilEnable( false )
render.CopyRenderTargetToTexture( DrawTexture )
render.SetRenderTarget( scene )
CopyMat:SetTexture( "$basetexture", StoreTexture )
render.SetMaterial( CopyMat )
render.DrawScreenQuad()
render.SetStencilEnable( true )
render.SetStencilReferenceValue( 0 )
render.SetStencilCompareFunction( STENCIL_EQUAL )
OutlineMat:SetTexture( "$basetexture", DrawTexture )
render.SetMaterial( OutlineMat )
render.DrawScreenQuadEx( -1, -1, w ,h )
render.DrawScreenQuadEx( -1, 0, w, h )
render.DrawScreenQuadEx( -1, 1, w, h )
render.DrawScreenQuadEx( 0, -1, w, h )
render.DrawScreenQuadEx( 0, 1, w, h )
render.DrawScreenQuadEx( 1, 1, w, h )
render.DrawScreenQuadEx( 1, 0, w, h )
render.DrawScreenQuadEx( 1, 1, w, h )
render.SetStencilEnable( false )
end
hook.Add( "PostDrawEffects", "RenderOutlines", function()
hook.Run( "PreDrawOutlines" )
if ( ListSize == 0 ) then return end
Render()
List, ListSize = {}, 0
end )