AddCSLuaFile( "cl_init.lua" ) AddCSLuaFile( "shared.lua" ) include('shared.lua') -- Configuration section. -- These variables can be set by derived entities too! --Misc ENT.Destroyable =true -- Should the shuttle be able to take any damage? ENT.InitialHealth =500 -- How much health the shuttle should start with ENT.Trail =true -- Should the shuttle have a flame trail? ENT.HoverEnabled =true -- Should the shuttle be able to hover? ENT.MinHeight =50 -- How far off the ground should the shuttle stay when active? ENT.PhysicsMass =10000 -- How much should the shuttle weigh? Note that this has some control over how much it can lift. ENT.Drift =false -- Should the shuttle behave somewhat like it is in space? That is, it can drift in one direction and turn. This negates the hover option. -- Appearance ENT.Mdl ="models/props_combine/headcrabcannister01a.mdl" -- The shuttle's model. ENT.TrailSprite ="sprites/firetrail.spr" -- The shuttle's trail sprite. ENT.SoundEffect =Sound("ambient/atmosphere/undercity_loop1.wav") -- The shuttle's flight sound. -- Movement rates ENT.ForwardSpeed =700 -- How fast we move forwards ENT.FastForwardSpeed =1000 -- How fast we turbo move forwards ENT.BackwardSpeed =700 -- How fast we move backwards ENT.RollSpeed =3 -- How fast we roll ENT.DeadZone =200 -- The dead zone for dropping ENT.AccelerationRate =10 -- How fast the shuttle will match the desired speed -- Complex movement - Don't touch these unless you know what they mean. ENT.secondstoarrive = 1 ENT.maxangular = 5000 ENT.maxangulardamp = 10000 ENT.maxspeed = 1000000 ENT.maxspeeddamp = 10000 ENT.dampfactor = 0.8 ENT.teleportdistance = 5000 -- Key bindings ENT.ForwardKey =IN_ATTACK ENT.FastForwardKey =IN_FORWARD ENT.BackwardKey =IN_ATTACK2 ENT.RollLeftKey =IN_MOVELEFT ENT.RollRightKey =IN_MOVERIGHT ENT.HoverKey =IN_SPEED -- You'll probably break everything if you edit anything further below. -- You probably broke everything already. ---------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------- function ENT:SpawnFunction( ply, tr) local SpawnPos = tr.HitPos + tr.HitNormal * 100 local ent = ents.Create( "shuttle" ) ent:SetPos( SpawnPos ) ent:Spawn() ent:Activate() return ent end function ENT:SetxHealth(amt) self.Entity:SetNetworkedInt("health",amt) end function ENT:GetxHealth() return self:GetNetworkedInt("health",-1) end function ENT:FireTrail(b) if b==true then self:FireTrail(false) -- oh recursion my recursion self.FireEntity = ents.Create("env_fire_trail") self.FireEntity:SetKeyValue("spawnrate","3") self.FireEntity:SetKeyValue("firesprite", self.TrailSprite ) self.FireEntity:SetPos(self.Entity:GetPos()) self.FireEntity:SetParent(self.Entity) self.FireEntity:Spawn() self.FireEntity:Activate() elseif b==false then if ValidEntity(self.FireEntity) then self.FireEntity:Remove() end end end function ENT:Initialize() -- Set up the sound effect self.Sound = CreateSound( self.Entity, self.SoundEffect ) -- Set our initial health self:SetxHealth(self.InitialHealth) -- Still don't know why this isn't default self.Entity:SetUseType( SIMPLE_USE ) -- Define some variables to be used later self.FireTrailEnt=nil self.InFlight=false self.Pilot=nil self.Accel=0 self.Roll=0 -- We can define pr here so that if required the previous values can be accessed self.pr={} -- We need to store the previous angle in the physics simulation so we can have a "drift" effect self.PrevAng=nil -- Set up the shuttle's physics simulation self.Entity:SetModel(self.Mdl) self.Entity:PhysicsInit( SOLID_VPHYSICS ) self.Entity:SetMoveType( MOVETYPE_VPHYSICS ) self.Entity:SetSolid( SOLID_VPHYSICS ) local phys = self.Entity:GetPhysicsObject() if (phys:IsValid()) then phys:Wake() phys:SetMass(self.PhysicsMass) end self.Entity:StartMotionController() end function ENT:Kill() -- Make an explosion effect local effectdata = EffectData() effectdata:SetOrigin( self.Entity:GetPos() ) util.Effect( "Explosion", effectdata, true, true ) -- Stop the sound effect self.Sound:Stop() -- Respawn the pilot if ValidEntity(self.Pilot) then self.Pilot:UnSpectate() self.Pilot:DrawViewModel(true) self.Pilot:DrawWorldModel(true) self.Pilot:Spawn() self.Pilot:SetNetworkedBool("isDriveShuttle",false) self.Pilot:SetPos(self.Entity:GetPos()+Vector(0,0,100)) end end function ENT:OnTakeDamage(dmg) if self.InFlight and self.Destroyable then -- Decrease the shuttle's health local health=self:GetxHealth() self:SetxHealth(health-dmg:GetDamage()) local health=self:GetxHealth() -- Is it dead yet? if health<1 then self.InFlight=false self.Entity:Kill() self.Entity:Remove() end end end function ENT:OnRemove() if (self.Sound) then self.Sound:Stop() end self.Entity:Kill() end function ENT:Think() -- Check our pilot is still valid if not ValidEntity(self.Pilot) then -- If not, reset the shuttle so someone else can get in self.Pilot=nil self.InFlight=false self.Sound:Stop() self:FireTrail(false) end if self.InFlight and ValidEntity(self.Pilot) then -- Make it sound like it's straining the faster we go if self.Sound then self.Sound:ChangePitch(math.Clamp(self.Entity:GetVelocity():Length()/5,1,200),0.001) end -- Make the pilot's player entity follow the shuttle for PVS reasons self.Pilot:SetPos(self.Entity:GetPos()) -- Process any custom thinking for derived entities if it exists if self.ProcessCustom then self:ProcessCustom() end -- See if they want to get out if self.Pilot:KeyDown(IN_USE) then -- Reset some variables and pop them out self.Sound:Stop() self.Pilot:UnSpectate() self.Pilot:DrawViewModel(true) self.Pilot:DrawWorldModel(true) self.Pilot:Spawn() self.Pilot:SetNetworkedBool("isDriveShuttle",false) self.Pilot:SetPos(self.Entity:GetPos()+Vector(0,0,100)) self.Accel=0 self.Roll=0 self.InFlight=false self:FireTrail(false) self.Entity:SetLocalVelocity(Vector(0,0,0)) self.Pilot=nil end self.Entity:NextThink(CurTime()) else -- If we think less often we use less cpu time self.Entity:NextThink(CurTime()+1) end return true end function ENT:Use(ply,caller) if not self.InFlight then -- Play the sound effect self.Sound:Play() -- Wake up the shuttle in case some twat froze it self.Entity:GetPhysicsObject():Wake() self.Entity:GetPhysicsObject():EnableMotion(true) self.InFlight=true self.Pilot=ply self.Roll=0 self.Accel=0 -- Put the player "inside" the shuttle ply:Spectate( OBS_MODE_CHASE ) ply:DrawViewModel(false) ply:DrawWorldModel(false) ply:StripWeapons() ply:SetNetworkedBool("isDriveShuttle",true) ply:SetNetworkedEntity("Shuttle",self.Entity) -- Set up the flame trail if self.Trail then self:FireTrail(true) end end end function ENT:PhysicsSimulate( phys, deltatime ) if self.InFlight then local hovering=false if self.HoverEnabled and self.Pilot:KeyDown(self.HoverKey) then hovering=true end if not self.Drift then self.Entity:SetNetworkedBool("hover",hovering) end local num=0 if self.Pilot:KeyDown(self.ForwardKey) then num=self.ForwardSpeed elseif self.Pilot:KeyDown(self.BackwardKey) then num=-self.BackwardSpeed elseif self.Pilot:KeyDown(self.FastForwardKey) then num=self.FastForwardSpeed end if self.Pilot:KeyDown(self.RollLeftKey) then self.Roll=self.Roll-self.RollSpeed elseif self.Pilot:KeyDown(self.RollRightKey) then self.Roll=self.Roll+self.RollSpeed end phys:Wake() -- wakey wakey! if self.Drift and not self.Pilot:KeyDown(self.HoverKey) or not self.Drift then self.Accel=math.Approach(self.Accel,num,self.AccelerationRate) else self.Sound:ChangePitch(0,0.001) end if self.Accel>-self.DeadZone and self.Accel < self.DeadZone and not self.Pilot:KeyDown(self.ForwardKey) and not self.Pilot:KeyDown(self.BackwardKey) and not self.Pilot:KeyDown(self.FastForwardKey) and not hovering then return end self.pr.secondstoarrive = self.secondstoarrive if not self.Pilot:KeyDown(self.HoverKey) then self.PrevAng = self.Entity:GetForward() end self.pr.pos = self.Entity:GetPos()+self.PrevAng*self.Accel if self.MinHeight~=0 then -- Check if we're too low local tracedata = {} tracedata.start = self:GetPos() tracedata.endpos = self:GetPos()+self:GetUp()*(-self.MinHeight) tracedata.filter = self.Entity -- ,we're only tracing to the world as people tend to use this as a vehicle base tracedata.mask = MASK_NPCWORLDSTATIC -- We're doing a hull trace so we get the whole shuttle ent.. any external props won't be accounted for tracedata.mins = self:OBBMins() tracedata.maxs = self:OBBMaxs() local trace = util.TraceLine(tracedata) if trace.HitWorld then -- Woop, move up then self.pr.pos=self.pr.pos+(self:GetUp()*(self.MinHeight*trace.Fraction)) end end self.pr.maxangular = self.maxangular self.pr.maxangulardamp = self.maxangulardamp self.pr.maxspeed = self.maxspeed self.pr.maxspeeddamp = self.maxspeeddamp self.pr.dampfactor = self.dampfactor self.pr.teleportdistance= self.teleportdistance local ang = self.Pilot:GetAimVector():Angle() ang.r=ang.r+self.Roll self.pr.angle = ang self.pr.deltatime = deltatime phys:ComputeShadowControl(self.pr) end end