Developer

3 min readUpdated 2 weeks ago

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

lua
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 to MaxRadiation
  • SetRadiation(source, level): Sets radiation to a specific value. Clamped between 0 and MaxRadiation. Each call is logged to ServerConfig.AdminWebhook
  • AddRadiation(source, amount): Adds radiation to the current level
  • RemoveRadiation(source, amount?): Removes radiation. If amount is omitted, removes all radiation
  • ResetRadiation(source): Sets radiation to zero and saves it. Returns true if the player was loaded. Rate limited per player, so a repeat call right after returns false. Not restricted by Config.AdminExportResources

Client Exports

lua
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 level
  • GetMaxRadiation(): Returns Config.PlayerEffects.MaxRadiation
  • PauseRadiation(): Stops contamination, damage, effects and sounds, and closes the Geiger interface
  • ResumeRadiation(): Restarts from the level held before the pause
  • IsRadiationPaused(): Returns true while 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:

lua
1local radiation = LocalPlayer.state.radiation

Readable from the local player's own client scripts without exports.

Server Handlers

Located in open/server.lua.

Item Control

open/server.lua
1function OpenServer.BeforeGiveItem(src, item, amount)
2    return true -- return false to block
3end

Runs before a cure or immunity item is consumed. Return false to block it.

Action Lifecycle

open/server.lua
1function OpenServer.OnActionComplete(src, actionType, data)
2end

Runs after a cure or immunity item is used.

Client Handlers

Located in open/client.lua.

Interaction

open/client.lua
1function OpenClient.BeforeOpenUI(data)
2    return true -- return false to block
3end

Called before the overlay counter opens. Return false to block it. The 3D device does not call it.

Shared Handlers

Located in open/shared.lua.

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
7end
  • OnPlayerAction: runs after a cure or immunity item is used, with the action type and item. Its return value is ignored
  • ValidateAction: runs before a cure or immunity item is used. Return false to 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 with Config.Debug = true and needs a group in ServerConfig.AdminPermissions

Examples

your_script/server.lua
1local rad = exports.ml_radiation:GetPlayerRadiation(source)
2if rad > 500 then
3    Bridge.NotifyPlayer(source, 'warning', 'High radiation detected!')
4end
your_script/client.lua
1CreateThread(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)
open/client.lua
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
8end
your_script/server.lua
1exports.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.

lua
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:

lua
1RegisterNetEvent('yourAmbulance:newLife', function()
2    exports.ml_radiation:ResetRadiation(source)
3end)