STG ScriptsDocumentation
Vanaheim Fuel

Configuration

Every option in STG Vanaheim Fuel, from stations, fuel prices and business rules to pumps, deliveries, NPC staff, car wash, siphoning and vehicle fuel consumption.

The settings are split over four files in stg-vanaheimfuel/shared/. They stay editable in the escrow version. Restart the resource after a change.

FileWhat it holds
config.luaLanguage, units, notifications, target, vehicle keys, stations, blips, helipad and dock fueling, fuel types, business rules
config_features.luaPumps, electric charging, jerrycans, siphons, car wash, deliveries, NPC staff, wrong fuel, police alerts, speech bubbles, default ranks
config_vehicles.luaStarting fuel, diesel and electric vehicles, tank sizes, fuel consumption
names.luaNames given to hired NPC staff

Language

Config.Language = 'en'

Available: en, de, fr, es, pt, it, nl, pl, sv, no, fi, ar, he, jp, zh. To change a text, edit the matching file in stg-vanaheimfuel/locales/. The locale files also hold the lines NPCs say in their speech bubbles and the texts of the fuel and management menus.

Station names are saved in the stg_fuel table the first time the script starts, using the station label of the language active at that moment (for example "Gas Station"). Changing Config.Language later does not rename stations that already exist, so a blip can read "Gas Station Tankstelle".

An owner can rename their station in the management menu. For unowned stations, update the database while the resource is stopped, for example:

UPDATE stg_fuel SET business_name = 'Tankstelle' WHERE owner_identifier IS NULL;

Use the gas_station text of your language file. When a station is sold, its name resets to the current language automatically.

Units

Config.UnitSystem = 'gallons'

liters or gallons. This only changes what players see in the menus and messages. Every amount and price in the config files stays in liters and dollars per liter.

Notifications

Config.CustomNotify = false

Config.Functions.Notify = function(type, message, title)
    -- ks-notify or ox_lib when CustomNotify is true, built-in notification otherwise
end
  • CustomNotify: false shows the script's own notifications. true sends them to ks-notify when it is running, otherwise to ox_lib.
  • Notify: replace the body to use another notification system. type is success, error, inform, info or warning.

Target

Config.Target = 'false'
ValueResult
'false'On-screen prompts, press E at a pump, charger, car wash or clerk
'auto'Uses ox_target or qb-target, whichever is running, and falls back to prompts
'ox_target'Uses ox_target
'qb-target'Uses qb-target

The target options are registered in stg-vanaheimfuel/client/editable/target.lua, which also stays editable in the escrow version. Unlocking a locked pump and delivering fuel always use on-screen prompts.

Vehicle keys

Config.Functions.GiveKeys = function(plate, vehicle)
    -- qbx_vehiclekeys, qb-vehiclekeys, qs-vehiclekeys, wasabi_carlock, t1ger_keys,
    -- mk_vehiclekeys, cd_garage, vehicles_keys, renzu_vehiclekeys, esx_vehiclelock
end

Gives the player keys for the delivery truck and trailer. The first key script from the list that is running is used. Replace the body if your server uses a different one.

Stations

The script ships with 26 stations, one for every vanilla gas station. Each entry describes one station:

Config.Stations = {
    ['station_1'] = {
        purchasable = true,
        label = Locales[Config.Language]['gas_station'],
        coords = vector3(265.65, -1261.65, 29.29),
        radius = 30.0,
        carWash = {
            coords = vector3(283.7935, -1269.5209, 29.2555),
            workers = {
                vector4(287.9035, -1268.4897, 28.4408, 93.0662),
                vector4(287.9611, -1270.6368, 28.4408, 93.6984),
            },
        },
        purchasePrice = 500000,
        maxStock = 5000,
        blip = { sprite = 361, color = 1, scale = 0.7 },
        purchaseNpc = {
            model = 's_m_y_shop_mask',
            coords = vector4(288.63, -1255.56, 29.43, 102.04),
        },
        attendants = {
            vector4(274.04, -1258.91, 28.14, 272.12),
            vector4(255.87, -1258.86, 28.12, 96.37),
        },
        electricPumps = {
            vector4(273.3984, -1237.5977, 28.3305, 359.1315),
        },
        mechanicNpc = vector4(275.9142, -1237.6418, 28.3406, 176.6533),
        driverNpc = vector4(293.9858, -1250.7382, 28.3315, 358.0730),
        deliverySpawn = vector4(291.6129, -1244.1595, 29.3547, 182.3531),
        deliveryDropoff = vector3(270.0, -1261.0, 29.14),
    },
    -- ...
}

Prop

Type

label and maxStock are copied into the database when a station is created. Changing them later only affects stations added after the change, and a station that is sold.

Adding a station

Copy an existing block, for example station_1, and give it a new key such as station_27.

Stand in the middle of the forecourt and use those coordinates for coords. Make sure radius covers every pump.

Walk to each NPC spot (clerk, attendants, car wash workers, mechanic, driver) and the truck spawn, and copy your coordinates and heading with /coords or your admin menu.

Restart the resource. The new station is saved to the database on start.

Map blips

Config.Blips = {
    enabled = true,
    sprite = 361,
    color = 1,
    scale = 0.7,
    shortRange = true,
    ownedSprite = 361,
    ownedColor = 2,
}

Prop

Type

The blip text is the station name followed by the ui_station_suffix text, for example "Ron's Gas Station".

Helicopter and boat fueling

Config.HelicopterFueling = {
    enabled = true,
    fuelType = 'premium',
    priceMultiplier = 2.5,
    locations = {
        vector4(-735.3836, -1456.6099, 3.9919, 322.7240),
    },
}

Config.BoatFueling = {
    enabled = true,
    fuelType = 'diesel',
    priceMultiplier = 1.5,
    locations = {
        vector4(-846.0560, -1367.5775, 0.6052, 108.5345),
    },
}

A pump prop and a blip are placed at each location. Fly or sail within 15 meters and press E, or use the target on the pump. These pads are not part of any station: the player pays the fuel type's defaultPrice times priceMultiplier and the money does not go to an owner.

  • fuelType: key from Config.FuelTypes sold at the pad.
  • priceMultiplier: price factor on top of the default price.
  • locations: add as many pads or docks as you want.

Fuel types

Config.FuelTypes = {
    ['diesel']   = { label = 'Diesel',   category = 'diesel',   defaultPrice = 1.5, minPrice = 0.5, maxPrice = 10.0, depletionRate = 1.0, wholesalePrice = 0.8, color = '#3ecc93' },
    ['gasoline'] = { label = 'Gasoline', category = 'gasoline', defaultPrice = 2.0, minPrice = 0.5, maxPrice = 10.0, depletionRate = 0.9, wholesalePrice = 1.2, color = '#cc7c3e' },
    ['premium']  = { label = 'Premium',  category = 'gasoline', defaultPrice = 3.0, minPrice = 0.5, maxPrice = 15.0, depletionRate = 0.8, wholesalePrice = 1.8, color = '#3e69cc' },
    ['electric'] = { label = 'Electric', category = 'electric', defaultPrice = 4.5, minPrice = 1.0, maxPrice = 20.0, depletionRate = 0.6, wholesalePrice = 2.5, color = '#36a69b' },
}

Prop

Type

The fuel menu has one card for each of these four keys. Change the values freely, but keep the keys diesel, gasoline, premium and electric.

Business rules

Config.Business = {
    taxRate = 10,
    sellPercent = 60,
    salaryPayInterval = 60,
    maxNameLength = 10,
    transferCooldown = 300,
    maxRanks = 10,
    maxStationsPerPlayer = 3,
    maxTransactions = 20,
}

Prop

Type

Unowned stations

Config.UnownedStationStaffActive = true
Config.UnownedStationStaffGhost = true
  • UnownedStationStaffActive: at stations nobody owns, the attendants fuel cars and the car wash works with one worker.
  • UnownedStationStaffGhost: only used when the setting above is false. true shows the attendants and car wash workers as transparent idle NPCs, false leaves the station empty.

Unowned stations have no stock limit and always sell at defaultPrice. At owned stations, staff positions nobody was hired for show a transparent NPC.

Pumps

Config.PumpSystem = {
    defaultUnlocked = 1,
    pricePerPump = 50000,
}

Config.Nozzle = {
    fuelPerSecond = 2.0,
    maxDistance = 8.0,
    animDict = 'timetable@gardener@filling_can',
    animName = 'gar_ig_5_filling_can',
}

Config.DisablePumpCollision = true

Config.PumpModels = {
    `prop_gas_pump_1a`, `prop_gas_pump_1b`, `prop_gas_pump_1c`, `prop_gas_pump_1d`,
    `prop_gas_pump_old1`, `prop_gas_pump_old2`, `prop_gas_pump_old3`,
    `prop_vintage_pump`, `prop_gas_pump_1d_ns`,
}

At unowned stations every pump works. After a station is bought, only the first defaultUnlocked pumps (closest to the station center) work. The others turn see-through until the owner unlocks them for pricePerPump from the station balance, at the pump or in the Pumps tab.

Prop

Type

Pump wear

Config.PumpBreakdown = {
    enabled = true,
    checkAfterLiters = 100,
    breakdownChance = 0.03,
    guaranteedAt = 667,
    repairCostPerPercent = 100,
    repairTimePerPercent = 2,
    slowdownEnabled = true,
    slowdownMinMultiplier = 0.3,
}

Pumps only wear out at owned stations. A pump loses health with every liter it pumps: health is 100% minus the liters pumped since the last repair divided by guaranteedAt. Worn pumps smoke, then spark, and a broken pump cannot be used until it is repaired.

Prop

Type

Electric charging

Config.ElectricCharging = {
    enabled = true,
    model = 'stg_prop_elec_pump',
    chargePerSecond = 3.0,
    maxDistance = 5.0,
}

Prop

Type

Electric vehicles can only charge at a charger, and chargers only accept electric vehicles.

Jerrycan

Config.Jerrycan = {
    itemName = 'jerrycan',
    emptyItemName = 'empty_jerrycan',
    model = 'w_am_jerrycan',
    fuelPerSecond = 1.5,
    capacity = 20,
    stockType = 'gasoline',
    containerFee = 500,
    refundPercent = 50,
    animDict = 'weapons@misc@jerrycan@',
    animName = 'fire',
}

Players buy, refill and return jerrycans in the fuel menu at any pump, paid in cash. To use one, use the item, walk to a vehicle's fuel cap and press E. Backspace cancels. It pours diesel into diesel vehicles and gasoline into everything else.

Prop

Type

Fuel siphon

Config.Siphon = {
    emptyItem = 'fuel_siphon',
    fullItem = 'fuel_siphon_full',
    model = 'v_ind_cs_jerrycan03',
    stealPerSecond = 0.8,
    fillPerSecond = 1.2,
    capacity = 20,
    animDict = 'weapons@misc@jerrycan@',
    animName = 'fire',
}

Use the empty siphon at a vehicle's fuel cap to drain it. The empty siphon is used up when draining starts, and the player only gets the full siphon if they drain until the end. The police are alerted either way. Use the full siphon on another vehicle to pour the fuel in and get the empty siphon back.

Prop

Type

Car wash

Config.CarWash = {
    price = 500,
    purchasePrice = 75000,
    baseDuration = 30,
    durationReduction = 0.6,
    dirtRemovalPercent = 100,
    marker = {
        type = 27,
        color = { r = 62, g = 204, b = 147, a = 120 },
        size = vector3(2.0, 2.0, 0.5),
        bobUpAndDown = false,
        rotate = false,
    },
    workerAnimDict = 'timetable@floyd@clean_kitchen@base',
    workerAnimName = 'base',
    workerCleanBones = { 'boot', 'wheel_lf', 'wheel_rf', 'wheel_lr', 'wheel_rr', 'bumper_f', 'bumper_r' },
}

Drive onto the marker of a station with a carWash block and press E. At owned stations, the owner first unlocks the car wash at the marker and hires at least one worker.

Prop

Type

Fuel delivery

Config.Delivery = {
    enabled = true,

    depots = {
        ['depot_1'] = {
            label = 'Oil Refinery',
            coords = vector3(2678.69, 1676.58, 24.49),
            heading = 180.0,
            blipSprite = 477,
            blipColor = 47,
            trailerSpawn = vector4(2680.50, 1662.00, 24.49, 0.0),
        },
    },

    vehicles = {
        ['small']  = { label = 'Fuel Van',    model = 'packer',  capacity = 5000,  costMultiplier = 1.0,  rentalPrice = 2000 },
        ['medium'] = { label = 'Fuel Truck',  model = 'hauler',  capacity = 10000, costMultiplier = 0.85, rentalPrice = 5000 },
        ['large']  = { label = 'Fuel Tanker', model = 'hauler2', capacity = 20000, costMultiplier = 0.7,  rentalPrice = 10000 },
    },

    trailer = { model = 'tanker' },
    spawnOffset = vector3(0.0, 0.0, 0.0),
    damageThreshold = 500.0,
    maxFuelLossPercent = 30,
    loadingTime = 15,
    unloadingTime = 10,
    blipRoute = true,

    npcDriver = {
        enabled = true,
        minDeliveryTime = 180,
        maxDeliveryTime = 240,
        model = 's_m_y_dockwork_01',
        idleScenario = 'WORLD_HUMAN_SMOKING',
    },
}

Stations get stock only through deliveries. In the management menu a member with the refuel permission picks the liters per fuel type and a truck size. The order is paid from the station balance: liters times wholesalePrice times the truck's costMultiplier, plus its rentalPrice.

The truck spawns at the station's deliverySpawn. Drive it to the depot.

Back up to the tanker trailer and attach it within two minutes, then wait for the loading bar.

Drive back and press E near the station. If the truck health is below damageThreshold, part of the fuel has leaked out.

Cancelling refunds 80% of the order. If the truck is destroyed or the player disconnects, 50% is refunded.

Prop

Type

NPC driver

When the station has hired a delivery driver, the order can be sent with the driver instead. He drives off and the stock arrives after a random time between minDeliveryTime and maxDeliveryTime seconds, without any loss. The price is the same as a delivery by hand, and one NPC delivery can run per station at a time.

Prop

Type

NPC staff

Config.NPC = {
    pumpAttendantCostPerDay = 500,
    carWashWorkerCostPerDay = 750,
    deliveryDriverCostPerDay = 1000,
    mechanicCostPerDay = 1500,

    maxPumpAttendants = 6,
    maxCarWashWorkers = 2,
    maxDeliveryDrivers = 1,
    maxMechanics = 1,

    pumpAttendantModels = { 's_m_y_dockwork_01', 's_m_y_garbage', ... },
    carWashWorkerModels = { 's_m_y_dockwork_01', 's_m_y_construct_01' },
    deliveryDriverModels = { 's_m_y_dockwork_01', 's_m_y_waretech_01' },
    mechanicModels = { 's_m_y_xmech_01' },
}

Members with the hire permission hire staff in the Staff tab. A random name from names.lua and a random model from the list are picked and saved.

Wages are taken from the station balance every Config.Business.salaryPayInterval minutes (60 by default) for each hired NPC. If the balance cannot cover all wages, nothing is taken that round. Firing an NPC costs one wage as severance pay.

Prop

Type

Pump attendants

Config.PumpAttendant = {
    enabled = true,
    runDistance = 3.0,
    idleAnim = {
        dict = 'WORLD_HUMAN_STAND_MOBILE',
        name = 'base',
        scenario = true,
    },
}

When a free attendant is working at the station, he walks to the pump and fuels the car while the player waits. Without one, the player uses the nozzle.

  • enabled: turn attendants off completely.
  • runDistance: the attendant walks to targets closer than this in meters and runs to anything further.
  • idleAnim.dict: scenario the attendant plays while waiting.

Mechanic

Config.Mechanic = {
    enabled = true,
    model = 's_m_y_xmech_01',
    healthThreshold = 90,
    repairSpeedPerPercent = 1.5,
    animDict = 'mini@repair',
    animName = 'fixing_a_player',
    idleScenario = 'WORLD_HUMAN_SMOKING',
}

A hired mechanic repairs worn pumps for free, one at a time, while a player is near the station.

Prop

Type

Staff names

Config.StaffNames = {
    'James Walker',
    'Robert Fischer',
    -- ...
}

Names in names.lua given to hired NPCs and shown in the Staff tab.

Wrong fuel

Config.WrongFuel = {
    enabled = true,
    damagePerTick = 10.0,
    smokingThreshold = 400.0,
    stallChance = 0.05,
    tickInterval = 1000,
    minEngineHealth = 0.0,
}

Fuel from another category, for example diesel in a gasoline car, damages the engine while it runs. The fuel menu warns before switching fuel types, and switching drains the tank first. Filling up with the right fuel fixes it.

Prop

Type

Police alert

Config.PoliceAlert = {
    enabled = true,
    useCustom = false,
    policeJobs = { 'police', 'sheriff' },
    showBlip = true,
    blipDuration = 30,
    blipSprite = 161,
    blipColor = 1,
    blipScale = 1.0,
    showMugshot = true,
    partialPlate = true,
    partialPlateChars = 4,

    customServer = function(thiefSource, plate, coords)
        -- ps-dispatch example
    end,
    customClient = function(thiefSource, plate, coords)
        -- cd_dispatch example
    end,
}

Players with one of the policeJobs get a notification when someone siphons fuel, with a flashing blip and an option to set a waypoint.

Prop

Type

Speech bubbles

Config.SpeechBubble = {
    enabled = true,
    triggerDistance = 8.0,
    viewDistance = 8.0,
    duration = 7000,
    cooldown = 20000,
    checkInterval = 5000,
    greetDistance = 4.0,
    categories = {
        pump_hired = true,
        pump_idle = true,
        wash_hired = true,
        wash_idle = true,
        driver_hired = true,
        driver_idle = true,
        purchase_unowned = true,
        purchase_owned = true,
        mechanic_hired = true,
        mechanic_idle = true,
    },
}

NPCs say short lines in a bubble above their head when players walk by. The lines are in the npcDialog part of each locale file.

Prop

Type

Default ranks

Config.DefaultRanks = {
    {
        name = 'Owner',
        salary = 0,
        sortOrder = 1,
        isDefault = true,
        permissions = {
            manage = true,
            hire = true,
            sell = true,
            refuel = true,
            set_prices = true,
            manage_members = true,
            withdraw_money = true,
        },
    },
    { name = 'Manager', salary = 1000, sortOrder = 2, isDefault = false, permissions = { ... } },
    { name = 'Employee', salary = 500, sortOrder = 3, isDefault = true, permissions = { ... } },
}

These ranks are created when a station is bought. Members with manage add more ranks, rename them and change their permissions in the management menu. Every member can open the management menu at the clerk.

Prop

Type

PermissionAllows
manageRename the station, create, rename and delete ranks, edit rank salaries and permissions, repair pumps
hireHire and fire NPC staff
sellShown in the rank editor
refuelOrder fuel deliveries
set_pricesChange fuel prices
manage_membersInvite and remove members and change their rank
withdraw_moneyWithdraw cash from the station balance

Only the owner can unlock pumps, buy the car wash, sell the station or transfer it to another player. Any member can deposit cash.

Vehicles

Starting fuel

Config.InitialFuel = {
    min = 20.0,
    max = 80.0,
}

The first time a vehicle is seen it gets a random fuel level between min and max percent. The level then stays on the vehicle as long as it exists. A garage that spawns a new vehicle has to set the saved level with SetFuel, see Exports.

Fuel categories

Config.UseClassBasedDetection = true
Config.UseManualVehicleLists = true

Config.DieselClasses = {
    [10] = true, -- Industrial
    [17] = true, -- Service
    [19] = true, -- Military
    [20] = true, -- Commercial
    [21] = true, -- Trains
}

Config.DieselVehicles = { 'benson', 'biff', 'hauler', 'mule', 'phantom', 'pounder', ... }
Config.ElectricVehicles = { 'voltic', 'caddy', 'surge', 'iwagen', 'raiden', 'neon', 'tezeract', ... }
Config.BlacklistedVehicles = { 'bmx', 'cruiser', 'fixter', 'scorcher', 'tribike', 'tribike2', 'tribike3' }

A vehicle is checked in this order: ElectricVehicles, DieselVehicles, DieselClasses. Everything else runs on gasoline.

  • UseClassBasedDetection: use DieselClasses. Set to false to rely on the lists only.
  • UseManualVehicleLists: use DieselVehicles and ElectricVehicles.
  • DieselVehicles / ElectricVehicles: spawn names. Add your addon EVs and trucks here.
  • BlacklistedVehicles: spawn names that never use fuel and cannot be filled with a jerrycan or siphon.

Tank sizes

Config.TankSizePerClass = {
    [0] = 45,   -- Compacts
    [1] = 60,   -- Sedans
    [2] = 75,   -- SUVs
    -- ...
    [8] = 15,   -- Motorcycles
    [13] = 0,   -- Cycles (no fuel)
    [15] = 300, -- Helicopters
    [16] = 500, -- Planes
    -- ...
}

Config.TankSizePerVehicle = {
    ['panto'] = 40,
    ['adder'] = 80,
}

Tank size in liters per GTA vehicle class. A larger tank takes more liters to fill and drains slower in percent. TankSizePerVehicle overrides the class for single models. Its keys are the lowercase display name of the model, which for vanilla cars is usually the spawn name. A class with size 0 never uses fuel.

Consumption

Config.FuelConsumption = {
    updateInterval = 1000,
}

Config.FuelUsage = {
    [0.0] = 0.0, [0.1] = 0.0, [0.2] = 0.4, [0.3] = 0.6, [0.4] = 0.8, [0.5] = 1.2,
    [0.6] = 1.6, [0.7] = 2.0, [0.8] = 3.0, [0.9] = 4.0, [1.0] = 5.0,
}

Config.FuelConsumptionPerClass = {
    [0] = 0.5,  -- Compacts
    [1] = 0.7,  -- Sedans
    -- ...
    [15] = 2.5, -- Helicopters
    [16] = 4.0, -- Planes
}

Every updateInterval milliseconds the vehicle the player drives loses fuel while the engine runs. The base value comes from FuelUsage for the current engine RPM, then it is multiplied by the class value from FuelConsumptionPerClass and the depletionRate of the fuel in the tank, and scaled to the tank size. When the tank is empty the engine shuts off. Raise the numbers for faster consumption, lower them for slower.

Still having trouble?

Open a ticket on our Discord. Our team answers around 15 hours a day.

Get help on Discord

On this page