Saltar al contenido principal

Crear Poderes

webapp_banner.jpg

Dos formas de escribir un poder​

Los poderes basados en archivos se guardan en plugins/EliteMobs/powers, incluidas las subcarpetas. Hay dos formatos:

FormatoArchivoÚsalo para
Lua*.luaComportamiento programado con hooks de jefe, bucles y estado. La mayoría de los poderes incluidos usan este formato.
EliteScript*.ymlEl formato declarativo de eventos/acciones documentado en el resto de esta página. Sigue estando plenamente soportado.

De los 71 poderes incluidos, 68 usan Lua. Solo bonus_coins.yml, custom_summon.yml y elite_script.yml siguen siendo poderes Java respaldados por YAML. Para crear nuevos comportamientos, empieza por Primeros Pasos con Lua y Hooks y Ciclo de Vida del Jefe.

Cualquiera de los dos formatos se referencia desde un jefe de la misma manera, mediante la lista powers.

Usa nombres de archivo únicos entre todas las subcarpetas. El registro usa el nombre del archivo, no una ruta que incluya la carpeta, por lo que las subcarpetas no separan nombres duplicados. Cuando dos archivos comparten nombre, EliteMobs carga el que tiene la ruta completa que va primero en orden alfabético y registra Duplicate content filename para el otro, salvo que ambos archivos tengan el mismo contenido. Después de editar los archivos, ejecuta /em reload y revisa las advertencias de carga.

Un poder .lua reemplaza a un poder .yml con el mismo nombre

Cuando un jefe pide attack_fire.yml, EliteMobs busca primero un attack_fire.lua cargado correctamente. La misma búsqueda se aplica a las solicitudes .yaml. Esto conserva las referencias antiguas cuando la sustitución Lua se carga. Las configuraciones nuevas deberían nombrar el archivo .lua directamente. Respeta las mayúsculas y minúsculas del nombre registrado.

Los archivos .lua predefinidos se escriben una vez, y los archivos editados nunca se sobrescriben

Cada poder Lua incluido se escribe solo cuando no se encuentra un archivo correspondiente dentro de powers. Cuando una actualización corrige un poder incluido, EliteMobs enumera las sumas de comprobación de las versiones incluidas anteriormente. Una copia sin editar que coincida con alguna se mueve a plugins/MagmaCore/outdated files/EliteMobs/, y la versión actual se escribe en ese mismo arranque. Un archivo que hayas editado nunca coincide, así que se queda tal cual y no recibe las correcciones oficiales. Da nombres propios a las copias modificadas y compara los archivos predefinidos conservados con la versión que quieras usar.

on_zone_enter / on_zone_leave no son disparados por las zonas de Lua

Ambos nombres de hook se aceptan, pero crear una zona Lua no los dispara. La fuente integrada es un listener de zonas de EliteScript que se inicia cuando un script YAML del mismo jefe incluye ZoneEnterEvent o ZoneLeaveEvent en Events: y define una zona válida. Estos eventos llegan a todos los poderes correspondientes de ese jefe y no identifican qué zona YAML los originó. Declarar los hooks en un jefe que solo usa Lua no basta para ejecutarlos.

No construyas un poder Lua alrededor de estos dos hooks salvo que lo estés emparejando deliberadamente con un script de zona en YAML de ese tipo. Usa context.zones:watch_zone(...) (cuyos propios callbacks on_enter / on_leave sí se invocan directamente), un bloque Zone de EliteScript, o sondeo desde on_game_tick en su lugar. Consulta Hooks y Ciclo de Vida y Eventos de Script.

Sistema de Scripting de EliteMobs​

La siguiente página describe cómo crear Elite Scripts.

Esta es una función avanzada y requiere un conocimiento profundo de EliteMobs.

Nota: Los Elite Scripts se pueden agregar como archivos de poder o a archivos de jefes personalizados. Si se usan como archivos de poder, puedes agregarlos como poderes normales a los jefes usando la configuración powers de los Jefes Personalizados, como de costumbre.

Agregar un EliteScript​

Para comenzar a agregar un EliteScript a un jefe, agrega la siguiente entrada al archivo del jefe:

eliteScript:

Nota: Lo siguiente es extremadamente sensible a mayúsculas/minúsculas y espacios. Asegúrate de que tus espacios, saltos de línea y formato general coincidan con los ejemplos.

Ahora que tienes declarado el inicio de tu script, puedes agregar tu script específico. Para este ejemplo, vamos a crear un script llamado Example:

eliteScript:
Example:

Los EliteScripts tienen cinco secciones: Events, Conditions, Zone, Actions y Cooldowns. Incluye una lista Actions no vacía para que el script funcione. Puedes omitir Events en scripts llamados por otros scripts o por callbacks de aterrizaje; sin quien lo llame, ese script no se ejecuta por sí mismo. Conditions y Cooldowns son mapas, no listas.

Veamos un ejemplo sencillo:

eliteScript:
Example:
Events:
- EliteMobDamagedByPlayerEvent
Actions:
- action: PUSH
Target:
targetType: SELF
vValue: 0,0.5,0
Cooldowns:
local: 60
global: 20

Cuando recibe un golpe de jugador que cumple los requisitos, este script empuja al elite hacia arriba e inicia un tiempo de reutilización local de 60 ticks y uno global de 20 ticks. A 20 TPS son tres segundos y un segundo. El tiempo global solo afecta a los poderes que lo comprueban; no bloquea todos los hooks o acciones. Los scripts YAML activados por eventos comprueban estos tiempos cuando su valor local o global es positivo. Consulta la guía de tiempos de reutilización de abajo para el comportamiento de los scripts llamados.

Ahora que conoces el formato general de cómo se estructuran los scripts, es hora de aprender qué puedes hacer con cada sección.


Eventos

Eventos

Haz clic en el enlace de arriba para aprender a usar los eventos.

Objetivos

Objetivos

Haz clic en el enlace de arriba para aprender a usar los objetivos.

Acciones

Acciones

Haz clic en el enlace de arriba para aprender a usar las acciones.

Zonas

Zonas

Haz clic en el enlace de arriba para aprender a usar las zonas.

Condiciones

Condiciones

Haz clic en el enlace de arriba para aprender a usar las condiciones.

Tiempos de reutilización

Tiempos de reutilización

Haz clic en el enlace de arriba para aprender a usar los tiempos de reutilización.


Agregar múltiples EliteScripts​

Puedes tener múltiples acciones en un evento, pero ¿qué pasa si quieres múltiples scripts en el mismo jefe? Es tan simple como crear una nueva entrada de script. Expandamos el ejemplo anterior y agreguemos otro script:

eliteScript:
Example:
Events:
- EliteMobDamagedByPlayerEvent
Actions:
- action: PUSH
Target:
targetType: SELF
vValue: 0,0.5,0
Cooldowns:
local: 60
global: 20
Example2:
Events:
- PlayerDamagedByEliteMobEvent
Actions:
- action: SET_ON_FIRE
duration: 20
Target:
targetType: DIRECT_TARGET
Cooldowns:
local: 200
global: 60

Example2 prende fuego al jugador dañado durante 20 ticks usando DIRECT_TARGET. Su tiempo local de 200 ticks impide otra ejecución de este script activada por eventos durante diez segundos a 20 TPS. Su tiempo global de 60 ticks se comparte con los poderes que comprueban el tiempo de reutilización del jefe. Otros scripts pueden aplicar fuego de forma independiente.

Crear poderes independientes​

Coloca los poderes YAML independientes en plugins/EliteMobs/powers. El bloque eliteScript contiene el comportamiento; los campos opcionales de metadatos que se describen abajo controlan la carga, la categoría, la presentación y los metadatos de reutilización. Ejemplo:

isEnabled: true
powerType: UNIQUE
eliteScript:
Example:
Events:
- EliteMobDamagedByPlayerEvent
Actions:
- action: PUSH
Target:
targetType: SELF
vValue: 0,.3,0
Cooldowns:
local: 60
global: 20

isEnabled​

Controla si el poder configurado está habilitado; el valor predeterminado es true. Para Lua personalizado, un archivo de metadatos complementario deshabilitado impide descubrir ese archivo Lua. Un poder Lua incluido se sigue cargando con un archivo complementario deshabilitado, pero queda marcado como deshabilitado, como se explica más abajo.

powerType​

El tipo de poder proporciona metadatos de categoría para las listas predeterminadas y la clasificación de los anillos de postura. Los valores son:

  • UNIQUE: Pensado para asignación explícita. Se excluye de las listas compartidas generadas automáticamente, pero puedes añadirlo explícitamente a una lista de poderes naturales.
  • DEFENSIVE / MISCELLANEOUS / OFFENSIVE: Se usan para generar la lista compartida correspondiente cuando falta. La elegibilidad depende de las listas configuradas, el estado habilitado y el nivel del mob.
  • MAJOR_ZOMBIE, MAJOR_SKELETON, MAJOR_BLAZE, MAJOR_ENDERMAN, MAJOR_GHAST: Estos cinco cuentan como poderes mayores; todos los demás cuentan como menores. La asignación natural usa la lista majorPowers de la entidad, sin comprobar durante la ejecución que el sufijo del tipo coincida con la entidad.

Cómo powerType llega a los elites naturales: EliteMobPowers.yml​

Los elites naturales eligen sus poderes de plugins/EliteMobs/EliteMobPowers.yml, no solo de powerType. Contiene:

ClaveSignificado
defensivePowersPoderes defensivos que los elites naturales pueden sortear al azar
offensivePowersPoderes ofensivos que los elites naturales pueden sortear al azar
miscellaneousPowersPoderes misceláneos que los elites naturales pueden sortear al azar
majorPowers.<ENTITY_TYPE>Poderes mayores que ese tipo de entidad puede sortear al azar
disabledPowers.<ENTITY_TYPE>Poderes eliminados de ese tipo de entidad después de aplicar las listas compartidas

Las listas compartidas defensivas, ofensivas y misceláneas que falten se generan con los poderes cargados del tipo correspondiente. Los valores predeterminados de poderes mayores se seleccionan explícitamente por tipo de entidad. Las listas existentes se conservan, por lo que añadir un poder después no lo incorpora a ellas: edita la lista adecuada. En cambio, un poder Lua personalizado presente cuando se genera una lista miscelánea ausente puede entrar en esa lista predeterminada.

En estas listas se aceptan tanto los nombres de archivo .lua como los nombres .yml heredados; los valores por defecto generados se escriben usando el alias .yml. Un nombre que no resuelva a ningún poder se omite con una advertencia en consola que indica el archivo y la clave.

Los espacios de poderes naturales se desbloquean a los niveles 10, 20, 30 y 40 para los poderes defensivos, ofensivos, misceláneos y mayores, respectivamente. Un segundo espacio de cada categoría se desbloquea a los niveles 50, 60, 70 y 80. Las listas vacías o deshabilitadas pueden producir menos poderes. Editar las listas no cambia la clasificación mayor o menor de un poder.

effect​

Establece el material del objeto que orbita en el anillo de postura del poder. Los tipos MAJOR_* usan el anillo mayor; los demás usan el menor. El valor debe ser un material de objeto, o un nombre de partícula que no necesite datos adicionales, que orbita como partícula. Cualquier otro valor desactiva el efecto y registra Disabled invalid power trail.

Un poder sin effect, o con un valor vacío, no aporta ningún objeto al anillo. Es el valor predeterminado de los poderes Lua personalizados sin effect en su archivo YAML opcional de metadatos.

Actualmente, los EliteScripts YAML independientes no copian estos metadatos a su estela de ejecución. Por tanto, definir effect en uno de esos poderes YAML no añade un objeto de postura. Los poderes Lua personalizados sí copian el effect de su archivo complementario.

ClaveValoresPredeterminado
effectMaterialninguno

powerCooldown​

Establece el tiempo de reutilización de los metadatos del poder, en ticks. Los EliteScripts YAML usan sus propios valores Cooldowns.local y Cooldowns.global, que sustituyen los metadatos al inicializarse el script. Los poderes Lua deben usar la API de reutilización documentada para comprobar y establecer sus tiempos.

ClaveValoresPredeterminado
powerCooldownInteger0

globalCooldown​

Establece los metadatos del tiempo de reutilización global en ticks. Ese tiempo solo bloquea los poderes que lo comprueban; no bloquea incondicionalmente todos los hooks o acciones. Para scripts YAML, configura la sección Cooldowns del propio script.

ClaveValoresPredeterminado
globalCooldownInteger0

Crear poderes Lua independientes​

Un poder Lua independiente es un archivo .lua en plugins/EliteMobs/powers, incluidas las subcarpetas. El archivo YAML de metadatos es opcional.

return {
api_version = 1,
on_player_damaged_by_boss = function(context)
if context.player == nil then
return
end
context.player:apply_potion_effect("BLINDNESS", 60, 0)
end
}

Sin un archivo de metadatos .yml en la misma carpeta y con el mismo nombre base, un poder Lua personalizado recibe estos valores predeterminados:

  • powerType es MISCELLANEOUS.
  • effect queda sin definir.

Para un my_power.lua personalizado, puedes añadir a su lado my_power.yml con isEnabled, powerType, effect, powerCooldown y globalCooldown. Por ejemplo, powerType: UNIQUE lo excluye de la lista miscelánea predeterminada. Un archivo de metadatos deshabilitado impide cargar ese archivo Lua personalizado.

Un .yml o .yaml con el mismo nombre base junto a un poder Lua predefinido incluido también se le aplica. Sus valores isEnabled, effect, powerCooldown y globalCooldown sustituyen a los integrados, incluidos los valores predeterminados de las claves que omitas, así que omitir effect elimina el objeto de postura del poder. powerType solo sustituye el tipo integrado cuando se define. Un archivo deshabilitado no impide que se cargue el poder incluido.

Los elites naturales usan las listas explícitas de EliteMobPowers.yml; revísalas al añadir poderes personalizados. Añade el nombre de archivo .lua a la lista powers: de un jefe para asignárselo directamente.

Hooks disponibles para los poderes Lua de jefe​

HookSe dispara cuando
on_spawnEl jefe aparece
on_game_tickCada tick del servidor mientras la instancia de ejecución está activa, sin pausa ni supresión
on_boss_damagedEl jefe recibe daño de cualquier fuente
on_boss_damaged_by_playerEl jefe recibe daño de un jugador
on_reinforcement_damaged_by_playerUn refuerzo recibe daño de un jugador; el hook se ejecuta en quien lo invocó
on_boss_damaged_by_eliteEl jefe recibe daño de otro elite
on_player_damaged_by_bossEl jefe daña a un jugador
on_enter_combatEl jefe entra en combate
on_exit_combatEl jefe sale de combate
on_healEl jefe se cura
on_boss_target_changedSe produce el evento de objetivo jugador, incluida la adquisición inicial; no cada cambio o pérdida de objetivo
on_deathEl jefe muere
on_phase_switchEl jefe cambia de fase
on_mind_actionUn Mind nativo solicita una acción a los poderes asociados

También se aceptan on_zone_enter y on_zone_leave. El despachador integrado los recibe de un listener de zonas de EliteScript del mismo jefe, no de los observadores de zonas Lua. Consulta la advertencia al principio de esta página.

Cada poder Lua asociado tiene su propia instancia de ejecución y estado para ese jefe. El ejemplo anterior no incluye tiempo de reutilización deliberadamente y se ejecuta en cada golpe correspondiente que se despache. Añade comprobaciones y asignaciones explícitas de los tiempos cuando las necesites; los metadatos por sí solos no controlan la ejecución de los hooks Lua. El daño puede despachar tanto el hook general como uno más específico, por lo que definir ambos puede ejecutar dos manejadores. Consulta la guía del ciclo de vida para la cancelación, eliminación y gestión de errores.

Para saber qué puedes llamar realmente dentro de estos hooks, consulta Primeros Pasos con Lua, Hooks y Ciclo de Vida del Jefe y Jefe y Entidades.