// The following script is written by freemmaann, if you have any complaints or ideas contact me: freemmaann@gmail.com or skype - comman6. //"VC_Enabled" - Force enable/shut down Vehicle Controller. //"VC_Enabled_CLIENT" - Force enable/shut down Client-Side part of the Vehicle Controller. VC_SentData = VC_SentData or {} hook.Add("PlayerInitialSpawn", "VC_PlayerInitialSpawn", function(ply) for Name, table in pairs(VC_SentData) do if table.LightTable then VC_SendToClient_Lights(Name, table.LightTable, true, ply) end -- if table.Siren then VC_SendToClient_Lights(Name, table.Siren, true, ply) end end end) local function SendData(name, Typek, k, v, kill, ply) net.Start("VC_SendToClient_Lights") net.WriteString(name) net.WriteString(kill and "A" or "") net.WriteString(Typek) net.WriteInt(k, 32) net.WriteTable(v) if ply then net.Send(ply) else net.Broadcast() end end util.AddNetworkString("VC_SendToClient_Lights") function VC_SendToClient_Lights(name, table, ignore, ply) if !VC_SentData[name] then VC_SentData[name] = {} end if !VC_SentData[name].LightTable or ignore then SendData(name, "", 0, {}, true, ply) for Typek, Typev in pairs(table) do for k,v in pairs(Typev) do SendData(name, Typek, k, v, nil, ply) end end VC_SentData[name].LightTable = table end end util.AddNetworkString("VC_SendToClient_Siren") function VC_SendToClient_Siren(name, table, ignore, ply) if !VC_SentData[name] then VC_SentData[name] = {} end if !VC_SentData[name].Siren or ignore then net.Start("VC_SendToClient_Siren") net.WriteString(name) net.WriteTable(table) if ply then net.Send(ply) else net.Broadcast() end VC_SentData[name].Siren = table end end util.AddNetworkString("VC_SendToClient_Name") function VC_SendToClient_Name(ent, name) net.Start("VC_SendToClient_Name") net.WriteEntity(ent) net.WriteString(name) net.Broadcast() end util.AddNetworkString("VC_SendToClient_ClearSiren") function VC_SendToClient_ClearSiren(ent) net.Start("VC_SendToClient_ClearSiren") net.WriteEntity(ent) net.Broadcast() end function VC_SendDataToClient(ent, ignore) if !ent.VC_IsPrisonerPod and ent.VC_Name then VC_SendToClient_Name(ent, ent.VC_Name) if ent.VC_LightTable then VC_SendToClient_Lights(ent.VC_Name, ent.VC_LightTable, ignore) end if ent.VehicleTable.VC_Siren then VC_SendToClient_Siren(ent.VC_Name, ent.VehicleTable.VC_Siren, ignore) end VC_SendToClient_ClearSiren(ent) end end function VCMsg(msg) if type(msg) != table then msg = {msg} end for _, PM in pairs(msg) do if type(PM) != string then PM = tostring(PM) end player.GetAll()[1]:ChatPrint(PM) end end VC_Horn = {Sound = "vehicles/vc_horn_light.wav", Pitch = 100, Looping = false} local ConVarT, ConVT, TMT = {["VC_Trl_Auto_Attach"] = "1", ["VC_Lights"] = "1", ["VC_HeadLights"] = "1", ["VC_Trl_Attach_Distance"] = "150", ["VC_Trl_Truck_Brakes"] = "1", ["VC_Trl_Brakes_Enter_Exit"] = "0", ["VC_Trl_Crash_Brakes"] = "1", ["VC_Wheel_Lock"] = "1", ["VC_Brake_Lock"] = "1", ["VC_Siren_Affect_NPCs"] = "1", ["VC_Door_Sounds"] = "1", ["VC_Wheel_Dust"] = "0", ["VC_Wheel_Dust_Brakes"] = "0", ["VC_Exit_Velocity"] = "1", ["VC_Exit_NoCollision"] = "1", ["VC_Exhaust_Effect"] = "0", ["VC_Damage"] = "1", ["VC_Dmg_Fire_Duration"] = "30", ["VC_Health_Multiplier"] = "1", ["VC_Lights_Brake"] = "1", ["VC_Lights_Reverse"] = "1", ["VC_Passenger_Seats"] = "1", ["VC_Radio"] = "1", ["VC_Model_Adjust"] = "1"}, 0, 0 for CVk,CVv in pairs(ConVarT) do if !ConVarExists(CVk) then CreateConVar(CVk, CVv, {FCVAR_PROTECTED}) end end CreateConVar("VC_Enabled", "1", {FCVAR_PROTECTED}, "Force enable/disable Vehicle Control.") AddCSLuaFile("autorun/client/VehController_cl.lua") local Tgs = string.Explode(",",(GetConVarString("sv_tags") or "")) table.insert(Tgs, "VCMod&MCMV") table.sort(Tgs) RunConsoleCommand("sv_tags", table.concat(Tgs, ",")) function VC_PrjTxtSpawn(ent, pos) local PLht = ents.Create("env_projectedtexture") PLht:SetAngles(VC_AngleCombCalc(ent:GetAngles(), Angle(0, 90, 0))) PLht:SetPos(VC_VectorToWorld(ent, pos)) PLht:SetParent(ent) PLht:SetKeyValue("lightcolor", "225, 225, 255") PLht:SetKeyValue("farz", 2048) PLht:SetKeyValue("lightfov", 130) PLht:SetKeyValue("enableshadows", 1) PLht:SetKeyValue("nearz", 32) PLht:Spawn() PLht.VC_Parent = ent return PLht end function VC_CreateLight(ent, LTbl) local LTable = {} if LTbl.HeadLightAngle then LTable.PrjTxt = VC_PrjTxtSpawn(ent, LTbl.Pos) end return LTable end function VC_RemoveLight(Lht) if IsValid(Lht.PrjTxt) then Lht.PrjTxt:Remove() end end function VC_DeleteLights_Head(ent) if ent.VC_LightTable.Head and ent.VC_Lights then for CLk, CLv in pairs(ent.VC_LightTable.Head) do if ent.VC_Lights[CLk] and ent.VC_Lights[CLk].Head then VC_RemoveLight(ent.VC_Lights[CLk].Head) ent.VC_Lights[CLk].Head = nil end end ent.VC_Lights_Head_Created = nil end end function VC_EngAboveWtr(veh, UWC) if !veh.VC_WaterCheckDl or CurTime() >= veh.VC_WaterCheckDl[1] then veh.VC_WaterCheckDl = {CurTime()+ 0.05, veh:WaterLevel() < 1} end return veh.VC_WaterCheckDl[2] or !UWC and veh.VC_InterWater != false and !veh:GetNWBool("VC_HullDamaged") end function VC_EaseInOut(num) return (math.sin(math.pi*(num-0.5))+1)/2 end function VC_AngleCombCalc(ang1, ang2) ang1:RotateAroundAxis(ang1:Forward(), ang2.p) ang1:RotateAroundAxis(ang1:Right(), ang2.r) ang1:RotateAroundAxis(ang1:Up(), ang2.y) return ang1 end function VC_AngleInBounds(BNum, ang1, ang2) return math.abs(math.AngleDifference(ang1.p, ang2.p)) < BNum and math.abs(math.AngleDifference(ang1.y, ang2.y)) < BNum and math.abs(math.AngleDifference(ang1.r, ang2.r)) < BNum end function VC_AngleDifference(ang1, ang2) return math.max(math.max(math.abs(math.AngleDifference(ang1.p, ang2.p)), math.abs(math.AngleDifference(ang1.y, ang2.y))), math.abs(math.AngleDifference(ang1.r, ang2.r))) end function VC_AtcToWorld(ent, vec) if vec then local Atc = ent:LookupAttachment(vec) if Atc != 0 then vec = ent:GetAttachment(Atc).Pos else vec = ent:GetPos() end else vec = Vector(0,0,0) end return vec end function VC_VectorToWorld(ent, vec) if !vec then vec = Vector(0,0,0) end return ent:LocalToWorld(vec) end local function DecalSpawn(ent, pos, mat, clr, scl, alf, dyn, gps) local BLht = ents.Create("env_sprite") BLht:SetPos(pos) BLht:SetKeyValue("model", "vcmod/light_distort.vmt") BLht:SetKeyValue("rendercolor", clr) BLht:SetKeyValue("rendermode", "9") BLht:SetKeyValue("renderfx", "14") BLht:SetKeyValue("renderamt", alf) BLht:SetKeyValue("Scale", scl*3) BLht:SetKeyValue("GlowProxySize", gps or 5) BLht:SetParent(ent) BLht:Spawn() if dyn then local DLht = ents.Create("VC_DynLight") DLht:SetParent(BLht) DLht:SetPos(pos) DLht:Spawn() DLht:SetNWString("DLClr", clr) DLht:SetNWInt("DLBrtns", alf/110) DLht:SetNWInt("DLSize", scl) end return BLht end local function EmitSoundTS(ent, snd, pch) ent:EmitSound(snd, 100, math.Clamp(GetConVarNumber("host_timescale")*(pch or 100),1,255)) end local function CarDoorOC(veh, cls) local VTbl = (veh.VC_ExtraSeat and veh:GetParent() or veh).VehicleTable if cls then if veh.VC_TBTDC and CurTime() >= veh.VC_TBTDC then EmitSoundTS(veh, VTbl and VTbl.VC_Sound_Door_Close or "vehicles/vc_door_close.wav", 100+ math.Rand(-2,2)) veh.VC_TBTDC = nil end else if !veh.VC_TBTDC or CurTime() >= veh.VC_TBTDC then EmitSoundTS(veh, VTbl and VTbl.VC_Sound_Door_Open or "vehicles/vc_door_open.wav", 100+ math.Rand(-2,2)) end end end local function AttachVecCalc(vec, ent) local EPos = false if type(vec) == "Vector" then EPos = ent:GetPos()+ ent:GetRight()* vec.x+ ent:GetForward()* vec.y+ ent:GetUp()* vec.z else EPos = ent:GetAttachment(ent:LookupAttachment(vec)).Pos end return EPos end local function VecAboveWtr(vec) local WTV = util.PointContents(vec) return WTV != 268435488 and WTV != 32 end local function EnginePos(veh) local EPos = false if veh.VehicleTable and veh.VehicleTable.VC_EnginePos then EPos = AttachVecCalc(veh.VehicleTable.VC_EnginePos, veh) else if veh:GetClass() == "prop_vehicle_airboat" then EPos = veh:GetPos()+ veh:GetUp()*55+ veh:GetForward()*-45 else EPos = veh:LookupAttachment("vehicle_engine") != 0 and veh:GetAttachment(veh:LookupAttachment("vehicle_engine")).Pos or veh:GetPos()+ veh:GetUp()*25+ veh:GetForward()*75 end if veh:GetModel() == "models/vehicle.mdl" then EPos = EPos+ veh:GetForward()* -20 end end return EPos end local function EngAboveWtr(veh) if veh:LookupAttachment("vehicle_engine") == 0 and veh:WaterLevel() < 3 or veh:LookupAttachment("vehicle_engine") != 0 and VecAboveWtr(veh:GetAttachment(veh:LookupAttachment("vehicle_engine")).Pos) then return true end end function VC_BrakesOff(ent, DSB) local VehT = ent.VehicleTable if !DSB then ent:Fire("HandBrakeOff") end ent.VC_BrakesOn = false if tobool(VC_AirBrake_Sound) and ent.VC_BrksOnTm and CurTime()-ent.VC_BrksOnTm > 0.6 and (!VehT or VehT.VC_AirBrakeSound != false) and (VehT and (VehT.VC_HookPosition or VehT.VC_SocketPosition or VehT.VC_AirBrakeSound) or ent.VC_Volume and ent.VC_Volume > 1500000) then VC_EmitSound(ent, "VehController/air_brake.wav", math.Rand(94,106), 75, 0.25+ math.Clamp(CurTime()-ent.VC_BrksOnTm- 0.6, 0, 2.5)/10) end ent.VC_BrksOnTm = nil end function VC_BrakesOn(ent, DSB) local VehT = ent.VehicleTable if !DSB then ent:Fire("HandBrakeOn") end ent.VC_BrakesOn = true if !ent.VC_BrksOnTm then ent.VC_BrksOnTm = CurTime() end end file.CreateDir("VCMod_Old") if SERVER then hook.Add("InitPostEntity", "VC_GM_Init", function() local NPC = ents.Create("npc_rp_car") if IsValid(NPC) then NPC:SetAngles(NPC_SpawnAngle or Angle(0,0,0)) NPC:SetPos(NPC_SpawnPosition or Vector(0,0,0)) NPC:Spawn() end end) end function VC_MakeScripts(id) if id then local Car = list.Get("Vehicles")[id] if Car and !file.Exists("data/vcmod_old/"..Car.Name..".txt", "GAME") and (Car.VC_Lights or Car.VC_Exhaust or Car.VC_ExtraSeats or Car.VC_Siren) then Cnt = Cnt+1 file.Write("VCMod_Old/"..Car.Name..".txt", util.TableToJSON(Car)) end else local Cnt = 0 for k,v in pairs(list.Get("Vehicles")) do if !file.Exists("data/vcmod_old/"..v.Name..".txt", "GAME") and (v.VC_Lights or v.VC_Exhaust or v.VC_ExtraSeats or v.VC_Siren) then Cnt = Cnt+1 file.Write("VCMod_Old/"..v.Name..".txt", util.TableToJSON(v)) end end print("VCMod: active scripts: "..Cnt..".") end end function VC_Lock(ent) if !ent.VC_Locked then if IsValid(ent:GetDriver()) then ent:GetDriver():ExitVehicle() end if ent.VC_SeatTable then for _, St in pairs(ent.VC_SeatTable) do if IsValid(St:GetDriver()) then St:GetDriver():ExitVehicle() end end end ent:Fire("Lock", 0) ent.VC_Locked = true end end function VC_UnLock(ent) if ent.VC_Locked then ent:Fire("Unlock", 0) ent.VC_Locked = false end end local meta = FindMetaTable("Vehicle") function meta:Lock() VC_Lock(self) end function meta:UnLock() VC_UnLock(self) end timer.Simple(1, function() VC_MakeScripts() end) hook.Add("PlayerEnteredVehicle", "VC_VehEnter", function(ply, veh) if VC_Enabled then if veh.VC_BrksOn and EngAboveWtr(veh) then veh.VC_BrksOn = false end if (tobool(VC_Trl_Truck_Brakes) or tobool(VC_Trl_Brakes_Enter_Exit)) and IsValid(veh.VC_Trailer) then veh.VC_Trailer:Fire("HandBrakeOff") veh.VC_Trailer.VC_BrksOn = false end if VC_Model_Adjust and veh.VehicleTable and veh.VehicleTable.VC_Model_Offset or veh.VC_MdlOfst then ply:SetParent() ply:SetPos(AttachVecCalc(veh.VC_MdlOfst or veh.VehicleTable.VC_Model_Offset, ply)) ply:SetParent(veh) end if tobool(VC_Door_Sounds) and (string.lower(veh:GetClass()) != "prop_vehicle_prisoner_pod" or veh.VC_ExtraSeat and veh.VC_DrSnds) and !table.HasValue({"models/vehicle.mdl", "models/buggy.mdl", "models/airboat.mdl"}, veh:GetModel()) then if !ply.VC_ChnSts then CarDoorOC(veh) veh.VC_TBTDC = CurTime()+ math.Rand(1,1.2) if !veh.VC_ExtraSeat then veh.VC_TBTET = CurTime()+ veh:SequenceDuration() end else ply.VC_ChnSts = false end end end end) hook.Add("EntityTakeDamage", "VC_Damaged", function(ent, dinfo) if VC_Enabled then if tobool(VC_Damage) and (ent:IsVehicle() or ent:IsPlayer() and IsValid(ent:GetVehicle())) then local DEnt = ent:IsPlayer() and ent:GetVehicle() or ent if ent.VC_Health and ent.VC_Health > 0 and string.lower(ent:GetClass()) != "prop_vehicle_prisoner_pod" and (!ent.VehicleTable or !ent.VehicleTable.VC_IsTrailer) then local Amount = dinfo:GetDamage() if Amount < 5 then Amount = 5 end ent.VC_Health = ent.VC_Health- Amount if ent.VC_Health < 0 then ent.VC_Health = 0 end end end end end) hook.Add("EntityRemoved", "VC_Removed", function(ent) if ent.VC_HornOn and ent.VC_HornSnd:IsPlaying() then ent.VC_HornSnd:Stop() ent.VC_HornSnd:Stop() ent.VC_HornOn = false ent.VC_HornSnd = nil ent.VC_HornStm = nil ent.VC_HornVL = nil end end) hook.Add("PlayerUse", "VC_PlyUse", function(ply, ent) if VC_Enabled and tobool(VC_Passenger_Seats) and !ent.VC_Locked then if (!ent.VC_Health or ent.VC_Health > 0) and !ply.VC_JEAES and !IsValid(ply:GetVehicle()) and ent:IsVehicle() and ent.VC_SeatTable then local Veh, Dst, PTPos = nil, nil, ply:GetEyeTraceNoCursor().HitPos if ply:EyePos():Distance(PTPos) <= 65 then for _, St in pairs(ent.VC_SeatTable) do if !IsValid(St:GetDriver()) then local MDst = PTPos:Distance(St:GetPos()) if MDst < St.VC_NtrRng and (!Dst or MDst <= Dst) then Veh, Dst = St, MDst end end end end if IsValid(Veh) and (ent:LookupAttachment("vehicle_driver_eyes") == 0 or PTPos:Distance(ent:GetAttachment(ent:LookupAttachment("vehicle_driver_eyes")).Pos) > Dst) and (ent:LookupAttachment("vehicle_feet_passenger0") == 0 or PTPos:Distance(ent:GetAttachment(ent:LookupAttachment("vehicle_feet_passenger0")).Pos) > Dst) then ply:EnterVehicle(Veh) ply.VC_CanEnterTime = CurTime()+0.5 end end ply.VC_JEAES = true end end) hook.Add("CanPlayerEnterVehicle", "VC_VehCanEnter", function(ply, veh) if (IsValid(veh.VC_HangingOutPlayer) and IsValid(veh.VC_HangingOutPlayer.VC_HangingOutPlayer) and veh == veh.VC_HangingOutSeat.VC_HangingOutPlayer) or (IsValid(ply.VC_HangingOutSeat) and IsValid(ply.VC_HangingOutSeat.VC_HangingOutPlayer) and ply == ply.VC_HangingOutSeat.VC_HangingOutPlayer) or ply.VC_CanEnterTime and CurTime() < ply.VC_CanEnterTime or !veh.VC_Locked and (veh.VehicleTable and veh.VehicleTable.VC_IsTrailer or veh.VC_Health and veh.VC_Health <= 0) then return false end end) hook.Add("PlayerLeaveVehicle", "VC_VehExit", function(ply, veh) ply.VC_CanEnterTime = CurTime()+0.5 if veh.VC_ECCSN then veh:SetCollisionGroup(veh.VC_ECCSN) veh.VC_ECCSN = false end if VC_Enabled then if tobool(VC_Brake_Lock) then veh.VC_BrksOn = true if !ply:KeyDown(IN_JUMP) and !ply.VC_BrkCONE and EngAboveWtr(veh) then if IsValid(veh.VC_Trailer) then veh.VC_Trailer:Fire("HandBrakeOff", "", 0.01) veh.VC_Trailer.VC_BrksOn = false end veh:Fire("HandBrakeOff", "", 0.01) veh.VC_BrksOn = false end end if tobool(VC_Wheel_Lock) then veh.VC_Steer = 0 if ply.VC_PESteer then if EngAboveWtr(veh) then for i=1, math.random(28,33) do veh:Fire("Steer", ply.VC_PESteer) end end veh.VC_Steer = ply.VC_PESteer ply.VC_PESteer = nil end end if tobool(VC_Door_Sounds) and (string.lower(veh:GetClass()) != "prop_vehicle_prisoner_pod" or veh.VC_ExtraSeat and veh.VC_DrSnds) and !table.HasValue({"models/vehicle.mdl", "models/buggy.mdl", "models/airboat.mdl"}, veh:GetModel()) then veh.VC_TBTAC = false end if (tobool(VC_Trl_Truck_Brakes) or tobool(VC_Trl_Brakes_Enter_Exit)) and IsValid(veh.VC_Trailer) then veh.VC_Trailer:Fire("HandBrakeOn") veh.VC_Trailer.VC_BrksOn = true end if tobool(VC_Exhaust_Effect) and veh.VehicleTable and veh.VehicleTable.VC_Exhaust then veh.VC_EETBAC = CurTime()+ math.Rand(0.5,2) end if tobool(VC_Exit_Velocity) then ply:SetVelocity(veh:GetVelocity()* math.Rand(0.8,1)) end if tobool(VC_Passenger_Seats) then if veh.VC_ExtraSeat then local Ext, Dst = nil, nil for Stk, Stv in pairs(veh:GetParent().VC_SeatTable) do if veh == Stv then local StT = veh:GetParent().VehicleTable.VC_ExtraSeats[Stk] if StT then local ExPos = AttachVecCalc(StT.Pos+Vector(60*(StT.Pos.x > 0 and 1 or -1),0,0), veh:GetParent()) if !util.TraceLine({start = ply:EyePos(), endpos = ExPos, filter = {ply, veh:GetParent()}}).Hit then Ext = ExPos end end end end if !Ext then for i=1, 10 do if veh:GetParent():LookupAttachment("Exit"..i) > 0 then local AtPos = veh:GetParent():GetAttachment(veh:GetParent():LookupAttachment("Exit"..i)).Pos if !util.TraceLine({start = ply:EyePos(), endpos = AtPos, filter = {ply, veh:GetParent()}}).Hit then local MDst = ply:GetPos():Distance(AtPos) if !Dst or MDst <= Dst then Ext, Dst = AtPos, MDst end end end end end if Ext then ply:SetPos(Ext) end ply:SetEyeAngles(Angle(0, (veh:GetPos()- ply:GetPos()):Angle().y, 0)) ply:SetVelocity(veh:GetParent():GetVelocity()) end ply.VC_JEAES = true end end end) hook.Add("KeyPress", "VC_KeyPress", function(ply, key) if VC_Enabled then local veh = ply:GetVehicle() if IsValid(veh) and (string.lower(veh:GetClass()) != "prop_vehicle_prisoner_pod" or veh.VC_ExtraSeat and veh.VC_DrSnds) then if key == IN_USE then if veh:GetClass() != "prop_vehicle_airboat" then if tobool(VC_Door_Sounds) and !table.HasValue({"models/vehicle.mdl", "models/buggy.mdl", "models/airboat.mdl"}, veh:GetModel()) then if !veh.VC_TBTDC then CarDoorOC(veh) end veh.VC_TBTDC = CurTime()+ math.Rand(1,1.2) veh.VC_TBTAC = true end if tobool(VC_Wheel_Lock) then if ply:KeyDown(IN_MOVERIGHT) then ply.VC_PESteer = 1 elseif ply:KeyDown(IN_MOVELEFT) then ply.VC_PESteer = -1 end end if tobool(VC_Brake_Lock) and ply:KeyDown(IN_JUMP) then ply.VC_BrkCONE = true else ply.VC_BrkCONE = nil end end if tobool(VC_Exit_NoCollision) and !veh.VC_ECCSN then veh.VC_ECCSN = veh:GetCollisionGroup() veh:SetCollisionGroup(COLLISION_GROUP_WORLD) end elseif ply:KeyDown(IN_USE) then if veh:GetClass() != "prop_vehicle_airboat" then if tobool(VC_Door_Sounds) and !table.HasValue({"models/vehicle.mdl", "models/buggy.mdl", "models/airboat.mdl"}, veh:GetModel()) then if !veh.VC_TBTDC then CarDoorOC(veh) end veh.VC_TBTDC = CurTime()+ math.Rand(1,1.2) veh.VC_TBTAC = true end if tobool(VC_Wheel_Lock) then if key == IN_MOVERIGHT then ply.VC_PESteer = 1 elseif key == IN_MOVELEFT then ply.VC_PESteer = -1 end end if tobool(VC_Brake_Lock) and key == IN_JUMP then ply.VC_BrkCONE = true else ply.VC_BrkCONE = nil end end if tobool(VC_Exit_NoCollision) and !veh.VC_ECCSN then veh.VC_ECCSN = veh:GetCollisionGroup() veh:SetCollisionGroup(COLLISION_GROUP_WORLD) end end end end end) local function Initializssde(ent) local VehT = ent.VehicleTable if VehT then local STbl,_ = file.Find("Data/VCMod_old/*.txt", "GAME") if (table.HasValue(STbl, VehT.Name..".txt") or table.HasValue(STbl, string.lower(VehT.Name)..".txt")) and file.Exists("Data/VCMod_old/"..string.lower(VehT.Name)..".txt", "GAME") then VehT = table.Merge(VehT, util.JSONToTable(file.Read("Data/VCMod_old/"..string.lower(VehT.Name)..".txt", "GAME"))) else local STbl,_ = file.Find("scripts/VCMod_old/*.txt", "GAME") if (table.HasValue(STbl, VehT.Name..".txt") or table.HasValue(STbl, string.lower(VehT.Name)..".txt")) and file.Exists("scripts/VCMod_old/"..string.lower(VehT.Name)..".txt", "GAME") then VehT = table.Merge(VehT, util.JSONToTable(file.Read("scripts/VCMod_old/"..string.lower(VehT.Name)..".txt", "GAME"))) end end end ent.VehicleTable = VehT if VehT then if VehT.VC_Lights then for _, Lt in pairs(ent.VehicleTable.VC_Lights) do if Lt.HeadLightAngle then ent.VC_HasHeadLights = true end if Lt.BrakeColor then ent.VC_HasBrakeLights = true end if Lt.NormalColor then ent.VC_HasNormalLights = true end if Lt.BlinkersColor then ent.VC_HasBlinkerLights = true end if Lt.ReverseColor then ent.HasReverseLights = true end if ent.VC_HasHeadLights and ent.VC_HasBrakeLights and ent.VC_HasNormalLights and ent.VC_HasBlinkerLights and ent.HasReverseLights then break end end end if VehT.Name and !ent.VC_IsPrsPd then ent.VC_Name = VehT.Name ent:SetNWString("VC_Name", ent.VC_Name) end if VehT.VC_No_Indoor_Sound then ent:SetNWBool("VC_NInDrSnd", true) end if VehT.VC_NoRadio then ent:SetNWBool("VC_NoRadio", true) end end local PhysObj = ent:GetPhysicsObject() if IsValid(PhysObj) then ent.VC_Volume = PhysObj:GetVolume() ent.VC_Mass = PhysObj:GetMass() else ent.VC_Volume = 500000 end ent.VC_Lights = {} VC_CheckLights(ent) ent.VC_IsBig = ent.VC_Volume > 1500000 ent:SetNWBool("VC_IsBig", ent.VC_IsBig) VC_SendDataToClient(ent, true) end function VC_CurrentThrottle(ent) local Drv, Thrt = ent:GetDriver(), nil if IsValid(Drv) then local DForw, DBack = Drv:KeyDown(IN_FORWARD), Drv:KeyDown(IN_BACK) if DForw and !DBack then Thrt = 1 elseif !DForw and DBack then Thrt = -1 end elseif ent.VC_Throttle and ent.VC_Throttle != 0 then Thrt = ent.VC_Throttle end return Thrt end hook.Add("Think", "VC_Think", function() if CurTime() >= TMT then VC_Enabled = tobool(GetConVarNumber("VC_Enabled")) TMT = CurTime()+ 1 end if !VC_Enabled then return end if CurTime() >= ConVT then for Con,_ in pairs(ConVarT) do _G[Con] = GetConVarNumber(Con) end ConVT = CurTime()+ 0.1 end local Ents_All = ents.GetAll() for _,PEnt in pairs(Ents_All) do if PEnt:IsVehicle() then if PEnt.VC_TPTSPV and !IsValid(PEnt.VC_Trailer) then PEnt:SetNWInt("VC_TPTSD", 0) PEnt.VC_TPTSPV = false elseif !PEnt.VC_TPTSPV and PEnt.VehicleTable and IsValid(PEnt.VC_Trailer) and PEnt.VC_Trailer.VehicleTable and PEnt.VC_Trailer.VehicleTable.VC_AttachedView then PEnt:SetNWInt("VC_TPTSD", PEnt.VC_Trailer.VehicleTable.VC_AttachedView.Dist or 600) PEnt:SetNWVector("VC_TPTSO", PEnt.VC_Trailer.VehicleTable.VC_AttachedView.Offset or Vector(0,0,80)) PEnt:SetNWEntity("VC_TPTSE", PEnt.VC_Trailer) PEnt:SetNWString("VC_TPTSA", PEnt.VehicleTable.VC_AttachPos) PEnt.VC_TPTSPV = true end if tobool(VC_Damage) then if string.lower(PEnt:GetClass()) != "prop_vehicle_prisoner_pod" and (!PEnt.VehicleTable or !PEnt.VehicleTable.VC_IsTrailer and !PEnt.VehicleTable.VC_Invulnerable) then if !PEnt.VC_DBTNVDT or CurTime() >= PEnt.VC_DBTNVDT then if !PEnt.VC_Health then local HP = false if PEnt.VehicleTable and PEnt.VehicleTable.VC_HealthOverride then HP = PEnt.VehicleTable.VC_HealthOverride else HP = 200+ (IsValid(PEnt:GetPhysicsObject()) and PEnt:GetPhysicsObject():GetVolume() or 500000)/5000 end PEnt.VC_Health = HP* VC_Health_Multiplier PEnt.VC_MaxHealth = PEnt.VC_Health end if (!PEnt.VC_TBESDO or CurTime() < PEnt.VC_TBESDO) and (!PEnt.VC_EBroke or !PEnt.VC_EngSFire) and PEnt.VC_Health < PEnt.VC_MaxHealth/3 and (!IsValid(PEnt.VC_EngSmk) or PEnt.VC_EngSFire) and VecAboveWtr(EnginePos(PEnt)) then if IsValid(PEnt.VC_EngSmk) then PEnt.VC_EngSmk:Remove() end local WDE, EFT = ents.Create("info_particle_system"), PEnt.VC_Health < PEnt.VC_MaxHealth/8 WDE:SetKeyValue("effect_name", EFT and "explosion_turret_fizzle" or "explosion_turret_break_pre_smoke") WDE:SetAngles(PEnt:GetAngles()) WDE:SetPos(EnginePos(PEnt)) WDE:SetParent(PEnt) WDE:Spawn() WDE:Activate() WDE:Fire("Start") PEnt.VC_EngSmk = WDE PEnt.VC_EngSFire = EFT PEnt.VC_TBESDO = CurTime()+ (EFT and math.Clamp(VC_Dmg_Fire_Duration- 0.5, 1, VC_Dmg_Fire_Duration)* math.Rand(0.9, 1.1) or math.Rand(1,2)) end if PEnt.VC_Health >= PEnt.VC_MaxHealth/3 then if PEnt.VC_Health- (PEnt.VC_LastHealth or PEnt.VC_Health) != 0 then if (PEnt.VC_EngSFire or PEnt.VC_EngSFire == nil) and VecAboveWtr(EnginePos(PEnt)) then PEnt.VC_TBESDO = CurTime()+ math.random(45,60) end PEnt.VC_FixTmr = CurTime()+ 2 end PEnt.VC_LastHealth = PEnt.VC_Health else PEnt.VC_Health = PEnt.VC_Health- PEnt.VC_MaxHealth/250 end if IsValid(PEnt.VC_EngSmk) and (PEnt.VC_TBESDO and CurTime() >= PEnt.VC_TBESDO or PEnt.VC_Health >= PEnt.VC_MaxHealth/3 or PEnt.VC_Health >= PEnt.VC_MaxHealth/3 or !VecAboveWtr(EnginePos(PEnt))) then PEnt.VC_EngSmk:Remove() PEnt.VC_TBESDO = nil end if PEnt.VC_EBroke then if PEnt.VC_TBESDL and CurTime() >= PEnt.VC_TBESDL then PEnt.VC_Health = PEnt.VC_MaxHealth/3 PEnt.VC_TBESDL = nil end if PEnt.VC_Health > 0 then if !PEnt.VC_Locked then PEnt:Fire("UnLock") end PEnt.VC_EBroke = false end end PEnt.VC_DBTNVDT = CurTime()+ 0.2 end if !PEnt.VC_EBroke and PEnt.VC_Health and PEnt.VC_Health <= 0 then PEnt.VC_Health = 0 PEnt:Fire("Lock") local EngE, EPos = ents.Create("env_explosion"), EnginePos(PEnt) EngE:SetKeyValue("iMagnitude", "100") EngE:SetPos(EPos) EngE:SetOwner(PEnt) EngE:Spawn() EngE:Fire("explode") PEnt:GetPhysicsObject():AddAngleVelocity(Vector(math.random(-200,250),math.random(-200,200),math.random(-100,100))) if IsValid(PEnt:GetDriver()) then PEnt:GetDriver():TakeDamage(100, PEnt) PEnt:GetDriver():ExitVehicle() end if PEnt.VC_SeatTable then for _, St in pairs(PEnt.VC_SeatTable) do if IsValid(St:GetDriver()) then St:GetDriver():TakeDamage(100, PEnt) St:GetDriver():ExitVehicle() end end end PEnt.VC_TBESDL = CurTime()+ VC_Dmg_Fire_Duration* math.Rand(0.9, 1.1) PEnt.VC_EBroke = true end end elseif IsValid(PEnt.VC_EngSmk) then PEnt.VC_EngSmk:Remove() end if !PEnt.VC_INITAH then Initializssde(PEnt) PEnt.VC_INITAH = true end local VehT, GVh, Drv = PEnt.VehicleTable, PEnt.VC_ExtraSeat and PEnt:GetParent() or PEnt, PEnt:GetDriver() if PEnt == GVh and IsValid(Drv) and !PEnt.VC_BrkCONE then local Brk, EAW = Drv:KeyDown(IN_JUMP), VC_EngAboveWtr(PEnt, true) if !PEnt.VC_BrakesOn and (Brk or !EAW) then VC_BrakesOn(PEnt, true) elseif PEnt.VC_BrakesOn and !Brk and EAW then VC_BrakesOff(PEnt, true) end end if !PEnt.VC_ExtraSeat and tobool(VC_Lights) then local Speed = 0 local Above = EngAboveWtr(PEnt) if Above then Speed = PEnt:GetVelocity():Dot(PEnt:GetForward()) end if Above and (PEnt.VC_BrakesOn or IsValid(Drv) and (!Drv:KeyDown(IN_BACK) or !Drv:KeyDown(IN_FORWARD)) and (Drv:KeyDown(IN_BACK) and Speed > 5 or IsValid(Drv) and Drv:KeyDown(IN_FORWARD) and Speed < -5)) then if !PEnt.VC_Lights_Brk_Created then PEnt.VC_Lights_Brk_Created = true PEnt:SetNWBool("VC_Lights_Brk_Created", true) end elseif PEnt.VC_Lights_Brk_Created then PEnt:SetNWBool("VC_Lights_Brk_Created", false) PEnt.VC_Lights_Brk_Created = nil end if Above and IsValid(Drv) and Drv:KeyDown(IN_BACK) and Speed < -5 then if !PEnt.VC_Lights_Rev_Created then PEnt.VC_Lights_Rev_Created = true PEnt:SetNWBool("VC_Lights_Rev_Created", true) end elseif PEnt.VC_Lights_Rev_Created then PEnt:SetNWBool("VC_Lights_Rev_Created", false) PEnt.VC_Lights_Rev_Created = nil end if Above and PEnt.VC_NormalLightsOn then if !PEnt.VC_Lights_Normal_Created then PEnt.VC_Lights_Normal_Created = true PEnt:SetNWBool("VC_Lights_Normal_Created", true) end elseif PEnt.VC_Lights_Normal_Created then PEnt:SetNWBool("VC_Lights_Normal_Created", false) PEnt.VC_Lights_Normal_Created = nil end if Above and PEnt.VC_HeadLightsOn and tobool(VC_HeadLights) then if !PEnt.VC_Lights_Head_Created then PEnt.VC_Lights_Head_Created = true PEnt:SetNWBool("VC_Lights_Head_Created", true) for CLk, CLv in pairs(PEnt.VC_LightTable.Head) do if !PEnt.VC_Lights[CLk] then PEnt.VC_Lights[CLk] = {} end if !PEnt.VC_Lights[CLk].Head then PEnt.VC_Lights[CLk].Head = VC_CreateLight(PEnt, CLv) end end end elseif PEnt.VC_Lights_Head_Created then VC_DeleteLights_Head(PEnt) PEnt:SetNWBool("VC_Lights_Head_Created", false) PEnt.VC_Lights_Head_Created = nil end if Above and PEnt.VC_HazardLightsOn and PEnt.VC_Blinker_OnTime then if !PEnt.VC_Lights_Hazards_Created then PEnt.VC_Lights_Hazards_Created = true PEnt:SetNWBool("VC_Lights_Hazards_Created", true) end elseif PEnt.VC_Lights_Hazards_Created then PEnt:SetNWBool("VC_Lights_Hazards_Created", false) PEnt.VC_Lights_Hazards_Created = nil end if Above and PEnt.VC_Blinker_Left_On and PEnt.VC_Blinker_OnTime then if !PEnt.VC_Lights_Blinker_Created_Left then PEnt.VC_Lights_Blinker_Created_Left = true PEnt:SetNWBool("VC_Lights_Blinker_Created_Left", true) end elseif PEnt.VC_Lights_Blinker_Created_Left then PEnt:SetNWBool("VC_Lights_Blinker_Created_Left", false) PEnt.VC_Lights_Blinker_Created_Left = nil end if Above and PEnt.VC_Blinker_Right_On and PEnt.VC_Blinker_OnTime then if !PEnt.VC_Lights_Blinker_Created_Right then PEnt.VC_Lights_Blinker_Created_Right = true PEnt:SetNWBool("VC_Lights_Blinker_Created_Right", true) end elseif PEnt.VC_Lights_Blinker_Created_Right then PEnt:SetNWBool("VC_Lights_Blinker_Created_Right", false) PEnt.VC_Lights_Blinker_Created_Right = nil end local On = PEnt.VC_Blinker_Left_On or PEnt.VC_Blinker_Right_On or PEnt.VC_HazardLightsOn if On and !PEnt.VC_Blinking then PEnt.VC_Blinker_OnTime = nil PEnt.VC_Blinker_OffTime = CurTime() PEnt.VC_Blinking = true elseif !On and PEnt.VC_Blinking then PEnt.VC_Blinker_OffTime = nil PEnt.VC_Blinker_OnTime = nil PEnt.VC_Blinking = nil end if PEnt.VC_Blinker_OnTime and CurTime() >= PEnt.VC_Blinker_OnTime then PEnt.VC_Blinker_OnTime = nil PEnt.VC_Blinker_OffTime = CurTime()+0.4 EmitSoundTS(PEnt, "vehicles/vc_blinkers_out.wav") elseif PEnt.VC_Blinker_OffTime and CurTime() >= PEnt.VC_Blinker_OffTime then PEnt.VC_Blinker_OffTime = nil PEnt.VC_Blinker_OnTime = CurTime()+0.4 EmitSoundTS(PEnt, "vehicles/vc_blinkers_in.wav") end end if PEnt.VC_HornSnd and PEnt.VC_HornSnd:IsPlaying() then if !PEnt.VC_HornPT or CurTime() >= PEnt.VC_HornPT then PEnt.VC_HornSnd:ChangePitch(math.Clamp(GetConVarNumber("host_timescale")*(VC_Horn.Pitch or 100),1,255),0.1) PEnt.VC_HornPT = CurTime()+0.1 end if PEnt.VC_HornVL then if PEnt.VC_HornVL <= 0 then PEnt.VC_HornSnd:Stop() PEnt.VC_HornOn = false PEnt.VC_HornStm = nil PEnt.VC_HornSnd = nil PEnt.VC_HornCSE = nil PEnt.VC_HornVL = nil end elseif PEnt.VC_Health and PEnt.VC_Health <= 0 or !IsValid(PEnt:GetDriver()) or !EngAboveWtr(PEnt) then PEnt.VC_HornVL = 1 end if PEnt.VC_HornCSE and !PEnt.VC_HornVL and PEnt.VC_HornStm and CurTime() >= PEnt.VC_HornStm then PEnt.VC_HornVL = 1 end if PEnt.VC_HornVL and PEnt.VC_HornVL > 0 then if PEnt.VC_HornStm and CurTime() >= PEnt.VC_HornStm and !PEnt.VC_HornLp then PEnt.VC_HornVL = 0 else PEnt.VC_HornSnd:ChangeVolume(PEnt.VC_HornVL,0.1) PEnt.VC_HornVL = PEnt.VC_HornVL-0.15 end PEnt.VC_HornStm = nil end end if tobool(VC_Passenger_Seats) then if PEnt.VehicleTable and PEnt.VehicleTable.VC_ExtraSeats and !PEnt.VC_SeatTable then PEnt.VC_SeatTable = {} for Stk, Stv in pairs(PEnt.VehicleTable.VC_ExtraSeats) do local Seat = ents.Create("prop_vehicle_prisoner_pod") Seat:SetModel(Stv.Model or "models/props_phx/carseat2.mdl") Seat:SetKeyValue("vehiclescript", "scripts/vehicles/prisoner_pod.txt") Seat:SetKeyValue("limitview", "0") Seat:SetAngles(VC_AngleCombCalc(PEnt:GetAngles(), Stv.Ang)) Seat:SetPos(AttachVecCalc(Stv.Pos, PEnt)) Seat:SetParent(PEnt) Seat:SetNoDraw(true) Seat:DrawShadow(false) Seat:SetNotSolid(true) Seat:SetNWBool("VC_ExtraSt", true) Seat:Spawn() Seat:SetNotSolid(true) Seat:SetNWBool("VC_ExtraSt", true) Seat.VC_MdlOfst = Stv.ModelOffset Seat.VC_NtrRng = Stv.EnterRange or 80 Seat.VC_DrSnds = Stv.DoorSounds Seat.VC_RCntrl = Stv.RadioControl Seat.VC_ExtraSeat = true Seat.VC_XtAng = Stv.ExitAng or Angle(0,0,0) table.insert(PEnt.VC_SeatTable, Seat) end end elseif PEnt.VC_SeatTable then for _, St in pairs(PEnt.VC_SeatTable) do St:Remove() end PEnt.VC_SeatTable = nil end if PEnt.VC_Cruise and !PEnt.VC_BrksOn and EngAboveWtr(PEnt) and (!PEnt.VC_Health or PEnt.VC_Health >= PEnt.VC_MaxHealth/8) then if IsValid(PEnt:GetDriver()) then if !PEnt.VC_TThl then PEnt.VC_TThl = 0.5 end if PEnt.VC_TThl > 0.1 and PEnt:GetDriver():KeyDown(IN_BACK) then PEnt.VC_TThl = PEnt.VC_TThl- 0.01 elseif PEnt.VC_TThl < 1 and PEnt:GetDriver():KeyDown(IN_FORWARD) then PEnt.VC_TThl = PEnt.VC_TThl+ 0.01 end end if !IsValid(PEnt:GetDriver()) or !PEnt:GetDriver():KeyDown(IN_JUMP) and !PEnt:GetDriver():KeyDown(IN_BACK) and !PEnt:GetDriver():KeyDown(IN_FORWARD) then PEnt:Fire("Throttle", tostring(PEnt.VC_TThl)) PEnt.VC_Thrtl = true end elseif PEnt.VC_Thrtl then PEnt:Fire("Throttle", "0") PEnt.VC_Thrtl = false end if tobool(VC_Door_Sounds) and (!PEnt.VC_TBTET or CurTime() >= PEnt.VC_TBTET) and !PEnt.VC_TBTAC and PEnt.VC_TBTDC and CurTime() >= PEnt.VC_TBTDC then CarDoorOC(PEnt, true) end if tobool(VC_Exhaust_Effect) and IsValid(PEnt:GetDriver()) and PEnt.VehicleTable and PEnt.VehicleTable.VC_Exhaust and PEnt:GetVelocity():Length() < 550 and EngAboveWtr(PEnt) then if IsValid(PEnt:GetDriver()) and (PEnt:GetDriver():KeyDown(IN_FORWARD) or PEnt:GetDriver():KeyDown(IN_BACK)) and !PEnt:GetDriver():KeyDown(IN_JUMP) and PEnt:GetVelocity():Length() < 450 then if !PEnt.VC_EEPES then PEnt.VC_EEPES = {} for _, HST in pairs(PEnt.VehicleTable.VC_Exhaust) do local WDE = ents.Create("info_particle_system") WDE:SetKeyValue("effect_name", "Exhaust") WDE:SetAngles(PEnt:GetAngles()+ (HST.Ang or Angle(0,0,0))) WDE:SetPos(AttachVecCalc(HST.Pos, PEnt) or Vector(0,0,0)) WDE:SetParent(PEnt) WDE:Spawn() WDE:Activate() WDE:Fire("Start") table.insert(PEnt.VC_EEPES, WDE) end end PEnt.VC_EETBACS = CurTime()+ math.Rand(0.2,0.4) else if (!PEnt.VC_EETBACS or CurTime() >= PEnt.VC_EETBACS) and PEnt.VC_EEPES then for _,HST in pairs(PEnt.VC_EEPES) do HST:Remove() end PEnt.VC_EEPES = nil end end if !PEnt.VC_EEPE then PEnt.VC_EEPE = {} for _, HST in pairs(PEnt.VehicleTable.VC_Exhaust) do local WDE = ents.Create("info_particle_system") WDE:SetKeyValue("effect_name", "Exhaust") WDE:SetAngles(PEnt:GetAngles()+ (HST.Ang or Angle(0,0,0))) WDE:SetPos(AttachVecCalc(HST.Pos, PEnt) or Vector(0,0,0)) WDE:SetParent(PEnt) WDE:Spawn() WDE:Activate() WDE:Fire("Start") table.insert(PEnt.VC_EEPE, WDE) end end else if (!PEnt.VC_EETBAC or CurTime() >= PEnt.VC_EETBAC) and PEnt.VC_EEPE then for _,HST in pairs(PEnt.VC_EEPE) do HST:Remove() end PEnt.VC_EEPE = nil end if PEnt.VC_EEPES then for _,HST in pairs(PEnt.VC_EEPES) do HST:Remove() end PEnt.VC_EEPES = nil end end if (!PEnt.VC_TBNWDC or CurTime() >= PEnt.VC_TBNWDC) and (!PEnt.VehicleTable or !PEnt.VehicleTable.VC_NoWheelDust) and string.lower(PEnt:GetClass()) != "prop_vehicle_prisoner_pod" and PEnt:GetClass() != "prop_vehicle_airboat" then local DEL = {"wheel_fl", "wheel_fr", "wheel_rl", "wheel_rr"} if tobool(VC_Wheel_Dust) then if !PEnt.VC_WDPST then PEnt.VC_WDPST = {} end if !PEnt.VC_WDNT then PEnt.VC_WDNT = {} end if !PEnt.VC_WDET then PEnt.VC_WDET = {} end local WDEA = {["65"] = "wheeldirt", ["66"] = "wheeldirt", ["68"] = "wheeldust", ["70"] = "wheeldirt", ["72"] = "wheeldirt", ["78"] = "wheeldust", ["79"] = "wheeldirt", ["80"] = "wheeldirt", ["83"] = "wheeldirt", ["87"] = "wheeldirt"} for i=1, 4 do if PEnt:LookupAttachment(DEL[i]) != 0 then local WDT = util.TraceLine({start = PEnt:GetAttachment(PEnt:LookupAttachment(DEL[i])).Pos, endpos = PEnt:GetAttachment(PEnt:LookupAttachment(DEL[i])).Pos+ PEnt:GetUp()* -30, filter = PEnt}) if WDT.Hit and PEnt:GetVelocity():Length()- WDT.Entity:GetVelocity():Length() > 250 and PEnt:WaterLevel() < 3 and VecAboveWtr(PEnt:GetPos()+ PEnt:GetUp()* 40) then if PEnt.VC_WDNT[i] and (WDT.MatType != PEnt.VC_WDET[i] or PEnt.VC_WDPST[i].VC_WDTBNC and CurTime() >= PEnt.VC_WDPST[i].VC_WDTBNC) then PEnt.VC_WDPST[i]:Remove() table.remove(PEnt.VC_WDPST, i) table.remove(PEnt.VC_WDNT, i) table.remove(PEnt.VC_WDET, i) end if !table.HasValue(PEnt.VC_WDNT, DEL[i]) then local WDE = ents.Create("info_particle_system") WDE:SetKeyValue("effect_name", !VecAboveWtr(WDT.HitPos+ WDT.HitNormal) and "wheelsplash" or WDEA[tostring(WDT.MatType)] or "exhaust") WDE:SetAngles(PEnt:GetAngles()) WDE:SetPos(WDT.HitPos+ WDT.HitNormal) WDE:SetParent(PEnt) WDE:Spawn() WDE:Activate() WDE:Fire("Start") table.insert(PEnt.VC_WDPST, WDE) table.insert(PEnt.VC_WDNT, DEL[i]) table.insert(PEnt.VC_WDET, WDT.MatType) WDE.VC_WDTBNC = CurTime()+ 0.5 end else if PEnt.VC_WDNT[i] then PEnt.VC_WDPST[i]:Remove() table.remove(PEnt.VC_WDPST, i) table.remove(PEnt.VC_WDNT, i) table.remove(PEnt.VC_WDET, i) end end end end else if PEnt.VC_WDNT and #PEnt.VC_WDNT > 0 then for WDk, WDv in pairs(PEnt.VC_WDNT) do PEnt.VC_WDPST[WDk]:Remove() table.remove(PEnt.VC_WDPST, WDk) table.remove(PEnt.VC_WDNT, WDk) table.remove(PEnt.VC_WDET, WDk) end end end if tobool(VC_Wheel_Dust_Brakes) and (IsValid(PEnt:GetDriver()) and PEnt:GetDriver():KeyDown(IN_JUMP) or PEnt.VC_BrksOn and IsValid(PEnt.VC_Truck) and IsValid(PEnt.VC_Truck:GetDriver()) and PEnt.VC_Truck:GetDriver():KeyDown(IN_JUMP)) then if !PEnt.VC_WDPSTB then PEnt.VC_WDPSTB = {} end if !PEnt.VC_WDNTB then PEnt.VC_WDNTB = {} end for i=1, 4 do if PEnt:LookupAttachment(DEL[i]) != 0 then local WDT = util.TraceLine({start = PEnt:GetAttachment(PEnt:LookupAttachment(DEL[i])).Pos, endpos = PEnt:GetAttachment(PEnt:LookupAttachment(DEL[i])).Pos+ PEnt:GetUp()* -30, filter = PEnt}) if WDT.Hit and PEnt:GetVelocity():Length()- WDT.Entity:GetVelocity():Length() > 100 and VecAboveWtr(WDT.HitPos+ WDT.HitNormal) and PEnt:WaterLevel() < 3 then if !table.HasValue(PEnt.VC_WDNTB, DEL[i]) then local WDE = ents.Create("info_particle_system") WDE:SetKeyValue("effect_name", "wheeldust") WDE:SetAngles(PEnt:GetAngles()) WDE:SetPos(WDT.HitPos+ WDT.HitNormal) WDE:SetParent(PEnt) WDE:Spawn() WDE:Activate() WDE:Fire("Start") table.insert(PEnt.VC_WDPSTB, WDE) table.insert(PEnt.VC_WDNTB, DEL[i]) end else if PEnt.VC_WDNTB[i] then PEnt.VC_WDPSTB[i]:Remove() table.remove(PEnt.VC_WDPSTB, i) table.remove(PEnt.VC_WDNTB, i) end end end end else if PEnt.VC_WDNTB and #PEnt.VC_WDNTB > 0 then for WDk, WDv in pairs(PEnt.VC_WDNTB) do PEnt.VC_WDPSTB[WDk]:Remove() table.remove(PEnt.VC_WDPSTB, WDk) table.remove(PEnt.VC_WDNTB, WDk) end end end PEnt.VC_TBNWDC = CurTime()+ 0.1 end if PEnt.VehicleTable and PEnt.VehicleTable.VC_IsTrailer and PEnt.VehicleTable.VC_AttachPos then if tobool(VC_Trl_Truck_Brakes) and IsValid(PEnt.VC_Truck) and IsValid(PEnt.VC_Truck:GetDriver()) then if !PEnt.VC_BrksOn and PEnt.VC_Truck:GetDriver():KeyDown(IN_JUMP) then PEnt:Fire("HandBrakeOn") PEnt.VC_BrksOn = true elseif PEnt.VC_BrksOn and !PEnt.VC_Truck:GetDriver():KeyDown(IN_JUMP) then PEnt:Fire("HandBrakeOff") PEnt.VC_BrksOn = false end end if tobool(VC_Trl_Crash_Brakes) and !IsValid(PEnt.VC_Truck) and !PEnt.VC_BrksOn then PEnt:Fire("HandBrakeOn") PEnt.VC_BrksOn = true end if tobool(VC_Trl_Auto_Attach) and (!PEnt.VC_AttachT or CurTime() >= PEnt.VC_AttachT) then for _,trk in pairs(Ents_All) do if trk:IsVehicle() and (!trk.VC_AttachT or CurTime() >= trk.VC_AttachT) and trk.VehicleTable and !trk.VehicleTable.VC_IsTrailer and trk.VehicleTable.VC_AttachPos then local TrlAP, TrkAP = AttachVecCalc(PEnt.VehicleTable.VC_AttachPos, PEnt), AttachVecCalc(trk.VehicleTable.VC_AttachPos, trk) trk.VC_AttachT = nil if TrkAP:Distance(TrlAP) <= math.Clamp(VC_Trl_Attach_Distance,15,300) and (!trk.VC_Health or trk.VC_Health > 0) then if !IsValid(PEnt.VC_Truck) and !IsValid(trk.VC_Trailer) then local TrlVel, TrkVel = PEnt:GetPhysicsObject():GetVelocity(), trk:GetPhysicsObject():GetVelocity() if TrlVel:Length() < TrkVel:Length()+10 and TrlVel:Length() > TrkVel:Length()-10 and !util.TraceLine({start = TrlAP, endpos = TrkAP, filter = {PEnt, trk}}).Hit then if IsValid(trk:GetDriver()) then trk:GetDriver().VC_PATBA = CurTime()+0.1 end trk.VC_Trailer = PEnt PEnt.VC_Truck = trk PEnt:SetPos(PEnt:GetPos()+ (TrkAP-TrlAP)) PEnt:GetPhysicsObject():AddAngleVelocity(trk:GetPhysicsObject():GetAngleVelocity()/(-5)) PEnt:GetPhysicsObject():Wake() PEnt:GetPhysicsObject():SetVelocity((TrlVel+ TrkVel)/2) if PEnt.VC_BrksOn and !tobool(VC_Trl_Truck_Brakes) and tobool(VC_Trl_Brakes_Enter_Exit) then PEnt:Fire("HandBrakeOff") PEnt.VC_BrksOn = false end end end else if trk.VC_Trailer and trk.VC_Trailer == PEnt then trk.VC_Trailer = nil end if PEnt.VC_Truck and PEnt.VC_Truck == trk then PEnt.VC_Truck = nil end end end end PEnt.VC_AttachT = CurTime()+ math.Rand(0.08,0.12) end end elseif PEnt:IsPlayer() then if tobool(VC_Passenger_Seats) then if PEnt.VC_ChnSts and !IsValid(PEnt:GetVehicle()) then PEnt.VC_ChnSts = false end if PEnt.VC_JEAES and !PEnt:KeyDown(IN_USE) then PEnt.VC_JEAES = nil end end end end end) function VC_NormalLightsOn(ent) if !ent.VC_NormalLightsOn and ent.VC_HasNormalLights then EmitSoundTS(ent, "buttons/lightswitch2.wav", 105) ent.VC_NormalLightsOn = true end end function VC_NormalLightsOff(ent) if ent.VC_NormalLightsOn and ent.VC_HasNormalLights then EmitSoundTS(ent, "buttons/lightswitch2.wav", 95) ent.VC_NormalLightsOn = false end end function VC_HeadLightsOn(ent) if !ent.VC_HeadLightsOn and ent.VC_HasHeadLights then EmitSoundTS(ent, "buttons/lightswitch2.wav", 105) ent.VC_HeadLightsOn = true end end function VC_HeadLightsOff(ent) if ent.VC_HeadLightsOn and ent.VC_HasHeadLights then EmitSoundTS(ent, "buttons/lightswitch2.wav", 95) ent.VC_HeadLightsOn = false end end function VC_HazardLightsOn(ent) if !ent.VC_HazardLightsOn and ent.VC_HasBlinkerLights then ent.VC_Blinker_Right_On = false ent.VC_Blinker_Left_On = false ent.VC_HazardLightsOn = true ent:SetNWBool("VC_HazardLightsOn", true) EmitSoundTS(ent, "buttons/lightswitch2.wav", 105) end end function VC_HazardLightsOff(ent) if ent.VC_HazardLightsOn and ent.VC_HasBlinkerLights then ent.VC_HazardLightsOn = false ent:SetNWBool("VC_HazardLightsOn", false) EmitSoundTS(ent, "buttons/lightswitch2.wav", 95) end end for i=1, 8 do concommand.Add("VC_Switch_Seats_"..tostring(i+1), function(ply) if VC_Enabled and IsValid(ply:GetVehicle()) and (ply:GetVehicle().VC_SeatTable or ply:GetVehicle().VC_ExtraSeat) and (!ply.VC_ChgST or CurTime() >= ply.VC_ChgST) and !(IsValid(ply.VC_HangingOutSeat) and IsValid(ply.VC_HangingOutSeat.VC_HangingOutPlayer) and ply == ply.VC_HangingOutSeat.VC_HangingOutPlayer) then local Seat = (ply:GetVehicle().VC_ExtraSeat and ply:GetVehicle():GetParent().VC_SeatTable or ply:GetVehicle().VC_SeatTable)[i] if IsValid(Seat) and Seat != ply:GetVehicle() and !IsValid(Seat:GetDriver()) then local ACA = Seat:WorldToLocalAngles(ply:EyeAngles()) ACA.r = 0 ply.VC_ChgST = CurTime()+ 0.2 ply.VC_ChnSts = true ply:ExitVehicle() ply.VC_CanEnterTime = nil ply:EnterVehicle(Seat) ply:SetEyeAngles(ACA) end end end) end concommand.Add("VC_Trailer_Detach", function(ply) if VC_Enabled and ply:InVehicle() and IsValid(ply:GetVehicle().VC_Trailer) then local vel, avel = ply:GetVehicle().VC_Trailer:GetPhysicsObject():GetVelocity(), ply:GetVehicle().VC_Trailer:GetPhysicsObject():GetAngleVelocity() EmitSoundTS(ply:GetVehicle(), "buttons/lightswitch2.wav", 100) ply:GetVehicle().VC_Trailer:SetAngles(ply:GetVehicle().VC_Trailer:GetAngles()+ Angle(0,0,2)) ply:GetVehicle().VC_Trailer:SetPos(ply:GetVehicle().VC_Trailer:GetPos()+ ply:GetVehicle():GetUp()* 10- ply:GetVehicle():GetForward()* 4) ply:GetVehicle().VC_Trailer:GetPhysicsObject():SetVelocity(vel) ply:GetVehicle().VC_Trailer:GetPhysicsObject():AddAngleVelocity(ply:GetVehicle().VC_Trailer:GetPhysicsObject():GetAngleVelocity()*(-1)+avel) ply:GetVehicle().VC_Trailer.VC_AttachT = CurTime()+ 5 ply:GetVehicle().VC_AttachT = CurTime()+ 5 if tobool(VC_Trl_Truck_Brakes) and !ply:GetVehicle().VC_Trailer.VC_BrksOn then ply:GetVehicle().VC_Trailer:Fire("HandBrakeOn") ply:GetVehicle().VC_Trailer.VC_BrksOn = true end ply:GetVehicle().VC_Trailer.VC_Truck = nil ply:GetVehicle().VC_Trailer = nil end end) concommand.Add("VC_Radio_Change", function(ply, cmd, arg) if VC_Enabled and tobool(VC_Radio) then local veh = ply:GetVehicle() if IsValid(veh) then local veh, TCnt, Bk = veh.VC_ExtraSeat and veh:GetParent() or veh, table.Count(util.KeyValuesToTable(file.Read("VehController/Radio.txt"))), arg[1] if (!veh.VC_RadTmr or CurTime() >= veh.VC_RadTmr) and (!veh.VehicleTable or !veh.VehicleTable.VC_NoRadio) and (!ply:GetVehicle().VC_ExtraSeat or ply:GetVehicle().VC_RCntrl) and EngAboveWtr(veh) and (string.lower(ply:GetVehicle():GetClass()) != "prop_vehicle_prisoner_pod" or ply:GetVehicle().VC_ExtraSeat) then veh.VC_RadStn = veh.VC_RadStn or 0 if !Bk and veh.VC_RadStn < TCnt or Bk and veh.VC_RadStn > 0 then veh.VC_RadStn = (veh.VC_RadStn or 0)+ (Bk and -1 or 1) elseif Bk and veh.VC_RadStn <= 0 then veh.VC_RadStn = TCnt elseif !Bk and veh.VC_RadStn >= TCnt then veh.VC_RadStn = 0 end EmitSoundTS(ply:GetVehicle(), "buttons/lightswitch2.wav", veh.VC_RadStn == 0 and 95 or 105) veh:SetNWInt("VC_RadStn", veh.VC_RadStn) veh.VC_RadTmr = CurTime()+ 1 end end end end) concommand.Add("VC_Horn_OnOff", function(ply, cmd, arg) if VC_Enabled then local veh, AG = ply:GetVehicle(), arg[1] if IsValid(veh) and (veh:GetClass() == "prop_vehicle_jeep" or veh:GetClass() == "prop_vehicle_jeep_old") and (!veh.VC_HornOn or tonumber(AG) == 1) and (!AG or tonumber(AG) != 2) and (!veh.VC_Health or veh.VC_Health > 0) and EngAboveWtr(veh) then if !veh.VC_HornSnd then veh.VC_HornSnd = CreateSound(veh, VC_Horn.Sound or "vehicles/vc_horn_light.wav") veh.VC_HornLp = VC_Horn.Looping end if !veh.VC_HornStm or CurTime() >= veh.VC_HornStm- SoundDuration(VC_Horn.Sound)/4 then veh.VC_HornSnd:Stop() veh.VC_HornSnd:Play() veh.VC_HornSnd:ChangePitch(math.Clamp(GetConVarNumber("host_timescale")*(VC_Horn.Pitch or 100),1,255),0.1) veh.VC_HornStm = CurTime()+ SoundDuration(VC_Horn.Sound) end if !AG then veh.VC_HornCSE = true else veh.VC_HornCSE = nil end veh.VC_HornOn = true veh.VC_HornSnd:ChangeVolume(1,0.1) veh.VC_HornVL = nil elseif tonumber(AG) == 2 then veh.VC_HornVL = 1 end end end) concommand.Add("VC_Blinkers_OnOff", function(ply) if VC_Enabled and IsValid(ply:GetVehicle()) and !ply:GetVehicle().VC_HazardLightsOn and (!ply.VC_CmdTmr or CurTime() >= ply.VC_CmdTmr) and (ply:GetVehicle().VehicleTable and ply:GetVehicle().VehicleTable.VC_Lights or IsValid(ply:GetVehicle().VC_Trailer) and ply:GetVehicle().VC_Trailer.VehicleTable and ply:GetVehicle().VC_Trailer.VehicleTable.VC_Lights) then local TCE = false for _, Lt in pairs(ply:GetVehicle().VehicleTable.VC_Lights) do if Lt.BlinkersColor then TCE = true break end end if !TCE and IsValid(ply:GetVehicle().VC_Trailer) then for _, Lt in pairs(ply:GetVehicle().VC_Trailer.VehicleTable.VC_Lights) do if Lt.BlinkersColor then TCE = true break end end end if TCE and (ply:KeyDown(IN_MOVELEFT) or ply:KeyDown(IN_MOVERIGHT)) then if !ply:GetVehicle().VC_TurnLOn then ply:GetVehicle().VC_TurnLOn = true EmitSoundTS(ply:GetVehicle(), "buttons/lightswitch2.wav", 105) else ply:GetVehicle().VC_TurnLOn = false end ply.VC_CmdTmr = CurTime()+ 0.1 end end end) concommand.Add("VC_Hazards_OnOff", function(ply) if VC_Enabled and IsValid(ply:GetVehicle()) and (!ply.VC_CmdTmr or CurTime() >= ply.VC_CmdTmr) and ply:GetVehicle().VC_HasBlinkerLights then if !ply:GetVehicle().VC_HazardLightsOn then VC_HazardLightsOn(ply:GetVehicle()) else VC_HazardLightsOff(ply:GetVehicle()) end ply.VC_CmdTmr = CurTime()+ 0.1 end end) concommand.Add("VC_Lights_OnOff", function(ply) if VC_Enabled and (!ply.VC_CmdTmr or CurTime() >= ply.VC_CmdTmr) and ply:GetVehicle().VC_HasNormalLights then if !ply:GetVehicle().VC_NormalLightsOn then VC_NormalLightsOn(ply:GetVehicle()) else VC_NormalLightsOff(ply:GetVehicle()) end ply.VC_CmdTmr = CurTime()+ 0.1 end end) concommand.Add("VC_Headlights_OnOff", function(ply) if VC_Enabled and IsValid(ply:GetVehicle()) and (!ply.VC_CmdTmr or CurTime() >= ply.VC_CmdTmr) and ply:GetVehicle().VC_HasHeadLights then if !ply:GetVehicle().VC_HeadLightsOn then VC_HeadLightsOn(ply:GetVehicle()) else VC_HeadLightsOff(ply:GetVehicle()) end ply.VC_CmdTmr = CurTime()+ 0.1 end end) concommand.Add("VC_Switch_Seats", function(ply) if VC_Enabled and tobool(VC_Passenger_Seats) and IsValid(ply:GetVehicle()) and (!ply.VC_ChgST or CurTime() >= ply.VC_ChgST) and !(IsValid(ply.VC_HangingOutSeat) and IsValid(ply.VC_HangingOutSeat.VC_HangingOutPlayer) and ply == ply.VC_HangingOutSeat.VC_HangingOutPlayer) then local MVeh = ply:GetVehicle().VC_ExtraSeat and ply:GetVehicle():GetParent() or ply:GetVehicle() local STbl = table.Add({MVeh}, table.Copy(MVeh.VC_SeatTable)) local SeatCount = table.Count(STbl) if table.Count(STbl) > 1 then local Seatk = 1 if MVeh != ply:GetVehicle() then for Stk, Stv in pairs(MVeh.VC_SeatTable) do if ply:GetVehicle() == Stv then Seatk = Stk+1 break end end end local SortedSeatTable = {} for Stk, Stv in pairs(STbl) do local SeatNum = Stk+Seatk if SeatNum > SeatCount then SeatNum = SeatNum-SeatCount end table.insert(SortedSeatTable, STbl[SeatNum]) end for Seatk, Seat in pairs(SortedSeatTable) do if !IsValid(Seat:GetDriver()) and !Seat.VC_AI_Driver then ply.VC_ChnSts = true ply.VC_SeatRCN = true local ACA = Seat:WorldToLocalAngles(ply:EyeAngles()) ACA.r = 0 ply:ExitVehicle() ply.VC_CanEnterTime = nil ply:EnterVehicle(Seat) ply:SetEyeAngles(ACA) ply.VC_ChnSts = false break end end end ply.VC_ChgST = CurTime()+ 0.5 end end) concommand.Add("VC_Siren_Sound_OnOff", function(ply) if VC_Enabled and (!ply.VC_CmdTmr or CurTime() >= ply.VC_CmdTmr) and IsValid(ply:GetVehicle()) and ply:GetVehicle().VehicleTable and ply:GetVehicle().VehicleTable.VC_Siren then if !ply:GetVehicle().VC_SSOff then ply:GetVehicle().VC_SSOff = true EmitSoundTS(ply:GetVehicle(), "buttons/lightswitch2.wav", 95) else ply:GetVehicle().VC_SSOff = false EmitSoundTS(ply:GetVehicle(), "buttons/lightswitch2.wav", 105) end ply.VC_CmdTmr = CurTime()+ 0.1 end end) concommand.Add("VC_Blinker_Left_Toggle", function(ply) if VC_Enabled and IsValid(ply:GetVehicle()) and (!ply.VC_CmdTmr or CurTime() >= ply.VC_CmdTmr) and string.lower(ply:GetVehicle():GetClass()) != "prop_vehicle_prisoner_pod" and !ply:GetVehicle().VC_HazardLightsOn and ply:GetVehicle().VC_HasBlinkerLights then if ply:GetVehicle().VC_Blinker_Left_On then ply:GetVehicle().VC_Blinker_Right_On = false ply:GetVehicle().VC_Blinker_Left_On = false EmitSoundTS(ply:GetVehicle(), "buttons/lightswitch2.wav", 95) else ply:GetVehicle().VC_Blinker_Right_On = false ply:GetVehicle().VC_Blinker_Left_On = true EmitSoundTS(ply:GetVehicle(), "buttons/lightswitch2.wav", 105) end ply.VC_CmdTmr = CurTime()+ 0.1 end end) concommand.Add("VC_Blinker_Right_Toggle", function(ply) if VC_Enabled and IsValid(ply:GetVehicle()) and (!ply.VC_CmdTmr or CurTime() >= ply.VC_CmdTmr) and string.lower(ply:GetVehicle():GetClass()) != "prop_vehicle_prisoner_pod" and !ply:GetVehicle().VC_HazardLightsOn and ply:GetVehicle().VC_HasBlinkerLights then if ply:GetVehicle().VC_Blinker_Right_On then ply:GetVehicle().VC_Blinker_Right_On = false ply:GetVehicle().VC_Blinker_Left_On = false EmitSoundTS(ply:GetVehicle(), "buttons/lightswitch2.wav", 95) else ply:GetVehicle().VC_Blinker_Right_On = true ply:GetVehicle().VC_Blinker_Left_On = false EmitSoundTS(ply:GetVehicle(), "buttons/lightswitch2.wav", 105) end ply.VC_CmdTmr = CurTime()+ 0.1 end end) concommand.Add("VC_Cruise_OnOff", function(ply) if VC_Enabled and IsValid(ply:GetVehicle()) and (!ply.VC_CmdTmr or CurTime() >= ply.VC_CmdTmr) and string.lower(ply:GetVehicle():GetClass()) != "prop_vehicle_prisoner_pod" then if ply:GetVehicle().VC_Cruise then ply:GetVehicle().VC_Cruise = false EmitSoundTS(ply:GetVehicle(), "buttons/lightswitch2.wav", 95) else ply:GetVehicle().VC_Cruise = true EmitSoundTS(ply:GetVehicle(), "buttons/lightswitch2.wav", 105) end ply.VC_CmdTmr = CurTime()+ 0.1 end end) concommand.Add("VC_Repair", function(ply) if VC_Enabled and tobool(VC_Exit_NoCollision) and IsValid(ply:GetVehicle()) and (!ply:GetVehicle().VC_FixTmr or CurTime() >= ply:GetVehicle().VC_FixTmr) and ply:GetVehicle().VC_Health < ply:GetVehicle().VC_MaxHealth then ply:GetVehicle().VC_Health = ply:GetVehicle().VC_MaxHealth EmitSoundTS(ply:GetVehicle(), "vehicles/vc_repair.wav", 95) end end) concommand.Add("VC_Switch_Seats_1", function(ply) if VC_Enabled and IsValid(ply:GetVehicle()) and ply:GetVehicle().VC_ExtraSeat and (!ply.VC_ChgST or CurTime() >= ply.VC_ChgST) and !(IsValid(ply.VC_HangingOutSeat) and IsValid(ply.VC_HangingOutSeat.VC_HangingOutPlayer) and ply == ply.VC_HangingOutSeat.VC_HangingOutPlayer)then local Seat = ply:GetVehicle():GetParent() if Seat != ply:GetVehicle() and !IsValid(Seat:GetDriver()) then ply.VC_ChnSts = true local ACA = Seat:WorldToLocalAngles(ply:EyeAngles()) ACA.r = 0 ply:ExitVehicle() ply.VC_CanEnterTime = nil ply:EnterVehicle(Seat) ply:SetEyeAngles(ACA) end end end) function VC_CheckLights(ent) if ent.VehicleTable then ent.VC_LightTable = {} if ent.VehicleTable.VC_Lights then for Lhtk, Lt in pairs(ent.VehicleTable.VC_Lights) do if Lt.BrakeColor then if !ent.VC_LightTable.Brake then ent.VC_LightTable.Brake = {} end ent.VC_LightTable.Brake[Lhtk] = Lt end if Lt.ReverseColor then if !ent.VC_LightTable.Reverse then ent.VC_LightTable.Reverse = {} end ent.VC_LightTable.Reverse[Lhtk] = Lt end if Lt.HeadLightAngle then if !ent.VC_LightTable.Head then ent.VC_LightTable.Head = {} end ent.VC_LightTable.Head[Lhtk] = Lt end if Lt.NormalColor then if !ent.VC_LightTable.Normal then ent.VC_LightTable.Normal = {} end ent.VC_LightTable.Normal[Lhtk] = Lt end if Lt.BlinkersColor then if !ent.VC_LightTable.Blinker then ent.VC_LightTable.Blinker = {} end ent.VC_LightTable.Blinker[Lhtk] = Lt end if Lt.SirenColor then if !ent.VC_LightTable.Siren then ent.VC_LightTable.Siren = {} end ent.VC_LightTable.Siren[Lhtk] = Lt end end end end end