-
Notifications
You must be signed in to change notification settings - Fork 137
Implement patterns from overevaluate #1177
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 1.21
Are you sure you want to change the base?
Changes from all commits
92acab9
b935151
9c1a790
3a982f1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| 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 net.minecraft.network.chat.Component | ||
| import net.minecraft.world.item.DyeColor | ||
|
|
||
| class MishapNeedsLoopContext : Mishap() { | ||
| // TODO: need to add to notebook? | ||
| override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = | ||
| dyeColor(DyeColor.BLUE) | ||
|
|
||
| override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context): Component = | ||
| error("needs_loop_context") | ||
|
|
||
| override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList<Iota>) {} | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| package at.petrak.hexcasting.common.casting.actions.eval | ||
|
|
||
| import at.petrak.hexcasting.api.casting.castables.Action | ||
| import at.petrak.hexcasting.api.casting.eval.CastingEnvironment | ||
| import at.petrak.hexcasting.api.casting.eval.OperationResult | ||
| import at.petrak.hexcasting.api.casting.eval.vm.CastingImage | ||
| import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation | ||
| import at.petrak.hexcasting.api.casting.mishaps.MishapNeedsLoopContext | ||
| import at.petrak.hexcasting.common.lib.hex.HexEvalSounds | ||
|
|
||
| object OpContinue : Action { | ||
| override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult { | ||
| var newCont = continuation | ||
| while (newCont is SpellContinuation.NotDone && !newCont.frame.breakSideways()) | ||
| newCont = newCont.next | ||
|
|
||
| if (newCont !is SpellContinuation.NotDone) { | ||
| // failed to find a loop frame | ||
| throw MishapNeedsLoopContext() | ||
| } | ||
|
|
||
| return OperationResult(image.withUsedOp(), listOf(), newCont, HexEvalSounds.SPELL) | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| package at.petrak.hexcasting.common.casting.actions.eval | ||
|
|
||
| import at.petrak.hexcasting.api.casting.castables.Action | ||
| import at.petrak.hexcasting.api.casting.eval.CastingEnvironment | ||
| import at.petrak.hexcasting.api.casting.eval.OperationResult | ||
| import at.petrak.hexcasting.api.casting.eval.vm.CastingImage | ||
| import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation | ||
| import at.petrak.hexcasting.common.lib.hex.HexEvalSounds | ||
|
|
||
| object OpNop : Action { | ||
| override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult = | ||
| OperationResult(image, listOf(), continuation, HexEvalSounds.NOTHING) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| package at.petrak.hexcasting.common.casting.actions.eval | ||
|
|
||
| import at.petrak.hexcasting.api.casting.castables.Action | ||
| import at.petrak.hexcasting.api.casting.eval.CastingEnvironment | ||
| import at.petrak.hexcasting.api.casting.eval.OperationResult | ||
| import at.petrak.hexcasting.api.casting.eval.vm.CastingImage | ||
| import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation | ||
| import at.petrak.hexcasting.common.lib.hex.HexEvalSounds | ||
|
|
||
| object OpTrulyHalt : Action { | ||
| override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult = | ||
| OperationResult(image.withUsedOp(), listOf(), SpellContinuation.Done, HexEvalSounds.SPELL) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| package at.petrak.hexcasting.common.casting.actions.lists | ||
|
|
||
| import at.petrak.hexcasting.api.casting.castables.ConstMediaAction | ||
| import at.petrak.hexcasting.api.casting.eval.CastingEnvironment | ||
| import at.petrak.hexcasting.api.casting.getList | ||
| import at.petrak.hexcasting.api.casting.getPositiveIntUnder | ||
| import at.petrak.hexcasting.api.casting.iota.Iota | ||
| import at.petrak.hexcasting.api.casting.iota.ListIota | ||
|
|
||
| object OpSnapList : ConstMediaAction { | ||
| override val argc = 2 | ||
| override fun execute(args: List<Iota>, env: CastingEnvironment): List<Iota> { | ||
| val list = args.getList(0, argc).toList() | ||
| val breakPosition = args.getPositiveIntUnder(1, list.size) | ||
| return listOf( | ||
| ListIota(list.subList(0, breakPosition)), | ||
| list[breakPosition], | ||
| ListIota(list.subList(breakPosition + 1, list.size)) | ||
| ) | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| package at.petrak.hexcasting.common.casting.actions.stack | ||
|
|
||
| import at.petrak.hexcasting.api.casting.castables.Action | ||
| import at.petrak.hexcasting.api.casting.eval.CastingEnvironment | ||
| import at.petrak.hexcasting.api.casting.eval.OperationResult | ||
| import at.petrak.hexcasting.api.casting.eval.vm.CastingImage | ||
| import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation | ||
| import at.petrak.hexcasting.api.casting.getPositiveIntUnderInclusive | ||
| import at.petrak.hexcasting.api.casting.mishaps.MishapNotEnoughArgs | ||
| import at.petrak.hexcasting.common.lib.hex.HexEvalSounds | ||
|
|
||
| object OpDuplicateMany : Action { | ||
| override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult { | ||
| val stack = image.stack.toMutableList() | ||
| if (stack.isEmpty()) | ||
| throw MishapNotEnoughArgs(1, 0) | ||
| val count = stack.takeLast(1).getPositiveIntUnderInclusive(0, stack.size - 1) | ||
| stack.removeAt(stack.lastIndex) | ||
| for (iota in stack.takeLast(count)) | ||
| stack.add(iota) | ||
| return OperationResult(image.withUsedOp().copy(stack = stack), listOf(), continuation, HexEvalSounds.NORMAL_EXECUTE) | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -762,6 +762,7 @@ | |
| replace: "Surgeon's Exaltation", | ||
| construct: "Speaker's Distillation", | ||
| deconstruct: "Speaker's Decomposition", | ||
| snap_list: "Extirpating Gambit", | ||
|
|
||
| get_entity: "Entity Purification", | ||
| "get_entity/": { | ||
|
|
@@ -789,10 +790,13 @@ | |
| swap: "Jester's Gambit", | ||
| rotate: "Rotation Gambit", | ||
| rotate_reverse: "Rotation Gambit II", | ||
| swap_one_three: "Reflecting Gambit", | ||
| swap_two_three: "Bubbling Gambit", | ||
| duplicate: "Gemini Decomposition", | ||
| over: "Prospector's Gambit", | ||
| tuck: "Undertaker's Gambit", | ||
| "2dup": "Dioscuri Gambit", | ||
| duplicate_many: "Dioscuri Gambit II", | ||
| duplicate_n: "Gemini Gambit", | ||
| stack_len: "Flock's Reflection", | ||
| fisherman: "Fisherman's Gambit", | ||
|
|
@@ -923,7 +927,10 @@ | |
| "eval/cc": "Iris' Gambit", | ||
| for_each: "Thoth's Gambit", | ||
| halt: "Charon's Gambit", | ||
| truly_halt: "Janus' Gambit", | ||
| continue: "Atalanta's Gambit", | ||
| thanatos: "Thanatos' Reflection", | ||
| nop: "Tutu's Gambit", | ||
|
|
||
| "interop/": { | ||
| "gravity/": { | ||
|
|
@@ -1053,6 +1060,7 @@ | |
| no_spell_circle: "requires a spell circle", | ||
| others_name: "Tried to invade the privacy of %s's soul", | ||
| "others_name.self": "Tried to divulge my Name too recklessly", | ||
| needs_loop_context: "needs to be cast within a skippable meta-evaluation pattern", | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would change |
||
|
|
||
| divide_by_zero: { | ||
| divide: "Attempted to divide %s by %s", | ||
|
|
@@ -1509,6 +1517,9 @@ | |
| "needs_parens.title": "Absent Introspection", | ||
| needs_parens: "I attempted to draw $(l:patterns/patterns_as_iotas#hexcasting:close_paren)$(action)Retrospection/$ or $(l:patterns/patterns_as_iotas#hexcasting:undo)$(action)Evanition/$ without first drawing $(l:patterns/patterns_as_iotas#hexcasting:open_paren)$(action)Introspection/$.$(br2)Causes orange sparks, and pushes the pattern I tried to draw to the stack as an iota.", | ||
|
|
||
| "needs_loop_context.title": "Absent Metaevaluation", | ||
| needs_loop_context: "I attempted to draw $(l:patterns/meta#hexcasting:continue)$(action)Atalanta's Gambit/$ while not using $(l:patterns/meta#hexcasting:for_each)$(action)Thoth's Gambit/$.$(br2)Causes dark blue sparks.", | ||
|
|
||
| "too_many_patterns.title": "Lost in Thought", | ||
| too_many_patterns: "I attempted to evaluate too many patterns in one _Hex. Often, this happens because I've accidentally created an infinite loop.$(br2)Causes dark blue sparks, and chokes all the air out of me.", | ||
|
|
||
|
|
@@ -1877,10 +1888,13 @@ | |
| swap: "Swaps the top two iotas of the stack.", | ||
| rotate: "Yanks the iota third from the top of the stack to the top. [0, 1, 2] becomes [1, 2, 0].", | ||
| rotate_reverse: "Yanks the top iota to the third position. [0, 1, 2] becomes [2, 0, 1].", | ||
| swap_one_three: "Swaps the top and third-from-the-top iota. [0, 1, 2] becomes [2, 1 0].", | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing comma in second example list |
||
| swap_two_three: "Swaps the second-from-the-top and third-from-the-top iota. [0, 1, 2] becomes [1, 0, 2].", | ||
| duplicate: "Duplicates the top iota of the stack.", | ||
| over: "Copy the second-to-last iota of the stack to the top. [0, 1] becomes [0, 1, 0].", | ||
| tuck: "Copy the top iota of the stack, then put it under the second iota. [0, 1] becomes [1, 0, 1].", | ||
| "2dup": "Copy the top two iotas of the stack. [0, 1] becomes [0, 1, 0, 1].", | ||
| duplicate_many: "Copy the top n iotas of the stack while preserving order.", | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should probably mention that it pops a number - you could use the |
||
| stack_len: "Pushes the size of the stack as a number to the top of the stack. (For example, a stack of [0, 1] will become [0, 1, 2].)", | ||
| duplicate_n: "Removes the number at the top of the stack, then copies the top iota of the stack that number of times. (A count of 2 results in two of the iota on the stack, not three.)", | ||
| fisherman: "Grabs the element in the stack indexed by the number and brings it to the top. If the number is negative, instead moves the top element of the stack down that many elements.", | ||
|
|
@@ -1958,6 +1972,7 @@ | |
| splat: "Remove the list at the top of the stack, then push its contents to the stack.", | ||
| construct: "Remove the top iota, then add it as the first element to the list at the top of the stack.", | ||
| deconstruct: "Remove the first iota from the list at the top of the stack, then push that iota to the stack.", | ||
| snap_list: "Remove the number at the top of the stack, then split the list at the top of the stack at the given index into a list of what came before, the iota, and what comes after.", | ||
| }, | ||
|
|
||
| patterns_as_iotas: { | ||
|
|
@@ -2006,11 +2021,17 @@ | |
|
|
||
| "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.", | ||
| "halt.2": "But when combined with $(l:patterns/meta#hexcasting:eval)$(action)Hermes'/$ or $(l:patterns/meta#hexcasting:for_each)$(action)Thoth's Gambits/$, it becomes $(italics)far/$ more interesting. Those patterns serve to 'contain' that halting, and rather than ending the entire _Hex, those gambits end instead. This can be used to cause $(l:patterns/meta#hexcasting:for_each)$(action)Thoth's Gambit/$ not to operate on every iota it's given. An escape from the madness, as it were.", | ||
|
|
||
|
|
||
| "truly_halt.1": "This pattern forcibly halts a _Hex, ignoring any $(l:patterns/meta#hexcasting:eval)$(action)Hermes'/$ or $(l:patterns/meta#hexcasting:for_each)$(action)Thoth's Gambits/$ that might otherwise contain $(l:patterns/meta#hexcasting:halt)$(action)Charon's Gambit/$.", | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The use of "contain" here is kinda ambiguous - I think your intent was to refer to the previous page where it talks about hermes and thoth "containing" the break effect, but it could also refer to such patterns evaluating a list that contains the charon pattern as an iota. Maybe "contain the effect of Charon's Gambit" or "hold back the effect of Charon's Gambit"? |
||
|
|
||
| "continue.1": "This pattern halts the current iteration of $(l:patterns/meta#hexcasting:for_each)$(action)Thoth's Gambit/$, immediately causing the next iteration, if any, to start. Mishaps if cast outside of a special context like $(l:patterns/meta#hexcasting:for_each)$(action)Thoth's Gambit/$.", | ||
|
|
||
| "eval/cc.1": "Cast a pattern or list of patterns from the stack exactly like $(l:patterns/meta#hexcasting:eval)$(action)Hermes' Gambit/$, except that a unique \"Jump\" iota is pushed to the stack beforehand. ", | ||
| "eval/cc.2": "When the \"Jump\"-iota is executed, it'll skip the rest of the patterns and jump directly to the end of the pattern list.$(p)While this may seem redundant given $(l:patterns/meta#hexcasting:halt)$(action)Charon's Gambit/$ exists, this allows you to exit $(italic)nested/$ $(l:patterns/meta#hexcasting:eval)$(action)Hermes'/$ invocations in a controlled way, where Charon only allows you to exit one.$(p)The \"Jump\" iota will apparently stay on the stack even after execution is finished... better not think about the implications of that.", | ||
|
|
||
| "thanatos.1": "Adds the number of patterns a _Hex is still capable of evaluating to the stack. This is reduced by one for each pattern cast by the _Hex." | ||
| "thanatos.1": "Adds the number of patterns a _Hex is still capable of evaluating to the stack. This is reduced by one for each pattern cast by the _Hex.", | ||
|
|
||
| "nop.1": "Does nothing. Executing it does not consume an operation, consume media, produce particles, or have any other impact on the world.", | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think "operation" is used to refer to the pattern limit anywhere in-game. Maybe "does not count towards the pattern limit"? |
||
| }, | ||
|
|
||
| circle_patterns: { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might want to mention that these come from Overevaluate