feat(phase-1): scaffold ChainLightning Sceptre plugin

Build infrastructure (Gradle wrapper, shadow, Java 25), manifest, item
JSON + interactions, and ChainLightningPlugin entry with stub handler
that logs sceptre clicks. Cooldown wiring deferred to Phase 3 (real
Hytale API is getCooldown(id).setCooldownMax — not cooldown(Duration)).
This commit is contained in:
2026-04-26 19:22:18 +02:00
parent d06743acbe
commit edca00fa4a
14 changed files with 656 additions and 0 deletions
@@ -0,0 +1,70 @@
package com.mythlane.chainlightning.sceptre;
import com.hypixel.hytale.codec.builder.BuilderCodec;
import com.hypixel.hytale.component.CommandBuffer;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.protocol.InteractionType;
import com.hypixel.hytale.server.core.entity.InteractionContext;
import com.hypixel.hytale.server.core.modules.interaction.interaction.CooldownHandler;
import com.hypixel.hytale.server.core.modules.interaction.interaction.config.SimpleInstantInteraction;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import javax.annotation.Nonnull;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Phase 1 stub interaction handler for the Chain Lightning Sceptre item.
* Logs the click + applies a 4s cooldown smoke-test. Full chain logic lands in Phase 3.
*/
public final class ChainLightningSceptreInteraction extends SimpleInstantInteraction {
private static final Logger LOGGER = Logger.getLogger(ChainLightningSceptreInteraction.class.getName());
@Nonnull
public static final BuilderCodec<ChainLightningSceptreInteraction> CODEC =
((BuilderCodec.Builder) BuilderCodec
.builder(ChainLightningSceptreInteraction.class,
ChainLightningSceptreInteraction::new,
SimpleInstantInteraction.CODEC)
.documentation(
"Chain Lightning sceptre: primary/secondary click chains lightning to up to 5 targets."))
.build();
public ChainLightningSceptreInteraction() {
}
@Override
protected void firstRun(@Nonnull InteractionType type,
@Nonnull InteractionContext context,
@Nonnull CooldownHandler cooldownHandler) {
// Phase 1: stub only. Identify the player for traceability, log, then arm the cooldown
// (smoke test of the CooldownHandler API — actual chain resolution lands in Phase 3).
UUID playerUuid = null;
try {
Ref<EntityStore> entityRef = context.getEntity();
CommandBuffer<EntityStore> commandBuffer = context.getCommandBuffer();
if (entityRef != null && commandBuffer != null) {
PlayerRef playerRef = commandBuffer.getComponent(entityRef, PlayerRef.getComponentType());
if (playerRef != null) {
playerUuid = playerRef.getUuid();
}
}
} catch (Throwable ignored) {
// Defensive: never fail the click because of telemetry.
}
LOGGER.log(Level.INFO,
"[ChainLightning] sceptre clicked by player {0} (type={1})",
new Object[]{playerUuid, type});
// TODO Phase 3: wire cooldown via CooldownHandler.
// Confirmed API (javap on Server-2026.03.26-89796e57b.jar):
// CooldownHandler has NO cooldown(Duration) method.
// Use: cooldownHandler.getCooldown("primary").setCooldownMax(4f)
// then cooldownHandler.resetCooldown("primary", ...) on next tick.
// Full cooldown integration deferred to Phase 3 to keep Phase 1 build green.
}
}