···11-2.0.0 engulfed hexxychests
11+1.4.7-pre.2 add a pattern to force snow
22+1.4.7-pre.2 add demiplane binding, replacing the positional arg for shattering demiplanes
33+1.4.7-pre.2 allow re-enabling old Lani behavior in config
44+1.4.7-pre.2 fix crash with canon 0.11.3 versions
55+1.4.7-pre.2 fix list math breaking hexdoc
66+1.4.7-pre.2 fix void-air scan
77+1.4.7-pre.2 make demiplanes not save redundant chunks
88+1.4.7-pre.2 make greatspells actually greatspells
99+1.4.7-pre.2 meow
1010+1.4.7-pre.2 remove internal error with out-of-bounds excisor's gambit
1111+2.0.0 add casting pouch sealing
1212+2.0.0 add Cessation and Resumption
1313+2.0.0 add docs for plane-related patterns
1414+2.0.0 add Hidden Sun's Nadir (blindness)
1515+2.0.0 add view iotas (experimental!)
2162.0.0 load config from config/*.properties instead of config/jvm.properties
3172.0.0 mediaweave now applies to all chat messages
4182.0.0 !mediaweave now uses trinket slots
5192.0.0 murmur and reveal now use separate components
6202.0.0 !only one mediaweave can be equipped at a time
2121+2.0.0 removed map iotas → moved to phlib with identical behavior
7222.0.0 !removed NBT iotas
2323+2.0.0 removed patchwork iotas → moved to iotaworks with identical behavior
8242.0.0 !removed tripwires
2525+2.0.0 remove snow pattern & fix lithium incompatibility
2626+2.0.0 !remove suffering
2727+2.0.0 rename media bundles to casting pouches
9282.0.0 textures now use JPEG XL
···292292 new FabricLanguageProvider(_):
293293 override def generateTranslations(gen: FabricLanguageProvider.TranslationBuilder): Unit =
294294 for action -> name <- Vector(
295295+ "blind" -> "Hidden Sun's Nadir",
295296 "deleteworld" -> "Shatter Demiplane",
296297 "drop" -> "Rejection Distillation",
297298 "dye_offhand" -> "Apply Pigment",
···317318 "staffcast_factory/lazy" -> "Lani's Lesser Gambit",
318319 "take" -> "Retention Distillation",
319320 "unfox" -> "Vulpine Expulsion",
320320- "whatthefuck" -> "Suffering",
321321 "where" -> "Deductive Purification",
322322 ) do gen.add(s"hexcasting.action.hexic:$action", name)
323323 gen.add("hexcasting.special.hexic:tuple", "Coupler's Gambit")
···358358 "get_other_caster" -> "Adds the closest sentient being, excluding me, to the stack.",
359359 "modulo" -> "Similar to Modulus, but differs for negative numbers: -8 %%₁ 3 = -2, but -8 %%₂ 3 = 1.",
360360 "murmur" -> "Finds the region of my mind known as the 'chat box' and adds its contents to the stack. If it cannot be found, adds Null instead.",
361361+ "blind" -> "Inflicts $(thing)blindness/$. Base cost is one $(l:items/amethyst)$(item)Amethyst Dust/$ per 10 seconds.",
361362 ) do gen.add(s"book.hexic.page.$page", text)
362363 gen.add("hexdoc.hexic.description", "Miscellaneous neat features and QoL patterns for Hex Casting")
363364 gen.add("hexdoc.hexic.title", "Hexic")
···55 "sortnum": 1,
66 "pages": [
77 "Though a $(l:items/phials)$(item)Phial/$ is my ultimate goal for _media storage, knitting a pouch out of $(l:addon/hexic/mediaweave)$(item)mediaweave/$ may help me manage my amethyst better. Only a few cloths are needed to give me some decent capacity. Each pouch holds six slots, and I can extend their capacity to twelve with a bit more weave. A small pouch may go within a large pouch, but neither size can be placed within itself.",
88- "Upon Nature's request for _media, my pouches will offer themselves and their contents first of all; similarly, if I attempt to $(l:patterns/spells/hexcasting#hexcasting:recharge)$(action)Recharge/$ a pouch, the inserted _media will form a 'cloud' of sorts inside, which will settle into any $(l:items/hexcasting)$(item)trinket/$ or similar within.",
88+ "Upon Nature's request for _media, my pouches will offer themselves and their contents first of all; similarly, if I attempt to $(l:patterns/spells/hexcasting#hexcasting:recharge)$(action)Recharge/$ a pouch, the inserted _media will form a 'cloud' of sorts inside, which will settle into any $(l:items/hexcasting)$(item)trinket/$ or similar within. To inhibit this behavior, casting pouches may be sealed by applying $(item)Honeycomb/$ the same way I'd insert an item. I can later wash off the seal by applying a wet sponge.",
99 {
1010 "type": "patchouli:text",
1111 "advancement": "hexcasting:enlightenment",
···11-{
22- "name": "Nature's Revenge",
33- "advancement": "hexcasting:enlightenment",
44- "category": "hexcasting:patterns",
55- "icon": "arrow",
66- "pages": [
77- "No. No. No. I— I thought Horrible was bad— etched into every waking moment— no— no— it hurts— must draw— can't draw— what have I done— why must Nature be like this— ",
88- {
99- "type": "hexcasting:pattern",
1010- "op_id": "hexic:whatthefuck",
1111- "anchor": "hexic:whatthefuck",
1212- "input": "???",
1313- "output": "???",
1414- "text": "How could one even begin to draw this?"
1515- }
1616- ]
1717-}
···1515 },
1616 {
1717 "type": "hexcasting:pattern",
1818- "op_id": "hexcasting:add",
1919- "anchor": "hexcasting:add",
2020- "input": "map<k, v>, map<k, v>",
1818+ "op_id": "hexcasting:replace",
1919+ "anchor": "hexcasting:replace",
2020+ "input": "map<k, v>, k, v",
2121 "output": "map<k, v>",
2222- "text": "Merges two maps together. Maps cannot have duplicate items: any entry in the latter map will override that in the first map."
2222+ "text": "Replaces the element associated with $(n)k/$ with $(n)v/$. If $(n)k/$ is not present in the map, the entry is created and placed at the end of the map."
2323 },
2424 {
2525 "type": "hexcasting:pattern",
2626- "op_id": "hexcasting:sub",
2727- "anchor": "hexcasting:sub",
2828- "input": "map<k, v>, map<t, *>",
2626+ "op_id": "hexcasting:remove_from",
2727+ "anchor": "hexcasting:remove_from",
2828+ "input": "map<k, v>, k",
2929 "output": "map<k, v>",
3030- "text": "Removes every entry in the first map that is found in the second map. The values in the second map are ignored."
3030+ "text": "Throws out the map's association for the given key. If there is no matching association, the map is returned unchanged."
3131 },
3232 {
3333 "type": "hexcasting:pattern",
···3535 "anchor": "hexcasting:index",
3636 "input": "map<k, v>, k",
3737 "output": "v?",
3838- "text": "Disintegrates the map, returning only the value associated with the given key. O(1), unlike scanning a list."
3838+ "text": "Destroys the map, returning only the value associated with the given key. O(1), unlike scanning a list."
3939+ },
4040+ {
4141+ "type": "hexcasting:pattern",
4242+ "op_id": "hexcasting:splat",
4343+ "anchor": "hexcasting:splat",
4444+ "input": "map<k, v>",
4545+ "output": "k, v, k, v...",
4646+ "text": "Disintegrates the map, returning the key-value pairs in the order I inserted them."
3947 },
4048 {
4149 "type": "hexcasting:pattern",
4250 "op_id": "hexcasting:unappend",
4351 "anchor": "hexcasting:unappend",
4444- "input": "map<k, v>",
4545- "output": "map<k, v>, (k, v)?",
4646- "text": "Shaves off one element of a map. Which element gets shaved off is undefined and subject to Nature's whims. If used on an empty map, returns two nulls."
5252+ "input": "map<k,v>",
5353+ "output": "map<k,v>, (k,v | nulls)",
5454+ "text": "Shaves off the element I added most recently from a map. If used on an empty map, returns two nulls."
4755 },
4856 {
4957 "type": "hexcasting:pattern",
5050- "op_id": "hexcasting:replace",
5151- "anchor": "hexcasting:replace",
5252- "input": "map<k, v>, k, v",
5858+ "op_id": "hexcasting:deconstruct",
5959+ "anchor": "hexcasting:deconstruct",
6060+ "input": "map<k,v>",
6161+ "output": "map<k,v>, (k,v | nulls)",
6262+ "text": "Shaves off the element I added least recently from a map. If used on an empty map, returns two nulls."
6363+ },
6464+ {
6565+ "type": "hexcasting:pattern",
6666+ "op_id": "hexcasting:add",
6767+ "anchor": "hexcasting:add",
6868+ "input": "map<k, v>, map<k, v>",
5369 "output": "map<k, v>",
5454- "text": "Replaces the element associated with $(n)k/$ with $(n)v/$. If $(n)k/$ is not present in the map, the entry is created."
7070+ "text": "Merges two maps together. Maps cannot have duplicate items: any entry in the latter map will override that in the first map."
5571 },
5672 {
5773 "type": "hexcasting:pattern",
5858- "op_id": "hexcasting:remove_from",
5959- "anchor": "hexcasting:remove_from",
6060- "input": "map<k, v>, k",
7474+ "op_id": "hexcasting:sub",
7575+ "anchor": "hexcasting:sub",
7676+ "input": "map<k, v>, map<t, *>",
6177 "output": "map<k, v>",
6262- "text": "Throws out the map's association for the given key. If there is no matching association, the map is returned unchanged."
7878+ "text": "Removes every entry in the first map that is found in the second map. The values in the second map are ignored."
6379 }
6480 ]
6581}
···9696 override def operate(env: CastingEnvironment, img: CastingImage, cont: SpellContinuation): OperationResult =
9797 val stack = img.getStack.asScala.toSeq
9898 val args = stack.takeRight(${Expr(a.size)})
9999- // I'm fairly certain the remainder of this method is considered a war crime
10099 ${
101100 Block(a.zipWithIndex.map { p =>
102101 val (v@ValDef(n, ty, _), i) = p