Inicio › Documentación › Hooks · origen_ilegalv2

Hooks · origen_ilegalv2

El runner expone un conjunto de hooks que te permiten inyectar lógica propia en el ciclo de vida del laboratorio sin modificar los ficheros del núcleo. Todos los hooks son opcionales: pásalos como tercer argumento de LabProcessRunner.Register() en el cliente, o usa las funciones independientes del servidor que se describen más abajo.


Hooks del cliente

Los hooks se pasan como una tabla al registrar el laboratorio:

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)

Se llama inmediatamente después de que el runner cree todos los puntos de interacción, cada vez que un jugador entra en un laboratorio de este tipo.

Casos de uso:

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)

Se llama después de que el runner elimine todos los puntos de interacción y reinicie el estado de producción, cada vez que un jugador sale de un laboratorio de este tipo.

Casos de uso:

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

onReset()

El runner la llama siempre que el ciclo de producción se reinicia a la fuerza: al salir, al descargar al jugador (origen:Client:OnPlayerUnload) y al detener el recurso.

Casos de uso:

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

onReset se llama siempre antes que onExit. El estado de producción (stage, runTimers, etc.) ya está limpio cuando se ejecuta tu hook.


onStageComplete(stageId, result)

Se llama después de que el runner termine de procesar una fase (barra de progreso completada, callback del servidor con éxito, items entregados). Se ejecuta en todas las fases, incluida la última.

Argumento Tipo Descripción
stageId string El ID de la fase que acaba de completarse
result table La respuesta original del callback del servidor para esta fase

Campos de result (lo que devolvió el servidor):

Campo Presente en Descripción
success siempre true
timers solo la primera fase Temporizadores efectivos tras los modificadores de mejoras
modifiers solo la primera fase { process_time_mult, output_bonus_pct }
outputs última fase Items finales entregados (con el bonus aplicado)
bonus_triggered última fase true si se activó el bonus de salida

Casos de uso:

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,

Eventos del ciclo de vida (cliente)

El runner escucha automáticamente estos eventos a nivel de recurso para cada laboratorio registrado. También puedes escucharlos desde tus propios ficheros de laboratorio para añadir lógica personalizada:

Evento Cuándo se dispara
origen:Lab:OnEnter El jugador es teletransportado al interior del laboratorio (arg: labType)
origen:Lab:OnExit El jugador sale del laboratorio (arg: labType)
origen:Client:OnPlayerUnload El jugador se desconecta / se descarga el personaje
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)

Ciclo de vida en el servidor

El servidor no tiene un parámetro de tabla de hooks; en su lugar expone funciones y exports que puedes llamar desde otros scripts:

LabProcessRunner.ResetPlayerState(labType, source)

Reinicia a la fuerza el estado de producción de un solo jugador para un tipo de laboratorio concreto. Úsalo cuando un script interrumpe la producción desde fuera (p. ej. la expulsión por una redada).

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

LabProcessRunner.ResetAllForSource(source)

Limpia el estado de producción de un jugador en todos los tipos de laboratorio registrados. Se llama automáticamente al salir y en playerDropped; úsalo si expulsas a un jugador mediante código.

lua
LabProcessRunner.ResetAllForSource(source)

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

Devuelve el estado de producción actual en memoria de un jugador para un tipo de laboratorio concreto:

lua
local state = LabProcessRunner.GetPlayerState('meth', source)
-- state = { stage, lab_id, timers, modifiers, last_done }
-- nil if not in production
Campo Descripción
stage ID de la fase actual, o nil si está entre ciclos
lab_id ID en la base de datos de la instancia del laboratorio en la que está el jugador
timers Temporizadores efectivos (tras los modificadores) calculados al inicio del ciclo
modifiers { process_time_mult, output_bonus_pct }
last_done os.time() de cuando se completó el último ciclo (se usa para el cooldown)

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

Devuelve en qué laboratorio está actualmente un jugador (lo establecen los callbacks de entrada/salida 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

Es lo que usan todos los ficheros de servidor de los laboratorios para validar que «el jugador está realmente en el laboratorio correcto».


Exports de reinicio por laboratorio

Cada laboratorio integrado registra su propio export de reinicio con nombre, por compatibilidad externa:

Export Laboratorio
MethLabResetPlayerState(source) Meta
WeedLabResetPlayerState(source) Marihuana
CokeLabResetPlayerState(source) Cocaína

Los laboratorios personalizados que añadas deben seguir el mismo patrón:

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

Ejemplo completo de hooks — prop de la bandeja de meta

El laboratorio de meta usa onStageComplete y onReset para pegar un prop físico de bandeja a la mano del jugador entre las fases grab_tray y 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,
})