diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/ActionUtils.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/ActionUtils.kt index c6dda37c9a..4d4d7393ac 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/ActionUtils.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/ActionUtils.kt @@ -6,6 +6,7 @@ import at.petrak.hexcasting.api.casting.iota.* import at.petrak.hexcasting.api.casting.math.HexPattern import at.petrak.hexcasting.api.casting.mishaps.MishapInvalidIota import at.petrak.hexcasting.api.casting.mishaps.MishapNotEnoughArgs +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.api.utils.asTranslatedComponent import com.mojang.datafixers.util.Either import net.minecraft.core.BlockPos @@ -22,7 +23,7 @@ import kotlin.math.abs import kotlin.math.roundToInt import kotlin.math.roundToLong -fun List.getDouble(idx: Int, argc: Int = 0): Double { +fun Vector.getDouble(idx: Int, argc: Int = 0): Double { val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) } if (x is DoubleIota) { return x.double @@ -32,7 +33,7 @@ fun List.getDouble(idx: Int, argc: Int = 0): Double { } } -fun List.getEntity(idx: Int, argc: Int = 0): Entity { +fun Vector.getEntity(idx: Int, argc: Int = 0): Entity { val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) } if (x is EntityIota) { return x.entity @@ -41,7 +42,7 @@ fun List.getEntity(idx: Int, argc: Int = 0): Entity { } } -fun List.getList(idx: Int, argc: Int = 0): SpellList { +fun Vector.getList(idx: Int, argc: Int = 0): Vector { val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) } if (x is ListIota) { return x.list @@ -50,7 +51,7 @@ fun List.getList(idx: Int, argc: Int = 0): SpellList { } } -fun List.getPattern(idx: Int, argc: Int = 0): HexPattern { +fun Vector.getPattern(idx: Int, argc: Int = 0): HexPattern { val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) } if (x is PatternIota) { return x.pattern @@ -59,7 +60,7 @@ fun List.getPattern(idx: Int, argc: Int = 0): HexPattern { } } -fun List.getVec3(idx: Int, argc: Int = 0): Vec3 { +fun Vector.getVec3(idx: Int, argc: Int = 0): Vec3 { val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) } if (x is Vec3Iota) { return x.vec3 @@ -68,7 +69,7 @@ fun List.getVec3(idx: Int, argc: Int = 0): Vec3 { } } -fun List.getBool(idx: Int, argc: Int = 0): Boolean { +fun Vector.getBool(idx: Int, argc: Int = 0): Boolean { val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) } if (x is BooleanIota) { return x.bool @@ -79,7 +80,7 @@ fun List.getBool(idx: Int, argc: Int = 0): Boolean { // Helpers -fun List.getItemEntity(idx: Int, argc: Int = 0): ItemEntity { +fun Vector.getItemEntity(idx: Int, argc: Int = 0): ItemEntity { val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) } if (x is EntityIota) { val e = x.entity @@ -89,7 +90,7 @@ fun List.getItemEntity(idx: Int, argc: Int = 0): ItemEntity { throw MishapInvalidIota.ofType(x, if (argc == 0) idx else argc - (idx + 1), "entity.item") } -fun List.getPlayer(idx: Int, argc: Int = 0): ServerPlayer { +fun Vector.getPlayer(idx: Int, argc: Int = 0): ServerPlayer { val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) } if (x is EntityIota) { val e = x.entity @@ -99,7 +100,7 @@ fun List.getPlayer(idx: Int, argc: Int = 0): ServerPlayer { throw MishapInvalidIota.ofType(x, if (argc == 0) idx else argc - (idx + 1), "entity.player") } -fun List.getMob(idx: Int, argc: Int = 0): Mob { +fun Vector.getMob(idx: Int, argc: Int = 0): Mob { val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) } if (x is EntityIota) { val e = x.entity @@ -109,7 +110,7 @@ fun List.getMob(idx: Int, argc: Int = 0): Mob { throw MishapInvalidIota.ofType(x, if (argc == 0) idx else argc - (idx + 1), "entity.mob") } -fun List.getLivingEntityButNotArmorStand(idx: Int, argc: Int = 0): LivingEntity { +fun Vector.getLivingEntityButNotArmorStand(idx: Int, argc: Int = 0): LivingEntity { val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) } if (x is EntityIota) { val e = x.entity @@ -119,7 +120,7 @@ fun List.getLivingEntityButNotArmorStand(idx: Int, argc: Int = 0): LivingE throw MishapInvalidIota.ofType(x, if (argc == 0) idx else argc - (idx + 1), "entity.living") } -fun List.getPositiveDouble(idx: Int, argc: Int = 0): Double { +fun Vector.getPositiveDouble(idx: Int, argc: Int = 0): Double { val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) } if (x is DoubleIota) { val double = x.double @@ -130,7 +131,7 @@ fun List.getPositiveDouble(idx: Int, argc: Int = 0): Double { throw MishapInvalidIota.of(x, if (argc == 0) idx else argc - (idx + 1), "double.positive") } -fun List.getPositiveDoubleUnder(idx: Int, max: Double, argc: Int = 0): Double { +fun Vector.getPositiveDoubleUnder(idx: Int, max: Double, argc: Int = 0): Double { val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) } if (x is DoubleIota) { val double = x.double @@ -141,7 +142,7 @@ fun List.getPositiveDoubleUnder(idx: Int, max: Double, argc: Int = 0): Dou throw MishapInvalidIota.of(x, if (argc == 0) idx else argc - (idx + 1), "double.positive.less", max) } -fun List.getPositiveDoubleUnderInclusive(idx: Int, max: Double, argc: Int = 0): Double { +fun Vector.getPositiveDoubleUnderInclusive(idx: Int, max: Double, argc: Int = 0): Double { val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) } if (x is DoubleIota) { val double = x.double @@ -152,7 +153,7 @@ fun List.getPositiveDoubleUnderInclusive(idx: Int, max: Double, argc: Int throw MishapInvalidIota.of(x, if (argc == 0) idx else argc - (idx + 1), "double.positive.less.equal", max) } -fun List.getDoubleBetween(idx: Int, min: Double, max: Double, argc: Int = 0): Double { +fun Vector.getDoubleBetween(idx: Int, min: Double, max: Double, argc: Int = 0): Double { val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) } if (x is DoubleIota) { val double = x.double @@ -163,7 +164,7 @@ fun List.getDoubleBetween(idx: Int, min: Double, max: Double, argc: Int = throw MishapInvalidIota.of(x, if (argc == 0) idx else argc - (idx + 1), "double.between", min, max) } -fun List.getInt(idx: Int, argc: Int = 0): Int { +fun Vector.getInt(idx: Int, argc: Int = 0): Int { val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) } if (x is DoubleIota) { val double = x.double @@ -175,7 +176,7 @@ fun List.getInt(idx: Int, argc: Int = 0): Int { throw MishapInvalidIota.of(x, if (argc == 0) idx else argc - (idx + 1), "int") } -fun List.getLong(idx: Int, argc: Int = 0): Long { +fun Vector.getLong(idx: Int, argc: Int = 0): Long { val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) } if (x is DoubleIota) { val double = x.double @@ -187,7 +188,7 @@ fun List.getLong(idx: Int, argc: Int = 0): Long { throw MishapInvalidIota.of(x, if (argc == 0) idx else argc - (idx + 1), "int") // shh we're lying } -fun List.getPositiveInt(idx: Int, argc: Int = 0): Int { +fun Vector.getPositiveInt(idx: Int, argc: Int = 0): Int { val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) } if (x is DoubleIota) { val double = x.double @@ -199,7 +200,7 @@ fun List.getPositiveInt(idx: Int, argc: Int = 0): Int { throw MishapInvalidIota.of(x, if (argc == 0) idx else argc - (idx + 1), "int.positive") } -fun List.getPositiveLong(idx: Int, argc: Int = 0): Long { +fun Vector.getPositiveLong(idx: Int, argc: Int = 0): Long { val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) } if (x is DoubleIota) { val double = x.double @@ -211,7 +212,7 @@ fun List.getPositiveLong(idx: Int, argc: Int = 0): Long { throw MishapInvalidIota.of(x, if (argc == 0) idx else argc - (idx + 1), "int.positive") } -fun List.getPositiveIntUnder(idx: Int, max: Int, argc: Int = 0): Int { +fun Vector.getPositiveIntUnder(idx: Int, max: Int, argc: Int = 0): Int { val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) } if (x is DoubleIota) { val double = x.double @@ -223,7 +224,7 @@ fun List.getPositiveIntUnder(idx: Int, max: Int, argc: Int = 0): Int { throw MishapInvalidIota.of(x, if (argc == 0) idx else argc - (idx + 1), "int.positive.less", max) } -fun List.getPositiveIntUnderInclusive(idx: Int, max: Int, argc: Int = 0): Int { +fun Vector.getPositiveIntUnderInclusive(idx: Int, max: Int, argc: Int = 0): Int { val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) } if (x is DoubleIota) { val double = x.double @@ -235,7 +236,7 @@ fun List.getPositiveIntUnderInclusive(idx: Int, max: Int, argc: Int = 0): throw MishapInvalidIota.of(x, if (argc == 0) idx else argc - (idx + 1), "int.positive.less.equal", max) } -fun List.getIntBetween(idx: Int, min: Int, max: Int, argc: Int = 0): Int { +fun Vector.getIntBetween(idx: Int, min: Int, max: Int, argc: Int = 0): Int { val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) } if (x is DoubleIota) { val double = x.double @@ -247,7 +248,7 @@ fun List.getIntBetween(idx: Int, min: Int, max: Int, argc: Int = 0): Int { throw MishapInvalidIota.of(x, if (argc == 0) idx else argc - (idx + 1), "int.between", min, max) } -fun List.getBlockPos(idx: Int, argc: Int = 0): BlockPos { +fun Vector.getBlockPos(idx: Int, argc: Int = 0): BlockPos { val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) } if (x is Vec3Iota) { return BlockPos.containing(x.vec3) @@ -256,7 +257,7 @@ fun List.getBlockPos(idx: Int, argc: Int = 0): BlockPos { throw MishapInvalidIota.ofType(x, if (argc == 0) idx else argc - (idx + 1), "vector") } -fun List.getNumOrVec(idx: Int, argc: Int = 0): Either { +fun Vector.getNumOrVec(idx: Int, argc: Int = 0): Either { val datum = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) } return when (datum) { is DoubleIota -> Either.left(datum.double) @@ -269,7 +270,7 @@ fun List.getNumOrVec(idx: Int, argc: Int = 0): Either { } } -fun List.getLongOrList(idx: Int, argc: Int = 0): Either { +fun Vector.getLongOrList(idx: Int, argc: Int = 0): Either> { val datum = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) } if (datum is DoubleIota) { val double = datum.double @@ -287,7 +288,7 @@ fun List.getLongOrList(idx: Int, argc: Int = 0): Either { ) } -fun evaluatable(datum: Iota, reverseIdx: Int): Either = +fun evaluatable(datum: Iota, reverseIdx: Int): Either> = when (datum) { is ListIota -> Either.right(datum.list) else -> if (datum.executable()) Either.left(datum) else throw MishapInvalidIota( @@ -308,16 +309,15 @@ fun aplKinnie(operatee: Either, fn: DoubleUnaryOperator): Iota = { vec -> Vec3Iota(Vec3(fn.applyAsDouble(vec.x), fn.applyAsDouble(vec.y), fn.applyAsDouble(vec.z))) } ) -inline val Boolean.asActionResult get() = listOf(BooleanIota(this)) -inline val Double.asActionResult get() = listOf(DoubleIota(this)) -inline val Number.asActionResult get() = listOf(DoubleIota(this.toDouble())) +inline val Boolean.asActionResult: Vector get() = Vector.from(listOf(BooleanIota(this))) +inline val Double.asActionResult: Vector get() = Vector.from(listOf(DoubleIota(this))) +inline val Number.asActionResult: Vector get() = Vector.from(listOf(DoubleIota(this.toDouble()))) -inline val SpellList.asActionResult get() = listOf(ListIota(this)) -inline val List.asActionResult get() = listOf(ListIota(this)) +inline val Vector.asActionResult: Vector get() = Vector.from(listOf(ListIota(this))) -inline val BlockPos.asActionResult get() = listOf(Vec3Iota(Vec3.atCenterOf(this))) -inline val Vector3f.asActionResult get() = listOf(Vec3Iota(Vec3(this))) -inline val Vec3.asActionResult get() = listOf(Vec3Iota(this)) +inline val BlockPos.asActionResult: Vector get() = Vector.from(listOf(Vec3Iota(Vec3.atCenterOf(this)))) +inline val Vector3f.asActionResult: Vector get() = Vector.from(listOf(Vec3Iota(Vec3(this)))) +inline val Vec3.asActionResult: Vector get() = Vector.from(listOf(Vec3Iota(this))) -inline val Entity?.asActionResult get() = listOf(if (this == null) NullIota() else EntityIota(this)) -inline val HexPattern.asActionResult get() = listOf(PatternIota(this)) +inline val Entity?.asActionResult: Vector get() = Vector.from(listOf(if (this == null) NullIota() else EntityIota(this))) +inline val HexPattern.asActionResult: Vector get() = Vector.from(listOf(PatternIota(this))) diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/SpellList.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/SpellList.kt deleted file mode 100644 index 2e76c18c76..0000000000 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/SpellList.kt +++ /dev/null @@ -1,93 +0,0 @@ -package at.petrak.hexcasting.api.casting - -import at.petrak.hexcasting.api.casting.iota.Iota - -/** - * Restricted interface for functional lists. - * - * ...Surely this won't have any performance implications. - */ -sealed class SpellList : Iterable { - - abstract val nonEmpty: Boolean - abstract val car: Iota - abstract val cdr: SpellList - - class LPair(override val car: Iota, override val cdr: SpellList) : SpellList() { - override val nonEmpty = true - } - - class LList(val idx: Int, val list: List) : SpellList() { - override val nonEmpty: Boolean - get() = idx < list.size - override val car: Iota - get() = list[idx] - override val cdr: SpellList - get() = LList(idx + 1, list) - - constructor(list: List) : this(0, list) - } - - fun modifyAt(startIdx: Int, modify: (SpellList) -> SpellList): SpellList { - val stack = mutableListOf() - val ptr = iterator() - var idx = startIdx - if (idx < 0) { - return this - } - while (idx > 0) { - if (!ptr.hasNext()) { - return this - } - idx-- - stack.add(ptr.next()) - } - var value = modify(ptr.list) - for (datum in stack.asReversed()) { - value = LPair(datum, value) - } - return value - } - - fun getAt(startIdx: Int): Iota { - var ptr = this - var idx = startIdx - if (idx < 0) { - throw ArrayIndexOutOfBoundsException() - } - while (idx > 0) { - when (ptr) { - is LPair -> ptr = ptr.cdr - is LList -> return ptr.list[ptr.idx + idx] - } - idx-- - } - return ptr.car - } - - override fun toString() = toList().toString() - - override fun iterator() = SpellListIterator(this) - - /** - * Note this is O(n), probably. - */ - fun size(): Int { - var size = 0 - var ptr = this - while (ptr.nonEmpty) { - ptr = ptr.cdr - size++ - } - return size - } - - class SpellListIterator(var list: SpellList) : Iterator { - override fun hasNext() = list.nonEmpty - override operator fun next(): Iota { - val car = list.car - list = list.cdr - return car - } - } -} diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/operator/OperatorBasic.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/operator/OperatorBasic.kt index 1d43c890ce..9c10684313 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/operator/OperatorBasic.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/operator/OperatorBasic.kt @@ -7,6 +7,7 @@ import at.petrak.hexcasting.api.casting.eval.vm.CastingImage import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.mishaps.Mishap +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.common.lib.hex.HexEvalSounds import java.util.function.Consumer @@ -14,14 +15,14 @@ abstract class OperatorBasic(arity: Int, accepts: IotaMultiPredicate) : Operator @Throws(Mishap::class) override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult { - val stack = image.stack.toMutableList() - val args = stack.takeLast(arity) - repeat(arity) { stack.removeLast() } + val stack = Vector.VectorBuilder() + stack.addAll(image.stack.dropRight(arity)) + val args = image.stack.takeRight(arity) val ret = apply(args, env) - ret.forEach(Consumer { e: Iota -> stack.add(e) }) + ret.forEach(Consumer { e: Iota -> stack.addOne(e) }) - val image2 = image.copy(stack = stack, opsConsumed = image.opsConsumed + 1) + val image2 = image.copy(stack = stack.result(), opsConsumed = image.opsConsumed + 1) return OperationResult(image2, listOf(), continuation, HexEvalSounds.NORMAL_EXECUTE) } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/Action.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/Action.kt index e60ff2dfe3..fc1bc30fc1 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/Action.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/Action.kt @@ -5,6 +5,7 @@ import at.petrak.hexcasting.api.casting.eval.OperationResult import at.petrak.hexcasting.api.casting.eval.vm.CastingImage import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector import net.minecraft.world.phys.Vec3 import java.text.DecimalFormat @@ -54,8 +55,8 @@ interface Action { override val argc: Int get() = 0 - override fun execute(args: List, env: CastingEnvironment): List = - listOf(x) + override fun execute(args: Vector, env: CastingEnvironment): Vector = + Vector.from(listOf(x)) } public val DOUBLE_FORMATTER = DecimalFormat("####.####") diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/ConstMediaAction.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/ConstMediaAction.kt index 276ee73122..ccf6301c26 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/ConstMediaAction.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/ConstMediaAction.kt @@ -8,6 +8,7 @@ import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.mishaps.MishapNotEnoughArgs import at.petrak.hexcasting.api.casting.mishaps.MishapNotEnoughMedia +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.common.lib.hex.HexEvalSounds /** @@ -18,30 +19,30 @@ interface ConstMediaAction : Action { val mediaCost: Long get() = 0 - fun execute(args: List, env: CastingEnvironment): List + fun execute(args: Vector, env: CastingEnvironment): Vector - fun executeWithOpCount(args: List, env: CastingEnvironment): CostMediaActionResult { + fun executeWithOpCount(args: Vector, env: CastingEnvironment): CostMediaActionResult { val stack = this.execute(args, env) return CostMediaActionResult(stack) } override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult { - val stack = image.stack.toMutableList() + val stack = Vector.VectorBuilder() if (env.extractMedia(this.mediaCost, true) > 0) throw MishapNotEnoughMedia(this.mediaCost) - if (this.argc > stack.size) - throw MishapNotEnoughArgs(this.argc, stack.size) - val args = stack.takeLast(this.argc) - repeat(this.argc) { stack.removeLast() } + if (this.argc > image.stack.size) + throw MishapNotEnoughArgs(this.argc, image.stack.size) + val args = image.stack.takeRight(this.argc) + stack.addAll(image.stack.dropRight(this.argc)) val result = this.executeWithOpCount(args, env) stack.addAll(result.resultStack) val sideEffects = mutableListOf(OperatorSideEffect.ConsumeMedia(this.mediaCost)) - val image2 = image.copy(stack = stack, opsConsumed = image.opsConsumed + result.opCount) + val image2 = image.copy(stack = stack.result(), opsConsumed = image.opsConsumed + result.opCount) return OperationResult(image2, sideEffects, continuation, HexEvalSounds.NORMAL_EXECUTE) } - data class CostMediaActionResult(val resultStack: List, val opCount: Long = 1) + data class CostMediaActionResult(val resultStack: Vector, val opCount: Long = 1) } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/SpellAction.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/SpellAction.kt index fcf17d08d0..634c25a388 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/SpellAction.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/SpellAction.kt @@ -10,6 +10,7 @@ import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.mishaps.MishapNotEnoughArgs import at.petrak.hexcasting.api.casting.mishaps.MishapNotEnoughMedia +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.common.lib.hex.HexEvalSounds import net.minecraft.nbt.CompoundTag @@ -21,23 +22,23 @@ interface SpellAction : Action { fun awardsCastingStat(ctx: CastingEnvironment): Boolean = true fun execute( - args: List, + args: Vector, env: CastingEnvironment ): Result fun executeWithUserdata( - args: List, env: CastingEnvironment, userData: CompoundTag + args: Vector, env: CastingEnvironment, userData: CompoundTag ): Result { return this.execute(args, env) } override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult { - val stack = image.stack.toMutableList() + val stack = Vector.VectorBuilder() - if (this.argc > stack.size) - throw MishapNotEnoughArgs(this.argc, stack.size) - val args = stack.takeLast(this.argc) - for (_i in 0 until this.argc) stack.removeLast() + if (this.argc > image.stack.size) + throw MishapNotEnoughArgs(this.argc, image.stack.size) + val args = image.stack.takeRight(this.argc) + stack.addAll(image.stack.dropRight(this.argc)) // execute! val userDataMut = image.userData.copy() @@ -61,7 +62,7 @@ interface SpellAction : Action { for (spray in result.particles) sideEffects.add(OperatorSideEffect.Particles(spray)) - val image2 = image.copy(stack = stack, opsConsumed = image.opsConsumed + result.opCount, userData = userDataMut) + val image2 = image.copy(stack = stack.result(), opsConsumed = image.opsConsumed + result.opCount, userData = userDataMut) val sound = if (this.hasCastingSound(env)) HexEvalSounds.SPELL else HexEvalSounds.MUTE return OperationResult(image2, sideEffects, continuation, sound) diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/sideeffects/OperatorSideEffect.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/sideeffects/OperatorSideEffect.kt index 72226fe291..c7011636da 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/sideeffects/OperatorSideEffect.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/sideeffects/OperatorSideEffect.kt @@ -66,7 +66,7 @@ sealed class OperatorSideEffect { ) ) - harness.image = harness.image.copy(stack = mishap.executeReturnStack(harness.env, errorCtx, harness.image.stack.toMutableList())) + harness.image = harness.image.copy(stack = mishap.executeReturnStack(harness.env, errorCtx, harness.image.stack)) } } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/CastingImage.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/CastingImage.kt index 3ffd771bcd..99f603f212 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/CastingImage.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/CastingImage.kt @@ -17,16 +17,16 @@ import net.minecraft.world.entity.Entity * The state of a casting VM, containing the stack and all */ data class CastingImage private constructor( - val stack: List, + val stack: Vector, val parenCount: Int, - val parenthesized: List, + val parenthesized: Vector, val escapeNext: Boolean, val opsConsumed: Long, val userData: CompoundTag ) { - constructor() : this(listOf(), 0, listOf(), false, 0, CompoundTag()) + constructor() : this(Vector.empty(), 0, Vector.empty(), false, 0, CompoundTag()) data class ParenthesizedIota(val iota: Iota, val escaped: Boolean) { companion object { @@ -38,14 +38,14 @@ data class CastingImage private constructor( /** * Returns an empty list if it's too complicated. */ - private fun Iterable.serializeToNBT(): CompoundTag { + private fun Vector.serializeToNBT(): CompoundTag { val tag = CompoundTag() if (IotaType.isTooLargeToSerialize(this.map { it.iota })) { tag.put(TAG_IOTAS, ListTag()) tag.put(TAG_ESCAPED, ListTag()) } else { - tag.put(TAG_IOTAS, ListIota(this.map { it.iota }).serialize()) + tag.put(TAG_IOTAS, ListIota(Vector.from(this).map { it.iota }).serialize()) tag.put(TAG_ESCAPED, this.map { it.escaped }.serializeToNBT()) } @@ -70,7 +70,7 @@ data class CastingImage private constructor( /** * Returns a copy of this with escape/paren-related fields cleared. */ - fun withResetEscape() = this.copy(parenCount = 0, parenthesized = listOf(), escapeNext = false) + fun withResetEscape() = this.copy(parenCount = 0, parenthesized = Vector.empty(), escapeNext = false) fun serializeToNbt() = NBTBuilder { TAG_STACK %= stack.serializeToNBT() @@ -94,11 +94,11 @@ data class CastingImage private constructor( @JvmStatic fun loadFromNbt(tag: CompoundTag, world: ServerLevel): CastingImage { return try { - val stack = mutableListOf() + val stack = Vector.VectorBuilder() val stackTag = tag.getList(TAG_STACK, Tag.TAG_COMPOUND) for (subtag in stackTag) { val datum = IotaType.deserialize(subtag.asCompound, world) - stack.add(datum) + stack.addOne(datum) } val userData = if (tag.contains(TAG_USERDATA)) { @@ -107,20 +107,20 @@ data class CastingImage private constructor( CompoundTag() } - val parenthesized = mutableListOf() + val parenthesized = Vector.VectorBuilder() val parenTag = tag.getCompound(TAG_PARENTHESIZED) val parenIotasTag = parenTag.getList(TAG_IOTAS, Tag.TAG_COMPOUND) val parenEscapedTag = parenTag.getByteArray(TAG_ESCAPED) for ((subtag, isEscapedByte) in parenIotasTag.zipWithDefault(parenEscapedTag) { _ -> 0 }) { - parenthesized.add(ParenthesizedIota(IotaType.deserialize(subtag.downcast(CompoundTag.TYPE), world), isEscapedByte != 0.toByte())) + parenthesized.addOne(ParenthesizedIota(IotaType.deserialize(subtag.downcast(CompoundTag.TYPE), world), isEscapedByte != 0.toByte())) } val parenCount = tag.getInt(TAG_PAREN_COUNT) val escapeNext = tag.getBoolean(TAG_ESCAPE_NEXT) val opsUsed = tag.getLong(TAG_OPS_CONSUMED) - CastingImage(stack, parenCount, parenthesized, escapeNext, opsUsed, userData) + CastingImage(stack.result(), parenCount, parenthesized.result(), escapeNext, opsUsed, userData) } catch (exn: Exception) { HexAPI.LOGGER.warn("error while loading a CastingImage", exn) CastingImage() 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 11503b0b6f..e0b10c3a88 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 @@ -2,7 +2,6 @@ package at.petrak.hexcasting.api.casting.eval.vm import at.petrak.hexcasting.api.HexAPI import at.petrak.hexcasting.api.casting.PatternShapeMatch.* -import at.petrak.hexcasting.api.casting.SpellList import at.petrak.hexcasting.api.casting.eval.* import at.petrak.hexcasting.api.casting.eval.sideeffects.OperatorSideEffect import at.petrak.hexcasting.api.casting.eval.vm.CastingImage.ParenthesizedIota @@ -30,7 +29,7 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) { /** * Execute a single iota. */ - fun queueExecuteAndWrapIota(iota: Iota, world: ServerLevel): ExecutionClientView = queueExecuteAndWrapIotas(listOf(iota), world) + fun queueExecuteAndWrapIota(iota: Iota, world: ServerLevel): ExecutionClientView = queueExecuteAndWrapIotas(Vector.from(listOf(iota)), world) /** * The main entrypoint to the VM. Given a list of iotas, execute them in sequence, and return whatever the client @@ -38,9 +37,9 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) { * * Mutates this */ - fun queueExecuteAndWrapIotas(iotas: List, world: ServerLevel): ExecutionClientView { + fun queueExecuteAndWrapIotas(iotas: Vector, world: ServerLevel): ExecutionClientView { // Initialize the continuation stack to a single top-level eval for all iotas. - var continuation = SpellContinuation.Done.pushFrame(FrameEvaluate(SpellList.LList(0, iotas), false)) + var continuation = SpellContinuation.Done.pushFrame(FrameEvaluate(iotas, false)) // Begin aggregating info val info = TempControllerInfo(earlyExit = false) var lastResolutionType = ResolvedPatternType.UNRESOLVED @@ -178,8 +177,7 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) { val out = if (displayDepth > 0) { if (this.image.escapeNext) { - val newParens = this.image.parenthesized.toMutableList() - newParens.add(ParenthesizedIota(iota, true)) + val newParens = this.image.parenthesized.appended(ParenthesizedIota(iota, true)) this.image.copy( escapeNext = false, parenthesized = newParens @@ -194,8 +192,8 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) { } SpecialPatterns.EVANITION.angles -> { - val newParens = this.image.parenthesized.toMutableList() - val last = newParens.removeLastOrNull() + val newParens = if (this.image.parenthesized.isEmpty()) Vector.empty() else this.image.parenthesized.init() + val last = if (this.image.parenthesized.isEmpty()) null else this.image.parenthesized.last() val newParenCount = this.image.parenCount + if (last == null || last.escaped || last.iota !is PatternIota) 0 else when (last.iota.pattern) { SpecialPatterns.INTROSPECTION -> -1 SpecialPatterns.RETROSPECTION -> 1 @@ -206,8 +204,7 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) { SpecialPatterns.INTROSPECTION.angles -> { // we have escaped the parens onto the stack; we just also record our count. - val newParens = this.image.parenthesized.toMutableList() - newParens.add(ParenthesizedIota(iota, false)) + val newParens = this.image.parenthesized.appended(ParenthesizedIota(iota, false)) this.image.copy( parenthesized = newParens, parenCount = this.image.parenCount + 1 @@ -218,20 +215,18 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) { val newParenCount = this.image.parenCount - 1 displayDepth-- if (newParenCount == 0) { - val newStack = this.image.stack.toMutableList() - newStack.add(ListIota(this.image.parenthesized.toList().map { it.iota })) + val newStack = this.image.stack.appended(ListIota(this.image.parenthesized.map { it.iota })) this.image.copy( stack = newStack, parenCount = newParenCount, - parenthesized = listOf() + parenthesized = Vector.empty() ) to ResolvedPatternType.EVALUATED } else if (newParenCount < 0) { throw MishapTooManyCloseParens() } else { // we have this situation: "(()" // we need to add the close paren - val newParens = this.image.parenthesized.toMutableList() - newParens.add(ParenthesizedIota(iota, false)) + val newParens = this.image.parenthesized.appended(ParenthesizedIota(iota, false)) this.image.copy( parenCount = newParenCount, parenthesized = newParens @@ -240,8 +235,7 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) { } else -> { - val newParens = this.image.parenthesized.toMutableList() - newParens.add(ParenthesizedIota(iota, false)) + val newParens = this.image.parenthesized.appended(ParenthesizedIota(iota, false)) this.image.copy( parenthesized = newParens ) to ResolvedPatternType.ESCAPED @@ -249,8 +243,7 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) { } } } else if (this.image.escapeNext) { - val newStack = this.image.stack.toMutableList() - newStack.add(iota) + val newStack = this.image.stack.appended(iota) this.image.copy( stack = newStack, escapeNext = false, diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/ContinuationFrame.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/ContinuationFrame.kt index 8000ec09aa..1226352fbd 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/ContinuationFrame.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/ContinuationFrame.kt @@ -1,8 +1,8 @@ package at.petrak.hexcasting.api.casting.eval.vm -import at.petrak.hexcasting.api.casting.SpellList import at.petrak.hexcasting.api.casting.eval.CastResult import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.common.lib.hex.HexContinuationTypes import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.Tag @@ -35,7 +35,7 @@ interface ContinuationFrame { * In other words, we should consume Evaluate frames until we hit a FinishEval or Thoth frame. * @return whether the break should stop here, alongside the new stack state (e.g. for finalizing a Thoth) */ - fun breakDownwards(stack: List): Pair> + fun breakDownwards(stack: Vector): Pair> /** * Serializes this frame. Used for things like delays, where we pause execution. @@ -60,10 +60,10 @@ interface ContinuationFrame { */ @JvmStatic fun fromNBT(tag: CompoundTag, world: ServerLevel): ContinuationFrame { - val type = getTypeFromTag(tag) ?: return FrameEvaluate(SpellList.LList(0, listOf()), false) + val type = getTypeFromTag(tag) ?: return FrameEvaluate(Vector.empty(), false) return (tag.get(HexContinuationTypes.KEY_DATA) as? CompoundTag)?.let { type.deserializeFromNBT(it, world) } - ?: FrameEvaluate(SpellList.LList(0, listOf()), false) + ?: FrameEvaluate(Vector.empty(), false) } /** diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FrameEvaluate.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FrameEvaluate.kt index 141148dfdc..ca8c28ee49 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FrameEvaluate.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FrameEvaluate.kt @@ -1,11 +1,11 @@ package at.petrak.hexcasting.api.casting.eval.vm -import at.petrak.hexcasting.api.casting.SpellList import at.petrak.hexcasting.api.casting.eval.CastResult import at.petrak.hexcasting.api.casting.eval.ResolvedPatternType import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.ListIota import at.petrak.hexcasting.api.utils.NBTBuilder +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.api.utils.getList import at.petrak.hexcasting.api.utils.serializeToNBT import at.petrak.hexcasting.common.lib.hex.HexEvalSounds @@ -19,9 +19,9 @@ import net.minecraft.server.level.ServerLevel * @property list the *remaining* list of patterns to be evaluated * @property isMetacasting only for sound effects, if this is being cast from a hermes / iris */ -data class FrameEvaluate(val list: SpellList, val isMetacasting: Boolean) : ContinuationFrame { +data class FrameEvaluate(val list: Vector, val isMetacasting: Boolean) : ContinuationFrame { // Discard this frame and keep discarding frames. - override fun breakDownwards(stack: List) = false to stack + override fun breakDownwards(stack: Vector) = false to stack // Step the list of patterns, evaluating a single one. override fun evaluate( @@ -30,13 +30,13 @@ data class FrameEvaluate(val list: SpellList, val isMetacasting: Boolean) : Cont harness: CastingVM ): CastResult { // If there are patterns left... - return if (list.nonEmpty) { - val newCont = if (list.cdr.nonEmpty) { // yay TCO + return if (!list.isEmpty()) { + val newCont = if (!list.tail().isEmpty()) { // yay TCO // ...enqueue the evaluation of the rest of the patterns... - continuation.pushFrame(FrameEvaluate(list.cdr, this.isMetacasting)) + continuation.pushFrame(FrameEvaluate(list.tail(), this.isMetacasting)) } else continuation // ...before evaluating the first one in the list. - val update = harness.executeInner(list.car, level, newCont) + val update = harness.executeInner(list.head(), level, newCont) if (this.isMetacasting && update.sound != HexEvalSounds.MISHAP) { update.copy(sound = HexEvalSounds.HERMES) } else { @@ -53,7 +53,7 @@ data class FrameEvaluate(val list: SpellList, val isMetacasting: Boolean) : Cont "isMetacasting" %= isMetacasting } - override fun size() = list.size() + override fun size() = list.size override val type: ContinuationFrame.Type<*> = TYPE diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FrameFinishEval.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FrameFinishEval.kt index 72bbb8c80c..ea468d5d99 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FrameFinishEval.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FrameFinishEval.kt @@ -5,6 +5,7 @@ import at.petrak.hexcasting.api.casting.eval.ResolvedPatternType import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.NullIota import at.petrak.hexcasting.api.utils.NBTBuilder +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.common.lib.hex.HexEvalSounds import net.minecraft.nbt.CompoundTag import net.minecraft.server.level.ServerLevel @@ -15,7 +16,7 @@ import net.minecraft.server.level.ServerLevel */ object FrameFinishEval : ContinuationFrame { // Don't do anything else to the stack, just finish the halt statement. - override fun breakDownwards(stack: List) = true to stack + override fun breakDownwards(stack: Vector) = true to stack // Evaluating it does nothing; it's only a boundary condition. override fun evaluate( diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FrameForEach.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FrameForEach.kt index 02d9612767..59b617963d 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FrameForEach.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FrameForEach.kt @@ -1,6 +1,5 @@ package at.petrak.hexcasting.api.casting.eval.vm -import at.petrak.hexcasting.api.casting.SpellList import at.petrak.hexcasting.api.casting.eval.CastResult import at.petrak.hexcasting.api.casting.eval.ResolvedPatternType import at.petrak.hexcasting.api.casting.iota.Iota @@ -9,6 +8,7 @@ import at.petrak.hexcasting.api.utils.NBTBuilder import at.petrak.hexcasting.api.utils.getList import at.petrak.hexcasting.api.utils.hasList import at.petrak.hexcasting.api.utils.serializeToNBT +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.common.lib.hex.HexEvalSounds import at.petrak.hexcasting.common.lib.hex.HexIotaTypes import net.minecraft.nbt.CompoundTag @@ -25,17 +25,15 @@ import net.minecraft.server.level.ServerLevel * @property acc concatenated list of final stack states after Thoth exit */ data class FrameForEach( - val data: SpellList, - val code: SpellList, - val baseStack: List?, - val acc: MutableList + val data: Vector, + val code: Vector, + val baseStack: Vector?, + val acc: Vector ) : ContinuationFrame { /** When halting, we add the stack state at halt to the stack accumulator, then return the original pre-Thoth stack, plus the accumulator. */ - override fun breakDownwards(stack: List): Pair> { - val newStack = baseStack?.toMutableList() ?: mutableListOf() - acc.addAll(stack) - newStack.add(ListIota(acc)) + override fun breakDownwards(stack: Vector): Pair> { + val newStack = stack.appendedAll(acc) return true to newStack } @@ -46,30 +44,28 @@ data class FrameForEach( harness: CastingVM ): CastResult { // If this isn't the very first Thoth step (i.e. no Thoth computations run yet)... - val stack = if (baseStack == null) { - // init stack to the VM stack... - harness.image.stack.toList() + val (stack, nextAcc) = if (baseStack == null) { + // init stack to the harness stack... + harness.image.stack to acc } else { // else save the stack to the accumulator and reuse the saved base stack. - acc.addAll(harness.image.stack) - baseStack + baseStack to acc.appendedAll(harness.image.stack) } // If we still have data to process... - val (stackTop, newImage, newCont) = if (data.nonEmpty) { + val (stackTop, newImage, newCont) = if (!data.isEmpty()) { // push the next datum to the top of the stack, val cont2 = continuation // put the next Thoth object back on the stack for the next Thoth cycle, - .pushFrame(FrameForEach(data.cdr, code, stack, acc)) + .pushFrame(FrameForEach(data.tail(), code, stack, nextAcc)) // and prep the Thoth'd code block for evaluation. .pushFrame(FrameEvaluate(code, true)) - Triple(data.car, harness.image.withUsedOp(), cont2) + Triple(data.head(), harness.image.withUsedOp(), cont2) } else { // Else, dump our final list onto the stack. - Triple(ListIota(acc), harness.image, continuation) + Triple(ListIota(nextAcc), harness.image, continuation) } - val tStack = stack.toMutableList() - tStack.add(stackTop) + val tStack = stack.appended(stackTop) return CastResult( ListIota(code), newCont, @@ -86,10 +82,10 @@ data class FrameForEach( "code" %= code.serializeToNBT() if (baseStack != null) "base" %= baseStack.serializeToNBT() - "accumulator" %= acc.serializeToNBT() + "accumulator" %= acc.toList().serializeToNBT() } - override fun size() = data.size() + code.size() + acc.size + (baseStack?.size ?: 0) + override fun size() = data.size + code.size + acc.size + (baseStack?.size ?: 0) override val type: ContinuationFrame.Type<*> = TYPE @@ -101,13 +97,13 @@ data class FrameForEach( HexIotaTypes.LIST.deserialize(tag.getList("data", Tag.TAG_COMPOUND), world)!!.list, HexIotaTypes.LIST.deserialize(tag.getList("code", Tag.TAG_COMPOUND), world)!!.list, if (tag.hasList("base", Tag.TAG_COMPOUND)) - HexIotaTypes.LIST.deserialize(tag.getList("base", Tag.TAG_COMPOUND), world)!!.list.toList() + HexIotaTypes.LIST.deserialize(tag.getList("base", Tag.TAG_COMPOUND), world)!!.list else null, HexIotaTypes.LIST.deserialize( tag.getList("accumulator", Tag.TAG_COMPOUND), world - )!!.list.toMutableList() + )!!.list ) } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/ListIota.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/ListIota.java index d3eb9455bf..e1859f0850 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/ListIota.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/ListIota.java @@ -1,7 +1,7 @@ package at.petrak.hexcasting.api.casting.iota; -import at.petrak.hexcasting.api.casting.SpellList; import at.petrak.hexcasting.api.utils.HexUtils; +import at.petrak.hexcasting.api.utils.Vector; import at.petrak.hexcasting.common.lib.hex.HexIotaTypes; import net.minecraft.ChatFormatting; import net.minecraft.nbt.CompoundTag; @@ -12,19 +12,18 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.List; +import java.util.Iterator; import static java.lang.Math.max; /** - * This is a wrapper for {@link SpellList}. + * This is a wrapper for {@link Vector}. */ public class ListIota extends Iota { private final int depth; private final int size; - public ListIota(@NotNull SpellList list) { + public ListIota(@NotNull Vector list) { super(HexIotaTypes.LIST, list); int maxChildDepth = 0; int totalSize = 1; @@ -36,17 +35,13 @@ public ListIota(@NotNull SpellList list) { size = totalSize; } - public ListIota(@NotNull List list) { - this(new SpellList.LList(list)); - } - - public SpellList getList() { - return (SpellList) this.payload; + public Vector getList() { + return (Vector) this.payload; } @Override public boolean isTruthy() { - return this.getList().getNonEmpty(); + return !this.getList().isEmpty(); } @Override @@ -60,7 +55,7 @@ public boolean toleratesOther(Iota that) { } var b = list.getList(); - SpellList.SpellListIterator aIter = a.iterator(), bIter = b.iterator(); + Iterator aIter = a.iterator(), bIter = b.iterator(); for (; ; ) { if (!aIter.hasNext() && !bIter.hasNext()) { // we ran out together! @@ -106,7 +101,7 @@ public int depth() { @Override public ListIota deserialize(Tag tag, ServerLevel world) throws IllegalArgumentException { var listTag = HexUtils.downcast(tag, ListTag.TYPE); - var out = new ArrayList(listTag.size()); + var out = new Vector.VectorBuilder(); for (var sub : listTag) { var csub = HexUtils.downcast(sub, CompoundTag.TYPE); @@ -114,10 +109,10 @@ public ListIota deserialize(Tag tag, ServerLevel world) throws IllegalArgumentEx if (subiota == null) { return null; } - out.add(subiota); + out.addOne(subiota); } - return new ListIota(out); + return new ListIota(out.result()); } @Override diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/Mishap.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/Mishap.kt index b9462fdda9..889f704b8f 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/Mishap.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/Mishap.kt @@ -6,6 +6,7 @@ import at.petrak.hexcasting.api.casting.eval.ResolvedPatternType import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.math.HexPattern import at.petrak.hexcasting.api.pigment.FrozenPigment +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.api.utils.asTranslatedComponent import at.petrak.hexcasting.api.utils.lightPurple import at.petrak.hexcasting.common.lib.HexItems @@ -32,19 +33,14 @@ abstract class Mishap : Throwable() { open fun resolutionType(ctx: CastingEnvironment): ResolvedPatternType = ResolvedPatternType.ERRORED + protected abstract fun errorMessage(ctx: CastingEnvironment, errorCtx: Context): Component? + /** * Execute the actual effect, not any sfx. * - * You can also mess up the stack with this. + * This returns a new stack. */ - abstract fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) - - protected abstract fun errorMessage(ctx: CastingEnvironment, errorCtx: Context): Component? - - fun executeReturnStack(ctx: CastingEnvironment, errorCtx: Context, stack: MutableList): List { - execute(ctx, errorCtx, stack) - return stack - } + abstract fun executeReturnStack(ctx: CastingEnvironment, errorCtx: Context, stack: Vector): Vector /** * Every error message should be prefixed with the name of the action... diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapAlreadyBrainswept.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapAlreadyBrainswept.kt index fcfe86b2d7..f08092e707 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapAlreadyBrainswept.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapAlreadyBrainswept.kt @@ -4,6 +4,7 @@ import at.petrak.hexcasting.api.casting.ParticleSpray import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.pigment.FrozenPigment +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.common.lib.HexDamageTypes import net.minecraft.world.entity.Mob import net.minecraft.world.item.DyeColor @@ -12,8 +13,9 @@ class MishapAlreadyBrainswept(val mob: Mob) : Mishap() { override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = dyeColor(DyeColor.GREEN) - override fun execute(ctx: CastingEnvironment, errorCtx: Context, stack: MutableList) { + override fun executeReturnStack(ctx: CastingEnvironment, errorCtx: Context, stack: Vector): Vector { mob.hurt(mob.damageSources().source(HexDamageTypes.OVERCAST, ctx.castingEntity), mob.health) + return stack } override fun particleSpray(ctx: CastingEnvironment) = diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadBlock.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadBlock.kt index b97a1b72f6..6e14b5757b 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadBlock.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadBlock.kt @@ -4,6 +4,7 @@ import at.petrak.hexcasting.api.casting.ParticleSpray import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.pigment.FrozenPigment +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.api.utils.asTranslatedComponent import net.minecraft.core.BlockPos import net.minecraft.network.chat.Component @@ -16,8 +17,9 @@ class MishapBadBlock(val pos: BlockPos, val expected: Component) : Mishap() { override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = dyeColor(DyeColor.LIME) - override fun execute(ctx: CastingEnvironment, errorCtx: Context, stack: MutableList) { + override fun executeReturnStack(ctx: CastingEnvironment, errorCtx: Context, stack: Vector): Vector { ctx.world.explode(null, pos.x + 0.5, pos.y + 0.5, pos.z + 0.5, 0.25f, Level.ExplosionInteraction.NONE) + return stack } override fun particleSpray(ctx: CastingEnvironment) = diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadBrainsweep.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadBrainsweep.kt index 601273fbb0..2443f4b669 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadBrainsweep.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadBrainsweep.kt @@ -4,6 +4,7 @@ import at.petrak.hexcasting.api.casting.ParticleSpray import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.pigment.FrozenPigment +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.common.lib.HexDamageTypes import net.minecraft.core.BlockPos import net.minecraft.world.entity.Mob @@ -14,8 +15,9 @@ class MishapBadBrainsweep(val mob: Mob, val pos: BlockPos) : Mishap() { override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = dyeColor(DyeColor.GREEN) - override fun execute(ctx: CastingEnvironment, errorCtx: Context, stack: MutableList) { + override fun executeReturnStack(ctx: CastingEnvironment, errorCtx: Context, stack: Vector): Vector { trulyHurt(mob, mob.damageSources().source(HexDamageTypes.OVERCAST, ctx.castingEntity), 1f) + return stack } override fun particleSpray(ctx: CastingEnvironment): ParticleSpray { diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadCaster.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadCaster.kt index 99199f9561..0f4347c20b 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadCaster.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadCaster.kt @@ -3,14 +3,15 @@ package at.petrak.hexcasting.api.casting.mishaps import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.pigment.FrozenPigment +import at.petrak.hexcasting.api.utils.Vector import net.minecraft.world.item.DyeColor class MishapBadCaster: Mishap() { override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = dyeColor(DyeColor.RED) - override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { - } + override fun executeReturnStack(env: CastingEnvironment, errorCtx: Context, stack: Vector) = + stack override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = error("bad_caster") diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadEntity.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadEntity.kt index 336a4fa18e..d92d11c6f8 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadEntity.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadEntity.kt @@ -3,6 +3,7 @@ package at.petrak.hexcasting.api.casting.mishaps import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.pigment.FrozenPigment +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.api.utils.aqua import at.petrak.hexcasting.api.utils.asTranslatedComponent import net.minecraft.network.chat.Component @@ -14,8 +15,9 @@ class MishapBadEntity(val entity: Entity, val wanted: Component) : Mishap() { override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = dyeColor(DyeColor.BROWN) - override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { + override fun executeReturnStack(env: CastingEnvironment, errorCtx: Context, stack: Vector): Vector { env.mishapEnvironment.yeetHeldItemsTowards(entity.position()) + return stack } override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadItem.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadItem.kt index d41cc88f32..6b93026311 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadItem.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadItem.kt @@ -3,6 +3,7 @@ package at.petrak.hexcasting.api.casting.mishaps import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.pigment.FrozenPigment +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.api.utils.asTranslatedComponent import net.minecraft.network.chat.Component import net.minecraft.world.entity.item.ItemEntity @@ -12,8 +13,9 @@ class MishapBadItem(val item: ItemEntity, val wanted: Component) : Mishap() { override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = dyeColor(DyeColor.BROWN) - override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { + override fun executeReturnStack(env: CastingEnvironment, errorCtx: Context, stack: Vector): Vector { item.deltaMovement = item.deltaMovement.add((Math.random() - 0.5) * 0.05, 0.75, (Math.random() - 0.5) * 0.05) + return stack } override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = if (item.item.isEmpty) diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadLocation.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadLocation.kt index 06955885a0..0d35903736 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadLocation.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadLocation.kt @@ -4,6 +4,7 @@ import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.Vec3Iota import at.petrak.hexcasting.api.pigment.FrozenPigment +import at.petrak.hexcasting.api.utils.Vector import net.minecraft.network.chat.Component import net.minecraft.world.item.DyeColor import net.minecraft.world.phys.Vec3 @@ -12,8 +13,9 @@ class MishapBadLocation(val location: Vec3, val type: String = "too_far") : Mish override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = dyeColor(DyeColor.MAGENTA) - override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { + override fun executeReturnStack(env: CastingEnvironment, errorCtx: Context, stack: Vector): Vector { env.mishapEnvironment.yeetHeldItemsTowards(this.location) + return stack } override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context): Component = diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadOffhandItem.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadOffhandItem.kt index d35104dab4..cf3db5c240 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadOffhandItem.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadOffhandItem.kt @@ -3,6 +3,7 @@ package at.petrak.hexcasting.api.casting.mishaps import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.pigment.FrozenPigment +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.api.utils.asTranslatedComponent import net.minecraft.network.chat.Component import net.minecraft.world.InteractionHand @@ -13,8 +14,9 @@ class MishapBadOffhandItem(val item: ItemStack?, val wanted: Component) : Mishap override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = dyeColor(DyeColor.BROWN) - override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { + override fun executeReturnStack(env: CastingEnvironment, errorCtx: Context, stack: Vector): Vector { env.mishapEnvironment.dropHeldItems() + return stack } override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = if (item?.isEmpty == false) diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapDisallowedSpell.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapDisallowedSpell.kt index d3118e5590..193d56f934 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapDisallowedSpell.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapDisallowedSpell.kt @@ -4,6 +4,7 @@ import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.eval.ResolvedPatternType import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.pigment.FrozenPigment +import at.petrak.hexcasting.api.utils.Vector import net.minecraft.world.item.DyeColor class MishapDisallowedSpell(val type: String = "disallowed") : Mishap() { @@ -12,9 +13,8 @@ class MishapDisallowedSpell(val type: String = "disallowed") : Mishap() { override fun resolutionType(ctx: CastingEnvironment) = ResolvedPatternType.INVALID - override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { - // NO-OP - } + override fun executeReturnStack(env: CastingEnvironment, errorCtx: Context, stack: Vector) = + stack override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = error(type) diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapDivideByZero.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapDivideByZero.kt index 98050ee244..b7f3b9fe5e 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapDivideByZero.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapDivideByZero.kt @@ -6,6 +6,7 @@ import at.petrak.hexcasting.api.casting.iota.GarbageIota import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.Vec3Iota import at.petrak.hexcasting.api.pigment.FrozenPigment +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.api.utils.asTranslatedComponent import net.minecraft.network.chat.Component import net.minecraft.world.item.DyeColor @@ -16,9 +17,9 @@ class MishapDivideByZero(val operand1: Component, val operand2: Component, val s override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = dyeColor(DyeColor.RED) - override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { - stack.add(GarbageIota()) + override fun executeReturnStack(env: CastingEnvironment, errorCtx: Context, stack: Vector): Vector { env.mishapEnvironment.damage(0.5f) + return stack.appended(GarbageIota()) } override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapEntityTooFarAway.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapEntityTooFarAway.kt index 41671a219c..e41bd91032 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapEntityTooFarAway.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapEntityTooFarAway.kt @@ -3,6 +3,7 @@ package at.petrak.hexcasting.api.casting.mishaps import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.pigment.FrozenPigment +import at.petrak.hexcasting.api.utils.Vector import net.minecraft.network.chat.Component import net.minecraft.world.entity.Entity import net.minecraft.world.item.DyeColor @@ -11,8 +12,9 @@ class MishapEntityTooFarAway(val entity: Entity) : Mishap() { override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = dyeColor(DyeColor.PINK) - override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { + override fun executeReturnStack(env: CastingEnvironment, errorCtx: Context, stack: Vector): Vector { env.mishapEnvironment.yeetHeldItemsTowards(entity.position()) + return stack } override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context): Component = diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapEvalTooMuch.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapEvalTooMuch.kt index 1634cd63e1..5d1b824d3e 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapEvalTooMuch.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapEvalTooMuch.kt @@ -3,14 +3,16 @@ package at.petrak.hexcasting.api.casting.mishaps import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.pigment.FrozenPigment +import at.petrak.hexcasting.api.utils.Vector import net.minecraft.world.item.DyeColor class MishapEvalTooMuch : Mishap() { override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = dyeColor(DyeColor.BLUE) - override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { + override fun executeReturnStack(env: CastingEnvironment, errorCtx: Context, stack: Vector): Vector { env.mishapEnvironment.drown() + return stack } override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapImmuneEntity.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapImmuneEntity.kt index a722efb2ec..02a69ceab2 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapImmuneEntity.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapImmuneEntity.kt @@ -3,6 +3,7 @@ package at.petrak.hexcasting.api.casting.mishaps import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.pigment.FrozenPigment +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.api.utils.aqua import net.minecraft.world.entity.Entity import net.minecraft.world.item.DyeColor @@ -11,8 +12,9 @@ class MishapImmuneEntity(val entity: Entity) : Mishap() { override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = dyeColor(DyeColor.BLUE) - override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { + override fun executeReturnStack(env: CastingEnvironment, errorCtx: Context, stack: Vector): Vector { env.mishapEnvironment.yeetHeldItemsTowards(entity.position()) + return stack } override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInternalException.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInternalException.kt index 7301c01127..110c6c4553 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInternalException.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInternalException.kt @@ -3,15 +3,15 @@ package at.petrak.hexcasting.api.casting.mishaps import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.pigment.FrozenPigment +import at.petrak.hexcasting.api.utils.Vector import net.minecraft.world.item.DyeColor class MishapInternalException(val exception: Exception) : Mishap() { override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = dyeColor(DyeColor.BLACK) - override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { - // NO-OP - } + override fun executeReturnStack(env: CastingEnvironment, errorCtx: Context, stack: Vector) = + stack override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = error("unknown", exception) diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidIota.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidIota.kt index 17e71d6044..49f0e2676a 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidIota.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidIota.kt @@ -4,6 +4,7 @@ import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.GarbageIota import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.pigment.FrozenPigment +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.api.utils.asTranslatedComponent import net.minecraft.network.chat.Component import net.minecraft.world.item.DyeColor @@ -19,9 +20,8 @@ class MishapInvalidIota( override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = dyeColor(DyeColor.GRAY) - override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { - stack[stack.size - 1 - reverseIdx] = GarbageIota(); - } + override fun executeReturnStack(env: CastingEnvironment, errorCtx: Context, stack: Vector): Vector = + stack.updated(stack.size - 1 - reverseIdx, GarbageIota()) override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = error( diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidOperatorArgs.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidOperatorArgs.kt index a16c083f4c..fea3847850 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidOperatorArgs.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidOperatorArgs.kt @@ -4,6 +4,7 @@ import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.GarbageIota import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.pigment.FrozenPigment +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.api.utils.asTextComponent import net.minecraft.network.chat.Component import net.minecraft.network.chat.ComponentUtils @@ -16,10 +17,12 @@ class MishapInvalidOperatorArgs(val perpetrators: List) : Mishap() { override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = dyeColor(DyeColor.GRAY) - override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { + override fun executeReturnStack(env: CastingEnvironment, errorCtx: Context, stack: Vector): Vector { + var acc = stack for (i in perpetrators.indices) { - stack[stack.size - 1 - i] = GarbageIota() + acc = acc.updated(stack.size - 1 - i, GarbageIota()) } + return acc } override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context): Component { diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidPattern.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidPattern.kt index 20fbd31fb5..a72349d593 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidPattern.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidPattern.kt @@ -5,6 +5,7 @@ import at.petrak.hexcasting.api.casting.eval.ResolvedPatternType import at.petrak.hexcasting.api.casting.iota.GarbageIota import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.pigment.FrozenPigment +import at.petrak.hexcasting.api.utils.Vector import net.minecraft.world.item.DyeColor class MishapInvalidPattern : Mishap() { @@ -13,9 +14,8 @@ class MishapInvalidPattern : Mishap() { override fun resolutionType(ctx: CastingEnvironment) = ResolvedPatternType.INVALID - override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { - stack.add(GarbageIota()) - } + override fun executeReturnStack(env: CastingEnvironment, errorCtx: Context, stack: Vector): Vector = + stack.appended(GarbageIota()) override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = error("invalid_pattern") diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidSpellDatumType.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidSpellDatumType.kt index 92384b0792..7c78862f34 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidSpellDatumType.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidSpellDatumType.kt @@ -3,6 +3,7 @@ package at.petrak.hexcasting.api.casting.mishaps import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.pigment.FrozenPigment +import at.petrak.hexcasting.api.utils.Vector import net.minecraft.world.item.DyeColor /** @@ -12,9 +13,8 @@ class MishapInvalidSpellDatumType(val perpetrator: Any) : Mishap() { override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = dyeColor(DyeColor.BLACK) - override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { - // NO-OP - } + override fun executeReturnStack(env: CastingEnvironment, errorCtx: Context, stack: Vector): Vector = + stack override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = error("invalid_spell_datum_type", this.perpetrator.toString(), this.perpetrator.javaClass.typeName) diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapLocationInWrongDimension.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapLocationInWrongDimension.kt index 2d0e721838..ca83017f8e 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapLocationInWrongDimension.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapLocationInWrongDimension.kt @@ -4,6 +4,7 @@ import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.GarbageIota import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.pigment.FrozenPigment +import at.petrak.hexcasting.api.utils.Vector import net.minecraft.network.chat.Component import net.minecraft.resources.ResourceLocation import net.minecraft.world.item.DyeColor @@ -12,9 +13,8 @@ class MishapLocationInWrongDimension(val properDimension: ResourceLocation) : Mi override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = dyeColor(DyeColor.MAGENTA) - override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { - stack.add(GarbageIota()) - } + override fun executeReturnStack(env: CastingEnvironment, errorCtx: Context, stack: Vector): Vector = + stack.appended(GarbageIota()) override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context): Component = error( diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapNoAkashicRecord.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapNoAkashicRecord.kt index 05eb6f5837..28aebaa3ae 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapNoAkashicRecord.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapNoAkashicRecord.kt @@ -3,6 +3,7 @@ package at.petrak.hexcasting.api.casting.mishaps import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.pigment.FrozenPigment +import at.petrak.hexcasting.api.utils.Vector import net.minecraft.core.BlockPos import net.minecraft.world.item.DyeColor @@ -10,8 +11,9 @@ class MishapNoAkashicRecord(val pos: BlockPos) : Mishap() { override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = dyeColor(DyeColor.PURPLE) - override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { + override fun executeReturnStack(env: CastingEnvironment, errorCtx: Context, stack: Vector): Vector { env.mishapEnvironment.removeXp(100) + return stack } override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapNotEnoughArgs.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapNotEnoughArgs.kt index 646f42c927..e8e0b8b031 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapNotEnoughArgs.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapNotEnoughArgs.kt @@ -4,14 +4,17 @@ import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.GarbageIota import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.pigment.FrozenPigment +import at.petrak.hexcasting.api.utils.Vector import net.minecraft.world.item.DyeColor class MishapNotEnoughArgs(val expected: Int, val got: Int) : Mishap() { override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = dyeColor(DyeColor.LIGHT_GRAY) - override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { - repeat(expected - got) { stack.add(GarbageIota()) } + override fun executeReturnStack(env: CastingEnvironment, errorCtx: Context, stack: Vector): Vector { + var acc = stack + repeat(expected - got) { acc = acc.appended(GarbageIota()) } + return stack } override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapNotEnoughMedia.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapNotEnoughMedia.kt index 07d686b56e..b5921958b0 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapNotEnoughMedia.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapNotEnoughMedia.kt @@ -4,6 +4,7 @@ import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.eval.ResolvedPatternType import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.pigment.FrozenPigment +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.api.utils.asTranslatedComponent import net.minecraft.world.item.DyeColor @@ -13,8 +14,9 @@ class MishapNotEnoughMedia(private val cost: Long) : Mishap() { override fun resolutionType(ctx: CastingEnvironment) = ResolvedPatternType.ERRORED - override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { + override fun executeReturnStack(env: CastingEnvironment, errorCtx: Context, stack: Vector): Vector { env.extractMedia(cost, false) + return stack } override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = "hexcasting.message.cant_overcast".asTranslatedComponent diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapOthersName.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapOthersName.kt index e6ea0326ed..41f2aeccda 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapOthersName.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapOthersName.kt @@ -5,6 +5,7 @@ import at.petrak.hexcasting.api.casting.iota.EntityIota import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.ListIota import at.petrak.hexcasting.api.pigment.FrozenPigment +import at.petrak.hexcasting.api.utils.Vector import net.minecraft.world.entity.player.Player import net.minecraft.world.item.DyeColor @@ -15,9 +16,10 @@ class MishapOthersName(val confidant: Player) : Mishap() { override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = dyeColor(DyeColor.BLACK) - override fun execute(ctx: CastingEnvironment, errorCtx: Context, stack: MutableList) { + override fun executeReturnStack(ctx: CastingEnvironment, errorCtx: Context, stack: Vector): Vector { val seconds = if (this.confidant == ctx.castingEntity) 5 else 60 ctx.mishapEnvironment.blind(seconds * 20) + return stack } override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapStackSize.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapStackSize.kt index 571e39bcd9..0262874a39 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapStackSize.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapStackSize.kt @@ -5,6 +5,7 @@ import at.petrak.hexcasting.api.casting.eval.ResolvedPatternType import at.petrak.hexcasting.api.casting.iota.GarbageIota import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.pigment.FrozenPigment +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.common.lib.HexDamageTypes import net.minecraft.world.item.DyeColor @@ -14,10 +15,8 @@ class MishapStackSize() : Mishap() { override fun resolutionType(ctx: CastingEnvironment) = ResolvedPatternType.ERRORED - override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { - stack.clear() - stack.add(GarbageIota()) - } + override fun executeReturnStack(env: CastingEnvironment, errorCtx: Context, stack: Vector): Vector = + Vector.from(listOf(GarbageIota())) override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = error("stack_size") diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapTooManyCloseParens.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapTooManyCloseParens.kt index dfa159bda7..79ccf35f79 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapTooManyCloseParens.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapTooManyCloseParens.kt @@ -4,16 +4,19 @@ import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.PatternIota import at.petrak.hexcasting.api.pigment.FrozenPigment +import at.petrak.hexcasting.api.utils.Vector import net.minecraft.world.item.DyeColor class MishapTooManyCloseParens : Mishap() { override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = dyeColor(DyeColor.ORANGE) - override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { + override fun executeReturnStack(env: CastingEnvironment, errorCtx: Context, stack: Vector): Vector { // TODO this is a kinda shitty mishap - if (errorCtx.pattern != null) - stack.add(PatternIota(errorCtx.pattern)) + return if (errorCtx.pattern != null) + stack.appended(PatternIota(errorCtx.pattern)) + else + stack } override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapUnenlightened.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapUnenlightened.kt index e0dde2150b..9ea13f4c4d 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapUnenlightened.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapUnenlightened.kt @@ -5,6 +5,7 @@ import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.eval.ResolvedPatternType import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.pigment.FrozenPigment +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.api.utils.asTranslatedComponent import net.minecraft.server.level.ServerPlayer import net.minecraft.sounds.SoundEvents @@ -17,7 +18,7 @@ class MishapUnenlightened : Mishap() { override fun resolutionType(ctx: CastingEnvironment) = ResolvedPatternType.INVALID - override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { + override fun executeReturnStack(env: CastingEnvironment, errorCtx: Context, stack: Vector): Vector { env.mishapEnvironment.dropHeldItems() env.castingEntity?.sendSystemMessage("hexcasting.message.cant_great_spell".asTranslatedComponent) @@ -29,6 +30,7 @@ class MishapUnenlightened : Mishap() { if (castingPlayer != null) { HexAdvancementTriggers.FAIL_GREAT_SPELL_TRIGGER.trigger(castingPlayer) } + return stack } override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = null diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapUnescapedValue.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapUnescapedValue.kt index 6a30a8221e..3c3e7e5a3b 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapUnescapedValue.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapUnescapedValue.kt @@ -3,6 +3,7 @@ package at.petrak.hexcasting.api.casting.mishaps import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.pigment.FrozenPigment +import at.petrak.hexcasting.api.utils.Vector import net.minecraft.world.item.DyeColor /** @@ -14,7 +15,7 @@ class MishapUnescapedValue( override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = dyeColor(DyeColor.GRAY) - override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { + override fun executeReturnStack(env: CastingEnvironment, errorCtx: Context, stack: Vector): Vector { // TODO /* val idx = stack.indexOfLast { it.getType() == DatumType.LIST } @@ -28,6 +29,7 @@ class MishapUnescapedValue( } } */ + return stack } override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/circle/MishapBoolDirectrixEmptyStack.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/circle/MishapBoolDirectrixEmptyStack.kt index ae27403f23..7499f002b0 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/circle/MishapBoolDirectrixEmptyStack.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/circle/MishapBoolDirectrixEmptyStack.kt @@ -4,6 +4,7 @@ import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.mishaps.Mishap import at.petrak.hexcasting.api.pigment.FrozenPigment +import at.petrak.hexcasting.api.utils.Vector import net.minecraft.core.BlockPos import net.minecraft.network.chat.Component import net.minecraft.world.item.DyeColor @@ -15,8 +16,9 @@ class MishapBoolDirectrixEmptyStack( override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = dyeColor(DyeColor.GRAY) - override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { + override fun executeReturnStack(env: CastingEnvironment, errorCtx: Context, stack: Vector): Vector { env.world.destroyBlock(this.pos, true) + return stack } override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context): Component = diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/circle/MishapBoolDirectrixNotBool.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/circle/MishapBoolDirectrixNotBool.kt index 7c3d7b1fb5..030088d14e 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/circle/MishapBoolDirectrixNotBool.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/circle/MishapBoolDirectrixNotBool.kt @@ -4,6 +4,7 @@ import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.mishaps.Mishap import at.petrak.hexcasting.api.pigment.FrozenPigment +import at.petrak.hexcasting.api.utils.Vector import net.minecraft.core.BlockPos import net.minecraft.network.chat.Component import net.minecraft.world.item.DyeColor @@ -16,8 +17,9 @@ class MishapBoolDirectrixNotBool( override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = dyeColor(DyeColor.GRAY) - override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { + override fun executeReturnStack(env: CastingEnvironment, errorCtx: Context, stack: Vector): Vector { env.world.destroyBlock(this.pos, true) + return stack } override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context): Component = diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/circle/MishapNoSpellCircle.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/circle/MishapNoSpellCircle.kt index 9eeae0f2b5..a1c557fd5f 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/circle/MishapNoSpellCircle.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/circle/MishapNoSpellCircle.kt @@ -4,6 +4,7 @@ import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.mishaps.Mishap import at.petrak.hexcasting.api.pigment.FrozenPigment +import at.petrak.hexcasting.api.utils.Vector import net.minecraft.server.level.ServerPlayer import net.minecraft.world.entity.player.Player import net.minecraft.world.item.DyeColor @@ -25,7 +26,7 @@ class MishapNoSpellCircle : Mishap() { } } - override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { + override fun executeReturnStack(env: CastingEnvironment, errorCtx: Context, stack: Vector): Vector { val caster = env.castingEntity as? ServerPlayer if (caster != null) { // FIXME: handle null caster case @@ -35,6 +36,7 @@ class MishapNoSpellCircle : Mishap() { !EnchantmentHelper.hasBindingCurse(it) } } + return stack } override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = diff --git a/Common/src/main/java/at/petrak/hexcasting/api/utils/HexUtils.kt b/Common/src/main/java/at/petrak/hexcasting/api/utils/HexUtils.kt index 209297766a..beadfd0aae 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/utils/HexUtils.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/utils/HexUtils.kt @@ -265,7 +265,7 @@ fun Iterable.serializeToNBT() = if (IotaType.isTooLargeToSerialize(this)) ListTag() else - ListIota(this.toList()).serialize() + ListIota(Vector.from(this)).serialize() fun Iterable.serializeToNBT(): ByteArrayTag { val out = ByteArray(if (this is Collection<*>) this.size else 10) diff --git a/Common/src/main/java/at/petrak/hexcasting/api/utils/Vector.java b/Common/src/main/java/at/petrak/hexcasting/api/utils/Vector.java new file mode 100644 index 0000000000..5d286b3821 --- /dev/null +++ b/Common/src/main/java/at/petrak/hexcasting/api/utils/Vector.java @@ -0,0 +1,3383 @@ +package at.petrak.hexcasting.api.utils; + +import com.google.common.collect.Lists; + +import java.lang.reflect.Array; +import java.util.*; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Predicate; + +import static java.util.Arrays.copyOf; +import static java.util.Arrays.copyOfRange; + +// TODO mark everything with use-site variance + +/** + * Ported from Scala 2.13.16's scala.collection.immutable.Vector + */ +@SuppressWarnings("unchecked") +public sealed abstract class Vector extends AbstractList implements RandomAccess { + + private static int copyToArray(Iterable it, Object[] dst, int start) { + if(it instanceof Collection cc) { + final int ccSize = cc.size(); + final int dstRoom = dst.length - start; + final int toCopy = Math.min(ccSize, dstRoom); + System.arraycopy(cc.toArray(), 0, dst, start, toCopy); + return toCopy; + } else { + int i = 0; + Iterator iter = it.iterator(); + while (i + start < dst.length && iter.hasNext()) { + dst[i + start] = iter.next(); + i++; + } + return i; + } + } + + private static int computeSize(Iterable it) { + if(it instanceof Collection cc) return cc.size(); + else { + int i = 0; + for (final Object o : it) { + i++; + } + return i; + } + } + + private static int knownSize(Iterable it) { + if(it instanceof Collection cc) { + return cc.size(); + } else return Integer.MAX_VALUE; + } + + private static int sizeCompare(Iterable left, int right) { + if(right == Integer.MAX_VALUE) return 1; + else { + final int known = knownSize(left); + if(known != Integer.MAX_VALUE) return Integer.compare(known, right); + else { + int i; + Iterator it; + for(i = 0, it = left.iterator(); it.hasNext(); i++, it.next()) { + if(i == right) return 1; + } + return i - right; + } + } + } + + private static int sizeCompare(Iterable left, Iterable right) { + final int rightKnownSize = knownSize(right); + + if(rightKnownSize != Integer.MAX_VALUE) return sizeCompare(left, rightKnownSize); + else { + final int leftKnownSize = knownSize(left); + + if(leftKnownSize != Integer.MAX_VALUE) { + final int res = sizeCompare(right, leftKnownSize); + if(res == Integer.MIN_VALUE) return 1; else return -res; + } else { + final Iterator leftIt = left.iterator(); + final Iterator rightIt = right.iterator(); + + while(leftIt.hasNext() && rightIt.hasNext()) { + leftIt.next(); + rightIt.next(); + } + return Boolean.compare(leftIt.hasNext(), rightIt.hasNext()); + } + } + } + + private static final int BITS = 5; + private static final int WIDTH = 1 << BITS; + private static final int MASK = WIDTH - 1; + private static final int BITS2 = BITS * 2; + private static final int WIDTH2 = 1 << BITS2; + private static final int BITS3 = BITS * 3; + private static final int WIDTH3 = 1 << BITS3; + private static final int BITS4 = BITS * 4; + private static final int WIDTH4 = 1 << BITS4; + private static final int BITS5 = BITS * 5; + private static final int WIDTH5 = 1 << BITS5; + private static final int LASTWIDTH = WIDTH << 1; // 1 extra bit in the last level to go up to Int.MaxValue (2^31-1) instead of 2^30: + private static final int LOG2_CONCAT_FASTER = 5; + private static final int ALIGN_TO_FASTER = 64; + + private static int vectorSliceDim(int count, int idx) { + final int c = count / 2; + return c + 1 - Math.abs(idx - c); + } + + private static T[] copyOrUse(T[] a, int start, int end) { + if(start == 0 && end == a.length) return a; else return copyOfRange(a, start, end); + } + + private static T[] copyTail(T[] a) { + return copyOfRange(a, 1, a.length); + } + + private static T[] copyInit(T[] a) { + return copyOfRange(a, 0, a.length - 1); + } + + private static T[] copyIfDifferentSize(T[] a, int len) { + if(a.length == len) return a; else return copyOf(a, len); + } + + private static Object[] wrap1(Object x) { + Object[] arr = new Object[1]; + arr[0] = x; + return arr; + } + + private static Object[][] wrap2(Object[] x) { + Object[][] arr = new Object[1][]; + arr[0] = x; + return arr; + } + + private static Object[][][] wrap3(Object[][] x) { + Object[][][] arr = new Object[1][][]; + arr[0] = x; + return arr; + } + + private static Object[][][][] wrap4(Object[][][] x) { + Object[][][][] arr = new Object[1][][][]; + arr[0] = x; + return arr; + } + + private static Object[][][][][] wrap5(Object[][][][] x) { + Object[][][][][] arr = new Object[1][][][][]; + arr[0] = x; + return arr; + } + + private static Object[] copyUpdate(Object[] a1, int idx1, Object elem) { + final Object[] a1c = a1.clone(); + a1c[idx1] = elem; + return a1c; + } + + private static Object[][] copyUpdate(Object[][] a2, int idx2, int idx1, Object elem) { + final Object[][] a2c = a2.clone(); + a2c[idx2] = copyUpdate(a2c[idx2], idx1, elem); + return a2c; + } + + private static Object[][][] copyUpdate(Object[][][] a3, int idx3, int idx2, int idx1, Object elem) { + final Object[][][] a3c = a3.clone(); + a3c[idx3] = copyUpdate(a3c[idx3], idx2, idx1, elem); + return a3c; + } + + private static Object[][][][] copyUpdate(Object[][][][] a4, int idx4, int idx3, int idx2, int idx1, Object elem) { + final Object[][][][] a4c = a4.clone(); + a4c[idx4] = copyUpdate(a4c[idx4], idx3, idx2, idx1, elem); + return a4c; + } + + private static Object[][][][][] copyUpdate(Object[][][][][] a5, int idx5, int idx4, int idx3, int idx2, int idx1, Object elem) { + final Object[][][][][] a5c = a5.clone(); + a5c[idx5] = copyUpdate(a5c[idx5], idx4, idx3, idx2, idx1, elem); + return a5c; + } + + private static Object[][][][][][] copyUpdate(Object[][][][][][] a6, int idx6, int idx5, int idx4, int idx3, int idx2, int idx1, Object elem) { + final Object[][][][][][] a6c = a6.clone(); + a6c[idx6] = copyUpdate(a6c[idx6], idx5, idx4, idx3, idx2, idx1, elem); + return a6c; + } + + private static T[] concatArrays(T[] a, T[] b) { + T[] dest = copyOf(a, a.length + b.length); + System.arraycopy(b, 0, dest, a.length, b.length); + return dest; + } + + private static Object[] copyAppend1(Object[] a, Object elem) { + final int alen = a.length; + final Object[] ac = new Object[alen + 1]; + System.arraycopy(a, 0, ac, 0, alen); + ac[alen] = elem; + return ac; + } + + private static T[] copyAppend(T[] a, T elem) { + T[] ac = copyOf(a, a.length + 1); + ac[ac.length - 1] = elem; + return ac; + } + + private static Object[] copyPrepend1(Object elem, Object[] a) { + final Object[] ac = new Object[a.length + 1]; + System.arraycopy(a, 0, ac, 1, a.length); + ac[0] = elem; + return ac; + } + + private static T[] copyPrepend(T elem, T[] a) { + T[] ac = (T[]) Array.newInstance(a.getClass().getComponentType(), a.length + 1); + System.arraycopy(a, 0, ac, 1, a.length); + ac[0] = elem; + return ac; + } + + private static final Object[] empty1 = new Object[0]; + private static final Object[][] empty2 = new Object[0][]; + private static final Object[][][] empty3 = new Object[0][][]; + private static final Object[][][][] empty4 = new Object[0][][][]; + private static final Object[][][][][] empty5 = new Object[0][][][][]; + private static final Object[][][][][][] empty6 = new Object[0][][][][][]; + + private static void foreachRec(int level, T[] a, Consumer f) { + int i = 0; + final int len = a.length; + if(level == 0) { + while(i < len) { + f.accept((A) a[i]); + i++; + } + } else { + final int l = level - 1; + while(i < len) { + foreachRec(l, (Object[]) a[i], f); + i++; + } + } + } + + private static Object[] mapElems1(Object[] a, Function f) { + for(int i = 0; i < a.length; i++) { + final Object v1 = a[i]; + final Object v2 = f.apply((A) v1); + if(v1 != v2) return mapElems1Rest(a, f, i, v2); + } + return a; + } + + private static Object[] mapElems1Rest(Object[] a, Function f, int at, Object v2) { + Object[] ac = new Object[a.length]; + if(at > 0) System.arraycopy(a, 0, ac, 0, at); + ac[at] = v2; + for(int i = at + 1; i < a.length; i++) { + ac[i] = f.apply((A) a[i]); + } + return ac; + } + + private static T[] mapElems(int n, T[] a, Function f) { + if(n == 1) return (T[]) mapElems1(a, f); + else { + for(int i = 0; i < a.length; i++) { + final T v1 = a[i]; + final Object[] v2 = mapElems(n - 1, (Object[]) v1, f); + if(v1 != v2) return mapElemsRest(n, a, f, i, v2); + } + return a; + } + } + + private static T[] mapElemsRest(int n, T[] a, Function f, int at, Object v2) { + final Object[] ac = (Object[]) Array.newInstance(a.getClass().getComponentType(), a.length); + if(at > 0) System.arraycopy(a, 0, ac, 0, at); + ac[at] = v2; + for(int i = at + 1; i < a.length; i++) { + ac[i] = mapElems(n - 1, (Object[]) a[i], f); + } + return (T[]) ac; + } + + private static Object[] prepend1IfSpace(Object[] prefix1, Iterable it) { + if(sizeCompare(it, WIDTH - prefix1.length) <= 0) { + final int s = computeSize(it); + if(s == 0) return null; + else if(s == 1) return copyPrepend(it.iterator().next(), prefix1); + else { + final Object[] prefix1b = new Object[prefix1.length + s]; + System.arraycopy(prefix1, 0, prefix1b, s, prefix1.length); + copyToArray(it, prefix1b, 0); + return prefix1b; + } + } else return null; + } + + private static Object[] append1IfSpace(Object[] suffix1, Iterable it) { + if(sizeCompare(it, WIDTH - suffix1.length) <= 0) { + final int s = computeSize(it); + if(s == 0) return null; + else if(s == 1) return copyAppend(suffix1, it.iterator().next()); + else { + final Object[] suffix1b = copyOf(suffix1, suffix1.length + s); + copyToArray(it, suffix1b, suffix1.length); + return suffix1b; + } + } else return null; + } + + final Object[] prefix1; + + Vector(Object[] prefix1) { + this.prefix1 = prefix1; + } + + protected final IndexOutOfBoundsException ioob(int index) { + return new IndexOutOfBoundsException("%d is out of bounds (min 0, max %d)".formatted(index, this.length() - 1)); + } + + public int length() { + return this.prefix1.length; + } + + public ListIterator iterator() { + return new NewVectorIterator<>(this, this.length(), this.vectorSliceCount()); + } + + protected Vector filterImpl(Predicate predicate, boolean isFlipped) { + int i = 0; + final int len = this.prefix1.length; + while (i != len) { + if(predicate.test((A) this.prefix1[i]) == isFlipped) { + // each 1 bit indicates that index passes the filter. + // all indices < i are also assumed to pass the filter + int bitmap = 0; + int j = i + 1; + while (j < len) { + if(predicate.test((A) this.prefix1[j]) != isFlipped) { + bitmap |= (1 << j); + } + j += 1; + } + final int newLen = Integer.bitCount(bitmap); + + if(newLen == 0) return Vector0.getInstance(); + else { + final Object[] newData = new Object[newLen]; + System.arraycopy(prefix1, 0, newData, 0, i); + int k = i + 1; + while (i != newLen) { + if (((1 << k) & bitmap) != 0) { + newData[i] = this.prefix1[k]; + i += 1; + } + k += 1; + } + return new Vector1(newData); + } + } + + i++; + } + + return this; + } + + public abstract Vector updated(int index, A elem); + + public abstract Vector appended(A elem); + + public abstract Vector prepended(A elem); + + public Vector prependedAll(Iterable prefix) { + int k = knownSize(prefix); + if(k == 0) return this; + else if (k >= Integer.MAX_VALUE) { + VectorBuilder builder = new VectorBuilder(); + builder.addAll(prefix); + builder.addAll(this); + return builder.result(); + } else return this.prependedAll0(prefix, k); + } + + public Vector appendedAll(Iterable suffix) { + int k = knownSize(suffix); + if(k == 0) return this; + else if (k >= Integer.MAX_VALUE) { + VectorBuilder builder = new VectorBuilder(); + builder.addAll(this); + builder.addAll(suffix); + return builder.result(); + } else return this.appendedAll0(suffix, k); + } + + protected Vector prependedAll0(Iterable prefix, int k) { + // k >= 0, k = prefix.knownSize + final int tinyAppendLimit = 4 + this.vectorSliceCount(); + if (k < tinyAppendLimit /*|| k < (this.size >>> Log2ConcatFaster)*/) { + Vector v = this; + Object[] elements = new Object[k]; + Iterator it = prefix.iterator(); + for(int i = elements.length - 1; i >= 0; i--) { + elements[i] = it.next(); + } + for(Object elem : elements) { + v = v.prepended((A) elem); + } + return v; + } else if (this.size() < (k >>> LOG2_CONCAT_FASTER) && prefix instanceof Vector) { + Vector v = (Vector) prefix; + for (A a : this) v = v.appended(a); + return v; + } else if (k < this.size() - ALIGN_TO_FASTER) { + return new VectorBuilder().alignTo(k, this).addAll(prefix).addAll(this).result(); + } else { + VectorBuilder builder = new VectorBuilder(); + builder.addAll(prefix); + builder.addAll(this); + return builder.result(); + } + } + + protected Vector appendedAll0(Iterable suffix, int k) { + // k >= 0, k = suffix.knownSize + final int tinyAppendLimit = 4 + this.vectorSliceCount(); + if (k < tinyAppendLimit) { + Vector v = this; + for(A a : suffix) v = v.appended(a); + return v; + } else if (this.size() < (k >>> LOG2_CONCAT_FASTER) && suffix instanceof Vector) { + Vector v = (Vector) suffix; + for (A a : this.reversed()) v = v.prepended(a); + return v; + } else if (this.size() < k - ALIGN_TO_FASTER && suffix instanceof Vector) { + Vector v = (Vector) suffix; + return new VectorBuilder().alignTo(this.size(), v).addAll(this).addAll(v).result(); + } else return new VectorBuilder().initFrom(this).addAll(suffix).result(); + } + + public final Vector take(int n) { + return this.slice(0, n); + } + + public final Vector drop(int n) { + return this.slice(n, this.length()); + } + + public final Vector takeRight(int n) { + return this.slice(this.length() - Math.max(n, 0), this.length()); + } + + public final Vector dropRight(int n) { + return this.slice(0, this.length() - Math.max(n, 0)); + } + + public Vector tail() { + return this.slice(1, this.length()); + } + + public Vector init() { + return this.slice(0, this.length() - 1); + } + + /** Like slice but parameters must be 0 <= lo < hi < length */ + protected abstract Vector slice0(int lo, int hi); + + /** Number of slices */ + abstract int vectorSliceCount(); + /** Slice at index */ + abstract Object[] vectorSlice(int idx); + /** Length of all slices up to and including index */ + abstract int vectorSlicePrefixLength(int idx); + + public final A head() { + if(this.prefix1.length == 0) throw new NoSuchElementException("empty.head"); + else return (A) this.prefix1[0]; + } + + public A last() { + return (A) this.prefix1[this.prefix1.length - 1]; + } + + public void foreach(Consumer f) { + final int c = this.vectorSliceCount(); + for(int i = 0; i < c; i++) { + foreachRec(vectorSliceDim(c, i) - 1, this.vectorSlice(i), f); + } + } + + public final Vector slice(int from, int until) { + final int lo = Math.max(from, 0); + final int hi = Math.min(until, this.length()); + if(hi <= lo) return Vector0.getInstance(); + else if(hi - lo == this.length()) return this; + else return this.slice0(lo, hi); + } + + public boolean contains(Object elem) { + return this.exists(elem::equals); + } + + public int copyToArray(A[] arr, int start, int len) { + int i; + ListIterator li; + for(i = 0, li = this.iterator(); i < len && (i + start) < arr.length && li.hasNext(); i++) { + arr[start + i] = li.next(); + } + return i; + } + + public final int copyToArray(A[] arr, int start) { + return this.copyToArray(arr, start, Integer.MAX_VALUE); + } + + public final int copyToArray(A[] arr) { + return this.copyToArray(arr, 0, Integer.MAX_VALUE); + } + + public static Vector empty() { + return Vector0.getInstance(); + } + + public static Vector from(Iterable it) { + if(it instanceof Vector v) return v; + + final int knownSize = knownSize(it); + if(knownSize == 0) return empty(); + else if(knownSize > 0 && knownSize <= WIDTH) { + Object[] a1; + if(it instanceof Collection c) a1 = c.toArray(); + else { + a1 = new Object[knownSize]; + copyToArray(it, a1, 0); + } + return new Vector1<>(a1); + } else { + VectorBuilder builder = new VectorBuilder<>(); + builder.addAll(it); + return builder.result(); + } + } + + @Override + public boolean equals(Object obj) { + if(this == obj) return true; + else if(obj instanceof List la) { + return this.sameElements((List) la); + } else return false; + } + + public boolean sameElements(Iterable iterable) { + final int thisKnownSize = this.knownSize(); + final boolean knownSizeDifference; + if(thisKnownSize != Integer.MAX_VALUE) { + final int thatKnownSize = knownSize(iterable); + knownSizeDifference = thatKnownSize != Integer.MAX_VALUE && thisKnownSize != thatKnownSize; + } else knownSizeDifference = false; + if(knownSizeDifference) return false; + Iterator left = this.iterator(); + Iterator right = iterable.iterator(); + while (left.hasNext() && right.hasNext()) { + if(!left.next().equals(right.next())) return false; + } + return left.hasNext() == right.hasNext(); + } + + public boolean exists(Predicate p) { + boolean res = false; + final Iterator it = this.iterator(); + while (!res && it.hasNext()) { res = p.test(it.next()); } + return res; + } + + public Vector filter(Predicate pred) { + return this.filterImpl(pred, false); + } + + public Vector flatMap(Function> func) { + VectorBuilder builder = new VectorBuilder(); + for(A a : this) { + builder.addAll(func.apply(a)); + } + return builder.result(); + } + + @Override + public int hashCode() { + int hashCode = 1; + for(A a : this) { + hashCode *= 31; + if(a != null) hashCode += a.hashCode(); + } + return hashCode; + } + + public boolean isEmpty() { + return this.length() == 0; + } + + public int knownSize() { + return this.length(); + } + + public abstract Vector map(Function f); + + public Vector reversed() { + // FIXME: Understand NewVectorIterator + VectorBuilder builder = new VectorBuilder<>(); + for(int i = this.size() - 1; i >= 0; i--) { + builder.addOne(this.get(i)); + } + return builder.result(); + } + + public final int size() { + return this.length(); + } + + public A[] toArray(Class clazz) { + final A[] destination = (A[]) Array.newInstance(clazz, this.knownSize()); + copyToArray(destination, 0); + return destination; + } + + public abstract A get(int i); + + private static sealed abstract class BigVector extends Vector { + final Object[] suffix1; + final int length0; + + protected BigVector(Object[] prefix1, Object[] suffix1, int length0) { + super(prefix1); + this.suffix1 = suffix1; + this.length0 = length0; + } + + @Override + public int length() { + return this.length0; + } + + @Override + protected Vector filterImpl(Predicate predicate, boolean isFlipped) { + int i = 0; + final int len = this.prefix1.length; + while (i != len) { + if(predicate.test((A) this.prefix1[i]) == isFlipped) { + int bitmap = 0; + int j = i + 1; + while(j < len) { + if(predicate.test((A) this.prefix1[j]) != isFlipped) { + bitmap |= (1 << j); + } + j += 1; + } + final int newLen = i + Integer.bitCount(bitmap); + + VectorBuilder b = new VectorBuilder<>(); + int k = 0; + while (k < i) { + b.addOne((A) this.prefix1[k]); + k += 1; + } + k = i + 1; + while(i != newLen) { + if(((1 << k) & bitmap) != 0) { + b.addOne((A) this.prefix1[k]); + i += 1; + } + k += 1; + } + this.foreachRest(v -> { + if(predicate.test(v) != isFlipped) b.addOne(v); + }); + return b.result(); + } + i += 1; + } + VectorBuilder b = new VectorBuilder<>(); + b.initFrom(this.prefix1); + this.foreachRest(v -> { + if(predicate.test(v) != isFlipped) b.addOne(v); + }); + return b.result(); + } + + protected final void foreachRest(Consumer f) { + final int c = this.vectorSliceCount(); + for(int i = 1; i < c; i++) { + foreachRec(vectorSliceDim(c, i)-1, vectorSlice(i), f); + } + } + + @Override + public A last() { + final Object[] suffix = this.suffix1; + if(suffix.length == 0) throw new NoSuchElementException("empty.tail"); + else return (A) suffix[suffix.length - 1]; + } + } + + private static final class Vector0 extends BigVector { + private static final Vector0 INSTANCE = new Vector0(); + + public static Vector getInstance() { return (Vector) INSTANCE; } + + private Vector0() { + super(empty1, empty1, 0); + } + + public ListIterator iterator() { + return Collections.emptyListIterator(); + } + + @Override + public Void get(int i) { + throw ioob(i); + } + + @Override + public Vector updated(int index, Object elem) { + throw ioob(index); + } + + @Override + public Vector appended(Object elem) { + return new Vector1<>(wrap1(elem)); + } + + @Override + public Vector prepended(Object elem) { + return new Vector1<>(wrap1(elem)); + } + + @Override + public Vector map(Function f) { + return (Vector) this; + } + + @Override + public Vector tail() { + throw new UnsupportedOperationException("empty.tail"); + } + + @Override + public Vector init() { + throw new UnsupportedOperationException("empty.init"); + } + + @Override + protected Vector slice0(int lo, int hi) { + return this; + } + + @Override + int vectorSliceCount() { + return 0; + } + + @Override + Object[] vectorSlice(int idx) { + return null; + } + + @Override + int vectorSlicePrefixLength(int idx) { + return 0; + } + + @Override + public boolean equals(Object obj) { + if(this == obj) return true; + else if(obj instanceof Vector) return false; + else return super.equals(obj); + } + + @Override + protected Vector prependedAll0(Iterable prefix, int k) { + return Vector.from(prefix); + } + + @Override + protected Vector appendedAll0(Iterable suffix, int k) { + return Vector.from(suffix); + } + } + + private static final class Vector1 extends Vector { + Vector1(Object[] data1) { + super(data1); + } + + @Override + public A get(int index) { + if(index >= 0 && index < this.prefix1.length) + return (A) this.prefix1[index]; + else throw ioob(index); + } + + @Override + public Vector updated(int index, A elem) { + if(index >= 0 && index < this.prefix1.length) + return new Vector1<>(copyUpdate(this.prefix1, index, elem)); + else throw ioob(index); + } + + @Override + public Vector appended(A elem) { + final int len1 = this.prefix1.length; + if(len1 < WIDTH) return new Vector1<>(copyAppend1(this.prefix1, elem)); + else return new Vector2<>(this.prefix1, WIDTH, empty2, wrap1(elem), WIDTH + 1); + } + + @Override + public Vector prepended(A elem) { + final int len1 = this.prefix1.length; + if(len1 < WIDTH) return new Vector1<>(copyPrepend1(elem, this.prefix1)); + else return new Vector2<>(wrap1(elem), 1, empty2, this.prefix1, len1 + 1); + } + + @Override + public Vector map(Function f) { + return new Vector1<>(mapElems1(this.prefix1, f)); + } + + @Override + protected Vector slice0(int lo, int hi) { + return new Vector1<>(copyOfRange(this.prefix1, lo, hi)); + } + + @Override + public Vector tail() { + if(this.prefix1.length == 1) return Vector0.getInstance(); + else return new Vector1<>(copyTail(this.prefix1)); + } + + @Override + public Vector init() { + if(this.prefix1.length == 1) return Vector0.getInstance(); + else return new Vector1<>(copyInit(this.prefix1)); + } + + @Override + int vectorSliceCount() { + return 1; + } + + @Override + Object[] vectorSlice(int idx) { + return this.prefix1; + } + + @Override + int vectorSlicePrefixLength(int idx) { + return this.prefix1.length; + } + + @Override + protected Vector prependedAll0(Iterable prefix, int k) { + final Object[] data1b = prepend1IfSpace(this.prefix1, prefix); + if(data1b == null) return super.prependedAll0(prefix, k); + else return new Vector1<>(data1b); + } + + @Override + protected Vector appendedAll0(Iterable suffix, int k) { + final Object[] data1b = append1IfSpace(this.prefix1, suffix); + if(data1b != null) return new Vector1<>(data1b); + else return super.appendedAll0(suffix, k); + } + } + + private static final class Vector2 extends BigVector { + final int len1; + final Object[][] data2; + + Vector2(Object[] prefix1, int len1, Object[][] data2, Object[] suffix1, int length0) { + super(prefix1, suffix1, length0); + this.len1 = len1; + this.data2 = data2; + } + + @Override + public A get(int i) { + if(i >= 0 && i < this.length0) { + final int io = i - this.len1; + if(io >= 0) { + final int i2 = io >>> BITS; + final int i1 = io & MASK; + if(i2 < data2.length) return (A) this.data2[i2][i1]; + else return (A) suffix1[io & MASK]; + } else return (A) this.prefix1[i]; + } else throw ioob(i); + } + + @Override + public Vector updated(int index, A elem) { + if(index >= 0 && index < this.length0) { + if(index >= this.len1) { + final int io = index - this.len1; + final int i2 = io >>> BITS; + final int i1 = io & MASK; + if(i2 < data2.length) return new Vector2<>( + this.prefix1, this.len1, + copyUpdate(this.data2, i2, i1, elem), + this.suffix1, this.length0 + ); else return new Vector2<>( + this.prefix1, this.len1, this.data2, + copyUpdate(this.suffix1, i1, elem), + this.length0 + ); + } else { + return new Vector2<>( + copyUpdate(this.prefix1, index, elem), + this.len1, this.data2, this.suffix1, this.length0 + ); + } + } else throw ioob(index); + } + + @Override + public Vector appended(A elem) { + if (suffix1.length < WIDTH) return new Vector2<>( + this.prefix1, this.len1, this.data2, + copyAppend1(this.suffix1, elem), this.length0 + 1 + ); else if(data2.length < WIDTH - 2) return new Vector2<>( + this.prefix1, this.len1, + copyAppend(this.data2, this.suffix1), wrap1(elem), this.length0 + 1 + ); else return new Vector3<>( + this.prefix1, this.len1, this.data2, WIDTH * (WIDTH - 2) + this.len1, + empty3, wrap2(this.suffix1), wrap1(elem), this.length0 + 1 + ); + } + + @Override + public Vector prepended(A elem) { + if (this.len1 < WIDTH) return new Vector2<>( + copyPrepend1(elem, this.prefix1), this.len1 + 1, + this.data2, this.suffix1, + this.length0 + 1 + ); else if(data2.length < WIDTH - 2) return new Vector2<>( + wrap1(elem), 1, copyPrepend(this.prefix1, this.data2), + this.suffix1, + this.length0 + 1 + ); else return new Vector3<>( + wrap1(elem), 1, wrap2(this.prefix1), this.len1 + 1, + empty3, this.data2, this.suffix1, this.length0 + 1 + ); + } + + @Override + public Vector map(Function f) { + return new Vector2<>( + mapElems1(this.prefix1, f), this.len1, + mapElems(2, this.data2, f), + mapElems1(this.suffix1, f), this.length0 + ); + } + + @Override + protected Vector slice0(int lo, int hi) { + final VectorSliceBuilder b = new VectorSliceBuilder(lo, hi); + b.consider(1, this.prefix1); + b.consider(2, this.data2); + b.consider(1, this.suffix1); + return b.result(); + } + + @Override + public Vector tail() { + if(this.len1 > 1) return new Vector2<>( + copyTail(this.prefix1), this.len1 - 1, + this.data2, this.suffix1, + this.length0 - 1 + ); else return this.slice0(1, this.length0); + } + + @Override + public Vector init() { + if(this.suffix1.length > 1) return new Vector2<>( + this.prefix1, this.len1, this.data2, + copyInit(this.suffix1), this.length0 - 1 + ); else return this.slice0(0, this.length0 - 1); + } + + @Override + int vectorSliceCount() { + return 3; + } + + @Override + Object[] vectorSlice(int idx) { + return switch(idx) { + case 0 -> this.prefix1; + case 1 -> this.data2; + case 2 -> this.suffix1; + default -> throw new IllegalArgumentException("slice idx " + idx); + }; + } + + @Override + int vectorSlicePrefixLength(int idx) { + return switch(idx) { + case 0 -> this.len1; + case 1 -> this.length0 - this.suffix1.length; + case 2 -> this.length0; + default -> throw new IllegalArgumentException("slice idx " + idx); + }; + } + + @Override + protected Vector prependedAll0(Iterable prefix, int k) { + final Object[] prefix1b = prepend1IfSpace(this.prefix1, prefix); + if(prefix1b == null) return super.prependedAll0(prefix, k); + else { + final int diff = prefix1b.length - prefix1.length; + return new Vector2<>( + prefix1b, this.len1 + diff, + this.data2, this.suffix1, + this.length0 + diff + ); + } + } + + @Override + protected Vector appendedAll0(Iterable suffix, int k) { + final Object[] suffix1b = append1IfSpace(this.suffix1, suffix); + if(suffix1b != null) return new Vector2<>( + this.prefix1, this.len1, this.data2, + suffix1b, this.length0 - suffix1.length + suffix1b.length + ); else return super.appendedAll0(suffix, k); + } + } + + private static final class Vector3 extends BigVector { + + final int len1; + final Object[][] prefix2; + final int len12; + final Object[][][] data3; + final Object[][] suffix2; + + Vector3( + Object[] prefix1, int len1, + Object[][] prefix2, int len12, + Object[][][] data3, Object[][] suffix2, Object[] suffix1, + int length0 + ) { + super(prefix1, suffix1, length0); + this.len1 = len1; + this.prefix2 = prefix2; + this.len12 = len12; + this.data3 = data3; + this.suffix2 = suffix2; + } + + @Override + public A get(int i) { + if(i >= 0 && i < this.length0) { + final int io = i - this.len12; + if(io >= 0) { + final int i3 = io >>> BITS2; + final int i2 = (io >>> BITS) & MASK; + final int i1 = io & MASK; + if(i3 < this.data3.length) return (A) this.data3[i3][i2][i1]; + else if(i2 < this.suffix2.length) return (A) this.suffix2[i2][i1]; + else return (A) this.suffix1[i1]; + } else if(i >= this.len1) { + final int io_ = i - this.len1; + return (A) prefix2[io_ >>> BITS][io_ & MASK]; + } else return (A) this.prefix1[i]; + } else throw ioob(i); + } + + @Override + public Vector updated(int index, A elem) { + if(index >= 0 && index < this.length0) { + if(index >= this.len12) { + final int io = index - this.len12; + final int i3 = io >>> BITS2; + final int i2 = (io >>> BITS) & MASK; + final int i1 = io & MASK; + if(i3 < this.data3.length) return new Vector3<>( + this.prefix1, this.len1, this.prefix2, this.len12, + copyUpdate(this.data3, i3, i2, i1, elem), + this.suffix2, this.suffix1, this.length0 + ); else if(i2 < this.suffix2.length) return new Vector3<>( + this.prefix1, this.len1, this.prefix2, this.len12, this.data3, + copyUpdate(this.suffix2, i2, i1, elem), + this.suffix1, this.length0 + ); else return new Vector3<>( + this.prefix1, this.len1, this.prefix2, this.len12, this.data3, this.suffix2, + copyUpdate(this.suffix1, i1, elem), + this.length0 + ); + } else if(index >= this.len1) { + final int io = index - this.len1; + return new Vector3<>( + this.prefix1, this.len1, + copyUpdate(prefix2, io >>> BITS, io & MASK, elem), + this.len12, this.data3, this.suffix2, this.suffix1, this.length0 + ); + } else { + return new Vector3<>( + copyUpdate(this.prefix1, index, elem), + this.len1, this.prefix2, this.len12, this.data3, this.suffix2, this.suffix1, this.length0 + ); + } + } else throw ioob(index); + } + + @Override + public Vector appended(A elem) { + if(this.suffix1.length < WIDTH) return new Vector3<>( + this.prefix1, this.len1, this.prefix2, this.len12, this.data3, this.suffix2, + copyAppend1(this.suffix1, elem), this.length0 + 1 + ); else if(this.suffix2.length < WIDTH - 1) return new Vector3<>( + this.prefix1, this.len1, this.prefix2, this.len12, this.data3, + copyAppend(this.suffix2, this.suffix1), wrap1(elem), this.length0 + 1 + ); else if(this.data3.length < WIDTH - 2) return new Vector3<>( + this.prefix1, this.len1, this.prefix2, this.len12, + copyAppend(this.data3, copyAppend(this.suffix2, this.suffix1)), empty2, wrap1(elem), this.length0 + 1 + ); else return new Vector4<>( + this.prefix1, this.len1, this.prefix2, this.len12, this.data3, (WIDTH - 2) * WIDTH2 + this.len12, + empty4, wrap3(copyAppend(this.suffix2, this.suffix1)), empty2, wrap1(elem), this.length0 + 1 + ); + } + + @Override + public Vector prepended(A elem) { + if(this.len1 < WIDTH) return new Vector3<>( + copyPrepend1(elem, this.prefix1), this.len1 + 1, + this.prefix2, + this.len12 + 1, + this.data3, this.suffix2, this.suffix1, + this.length0 + 1 + ); else if(this.len12 < WIDTH2) return new Vector3<>( + wrap1(elem), 1, copyPrepend(this.prefix1, this.prefix2), this.len12 + 1, + this.data3, this.suffix2, this.suffix1, + this.length0 + 1 + ); else if(this.data3.length < WIDTH - 2) return new Vector3<>( + wrap1(elem), 1, empty2, 1, copyPrepend(copyPrepend(this.prefix1, this.prefix2), this.data3), + this.suffix2, this.suffix1, + this.length0 + 1 + ); else return new Vector4<>( + wrap1(elem), 1, empty2, 1, wrap3(copyPrepend(this.prefix1, this.prefix2)), this.len12 + 1, + empty4, this.data3, this.suffix2, this.suffix1, this.length0 + 1 + ); + } + + @Override + public Vector map(Function f) { + return new Vector3<>( + mapElems1(this.prefix1, f), this.len1, + mapElems(2, this.prefix2, f), this.len12, + mapElems(3, this.data3, f), + mapElems(2, this.suffix2, f), + mapElems1(this.suffix1, f), + this.length0 + ); + } + + @Override + protected Vector slice0(int lo, int hi) { + final VectorSliceBuilder b = new VectorSliceBuilder(lo, hi); + b.consider(1, this.prefix1); + b.consider(2, this.prefix2); + b.consider(3, this.data3); + b.consider(2, this.suffix2); + b.consider(1, this.suffix1); + return b.result(); + } + + @Override + public Vector tail() { + if(this.len1 > 1) return new Vector3<>( + copyTail(this.prefix1), this.len1 - 1, + this.prefix2, this.len12 - 1, + this.data3, this.suffix2, this.suffix1, + this.length0 - 1 + ); else return this.slice0(1, this.length0); + } + + @Override + public Vector init() { + if(this.suffix1.length > 1) return new Vector3<>( + this.prefix1, this.len1, this.prefix2, this.len12, this.data3, this.suffix2, + copyInit(this.suffix1), this.length0 - 1 + ); else return this.slice0(0, this.length0 - 1); + } + + @Override + int vectorSliceCount() { + return 5; + } + + @Override + Object[] vectorSlice(int idx) { + return switch(idx) { + case 0 -> this.prefix1; + case 1 -> this.prefix2; + case 2 -> this.data3; + case 3 -> this.suffix2; + case 4 -> this.suffix1; + default -> throw new IllegalArgumentException("slice idx " + idx); + }; + } + + @Override + int vectorSlicePrefixLength(int idx) { + return switch (idx) { + case 0 -> this.len1; + case 1 -> this.len12; + case 2 -> this.len12 + this.data3.length * WIDTH2; + case 3 -> this.length0 - this.suffix1.length; + case 4 -> this.length0; + default -> throw new IllegalArgumentException("slice idx " + idx); + }; + } + + @Override + protected Vector prependedAll0(Iterable prefix, int k) { + final Object[] prefix1b = prepend1IfSpace(this.prefix1, prefix); + if(prefix1b == null) return super.prependedAll0(prefix, k); + else { + final int diff = prefix1b.length - this.prefix1.length; + return new Vector3<>( + prefix1b, this.len1 + diff, + this.prefix2, this.len12 + diff, + this.data3, this.suffix2, this.suffix1, + this.length0 + diff + ); + } + } + + @Override + protected Vector appendedAll0(Iterable suffix, int k) { + final Object[] suffix1b = prepend1IfSpace(this.suffix1, suffix); + if(suffix1b != null) return new Vector3<>( + this.prefix1, this.len1, this.prefix2, this.len12, this.data3, this.suffix2, + suffix1b, this.length0 - this.suffix1.length + suffix1b.length + ); else return super.appendedAll0(suffix, k); + } + } + + private static final class Vector4 extends BigVector { + + final int len1; + final Object[][] prefix2; + final int len12; + final Object[][][] prefix3; + final int len123; + final Object[][][][] data4; + final Object[][][] suffix3; + final Object[][] suffix2; + + Vector4( + Object[] prefix1, int len1, + Object[][] prefix2, int len12, + Object[][][] prefix3, int len123, + Object[][][][] data4, + Object[][][] suffix3, Object[][] suffix2, Object[] suffix1, + int length0 + ) { + super(prefix1, suffix1, length0); + this.len1 = len1; + this.prefix2 = prefix2; + this.len12 = len12; + this.prefix3 = prefix3; + this.len123 = len123; + this.data4 = data4; + this.suffix3 = suffix3; + this.suffix2 = suffix2; + } + + @Override + public A get(int i) { + if(i >= 0 && i < this.length0) { + final int io_ = i - this.len123; + if(io_ >= 0) { + final int i4 = io_ >>> BITS3; + final int i3 = (io_ >>> BITS2) & MASK; + final int i2 = (io_ >>> BITS) & MASK; + final int i1 = io_ & MASK; + if(i4 < this.data4.length) return (A) this.data4[i4][i3][i2][i1]; + else if(i3 < this.suffix3.length) return (A) this.suffix3[i3][i2][i1]; + else if(i2 < this.suffix2.length) return (A) this.suffix2[i2][i1]; + else return (A) this.suffix1[i1]; + } else if(i >= this.len12) { + final int io = i - this.len12; + return (A) this.prefix3[io >>> BITS2][(io >>> BITS) & MASK][io & MASK]; + } else if(i >= this.len1) { + final int io = i - this.len1; + return (A) this.prefix2[io >>> BITS][io & MASK]; + } else return (A) this.prefix1[i]; + } else throw ioob(i); + } + + @Override + public Vector updated(int index, A elem) { + if(index >= 0 && index < this.length0) { + if(index >= this.len123) { + final int io = index - this.len123; + final int i4 = io >>> BITS3; + final int i3 = (io >>> BITS2) & MASK; + final int i2 = (io >>> BITS) & MASK; + final int i1 = io & MASK; + if(i4 < this.data4.length) return new Vector4<>( + this.prefix1, this.len1, + this.prefix2, this.len12, + this.prefix3, this.len123, + copyUpdate(this.data4, i4, i3, i2, i1, elem), + this.suffix3, this.suffix2, this.suffix1, + this.length0 + ); else if(i3 < suffix3.length) return new Vector4<>( + this.prefix1, this.len1, + this.prefix2, this.len12, + this.prefix3, this.len123, + this.data4, + copyUpdate(this.suffix3, i3, i2, i1, elem), this.suffix2, this.suffix1, + this.length0 + ); else if(i2 < suffix2.length) return new Vector4<>( + this.prefix1, this.len1, + this.prefix2, this.len12, + this.prefix3, this.len123, + this.data4, + this.suffix3, copyUpdate(this.suffix2, i2, i1, elem), this.suffix1, + this.length0 + ); else return new Vector4<>( + this.prefix1, this.len1, + this.prefix2, this.len12, + this.prefix3, this.len123, + this.data4, + this.suffix3, this.suffix2, copyUpdate(this.suffix1, i1, elem), + this.length0 + ); + } else if(index >= this.len12) { + final int io = index - this.len12; + return new Vector4<>( + this.prefix1, this.len1, + this.prefix2, this.len12, + copyUpdate(this.prefix3,io >>> BITS2, (io >>> BITS) & MASK, io & MASK, elem), this.len123, + this.data4, + this.suffix3, this.suffix2, this.suffix1, + this.length0 + ); + } else if(index >= this.len1) { + final int io = index - this.len1; + return new Vector4<>( + this.prefix1, this.len1, + copyUpdate(this.prefix2,io >>> BITS, io & MASK, elem), this.len12, + this.prefix3, this.len123, + this.data4, + this.suffix3, this.suffix2, this.suffix1, + this.length0 + ); + } else return new Vector4<>( + copyUpdate(this.prefix1, index, elem), this.len1, + this.prefix2, this.len12, + this.prefix3, this.len123, + this.data4, + this.suffix3, this.suffix2, this.suffix1, + this.length0 + ); + } else throw ioob(index); + } + + @Override + public Vector appended(A elem) { + if(suffix1.length < WIDTH) return new Vector4<>( + this.prefix1, this.len1, this.prefix2, this.len12, this.prefix3, this.len123, this.data4, + this.suffix3, this.suffix2, copyAppend1(this.suffix1, elem), this.length0 + 1 + ); else if(suffix2.length < WIDTH - 1) return new Vector4<>( + this.prefix1, this.len1, this.prefix2, this.len12, this.prefix3, this.len123, this.data4, + this.suffix3, copyAppend(this.suffix2, this.suffix1), wrap1(elem), this.length0 + 1 + ); else if(suffix3.length < WIDTH - 1) return new Vector4<>( + this.prefix1, this.len1, this.prefix2, this.len12, this.prefix3, this.len123, this.data4, + copyAppend(this.suffix3, copyAppend(this.suffix2, this.suffix1)), empty2, wrap1(elem), this.length0 + 1 + ); else if(data4.length < WIDTH - 2) return new Vector4<>( + this.prefix1, this.len1, this.prefix2, this.len12, this.prefix3, this.len123, + copyAppend(this.data4, copyAppend(this.suffix3, copyAppend(this.suffix2, this.suffix1))), + empty3, empty2, wrap1(elem), this.length0 + 1 + ); else return new Vector5<>( + this.prefix1, this.len1, this.prefix2, this.len12, this.prefix3, this.len123, + this.data4, (WIDTH - 2) * WIDTH3 + this.len123, empty5, + wrap4(copyAppend(this.suffix3, copyAppend(this.suffix2, this.suffix1))), empty3, empty2, wrap1(elem), + this.length0 + 1 + ); + } + + @Override + public Vector prepended(A elem) { + if(this.len1 < WIDTH) return new Vector4<>( + copyPrepend1(elem, this.prefix1), this.len1 + 1, this.prefix2, this.len12 + 1, + this.prefix3, this.len123 + 1, this.data4, this.suffix3, this.suffix2, this.suffix1, + this.length0 + 1 + ); else if(this.len12 < WIDTH2) return new Vector4<>( + wrap1(elem), 1, copyPrepend(this.prefix1, this.prefix2), this.len12 + 1, + this.prefix3, this.len123 + 1, this.data4, this.suffix3, this.suffix2, this.suffix1, + this.length0 + 1 + ); else if(this.len123 < WIDTH3) return new Vector4<>( + wrap1(elem), 1, empty2, 1, + copyPrepend(copyPrepend(this.prefix1, this.prefix2), this.prefix3), this.len123 + 1, + this.data4, this.suffix3, this.suffix2, this.suffix1, + this.length0 + 1 + ); else if(this.data4.length < WIDTH - 2) return new Vector4<>( + wrap1(elem), 1, empty2, 1, empty3, 1, + copyPrepend(copyPrepend(copyPrepend(this.prefix1, this.prefix2), this.prefix3), this.data4), + this.suffix3, this.suffix2, this.suffix1, + this.length0 + 1 + ); else return new Vector5<>( + wrap1(elem), 1, empty2, 1, empty3, 1, + wrap4(copyPrepend(copyPrepend(this.prefix1, this.prefix2), this.prefix3)), this.len123 + 1, + empty5, this.data4, this.suffix3, this.suffix2, this.suffix1, this.length0 + 1 + ); + } + + @Override + public Vector map(Function f) { + return new Vector4<>( + mapElems1(this.prefix1, f), this.len1, + mapElems(2, this.prefix2, f), this.len12, + mapElems(3, this.prefix3, f), this.len123, + mapElems(4, this.data4, f), + mapElems(3, this.suffix3, f), mapElems(2, this.suffix2, f), mapElems1(this.suffix1, f), + this.length0 + ); + } + + @Override + protected Vector slice0(int lo, int hi) { + final VectorSliceBuilder b = new VectorSliceBuilder(lo, hi); + b.consider(1, this.prefix1); + b.consider(2, this.prefix2); + b.consider(3, this.prefix3); + b.consider(4, this.data4); + b.consider(3, this.suffix3); + b.consider(2, this.suffix2); + b.consider(1, this.suffix1); + return b.result(); + } + + @Override + public Vector tail() { + if(this.len1 > 1) return new Vector4<>( + copyTail(this.prefix1), this.len1 - 1, + this.prefix2, this.len12 - 1, + this.prefix3, this.len123 - 1, + this.data4, this.suffix3, this.suffix2, this.suffix1, + this.length0 - 1 + ); else return this.slice0(1, this.length0); + } + + @Override + public Vector init() { + if(this.suffix1.length > 1) return new Vector4<>( + this.prefix1, this.len1, this.prefix2, this.len12, + this.prefix3, this.len123, this.data4, + this.suffix3, this.suffix2, copyInit(this.suffix1), + this.length0 - 1 + ); else return this.slice(0, this.length0 - 1); + } + + @Override + int vectorSliceCount() { + return 7; + } + + @Override + Object[] vectorSlice(int idx) { + return switch(idx) { + case 0 -> this.prefix1; + case 1 -> this.prefix2; + case 2 -> this.prefix3; + case 3 -> this.data4; + case 4 -> this.suffix3; + case 5 -> this.suffix2; + case 6 -> this.suffix1; + default -> throw new IllegalArgumentException("slice idx " + idx); + }; + } + + @Override + int vectorSlicePrefixLength(int idx) { + return switch (idx) { + case 0 -> this.len1; + case 1 -> this.len12; + case 2 -> this.len123; + case 3 -> this.len123 + this.data4.length * WIDTH3; + case 4 -> this.len123 + this.data4.length * WIDTH3 + this.suffix3.length * WIDTH2; + case 5 -> this.length0 - this.suffix1.length; + case 6 -> this.length0; + default -> throw new IllegalArgumentException("slice idx " + idx); + }; + } + + @Override + protected Vector prependedAll0(Iterable prefix, int k) { + Object[] prefix1b = prepend1IfSpace(this.prefix1, prefix); + if(prefix1b == null) return super.prependedAll0(prefix, k); + else { + final int diff = prefix1b.length - this.prefix1.length; + return new Vector4<>( + prefix1b, this.len1 + diff, + this.prefix2, this.len12 + diff, + this.prefix3, this.len123 + diff, + this.data4, this.suffix3, this.suffix2, this.suffix1, + this.length0 + diff + ); + } + } + + @Override + protected Vector appendedAll0(Iterable suffix, int k) { + Object[] suffix1b = append1IfSpace(this.suffix1, suffix); + if(suffix1b != null) return new Vector4<>( + this.prefix1, this.len1, this.prefix2, this.len12, + this.prefix3, this.len123, this.data4, this.suffix3, this.suffix2, + suffix1b, this.length0 - this.suffix1.length + suffix1b.length + ); else return super.appendedAll0(suffix, k); + } + } + + private static final class Vector5 extends BigVector { + + final int len1; + final Object[][] prefix2; + final int len12; + final Object[][][] prefix3; + final int len123; + final Object[][][][] prefix4; + final int len1234; + final Object[][][][][] data5; + final Object[][][][] suffix4; + final Object[][][] suffix3; + final Object[][] suffix2; + + Vector5( + Object[] prefix1, int len1, + Object[][] prefix2, int len12, + Object[][][] prefix3, int len123, + Object[][][][] prefix4, int len1234, + Object[][][][][] data5, + Object[][][][] suffix4, Object[][][] suffix3, Object[][] suffix2, Object[] suffix1, + int length0 + ) { + super(prefix1, suffix1, length0); + this.len1 = len1; + this.prefix2 = prefix2; + this.len12 = len12; + this.prefix3 = prefix3; + this.len123 = len123; + this.prefix4 = prefix4; + this.len1234 = len1234; + this.data5 = data5; + this.suffix4 = suffix4; + this.suffix3 = suffix3; + this.suffix2 = suffix2; + } + + @Override + public A get(int i) { + if(i >= 0 && i < this.length0) { + final int io_ = i - this.len1234; + if(io_ >= 0) { + final int i5 = io_ >>> BITS4; + final int i4 = (io_ >>> BITS3) & MASK; + final int i3 = (io_ >>> BITS2) & MASK; + final int i2 = (io_ >>> BITS) & MASK; + final int i1 = io_ & MASK; + if(i5 < this.data5.length) return (A) this.data5[i5][i4][i3][i2][i1]; + else if(i4 < this.suffix4.length) return (A) this.suffix4[i4][i3][i2][i1]; + else if(i3 < this.suffix3.length) return (A) this.suffix3[i3][i2][i1]; + else if(i2 < this.suffix2.length) return (A) this.suffix2[i2][i1]; + else return (A) this.suffix1[i1]; + } else if(i >= this.len123) { + final int io = i - this.len123; + return (A) this.prefix4[io >>> BITS3][(io >>> BITS2) & MASK][(io >>> BITS) & MASK][io & MASK]; + } else if(i >= this.len12) { + final int io = i - this.len12; + return (A) this.prefix3[io >>> BITS2][(io >>> BITS) & MASK][io & MASK]; + } else if(i >= this.len1) { + final int io = i - this.len1; + return (A) this.prefix2[io >>> BITS][io & MASK]; + } else return (A) this.prefix1[i]; + } else throw ioob(i); + } + + @Override + public Vector updated(int index, A elem) { + if(index >= 0 && index < this.length0) { + if(index >= this.len1234) { + final int io = index - this.len1234; + final int i5 = io >>> BITS4; + final int i4 = (io >>> BITS3) & MASK; + final int i3 = (io >>> BITS2) & MASK; + final int i2 = (io >>> BITS) & MASK; + final int i1 = io & MASK; + if(i5 < this.data5.length) return new Vector5<>( + this.prefix1, this.len1, + this.prefix2, this.len12, + this.prefix3, this.len123, + this.prefix4, this.len1234, + copyUpdate(this.data5, i5, i4, i3, i2, i1, elem), + this.suffix4, this.suffix3, this.suffix2, this.suffix1, + this.length0 + ); else if(i4 < suffix4.length) return new Vector5<>( + this.prefix1, this.len1, + this.prefix2, this.len12, + this.prefix3, this.len123, + this.prefix4, this.len1234, + this.data5, + copyUpdate(this.suffix4, i4, i3, i2, i1, elem), this.suffix3, this.suffix2, this.suffix1, + this.length0 + ); else if(i3 < suffix3.length) return new Vector5<>( + this.prefix1, this.len1, + this.prefix2, this.len12, + this.prefix3, this.len123, + this.prefix4, this.len1234, + this.data5, + this.suffix4, copyUpdate(this.suffix3, i3, i2, i1, elem), this.suffix2, this.suffix1, + this.length0 + ); else if(i2 < suffix2.length) return new Vector5<>( + this.prefix1, this.len1, + this.prefix2, this.len12, + this.prefix3, this.len123, + this.prefix4, this.len1234, + this.data5, + this.suffix4, this.suffix3, copyUpdate(this.suffix2, i2, i1, elem), this.suffix1, + this.length0 + ); else return new Vector5<>( + this.prefix1, this.len1, + this.prefix2, this.len12, + this.prefix3, this.len123, + this.prefix4, this.len1234, + this.data5, + this.suffix4, this.suffix3, this.suffix2, copyUpdate(this.suffix1, i1, elem), + this.length0 + ); + } else if(index >= this.len123) { + final int io = index - this.len123; + return new Vector5<>( + this.prefix1, this.len1, + this.prefix2, this.len12, + this.prefix3, this.len123, + copyUpdate(this.prefix4,io >>> BITS3, (io >>> BITS2) & MASK, (io >>> BITS) & MASK, io & MASK, elem), this.len1234, + this.data5, + this.suffix4, this.suffix3, this.suffix2, this.suffix1, + this.length0 + ); + } else if(index >= this.len12) { + final int io = index - this.len12; + return new Vector5<>( + this.prefix1, this.len1, + this.prefix2, this.len12, + copyUpdate(this.prefix3,io >>> BITS2, (io >>> BITS) & MASK, io & MASK, elem), this.len123, + this.prefix4, this.len1234, + this.data5, + this.suffix4, this.suffix3, this.suffix2, this.suffix1, + this.length0 + ); + } else if(index >= this.len1) { + final int io = index - this.len1; + return new Vector5<>( + this.prefix1, this.len1, + copyUpdate(this.prefix2,io >>> BITS, io & MASK, elem), this.len12, + this.prefix3, this.len123, + this.prefix4, this.len1234, + this.data5, + this.suffix4, this.suffix3, this.suffix2, this.suffix1, + this.length0 + ); + } else return new Vector5<>( + copyUpdate(this.prefix1, index, elem), this.len1, + this.prefix2, this.len12, + this.prefix3, this.len123, + this.prefix4, this.len1234, + this.data5, + this.suffix4, this.suffix3, this.suffix2, this.suffix1, + this.length0 + ); + } else throw ioob(index); + } + + @Override + public Vector appended(A elem) { + if(suffix1.length < WIDTH) return new Vector5<>( + this.prefix1, this.len1, this.prefix2, this.len12, this.prefix3, this.len123, this.prefix4, this.len1234, + this.data5, this.suffix4, this.suffix3, this.suffix2, copyAppend1(this.suffix1, elem), this.length0 + 1 + ); else if(suffix2.length < WIDTH - 1) return new Vector5<>( + this.prefix1, this.len1, this.prefix2, this.len12, this.prefix3, this.len123, this.prefix4, this.len1234, + this.data5, this.suffix4, this.suffix3, copyAppend(this.suffix2, this.suffix1), wrap1(elem), this.length0 + 1 + ); else if(suffix3.length < WIDTH - 1) return new Vector5<>( + this.prefix1, this.len1, this.prefix2, this.len12, this.prefix3, this.len123, this.prefix4, this.len1234, + this.data5, this.suffix4, + copyAppend(this.suffix3, copyAppend(this.suffix2, this.suffix1)), empty2, wrap1(elem), this.length0 + 1 + ); else if(suffix4.length < WIDTH - 1) return new Vector5<>( + this.prefix1, this.len1, this.prefix2, this.len12, this.prefix3, this.len123, this.prefix4, this.len1234, this.data5, + copyAppend(this.suffix4, copyAppend(this.suffix3, copyAppend(this.suffix2, this.suffix1))), empty3, empty2, wrap1(elem), + this.length0 + 1 + ); else if(data5.length < WIDTH - 2) return new Vector5<>( + this.prefix1, this.len1, this.prefix2, this.len12, this.prefix3, this.len123, this.prefix4, this.len1234, + copyAppend(this.data5, copyAppend(this.suffix4, copyAppend(this.suffix3, copyAppend(this.suffix2, this.suffix1)))), + empty4, empty3, empty2, wrap1(elem), this.length0 + 1 + ); else return new Vector6<>( + this.prefix1, this.len1, this.prefix2, this.len12, this.prefix3, this.len123, this.prefix4, this.len1234, + this.data5, (WIDTH - 2) * WIDTH4 + this.len1234, empty6, + wrap5(copyAppend(this.suffix4, copyAppend(this.suffix3, copyAppend(this.suffix2, this.suffix1)))), + empty4, empty3, empty2, wrap1(elem), + this.length0 + 1 + ); + } + + @Override + public Vector prepended(A elem) { + if(this.len1 < WIDTH) return new Vector5<>( + copyPrepend1(elem, this.prefix1), this.len1 + 1, this.prefix2, this.len12 + 1, + this.prefix3, this.len123 + 1, this.prefix4, this.len1234 + 1, + this.data5, this.suffix4, this.suffix3, this.suffix2, this.suffix1, + this.length0 + 1 + ); else if(this.len12 < WIDTH2) return new Vector5<>( + wrap1(elem), 1, copyPrepend(this.prefix1, this.prefix2), this.len12 + 1, + this.prefix3, this.len123 + 1, this.prefix4, this.len1234 + 1, + this.data5, this.suffix4, this.suffix3, this.suffix2, this.suffix1, + this.length0 + 1 + ); else if(this.len123 < WIDTH3) return new Vector5<>( + wrap1(elem), 1, empty2, 1, + copyPrepend(copyPrepend(this.prefix1, this.prefix2), this.prefix3), this.len123 + 1, + this.prefix4, this.len1234 + 1, this.data5, + this.suffix4, this.suffix3, this.suffix2, this.suffix1, + this.length0 + 1 + ); else if(this.len1234 < WIDTH4) return new Vector5<>( + wrap1(elem), 1, empty2, 1, empty3, 1, + copyPrepend(copyPrepend(copyPrepend(this.prefix1, this.prefix2), this.prefix3), this.prefix4), this.len1234 + 1, + this.data5, this.suffix4, this.suffix3, this.suffix2, this.suffix1, + this.length0 + 1 + ); else if(this.data5.length < WIDTH - 2) return new Vector5<>( + wrap1(elem), 1, empty2, 1, empty3, 1, empty4, 1, + copyPrepend(copyPrepend(copyPrepend(copyPrepend(this.prefix1, this.prefix2), this.prefix3), this.prefix4), this.data5), + this.suffix4, this.suffix3, this.suffix2, this.suffix1, + this.length0 + 1 + ); else return new Vector6<>( + wrap1(elem), 1, empty2, 1, empty3, 1, empty4, 1, + wrap5(copyPrepend(copyPrepend(copyPrepend(this.prefix1, this.prefix2), this.prefix3), this.prefix4)), this.len1234 + 1, + empty6, this.data5, this.suffix4, this.suffix3, this.suffix2, this.suffix1, this.length0 + 1 + ); + } + + @Override + public Vector map(Function f) { + return new Vector5<>( + mapElems1(this.prefix1, f), this.len1, + mapElems(2, this.prefix2, f), this.len12, + mapElems(3, this.prefix3, f), this.len123, + mapElems(4, this.prefix4, f), this.len1234, + mapElems(5, this.data5, f), + mapElems(4, this.suffix4, f), mapElems(3, this.suffix3, f), mapElems(2, this.suffix2, f), mapElems1(this.suffix1, f), + this.length0 + ); + } + + @Override + protected Vector slice0(int lo, int hi) { + final VectorSliceBuilder b = new VectorSliceBuilder(lo, hi); + b.consider(1, prefix1); + b.consider(2, prefix2); + b.consider(3, prefix3); + b.consider(4, prefix4); + b.consider(5, data5); + b.consider(4, suffix4); + b.consider(3, suffix3); + b.consider(2, suffix2); + b.consider(1, suffix1); + return b.result(); + } + + @Override + public Vector tail() { + if(this.len1 > 1) return new Vector5<>( + copyTail(this.prefix1), this.len1 - 1, + this.prefix2, this.len12 - 1, + this.prefix3, this.len123 - 1, + this.prefix4, this.len1234 - 1, + this.data5, this.suffix4, this.suffix3, this.suffix2, this.suffix1, + this.length0 - 1 + ); else return this.slice0(1, this.length0); + } + + @Override + public Vector init() { + if(this.suffix1.length > 1) return new Vector5<>( + this.prefix1, this.len1, this.prefix2, this.len12, + this.prefix3, this.len123, this.prefix4, this.len1234, + this.data5, this.suffix4, this.suffix3, this.suffix2, + copyInit(this.suffix1), this.length0 - 1 + ); else return this.slice(0, this.length0 - 1); + } + + @Override + int vectorSliceCount() { + return 9; + } + + @Override + Object[] vectorSlice(int idx) { + return switch(idx) { + case 0 -> this.prefix1; + case 1 -> this.prefix2; + case 2 -> this.prefix3; + case 3 -> this.prefix4; + case 4 -> this.data5; + case 5 -> this.suffix4; + case 6 -> this.suffix3; + case 7 -> this.suffix2; + case 8 -> this.suffix1; + default -> throw new IllegalArgumentException("slice idx " + idx); + }; + } + + @Override + int vectorSlicePrefixLength(int idx) { + return switch(idx) { + case 0 -> this.len1; + case 1 -> this.len12; + case 2 -> this.len123; + case 3 -> this.len1234; + case 4 -> this.len1234 + this.data5.length * WIDTH4; + case 5 -> this.len1234 + this.data5.length * WIDTH4 + this.suffix4.length * WIDTH3; + case 6 -> this.len1234 + this.data5.length * WIDTH4 + this.suffix4.length * WIDTH3 + this.suffix3.length * WIDTH2; + case 7 -> this.length0 - this.suffix1.length; + case 8 -> this.length0; + default -> throw new IllegalArgumentException("slice idx " + idx); + }; + } + + @Override + protected Vector prependedAll0(Iterable prefix, int k) { + Object[] prefix1b = prepend1IfSpace(this.prefix1, prefix); + if(prefix1b == null) return super.prependedAll0(prefix, k); + else { + final int diff = prefix1b.length - this.prefix1.length; + return new Vector5<>( + prefix1b, this.len1 + diff, + this.prefix2, this.len12 + diff, + this.prefix3, this.len123 + diff, + this.prefix4, this.len1234 + diff, + this.data5, this.suffix4, this.suffix3, this.suffix2, this.suffix1, + this.length0 + diff + ); + } + } + + @Override + protected Vector appendedAll0(Iterable suffix, int k) { + Object[] suffix1b = append1IfSpace(this.suffix1, suffix); + if(suffix1b != null) return new Vector5<>( + this.prefix1, this.len1, this.prefix2, this.len12, + this.prefix3, this.len123, this.prefix4, this.len1234, + this.data5, this.suffix4, this.suffix3, this.suffix2, + suffix1b, this.length0 - this.suffix1.length + suffix1b.length + ); else return super.appendedAll0(suffix, k); + } + } + + private static final class Vector6 extends BigVector { + + final int len1; + final Object[][] prefix2; + final int len12; + final Object[][][] prefix3; + final int len123; + final Object[][][][] prefix4; + final int len1234; + final Object[][][][][] prefix5; + final int len12345; + final Object[][][][][][] data6; + final Object[][][][][] suffix5; + final Object[][][][] suffix4; + final Object[][][] suffix3; + final Object[][] suffix2; + + Vector6( + Object[] prefix1, int len1, + Object[][] prefix2, int len12, + Object[][][] prefix3, int len123, + Object[][][][] prefix4, int len1234, + Object[][][][][] prefix5, int len12345, + Object[][][][][][] data6, + Object[][][][][] suffix5, Object[][][][] suffix4, Object[][][] suffix3, Object[][] suffix2, Object[] suffix1, + int length0 + ) { + super(prefix1, suffix1, length0); + this.len1 = len1; + this.prefix2 = prefix2; + this.len12 = len12; + this.prefix3 = prefix3; + this.len123 = len123; + this.prefix4 = prefix4; + this.len1234 = len1234; + this.prefix5 = prefix5; + this.len12345 = len12345; + this.data6 = data6; + this.suffix5 = suffix5; + this.suffix4 = suffix4; + this.suffix3 = suffix3; + this.suffix2 = suffix2; + } + + @Override + public A get(int i) { + if(i >= 0 && i < this.length0) { + final int io_ = i - this.len12345; + if(io_ >= 0) { + final int i6 = io_ >>> BITS5; + final int i5 = (io_ >>> BITS4) & MASK; + final int i4 = (io_ >>> BITS3) & MASK; + final int i3 = (io_ >>> BITS2) & MASK; + final int i2 = (io_ >>> BITS) & MASK; + final int i1 = io_ & MASK; + if(i6 < this.data6.length) return (A) this.data6[i6][i5][i4][i3][i2][i1]; + else if(i5 < this.suffix5.length) return (A) this.suffix5[i5][i4][i3][i2][i1]; + else if(i4 < this.suffix4.length) return (A) this.suffix4[i4][i3][i2][i1]; + else if(i3 < this.suffix3.length) return (A) this.suffix3[i3][i2][i1]; + else if(i2 < this.suffix2.length) return (A) this.suffix2[i2][i1]; + else return (A) this.suffix1[i1]; + } else if(i >= this.len1234) { + final int io = i - this.len1234; + return (A) this.prefix5[io >>> BITS4][(io >>> BITS3) & MASK][(io >>> BITS2) & MASK][(io >>> BITS) & MASK][io & MASK]; + } else if(i >= this.len123) { + final int io = i - this.len123; + return (A) this.prefix4[io >>> BITS3][(io >>> BITS2) & MASK][(io >>> BITS) & MASK][io & MASK]; + } else if(i >= this.len12) { + final int io = i - this.len12; + return (A) this.prefix3[io >>> BITS2][(io >>> BITS) & MASK][io & MASK]; + } else if(i >= this.len1) { + final int io = i - this.len1; + return (A) this.prefix2[io >>> BITS][io & MASK]; + } else return (A) this.prefix1[i]; + } else throw ioob(i); + } + + @Override + public Vector updated(int index, A elem) { + if(index >= 0 && index < this.length0) { + if(index >= this.len12345) { + final int io = index - this.len12345; + final int i6 = io >>> BITS5; + final int i5 = (io >>> BITS4) & MASK; + final int i4 = (io >>> BITS3) & MASK; + final int i3 = (io >>> BITS2) & MASK; + final int i2 = (io >>> BITS) & MASK; + final int i1 = io & MASK; + if(i6 < this.data6.length) return new Vector6<>( + this.prefix1, this.len1, + this.prefix2, this.len12, + this.prefix3, this.len123, + this.prefix4, this.len1234, + this.prefix5, this.len12345, + copyUpdate(this.data6, i6, i5, i4, i3, i2, i1, elem), + this.suffix5, this.suffix4, this.suffix3, this.suffix2, this.suffix1, + this.length0 + ); else if(i5 < suffix5.length) return new Vector6<>( + this.prefix1, this.len1, + this.prefix2, this.len12, + this.prefix3, this.len123, + this.prefix4, this.len1234, + this.prefix5, this.len12345, + this.data6, + copyUpdate(this.suffix5, i5, i4, i3, i2, i1, elem), this.suffix4, this.suffix3, this.suffix2, this.suffix1, + this.length0 + ); else if(i4 < suffix4.length) return new Vector6<>( + this.prefix1, this.len1, + this.prefix2, this.len12, + this.prefix3, this.len123, + this.prefix4, this.len1234, + this.prefix5, this.len12345, + this.data6, + this.suffix5, copyUpdate(this.suffix4, i4, i3, i2, i1, elem), this.suffix3, this.suffix2, this.suffix1, + this.length0 + ); else if(i3 < suffix3.length) return new Vector6<>( + this.prefix1, this.len1, + this.prefix2, this.len12, + this.prefix3, this.len123, + this.prefix4, this.len1234, + this.prefix5, this.len12345, + this.data6, + this.suffix5, this.suffix4, copyUpdate(this.suffix3, i3, i2, i1, elem), this.suffix2, this.suffix1, + this.length0 + ); else if(i2 < suffix2.length) return new Vector6<>( + this.prefix1, this.len1, + this.prefix2, this.len12, + this.prefix3, this.len123, + this.prefix4, this.len1234, + this.prefix5, this.len12345, + this.data6, + this.suffix5, this.suffix4, this.suffix3, copyUpdate(this.suffix2, i2, i1, elem), this.suffix1, + this.length0 + ); else return new Vector6<>( + this.prefix1, this.len1, + this.prefix2, this.len12, + this.prefix3, this.len123, + this.prefix4, this.len1234, + this.prefix5, this.len12345, + this.data6, + this.suffix5, this.suffix4, this.suffix3, this.suffix2, copyUpdate(this.suffix1, i1, elem), + this.length0 + ); + } else if(index >= this.len1234) { + final int io = index - this.len1234; + return new Vector6<>( + this.prefix1, this.len1, + this.prefix2, this.len12, + this.prefix3, this.len123, + this.prefix4, this.len1234, + copyUpdate(this.prefix5, io >>> BITS4, (io >>> BITS3) & MASK, (io >>> BITS2) & MASK, (io >>> BITS) & MASK, io & MASK, elem), this.len12345, + this.data6, + this.suffix5, this.suffix4, this.suffix3, this.suffix2, this.suffix1, + this.length0 + ); + } else if(index >= this.len123) { + final int io = index - this.len123; + return new Vector6<>( + this.prefix1, this.len1, + this.prefix2, this.len12, + this.prefix3, this.len123, + copyUpdate(this.prefix4,io >>> BITS3, (io >>> BITS2) & MASK, (io >>> BITS) & MASK, io & MASK, elem), this.len1234, + this.prefix5, this.len12345, + this.data6, + this.suffix5, this.suffix4, this.suffix3, this.suffix2, this.suffix1, + this.length0 + ); + } else if(index >= this.len12) { + final int io = index - this.len12; + return new Vector6<>( + this.prefix1, this.len1, + this.prefix2, this.len12, + copyUpdate(this.prefix3,io >>> BITS2, (io >>> BITS) & MASK, io & MASK, elem), this.len123, + this.prefix4, this.len1234, + this.prefix5, this.len12345, + this.data6, + this.suffix5, this.suffix4, this.suffix3, this.suffix2, this.suffix1, + this.length0 + ); + } else if(index >= this.len1) { + final int io = index - this.len1; + return new Vector6<>( + this.prefix1, this.len1, + copyUpdate(this.prefix2,io >>> BITS, io & MASK, elem), this.len12, + this.prefix3, this.len123, + this.prefix4, this.len1234, + this.prefix5, this.len12345, + this.data6, + this.suffix5, this.suffix4, this.suffix3, this.suffix2, this.suffix1, + this.length0 + ); + } else return new Vector6<>( + copyUpdate(this.prefix1, index, elem), this.len1, + this.prefix2, this.len12, + this.prefix3, this.len123, + this.prefix4, this.len1234, + this.prefix5, this.len12345, + this.data6, + this.suffix5, this.suffix4, this.suffix3, this.suffix2, this.suffix1, + this.length0 + ); + } else throw ioob(index); + } + + @Override + public Vector appended(A elem) { + if(suffix1.length < WIDTH) return new Vector6<>( + this.prefix1, this.len1, this.prefix2, this.len12, + this.prefix3, this.len123, this.prefix4, this.len1234, + this.prefix5, this.len12345, this.data6, + this.suffix5, this.suffix4, this.suffix3, this.suffix2, + copyAppend1(this.suffix1, elem), this.length0 + 1 + ); else if(suffix2.length < WIDTH - 1) return new Vector6<>( + this.prefix1, this.len1, this.prefix2, this.len12, + this.prefix3, this.len123, this.prefix4, this.len1234, + this.prefix5, this.len12345, this.data6, + this.suffix5, this.suffix4, this.suffix3, + copyAppend(this.suffix2, this.suffix1), wrap1(elem), this.length0 + 1 + ); else if(suffix3.length < WIDTH - 1) return new Vector6<>( + this.prefix1, this.len1, this.prefix2, this.len12, + this.prefix3, this.len123, this.prefix4, this.len1234, + this.prefix5, this.len12345, this.data6, + this.suffix5, this.suffix4, + copyAppend(this.suffix3, copyAppend(this.suffix2, this.suffix1)), empty2, wrap1(elem), this.length0 + 1 + ); else if(suffix4.length < WIDTH - 1) return new Vector6<>( + this.prefix1, this.len1, this.prefix2, this.len12, + this.prefix3, this.len123, this.prefix4, this.len1234, + this.prefix5, this.len12345, this.data6, + this.suffix5, + copyAppend(this.suffix4, copyAppend(this.suffix3, copyAppend(this.suffix2, this.suffix1))), + empty3, empty2, wrap1(elem), this.length0 + 1 + ); else if(suffix5.length < WIDTH - 1) return new Vector6<>( + this.prefix1, this.len1, this.prefix2, this.len12, + this.prefix3, this.len123, this.prefix4, this.len1234, + this.prefix5, this.len12345, this.data6, + copyAppend(this.suffix5, copyAppend(this.suffix4, copyAppend(this.suffix3, copyAppend(this.suffix2, this.suffix1)))), + empty4, empty3, empty2, wrap1(elem), this.length0 + 1 + ); else if(data6.length < LASTWIDTH - 2) return new Vector6<>( + this.prefix1, this.len1, this.prefix2, this.len12, + this.prefix3, this.len123, this.prefix4, this.len1234, + this.prefix5, this.len12345, + copyAppend(this.data6, copyAppend(this.suffix5, copyAppend(this.suffix4, copyAppend(this.suffix3, copyAppend(this.suffix2, this.suffix1))))), + empty5, empty4, empty3, empty2, wrap1(elem), this.length0 + 1 + ); else throw new IllegalArgumentException(); + } + + @Override + public Vector prepended(A elem) { + if(this.len1 < WIDTH) return new Vector6<>( + copyPrepend1(elem, this.prefix1), this.len1 + 1, + this.prefix2, this.len12 + 1, + this.prefix3, this.len123 + 1, + this.prefix4, this.len1234 + 1, + this.prefix5, this.len12345 + 1, + this.data6, this.suffix5, this.suffix4, this.suffix3, this.suffix2, this.suffix1, + this.length0 + 1 + ); else if(this.len12 < WIDTH2) return new Vector6<>( + wrap1(elem), 1, + copyPrepend(this.prefix1, this.prefix2), this.len12 + 1, + this.prefix3, this.len123 + 1, + this.prefix4, this.len1234 + 1, + this.prefix5, this.len12345 + 1, + this.data6, this.suffix5, this.suffix4, this.suffix3, this.suffix2, this.suffix1, + this.length0 + 1 + ); else if(this.len123 < WIDTH3) return new Vector6<>( + wrap1(elem), 1, + empty2, 1, + copyPrepend(copyPrepend(this.prefix1, this.prefix2), this.prefix3), this.len123 + 1, + this.prefix4, this.len1234 + 1, + this.prefix5, this.len12345 + 1, + this.data6, this.suffix5, this.suffix4, this.suffix3, this.suffix2, this.suffix1, + this.length0 + 1 + ); else if(this.len1234 < WIDTH4) return new Vector6<>( + wrap1(elem), 1, + empty2, 1, + empty3, 1, + copyPrepend(copyPrepend(copyPrepend(this.prefix1, this.prefix2), this.prefix3), this.prefix4), this.len1234 + 1, + this.prefix5, this.len12345 + 1, + this.data6, this.suffix5, this.suffix4, this.suffix3, this.suffix2, this.suffix1, + this.length0 + 1 + ); else if(this.len12345 < WIDTH5) return new Vector6<>( + wrap1(elem), 1, + empty2, 1, + empty3, 1, + empty4, 1, + copyPrepend(copyPrepend(copyPrepend(copyPrepend(this.prefix1, this.prefix2), this.prefix3), this.prefix4), this.prefix5), this.len12345 + 1, + this.data6, this.suffix5, this.suffix4, this.suffix3, this.suffix2, this.suffix1, + this.length0 + 1 + ); else if(data6.length < LASTWIDTH - 2) return new Vector6<>( + wrap1(elem), 1, + empty2, 1, + empty3, 1, + empty4, 1, + empty5, 1, + copyPrepend(copyPrepend(copyPrepend(copyPrepend(copyPrepend(this.prefix1, this.prefix2), this.prefix3), this.prefix4), this.prefix5), this.data6), + this.suffix5, this.suffix4, this.suffix3, this.suffix2, this.suffix1, + this.length0 + 1 + ); else throw new IllegalArgumentException(); + } + + @Override + public Vector map(Function f) { + return new Vector6<>( + mapElems1(this.prefix1, f), this.len1, + mapElems(2, this.prefix2, f), this.len12, + mapElems(3, this.prefix3, f), this.len123, + mapElems(4, this.prefix4, f), this.len1234, + mapElems(5, this.prefix5, f), this.len12345, + mapElems(6, this.data6, f), + mapElems(5, this.suffix5, f), mapElems(4, this.suffix4, f), mapElems(3, this.suffix3, f), mapElems(2, this.suffix2, f), mapElems1(this.suffix1, f), + this.length0 + ); + } + + @Override + protected Vector slice0(int lo, int hi) { + final VectorSliceBuilder b = new VectorSliceBuilder(lo, hi); + b.consider(1, this.prefix1); + b.consider(2, this.prefix2); + b.consider(3, this.prefix3); + b.consider(4, this.prefix4); + b.consider(5, this.prefix5); + b.consider(6, this.data6); + b.consider(5, this.suffix5); + b.consider(4, this.suffix4); + b.consider(3, this.suffix3); + b.consider(2, this.suffix2); + b.consider(1, this.suffix1); + return b.result(); + } + + @Override + public Vector tail() { + if(this.len1 > 1) return new Vector6<>( + copyTail(this.prefix1), this.len1 - 1, + this.prefix2, this.len12 - 1, + this.prefix3, this.len123 - 1, + this.prefix4, this.len1234 - 1, + this.prefix5, this.len12345 - 1, + this.data6, this.suffix5, this.suffix4, this.suffix3, this.suffix2, this.suffix1, + this.length0 - 1 + ); else return this.slice0(1, this.length0); + } + + @Override + public Vector init() { + if(this.suffix1.length > 1) return new Vector6<>( + this.prefix1, this.len1, this.prefix2, this.len12, + this.prefix3, this.len123, this.prefix4, this.len1234, + this.prefix5, this.len12345, this.data6, + this.suffix5, this.suffix4, this.suffix3, this.suffix2, + copyInit(this.suffix1), this.length0 - 1 + ); else return this.slice0(0, this.length0 - 1); + } + + @Override + int vectorSliceCount() { + return 11; + } + + @Override + Object[] vectorSlice(int idx) { + return switch(idx) { + case 0 -> this.prefix1; + case 1 -> this.prefix2; + case 2 -> this.prefix3; + case 3 -> this.prefix4; + case 4 -> this.prefix5; + case 5 -> this.data6; + case 6 -> this.suffix5; + case 7 -> this.suffix4; + case 8 -> this.suffix3; + case 9 -> this.suffix2; + case 10 -> this.suffix1; + default -> throw new IllegalArgumentException("slice idx " + idx); + }; + } + + @Override + int vectorSlicePrefixLength(int idx) { + return switch(idx) { + case 0 -> this.len1; + case 1 -> this.len12; + case 2 -> this.len123; + case 3 -> this.len1234; + case 4 -> this.len12345; + case 5 -> this.len12345 + this.data6.length * WIDTH5; + case 6 -> this.len12345 + this.data6.length * WIDTH5 + this.suffix5.length * WIDTH4; + case 7 -> this.len12345 + this.data6.length * WIDTH5 + this.suffix5.length * WIDTH4 + this.suffix4.length * WIDTH3; + case 8 -> this.len12345 + this.data6.length * WIDTH5 + this.suffix5.length * WIDTH4 + this.suffix4.length * WIDTH3 + this.suffix3.length * WIDTH2; + case 9 -> this.length0 - this.suffix1.length; + case 10 -> this.length0; + default -> throw new IllegalArgumentException("slice idx " + idx); + }; + } + + @Override + protected Vector prependedAll0(Iterable prefix, int k) { + final Object[] prefix1b = prepend1IfSpace(this.prefix1, prefix); + if(prefix1b == null) return super.prependedAll0(prefix, k); + else { + final int diff = prefix1b.length - this.prefix1.length; + return new Vector6<>( + prefix1b, this.len1 + diff, + this.prefix2, this.len12 + diff, + this.prefix3, this.len123 + diff, + this.prefix4, this.len1234 + diff, + this.prefix5, this.len12345 + diff, + this.data6, this.suffix5, this.suffix4, this.suffix3, this.suffix2, this.suffix1, + this.length0 + diff + ); + } + } + + @Override + protected Vector appendedAll0(Iterable suffix, int k) { + final Object[] suffix1b = append1IfSpace(this.suffix1, suffix); + if(suffix1b != null) return new Vector6<>( + this.prefix1, this.len1, this.prefix2, this.len12, + this.prefix3, this.len123, this.prefix4, this.len1234, + this.prefix5, this.len12345, this.data6, + this.suffix5, this.suffix4, this.suffix3, this.suffix2, + suffix1b, this.length0 - this.suffix1.length + suffix1b.length + ); else return super.appendedAll0(suffix, k); + } + } + + private static final class VectorSliceBuilder { + private static int prefixIdx(int n) { + return n - 1; + } + + private static int suffixIdx(int n) { + return 11 - n; + } + + private final int lo; + private final int hi; + + private final Object[][] slices; + private int len; + private int pos; + private int maxDim; + + public VectorSliceBuilder(int lo, int hi) { + this.lo = lo; + this.hi = hi; + this.slices = new Object[11][]; + this.len = 0; + this.pos = 0; + this.maxDim = 0; + } + + public void consider(int n, T[] a) { + final int count = a.length * (1 << (BITS * (n - 1))); + final int lo0 = Math.max(this.lo - this.pos, 0); + final int hi0 = Math.min(this.hi - this.pos, count); + if(hi0 > lo0) { + this.addSlice(n, a, lo0, hi0); + this.len += (hi0 - lo0); + } + this.pos += count; + } + + private void addSlice(int n, T[] a, int lo, int hi) { + if(n == 1) { + this.add(1, copyOrUse(a, lo, hi)); + } else { + final int bitsN = BITS * (n - 1); + final int widthN = 1 << bitsN; + final int loN = lo >>> bitsN; + final int hiN = hi >>> bitsN; + final int loRest = lo & (widthN - 1); + final int hiRest = hi & (widthN - 1); + + if(loRest == 0) { + if(hiRest == 0) { + this.add(n, copyOrUse(a, loN, hiN)); + } else { + if(hiN > loN) this.add(n, copyOrUse(a, loN, hiN)); + this.addSlice(n - 1, (Object[]) a[hiN], 0, hiRest); + } + } else { + if(hiN == loN) { + this.addSlice(n - 1, (Object[]) a[loN], loRest, hiRest); + } else { + this.addSlice(n - 1, (Object[]) a[loN], loRest, widthN); + if(hiRest == 0) { + if(hiN > loN + 1) this.add(n, copyOrUse(a, loN + 1, hiN)); + } else { + if(hiN > loN + 1) this.add(n, copyOrUse(a, loN + 1, hiN)); + this.addSlice(n - 1, (Object[]) a[hiN], 0, hiRest); + } + } + } + } + } + + private void add(int n, T[] a) { + final int idx; + if(n <= maxDim) idx = suffixIdx(n); + else { + maxDim = n; + idx = prefixIdx(n); + } + this.slices[idx] = a; + } + + public Vector result() { + if(this.len <= 32) { + if(this.len == 0) return Vector0.getInstance(); + else { + final Object[] prefix1 = slices[prefixIdx(1)]; + final Object[] suffix1 = slices[suffixIdx(1)]; + final Object[] a; + if(prefix1 != null) { + if(suffix1 != null) a = concatArrays(prefix1, suffix1); + else a = prefix1; + } else if(suffix1 != null) a = suffix1; + else { + final Object[][] prefix2 = (Object[][]) slices[prefixIdx(2)]; + if(prefix2 != null) a = prefix2[0]; + else { + final Object[][] suffix2 = (Object[][]) slices[suffixIdx(2)]; + a = suffix2[0]; + } + } + return new Vector1<>(a); + } + } else { + this.balancePrefix(1); + this.balanceSuffix(1); + int resultDim = this.maxDim; + if(resultDim < 6) { + final Object[] pre = this.slices[prefixIdx(this.maxDim)]; + final Object[] suf = this.slices[suffixIdx(this.maxDim)]; + if(pre != null && suf != null) { + if(pre.length + suf.length <= WIDTH - 2) { + this.slices[prefixIdx(this.maxDim)] = concatArrays(pre, suf); + this.slices[suffixIdx(this.maxDim)] = null; + } else resultDim += 1; + } else { + final Object[] one = pre != null ? pre : suf; + if(one.length > WIDTH - 2) resultDim += 1; + } + } + final Object[] prefix1 = this.slices[prefixIdx(1)]; + final Object[] suffix1 = this.slices[suffixIdx(1)]; + final int len1 = prefix1.length; + return switch(resultDim) { + case 2 -> { + final Object[][] data2 = dataOr(2, empty2); + yield new Vector2<>(prefix1, len1, data2, suffix1, this.len); + } + case 3 -> { + final Object[][] prefix2 = prefixOr(2, empty2); + final Object[][][] data3 = dataOr(3, empty3); + final Object[][] suffix2 = suffixOr(2, empty2); + final int len12 = len1 + (prefix2.length * WIDTH); + yield new Vector3<>( + prefix1, len1, + prefix2, len12, + data3, + suffix2, suffix1, + this.len + ); + } + case 4 -> { + final Object[][] prefix2 = prefixOr(2, empty2); + final Object[][][] prefix3 = prefixOr(3, empty3); + final Object[][][][] data4 = dataOr(4, empty4); + final Object[][][] suffix3 = suffixOr(3, empty3); + final Object[][] suffix2 = suffixOr(2, empty2); + final int len12 = len1 + (prefix2.length * WIDTH); + final int len123 = len12 + (prefix3.length * WIDTH2); + yield new Vector4<>( + prefix1, len1, + prefix2, len12, + prefix3, len123, + data4, + suffix3, suffix2, suffix1, + this.len + ); + } + case 5 -> { + final Object[][] prefix2 = prefixOr(2, empty2); + final Object[][][] prefix3 = prefixOr(3, empty3); + final Object[][][][] prefix4 = prefixOr(4, empty4); + final Object[][][][][] data5 = dataOr(5, empty5); + final Object[][][][] suffix4 = suffixOr(4, empty4); + final Object[][][] suffix3 = suffixOr(3, empty3); + final Object[][] suffix2 = suffixOr(2, empty2); + final int len12 = len1 + (prefix2.length * WIDTH); + final int len123 = len12 + (prefix3.length * WIDTH2); + final int len1234 = len123 + (prefix4.length * WIDTH3); + yield new Vector5<>( + prefix1, len1, + prefix2, len12, + prefix3, len123, + prefix4, len1234, + data5, + suffix4, suffix3, suffix2, suffix1, + this.len + ); + } + case 6 -> { + final Object[][] prefix2 = prefixOr(2, empty2); + final Object[][][] prefix3 = prefixOr(3, empty3); + final Object[][][][] prefix4 = prefixOr(4, empty4); + final Object[][][][][] prefix5 = prefixOr(5, empty5); + final Object[][][][][][] data6 = dataOr(6, empty6); + final Object[][][][][] suffix5 = suffixOr(5, empty5); + final Object[][][][] suffix4 = suffixOr(4, empty4); + final Object[][][] suffix3 = suffixOr(3, empty3); + final Object[][] suffix2 = suffixOr(2, empty2); + final int len12 = len1 + (prefix2.length * WIDTH); + final int len123 = len12 + (prefix3.length * WIDTH2); + final int len1234 = len123 + (prefix4.length * WIDTH3); + final int len12345 = len1234 + (prefix5.length * WIDTH4); + yield new Vector6<>( + prefix1, len1, prefix2, len12, + prefix3, len123, prefix4, len1234, + prefix5, len12345, + data6, + suffix5, suffix4, suffix3, suffix2, suffix1, + this.len + ); + } + default -> throw new IllegalStateException("bad resultDim " + resultDim); + }; + } + } + + private T[] prefixOr(int n, T[] a) { + final Object[] p = this.slices[prefixIdx(n)]; + return p != null ? (T[]) p : a; + } + + private T[] suffixOr(int n, T[] a) { + final Object[] s = this.slices[suffixIdx(n)]; + return s != null ? (T[]) s : a; + } + + private T[] dataOr(int n, T[] a) { + final Object[] p = this.slices[prefixIdx(n)]; + if(p != null) return (T[]) p; + else { + final Object[] s = this.slices[suffixIdx(n)]; + return s != null ? (T[]) s : a; + } + } + + private void balancePrefix(int n) { + if(this.slices[prefixIdx(n)] == null) { + if(n == this.maxDim) { + this.slices[prefixIdx(n)] = this.slices[suffixIdx(n)]; + this.slices[suffixIdx(n)] = null; + } else { + this.balancePrefix(n + 1); + final Object[][] preN1 = (Object[][]) this.slices[prefixIdx(n + 1)]; + this.slices[prefixIdx(n)] = preN1[0]; + if(preN1.length == 1) { + this.slices[prefixIdx(n + 1)] = null; + if((this.maxDim == n + 1) && (this.slices[suffixIdx(n + 1)] == null)) this.maxDim = n; + } else { + this.slices[prefixIdx(n + 1)] = copyOfRange(preN1, 1, preN1.length); + } + } + } + } + + private void balanceSuffix(int n) { + if(this.slices[suffixIdx(n)] == null) { + if(n == this.maxDim) { + slices[suffixIdx(n)] = this.slices[prefixIdx(n)]; + slices[prefixIdx(n)] = null; + } else { + this.balanceSuffix(n + 1); + final Object[][] sufN1 = (Object[][]) this.slices[suffixIdx(n + 1)]; + this.slices[suffixIdx(n)] = sufN1[sufN1.length - 1]; + if(sufN1.length == 1) { + this.slices[suffixIdx(n + 1)] = null; + if((this.maxDim == n + 1) && (this.slices[prefixIdx(n + 1)] == null)) this.maxDim = n; + } else { + this.slices[suffixIdx(n + 1)] = copyOfRange(sufN1, 0, sufN1.length - 1); + } + } + } + } + } + + public static final class VectorBuilder { + private Object[][][][][][] a6; + private Object[][][][][] a5; + private Object[][][][] a4; + private Object[][][] a3; + private Object[][] a2; + private Object[] a1; + private int len1; + private int lenRest; + private int offset; + private boolean prefixIsRightAligned; + private int depth; + + public VectorBuilder() { + this.clear(); + } + + private void setLen(int i) { + this.len1 = i & MASK; + this.lenRest = i - this.len1; + } + + public int size() { + return this.len1 + this.lenRest - this.offset; + } + + public void clear() { + this.a6 = null; + this.a5 = null; + this.a4 = null; + this.a3 = null; + this.a2 = null; + this.a1 = new Object[WIDTH]; + this.len1 = 0; + this.lenRest = 0; + this.offset = 0; + this.prefixIsRightAligned = false; + this.depth = 1; + } + + void initSparse(int size, A elem) { + this.setLen(size); + Arrays.fill(this.a1, elem); + if(size > WIDTH) { + this.a2 = new Object[WIDTH][]; + Arrays.fill(this.a2, this.a1); + if(size > WIDTH2) { + this.a3 = new Object[WIDTH][][]; + Arrays.fill(this.a3, this.a2); + if(size > WIDTH3) { + this.a4 = new Object[WIDTH][][][]; + Arrays.fill(this.a4, this.a3); + if(size > WIDTH4) { + this.a5 = new Object[WIDTH][][][][]; + Arrays.fill(this.a5, this.a4); + if(size > WIDTH5) { + this.a6 = new Object[WIDTH][][][][][]; + Arrays.fill(this.a6, this.a5); + this.depth = 6; + } else this.depth = 5; + } else this.depth = 4; + } else this.depth = 3; + } else this.depth = 2; + } else this.depth = 1; + } + + void initFrom(Object[] prefix1) { + this.depth = 1; + this.setLen(prefix1.length); + this.a1 = copyOrUse(prefix1, 0, WIDTH); + if(this.len1 == 0 && this.lenRest > 0) { + this.len1 = WIDTH; + this.lenRest -= WIDTH; + } + } + + VectorBuilder initFrom(Vector v) { + switch(v.vectorSliceCount()) { + case 0 -> {} + case 1 -> { + final Vector1 v1 = (Vector1) v; + this.depth = 1; + this.setLen(v1.prefix1.length); + this.a1 = copyOrUse(v1.prefix1, 0, WIDTH); + } + case 3 -> { + final Vector2 v2 = (Vector2) v; + final Object[][] d2 = v2.data2; + this.a1 = copyOrUse(v2.suffix1, 0, WIDTH); + this.depth = 2; + this.offset = WIDTH - v2.len1; + this.setLen(v2.length0 + this.offset); + this.a2 = new Object[WIDTH][]; + this.a2[0] = v2.prefix1; + System.arraycopy(d2, 0, this.a2, 1, d2.length); + this.a2[d2.length + 1] = this.a1; + } + case 5 -> { + final Vector3 v3 = (Vector3) v; + final Object[][][] d3 = v3.data3; + final Object[][] s2 = v3.suffix2; + this.a1 = copyOrUse(v3.suffix1, 0, WIDTH); + this.depth = 3; + this.offset = WIDTH2 - v3.len12; + this.setLen(v3.length0 + this.offset); + this.a3 = new Object[WIDTH][][]; + this.a3[0] = copyPrepend(v3.prefix1, v3.prefix2); + System.arraycopy(d3, 0, this.a3, 1, d3.length); + this.a2 = copyOf(s2, WIDTH); + this.a3[d3.length + 1] = this.a2; + this.a2[s2.length] = this.a1; + } + case 7 -> { + final Vector4 v4 = (Vector4) v; + final Object[][][][] d4 = v4.data4; + final Object[][][] s3 = v4.suffix3; + final Object[][] s2 = v4.suffix2; + this.a1 = copyOrUse(v4.suffix1, 0, WIDTH); + this.depth = 4; + this.offset = WIDTH3 - v4.len123; + this.setLen(v4.length0 + this.offset); + this.a4 = new Object[WIDTH][][][]; + this.a4[0] = copyPrepend(copyPrepend(v4.prefix1, v4.prefix2), v4.prefix3); + System.arraycopy(d4, 0, this.a4, 1, d4.length); + this.a3 = copyOf(s3, WIDTH); + this.a2 = copyOf(s2, WIDTH); + this.a4[d4.length + 1] = this.a3; + this.a3[s3.length] = this.a2; + this.a2[s2.length] = this.a1; + } + case 9 -> { + final Vector5 v5 = (Vector5) v; + final Object[][][][][] d5 = v5.data5; + final Object[][][][] s4 = v5.suffix4; + final Object[][][] s3 = v5.suffix3; + final Object[][] s2 = v5.suffix2; + this.a1 = copyOrUse(v5.suffix1, 0, WIDTH); + this.depth = 5; + this.offset = WIDTH4 - v5.len1234; + this.setLen(v5.length0 + this.offset); + this.a5 = new Object[WIDTH][][][][]; + this.a5[0] = copyPrepend(copyPrepend(copyPrepend(v5.prefix1, v5.prefix2), v5.prefix3), v5.prefix4); + System.arraycopy(d5, 0, this.a5, 1, d5.length); + this.a4 = copyOf(s4, WIDTH); + this.a3 = copyOf(s3, WIDTH); + this.a2 = copyOf(s2, WIDTH); + this.a5[d5.length + 1] = this.a4; + this.a4[s4.length] = this.a3; + this.a3[s3.length] = this.a2; + this.a2[s2.length] = this.a1; + } + case 11 -> { + final Vector6 v6 = (Vector6) v; + final Object[][][][][][] d6 = v6.data6; + final Object[][][][][] s5 = v6.suffix5; + final Object[][][][] s4 = v6.suffix4; + final Object[][][] s3 = v6.suffix3; + final Object[][] s2 = v6.suffix2; + this.a1 = copyOrUse(v6.suffix1, 0, WIDTH); + this.depth = 6; + this.offset = WIDTH5 - v6.len12345; + this.setLen(v6.length0 + this.offset); + this.a6 = new Object[WIDTH][][][][][]; + this.a6[0] = copyPrepend(copyPrepend(copyPrepend(copyPrepend(v6.prefix1, v6.prefix2), v6.prefix3), v6.prefix4), v6.prefix5); + System.arraycopy(d6, 0, this.a6, 1, d6.length); + this.a5 = copyOf(s5, WIDTH); + this.a4 = copyOf(s4, WIDTH); + this.a3 = copyOf(s3, WIDTH); + this.a2 = copyOf(s2, WIDTH); + this.a6[d6.length + 1] = this.a5; + this.a5[s5.length] = this.a4; + this.a4[s4.length] = this.a3; + this.a3[s3.length] = this.a2; + this.a2[s2.length] = this.a1; + } + } + if(this.len1 == 0 && this.lenRest > 0) { + this.len1 = WIDTH; + this.lenRest -= WIDTH; + } + return this; + } + + public VectorBuilder alignTo(int before, Vector bigVector) { + if(this.len1 != 0 || this.lenRest != 0) + throw new UnsupportedOperationException("A non-empty VectorBuilder cannot be aligned retrospectively. Please call .reset() or use a new VectorBuilder."); + + final int prefixLength; + final int maxPrefixLength; + if(bigVector instanceof Vector0) { + prefixLength = 0; maxPrefixLength = 1; + } else if(bigVector instanceof Vector1) { + prefixLength = 0; maxPrefixLength = 1; + } else if(bigVector instanceof Vector2 v2) { + prefixLength = v2.len1; maxPrefixLength = WIDTH; + } else if(bigVector instanceof Vector3 v3) { + prefixLength = v3.len12; maxPrefixLength = WIDTH2; + } else if(bigVector instanceof Vector4 v4) { + prefixLength = v4.len123; maxPrefixLength = WIDTH3; + } else if(bigVector instanceof Vector5 v5) { + prefixLength = v5.len1234; maxPrefixLength = WIDTH4; + } else if(bigVector instanceof Vector6 v6) { + prefixLength = v6.len12345; maxPrefixLength = WIDTH5; + } else { + throw new IllegalStateException(); + } + + if(maxPrefixLength == 1) return this; + + final int overallPrefixLength = (before + prefixLength) % maxPrefixLength; + this.offset = (maxPrefixLength - overallPrefixLength) % maxPrefixLength; + + this.advanceN(this.offset & ~MASK); + this.len1 = this.offset & MASK; + this.prefixIsRightAligned = true; + return this; + } + + private void shrinkOffsetIfTooLarge(int width) { + final int newOffset = this.offset % width; + this.lenRest -= (offset - newOffset); + this.offset = newOffset; + } + + private void leftAlignPrefix() { + Object[] a = null; + Object[] aParent = null; + if(this.depth >= 6) { + a = this.a6; + final int i = this.offset >>> BITS5; + if(i > 0) System.arraycopy(a, i, a, 0, LASTWIDTH - i); + this.shrinkOffsetIfTooLarge(WIDTH5); + if((this.lenRest >>> BITS5) == 0) this.depth = 5; + aParent = a; + a = (Object[]) a[0]; + } + if(this.depth >= 5) { + if(a == null) a = this.a5; + final int i = (this.offset >>> BITS4) & MASK; + if(this.depth == 5) { + if(i > 0) System.arraycopy(a, i, a, 0, WIDTH - i); + this.a5 = (Object[][][][][]) a; + this.shrinkOffsetIfTooLarge(WIDTH4); + if((this.lenRest >>> BITS4) == 0) this.depth = 4; + } else { + if(i > 0) a = copyOfRange(a, i, WIDTH); + aParent[0] = a; + } + aParent = a; + a = (Object[]) a[0]; + } + if(this.depth >= 4) { + if(a == null) a = this.a4; + final int i = (this.offset >>> BITS3) & MASK; + if(this.depth == 4) { + if(i > 0) System.arraycopy(a, i, a, 0, WIDTH - i); + this.a4 = (Object[][][][]) a; + this.shrinkOffsetIfTooLarge(WIDTH3); + if((this.lenRest >>> BITS3) == 0) this.depth = 3; + } else { + if(i > 0) a = copyOfRange(a, i, WIDTH); + aParent[0] = a; + } + aParent = a; + a = (Object[]) a[0]; + } + if(this.depth >= 3) { + if(a == null) a = this.a3; + final int i = (this.offset >>> BITS2) & MASK; + if(this.depth == 3) { + if(i > 0) System.arraycopy(a, i, a, 0, WIDTH - i); + this.a3 = (Object[][][]) a; + this.shrinkOffsetIfTooLarge(WIDTH2); + if((this.lenRest >>> BITS2) == 0) this.depth = 2; + } else { + if(i > 0) a = copyOfRange(a, i, WIDTH); + aParent[0] = a; + } + aParent = a; + a = (Object[]) a[0]; + } + if(this.depth >= 2) { + if(a == null) a = this.a2; + final int i = (this.offset >>> BITS) & MASK; + if(this.depth == 2) { + if(i > 0) System.arraycopy(a, i, a, 0, WIDTH - i); + this.a2 = (Object[][]) a; + this.shrinkOffsetIfTooLarge(WIDTH); + if((this.lenRest >>> BITS) == 0) this.depth = 1; + } else { + if(i > 0) a = copyOfRange(a, i, WIDTH); + aParent[0] = a; + } + aParent = a; + a = (Object[]) a[0]; + } + if(this.depth >= 1) { + if(a == null) a = this.a1; + final int i = this.offset & MASK; + if(this.depth == 1) { + if(i > 0) System.arraycopy(a, i, a, 0, WIDTH - i); + this.a1 = (Object[]) a; + this.len1 -= this.offset; + this.offset = 0; + } else { + if(i > 0) a = copyOfRange(a, i, WIDTH); + aParent[0] = a; + } + } + this.prefixIsRightAligned = false; + } + + public VectorBuilder addOne(A elem) { + if(this.len1 == WIDTH) this.advance(); + this.a1[len1] = elem; + this.len1++; + return this; + } + + private void addArr1(Object[] data) { + final int dl = data.length; + if(dl > 0) { + if(this.len1 == WIDTH) this.advance(); + final int copy1 = Math.min(WIDTH - this.len1, dl); + final int copy2 = dl - copy1; + System.arraycopy(data, 0, this.a1, this.len1, copy1); + this.len1 += copy1; + if(copy2 > 0) { + this.advance(); + System.arraycopy(data, copy1, this.a1, 0, copy2); + this.len1 += copy2; + } + } + } + + private void addArrN(Object[] slice, int dim) { + if(slice.length == 0) return; + if(this.len1 == WIDTH) this.advance(); + + final int sl = slice.length; + switch(dim) { + case 2 -> { + final int copy1 = Math.min(((WIDTH2 - this.lenRest) >>> BITS) & MASK, sl); + final int copy2 = sl - copy1; + final int destPos = (this.lenRest >>> BITS) & MASK; + System.arraycopy((Object[][]) slice, 0, this.a2, destPos, copy1); + this.advanceN(WIDTH * copy1); + if(copy2 > 0) { + System.arraycopy((Object[][]) slice, copy1, this.a2, 0, copy2); + this.advanceN(WIDTH * copy2); + } + } + case 3 -> { + if(this.lenRest % WIDTH2 != 0) { + for(Object[][] e : (Object[][][]) slice) { + this.addArrN(e, 2); + } + } else { + final int copy1 = Math.min(((WIDTH3 - this.lenRest) >>> BITS2) & MASK, sl); + final int copy2 = sl - copy1; + final int destPos = (this.lenRest >>> BITS2) & MASK; + System.arraycopy((Object[][][]) slice, 0, this.a3, destPos, copy1); + this.advanceN(WIDTH2 * copy1); + if(copy2 > 0) { + System.arraycopy((Object[][][]) slice, copy1, this.a3, 0, copy2); + this.advanceN(WIDTH2 * copy2); + } + } + } + case 4 -> { + if(this.lenRest % WIDTH3 != 0) { + for(Object[][][] e : (Object[][][][]) slice) { + this.addArrN(e, 3); + } + } else { + final int copy1 = Math.min(((WIDTH4 - this.lenRest) >>> BITS3) & MASK, sl); + final int copy2 = sl - copy1; + final int destPos = (this.lenRest >>> BITS3) & MASK; + System.arraycopy((Object[][][][]) slice, 0, this.a4, destPos, copy1); + this.advanceN(WIDTH3 * copy1); + if(copy2 > 0) { + System.arraycopy((Object[][][][]) slice, copy1, this.a4, 0, copy2); + this.advanceN(WIDTH3 * copy2); + } + } + } + case 5 -> { + if(this.lenRest % WIDTH4 != 0) { + for(Object[][][][] e : (Object[][][][][]) slice) { + this.addArrN(e, 4); + } + } else { + final int copy1 = Math.min(((WIDTH5 - this.lenRest) >>> BITS4) & MASK, sl); + final int copy2 = sl - copy1; + final int destPos = (this.lenRest >>> BITS4) & MASK; + System.arraycopy((Object[][][][][]) slice, 0, this.a5, destPos, copy1); + this.advanceN(WIDTH4 * copy1); + if(copy2 > 0) { + System.arraycopy((Object[][][][][]) slice, copy1, this.a5, 0, copy2); + this.advanceN(WIDTH4 * copy2); + } + } + } + case 6 -> { + if(this.lenRest % WIDTH5 != 0) { + for(Object[][][][][] e : (Object[][][][][][]) slice) { + this.addArrN(e, 5); + } + } else { + final int copy1 = sl; + final int destPos = this.lenRest >>> BITS5; + if(destPos + copy1 > LASTWIDTH) + throw new IllegalArgumentException("exceeding 2^31 elements"); + System.arraycopy((Object[][][][][][]) slice, 0, this.a6, destPos, copy1); + this.advanceN(WIDTH5 * copy1); + } + } + default -> throw new IllegalArgumentException(); + } + } + + private VectorBuilder addVector(Vector xs) { + final int sliceCount = xs.vectorSliceCount(); + for(int sliceIdx = 0; sliceIdx < sliceCount; sliceIdx++) { + final Object[] slice = xs.vectorSlice(sliceIdx); + final int n = vectorSliceDim(sliceCount, sliceIdx); + if(n == 1) this.addArr1(slice); + else if(this.len1 == WIDTH || this.len1 == 0) this.addArrN(slice, n); + else foreachRec(n - 2, slice, this::addArr1); + } + return this; + } + + public VectorBuilder addAll(Iterable xs) { + if(xs instanceof Vector v) { + if(this.len1 == 0 && this.lenRest == 0 && !prefixIsRightAligned) this.initFrom(v); + else this.addVector((Vector) v); + } else { + for(A a : xs) { + this.addOne(a); + } + } + return this; + } + + private void advance() { + final int idx = this.lenRest + WIDTH; + final int xor = idx ^ this.lenRest; + this.lenRest = idx; + this.len1 = 0; + this.advance1(idx, xor); + } + + private void advanceN(int n) { + if(n > 0) { + final int idx = this.lenRest + n; + final int xor = idx ^ this.lenRest; + this.lenRest = idx; + this.len1 = 0; + this.advance1(idx, xor); + } + } + + private void advance1(int idx, int xor) { + if(xor <= 0) { + // TODO actually print stuff like Scala stdlib does + throw new IllegalStateException(); + } else if(xor < WIDTH2) { + if(this.depth <= 1) { + this.a2 = new Object[WIDTH][]; + this.a2[0] = this.a1; + this.depth = 2; + } + this.a1 = new Object[WIDTH]; + this.a2[(idx >>> BITS) & MASK] = this.a1; + } else if(xor < WIDTH3) { + if(this.depth <= 2) { + this.a3 = new Object[WIDTH][][]; + this.a3[0] = this.a2; + this.depth = 3; + } + this.a1 = new Object[WIDTH]; + this.a2 = new Object[WIDTH][]; + this.a2[(idx >>> BITS) & MASK] = this.a1; + this.a3[(idx >>> BITS2) & MASK] = this.a2; + } else if(xor < WIDTH4) { + if(this.depth <= 3) { + this.a4 = new Object[WIDTH][][][]; + this.a4[0] = this.a3; + this.depth = 4; + } + this.a1 = new Object[WIDTH]; + this.a2 = new Object[WIDTH][]; + this.a3 = new Object[WIDTH][][]; + this.a2[(idx >>> BITS) & MASK] = this.a1; + this.a3[(idx >>> BITS2) & MASK] = this.a2; + this.a4[(idx >>> BITS3) & MASK] = this.a3; + } else if(xor < WIDTH5) { + if(this.depth <= 4) { + this.a5 = new Object[WIDTH][][][][]; + this.a5[0] = this.a4; + this.depth = 5; + } + this.a1 = new Object[WIDTH]; + this.a2 = new Object[WIDTH][]; + this.a3 = new Object[WIDTH][][]; + this.a4 = new Object[WIDTH][][][]; + this.a2[(idx >>> BITS) & MASK] = this.a1; + this.a3[(idx >>> BITS2) & MASK] = this.a2; + this.a4[(idx >>> BITS3) & MASK] = this.a3; + this.a5[(idx >>> BITS4) & MASK] = this.a4; + } else { + if(this.depth <= 5) { + this.a6 = new Object[LASTWIDTH][][][][][]; + this.a6[0] = this.a5; + this.depth = 6; + } + this.a1 = new Object[WIDTH]; + this.a2 = new Object[WIDTH][]; + this.a3 = new Object[WIDTH][][]; + this.a4 = new Object[WIDTH][][][]; + this.a5 = new Object[WIDTH][][][][]; + this.a2[(idx >>> BITS) & MASK] = this.a1; + this.a3[(idx >>> BITS2) & MASK] = this.a2; + this.a4[(idx >>> BITS3) & MASK] = this.a3; + this.a5[(idx >>> BITS4) & MASK] = this.a4; + this.a6[idx >>> BITS5] = this.a5; + } + } + + public Vector result() { + if(this.prefixIsRightAligned) this.leftAlignPrefix(); + + final int len = this.len1 + this.lenRest; + final int realLen = len - this.offset; + if(realLen == 0) return Vector.empty(); + else if(len < 0) throw new IndexOutOfBoundsException("Vector cannot have negative size " + len); + else if(len <= WIDTH) { + return new Vector1<>(copyIfDifferentSize(this.a1, realLen)); + } else if(len <= WIDTH2) { + final int i1 = (len - 1) & MASK; + final int i2 = (len - 1) >>> BITS; + final Object[][] data = copyOfRange(this.a2, 1, i2); + final Object[] prefix1 = this.a2[0]; + final Object[] suffix1 = copyIfDifferentSize(this.a2[i2], i1 + 1); + return new Vector2<>(prefix1, WIDTH - this.offset, data, suffix1, realLen); + } else if(len <= WIDTH3) { + final int i1 = (len - 1) & MASK; + final int i2 = ((len - 1) >>> BITS) & MASK; + final int i3 = (len - 1) >>> BITS2; + final Object[][][] data = copyOfRange(this.a3, 1, i3); + final Object[][] prefix2 = copyTail(this.a3[0]); + final Object[] prefix1 = this.a3[0][0]; + final Object[][] suffix2 = copyOf(this.a3[i3], i2); + final Object[] suffix1 = copyIfDifferentSize(this.a3[i3][i2], i1 + 1); + final int len1 = prefix1.length; + final int len12 = len1 + prefix2.length * WIDTH; + return new Vector3<>(prefix1, len1, prefix2, len12, data, suffix2, suffix1, realLen); + } else if(len <= WIDTH4) { + final int i1 = (len - 1) & MASK; + final int i2 = ((len - 1) >>> BITS) & MASK; + final int i3 = ((len - 1) >>> BITS2) & MASK; + final int i4 = (len - 1) >>> BITS3; + final Object[][][][] data = copyOfRange(this.a4, 1, i4); + final Object[][][] prefix3 = copyTail(this.a4[0]); + final Object[][] prefix2 = copyTail(this.a4[0][0]); + final Object[] prefix1 = this.a4[0][0][0]; + final Object[][][] suffix3 = copyOf(this.a4[i4], i3); + final Object[][] suffix2 = copyOf(this.a4[i4][i3], i2); + final Object[] suffix1 = copyIfDifferentSize(this.a4[i4][i3][i2], i1 + 1); + final int len1 = prefix1.length; + final int len12 = len1 + prefix2.length * WIDTH; + final int len123 = len12 + prefix3.length * WIDTH2; + return new Vector4<>( + prefix1, len1, prefix2, len12, prefix3, len123, data, suffix3, suffix2, suffix1, realLen + ); + } else if(len <= WIDTH5) { + final int i1 = (len - 1) & MASK; + final int i2 = ((len - 1) >>> BITS) & MASK; + final int i3 = ((len - 1) >>> BITS2) & MASK; + final int i4 = ((len - 1) >>> BITS3) & MASK; + final int i5 = (len - 1) >>> BITS4; + final Object[][][][][] data = copyOfRange(this.a5, 1, i5); + final Object[][][][] prefix4 = copyTail(this.a5[0]); + final Object[][][] prefix3 = copyTail(this.a5[0][0]); + final Object[][] prefix2 = copyTail(this.a5[0][0][0]); + final Object[] prefix1 = this.a5[0][0][0][0]; + final Object[][][][] suffix4 = copyOf(this.a5[i5], i4); + final Object[][][] suffix3 = copyOf(this.a5[i5][i4], i3); + final Object[][] suffix2 = copyOf(this.a5[i5][i4][i3], i2); + final Object[] suffix1 = copyIfDifferentSize(a5[i5][i4][i3][i2], i1 + 1); + final int len1 = prefix1.length; + final int len12 = len1 + prefix2.length * WIDTH; + final int len123 = len12 + prefix3.length * WIDTH2; + final int len1234 = len123 + prefix4.length * WIDTH3; + return new Vector5<>( + prefix1, len1, prefix2, len12, prefix3, len123, prefix4, len1234, + data, suffix4, suffix3, suffix2, suffix1, realLen + ); + } else { + final int i1 = (len - 1) & MASK; + final int i2 = ((len - 1) >>> BITS) & MASK; + final int i3 = ((len - 1) >>> BITS2) & MASK; + final int i4 = ((len - 1) >>> BITS3) & MASK; + final int i5 = ((len - 1) >>> BITS4) & MASK; + final int i6 = (len - 1) >>> BITS5; + final Object[][][][][][] data = copyOfRange(this.a6, 1, i6); + final Object[][][][][] prefix5 = copyTail(this.a6[0]); + final Object[][][][] prefix4 = copyTail(this.a6[0][0]); + final Object[][][] prefix3 = copyTail(this.a6[0][0][0]); + final Object[][] prefix2 = copyTail(this.a6[0][0][0][0]); + final Object[] prefix1 = this.a6[0][0][0][0][0]; + final Object[][][][][] suffix5 = copyOf(this.a6[i6], i5); + final Object[][][][] suffix4 = copyOf(this.a6[i6][i5], i4); + final Object[][][] suffix3 = copyOf(this.a6[i6][i5][i4], i3); + final Object[][] suffix2 = copyOf(this.a6[i6][i5][i4][i3], i2); + final Object[] suffix1 = copyIfDifferentSize(this.a6[i6][i5][i4][i3][i2], i1 + 1); + final int len1 = prefix1.length; + final int len12 = len1 + prefix2.length * WIDTH; + final int len123 = len12 + prefix3.length * WIDTH2; + final int len1234 = len123 + prefix4.length * WIDTH3; + final int len12345 = len1234 + prefix5.length * WIDTH4; + return new Vector6<>( + prefix1, len1, prefix2, len12, prefix3, len123, prefix4, len1234, + prefix5, len12345, data, suffix5, suffix4, suffix3, suffix2, suffix1, + realLen + ); + } + } + + } + + private static final class NewVectorIterator implements ListIterator { + + private final Vector v; + private int totalLength; + private final int sliceCount; + + private Object[] a1; + private Object[][] a2; + private Object[][][] a3; + private Object[][][][] a4; + private Object[][][][][] a5; + private Object[][][][][][] a6; + private int a1len; + private int i1; + private int oldPos; + private int len1; + + private int sliceIdx; + private int sliceDim; + private int sliceStart; + private int sliceEnd; + + public NewVectorIterator(Vector v, int totalLength, int sliceCount) { + this.v = v; + this.totalLength = totalLength; + this.sliceCount = sliceCount; + + this.a1 = v.prefix1; + this.a2 = null; + this.a3 = null; + this.a4 = null; + this.a5 = null; + this.a6 = null; + this.a1len = this.a1.length; + this.i1 = 0; + this.oldPos = 0; + this.len1 = this.totalLength; + + this.sliceIdx = 0; + this.sliceDim = 1; + this.sliceStart = 0; + this.sliceEnd = this.a1len; + } + + @Override + public boolean hasNext() { + return this.len1 > this.i1; + } + + @Override + public A next() { + if(this.i1 == this.a1len) this.advance(); + + final Object r = this.a1[this.i1]; + this.i1++; + return (A) r; + } + + private void advanceSlice() { + if(!this.hasNext()) Collections.emptyIterator().next(); + + this.sliceIdx++; + Object[] slice = v.vectorSlice(this.sliceIdx); + while(slice.length == 0) { + this.sliceIdx++; + slice = v.vectorSlice(this.sliceIdx); + } + + this.sliceStart = this.sliceEnd; + this.sliceDim = vectorSliceDim(this.sliceCount, this.sliceIdx); + switch(this.sliceDim) { + case 1 -> this.a1 = (Object[]) slice; + case 2 -> this.a2 = (Object[][]) slice; + case 3 -> this.a3 = (Object[][][]) slice; + case 4 -> this.a4 = (Object[][][][]) slice; + case 5 -> this.a5 = (Object[][][][][]) slice; + case 6 -> this.a6 = (Object[][][][][][]) slice; + } + this.sliceEnd = this.sliceStart + slice.length * (1 << (BITS * (this.sliceDim - 1))); + if(this.sliceEnd > this.totalLength) this.sliceEnd = this.totalLength; + if(this.sliceDim > 1) this.oldPos = (1 << (BITS * this.sliceDim)) - 1; + } + + private void advance() { + final int pos = this.i1 - this.len1 + this.totalLength; + if(pos == sliceEnd) this.advanceSlice(); + if(this.sliceDim > 1) { + final int io = pos - this.sliceStart; + final int xor = this.oldPos ^ io; + this.advanceA(io, xor); + this.oldPos = io; + } + this.len1 -= this.i1; + this.a1len = Math.min(this.a1.length, this.len1); + this.i1 = 0; + } + + private void advanceA(int io, int xor) { + if(xor < WIDTH2) { + this.a1 = this.a2[(io >>> BITS) & MASK]; + } else if(xor < WIDTH3) { + this.a2 = this.a3[(io >>> BITS2) & MASK]; + this.a1 = this.a2[0]; + } else if(xor < WIDTH4) { + this.a3 = this.a4[(io >>> BITS3) & MASK]; + this.a2 = this.a3[0]; + this.a1 = this.a2[0]; + } else if(xor < WIDTH5) { + this.a4 = this.a5[(io >>> BITS4) & MASK]; + this.a3 = this.a4[0]; + this.a2 = this.a3[0]; + this.a1 = this.a2[0]; + } else { + this.a5 = this.a6[io >>> BITS5]; + this.a4 = this.a5[0]; + this.a3 = this.a4[0]; + this.a2 = this.a3[0]; + this.a1 = this.a2[0]; + } + } + + private void setA(int io, int xor) { + if(xor < WIDTH2) { + this.a1 = this.a2[(io >>> BITS) & MASK]; + } else if(xor < WIDTH3) { + this.a2 = this.a3[(io >>> BITS2) & MASK]; + this.a1 = this.a2[(io >>> BITS) & MASK]; + } else if(xor < WIDTH4) { + this.a3 = this.a4[(io >>> BITS3) & MASK]; + this.a2 = this.a3[(io >>> BITS2) & MASK]; + this.a1 = this.a2[(io >>> BITS) & MASK]; + } else if(xor < WIDTH5) { + this.a4 = this.a5[(io >>> BITS4) & MASK]; + this.a3 = this.a4[(io >>> BITS3) & MASK]; + this.a2 = this.a3[(io >>> BITS2) & MASK]; + this.a1 = this.a2[(io >>> BITS) & MASK]; + } else { + this.a5 = this.a6[io >>> BITS5]; + this.a4 = this.a5[(io >>> BITS4) & MASK]; + this.a3 = this.a4[(io >>> BITS3) & MASK]; + this.a2 = this.a3[(io >>> BITS2) & MASK]; + this.a1 = this.a2[(io >>> BITS) & MASK]; + } + } + + @Override + public int nextIndex() { + throw new UnsupportedOperationException("Not yet implemented"); + } + + @Override + public boolean hasPrevious() { + throw new UnsupportedOperationException("Not yet implemented"); + } + + @Override + public A previous() { + throw new UnsupportedOperationException("Not yet implemented"); + } + + @Override + public int previousIndex() { + throw new UnsupportedOperationException("Not yet implemented"); + } + + @Override + public void remove() { + throw new UnsupportedOperationException("Immutable collection"); + } + + @Override + public void set(A a) { + throw new UnsupportedOperationException("Immutable collection"); + } + + @Override + public void add(A a) { + throw new UnsupportedOperationException("Immutable collection"); + } + } + +} diff --git a/Common/src/main/java/at/petrak/hexcasting/common/blocks/circles/directrix/BlockBooleanDirectrix.java b/Common/src/main/java/at/petrak/hexcasting/common/blocks/circles/directrix/BlockBooleanDirectrix.java index 81306f05de..a778611513 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/blocks/circles/directrix/BlockBooleanDirectrix.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/blocks/circles/directrix/BlockBooleanDirectrix.java @@ -43,13 +43,13 @@ public BlockBooleanDirectrix(Properties properties) { @Override public ControlFlow acceptControlFlow(CastingImage imageIn, CircleCastEnv env, Direction enterDir, BlockPos pos, BlockState bs, ServerLevel world) { - var stack = new ArrayList<>(imageIn.getStack()); + var stack = imageIn.getStack(); if (stack.isEmpty()) { this.fakeThrowMishap(pos, bs, imageIn, env, new MishapBoolDirectrixEmptyStack(pos)); return new ControlFlow.Stop(); } - var last = stack.remove(stack.size() - 1); + var last = stack.last(); if (!(last instanceof BooleanIota biota)) { this.fakeThrowMishap(pos, bs, imageIn, env, @@ -62,7 +62,7 @@ public ControlFlow acceptControlFlow(CastingImage imageIn, CircleCastEnv env, Di var outputDir = biota.getBool() ? bs.getValue(FACING).getOpposite() : bs.getValue(FACING); - var imageOut = imageIn.copy(stack, imageIn.getParenCount(), imageIn.getParenthesized(), + var imageOut = imageIn.copy(stack.init(), imageIn.getParenCount(), imageIn.getParenthesized(), imageIn.getEscapeNext(), imageIn.getOpsConsumed(), imageIn.getUserData()); return new ControlFlow.Continue(imageOut, List.of(this.exitPositionFromDirection(pos, outputDir))); diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/akashic/OpAkashicRead.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/akashic/OpAkashicRead.kt index 34a28f0d26..92c5fd0328 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/akashic/OpAkashicRead.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/akashic/OpAkashicRead.kt @@ -8,13 +8,14 @@ import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.NullIota import at.petrak.hexcasting.api.casting.mishaps.MishapNoAkashicRecord import at.petrak.hexcasting.api.misc.MediaConstants +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.common.blocks.akashic.BlockAkashicRecord object OpAkashicRead : ConstMediaAction { override val argc = 2 override val mediaCost: Long = MediaConstants.DUST_UNIT - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val pos = args.getBlockPos(0, argc) val key = args.getPattern(1, argc) @@ -24,6 +25,6 @@ object OpAkashicRead : ConstMediaAction { } val datum = record.lookupPattern(pos, key, env.world) - return listOf(datum ?: NullIota()) + return Vector.from(listOf(datum ?: NullIota())) } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/akashic/OpAkashicWrite.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/akashic/OpAkashicWrite.kt index 2089965835..e64262820a 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/akashic/OpAkashicWrite.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/akashic/OpAkashicWrite.kt @@ -10,6 +10,7 @@ import at.petrak.hexcasting.api.casting.math.HexPattern import at.petrak.hexcasting.api.casting.mishaps.MishapNoAkashicRecord import at.petrak.hexcasting.api.casting.mishaps.MishapOthersName import at.petrak.hexcasting.api.misc.MediaConstants +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.common.blocks.akashic.BlockAkashicRecord import at.petrak.hexcasting.common.lib.HexSounds import net.minecraft.core.BlockPos @@ -20,12 +21,12 @@ object OpAkashicWrite : SpellAction { override val argc = 3 override fun execute( - args: List, - env: CastingEnvironment + args: Vector, + env: CastingEnvironment ): SpellAction.Result { val pos = args.getBlockPos(0, argc) val key = args.getPattern(1, argc) - val datum = args.get(2) + val datum = args[2] env.assertPosInRange(pos) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/circles/OpCircleBounds.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/circles/OpCircleBounds.kt index 777ff834f0..442f334b8b 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/circles/OpCircleBounds.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/circles/OpCircleBounds.kt @@ -6,12 +6,13 @@ import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.eval.env.CircleCastEnv import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.mishaps.circle.MishapNoSpellCircle +import at.petrak.hexcasting.api.utils.Vector import net.minecraft.world.phys.Vec3 class OpCircleBounds(val max: Boolean) : ConstMediaAction { override val argc = 0 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { if (env !is CircleCastEnv) throw MishapNoSpellCircle() val circle = env.impetus ?: throw MishapNoSpellCircle() diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/circles/OpImpetusDir.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/circles/OpImpetusDir.kt index cb231bb416..3917ece21e 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/circles/OpImpetusDir.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/circles/OpImpetusDir.kt @@ -6,6 +6,7 @@ import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.eval.env.CircleCastEnv import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.mishaps.circle.MishapNoSpellCircle +import at.petrak.hexcasting.api.utils.Vector // TODO: we now have the interesting potential to add *other* spell circle getters, like the current position // of the eval. Hmm hm hm. @@ -14,7 +15,7 @@ import at.petrak.hexcasting.api.casting.mishaps.circle.MishapNoSpellCircle object OpImpetusDir : ConstMediaAction { override val argc = 0 - override fun execute(args: List, ctx: CastingEnvironment): List { + override fun execute(args: Vector, ctx: CastingEnvironment): Vector { if (ctx !is CircleCastEnv) throw MishapNoSpellCircle() diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/circles/OpImpetusPos.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/circles/OpImpetusPos.kt index d1ca443041..d312228f33 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/circles/OpImpetusPos.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/circles/OpImpetusPos.kt @@ -6,11 +6,12 @@ import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.eval.env.CircleCastEnv import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.mishaps.circle.MishapNoSpellCircle +import at.petrak.hexcasting.api.utils.Vector object OpImpetusPos : ConstMediaAction { override val argc = 0 - override fun execute(args: List, ctx: CastingEnvironment): List { + override fun execute(args: Vector, ctx: CastingEnvironment): Vector { if (ctx !is CircleCastEnv) throw MishapNoSpellCircle() diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/eval/OpEval.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/eval/OpEval.kt index e9c9adf2a1..d8bf0c520d 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/eval/OpEval.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/eval/OpEval.kt @@ -1,6 +1,5 @@ package at.petrak.hexcasting.common.casting.actions.eval -import at.petrak.hexcasting.api.casting.SpellList import at.petrak.hexcasting.api.casting.castables.Action import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.eval.OperationResult @@ -11,16 +10,17 @@ import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation import at.petrak.hexcasting.api.casting.evaluatable import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.mishaps.MishapNotEnoughArgs +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.common.lib.hex.HexEvalSounds object OpEval : Action { override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult { - val stack = image.stack.toMutableList() - val iota = stack.removeLastOrNull() ?: throw MishapNotEnoughArgs(1, 0) + val iota = if (image.stack.isEmpty()) throw MishapNotEnoughArgs(1, 0) else image.stack.last() + val stack = image.stack.init() return exec(env, image, continuation, stack, iota) } - fun exec(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation, newStack: MutableList, iota: Iota): OperationResult { + fun exec(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation, newStack: Vector, iota: Iota): OperationResult { // also, never make a break boundary when evaluating just one pattern val instrs = evaluatable(iota, 0) val newCont = @@ -30,7 +30,7 @@ object OpEval : Action { continuation.pushFrame(FrameFinishEval) // install a break-boundary after eval } - val instrsList = instrs.map({ SpellList.LList(0, listOf(it)) }, { it }) + val instrsList = instrs.map({ Vector.from(listOf(it)) }, { it }) val frame = FrameEvaluate(instrsList, true) val image2 = image.withUsedOp().copy(stack = newStack) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/eval/OpEvalBreakable.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/eval/OpEvalBreakable.kt index f778d87356..a4595a8fb2 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/eval/OpEvalBreakable.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/eval/OpEvalBreakable.kt @@ -12,9 +12,8 @@ object OpEvalBreakable : Action { override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult { - val stack = image.stack.toMutableList() - val iota = stack.removeLastOrNull() ?: throw MishapNotEnoughArgs(1, 0) - stack.add(ContinuationIota(continuation)) + val iota = if (image.stack.isEmpty()) throw MishapNotEnoughArgs(1, 0) else image.stack.last() + val stack = image.stack.init().appended(ContinuationIota(continuation)) return OpEval.exec(env, image, continuation, stack, iota) } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/eval/OpForEach.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/eval/OpForEach.kt index bdd4f76f7a..95acfdd37c 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/eval/OpForEach.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/eval/OpForEach.kt @@ -8,21 +8,21 @@ import at.petrak.hexcasting.api.casting.eval.vm.FrameForEach import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation import at.petrak.hexcasting.api.casting.getList import at.petrak.hexcasting.api.casting.mishaps.MishapNotEnoughArgs +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.common.lib.hex.HexEvalSounds object OpForEach : Action { override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult { - val stack = image.stack.toMutableList() + var stack = image.stack if (stack.size < 2) throw MishapNotEnoughArgs(2, stack.size) val instrs = stack.getList(stack.lastIndex - 1, stack.size) val datums = stack.getList(stack.lastIndex, stack.size) - stack.removeLastOrNull() - stack.removeLastOrNull() + stack = stack.dropRight(2) - val frame = FrameForEach(datums, instrs, null, mutableListOf()) + val frame = FrameForEach(datums, instrs, null, Vector.empty()) val image2 = image.withUsedOp().copy(stack = stack) return OperationResult(image2, listOf(), continuation.pushFrame(frame), HexEvalSounds.THOTH) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/eval/OpHalt.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/eval/OpHalt.kt index 7436c26a0c..65c965ae3e 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/eval/OpHalt.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/eval/OpHalt.kt @@ -5,11 +5,12 @@ import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.eval.OperationResult import at.petrak.hexcasting.api.casting.eval.vm.CastingImage import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.common.lib.hex.HexEvalSounds object OpHalt : Action { override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult { - var newStack = image.stack.toList() + var newStack = image.stack var done = false var newCont = continuation @@ -23,7 +24,7 @@ object OpHalt : Action { // if we hit no continuation boundaries (i.e. thoth/hermes exits), we've TOTALLY cleared the itinerary... if (!done) { // bomb the stack so we exit - newStack = listOf() + newStack = Vector.empty() } val image2 = image.withUsedOp().copy(stack = newStack) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/eval/OpThanos.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/eval/OpThanos.kt index 075fa90a2b..4f4f3ccedf 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/eval/OpThanos.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/eval/OpThanos.kt @@ -12,8 +12,7 @@ import at.petrak.hexcasting.common.lib.hex.HexEvalSounds object OpThanos : Action { override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult { val opsLeft = env.maxOpCount() - image.opsConsumed - val stack = image.stack.toMutableList() - stack.add(DoubleIota(opsLeft.toDouble())) + val stack = image.stack.appended(DoubleIota(opsLeft.toDouble())) val image2 = image.withUsedOp().copy(stack = stack) return OperationResult(image2, listOf(), continuation, HexEvalSounds.NORMAL_EXECUTE) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpAppend.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpAppend.kt index 1834166ee2..5bbb2c77d5 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpAppend.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpAppend.kt @@ -5,11 +5,12 @@ import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getList import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector object OpAppend : ConstMediaAction { override val argc = 2 - override fun execute(args: List, env: CastingEnvironment): List { - val list = args.getList(0, argc).toMutableList() + override fun execute(args: Vector, env: CastingEnvironment): Vector { + val list = args.getList(0, argc) val datum = args[1] list.add(datum) return list.asActionResult diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpConcat.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpConcat.kt index 2e77b35673..6e2f79f200 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpConcat.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpConcat.kt @@ -5,11 +5,12 @@ import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getList import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector object OpConcat : ConstMediaAction { override val argc = 2 - override fun execute(args: List, env: CastingEnvironment): List { - val lhs = args.getList(0, argc).toMutableList() + override fun execute(args: Vector, env: CastingEnvironment): Vector { + val lhs = args.getList(0, argc) val rhs = args.getList(1, argc) lhs.addAll(rhs) return lhs.asActionResult diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpCons.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpCons.kt index b0ec3173fc..0bb60125da 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpCons.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpCons.kt @@ -1,17 +1,17 @@ package at.petrak.hexcasting.common.casting.actions.lists -import at.petrak.hexcasting.api.casting.SpellList import at.petrak.hexcasting.api.casting.asActionResult import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getList import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector object OpCons : ConstMediaAction { override val argc = 2 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val bottom = args.getList(0, argc) val top = args[1] - return SpellList.LPair(top, bottom).asActionResult + return bottom.prepended(top).asActionResult } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpEmptyList.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpEmptyList.kt index b3c6398128..cf1023631f 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpEmptyList.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpEmptyList.kt @@ -4,10 +4,11 @@ import at.petrak.hexcasting.api.casting.asActionResult import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector object OpEmptyList : ConstMediaAction { override val argc = 0 - override fun execute(args: List, env: CastingEnvironment): List { - return emptyList().asActionResult // sorry for taking all the easy impls, hudeler + override fun execute(args: Vector, env: CastingEnvironment): Vector { + return Vector.empty().asActionResult // sorry for taking all the easy impls, hudeler } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpIndex.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpIndex.kt index dacaa022a8..f6dfca6d97 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpIndex.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpIndex.kt @@ -6,14 +6,15 @@ import at.petrak.hexcasting.api.casting.getDouble import at.petrak.hexcasting.api.casting.getList import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.NullIota +import at.petrak.hexcasting.api.utils.Vector import kotlin.math.roundToInt object OpIndex : ConstMediaAction { override val argc = 2 - override fun execute(args: List, env: CastingEnvironment): List { - val list = args.getList(0, argc).toMutableList() + override fun execute(args: Vector, env: CastingEnvironment): Vector { + val list = args.getList(0, argc) val index = args.getDouble(1, argc) val x = list.getOrElse(index.roundToInt()) { NullIota() } - return listOf(x) + return Vector.from(listOf(x)) } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpIndexOf.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpIndexOf.kt index 98209c9b08..ddba4b084d 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpIndexOf.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpIndexOf.kt @@ -5,13 +5,14 @@ import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getList import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector object OpIndexOf : ConstMediaAction { override val argc: Int get() = 2 - override fun execute(args: List, env: CastingEnvironment): List { - val list = args.getList(0, argc).toMutableList() + override fun execute(args: Vector, env: CastingEnvironment): Vector { + val list = args.getList(0, argc) val value = args[1] return list.indexOfFirst { Iota.tolerates(value, it) }.asActionResult } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpLastNToList.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpLastNToList.kt index ffd4e3c10a..76e6587d27 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpLastNToList.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpLastNToList.kt @@ -13,18 +13,14 @@ import at.petrak.hexcasting.common.lib.hex.HexEvalSounds object OpLastNToList : Action { override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult { - val stack = image.stack.toMutableList() + var stack = image.stack if (stack.isEmpty()) throw MishapNotEnoughArgs(1, 0) - val yoinkCount = stack.takeLast(1).getPositiveIntUnderInclusive(0, stack.size - 1) - stack.removeLast() - val output = mutableListOf() - output.addAll(stack.takeLast(yoinkCount)) - for (i in 0 until yoinkCount) { - stack.removeLast() - } - stack.addAll(output.asActionResult) + val yoinkCount = stack.takeRight(1).getPositiveIntUnderInclusive(0, stack.size - 1) + stack = stack.init() + val output = stack.takeRight(yoinkCount) + stack = stack.dropRight(yoinkCount).appendedAll(output.asActionResult) val image2 = image.withUsedOp().copy(stack = stack) return OperationResult(image2, listOf(), continuation, HexEvalSounds.NORMAL_EXECUTE) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpListSize.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpListSize.kt index 0df98e1653..48286ac245 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpListSize.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpListSize.kt @@ -5,11 +5,12 @@ import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getList import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector // it's still called beancounter's distillation in my heart object OpListSize : ConstMediaAction { override val argc = 1 - override fun execute(args: List, env: CastingEnvironment): List { - return args.getList(0, argc).toList().size.asActionResult // mmm one-liner + override fun execute(args: Vector, env: CastingEnvironment): Vector { + return args.getList(0, argc).size.asActionResult // mmm one-liner } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpModifyInPlace.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpModifyInPlace.kt index f54ec91edb..b5e741bdde 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpModifyInPlace.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpModifyInPlace.kt @@ -1,19 +1,19 @@ package at.petrak.hexcasting.common.casting.actions.lists -import at.petrak.hexcasting.api.casting.SpellList import at.petrak.hexcasting.api.casting.asActionResult import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getList import at.petrak.hexcasting.api.casting.getPositiveIntUnder import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector object OpModifyInPlace : ConstMediaAction { override val argc = 3 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val list = args.getList(0, argc) - val index = args.getPositiveIntUnder(1, list.size(), argc) + val index = args.getPositiveIntUnder(1, list.size, argc) val iota = args[2] - return list.modifyAt(index) { SpellList.LPair(iota, it.cdr) }.asActionResult + return list.updated(index, iota).asActionResult } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpRemove.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpRemove.kt index 586b679eb0..81380e475c 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpRemove.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpRemove.kt @@ -6,13 +6,14 @@ import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getInt import at.petrak.hexcasting.api.casting.getList import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector object OpRemove : ConstMediaAction { override val argc: Int get() = 2 - override fun execute(args: List, env: CastingEnvironment): List { - val list = args.getList(0, argc).toMutableList() + override fun execute(args: Vector, env: CastingEnvironment): Vector { + val list = args.getList(0, argc) val index = args.getInt(1, argc) if (index < 0 || index >= list.size) return list.asActionResult diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpReverski.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpReverski.kt index ffee540359..c3a1e43e68 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpReverski.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpReverski.kt @@ -5,10 +5,11 @@ import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getList import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector object OpReverski : ConstMediaAction { override val argc = 1 - override fun execute(args: List, env: CastingEnvironment): List { - return args.getList(0, argc).toList().asReversed().asActionResult // okay kotlin kinda pogged for this + override fun execute(args: Vector, env: CastingEnvironment): Vector { + return args.getList(0, argc).reversed().asActionResult } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpSingleton.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpSingleton.kt index 41fab11ff4..ed3ca92e9c 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpSingleton.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpSingleton.kt @@ -4,10 +4,11 @@ import at.petrak.hexcasting.api.casting.asActionResult import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector object OpSingleton : ConstMediaAction { override val argc = 1 - override fun execute(args: List, env: CastingEnvironment): List { - return listOf(args[0]).asActionResult // god i love one-liners + override fun execute(args: Vector, env: CastingEnvironment): Vector { + return Vector.from(listOf(args[0])).asActionResult // god i love one-liners } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpSlice.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpSlice.kt index f83daf7614..abd6607bd5 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpSlice.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpSlice.kt @@ -6,19 +6,20 @@ import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getList import at.petrak.hexcasting.api.casting.getPositiveIntUnderInclusive import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector import kotlin.math.max import kotlin.math.min object OpSlice : ConstMediaAction { override val argc = 3 - override fun execute(args: List, env: CastingEnvironment): List { - val list = args.getList(0, argc).toList() + override fun execute(args: Vector, env: CastingEnvironment): Vector { + val list = args.getList(0, argc) val index1 = args.getPositiveIntUnderInclusive(1, list.size, argc) val index2 = args.getPositiveIntUnderInclusive(2, list.size, argc) if (index1 == index2) - return emptyList().asActionResult + return Vector.empty().asActionResult - return list.subList(min(index1, index2), max(index1, index2)).asActionResult + return list.slice(min(index1, index2), max(index1, index2)).asActionResult } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpSplat.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpSplat.kt index f35f0d8ac3..7882bab7a0 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpSplat.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpSplat.kt @@ -4,11 +4,12 @@ import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getList import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector object OpSplat : ConstMediaAction { override val argc: Int get() = 1 - override fun execute(args: List, env: CastingEnvironment): List = - args.getList(0, argc).toList() + override fun execute(args: Vector, env: CastingEnvironment): Vector = + args.getList(0, argc) } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpUnCons.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpUnCons.kt index 211e91283d..1d28837d87 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpUnCons.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpUnCons.kt @@ -6,14 +6,15 @@ import at.petrak.hexcasting.api.casting.getList import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.ListIota import at.petrak.hexcasting.api.casting.iota.NullIota +import at.petrak.hexcasting.api.utils.Vector object OpUnCons : ConstMediaAction { override val argc = 1 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val list = args.getList(0, argc) - if (list.nonEmpty) { - return listOf(ListIota(list.cdr), list.car) + if (!list.isEmpty()) { + return Vector.from(listOf(ListIota(list.tail()), list.head())) } - return listOf(args[0], NullIota()) + return Vector.from(listOf(args[0], NullIota())) } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/local/OpPeekLocal.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/local/OpPeekLocal.kt index 375b5bbcc0..cf77180ca4 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/local/OpPeekLocal.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/local/OpPeekLocal.kt @@ -12,17 +12,16 @@ import at.petrak.hexcasting.common.lib.hex.HexEvalSounds object OpPeekLocal : Action { override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult { - val stack = image.stack.toMutableList() + val stack = image.stack val rm = if (image.userData.contains(HexAPI.RAVENMIND_USERDATA)) { IotaType.deserialize(image.userData.getCompound(HexAPI.RAVENMIND_USERDATA), env.world) } else { NullIota() } - stack.add(rm) // does not mutate userdata - val image2 = image.withUsedOp().copy(stack = stack) + val image2 = image.withUsedOp().copy(stack = stack.appended(rm)) return OperationResult(image2, listOf(), continuation, HexEvalSounds.NORMAL_EXECUTE) } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/local/OpPushLocal.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/local/OpPushLocal.kt index 59c8a7e078..9f02fa2248 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/local/OpPushLocal.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/local/OpPushLocal.kt @@ -13,12 +13,12 @@ import at.petrak.hexcasting.common.lib.hex.HexIotaTypes object OpPushLocal : Action { override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult { - val stack = image.stack.toMutableList() - - if (stack.isEmpty()) + if (image.stack.isEmpty()) throw MishapNotEnoughArgs(1, 0) - val newLocal = stack.removeLast() + val stack = image.stack.init() + + val newLocal = image.stack.last() if (newLocal.type == HexIotaTypes.NULL) image.userData.remove(HexAPI.RAVENMIND_USERDATA) else diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpAbsLen.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpAbsLen.kt index b78bb09a9b..4fd5ae23ae 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpAbsLen.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpAbsLen.kt @@ -5,13 +5,14 @@ import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getNumOrVec import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector import kotlin.math.absoluteValue object OpAbsLen : ConstMediaAction { override val argc: Int get() = 1 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val x = args.getNumOrVec(0, argc) return x.map({ num -> num.absoluteValue }, { vec -> vec.length() }).asActionResult diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpAdd.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpAdd.kt index cdb1cea4d9..9e4f6e4ef2 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpAdd.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpAdd.kt @@ -5,12 +5,13 @@ import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getNumOrVec import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector object OpAdd : ConstMediaAction { override val argc: Int get() = 2 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val lhs = args.getNumOrVec(0, argc) val rhs = args.getNumOrVec(1, argc) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpCeil.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpCeil.kt index d9b7cbd6af..884d664930 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpCeil.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpCeil.kt @@ -5,15 +5,16 @@ import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getNumOrVec import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector import kotlin.math.ceil object OpCeil : ConstMediaAction { override val argc: Int get() = 1 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val value = args.getNumOrVec(0, argc) // i hate this fucking syntax what the hell is ::ceil are you a goddamn homestuck ::c - return listOf(aplKinnie(value, ::ceil)) + return Vector.from(listOf(aplKinnie(value, ::ceil))) } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpCoerceToAxial.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpCoerceToAxial.kt index 2338066fc7..c8c1ac8ac3 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpCoerceToAxial.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpCoerceToAxial.kt @@ -5,6 +5,7 @@ import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getNumOrVec import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector import net.minecraft.core.Direction import net.minecraft.world.phys.Vec3 import kotlin.math.sign @@ -13,7 +14,7 @@ object OpCoerceToAxial : ConstMediaAction { override val argc: Int get() = 1 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val value = args.getNumOrVec(0, argc) return value.map({ num -> num.sign.asActionResult diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpConstructVec.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpConstructVec.kt index 3a94ea1e54..071ea7289b 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpConstructVec.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpConstructVec.kt @@ -5,11 +5,12 @@ import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getDouble import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector import net.minecraft.world.phys.Vec3 object OpConstructVec : ConstMediaAction { override val argc = 3 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val x = args.getDouble(0, argc) val y = args.getDouble(1, argc) val z = args.getDouble(2, argc) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpDeconstructVec.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpDeconstructVec.kt index 68a979d206..f56d9a53ae 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpDeconstructVec.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpDeconstructVec.kt @@ -5,11 +5,12 @@ import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getVec3 import at.petrak.hexcasting.api.casting.iota.DoubleIota import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector object OpDeconstructVec : ConstMediaAction { override val argc = 1 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val v = args.getVec3(0, argc) - return listOf(DoubleIota(v.x), DoubleIota(v.y), DoubleIota(v.z)) + return Vector.from(listOf(DoubleIota(v.x), DoubleIota(v.y), DoubleIota(v.z))) } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpDivCross.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpDivCross.kt index f83c97b43f..be944fa2ed 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpDivCross.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpDivCross.kt @@ -6,13 +6,14 @@ import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getNumOrVec import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.mishaps.MishapDivideByZero +import at.petrak.hexcasting.api.utils.Vector import net.minecraft.world.phys.Vec3 object OpDivCross : ConstMediaAction { override val argc: Int get() = 2 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val lhs = args.getNumOrVec(0, argc) val rhs = args.getNumOrVec(1, argc) val theMishap = MishapDivideByZero.of(args[0], args[1]) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpFloor.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpFloor.kt index 761888de93..e28d46e940 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpFloor.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpFloor.kt @@ -5,14 +5,15 @@ import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getNumOrVec import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector import kotlin.math.floor object OpFloor : ConstMediaAction { override val argc: Int get() = 1 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val value = args.getNumOrVec(0, argc) - return listOf(aplKinnie(value, ::floor)) + return Vector.from(listOf(aplKinnie(value, ::floor))) } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpLog.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpLog.kt index 054debb4a4..a1427b71ed 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpLog.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpLog.kt @@ -6,13 +6,14 @@ import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getDouble import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.mishaps.MishapDivideByZero +import at.petrak.hexcasting.api.utils.Vector import kotlin.math.log object OpLog : ConstMediaAction { override val argc: Int get() = 2 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val value = args.getDouble(0, argc) val base = args.getDouble(1, argc) if (value <= 0.0 || base <= 0.0 || base == 1.0) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpModulo.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpModulo.kt index 57753f8fb4..03f63e92d3 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpModulo.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpModulo.kt @@ -6,12 +6,13 @@ import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getDouble import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.mishaps.MishapDivideByZero +import at.petrak.hexcasting.api.utils.Vector object OpModulo : ConstMediaAction { override val argc: Int get() = 2 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { // TODO: some wAckY vector operation to go in the vector x vector overload val l = args.getDouble(0, argc) val r = args.getDouble(1, argc) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpMulDot.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpMulDot.kt index fe5324ddd1..d16fe6e388 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpMulDot.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpMulDot.kt @@ -5,12 +5,13 @@ import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getNumOrVec import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector object OpMulDot : ConstMediaAction { override val argc: Int get() = 2 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val lhs = args.getNumOrVec(0, OpAdd.argc) val rhs = args.getNumOrVec(1, OpAdd.argc) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpPowProj.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpPowProj.kt index 814fca39d7..c3ec575362 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpPowProj.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpPowProj.kt @@ -6,6 +6,7 @@ import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getNumOrVec import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.mishaps.MishapDivideByZero +import at.petrak.hexcasting.api.utils.Vector import net.minecraft.world.phys.Vec3 import kotlin.math.pow @@ -13,7 +14,7 @@ object OpPowProj : ConstMediaAction { override val argc: Int get() = 2 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val lhs = args.getNumOrVec(0, OpAdd.argc) val rhs = args.getNumOrVec(1, OpAdd.argc) val theMishap = MishapDivideByZero.of(args[0], args[1], "exponent") diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpRandom.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpRandom.kt index 87853a1ecf..e3cd4a3bda 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpRandom.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpRandom.kt @@ -4,12 +4,13 @@ import at.petrak.hexcasting.api.casting.asActionResult import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector object OpRandom : ConstMediaAction { override val argc: Int get() = 0 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { return env.world.random.nextDouble().asActionResult } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpSub.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpSub.kt index e5aec943ca..b55d361848 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpSub.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/OpSub.kt @@ -5,13 +5,14 @@ import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getNumOrVec import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector import net.minecraft.world.phys.Vec3 object OpSub : ConstMediaAction { override val argc: Int get() = 2 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val lhs = args.getNumOrVec(0, OpAdd.argc) val rhs = args.getNumOrVec(1, OpAdd.argc) 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 20d317ce84..ec600dbdfb 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 @@ -8,6 +8,7 @@ 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.HexPattern +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.api.utils.asTranslatedComponent import at.petrak.hexcasting.api.utils.lightPurple import at.petrak.hexcasting.common.lib.hex.HexSpecialHandlers @@ -28,7 +29,7 @@ class SpecialHandlerNumberLiteral(val x: Double) : SpecialHandler { class InnerAction(val x: Double) : ConstMediaAction { override val argc = 0 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { return this.x.asActionResult } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/bit/OpAnd.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/bit/OpAnd.kt index 60ec2eecb8..3ece8f0f40 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/bit/OpAnd.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/bit/OpAnd.kt @@ -7,11 +7,12 @@ import at.petrak.hexcasting.api.casting.getList import at.petrak.hexcasting.api.casting.getLong import at.petrak.hexcasting.api.casting.getLongOrList import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector object OpAnd : ConstMediaAction { override val argc = 2 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val firstParam = args.getLongOrList(0, argc) return firstParam.map( diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/bit/OpNot.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/bit/OpNot.kt index 435b1706f0..7a093d7c40 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/bit/OpNot.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/bit/OpNot.kt @@ -5,11 +5,12 @@ import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getLong import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector object OpNot : ConstMediaAction { override val argc = 1 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val num = args.getLong(0, argc) return num.inv().asActionResult } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/bit/OpOr.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/bit/OpOr.kt index 220ff72468..195d5c7f73 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/bit/OpOr.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/bit/OpOr.kt @@ -7,11 +7,12 @@ import at.petrak.hexcasting.api.casting.getList import at.petrak.hexcasting.api.casting.getLong import at.petrak.hexcasting.api.casting.getLongOrList import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector object OpOr : ConstMediaAction { override val argc = 2 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val firstParam = args.getLongOrList(0, argc) return firstParam.map( @@ -21,7 +22,7 @@ object OpOr : ConstMediaAction { }, { list1 -> val list2 = args.getList(1, argc) - (list1 + list2.filter { x -> list1.none { Iota.tolerates(x, it) } }).asActionResult + (list1.appendedAll(list2.filter { x -> !list1.exists { Iota.tolerates(x, it) } })).asActionResult } ) } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/bit/OpToSet.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/bit/OpToSet.kt index 94ddcba5c1..f2068daa65 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/bit/OpToSet.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/bit/OpToSet.kt @@ -5,11 +5,12 @@ import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getList import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector object OpToSet : ConstMediaAction { override val argc = 1 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val list = args.getList(0, argc) val out = mutableListOf() @@ -19,6 +20,6 @@ object OpToSet : ConstMediaAction { } } - return out.asActionResult + return Vector.from(out).asActionResult } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/bit/OpXor.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/bit/OpXor.kt index d45323de52..96168fe804 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/bit/OpXor.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/bit/OpXor.kt @@ -7,11 +7,12 @@ import at.petrak.hexcasting.api.casting.getList import at.petrak.hexcasting.api.casting.getLong import at.petrak.hexcasting.api.casting.getLongOrList import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector object OpXor : ConstMediaAction { override val argc = 2 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val firstParam = args.getLongOrList(0, argc) return firstParam.map( @@ -23,13 +24,13 @@ object OpXor : ConstMediaAction { val list2 = args.getList(1, argc) val out = list1.filter { x1 -> - list2.none { + !list2.exists { Iota.tolerates( x1, it ) } - } + list2.filter { x2 -> list1.none { Iota.tolerates(x2, it) } } + }.appendedAll(list2.filter { x2 -> !list1.exists { Iota.tolerates(x2, it) } }) out.asActionResult } ) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/logic/OpBoolAnd.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/logic/OpBoolAnd.kt index db3e8b0e7e..e018ec209e 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/logic/OpBoolAnd.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/logic/OpBoolAnd.kt @@ -5,11 +5,12 @@ import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getBool import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector object OpBoolAnd : ConstMediaAction { override val argc = 2 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val lhs = args.getBool(0, argc) val rhs = args.getBool(1, argc) return (lhs && rhs).asActionResult diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/logic/OpBoolIf.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/logic/OpBoolIf.kt index 140de0ea4f..089eeb4262 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/logic/OpBoolIf.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/logic/OpBoolIf.kt @@ -4,14 +4,15 @@ import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getBool import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector object OpBoolIf : ConstMediaAction { override val argc = 3 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val cond = args.getBool(0, argc) val t = args[1] val f = args[2] - return listOf(if (cond) t else f) + return Vector.from(listOf(if (cond) t else f)) } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/logic/OpBoolNot.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/logic/OpBoolNot.kt index 834f498fc8..3414231427 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/logic/OpBoolNot.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/logic/OpBoolNot.kt @@ -5,11 +5,12 @@ import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getBool import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector object OpBoolNot : ConstMediaAction { override val argc = 1 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val b = args.getBool(0, argc) return (!b).asActionResult } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/logic/OpBoolOr.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/logic/OpBoolOr.kt index 7c2123b159..b837c8f2c6 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/logic/OpBoolOr.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/logic/OpBoolOr.kt @@ -5,11 +5,12 @@ import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getBool import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector object OpBoolOr : ConstMediaAction { override val argc = 2 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val lhs = args.getBool(0, argc) val rhs = args.getBool(1, argc) return (lhs || rhs).asActionResult diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/logic/OpBoolToNumber.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/logic/OpBoolToNumber.kt index cc3902893c..153f5e67af 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/logic/OpBoolToNumber.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/logic/OpBoolToNumber.kt @@ -5,11 +5,12 @@ import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getBool import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector object OpBoolToNumber : ConstMediaAction { override val argc = 1 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val arg = args.getBool(0, argc) return (if (arg) 1.0 else 0.0).asActionResult } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/logic/OpBoolXor.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/logic/OpBoolXor.kt index 5c1af93652..17c9ecf96b 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/logic/OpBoolXor.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/logic/OpBoolXor.kt @@ -5,11 +5,12 @@ import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getBool import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector object OpBoolXor : ConstMediaAction { override val argc = 2 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val lhs = args.getBool(0, argc) val rhs = args.getBool(1, argc) return (lhs xor rhs).asActionResult diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/logic/OpCoerceToBool.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/logic/OpCoerceToBool.kt index d9996457be..dfea551993 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/logic/OpCoerceToBool.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/logic/OpCoerceToBool.kt @@ -4,11 +4,12 @@ import at.petrak.hexcasting.api.casting.asActionResult import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector object OpCoerceToBool : ConstMediaAction { override val argc = 1 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { return (args[0].isTruthy).asActionResult } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/logic/OpCompare.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/logic/OpCompare.kt index 98c479aa6e..b70fc35a3a 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/logic/OpCompare.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/logic/OpCompare.kt @@ -6,12 +6,13 @@ import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getDouble import at.petrak.hexcasting.api.casting.iota.DoubleIota import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector import java.util.function.BiPredicate class OpCompare(val acceptsEqual: Boolean, val cmp: BiPredicate) : ConstMediaAction { override val argc = 2 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val lhs = args.getDouble(0, argc) val rhs = args.getDouble(1, argc) if (DoubleIota.tolerates(lhs, rhs)) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/logic/OpEquality.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/logic/OpEquality.kt index 2dcc9f1961..a60ec52cf4 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/logic/OpEquality.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/logic/OpEquality.kt @@ -4,11 +4,12 @@ import at.petrak.hexcasting.api.casting.asActionResult import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector class OpEquality(val invert: Boolean) : ConstMediaAction { override val argc = 2 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val lhs = args[0] val rhs = args[1] diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/trig/OpArcCos.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/trig/OpArcCos.kt index 49dce7e697..2313a3cadc 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/trig/OpArcCos.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/trig/OpArcCos.kt @@ -5,13 +5,14 @@ import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getDoubleBetween import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector import kotlin.math.acos object OpArcCos : ConstMediaAction { override val argc: Int get() = 1 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val value = args.getDoubleBetween(0, -1.0, 1.0, argc) return acos(value).asActionResult } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/trig/OpArcSin.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/trig/OpArcSin.kt index 49e82a21df..1b06f8cc69 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/trig/OpArcSin.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/trig/OpArcSin.kt @@ -5,13 +5,14 @@ import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getDoubleBetween import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector import kotlin.math.asin object OpArcSin : ConstMediaAction { override val argc: Int get() = 1 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val value = args.getDoubleBetween(0, -1.0, 1.0, OpArcCos.argc) return asin(value).asActionResult } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/trig/OpArcTan.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/trig/OpArcTan.kt index 45b07c6ea5..6e1cd91fa5 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/trig/OpArcTan.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/trig/OpArcTan.kt @@ -5,13 +5,14 @@ import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getDouble import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector import kotlin.math.atan object OpArcTan : ConstMediaAction { override val argc: Int get() = 1 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val value = args.getDouble(0, argc) return atan(value).asActionResult } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/trig/OpArcTan2.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/trig/OpArcTan2.kt index 6418ccfa5e..b841a8dc53 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/trig/OpArcTan2.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/trig/OpArcTan2.kt @@ -5,13 +5,14 @@ import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getDouble import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector import kotlin.math.atan2 object OpArcTan2 : ConstMediaAction { override val argc: Int get() = 2 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val y = args.getDouble(0, argc) val x = args.getDouble(1, argc) return atan2(y, x).asActionResult diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/trig/OpCos.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/trig/OpCos.kt index 7411c3b8ad..62123e81e7 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/trig/OpCos.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/trig/OpCos.kt @@ -5,13 +5,14 @@ import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getDouble import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector import kotlin.math.cos object OpCos : ConstMediaAction { override val argc: Int get() = 1 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val angle = args.getDouble(0, argc) return cos(angle).asActionResult } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/trig/OpSin.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/trig/OpSin.kt index de67f35c65..698ff3a7ed 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/trig/OpSin.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/trig/OpSin.kt @@ -5,13 +5,14 @@ import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getDouble import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector import kotlin.math.sin object OpSin : ConstMediaAction { override val argc: Int get() = 1 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val angle = args.getDouble(0, argc) return sin(angle).asActionResult } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/trig/OpTan.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/trig/OpTan.kt index b6b7687276..22fb52a8a2 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/trig/OpTan.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/math/trig/OpTan.kt @@ -7,6 +7,7 @@ import at.petrak.hexcasting.api.casting.getDouble import at.petrak.hexcasting.api.casting.iota.DoubleIota import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.mishaps.MishapDivideByZero +import at.petrak.hexcasting.api.utils.Vector import kotlin.math.cos import kotlin.math.tan @@ -14,7 +15,7 @@ object OpTan : ConstMediaAction { override val argc: Int get() = 1 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val angle = args.getDouble(0, argc) if (cos(angle) == 0.0) throw MishapDivideByZero.tan(args[0] as DoubleIota) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpCanEntityHexFly.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpCanEntityHexFly.kt index 8e79bd84da..8de3c979f6 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpCanEntityHexFly.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpCanEntityHexFly.kt @@ -5,12 +5,13 @@ import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getPlayer import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.xplat.IXplatAbstractions object OpCanEntityHexFly : ConstMediaAction { override val argc = 1 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val player = args.getPlayer(0, argc) env.assertEntityInRange(player) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpEntityHeight.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpEntityHeight.kt index 5e84528387..8d239a152e 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpEntityHeight.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpEntityHeight.kt @@ -5,11 +5,12 @@ import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getEntity import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector object OpEntityHeight : ConstMediaAction { override val argc = 1 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val e = args.getEntity(0, argc) env.assertEntityInRange(e) return e.bbHeight.asActionResult diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpEntityLook.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpEntityLook.kt index 23e47e9076..db973441dd 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpEntityLook.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpEntityLook.kt @@ -5,11 +5,12 @@ import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getEntity import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector object OpEntityLook : ConstMediaAction { override val argc = 1 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val e = args.getEntity(0, argc) env.assertEntityInRange(e) return e.lookAngle.asActionResult diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpEntityPos.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpEntityPos.kt index 06a6e1cb36..5d756d0ebc 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpEntityPos.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpEntityPos.kt @@ -5,11 +5,12 @@ import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getEntity import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector class OpEntityPos(val feet: Boolean) : ConstMediaAction { override val argc = 1 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val e = args.getEntity(0, argc) env.assertEntityInRange(e) return (if (this.feet) e.position() else e.eyePosition).asActionResult diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpEntityVelocity.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpEntityVelocity.kt index 8ce1097d56..abbdbcb51f 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpEntityVelocity.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpEntityVelocity.kt @@ -6,11 +6,12 @@ import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getEntity import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector object OpEntityVelocity : ConstMediaAction { override val argc = 1 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val e = args.getEntity(0, argc) env.assertEntityInRange(e) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/raycast/OpBlockAxisRaycast.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/raycast/OpBlockAxisRaycast.kt index 2aa68ecf28..faf6b1ef83 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/raycast/OpBlockAxisRaycast.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/raycast/OpBlockAxisRaycast.kt @@ -8,6 +8,7 @@ import at.petrak.hexcasting.api.casting.getVec3 import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.NullIota import at.petrak.hexcasting.api.misc.MediaConstants +import at.petrak.hexcasting.api.utils.Vector import net.minecraft.world.level.ClipContext import net.minecraft.world.phys.HitResult import net.minecraft.world.phys.Vec3 @@ -15,7 +16,7 @@ import net.minecraft.world.phys.Vec3 object OpBlockAxisRaycast : ConstMediaAction { override val argc = 2 override val mediaCost: Long = MediaConstants.DUST_UNIT / 100 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val origin = args.getVec3(0, argc) val look = args.getVec3(1, argc) @@ -35,7 +36,7 @@ object OpBlockAxisRaycast : ConstMediaAction { return if (blockHitResult.type == HitResult.Type.BLOCK && env.isVecInRange(Vec3.atCenterOf(blockHitResult.blockPos))) { blockHitResult.direction.step().asActionResult } else { - listOf(NullIota()) + Vector.from(listOf(NullIota())) } } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/raycast/OpBlockRaycast.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/raycast/OpBlockRaycast.kt index 33a2e990eb..8bdb0bbd80 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/raycast/OpBlockRaycast.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/raycast/OpBlockRaycast.kt @@ -8,6 +8,7 @@ import at.petrak.hexcasting.api.casting.getVec3 import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.NullIota import at.petrak.hexcasting.api.misc.MediaConstants +import at.petrak.hexcasting.api.utils.Vector import net.minecraft.world.level.ClipContext import net.minecraft.world.phys.HitResult import net.minecraft.world.phys.Vec3 @@ -15,7 +16,7 @@ import net.minecraft.world.phys.Vec3 object OpBlockRaycast : ConstMediaAction { override val argc = 2 override val mediaCost: Long = MediaConstants.DUST_UNIT / 100 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val origin = args.getVec3(0, argc) val look = args.getVec3(1, argc) @@ -39,7 +40,7 @@ object OpBlockRaycast : ConstMediaAction { // TODO some action that has the "weird" version? blockHitResult.blockPos.asActionResult } else { - listOf(NullIota()) + Vector.from(listOf(NullIota())) } } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/raycast/OpEntityRaycast.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/raycast/OpEntityRaycast.kt index 64ea54525a..2a24a51a9a 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/raycast/OpEntityRaycast.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/raycast/OpEntityRaycast.kt @@ -8,6 +8,7 @@ import at.petrak.hexcasting.api.casting.getVec3 import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.NullIota import at.petrak.hexcasting.api.misc.MediaConstants +import at.petrak.hexcasting.api.utils.Vector import net.minecraft.world.entity.Entity import net.minecraft.world.level.Level import net.minecraft.world.phys.AABB @@ -18,7 +19,7 @@ import java.util.function.Predicate object OpEntityRaycast : ConstMediaAction { override val argc = 2 override val mediaCost: Long = MediaConstants.DUST_UNIT / 100 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val origin = args.getVec3(0, argc) val look = args.getVec3(1, argc) val endp = Action.raycastEnd(origin, look) @@ -38,7 +39,7 @@ object OpEntityRaycast : ConstMediaAction { return if (entityHitResult != null && env.isEntityInRange(entityHitResult.entity)) { entityHitResult.entity.asActionResult } else { - listOf(NullIota()) + Vector.from(listOf(NullIota())) } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpRead.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpRead.kt index 51791b6d26..30a3eac59c 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpRead.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpRead.kt @@ -4,12 +4,13 @@ import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.mishaps.MishapBadOffhandItem +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.xplat.IXplatAbstractions object OpRead : ConstMediaAction { override val argc = 0 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val (handStack) = env.getHeldItemToOperateOn { val dataHolder = IXplatAbstractions.INSTANCE.findDataHolder(it) dataHolder != null && (dataHolder.readIota(env.world) != null || dataHolder.emptyIota() != null) @@ -28,6 +29,6 @@ object OpRead : ConstMediaAction { ?: datumHolder.emptyIota() ?: throw MishapBadOffhandItem.of(handStack, "iota.read") - return listOf(datum) + return Vector.from(listOf(datum)) } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpReadable.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpReadable.kt index d368b9d87b..743ae332d5 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpReadable.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpReadable.kt @@ -4,12 +4,13 @@ import at.petrak.hexcasting.api.casting.asActionResult import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.xplat.IXplatAbstractions object OpReadable : ConstMediaAction { override val argc = 0 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val (handStack) = env.getHeldItemToOperateOn { IXplatAbstractions.INSTANCE.findDataHolder(it) != null } ?: return false.asActionResult diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpTheCoolerRead.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpTheCoolerRead.kt index 4fd4a69f8b..a1fcf24bee 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpTheCoolerRead.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpTheCoolerRead.kt @@ -5,15 +5,16 @@ import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getEntity import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.mishaps.MishapBadEntity +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.xplat.IXplatAbstractions object OpTheCoolerRead : ConstMediaAction { override val argc = 1 override fun execute( - args: List, + args: Vector, env: CastingEnvironment - ): List { + ): Vector { val target = args.getEntity(0, argc) env.assertEntityInRange(target) @@ -24,6 +25,6 @@ object OpTheCoolerRead : ConstMediaAction { val datum = datumHolder.readIota(env.world) ?: datumHolder.emptyIota() ?: throw MishapBadEntity.of(target, "iota.read") - return listOf(datum) + return Vector.from(listOf(datum)) } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpTheCoolerReadable.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpTheCoolerReadable.kt index aa118182af..93bd66df5a 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpTheCoolerReadable.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpTheCoolerReadable.kt @@ -5,15 +5,16 @@ import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getEntity import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.xplat.IXplatAbstractions object OpTheCoolerReadable : ConstMediaAction { override val argc = 1 override fun execute( - args: List, + args: Vector, env: CastingEnvironment - ): List { + ): Vector { val target = args.getEntity(0, argc) env.assertEntityInRange(target) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpTheCoolerWritable.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpTheCoolerWritable.kt index 598ae8b145..24b861b8cc 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpTheCoolerWritable.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpTheCoolerWritable.kt @@ -6,15 +6,16 @@ import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getEntity import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.NullIota +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.xplat.IXplatAbstractions object OpTheCoolerWritable : ConstMediaAction { override val argc = 1 override fun execute( - args: List, + args: Vector, env: CastingEnvironment - ): List { + ): Vector { val target = args.getEntity(0, argc) env.assertEntityInRange(target) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpTheCoolerWrite.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpTheCoolerWrite.kt index 27e02a8f97..74bb2ef1e4 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpTheCoolerWrite.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpTheCoolerWrite.kt @@ -9,6 +9,7 @@ import at.petrak.hexcasting.api.casting.getEntity import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.mishaps.MishapBadEntity import at.petrak.hexcasting.api.casting.mishaps.MishapOthersName +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.xplat.IXplatAbstractions import net.minecraft.world.entity.item.ItemEntity import net.minecraft.world.phys.Vec3 @@ -16,7 +17,7 @@ import net.minecraft.world.phys.Vec3 object OpTheCoolerWrite : SpellAction { override val argc = 2 override fun execute( - args: List, + args: Vector, env: CastingEnvironment ): SpellAction.Result { val target = args.getEntity(0, argc) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpWritable.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpWritable.kt index f0a3d0da10..992aebf86a 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpWritable.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpWritable.kt @@ -4,12 +4,13 @@ import at.petrak.hexcasting.api.casting.asActionResult import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.xplat.IXplatAbstractions object OpWritable : ConstMediaAction { override val argc = 0 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val (handStack) = env.getHeldItemToOperateOn { val datumHolder = IXplatAbstractions.INSTANCE.findDataHolder(it) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpWrite.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpWrite.kt index 317dbc0453..7eefa41ca8 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpWrite.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpWrite.kt @@ -7,6 +7,7 @@ import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.mishaps.MishapBadOffhandItem import at.petrak.hexcasting.api.casting.mishaps.MishapOthersName +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.xplat.IXplatAbstractions import net.minecraft.server.level.ServerPlayer @@ -14,7 +15,7 @@ import net.minecraft.server.level.ServerPlayer object OpWrite : SpellAction { override val argc = 1 override fun execute( - args: List, + args: Vector, env: CastingEnvironment ): SpellAction.Result { val datum = args[0] diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/selectors/OpGetCaster.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/selectors/OpGetCaster.kt index d392927a2a..569d60ba99 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/selectors/OpGetCaster.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/selectors/OpGetCaster.kt @@ -4,11 +4,12 @@ import at.petrak.hexcasting.api.casting.asActionResult import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector object OpGetCaster : ConstMediaAction { override val argc = 0 - override fun execute(args: List, ctx: CastingEnvironment): List { + override fun execute(args: Vector, ctx: CastingEnvironment): Vector { if (ctx.castingEntity == null) return null.asActionResult diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/selectors/OpGetEntitiesBy.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/selectors/OpGetEntitiesBy.kt index 1ae7a0a1c6..a66fb93f9d 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/selectors/OpGetEntitiesBy.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/selectors/OpGetEntitiesBy.kt @@ -7,6 +7,7 @@ import at.petrak.hexcasting.api.casting.getPositiveDouble import at.petrak.hexcasting.api.casting.getVec3 import at.petrak.hexcasting.api.casting.iota.EntityIota import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector import net.minecraft.world.entity.Entity import net.minecraft.world.entity.LivingEntity import net.minecraft.world.entity.animal.Animal @@ -22,7 +23,7 @@ import java.util.function.Predicate class OpGetEntitiesBy(val checker: Predicate, val negate: Boolean) : ConstMediaAction { override val argc = 2 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val pos = args.getVec3(0, argc) val radius = args.getPositiveDouble(1, argc) env.assertVecInRange(pos) @@ -33,7 +34,7 @@ class OpGetEntitiesBy(val checker: Predicate, val negate: Boolean) : Con && it.distanceToSqr(pos) <= radius * radius && (checker.test(it) != negate) }.sortedBy { it.distanceToSqr(pos) } - return entitiesGot.map(::EntityIota).asActionResult + return Vector.from(entitiesGot).map(::EntityIota).asActionResult } companion object { diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/selectors/OpGetEntityAt.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/selectors/OpGetEntityAt.kt index 55de453738..1c459cd249 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/selectors/OpGetEntityAt.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/selectors/OpGetEntityAt.kt @@ -5,6 +5,7 @@ import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getVec3 import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector import net.minecraft.world.entity.Entity import net.minecraft.world.phys.AABB import net.minecraft.world.phys.Vec3 @@ -12,7 +13,7 @@ import java.util.function.Predicate class OpGetEntityAt(val checker: Predicate) : ConstMediaAction { override val argc = 1 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val pos = args.getVec3(0, argc) env.assertVecInRange(pos) val aabb = AABB(pos.add(Vec3(-0.5, -0.5, -0.5)), pos.add(Vec3(0.5, 0.5, 0.5))) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpAddMotion.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpAddMotion.kt index 7f45168f85..e804e38fd3 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpAddMotion.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpAddMotion.kt @@ -9,6 +9,7 @@ import at.petrak.hexcasting.api.casting.getEntity import at.petrak.hexcasting.api.casting.getVec3 import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.misc.MediaConstants +import at.petrak.hexcasting.api.utils.Vector import net.minecraft.nbt.CompoundTag import net.minecraft.world.entity.Entity import net.minecraft.world.phys.Vec3 @@ -21,7 +22,7 @@ object OpAddMotion : SpellAction { val MAX_MOTION: Double = 8192.0 override fun executeWithUserdata( - args: List, + args: Vector, env: CastingEnvironment, userData: CompoundTag ): SpellAction.Result { @@ -51,7 +52,7 @@ object OpAddMotion : SpellAction { ) } - override fun execute(args: List, env: CastingEnvironment): SpellAction.Result { + override fun execute(args: Vector, env: CastingEnvironment): SpellAction.Result { throw IllegalStateException() } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpBeep.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpBeep.kt index 74807561f3..3296605506 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpBeep.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpBeep.kt @@ -5,6 +5,7 @@ import at.petrak.hexcasting.api.casting.castables.SpellAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.misc.MediaConstants +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.common.msgs.MsgBeepS2C import at.petrak.hexcasting.xplat.IXplatAbstractions import net.minecraft.world.level.block.state.properties.NoteBlockInstrument @@ -15,7 +16,7 @@ object OpBeep : SpellAction { override val argc = 3 override fun execute( - args: List, + args: Vector, env: CastingEnvironment ): SpellAction.Result { val target = args.getVec3(0, argc) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpBlink.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpBlink.kt index f7fd817308..dce5fcb273 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpBlink.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpBlink.kt @@ -12,6 +12,7 @@ import at.petrak.hexcasting.api.casting.mishaps.MishapImmuneEntity import at.petrak.hexcasting.api.misc.MediaConstants import at.petrak.hexcasting.api.mod.HexConfig import at.petrak.hexcasting.api.mod.HexTags +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.common.casting.actions.spells.great.OpTeleport import net.minecraft.world.entity.Entity import kotlin.math.absoluteValue @@ -20,7 +21,7 @@ import kotlin.math.roundToLong object OpBlink : SpellAction { override val argc = 2 override fun execute( - args: List, + args: Vector, env: CastingEnvironment ): SpellAction.Result { val target = args.getEntity(0, argc) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpBreakBlock.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpBreakBlock.kt index 796e82ccd0..fcc770fec9 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpBreakBlock.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpBreakBlock.kt @@ -9,6 +9,7 @@ import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.misc.MediaConstants import at.petrak.hexcasting.api.mod.HexConfig import at.petrak.hexcasting.api.mod.HexTags +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.xplat.IXplatAbstractions import net.minecraft.core.BlockPos import net.minecraft.server.level.ServerPlayer @@ -19,7 +20,7 @@ object OpBreakBlock : SpellAction { get() = 1 override fun execute( - args: List, + args: Vector, env: CastingEnvironment ): SpellAction.Result { val vecPos = args.getVec3(0, argc) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpColorize.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpColorize.kt index ba4c407c4a..3e8c343e33 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpColorize.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpColorize.kt @@ -7,6 +7,7 @@ import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.mishaps.MishapBadOffhandItem import at.petrak.hexcasting.api.misc.MediaConstants import at.petrak.hexcasting.api.pigment.FrozenPigment +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.xplat.IXplatAbstractions import net.minecraft.Util import net.minecraft.world.item.ItemStack @@ -15,7 +16,7 @@ object OpColorize : SpellAction { override val argc = 0 override fun execute( - args: List, + args: Vector, env: CastingEnvironment ): SpellAction.Result { val (handStack) = env.getHeldItemToOperateOn(IXplatAbstractions.INSTANCE::isPigment) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpConjureBlock.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpConjureBlock.kt index b77d7dd06a..981f670625 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpConjureBlock.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpConjureBlock.kt @@ -8,6 +8,7 @@ import at.petrak.hexcasting.api.casting.getVec3 import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.mishaps.MishapBadBlock import at.petrak.hexcasting.api.misc.MediaConstants +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.common.blocks.BlockConjured import at.petrak.hexcasting.common.lib.HexBlocks import at.petrak.hexcasting.xplat.IXplatAbstractions @@ -21,7 +22,7 @@ import net.minecraft.world.phys.Vec3 class OpConjureBlock(val light: Boolean) : SpellAction { override val argc = 1 override fun execute( - args: List, + args: Vector, env: CastingEnvironment ): SpellAction.Result { val vecPos = args.getVec3(0, argc) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpCreateFluid.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpCreateFluid.kt index 46c0662619..68cf3cce8a 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpCreateFluid.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpCreateFluid.kt @@ -7,6 +7,7 @@ import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getVec3 import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.mishaps.MishapBadLocation +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.xplat.IXplatAbstractions import net.minecraft.core.BlockPos import net.minecraft.server.level.ServerPlayer @@ -21,7 +22,7 @@ import net.minecraft.world.phys.Vec3 class OpCreateFluid(val cost: Long, val bucket: Item, val cauldron: BlockState, val fluid: Fluid) : SpellAction { override val argc = 1 override fun execute( - args: List, + args: Vector, env: CastingEnvironment ): SpellAction.Result { val vecPos = args.getVec3(0, argc) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpCycleVariant.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpCycleVariant.kt index e49e6e70af..20f57f427b 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpCycleVariant.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpCycleVariant.kt @@ -6,13 +6,14 @@ import at.petrak.hexcasting.api.casting.castables.SpellAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.mishaps.MishapBadOffhandItem +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.xplat.IXplatAbstractions import net.minecraft.world.item.ItemStack object OpCycleVariant : SpellAction { override val argc = 0 - override fun execute(args: List, env: CastingEnvironment): SpellAction.Result { + override fun execute(args: Vector, env: CastingEnvironment): SpellAction.Result { val (handStack) = env.getHeldItemToOperateOn { IXplatAbstractions.INSTANCE.findVariantHolder(it) != null } ?: throw MishapBadOffhandItem.of(ItemStack.EMPTY.copy(), "variant") // TODO: hack diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpDestroyFluid.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpDestroyFluid.kt index 73b1ac569f..cfed87ea08 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpDestroyFluid.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpDestroyFluid.kt @@ -8,6 +8,7 @@ import at.petrak.hexcasting.api.casting.getVec3 import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.misc.MediaConstants import at.petrak.hexcasting.api.mod.HexTags +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.xplat.IXplatAbstractions import net.minecraft.core.BlockPos import net.minecraft.core.Direction @@ -23,7 +24,7 @@ import net.minecraft.world.phys.Vec3 object OpDestroyFluid : SpellAction { override val argc = 1 override fun execute( - args: List, + args: Vector, env: CastingEnvironment ): SpellAction.Result { val vecPos = args.getVec3(0, argc) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpEdifySapling.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpEdifySapling.kt index 415d4c2a13..dd32bf00b0 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpEdifySapling.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpEdifySapling.kt @@ -8,6 +8,7 @@ import at.petrak.hexcasting.api.casting.getVec3 import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.mishaps.MishapBadBlock import at.petrak.hexcasting.api.misc.MediaConstants +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.common.misc.AkashicTreeGrower import at.petrak.hexcasting.xplat.IXplatAbstractions import net.minecraft.core.BlockPos @@ -19,7 +20,7 @@ object OpEdifySapling : SpellAction { override val argc = 1 override fun execute( - args: List, + args: Vector, env: CastingEnvironment ): SpellAction.Result { val vecPos = args.getVec3(0, argc) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpErase.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpErase.kt index 85fc913276..f9b2e2695f 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpErase.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpErase.kt @@ -6,6 +6,7 @@ import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.mishaps.MishapBadOffhandItem import at.petrak.hexcasting.api.misc.MediaConstants +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.xplat.IXplatAbstractions import net.minecraft.world.item.ItemStack @@ -13,7 +14,7 @@ object OpErase : SpellAction { override val argc = 0 override fun execute( - args: List, + args: Vector, env: CastingEnvironment ): SpellAction.Result { val (handStack) = env.getHeldItemToOperateOn { diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpExplode.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpExplode.kt index 0bed07989c..a819969750 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpExplode.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpExplode.kt @@ -8,6 +8,7 @@ import at.petrak.hexcasting.api.casting.getPositiveDoubleUnderInclusive import at.petrak.hexcasting.api.casting.getVec3 import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.misc.MediaConstants +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.common.casting.actions.selectors.OpGetEntitiesBy import net.minecraft.core.BlockPos import net.minecraft.util.Mth @@ -20,7 +21,7 @@ class OpExplode(val fire: Boolean) : SpellAction { get() = 2 override fun execute( - args: List, + args: Vector, env: CastingEnvironment ): SpellAction.Result { var pos = args.getVec3(0, argc) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpExtinguish.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpExtinguish.kt index 0d731159dd..28a4c29f00 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpExtinguish.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpExtinguish.kt @@ -7,6 +7,7 @@ import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getVec3 import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.misc.MediaConstants +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.ktxt.UseOnContext import at.petrak.hexcasting.xplat.IXplatAbstractions import net.minecraft.core.BlockPos @@ -25,7 +26,7 @@ import net.minecraft.world.phys.Vec3 object OpExtinguish : SpellAction { override val argc = 1 override fun execute( - args: List, + args: Vector, env: CastingEnvironment ): SpellAction.Result { // TODO: sho diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpFlight.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpFlight.kt index 9258cc059e..9cc89ae189 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpFlight.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpFlight.kt @@ -10,6 +10,7 @@ import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.misc.MediaConstants import at.petrak.hexcasting.api.pigment.FrozenPigment import at.petrak.hexcasting.api.player.FlightAbility +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.common.lib.HexItems import at.petrak.hexcasting.common.lib.HexSounds import at.petrak.hexcasting.xplat.IXplatAbstractions @@ -28,7 +29,7 @@ import kotlin.math.roundToLong class OpFlight(val type: Type) : SpellAction { override val argc = 2 override fun execute( - args: List, + args: Vector, env: CastingEnvironment ): SpellAction.Result { val target = args.getPlayer(0, argc) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpIgnite.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpIgnite.kt index eeb7fae5cf..e0ffe47bc5 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpIgnite.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpIgnite.kt @@ -11,6 +11,7 @@ import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.Vec3Iota import at.petrak.hexcasting.api.casting.mishaps.MishapInvalidIota import at.petrak.hexcasting.api.misc.MediaConstants +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.ktxt.UseOnContext import at.petrak.hexcasting.xplat.IXplatAbstractions import net.minecraft.core.BlockPos @@ -27,7 +28,7 @@ import net.minecraft.world.phys.Vec3 object OpIgnite : SpellAction { override val argc = 1 override fun execute( - args: List, + args: Vector, env: CastingEnvironment ): SpellAction.Result { when (val target = args[0]) { diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpMakeBattery.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpMakeBattery.kt index 5e86b23504..e5af863d11 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpMakeBattery.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpMakeBattery.kt @@ -10,6 +10,7 @@ import at.petrak.hexcasting.api.casting.mishaps.MishapBadItem import at.petrak.hexcasting.api.casting.mishaps.MishapBadOffhandItem import at.petrak.hexcasting.api.misc.MediaConstants import at.petrak.hexcasting.api.mod.HexTags +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.api.utils.extractMedia import at.petrak.hexcasting.api.utils.isMediaItem import at.petrak.hexcasting.common.items.magic.ItemMediaHolder @@ -23,7 +24,7 @@ object OpMakeBattery : SpellAction { override val argc = 1 override fun execute( - args: List, + args: Vector, env: CastingEnvironment ): SpellAction.Result { val entity = args.getItemEntity(0, argc) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpMakePackagedSpell.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpMakePackagedSpell.kt index 9420e53242..6f087d4211 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpMakePackagedSpell.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpMakePackagedSpell.kt @@ -10,6 +10,7 @@ import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.mishaps.MishapBadItem import at.petrak.hexcasting.api.casting.mishaps.MishapBadOffhandItem import at.petrak.hexcasting.api.casting.mishaps.MishapOthersName +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.api.utils.extractMedia import at.petrak.hexcasting.api.utils.isMediaItem import at.petrak.hexcasting.common.items.magic.ItemPackagedHex @@ -26,7 +27,7 @@ class OpMakePackagedSpell(val isValid: Predicate, val expectedTypeDes override val argc = 2 override fun execute( - args: List, + args: Vector, env: CastingEnvironment ): SpellAction.Result { val entity = args.getItemEntity(0, argc) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpPlaceBlock.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpPlaceBlock.kt index d16e173a21..4fcf9ceb4b 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpPlaceBlock.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpPlaceBlock.kt @@ -9,6 +9,7 @@ import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.mishaps.MishapBadBlock import at.petrak.hexcasting.api.casting.mishaps.MishapBadOffhandItem import at.petrak.hexcasting.api.misc.MediaConstants +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.xplat.IXplatAbstractions import net.minecraft.core.BlockPos import net.minecraft.core.Direction @@ -29,7 +30,7 @@ object OpPlaceBlock : SpellAction { get() = 1 override fun execute( - args: List, + args: Vector, env: CastingEnvironment ): SpellAction.Result { val pos = args.getBlockPos(0, argc) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpPotionEffect.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpPotionEffect.kt index 6f7dc5a05e..09ae24184f 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpPotionEffect.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpPotionEffect.kt @@ -4,6 +4,7 @@ import at.petrak.hexcasting.api.casting.* import at.petrak.hexcasting.api.casting.castables.SpellAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector import net.minecraft.world.effect.MobEffect import net.minecraft.world.effect.MobEffectInstance import net.minecraft.world.entity.LivingEntity @@ -18,7 +19,7 @@ class OpPotionEffect( get() = if (this.allowPotency) 3 else 2 override fun execute( - args: List, + args: Vector, env: CastingEnvironment ): SpellAction.Result { val target = args.getLivingEntityButNotArmorStand(0, argc) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpPrint.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpPrint.kt index 4fc5e565ca..52ac173f2c 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpPrint.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpPrint.kt @@ -14,14 +14,14 @@ import at.petrak.hexcasting.common.lib.hex.HexEvalSounds // TODO should this dump the whole stack object OpPrint : Action { override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult { - val stack = image.stack.toMutableList() + val stack = image.stack if (stack.isEmpty()) { throw MishapNotEnoughArgs(1, 0) } val datum = stack[stack.lastIndex] - val image2 = image.withUsedOp().copy(stack = stack) + val image2 = image.withUsedOp() return OperationResult( image2, listOf( diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpRecharge.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpRecharge.kt index 0b7fcb6dfd..169a0d343c 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpRecharge.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpRecharge.kt @@ -9,6 +9,7 @@ import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.mishaps.MishapBadItem import at.petrak.hexcasting.api.casting.mishaps.MishapBadOffhandItem import at.petrak.hexcasting.api.misc.MediaConstants +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.api.utils.extractMedia import at.petrak.hexcasting.api.utils.isMediaItem import at.petrak.hexcasting.xplat.IXplatAbstractions @@ -18,7 +19,7 @@ import net.minecraft.world.item.ItemStack object OpRecharge : SpellAction { override val argc = 1 override fun execute( - args: List, + args: Vector, env: CastingEnvironment ): SpellAction.Result { val entity = args.getItemEntity(0, argc) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpTheOnlyReasonAnyoneDownloadedPsi.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpTheOnlyReasonAnyoneDownloadedPsi.kt index 0b663b871c..0b34efac06 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpTheOnlyReasonAnyoneDownloadedPsi.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpTheOnlyReasonAnyoneDownloadedPsi.kt @@ -7,6 +7,7 @@ import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getBlockPos import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.misc.MediaConstants +import at.petrak.hexcasting.api.utils.Vector import net.minecraft.core.BlockPos import net.minecraft.core.Direction import net.minecraft.server.level.ServerPlayer @@ -21,7 +22,7 @@ import net.minecraft.world.phys.Vec3 object OpTheOnlyReasonAnyoneDownloadedPsi : SpellAction { override val argc = 1 override fun execute( - args: List, + args: Vector, env: CastingEnvironment ): SpellAction.Result { val target = args.getBlockPos(0, argc) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/great/OpAltiora.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/great/OpAltiora.kt index 515518cadc..8664d0c603 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/great/OpAltiora.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/great/OpAltiora.kt @@ -8,6 +8,7 @@ import at.petrak.hexcasting.api.casting.getPlayer import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.misc.MediaConstants import at.petrak.hexcasting.api.player.AltioraAbility +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.common.lib.HexSounds import at.petrak.hexcasting.xplat.IXplatAbstractions import net.minecraft.server.level.ServerLevel @@ -19,7 +20,7 @@ import kotlin.math.max object OpAltiora : SpellAction { override val argc = 1 - override fun execute(args: List, env: CastingEnvironment): SpellAction.Result { + override fun execute(args: Vector, env: CastingEnvironment): SpellAction.Result { val target = args.getPlayer(0, argc) env.assertEntityInRange(target) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/great/OpBrainsweep.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/great/OpBrainsweep.kt index b6325f685a..b54bbe7525 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/great/OpBrainsweep.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/great/OpBrainsweep.kt @@ -12,6 +12,7 @@ import at.petrak.hexcasting.api.casting.mishaps.MishapBadBrainsweep import at.petrak.hexcasting.api.casting.mishaps.MishapBadLocation import at.petrak.hexcasting.api.mod.HexConfig import at.petrak.hexcasting.api.mod.HexTags +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.common.recipe.BrainsweepRecipe import at.petrak.hexcasting.common.recipe.HexRecipeStuffRegistry import at.petrak.hexcasting.ktxt.tellWitnessesThatIWasMurdered @@ -32,7 +33,7 @@ object OpBrainsweep : SpellAction { override fun hasCastingSound(ctx: CastingEnvironment) = false override fun execute( - args: List, + args: Vector, env: CastingEnvironment ): SpellAction.Result { val sacrifice = args.getMob(0, argc) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/great/OpLightning.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/great/OpLightning.kt index 318b247ed4..60fe128fa6 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/great/OpLightning.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/great/OpLightning.kt @@ -8,6 +8,7 @@ import at.petrak.hexcasting.api.casting.getVec3 import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.mishaps.MishapBadLocation import at.petrak.hexcasting.api.misc.MediaConstants +import at.petrak.hexcasting.api.utils.Vector import net.minecraft.core.BlockPos import net.minecraft.world.entity.EntityType import net.minecraft.world.entity.LightningBolt @@ -17,7 +18,7 @@ object OpLightning : SpellAction { override val argc = 1 override fun execute( - args: List, + args: Vector, env: CastingEnvironment ): SpellAction.Result { val target = args.getVec3(0, argc) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/great/OpTeleport.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/great/OpTeleport.kt index c349aa0bba..3482e06f93 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/great/OpTeleport.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/great/OpTeleport.kt @@ -12,6 +12,7 @@ import at.petrak.hexcasting.api.casting.mishaps.MishapImmuneEntity import at.petrak.hexcasting.api.misc.MediaConstants import at.petrak.hexcasting.api.mod.HexConfig import at.petrak.hexcasting.api.mod.HexTags +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.common.msgs.MsgBlinkS2C import at.petrak.hexcasting.xplat.IXplatAbstractions import net.minecraft.core.BlockPos @@ -28,7 +29,7 @@ import net.minecraft.world.phys.Vec3 object OpTeleport : SpellAction { override val argc = 2 override fun execute( - args: List, + args: Vector, env: CastingEnvironment ): SpellAction.Result { diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/great/OpWeather.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/great/OpWeather.kt index ba648970cf..b7444fc204 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/great/OpWeather.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/great/OpWeather.kt @@ -5,12 +5,13 @@ import at.petrak.hexcasting.api.casting.castables.SpellAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.misc.MediaConstants +import at.petrak.hexcasting.api.utils.Vector class OpWeather(val rain: Boolean) : SpellAction { override val argc = 0 override fun execute( - args: List, + args: Vector, env: CastingEnvironment ): SpellAction.Result { return SpellAction.Result( diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/sentinel/OpCreateSentinel.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/sentinel/OpCreateSentinel.kt index 3b45740587..01806c9ebe 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/sentinel/OpCreateSentinel.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/sentinel/OpCreateSentinel.kt @@ -9,6 +9,7 @@ import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.mishaps.MishapBadCaster import at.petrak.hexcasting.api.misc.MediaConstants import at.petrak.hexcasting.api.player.Sentinel +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.xplat.IXplatAbstractions import net.minecraft.server.level.ServerPlayer import net.minecraft.world.phys.Vec3 @@ -17,7 +18,7 @@ class OpCreateSentinel(val extendsRange: Boolean) : SpellAction { override val argc = 1 override fun execute( - args: List, + args: Vector, env: CastingEnvironment ): SpellAction.Result { if (env.castingEntity !is ServerPlayer) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/sentinel/OpDestroySentinel.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/sentinel/OpDestroySentinel.kt index 43785a2adb..cee7a49a38 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/sentinel/OpDestroySentinel.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/sentinel/OpDestroySentinel.kt @@ -8,13 +8,14 @@ import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.mishaps.MishapBadCaster import at.petrak.hexcasting.api.casting.mishaps.MishapLocationInWrongDimension import at.petrak.hexcasting.api.misc.MediaConstants +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.xplat.IXplatAbstractions import net.minecraft.server.level.ServerPlayer object OpDestroySentinel : SpellAction { override val argc = 0 override fun execute( - args: List, + args: Vector, env: CastingEnvironment ): SpellAction.Result { if (env.castingEntity !is ServerPlayer) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/sentinel/OpGetSentinelPos.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/sentinel/OpGetSentinelPos.kt index fa56812ca5..e7ae73b18b 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/sentinel/OpGetSentinelPos.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/sentinel/OpGetSentinelPos.kt @@ -8,17 +8,18 @@ import at.petrak.hexcasting.api.casting.iota.NullIota import at.petrak.hexcasting.api.casting.mishaps.MishapBadCaster import at.petrak.hexcasting.api.casting.mishaps.MishapLocationInWrongDimension import at.petrak.hexcasting.api.misc.MediaConstants +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.xplat.IXplatAbstractions import net.minecraft.server.level.ServerPlayer object OpGetSentinelPos : ConstMediaAction { override val argc = 0 override val mediaCost: Long = MediaConstants.DUST_UNIT / 10 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { if (env.castingEntity !is ServerPlayer) throw MishapBadCaster() - val sentinel = IXplatAbstractions.INSTANCE.getSentinel(env.castingEntity as? ServerPlayer) ?: return listOf(NullIota()) + val sentinel = IXplatAbstractions.INSTANCE.getSentinel(env.castingEntity as? ServerPlayer) ?: return Vector.from(listOf(NullIota())) if (sentinel.dimension != env.world.dimension()) throw MishapLocationInWrongDimension(sentinel.dimension.location()) return sentinel.position.asActionResult diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/sentinel/OpGetSentinelWayfind.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/sentinel/OpGetSentinelWayfind.kt index cad52447ed..b09cc103cc 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/sentinel/OpGetSentinelWayfind.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/sentinel/OpGetSentinelWayfind.kt @@ -9,6 +9,7 @@ import at.petrak.hexcasting.api.casting.iota.NullIota import at.petrak.hexcasting.api.casting.mishaps.MishapBadCaster import at.petrak.hexcasting.api.casting.mishaps.MishapLocationInWrongDimension import at.petrak.hexcasting.api.misc.MediaConstants +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.xplat.IXplatAbstractions import net.minecraft.server.level.ServerPlayer @@ -17,13 +18,13 @@ import net.minecraft.server.level.ServerPlayer object OpGetSentinelWayfind : ConstMediaAction { override val argc = 1 override val mediaCost: Long = MediaConstants.DUST_UNIT / 10 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { if (env.castingEntity !is ServerPlayer) throw MishapBadCaster() val from = args.getVec3(0, argc) - val sentinel = IXplatAbstractions.INSTANCE.getSentinel(env.castingEntity as? ServerPlayer) ?: return listOf(NullIota()) + val sentinel = IXplatAbstractions.INSTANCE.getSentinel(env.castingEntity as? ServerPlayer) ?: return Vector.from(listOf(NullIota())) if (sentinel.dimension != env.world.dimension()) throw MishapLocationInWrongDimension(sentinel.dimension.location()) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/stack/OpAlwinfyHasAscendedToABeingOfPureMath.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/stack/OpAlwinfyHasAscendedToABeingOfPureMath.kt index da6757147d..5745ca07b8 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/stack/OpAlwinfyHasAscendedToABeingOfPureMath.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/stack/OpAlwinfyHasAscendedToABeingOfPureMath.kt @@ -7,19 +7,18 @@ import at.petrak.hexcasting.api.casting.eval.vm.CastingImage import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation import at.petrak.hexcasting.api.casting.getPositiveLong import at.petrak.hexcasting.api.casting.mishaps.MishapNotEnoughArgs +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.common.lib.hex.HexEvalSounds import it.unimi.dsi.fastutil.longs.LongArrayList // "lehmer code" object OpAlwinfyHasAscendedToABeingOfPureMath : Action { override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult { - val stack = image.stack.toMutableList() - - if (stack.isEmpty()) + if (image.stack.isEmpty()) throw MishapNotEnoughArgs(1, 0) - val code = stack.getPositiveLong(stack.lastIndex) - stack.removeLast() + val code = image.stack.getPositiveLong(image.stack.lastIndex) + val stack = image.stack.init() val strides = LongArrayList() for (f in FactorialIter()) { @@ -31,7 +30,10 @@ object OpAlwinfyHasAscendedToABeingOfPureMath : Action { if (strides.size > stack.size) throw MishapNotEnoughArgs(strides.size + 1, stack.size + 1) - var editTarget = stack.subList(stack.size - strides.size, stack.size) + + val base = stack.dropRight(strides.size) + val editSlice = stack.takeRight(strides.size).toMutableList() + var editTarget = editSlice val swap = editTarget.toMutableList() var radix = code for (divisor in strides.asReversed()) { @@ -42,7 +44,9 @@ object OpAlwinfyHasAscendedToABeingOfPureMath : Action { editTarget = editTarget.subList(1, editTarget.size) } - val image2 = image.withUsedOp().copy(stack = stack) + val result = base.appendedAll(Vector.from(editSlice)) + + val image2 = image.withUsedOp().copy(stack = result) return OperationResult(image2, listOf(), continuation, HexEvalSounds.NORMAL_EXECUTE) } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/stack/OpDuplicateN.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/stack/OpDuplicateN.kt index ca92c7f082..f6274719fa 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/stack/OpDuplicateN.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/stack/OpDuplicateN.kt @@ -4,13 +4,14 @@ import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getPositiveInt import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.common.lib.hex.HexIotaTypes object OpDuplicateN : ConstMediaAction { override val argc: Int get() = 2 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { var count = args.getPositiveInt(1, argc) if (count > HexIotaTypes.MAX_SERIALIZATION_TOTAL) { @@ -20,6 +21,6 @@ object OpDuplicateN : ConstMediaAction { count = HexIotaTypes.MAX_SERIALIZATION_TOTAL } - return (List(count) { args[0] }) + return Vector.from(List(count) { args[0] }) } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/stack/OpFisherman.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/stack/OpFisherman.kt index c2c8874f28..5c6d3b9d03 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/stack/OpFisherman.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/stack/OpFisherman.kt @@ -14,15 +14,13 @@ import kotlin.math.roundToInt object OpFisherman : Action { override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult { - val stack = image.stack.toMutableList() - - if (stack.size < 2) - throw MishapNotEnoughArgs(2, stack.size) + if (image.stack.size < 2) + throw MishapNotEnoughArgs(2, image.stack.size) + val x = image.stack.last() + var stack = image.stack.init() + val maxIdx = stack.size - 1 val depth = let { - val x = stack.last() - stack.removeLast() - val maxIdx = stack.size - 1 if (x is DoubleIota) { val double = x.double val rounded = double.roundToInt() @@ -34,11 +32,11 @@ object OpFisherman : Action { } if (depth >= 0) { - val fish = stack.removeAt(stack.size - 1 - depth) - stack.add(fish) + val fish = stack[stack.size - 1 - depth] + stack = stack.dropRight(depth + 1).appendedAll(stack.takeRight(depth)).appended(fish) } else { - val lure = stack.removeLast() - stack.add(stack.size + depth, lure) + val lure = stack.last() + stack = stack.dropRight(1 - depth).appended(lure).appendedAll(stack.takeRight(1 - depth).init()) } val image2 = image.withUsedOp().copy(stack = stack) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/stack/OpFishermanButItCopies.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/stack/OpFishermanButItCopies.kt index 91ed5b94a3..1fc05651b4 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/stack/OpFishermanButItCopies.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/stack/OpFishermanButItCopies.kt @@ -11,20 +11,18 @@ import at.petrak.hexcasting.common.lib.hex.HexEvalSounds object OpFishermanButItCopies : Action { override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult { - val stack = image.stack.toMutableList() + if (image.stack.size < 2) + throw MishapNotEnoughArgs(2, image.stack.size) - if (stack.size < 2) - throw MishapNotEnoughArgs(2, stack.size) - - val depth = stack.getIntBetween(stack.lastIndex, -(stack.size - 2), stack.size - 2) - stack.removeLast() + val depth = image.stack.getIntBetween(image.stack.lastIndex, -(image.stack.size - 2), image.stack.size - 2) + var stack = image.stack.init() if (depth >= 0) { val fish = stack[stack.size - 1 - depth] - stack.add(fish) + stack = stack.appended(fish) } else { val lure = stack.last() - stack.add(stack.size - 1 + depth, lure) + stack = stack.dropRight(1 - depth).appended(lure).appendedAll(stack.takeRight(1 - depth)) } val image2 = image.withUsedOp().copy(stack = stack) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/stack/OpMask.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/stack/OpMask.kt index 3e15480bfd..d56fa0119e 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/stack/OpMask.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/stack/OpMask.kt @@ -3,6 +3,7 @@ package at.petrak.hexcasting.common.casting.actions.stack import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector import it.unimi.dsi.fastutil.booleans.BooleanList import net.minecraft.resources.ResourceLocation @@ -10,12 +11,12 @@ class OpMask(val mask: BooleanList, val key: ResourceLocation) : ConstMediaActio override val argc: Int get() = mask.size - override fun execute(args: List, env: CastingEnvironment): List { - val out = ArrayList(this.mask.size) + override fun execute(args: Vector, env: CastingEnvironment): Vector { + val out = Vector.VectorBuilder() for ((i, include) in this.mask.withIndex()) { if (include) - out.add(args[i]) + out.addOne(args[i]) } - return out + return out.result() } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/stack/OpStackSize.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/stack/OpStackSize.kt index eeec0f572b..42dcd19dac 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/stack/OpStackSize.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/stack/OpStackSize.kt @@ -10,8 +10,7 @@ import at.petrak.hexcasting.common.lib.hex.HexEvalSounds object OpStackSize : Action { override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult { - val stack = image.stack.toMutableList() - stack.add(DoubleIota(stack.size.toDouble())) + val stack = image.stack.appended(DoubleIota(image.stack.size.toDouble())) val image2 = image.withUsedOp().copy(stack = stack) return OperationResult(image2, listOf(), continuation, HexEvalSounds.NORMAL_EXECUTE) } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/stack/OpTwiddling.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/stack/OpTwiddling.kt index b2f73c1bfd..d12c3c8579 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/stack/OpTwiddling.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/stack/OpTwiddling.kt @@ -3,11 +3,12 @@ package at.petrak.hexcasting.common.casting.actions.stack import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector class OpTwiddling(val argumentCount: Int, val lookup: IntArray) : ConstMediaAction { override val argc: Int get() = this.argumentCount - override fun execute(args: List, env: CastingEnvironment): List = - this.lookup.map(args::get) + override fun execute(args: Vector, env: CastingEnvironment): Vector = + Vector.from(this.lookup.map(args::get)) } \ No newline at end of file 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 29e0183358..c0d725f41f 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 @@ -9,6 +9,7 @@ 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.utils.Vector import at.petrak.hexcasting.api.utils.asTranslatedComponent import at.petrak.hexcasting.api.utils.lightPurple import at.petrak.hexcasting.common.lib.hex.HexSpecialHandlers @@ -35,13 +36,13 @@ class SpecialHandlerMask(val mask: BooleanList) : SpecialHandler { override val argc: Int get() = this.mask.size - override fun execute(args: List, env: CastingEnvironment): List { - val out = ArrayList(this.mask.size) + override fun execute(args: Vector, env: CastingEnvironment): Vector { + val out = Vector.VectorBuilder() for ((i, include) in this.mask.withIndex()) { if (include) - out.add(args[i]) + out.addOne(args[i]) } - return out + return out.result() } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/ListArithmetic.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/ListArithmetic.kt index 35a34e61ec..6b17fd9ffd 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/ListArithmetic.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/ListArithmetic.kt @@ -1,6 +1,5 @@ package at.petrak.hexcasting.common.casting.arithmetic -import at.petrak.hexcasting.api.casting.SpellList import at.petrak.hexcasting.api.casting.arithmetic.Arithmetic import at.petrak.hexcasting.api.casting.arithmetic.Arithmetic.* import at.petrak.hexcasting.api.casting.arithmetic.engine.InvalidOperatorException @@ -15,6 +14,7 @@ import at.petrak.hexcasting.api.casting.iota.DoubleIota import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.ListIota import at.petrak.hexcasting.api.casting.math.HexPattern +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.common.casting.arithmetic.operator.list.* import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.LIST import java.util.function.BinaryOperator @@ -45,20 +45,20 @@ object ListArithmetic : Arithmetic { SLICE -> OperatorSlice APPEND -> OperatorAppend UNAPPEND -> OperatorUnappend - ADD -> make2 { list0, list1 -> list0 + list1 } - ABS -> OperatorUnary(all(IotaPredicate.ofType(LIST))) { iota: Iota -> DoubleIota(downcast(iota, LIST).list.size().toDouble()) } - REV -> OperatorUnary(all(IotaPredicate.ofType(LIST))) { iota: Iota -> ListIota(downcast(iota, LIST).list.toList().asReversed()) } + ADD -> make2 { list0, list1 -> list0.appendedAll(list1) } + ABS -> OperatorUnary(all(IotaPredicate.ofType(LIST))) { iota: Iota -> DoubleIota(downcast(iota, LIST).list.size.toDouble()) } + REV -> OperatorUnary(all(IotaPredicate.ofType(LIST))) { iota: Iota -> ListIota(downcast(iota, LIST).list.reversed()) } INDEX_OF -> OperatorIndexOf REMOVE -> OperatorRemove REPLACE -> OperatorReplace - CONS -> OperatorBinary(pair(IotaPredicate.ofType(LIST), IotaPredicate.TRUE)) { list, iota -> ListIota(SpellList.LPair(iota, downcast(list, LIST).list)) } + CONS -> OperatorBinary(pair(IotaPredicate.ofType(LIST), IotaPredicate.TRUE)) { list, iota -> ListIota(downcast(list, LIST).list.prepended(iota)) } UNCONS -> OperatorUnCons else -> throw InvalidOperatorException("$pattern is not a valid operator in Arithmetic $this.") } } - private fun make2(op: BinaryOperator>): OperatorBinary = OperatorBinary(all(IotaPredicate.ofType(LIST))) + private fun make2(op: BinaryOperator>): OperatorBinary = OperatorBinary(all(IotaPredicate.ofType(LIST))) { i: Iota, j: Iota -> ListIota( - op.apply(downcast(i, LIST).list.toList(), downcast(j, LIST).list.toList()) + op.apply(downcast(i, LIST).list, downcast(j, LIST).list) ) } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/ListSetArithmetic.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/ListSetArithmetic.kt index d412c66652..5fee12cc5c 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/ListSetArithmetic.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/ListSetArithmetic.kt @@ -11,6 +11,7 @@ import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaPredicate import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.ListIota import at.petrak.hexcasting.api.casting.math.HexPattern +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.common.casting.arithmetic.operator.list.OperatorUnique import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.LIST import java.util.function.BinaryOperator @@ -28,16 +29,16 @@ object ListSetArithmetic : Arithmetic { override fun opTypes() = OPS override fun getOperator(pattern: HexPattern): Operator = when (pattern) { - AND -> make2 { list0, list1 -> list0.filter { x -> list1.any { Iota.tolerates(x, it) } } } - OR -> make2 { list0, list1 -> list0 + list1.filter { x -> list0.none { Iota.tolerates(x, it) } } } - XOR -> make2 { list0, list1 -> list0.filter { x0 -> list1.none {Iota.tolerates(x0, it) } } + list1.filter { x1 -> list0.none { Iota.tolerates(x1, it) } } } + AND -> make2 { list0, list1 -> list0.filter { x -> list1.exists { Iota.tolerates(x, it) } } } + OR -> make2 { list0, list1 -> list0.appendedAll(list1.filter { x -> !list0.exists { Iota.tolerates(x, it) } }) } + XOR -> make2 { list0, list1 -> list0.filter { x0 -> !list1.exists {Iota.tolerates(x0, it) } }.appendedAll(list1.filter { x1 -> !list0.exists { Iota.tolerates(x1, it) } }) } UNIQUE -> OperatorUnique else -> throw InvalidOperatorException("$pattern is not a valid operator in Arithmetic $this.") } - private fun make2(op: BinaryOperator>): OperatorBinary = OperatorBinary(all(IotaPredicate.ofType(LIST))) + private fun make2(op: BinaryOperator>): OperatorBinary = OperatorBinary(all(IotaPredicate.ofType(LIST))) { i: Iota, j: Iota -> ListIota( - op.apply(downcast(i, LIST).list.toList(), downcast(j, LIST).list.toList()) + op.apply(downcast(i, LIST).list, downcast(j, LIST).list) ) } } \ No newline at end of file diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/OperatorUtils.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/OperatorUtils.kt index 24247286c8..77a8e8fa98 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/OperatorUtils.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/OperatorUtils.kt @@ -1,14 +1,14 @@ package at.petrak.hexcasting.common.casting.arithmetic.operator -import at.petrak.hexcasting.api.casting.SpellList import at.petrak.hexcasting.api.casting.iota.DoubleIota import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.ListIota import at.petrak.hexcasting.api.casting.mishaps.MishapInvalidIota +import at.petrak.hexcasting.api.utils.Vector import kotlin.math.abs import kotlin.math.roundToInt -fun Iterator>.nextList(argc: Int = 0): SpellList { +fun Iterator>.nextList(argc: Int = 0): Vector { val (idx, x) = this.next() if (x is ListIota) { return x.list diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorAppend.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorAppend.kt index 724e5f6746..f857d7b04b 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorAppend.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorAppend.kt @@ -13,8 +13,7 @@ import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.* object OperatorAppend : OperatorBasic(2, IotaMultiPredicate.pair(IotaPredicate.ofType(LIST), IotaPredicate.TRUE)) { override fun apply(iotas: Iterable, env: CastingEnvironment): Iterable { val it = iotas.iterator().withIndex() - val list = it.nextList(arity).toMutableList() - list.add(it.next().value) - return list.asActionResult + val list = it.nextList(arity) + return list.appended(it.next().value).asActionResult } } \ No newline at end of file diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorRemove.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorRemove.kt index 1a1af53cfc..0c0a5108a2 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorRemove.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorRemove.kt @@ -14,11 +14,10 @@ import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.* object OperatorRemove : OperatorBasic(2, IotaMultiPredicate.pair(IotaPredicate.ofType(LIST), IotaPredicate.ofType(DOUBLE))) { override fun apply(iotas: Iterable, env: CastingEnvironment): Iterable { val it = iotas.iterator().withIndex() - val list = it.nextList(arity).toMutableList() + val list = it.nextList(arity) val index = it.nextInt(arity) if (index < 0 || index >= list.size) return list.asActionResult - list.removeAt(index) - return list.asActionResult + return list.take(index).appendedAll(list.drop(index + 1)).asActionResult } -} \ No newline at end of file +} diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorReplace.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorReplace.kt index ca976369c2..bc2d730449 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorReplace.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorReplace.kt @@ -1,6 +1,5 @@ package at.petrak.hexcasting.common.casting.arithmetic.operator.list -import at.petrak.hexcasting.api.casting.SpellList import at.petrak.hexcasting.api.casting.arithmetic.operator.Operator import at.petrak.hexcasting.api.casting.arithmetic.operator.OperatorBasic import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate @@ -16,8 +15,8 @@ object OperatorReplace : OperatorBasic(3, IotaMultiPredicate.triple(IotaPredicat override fun apply(iotas: Iterable, env: CastingEnvironment): Iterable { val it = iotas.iterator().withIndex() val list = it.nextList(arity) - val index = it.nextPositiveIntUnder(list.size(), arity) + val index = it.nextPositiveIntUnder(list.size, arity) val iota = it.next().value - return list.modifyAt(index) { SpellList.LPair(iota, it.cdr) }.asActionResult + return list.updated(index, iota).asActionResult } } \ No newline at end of file diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorSlice.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorSlice.kt index d4e8c5f8ec..cdb0de27ca 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorSlice.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorSlice.kt @@ -7,6 +7,7 @@ import at.petrak.hexcasting.api.casting.arithmetic.operator.OperatorBasic import at.petrak.hexcasting.api.casting.asActionResult import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.common.casting.arithmetic.operator.nextList import at.petrak.hexcasting.common.casting.arithmetic.operator.nextPositiveIntUnderInclusive import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.* @@ -16,12 +17,12 @@ import kotlin.math.min object OperatorSlice : OperatorBasic(3, IotaMultiPredicate.triple(IotaPredicate.ofType(LIST), IotaPredicate.ofType(DOUBLE), IotaPredicate.ofType(DOUBLE))) { override fun apply(iotas: Iterable, env: CastingEnvironment): Iterable { val it = iotas.iterator().withIndex() - val list = it.nextList(arity).toList() + val list = it.nextList(arity) val index0 = it.nextPositiveIntUnderInclusive(list.size, arity) val index1 = it.nextPositiveIntUnderInclusive(list.size, arity) if (index0 == index1) - return emptyList().asActionResult - return list.subList(min(index0, index1), max(index0, index1)).asActionResult + return Vector.empty().asActionResult + return Vector.from(list.subList(min(index0, index1), max(index0, index1))).asActionResult } } \ No newline at end of file diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorUnCons.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorUnCons.kt index 54f0de69c2..b8369512c2 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorUnCons.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorUnCons.kt @@ -15,8 +15,8 @@ object OperatorUnCons : OperatorBasic(1, IotaMultiPredicate.all(IotaPredicate.of override fun apply(iotas: Iterable, env: CastingEnvironment): Iterable { val it = iotas.iterator().withIndex() val list = it.nextList(arity) - if (list.nonEmpty) - return listOf(ListIota(list.cdr), list.car) + if (!list.isEmpty()) + return listOf(ListIota(list.tail()), list.head()) return listOf(ListIota(list), NullIota()) } } \ No newline at end of file diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorUnappend.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorUnappend.kt index 6d60362b0d..f86e6cf67f 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorUnappend.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorUnappend.kt @@ -14,8 +14,8 @@ import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.* object OperatorUnappend : OperatorBasic(1, IotaMultiPredicate.all(IotaPredicate.ofType(LIST))) { override fun apply(iotas: Iterable, env: CastingEnvironment): Iterable { val it = iotas.iterator().withIndex() - val list = it.nextList(arity).toMutableList() - val last = list.removeLastOrNull() ?: NullIota() - return listOf(ListIota(list), last) + val list = it.nextList(arity) + val last = if (list.isEmpty()) NullIota() else list.last() + return listOf(ListIota(if (list.isEmpty()) list else list.init()), last) } } \ No newline at end of file diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorUnique.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorUnique.kt index b3cb19ec28..bb9086daaf 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorUnique.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorUnique.kt @@ -7,6 +7,7 @@ import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaPredicate import at.petrak.hexcasting.api.casting.asActionResult import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.common.casting.arithmetic.operator.nextList import at.petrak.hexcasting.common.casting.actions.math.bit.OpToSet import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.LIST @@ -23,6 +24,6 @@ object OperatorUnique : OperatorBasic(1, IotaMultiPredicate.all(IotaPredicate.of } } - return out.asActionResult + return Vector.from(out).asActionResult } } \ No newline at end of file diff --git a/Common/src/main/java/at/petrak/hexcasting/common/items/magic/ItemPackagedHex.java b/Common/src/main/java/at/petrak/hexcasting/common/items/magic/ItemPackagedHex.java index 1c8886f999..2a1eae9c94 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/items/magic/ItemPackagedHex.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/items/magic/ItemPackagedHex.java @@ -9,6 +9,7 @@ import at.petrak.hexcasting.api.item.HexHolderItem; import at.petrak.hexcasting.api.pigment.FrozenPigment; import at.petrak.hexcasting.api.utils.NBTHelper; +import at.petrak.hexcasting.api.utils.Vector; import at.petrak.hexcasting.common.msgs.MsgNewSpiralPatternsS2C; import at.petrak.hexcasting.xplat.IXplatAbstractions; import net.minecraft.nbt.CompoundTag; @@ -66,19 +67,19 @@ public boolean hasHex(ItemStack stack) { } @Override - public @Nullable List getHex(ItemStack stack, ServerLevel level) { + public @Nullable Vector getHex(ItemStack stack, ServerLevel level) { var patsTag = NBTHelper.getList(stack, TAG_PROGRAM, Tag.TAG_COMPOUND); if (patsTag == null) { return null; } - var out = new ArrayList(); + var out = new Vector.VectorBuilder(); for (var patTag : patsTag) { CompoundTag tag = NBTHelper.getAsCompound(patTag); - out.add(IotaType.deserialize(tag, level)); + out.addOne(IotaType.deserialize(tag, level)); } - return out; + return out.result(); } @Override @@ -122,7 +123,7 @@ public InteractionResultHolder use(Level world, Player player, Intera return InteractionResultHolder.success(stack); } - List instrs = getHex(stack, (ServerLevel) world); + Vector instrs = getHex(stack, (ServerLevel) world); if (instrs == null) { return InteractionResultHolder.fail(stack); } diff --git a/Common/src/main/java/at/petrak/hexcasting/interop/pehkui/OpGetScale.kt b/Common/src/main/java/at/petrak/hexcasting/interop/pehkui/OpGetScale.kt index d1a9868c51..3b1a732da9 100644 --- a/Common/src/main/java/at/petrak/hexcasting/interop/pehkui/OpGetScale.kt +++ b/Common/src/main/java/at/petrak/hexcasting/interop/pehkui/OpGetScale.kt @@ -5,12 +5,13 @@ import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getEntity import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.xplat.IXplatAbstractions object OpGetScale : ConstMediaAction { override val argc = 1 - override fun execute(args: List, env: CastingEnvironment): List { + override fun execute(args: Vector, env: CastingEnvironment): Vector { val target = args.getEntity(0, argc) env.assertEntityInRange(target) return IXplatAbstractions.INSTANCE.pehkuiApi.getScale(target).toDouble().asActionResult diff --git a/Common/src/main/java/at/petrak/hexcasting/interop/pehkui/OpSetScale.kt b/Common/src/main/java/at/petrak/hexcasting/interop/pehkui/OpSetScale.kt index 9c171c5784..a717287614 100644 --- a/Common/src/main/java/at/petrak/hexcasting/interop/pehkui/OpSetScale.kt +++ b/Common/src/main/java/at/petrak/hexcasting/interop/pehkui/OpSetScale.kt @@ -7,6 +7,7 @@ import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getDoubleBetween import at.petrak.hexcasting.api.casting.getEntity import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.utils.Vector import at.petrak.hexcasting.xplat.IXplatAbstractions import net.minecraft.world.entity.Entity @@ -14,7 +15,7 @@ object OpSetScale : SpellAction { override val argc = 2 override fun execute( - args: List, + args: Vector, env: CastingEnvironment ): SpellAction.Result { val target = args.getEntity(0, argc)