Configurations
Wasabi Ambulance Job V2 (wasabi_ambulance_v2) is extremely configurable with configuration organized between the client, server, and shared between the two.
Client
View Config
local config = {
-------------------------------------------------------------------------------------------------------------
-- FIRST TIME CONFIGURATION NOTE: --
-- * Hopsitals/Facilities can be set up by executing the command: /facilitypanel while in an admin group. --
-------------------------------------------------------------------------------------------------------------
---@NOTE: drawText needs ox_lib context menu currently
interact = "drawText", -- "ox_target" or "qb-target" or "sleepless_interact" or "drawText"
-- When using drawText, you need to use /inspect command to inspect nearby players
-- if using drawText set Options here
drawText = {
maxDistance = 8.0,
defaultInteractDistance = 2.0,
useSprite = true,
sprite = {
dict = "shared",
texture = "emptydot_32",
color = { 28, 100, 184, 255 }
}
},
disableSpawnManager = true, -- Leave as true unless you know what you are doing
enableHealthRegen = false, -- Enable the GTA style health regeneration by setting to true
blips = {
enabled = true, -- Enable hospital blips to ensure easier navigation to the hospital
sprite = 61, -- Sprite of the blip https://docs.fivem.net/docs/game-references/blips/
color = 2, -- Color of the blip https://docs.fivem.net/docs/game-references/blips/
scale = 1.0 -- Scale of the blip
},
death = {
allowedControls = {
-- Controls that are allowed while dead
1, -- LookLeftRight
2, -- LookUpDown
},
lastStand = {
enable = true, -- Enable/disable last stand feature
bleedOutRate = 1, -- Amount of health lost per second while in last stand
}
},
bleeding = {
enabled = true,
bleedStates = {
light = { threshold = 1, damagePerSecond = 1 },
moderate = { threshold = 33, damagePerSecond = 3 },
heavy = { threshold = 66, damagePerSecond = 5 },
}
},
stun = {
enabled = true,
stunDuration = { min = 5, max = 8 }, -- Duration range (in seconds) for stun effect. minimum must be at least 2.8 seconds for the animations to work properly
},
injuries = {
--- status types: bleed, stun, brokenbone, gunshot, fist
cut = {
limbHealthDamage = 100,
statusPerLimb = {
[1] = { status = "bleed", amount = 25 }, -- HEAD
[2] = { status = "bleed", amount = 15 }, -- BODY
[3] = { status = "bleed", amount = 3 }, -- LEFT_ARM
[4] = { status = "bleed", amount = 3 }, -- RIGHT_ARM
[5] = { status = "bleed", amount = 3 }, -- LEFT_LEG
[6] = { status = "bleed", amount = 3 }, -- RIGHT_LEG
}
},
blunt = {
limbHealthDamage = 350,
canBreakBones = true,
statusPerLimb = {
[1] = { status = "stun", amount = 25 },
[2] = { status = "stun", amount = 15 },
[3] = { status = "stun", amount = 3 },
[4] = { status = "stun", amount = 3 },
[5] = { status = "stun", amount = 3 },
[6] = { status = "stun", amount = 3 },
}
},
brokenbone = {
limbHealthDamage = 500,
},
gunshot = {
limbHealthDamage = 250,
canBreakBones = true,
statusPerLimb = {
[1] = { status = "bleed", amount = 25 },
[2] = { status = "bleed", amount = 15 },
[3] = { status = "bleed", amount = 3 },
[4] = { status = "bleed", amount = 3 },
[5] = { status = "bleed", amount = 3 },
[6] = { status = "bleed", amount = 3 },
}
},
fist = {
limbHealthDamage = 10,
statusPerLimb = {
[1] = { status = "stun", amount = 25 },
[2] = { status = "stun", amount = 15 },
[3] = { status = "stun", amount = 3 },
[4] = { status = "stun", amount = 3 },
[5] = { status = "stun", amount = 3 },
[6] = { status = "stun", amount = 3 },
}
},
taser = {
limbHealthDamage = 100,
},
burn = {
limbHealthDamage = 100,
}
},
beds = {
[`v_med_bed2`] = {
inBed = {
posOffset = vec3(0, 0, 1.05),
rotOffset = vec3(0, 0, 180),
model = `v_med_bed2`,
},
outBed = {
posOffset = vec3(0.0, -1.3, 0.0),
rotOffset = vec3(0, 0, 180),
},
animations = {
layDown = {
dict = "anim@gangops@morgue@table@",
anim = "ko_front",
flag = 63,
},
},
},
[`v_med_bed1`] = {
inBed = {
posOffset = vec3(0, 0.15, 1.6),
rotOffset = vec3(0, 0, 175),
model = `v_med_bed1`,
},
outBed = {
posOffset = vec3(0, -1.5, 0.0),
rotOffset = vec3(0, 0, 180),
},
animations = {
layDown = {
dict = "anim@gangops@morgue@table@",
anim = "ko_front",
flag = 63,
},
},
},
[`v_med_emptybed`] = {
inBed = {
posOffset = vec3(0, 0.15, 1.4),
rotOffset = vec3(0, 0, 175),
model = `v_med_bed1`,
},
outBed = {
posOffset = vec3(0, -1.5, 0.0),
rotOffset = vec3(0, 0, 180),
},
animations = {
layDown = {
dict = "anim@gangops@morgue@table@",
anim = "ko_front",
flag = 63,
},
},
}
},
cloakroom = {
enabled = true,
requireDuty = false, -- If true, player must be on duty to access cloakroom
skinScript = "default", -- "default", "qb", or "illenium"
uniforms = {
{
label = "Paramedic",
minGrade = 0,
male = {
clothing = {
{ component = 11, drawable = 250, texture = 0 },
{ component = 8, drawable = 159, texture = 0 },
{ component = 4, drawable = 96, texture = 0 },
{ component = 6, drawable = 25, texture = 0 },
},
props = {}
},
female = {
clothing = {
{ component = 11, drawable = 258, texture = 0 },
{ component = 8, drawable = 187, texture = 0 },
{ component = 4, drawable = 99, texture = 0 },
{ component = 6, drawable = 25, texture = 0 },
},
props = {}
}
},
{
label = "Doctor",
minGrade = 2,
male = {
clothing = {
{ component = 11, drawable = 31, texture = 0 },
{ component = 8, drawable = 31, texture = 0 },
{ component = 4, drawable = 28, texture = 0 },
{ component = 6, drawable = 10, texture = 0 },
},
props = {}
},
female = {
clothing = {
{ component = 11, drawable = 31, texture = 0 },
{ component = 8, drawable = 31, texture = 0 },
{ component = 4, drawable = 28, texture = 0 },
{ component = 6, drawable = 10, texture = 0 },
},
props = {}
}
},
}
}
}
---@ignore
Modules.register('config', config, true)
Server
View Config
local config = {
-------------------------------------------------------------------------------------------------------------
-- FIRST TIME CONFIGURATION NOTE: --
-- * Hopsitals/Facilities can be set up by executing the command: /facilitypanel while in an admin group. --
-------------------------------------------------------------------------------------------------------------
checkForUpdates = true, -- To enable the update checker (recommended)
adminGroups = {
'admin',
'god',
},
--- Treatment Settings
treatment = {
minTreatmentTime = 4, -- Minimum seconds player must be checked in before treatment completes (should match client progress bar)
treatmentCooldown = 30, -- Seconds before same player can check in again (prevents spam healing)
},
shops = {
['medical_general'] = {
name = "Medical Supplies",
inventory = {
{ name = 'medbag', price = 200, label = 'Medical Bag' },
{ name = 'bandage', price = 10, label = 'Bandage' },
{ name = 'water', price = 10, label = 'Water' },
}
}
},
logger = {
enabled = true,
type = 'ox', -- ox, discord
discordWebhook = '', -- Discord webhook URL
}
}
---@ignore
Modules.register('config', config, true)
Shared
View Config
local config = {
-------------------------------------------------------------------------------------------------------------
-- FIRST TIME CONFIGURATION NOTE: --
-- * If not using ox_inventory, set inventoryImagePath to have images show properly. --
-- * Hopsitals/Facilities can be set up by executing the command: /facilitypanel while in an admin group. --
-------------------------------------------------------------------------------------------------------------
debug = false,
inventoryImagePath = "nui://ox_inventory/web/images/",--"nui://ox_inventory/web/images/",
-- QBCore inventory path is "nui://qb-inventory/html/images/"
-- Diagnose Patient
ambulanceJobs = { -- Jobs / groups that can inspect, treat, and revive patients
'ambulance',
'ems',
'doctor',
'admin',
},
--- Inventory Settings for job lockers
personalLocker = {
weight = 50000,
slots = 30
},
-- Death state constants (shared between client and server)
deathState = {
ALIVE = 0,
LAST_STAND = 1,
DEAD = 2,
},
--- Dispatch Settings
--- Supported types: "internal", "none"
--- Future support planned for: "cd_dispatch", "ps-dispatch"
dispatch = {
type = "internal", -- Type of dispatch system to use
allowedJobs = { -- Jobs that can access the dispatch menu (internal only)
'ambulance',
'ems',
'doctor',
},
keybind = 'F6', -- Default keybind for the dispatch menu (internal only)
distressCooldown = 45, -- Cooldown (in seconds) before player can ping EMS again
},
--- Respawn Settings
respawn = {
respawnTime = 10, -- Time (in seconds) before a player can respawn
forcedRespawnTime = 600, -- Time (in seconds) before a player is forced to respawn
wipeItems = true, -- Whether or not to wipe items when respawning
itemsToKeep = { 'water', 'bandage' }, -- these items will be kept when respawning
keepItemsIfNoEMS = true, -- Whether or not to keep items if EMS is not available
},
medicalItems = {
medkit = { healAmount = 300 },
bandage = { healAmount = 150 },
forceps = { healType = "gunshot", healAmount = 50 },
pliers = { healType = "taser", healAmount = 50 },
suture = { healType = "cut", healAmount = 50 },
splint = { healType = "brokenbone", healAmount = 50 },
burncream = { healType = "burn", healAmount = 50 },
icepack = { healType = "fist", healAmount = 50 },
traumakit = { healType = "blunt", healAmount = 50 },
},
---@type table<string, HealingItemConfig>
healingItems = {
['bandage'] = {
healAmount = 25,
remove = 1,
healOverTime = {
amount = 5,
interval = 1000,
duration = 5000,
},
useTime = 3000,
progress = {
label = "Applying bandage...",
useWhileDead = false,
canCancel = true,
disable = {
move = true,
car = true,
combat = true,
},
anim = {
dict = "missmic4",
clip = "michael_tux_fidget",
},
},
statusEffects = {
bleed = {
action = "remove",
amount = 15,
removeChance = 75, -- 75% chance to remove, 25% chance to just pause
pauseDuration = 10000,
},
},
removeItem = true,
},
['medkit'] = {
remove = 1,
healAmount = 50,
healOverTime = {
amount = 10,
interval = 1000,
duration = 10000,
},
useTime = 5000,
progress = {
label = "Using medkit...",
useWhileDead = false,
canCancel = true,
disable = {
move = true,
car = true,
combat = true,
},
anim = {
dict = "mini@repair",
clip = "fixing_a_player",
},
},
statusEffects = {
bleed = {
action = "remove",
amount = 50,
removeChance = 90,
pauseDuration = 15000,
},
},
removeItem = true,
},
['firstaidkit'] = {
remove = 1,
healAmount = 75,
healOverTime = {
amount = 15,
interval = 1500,
duration = 15000,
},
useTime = 7000,
progress = {
label = "Applying first aid...",
useWhileDead = false,
canCancel = true,
disable = {
move = true,
car = true,
combat = true,
},
anim = {
dict = "mini@repair",
clip = "fixing_a_player",
},
},
statusEffects = {
bleed = {
action = "remove",
amount = 100,
removeChance = 100,
},
stun = {
action = "remove",
amount = 50,
},
},
removeItem = true,
},
['painkillers'] = {
remove = 1,
healAmount = 10,
useTime = 2000,
progress = {
label = "Taking painkillers...",
useWhileDead = false,
canCancel = true,
disable = {
move = false,
car = false,
combat = true,
},
anim = {
dict = "mp_suicide",
clip = "pill",
},
},
statusEffects = {
stun = {
action = "pause",
pauseDuration = 30000,
},
},
removeItem = true,
},
['ifak'] = {
remove = 1,
healAmount = 35,
healOverTime = {
amount = 8,
interval = 1000,
duration = 8000,
},
useTime = 4000,
progress = {
label = "Using IFAK...",
useWhileDead = false,
canCancel = true,
disable = {
move = true,
car = true,
combat = true,
},
anim = {
dict = "mini@repair",
clip = "fixing_a_player",
},
},
statusEffects = {
bleed = {
action = "remove",
amount = 35,
removeChance = 85,
pauseDuration = 12000,
},
},
removeItem = true,
},
},
medBag = {
model = `xm_prop_x17_bag_med_01a`,
-- Add offset and bone for the med bag
--offset = { x = 0.0, y = 0.0, z = 0.0 },
--bone = 'bag_med_01a',
items = {
{ 'water', 10, 'Water' }, -- Item, amount, label (Amount will not apply to non-metadata inventories)
{ 'bandage', 10, 'Bandage' },
{ 'medkit', 10, 'Medkit' },
{ 'forceps', 10, 'Forceps' },
{ 'pliers', 10, 'Pliers' },
{ 'suture', 10, 'Suture' },
{ 'splint', 10, 'Splint' },
{ 'burncream', 10, 'Burn Cream' },
{ 'icepack', 10, 'Ice Pack' },
{ 'traumakit', 10, 'Trauma Kit' },
},
},
stretcher = {
enabled = true,
model = `wasabi_stretcher`,
stretcherKey = 38,
allowedJobs = {
'ambulance',
-- 'ems',
-- 'doctor',
},
holdingOffset = {
pos = { x = -0.032, y = -0.716, z = -1.269 },
rot = { x = 16.489, y = 1.863, z = -1.3292 }
},
occupyingOffset = {
pos = { x = 0.0, y = 0.0, z = 1.9 },
rot = { x = 0.0, y = 0.0, z = 180.0 }
},
ambulanceOffsets = {
[`ambulance`] = {
trunkAsBackDoor = false,
pos = { x = 0.15, y = -3.0, z = 0.00 },
rot = { x = -1.3, y = 0.0, z = 90.0 }
},
-- Add more ambulance models here
-- ['ambulance2'] = {
-- trunkAsBackDoor = true,
-- pos = { x = -0.26, y = -1.3, z = 0.3 },
-- rot = { x = -1.3, y = 0.0, z = 360.0 }
-- },
},
},
weaponInjuries = {
-- MELEE: FIST --
[`WEAPON_UNARMED`] = { "fist" },
-- MELEE: BLUNT --
[`WEAPON_KNUCKLE`] = { "blunt" },
[`WEAPON_BAT`] = { "blunt" },
[`WEAPON_BALL`] = { "blunt" },
[`WEAPON_CROWBAR`] = { "blunt" },
[`WEAPON_FLASHLIGHT`] = { "blunt" },
[`WEAPON_GOLFCLUB`] = { "blunt" },
[`WEAPON_HAMMER`] = { "blunt" },
[`WEAPON_NIGHTSTICK`] = { "blunt" },
[`WEAPON_POOLCUE`] = { "blunt" },
[`WEAPON_WRENCH`] = { "blunt" },
[`WEAPON_FALL`] = { "blunt" },
[`WEAPON_RUN_OVER_BY_CAR`] = { "blunt" },
[`WEAPON_RAMMED_BY_CAR`] = { "blunt" },
-- MELEE: CUT --
[`WEAPON_BOTTLE`] = { "cut" },
[`WEAPON_DAGGER`] = { "cut" },
[`WEAPON_HATCHET`] = { "cut" },
[`WEAPON_KNIFE`] = { "cut" },
[`WEAPON_MACHETE`] = { "cut" },
[`WEAPON_BATTLEAXE`] = { "cut" },
[`WEAPON_SWITCHBLADE`] = { "cut" },
[`WEAPON_STONE_HATCHET`] = { "cut" },
-- GUNS --
-- pistols
[`WEAPON_PISTOL`] = { "gunshot" },
[`WEAPON_PISTOL_MK2`] = { "gunshot" },
[`WEAPON_COMBATPISTOL`] = { "gunshot" },
[`WEAPON_PISTOL50`] = { "gunshot" },
[`WEAPON_SNSPISTOL`] = { "gunshot" },
[`WEAPON_HEAVYPISTOL`] = { "gunshot" },
[`WEAPON_APPISTOL`] = { "gunshot" },
[`WEAPON_MACHINEPISTOL`] = { "gunshot" },
[`WEAPON_DOUBLEACTION`] = { "gunshot" },
[`WEAPON_MARKSMANPISTOL`] = { "gunshot" },
[`WEAPON_REVOLVER`] = { "gunshot" },
[`WEAPON_VINTAGEPISTOL`] = { "gunshot" },
-- shotguns
[`WEAPON_PUMPSHOTGUN`] = { "gunshot" },
[`WEAPON_PUMPSHOTGUN_MK2`] = { "gunshot" },
[`WEAPON_MUSKET`] = { "gunshot" },
[`WEAPON_ASSAULTSHOTGUN`] = { "gunshot" },
[`WEAPON_AUTOSHOTGUN`] = { "gunshot" },
[`WEAPON_BULLPUPSHOTGUN`] = { "gunshot" },
[`WEAPON_DBSHOTGUN`] = { "gunshot" },
[`WEAPON_HEAVYSHOTGUN`] = { "gunshot" },
[`WEAPON_SAWNOFFSHOTGUN`] = { "gunshot" },
-- SMGs --
[`WEAPON_SMG`] = { "gunshot" },
[`WEAPON_SMG_MK2`] = { "gunshot" },
[`WEAPON_GUSENBERG`] = { "gunshot" },
[`WEAPON_ASSAULTSMG`] = { "gunshot" },
[`WEAPON_COMBATPDW`] = { "gunshot" },
[`WEAPON_MICROSMG`] = { "gunshot" },
[`WEAPON_MINISMG`] = { "gunshot" },
-- MACHINE GUNS --
[`WEAPON_COMBATMG`] = { "gunshot" },
[`WEAPON_MG`] = { "gunshot" },
-- RIFLES --
[`WEAPON_CARBINERIFLE`] = { "gunshot" },
[`WEAPON_CARBINERIFLE_MK2`] = { "gunshot" },
[`WEAPON_COMPACTRIFLE`] = { "gunshot" },
[`WEAPON_ADVANCEDRIFLE`] = { "gunshot" },
[`WEAPON_ASSAULTRIFLE`] = { "gunshot" },
[`WEAPON_BULLPUPRIFLE`] = { "gunshot" },
[`WEAPON_SPECIALCARBINE`] = { "gunshot" },
[`WEAPON_MARKSMANRIFLE`] = { "gunshot" },
-- SNIPERS --
[`WEAPON_HEAVYSNIPER`] = { "gunshot" },
[`WEAPON_SNIPERRIFLE`] = { "gunshot" },
-- TASER --
[`WEAPON_STUNGUN`] = { "taser" },
-- BURN / EXPLOSIVES --
[`WEAPON_FIRE`] = { "burn" },
[`WEAPON_BZGAS`] = { "burn" },
[`WEAPON_FIREEXTINGUISHER`] = { "burn" },
[`WEAPON_FIREWORK`] = { "burn" },
[`WEAPON_FLARE`] = { "burn" },
[`WEAPON_FLAREGUN`] = { "burn" },
[`WEAPON_GRENADE`] = { "burn" },
[`WEAPON_GRENADELAUNCHER`] = { "burn" },
[`WEAPON_HOMINGLAUNCHER`] = { "burn" },
[`WEAPON_MOLOTOV`] = { "burn" },
[`WEAPON_PETROLCAN`] = { "burn" },
[`WEAPON_PIPEBOMB`] = { "burn" },
[`WEAPON_PROXMINE`] = { "burn" },
[`WEAPON_RPG`] = { "burn" },
[`WEAPON_SMOKEGRENADE`] = { "burn" },
[`WEAPON_STICKYBOMB`] = { "burn" },
[`WEAPON_EXPLOSION`] = { "burn" },
},
--- Garage Settings
--- Supported types: "internal"
--- Future support planned for: "wasabi_garage", "jg_advancedgarage", "cd_garage", "ps_garage",
--- "qb-garage", "esx_garage"
garages = {
enabled = true,
requireDuty = false, -- If true, player must be on duty to access garage
type = 'internal', -- Type of garage system to use
-- If type = 'internal', set the garage vehicle options here
account = 'bank', -- String, account to use for purchasing vehicles
options = {
ambulance = { -- Job name, this will be used to correlate when accessing the garage
ownedVehicles = true, -- If true, the garage will give ownership of vehicle and allow storage of owned vehicles
plateFormat = 'EMS###', -- String, format of the plate, use # for random letters and numbers(8 characters max)
onlyNumbers = true, -- Boolean, if true, the plate will only contain numbers for the # characters
recoveryCost = 200, -- Int, cost to recover a vehicle when not stored in garage (If it is lost or stolen)
ranks = { -- Table, ranks that can access the garage
[1] = { -- Int, rank to access the garage
vehicles = { -- Table | nil, vehicles that can be accessed by the rank | nil if no vehicles are available for the rank
['ambulance'] = { -- String, vehicle model game name that will correlate when accessing the garage
label = 'Ambulance', -- String, label of the vehicle that will be displayed to the player
price = 1000, -- Int | nil | false, price or false if the vehicle is free
type = 'automobile', -- String, type of the vehicle, can be 'automobile', 'bike', 'boat', 'heli', 'plane'
maxUpgrades = false, -- Boolean, true if the vehicle has max upgrades, false if the vehicle does not have max upgrades
},
['sultan'] = { -- This is example of available optional vehicle options
label = 'Sultan',
price = 2000,
type = 'automobile', -- String, type of the vehicle, can be 'automobile', 'bike', 'boat', 'heli', 'plane'
paint = {
primary = 35, -- Int | nil | false, primary color index or false (https://docs.fivem.net/docs/game-references/vehicle-references/vehicle-colours/)
secondary = 0, -- Int | nil | false, secondary color index or false
},
maxUpgrades = false, -- Boolean, true if the vehicle has max upgrades, false if the vehicle does not have max upgrades
livery = 0, -- Int | nil | false, livery index or false if no livery is available/needed to set for the vehicle
extras = { --Table | nil | false, extras to set for the vehicle | nil if no extras are available/needed to set for the vehicle }
[1] = false, -- Boolean, true if the extra is enabled, false if the extra is disabled
[2] = false,
[3] = false,
[4] = false,
[5] = false,
}
},
},
helicopters = { -- Table | nil, helicopters that can be accessed by the rank | nil if no helicopters are available for the rank
['polmav'] = { -- String, helicopter model game name that will correlate when accessing the garage
label = 'Medic Chopper', -- String, label of the helicopter that will be displayed to the player
price = 1000, -- Int | nil | false, price or false if the helicopter is free
type = 'heli', -- String, type of the helicopter, can be 'heli', 'plane'
livery = 1, -- Int | nil | false, livery index or false if no livery is available/needed to set for the vehicles
}
},
},
[2] = {
vehicles = {
['ambulance'] = {
label = 'Ambulance',
price = 1000,
type = 'automobile',
},
},
helicopters = {
['polmav'] = {
label = 'Medic Chopper',
price = 1000,
type = 'heli',
livery = 1,
}
},
},
},
},
-- Example of how to add a new job to the garage:
-- sheriff = {
-- ownedVehicles = false,
-- ranks = {
--- [1] = {
-- vehicles = {
-- ['sheriff'] = {
-- label = 'Sheriff Cruiser',
-- price = 1000,
-- type = 'automobile',
-- },
-- },
-- helicopters = nil
-- },
-- [2] = {
-- vehicles = {
-- ['sheriff'] = {
-- label = 'Sheriff Cruiser',
-- price = 1000,
-- type = 'automobile',
-- },
-- },
-- helicopters = {
-- ['sheriffmov'] = {
-- label = 'Sheriff Helicopter',
-- price = 1000,
-- type = 'heli',
-- }
-- }
-- },
-- },
-- },
}
},
enviMedic = { -- if you use Envi-Medic AI Ambulance System, set this to true - https://envi-scripts.tebex.io/package/5969648
enabled = false,
maximumEMSCount = 0, -- AI Medic is available only when EMS online is at most this number (0 = when no EMS online, 5 = when 5 or less EMS online) - Check Envi-Medic config and match up!
},
}
---@ignore
Modules.register('config', config, true)