From b9a99bb5aead64c5ae30b02990984b77228b73ec Mon Sep 17 00:00:00 2001 From: gamma-delta <29877714+gamma-delta@users.noreply.github.com> Date: Fri, 8 Apr 2022 22:00:08 -0500 Subject: [PATCH] document everything --- .../common/casting/RegisterPatterns.java | 5 +- .../casting/operators/lists/OpLastNToList.kt | 2 +- .../OpAlwinfyHasAscendedToABeingOfPureMath.kt | 71 +++++++++++++++++++ .../operators/{ => stack}/OpDuplicate.kt | 2 +- .../operators/{ => stack}/OpDuplicateN.kt | 6 +- .../operators/{ => stack}/OpFisherman.kt | 13 ++-- .../casting/operators/{ => stack}/OpMask.kt | 2 +- .../casting/operators/{ => stack}/OpSwap.kt | 2 +- .../assets/hexcasting/lang/en_us.json | 7 +- .../en_us/entries/patterns/stackmanip.json | 14 ++++ 10 files changed, 109 insertions(+), 15 deletions(-) create mode 100644 src/main/java/at/petrak/hexcasting/common/casting/operators/stack/OpAlwinfyHasAscendedToABeingOfPureMath.kt rename src/main/java/at/petrak/hexcasting/common/casting/operators/{ => stack}/OpDuplicate.kt (90%) rename src/main/java/at/petrak/hexcasting/common/casting/operators/{ => stack}/OpDuplicateN.kt (86%) rename src/main/java/at/petrak/hexcasting/common/casting/operators/{ => stack}/OpFisherman.kt (79%) rename src/main/java/at/petrak/hexcasting/common/casting/operators/{ => stack}/OpMask.kt (91%) rename src/main/java/at/petrak/hexcasting/common/casting/operators/{ => stack}/OpSwap.kt (90%) diff --git a/src/main/java/at/petrak/hexcasting/common/casting/RegisterPatterns.java b/src/main/java/at/petrak/hexcasting/common/casting/RegisterPatterns.java index 0e0f254e..d886a893 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/RegisterPatterns.java +++ b/src/main/java/at/petrak/hexcasting/common/casting/RegisterPatterns.java @@ -22,6 +22,7 @@ import at.petrak.hexcasting.common.casting.operators.spells.sentinel.OpCreateSen import at.petrak.hexcasting.common.casting.operators.spells.sentinel.OpDestroySentinel; import at.petrak.hexcasting.common.casting.operators.spells.sentinel.OpGetSentinelPos; import at.petrak.hexcasting.common.casting.operators.spells.sentinel.OpGetSentinelWayfind; +import at.petrak.hexcasting.common.casting.operators.stack.*; import at.petrak.hexcasting.common.items.HexItems; import at.petrak.hexcasting.hexmath.HexAngle; import at.petrak.hexcasting.hexmath.HexDir; @@ -79,6 +80,8 @@ public class RegisterPatterns { PatternRegistry.mapPattern(HexPattern.FromAnglesSig("aawdd", HexDir.EAST), prefix("swap"), OpSwap.INSTANCE); PatternRegistry.mapPattern(HexPattern.FromAnglesSig("ddad", HexDir.WEST), prefix("fisherman"), OpFisherman.INSTANCE); + PatternRegistry.mapPattern(HexPattern.FromAnglesSig("qaawdde", HexDir.SOUTH_EAST), prefix("swizzle"), + OpAlwinfyHasAscendedToABeingOfPureMath.INSTANCE); // == Math == @@ -390,7 +393,7 @@ public class RegisterPatterns { return null; } }); - + PatternRegistry.addSpecialHandler(prefix("mask"), pat -> { var directions = pat.directions(); diff --git a/src/main/java/at/petrak/hexcasting/common/casting/operators/lists/OpLastNToList.kt b/src/main/java/at/petrak/hexcasting/common/casting/operators/lists/OpLastNToList.kt index 7f3a2cb4..971710be 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/operators/lists/OpLastNToList.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/operators/lists/OpLastNToList.kt @@ -25,7 +25,7 @@ object OpLastNToList : Operator { throw MishapInvalidIota( datum, 0, - TranslatableComponent("hexcasting.mishap.invalid_value.fisherman", stack.size) + TranslatableComponent("hexcasting.mishap.invalid_value.int.between", 0, stack.size) ) } val output = mutableListOf>() diff --git a/src/main/java/at/petrak/hexcasting/common/casting/operators/stack/OpAlwinfyHasAscendedToABeingOfPureMath.kt b/src/main/java/at/petrak/hexcasting/common/casting/operators/stack/OpAlwinfyHasAscendedToABeingOfPureMath.kt new file mode 100644 index 00000000..94ccfbd8 --- /dev/null +++ b/src/main/java/at/petrak/hexcasting/common/casting/operators/stack/OpAlwinfyHasAscendedToABeingOfPureMath.kt @@ -0,0 +1,71 @@ +package at.petrak.hexcasting.common.casting.operators.stack + +import at.petrak.hexcasting.api.spell.OperationResult +import at.petrak.hexcasting.api.spell.Operator +import at.petrak.hexcasting.api.spell.Operator.Companion.getChecked +import at.petrak.hexcasting.api.spell.SpellDatum +import at.petrak.hexcasting.common.casting.CastingContext +import at.petrak.hexcasting.common.casting.OperatorSideEffect +import at.petrak.hexcasting.common.casting.mishaps.MishapInvalidIota +import at.petrak.hexcasting.common.casting.mishaps.MishapNotEnoughArgs +import it.unimi.dsi.fastutil.ints.IntArrayList +import net.minecraft.network.chat.TranslatableComponent +import kotlin.math.abs +import kotlin.math.roundToInt + +// "lehmer code" +object OpAlwinfyHasAscendedToABeingOfPureMath : Operator { + override fun operate(stack: MutableList>, ctx: CastingContext): OperationResult { + if (stack.isEmpty()) + throw MishapNotEnoughArgs(1, 0) // todo: better message? + + val codeDouble = stack.getChecked(stack.lastIndex) + if (abs(codeDouble.roundToInt() - codeDouble) >= 0.05f) + throw MishapInvalidIota( + stack.last(), + 0, + TranslatableComponent("hexcasting.mishap.invalid_value.int", 0) + ) + stack.removeLast() + val code = codeDouble.roundToInt() + + val strides = IntArrayList() + for (f in FactorialIter()) { + if (f <= code) + strides.add(f) + else + break + } + + if (strides.size > stack.size) + throw MishapNotEnoughArgs(strides.size + 1, stack.size + 1) + var editTarget = stack.subList(stack.size - strides.size, stack.size) + val swap = editTarget.toMutableList() + var radix = code + for (divisor in strides.asReversed()) { + val index = radix / divisor + radix %= divisor + editTarget[0] = swap.removeAt(index) + // i hope this isn't O(n) + editTarget = editTarget.subList(1, editTarget.size) + } + + return OperationResult( + stack, + listOf(OperatorSideEffect.ConsumeMana(code / 10)) + ) + } + + private class FactorialIter : Iterator { + var acc = 1 + var n = 1 + override fun hasNext(): Boolean = true + + override fun next(): Int { + val out = this.acc + this.acc *= this.n + this.n++ + return out + } + } +} \ No newline at end of file diff --git a/src/main/java/at/petrak/hexcasting/common/casting/operators/OpDuplicate.kt b/src/main/java/at/petrak/hexcasting/common/casting/operators/stack/OpDuplicate.kt similarity index 90% rename from src/main/java/at/petrak/hexcasting/common/casting/operators/OpDuplicate.kt rename to src/main/java/at/petrak/hexcasting/common/casting/operators/stack/OpDuplicate.kt index 580d580b..aa4d5e28 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/operators/OpDuplicate.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/operators/stack/OpDuplicate.kt @@ -1,4 +1,4 @@ -package at.petrak.hexcasting.common.casting.operators +package at.petrak.hexcasting.common.casting.operators.stack import at.petrak.hexcasting.api.spell.ConstManaOperator import at.petrak.hexcasting.api.spell.Operator.Companion.getChecked diff --git a/src/main/java/at/petrak/hexcasting/common/casting/operators/OpDuplicateN.kt b/src/main/java/at/petrak/hexcasting/common/casting/operators/stack/OpDuplicateN.kt similarity index 86% rename from src/main/java/at/petrak/hexcasting/common/casting/operators/OpDuplicateN.kt rename to src/main/java/at/petrak/hexcasting/common/casting/operators/stack/OpDuplicateN.kt index c3d4ea10..40ec3294 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/operators/OpDuplicateN.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/operators/stack/OpDuplicateN.kt @@ -1,4 +1,4 @@ -package at.petrak.hexcasting.common.casting.operators +package at.petrak.hexcasting.common.casting.operators.stack import at.petrak.hexcasting.api.spell.ConstManaOperator import at.petrak.hexcasting.api.spell.Operator.Companion.getChecked @@ -16,11 +16,11 @@ object OpDuplicateN : ConstManaOperator { override fun execute(args: List>, ctx: CastingContext): List> { val countDouble = args.getChecked(1) - if (abs(countDouble.toInt() - countDouble) >= 0.05f) + if (abs(countDouble.roundToInt() - countDouble) >= 0.05f) throw MishapInvalidIota( args[1], 0, - TranslatableComponent("hexcasting.mishap.invalid_value.fisherman", args.size) + TranslatableComponent("hexcasting.mishap.invalid_value.int.between", 0, args.size) ) val count = countDouble.roundToInt() diff --git a/src/main/java/at/petrak/hexcasting/common/casting/operators/OpFisherman.kt b/src/main/java/at/petrak/hexcasting/common/casting/operators/stack/OpFisherman.kt similarity index 79% rename from src/main/java/at/petrak/hexcasting/common/casting/operators/OpFisherman.kt rename to src/main/java/at/petrak/hexcasting/common/casting/operators/stack/OpFisherman.kt index 181ee7e8..d9adb5c6 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/operators/OpFisherman.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/operators/stack/OpFisherman.kt @@ -1,4 +1,4 @@ -package at.petrak.hexcasting.common.casting.operators +package at.petrak.hexcasting.common.casting.operators.stack import at.petrak.hexcasting.api.spell.OperationResult import at.petrak.hexcasting.api.spell.Operator @@ -10,6 +10,7 @@ import at.petrak.hexcasting.common.casting.mishaps.MishapInvalidIota import at.petrak.hexcasting.common.casting.mishaps.MishapNotEnoughArgs import net.minecraft.network.chat.TranslatableComponent import kotlin.math.abs +import kotlin.math.roundToInt object OpFisherman : Operator { val manaCost: Int @@ -22,19 +23,19 @@ object OpFisherman : Operator { val datum = stack[stack.lastIndex] val distance = stack.size - (arg + 1) // because getChecked just gives me a double for some reason stack.removeLast() - if (distance < stack.size && abs(distance.toInt() - distance) < 0.05f) { - val fish = stack[distance.toInt()] - stack.removeAt(distance.toInt()) + if (distance < stack.size && abs(distance.roundToInt() - distance) < 0.05f) { + val fish = stack[distance.roundToInt()] + stack.removeAt(distance.roundToInt()) stack.add(stack.size, fish) } else { throw MishapInvalidIota( datum, 0, - TranslatableComponent("hexcasting.mishap.invalid_value.fisherman", stack.size) + TranslatableComponent("hexcasting.mishap.invalid_value.int.between", 0, stack.size) ) } - val sideEffects = mutableListOf(OperatorSideEffect.ConsumeMana(this.manaCost)) + val sideEffects = mutableListOf(OperatorSideEffect.ConsumeMana(manaCost)) return OperationResult(stack, sideEffects) } diff --git a/src/main/java/at/petrak/hexcasting/common/casting/operators/OpMask.kt b/src/main/java/at/petrak/hexcasting/common/casting/operators/stack/OpMask.kt similarity index 91% rename from src/main/java/at/petrak/hexcasting/common/casting/operators/OpMask.kt rename to src/main/java/at/petrak/hexcasting/common/casting/operators/stack/OpMask.kt index 213261a4..c8702088 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/operators/OpMask.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/operators/stack/OpMask.kt @@ -1,4 +1,4 @@ -package at.petrak.hexcasting.common.casting.operators +package at.petrak.hexcasting.common.casting.operators.stack import at.petrak.hexcasting.api.spell.ConstManaOperator import at.petrak.hexcasting.api.spell.SpellDatum diff --git a/src/main/java/at/petrak/hexcasting/common/casting/operators/OpSwap.kt b/src/main/java/at/petrak/hexcasting/common/casting/operators/stack/OpSwap.kt similarity index 90% rename from src/main/java/at/petrak/hexcasting/common/casting/operators/OpSwap.kt rename to src/main/java/at/petrak/hexcasting/common/casting/operators/stack/OpSwap.kt index 192be382..e699edfd 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/operators/OpSwap.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/operators/stack/OpSwap.kt @@ -1,4 +1,4 @@ -package at.petrak.hexcasting.common.casting.operators +package at.petrak.hexcasting.common.casting.operators.stack import at.petrak.hexcasting.api.spell.ConstManaOperator import at.petrak.hexcasting.api.spell.Operator.Companion.getChecked diff --git a/src/main/resources/assets/hexcasting/lang/en_us.json b/src/main/resources/assets/hexcasting/lang/en_us.json index cceedcf8..a45ab3a8 100644 --- a/src/main/resources/assets/hexcasting/lang/en_us.json +++ b/src/main/resources/assets/hexcasting/lang/en_us.json @@ -175,6 +175,7 @@ "hexcasting.spell.hexcasting:duplicate_n": "Gemini Gambit", "hexcasting.spell.hexcasting:swap": "Jester's Gambit", "hexcasting.spell.hexcasting:fisherman": "Fisherman's Gambit", + "hexcasting.spell.hexcasting:swizzle": "Swindler's Gambit", "hexcasting.spell.hexcasting:add": "Additive Distillation", "hexcasting.spell.hexcasting:sub": "Subtractive Distillation", "hexcasting.spell.hexcasting:mul_dot": "Multiplicative Dstln.", @@ -272,7 +273,8 @@ "hexcasting.mishap.invalid_value.class.unknown": "(unknown, uh-oh, this is a bug)", "hexcasting.mishap.invalid_value.numvec": "a number or vector", "hexcasting.mishap.invalid_value.list.pattern": "a list of patterns", - "hexcasting.mishap.invalid_value.fisherman": "an integer between 0 and %d", + "hexcasting.mishap.invalid_value.int": "an integer", + "hexcasting.mishap.invalid_value.int.between": "an integer between %d and %d", "hexcasting.mishap.not_enough_args": "%s expected %s or more arguments but the stack was only %s tall", "hexcasting.mishap.too_many_close_parens": "Used Retrospection without first using Introspection", "hexcasting.mishap.location_too_far": "%s is out of range for %s", @@ -567,6 +569,9 @@ "hexcasting.page.stackmanip.5.header": "Bookkeeper's Gambits", "hexcasting.page.stackmanip.5": "An infinite family of actions that keep or remove elements at the top of the stack based on the sequence of dips and lines.", "hexcasting.page.stackmanip.6": "Assuming that I draw a Bookkeeper's Gambit pattern left-to-right, the number of iotas the action will require is determined by the horizontal distance covered by the pattern. From deepest in the stack to shallowest, a flat line will keep the iota, whereas a triangle dipping down will remove it.$(br2)If my stack contains $(italic)0, 1, 2/$ from deepest to shallowest, drawing the first pattern opposite will give me $(italic)1/$, the second will give me $(italic)0/$, and the third will give me $(italic)0, 2/$ (the 0 at the bottom is left untouched).", + "hexcasting.page.stackmanip.7": "Rearranges the top elements of the stack based on the given numerical code, which is the index of the permutation wanted.", + "hexcasting.page.stackmanip.8": "Although I can't pretend to know the mathematics behind calculating this permutation code, I have managed to dig up an extensive chart of them, enumerating all permutations of up to six elements.$(br2)If I wish to do further study, the key word is \"Lehmer Code.\"", + "hexcasting.page.stackmanip.8.link": "Table of Codes", "hexcasting.entry.logic": "Logical Operators", "hexcasting.page.logic.1": "If the first argument is greater than the second, return 1. Otherwise, return 0.", diff --git a/src/main/resources/data/hexcasting/patchouli_books/thehexbook/en_us/entries/patterns/stackmanip.json b/src/main/resources/data/hexcasting/patchouli_books/thehexbook/en_us/entries/patterns/stackmanip.json index ad4ca92b..6b158ec0 100644 --- a/src/main/resources/data/hexcasting/patchouli_books/thehexbook/en_us/entries/patterns/stackmanip.json +++ b/src/main/resources/data/hexcasting/patchouli_books/thehexbook/en_us/entries/patterns/stackmanip.json @@ -65,6 +65,20 @@ { "type": "patchouli:text", "text": "hexcasting.page.stackmanip.6" + }, + { + "type": "hexcasting:pattern", + "op_id": "hexcasting:swizzle", + "anchor": "hexcasting:swizzle", + "input": "number, any", + "output": "many", + "text": "hexcasting.page.stackmanip.7" + }, + { + "type": "patchouli:link", + "text": "hexcasting.page.stackmanip.8", + "link_text": "hexcasting.page.stackmanip.8.link", + "url": "https://github.com/gamma-delta/HexMod/wiki/Table-of-Lehmer-Codes-for-Swindler's-Gambit" } ] }