PVP-safe death¶
Permite que otros scripts (PVP, arenas, gulag, minijuegos, eventos staff) suspendan el flujo de muerte de nb-ambulance sin tocar el codigo. El jugador nunca entra en laststand ni ve la pantalla de muerte mientras el flag este activo — solo se restaura su HP en sitio y se dispara un evento que tu script puede capturar para correr su propio respawn.
Por que existe¶
En servidores con muchos scripts de combate (battle royale, deathmatch, eventos), el flujo de muerte de un ambulancejob normal interrumpe la partida: el jugador entra en writhe loop, se le obliga a respawnear en hospital, paga tarifa, etc.
nb-ambulance da tres mecanismos para que tu script de PVP gane el control sobre la muerte de un jugador especifico, sin race conditions.
Mecanismo 1: Export client¶
Desde el script PVP, en el client del jugador afectado:
-- al entrar a la arena
exports['nb-ambulance']:setDeathDisabled(true)
-- al salir
exports['nb-ambulance']:setDeathDisabled(false)
Equivalente server-side:
Internamente setea el statebag nb_disableDeath y nb_disableDeath_manual (asi las zonas auto no lo limpian al salir).
Mecanismo 2: Statebag directo¶
Si prefieres no depender del export:
-- server
Player(src).state:set('nb_disableDeath', true, true)
-- client (de tu propio jugador)
LocalPlayer.state:set('nb_disableDeath', true, true)
nb-ambulance lee el statebag al momento de la muerte. Si esta true, intercepta antes de entrar en laststand:
SetEntityHealth(ped, 200)ClearPedBloodDamage(ped)SetPlayerInvincible(false)- Dispara
nb-ambulance:client:deathInterceptedpara que tu script tome el relevo.
Mecanismo 3: Zonas configurables¶
Esferas en el mapa que activan el flag automaticamente al entrar y lo desactivan al salir.
Config.Pvp = {
Zones = {
{ coords = vec3(2440.0, 4970.0, 47.0), radius = 60.0, label = 'sandy_arena' },
{ coords = vec3(-1100.0, 250.0, 70.0), radius = 80.0, label = 'mansion_dm' },
},
ZoneCheckInterval = 750, -- ms
RestoreHealth = 200,
NotifyZoneTransitions = true, -- toast al entrar/salir
}
Util para arenas estaticas. Las zonas y los flags manuales coexisten — si entras a una zona y luego sales, las llamadas manuales setDeathDisabled(true) siguen activas.
Capturar la muerte interceptada¶
Cuando nb-ambulance intercepta, dispara nb-ambulance:client:deathIntercepted en el cliente afectado:
AddEventHandler('nb-ambulance:client:deathIntercepted', function(payload)
-- payload = { weapon = hash, killer = serverId }
-- corre tu propio flujo de respawn / muerte
DoMyArenaRespawn()
end)
Esto te da el "killer + weapon" que ya capturo el listener de damage de nb-ambulance, asi no tienes que duplicar el listener en tu script.
Ejemplo completo: minijuego de boxeo¶
-- server: tu-script/server.lua
RegisterNetEvent('boxing:start', function()
local src = source
Player(src).state:set('nb_disableDeath', true, true)
end)
RegisterNetEvent('boxing:end', function()
local src = source
Player(src).state:set('nb_disableDeath', false, true)
end)
-- client: tu-script/client.lua
AddEventHandler('nb-ambulance:client:deathIntercepted', function(payload)
if not inBoxingMatch then return end
-- knockout!
showKOMessage()
ResetBoxingRound()
end)
Comando admin (debug)¶
Solo desde consola/admin. Toggle manual del flag para testing.
API completa¶
| Export | Lado | Que hace |
|---|---|---|
setDeathDisabled(bool) |
client | flip flag para uno mismo |
isDeathDisabled() |
client | bool |
setDeathDisabled(playerId, bool) |
server | flip flag de un target |
isDeathDisabled(playerId) |
server | bool |
| Statebag | Donde | Notas |
|---|---|---|
Player(src).state.nb_disableDeath |
server-replicated | Source of truth. |
Player(src).state.nb_disableDeath_manual |
server-replicated | Indica que el flag fue puesto manualmente, no por zona. Las zonas no lo limpian al salir si esto es true. |
Player(src).state.nb_disableDeath_zone |
server-replicated | Indica que el flag esta activo por una zona. |
| Evento | Lado | Cuando |
|---|---|---|
nb-ambulance:client:deathIntercepted |
client | Una muerte fue interceptada. Payload: { weapon, killer } |