add sborka
This commit is contained in:
193
garrysmod/addons/tacrp/lua/entities/tacrp_smoke_cloud.lua
Normal file
193
garrysmod/addons/tacrp/lua/entities/tacrp_smoke_cloud.lua
Normal file
@@ -0,0 +1,193 @@
|
||||
ENT.Type = "anim"
|
||||
ENT.Base = "base_entity"
|
||||
ENT.PrintName = "Smoke Cloud"
|
||||
ENT.Author = ""
|
||||
ENT.Information = ""
|
||||
ENT.Spawnable = false
|
||||
ENT.AdminSpawnable = false
|
||||
|
||||
local smokeimages = {"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"}
|
||||
|
||||
local function GetSmokeImage()
|
||||
return smokeimages[math.random(#smokeimages)]
|
||||
end
|
||||
|
||||
ENT.TacRPSmoke = true
|
||||
ENT.Particles = nil
|
||||
ENT.SmokeRadius = 300
|
||||
ENT.SmokeColor = Color(150, 150, 150)
|
||||
ENT.BillowTime = 1
|
||||
ENT.Life = 20
|
||||
|
||||
-- Cheap maths
|
||||
ENT.SmokeRadiusSqr = ENT.SmokeRadius * ENT.SmokeRadius
|
||||
|
||||
AddCSLuaFile()
|
||||
|
||||
function ENT:Initialize()
|
||||
local mins, maxs = Vector(-self.SmokeRadius / 2, -self.SmokeRadius / 2, -self.SmokeRadius / 2), Vector(self.SmokeRadius / 2, self.SmokeRadius / 2, self.SmokeRadius / 2)
|
||||
if SERVER then
|
||||
self:PhysicsInitSphere(self.SmokeRadius / 2)
|
||||
self:SetCollisionBounds(mins, maxs)
|
||||
self:SetMoveType( MOVETYPE_NONE )
|
||||
self:DrawShadow( false )
|
||||
else
|
||||
|
||||
table.insert(TacRP.ClientSmokeCache, self)
|
||||
|
||||
local emitter = ParticleEmitter(self:GetPos())
|
||||
|
||||
self.Particles = {}
|
||||
|
||||
local amt = 20
|
||||
|
||||
for i = 1, amt do
|
||||
local smoke = emitter:Add(GetSmokeImage(), self:GetPos())
|
||||
smoke:SetVelocity( VectorRand() * 8 + (Angle(0, i * (360 / amt), 0):Forward() * 250) )
|
||||
smoke:SetStartAlpha( 0 )
|
||||
smoke:SetEndAlpha( 255 )
|
||||
smoke:SetStartSize( 0 )
|
||||
smoke:SetEndSize( self.SmokeRadius )
|
||||
smoke:SetRoll( math.Rand(-180, 180) )
|
||||
smoke:SetRollDelta( math.Rand(-0.2,0.2) )
|
||||
smoke:SetColor( self.SmokeColor.r, self.SmokeColor.g, self.SmokeColor.b )
|
||||
smoke:SetAirResistance( 75 )
|
||||
smoke:SetPos( self:GetPos() )
|
||||
smoke:SetCollide( true )
|
||||
smoke:SetBounce( 0.2 )
|
||||
smoke:SetLighting( false )
|
||||
smoke:SetNextThink( CurTime() + FrameTime() )
|
||||
smoke.bt = CurTime() + self.BillowTime
|
||||
smoke.dt = CurTime() + self.BillowTime + self.Life
|
||||
smoke.ft = CurTime() + self.BillowTime + self.Life + math.Rand(2.5, 5)
|
||||
smoke:SetDieTime(smoke.ft)
|
||||
smoke.life = self.Life
|
||||
smoke.billowed = false
|
||||
smoke.radius = self.SmokeRadius
|
||||
smoke:SetThinkFunction( function(pa)
|
||||
if !pa then return end
|
||||
|
||||
local prog = 1
|
||||
local alph = 0
|
||||
|
||||
if pa.ft < CurTime() then
|
||||
// pass
|
||||
elseif pa.dt < CurTime() then
|
||||
local d = (CurTime() - pa.dt) / (pa.ft - pa.dt)
|
||||
|
||||
alph = 1 - d
|
||||
elseif pa.bt < CurTime() then
|
||||
alph = 1
|
||||
else
|
||||
local d = math.Clamp(pa:GetLifeTime() / (pa.bt - CurTime()), 0, 1)
|
||||
|
||||
prog = (-d ^ 2) + (2 * d)
|
||||
|
||||
alph = d
|
||||
end
|
||||
|
||||
pa:SetEndSize( pa.radius * prog )
|
||||
pa:SetStartSize( pa.radius * prog )
|
||||
|
||||
pa:SetStartAlpha(255 * alph)
|
||||
pa:SetEndAlpha(255 * alph)
|
||||
|
||||
-- pa:SetLifeTime(pa:GetLifeTime() + FrameTime())
|
||||
pa:SetNextThink( CurTime() + FrameTime() )
|
||||
end )
|
||||
|
||||
table.insert(self.Particles, smoke)
|
||||
end
|
||||
|
||||
emitter:Finish()
|
||||
end
|
||||
|
||||
if TacRP.ConVars["smoke_affectnpcs"]:GetBool() then
|
||||
self:EnableCustomCollisions()
|
||||
self:SetCustomCollisionCheck(true)
|
||||
self:CollisionRulesChanged()
|
||||
else
|
||||
self:SetSolid(SOLID_NONE)
|
||||
end
|
||||
|
||||
self.dt = CurTime() + self.Life + self.BillowTime
|
||||
end
|
||||
|
||||
function ENT:TestCollision( startpos, delta, isbox, extents, mask )
|
||||
if (mask == MASK_BLOCKLOS or mask == MASK_BLOCKLOS_AND_NPCS) then
|
||||
local len = delta:Length()
|
||||
if len <= 200 then return false end -- NPCs can see very close
|
||||
|
||||
local rad = self.SmokeRadiusSqr
|
||||
local pos = self:GetPos()
|
||||
local dir = delta:GetNormalized()
|
||||
|
||||
-- Trace started within the smoke
|
||||
if startpos:DistToSqr(pos) <= rad then
|
||||
return {
|
||||
HitPos = startpos,
|
||||
Fraction = 0,
|
||||
Normal = -dir,
|
||||
}
|
||||
end
|
||||
|
||||
-- Find the closest point on the original trace to the smoke's origin point
|
||||
local t = (pos - startpos):Dot(dir)
|
||||
local p = startpos + t * dir
|
||||
|
||||
-- If the point is within smoke radius, the trace is intersecting the smoke
|
||||
if p:DistToSqr(pos) <= rad then
|
||||
return {
|
||||
HitPos = p,
|
||||
Fraction = math.Clamp(t / len, 0, 0.95),
|
||||
Normal = -dir,
|
||||
}
|
||||
end
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
hook.Add("ShouldCollide", "tacrp_smoke_cloud", function(ent1, ent2)
|
||||
if ent1.TacRPSmoke and !ent2:IsNPC() then return false end
|
||||
if ent2.TacRPSmoke and !ent1:IsNPC() then return false end
|
||||
end)
|
||||
|
||||
function ENT:Think()
|
||||
|
||||
if SERVER then
|
||||
if self.dt < CurTime() then
|
||||
SafeRemoveEntity(self)
|
||||
return
|
||||
end
|
||||
|
||||
--[[]
|
||||
if !TacRP.ConVars["smoke_affectnpcs"]:GetBool() then return end
|
||||
local targets = ents.FindInSphere(self:GetPos(), self.SmokeRadius)
|
||||
for _, k in pairs(targets) do
|
||||
if k:IsNPC() then
|
||||
local ret = hook.Run("TacRP_StunNPC", k, self)
|
||||
if ret then continue end
|
||||
k:SetSchedule(SCHED_STANDOFF)
|
||||
end
|
||||
end
|
||||
|
||||
self:NextThink(CurTime() + 0.5)
|
||||
]]
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:OnRemove()
|
||||
if CLIENT then
|
||||
timer.Simple(0, function()
|
||||
if !IsValid(self) then
|
||||
table.RemoveByValue(TacRP.ClientSmokeCache, self)
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:Draw()
|
||||
return false
|
||||
end
|
||||
Reference in New Issue
Block a user