This commit is contained in:
lifestorm
2024-08-04 23:54:45 +03:00
parent 8064ba84d8
commit 6a58f406b1
7522 changed files with 4011896 additions and 15 deletions

View File

@@ -0,0 +1,373 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
SWEP.Flashlights = {} -- tracks projectedlights
-- {{att = int, light = ProjectedTexture}}
SWEP.CheapFlashlights = {} -- tracks cheap flashlight models + lights
-- {{att = int, dlight = DynamicLight, vlight = ClientsideModel}}
function SWEP:GetHasFlashlights()
for i, k in pairs(self.Attachments) do
if !k.Installed then continue end
if self:GetBuff_Stat("Flashlight", i) != nil then return true end
end
return false
end
function SWEP:CreateFlashlightsVM()
self:KillFlashlights()
self.Flashlights = {}
local total_lights = 0
for i, k in pairs(self.Attachments) do
if !k.Installed then continue end
if self:GetBuff_Stat("Flashlight", i) then
local newlight = {
att = i,
light = ProjectedTexture(),
bone = self:GetBuff_Stat("FlashlightBone", i) or "laser",
col = self:GetBuff_Stat("FlashlightColor", i) or Color(255, 255, 255),
br = self:GetBuff_Stat("FlashlightBrightness", i) or 2
}
total_lights = total_lights + 1
local l = newlight.light
if !IsValid(l) then continue end
table.insert(self.Flashlights, newlight)
l:SetFOV(self:GetBuff_Stat("FlashlightFOV", i) or 50)
if self:GetBuff_Stat("FlashlightHFOV", i) then
l:SetHorizontalFOV(self:GetBuff_Stat("FlashlightHFOV", i))
end
if self:GetBuff_Stat("FlashlightVFOV", i) then
l:SetVerticalFOV(self:GetBuff_Stat("FlashlightVFOV", i))
end
l:SetFarZ(self:GetBuff_Stat("FlashlightFarZ", i) or 512)
l:SetNearZ(self:GetBuff_Stat("FlashlightNearZ", i) or 4)
local atten = self:GetBuff_Stat("FlashlightAttenuationType", i) or ArcCW.FLASH_ATT_LINEAR
l:SetLinearAttenuation(0)
l:SetConstantAttenuation(0)
l:SetQuadraticAttenuation(0)
if atten == ArcCW.FLASH_ATT_CONSTANT then
l:SetConstantAttenuation(100)
elseif atten == ArcCW.FLASH_ATT_QUADRATIC then
l:SetQuadraticAttenuation(100)
else
l:SetLinearAttenuation(100)
end
l:SetColor(self:GetBuff_Stat("FlashlightColor", i) or Color(255, 255, 255))
l:SetTexture(self:GetBuff_Stat("FlashlightTexture", i))
l:SetBrightness(self:GetBuff_Stat("FlashlightBrightness", i))
l:SetEnableShadows(true)
l:Update()
local g_light = {
Weapon = self,
ProjectedTexture = l
}
table.insert(ArcCW.FlashlightPile, g_light)
end
end
if total_lights > 2 then -- you are a madman
for i, k in pairs(self.Flashlights) do
if k.light:IsValid() then k.light:SetEnableShadows(false) end
end
end
end
-- for world model flashlights we will use a cheap solution similar to what HL2 uses
-- throw up a volumetric light model
-- function SWEP:CreateFlashlightsWM()
-- self:KillFlashlights()
-- self.CheapFlashlights = {}
-- for i, k in pairs(self.Attachments) do
-- if !k.Installed then continue end
-- local atttbl = ArcCW.AttachmentTable[k.Installed]
-- if atttbl.Flashlight then
-- local newlight = {
-- att = i,
-- vlight = ClientsideModel(ArcCW.VolumetricLightModel),
-- scale_x = 1,
-- scale_y = 1,
-- maxz = atttbl.FlashlightFarZ or 512,
-- bone = atttbl.FlashlightBone or "laser",
-- col = Color(255, 255, 255)
-- }
-- local vl = newlight.vlight
-- if !IsValid(vl) then continue end
-- table.insert(self.CheapFlashlights, newlight)
-- local xfov = atttbl.FlashlightHFOV or atttbl.FlashlightFOV or 50
-- local yfov = atttbl.FlashlightVFOV or atttbl.FlashlightFOV or 50
-- local target_x = 128 * (xfov / 90)
-- local target_y = 128 * (yfov / 90)
-- local scale_x = target_x / ArcCW.VolumetricLightX
-- local scale_y = target_y / ArcCW.VolumetricLightY
-- newlight.scale_x = scale_x
-- newlight.scale_y = scale_y
-- vl:SetNoDraw(ArcCW.NoDraw)
-- vl:DrawShadow(false)
-- local col = atttbl.FlashlightColor or Color(255, 255, 255)
-- col = Color(255, 0, 0)
-- newlight.col = col
-- -- vl:SetColor(col)
-- local g_light = {
-- Model = vl,
-- Weapon = self
-- }
-- table.insert(ArcCW.CSModelPile, g_light)
-- end
-- end
-- end
function SWEP:KillFlashlights()
self:KillFlashlightsVM()
-- self:KillFlashlightsWM()
end
function SWEP:KillFlashlightsVM()
if !self.Flashlights then return end
for i, k in pairs(self.Flashlights) do
if k.light and k.light:IsValid() then
k.light:Remove()
end
end
self.Flashlights = nil
end
function SWEP:KillFlashlightsWM()
-- if !self.CheapFlashlights then return end
-- for i, k in pairs(self.CheapFlashlights) do
-- if k.vlight and k.vlight:IsValid() then
-- k.vlight:Remove()
-- end
-- end
-- self.CheapFlashlights = nil
end
-- given fov and distance solve apparent size
local function solvetriangle(angle, dist)
local a = angle / 2
local b = dist
return b * math.tan(a) * 2
end
local flashlight_mat = Material("models/effects/vol_light002")
-- local flashlight_mat = Material("effects/blueblacklargebeam")
function SWEP:DrawFlashlightsWM()
-- if !self.CheapFlashlights then
-- self:CreateFlashlightsWM()
-- end
local owner = self:GetOwner()
for i, k in pairs(self.Attachments) do
if !k.Installed then continue end
local atttbl = ArcCW.AttachmentTable[k.Installed]
if !atttbl or !self:GetBuff_Stat("Flashlight", i) then continue end
local maxz = atttbl.FlashlightFarZ or 512
local bone = atttbl.FlashlightBone or "laser"
local col = atttbl.FlashlightColor or Color(255, 255, 255)
if !k.WElement then continue end
local model = k.WElement.Model
if !IsValid(model) then return end
local pos, ang, dir
if !model then
pos = owner:EyePos()
ang = owner:EyeAngles()
dir = ang:Forward()
else
local att = model:LookupAttachment(bone or "laser")
att = att == 0 and model:LookupAttachment("muzzle") or att
if att == 0 then
pos = model:GetPos()
ang = IsValid(owner) and owner:EyeAngles() or model:GetAngles()
dir = ang:Forward()
dir_2 = ang:Up()
else
local attdata = model:GetAttachment(att)
pos, ang = attdata.Pos, attdata.Ang
dir = -ang:Right()
dir_2 = ang:Up()
end
end
local maxs = Vector(2, 2, 2)
local mins = -maxs
-- scale volumetric light
local tr = util.TraceHull({
start = pos,
endpos = pos + (dir * maxz),
mask = MASK_OPAQUE,
mins = mins,
maxs = maxs
})
local z = (tr.HitPos - tr.StartPos):Length()
-- local s_z = z / ArcCW.VolumetricLightZ
local xfov = atttbl.FlashlightHFOV or atttbl.FlashlightFOV or 50
local yfov = atttbl.FlashlightVFOV or atttbl.FlashlightFOV or 50
-- local target_x = 128 * (xfov / 90)
-- local target_y = 128 * (yfov / 90)
local target_x = solvetriangle(xfov, z)
local target_y = target_x
if xfov != yfov then
target_y = solvetriangle(yfov, z)
end
local vs = EyeAngles():Up()
local c1 = pos + vs
local c4 = pos - vs
local c2 = tr.HitPos + (vs * target_y * 0.75)
local c3 = tr.HitPos - (vs * target_y * 0.75)
render.SetMaterial(flashlight_mat)
render.DrawQuad(c1,c2,c3,c4, col)
-- local scale = Matrix()
-- scale:Scale(Vector(s_x, s_y, s_z))
-- k.vlight:SetPos(pos)
-- k.vlight:SetAngles(ang + Angle(0, 0, 90))
-- k.vlight:EnableMatrix("RenderMultiply", scale)
-- k.vlight:SetColor(Color(255, 0, 0, 255))
-- k.vlight:SetRenderMode(RENDERMODE_NORMAL)
-- k.vlight:SetKeyValue("RenderFX", kRenderFxNone)
-- k.vlight:DrawModel()
-- place dynamic light to make some light appear
local dl = DynamicLight(self:EntIndex())
local delta = (z / maxz)
delta = math.Clamp(delta, 0, 1)
if dl then
dl.pos = tr.HitPos
dl.r = col.r
dl.g = col.g
dl.b = col.b
dl.brightness = Lerp(delta, atttbl.FlashlightBrightness or 2, 0)
-- print(z / maxz)
dl.Decay = 1000 / 1
dl.dietime = CurTime() + 0.1
dl.size = xfov * 5
end
end
end
function SWEP:DrawFlashlightsVM()
if !self.Flashlights then
self:CreateFlashlightsVM()
end
local owner = self:GetOwner()
for i, k in pairs(self.Flashlights) do
local model = (self.Attachments[k.att].VElement or {}).Model
local pos, ang
if !model then
pos = owner:EyePos()
ang = owner:EyeAngles()
else
local att = model:LookupAttachment(k.bone or "laser")
att = att == 0 and model:LookupAttachment("muzzle") or att
if att == 0 then
pos = model:GetPos()
ang = owner:EyeAngles()
else
local attdata = model:GetAttachment(att)
pos, ang = attdata.Pos, attdata.Ang
end
end
local tr = util.TraceLine({
start = owner:EyePos(),
endpos = owner:EyePos() - ang:Right() * 128,
mask = MASK_OPAQUE,
filter = LocalPlayer(),
})
if tr.Fraction < 1 then -- We need to push the flashlight back
local tr2 = util.TraceLine({
start = owner:EyePos(),
endpos = owner:EyePos() + ang:Right() * 128,
mask = MASK_OPAQUE,
filter = LocalPlayer(),
})
-- push it as back as the area behind us allows
pos = pos + ang:Right() * 128 * math.min(1 - tr.Fraction, tr2.Fraction)
end
ang:RotateAroundAxis(ang:Up(), 90)
k.light:SetPos(pos)
k.light:SetAngles(ang)
k.light:Update()
-- local col = k.col
-- local dl = DynamicLight(self:EntIndex())
-- if dl then
-- dl.pos = pos
-- dl.r = col.r
-- dl.g = col.g
-- dl.b = col.b
-- dl.brightness = k.br or 2
-- -- print(z / maxz)
-- dl.Decay = 1000 / 0.1
-- dl.dietime = CurTime() + 0.1
-- dl.size = (k.br or 2) * 64
-- end
end
end