Accueil › Documentation › Hooks · origen_ilegalv2

Hooks · origen_ilegalv2

Le runner expose un ensemble de hooks qui te permettent d’injecter ta propre logique dans le cycle de vie du laboratoire sans modifier les fichiers du cœur. Tous les hooks sont facultatifs : passe-les en troisième argument de LabProcessRunner.Register() côté client, ou utilise les fonctions autonomes côté serveur décrites plus bas.


Hooks client

Les hooks se passent sous forme de table lors de l’enregistrement du laboratoire :

luaclient/lab_heroin.lua
LabProcessRunner.Register('heroin', Config.LabHeroin, {
    onEnter         = function(labType) ... end,
    onExit          = function(labType) ... end,
    onReset         = function() ... end,
    onStageComplete = function(stageId, result) ... end,
})

onEnter(labType)

Appelé immédiatement après que le runner a créé tous les points d’interaction, à chaque fois qu’un joueur entre dans un laboratoire de ce type.

Cas d’usage :

lua
onEnter = function(labType)
    -- Ask the server which plants are already taken
    local takenPlants = lib.callback.await('origen_gang:labs:weed:getTakenPlants', false)
    for _, idx in ipairs(takenPlants or {}) do
        RemovePlantProp(idx)  -- your custom function
    end
end,

onExit(labType)

Appelé après que le runner a supprimé tous les points d’interaction et réinitialisé l’état de production, à chaque fois qu’un joueur sort d’un laboratoire de ce type.

Cas d’usage :

lua
onExit = function(labType)
    DeleteCustomProps()
    StopMyThread()
end,

onReset()

Appelé par le runner chaque fois que le cycle de production est réinitialisé de force : à la sortie, au déchargement du joueur (origen:Client:OnPlayerUnload) et à l’arrêt de la ressource.

Cas d’usage :

lua
onReset = function()
    if trayPropEntity and DoesEntityExist(trayPropEntity) then
        DetachEntity(trayPropEntity, true, true)
        DeleteEntity(trayPropEntity)
        trayPropEntity = nil
    end
end,

onReset est toujours appelé avant onExit. L’état de production (stage, runTimers, etc.) est déjà vidé quand ton hook s’exécute.


onStageComplete(stageId, result)

Appelé après que le runner a fini de traiter une étape (barre de progression terminée, callback du serveur réussi, items remis). S’exécute pour chaque étape, y compris la dernière.

Argument Type Description
stageId string L’ID de l’étape qui vient de se terminer
result table La réponse brute du callback serveur pour cette étape

Champs de result (ce que le serveur a renvoyé) :

Champ Présent sur Description
success toujours true
timers première étape uniquement Minuteurs effectifs après les modificateurs d’améliorations
modifiers première étape uniquement { process_time_mult, output_bonus_pct }
outputs dernière étape Items finaux remis (bonus appliqué)
bonus_triggered dernière étape true si le bonus de sortie s’est activé

Cas d’usage :

lua
onStageComplete = function(stageId, result)
    if stageId == 'grab_tray' then
        -- Attach the tray prop to the player's hand
        AttachTrayToHand()
    elseif stageId == 'smash' then
        -- Detach and delete the tray
        DetachTrayFromHand()
    end
end,

Événements du cycle de vie (client)

Le runner écoute automatiquement ces événements au niveau de la ressource pour chaque laboratoire enregistré. Tu peux aussi les écouter depuis tes propres fichiers de laboratoire pour ajouter une logique personnalisée :

Événement Quand il se déclenche
origen:Lab:OnEnter Le joueur est téléporté à l’intérieur du laboratoire (arg : labType)
origen:Lab:OnExit Le joueur sort du laboratoire (arg : labType)
origen:Client:OnPlayerUnload Le joueur se déconnecte / le personnage est déchargé
lua
-- Example: custom logic on any weed lab entry
AddEventHandler('origen:Lab:OnEnter', function(labType)
    if labType ~= 'weed' then return end
    print('Player entered a weed lab!')
end)

Cycle de vie côté serveur

Le serveur n’a pas de paramètre de table de hooks ; il expose à la place des fonctions et des exports que tu peux appeler depuis d’autres scripts :

LabProcessRunner.ResetPlayerState(labType, source)

Réinitialise de force l’état de production d’un seul joueur pour un type de laboratoire précis. Utilise-le quand un script interrompt la production de l’extérieur (p. ex. une expulsion lors d’un raid).

lua
-- From another resource via export
exports['origen_ilegalv2']:MethLabResetPlayerState(source)
 
-- From inside origen_ilegalv2
LabProcessRunner.ResetPlayerState('meth', source)

LabProcessRunner.ResetAllForSource(source)

Efface l’état de production d’un joueur sur tous les types de laboratoire enregistrés. Appelé automatiquement à la sortie et sur playerDropped ; utilise-le si tu expulses un joueur par code.

lua
LabProcessRunner.ResetAllForSource(source)

LabProcessRunner.GetPlayerState(labType, source) → table | nil

Renvoie l’état de production actuel en mémoire d’un joueur pour un type de laboratoire précis :

lua
local state = LabProcessRunner.GetPlayerState('meth', source)
-- state = { stage, lab_id, timers, modifiers, last_done }
-- nil if not in production
Champ Description
stage ID de l’étape en cours, ou nil entre deux cycles
lab_id ID en base de données de l’instance du laboratoire où se trouve le joueur
timers Minuteurs effectifs (après modificateurs) calculés au début du cycle
modifiers { process_time_mult, output_bonus_pct }
last_done os.time() de la fin du dernier cycle (utilisé pour le cooldown)

exports('GetPlayerLabState', ...) → table | nil

Renvoie le laboratoire dans lequel se trouve actuellement un joueur (défini par les callbacks d’entrée/sortie de server/labs.lua) :

lua
local labState = exports['origen_ilegalv2']:GetPlayerLabState(source)
-- { lab_id, lab_type, bucket, world_exit }
-- nil if the player is not inside any lab

C’est ce que tous les fichiers serveur des laboratoires utilisent pour vérifier que « le joueur est bien dans le bon laboratoire ».


Exports de réinitialisation par laboratoire

Chaque laboratoire intégré enregistre son propre export de réinitialisation nommé, pour la compatibilité externe :

Export Laboratoire
MethLabResetPlayerState(source) Meth
WeedLabResetPlayerState(source) Weed
CokeLabResetPlayerState(source) Coke

Les laboratoires personnalisés que tu ajoutes doivent suivre le même modèle :

luaserver/lab_heroin.lua
exports('HeroinLabResetPlayerState', function(source)
    LabProcessRunner.ResetPlayerState('heroin', source)
end)

Exemple complet de hooks — prop du plateau de meth

Le laboratoire de meth utilise onStageComplete et onReset pour attacher un prop physique de plateau à la main du joueur entre les étapes grab_tray et smash :

luaclient/lab_meth.lua (simplified)
local trayProp = nil
 
local function attachTray(ped)
    local hash = GetHashKey('bkr_prop_meth_tray_02a')
    RequestModel(hash)
    while not HasModelLoaded(hash) do Wait(50) end
    trayProp = CreateObject(hash, 0, 0, 0, true, true, true)
    AttachEntityToEntity(trayProp, ped, GetPedBoneIndex(ped, 28422),
        0.01, -0.2, -0.2, 20.0, 0.0, 0.0, true, true, false, true, 1, true)
    SetModelAsNoLongerNeeded(hash)
end
 
local function detachTray()
    if trayProp and DoesEntityExist(trayProp) then
        DetachEntity(trayProp, true, true)
        DeleteEntity(trayProp)
        trayProp = nil
    end
end
 
LabProcessRunner.Register('meth', Config.LabMeth, {
    onStageComplete = function(stageId, result)
        if stageId == 'grab_tray' then
            attachTray(PlayerPedId())
        elseif stageId == 'smash' then
            detachTray()
        end
    end,
    onReset = function()
        detachTray()
    end,
})