EFFECT.SmokeMat = { "particle/smokesprites_0001", "particle/smokesprites_0002", "particle/smokesprites_0003", "particle/smokesprites_0004", "particle/smokesprites_0005", "particle/smokesprites_0006", "particle/smokesprites_0007", "particle/smokesprites_0008", "particle/smokesprites_0009", "particle/smokesprites_0010", "particle/smokesprites_0011", "particle/smokesprites_0012", "particle/smokesprites_0013", "particle/smokesprites_0014", "particle/smokesprites_0015", "particle/smokesprites_0016" } EFFECT.DustMat = { "effects/lvs_base/particle_debris_01", "effects/lvs_base/particle_debris_02", } local SmokeMat = EFFECT.SmokeMat local function MakeDustParticle( emitter, emitter3D, pos, vel, r, g, b ) local particle = emitter:Add( SmokeMat[ math.random(1,#SmokeMat) ], pos ) if not particle then return end particle:SetVelocity( vel ) particle:SetDieTime( 0.4 ) particle:SetAirResistance( 0 ) particle:SetStartAlpha( 255 ) particle:SetStartSize( 20 ) particle:SetEndSize( 30 ) particle:SetRollDelta( math.Rand(-6,6) ) particle:SetColor( r, g, b ) particle:SetGravity( Vector(0,0,-600) ) particle:SetCollide( false ) particle:SetNextThink( CurTime() ) particle:SetThinkFunction( function( p ) if not IsValid( emitter3D ) then return end p:SetNextThink( CurTime() + 0.05 ) local pos = p:GetPos() local vel = p:GetVelocity() local traceData = { start = pos, endpos = pos + Vector(0,0,vel.z) * 0.06, mask = MASK_SOLID_BRUSHONLY, } local trace = util.TraceLine( traceData ) if not trace.Hit then return end p:SetEndSize( 0 ) p:SetDieTime( 0 ) local pHit = emitter3D:Add( SmokeMat[ math.random(1,#SmokeMat) ], trace.HitPos + trace.HitNormal ) pHit:SetStartSize( 15 ) pHit:SetEndSize( 15 ) pHit:SetDieTime( math.Rand(5,6) ) pHit:SetStartAlpha( 50 ) pHit:SetEndAlpha( 0 ) pHit:SetColor( p:GetColor() ) local Ang = trace.HitNormal:Angle() Ang:RotateAroundAxis( trace.HitNormal, math.Rand(-180,180) ) pHit:SetAngles( Ang ) end ) end function EFFECT:Init( data ) local pos = data:GetOrigin() local ent = data:GetEntity() if not IsValid( ent ) then return end local dir = data:GetNormal() local scale = data:GetMagnitude() local speed = ent:GetVelocity():LengthSqr() local tooSlow = speed < 30000 local tooFast = speed > 400000 local underwater = data:GetFlags() == 1 local start = ent:GetPos() local emitter = ent:GetParticleEmitter( start ) local emitter3D = ent:GetParticleEmitter3D( start ) local VecCol local LightColor = render.GetLightColor( pos + dir ) if underwater then VecCol = Vector(1,1.2,1.4) * (0.06 + (0.2126 * LightColor.r) + (0.7152 * LightColor.g) + (0.0722 * LightColor.b)) * 1000 else VecCol = Vector(0.3,0.25,0.15) * (0.1 + (0.2126 * LightColor.r) + (0.7152 * LightColor.g) + (0.0722 * LightColor.b)) * 1000 end VecCol.x = math.min( VecCol.x, 255 ) VecCol.y = math.min( VecCol.y, 255 ) VecCol.z = math.min( VecCol.z, 255 ) local DieTime = math.Rand(0.8,1.6) if not tooSlow then for i = 1, 5 do local particle = emitter:Add( self.DustMat[ math.random(1,#self.DustMat) ] , pos ) if not particle then continue end particle:SetVelocity( (dir * 50 * i + VectorRand() * 25) * scale ) particle:SetDieTime( (i / 8) * DieTime ) particle:SetAirResistance( 10 ) particle:SetStartAlpha( 255 ) particle:SetStartSize( 10 * scale ) particle:SetEndSize( 20 * i * scale ) particle:SetRollDelta( math.Rand(-1,1) ) particle:SetColor( VecCol.r, VecCol.g, VecCol.b ) particle:SetGravity( Vector(0,0,-600) * scale ) particle:SetCollide( false ) end end for i = 1, 5 do local particle = emitter:Add( underwater and "effects/splash4" or self.SmokeMat[ math.random(1,#self.SmokeMat) ] , pos ) if not particle then continue end particle:SetVelocity( (dir * 50 * i + VectorRand() * 40) * scale ) particle:SetDieTime( (i / 8) * DieTime ) particle:SetAirResistance( 10 ) particle:SetStartAlpha( underwarter and 150 or 255 ) particle:SetStartSize( 10 * scale ) particle:SetEndSize( 20 * i * scale ) particle:SetRollDelta( math.Rand(-1,1) ) particle:SetColor( VecCol.r, VecCol.g, VecCol.b ) particle:SetGravity( Vector(0,0,-600) * scale ) particle:SetCollide( false ) if underwater or tooFast then continue end particle:SetNextThink( CurTime() ) particle:SetThinkFunction( function( p ) if not IsValid( ent ) or not IsValid( emitter ) or not IsValid( emitter3D ) then return end p:SetNextThink( CurTime() + 0.05 ) local pos = p:GetPos() local vel = p:GetVelocity() local dir = vel:GetNormalized() local speed = vel:Length() local traceData = { start = pos, endpos = pos + dir * speed * 0.06, whitelist = true, filter = ent, } local trace = util.TraceLine( traceData ) if not trace.Hit then return end if tooSlow then p:SetEndSize( 0 ) p:SetDieTime( 0 ) end MakeDustParticle( emitter, emitter3D, trace.HitPos - trace.HitNormal * 10, trace.HitNormal * 20 + VectorRand() * 40, p:GetColor() ) end ) end end function EFFECT:Think() return false end function EFFECT:Render() end