repo for my hex addons :3
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

hexic fusion, repairs, and refactors

+161 -281
+46 -56
project.org
··· 1 + # -*- mode: org; mode: visual-line -*- 1 2 #+TITLE: Hex Addon Planning 2 3 #+AUTHOR: poolcritter 3 4 #+CATEGORY: hex-addons ··· 8 9 :PROPERTIES: 9 10 :CATEGORY: hexic 10 11 :END: 11 - pile of old ideas, deprecated and ripe for theft 12 - *** TODO finish enumerating features 13 - :LOGBOOK: 14 - CLOCK: [2026-01-08 Thu 13:25]--[2026-01-08 Thu 13:26] => 0:01 15 - CLOCK: [2026-01-08 Thu 13:03]--[2026-01-08 Thu 13:19] => 0:16 16 - :END: 17 - if any of y'all people want to steal this, ping me so I can remove it from the list 18 - 19 - - [X] [[./project/iotaworks/][patchworks]] 20 - - [X] [[./project/hexxytounge][murmur refl]] 21 - - [X] [[./project/hexxytounge/][greater reveal]] 22 - - [ ] mediaweave 23 - - [ ] wool edification 24 - - [ ] messaging frames (for mediaweave) 25 - - [ ] stringworms 26 - - [ ] shimmering stringworms 27 - - [ ] stream iotas 28 - - [ ] pattern remapping (modpacks) 29 - - [ ] pens 30 - - [ ] media pouches 31 - - [ ] NBT iotas 32 - - [ ] tripwire iotas (unimplemented) 33 - - [ ] media chiseling 34 - - [ ] (+hexical) hopper into/out of conduits 35 - - [X] (+hexical) Apply Pigment pattern 36 - - [X] works on trinkets 37 - - [ ] list manipulation patterns (where, take, rotate, drop, grep, extract) 38 - - [ ] modulo 2 39 - - [ ] vulpine gambit 40 - - [ ] tupling exaltations 41 - - [ ] snow pattern 42 - - [ ] lani gambits 43 - - [ ] dual's reflection 44 - - [X] [[https://github.com/object-Object/IoticBlocks][erase block/entity]] 45 - - [ ] pseudothoth 46 - - [ ] echo shard casting 47 - - [ ] item overstacking 12 + the misc stuff addon for doing misc addon things 13 + ** Chiseled amethyst 48 14 *** TODO give chisels a texture 49 - *** TODO special demiplane NG handling 50 - when entering, always enter at the center 51 - when exiting, exit where you last entered from 52 - or get sent to the deep noo 53 15 *** TODO give tables a model in-inventory 16 + *** TODO tripwires 17 + deleted code: 18 + #+BEGIN_SRC scala 19 + hexXplat.getContinuationTypeRegistry("tripwire") = TripwireIota.Frame 20 + Patterns.register("tripwire", w"edewqwaqede"): 21 + Patterns.mkLiteral(TripwireIota) 22 + #+END_SRC 23 + #+BEGIN_SRC scala 24 + object TripwireIota extends Iota(new IotaType[TripwireIota.type]: 25 + override def deserialize(tag: NbtElement, world: ServerWorld): TripwireIota.type = TripwireIota 26 + override def color: Int = 0xba4216 27 + override def display(tag: NbtElement): Text = typeName 28 + , Object()): 29 + override def isTruthy: Boolean = true 30 + override def toleratesOther(that: Iota): Boolean = eq(that) 31 + override def serialize(): NbtElement = NbtCompound() 32 + class Frame(mishap: Mishap) extends ContinuationFrame: 33 + override def breakDownwards(x: ju.List[? <: Iota]): Pair[java.lang.Boolean, ju.List[Iota]] = ??? 34 + override def evaluate(cont: SpellContinuation, world: ServerWorld, vm: CastingVM): CastResult = throw mishap 35 + override def getType: Type[?] = Frame 36 + override def serializeToNBT(): NbtCompound = 37 + val c = NbtCompound() 38 + val codec = mishap.getCodec 39 + c.putString("Class", mishap.getClass.getName) 40 + c.put("Data", codec.encodeStart(NbtOps.INSTANCE, mishap.asInstanceOf).getOrThrow(false, _ => {})) 41 + c 42 + override def size: Int = 1 43 + object Frame extends ContinuationFrame.Type[Frame]: 44 + override def deserializeFromNBT(c: NbtCompound, world: ServerWorld): Frame = 45 + val klass = classNamed(c.getString("Class")) 46 + val codec = klass.get.runtimeClass.getMethod("getCodec").invoke(null).asInstanceOf[Codec[? <: Mishap]] 47 + Frame(codec.decode(NbtOps.INSTANCE, c.get("Data")).getOrThrow(false, _ => {}).getFirst) 48 + #+END_SRC 54 49 *** TODO crafted amethyst 55 50 created by a table; worth a shard 56 51 need to implement texture generation ··· 59 54 - [X] demiplane patterns 60 55 - [ ] conjure snow 61 56 - [ ] pseudothoth 57 + ** Demiplanes 58 + *** TODO special demiplane NG handling 59 + when entering, always enter at the center 60 + when exiting, exit where you last entered from 61 + or get sent to the deep noo 62 62 ** [[https://modrinth.com/mod/phlib][PHLib]] 63 63 *** TODO [#A] make a mod icon 64 64 probably my player head holding a quenched amethyst 65 65 *** TODO reimplement Flock Decomp on maps 66 66 *** TODO phlib ↔ [[https://modrinth.com/mod/hexthings][hexthings]] map conversion 67 67 *** TODO dialect conversion in general, actually 68 - ** Underevaluate 69 - *** TODO create project 70 - it needs a real name 71 - *** TODO Hermes' Gambling 72 - executes given iota with a 25% chance, <ne,qqqeeaqq> 73 - *** TODO find other scrapped ideas 74 68 ** [[https://modrinth.com/mod/iotaworks][Iotaworks]] 75 69 *** TODO finish implementing subscripts 76 70 *** TODO implement patchwork subscripts 77 - ** HexxyChests 78 - *** TODO make sure everything works 79 - *** TODO make todo list 80 - ** HexxyTongue 81 - *** TODO port mediaweaves 82 - *** TODO channeled reveal 83 - maybe revealing a map merges it with an internal 'channel' map? 71 + *** TODO steal labels and annotations from hex\mu 72 + probably blocked on [[IoticIotas]] 84 73 ** IoticIotas 85 74 *** TODO revisit 86 75 does this still exist? is it still worth it? ··· 101 90 *** TODO wait for reply wrt Apply Pigment 102 91 **** TODO ping Miyu about [[https://discord.com/channels/936370934292549712/1011455473528098857/1459290686841946153][message]] 103 92 SCHEDULED: <2026-01-10 12:00:00> 104 - *** TODO PR Apply Pigment 105 - make sure it works on trinkets 106 93 * Ideas 107 94 ** TODO Spellminds 108 95 effectively cross-server cross-instance iota transfer bound permanenently to one specific player ··· 110 97 we need iota fmapping though 111 98 ** TODO Liquidification greatspell 112 99 [[./.project.org.assets/liquidify-spell.png]] 100 + * Bugs 101 + ** TODO see if latest VS2 is still incompatible 102 + ** TODO fix Windows compatibility with Bind Demiplane
+10 -3
project/hexic/build.gradle.kts
··· 114 114 } 115 115 } 116 116 117 + loom.runs { 118 + register("mixinDebugClient") { 119 + inherit(loom.runs["client"]) 120 + vmArgs("-Dmixin.debug.export=true", "-Dmixin.debug.export.decompile=true") 121 + } 122 + } 123 + 117 124 val modDepends: Configuration by configurations.creating { 118 125 isTransitive = false 119 126 isCanBeResolved = true ··· 225 232 conflicts("valkyrienskies", "*") // need to figure out how to create dimensions without causing a crash 226 233 227 234 entrypoint("org.eu.net.pool.hexic.main\$package::init") 228 - entrypoint("org.eu.net.pool.hexic.client.main\$package::init", Environment.Client) 229 - entrypoint("fabric-datagen", "org.eu.net.pool.hexic.client.main\$package::datagen") 235 + entrypoint("org.eu.net.pool.hexic.client\$package::init", Environment.Client) 236 + entrypoint("fabric-datagen", "org.eu.net.pool.hexic.client\$package::datagen") 230 237 entrypoint("mm:early_risers", "org.eu.net.pool.hexic.early_riser\$package::warCrimes") 231 238 entrypoint("cardinal-components", "org.eu.net.pool.hexic.ComponentInit") 232 239 mixins("hexic.mixins.json") 233 240 mixins("hexic.client.mixins.json", Environment.Client) 234 - cardinalComponents("player_wisp", "server_info") 241 + cardinalComponents("player_wisp", "server_info", "murmur", "reveal") 235 242 } 236 243 } 237 244
+4
project/hexic/changelog
··· 1 + 2.0.0 engulfed hexxychests 2 + 2.0.0 load config from config/*.properties instead of config/jvm.properties 3 + 2.0.0 murmur and reveal now use separate components 4 + 2.0.0 !removed tripwires
+1 -1
project/hexic/gradle.properties
··· 3 3 loader_version=0.16.14 4 4 scala_loader_version=0.3.1.11 5 5 modid=hexic 6 - version=2.0.0-alpha.01 6 + version=2.0.0 7 7 py_version=1.0 8 8 fabric_version=0.92.6+1.20.1
+1 -1
project/hexic/src/client/resources/hexic.client.mixins.json
··· 1 1 { 2 2 "required": true, 3 3 "minVersion": "0.8", 4 - "package": "org.eu.net.pool.hexic.mixin.client", 4 + "package": "org.eu.net.pool.hexic.mixin", 5 5 "compatibilityLevel": "JAVA_17", 6 6 "client": [ 7 7 "ChatHudMixin",
+21 -16
project/hexic/src/client/scala/org/eu/net/pool/hexic/client/main.scala project/hexic/src/client/scala/org/eu/net/pool/hexic/client.scala
··· 1 1 package org.eu.net.pool 2 2 package hexic 3 - package client 4 3 5 4 import at.petrak.hexcasting.api.item.PigmentItem 6 5 import at.petrak.hexcasting.api.mod.HexTags ··· 22 21 import net.minecraft.client.gui.screen.ChatScreen 23 22 import net.minecraft.client.gui.widget.TextFieldWidget 24 23 import net.minecraft.client.network.{ClientPlayNetworkHandler, ClientPlayerEntity} 25 - import net.minecraft.client.render.{BufferBuilder, RenderLayer, RenderLayers, VertexConsumer, VertexConsumerProvider, VertexFormat} 26 24 import net.minecraft.client.render.block.entity.{BlockEntityRenderer, BlockEntityRendererFactories} 27 25 import net.minecraft.client.render.model.json 26 + import net.minecraft.client.render.* 28 27 import net.minecraft.client.texture.Sprite 29 28 import net.minecraft.client.util.math.MatrixStack 30 - import net.minecraft.data.client.{BlockStateModelGenerator, ItemModelGenerator, ModelIds, Models, TextureKey, TextureMap} 29 + import net.minecraft.data.client.* 31 30 import net.minecraft.data.server.recipe.{RecipeJsonProvider, ShapedRecipeJsonBuilder} 32 31 import net.minecraft.entity.player.PlayerEntity 33 32 import net.minecraft.inventory.Inventory ··· 36 35 import net.minecraft.registry.{MutableRegistry, Registries, RegistryKeys, RegistryWrapper} 37 36 import net.minecraft.screen.slot.Slot 38 37 import net.minecraft.text.{CharacterVisitor, OrderedText, Style} 39 - import net.minecraft.util.{DyeColor, Identifier} 40 38 import net.minecraft.util.collection.DefaultedList 41 39 import net.minecraft.util.math.{Direction, MathHelper, Vec3d} 40 + import net.minecraft.util.{DyeColor, Identifier} 42 41 43 42 import java.io.{InputStreamReader, Reader} 44 43 import java.util.function.Consumer ··· 49 48 import scala.util.boundary 50 49 import scala.util.boundary.Label 51 50 import scala.util.chaining.scalaUtilChainingOps 52 - import phlib.{*, given} 51 + 52 + import phlib.{_, given} 53 53 54 54 given client: MinecraftClient = MinecraftClient.getInstance 55 55 ··· 58 58 case null => default 59 59 case player => ifPresent(player) 60 60 61 - object Hooks: 61 + object ClientHooks: 62 62 def provideRenderText(string: String, firstCharacterIndex: Int, field: TextFieldWidget, original: OrderedText): OrderedText = 63 63 foldLocalPlayer(original): p => 64 64 val c = p.getComponent(PlayerInfoComponent.key) ··· 136 136 val preferredColor = DyeColor.values()(client.getSession.getUuidOrNull.getLeastSignificantBits.abs.%(16).toInt) 137 137 val preferredStringworm = stringworms(Stringworm.flavors(client.getSession.getUuidOrNull.getLeastSignificantBits.abs.%(48).*(7).%(4).toInt)) 138 138 val preferredMediaweave = Mediaweave.colors(preferredColor) 139 - val preferredPen = Pen(preferredColor) 139 + val preferredPen = Pen.instances(preferredColor) 140 140 val preferredPouch = memo(MediaBundle(preferredColor, _)) 141 141 { 142 142 case (Registries.ITEM, id) if id == ("preferred_mediaweave": Identifier) => preferredMediaweave ··· 318 318 pack.addProvider: 319 319 new FabricLanguageProvider(_): 320 320 override def generateTranslations(gen: FabricLanguageProvider.TranslationBuilder): Unit = 321 - for (action, name) <- Vector( 321 + for action -> name <- Vector( 322 322 "deleteworld" -> "Shatter Demiplane", 323 323 "drop" -> "Rejection Distillation", 324 324 "dye_offhand" -> "Apply Pigment", 325 325 "erase" -> "Erase Block", 326 326 "extract" -> "Excisor's Gambit", 327 + "findview" -> "Reflection Purification", 327 328 "fox" -> "Vulpine Gambit", 328 329 "free" -> "Deallocator's Gambit", 329 330 "get_other_caster" -> "Dual's Reflection", ··· 336 337 "makeworld" -> "Conjure Demiplane", 337 338 "malloc" -> "Allocator's Purification", 338 339 "modulo" -> "Modulus Distillation II", 340 + "moveconcept" -> "Transfer Substance", 341 + "moveentity" -> "Transfer Creature", 342 + "murmur" -> "Murmur Reflection", 339 343 "nbt/deserialize" -> "Importer's Purification", 340 344 "nbt/lift1" -> "Secretary's Purification: Byte", 341 345 "nbt/lift2" -> "Secretary's Purification: Short", ··· 355 359 "staffcast_factory" -> "Lani's Greater Gambit", 356 360 "staffcast_factory/lazy" -> "Lani's Lesser Gambit", 357 361 "take" -> "Retention Distillation", 358 - "tripwire" -> "Tripwire Reflection", 359 362 "unfox" -> "Vulpine Expulsion", 360 363 "whatthefuck" -> "Suffering", 361 364 "where" -> "Deductive Purification", 362 365 ) do gen.add(s"hexcasting.action.hexic:$action", name) 363 366 gen.add("hexcasting.special.hexic:tuple", "Coupler's Gambit") 364 367 gen.add("hexcasting.special.hexic:tuple.n", "Coupler's Gambit %s") 365 - for (klass, name) <- Vector( 368 + for klass ->name<- Vector( 366 369 "erase" -> "an item entity or vector", 367 370 "int_or_list" -> "§aint§r or §5[§aint§5]§r", 368 371 ) do gen.add(s"hexcasting.mishap.invalid_value.class.hexic:$klass", name) 369 - for (ty, name) <- Vector( 372 + for ty ->name<- Vector( 370 373 "nbt" -> "Tag", 371 - "tripwire" -> "Tripwire", 372 374 "variant" -> "Concept", 373 375 ) do gen.add(s"hexcasting.iota.hexic:$ty", name) 374 376 gen.add("hexcasting.mishap.bad_block.hexic:erase", "a block holding a casting item or acting as an iota holder") ··· 393 395 Registries.ITEM.forEach: 394 396 case p: PigmentItem => gen.add("item.hexic.stringworm." + p.getTranslationKey, "Shimmering " + hexLang(p.getTranslationKey).replace("Pigment", "Stringworm")) 395 397 case e => println(e) 396 - gen.add("book.hexic.page.dye_offhand", "Imbues the item held in my offhand (e.g. a $(l:items/hexcasting)$(item)casting item/$) with the given pigment.") 397 - gen.add("book.hexic.page.erase", "Erases the _Hex or iota contained within a dropped item or block. Costs one dust per item.") 398 - gen.add("book.hexic.page.get_other_caster", "Adds the closest sentient being, excluding me, to the stack.") 399 - gen.add("book.hexic.page.modulo", "Similar to Modulus, but differs for negative numbers: -8 %%₁ 3 = -2, but -8 %%₂ 3 = 1.") 398 + for page -> text <- Vector( 399 + "dye_offhand" -> "Imbues the item held in my offhand (e.g. a $(l:items/hexcasting)$(item)casting item/$) with the given pigment.", 400 + "erase" -> "Erases the _Hex or iota contained within a dropped item or block. Costs one dust per item.", 401 + "get_other_caster" -> "Adds the closest sentient being, excluding me, to the stack.", 402 + "modulo" -> "Similar to Modulus, but differs for negative numbers: -8 %%₁ 3 = -2, but -8 %%₂ 3 = 1.", 403 + "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.", 404 + ) do gen.add(s"book.hexic.page.$page", text) 400 405 gen.add("hexdoc.hexic.description", "Miscellaneous neat features and QoL patterns for Hex Casting") 401 406 gen.add("hexdoc.hexic.title", "Hexic") 402 407 gen.add("hexic.media.external", "Media")
+3 -4
project/hexic/src/client/scala/org/eu/net/pool/hexic/mixin/client/ChatInputSuggestorMixin.java project/hexic/src/client/scala/org/eu/net/pool/hexic/mixin/ChatInputSuggestorMixin.java
··· 1 - package org.eu.net.pool.hexic.mixin.client; 1 + package org.eu.net.pool.hexic.mixin; 2 2 3 3 import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod; 4 4 import com.llamalad7.mixinextras.injector.wrapoperation.Operation; 5 - import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; 6 5 import net.minecraft.client.gui.screen.ChatInputSuggestor; 7 6 import net.minecraft.client.gui.widget.TextFieldWidget; 8 7 import net.minecraft.text.OrderedText; 9 - import org.eu.net.pool.hexic.client.Hooks; 8 + import org.eu.net.pool.hexic.ClientHooks; 10 9 import org.spongepowered.asm.mixin.Final; 11 10 import org.spongepowered.asm.mixin.Mixin; 12 11 import org.spongepowered.asm.mixin.Shadow; ··· 17 16 18 17 @WrapMethod(method = "provideRenderText") 19 18 OrderedText provideRenderText(String string, int firstCharacterIndex, Operation<OrderedText> original) { 20 - return Hooks.provideRenderText(string, firstCharacterIndex, textField, original.call(string, firstCharacterIndex)); 19 + return ClientHooks.provideRenderText(string, firstCharacterIndex, textField, original.call(string, firstCharacterIndex)); 21 20 } 22 21 }
+3 -3
project/hexic/src/client/scala/org/eu/net/pool/hexic/mixin/client/ChatScreenMixin.java project/hexic/src/client/scala/org/eu/net/pool/hexic/mixin/ChatScreenMixin.java
··· 1 - package org.eu.net.pool.hexic.mixin.client; 1 + package org.eu.net.pool.hexic.mixin; 2 2 3 3 import com.llamalad7.mixinextras.injector.wrapoperation.Operation; 4 4 import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; 5 5 import net.minecraft.client.gui.screen.ChatScreen; 6 6 import net.minecraft.client.network.ClientPlayNetworkHandler; 7 - import org.eu.net.pool.hexic.client.Hooks; 7 + import org.eu.net.pool.hexic.ClientHooks; 8 8 import org.spongepowered.asm.mixin.Mixin; 9 9 import org.spongepowered.asm.mixin.injection.At; 10 10 ··· 12 12 public class ChatScreenMixin { 13 13 @WrapOperation(method = "sendMessage", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayNetworkHandler;sendChatMessage(Ljava/lang/String;)V")) 14 14 void sendChatMessage(ClientPlayNetworkHandler instance, String content, Operation<Void> original) { 15 - if (!Hooks.interceptSendMessage(instance, content)) original.call(instance, content); 15 + if (!ClientHooks.interceptSendMessage(instance, content)) original.call(instance, content); 16 16 } 17 17 }
+1 -5
project/hexic/src/client/scala/org/eu/net/pool/hexic/mixin/client/InventoryScreenMixin.java project/hexic/src/client/scala/org/eu/net/pool/hexic/mixin/InventoryScreenMixin.java
··· 1 - package org.eu.net.pool.hexic.mixin.client; 1 + package org.eu.net.pool.hexic.mixin; 2 2 3 3 import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; 4 4 import net.fabricmc.fabric.api.networking.v1.PacketByteBufs; 5 - import net.fabricmc.fabric.impl.networking.client.ClientPlayNetworkAddon; 6 5 import net.fabricmc.loader.api.FabricLoader; 7 - import net.fabricmc.loader.impl.launch.FabricLauncher; 8 6 import net.minecraft.client.gui.screen.ingame.AbstractInventoryScreen; 9 7 import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen; 10 8 import net.minecraft.client.gui.screen.ingame.InventoryScreen; 11 9 import net.minecraft.entity.player.PlayerInventory; 12 10 import net.minecraft.item.ItemStack; 13 - import net.minecraft.screen.PlayerScreenHandler; 14 11 import net.minecraft.screen.ScreenHandler; 15 12 import net.minecraft.text.Text; 16 13 import net.minecraft.util.Identifier; 17 14 import org.eu.net.pool.hexic.PlayerInfoComponent; 18 15 import org.spongepowered.asm.mixin.Mixin; 19 - import org.spongepowered.asm.mixin.Unique; 20 16 import org.spongepowered.asm.mixin.injection.At; 21 17 import org.spongepowered.asm.mixin.injection.Inject; 22 18 import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
+2
project/hexic/src/main/resources/assets/hexic/lang/zh_cn.json
··· 3 3 "book.hexic.page.erase": "清除物品实体或方块中的$(hex)咒术/$或 iota。每个物品消耗 1 个紫水晶粉。", 4 4 "book.hexic.page.get_other_caster": "将离我最近的有智慧存在压入栈,我自己不计入统计范围。", 5 5 "book.hexic.page.modulo": "与余数之馏化类似,但两者在负数上的表现不同:-8 %%₁ 3 = -2,而 -8 %%₂ 3 = 1。", 6 + "book.hexic.page.murmur": "找到我意识中名为“聊天栏”的区域,将其内容压栈;无法找到则返回 Null。", 6 7 "hexcasting.action.hexic:deleteworld": "击碎半位面", 7 8 "hexcasting.action.hexic:drop": "拒斥之馏化", 8 9 "hexcasting.action.hexic:dye_offhand": "应用染色剂", ··· 20 21 "hexcasting.action.hexic:makeworld": "构筑半位面", 21 22 "hexcasting.action.hexic:malloc": "分配器之纯化", 22 23 "hexcasting.action.hexic:modulo": "余数之馏化,第二型", 24 + "hexcasting.action.hexic:murmur": "私语之精思", 23 25 "hexcasting.action.hexic:nbt/deserialize": "导入器之纯化", 24 26 "hexcasting.action.hexic:nbt/lift1": "秘书之纯化:字节", 25 27 "hexcasting.action.hexic:nbt/lift2": "秘书之纯化:短整型",
+2 -3
project/hexic/src/main/resources/data/hexcasting/tags/action/per_world_pattern.json
··· 1 1 { 2 2 "values": [ 3 - "hexcasting:craft/artifact", 4 - "hexcasting:craft/trinket", 5 - "hexic:snow" 3 + "hexic:snow", 4 + "hexic:moveentity" 6 5 ] 7 6 }
+2 -1
project/hexic/src/main/resources/data/hexcasting/tags/action/requires_enlightenment.json
··· 1 1 { 2 2 "values": [ 3 - "hexic:snow" 3 + "hexic:snow", 4 + "hexic:moveentity" 4 5 ] 5 6 }
+17 -60
project/hexic/src/main/scala/org/eu/net/pool/hexic/main.scala
··· 95 95 import scala.annotation.unchecked.uncheckedVariance 96 96 import scala.annotation.{elidable, experimental, showAsInfix, tailrec, targetName, unused} 97 97 import scala.ref.WeakReference 98 - import scala.util.{Failure, Success, Try} 98 + import scala.util.{Failure, NotGiven, Random, Success, Try, TupledFunction, Using, boundary} 99 99 import scala.collection.mutable 100 100 import scala.compiletime.summonFrom 101 101 import scala.concurrent.{Await, ExecutionContext, Future, Promise} ··· 103 103 import scala.language.experimental.{macros, saferExceptions} 104 104 import scala.language.{dynamics, existentials, implicitConversions, postfixOps, reflectiveCalls} 105 105 import scala.reflect.{ClassTag, classTag} 106 - import scala.util.{NotGiven, Random, TupledFunction, boundary} 107 106 import at.petrak.hexcasting.api.casting.mishaps.Mishap.Context 108 107 import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking.PlayChannelHandler 109 108 import net.fabricmc.fabric.api.networking.v1.{FabricPacket, PacketByteBufs, PacketSender, PacketType, ServerPlayNetworking} ··· 366 365 367 366 class PlayerInfoComponent( 368 367 val player: PlayerEntity, 369 - var murmur: Option[String] = None, 370 368 var leftWeave: ItemStack = ItemStack.EMPTY, 371 369 var rightWeave: ItemStack = ItemStack.EMPTY, 372 370 var chatLines: Seq[Text] = Seq(), ··· 476 474 given [T <: java.lang.Enum[T]: ClassTag as ct] => FromString[T]: 477 475 override def fromString(s: String): T = Enum.valueOf[T](ct.runtimeClass.asInstanceOf[Class[T]], s) 478 476 479 - case class Pen private [hexic] (color: DyeColor) extends Item(Item.Settings().maxCount(1)): 477 + case class Pen private [hexic] (color: DyeColor) extends Item(Item.Settings().maxCount(1)) with Registered(Registries.ITEM, s"pen/$color"): 478 + override def toString = s"$getClass(color=$color)${super[Item].toString}" 480 479 override def use(world: World, player: PlayerEntity, hand: Hand): TypedActionResult[ItemStack] = 481 480 // if player.getAttributeValue(HexAttributes.FEEBLE_MIND) > 0.0 then 482 481 // TypedActionResult.fail(player.getStackInHand(hand)) ··· 853 852 ) 854 853 possible(Random.nextInt(possible.size)) 855 854 Interop.thoughtWorld = RegistryKey.of(RegistryKeys.WORLD, "thought") 856 - try System.getProperties.load(Files.newBufferedReader(Path.of("config/jvm.properties"), Charsets.UTF_8)) 857 - catch 858 - case _: FileNotFoundException => 859 - case i: IOException => summon[Logger].warn("Failed to read properties", i) 860 - iotaTypeRegistry("location") = LocationIota 861 855 iotaTypeRegistry("nbt") = NbtIota 862 - iotaTypeRegistry("tripwire") = TripwireIota.getType 863 856 iotaTypeRegistry("access") = PropertyAccessIota.Type 864 - hexXplat.getContinuationTypeRegistry("tripwire") = TripwireIota.Frame 865 857 for (color, item) <- Mediaweave.colors do 866 858 Registries.ITEM(s"${color.asString}_mediaweave") = item 867 859 for item <- MediaBundle.items do ··· 870 862 case 12 => s"large_${item.color.asString}_bundle") = item 871 863 for (flavor, item) <- stringworms do 872 864 Registries.ITEM(s"stringworm_$flavor") = item 865 + Pen.instances 873 866 Registries.ITEM("stringworm_pigmented") = dyedStringworm 874 867 Registries.ITEM("wizard") = wizard 875 868 val cutItem = new Item(Item.Settings().maxCount(16)) with MediaHolderItem: ··· 968 961 case _ => ActionResult.PASS 969 962 Registries.BLOCK("chisel_table") = table 970 963 Registries.ITEM("chisel_table") = BlockItem(table, Item.Settings()) 971 - for (color, item) <- Pen.instances do Registries.ITEM(s"pen/${color.asString}") = item 972 964 Registries.ITEM_GROUP("group") = itemGroup 973 965 //Registries.ITEM("echo") = EchoItem 966 + initChat() 967 + initViews() 974 968 if fabric.isModLoaded("hexical") then 975 969 for 976 970 HopperEndpointRegistry <- classNamed("miyucomics.hexical.features.hopper.HopperEndpointRegistry") ··· 1065 1059 case _ => mishap 1066 1060 )) 1067 1061 case _ => mishap 1068 - Patterns.register("tripwire", w"edewqwaqede"): 1069 - Patterns.mkLiteral(TripwireIota) 1070 1062 Patterns.arithmetic("modulo", goodModulo) 1071 1063 Registry.register(hexXplat.getArithmeticRegistry, "goodModulo": Identifier, arith("goodModulo", 1072 1064 goodModulo -> ((x: DoubleIota, y: DoubleIota) => Seq(DoubleIota((x.getDouble % y.getDouble + y.getDouble) % y.getDouble))), ··· 1982 1974 given [T] => Conversion[Const[T], T] = _.value 1983 1975 1984 1976 private[hexic] class ComponentInit extends EntityComponentInitializer, LevelComponentInitializer: 1985 - override def registerEntityComponentFactories(using EntityComponentFactoryRegistry): Unit = 1977 + override def registerEntityComponentFactories(using r: EntityComponentFactoryRegistry): Unit = 1986 1978 PlayerInfoComponent.register 1979 + r.registerForPlayers(summon[ComponentKey[MurmurCache]], _ => MurmurCache(None), RespawnCopyStrategy.ALWAYS_COPY) 1980 + r.registerForPlayers(summon[ComponentKey[RevealComponent]], _ => RevealComponent(Seq.empty), RespawnCopyStrategy.LOSSLESS_ONLY) 1987 1981 override def registerLevelComponentFactories(using LevelComponentFactoryRegistry): Unit = 1988 1982 ServerInfoComponent.register 1989 1983 ··· 2051 2045 def unapply[T <: NbtElement](l: AbstractNbtList[T]): Some[ClassTag[T]] = Some(elementTag(l)) 2052 2046 2053 2047 private[hexic] object cfg: 2048 + locally: 2049 + Using.resource(Files.list(Path.of("config/"))): dir => 2050 + dir.forEach: file => 2051 + if file.toString.endsWith(".properties") then 2052 + try 2053 + System.getProperties.load(Files.newBufferedReader(file, Charsets.UTF_8)) 2054 + catch 2055 + case i: IOException => summon[Logger].warn(s"Failed to read properties from $file", i) 2054 2056 def apply[T: FromString as t](key: String): Option[T] = 2055 2057 sys.props.get(key).map(t.fromString) 2056 2058 def flag(key: String): Boolean = cfg[Boolean](s"hexic.$key").contains(true) ··· 2145 2147 given Conversion[NbtIntArray, Array[Int]] = _.getIntArray 2146 2148 given Conversion[NbtLongArray, Array[Long]] = _.getLongArray 2147 2149 2148 - case class MishapWrongDimensionKiddo(val dim1: RegistryKey[World], val dim2: RegistryKey[World]) extends Mishap: 2149 - override def accentColor(using CastingEnvironment, Mishap.Context): FrozenPigment = dyeColor(DyeColor.MAGENTA) 2150 - override def errorMessage(using CastingEnvironment, Mishap.Context): Text = 2151 - val env = summon[CastingEnvironment] 2152 - val color = env.getPigment.getColorProvider.getColor(0, Vec3d.ZERO) 2153 - val mind = t"Mind".styled(_ `withColor` color) 2154 - t"My ${mind} cannot think in ${dim1.getValue `toTranslationKey` "dimension"} and ${dim2.getValue `toTranslationKey` "dimension"} at once" 2155 - override def execute(using CastingEnvironment, Mishap.Context, util.List[Iota]): Unit = ??? 2156 - 2157 2150 trait Tagged[+F[_ <: U @uncheckedVariance], +U]: 2158 2151 type T <: U: ClassTag 2159 2152 val value: F[T] ··· 2243 2236 def piece = s"${b.toUpperCase}$v$b" + Iterator.continually(v + b).takeWhile(_ => rand.nextInt(3) != 0).mkString("") 2244 2237 (piece +: Iterator.continually(piece).takeWhile(_ => rand.nextInt(5) == 0).toSeq).mkString("-") 2245 2238 val pocketNames = memo((id: UUID) => pocketName(using Random(id.getLeastSignificantBits))) 2246 - 2247 - object TripwireIota extends Iota(new IotaType[TripwireIota.type]: 2248 - override def deserialize(tag: NbtElement, world: ServerWorld): TripwireIota.type = TripwireIota 2249 - override def color: Int = 0xba4216 2250 - override def display(tag: NbtElement): Text = typeName 2251 - , Object()): 2252 - override def isTruthy: Boolean = true 2253 - override def toleratesOther(that: Iota): Boolean = eq(that) 2254 - override def serialize(): NbtElement = NbtCompound() 2255 - class Frame(mishap: Mishap) extends ContinuationFrame: 2256 - override def breakDownwards(x: ju.List[? <: Iota]): Pair[java.lang.Boolean, ju.List[Iota]] = ??? 2257 - override def evaluate(cont: SpellContinuation, world: ServerWorld, vm: CastingVM): CastResult = throw mishap 2258 - override def getType: Type[?] = Frame 2259 - override def serializeToNBT(): NbtCompound = 2260 - val c = NbtCompound() 2261 - val codec = mishap.getCodec 2262 - c.putString("Class", mishap.getClass.getName) 2263 - c.put("Data", codec.encodeStart(NbtOps.INSTANCE, mishap.asInstanceOf).getOrThrow(false, _ => {})) 2264 - c 2265 - override def size: Int = 1 2266 - object Frame extends ContinuationFrame.Type[Frame]: 2267 - override def deserializeFromNBT(c: NbtCompound, world: ServerWorld): Frame = 2268 - val klass = classNamed(c.getString("Class")) 2269 - val codec = klass.get.runtimeClass.getMethod("getCodec").invoke(null).asInstanceOf[Codec[? <: Mishap]] 2270 - Frame(codec.decode(NbtOps.INSTANCE, c.get("Data")).getOrThrow(false, _ => {}).getFirst) 2271 - 2272 - case class LocationIota(vec: Vec3d, dim: Option[RegistryKey[World]]) extends Vec3Iota(vec), IotaTypeHint: 2273 - override def serialize: NbtElement = NbtCompound().tap(_.put("vec", super.serialize())).tap(n => dim.map(v => n.putString("dim", v.getValue.toString))) 2274 - override def hexic$iotaType(): IotaType[?] = LocationIota 2275 - 2276 - object LocationIota extends IotaType[LocationIota]: 2277 - override def color: Int = Vec3Iota.TYPE.color() 2278 - override def deserialize(using NbtElement, ServerWorld): LocationIota = ??? 2279 - override def display(d: NbtElement): Text = d match 2280 - case d: NbtCompound => Vec3Iota.TYPE.display(d.get("vec")) 2281 - case _ => null 2282 2239 2283 2240 inline def repeat[T](inline value: T, inline cond: T => Boolean)(inline body: T => T): T = 2284 2241 var current = value
+1
project/hexic/src/main/scala/org/eu/net/pool/hexic/mixin/ItemMixin.java
··· 22 22 import net.minecraft.world.World; 23 23 import org.jetbrains.annotations.Nullable; 24 24 import org.spongepowered.asm.mixin.Mixin; 25 + import org.spongepowered.asm.mixin.Unique; 25 26 import org.spongepowered.asm.mixin.injection.At; 26 27 import org.spongepowered.asm.mixin.injection.Inject; 27 28 import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
-44
project/hexxychests/build.gradle.kts
··· 1 - plugins { 2 - id("fabric-loom") 3 - id("scala") 4 - kotlin("jvm") version "2.2.0" 5 - id("maven-publish") 6 - id("de.undercouch.download") version "5.6.0" 7 - id("org.eu.net.pool.mc-plugin") 8 - } 9 - 10 - dependencies { 11 - minecraft("com.mojang:minecraft:${project.property("minecraft_version")}") 12 - mappings("net.fabricmc:yarn:${project.property("yarn_mappings")}:v2") 13 - modImplementation("net.fabricmc:fabric-loader:${project.property("loader_version")}") 14 - modImplementation("net.fabricmc.fabric-api:fabric-api:${project.property("fabric_version")}") 15 - api("org.scala-lang:scala3-library_3:3.7.1") 16 - api("org.scala-lang:scala-library:2.13.6") 17 - api(project(":util", "namedElements")) 18 - modImplementation("at.petra-k.hexcasting:hexcasting-fabric-$minecraft_version:0.11.3") 19 - modImplementation("at.petra-k.paucal:paucal-fabric-$minecraft_version:0.6.0-pre-118") 20 - modImplementation("com.samsthenerd.inline:inline-fabric:$minecraft_version-1.0.1") 21 - modImplementation("dev.onyxstudios.cardinal-components-api:cardinal-components-block:5.2.3") 22 - modImplementation("dev.onyxstudios.cardinal-components-api:cardinal-components-item:5.2.3") 23 - } 24 - 25 - tasks.processResources { 26 - preprocessor { 27 - fabricMod("hexxychests", version as String) { 28 - name = "Hex In Yo' Chests" 29 - description = "A Hex Casting addon for manipulating iotas." 30 - license = "LGPL-3.0" 31 - icon = "assets/hexxychests/icon.png" 32 - 33 - author("pool") { 34 - put("discord", "https://discord.com/users/758407438251720795") 35 - } 36 - 37 - depends("phlib", ">=0.2.0") 38 - depends("hexcasting", ">=0.11.2") 39 - 40 - entrypoint("org.eu.net.pool.hexxychests.main\$package::init") 41 - mixins("hexxychests.mixins.json") 42 - } 43 - } 44 - }
-9
project/hexxychests/gradle.properties
··· 1 - minecraft_version=1.20.1 2 - yarn_mappings=1.20.1+build.10 3 - loader_version=0.16.14 4 - scala_loader_version=0.3.1.11 5 - version=0.1.0 6 - maven_group=org.eu.net.pool 7 - modid=hexxychests 8 - archives_base_name=hexxychests 9 - fabric_version=0.92.6+1.20.1
-7
project/hexxychests/src/main/resources/data/hexcasting/tags/action/per_world_pattern.json
··· 1 - { 2 - "values": [ 3 - "hexxychests:findview", 4 - "hexxychests:moveconcept", 5 - "hexxychests:moveentity" 6 - ] 7 - }
-5
project/hexxychests/src/main/resources/data/hexcasting/tags/action/requires_enlightenment.json
··· 1 - { 2 - "values": [ 3 - "hexxychests:moveentity" 4 - ] 5 - }
-7
project/hexxychests/src/main/resources/hexxychests.mixins.json
··· 1 - { 2 - "package": "org.eu.net.pool.hexxychests.mixin", 3 - "parent": "phlib.mixins.json", 4 - "mixins": [ 5 - "AbstractFurnaceBlockEntityMixin" 6 - ] 7 - }
+20 -15
project/hexxychests/src/main/scala/org/eu/net/pool/hexxychests/main.scala project/hexic/src/main/scala/org/eu/net/pool/hexic/views.scala
··· 1 - package org.eu.net.pool.hexxychests 1 + package org.eu.net.pool.hexic 2 + 2 3 import at.petrak.hexcasting.api.casting.arithmetic.Arithmetic 3 4 import at.petrak.hexcasting.api.casting.circles.BlockEntityAbstractImpetus 4 5 import at.petrak.hexcasting.api.casting.eval.CastingEnvironment 5 - import at.petrak.hexcasting.api.casting.iota.{DoubleIota, Iota, IotaType, NullIota, Vec3Iota} 6 + import at.petrak.hexcasting.api.casting.iota.* 6 7 import at.petrak.hexcasting.api.casting.mishaps.{Mishap, MishapInvalidIota} 7 8 import com.mojang.serialization.Codec 8 9 import com.samsthenerd.inline.api.data.ItemInlineData ··· 30 31 import org.slf4j.{Logger, LoggerFactory} 31 32 32 33 import java.util.UUID 34 + import scala.collection.immutable.ArraySeq.unsafeWrapArray 33 35 import scala.collection.mutable 34 36 import scala.reflect.ClassTag 35 37 import scala.util.{Failure, Success, Using} 36 - 37 - private[hexxychests] given Conversion[String, Identifier] = Identifier.of("hexxychests", _) 38 - private[hexxychests] given Logger = LoggerFactory.getLogger("hexxychests") 39 38 40 39 trait InventoryView(val viewType: InventoryView.Type[?]) extends InventoryView.Handler: 41 40 def isTruthy = true ··· 60 59 @throws[Mishap] 61 60 def teleportEntity(ent: Entity)(using TransactionContext, CastingEnvironment): Boolean = false 62 61 object Events: 63 - val forEntity: Event[Entity => ServerWorld ?=> Seq[Handler]] = EventFactory.createArrayBacked(classOf, _ => Seq(), fns => e => fns.flatMap(_(e))) 64 - val forBlock: Event[(BlockPos, BlockState) => ServerWorld ?=> Seq[Handler]] = EventFactory.createArrayBacked(classOf, (_, _) => Seq(), fns => (pos, state) => fns.flatMap(_(pos, state))) 62 + val forEntity: Event[Entity => ServerWorld ?=> Seq[Handler]] = EventFactory.createArrayBacked(classOf, _ => Seq(), fns => e => unsafeWrapArray(fns).flatMap(_(e))) 63 + val forBlock: Event[(BlockPos, BlockState) => ServerWorld ?=> Seq[Handler]] = EventFactory.createArrayBacked(classOf, (_, _) => Seq(), fns => (pos, state) => unsafeWrapArray(fns).flatMap(_(pos, state))) 65 64 // 'implementation restriction' my ass 66 65 val forIota: Event[CastingEnvironment ?=> PartialFunction[Iota, InventoryView]] = EventFactory.createArrayBacked(classOf, PartialFunction.empty, new java.util.function.Function[Array[CastingEnvironment ?=> PartialFunction[Iota, InventoryView]], CastingEnvironment ?=> PartialFunction[Iota, InventoryView]]: 67 66 def apply(fns: Array[CastingEnvironment ?=> PartialFunction[Iota, InventoryView]]): CastingEnvironment ?=> PartialFunction[Iota, InventoryView] = (((_: CastingEnvironment) ?=> PartialFunction.empty[Iota, InventoryView]) /: fns) { _ orElse _ } 68 67 ) 69 68 abstract class OfMerged(viewType: InventoryView.Type[?], views: => Seq[Handler]) extends InventoryView(viewType): 70 69 def getViews = views 71 - override def apply(idx: Int)(using CastingEnvironment): Option[SlotReference] = views.collectFirst(hexicVisibilityHack.unlifted(_(idx))) 70 + override def apply(idx: Int)(using CastingEnvironment): Option[SlotReference] = views.collectFirst(Function.unlift(_(idx))) 72 71 override def tryExtract(variant: TransferVariant[?], amount: Long)(using TransactionContext, CastingEnvironment): Long = LazyList.from(views).scanLeft(0L)((n, view) => view.tryExtract(variant, amount - n) + n).findFirstOrLast(_ >= amount).getOrElse(0) 73 72 override def tryInsert(variant: TransferVariant[?], amount: Long)(using TransactionContext, CastingEnvironment): Long = LazyList.from(views).scanLeft(0L)((n, view) => view.tryInsert(variant, amount - n) + n).findFirstOrLast(_ >= amount).getOrElse(0) 74 73 override def capacity(variant: TransferVariant[?])(using TransactionContext, CastingEnvironment) = views.map(_.capacity(variant)).sum ··· 88 87 case v: OfSum => v.views 89 88 case v => Iterable(v) 90 89 ) 91 - class OfEntity(id: UUID)(using server: MinecraftServer) extends OfMerged(typeOfEntity, server.getWorlds.collectFirst(hexicVisibilityHack.unlifted(w => Option(w.getEntity(id)).map(Events.forEntity.invoker()(_)(using w)))).getOrElse(Seq())): 90 + class OfEntity(id: UUID)(using server: MinecraftServer) extends OfMerged(typeOfEntity, server.getWorlds.collectFirst(Function.unlift(w => Option(w.getEntity(id)).map(Events.forEntity.invoker()(_)(using w)))).getOrElse(Seq())): 92 91 override def serialize = 93 92 val c = super.serialize 94 93 c.putLong("m", id.getMostSignificantBits) ··· 210 209 def fuelTime: Int 211 210 def fuelTime_=(fuelTime: Int): Unit 212 211 213 - private [hexxychests] val conceptScale = mutable.Map[ClassTag[? <: TransferVariant[?]], Double]().withDefaultValue(1.0) 212 + private [hexic] val conceptScale = mutable.Map[ClassTag[? <: TransferVariant[?]], Double]().withDefaultValue(1.0) 214 213 def setConceptScale[T <: TransferVariant[?]: ClassTag as ct](scale: Int) = 215 214 if conceptScale.isDefinedAt(ct) && conceptScale(ct) != scale then 216 215 throw IllegalStateException(s"Conflicting scales ${conceptScale(ct)} and $scale defined for class $ct") ··· 253 252 object SlotReference extends Registrar[SlotReference.Type[?]]("slot"): 254 253 class Type[T <: SlotReference: Codec] 255 254 256 - def init() = 257 - hexXplat.getIotaTypeRegistry("variant") = VariantIota 258 - hexXplat.getIotaTypeRegistry("reference") = BoxedView 255 + object id: 256 + def unapply(x: Identifier) = (x.getNamespace, x.getPath) 257 + 258 + def initViews() = 259 + hexXplat.getIotaTypeRegistry("transfer_type") = VariantIota 260 + hexXplat.getIotaTypeRegistry("inventory_view") = BoxedView 261 + Events.registryLookup.register: 262 + case (r, id("hexic" | "hexxychests", "variant")) => VariantIota 263 + case (r, id("hexic" | "hexxychests", "reference")) => BoxedView 259 264 Patterns.register("findview", e"addaadewewedaaddqwawqddaadewewedaaddqwawdeeweee"): 260 265 // 2026-01-01 pool: nathan, we call this 'jank'. why would you do this? 261 266 inline def lookup = InventoryView.Events.forIota.invoker()(using compiletime.summonInline) ··· 291 296 ??? // TODO: mishap 292 297 tx.commit() 293 298 Seq(DoubleIota(insert / scale)) 294 - Patterns.register("moveentity", e"edeeewawdweaaddaqwqwqaddaaewdwawewdqd"): 299 + Patterns.register("moveentity", se"edeeewawdweaaddaqwqwqaddaaewdwawewdqd"): 295 300 Patterns.mkConstAction(3): 296 301 case Seq(isIota[BoxedView.Instance, 2](from), isIota[BoxedView.Instance, 1](into), isIota[DoubleIota, 0](count)) => 297 302 Using.resource(Transaction.openOuter()): ··· 318 323 def variant: TransferVariant[T] 319 324 def display: Text 320 325 def color: Int = 0x720a0a 321 - private[hexxychests] def parseVariant(c: NbtCompound): Option[(TaggedVariant, RegistryKey[Reader])] = 326 + private[hexic] def parseVariant(c: NbtCompound): Option[(TaggedVariant, RegistryKey[Reader])] = 322 327 for 323 328 i <- Option(Identifier.tryParse(c.getString("type"))) 324 329 entry <- Option.fromNullable(registry.get(i))
+2 -2
project/hexxychests/src/main/scala/org/eu/net/pool/hexxychests/mixin/AbstractFurnaceBlockEntityMixin.java project/hexic/src/main/scala/org/eu/net/pool/hexic/mixin/AbstractFurnaceBlockEntityMixin.java
··· 1 - package org.eu.net.pool.hexxychests.mixin; 1 + package org.eu.net.pool.hexic.mixin; 2 2 3 3 import net.minecraft.block.entity.AbstractFurnaceBlockEntity; 4 - import org.eu.net.pool.hexxychests.AbstractFurnaceBlockEntityAccess; 4 + import org.eu.net.pool.hexic.AbstractFurnaceBlockEntityAccess; 5 5 import org.spongepowered.asm.mixin.Mixin; 6 6 import org.spongepowered.asm.mixin.gen.Accessor; 7 7
-2
project/hexxychests/src/main/scala/scala/hexicVisibilityHack/hack.scala
··· 1 - package scala.hexicVisibilityHack 2 - export PartialFunction.unlifted
+6 -7
project/hexxytounge/src/client/scala/org/eu/net/pool/hexxytounge/client.scala project/hexic/src/client/scala/org/eu/net/pool/hexic/chatClient.scala
··· 1 - package org.eu.net.pool.hexxytounge 1 + package org.eu.net.pool 2 + package hexic 2 3 3 4 import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking 4 5 import net.fabricmc.fabric.api.networking.v1.PacketByteBufs ··· 10 11 given Conversion[ChatScreen, mixin.ChatScreenAccess] = _.asInstanceOf 11 12 12 13 var lastMurmur = None: Option[String] 13 - def tick() = 14 + def tickChat() = 14 15 val currentMurmur = MinecraftClient.getInstance.currentScreen match 15 16 case null => None 16 17 case c: ChatScreen => Some(c.chatField.getText) ··· 32 33 import net.minecraft.client.gui.hud.{ChatHud, ChatHudLine, MessageIndicator} 33 34 import net.minecraft.client.gui.screen.ChatScreen 34 35 import net.minecraft.client.gui.widget.TextFieldWidget 35 - import org.eu.net.pool.hexxytounge 36 36 import org.eu.net.pool.phlib.given 37 - import org.spongepowered.asm.mixin.{Mixin, Unique} 38 37 import org.spongepowered.asm.mixin.gen.Accessor 38 + import org.spongepowered.asm.mixin.injection.callback.CallbackInfo 39 39 import org.spongepowered.asm.mixin.injection.{At, Inject} 40 - import org.spongepowered.asm.mixin.injection.callback.CallbackInfo 40 + import org.spongepowered.asm.mixin.{Mixin, Unique} 41 41 42 42 @Mixin(Array(classOf[MinecraftClient])) 43 43 private[mixin] class MinecraftClientMixin: 44 44 @Inject(at = Array(new At(value = "HEAD")), method = Array("tick")) 45 45 def tick(using CallbackInfo) = 46 - hexxytounge.tick() 46 + tickChat() 47 47 @Mixin(Array(classOf[ChatScreen])) 48 48 trait ChatScreenAccess: 49 49 @Accessor("chatField") val chatField: TextFieldWidget ··· 54 54 val p = MinecraftClient.getInstance.player 55 55 if p != null then 56 56 val lines = p.component[RevealComponent].lines.map(line => new ChatHudLine.Visible(currentTick, line.asOrderedText, MessageIndicator.system, true)) 57 - println(lines) 58 57 if lines.nonEmpty then 59 58 lines.reverse ++ original 60 59 else
+2 -2
project/hexxytounge/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/addon/hexxytongue/greater_reveal.json project/hexic/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/addon/hexic/greater_reveal.json
··· 7 7 "Thus, I've devised a new pattern of my own. It's similar to $(l:hexcasting:patterns/basics#hexcasting:print)$(action)Reveal/$, but the message is lodged well within my mind, and I forget it instantly if I replace it with something else. It can also take a list of messages, for convenience.", 8 8 { 9 9 "type": "hexcasting:pattern", 10 - "anchor": "hexxytounge:reveal", 11 - "op_id": "hexxytounge:reveal", 10 + "anchor": "hexic:reveal", 11 + "op_id": "hexic:reveal", 12 12 "input": "[iota] | iota", 13 13 "output": "", 14 14 "text": "Takes a list of iotas (or a single non-iota, which is treated as a list with one element) and embeds them in my mind persistently. Displayed iotas survive all methods that would clear a normal Reveal, and can only be cleared by another casting of Greater Reveal or my untimely demise."
+2 -2
project/hexxytounge/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/zh_cn/entries/addon/hexxytongue/greater_reveal.json project/hexic/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/zh_cn/entries/addon/hexic/greater_reveal.json
··· 7 7 "因此,我自己设计了一个图案。它的功能和$(l:hexcasting:patterns/basics#hexcasting:print)$(action)揭示/$类似,但发来的消息会牢牢嵌在我的意识里,而且一经替换就会立刻遗忘。为方便起见,它还能接受一个消息列表。", 8 8 { 9 9 "type": "hexcasting:pattern", 10 - "anchor": "hexxytounge:reveal", 11 - "op_id": "hexxytounge:reveal", 10 + "anchor": "hexic:reveal", 11 + "op_id": "hexic:reveal", 12 12 "input": "[iota] | iota", 13 13 "output": "", 14 14 "text": "接受 iota 列表(或单个非 iota,此时视作单元素列表)并永久性将其嵌入我的意识。清除普通揭示的方法无法清除此操作展示的 iota,而是只能通过再次施放卓越揭示或死亡清除。"
+3 -3
project/hexxytounge/src/main/resources/assets/hexxytounge/jsonpatch/strings.jsonpatch project/hexic/src/main/resources/assets/hexic/jsonpatch/strings.jsonpatch
··· 3 3 4 4 $pages = arrays.insert($pages, 11, { 5 5 type: "hexcasting:pattern", 6 - op_id: "hexxytounge:murmur", 7 - anchor: "hexxytounge:murmur", 6 + op_id: "hexic:murmur", 7 + anchor: "hexic:murmur", 8 8 input: "", 9 9 output: "str", 10 - text: "book.hexxytounge.page.murmur" 10 + text: "book.hexic.page.murmur" 11 11 });
-4
project/hexxytounge/src/main/resources/assets/hexxytounge/lang/en_us.json
··· 1 - { 2 - "hexcasting.action.hexxytounge:murmur": "Murmur Reflection", 3 - "book.hexxytounge.page.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." 4 - }
-4
project/hexxytounge/src/main/resources/assets/hexxytounge/lang/zh_cn.json
··· 1 - { 2 - "hexcasting.action.hexxytounge:murmur": "私语之精思", 3 - "book.hexxytounge.page.murmur": "找到我意识中名为“聊天栏”的区域,将其内容压栈;无法找到则返回 Null。" 4 - }
+7 -14
project/hexxytounge/src/main/scala/org/eu/net/pool/hexxytounge/main.scala project/hexic/src/main/scala/org/eu/net/pool/hexic/chat.scala
··· 1 - package org.eu.net.pool.hexxytounge 1 + package org.eu.net.pool 2 + package hexic 2 3 3 4 import at.petrak.hexcasting.api.casting.eval.CastingEnvironment 4 5 import at.petrak.hexcasting.api.casting.iota.{Iota, IotaType, ListIota, NullIota} ··· 20 21 import scala.collection.immutable.* 21 22 import scala.language.implicitConversions 22 23 23 - private[hexxytounge] given Logger = LoggerFactory.getLogger("hexxytounge") 24 - private[hexxytounge] given Conversion[String, Identifier] = Identifier.of("hexxytounge", _) 25 - 26 - private[hexxytounge] case class MurmurCache(var value: Option[String]) extends Component: 24 + private[hexic] case class MurmurCache(var value: Option[String]) extends Component: 27 25 override def readFromNbt(tag: NbtCompound): Unit = 28 26 if tag.getBoolean("active") then 29 27 value = Some(tag.getString("value")) ··· 34 32 for value <- value do 35 33 tag.putBoolean("active", true) 36 34 tag.putString("value", value) 37 - private[hexxytounge] object MurmurCache: 35 + private[hexic] object MurmurCache: 38 36 given ComponentKey[MurmurCache] = ComponentRegistry.getOrCreate("murmur", classOf[MurmurCache]) 39 37 40 - private[hexxytounge] case class RevealComponent(var lines: Seq[Text]) extends AutoSyncedComponent: 38 + private[hexic] case class RevealComponent(var lines: Seq[Text]) extends AutoSyncedComponent: 41 39 override def readFromNbt(tag: NbtCompound): Unit = 42 40 lines = for n <- 0 until tag.getInt("lineCount") yield Text.Serializer.fromJson(tag(s"line$n")) // nbt is json apparently? 43 41 override def writeToNbt(tag: NbtCompound): Unit = 44 42 tag.putInt("lineCount", lines.size) 45 43 for (line, n) <- lines.zipWithIndex do tag(s"line$n") = Text.Serializer.toJsonTree(line) 46 - private[hexxytounge] object RevealComponent: 44 + private[hexic] object RevealComponent: 47 45 given ComponentKey[RevealComponent] = ComponentRegistry.getOrCreate("reveal", classOf[RevealComponent]) 48 - 49 - class Components extends EntityComponentInitializer: 50 - override def registerEntityComponentFactories(registry: EntityComponentFactoryRegistry): Unit = 51 - registry.registerForPlayers(summon[ComponentKey[MurmurCache]], _ => MurmurCache(None), RespawnCopyStrategy.ALWAYS_COPY) 52 - registry.registerForPlayers(summon[ComponentKey[RevealComponent]], _ => RevealComponent(Seq.empty), RespawnCopyStrategy.LOSSLESS_ONLY) 53 46 54 47 def keyOf[C <: Component: ComponentKey as key] = key 55 48 ··· 64 57 catch case _: NoSuchElementException => 65 58 None 66 59 67 - def init() = 60 + def initChat() = 68 61 Patterns.register("reveal", ne"deqed" ): 69 62 Patterns.mkConstAction(1, 0): 70 63 case Seq(iota: Iota) =>
+1 -1
settings.gradle.kts
··· 24 24 25 25 include("util") 26 26 includeBuild("plugin") 27 - for (mod in listOf("hexic", "iotaworks", "hexxytounge", "hexxychests")) { 27 + for (mod in listOf("hexic", "iotaworks", "hexxytounge")) { 28 28 include(mod) 29 29 project(":$mod").projectDir = file("project/$mod") 30 30 }
+4
util/src/main/scala/org/eu/net/pool/phlib/main.scala
··· 240 240 else 241 241 `else` 242 242 243 + trait Registered[T](registry: Registry[T], id: Identifier): 244 + this: T => 245 + registry(id) = this 246 + 243 247 extension (p: ServerPlayerEntity) def gimmeIota(iota: Iota): Unit = 244 248 val m = p.getComponent(HexCardinalComponents.STAFFCAST_IMAGE) 245 249 m.setImage(m.getVM(Hand.MAIN_HAND).getImage.withStack(_ ++ Vector(iota)))