From d71f3900583a7073128488fa3933487d8c60cd6e Mon Sep 17 00:00:00 2001 From: Robotgiggle <88736742+Robotgiggle@users.noreply.github.com> Date: Sat, 7 Mar 2026 01:10:13 -0500 Subject: [PATCH 1/7] Correct thoth book entry (pattern -> pattern-list) --- .../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 5a0087c10..45274994a 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 @@ -1974,7 +1974,7 @@ "eval.1": "Remove a pattern or list of patterns from the stack, then cast them as if I had drawn them myself with my $(l:items/staff)$(item)Staff/$ (until a $(l:patterns/meta#hexcasting:halt)$(action)Charon's Gambit/$ is encountered). If an iota is escaped with $(l:patterns/patterns_as_iotas#hexcasting:escape)$(action)Consideration/$ or $(l:patterns/patterns_as_iotas#hexcasting:open_paren)$(action)its ilk/$, it will be pushed to the stack. Otherwise, non-patterns will fail.", "eval.2": "This can be $(italic)very/$ powerful in tandem with $(l:items/focus)$(item)Foci/$.$(br2)It also makes the bureaucracy of Nature a \"Turing-complete\" system, according to one esoteric scroll I found.$(br2)However, it seems there's a limit to how many times a _Hex can cast itself-- Nature doesn't look kindly on runaway spells!$(br2)In addition, with the energies of the patterns occurring without me to guide them, any mishap will cause the remaining actions to become too unstable and immediately unravel.", - "for_each.1": "Remove a list of patterns and a list from the stack, then cast the given pattern over each element of the second list.", + "for_each.1": "Remove a list of patterns and a list from the stack, then cast the given pattern-list over each element of the second list.", "for_each.2": "More specifically, for each element in the second list, it will:$(li)Create a new stack, with everything on the current stack plus that element$(li)Draw all the patterns in the first list$(li)Save all the iotas remaining on the stack to a list$(br)Then, after all is said and done, pushes the list of saved iotas onto the main stack.$(br2)No wonder all the practitioners of this art go mad.", "halt.1": "This pattern forcibly halts a _Hex. This is mostly useless on its own, as I could simply just stop writing patterns, or put down my staff.", From e21f58a3ebb45c49b7aa23097d48fb250d201519 Mon Sep 17 00:00:00 2001 From: Robotgiggle <88736742+Robotgiggle@users.noreply.github.com> Date: Sat, 7 Mar 2026 01:13:06 -0500 Subject: [PATCH 2/7] Describe correct size limit for akashic library --- .../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 45274994a..ed57ff95f 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 @@ -1706,7 +1706,7 @@ akashiclib: { "1": "I KNOW SO MUCH it is ONLY RIGHT to have a place to store it all. Information can be stored in books but it is oh so so so so $(italic)slow/$ to write by hand and read by eye. I demand BETTER. And so I shall MAKE better.$(br2)... I am getting worse ... do not know if I have time to write everything bursting through my head before expiring.", - "2": "The library. Here. My plans.$(br2)Like how patterns are associated with actions, I can associate my own patterns with iotas in any way I choose. An $(l:greatwork/akashiclib)$(item)Akashic Record/$ controls the library, and each $(l:greatwork/akashiclib)$(item)Akashic Bookshelf/$ stores one pattern mapped to one iota. These must all be directly connected together, touching, within 32 blocks. An $(l:greatwork/akashiclib)$(item)Akashic Ligature/$ doesn't do anything but count as a connecting block, to extend the size of my library.", + "2": "The library. Here. My plans.$(br2)Like how patterns are associated with actions, I can associate my own patterns with iotas in any way I choose. An $(l:greatwork/akashiclib)$(item)Akashic Record/$ controls the library, and each $(l:greatwork/akashiclib)$(item)Akashic Bookshelf/$ stores one pattern mapped to one iota. These must all be directly connected together, touching, within 128 blocks. An $(l:greatwork/akashiclib)$(item)Akashic Ligature/$ doesn't do anything but count as a connecting block, to extend the size of my library.", akashic_record: "Allocating and assigning patterns is simple but oh so boring. I have better things to do. I will need a mind well-used to its work for the extraction to stay sound.", "3": "Then to operate the library is simple, the patterns are routed through the librarian and it looks them up and returns the iota to you. Two actions do the work. $(l:patterns/akashic_patterns)Notes here/$.$(br2)Using an empty $(l:items/scroll)$(item)scroll/$ on a bookshelf copies the pattern there onto the $(l:items/scroll)$(item)scroll/$. Sneaking and using an empty hand clears the datum in the shelf.", }, From d1a46b40759ae1e40e0cbbeeb63ba7052ba069f8 Mon Sep 17 00:00:00 2001 From: Robotgiggle <88736742+Robotgiggle@users.noreply.github.com> Date: Sat, 7 Mar 2026 01:18:47 -0500 Subject: [PATCH 3/7] Remove mention of GTP range limit since it doesn't have one anymore --- .../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 ed57ff95f..5575894a9 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 @@ -2105,7 +2105,7 @@ }, "teleport/great": { - "1": "Far more powerful than $(l:patterns/spells/basic#hexcasting:blink)$(action)Blink/$, this spell lets me teleport nearly anywhere in the entire world! There does seem to be a limit, but it is $(italic)much/$ greater than the normal radius of influence I am used to.", + "1": "Far more powerful than $(l:patterns/spells/basic#hexcasting:blink)$(action)Blink/$, this spell lets me teleport an entity to anywhere in the entire world!", "2": "The entity will be teleported by the given vector. Curiously, this vector seems to be an offset, not an absolute position in the world; for example, if I use $(l:patterns/consts#hexcasting:const/vec/x)$(action)Vector Reflection +X/$, the entity will end up precisely one block east of its original position. No matter the distance, it always seems to cost about ten $(l:items/amethyst)$(item)Charged Amethyst/$.$(br2)The transference is not perfect, and it seems when teleporting something as complex as a player, their inventory doesn't $(italic)quite/$ stay attached, and tends to splatter everywhere at the destination. In addition, the target will be forcibly removed from anything inanimate they are riding or sitting on ... but I've read scraps that suggest animals can come along for the ride, so to speak.", }, From 7ece903c9690017a4a81d32b6cde458eaca879a3 Mon Sep 17 00:00:00 2001 From: Robotgiggle <88736742+Robotgiggle@users.noreply.github.com> Date: Sat, 7 Mar 2026 01:58:58 -0500 Subject: [PATCH 4/7] Trim descriptions of Hermes and GTP to avoid page overflow --- .../resources/assets/hexcasting/lang/en_us.flatten.json5 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 5575894a9..587a765c1 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 @@ -1972,7 +1972,7 @@ meta: { "eval.1": "Remove a pattern or list of patterns from the stack, then cast them as if I had drawn them myself with my $(l:items/staff)$(item)Staff/$ (until a $(l:patterns/meta#hexcasting:halt)$(action)Charon's Gambit/$ is encountered). If an iota is escaped with $(l:patterns/patterns_as_iotas#hexcasting:escape)$(action)Consideration/$ or $(l:patterns/patterns_as_iotas#hexcasting:open_paren)$(action)its ilk/$, it will be pushed to the stack. Otherwise, non-patterns will fail.", - "eval.2": "This can be $(italic)very/$ powerful in tandem with $(l:items/focus)$(item)Foci/$.$(br2)It also makes the bureaucracy of Nature a \"Turing-complete\" system, according to one esoteric scroll I found.$(br2)However, it seems there's a limit to how many times a _Hex can cast itself-- Nature doesn't look kindly on runaway spells!$(br2)In addition, with the energies of the patterns occurring without me to guide them, any mishap will cause the remaining actions to become too unstable and immediately unravel.", + "eval.2": "This can be very powerful in tandem with $(l:items/focus)$(item)Foci/$, and according to one esoteric scroll I found it also makes the bureaucracy of Nature a \"Turing-complete\" system.$(br2)However, it seems there's a limit to how many times a _Hex can cast itself-- Nature doesn't look kindly on runaway spells!$(br2)In addition, with the energies of the patterns occurring without me to guide them, any mishap will cause the remaining actions to immediately unravel.", "for_each.1": "Remove a list of patterns and a list from the stack, then cast the given pattern-list over each element of the second list.", "for_each.2": "More specifically, for each element in the second list, it will:$(li)Create a new stack, with everything on the current stack plus that element$(li)Draw all the patterns in the first list$(li)Save all the iotas remaining on the stack to a list$(br)Then, after all is said and done, pushes the list of saved iotas onto the main stack.$(br2)No wonder all the practitioners of this art go mad.", @@ -2105,8 +2105,8 @@ }, "teleport/great": { - "1": "Far more powerful than $(l:patterns/spells/basic#hexcasting:blink)$(action)Blink/$, this spell lets me teleport an entity to anywhere in the entire world!", - "2": "The entity will be teleported by the given vector. Curiously, this vector seems to be an offset, not an absolute position in the world; for example, if I use $(l:patterns/consts#hexcasting:const/vec/x)$(action)Vector Reflection +X/$, the entity will end up precisely one block east of its original position. No matter the distance, it always seems to cost about ten $(l:items/amethyst)$(item)Charged Amethyst/$.$(br2)The transference is not perfect, and it seems when teleporting something as complex as a player, their inventory doesn't $(italic)quite/$ stay attached, and tends to splatter everywhere at the destination. In addition, the target will be forcibly removed from anything inanimate they are riding or sitting on ... but I've read scraps that suggest animals can come along for the ride, so to speak.", + "1": "Far more powerful than $(l:patterns/spells/basic#hexcasting:blink)$(action)Blink/$, this spell lets me teleport an entity to anywhere in the entire world! No matter the distance, it always seems to cost about ten $(l:items/amethyst)$(item)Charged Amethyst/$.", + "2": "The provided vector is an offset, not an absolute position in the world; for example, if I use (1, 0, 0), the entity will end up precisely one block east of its original position.$(br2)Unfortunately, it seems that when teleporting myself, I'm unable to maintain a perfect focus. This can cause some of my items to splatter out of my inventory on arrival.$(br2)I should also note that the target will be forcibly removed from anything inanimate they are riding ... but I've read scraps that suggest animals can come along for the ride, so to speak.", }, zeniths: { From 65e8f8bbbbbbb9bfb0dab25afb1fa9290905aef5 Mon Sep 17 00:00:00 2001 From: Robotgiggle <88736742+Robotgiggle@users.noreply.github.com> Date: Sat, 7 Mar 2026 02:00:00 -0500 Subject: [PATCH 5/7] Describe correct ordering of Power Distillation vector args --- .../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 587a765c1..2e55951ef 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 @@ -1788,7 +1788,7 @@ "abs.2": "Replaces a number with its absolute value, or a vector with its length.", "pow.1": "Perform exponentiation or vector projection.", - "pow.2": "With two numbers, combines them by raising the first to the power of the second.$(li)With a number and a vector, removes the number and raises each component of the vector to the number's power.$(li)With two vectors, combines them into the $(l:https://en.wikipedia.org/wiki/Vector_projection)vector projection/$ of the top of the stack onto the second-from-the-top.$(br2)In the first and second cases, the first argument or its components are the base, and the second argument or its components are the exponent.", + "pow.2": "With two numbers, combines them by raising the first to the power of the second.$(li)With a number and a vector, removes the number and raises each component of the vector to the number's power.$(li)With two vectors, combines them into the $(l:https://en.wikipedia.org/wiki/Vector_projection)vector projection/$ of the second-from-the-top onto the top of the stack.$(br2)In the first and second cases, the first argument or its components are the base, and the second argument or its components are the exponent.", floor: "\"Floors\" a number, cutting off the fractional component and leaving an integer value. If passed a vector, instead floors each of its components.", ceil: "\"Ceilings\" a number, raising it to the next integer value if it has a fractional component. If passed a vector, instead ceils each of its components.", From 8df0b457f68dc6852685d26ebb1d711a66c78a29 Mon Sep 17 00:00:00 2001 From: Robotgiggle <88736742+Robotgiggle@users.noreply.github.com> Date: Sat, 7 Mar 2026 02:11:24 -0500 Subject: [PATCH 6/7] Fix mishap for no placeable item in hotbar --- .../casting/mishaps/MishapBadHotbarItem.kt | 31 +++++++++++++++++++ .../casting/actions/spells/OpPlaceBlock.kt | 4 +-- .../hexcasting/lang/en_us.flatten.json5 | 3 ++ 3 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadHotbarItem.kt diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadHotbarItem.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadHotbarItem.kt new file mode 100644 index 000000000..f5ba27c07 --- /dev/null +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadHotbarItem.kt @@ -0,0 +1,31 @@ +package at.petrak.hexcasting.api.casting.mishaps + +import at.petrak.hexcasting.api.casting.eval.CastingEnvironment +import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.pigment.FrozenPigment +import at.petrak.hexcasting.api.utils.asTranslatedComponent +import net.minecraft.network.chat.Component +import net.minecraft.world.InteractionHand +import net.minecraft.world.item.DyeColor +import net.minecraft.world.item.ItemStack + +class MishapBadHotbarItem(val item: ItemStack?, val wanted: Component) : Mishap() { + override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = + dyeColor(DyeColor.BROWN) + + override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { + env.mishapEnvironment.dropHeldItems() + } + + override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = if (item?.isEmpty == false) + error("bad_item.hotbar", wanted, item.count, item.displayName) + else + error("no_item.hotbar", wanted) + + companion object { + @JvmStatic + fun of(item: ItemStack?, stub: String, vararg args: Any): MishapBadHotbarItem { + return MishapBadHotbarItem(item, "hexcasting.mishap.bad_item.$stub".asTranslatedComponent(*args)) + } + } +} 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 d16e173a2..a2d32e9cf 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 @@ -7,7 +7,7 @@ import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getBlockPos import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.mishaps.MishapBadBlock -import at.petrak.hexcasting.api.casting.mishaps.MishapBadOffhandItem +import at.petrak.hexcasting.api.casting.mishaps.MishapBadHotbarItem import at.petrak.hexcasting.api.misc.MediaConstants import at.petrak.hexcasting.xplat.IXplatAbstractions import net.minecraft.core.BlockPos @@ -41,7 +41,7 @@ object OpPlaceBlock : SpellAction { val itemUseCtx = env .queryForMatchingStack { it.item is BlockItem } ?.let { UseOnContext(env.world, env.castingEntity as? ServerPlayer, env.castingHand, it, blockHit) } - ?: throw MishapBadOffhandItem.of(ItemStack.EMPTY, "placeable") + ?: throw MishapBadHotbarItem.of(ItemStack.EMPTY, "placeable") val placeContext = BlockPlaceContext(itemUseCtx) val worldState = env.world.getBlockState(pos) 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 2e55951ef..aa8626344 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 @@ -1028,6 +1028,7 @@ eval_too_much: "Evaluated too many patterns", no_item: "needs %s but got nothing", "no_item.offhand": "needs %s in the other hand but got nothing", + "no_item.hotbar": "needs %s somewhere in the hotbar but got nothing", bad_entity: "needs %s but got %s", bad_brainsweep: "The %s rejected the being's mind", already_brainswept: "The mind has already been used", @@ -1130,6 +1131,7 @@ bad_item: { "": "needs %s but got %dx %s", offhand: "needs %s in the other hand but got %dx %s", + hotbar: "needs %s somewhere in the hotbar but got %dx %s", iota: { "": "a place to store iotas", @@ -1146,6 +1148,7 @@ rechargable: "a rechargable item", colorizer: "a pigment", variant: "an item with variants", + placeable: "a placeable item", }, bad_block: { From 8ba136d72a9da9927fec4bc8cddf3b892050d090 Mon Sep 17 00:00:00 2001 From: Robotgiggle <88736742+Robotgiggle@users.noreply.github.com> Date: Sat, 7 Mar 2026 02:23:05 -0500 Subject: [PATCH 7/7] Implement and properly document caster's glamour cost --- .../hexcasting/common/casting/actions/spells/OpCycleVariant.kt | 3 ++- .../main/resources/assets/hexcasting/lang/en_us.flatten.json5 | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) 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 e49e6e70a..91ed0c80b 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpCycleVariant.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpCycleVariant.kt @@ -6,6 +6,7 @@ import at.petrak.hexcasting.api.casting.castables.SpellAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.mishaps.MishapBadOffhandItem +import at.petrak.hexcasting.api.misc.MediaConstants import at.petrak.hexcasting.xplat.IXplatAbstractions import net.minecraft.world.item.ItemStack @@ -22,7 +23,7 @@ object OpCycleVariant : SpellAction { return SpellAction.Result( Spell(variantHolder), - 0, + MediaConstants.DUST_UNIT / 10, listOf() ) } 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 aa8626344..359aace20 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 @@ -2074,7 +2074,7 @@ colorize: "I must be holding a $(l:items/pigments)$(item)Pigment/$ in my other hand to cast this spell. When I do, it will consume the dye and permanently change my mind's coloration (at least, until I cast the spell again). Costs about one $(l:items/amethyst)$(item)Amethyst Dust/$.", - cycle_variant: "Certain items I create seem oddly receptive to the influence of _media. By holding a $(l:items/hexcasting)$(item)Cypher/$, $(l:items/hexcasting)$(item)Trinket/$, $(l:items/hexcasting)$(item)Artifact/$, $(l:items/focus)$(item)Focus/$, or $(l:items/spellbook)$(item)Spellbook/$ in my other hand, I can use this spell to change the appearance of the item. Costs about one $(l:items/amethyst)$(item)Amethyst Dust/$.", + cycle_variant: "Certain items I create seem oddly receptive to the influence of _media. By holding a $(l:items/hexcasting)$(item)Cypher/$, $(l:items/hexcasting)$(item)Trinket/$, $(l:items/hexcasting)$(item)Artifact/$, $(l:items/focus)$(item)Focus/$, or $(l:items/spellbook)$(item)Spellbook/$ in my other hand, I can use this spell to change the appearance of the item. Costs a negligible amount of _media.", flights: { "1": "Although it seems that true, limitless flight is out of my grasp, I have nonetheless found some methods of holding one in the sky, each with their respective drawbacks.$(br2)All forms produce a shimmer of excess _media; as the spell gets closer to ending, the sparks are shot through with more red and black.",