254 lines
8.2 KiB
Lua
254 lines
8.2 KiB
Lua
AddCSLuaFile()
|
|
|
|
ENT.Base = "tacrp_proj_base"
|
|
ENT.PrintName = "RPG-7 Improvised Rocket"
|
|
ENT.Spawnable = false
|
|
|
|
ENT.Model = "models/weapons/tacint/rocket_deployed.mdl"
|
|
|
|
ENT.IsRocket = true // projectile has a booster and will not drop.
|
|
|
|
ENT.InstantFuse = false // projectile is armed immediately after firing.
|
|
ENT.RemoteFuse = false // allow this projectile to be triggered by remote detonator.
|
|
ENT.ImpactFuse = true // projectile explodes on impact.
|
|
|
|
ENT.ExplodeOnDamage = true
|
|
ENT.ExplodeUnderwater = true
|
|
|
|
ENT.Delay = 0
|
|
ENT.SafetyFuse = 0
|
|
ENT.BoostTime = 5
|
|
ENT.ImpactDamage = 150
|
|
|
|
ENT.AudioLoop = "TacRP/weapons/rpg7/rocket_flight-1.wav"
|
|
|
|
ENT.SmokeTrail = true
|
|
|
|
ENT.FlareColor = Color(255, 255, 75)
|
|
|
|
DEFINE_BASECLASS(ENT.Base)
|
|
|
|
function ENT:SetupDataTables()
|
|
self:NetworkVar("Bool", 0, "NoBooster")
|
|
self:NetworkVar("Entity", 0, "Weapon")
|
|
end
|
|
|
|
function ENT:Initialize()
|
|
BaseClass.Initialize(self)
|
|
|
|
if SERVER then
|
|
local phys = self:GetPhysicsObject()
|
|
local rng = math.random()
|
|
if rng <= 0.01 then
|
|
self:EmitSound("weapons/rpg/shotdown.wav", 80, 95)
|
|
local fx = EffectData()
|
|
fx:SetOrigin(self:GetPos() + self:GetForward() * 32)
|
|
fx:SetStart(Vector(math.Rand(0, 255), math.Rand(0, 255), math.Rand(0, 255)))
|
|
util.Effect("balloon_pop", fx)
|
|
self:GetOwner():EmitSound("tacrp/kids_cheering.mp3", 100, 100, 1)
|
|
SafeRemoveEntity(self)
|
|
elseif rng <= 0.25 then
|
|
self.BoostTime = math.Rand(0.5, 5)
|
|
|
|
self:EmitSound("weapons/rpg/shotdown.wav", 80, 95)
|
|
|
|
self:SetNoBooster(math.random() <= 0.2)
|
|
phys:EnableGravity(true)
|
|
|
|
if self:GetNoBooster() then
|
|
phys:SetVelocityInstantaneous(self:GetOwner():GetVelocity() + self:GetForward() * math.Rand(25, 75) + self:GetUp() * math.Rand(75, 150))
|
|
else
|
|
phys:SetVelocityInstantaneous(self:GetOwner():GetVelocity() + self:GetForward() * math.Rand(100, 500) + self:GetUp() * math.Rand(50, 200))
|
|
end
|
|
phys:AddAngleVelocity(VectorRand() * 180)
|
|
else
|
|
self.BoostTime = math.Rand(1, 3)
|
|
phys:SetVelocityInstantaneous(self:GetForward() * math.Rand(3000, 6000))
|
|
end
|
|
end
|
|
end
|
|
|
|
function ENT:Detonate(ent)
|
|
local attacker = self.Attacker or self:GetOwner()
|
|
|
|
if math.random() <= 0.05 then
|
|
self:EmitSound("physics/metal/metal_barrel_impact_hard3.wav", 125, 115)
|
|
local fx = EffectData()
|
|
fx:SetOrigin(self:GetPos())
|
|
fx:SetMagnitude(4)
|
|
fx:SetScale(4)
|
|
fx:SetRadius(4)
|
|
fx:SetNormal(self:GetVelocity():GetNormalized())
|
|
util.Effect("Sparks", fx)
|
|
|
|
for i = 1, 4 do
|
|
local prop = ents.Create("prop_physics")
|
|
prop:SetPos(self:GetPos())
|
|
prop:SetAngles(self:GetAngles())
|
|
prop:SetModel("models/weapons/tacint/rpg7_shrapnel_p" .. i .. ".mdl")
|
|
prop:Spawn()
|
|
prop:GetPhysicsObject():SetVelocityInstantaneous(self:GetVelocity() * 0.5 + VectorRand() * 75)
|
|
prop:SetCollisionGroup(COLLISION_GROUP_DEBRIS)
|
|
|
|
SafeRemoveEntityDelayed(prop, 3)
|
|
end
|
|
|
|
self:Remove()
|
|
return
|
|
end
|
|
|
|
local mult = TacRP.ConVars["mult_damage_explosive"]:GetFloat()
|
|
if self.NPCDamage then
|
|
util.BlastDamage(self, attacker, self:GetPos(), 350, 100)
|
|
else
|
|
util.BlastDamage(self, attacker, self:GetPos(), 350, math.Rand(150, 250) * mult)
|
|
self:ImpactTraceAttack(ent, math.Rand(750, 1500) * mult, math.Rand(7500, 20000))
|
|
end
|
|
|
|
local fx = EffectData()
|
|
fx:SetOrigin(self:GetPos())
|
|
|
|
if self:WaterLevel() > 0 then
|
|
util.Effect("WaterSurfaceExplosion", fx)
|
|
else
|
|
util.Effect("Explosion", fx)
|
|
end
|
|
|
|
self:EmitSound("TacRP/weapons/rpg7/explode.wav", 125)
|
|
|
|
self:Remove()
|
|
end
|
|
|
|
function ENT:PhysicsUpdate(phys)
|
|
if self:GetNoBooster() then return end
|
|
local len = phys:GetVelocity():Length()
|
|
local f = math.Clamp(len / 5000, 0, 1)
|
|
if phys:IsGravityEnabled() then
|
|
phys:AddVelocity(self:GetForward() * math.Rand(0, Lerp(f, 100, 10)))
|
|
phys:AddAngleVelocity(VectorRand() * Lerp(f, 8, 2))
|
|
elseif self.SpawnTime < CurTime() and len < 500 then
|
|
phys:EnableGravity(true)
|
|
else
|
|
phys:AddVelocity(VectorRand() * Lerp(f, 5, 50) + self:GetForward() * Lerp(f, 10, 0))
|
|
end
|
|
end
|
|
|
|
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
|
|
|
|
function ENT:Think()
|
|
if !IsValid(self) or self:GetNoDraw() then return end
|
|
|
|
if !self.SpawnTime then
|
|
self.SpawnTime = CurTime()
|
|
end
|
|
|
|
if !self.Armed and isnumber(self.TimeFuse) and self.SpawnTime + self.TimeFuse < CurTime() then
|
|
self.ArmTime = CurTime()
|
|
self.Armed = true
|
|
end
|
|
|
|
if self.Armed and self.ArmTime + self.Delay < CurTime() then
|
|
self:PreDetonate()
|
|
end
|
|
|
|
if SERVER and !self:GetNoBooster() and self.SpawnTime + self.BoostTime < CurTime() then
|
|
self:SetNoBooster(true)
|
|
self:GetPhysicsObject():EnableGravity(true)
|
|
end
|
|
|
|
if self.LoopSound and self:GetNoBooster() then
|
|
self.LoopSound:Stop()
|
|
end
|
|
|
|
if self.ExplodeUnderwater and self:WaterLevel() > 0 then
|
|
self:PreDetonate()
|
|
end
|
|
|
|
if self.SmokeTrail and CLIENT then
|
|
local emitter = ParticleEmitter(self:GetPos())
|
|
if !self:GetNoBooster() then
|
|
local smoke = emitter:Add(GetSmokeImage(), self:GetPos())
|
|
|
|
smoke:SetStartAlpha(50)
|
|
smoke:SetEndAlpha(0)
|
|
|
|
smoke:SetStartSize(10)
|
|
smoke:SetEndSize(math.Rand(50, 75))
|
|
|
|
smoke:SetRoll(math.Rand(-180, 180))
|
|
smoke:SetRollDelta(math.Rand(-1, 1))
|
|
|
|
smoke:SetPos(self:GetPos())
|
|
smoke:SetVelocity(-self:GetAngles():Forward() * 400 + (VectorRand() * 10))
|
|
|
|
smoke:SetColor(200, 200, 200)
|
|
smoke:SetLighting(true)
|
|
|
|
smoke:SetDieTime(math.Rand(0.75, 1.25))
|
|
|
|
smoke:SetGravity(Vector(0, 0, 0))
|
|
|
|
elseif !self.LastNoBooster then
|
|
|
|
for i = 1, 10 do
|
|
local smoke = emitter:Add(GetSmokeImage(), self:GetPos())
|
|
smoke:SetStartAlpha(50)
|
|
smoke:SetEndAlpha(0)
|
|
smoke:SetStartSize(25)
|
|
smoke:SetEndSize(math.Rand(100, 150))
|
|
smoke:SetRoll(math.Rand(-180, 180))
|
|
smoke:SetRollDelta(math.Rand(-1, 1))
|
|
smoke:SetPos(self:GetPos())
|
|
smoke:SetVelocity(VectorRand() * 200)
|
|
smoke:SetColor(200, 200, 200)
|
|
smoke:SetLighting(true)
|
|
smoke:SetDieTime(math.Rand(0.75, 1.75))
|
|
smoke:SetGravity(Vector(0, 0, -200))
|
|
end
|
|
else
|
|
local smoke = emitter:Add(GetSmokeImage(), self:GetPos())
|
|
|
|
smoke:SetStartAlpha(30)
|
|
smoke:SetEndAlpha(0)
|
|
|
|
smoke:SetStartSize(10)
|
|
smoke:SetEndSize(math.Rand(25, 50))
|
|
|
|
smoke:SetRoll(math.Rand(-180, 180))
|
|
smoke:SetRollDelta(math.Rand(-1, 1))
|
|
|
|
smoke:SetPos(self:GetPos())
|
|
smoke:SetVelocity(VectorRand() * 10)
|
|
|
|
smoke:SetColor(150, 150, 150)
|
|
smoke:SetLighting(true)
|
|
|
|
smoke:SetDieTime(math.Rand(0.2, 0.3))
|
|
|
|
smoke:SetGravity(Vector(0, 0, 0))
|
|
end
|
|
emitter:Finish()
|
|
|
|
self.LastNoBooster = self:GetNoBooster()
|
|
|
|
end
|
|
|
|
|
|
self:OnThink()
|
|
end
|
|
|
|
local mat = Material("effects/ar2_altfire1b")
|
|
|
|
function ENT:Draw()
|
|
self:DrawModel()
|
|
|
|
if self.FlareColor and !self:GetNoBooster() then
|
|
render.SetMaterial(mat)
|
|
render.DrawSprite(self:GetPos() + (self:GetAngles():Forward() * -16), math.Rand(100, 150), math.Rand(100, 150), self.FlareColor)
|
|
end
|
|
end
|