Developer
Overview
Other scripts read and change radiation through server and client exports, react through the hooks in open/, and read the local level from a state bag. The server keeps the real value: it accepts only increases from clients and handles every decrease itself. SetRadiation, AddRadiation and RemoveRadiation accept calls only from resources listed in Config.AdminExportResources, so add yours there. GetPlayerRadiation is open to any resource.
Server Exports
Radiation State
1local radiation = exports.ml_radiation:GetPlayerRadiation(source)
2exports.ml_radiation:SetRadiation(source, 500)
3exports.ml_radiation:AddRadiation(source, 100)
4exports.ml_radiation:RemoveRadiation(source, 200)
5exports.ml_radiation:RemoveRadiation(source)
6exports.ml_radiation:ResetRadiation(source)GetPlayerRadiation(source): current radiation level, from 0 toMaxRadiationSetRadiation(source, level): Sets radiation to a specific value. Clamped between 0 andMaxRadiation. Each call is logged toServerConfig.AdminWebhookAddRadiation(source, amount): Adds radiation to the current levelRemoveRadiation(source, amount?): Removes radiation. Ifamountis omitted, removes all radiationResetRadiation(source): Sets radiation to zero and saves it. Returnstrueif the player was loaded. Rate limited per player, so a repeat call right after returnsfalse. Not restricted byConfig.AdminExportResources
Client Exports
1local radiation = exports.ml_radiation:GetRadiation()
2local ceiling = exports.ml_radiation:GetMaxRadiation()
3
4exports.ml_radiation:PauseRadiation()
5exports.ml_radiation:ResumeRadiation()
6local paused = exports.ml_radiation:IsRadiationPaused()GetRadiation(): Returns the local player's current radiation levelGetMaxRadiation(): ReturnsConfig.PlayerEffects.MaxRadiationPauseRadiation(): Stops contamination, damage, effects and sounds, and closes the Geiger interfaceResumeRadiation(): Restarts from the level held before the pauseIsRadiationPaused(): Returnstruewhile paused
State Bags
The radiation level is written to the player's own state bag, by the server on change and by the client every second. It is not replicated, so each client reads only its own value:
1local radiation = LocalPlayer.state.radiationReadable from the local player's own client scripts without exports.
Server Handlers
Located in open/server.lua.
Item Control
1function OpenServer.BeforeGiveItem(src, item, amount)
2 return true -- return false to block
3endRuns before a cure or immunity item is consumed. Return false to block it.
Action Lifecycle
1function OpenServer.OnActionComplete(src, actionType, data)
2endRuns after a cure or immunity item is used.
Client Handlers
Located in open/client.lua.
Interaction
1function OpenClient.BeforeOpenUI(data)
2 return true -- return false to block
3endCalled before the overlay counter opens. Return false to block it. The 3D device does not call it.
Shared Handlers
Located in open/shared.lua.
1function OpenHandlers.OnPlayerAction(src, data)
2 return true -- return false to block
3end
4
5function OpenHandlers.ValidateAction(src, actionType)
6 return true -- return false to block
7endOnPlayerAction: runs after a cure or immunity item is used, with the action type and item. Its return value is ignoredValidateAction: runs before a cure or immunity item is used. Returnfalseto block it
Commands
/movegeiger: moves the on-screen counter while it is open. The 3D device ignores it/resetgeigerpos: Reset Geiger UI position to defaults/setradiation [level]: sets your own radiation, from 0 to 1000. It exists only withConfig.Debug = trueand needs a group inServerConfig.AdminPermissions
Examples
1local rad = exports.ml_radiation:GetPlayerRadiation(source)
2if rad > 500 then
3 Bridge.NotifyPlayer(source, 'warning', 'High radiation detected!')
4end1CreateThread(function()
2 while true do
3 local rad = LocalPlayer.state.radiation or 0
4 if rad > 750 then
5 Bridge.Notify('Radiation critical', 'error')
6 end
7 Wait(5000)
8 end
9end)1function OpenClient.BeforeOpenUI(data)
2 local zone = GetNameOfZone(GetEntityCoords(cache.ped))
3 if zone == 'AIRP' then
4 Bridge.Notify('Cannot use Geiger here', 'error')
5 return false
6 end
7 return true
8end1exports.ml_radiation:RemoveRadiation(source)Config.OnDeath covers this when the framework reports the player as dead. Use the exports for a downed state that keeps the ped alive.
1AddEventHandler('yourAmbulance:playerDowned', function()
2 exports.ml_radiation:PauseRadiation()
3end)
4
5AddEventHandler('yourAmbulance:playerRevived', function()
6 exports.ml_radiation:ResumeRadiation()
7end)For a New Life reset, call the server export:
1RegisterNetEvent('yourAmbulance:newLife', function()
2 exports.ml_radiation:ResetRadiation(source)
3end)