From e6253263e07aad70e5c7069d96958394c3aee7a8 Mon Sep 17 00:00:00 2001 From: Talia-12 Date: Mon, 5 Feb 2024 23:27:06 +1000 Subject: [PATCH 01/14] Fix #585, Power Distillation should mishap when taking the square root of a negative number --- .../hexcasting/common/casting/arithmetic/DoubleArithmetic.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/DoubleArithmetic.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/DoubleArithmetic.kt index 57917c2279..a111f9958d 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/DoubleArithmetic.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/DoubleArithmetic.kt @@ -57,7 +57,7 @@ object DoubleArithmetic : Arithmetic { MUL -> make2 { a, b -> a * b } DIV -> make2 { a, b -> if (b == 0.0) throw MishapDivideByZero.of(a, b) else a / b } ABS -> make1 { a -> abs(a) } - POW -> make2 { a, b -> a.pow(b) } + POW -> make2 { a, b -> if (a < 0 && !DoubleIota.tolerates(floor(b), b)) throw MishapDivideByZero.of(a, b, "power_neg") else a.pow(b) } FLOOR -> make1 { a -> floor(a) } CEIL -> make1 { a -> ceil(a) } SIN -> make1 { a -> sin(a) } From 1559d70d4f069d948a5202e432d1d70d0ee870a3 Mon Sep 17 00:00:00 2001 From: Talia-12 Date: Mon, 5 Feb 2024 23:59:50 +1000 Subject: [PATCH 02/14] Fix #551, White Sun's Zeniths at level 0 gives a high regen for free. --- .../hexcasting/common/casting/actions/spells/OpPotionEffect.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpPotionEffect.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpPotionEffect.kt index cea6c99faf..6f7dc5a05e 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpPotionEffect.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpPotionEffect.kt @@ -24,7 +24,7 @@ class OpPotionEffect( val target = args.getLivingEntityButNotArmorStand(0, argc) val duration = args.getPositiveDouble(1, argc) val potency = if (this.allowPotency) - args.getPositiveDoubleUnderInclusive(2, 127.0, argc) + args.getDoubleBetween(2, 1.0, 127.0, argc) else 1.0 env.assertEntityInRange(target) From e8dfa94f93ed3c5ce3a8035fcb63f1acb2685627 Mon Sep 17 00:00:00 2001 From: Talia-12 Date: Tue, 6 Feb 2024 00:29:54 +1000 Subject: [PATCH 03/14] Fixed #545 (Cannot read null from empty scrolls/slates) by defaulting all readable items to read NullIota() if no iota contained. Fixed behaviour of OpRead and similar if no IotaHolder found. --- .../api/casting/mishaps/MishapBadOffhandItem.kt | 6 +++--- .../at/petrak/hexcasting/api/item/IotaHolderItem.java | 5 ++--- .../petrak/hexcasting/common/casting/actions/rw/OpRead.kt | 3 +-- .../hexcasting/common/casting/actions/rw/OpReadable.kt | 4 ++-- .../hexcasting/common/casting/actions/rw/OpWrite.kt | 8 ++++---- .../petrak/hexcasting/common/items/storage/ItemFocus.java | 6 ------ .../hexcasting/common/items/storage/ItemSpellbook.java | 7 ------- 7 files changed, 12 insertions(+), 27 deletions(-) diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadOffhandItem.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadOffhandItem.kt index 1de584503c..2e7ad8df9d 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadOffhandItem.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadOffhandItem.kt @@ -9,7 +9,7 @@ import net.minecraft.world.InteractionHand import net.minecraft.world.item.DyeColor import net.minecraft.world.item.ItemStack -class MishapBadOffhandItem(val item: ItemStack, val hand: InteractionHand?, val wanted: Component) : Mishap() { +class MishapBadOffhandItem(val item: ItemStack?, val hand: InteractionHand?, val wanted: Component) : Mishap() { override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = dyeColor(DyeColor.BROWN) @@ -17,14 +17,14 @@ class MishapBadOffhandItem(val item: ItemStack, val hand: InteractionHand?, val env.mishapEnvironment.dropHeldItems() } - override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = if (item.isEmpty) + override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = if (item?.isEmpty != false) error("no_item.offhand", wanted) else error("bad_item.offhand", wanted, item.count, item.displayName) companion object { @JvmStatic - fun of(item: ItemStack, hand: InteractionHand?, stub: String, vararg args: Any): MishapBadOffhandItem { + fun of(item: ItemStack?, hand: InteractionHand?, stub: String, vararg args: Any): MishapBadOffhandItem { return MishapBadOffhandItem(item, hand, "hexcasting.mishap.bad_item.$stub".asTranslatedComponent(*args)) } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/item/IotaHolderItem.java b/Common/src/main/java/at/petrak/hexcasting/api/item/IotaHolderItem.java index 46f4074fc8..c9cca3d607 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/item/IotaHolderItem.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/item/IotaHolderItem.java @@ -2,6 +2,7 @@ import at.petrak.hexcasting.api.casting.iota.Iota; import at.petrak.hexcasting.api.casting.iota.IotaType; +import at.petrak.hexcasting.api.casting.iota.NullIota; import at.petrak.hexcasting.api.utils.HexUtils; import at.petrak.hexcasting.api.utils.NBTHelper; import at.petrak.hexcasting.client.ClientTickCounter; @@ -54,12 +55,10 @@ default Iota readIota(ItemStack stack, ServerLevel world) { /** * What is this considered to contain when nothing can be read? - *

- * TODO i'm not sure what this isCastable for */ @Nullable default Iota emptyIota(ItemStack stack) { - return null; + return new NullIota(); } default int getColor(ItemStack stack) { diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpRead.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpRead.kt index fceb1a1af1..4dd0e04dfc 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpRead.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpRead.kt @@ -3,7 +3,6 @@ package at.petrak.hexcasting.common.casting.actions.rw import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota -import at.petrak.hexcasting.api.casting.iota.NullIota import at.petrak.hexcasting.api.casting.mishaps.MishapBadOffhandItem import at.petrak.hexcasting.xplat.IXplatAbstractions @@ -14,7 +13,7 @@ object OpRead : ConstMediaAction { val (handStack, hand) = env.getHeldItemToOperateOn { val dataHolder = IXplatAbstractions.INSTANCE.findDataHolder(it) dataHolder != null && (dataHolder.readIota(env.world) != null || dataHolder.emptyIota() != null) - } ?: return listOf(NullIota()) + } ?: throw MishapBadOffhandItem.of(null, null, "iota.read") val datumHolder = IXplatAbstractions.INSTANCE.findDataHolder(handStack) ?: throw MishapBadOffhandItem.of(handStack, hand, "iota.read") diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpReadable.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpReadable.kt index 8b4cee8524..d368b9d87b 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpReadable.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpReadable.kt @@ -17,9 +17,9 @@ object OpReadable : ConstMediaAction { val datumHolder = IXplatAbstractions.INSTANCE.findDataHolder(handStack) ?: return false.asActionResult + // If the datum contains no iota, return whether it has a default empty iota. datumHolder.readIota(env.world) - ?: datumHolder.emptyIota() - ?: return false.asActionResult + ?: return (datumHolder.emptyIota() != null).asActionResult return true.asActionResult } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpWrite.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpWrite.kt index 211f74a30f..d26a27b49a 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpWrite.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpWrite.kt @@ -20,17 +20,17 @@ object OpWrite : SpellAction { ): SpellAction.Result { val datum = args[0] - val (handStack, hand) = env.getHeldItemToOperateOn { + val (handStack) = env.getHeldItemToOperateOn { val datumHolder = IXplatAbstractions.INSTANCE.findDataHolder(it) datumHolder != null && datumHolder.writeIota(datum, true) - } ?: throw MishapBadOffhandItem.of(ItemStack.EMPTY.copy(), null, "iota.write") // TODO: hack + } ?: throw MishapBadOffhandItem.of(null, "iota.write") val datumHolder = IXplatAbstractions.INSTANCE.findDataHolder(handStack) - ?: throw MishapBadOffhandItem.of(handStack, hand, "iota.write") + ?: throw MishapBadOffhandItem.of(handStack, "iota.write") if (!datumHolder.writeIota(datum, true)) - throw MishapBadOffhandItem.of(handStack, hand, "iota.readonly", datum.display()) + throw MishapBadOffhandItem.of(handStack, "iota.readonly", datum.display()) val trueName = MishapOthersName.getTrueNameFromDatum(datum, env.castingEntity as? ServerPlayer) if (trueName != null) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemFocus.java b/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemFocus.java index 27c6a8c8ee..4a3cd6b631 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemFocus.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemFocus.java @@ -2,7 +2,6 @@ import at.petrak.hexcasting.api.casting.iota.Iota; import at.petrak.hexcasting.api.casting.iota.IotaType; -import at.petrak.hexcasting.api.casting.iota.NullIota; import at.petrak.hexcasting.api.item.IotaHolderItem; import at.petrak.hexcasting.api.item.VariantItem; import at.petrak.hexcasting.api.utils.NBTHelper; @@ -44,11 +43,6 @@ public String getDescriptionId(ItemStack stack) { return super.getDescriptionId(stack) + (NBTHelper.getBoolean(stack, TAG_SEALED) ? ".sealed" : ""); } - @Override - public @Nullable Iota emptyIota(ItemStack stack) { - return new NullIota(); - } - @Override public boolean canWrite(ItemStack stack, Iota datum) { return datum == null || !NBTHelper.getBoolean(stack, TAG_SEALED); diff --git a/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemSpellbook.java b/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemSpellbook.java index 2b2eb98d77..fc6b85854e 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemSpellbook.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemSpellbook.java @@ -2,7 +2,6 @@ import at.petrak.hexcasting.api.casting.iota.Iota; import at.petrak.hexcasting.api.casting.iota.IotaType; -import at.petrak.hexcasting.api.casting.iota.NullIota; import at.petrak.hexcasting.api.item.IotaHolderItem; import at.petrak.hexcasting.api.item.VariantItem; import at.petrak.hexcasting.api.utils.NBTHelper; @@ -129,12 +128,6 @@ CompoundTag readIotaTag(ItemStack stack) { } } - @Override - public @Nullable - Iota emptyIota(ItemStack stack) { - return new NullIota(); - } - @Override public boolean canWrite(ItemStack stack, Iota datum) { return datum == null || !isSealed(stack); From 17b8966a0a8d80ec841201bb4fbe68151a99c912 Mon Sep 17 00:00:00 2001 From: Talia-12 Date: Tue, 6 Feb 2024 16:23:26 +1000 Subject: [PATCH 04/14] Fixed #541, allow MediaHolderItems to specify their consumptionPriority. --- .../java/at/petrak/hexcasting/api/item/MediaHolderItem.java | 5 +++++ .../at/petrak/hexcasting/fabric/cc/adimpl/CCMediaHolder.java | 2 +- .../hexcasting/forge/cap/adimpl/CapItemMediaHolder.java | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Common/src/main/java/at/petrak/hexcasting/api/item/MediaHolderItem.java b/Common/src/main/java/at/petrak/hexcasting/api/item/MediaHolderItem.java index 51dad5b8ff..a4aa3cfc0a 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/item/MediaHolderItem.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/item/MediaHolderItem.java @@ -1,5 +1,6 @@ package at.petrak.hexcasting.api.item; +import at.petrak.hexcasting.api.addldata.ADMediaHolder; import net.minecraft.world.item.ItemStack; import org.jetbrains.annotations.ApiStatus; @@ -59,4 +60,8 @@ default long insertMedia(ItemStack stack, long amount, boolean simulate) { } return inserting; } + + default int getConsumptionPriority(ItemStack stack) { + return ADMediaHolder.BATTERY_PRIORITY; + } } diff --git a/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/adimpl/CCMediaHolder.java b/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/adimpl/CCMediaHolder.java index 539c5e5edd..b4ff6ed091 100644 --- a/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/adimpl/CCMediaHolder.java +++ b/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/adimpl/CCMediaHolder.java @@ -51,7 +51,7 @@ public boolean canProvide() { @Override public int getConsumptionPriority() { - return ADMediaHolder.BATTERY_PRIORITY; + return this.mediaHolder.getConsumptionPriority(this.stack); } @Override diff --git a/Forge/src/main/java/at/petrak/hexcasting/forge/cap/adimpl/CapItemMediaHolder.java b/Forge/src/main/java/at/petrak/hexcasting/forge/cap/adimpl/CapItemMediaHolder.java index b595891118..7f84f1d154 100644 --- a/Forge/src/main/java/at/petrak/hexcasting/forge/cap/adimpl/CapItemMediaHolder.java +++ b/Forge/src/main/java/at/petrak/hexcasting/forge/cap/adimpl/CapItemMediaHolder.java @@ -37,7 +37,7 @@ public boolean canProvide() { @Override public int getConsumptionPriority() { - return ADMediaHolder.BATTERY_PRIORITY; + return holder.getConsumptionPriority(stack); } @Override From 242c20dca3de257554d60bdd6041af48c549efb0 Mon Sep 17 00:00:00 2001 From: Talia-12 Date: Tue, 6 Feb 2024 16:34:44 +1000 Subject: [PATCH 05/14] Fixed #515 --- .../main/resources/assets/hexcasting/lang/en_us.flatten.json5 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Common/src/main/resources/assets/hexcasting/lang/en_us.flatten.json5 b/Common/src/main/resources/assets/hexcasting/lang/en_us.flatten.json5 index 7c3b965478..cd5888eda8 100644 --- a/Common/src/main/resources/assets/hexcasting/lang/en_us.flatten.json5 +++ b/Common/src/main/resources/assets/hexcasting/lang/en_us.flatten.json5 @@ -1145,7 +1145,7 @@ "hexcasting.crafting.desc": "$(italic)We have a saying in our field: \"Magic isn't\". It doesn't \"just work,\" it doesn't respond to your thoughts, you can't throw fireballs or create a roast dinner from thin air or turn a bunch of muggers into frogs and snails./$", - "phials.1": "I find it quite ... irritating, how Nature refuses to give me change for my work. If all I have on hand is $(l:items/amethyst)$(item)Charged Amethyst/$, even the tiniest $(l:patterns/basics#hexcasting:raycast)$(action)Archer's Purification/$ will consume the entire crystal, wasting the remaining _media.$(br2)Fortunately, it seems I've found a way to somewhat allay this problem.", + "phials.1": "I find it quite ... irritating, how Nature refuses to give me change for my work. If all I have on hand is $(l:items/amethyst)$(item)Charged Amethyst/$, even the tiniest $(l:patterns/basics#hexcasting:raycast)$(action)Archer's Distillation/$ will consume the entire crystal, wasting the remaining _media.$(br2)Fortunately, it seems I've found a way to somewhat allay this problem.", "phials.2": "I've found old scrolls describing a $(item)Glass Bottle/$ infused with _media. When casting _Hexes, my spells would then draw _media out of the phial. The liquid form of the _media would let me take exact change, so to speak; nothing would be wasted. It's quite like the internal battery of a $(l:items/hexcasting)$(item)Trinket/$, or similar; I can even $(l:patterns/spells/hexcasting#hexcasting:recharge)$(action)Recharge/$ them in the same manner.", "phials.3": "Unfortunately, the art of actually $(italic)making/$ the things seems to have been lost to time. I've found a $(l:patterns/great_spells/make_battery#hexcasting:craft/battery)$(thing)hint at the pattern used to craft it/$, but the technique is irritatingly elusive, and I can't seem to do it successfully. I suspect I will figure it out with study and practice, though. For now, I will simply deal with the wasted _media...$(br2)But I won't settle for it forever.", "phials.desc": "$(italic)Drink the milk./$", From 96598b80aeaaaa7518c0b37539018deae4a62bd0 Mon Sep 17 00:00:00 2001 From: Talia-12 Date: Tue, 6 Feb 2024 17:56:03 +1000 Subject: [PATCH 06/14] Mostly implement accepted solution for #545 (no reading from things with nothing in them), remove references to Hands in places where they aren't needed. --- .../api/casting/mishaps/MishapBadOffhandItem.kt | 6 +++--- .../petrak/hexcasting/api/item/IotaHolderItem.java | 2 +- .../hexcasting/common/casting/actions/rw/OpRead.kt | 14 ++++++++++---- .../common/casting/actions/rw/OpWrite.kt | 7 ++++++- .../common/casting/actions/spells/OpColorize.kt | 5 ++--- .../casting/actions/spells/OpCycleVariant.kt | 6 +++--- .../common/casting/actions/spells/OpErase.kt | 6 +++--- .../common/casting/actions/spells/OpMakeBattery.kt | 4 +--- .../casting/actions/spells/OpMakePackagedSpell.kt | 8 ++++---- .../common/casting/actions/spells/OpPlaceBlock.kt | 8 ++++---- .../common/casting/actions/spells/OpRecharge.kt | 5 ++--- 11 files changed, 39 insertions(+), 32 deletions(-) diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadOffhandItem.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadOffhandItem.kt index 2e7ad8df9d..7d1410a550 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadOffhandItem.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadOffhandItem.kt @@ -9,7 +9,7 @@ import net.minecraft.world.InteractionHand import net.minecraft.world.item.DyeColor import net.minecraft.world.item.ItemStack -class MishapBadOffhandItem(val item: ItemStack?, val hand: InteractionHand?, val wanted: Component) : Mishap() { +class MishapBadOffhandItem(val item: ItemStack?, val wanted: Component) : Mishap() { override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = dyeColor(DyeColor.BROWN) @@ -24,8 +24,8 @@ class MishapBadOffhandItem(val item: ItemStack?, val hand: InteractionHand?, val companion object { @JvmStatic - fun of(item: ItemStack?, hand: InteractionHand?, stub: String, vararg args: Any): MishapBadOffhandItem { - return MishapBadOffhandItem(item, hand, "hexcasting.mishap.bad_item.$stub".asTranslatedComponent(*args)) + fun of(item: ItemStack?, stub: String, vararg args: Any): MishapBadOffhandItem { + return MishapBadOffhandItem(item, "hexcasting.mishap.bad_item.$stub".asTranslatedComponent(*args)) } } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/item/IotaHolderItem.java b/Common/src/main/java/at/petrak/hexcasting/api/item/IotaHolderItem.java index c9cca3d607..cb58c3280a 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/item/IotaHolderItem.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/item/IotaHolderItem.java @@ -58,7 +58,7 @@ default Iota readIota(ItemStack stack, ServerLevel world) { */ @Nullable default Iota emptyIota(ItemStack stack) { - return new NullIota(); + return null; } default int getColor(ItemStack stack) { diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpRead.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpRead.kt index 4dd0e04dfc..51791b6d26 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpRead.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpRead.kt @@ -10,17 +10,23 @@ object OpRead : ConstMediaAction { override val argc = 0 override fun execute(args: List, env: CastingEnvironment): List { - val (handStack, hand) = env.getHeldItemToOperateOn { + val (handStack) = env.getHeldItemToOperateOn { val dataHolder = IXplatAbstractions.INSTANCE.findDataHolder(it) dataHolder != null && (dataHolder.readIota(env.world) != null || dataHolder.emptyIota() != null) - } ?: throw MishapBadOffhandItem.of(null, null, "iota.read") + } + // If there are no data holders that are readable, find a data holder that isn't readable + // so that the error message is more helpful. + ?: env.getHeldItemToOperateOn { + val dataHolder = IXplatAbstractions.INSTANCE.findDataHolder(it) + dataHolder != null + } ?: throw MishapBadOffhandItem.of(null, "iota.read") val datumHolder = IXplatAbstractions.INSTANCE.findDataHolder(handStack) - ?: throw MishapBadOffhandItem.of(handStack, hand, "iota.read") + ?: throw MishapBadOffhandItem.of(handStack, "iota.read") val datum = datumHolder.readIota(env.world) ?: datumHolder.emptyIota() - ?: throw MishapBadOffhandItem.of(handStack, hand, "iota.read") + ?: throw MishapBadOffhandItem.of(handStack, "iota.read") return listOf(datum) } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpWrite.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpWrite.kt index d26a27b49a..317dbc0453 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpWrite.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpWrite.kt @@ -9,7 +9,6 @@ import at.petrak.hexcasting.api.casting.mishaps.MishapBadOffhandItem import at.petrak.hexcasting.api.casting.mishaps.MishapOthersName import at.petrak.hexcasting.xplat.IXplatAbstractions import net.minecraft.server.level.ServerPlayer -import net.minecraft.world.item.ItemStack // we make this a spell cause imo it's a little ... anticlimactic for it to just make no noise object OpWrite : SpellAction { @@ -24,6 +23,12 @@ object OpWrite : SpellAction { val datumHolder = IXplatAbstractions.INSTANCE.findDataHolder(it) datumHolder != null && datumHolder.writeIota(datum, true) + } + // If there are no data holders that are writeable, find a data holder that isn't writeable + // so that the error message is more helpful. + ?: env.getHeldItemToOperateOn { + val dataHolder = IXplatAbstractions.INSTANCE.findDataHolder(it) + dataHolder != null } ?: throw MishapBadOffhandItem.of(null, "iota.write") val datumHolder = IXplatAbstractions.INSTANCE.findDataHolder(handStack) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpColorize.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpColorize.kt index d4cdff836b..ba4c407c4a 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpColorize.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpColorize.kt @@ -18,13 +18,12 @@ object OpColorize : SpellAction { args: List, env: CastingEnvironment ): SpellAction.Result { - val (handStack, hand) = env.getHeldItemToOperateOn(IXplatAbstractions.INSTANCE::isPigment) - ?: throw MishapBadOffhandItem.of(ItemStack.EMPTY, null, "colorizer") // TODO: hack + val (handStack) = env.getHeldItemToOperateOn(IXplatAbstractions.INSTANCE::isPigment) + ?: throw MishapBadOffhandItem.of(ItemStack.EMPTY, "colorizer") // TODO: hack if (!IXplatAbstractions.INSTANCE.isPigment(handStack)) { throw MishapBadOffhandItem.of( handStack, - hand, "colorizer" ) } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpCycleVariant.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpCycleVariant.kt index 557f29e27c..e49e6e70af 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpCycleVariant.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpCycleVariant.kt @@ -13,12 +13,12 @@ object OpCycleVariant : SpellAction { override val argc = 0 override fun execute(args: List, env: CastingEnvironment): SpellAction.Result { - val (handStack, hand) = env.getHeldItemToOperateOn { + val (handStack) = env.getHeldItemToOperateOn { IXplatAbstractions.INSTANCE.findVariantHolder(it) != null - } ?: throw MishapBadOffhandItem.of(ItemStack.EMPTY.copy(), null, "variant") // TODO: hack + } ?: throw MishapBadOffhandItem.of(ItemStack.EMPTY.copy(), "variant") // TODO: hack val variantHolder = IXplatAbstractions.INSTANCE.findVariantHolder(handStack) - ?: throw MishapBadOffhandItem.of(handStack, hand, "variant") + ?: throw MishapBadOffhandItem.of(handStack, "variant") return SpellAction.Result( Spell(variantHolder), diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpErase.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpErase.kt index f1c810ccfb..85fc913276 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpErase.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpErase.kt @@ -16,13 +16,13 @@ object OpErase : SpellAction { args: List, env: CastingEnvironment ): SpellAction.Result { - val (handStack, hand) = env.getHeldItemToOperateOn { + val (handStack) = env.getHeldItemToOperateOn { val hexHolder = IXplatAbstractions.INSTANCE.findHexHolder(it) val datumHolder = IXplatAbstractions.INSTANCE.findDataHolder(it) (hexHolder?.hasHex() == true) || (datumHolder?.writeIota(null, true) == true) - } ?: throw MishapBadOffhandItem.of(ItemStack.EMPTY.copy(), null, "eraseable") // TODO: hack + } ?: throw MishapBadOffhandItem.of(ItemStack.EMPTY.copy(), "eraseable") // TODO: hack val hexHolder = IXplatAbstractions.INSTANCE.findHexHolder(handStack) val datumHolder = IXplatAbstractions.INSTANCE.findDataHolder(handStack) @@ -30,7 +30,7 @@ object OpErase : SpellAction { if ((hexHolder?.hasHex() != true) && (datumHolder?.writeIota(null, true) != true) ) { - throw MishapBadOffhandItem.of(handStack, hand, "eraseable") + throw MishapBadOffhandItem.of(handStack, "eraseable") } return SpellAction.Result( diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpMakeBattery.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpMakeBattery.kt index 7b60cf4769..5e86b23504 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpMakeBattery.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpMakeBattery.kt @@ -29,19 +29,17 @@ object OpMakeBattery : SpellAction { val entity = args.getItemEntity(0, argc) val (handStack, hand) = env.getHeldItemToOperateOn { it.`is`(HexTags.Items.PHIAL_BASE) } - ?: throw MishapBadOffhandItem.of(ItemStack.EMPTY.copy(), null, "bottle") // TODO: hack + ?: throw MishapBadOffhandItem.of(ItemStack.EMPTY.copy(), "bottle") // TODO: hack if (!handStack.`is`(HexTags.Items.PHIAL_BASE)) { throw MishapBadOffhandItem.of( handStack, - hand, "bottle" ) } if (handStack.count != 1) { throw MishapBadOffhandItem.of( handStack, - hand, "only_one" ) } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpMakePackagedSpell.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpMakePackagedSpell.kt index 8101af64b7..2601a70696 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpMakePackagedSpell.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpMakePackagedSpell.kt @@ -28,17 +28,17 @@ class OpMakePackagedSpell(val itemType: T, val cost: Long) val entity = args.getItemEntity(0, argc) val patterns = args.getList(1, argc).toList() - val (handStack, hand) = env.getHeldItemToOperateOn { + val (handStack) = env.getHeldItemToOperateOn { val hexHolder = IXplatAbstractions.INSTANCE.findHexHolder(it) it.`is`(itemType) && hexHolder != null && !hexHolder.hasHex() } - ?: throw MishapBadOffhandItem(ItemStack.EMPTY.copy(), null, itemType.description) // TODO: hack + ?: throw MishapBadOffhandItem(ItemStack.EMPTY.copy(), itemType.description) // TODO: hack val hexHolder = IXplatAbstractions.INSTANCE.findHexHolder(handStack) if (!handStack.`is`(itemType)) { - throw MishapBadOffhandItem(handStack, hand, itemType.description) + throw MishapBadOffhandItem(handStack, itemType.description) } else if (hexHolder == null || hexHolder.hasHex()) { - throw MishapBadOffhandItem.of(handStack, hand, "iota.write") + throw MishapBadOffhandItem.of(handStack, "iota.write") } env.assertEntityInRange(entity) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpPlaceBlock.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpPlaceBlock.kt index dcbe77844a..e71a3df9bd 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpPlaceBlock.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpPlaceBlock.kt @@ -39,9 +39,9 @@ object OpPlaceBlock : SpellAction { Vec3.atCenterOf(pos), env.castingEntity?.direction ?: Direction.NORTH, pos, false ) val itemUseCtx = env - .getHeldItemToOperateOn { it.item is BlockItem } - ?.stack?.let { UseOnContext(env.world, env.castingEntity as? ServerPlayer, env.castingHand, it, blockHit) } - ?: throw MishapBadOffhandItem.of(ItemStack.EMPTY, env.castingHand, "placeable") + .queryForMatchingStack { it.item is BlockItem } + ?.let { UseOnContext(env.world, env.castingEntity as? ServerPlayer, env.castingHand, it, blockHit) } + ?: throw MishapBadOffhandItem.of(ItemStack.EMPTY, "placeable") val placeContext = BlockPlaceContext(itemUseCtx) val worldState = env.world.getBlockState(pos) @@ -64,7 +64,7 @@ object OpPlaceBlock : SpellAction { ) val bstate = env.world.getBlockState(pos) - val placeeStack = env.getHeldItemToOperateOn { it.item is BlockItem }?.stack + val placeeStack = env.queryForMatchingStack { it.item is BlockItem } if (placeeStack != null) { if (!IXplatAbstractions.INSTANCE.isPlacingAllowed(env.world, pos, placeeStack, caster as? ServerPlayer)) return diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpRecharge.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpRecharge.kt index 675dc4996f..0b7fcb6dfd 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpRecharge.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpRecharge.kt @@ -23,18 +23,17 @@ object OpRecharge : SpellAction { ): SpellAction.Result { val entity = args.getItemEntity(0, argc) - val (handStack, hand) = env.getHeldItemToOperateOn { + val (handStack) = env.getHeldItemToOperateOn { val media = IXplatAbstractions.INSTANCE.findMediaHolder(it) media != null && media.canRecharge() && media.insertMedia(-1, true) != 0L } - ?: throw MishapBadOffhandItem.of(ItemStack.EMPTY.copy(), null, "rechargable") // TODO: hack + ?: throw MishapBadOffhandItem.of(ItemStack.EMPTY.copy(), "rechargable") // TODO: hack val media = IXplatAbstractions.INSTANCE.findMediaHolder(handStack) if (media == null || !media.canRecharge()) throw MishapBadOffhandItem.of( handStack, - hand, "rechargable" ) From a18d9a42e3a1a333f576d3a245d36a2c4bb05818 Mon Sep 17 00:00:00 2001 From: Talia-12 Date: Tue, 6 Feb 2024 18:10:13 +1000 Subject: [PATCH 07/14] fix OpWritable for items that only accept specific types of iotas by adding a writeable() method to IotaHolderItem. --- .../petrak/hexcasting/api/addldata/ADIotaHolder.java | 5 +++++ .../api/addldata/ItemDelegatingEntityIotaHolder.java | 6 ++++++ .../at/petrak/hexcasting/api/item/IotaHolderItem.java | 6 +++++- .../hexcasting/common/casting/actions/rw/OpWritable.kt | 3 +-- .../hexcasting/common/items/storage/ItemAbacus.java | 5 +++++ .../hexcasting/common/items/storage/ItemFocus.java | 5 +++++ .../hexcasting/common/items/storage/ItemScroll.java | 5 +++++ .../hexcasting/common/items/storage/ItemSlate.java | 5 +++++ .../hexcasting/common/items/storage/ItemSpellbook.java | 5 +++++ .../common/items/storage/ItemThoughtKnot.java | 5 +++++ .../fabric/cc/adimpl/CCEntityIotaHolder.java | 5 +++++ .../hexcasting/fabric/cc/adimpl/CCItemIotaHolder.java | 10 ++++++++++ .../forge/cap/adimpl/CapEntityIotaHolder.java | 5 +++++ .../hexcasting/forge/cap/adimpl/CapItemIotaHolder.java | 5 +++++ .../forge/cap/adimpl/CapStaticIotaHolder.java | 5 +++++ 15 files changed, 77 insertions(+), 3 deletions(-) diff --git a/Common/src/main/java/at/petrak/hexcasting/api/addldata/ADIotaHolder.java b/Common/src/main/java/at/petrak/hexcasting/api/addldata/ADIotaHolder.java index 45e3e404f2..7b8fcc1c95 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/addldata/ADIotaHolder.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/addldata/ADIotaHolder.java @@ -29,4 +29,9 @@ default Iota emptyIota() { * @return if the writing succeeded/would succeed */ boolean writeIota(@Nullable Iota iota, boolean simulate); + + /** + * @return whether it is possible to write to this IotaHolder + */ + boolean writeable(); } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/addldata/ItemDelegatingEntityIotaHolder.java b/Common/src/main/java/at/petrak/hexcasting/api/addldata/ItemDelegatingEntityIotaHolder.java index 390ce0dc9f..5af67a99ab 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/addldata/ItemDelegatingEntityIotaHolder.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/addldata/ItemDelegatingEntityIotaHolder.java @@ -29,6 +29,12 @@ public ItemDelegatingEntityIotaHolder(Supplier stackSupplier, Consume return delegate == null ? null : delegate.readIotaTag(); } + @Override + public boolean writeable() { + var delegate = IXplatAbstractions.INSTANCE.findDataHolder(this.stackSupplier.get()); + return delegate != null && delegate.writeable(); + } + @Override public boolean writeIota(@Nullable Iota datum, boolean simulate) { var stacc = this.stackSupplier.get(); diff --git a/Common/src/main/java/at/petrak/hexcasting/api/item/IotaHolderItem.java b/Common/src/main/java/at/petrak/hexcasting/api/item/IotaHolderItem.java index cb58c3280a..c312383129 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/item/IotaHolderItem.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/item/IotaHolderItem.java @@ -2,7 +2,6 @@ import at.petrak.hexcasting.api.casting.iota.Iota; import at.petrak.hexcasting.api.casting.iota.IotaType; -import at.petrak.hexcasting.api.casting.iota.NullIota; import at.petrak.hexcasting.api.utils.HexUtils; import at.petrak.hexcasting.api.utils.NBTHelper; import at.petrak.hexcasting.client.ClientTickCounter; @@ -86,6 +85,11 @@ default int getColor(ItemStack stack) { return IotaType.getColor(tag); } + /** + * @return whether it is possible to write to this IotaHolder + */ + boolean writeable(ItemStack stack); + /** * Write {@code null} to indicate erasing */ diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpWritable.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpWritable.kt index 6912f7f692..f0a3d0da10 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpWritable.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpWritable.kt @@ -4,7 +4,6 @@ import at.petrak.hexcasting.api.casting.asActionResult import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota -import at.petrak.hexcasting.api.casting.iota.NullIota import at.petrak.hexcasting.xplat.IXplatAbstractions object OpWritable : ConstMediaAction { @@ -18,7 +17,7 @@ object OpWritable : ConstMediaAction { } ?: return false.asActionResult val datumHolder = IXplatAbstractions.INSTANCE.findDataHolder(handStack) ?: return false.asActionResult - val success = datumHolder.writeIota(NullIota(), true) + val success = datumHolder.writeable() return success.asActionResult } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemAbacus.java b/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemAbacus.java index 3ecb220bf0..ad8527581f 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemAbacus.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemAbacus.java @@ -33,6 +33,11 @@ CompoundTag readIotaTag(ItemStack stack) { return IotaType.serialize(datum); } + @Override + public boolean writeable(ItemStack stack) { + return false; + } + @Override public boolean canWrite(ItemStack stack, Iota datum) { return false; diff --git a/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemFocus.java b/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemFocus.java index 4a3cd6b631..bc3af022b1 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemFocus.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemFocus.java @@ -43,6 +43,11 @@ public String getDescriptionId(ItemStack stack) { return super.getDescriptionId(stack) + (NBTHelper.getBoolean(stack, TAG_SEALED) ? ".sealed" : ""); } + @Override + public boolean writeable(ItemStack stack) { + return !NBTHelper.getBoolean(stack, TAG_SEALED); + } + @Override public boolean canWrite(ItemStack stack, Iota datum) { return datum == null || !NBTHelper.getBoolean(stack, TAG_SEALED); diff --git a/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemScroll.java b/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemScroll.java index 4ed6093a46..96241ea367 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemScroll.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemScroll.java @@ -63,6 +63,11 @@ CompoundTag readIotaTag(ItemStack stack) { return out; } + @Override + public boolean writeable(ItemStack stack) { + return true; + } + @Override public boolean canWrite(ItemStack stack, Iota datum) { return datum instanceof PatternIota || datum == null; diff --git a/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemSlate.java b/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemSlate.java index 3821a83e99..6ad6f5b51b 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemSlate.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemSlate.java @@ -84,6 +84,11 @@ CompoundTag readIotaTag(ItemStack stack) { return out; } + @Override + public boolean writeable(ItemStack stack) { + return true; + } + @Override public boolean canWrite(ItemStack stack, Iota datum) { return datum instanceof PatternIota || datum == null; diff --git a/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemSpellbook.java b/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemSpellbook.java index fc6b85854e..b7521f7619 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemSpellbook.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemSpellbook.java @@ -128,6 +128,11 @@ CompoundTag readIotaTag(ItemStack stack) { } } + @Override + public boolean writeable(ItemStack stack) { + return !isSealed(stack); + } + @Override public boolean canWrite(ItemStack stack, Iota datum) { return datum == null || !isSealed(stack); diff --git a/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemThoughtKnot.java b/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemThoughtKnot.java index 518917b0b9..da1a2631fc 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemThoughtKnot.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemThoughtKnot.java @@ -32,6 +32,11 @@ public ItemThoughtKnot(Properties properties) { return NBTHelper.getCompound(stack, TAG_DATA); } + @Override + public boolean writeable(ItemStack stack) { + return !NBTHelper.contains(stack, TAG_DATA); + } + @Override public boolean canWrite(ItemStack stack, @Nullable Iota iota) { return iota != null && !NBTHelper.contains(stack, TAG_DATA); diff --git a/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/adimpl/CCEntityIotaHolder.java b/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/adimpl/CCEntityIotaHolder.java index ae794ad913..81998b9e69 100644 --- a/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/adimpl/CCEntityIotaHolder.java +++ b/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/adimpl/CCEntityIotaHolder.java @@ -31,6 +31,11 @@ public Wrapper(ItemDelegatingEntityIotaHolder inner) { return inner.readIotaTag(); } + @Override + public boolean writeable() { + return inner.writeable(); + } + @Override public boolean writeIota(@Nullable Iota iota, boolean simulate) { return inner.writeIota(iota, simulate); diff --git a/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/adimpl/CCItemIotaHolder.java b/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/adimpl/CCItemIotaHolder.java index c0f8993ff9..10e9566594 100644 --- a/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/adimpl/CCItemIotaHolder.java +++ b/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/adimpl/CCItemIotaHolder.java @@ -32,6 +32,11 @@ public ItemBased(ItemStack stack) { return this.iotaHolder.readIotaTag(this.stack); } + @Override + public boolean writeable() { + return this.iotaHolder.writeable(this.stack); + } + @Override public boolean writeIota(@Nullable Iota iota, boolean simulate) { var canWrite = this.iotaHolder.canWrite(this.stack, iota); @@ -59,6 +64,11 @@ public Static(ItemStack stack, Function provider) { return iota == null ? null : IotaType.serialize(iota); } + @Override + public boolean writeable() { + return false; + } + @Override public boolean writeIota(@Nullable Iota datum, boolean simulate) { return false; diff --git a/Forge/src/main/java/at/petrak/hexcasting/forge/cap/adimpl/CapEntityIotaHolder.java b/Forge/src/main/java/at/petrak/hexcasting/forge/cap/adimpl/CapEntityIotaHolder.java index 8ad61fd00a..a8623e6249 100644 --- a/Forge/src/main/java/at/petrak/hexcasting/forge/cap/adimpl/CapEntityIotaHolder.java +++ b/Forge/src/main/java/at/petrak/hexcasting/forge/cap/adimpl/CapEntityIotaHolder.java @@ -21,6 +21,11 @@ public Wrapper(ItemDelegatingEntityIotaHolder inner) { return inner.readIotaTag(); } + @Override + public boolean writeable() { + return inner.writeable(); + } + @Override public boolean writeIota(@Nullable Iota iota, boolean simulate) { return inner.writeIota(iota, simulate); diff --git a/Forge/src/main/java/at/petrak/hexcasting/forge/cap/adimpl/CapItemIotaHolder.java b/Forge/src/main/java/at/petrak/hexcasting/forge/cap/adimpl/CapItemIotaHolder.java index a1937c0ce3..29caaeb0d0 100644 --- a/Forge/src/main/java/at/petrak/hexcasting/forge/cap/adimpl/CapItemIotaHolder.java +++ b/Forge/src/main/java/at/petrak/hexcasting/forge/cap/adimpl/CapItemIotaHolder.java @@ -39,4 +39,9 @@ public boolean writeIota(@Nullable Iota iota, boolean simulate) { } return true; } + + @Override + public boolean writeable() { + return holder.writeable(stack); + } } diff --git a/Forge/src/main/java/at/petrak/hexcasting/forge/cap/adimpl/CapStaticIotaHolder.java b/Forge/src/main/java/at/petrak/hexcasting/forge/cap/adimpl/CapStaticIotaHolder.java index 1eb438a191..f94cd93455 100644 --- a/Forge/src/main/java/at/petrak/hexcasting/forge/cap/adimpl/CapStaticIotaHolder.java +++ b/Forge/src/main/java/at/petrak/hexcasting/forge/cap/adimpl/CapStaticIotaHolder.java @@ -26,6 +26,11 @@ Iota readIota(ServerLevel world) { return provider.apply(stack); } + @Override + public boolean writeable() { + return false; + } + @Override public boolean writeIota(@Nullable Iota iota, boolean simulate) { return false; From e73b2af3b99f9ef4638d09890db128b7819294e8 Mon Sep 17 00:00:00 2001 From: Talia-12 Date: Tue, 6 Feb 2024 20:11:01 +1000 Subject: [PATCH 08/14] refactor some unnecessary slowdown points found (repeatedly sending packets unnecessarily, getting names of patterns for every cast and only using if a mishap occurs) --- .../api/casting/eval/CastingEnvironment.java | 14 +++++++++ .../eval/CastingEnvironmentComponent.java | 8 +++++ .../api/casting/eval/env/StaffCastEnv.java | 29 +++++++++++++++---- .../api/casting/eval/vm/CastingVM.kt | 2 ++ .../api/casting/iota/PatternIota.java | 9 +++--- 5 files changed, 52 insertions(+), 10 deletions(-) diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastingEnvironment.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastingEnvironment.java index 00789ac469..d1b3122189 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastingEnvironment.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastingEnvironment.java @@ -2,6 +2,7 @@ import at.petrak.hexcasting.api.casting.ParticleSpray; import at.petrak.hexcasting.api.casting.PatternShapeMatch; +import at.petrak.hexcasting.api.casting.eval.vm.CastingImage; import at.petrak.hexcasting.api.casting.mishaps.Mishap; import at.petrak.hexcasting.api.casting.mishaps.MishapBadLocation; import at.petrak.hexcasting.api.casting.mishaps.MishapDisallowedSpell; @@ -66,6 +67,7 @@ public final void triggerCreateEvent() { protected Map, @NotNull CastingEnvironmentComponent> componentMap = new HashMap<>(); private final List postExecutions = new ArrayList<>(); + private final List postCasts = new ArrayList<>(); private final List extractMedias = new ArrayList<>(); private final List isVecInRanges = new ArrayList<>(); private final List hasEditPermissionsAts = new ArrayList<>(); @@ -111,6 +113,8 @@ public void addExtension(@NotNull T exte componentMap.put(extension.getKey(), extension); if (extension instanceof PostExecution postExecution) postExecutions.add(postExecution); + if (extension instanceof PostCast postCast) + postCasts.add(postCast); if (extension instanceof ExtractMedia extractMedia) extractMedias.add(extractMedia); if (extension instanceof IsVecInRange isVecInRange) @@ -126,6 +130,8 @@ public void removeExtension(@NotNull CastingEnvironmentComponent.Key key) { if (extension instanceof PostExecution postExecution) postExecutions.remove(postExecution); + if (extension instanceof PostCast postCast) + postCasts.remove(postCast); if (extension instanceof ExtractMedia extractMedia) extractMedias.remove(extractMedia); if (extension instanceof IsVecInRange isVecInRange) @@ -178,6 +184,14 @@ public void postExecution(CastResult result) { postExecutionComponent.onPostExecution(result); } + /** + * Do things after the whole cast is finished (i.e. every pattern to be executed has been executed). + */ + public void postCast(CastingImage image) { + for (var postCastComponent : postCasts) + postCastComponent.onPostCast(image); + } + public abstract Vec3 mishapSprayPos(); /** diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastingEnvironmentComponent.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastingEnvironmentComponent.java index fd8de3da7b..5cae9e9f41 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastingEnvironmentComponent.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastingEnvironmentComponent.java @@ -1,5 +1,6 @@ package at.petrak.hexcasting.api.casting.eval; +import at.petrak.hexcasting.api.casting.eval.vm.CastingImage; import net.minecraft.core.BlockPos; import net.minecraft.world.phys.Vec3; @@ -15,6 +16,13 @@ interface PostExecution extends CastingEnvironmentComponent { void onPostExecution(CastResult result); } + interface PostCast extends CastingEnvironmentComponent { + /** + * Do things after the whole cast is finished (i.e. every pattern to be executed has been executed). + */ + void onPostCast(CastingImage image); + } + interface ExtractMedia extends CastingEnvironmentComponent { /** * Receives the cost that is being extracted, should return the diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/StaffCastEnv.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/StaffCastEnv.java index 9b63ece8de..6fbfa7bcf6 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/StaffCastEnv.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/StaffCastEnv.java @@ -5,8 +5,10 @@ import at.petrak.hexcasting.api.casting.eval.CastResult; import at.petrak.hexcasting.api.casting.eval.ExecutionClientView; import at.petrak.hexcasting.api.casting.eval.ResolvedPattern; +import at.petrak.hexcasting.api.casting.eval.vm.CastingImage; import at.petrak.hexcasting.api.casting.iota.PatternIota; import at.petrak.hexcasting.api.casting.math.HexCoord; +import at.petrak.hexcasting.api.casting.math.HexPattern; import at.petrak.hexcasting.api.mod.HexStatistics; import at.petrak.hexcasting.api.pigment.FrozenPigment; import at.petrak.hexcasting.common.msgs.*; @@ -19,10 +21,14 @@ import java.util.HashSet; import java.util.List; +import java.util.Set; public class StaffCastEnv extends PlayerBasedCastEnv { private final InteractionHand castingHand; + private final Set castPatterns = new HashSet<>(); + private int soundsPlayed = 0; + public StaffCastEnv(ServerPlayer caster, InteractionHand castingHand) { super(caster, castingHand); @@ -35,22 +41,33 @@ public void postExecution(CastResult result) { super.postExecution(result); if (result.component1() instanceof PatternIota patternIota) { - var packet = new MsgNewSpiralPatternsS2C( - this.caster.getUUID(), List.of(patternIota.getPattern()), Integer.MAX_VALUE - ); - IXplatAbstractions.INSTANCE.sendPacketToPlayer(this.caster, packet); - IXplatAbstractions.INSTANCE.sendPacketTracking(this.caster, packet); + castPatterns.add(patternIota.getPattern()); } // we always want to play this sound one at a time var sound = result.getSound().sound(); - if (sound != null) { + if (soundsPlayed < 100 && sound != null) { // TODO: Make configurable var soundPos = this.caster.position(); this.world.playSound(null, soundPos.x, soundPos.y, soundPos.z, sound, SoundSource.PLAYERS, 1f, 1f); + soundsPlayed++; } } + @Override + public void postCast(CastingImage image) { + super.postCast(image); + + var packet = new MsgNewSpiralPatternsS2C( + this.caster.getUUID(), castPatterns.stream().toList(), Integer.MAX_VALUE + ); + IXplatAbstractions.INSTANCE.sendPacketToPlayer(this.caster, packet); + IXplatAbstractions.INSTANCE.sendPacketTracking(this.caster, packet); + + castPatterns.clear(); + soundsPlayed = 0; + } + @Override public long extractMediaEnvironment(long cost) { if (this.caster.isCreative()) diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/CastingVM.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/CastingVM.kt index d2cdfbdb04..dbbc4865a9 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/CastingVM.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/CastingVM.kt @@ -71,6 +71,8 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) { val (stackDescs, ravenmind) = generateDescs() val isStackClear = image.stack.isEmpty() && image.parenCount == 0 && !image.escapeNext && ravenmind == null + + this.env.postCast(image) return ExecutionClientView(isStackClear, lastResolutionType, stackDescs, ravenmind) } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/PatternIota.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/PatternIota.java index 6a3ec539d1..3cde42fc4b 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/PatternIota.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/PatternIota.java @@ -32,6 +32,7 @@ import java.util.List; import java.util.Objects; +import java.util.function.Supplier; import static at.petrak.hexcasting.api.utils.HexUtils.isOfTag; @@ -67,7 +68,7 @@ public boolean toleratesOther(Iota that) { @Override public @NotNull CastResult execute(CastingVM vm, ServerLevel world, SpellContinuation continuation) { - @Nullable Component castedName = null; + Supplier<@Nullable Component> castedName = () -> null; try { var lookup = PatternRegistryManifest.matchPattern(this.getPattern(), vm.getEnv(), false); vm.getEnv().precheckAction(lookup); @@ -85,7 +86,7 @@ public boolean toleratesOther(Iota that) { var reqsEnlightenment = isOfTag(IXplatAbstractions.INSTANCE.getActionRegistry(), key, HexTags.Actions.REQUIRES_ENLIGHTENMENT); - castedName = HexAPI.instance().getActionI18n(key, reqsEnlightenment); + castedName = () -> HexAPI.instance().getActionI18n(key, reqsEnlightenment); action = Objects.requireNonNull(IXplatAbstractions.INSTANCE.getActionRegistry().get(key)).action(); if (reqsEnlightenment && !vm.getEnv().isEnlightened()) { @@ -93,7 +94,7 @@ public boolean toleratesOther(Iota that) { throw new MishapUnenlightened(); } } else if (lookup instanceof PatternShapeMatch.Special special) { - castedName = special.handler.getName(); + castedName = special.handler::getName; action = special.handler.act(); } else if (lookup instanceof PatternShapeMatch.Nothing) { throw new MishapInvalidPattern(); @@ -127,7 +128,7 @@ public boolean toleratesOther(Iota that) { this, continuation, null, - List.of(new OperatorSideEffect.DoMishap(mishap, new Mishap.Context(this.getPattern(), castedName))), + List.of(new OperatorSideEffect.DoMishap(mishap, new Mishap.Context(this.getPattern(), castedName.get()))), mishap.resolutionType(vm.getEnv()), HexEvalSounds.MISHAP); } From 58cb3b77566244d104924dcc38a411055168830e Mon Sep 17 00:00:00 2001 From: Talia-12 Date: Tue, 6 Feb 2024 20:57:03 +1000 Subject: [PATCH 09/14] refactor moar, increase the default max op count since it is now fast enough for that to be fine. --- .../hexcasting/api/casting/eval/vm/CastingVM.kt | 16 ++++++++-------- .../hexcasting/api/casting/iota/PatternIota.java | 2 +- .../hexcasting/api/casting/math/HexPattern.kt | 4 ++-- .../at/petrak/hexcasting/api/mod/HexConfig.java | 2 +- .../common/casting/PatternRegistryManifest.java | 15 +++++++++++---- 5 files changed, 23 insertions(+), 16 deletions(-) diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/CastingVM.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/CastingVM.kt index dbbc4865a9..5ff591bf8d 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/CastingVM.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/CastingVM.kt @@ -158,7 +158,7 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) { */ @Throws(MishapTooManyCloseParens::class) private fun handleParentheses(iota: Iota): Pair? { - val sig = (iota as? PatternIota)?.pattern?.anglesSignature() + val sig = (iota as? PatternIota)?.pattern?.angles var displayDepth = this.image.parenCount @@ -173,13 +173,13 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) { } else { when (sig) { - SpecialPatterns.CONSIDERATION.anglesSignature() -> { + SpecialPatterns.CONSIDERATION.angles -> { this.image.copy( escapeNext = true, ) to ResolvedPatternType.EVALUATED } - SpecialPatterns.EVANITION.anglesSignature() -> { + SpecialPatterns.EVANITION.angles -> { val newParens = this.image.parenthesized.toMutableList() val last = newParens.removeLastOrNull() val newParenCount = this.image.parenCount + if (last == null || last.escaped || last.iota !is PatternIota) 0 else when (last.iota.pattern) { @@ -190,7 +190,7 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) { this.image.copy(parenthesized = newParens, parenCount = newParenCount) to if (last == null) ResolvedPatternType.ERRORED else ResolvedPatternType.UNDONE } - SpecialPatterns.INTROSPECTION.anglesSignature() -> { + SpecialPatterns.INTROSPECTION.angles -> { // we have escaped the parens onto the stack; we just also record our count. val newParens = this.image.parenthesized.toMutableList() newParens.add(ParenthesizedIota(iota, false)) @@ -200,7 +200,7 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) { ) to if (this.image.parenCount == 0) ResolvedPatternType.EVALUATED else ResolvedPatternType.ESCAPED } - SpecialPatterns.RETROSPECTION.anglesSignature() -> { + SpecialPatterns.RETROSPECTION.angles -> { val newParenCount = this.image.parenCount - 1 displayDepth-- if (newParenCount == 0) { @@ -243,19 +243,19 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) { ) to ResolvedPatternType.ESCAPED } else { when (sig) { - SpecialPatterns.CONSIDERATION.anglesSignature() -> { + SpecialPatterns.CONSIDERATION.angles -> { this.image.copy( escapeNext = true ) to ResolvedPatternType.EVALUATED } - SpecialPatterns.INTROSPECTION.anglesSignature() -> { + SpecialPatterns.INTROSPECTION.angles -> { this.image.copy( parenCount = this.image.parenCount + 1 ) to ResolvedPatternType.EVALUATED } - SpecialPatterns.RETROSPECTION.anglesSignature() -> { + SpecialPatterns.RETROSPECTION.angles -> { throw MishapTooManyCloseParens() } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/PatternIota.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/PatternIota.java index 3cde42fc4b..6b52868ad6 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/PatternIota.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/PatternIota.java @@ -58,7 +58,7 @@ public boolean isTruthy() { public boolean toleratesOther(Iota that) { return typesMatch(this, that) && that instanceof PatternIota piota - && this.getPattern().anglesSignature().equals(piota.getPattern().anglesSignature()); + && this.getPattern().getAngles().equals(piota.getPattern().getAngles()); } @Override diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexPattern.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexPattern.kt index 096d0340df..6b6c587ea0 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexPattern.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexPattern.kt @@ -11,7 +11,7 @@ import net.minecraft.world.phys.Vec2 /** * Sequence of angles to define a pattern traced. */ -data class HexPattern(public val startDir: HexDir, public val angles: MutableList = arrayListOf()) { +data class HexPattern(val startDir: HexDir, val angles: MutableList = arrayListOf()) { /** * @return True if it successfully appended, false if not. */ @@ -113,7 +113,7 @@ data class HexPattern(public val startDir: HexDir, public val angles: MutableLis fun toLines(hexSize: Float, origin: Vec2): List = this.positions().map { coordToPx(it, hexSize, origin) } - fun sigsEqual(that: HexPattern) = this.anglesSignature() == that.anglesSignature() + fun sigsEqual(that: HexPattern) = this.angles == that.angles override fun toString(): String = buildString { append("HexPattern[") diff --git a/Common/src/main/java/at/petrak/hexcasting/api/mod/HexConfig.java b/Common/src/main/java/at/petrak/hexcasting/api/mod/HexConfig.java index be86acef10..c7a56ff432 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/mod/HexConfig.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/mod/HexConfig.java @@ -69,7 +69,7 @@ public interface ServerConfigAccess { // fun fact, although dimension keys are a RegistryHolder, they aren't a registry, so i can't do tags boolean canTeleportInThisDimension(ResourceKey dimension); - int DEFAULT_MAX_OP_COUNT = 1_000_000; + int DEFAULT_MAX_OP_COUNT = 2_000_000; int DEFAULT_MAX_SPELL_CIRCLE_LENGTH = 1024; int DEFAULT_OP_BREAK_HARVEST_LEVEL = 3; diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/PatternRegistryManifest.java b/Common/src/main/java/at/petrak/hexcasting/common/casting/PatternRegistryManifest.java index c2a8122de3..c15ad6488f 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/PatternRegistryManifest.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/PatternRegistryManifest.java @@ -5,6 +5,7 @@ import at.petrak.hexcasting.api.casting.PatternShapeMatch; import at.petrak.hexcasting.api.casting.castables.SpecialHandler; import at.petrak.hexcasting.api.casting.eval.CastingEnvironment; +import at.petrak.hexcasting.api.casting.math.HexAngle; import at.petrak.hexcasting.api.casting.math.HexPattern; import at.petrak.hexcasting.api.mod.HexTags; import at.petrak.hexcasting.api.utils.HexUtils; @@ -16,12 +17,13 @@ import org.apache.commons.lang3.NotImplementedException; import org.jetbrains.annotations.Nullable; +import java.util.List; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; // Now an internal-only class used to do final processing on the registered stuff public class PatternRegistryManifest { - private static final ConcurrentMap> NORMAL_ACTION_LOOKUP = + private static final ConcurrentMap, ResourceKey> NORMAL_ACTION_LOOKUP = new ConcurrentHashMap<>(); /** @@ -42,8 +44,11 @@ public static void processRegistry(@Nullable ServerLevel overworld) { var registry = IXplatAbstractions.INSTANCE.getActionRegistry(); for (var key : registry.registryKeySet()) { var entry = registry.get(key); + if (entry == null) + continue; + if (!HexUtils.isOfTag(registry, key, HexTags.Actions.PER_WORLD_PATTERN)) { - NORMAL_ACTION_LOOKUP.put(entry.prototype().anglesSignature(), key); + NORMAL_ACTION_LOOKUP.put(entry.prototype().getAngles(), key); } else { perWorldActionCount++; } @@ -64,6 +69,8 @@ public static Pair>> match var registry = IXplatAbstractions.INSTANCE.getSpecialHandlerRegistry(); for (var key : registry.registryKeySet()) { var factory = registry.get(key); + if (factory == null) + continue; var handler = factory.tryMatch(pat,environment); if (handler != null) { return Pair.of(handler, key); @@ -84,7 +91,7 @@ public static PatternShapeMatch matchPattern(HexPattern pat, CastingEnvironment boolean checkForAlternateStrokeOrders) { // I am PURPOSELY checking normal actions before special handlers // This way we don't get a repeat of the phial number literal incident - var sig = pat.anglesSignature(); + var sig = pat.getAngles(); if (NORMAL_ACTION_LOOKUP.containsKey(sig)) { var key = NORMAL_ACTION_LOOKUP.get(sig); return new PatternShapeMatch.Normal(key); @@ -92,7 +99,7 @@ public static PatternShapeMatch matchPattern(HexPattern pat, CastingEnvironment // Look it up in the world? var perWorldPatterns = ScrungledPatternsSave.open(environment.getWorld().getServer().overworld()); - var entry = perWorldPatterns.lookup(sig); + var entry = perWorldPatterns.lookup(pat.anglesSignature()); if (entry != null) { return new PatternShapeMatch.PerWorld(entry.key(), true); } From 7ac3d0d0ce203e5c79aa02b58a35a08a7bc2d657 Mon Sep 17 00:00:00 2001 From: Talia-12 Date: Tue, 6 Feb 2024 21:24:41 +1000 Subject: [PATCH 10/14] Fix #608, advancements based on amount of media spent no longer triggering. --- .../api/advancements/MinMaxLongs.java | 85 +++++++++++++++++++ .../api/advancements/SpendMediaTrigger.java | 16 ++-- .../casting/eval/env/PlayerBasedCastEnv.java | 5 ++ .../hexcasting/datagen/HexAdvancements.java | 9 +- 4 files changed, 103 insertions(+), 12 deletions(-) create mode 100644 Common/src/main/java/at/petrak/hexcasting/api/advancements/MinMaxLongs.java diff --git a/Common/src/main/java/at/petrak/hexcasting/api/advancements/MinMaxLongs.java b/Common/src/main/java/at/petrak/hexcasting/api/advancements/MinMaxLongs.java new file mode 100644 index 0000000000..0be502c86e --- /dev/null +++ b/Common/src/main/java/at/petrak/hexcasting/api/advancements/MinMaxLongs.java @@ -0,0 +1,85 @@ +package at.petrak.hexcasting.api.advancements; + +import com.google.gson.JsonElement; +import com.mojang.brigadier.StringReader; +import com.mojang.brigadier.exceptions.BuiltInExceptionProvider; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import net.minecraft.advancements.critereon.MinMaxBounds; +import net.minecraft.util.GsonHelper; + +import javax.annotation.Nullable; +import java.util.Objects; +import java.util.function.Function; + +public class MinMaxLongs extends MinMaxBounds { + public static final MinMaxLongs ANY = new MinMaxLongs(null, null); + @Nullable + private final Long minSq; + @Nullable + private final Long maxSq; + + private static MinMaxLongs create(StringReader reader, @Nullable Long min, @Nullable Long max) throws CommandSyntaxException { + if (min != null && max != null && min > max) { + throw ERROR_SWAPPED.createWithContext(reader); + } else { + return new MinMaxLongs(min, max); + } + } + + @Nullable + private static Long squareOpt(@Nullable Long l) { + return l == null ? null : l * l; + } + + private MinMaxLongs(@Nullable Long min, @Nullable Long max) { + super(min, max); + this.minSq = squareOpt(min); + this.maxSq = squareOpt(max); + } + + public static MinMaxLongs exactly(long l) { + return new MinMaxLongs(l, l); + } + + public static MinMaxLongs between(long min, long max) { + return new MinMaxLongs(min, max); + } + + public static MinMaxLongs atLeast(long min) { + return new MinMaxLongs(min, null); + } + + public static MinMaxLongs atMost(long max) { + return new MinMaxLongs(null, max); + } + + public boolean matches(long l) { + if (this.min != null && this.min > l) { + return false; + } else { + return this.max == null || this.max >= l; + } + } + + public boolean matchesSqr(long l) { + if (this.minSq != null && this.minSq > l) { + return false; + } else { + return this.maxSq == null || this.maxSq >= l; + } + } + + public static MinMaxLongs fromJson(@Nullable JsonElement json) { + return fromJson(json, ANY, GsonHelper::convertToLong, MinMaxLongs::new); + } + + public static MinMaxLongs fromReader(StringReader reader) throws CommandSyntaxException { + return fromReader(reader, (l) -> l); + } + + public static MinMaxLongs fromReader(StringReader reader, Function map) throws CommandSyntaxException { + BuiltInExceptionProvider builtInExceptions = CommandSyntaxException.BUILT_IN_EXCEPTIONS; + Objects.requireNonNull(builtInExceptions); + return fromReader(reader, MinMaxLongs::create, Long::parseLong, builtInExceptions::readerInvalidInt, map); + } +} diff --git a/Common/src/main/java/at/petrak/hexcasting/api/advancements/SpendMediaTrigger.java b/Common/src/main/java/at/petrak/hexcasting/api/advancements/SpendMediaTrigger.java index aa12d472cf..d610807f59 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/advancements/SpendMediaTrigger.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/advancements/SpendMediaTrigger.java @@ -20,20 +20,20 @@ public ResourceLocation getId() { protected Instance createInstance(JsonObject json, ContextAwarePredicate predicate, DeserializationContext context) { return new Instance(predicate, - MinMaxBounds.Ints.fromJson(json.get(TAG_MEDIA_SPENT)), - MinMaxBounds.Ints.fromJson(json.get(TAG_MEDIA_WASTED))); + MinMaxLongs.fromJson(json.get(TAG_MEDIA_SPENT)), + MinMaxLongs.fromJson(json.get(TAG_MEDIA_WASTED))); } - public void trigger(ServerPlayer player, int mediaSpent, int mediaWasted) { + public void trigger(ServerPlayer player, long mediaSpent, long mediaWasted) { super.trigger(player, inst -> inst.test(mediaSpent, mediaWasted)); } public static class Instance extends AbstractCriterionTriggerInstance { - protected final MinMaxBounds.Ints mediaSpent; - protected final MinMaxBounds.Ints mediaWasted; + protected final MinMaxLongs mediaSpent; + protected final MinMaxLongs mediaWasted; - public Instance(ContextAwarePredicate predicate, MinMaxBounds.Ints mediaSpent, - MinMaxBounds.Ints mediaWasted) { + public Instance(ContextAwarePredicate predicate, MinMaxLongs mediaSpent, + MinMaxLongs mediaWasted) { super(SpendMediaTrigger.ID, predicate); this.mediaSpent = mediaSpent; this.mediaWasted = mediaWasted; @@ -56,7 +56,7 @@ public JsonObject serializeToJson(SerializationContext ctx) { return json; } - private boolean test(int mediaSpentIn, int mediaWastedIn) { + private boolean test(long mediaSpentIn, long mediaWastedIn) { return this.mediaSpent.matches(mediaSpentIn) && this.mediaWasted.matches(mediaWastedIn); } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PlayerBasedCastEnv.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PlayerBasedCastEnv.java index 9932ba7b3c..c137930071 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PlayerBasedCastEnv.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PlayerBasedCastEnv.java @@ -223,6 +223,11 @@ protected long extractMediaFromInventory(long costLeft, boolean allowOvercast) { } this.caster.awardStat(HexStatistics.MEDIA_USED, (int) (startCost - costLeft)); + HexAdvancementTriggers.SPEND_MEDIA_TRIGGER.trigger( + this.caster, + startCost - costLeft, + costLeft < 0 ? -costLeft : 0 + ); return costLeft; } diff --git a/Common/src/main/java/at/petrak/hexcasting/datagen/HexAdvancements.java b/Common/src/main/java/at/petrak/hexcasting/datagen/HexAdvancements.java index 19956a7db8..28012e0da5 100644 --- a/Common/src/main/java/at/petrak/hexcasting/datagen/HexAdvancements.java +++ b/Common/src/main/java/at/petrak/hexcasting/datagen/HexAdvancements.java @@ -2,6 +2,7 @@ import at.petrak.hexcasting.api.HexAPI; import at.petrak.hexcasting.api.advancements.FailToCastGreatSpellTrigger; +import at.petrak.hexcasting.api.advancements.MinMaxLongs; import at.petrak.hexcasting.api.advancements.OvercastTrigger; import at.petrak.hexcasting.api.advancements.SpendMediaTrigger; import at.petrak.hexcasting.api.misc.MediaConstants; @@ -57,15 +58,15 @@ public void generate(HolderLookup.Provider provider, Consumer consu .display(simpleDisplay(Items.GLISTERING_MELON_SLICE, "wasteful_cast", FrameType.TASK)) .parent(root) .addCriterion("waste_amt", new SpendMediaTrigger.Instance(ContextAwarePredicate.ANY, - MinMaxBounds.Ints.ANY, - MinMaxBounds.Ints.atLeast((int) (89 * MediaConstants.DUST_UNIT / 10)))) + MinMaxLongs.ANY, + MinMaxLongs.atLeast(89 * MediaConstants.DUST_UNIT / 10))) .save(consumer, prefix("aaa_wasteful_cast")); Advancement.Builder.advancement() .display(simpleDisplay(HexItems.CHARGED_AMETHYST, "big_cast", FrameType.TASK)) .parent(root) .addCriterion("cast_amt", new SpendMediaTrigger.Instance(ContextAwarePredicate.ANY, - MinMaxBounds.Ints.atLeast((int) (64 * MediaConstants.CRYSTAL_UNIT)), - MinMaxBounds.Ints.ANY)) + MinMaxLongs.atLeast(64 * MediaConstants.CRYSTAL_UNIT), + MinMaxLongs.ANY)) .save(consumer, prefix("aab_big_cast")); var impotence = Advancement.Builder.advancement() From 2e9172950a531c1b870777f3ea5549637745f217 Mon Sep 17 00:00:00 2001 From: Talia-12 Date: Thu, 8 Feb 2024 23:51:35 +1000 Subject: [PATCH 11/14] turns out there's still a bunch of lag with a loop that actually does things --- .../src/main/java/at/petrak/hexcasting/api/mod/HexConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Common/src/main/java/at/petrak/hexcasting/api/mod/HexConfig.java b/Common/src/main/java/at/petrak/hexcasting/api/mod/HexConfig.java index c7a56ff432..be86acef10 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/mod/HexConfig.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/mod/HexConfig.java @@ -69,7 +69,7 @@ public interface ServerConfigAccess { // fun fact, although dimension keys are a RegistryHolder, they aren't a registry, so i can't do tags boolean canTeleportInThisDimension(ResourceKey dimension); - int DEFAULT_MAX_OP_COUNT = 2_000_000; + int DEFAULT_MAX_OP_COUNT = 1_000_000; int DEFAULT_MAX_SPELL_CIRCLE_LENGTH = 1024; int DEFAULT_OP_BREAK_HARVEST_LEVEL = 3; From f670ad566fbc1ae80d6606ce68678addefb6d3ce Mon Sep 17 00:00:00 2001 From: SamsTheNerd Date: Fri, 2 Aug 2024 12:24:07 -0400 Subject: [PATCH 12/14] make focus and thought knot re-use some writeable checks --- .../at/petrak/hexcasting/common/items/storage/ItemFocus.java | 2 +- .../petrak/hexcasting/common/items/storage/ItemThoughtKnot.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemFocus.java b/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemFocus.java index bc3af022b1..424eccadc3 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemFocus.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemFocus.java @@ -50,7 +50,7 @@ public boolean writeable(ItemStack stack) { @Override public boolean canWrite(ItemStack stack, Iota datum) { - return datum == null || !NBTHelper.getBoolean(stack, TAG_SEALED); + return datum == null || !isSealed(stack); } @Override diff --git a/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemThoughtKnot.java b/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemThoughtKnot.java index da1a2631fc..9e867cc250 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemThoughtKnot.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemThoughtKnot.java @@ -39,7 +39,7 @@ public boolean writeable(ItemStack stack) { @Override public boolean canWrite(ItemStack stack, @Nullable Iota iota) { - return iota != null && !NBTHelper.contains(stack, TAG_DATA); + return iota != null && writeable(stack); } @Override From ffcc37df4441199a573876ae86c221a92d18f9ef Mon Sep 17 00:00:00 2001 From: SamsTheNerd Date: Fri, 2 Aug 2024 12:25:56 -0400 Subject: [PATCH 13/14] switch power_neg to exponent. translation is close enough imo? --- .../hexcasting/common/casting/arithmetic/DoubleArithmetic.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/DoubleArithmetic.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/DoubleArithmetic.kt index a111f9958d..07da240b2a 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/DoubleArithmetic.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/DoubleArithmetic.kt @@ -57,7 +57,7 @@ object DoubleArithmetic : Arithmetic { MUL -> make2 { a, b -> a * b } DIV -> make2 { a, b -> if (b == 0.0) throw MishapDivideByZero.of(a, b) else a / b } ABS -> make1 { a -> abs(a) } - POW -> make2 { a, b -> if (a < 0 && !DoubleIota.tolerates(floor(b), b)) throw MishapDivideByZero.of(a, b, "power_neg") else a.pow(b) } + POW -> make2 { a, b -> if (a < 0 && !DoubleIota.tolerates(floor(b), b)) throw MishapDivideByZero.of(a, b, "exponent") else a.pow(b) } FLOOR -> make1 { a -> floor(a) } CEIL -> make1 { a -> ceil(a) } SIN -> make1 { a -> sin(a) } From 5f7410fc3d007bb9a52f07b4fb93c8615c1f2f28 Mon Sep 17 00:00:00 2001 From: "[object Object]" Date: Mon, 12 Aug 2024 17:18:57 -0400 Subject: [PATCH 14/14] Add comments and refactor some code to improve clarity --- .../hexcasting/api/casting/mishaps/MishapBadOffhandItem.kt | 6 +++--- .../common/casting/arithmetic/DoubleArithmetic.kt | 1 + .../petrak/hexcasting/common/items/storage/ItemFocus.java | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadOffhandItem.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadOffhandItem.kt index 7d1410a550..d35104dab4 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadOffhandItem.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadOffhandItem.kt @@ -17,10 +17,10 @@ class MishapBadOffhandItem(val item: ItemStack?, val wanted: Component) : Mishap env.mishapEnvironment.dropHeldItems() } - override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = if (item?.isEmpty != false) - error("no_item.offhand", wanted) - else + override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = if (item?.isEmpty == false) error("bad_item.offhand", wanted, item.count, item.displayName) + else + error("no_item.offhand", wanted) companion object { @JvmStatic diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/DoubleArithmetic.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/DoubleArithmetic.kt index 07da240b2a..075a17a76f 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/DoubleArithmetic.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/DoubleArithmetic.kt @@ -57,6 +57,7 @@ object DoubleArithmetic : Arithmetic { MUL -> make2 { a, b -> a * b } DIV -> make2 { a, b -> if (b == 0.0) throw MishapDivideByZero.of(a, b) else a / b } ABS -> make1 { a -> abs(a) } + // throw MishapDivideByZero if raising a negative number to a fractional power (ie. sqrt(-1) etc) POW -> make2 { a, b -> if (a < 0 && !DoubleIota.tolerates(floor(b), b)) throw MishapDivideByZero.of(a, b, "exponent") else a.pow(b) } FLOOR -> make1 { a -> floor(a) } CEIL -> make1 { a -> ceil(a) } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemFocus.java b/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemFocus.java index 424eccadc3..8d08c9923f 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemFocus.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemFocus.java @@ -45,7 +45,7 @@ public String getDescriptionId(ItemStack stack) { @Override public boolean writeable(ItemStack stack) { - return !NBTHelper.getBoolean(stack, TAG_SEALED); + return !isSealed(stack); } @Override