<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.dragonminez.com/es/wiki/Implementation_and_Events?action=history&amp;feed=atom</id>
	<title>Implementation and Events/es - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.dragonminez.com/es/wiki/Implementation_and_Events?action=history&amp;feed=atom"/>
	<link rel="alternate" type="text/html" href="https://wiki.dragonminez.com/es/wiki/Implementation_and_Events?action=history"/>
	<updated>2026-10-25T13:03:08Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.11</generator>
	<entry>
		<id>https://wiki.dragonminez.com/es/wiki/Implementation_and_Events?diff=37051&amp;oldid=prev</id>
		<title>Shokkoh: Translation sync from dragonminez-wiki repository</title>
		<link rel="alternate" type="text/html" href="https://wiki.dragonminez.com/es/wiki/Implementation_and_Events?diff=37051&amp;oldid=prev"/>
		<updated>2026-10-14T06:50:22Z</updated>

		<summary type="html">&lt;p&gt;Translation sync from dragonminez-wiki repository&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Nova página&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;#039;&amp;#039;&amp;#039;Implementación y eventos&amp;#039;&amp;#039;&amp;#039; describe la superficie de hooks que DragonMineZ ofrece a los addons: sus eventos, cómo leer el estado del jugador, los registros de extensión y dónde conectar tu propia red y tus propios registros. Léela cuando tu addon ya compile contra DMZ (consulta [[Special:MyLanguage/Add-on Getting Started|Primeros pasos con addons]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;Listening_to_a_DMZ_event&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
== Escuchar un evento de DMZ ==&lt;br /&gt;
Todos los eventos de servidor y comunes son clases estáticas anidadas de &amp;lt;code&amp;gt;com.dragonminez.common.events.DMZEvent&amp;lt;/code&amp;gt;, publicadas en el bus de eventos estándar de Forge (&amp;lt;code&amp;gt;MinecraftForge.EVENT_BUS&amp;lt;/code&amp;gt;). Cada clase anidada extiende directamente el &amp;lt;code&amp;gt;Event&amp;lt;/code&amp;gt; de Forge (&amp;lt;code&amp;gt;DMZEvent&amp;lt;/code&amp;gt; en sí solo es el contenedor), así que suscríbete a la clase anidada concreta:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
@Mod.EventBusSubscriber(modid = &amp;quot;your_addon_modid&amp;quot;, bus = Mod.EventBusSubscriber.Bus.FORGE)&lt;br /&gt;
public class DmzHooks {&lt;br /&gt;
    @SubscribeEvent&lt;br /&gt;
    public static void onTpGain(DMZEvent.TPGainEvent event) {&lt;br /&gt;
        int boosted = Math.round(event.getTpGain() * 1.10f);&lt;br /&gt;
        event.setTpGain(boosted);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @SubscribeEvent&lt;br /&gt;
    public static void onFormChange(DMZEvent.FormChangeEvent event) {&lt;br /&gt;
        if (event.isTransform()) {&lt;br /&gt;
            // player transformed into event.getNewGroup() / event.getNewForm()&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Los eventos marcados abajo como &amp;#039;&amp;#039;&amp;#039;cancelables&amp;#039;&amp;#039;&amp;#039; llevan la anotación &amp;lt;code&amp;gt;@Cancelable&amp;lt;/code&amp;gt; de Forge: &amp;lt;code&amp;gt;event.setCanceled(true)&amp;lt;/code&amp;gt; bloquea la acción subyacente. Los campos marcados como &amp;#039;&amp;#039;modificables&amp;#039;&amp;#039; tienen un setter (&amp;lt;code&amp;gt;setTpGain&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;setAmount&amp;lt;/code&amp;gt;, ...), y DMZ usa el valor resultante después de que se ejecuten todos los listeners. Todos los getters siguen los nombres de los campos (&amp;lt;code&amp;gt;getPlayer()&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;getOldValue()&amp;lt;/code&amp;gt;, ...); los campos booleanos usan &amp;lt;code&amp;gt;is...&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;isParry()&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;isBlocked()&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;Event_list&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
== Lista de eventos ==&lt;br /&gt;
Origen: &amp;lt;code&amp;gt;src/main/java/com/dragonminez/common/events/DMZEvent.java&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;Stats,_resources_and_progression&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
=== Estadísticas, recursos y progreso ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Evento !! Cancelable !! Se dispara cuando !! Campos clave&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StatChangeEvent&amp;lt;/code&amp;gt; || Sí || Una estadística (STR, SKP, RES, VIT, PWR o ENE) cambia mediante una llamada a &amp;lt;code&amp;gt;Stats.set*()&amp;lt;/code&amp;gt;: comandos, objetos, menús, y también cuando se cargan o copian las estadísticas (tanto en el servidor como en el cliente). || &amp;lt;code&amp;gt;player&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;stat&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;STRENGTH&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;STRIKE_POWER&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;RESISTANCE&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;VITALITY&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;KI_POWER&amp;lt;/code&amp;gt; o &amp;lt;code&amp;gt;ENERGY&amp;lt;/code&amp;gt;), &amp;lt;code&amp;gt;oldValue&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;newValue&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;TPGainEvent&amp;lt;/code&amp;gt; || Sí || Antes de que se añada una cantidad positiva de puntos de entrenamiento (&amp;lt;code&amp;gt;Resources.addTrainingPoints&amp;lt;/code&amp;gt;). || &amp;lt;code&amp;gt;player&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;oldValue&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;tpGain&amp;lt;/code&amp;gt; (modificable), &amp;lt;code&amp;gt;shareWithParty&amp;lt;/code&amp;gt; (modificable); auxiliar &amp;lt;code&amp;gt;getNewTpsValue()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;KiChargeEvent&amp;lt;/code&amp;gt; || Sí || Una vez por segundo mientras el jugador está cargando ki activamente. Cancélalo para detener la ganancia de ki de ese segundo. || &amp;lt;code&amp;gt;player&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;currentEnergy&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;maxEnergy&amp;lt;/code&amp;gt;; auxiliar &amp;lt;code&amp;gt;isEnergyFull()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;HealthRegenEvent&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;EnergyRegenEvent&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;StaminaRegenEvent&amp;lt;/code&amp;gt; || Sí || Antes de aplicar la regeneración por segundo de vida, ki o stamina. Comparten la base &amp;lt;code&amp;gt;ResourceRegenEvent&amp;lt;/code&amp;gt;. || &amp;lt;code&amp;gt;player&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;statsData&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;amount&amp;lt;/code&amp;gt; (modificable)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;FormChangeEvent&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;StackFormChangeEvent&amp;lt;/code&amp;gt; || No || Después de que cambie la forma de raza o la forma acumulable del jugador (lado del servidor). || &amp;lt;code&amp;gt;player&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;oldGroup&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;oldForm&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;newGroup&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;newForm&amp;lt;/code&amp;gt;; auxiliares &amp;lt;code&amp;gt;isTransform()&amp;lt;/code&amp;gt; y &amp;lt;code&amp;gt;isUntransform()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;PlayerDataSaveEvent&amp;lt;/code&amp;gt; || No || Los datos del jugador están a punto de escribirse en el backend de almacenamiento &amp;lt;code&amp;gt;JSON&amp;lt;/code&amp;gt; o &amp;lt;code&amp;gt;DATABASE&amp;lt;/code&amp;gt;. Puedes añadir tus propias claves a &amp;lt;code&amp;gt;data&amp;lt;/code&amp;gt;. || &amp;lt;code&amp;gt;player&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;data&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;PlayerDataLoadEvent&amp;lt;/code&amp;gt; || No || Los datos del jugador se leyeron del backend &amp;lt;code&amp;gt;JSON&amp;lt;/code&amp;gt; o &amp;lt;code&amp;gt;DATABASE&amp;lt;/code&amp;gt;, justo antes de aplicarse al jugador. || &amp;lt;code&amp;gt;player&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;data&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{{Note|title=StatChangeEvent y la carga de datos|text=&amp;lt;code&amp;gt;StatChangeEvent&amp;lt;/code&amp;gt; también se dispara mientras DMZ carga los datos guardados y aplica las sincronizaciones del cliente. Si lo cancelas, comprueba antes &amp;lt;code&amp;gt;event.getPlayer().level().isClientSide()&amp;lt;/code&amp;gt; y tus propias condiciones, o podrías impedir que se carguen las estadísticas guardadas de un jugador.}}&lt;br /&gt;
&lt;br /&gt;
{{Note|title=Backends de almacenamiento|text=&amp;lt;code&amp;gt;PlayerDataSaveEvent&amp;lt;/code&amp;gt; y &amp;lt;code&amp;gt;PlayerDataLoadEvent&amp;lt;/code&amp;gt; no se disparan con el backend &amp;lt;code&amp;gt;NBT&amp;lt;/code&amp;gt; por defecto, en el que vanilla guarda los datos de DMZ junto con el archivo del jugador. Consulta [[Special:MyLanguage/General Server Config|Configuración del servidor]] para ver los ajustes de &amp;lt;code&amp;gt;storage&amp;lt;/code&amp;gt;.}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;Combat&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
=== Combate ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Evento !! Cancelable !! Se dispara cuando !! Campos clave&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;DamageModifyEvent&amp;lt;/code&amp;gt; || Sí || Cálculo del daño antes de la mitigación, para un golpe de un jugador (golpes cuerpo a cuerpo y Super Golpes). Cancélalo para no hacer daño de DMZ. || &amp;lt;code&amp;gt;attacker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;victim&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;amount&amp;lt;/code&amp;gt; (modificable), &amp;lt;code&amp;gt;defensePenetration&amp;lt;/code&amp;gt; (modificable), &amp;lt;code&amp;gt;sourceType&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;MELEE&amp;lt;/code&amp;gt; o &amp;lt;code&amp;gt;STRIKE&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;DamageDealtEvent&amp;lt;/code&amp;gt; || No || Después de resolver el bloqueo de un golpe cuerpo a cuerpo de un jugador (cantidad antes de la mitigación). || &amp;lt;code&amp;gt;attacker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;victim&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;amount&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;blocked&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;parried&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;sourceType&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;PlayerDamageMitigatedEvent&amp;lt;/code&amp;gt; || No || Después de que DMZ termine de mitigar un golpe recibido por un jugador. Solo lectura: no cambies el daño aquí. || &amp;lt;code&amp;gt;victim&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;source&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;DamageSource&amp;lt;/code&amp;gt;), &amp;lt;code&amp;gt;rawDamage&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;defenseMitigated&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;blockMitigated&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;finalDamage&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;PlayerBlockEvent&amp;lt;/code&amp;gt; || Sí || El jugador bloquea o hace parry a un ataque con éxito. Cancélalo y el jugador recibe el golpe completo. || &amp;lt;code&amp;gt;victim&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;attacker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;originalDamage&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;finalDamage&amp;lt;/code&amp;gt; (modificable), &amp;lt;code&amp;gt;isParry&amp;lt;/code&amp;gt; (modificable), &amp;lt;code&amp;gt;poiseDamage&amp;lt;/code&amp;gt; (modificable)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;BarrierAbsorbEvent&amp;lt;/code&amp;gt; || No || Una barrera de ki (la técnica de barrera o la barrera de los Androides) absorbe un golpe antes de que llegue a la entidad protegida. || &amp;lt;code&amp;gt;owner&amp;lt;/code&amp;gt; (quien creó la barrera), &amp;lt;code&amp;gt;protectedEntity&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;attacker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;amount&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;PlayerDashEvent&amp;lt;/code&amp;gt; || Sí || Antes de que se ejecute un dash. || &amp;lt;code&amp;gt;player&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;dashType&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;NORMAL&amp;lt;/code&amp;gt; o &amp;lt;code&amp;gt;DOUBLE&amp;lt;/code&amp;gt;), &amp;lt;code&amp;gt;distance&amp;lt;/code&amp;gt; (modificable), &amp;lt;code&amp;gt;kiCost&amp;lt;/code&amp;gt; (modificable)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;PlayerEvasionEvent&amp;lt;/code&amp;gt; || Sí || Antes de que se active una evasión. || &amp;lt;code&amp;gt;player&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;attacker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;originalDamage&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;kiCost&amp;lt;/code&amp;gt; (modificable)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;CritChanceEvent&amp;lt;/code&amp;gt; || No || Mientras se calcula la probabilidad crítica de un jugador. || &amp;lt;code&amp;gt;player&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;chance&amp;lt;/code&amp;gt; (modificable, de 0 a 1)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;KiAttackCastEvent&amp;lt;/code&amp;gt; || No || Un jugador empieza a cargar (lanza) un ataque de ki. || &amp;lt;code&amp;gt;player&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;statsData&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;kiAttack&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;KiAttackFireEvent&amp;lt;/code&amp;gt; || No || Se suelta un ataque de ki cargado. || &amp;lt;code&amp;gt;player&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;statsData&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;kiAttack&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;chargeMultiplier&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;cooldownTicks&amp;lt;/code&amp;gt; (modificable, mínimo 1)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StrikeAttackCastEvent&amp;lt;/code&amp;gt; || No || Un jugador inicia un Super Golpe. || &amp;lt;code&amp;gt;player&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;statsData&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;strike&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StrikeAttackFireEvent&amp;lt;/code&amp;gt; || No || Un Super Golpe conecta y empieza sobre un objetivo. || &amp;lt;code&amp;gt;player&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;statsData&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;strike&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;target&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;DamageSourceType&amp;lt;/code&amp;gt; también contiene un valor &amp;lt;code&amp;gt;KI&amp;lt;/code&amp;gt;; en la v2.2, los ataques de ki no publican &amp;lt;code&amp;gt;DamageModifyEvent&amp;lt;/code&amp;gt; ni &amp;lt;code&amp;gt;DamageDealtEvent&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;Fusions_and_dragons&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
=== Fusiones y dragones ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Evento !! Cancelable !! Se dispara cuando !! Campos clave&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;FusionEvent&amp;lt;/code&amp;gt; || Sí || Antes de un intento de fusión. DMZ lo publica para las fusiones &amp;lt;code&amp;gt;METAMORU&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;POTHALA&amp;lt;/code&amp;gt; y &amp;lt;code&amp;gt;BEETLE&amp;lt;/code&amp;gt; (Escarabajo Medi-Bug); el enum también contiene &amp;lt;code&amp;gt;ABSORPTION&amp;lt;/code&amp;gt; y &amp;lt;code&amp;gt;ASSIMILATION&amp;lt;/code&amp;gt;. || &amp;lt;code&amp;gt;initiator&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;target&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;type&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;DragonSummonedEvent&amp;lt;/code&amp;gt; || No || Después de invocar un dragón con un conjunto de esferas completo. || &amp;lt;code&amp;gt;player&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;level&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;position&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;dragonDefinition&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ballSetDefinition&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;consumedPositions&amp;lt;/code&amp;gt;; auxiliares &amp;lt;code&amp;gt;getDragonId()&amp;lt;/code&amp;gt; y &amp;lt;code&amp;gt;getBallSetId()&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Consulta [[Special:MyLanguage/Fusions|Fusiones]] y [[Special:MyLanguage/Dragons and Wishes|Dragones y deseos]] para ver la parte de jugabilidad.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;Quests&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
=== Misiones ===&lt;br /&gt;
Todos los eventos de misiones extienden &amp;lt;code&amp;gt;QuestLifecycleEvent&amp;lt;/code&amp;gt; y comparten sus campos: &amp;lt;code&amp;gt;player&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;questKey&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;sagaId:questId&amp;lt;/code&amp;gt; para las misiones de saga, el id de texto para las misiones secundarias), &amp;lt;code&amp;gt;saga&amp;lt;/code&amp;gt; (null para las misiones secundarias), &amp;lt;code&amp;gt;quest&amp;lt;/code&amp;gt; y &amp;lt;code&amp;gt;partyMembers&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Evento !! Cancelable !! Se dispara cuando !! Campos extra&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;QuestStartEvent&amp;lt;/code&amp;gt; || Sí || Antes de aceptar una misión. || &amp;lt;code&amp;gt;difficulty&amp;lt;/code&amp;gt; (modificable)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;QuestObjectiveProgressEvent&amp;lt;/code&amp;gt; || Sí || Antes de guardar el progreso de un objetivo. || &amp;lt;code&amp;gt;objectiveIndex&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;oldProgress&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;newProgress&amp;lt;/code&amp;gt; (modificable), &amp;lt;code&amp;gt;objectiveRequired&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;QuestFailEvent&amp;lt;/code&amp;gt; || Sí || Antes de marcar una misión como fallida. || &amp;lt;code&amp;gt;reason&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;PLAYER_DEATH&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;FORCED_RESET&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;SCRIPT&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;TIME_EXPIRED&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ESCORT_FAILED&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;QuestTurnInEvent&amp;lt;/code&amp;gt; || Sí || Antes de aplicar la entrega de una misión. || &amp;lt;code&amp;gt;npcId&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;QuestRewardClaimEvent&amp;lt;/code&amp;gt; || Sí || Antes de reclamar una recompensa individual. || &amp;lt;code&amp;gt;rewardIndex&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;QuestCompletedEvent&amp;lt;/code&amp;gt; || No || Cuando se completa una misión. || Solo los campos compartidos&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;Client_events&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
=== Eventos de cliente ===&lt;br /&gt;
Los eventos solo de cliente están en &amp;lt;code&amp;gt;com.dragonminez.client.events.DMZClientEvent&amp;lt;/code&amp;gt; y se publican en el bus de Forge del cliente físico. Registra estos listeners con &amp;lt;code&amp;gt;value = Dist.CLIENT&amp;lt;/code&amp;gt;. Ninguno es cancelable y son solo informativos: el servidor sigue decidiendo lo que realmente ocurre.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Evento !! Se dispara cuando !! Campos clave&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;PlayerAttackStart&amp;lt;/code&amp;gt; || El jugador local empieza la preparación del ataque. || &amp;lt;code&amp;gt;player&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;attackHand&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;PlayerAttackHit&amp;lt;/code&amp;gt; || El ataque del jugador local resuelve sus objetivos (cero o más). || &amp;lt;code&amp;gt;player&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;attackHand&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;targets&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;cursorTarget&amp;lt;/code&amp;gt; (puede ser null)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;KiAttackCast&amp;lt;/code&amp;gt; || El jugador local empieza a cargar el ataque de ki de una ranura. || &amp;lt;code&amp;gt;player&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;slot&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;KiAttackRelease&amp;lt;/code&amp;gt; || El jugador local suelta un ataque de ki cargado. || &amp;lt;code&amp;gt;player&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StrikeAttack&amp;lt;/code&amp;gt; || El jugador local inicia un Super Golpe. || &amp;lt;code&amp;gt;player&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;targetId&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;Reading_player_state&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
== Leer el estado del jugador ==&lt;br /&gt;
Obtén la capability de cualquier &amp;lt;code&amp;gt;Player&amp;lt;/code&amp;gt; (un jugador del servidor, o el jugador local en el cliente; DMZ mantiene sincronizada la copia del cliente):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
StatsProvider.get(StatsCapability.INSTANCE, player).ifPresent(data -&amp;gt; {&lt;br /&gt;
    String race = data.getCharacter().getRaceName();&lt;br /&gt;
    String activeForm = data.getCharacter().getActiveForm();&lt;br /&gt;
    float currentKi = data.getResources().getCurrentEnergy();&lt;br /&gt;
    float maxKi = data.getMaxEnergy();&lt;br /&gt;
    int level = data.getLevel();&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;StatsProvider.get(cap, entity)&amp;lt;/code&amp;gt; es un atajo de &amp;lt;code&amp;gt;player.getCapability(StatsCapability.INSTANCE)&amp;lt;/code&amp;gt;; ambos devuelven un &amp;lt;code&amp;gt;LazyOptional&amp;lt;StatsData&amp;gt;&amp;lt;/code&amp;gt;. Lombok genera los getters de DMZ en tiempo de compilación, así que no necesitas Lombok en tu addon para llamarlos.&lt;br /&gt;
&lt;br /&gt;
Lecturas útiles de &amp;lt;code&amp;gt;StatsData&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Getter !! Devuelve&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;getCharacter().getRaceName() / getCharacterClass() / getGender()&amp;lt;/code&amp;gt; || Raza, clase y género&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;getCharacter().getActiveForm() / getActiveFormGroup()&amp;lt;/code&amp;gt; || Forma de raza actual (un texto vacío en la forma base)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;getCharacter().getActiveStackForm() / getActiveStackFormGroup()&amp;lt;/code&amp;gt; || Forma acumulable actual (por ejemplo, el nivel de Kaioken)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;getStats().getStrength() / getStrikePower() / getResistance() / getVitality() / getKiPower() / getEnergy()&amp;lt;/code&amp;gt; || Valores base de las estadísticas&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;getResources().getCurrentEnergy() / getCurrentStamina() / getCurrentPoise() / getAlignment()&amp;lt;/code&amp;gt; || Reservas de recursos actuales y alineamiento&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;getMaxHealth() / getMaxEnergy() / getMaxStamina() / getMaxPoise()&amp;lt;/code&amp;gt; || Topes de recursos calculados&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;getBattlePower() / getMeleeDamage() / getStrikeDamage() / getKiDamage() / getDefense()&amp;lt;/code&amp;gt; || Estadísticas de combate calculadas&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;getLevel()&amp;lt;/code&amp;gt; || Nivel de jugador calculado&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;getPlayerQuestData()&amp;lt;/code&amp;gt; || Progreso de misiones (&amp;lt;code&amp;gt;getQuestStatus(questKey)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;isQuestAccepted(questKey)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;isQuestCompleted(questKey)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;isSagaLocked(sagaId)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;getTrackedQuestId()&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;getDifficulty()&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;getSkills()&amp;lt;/code&amp;gt; || Niveles de habilidades (&amp;lt;code&amp;gt;hasSkill(name)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;getSkillLevel(name)&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;getStatus()&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;getEffects()&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;getTechniques()&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;getBonusStats()&amp;lt;/code&amp;gt; || Indicadores de estado, efectos activos, técnicas de ki y de golpe, modificadores de estadísticas extra&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Los cálculos de raza, forma y estadísticas leen la configuración en vivo cada vez, así que los valores siempre reflejan la configuración actual del servidor (también después de &amp;lt;code&amp;gt;/dmzreload&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;Changing_state_safely&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
== Cambiar el estado de forma segura ==&lt;br /&gt;
Los setters de estadísticas propios de DMZ (por ejemplo &amp;lt;code&amp;gt;Stats.setStrength()&amp;lt;/code&amp;gt;) publican primero un evento cancelable y solo aplican el cambio si no se canceló:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
DMZEvent.StatChangeEvent event = new DMZEvent.StatChangeEvent(player, StatType.STRENGTH, oldValue, newValue);&lt;br /&gt;
if (!MinecraftForge.EVENT_BUS.post(event)) {&lt;br /&gt;
    // apply the change&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En tu addon, es preferible &amp;#039;&amp;#039;&amp;#039;reaccionar a&amp;#039;&amp;#039;&amp;#039; los eventos (cambiando sus campos modificables o cancelándolos) que llamar directamente a los setters de DMZ. No todos los setters validan o publican un evento (la mayoría de los setters de &amp;lt;code&amp;gt;Resources&amp;lt;/code&amp;gt;, por ejemplo, solo limitan el valor y lo aplican sin evento), así que pasar por los eventos es el único punto de integración garantizado que se mantendrá estable.&lt;br /&gt;
&lt;br /&gt;
Si cambias datos de DMZ desde el servidor, hazlo en el hilo del servidor y después envía al cliente una copia actualizada, igual que hace DMZ:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
NetworkHandler.sendToTrackingEntityAndSelf(new StatsSyncS2C(serverPlayer), serverPlayer);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;StatsSyncS2C&amp;lt;/code&amp;gt; envía todos los datos del jugador; DMZ también usa &amp;lt;code&amp;gt;ProgressionSyncS2C&amp;lt;/code&amp;gt; (estadísticas, estadísticas extra, habilidades, técnicas, datos de misiones) y &amp;lt;code&amp;gt;ResourceSyncS2C&amp;lt;/code&amp;gt; (recursos y estado) para actualizaciones más pequeñas.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;Custom_quest_objectives_and_rewards&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
== Objetivos y recompensas de misión personalizados ==&lt;br /&gt;
{{See also|Custom Quests}}&lt;br /&gt;
Los addons pueden añadir nuevos &amp;#039;&amp;#039;&amp;#039;tipos&amp;#039;&amp;#039;&amp;#039; de objetivos y recompensas de misiones que luego pueden usar los archivos JSON de misiones, sin tocar el parser de DMZ. Regístralos durante la configuración del mod (por ejemplo, en &amp;lt;code&amp;gt;FMLCommonSetupEvent&amp;lt;/code&amp;gt;) en &amp;#039;&amp;#039;&amp;#039;ambos&amp;#039;&amp;#039;&amp;#039; lados: el cliente reconstruye las misiones a partir del registro sincronizado con las mismas fábricas.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
QuestObjectiveRegistry.register(&amp;quot;MEDITATE&amp;quot;,&lt;br /&gt;
    json -&amp;gt; new MeditateObjective(json.get(&amp;quot;seconds&amp;quot;).getAsInt()),                                 // parse quest JSON&lt;br /&gt;
    (objective, out) -&amp;gt; out.addProperty(&amp;quot;seconds&amp;quot;, ((MeditateObjective) objective).getSeconds()),  // client sync fields&lt;br /&gt;
    objective -&amp;gt; Component.translatable(&amp;quot;myaddon.quest.meditate.obj&amp;quot;));                            // HUD/journal text&lt;br /&gt;
&lt;br /&gt;
QuestRewardRegistry.register(&amp;quot;MY_CURRENCY&amp;quot;,&lt;br /&gt;
    json -&amp;gt; new MyCurrencyReward(json.get(&amp;quot;amount&amp;quot;).getAsInt()),&lt;br /&gt;
    (reward, out) -&amp;gt; out.addProperty(&amp;quot;amount&amp;quot;, ((MyCurrencyReward) reward).getAmount()));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
El contrato:&lt;br /&gt;
* Las clases de objetivos extienden &amp;lt;code&amp;gt;QuestObjective&amp;lt;/code&amp;gt; y llaman al constructor &amp;lt;code&amp;gt;QuestObjective(String customType, int required)&amp;lt;/code&amp;gt;; las clases de recompensas extienden &amp;lt;code&amp;gt;QuestReward&amp;lt;/code&amp;gt;, llaman a &amp;lt;code&amp;gt;QuestReward(String customType)&amp;lt;/code&amp;gt; e implementan &amp;lt;code&amp;gt;giveReward(ServerPlayer)&amp;lt;/code&amp;gt; y &amp;lt;code&amp;gt;getDescription()&amp;lt;/code&amp;gt;. Los objetivos también deben implementar &amp;lt;code&amp;gt;checkProgress(Object... params)&amp;lt;/code&amp;gt;.&lt;br /&gt;
* En el JSON de las misiones, usa tu clave como &amp;lt;code&amp;gt;&amp;quot;type&amp;quot;&amp;lt;/code&amp;gt; (por ejemplo &amp;lt;code&amp;gt;{&amp;quot;type&amp;quot;: &amp;quot;MEDITATE&amp;quot;, &amp;quot;seconds&amp;quot;: 60}&amp;lt;/code&amp;gt;). Las claves de tipo no distinguen mayúsculas de minúsculas (se guardan en mayúsculas). Trátalas como nombres de registro: no las renombres una vez que las misiones las usen.&lt;br /&gt;
* El escritor de sincronización debe escribir todos los campos que lee tu fábrica, porque el cliente vuelve a analizar el JSON sincronizado con tu fábrica.&lt;br /&gt;
* Los tipos desconocidos se informan en el reporte de carga de JSON (consulta [[Special:MyLanguage/Developer Scope and Prerequisites#Finding JSON mistakes|Encontrar errores de JSON]]) y el objetivo o la recompensa se omite.&lt;br /&gt;
* El progreso lo controla el servidor y se basa en eventos: escucha tus propios eventos de juego en el servidor y guarda el progreso con &amp;lt;code&amp;gt;PlayerQuestData.setObjectiveProgress(questKey, objectiveIndex, progress)&amp;lt;/code&amp;gt;, y luego sincroniza con &amp;lt;code&amp;gt;ProgressionSyncS2C&amp;lt;/code&amp;gt;. Usa &amp;lt;code&amp;gt;DMZEvent.QuestObjectiveProgressEvent&amp;lt;/code&amp;gt; y &amp;lt;code&amp;gt;QuestCompletedEvent&amp;lt;/code&amp;gt; para reaccionar a las misiones incluidas.&lt;br /&gt;
&lt;br /&gt;
Consulta [[Special:MyLanguage/Custom Quests|Misiones personalizadas]] para ver el formato JSON de las misiones.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;Custom_text_placeholders&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
== Placeholders de texto personalizados ==&lt;br /&gt;
Los textos de misiones, diálogos y NPCs admiten &amp;lt;code&amp;gt;%placeholders%&amp;lt;/code&amp;gt; como &amp;lt;code&amp;gt;%player%&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;%race%&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;%class%&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;%level%&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;%alignment%&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;%deaths%&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;%form%&amp;lt;/code&amp;gt; y &amp;lt;code&amp;gt;%dimension%&amp;lt;/code&amp;gt;. Añade los tuyos durante la configuración del mod:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
DMZTextPlaceholders.register(&amp;quot;zeni&amp;quot;, (player, data) -&amp;gt; String.valueOf(MyAddon.getZeni(player)));&lt;br /&gt;
// &amp;quot;%zeni%&amp;quot; in quest/dialogue text now resolves to your value&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Las claves no distinguen mayúsculas de minúsculas. El resolvedor se ejecuta en el lado que renderiza el texto (normalmente el cliente) y debe manejar un &amp;lt;code&amp;gt;StatsData&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;Utility_menu_buttons&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
== Botones del menú de utilidades ==&lt;br /&gt;
El menú de utilidades (radial) del cliente tiene dos ranuras libres, a la izquierda y a la derecha de la rueda, reservadas para addons. Añade un botón desde la configuración del cliente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
UtilityMenuScreen.addMenuSlot(new IUtilityMenuSlot() {&lt;br /&gt;
    @Override&lt;br /&gt;
    public ButtonInfo render(StatsData statsData) {&lt;br /&gt;
        return new ButtonInfo(Component.literal(&amp;quot;My Addon&amp;quot;), Component.literal(&amp;quot;Open&amp;quot;));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @Override&lt;br /&gt;
    public void handle(StatsData statsData, boolean rightClick) {&lt;br /&gt;
        // client side: open your screen or send your own packet to the server&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Las ranuras se llenan en orden de registro; los registros que superen las dos ranuras libres no se muestran. Sobrescribe &amp;lt;code&amp;gt;hasRightClickAction&amp;lt;/code&amp;gt; para que devuelva &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; si tu botón también reacciona al clic derecho. &amp;lt;code&amp;gt;IUtilityMenuSlot&amp;lt;/code&amp;gt; y &amp;lt;code&amp;gt;ButtonInfo&amp;lt;/code&amp;gt; están en &amp;lt;code&amp;gt;com.dragonminez.client.gui.utilitymenu&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;Armor_and_render_layers&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
== Armaduras y capas de renderizado ==&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Armaduras de tu addon:&amp;#039;&amp;#039;&amp;#039; la clase de objeto de armadura de DMZ, &amp;lt;code&amp;gt;DbzArmorItem&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;common/init/armor&amp;lt;/code&amp;gt;), tiene un constructor &amp;lt;code&amp;gt;DbzArmorItem(material, type, properties, modId, itemId)&amp;lt;/code&amp;gt;. Pasa tu propio &amp;lt;code&amp;gt;modId&amp;lt;/code&amp;gt; y las texturas se leen de tu propio namespace: &amp;lt;code&amp;gt;assets/&amp;lt;modId&amp;gt;/textures/armor/&amp;lt;itemId&amp;gt;_layer1.png&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;_layer2&amp;lt;/code&amp;gt; para las grebas), más las opcionales &amp;lt;code&amp;gt;&amp;lt;itemId&amp;gt;_damaged_layer1.png&amp;lt;/code&amp;gt; y &amp;lt;code&amp;gt;_damaged_layer2.png&amp;lt;/code&amp;gt;, que se usan cuando el objeto ha perdido más de la mitad de su durabilidad.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Otras armaduras:&amp;#039;&amp;#039;&amp;#039; los &amp;lt;code&amp;gt;ArmorItem&amp;lt;/code&amp;gt; normales de otros mods se dibujan sobre el modelo de jugador de DMZ con su textura de armadura habitual.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Capas de renderizado de terceros:&amp;#039;&amp;#039;&amp;#039; las capas de renderizado que otros mods añaden al renderizador de jugador vanilla se trasladan al modelo de jugador de DMZ. Se omiten las capas vanilla y las capas de armaduras cosméticas, y no se traslada nada mientras el jugador es un Oozaru.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;Networking&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
== Red ==&lt;br /&gt;
El canal de DMZ es &amp;lt;code&amp;gt;NetworkHandler.INSTANCE&amp;lt;/code&amp;gt; (un &amp;lt;code&amp;gt;SimpleChannel&amp;lt;/code&amp;gt; de Forge en &amp;lt;code&amp;gt;dragonminez:network&amp;lt;/code&amp;gt;). No registres tus propios paquetes en él: DMZ asigna los ids de paquete por orden de registro, así que cualquier cosa que añadas desplazaría los ids de DMZ o chocaría con ellos. En su lugar, registra tu propio &amp;lt;code&amp;gt;SimpleChannel&amp;lt;/code&amp;gt; en tu addon y usa el de DMZ como referencia del patrón (&amp;lt;code&amp;gt;messageBuilder&amp;lt;/code&amp;gt;, codificador, decodificador y manejador, con una dirección explícita).&lt;br /&gt;
&lt;br /&gt;
Puedes usar los helpers de envío de DMZ (&amp;lt;code&amp;gt;sendToPlayer&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;sendToTrackingEntityAndSelf&amp;lt;/code&amp;gt;, ...) para enviar los paquetes de sincronización propios de DMZ, como se muestra arriba.&lt;br /&gt;
&lt;br /&gt;
Tampoco confíes nunca en el cliente en tus propios paquetes: valida en el servidor todo lo que afecte a estadísticas, desbloqueos, misiones, deseos o progreso.&lt;br /&gt;
&lt;br /&gt;
No existe un evento de &amp;quot;datos sincronizados&amp;quot; en el lado del cliente. En el cliente, lee la capability cuando la necesites (por ejemplo, al renderizar) en lugar de intentar interceptar los paquetes de DMZ.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;Using_DMZ&amp;amp;#039;s_registries&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
== Usar los registros de DMZ ==&lt;br /&gt;
Importa directamente los contenedores de registro &amp;lt;code&amp;gt;Main*&amp;lt;/code&amp;gt; en lugar de escribir a mano las resource locations:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
import com.dragonminez.common.init.MainItems;&lt;br /&gt;
import com.dragonminez.common.init.MainAttributes;&lt;br /&gt;
&lt;br /&gt;
Item redCapsule = MainItems.RED_CAPSULE.get();&lt;br /&gt;
Attribute strength = MainAttributes.STRENGTH.get();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Disponibles en &amp;lt;code&amp;gt;common/init/&amp;lt;/code&amp;gt;: &amp;lt;code&amp;gt;MainItems&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;MainBlocks&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;MainBlockEntities&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;MainEntities&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;MainAttributes&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;MainEffects&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;MainEnchants&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;MainPotions&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;MainSounds&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;MainParticles&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;MainFluids&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;MainMenus&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;MainRecipes&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;MainTabs&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;MainTags&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;MainVillagers&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;MainDamageTypes&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;MainGameRules&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;MainLootModifiers&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;Optional_dependency_pattern&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
== Patrón de dependencia opcional ==&lt;br /&gt;
Si tu addon debe funcionar con o sin DMZ instalado, sigue el patrón que usa DMZ para sus propias integraciones opcionales (&amp;lt;code&amp;gt;common/compat/WeaponLevelingCompat.java&amp;lt;/code&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public final class DmzCompat {&lt;br /&gt;
    private static Boolean loaded;&lt;br /&gt;
&lt;br /&gt;
    public static boolean isLoaded() {&lt;br /&gt;
        if (loaded == null) loaded = ModList.get().isLoaded(&amp;quot;dragonminez&amp;quot;);&lt;br /&gt;
        return loaded;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public static int getLevel(Player player) {&lt;br /&gt;
        if (!isLoaded()) return 0;   // safe fallback without DMZ&lt;br /&gt;
        return Impl.getLevel(player);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Only this nested class imports DMZ classes, so it is never loaded without DMZ.&lt;br /&gt;
    private static final class Impl {&lt;br /&gt;
        static int getLevel(Player player) {&lt;br /&gt;
            return StatsProvider.get(StatsCapability.INSTANCE, player).map(StatsData::getLevel).orElse(0);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Comprueba &amp;lt;code&amp;gt;ModList.get().isLoaded(&amp;quot;dragonminez&amp;quot;)&amp;lt;/code&amp;gt; una sola vez y guarda el resultado en caché.&lt;br /&gt;
# Mantén todos los imports de DMZ dentro de clases que solo se tocan después de esa comprobación (incluidos los listeners de eventos de DMZ: regístralos a mano y solo cuando DMZ esté cargado).&lt;br /&gt;
# Protege con ese indicador toda llamada que toque DMZ, con un comportamiento alternativo seguro o un valor por defecto cuando sea &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Registra en el log un mensaje claro de información o de advertencia en ambos casos, para que los dueños de servidores vean de un vistazo si la integración está activa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;Next_step&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
== Siguiente paso ==&lt;br /&gt;
Consulta [[Special:MyLanguage/Creating a DMZ Addon|Crear un addon de DMZ]] para la configuración completa del proyecto de Gradle y la declaración de la dependencia en &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Navbox Add-ons}}&lt;/div&gt;</summary>
		<author><name>Shokkoh</name></author>
	</entry>
</feed>