Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- if wac then
- MsgC( Color( 255, 0, 0 ), "WAC and HVAP are both installed and are incompatable, remove WAC to regain HVAP functionality." )
- PrintMessage( HUD_PRINTCENTER, "WAC and HVAP are both installed and are incompatable, remove WAC to regain HVAP functionality." )
- PrintMessage( HUD_PRINTTALK, "WAC and HVAP are both installed and are incompatable, remove WAC to regain HVAP functionality." )
- return end
- include("shared.lua")
- AddCSLuaFile("cl_init.lua")
- AddCSLuaFile("shared.lua")
- include("hvap/aircraft.lua")
- util.AddNetworkString("hvap.aircraft.updateWeapons")
- function ENT:Initialize()
- hvap.aircraft.initialize()
- self.Entity:SetModel(self.Model)
- self.Entity:PhysicsInit(SOLID_VPHYSICS)
- self.Entity:SetMoveType(MOVETYPE_VPHYSICS)
- self.Entity:SetSolid(SOLID_VPHYSICS)
- self.phys = self:GetPhysicsObject()
- if self.phys:IsValid() then
- self.phys:SetMass(self.Weight)
- self.phys:EnableDrag(false)
- self.phys:Wake()
- end
- local skins = self:SkinCount()
- if skins != 1 then
- skin = math.random(skins)
- self:SetSkin(skin)
- end
- self.BBoxRadius = (self:OBBMins()-self:OBBMaxs()):Length()
- self.Children = {}
- self.CamData = {}
- self.OnRemoveEntities={}
- self.OnRemoveFunctions={}
- self.wheels = {}
- self.NumEngines = #self.Engines
- self.NumRotors = #self.Rotors
- self.nextUpdate = 0
- self.CvarTick = 0
- self.LastDamageTaken = 0
- self.hvap_seatswitch = true
- self.rotorRpm = 0
- self.EnginesRPM = 0
- self.EnginePower = 0
- self.LastPhys = 0
- self.Roll = 0
- self.Pitch = 0
- self.Yaw = 0
- self.Throttle = 0
- self.SmoothThrottle = 0
- self.Boost = false
- self.ThrSensitivity = 1
- self.FuselageHPMult = hvap.aircraft.cvars.fhealthmul:GetFloat()
- self.EngineHPMult = hvap.aircraft.cvars.ehealthmul:GetFloat()
- self.RotorHPMult = hvap.aircraft.cvars.rhealthmul:GetFloat()
- self.StartSpd = hvap.aircraft.cvars.startSpeed:GetFloat()
- self.EnableFuel = tobool(hvap.aircraft.cvars.fuelenable:GetInt())
- self.FuelConMultCvar = hvap.aircraft.cvars.fuelconsumptionmult:GetFloat()
- self.SpeedMult = hvap.aircraft.cvars.speedMult:GetInt()
- self.PilotDamageCvar = hvap.aircraft.cvars.noplayerdamage:GetInt()
- self.waterDamage = hvap.aircraft.cvars.waterDamage:GetInt()
- if self.FuselageHPMult > 0 then
- self.FuselageHealth = self.FuselageHealth*self.FuselageHPMult
- self.Unbreakable = false
- else
- self.Unbreakable = true
- end
- self.FuselageBaseHealth = self.FuselageHealth
- self.CriticalHealth = self.FuselageBaseHealth*4
- self.CriticalBaseHealth = self.CriticalHealth
- self.EnginesMaxHealth = 0
- self.FSCL = 1
- self.BaseFuel = self.Fuel
- self.passengers = {}
- self.controls = {
- throttle = 0,
- pitch = 0,
- yaw = 0,
- roll = 0,
- }
- self.disabled = false
- self.dead = false
- self.CriticalDeath = false
- self.spinout = false
- self.Refueling = false
- self.GearDown = false
- self:LandingGear(false)
- self:addSounds()
- self:addEngines()
- self:addRotors()
- self:addWheels()
- self:addTurrets()
- self:addWeapons()
- self:addCountermeasures()
- self:addSeats()
- self:addNpcTargets()
- self:addExtras()
- self:SecondaryInitialize()
- if self.HasDoors and self.DoorFlip then
- self:SetBodygroup(self.DoorBodygroup, 1)
- end
- self.DoorIsOpen = true
- local effectdata = EffectData()
- effectdata:SetEntity( self )
- util.Effect( "hvap_spawn", effectdata, true, true )
- table.insert(self.Children, self)
- end
- function ENT:SecondaryInitialize()
- end
- function ENT:SpawnFunction( ply, tr, ClassName )
- if ( !tr.Hit ) then return end
- local SpawnPos = tr.HitPos + tr.HitNormal * self.SpawnHeight
- local SpawnAng = ply:EyeAngles()
- SpawnAng.p = 0
- SpawnAng.y = SpawnAng.y + 180
- local ent = ents.Create( ClassName )
- ent:SetCreator( ply )
- ent:SetPos( SpawnPos )
- ent:SetAngles( SpawnAng )
- ent:Spawn()
- ent:Activate()
- ent.Owner=ply
- ent.SpawnedBy=ply
- return ent
- end
- function ENT:addEntity(name, nofx)
- local e = ents.Create(name)
- if !IsValid(e) then return nil end
- if !nofx then
- local effectdata = EffectData()
- effectdata:SetEntity( e )
- util.Effect( "hvap_spawn", effectdata, true, true )
- end
- table.insert(self.Children, e)
- e.Owner = self.Owner
- e:SetNWEntity("hvap_aircraft", self)
- e.aircraft = self
- return e
- end
- function ENT:UpdateTransmitState() return TRANSMIT_PVS end -- TRANSMIT_ALWAYS
- function ENT:addNpcTargets()
- for _,s in pairs(self.HatingNPCs) do
- self:Fire("SetRelationShip", s.." D_HT 99")
- end
- end
- function ENT:addEngines()
- self.engines = {}
- for k, v in pairs(self.Engines) do
- if k != "BaseClass" then
- local eng = self:addEntity("hvap_engine", true)
- eng:SetPos(self:LocalToWorld(v.pos))
- eng:SetAngles(self:GetAngles())
- eng:SetParent(self)
- for index, value in pairs(v.info) do
- eng[index] = value
- end
- eng:Spawn()
- eng:Activate()
- self.engines[k] = eng
- self:AddOnRemove(eng)
- end
- end
- for i = 1, self.NumEngines do
- self.EnginesMaxHealth = self.EnginesMaxHealth+self.engines[i].BaseHealth
- end
- end
- function ENT:addRotors()
- self.rotors={}
- for k, v in pairs(self.Rotors) do
- if k != "BaseClass" then
- if !v.istail then
- local rotor = self:addEntity("hvap_rotor", false)
- rotor:SetPos(self:LocalToWorld(v.pos))
- rotor:SetAngles(self:LocalToWorldAngles(v.ang))
- rotor:SetModel(v.model)
- for index, value in pairs(v.info) do
- rotor[index] = value
- end
- rotor:Spawn()
- rotor:Activate()
- self.rotors[k] = rotor
- self:AddOnRemove(rotor)
- if rotor:IsValid() then
- constraint.Axis(self.Entity, rotor, 0, 0, v.pos, Vector(0,0,1), 0,0,0.01,1)
- end
- else
- local trotor = self:addEntity("hvap_rotor_r", false)
- trotor:SetPos(self:LocalToWorld(v.pos))
- trotor:SetAngles(self:LocalToWorldAngles(v.ang))
- trotor:SetModel(v.model)
- for index, value in pairs(v.info) do
- trotor[index] = value
- end
- trotor:Spawn()
- trotor:Activate()
- self.RearRotor = trotor
- self.rotors[k] = trotor
- self:AddOnRemove(trotor)
- if trotor:IsValid() then
- constraint.Axis(self.Entity, trotor, 0, 0, v.pos, Vector(0, 1, 0), 0,0,0.01,1)
- end
- end
- end
- end
- end
- function ENT:addWeapons()
- self.weapons = {}
- self.weapons2 = {}
- for i, w in pairs(self.Weapons) do
- if i != "BaseClass" then
- local pod = ents.Create(w.class)
- pod:SetPos(self:GetPos()+Vector(0,0,32))
- pod:SetAngles(self:GetAngles())
- pod:SetParent(self)
- for index, value in pairs(w.info) do
- pod[index] = value
- end
- if w.info.Attach then
- pod:SetNWEntity( "hvap_turret_gun", self.turrets[w.info.Turret][w.info.Pod][w.info.Attach])
- end
- pod.aircraft = self
- pod:Spawn()
- pod:Activate()
- pod:SetNoDraw(true)
- pod:SetNWEntity("hvap_aircraft", self)
- pod.podIndex = i
- self.weapons[i] = pod
- self:AddOnRemove(pod)
- table.insert(self.Children, pod)
- end
- end
- for i, w in pairs(self.Weapons2) do
- if i != "BaseClass" then
- local pod2 = ents.Create(w.class)
- pod2:SetPos(self:GetPos()+Vector(0,0,32))
- pod2:SetAngles(self:GetAngles())
- pod2:SetParent(self)
- for index, value in pairs(w.info) do
- pod2[index] = value
- end
- if w.info.Attach then
- pod2:SetNWEntity( "hvap_turret_gun", self.turrets[w.info.Turret][w.info.Pod][w.info.Attach])
- end
- pod2.aircraft = self
- pod2:Spawn()
- pod2:Activate()
- pod2:SetNoDraw(true)
- pod2:SetNWEntity("hvap_aircraft", self)
- pod2.podIndex = i
- self.weapons2[i] = pod2
- self:AddOnRemove(pod2)
- table.insert(self.Children, pod2)
- end
- end
- end
- function ENT:addSeats()
- self.seats = {}
- local e = self:addEntity("hvap_seat_connector", true)
- e:SetPos(self:LocalToWorld(self.SeatSwitcherPos))
- e:SetNoDraw(true)
- e:Spawn()
- e:Activate()
- e.hvap_ignore = true
- e:SetNotSolid(true)
- e:SetParent(self)
- self:SetSwitcher(e)
- for k, v in pairs(self.Seats) do
- if k != "BaseClass" then
- local ang = self:GetAngles()
- self.seats[k] = self:addEntity("prop_vehicle_prisoner_pod", true)
- self.seats[k].activeProfile = 1
- self.seats[k].Number = k
- self.seats[k]:SetModel("models/nova/airboat_seat.mdl")
- self.seats[k]:SetPos(self:LocalToWorld(v.pos))
- self.seats[k]:Spawn()
- self.seats[k]:Activate()
- self.seats[k]:SetNWInt("selectedWeapon", 0)
- if v.ang then
- local a = self:GetAngles()
- a.y = a.y-90
- a:RotateAroundAxis(Vector(0,0,1), v.ang.y)
- self.seats[k]:SetAngles(a)
- else
- ang:RotateAroundAxis(self:GetUp(), -90)
- self.seats[k]:SetAngles(ang)
- end
- self.seats[k]:SetNoDraw(true)
- self.seats[k]:SetNotSolid(true)
- self.seats[k]:SetParent(self)
- self.seats[k]:SetKeyValue( "limitview", 0 )
- self:SetNWInt("seat_"..k.."_actwep", 1)
- self:SetNWInt("seat_"..k.."_actwep2", 1)
- e:addVehicle(self.seats[k])
- end
- end
- end
- function ENT:addTurrets()
- self.turrets = {}
- if !self.Turrets then return end
- for k, v in pairs(self.Turrets) do
- local pods = {}
- local info = {}
- for podk, podv in pairs(v.pods) do
- local part = {}
- for partk, partv in pairs(podv) do
- local t = self:addEntity("hvap_turret")
- t:SetPos(self:LocalToWorld(partv.pos))
- t:SetAngles(self:LocalToWorldAngles(v.info.ang or Angle()))
- t:SetModel(partv.model)
- t:SetParent(self)
- for index, value in pairs(partv) do
- t[index] = value
- end
- t:Spawn()
- t:Activate()
- t.restrictPitch = partv.restrictPitch
- t.restrictYaw = partv.restrictYaw
- t.offset = partv.offset
- t.Turret = k
- self:SetNWEntity("hvap_"..k.."_"..podk.."_"..partk, t)
- self:AddOnRemove(t)
- part[partk] = t
- end
- pods[podk] = part
- end
- self.turrets[k] = pods
- for infok, infov in pairs(v.info) do
- info[infok] = infov
- end
- self.turrets[k].info = info
- end
- end
- function ENT:addExtras()
- if self.Extras then
- for k, v in pairs(self.Extras) do
- local e = self:addEntity("hvap_extra")
- e:SetPos(self:LocalToWorld(v.pos))
- e:SetAngles(self:GetAngles()+v.ang)
- e:SetModel(v.model)
- e:SetNotSolid(true)
- e.IsHVAP = true
- e.IsHVAPAircraft = true
- e.IsHVAPPlane = false
- e.IsHVAPGround = false
- e:SetParent(self)
- e:Spawn()
- e:Activate()
- self:AddOnRemove(e)
- end
- end
- end
- function ENT:addWheels()
- if !self.Wheels then return end
- self.NumWheels = #self.Wheels
- for _,t in pairs(self.Wheels) do
- if t != "BaseClass" then
- if t.mdl then
- local e=self:addEntity("hvap_entity")
- e:SetModel(t.mdl)
- e:SetPos(self:LocalToWorld(t.pos))
- e:SetAngles(self:GetAngles())
- e.health = self.FuselageHealth
- e.Unbreakable = self.Unbreakable
- e.Type = "Wheel"
- e:Spawn()
- e:Activate()
- local ph=e:GetPhysicsObject()
- ph:SetMass(t.mass)
- ph:EnableDrag(false)
- e:SetGravity(0.01)
- ph:SetMaterial( "rubbertire" )
- constraint.Axis(e,self,0,0,Vector(0,0,0),self:WorldToLocal(e:LocalToWorld(Vector(0,1,0))),0,0,t.friction,1)
- table.insert(self.wheels,e)
- self:AddOnRemove(e)
- end
- end
- end
- end
- function ENT:addCountermeasures()
- for i, w in pairs(self.CounterMeasures) do
- if i != "BaseClass" then
- local pod = ents.Create(w.class)
- pod:SetPos(self:GetPos())
- pod:SetAngles(self:GetAngles())
- pod:SetParent(self)
- for index, value in pairs(w.info) do
- pod[index] = value
- end
- pod.aircraft = self
- pod.entTable = self.OnRemoveEntities
- pod:Spawn()
- pod:Activate()
- pod:SetNWEntity("hvap_aircraft", self)
- pod:SetNoDraw(true)
- self.countermeasure = pod
- self:AddOnRemove(pod)
- end
- end
- end
- function ENT:MakeGibs()
- if !self.Gibs then return end
- for k, v in pairs(self.Gibs) do
- if k != "BaseClass" then
- local gib = ents.Create("hvap_entity")
- gib:SetModel(t.mdl)
- gib:SetPos(self:LocalToWorld(t.pos))
- gib:SetAngles(self:GetAngles())
- gib.health = self.FuselageHealth/2
- gib.Unbreakable = false
- gib.Type = "Gib"
- gib:Spawn()
- gib:Activate()
- local ph=gib:GetPhysicsObject()
- ph:SetMass(t.mass)
- ph:EnableDrag(false)
- end
- end
- end
- function ENT:LandingGear(b)
- if !self.HasGear then return end
- if b then
- self.GearDown = true
- elseif self.GearDown then
- self.GearDown = false
- end
- local geardown,t1=self:LookupSequence(self.GearUpAnim)
- local gearup,t2=self:LookupSequence(self.GearDownAnim)
- if !self.disabled then
- if b then
- self:ResetSequence(gearup)
- self:SetPlaybackRate(1.0)
- self:SetBodygroup(self.GearBodygroup,1)
- for i=1,#self.wheels do
- self.wheels[i]:SetRenderMode(RENDERMODE_TRANSALPHA)
- self.wheels[i]:SetColor(Color(255,255,255,0))
- self.wheels[i]:SetSolid(SOLID_NONE)
- end
- elseif !b then
- self:ResetSequence(geardown)
- self:SetPlaybackRate(1.0)
- self:SetBodygroup(self.GearBodygroup,0)
- for i=1,#self.wheels do
- self.wheels[i]:SetRenderMode(RENDERMODE_NORMAL)
- self.wheels[i]:SetColor(Color(255,255,255,255))
- self.wheels[i]:SetSolid(SOLID_VPHYSICS)
- end
- end
- end
- end
- function ENT:Doors(b)-- true closed, false open
- if b then
- if self.DoorOpen then return end
- self.DoorOpen = true
- elseif self.DoorOpen then
- self.DoorOpen=false
- end
- if !self.DoorFlip then
- self:SetBodygroup(self.DoorBodygroup, b and 1 or !b and 0)
- else
- self:SetBodygroup(self.DoorBodygroup, b and 0 or !b and 1)
- end
- self.DoorIsOpen = !self.DoorIsOpen
- end
- function ENT:fireWeapon1(bool, i)
- if !self.Seats[i].weapons then return end
- local pod = self.weapons[self.Seats[i].weapons[self.seats[i].activeProfile]]
- if !pod then return end
- pod.shouldFire = bool
- pod:trigger(bool, self.seats[i])
- -- self.Entity:SetPoseParameter("minigun_fire", 12)
- end
- function ENT:fireWeapon2(bool, i)
- if !self.Seats[i].weapons2 then return end
- local pod = self.weapons2[self.Seats[i].weapons2[self.seats[i].activeProfile]]
- if !pod then return end
- pod.shouldFire = bool
- pod:trigger(bool, self.seats[i])
- end
- function ENT:fireCounter(bool, i)
- if !self.CounterMeasures then return end
- local pod = self.countermeasure
- if !pod then return end
- pod.shouldFire = bool
- pod:trigger(bool, self.seats[1])
- end
- function ENT:nextWeapon(i, p)
- if !self.Seats[i].weapons then return end
- local seat = self.seats[i]
- local Seat = self.Seats[i]
- local pod = self.weapons[Seat.weapons[seat.activeProfile]]
- if pod then
- pod:select(false)
- pod.seat = nil
- end
- if self.Seats[i].weapons2 then
- local pod2 = self.weapons2[Seat.weapons2[seat.activeProfile]]
- if pod2 then
- pod2:select(false)
- pod2.seat = nil
- end
- end
- if seat.activeProfile == #Seat.weapons then
- seat.activeProfile = 0
- else
- seat.activeProfile = seat.activeProfile + 1
- end
- if Seat.weapons[seat.activeProfile] then
- local weapon = self.weapons[Seat.weapons[seat.activeProfile]]
- weapon:select(true)
- weapon.seat = seat
- end
- self:SetNWInt("seat_"..i.."_actwep", seat.activeProfile)
- if self.Seats[i].weapons2 then
- if Seat.weapons2[seat.activeProfile] then
- local weapon = self.weapons2[Seat.weapons2[seat.activeProfile]]
- weapon:select(true)
- weapon.seat = seat
- end
- self:SetNWInt("seat_"..i.."_actwep2", seat.activeProfile)
- end
- end
- function ENT:EjectPassenger(ply,idx,t)
- if !idx then
- for k,p in pairs(self.passengers) do
- if p==ply then idx=k end
- end
- if !idx then
- return
- end
- end
- ply.LastVehicleEntered = CurTime()+0.5
- ply:ExitVehicle()
- ply:SetPos(self:LocalToWorld(self.Seats[idx].exit))
- ply:SetVelocity(self:GetPhysicsObject():GetVelocity()*1.6)
- ply:SetEyeAngles((self:LocalToWorld(self.Seats[idx].pos-Vector(0,0,40))-ply:GetPos()):Angle())
- self:updateSeats()
- end
- function ENT:Bail(ply,idx,t)
- if !idx then
- for k,p in pairs(self.passengers) do
- if p==ply then idx=k end
- end
- if !idx then
- return
- end
- end
- ply.LastVehicleEntered = CurTime()+0.5
- ply:ExitVehicle()
- ply:SetPos(self:LocalToWorld(self.Seats[idx].exit+Vector(0,self.Seats[idx].exit.y*4,256)))
- ply:SetVelocity(self:GetPhysicsObject():GetVelocity()*-0.64 +Vector(0,0,1024+self:GetPhysicsObject():GetVelocity().z))
- ply:SetEyeAngles((self:LocalToWorld(self.Seats[idx].pos-Vector(0,0,40))-ply:GetPos()):Angle())
- self:updateSeats()
- end
- function ENT:Use(act, cal)
- if self.disabled then return end
- if act.hvap and act.hvap.lastEnter and act.hvap.lastEnter+0.5 > CurTime() then return end
- local d = self.MaxEnterDistance
- local v
- local num
- for k, veh in pairs(self.seats) do
- if veh and veh:IsValid() then
- local psngr = veh:GetPassenger(0)
- if !psngr or !psngr:IsValid() then
- local dist = veh:GetPos():Distance(util.QuickTrace(act:GetShootPos(),act:GetAimVector()*self.MaxEnterDistance,act).HitPos)
- if dist < d then
- d = dist
- v = veh
- num = k
- end
- end
- end
- end
- act.hvap = act.hvap or {}
- act.hvap.lastEnter = CurTime()
- if v and num < 3 then
- act:EnterVehicle(v)
- elseif v and num >= 3 then
- if self.DoorIsOpen then
- act:EnterVehicle(v)
- else
- sound.Play( "HVAP.Gun.Misc.NoSecondary", act:GetPos() )
- end
- end
- self:updateSeats()
- end
- function ENT:updateSeats()
- for k, veh in pairs(self.seats) do
- if !veh:IsValid() then return end
- local p = veh:GetPassenger(0)
- if self.passengers[k] != p then
- if IsValid(self.passengers[k]) then
- self.passengers[k]:SetNWEntity("hvap_aircraft", NULL)
- end
- self:SetNWEntity("passenger_"..k, p)
- self.passengers[k] = p
- if IsValid(p) then
- p:SetNWInt("hvap_passenger_id",k)
- p.hvap = p.hvap or {}
- p.hvap.mouseInput = true
- p.hvap.viewAngs = Angle()
- net.Start("hvap.aircraft.updateWeapons")
- net.WriteEntity(self)
- net.WriteInt(table.Count(self.weapons), 5)
- for name, weapon in pairs(self.weapons) do
- net.WriteString(name)
- net.WriteEntity(weapon)
- end
- net.WriteInt(table.Count(self.weapons2), 5)
- for name, weapon2 in pairs(self.weapons2) do
- net.WriteString(name)
- net.WriteEntity(weapon2)
- end
- net.Send(p)
- end
- end
- end
- if !IsValid(self.seats[1]:GetDriver()) then
- self.controls = {
- throttle = 0,
- pitch = 0,
- yaw = 0,
- roll = 0,
- }
- self.IncrementalThr = 0
- self.ThrSensitivity = 0
- self.AutoLevel = 1
- else
- self.IncrementalThr = self.seats[1]:GetDriver():GetInfoNum("hvap_cl_air_incthr", 0)
- self.AutoLevel = self.seats[1]:GetDriver():GetInfoNum("hvap_cl_air_autolevel", 1)
- self.ThrSensitivity = self.seats[1]:GetDriver():GetInfoNum("hvap_cl_air_throttle_sensitivity", 5)
- end
- self:GetSwitcher():updateSeats()
- end
- function ENT:StopAllSounds()
- for k, s in pairs(self.sounds) do
- if s:IsPlaying() then
- s:Stop()
- end
- end
- end
- function ENT:RocketAlert()
- if self.active and !self.disabled and !self.Unbreakable then
- local b=false
- local rockets = ents.FindByClass("hvap_bullet_rocket2")
- for _, e in pairs(rockets) do
- if e:GetPos():Distance(self:GetPos()) < 7680 and e.target == self then b = true break end
- end
- if self.sounds.MissileAlert:IsPlaying() then
- if !b then
- self.sounds.MissileAlert:Stop()
- self.Targeted = false
- end
- elseif b then
- self.sounds.MissileAlert:Play()
- self.Targeted = true
- end
- end
- end
- function ENT:calcAerodynamics(ph)
- local dvel = self:GetVelocity():Length()
- local lvel = self:WorldToLocal(self:GetPos() + self:GetVelocity())
- local targetVelocity = (
- - self:LocalToWorld(self.Aerodynamics.Rail * lvel * dvel * dvel / 1000000000) + self:GetPos()
- + self:LocalToWorld(
- self.Aerodynamics.Movement.Forwards * lvel.x * dvel / 10000000 +
- self.Aerodynamics.Movement.Right * Vector(math.abs(lvel.y),lvel.y,lvel.y) * dvel / 10000000 +
- self.Aerodynamics.Movement.Up * lvel.z * dvel / 10000000
- ) - self:GetPos()
- )
- local targetAngVel =
- (
- lvel.x*self.Aerodynamics.Rotation.Forwards +
- lvel.y*self.Aerodynamics.Rotation.Right +
- lvel.z*self.Aerodynamics.Rotation.Up
- ) / 10000 - ph:GetAngleVelocity()*self.Aerodynamics.AngleDrag
- return targetVelocity, targetAngVel
- end
- function ENT:Think()
- local crt = CurTime()
- local frt = FrameTime()
- ------------------------------------------------------------------------------------------------coop brings all engines to one rotor, separate brings engine to rotor
- local rpm = 0
- local power = 0
- local rotrpm = 0
- local rotcap = 0
- local ehealth = 0
- local vel = self.phys:GetVelocity()
- -- local spd = math.Round(vel:Length()*0.068796244/2,1)
- local pos = self:GetPos()
- local ang = self:GetAngles()
- if self.CoopEngines then -----coop calc engines to rotors
- for i = 1, self.NumEngines do
- rpm = rpm + self.engines[i].RPMSCL
- power = power + self.engines[i].enginePower
- end
- self.EnginesRPM = rpm/self.NumEngines
- self.EnginePower = power
- if !self.rotors[1].Disabled then
- self.rotors[1].EngRpm = self.EnginesRPM
- self.rotorRpm = self.rotors[1].rotorRPM
- else
- self.rotorRpm = 0
- end
- else ------separate calc engine to rotor assuming 1 engine per rotor
- for i = 1, self.NumEngines do
- rpm = rpm + self.engines[i].RPMSCL
- power = power + self.engines[i].enginePower
- end
- self.EnginesRPM = rpm/self.NumEngines
- self.EnginePower = power
- for i = 1, self.NumEngines do
- if !self.rotors[i].Disabled then
- self.rotors[i].EngRpm = self.engines[i].RPMSCL
- end
- end
- for i = 1, self.NumEngines do
- if !self.rotors[i].Disabled then
- rotrpm = rotrpm + self.rotors[i].rotorRPM
- end
- end
- self.rotorRpm = rotrpm/self.NumRotors
- end
- ------------------------------------------------------------------------------------------------throttle calc
- self.Hover = self:calcHover(self.phys,pos,vel,ang)
- self.Autolvl = self:autoLevelCalc(self.phys,pos,vel,ang)
- self.Roll = self.Hover.r+self.Autolvl.r
- self.Pitch = self.Hover.p+self.Autolvl.p
- self.Yaw = math.Clamp(self.Yaw - (self.Yaw - math.abs(self.controls.yaw))/20,0,1)
- local thr = math.Clamp(self.Hover.t+self.Autolvl.t, -1, 1)
- if self.IncrementalThr == 1 then
- self.Throttle = math.Clamp(self.Throttle+(self.controls.throttle*self.ThrSensitivity/256)+thr, -1, 1)
- elseif self.IncrementalThr == 0 then
- self.SmoothThrottle = math.Clamp(self.SmoothThrottle - (self.SmoothThrottle - math.pow( math.abs(self.controls.throttle), 10 ))/50,0,1)
- self.Throttle = math.Clamp(self.SmoothThrottle*self.controls.throttle+thr, -1, 1)
- end
- ------------------------------------------------------------------------------------------------fuelcalc
- if self.EnableFuel then
- local mul = (hvap.aircraft.cvars.fuelconsumptionmult:GetFloat()*self.FuelConMult*frt)/25
- local subval = 0
- for k, v in pairs(self.engines) do
- subval = (subval + v.FuelSub)
- end
- if subval < math.huge then
- self.Fuel = math.Clamp(self.Fuel - (subval + (self.active and (math.abs(self.Throttle) + ((1-self.FSCL)*math.random(0.01,0.5))) or 0) )*mul, 0, self.BaseFuel)
- end
- self.FuelScl = self.Fuel/self.BaseFuel
- if self.active and self.EnableFuel then
- if self.FuelScl <= 0.15 or self.FSCL <= 0.15 then
- if math.random(0,512) == 256 then
- self.active = false
- end
- end
- end
- if self.active and self.FuelScl <= 0 then
- self.active = false
- end
- if self.Refueling then
- if !self.sounds.Refuel:IsPlaying() then
- self.sounds.Refuel:PlayEx(1,80+self.FuelScl*25)
- else
- self.sounds.Refuel:ChangePitch(80+self.FuelScl*25,0.1)
- end
- else
- if self.sounds.Refuel:IsPlaying() then
- self.sounds.Refuel:Stop()
- end
- end
- end
- ------------------------------------------------------------------------------------------------engine health calc
- for i = 1, self.NumEngines do
- ehealth = ehealth + self.engines[i].engineHealth
- end
- self.EnginesHealth = ehealth/self.EnginesMaxHealth
- ------------------------------------------------------------------------------------------------
- self.FSCL = math.Clamp(self.FuselageHealth/self.FuselageBaseHealth,0,1)
- ------------------------------------------------------------------------------------------------
- if self.nextUpdate<crt then
- self:RocketAlert()
- self.Refueling = false
- self.nextUpdate = crt+0.2
- if self.FuselageHealth > 0 then
- local tr=util.QuickTrace(pos,Vector(0,0,-999999),self.Entity)
- self.ALT = pos.z-tr.HitPos.z
- end
- if self:WaterLevel() > 0 and self.waterDamage > 0 then
- self:DamageFuselage(self:WaterLevel()*self.waterDamage)
- end
- if self.active and self.EnableFuel then
- if self.FuelScl <= 0.15 or self.FSCL <= 0.15 then
- if math.random(0,512) == 256 then
- self.active = false
- end
- end
- if self.FuelScl <= 0 then
- self.active = false
- end
- end
- if self.skin != self:GetSkin() then
- self.skin = self:GetSkin()
- self:updateSkin(self.skin)
- end
- end
- ------------------------------------------------------------------------------------------------
- if self.CvarTick<crt then
- self.CvarTick = crt+4
- self.StartSpd = hvap.aircraft.cvars.startSpeed:GetFloat()
- self.EnableFuel = tobool(hvap.aircraft.cvars.fuelenable:GetInt())
- self.FuelConMultCvar = hvap.aircraft.cvars.fuelconsumptionmult:GetFloat()
- self.SpeedMult = hvap.aircraft.cvars.speedMult:GetInt()
- self.PilotDamageCvar = hvap.aircraft.cvars.noplayerdamage:GetInt()
- self.waterDamage = hvap.aircraft.cvars.waterDamage:GetInt()
- end
- ------------------------------------------------------------------------------------------------
- if !self.dead and self.FSCL == 0 then
- if hvap.aircraft.cvars.kickdeath:GetInt() == 1 then
- for i = 1, #self.seats do
- if self.passengers[i]:IsValid() then
- self:Bail(self.passengers[i])
- end
- end
- end
- local effectdata = EffectData()
- effectdata:SetOrigin(self.Entity:GetPos())
- effectdata:SetScale((self.FuselageBaseHealth/self.FuselageHPMult)/50)
- util.Effect("hvap_explode", effectdata)
- util.BlastDamage(self.Entity, self.Entity, self:GetPos(), (self.FuselageBaseHealth/self.FuselageHPMult)/5, self.BBoxRadius)
- self.dead = true
- self.active = false
- end
- ------------------------------------------------------------------------------------------------
- if self.CriticalDeath then
- local effectdata = EffectData()
- effectdata:SetOrigin(self.Entity:GetPos())
- effectdata:SetScale(self.FuselageBaseHealth/32)
- util.Effect("hvap_explode", effectdata)
- util.BlastDamage(self.Entity, self.Entity, self:GetPos(), (self.FuselageBaseHealth/self.FuselageHPMult)/5, self.BBoxRadius)
- self:MakeGibs()
- self:Remove()
- end
- ------------------------------------------------------------------------------------------------
- if self.skin != self:GetSkin() then
- self.skin = self:GetSkin()
- self:updateSkin(self.skin)
- end
- ------------------------------------------------------------------------------------------------
- self:updateSeats()
- self:TurretThink()
- self:SecondaryThink(crt)
- self:setVar("on", self.active, true)
- self:setVar("Targeted", self.Targeted, true)
- self:setVar("up", self.Throttle)
- self:setVar("rotorRpm", self.rotorRpm)
- self:setVar("engineRpm", self.EnginesRPM)
- self:setVar("ehp", self.EnginesHealth)
- self:setVar("fhp", self.FSCL)
- self:setVar("fuel", self.FuelScl)
- self:NextThink(crt)
- return true
- end
- function ENT:SecondaryThink(crt)
- end
- function ENT:TurretThink()
- if !self.Turrets or !self.turrets then return end
- for k, v in pairs(self.turrets) do
- local tr = self:GetViewTarget(v.info)
- if tr then
- for key, value in pairs(v) do
- if key != "info" then
- for _, t in pairs(value) do
- if IsValid(t) then
- local viewAng = ( tr.HitPos - t:GetPos() ):Angle()
- viewAng:Normalize()
- local clampAng = Angle(
- t.pitch and viewAng.p or 0,
- t.yaw and viewAng.y or 0,
- viewAng.r
- )
- local setangles = LerpAngle( self.RotSPD, t:GetAngles(), clampAng )
- t:SetAngles( setangles )
- if t.localto and t.offset then
- local localtoent = self.turrets[k][key][t.localto]
- t:SetPos(localtoent:LocalToWorld(t.offset))
- end
- end
- end
- end
- end
- end
- end
- end
- function ENT:setVar(name, var, b)
- if b then
- if self:GetNWBool(name) != var then
- self:SetNWBool(name, var)
- end
- else
- if self:GetNWFloat(name) != var then
- self:SetNWFloat(name, var)
- end
- end
- end
- function ENT:receiveInput(name, value, seat)--CONTROLS
- if seat == 1 then
- if name == "Start" and value>0.5 then
- self:setEngine(!self.active)
- elseif name == "Throttle" then
- self.controls.throttle = value or 0
- elseif name == "Pitch" then
- self.controls.pitch = value or 0
- elseif name == "Yaw" then
- self.controls.yaw = value or 0
- elseif name == "Roll" then
- self.controls.roll = value or 0
- elseif name == "Hover" and value>0.5 then
- self:SetHover(!self:GetHover())
- elseif name == "FreeView" then
- self.passengers[seat].hvap.mouseInput = (value < 0.5)
- elseif name == "CounterMeasure" then
- self:fireCounter(value > 0.5)
- elseif name == "Doors" and value>0.5 and self.HasDoors then
- self:Doors(!self.DoorOpen)
- elseif name == "Gear" and value>0.5 and self.HasGear then
- self:LandingGear(!self.GearDown)
- end
- end
- if name == "Exit" and value>0.5 and self.passengers[seat].hvap.lastEnter<CurTime()-0.5 then
- self:EjectPassenger(self.passengers[seat])
- elseif name == "Bail" and value>0.5 and self.passengers[seat].hvap.lastEnter<CurTime()-0.5 then
- self:Bail(self.passengers[seat])
- elseif name == "FirstFire" then
- self:fireWeapon1(value > 0.5, seat)
- elseif name == "SecondFire" then
- self:fireWeapon2(value > 0.5, seat)
- elseif name == "NextWeapon" and value > 0.5 then
- self:nextWeapon(seat, self.passengers[seat])
- elseif name == "Function1" and value>0.5 then
- self:Function1(seat)
- elseif name == "Function2" and value>0.5 then
- self:Function2(seat)
- elseif name == "Function3" and value>0.5 then
- self:Function3(seat)
- elseif name == "FirstMenu" and value>0.5 then
- self:FirstMenu(seat)
- elseif name == "SecondMenu" and value>0.5 then
- self:SecondMenu(seat)
- elseif name == "Hover" and value>0.5 and seat != 1 then
- self:HoverFunction(seat)
- end
- end
- function ENT:Function1(k)
- end
- function ENT:Function2(k)
- end
- function ENT:Function3(k)
- end
- function ENT:FirstMenu(k)
- end
- function ENT:SecondMenu(k)
- end
- function ENT:HoverFunction(k)
- end
- function ENT:GetSeat(player)
- for i, p in pairs(self.passengers) do
- if p == player then
- return self.seats[i]
- end
- end
- end
- function ENT:setEngine(b)
- if self.disabled or self.FuelScl == 0 then b = false end
- if b then
- if self.active then return end
- self.active = true
- elseif self.active then
- self.active=false
- end
- self:SetNWBool("active", self.active)
- end
- function ENT:calcHover(ph,pos,vel,ang)
- if self:GetHover() and !self.spinout and !self.disabled then
- local v=self:WorldToLocal(pos+vel)
- local av=ph:GetAngleVelocity()
- if math.abs(self.controls.pitch) >= 0.1 then
- pitch = 0
- else
- pitch = math.Clamp(-ang.p*0.64-av.y*0.64-v.x*0.064,-06465,0.64)
- end
- if math.abs(self.controls.roll) >= 0.1 then
- roll = 0
- else
- roll = math.Clamp(-ang.r*0.64-av.x*0.64+v.y*0.064,-0.64,0.64)
- end
- if math.abs(self.controls.throttle) >= 0.1 then
- throttle = 0
- else
- throttle = math.Clamp(-v.z*0.128+av:Length()*0.064, -0.1, 1)
- end
- return{p=pitch,r=roll,t=throttle}
- else
- return {p=0,r=0,t=0}
- end
- end
- function ENT:autoLevelCalc(ph,pos,vel,ang)
- if self.AutoLevel == 1 and !self:GetHover() and !self.spinout and !self.disabled and #self.passengers > 0 then
- local v=self:WorldToLocal(pos+vel)
- local av=ph:GetAngleVelocity()
- if math.abs(self.controls.pitch) >= 0.1 then
- pitch = 0
- else
- pitch = math.Clamp(-ang.p*0.128-av.y-v.x*0.005, -0.128, 0.128)
- end
- if math.abs(self.controls.roll) >= 0.1 then
- roll = 0
- else
- roll = math.Clamp(-ang.r*0.128-av.x+v.y*0.015, -0.128, 0.128)
- end
- if math.abs(self.controls.throttle) >= 0.1 then
- throttle = 0
- else
- throttle = math.Clamp(-v.z*0.128+av:Length()*0.032, -1, 1)
- end
- return{p=pitch,r=roll,t=throttle}
- else
- return {p=0,r=0,t=0}
- end
- end
- function ENT:PhysicsUpdate(ph)
- local vel = ph:GetVelocity()
- local vell = math.Round(vel:Length()*0.068796244/2,1)
- local pos = self:GetPos()
- local ang = self:GetAngles()
- local lvel = self:WorldToLocal(pos+vel)
- local up = self:GetUp()
- local phm = FrameTime()*66
- local spinout = Vector(0,0,0)
- local spinoutv = Vector(0,0,0)
- local rot = Vector (
- math.Clamp((self.controls.roll +self.Roll )*self.rotorRpm, -1.28,1.28),
- math.Clamp((self.controls.pitch +self.Pitch )*self.rotorRpm, -1.28,1.28),
- math.Clamp((self.controls.yaw *math.pow(self.Yaw, 0.5 ))*self.rotorRpm, -1.28,1.28)
- )
- local throttle = self:GetUp()*((self.Throttle*(self.rotorRpm+0.01))*((self.EnginePower)/300)+self.rotorRpm*(9+self.controls.throttle))
- local brakez = self:LocalToWorld(Vector(0, 0, lvel.z*vel:Length()*self.rotorRpm/100000*self.Aerodynamics.RailRotor)) - pos
- if self.CoopEngines then
- if self.rotors[1].Disabled and !self.disabled and self.active or self.RearRotor.Disabled and !self.disabled and self.active then
- spinout = Vector(math.Rand(-4,4)*self.rotorRpm,math.Rand(-4,4)*self.rotorRpm,math.random(4,12)*self.rotorRpm)
- spinoutv = Vector(math.random(-6,6),math.random(-6,6),-1*(math.random(2,4)*up:Length()))
- self.spinout = true
- end
- else
- for i = 1, self.NumRotors do
- if self.rotors[i].Disabled and self.active and !self.disabled and self.active or self.engines[i].engineRpm == 0 and self.active and !self.disabled and self.active then
- spinout = Vector(math.Rand(-4,4)*self.rotorRpm,math.Rand(-4,4)*self.rotorRpm,math.random(4,12)*self.rotorRpm)
- spinoutv = Vector(math.random(-6,6),math.random(-6,6),-1*(math.random(2,4)*up:Length()))
- self.spinout = true
- end
- end
- end
- util.ScreenShake( pos, math.Clamp((vell-30)/16,0,5)*(math.Clamp((rot:Length()-1.128),0,1)/10), 200, 1.6, self.BBoxRadius )
- local controlAng = (rot*1.6+spinout)*self.Aerodynamics.Rotate
- local aeroVelocity, aeroAng = self:calcAerodynamics(ph)
- ph:AddVelocity(((throttle-brakez)+aeroVelocity+spinoutv)*phm)
- ph:AddAngleVelocity((aeroAng + controlAng)*phm)
- if self.Wheels then
- for k,v in pairs(self.wheels) do
- if IsValid(v) then
- local phy = v:GetPhysicsObject()
- phy:AddVelocity(((throttle-brakez)+aeroVelocity+spinoutv)*phm*0.9)
- phy:AddAngleVelocity((aeroAng + controlAng)*phm*0.8)
- end
- end
- end
- end
- function ENT:Rearm(amt, b, phy, rkt)
- if b then
- if self.Weapons2 then
- for k, v in pairs(self.weapons2) do
- if !v.DisableRearm and v:GetAmmo() < v.Ammo then
- v:takeAmmo( -v.ReloadAmt*amt )
- sound.Play( "HVAP.Reload.Pickup", self:GetPos() )
- end
- if phy and v.PhysOrd then
- if v.Rocket == rkt then
- v:ReloadBombs(amt)
- end
- end
- end
- end
- if self.Weapons then
- for k, v in pairs(self.weapons) do
- if !v.DisableRearm and v:GetAmmo() < v.Ammo then
- v:takeAmmo( -v.ReloadAmt*amt )
- sound.Play( "HVAP.Reload.Pickup", self:GetPos() )
- end
- end
- if phy and v.PhysOrd then
- if v.Rocket == rkt then
- v:ReloadBombs(amt)
- end
- end
- end
- else
- if self.Weapons2 then
- for k, v in pairs(self.weapons2) do
- if !v.DisableRearm and v:GetAmmo() != v.Ammo then
- v:SetAmmo(v.Ammo)
- end
- end
- end
- if self.Weapons then
- for k, v in pairs(self.weapons) do
- if !v.DisableRearm and v:GetAmmo() != v.Ammo then
- v:SetAmmo(v.Ammo)
- end
- end
- end
- end
- end
- function ENT:Refuel(amt, b)
- if self.Fuel != self.BaseFuel then
- self.Fuel = math.Clamp( self.Fuel+amt, 0,self.BaseFuel)
- if b then
- self.Refueling = true
- else
- self.Refueling = false
- end
- end
- end
- function ENT:Repair(amt, b, c)
- if b then
- if self.FuselageHealth < self.FuselageBaseHealth then
- self.FuselageHealth = math.Clamp(self.FuselageHealth + amt, 0, self.FuselageBaseHealth )
- sound.Play( "HVAP.Misc.Repair.Small", self:GetPos() )
- end
- if self.disabled then
- self.disabled = false
- end
- if self.dead then
- self.dead = false
- end
- if c then
- if self.FSCL >= 0.99 then
- for k, v in pairs(self.rotors) do
- if amt == 1 and !v.Disabed then
- v:ResetRot()
- else
- v:Repair(amt, b, c)
- end
- end
- end
- for k, v in pairs(self.engines) do
- if v:IsValid() then
- v:Repair(amt, b, c)
- end
- end
- end
- else
- for k, v in pairs(self.rotors) do
- if amt == 1 and !v.Disabed then
- v:ResetRot()
- else
- v:Repair(amt)
- end
- end
- for k, v in pairs(self.engines) do
- if v:IsValid() then
- v:Repair(amt)
- end
- end
- if self.FuselageHealth < self.FuselageBaseHealth then
- self.FuselageHealth = math.Clamp(self.FuselageHealth + self.FuselageBaseHealth/amt, self.FuselageBaseHealth/amt, self.FuselageBaseHealth )
- end
- if self.disabled then
- self.disabled = false
- end
- if self.dead then
- self.dead = false
- end
- end
- end
- function ENT:PhysicsCollide(cdat, phys)
- if cdat.DeltaTime > 0.5 then
- local mass = cdat.HitObject:GetMass()
- if cdat.HitEntity:GetClass() == "worldspawn" then
- mass = 3200
- end
- local dmg = (math.pow(cdat.Speed, 2)*math.Clamp(mass, 0, 5000))/10000000
- if !dmg or dmg <= 32 then return end
- local lasta=(self.LastDamageTaken<CurTime()+6 and self.LastAttacker or self.Entity)
- for k, p in pairs(self.passengers) do
- if p and p:IsValid() then
- p:TakeDamage(dmg/16, lasta, self.Entity)
- end
- end
- for i = 1, self.NumEngines do
- self.engines[i]:DamageEngine(dmg)
- end
- self:DamageFuselage(dmg, lasta)
- sound.Play( "HVAP.Vehicle.Collide", self:GetPos() )
- end
- end
- function ENT:OnTakeDamage(dmg)
- if self.Unbreakable then return end
- local crt = CurTime()
- self.LastAttacker=dmg:GetAttacker()
- self.LastDamageTaken=crt
- if !dmg:IsExplosionDamage() then
- dmg:ScaleDamage(10)
- end
- local pos=self:WorldToLocal(dmg:GetDamagePosition())
- local dmgVal = dmg:GetDamage()
- local driver = self:getPassenger()
- local lasta=(self.LastDamageTaken<crt+6 and self.LastAttacker or self.Entity)
- -------------------------engine damage
- for k, v in pairs(self.engines) do
- if v:IsValid() then
- local dist = pos:Distance(self.Engines[k].pos)/(dmg:IsExplosionDamage() and 24 or 1)
- local edmg = dmgVal/dist
- if dist <= self.Engines[k].radius*1.128 then
- v:DamageEngine(edmg/2)
- end
- end
- end
- -------------------------rotor damage
- for k, v in pairs(self.rotors) do
- if v:IsValid() then
- local dist = pos:Distance(self.Rotors[k].pos)
- if dist < 16 then
- local rdmg = math.Clamp((dmgVal/dist),1,24)
- v:DamageRotor(rdmg/4)
- end
- end
- end
- -------------------------pilot snipe calc
- if self.PilotDamageCvar != 1 then
- for k, p in pairs(self.passengers) do
- local dist = pos:Distance(self.Seats[k].pos)
- if p and p:IsValid() and dist<=(self.PlyDmgDist*1.92) then
- local pdmg = ((dmgVal/dist)*self.PlyDmgMult) / (dmg:IsExplosionDamage() and 2 or 1)
- p:TakeDamage(pdmg*0.4, lasta, self.Entity)
- end
- end
- end
- self:DamageFuselage(dmgVal/(dmg:IsExplosionDamage() and 2 or 16), lasta)
- end
- function ENT:DamageFuselage(dmg, lasta)
- if self.Unbreakable then return end
- local crt = CurTime()
- self.FuselageHealth = math.Clamp(self.FuselageHealth - dmg, 0, self.FuselageBaseHealth)
- if dmg > 0.01 then
- util.ScreenShake( self:GetPos(), dmg/10, 200, 1.6, self.BBoxRadius*2 )
- end
- if !self.disabled then
- if dmg > 0.01 then
- if self.FSCL > 0.60 and crt>self.LastDamageTaken+0.28 then
- sound.Play( self.Sounds.Damaged, self:GetPos() )
- elseif self.FSCL > 0.40 and crt>self.LastDamageTaken+0.4 then
- sound.Play( self.Sounds.Alarm75, self:GetPos() )
- elseif self.FSCL > 0.20 and crt>self.LastDamageTaken+0.5 then
- sound.Play( self.Sounds.Alarm50, self:GetPos() )
- elseif self.FSCL > 0.20 and crt>self.LastDamageTaken+0.6 then
- sound.Play( self.Sounds.Alarm25, self:GetPos() )
- end
- end
- if self.FuselageHealth == 0 then
- for i = 1, self.NumEngines do
- self.engines[i]:DamageEngine(10000)
- end
- self.disabled = true
- end
- elseif self.dead and !self.CriticalDeath then
- self.CriticalHealth = math.Clamp( self.CriticalHealth - dmg, 0, self.CriticalBaseHealth )
- if self.CriticalHealth == 0 then
- self.CriticalDeath = true
- end
- end
- end
- function ENT:CPPIGetOwner()
- return self.SpawnedBy
- end
- function ENT:AddOnRemove(f)
- if type(f)=="function" then
- table.insert(self.OnRemoveFunctions,f)
- elseif type(f)=="Entity" or type(f)=="Vehicle" then
- table.insert(self.OnRemoveEntities,f)
- end
- end
- function ENT:OnRemove()
- self:StopAllSounds()
- for _,p in pairs(self.passengers) do
- if IsValid(p) then
- p:SetNWInt("hvap_passenger_id",0)
- end
- end
- for _,f in pairs(self.OnRemoveFunctions) do
- f()
- end
- for _,e in pairs(self.OnRemoveEntities) do
- if IsValid(e) then e:Remove() end
- end
- for _,e in pairs(self.Children) do
- if IsValid(e) then e:Remove() end
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement