Cómo funcionan las integraciones#
Air Hockey se comunica con el resto de tu servidor mediante unos pocos archivos pequeños y abiertos: server/custom/framework/ para el dinero, los permisos y los nombres, y client/custom/framework.lua para las notificaciones y el aviso. Todo lo demás se detecta por sí solo:
Capa | Compatibles | Sin ella |
|---|---|---|
Framework |
| Funciona en modo standalone: no se cobra a nadie y los jugadores aparecen con su nombre de FiveM. |
Dinero | Efectivo y banco en ESX, QBCore y Qbox | Todas las mesas son gratuitas. |
Moneda personalizada |
| El efectivo y el banco del framework. |
Permisos | ACE — | Nadie puede abrir el creador. |
Notificaciones |
|
|
Aviso 3D |
| Texto 3D integrado sobre la mesa. |
Mesas del mapa | Cualquier | Solo las mesas del creador y de la config. |
Idiomas | 41 archivos de idioma | Inglés. |
Toda integración opcional se degrada en silencio. Si falta un recurso, su parte recurre al comportamiento integrado — nada da error y no hay que desactivar nada a mano.
Frameworks#
El framework se elige según cuál de estos ya está iniciado cuando arranca Air Hockey:
Recurso | Modo |
|---|---|
|
|
|
|
|
|
Ninguno |
|
Cada modo tiene un archivo en server/custom/framework/ — esx.lua, qb.lua y standalone.lua — y solo se ejecuta el que corresponde a tu servidor. Cada uno define las mismas cuatro funciones:
Función | Decide |
|---|---|
| Si un jugador puede pagar la entrada de una mesa — se comprueba antes de una partida contra el bot, al enviar un desafío y al aceptarlo. |
| Cobra la entrada. |
| Quién puede abrir el creador y crear, mover o borrar mesas. |
| El nombre que se muestra en la lista de rivales y en la ventana de desafío: el nombre del personaje en ESX, QBCore y Qbox, y el nombre de FiveM en standalone. |
method es el método de pago de la mesa en el creador — 'money' para efectivo o 'bank' — y corresponde al efectivo y a la cuenta bancaria en todos los frameworks.
Una moneda personalizada#
La entrada se puede pagar con algo que no sea dinero — fichas de casino, una moneda VIP, tokens de arcade. Define estas dos funciones en config/config.lua y todos los archivos de framework les delegan la decisión, incluido standalone:
-- config/config.lua
Config.CanAfford = function(src, amount, method)
return exports.ox_inventory:GetItemCount(src, 'casino_chips') >= amount
end
Config.RemoveMoney = function(src, amount, method)
exports.ox_inventory:RemoveItem(src, 'casino_chips', amount)
endSolo se llaman en el servidor, y nunca para una mesa gratuita. method se sigue pasando, así que puedes usar la opción Cash / Bank de la mesa para elegir entre dos monedas propias.
Defínelas juntas. Una sin la otra comprueba una moneda y cobra otra. Air Hockey nunca paga nada, así que no hay una tercera función que escribir.
Permisos#
HasPermission comprueba el ace en Config.Creator.permission — command.ahcreator salvo que definas el tuyo. Para dejar entrar también a los grupos de administración de tu framework, amplíalo en el archivo correspondiente:
-- server/custom/framework/esx.lua
function HasPermission(src)
local xPlayer = ESX.GetPlayerFromId(src)
if xPlayer and (xPlayer.getGroup() == 'admin' or xPlayer.getGroup() == 'superadmin') then
return true
end
local perm = Config.Creator and Config.Creator.permission or 'command.ahcreator'
return IsPlayerAceAllowed(src, perm)
end-- server/custom/framework/qb.lua
function HasPermission(src)
if QBCore.Functions.HasPermission(src, 'admin') then
return true
end
local perm = Config.Creator and Config.Creator.permission or 'command.ahcreator'
return IsPlayerAceAllowed(src, perm)
endLa misma comprobación abre el creador, y el servidor la vuelve a ejecutar en cada creación, movimiento y borrado — un cliente modificado no puede cambiar mesas. Las herramientas de depuración son la excepción: solo dependen de Config.Debug.
Notificaciones y el aviso#
Dos funciones en client/custom/framework.lua deciden cómo se ve Air Hockey junto al resto de tu HUD:
Función | Qué hace | Por defecto |
|---|---|---|
| Cada mensaje que ve un jugador. |
|
| El aviso [E] - Play Air Hockey sobre una mesa. |
|
Para usar otro sistema de notificaciones, reemplaza el cuerpo de Notification. Por ejemplo, con las notificaciones propias de QBCore:
-- client/custom/framework.lua
function Notification(msg, kind)
local types = { inform = 'primary', success = 'success', error = 'error' }
TriggerEvent('QBCore:Notify', msg, types[kind] or 'primary')
endMesas de Air Hockey en los mapas#
Muchos salones recreativos y MLO ya tienen la mesa de air hockey de GTA V. Con Config.AutoDetect = true, el juego de cada jugador busca la más cercana dentro de Config.StreamDistance cada dos segundos y la hace jugable — sin colocarla ni añadir líneas de config. Una mesa transparente, como la vista previa del creador, nunca se detecta.
Los modelos están en la config. Si tu mapa usa una mesa distinta, configúrala en Config.TableModel — el creador coloca el mismo modelo — y calibra Config.Table para ella como se muestra en Uso.
Config.TableModel = joaat('prop_airhockey_01')
-- Puck: tried in order, the first that exists in the game is used
Config.PuckModels = {
joaat('proair_hoc_puck'),
joaat('prop_air_hoc_puck_01'),
joaat('prop_air_hoc_puck'),
}
Config.PaddleModels = {
[1] = joaat('prop_air_hoc_paddle_01'), -- red (the solo player / the challenger)
[2] = joaat('prop_air_hoc_paddle_02'), -- blue (the bot / the challenged player)
}Si ninguno de los modelos de disco existe en tu juego, el disco es invisible — /ahcheck muestra cuáles son válidos. Consulta Errores comunes.
Idiomas#
Incluye 41 traducciones en locales/: árabe (ar), búlgaro (bg), bengalí (bn), catalán (ca), checo (cs), danés (da), alemán (de), griego (el), inglés (en), español (es), estonio (et), persa (fa), finés (fi), francés (fr), hebreo (he), hindi (hi), croata (hr), húngaro (hu), indonesio (id), italiano (it), japonés (ja), coreano (ko), lituano (lt), letón (lv), malayo (ms), neerlandés (nl), noruego (no), polaco (pl), portugués (pt), rumano (ro), ruso (ru), eslovaco (sk), esloveno (sl), sueco (sv), suajili (sw), tailandés (th), turco (tr), ucraniano (uk), urdu (ur), vietnamita (vi) y chino (zh). Elige uno con:
Config.Locale = 'es'Un solo archivo traduce las notificaciones y toda la interfaz, incluido el creador. Para ajustar una frase, edita locales/<code>.json y reinicia el recurso. Cualquier clave que falte en tu idioma usa el inglés, y un código sin archivo pasa por completo al inglés, con un aviso en la consola F8.



