From d722c40526c1700f7af336a879bdc7fa8109fc14 Mon Sep 17 00:00:00 2001 From: luk Date: Sat, 31 Jan 2026 00:43:41 +0000 Subject: [PATCH] src: add 2 files --- .../events/ecs/ChangeHotbarSlotEvent.java | 43 +++++ .../none/ChangeActiveSlotInteraction.java | 166 ++++++++++++++++++ 2 files changed, 209 insertions(+) create mode 100644 src/com/hypixel/hytale/server/core/event/events/ecs/ChangeHotbarSlotEvent.java create mode 100644 src/com/hypixel/hytale/server/core/modules/interaction/interaction/config/none/ChangeActiveSlotInteraction.java diff --git a/src/com/hypixel/hytale/server/core/event/events/ecs/ChangeHotbarSlotEvent.java b/src/com/hypixel/hytale/server/core/event/events/ecs/ChangeHotbarSlotEvent.java new file mode 100644 index 00000000..a6a4791f --- /dev/null +++ b/src/com/hypixel/hytale/server/core/event/events/ecs/ChangeHotbarSlotEvent.java @@ -0,0 +1,43 @@ +package com.hypixel.hytale.server.core.event.events.ecs; + +import com.hypixel.hytale.component.system.CancellableEcsEvent; + +/** + * Fired when a player changes their active hotbar slot. + */ +public class ChangeHotbarSlotEvent extends CancellableEcsEvent { + private final byte previousSlot; + private byte newSlot; + private final boolean serverRequest; + + public ChangeHotbarSlotEvent(byte previousSlot, byte newSlot, boolean serverRequest) { + this.previousSlot = previousSlot; + this.newSlot = newSlot; + this.serverRequest = serverRequest; + } + + public byte getPreviousSlot() { + return previousSlot; + } + + public byte getNewSlot() { + return newSlot; + } + + public void setNewSlot(byte newSlot) { + this.newSlot = newSlot; + } + + public boolean isServerRequest() { + return serverRequest; + } + + public boolean isClientRequest() { + return !serverRequest; + } + + @Override + public String toString() { + return "ChangeHotbarSlotEvent{previousSlot=" + previousSlot + ", newSlot=" + newSlot + ", serverRequest=" + serverRequest + "}"; + } +} diff --git a/src/com/hypixel/hytale/server/core/modules/interaction/interaction/config/none/ChangeActiveSlotInteraction.java b/src/com/hypixel/hytale/server/core/modules/interaction/interaction/config/none/ChangeActiveSlotInteraction.java new file mode 100644 index 00000000..3c40efb6 --- /dev/null +++ b/src/com/hypixel/hytale/server/core/modules/interaction/interaction/config/none/ChangeActiveSlotInteraction.java @@ -0,0 +1,166 @@ +package com.hypixel.hytale.server.core.modules.interaction.interaction.config.none; + +import com.hypixel.hytale.codec.Codec; +import com.hypixel.hytale.codec.KeyedCodec; +import com.hypixel.hytale.codec.builder.BuilderCodec; +import com.hypixel.hytale.codec.validation.Validators; +import com.hypixel.hytale.component.CommandBuffer; +import com.hypixel.hytale.component.Ref; +import com.hypixel.hytale.protocol.InteractionCooldown; +import com.hypixel.hytale.protocol.InteractionState; +import com.hypixel.hytale.protocol.InteractionType; +import com.hypixel.hytale.protocol.WaitForDataFrom; +import com.hypixel.hytale.server.core.entity.EntityUtils; +import com.hypixel.hytale.server.core.entity.InteractionContext; +import com.hypixel.hytale.server.core.entity.InteractionManager; +import com.hypixel.hytale.server.core.entity.LivingEntity; +import com.hypixel.hytale.server.core.meta.DynamicMetaStore; +import com.hypixel.hytale.server.core.meta.MetaKey; +import com.hypixel.hytale.server.core.modules.interaction.interaction.CooldownHandler; +import com.hypixel.hytale.server.core.modules.interaction.interaction.config.Interaction; +import com.hypixel.hytale.server.core.modules.interaction.interaction.config.RootInteraction; +import com.hypixel.hytale.server.core.modules.interaction.interaction.config.data.Collector; +import com.hypixel.hytale.server.core.universe.world.storage.EntityStore; +import com.hypixel.hytale.server.core.event.events.ecs.ChangeHotbarSlotEvent; +import javax.annotation.Nonnull; + +public class ChangeActiveSlotInteraction extends Interaction { + @Nonnull + public static final ChangeActiveSlotInteraction DEFAULT_INTERACTION = new ChangeActiveSlotInteraction("*Change_Active_Slot"); + @Nonnull + public static final RootInteraction DEFAULT_ROOT = new RootInteraction( + "*Default_Swap", + new InteractionCooldown("ChangeActiveSlot", 0.0F, false, InteractionManager.DEFAULT_CHARGE_TIMES, true, false), + DEFAULT_INTERACTION.getId() + ); + @Deprecated + public static final MetaKey PLACE_MOVED_ITEM = CONTEXT_META_REGISTRY.registerMetaObject(i -> null); + private static final int UNSET_INT = Integer.MIN_VALUE; + @Nonnull + public static final BuilderCodec CODEC = BuilderCodec.builder( + ChangeActiveSlotInteraction.class, ChangeActiveSlotInteraction::new, Interaction.ABSTRACT_CODEC + ) + .documentation("Changes the active hotbar slot for the user of the interaction.") + .appendInherited( + new KeyedCodec<>("TargetSlot", Codec.INTEGER), + (o, i) -> o.targetSlot = i == null ? Integer.MIN_VALUE : i, + o -> o.targetSlot == Integer.MIN_VALUE ? null : o.targetSlot, + (o, p) -> o.targetSlot = p.targetSlot + ) + .addValidator(Validators.range(0, 8)) + .add() + .afterDecode(i -> i.cancelOnItemChange = false) + .build(); + protected int targetSlot = Integer.MIN_VALUE; + + public ChangeActiveSlotInteraction() { + } + + private ChangeActiveSlotInteraction(@Nonnull String id) { + super(id); + this.cancelOnItemChange = false; + } + + @Nonnull + @Override + public WaitForDataFrom getWaitForDataFrom() { + return WaitForDataFrom.None; + } + + @Override + protected void tick0( + boolean firstRun, float time, @Nonnull InteractionType type, @Nonnull InteractionContext context, @Nonnull CooldownHandler cooldownHandler + ) { + if (!firstRun) { + context.getState().state = InteractionState.Finished; + } else { + CommandBuffer commandBuffer = context.getCommandBuffer(); + + assert commandBuffer != null; + + Ref ref = context.getEntity(); + if (EntityUtils.getEntity(ref, commandBuffer) instanceof LivingEntity livingEntity) { + DynamicMetaStore var15 = context.getMetaStore(); + byte slot; + if (this.targetSlot == Integer.MIN_VALUE) { + slot = ((Number)var15.getMetaObject(TARGET_SLOT)).byteValue(); + } else { + if (livingEntity.getInventory().getActiveHotbarSlot() == this.targetSlot) { + context.getState().state = InteractionState.Finished; + return; + } + + slot = (byte)this.targetSlot; + var15.putMetaObject(TARGET_SLOT, Integer.valueOf(slot)); + } + + byte previousSlot = livingEntity.getInventory().getActiveHotbarSlot(); + ChangeHotbarSlotEvent event = new ChangeHotbarSlotEvent(previousSlot, slot, false); + commandBuffer.invoke(ref, event); + if (event.isCancelled()) { + context.getState().state = InteractionState.Finished; + return; + } + slot = event.getNewSlot(); + + livingEntity.getInventory().setActiveHotbarSlot(slot); + Runnable action = (Runnable)var15.removeMetaObject(PLACE_MOVED_ITEM); + if (action != null) { + action.run(); + } + + InteractionManager interactionManager = context.getInteractionManager(); + + assert interactionManager != null; + + InteractionContext forkContext = InteractionContext.forInteraction(interactionManager, ref, InteractionType.SwapTo, commandBuffer); + String forkInteractions = forkContext.getRootInteractionId(InteractionType.SwapTo); + if (forkInteractions != null) { + if (this.targetSlot != Integer.MIN_VALUE) { + forkContext.getMetaStore().putMetaObject(TARGET_SLOT, Integer.valueOf(slot)); + } + + context.fork(InteractionType.SwapTo, forkContext, RootInteraction.getRootInteractionOrUnknown(forkInteractions), action == null); + } + + context.getState().state = InteractionState.Finished; + } + } + } + + @Override + protected void simulateTick0( + boolean firstRun, float time, @Nonnull InteractionType type, @Nonnull InteractionContext context, @Nonnull CooldownHandler cooldownHandler + ) { + context.getState().state = context.getServerState().state; + } + + @Override + public boolean walk(@Nonnull Collector collector, @Nonnull InteractionContext context) { + return false; + } + + @Override + public boolean needsRemoteSync() { + return true; + } + + @Nonnull + @Override + protected com.hypixel.hytale.protocol.Interaction generatePacket() { + return new com.hypixel.hytale.protocol.ChangeActiveSlotInteraction(); + } + + @Override + protected void configurePacket(com.hypixel.hytale.protocol.Interaction packet) { + super.configurePacket(packet); + com.hypixel.hytale.protocol.ChangeActiveSlotInteraction p = (com.hypixel.hytale.protocol.ChangeActiveSlotInteraction)packet; + p.targetSlot = this.targetSlot; + } + + @Nonnull + @Override + public String toString() { + return "ChangeActiveSlotInteraction{targetSlot=" + this.targetSlot + "} " + super.toString(); + } +}