# Installation

## 1) Go to keymaster and download the package

You can find your keymaster [here](https://keymaster.fivem.net/asset-grants), you'll need to login with your Fivem account. Make sure you get the right account because when you purchase the package, it is connected to the Fivem account you logged into.

Once logged in, you can download the package! Downloading the package is as easy as just pressing one button.&#x20;

<figure><img src="/files/54ljxq4nVeEULtAL4z5H" alt=""><figcaption></figcaption></figure>

## 2) Putting it in the server

Unzip the folder and drop it into one of your folders inside **resources**.

<details>

<summary>resources</summary>

\[cfx-default]

**\[qb]** -> Drop here

**\[standalone]** -> Or here

\[voice]

</details>

## 3) LegacyFuel | ps-fuel | ox\_fuel

### LegacyFuel

1\) Go to `LegacyFuel > source > fuel_client.lua` and find (around line 205)

```lua
if IsControlJustReleased(0, 38) then
    isFueling = true

    TriggerEvent('fuel:refuelFromPump', isNearPump, ped, vehicle)
    LoadAnimDict("timetable@gardener@filling_can")
end
```

2\) Then replace it with

```lua
if IsControlJustReleased(0, 38) then
    local vehModel = GetEntityModel(vehicle)
    QBCore.Functions.TriggerCallback('lumio-electric:server:getCarTypeQB', function(isElectric)
        if isElectric then
            QBCore.Functions.Notify("Vehicle is electric, go to charging station")
        else
            isFueling = true
        end
    end, vehModel)

    TriggerEvent('fuel:refuelFromPump', isNearPump, ped, vehicle)
    LoadAnimDict("timetable@gardener@filling_can")
end
```

### ps-fuel

1\) Go to `ps-fuel > client > client.lua` and find (around line 254)

```lua
RegisterNetEvent('ps-fuel:client:SendMenuToServer', function()
    local vehicle = QBCore.Functions.GetClosestVehicle()
    local CurFuel = GetVehicleFuelLevel(vehicle)
    local refillCost = Round(Config.RefillCost - CurFuel) * Config.CostMultiplier
    local ped = PlayerPedId()
	
    if HasPedGotWeapon(ped, 883325847) then
	if GetAmmoInPedWeapon(ped, 883325847) ~= 0 then
	    if CurFuel < 95 then
		TriggerServerEvent('ps-fuel:server:OpenMenu', 0, inGasStatio, true)
	    else
		QBCore.Functions.Notify(Lang:t("notify.vehicle_full"), "error")
	    end
	else
	    QBCore.Functions.Notify(Lang:t("notify.jerrycan_empty"), "error")
	end
    else
	if CurFuel < 95 then
	    TriggerServerEvent('ps-fuel:server:OpenMenu', refillCost, inGasStation, false)
	else
	    QBCore.Functions.Notify(Lang:t("notify.vehicle_full"), "error")
	end
    end
end)
```

2\) Then replace it with

```lua
RegisterNetEvent('ps-fuel:client:SendMenuToServer', function()
    local vehicle = QBCore.Functions.GetClosestVehicle()
    local vehModel = GetEntityModel(vehicle)
    local CurFuel = GetVehicleFuelLevel(vehicle)
    local refillCost = Round(Config.RefillCost - CurFuel) * Config.CostMultiplier
    local ped = PlayerPedId()
	
    QBCore.Functions.TriggerCallback('lumio-electric:server:getCarTypeQB', function(isElectric)
    	if isElectric then
            QBCore.Functions.Notify("Vehicle is electric, go to charging station")
        else
	    if HasPedGotWeapon(ped, 883325847) then
		if GetAmmoInPedWeapon(ped, 883325847) ~= 0 then
		    if CurFuel < 95 then
			TriggerServerEvent('ps-fuel:server:OpenMenu', 0, inGasStatio, true)
		    else
			QBCore.Functions.Notify(Lang:t("notify.vehicle_full"), "error")
		    end
		else
		    QBCore.Functions.Notify(Lang:t("notify.jerrycan_empty"), "error")
		end
	    else
		if CurFuel < 95 then
		    TriggerServerEvent('ps-fuel:server:OpenMenu', refillCost, inGasStation, false)
		else
		    QBCore.Functions.Notify(Lang:t("notify.vehicle_full"), "error")
		end
	    end
	end
    end, vehModel)
end)
```

## ox\_fuel

1\) Go to `ox_fuel > client > fuel.lua` and find (around line 48)

```lua
function fuel.startFueling(vehicle, isPump)
	local vehState = Entity(vehicle).state
	local fuelAmount = vehState.fuel or GetVehicleFuelLevel(vehicle)
	local duration = math.ceil((100 - fuelAmount) / config.refillValue) * config.refillTick
	local price, moneyAmount
	local durability = 0

	if 100 - fuelAmount < config.refillValue then
		return lib.notify({ type = 'error', description = locale('tank_full') })
	end

	if isPump then
		price = 0
		moneyAmount = utils.getMoney()

		if config.priceTick > moneyAmount then
			return lib.notify({
				type = 'error',
				description = locale('not_enough_money', config.priceTick)
			})
		end
	elseif not state.petrolCan then
		return lib.notify({ type = 'error', description = locale('petrolcan_not_equipped') })
	elseif state.petrolCan.metadata.ammo <= config.durabilityTick then
		return lib.notify({
			type = 'error',
			description = locale('petrolcan_not_enough_fuel')
		})
	end

	state.isFueling = true

	TaskTurnPedToFaceEntity(cache.ped, vehicle, duration)
	Wait(500)

	CreateThread(function()
		lib.progressCircle({
			duration = duration,
			useWhileDead = false,
			canCancel = true,
			disable = {
				move = true,
				car = true,
				combat = true,
			},
			anim = {
				dict = isPump and 'timetable@gardener@filling_can' or 'weapon@w_sp_jerrycan',
				clip = isPump and 'gar_ig_5_filling_can' or 'fire',
			},
		})

		state.isFueling = false
	end)

	while state.isFueling do
		if isPump then
			price += config.priceTick

			if price + config.priceTick >= moneyAmount and lib.progressActive() then
				lib.cancelProgress()
			end
		elseif state.petrolCan then
			durability += config.durabilityTick

			if durability >= state.petrolCan.metadata.ammo then
				lib.cancelProgress()
				durability = state.petrolCan.metadata.ammo
				break
			end
		else
			break
		end

		fuelAmount += config.refillValue

		if fuelAmount >= 100 then
			state.isFueling = false
			fuelAmount = 100.0
		end

		Wait(config.refillTick)
	end

	ClearPedTasks(cache.ped)

	if isPump then
		TriggerServerEvent('ox_fuel:pay', price, fuelAmount, NetworkGetNetworkIdFromEntity(vehicle))
	else
		TriggerServerEvent('ox_fuel:updateFuelCan', durability, NetworkGetNetworkIdFromEntity(vehicle), fuelAmount)
	end
end

```

2\) Then replace it with

```lua
function fuel.startFueling(vehicle, isPump)
	local vehState = Entity(vehicle).state
	local fuelAmount = vehState.fuel or GetVehicleFuelLevel(vehicle)
	local duration = math.ceil((100 - fuelAmount) / config.refillValue) * config.refillTick
	local price, moneyAmount
	local durability = 0
    local vehModel = GetEntityModel(vehicle)

	local isElectric = lib.callback.await('lumio-electric:server:getCarTypeOX', false, vehModel)

	if isElectric then
		return lib.notify({
			type = 'error',
			description = 'Vehicle is electric and cannot be refueled with petrol.'
		})
	end

	if 100 - fuelAmount < config.refillValue then
		return lib.notify({ type = 'error', description = locale('tank_full') })
	end

	if isPump then
		price = 0
		moneyAmount = utils.getMoney()

		if config.priceTick > moneyAmount then
			return lib.notify({
				type = 'error',
				description = locale('not_enough_money', config.priceTick)
			})
		end
	elseif not state.petrolCan then
		return lib.notify({ type = 'error', description = locale('petrolcan_not_equipped') })
	elseif state.petrolCan.metadata.ammo <= config.durabilityTick then
		return lib.notify({
			type = 'error',
			description = locale('petrolcan_not_enough_fuel')
		})
	end

	state.isFueling = true

	TaskTurnPedToFaceEntity(cache.ped, vehicle, duration)
	Wait(500)

	CreateThread(function()
		lib.progressCircle({
			duration = duration,
			useWhileDead = false,
			canCancel = true,
			disable = {
				move = true,
				car = true,
				combat = true,
			},
			anim = {
				dict = isPump and 'timetable@gardener@filling_can' or 'weapon@w_sp_jerrycan',
				clip = isPump and 'gar_ig_5_filling_can' or 'fire',
			},
		})

		state.isFueling = false
	end)

	while state.isFueling do
		if isPump then
			price += config.priceTick

			if price + config.priceTick >= moneyAmount and lib.progressActive() then
				lib.cancelProgress()
			end
		elseif state.petrolCan then
			durability += config.durabilityTick

			if durability >= state.petrolCan.metadata.ammo then
				lib.cancelProgress()
				durability = state.petrolCan.metadata.ammo
				break
			end
		else
			break
		end

		fuelAmount += config.refillValue

		if fuelAmount >= 100 then
			state.isFueling = false
			fuelAmount = 100.0
		end

		Wait(config.refillTick)
	end

	ClearPedTasks(cache.ped)

	if isPump then
		TriggerServerEvent('ox_fuel:pay', price, fuelAmount, NetworkGetNetworkIdFromEntity(vehicle))
	else
		TriggerServerEvent('ox_fuel:updateFuelCan', durability, NetworkGetNetworkIdFromEntity(vehicle), fuelAmount)
	end
end

```

## 4) Battery item

Add the following to your `qb-core > shared > items.lua`

```lua
    ['car_battery']                     = {['name'] = 'car_battery',                       ['label'] = 'Car battery',               ['weight'] = 10000,        ['type'] = 'item',         ['image'] = 'car_battery.png',             ['unique'] = false,         ['useable'] = true,      ['shouldClose'] = true,      ['combinable'] = nil,   ['description'] = 'Small amount of battery for your electric car'},
```

Also drop the image found in **image folder**, inside `qb-inventory > html > images`

## 5) Optional map

Download [this map](https://www.gta5-mods.com/maps/tesla-superchargers-stations-sp-fivem) and start it. This is optional.

## 6) Start the script

Start the script and enjoy! For configuration info go to the next page :smile:


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://lumio-studio.gitbook.io/intro/evs-qb/installation.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
