Saltar al contenido principal

Encantamientos personalizados

EliteMobs y FreeMinecraftModels proporcionan encantamientos personalizados mediante un sistema compartido de MagmaCore. Cada plugin mantiene sus definiciones y efectos Lua en su propia carpeta enchantments/. Los encantamientos nativos de Minecraft permanecen en el espacio de nombres minecraft:.

Actualizar las definiciones incluidas​

El catálogo restaura los archivos YAML y Lua incluidos que falten y añade los campos predeterminados ausentes a las definiciones incluidas existentes. Conserva los valores ya configurados y el código Lua existente. Esto funciona incluso cuando la carpeta enchantments/ ya existe.

El plugin responsable puede archivar primero los archivos que coincidan con un formato retirado. Por ejemplo, EliteMobs conserva los YAML de encantamientos que contienen maxLevelV2 antes de generar los valores predeterminados actuales. EliteMobs también archiva las copias sin editar de scripts de encantamientos incluidos en versiones anteriores, como un antiguo grappling_hook.lua, para escribir en su lugar el valor predeterminado actual; un script que hayas editado se conserva. Revisa los ajustes personalizados en el archivo de configuraciones y vuelve a aplicarlos con los campos actuales. Un DLC actualizado o un efecto personalizado sigue necesitando su propia definición y código Lua correspondientes.

Referencias en objetos​

Los efectos personalizados usan un ID en minúsculas con espacio de nombres y un nivel entero positivo. Este ejemplo es una definición de objeto de FMM:

enchantments:
- "minecraft:unbreaking,3"
- "elitemobs:critical_strikes,2"

Por ejemplo, critical_strikes.yml en el catálogo de encantamientos de EliteMobs define elitemobs:critical_strikes. Una definición de FMM usa freeminecraftmodels:. Las subcarpetas no forman parte del ID; asigna nombres de archivo únicos al contenido.

El YAML de objetos personalizados de EliteMobs conserva los nombres de Bukkit, como UNBREAKING,3, para encantamientos nativos, pero exige IDs con espacio de nombres para efectos personalizados. No copies la sintaxis de objetos nativos de FMM a otro plugin sin comprobar su formato de objetos.

El proveedor instalado debe reconocer el ID. La compatibilidad, el tipo de objeto, la ranura, los conflictos y las capacidades necesarias proceden de su definición. Eliminar un proveedor no convierte su efecto personalizado en un encantamiento nativo.

Formato de definición​

Esta es la definición Ignition incluida en FMM, asociada a ignition.lua en el mismo catálogo de encantamientos:

isEnabled: true
name: Ignition
description: Sets surviving targets on fire after a staff fireball hits.
maxLevel: 3
curse: false
validSlots: [MAINHAND]
itemTypes: [STAFF]
attackKinds: [STAFF_FIREBALL]
requires: []
conflicts: []
stacking: source_item
script: ignition.lua
parameters:
base_ticks: 20
ticks_per_level: 20
return {
api_version = 1,
on_ignition_ticks = function(context)
return math.max(0, math.min(200, context.parameters.base_ticks
+ context.parameters.ticks_per_level * context.enchantment.level))
end
}

Esta consulta devuelve una duración de ignición a FMM. No se ejecuta como un script de prop ni de objeto equipado.

CampoSignificado
isEnabledPor defecto true; las definiciones desactivadas no entran en el catálogo
nameNombre visible de texto simple, obligatorio
descriptionDescripción opcional, vacía por defecto
maxLevelLímite positivo de nivel al encantar; los objetos definidos explícitamente pueden superarlo
curseIndica si el encantamiento es una maldición; por defecto false
validSlotsRanuras de equipo: HEAD, CHEST, LEGS, FEET, MAINHAND, OFFHAND
itemTypesCategorías admitidas: SWORD, AXE, PICKAXE, SHOVEL, HOE, BOW, CROSSBOW, TRIDENT, MACE, SPEAR, HELMET, CHESTPLATE, LEGGINGS, BOOTS, SHIELD, FISHING_ROD, SHEARS, ELYTRA, WAND, STAFF, OTHER
attackKindsFiltro opcional de ataque mágico: WAND_MISSILE, STAFF_MELEE, STAFF_FIREBALL
requiresCapacidades exigidas al proveedor
conflictsOtros IDs de encantamientos en minúsculas con espacio de nombres
stackingsource_item por defecto, o sum_equipped_levels
scriptNombre de archivo .lua obligatorio, en minúsculas y sin directorio
parametersValores escalares con nombre o listas de escalares por nivel
setOpcional. Convierte este encantamiento en un conjunto de objetos

Una lista por nivel debe tener exactamente maxLevel entradas. Por encima de ese nivel se conserva el último valor de la lista, mientras que el script sigue recibiendo el nivel real del encantamiento. Los parámetros pertenecen al efecto concreto; añadir una clave arbitraria aquí no crea una mecánica nueva.

Los campos desconocidos de nivel superior, los IDs duplicados, los scripts ausentes y los hooks no admitidos provocan el rechazo del catálogo candidato. Corrige el archivo que indique el error antes de recargar. Un candidato fallido no sustituye al catálogo activo.

Responsabilidad de los efectos​

Parte de un efecto incluido en el plugin al que pertenecerá la nueva definición. Sus hooks y operaciones de dominio admitidos determinan lo que puede hacer. Los hooks de consulta devuelven valores como el número de misiles, la probabilidad de crítico o la bonificación de amenaza. Los hooks de acción procesan entradas de objetos aceptadas y pueden mantener efectos temporizados.

La antigua API context.item de FMM y su ciclo de equipar/desequipar no se aplican aquí. Los scripts de encantamiento usan sus propios context.enchantment, context.parameters, datos del origen capturados y operaciones de acción. No renombres un antiguo script de objeto suponiendo que su contexto es compatible.

Libros y yunques​

Los libros encantados personalizados usan las mismas definiciones de proveedor que los objetos equipados. Un yunque valida el objeto de origen, el libro y el resultado completo, incluidos los encantamientos nativos. Los niveles personalizados iguales se combinan para obtener el siguiente nivel; si son distintos, se conserva el mayor. Cada encantamiento personalizado modificado suma su nivel resultante al coste nativo de reparación. El nivel resultante debe superar las comprobaciones de límite de nivel en yunque, ranura, tipo, capacidades y conflictos de la definición.

Los libros mixtos deben transferir todas las entradas nativas que acepte el servidor, además de las personalizadas. Si el servidor rechaza una entrada nativa, se rechaza la operación personalizada en lugar de descartar silenciosamente esa parte del libro. Las definiciones no válidas o no disponibles también impiden la vista previa. Los materiales de entrada y el estado del proveedor se comprueban de nuevo al recoger el resultado; una vista previa visible no reserva un resultado que siga siendo válido tras cambiar el catálogo.

Referencia de consultas Lua​

Las consultas numéricas ejecutan una instancia nueva del script y la cierran inmediatamente después del resultado. Devuelve un único número finito o nil para no aportar ningún valor. El estado y el trabajo programado no sobreviven a la consulta. Una definición fallida queda en cuarentena hasta que se recargue correctamente el catálogo; agotar el presupuesto restante del llamador no pone por sí solo la definición en cuarentena.

ContextoContenido
context.enchantmentid y level real
context.parametersValores de esta definición resueltos para ese nivel
context.inputDatos escalares proporcionados por la mecánica responsable; consulta el efecto incluido para conocer las claves exactas
context.targetTabla Entity o Living Entity del objetivo, o nil
context.playerJugador desencadenante cuando la consulta dispone de uno

FMM proporciona on_missile_count, on_missile_damage_factor, on_blast_radius_factor y on_ignition_ticks. Otros proveedores exponen sus propios hooks numéricos. Una definición solo puede declarar hooks aceptados por su proveedor.

Referencia de acciones Lua​

Los scripts de acción usan las tablas compartidas de planificador, tiempos de reutilización, mundo, zonas, jugador y eventos. Se ejecutan para una entrada o ataque aceptado y usan un origen capturado en las llamadas posteriores. El chat captura el mensaje durante el evento de chat y después captura el equipo cuando se despacha en el hilo del servidor. El parámetro opcional parameters.lifetime_ticks debe ser un entero positivo; sin él, la activación dura un tick. Los efectos programados necesitan una duración definida lo bastante larga para terminar.

Las activaciones se detienen al finalizar su duración, cuando el actor muere, se desconecta o cambia de mundo, cuando se descarga el mundo al que pertenecen, cuando se descarga un chunk que contiene alguna entidad que poseen, o cuando el proveedor se recarga o se desactiva. Pueden terminar antes si, tras la última entrada, no queda trabajo propio pendiente. parameters.stop_on_unequip: true también detiene una activación cuando su objeto capturado deja de estar equipado. Los tiempos de reutilización locales pertenecen al jugador y al ID de encantamiento; los globales pertenecen al jugador dentro del proveedor. Ambos sobreviven a los cambios de equipo, las activaciones finalizadas, los cambios de mundo y las recargas válidas, y se borran al desconectarse o al apagarse el proveedor.

HookEntrada aceptada
on_attack_entityDaño cuerpo a cuerpo nativo, positivo y aplicado correctamente con el objeto de la mano principal, o un ataque explícito del plugin
on_projectile_hitDaño aplicado correctamente a un objetivo vivo por un proyectil de arco capturado, entregado una vez por proyectil y objetivo, o un impacto explícito del plugin
on_take_damageDaño positivo al jugador; se examinan las ranuras equipadas que sean elegibles
on_right_click, on_left_clickInteracción de mano sin agacharse
on_shift_right_click, on_shift_left_clickInteracción de mano mientras se está agachado; sustituyen al hook de clic ordinario correspondiente
on_break_blockRotura de bloque aceptada del jugador con el objeto de la mano principal
on_chatChat aceptado, despachado en el hilo del servidor con la copia del mensaje
on_sneakInicio de la postura agachada; las contribuciones del equipo se recopilan por definición
on_projectile_launchMunición encantada consumida que se lanza como flecha desde un evento de arco
on_game_tickTick mientras esta activación sigue activa
on_zone_enter, on_zone_leaveJugadores que cruzan una zona vigilada por esta activación

Estos hooks no crean un entorno de scripts de equipar/desequipar. Una definición que solo actúe en cada tick sigue necesitando un hook de entrada para iniciar su activación. Los hooks nativos de ataque, daño, chat y minería observan entradas ya aceptadas; no pueden cancelar el evento original. Los cuatro hooks de interacción exponen una marca de cancelación síncrona: context.event:cancel() impide la interacción asociada con el objeto y el bloque. Las llamadas programadas no pueden cancelar retroactivamente una entrada.

ContextoContenido
context.enchantmentid, level
context.parametersParámetros de la definición resueltos para el nivel
context.playerTabla Player del actor actual
context.targetTabla Living Entity del objetivo afectado actual, o nil
context.sourceDatos capturados: item, slot, inventory_slot, equipment, attack_kind, providers; algunas entradas también proporcionan ammunition, projectile, message, block, drop_items, sneaking o equipped_levels
context.itemMétodos de durabilidad y consumo de la ranura capturada, cuando aún se puede acceder al objeto del inventario; consulta los métodos de objeto
context.actionid (UUID del ataque), instance (token de activación), actor (UUID), world (UUID del mundo) y los métodos siguientes
context.setPara un conjunto de objetos: id, name, level y pieces; nil en caso contrario

Las copias de objetos contienen material, amount y enchantments. Son datos, no objetos vivos del inventario. Los UUID de los datos del origen son cadenas. En minería, source.block contiene x, y, z y material en minúsculas.

Método de acciónDevuelveComportamiento
stop()nilDetiene esta activación y limpia el trabajo que posee
has_previous()boolComprueba si existe otra instancia activa de este encantamiento para el mismo jugador
replace_previous()nilDetiene esas instancias anteriores y conserva esta
damage_target(target_uuid, amount)boolSolicita al proveedor que aplique daño finito positivo atribuido al origen capturado; false si se rechaza
own_entity(uuid)boolRegistra una entidad válida del mismo mundo que no sea un jugador para eliminarla durante la limpieza; úsalo después de crearla
launch_projectile(location, direction, speed, range, ticks, impact, visual?, protected_path?=false)boolLanza un proyectil de script propio; speed/range deben ser finitos y positivos, y ticks al menos 1
attribute_projectile(uuid, callback, protect?=false)boolVincula el daño de un proyectil nativo propio a una función definida por el autor
place_block(x, y, z, expected_material, block_data)boolColoca un bloque mediante la validación de acciones de bloques del jugador, solo si coincide el material actual
break_block(x, y, z, expected_material, drop_material?, amount?=1)boolRompe mediante la validación de acciones de bloques del jugador, con un objeto soltado opcional definido por el autor
break_naturally(x, y, z, expected_material)boolRompe usando la herramienta capturada y la política de objetos soltados del evento de rotura original
temporary_block(x, y, z, block_data, ticks?=0)boolToma posesión temporal de un bloque cargado y lo restaura durante la limpieza o tras un número positivo de ticks; cero dura hasta la limpieza
can_own_block(x, y, z)boolComprueba que las coordenadas estén cargadas y se pueda tomar posesión temporal
temporary_gravity(uuid, enabled)boolModifica temporalmente la gravedad y la restaura durante la limpieza
restore_gravity(uuid)boolRestaura antes de tiempo la gravedad modificada por esta activación
temporary_scale(uuid, scale)boolModifica temporalmente la escala de una entidad viva hasta la limpieza
temporary_potion(uuid, type, ticks, amplifier)boolAplica temporalmente un efecto de poción con ticks positivos y un amplificador no negativo
restore_potion(uuid, type)boolRestaura antes de tiempo el efecto de poción modificado por esta activación
ride_rails(speed)boolSienta al jugador en una vagoneta que solo ven los clientes y la hace avanzar por los raíles conectados en el bloque del jugador, hacia el extremo al que mira, a speed bloques por tick (mayor que 0 y como máximo 2); false cuando no hay un raíl allí, el jugador ya va montado en algo o el adaptador NMS del servidor no está disponible

Un viaje en raíles es trabajo que posee su activación. Agacharse, el final de la vía, un teletransporte, la muerte, desconectarse o cualquier otra cosa que aleje al jugador más de un bloque de la vagoneta termina el viaje y después la activación; el jugador queda donde se detuvo la vagoneta, salvo tras un teletransporte, la muerte o una desconexión. Detener la activación, también mediante replace_previous(), igualmente baja al jugador. El lifetime_ticks de la activación sigue aplicándose, así que dale tiempo suficiente para la vía más larga.

Las funciones de impacto de proyectil reciben (fresh_context, target_or_nil, location); las visuales reciben (fresh_context, location). Las funciones de daño de proyectiles nativos reciben (fresh_context, target, native_damage) en el siguiente tick. Sustituyen la aplicación nativa y deben aplicar explícitamente el daño deseado, normalmente mediante fresh_context.action:damage_target(target.uuid, amount). Con protect=true en proyectiles nativos, se filtran los bloques protegidos de explosiones y la ignición. En los proyectiles de script, protected_path=true absorbe los vuelos que cruzan posiciones protegidas o no cargadas.

La limpieza se limita a operaciones que registran la propiedad. Las operaciones ordinarias world:spawn_entity, entity:set_gravity y world:set_block_at no reciben automáticamente limpieza de la acción. Los métodos de estado temporal gestionan la restauración; no sustituyen la comprobación de si está permitido un efecto hostil o un cambio de bloques.

Conjuntos de objetos​

Una sección set convierte un encantamiento en un conjunto de objetos. Pon el mismo encantamiento en cada pieza. El conjunto está completo mientras cada ranura indicada en pieces contiene un objeto que lo lleva. Un conjunto completo ejecuta sus hooks una vez por evento. Si falta alguna pieza, no se ejecuta nada.

name: Crooked's Full Set
maxLevel: 1
validSlots: [HEAD, CHEST, LEGS, FEET]
itemTypes: [HELMET, CHESTPLATE, LEGGINGS, BOOTS]
script: crooked_set.lua
parameters:
lifetime_ticks: 620
stop_on_unequip: true
set:
pieces:
HEAD: Crooked's Hex-Brim
CHEST: Crooked's Warded Wrap
LEGS: Crooked's Bent Hosen
FEET: Crooked's Wayward Soles
lore:
- "&5Crooked's Full Set &7($equippedPieces/$totalPieces)"
- "$setPieces"
- "&7When damaged, has a 5% chance to grant Regeneration I."
return {
api_version = 1,
on_take_damage = function(context)
-- Runs only while all four pieces are worn, once per hit.
context.action:temporary_potion(context.player.uuid, "REGENERATION", 100, 0)
end
}
Campo del conjuntoSignificado
piecesObligatorio. Asocia ranuras de equipo con nombres de pieza. Cuando se define validSlots, debe incluir la ranura de cada pieza
nameNombre que usa $setName. Por defecto es el name del encantamiento y admite códigos de color &
loreLas líneas de lore del conjunto. Por defecto es el nombre del conjunto con su recuento de piezas, seguido de una línea por pieza
equippedPieceLínea para una pieza puesta. Por defecto &a✔ $pieceName
missingPieceLínea para una pieza que falta. Por defecto &c✘ $pieceName

El lore del conjunto admite estos placeholders:

PlaceholderMuestra
$setNameEl nombre del conjunto
$equippedPiecesCuántas piezas lleva puestas el jugador
$totalPiecesCuántas piezas tiene el conjunto
$setPiecesUna línea por pieza en orden de ranura, tomada de equippedPiece o missingPiece. El texto que rodea al placeholder se repite en cada línea
$pieceName, $pieceSlotDentro de equippedPiece y missingPiece, el nombre de la pieza y su ranura, como Head o Main Hand
$ifSetCompleteMuestra la línea solo mientras todas las piezas están puestas
$ifSetIncompleteMuestra la línea solo mientras falta alguna pieza

Los objetos de un conjunto muestran esta sección en lugar de una línea en la lista de encantamientos personalizados. En EliteMobs, pon $itemSet en itemLoreStructureV2 de ItemSettings.yml, o en el propio lore de un objeto personalizado. Sin ninguna de las dos cosas, el conjunto va después del lore personalizado del objeto. $ifItemSet muestra una línea de la estructura solo en los objetos de un conjunto. Los objetos personalizados de FMM muestran el conjunto en la línea de lore que contiene $itemSet, o después de su lore.

La sección muestra lo que lleva puesto el jugador que porta el objeto y se redibuja cuando se equipa o se quita una pieza. Un objeto guardado fuera del inventario de un jugador conserva el estado que mostraba al salir.

Los hooks de un conjunto se diferencian de los hooks de encantamientos ordinarios en varios aspectos:

  • Todos los hooks de acción de la tabla anterior llegan a un conjunto completo, sean cuales sean las ranuras de sus piezas. Un conjunto de armadura puede responder a on_attack_entity o on_break_block.
  • Si el conjunto está completo se comprueba en el momento del evento. Un proyectil comprueba los conjuntos que se llevan puestos cuando aterriza, y cuenta cualquier proyectil, no solo las flechas de arco.
  • on_take_damage establece context.target como el atacante cuando lo hay.
  • context.source.item y context.item son la primera pieza en orden de ranura: HEAD, CHEST, LEGS, FEET, MAINHAND, OFFHAND. Lee context.source.equipment.MAINHAND para el arma o herramienta que se sostiene.
  • context.set.level es el nivel más bajo entre las piezas. context.set.pieces está indexado por ranura, con el name y el inventory_slot de cada pieza.
  • stop_on_unequip: true detiene la activación de un conjunto cuando se quita cualquier pieza.
  • Las consultas numéricas, como la amenaza y la probabilidad de crítico de EliteMobs o los modificadores de lanzamiento de FMM, cuentan un conjunto una sola vez y solo mientras está completo.

Actualizar contenido existente​

FMM omite los objetos personalizados con scripts: no vacío o entradas de encantamiento retiradas sin espacio de nombres. Sustituye esas definiciones de objeto por encantamientos con espacio de nombres; los scripts de props siguen siendo compatibles.

Los efectos personalizados de EliteMobs ahora usan maxLevel y parameters específicos del efecto en el YAML del proveedor. La configuración de encantamientos nativos y de nivel élite tiene un formato distinto. Sigue la referencia de encantamientos de EliteMobs en lugar de copiar un archivo antiguo de maxLevelV2 a una definición de proveedor.