Files
2026-03-31 10:27:04 +03:00

312 lines
7.5 KiB
Lua

AddCSLuaFile()
ENT.Type = "anim"
ENT.PrintName = "Fire"
ENT.Author = "Luna"
ENT.Information = "Luna's Vehicle Script"
ENT.Category = "[LVS]"
ENT.Spawnable = false
ENT.AdminOnly = false
ENT.RenderGroup = RENDERGROUP_BOTH
function ENT:SetupDataTables()
self:NetworkVar( "Entity", 0, "Emitter" )
self:NetworkVar( "Float", 0, "LifeTime" )
self:NetworkVar( "Float", 1, "DieTime" )
if SERVER then
self:SetLifeTime( math.Rand(8,12) )
end
end
function ENT:GetSize()
return math.min( (self:GetDieTime() - CurTime()) / self:GetLifeTime() * 10, 1) ^ 2
end
if SERVER then
function ENT:SpawnFunction( ply, tr, ClassName )
if not tr.Hit then return end
local ent = ents.Create( ClassName )
ent:SetPos( tr.HitPos + tr.HitNormal )
ent:SetAngles( tr.HitNormal:Angle() + Angle(90,0,0) )
ent:Spawn()
ent:Activate()
return ent
end
function ENT:SetDamage( num ) self._dmg = num end
function ENT:SetAttacker( ent ) self._attacker = ent end
function ENT:GetAttacker() return self._attacker or NULL end
function ENT:GetDamage() return (self._dmg or 3) end
function ENT:SendDamage( victim, pos )
if not IsValid( victim ) then return end
if victim:IsPlayer() and victim:InVehicle() and victim:GetCollisionGroup() ~= COLLISION_GROUP_PLAYER then return end
local attacker = self:GetAttacker()
local dmg = DamageInfo()
dmg:SetDamage( self:GetDamage() )
dmg:SetAttacker( IsValid( attacker ) and attacker or game.GetWorld() )
dmg:SetInflictor( self )
dmg:SetDamageType( DMG_BURN + DMG_PREVENT_PHYSICS_FORCE )
dmg:SetDamagePosition( pos or vector_origin )
victim:TakeDamageInfo( dmg )
end
function ENT:Initialize()
self:SetMoveType( MOVETYPE_NONE )
self:SetSolid( SOLID_NONE )
self:DrawShadow( false )
self:SetDieTime( CurTime() + self:GetLifeTime() )
if self:WaterLevel() > 0 then self:Remove() end
end
function ENT:Think()
local T = CurTime()
self:NextThink( T )
if T > self:GetDieTime() then
self:Remove()
end
local EntTable = self:GetTable()
if (EntTable._NextDamage or 0) < T then
EntTable._NextDamage = T + 0.5
local Size = self:GetSize()
local startpos = self:LocalToWorld( Vector(0,0,1) )
local endpos = self:LocalToWorld( Vector(0,0,Size * 120) )
local maxs = Vector(80,80,0) * Size
local mins = Vector(-80,-80,0) * Size
local trace = util.TraceHull( {
start = startpos,
endpos = endpos,
maxs = maxs,
mins = mins,
filter = self,
} )
if not trace.Hit or not IsValid( trace.Entity ) then return true end
self:SendDamage( trace.Entity, trace.HitPos, 1 )
end
return true
end
function ENT:PhysicsCollide( data, physobj )
end
function ENT:OnRemove()
end
return
end
local GlowMat = Material( "sprites/light_glow02_add" )
local Materials = {
"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"
}
function ENT:Initialize()
self.snd = CreateSound(self, "ambient/fire/fire_small_loop"..math.random(1,2)..".wav")
self.snd:SetSoundLevel( 60 )
self.snd:Play()
end
function ENT:Draw( flags )
end
function ENT:DrawTranslucent( flags )
local Size = self:GetSize() * 200
render.SetMaterial( GlowMat )
render.DrawSprite( self:GetPos(), Size, Size, Color( 255, 150, 75, 255) )
end
function ENT:SoundStop()
if self.snd then
self.snd:Stop()
end
end
function ENT:OnRemove()
self:SoundStop()
self:StopEmitter()
self:StopEmitter3D()
end
function ENT:GetParticleEmitter( Pos )
local EntTable = self:GetTable()
local T = CurTime()
if IsValid( EntTable.Emitter ) and (EntTable.EmitterTime or 0) > T then
return EntTable.Emitter
end
self:StopEmitter()
EntTable.Emitter = ParticleEmitter( Pos, false )
EntTable.EmitterTime = T + 2
return EntTable.Emitter
end
function ENT:EmitFire()
local Pos = self:GetPos()
local Dir = self:GetUp()
local emitter = self:GetParticleEmitter( Pos )
local emitter3D = self:GetParticleEmitter3D( Pos )
if not IsValid( emitter ) or not IsValid( emitter3D ) then return end
local particle = emitter3D:Add( "effects/lvs_base/flamelet"..math.random(1,5), Pos )
local Size = self:GetSize()
if particle then
particle:SetStartSize( 20 * Size )
particle:SetEndSize( 60 * Size )
particle:SetDieTime( math.Rand(0.5,1) )
particle:SetStartAlpha( 255 )
particle:SetEndAlpha( 0 )
particle:SetRollDelta( math.Rand(-2,2) )
particle:SetAngles( Dir:Angle() )
end
local fparticle = emitter:Add( "effects/lvs_base/fire", Pos )
if fparticle then
fparticle:SetVelocity( (VectorRand() * 30 + Dir * 100) * Size )
fparticle:SetDieTime( math.Rand(0.6,0.8) )
fparticle:SetAirResistance( 0 )
fparticle:SetStartAlpha( 255 )
fparticle:SetEndAlpha( 255 )
fparticle:SetStartSize( 40 * Size )
fparticle:SetEndSize( 0 )
fparticle:SetRollDelta( math.Rand(-2,2) )
fparticle:SetColor( 255,255,255 )
fparticle:SetGravity( Vector( 0, 0, 100 ) * Size )
fparticle:SetCollide( false )
end
local fparticle = emitter:Add( "effects/lvs_base/flamelet"..math.random(1,5), Pos )
if fparticle then
fparticle:SetVelocity( VectorRand() * 25 * Size )
fparticle:SetDieTime( math.Rand(0.4,0.8) )
fparticle:SetStartAlpha( 150 )
fparticle:SetEndAlpha( 0 )
fparticle:SetStartSize( 0 )
fparticle:SetEndSize( math.Rand(60,80) * Size )
fparticle:SetColor( 255, 255, 255 )
fparticle:SetGravity( Vector(0,0,100) * Size )
fparticle:SetRollDelta( math.Rand(-2,2) )
fparticle:SetAirResistance( 0 )
end
for i = 0, 6 do
local eparticle = emitter:Add( "effects/fire_embers"..math.random(1,2), Pos )
if not eparticle then continue end
eparticle:SetVelocity( VectorRand() * 400 * Size )
eparticle:SetDieTime( math.Rand(0.4,0.6) )
eparticle:SetStartAlpha( 255 )
eparticle:SetEndAlpha( 0 )
eparticle:SetStartSize( 20 * Size )
eparticle:SetEndSize( 0 )
eparticle:SetColor( 255, 255, 255 )
eparticle:SetGravity( Vector(0,0,600) * Size )
eparticle:SetRollDelta( math.Rand(-8,8) )
eparticle:SetAirResistance( 300 * Size )
end
if math.random(1,3) ~= 1 then return end
local sparticle = emitter:Add( Materials[ math.random(1, #Materials ) ], Pos )
if sparticle then
sparticle:SetVelocity( Dir * 400 * Size )
sparticle:SetDieTime( math.Rand(2,4) )
sparticle:SetAirResistance( 500 )
sparticle:SetStartAlpha( 125 )
sparticle:SetStartSize( 0 )
sparticle:SetEndSize( 200 * Size )
sparticle:SetRoll( math.Rand(-3,3) )
sparticle:SetRollDelta( math.Rand(-1,1) )
sparticle:SetColor( 0, 0, 0 )
sparticle:SetGravity( Vector( 0, 0, 800 ) * Size )
sparticle:SetCollide( false )
end
end
function ENT:Think()
self:EmitFire()
self:SetNextClientThink( CurTime() + math.Rand(0.01,0.4) )
return true
end
function ENT:GetParticleEmitter3D( Pos )
local EntTable = self:GetTable()
local T = CurTime()
if IsValid( EntTable.Emitter3D ) and (EntTable.EmitterTime3D or 0) > T then
return EntTable.Emitter3D
end
self:StopEmitter3D()
EntTable.Emitter3D = ParticleEmitter( Pos, true )
EntTable.EmitterTime3D = T + 2
return EntTable.Emitter3D
end
function ENT:StopEmitter()
if not IsValid( self.Emitter ) then return end
self.Emitter:Finish()
end
function ENT:StopEmitter3D()
if not IsValid( self.Emitter3D ) then return end
self.Emitter3D:Finish()
end