@name 
@inputs 
@outputs 
@persist 
@trigger 
runOnChat(1)
luaRunAll("
local bulletholes = {}
local spampreventiontime, spampreventiontimeold = CurTime()
local spampreventionent, spampreventionentold
local tube = ClientsideModel('models/Mechanics/robotics/a1.mdl',RENDERGROUP_OPAQUE)
tube:SetRenderMode(1)
local c = tube:GetColor()
tube:SetColor(Color(c.r,c.g,c.b,0))
local mat1 = Matrix()
local width = 10
local depth = 15
mat1:Scale(Vector(1/24.5*depth,1/12*width,1/12*width))
tube:EnableMatrix('RenderMultiply',mat1)
local hole = ClientsideModel('models/props_c17/streetsign001c.mdl',RENDERGROUP_OPAQUE)
hole:SetRenderMode(1)
local c = hole:GetColor()
hole:SetColor(Color(c.r,c.g,c.b,0))
local mat2 = Matrix()
mat2:Scale(Vector(1/24.14*width,.1,1/24.14*width))
hole:EnableMatrix('RenderMultiply',mat2)
function hole:DrawHole(side)
	--side = 0 or 1 (A or B)
	local tr = self.trace
	local norm = tr.Normal
	local tiltednorm = Vector(norm.x,norm.y,norm.z)
	tiltednorm:Rotate(Angle(0,90,0))
	local ang = tiltednorm:Angle()
	self:SetAngles(ang+Angle(-ang.p,0,ang.p))
	if side == 0 then 
		self:SetPos(tr.HitPos+norm*-1)
	else
		depth = 4
		self:SetPos(tr.HitPos+norm*depth)
	end
	local c = self:GetColor()
	self:SetColor(Color(c.r,c.g,c.b,255))
	self:SetupBones() --necessary for some reason to update it so quickly
	self:DrawModel()
	self:SetColor(Color(c.r,c.g,c.b,0))
end

local function drawfunc(self)
	local drawfunc
	if self.Draw != nil then
		drawfunc = self.Draw
	elseif self.DrawModel != nil then
		drawfunc = self.DrawModel
	end
	if drawfunc then
		local c = self:GetColor()
		self:SetColor(Color(c.r,c.g,c.b,255))
		drawfunc(self)
		self:SetColor(Color(c.r,c.g,c.b,0))
	end
end

local function customdraw(ent,traces)
	ent:RemoveAllDecals()
	render.ClearStencil()
	render.SetStencilEnable(true)
		render.SetStencilWriteMask(255)
		render.SetStencilTestMask(255)
		render.SetStencilFailOperation(STENCILOPERATION_KEEP)
		render.SetStencilZFailOperation(STENCILOPERATION_REPLACE)
		render.SetStencilPassOperation(STENCILOPERATION_REPLACE)
		render.SetStencilCompareFunction(STENCILCOMPARISONFUNCTION_ALWAYS)
		render.SetBlend(0) --for visual testing, blend unchanged
			render.SetStencilReferenceValue(3)
			drawfunc(ent)
			
			for i = 1, #traces do
			hole.trace = traces[i]
			render.SetStencilZFailOperation(STENCILOPERATION_DECRSAT)
			render.SetStencilPassOperation(STENCILOPERATION_DECRSAT)
			hole:DrawHole(0)
			hole:DrawHole(1)
			end
		render.SetBlend(1)
		render.SetStencilReferenceValue(1)
		render.SetStencilCompareFunction(STENCILCOMPARISONFUNCTION_NOTEQUAL)
		render.SetStencilZFailOperation(STENCILOPERATION_KEEP)
		render.SetStencilPassOperation(STENCILOPERATION_KEEP)
		drawfunc(ent) --ent = 3, hole A/B are 2, A+B is 1
		
		render.SetStencilReferenceValue(2)
		render.SetStencilCompareFunction(STENCILCOMPARISONFUNCTION_EQUAL)
		render.SetStencilZFailOperation(STENCILOPERATION_DECRSAT)
		render.SetBlend(0)
			for i = 1, #traces do
				hole.trace = traces[i]
				hole:DrawHole(0)
				hole:DrawHole(1) --the visible hole is still 2, but the blocked one is now 1
			end
		render.SetBlend(1)
		render.SetStencilZFailOperation(STENCILOPERATION_KEEP)
		render.CullMode(MATERIAL_CULLMODE_CW) --now draw the tube inside the visible hole, but not A+B
			for i = 1, #traces do
				tube:SetPos(traces[i].HitPos+traces[i].Normal*-2)
				tube:SetAngles(traces[i].Normal:Angle())
				tube:SetupBones()
				cam.IgnoreZ(true)
					tube:DrawModel()
				cam.IgnoreZ(false)
			end
		render.CullMode(MATERIAL_CULLMODE_CCW)
	render.SetStencilEnable(false)
end

local function bullethole(ply,trace,damage)
	spampreventionentold, spampreventiontimeold = spampreventionent, spampreventiontime
	spampreventionent, spampreventiontime = trace.Entity, CurTime()
	if spampreventionent == spampreventionentold && spampreventiontime == spampreventiontimeold then return end
	if !trace.Hit || trace.HitWorld || !trace.Entity || trace.Entity:IsWorld() then return end
	bulletholes[trace.Entity] = bulletholes[trace.Entity] || {}
	table.insert(bulletholes[trace.Entity],trace)
	trace.Entity:SetRenderMode(1)
	local c = trace.Entity:GetColor()
	trace.Entity:SetColor(Color(c.r,c.g,c.b,0))
end

hook.Add('PreDrawOpaqueRenderables','bulletholes',function(drawdepth,drawskybox)
	for k, v in pairs(bulletholes) do
		if k == NULL then bulletholes[k] = nil else
			customdraw(k,bulletholes[k])
		end
	end
end)

hook.Add('EntityFireBullets','bulletholes',function(ent,info)
	info.Callback = bullethole
	return true
end)
")


if(chatClk()){  
    
    local ChatCommand = lastSpoke()
    local ModelText = lastSpoke()
if(ChatCommand:lastSaid():lower() == "!undo"){
ChatCommand:luaRunPly("
hook.Remove('EntityFireBullets','bulletholes')
hook.Remove('PreDrawOpaqueRenderables','bulletholes')
")
print("X")
}
}
