1094 lines
30 KiB
Lua
1094 lines
30 KiB
Lua
local checkinterval = 2
|
|
local maxLampDist = 3000 * 3000
|
|
local maxLightSpriteDist = 3000 * 3000
|
|
local NextCheck = CurTime() + checkinterval
|
|
|
|
local hdr = GetConVar('mat_hdr_level')
|
|
local mat = Material('sprites/light_ignorez')
|
|
local mat2 = Material('sprites/light_glow02_add_noz')
|
|
|
|
if file.Exists('materials/sprites/glow_headlight_ignorez.vmt', 'GAME') then
|
|
mat2 = Material('sprites/glow_headlight_ignorez')
|
|
end
|
|
|
|
local SpritesDisabled = false
|
|
local AllowVisualDamage = true
|
|
local FrontProjectedLights = true
|
|
local RearProjectedLights = true
|
|
local Shadows = false
|
|
|
|
cvars.AddChangeCallback('cl_simfphys_hidesprites', function(convar, oldValue, newValue) SpritesDisabled = (tonumber(newValue) ~= 0) end)
|
|
cvars.AddChangeCallback('cl_simfphys_spritedamage', function(convar, oldValue, newValue) AllowVisualDamage = (tonumber(newValue) ~= 0) end)
|
|
cvars.AddChangeCallback('cl_simfphys_frontlamps', function(convar, oldValue, newValue) FrontProjectedLights = (tonumber(newValue) ~= 0) end)
|
|
cvars.AddChangeCallback('cl_simfphys_rearlamps', function(convar, oldValue, newValue) RearProjectedLights = (tonumber(newValue) ~= 0) end)
|
|
cvars.AddChangeCallback('cl_simfphys_shadows', function(convar, oldValue, newValue) Shadows = (tonumber(newValue) ~= 0) end)
|
|
|
|
SpritesDisabled = GetConVar('cl_simfphys_hidesprites'):GetBool()
|
|
AllowVisualDamage = GetConVar('cl_simfphys_spritedamage'):GetBool()
|
|
FrontProjectedLights = GetConVar('cl_simfphys_frontlamps'):GetBool()
|
|
RearProjectedLights = GetConVar('cl_simfphys_rearlamps'):GetBool()
|
|
Shadows = GetConVar('cl_simfphys_shadows'):GetBool()
|
|
|
|
if not istable(vtable) then
|
|
vtable = {}
|
|
end
|
|
|
|
local function BodyGroupIsValid(bodygroups, entity)
|
|
for index, groups in pairs(bodygroups) do
|
|
local mygroup = entity:GetBodygroup(index)
|
|
for g_index = 1, table.Count(groups) do
|
|
if (mygroup == groups[g_index]) then return true end
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
local function UpdateSubMats(ent, Lowbeam, Highbeam, IsBraking, IsReversing)
|
|
if not istable(ent.SubMaterials) then return end
|
|
|
|
if ent.SubMaterials.turnsignals then
|
|
local IsTurningLeft = ent.signal_left
|
|
local IsTurningRight = ent.signal_right
|
|
local IsFlashing = ent:GetFlasher() == 1
|
|
|
|
if ent.WasTurningLeft ~= IsTurningLeft or ent.WasTurningRight ~= IsTurningRight or ent.WasFlashing ~= IsFlashing then
|
|
if ent.SubMaterials.turnsignals.left then
|
|
for k,v in pairs(ent.SubMaterials.turnsignals.left) do
|
|
local mat = (IsFlashing and IsTurningLeft) and v or ''
|
|
ent:SetSubMaterial(k, mat)
|
|
end
|
|
end
|
|
if ent.SubMaterials.turnsignals.right then
|
|
for k,v in pairs(ent.SubMaterials.turnsignals.right) do
|
|
local mat = (IsFlashing and IsTurningRight) and v or ''
|
|
ent:SetSubMaterial(k, mat)
|
|
end
|
|
end
|
|
|
|
ent.WasTurningLeft = IsTurningLeft
|
|
ent.WasTurningRight = IsTurningRight
|
|
ent.WasFlashing = IsFlashing
|
|
end
|
|
end
|
|
|
|
if ent.WasReversing == IsReversing and ent.WasBraking == IsBraking and ent.WasLowbeam == Lowbeam and ent.WasHighbeam == Highbeam then return end
|
|
|
|
if Lowbeam then
|
|
if Highbeam then
|
|
if ent.SubMaterials.on_highbeam then
|
|
if not IsReversing and not IsBraking then
|
|
if ent.SubMaterials.on_highbeam.Base then
|
|
for k,v in pairs(ent.SubMaterials.on_highbeam.Base) do
|
|
ent:SetSubMaterial(k, v)
|
|
end
|
|
end
|
|
elseif IsBraking then
|
|
if IsReversing then
|
|
if ent.SubMaterials.on_highbeam.Brake_Reverse then
|
|
for k,v in pairs(ent.SubMaterials.on_highbeam.Brake_Reverse) do
|
|
ent:SetSubMaterial(k, v)
|
|
end
|
|
end
|
|
else
|
|
if ent.SubMaterials.on_highbeam.Brake then
|
|
for k,v in pairs(ent.SubMaterials.on_highbeam.Brake) do
|
|
ent:SetSubMaterial(k, v)
|
|
end
|
|
end
|
|
end
|
|
else
|
|
if ent.SubMaterials.on_highbeam.Reverse then
|
|
for k,v in pairs(ent.SubMaterials.on_highbeam.Reverse) do
|
|
ent:SetSubMaterial(k, v)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
else
|
|
if ent.SubMaterials.on_lowbeam then
|
|
if not IsReversing and not IsBraking then
|
|
if ent.SubMaterials.on_lowbeam.Base then
|
|
for k,v in pairs(ent.SubMaterials.on_lowbeam.Base) do
|
|
ent:SetSubMaterial(k, v)
|
|
end
|
|
end
|
|
elseif IsBraking then
|
|
if IsReversing then
|
|
if ent.SubMaterials.on_lowbeam.Brake_Reverse then
|
|
for k,v in pairs(ent.SubMaterials.on_lowbeam.Brake_Reverse) do
|
|
ent:SetSubMaterial(k, v)
|
|
end
|
|
end
|
|
else
|
|
if ent.SubMaterials.on_lowbeam.Brake then
|
|
for k,v in pairs(ent.SubMaterials.on_lowbeam.Brake) do
|
|
ent:SetSubMaterial(k, v)
|
|
end
|
|
end
|
|
end
|
|
else
|
|
if ent.SubMaterials.on_lowbeam.Reverse then
|
|
for k,v in pairs(ent.SubMaterials.on_lowbeam.Reverse) do
|
|
ent:SetSubMaterial(k, v)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
else
|
|
if ent.SubMaterials.off then
|
|
if not IsReversing and not IsBraking then
|
|
if ent.SubMaterials.off.Base then
|
|
for k,v in pairs(ent.SubMaterials.off.Base) do
|
|
ent:SetSubMaterial(k, v)
|
|
end
|
|
end
|
|
elseif IsBraking then
|
|
if IsReversing then
|
|
if ent.SubMaterials.off.Brake_Reverse then
|
|
for k,v in pairs(ent.SubMaterials.off.Brake_Reverse) do
|
|
ent:SetSubMaterial(k, v)
|
|
end
|
|
end
|
|
else
|
|
if ent.SubMaterials.off.Brake then
|
|
for k,v in pairs(ent.SubMaterials.off.Brake) do
|
|
ent:SetSubMaterial(k, v)
|
|
end
|
|
end
|
|
end
|
|
else
|
|
if ent.SubMaterials.off.Reverse then
|
|
for k,v in pairs(ent.SubMaterials.off.Reverse) do
|
|
ent:SetSubMaterial(k, v)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
ent.WasReversing = IsReversing
|
|
ent.WasBraking = IsBraking
|
|
ent.WasLowbeam = Lowbeam
|
|
ent.WasHighbeam = Highbeam
|
|
end
|
|
|
|
local function ManageProjTextures()
|
|
if not vtable then return end
|
|
|
|
local eyePos = LocalPlayer():GetShootPos()
|
|
for i, ent in pairs(vtable) do
|
|
if IsValid(ent) then
|
|
if ent:GetPos():DistToSqr(eyePos) > maxLampDist then
|
|
if ent.checkProjectors then
|
|
for _, proj in pairs(ent.Projtexts) do
|
|
if IsValid(proj.projector) then
|
|
proj.projector:Remove()
|
|
proj.projector = nil
|
|
proj.LampsActive = nil
|
|
end
|
|
end
|
|
ent.checkProjectors = nil
|
|
end
|
|
continue
|
|
end
|
|
ent.checkProjectors = true
|
|
|
|
local vel = ent:GetVelocity() * RealFrameTime()
|
|
ent.triggers = {
|
|
[1] = ent:GetLightsEnabled(),
|
|
[2] = ent:GetLampsEnabled(),
|
|
[4] = ent:GetIsBraking(),
|
|
[5] = ent:GetGear() == 1,
|
|
[6] = ent.signal_left,
|
|
[7] = ent.signal_right,
|
|
[8] = ent:GetIsBraking(),
|
|
[9] = ent:GetIsBraking(),
|
|
}
|
|
|
|
UpdateSubMats(ent, ent.triggers[1], ent.triggers[2], ent.triggers[4], ent.triggers[5])
|
|
|
|
local mul = StormFox2.Time.IsNight() and 1 or 0.2
|
|
for _, proj in pairs(ent.Projtexts) do
|
|
local trigger = ent.triggers[proj.trigger]
|
|
local enable = ent.triggers[1] or trigger
|
|
|
|
if proj.Damaged or (proj.trigger == 2 and not FrontProjectedLights) or (proj.trigger == 4 and not RearProjectedLights) then
|
|
trigger = false
|
|
enable = false
|
|
end
|
|
|
|
if ent.HasSpecialTurnSignals and proj.trigger == 4 and (ent.triggers[6] or ent.triggers[7]) then
|
|
trigger = false
|
|
end
|
|
|
|
if proj.LampsActive ~= trigger then
|
|
proj.LampsActive = trigger
|
|
|
|
if enable then
|
|
proj.istriggered = trigger
|
|
local brightness = trigger and proj.ontrigger.brightness or proj.brightness
|
|
local mat = trigger and proj.ontrigger.mat or proj.mat
|
|
local col = trigger and proj.ontrigger.col or proj.col
|
|
local FarZ = trigger and proj.ontrigger.FarZ or proj.FarZ
|
|
|
|
if trigger and brightness > 0 then
|
|
local thelamp = ProjectedTexture()
|
|
thelamp:SetBrightness(brightness * mul)
|
|
thelamp:SetTexture(mat)
|
|
thelamp:SetColor(col)
|
|
thelamp:SetEnableShadows(Shadows)
|
|
thelamp:SetFarZ(FarZ)
|
|
thelamp:SetNearZ(proj.NearZ)
|
|
thelamp:SetFOV(proj.Fov)
|
|
if FarZ > 500 then
|
|
thelamp:SetConstantAttenuation(0.5)
|
|
end
|
|
|
|
proj.projector = thelamp
|
|
elseif IsValid(proj.projector) then
|
|
proj.projector:Remove()
|
|
proj.projector = nil
|
|
end
|
|
elseif IsValid(proj.projector) then
|
|
proj.projector:Remove()
|
|
proj.projector = nil
|
|
end
|
|
end
|
|
|
|
if IsValid(proj.projector) then
|
|
local pos = ent:LocalToWorld(proj.pos)
|
|
local ang = ent:LocalToWorldAngles(proj.ang)
|
|
|
|
if proj.istriggered ~= trigger then
|
|
proj.istriggered = trigger
|
|
|
|
if proj.ontrigger.brightness then
|
|
local brightness = trigger and proj.ontrigger.brightness or proj.brightness
|
|
proj.projector:SetBrightness(brightness * mul)
|
|
end
|
|
|
|
if proj.ontrigger.mat then
|
|
local mat = trigger and proj.ontrigger.mat or proj.mat
|
|
proj.projector:SetTexture(mat)
|
|
end
|
|
|
|
if proj.ontrigger.FarZ then
|
|
local FarZ = trigger and proj.ontrigger.FarZ or proj.FarZ
|
|
proj.projector:SetFarZ(FarZ)
|
|
end
|
|
end
|
|
|
|
proj.projector:SetPos(pos + vel)
|
|
proj.projector:SetAngles(ang)
|
|
proj.projector:Update()
|
|
end
|
|
end
|
|
else
|
|
vtable[i] = nil
|
|
end
|
|
end
|
|
end
|
|
|
|
local function SetupProjectedTextures(ent , vehiclelist)
|
|
ent.Projtexts = {}
|
|
|
|
local proj_col = vehiclelist.ModernLights and Color(215,240,255) or Color(220,205,160)
|
|
|
|
if isvector(vehiclelist.L_HeadLampPos) and isangle(vehiclelist.L_HeadLampAng) then
|
|
ent.Projtexts['FL'] = {
|
|
trigger = 2,
|
|
ontrigger = {
|
|
mat = 'effects/flashlight/headlight_highbeam',
|
|
FarZ = 2000,
|
|
brightness = hdr:GetBool() and 8 or 0.5,
|
|
},
|
|
pos = vehiclelist.L_HeadLampPos,
|
|
ang = vehiclelist.L_HeadLampAng,
|
|
mat = 'effects/flashlight/headlight_lowbeam',
|
|
col = proj_col,
|
|
brightness = 0.5,
|
|
FarZ = 1000,
|
|
NearZ = 75,
|
|
Fov = 80,
|
|
}
|
|
end
|
|
|
|
if isvector(vehiclelist.R_HeadLampPos) and isangle(vehiclelist.R_HeadLampAng) then
|
|
ent.Projtexts['FR'] = {
|
|
trigger = 2,
|
|
ontrigger = {
|
|
mat = 'effects/flashlight/headlight_highbeam',
|
|
FarZ = 2000,
|
|
brightness = hdr:GetBool() and 8 or 0.5,
|
|
},
|
|
pos = vehiclelist.R_HeadLampPos,
|
|
ang = vehiclelist.R_HeadLampAng,
|
|
mat = 'effects/flashlight/headlight_lowbeam',
|
|
col = proj_col,
|
|
brightness = 0.5,
|
|
FarZ = 1000,
|
|
NearZ = 75,
|
|
Fov = 80,
|
|
}
|
|
end
|
|
|
|
if isvector(vehiclelist.L_RearLampPos) and isangle(vehiclelist.L_RearLampAng) then
|
|
ent.Projtexts['RL'] = {
|
|
trigger = 4,
|
|
ontrigger = {
|
|
brightness = hdr:GetBool() and 5 or 0.3,
|
|
},
|
|
pos = vehiclelist.L_RearLampPos,
|
|
ang = vehiclelist.L_RearLampAng,
|
|
mat = 'effects/flashlight/soft',
|
|
col = Color(30,0,0),
|
|
brightness = 0,
|
|
FarZ = 200,
|
|
NearZ = 45,
|
|
Fov = 140,
|
|
}
|
|
|
|
ent.Projtexts['RL2'] = {
|
|
trigger = 5,
|
|
ontrigger = {
|
|
brightness = hdr:GetBool() and 5 or 0.3,
|
|
},
|
|
pos = vehiclelist.L_RearLampPos,
|
|
ang = vehiclelist.L_RearLampAng,
|
|
mat = 'effects/flashlight/soft',
|
|
col = Color(50,50,50),
|
|
brightness = 0,
|
|
FarZ = 200,
|
|
NearZ = 45,
|
|
Fov = 140,
|
|
}
|
|
end
|
|
|
|
if isvector(vehiclelist.R_RearLampPos) and isangle(vehiclelist.R_RearLampAng) then
|
|
ent.Projtexts['RR'] = {
|
|
trigger = 4,
|
|
ontrigger = {
|
|
brightness = hdr:GetBool() and 5 or 0.3,
|
|
},
|
|
pos = vehiclelist.R_RearLampPos,
|
|
ang = vehiclelist.R_RearLampAng,
|
|
mat = 'effects/flashlight/soft',
|
|
col = Color(30,0,0),
|
|
brightness = 0,
|
|
FarZ = 200,
|
|
NearZ = 45,
|
|
Fov = 140,
|
|
}
|
|
|
|
ent.Projtexts['RR2'] = {
|
|
trigger = 5,
|
|
ontrigger = {
|
|
brightness = hdr:GetBool() and 5 or 0.3,
|
|
},
|
|
pos = vehiclelist.R_RearLampPos,
|
|
ang = vehiclelist.R_RearLampAng,
|
|
mat = 'effects/flashlight/soft',
|
|
col = Color(50,50,50),
|
|
brightness = 0,
|
|
FarZ = 200,
|
|
NearZ = 45,
|
|
Fov = 140,
|
|
}
|
|
end
|
|
|
|
ent:CallOnRemove('remove_projected_textures', function(vehicle)
|
|
for _, proj in pairs(ent.Projtexts) do
|
|
local thelamp = proj.projector
|
|
if IsValid(thelamp) then
|
|
thelamp:Remove()
|
|
end
|
|
end
|
|
end)
|
|
end
|
|
|
|
local function SetUpLights(vname , ent)
|
|
ent.Sprites = {}
|
|
|
|
local vehiclelist = list.Get('simfphys_lights')[vname]
|
|
if not vehiclelist then ent.SubMaterials = false return end
|
|
|
|
ent.LightsEMS = vehiclelist.ems_sprites or false
|
|
local hl_col = vehiclelist.ModernLights and {215,240,255} or {220,205,160}
|
|
|
|
SetupProjectedTextures(ent , vehiclelist)
|
|
|
|
if not vehiclelist or not vehiclelist.SubMaterials then
|
|
ent.SubMaterials = false
|
|
else
|
|
ent.SubMaterials = vehiclelist.SubMaterials
|
|
end
|
|
|
|
if istable(vehiclelist.ems_sprites) then
|
|
ent.PixVisEMS = {}
|
|
for i = 1, table.Count(vehiclelist.ems_sprites) do
|
|
ent.PixVisEMS[i] = util.GetPixelVisibleHandle()
|
|
|
|
ent.LightsEMS[i].material = ent.LightsEMS[i].material and Material(ent.LightsEMS[i].material) or mat2
|
|
end
|
|
end
|
|
|
|
if istable(vehiclelist.Headlight_sprites) then
|
|
for _, data in pairs(vehiclelist.Headlight_sprites) do
|
|
local s = {}
|
|
s.PixVis = util.GetPixelVisibleHandle()
|
|
s.trigger = 1
|
|
|
|
if not isvector(data) then
|
|
s.color = data.color and data.color or Color(hl_col[1], hl_col[2], hl_col[3], 255)
|
|
s.material = data.material and Material(data.material) or mat2
|
|
s.size = data.size and data.size or 16
|
|
s.pos = data.pos
|
|
if (data.OnBodyGroups) then s.bodygroups = data.OnBodyGroups end
|
|
table.insert(ent.Sprites, s)
|
|
else
|
|
s.pos = data
|
|
s.color = Color(hl_col[1], hl_col[2], hl_col[3], 255)
|
|
s.material = mat
|
|
s.size = 16
|
|
table.insert(ent.Sprites, s)
|
|
|
|
local s2 = {}
|
|
s2.PixVis = util.GetPixelVisibleHandle()
|
|
s2.trigger = s.trigger
|
|
s2.pos = data
|
|
s2.color = Color(hl_col[1], hl_col[2], hl_col[3], 150)
|
|
s2.material = mat2
|
|
s2.size = 64
|
|
table.insert(ent.Sprites, s2)
|
|
end
|
|
end
|
|
end
|
|
|
|
if istable(vehiclelist.Rearlight_sprites) then
|
|
for _, data in pairs(vehiclelist.Rearlight_sprites) do
|
|
local s = {}
|
|
s.PixVis = util.GetPixelVisibleHandle()
|
|
s.trigger = 1
|
|
|
|
if not isvector(data) then
|
|
s.color = data.color and data.color or Color(255, 0, 0, 125)
|
|
s.material = data.material and Material(data.material) or mat2
|
|
s.size = data.size and data.size or 16
|
|
s.pos = data.pos
|
|
if (data.OnBodyGroups) then s.bodygroups = data.OnBodyGroups end
|
|
table.insert(ent.Sprites, s)
|
|
else
|
|
local s2 = {}
|
|
s2.PixVis = util.GetPixelVisibleHandle()
|
|
s2.trigger = s.trigger
|
|
s2.pos = data
|
|
s2.color = Color(255, 120, 0, 125)
|
|
s2.material = mat2
|
|
s2.size = 12
|
|
table.insert(ent.Sprites, s2)
|
|
|
|
s.pos = data
|
|
s.color = Color(255, 0, 0, 90)
|
|
s.material = mat
|
|
s.size = 32
|
|
table.insert(ent.Sprites, s)
|
|
end
|
|
end
|
|
end
|
|
|
|
if istable(vehiclelist.Brakelight_sprites) then
|
|
for _, data in pairs(vehiclelist.Brakelight_sprites) do
|
|
local s = {}
|
|
s.PixVis = util.GetPixelVisibleHandle()
|
|
s.trigger = 4
|
|
|
|
if not isvector(data) then
|
|
s.color = data.color and data.color or Color(255, 0, 0, 125)
|
|
s.material = data.material and Material(data.material) or mat2
|
|
s.size = data.size and data.size or 16
|
|
s.pos = data.pos
|
|
if (data.OnBodyGroups) then s.bodygroups = data.OnBodyGroups end
|
|
table.insert(ent.Sprites, s)
|
|
else
|
|
s.pos = data
|
|
s.color = Color(255, 0, 0, 90)
|
|
s.material = mat
|
|
s.size = 32
|
|
table.insert(ent.Sprites, s)
|
|
|
|
local s2 = {}
|
|
s2.PixVis = util.GetPixelVisibleHandle()
|
|
s2.trigger = s.trigger
|
|
s2.pos = data
|
|
s2.color = Color(255, 120, 0, 125)
|
|
s2.material = mat2
|
|
s2.size = 12
|
|
table.insert(ent.Sprites, s2)
|
|
end
|
|
end
|
|
end
|
|
|
|
if istable(vehiclelist.Reverselight_sprites) then
|
|
for _, data in pairs(vehiclelist.Reverselight_sprites) do
|
|
local s = {}
|
|
s.PixVis = util.GetPixelVisibleHandle()
|
|
s.trigger = 5
|
|
|
|
if not isvector(data) then
|
|
s.color = data.color and data.color or Color(255, 255, 255, 255)
|
|
s.material = data.material and Material(data.material) or mat2
|
|
s.size = data.size and data.size or 16
|
|
s.pos = data.pos
|
|
if (data.OnBodyGroups) then s.bodygroups = data.OnBodyGroups end
|
|
table.insert(ent.Sprites, s)
|
|
else
|
|
s.pos = data
|
|
s.color = Color(255, 255, 255, 150)
|
|
s.material = mat
|
|
s.size = 12
|
|
table.insert(ent.Sprites, s)
|
|
|
|
local s2 = {}
|
|
s2.PixVis = util.GetPixelVisibleHandle()
|
|
s2.trigger = s.trigger
|
|
s2.pos = data
|
|
s2.color = Color(255, 255, 255, 80)
|
|
s2.material = mat2
|
|
s2.size = 25
|
|
table.insert(ent.Sprites, s2)
|
|
end
|
|
end
|
|
end
|
|
|
|
if istable(vehiclelist.FrontMarker_sprites) then
|
|
for _, data in pairs(vehiclelist.FrontMarker_sprites) do
|
|
local s = {}
|
|
s.PixVis = util.GetPixelVisibleHandle()
|
|
s.trigger = 1
|
|
|
|
if isvector(data) then
|
|
s.pos = data
|
|
s.color = Color(200, 100, 0, 150)
|
|
s.material = mat
|
|
s.size = 12
|
|
table.insert(ent.Sprites, s)
|
|
end
|
|
end
|
|
end
|
|
|
|
if istable(vehiclelist.RearMarker_sprites) then
|
|
for _, data in pairs(vehiclelist.RearMarker_sprites) do
|
|
local s = {}
|
|
s.PixVis = util.GetPixelVisibleHandle()
|
|
s.trigger = 1
|
|
|
|
if isvector(data) then
|
|
s.pos = data
|
|
s.color = Color(205, 0, 0, 150)
|
|
s.material = mat
|
|
s.size = 12
|
|
table.insert(ent.Sprites, s)
|
|
end
|
|
end
|
|
end
|
|
|
|
if istable(vehiclelist.Headlamp_sprites) then
|
|
for _, data in pairs(vehiclelist.Headlamp_sprites) do
|
|
local s = {}
|
|
s.PixVis = util.GetPixelVisibleHandle()
|
|
s.trigger = 2
|
|
|
|
if not isvector(data) then
|
|
s.color = data.color and data.color or Color(hl_col[1], hl_col[2], hl_col[3], 255)
|
|
s.material = data.material and Material(data.material) or mat2
|
|
s.size = data.size and data.size or 16
|
|
s.pos = data.pos
|
|
if (data.OnBodyGroups) then s.bodygroups = data.OnBodyGroups end
|
|
table.insert(ent.Sprites, s)
|
|
else
|
|
s.pos = data
|
|
s.color = Color(hl_col[1], hl_col[2], hl_col[3], 255)
|
|
s.material = mat
|
|
s.size = 16
|
|
table.insert(ent.Sprites, s)
|
|
|
|
local s2 = {}
|
|
s2.PixVis = util.GetPixelVisibleHandle()
|
|
s2.trigger = s.trigger
|
|
s2.pos = data
|
|
s2.color = Color(hl_col[1], hl_col[2], hl_col[3], 150)
|
|
s2.material = mat2
|
|
s2.size = 64
|
|
table.insert(ent.Sprites, s2)
|
|
end
|
|
end
|
|
end
|
|
|
|
if istable(vehiclelist.FogLight_sprites) then
|
|
for _, data in pairs(vehiclelist.FogLight_sprites) do
|
|
local s = {}
|
|
s.PixVis = util.GetPixelVisibleHandle()
|
|
s.trigger = 3
|
|
|
|
if not isvector(data) then
|
|
s.color = data.color and data.color or Color(hl_col[1], hl_col[2], hl_col[3], 255)
|
|
s.material = data.material and Material(data.material) or mat2
|
|
s.size = data.size and data.size or 32
|
|
s.pos = data.pos
|
|
if (data.OnBodyGroups) then s.bodygroups = data.OnBodyGroups end
|
|
table.insert(ent.Sprites, s)
|
|
else
|
|
s.pos = data
|
|
s.color = Color(hl_col[1], hl_col[2], hl_col[3], 200)
|
|
s.material = mat2
|
|
s.size = 32
|
|
table.insert(ent.Sprites, s)
|
|
end
|
|
end
|
|
end
|
|
|
|
if istable(vehiclelist.Turnsignal_sprites) then
|
|
ent.HasTurnSignals = true
|
|
|
|
if istable(vehiclelist.Turnsignal_sprites.Left) then
|
|
for _, data in pairs(vehiclelist.Turnsignal_sprites.Left) do
|
|
local s = {}
|
|
s.PixVis = util.GetPixelVisibleHandle()
|
|
s.trigger = 6
|
|
|
|
if not isvector(data) then
|
|
s.color = data.color and data.color or Color(200, 100, 0, 255)
|
|
s.material = data.material and Material(data.material) or mat2
|
|
s.size = data.size and data.size or 24
|
|
s.pos = data.pos
|
|
if (data.OnBodyGroups) then s.bodygroups = data.OnBodyGroups end
|
|
table.insert(ent.Sprites, s)
|
|
else
|
|
s.pos = data
|
|
s.color = Color(255, 150, 0, 150)
|
|
s.material = mat
|
|
s.size = 20
|
|
table.insert(ent.Sprites, s)
|
|
|
|
local s2 = {}
|
|
s2.PixVis = util.GetPixelVisibleHandle()
|
|
s2.trigger = s.trigger
|
|
s2.pos = data
|
|
s2.color = Color(200, 100, 0, 80)
|
|
s2.material = mat2
|
|
s2.size = 70
|
|
table.insert(ent.Sprites, s2)
|
|
end
|
|
end
|
|
end
|
|
|
|
if istable(vehiclelist.Turnsignal_sprites.Right) then
|
|
for _, data in pairs(vehiclelist.Turnsignal_sprites.Right) do
|
|
local s = {}
|
|
s.PixVis = util.GetPixelVisibleHandle()
|
|
s.trigger = 7
|
|
|
|
if not isvector(data) then
|
|
s.color = data.color and data.color or Color(200, 100, 0, 255)
|
|
s.material = data.material and Material(data.material) or mat2
|
|
s.size = data.size and data.size or 24
|
|
s.pos = data.pos
|
|
if (data.OnBodyGroups) then s.bodygroups = data.OnBodyGroups end
|
|
table.insert(ent.Sprites, s)
|
|
else
|
|
s.pos = data
|
|
s.color = Color(255, 150, 0, 150)
|
|
s.material = mat
|
|
s.size = 20
|
|
table.insert(ent.Sprites, s)
|
|
|
|
local s2 = {}
|
|
s2.PixVis = util.GetPixelVisibleHandle()
|
|
s2.trigger = s.trigger
|
|
s2.pos = data
|
|
s2.color = Color(200, 100, 0, 80)
|
|
s2.material = mat2
|
|
s2.size = 70
|
|
table.insert(ent.Sprites, s2)
|
|
end
|
|
end
|
|
end
|
|
|
|
if istable(vehiclelist.Turnsignal_sprites.TurnBrakeLeft) then
|
|
ent.HasSpecialTurnSignals = true
|
|
for _, data in pairs(vehiclelist.Turnsignal_sprites.TurnBrakeLeft) do
|
|
local s = {}
|
|
s.PixVis = util.GetPixelVisibleHandle()
|
|
s.trigger = 8
|
|
|
|
if not isvector(data) then
|
|
s.color = data.color and data.color or Color(255, 0, 0, 125)
|
|
s.material = data.material and Material(data.material) or mat2
|
|
s.size = data.size and data.size or 16
|
|
s.pos = data.pos
|
|
if (data.OnBodyGroups) then s.bodygroups = data.OnBodyGroups end
|
|
table.insert(ent.Sprites, s)
|
|
else
|
|
s.pos = data
|
|
s.color = Color(255, 60, 0, 90)
|
|
s.material = mat
|
|
s.size = 40
|
|
table.insert(ent.Sprites, s)
|
|
|
|
local s2 = {}
|
|
s2.PixVis = util.GetPixelVisibleHandle()
|
|
s2.trigger = s.trigger
|
|
s2.pos = data
|
|
s2.color = Color(255, 120, 0, 125)
|
|
s2.material = mat2
|
|
s2.size = 16
|
|
table.insert(ent.Sprites, s2)
|
|
end
|
|
end
|
|
end
|
|
|
|
if istable(vehiclelist.Turnsignal_sprites.TurnBrakeRight) then
|
|
ent.HasSpecialTurnSignals = true
|
|
for _, data in pairs(vehiclelist.Turnsignal_sprites.TurnBrakeRight) do
|
|
local s = {}
|
|
s.PixVis = util.GetPixelVisibleHandle()
|
|
s.trigger = 9
|
|
|
|
if not isvector(data) then
|
|
s.color = data.color and data.color or Color(255, 0, 0, 125)
|
|
s.material = data.material and Material(data.material) or mat2
|
|
s.size = data.size and data.size or 16
|
|
s.pos = data.pos
|
|
if (data.OnBodyGroups) then s.bodygroups = data.OnBodyGroups end
|
|
table.insert(ent.Sprites, s)
|
|
else
|
|
s.pos = data
|
|
s.color = Color(255, 60, 0, 90)
|
|
s.material = mat
|
|
s.size = 40
|
|
table.insert(ent.Sprites, s)
|
|
|
|
local s2 = {}
|
|
s2.PixVis = util.GetPixelVisibleHandle()
|
|
s2.trigger = s.trigger
|
|
s2.pos = data
|
|
s2.color = Color(255, 120, 0, 125)
|
|
s2.material = mat2
|
|
s2.size = 16
|
|
table.insert(ent.Sprites, s2)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
ent.EnableLights = true
|
|
table.insert(vtable, ent)
|
|
end
|
|
|
|
local function DrawEMSLights(ent)
|
|
local Time = CurTime()
|
|
|
|
if ent.LightsEMS then
|
|
|
|
for i = 1, table.Count(ent.LightsEMS) do
|
|
if not ent.LightsEMS[i].Damaged then
|
|
|
|
local size = ent.LightsEMS[i].size
|
|
local LightPos = ent:LocalToWorld(ent.LightsEMS[i].pos)
|
|
local Visible = util.PixelVisible(LightPos, 4, ent.PixVisEMS[i])
|
|
local mat = ent.LightsEMS[i].material
|
|
local numcolors = table.Count(ent.LightsEMS[i].Colors)
|
|
|
|
ent.LightsEMS[i].Timer = ent.LightsEMS[i].Timer or 0
|
|
ent.LightsEMS[i].Index = ent.LightsEMS[i].Index or 0
|
|
|
|
if numcolors > 1 and ent.LightsEMS[i].Timer < Time then
|
|
ent.LightsEMS[i].Timer = Time + ent.LightsEMS[i].Speed
|
|
ent.LightsEMS[i].Index = ent.LightsEMS[i].Index + 1
|
|
|
|
if ent.LightsEMS[i].Index > numcolors then
|
|
ent.LightsEMS[i].Index = 1
|
|
end
|
|
end
|
|
|
|
local col = ent.LightsEMS[i].Colors[ent.LightsEMS[i].Index]
|
|
|
|
if ent.LightsEMS[i].OnBodyGroups then
|
|
Visible = ent:BodyGroupIsValid(ent.LightsEMS[i].OnBodyGroups) and Visible or 0
|
|
end
|
|
|
|
if Visible and Visible >= 0.6 and col ~= Color(0,0,0,0) then
|
|
Visible = (Visible - 0.6) / 0.4
|
|
|
|
render.SetMaterial(mat)
|
|
-- they are way too dim by default
|
|
-- TODO: render specific 3d sprites from photon along with halos
|
|
for _ = 1, 5 do
|
|
render.DrawSprite(LightPos, size, size, Color(col['r'], col['g'], col['b'], col['a'] * Visible))
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
hook.Add('Think', 'simfphys_lights_managment', function()
|
|
local curtime = CurTime()
|
|
|
|
ManageProjTextures()
|
|
|
|
if NextCheck < curtime then
|
|
NextCheck = curtime + checkinterval
|
|
|
|
for _, ent in pairs(ents.FindByClass('gmod_sent_vehicle_fphysics_base')) do
|
|
if ent.EnableLights ~= true then
|
|
local listname = ent:GetLights_List()
|
|
|
|
if listname then
|
|
if listname ~= 'no_lights' then
|
|
SetUpLights(listname, ent)
|
|
else
|
|
ent.EnableLights = true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end)
|
|
|
|
hook.Add('PostDrawTranslucentRenderables', 'simfphys_draw_sprites', function()
|
|
if SpritesDisabled then return end
|
|
if vtable then
|
|
for _, ent in pairs(vtable) do
|
|
if IsValid(ent) and istable(ent.triggers) and ent:GetPos():DistToSqr(EyePos()) < maxLightSpriteDist then
|
|
if ent:GetEMSEnabled() then
|
|
DrawEMSLights(ent)
|
|
end
|
|
|
|
for _, sprite in pairs(ent.Sprites) do
|
|
if not sprite.Damaged then
|
|
local regTrigger = ent.triggers[ sprite.trigger ]
|
|
local typeSpecial = (sprite.trigger == 8 and ent.triggers[ 6 ]) or (sprite.trigger == 9 and ent.triggers[7])
|
|
if typeSpecial then regTrigger = false end
|
|
|
|
if regTrigger or typeSpecial then
|
|
local LightPos = ent:LocalToWorld(sprite.pos)
|
|
local Visible = util.PixelVisible(LightPos, 4, sprite.PixVis)
|
|
local s_col = sprite.color
|
|
local s_mat = sprite.material
|
|
local s_size = sprite.size
|
|
|
|
if sprite.bodygroups then
|
|
Visible = BodyGroupIsValid(sprite.bodygroups, ent) and Visible or 0
|
|
end
|
|
|
|
if Visible and Visible >= 0.6 then
|
|
Visible = (Visible - 0.6) / 0.4
|
|
render.SetMaterial(s_mat)
|
|
|
|
local c_Alpha = s_col['a'] * Visible
|
|
if (sprite.trigger == 6 or sprite.trigger == 7 or typeSpecial) and not ent.forceFlasher then
|
|
c_Alpha = c_Alpha * (ent:GetFlasher() ^ 7)
|
|
end
|
|
|
|
render.DrawSprite(LightPos, s_size, s_size, Color(s_col['r'], s_col['g'], s_col['b'], c_Alpha))
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end)
|
|
|
|
local glassimpact = Sound('Glass.BulletImpact')
|
|
local function spritedamage(length)
|
|
if not AllowVisualDamage then return end
|
|
|
|
local veh = net.ReadEntity()
|
|
if not IsValid(veh) then return end
|
|
|
|
local pos = veh:LocalToWorld(net.ReadVector())
|
|
local Rad = net.ReadBool() and 26 or 8
|
|
local curtime = CurTime()
|
|
|
|
veh.NextImpactsnd = veh.NextImpactsnd or 0
|
|
|
|
if istable(veh.Sprites) then
|
|
|
|
for i, sprite in pairs(veh.Sprites) do
|
|
|
|
if not sprite.Damaged then
|
|
|
|
local spritepos = veh:LocalToWorld(sprite.pos)
|
|
local Dist = (spritepos - pos):Length()
|
|
|
|
if Dist < Rad then
|
|
veh.Sprites[i].Damaged = true
|
|
|
|
if sprite.trigger >= 6 then
|
|
veh.turnsignals_damaged = true
|
|
end
|
|
|
|
local effectdata = EffectData()
|
|
effectdata:SetOrigin(spritepos)
|
|
util.Effect('GlassImpact', effectdata, true, true)
|
|
|
|
if veh.NextImpactsnd < curtime then
|
|
veh.NextImpactsnd = curtime + 0.05
|
|
sound.Play(glassimpact, spritepos, 75)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if istable(veh.Projtexts) then
|
|
|
|
for i, proj in pairs(veh.Projtexts) do
|
|
|
|
if not proj.Damaged then
|
|
|
|
local lamppos = veh:LocalToWorld(proj.pos)
|
|
local Dist = (lamppos - pos):Length()
|
|
|
|
if Dist < Rad * 2 then
|
|
veh.Projtexts[i].Damaged = true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if istable(veh.LightsEMS) then
|
|
|
|
for i = 1, table.Count(veh.LightsEMS) do
|
|
|
|
if not veh.LightsEMS[i].Damaged then
|
|
|
|
local spritepos = veh:LocalToWorld(veh.LightsEMS[i].pos)
|
|
local Dist = (spritepos - pos):Length()
|
|
|
|
if Dist < Rad then
|
|
veh.LightsEMS[i].Damaged = true
|
|
|
|
local effectdata = EffectData()
|
|
effectdata:SetOrigin(spritepos)
|
|
util.Effect('GlassImpact', effectdata, true, true)
|
|
|
|
if veh.NextImpactsnd < curtime then
|
|
veh.NextImpactsnd = curtime + 0.05
|
|
sound.Play(glassimpact, spritepos, 75)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
net.Receive('simfphys_spritedamage', spritedamage)
|
|
|
|
local function spriterepair(length)
|
|
local veh = net.ReadEntity()
|
|
|
|
if not IsValid(veh) then return end
|
|
|
|
veh.turnsignals_damaged = nil
|
|
|
|
if istable(veh.Sprites) then
|
|
for i in pairs(veh.Sprites) do
|
|
veh.Sprites[i].Damaged = false
|
|
end
|
|
end
|
|
|
|
if istable(veh.Projtexts) then
|
|
for i in pairs(veh.Projtexts) do
|
|
veh.Projtexts[i].Damaged = false
|
|
end
|
|
end
|
|
|
|
if istable(veh.LightsEMS) then
|
|
for i = 1, table.Count(veh.LightsEMS) do
|
|
veh.LightsEMS[i].Damaged = false
|
|
end
|
|
end
|
|
end
|
|
net.Receive('simfphys_lightsfixall', spriterepair)
|
|
|
|
|
|
local function turnSignal(ent, turnmode)
|
|
if not IsValid(ent) then return end
|
|
|
|
ent.lastTurnMode = turnmode
|
|
|
|
if turnmode == 0 then
|
|
ent.signal_left = false
|
|
ent.signal_right = false
|
|
|
|
local vehicle = LocalPlayer():GetVehicle()
|
|
if IsValid(vehicle) and IsValid(vehicle.vehiclebase) and vehicle.vehiclebase == ent then
|
|
vehicle.vehiclebase:EmitSound('simulated_vehicles/sfx/turnsignal_end.ogg')
|
|
end
|
|
end
|
|
|
|
if turnmode == 1 then
|
|
ent.signal_left = true
|
|
ent.signal_right = true
|
|
end
|
|
|
|
if turnmode == 2 then
|
|
ent.signal_left = true
|
|
ent.signal_right = false
|
|
end
|
|
|
|
if turnmode == 3 then
|
|
ent.signal_left = false
|
|
ent.signal_right = true
|
|
end
|
|
end
|
|
net.Receive('simfphys_turnsignal', function()
|
|
turnSignal(net.ReadEntity(), net.ReadInt(32))
|
|
end)
|
|
|
|
local wasNight = false
|
|
timer.Create('simfphys.updateProjectorsAtNight', 5, 0, function()
|
|
local isNight = StormFox2.Time.IsNight()
|
|
if isNight == wasNight then return end
|
|
wasNight = isNight
|
|
|
|
for i, ent in pairs(vtable) do
|
|
if IsValid(ent) then
|
|
for _, proj in pairs(ent.Projtexts) do
|
|
if IsValid(proj.projector) then
|
|
proj.projector:Remove()
|
|
proj.projector = nil
|
|
proj.LampsActive = nil
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end)
|
|
|
|
hook.Add('NotifyShouldTransmit', 'simfphys.lighting', function(ent, transmit)
|
|
if not transmit or not ent.SubMaterials then return end
|
|
|
|
timer.Simple(0, function()
|
|
UpdateSubMats(ent)
|
|
end)
|
|
end)
|
|
|
|
-- local function setFlasher(veh, on)
|
|
-- if not IsValid(veh) then return end
|
|
-- veh.signal_left = on
|
|
-- veh.signal_right = on
|
|
-- veh.forceFlasher = on
|
|
-- end
|
|
|
|
-- netstream.Hook('simfphys.flash', function(veh, times)
|
|
-- for i = 0, times - 1 do
|
|
-- timer.Simple(i * 0.25, function() setFlasher(veh, true) end)
|
|
-- timer.Simple(i * 0.25 + 0.15, function() setFlasher(veh, false) end)
|
|
-- end
|
|
-- timer.Simple(times * 0.25 + 0.15, function()
|
|
-- turnSignal(veh, veh.lastTurnMode or 0)
|
|
-- end)
|
|
-- end)
|