Files
wnsrc/lua/entities/npc_vj_gunship2_z/init.lua
lifestorm 94063e4369 Upload
2024-08-04 22:55:00 +03:00

417 lines
17 KiB
Lua

--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
AddCSLuaFile("shared.lua")
include("shared.lua")
ENT.Model = {"models/gunship.mdl"}
ENT.StartHealth = 440
--ENT.CustomBlood_Particle = {"blood_impact_synth_01"}
ENT.BloodColor = "White"
ENT.HeliLights = false
ENT.Heli_CanCrash = false
ENT.Heli_CanBomb = false
ENT.CrashAlarmSound = "npc/combine_gunship/gunship_crashing1.wav"
ENT.HasRockets = false
ENT.RotorSound = "npc/combine_gunship/engine_rotor_loop1.wav"
ENT.ShootSound = "npc/combine_gunship/gunship_weapon_fire_loop6.wav"
ENT.SoundTbl_Idle = {"NPC_CombineGunship.PatrolPing"}
ENT.SoundTbl_Alert = {"NPC_CombineGunship.SeeEnemy"}
ENT.SoundTbl_CombatIdle = {"NPC_CombineGunship.SeeEnemy"}
ENT.SoundTbl_CallForHelp = {"NPC_CombineGunship.SeeEnemy"}
ENT.SoundTbl_Pain = {"NPC_CombineGunship.Pain"}
ENT.SoundTbl_Breath = {"NPC_CombineGunship.RotorBlastSound"}
ENT.SoundTbl_Investigate = {"NPC_CombineGunship.SearchPing"}
ENT.SoundTbl_LostEnemy = {"NPC_CombineGunship.SearchPing"}
ENT.SoundTbl_OnReceiveOrder = {"NPC_CombineGunship.SearchPing"}
ENT.BreathSoundLevel = 90
ENT.IdleSoundLevel = 130
ENT.CombatIdleSoundLevel = 130
ENT.OnReceiveOrderSoundLevel = 130
ENT.InvestigateSoundLevel = 130
ENT.LostEnemySoundLevel = 130
ENT.AlertSoundLevel = 130
ENT.CallForHelpSoundLevel = 130
ENT.PainSoundLevel = 130
ENT.DeathCorpseSkin = 1
ENT.HasDeathRagdoll = true -- If set to false, it will not spawn the regular ragdoll of the SNPC
ENT.GibOnDeathDamagesTable = {"UseDefault"}
ENT.HasGibOnDeathSounds = true
ENT.BulletSpread = 0.03
ENT.BulletsUntilReload = 30
ENT.AimYawPoseParam = "flex_horz"
ENT.AimPitchPoseParam = "flex_vert"
ENT.FlipAimPitchPoseParam = false
ENT.MaxBCannonDistFromEnemy = 250
ENT.BCannonCooldown = 4
ENT.CanShootDownRockets = false
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function ENT:CustomHeliInit()
self.Bullseye = ents.Create("obj_vj_Bullseye")
self.Bullseye:SetModel("models/hunter/plates/plate.mdl")
self.Bullseye:SetParent(self,5)
self.Bullseye:SetPos(self:GetAttachment(5).Pos - Vector(0,0,30))
self.Bullseye:Spawn()
self.Bullseye:SetNoDraw(true)
self.Bullseye:DrawShadow(false)
self.Bullseye:SetSolid(SOLID_NONE)
self.Bullseye.VJ_NPC_Class = self.VJ_NPC_Class
self.RotorBlastSoundLoop = CreateSound(self, "npc/combine_gunship/gunship_engine_loop3.wav")
self.RotorBlastSoundLoop:SetSoundLevel(95)
self.RotorBlastSoundLoop:Play()
self.Antennas_NoiseSpeedOffset = math.Rand(0.9, 1.1)
self.Fins_NoiseSpeedOffset = math.Rand(0.9, 1.1)
self.Body_vert_NoiseSpeedOffset = math.Rand(0.9, 1.1)
self.Body_horz_NoiseSpeedOffset = math.Rand(0.9, 1.1)
self:SetCollisionBounds( Vector (185,185,95) , Vector (-185,-185,-30) )
self.NextBCannon = CurTime()
end
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function ENT:DoGunAttack()
local bullet_source = self:GetAttachment(1).Pos
local fire_dir = (self.ShootPos - bullet_source):GetNormalized()
local expLight = ents.Create("light_dynamic")
expLight:SetKeyValue("brightness", "5")
expLight:SetKeyValue("distance", "250")
expLight:Fire("Color", "0 75 255")
expLight:SetPos(bullet_source)
expLight:Spawn()
expLight:SetParent(self,1)
expLight:Fire("TurnOn", "", 0)
timer.Simple(0.1,function() if IsValid(expLight) then expLight:Remove() end end)
self:DeleteOnRemove(expLight)
ParticleEffectAttach("vj_rifle_full_blue",PATTACH_POINT_FOLLOW,self,1)
self:FireBullets({
Src = bullet_source,
Dir = fire_dir,
Damage = 3,
Force = 25,
TracerName = "AirboatGunTracer",
Spread = Vector( self.BulletSpread,self.BulletSpread,self.BulletSpread ),
Num = 1,
Callback = function(attacker, tracer)
if math.random(1, 2) == 1 then
local effectdata = EffectData()
effectdata:SetOrigin(tracer.HitPos)
effectdata:SetNormal(tracer.HitNormal)
effectdata:SetRadius( 10 )
util.Effect( "cball_bounce", effectdata )
end
effects.BeamRingPoint( tracer.HitPos, 0.2, 0, 70, 12, 12, Color(255,255,175) )
util.VJ_SphereDamage(self,self,tracer.HitPos,20,3,DMG_SONIC,true,false,false,false)
end,
})
if IsValid(self.EnemyRocket) && self.ShootPos:Distance(self.EnemyRocket:GetPos()) < 50 then
local destroyed_rocket = ents.Create("obj_vj_destroyed_rocket_z")
destroyed_rocket:SetPos(self.EnemyRocket:GetPos())
destroyed_rocket:SetModel(self.EnemyRocket:GetModel())
destroyed_rocket:Spawn()
self.EnemyRocket:Fire("KillHierarchy")
end
self.BulletsFired = self.BulletsFired + 1
if self.BulletsFired >= self.BulletsUntilReload then
self:UnchargeGun()
self.GunHasCooledDown = false
timer.Simple(self.GunCooldownTime, function() if IsValid(self) then self.GunHasCooledDown = true end end)
if self.Diving then self.Diving = false end
self:ConsiderDive()
end
self.GunFiring = true
end
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function ENT:AnimationThink()
local sin = math.sin
local time = CurTime()
local noise_speed_mult = 2
self.body_vert_noise = 13 + sin(time*self.Body_vert_NoiseSpeedOffset*noise_speed_mult)*13
self.body_horz_noise = sin(time*self.Body_horz_NoiseSpeedOffset*noise_speed_mult)*5
local fin_noise = 0.33 + sin(time*self.Fins_NoiseSpeedOffset*noise_speed_mult)*0.33
local antenna_noise = 0.5 + sin(time*self.Antennas_NoiseSpeedOffset*noise_speed_mult)*0.5
self:SetPoseParameter("fin_accel",fin_noise)
self:SetPoseParameter("antenna_accel",antenna_noise)
self:AddLayeredSequence(self:LookupSequence("prop_turn"),2)
end
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function ENT:EnemyInBCannonDist()
local tr = util.TraceLine({
start = self:GetPos(),
endpos = self:GetPos() - Vector(0,0,10000),
mask = MASK_NPCWORLDSTATIC,
})
local BombSpot = tr.HitPos
if self:GetEnemy():GetPos():Distance(BombSpot) < self.MaxBCannonDistFromEnemy then
return true
end
end
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function ENT:DoBCannon()
if self.DoingBCannon or self.NextBCannon > CurTime() then return end
self.DoingBCannon = true
self:SetNWBool("VJGunshipZDoingBCannon", true)
local time_until_fire = 1.15
local chargeLight = ents.Create("light_dynamic")
chargeLight:SetKeyValue("brightness", "5")
chargeLight:SetKeyValue("distance", "400")
chargeLight:Fire("Color", "0 75 255")
chargeLight:SetPos(self:GetAttachment(4).Pos)
chargeLight:Spawn()
chargeLight:SetParent(self,4)
chargeLight:Fire("TurnOn", "", 0)
self:DeleteOnRemove(chargeLight)
self:EmitSound( "NPC_Strider.Charge", 120, 100)
timer.Simple(time_until_fire, function() if IsValid(self) then
if IsValid(chargeLight) then chargeLight:Remove() end
local tr_bcannon = util.TraceLine({
start = self:GetPos(),
endpos = self:GetPos() - Vector(0,0,10000),
mask = MASK_NPCWORLDSTATIC,
})
local expLight = ents.Create("light_dynamic")
expLight:SetKeyValue("brightness", "7")
expLight:SetKeyValue("distance", "600")
expLight:Fire("Color", "0 75 255")
expLight:SetPos(self:GetAttachment(4).Pos)
expLight:Spawn()
expLight:SetParent(self,4)
expLight:Fire("TurnOn", "", 0)
timer.Simple(0.1,function() if IsValid(expLight) then expLight:Remove() end end)
self:DeleteOnRemove(expLight)
local expLight2 = ents.Create("light_dynamic")
expLight2:SetKeyValue("brightness", "8")
expLight2:SetKeyValue("distance", "700")
expLight2:Fire("Color", "0 75 255")
expLight2:SetPos(tr_bcannon.HitPos)
expLight2:Spawn()
expLight2:Fire("TurnOn", "", 0)
timer.Simple(0.1,function() if IsValid(expLight2) then expLight2:Remove() end end)
self:DeleteOnRemove(expLight2)
util.ScreenShake(tr_bcannon.HitPos, 16, 200, 1, 3000)
util.ParticleTracerEx("Weapon_Combine_Ion_Cannon_Beam",self:GetAttachment(4).Pos,tr_bcannon.HitPos,false,self:EntIndex(),4)
--ParticleEffect("grenade_explosion_01f", tr_bcannon.HitPos, Angle(0,0,0))
local effectdata = EffectData()
effectdata:SetOrigin(tr_bcannon.HitPos)
effectdata:SetNormal(tr_bcannon.HitNormal)
effectdata:SetRadius( 400 )
effectdata:SetScale( 200 )
util.Effect( "cball_bounce", effectdata )
util.Effect( "AR2Explosion", effectdata )
util.Effect( "ThumperDust", effectdata )
util.Effect( "ThumperDust", effectdata )
util.Effect( "ThumperDust", effectdata )
util.Decal( "Scorch", tr_bcannon.HitPos + tr_bcannon.HitNormal, tr_bcannon.HitPos - tr_bcannon.HitNormal)
local damage = 150
util.VJ_SphereDamage(self,self,tr_bcannon.HitPos,self.MaxBCannonDistFromEnemy*1.5,damage,bit.bor(DMG_DISSOLVE,DMG_SHOCK,DMG_BLAST),true,true,false,false)
self:EmitSound( "NPC_Strider.Shoot", 100, 120)
sound.Play( "Weapon_Mortar.Impact", tr_bcannon.HitPos, 120, 100, 1 )
self.DoingBCannon = false
self:SetNWBool("VJGunshipZDoingBCannon", false)
if self.Diving then
self.Diving = false
self.NextDiveTime = CurTime() + self.DiveCooldown
end
self.NextBCannon = CurTime() + self.BCannonCooldown
end end)
end
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function ENT:DiveBehavior()
local enemy = self:GetEnemy()
if self.Diving && IsValid(enemy) && util.TraceLine({start = enemy:GetPos(), endpos = enemy:GetPos()-Vector(0,0,self.MaxBCannonDistFromEnemy), mask = MASK_NPCWORLDSTATIC}).Hit then
self.Heli_MinChaseDist = self.MaxBCannonDistFromEnemy
self.Heli_BackAwayFromEnemyDist = self.MaxBCannonDistFromEnemy
else
self.Heli_MinChaseDist = self.ShootDist
self.Heli_BackAwayFromEnemyDist = 1000
end
end
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function ENT:CustomHeliThink()
self.Bullseye.VJ_NPC_Class = self.VJ_NPC_Class
self:AnimationThink()
if self.DoingBCannon then
ParticleEffectAttach("hunter_shield_impact", PATTACH_POINT_FOLLOW, self, 4)
-- local effectdata = EffectData()
-- effectdata:SetStart(self:GetAttachment(4).Pos)
-- util.Effect("cguard_suck", effectdata)
end
if IsValid(self:GetEnemy()) then
if self:EnemyInBCannonDist() then
self:DoBCannon()
end
end
end
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function ENT:CustomOnRemove()
self.RotorSoundLoop:Stop()
self.ShootGunLoop:Stop()
self.RotorBlastSoundLoop:Stop()
if self.CrashAlarm && self.CrashSound then
self.CrashAlarm:Stop()
self.CrashSound:Stop()
end
end
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function ENT:SetUpGibesOnDeath(dmginfo, hitgroup)
self:EmitSound("NPC_CombineGunship.Explode", 120, 100)
local effectdata = EffectData()
effectdata:SetOrigin(self:GetPos())
effectdata:SetScale( 500 )
util.Effect( "Explosion", effectdata )
self:EmitSound( "Explo.ww2bomb", 130, 100)
ParticleEffect("vj_explosion1", self:GetPos(), Angle(0,0,0), nil)
ParticleEffect( "striderbuster_explode_goop", self:GetPos(), self:GetAngles() )
self:CreateGibEntity("obj_vj_gib","models/gibs/gunship_gibs_sensorarray.mdl",{BloodType = "",Vel = self:GetVelocity()+VectorRand()*600, CollideSound = {"SolidMetal.ImpactSoft"}})
self:CreateGibEntity("obj_vj_gib","models/gibs/gunship_gibs_eye.mdl",{BloodType = "",Vel = self:GetVelocity()+VectorRand()*600, CollideSound = {"SolidMetal.ImpactSoft"}})
self:CreateGibEntity("obj_vj_gib","models/gibs/gunship_gibs_wing.mdl",{BloodType = "",Vel = self:GetVelocity()+VectorRand()*600, CollideSound = {"SolidMetal.ImpactSoft"}})
self:CreateGibEntity("obj_vj_gib","models/gibs/gunship_gibs_engine.mdl",{BloodType = "",Vel = self:GetVelocity()+VectorRand()*600, CollideSound = {"SolidMetal.ImpactSoft"}})
self:CreateGibEntity("obj_vj_gib","models/gibs/gunship_gibs_headsection.mdl",{Pos = self:LocalToWorld(Vector(150,0,0)), BloodType = "", Ang = self:GetAngles(), Vel = self:GetVelocity(), AngVel = VectorRand()*50, CollideSound = {"SolidMetal.ImpactSoft"}})
self:CreateGibEntity("obj_vj_gib","models/gibs/gunship_gibs_midsection.mdl",{BloodType = "", Ang = self:GetAngles(), Vel = self:GetVelocity(), AngVel = VectorRand()*50, CollideSound = {"SolidMetal.ImpactSoft"}})
self:CreateGibEntity("obj_vj_gib","models/gibs/gunship_gibs_tailsection.mdl",{Pos = self:LocalToWorld(Vector(-150,0,0)), BloodType = "", Ang = self:GetAngles(), Vel = self:GetVelocity(), AngVel = VectorRand()*50, CollideSound = {"SolidMetal.ImpactSoft"}})
self:CreateGibEntity("obj_vj_gib","models/gibs/gunship_gibs_nosegun.mdl",{Pos = self:LocalToWorld(Vector(250,0,0)), BloodType = "", Ang = self:GetAngles(), Vel = self:GetVelocity(), AngVel = VectorRand()*50, CollideSound = {"SolidMetal.ImpactSoft"}})
return true
end
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function ENT:CustomOnDeath_AfterCorpseSpawned(dmginfo, hitgroup, corpseEnt)
corpseEnt:GetPhysicsObject():SetVelocity( self:GetVelocity() * 4 + Vector(0,0,250) )
corpseEnt:EmitSound("NPC_CombineGunship.Explode", 120, 100)
ParticleEffectAttach("env_fire_large_smoke", PATTACH_POINT_FOLLOW, corpseEnt, 5)
local effectdata = EffectData()
effectdata:SetOrigin(self:GetAttachment(5).Pos)
effectdata:SetScale( 500 )
util.Effect( "Explosion", effectdata )
self:EmitSound( "Explo.ww2bomb", 130, 100)
timer.Simple(16,function() if IsValid(corpseEnt) then
corpseEnt:StopParticles()
end end)
end
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function ENT:CustomOnTakeDamage_BeforeDamage(dmginfo, hitgroup)
self.HasPainSounds = true -- If set to false, it won't play the pain sounds
self.Bleeds = false
local rotor_damage = dmginfo:GetDamagePosition():Distance(self:GetAttachment(5).Pos) < 75
if !dmginfo:IsExplosionDamage() && !rotor_damage && !comballdamage then
self.HasPainSounds = false -- If set to false, it won't play the pain sounds
dmginfo:SetDamage(dmginfo:GetDamage() * 0.1)
if math.random(1, 4) == 1 then
self.Bleeds = true
self:EmitSound("physics/metal/metal_sheet_impact_bullet1.wav", 92, math.random(70, 90))
local spark = ents.Create("env_spark")
spark:SetPos(dmginfo:GetDamagePosition())
spark:Spawn()
spark:Fire("StartSpark", "", 0)
spark:Fire("StopSpark", "", 0.001)
self:DeleteOnRemove(spark)
end
else
self.Bleeds = true
if rotor_damage then
if dmginfo:IsExplosionDamage() then
dmginfo:ScaleDamage(1.5)
else
dmginfo:ScaleDamage(0.33)
end
end
local spark = ents.Create("env_spark")
spark:SetPos(dmginfo:GetDamagePosition())
spark:SetKeyValue("Magnitude","2")
spark:SetKeyValue("Spark Trail Length","2")
spark:Spawn()
spark:Fire("StartSpark", "", 0)
spark:Fire("StopSpark", "", 0.001)
self:DeleteOnRemove(spark)
end
end
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------