From 9ef0b4fa723db4c529b99fb125f1d7a6208f7c02 Mon Sep 17 00:00:00 2001 From: gamma-delta <29877714+gamma-delta@users.noreply.github.com> Date: Sat, 26 Mar 2022 16:33:04 -0500 Subject: [PATCH] ridiculous bug where it can't find a class I MADE --- .../petrak/hexcasting/api/PatternRegistry.kt | 23 ++- .../circle/BlockEntityAbstractImpetus.java | 4 +- .../hexcasting/api/spell/ConstManaOperator.kt | 4 +- .../petrak/hexcasting/api/spell/Operator.kt | 18 +-- .../petrak/hexcasting/api/spell/SpellDatum.kt | 11 +- .../hexcasting/api/spell/SpellOperator.kt | 4 +- .../common/casting/CastException.kt | 136 ------------------ .../common/casting/CastingContext.kt | 23 ++- .../common/casting/CastingHarness.kt | 20 ++- .../common/casting/OperatorSideEffect.kt | 30 ++-- .../common/casting/RegisterPatterns.java | 10 +- .../common/casting/mishaps/Mishap.kt | 26 +++- .../mishaps/MishapAlreadyBrainswept.kt | 27 ++++ .../casting/mishaps/MishapBadBrainsweep.kt | 6 + .../common/casting/mishaps/MishapBadItem.kt | 2 +- .../casting/mishaps/MishapBadOffhandItem.kt | 11 +- .../casting/mishaps/MishapEntityTooFarAway.kt | 13 +- .../casting/mishaps/MishapInvalidIota.kt | 24 ++-- .../mishaps/MishapLocationTooFarAway.kt | 11 +- .../casting/mishaps/MishapNoSpellCircle.kt | 2 +- .../casting/mishaps/MishapNotEnoughArgs.kt | 2 +- .../mishaps/MishapTooManyCloseParens.kt | 5 +- .../common/casting/operators/OpFisherman.kt | 18 ++- .../common/casting/operators/OpRead.kt | 13 +- .../casting/operators/OpTheCoolerRead.kt | 14 +- .../common/casting/operators/OpWrite.kt | 9 +- .../operators/circles/OpCircleBounds.kt | 4 +- .../casting/operators/circles/OpImpetusDir.kt | 6 +- .../casting/operators/circles/OpImpetusPos.kt | 4 +- .../common/casting/operators/eval/OpEval.kt | 12 +- .../casting/operators/eval/OpForEach.kt | 20 ++- .../casting/operators/lists/OpLastNToList.kt | 17 ++- .../casting/operators/math/MathOpUtils.kt | 11 +- .../common/casting/operators/math/OpAbsLen.kt | 2 +- .../common/casting/operators/math/OpAdd.kt | 4 +- .../casting/operators/math/OpDivCross.kt | 4 +- .../common/casting/operators/math/OpMulDot.kt | 4 +- .../casting/operators/math/OpPowProj.kt | 4 +- .../common/casting/operators/math/OpSub.kt | 4 +- .../casting/operators/spells/OpErase.kt | 4 +- .../casting/operators/spells/OpMakeBattery.kt | 21 ++- .../operators/spells/OpMakePackagedSpell.kt | 23 ++- .../casting/operators/spells/OpPrint.kt | 4 +- .../casting/operators/spells/OpRecharge.kt | 14 +- .../operators/spells/great/OpBrainsweep.kt | 7 +- .../hexcasting/common/items/ItemAbacus.java | 5 + .../common/items/ItemDataHolder.java | 4 + .../hexcasting/common/items/ItemFocus.java | 5 + .../common/items/ItemSpellbook.java | 5 + .../hexcasting/datagen/HexItemModels.java | 6 +- .../petrak/hexcasting/datagen/HexRecipes.java | 6 +- .../assets/hexcasting/lang/en_us.json | 20 ++- 52 files changed, 348 insertions(+), 338 deletions(-) delete mode 100644 src/main/java/at/petrak/hexcasting/common/casting/CastException.kt create mode 100644 src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapAlreadyBrainswept.kt diff --git a/src/main/java/at/petrak/hexcasting/api/PatternRegistry.kt b/src/main/java/at/petrak/hexcasting/api/PatternRegistry.kt index a830ef95..13e8e7cf 100644 --- a/src/main/java/at/petrak/hexcasting/api/PatternRegistry.kt +++ b/src/main/java/at/petrak/hexcasting/api/PatternRegistry.kt @@ -1,7 +1,7 @@ package at.petrak.hexcasting.api import at.petrak.hexcasting.api.spell.Operator -import at.petrak.hexcasting.common.casting.CastException +import at.petrak.hexcasting.common.casting.mishaps.MishapInvalidPattern import at.petrak.hexcasting.hexmath.EulerPathFinder import at.petrak.hexcasting.hexmath.HexDir import at.petrak.hexcasting.hexmath.HexPattern @@ -68,28 +68,39 @@ object PatternRegistry { * Internal use only. */ @JvmStatic - fun matchPattern(pat: HexPattern, overworld: ServerLevel): Operator { + fun matchPattern(pat: HexPattern, overworld: ServerLevel): Operator = + matchPatternAndID(pat, overworld).first + + /** + * Internal use only. + */ + @JvmStatic + fun matchPatternAndID(pat: HexPattern, overworld: ServerLevel): Pair { // Pipeline: // patterns are registered here every time the game boots // when we try to look for (handler in specialHandlers) { val op = handler.handlePattern(pat) - if (op != null) return op + if (op != null) return Pair(op, null) } // Is it global? val sig = pat.anglesSignature() this.regularPatternLookup[sig]?.let { - return this.operatorLookup[it.opId] ?: throw CastException(CastException.Reason.INVALID_PATTERN, pat) + val op = this.operatorLookup[it.opId] ?: throw MishapInvalidPattern() + return Pair(op, it.opId) } // Look it up in the world? val ds = overworld.dataStorage val perWorldPatterns: Save = ds.computeIfAbsent(Save.Companion::load, { Save.create(overworld.seed) }, TAG_SAVED_DATA) - perWorldPatterns.lookup[sig]?.let { return this.operatorLookup[it.first]!! } + perWorldPatterns.lookup[sig]?.let { + val op = this.operatorLookup[it.first]!! + return Pair(op, it.first) + } - throw CastException(CastException.Reason.INVALID_PATTERN, pat) + throw MishapInvalidPattern() } /** diff --git a/src/main/java/at/petrak/hexcasting/api/circle/BlockEntityAbstractImpetus.java b/src/main/java/at/petrak/hexcasting/api/circle/BlockEntityAbstractImpetus.java index a6147d38..f6a8a93d 100644 --- a/src/main/java/at/petrak/hexcasting/api/circle/BlockEntityAbstractImpetus.java +++ b/src/main/java/at/petrak/hexcasting/api/circle/BlockEntityAbstractImpetus.java @@ -28,6 +28,7 @@ import net.minecraft.tags.BlockTags; import net.minecraft.util.Mth; import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.DyeColor; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.level.block.Block; @@ -364,7 +365,8 @@ public abstract class BlockEntityAbstractImpetus extends PaucalBlockEntity imple var spray = new ParticleSpray(vpos, vecOutDir.scale(success ? 1.0 : 1.5), success ? 0.1 : 0.5, Mth.PI / (success ? 4 : 2), success ? 30 : 100); spray.sprayParticles(serverLevel, - success ? this.colorizer : new FrozenColorizer(HexItems.DYE_COLORIZERS[14].get(), this.activator)); + success ? this.colorizer : new FrozenColorizer(HexItems.DYE_COLORIZERS.get(DyeColor.RED).get(), + this.activator)); } var pitch = 1f; diff --git a/src/main/java/at/petrak/hexcasting/api/spell/ConstManaOperator.kt b/src/main/java/at/petrak/hexcasting/api/spell/ConstManaOperator.kt index c293c714..2f6e30ee 100644 --- a/src/main/java/at/petrak/hexcasting/api/spell/ConstManaOperator.kt +++ b/src/main/java/at/petrak/hexcasting/api/spell/ConstManaOperator.kt @@ -1,8 +1,8 @@ package at.petrak.hexcasting.api.spell -import at.petrak.hexcasting.common.casting.CastException import at.petrak.hexcasting.common.casting.CastingContext import at.petrak.hexcasting.common.casting.OperatorSideEffect +import at.petrak.hexcasting.common.casting.mishaps.MishapNotEnoughArgs /** * A SimpleOperator that always costs the same amount of mana. @@ -16,7 +16,7 @@ interface ConstManaOperator : Operator { override fun operate(stack: MutableList>, ctx: CastingContext): OperationResult { if (this.argc > stack.size) - throw CastException(CastException.Reason.NOT_ENOUGH_ARGS, 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 newData = this.execute(args, ctx) diff --git a/src/main/java/at/petrak/hexcasting/api/spell/Operator.kt b/src/main/java/at/petrak/hexcasting/api/spell/Operator.kt index 667c18f5..6cc5c833 100644 --- a/src/main/java/at/petrak/hexcasting/api/spell/Operator.kt +++ b/src/main/java/at/petrak/hexcasting/api/spell/Operator.kt @@ -1,7 +1,8 @@ package at.petrak.hexcasting.api.spell -import at.petrak.hexcasting.common.casting.CastException import at.petrak.hexcasting.common.casting.CastingContext +import at.petrak.hexcasting.common.casting.mishaps.MishapInvalidIota +import at.petrak.hexcasting.common.casting.mishaps.MishapNotEnoughArgs import net.minecraft.world.phys.Vec3 /** @@ -43,16 +44,11 @@ interface Operator { */ @JvmStatic inline fun List>.getChecked(idx: Int): T { - val x = this.getOrElse(idx) { throw CastException(CastException.Reason.NOT_ENOUGH_ARGS, idx, this.size) } - return x.tryGet() - } - - /** - * Check if the value at the given index is OK. Will throw an error otherwise. - */ - @JvmStatic - inline fun List>.assertChecked(idx: Int) { - this.getChecked(idx) + val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) } + if (x.payload is T) + return x.payload + else + throw MishapInvalidIota.ofClass(x, idx, T::class.java) } @JvmStatic diff --git a/src/main/java/at/petrak/hexcasting/api/spell/SpellDatum.kt b/src/main/java/at/petrak/hexcasting/api/spell/SpellDatum.kt index 1e1ad64c..e927a272 100644 --- a/src/main/java/at/petrak/hexcasting/api/spell/SpellDatum.kt +++ b/src/main/java/at/petrak/hexcasting/api/spell/SpellDatum.kt @@ -2,9 +2,9 @@ package at.petrak.hexcasting.api.spell import at.petrak.hexcasting.HexUtils import at.petrak.hexcasting.HexUtils.serializeToNBT -import at.petrak.hexcasting.common.casting.CastException import at.petrak.hexcasting.common.casting.CastingContext import at.petrak.hexcasting.common.casting.Widget +import at.petrak.hexcasting.common.casting.mishaps.MishapInvalidSpellDatumType import at.petrak.hexcasting.hexmath.HexPattern import net.minecraft.ChatFormatting import net.minecraft.nbt.* @@ -32,13 +32,6 @@ import net.minecraft.world.phys.Vec3 class SpellDatum private constructor(val payload: T) { val clazz: Class = payload.javaClass - inline fun tryGet(): U = - if (payload is U) { - payload - } else { - throw CastException(CastException.Reason.OP_WRONG_TYPE, U::class.java, this.payload) - } - fun serializeToNBT(): CompoundTag { val out = CompoundTag() when (val pl = this.payload) { @@ -113,7 +106,7 @@ class SpellDatum private constructor(val payload: T) { val num = payload.toDouble() SpellDatum(HexUtils.FixNANs(num)) } else { - throw CastException(CastException.Reason.INVALID_TYPE, payload) + throw MishapInvalidSpellDatumType(payload) } diff --git a/src/main/java/at/petrak/hexcasting/api/spell/SpellOperator.kt b/src/main/java/at/petrak/hexcasting/api/spell/SpellOperator.kt index de0103bc..94eabd65 100644 --- a/src/main/java/at/petrak/hexcasting/api/spell/SpellOperator.kt +++ b/src/main/java/at/petrak/hexcasting/api/spell/SpellOperator.kt @@ -1,8 +1,8 @@ package at.petrak.hexcasting.api.spell -import at.petrak.hexcasting.common.casting.CastException import at.petrak.hexcasting.common.casting.CastingContext import at.petrak.hexcasting.common.casting.OperatorSideEffect +import at.petrak.hexcasting.common.casting.mishaps.MishapNotEnoughArgs interface SpellOperator : Operator { val argc: Int @@ -14,7 +14,7 @@ interface SpellOperator : Operator { override fun operate(stack: MutableList>, ctx: CastingContext): OperationResult { if (this.argc > stack.size) - throw CastException(CastException.Reason.NOT_ENOUGH_ARGS, 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 (spell, mana, particles) = this.execute(args, ctx) diff --git a/src/main/java/at/petrak/hexcasting/common/casting/CastException.kt b/src/main/java/at/petrak/hexcasting/common/casting/CastException.kt deleted file mode 100644 index b981281c..00000000 --- a/src/main/java/at/petrak/hexcasting/common/casting/CastException.kt +++ /dev/null @@ -1,136 +0,0 @@ -package at.petrak.hexcasting.common.casting - -import at.petrak.hexcasting.hexmath.HexPattern -import net.minecraft.core.BlockPos -import net.minecraft.world.item.Item -import net.minecraft.world.phys.Vec3 - -class CastException(val reason: Reason, vararg val data: Any) : Exception() { - enum class Reason { - // Compilation - /** - * We couldn't match this pattern to an operator. - * - * `pattern: HexPattern` - */ - INVALID_PATTERN, - - /** - * Completely invalid type for spellcasting. - * If you're seeing this error I messed up really bad - * - * `perpetrator: Any` - */ - INVALID_TYPE, - - /** - * We need an argument with these properties, but didn't get it. - * Maddy put this in because Fisherman's needed it. - * - * `expected: Natural Number (1, 2, 3, n), got: -1` - */ - INVALID_VALUE, - - // Pre-execution - /** - * When executing an operator we expected a different type. - * - * `expected: Class<*>, got: Any` - */ - OP_WRONG_TYPE, - - /** - * We need at least this much on the stack to cast the spell but only got this much. - * - * `requiredArgc: Int, gotArgc: Int` - */ - NOT_ENOUGH_ARGS, - - /** - * There are too many close parentheses. - * - * `no args` - */ - TOO_MANY_CLOSE_PARENS, - - // Execution - /** - * Tried to interact with a vector that was too far away - * - * `vec: Vec3` - */ - TOO_FAR, - - /** - * We went too deep! - * - * `maxDepth: Int, gotDepth: Int` - */ - TOO_MANY_RECURSIVE_EVALS, - - /** - * Bad item in offhand - * - * `Class expected, ItemStack got` - */ - BAD_OFFHAND_ITEM, - - /** - * Bad item in offhand except it uses items and not classes - * - * `Item expected, ItemStack got` - */ - BAD_OFFHAND_ITEM_ITEM, - - /** - * Needs exactly X items in the offhand - * - * `Int needed, Int got` - */ - BAD_OFFHAND_COUNT, - - - /** - * Required an inventory at the given position. - * - * `BlockPos pos` - */ - REQUIRES_INVENTORY, - - /** - * Extracting sentience didn't work - * - * for fucks sake i need to just implement mishaps already - */ - RECIPE_DIDNT_WORK, - - /** - * No spell circles?? - */ - NO_SPELL_CIRCLE, - - /** - * No writing someone else's name! - */ - NO_WRITING_OTHER_NAMES - } - - override val message: String - get() = when (this.reason) { - Reason.INVALID_PATTERN -> "could not match pattern to operator: ${this.data[0] as HexPattern}" - Reason.INVALID_TYPE -> "cannot use ${this.data[0]} as a SpellDatum (type ${this.data[0].javaClass.typeName})" - Reason.INVALID_VALUE -> "operator expected ${this.data[0]} but got ${this.data[1]}" - Reason.OP_WRONG_TYPE -> "operator expected ${(this.data[0] as Class<*>).typeName} but got ${this.data[1]} (type ${this.data[1].javaClass.typeName})" - Reason.NOT_ENOUGH_ARGS -> "required at least ${this.data[0] as Int} args on the stack but only had ${this.data[1] as Int}" - Reason.TOO_MANY_CLOSE_PARENS -> "too many close parentheses" - Reason.TOO_FAR -> "tried to interact with something too far away at ${this.data[0] as Vec3}" - Reason.TOO_MANY_RECURSIVE_EVALS -> "can only recursively call OpEval ${this.data[0] as Int} times but called it ${this.data[1] as Int} times" - Reason.BAD_OFFHAND_ITEM -> "operator expected ${(this.data[0] as Class<*>).typeName} in offhand but got ${this.data[1]}" - Reason.BAD_OFFHAND_ITEM_ITEM -> "operator expected ${(this.data[0] as Item).registryName} in offhand but got ${this.data[1]}" - Reason.BAD_OFFHAND_COUNT -> "operator expected ${this.data[0]} items in the offhand but got ${this.data[1]}" - Reason.REQUIRES_INVENTORY -> "required an inventory at ${this.data[0] as BlockPos}" - Reason.RECIPE_DIDNT_WORK -> "bad recipe" - Reason.NO_SPELL_CIRCLE -> "requires a spell circle to cast" - Reason.NO_WRITING_OTHER_NAMES -> "can't write someone else's Name" - } -} \ No newline at end of file diff --git a/src/main/java/at/petrak/hexcasting/common/casting/CastingContext.kt b/src/main/java/at/petrak/hexcasting/common/casting/CastingContext.kt index 03ec0b38..7495735d 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/CastingContext.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/CastingContext.kt @@ -3,8 +3,11 @@ package at.petrak.hexcasting.common.casting import at.petrak.hexcasting.HexConfig import at.petrak.hexcasting.HexUtils import at.petrak.hexcasting.api.spell.Operator +import at.petrak.hexcasting.common.casting.mishaps.MishapBadOffhandItem +import at.petrak.hexcasting.common.casting.mishaps.MishapEntityTooFarAway +import at.petrak.hexcasting.common.casting.mishaps.MishapEvalTooDeep +import at.petrak.hexcasting.common.casting.mishaps.MishapLocationTooFarAway import at.petrak.hexcasting.common.items.ItemDataHolder -import at.petrak.hexcasting.common.items.ItemSpellbook import at.petrak.hexcasting.common.lib.HexCapabilities import at.petrak.hexcasting.common.lib.RegisterHelper.prefix import net.minecraft.server.level.ServerLevel @@ -34,23 +37,13 @@ data class CastingContext( val position: Vec3 get() = caster.position() - fun getSpellbook(): ItemStack { - val handItem = - caster.getItemInHand(this.otherHand) - return if (handItem.item is ItemSpellbook) { - handItem - } else { - throw CastException(CastException.Reason.BAD_OFFHAND_ITEM, ItemSpellbook::class.java, handItem) - } - } - fun getDataHolder(): ItemStack { val handItem = caster.getItemInHand(this.otherHand) return if (handItem.item is ItemDataHolder) { handItem } else { - throw CastException(CastException.Reason.BAD_OFFHAND_ITEM, ItemDataHolder::class.java, handItem) + throw MishapBadOffhandItem.of(handItem, "iota") } } @@ -61,7 +54,7 @@ data class CastingContext( this.depth++ val maxAllowedDepth = HexConfig.maxRecurseDepth.get() if (this.depth > maxAllowedDepth) { - throw CastException(CastException.Reason.TOO_MANY_RECURSIVE_EVALS, maxAllowedDepth, this.depth) + throw MishapEvalTooDeep() } } @@ -69,14 +62,14 @@ data class CastingContext( * Check to make sure a vec is in range */ fun assertVecInRange(vec: Vec3) { - if (!isVecInRange(vec)) throw CastException(CastException.Reason.TOO_FAR, vec) + if (!isVecInRange(vec)) throw MishapLocationTooFarAway(vec) } /** * Check to make sure an entity is in range */ fun assertEntityInRange(entity: Entity) { - if (!isEntityInRange(entity)) throw CastException(CastException.Reason.TOO_FAR, entity.position()) + if (!isEntityInRange(entity)) throw MishapEntityTooFarAway(entity) } fun isVecInRange(vec: Vec3): Boolean { diff --git a/src/main/java/at/petrak/hexcasting/common/casting/CastingHarness.kt b/src/main/java/at/petrak/hexcasting/common/casting/CastingHarness.kt index 613d096c..038fd21b 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/CastingHarness.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/CastingHarness.kt @@ -4,9 +4,12 @@ import at.petrak.hexcasting.HexConfig import at.petrak.hexcasting.HexMod import at.petrak.hexcasting.api.PatternRegistry import at.petrak.hexcasting.api.circle.BlockEntityAbstractImpetus +import at.petrak.hexcasting.api.spell.Operator import at.petrak.hexcasting.api.spell.ParticleSpray import at.petrak.hexcasting.api.spell.SpellDatum import at.petrak.hexcasting.common.casting.colors.FrozenColorizer +import at.petrak.hexcasting.common.casting.mishaps.Mishap +import at.petrak.hexcasting.common.casting.mishaps.MishapTooManyCloseParens import at.petrak.hexcasting.common.items.ItemWand import at.petrak.hexcasting.common.items.magic.ItemPackagedSpell import at.petrak.hexcasting.common.lib.HexCapabilities @@ -18,6 +21,7 @@ import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.ListTag import net.minecraft.nbt.Tag import net.minecraft.network.chat.Component +import net.minecraft.resources.ResourceLocation import net.minecraft.server.level.ServerLevel import net.minecraft.world.phys.Vec3 import kotlin.math.min @@ -57,6 +61,8 @@ class CastingHarness private constructor( fun getUpdate(newPat: HexPattern, world: ServerLevel): CastResult { if (this.ctx.spellCircle == null) this.ctx.caster.awardStat(HexStatistics.PATTERNS_DRAWN) + + var operatorIdPair: Pair? = null try { // wouldn't it be nice to be able to go paren' // i guess i'll call it paren2 @@ -69,8 +75,8 @@ class CastingHarness private constructor( } // Don't catch this one - val operator = PatternRegistry.matchPattern(newPat, world) - val (stack2, sideEffectsUnmut) = operator.operate(this.stack.toMutableList(), this.ctx) + operatorIdPair = PatternRegistry.matchPatternAndID(newPat, world) + val (stack2, sideEffectsUnmut) = operatorIdPair.first.operate(this.stack.toMutableList(), this.ctx) // Stick a poofy particle effect at the caster position val sideEffects = sideEffectsUnmut.toMutableList() if (this.ctx.spellCircle == null) @@ -92,10 +98,10 @@ class CastingHarness private constructor( fd, sideEffects, ) - } catch (exn: CastException) { + } catch (mishap: Mishap) { return CastResult( this.getFunctionalData(), - listOf(OperatorSideEffect.Mishap(exn)), + listOf(OperatorSideEffect.DoMishap(mishap, Mishap.Context(newPat, operatorIdPair?.second))), ) } } @@ -159,7 +165,7 @@ class CastingHarness private constructor( private fun handleParentheses(newPat: HexPattern): FunctionalData? { val operator = try { PatternRegistry.matchPattern(newPat, this.ctx.world) - } catch (e: CastException) { + } catch (mishap: Mishap) { null } @@ -194,7 +200,7 @@ class CastingHarness private constructor( parenthesized = listOf() ) } else if (newParenCount < 0) { - throw CastException(CastException.Reason.TOO_MANY_CLOSE_PARENS) + throw MishapTooManyCloseParens() } else { // we have this situation: "(()" // we need to add the close paren @@ -228,7 +234,7 @@ class CastingHarness private constructor( parenCount = this.parenCount + 1 ) } else if (operator == Widget.CLOSE_PAREN) { - throw CastException(CastException.Reason.TOO_MANY_CLOSE_PARENS) + throw MishapTooManyCloseParens() } else { null } diff --git a/src/main/java/at/petrak/hexcasting/common/casting/OperatorSideEffect.kt b/src/main/java/at/petrak/hexcasting/common/casting/OperatorSideEffect.kt index 096f4088..5b062e8e 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/OperatorSideEffect.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/OperatorSideEffect.kt @@ -2,14 +2,14 @@ package at.petrak.hexcasting.common.casting import at.petrak.hexcasting.api.spell.ParticleSpray import at.petrak.hexcasting.api.spell.RenderedSpell -import at.petrak.hexcasting.api.spell.SpellDatum +import at.petrak.hexcasting.common.casting.colors.FrozenColorizer +import at.petrak.hexcasting.common.casting.mishaps.Mishap +import at.petrak.hexcasting.common.items.HexItems import at.petrak.hexcasting.common.lib.HexStatistics import at.petrak.hexcasting.datagen.HexAdvancements import net.minecraft.Util -import net.minecraft.network.chat.TextComponent import net.minecraft.network.chat.TranslatableComponent -import kotlin.random.Random -import kotlin.random.nextInt +import net.minecraft.world.item.DyeColor /** * Things that happen after a spell is cast. @@ -59,20 +59,20 @@ sealed class OperatorSideEffect { } } - data class Mishap(val exn: CastException) : OperatorSideEffect() { + data class DoMishap(val mishap: Mishap, val errorCtx: Mishap.Context) : OperatorSideEffect() { override fun performEffect(harness: CastingHarness): Boolean { - harness.ctx.caster.sendMessage( - TextComponent(exn.message), - Util.NIL_UUID + // for now + harness.ctx.caster.sendMessage(mishap.errorMessage(harness.ctx, errorCtx), Util.NIL_UUID) + + val spray = mishap.particleSpray(harness.ctx) + val color = mishap.accentColor(harness.ctx, errorCtx) + spray.sprayParticles(harness.ctx.world, color) + spray.sprayParticles( + harness.ctx.world, + FrozenColorizer(HexItems.DYE_COLORIZERS[DyeColor.RED]!!.get(), Util.NIL_UUID) ) - when (exn.reason) { - CastException.Reason.INVALID_PATTERN -> { - val idx = Random.nextInt(0..harness.stack.size) - harness.stack.add(idx, SpellDatum.make(Widget.GARBAGE)) - } - else -> {} - } + mishap.execute(harness.ctx, errorCtx, harness.stack) return true } diff --git a/src/main/java/at/petrak/hexcasting/common/casting/RegisterPatterns.java b/src/main/java/at/petrak/hexcasting/common/casting/RegisterPatterns.java index df7da955..bb1a5269 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/RegisterPatterns.java +++ b/src/main/java/at/petrak/hexcasting/common/casting/RegisterPatterns.java @@ -23,9 +23,7 @@ import at.petrak.hexcasting.common.casting.operators.spells.sentinel.OpCreateSen import at.petrak.hexcasting.common.casting.operators.spells.sentinel.OpDestroySentinel; import at.petrak.hexcasting.common.casting.operators.spells.sentinel.OpGetSentinelPos; import at.petrak.hexcasting.common.casting.operators.spells.sentinel.OpGetSentinelWayfind; -import at.petrak.hexcasting.common.items.magic.ItemArtifact; -import at.petrak.hexcasting.common.items.magic.ItemCypher; -import at.petrak.hexcasting.common.items.magic.ItemTrinket; +import at.petrak.hexcasting.common.items.HexItems; import at.petrak.hexcasting.hexmath.HexDir; import at.petrak.hexcasting.hexmath.HexPattern; import net.minecraft.world.effect.MobEffects; @@ -164,14 +162,14 @@ public class RegisterPatterns { new OpErase()); PatternRegistry.mapPattern(HexPattern.FromAnglesSig("waqqqqq", HexDir.EAST), prefix("craft/cypher"), - new OpMakePackagedSpell<>(ItemCypher.class, 100_000)); + new OpMakePackagedSpell<>(HexItems.CYPHER.get(), 100_000)); PatternRegistry.mapPattern(HexPattern.FromAnglesSig("wwaqqqqqeaqeaeqqqeaeq", HexDir.EAST), prefix("craft/trinket"), - new OpMakePackagedSpell<>(ItemTrinket.class, 500_000)); + new OpMakePackagedSpell<>(HexItems.TRINKET.get(), 500_000)); PatternRegistry.mapPattern( HexPattern.FromAnglesSig("wwaqqqqqeawqwqwqwqwqwwqqeadaeqqeqqeadaeqq", HexDir.EAST), prefix("craft/artifact"), - new OpMakePackagedSpell<>(ItemArtifact.class, 1_000_000)); + new OpMakePackagedSpell<>(HexItems.ARTIFACT.get(), 1_000_000)); PatternRegistry.mapPattern( HexPattern.FromAnglesSig("aqqqaqwwaqqqqqeqaqqqawwqwqwqwqwqw", HexDir.SOUTH_WEST), prefix("craft/battery"), diff --git a/src/main/java/at/petrak/hexcasting/common/casting/mishaps/Mishap.kt b/src/main/java/at/petrak/hexcasting/common/casting/mishaps/Mishap.kt index a0e44ba7..081d4c04 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/mishaps/Mishap.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/mishaps/Mishap.kt @@ -5,19 +5,22 @@ import at.petrak.hexcasting.api.spell.SpellDatum import at.petrak.hexcasting.common.casting.CastingContext import at.petrak.hexcasting.common.casting.colors.FrozenColorizer import at.petrak.hexcasting.common.items.HexItems +import at.petrak.hexcasting.hexmath.HexPattern import net.minecraft.Util import net.minecraft.network.chat.Component import net.minecraft.network.chat.TranslatableComponent import net.minecraft.resources.ResourceLocation +import net.minecraft.world.entity.item.ItemEntity import net.minecraft.world.item.DyeColor -import java.util.regex.Pattern +import net.minecraft.world.item.ItemStack +import net.minecraft.world.phys.Vec3 sealed class Mishap : Throwable() { /** Mishaps spray half-red, half-this-color. */ abstract fun accentColor(ctx: CastingContext, errorCtx: Context): FrozenColorizer open fun particleSpray(ctx: CastingContext): ParticleSpray { - return ParticleSpray.Burst(ctx.position, 0.5) + return ParticleSpray(ctx.position.add(0.0, 0.2, 0.0), Vec3(0.0, 2.0, 0.0), 0.2, Math.PI / 4, 40) } /** @@ -35,8 +38,21 @@ sealed class Mishap : Throwable() { protected fun error(stub: String, vararg args: Any): Component = TranslatableComponent("hexcasting.mishap.$stub", *args) - protected fun actionName(action: ResourceLocation): Component = - TranslatableComponent("hexcasting.spell.$action") + protected fun actionName(action: ResourceLocation?): Component = + TranslatableComponent("hexcasting.spell.${action ?: "unknown"}") - data class Context(val pattern: Pattern, val action: ResourceLocation?) + protected fun yeetItem(stack: ItemStack, ctx: CastingContext, delta: Vec3) { + val entity = ItemEntity( + ctx.world, + ctx.position.x, ctx.position.y, ctx.position.z, + stack, + delta.x + (Math.random() - 0.5) * 0.1, + delta.y + (Math.random() - 0.5) * 0.1, + delta.z + (Math.random() - 0.5) * 0.1 + ) + entity.setPickUpDelay(40) + ctx.world.addWithUUID(entity) + } + + data class Context(val pattern: HexPattern, val action: ResourceLocation?) } diff --git a/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapAlreadyBrainswept.kt b/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapAlreadyBrainswept.kt new file mode 100644 index 00000000..e7e3062f --- /dev/null +++ b/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapAlreadyBrainswept.kt @@ -0,0 +1,27 @@ +package at.petrak.hexcasting.common.casting.mishaps + +import at.petrak.hexcasting.api.spell.ParticleSpray +import at.petrak.hexcasting.api.spell.SpellDatum +import at.petrak.hexcasting.common.casting.CastingContext +import at.petrak.hexcasting.common.casting.colors.FrozenColorizer +import at.petrak.hexcasting.common.lib.HexDamageSources +import net.minecraft.network.chat.Component +import net.minecraft.world.entity.npc.Villager +import net.minecraft.world.item.DyeColor + +class MishapAlreadyBrainswept(val villager: Villager) : Mishap() { + override fun accentColor(ctx: CastingContext, errorCtx: Context): FrozenColorizer = + dyeColor(DyeColor.LIME) + + override fun execute(ctx: CastingContext, errorCtx: Context, stack: MutableList>) { + villager.hurt(HexDamageSources.OVERCAST, villager.health) + } + + override fun particleSpray(ctx: CastingContext): ParticleSpray { + return ParticleSpray.Burst(villager.eyePosition, 1.0) + } + + override fun errorMessage(ctx: CastingContext, errorCtx: Context): Component = + error("already_brainswept") + +} \ No newline at end of file diff --git a/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapBadBrainsweep.kt b/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapBadBrainsweep.kt index aaab727c..caeb21db 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapBadBrainsweep.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapBadBrainsweep.kt @@ -1,5 +1,6 @@ package at.petrak.hexcasting.common.casting.mishaps +import at.petrak.hexcasting.api.spell.ParticleSpray import at.petrak.hexcasting.api.spell.SpellDatum import at.petrak.hexcasting.common.casting.CastingContext import at.petrak.hexcasting.common.casting.colors.FrozenColorizer @@ -8,6 +9,7 @@ import net.minecraft.core.BlockPos import net.minecraft.network.chat.Component import net.minecraft.world.entity.npc.Villager import net.minecraft.world.item.DyeColor +import net.minecraft.world.phys.Vec3 class MishapBadBrainsweep(val villager: Villager, val pos: BlockPos) : Mishap() { override fun accentColor(ctx: CastingContext, errorCtx: Context): FrozenColorizer = @@ -17,6 +19,10 @@ class MishapBadBrainsweep(val villager: Villager, val pos: BlockPos) : Mishap() villager.hurt(HexDamageSources.OVERCAST, villager.health) } + override fun particleSpray(ctx: CastingContext): ParticleSpray { + return ParticleSpray.Burst(Vec3.atCenterOf(pos), 1.0) + } + override fun errorMessage(ctx: CastingContext, errorCtx: Context): Component { val bs = ctx.world.getBlockState(this.pos) return error("bad_brainsweep", bs.block.name) diff --git a/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapBadItem.kt b/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapBadItem.kt index 958fef3d..d8c2de1d 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapBadItem.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapBadItem.kt @@ -17,7 +17,7 @@ class MishapBadItem(val item: ItemStack, val wanted: Component) : Mishap() { } override fun errorMessage(ctx: CastingContext, errorCtx: Context): Component = - error("bad_item", actionName(errorCtx.action!!), wanted, item) + error("bad_item", actionName(errorCtx.action), wanted, item) companion object { @JvmStatic diff --git a/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapBadOffhandItem.kt b/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapBadOffhandItem.kt index 0fe9a313..1d649127 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapBadOffhandItem.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapBadOffhandItem.kt @@ -5,7 +5,6 @@ import at.petrak.hexcasting.common.casting.CastingContext import at.petrak.hexcasting.common.casting.colors.FrozenColorizer import net.minecraft.network.chat.Component import net.minecraft.network.chat.TranslatableComponent -import net.minecraft.world.entity.item.ItemEntity import net.minecraft.world.item.DyeColor import net.minecraft.world.item.ItemStack @@ -17,16 +16,12 @@ class MishapBadOffhandItem(val item: ItemStack, val wanted: Component) : Mishap( val item = ctx.caster.getItemInHand(ctx.otherHand).copy() ctx.caster.setItemInHand(ctx.otherHand, ItemStack.EMPTY.copy()) - val delta = ctx.caster.lookAngle - val entity = ItemEntity( - ctx.world, ctx.caster.x, ctx.caster.eyeY, ctx.caster.z, item, - delta.x, delta.y, delta.z - ) - ctx.world.addWithUUID(entity) + val delta = ctx.caster.lookAngle.scale(0.5) + yeetItem(item, ctx, delta) } override fun errorMessage(ctx: CastingContext, errorCtx: Context): Component = - error("bad_item.offhand", actionName(errorCtx.action!!), wanted, item) + error("bad_item.offhand", actionName(errorCtx.action), wanted, item.count, item.displayName) companion object { @JvmStatic diff --git a/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapEntityTooFarAway.kt b/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapEntityTooFarAway.kt index 3c3f293d..49936d04 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapEntityTooFarAway.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapEntityTooFarAway.kt @@ -6,7 +6,6 @@ import at.petrak.hexcasting.common.casting.colors.FrozenColorizer import net.minecraft.network.chat.Component import net.minecraft.world.InteractionHand import net.minecraft.world.entity.Entity -import net.minecraft.world.entity.item.ItemEntity import net.minecraft.world.item.DyeColor import net.minecraft.world.item.ItemStack @@ -24,19 +23,13 @@ class MishapEntityTooFarAway(val entity: Entity) : Mishap() { ctx.caster.setItemInHand(hand, ItemStack.EMPTY.copy()) } - val delta = entity.position().subtract(ctx.position).normalize().scale(2.0) + val delta = entity.position().subtract(ctx.position).normalize().scale(0.5) for (item in items) { - val entity = ItemEntity( - ctx.world, - ctx.position.x, ctx.position.y, ctx.position.z, - item, - delta.x, delta.y, delta.z - ) - ctx.world.addWithUUID(entity) + yeetItem(item, ctx, delta) } } override fun errorMessage(ctx: CastingContext, errorCtx: Context): Component = - error("entity_too_far", SpellDatum.make(entity).display(), actionName(errorCtx.action!!)) + error("entity_too_far", SpellDatum.make(entity).display(), actionName(errorCtx.action)) } \ No newline at end of file diff --git a/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapInvalidIota.kt b/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapInvalidIota.kt index 7ca1ace9..0743cc1a 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapInvalidIota.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapInvalidIota.kt @@ -1,5 +1,6 @@ package at.petrak.hexcasting.common.casting.mishaps +import at.petrak.hexcasting.HexMod import at.petrak.hexcasting.api.spell.SpellDatum import at.petrak.hexcasting.common.casting.CastingContext import at.petrak.hexcasting.common.casting.Widget @@ -18,32 +19,32 @@ import net.minecraft.world.phys.Vec3 /** * The value failed some kind of predicate. * - * [MishapInvalidIota.idx] is the absolute index in the stack. + * [MishapInvalidIota.reverseIdx] is the index from the *back* of the stack. */ class MishapInvalidIota( val perpetrator: SpellDatum<*>, - val idx: Int, - val expectedKey: String + val reverseIdx: Int, + val expected: Component ) : Mishap() { override fun accentColor(ctx: CastingContext, errorCtx: Context): FrozenColorizer = dyeColor(DyeColor.GRAY) override fun execute(ctx: CastingContext, errorCtx: Context, stack: MutableList>) { - stack[idx] = SpellDatum.make(Widget.GARBAGE) + stack[stack.size - 1 - reverseIdx] = SpellDatum.make(Widget.GARBAGE) } override fun errorMessage(ctx: CastingContext, errorCtx: Context): Component = error( "invalid_value", - actionName(errorCtx.action!!), - idx, - TranslatableComponent(expectedKey), + actionName(errorCtx.action), + reverseIdx, + expected, perpetrator.display() ) companion object { @JvmStatic - fun ofClass(perpetrator: SpellDatum<*>, idx: Int, cls: Class<*>): MishapInvalidIota { + fun ofClass(perpetrator: SpellDatum<*>, reverseIdx: Int, cls: Class<*>): MishapInvalidIota { val key = "hexcasting.mishap.invalid_value.class." + when { Double::class.java.isAssignableFrom(cls) -> "double" Vec3::class.java.isAssignableFrom(cls) -> "vector" @@ -57,9 +58,12 @@ class MishapInvalidIota( LivingEntity::class.java.isAssignableFrom(cls) -> "entity.living" Entity::class.java.isAssignableFrom(cls) -> "entity" - else -> "unknown" + else -> { + HexMod.getLogger().warn("tried to call MishapInvalidData.ofClass with class $cls") + "unknown" + } } - return MishapInvalidIota(perpetrator, idx, key) + return MishapInvalidIota(perpetrator, reverseIdx, TranslatableComponent(key)) } } } \ No newline at end of file diff --git a/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapLocationTooFarAway.kt b/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapLocationTooFarAway.kt index 746f2ec7..23aadd71 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapLocationTooFarAway.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapLocationTooFarAway.kt @@ -5,7 +5,6 @@ import at.petrak.hexcasting.common.casting.CastingContext import at.petrak.hexcasting.common.casting.colors.FrozenColorizer import net.minecraft.network.chat.Component import net.minecraft.world.InteractionHand -import net.minecraft.world.entity.item.ItemEntity import net.minecraft.world.item.DyeColor import net.minecraft.world.item.ItemStack import net.minecraft.world.phys.Vec3 @@ -24,16 +23,10 @@ class MishapLocationTooFarAway(val location: Vec3) : Mishap() { ctx.caster.setItemInHand(hand, ItemStack.EMPTY.copy()) } - val delta = location.subtract(ctx.position).normalize().scale(2.0) + val delta = location.subtract(ctx.position).normalize().scale(0.5) for (item in items) { - val entity = ItemEntity( - ctx.world, - ctx.position.x, ctx.position.y, ctx.position.z, - item, - delta.x, delta.y, delta.z - ) - ctx.world.addWithUUID(entity) + yeetItem(item, ctx, delta) } } diff --git a/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapNoSpellCircle.kt b/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapNoSpellCircle.kt index ffc6d639..33369970 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapNoSpellCircle.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapNoSpellCircle.kt @@ -15,5 +15,5 @@ class MishapNoSpellCircle : Mishap() { } override fun errorMessage(ctx: CastingContext, errorCtx: Context): Component = - error("no_spell_circle", actionName(errorCtx.action!!)) + error("no_spell_circle", actionName(errorCtx.action)) } \ No newline at end of file diff --git a/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapNotEnoughArgs.kt b/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapNotEnoughArgs.kt index e9abc1de..3ec54a4b 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapNotEnoughArgs.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapNotEnoughArgs.kt @@ -17,5 +17,5 @@ class MishapNotEnoughArgs(val expected: Int, val got: Int) : Mishap() { } override fun errorMessage(ctx: CastingContext, errorCtx: Context): Component = - error("not_enough_args", actionName(errorCtx.action!!), expected, got) + error("not_enough_args", actionName(errorCtx.action), expected, got) } \ No newline at end of file diff --git a/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapTooManyCloseParens.kt b/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapTooManyCloseParens.kt index 8d79a25b..db80b64d 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapTooManyCloseParens.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapTooManyCloseParens.kt @@ -3,16 +3,15 @@ package at.petrak.hexcasting.common.casting.mishaps import at.petrak.hexcasting.api.spell.SpellDatum import at.petrak.hexcasting.common.casting.CastingContext import at.petrak.hexcasting.common.casting.colors.FrozenColorizer -import at.petrak.hexcasting.hexmath.HexPattern import net.minecraft.network.chat.Component import net.minecraft.world.item.DyeColor -class MishapTooManyCloseParens(val paren: HexPattern) : Mishap() { +class MishapTooManyCloseParens : Mishap() { override fun accentColor(ctx: CastingContext, errorCtx: Context): FrozenColorizer = dyeColor(DyeColor.PINK) override fun execute(ctx: CastingContext, errorCtx: Context, stack: MutableList>) { - stack.add(SpellDatum.make(paren)) + stack.add(SpellDatum.make(errorCtx.pattern)) } override fun errorMessage(ctx: CastingContext, errorCtx: Context): Component = diff --git a/src/main/java/at/petrak/hexcasting/common/casting/operators/OpFisherman.kt b/src/main/java/at/petrak/hexcasting/common/casting/operators/OpFisherman.kt index 4b76de5c..181ee7e8 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/operators/OpFisherman.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/operators/OpFisherman.kt @@ -4,9 +4,12 @@ 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.common.casting.CastException import at.petrak.hexcasting.common.casting.CastingContext import at.petrak.hexcasting.common.casting.OperatorSideEffect +import at.petrak.hexcasting.common.casting.mishaps.MishapInvalidIota +import at.petrak.hexcasting.common.casting.mishaps.MishapNotEnoughArgs +import net.minecraft.network.chat.TranslatableComponent +import kotlin.math.abs object OpFisherman : Operator { val manaCost: Int @@ -14,16 +17,21 @@ object OpFisherman : Operator { override fun operate(stack: MutableList>, ctx: CastingContext): OperationResult { if (stack.isEmpty()) - throw CastException(CastException.Reason.NOT_ENOUGH_ARGS, 1, stack.size) - val arg = stack.takeLast(1).getChecked(0) + throw MishapNotEnoughArgs(1, 0) + val arg = stack.getChecked(stack.lastIndex) + val datum = stack[stack.lastIndex] val distance = stack.size - (arg + 1) // because getChecked just gives me a double for some reason stack.removeLast() - if (distance < stack.size && Math.abs(distance.toInt() - distance) < 0.05f) { + if (distance < stack.size && abs(distance.toInt() - distance) < 0.05f) { val fish = stack[distance.toInt()] stack.removeAt(distance.toInt()) stack.add(stack.size, fish) } else { - throw CastException(CastException.Reason.INVALID_VALUE, "integer less than " + stack.size + " but greater than 0", arg) + throw MishapInvalidIota( + datum, + 0, + TranslatableComponent("hexcasting.mishap.invalid_value.fisherman", stack.size) + ) } val sideEffects = mutableListOf(OperatorSideEffect.ConsumeMana(this.manaCost)) diff --git a/src/main/java/at/petrak/hexcasting/common/casting/operators/OpRead.kt b/src/main/java/at/petrak/hexcasting/common/casting/operators/OpRead.kt index cf52ced3..87b9ee69 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/operators/OpRead.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/operators/OpRead.kt @@ -3,15 +3,20 @@ package at.petrak.hexcasting.common.casting.operators import at.petrak.hexcasting.api.spell.ConstManaOperator import at.petrak.hexcasting.api.spell.SpellDatum import at.petrak.hexcasting.common.casting.CastingContext -import at.petrak.hexcasting.common.casting.Widget +import at.petrak.hexcasting.common.casting.mishaps.MishapBadOffhandItem import at.petrak.hexcasting.common.items.ItemDataHolder object OpRead : ConstManaOperator { override val argc = 0 override fun execute(args: List>, ctx: CastingContext): List> { - val dataer = ctx.getDataHolder() - val datum = (dataer.item as ItemDataHolder).readDatum(dataer, ctx) - return listOf(datum ?: SpellDatum.make(Widget.NULL)) + val handStack = + ctx.caster.getItemInHand(ctx.otherHand) + val handItem = handStack.item + if (handItem !is ItemDataHolder) { + throw MishapBadOffhandItem.of(handStack, "iota.read") + } + val datum = handItem.readDatum(handStack, ctx) ?: throw MishapBadOffhandItem.of(handStack, "iota.read") + return listOf(datum) } } \ No newline at end of file diff --git a/src/main/java/at/petrak/hexcasting/common/casting/operators/OpTheCoolerRead.kt b/src/main/java/at/petrak/hexcasting/common/casting/operators/OpTheCoolerRead.kt index e594d355..2d4177f8 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/operators/OpTheCoolerRead.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/operators/OpTheCoolerRead.kt @@ -3,9 +3,8 @@ package at.petrak.hexcasting.common.casting.operators 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.casting.CastException import at.petrak.hexcasting.common.casting.CastingContext -import at.petrak.hexcasting.common.casting.Widget +import at.petrak.hexcasting.common.casting.mishaps.MishapBadOffhandItem import at.petrak.hexcasting.common.items.ItemDataHolder import net.minecraft.world.entity.item.ItemEntity @@ -17,14 +16,15 @@ object OpTheCoolerRead : ConstManaOperator { ctx: CastingContext ): List> { val target = args.getChecked(0) - if (target.item.item !is ItemDataHolder) { - throw CastException(CastException.Reason.BAD_OFFHAND_ITEM, ItemDataHolder::class.java, target.item) + val stack = target.item + val item = stack.item + if (item !is ItemDataHolder) { + throw MishapBadOffhandItem.of(stack, "iota.read") } ctx.assertEntityInRange(target) - val stack = target.item - val item = stack.item as ItemDataHolder - val datum = item.readDatum(stack, ctx) ?: SpellDatum.make(Widget.NULL) + + val datum = item.readDatum(stack, ctx) ?: throw MishapBadOffhandItem.of(stack, "iota.read") return listOf(datum) } } \ No newline at end of file diff --git a/src/main/java/at/petrak/hexcasting/common/casting/operators/OpWrite.kt b/src/main/java/at/petrak/hexcasting/common/casting/operators/OpWrite.kt index 77fe44dc..bdaef182 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/operators/OpWrite.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/operators/OpWrite.kt @@ -5,8 +5,9 @@ import at.petrak.hexcasting.api.spell.RenderedSpell import at.petrak.hexcasting.api.spell.SpellDatum import at.petrak.hexcasting.api.spell.SpellOperator import at.petrak.hexcasting.common.blocks.circles.BlockEntitySlate -import at.petrak.hexcasting.common.casting.CastException import at.petrak.hexcasting.common.casting.CastingContext +import at.petrak.hexcasting.common.casting.mishaps.MishapBadOffhandItem +import at.petrak.hexcasting.common.casting.mishaps.MishapOthersName import at.petrak.hexcasting.common.items.HexItems import at.petrak.hexcasting.common.items.ItemDataHolder import at.petrak.hexcasting.common.items.ItemScroll @@ -26,7 +27,7 @@ object OpWrite : SpellOperator { val datum = args[0] val canWrite = if (handItem is ItemDataHolder) { - true + handItem.canWrite(tag, datum) } else if (datum.payload is HexPattern) { if (handStack.`is`(HexItems.SCROLL.get()) && !tag.contains(ItemScroll.TAG_PATTERN)) { true @@ -44,10 +45,10 @@ object OpWrite : SpellOperator { false } if (!canWrite) - throw CastException(CastException.Reason.BAD_OFFHAND_ITEM, ItemDataHolder::class.java, handStack) + throw MishapBadOffhandItem.of(handStack, "iota.write") if (datum.payload is Player && datum.payload != ctx.caster) - throw CastException(CastException.Reason.NO_WRITING_OTHER_NAMES) + throw MishapOthersName(datum.payload) return Triple( Spell(datum), diff --git a/src/main/java/at/petrak/hexcasting/common/casting/operators/circles/OpCircleBounds.kt b/src/main/java/at/petrak/hexcasting/common/casting/operators/circles/OpCircleBounds.kt index 68851aae..97b36860 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/operators/circles/OpCircleBounds.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/operators/circles/OpCircleBounds.kt @@ -3,8 +3,8 @@ package at.petrak.hexcasting.common.casting.operators.circles import at.petrak.hexcasting.api.spell.ConstManaOperator import at.petrak.hexcasting.api.spell.Operator import at.petrak.hexcasting.api.spell.SpellDatum -import at.petrak.hexcasting.common.casting.CastException import at.petrak.hexcasting.common.casting.CastingContext +import at.petrak.hexcasting.common.casting.mishaps.MishapNoSpellCircle import net.minecraft.world.phys.Vec3 class OpCircleBounds(val max: Boolean) : ConstManaOperator { @@ -12,7 +12,7 @@ class OpCircleBounds(val max: Boolean) : ConstManaOperator { override fun execute(args: List>, ctx: CastingContext): List> { if (ctx.spellCircle == null) - throw CastException(CastException.Reason.NO_SPELL_CIRCLE) + throw MishapNoSpellCircle() val aabb = ctx.spellCircle.aabb diff --git a/src/main/java/at/petrak/hexcasting/common/casting/operators/circles/OpImpetusDir.kt b/src/main/java/at/petrak/hexcasting/common/casting/operators/circles/OpImpetusDir.kt index 0fb518c0..b35147da 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/operators/circles/OpImpetusDir.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/operators/circles/OpImpetusDir.kt @@ -1,11 +1,11 @@ package at.petrak.hexcasting.common.casting.operators.circles +import at.petrak.hexcasting.api.circle.BlockAbstractImpetus import at.petrak.hexcasting.api.spell.ConstManaOperator import at.petrak.hexcasting.api.spell.Operator import at.petrak.hexcasting.api.spell.SpellDatum -import at.petrak.hexcasting.api.circle.BlockAbstractImpetus -import at.petrak.hexcasting.common.casting.CastException import at.petrak.hexcasting.common.casting.CastingContext +import at.petrak.hexcasting.common.casting.mishaps.MishapNoSpellCircle import net.minecraft.world.phys.Vec3 object OpImpetusDir : ConstManaOperator { @@ -13,7 +13,7 @@ object OpImpetusDir : ConstManaOperator { override fun execute(args: List>, ctx: CastingContext): List> { if (ctx.spellCircle == null) - throw CastException(CastException.Reason.NO_SPELL_CIRCLE) + throw MishapNoSpellCircle() val pos = ctx.spellCircle.impetusPos val bs = ctx.world.getBlockState(pos) diff --git a/src/main/java/at/petrak/hexcasting/common/casting/operators/circles/OpImpetusPos.kt b/src/main/java/at/petrak/hexcasting/common/casting/operators/circles/OpImpetusPos.kt index c8140bb9..edf497e4 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/operators/circles/OpImpetusPos.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/operators/circles/OpImpetusPos.kt @@ -3,8 +3,8 @@ package at.petrak.hexcasting.common.casting.operators.circles import at.petrak.hexcasting.api.spell.ConstManaOperator import at.petrak.hexcasting.api.spell.Operator import at.petrak.hexcasting.api.spell.SpellDatum -import at.petrak.hexcasting.common.casting.CastException import at.petrak.hexcasting.common.casting.CastingContext +import at.petrak.hexcasting.common.casting.mishaps.MishapNoSpellCircle import net.minecraft.world.phys.Vec3 object OpImpetusPos : ConstManaOperator { @@ -12,7 +12,7 @@ object OpImpetusPos : ConstManaOperator { override fun execute(args: List>, ctx: CastingContext): List> { if (ctx.spellCircle == null) - throw CastException(CastException.Reason.NO_SPELL_CIRCLE) + throw MishapNoSpellCircle() return Operator.spellListOf(Vec3.atCenterOf(ctx.spellCircle.impetusPos)) } diff --git a/src/main/java/at/petrak/hexcasting/common/casting/operators/eval/OpEval.kt b/src/main/java/at/petrak/hexcasting/common/casting/operators/eval/OpEval.kt index 39d779ef..dfe87295 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/operators/eval/OpEval.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/operators/eval/OpEval.kt @@ -7,6 +7,9 @@ import at.petrak.hexcasting.api.spell.SpellDatum import at.petrak.hexcasting.common.casting.CastingContext import at.petrak.hexcasting.common.casting.CastingHarness import at.petrak.hexcasting.common.casting.OperatorSideEffect +import at.petrak.hexcasting.common.casting.mishaps.MishapInvalidIota +import at.petrak.hexcasting.hexmath.HexPattern +import net.minecraft.network.chat.TranslatableComponent object OpEval : Operator { override fun operate(stack: MutableList>, ctx: CastingContext): OperationResult { @@ -20,9 +23,14 @@ object OpEval : Operator { val sideEffects = mutableListOf() for (pat in instrs) { - val res = harness.getUpdate(pat.tryGet(), ctx.world) + val pattern = if (pat.payload is HexPattern) { + pat.payload + } else { + throw MishapInvalidIota(pat, 0, TranslatableComponent("hexcasting.mishap.invalid_value.list.pattern")) + } + val res = harness.getUpdate(pattern, ctx.world) sideEffects.addAll(res.sideEffects) - if (res.sideEffects.any { it is OperatorSideEffect.Mishap }) { + if (res.sideEffects.any { it is OperatorSideEffect.DoMishap }) { break } harness.applyFunctionalData(res.newData) diff --git a/src/main/java/at/petrak/hexcasting/common/casting/operators/eval/OpForEach.kt b/src/main/java/at/petrak/hexcasting/common/casting/operators/eval/OpForEach.kt index 75056d48..d172cb4c 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/operators/eval/OpForEach.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/operators/eval/OpForEach.kt @@ -4,15 +4,18 @@ 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.common.casting.CastException import at.petrak.hexcasting.common.casting.CastingContext import at.petrak.hexcasting.common.casting.CastingHarness import at.petrak.hexcasting.common.casting.OperatorSideEffect +import at.petrak.hexcasting.common.casting.mishaps.MishapInvalidIota +import at.petrak.hexcasting.common.casting.mishaps.MishapNotEnoughArgs +import at.petrak.hexcasting.hexmath.HexPattern +import net.minecraft.network.chat.TranslatableComponent object OpForEach : Operator { override fun operate(stack: MutableList>, ctx: CastingContext): OperationResult { if (stack.size < 2) - throw CastException(CastException.Reason.NOT_ENOUGH_ARGS, 2, stack.size) + throw MishapNotEnoughArgs(2, stack.size) val instrs: List> = stack.getChecked(stack.lastIndex - 1) val datums: List> = stack.getChecked(stack.lastIndex) @@ -28,9 +31,18 @@ object OpForEach : Operator { harness.stack.addAll(stack) harness.stack.add(subdatum) for (pat in instrs) { - val res = harness.getUpdate(pat.tryGet(), ctx.world) + val pattern = if (pat.payload is HexPattern) { + pat.payload + } else { + throw MishapInvalidIota( + pat, + 1, + TranslatableComponent("hexcasting.mishap.invalid_value.list.pattern") + ) + } + val res = harness.getUpdate(pattern, ctx.world) sideEffects.addAll(res.sideEffects) - if (res.sideEffects.any { it is OperatorSideEffect.Mishap }) { + if (res.sideEffects.any { it is OperatorSideEffect.DoMishap }) { break } harness.applyFunctionalData(res.newData) diff --git a/src/main/java/at/petrak/hexcasting/common/casting/operators/lists/OpLastNToList.kt b/src/main/java/at/petrak/hexcasting/common/casting/operators/lists/OpLastNToList.kt index 6057b18e..7f3a2cb4 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/operators/lists/OpLastNToList.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/operators/lists/OpLastNToList.kt @@ -5,9 +5,11 @@ import at.petrak.hexcasting.api.spell.Operator 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.common.casting.CastException import at.petrak.hexcasting.common.casting.CastingContext import at.petrak.hexcasting.common.casting.OperatorSideEffect +import at.petrak.hexcasting.common.casting.mishaps.MishapInvalidIota +import at.petrak.hexcasting.common.casting.mishaps.MishapNotEnoughArgs +import net.minecraft.network.chat.TranslatableComponent object OpLastNToList : Operator { val manaCost: Int @@ -15,13 +17,18 @@ object OpLastNToList : Operator { override fun operate(stack: MutableList>, ctx: CastingContext): OperationResult { if (stack.isEmpty()) - throw CastException(CastException.Reason.NOT_ENOUGH_ARGS, 1, stack.size) + throw MishapNotEnoughArgs(1, 0) val arg = stack.takeLast(1).getChecked(0) + val datum = stack[stack.lastIndex] stack.removeLast() - if (arg < 0) { - throw CastException(CastException.Reason.INVALID_VALUE, "integer greater than 0", arg) + if (arg < 0 || arg >= stack.size) { + throw MishapInvalidIota( + datum, + 0, + TranslatableComponent("hexcasting.mishap.invalid_value.fisherman", stack.size) + ) } - val output = emptyList>().toMutableList() + val output = mutableListOf>() output.addAll(stack.takeLast(arg.toInt())) val endSize = stack.size - output.toList().size while (stack.size != endSize) { diff --git a/src/main/java/at/petrak/hexcasting/common/casting/operators/math/MathOpUtils.kt b/src/main/java/at/petrak/hexcasting/common/casting/operators/math/MathOpUtils.kt index 422206eb..824c2613 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/operators/math/MathOpUtils.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/operators/math/MathOpUtils.kt @@ -1,15 +1,20 @@ package at.petrak.hexcasting.common.casting.operators.math import at.petrak.hexcasting.api.spell.SpellDatum -import at.petrak.hexcasting.common.casting.CastException +import at.petrak.hexcasting.common.casting.mishaps.MishapInvalidIota import com.mojang.datafixers.util.Either +import net.minecraft.network.chat.TranslatableComponent import net.minecraft.world.phys.Vec3 object MathOpUtils { - fun GetNumOrVec(datum: SpellDatum<*>): Either = + fun GetNumOrVec(datum: SpellDatum<*>, reverseIdx: Int): Either = when (datum.payload) { is Double -> Either.left(datum.payload) is Vec3 -> Either.right(datum.payload) - else -> throw CastException(CastException.Reason.OP_WRONG_TYPE, Either::class.java, datum.payload) + else -> throw MishapInvalidIota( + datum, + reverseIdx, + TranslatableComponent("hexcasting.mishap.invalid_value.numvec") + ) } } \ No newline at end of file diff --git a/src/main/java/at/petrak/hexcasting/common/casting/operators/math/OpAbsLen.kt b/src/main/java/at/petrak/hexcasting/common/casting/operators/math/OpAbsLen.kt index dfebddd4..0175a5f0 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/operators/math/OpAbsLen.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/operators/math/OpAbsLen.kt @@ -11,7 +11,7 @@ object OpAbsLen : ConstManaOperator { get() = 1 override fun execute(args: List>, ctx: CastingContext): List> { - val x = MathOpUtils.GetNumOrVec(args[0]) + val x = MathOpUtils.GetNumOrVec(args[0], 0) return spellListOf( x.map({ num -> num.absoluteValue }, { vec -> vec.length() }) diff --git a/src/main/java/at/petrak/hexcasting/common/casting/operators/math/OpAdd.kt b/src/main/java/at/petrak/hexcasting/common/casting/operators/math/OpAdd.kt index ffc6ca00..ff7dd0df 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/operators/math/OpAdd.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/operators/math/OpAdd.kt @@ -10,8 +10,8 @@ object OpAdd : ConstManaOperator { get() = 2 override fun execute(args: List>, ctx: CastingContext): List> { - val lhs = MathOpUtils.GetNumOrVec(args[0]) - val rhs = MathOpUtils.GetNumOrVec(args[1]) + val lhs = MathOpUtils.GetNumOrVec(args[0], 1) + val rhs = MathOpUtils.GetNumOrVec(args[1], 0) return spellListOf( lhs.map({ lnum -> diff --git a/src/main/java/at/petrak/hexcasting/common/casting/operators/math/OpDivCross.kt b/src/main/java/at/petrak/hexcasting/common/casting/operators/math/OpDivCross.kt index e3b720c6..57f0c7cf 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/operators/math/OpDivCross.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/operators/math/OpDivCross.kt @@ -11,8 +11,8 @@ object OpDivCross : ConstManaOperator { get() = 2 override fun execute(args: List>, ctx: CastingContext): List> { - val lhs = MathOpUtils.GetNumOrVec(args[0]) - val rhs = MathOpUtils.GetNumOrVec(args[1]) + val lhs = MathOpUtils.GetNumOrVec(args[0], 1) + val rhs = MathOpUtils.GetNumOrVec(args[1], 0) return spellListOf( lhs.map({ lnum -> diff --git a/src/main/java/at/petrak/hexcasting/common/casting/operators/math/OpMulDot.kt b/src/main/java/at/petrak/hexcasting/common/casting/operators/math/OpMulDot.kt index f44bc707..949d4210 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/operators/math/OpMulDot.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/operators/math/OpMulDot.kt @@ -10,8 +10,8 @@ object OpMulDot : ConstManaOperator { get() = 2 override fun execute(args: List>, ctx: CastingContext): List> { - val lhs = MathOpUtils.GetNumOrVec(args[0]) - val rhs = MathOpUtils.GetNumOrVec(args[1]) + val lhs = MathOpUtils.GetNumOrVec(args[0], 1) + val rhs = MathOpUtils.GetNumOrVec(args[1], 0) return spellListOf( lhs.map({ lnum -> diff --git a/src/main/java/at/petrak/hexcasting/common/casting/operators/math/OpPowProj.kt b/src/main/java/at/petrak/hexcasting/common/casting/operators/math/OpPowProj.kt index a9bd75a4..fabc206b 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/operators/math/OpPowProj.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/operators/math/OpPowProj.kt @@ -12,8 +12,8 @@ object OpPowProj : ConstManaOperator { get() = 2 override fun execute(args: List>, ctx: CastingContext): List> { - val lhs = MathOpUtils.GetNumOrVec(args[0]) - val rhs = MathOpUtils.GetNumOrVec(args[1]) + val lhs = MathOpUtils.GetNumOrVec(args[0], 1) + val rhs = MathOpUtils.GetNumOrVec(args[1], 0) return spellListOf( lhs.map({ lnum -> diff --git a/src/main/java/at/petrak/hexcasting/common/casting/operators/math/OpSub.kt b/src/main/java/at/petrak/hexcasting/common/casting/operators/math/OpSub.kt index 922ee84b..1471702e 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/operators/math/OpSub.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/operators/math/OpSub.kt @@ -11,8 +11,8 @@ object OpSub : ConstManaOperator { get() = 2 override fun execute(args: List>, ctx: CastingContext): List> { - val lhs = MathOpUtils.GetNumOrVec(args[0]) - val rhs = MathOpUtils.GetNumOrVec(args[1]) + val lhs = MathOpUtils.GetNumOrVec(args[0], 1) + val rhs = MathOpUtils.GetNumOrVec(args[1], 0) return spellListOf( lhs.map({ lnum -> diff --git a/src/main/java/at/petrak/hexcasting/common/casting/operators/spells/OpErase.kt b/src/main/java/at/petrak/hexcasting/common/casting/operators/spells/OpErase.kt index 08ca04b6..ff72a309 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/operators/spells/OpErase.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/operators/spells/OpErase.kt @@ -4,8 +4,8 @@ import at.petrak.hexcasting.api.spell.ParticleSpray import at.petrak.hexcasting.api.spell.RenderedSpell import at.petrak.hexcasting.api.spell.SpellDatum import at.petrak.hexcasting.api.spell.SpellOperator -import at.petrak.hexcasting.common.casting.CastException import at.petrak.hexcasting.common.casting.CastingContext +import at.petrak.hexcasting.common.casting.mishaps.MishapBadOffhandItem import at.petrak.hexcasting.common.items.magic.ItemPackagedSpell class OpErase : SpellOperator { @@ -17,7 +17,7 @@ class OpErase : SpellOperator { ): Triple> { val otherHandItem = ctx.caster.getItemInHand(ctx.otherHand) if (otherHandItem.item !is ItemPackagedSpell) { - throw CastException(CastException.Reason.BAD_OFFHAND_ITEM, ItemPackagedSpell::class.java, otherHandItem) + throw MishapBadOffhandItem.of(otherHandItem, "eraseable") } return Triple(Spell, 10_000, listOf()) diff --git a/src/main/java/at/petrak/hexcasting/common/casting/operators/spells/OpMakeBattery.kt b/src/main/java/at/petrak/hexcasting/common/casting/operators/spells/OpMakeBattery.kt index 4db3360b..3a408c2c 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/operators/spells/OpMakeBattery.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/operators/spells/OpMakeBattery.kt @@ -5,9 +5,9 @@ import at.petrak.hexcasting.api.spell.ParticleSpray import at.petrak.hexcasting.api.spell.RenderedSpell import at.petrak.hexcasting.api.spell.SpellDatum import at.petrak.hexcasting.api.spell.SpellOperator -import at.petrak.hexcasting.common.casting.CastException import at.petrak.hexcasting.common.casting.CastingContext import at.petrak.hexcasting.common.casting.ManaHelper +import at.petrak.hexcasting.common.casting.mishaps.MishapBadOffhandItem import at.petrak.hexcasting.common.items.HexItems import at.petrak.hexcasting.common.items.magic.ItemManaHolder import net.minecraft.world.entity.item.ItemEntity @@ -24,14 +24,27 @@ object OpMakeBattery : SpellOperator { val otherHandItem = ctx.caster.getItemInHand(ctx.otherHand) if (otherHandItem.item != Items.GLASS_BOTTLE) { - throw CastException(CastException.Reason.BAD_OFFHAND_ITEM_ITEM, Items.GLASS_BOTTLE, otherHandItem) + throw MishapBadOffhandItem.of( + otherHandItem, + "bottle" + ) } if (otherHandItem.count != 1) { - throw CastException(CastException.Reason.BAD_OFFHAND_COUNT, 1, otherHandItem.count) + throw MishapBadOffhandItem.of( + otherHandItem, + "only_one" + ) } - + ctx.assertEntityInRange(entity) + if (!ManaHelper.isManaItem(entity.item)) { + throw MishapBadOffhandItem.of( + otherHandItem, + "mana" + ) + } + return Triple(Spell(entity), 100_000, listOf(ParticleSpray.Burst(entity.position(), 0.5))) } diff --git a/src/main/java/at/petrak/hexcasting/common/casting/operators/spells/OpMakePackagedSpell.kt b/src/main/java/at/petrak/hexcasting/common/casting/operators/spells/OpMakePackagedSpell.kt index 8101a7d6..135a8872 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/operators/spells/OpMakePackagedSpell.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/operators/spells/OpMakePackagedSpell.kt @@ -5,29 +5,42 @@ import at.petrak.hexcasting.api.spell.ParticleSpray import at.petrak.hexcasting.api.spell.RenderedSpell import at.petrak.hexcasting.api.spell.SpellDatum import at.petrak.hexcasting.api.spell.SpellOperator -import at.petrak.hexcasting.common.casting.CastException import at.petrak.hexcasting.common.casting.CastingContext import at.petrak.hexcasting.common.casting.ManaHelper +import at.petrak.hexcasting.common.casting.mishaps.MishapBadOffhandItem +import at.petrak.hexcasting.common.casting.mishaps.MishapInvalidIota import at.petrak.hexcasting.common.items.magic.ItemPackagedSpell import at.petrak.hexcasting.hexmath.HexPattern import net.minecraft.nbt.ListTag +import net.minecraft.network.chat.TranslatableComponent import net.minecraft.world.entity.item.ItemEntity -class OpMakePackagedSpell(val type: Class, val cost: Int) : SpellOperator { +class OpMakePackagedSpell(val itemType: T, val cost: Int) : SpellOperator { override val argc = 2 override fun execute( args: List>, ctx: CastingContext ): Triple> { val entity = args.getChecked(0) - val patterns = args.getChecked>>(1).map { it.tryGet() } + val patterns = args.getChecked>>(1).map { + if (it.payload is HexPattern) + it.payload + else + throw MishapInvalidIota(it, 0, TranslatableComponent("hexcasting.mishap.invalid_value.list.pattern")) + } val otherHandItem = ctx.caster.getItemInHand(ctx.otherHand) - if (!type.isAssignableFrom(otherHandItem.item.javaClass)) { - throw CastException(CastException.Reason.BAD_OFFHAND_ITEM, type, otherHandItem) + if (!otherHandItem.`is`(itemType)) { + throw MishapBadOffhandItem(otherHandItem, itemType.description) } ctx.assertEntityInRange(entity) + if (!ManaHelper.isManaItem(entity.item)) { + throw MishapBadOffhandItem.of( + otherHandItem, + "mana" + ) + } return Triple(Spell(entity, patterns), cost, listOf(ParticleSpray.Burst(entity.position(), 0.5))) } diff --git a/src/main/java/at/petrak/hexcasting/common/casting/operators/spells/OpPrint.kt b/src/main/java/at/petrak/hexcasting/common/casting/operators/spells/OpPrint.kt index 6707c527..0f7256bc 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/operators/spells/OpPrint.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/operators/spells/OpPrint.kt @@ -4,15 +4,15 @@ import at.petrak.hexcasting.api.spell.OperationResult import at.petrak.hexcasting.api.spell.Operator import at.petrak.hexcasting.api.spell.RenderedSpell import at.petrak.hexcasting.api.spell.SpellDatum -import at.petrak.hexcasting.common.casting.CastException import at.petrak.hexcasting.common.casting.CastingContext import at.petrak.hexcasting.common.casting.OperatorSideEffect +import at.petrak.hexcasting.common.casting.mishaps.MishapNotEnoughArgs import net.minecraft.Util object OpPrint : Operator { override fun operate(stack: MutableList>, ctx: CastingContext): OperationResult { if (stack.isEmpty()) { - throw CastException(CastException.Reason.NOT_ENOUGH_ARGS, 1, stack.size) + throw MishapNotEnoughArgs(1, 0) } val datum = stack[stack.lastIndex] return OperationResult( diff --git a/src/main/java/at/petrak/hexcasting/common/casting/operators/spells/OpRecharge.kt b/src/main/java/at/petrak/hexcasting/common/casting/operators/spells/OpRecharge.kt index 4c45fb25..78dd77cd 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/operators/spells/OpRecharge.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/operators/spells/OpRecharge.kt @@ -5,9 +5,9 @@ import at.petrak.hexcasting.api.spell.ParticleSpray import at.petrak.hexcasting.api.spell.RenderedSpell import at.petrak.hexcasting.api.spell.SpellDatum import at.petrak.hexcasting.api.spell.SpellOperator -import at.petrak.hexcasting.common.casting.CastException import at.petrak.hexcasting.common.casting.CastingContext import at.petrak.hexcasting.common.casting.ManaHelper +import at.petrak.hexcasting.common.casting.mishaps.MishapBadOffhandItem import at.petrak.hexcasting.common.items.magic.ItemManaHolder import net.minecraft.util.Mth import net.minecraft.world.entity.item.ItemEntity @@ -20,12 +20,22 @@ object OpRecharge : SpellOperator { ): Triple> { val otherHandItem = ctx.caster.getItemInHand(ctx.otherHand) if (otherHandItem.item !is ItemManaHolder) { - throw CastException(CastException.Reason.BAD_OFFHAND_ITEM, ItemManaHolder::class.java, otherHandItem) + throw MishapBadOffhandItem.of( + otherHandItem, + "rechargable" + ) } val entity = args.getChecked(0) ctx.assertEntityInRange(entity) + if (!ManaHelper.isManaItem(entity.item)) { + throw MishapBadOffhandItem.of( + otherHandItem, + "mana" + ) + } + return Triple(Spell(entity), 100_000, listOf(ParticleSpray.Burst(entity.position(), 0.5))) } diff --git a/src/main/java/at/petrak/hexcasting/common/casting/operators/spells/great/OpBrainsweep.kt b/src/main/java/at/petrak/hexcasting/common/casting/operators/spells/great/OpBrainsweep.kt index 283ec6b6..6052980e 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/operators/spells/great/OpBrainsweep.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/operators/spells/great/OpBrainsweep.kt @@ -5,8 +5,9 @@ import at.petrak.hexcasting.api.spell.ParticleSpray import at.petrak.hexcasting.api.spell.RenderedSpell import at.petrak.hexcasting.api.spell.SpellDatum import at.petrak.hexcasting.api.spell.SpellOperator -import at.petrak.hexcasting.common.casting.CastException import at.petrak.hexcasting.common.casting.CastingContext +import at.petrak.hexcasting.common.casting.mishaps.MishapAlreadyBrainswept +import at.petrak.hexcasting.common.casting.mishaps.MishapBadBrainsweep import at.petrak.hexcasting.common.misc.Brainsweeping import at.petrak.hexcasting.common.recipe.BrainsweepRecipe import at.petrak.hexcasting.common.recipe.HexRecipeSerializers @@ -29,7 +30,7 @@ object OpBrainsweep : SpellOperator { ctx.assertEntityInRange(sacrifice) if (Brainsweeping.isBrainswept(sacrifice)) - throw CastException(CastException.Reason.RECIPE_DIDNT_WORK) + throw MishapAlreadyBrainswept(sacrifice) val bpos = BlockPos(pos) val state = ctx.world.getBlockState(bpos) @@ -37,7 +38,7 @@ object OpBrainsweep : SpellOperator { val recman = ctx.world.recipeManager val recipes = recman.getAllRecipesFor(HexRecipeSerializers.BRAINSWEEP_TYPE) val recipe = recipes.find { it.matches(state, sacrifice) } - ?: throw CastException(CastException.Reason.RECIPE_DIDNT_WORK) + ?: throw MishapBadBrainsweep(sacrifice, bpos) return Triple( Spell(bpos, sacrifice, recipe), diff --git a/src/main/java/at/petrak/hexcasting/common/items/ItemAbacus.java b/src/main/java/at/petrak/hexcasting/common/items/ItemAbacus.java index 2137eb45..d477a241 100644 --- a/src/main/java/at/petrak/hexcasting/common/items/ItemAbacus.java +++ b/src/main/java/at/petrak/hexcasting/common/items/ItemAbacus.java @@ -32,6 +32,11 @@ public class ItemAbacus extends ItemDataHolder { return datum.serializeToNBT(); } + @Override + public boolean canWrite(CompoundTag tag, SpellDatum datum) { + return false; + } + @Override public void writeDatum(CompoundTag tag, SpellDatum datum) { // nope diff --git a/src/main/java/at/petrak/hexcasting/common/items/ItemDataHolder.java b/src/main/java/at/petrak/hexcasting/common/items/ItemDataHolder.java index de286d0e..be6c4e1a 100644 --- a/src/main/java/at/petrak/hexcasting/common/items/ItemDataHolder.java +++ b/src/main/java/at/petrak/hexcasting/common/items/ItemDataHolder.java @@ -36,8 +36,12 @@ abstract public class ItemDataHolder extends Item { } } + + public abstract boolean canWrite(CompoundTag tag, SpellDatum datum); + public abstract void writeDatum(CompoundTag tag, SpellDatum datum); + @Override public void appendHoverText(ItemStack pStack, @Nullable Level pLevel, List pTooltipComponents, TooltipFlag pIsAdvanced) { diff --git a/src/main/java/at/petrak/hexcasting/common/items/ItemFocus.java b/src/main/java/at/petrak/hexcasting/common/items/ItemFocus.java index 3c3b12e3..b7f19544 100644 --- a/src/main/java/at/petrak/hexcasting/common/items/ItemFocus.java +++ b/src/main/java/at/petrak/hexcasting/common/items/ItemFocus.java @@ -29,6 +29,11 @@ public class ItemFocus extends ItemDataHolder { return tag.getCompound(TAG_DATA); } + @Override + public boolean canWrite(CompoundTag tag, SpellDatum datum) { + return !tag.getBoolean(TAG_SEALED); + } + @Override public void writeDatum(CompoundTag tag, SpellDatum datum) { if (!tag.getBoolean(TAG_SEALED)) { diff --git a/src/main/java/at/petrak/hexcasting/common/items/ItemSpellbook.java b/src/main/java/at/petrak/hexcasting/common/items/ItemSpellbook.java index f210b715..b26ffb13 100644 --- a/src/main/java/at/petrak/hexcasting/common/items/ItemSpellbook.java +++ b/src/main/java/at/petrak/hexcasting/common/items/ItemSpellbook.java @@ -82,6 +82,11 @@ public class ItemSpellbook extends ItemDataHolder { } } + @Override + public boolean canWrite(CompoundTag tag, SpellDatum datum) { + return true; + } + public void writeDatum(CompoundTag tag, SpellDatum datum) { int idx; if (tag.contains(TAG_SELECTED_PAGE)) { diff --git a/src/main/java/at/petrak/hexcasting/datagen/HexItemModels.java b/src/main/java/at/petrak/hexcasting/datagen/HexItemModels.java index 92b9b36e..234427f6 100644 --- a/src/main/java/at/petrak/hexcasting/datagen/HexItemModels.java +++ b/src/main/java/at/petrak/hexcasting/datagen/HexItemModels.java @@ -11,6 +11,7 @@ import at.petrak.paucal.api.datagen.PaucalItemModelProvider; import com.mojang.datafixers.util.Pair; import net.minecraft.data.DataGenerator; import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.DyeColor; import net.minecraft.world.item.Item; import net.minecraftforge.client.model.generators.ModelFile; import net.minecraftforge.common.data.ExistingFileHelper; @@ -104,8 +105,9 @@ public class HexItemModels extends PaucalItemModelProvider { } } - for (int i = 0; i < 16; i++) { - singleTexture(HexItems.DYE_COLORIZERS[i].getId().getPath(), new ResourceLocation("item/generated"), + for (int i = 0; i < DyeColor.values().length; i++) { + singleTexture(HexItems.DYE_COLORIZERS.get(DyeColor.values()[i]).getId().getPath(), + new ResourceLocation("item/generated"), "layer0", new ResourceLocation(HexMod.MOD_ID, "item/colorizer/dye" + i)); } for (int i = 0; i < 14; i++) { diff --git a/src/main/java/at/petrak/hexcasting/datagen/HexRecipes.java b/src/main/java/at/petrak/hexcasting/datagen/HexRecipes.java index 21030a72..be2a8b9e 100644 --- a/src/main/java/at/petrak/hexcasting/datagen/HexRecipes.java +++ b/src/main/java/at/petrak/hexcasting/datagen/HexRecipes.java @@ -105,12 +105,12 @@ public class HexRecipes extends PaucalRecipeProvider { .pattern(" B ") .unlockedBy("has_item", has(Items.AMETHYST_SHARD)).save(recipes); - for (var dyeColorizer : HexItems.DYE_COLORIZERS) { - var item = dyeColorizer.get(); + for (var dye : DyeColor.values()) { + var item = HexItems.DYE_COLORIZERS.get(dye).get(); ShapedRecipeBuilder.shaped(item) .define('B', Items.BOWL) .define('D', HexItems.AMETHYST_DUST.get()) - .define('C', DyeItem.byColor(DyeColor.values()[item.getDyeIdx()])) + .define('C', DyeItem.byColor(dye)) .pattern(" C ") .pattern(" D ") .pattern(" B ") diff --git a/src/main/resources/assets/hexcasting/lang/en_us.json b/src/main/resources/assets/hexcasting/lang/en_us.json index f8ca2225..e2bf23ee 100644 --- a/src/main/resources/assets/hexcasting/lang/en_us.json +++ b/src/main/resources/assets/hexcasting/lang/en_us.json @@ -247,10 +247,11 @@ "hexcasting.spell.hexcasting:const/vec/ny": "Vector Reflection -Y", "hexcasting.spell.hexcasting:const/vec/nz": "Vector Reflection -Z", "hexcasting.spell.hexcasting:const/vec/0": "Vector Reflection Zero", + "hexcasting.spell.unknown": "Special Handler", - "hexcasting.mishap.invalid_pattern": "That pattern isn't associated with any action.", + "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, but got %s", + "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", "hexcasting.mishap.invalid_value.class.list": "a list", @@ -261,18 +262,27 @@ "hexcasting.mishap.invalid_value.class.entity.villager": "a villager", "hexcasting.mishap.invalid_value.class.entity.living": "a living entity", "hexcasting.mishap.invalid_value.class.entity": "an entity", - "hexcasting.mishap.not_enough_args": "%s expected %s arguments but the stack was only %s tall", + "hexcasting.mishap.invalid_value.class.unknown": "(unknown, uh-oh, this is a bug)", + "hexcasting.mishap.invalid_value.numvec": "a number or vector", + "hexcasting.mishap.invalid_value.list.pattern": "a list of patterns", + "hexcasting.mishap.invalid_value.fisherman": "an integer between 0 and %d", + "hexcasting.mishap.not_enough_args": "%s expected %s or more arguments but the stack was only %s tall", "hexcasting.mishap.too_many_close_parens": "Used Retrospection without first using Introspection", "hexcasting.mishap.location_too_far": "%s is out of range for %s", "hexcasting.mishap.entity_too_far": "%s is out of range for %s", "hexcasting.mishap.eval_too_deep": "Recursively evaluated too deep", "hexcasting.mishap.bad_item": "%s needs %s but got %s", - "hexcasting.mishap.bad_item.offhand": "%s needs %s in the other hand but got %s", + "hexcasting.mishap.bad_item.offhand": "%s needs %s in the other hand but got %dx %s", + "hexcasting.mishap.bad_item.iota": "a place to store iotas", "hexcasting.mishap.bad_item.iota.read": "a place to read iotas from", "hexcasting.mishap.bad_item.iota.write": "a place to write iotas to", - "hexcasting.mishap.bad_item.media": "a media-containing item", + "hexcasting.mishap.bad_item.mana": "a media-containing item", "hexcasting.mishap.bad_item.only_one": "exactly one item", + "hexcasting.mishap.bad_item.eraseable": "an eraseable item", + "hexcasting.mishap.bad_item.bottle": "a glass bottle", + "hexcasting.mishap.bad_item.rechargable": "a rechargable item", "hexcasting.mishap.bad_brainsweep": "The %s rejected the villager's mind", + "hexcasting.mishap.already_brainswept": "The villager has already been used", "hexcasting.mishap.no_spell_circle": "%s requires a spell circle", "hexcasting.mishap.others_name": "Tried to invade %s's privacy",