Saltar a contenido

Ejemplo: Custom Interaction

Ejemplo de cómo crear una interacción personalizada.

Interacción Teleport

package com.ejemplo.interactions;

import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.protocol.InteractionState;
import com.hypixel.hytale.protocol.InteractionType;
import com.hypixel.hytale.server.core.entity.InteractionContext;
import com.hypixel.hytale.server.core.entity.LivingEntity;
import com.hypixel.hytale.server.core.modules.interaction.interaction.CooldownHandler;
import com.hypixel.hytale.server.core.modules.interaction.interaction.config.SimpleInstantInteraction;
import javax.annotation.Nonnull;

/**
 * Interacción que teletransporta al jugador 5 bloques hacia adelante.
 */
public class TeleportInteraction extends SimpleInstantInteraction {

    private final double teleportDistance = 5.0;

    public TeleportInteraction() {
        super();
        this.id = "custom:teleport";
        this.runTime = 0.5f; // 0.5 segundos de cooldown
    }

    @Override
    protected void firstRun(@Nonnull InteractionType type,
                           @Nonnull InteractionContext context,
                           @Nonnull CooldownHandler cooldownHandler) {

        // Obtener entidad
        LivingEntity entity = getEntity(context);
        if (entity == null) {
            failInteraction(context);
            return;
        }

        // Calcular nueva posición
        Vector3d currentPos = entity.getPosition();
        Vector3d lookDir = entity.getLookDirection();

        Vector3d newPos = new Vector3d(
            currentPos.x + lookDir.x * teleportDistance,
            currentPos.y,
            currentPos.z + lookDir.z * teleportDistance
        );

        // Teletransportar
        entity.setPosition(newPos);

        // Mensaje
        entity.sendMessage("¡Teletransportado!");

        // Completar interacción
        context.getState().state = InteractionState.Finished;
    }

    private LivingEntity getEntity(InteractionContext ctx) {
        var ref = ctx.getEntity();
        if (ref == null || !ref.isValid()) return null;

        var buffer = ctx.getCommandBuffer();
        if (buffer == null) return null;

        var entity = buffer.getEntity(ref);
        return entity instanceof LivingEntity ? (LivingEntity) entity : null;
    }

    private void failInteraction(InteractionContext ctx) {
        ctx.getState().state = InteractionState.Failed;
    }
}

Interacción con Metadatos

public class CounterInteraction extends SimpleInstantInteraction {

    // MetaKey para contador
    private static final MetaKey<Integer> USE_COUNT =
        Interaction.META_REGISTRY.registerMetaObject(i -> 0);

    @Override
    protected void firstRun(InteractionType type,
                           InteractionContext context,
                           CooldownHandler cooldownHandler) {

        // Incrementar contador
        int count = context.getMetaObject(USE_COUNT);
        context.putMetaObject(USE_COUNT, count + 1);

        // Obtener entidad
        LivingEntity entity = getEntity(context);
        if (entity != null) {
            entity.sendMessage("Usos: " + (count + 1));
        }

        context.getState().state = InteractionState.Finished;
    }
}

Interacción con Target

public class HighlightEntityInteraction extends SimpleInstantInteraction {

    @Override
    protected void firstRun(InteractionType type,
                           InteractionContext context,
                           CooldownHandler cooldownHandler) {

        // Obtener entidad objetivo
        Ref<EntityStore> targetRef =
            context.getMetaObject(Interaction.TARGET_ENTITY);

        if (targetRef == null || !targetRef.isValid()) {
            context.getState().state = InteractionState.Failed;
            return;
        }

        // Obtener ubicación del impacto
        Vector4d hitLocation =
            context.getMetaObject(Interaction.HIT_LOCATION);

        // Procesar
        CommandBuffer<EntityStore> buffer = context.getCommandBuffer();
        Entity target = buffer.getEntity(targetRef);

        // Aplicar efecto de highlight
        applyHighlight(target, hitLocation);

        context.getState().state = InteractionState.Finished;
    }

    private void applyHighlight(Entity entity, Vector4d hitPos) {
        // Lógica para destacar la entidad
        System.out.println("Destacando: " + entity + " en " + hitPos);
    }
}

Interacción Progresiva

public class ChargingBlastInteraction extends Interaction {

    private float chargeTime = 2.0f; // 2 segundos para carga completa

    @Override
    protected void tick0(boolean firstRun, float time,
                        InteractionType type,
                        InteractionContext context,
                        CooldownHandler cooldownHandler) {

        float progress = Math.min(time / chargeTime, 1.0f);

        // Actualizar efectos según progreso
        updateChargeEffects(context, progress);

        if (time >= chargeTime) {
            // Carga completa - disparar
            fireBlast(context, progress);
            context.getState().state = InteractionState.Finished;
        } else {
            // Aún cargando
            context.getState().state = InteractionState.NotFinished;
            context.getState().progress = time;
        }
    }

    @Override
    protected void simulateTick0(boolean firstRun, float time,
                                 InteractionType type,
                                 InteractionContext context,
                                 CooldownHandler cooldownHandler) {
        // Misma lógica para predicción cliente
        tick0(firstRun, time, type, context, cooldownHandler);
    }

    @Override
    public boolean walk(Collector collector, InteractionContext context) {
        return true;
    }

    private void updateChargeEffects(InteractionContext ctx, float progress) {
        // Actualizar partículas, sonido, etc.
    }

    private void fireBlast(InteractionContext ctx, float power) {
        // Disparar proyectil
    }
}

Registrar Interacción

// En tu plugin o mod
public class MyPlugin {

    public static void registerInteractions() {
        AssetStore<String, Interaction, ?> store =
            Interaction.getAssetStore();

        // Registrar interacciones
        store.loadAssets("MyMod:MyMod", List.of(
            new TeleportInteraction(),
            new CounterInteraction(),
            new HighlightEntityInteraction()
        ));

        System.out.println("[MyPlugin] Interacciones registradas");
    }
}

Ver También