--[[ | 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/combine_apc.mdl" ENT.StartHealth = 430 ENT.Immune_Dissolve = false -- Immune to Dissolving | Example: Combine Ball ENT.Immune_AcidPoisonRadiation = false -- Immune to Acid, Poison and Radiation ENT.Immune_Bullet = false -- Immune to Bullets ENT.Immune_Physics = false -- Immune to Physics ENT.ImmuneDamagesTable = {} -- You can set Specific types of damages for the SNPC to be immune to ENT.VJ_NPC_Class = {"CLASS_COMBINE"} ENT.CallForHelp = true -- Does the SNPC call for help? ENT.InvestigateSoundDistance = 18 ENT.CallForHelpDistance = 10000 -- -- How far away the SNPC's call for help goes | Counted in World Units -- STOP RANDOMLY TURNING GOD PLEASE ENT.CallForHelpAnimationFaceEnemy = false -- Should it face the enemy when playing the animation? ENT.CombatFaceEnemy = false -- If enemy exists and is visible ENT.SoundTbl_Breath = {"vehicles/apc/apc_idle1.wav"} ENT.BreathSoundLevel = 90 ENT.DeathCorpseModel = {"models/combine_apc_destroyed_gib01.mdl"} ENT.Tank_AngleDiffuseNumber = 90 -- Used if the forward direction of the y-axis isn't correct on the model ENT.APC_RunOverDist = 750 ENT.APC_MinDriveDist = 1250 ENT.APC_AccelSpeed = 15 ENT.APC_DrivingSpeed = 500 ENT.APC_BackPedalSpeed = 200 ENT.APC_TurnSpeedMax = 45 ENT.ShootDist = 3000 ENT.BulletSpread = 0.03 ENT.Shots = { min = 10, max = 20 } ENT.ShootCoolDown = { min = 2, max = 3, } ENT.RocketDistance = 4500 ENT.RocketCoolDown = { min = 1.75, max = 2.5, } ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ENT.VJC_Data = { CameraMode = 1, -- Sets the default camera mode | 1 = Third Person, 2 = First Person ThirdP_Offset = Vector(0, 0, 0), -- The offset for the controller when the camera is in third person FirstP_Bone = "APC.Frame", -- If left empty, the base will attempt to calculate a position for first person FirstP_Offset = Vector(0, 0, 50), -- The offset for the controller when the camera is in first person FirstP_ShrinkBone = false, -- Should the bone shrink? Useful if the bone is obscuring the player's view FirstP_CameraBoneAng = 0, -- Should the camera's angle be affected by the bone's angle? | 0 = No, 1 = Pitch, 2 = Yaw, 3 = Roll FirstP_CameraBoneAng_Offset = 0, -- How much should the camera's angle be rotated by? | Useful for weird bone angles } ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- function ENT:Controller_IntMsg(ply, controlEnt) ply:ChatPrint("MOUSE1 (primary attack key): Shoot Gun") ply:ChatPrint("MOUSE2 (secondary attack key): Launch Rockets") end ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- function ENT:CreateWheels() local phys = self:GetPhysicsObject() self.Wheel_FR = ents.Create("base_gmodentity") self.Wheel_FL = ents.Create("base_gmodentity") self.Wheel_RR = ents.Create("base_gmodentity") self.Wheel_RL = ents.Create("base_gmodentity") local wheels = { { ent = self.Wheel_FR, pos = phys:GetPos()+self:GetForward()*45-self:GetRight()*68+self:GetUp()*24, ang = phys:GetAngles()+Angle(0,90,90), }, { ent = self.Wheel_FL, pos = phys:GetPos()-self:GetForward()*45-self:GetRight()*68+self:GetUp()*24, ang = phys:GetAngles()+Angle(0,90,-90), }, { ent = self.Wheel_RR, pos = phys:GetPos()+self:GetForward()*45+self:GetRight()*78+self:GetUp()*24, ang = phys:GetAngles()+Angle(0,90,90), }, { ent = self.Wheel_RL, pos = phys:GetPos()-self:GetForward()*45+self:GetRight()*78+self:GetUp()*24, ang = phys:GetAngles()+Angle(0,90,-90), }, } for _,wheel_data in pairs(wheels) do local wheel = wheel_data.ent wheel:SetModel("models/props_phx/wheels/trucktire.mdl") wheel:SetPos(wheel_data.pos) wheel:SetAngles(wheel_data.ang) wheel:Spawn() wheel:PhysicsInit(SOLID_VPHYSICS) wheel:GetPhysicsObject():SetMass(phys:GetMass()*0.125) wheel:SetNoDraw(true) wheel:SetCollisionGroup(COLLISION_GROUP_DEBRIS) self:DeleteOnRemove(wheel) local axis = constraint.Axis(wheel, self, 0, 0, wheel:OBBCenter(), Vector(0,0,0), 0, 0, 0, 1, Vector(0,0,0)) end end ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- function ENT:CustomInitialize_CustomTank() self.NextShootTime = CurTime() self.NextRocketTime = CurTime() self.bulletprop1 = ents.Create("base_gmodentity") self.bulletprop1:SetModel("models/hunter/blocks/cube025x025x025.mdl") self.bulletprop1:SetPos(self:GetAttachment(7).Pos) self.bulletprop1:SetParent(self,7) self.bulletprop1:SetSolid(SOLID_NONE) self.bulletprop1:AddEFlags(EFL_DONTBLOCKLOS) self.bulletprop1:SetNoDraw(true) self.bulletprop1:Spawn() self.APCAlarm = CreateSound(self,"ambient/alarms/apc_alarm_loop1.wav") self.APCAlarm:SetSoundLevel(100) timer.Simple(0, function() self:CreateWheels() end) end ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- function ENT:CustomOnAlert(ent) self.APCAlarm:Play() self.APCAlarm:ChangePitch(math.random(90,100)) timer.Simple(6, function() if IsValid(self) then self.APCAlarm:Stop() end end) end ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- function ENT:GetNearDeathSparkPositions() local randpos = math.random(1,7) if randpos == 1 then self.Spark1:SetLocalPos(self:GetPos() +self:GetForward()*100 +self:GetUp()*60) elseif randpos == 2 then self.Spark1:SetLocalPos(self:GetPos() +self:GetForward()*30 +self:GetUp()*60) elseif randpos == 5 then self.Spark1:SetLocalPos(self:GetPos() +self:GetForward()*10 +self:GetUp()*60 +self:GetRight()*50) elseif randpos == 6 then self.Spark1:SetLocalPos(self:GetPos() +self:GetForward()*80 +self:GetUp()*60 +self:GetRight()*-50) elseif randpos == 7 then self.Spark1:SetLocalPos(self:GetPos() +self:GetForward()*-20 +self:GetUp()*60 +self:GetRight()*-30) end end ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- function ENT:EnemyInDriveDist() local enemy = self:GetEnemy() local enemypos = enemy:GetPos() local mypos = self:GetPos() local yaw_difference = self:WorldToLocalAngles( Angle( 0 , (self:GetPos()-enemy:GetPos()):Angle().y + self.Tank_AngleDiffuseNumber, 0 ) ).y local distXY = Vector(enemypos.x,enemypos.y,0):Distance(Vector(mypos.x,mypos.y,0)) local pos_z_dist = math.abs(enemypos.z-mypos.z) if distXY < self.APC_RunOverDist && math.abs(yaw_difference) < 40 && pos_z_dist < 100 then return true end if distXY > self.APC_MinDriveDist then return true end end ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- function ENT:HasObstacle(dir) local mult = nil if dir == "forward" then mult = 150 elseif dir == "backward" then mult = -150 end local defaultpos = self:GetPos() - self:GetRight()*mult + self:GetUp()*35 local collision_positions = { defaultpos, defaultpos + self:GetForward() * 70, defaultpos - self:GetForward() * 70, } for _,pos in pairs(collision_positions) do -- if dir == "backward" then -- local prop = ents.Create("prop_dynamic") -- prop:SetPos(pos) -- prop:SetModel("models/props_junk/PopCan01a.mdl") -- end if bit.band( util.PointContents(pos) , CONTENTS_SOLID ) == CONTENTS_SOLID then --print("has obstacle (" .. dir .. ")!") return true end end end ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- function ENT:HasGroundInFrontOfSelf() local trStartPos = self:GetPos()-self:GetRight()*150+self:GetUp()*25 -- local prop = ents.Create("prop_dynamic") -- prop:SetPos(trStartPos) -- prop:SetModel("models/props_junk/PopCan01a.mdl") local tr = util.TraceLine({ start = trStartPos, endpos = trStartPos - Vector(0,0,50), mask = MASK_NPCWORLDSTATIC, }) -- local prop = ents.Create("prop_dynamic") -- prop:SetPos(tr.HitPos) -- prop:SetModel("models/props_junk/PopCan01a.mdl") -- if !tr.Hit then -- prop:SetSkin(1,2) -- end if tr.Hit then return true else /*print("no ground in front!")*/ end end ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- function ENT:APC_stop() self.CurrentMoveSpeed = 0 if self.APCDriveSound:IsPlaying() then self.APCDriveSound:Stop() self:EmitSound("vehicles/apc/apc_shutdown.wav",90,math.random(90, 110)) end end ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --ENT.CanInitBackPedal = true function ENT:BackPedal() --if !self.CanInitBackPedal or self.ShouldBackpedal then return end if self.ShouldBackpedal then return end self:APC_stop() self.ShouldBackpedal = true --self.CanInitBackPedal = false --print("doing backpedal..") local backpedaltime = 3 timer.Simple(backpedaltime, function() if IsValid(self) then self:APC_stop() self.ShouldBackpedal = false --print("backpedal done!") end end) --local nextbackpedal = 4 --timer.Simple(nextbackpedal, function() if IsValid(self) then self.CanInitBackPedal = true print("backpedal cooldown finished!") end end) end ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- function ENT:APCOnGround() local tr_ent = util.TraceEntity({ start = self:GetPos() + self:GetUp()*10, endpos = self:GetPos() + self:GetUp()*-25, mask = MASK_NPCWORLDSTATIC },self) if tr_ent.Hit then return true end end ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- function ENT:Brake(activate) if !self.BrakeActive && activate == true then self.BrakeActive = true local wheels = { self.Wheel_FL, self.Wheel_FR, self.Wheel_RL, self.Wheel_RR, } for _,wheel in pairs(wheels) do local weld = constraint.Weld(wheel, self, 0, 0, 0, false, false) end elseif self.BrakeActive && activate == false then self.BrakeActive = false constraint.RemoveConstraints(self, "Weld") end end ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- function ENT:CustomOnThink() if self.ShouldDrive then self:Brake(false) else self:Brake(true) end if !self.APCDriveSound then self.APCDriveSound = CreateSound(self,"vehicles/apc/apc_firstgear_loop1.wav") self.APCDriveSound:SetSoundLevel(95) end end ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ENT.CurrentMoveSpeed = 0 ENT.CurrentTurnSpeed = 0 function ENT:DriveThink() local phys = self:GetPhysicsObject() local enemy = self:GetEnemy() ---------------------------------------------------------------------------------------------------------------------- -- Decide if we should drive/backpedal: ---------------------------------------------------------------------------------------------------------------------- if !self.VJ_IsBeingControlled then if IsValid(enemy) then local localang = self:WorldToLocalAngles((self:GetPos()-enemy:GetPos()):Angle() + Angle(0,-90,0)) local enemy_outside_of_rocket_ang = math.abs(localang.y) < 135 local no_ground_in_front = !self:HasGroundInFrontOfSelf() --local NoChaseFlyingEnemyDist = 1000 --local flying_enemy_unreachable = self:GetPos():Distance(enemy:GetPos()) > NoChaseFlyingEnemyDist && !enemy:IsOnGround() --print("flying_enemy_unreachable = " .. tostring(flying_enemy_unreachable)) if self:Visible(enemy) && (self:EnemyInDriveDist() or enemy_outside_of_rocket_ang) /*&& !flying_enemy_unreachable*/ then self.ShouldDrive = true if !self:HasObstacle("backward") && (self:HasObstacle("forward") or no_ground_in_front or enemy_outside_of_rocket_ang) then self:BackPedal() end else self.ShouldDrive = false end else self.ShouldDrive = false end elseif self.VJ_IsBeingControlled then local controller = self.VJ_TheController if controller:KeyDown(IN_FORWARD) or controller:KeyDown(IN_BACK) then self.ShouldDrive = true if !self.ShouldBackpedal && controller:KeyDown(IN_BACK) then self:APC_stop() self.ShouldBackpedal = true elseif self.ShouldBackpedal && !controller:KeyDown(IN_BACK) then self:APC_stop() self.ShouldBackpedal = false end else self.ShouldDrive = false self.ShouldBackpedal = false end end ---------------------------------------------------------------------------------------------------------------------- -- Move/Turn: ---------------------------------------------------------------------------------------------------------------------- if self.ShouldDrive && self:APCOnGround() then if !self.APCDriveSound:IsPlaying() then self.APCDriveSound:Play() self.APCDriveSound:ChangePitch(math.random(95, 105)) end local yaw_difference = self:WorldToLocalAngles( Angle( 0 , (self:GetPos()-enemy:GetPos()):Angle().y + self.Tank_AngleDiffuseNumber, 0 ) ).y -- Turning for both controller and ai if !self.VJ_IsBeingControlled then if math.abs(yaw_difference) > 20 then self.CurrentTurnSpeed = math.Clamp(yaw_difference*0.5,-self.APC_TurnSpeedMax,self.APC_TurnSpeedMax) phys:AddAngleVelocity(Vector(0,0, self.CurrentTurnSpeed )) else self.CurrentTurnSpeed = 0 end else local controller = self.VJ_TheController if controller:KeyDown(IN_MOVERIGHT) then self.CurrentTurnSpeed = -self.APC_TurnSpeedMax if self.ShouldBackpedal then self.CurrentTurnSpeed = -self.CurrentTurnSpeed end phys:AddAngleVelocity(Vector(0,0, self.CurrentTurnSpeed )) elseif controller:KeyDown(IN_MOVELEFT) then self.CurrentTurnSpeed = self.APC_TurnSpeedMax if self.ShouldBackpedal then self.CurrentTurnSpeed = -self.CurrentTurnSpeed end phys:AddAngleVelocity(Vector(0,0, self.CurrentTurnSpeed )) else self.CurrentTurnSpeed = 0 end end if self.ShouldBackpedal && !self:HasObstacle("backward") then self.CurrentMoveSpeed = math.Clamp( self.CurrentMoveSpeed-self.APC_AccelSpeed, -self.APC_BackPedalSpeed, self.APC_DrivingSpeed ) else self.CurrentMoveSpeed = math.Clamp( self.CurrentMoveSpeed+self.APC_AccelSpeed, -self.APC_BackPedalSpeed, self.APC_DrivingSpeed ) end phys:SetVelocity( ( self:GetForward():Angle()+Angle(0,self.Tank_AngleDiffuseNumber,0) ):Forward()*self.CurrentMoveSpeed ) elseif !self:APCOnGround() then --print("not on ground!") phys:AddAngleVelocity(Vector(0,-self:GetAngles().x*1.5,0)) end if !(self.ShouldDrive && self:APCOnGround()) then self:APC_stop() end ---------------------------------------------------------------------------------------------------------------------- -- Poseparameters: ---------------------------------------------------------------------------------------------------------------------- if self.ShouldDrive then local turnposeparam = -phys:GetAngleVelocity().z*0.005 if self.ShouldBackpedal then turnposeparam = -turnposeparam end self:SetPoseParameter("vehicle_steer", turnposeparam) else self:SetPoseParameter("vehicle_steer", 0) end local wheels = { fl = self.Wheel_FL, fr = self.Wheel_FR, rl = self.Wheel_RL, rr = self.Wheel_RR, } for k,ent_wheel in pairs(wheels) do local poseparam_name = "vehicle_wheel_" .. k .. "_spin" local poseparam_add = ent_wheel:GetPhysicsObject():GetAngleVelocity().z*0.06 if k == "fr" or k == "rr" then poseparam_add = -poseparam_add end self:SetPoseParameter(poseparam_name, self:GetPoseParameter(poseparam_name) + poseparam_add) end end ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- function ENT:AimGun() local enemy = self:GetEnemy() local pos = self.ShootPos or self:GetAttachment(7).Pos+self:GetRight()*-100 local bullet_source = self:GetAttachment(7).Pos local fire_dir = (pos - bullet_source):GetNormalized() local ideal_poseparam_ang = self:WorldToLocalAngles(fire_dir:Angle()) - Angle(0,90,0) if !self.CurrentAimPoseParamAng then self.CurrentAimPoseParamAng = Angle(0,0,0) end self.CurrentAimPoseParamAng = LerpAngle(0.5, self.CurrentAimPoseParamAng, ideal_poseparam_ang) local weapon_yaw = self.CurrentAimPoseParamAng.y self:SetPoseParameter( "vehicle_weapon_yaw", weapon_yaw ) self:SetPoseParameter( "vehicle_weapon_pitch", self.CurrentAimPoseParamAng.x ) end ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- function ENT:ShootBullet() local bullet_source = self:GetAttachment(7).Pos local fire_dir = (self.ShootPos - self.bulletprop1:GetPos()):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,7) 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,7) self.bulletprop1:FireBullets({ Src = self.bulletprop1:GetPos(), Dir = fire_dir, Damage = 10, Force = 25, TracerName = "AirboatGunTracer", Spread = Vector( self.BulletSpread,self.BulletSpread,self.BulletSpread ), Num = 1, Attacker = self, Inflictor = self, Filter = self, Callback = function(attacker, tracer) -- local effectdata = EffectData() -- effectdata:SetOrigin(tracer.HitPos) -- effectdata:SetNormal(tracer.HitNormal) -- effectdata:SetRadius( 5 ) -- util.Effect( "cball_bounce", effectdata ) end, }) self:EmitSound("^weapons/ar1/ar1_dist1.wav",130,math.random(80, 90),1,CHAN_WEAPON) end ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- function ENT:FireGun(times) if self.Shooting then return end self.Shooting = true local timername = "VJ_APC_Z_ShootTimer" .. self:EntIndex() timer.Create(timername, 0.11, times, function() if !IsValid(self) or !self.ShootPos or self.Dead then timer.Remove(timername) if IsValid(self) then self.Shooting = false self.NextShootTime = CurTime() + math.Rand(self.ShootCoolDown.min, self.ShootCoolDown.max) end return end self:ShootBullet() if timer.RepsLeft(timername) == 0 then self.Shooting = false self.NextShootTime = CurTime() + math.Rand(self.ShootCoolDown.min, self.ShootCoolDown.max) end end) end ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- function ENT:FireRocket() local enemy = self:GetEnemy() local rocketspeed = 1150 local dir = enemy:GetPos()+enemy:OBBCenter() - self:GetPos() local rocket = ents.Create("obj_vj_chopper_missile_z") rocket:SetPos(self:GetAttachment(8).Pos) rocket:SetOwner(self) rocket:Spawn() rocket:GetPhysicsObject():SetVelocity( ( dir ):GetNormalized()*rocketspeed ) rocket:SetAngles( (dir):Angle() ) rocket.Target = enemy rocket.Speed = rocketspeed self.NextRocketTime = CurTime() + math.Rand(self.RocketCoolDown.min,self.RocketCoolDown.max) end ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- function ENT:CustomOnThink_AIEnabled() if self.Dead then return end self:DriveThink() self:AimGun() -- Forward or at shootpos local enemy = self:GetEnemy() if IsValid(enemy) then local enemydist = self:GetPos():Distance(enemy:GetPos()) if self:Visible(enemy) then self.ShootPos = enemy:GetPos()+enemy:OBBCenter() end if !self.VJ_IsBeingControlled then if self.ShootPos && self.NextShootTime < CurTime() && enemydist < self.ShootDist then self:FireGun( math.Rand(self.Shots.min,self.Shots.max) ) end if self:Visible(enemy) && self.NextRocketTime < CurTime() && enemydist < self.RocketDistance then local fire_dir = ( enemy:GetPos() - self:GetAttachment(7).Pos ):GetNormalized() local localang = self:WorldToLocalAngles(fire_dir:Angle() + Angle(0,-90,0)) if math.abs(localang.x) < 90 && math.abs(localang.y) < 90 then self:FireRocket() end end else local controller = self.VJ_TheController if controller:KeyDown(IN_ATTACK) then self:ShootBullet() end if self:Visible(enemy) && self.NextRocketTime < CurTime() && controller:KeyDown(IN_ATTACK2) then self:FireRocket() end end else self.ShootPos = nil end end ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- function ENT:CustomOnDeath_AfterCorpseSpawned(dmginfo, hitgroup, corpseEnt) self:EmitSound( "Explo.ww2bomb", 130, 100) local effectdata = EffectData() effectdata:SetOrigin(self:GetPos()) effectdata:SetScale( 500 ) util.Effect( "Explosion", effectdata ) ParticleEffect("vj_explosion1", self:GetPos(), Angle(0,0,0), nil) ParticleEffect( "striderbuster_explode_dummy_core", self:GetPos(), self:GetAngles() ) corpseEnt:GetPhysicsObject():SetVelocity(VectorRand()*150+Vector(0,0,150)) self:CreateGibEntity("obj_vj_gib","models/combine_apc_destroyed_gib02.mdl",{BloodType = "",Vel = self:GetVelocity()+VectorRand()*600, CollideSound = {"SolidMetal.ImpactSoft"}}) self:CreateGibEntity("obj_vj_gib","models/combine_apc_destroyed_gib03.mdl",{BloodType = "",Vel = self:GetVelocity()+VectorRand()*600, CollideSound = {"SolidMetal.ImpactSoft"}}) self:CreateGibEntity("obj_vj_gib","models/combine_apc_destroyed_gib04.mdl",{BloodType = "",Vel = self:GetVelocity()+VectorRand()*600, CollideSound = {"SolidMetal.ImpactSoft"}}) self:CreateGibEntity("obj_vj_gib","models/combine_apc_destroyed_gib05.mdl",{BloodType = "",Vel = self:GetVelocity()+VectorRand()*600, CollideSound = {"SolidMetal.ImpactSoft"}}) end ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- function ENT:DoSpark(pos,intensity) intensity = intensity or 1 local spark = ents.Create("env_spark") spark:SetKeyValue("Magnitude",tostring(intensity)) spark:SetKeyValue("Spark Trail Length",tostring(intensity)) spark:SetPos(pos) spark:Spawn() spark:Fire("StartSpark", "", 0) timer.Simple(0.1, function() if IsValid(spark) then spark:Remove() end end) end ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- function ENT:CustomOnTakeDamage_BeforeDamage(dmginfo, hitgroup) self.HasPainSounds = true -- If set to false, it won't play the pain sounds if !dmginfo:IsExplosionDamage() then dmginfo:SetDamage(dmginfo:GetDamage() * 0.1) if math.random(1, 4) == 1 then self:EmitSound("physics/metal/metal_sheet_impact_bullet1.wav", 92, math.random(70, 90)) self.Spark1 = ents.Create("env_spark") self.Spark1:SetPos(dmginfo:GetDamagePosition()) self.Spark1:Spawn() self.Spark1:Fire("StartSpark", "", 0) self.Spark1:Fire("StopSpark", "", 0.001) self:DeleteOnRemove(self.Spark1) end self.HasPainSounds = false -- If set to false, it won't play the pain sounds else self:DoSpark(dmginfo:GetDamagePosition(),5) end end ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- function ENT:CustomOnRemove() if self.APCDriveSound then self.APCDriveSound:Stop() end self.APCAlarm:Stop() end -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------