--script version 5.0.4     https://steamcommunity.com/sharedfiles/filedetails/?id=3009223120
doorvolume = 0.4
beep = GetBoolParam("chime")
trunklift = GetBoolParam("trunklift")
hoodlift = GetBoolParam("hoodlift")
sounddir = GetStringParam("sounddir")
chimevar = GetStringParam("chimevar")
smoothInteriorLight = GetBoolParam("smoothIntLight")
function init()
    doors = FindShapes("door")
    hood = FindShape("hood")
    trunk = FindShape("trunk")
    trunk_down = FindShape("trunk_down")
    steer = FindShape("steer")
    spoiler = FindShape("spoiler")
    intlights = FindShapes("interiorlight")
    for i = 1, #intlights do
        SetTag(intlights[i], "interact", "Mode: Active")
    end
    vehicle = FindVehicle("EVF")
    if not IsHandleValid(vehicle) then
        vehicle = FindVehicle("vehicle")
    end
    vehicle_body = GetVehicleBody(vehicle)
    vehicle_body_shape = GetBodyShapes(vehicle_body)[1]
    if sounddir == "" then
        sounddir = "MOD/EVF/snd"
    end
    if chimevar == "" then
        doorchime = LoadLoop(sounddir .. "/chime1.ogg")
    else
        doorchime = LoadLoop(sounddir .. "/chime" .. chimevar .. ".ogg")
    end
    door_o1 = LoadSound(sounddir .. "/door_o1.ogg")
    door_o2 = LoadSound(sounddir .. "/door_o2.ogg")
    door_c = LoadSound(sounddir .. "/door_c.ogg")
    hood_o = LoadSound(sounddir .. "/hood_o.ogg")
    hood_o1 = LoadSound(sounddir .. "/hood_o1.ogg")
    hood_c = LoadSound(sounddir .. "/hood_c.ogg")
    trunk_o1 = LoadSound(sounddir .. "/trunk_o1.ogg")
    trunk_o2 = LoadSound(sounddir .. "/trunk_o2.ogg")
    trunk_c = LoadSound(sounddir .. "/trunk_c.ogg")
    hood_lift_loop = LoadLoop(sounddir .. "/hood_lift_loop.ogg")
    lightclicksound = LoadSound(sounddir .. "/click.ogg")
    doorjoint = {}
    playeddoor = {}
    playedhood = {}
    smoothLightValue = 0
    if vehicle ~= 0 then
        for i = 1, #doors do
            local index = 1
            doorjoint[i] = GetShapeJoints(doors[i])[index]
            while GetJointOtherShape(doorjoint[i], doors[i]) ~= vehicle_body_shape do
                index = index + 1
                doorjoint[i] = GetShapeJoints(doors[i])[index]
            end
            playeddoor[i] = {
                ["played1o"] = false,
                ["played2o"] = true,
                ["playedc"] = true,
                ["open"] = false
            }
        end
        if IsHandleValid(hood) then
            local index = 1
            hoodjoint = GetShapeJoints(hood)[index]
            while GetJointOtherShape(hoodjoint, hood) ~= vehicle_body_shape do
                index = index + 1
                hoodjoint = GetShapeJoints(hood)[index]
            end
            playedhood[1] = {
                ["played1o"] = false,
                ["played2o"] = true,
                ["played3o"] = true,
                ["playedc"] = true,
                ["open"] = false
            }
        end
        if IsHandleValid(trunk) then
            local index = 1
            trunkjoint = GetShapeJoints(trunk)[index]
            while GetJointOtherShape(trunkjoint, trunk) ~= vehicle_body_shape do
                index = index + 1
                trunkjoint = GetShapeJoints(trunk)[index]
            end
            playedhood[2] = {
                ["played1o"] = false,
                ["played2o"] = true,
                ["played3o"] = true,
                ["playedc"] = true,
                ["open"] = false
            }
        end
        if IsHandleValid(trunk_down) then
            local index = 1
            trunk_down_joint = GetShapeJoints(trunk_down)[index]
            while GetJointOtherShape(trunk_down_joint, trunk_down) ~= vehicle_body_shape do
                index = index + 1
                trunk_down_joint = GetShapeJoints(trunk_down)[index]
            end
            playedhood[3] = {
                ["played1o"] = false,
                ["played2o"] = true,
                ["played3o"] = true,
                ["playedc"] = true,
                ["open"] = false
            }
        end
        if IsHandleValid(spoiler) then
            local index = 1
            spoilerjoint = GetShapeJoints(spoiler)[index]
            while GetJointOtherShape(spoilerjoint, spoiler) ~= vehicle_body_shape do
                index = index + 1
                spoilerjoint = GetShapeJoints(spoiler)[index]
            end
            spmin, spmax = GetJointLimits(spoilerjoint)
        end
        if IsHandleValid(steer) then
            steerjoint = GetShapeJoints(steer)[1]
        end
    else 
        DebugPrint("Vehicle node with tag 'EVF' is not found!")
    end
    grabshape = GetPlayerGrabShape()
    grabbody = GetPlayerGrabBody()
end

function doorlatchsystem(shape, joint, ID)
    if not IsJointBroken(joint) then
        local jointmovement = GetJointMovement(joint)
        local body1 = GetShapeBody(shape)
        local pos = GetShapeWorldTransform(shape).pos
        if not IsJointBroken(joint) then
            if grabshape == shape or grabbody == body1 then
                SetJointMotor(joint, 0, 0)
                if not playeddoor[ID]["played1o"] and jointmovement >= 0.06 then
                    playeddoor[ID]["played1o"] = true
                    playeddoor[ID]["played2o"] = false
                    if HasTag(shape, "AltOpen1Sound") then
                        PlaySound(LoadSound(GetTagValue(shape, "AltOpen1Sound")), pos, doorvolume)
                    else
                        PlaySound(door_o1, pos, doorvolume)
                    end
                end
            else
                if not playeddoor[ID]["played2o"] then
                    playeddoor[ID]["played2o"] = true
                    playeddoor[ID]["playedc"] = false
                    if HasTag(shape, "AltOpen2Sound") then
                        PlaySound(LoadSound(GetTagValue(shape, "AltOpen2Sound")), pos, doorvolume)
                    else
                        PlaySound(door_o2, pos, doorvolume)
                    end
                end
                if jointmovement <= 0.18 then
                    SetJointMotorTarget(joint, 0)
                    if not playeddoor[ID]["playedc"] then
                        playeddoor[ID]["playedc"] = true
                        playeddoor[ID]["played1o"] = false
                        if HasTag(shape, "AltCloseSound") then
                            PlaySound(LoadSound(GetTagValue(shape, "AltCloseSound")), pos, doorvolume)
                        else
                            PlaySound(door_c, pos, doorvolume)
                        end
                    end
                end
            end
            if jointmovement >= 0.7 then
                playeddoor[ID]["open"] = true
            else
                playeddoor[ID]["open"] = false
            end
        end
    end
end

function hoodlatchsystem(shape, joint, ID, sound_o1, sound_c, lift, table, sound_o2)
    if not IsJointBroken(joint) then
        local jointmovement = GetJointMovement(joint)
        local body1 = GetShapeBody(shape)
        local pos = GetShapeWorldTransform(shape).pos
        local min, max = GetJointLimits(joint)
        local b = max / 2 - 15
        local c = max - 0.2
        if grabshape == shape or grabbody == body1 then
            SetJointMotor(joint, 0, 0)
            table[ID]["open"] = true
            if not table[ID]["played1o"] and jointmovement >= 0.06 then
                table[ID]["played1o"] = true
                table[ID]["playedc"] = false
                table[ID]["played3o"] = false
                table[ID]["played2o"] = false
                PlaySound(sound_o1, pos, doorvolume)
            end
        else
            if sound_o2 ~= nil then
                if not table[ID]["played2o"] then
                    table[ID]["played2o"] = true
                    PlaySound(sound_o2, pos, doorvolume)
                end
            end
            if table[ID]["open"] then
                if lift then
                    if jointmovement >= b then
                        SetJointMotorTarget(joint, max, 0.5)
                        if not table[ID]["played3o"] then
                            PlayLoop(hood_lift_loop, pos, doorvolume)
                        end
                    else
                        SetJointMotor(joint, 0, 0)
                    end
                else
                    if jointmovement >= c then
                        SetJointMotorTarget(joint, max, 0.5)
                    else
                        SetJointMotor(joint, 0, 0)
                    end
                end
            end
            if jointmovement <= 0.05 then
                SetJointMotorTarget(joint, 0)
                table[ID]["open"] = false
                if not table[ID]["playedc"] then
                    PlaySound(sound_c, pos, doorvolume)
                    table[ID]["playedc"] = true
                    table[ID]["played1o"] = false
                end
            end
            if jointmovement >= c then
                if not table[ID]["played3o"] then
                    table[ID]["played3o"] = true
                    PlaySound(hood_o1, pos, doorvolume)
                end
            else
                table[ID]["played3o"] = false
            end
        end
    end
end

function lightmodecheck(shape, mode)
    if GetTagValue(shape, "interact") == mode then
        return true
    else
        return false
    end
end

function tick()
    grabshape = GetPlayerGrabShape()
    grabbody = GetPlayerGrabBody()
    for i = 1, #doors do
        if HasTag(doors[i], "doorlift") then
            hoodlatchsystem(doors[i], doorjoint[i], i, door_o1, door_c, true, playeddoor, trunk_o2)
        else
            doorlatchsystem(doors[i], doorjoint[i], i)
        end
    end
    if IsHandleValid(hood) then
        hoodlatchsystem(hood, hoodjoint, 1, hood_o, hood_c, hoodlift, playedhood)
    end
    if IsHandleValid(trunk) then
        hoodlatchsystem(trunk, trunkjoint, 2, trunk_o1, trunk_c, trunklift, playedhood, trunk_o2)
    end
    if IsHandleValid(trunk_down) then
        hoodlatchsystem(trunk_down, trunk_down_joint, 3, trunk_o1, trunk_c, false, playedhood, trunk_o2)
    end
    if GetPlayerVehicle() == vehicle then
        local t = GetVehicleTransform(vehicle)
        local vel = TransformToLocalVec(t, GetBodyVelocity(vehicle_body))
        local speed = -vel[3]
        local speedside = -vel[1]
        if IsHandleValid(spoiler) then
            if speed >= 15 or speedside >= 8 then
                SetJointMotorTarget(spoilerjoint, spmax, 2)
            else
                SetJointMotorTarget(spoilerjoint, spmin, 2)
            end
        end
        if beep and doorsopen then
            PlayLoop(doorchime, t.pos, doorvolume*0.8)
        end
        if InputDown("left") or InputDown("right") then
            if InputDown("left") then
                SetJointMotorTarget(steerjoint, 110  , 4)
            else
                SetJointMotorTarget(steerjoint, -110, 4)
            end
        else
            SetJointMotorTarget(steerjoint, 0, 4.5)
        end
    else
        SetJointMotorTarget(steerjoint, 0, 4.5)
        SetJointMotorTarget(spoilerjoint, spmin, 2)
    end
    for i = 1, #intlights do
        if not IsShapeBroken(intlights[i]) then
            if GetPlayerInteractShape() == intlights[i] and InputPressed("interact") then
                if lightmodecheck(intlights[i], "Mode: Active") then
                    PlaySound(lightclicksound, GetShapeWorldTransform(intlights[i]).pos, 0.5)
                    SetTag(intlights[i], "interact", "Mode: On")
                    SetShapeEmissiveScale(intlights[i], 0.5)
                elseif lightmodecheck(intlights[i], "Mode: On") then
                    PlaySound(lightclicksound, GetShapeWorldTransform(intlights[i]).pos, 0.5)
                    SetTag(intlights[i], "interact", "Mode: Off")
                    SetShapeEmissiveScale(intlights[i], 0)
                elseif lightmodecheck(intlights[i], "Mode: Off") then
                    PlaySound(lightclicksound, GetShapeWorldTransform(intlights[i]).pos, 0.5)
                    SetTag(intlights[i], "interact", "Mode: Active")
                end
            end
        else
            RemoveTag(intlights[i], "interact")
            SetShapeEmissiveScale(intlights[i], 0)
        end
    end

    if vehicle ~= 0 then
        for i = 1, #doors do
            if playeddoor[i]["open"] and not HasTag(doors[i], "nolight") then
                doorsopen = true
                break
            else
                doorsopen = false
            end
        end
        if doorsopen then
            for i = 1, #intlights do
                if not lightmodecheck(intlights[i], "Mode: Off") and not IsShapeBroken(intlights[i]) then
                    if smoothInteriorLight then
                        SetValue("smoothLightValue", 0.5, "linear", 1)
                    else
                        smoothLightValue = 0.5
                    end
                    if (smoothLightValue > 0.47) then
                        smoothLightValue = 0.5
                    end
                    SetShapeEmissiveScale(intlights[i], smoothLightValue)
                end
            end
        else
            for i = 1, #intlights do
                if not lightmodecheck(intlights[i], "Mode: On") then
                    if smoothInteriorLight then
                        SetValue("smoothLightValue", 0, "linear", 1)
                    else
                        smoothLightValue = 0
                    end
                    if (smoothLightValue < 0.03) then
                        smoothLightValue = 0
                    end
                    SetShapeEmissiveScale(intlights[i], smoothLightValue)
                end
            end
        end
    end
end