Basic understanding of FiveM server setup and resource management
An up-to-date version of ox_lib
1. Introduction
Envi-Medic is a comprehensive medical assistance system for FiveM servers. It offers a wide range of customizable features to create a realistic and immersive emergency medical service experience.
/callmedic [server id]: Call an ambulance for yourself or another player
/cancelmedic: Cancel an ambulance that's on the way to you
Client Exports
exports['envi-medic']:SendHelp(): Sends an ambulance to the player
exports['envi-medic']:CancelHelp(): Cancels the ambulance if it's on the way
exports['envi-medic']:IsWalkingToAmbulance(): Returns true if the player is walking to the ambulance
exports['envi-medic']:IsInAmbulance(): Returns true if the player is in the ambulance
exports['envi-medic']:IsOnCooldown(): Returns true if the player is on cooldown
exports['envi-medic']:GetMedicPedNetID(): Returns the net ID of the medic ped
exports['envi-medic']:GetAmbulanceNetID(): Returns the net ID of the ambulance
3. Debug and Failsafe Settings
Config.DebugZones: Enable to visualize zones for testing
Config.FailSafeMode: Enable timeouts for actions to prevent stuck scenarios
Configurable timeouts for various stages of the medical assistance process
4. Core Configuration
Config.AutoMedicCleanUp: Automatically delete medic and ambulances after a set time
Config.UltimateTimeOut: Force despawn ambulance and use a "magic ped" to revive player
Config.RemoveAllItemsOnMedicRevive: Option to remove all items on revive
Config.RemoveCertainItemsOnMedicRevive: Option to remove specific items on revive
5. Medic and Ambulance Settings
Configurable ambulance and medic models
Customizable spawn distance and arrival parameters
Options for invincible medics and ambulances
Ambulance driving style configuration
Config.AmbulanceModel = `ambulance` -- Model to spawn for the ambulance [ must be in `ticks` like `ambulance` (not 'ambulance') ]
Config.MedicModel = `s_m_m_paramedic_01` -- Model to spawn for the medic [ must be in `ticks` like `s_m_m_paramedic_01` (not 's_m_m_paramedic_01') ]
Config.InvincibleMedic = true -- Set to true if you want the medic/ambulance to be invincible
Config.AmbulanceDriveFlag = 787004 -- Driving style for the ambulance to get to the player -- see more here: https://vespura.com/fivem/drivingstyle/ -- [[ NEW - UPDATED FLAG ]]
6. Hospital and Revive Settings
Configurable hospital slow-down and parking area radius
Option to always take players to the hospital or revive on the spot
Wasabi Crutch system integration for post-revive effects
Config.HospitalSlowDownAreaRadius = 40.0 -- Radius to check for the ambulance arriving at the hospital - if the player enters this radius the ambulance will slow down
Config.HospitalParkingAreaRadius = 15.0 -- Radius to check for the ambulance pulling into the hospital - if the player enters this radius they will revive (should be smaller than the slow down radius)
Config.AlwaysTakeToHosptial = false -- Set to true if you want to always take the player to the closest hospital when they are revived
-- Set to false if you want to take the player to be revived on the spot and free to walk away
Config.WasabiCrutch = {
enabled = false, -- Set to true if you want to use the wasabi-crutch system on final revive (edit in ReviveEvent below)
type = 'crutch', -- 'crutch' or 'chair'
time = 10, -- Time in mins before the crutch/chair despawns
}
7. Job and Payment Settings
Job-locked functionality with configurable job list
Online job check to prevent calling when real medics are available
Configurable payment types and costs for revival
Society fund integration
Config.JobLocked = false -- Set to true if you want to lock the command to only allow jobs in the Config.Jobs table below
-- If set to false it will allow anyone to use it to call EMS
Config.Jobs = { -- ['job_name'] = MinimumGrade,
['police'] = 2,
['ambulance'] = 2,
}
Config.JobToCheck = 'ambulance' -- The job to check for
Config.JobToCheckAmountOnline = 1 -- If there is this amount of people online with the job, you can't call a medic.
Config.PaymentType = 'bank' -- 'cash' / 'bank'
Config.ReviveCostSuccessfulSkillCheck = 3000 -- How much it costs to be revived if you spawn back in the hospital (if AlwaysTakeToHosptial is set to true and you pass the minigame)
Config.ReviveCostFailedSkillCheck = 5000 -- How much it costs to be revived if you spawn back in the hospital (if you fail the minigame) -- will default to this if you do not use skillcheck or if AlwaysTakeToHosptial is set to false
Config.Society = 'ambulance' -- Name of Society to send funds to - set to false to disable
8. Animation and Cinematic Settings
Toggle for cinematic mode during revival
Advanced animation options with customizable offsets
Player control disable option during transport
Config.CinematicMode = true -- Set to true if you want the camera to go into cinematic mode when you are being revived
-- Set to false if you want the camera to stay where it is when you are being revived
Config.AdvancedAnimations = true -- Set to true if you want to use the advanced animations (sometimes onesync will break these)
-- Set to false if you want to use the basic animations
Config.DisablePlayerControls = true -- Set to true if you want to disable player controls when they are being revived and transported to the hospital
-- Set to false if you want to allow players to move around when they are being transported to the hospital
9. Minigame and Skill Check
Optional minigame for revival process
Config.MiniGame = false -- Set to true if you want to use the minigame when you are being revived
Config.ReviveCostSuccessfulSkillCheck = 3000 -- How much it costs to be revived if you spawn back in the hospital (if AlwaysTakeToHosptial is set to true and you pass the minigame)
Config.ReviveCostFailedSkillCheck = 5000 -- How much it costs to be revived if you spawn back in the hospital (if you fail the minigame) -- will default to this if you do not use skillcheck or if AlwaysTakeToHosptial is set to false
10. Blacklist Areas and Drop-off Spots
Define areas where ambulances won't respond
Configurable hospital drop-off and respawn locations
Config.BlacklistAreas = { -- Areas that are blacklisted, ambulance will NOT come to a player in these areas
['Hospital Area'] = { area = vec4(1140.0322, -1446.7982, 34.3813, 192.7532), radius = 50.0 },
['Cayo Perico'] = { area = vec4(5034.0801, -5110.3999, 4.9121, 258.0274), radius = 1500.0 },
}
Config.DropOffSpots = { -- Where the ambulance will take you - it should always find the closest one
--['St Feiacre Hospital'] = { dropOff = vec4(1140.0322, -1446.7982, 34.3813, 192.7532), respawnSpot = vec4(1125.2919, -1527.3180, 35.3501, 258.0274)},
['St Feiacre Hospital'] = { dropOff = vec4(1120.0826, -1517.0491, 34.6926, 86.2999), respawnSpot = vec4(1149.4230, -1529.0354, 35.3748, 324.1485)},
}
11. Config Animation Settings
Config.AnimationOffsetZ = -0.9 -- This is the offset for the animation when the medic is reviving the player - play with this setting to get the right position if you ambulancejob causes the medic to be high or low during anims - default is -0.9 - negative number for lower, number for higher
Config.AnimationTime = 1000 -- This is an addition for the Wait time for animation syncing issues. Adjust this for your server if the animations are out of sync
12. Arrival Settings
Config.ArrivalZoneRadius = 100.0 -- Radius to check for the ambulance arriving at the player - if the player leaves this radius the ambulance will leave -- [[ MUST HAVE THE .0 AT THE END ]]
Config.ArrivalDistance = 18.0 -- How close the ambulance needs to be to the player before it stops and the medic gets out
13. Language Configuration
Extensive language configuration for all script messages and prompts.
Config.Lang = {
ambulance_called = "An ambulance has been called for you!",
ambulance_timeout = "The ambulance has timed out",
ambulance_busy = "We're too busy right now.. Call back later!",
ambulance_area_blacklisted = "Doesn't look like we can come to that area!",
ambulance_area_blacklisted2 = "Sorry, we can\'t go to that area. Call back later.",
ambulance_water = "Sorry, we hate water! - Try again later!",
ambulance_dispatched = "An ambulance has been dispatched!",
ambulance_help_arrived = "Help has arrived!",
ambulance_resuscitated = "You have been successfully resuscitated!",
ambulance_transported = "You have been resuscitated and need to be transported to the hospital!",
ambulance_next_stop = "Next Stop - ",
too_many_medics = "There are too many Medical Professionals on duty to call for local medical assistance",
unauthorized_medical_call = "You are not authorized to call for medical",
invalid_server_id = "We can\'t find any active citizens from the ID you provided! Please call back later.",
medical_treatment_paid = 'You paid $%s for Medical Treatment',
ambulance_no_pay = 'You can\'t afford your Medical Bills.. Get a job, you bum!',
ambulance_left_area = 'You left the area and the ambulance has left!',
ambulance_not_dead = 'It doesn\'t sound like the patient needs Emergency Medical Assistance?!',
no_phone = 'You don\'t have a phone to call for help!',
ambulance_ultimate_failsafe = 'KIFFLOM! The ambulance has failed to arrive, you will be revived by the power of Epsilon!',
ambulance_ultimate_failsafe_healing = 'Baninishing Demons...',
-- NEW --
keep_items = 'You have been revived but have lost some items.',
}
14. ESX_Ambulance replacement
RegisterNetEvent('esx_ambulancejob:revive')
AddEventHandler('esx_ambulancejob:revive', function(fromMedic)
local playerPed = PlayerPedId()
local coords = GetEntityCoords(playerPed)
TriggerServerEvent('esx_ambulancejob:setDeathStatus', false)
DoScreenFadeOut(800)
while not IsScreenFadedOut() do
Wait(50)
end
local formattedCoords = {x = ESX.Math.Round(coords.x, 1), y = ESX.Math.Round(coords.y, 1), z = ESX.Math.Round(coords.z, 1)}
RespawnPed(playerPed, formattedCoords, 0.0)
isDead = false
ClearTimecycleModifier()
SetPedMotionBlur(playerPed, false)
ClearExtraTimecycleModifier()
EndDeathCam()
DoScreenFadeIn(800)
if fromMedic then
FreezeEntityPosition(playerPed, true)
Wait(3000)
FreezeEntityPosition(playerPed, false)
end
end)
15. Additional Features
Phone requirement check for calling ambulance
QBVehicleKeys integration
Custom vehicle lock/unlock functions
Automatic resource detection for revive and fuel events
Wasabi Crutch system integration for post-revive effects
Config.CheckForPhone = false -- Set to true if you want to check if the player has a phone before they can call for help
-- Set to false if you want to allow anyone to call for help regardless if they have a phone or not
Config.PhoneItems = { 'phone', 'phone2', } -- Items to check for if CheckForPhone is set to true (supports multiple items)
Config.QBVehicleKeys = true -- Set to true if you want to use the QBVehicleKeys script to lock/unlock the ambulance
-- Set to false if you want to use the custom lock/unlock functions below
function CustomUnlockVehicleEvent(ambulance)
end
function CustomLockVehicleEvent(ambulance)
end
local reviveEvent = nil
local fuelEvent = nil
CreateThread(function()
if GetResourceState('qb-ambulancejob') == 'started' then
reviveEvent = 'hospital:client:Revive'
return
end
if GetResourceState('esx_ambulancejob') == 'started' then
reviveEvent = 'esx_ambulancejob:revive'
return
end
if GetResourceState('wasabi_ambulance') == 'started' then
reviveEvent = 'wasabi_ambulance:revive'
return
end
if GetResourceState('brutal_ambulancejob') == 'started' then
reviveEvent = 'brutal_ambulancejob:revive'
return
end
if GetResourceState('qbx_medical') == 'started' then
reviveEvent = 'qbx_medical:client:playerRevived'
return
end
if GetResourceState('ak47_ambulancejob') == 'started' then
reviveEvent = 'ak47_ambulancejob:revive'
return
end
if GetResourceState('osp_ambulance') == 'started' then
reviveEvent = 'hospital:client:Revive'
return
end
print('ERROR: No Ambulance Job Detected - Please add custom ReviveEvent in config.lua')
reviveEvent = nil
end)
CreateThread(function()
if GetResourceState('LegacyFuel') == 'started' then
fuelEvent = 'LegacyFuel'
return
end
if GetResourceState('cdn-fuel') == 'started' then
fuelEvent = 'cdn-fuel'
return
end
if GetResourceState('BigDaddy-Fuel') == 'started' then
fuelEvent = 'BigDaddy-Fuel'
return
end
if GetResourceState('ps-fuel') == 'started' then
fuelEvent = 'ps-fuel'
return
end
if GetResourceState('okokGasStation') == 'started' then
fuelEvent = 'okokGasStation'
return
end
if GetResourceState('qs-fuelstations') == 'started' then
fuelEvent = 'qs-fuelstations'
return
end
end)
function ReviveEvent(finalRevive)
if reviveEvent == nil then
print('ERROR: No Ambulance Job Detected - Please add custom Revive Event in config.lua')
return
end
if Config.FreezeOnRevive then
FreezeEntityPosition(cache.ped, true)
end
TriggerEvent(reviveEvent, cache.ped)
if finalRevive then
-- do additional things here
if Config.WasabiCrutch.enabled then
if Config.WasabiCrutch.enabled then
if Config.WasabiCrutch.type == 'crutch' then
exports.wasabi_crutch:SetCrutchTime(PlayerId(), Config.WasabiCrutch.time)
elseif Config.WasabiCrutch.type == 'chair' then
exports.wasabi_crutch:SetChairTime(PlayerId(), Config.WasabiCrutch.time)
end
end
end
end
end
function FuelEvent(ambulance)
if fuelEvent and GetResourceState('ox_fuel') ~= 'started' then
exports[fuelEvent]:SetFuel(ambulance, 100)
return
elseif GetResourceState('ox_fuel') == 'started' then
Entity(ambulance).state.fuel = 100.0
return
end
print('ERROR: No Fuel Resource Detected - Please add custom Fuel Event in config.lua')
fuelEvent = nil
end
Remember to adjust these settings carefully to balance your server's gameplay experience. This comprehensive documentation covers the main features of the Envi-Medic system, providing both server administrators and players with a detailed understanding of its capabilities and configuration options.