local k=game:GetService("\082\117\110\083\101\114\118\105\099\101")local t=game:GetService("\083\101\114\118\101\114\083\099\114\105\112\116\083\101\114\118\105\099\101")local Z=require(script.Parent:WaitForChild("\069\120\078\105\104\105\108\111",2))local F=(t:WaitForChild("\067\111\109\112\111\110\101\110\116\115",5)):WaitForChild("\069\108\115",2)local D=require(F:FindFirstChild("\069\108\115\072\117\100"))local J=game:GetService("\082\101\112\108\105\099\097\116\101\100\083\116\111\114\097\103\101")local u=require(J:WaitForChild("\078\101\118\101\114\109\111\114\101",2))local m=u("\083\116\100")local a=m.rquery local A={}function A.__setVehicleNetworkOwnershipToPlayer(k,t)for k,Z in pairs(k:GetDescendants())do if Z:IsA("\066\097\115\101\080\097\114\116")then Z:SetNetworkOwner(t)end end end function A.__attachGuiToVehicleSeatOccupant(k,t)if k~=nil and t~=nil then local Z=((J:WaitForChild("\069\113\117\105\112\109\101\110\116",2)):WaitForChild("\067\104\097\115\115\105\115\076\111\099\097\108")):Clone()if Z:FindFirstChild("\079\098\106\101\099\116")==nil then local k=Instance.new("\079\098\106\101\099\116\086\097\108\117\101")k.Name="\079\098\106\101\099\116"k.Parent=Z end Z.Object.Value=k Z.Parent=t.PlayerGui Z.Disabled=false end end function A._attachVehicleSeatHandlers(k)local t=k:WaitForChild("\086\101\104\105\099\108\101\083\101\097\116")local Z=function(t)if t=="\079\099\099\117\112\097\110\116"and a.GetPlayerDrivingVehicle(k)~=nil then local t=a.GetPlayerDrivingVehicle(k)A.__attachGuiToVehicleSeatOccupant(k,t)A.__setVehicleNetworkOwnershipToPlayer(k,t)end end t.Changed:Connect(Z)end function A._weldVehicleTogether(k)local t=k:WaitForChild("\086\101\104\105\099\108\101\083\101\097\116")local Z=k:WaitForChild("\069\110\103\105\110\101")local F=k:WaitForChild("\083\116\097\116\115")local D=k:WaitForChild("\067\111\110\115\116\114\097\105\110\116\115")local J=Instance.new("\070\111\108\100\101\114")J.Name="\087\101\108\100\115"J.Parent=Z local u=Instance.new("\087\101\108\100\067\111\110\115\116\114\097\105\110\116")u.Part0=Z u.Part1=t u.Parent=J for k,t in next,k:GetDescendants()do if t.Name=="\072\111\108\100\101\114"then local k=Instance.new("\087\101\108\100\067\111\110\115\116\114\097\105\110\116")k.Part0=Z k.Part1=t k.Parent=J end end for k,t in next,k.Body:GetDescendants()do if t:IsA("\066\097\115\101\080\097\114\116")then local k=Instance.new("\087\101\108\100\067\111\110\115\116\114\097\105\110\116")k.Part0=Z k.Part1=t k.Parent=J t.CustomPhysicalProperties=PhysicalProperties.new(0,0,0,0,0)end end for k,t in next,k:GetDescendants()do if t.Parent.Name=="\087\104\101\101\108"and t:IsA("\066\097\115\101\080\097\114\116")then local k=Instance.new("\087\101\108\100\067\111\110\115\116\114\097\105\110\116")k.Part0=t.Parent k.Part1=t k.Parent=J t.CanCollide=false t.CustomPhysicalProperties=PhysicalProperties.new(0,0,0,0,0)end end for k,t in next,k:GetDescendants()do if t:IsA("\066\097\115\101\080\097\114\116")then t.Anchored=false end end end function A._setConstraints(t)k.Heartbeat:Connect(function()local k=t:WaitForChild("\083\116\097\116\115")local Z=t:WaitForChild("\067\111\110\115\116\114\097\105\110\116\115")for t,Z in next,Z:GetDescendants()do if Z:IsA("\072\105\110\103\101\067\111\110\115\116\114\097\105\110\116")then Z.MotorMaxTorque=k.Torque.Value Z.AngularSpeed=k.TurnSpeed.Value end end for t,Z in next,Z:GetChildren()do if Z:IsA("\083\112\114\105\110\103\067\111\110\115\116\114\097\105\110\116")then Z.FreeLength=k.Height.Value end end for t,Z in next,Z:GetChildren()do if Z:IsA("\080\114\105\115\109\097\116\105\099\067\111\110\115\116\114\097\105\110\116")then Z.UpperLimit=-k.Height.Value end end if not t.VehicleSeat.Occupant then for k,t in pairs(t:GetDescendants())do if t:IsA("\066\097\115\101\080\097\114\116")then t:SetNetworkOwner(nil)end end end end)end function A.WireUpVehicleScripts(k)A._weldVehicleTogether(k)A._attachVehicleSeatHandlers(k)A._setConstraints(k)D:TryExecute(k)end function A.CreateVehicleFromServerStorage(k,t)local F=function(k)A.WireUpVehicleScripts(k)print("\086\101\104\105\099\108\101 \115\099\114\105\112\116\115 \119\105\114\101\100 \117\112 \121\111")end return Z.CreateFromServerStorage("\086\101\104\105\099\108\101\115",k,t,F)end return A

local RunService = game:GetService("RunService")
local ServerScriptService = game:GetService("ServerScriptService")

local exNihilo = require(script.Parent:WaitForChild("ExNihilo", 2))

local elsComponents = ServerScriptService:WaitForChild("Components", 5):WaitForChild("Els", 2)
local elsHud = require(elsComponents:FindFirstChild("ElsHud"))

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local require = require(ReplicatedStorage:WaitForChild("Nevermore", 2))
local std = require("Std")
local rq = std.rquery

local module = {}

function module.__setVehicleNetworkOwnershipToPlayer(vehicleModel, occupantPlayer)
    for i, v in pairs(vehicleModel:GetDescendants()) do
        if v:IsA("BasePart") then
            v:SetNetworkOwner(occupantPlayer)
        end
    end
end

function module.__attachGuiToVehicleSeatOccupant(vehicleModel, occupantPlayer)

    if vehicleModel ~= nil and occupantPlayer ~= nil then
        local ChassisLocal = ReplicatedStorage:WaitForChild("Equipment", 2):WaitForChild("ChassisLocal"):Clone()

        if ChassisLocal:FindFirstChild("Object") == nil then
            local objInstance = Instance.new("ObjectValue")
            objInstance.Name = "Object"
            objInstance.Parent = ChassisLocal
        end

        ChassisLocal.Object.Value = vehicleModel
        ChassisLocal.Parent = occupantPlayer.PlayerGui
        ChassisLocal.Disabled = false
    end
end

function module._attachVehicleSeatHandlers(vehicleModel)
    local vehicleSeat = vehicleModel:WaitForChild("VehicleSeat")
    local seatOccupantChangedHandler = function(changedProperty)
        if changedProperty == "Occupant" and rq.GetPlayerDrivingVehicle(vehicleModel) ~= nil then
            local occupantPlayer = rq.GetPlayerDrivingVehicle(vehicleModel)
            module.__attachGuiToVehicleSeatOccupant(vehicleModel, occupantPlayer)

            module.__setVehicleNetworkOwnershipToPlayer(vehicleModel, occupantPlayer)
        end
    end
    vehicleSeat.Changed:Connect(seatOccupantChangedHandler)
end

function module._weldVehicleTogether(vehicleModel)
    local vehicleSeat = vehicleModel:WaitForChild("VehicleSeat")
    local engine = vehicleModel:WaitForChild("Engine")
    local stats = vehicleModel:WaitForChild("Stats")
    local constraints = vehicleModel:WaitForChild("Constraints")

    local Welds = Instance.new("Folder")
    Welds.Name = ("Welds")
    Welds.Parent = engine

    local SeatWeld = Instance.new("WeldConstraint")
    SeatWeld.Part0 = engine
    SeatWeld.Part1 = vehicleSeat
    SeatWeld.Parent = Welds

    for i , v in next, vehicleModel:GetDescendants() do
        if v.Name == "Holder" then
            local WeldConstraint = Instance.new("WeldConstraint")
            WeldConstraint.Part0 = engine
            WeldConstraint.Part1 = v
            WeldConstraint.Parent = Welds
        end
    end

    for i , v in next, vehicleModel.Body:GetDescendants() do
        if v:IsA("BasePart") then
            local WeldConstraint = Instance.new("WeldConstraint")
            WeldConstraint.Part0 = engine
            WeldConstraint.Part1 = v
            WeldConstraint.Parent = Welds
            v.CustomPhysicalProperties = PhysicalProperties.new(0 , 0 , 0 , 0 , 0)
        end
    end

    for i , v in next, vehicleModel:GetDescendants() do
        if v.Parent.Name == "Wheel" and v:IsA("BasePart") then
        local WeldConstraint = Instance.new("WeldConstraint")
        WeldConstraint.Part0 = v.Parent
        WeldConstraint.Part1 = v
        WeldConstraint.Parent = Welds
        v.CanCollide = false
        v.CustomPhysicalProperties = PhysicalProperties.new(0 , 0 , 0 , 0 , 0)
        end
    end
	
    for i, v in next, (vehicleModel:GetDescendants()) do
        if v:IsA("BasePart") then
        v.Anchored = false
        end
    end

end

function module._setConstraints(vehicleModel)

    RunService.Heartbeat:Connect(function()

        local stats = vehicleModel:WaitForChild("Stats")
        local constraints = vehicleModel:WaitForChild("Constraints")
        for i , v in next, constraints:GetDescendants() do
            if v:IsA("HingeConstraint") then
               v.MotorMaxTorque = stats.Torque.Value
               v.AngularSpeed = stats.TurnSpeed.Value
            end
         end
         for i , v in next, constraints:GetChildren() do
            if v:IsA("SpringConstraint") then
               v.FreeLength = stats.Height.Value
            end
         end
         for i , v in next, constraints:GetChildren() do
            if v:IsA("PrismaticConstraint") then
               v.UpperLimit = -stats.Height.Value
            end
         end
        
        if not vehicleModel.VehicleSeat.Occupant then
           for i, v in pairs(vehicleModel:GetDescendants()) do
               if v:IsA("BasePart") then
                  v:SetNetworkOwner(nil)
               end
           end
        end
    end)
end

function module.WireUpVehicleScripts(vehicleModel)
    module._weldVehicleTogether(vehicleModel)
    module._attachVehicleSeatHandlers(vehicleModel)
    module._setConstraints(vehicleModel)
    elsHud:TryExecute(vehicleModel)
end

function module.CreateVehicleFromServerStorage( prototypeId, creationLocation )
    
    local createdModelCallback = function(createdModel)
        module.WireUpVehicleScripts(createdModel)
        print("Vehicle scripts wired up yo")
    end

    return exNihilo.CreateFromServerStorage( "Vehicles", prototypeId, creationLocation, createdModelCallback )

end

return module
