add sborka
This commit is contained in:
244
garrysmod/addons/tacrp/lua/entities/tacrp_gas_cloud.lua
Normal file
244
garrysmod/addons/tacrp/lua/entities/tacrp_gas_cloud.lua
Normal file
@@ -0,0 +1,244 @@
|
||||
ENT.Type = "anim"
|
||||
ENT.Base = "base_entity"
|
||||
ENT.PrintName = "Gas 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.Particles = nil
|
||||
ENT.SmokeRadius = 256
|
||||
ENT.SmokeColor = Color(125, 150, 50)
|
||||
ENT.BillowTime = 5
|
||||
ENT.Life = 15
|
||||
|
||||
AddCSLuaFile()
|
||||
|
||||
function ENT:Initialize()
|
||||
if SERVER then
|
||||
self:SetModel( "models/weapons/w_eq_smokegrenade_thrown.mdl" )
|
||||
self:SetMoveType( MOVETYPE_NONE )
|
||||
self:SetSolid( SOLID_NONE )
|
||||
self:DrawShadow( false )
|
||||
|
||||
sound.EmitHint(SOUND_DANGER, self:GetPos(), 328, self.Life, self)
|
||||
else
|
||||
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() * 200) )
|
||||
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
|
||||
return
|
||||
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 )
|
||||
|
||||
alph = math.Clamp(alph, 0, 1)
|
||||
|
||||
pa:SetStartAlpha(50 * alph)
|
||||
pa:SetEndAlpha(50 * alph)
|
||||
|
||||
pa:SetNextThink( CurTime() + FrameTime() )
|
||||
end )
|
||||
|
||||
table.insert(self.Particles, smoke)
|
||||
end
|
||||
|
||||
emitter:Finish()
|
||||
end
|
||||
|
||||
self.dt = CurTime() + self.Life + self.BillowTime
|
||||
end
|
||||
|
||||
|
||||
function ENT:Think()
|
||||
|
||||
if SERVER then
|
||||
if !self:GetOwner():IsValid() then self:Remove() return end
|
||||
|
||||
local o = self:GetOwner()
|
||||
local origin = self:GetPos() + Vector(0, 0, 16)
|
||||
|
||||
local ttt = TacRP.GetBalanceMode() == TacRP.BALANCE_TTT
|
||||
local threshold = ttt and 50 or 25
|
||||
|
||||
local dmg = DamageInfo()
|
||||
dmg:SetAttacker(self:GetOwner())
|
||||
dmg:SetInflictor(self)
|
||||
dmg:SetDamageType(DMG_NERVEGAS)
|
||||
dmg:SetDamageForce(Vector(0, 0, 0))
|
||||
dmg:SetDamagePosition(self:GetPos())
|
||||
dmg:SetDamageCustom(1024) -- immersive death
|
||||
for i, k in pairs(ents.FindInSphere(origin, 300)) do
|
||||
if k:IsPlayer() or k:IsNPC() or k:IsNextBot() then
|
||||
|
||||
if k:IsPlayer() then
|
||||
local wep = k:GetActiveWeapon()
|
||||
if IsValid(wep) and wep.ArcticTacRP and wep:GetValue("GasImmunity") then
|
||||
continue
|
||||
end
|
||||
end
|
||||
|
||||
local tr = util.TraceLine({
|
||||
start = origin,
|
||||
endpos = k:EyePos() or k:WorldSpaceCenter(),
|
||||
filter = self,
|
||||
mask = MASK_SOLID_BRUSHONLY
|
||||
})
|
||||
if tr.Fraction < 1 then continue end
|
||||
|
||||
dmg:SetDamage(math.Rand(3, 6))
|
||||
|
||||
if k:IsPlayer() and TacRP.ConVars["gas_affectplayers"]:GetBool() then
|
||||
k:TakeDamageInfo(dmg)
|
||||
|
||||
local timername = "tacrp_gas_" .. k:EntIndex()
|
||||
local reps = 6
|
||||
|
||||
if timer.Exists(timername) then
|
||||
reps = math.Clamp(timer.RepsLeft(timername) + 3, reps, 20)
|
||||
timer.Remove(timername)
|
||||
end
|
||||
timer.Create(timername, ttt and 5 or 1.5, reps, function()
|
||||
if !IsValid(k) or !k:Alive() or (engine.ActiveGamemode() == "terrortown" and (GetRoundState() == ROUND_PREP or GetRoundState() == ROUND_POST)) then
|
||||
timer.Remove(timername)
|
||||
return
|
||||
end
|
||||
k:ScreenFade( SCREENFADE.IN, Color(125, 150, 50, 3), 0.1, 0 )
|
||||
if k:Health() > threshold then
|
||||
local d = DamageInfo()
|
||||
d:SetDamageType(DMG_NERVEGAS)
|
||||
d:SetDamage(1)
|
||||
d:SetInflictor(IsValid(self) and self or o)
|
||||
d:SetAttacker(o)
|
||||
d:SetDamageForce(k:GetForward())
|
||||
d:SetDamagePosition(k:GetPos())
|
||||
d:SetDamageCustom(1024)
|
||||
k:TakeDamageInfo(d)
|
||||
else
|
||||
k:ViewPunch(Angle(math.Rand(-2, 2), 0, 0))
|
||||
end
|
||||
if ttt or math.random() <= 0.333 then
|
||||
k:EmitSound("ambient/voices/cough" .. math.random(1, 4) .. ".wav", 80, math.Rand(95, 105))
|
||||
end
|
||||
end)
|
||||
elseif k:IsNPC() and TacRP.ConVars["gas_affectnpcs"]:GetBool() and (k:GetHullType() == HULL_HUMAN or k:GetHullType() == HULL_WIDE_HUMAN) then
|
||||
k:SetCurrentWeaponProficiency(WEAPON_PROFICIENCY_POOR)
|
||||
local rng = math.random()
|
||||
if rng <= 0.3 then
|
||||
k:SetSchedule(SCHED_RUN_RANDOM)
|
||||
elseif rng <= 0.8 then
|
||||
k:SetSchedule(SCHED_COWER)
|
||||
end
|
||||
k:TakeDamageInfo(dmg)
|
||||
elseif !k:IsNPC() and !k:IsPlayer() then
|
||||
k:TakeDamageInfo(dmg)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
self:NextThink(CurTime() + 1)
|
||||
|
||||
if self.dt < CurTime() then
|
||||
SafeRemoveEntity(self)
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function ENT:Draw()
|
||||
return false
|
||||
end
|
||||
|
||||
-- cs gas strips armor and will try not deal lethal damage
|
||||
hook.Add("EntityTakeDamage", "tacrp_gas", function(ent, dmg)
|
||||
if dmg:GetDamageType() == DMG_NERVEGAS and bit.band(dmg:GetDamageCustom(), 1024) == 1024 then
|
||||
if ent:IsPlayer() then
|
||||
local threshold = TacRP.GetBalanceMode() == TacRP.BALANCE_TTT and 50 or 25
|
||||
local wep = ent:GetActiveWeapon()
|
||||
if IsValid(wep) and wep.ArcticTacRP and wep:GetValue("GasImmunity") then
|
||||
dmg:SetDamage(0)
|
||||
elseif ent:Health() - dmg:GetDamage() <= threshold then
|
||||
dmg:SetDamage(math.max(0, ent:Health() - threshold))
|
||||
end
|
||||
if dmg:GetDamage() <= 0 then
|
||||
ent.TacRPGassed = true
|
||||
end
|
||||
elseif ent:IsNPC() then
|
||||
if ent:Health() <= dmg:GetDamage() then
|
||||
ent:SetHealth(1)
|
||||
dmg:SetDamage(0)
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
hook.Add("PostEntityTakeDamage", "tacrp_gas", function(ent, dmg, took)
|
||||
if ent:IsPlayer() and dmg:GetDamageType() == DMG_NERVEGAS and bit.band(dmg:GetDamageCustom(), 1024) == 1024 then
|
||||
ent:SetArmor(math.max(0, ent:Armor() - dmg:GetDamage()))
|
||||
if ent.TacRPGassed or (dmg:GetDamage() > 0 and IsValid(dmg:GetInflictor()) and (dmg:GetInflictor():GetClass() == "tacrp_gas_cloud" or dmg:GetInflictor():GetClass() == "tacrp_smoke_cloud_ninja")) then
|
||||
local distsqr = dmg:GetInflictor():GetPos():DistToSqr(ent:GetPos())
|
||||
if distsqr <= 350 * 350 then
|
||||
ent:SetNWFloat("TacRPGasEnd", CurTime() + 10)
|
||||
ent.TacRPGassed = nil
|
||||
ent:ScreenFade( SCREENFADE.IN, Color(125, 150, 50, 100), 0.5, 0 )
|
||||
ent:ViewPunch(Angle(math.Rand(-1, 1), math.Rand(-1, 1), math.Rand(-1, 1)))
|
||||
local ttt = TacRP.GetBalanceMode() == TacRP.BALANCE_TTT
|
||||
if ttt or math.random() <= 0.333 then
|
||||
ent:EmitSound("ambient/voices/cough" .. math.random(1, 4) .. ".wav", 80, math.Rand(95, 105))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
Reference in New Issue
Block a user