mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 13:53:45 +03:00
Upload
This commit is contained in:
373
lua/weapons/arccw_base/cl_light.lua
Normal file
373
lua/weapons/arccw_base/cl_light.lua
Normal 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
|
||||
Reference in New Issue
Block a user