add Huginn's Gambit, Muninn's Reflection, and Surgeon's Exaltation
no patterns for huginn and muninn (yet)
This commit is contained in:
parent
74b6352594
commit
2428d18075
28 changed files with 284 additions and 77 deletions
|
@ -152,7 +152,7 @@ public abstract class BlockEntityAbstractImpetus extends HexBlockEntity implemen
|
|||
if (tag.contains(TAG_ACTIVATOR, Tag.TAG_INT_ARRAY) &&
|
||||
tag.contains(TAG_COLORIZER, Tag.TAG_COMPOUND) &&
|
||||
tag.contains(TAG_NEXT_BLOCK, Tag.TAG_COMPOUND) &&
|
||||
tag.contains(TAG_TRACKED_BLOCKS, Tag.TAG_COMPOUND)) {
|
||||
tag.contains(TAG_TRACKED_BLOCKS, Tag.TAG_LIST)) {
|
||||
this.activator = tag.getUUID(TAG_ACTIVATOR);
|
||||
this.colorizer = FrozenColorizer.deserialize(tag.getCompound(TAG_COLORIZER));
|
||||
this.nextBlock = NbtUtils.readBlockPos(tag.getCompound(TAG_NEXT_BLOCK));
|
||||
|
|
|
@ -14,7 +14,7 @@ interface ConstManaOperator : Operator {
|
|||
|
||||
fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): List<SpellDatum<*>>
|
||||
|
||||
override fun operate(stack: MutableList<SpellDatum<*>>, ctx: CastingContext): OperationResult {
|
||||
override fun operate(stack: MutableList<SpellDatum<*>>, local: SpellDatum<*>, ctx: CastingContext): OperationResult {
|
||||
if (this.argc > stack.size)
|
||||
throw MishapNotEnoughArgs(this.argc, stack.size)
|
||||
val args = stack.takeLast(this.argc)
|
||||
|
@ -24,6 +24,6 @@ interface ConstManaOperator : Operator {
|
|||
|
||||
val sideEffects = mutableListOf<OperatorSideEffect>(OperatorSideEffect.ConsumeMana(this.manaCost))
|
||||
|
||||
return OperationResult(stack, sideEffects)
|
||||
return OperationResult(stack, local, sideEffects)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,4 +5,4 @@ import at.petrak.hexcasting.api.spell.casting.OperatorSideEffect
|
|||
/**
|
||||
* What happens when an operator is through?
|
||||
*/
|
||||
data class OperationResult(val newStack: List<SpellDatum<*>>, val sideEffects: List<OperatorSideEffect>)
|
||||
data class OperationResult(val newStack: List<SpellDatum<*>>, val newLocalIota: SpellDatum<*>, val sideEffects: List<OperatorSideEffect>)
|
||||
|
|
|
@ -23,7 +23,7 @@ interface Operator {
|
|||
*
|
||||
* A particle effect at the cast site and various messages and advancements are done automagically.
|
||||
*/
|
||||
fun operate(stack: MutableList<SpellDatum<*>>, ctx: CastingContext): OperationResult
|
||||
fun operate(stack: MutableList<SpellDatum<*>>, local: SpellDatum<*>, ctx: CastingContext): OperationResult
|
||||
|
||||
/**
|
||||
* Do you need to be enlightened to use this operator?
|
||||
|
|
|
@ -5,6 +5,7 @@ import at.petrak.hexcasting.api.spell.math.HexPattern
|
|||
import at.petrak.hexcasting.api.spell.mishaps.MishapInvalidSpellDatumType
|
||||
import at.petrak.hexcasting.api.utils.HexUtils
|
||||
import at.petrak.hexcasting.api.utils.HexUtils.serializeToNBT
|
||||
import at.petrak.hexcasting.api.utils.getList
|
||||
import net.minecraft.ChatFormatting
|
||||
import net.minecraft.nbt.*
|
||||
import net.minecraft.network.chat.Component
|
||||
|
@ -144,7 +145,7 @@ class SpellDatum<T : Any> private constructor(val payload: T) {
|
|||
TAG_DOUBLE -> SpellDatum(nbt.getDouble(key))
|
||||
TAG_VEC3 -> SpellDatum(HexUtils.DeserializeVec3FromNBT(nbt.getLongArray(key)))
|
||||
TAG_LIST -> {
|
||||
val arr = nbt.getList(key, Tag.TAG_COMPOUND.toInt())
|
||||
val arr = nbt.getList(key, Tag.TAG_COMPOUND)
|
||||
val out = ArrayList<SpellDatum<*>>(arr.size)
|
||||
for (subtag in arr) {
|
||||
// this is safe because otherwise we wouldn't have been able to get the list before
|
||||
|
@ -188,7 +189,7 @@ class SpellDatum<T : Any> private constructor(val payload: T) {
|
|||
TAG_LIST -> {
|
||||
val out = TextComponent("[").withStyle(ChatFormatting.WHITE)
|
||||
|
||||
val arr = nbt.getList(key, Tag.TAG_COMPOUND.toInt())
|
||||
val arr = nbt.getList(key, Tag.TAG_COMPOUND)
|
||||
for ((i, subtag) in arr.withIndex()) {
|
||||
// this is safe because otherwise we wouldn't have been able to get the list before
|
||||
out.append(DisplayFromTag(subtag as CompoundTag))
|
||||
|
|
|
@ -16,12 +16,12 @@ interface SpellOperator : Operator {
|
|||
ctx: CastingContext
|
||||
): Triple<RenderedSpell, Int, List<ParticleSpray>>?
|
||||
|
||||
override fun operate(stack: MutableList<SpellDatum<*>>, ctx: CastingContext): OperationResult {
|
||||
override fun operate(stack: MutableList<SpellDatum<*>>, local: SpellDatum<*>, ctx: CastingContext): OperationResult {
|
||||
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 executeResult = this.execute(args, ctx) ?: return OperationResult(stack, listOf())
|
||||
val executeResult = this.execute(args, ctx) ?: return OperationResult(stack, local, listOf())
|
||||
val (spell, mana, particles) = executeResult
|
||||
|
||||
val sideEffects = mutableListOf(
|
||||
|
@ -32,7 +32,7 @@ interface SpellOperator : Operator {
|
|||
sideEffects.add(OperatorSideEffect.Particles(spray))
|
||||
}
|
||||
|
||||
return OperationResult(stack, sideEffects)
|
||||
return OperationResult(stack, local, sideEffects)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,9 +15,12 @@ import at.petrak.hexcasting.api.spell.Widget
|
|||
import at.petrak.hexcasting.api.spell.math.HexPattern
|
||||
import at.petrak.hexcasting.api.spell.mishaps.Mishap
|
||||
import at.petrak.hexcasting.api.spell.mishaps.MishapDisallowedSpell
|
||||
import at.petrak.hexcasting.api.spell.mishaps.MishapError
|
||||
import at.petrak.hexcasting.api.spell.mishaps.MishapTooManyCloseParens
|
||||
import at.petrak.hexcasting.api.utils.ManaHelper
|
||||
import at.petrak.hexcasting.xplat.IXplatAbstractions
|
||||
import at.petrak.hexcasting.api.utils.asCompound
|
||||
import at.petrak.hexcasting.api.utils.getList
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.nbt.ListTag
|
||||
import net.minecraft.nbt.Tag
|
||||
|
@ -33,6 +36,7 @@ import kotlin.math.min
|
|||
*/
|
||||
class CastingHarness private constructor(
|
||||
var stack: MutableList<SpellDatum<*>>,
|
||||
var localIota: SpellDatum<*>,
|
||||
var parenCount: Int,
|
||||
var parenthesized: List<HexPattern>,
|
||||
var escapeNext: Boolean,
|
||||
|
@ -44,7 +48,7 @@ class CastingHarness private constructor(
|
|||
constructor(
|
||||
ctx: CastingContext,
|
||||
prepackagedColorizer: FrozenColorizer? = null
|
||||
) : this(mutableListOf(), 0, mutableListOf(), false, ctx, prepackagedColorizer)
|
||||
) : this(mutableListOf(), SpellDatum.make(Widget.NULL), 0, mutableListOf(), false, ctx, prepackagedColorizer)
|
||||
|
||||
/**
|
||||
* Given a pattern, do all the updating/side effects/etc required.
|
||||
|
@ -80,7 +84,8 @@ class CastingHarness private constructor(
|
|||
if (!HexConfig.server().isActionAllowed(operatorIdPair.second)) {
|
||||
throw MishapDisallowedSpell()
|
||||
}
|
||||
val (stack2, sideEffectsUnmut) = operatorIdPair.first.operate(this.stack.toMutableList(), this.ctx)
|
||||
val (stack2, local2, sideEffectsUnmut) = operatorIdPair.first.operate(this.stack.toMutableList(), this.localIota, this.ctx)
|
||||
this.localIota = local2
|
||||
// Stick a poofy particle effect at the caster position
|
||||
val sideEffects = sideEffectsUnmut.toMutableList()
|
||||
if (this.ctx.spellCircle == null)
|
||||
|
@ -107,6 +112,12 @@ class CastingHarness private constructor(
|
|||
this.getFunctionalData(),
|
||||
listOf(OperatorSideEffect.DoMishap(mishap, Mishap.Context(newPat, operatorIdPair?.second))),
|
||||
)
|
||||
} catch (exception: Exception) {
|
||||
exception.printStackTrace()
|
||||
return CastResult(
|
||||
this.getFunctionalData(),
|
||||
listOf(OperatorSideEffect.DoMishap(MishapError(exception), Mishap.Context(newPat, operatorIdPair?.second)))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -339,6 +350,8 @@ class CastingHarness private constructor(
|
|||
stackTag.add(datum.serializeToNBT())
|
||||
out.put(TAG_STACK, stackTag)
|
||||
|
||||
out.put(TAG_LOCAL, localIota.serializeToNBT())
|
||||
|
||||
out.putInt(TAG_PAREN_COUNT, this.parenCount)
|
||||
out.putBoolean(TAG_ESCAPE_NEXT, this.escapeNext)
|
||||
|
||||
|
@ -357,25 +370,29 @@ class CastingHarness private constructor(
|
|||
|
||||
companion object {
|
||||
const val TAG_STACK = "stack"
|
||||
const val TAG_LOCAL = "local"
|
||||
const val TAG_PAREN_COUNT = "open_parens"
|
||||
const val TAG_PARENTHESIZED = "parenthesized"
|
||||
const val TAG_ESCAPE_NEXT = "escape_next"
|
||||
const val TAG_PREPACKAGED_COLORIZER = "prepackaged_colorizer"
|
||||
|
||||
@JvmStatic
|
||||
fun DeserializeFromNBT(nbt: Tag, ctx: CastingContext): CastingHarness {
|
||||
fun DeserializeFromNBT(nbt: CompoundTag, ctx: CastingContext): CastingHarness {
|
||||
return try {
|
||||
val stack = mutableListOf<SpellDatum<*>>()
|
||||
val stackTag = (nbt as CompoundTag).getList(TAG_STACK, Tag.TAG_COMPOUND.toInt())
|
||||
val stackTag = nbt.getList(TAG_STACK, Tag.TAG_COMPOUND)
|
||||
for (subtag in stackTag) {
|
||||
val datum = SpellDatum.DeserializeFromNBT(subtag as CompoundTag, ctx.world)
|
||||
val datum = SpellDatum.DeserializeFromNBT(subtag.asCompound, ctx.world)
|
||||
stack.add(datum)
|
||||
}
|
||||
|
||||
val localTag = nbt.getCompound(TAG_LOCAL)
|
||||
val localIota = SpellDatum.DeserializeFromNBT(localTag, ctx.world)
|
||||
|
||||
val parenthesized = mutableListOf<HexPattern>()
|
||||
val parenTag = nbt.getList(TAG_PARENTHESIZED, Tag.TAG_COMPOUND.toInt())
|
||||
val parenTag = nbt.getList(TAG_PARENTHESIZED, Tag.TAG_COMPOUND)
|
||||
for (subtag in parenTag) {
|
||||
parenthesized.add(HexPattern.DeserializeFromNBT(subtag as CompoundTag))
|
||||
parenthesized.add(HexPattern.DeserializeFromNBT(subtag.asCompound))
|
||||
}
|
||||
|
||||
val parenCount = nbt.getInt(TAG_PAREN_COUNT)
|
||||
|
@ -387,7 +404,7 @@ class CastingHarness private constructor(
|
|||
null
|
||||
}
|
||||
|
||||
CastingHarness(stack, parenCount, parenthesized, escapeNext, ctx, colorizer)
|
||||
CastingHarness(stack, localIota, parenCount, parenthesized, escapeNext, ctx, colorizer)
|
||||
} catch (exn: Exception) {
|
||||
CastingHarness(ctx)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
package at.petrak.hexcasting.api.spell.mishaps
|
||||
|
||||
import at.petrak.hexcasting.api.misc.FrozenColorizer
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.world.item.DyeColor
|
||||
|
||||
class MishapError(val exception: Exception) : Mishap() {
|
||||
override fun accentColor(ctx: CastingContext, errorCtx: Context): FrozenColorizer =
|
||||
dyeColor(DyeColor.BLACK)
|
||||
|
||||
override fun execute(ctx: CastingContext, errorCtx: Context, stack: MutableList<SpellDatum<*>>) {
|
||||
}
|
||||
|
||||
override fun errorMessage(ctx: CastingContext, errorCtx: Context): Component =
|
||||
error("unknown", actionName(errorCtx.action), exception)
|
||||
}
|
|
@ -1,9 +1,7 @@
|
|||
@file:JvmName("NBTHelper")
|
||||
package at.petrak.hexcasting.api.utils
|
||||
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.nbt.ListTag
|
||||
import net.minecraft.nbt.Tag
|
||||
import net.minecraft.nbt.*
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import java.util.*
|
||||
|
||||
|
@ -85,14 +83,76 @@ fun CompoundTag?.getIntArray(key: String) = getIf(key, CompoundTag?::hasIntArray
|
|||
fun CompoundTag?.getByteArray(key: String) = getIf(key, CompoundTag?::hasByteArray, CompoundTag::getByteArray)
|
||||
fun CompoundTag?.getCompound(key: String): CompoundTag? = getIf(key, CompoundTag?::hasCompound, CompoundTag::getCompound)
|
||||
fun CompoundTag?.getString(key: String) = getIf(key, CompoundTag?::hasString, CompoundTag::getString)
|
||||
fun CompoundTag?.getList(key: String, objType: Byte) = getList(key, objType.toInt())
|
||||
fun CompoundTag?.getList(key: String, objType: Int) = getIf(key, { hasList(key, objType) }) { getList(it, objType) }
|
||||
fun CompoundTag?.getUUID(key: String) = getIf(key, CompoundTag?::hasUUID, CompoundTag::getUUID)
|
||||
fun CompoundTag?.get(key: String) = getIf(key, CompoundTag?::contains, CompoundTag::get)
|
||||
|
||||
@JvmSynthetic
|
||||
@JvmName("getListByByte")
|
||||
fun CompoundTag.getList(key: String, objType: Byte): ListTag = getList(key, objType.toInt())
|
||||
|
||||
// Get-or-create
|
||||
|
||||
fun CompoundTag.getOrCreateCompound(key: String) = getCompound(key) ?: CompoundTag().also { putCompound(key, this) }
|
||||
|
||||
// ================================================================================================================ Tag
|
||||
|
||||
val Tag.asBoolean get() = asByte == 0.toByte()
|
||||
val Tag.asByte get() = (this as? NumericTag)?.asByte ?: 0.toByte()
|
||||
val Tag.asShort get() = (this as? NumericTag)?.asShort ?: 0.toShort()
|
||||
val Tag.asInt get() = (this as? NumericTag)?.asInt ?: 0
|
||||
val Tag.asLong get() = (this as? NumericTag)?.asLong ?: 0L
|
||||
val Tag.asFloat get() = (this as? NumericTag)?.asFloat ?: 0F
|
||||
val Tag.asDouble get() = (this as? NumericTag)?.asDouble ?: 0.0
|
||||
|
||||
val Tag.asLongArray: LongArray
|
||||
get() = when (this) {
|
||||
is LongArrayTag -> this.asLongArray
|
||||
is IntArrayTag -> {
|
||||
val array = this.asIntArray
|
||||
LongArray(array.size) { array[it].toLong() }
|
||||
}
|
||||
is ByteArrayTag -> {
|
||||
val array = this.asByteArray
|
||||
LongArray(array.size) { array[it].toLong() }
|
||||
}
|
||||
else -> LongArray(0)
|
||||
}
|
||||
|
||||
val Tag.asIntArray: IntArray
|
||||
get() = when (this) {
|
||||
is IntArrayTag -> this.asIntArray
|
||||
is LongArrayTag -> {
|
||||
val array = this.asLongArray
|
||||
IntArray(array.size) { array[it].toInt() }
|
||||
}
|
||||
is ByteArrayTag -> {
|
||||
val array = this.asByteArray
|
||||
IntArray(array.size) { array[it].toInt() }
|
||||
}
|
||||
else -> IntArray(0)
|
||||
}
|
||||
|
||||
val Tag.asByteArray: ByteArray
|
||||
get() = when (this) {
|
||||
is ByteArrayTag -> this.asByteArray
|
||||
is LongArrayTag -> {
|
||||
val array = this.asLongArray
|
||||
ByteArray(array.size) { array[it].toByte() }
|
||||
}
|
||||
is IntArrayTag -> {
|
||||
val array = this.asIntArray
|
||||
ByteArray(array.size) { array[it].toByte() }
|
||||
}
|
||||
else -> ByteArray(0)
|
||||
}
|
||||
|
||||
val Tag.asCompound get() = this as? CompoundTag ?: CompoundTag()
|
||||
// asString is defined in Tag
|
||||
val Tag.asList get() = this as? ListTag ?: ListTag()
|
||||
val Tag.asUUID: UUID get() = if (this is IntArrayTag && this.size == 4) NbtUtils.loadUUID(this) else UUID(0, 0)
|
||||
|
||||
// ========================================================================================================== ItemStack
|
||||
|
||||
// Checks for containment
|
||||
|
|
|
@ -4,25 +4,31 @@ import at.petrak.hexcasting.api.client.ScryingLensOverlayRegistry;
|
|||
import at.petrak.hexcasting.api.player.Sentinel;
|
||||
import at.petrak.hexcasting.common.lib.HexItems;
|
||||
import at.petrak.hexcasting.xplat.IXplatAbstractions;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.Tesselator;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import com.mojang.math.Quaternion;
|
||||
import com.mojang.math.Vector3f;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.locale.Language;
|
||||
import net.minecraft.network.chat.FormattedText;
|
||||
import net.minecraft.network.chat.Style;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public class HexAdditionalRenderers {
|
||||
|
@ -140,21 +146,24 @@ public class HexAdditionalRenderers {
|
|||
}
|
||||
}
|
||||
|
||||
// My internet is really shaky right now but thank god Patchi already does this exact thing
|
||||
// cause it's a dependency so i have the .class files downloaded
|
||||
private static void tryRenderScryingLensOverlay(PoseStack ps, float partialTicks) {
|
||||
var mc = Minecraft.getInstance();
|
||||
|
||||
LocalPlayer player = mc.player;
|
||||
ClientLevel level = mc.level;
|
||||
if (player == null || level == null)
|
||||
return;
|
||||
|
||||
boolean foundLens = false;
|
||||
InteractionHand lensHand = null;
|
||||
for (var hand : InteractionHand.values()) {
|
||||
if (mc.player.getItemInHand(hand).is(HexItems.SCRYING_LENS)) {
|
||||
if (player.getItemInHand(hand).is(HexItems.SCRYING_LENS)) {
|
||||
lensHand = hand;
|
||||
foundLens = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!foundLens && mc.player.getItemBySlot(EquipmentSlot.HEAD).is(HexItems.SCRYING_LENS)) {
|
||||
if (!foundLens && player.getItemBySlot(EquipmentSlot.HEAD).is(HexItems.SCRYING_LENS)) {
|
||||
foundLens = true;
|
||||
}
|
||||
|
||||
|
@ -163,24 +172,38 @@ public class HexAdditionalRenderers {
|
|||
}
|
||||
|
||||
var hitRes = mc.hitResult;
|
||||
if (hitRes.getType() == HitResult.Type.BLOCK) {
|
||||
if (hitRes != null && hitRes.getType() == HitResult.Type.BLOCK) {
|
||||
var bhr = (BlockHitResult) hitRes;
|
||||
var pos = bhr.getBlockPos();
|
||||
var bs = mc.level.getBlockState(pos);
|
||||
var bs = level.getBlockState(pos);
|
||||
|
||||
var lineSpace = 9.0 * (mc.options.chatLineSpacing + 1.0);
|
||||
var lines = ScryingLensOverlayRegistry.getLines(bs, pos, player, level, bhr.getDirection(), lensHand);
|
||||
|
||||
int totalHeight = 8;
|
||||
List<Pair<ItemStack, List<FormattedText>>> actualLines = Lists.newArrayList();
|
||||
|
||||
var window = mc.getWindow();
|
||||
var maxWidth = (int) (window.getGuiScaledWidth() / 2f * 0.8f);
|
||||
|
||||
for (var pair : lines) {
|
||||
totalHeight += mc.font.lineHeight + 6;
|
||||
var text = pair.getSecond();
|
||||
var textLines = mc.font.getSplitter().splitLines(text, maxWidth, Style.EMPTY);
|
||||
|
||||
actualLines.add(Pair.of(pair.getFirst(), textLines));
|
||||
|
||||
if (textLines.size() > 1) {
|
||||
totalHeight += mc.font.lineHeight * (textLines.size() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
var lines = ScryingLensOverlayRegistry.getLines(bs, pos, mc.player, mc.level, bhr.getDirection(), lensHand);
|
||||
if (!lines.isEmpty()) {
|
||||
var window = mc.getWindow();
|
||||
var x = window.getGuiScaledWidth() / 2f + 8f;
|
||||
var y = window.getGuiScaledHeight() / 2f;
|
||||
var y = window.getGuiScaledHeight() / 2f - totalHeight;
|
||||
ps.pushPose();
|
||||
ps.translate(x, y, 0);
|
||||
|
||||
var maxWidth = (int) (window.getGuiScaledWidth() / 2f * 0.8f);
|
||||
|
||||
for (var pair : lines) {
|
||||
for (var pair : actualLines) {
|
||||
var stack = pair.getFirst();
|
||||
if (!stack.isEmpty()) {
|
||||
// this draws centered in the Y ...
|
||||
|
@ -190,18 +213,14 @@ public class HexAdditionalRenderers {
|
|||
float ty = 5;
|
||||
// but this draws where y=0 is the baseline
|
||||
var text = pair.getSecond();
|
||||
var textLines = mc.font.getSplitter().splitLines(text, maxWidth, Style.EMPTY);
|
||||
|
||||
for (var line : textLines) {
|
||||
for (var line : text) {
|
||||
var actualLine = Language.getInstance().getVisualOrder(line);
|
||||
mc.font.drawShadow(ps, actualLine, tx, ty, 0xffffffff);
|
||||
ps.translate(0, lineSpace, 0);
|
||||
ps.translate(0, mc.font.lineHeight, 0);
|
||||
}
|
||||
if (textLines.isEmpty()) {
|
||||
ps.translate(0, lineSpace, 0);
|
||||
}
|
||||
|
||||
ps.translate(0, lineSpace * 0.66666, 0);
|
||||
if (text.isEmpty())
|
||||
ps.translate(0, mc.font.lineHeight, 0);
|
||||
}
|
||||
|
||||
ps.popPose();
|
||||
|
|
|
@ -448,6 +448,8 @@ public class RegisterPatterns {
|
|||
OpRemove.INSTANCE);
|
||||
PatternRegistry.mapPattern(HexPattern.FromAnglesSig("qaeaqwded", HexDir.NORTH_WEST), modLoc("slice"),
|
||||
OpSlice.INSTANCE);
|
||||
PatternRegistry.mapPattern(HexPattern.FromAnglesSig("wqaeaqw", HexDir.NORTH_WEST), prefix("modify_in_place"),
|
||||
OpModifyInPlace.INSTANCE);
|
||||
|
||||
} catch (PatternRegistry.RegisterPatternException exn) {
|
||||
exn.printStackTrace();
|
||||
|
|
|
@ -4,11 +4,11 @@ import at.petrak.hexcasting.api.misc.ManaConstants
|
|||
import at.petrak.hexcasting.api.spell.ConstManaOperator
|
||||
import at.petrak.hexcasting.api.spell.Operator.Companion.getChecked
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.common.blocks.akashic.BlockEntityAkashicRecord
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import at.petrak.hexcasting.api.spell.Widget
|
||||
import at.petrak.hexcasting.api.spell.mishaps.MishapNoAkashicRecord
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import at.petrak.hexcasting.api.spell.math.HexPattern
|
||||
import at.petrak.hexcasting.api.spell.mishaps.MishapNoAkashicRecord
|
||||
import at.petrak.hexcasting.common.blocks.akashic.BlockEntityAkashicRecord
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
|
|
|
@ -7,18 +7,19 @@ import at.petrak.hexcasting.api.spell.SpellDatum
|
|||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingHarness
|
||||
import at.petrak.hexcasting.api.spell.casting.OperatorSideEffect
|
||||
import at.petrak.hexcasting.api.spell.mishaps.MishapInvalidIota
|
||||
import at.petrak.hexcasting.api.spell.math.HexPattern
|
||||
import at.petrak.hexcasting.api.spell.mishaps.MishapInvalidIota
|
||||
import net.minecraft.network.chat.TranslatableComponent
|
||||
|
||||
object OpEval : Operator {
|
||||
override fun operate(stack: MutableList<SpellDatum<*>>, ctx: CastingContext): OperationResult {
|
||||
override fun operate(stack: MutableList<SpellDatum<*>>, local: SpellDatum<*>, ctx: CastingContext): OperationResult {
|
||||
val instrs: List<SpellDatum<*>> = stack.getChecked(stack.lastIndex)
|
||||
stack.removeLastOrNull()
|
||||
|
||||
ctx.incDepth()
|
||||
val harness = CastingHarness(ctx)
|
||||
harness.stack.addAll(stack)
|
||||
harness.localIota = local
|
||||
|
||||
val sideEffects = mutableListOf<OperatorSideEffect>()
|
||||
|
||||
|
@ -35,8 +36,7 @@ object OpEval : Operator {
|
|||
}
|
||||
harness.applyFunctionalData(res.newData)
|
||||
}
|
||||
stack.addAll(harness.stack)
|
||||
|
||||
return OperationResult(harness.stack, sideEffects)
|
||||
return OperationResult(harness.stack, harness.localIota, sideEffects)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import at.petrak.hexcasting.api.spell.SpellDatum
|
|||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
|
||||
object OpEvalDelay : Operator {
|
||||
override fun operate(stack: MutableList<SpellDatum<*>>, ctx: CastingContext): OperationResult {
|
||||
return OperationResult(stack, listOf())
|
||||
override fun operate(stack: MutableList<SpellDatum<*>>, local: SpellDatum<*>, ctx: CastingContext): OperationResult {
|
||||
return OperationResult(stack, local, listOf())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ import at.petrak.hexcasting.api.spell.mishaps.MishapNotEnoughArgs
|
|||
import net.minecraft.network.chat.TranslatableComponent
|
||||
|
||||
object OpForEach : Operator {
|
||||
override fun operate(stack: MutableList<SpellDatum<*>>, ctx: CastingContext): OperationResult {
|
||||
override fun operate(stack: MutableList<SpellDatum<*>>, local: SpellDatum<*>, ctx: CastingContext): OperationResult {
|
||||
if (stack.size < 2)
|
||||
throw MishapNotEnoughArgs(2, stack.size)
|
||||
|
||||
|
@ -25,11 +25,14 @@ object OpForEach : Operator {
|
|||
val out = mutableListOf<SpellDatum<*>>()
|
||||
val sideEffects = mutableListOf<OperatorSideEffect>()
|
||||
|
||||
var localIota = local
|
||||
|
||||
for (subdatum in datums) {
|
||||
ctx.incDepth()
|
||||
val harness = CastingHarness(ctx)
|
||||
harness.stack.addAll(stack)
|
||||
harness.stack.add(subdatum)
|
||||
harness.localIota = localIota
|
||||
for (pat in instrs) {
|
||||
val pattern = if (pat.payload is HexPattern) {
|
||||
pat.payload
|
||||
|
@ -43,14 +46,15 @@ object OpForEach : Operator {
|
|||
val res = harness.getUpdate(pattern, ctx.world)
|
||||
sideEffects.addAll(res.sideEffects)
|
||||
if (res.sideEffects.any { it is OperatorSideEffect.DoMishap }) {
|
||||
return OperationResult(harness.stack, sideEffects)
|
||||
return OperationResult(harness.stack, harness.localIota, sideEffects)
|
||||
}
|
||||
harness.applyFunctionalData(res.newData)
|
||||
}
|
||||
out.addAll(harness.stack)
|
||||
localIota = harness.localIota
|
||||
}
|
||||
stack.add(SpellDatum.make(out))
|
||||
|
||||
return OperationResult(stack, sideEffects)
|
||||
return OperationResult(stack, localIota, sideEffects)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ import at.petrak.hexcasting.api.spell.Operator.Companion.getChecked
|
|||
import at.petrak.hexcasting.api.spell.Operator.Companion.spellListOf
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import at.petrak.hexcasting.api.spell.casting.OperatorSideEffect
|
||||
import at.petrak.hexcasting.api.spell.mishaps.MishapInvalidIota
|
||||
import at.petrak.hexcasting.api.spell.mishaps.MishapNotEnoughArgs
|
||||
import net.minecraft.network.chat.TranslatableComponent
|
||||
|
@ -14,7 +13,7 @@ import kotlin.math.abs
|
|||
import kotlin.math.roundToInt
|
||||
|
||||
object OpLastNToList : Operator {
|
||||
override fun operate(stack: MutableList<SpellDatum<*>>, ctx: CastingContext): OperationResult {
|
||||
override fun operate(stack: MutableList<SpellDatum<*>>, local: SpellDatum<*>, ctx: CastingContext): OperationResult {
|
||||
if (stack.isEmpty())
|
||||
throw MishapNotEnoughArgs(1, 0)
|
||||
val arg = stack.takeLast(1).getChecked<Double>(0)
|
||||
|
@ -35,6 +34,6 @@ object OpLastNToList : Operator {
|
|||
}
|
||||
stack.addAll(spellListOf(output))
|
||||
|
||||
return OperationResult(stack, listOf())
|
||||
return OperationResult(stack, local, listOf())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.lists
|
||||
|
||||
import at.petrak.hexcasting.api.spell.ConstManaOperator
|
||||
import at.petrak.hexcasting.api.spell.Operator.Companion.getChecked
|
||||
import at.petrak.hexcasting.api.spell.Operator.Companion.spellListOf
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
object OpModifyInPlace : ConstManaOperator {
|
||||
override val argc = 3
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): List<SpellDatum<*>> {
|
||||
val list = args.getChecked<List<SpellDatum<*>>>(0)
|
||||
val index = args.getChecked<Double>(1).roundToInt()
|
||||
val iota = args[2]
|
||||
|
||||
if (0 > index || index > list.size)
|
||||
return spellListOf(list)
|
||||
|
||||
|
||||
val newList = list.toMutableList()
|
||||
if (index == list.size)
|
||||
newList.add(iota)
|
||||
else
|
||||
newList[index] = iota
|
||||
|
||||
return spellListOf(newList)
|
||||
}
|
||||
}
|
|
@ -10,13 +10,13 @@ import at.petrak.hexcasting.api.spell.mishaps.MishapNotEnoughArgs
|
|||
import net.minecraft.Util
|
||||
|
||||
object OpPrint : Operator {
|
||||
override fun operate(stack: MutableList<SpellDatum<*>>, ctx: CastingContext): OperationResult {
|
||||
override fun operate(stack: MutableList<SpellDatum<*>>, local: SpellDatum<*>, ctx: CastingContext): OperationResult {
|
||||
if (stack.isEmpty()) {
|
||||
throw MishapNotEnoughArgs(1, 0)
|
||||
}
|
||||
val datum = stack[stack.lastIndex]
|
||||
return OperationResult(
|
||||
stack, listOf(
|
||||
stack, local, listOf(
|
||||
OperatorSideEffect.AttemptSpell(Spell(datum), false)
|
||||
)
|
||||
)
|
||||
|
|
|
@ -82,7 +82,11 @@ object OpFlight : SpellOperator {
|
|||
abilities.mayfly = false
|
||||
entity.onUpdateAbilities()
|
||||
}
|
||||
} else
|
||||
} else {
|
||||
if (!entity.abilities.mayfly) {
|
||||
entity.abilities.mayfly = true
|
||||
entity.onUpdateAbilities()
|
||||
}
|
||||
IXplatAbstractions.INSTANCE.setFlight(
|
||||
entity,
|
||||
FlightAbility(
|
||||
|
@ -93,6 +97,7 @@ object OpFlight : SpellOperator {
|
|||
flight.radius
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ import kotlin.math.roundToInt
|
|||
|
||||
// "lehmer code"
|
||||
object OpAlwinfyHasAscendedToABeingOfPureMath : Operator {
|
||||
override fun operate(stack: MutableList<SpellDatum<*>>, ctx: CastingContext): OperationResult {
|
||||
override fun operate(stack: MutableList<SpellDatum<*>>, local: SpellDatum<*>, ctx: CastingContext): OperationResult {
|
||||
if (stack.isEmpty())
|
||||
throw MishapNotEnoughArgs(1, 0) // todo: better message?
|
||||
|
||||
|
@ -56,6 +56,7 @@ object OpAlwinfyHasAscendedToABeingOfPureMath : Operator {
|
|||
|
||||
return OperationResult(
|
||||
stack,
|
||||
local,
|
||||
listOf(OperatorSideEffect.ConsumeMana(cost))
|
||||
)
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ import kotlin.math.abs
|
|||
import kotlin.math.roundToInt
|
||||
|
||||
object OpFisherman : Operator {
|
||||
override fun operate(stack: MutableList<SpellDatum<*>>, ctx: CastingContext): OperationResult {
|
||||
override fun operate(stack: MutableList<SpellDatum<*>>, local: SpellDatum<*>, ctx: CastingContext): OperationResult {
|
||||
if (stack.isEmpty())
|
||||
throw MishapNotEnoughArgs(1, 0)
|
||||
val arg = stack.getChecked<Double>(stack.lastIndex)
|
||||
|
@ -31,6 +31,6 @@ object OpFisherman : Operator {
|
|||
)
|
||||
}
|
||||
|
||||
return OperationResult(stack, listOf())
|
||||
return OperationResult(stack, local, listOf())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,19 +2,12 @@ package at.petrak.hexcasting.common.casting.operators.stack
|
|||
|
||||
import at.petrak.hexcasting.api.spell.OperationResult
|
||||
import at.petrak.hexcasting.api.spell.Operator
|
||||
import at.petrak.hexcasting.api.spell.Operator.Companion.getChecked
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import at.petrak.hexcasting.api.spell.casting.OperatorSideEffect
|
||||
import at.petrak.hexcasting.api.spell.mishaps.MishapInvalidIota
|
||||
import at.petrak.hexcasting.api.spell.mishaps.MishapNotEnoughArgs
|
||||
import net.minecraft.network.chat.TranslatableComponent
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
object OpStackSize : Operator {
|
||||
override fun operate(stack: MutableList<SpellDatum<*>>, ctx: CastingContext): OperationResult {
|
||||
override fun operate(stack: MutableList<SpellDatum<*>>, local: SpellDatum<*>, ctx: CastingContext): OperationResult {
|
||||
stack.add(SpellDatum.make(stack.size.toDouble()))
|
||||
return OperationResult(stack, listOf())
|
||||
return OperationResult(stack, local, listOf())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import org.spongepowered.asm.mixin.Mixin;
|
|||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
// Prevents the villager from any of its brain goals
|
||||
@Mixin(Villager.class)
|
||||
|
@ -17,4 +18,12 @@ public class MixinVillager {
|
|||
ci.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "canBreed", at = @At("HEAD"), cancellable = true)
|
||||
private void preventBreeding(CallbackInfoReturnable<Boolean> cir) {
|
||||
var self = (Villager) (Object) this;
|
||||
if (Brainsweeping.isBrainswept(self)) {
|
||||
cir.setReturnValue(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -198,6 +198,7 @@
|
|||
"hexcasting.spell.hexcasting:index_of": "Locator's Distillation",
|
||||
"hexcasting.spell.hexcasting:list_remove": "Excisor's Distillation",
|
||||
"hexcasting.spell.hexcasting:slice": "Selection Exaltation",
|
||||
"hexcasting.spell.hexcasting:modify_in_place": "Surgeon's Exaltation",
|
||||
"hexcasting.spell.hexcasting:get_entity": "Entity Purification",
|
||||
"hexcasting.spell.hexcasting:get_entity/animal": "Entity Prfn.: Animal",
|
||||
"hexcasting.spell.hexcasting:get_entity/monster": "Entity Prfn.: Monster",
|
||||
|
@ -307,6 +308,8 @@
|
|||
"hexcasting.spell.hexcasting:escape": "Consideration",
|
||||
"hexcasting.spell.hexcasting:eval": "Hermes' Gambit",
|
||||
"hexcasting.spell.hexcasting:eval/delay": "Secret Gambit!",
|
||||
"hexcasting.spell.hexcasting:read_local": "Muginn's Reflection",
|
||||
"hexcasting.spell.hexcasting:write_local": "Huginn's Gambit",
|
||||
"hexcasting.spell.hexcasting:read": "Scribe's Reflection",
|
||||
"hexcasting.spell.hexcasting:write": "Scribe's Gambit",
|
||||
"hexcasting.spell.hexcasting:readable": "Auditor's Reflection",
|
||||
|
@ -333,7 +336,6 @@
|
|||
"hexcasting.spell.unknown": "Special Handler",
|
||||
|
||||
"hexcasting.mishap.invalid_pattern": "That pattern isn't associated with any action",
|
||||
"hexcasting.mishap.invalid_spell_datum_type": "Tried to use a value of invalid type as a SpellDatum: %s (class %s). This is a bug in the mod.",
|
||||
"hexcasting.mishap.invalid_value": "%s expected %s at index %s of the stack, but got %s",
|
||||
"hexcasting.mishap.invalid_value.class.double": "a number",
|
||||
"hexcasting.mishap.invalid_value.class.vector": "a vector",
|
||||
|
@ -391,6 +393,8 @@
|
|||
"hexcasting.mishap.divide_by_zero.cos": "the cosine of %s",
|
||||
"hexcasting.mishap.no_akashic_record": "No Akashic Record at %s",
|
||||
"hexcasting.mishap.disallowed": "%s has been disallowed by the server admins",
|
||||
"hexcasting.mishap.invalid_spell_datum_type": "Tried to use a value of invalid type as a SpellDatum: %s (class %s). This is a bug in the mod.",
|
||||
"hexcasting.mishap.unknown": "%s threw an exception (%s). This is a bug in the mod.",
|
||||
|
||||
"hexcasting.landing": "I seem to have discovered a new method of magical arts, in which one draws patterns strange and wild onto a hexagonal grid. It fascinates me. I've decided to start a journal of my thoughts and findings.$(br2)$(l:https://discord.gg/4xxHGYteWk)Discord Server Link/$",
|
||||
|
||||
|
@ -500,8 +504,8 @@
|
|||
"hexcasting.page.mishaps.true_name": "I attempted to $(l:patterns/readwrite#hexcasting:write)$(action)save a reference/$ to another player to a permanent medium.$(br2)Causes black sparks, and robs me of my sight for approximately one minute.",
|
||||
"hexcasting.page.mishaps.disabled.title": "Disallowed Action",
|
||||
"hexcasting.page.mishaps.disabled": "I tried to cast an action that has been disallowed by a server administrator.$(br2)Causes black sparks.",
|
||||
"hexcasting.page.mishaps.invalid_iota.title": "Invalid Iota Type",
|
||||
"hexcasting.page.mishaps.invalid_iota": "A bug in the mod caused an iota of an invalid type. $(l:https://https://github.com/gamma-delta/HexMod/issues)Please open a bug report!/$$(br2)Causes black sparks.",
|
||||
"hexcasting.page.mishaps.other.title": "Catastrophic Failure",
|
||||
"hexcasting.page.mishaps.other": "A bug in the mod caused an iota of an invalid type or otherwise caused the spell to crash. $(l:https://https://github.com/gamma-delta/HexMod/issues)Please open a bug report!/$$(br2)Causes black sparks.",
|
||||
|
||||
"hexcasting.entry.stack": "Stacks",
|
||||
"hexcasting.page.stack.1": "A $(thing)Stack/$, also known as a \"LIFO\", is a concept borrowed from computer science. In short, it's a collection of things designed so that you can only interact with the most recently used thing.$(br2)Think of a stack of plates, where new plates are added to the top: if you want to interact with a plate halfway down the stack, you have to remove the plates above it in order to get ahold of it.",
|
||||
|
@ -797,6 +801,7 @@
|
|||
"hexcasting.page.lists.reverse_list": "Reverse the list at the top of the stack.",
|
||||
"hexcasting.page.lists.index_of": "Remove the iota at the top of the stack, then replace the list at the top with the first index of that iota within the list (starting from 0). Replaces the list with -1 if the iota doesn't exist in the list.",
|
||||
"hexcasting.page.lists.list_remove": "Remove the number at the top of the stack, then remove the nth element of the list at the top of the stack (where n is the number you removed).",
|
||||
"hexcasting.page.lists.modify_in_place": "Remove the top iota of the stack and the number at the top, then set the nth element of the list at the top of the stack to that iota (where n is the number you removed). Does nothing if the number is out of bounds.",
|
||||
|
||||
"hexcasting.entry.patterns_as_iotas": "Patterns as Iotas",
|
||||
"hexcasting.page.patterns_as_iotas.1": "One of the many peculiarities of this art is that $(italic)patterns themselves/$ can act as iotas-- I can even put them onto my stack when casting.$(br2)This raises a fairly obvious question: how do I express them? If I simply drew a pattern, it would hardly tell Nature to add it to my stack-- rather, it would simply be matched to an action.",
|
||||
|
|
|
@ -85,8 +85,8 @@
|
|||
},
|
||||
{
|
||||
"type": "patchouli:text",
|
||||
"title": "hexcasting.page.mishaps.invalid_iota.title",
|
||||
"text": "hexcasting.page.mishaps.invalid_iota"
|
||||
"title": "hexcasting.page.mishaps.other.title",
|
||||
"text": "hexcasting.page.mishaps.other"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -85,6 +85,14 @@
|
|||
"input": "list, num",
|
||||
"output": "list",
|
||||
"text": "hexcasting.page.lists.list_remove"
|
||||
},
|
||||
{
|
||||
"type": "hexcasting:pattern",
|
||||
"op_id": "hexcasting:modify_in_place",
|
||||
"anchor": "hexcasting:modify_in_place",
|
||||
"input": "list, num, any",
|
||||
"output": "list",
|
||||
"text": "hexcasting.page.lists.modify_in_place"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.local
|
||||
|
||||
import at.petrak.hexcasting.api.spell.OperationResult
|
||||
import at.petrak.hexcasting.api.spell.Operator
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
|
||||
object OpPeekLocal : Operator {
|
||||
override fun operate(
|
||||
stack: MutableList<SpellDatum<*>>,
|
||||
local: SpellDatum<*>,
|
||||
ctx: CastingContext
|
||||
): OperationResult {
|
||||
stack.add(local)
|
||||
return OperationResult(stack, local, listOf())
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.local
|
||||
|
||||
import at.petrak.hexcasting.api.spell.OperationResult
|
||||
import at.petrak.hexcasting.api.spell.Operator
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import at.petrak.hexcasting.api.spell.mishaps.MishapNotEnoughArgs
|
||||
|
||||
object OpPushLocal : Operator {
|
||||
override fun operate(
|
||||
stack: MutableList<SpellDatum<*>>,
|
||||
local: SpellDatum<*>,
|
||||
ctx: CastingContext
|
||||
): OperationResult {
|
||||
if (stack.isEmpty())
|
||||
throw MishapNotEnoughArgs(1, 0)
|
||||
val newLocal = stack.removeLast()
|
||||
return OperationResult(stack, newLocal, listOf())
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue