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

710 lines
28 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/
--]]
local function IsServerOK()
if GetConVar( "gmod_physiterations" ):GetInt() < 4 then
RunConsoleCommand("gmod_physiterations", "4")
return false
end
return true
end
function ENT:Initialize()
self:PhysicsInit( SOLID_VPHYSICS )
self:SetMoveType( MOVETYPE_VPHYSICS )
self:SetSolid( SOLID_VPHYSICS )
self:SetNotSolid( true )
self:SetUseType( SIMPLE_USE )
--self:SetRenderMode( RENDERMODE_TRANSALPHA ) -- fix broken decals
self:AddFlags( FL_OBJECT ) -- this allows npcs to see this entity
if not IsServerOK() then
self:Remove()
print("[SIMFPHYS] ERROR COULDN'T INITIALIZE VEHICLE!")
end
local PObj = self:GetPhysicsObject()
if not IsValid( PObj ) then print("[SIMFPHYS] ERROR COULDN'T INITIALIZE VEHICLE! '"..self:GetModel().."' has no physics model!") self:Remove() return end
PObj:EnableMotion( false )
self:SetValues()
timer.Simple( 0.1, function()
if not IsValid( self ) then return end
self:InitializeVehicle()
end)
end
function ENT:PostEntityPaste( ply , ent , createdEntities )
self:SetValues()
self:SetActive( false )
self:SetDriver( NULL )
self:SetLightsEnabled( false )
self:SetLampsEnabled( false )
self:SetFogLightsEnabled( false )
self:SetDriverSeat( NULL )
self:SetFlyWheelRPM( 0 )
self:SetThrottle( 0 )
end
function ENT:UpdateTransmitState()
return TRANSMIT_ALWAYS
end
function ENT:SetupView()
local AttachmentID = self:LookupAttachment( "vehicle_driver_eyes" )
local AttachmentID2 = self:LookupAttachment( "vehicle_passenger0_eyes" )
local a_data1 = self:GetAttachment( AttachmentID )
local a_data2 = self:GetAttachment( AttachmentID2 )
local ID
local ViewPos
if a_data1 then
ID = AttachmentID
ViewPos = a_data1
elseif a_data2 then
ID = AttachmentID2
ViewPos = a_data2
else
ID = false
ViewPos = {Ang = self:LocalToWorldAngles( Angle(0, 90,0) ),Pos = self:GetPos()}
end
local ViewAng = ViewPos.Ang - Angle(0,0,self.SeatPitch)
ViewAng:RotateAroundAxis(self:GetUp(), -90 - (self.SeatYaw or 0))
local data = {
ID = ID,
ViewPos = ViewPos.Pos,
ViewAng = ViewAng,
}
return data
end
function ENT:SetupEnteringAnims()
local attachments = self:GetAttachments()
self.Exitpoints = {}
self.Enterpoints = {}
for _,i in pairs(attachments) do
local curstring = string.lower( i.name )
if string.match( curstring, "exit", 1 ) then
table.insert(self.Exitpoints, curstring)
end
if string.match( curstring, "enter", 1 ) then
table.insert(self.Enterpoints, curstring)
end
end
if table.Count( self.Enterpoints ) < 1 then
self.Enterpoints = nil
end
if table.Count( self.Exitpoints ) < 1 then
self.Exitpoints = nil
end
end
function ENT:InitializeVehicle()
if not IsValid( self ) then return end
local physObj = self:GetPhysicsObject()
if not IsValid( physObj ) then return end
if self.LightsTable then
local vehiclelist = list.Get( "simfphys_lights" )[self.LightsTable] or false
if vehiclelist then
if vehiclelist.PoseParameters then
self.LightsPP = vehiclelist.PoseParameters
end
if vehiclelist.BodyGroups then
self:SetBodygroup(vehiclelist.BodyGroups.Off[1], vehiclelist.BodyGroups.Off[2] )
end
end
end
physObj:SetDragCoefficient( self.AirFriction or -250 )
physObj:SetMass( self.Mass * 0.75 )
if self.Inertia then
physObj:SetInertia( self.Inertia )
end
local tanksize = self.FuelTankSize and self.FuelTankSize or 65
local fueltype = self.FuelType and self.FuelType or FUELTYPE_PETROL
self:SetMaxFuel( tanksize )
self:SetFuel( self:GetMaxFuel() )
self:SetFuelType( fueltype )
self:SetFuelPos( self.FuelFillPos and self.FuelFillPos or Vector(0,0,0) )
if fueltype ~= FUELTYPE_NONE then
self:AddFuelTank()
end
local View = self:SetupView()
self.DriverSeat = self:AddDriverSeat( self:WorldToLocal( View.ViewPos ), self:WorldToLocalAngles( View.ViewAng ) )
self.DriverSeat:SetParent( NULL )
self.DriverSeat:SetMoveType( MOVETYPE_NONE )
self.DriverSeat:Spawn()
self.DriverSeat:Activate()
self.DriverSeat:SetPos( View.ViewPos + self.DriverSeat:GetUp() * (-34 + self.SeatOffset.z) + self.DriverSeat:GetRight() * (self.SeatOffset.y) + self.DriverSeat:GetForward() * (-6 + self.SeatOffset.x) )
if View.ID ~= false then
self:SetupEnteringAnims()
self.DriverSeat:SetParent( self , View.ID )
else
self.DriverSeat:SetParent( self )
end
self.DriverSeat.fphysSeat = true
self.DriverSeat.base = self
if self.PassengerSeats then
for i = 1, table.Count( self.PassengerSeats ) do
self.pSeat[i] = self:AddPassengerSeat( self.PassengerSeats[i].pos, self.PassengerSeats[i].ang )
self.pSeat[i].fphysSeat = true
self.pSeat[i].base = self
end
end
if istable(WireLib) then
local passengersSeats = istable( self.pSeat ) and self.pSeat or {}
WireLib.TriggerOutput(self, "PassengerSeats", passengersSeats )
WireLib.TriggerOutput(self, "DriverSeat", self.DriverSeat )
end
if self.Attachments then
for i = 1, table.Count( self.Attachments ) do
local prop = ents.Create( "gmod_sent_vehicle_fphysics_attachment" )
prop:SetModel( self.Attachments[i].model )
prop:SetMaterial( self.Attachments[i].material )
prop:SetRenderMode( RENDERMODE_TRANSALPHA )
prop:SetPos( self:LocalToWorld( self.Attachments[i].pos ) )
prop:SetAngles( self:LocalToWorldAngles( self.Attachments[i].ang ) )
prop:SetOwner( self )
prop:Spawn()
prop:Activate()
prop:DrawShadow( true )
prop:SetNotSolid( true )
prop:SetParent( self )
prop.DoNotDuplicate = true
simfphys.SetOwner( self.EntityOwner, prop )
if self.Attachments[i].skin then
prop:SetSkin( self.Attachments[i].skin )
end
if self.Attachments[i].bodygroups then
for b = 1, table.Count( self.Attachments[i].bodygroups ) do
prop:SetBodygroup(b, self.Attachments[i].bodygroups[b] )
end
end
if self.Attachments[i].useVehicleColor == true then
self.ColorableProps[i] = prop
prop:SetColor( self:GetColor() )
else
prop:SetColor( self.Attachments[i].color or Color(255,255,255,255) )
end
self:DeleteOnRemove( prop )
end
end
self:GetVehicleData()
end
function ENT:GetVehicleData()
self:SetPoseParameter("vehicle_steer",1)
self:SetPoseParameter("vehicle_wheel_fl_height",1)
self:SetPoseParameter("vehicle_wheel_fr_height",1)
self:SetPoseParameter("vehicle_wheel_rl_height",1)
self:SetPoseParameter("vehicle_wheel_rr_height",1)
timer.Simple( 0.15, function()
if not IsValid(self) then return end
self.posepositions["Pose0_Steerangle"] = self.CustomWheels and Angle(0,0,0) or self:GetAttachment( self:LookupAttachment( "wheel_fl" ) ).Ang
self.posepositions["Pose0_Pos_FL"] = self.CustomWheels and self:LocalToWorld( self.CustomWheelPosFL ) or self:GetAttachment( self:LookupAttachment( "wheel_fl" ) ).Pos
self.posepositions["Pose0_Pos_FR"] = self.CustomWheels and self:LocalToWorld( self.CustomWheelPosFR ) or self:GetAttachment( self:LookupAttachment( "wheel_fr" ) ).Pos
self.posepositions["Pose0_Pos_RL"] = self.CustomWheels and self:LocalToWorld( self.CustomWheelPosRL ) or self:GetAttachment( self:LookupAttachment( "wheel_rl" ) ).Pos
self.posepositions["Pose0_Pos_RR"] = self.CustomWheels and self:LocalToWorld( self.CustomWheelPosRR ) or self:GetAttachment( self:LookupAttachment( "wheel_rr" ) ).Pos
self:WriteVehicleDataTable()
end )
end
function ENT:ResetJoystick()
self.PressedKeys["joystick_steer_left"] = 0
self.PressedKeys["joystick_steer_right"] = 0
self.PressedKeys["joystick_brake"] = 0
self.PressedKeys["joystick_throttle"] = 0
self.PressedKeys["joystick_gearup"] = 0
self.PressedKeys["joystick_geardown"] = 0
self.PressedKeys["joystick_handbrake"] = 0
self.PressedKeys["joystick_clutch"] = 0
self.PressedKeys["joystick_air_w"] = 0
self.PressedKeys["joystick_air_a"] = 0
self.PressedKeys["joystick_air_s"] = 0
self.PressedKeys["joystick_air_d"] = 0
end
function ENT:SetValues()
if istable( WireLib ) then
self:createWireIO()
end
self:SetGear( 2 )
self.WheelOnGroundDelay = 0
self.SmoothAng = 0
self.Steer = 0
self.EngineIsOn = 0
self.EngineTorque = 0
self.pSeat = {}
self.exfx = {}
self.Wheels = {}
self.Elastics = {}
self.GhostWheels = {}
self.PressedKeys = {}
self:ResetJoystick()
self.ColorableProps = {}
self.posepositions = {}
self.HandBrakePower = 0
self.DriveWheelsOnGround = 0
self.WheelRPM = 0
self.EngineRPM = 0
self.RpmDiff = 0
self.Torque = 0
self.CurrentGear = 2
self.GearUpPressed = 0
self.GearDownPressed = 0
self.RPM_DIFFERENCE = 0
self.exprpmdiff = 0
self.OldLockBrakes = 0
self.ThrottleDelay = 0
self.Brake = 0
self.HandBrake = 0
self.AutoClutch = 0
self.NextShift = 0
self.ForwardSpeed = 0
self.EngineWasOn = 0
self.SmoothTurbo = 0
self.SmoothBlower = 0
self.cc_speed = 0
self.LightsActivated = false
self.VehicleData = {}
for i = 1, 6 do
self.VehicleData[ "spin_"..i ] = 0
self.VehicleData[ "SurfaceMul_"..i ] = 1
self.VehicleData[ "onGround_"..i ] = 0
end
self.VehicleData[ "Steer" ] = 0
end
function ENT:WriteVehicleDataTable()
self:SetPoseParameter("vehicle_steer",0)
self:SetPoseParameter("vehicle_wheel_fl_height",0)
self:SetPoseParameter("vehicle_wheel_fr_height",0)
self:SetPoseParameter("vehicle_wheel_rl_height",0)
self:SetPoseParameter("vehicle_wheel_rr_height",0)
timer.Simple( 0.15, function()
if not IsValid(self) then return end
self.posepositions["Pose1_Steerangle"] = self.CustomWheels and Angle(0,0,0) or self:GetAttachment( self:LookupAttachment( "wheel_fl" ) ).Ang
self.posepositions["Pose1_Pos_FL"] = self.CustomWheels and self:LocalToWorld( self.CustomWheelPosFL ) or self:GetAttachment( self:LookupAttachment( "wheel_fl" ) ).Pos
self.posepositions["Pose1_Pos_FR"] = self.CustomWheels and self:LocalToWorld( self.CustomWheelPosFR ) or self:GetAttachment( self:LookupAttachment( "wheel_fr" ) ).Pos
self.posepositions["Pose1_Pos_RL"] = self.CustomWheels and self:LocalToWorld( self.CustomWheelPosRL ) or self:GetAttachment( self:LookupAttachment( "wheel_rl" ) ).Pos
self.posepositions["Pose1_Pos_RR"] = self.CustomWheels and self:LocalToWorld( self.CustomWheelPosRR ) or self:GetAttachment( self:LookupAttachment( "wheel_rr" ) ).Pos
self.posepositions["PoseL_Pos_FL"] = self:WorldToLocal( self.posepositions.Pose1_Pos_FL )
self.posepositions["PoseL_Pos_FR"] = self:WorldToLocal( self.posepositions.Pose1_Pos_FR )
self.posepositions["PoseL_Pos_RL"] = self:WorldToLocal( self.posepositions.Pose1_Pos_RL )
self.posepositions["PoseL_Pos_RR"] = self:WorldToLocal( self.posepositions.Pose1_Pos_RR )
self.VehicleData["suspensiontravel_fl"] = self.CustomWheels and self.FrontHeight or math.Round( (self.posepositions.Pose0_Pos_FL - self.posepositions.Pose1_Pos_FL):Length() , 2)
self.VehicleData["suspensiontravel_fr"] = self.CustomWheels and self.FrontHeight or math.Round( (self.posepositions.Pose0_Pos_FR - self.posepositions.Pose1_Pos_FR):Length() , 2)
self.VehicleData["suspensiontravel_rl"] = self.CustomWheels and self.RearHeight or math.Round( (self.posepositions.Pose0_Pos_RL - self.posepositions.Pose1_Pos_RL):Length() , 2)
self.VehicleData["suspensiontravel_rr"] = self.CustomWheels and self.RearHeight or math.Round( (self.posepositions.Pose0_Pos_RR - self.posepositions.Pose1_Pos_RR):Length() , 2)
local Figure1 = math.Round( math.acos( math.Clamp(self.posepositions.Pose0_Steerangle:Up():Dot(self.posepositions.Pose1_Steerangle:Up()),-1,1) ) * (180 / math.pi) , 2)
local Figure2 = math.Round( math.acos( math.Clamp(self.posepositions.Pose0_Steerangle:Forward():Dot(self.posepositions.Pose1_Steerangle:Forward()),-1,1) ) * (180 / math.pi) , 2)
local Figure3 = math.Round( math.acos( math.Clamp(self.posepositions.Pose0_Steerangle:Right():Dot(self.posepositions.Pose1_Steerangle:Right()),-1,1) ) * (180 / math.pi) , 2)
self.VehicleData["steerangle"] = self.CustomWheels and self.CustomSteerAngle or math.max(Figure1,Figure2,Figure3)
local pFL = self.posepositions.Pose0_Pos_FL
local pFR = self.posepositions.Pose0_Pos_FR
local pRL = self.posepositions.Pose0_Pos_RL
local pRR = self.posepositions.Pose0_Pos_RR
local pAngL = self:WorldToLocalAngles( ((pFL + pFR) / 2 - (pRL + pRR) / 2):Angle() )
pAngL.r = 0
pAngL.p = 0
self.VehicleData["LocalAngForward"] = pAngL
local yAngL = self.VehicleData.LocalAngForward - Angle(0,90,0)
yAngL:Normalize()
self.VehicleData["LocalAngRight"] = yAngL
self.VehicleData[ "pp_spin_1" ] = "vehicle_wheel_fl_spin"
self.VehicleData[ "pp_spin_2" ] = "vehicle_wheel_fr_spin"
self.VehicleData[ "pp_spin_3" ] = "vehicle_wheel_rl_spin"
self.VehicleData[ "pp_spin_4" ] = "vehicle_wheel_rr_spin"
self.Turbo = CreateSound(self, "")
self.Blower = CreateSound(self, "")
self.BlowerWhine = CreateSound(self, "")
self.BlowOff = CreateSound(self, "")
local Health = math.floor(self.MaxHealth ~= -1 and self.MaxHealth or (1000 + self:GetPhysicsObject():GetMass() / 3))
self:SetMaxHealth( Health )
self:SetCurHealth( Health )
self:SetAITEAM( self.AITEAM )
self:SetFastSteerAngle(self.FastSteeringAngle / self.VehicleData["steerangle"])
self:SetNotSolid( false )
self:SetupVehicle()
end )
end
function ENT:SetupVehicle()
local BaseMass = self:GetPhysicsObject():GetMass()
local MassCenterOffset = self.CustomMassCenter or Vector(0,0,0)
local BaseMassCenter = self:LocalToWorld( self:GetPhysicsObject():GetMassCenter() - MassCenterOffset )
local OffsetMass = BaseMass * 0.25
local CenterWheels = (self.posepositions["Pose1_Pos_FL"] + self.posepositions["Pose1_Pos_FR"] + self.posepositions["Pose1_Pos_RL"] + self.posepositions["Pose1_Pos_RR"]) / 4
local Sub = CenterWheels - BaseMassCenter
local Dir = Sub:GetNormalized()
local Dist = Sub:Length()
local DistAdd = BaseMass * Dist / OffsetMass
local OffsetMassCenter = BaseMassCenter + Dir * (Dist + DistAdd)
self.MassOffset = ents.Create( "prop_physics" )
self.MassOffset:SetModel( "models/hunter/plates/plate.mdl" )
self.MassOffset:SetPos( OffsetMassCenter )
self.MassOffset:SetAngles( Angle(0,0,0) )
self.MassOffset:Spawn()
self.MassOffset:Activate()
self.MassOffset:GetPhysicsObject():EnableMotion(false)
self.MassOffset:GetPhysicsObject():SetMass( OffsetMass )
self.MassOffset:GetPhysicsObject():EnableDrag( false )
self.MassOffset:SetOwner( self )
self.MassOffset:DrawShadow( false )
self.MassOffset:SetNotSolid( true )
self.MassOffset:SetNoDraw( true )
self.MassOffset.DoNotDuplicate = true
simfphys.SetOwner( self.EntityOwner, self.MassOffset )
local weld = constraint.Weld(self.MassOffset,self, 0, 0, 0,true, true)
weld.DoNotDuplicate = true
local ballsack = constraint.AdvBallsocket(self.MassOffset, self,0,0,Vector(0,0,0),Vector(0,0,0),0,0, -0.01, -0.01, -0.01, 0.01, 0.01, 0.01, 0, 0, 0, 0, 1)
ballsack.DoNotDuplicate = true
if self.CustomWheels then
if self.CustomWheelModel then
if not file.Exists( self.CustomWheelModel, "GAME" ) then
if IsValid( self.EntityOwner ) then
self.EntityOwner:PrintMessage( HUD_PRINTTALK, "ERROR: \""..self.CustomWheelModel.."\" does not exist! Removing vehicle. (Class: "..self:GetSpawn_List()..")")
end
self:Remove()
return
end
if self.SteerFront ~= false then
self.SteerMaster = ents.Create( "prop_physics" )
self.SteerMaster:SetModel( self.CustomWheelModel )
self.SteerMaster:SetPos( self:GetPos() )
self.SteerMaster:SetAngles( self:GetAngles() )
self.SteerMaster:Spawn()
self.SteerMaster:Activate()
local pobj = self.SteerMaster:GetPhysicsObject()
if IsValid(pobj) then
pobj:EnableMotion(false)
else
if IsValid( self.EntityOwner ) then
self.EntityOwner:PrintMessage( HUD_PRINTTALK, "ERROR: \""..self.CustomWheelModel.."\" doesn't have an collision model! Removing vehicle. (Class: "..self:GetSpawn_List()..")")
end
self.SteerMaster:Remove()
self:Remove()
return
end
self.SteerMaster:SetOwner( self )
self.SteerMaster:DrawShadow( false )
self.SteerMaster:SetNotSolid( true )
self.SteerMaster:SetNoDraw( true )
self.SteerMaster.DoNotDuplicate = true
self:DeleteOnRemove( self.SteerMaster )
simfphys.SetOwner( self.EntityOwner, self.SteerMaster )
end
if self.SteerRear then
self.SteerMaster2 = ents.Create( "prop_physics" )
self.SteerMaster2:SetModel( self.CustomWheelModel )
self.SteerMaster2:SetPos( self:GetPos() )
self.SteerMaster2:SetAngles( self:GetAngles() )
self.SteerMaster2:Spawn()
self.SteerMaster2:Activate()
local pobj = self.SteerMaster2:GetPhysicsObject()
if IsValid(pobj) then
pobj:EnableMotion(false)
else
if IsValid( self.EntityOwner ) then
self.EntityOwner:PrintMessage( HUD_PRINTTALK, "ERROR: \""..self.CustomWheelModel.."\" doesn't have an collision model! Removing vehicle. (Class: "..self:GetSpawn_List()..")")
end
self.SteerMaster2:Remove()
self:Remove()
return
end
self.SteerMaster2:SetOwner( self )
self.SteerMaster2:DrawShadow( false )
self.SteerMaster2:SetNotSolid( true )
self.SteerMaster2:SetNoDraw( true )
self.SteerMaster2.DoNotDuplicate = true
self:DeleteOnRemove( self.SteerMaster2 )
simfphys.SetOwner( self.EntityOwner, self.SteerMaster2 )
end
local radius = IsValid(self.SteerMaster) and (self.SteerMaster:OBBMaxs() - self.SteerMaster:OBBMins()) or (self.SteerMaster2:OBBMaxs() - self.SteerMaster2:OBBMins())
self.FrontWheelRadius = self.FrontWheelRadius or math.max( radius.x, radius.y, radius.z ) * 0.5
self.RearWheelRadius = self.RearWheelRadius or self.FrontWheelRadius
self:CreateWheel(1, WheelFL, self:LocalToWorld( self.CustomWheelPosFL ), self.FrontHeight, self.FrontWheelRadius, false , self:LocalToWorld( self.CustomWheelPosFL + Vector(0,0,self.CustomSuspensionTravel * 0.5) ),self.CustomSuspensionTravel, self.FrontConstant, self.FrontDamping, self.FrontRelativeDamping)
self:CreateWheel(2, WheelFR, self:LocalToWorld( self.CustomWheelPosFR ), self.FrontHeight, self.FrontWheelRadius, true , self:LocalToWorld( self.CustomWheelPosFR + Vector(0,0,self.CustomSuspensionTravel * 0.5) ),self.CustomSuspensionTravel, self.FrontConstant, self.FrontDamping, self.FrontRelativeDamping)
self:CreateWheel(3, WheelRL, self:LocalToWorld( self.CustomWheelPosRL ), self.RearHeight, self.RearWheelRadius, false , self:LocalToWorld( self.CustomWheelPosRL + Vector(0,0,self.CustomSuspensionTravel * 0.5) ),self.CustomSuspensionTravel, self.RearConstant, self.RearDamping, self.RearRelativeDamping)
self:CreateWheel(4, WheelRR, self:LocalToWorld( self.CustomWheelPosRR ), self.RearHeight, self.RearWheelRadius, true , self:LocalToWorld( self.CustomWheelPosRR + Vector(0,0,self.CustomSuspensionTravel * 0.5) ), self.CustomSuspensionTravel, self.RearConstant, self.RearDamping, self.RearRelativeDamping)
if self.CustomWheelPosML then
self:CreateWheel(5, WheelML, self:LocalToWorld( self.CustomWheelPosML ), self.RearHeight, self.RearWheelRadius, false , self:LocalToWorld( self.CustomWheelPosML + Vector(0,0,self.CustomSuspensionTravel * 0.5) ),self.CustomSuspensionTravel, self.RearConstant, self.RearDamping, self.RearRelativeDamping)
end
if self.CustomWheelPosMR then
self:CreateWheel(6, WheelMR, self:LocalToWorld( self.CustomWheelPosMR ), self.RearHeight, self.RearWheelRadius, true , self:LocalToWorld( self.CustomWheelPosMR + Vector(0,0,self.CustomSuspensionTravel * 0.5) ), self.CustomSuspensionTravel, self.RearConstant, self.RearDamping, self.RearRelativeDamping)
end
else
if IsValid( self.EntityOwner ) then
self.EntityOwner:PrintMessage( HUD_PRINTTALK, "ERROR: no wheel model defined. Removing vehicle. (Class: "..self:GetSpawn_List()..")")
end
self:Remove()
end
else
self:CreateWheel(1, WheelFL, self:GetAttachment( self:LookupAttachment( "wheel_fl" ) ).Pos, self.FrontHeight, self.FrontWheelRadius, false , self.posepositions.Pose1_Pos_FL, self.VehicleData.suspensiontravel_fl, self.FrontConstant, self.FrontDamping, self.FrontRelativeDamping)
self:CreateWheel(2, WheelFR, self:GetAttachment( self:LookupAttachment( "wheel_fr" ) ).Pos, self.FrontHeight, self.FrontWheelRadius, true , self.posepositions.Pose1_Pos_FR, self.VehicleData.suspensiontravel_fr, self.FrontConstant, self.FrontDamping, self.FrontRelativeDamping)
self:CreateWheel(3, WheelRL, self:GetAttachment( self:LookupAttachment( "wheel_rl" ) ).Pos, self.RearHeight, self.RearWheelRadius, false , self.posepositions.Pose1_Pos_RL, self.VehicleData.suspensiontravel_rl, self.RearConstant, self.RearDamping, self.RearRelativeDamping)
self:CreateWheel(4, WheelRR, self:GetAttachment( self:LookupAttachment( "wheel_rr" ) ).Pos, self.RearHeight, self.RearWheelRadius, true , self.posepositions.Pose1_Pos_RR, self.VehicleData.suspensiontravel_rr, self.RearConstant, self.RearDamping, self.RearRelativeDamping)
end
timer.Simple( 0.01, function()
if not istable( self.Wheels ) then return end
for i = 1, table.Count( self.Wheels ) do
local Ent = self.Wheels[ i ]
local PhysObj = Ent:GetPhysicsObject()
if IsValid( PhysObj ) then
PhysObj:EnableMotion( true )
end
end
timer.Simple( 0.1, function()
if not IsValid( self ) then return end
self:GetPhysicsObject():EnableMotion(true)
local PhysObj = self.MassOffset:GetPhysicsObject()
if IsValid( PhysObj ) then
PhysObj:EnableMotion(true)
end
end )
end )
if istable( self.GibModels ) then
for _, modelName in ipairs( self.GibModels ) do
util.PrecacheModel( modelName )
end
end
self:OnSpawn()
hook.Run( "simfphysOnSpawn", self )
self:SetlvsReady( true )
self.VehicleData["filter"] = self:GetCrosshairFilterEnts()
end
function ENT:CreateWheel(index, name, attachmentpos, height, radius, swap_y , poseposition, suspensiontravel, constant, damping, rdamping)
local fAng = self:LocalToWorldAngles( self.VehicleData.LocalAngForward )
local rAng = self:LocalToWorldAngles( self.VehicleData.LocalAngRight )
local Forward = fAng:Forward()
local Right = swap_y and -rAng:Forward() or rAng:Forward()
local Up = self:GetUp()
local RopeLength = 150
local LimiterLength = 60
local LimiterRopeLength = math.sqrt( (suspensiontravel * 0.5) ^ 2 + LimiterLength ^ 2 )
local WheelMass = self.Mass / 32
if self.FrontWheelMass and (index == 1 or index == 2) then
WheelMass = self.FrontWheelMass
end
if self.RearWheelMass and (index == 3 or index == 4 or index == 5 or index == 6) then
WheelMass = self.RearWheelMass
end
self.name = ents.Create( "gmod_sent_vehicle_fphysics_wheel" )
self.name:SetPos( attachmentpos - Up * height)
self.name:SetAngles( fAng )
self.name:Spawn()
self.name:Activate()
self.name:PhysicsInitSphere( radius, "jeeptire" )
self.name:SetCollisionBounds( Vector(-radius,-radius,-radius), Vector(radius,radius,radius) )
self.name:GetPhysicsObject():EnableMotion(false)
self.name:GetPhysicsObject():SetMass( WheelMass )
self.name:SetBaseEnt( self )
simfphys.SetOwner( self.EntityOwner, self.name )
self.name.EntityOwner = self.EntityOwner
self.name.Index = index
self.name.Radius = radius
self.name:SetRadius( radius )
if self.CustomWheels then
local Model = (self.CustomWheelModel_R and (index == 3 or index == 4 or index == 5 or index == 6)) and self.CustomWheelModel_R or self.CustomWheelModel
local ghostAng = Right:Angle()
local mirAng = swap_y and 1 or -1
ghostAng:RotateAroundAxis(Forward,self.CustomWheelAngleOffset.p * mirAng)
ghostAng:RotateAroundAxis(Right,self.CustomWheelAngleOffset.r * mirAng)
ghostAng:RotateAroundAxis(Up,-self.CustomWheelAngleOffset.y)
local Camber = self.CustomWheelCamber or 0
ghostAng:RotateAroundAxis(Forward, Camber * mirAng)
self.GhostWheels[index] = ents.Create( "gmod_sent_vehicle_fphysics_attachment" )
self.GhostWheels[index]:SetModel( Model )
self.GhostWheels[index]:SetPos( self.name:GetPos() )
self.GhostWheels[index]:SetAngles( ghostAng )
self.GhostWheels[index]:SetOwner( self )
self.GhostWheels[index]:Spawn()
self.GhostWheels[index]:Activate()
self.GhostWheels[index]:SetNotSolid( true )
self.GhostWheels[index].DoNotDuplicate = true
self.GhostWheels[index]:SetParent( self.name )
self:DeleteOnRemove( self.GhostWheels[index] )
simfphys.SetOwner( self.EntityOwner, self.GhostWheels[index] )
self.GhostWheels[index]:SetRenderMode( RENDERMODE_TRANSALPHA )
if self.ModelInfo then
if self.ModelInfo.WheelColor then
self.GhostWheels[index]:SetColor( self.ModelInfo.WheelColor )
end
end
self.name.GhostEnt = self.GhostWheels[index]
local nocollide = constraint.NoCollide(self,self.name,0,0)
nocollide.DoNotDuplicate = true
end
local targetentity = self
if self.CustomWheels then
if index == 1 or index == 2 then
targetentity = self.SteerMaster or self
end
if index == 3 or index == 4 then
targetentity = self.SteerMaster2 or self
end
end
local Ballsocket = constraint.AdvBallsocket(targetentity,self.name,0,0,Vector(0,0,0),Vector(0,0,0),0,0, -0.01, -0.01, -0.01, 0.01, 0.01, 0.01, 0, 0, 0, 1, 1)
local Rope1 = constraint.Rope(self,self.name,0,0,self:WorldToLocal( self.name:GetPos() + Forward * RopeLength * 0.5 + Right * RopeLength), Vector(0,0,0), Vector(RopeLength * 0.5,RopeLength,0):Length(), 0, 0, 0,"cable/cable2", true )
local Rope2 = constraint.Rope(self,self.name,0,0,self:WorldToLocal( self.name:GetPos() - Forward * RopeLength * 0.5 + Right * RopeLength), Vector(0,0,0), Vector(RopeLength * 0.5,RopeLength,0):Length(), 0, 0, 0,"cable/cable2", true )
if self.StrengthenSuspension == true then
local Rope3 = constraint.Rope(self,self.name,0,0,self:WorldToLocal( poseposition - Up * suspensiontravel * 0.5 + Right * LimiterLength), Vector(0,0,0),LimiterRopeLength * 0.99, 0, 0, 0,"cable/cable2", false )
local Rope4 = constraint.Rope(self,self.name,0,0,self:WorldToLocal( poseposition - Up * suspensiontravel * 0.5 - Right * LimiterLength), Vector(0,0,0),LimiterRopeLength * 1, 0, 0, 0,"cable/cable2", false )
local elastic1 = constraint.Elastic(self.name, self, 0, 0, Vector(0,0,height), self:WorldToLocal( self.name:GetPos() ), constant * 0.5, damping * 0.5, rdamping * 0.5,"cable/cable2",0, false)
local elastic2 = constraint.Elastic(self.name, self, 0, 0, Vector(0,0,height), self:WorldToLocal( self.name:GetPos() ), constant * 0.5, damping * 0.5, rdamping * 0.5,"cable/cable2",0, false)
Rope3.DoNotDuplicate = true
Rope4.DoNotDuplicate = true
elastic1.DoNotDuplicate = true
elastic2.DoNotDuplicate = true
self.Elastics[index] = elastic1
self.Elastics[index * 10] = elastic2
else
local Rope3 = constraint.Rope(self,self.name,0,0,self:WorldToLocal( poseposition - Up * suspensiontravel * 0.5 + Right * LimiterLength), Vector(0,0,0),LimiterRopeLength, 0, 0, 0,"cable/cable2", false )
local elastic = constraint.Elastic(self.name, self, 0, 0, Vector(0,0,height), self:WorldToLocal( self.name:GetPos() ), constant, damping, rdamping,"cable/cable2",0, false)
Rope3.DoNotDuplicate = true
elastic.DoNotDuplicate = true
self.Elastics[index] = elastic
end
self.Wheels[index] = self.name
Ballsocket.DoNotDuplicate = true
Rope1.DoNotDuplicate = true
Rope2.DoNotDuplicate = true
if index == 2 then
if IsValid( self.Wheels[ 1 ] ) and IsValid( self.Wheels[ 2 ] ) then
local nocollide = constraint.NoCollide( self.Wheels[ 1 ], self.Wheels[ 2 ], 0, 0 )
nocollide.DoNotDuplicate = true
end
elseif index == 4 then
if IsValid( self.Wheels[ 3 ] ) and IsValid( self.Wheels[ 4 ] ) then
local nocollide = constraint.NoCollide( self.Wheels[ 3 ], self.Wheels[ 4 ], 0, 0 )
nocollide.DoNotDuplicate = true
end
elseif index == 6 then
if IsValid( self.Wheels[ 5 ] ) and IsValid( self.Wheels[ 6 ] ) then
local nocollide = constraint.NoCollide( self.Wheels[ 5 ], self.Wheels[ 6 ], 0, 0 )
nocollide.DoNotDuplicate = true
end
end
end