Garage, Parking Lots & Impound [NUI] [ESX/QBCore/Standalone]

A script by slizzarn1

No reviews yet.
Garage, Parking Lots & Impound [NUI] [ESX/QBCore/Standalone] main image

Full Description

INTERESTED IN BUYING IT?
Price: $23.75 (including tebex tax)
Click here to purchase it!

HOW DOES IT WORK?

Every vehicle either is in a garage, a parking lot, an impound or it is outside. You can only access the vehicle in the specific garage or parking lot they are in. You can only access them if you have the requirements to spawn it. The requirements are originally that you are signed as the owner of the vehicle, but you can change this and add your criteria which could be having a key. The garages and parking lots are public, but you can add that just a specific job can open the garage. Which would be necessary if you have a garage of each job.

This garage script is different from others, because I have done a inspiration from GTA 5 garages. Where you enter a “real garage”, with a cool cutscene when you enter and leave the garage. When you are inside the garage there is a UI instead of having the vehicles inside the garage.

The parking lots is necessary when you do not have a garage door nearby. The parking lots are much faster and would work at places where there is a lot of players. The parking lots also have the same UI as the garages, but not the cool cutscenes.

The impound do not work like the garages or parking lots. At the impound you can find vehicles you did not stored in a garage or a parking lot. They only appear there if your vehicle is outside when the server restarts. It could either be a cost to buy your vehicle out of the impound or it could be free, that can be changed in the config.

All this is shown in action in the showcases below, and it is easier to understand how everything works.

WHAT CAN I CUSTOMIZE?

You can customize almost everything. There are many options you can choose between, some of them are translation, image API, animations, background interiors, vehicle properties, notification, vehicle check, and more. You can read more about these options in the config examples.

The resource is very friendly for developers. There are a lot of options and you can customize almost everything. You have access to the server-side code which is explained more below, and you have the opportunity to change almost whatever you want.

IS IT OBFUSCATED?

The client code is obfuscated and some of the server-side code, but you can access the fetching and updating of the vehicles. This means that you can easily customize the resource after your framework but it is already made for ESX and QBCore. You need some experience with coding if you want to customize the resource for another framework. Customizing the resource is not included in the support.

CAN I GET SUPPORT?

I can not promise that I will have the time to help you personally, but if it is regarding a problem that you found then I will prioritize that. I am sure that others will help you, so just ask in this topic.

REQUIREMENTS

There are no requirements. It all depends on what you know and how much you can do. This resource is originally standalone but I have made it for both ESX and QBCore, but you have access to customize the resource to your liking which makes this standalone.

GARAGE SHOWCASE


(click here if the video doesn’t work)

PARKING LOT SHOWCASE


(click here if the video doesn’t work)

IMPOUND SHOWCASE


(click here if the video doesn’t work)

CONFIGURATION EXAMPLES

config.lua

Config = {}

Config.Framework = 'ESX'
-- 'ESX' | 'QBCore' | undefined

-- Translation

Config.Translation = {
    ['enter_garage'] = 'Press %s to enter the garage', -- %s is the button
    ['open_parking'] = 'Press %s to open the parking lot',
    ['open_impound'] = 'Press %s to open the impound',

    ['store_vehicle'] = 'Press %s to store the vehicle',

    ['not_owner'] = 'You are not the owner of the vehicle',
    ['not_afford'] = 'You do not have enough money.',

    -- UI
    ['garage_title'] = '%s Garage', -- %s is the title of the garage
    ['parkinglot_title'] = '%s Parking Lot', -- %s is the title of the parking lot
    ['refresh'] = 'Refresh',
    ['change_view'] = 'Change view',
    ['light_mode'] = 'Light mode',
    ['dark_mode'] = 'Dark mode',
    ['close'] = 'Close',
    ['drive_out'] = 'Drive out',

    ['impound_free'] = 'Spawn vehicle',
    ['impound_buy'] = 'Pay %s$ and spawn vehicle',
}

-- Vehicle Details

Config.VehicleDetails = {
    {
        label = 'Plate',
        type = 'text',
        prop = 'plate'
    },
    {
        label = 'Engine health',
        type = 'percentage',
        max = 1000,
        prop = 'engineHealth'
    },
    {
        label = 'Body health',
        type = 'percentage',
        max = 1000,
        prop = 'bodyHealth'
    },
    {
        label = 'Fuel level',
        type = 'percentage',
        max = 100,
        prop = 'fuelLevel'
    },
}

-- Enter options
-- This is used when you enter the garage and open the impound.

Config.EnterKey = {
    index = 38, 
    name = 'INPUT_CONTEXT'
}

Config.EnterAnim = {
    dict = 'anim@apt_trans@garage',
    anim = 'gar_open_1_right',
    startTime = 0.24
}

Config.EnterDistance = {
    on_foot = 2.0,
    in_vehicle = 5.0
}

-- Interiors
-- This is the background while you are inside a garage.

Config.DefaultInterior = 'low';
Config.Interiors = {
    ['low'] = {
        coords = vector3(177.61, -1007.26, -98.9),
        rotation = vector3(0, 0, 45)
    },
    ['mid'] = {
        coords = vector3(191.78, -1001.44, -99.0),
        rotation = vector3(0, 0, -90)
    },
    ['mid2'] = {
        coords = vector3(192.0, -1020.26, -98.9),
        rotation = vector3(0, 0, -90)
    },
    ['high'] = {
        coords = vector3(228.3, -1003.1, -98.9),
        rotation = vector3(0, 0, 0)
    },
    ['tuner'] = {
        coords = vector3(996.6, -2994.4, -38.0),
        rotation = vector3(0, 0, 120)
    },
    ['parking_garage'] = {
        coords = vector3(1306.8, 260.4, -48.0),
        rotation = vector3(0, 0, 140)
    }
}

-- Images
-- These images are for the vehicles.

-- This is just an example. I can not assure you that the API will work forever, but it worked when I did this.
-- This example does not work for all vehicles. If you have a better API you can easily replace it.
-- Do not touch this if you do not know how it works.

Config.ImageAPI = { 
    url = function(modelHash, modelName, modelLabel)
        return ('https://gta.now.sh/api/vehicles/%s'):format(modelLabel:lower())
    end,
    callback = function(result)
        return result.images and result.images['frontQuarter'] or false
    end
}

Config.Images = { -- Here you can add your images for models.
    -- Example
    -- ['rmodsupra'] = 'https://libertycity.net/uploads/download/gta5_toyota/fulls/f0b94mbi94gqu2848t03eqaas4/1498320350941_14902102306952_1.jpg'

    ['baller2'] = 'https://i.imgur.com/twz773F.png',
    ['dubsta3'] = 'https://i.imgur.com/gRJeu00.png',
    ['elegy2'] = 'https://i.imgur.com/tXAFkee.png'
}

-- Vehicle Labels
-- Some of your addons vehicles may not have a label, here you can add your labels. These will also override the default labels.

Config.VehicleLabels = {
    -- Example
    -- ['rmodsupra'] = 'Toyota Supra'
}

-- Hide HUD
-- You can add your exports and events here. The boolean will be true when you enter the garage and false when you leave it.

Config.HideHUD = function(boolean) 
    DisplayRadar(not boolean); 

    if Config.Framework == 'ESX' then

    elseif Config.Framework == 'QBCore' then

    end

    TriggerEvent('esx_status:setDisplay', boolean and 0.0 or 0.5)
end

-- Check if owner of vehicle
-- You can add other criteria, for example that you need a key for the vehicle instead of being owner.
-- ! This only works for ESX and QBCore !

Config.DisableVehicleCheck = true -- If false it will check if you are the owner
Config.VehicleCheck = function(plate, owner, identifier, vehicle, player)
    return owner == identifier
end

-- Check if player has the job
Config.JobCheck = function(job)
    if Config.Framework == 'ESX' then
        return ESX.PlayerData.job.name == job
    elseif Config.Framework == 'QBCore' then
        return QBCore.playerJob.name == job
    else
        -- standalone

        return true
    end
end

Config.ShowBlipForEveryone = false -- If true the blips with required jobs will not be shown for people without the job

-- Notification

Config.Notification = function(source, text)
    if Config.Framework == 'ESX' then
        TriggerClientEvent('esx:showNotification', source, text)
    elseif Config.Framework == 'QBCore' then
        TriggerClientEvent('QBCore:Notify', source, text)
    end
end

-- Vehicle Props
-- This is only extra props if you are using ESX or QBCore. 
-- These props can also be used in Config.VehicleDetails. If you want a specific detail about a vehicle you can save the prop here.

Config.GetVehicleProps = function(props, vehicle)
    props.wheelHealth = {}
    props.tireBurst = {}
    props.tireCompletelyBurst = {}
    props.smashedWindows = {}
    props.brokenDoors = {}

    props.engineHealth = GetVehicleEngineHealth(vehicle)
    props.bodyHealth = GetVehicleBodyHealth(vehicle)
    props.fuelLevel = GetVehicleFuelLevel(vehicle)

    for i = 0, 3 do
        props.wheelHealth[i] = GetVehicleWheelHealth(vehicle, i)
    end

    for i = 0, 5 do
        props.tireBurst[i] = IsVehicleTyreBurst(vehicle, i, false)
    end

    for i = 0, 5 do
        props.tireCompletelyBurst[i] = IsVehicleTyreBurst(vehicle, i, true)
    end

    for i = 0, 7 do
        props.smashedWindows[i] = IsVehicleWindowIntact(vehicle, i) ~= 1
    end

    for i = 0, 5 do
        props.brokenDoors[i] = IsVehicleDoorDamaged(vehicle, i) == 1
    end
end

Config.SetVehicleProps = function(props, vehicle)
    if Config.Framework == 'QBCore' then
        TriggerEvent("vehiclekeys:client:SetOwner", QBCore.Functions.GetPlate(vehicle))
    end

    SetVehicleEngineHealth(vehicle, props.engineHealth and props.engineHealth + 0.0 or 1000.0)
    SetVehicleBodyHealth(vehicle, props.bodyHealth and props.bodyHealth + 0.0 or 1000.0)
    SetVehicleFuelLevel(vehicle, props.fuelLevel and props.fuelLevel + 0.0 or 100.0)
  
    if props.wheelHealth then
        for wheelIndex, health in pairs(props.wheelHealth) do
            SetVehicleWheelHealth(vehicle, tonumber(wheelIndex), health)
        end
    end

    if props.tireBurst then
        for wheelIndex, burstState in pairs(props.tireBurst) do
            if burstState then
                SetVehicleTyreBurst(vehicle, tonumber(wheelIndex), false, 1000.0)
            end
        end
    end

    if props.tireCompletelyBurst then
        for wheelIndex, burstState in pairs(props.tireCompletelyBurst) do
            if burstState then
                SetVehicleTyreBurst(vehicle, tonumber(wheelIndex), true, 1000.0)
            end
        end
    end

    if props.smashedWindows then
        for windowIndex, smashWindow in pairs(props.smashedWindows) do
            if smashWindow then 
                SmashVehicleWindow(vehicle, tonumber(windowIndex)) 
            end
        end
    end

    if props.brokenDoors then
        for doorIndex, breakDoor in pairs(props.brokenDoors) do
            if breakDoor and GetIsDoorValid(vehicle, tonumber(doorIndex)) then
                SetVehicleDoorBroken(vehicle, tonumber(doorIndex), true)
            end
        end
    end
end

config.garages.lua

-- Garages

Config.Garages = {
    -- Example
    -- {
    --     name = 'vinewood', -- this need to be unique. No capital letters or spaces
    --     title = 'Vinewood', -- this is will be displayed in the UI and on the blip.
    --     coords = vector4(-62.8, 80.0, 71.6, 248.9), -- this is the coords for entering the garages. Needs to be a vector4.
    --     enterDistance = 1.2, -- this is optional, this is a multiplier for the distance. The distances can be changed in config.lua.
    --     interior = 'mid2', -- this is optional, this is only necessary if you want a specific interior. The default can be changed below
    --     noBlip = false, -- this is optional, if true then there is no blip.
    --     requiredJob = 'police', -- this is optional, this means that you need a specific job to access the garage.
    --     cameraHeight = 2.0, -- this is optional, the default is 10.0.
    --     blip = { -- this is optional, you can customize the blip for this specific garage. The default style can be changed below
    --         sprite = 357,
    --         scale = 1.0,
    --         color = 7,
    --         title = 'Example garage'
    --     }
    -- }
    {
        name = 'vinewood',
        title = 'Vinewood',
        coords = vector4(-62.8, 80.0, 71.6, 248.9),
        enterDistance = 1.5,
        interior = 'mid'
     }
}

-- Garage Blip

Config.GarageBlip = { -- You can find the blips here: https://docs.fivem.net/docs/game-references/blips/
    sprite = 357,
    scale = 0.8,
    color = 4,
    title = '%s Garage'
}

config.parkinglots.lua

-- Locations

Config.ParkingLots = {
    -- Example
    -- {
    --     name = 'alta', -- this need to be unique. No capital letters or spaces.
    --     title = 'Alta', -- this is will be displayed in the ui and on the blip.
    --     coords = vector4(-62.8, 80.0, 71.6, 248.9), -- this is the coords for entering of the garages. Needs to be a vector4
    --     enterDistance = 1.2, -- this is optional, this is a multiplier for the distance. The distances can be changed in config.lua.
    --     noBlip = false, -- this is optional, if true then there is no blip.
    --     requiredJob = 'police', -- this is optional, this means that you need a specific job to access the garage.
    --     blip = { -- this is optional, you can customize the blip for this specific garage. The default style can be changed below
    --         sprite = 357,
    --         scale = 1.0,
    --         color = 7,
    --         title = 'Example parking lot'
    --     }
    -- }
    {
        name = 'alta',
        title = 'Alta',
        coords = vector4(277.96, -347.76, 44.93, 342.94),
        vehicle = vector4(283.63, -342.36, 44.23, 251.941)
    }
}

-- Parking Lot Marker

Config.ParkingLotMarker = {
    type = 2,
    r = 255,
    g = 50,
    b = 50,
    alpha = 150,
    offsetCoords = vector3(0, 0, 0.5),
    scale = vector3(0.7, 0.7, 0.7)
}

-- Parking Lot Model

Config.ParkingLotModel = `prop_park_ticket_01`;

-- Parking Lot Blip

Config.ParkingLotBlip = { -- You can find the blips here: https://docs.fivem.net/docs/game-references/blips/
    sprite = 267,
    scale = 0.6,
    color = 67,
    title = '%s Parking Lot'
}

config.impounds.lua

-- Locations

Config.Impounds = {
    -- Example
    -- {
    --     coords = vector4(409.4, -1624.1, 29.3, 232.5), -- this is the coords for the ped
    --     vehicle = vector4(401.4, -1632.2, 29.0, 319.2), -- this is the coords for where the vehicle spawns
    --     price = 500, -- the price for buying out your vehicle. Set to 0 if you want it to be free
    -- }
    {
        coords = vector4(409.4, -1624.1, 29.3, 232.5),
        vehicle = vector4(401.4, -1632.2, 29.0, 319.2),
        price = 500
    }
}

-- Ped models

Config.ImpoundModels = {
    `cs_drfriedlander`,
    `cs_johnnyklebitz`
}

-- Ped scenarios
Config.ImpoundScenarios = {
    'WORLD_HUMAN_CLIPBOARD'
}

-- Blip

Config.ImpoundBlip = { -- You can find the blips here: https://docs.fivem.net/docs/game-references/blips/
    sprite = 68,
    scale = 0.8,
    color = 5,
    title = 'Impound'
}

INTERESTED IN BUYING IT?
Price: $23.75 (including tebex tax)
Click here to purchase it!

Code is accessible Only server side is accessible
Subscription-based No
Lines (approximately) 1678 (not NUI included)
Requirements N/A
Support Yes