From 73c0af4b513ac303082c08a6739e971a4f5f6b93 Mon Sep 17 00:00:00 2001 From: Aly Date: Mon, 17 Aug 2026 13:49:33 -0600 Subject: [PATCH 1/7] basic implementation of more optimal pattern builder --- .../api/casting/eval/vm/CastingVM.kt | 2 +- .../hexcasting/api/casting/iota/Iota.java | 2 +- .../api/casting/iota/PatternIota.java | 10 +- .../api/casting/math/EulerPathFinder.kt | 9 +- .../hexcasting/api/casting/math/HexAngle.kt | 16 +- .../hexcasting/api/casting/math/HexDir.kt | 2 + .../api/casting/math/HexPattern.java | 121 +++++++++ .../hexcasting/api/casting/math/HexPattern.kt | 207 --------------- .../api/casting/math/HexSignature.java | 251 ++++++++++++++++++ .../hexcasting/client/gui/GuiSpellcasting.kt | 74 ++++-- .../client/render/HexPatternLike.java | 2 +- .../blocks/akashic/BlockAkashicRecord.java | 4 +- .../casting/PatternRegistryManifest.java | 11 +- .../common/casting/actions/escaping/OpUndo.kt | 6 +- .../actions/eval/SpecialHandlerForEach.kt | 2 +- .../math/SpecialHandlerNumberLiteral.kt | 2 +- .../actions/stack/SpecialHandlerMask.kt | 75 ++++-- .../command/ListPerWorldPatternsCommand.java | 2 +- .../interop/inline/HexPatternMatcher.java | 2 +- .../patchouli/ManualPatternComponent.java | 2 +- .../server/ScrungledPatternsSave.java | 2 +- 21 files changed, 524 insertions(+), 280 deletions(-) create mode 100644 Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexPattern.java delete mode 100644 Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexPattern.kt create mode 100644 Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexSignature.java diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/CastingVM.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/CastingVM.kt index 8d97888180..e8d472d6e9 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/CastingVM.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/CastingVM.kt @@ -178,7 +178,7 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) { OperatorSideEffect.DoMishap( MishapInternalException(exception), Mishap.Context( - (iota as? PatternIota)?.pattern ?: HexPattern(HexDir.WEST), + (iota as? PatternIota)?.pattern, null ) ) diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/Iota.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/Iota.java index 996e085dcd..0839d919e4 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/Iota.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/Iota.java @@ -54,7 +54,7 @@ protected Iota(@NotNull Supplier> type) { List.of( new OperatorSideEffect.DoMishap( new MishapUnescapedValue(this), - new Mishap.Context(new HexPattern(HexDir.WEST, List.of()), null) + new Mishap.Context(null, null) ) ), ResolvedPatternType.INVALID, diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/PatternIota.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/PatternIota.java index 874b839779..25267fc1d4 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/PatternIota.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/PatternIota.java @@ -57,7 +57,7 @@ public boolean isTruthy() { public boolean toleratesOther(Iota that) { return typesMatch(this, that) && that instanceof PatternIota piota - && this.getPattern().getAngles().equals(piota.getPattern().getAngles()); + && this.getPattern().getSignature().equals(piota.getPattern().getSignature()); } @Override @@ -224,12 +224,12 @@ public static Component display(HexPattern pat) { // keep around just in case it's needed. public static Component displayNonInline(HexPattern pat){ var bob = new StringBuilder(); - bob.append(pat.getStartDir()); + bob.append(pat.getOrientation()); - var sig = pat.anglesSignature(); - if (!sig.isEmpty()) { + var sig = pat.getSignature(); + if (sig.sizeUpperBound() > 0) { bob.append(" "); - bob.append(sig); + bob.append(sig.toAnglesString()); } return Component.translatable("hexcasting.tooltip.pattern_iota", Component.literal(bob.toString()).withStyle(ChatFormatting.WHITE)) diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/math/EulerPathFinder.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/math/EulerPathFinder.kt index d79ff002b8..d264a6a66c 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/math/EulerPathFinder.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/math/EulerPathFinder.kt @@ -63,16 +63,17 @@ object EulerPathFinder { out.add(current) val dirs = out.zipWithNext { a, b -> a.immediateDelta(b)!! } - val angles = dirs.zipWithNext { a, b -> b.angleFrom(a) } - return HexPattern(dirs[0], angles.toMutableList()) + val signatureBuilder = HexSignature.Builder(false) + dirs.zipWithNext().forEach { (a, b) -> signatureBuilder.addAngle(b.angleFrom(a)) } + return HexPattern(dirs[0], signatureBuilder.build()) } private fun toGraph(pat: HexPattern): HashMap> { val graph = HashMap>() - var compass: HexDir = pat.startDir + var compass: HexDir = pat.orientation var cursor = HexCoord.Origin - for (a in pat.angles) { + for (a in pat.signature) { // i hate kotlin graph.getOrPut(cursor) { EnumSet.noneOf(HexDir::class.java) }.add(compass) graph.getOrPut(cursor + compass) { EnumSet.noneOf(HexDir::class.java) }.add(compass * HexAngle.BACK) diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexAngle.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexAngle.kt index c5d98997c8..d0183acec0 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexAngle.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexAngle.kt @@ -3,10 +3,24 @@ package at.petrak.hexcasting.api.casting.math enum class HexAngle { FORWARD, RIGHT, RIGHT_BACK, BACK, LEFT_BACK, LEFT; - fun rotatedBy(a: HexAngle) = values()[(this.ordinal + a.ordinal) % values().size] + fun rotatedBy(a: HexAngle) = entries[(this.ordinal + a.ordinal) % entries.size] operator fun times(a: HexAngle) = this.rotatedBy(a) + fun inverse() = entries[(entries.size - this.ordinal) % entries.size] + + fun toChar(): Char { + return when (this) { + FORWARD -> 'w' + RIGHT -> 'e' + RIGHT_BACK -> 'd' + BACK -> 's' + LEFT_BACK -> 'a' + LEFT -> 'q' + } + } + companion object { + @JvmStatic fun fromChar(c: Char): HexAngle? { return when (c) { 'w' -> FORWARD diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexDir.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexDir.kt index b59df73cca..2497b42f80 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexDir.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexDir.kt @@ -30,10 +30,12 @@ enum class HexDir { } companion object { + @JvmField val CODEC: Codec = Codec.STRING.xmap( HexDir::fromString, HexDir::name ) + @JvmField val STREAM_CODEC: StreamCodec = ByteBufCodecs.STRING_UTF8.map( HexDir::fromString, HexDir::name diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexPattern.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexPattern.java new file mode 100644 index 0000000000..673afde23b --- /dev/null +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexPattern.java @@ -0,0 +1,121 @@ +package at.petrak.hexcasting.api.casting.math; + +import at.petrak.hexcasting.api.utils.HexUtils; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import io.netty.buffer.ByteBuf; +import it.unimi.dsi.fastutil.longs.LongOpenHashSet; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.PrimitiveIterator; +import java.util.stream.IntStream; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.world.phys.Vec2; + +/** + * Sequence of angles to define a pattern traced. + */ +public final class HexPattern { + private final HexDir orientation; + private final HexSignature signature; + + public HexPattern(HexDir orientation, HexSignature signature) { + this.orientation = orientation; + this.signature = signature; + } + + public HexDir getOrientation() { + return orientation; + } + + public HexSignature getSignature() { + return signature; + } + + public Vec2 getCenter(float hexRadius) { + return this.getCenter(hexRadius, HexCoord.getOrigin()); + } + + public Vec2 getCenter(float hexRadius, HexCoord origin) { + Vec2 originPx = HexUtils.coordToPx(origin, hexRadius, Vec2.ZERO); + List points = this.toLines(hexRadius, originPx); + return HexUtils.findCenter(points); + } + + /** + * Convert a hex pattern into a sequence of straight linePoints spanning its points. + */ + public List toLines(float hexSize, Vec2 origin) { + return this.positions().stream().map(it -> HexUtils.coordToPx(it, hexSize, origin)).toList(); + } + + public List positions() { + return this.positions(HexCoord.getOrigin()); + } + + public List positions(HexCoord start) { + ArrayList out = new ArrayList<>(this.signature.sizeUpperBound() + 2); + out.add(start); + HexDir compass = this.orientation; + HexCoord cursor = start; + for (HexAngle a : this.signature) { + cursor = cursor.plus(compass); + out.add(cursor); + compass = compass.times(a); + } + out.add(cursor.plus(compass)); + return out; + } + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) return false; + HexPattern that = (HexPattern) o; + return Objects.equals(signature, that.signature) && orientation == that.orientation; + } + + @Override + public int hashCode() { + return Objects.hash(signature, orientation); + } + + @Override + public String toString() { + return "HexPattern[" + + "orientation=" + orientation + + ", signature=" + signature + + ']'; + } + + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( + HexDir.CODEC.fieldOf("orientation").forGetter(HexPattern::getOrientation), + HexSignature.CODEC.fieldOf("signature").forGetter(HexPattern::getSignature) + ).apply(instance, HexPattern::new)); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + HexDir.STREAM_CODEC, HexPattern::getOrientation, + HexSignature.STREAM_CODEC, HexPattern::getSignature, + HexPattern::new + ); + + public static HexPattern fromAngles(String angleString, HexDir startDir) { + return fromAngles(angleString, startDir, true); + } + + public static HexPattern fromAngles(String angleString, HexDir startDir, boolean rejectOverlap) { + HexSignature.Builder signature = new HexSignature.Builder(rejectOverlap); + + for (int i = 0; i < angleString.length(); i++) { + char c = angleString.charAt(i); + + HexAngle angle = HexAngle.fromChar(c); + if(angle == null) throw new IllegalArgumentException("Cannot match %c at idx %d to a direction".formatted(c, i)); + + signature.addAngle(angle); + } + + return new HexPattern(startDir, signature.build()); + } +} diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexPattern.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexPattern.kt deleted file mode 100644 index 9f99262c88..0000000000 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexPattern.kt +++ /dev/null @@ -1,207 +0,0 @@ -package at.petrak.hexcasting.api.casting.math - -import at.petrak.hexcasting.api.utils.coordToPx -import at.petrak.hexcasting.api.utils.findCenter -import com.mojang.serialization.Codec -import com.mojang.serialization.DataResult -import com.mojang.serialization.codecs.RecordCodecBuilder -import net.minecraft.network.RegistryFriendlyByteBuf -import net.minecraft.network.codec.ByteBufCodecs -import net.minecraft.network.codec.StreamCodec -import net.minecraft.world.phys.Vec2 - -/** - * Sequence of angles to define a pattern traced. - */ -data class HexPattern(val startDir: HexDir, val angles: MutableList = arrayListOf()) { - /** - * @return True if it successfully appended, false if not. - */ - fun tryAppendDir(newDir: HexDir): Boolean { - // Two restrictions: - // - No adding a pos/dir pair we previously added - // - No backtracking - val linesSeen = mutableSetOf>() - - var compass = this.startDir - var cursor = HexCoord.Origin - for (a in this.angles) { - linesSeen.add(cursor to compass) - // Line from here to there also blocks there to here - linesSeen.add(cursor + compass to compass.rotatedBy(HexAngle.BACK)) - cursor += compass - compass *= a - } - cursor += compass - - val potentialNewLine = cursor to newDir - if (potentialNewLine in linesSeen) return false - val nextAngle = newDir - compass - if (nextAngle == HexAngle.BACK) return false - - this.angles.add(nextAngle) - return true - } - - @JvmOverloads - fun positions(start: HexCoord = HexCoord.Origin): List { - val out: ArrayList = ArrayList(this.angles.size + 2) - out.add(start) - var compass: HexDir = this.startDir - var cursor = start - for (a in this.angles) { - cursor += compass - out.add(cursor) - compass *= a - } - out.add(cursor + compass) - return out - } - - fun directions(): List { - val out = ArrayList(this.angles.size + 1) - out.add(this.startDir) - - var compass: HexDir = this.startDir - for (a in this.angles) { - compass *= a - out.add(compass) - } - return out - } - - fun finalDir(): HexDir = - this.angles.fold(this.startDir) { acc, angle -> acc * angle } - - // Terrible shorthand method for easy matching - fun anglesSignature(): String { - return buildString { - for (a in this@HexPattern.angles) { - append( - when (a) { - HexAngle.FORWARD -> "w" - HexAngle.RIGHT -> "e" - HexAngle.RIGHT_BACK -> "d" - HexAngle.BACK -> "s" - HexAngle.LEFT_BACK -> "a" - HexAngle.LEFT -> "q" - } - ) - } - } - } - - /** - * Return the "center of mass" of the pattern. - * Drawing the pattern with the returned vector as the origin will center the pattern around it. - */ - @JvmOverloads - fun getCenter(hexRadius: Float, origin: HexCoord = HexCoord.Origin): Vec2 { - val originPx = coordToPx(origin, hexRadius, Vec2.ZERO) - val points = this.toLines(hexRadius, originPx) - return findCenter(points) - } - - - /** - * Convert a hex pattern into a sequence of straight linePoints spanning its points. - */ - fun toLines(hexSize: Float, origin: Vec2): List = - this.positions().map { coordToPx(it, hexSize, origin) } - - fun sigsEqual(that: HexPattern) = this.angles == that.angles - - override fun toString(): String = buildString { - append("HexPattern[") - append(this@HexPattern.startDir) - append(", ") - append(this@HexPattern.anglesSignature()) - append("]") - } - - data class RawHexPattern(val anglesSignature: String, val startDir: String) - - companion object { - const val TAG_START_DIR = "start_dir" - const val TAG_ANGLES = "angles" - - @JvmField - val CODEC: Codec = RecordCodecBuilder.create { instance -> - instance.group( - Codec.STRING.fieldOf(TAG_ANGLES).forGetter(RawHexPattern::anglesSignature), - Codec.STRING.fieldOf(TAG_START_DIR).forGetter(RawHexPattern::startDir) - ).apply(instance, ::RawHexPattern) - }.flatXmap({ - val dir = HexDir.fromString(it.startDir) - try { - return@flatXmap DataResult.success(fromAnglesUnchecked(it.anglesSignature, dir)) - } catch (exception: IllegalArgumentException) { - return@flatXmap DataResult.error { exception.message } - } - }, { DataResult.success(RawHexPattern(it.anglesSignature(), it.startDir.name)) }) - - @JvmField - val STREAM_CODEC: StreamCodec = StreamCodec.composite( - ByteBufCodecs.STRING_UTF8, HexPattern::anglesSignature, - HexDir.STREAM_CODEC, HexPattern::startDir, - HexPattern::fromAnglesUnchecked - ) - - /** - * Construct a [HexPattern] from an angle signature and starting direction. - * - * Throws if the signature contains an invalid character, or if the resulting pattern would contain overlaps. - */ - @JvmStatic - @Throws(IllegalArgumentException::class, IllegalStateException::class) - fun fromAngles(signature: String, startDir: HexDir): HexPattern { - val out = HexPattern(startDir) - - var cursor = HexCoord.Origin - var compass = startDir - val linesSeen = mutableSetOf( - cursor to compass, - cursor + compass to compass.rotatedBy(HexAngle.BACK), - ) - - for ((idx, c) in signature.withIndex()) { - val angle = HexAngle.fromChar(c) - ?: throw IllegalArgumentException("Cannot match $c at idx $idx to a direction") - - cursor += compass - compass *= angle - - if ( - !linesSeen.add(cursor to compass) - // Line from here to there also blocks there to here - || !linesSeen.add(cursor + compass to compass.rotatedBy(HexAngle.BACK)) - ) { - throw IllegalStateException("Adding the angle $c at index $idx made the pattern invalid by looping back on itself") - } - - out.angles.add(angle) - } - - return out - } - - /** - * Construct a [HexPattern] from an angle signature and starting direction, without checking for overlaps. - * - * Throws if the signature contains an invalid character. - */ - @JvmStatic - @Throws(IllegalArgumentException::class) - fun fromAnglesUnchecked(signature: String, startDir: HexDir): HexPattern { - val out = HexPattern(startDir) - - for ((idx, c) in signature.withIndex()) { - val angle = HexAngle.fromChar(c) - ?: throw IllegalArgumentException("Cannot match $c at idx $idx to a direction") - out.angles.add(angle) - } - - return out - } - } -} diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexSignature.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexSignature.java new file mode 100644 index 0000000000..53094c162d --- /dev/null +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexSignature.java @@ -0,0 +1,251 @@ +package at.petrak.hexcasting.api.casting.math; + +import at.petrak.hexcasting.api.casting.castables.Action; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import io.netty.buffer.ByteBuf; +import it.unimi.dsi.fastutil.ints.IntArrayList; +import it.unimi.dsi.fastutil.longs.LongOpenHashSet; +import java.util.Arrays; +import java.util.Iterator; +import java.util.Objects; +import java.util.stream.IntStream; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.VarInt; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; + +public final class HexSignature implements Iterable { + public static final int BITS_PER_TURN = 3; + public static final int TURNS_PER_ARRAY_ELEMENT = Integer.SIZE / BITS_PER_TURN; + + private final int[] packedTurns; + private final int memoizedHash; + + private HexSignature(int[] packedTurns) { + this.packedTurns = packedTurns; + this.memoizedHash = Arrays.hashCode(packedTurns); + } + + private static final HexAngle[] BITS_TO_ANGLE = { + null, HexAngle.getEntries().get(0), HexAngle.getEntries().get(1), HexAngle.getEntries().get(2), + HexAngle.getEntries().get(3), HexAngle.getEntries().get(4), HexAngle.getEntries().get(5), + }; + + @Override + public @NotNull Iterator iterator() { + return new Iterator<>() { + private int arrayIndex = 0; + private int turnIndex = 0; + + @Override + public boolean hasNext() { + return arrayIndex < packedTurns.length && (packedTurns[arrayIndex] & (0b111 << (turnIndex * BITS_PER_TURN))) != 0; + } + + @Override + public HexAngle next() { + int bits = (packedTurns[arrayIndex] >> (turnIndex * BITS_PER_TURN)) & 0b111; + turnIndex = (turnIndex + 1) % TURNS_PER_ARRAY_ELEMENT; + if(turnIndex == 0) arrayIndex++; + return BITS_TO_ANGLE[bits]; + } + }; + } + + public String toAnglesString() { + StringBuilder builder = new StringBuilder(this.packedTurns.length * TURNS_PER_ARRAY_ELEMENT); + this.iterator().forEachRemaining(a -> builder.append(a.toChar())); + return builder.toString(); + } + + public int sizeUpperBound() { + return this.packedTurns.length * TURNS_PER_ARRAY_ELEMENT; + } + + @Override + public boolean equals(Object obj) { + return (obj instanceof HexSignature sig) && Arrays.equals(this.packedTurns, sig.packedTurns); + } + + @Override + public int hashCode() { + return this.memoizedHash; + } + + @Override + public String toString() { + return "HexSignature[" + this.toAnglesString() + ']'; + } + + public static final Codec CODEC = Codec.INT_STREAM + .xmap(IntStream::toArray, Arrays::stream) + .xmap(HexSignature::new, hs -> hs.packedTurns); + + public static final StreamCodec STREAM_CODEC = new StreamCodec<>() { + @Override + public HexSignature decode(ByteBuf buf) { + int length = VarInt.read(buf); + int[] packedTurns = new int[length]; + int byteLength = length * Integer.BYTES; + + // zero-copy reinterpret as ints + buf.nioBuffer(buf.readerIndex(), byteLength) + .asIntBuffer() + .get(packedTurns); + + buf.skipBytes(byteLength); + + return new HexSignature(packedTurns); + } + + @Override + public void encode(ByteBuf buf, HexSignature value) { + VarInt.write(buf, value.packedTurns.length); + + int byteLength = value.packedTurns.length * Integer.BYTES; + buf.ensureWritable(byteLength); + + // zero-copy reinterpret as ints + buf.nioBuffer(buf.writerIndex(), byteLength) + .asIntBuffer() + .put(value.packedTurns); + + buf.writerIndex(buf.writerIndex() + byteLength); + } + }; + + public static final class Builder { + private final IntArrayList turnsBuilder; + private int currentInt; + private int currentTurnIndex; + private boolean checked; + private HexCoord cursor; + private HexDir compass; + private final LongOpenHashSet edges; + + public Builder() { + this(true); + } + + public Builder(boolean checked) { + this.turnsBuilder = new IntArrayList(); + this.currentInt = 0; + this.currentTurnIndex = 0; + this.checked = checked; + this.cursor = HexCoord.getOrigin(); + // orientation doesn't actually matter for edge checking + this.compass = HexDir.EAST; + this.edges = new LongOpenHashSet(); + + if(this.checked) { + this.edges.add(edgeRepresentation(cursor, cursor.plus(compass))); + } + } + + public void reset() { + this.reset(true); + } + + public void reset(boolean checked) { + this.turnsBuilder.clear(); + this.currentInt = 0; + this.currentTurnIndex = 0; + this.checked = checked; + this.cursor = HexCoord.getOrigin(); + this.compass = HexDir.EAST; + this.edges.clear(); + + if(this.checked) { + this.edges.add(edgeRepresentation(this.cursor, this.cursor.plus(this.compass))); + } + } + + public int size() { + return (10 * this.turnsBuilder.size()) + this.currentTurnIndex; + } + + private static long edgeRepresentation(HexCoord from, HexCoord to) { + short fromQ = (short) from.getQ(); + short fromR = (short) from.getR(); + short toQ = (short) to.getQ(); + short toR = (short) to.getR(); + + int fromI = (fromQ << Short.SIZE) | (fromR & Short.MAX_VALUE); + int toI = (toQ << Short.SIZE) | (toR & Short.MAX_VALUE); + + if(toI < fromI) { + int tmp = fromI; + fromI = toI; + toI = tmp; + } + + return ((long) fromI << Integer.SIZE) | ((long) toI & (long) Integer.MAX_VALUE); + } + + public Builder addAngle(HexAngle angle) { + if(this.checked) { + HexCoord newCursor = this.cursor.plus(compass); + HexDir newCompass = this.compass.times(angle); + + if (!this.edges.add(edgeRepresentation(newCursor, newCursor.plus(newCompass)))) { + int idx = this.size() - 1; + throw new IllegalStateException("Adding the angle %s at index %d made the pattern invalid by looping back on itself".formatted(angle, idx)); + } + + this.cursor = newCursor; + this.compass = newCompass; + } + + int turnBits = 1 + angle.ordinal(); + int maskIn = turnBits << (BITS_PER_TURN * this.currentTurnIndex); + this.currentInt |= maskIn; + + this.currentTurnIndex = (this.currentTurnIndex + 1) % TURNS_PER_ARRAY_ELEMENT; + // TODO doc this + if(this.currentTurnIndex == 0) { + this.turnsBuilder.add(this.currentInt); + this.currentInt = 0; + } + + return this; + } + + public Builder undoAngle() { + if(this.currentTurnIndex == 0) { + this.currentInt = this.turnsBuilder.removeLast(); + this.currentTurnIndex = TURNS_PER_ARRAY_ELEMENT - 1; + } else { + this.currentTurnIndex = this.currentTurnIndex - 1; + } + + int shift = this.currentTurnIndex * BITS_PER_TURN; + int rawTurnBits = (this.currentInt >>> shift) & 0b111; + + HexAngle angle = BITS_TO_ANGLE[rawTurnBits]; + Objects.requireNonNull(angle); + + this.currentInt &= ~(0b111 << shift); + + if(this.checked) { + this.edges.remove(edgeRepresentation(this.cursor, this.cursor.plus(this.compass))); + + HexAngle inverseAngle = angle.inverse(); + this.compass = this.compass.times(inverseAngle); + + this.cursor = this.cursor.plus(this.compass.times(HexAngle.BACK)); + } + + return this; + } + + public HexSignature build() { + if(this.currentInt != 0) this.turnsBuilder.add(this.currentInt); + + return new HexSignature(this.turnsBuilder.toIntArray()); + } + } +} diff --git a/Common/src/main/java/at/petrak/hexcasting/client/gui/GuiSpellcasting.kt b/Common/src/main/java/at/petrak/hexcasting/client/gui/GuiSpellcasting.kt index bf29700dbe..471661c53b 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/gui/GuiSpellcasting.kt +++ b/Common/src/main/java/at/petrak/hexcasting/client/gui/GuiSpellcasting.kt @@ -8,6 +8,7 @@ import at.petrak.hexcasting.api.casting.math.HexAngle import at.petrak.hexcasting.api.casting.math.HexCoord import at.petrak.hexcasting.api.casting.math.HexDir import at.petrak.hexcasting.api.casting.math.HexPattern +import at.petrak.hexcasting.api.casting.math.HexSignature import at.petrak.hexcasting.api.mod.HexConfig import at.petrak.hexcasting.api.mod.HexTags import at.petrak.hexcasting.api.utils.asTranslatedComponent @@ -92,9 +93,9 @@ class GuiSpellcasting constructor( // - unescaped Introspection and Meditation can be undone if there's nothing else left to undo // - Interjection can always be undone (undoing its inserted iota) despite using the EVALUATED coloring ResolvedPatternType.EVALUATED -> { - resolvedPat.pattern.angles == HexActions.OPEN_PAREN.value().prototype.angles || - resolvedPat.pattern.angles == HexActions.OPEN_N_PARENS.value().prototype.angles || - resolvedPat.pattern.angles == HexActions.READ_INTO_PARENS.value().prototype.angles + resolvedPat.pattern.signature == HexActions.OPEN_PAREN.value().prototype.signature || + resolvedPat.pattern.signature == HexActions.OPEN_N_PARENS.value().prototype.signature || + resolvedPat.pattern.signature == HexActions.READ_INTO_PARENS.value().prototype.signature } else -> false } @@ -223,29 +224,22 @@ class GuiSpellcasting constructor( var playSound = false if (!this.usedSpots.contains(idealNextLoc)) { if (this.drawState is PatternDrawState.JustStarted) { - val pat = HexPattern(newdir) - - this.drawState = PatternDrawState.Drawing(anchorCoord, idealNextLoc, pat) + this.drawState = (this.drawState as PatternDrawState.JustStarted).startDrawing(anchorCoord, newdir, idealNextLoc) playSound = true } else if (this.drawState is PatternDrawState.Drawing) { // how anyone gets around without a borrowck is beyond me val ds = (this.drawState as PatternDrawState.Drawing) - val lastDir = ds.wipPattern.finalDir() + val lastDir = ds.recentDirection() if (newdir == lastDir.rotatedBy(HexAngle.BACK)) { // We're diametrically opposite! Do a backtrack - if (ds.wipPattern.angles.isEmpty()) { + if (ds.wipPattern.size() == 0) { this.drawState = PatternDrawState.JustStarted(ds.current + newdir) } else { - ds.current += newdir - ds.wipPattern.angles.removeLast() + ds.undo() } playSound = true } else { - val success = ds.wipPattern.tryAppendDir(newdir) - if (success) { - ds.current = idealNextLoc - } - playSound = success + ds.go(newdir) } } } @@ -288,7 +282,8 @@ class GuiSpellcasting constructor( } is PatternDrawState.Drawing -> { - val (start, _, pat) = this.drawState as PatternDrawState.Drawing + val (start, _, orientation, sig) = this.drawState as PatternDrawState.Drawing + val pat = HexPattern(orientation, sig.build()) this.drawState = PatternDrawState.BetweenPatterns this.patterns.add(ResolvedPattern(pat, start, ResolvedPatternType.UNRESOLVED)) @@ -432,9 +427,9 @@ class GuiSpellcasting constructor( points.add(this.coordToPx(ds.start)) } else if (this.drawState is PatternDrawState.Drawing) { val ds = this.drawState as PatternDrawState.Drawing - dupIndices = findDupIndices(ds.wipPattern.positions()) - for (pos in ds.wipPattern.positions()) { - val pix = this.coordToPx(pos + ds.start) + dupIndices = findDupIndices(ds.positions) + for (pos in ds.positions) { + val pix = this.coordToPx(pos) points.add(pix) } } @@ -545,10 +540,47 @@ class GuiSpellcasting constructor( object BetweenPatterns : PatternDrawState() /** We just started drawing and haven't drawn the first line yet. */ - data class JustStarted(val start: HexCoord) : PatternDrawState() + data class JustStarted(val start: HexCoord) : PatternDrawState() { + fun startDrawing(anchorCoord: HexCoord, newDir: HexDir, idealNextLoc: HexCoord): Drawing = + Drawing( + anchorCoord, + idealNextLoc, + newDir, + HexSignature.Builder(), + mutableListOf(anchorCoord, idealNextLoc) + ) + } /** We've started drawing a pattern for real. */ - data class Drawing(val start: HexCoord, var current: HexCoord, val wipPattern: HexPattern) : PatternDrawState() + data class Drawing( + val start: HexCoord, + var current: HexCoord, + val orientation: HexDir, + val wipPattern: HexSignature.Builder, + val positions: MutableList + ) : PatternDrawState() { + fun go(direction: HexDir): Boolean { + val angle = direction.angleFrom(this.recentDirection()) + try { + wipPattern.addAngle(angle) + current = current.plus(direction) + positions.add(current) + return true + } catch (ise: IllegalStateException) { + return false + } + } + + fun recentDirection(): HexDir { + return positions[positions.size - 2].immediateDelta(positions[positions.size - 1])!! + } + + fun undo() { + positions.removeLast() + current = positions.last() + wipPattern.undoAngle() + } + } } companion object { diff --git a/Common/src/main/java/at/petrak/hexcasting/client/render/HexPatternLike.java b/Common/src/main/java/at/petrak/hexcasting/client/render/HexPatternLike.java index 1b82992398..0675c2af2f 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/render/HexPatternLike.java +++ b/Common/src/main/java/at/petrak/hexcasting/client/render/HexPatternLike.java @@ -34,7 +34,7 @@ public List getNonZappyPoints(){ } public String getName(){ - return pat.getStartDir() + "-" + pat.anglesSignature(); + return pat.getOrientation() + "-" + pat.getSignature().toAnglesString(); } public Set getDups(){ diff --git a/Common/src/main/java/at/petrak/hexcasting/common/blocks/akashic/BlockAkashicRecord.java b/Common/src/main/java/at/petrak/hexcasting/common/blocks/akashic/BlockAkashicRecord.java index 5fecbdc4a0..7d00f44eea 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/blocks/akashic/BlockAkashicRecord.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/blocks/akashic/BlockAkashicRecord.java @@ -24,7 +24,7 @@ BlockPos addNewDatum(BlockPos herePos, Level level, HexPattern key, Iota datum) var clobbereePos = AkashicFloodfiller.floodFillFor(herePos, level, (pos, bs, world) -> world.getBlockEntity(pos) instanceof BlockEntityAkashicBookshelf tile - && tile.getPattern() != null && tile.getPattern().sigsEqual(key)); + && tile.getPattern() != null && tile.getPattern().getSignature().equals(key.getSignature())); if (clobbereePos != null) { return null; @@ -48,7 +48,7 @@ BlockPos addNewDatum(BlockPos herePos, Level level, HexPattern key, Iota datum) var foundPos = AkashicFloodfiller.floodFillFor(herePos, slevel, (pos, bs, world) -> world.getBlockEntity(pos) instanceof BlockEntityAkashicBookshelf tile - && tile.getPattern() != null && tile.getPattern().sigsEqual(key)); + && tile.getPattern() != null && tile.getPattern().getSignature().equals(key.getSignature())); if (foundPos == null) { return null; } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/PatternRegistryManifest.java b/Common/src/main/java/at/petrak/hexcasting/common/casting/PatternRegistryManifest.java index e8ca9d1f37..0dda617d5e 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/PatternRegistryManifest.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/PatternRegistryManifest.java @@ -7,6 +7,7 @@ import at.petrak.hexcasting.api.casting.eval.CastingEnvironment; import at.petrak.hexcasting.api.casting.math.HexAngle; import at.petrak.hexcasting.api.casting.math.HexPattern; +import at.petrak.hexcasting.api.casting.math.HexSignature; import at.petrak.hexcasting.api.mod.HexTags; import at.petrak.hexcasting.api.utils.HexUtils; import at.petrak.hexcasting.server.ScrungledPatternsSave; @@ -23,7 +24,7 @@ // Now an internal-only class used to do final processing on the registered stuff public class PatternRegistryManifest { - private static final ConcurrentMap, ResourceKey> NORMAL_ACTION_LOOKUP = + private static final ConcurrentMap> NORMAL_ACTION_LOOKUP = new ConcurrentHashMap<>(); /** @@ -48,7 +49,7 @@ public static void processRegistry(@Nullable ServerLevel overworld) { continue; if (!HexUtils.isOfTag(registry, key, HexTags.Actions.PER_WORLD_PATTERN)) { - var old = NORMAL_ACTION_LOOKUP.put(entry.prototype().getAngles(), key); + var old = NORMAL_ACTION_LOOKUP.put(entry.prototype().getSignature(), key); if (old != null) { HexAPI.LOGGER.warn("Inserted %s which has same signature as %s, overriding it.".formatted(key, old)); } @@ -89,7 +90,7 @@ public static Pair>> match public static PatternShapeMatch matchPattern(HexPattern pat, CastingEnvironment environment) { // I am PURPOSELY checking normal actions before special handlers // This way we don't get a repeat of the phial number literal incident - var sig = pat.getAngles(); + var sig = pat.getSignature(); if (NORMAL_ACTION_LOOKUP.containsKey(sig)) { var key = NORMAL_ACTION_LOOKUP.get(sig); return new PatternShapeMatch.Normal(key); @@ -97,7 +98,7 @@ public static PatternShapeMatch matchPattern(HexPattern pat, CastingEnvironment // Look it up in the world? var perWorldPatterns = ScrungledPatternsSave.open(environment.getWorld().getServer().overworld()); - var entry = perWorldPatterns.lookup(pat.anglesSignature()); + var entry = perWorldPatterns.lookup(pat.getSignature().toAnglesString()); if (entry != null) { return new PatternShapeMatch.PerWorld(entry.key(), true); } @@ -119,6 +120,6 @@ public static HexPattern getCanonicalStrokesPerWorld(ResourceKey newParenCount-- - HexActions.CLOSE_PAREN.value().prototype.angles -> newParenCount++ + when (last.iota.pattern.signature) { + HexActions.OPEN_PAREN.value().prototype.signature -> newParenCount-- + HexActions.CLOSE_PAREN.value().prototype.signature -> newParenCount++ } } val image2 = image.withUsedOp().copy( diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/eval/SpecialHandlerForEach.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/eval/SpecialHandlerForEach.kt index 6be0ed233e..b42033d33f 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/eval/SpecialHandlerForEach.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/eval/SpecialHandlerForEach.kt @@ -56,7 +56,7 @@ class SpecialHandlerForEach(val n: Int) : SpecialHandler { class Factory : SpecialHandler.Factory { override fun tryMatch(pat: HexPattern, env: CastingEnvironment): SpecialHandlerForEach? { - val sig = pat.anglesSignature() + val sig = pat.signature.toAnglesString() if (!sig.startsWith("waaddw")) return null val tail = sig.substring(6) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/SpecialHandlerNumberLiteral.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/SpecialHandlerNumberLiteral.kt index 44d6c56edd..6b5c6a34f2 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/SpecialHandlerNumberLiteral.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/SpecialHandlerNumberLiteral.kt @@ -35,7 +35,7 @@ class SpecialHandlerNumberLiteral(val x: Double) : SpecialHandler { class Factory : SpecialHandler.Factory { override fun tryMatch(pat: HexPattern, env: CastingEnvironment): SpecialHandlerNumberLiteral? { - val sig = pat.anglesSignature() + val sig = pat.signature.toAnglesString() if (sig.startsWith("aqaa") || sig.startsWith("dedd")) { val negate = sig.startsWith("dedd"); var accumulator = 0.0; diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/stack/SpecialHandlerMask.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/stack/SpecialHandlerMask.kt index c10be9450e..af54a8a614 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/stack/SpecialHandlerMask.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/stack/SpecialHandlerMask.kt @@ -47,37 +47,66 @@ class SpecialHandlerMask(val mask: BooleanList) : SpecialHandler { class Factory : SpecialHandler.Factory { override fun tryMatch(pat: HexPattern, env: CastingEnvironment): SpecialHandlerMask? { - val directions = pat.directions() + val iterator = pat.signature.iterator() + // if there's a first angle we need it + val firstTurn = if (iterator.hasNext()) iterator.next() else null - var flatDir = pat.startDir - if (pat.angles.isNotEmpty() && pat.angles[0] == HexAngle.LEFT_BACK) { - flatDir = directions[0].rotatedBy(HexAngle.LEFT); + // if we start with `a`, that means the first segment is a spike + // this means if we extended backwards, the spike would start with `e` + // meaning the direction of flatness is the inverse of `e`, which is `q` + // + // if we don't start with `a`, we started with something flat + val flatDir = if (firstTurn == HexAngle.LEFT_BACK) { + pat.orientation.rotatedBy(HexAngle.LEFT) + } else { + pat.orientation } - // TODO: we could probably definitely do this with a long to make it faster val mask = BooleanArrayList() - var i = 0; - while (i < directions.size) { - // Angle with respect to the *start direction* - val angle = directions[i].angleFrom(flatDir); - if (angle == HexAngle.FORWARD) { + var direction = pat.orientation + + var currentAngleFromForward = direction.angleFrom(flatDir) + // 0 angles = 1 straight line, so we have to hold the angle between our current segment and next segment + var nextAngle = firstTurn + + while (true) { + if (currentAngleFromForward == HexAngle.FORWARD) { + // a line means keep this stack element mask.add(true) - i++ - continue; - } - if (i >= directions.size - 1) { - // then we're out of angles! - return null - } - val angle2 = directions[i + 1].angleFrom(flatDir); - if (angle == HexAngle.RIGHT && angle2 == HexAngle.LEFT) { + + // no more angles, we're done + if (nextAngle == null) break + + // since this was a flat segment, we just advance to the next segment + direction *= nextAngle + currentAngleFromForward = direction.angleFrom(flatDir) + nextAngle = if (iterator.hasNext()) iterator.next() else null + } else if (currentAngleFromForward == HexAngle.RIGHT) { + // if we are starting a spike, but there's nothing after the start, we don't match + if (nextAngle == null) return null + + // if we aren't finishing the spike with `a` (`q` relative to flatDir), we don't match + direction *= nextAngle + if (direction.angleFrom(flatDir) != HexAngle.LEFT) return null + + // a spike means drop this stack element mask.add(false) - // skip both segments of the dip - i += 2 - continue + + // chomp the end of the spike + nextAngle = if (iterator.hasNext()) iterator.next() else null + // if there's nothing after the spike, we're done + if (nextAngle == null) break + + // since we chomped the end of the spike, we just advance to the next segment + direction *= nextAngle + currentAngleFromForward = direction.angleFrom(flatDir) + nextAngle = if (iterator.hasNext()) iterator.next() else null + } else { + // only FORWARD and RIGHT can appear as transitions in the state machine + return null } - return null } + return SpecialHandlerMask(mask) } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/command/ListPerWorldPatternsCommand.java b/Common/src/main/java/at/petrak/hexcasting/common/command/ListPerWorldPatternsCommand.java index 716899a83d..aec6cdbdd1 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/command/ListPerWorldPatternsCommand.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/command/ListPerWorldPatternsCommand.java @@ -95,7 +95,7 @@ private static int giveAll(CommandSourceStack source, Collection t var found = save.lookupReverse(key); var signature = found.getFirst(); var startDir = found.getSecond().canonicalStartDir(); - var pat = HexPattern.fromAnglesUnchecked(signature, startDir); + var pat = HexPattern.fromAngles(signature, startDir, false); var stack = new ItemStack(HexItems.SCROLL_LARGE.get()); stack.set(HexDataComponents.ACTION.get(), key); diff --git a/Common/src/main/java/at/petrak/hexcasting/interop/inline/HexPatternMatcher.java b/Common/src/main/java/at/petrak/hexcasting/interop/inline/HexPatternMatcher.java index 114b75101a..1ef462feaa 100644 --- a/Common/src/main/java/at/petrak/hexcasting/interop/inline/HexPatternMatcher.java +++ b/Common/src/main/java/at/petrak/hexcasting/interop/inline/HexPatternMatcher.java @@ -53,7 +53,7 @@ public Tuple getMatchAndGroup(MatchResult regexMatch, Matc angleSigs = ""; } try{ - pat = HexPattern.fromAnglesUnchecked(angleSigs.toLowerCase(), dir); + pat = HexPattern.fromAngles(angleSigs.toLowerCase(), dir, false); InlinePatternData patData = new InlinePatternData(pat); Style patDataStyle = patData.getExtraStyle(); if(sizeModString != null && sizeModString.equals("+")) diff --git a/Common/src/main/java/at/petrak/hexcasting/interop/patchouli/ManualPatternComponent.java b/Common/src/main/java/at/petrak/hexcasting/interop/patchouli/ManualPatternComponent.java index c06c04238c..dd6431edd7 100644 --- a/Common/src/main/java/at/petrak/hexcasting/interop/patchouli/ManualPatternComponent.java +++ b/Common/src/main/java/at/petrak/hexcasting/interop/patchouli/ManualPatternComponent.java @@ -35,7 +35,7 @@ public List getPatterns(UnaryOperator lookup) { RawPattern raw = new Gson().fromJson(json, RawPattern.class); var dir = HexDir.fromString(raw.startdir); - var pat = HexPattern.fromAnglesUnchecked(raw.signature, dir); + var pat = HexPattern.fromAngles(raw.signature, dir, false); out.add(pat); } diff --git a/Common/src/main/java/at/petrak/hexcasting/server/ScrungledPatternsSave.java b/Common/src/main/java/at/petrak/hexcasting/server/ScrungledPatternsSave.java index 8a8ab9eb7b..b700dfbd61 100644 --- a/Common/src/main/java/at/petrak/hexcasting/server/ScrungledPatternsSave.java +++ b/Common/src/main/java/at/petrak/hexcasting/server/ScrungledPatternsSave.java @@ -107,7 +107,7 @@ public static ScrungledPatternsSave createFromScratch(long seed) { var entry = registry.get(key); if (HexUtils.isOfTag(registry, key, HexTags.Actions.PER_WORLD_PATTERN)) { var scrungledPat = EulerPathFinder.findAltDrawing(entry.prototype(), seed); - map.put(scrungledPat.anglesSignature(), new PerWorldEntry(key, scrungledPat.getStartDir())); + map.put(scrungledPat.getSignature().toAnglesString(), new PerWorldEntry(key, scrungledPat.getOrientation())); } } From 678f650c5ac54d5b9f50634cc8ba537df66dc558 Mon Sep 17 00:00:00 2001 From: Aly Date: Mon, 17 Aug 2026 13:52:15 -0600 Subject: [PATCH 2/7] fix inline rendering --- .../at/petrak/hexcasting/api/casting/math/HexPattern.java | 4 ++++ .../petrak/hexcasting/interop/inline/InlinePatternData.java | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexPattern.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexPattern.java index 673afde23b..340f6ca285 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexPattern.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexPattern.java @@ -89,6 +89,10 @@ public String toString() { ']'; } + public String toChatString() { + return "HexPattern[" + orientation + ", " + signature.toAnglesString() + ']'; + } + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( HexDir.CODEC.fieldOf("orientation").forGetter(HexPattern::getOrientation), HexSignature.CODEC.fieldOf("signature").forGetter(HexPattern::getSignature) diff --git a/Common/src/main/java/at/petrak/hexcasting/interop/inline/InlinePatternData.java b/Common/src/main/java/at/petrak/hexcasting/interop/inline/InlinePatternData.java index 6bd96b12f6..853f71fb4b 100644 --- a/Common/src/main/java/at/petrak/hexcasting/interop/inline/InlinePatternData.java +++ b/Common/src/main/java/at/petrak/hexcasting/interop/inline/InlinePatternData.java @@ -67,7 +67,7 @@ public static Component getPatternName(HexPattern pattern){ @Override public Component asText(boolean withExtra) { - return Component.literal(pattern.toString()).withStyle(asStyle(withExtra)); + return Component.literal(pattern.toChatString()).withStyle(asStyle(withExtra)); } public static class InlinePatternDataType implements InlineDataType { From 16efec01bbcc0561a53767703dc1bf65e7a0f9ba Mon Sep 17 00:00:00 2001 From: Aly Date: Mon, 17 Aug 2026 14:29:45 -0600 Subject: [PATCH 3/7] efficient prefix checking --- .../api/casting/math/HexSignature.java | 25 +++++++ .../hexcasting/client/gui/GuiSpellcasting.kt | 2 +- .../actions/eval/SpecialHandlerForEach.kt | 24 ++++--- .../math/SpecialHandlerNumberLiteral.kt | 68 +++++++++++-------- 4 files changed, 79 insertions(+), 40 deletions(-) diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexSignature.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexSignature.java index 53094c162d..5ecd07637d 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexSignature.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexSignature.java @@ -17,6 +17,7 @@ import net.minecraft.network.codec.StreamCodec; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public final class HexSignature implements Iterable { public static final int BITS_PER_TURN = 3; @@ -56,6 +57,20 @@ public HexAngle next() { }; } + /** + * @return null if this does not start with prefix, an Iterator with the remainder after the prefix otherwise + */ + public @Nullable Iterator stripPrefix(HexSignature prefix) { + Iterator strIt = this.iterator(); + Iterator prefixIt = prefix.iterator(); + + while(strIt.hasNext() && prefixIt.hasNext()) { + if(!strIt.next().equals(prefixIt.next())) return null; + } + if(!prefixIt.hasNext()) return strIt; + else return null; + } + public String toAnglesString() { StringBuilder builder = new StringBuilder(this.packedTurns.length * TURNS_PER_ARRAY_ELEMENT); this.iterator().forEachRemaining(a -> builder.append(a.toChar())); @@ -118,6 +133,16 @@ public void encode(ByteBuf buf, HexSignature value) { } }; + public static HexSignature fromAnglesStringUnchecked(String anglesString) { + Builder b = new Builder(false); + for(int i = 0; i < anglesString.length(); i++) { + char c = anglesString.charAt(i); + HexAngle a = HexAngle.fromChar(c); + b.addAngle(a); + } + return b.build(); + } + public static final class Builder { private final IntArrayList turnsBuilder; private int currentInt; diff --git a/Common/src/main/java/at/petrak/hexcasting/client/gui/GuiSpellcasting.kt b/Common/src/main/java/at/petrak/hexcasting/client/gui/GuiSpellcasting.kt index 471661c53b..30cd7676bb 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/gui/GuiSpellcasting.kt +++ b/Common/src/main/java/at/petrak/hexcasting/client/gui/GuiSpellcasting.kt @@ -239,7 +239,7 @@ class GuiSpellcasting constructor( } playSound = true } else { - ds.go(newdir) + playSound = ds.go(newdir) } } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/eval/SpecialHandlerForEach.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/eval/SpecialHandlerForEach.kt index b42033d33f..bb693b0b64 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/eval/SpecialHandlerForEach.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/eval/SpecialHandlerForEach.kt @@ -10,7 +10,9 @@ import at.petrak.hexcasting.api.casting.eval.vm.FrameForEach import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation import at.petrak.hexcasting.api.casting.getEvaluatable import at.petrak.hexcasting.api.casting.getList +import at.petrak.hexcasting.api.casting.math.HexAngle import at.petrak.hexcasting.api.casting.math.HexPattern +import at.petrak.hexcasting.api.casting.math.HexSignature import at.petrak.hexcasting.api.casting.mishaps.MishapNotEnoughArgs import at.petrak.hexcasting.api.utils.TreeList import at.petrak.hexcasting.api.utils.asTranslatedComponent @@ -54,22 +56,26 @@ class SpecialHandlerForEach(val n: Int) : SpecialHandler { } } + companion object { + @JvmField + val PREFIX: HexSignature = HexSignature.fromAnglesStringUnchecked("waaddw") + } + class Factory : SpecialHandler.Factory { override fun tryMatch(pat: HexPattern, env: CastingEnvironment): SpecialHandlerForEach? { - val sig = pat.signature.toAnglesString() - if (!sig.startsWith("waaddw")) return null - - val tail = sig.substring(6) - if (tail.length % 2 != 0) return null + val sig = pat.signature + val suffix = (sig.stripPrefix(PREFIX) ?: return null).asSequence() - for ((index, segment) in tail.chunked(2).withIndex()) { + var tailLength = 0 + for ((index, segment) in suffix.chunked(2).withIndex()) { when (index % 2) { - 0 -> if (segment != "da") return null - 1 -> if (segment != "ad") return null + 0 -> if (segment != listOf(HexAngle.RIGHT_BACK, HexAngle.LEFT_BACK)) return null + 1 -> if (segment != listOf(HexAngle.LEFT_BACK, HexAngle.RIGHT_BACK)) return null } + tailLength++ } - return SpecialHandlerForEach(tail.length / 2) + return SpecialHandlerForEach(tailLength) } } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/SpecialHandlerNumberLiteral.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/SpecialHandlerNumberLiteral.kt index 6b5c6a34f2..74135e208b 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/SpecialHandlerNumberLiteral.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/SpecialHandlerNumberLiteral.kt @@ -7,7 +7,9 @@ import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.castables.SpecialHandler import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.casting.math.HexAngle import at.petrak.hexcasting.api.casting.math.HexPattern +import at.petrak.hexcasting.api.casting.math.HexSignature import at.petrak.hexcasting.api.utils.asTranslatedComponent import at.petrak.hexcasting.api.utils.lightPurple import at.petrak.hexcasting.common.lib.hex.HexSpecialHandlers @@ -33,45 +35,51 @@ class SpecialHandlerNumberLiteral(val x: Double) : SpecialHandler { } } + companion object { + @JvmField + val POSITIVE_PREFIX = HexSignature.fromAnglesStringUnchecked("aqaa") + @JvmField + val NEGATIVE_PREFIX = HexSignature.fromAnglesStringUnchecked("dedd") + } + class Factory : SpecialHandler.Factory { override fun tryMatch(pat: HexPattern, env: CastingEnvironment): SpecialHandlerNumberLiteral? { - val sig = pat.signature.toAnglesString() - if (sig.startsWith("aqaa") || sig.startsWith("dedd")) { - val negate = sig.startsWith("dedd"); - var accumulator = 0.0; - for (ch in sig.substring(4)) { - when (ch) { - 'w' -> { - accumulator += 1; - } + val sig = pat.signature + val (suffix, negate) = sig.stripPrefix(POSITIVE_PREFIX)?.let { it to false } + ?: sig.stripPrefix(NEGATIVE_PREFIX)?.let { it to true } + ?: return null - 'q' -> { - accumulator += 5; - } + var accumulator = 0.0; + for (angle in suffix) { + when (angle) { + HexAngle.FORWARD -> { + accumulator += 1; + } - 'e' -> { - accumulator += 10; - } + HexAngle.LEFT -> { + accumulator += 5; + } - 'a' -> { - accumulator *= 2; - } + HexAngle.RIGHT -> { + accumulator += 10; + } - 'd' -> { - accumulator /= 2; - } - // ok funny man - 's' -> {} - else -> throw IllegalStateException() + HexAngle.LEFT_BACK -> { + accumulator *= 2; } + + HexAngle.RIGHT_BACK -> { + accumulator /= 2; + } + // ok funny man + HexAngle.BACK -> {} + else -> throw IllegalStateException() } - if (negate) { - accumulator = -accumulator; - } - return SpecialHandlerNumberLiteral(accumulator); - } else { - return null; } + if (negate) { + accumulator = -accumulator; + } + return SpecialHandlerNumberLiteral(accumulator); } } From d9ad2fd128952ebfe2097f01cd0b681d3d80808c Mon Sep 17 00:00:00 2001 From: Aly Date: Mon, 17 Aug 2026 14:30:57 -0600 Subject: [PATCH 4/7] don't duplicate map traversal work --- .../hexcasting/common/casting/PatternRegistryManifest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/PatternRegistryManifest.java b/Common/src/main/java/at/petrak/hexcasting/common/casting/PatternRegistryManifest.java index 0dda617d5e..5786fd82aa 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/PatternRegistryManifest.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/PatternRegistryManifest.java @@ -91,8 +91,8 @@ public static PatternShapeMatch matchPattern(HexPattern pat, CastingEnvironment // I am PURPOSELY checking normal actions before special handlers // This way we don't get a repeat of the phial number literal incident var sig = pat.getSignature(); - if (NORMAL_ACTION_LOOKUP.containsKey(sig)) { - var key = NORMAL_ACTION_LOOKUP.get(sig); + var key = NORMAL_ACTION_LOOKUP.get(sig); + if (key != null) { return new PatternShapeMatch.Normal(key); } From d0a698d7a42275659841226f3e5e747f91a0aaf4 Mon Sep 17 00:00:00 2001 From: Aly Date: Mon, 17 Aug 2026 14:36:05 -0600 Subject: [PATCH 5/7] per-world patterns use more efficient keys --- .../casting/PatternRegistryManifest.java | 4 ++-- .../command/ListPerWorldPatternsCommand.java | 2 +- .../server/ScrungledPatternsSave.java | 23 ++++++++++--------- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/PatternRegistryManifest.java b/Common/src/main/java/at/petrak/hexcasting/common/casting/PatternRegistryManifest.java index 5786fd82aa..3414af09ee 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/PatternRegistryManifest.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/PatternRegistryManifest.java @@ -98,7 +98,7 @@ public static PatternShapeMatch matchPattern(HexPattern pat, CastingEnvironment // Look it up in the world? var perWorldPatterns = ScrungledPatternsSave.open(environment.getWorld().getServer().overworld()); - var entry = perWorldPatterns.lookup(pat.getSignature().toAnglesString()); + var entry = perWorldPatterns.lookup(pat.getSignature()); if (entry != null) { return new PatternShapeMatch.PerWorld(entry.key(), true); } @@ -120,6 +120,6 @@ public static HexPattern getCanonicalStrokesPerWorld(ResourceKey t var found = save.lookupReverse(key); var signature = found.getFirst(); var startDir = found.getSecond().canonicalStartDir(); - var pat = HexPattern.fromAngles(signature, startDir, false); + var pat = new HexPattern(startDir, signature); var stack = new ItemStack(HexItems.SCROLL_LARGE.get()); stack.set(HexDataComponents.ACTION.get(), key); diff --git a/Common/src/main/java/at/petrak/hexcasting/server/ScrungledPatternsSave.java b/Common/src/main/java/at/petrak/hexcasting/server/ScrungledPatternsSave.java index b700dfbd61..e80e1806a8 100644 --- a/Common/src/main/java/at/petrak/hexcasting/server/ScrungledPatternsSave.java +++ b/Common/src/main/java/at/petrak/hexcasting/server/ScrungledPatternsSave.java @@ -3,6 +3,7 @@ import at.petrak.hexcasting.api.casting.ActionRegistryEntry; import at.petrak.hexcasting.api.casting.math.EulerPathFinder; import at.petrak.hexcasting.api.casting.math.HexDir; +import at.petrak.hexcasting.api.casting.math.HexSignature; import at.petrak.hexcasting.api.mod.HexTags; import at.petrak.hexcasting.api.utils.HexUtils; import at.petrak.hexcasting.xplat.IXplatAbstractions; @@ -32,16 +33,16 @@ public class ScrungledPatternsSave extends SavedData { /** * Maps scrungled signatures to their keys. */ - private final Map lookup; + private final Map lookup; /** * Reverse-maps resource keys to their signature; you can use that in {@code lookup}. *

* This way we can look up things if we know their resource key, for commands and such */ - private final Map, String> reverseLookup; + private final Map, HexSignature> reverseLookup; - private ScrungledPatternsSave(Map lookup) { + private ScrungledPatternsSave(Map lookup) { this.lookup = lookup; this.reverseLookup = new HashMap<>(); this.lookup.forEach((sig, entry) -> { @@ -50,12 +51,12 @@ private ScrungledPatternsSave(Map lookup) { } @Nullable - public PerWorldEntry lookup(String signature) { + public PerWorldEntry lookup(HexSignature signature) { return this.lookup.get(signature); } @Nullable - public Pair lookupReverse(ResourceKey key) { + public Pair lookupReverse(ResourceKey key) { var sig = this.reverseLookup.get(key); if (sig == null) return null; @@ -69,7 +70,7 @@ public CompoundTag save(CompoundTag tag, HolderLookup.Provider registries) { var inner = new CompoundTag(); inner.putByte(TAG_DIR, (byte) entry.canonicalStartDir.ordinal()); inner.putString(TAG_KEY, entry.key().location().toString()); - tag.put(sig, inner); + tag.put(sig.toAnglesString(), inner); }); return tag; } @@ -77,24 +78,24 @@ public CompoundTag save(CompoundTag tag, HolderLookup.Provider registries) { private static ScrungledPatternsSave load(CompoundTag tag, HolderLookup.Provider lookup) { var registryKey = IXplatAbstractions.INSTANCE.getActionRegistry().key(); - var map = new HashMap(); + var map = new HashMap(); for (var sig : tag.getAllKeys()) { var inner = tag.getCompound(sig); var rawDir = inner.getByte(TAG_DIR); var rawKey = inner.getString(TAG_KEY); - var dir = HexDir.values()[rawDir]; + var dir = HexDir.getEntries().get(rawDir); var key = ResourceKey.create(registryKey, ResourceLocation.parse(rawKey)); - map.put(sig, new PerWorldEntry(key, dir)); + map.put(HexSignature.fromAnglesStringUnchecked(sig), new PerWorldEntry(key, dir)); } return new ScrungledPatternsSave(map); } public static ScrungledPatternsSave createFromScratch(long seed) { - var map = new HashMap(); + var map = new HashMap(); var registry = IXplatAbstractions.INSTANCE.getActionRegistry(); @@ -107,7 +108,7 @@ public static ScrungledPatternsSave createFromScratch(long seed) { var entry = registry.get(key); if (HexUtils.isOfTag(registry, key, HexTags.Actions.PER_WORLD_PATTERN)) { var scrungledPat = EulerPathFinder.findAltDrawing(entry.prototype(), seed); - map.put(scrungledPat.getSignature().toAnglesString(), new PerWorldEntry(key, scrungledPat.getOrientation())); + map.put(scrungledPat.getSignature(), new PerWorldEntry(key, scrungledPat.getOrientation())); } } From 7c95aa390eddaa70c57dbe978f64f8258269d6d3 Mon Sep 17 00:00:00 2001 From: Aly Date: Mon, 17 Aug 2026 14:43:20 -0600 Subject: [PATCH 6/7] fix bitmasks --- .../at/petrak/hexcasting/api/casting/math/HexSignature.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexSignature.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexSignature.java index 5ecd07637d..c869fbd789 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexSignature.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexSignature.java @@ -199,8 +199,8 @@ private static long edgeRepresentation(HexCoord from, HexCoord to) { short toQ = (short) to.getQ(); short toR = (short) to.getR(); - int fromI = (fromQ << Short.SIZE) | (fromR & Short.MAX_VALUE); - int toI = (toQ << Short.SIZE) | (toR & Short.MAX_VALUE); + int fromI = (fromQ << Short.SIZE) | (fromR & 0xFFFF); + int toI = (toQ << Short.SIZE) | (toR & 0xFFFF); if(toI < fromI) { int tmp = fromI; @@ -208,7 +208,7 @@ private static long edgeRepresentation(HexCoord from, HexCoord to) { toI = tmp; } - return ((long) fromI << Integer.SIZE) | ((long) toI & (long) Integer.MAX_VALUE); + return ((long) fromI << Integer.SIZE) | ((long) toI & (long) 0xFFFF_FFFFL); } public Builder addAngle(HexAngle angle) { From de81d90c7152cc13278355da403c0e97d9b20f48 Mon Sep 17 00:00:00 2001 From: Aly Date: Mon, 17 Aug 2026 14:44:35 -0600 Subject: [PATCH 7/7] rename fromAngles to fromAngleString to be more consistent --- .../api/casting/arithmetic/Arithmetic.java | 76 ++-- .../api/casting/math/HexPattern.java | 10 +- .../hexcasting/common/lib/hex/HexActions.java | 375 +++++++++--------- .../loot/AddHexToAncientCypherFunc.java | 2 +- .../interop/inline/HexPatternMatcher.java | 2 +- .../patchouli/ManualPatternComponent.java | 2 +- 6 files changed, 228 insertions(+), 239 deletions(-) diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/Arithmetic.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/Arithmetic.java index 10f9f9cd6e..f52dad06ba 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/Arithmetic.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/Arithmetic.java @@ -24,49 +24,49 @@ public interface Arithmetic { // Below are some common Operator patterns that you can make use of in your Arithmetic: - HexPattern ADD = HexPattern.fromAngles("waaw", HexDir.NORTH_EAST); - HexPattern SUB = HexPattern.fromAngles("wddw", HexDir.NORTH_WEST); - HexPattern MUL = HexPattern.fromAngles("waqaw", HexDir.SOUTH_EAST); - HexPattern DIV = HexPattern.fromAngles("wdedw", HexDir.NORTH_EAST); - HexPattern ABS = HexPattern.fromAngles("wqaqw", HexDir.NORTH_EAST); - HexPattern POW = HexPattern.fromAngles("wedew", HexDir.NORTH_WEST); - HexPattern FLOOR = HexPattern.fromAngles("ewq", HexDir.EAST); - HexPattern CEIL = HexPattern.fromAngles("qwe", HexDir.EAST); - HexPattern SIN = HexPattern.fromAngles("qqqqqaa", HexDir.SOUTH_EAST); - HexPattern COS = HexPattern.fromAngles("qqqqqad", HexDir.SOUTH_EAST); - HexPattern TAN = HexPattern.fromAngles("wqqqqqadq", HexDir.SOUTH_WEST); - HexPattern ARCSIN = HexPattern.fromAngles("ddeeeee", HexDir.SOUTH_EAST); - HexPattern ARCCOS = HexPattern.fromAngles("adeeeee", HexDir.NORTH_EAST); - HexPattern ARCTAN = HexPattern.fromAngles("eadeeeeew", HexDir.NORTH_EAST); - HexPattern ARCTAN2 = HexPattern.fromAngles("deadeeeeewd", HexDir.WEST); - HexPattern LOG = HexPattern.fromAngles("eqaqe", HexDir.NORTH_WEST); - HexPattern MOD = HexPattern.fromAngles("addwaad", HexDir.NORTH_EAST); + HexPattern ADD = HexPattern.fromAngleString("waaw", HexDir.NORTH_EAST); + HexPattern SUB = HexPattern.fromAngleString("wddw", HexDir.NORTH_WEST); + HexPattern MUL = HexPattern.fromAngleString("waqaw", HexDir.SOUTH_EAST); + HexPattern DIV = HexPattern.fromAngleString("wdedw", HexDir.NORTH_EAST); + HexPattern ABS = HexPattern.fromAngleString("wqaqw", HexDir.NORTH_EAST); + HexPattern POW = HexPattern.fromAngleString("wedew", HexDir.NORTH_WEST); + HexPattern FLOOR = HexPattern.fromAngleString("ewq", HexDir.EAST); + HexPattern CEIL = HexPattern.fromAngleString("qwe", HexDir.EAST); + HexPattern SIN = HexPattern.fromAngleString("qqqqqaa", HexDir.SOUTH_EAST); + HexPattern COS = HexPattern.fromAngleString("qqqqqad", HexDir.SOUTH_EAST); + HexPattern TAN = HexPattern.fromAngleString("wqqqqqadq", HexDir.SOUTH_WEST); + HexPattern ARCSIN = HexPattern.fromAngleString("ddeeeee", HexDir.SOUTH_EAST); + HexPattern ARCCOS = HexPattern.fromAngleString("adeeeee", HexDir.NORTH_EAST); + HexPattern ARCTAN = HexPattern.fromAngleString("eadeeeeew", HexDir.NORTH_EAST); + HexPattern ARCTAN2 = HexPattern.fromAngleString("deadeeeeewd", HexDir.WEST); + HexPattern LOG = HexPattern.fromAngleString("eqaqe", HexDir.NORTH_WEST); + HexPattern MOD = HexPattern.fromAngleString("addwaad", HexDir.NORTH_EAST); // Vecs - HexPattern PACK = HexPattern.fromAngles("eqqqqq", HexDir.EAST); - HexPattern UNPACK = HexPattern.fromAngles("qeeeee", HexDir.EAST); + HexPattern PACK = HexPattern.fromAngleString("eqqqqq", HexDir.EAST); + HexPattern UNPACK = HexPattern.fromAngleString("qeeeee", HexDir.EAST); // Lists - HexPattern INDEX = HexPattern.fromAngles("deeed", HexDir.NORTH_WEST); - HexPattern SLICE = HexPattern.fromAngles("qaeaqwded", HexDir.NORTH_WEST); - HexPattern APPEND = HexPattern.fromAngles("edqde", HexDir.SOUTH_WEST); - HexPattern UNAPPEND = HexPattern.fromAngles("qaeaq", HexDir.NORTH_WEST); - HexPattern REV = HexPattern.fromAngles("qqqaede", HexDir.EAST); - HexPattern INDEX_OF = HexPattern.fromAngles("dedqde", HexDir.EAST); - HexPattern REMOVE = HexPattern.fromAngles("edqdewaqa", HexDir.SOUTH_WEST); - HexPattern REPLACE = HexPattern.fromAngles("wqaeaqw", HexDir.NORTH_WEST); - HexPattern CONS = HexPattern.fromAngles("ddewedd", HexDir.SOUTH_EAST); - HexPattern UNCONS = HexPattern.fromAngles("aaqwqaa", HexDir.SOUTH_WEST); + HexPattern INDEX = HexPattern.fromAngleString("deeed", HexDir.NORTH_WEST); + HexPattern SLICE = HexPattern.fromAngleString("qaeaqwded", HexDir.NORTH_WEST); + HexPattern APPEND = HexPattern.fromAngleString("edqde", HexDir.SOUTH_WEST); + HexPattern UNAPPEND = HexPattern.fromAngleString("qaeaq", HexDir.NORTH_WEST); + HexPattern REV = HexPattern.fromAngleString("qqqaede", HexDir.EAST); + HexPattern INDEX_OF = HexPattern.fromAngleString("dedqde", HexDir.EAST); + HexPattern REMOVE = HexPattern.fromAngleString("edqdewaqa", HexDir.SOUTH_WEST); + HexPattern REPLACE = HexPattern.fromAngleString("wqaeaqw", HexDir.NORTH_WEST); + HexPattern CONS = HexPattern.fromAngleString("ddewedd", HexDir.SOUTH_EAST); + HexPattern UNCONS = HexPattern.fromAngleString("aaqwqaa", HexDir.SOUTH_WEST); // Boolean Logic, Comparisons, & Sets - HexPattern AND = HexPattern.fromAngles("wdw", HexDir.NORTH_EAST); - HexPattern OR = HexPattern.fromAngles("waw", HexDir.SOUTH_EAST); - HexPattern XOR = HexPattern.fromAngles("dwa", HexDir.NORTH_WEST); - HexPattern GREATER = HexPattern.fromAngles("e", HexDir.SOUTH_EAST); - HexPattern LESS = HexPattern.fromAngles("q", HexDir.SOUTH_WEST); - HexPattern GREATER_EQ = HexPattern.fromAngles("ee", HexDir.SOUTH_EAST); - HexPattern LESS_EQ = HexPattern.fromAngles("qq", HexDir.SOUTH_WEST); - HexPattern NOT = HexPattern.fromAngles("dw", HexDir.NORTH_WEST); - HexPattern UNIQUE = HexPattern.fromAngles("aweaqa", HexDir.NORTH_EAST); + HexPattern AND = HexPattern.fromAngleString("wdw", HexDir.NORTH_EAST); + HexPattern OR = HexPattern.fromAngleString("waw", HexDir.SOUTH_EAST); + HexPattern XOR = HexPattern.fromAngleString("dwa", HexDir.NORTH_WEST); + HexPattern GREATER = HexPattern.fromAngleString("e", HexDir.SOUTH_EAST); + HexPattern LESS = HexPattern.fromAngleString("q", HexDir.SOUTH_WEST); + HexPattern GREATER_EQ = HexPattern.fromAngleString("ee", HexDir.SOUTH_EAST); + HexPattern LESS_EQ = HexPattern.fromAngleString("qq", HexDir.SOUTH_WEST); + HexPattern NOT = HexPattern.fromAngleString("dw", HexDir.NORTH_WEST); + HexPattern UNIQUE = HexPattern.fromAngleString("aweaqa", HexDir.NORTH_EAST); } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexPattern.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexPattern.java index 340f6ca285..7f60749419 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexPattern.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexPattern.java @@ -3,13 +3,9 @@ import at.petrak.hexcasting.api.utils.HexUtils; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import io.netty.buffer.ByteBuf; -import it.unimi.dsi.fastutil.longs.LongOpenHashSet; import java.util.ArrayList; import java.util.List; import java.util.Objects; -import java.util.PrimitiveIterator; -import java.util.stream.IntStream; import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.codec.StreamCodec; import net.minecraft.world.phys.Vec2; @@ -104,11 +100,11 @@ public String toChatString() { HexPattern::new ); - public static HexPattern fromAngles(String angleString, HexDir startDir) { - return fromAngles(angleString, startDir, true); + public static HexPattern fromAngleString(String angleString, HexDir startDir) { + return fromAngleString(angleString, startDir, true); } - public static HexPattern fromAngles(String angleString, HexDir startDir, boolean rejectOverlap) { + public static HexPattern fromAngleString(String angleString, HexDir startDir, boolean rejectOverlap) { HexSignature.Builder signature = new HexSignature.Builder(rejectOverlap); for (int i = 0; i < angleString.length(); i++) { diff --git a/Common/src/main/java/at/petrak/hexcasting/common/lib/hex/HexActions.java b/Common/src/main/java/at/petrak/hexcasting/common/lib/hex/HexActions.java index 07fc06b718..83342e8b52 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/lib/hex/HexActions.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/lib/hex/HexActions.java @@ -58,7 +58,6 @@ import at.petrak.hexcasting.xplat.IXplatRegister; import net.minecraft.core.Holder; import net.minecraft.core.Registry; -import net.minecraft.resources.ResourceLocation; import net.minecraft.world.effect.MobEffects; import net.minecraft.world.item.Items; import net.minecraft.world.level.block.Blocks; @@ -66,12 +65,6 @@ import net.minecraft.world.level.material.Fluids; import net.minecraft.world.phys.Vec3; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.function.BiConsumer; - -import static at.petrak.hexcasting.api.HexAPI.modLoc; - @SuppressWarnings("unused") public class HexActions { private static final IXplatRegister REGISTER = IXplatAbstractions.INSTANCE.createRegistar(HexRegistries.ACTION); @@ -87,535 +80,535 @@ public static void register() { // - CW is the special or destruction version public static final Holder GET_CASTER = REGISTER.registerHolder("get_caster", () -> - new ActionRegistryEntry(HexPattern.fromAngles("qaq", HexDir.NORTH_EAST), OpGetCaster.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("qaq", HexDir.NORTH_EAST), OpGetCaster.INSTANCE)); public static final Holder ENTITY_POS$EYE = REGISTER.registerHolder("entity_pos/eye", () -> - new ActionRegistryEntry(HexPattern.fromAngles("aa", HexDir.EAST), new OpEntityPos(false))); + new ActionRegistryEntry(HexPattern.fromAngleString("aa", HexDir.EAST), new OpEntityPos(false))); public static final Holder ENTITY_POS$FOOT = REGISTER.registerHolder("entity_pos/foot", () -> - new ActionRegistryEntry(HexPattern.fromAngles("dd", HexDir.NORTH_EAST), new OpEntityPos(true))); + new ActionRegistryEntry(HexPattern.fromAngleString("dd", HexDir.NORTH_EAST), new OpEntityPos(true))); public static final Holder ENTITY_LOOK = REGISTER.registerHolder("get_entity_look", () -> - new ActionRegistryEntry(HexPattern.fromAngles("wa", HexDir.EAST), OpEntityLook.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("wa", HexDir.EAST), OpEntityLook.INSTANCE)); public static final Holder ENTITY_HEIGHT = REGISTER.registerHolder("get_entity_height", () -> - new ActionRegistryEntry(HexPattern.fromAngles("awq", HexDir.NORTH_EAST), OpEntityHeight.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("awq", HexDir.NORTH_EAST), OpEntityHeight.INSTANCE)); public static final Holder ENTITY_VELOCITY = REGISTER.registerHolder("get_entity_velocity", () -> - new ActionRegistryEntry(HexPattern.fromAngles("wq", HexDir.EAST), OpEntityVelocity.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("wq", HexDir.EAST), OpEntityVelocity.INSTANCE)); // == Getters == public static final Holder RAYCAST = REGISTER.registerHolder("raycast", () -> - new ActionRegistryEntry(HexPattern.fromAngles("wqaawdd", HexDir.EAST), OpBlockRaycast.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("wqaawdd", HexDir.EAST), OpBlockRaycast.INSTANCE)); public static final Holder RAYCAST_AXIS = REGISTER.registerHolder("raycast/axis", () -> - new ActionRegistryEntry(HexPattern.fromAngles("weddwaa", HexDir.EAST), OpBlockAxisRaycast.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("weddwaa", HexDir.EAST), OpBlockAxisRaycast.INSTANCE)); public static final Holder RAYCAST_ENTITY = REGISTER.registerHolder("raycast/entity", () -> - new ActionRegistryEntry(HexPattern.fromAngles("weaqa", HexDir.EAST), OpEntityRaycast.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("weaqa", HexDir.EAST), OpEntityRaycast.INSTANCE)); public static final Holder GET_MEDIA = REGISTER.registerHolder("get_media", () -> - new ActionRegistryEntry(HexPattern.fromAngles("dde", HexDir.WEST), OpGetMedia.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("dde", HexDir.WEST), OpGetMedia.INSTANCE)); // == spell circle getters == public static final Holder CIRCLE$IMPETUS_POST = REGISTER.registerHolder("circle/impetus_pos", () -> - new ActionRegistryEntry(HexPattern.fromAngles("eaqwqae", HexDir.SOUTH_WEST), OpImpetusPos.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("eaqwqae", HexDir.SOUTH_WEST), OpImpetusPos.INSTANCE)); public static final Holder CIRCLE$IMPETUS_DIR = REGISTER.registerHolder("circle/impetus_dir", () -> - new ActionRegistryEntry(HexPattern.fromAngles("eaqwqaewede", HexDir.SOUTH_WEST), OpImpetusDir.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("eaqwqaewede", HexDir.SOUTH_WEST), OpImpetusDir.INSTANCE)); public static final Holder CIRCLE$BOUNDS$MIN = REGISTER.registerHolder("circle/bounds/min", () -> - new ActionRegistryEntry(HexPattern.fromAngles("eaqwqaewdd", HexDir.SOUTH_WEST), new OpCircleBounds(false))); + new ActionRegistryEntry(HexPattern.fromAngleString("eaqwqaewdd", HexDir.SOUTH_WEST), new OpCircleBounds(false))); public static final Holder CIRCLE$BOUNDS$MAX = REGISTER.registerHolder("circle/bounds/max", () -> - new ActionRegistryEntry(HexPattern.fromAngles("aqwqawaaqa", HexDir.WEST), new OpCircleBounds(true))); + new ActionRegistryEntry(HexPattern.fromAngleString("aqwqawaaqa", HexDir.WEST), new OpCircleBounds(true))); // == Modify Stack == public static final Holder SWAP = REGISTER.registerHolder("swap", () -> - new ActionRegistryEntry(HexPattern.fromAngles("aawdd", HexDir.EAST), new OpTwiddling(2, new int[]{1, 0}))); + new ActionRegistryEntry(HexPattern.fromAngleString("aawdd", HexDir.EAST), new OpTwiddling(2, new int[]{1, 0}))); public static final Holder ROTATE = REGISTER.registerHolder("rotate", () -> - new ActionRegistryEntry(HexPattern.fromAngles("aaeaa", HexDir.EAST), new OpTwiddling(3, new int[]{1, 2, 0}))); + new ActionRegistryEntry(HexPattern.fromAngleString("aaeaa", HexDir.EAST), new OpTwiddling(3, new int[]{1, 2, 0}))); public static final Holder ROTATE_REVERSE = REGISTER.registerHolder("rotate_reverse", () -> - new ActionRegistryEntry(HexPattern.fromAngles("ddqdd", + new ActionRegistryEntry(HexPattern.fromAngleString("ddqdd", HexDir.NORTH_EAST), new OpTwiddling(3, new int[]{2, 0, 1}))); public static final Holder DUPLICATE = REGISTER.registerHolder("duplicate", () -> - new ActionRegistryEntry(HexPattern.fromAngles("aadaa", HexDir.EAST), new OpTwiddling(1, new int[]{0, 0}))); + new ActionRegistryEntry(HexPattern.fromAngleString("aadaa", HexDir.EAST), new OpTwiddling(1, new int[]{0, 0}))); public static final Holder OVER = REGISTER.registerHolder("over", () -> - new ActionRegistryEntry(HexPattern.fromAngles("aaedd", HexDir.EAST), new OpTwiddling(2, new int[]{0, 1, 0}))); + new ActionRegistryEntry(HexPattern.fromAngleString("aaedd", HexDir.EAST), new OpTwiddling(2, new int[]{0, 1, 0}))); public static final Holder TUCK = REGISTER.registerHolder("tuck", () -> - new ActionRegistryEntry(HexPattern.fromAngles("ddqaa", HexDir.EAST), new OpTwiddling(2, new int[]{1, 0, 1}))); + new ActionRegistryEntry(HexPattern.fromAngleString("ddqaa", HexDir.EAST), new OpTwiddling(2, new int[]{1, 0, 1}))); public static final Holder TWO_DUP = REGISTER.registerHolder("2dup", () -> - new ActionRegistryEntry(HexPattern.fromAngles("aadadaaw", + new ActionRegistryEntry(HexPattern.fromAngleString("aadadaaw", HexDir.EAST), new OpTwiddling(2, new int[]{0, 1, 0, 1}))); public static final Holder STACK_LEN = REGISTER.registerHolder("stack_len", () -> - new ActionRegistryEntry(HexPattern.fromAngles("qwaeawqaeaqa", HexDir.NORTH_WEST), OpStackSize.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("qwaeawqaeaqa", HexDir.NORTH_WEST), OpStackSize.INSTANCE)); public static final Holder DUPLICATE_N = REGISTER.registerHolder("duplicate_n", () -> - new ActionRegistryEntry(HexPattern.fromAngles("aadaadaa", HexDir.EAST), OpDuplicateN.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("aadaadaa", HexDir.EAST), OpDuplicateN.INSTANCE)); public static final Holder FISHERMAN = REGISTER.registerHolder("fisherman", () -> - new ActionRegistryEntry(HexPattern.fromAngles("ddad", HexDir.WEST), OpFisherman.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("ddad", HexDir.WEST), OpFisherman.INSTANCE)); public static final Holder FISHERMAN$COPY = REGISTER.registerHolder("fisherman/copy", () -> - new ActionRegistryEntry(HexPattern.fromAngles("aada", HexDir.EAST), OpFishermanButItCopies.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("aada", HexDir.EAST), OpFishermanButItCopies.INSTANCE)); public static final Holder SWIZZLE = REGISTER.registerHolder("swizzle", () -> - new ActionRegistryEntry(HexPattern.fromAngles("qaawdde", + new ActionRegistryEntry(HexPattern.fromAngleString("qaawdde", HexDir.SOUTH_EAST), OpAlwinfyHasAscendedToABeingOfPureMath.INSTANCE)); // == Math == public static final Holder ADD = make("add", - new OperationAction(HexPattern.fromAngles("waaw", HexDir.NORTH_EAST))); + new OperationAction(HexPattern.fromAngleString("waaw", HexDir.NORTH_EAST))); public static final Holder SUB = make("sub", - new OperationAction(HexPattern.fromAngles("wddw", HexDir.NORTH_WEST))); + new OperationAction(HexPattern.fromAngleString("wddw", HexDir.NORTH_WEST))); public static final Holder MUL_DOT = make("mul", - new OperationAction(HexPattern.fromAngles("waqaw", HexDir.SOUTH_EAST))); + new OperationAction(HexPattern.fromAngleString("waqaw", HexDir.SOUTH_EAST))); public static final Holder DIV_CROSS = make("div", - new OperationAction(HexPattern.fromAngles("wdedw", HexDir.NORTH_EAST))); + new OperationAction(HexPattern.fromAngleString("wdedw", HexDir.NORTH_EAST))); public static final Holder ABS = make("abs", - new OperationAction(HexPattern.fromAngles("wqaqw", HexDir.NORTH_EAST))); + new OperationAction(HexPattern.fromAngleString("wqaqw", HexDir.NORTH_EAST))); public static final Holder POW_PROJ = make("pow", - new OperationAction(HexPattern.fromAngles("wedew", HexDir.NORTH_WEST))); + new OperationAction(HexPattern.fromAngleString("wedew", HexDir.NORTH_WEST))); public static final Holder FLOOR = make("floor", - new OperationAction(HexPattern.fromAngles("ewq", HexDir.EAST))); + new OperationAction(HexPattern.fromAngleString("ewq", HexDir.EAST))); public static final Holder CEIL = make("ceil", - new OperationAction(HexPattern.fromAngles("qwe", HexDir.EAST))); + new OperationAction(HexPattern.fromAngleString("qwe", HexDir.EAST))); public static final Holder CONSTRUCT_VEC = make("construct_vec", - new OperationAction(HexPattern.fromAngles("eqqqqq", HexDir.EAST))); + new OperationAction(HexPattern.fromAngleString("eqqqqq", HexDir.EAST))); public static final Holder DECONSTRUCT_VEC = make("deconstruct_vec", - new OperationAction(HexPattern.fromAngles("qeeeee", HexDir.EAST))); + new OperationAction(HexPattern.fromAngleString("qeeeee", HexDir.EAST))); public static final Holder COERCE_AXIAL = REGISTER.registerHolder("coerce_axial", () -> - new ActionRegistryEntry(HexPattern.fromAngles("qqqqqaww", HexDir.NORTH_WEST), OpCoerceToAxial.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("qqqqqaww", HexDir.NORTH_WEST), OpCoerceToAxial.INSTANCE)); // == Logic == public static final Holder AND = make("and", - new OperationAction(HexPattern.fromAngles("wdw", HexDir.NORTH_EAST))); + new OperationAction(HexPattern.fromAngleString("wdw", HexDir.NORTH_EAST))); public static final Holder OR = make("or", - new OperationAction(HexPattern.fromAngles("waw", HexDir.SOUTH_EAST))); + new OperationAction(HexPattern.fromAngleString("waw", HexDir.SOUTH_EAST))); public static final Holder NOT = make("not", - new OperationAction(HexPattern.fromAngles("dw", HexDir.NORTH_WEST))); + new OperationAction(HexPattern.fromAngleString("dw", HexDir.NORTH_WEST))); public static final Holder XOR = make("xor", - new OperationAction(HexPattern.fromAngles("dwa", HexDir.NORTH_WEST))); + new OperationAction(HexPattern.fromAngleString("dwa", HexDir.NORTH_WEST))); public static final Holder GREATER = make("greater", new OperationAction( - HexPattern.fromAngles("e", HexDir.SOUTH_EAST)) + HexPattern.fromAngleString("e", HexDir.SOUTH_EAST)) ); public static final Holder LESS = make("less", new OperationAction( - HexPattern.fromAngles("q", HexDir.SOUTH_WEST)) + HexPattern.fromAngleString("q", HexDir.SOUTH_WEST)) ); public static final Holder GREATER_EQ = make("greater_eq", new OperationAction( - HexPattern.fromAngles("ee", HexDir.SOUTH_EAST)) + HexPattern.fromAngleString("ee", HexDir.SOUTH_EAST)) ); public static final Holder LESS_EQ = make("less_eq", new OperationAction( - HexPattern.fromAngles("qq", HexDir.SOUTH_WEST)) + HexPattern.fromAngleString("qq", HexDir.SOUTH_WEST)) ); public static final Holder EQUALS = REGISTER.registerHolder("equals", () -> - new ActionRegistryEntry(HexPattern.fromAngles("ad", HexDir.EAST), new OpEquality(false))); + new ActionRegistryEntry(HexPattern.fromAngleString("ad", HexDir.EAST), new OpEquality(false))); public static final Holder NOT_EQUALS = REGISTER.registerHolder("not_equals", () -> - new ActionRegistryEntry(HexPattern.fromAngles("da", HexDir.EAST), new OpEquality(true))); + new ActionRegistryEntry(HexPattern.fromAngleString("da", HexDir.EAST), new OpEquality(true))); public static final Holder TYPE_EQUALS = REGISTER.registerHolder("type_equals", () -> - new ActionRegistryEntry(HexPattern.fromAngles("wawdw", HexDir.EAST), new OpTypeEquality(false))); + new ActionRegistryEntry(HexPattern.fromAngleString("wawdw", HexDir.EAST), new OpTypeEquality(false))); public static final Holder TYPE_NOT_EQUALS = REGISTER.registerHolder("type_not_equals", () -> - new ActionRegistryEntry(HexPattern.fromAngles("wdwaw", HexDir.EAST), new OpTypeEquality(true))); + new ActionRegistryEntry(HexPattern.fromAngleString("wdwaw", HexDir.EAST), new OpTypeEquality(true))); public static final Holder BOOL_COERCE = REGISTER.registerHolder("bool_coerce", () -> - new ActionRegistryEntry(HexPattern.fromAngles("aw", HexDir.NORTH_EAST), OpCoerceToBool.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("aw", HexDir.NORTH_EAST), OpCoerceToBool.INSTANCE)); public static final Holder IF = REGISTER.registerHolder("if", () -> - new ActionRegistryEntry(HexPattern.fromAngles("awdd", HexDir.SOUTH_EAST), OpBoolIf.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("awdd", HexDir.SOUTH_EAST), OpBoolIf.INSTANCE)); public static final Holder RANDOM = REGISTER.registerHolder("random", () -> - new ActionRegistryEntry(HexPattern.fromAngles("eqqq", HexDir.NORTH_WEST), OpRandom.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("eqqq", HexDir.NORTH_WEST), OpRandom.INSTANCE)); // == Advanced Math == public static final Holder SIN = make("sin", - new OperationAction(HexPattern.fromAngles("qqqqqaa", HexDir.SOUTH_EAST))); + new OperationAction(HexPattern.fromAngleString("qqqqqaa", HexDir.SOUTH_EAST))); public static final Holder COS = make("cos", - new OperationAction(HexPattern.fromAngles("qqqqqad", HexDir.SOUTH_EAST))); + new OperationAction(HexPattern.fromAngleString("qqqqqad", HexDir.SOUTH_EAST))); public static final Holder TAN = make("tan", - new OperationAction(HexPattern.fromAngles("wqqqqqadq", HexDir.SOUTH_WEST))); + new OperationAction(HexPattern.fromAngleString("wqqqqqadq", HexDir.SOUTH_WEST))); public static final Holder ARCSIN = make("arcsin", - new OperationAction(HexPattern.fromAngles("ddeeeee", HexDir.SOUTH_EAST))); + new OperationAction(HexPattern.fromAngleString("ddeeeee", HexDir.SOUTH_EAST))); public static final Holder ARCCOS = make("arccos", - new OperationAction(HexPattern.fromAngles("adeeeee", HexDir.NORTH_EAST))); + new OperationAction(HexPattern.fromAngleString("adeeeee", HexDir.NORTH_EAST))); public static final Holder ARCTAN = make("arctan", - new OperationAction(HexPattern.fromAngles("eadeeeeew", HexDir.NORTH_EAST))); + new OperationAction(HexPattern.fromAngleString("eadeeeeew", HexDir.NORTH_EAST))); public static final Holder ARCTAN2 = make("arctan2", - new OperationAction(HexPattern.fromAngles("deadeeeeewd", HexDir.WEST))); + new OperationAction(HexPattern.fromAngleString("deadeeeeewd", HexDir.WEST))); public static final Holder LOGARITHM = make("logarithm", - new OperationAction(HexPattern.fromAngles("eqaqe", HexDir.NORTH_WEST))); + new OperationAction(HexPattern.fromAngleString("eqaqe", HexDir.NORTH_WEST))); public static final Holder MODULO = make("modulo", - new OperationAction(HexPattern.fromAngles("addwaad", HexDir.NORTH_EAST))); + new OperationAction(HexPattern.fromAngleString("addwaad", HexDir.NORTH_EAST))); // == Sets == public static final Holder UNIQUE = make("unique", - new OperationAction(HexPattern.fromAngles("aweaqa", HexDir.NORTH_EAST))); + new OperationAction(HexPattern.fromAngleString("aweaqa", HexDir.NORTH_EAST))); // == Spells == public static final Holder PRINT = REGISTER.registerHolder("print", () -> - new ActionRegistryEntry(HexPattern.fromAngles("de", HexDir.NORTH_EAST), OpPrint.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("de", HexDir.NORTH_EAST), OpPrint.INSTANCE)); public static final Holder EXPLODE = REGISTER.registerHolder("explode", () -> - new ActionRegistryEntry(HexPattern.fromAngles("aawaawaa", HexDir.EAST), new OpExplode(false))); + new ActionRegistryEntry(HexPattern.fromAngleString("aawaawaa", HexDir.EAST), new OpExplode(false))); public static final Holder EXPLODE$FIRE = REGISTER.registerHolder("explode/fire", () -> - new ActionRegistryEntry(HexPattern.fromAngles("ddwddwdd", HexDir.EAST), new OpExplode(true))); + new ActionRegistryEntry(HexPattern.fromAngleString("ddwddwdd", HexDir.EAST), new OpExplode(true))); public static final Holder ADD_MOTION = REGISTER.registerHolder("add_motion", () -> - new ActionRegistryEntry(HexPattern.fromAngles("awqqqwaqw", HexDir.SOUTH_WEST), OpAddMotion.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("awqqqwaqw", HexDir.SOUTH_WEST), OpAddMotion.INSTANCE)); public static final Holder BLINK = REGISTER.registerHolder("blink", () -> - new ActionRegistryEntry(HexPattern.fromAngles("awqqqwaq", HexDir.SOUTH_WEST), OpBlink.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("awqqqwaq", HexDir.SOUTH_WEST), OpBlink.INSTANCE)); public static final Holder BREAK_BLOCK = REGISTER.registerHolder("break_block", () -> - new ActionRegistryEntry(HexPattern.fromAngles("qaqqqqq", HexDir.EAST), OpBreakBlock.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("qaqqqqq", HexDir.EAST), OpBreakBlock.INSTANCE)); public static final Holder PLACE_BLOCK = REGISTER.registerHolder("place_block", () -> - new ActionRegistryEntry(HexPattern.fromAngles("eeeeede", HexDir.SOUTH_WEST), OpPlaceBlock.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("eeeeede", HexDir.SOUTH_WEST), OpPlaceBlock.INSTANCE)); public static final Holder COLORIZE = REGISTER.registerHolder("colorize", () -> - new ActionRegistryEntry(HexPattern.fromAngles("awddwqawqwawq", HexDir.EAST), OpColorize.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("awddwqawqwawq", HexDir.EAST), OpColorize.INSTANCE)); public static final Holder CYCLE_VARIANT = REGISTER.registerHolder("cycle_variant", () -> - new ActionRegistryEntry(HexPattern.fromAngles("dwaawedwewdwe", HexDir.WEST), OpCycleVariant.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("dwaawedwewdwe", HexDir.WEST), OpCycleVariant.INSTANCE)); public static final Holder CREATE_WATER = REGISTER.registerHolder("create_water", () -> - new ActionRegistryEntry(HexPattern.fromAngles("aqawqadaq", HexDir.SOUTH_EAST), new OpCreateFluid( + new ActionRegistryEntry(HexPattern.fromAngleString("aqawqadaq", HexDir.SOUTH_EAST), new OpCreateFluid( MediaConstants.DUST_UNIT, Items.WATER_BUCKET, Blocks.WATER_CAULDRON.defaultBlockState() .setValue(LayeredCauldronBlock.LEVEL, LayeredCauldronBlock.MAX_FILL_LEVEL), Fluids.WATER))); public static final Holder DESTROY_WATER = REGISTER.registerHolder("destroy_water", () -> - new ActionRegistryEntry(HexPattern.fromAngles("dedwedade", HexDir.SOUTH_WEST), OpDestroyFluid.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("dedwedade", HexDir.SOUTH_WEST), OpDestroyFluid.INSTANCE)); public static final Holder IGNITE = REGISTER.registerHolder("ignite", () -> - new ActionRegistryEntry(HexPattern.fromAngles("aaqawawa", HexDir.SOUTH_EAST), OpIgnite.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("aaqawawa", HexDir.SOUTH_EAST), OpIgnite.INSTANCE)); public static final Holder EXTINGUISH = REGISTER.registerHolder("extinguish", () -> - new ActionRegistryEntry(HexPattern.fromAngles("ddedwdwd", HexDir.SOUTH_WEST), OpExtinguish.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("ddedwdwd", HexDir.SOUTH_WEST), OpExtinguish.INSTANCE)); public static final Holder CONJURE_BLOCK = REGISTER.registerHolder("conjure_block", () -> - new ActionRegistryEntry(HexPattern.fromAngles("qqa", HexDir.NORTH_EAST), new OpConjureBlock(false))); + new ActionRegistryEntry(HexPattern.fromAngleString("qqa", HexDir.NORTH_EAST), new OpConjureBlock(false))); public static final Holder CONJURE_LIGHT = REGISTER.registerHolder("conjure_light", () -> - new ActionRegistryEntry(HexPattern.fromAngles("qqd", HexDir.NORTH_EAST), new OpConjureBlock(true))); + new ActionRegistryEntry(HexPattern.fromAngleString("qqd", HexDir.NORTH_EAST), new OpConjureBlock(true))); public static final Holder BONEMEAL = REGISTER.registerHolder("bonemeal", () -> - new ActionRegistryEntry(HexPattern.fromAngles("wqaqwawqaqw", + new ActionRegistryEntry(HexPattern.fromAngleString("wqaqwawqaqw", HexDir.NORTH_EAST), OpTheOnlyReasonAnyoneDownloadedPsi.INSTANCE)); public static final Holder RECHARGE = REGISTER.registerHolder("recharge", () -> - new ActionRegistryEntry(HexPattern.fromAngles("qqqqqwaeaeaeaeaea", HexDir.NORTH_WEST), OpRecharge.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("qqqqqwaeaeaeaeaea", HexDir.NORTH_WEST), OpRecharge.INSTANCE)); public static final Holder ERASE = REGISTER.registerHolder("erase", () -> - new ActionRegistryEntry(HexPattern.fromAngles("qdqawwaww", HexDir.EAST), OpErase.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("qdqawwaww", HexDir.EAST), OpErase.INSTANCE)); public static final Holder EDIFY = REGISTER.registerHolder("edify", () -> - new ActionRegistryEntry(HexPattern.fromAngles("wqaqwd", HexDir.NORTH_EAST), OpEdifySapling.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("wqaqwd", HexDir.NORTH_EAST), OpEdifySapling.INSTANCE)); public static final Holder BEEP = REGISTER.registerHolder("beep", () -> - new ActionRegistryEntry(HexPattern.fromAngles("adaa", HexDir.WEST), OpBeep.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("adaa", HexDir.WEST), OpBeep.INSTANCE)); public static final Holder CRAFT$CYPHER = REGISTER.registerHolder("craft/cypher", () -> new ActionRegistryEntry( - HexPattern.fromAngles("waqqqqq", HexDir.EAST), + HexPattern.fromAngleString("waqqqqq", HexDir.EAST), new OpMakePackagedSpell(s -> (s.is(HexItems.CYPHER.get())||s.is(HexItems.ANCIENT_CYPHER.get())), HexItems.CYPHER.get()::getDescription, MediaConstants.CRYSTAL_UNIT) )); public static final Holder CRAFT$TRINKET = REGISTER.registerHolder("craft/trinket", () -> new ActionRegistryEntry( - HexPattern.fromAngles("wwaqqqqqeaqeaeqqqeaeq", HexDir.EAST), + HexPattern.fromAngleString("wwaqqqqqeaqeaeqqqeaeq", HexDir.EAST), new OpMakePackagedSpell(HexItems.TRINKET.get(), 5 * MediaConstants.CRYSTAL_UNIT) )); public static final Holder CRAFT$ARTIFACT = REGISTER.registerHolder("craft/artifact", () -> new ActionRegistryEntry( - HexPattern.fromAngles("wwaqqqqqeawqwqwqwqwqwwqqeadaeqqeqqeadaeqq", HexDir.EAST), + HexPattern.fromAngleString("wwaqqqqqeawqwqwqwqwqwwqqeadaeqqeqqeadaeqq", HexDir.EAST), new OpMakePackagedSpell(HexItems.ARTIFACT.get(), 10 * MediaConstants.CRYSTAL_UNIT) )); public static final Holder CRAFT$BATTERY = REGISTER.registerHolder("craft/battery", () -> new ActionRegistryEntry( - HexPattern.fromAngles("aqqqaqwwaqqqqqeqaqqqawwqwqwqwqwqw", HexDir.SOUTH_WEST), OpMakeBattery.INSTANCE)); + HexPattern.fromAngleString("aqqqaqwwaqqqqqeqaqqqawwqwqwqwqwqw", HexDir.SOUTH_WEST), OpMakeBattery.INSTANCE)); public static final Holder POTION$WEAKNESS = REGISTER.registerHolder("potion/weakness", () -> new ActionRegistryEntry( - HexPattern.fromAngles("qqqqqaqwawaw", HexDir.NORTH_WEST), new OpPotionEffect(MobEffects.WEAKNESS, + HexPattern.fromAngleString("qqqqqaqwawaw", HexDir.NORTH_WEST), new OpPotionEffect(MobEffects.WEAKNESS, MediaConstants.DUST_UNIT / 10, true, false) )); public static final Holder POTION$LEVITATION = REGISTER.registerHolder("potion/levitation", () -> new ActionRegistryEntry( - HexPattern.fromAngles("qqqqqawwawawd", HexDir.WEST), new OpPotionEffect(MobEffects.LEVITATION, + HexPattern.fromAngleString("qqqqqawwawawd", HexDir.WEST), new OpPotionEffect(MobEffects.LEVITATION, MediaConstants.DUST_UNIT / 5, false, false) )); public static final Holder POTION$WITHER = REGISTER.registerHolder("potion/wither", () -> new ActionRegistryEntry( - HexPattern.fromAngles("qqqqqaewawawe", HexDir.SOUTH_WEST), new OpPotionEffect(MobEffects.WITHER, + HexPattern.fromAngleString("qqqqqaewawawe", HexDir.SOUTH_WEST), new OpPotionEffect(MobEffects.WITHER, MediaConstants.DUST_UNIT, true, false) )); public static final Holder POTION$POISON = REGISTER.registerHolder("potion/poison", () -> new ActionRegistryEntry( - HexPattern.fromAngles("qqqqqadwawaww", HexDir.SOUTH_EAST), new OpPotionEffect(MobEffects.POISON, + HexPattern.fromAngleString("qqqqqadwawaww", HexDir.SOUTH_EAST), new OpPotionEffect(MobEffects.POISON, MediaConstants.DUST_UNIT / 3, true, false) )); public static final Holder POTION$SLOWNESS = REGISTER.registerHolder("potion/slowness", () -> new ActionRegistryEntry( - HexPattern.fromAngles("qqqqqadwawaw", HexDir.SOUTH_EAST), new OpPotionEffect(MobEffects.MOVEMENT_SLOWDOWN, + HexPattern.fromAngleString("qqqqqadwawaw", HexDir.SOUTH_EAST), new OpPotionEffect(MobEffects.MOVEMENT_SLOWDOWN, MediaConstants.DUST_UNIT / 3, true, false) )); public static final Holder POTION$REGENERATION = REGISTER.registerHolder("potion/regeneration", () -> new ActionRegistryEntry( - HexPattern.fromAngles("qqqqaawawaedd", HexDir.NORTH_WEST), new OpPotionEffect(MobEffects.REGENERATION, + HexPattern.fromAngleString("qqqqaawawaedd", HexDir.NORTH_WEST), new OpPotionEffect(MobEffects.REGENERATION, MediaConstants.DUST_UNIT, true, true) )); public static final Holder POTION$NIGHT_VISION = REGISTER.registerHolder("potion/night_vision", () -> new ActionRegistryEntry( - HexPattern.fromAngles("qqqaawawaeqdd", HexDir.WEST), new OpPotionEffect(MobEffects.NIGHT_VISION, + HexPattern.fromAngleString("qqqaawawaeqdd", HexDir.WEST), new OpPotionEffect(MobEffects.NIGHT_VISION, MediaConstants.DUST_UNIT / 5, false, true) )); public static final Holder POTION$ABSORPTION = REGISTER.registerHolder("potion/absorption", () -> new ActionRegistryEntry( - HexPattern.fromAngles("qqaawawaeqqdd", HexDir.SOUTH_WEST), new OpPotionEffect(MobEffects.ABSORPTION, + HexPattern.fromAngleString("qqaawawaeqqdd", HexDir.SOUTH_WEST), new OpPotionEffect(MobEffects.ABSORPTION, MediaConstants.DUST_UNIT, true, true) )); public static final Holder POTION$HASTE = REGISTER.registerHolder("potion/haste", () -> new ActionRegistryEntry( - HexPattern.fromAngles("qaawawaeqqqdd", HexDir.SOUTH_EAST), new OpPotionEffect(MobEffects.DIG_SPEED, + HexPattern.fromAngleString("qaawawaeqqqdd", HexDir.SOUTH_EAST), new OpPotionEffect(MobEffects.DIG_SPEED, MediaConstants.DUST_UNIT / 3, true, true) )); public static final Holder POTION$STRENGTH = REGISTER.registerHolder("potion/strength", () -> new ActionRegistryEntry( - HexPattern.fromAngles("aawawaeqqqqdd", HexDir.EAST), new OpPotionEffect(MobEffects.DAMAGE_BOOST, + HexPattern.fromAngleString("aawawaeqqqqdd", HexDir.EAST), new OpPotionEffect(MobEffects.DAMAGE_BOOST, MediaConstants.DUST_UNIT / 3, true, true) )); public static final Holder FLIGHT$RANGE = REGISTER.registerHolder("flight/range", () -> - new ActionRegistryEntry(HexPattern.fromAngles("awawaawq", HexDir.SOUTH_WEST), + new ActionRegistryEntry(HexPattern.fromAngleString("awawaawq", HexDir.SOUTH_WEST), new OpFlight(OpFlight.Type.LimitRange))); public static final Holder FLIGHT$TIME = REGISTER.registerHolder("flight/time", () -> - new ActionRegistryEntry(HexPattern.fromAngles("dwdwdewq", HexDir.NORTH_EAST), + new ActionRegistryEntry(HexPattern.fromAngleString("dwdwdewq", HexDir.NORTH_EAST), new OpFlight(OpFlight.Type.LimitTime))); public static final Holder FLIGHT$CAN_FLY = REGISTER.registerHolder("flight/can_fly", () -> - new ActionRegistryEntry(HexPattern.fromAngles("dwdwdeweaqa", HexDir.NORTH_EAST), + new ActionRegistryEntry(HexPattern.fromAngleString("dwdwdeweaqa", HexDir.NORTH_EAST), OpCanEntityHexFly.INSTANCE)); public static final Holder SENTINEL$CREATE = REGISTER.registerHolder("sentinel/create", () -> - new ActionRegistryEntry(HexPattern.fromAngles("waeawae", HexDir.EAST), new OpCreateSentinel(false))); + new ActionRegistryEntry(HexPattern.fromAngleString("waeawae", HexDir.EAST), new OpCreateSentinel(false))); public static final Holder SENTINEL$DESTROY = REGISTER.registerHolder("sentinel/destroy", () -> - new ActionRegistryEntry(HexPattern.fromAngles("qdwdqdw", HexDir.NORTH_EAST), OpDestroySentinel.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("qdwdqdw", HexDir.NORTH_EAST), OpDestroySentinel.INSTANCE)); public static final Holder SENTINEL$GET_POS = REGISTER.registerHolder("sentinel/get_pos", () -> - new ActionRegistryEntry(HexPattern.fromAngles("waeawaede", HexDir.EAST), OpGetSentinelPos.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("waeawaede", HexDir.EAST), OpGetSentinelPos.INSTANCE)); public static final Holder SENTINEL$WAYFIND = REGISTER.registerHolder("sentinel/wayfind", () -> - new ActionRegistryEntry(HexPattern.fromAngles("waeawaedwa", HexDir.EAST), OpGetSentinelWayfind.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("waeawaedwa", HexDir.EAST), OpGetSentinelWayfind.INSTANCE)); public static final Holder LIGHTNING = REGISTER.registerHolder("lightning", () -> - new ActionRegistryEntry(HexPattern.fromAngles("waadwawdaaweewq", HexDir.EAST), OpLightning.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("waadwawdaaweewq", HexDir.EAST), OpLightning.INSTANCE)); public static final Holder ALTIORA = REGISTER.registerHolder("flight", () -> - new ActionRegistryEntry(HexPattern.fromAngles("eawwaeawawaa", HexDir.NORTH_WEST), OpAltiora.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("eawwaeawawaa", HexDir.NORTH_WEST), OpAltiora.INSTANCE)); public static final Holder CREATE_LAVA = REGISTER.registerHolder("create_lava", () -> - new ActionRegistryEntry(HexPattern.fromAngles("eaqawqadaqd", HexDir.EAST), new OpCreateFluid( + new ActionRegistryEntry(HexPattern.fromAngleString("eaqawqadaqd", HexDir.EAST), new OpCreateFluid( MediaConstants.CRYSTAL_UNIT, Items.LAVA_BUCKET, Blocks.LAVA_CAULDRON.defaultBlockState(), Fluids.LAVA))); public static final Holder TELEPORT = REGISTER.registerHolder("teleport/great", () -> - new ActionRegistryEntry(HexPattern.fromAngles("wwwqqqwwwqqeqqwwwqqwqqdqqqqqdqq", + new ActionRegistryEntry(HexPattern.fromAngleString("wwwqqqwwwqqeqqwwwqqwqqdqqqqqdqq", HexDir.EAST), OpTeleport.INSTANCE)); public static final Holder SENTINEL$GREAT = REGISTER.registerHolder("sentinel/create/great", () -> - new ActionRegistryEntry(HexPattern.fromAngles("waeawaeqqqwqwqqwq", HexDir.EAST), new OpCreateSentinel(true))); + new ActionRegistryEntry(HexPattern.fromAngleString("waeawaeqqqwqwqqwq", HexDir.EAST), new OpCreateSentinel(true))); public static final Holder DISPEL_RAIN = REGISTER.registerHolder("dispel_rain", () -> - new ActionRegistryEntry(HexPattern.fromAngles("eeewwweeewwaqqddqdqd", HexDir.EAST), new OpWeather(false))); + new ActionRegistryEntry(HexPattern.fromAngleString("eeewwweeewwaqqddqdqd", HexDir.EAST), new OpWeather(false))); public static final Holder SUMMON_RAIN = REGISTER.registerHolder("summon_rain", () -> - new ActionRegistryEntry(HexPattern.fromAngles("wwweeewwweewdawdwad", HexDir.WEST), new OpWeather(true))); + new ActionRegistryEntry(HexPattern.fromAngleString("wwweeewwweewdawdwad", HexDir.WEST), new OpWeather(true))); public static final Holder BRAINSWEEP = REGISTER.registerHolder("brainsweep", () -> - new ActionRegistryEntry(HexPattern.fromAngles("qeqwqwqwqwqeqaeqeaqeqaeqaqded", + new ActionRegistryEntry(HexPattern.fromAngleString("qeqwqwqwqwqeqaeqeaqeqaeqaqded", HexDir.NORTH_EAST), OpBrainsweep.INSTANCE)); public static final Holder AKASHIC$READ = REGISTER.registerHolder("akashic/read", () -> - new ActionRegistryEntry(HexPattern.fromAngles("qqqwqqqqqaq", HexDir.WEST), OpAkashicRead.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("qqqwqqqqqaq", HexDir.WEST), OpAkashicRead.INSTANCE)); public static final Holder AKASHIC$WRITE = REGISTER.registerHolder("akashic/write", () -> - new ActionRegistryEntry(HexPattern.fromAngles("eeeweeeeede", HexDir.EAST), OpAkashicWrite.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("eeeweeeeede", HexDir.EAST), OpAkashicWrite.INSTANCE)); // == Meta stuff == public static final Holder ESCAPE = REGISTER.registerHolder("escape", () -> - new ActionRegistryEntry(HexPattern.fromAngles("qqqaw", HexDir.WEST), OpEscape.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("qqqaw", HexDir.WEST), OpEscape.INSTANCE)); public static final Holder RUNTIME_ESCAPE = REGISTER.registerHolder("runtime_escape", () -> - new ActionRegistryEntry(HexPattern.fromAngles("wdeee", HexDir.SOUTH_EAST), OpRuntimeEscape.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("wdeee", HexDir.SOUTH_EAST), OpRuntimeEscape.INSTANCE)); public static final Holder OPEN_PAREN = REGISTER.registerHolder("open_paren", () -> - new ActionRegistryEntry(HexPattern.fromAngles("qqq", HexDir.WEST), OpOpenParen.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("qqq", HexDir.WEST), OpOpenParen.INSTANCE)); public static final Holder CLOSE_PAREN = REGISTER.registerHolder("close_paren", () -> - new ActionRegistryEntry(HexPattern.fromAngles("eee", HexDir.EAST), OpCloseParen.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("eee", HexDir.EAST), OpCloseParen.INSTANCE)); public static final Holder OPEN_N_PARENS = REGISTER.registerHolder("open_n_parens", () -> - new ActionRegistryEntry(HexPattern.fromAngles("qdaqadq", HexDir.WEST), OpOpenNParens.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("qdaqadq", HexDir.WEST), OpOpenNParens.INSTANCE)); public static final Holder CLOSE_ALL_PARENS = REGISTER.registerHolder("close_all_parens", () -> - new ActionRegistryEntry(HexPattern.fromAngles("eadedae", HexDir.EAST), OpCloseAllParens.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("eadedae", HexDir.EAST), OpCloseAllParens.INSTANCE)); public static final Holder READ_INTO_PARENS = REGISTER.registerHolder("read_into_parens", () -> - new ActionRegistryEntry(HexPattern.fromAngles("aqqqqqwded", HexDir.EAST), OpReadIntoParens.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("aqqqqqwded", HexDir.EAST), OpReadIntoParens.INSTANCE)); public static final Holder UNDO = REGISTER.registerHolder("undo", () -> - new ActionRegistryEntry(HexPattern.fromAngles("eeedw", HexDir.EAST), OpUndo.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("eeedw", HexDir.EAST), OpUndo.INSTANCE)); public static final Holder SIMULATE = REGISTER.registerHolder("simulate", () -> - new ActionRegistryEntry(HexPattern.fromAngles("deaq", HexDir.EAST), OpSimulate.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("deaq", HexDir.EAST), OpSimulate.INSTANCE)); // http://www.toroidalsnark.net/mkss3-pix/CalderheadJMM2014.pdf // eval being a space filling curve feels apt doesn't it public static final Holder EVAL = REGISTER.registerHolder("eval", () -> - new ActionRegistryEntry(HexPattern.fromAngles("deaqq", HexDir.SOUTH_EAST), OpEval.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("deaqq", HexDir.SOUTH_EAST), OpEval.INSTANCE)); public static final Holder EVAL$CC = REGISTER.registerHolder("eval/cc", () -> - new ActionRegistryEntry(HexPattern.fromAngles("qwaqde", HexDir.NORTH_WEST), OpEvalBreakable.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("qwaqde", HexDir.NORTH_WEST), OpEvalBreakable.INSTANCE)); public static final Holder HALT = REGISTER.registerHolder("halt", () -> - new ActionRegistryEntry(HexPattern.fromAngles("aqdee", HexDir.SOUTH_WEST), OpHalt.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("aqdee", HexDir.SOUTH_WEST), OpHalt.INSTANCE)); public static final Holder READ = REGISTER.registerHolder("read", () -> - new ActionRegistryEntry(HexPattern.fromAngles("aqqqqq", HexDir.EAST), OpRead.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("aqqqqq", HexDir.EAST), OpRead.INSTANCE)); public static final Holder READ$ENTITY = REGISTER.registerHolder("read/entity", () -> - new ActionRegistryEntry(HexPattern.fromAngles("wawqwqwqwqwqw", HexDir.EAST), OpTheCoolerRead.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("wawqwqwqwqwqw", HexDir.EAST), OpTheCoolerRead.INSTANCE)); public static final Holder WRITE = REGISTER.registerHolder("write", () -> - new ActionRegistryEntry(HexPattern.fromAngles("deeeee", HexDir.EAST), OpWrite.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("deeeee", HexDir.EAST), OpWrite.INSTANCE)); public static final Holder WRITE$ENTITY = REGISTER.registerHolder("write/entity", () -> - new ActionRegistryEntry(HexPattern.fromAngles("wdwewewewewew", HexDir.EAST), OpTheCoolerWrite.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("wdwewewewewew", HexDir.EAST), OpTheCoolerWrite.INSTANCE)); public static final Holder READ$LOCAL = REGISTER.registerHolder("read/local", () -> - new ActionRegistryEntry(HexPattern.fromAngles("qeewdweddw", HexDir.NORTH_EAST), OpPeekLocal.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("qeewdweddw", HexDir.NORTH_EAST), OpPeekLocal.INSTANCE)); public static final Holder WRITE$LOCAL = REGISTER.registerHolder("write/local", () -> - new ActionRegistryEntry(HexPattern.fromAngles("eqqwawqaaw", HexDir.NORTH_WEST), OpPushLocal.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("eqqwawqaaw", HexDir.NORTH_WEST), OpPushLocal.INSTANCE)); public static final Holder THANATOS = REGISTER.registerHolder("thanatos", () -> - new ActionRegistryEntry(HexPattern.fromAngles("qqaed", HexDir.SOUTH_EAST), OpThanos.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("qqaed", HexDir.SOUTH_EAST), OpThanos.INSTANCE)); // == Consts == public static final Holder CONST$NULL = REGISTER.registerHolder("const/null", () -> - new ActionRegistryEntry(HexPattern.fromAngles("d", HexDir.EAST), Action.makeConstantOp(new NullIota()))); + new ActionRegistryEntry(HexPattern.fromAngleString("d", HexDir.EAST), Action.makeConstantOp(new NullIota()))); public static final Holder CONST$TRUE = REGISTER.registerHolder("const/true", () -> - new ActionRegistryEntry(HexPattern.fromAngles("aqae", + new ActionRegistryEntry(HexPattern.fromAngleString("aqae", HexDir.SOUTH_EAST), Action.makeConstantOp(new BooleanIota(true)))); public static final Holder CONST$FALSE = REGISTER.registerHolder("const/false", () -> - new ActionRegistryEntry(HexPattern.fromAngles("dedq", + new ActionRegistryEntry(HexPattern.fromAngleString("dedq", HexDir.NORTH_EAST), Action.makeConstantOp(new BooleanIota(false)))); public static final Holder CONST$VEC$PX = REGISTER.registerHolder("const/vec/px", () -> - new ActionRegistryEntry(HexPattern.fromAngles( + new ActionRegistryEntry(HexPattern.fromAngleString( "qqqqqea", HexDir.NORTH_WEST), Action.makeConstantOp(new Vec3Iota(new Vec3(1.0, 0.0, 0.0))))); public static final Holder CONST$VEC$PY = REGISTER.registerHolder("const/vec/py", () -> - new ActionRegistryEntry(HexPattern.fromAngles( + new ActionRegistryEntry(HexPattern.fromAngleString( "qqqqqew", HexDir.NORTH_WEST), Action.makeConstantOp(new Vec3Iota(new Vec3(0.0, 1.0, 0.0))))); public static final Holder CONST$VEC$PZ = REGISTER.registerHolder("const/vec/pz", () -> - new ActionRegistryEntry(HexPattern.fromAngles( + new ActionRegistryEntry(HexPattern.fromAngleString( "qqqqqed", HexDir.NORTH_WEST), Action.makeConstantOp(new Vec3Iota(new Vec3(0.0, 0.0, 1.0))))); public static final Holder CONST$VEC$NX = REGISTER.registerHolder("const/vec/nx", () -> - new ActionRegistryEntry(HexPattern.fromAngles( + new ActionRegistryEntry(HexPattern.fromAngleString( "eeeeeqa", HexDir.SOUTH_WEST), Action.makeConstantOp(new Vec3Iota(new Vec3(-1.0, 0.0, 0.0))))); public static final Holder CONST$VEC$NY = REGISTER.registerHolder("const/vec/ny", () -> - new ActionRegistryEntry(HexPattern.fromAngles( + new ActionRegistryEntry(HexPattern.fromAngleString( "eeeeeqw", HexDir.SOUTH_WEST), Action.makeConstantOp(new Vec3Iota(new Vec3(0.0, -1.0, 0.0))))); public static final Holder CONST$VEC$NZ = REGISTER.registerHolder("const/vec/nz", () -> - new ActionRegistryEntry(HexPattern.fromAngles( + new ActionRegistryEntry(HexPattern.fromAngleString( "eeeeeqd", HexDir.SOUTH_WEST), Action.makeConstantOp(new Vec3Iota(new Vec3(0.0, 0.0, -1.0))))); // Yep, this is what I spend the "plain hexagon" pattern on. public static final Holder CONST$VEC$0 = REGISTER.registerHolder("const/vec/0", () -> - new ActionRegistryEntry(HexPattern.fromAngles( + new ActionRegistryEntry(HexPattern.fromAngleString( "qqqqq", HexDir.NORTH_WEST), Action.makeConstantOp(new Vec3Iota(new Vec3(0.0, 0.0, 0.0))))); public static final Holder CONST$DOUBLE$PI = REGISTER.registerHolder("const/double/pi", () -> - new ActionRegistryEntry(HexPattern.fromAngles("qdwdq", + new ActionRegistryEntry(HexPattern.fromAngleString("qdwdq", HexDir.NORTH_EAST), Action.makeConstantOp(new DoubleIota(Math.PI)))); public static final Holder CONST$DOUBLE$TAU = REGISTER.registerHolder("const/double/tau", () -> - new ActionRegistryEntry(HexPattern.fromAngles("eawae", + new ActionRegistryEntry(HexPattern.fromAngleString("eawae", HexDir.NORTH_WEST), Action.makeConstantOp(new DoubleIota(HexUtils.TAU)))); public static final Holder CONST$E = REGISTER.registerHolder("const/double/e", () -> - new ActionRegistryEntry(HexPattern.fromAngles("aaq", + new ActionRegistryEntry(HexPattern.fromAngleString("aaq", HexDir.EAST), Action.makeConstantOp(new DoubleIota(Math.E)))); public static final Holder CONST$PHI = REGISTER.registerHolder("const/double/phi", () -> - new ActionRegistryEntry(HexPattern.fromAngles("wdded", + new ActionRegistryEntry(HexPattern.fromAngleString("wdded", HexDir.NORTH_EAST), Action.makeConstantOp(new DoubleIota(1.618033988749895)))); // == Entities == public static final Holder GET_ENTITY = REGISTER.registerHolder("get_entity", () -> - new ActionRegistryEntry(HexPattern.fromAngles("qqqqqdaqa", HexDir.SOUTH_EAST), new OpGetEntityAt(e -> true))); + new ActionRegistryEntry(HexPattern.fromAngleString("qqqqqdaqa", HexDir.SOUTH_EAST), new OpGetEntityAt(e -> true))); public static final Holder GET_ENTITY$ANIMAL = REGISTER.registerHolder("get_entity/animal", () -> - new ActionRegistryEntry(HexPattern.fromAngles("qqqqqdaqaawa", + new ActionRegistryEntry(HexPattern.fromAngleString("qqqqqdaqaawa", HexDir.SOUTH_EAST), new OpGetEntityAt(OpGetEntitiesBy::isAnimal))); public static final Holder GET_ENTITY$MONSTER = REGISTER.registerHolder("get_entity/monster", () -> - new ActionRegistryEntry(HexPattern.fromAngles("qqqqqdaqaawq", + new ActionRegistryEntry(HexPattern.fromAngleString("qqqqqdaqaawq", HexDir.SOUTH_EAST), new OpGetEntityAt(OpGetEntitiesBy::isMonster))); public static final Holder GET_ENTITY$ITEM = REGISTER.registerHolder("get_entity/item", () -> - new ActionRegistryEntry(HexPattern.fromAngles("qqqqqdaqaaww", + new ActionRegistryEntry(HexPattern.fromAngleString("qqqqqdaqaaww", HexDir.SOUTH_EAST), new OpGetEntityAt(OpGetEntitiesBy::isItem))); public static final Holder GET_ENTITY$PLAYER = REGISTER.registerHolder("get_entity/player", () -> - new ActionRegistryEntry(HexPattern.fromAngles("qqqqqdaqaawe", + new ActionRegistryEntry(HexPattern.fromAngleString("qqqqqdaqaawe", HexDir.SOUTH_EAST), new OpGetEntityAt(OpGetEntitiesBy::isPlayer))); public static final Holder GET_ENTITY$LIVING = REGISTER.registerHolder("get_entity/living", () -> - new ActionRegistryEntry(HexPattern.fromAngles("qqqqqdaqaawd", + new ActionRegistryEntry(HexPattern.fromAngleString("qqqqqdaqaawd", HexDir.SOUTH_EAST), new OpGetEntityAt(OpGetEntitiesBy::isLiving))); public static final Holder ZONE_ENTITY = REGISTER.registerHolder("zone_entity", () -> new ActionRegistryEntry( - HexPattern.fromAngles("qqqqqwded", HexDir.SOUTH_EAST), new OpGetEntitiesBy(e -> true, false) + HexPattern.fromAngleString("qqqqqwded", HexDir.SOUTH_EAST), new OpGetEntitiesBy(e -> true, false) )); public static final Holder ZONE_ENTITY$ANIMAL = REGISTER.registerHolder("zone_entity/animal", () -> new ActionRegistryEntry( - HexPattern.fromAngles("qqqqqwdeddwa", HexDir.SOUTH_EAST), new OpGetEntitiesBy(OpGetEntitiesBy::isAnimal, false) + HexPattern.fromAngleString("qqqqqwdeddwa", HexDir.SOUTH_EAST), new OpGetEntitiesBy(OpGetEntitiesBy::isAnimal, false) )); public static final Holder ZONE_ENTITY$NOT_ANIMAL = REGISTER.registerHolder("zone_entity/not_animal", () -> new ActionRegistryEntry( - HexPattern.fromAngles("eeeeewaqaawa", HexDir.NORTH_EAST), new OpGetEntitiesBy(OpGetEntitiesBy::isAnimal, + HexPattern.fromAngleString("eeeeewaqaawa", HexDir.NORTH_EAST), new OpGetEntitiesBy(OpGetEntitiesBy::isAnimal, true) )); public static final Holder ZONE_ENTITY$MONSTER = REGISTER.registerHolder("zone_entity/monster", () -> new ActionRegistryEntry( - HexPattern.fromAngles("qqqqqwdeddwq", HexDir.SOUTH_EAST), new OpGetEntitiesBy(OpGetEntitiesBy::isMonster, false) + HexPattern.fromAngleString("qqqqqwdeddwq", HexDir.SOUTH_EAST), new OpGetEntitiesBy(OpGetEntitiesBy::isMonster, false) )); public static final Holder ZONE_ENTITY$NOT_MONSTER = REGISTER.registerHolder("zone_entity/not_monster", () -> new ActionRegistryEntry( - HexPattern.fromAngles("eeeeewaqaawq", HexDir.NORTH_EAST), new OpGetEntitiesBy(OpGetEntitiesBy::isMonster, + HexPattern.fromAngleString("eeeeewaqaawq", HexDir.NORTH_EAST), new OpGetEntitiesBy(OpGetEntitiesBy::isMonster, true) )); public static final Holder ZONE_ENTITY$ITEM = REGISTER.registerHolder("zone_entity/item", () -> new ActionRegistryEntry( - HexPattern.fromAngles("qqqqqwdeddww", HexDir.SOUTH_EAST), new OpGetEntitiesBy(OpGetEntitiesBy::isItem, false) + HexPattern.fromAngleString("qqqqqwdeddww", HexDir.SOUTH_EAST), new OpGetEntitiesBy(OpGetEntitiesBy::isItem, false) )); public static final Holder ZONE_ENTITY$NOT_ITEM = REGISTER.registerHolder("zone_entity/not_item", () -> new ActionRegistryEntry( - HexPattern.fromAngles("eeeeewaqaaww", HexDir.NORTH_EAST), new OpGetEntitiesBy(OpGetEntitiesBy::isItem, true) + HexPattern.fromAngleString("eeeeewaqaaww", HexDir.NORTH_EAST), new OpGetEntitiesBy(OpGetEntitiesBy::isItem, true) )); public static final Holder ZONE_ENTITY$PLAYER = REGISTER.registerHolder("zone_entity/player", () -> new ActionRegistryEntry( - HexPattern.fromAngles("qqqqqwdeddwe", HexDir.SOUTH_EAST), new OpGetEntitiesBy(OpGetEntitiesBy::isPlayer, false) + HexPattern.fromAngleString("qqqqqwdeddwe", HexDir.SOUTH_EAST), new OpGetEntitiesBy(OpGetEntitiesBy::isPlayer, false) )); public static final Holder ZONE_ENTITY$NOT_PLAYER = REGISTER.registerHolder("zone_entity/not_player", () -> new ActionRegistryEntry( - HexPattern.fromAngles("eeeeewaqaawe", HexDir.NORTH_EAST), new OpGetEntitiesBy(OpGetEntitiesBy::isPlayer, + HexPattern.fromAngleString("eeeeewaqaawe", HexDir.NORTH_EAST), new OpGetEntitiesBy(OpGetEntitiesBy::isPlayer, true) )); public static final Holder ZONE_ENTITY$LIVING = REGISTER.registerHolder("zone_entity/living", () -> new ActionRegistryEntry( - HexPattern.fromAngles("qqqqqwdeddwd", HexDir.SOUTH_EAST), new OpGetEntitiesBy(OpGetEntitiesBy::isLiving, false) + HexPattern.fromAngleString("qqqqqwdeddwd", HexDir.SOUTH_EAST), new OpGetEntitiesBy(OpGetEntitiesBy::isLiving, false) )); public static final Holder ZONE_ENTITY$NOT_LIVING = REGISTER.registerHolder("zone_entity/not_living", () -> new ActionRegistryEntry( - HexPattern.fromAngles("eeeeewaqaawd", HexDir.NORTH_EAST), new OpGetEntitiesBy(OpGetEntitiesBy::isLiving, + HexPattern.fromAngleString("eeeeewaqaawd", HexDir.NORTH_EAST), new OpGetEntitiesBy(OpGetEntitiesBy::isLiving, true) )); // == Types == public static final Holder COMPARE_BLOCK = REGISTER.registerHolder("compare_block/lenient", () -> new ActionRegistryEntry( - HexPattern.fromAngles("qqqqqeqeeeee", HexDir.NORTH_WEST), new OpBlockEquality(false) + HexPattern.fromAngleString("qqqqqeqeeeee", HexDir.NORTH_WEST), new OpBlockEquality(false) )); public static final Holder COMPARE_BLOCK_STRICT = REGISTER.registerHolder("compare_block/strict", () -> new ActionRegistryEntry( - HexPattern.fromAngles("qwawqwadadwewdwe", HexDir.NORTH_WEST), new OpBlockEquality(true) + HexPattern.fromAngleString("qwawqwadadwewdwe", HexDir.NORTH_WEST), new OpBlockEquality(true) )); public static final Holder COMPARE_ENTITY = REGISTER.registerHolder("compare_entity", () -> new ActionRegistryEntry( - HexPattern.fromAngles("aqaeqded", HexDir.NORTH_WEST), OpEntityEquality.INSTANCE + HexPattern.fromAngleString("aqaeqded", HexDir.NORTH_WEST), OpEntityEquality.INSTANCE )); public static final Holder COMPARE_ITEM = REGISTER.registerHolder("compare_item/lenient", () -> new ActionRegistryEntry( - HexPattern.fromAngles("qaeaqeqedqde", HexDir.NORTH_WEST), new OpItemEquality(false) + HexPattern.fromAngleString("qaeaqeqedqde", HexDir.NORTH_WEST), new OpItemEquality(false) )); public static final Holder COMPARE_ITEM_STRICT = REGISTER.registerHolder("compare_item/strict", () -> new ActionRegistryEntry( - HexPattern.fromAngles("qaeaqewqedqde", HexDir.NORTH_WEST), new OpItemEquality(true) + HexPattern.fromAngleString("qaeaqewqedqde", HexDir.NORTH_WEST), new OpItemEquality(true) )); // == Lists == public static final Holder APPEND = make("append", - new OperationAction(HexPattern.fromAngles("edqde", HexDir.SOUTH_WEST))); + new OperationAction(HexPattern.fromAngleString("edqde", HexDir.SOUTH_WEST))); public static final Holder UNAPPEND = make("unappend", - new OperationAction(HexPattern.fromAngles("qaeaq", HexDir.NORTH_WEST))); + new OperationAction(HexPattern.fromAngleString("qaeaq", HexDir.NORTH_WEST))); // public static final Holder CONCAT = REGISTER.registerHolder("concat", () -> // new ActionRegistryEntry(HexPattern.fromAngles("qaeaq", HexDir.NORTH_WEST), OpConcat.INSTANCE)); public static final Holder INDEX = make("index", - new OperationAction(HexPattern.fromAngles("deeed", HexDir.NORTH_WEST))); + new OperationAction(HexPattern.fromAngleString("deeed", HexDir.NORTH_WEST))); // public static final Holder LIST_SIZE = REGISTER.registerHolder("list_size", () -> // new ActionRegistryEntry(HexPattern.fromAngles("aqaeaq", HexDir.EAST), OpListSize.INSTANCE)); public static final Holder SINGLETON = REGISTER.registerHolder("singleton", () -> - new ActionRegistryEntry(HexPattern.fromAngles("adeeed", HexDir.EAST), OpSingleton.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("adeeed", HexDir.EAST), OpSingleton.INSTANCE)); public static final Holder EMPTY_LIST = REGISTER.registerHolder("empty_list", () -> - new ActionRegistryEntry(HexPattern.fromAngles("qqaeaae", HexDir.NORTH_EAST), OpEmptyList.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("qqaeaae", HexDir.NORTH_EAST), OpEmptyList.INSTANCE)); public static final Holder REVERSE = make("reverse", - new OperationAction(HexPattern.fromAngles("qqqaede", HexDir.EAST))); + new OperationAction(HexPattern.fromAngleString("qqqaede", HexDir.EAST))); public static final Holder LAST_N_LIST = REGISTER.registerHolder("last_n_list", () -> - new ActionRegistryEntry(HexPattern.fromAngles("ewdqdwe", HexDir.SOUTH_WEST), OpLastNToList.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("ewdqdwe", HexDir.SOUTH_WEST), OpLastNToList.INSTANCE)); public static final Holder SPLAT = REGISTER.registerHolder("splat", () -> - new ActionRegistryEntry(HexPattern.fromAngles("qwaeawq", HexDir.NORTH_WEST), OpSplat.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("qwaeawq", HexDir.NORTH_WEST), OpSplat.INSTANCE)); public static final Holder INDEX_OF = make("index_of", - new OperationAction(HexPattern.fromAngles("dedqde", HexDir.EAST))); + new OperationAction(HexPattern.fromAngleString("dedqde", HexDir.EAST))); public static final Holder REMOVE_FROM = make("remove_from", - new OperationAction(HexPattern.fromAngles("edqdewaqa", HexDir.SOUTH_WEST))); + new OperationAction(HexPattern.fromAngleString("edqdewaqa", HexDir.SOUTH_WEST))); public static final Holder SLICE = make("slice", - new OperationAction(HexPattern.fromAngles("qaeaqwded", HexDir.NORTH_WEST))); + new OperationAction(HexPattern.fromAngleString("qaeaqwded", HexDir.NORTH_WEST))); public static final Holder REPLACE = make("replace", - new OperationAction(HexPattern.fromAngles("wqaeaqw", HexDir.NORTH_WEST))); + new OperationAction(HexPattern.fromAngleString("wqaeaqw", HexDir.NORTH_WEST))); public static final Holder CONSTRUCT = make("construct", - new OperationAction(HexPattern.fromAngles("ddewedd", HexDir.SOUTH_EAST))); + new OperationAction(HexPattern.fromAngleString("ddewedd", HexDir.SOUTH_EAST))); public static final Holder DECONSTRUCT = make("deconstruct", - new OperationAction(HexPattern.fromAngles("aaqwqaa", HexDir.SOUTH_WEST))); + new OperationAction(HexPattern.fromAngleString("aaqwqaa", HexDir.SOUTH_WEST))); // Xplat interops static { if (PehkuiInterop.isActive()) { REGISTER.registerHolder("interop/pehkui/get", () -> - new ActionRegistryEntry(HexPattern.fromAngles("aawawwawwa", HexDir.NORTH_WEST), OpGetScale.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("aawawwawwa", HexDir.NORTH_WEST), OpGetScale.INSTANCE)); REGISTER.registerHolder("interop/pehkui/set", () -> - new ActionRegistryEntry(HexPattern.fromAngles("ddwdwwdwwd", HexDir.NORTH_EAST), OpSetScale.INSTANCE)); + new ActionRegistryEntry(HexPattern.fromAngleString("ddwdwwdwwd", HexDir.NORTH_EAST), OpSetScale.INSTANCE)); } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/loot/AddHexToAncientCypherFunc.java b/Common/src/main/java/at/petrak/hexcasting/common/loot/AddHexToAncientCypherFunc.java index f922ead847..da189ca3e1 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/loot/AddHexToAncientCypherFunc.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/loot/AddHexToAncientCypherFunc.java @@ -48,7 +48,7 @@ public static ItemStack doStatic(ItemStack stack, RandomSource rand) { stack.set(HexDataComponents.ITEM_VARIANT.get(), rand.nextInt(8)); stack.set(HexDataComponents.HEX_HOLDER_PATTERNS.get(), Arrays.stream(hex.getSecond()).map(el -> { var pieces = el.split(" "); - return new PatternIota(HexPattern.fromAngles(pieces[1],HexDir.fromString(pieces[0]))); + return new PatternIota(HexPattern.fromAngleString(pieces[1],HexDir.fromString(pieces[0]))); }).collect(Collectors.toList())); return stack; diff --git a/Common/src/main/java/at/petrak/hexcasting/interop/inline/HexPatternMatcher.java b/Common/src/main/java/at/petrak/hexcasting/interop/inline/HexPatternMatcher.java index 1ef462feaa..752e332897 100644 --- a/Common/src/main/java/at/petrak/hexcasting/interop/inline/HexPatternMatcher.java +++ b/Common/src/main/java/at/petrak/hexcasting/interop/inline/HexPatternMatcher.java @@ -53,7 +53,7 @@ public Tuple getMatchAndGroup(MatchResult regexMatch, Matc angleSigs = ""; } try{ - pat = HexPattern.fromAngles(angleSigs.toLowerCase(), dir, false); + pat = HexPattern.fromAngleString(angleSigs.toLowerCase(), dir, false); InlinePatternData patData = new InlinePatternData(pat); Style patDataStyle = patData.getExtraStyle(); if(sizeModString != null && sizeModString.equals("+")) diff --git a/Common/src/main/java/at/petrak/hexcasting/interop/patchouli/ManualPatternComponent.java b/Common/src/main/java/at/petrak/hexcasting/interop/patchouli/ManualPatternComponent.java index dd6431edd7..456f128f87 100644 --- a/Common/src/main/java/at/petrak/hexcasting/interop/patchouli/ManualPatternComponent.java +++ b/Common/src/main/java/at/petrak/hexcasting/interop/patchouli/ManualPatternComponent.java @@ -35,7 +35,7 @@ public List getPatterns(UnaryOperator lookup) { RawPattern raw = new Gson().fromJson(json, RawPattern.class); var dir = HexDir.fromString(raw.startdir); - var pat = HexPattern.fromAngles(raw.signature, dir, false); + var pat = HexPattern.fromAngleString(raw.signature, dir, false); out.add(pat); }