AddCSLuaFile( "cl_init.lua" ) AddCSLuaFile( "shared.lua" ) include('shared.lua') ENT.WireDebugName = "Thruster" local Thruster_Sound = Sound( "PhysicsCannister.ThrusterLoop" ) function ENT:Initialize() self.Entity:PhysicsInit( SOLID_VPHYSICS ) self.Entity:SetMoveType( MOVETYPE_VPHYSICS ) self.Entity:SetSolid( SOLID_VPHYSICS ) self.Entity:DrawShadow( false ) local phys = self.Entity:GetPhysicsObject() if (phys:IsValid()) then phys:Wake() end local max = self.Entity:OBBMaxs() local min = self.Entity:OBBMins() self.ThrustOffset = Vector( 0, 0, max.z ) self.ThrustOffsetR = Vector( 0, 0, min.z ) self.ForceAngle = self.ThrustOffset:GetNormalized() * -1 self:SetForce( 2000 ) self.OWEffect = "fire" self.UWEffect = "same" self:SetOffset( self.ThrustOffset ) self.Entity:StartMotionController() self:Switch( false ) self.Inputs = Wire_CreateInputs(self.Entity, { "A" }) end function ENT:OnRemove() self.BaseClass.OnRemove(self) if (self.EnableSound) then self.Entity:StopSound(Thruster_Sound) end end function ENT:SetForce( force, mul ) if (force) then self.force = force self:NetSetForce( force ) end mul = mul or 1 local phys = self.Entity:GetPhysicsObject() if (!phys:IsValid()) then Msg("Warning: [gmod_thruster] Physics object isn't valid!\n") return end // Get the data in worldspace local ThrusterWorldPos = phys:LocalToWorld( self.ThrustOffset ) local ThrusterWorldForce = phys:LocalToWorldVector( self.ThrustOffset * -1 ) // Calculate the velocity ThrusterWorldForce = ThrusterWorldForce * self.force * mul * 50 self.ForceLinear, self.ForceAngle = phys:CalculateVelocityOffset( ThrusterWorldForce, ThrusterWorldPos ); self.ForceLinear = phys:WorldToLocalVector( self.ForceLinear ) if ( mul > 0 ) then self:SetOffset( self.ThrustOffset ) else self:SetOffset( self.ThrustOffsetR ) end -- self.Entity:SetNetworkedVector( 1, self.ForceAngle ) -- self.Entity:SetNetworkedVector( 2, self.ForceLinear ) end function ENT:Setup(force, force_min, force_max, oweffect, uweffect, owater, uwater, bidir, sound) self:SetForce(force) self.OWEffect = oweffect self.UWEffect = uweffect self.ForceMin = force_min self.ForceMax = force_max self.BiDir = bidir self.EnableSound = sound self.OWater = owater self.UWater = uwater if (not sound) then self.Entity:StopSound(Thruster_Sound) end --self:SetOverlayText( "Thrust = " .. 0 .. "\nMul: " .. math.Round(force*1000)/1000 ) end function ENT:TriggerInput(iname, value) if (iname == "A") then if ( (self.BiDir) and (math.abs(value) > 0.01) and (math.abs(value) > self.ForceMin) ) or ( (value > 0.01) and (value > self.ForceMin) ) then self:Switch(true, math.min(value, self.ForceMax)) else self:Switch(false, 0) end end end function ENT:PhysicsSimulate( phys, deltatime ) if (!self:IsOn()) then return SIM_NOTHING end if (self.Entity:WaterLevel() > 0) then if (not self.UWater) then self:SetEffect("none") return SIM_NOTHING end if (self.UWEffect == "same") then self:SetEffect(self.OWEffect) else self:SetEffect(self.UWEffect) end else if (not self.OWater) then self:SetEffect("none") return SIM_NOTHING end self:SetEffect(self.OWEffect) end local ForceAngle, ForceLinear = self.ForceAngle, self.ForceLinear return ForceAngle, ForceLinear, SIM_LOCAL_ACCELERATION end function ENT:Switch( on, mul ) if (!self.Entity:IsValid()) then return false end local changed = (self:IsOn() ~= on) self:SetOn( on ) if (on) then if (changed) and (self.EnableSound) then self.Entity:StopSound( Thruster_Sound ) self.Entity:EmitSound( Thruster_Sound ) end self:NetSetMul( mul ) /*if (mul ~= self.PrevOutput) then self:SetOverlayText( "Thrust = " .. math.Round(self.force*mul*1000)/1000 .. "\nMul: " .. math.Round(self.force*1000)/1000 ) self.PrevOutput = mul end*/ self:SetForce( nil, mul ) else if (self.EnableSound) then self.Entity:StopSound( Thruster_Sound ) end /*if (self.PrevOutput) then self:SetOverlayText( "Thrust = Off".."\nMul: "..math.Round(self.force*1000)/1000 ) self.PrevOutput = nil end*/ end local phys = self.Entity:GetPhysicsObject() if (phys:IsValid()) then phys:Wake() end return true end function ENT:OnRestore() local phys = self.Entity:GetPhysicsObject() if (phys:IsValid()) then phys:Wake() end local max = self.Entity:OBBMaxs() local min = self.Entity:OBBMins() self.ThrustOffset = Vector( 0, 0, max.z ) self.ThrustOffsetR = Vector( 0, 0, min.z ) self.ForceAngle = self.ThrustOffset:GetNormalized() * -1 self:SetOffset( self.ThrustOffset ) self.Entity:StartMotionController() if (self.PrevOutput) then self:Switch(true, self.PrevOutput) else self:Switch(false) end self.BaseClass.OnRestore(self) end function ENT:BuildDupeInfo() local info = self.BaseClass.BuildDupeInfo(self) or {} if (self.PrevOutput) and (self:IsOn()) then info.PrevOutput = self.PrevOutput end return info end function ENT:ApplyDupeInfo(ply, ent, info, GetEntByID) self.BaseClass.ApplyDupeInfo(self, ply, ent, info, GetEntByID) if (info.PrevOutput) then self:Switch(true, info.PrevOutput) end end