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..70fcdc99e5 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.TreeList import at.petrak.hexcasting.api.utils.asTranslatedComponent import com.mojang.datafixers.util.Either import net.minecraft.core.BlockPos @@ -41,7 +42,7 @@ fun List.getEntity(idx: Int, argc: Int = 0): Entity { } } -fun List.getList(idx: Int, argc: Int = 0): SpellList { +fun List.getList(idx: Int, argc: Int = 0): TreeList { val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) } if (x is ListIota) { return x.list @@ -269,7 +270,7 @@ fun List.getNumOrVec(idx: Int, argc: Int = 0): Either { } } -fun List.getLongOrList(idx: Int, argc: Int = 0): Either { +fun List.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( @@ -312,7 +313,7 @@ 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 SpellList.asActionResult get() = listOf(ListIota(this)) +inline val TreeList.asActionResult get() = listOf(ListIota(this)) inline val List.asActionResult get() = listOf(ListIota(this)) inline val BlockPos.asActionResult get() = listOf(Vec3Iota(Vec3.atCenterOf(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..0bcb9c6683 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 @@ -14,14 +14,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 = image.stack + val args = stack.takeRight(arity) + val stackWithoutArgs = stack.dropRight(arity) val ret = apply(args, env) - ret.forEach(Consumer { e: Iota -> stack.add(e) }) + val stackWithResult = stackWithoutArgs.appendedAll(ret) - val image2 = image.copy(stack = stack, opsConsumed = image.opsConsumed + 1) + val image2 = image.copy(stack = stackWithResult, 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/ConstMediaAction.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/ConstMediaAction.kt index 7586d07bd5..74f3a0f602 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 @@ -29,21 +29,21 @@ interface ConstMediaAction : Action { } override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult { - val stack = image.stack.toMutableList() + val stack = image.stack if (this.argc > stack.size) throw MishapNotEnoughArgs(this.argc, stack.size) - val args = stack.takeLast(this.argc) - repeat(this.argc) { stack.removeLast() } + val args = stack.takeRight(this.argc) + val stackWithoutArgs = stack.dropRight(this.argc) val result = this.executeWithOpCount(args, env) - stack.addAll(result.resultStack) + val stackWithResult = stackWithoutArgs.appendedAll(result.resultStack) if (env.extractMedia(this.mediaCost, true) > 0) throw MishapNotEnoughMedia(this.mediaCost) val sideEffects = mutableListOf(OperatorSideEffect.ConsumeMedia(this.mediaCost)) - val image2 = image.copy(stack = stack, opsConsumed = image.opsConsumed + result.opCount) + val image2 = image.copy(stack = stackWithResult, opsConsumed = image.opsConsumed + result.opCount) return OperationResult(image2, sideEffects, continuation, HexEvalSounds.NORMAL_EXECUTE) } 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 3405830d62..005526f704 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 @@ -36,12 +36,12 @@ interface SpellAction : Action { } override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult { - val stack = image.stack.toMutableList() + val stack = image.stack 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() + val args = stack.takeRight(this.argc) + val stackWithoutArgs = stack.dropRight(this.argc) // execute! val userDataMut = image.userData.copy() @@ -65,7 +65,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 = stackWithoutArgs, 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..48d497f87b 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.execute(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 cf887a117b..f9f6855308 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: TreeList, val parenCount: Int, - val parenthesized: List, + val parenthesized: TreeList, val escapeNext: Boolean, val opsConsumed: Long, val userData: CompoundTag ) { - constructor() : this(listOf(), 0, listOf(), false, 0, CompoundTag()) + constructor() : this(TreeList.empty(), 0, TreeList.empty(), false, 0, CompoundTag()) data class ParenthesizedIota(val iota: Iota, val escaped: Boolean) { companion object { @@ -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 = TreeList.empty(), escapeNext = false) fun serializeToNbt() = NBTBuilder { TAG_STACK %= stack.serializeToNBT() @@ -120,7 +120,7 @@ data class CastingImage private constructor( val escapeNext = tag.getBoolean(TAG_ESCAPE_NEXT) val opsUsed = tag.getLong(TAG_OPS_CONSUMED) - CastingImage(stack, parenCount, parenthesized, escapeNext, opsUsed, userData) + CastingImage(TreeList.from(stack), parenCount, TreeList.from(parenthesized), 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 3d03a9a843..744ea8dec1 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 @@ -40,7 +39,7 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) { */ fun queueExecuteAndWrapIotas(iotas: List, 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(TreeList.from(iotas), false)) // Begin aggregating info val info = TempControllerInfo(earlyExit = false) var lastResolutionType = ResolvedPatternType.UNRESOLVED @@ -185,8 +184,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 @@ -201,8 +199,8 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) { } SpecialPatterns.EVANITION.angles -> { - val newParens = this.image.parenthesized.toMutableList() - val last = newParens.removeLastOrNull() + val newParens = this.image.parenthesized.init() + val last = this.image.parenthesized.lastOrNull() 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 @@ -213,8 +211,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 @@ -225,20 +222,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 = TreeList.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 @@ -247,8 +242,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 @@ -256,8 +250,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..003be41e99 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.TreeList 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: TreeList): 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(TreeList.empty(), false) return (tag.get(HexContinuationTypes.KEY_DATA) as? CompoundTag)?.let { type.deserializeFromNBT(it, world) } - ?: FrameEvaluate(SpellList.LList(0, listOf()), false) + ?: FrameEvaluate(TreeList.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..f07e7aa80c 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.TreeList 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: TreeList, val isMetacasting: Boolean) : ContinuationFrame { // Discard this frame and keep discarding frames. - override fun breakDownwards(stack: List) = false to stack + override fun breakDownwards(stack: TreeList) = 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..f5af3c5a65 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.TreeList 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: TreeList) = 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 872bbe8e14..63df0a3133 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 @@ -26,26 +25,26 @@ import net.minecraft.server.level.ServerLevel * @property immutableAcc concatenated list of final stack states after Thoth exit */ data class FrameForEach( - val data: SpellList, - val code: SpellList, - val baseStack: List?, + val data: TreeList, + val code: TreeList, + val baseStack: TreeList?, val immutableAcc: TreeList ) : ContinuationFrame { @Deprecated("use the primary constructor that accepts a TreeList instead") constructor( - data: SpellList, - code: SpellList, + data: TreeList, + code: TreeList, baseStack: List?, acc: MutableList - ) : this(data, code, baseStack, TreeList.from(acc)) + ) : this(data, code, TreeList.from(baseStack), TreeList.from(acc)) @Deprecated("access immutableAcc instead") val acc: MutableList get() = immutableAcc.toMutableList() /** 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() + override fun breakDownwards(stack: TreeList): Pair> { + val newStack = baseStack ?: TreeList.empty() newStack.add(ListIota(immutableAcc.appendedAll(stack))) return true to newStack } @@ -59,27 +58,26 @@ data class FrameForEach( // If this isn't the very first Thoth step (i.e. no Thoth computations run yet)... val (stack, newAcc) = if (baseStack == null) { // init stack to the harness stack... - harness.image.stack.toList() to immutableAcc + harness.image.stack to immutableAcc } else { // else save the stack to the accumulator and reuse the saved base stack. baseStack to immutableAcc.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, newAcc)) + .pushFrame(FrameForEach(data.tail(), code, stack, newAcc)) // 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(immutableAcc), harness.image, continuation) } - val tStack = stack.toMutableList() - tStack.add(stackTop) + val tStack = stack.appended(stackTop) return CastResult( ListIota(code), newCont, @@ -99,7 +97,7 @@ data class FrameForEach( "accumulator" %= immutableAcc.serializeToNBT() } - override fun size() = data.size() + code.size() + immutableAcc.size + (baseStack?.size ?: 0) + override fun size() = data.size + code.size + immutableAcc.size + (baseStack?.size ?: 0) override val type: ContinuationFrame.Type<*> = TYPE @@ -111,7 +109,7 @@ 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, TreeList.from(HexIotaTypes.LIST.deserialize( 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 588c72bca3..52867f50d8 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,10 +1,10 @@ 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.TreeList; import at.petrak.hexcasting.common.lib.hex.HexIotaTypes; import at.petrak.hexcasting.api.mod.HexConfig; +import java.util.ListIterator; import net.minecraft.ChatFormatting; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; @@ -20,13 +20,13 @@ import static java.lang.Math.max; /** - * This is a wrapper for {@link SpellList}. + * This is a wrapper for {@link TreeList} of {@link Iota}. */ public class ListIota extends Iota { private final int depth; private final int size; - public ListIota(@NotNull SpellList list) { + public ListIota(@NotNull TreeList list) { super(HexIotaTypes.LIST, list); int maxChildDepth = 0; int totalSize = 1; @@ -38,21 +38,18 @@ public ListIota(@NotNull SpellList list) { size = totalSize; } - public ListIota(@NotNull TreeList list) { - this(new SpellList.LList(list)); - } - public ListIota(@NotNull List list) { - this(new SpellList.LList(list)); + this(TreeList.from(list)); } - public SpellList getList() { - return (SpellList) this.payload; + @SuppressWarnings("unchecked") + public TreeList getList() { + return (TreeList) this.payload; } @Override public boolean isTruthy() { - return this.getList().getNonEmpty(); + return !this.getList().isEmpty(); } @Override @@ -66,7 +63,7 @@ public boolean toleratesOther(Iota that) { } var b = list.getList(); - SpellList.SpellListIterator aIter = a.iterator(), bIter = b.iterator(); + ListIterator aIter = a.iterator(), bIter = b.iterator(); for (; ; ) { if (!aIter.hasNext() && !bIter.hasNext()) { // we ran out together! 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 685b3e8984..ffbf4425af 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.TreeList import at.petrak.hexcasting.api.utils.asTranslatedComponent import at.petrak.hexcasting.api.utils.lightPurple import at.petrak.hexcasting.common.lib.HexItems @@ -38,15 +39,10 @@ abstract class Mishap : RuntimeException() { * * You can also mess up the stack with this. */ - abstract fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) + abstract fun execute(env: CastingEnvironment, errorCtx: Context, stack: TreeList): TreeList protected abstract fun errorMessage(ctx: CastingEnvironment, errorCtx: Context): Component? - fun executeReturnStack(ctx: CastingEnvironment, errorCtx: Context, stack: MutableList): List { - execute(ctx, errorCtx, stack) - return stack - } - /** * 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..f863407c12 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.TreeList 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 execute(ctx: CastingEnvironment, errorCtx: Context, stack: TreeList): TreeList { 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..09475b1c25 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.TreeList 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 execute(ctx: CastingEnvironment, errorCtx: Context, stack: TreeList): TreeList { 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..1f488834e0 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.TreeList 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 execute(ctx: CastingEnvironment, errorCtx: Context, stack: TreeList): TreeList { 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..32b0110cd7 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,13 +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.TreeList 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 execute(env: CastingEnvironment, errorCtx: Context, stack: TreeList): TreeList { + return stack } override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = 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..c175470421 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.TreeList 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 execute(env: CastingEnvironment, errorCtx: Context, stack: TreeList): TreeList { 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..77e9ed7313 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.TreeList 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 execute(env: CastingEnvironment, errorCtx: Context, stack: TreeList): TreeList { 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..bd19aa42f3 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.TreeList 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 execute(env: CastingEnvironment, errorCtx: Context, stack: TreeList): TreeList { 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..e37b636235 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.TreeList 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 execute(env: CastingEnvironment, errorCtx: Context, stack: TreeList): TreeList { 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 c55772107e..14386abd30 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.TreeList import at.petrak.hexcasting.api.utils.asTranslatedComponent import net.minecraft.resources.ResourceLocation; import net.minecraft.network.chat.Component @@ -18,8 +19,9 @@ class MishapDisallowedSpell(val type: String, val actionKey: ResourceLocation?) override fun resolutionType(ctx: CastingEnvironment) = ResolvedPatternType.INVALID - override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { + override fun execute(env: CastingEnvironment, errorCtx: Context, stack: TreeList): TreeList { // NO-OP + return stack } override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context): Component? { 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..60704fe8f6 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.TreeList 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 execute(env: CastingEnvironment, errorCtx: Context, stack: TreeList): TreeList { 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..521b8bbcc1 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.TreeList 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 execute(env: CastingEnvironment, errorCtx: Context, stack: TreeList): TreeList { 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..b136030422 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.TreeList 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 execute(env: CastingEnvironment, errorCtx: Context, stack: TreeList): TreeList { 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..8abd7210c3 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.TreeList 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 execute(env: CastingEnvironment, errorCtx: Context, stack: TreeList): TreeList { 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..573b5cbb95 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,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.TreeList 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) { + override fun execute(env: CastingEnvironment, errorCtx: Context, stack: TreeList): TreeList { // NO-OP + return stack } override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = 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 f7752c6567..e492c2dd16 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.TreeList import at.petrak.hexcasting.api.utils.asTranslatedComponent import at.petrak.hexcasting.common.lib.hex.HexIotaTypes import net.minecraft.network.chat.Component @@ -20,8 +21,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 execute(env: CastingEnvironment, errorCtx: Context, stack: TreeList): TreeList { + return stack.updated(stack.size - 1 - reverseIdx, GarbageIota()) } override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context): Component? { 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..78c09ab5b6 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.TreeList 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 execute(env: CastingEnvironment, errorCtx: Context, stack: TreeList): TreeList { + var newStack = stack for (i in perpetrators.indices) { - stack[stack.size - 1 - i] = GarbageIota() + newStack = newStack.updated(stack.size - 1 - i, GarbageIota()) } + return newStack } 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 4e9f9a18df..5f16258d00 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 @@ -7,6 +7,7 @@ import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.PatternIota import at.petrak.hexcasting.api.casting.math.HexPattern import at.petrak.hexcasting.api.pigment.FrozenPigment +import at.petrak.hexcasting.api.utils.TreeList import net.minecraft.network.chat.Component import net.minecraft.world.item.DyeColor @@ -19,8 +20,8 @@ class MishapInvalidPattern(val pattern: HexPattern?) : Mishap() { override fun resolutionType(ctx: CastingEnvironment) = ResolvedPatternType.INVALID - override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { - stack.add(GarbageIota()) + override fun execute(env: CastingEnvironment, errorCtx: Context, stack: TreeList): TreeList { + return stack.appended(GarbageIota()) } override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context): Component? { 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..a8ab545c6b 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.TreeList import net.minecraft.world.item.DyeColor /** @@ -12,8 +13,9 @@ 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) { + override fun execute(env: CastingEnvironment, errorCtx: Context, stack: TreeList): TreeList { // NO-OP + return stack } override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapLackingHotbarItem.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapLackingHotbarItem.kt index cd26153399..a2cc93b771 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapLackingHotbarItem.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapLackingHotbarItem.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.TreeList import at.petrak.hexcasting.api.utils.asTranslatedComponent import net.minecraft.network.chat.Component import net.minecraft.world.item.DyeColor @@ -16,8 +17,9 @@ class MishapLackingHotbarItem(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 execute(env: CastingEnvironment, errorCtx: Context, stack: TreeList): TreeList { env.mishapEnvironment.dropHeldItems() + return stack } override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = error("bad_item.hotbar", wanted) 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..830a24c424 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.TreeList import net.minecraft.network.chat.Component import net.minecraft.resources.ResourceLocation import net.minecraft.world.item.DyeColor @@ -12,8 +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 execute(env: CastingEnvironment, errorCtx: Context, stack: TreeList): TreeList { + return stack.appended(GarbageIota()) } override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context): Component = 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..43cc02764a 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.TreeList 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 execute(env: CastingEnvironment, errorCtx: Context, stack: TreeList): TreeList { 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..adb38bcc25 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,15 @@ 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.TreeList 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 execute(env: CastingEnvironment, errorCtx: Context, stack: TreeList): TreeList { + return stack.appendedAll(List(expected - got) { GarbageIota() }) } 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..9b7deacaba 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.TreeList 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 execute(env: CastingEnvironment, errorCtx: Context, stack: TreeList): TreeList { 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..05aa0da9e7 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.TreeList 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 execute(ctx: CastingEnvironment, errorCtx: Context, stack: TreeList): TreeList { 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..908e7f11fd 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.TreeList import at.petrak.hexcasting.common.lib.HexDamageTypes import net.minecraft.world.item.DyeColor @@ -14,9 +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 execute(env: CastingEnvironment, errorCtx: Context, stack: TreeList): TreeList { + return TreeList.from(listOf(GarbageIota())) } override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = 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..39f8ae7041 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,18 @@ 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.TreeList 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 execute(env: CastingEnvironment, errorCtx: Context, stack: TreeList): TreeList { // 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..e0eb08f2ea 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.TreeList 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 execute(env: CastingEnvironment, errorCtx: Context, stack: TreeList): TreeList { 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..d54a9c9583 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.TreeList 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 execute(env: CastingEnvironment, errorCtx: Context, stack: TreeList): TreeList { // 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..b06cd7ad39 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.TreeList 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 execute(env: CastingEnvironment, errorCtx: Context, stack: TreeList): TreeList { 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 e4975f59a8..cd298fe21c 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.TreeList 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 execute(env: CastingEnvironment, errorCtx: Context, stack: TreeList): TreeList { 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..12babfab8d 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.TreeList 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 execute(env: CastingEnvironment, errorCtx: Context, stack: TreeList): TreeList { 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/common/blocks/circles/directrix/BlockBooleanDirectrix.java b/Common/src/main/java/at/petrak/hexcasting/common/blocks/circles/directrix/BlockBooleanDirectrix.java index 6d99767bce..f5bb54396e 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 @@ -6,6 +6,7 @@ import at.petrak.hexcasting.api.casting.iota.BooleanIota; import at.petrak.hexcasting.api.casting.mishaps.circle.MishapBoolDirectrixEmptyStack; import at.petrak.hexcasting.api.casting.mishaps.circle.MishapBoolDirectrixNotBool; +import at.petrak.hexcasting.api.utils.TreeList; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.server.level.ServerLevel; @@ -62,7 +63,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(TreeList.from(stack), 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/eval/OpEval.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/eval/OpEval.kt index e9c9adf2a1..9403204239 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.TreeList 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) - return exec(env, image, continuation, stack, iota) + val stack = image.stack + val iota = stack.lastOrNull() ?: throw MishapNotEnoughArgs(1, 0) + return exec(env, image, continuation, stack.init(), iota) } - fun exec(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation, newStack: MutableList, iota: Iota): OperationResult { + fun exec(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation, newStack: TreeList, 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({ TreeList.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..0646c3ea0a 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)) - return OpEval.exec(env, image, continuation, stack, iota) + val stack = image.stack + val iota = stack.lastOrNull() ?: throw MishapNotEnoughArgs(1, 0) + return OpEval.exec(env, image, continuation, stack.init().appended(ContinuationIota(continuation)), 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 926bce1d82..e3100fb1bf 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 @@ -13,18 +13,17 @@ 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() + val 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() + val newStack = stack.dropRight(2) val frame = FrameForEach(datums, instrs, null, TreeList.empty()) - val image2 = image.withUsedOp().copy(stack = stack) + val image2 = image.withUsedOp().copy(stack = newStack) 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..f4e4908b2c 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.TreeList 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 = TreeList.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/OpCons.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpCons.kt index b0ec3173fc..2db64a4427 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,6 +1,5 @@ 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 @@ -12,6 +11,6 @@ object OpCons : ConstMediaAction { override fun execute(args: List, env: CastingEnvironment): List { 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/OpLastNToList.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpLastNToList.kt index ffd4e3c10a..13dfa9a305 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 @@ -9,24 +9,22 @@ import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation import at.petrak.hexcasting.api.casting.getPositiveIntUnderInclusive import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.mishaps.MishapNotEnoughArgs +import at.petrak.hexcasting.api.utils.TreeList 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() + val 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) + val stackWithoutArg = stack.init() + val output = TreeList.from(stackWithoutArg.takeRight(yoinkCount)) + val stackWithoutContents = stackWithoutArg.dropRight(yoinkCount) + val stackWithResult = stackWithoutContents.appendedAll(output.asActionResult) - val image2 = image.withUsedOp().copy(stack = stack) + val image2 = image.withUsedOp().copy(stack = stackWithResult) return OperationResult(image2, listOf(), continuation, HexEvalSounds.NORMAL_EXECUTE) } } 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..f7be737c2d 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,6 +1,5 @@ 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 @@ -12,8 +11,8 @@ object OpModifyInPlace : ConstMediaAction { override val argc = 3 override fun execute(args: List, env: CastingEnvironment): List { 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/OpUnCons.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpUnCons.kt index 211e91283d..a272f05d9f 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 @@ -11,8 +11,8 @@ object OpUnCons : ConstMediaAction { override val argc = 1 override fun execute(args: List, env: CastingEnvironment): List { val list = args.getList(0, argc) - if (list.nonEmpty) { - return listOf(ListIota(list.cdr), list.car) + if (!list.isEmpty()) { + return listOf(ListIota(list.tail()), list.head()) } return 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..ec238e46a5 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,17 @@ 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) + val newStack = stack.appended(rm) // does not mutate userdata - val image2 = image.withUsedOp().copy(stack = stack) + val image2 = image.withUsedOp().copy(stack = newStack) 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..57bba20746 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,18 +13,18 @@ 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() + val stack = image.stack if (stack.isEmpty()) throw MishapNotEnoughArgs(1, 0) - val newLocal = stack.removeLast() + val newLocal = stack.last() if (newLocal.type == HexIotaTypes.NULL) image.userData.remove(HexAPI.RAVENMIND_USERDATA) else image.userData.put(HexAPI.RAVENMIND_USERDATA, IotaType.serialize(newLocal)) - val image2 = image.withUsedOp().copy(stack = stack) + val image2 = image.withUsedOp().copy(stack = stack.init()) return OperationResult(image2, listOf(), continuation, HexEvalSounds.NORMAL_EXECUTE) } } 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..d2f33a8499 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,7 +14,7 @@ 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) 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..d065527d09 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,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.getPositiveLong import at.petrak.hexcasting.api.casting.mishaps.MishapNotEnoughArgs +import at.petrak.hexcasting.api.utils.TreeList import at.petrak.hexcasting.common.lib.hex.HexEvalSounds import it.unimi.dsi.fastutil.longs.LongArrayList @@ -42,7 +43,9 @@ object OpAlwinfyHasAscendedToABeingOfPureMath : Action { editTarget = editTarget.subList(1, editTarget.size) } - val image2 = image.withUsedOp().copy(stack = stack) + // FIXME this is expensive if the stack is incredibly large + // someone should rewrite this op to cut and replace a `slice` of the `TreeList` stack + val image2 = image.withUsedOp().copy(stack = TreeList.from(stack)) return OperationResult(image2, listOf(), continuation, HexEvalSounds.NORMAL_EXECUTE) } 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..5f53dfa950 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,14 +14,14 @@ import kotlin.math.roundToInt object OpFisherman : 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 depth = let { val x = stack.last() - stack.removeLast() + stack = stack.init() val maxIdx = stack.size - 1 if (x is DoubleIota) { val double = x.double @@ -34,11 +34,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..e9999abaff 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,20 @@ 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() + var stack = image.stack if (stack.size < 2) throw MishapNotEnoughArgs(2, stack.size) val depth = stack.getIntBetween(stack.lastIndex, -(stack.size - 2), stack.size - 2) - stack.removeLast() + stack = 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/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/arithmetic/ListArithmetic.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/ListArithmetic.kt index 35a34e61ec..0f0953326f 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 @@ -46,12 +45,12 @@ object ListArithmetic : Arithmetic { 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()) } + 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()) } 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.") } 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..00f71e831b 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.TreeList import kotlin.math.abs import kotlin.math.roundToInt -fun Iterator>.nextList(argc: Int = 0): SpellList { +fun Iterator>.nextList(argc: Int = 0): TreeList { 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/OperatorReplace.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorReplace.kt index ca976369c2..39abe2caee 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,7 +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 import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaPredicate @@ -16,8 +14,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/OperatorUnCons.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorUnCons.kt index 54f0de69c2..0ba55ecb9b 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 @@ -1,6 +1,5 @@ package at.petrak.hexcasting.common.casting.arithmetic.operator.list -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 import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaPredicate @@ -15,8 +14,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