From 069009af2c9fd4c707492bf1a1d2baaa5fdf2a81 Mon Sep 17 00:00:00 2001 From: pipythonmc <47196755+pythonmcpi@users.noreply.github.com> Date: Sun, 12 Apr 2026 13:54:19 -0700 Subject: [PATCH 1/3] Batch pattern spiral packets when casting packaged items --- .../casting/eval/env/PackagedItemCastEnv.java | 18 +++---- .../casting/eval/env/PlayerBasedCastEnv.java | 4 ++ .../env/PlayerBasedSpiralPatternCastEnv.java | 48 +++++++++++++++++++ .../api/casting/eval/env/StaffCastEnv.java | 22 +++------ 4 files changed, 64 insertions(+), 28 deletions(-) create mode 100644 Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PlayerBasedSpiralPatternCastEnv.java diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PackagedItemCastEnv.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PackagedItemCastEnv.java index 43d0c67d28..284d20c4c5 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PackagedItemCastEnv.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PackagedItemCastEnv.java @@ -2,17 +2,14 @@ import at.petrak.hexcasting.api.casting.eval.CastResult; import at.petrak.hexcasting.api.casting.eval.sideeffects.EvalSound; -import at.petrak.hexcasting.api.casting.iota.PatternIota; import at.petrak.hexcasting.api.pigment.FrozenPigment; import at.petrak.hexcasting.common.lib.hex.HexEvalSounds; -import at.petrak.hexcasting.common.msgs.MsgNewSpiralPatternsS2C; import at.petrak.hexcasting.xplat.IXplatAbstractions; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.InteractionHand; -import java.util.List; -public class PackagedItemCastEnv extends PlayerBasedCastEnv { +public class PackagedItemCastEnv extends PlayerBasedSpiralPatternCastEnv { protected EvalSound sound = HexEvalSounds.NOTHING; @@ -24,18 +21,15 @@ public PackagedItemCastEnv(ServerPlayer caster, InteractionHand castingHand) { public void postExecution(CastResult result) { super.postExecution(result); - if (result.component1() instanceof PatternIota patternIota) { - var packet = new MsgNewSpiralPatternsS2C( - this.caster.getUUID(), List.of(patternIota.getPattern()), 140 - ); - IXplatAbstractions.INSTANCE.sendPacketToPlayer(this.caster, packet); - IXplatAbstractions.INSTANCE.sendPacketTracking(this.caster, packet); - } - // TODO: how do we know when to actually play this sound? this.sound = this.sound.greaterOf(result.getSound()); } + @Override + public int getSpiralPatternDuration() { + return 140; + } + @Override public long extractMediaEnvironment(long costLeft, boolean simulate) { if (this.caster.isCreative()) diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PlayerBasedCastEnv.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PlayerBasedCastEnv.java index 1f5b6703ff..405fe1ed20 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PlayerBasedCastEnv.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PlayerBasedCastEnv.java @@ -39,6 +39,10 @@ import static at.petrak.hexcasting.api.HexAPI.modLoc; import static at.petrak.hexcasting.api.utils.HexUtils.isOfTag; +/** + * Player-based casting environment. Consider using {@link PlayerBasedSpiralPatternCastEnv} instead + * if executed patterns should be displayed in a spiral around the caster. + */ public abstract class PlayerBasedCastEnv extends CastingEnvironment { public static final double DEFAULT_AMBIT_RADIUS = 32.0; private double ambitRadius; diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PlayerBasedSpiralPatternCastEnv.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PlayerBasedSpiralPatternCastEnv.java new file mode 100644 index 0000000000..05ff9eb9b4 --- /dev/null +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PlayerBasedSpiralPatternCastEnv.java @@ -0,0 +1,48 @@ +package at.petrak.hexcasting.api.casting.eval.env; + +import at.petrak.hexcasting.api.casting.eval.CastResult; +import at.petrak.hexcasting.api.casting.eval.vm.CastingImage; +import at.petrak.hexcasting.api.casting.iota.PatternIota; +import at.petrak.hexcasting.api.casting.math.HexPattern; +import at.petrak.hexcasting.common.msgs.MsgNewSpiralPatternsS2C; +import at.petrak.hexcasting.xplat.IXplatAbstractions; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.InteractionHand; + +import java.util.HashSet; +import java.util.Set; + +/** + * Variant of {@link PlayerBasedCastEnv} that tracks executed patterns and displays them in a spiral around the player + */ +public abstract class PlayerBasedSpiralPatternCastEnv extends PlayerBasedCastEnv { + private final Set castPatterns = new HashSet<>(); + + public PlayerBasedSpiralPatternCastEnv(ServerPlayer caster, InteractionHand castingHand) { + super(caster, castingHand); + } + + public abstract int getSpiralPatternDuration(); + + @Override + public void postExecution(CastResult result) { + super.postExecution(result); + + if (result.component1() instanceof PatternIota patternIota) { + castPatterns.add(patternIota.getPattern()); + } + } + + @Override + public void postCast(CastingImage image) { + super.postCast(image); + + var packet = new MsgNewSpiralPatternsS2C( + this.caster.getUUID(), castPatterns.stream().toList(), getSpiralPatternDuration() + ); + IXplatAbstractions.INSTANCE.sendPacketToPlayer(this.caster, packet); + IXplatAbstractions.INSTANCE.sendPacketTracking(this.caster, packet); + + castPatterns.clear(); + } +} diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/StaffCastEnv.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/StaffCastEnv.java index 29e80d3817..2b51203d91 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/StaffCastEnv.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/StaffCastEnv.java @@ -8,7 +8,6 @@ import at.petrak.hexcasting.api.casting.eval.vm.CastingImage; import at.petrak.hexcasting.api.casting.iota.PatternIota; import at.petrak.hexcasting.api.casting.math.HexCoord; -import at.petrak.hexcasting.api.casting.math.HexPattern; import at.petrak.hexcasting.api.mod.HexStatistics; import at.petrak.hexcasting.api.pigment.FrozenPigment; import at.petrak.hexcasting.common.msgs.*; @@ -21,15 +20,12 @@ import java.util.HashSet; import java.util.List; -import java.util.Set; -public class StaffCastEnv extends PlayerBasedCastEnv { +public class StaffCastEnv extends PlayerBasedSpiralPatternCastEnv { private final InteractionHand castingHand; - private final Set castPatterns = new HashSet<>(); private int soundsPlayed = 0; - public StaffCastEnv(ServerPlayer caster, InteractionHand castingHand) { super(caster, castingHand); @@ -40,10 +36,6 @@ public StaffCastEnv(ServerPlayer caster, InteractionHand castingHand) { public void postExecution(CastResult result) { super.postExecution(result); - if (result.component1() instanceof PatternIota patternIota) { - castPatterns.add(patternIota.getPattern()); - } - // we always want to play this sound one at a time var sound = result.getSound().sound(); if (soundsPlayed < 100 && sound != null) { // TODO: Make configurable @@ -58,16 +50,14 @@ public void postExecution(CastResult result) { public void postCast(CastingImage image) { super.postCast(image); - var packet = new MsgNewSpiralPatternsS2C( - this.caster.getUUID(), castPatterns.stream().toList(), Integer.MAX_VALUE - ); - IXplatAbstractions.INSTANCE.sendPacketToPlayer(this.caster, packet); - IXplatAbstractions.INSTANCE.sendPacketTracking(this.caster, packet); - - castPatterns.clear(); soundsPlayed = 0; } + @Override + public int getSpiralPatternDuration() { + return Integer.MAX_VALUE; + } + @Override public long extractMediaEnvironment(long cost, boolean simulate) { if (this.caster.isCreative()) From 5a54b86082dbaa4e84119a6ce0a7886d0eb3ba66 Mon Sep 17 00:00:00 2001 From: pipythonmc <47196755+pythonmcpi@users.noreply.github.com> Date: Sun, 12 Apr 2026 13:54:44 -0700 Subject: [PATCH 2/3] Remove duplicate pattern spiral packet --- .../hexcasting/common/items/magic/ItemPackagedHex.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/items/magic/ItemPackagedHex.java b/Common/src/main/java/at/petrak/hexcasting/common/items/magic/ItemPackagedHex.java index 1c8886f999..8ad3ea702f 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/items/magic/ItemPackagedHex.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/items/magic/ItemPackagedHex.java @@ -131,14 +131,6 @@ public InteractionResultHolder use(Level world, Player player, Intera var vm = CastingVM.empty(ctx); var clientView = vm.queueExecuteAndWrapIotas(instrs, sPlayer.serverLevel()); - var patterns = instrs.stream() - .filter(i -> i instanceof PatternIota) - .map(i -> ((PatternIota) i).getPattern()) - .toList(); - var packet = new MsgNewSpiralPatternsS2C(sPlayer.getUUID(), patterns, 140); - IXplatAbstractions.INSTANCE.sendPacketToPlayer(sPlayer, packet); - IXplatAbstractions.INSTANCE.sendPacketTracking(sPlayer, packet); - boolean broken = breakAfterDepletion() && getMedia(stack) == 0; Stat stat; From 90763b6ac9a0f39f4c1f8e9a9e577b83976be53e Mon Sep 17 00:00:00 2001 From: pipythonmc <47196755+pythonmcpi@users.noreply.github.com> Date: Sun, 12 Apr 2026 20:53:57 -0700 Subject: [PATCH 3/3] Add doc comment for PlayerBasedSpiralPatternCastEnv.getSpiralPatternDuration --- .../api/casting/eval/env/PlayerBasedSpiralPatternCastEnv.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PlayerBasedSpiralPatternCastEnv.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PlayerBasedSpiralPatternCastEnv.java index 05ff9eb9b4..7edb98557a 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PlayerBasedSpiralPatternCastEnv.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PlayerBasedSpiralPatternCastEnv.java @@ -22,6 +22,9 @@ public PlayerBasedSpiralPatternCastEnv(ServerPlayer caster, InteractionHand cast super(caster, castingHand); } + /** + * Returns the duration (in ticks) that patterns should remain visible after being executed by the env. + */ public abstract int getSpiralPatternDuration(); @Override