diff --git a/.github/workflows/build_docs.yml b/.github/workflows/build_docs.yml index f2d8c7906c..736ec27fd2 100644 --- a/.github/workflows/build_docs.yml +++ b/.github/workflows/build_docs.yml @@ -24,7 +24,7 @@ permissions: jobs: hexdoc: - uses: hexdoc-dev/hexdoc/.github/workflows/hexdoc.yml@main + uses: hexdoc-dev/actions/.github/workflows/hexdoc.yml@v1 permissions: contents: write pages: read @@ -51,7 +51,7 @@ jobs: id-token: write steps: - name: Download package artifact - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: hexdoc-build path: dist diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 2600ad5068..c30d27f7d3 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -11,7 +11,7 @@ on: branches: main env: - JAVA_VERSION: '17.0.1' + JAVA_VERSION: '21.0.5' jobs: build: @@ -74,7 +74,7 @@ jobs: hexdoc: # don't bother running the docs build when pushing to main - nothing necessary to cache here if: github.event_name != 'push' - uses: hexdoc-dev/hexdoc/.github/workflows/hexdoc.yml@main + uses: hexdoc-dev/actions/.github/workflows/hexdoc.yml@v1 permissions: contents: write pages: read diff --git a/Common/build.gradle b/Common/build.gradle index 91a09e78b5..2137b32843 100644 --- a/Common/build.gradle +++ b/Common/build.gradle @@ -1,5 +1,9 @@ architectury { - common(["fabric", "neoforge"]) + common([/*"fabric", */"neoforge"]) +} + +loom { + accessWidenerPath = file("src/main/resources/hexplat.accesswidener") } pkSubproj { @@ -9,6 +13,7 @@ pkSubproj { repositories { mavenCentral() + mavenLocal() maven { url 'https://maven.blamejared.com' } @@ -32,15 +37,19 @@ repositories { dependencies { // === MANDATORY DEPS === - compileOnly "at.petra-k:paucal:$paucalVersion+$minecraftVersion-common" + // We depend on Fabric Loader here to use the Fabric @Environment annotations, + // which get remapped to the correct annotations on each platform. + // Do NOT use other classes from Fabric Loader. + modImplementation "net.fabricmc:fabric-loader:$rootProject.fabric_loader_version" + + modCompileOnly "at.petra-k:paucal:$paucalVersion+$minecraftVersion-common" // i do not know why the xplat and mod jars are in different coordinates - compileOnly "vazkii.patchouli:Patchouli-xplat:1.21-$patchouliVersion-SNAPSHOT" - // inline isn't out for 1.21 yet shaking my sm my shaking smh head -// compileOnly "com.samsthenerd.inline:inline-forge:$minecraftVersion-$inlineVersion" + modCompileOnly "vazkii.patchouli:Patchouli-xplat:1.21-$patchouliVersion-SNAPSHOT" + modCompileOnly "com.samsthenerd.inline:inline-common:1.21.1-1.2.2-74" // === OPTIONAL DEPS === modCompileOnly "dev.emi:emi-xplat-intermediary:${emiVersion}:api" - compileOnly "io.wispforest:accessories-common:$accessoriesVersion" + modCompileOnly "io.wispforest:accessories-common:$accessoriesVersion" // === OTHER STUFF === compileOnly "org.jetbrains:annotations:$jetbrainsAnnotationsVersion" diff --git a/Common/src/generated/resources/.cache/8f7cd5c924d3264b7777ef1696459761f9a70902 b/Common/src/generated/resources/.cache/8f7cd5c924d3264b7777ef1696459761f9a70902 index 8cf64135d8..65cd7f4b28 100644 --- a/Common/src/generated/resources/.cache/8f7cd5c924d3264b7777ef1696459761f9a70902 +++ b/Common/src/generated/resources/.cache/8f7cd5c924d3264b7777ef1696459761f9a70902 @@ -1,4 +1,4 @@ -// 1.20.1 2023-12-24T17:59:13.7584156 Item Models: hexcasting +// 1.20.1 2024-12-10T14:26:44.916295 Item Models: hexcasting 2fc68dcd6d73da3deaa6a33240dd9160a2b79592 assets/hexcasting/models/block/deco/quenched_allay_bricks_0.json d59af7a48b20b210240b26115fb172d6202f9254 assets/hexcasting/models/block/deco/quenched_allay_bricks_1.json a62eeebbca2d145c22f25725bd848ed4d673cefa assets/hexcasting/models/block/deco/quenched_allay_bricks_2.json @@ -19,6 +19,22 @@ f2156b3a7041cf99891b528393db64c6b9ca1a4f assets/hexcasting/models/item/abacus.js 19730853397b109cfedd0c3bbda83d5de6cd15b9 assets/hexcasting/models/item/akashic_record.json 8c735feff09d46d00ed681311f46f61a50cfdc9b assets/hexcasting/models/item/amethyst_dust.json fbb8706993fbc3246c56b9f3eb274ff8968b70f8 assets/hexcasting/models/item/amethyst_pillar.json +533a859174052a332de069b2ffeaf0106d132b9a assets/hexcasting/models/item/ancient_cypher.json +71a7968e43fbb872ee52315a3ee738d0b3fd1a69 assets/hexcasting/models/item/ancient_cypher_0_filled.json +0f0c627d7ed0e8a7e3666ca80ddc13b280d6ce9f assets/hexcasting/models/item/ancient_cypher_1.json +097b8ecfb34df710ca4b396d3a5df7722ecc3596 assets/hexcasting/models/item/ancient_cypher_1_filled.json +9fdde927e7e8b06221aef34a6a6b22d0b790f297 assets/hexcasting/models/item/ancient_cypher_2.json +93257ad393b751931539a5641d4430a4631e95f9 assets/hexcasting/models/item/ancient_cypher_2_filled.json +4af6234e24031ee0989282c8435fe07e85b02771 assets/hexcasting/models/item/ancient_cypher_3.json +41760f3c89d8dc94c515b0ab8220ecf996710a3c assets/hexcasting/models/item/ancient_cypher_3_filled.json +4df83ae775400ca2d480bfb3621abcf58d4d7352 assets/hexcasting/models/item/ancient_cypher_4.json +d21eb7093c0231015808a8b51b27857da1748431 assets/hexcasting/models/item/ancient_cypher_4_filled.json +e2b4e2ac4ad4fa4b490e1774a565a26fb840c474 assets/hexcasting/models/item/ancient_cypher_5.json +4555e5de80047ffa4e72a4a98eb51437a95e7291 assets/hexcasting/models/item/ancient_cypher_5_filled.json +420840b5761fcddbdd10186f3127bc7589badc46 assets/hexcasting/models/item/ancient_cypher_6.json +55c08581a2e8c7134d63b38226bddafff0fba3ae assets/hexcasting/models/item/ancient_cypher_6_filled.json +2731192f0c7a9a8d45ba4fcd8d1de60bade0b49e assets/hexcasting/models/item/ancient_cypher_7.json +7ba3015d79601f1c8238dbac4a45e525e3589f16 assets/hexcasting/models/item/ancient_cypher_7_filled.json 87e7ee44cdd0808a3dd72babfd1db716df2bcdfe assets/hexcasting/models/item/artifact.json 1cd1b4d002d1a9a044ceab7cca842e4a2b7bd2f4 assets/hexcasting/models/item/artifact_0_filled.json 4709e65d8e74cf45b3ba014bdf70373728cccc78 assets/hexcasting/models/item/artifact_1.json diff --git a/Common/src/generated/resources/assets/hexcasting/blockstates/amethyst_sconce.json b/Common/src/generated/resources/assets/hexcasting/blockstates/amethyst_sconce.json index af52410929..10507061f7 100644 --- a/Common/src/generated/resources/assets/hexcasting/blockstates/amethyst_sconce.json +++ b/Common/src/generated/resources/assets/hexcasting/blockstates/amethyst_sconce.json @@ -1,7 +1,30 @@ { "variants": { - "": { + "facing=down": { + "model": "hexcasting:block/amethyst_sconce", + "x": 180 + }, + "facing=east": { + "model": "hexcasting:block/amethyst_sconce", + "x": 90, + "y": 90 + }, + "facing=north": { + "model": "hexcasting:block/amethyst_sconce", + "x": 90 + }, + "facing=south": { + "model": "hexcasting:block/amethyst_sconce", + "x": 90, + "y": 180 + }, + "facing=up": { "model": "hexcasting:block/amethyst_sconce" + }, + "facing=west": { + "model": "hexcasting:block/amethyst_sconce", + "x": 90, + "y": 270 } } } \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher.json b/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher.json new file mode 100644 index 0000000000..ffc8b5e1cc --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher.json @@ -0,0 +1,120 @@ +{ + "parent": "minecraft:item/generated", + "overrides": [ + { + "model": "hexcasting:item/ancient_cypher", + "predicate": { + "hexcasting:has_patterns": -0.01, + "hexcasting:variant": 0.0 + } + }, + { + "model": "hexcasting:item/ancient_cypher_0_filled", + "predicate": { + "hexcasting:has_patterns": 0.99, + "hexcasting:variant": 0.0 + } + }, + { + "model": "hexcasting:item/ancient_cypher_1", + "predicate": { + "hexcasting:has_patterns": -0.01, + "hexcasting:variant": 1.0 + } + }, + { + "model": "hexcasting:item/ancient_cypher_1_filled", + "predicate": { + "hexcasting:has_patterns": 0.99, + "hexcasting:variant": 1.0 + } + }, + { + "model": "hexcasting:item/ancient_cypher_2", + "predicate": { + "hexcasting:has_patterns": -0.01, + "hexcasting:variant": 2.0 + } + }, + { + "model": "hexcasting:item/ancient_cypher_2_filled", + "predicate": { + "hexcasting:has_patterns": 0.99, + "hexcasting:variant": 2.0 + } + }, + { + "model": "hexcasting:item/ancient_cypher_3", + "predicate": { + "hexcasting:has_patterns": -0.01, + "hexcasting:variant": 3.0 + } + }, + { + "model": "hexcasting:item/ancient_cypher_3_filled", + "predicate": { + "hexcasting:has_patterns": 0.99, + "hexcasting:variant": 3.0 + } + }, + { + "model": "hexcasting:item/ancient_cypher_4", + "predicate": { + "hexcasting:has_patterns": -0.01, + "hexcasting:variant": 4.0 + } + }, + { + "model": "hexcasting:item/ancient_cypher_4_filled", + "predicate": { + "hexcasting:has_patterns": 0.99, + "hexcasting:variant": 4.0 + } + }, + { + "model": "hexcasting:item/ancient_cypher_5", + "predicate": { + "hexcasting:has_patterns": -0.01, + "hexcasting:variant": 5.0 + } + }, + { + "model": "hexcasting:item/ancient_cypher_5_filled", + "predicate": { + "hexcasting:has_patterns": 0.99, + "hexcasting:variant": 5.0 + } + }, + { + "model": "hexcasting:item/ancient_cypher_6", + "predicate": { + "hexcasting:has_patterns": -0.01, + "hexcasting:variant": 6.0 + } + }, + { + "model": "hexcasting:item/ancient_cypher_6_filled", + "predicate": { + "hexcasting:has_patterns": 0.99, + "hexcasting:variant": 6.0 + } + }, + { + "model": "hexcasting:item/ancient_cypher_7", + "predicate": { + "hexcasting:has_patterns": -0.01, + "hexcasting:variant": 7.0 + } + }, + { + "model": "hexcasting:item/ancient_cypher_7_filled", + "predicate": { + "hexcasting:has_patterns": 0.99, + "hexcasting:variant": 7.0 + } + } + ], + "textures": { + "layer0": "hexcasting:item/cad/0_ancient_cypher" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_0_filled.json b/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_0_filled.json new file mode 100644 index 0000000000..b38ad18d6d --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_0_filled.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "hexcasting:item/cad/0_ancient_cypher", + "layer1": "hexcasting:item/cad/0_ancient_cypher_overlay" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_1.json b/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_1.json new file mode 100644 index 0000000000..e8b7b12d55 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_1.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "hexcasting:item/cad/1_ancient_cypher" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_1_filled.json b/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_1_filled.json new file mode 100644 index 0000000000..856b0a26d7 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_1_filled.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "hexcasting:item/cad/1_ancient_cypher", + "layer1": "hexcasting:item/cad/1_ancient_cypher_overlay" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_2.json b/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_2.json new file mode 100644 index 0000000000..3badfcdd0f --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_2.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "hexcasting:item/cad/2_ancient_cypher" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_2_filled.json b/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_2_filled.json new file mode 100644 index 0000000000..effb9e0198 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_2_filled.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "hexcasting:item/cad/2_ancient_cypher", + "layer1": "hexcasting:item/cad/2_ancient_cypher_overlay" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_3.json b/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_3.json new file mode 100644 index 0000000000..98aabd91e8 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_3.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "hexcasting:item/cad/3_ancient_cypher" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_3_filled.json b/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_3_filled.json new file mode 100644 index 0000000000..2f19e9feea --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_3_filled.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "hexcasting:item/cad/3_ancient_cypher", + "layer1": "hexcasting:item/cad/3_ancient_cypher_overlay" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_4.json b/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_4.json new file mode 100644 index 0000000000..93318f7bc4 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_4.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "hexcasting:item/cad/4_ancient_cypher" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_4_filled.json b/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_4_filled.json new file mode 100644 index 0000000000..081cfd65c4 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_4_filled.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "hexcasting:item/cad/4_ancient_cypher", + "layer1": "hexcasting:item/cad/4_ancient_cypher_overlay" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_5.json b/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_5.json new file mode 100644 index 0000000000..9d247cdd23 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_5.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "hexcasting:item/cad/5_ancient_cypher" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_5_filled.json b/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_5_filled.json new file mode 100644 index 0000000000..0ed6accc2a --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_5_filled.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "hexcasting:item/cad/5_ancient_cypher", + "layer1": "hexcasting:item/cad/5_ancient_cypher_overlay" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_6.json b/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_6.json new file mode 100644 index 0000000000..bf9c9fe505 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_6.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "hexcasting:item/cad/6_ancient_cypher" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_6_filled.json b/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_6_filled.json new file mode 100644 index 0000000000..199292d90f --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_6_filled.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "hexcasting:item/cad/6_ancient_cypher", + "layer1": "hexcasting:item/cad/6_ancient_cypher_overlay" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_7.json b/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_7.json new file mode 100644 index 0000000000..56e0653080 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_7.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "hexcasting:item/cad/7_ancient_cypher" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_7_filled.json b/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_7_filled.json new file mode 100644 index 0000000000..b408892c14 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/item/ancient_cypher_7_filled.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "hexcasting:item/cad/7_ancient_cypher", + "layer1": "hexcasting:item/cad/7_ancient_cypher_overlay" + } +} \ No newline at end of file diff --git a/Common/src/main/java/at/petrak/hexcasting/api/HexAPI.java b/Common/src/main/java/at/petrak/hexcasting/api/HexAPI.java index 8ddde5669b..37a1f59371 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/HexAPI.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/HexAPI.java @@ -29,6 +29,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Collections; import java.util.function.Consumer; import java.util.function.Supplier; @@ -165,49 +166,15 @@ default FrozenPigment getColorizer(Player player) { return FrozenPigment.DEFAULT.get(); } - ArmorMaterial DUMMY_ARMOR_MATERIAL = new ArmorMaterial() { - @Override - public int getDurabilityForType(ArmorItem.Type type) { - return 0; - } - - @Override - public int getDefenseForType(ArmorItem.Type type) { - return 0; - } - - @Override - public int getEnchantmentValue() { - return 0; - } - - @NotNull - @Override - public SoundEvent getEquipSound() { - return SoundEvents.ARMOR_EQUIP_LEATHER; - } - - @NotNull - @Override - public Ingredient getRepairIngredient() { - return Ingredient.EMPTY; - } - - @Override - public String getName() { - return "missingno"; - } - - @Override - public float getToughness() { - return 0; - } - - @Override - public float getKnockbackResistance() { - return 0; - } - }; + ArmorMaterial DUMMY_ARMOR_MATERIAL = new ArmorMaterial( + Collections.emptyMap(), + 0, + SoundEvents.ARMOR_EQUIP_LEATHER, + () -> Ingredient.EMPTY, + Collections.emptyList(), + 0, + 0 + ); default ArmorMaterial robesMaterial() { return DUMMY_ARMOR_MATERIAL; @@ -217,10 +184,6 @@ default ArmorMaterial robesMaterial() { * Location in the userdata of the ravenmind */ String RAVENMIND_USERDATA = modLoc("ravenmind").toString(); - /** - * Location in the userdata of the number of ops executed - */ - String OP_COUNT_USERDATA = modLoc("op_count").toString(); String MARKED_MOVED_USERDATA = modLoc("impulsed").toString(); @@ -229,6 +192,6 @@ static HexAPI instance() { } static ResourceLocation modLoc(String s) { - return new ResourceLocation(MOD_ID, s); + return ResourceLocation.fromNamespaceAndPath(MOD_ID, s); } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/addldata/ADIotaHolder.java b/Common/src/main/java/at/petrak/hexcasting/api/addldata/ADIotaHolder.java index 7b8fcc1c95..0ab8836c9f 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/addldata/ADIotaHolder.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/addldata/ADIotaHolder.java @@ -7,18 +7,9 @@ import org.jetbrains.annotations.Nullable; public interface ADIotaHolder { - @Nullable - CompoundTag readIotaTag(); @Nullable - default Iota readIota(ServerLevel world) { - var tag = readIotaTag(); - if (tag != null) { - return IotaType.deserialize(tag, world); - } else { - return null; - } - } + Iota readIota(); @Nullable default Iota emptyIota() { diff --git a/Common/src/main/java/at/petrak/hexcasting/api/addldata/ItemDelegatingEntityIotaHolder.java b/Common/src/main/java/at/petrak/hexcasting/api/addldata/ItemDelegatingEntityIotaHolder.java index 5af67a99ab..8bad581fcb 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/addldata/ItemDelegatingEntityIotaHolder.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/addldata/ItemDelegatingEntityIotaHolder.java @@ -23,12 +23,6 @@ public ItemDelegatingEntityIotaHolder(Supplier stackSupplier, Consume this.save = save; } - @Override - public @Nullable CompoundTag readIotaTag() { - var delegate = IXplatAbstractions.INSTANCE.findDataHolder(this.stackSupplier.get()); - return delegate == null ? null : delegate.readIotaTag(); - } - @Override public boolean writeable() { var delegate = IXplatAbstractions.INSTANCE.findDataHolder(this.stackSupplier.get()); @@ -47,9 +41,9 @@ public boolean writeIota(@Nullable Iota datum, boolean simulate) { } @Override - public @Nullable Iota readIota(ServerLevel world) { + public @Nullable Iota readIota() { var delegate = IXplatAbstractions.INSTANCE.findDataHolder(this.stackSupplier.get()); - return delegate == null ? null : delegate.readIota(world); + return delegate == null ? null : delegate.readIota(); } @Override diff --git a/Common/src/main/java/at/petrak/hexcasting/api/advancements/FailToCastGreatSpellTrigger.java b/Common/src/main/java/at/petrak/hexcasting/api/advancements/FailToCastGreatSpellTrigger.java index fe85fec5b3..f58dfab3a9 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/advancements/FailToCastGreatSpellTrigger.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/advancements/FailToCastGreatSpellTrigger.java @@ -1,39 +1,38 @@ package at.petrak.hexcasting.api.advancements; -import com.google.gson.JsonObject; -import net.minecraft.advancements.critereon.*; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.advancements.critereon.ContextAwarePredicate; +import net.minecraft.advancements.critereon.EntityPredicate; +import net.minecraft.advancements.critereon.SimpleCriterionTrigger; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerPlayer; -public class FailToCastGreatSpellTrigger extends SimpleCriterionTrigger { - private static final ResourceLocation ID = new ResourceLocation("hexcasting", "fail_to_cast_great_spell"); +import java.util.Optional; - @Override - public ResourceLocation getId() { - return ID; - } +public class FailToCastGreatSpellTrigger extends SimpleCriterionTrigger { + private static final ResourceLocation ID = ResourceLocation.fromNamespaceAndPath("hexcasting", "fail_to_cast_great_spell"); @Override - protected Instance createInstance(JsonObject json, ContextAwarePredicate predicate, DeserializationContext context) { - return new Instance(predicate); + public Codec codec() { + return Instance.CODEC; } public void trigger(ServerPlayer player) { super.trigger(player, e -> true); } - public static class Instance extends AbstractCriterionTriggerInstance { - public Instance(ContextAwarePredicate predicate) { - super(ID, predicate); - } + public static record Instance(Optional player) implements SimpleCriterionTrigger.SimpleInstance { + public static final Codec CODEC = RecordCodecBuilder.create( + p_337348_ -> p_337348_.group( + EntityPredicate.ADVANCEMENT_CODEC.optionalFieldOf("player").forGetter(FailToCastGreatSpellTrigger.Instance::player) + ) + .apply(p_337348_, FailToCastGreatSpellTrigger.Instance::new) + ); @Override - public ResourceLocation getCriterion() { - return ID; - } - - public JsonObject serializeToJson(SerializationContext pConditions) { - return new JsonObject(); + public Optional player() { + return player; } } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/advancements/HexAdvancementTriggers.java b/Common/src/main/java/at/petrak/hexcasting/api/advancements/HexAdvancementTriggers.java index 16af02ab39..36d051ab96 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/advancements/HexAdvancementTriggers.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/advancements/HexAdvancementTriggers.java @@ -1,15 +1,35 @@ package at.petrak.hexcasting.api.advancements; -import at.petrak.hexcasting.mixin.accessor.CriteriaTriggersAccessor; +import net.minecraft.advancements.CriterionTrigger; +import net.minecraft.resources.ResourceLocation; + +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.function.BiConsumer; + +import static at.petrak.hexcasting.api.HexAPI.modLoc; public class HexAdvancementTriggers { - public static final OvercastTrigger OVERCAST_TRIGGER = new OvercastTrigger(); - public static final SpendMediaTrigger SPEND_MEDIA_TRIGGER = new SpendMediaTrigger(); - public static final FailToCastGreatSpellTrigger FAIL_GREAT_SPELL_TRIGGER = new FailToCastGreatSpellTrigger(); - - public static void registerTriggers() { - CriteriaTriggersAccessor.hex$register(OVERCAST_TRIGGER); - CriteriaTriggersAccessor.hex$register(SPEND_MEDIA_TRIGGER); - CriteriaTriggersAccessor.hex$register(FAIL_GREAT_SPELL_TRIGGER); + private static final Map> TRIGGERS = new LinkedHashMap<>(); + + public static final OvercastTrigger OVERCAST_TRIGGER = register("overcast", new OvercastTrigger()); + public static final SpendMediaTrigger SPEND_MEDIA_TRIGGER = register("spend_media", new SpendMediaTrigger()); + public static final FailToCastGreatSpellTrigger FAIL_GREAT_SPELL_TRIGGER = register("fail_to_cast_great_spell", new FailToCastGreatSpellTrigger()); + + public static void registerTriggers(BiConsumer, ResourceLocation> r) { + for (var e : TRIGGERS.entrySet()) { + r.accept(e.getValue(), e.getKey()); + } + } + + private static > T register( + String id, + T lift + ) { + var old = TRIGGERS.put(modLoc(id), lift); + if (old != null) { + throw new IllegalArgumentException("Typo? Duplicate id " + id); + } + return lift; } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/advancements/MinMaxLongs.java b/Common/src/main/java/at/petrak/hexcasting/api/advancements/MinMaxLongs.java index 0be502c86e..e6ba6a91a1 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/advancements/MinMaxLongs.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/advancements/MinMaxLongs.java @@ -1,85 +1,65 @@ package at.petrak.hexcasting.api.advancements; -import com.google.gson.JsonElement; import com.mojang.brigadier.StringReader; -import com.mojang.brigadier.exceptions.BuiltInExceptionProvider; import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.serialization.Codec; import net.minecraft.advancements.critereon.MinMaxBounds; -import net.minecraft.util.GsonHelper; -import javax.annotation.Nullable; -import java.util.Objects; +import java.util.Optional; import java.util.function.Function; -public class MinMaxLongs extends MinMaxBounds { - public static final MinMaxLongs ANY = new MinMaxLongs(null, null); - @Nullable - private final Long minSq; - @Nullable - private final Long maxSq; +public record MinMaxLongs(Optional min, Optional max, Optional minSq, Optional maxSq) implements MinMaxBounds { + public static final Codec CODEC = MinMaxBounds.createCodec(Codec.LONG, MinMaxLongs::new); - private static MinMaxLongs create(StringReader reader, @Nullable Long min, @Nullable Long max) throws CommandSyntaxException { - if (min != null && max != null && min > max) { + public static final MinMaxLongs ANY = new MinMaxLongs(Optional.empty(), Optional.empty()); + + private MinMaxLongs(Optional min, Optional max) { + this(min, max, squareOpt(min), squareOpt(max)); + } + + private static MinMaxLongs create(StringReader reader, Optional min, Optional max) throws CommandSyntaxException { + if (min.isPresent() && max.isPresent() && min.get() > max.get()) { throw ERROR_SWAPPED.createWithContext(reader); } else { return new MinMaxLongs(min, max); } } - @Nullable - private static Long squareOpt(@Nullable Long l) { - return l == null ? null : l * l; - } - - private MinMaxLongs(@Nullable Long min, @Nullable Long max) { - super(min, max); - this.minSq = squareOpt(min); - this.maxSq = squareOpt(max); + private static Optional squareOpt(Optional value) { + return value.map(p_297909_ -> p_297909_ * p_297909_); } public static MinMaxLongs exactly(long l) { - return new MinMaxLongs(l, l); + return new MinMaxLongs(Optional.of(l), Optional.of(l)); } public static MinMaxLongs between(long min, long max) { - return new MinMaxLongs(min, max); + return new MinMaxLongs(Optional.of(min), Optional.of(max)); } public static MinMaxLongs atLeast(long min) { - return new MinMaxLongs(min, null); + return new MinMaxLongs(Optional.of(min), Optional.empty()); } public static MinMaxLongs atMost(long max) { - return new MinMaxLongs(null, max); + return new MinMaxLongs(Optional.empty(), Optional.of(max)); } - public boolean matches(long l) { - if (this.min != null && this.min > l) { - return false; - } else { - return this.max == null || this.max >= l; - } - } - - public boolean matchesSqr(long l) { - if (this.minSq != null && this.minSq > l) { - return false; - } else { - return this.maxSq == null || this.maxSq >= l; - } + public boolean matches(long value) { + return (this.min.isEmpty() || this.min.get() <= value) && (this.max.isEmpty() || this.max.get() >= value); } - public static MinMaxLongs fromJson(@Nullable JsonElement json) { - return fromJson(json, ANY, GsonHelper::convertToLong, MinMaxLongs::new); + public boolean matchesSqr(long value) { + return (this.minSq.isEmpty() || this.minSq.get() <= value) && (this.maxSq.isEmpty() || this.maxSq.get() >= value); } public static MinMaxLongs fromReader(StringReader reader) throws CommandSyntaxException { return fromReader(reader, (l) -> l); } - public static MinMaxLongs fromReader(StringReader reader, Function map) throws CommandSyntaxException { - BuiltInExceptionProvider builtInExceptions = CommandSyntaxException.BUILT_IN_EXCEPTIONS; - Objects.requireNonNull(builtInExceptions); - return fromReader(reader, MinMaxLongs::create, Long::parseLong, builtInExceptions::readerInvalidInt, map); + public static MinMaxLongs fromReader(StringReader reader, Function formatter) throws CommandSyntaxException { + return MinMaxBounds.fromReader( + reader, MinMaxLongs::create, Long::parseLong, CommandSyntaxException.BUILT_IN_EXCEPTIONS::readerInvalidLong, formatter + ); } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/advancements/OvercastTrigger.java b/Common/src/main/java/at/petrak/hexcasting/api/advancements/OvercastTrigger.java index b1661e869e..d98f9ca773 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/advancements/OvercastTrigger.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/advancements/OvercastTrigger.java @@ -2,34 +2,23 @@ import at.petrak.hexcasting.api.mod.HexConfig; import com.google.gson.JsonObject; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.advancements.critereon.*; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerPlayer; +import java.util.Optional; + // https://github.com/TelepathicGrunt/Bumblezone/blob/latest-released/src/main/java/com/telepathicgrunt/the_bumblezone/advancements/CleanupStickyHoneyResidueTrigger.java // https://github.com/VazkiiMods/Botania/blob/b8706e2e0bba20f67f1e103559a4ce39d63d48f9/src/main/java/vazkii/botania/common/advancements/CorporeaRequestTrigger.java public class OvercastTrigger extends SimpleCriterionTrigger { - private static final ResourceLocation ID = new ResourceLocation("hexcasting", "overcast"); - - private static final String TAG_MEDIA_GENERATED = "media_generated"; - private static final String TAG_HEALTH_USED = "health_used"; - // HEY KIDS DID YOYU KNOW THERE'S NOT A CRITERIA FOR HOW MUCH ***HEALTH*** AN ENTITY HAS - private static final String TAG_HEALTH_LEFT = - "mojang_i_am_begging_and_crying_please_add_an_entity_health_criterion"; - - @Override - public ResourceLocation getId() { - return ID; - } + private static final ResourceLocation ID = ResourceLocation.fromNamespaceAndPath("hexcasting", "overcast"); @Override - protected Instance createInstance(JsonObject json, ContextAwarePredicate predicate, - DeserializationContext pContext) { - return new Instance(predicate, - MinMaxBounds.Ints.fromJson(json.get(TAG_MEDIA_GENERATED)), - MinMaxBounds.Doubles.fromJson(json.get(TAG_HEALTH_USED)), - MinMaxBounds.Doubles.fromJson(json.get(TAG_HEALTH_LEFT))); + public Codec codec() { + return Instance.CODEC; } public void trigger(ServerPlayer player, int mediaGenerated) { @@ -40,41 +29,25 @@ public void trigger(ServerPlayer player, int mediaGenerated) { }); } - public static class Instance extends AbstractCriterionTriggerInstance { - protected final MinMaxBounds.Ints mediaGenerated; - // This is the *proporttion* of the health bar. - protected final MinMaxBounds.Doubles healthUsed; - // DID YOU KNOW THERES ONE TO CHECK THE WORLD TIME, BUT NOT THE HEALTH!? - protected final MinMaxBounds.Doubles healthLeft; - - public Instance(ContextAwarePredicate predicate, MinMaxBounds.Ints mediaGenerated, - MinMaxBounds.Doubles healthUsed, MinMaxBounds.Doubles healthLeft) { - super(OvercastTrigger.ID, predicate); - this.mediaGenerated = mediaGenerated; - this.healthUsed = healthUsed; + public static record Instance( + Optional player, + MinMaxBounds.Ints mediaGenerated, + // This is the *proporttion* of the health bar. + MinMaxBounds.Doubles healthUsed, + // DID YOU KNOW THERES ONE TO CHECK THE WORLD TIME, BUT NOT THE HEALTH!? + MinMaxBounds.Doubles healthLeft // DID YOU KNOW THERE'S ONE TO CHECK THE FUCKING C A T T Y P E BUT NOT THE HEALTH - this.healthLeft = healthLeft; - } - - @Override - public ResourceLocation getCriterion() { - return ID; - } - - @Override - public JsonObject serializeToJson(SerializationContext ctx) { - JsonObject json = super.serializeToJson(ctx); - if (!this.mediaGenerated.isAny()) { - json.add(TAG_MEDIA_GENERATED, this.mediaGenerated.serializeToJson()); - } - if (!this.healthUsed.isAny()) { - json.add(TAG_HEALTH_USED, this.healthUsed.serializeToJson()); - } - if (!this.healthLeft.isAny()) { - json.add(TAG_HEALTH_LEFT, this.healthLeft.serializeToJson()); - } - return json; - } + ) implements SimpleCriterionTrigger.SimpleInstance { + public static final Codec CODEC = RecordCodecBuilder.create( + inst -> inst.group( + EntityPredicate.ADVANCEMENT_CODEC.optionalFieldOf("player").forGetter(Instance::player), + MinMaxBounds.Ints.CODEC.fieldOf("media_generated").forGetter(Instance::mediaGenerated), + MinMaxBounds.Doubles.CODEC.fieldOf("health_used").forGetter(Instance::healthUsed), + // HEY KIDS DID YOYU KNOW THERE'S NOT A CRITERIA FOR HOW MUCH ***HEALTH*** AN ENTITY HAS + MinMaxBounds.Doubles.CODEC.fieldOf("mojang_i_am_begging_and_crying_please_add_an_entity_health_criterion").forGetter(Instance::healthLeft) + ) + .apply(inst, Instance::new) + ); private boolean test(int mediaGeneratedIn, double healthUsedIn, float healthLeftIn) { return this.mediaGenerated.matches(mediaGeneratedIn) diff --git a/Common/src/main/java/at/petrak/hexcasting/api/advancements/SpendMediaTrigger.java b/Common/src/main/java/at/petrak/hexcasting/api/advancements/SpendMediaTrigger.java index d610807f59..4d56e48828 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/advancements/SpendMediaTrigger.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/advancements/SpendMediaTrigger.java @@ -1,60 +1,39 @@ package at.petrak.hexcasting.api.advancements; import com.google.gson.JsonObject; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.advancements.critereon.*; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerPlayer; -public class SpendMediaTrigger extends SimpleCriterionTrigger { - private static final ResourceLocation ID = new ResourceLocation("hexcasting", "spend_media"); - - private static final String TAG_MEDIA_SPENT = "media_spent"; - private static final String TAG_MEDIA_WASTED = "media_wasted"; +import java.util.Optional; - @Override - public ResourceLocation getId() { - return ID; - } +public class SpendMediaTrigger extends SimpleCriterionTrigger { + private static final ResourceLocation ID = ResourceLocation.fromNamespaceAndPath("hexcasting", "spend_media"); @Override - protected Instance createInstance(JsonObject json, ContextAwarePredicate predicate, - DeserializationContext context) { - return new Instance(predicate, - MinMaxLongs.fromJson(json.get(TAG_MEDIA_SPENT)), - MinMaxLongs.fromJson(json.get(TAG_MEDIA_WASTED))); + public Codec codec() { + return Instance.CODEC; } public void trigger(ServerPlayer player, long mediaSpent, long mediaWasted) { super.trigger(player, inst -> inst.test(mediaSpent, mediaWasted)); } - public static class Instance extends AbstractCriterionTriggerInstance { - protected final MinMaxLongs mediaSpent; - protected final MinMaxLongs mediaWasted; - - public Instance(ContextAwarePredicate predicate, MinMaxLongs mediaSpent, - MinMaxLongs mediaWasted) { - super(SpendMediaTrigger.ID, predicate); - this.mediaSpent = mediaSpent; - this.mediaWasted = mediaWasted; - } - - @Override - public ResourceLocation getCriterion() { - return ID; - } - - @Override - public JsonObject serializeToJson(SerializationContext ctx) { - JsonObject json = super.serializeToJson(ctx); - if (!this.mediaSpent.isAny()) { - json.add(TAG_MEDIA_SPENT, this.mediaSpent.serializeToJson()); - } - if (!this.mediaWasted.isAny()) { - json.add(TAG_MEDIA_WASTED, this.mediaWasted.serializeToJson()); - } - return json; - } + public static record Instance( + Optional player, + MinMaxLongs mediaSpent, + MinMaxLongs mediaWasted + ) implements SimpleCriterionTrigger.SimpleInstance { + public static final Codec CODEC = RecordCodecBuilder.create( + inst -> inst.group( + EntityPredicate.ADVANCEMENT_CODEC.optionalFieldOf("player").forGetter(Instance::player), + MinMaxLongs.CODEC.fieldOf("media_generated").forGetter(Instance::mediaSpent), + MinMaxLongs.CODEC.fieldOf("health_used").forGetter(Instance::mediaWasted) + ) + .apply(inst, Instance::new) + ); private boolean test(long mediaSpentIn, long mediaWastedIn) { return this.mediaSpent.matches(mediaSpentIn) && this.mediaWasted.matches(mediaWastedIn); diff --git a/Common/src/main/java/at/petrak/hexcasting/api/block/HexBlockEntity.java b/Common/src/main/java/at/petrak/hexcasting/api/block/HexBlockEntity.java index e531ddb12d..b7eb267b7c 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/block/HexBlockEntity.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/block/HexBlockEntity.java @@ -1,6 +1,7 @@ package at.petrak.hexcasting.api.block; import net.minecraft.core.BlockPos; +import net.minecraft.core.HolderLookup; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.game.ClientGamePacketListener; @@ -14,25 +15,26 @@ public HexBlockEntity(BlockEntityType pType, BlockPos pWorldPosition, BlockSt super(pType, pWorldPosition, pBlockState); } - protected abstract void saveModData(CompoundTag tag); + protected abstract void saveModData(CompoundTag tag, HolderLookup.Provider registries); - protected abstract void loadModData(CompoundTag tag); + protected abstract void loadModData(CompoundTag tag, HolderLookup.Provider registries); @Override - protected void saveAdditional(CompoundTag pTag) { - this.saveModData(pTag); + protected void saveAdditional(CompoundTag pTag, HolderLookup.Provider registries) { + super.saveAdditional(pTag, registries); + this.saveModData(pTag, registries); } @Override - public void load(CompoundTag pTag) { - super.load(pTag); - this.loadModData(pTag); + public void loadAdditional(CompoundTag pTag, HolderLookup.Provider registries) { + super.loadAdditional(pTag, registries); + this.loadModData(pTag, registries); } @Override - public CompoundTag getUpdateTag() { + public CompoundTag getUpdateTag(HolderLookup.Provider registries) { CompoundTag tag = new CompoundTag(); - this.saveModData(tag); + this.saveModData(tag, registries); return tag; } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/block/circle/BlockAbstractImpetus.java b/Common/src/main/java/at/petrak/hexcasting/api/block/circle/BlockAbstractImpetus.java index d5197fce68..1dbe8052d6 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/block/circle/BlockAbstractImpetus.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/block/circle/BlockAbstractImpetus.java @@ -13,6 +13,7 @@ import net.minecraft.world.level.block.EntityBlock; import net.minecraft.world.level.block.Mirror; import net.minecraft.world.level.block.Rotation; +import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.StateDefinition; import net.minecraft.world.level.block.state.properties.BlockStateProperties; @@ -30,6 +31,8 @@ public BlockAbstractImpetus(Properties p_49795_) { this.stateDefinition.any().setValue(ENERGIZED, false).setValue(FACING, Direction.NORTH)); } + public abstract BlockEntityType getBlockEntityType(); + @Override public ControlFlow acceptControlFlow(CastingImage imageIn, CircleCastEnv env, Direction enterDir, BlockPos pos, BlockState bs, ServerLevel world) { diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/ActionUtils.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/ActionUtils.kt index c6dda37c9a..eaa9cc1e75 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/ActionUtils.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/ActionUtils.kt @@ -4,11 +4,13 @@ package at.petrak.hexcasting.api.casting import at.petrak.hexcasting.api.casting.iota.* import at.petrak.hexcasting.api.casting.math.HexPattern +import at.petrak.hexcasting.api.casting.mishaps.MishapEntityUnavailable import at.petrak.hexcasting.api.casting.mishaps.MishapInvalidIota import at.petrak.hexcasting.api.casting.mishaps.MishapNotEnoughArgs import at.petrak.hexcasting.api.utils.asTranslatedComponent import com.mojang.datafixers.util.Either import net.minecraft.core.BlockPos +import net.minecraft.server.level.ServerLevel import net.minecraft.server.level.ServerPlayer import net.minecraft.world.entity.Entity import net.minecraft.world.entity.LivingEntity @@ -32,10 +34,28 @@ fun List.getDouble(idx: Int, argc: Int = 0): Double { } } -fun List.getEntity(idx: Int, argc: Int = 0): Entity { +fun List.getEntity(level: ServerLevel, idx: Int, argc: Int = 0): Entity { val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) } if (x is EntityIota) { - return x.entity + return x.getOrFindEntity(level) ?: throw MishapEntityUnavailable(x.entityId, x.cachedEntityName) + } else { + throw MishapInvalidIota.ofType(x, if (argc == 0) idx else argc - (idx + 1), "entity") + } +} + +fun List.getOrFindEntity(level: ServerLevel, idx: Int, argc: Int = 0): Entity? { + val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) } + if (x is EntityIota) { + return x.getOrFindEntity(level) + } else { + throw MishapInvalidIota.ofType(x, if (argc == 0) idx else argc - (idx + 1), "entity") + } +} + +fun List.getCachedEntity(idx: Int, argc: Int = 0): Entity? { + val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) } + if (x is EntityIota) { + return x.cachedEntity; } else { throw MishapInvalidIota.ofType(x, if (argc == 0) idx else argc - (idx + 1), "entity") } @@ -79,40 +99,40 @@ fun List.getBool(idx: Int, argc: Int = 0): Boolean { // Helpers -fun List.getItemEntity(idx: Int, argc: Int = 0): ItemEntity { +fun List.getItemEntity(level: ServerLevel, idx: Int, argc: Int = 0): ItemEntity { val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) } if (x is EntityIota) { - val e = x.entity + val e = x.getOrFindEntity(level) ?: throw MishapEntityUnavailable(x.entityId, x.cachedEntityName) if (e is ItemEntity) return e } throw MishapInvalidIota.ofType(x, if (argc == 0) idx else argc - (idx + 1), "entity.item") } -fun List.getPlayer(idx: Int, argc: Int = 0): ServerPlayer { +fun List.getPlayer(level: ServerLevel, idx: Int, argc: Int = 0): ServerPlayer { val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) } if (x is EntityIota) { - val e = x.entity + val e = x.getOrFindEntity(level) ?: throw MishapEntityUnavailable(x.entityId, x.cachedEntityName) if (e is ServerPlayer) return e } throw MishapInvalidIota.ofType(x, if (argc == 0) idx else argc - (idx + 1), "entity.player") } -fun List.getMob(idx: Int, argc: Int = 0): Mob { +fun List.getMob(level: ServerLevel, idx: Int, argc: Int = 0): Mob { val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) } if (x is EntityIota) { - val e = x.entity + val e = x.getOrFindEntity(level) ?: throw MishapEntityUnavailable(x.entityId, x.cachedEntityName) if (e is Mob) return e } throw MishapInvalidIota.ofType(x, if (argc == 0) idx else argc - (idx + 1), "entity.mob") } -fun List.getLivingEntityButNotArmorStand(idx: Int, argc: Int = 0): LivingEntity { +fun List.getLivingEntityButNotArmorStand(level: ServerLevel, idx: Int, argc: Int = 0): LivingEntity { val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) } if (x is EntityIota) { - val e = x.entity + val e = x.getOrFindEntity(level) ?: throw MishapEntityUnavailable(x.entityId, x.cachedEntityName) if (e is LivingEntity && e !is ArmorStand) return e } @@ -297,7 +317,7 @@ fun evaluatable(datum: Iota, reverseIdx: Int): Either = ) } -fun Iota?.orNull() = this ?: NullIota() +fun Iota?.orNull() = this ?: NullIota.INSTANCE // TODO do we make this work on lists // there should probably be some way to abstract function application over lists, vecs, and numbers, @@ -319,5 +339,5 @@ inline val BlockPos.asActionResult get() = listOf(Vec3Iota(Vec3.atCenterOf(this) inline val Vector3f.asActionResult get() = listOf(Vec3Iota(Vec3(this))) inline val Vec3.asActionResult get() = listOf(Vec3Iota(this)) -inline val Entity?.asActionResult get() = listOf(if (this == null) NullIota() else EntityIota(this)) +inline val Entity?.asActionResult get() = listOf(if (this == null) NullIota.INSTANCE else EntityIota(this)) inline val HexPattern.asActionResult get() = listOf(PatternIota(this)) diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/ParticleSpray.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/ParticleSpray.kt index 88129e6bf8..966e6abe18 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/ParticleSpray.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/ParticleSpray.kt @@ -3,6 +3,11 @@ package at.petrak.hexcasting.api.casting import at.petrak.hexcasting.api.pigment.FrozenPigment import at.petrak.hexcasting.common.msgs.MsgCastParticleS2C import at.petrak.hexcasting.xplat.IXplatAbstractions +import at.petrak.paucal.api.PaucalCodecs +import io.netty.buffer.ByteBuf +import net.minecraft.network.RegistryFriendlyByteBuf +import net.minecraft.network.codec.ByteBufCodecs +import net.minecraft.network.codec.StreamCodec import net.minecraft.server.level.ServerLevel import net.minecraft.world.phys.Vec3 @@ -12,6 +17,16 @@ import net.minecraft.world.phys.Vec3 */ data class ParticleSpray(val pos: Vec3, val vel: Vec3, val fuzziness: Double, val spread: Double, val count: Int = 20) { companion object { + @JvmStatic + val STREAM_CODEC: StreamCodec = StreamCodec.composite( + PaucalCodecs.VEC3, ParticleSpray::pos, + PaucalCodecs.VEC3, ParticleSpray::vel, + ByteBufCodecs.DOUBLE, ParticleSpray::fuzziness, + ByteBufCodecs.DOUBLE, ParticleSpray::spread, + ByteBufCodecs.VAR_INT, ParticleSpray::count, + ::ParticleSpray + ) + @JvmStatic fun burst(pos: Vec3, size: Double, count: Int = 20): ParticleSpray { return ParticleSpray(pos, Vec3(size, 0.0, 0.0), 0.0, 3.14, count) diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/SpellList.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/SpellList.kt index 2e76c18c76..f6e4090ed5 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/SpellList.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/SpellList.kt @@ -1,6 +1,8 @@ package at.petrak.hexcasting.api.casting import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.casting.iota.IotaType +import net.minecraft.network.codec.ByteBufCodecs /** * Restricted interface for functional lists. @@ -90,4 +92,17 @@ sealed class SpellList : Iterable { return car } } + + companion object { + @JvmStatic + val CODEC = IotaType.TYPED_CODEC.listOf().xmap( + { list -> LList(list) as SpellList }, + { b -> b.toList() } + ) + @JvmStatic + val STREAM_CODEC = IotaType.TYPED_STREAM_CODEC.apply(ByteBufCodecs.list()).map( + { list -> LList(list) as SpellList }, + { b -> b.toList() } + ) + } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/SpellAction.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/SpellAction.kt index fcf17d08d0..75e3a246b0 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/SpellAction.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/SpellAction.kt @@ -20,17 +20,18 @@ interface SpellAction : Action { fun awardsCastingStat(ctx: CastingEnvironment): Boolean = true + fun executeWithUserdata( + args: List, + env: CastingEnvironment, + userData: CompoundTag + ): Result = + execute(args, env) + fun execute( args: List, env: CastingEnvironment ): Result - fun executeWithUserdata( - args: List, env: CastingEnvironment, userData: CompoundTag - ): Result { - return this.execute(args, env) - } - override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult { val stack = image.stack.toMutableList() diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/circles/BlockEntityAbstractImpetus.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/circles/BlockEntityAbstractImpetus.java index ac8bf92d0d..c37ed07f58 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/circles/BlockEntityAbstractImpetus.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/circles/BlockEntityAbstractImpetus.java @@ -2,6 +2,7 @@ import at.petrak.hexcasting.api.block.HexBlockEntity; import at.petrak.hexcasting.api.block.circle.BlockCircleComponent; +import at.petrak.hexcasting.api.casting.math.HexPattern; import at.petrak.hexcasting.api.misc.MediaConstants; import at.petrak.hexcasting.api.pigment.FrozenPigment; import at.petrak.hexcasting.api.utils.MediaHelper; @@ -11,7 +12,9 @@ import net.minecraft.ChatFormatting; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; +import net.minecraft.core.HolderLookup; import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtOps; import net.minecraft.nbt.Tag; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerLevel; @@ -284,7 +287,7 @@ public FrozenPigment getPigment() { } @Override - protected void saveModData(CompoundTag tag) { + protected void saveModData(CompoundTag tag, HolderLookup.Provider registries) { if (this.executionState != null) { tag.put(TAG_EXECUTION_STATE, this.executionState.save()); } @@ -292,17 +295,17 @@ protected void saveModData(CompoundTag tag) { tag.putLong(TAG_MEDIA, this.media); if (this.displayMsg != null && this.displayItem != null) { - tag.putString(TAG_ERROR_MSG, Component.Serializer.toJson(this.displayMsg)); + tag.putString(TAG_ERROR_MSG, Component.Serializer.toJson(this.displayMsg, registries)); var itemTag = new CompoundTag(); - this.displayItem.save(itemTag); + this.displayItem.save(registries, itemTag); tag.put(TAG_ERROR_DISPLAY, itemTag); } if (this.pigment != null) - tag.put(TAG_PIGMENT, this.pigment.serializeToNBT()); + tag.put(TAG_PIGMENT, FrozenPigment.CODEC.encodeStart(NbtOps.INSTANCE, pigment).getOrThrow()); } @Override - protected void loadModData(CompoundTag tag) { + protected void loadModData(CompoundTag tag, HolderLookup.Provider registries) { this.executionState = null; if (tag.contains(TAG_EXECUTION_STATE, Tag.TAG_COMPOUND)) { this.lazyExecutionState = tag.getCompound(TAG_EXECUTION_STATE); @@ -315,8 +318,8 @@ protected void loadModData(CompoundTag tag) { } if (tag.contains(TAG_ERROR_MSG, Tag.TAG_STRING) && tag.contains(TAG_ERROR_DISPLAY, Tag.TAG_COMPOUND)) { - var msg = Component.Serializer.fromJson(tag.getString(TAG_ERROR_MSG)); - var display = ItemStack.of(tag.getCompound(TAG_ERROR_DISPLAY)); + var msg = Component.Serializer.fromJson(tag.getString(TAG_ERROR_MSG), registries); + var display = ItemStack.parseOptional(registries, tag); this.displayMsg = msg; this.displayItem = display; } else { @@ -324,7 +327,7 @@ protected void loadModData(CompoundTag tag) { this.displayItem = null; } if (tag.contains(TAG_PIGMENT, Tag.TAG_COMPOUND)) - this.pigment = FrozenPigment.fromNBT(tag.getCompound(TAG_PIGMENT)); + this.pigment = FrozenPigment.CODEC.parse(NbtOps.INSTANCE, tag.getCompound(TAG_PIGMENT)).getOrThrow(); } public void applyScryingLensOverlay(List> lines, diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/circles/CircleExecutionState.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/circles/CircleExecutionState.java index f95fa84f01..b62b4ec3c5 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/circles/CircleExecutionState.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/circles/CircleExecutionState.java @@ -10,10 +10,7 @@ import net.minecraft.ChatFormatting; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.ListTag; -import net.minecraft.nbt.NbtUtils; -import net.minecraft.nbt.Tag; +import net.minecraft.nbt.*; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; @@ -166,35 +163,37 @@ public CompoundTag save() { out.put(TAG_CURRENT_POS, NbtUtils.writeBlockPos(this.currentPos)); out.putByte(TAG_ENTERED_FROM, (byte) this.enteredFrom.ordinal()); - out.put(TAG_IMAGE, this.currentImage.serializeToNbt()); + out.put(TAG_IMAGE, CastingImage.getCODEC().encodeStart(NbtOps.INSTANCE, currentImage).getOrThrow()); if (this.caster != null) out.putUUID(TAG_CASTER, this.caster); if (this.casterPigment != null) - out.put(TAG_PIGMENT, this.casterPigment.serializeToNBT()); + out.put(TAG_PIGMENT, FrozenPigment.CODEC.encodeStart(NbtOps.INSTANCE, casterPigment).getOrThrow()); return out; } public static CircleExecutionState load(CompoundTag nbt, ServerLevel world) { - var startPos = NbtUtils.readBlockPos(nbt.getCompound(TAG_IMPETUS_POS)); + var startPos = NbtUtils.readBlockPos(nbt, TAG_IMPETUS_POS).orElseThrow(); var startDir = Direction.values()[nbt.getByte(TAG_IMPETUS_DIR)]; var knownPositions = new HashSet(); var knownTag = nbt.getList(TAG_KNOWN_POSITIONS, Tag.TAG_COMPOUND); for (var tag : knownTag) { - knownPositions.add(NbtUtils.readBlockPos(HexUtils.downcast(tag, CompoundTag.TYPE))); + var pos = readBlockPos(HexUtils.downcast(tag, IntArrayTag.TYPE).getAsIntArray()); + pos.ifPresent(knownPositions::add); } var reachedPositions = new ArrayList(); var reachedTag = nbt.getList(TAG_REACHED_POSITIONS, Tag.TAG_COMPOUND); for (var tag : reachedTag) { - reachedPositions.add(NbtUtils.readBlockPos(HexUtils.downcast(tag, CompoundTag.TYPE))); + var pos = readBlockPos(HexUtils.downcast(tag, IntArrayTag.TYPE).getAsIntArray()); + pos.ifPresent(reachedPositions::add); } - var currentPos = NbtUtils.readBlockPos(nbt.getCompound(TAG_CURRENT_POS)); + var currentPos = NbtUtils.readBlockPos(nbt, TAG_CURRENT_POS).orElseThrow(); var enteredFrom = Direction.values()[nbt.getByte(TAG_ENTERED_FROM)]; - var image = CastingImage.loadFromNbt(nbt.getCompound(TAG_IMAGE), world); + var image = CastingImage.getCODEC().parse(NbtOps.INSTANCE, nbt.getCompound(TAG_IMAGE)).getOrThrow(); UUID caster = null; if (nbt.hasUUID(TAG_CASTER)) @@ -202,12 +201,16 @@ public static CircleExecutionState load(CompoundTag nbt, ServerLevel world) { FrozenPigment pigment = null; if (nbt.contains(TAG_PIGMENT, Tag.TAG_COMPOUND)) - pigment = FrozenPigment.fromNBT(nbt.getCompound(TAG_PIGMENT)); + pigment = FrozenPigment.CODEC.parse(NbtOps.INSTANCE, nbt.getCompound(TAG_PIGMENT)).getOrThrow(); return new CircleExecutionState(startPos, startDir, knownPositions, reachedPositions, currentPos, enteredFrom, image, caster, pigment); } + private static Optional readBlockPos(int[] aint) { + return aint.length == 3 ? Optional.of(new BlockPos(aint[0], aint[1], aint[2])) : Optional.empty(); + } + /** * Update this, also mutates the impetus. *

diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastResult.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastResult.kt index c0b4d4442d..dea8869286 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastResult.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastResult.kt @@ -7,7 +7,7 @@ import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation import at.petrak.hexcasting.api.casting.iota.Iota /** - * The result of doing something to a cast harness. + * The result of doing something to a casting VM. * * Contains the iota that was executed to produce this CastResult, * the next thing to execute after this is finished, the modified state of the stack, diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastingEnvironment.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastingEnvironment.java index 9157063a97..e74d123f19 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastingEnvironment.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastingEnvironment.java @@ -10,7 +10,9 @@ import at.petrak.hexcasting.api.mod.HexConfig; import at.petrak.hexcasting.api.pigment.FrozenPigment; import at.petrak.hexcasting.api.utils.HexUtils; +import at.petrak.hexcasting.common.lib.HexAttributes; import net.minecraft.core.BlockPos; +import net.minecraft.core.Holder; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; @@ -229,7 +231,7 @@ public void postCast(CastingImage image) { * Return whether this env can cast great spells. */ public boolean isEnlightened() { - var adv = this.world.getServer().getAdvancements().getAdvancement(modLoc("enlightenment")); + var adv = this.world.getServer().getAdvancements().get(modLoc("enlightenment")); if (adv == null) return false; @@ -247,6 +249,9 @@ public boolean isEnlightened() { * positive. */ public long extractMedia(long cost, boolean simulate) { + if (this.getCastingEntity() != null){ + cost = (long) (cost * this.getCastingEntity().getAttributeValue(HexAttributes.MEDIA_CONSUMPTION_MODIFIER)); + } for (var extractMediaComponent : preMediaExtract) cost = extractMediaComponent.onExtractMedia(cost, simulate); cost = extractMediaEnvironment(cost, simulate); diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/ExecutionClientView.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/ExecutionClientView.kt index 3fcf1bf766..90e7285b37 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/ExecutionClientView.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/ExecutionClientView.kt @@ -1,6 +1,13 @@ package at.petrak.hexcasting.api.casting.eval +import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.casting.iota.IotaType import net.minecraft.nbt.CompoundTag +import net.minecraft.network.RegistryFriendlyByteBuf +import net.minecraft.network.codec.ByteBufCodecs +import net.minecraft.network.codec.StreamCodec +import java.util.* +import kotlin.jvm.optionals.getOrNull /** * Information sent back to the client @@ -11,7 +18,26 @@ data class ExecutionClientView( // These must be tags so the wrapping of the text can happen on the client // otherwise we don't know when to stop rendering - val stackDescs: List, - val ravenmind: CompoundTag?, -) + val stackDescs: List, + val ravenmind: CompoundTag? +) { + + companion object { + @JvmStatic + val STREAM_CODEC: StreamCodec = + StreamCodec.composite( + ByteBufCodecs.BOOL, ExecutionClientView::isStackClear, + ByteBufCodecs.idMapper( + { ResolvedPatternType.entries[it] }, + ResolvedPatternType::ordinal + ), ExecutionClientView::resolutionType, + IotaType.TYPED_STREAM_CODEC.apply(ByteBufCodecs.list()), ExecutionClientView::stackDescs, + ByteBufCodecs.optional(ByteBufCodecs.COMPOUND_TAG).map( + { it.getOrNull() }, + Optional::ofNullable + ), ExecutionClientView::ravenmind, + ::ExecutionClientView + ) + } +} diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/ResolvedPattern.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/ResolvedPattern.kt index 6108850727..ac4ec14fbe 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/ResolvedPattern.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/ResolvedPattern.kt @@ -2,26 +2,40 @@ package at.petrak.hexcasting.api.casting.eval import at.petrak.hexcasting.api.casting.math.HexCoord import at.petrak.hexcasting.api.casting.math.HexPattern -import at.petrak.hexcasting.api.utils.NBTBuilder -import net.minecraft.nbt.CompoundTag -import java.util.* +import com.mojang.serialization.Codec +import com.mojang.serialization.codecs.RecordCodecBuilder +import net.minecraft.network.RegistryFriendlyByteBuf +import net.minecraft.network.codec.ByteBufCodecs +import net.minecraft.network.codec.StreamCodec data class ResolvedPattern(val pattern: HexPattern, val origin: HexCoord, var type: ResolvedPatternType) { - fun serializeToNBT() = NBTBuilder { - "Pattern" %= pattern.serializeToNBT() - "OriginQ" %= origin.q - "OriginR" %= origin.r - "Valid" %= type.name.lowercase(Locale.ROOT) - } + + constructor(pattern: HexPattern, q: Int, r: Int, type: ResolvedPatternType): this(pattern, HexCoord(q, r), type) companion object { - @JvmStatic - fun fromNBT(tag: CompoundTag): ResolvedPattern { - val pattern = HexPattern.fromNBT(tag.getCompound("Pattern")) - val origin = HexCoord(tag.getInt("OriginQ"), tag.getInt("OriginR")) - val valid = ResolvedPatternType.fromString(tag.getString("Valid")) - return ResolvedPattern(pattern, origin, valid) - } + @JvmField + val CODEC: Codec = RecordCodecBuilder.create({instance -> instance.group( + HexPattern.CODEC.fieldOf("pattern").forGetter { it.pattern }, + Codec.INT.fieldOf("OriginQ").forGetter { it.origin.q }, + Codec.INT.fieldOf("OriginR").forGetter { it.origin.r }, + Codec.STRING.xmap( + { ResolvedPatternType.fromString(it) }, + { it.name.lowercase() } + ).fieldOf("Valid").forGetter { it.type } + ).apply(instance, ::ResolvedPattern) + }) + + @JvmField + val STREAM_CODEC: StreamCodec = StreamCodec.composite( + HexPattern.STREAM_CODEC, ResolvedPattern::pattern, + ByteBufCodecs.VAR_INT, { it.origin.q }, + ByteBufCodecs.VAR_INT, { it.origin.r }, + ByteBufCodecs.STRING_UTF8.map( + { ResolvedPatternType.fromString(it) }, + { it.name.lowercase() } + ), ResolvedPattern::type, + ::ResolvedPattern + ) } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/CircleCastEnv.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/CircleCastEnv.java index d1d542780d..2b0d914839 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/CircleCastEnv.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/CircleCastEnv.java @@ -13,7 +13,9 @@ import at.petrak.hexcasting.api.casting.mishaps.MishapDisallowedSpell; import at.petrak.hexcasting.api.mod.HexConfig; import at.petrak.hexcasting.api.pigment.FrozenPigment; +import at.petrak.hexcasting.common.lib.HexAttributes; import net.minecraft.core.BlockPos; +import net.minecraft.core.Holder; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerLevel; @@ -29,8 +31,6 @@ import java.util.List; import java.util.function.Predicate; -import static at.petrak.hexcasting.api.casting.eval.env.PlayerBasedCastEnv.SENTINEL_RADIUS; - public class CircleCastEnv extends CastingEnvironment { protected final CircleExecutionState execState; @@ -133,6 +133,7 @@ public long extractMediaEnvironment(long cost, boolean simulate) { public boolean isVecInRangeEnvironment(Vec3 vec) { var caster = this.execState.getCaster(this.world); if (caster != null) { + double sentinelRadius = caster.getAttributeValue(HexAttributes.SENTINEL_RADIUS); if (vec.distanceToSqr(caster.position()) <= caster.getBbHeight() * caster.getBbHeight()) { return true; } @@ -141,7 +142,7 @@ public boolean isVecInRangeEnvironment(Vec3 vec) { if (sentinel != null && sentinel.extendsRange() && caster.level().dimension() == sentinel.dimension() - && vec.distanceToSqr(sentinel.position()) <= SENTINEL_RADIUS * SENTINEL_RADIUS + 0.00000000001 + && vec.distanceToSqr(sentinel.position()) <= sentinelRadius * sentinelRadius + 0.00000000001 ) { return true; } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PlayerBasedCastEnv.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PlayerBasedCastEnv.java index 10ff3b052b..f143bf58c5 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PlayerBasedCastEnv.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PlayerBasedCastEnv.java @@ -14,9 +14,11 @@ import at.petrak.hexcasting.api.pigment.FrozenPigment; import at.petrak.hexcasting.api.utils.HexUtils; import at.petrak.hexcasting.api.utils.MediaHelper; +import at.petrak.hexcasting.common.lib.HexAttributes; import at.petrak.hexcasting.common.lib.HexDamageTypes; import at.petrak.hexcasting.xplat.IXplatAbstractions; import net.minecraft.core.BlockPos; +import net.minecraft.core.Holder; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerPlayer; import net.minecraft.util.Mth; @@ -35,8 +37,10 @@ import static at.petrak.hexcasting.api.HexAPI.modLoc; public abstract class PlayerBasedCastEnv extends CastingEnvironment { - public static final double AMBIT_RADIUS = 32.0; - public static final double SENTINEL_RADIUS = 16.0; + public static final double DEFAULT_AMBIT_RADIUS = 32.0; + private double ambitRadius; + public static final double DEFAULT_SENTINEL_RADIUS = 16.0; + private double sentinelRadius; protected final ServerPlayer caster; protected final InteractionHand castingHand; @@ -45,6 +49,8 @@ protected PlayerBasedCastEnv(ServerPlayer caster, InteractionHand castingHand) { super(caster.serverLevel()); this.caster = caster; this.castingHand = castingHand; + this.ambitRadius = caster.getAttributeValue(HexAttributes.AMBIT_RADIUS); + this.sentinelRadius = caster.getAttributeValue(HexAttributes.SENTINEL_RADIUS); } @Override @@ -66,6 +72,16 @@ public void postExecution(CastResult result) { this.sendMishapMsgToPlayer(doMishap); } } + if (this.caster != null){ + double ambitAttribute = this.caster.getAttributeValue(HexAttributes.AMBIT_RADIUS); + if (this.ambitRadius != ambitAttribute){ + this.ambitRadius = ambitAttribute; + } + double sentinelAttribute = this.caster.getAttributeValue(HexAttributes.SENTINEL_RADIUS); + if (this.sentinelRadius != sentinelAttribute){ + this.sentinelRadius = sentinelAttribute; + } + } } @Override @@ -78,6 +94,14 @@ protected List getPrimaryStacks() { return getPrimaryStacksForPlayer(this.castingHand, this.caster); } + public double getAmbitRadius() { + return this.ambitRadius; + } + + public double getSentinelRadius(){ + return this.sentinelRadius; + } + @Override public boolean replaceItem(Predicate stackOk, ItemStack replaceWith, @Nullable InteractionHand hand) { return replaceItemForPlayer(stackOk, replaceWith, hand, this.caster); @@ -90,12 +114,12 @@ public boolean isVecInRangeEnvironment(Vec3 vec) { && sentinel.extendsRange() && this.caster.level().dimension() == sentinel.dimension() // adding 0.00000000001 to avoid machine precision errors at specific angles - && vec.distanceToSqr(sentinel.position()) <= SENTINEL_RADIUS * SENTINEL_RADIUS + 0.00000000001 + && vec.distanceToSqr(sentinel.position()) <= sentinelRadius * sentinelRadius + 0.00000000001 ) { return true; } - return vec.distanceToSqr(this.caster.position()) <= AMBIT_RADIUS * AMBIT_RADIUS + 0.00000000001; + return vec.distanceToSqr(this.caster.position()) <= ambitRadius * ambitRadius + 0.00000000001; } @Override @@ -152,9 +176,12 @@ protected long extractMediaFromInventory(long costLeft, boolean allowOvercast, b } protected boolean canOvercast() { - var adv = this.world.getServer().getAdvancements().getAdvancement(modLoc("y_u_no_cast_angy")); - var advs = this.caster.getAdvancements(); - return advs.getOrStartProgress(adv).isDone(); + var adv = this.world.getServer().getAdvancements().get(modLoc("y_u_no_cast_angy")); + if(adv != null) { + var advs = this.caster.getAdvancements(); + return advs.getOrStartProgress(adv).isDone(); + } + return false; } @Override diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/StaffCastEnv.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/StaffCastEnv.java index 29e80d3817..537c146b71 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/StaffCastEnv.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/StaffCastEnv.java @@ -14,6 +14,7 @@ import at.petrak.hexcasting.common.msgs.*; import at.petrak.hexcasting.xplat.IXplatAbstractions; import net.minecraft.network.chat.Component; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.server.level.ServerPlayer; import net.minecraft.sounds.SoundSource; import net.minecraft.world.InteractionHand; @@ -131,7 +132,7 @@ public static void handleNewPatternOnServer(ServerPlayer sender, MsgNewSpellPatt IXplatAbstractions.INSTANCE.sendPacketToPlayer(sender, new MsgNewSpellPatternS2C(clientInfo, resolvedPatterns.size() - 1)); - IMessage packet; + CustomPacketPayload packet; if (clientInfo.isStackClear()) { packet = new MsgClearSpiralPatternsS2C(sender.getUUID()); } else { diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/CastingImage.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/CastingImage.kt index 3ffd771bcd..573f73fb61 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/CastingImage.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/CastingImage.kt @@ -1,57 +1,59 @@ package at.petrak.hexcasting.api.casting.eval.vm import at.petrak.hexcasting.api.HexAPI +import at.petrak.hexcasting.api.casting.eval.vm.CastingImage.ParenthesizedIota import at.petrak.hexcasting.api.casting.eval.vm.CastingImage.ParenthesizedIota.Companion.TAG_ESCAPED import at.petrak.hexcasting.api.casting.eval.vm.CastingImage.ParenthesizedIota.Companion.TAG_IOTAS import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.IotaType import at.petrak.hexcasting.api.casting.iota.ListIota import at.petrak.hexcasting.api.utils.* +import com.mojang.serialization.Codec +import com.mojang.serialization.codecs.RecordCodecBuilder import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.ListTag import net.minecraft.nbt.Tag +import net.minecraft.network.codec.ByteBufCodecs +import net.minecraft.network.codec.StreamCodec import net.minecraft.server.level.ServerLevel +import net.minecraft.util.ExtraCodecs import net.minecraft.world.entity.Entity +import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** * The state of a casting VM, containing the stack and all */ -data class CastingImage private constructor( +data class CastingImage( val stack: List, val parenCount: Int, val parenthesized: List, val escapeNext: Boolean, val opsConsumed: Long, - val userData: CompoundTag ) { constructor() : this(listOf(), 0, listOf(), false, 0, CompoundTag()) data class ParenthesizedIota(val iota: Iota, val escaped: Boolean) { companion object { + val CODEC = RecordCodecBuilder.create { inst -> + inst.group( + IotaType.TYPED_CODEC.fieldOf("iota").forGetter { it.iota }, + Codec.BOOL.fieldOf("escaped").forGetter { it.escaped } + ).apply(inst, ::ParenthesizedIota) + } + val STREAM_CODEC = StreamCodec.composite( + IotaType.TYPED_STREAM_CODEC, ParenthesizedIota::iota, + ByteBufCodecs.BOOL, ParenthesizedIota::escaped, + ::ParenthesizedIota + ) + const val TAG_IOTAS = "iotas" const val TAG_ESCAPED = "escaped" } } - /** - * Returns an empty list if it's too complicated. - */ - private fun Iterable.serializeToNBT(): CompoundTag { - val tag = CompoundTag() - - if (IotaType.isTooLargeToSerialize(this.map { it.iota })) { - tag.put(TAG_IOTAS, ListTag()) - tag.put(TAG_ESCAPED, ListTag()) - } else { - tag.put(TAG_IOTAS, ListIota(this.map { it.iota }).serialize()) - tag.put(TAG_ESCAPED, this.map { it.escaped }.serializeToNBT()) - } - - return tag - } - /** * Return a copy of this with the given number of ops additionally exhausted */ @@ -72,60 +74,32 @@ data class CastingImage private constructor( */ fun withResetEscape() = this.copy(parenCount = 0, parenthesized = listOf(), escapeNext = false) - fun serializeToNbt() = NBTBuilder { - TAG_STACK %= stack.serializeToNBT() - - TAG_PAREN_COUNT %= parenCount - TAG_ESCAPE_NEXT %= escapeNext - TAG_PARENTHESIZED %= parenthesized.serializeToNBT() - TAG_OPS_CONSUMED %= opsConsumed - - TAG_USERDATA %= userData - } - companion object { - const val TAG_STACK = "stack" - const val TAG_PAREN_COUNT = "open_parens" - const val TAG_PARENTHESIZED = "parenthesized" - const val TAG_ESCAPE_NEXT = "escape_next" - const val TAG_OPS_CONSUMED = "ops_consumed" - const val TAG_USERDATA = "userdata" - @JvmStatic - fun loadFromNbt(tag: CompoundTag, world: ServerLevel): CastingImage { - return try { - val stack = mutableListOf() - val stackTag = tag.getList(TAG_STACK, Tag.TAG_COMPOUND) - for (subtag in stackTag) { - val datum = IotaType.deserialize(subtag.asCompound, world) - stack.add(datum) - } - - val userData = if (tag.contains(TAG_USERDATA)) { - tag.getCompound(TAG_USERDATA) - } else { - CompoundTag() - } - - val parenthesized = mutableListOf() - val parenTag = tag.getCompound(TAG_PARENTHESIZED) - val parenIotasTag = parenTag.getList(TAG_IOTAS, Tag.TAG_COMPOUND) - val parenEscapedTag = parenTag.getByteArray(TAG_ESCAPED) - - for ((subtag, isEscapedByte) in parenIotasTag.zipWithDefault(parenEscapedTag) { _ -> 0 }) { - parenthesized.add(ParenthesizedIota(IotaType.deserialize(subtag.downcast(CompoundTag.TYPE), world), isEscapedByte != 0.toByte())) - } - - val parenCount = tag.getInt(TAG_PAREN_COUNT) - val escapeNext = tag.getBoolean(TAG_ESCAPE_NEXT) - val opsUsed = tag.getLong(TAG_OPS_CONSUMED) - - CastingImage(stack, parenCount, parenthesized, escapeNext, opsUsed, userData) - } catch (exn: Exception) { - HexAPI.LOGGER.warn("error while loading a CastingImage", exn) - CastingImage() + val CODEC = RecordCodecBuilder.create { inst -> + inst.group( + IotaType.TYPED_CODEC.listOf().fieldOf("stack").forGetter { it.stack }, + Codec.INT.fieldOf("open_parens").forGetter { it.parenCount }, + ParenthesizedIota.CODEC.listOf().fieldOf("parenthesized").forGetter { it.parenthesized }, + Codec.BOOL.fieldOf("escape_next").forGetter { it.escapeNext }, + Codec.LONG.fieldOf("ops_consumed").forGetter { it.opsConsumed }, + CompoundTag.CODEC.fieldOf("userData").forGetter { it.userData } + ).apply(inst) { a, b, c, d, e, f -> + CastingImage(a, b, c, d, e, f) } - } + }.orElseGet(::CastingImage) + @JvmStatic + val STREAM_CODEC = StreamCodec.composite( + IotaType.TYPED_STREAM_CODEC.apply(ByteBufCodecs.list()), CastingImage::stack, + ByteBufCodecs.VAR_INT, CastingImage::parenCount, + ParenthesizedIota.STREAM_CODEC.apply(ByteBufCodecs.list()), CastingImage::parenthesized, + ByteBufCodecs.BOOL, CastingImage::escapeNext, + ByteBufCodecs.VAR_LONG, CastingImage::opsConsumed, + ByteBufCodecs.COMPOUND_TAG, { it.userData }, + { a, b, c, d, e, f -> + CastingImage(a, b, c, d, e, f) + } + ) @JvmStatic fun checkAndMarkGivenMotion(userData: CompoundTag, entity: Entity): Boolean { diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/CastingVM.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/CastingVM.kt index 587500355b..c6e4336a47 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/CastingVM.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/CastingVM.kt @@ -1,7 +1,6 @@ package at.petrak.hexcasting.api.casting.eval.vm import at.petrak.hexcasting.api.HexAPI -import at.petrak.hexcasting.api.casting.PatternShapeMatch.* import at.petrak.hexcasting.api.casting.SpellList import at.petrak.hexcasting.api.casting.eval.* import at.petrak.hexcasting.api.casting.eval.sideeffects.OperatorSideEffect @@ -12,8 +11,10 @@ import at.petrak.hexcasting.api.casting.iota.ListIota import at.petrak.hexcasting.api.casting.iota.PatternIota import at.petrak.hexcasting.api.casting.math.HexDir import at.petrak.hexcasting.api.casting.math.HexPattern -import at.petrak.hexcasting.api.casting.mishaps.* -import at.petrak.hexcasting.api.utils.* +import at.petrak.hexcasting.api.casting.mishaps.Mishap +import at.petrak.hexcasting.api.casting.mishaps.MishapInternalException +import at.petrak.hexcasting.api.casting.mishaps.MishapStackSize +import at.petrak.hexcasting.api.casting.mishaps.MishapTooManyCloseParens import at.petrak.hexcasting.common.lib.hex.HexEvalSounds import net.minecraft.nbt.CompoundTag import net.minecraft.server.level.ServerLevel @@ -64,7 +65,7 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) { } } - // Then write all pertinent data back to the harness for the next iteration. + // Then write all pertinent data back to the VM for the next iteration. if (image2.newData != null) { this.image = image2.newData } @@ -86,12 +87,14 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) { if (lastResolutionType.success) ResolvedPatternType.EVALUATED else ResolvedPatternType.ERRORED } - val (stackDescs, ravenmind) = generateDescs() + val ravenmind: CompoundTag? = image.userData + ?.takeIf { it.contains(HexAPI.RAVENMIND_USERDATA) } + ?.getCompound(HexAPI.RAVENMIND_USERDATA) val isStackClear = image.stack.isEmpty() && image.parenCount == 0 && !image.escapeNext && ravenmind == null this.env.postCast(image) - return ExecutionClientView(isStackClear, lastResolutionType, stackDescs, ravenmind) + return ExecutionClientView(isStackClear, lastResolutionType, image.stack, ravenmind) } /** @@ -158,14 +161,6 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) { } } - fun generateDescs(): Pair, CompoundTag?> { - val stackDescs = this.image.stack.map { IotaType.serialize(it) } - val ravenmind = if (this.image.userData.contains(HexAPI.RAVENMIND_USERDATA)) { - this.image.userData.getCompound(HexAPI.RAVENMIND_USERDATA) - } else null - return Pair(stackDescs, ravenmind) - } - /** * Return a non-null value if we handled this in some sort of parenthesey way, * either escaping it onto the stack or changing the parenthese-handling state. diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/ContinuationFrame.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/ContinuationFrame.kt index f565135837..ff25b70b57 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/ContinuationFrame.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/ContinuationFrame.kt @@ -2,12 +2,24 @@ package at.petrak.hexcasting.api.casting.eval.vm import at.petrak.hexcasting.api.casting.SpellList import at.petrak.hexcasting.api.casting.eval.CastResult +import at.petrak.hexcasting.api.casting.iota.GarbageIota import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.casting.iota.IotaType +import at.petrak.hexcasting.common.lib.HexRegistries import at.petrak.hexcasting.common.lib.hex.HexContinuationTypes +import at.petrak.hexcasting.xplat.IXplatAbstractions +import com.mojang.serialization.Codec +import com.mojang.serialization.DataResult +import com.mojang.serialization.MapCodec import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.Tag +import net.minecraft.network.RegistryFriendlyByteBuf +import net.minecraft.network.codec.ByteBufCodecs +import net.minecraft.network.codec.StreamCodec import net.minecraft.resources.ResourceLocation import net.minecraft.server.level.ServerLevel +import java.util.function.Function +import java.util.function.Supplier /** * A single frame of evaluation during the execution of a spell. @@ -37,11 +49,6 @@ interface ContinuationFrame { */ fun breakDownwards(stack: List): Pair> - /** - * Serializes this frame. Used for things like delays, where we pause execution. - */ - fun serializeToNBT(): CompoundTag - /** * Return the number of iotas contained inside this frame, used for determining whether it is valid to serialise. */ @@ -50,41 +57,36 @@ interface ContinuationFrame { val type: Type<*> interface Type { - fun deserializeFromNBT(tag: CompoundTag, world: ServerLevel): U? - } - companion object { - /** - * Takes a tag containing the ContinuationFrame.Type resourcelocation and the serialized continuation frame, and returns - * the deserialized continuation frame. - */ - @JvmStatic - fun fromNBT(tag: CompoundTag, world: ServerLevel): ContinuationFrame { - val type = getTypeFromTag(tag) ?: return FrameEvaluate(SpellList.LList(0, listOf()), false) + fun codec(): MapCodec - return (tag.get(HexContinuationTypes.KEY_DATA) as? CompoundTag)?.let { type.deserializeFromNBT(it, world) } - ?: FrameEvaluate(SpellList.LList(0, listOf()), false) - } + fun streamCodec(): StreamCodec + + companion object { + //TODO if doesn't exist use `FrameEvaluate(SpellList.LList(0, listOf()), false)` as default value + @JvmStatic + val TYPED_CODEC: Codec = Codec.lazyInitialized { + IXplatAbstractions.INSTANCE + .continuationTypeRegistry + .byNameCodec() + .dispatch( + "type", + ContinuationFrame::type, + Type<*>::codec + ) + } - /** - * Takes a continuation frame and serializes it along with its type. - */ - @JvmStatic - fun toNBT(frame: ContinuationFrame): CompoundTag { - val type = frame.type - val typeId = HexContinuationTypes.REGISTRY.getKey(type) - ?: throw IllegalStateException( - "Tried to serialize an unregistered continuation type. Continuation: " + frame - + " ; Type" + type.javaClass.typeName + @JvmStatic + val TYPED_STREAM_CODEC: StreamCodec = ByteBufCodecs + .registry(HexRegistries.CONTINUATION_TYPE) + .dispatch( + ContinuationFrame::type, + Type<*>::streamCodec ) - - val data = frame.serializeToNBT() - - val out = CompoundTag() - out.putString(HexContinuationTypes.KEY_TYPE, typeId.toString()) - out.put(HexContinuationTypes.KEY_DATA, data) - return out } + } + + companion object { /** * This method attempts to find the type from the `type` key. @@ -98,9 +100,11 @@ interface ContinuationFrame { } val typeKey = tag.getString(HexContinuationTypes.KEY_TYPE) + val typeLoc = ResourceLocation.tryParse(typeKey) + ?: return null - return typeLoc?.let { HexContinuationTypes.REGISTRY[it] } + return HexContinuationTypes.REGISTRY[typeLoc] } } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FrameEvaluate.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FrameEvaluate.kt index 141148dfdc..c67b2683ba 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FrameEvaluate.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FrameEvaluate.kt @@ -5,13 +5,13 @@ import at.petrak.hexcasting.api.casting.eval.CastResult import at.petrak.hexcasting.api.casting.eval.ResolvedPatternType import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.ListIota -import at.petrak.hexcasting.api.utils.NBTBuilder -import at.petrak.hexcasting.api.utils.getList -import at.petrak.hexcasting.api.utils.serializeToNBT import at.petrak.hexcasting.common.lib.hex.HexEvalSounds -import at.petrak.hexcasting.common.lib.hex.HexIotaTypes -import net.minecraft.nbt.CompoundTag -import net.minecraft.nbt.Tag +import com.mojang.serialization.Codec +import com.mojang.serialization.MapCodec +import com.mojang.serialization.codecs.RecordCodecBuilder +import net.minecraft.network.RegistryFriendlyByteBuf +import net.minecraft.network.codec.ByteBufCodecs +import net.minecraft.network.codec.StreamCodec import net.minecraft.server.level.ServerLevel /** @@ -48,27 +48,32 @@ data class FrameEvaluate(val list: SpellList, val isMetacasting: Boolean) : Cont } } - override fun serializeToNBT() = NBTBuilder { - "patterns" %= list.serializeToNBT() - "isMetacasting" %= isMetacasting - } - override fun size() = list.size() override val type: ContinuationFrame.Type<*> = TYPE companion object { + @JvmField val TYPE: ContinuationFrame.Type = object : ContinuationFrame.Type { - override fun deserializeFromNBT(tag: CompoundTag, world: ServerLevel): FrameEvaluate { - return FrameEvaluate( - HexIotaTypes.LIST.deserialize( - tag.getList("patterns", Tag.TAG_COMPOUND), - world - )!!.list, - tag.getBoolean("isMetacasting")) + val CODEC = RecordCodecBuilder.mapCodec { inst -> + inst.group( + SpellList.CODEC.fieldOf("patterns").forGetter { it.list }, + Codec.BOOL.fieldOf("isMetacasting").forGetter { it.isMetacasting } + ).apply(inst, ::FrameEvaluate) } + val STREAM_CODEC = StreamCodec.composite( + SpellList.STREAM_CODEC, FrameEvaluate::list, + ByteBufCodecs.BOOL, FrameEvaluate::isMetacasting, + ::FrameEvaluate + ) + + + override fun codec(): MapCodec = + CODEC + override fun streamCodec(): StreamCodec = + STREAM_CODEC } } } \ No newline at end of file diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FrameFinishEval.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FrameFinishEval.kt index 72bbb8c80c..ed16b1768c 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FrameFinishEval.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FrameFinishEval.kt @@ -6,7 +6,10 @@ import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.NullIota import at.petrak.hexcasting.api.utils.NBTBuilder import at.petrak.hexcasting.common.lib.hex.HexEvalSounds +import com.mojang.serialization.MapCodec import net.minecraft.nbt.CompoundTag +import net.minecraft.network.RegistryFriendlyByteBuf +import net.minecraft.network.codec.StreamCodec import net.minecraft.server.level.ServerLevel /** @@ -24,7 +27,7 @@ object FrameFinishEval : ContinuationFrame { harness: CastingVM ): CastResult { return CastResult( - NullIota(), + NullIota.INSTANCE, continuation, null, listOf(), @@ -33,13 +36,19 @@ object FrameFinishEval : ContinuationFrame { ) } - override fun serializeToNBT() = CompoundTag() - override fun size() = 0 @JvmField val TYPE: ContinuationFrame.Type = object : ContinuationFrame.Type { - override fun deserializeFromNBT(tag: CompoundTag, world: ServerLevel) = FrameFinishEval + val CODEC = MapCodec.unit(FrameFinishEval) + val STREAM_CODEC = StreamCodec.unit(FrameFinishEval) + + override fun codec(): MapCodec = + CODEC + + override fun streamCodec(): StreamCodec = + STREAM_CODEC + } override val type = TYPE diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FrameForEach.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FrameForEach.kt index 0221c1f36d..0017aeecf3 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FrameForEach.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FrameForEach.kt @@ -4,16 +4,17 @@ import at.petrak.hexcasting.api.casting.SpellList import at.petrak.hexcasting.api.casting.eval.CastResult import at.petrak.hexcasting.api.casting.eval.ResolvedPatternType import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.casting.iota.IotaType import at.petrak.hexcasting.api.casting.iota.ListIota -import at.petrak.hexcasting.api.utils.NBTBuilder -import at.petrak.hexcasting.api.utils.getList -import at.petrak.hexcasting.api.utils.hasList -import at.petrak.hexcasting.api.utils.serializeToNBT import at.petrak.hexcasting.common.lib.hex.HexEvalSounds -import at.petrak.hexcasting.common.lib.hex.HexIotaTypes -import net.minecraft.nbt.CompoundTag -import net.minecraft.nbt.Tag +import com.mojang.serialization.MapCodec +import com.mojang.serialization.codecs.RecordCodecBuilder +import net.minecraft.network.RegistryFriendlyByteBuf +import net.minecraft.network.codec.ByteBufCodecs +import net.minecraft.network.codec.StreamCodec import net.minecraft.server.level.ServerLevel +import java.util.* +import kotlin.jvm.optionals.getOrNull /** * A frame representing all the state for a Thoth evaluation. @@ -47,7 +48,7 @@ data class FrameForEach( ): CastResult { // If this isn't the very first Thoth step (i.e. no Thoth computations run yet)... val stack = if (baseStack == null) { - // init stack to the harness stack... + // init stack to the VM stack... harness.image.stack.toList() } else { // else save the stack to the accumulator and reuse the saved base stack. @@ -81,14 +82,6 @@ data class FrameForEach( ) } - override fun serializeToNBT() = NBTBuilder { - "data" %= data.serializeToNBT() - "code" %= code.serializeToNBT() - if (baseStack != null) - "base" %= baseStack.serializeToNBT() - "accumulator" %= acc.serializeToNBT() - } - override fun size() = data.size() + code.size() + acc.size + (baseStack?.size ?: 0) override val type: ContinuationFrame.Type<*> = TYPE @@ -96,21 +89,33 @@ data class FrameForEach( companion object { @JvmField val TYPE: ContinuationFrame.Type = object : ContinuationFrame.Type { - override fun deserializeFromNBT(tag: CompoundTag, world: ServerLevel): FrameForEach { - return FrameForEach( - HexIotaTypes.LIST.deserialize(tag.getList("data", Tag.TAG_COMPOUND), world)!!.list, - HexIotaTypes.LIST.deserialize(tag.getList("code", Tag.TAG_COMPOUND), world)!!.list, - if (tag.hasList("base", Tag.TAG_COMPOUND)) - HexIotaTypes.LIST.deserialize(tag.getList("base", Tag.TAG_COMPOUND), world)!!.list.toList() - else - null, - HexIotaTypes.LIST.deserialize( - tag.getList("accumulator", Tag.TAG_COMPOUND), - world - )!!.list.toMutableList() - ) + val CODEC = RecordCodecBuilder.mapCodec { inst -> + inst.group( + SpellList.CODEC.fieldOf("data").forGetter { it.data }, + SpellList.CODEC.fieldOf("code").forGetter { it.code }, + IotaType.TYPED_CODEC.listOf().optionalFieldOf("base").forGetter { Optional.ofNullable(it.baseStack) }, + IotaType.TYPED_CODEC.listOf().fieldOf("accumulator").forGetter { it.acc } + ).apply(inst) { a, b, c, d -> + FrameForEach(a, b, c.getOrNull(), d) + } + } + val STREAM_CODEC = StreamCodec.composite( + SpellList.STREAM_CODEC, FrameForEach::data, + SpellList.STREAM_CODEC, FrameForEach::code, + ByteBufCodecs.optional(IotaType.TYPED_STREAM_CODEC + .apply(ByteBufCodecs.list())), { Optional.ofNullable(it.baseStack) }, + IotaType.TYPED_STREAM_CODEC + .apply(ByteBufCodecs.list()), FrameForEach::acc + ) { a, b, c, d -> + FrameForEach(a, b, c.getOrNull(), d) } + + override fun codec(): MapCodec = + CODEC + + override fun streamCodec(): StreamCodec = + STREAM_CODEC } } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FunctionalData.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FunctionalData.kt index 49f3d149d0..79c48bf6bb 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FunctionalData.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FunctionalData.kt @@ -3,7 +3,7 @@ package at.petrak.hexcasting.api.casting.eval.vm import at.petrak.hexcasting.api.casting.iota.Iota /** - * A change to the data in a CastHarness after a pattern is drawn. + * A change to the data in a CastingVM after a pattern is drawn. */ data class FunctionalData( val stack: List, diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/SpellContinuation.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/SpellContinuation.kt index ec706c2858..774d9ea60d 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/SpellContinuation.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/SpellContinuation.kt @@ -1,10 +1,13 @@ package at.petrak.hexcasting.api.casting.eval.vm -import at.petrak.hexcasting.api.utils.NBTBuilder -import at.petrak.hexcasting.api.utils.getList -import net.minecraft.nbt.CompoundTag -import net.minecraft.nbt.Tag -import net.minecraft.server.level.ServerLevel +import com.mojang.datafixers.util.Either +import com.mojang.serialization.Codec +import com.mojang.serialization.codecs.RecordCodecBuilder +import io.netty.buffer.ByteBuf +import net.minecraft.network.RegistryFriendlyByteBuf +import net.minecraft.network.codec.ByteBufCodecs +import net.minecraft.network.codec.StreamCodec +import java.util.function.Function /** * A continuation during the execution of a spell. @@ -16,31 +19,43 @@ sealed interface SpellContinuation { fun pushFrame(frame: ContinuationFrame): SpellContinuation = NotDone(frame, this) - fun serializeToNBT() = NBTBuilder { - TAG_FRAME %= list(getNBTFrames()) - } - fun getNBTFrames(): List { - var self = this - val frames = mutableListOf() - while (self is NotDone) { - frames.add(ContinuationFrame.toNBT(self.frame)) - self = self.next - } - return frames - } companion object { - const val TAG_FRAME = "frame" - + // TODO port: maybe serialize to list like before? + // TODO port: maybe unit should be first @JvmStatic - fun fromNBT(nbt: CompoundTag, world: ServerLevel): SpellContinuation { - val frames = nbt.getList(TAG_FRAME, Tag.TAG_COMPOUND) - var result: SpellContinuation = Done - for (frame in frames.asReversed()) { - if (frame is CompoundTag) { - result = result.pushFrame(ContinuationFrame.fromNBT(frame, world)) + val CODEC = Codec.recursive( + SpellContinuation::class.java.simpleName + ) { recursed: Codec -> + Codec.withAlternative( + Codec.unit(Done), + RecordCodecBuilder.create { inst -> + inst.group( + ContinuationFrame.Type.TYPED_CODEC.fieldOf("frame").forGetter { it.frame }, + recursed.fieldOf("next").forGetter { it.next } + ).apply(inst, ::NotDone) } - } - return result + ) + } + @JvmStatic + val STREAM_CODEC = StreamCodec.recursive { recursed -> + withAlternative( + StreamCodec.unit(Done), + StreamCodec.composite( + ContinuationFrame.Type.TYPED_STREAM_CODEC, NotDone::frame, + recursed, NotDone::next, + ::NotDone + ).map(Function.identity()) { it as NotDone } + ) + } + + private fun withAlternative(primary: StreamCodec, alternative: StreamCodec): StreamCodec { + return ByteBufCodecs.either( + primary, + alternative + ).map( + Function { either: Either -> Either.unwrap(either) }, + Function { value: T -> Either.left(value) } + ) } } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/BooleanIota.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/BooleanIota.java index 91cf0b339d..8b03fc33c9 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/BooleanIota.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/BooleanIota.java @@ -2,21 +2,26 @@ import at.petrak.hexcasting.api.utils.HexUtils; import at.petrak.hexcasting.common.lib.hex.HexIotaTypes; +import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; +import io.netty.buffer.ByteBuf; import net.minecraft.ChatFormatting; import net.minecraft.nbt.ByteTag; import net.minecraft.nbt.Tag; +import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.chat.Component; -import net.minecraft.server.level.ServerLevel; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; public class BooleanIota extends Iota { + private boolean value; public BooleanIota(boolean d) { - super(HexIotaTypes.BOOLEAN, d); + super(() -> HexIotaTypes.BOOLEAN); + this.value = d; } public boolean getBool() { - return (boolean) this.payload; + return value; } @Override @@ -32,21 +37,30 @@ public boolean toleratesOther(Iota that) { } @Override - public @NotNull Tag serialize() { - // there is no boolean tag :( - return ByteTag.valueOf(this.getBool()); + public int hashCode() { + return Boolean.hashCode(value); + } + + @Override + public Component display() { + return BooleanIota.display(getBool()); } public static IotaType TYPE = new IotaType<>() { - @Nullable + public static final MapCodec CODEC = Codec.BOOL + .xmap(BooleanIota::new, BooleanIota::getBool) + .fieldOf("value"); + public static final StreamCodec STREAM_CODEC = + ByteBufCodecs.BOOL.map(BooleanIota::new, BooleanIota::getBool).mapStream(buffer -> buffer); + @Override - public BooleanIota deserialize(Tag tag, ServerLevel world) throws IllegalArgumentException { - return BooleanIota.deserialize(tag); + public MapCodec codec() { + return CODEC; } @Override - public Component display(Tag tag) { - return BooleanIota.display(BooleanIota.deserialize(tag).getBool()); + public StreamCodec streamCodec() { + return STREAM_CODEC; } @Override diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/ContinuationIota.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/ContinuationIota.java index 13764c4675..7eca19aa6d 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/ContinuationIota.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/ContinuationIota.java @@ -4,13 +4,17 @@ import at.petrak.hexcasting.api.casting.eval.ResolvedPatternType; import at.petrak.hexcasting.api.casting.eval.vm.CastingVM; import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation; +import at.petrak.hexcasting.api.casting.math.HexPattern; import at.petrak.hexcasting.api.utils.HexUtils; import at.petrak.hexcasting.common.lib.hex.HexEvalSounds; import at.petrak.hexcasting.common.lib.hex.HexIotaTypes; +import com.mojang.serialization.MapCodec; import net.minecraft.ChatFormatting; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.Tag; +import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.chat.Component; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.server.level.ServerLevel; import org.jetbrains.annotations.NotNull; @@ -21,13 +25,15 @@ */ public class ContinuationIota extends Iota { public static final Component DISPLAY = Component.translatable("hexcasting.tooltip.jump_iota").withStyle(ChatFormatting.RED); + private SpellContinuation value; public ContinuationIota(SpellContinuation cont) { - super(HexIotaTypes.CONTINUATION, cont); + super(() -> HexIotaTypes.CONTINUATION); + this.value = cont; } public SpellContinuation getContinuation() { - return (SpellContinuation) this.payload; + return value; } @Override @@ -40,12 +46,6 @@ public boolean toleratesOther(Iota that) { return typesMatch(this, that) && that instanceof ContinuationIota cont && cont.getContinuation().equals(getContinuation()); } - @Override - public @NotNull - Tag serialize() { - return getContinuation().serializeToNBT(); - } - @Override public @NotNull CastResult execute(CastingVM vm, ServerLevel world, SpellContinuation continuation) { return new CastResult(this, this.getContinuation(), vm.getImage(), List.of(), ResolvedPatternType.EVALUATED, HexEvalSounds.HERMES); @@ -69,16 +69,31 @@ public int size() { return Math.min(size, 1); } + @Override + public int hashCode() { + return value.hashCode(); + } + + @Override + public Component display() { + return DISPLAY; + } + public static IotaType TYPE = new IotaType<>() { + public static final MapCodec CODEC = SpellContinuation.getCODEC() + .xmap(ContinuationIota::new, ContinuationIota::getContinuation) + .fieldOf("value"); + public static final StreamCodec STREAM_CODEC = + SpellContinuation.getSTREAM_CODEC().map(ContinuationIota::new, ContinuationIota::getContinuation); + @Override - public @NotNull ContinuationIota deserialize(Tag tag, ServerLevel world) throws IllegalArgumentException { - var compoundTag = HexUtils.downcast(tag, CompoundTag.TYPE); - return new ContinuationIota(SpellContinuation.fromNBT(compoundTag, world)); + public MapCodec codec() { + return CODEC; } @Override - public Component display(Tag tag) { - return DISPLAY; + public StreamCodec streamCodec() { + return STREAM_CODEC; } @Override diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/DoubleIota.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/DoubleIota.java index e9ff20f57c..229fded62a 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/DoubleIota.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/DoubleIota.java @@ -2,23 +2,30 @@ import at.petrak.hexcasting.api.utils.HexUtils; import at.petrak.hexcasting.common.lib.hex.HexIotaTypes; +import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; import net.minecraft.ChatFormatting; import net.minecraft.nbt.DoubleTag; import net.minecraft.nbt.Tag; +import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.chat.Component; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.server.level.ServerLevel; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class DoubleIota extends Iota { public static final double TOLERANCE = 0.0001; + private double value; public DoubleIota(double d) { - super(HexIotaTypes.DOUBLE, d); + super(() -> HexIotaTypes.DOUBLE); + this.value = d; } public double getDouble() { - return HexUtils.fixNAN((Double) this.payload); + return HexUtils.fixNAN((Double) value); } @Override @@ -38,20 +45,30 @@ public static boolean tolerates(double a, double b) { } @Override - public @NotNull Tag serialize() { - return DoubleTag.valueOf(this.getDouble()); + public int hashCode() { + return Double.hashCode(value); + } + + @Override + public Component display() { + return DoubleIota.display(value); } public static IotaType TYPE = new IotaType<>() { - @Nullable + public static final MapCodec CODEC = Codec.DOUBLE + .xmap(DoubleIota::new, DoubleIota::getDouble) + .fieldOf("value"); + public static final StreamCodec STREAM_CODEC = + ByteBufCodecs.DOUBLE.map(DoubleIota::new, DoubleIota::getDouble).mapStream(buffer -> buffer); + @Override - public DoubleIota deserialize(Tag tag, ServerLevel world) throws IllegalArgumentException { - return DoubleIota.deserialize(tag); + public MapCodec codec() { + return CODEC; } @Override - public Component display(Tag tag) { - return DoubleIota.display(DoubleIota.deserialize(tag).getDouble()); + public StreamCodec streamCodec() { + return STREAM_CODEC; } @Override diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/EntityIota.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/EntityIota.java index 2a8023cf01..9c4f3bfc49 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/EntityIota.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/EntityIota.java @@ -1,36 +1,96 @@ package at.petrak.hexcasting.api.casting.iota; -import at.petrak.hexcasting.api.utils.HexUtils; import at.petrak.hexcasting.common.lib.hex.HexIotaTypes; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; import com.samsthenerd.inline.api.InlineAPI; import com.samsthenerd.inline.api.data.EntityInlineData; import com.samsthenerd.inline.api.data.PlayerHeadData; import net.minecraft.ChatFormatting; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.NbtUtils; -import net.minecraft.nbt.Tag; +import net.minecraft.core.UUIDUtil; +import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.ComponentSerialization; import net.minecraft.network.chat.MutableComponent; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.component.ResolvableProfile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.lang.ref.WeakReference; +import java.util.Optional; +import java.util.UUID; + public class EntityIota extends Iota { + private final UUID entityId; + @Nullable + private WeakReference cachedEntity; + @Nullable + private Component entityName; + public EntityIota(@NotNull Entity e) { - super(HexIotaTypes.ENTITY, e); + this(e.getUUID(), getEntityNameWithInline(e)); + this.cachedEntity = new WeakReference<>(e); } - public Entity getEntity() { - return (Entity) this.payload; + public EntityIota(UUID entityId, @Nullable Component entityName) { + super(() -> HexIotaTypes.ENTITY); + this.entityId = entityId; + this.entityName = entityName; + } + + public UUID getEntityId() { + return entityId; + } + + @Nullable + public Entity getOrFindEntity(ServerLevel level) { + // First, let's try to get it from weak reference + var entity = getCachedEntity(); + if (entity != null) + return entity; + // Now let's try to fetch it from the world + entity = level.getEntity(entityId); + // Store in weak reference + if (entity != null) + cachedEntity = new WeakReference<>(entity); + return entity; + } + + @Nullable + public Entity getCachedEntity() { + if (cachedEntity != null) + if (!cachedEntity.refersTo(null)) + return cachedEntity.get(); + else + cachedEntity = null; // Clear weakref + return null; + } + + public @Nullable Component getEntityName() { + var ent = getCachedEntity(); + if(ent != null) { + var name = getEntityNameWithInline(ent); + this.entityName = name; + return name; + } + + return getCachedEntityName(); + } + + public @Nullable Component getCachedEntityName() { + return entityName; } @Override public boolean toleratesOther(Iota that) { return typesMatch(this, that) - && that instanceof EntityIota dent - && this.getEntity() == dent.getEntity(); + && that instanceof EntityIota dent + && this.getEntityId() == dent.getEntityId(); } @Override @@ -39,63 +99,49 @@ public boolean isTruthy() { } @Override - public @NotNull - Tag serialize() { - var out = new CompoundTag(); - out.putUUID("uuid", this.getEntity().getUUID()); - out.putString("name", Component.Serializer.toJson(getEntityNameWithInline(true))); - return out; + public Component display() { + var name = getCachedEntityName(); + return name != null ? name.copy().withStyle(ChatFormatting.AQUA) : Component.translatable("hexcasting.spelldata.entity.whoknows"); } @Override - public Component display() { - return getEntityNameWithInline(false).copy().withStyle(ChatFormatting.AQUA); + public int hashCode() { + return entityId.hashCode(); } - private Component getEntityNameWithInline(boolean fearSerializer){ - MutableComponent baseName = this.getEntity().getName().copy(); - Component inlineEnt = null; - if(this.getEntity() instanceof Player player){ - inlineEnt = new PlayerHeadData(player.getGameProfile()).asText(!fearSerializer); + private static Component getEntityNameWithInline(Entity entity) { + MutableComponent baseName = entity.getName().copy(); + Component inlineEnt; + if(entity instanceof Player player){ + inlineEnt = new PlayerHeadData(new ResolvableProfile(player.getGameProfile())).asText(false); inlineEnt = inlineEnt.plainCopy().withStyle(InlineAPI.INSTANCE.withSizeModifier(inlineEnt.getStyle(), 1.5)); - } else{ - if(fearSerializer){ // we don't want to have to serialize an entity just to display it - inlineEnt = EntityInlineData.fromType(this.getEntity().getType()).asText(!fearSerializer); - } else { - inlineEnt = EntityInlineData.fromEntity(this.getEntity()).asText(!fearSerializer); - } + } else { + inlineEnt = EntityInlineData.fromType(entity.getType()).asText(false); } return baseName.append(Component.literal(": ")).append(inlineEnt); } public static IotaType TYPE = new IotaType<>() { - @Nullable + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(inst -> + inst.group( + UUIDUtil.CODEC.fieldOf("entityId").forGetter(EntityIota::getEntityId), + ComponentSerialization.CODEC.optionalFieldOf("entityName").forGetter(iota -> Optional.ofNullable(iota.getEntityName())) + ).apply(inst, (a, b) -> new EntityIota(a, b.orElse(null)))); + public static final StreamCodec STREAM_CODEC = + StreamCodec.composite( + UUIDUtil.STREAM_CODEC, EntityIota::getEntityId, + ByteBufCodecs.optional(ComponentSerialization.STREAM_CODEC), iota -> Optional.ofNullable(iota.getEntityName()), + (a, b) -> new EntityIota(a, b.orElse(null)) + ); + @Override - public EntityIota deserialize(Tag tag, ServerLevel world) throws IllegalArgumentException { - var ctag = HexUtils.downcast(tag, CompoundTag.TYPE); - Tag uuidTag = ctag.get("uuid"); - if (uuidTag == null) { - return null; - } - var uuid = NbtUtils.loadUUID(uuidTag); - var entity = world.getEntity(uuid); - if (entity == null) { - return null; - } - return new EntityIota(entity); + public MapCodec codec() { + return CODEC; } @Override - public Component display(Tag tag) { - if (!(tag instanceof CompoundTag ctag)) { - return Component.translatable("hexcasting.spelldata.entity.whoknows"); - } - if (!ctag.contains("name", Tag.TAG_STRING)) { - return Component.translatable("hexcasting.spelldata.entity.whoknows"); - } - var nameJson = ctag.getString("name"); -// return Component.literal(nameJson); - return Component.Serializer.fromJsonLenient(nameJson).withStyle(ChatFormatting.AQUA); + public StreamCodec streamCodec() { + return STREAM_CODEC; } @Override diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/GarbageIota.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/GarbageIota.java index 0824985852..f0c869b00c 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/GarbageIota.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/GarbageIota.java @@ -1,31 +1,28 @@ package at.petrak.hexcasting.api.casting.iota; import at.petrak.hexcasting.common.lib.hex.HexIotaTypes; +import com.mojang.serialization.MapCodec; import net.minecraft.ChatFormatting; -import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.Tag; +import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.chat.Component; -import net.minecraft.server.level.ServerLevel; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.Random; +import net.minecraft.network.codec.StreamCodec; /** * this is LITERALLY a copy of NullIota but I can't see how to do it any better, i hate java generics */ public class GarbageIota extends Iota { + public static final GarbageIota INSTANCE = new GarbageIota(); + private static final Object NULL_SUBSTITUTE = new Object(); public static final Component DISPLAY = Component.literal("arimfexendrapuse") .withStyle(ChatFormatting.DARK_GRAY, ChatFormatting.OBFUSCATED); - private static final Random RANDOM = new Random(); - - public GarbageIota() { + private GarbageIota() { // We have to pass *something* here, but there's nothing that actually needs to go there, // so we just do this i guess - super(HexIotaTypes.GARBAGE, NULL_SUBSTITUTE); + super(() -> HexIotaTypes.GARBAGE); } @Override @@ -39,20 +36,28 @@ public boolean toleratesOther(Iota that) { } @Override - public @NotNull Tag serialize() { - return new CompoundTag(); + public int hashCode() { + return NULL_SUBSTITUTE.hashCode(); + } + + @Override + public Component display() { + return DISPLAY; } public static IotaType TYPE = new IotaType<>() { - @Nullable + public static final MapCodec CODEC = MapCodec.unit(GarbageIota.INSTANCE); + public static final StreamCodec STREAM_CODEC = + StreamCodec.unit(GarbageIota.INSTANCE); + @Override - public GarbageIota deserialize(Tag tag, ServerLevel world) throws IllegalArgumentException { - return new GarbageIota(); + public MapCodec codec() { + return CODEC; } @Override - public Component display(Tag tag) { - return DISPLAY; + public StreamCodec streamCodec() { + return STREAM_CODEC; } @Override diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/Iota.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/Iota.java index cad6baee82..1bc2a893a4 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/Iota.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/Iota.java @@ -11,27 +11,34 @@ import at.petrak.hexcasting.api.casting.mishaps.MishapUnescapedValue; import at.petrak.hexcasting.common.lib.hex.HexEvalSounds; import at.petrak.hexcasting.common.lib.hex.HexIotaTypes; +import com.mojang.serialization.Codec; +import net.minecraft.ChatFormatting; +import net.minecraft.client.gui.Font; +import net.minecraft.nbt.NbtOps; import net.minecraft.nbt.Tag; import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.ComponentSerialization; +import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.FormattedCharSequence; +import net.minecraft.world.level.Level; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.List; +import java.util.Objects; +import java.util.function.Supplier; public abstract class Iota { @NotNull - protected final Object payload; - @NotNull - protected final IotaType type; + protected final Supplier> type; - protected Iota(@NotNull IotaType type, @NotNull Object payload) { + protected Iota(@NotNull Supplier> type) { this.type = type; - this.payload = payload; } - public @NotNull IotaType getType() { - return this.type; + public @NotNull IotaType getType() { + return this.type.get(); } abstract public boolean isTruthy(); @@ -41,13 +48,6 @@ protected Iota(@NotNull IotaType type, @NotNull Object payload) { */ abstract protected boolean toleratesOther(Iota that); - /** - * Serialize this under the {@code data} tag. - *

- * You probably don't want to call this directly; use {@link IotaType#serialize}. - */ - abstract public @NotNull Tag serialize(); - /** * This method is called when this iota is executed (i.e. Hermes is run on a list containing it, unescaped). * By default it will return a {@link CastResult} indicating an error has occurred. @@ -100,8 +100,19 @@ public int depth() { return 1; } - public Component display() { - return this.type.display(this.serialize()); + public abstract Component display(); + + public FormattedCharSequence displayWithMaxWidth(int maxWidth, Font font) { + var splitted = font.split(display(), maxWidth - font.width("...")); + if (splitted.isEmpty()) + return FormattedCharSequence.EMPTY; + else if (splitted.size() == 1) + return splitted.getFirst(); + else { + var first = splitted.getFirst(); + return FormattedCharSequence.fromPair(first, + Component.literal("...").withStyle(ChatFormatting.GRAY).getVisualOrderText()); + } } /** @@ -121,7 +132,13 @@ public static boolean tolerates(Iota a, Iota b) { } @Override - public int hashCode() { - return payload.hashCode(); + public abstract int hashCode(); + + @Override + public boolean equals(Object o) { + if(o instanceof Iota io) { + return tolerates(this, io); + } + return false; } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/IotaType.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/IotaType.java index c0167ae5df..66e4130482 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/IotaType.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/IotaType.java @@ -1,78 +1,52 @@ package at.petrak.hexcasting.api.casting.iota; -import at.petrak.hexcasting.api.HexAPI; import at.petrak.hexcasting.api.utils.HexUtils; +import at.petrak.hexcasting.common.lib.HexRegistries; import at.petrak.hexcasting.common.lib.hex.HexIotaTypes; -import com.mojang.datafixers.util.Pair; +import at.petrak.hexcasting.xplat.IXplatAbstractions; +import com.mojang.serialization.Codec; +import com.mojang.serialization.DataResult; +import com.mojang.serialization.MapCodec; import net.minecraft.ChatFormatting; import net.minecraft.client.gui.Font; import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtOps; import net.minecraft.nbt.Tag; +import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.TextColor; +import net.minecraft.network.chat.ComponentSerialization; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.level.ServerLevel; import net.minecraft.util.FormattedCharSequence; -import javax.annotation.Nullable; import java.util.List; -import java.util.Objects; +import java.util.function.Function; // Take notes from ForgeRegistryEntry public abstract class IotaType { - - /** - * Spell datums are stored as such: {@code { "type": "modid:type", "datum": a_tag }}. - *

- * The {@code type} key is given when registering the spell datum type; this method - * deserializes the tag associated with {@code "datum"}. - *

- * Returning {@code null} makes the resulting datum be {@link NullIota}. - * Throwing an exception raises a mishap. - */ - @Nullable - public abstract T deserialize(Tag tag, ServerLevel world) throws IllegalArgumentException; - - /** - * Get a display of this datum from the {@code data} tag, without the world. - * This is for use on the client. - */ - public abstract Component display(Tag tag); - - /** - * Get the color associated with this datum type. - */ - public abstract int color(); - - /** - * Get a display component that's the name of this iota type. - */ - public Component typeName() { - var key = HexIotaTypes.REGISTRY.getKey(this); - return Component.translatable("hexcasting.iota." + key) - .withStyle(style -> style.withColor(TextColor.fromRgb(color()))); - } - - public static CompoundTag serialize(Iota iota) { - var type = iota.getType(); - var typeId = HexIotaTypes.REGISTRY.getKey(type); - if (typeId == null) { - throw new IllegalStateException( - "Tried to serialize an unregistered iota type. Iota: " + iota - + " ; Type" + type.getClass().getTypeName()); - } - - // We check if it's too big on serialization; if it is we just return a garbage. - if (isTooLargeToSerialize(List.of(iota), 0)) { - // Garbage will never be too large so we just recurse - return serialize(new GarbageIota()); - } - var dataTag = iota.serialize(); - var out = new CompoundTag(); - out.putString(HexIotaTypes.KEY_TYPE, typeId.toString()); - out.put(HexIotaTypes.KEY_DATA, dataTag); - return out; - } + public static final Codec TYPED_CODEC = Codec.lazyInitialized(() -> IXplatAbstractions.INSTANCE + .getIotaTypeRegistry() + .byNameCodec() + .dispatch("type", Iota::getType, IotaType::codec) + .comapFlatMap( + iota -> { + if (isTooLargeToSerialize(List.of(iota), 0)) { + return DataResult.success(GarbageIota.INSTANCE); + } + return DataResult.success(iota); + }, + Function.identity() + ).orElse(GarbageIota.INSTANCE) + ); + public static final StreamCodec TYPED_STREAM_CODEC = ByteBufCodecs + .registry(HexRegistries.IOTA_TYPE) + .dispatch(Iota::getType, IotaType::streamCodec); + + + public abstract MapCodec codec(); + + public abstract StreamCodec streamCodec(); public static boolean isTooLargeToSerialize(Iterable examinee) { return isTooLargeToSerialize(examinee, 1); @@ -88,99 +62,10 @@ private static boolean isTooLargeToSerialize(Iterable examinee, int starti return totalSize >= HexIotaTypes.MAX_SERIALIZATION_TOTAL; } - /** - * This method attempts to find the type from the {@code type} key. - * See {@link IotaType#serialize(Iota)} for the storage format. - * - * @return {@code null} if it cannot get the type. - */ - @org.jetbrains.annotations.Nullable - public static IotaType getTypeFromTag(CompoundTag tag) { - if (!tag.contains(HexIotaTypes.KEY_TYPE, Tag.TAG_STRING)) { - return null; - } - var typeKey = tag.getString(HexIotaTypes.KEY_TYPE); - if (!ResourceLocation.isValidResourceLocation(typeKey)) { - return null; - } - var typeLoc = new ResourceLocation(typeKey); - return HexIotaTypes.REGISTRY.get(typeLoc); - } - - /** - * Attempt to deserialize an iota from a tag. - *
- * Iotas are saved as such: - * - * { - * "type": "hexcasting:atype", - * "data": {...} - * } - * - */ - public static Iota deserialize(CompoundTag tag, ServerLevel world) { - var type = getTypeFromTag(tag); - if (type == null) { - return new GarbageIota(); - } - var data = tag.get(HexIotaTypes.KEY_DATA); - if (data == null) { - return new GarbageIota(); - } - Iota deserialized; - try { - deserialized = Objects.requireNonNullElse(type.deserialize(data, world), new NullIota()); - } catch (IllegalArgumentException exn) { - HexAPI.LOGGER.warn("Caught an exception deserializing an iota", exn); - deserialized = new GarbageIota(); - } - return deserialized; - } - - private static Component brokenIota() { + public static Component brokenIota() { return Component.translatable("hexcasting.spelldata.unknown") .withStyle(ChatFormatting.GRAY, ChatFormatting.ITALIC); } - public static Component getDisplay(CompoundTag tag) { - var type = getTypeFromTag(tag); - if (type == null) { - return brokenIota(); - } - var data = tag.get(HexIotaTypes.KEY_DATA); - if (data == null) { - return brokenIota(); - } - return type.display(data); - } - - public static FormattedCharSequence getDisplayWithMaxWidth(CompoundTag tag, int maxWidth, Font font) { - var type = getTypeFromTag(tag); - if (type == null) { - return brokenIota().getVisualOrderText(); - } - var data = tag.get(HexIotaTypes.KEY_DATA); - if (data == null) { - return brokenIota().getVisualOrderText(); - } - var display = type.display(data); - var splitted = font.split(display, maxWidth - font.width("...")); - if (splitted.isEmpty()) - return FormattedCharSequence.EMPTY; - else if (splitted.size() == 1) - return splitted.get(0); - else { - var first = splitted.get(0); - return FormattedCharSequence.fromPair(first, - Component.literal("...").withStyle(ChatFormatting.GRAY).getVisualOrderText()); - } - } - - public static int getColor(CompoundTag tag) { - var type = getTypeFromTag(tag); - if (type == null) { - return HexUtils.ERROR_COLOR; - } - return type.color(); - } + public abstract int color(); } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/ListIota.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/ListIota.java index d3eb9455bf..ab41d887c4 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/ListIota.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/ListIota.java @@ -1,18 +1,15 @@ package at.petrak.hexcasting.api.casting.iota; import at.petrak.hexcasting.api.casting.SpellList; -import at.petrak.hexcasting.api.utils.HexUtils; import at.petrak.hexcasting.common.lib.hex.HexIotaTypes; +import com.mojang.serialization.MapCodec; import net.minecraft.ChatFormatting; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.ListTag; -import net.minecraft.nbt.Tag; +import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.chat.Component; -import net.minecraft.server.level.ServerLevel; +import net.minecraft.network.codec.StreamCodec; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; import java.util.List; import static java.lang.Math.max; @@ -21,11 +18,13 @@ * This is a wrapper for {@link SpellList}. */ public class ListIota extends Iota { + private SpellList list; private final int depth; private final int size; public ListIota(@NotNull SpellList list) { - super(HexIotaTypes.LIST, list); + super(() -> HexIotaTypes.LIST); + this.list = list; int maxChildDepth = 0; int totalSize = 1; for (Iota iota : list) { @@ -41,7 +40,7 @@ public ListIota(@NotNull List list) { } public SpellList getList() { - return (SpellList) this.payload; + return list; } @Override @@ -77,15 +76,6 @@ public boolean toleratesOther(Iota that) { } } - @Override - public @NotNull Tag serialize() { - var out = new ListTag(); - for (var subdatum : this.getList()) { - out.add(IotaType.serialize(subdatum)); - } - return out; - } - @Override public @Nullable Iterable subIotas() { return this.getList(); @@ -101,43 +91,45 @@ public int depth() { return depth; } - public static IotaType TYPE = new IotaType<>() { - @Nullable - @Override - public ListIota deserialize(Tag tag, ServerLevel world) throws IllegalArgumentException { - var listTag = HexUtils.downcast(tag, ListTag.TYPE); - var out = new ArrayList(listTag.size()); - - for (var sub : listTag) { - var csub = HexUtils.downcast(sub, CompoundTag.TYPE); - var subiota = IotaType.deserialize(csub, world); - if (subiota == null) { - return null; - } - out.add(subiota); + @Override + public int hashCode() { + return list.hashCode(); + } + + @Override + public Component display() { + var out = Component.empty(); + + for (int i = 0; i < list.size(); i++) { + var sub = list.getAt(i); + + out.append(sub.display()); + + // only add a comma between 2 non-patterns (commas don't look good with Inline patterns) + // TODO: maybe add a config? maybe add a method on IotaType to allow it to opt out of commas + if (i < list.size() - 1 && (sub.type != PatternIota.TYPE + || list.getAt(i + 1).type != PatternIota.TYPE)) { + out.append(", "); } + } + return Component.translatable("hexcasting.tooltip.list_contents", out).withStyle(ChatFormatting.DARK_PURPLE); + } - return new ListIota(out); + public static IotaType TYPE = new IotaType<>() { + public static final MapCodec CODEC = SpellList.getCODEC() + .xmap(ListIota::new, ListIota::getList) + .fieldOf("list"); + public static final StreamCodec STREAM_CODEC = + SpellList.getSTREAM_CODEC().map(ListIota::new, ListIota::getList); + + @Override + public MapCodec codec() { + return CODEC; } @Override - public Component display(Tag tag) { - var out = Component.empty(); - var list = HexUtils.downcast(tag, ListTag.TYPE); - for (int i = 0; i < list.size(); i++) { - Tag sub = list.get(i); - var csub = HexUtils.downcast(sub, CompoundTag.TYPE); - - out.append(IotaType.getDisplay(csub)); - - // only add a comma between 2 non-patterns (commas don't look good with Inline patterns) - // TODO: maybe add a config? maybe add a method on IotaType to allow it to opt out of commas - if (i < list.size() - 1 && (IotaType.getTypeFromTag(csub) != PatternIota.TYPE - || IotaType.getTypeFromTag(HexUtils.downcast(list.get(i+1), CompoundTag.TYPE)) != PatternIota.TYPE)) { - out.append(", "); - } - } - return Component.translatable("hexcasting.tooltip.list_contents", out).withStyle(ChatFormatting.DARK_PURPLE); + public StreamCodec streamCodec() { + return STREAM_CODEC; } @Override diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/NullIota.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/NullIota.java index 525e6b22a9..73bde5b4fb 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/NullIota.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/NullIota.java @@ -1,10 +1,13 @@ package at.petrak.hexcasting.api.casting.iota; import at.petrak.hexcasting.common.lib.hex.HexIotaTypes; +import com.mojang.serialization.MapCodec; import net.minecraft.ChatFormatting; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.Tag; +import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.chat.Component; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.server.level.ServerLevel; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -13,15 +16,14 @@ * An iota with no data associated with it. */ public class NullIota extends Iota { + public static final NullIota INSTANCE = new NullIota(); private static final Object NULL_SUBSTITUTE = new Object(); public static final Component DISPLAY = Component.translatable("hexcasting.tooltip.null_iota").withStyle(ChatFormatting.GRAY); - public NullIota() { - // We have to pass *something* here, but there's nothing that actually needs to go there, - // so we just do this i guess - super(HexIotaTypes.NULL, NULL_SUBSTITUTE); + private NullIota() { + super(() -> HexIotaTypes.NULL); } @Override @@ -35,20 +37,28 @@ public boolean toleratesOther(Iota that) { } @Override - public @NotNull Tag serialize() { - return new CompoundTag(); + public int hashCode() { + return NULL_SUBSTITUTE.hashCode(); + } + + @Override + public Component display() { + return DISPLAY; } public static IotaType TYPE = new IotaType<>() { - @Nullable + public static final MapCodec CODEC = MapCodec.unit(NullIota.INSTANCE); + public static final StreamCodec STREAM_CODEC = + StreamCodec.unit(NullIota.INSTANCE); + @Override - public NullIota deserialize(Tag tag, ServerLevel world) throws IllegalArgumentException { - return new NullIota(); + public MapCodec codec() { + return CODEC; } @Override - public Component display(Tag tag) { - return DISPLAY; + public StreamCodec streamCodec() { + return STREAM_CODEC; } @Override diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/PatternIota.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/PatternIota.java index b86e8541ce..91fa4fe2f2 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/PatternIota.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/PatternIota.java @@ -21,11 +21,16 @@ import at.petrak.hexcasting.common.lib.hex.HexIotaTypes; import at.petrak.hexcasting.interop.inline.InlinePatternData; import at.petrak.hexcasting.xplat.IXplatAbstractions; +import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; import net.minecraft.ChatFormatting; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.Tag; +import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Style; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.resources.ResourceKey; import net.minecraft.server.level.ServerLevel; import org.jetbrains.annotations.NotNull; @@ -38,16 +43,15 @@ import static at.petrak.hexcasting.api.utils.HexUtils.isOfTag; public class PatternIota extends Iota { + private HexPattern value; + public PatternIota(@NotNull HexPattern pattern) { - super(HexIotaTypes.PATTERN, pattern); + super(() -> HexIotaTypes.PATTERN); + this.value = pattern; } public HexPattern getPattern() { - return (HexPattern) this.payload; - } - - protected PatternIota(@NotNull IotaType type, @NotNull Object payload) { - super(type, payload); + return value; } @Override @@ -62,11 +66,6 @@ public boolean toleratesOther(Iota that) { && this.getPattern().getAngles().equals(piota.getPattern().getAngles()); } - @Override - public @NotNull Tag serialize() { - return this.getPattern().serializeToNBT(); - } - @Override public @NotNull CastResult execute(CastingVM vm, ServerLevel world, SpellContinuation continuation) { Supplier<@Nullable Component> castedName = () -> null; @@ -140,15 +139,31 @@ public boolean executable() { return true; } + @Override + public int hashCode() { + return value.hashCode(); + } + + @Override + public Component display() { + return PatternIota.display(getPattern()); + } + public static IotaType TYPE = new IotaType<>() { + public static final MapCodec CODEC = HexPattern.CODEC + .xmap(PatternIota::new, PatternIota::getPattern) + .fieldOf("value"); + public static final StreamCodec STREAM_CODEC = + HexPattern.STREAM_CODEC.map(PatternIota::new, PatternIota::getPattern); + @Override - public PatternIota deserialize(Tag tag, ServerLevel world) throws IllegalArgumentException { - return PatternIota.deserialize(tag); + public MapCodec codec() { + return CODEC; } @Override - public Component display(Tag tag) { - return PatternIota.display(PatternIota.deserialize(tag).getPattern()); + public StreamCodec streamCodec() { + return STREAM_CODEC; } @Override @@ -157,12 +172,6 @@ public int color() { } }; - public static PatternIota deserialize(Tag tag) throws IllegalArgumentException { - var patTag = HexUtils.downcast(tag, CompoundTag.TYPE); - HexPattern pat = HexPattern.fromNBT(patTag); - return new PatternIota(pat); - } - public static Component display(HexPattern pat) { Component text = (new InlinePatternData(pat)).asText(true); return text.copy().withStyle(text.getStyle().applyTo(Style.EMPTY.withColor(ChatFormatting.WHITE))); diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/Vec3Iota.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/Vec3Iota.java index 9d9d7fbf67..8836869fce 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/Vec3Iota.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/Vec3Iota.java @@ -2,27 +2,35 @@ import at.petrak.hexcasting.api.utils.HexUtils; import at.petrak.hexcasting.common.lib.hex.HexIotaTypes; +import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; import net.minecraft.ChatFormatting; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.LongArrayTag; import net.minecraft.nbt.Tag; +import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.chat.Component; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.phys.Vec3; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.List; + public class Vec3Iota extends Iota { + private Vec3 value; public Vec3Iota(@NotNull Vec3 datum) { - super(HexIotaTypes.VEC3, datum); + super(() -> HexIotaTypes.VEC3); + this.value = datum; } public Vec3 getVec3() { - var v = (Vec3) this.payload; return new Vec3( - HexUtils.fixNAN(v.x), - HexUtils.fixNAN(v.y), - HexUtils.fixNAN(v.z) + HexUtils.fixNAN(value.x), + HexUtils.fixNAN(value.y), + HexUtils.fixNAN(value.z) ); } @@ -40,20 +48,36 @@ public boolean toleratesOther(Iota that) { } @Override - public @NotNull Tag serialize() { - return HexUtils.serializeToNBT(this.getVec3()); + public int hashCode() { + return value.hashCode(); + } + + @Override + public Component display() { + return Vec3Iota.display(getVec3()); } public static IotaType TYPE = new IotaType<>() { - @Nullable + public static final MapCodec CODEC = Vec3.CODEC + .xmap(Vec3Iota::new, Vec3Iota::getVec3) + .fieldOf("value"); + // TODO replace with Vec3 codec if it will appear somewhere + public static final StreamCodec STREAM_CODEC = + ByteBufCodecs.DOUBLE.apply(ByteBufCodecs.list()) + .map( + l -> new Vec3Iota(new Vec3(l.get(0), l.get(1), l.get(2))), + iota -> List.of(iota.getVec3().x, iota.getVec3().y, iota.getVec3().z) + ) + .mapStream(b -> b); + @Override - public Vec3Iota deserialize(Tag tag, ServerLevel world) throws IllegalArgumentException { - return Vec3Iota.deserialize(tag); + public MapCodec codec() { + return CODEC; } @Override - public Component display(Tag tag) { - return Vec3Iota.display(Vec3Iota.deserialize(tag).getVec3()); + public StreamCodec streamCodec() { + return STREAM_CODEC; } @Override @@ -62,16 +86,6 @@ public int color() { } }; - public static Vec3Iota deserialize(Tag tag) throws IllegalArgumentException { - Vec3 vec; - if (tag.getType() == LongArrayTag.TYPE) { - var lat = HexUtils.downcast(tag, LongArrayTag.TYPE); - vec = HexUtils.vecFromNBT(lat.getAsLongArray()); - } else - vec = HexUtils.vecFromNBT(HexUtils.downcast(tag, CompoundTag.TYPE)); - return new Vec3Iota(vec); - } - public static Component display(double x, double y, double z) { return Component.literal(String.format("(%.2f, %.2f, %.2f)", x, y, z)) .withStyle(ChatFormatting.RED); diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexDir.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexDir.kt index 03f4ca5a56..b11ba185a0 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexDir.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexDir.kt @@ -2,6 +2,10 @@ package at.petrak.hexcasting.api.casting.math import at.petrak.hexcasting.api.utils.getSafe import com.mojang.serialization.Codec +import io.netty.buffer.ByteBuf +import net.minecraft.network.RegistryFriendlyByteBuf +import net.minecraft.network.codec.ByteBufCodecs +import net.minecraft.network.codec.StreamCodec enum class HexDir { NORTH_EAST, EAST, SOUTH_EAST, SOUTH_WEST, WEST, NORTH_WEST; @@ -31,6 +35,10 @@ enum class HexDir { HexDir::fromString, HexDir::name ) + val STREAM_CODEC: StreamCodec = ByteBufCodecs.STRING_UTF8.map( + HexDir::fromString, + HexDir::name + ) @JvmStatic fun fromString(key: String): HexDir { diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexPattern.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexPattern.kt index 001cfdeab4..9dea87f1bc 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexPattern.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexPattern.kt @@ -8,6 +8,9 @@ import com.mojang.serialization.Codec import com.mojang.serialization.codecs.RecordCodecBuilder import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.Tag +import net.minecraft.network.RegistryFriendlyByteBuf +import net.minecraft.network.codec.ByteBufCodecs +import net.minecraft.network.codec.StreamCodec import net.minecraft.world.phys.Vec2 /** @@ -73,12 +76,6 @@ data class HexPattern(val startDir: HexDir, val angles: MutableList = fun finalDir(): HexDir = this.angles.fold(this.startDir) { acc, angle -> acc * angle } - - fun serializeToNBT() = NBTBuilder { - TAG_START_DIR %= byte(startDir.ordinal) - TAG_ANGLES %= byteArray(angles.map(HexAngle::ordinal)) - } - // Terrible shorthand method for easy matching fun anglesSignature(): String { return buildString { @@ -126,28 +123,19 @@ data class HexPattern(val startDir: HexDir, val angles: MutableList = } companion object { - const val TAG_START_DIR = "start_dir" - const val TAG_ANGLES = "angles" - @JvmField val CODEC: Codec = RecordCodecBuilder.create({instance -> instance.group( - Codec.STRING.fieldOf(TAG_START_DIR).forGetter(HexPattern::anglesSignature), - HexDir.CODEC.fieldOf(TAG_ANGLES).forGetter(HexPattern::startDir) + Codec.STRING.fieldOf("start_dir").forGetter(HexPattern::anglesSignature), + HexDir.CODEC.fieldOf("angles").forGetter(HexPattern::startDir) ).apply(instance, HexPattern::fromAngles) }) - @JvmStatic - fun isPattern(tag: CompoundTag): Boolean { - return tag.contains(TAG_START_DIR, Tag.TAG_ANY_NUMERIC.toInt()) - && tag.contains(TAG_ANGLES, Tag.TAG_BYTE_ARRAY.toInt()) - } - - @JvmStatic - fun fromNBT(tag: CompoundTag): HexPattern { - val startDir = HexDir.values().getSafe(tag.getByte(TAG_START_DIR)) - val angles = tag.getByteArray(TAG_ANGLES).map(HexAngle.values()::getSafe) - return HexPattern(startDir, angles.toMutableList()) - } + @JvmField + val STREAM_CODEC: StreamCodec = StreamCodec.composite( + ByteBufCodecs.STRING_UTF8, HexPattern::anglesSignature, + HexDir.STREAM_CODEC, HexPattern::startDir, + HexPattern::fromAngles + ) @JvmStatic fun fromAngles(signature: String, startDir: HexDir): HexPattern { diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapAlreadyBrainswept.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapAlreadyBrainswept.kt index d076dd36e2..fcfe86b2d7 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapAlreadyBrainswept.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapAlreadyBrainswept.kt @@ -5,7 +5,6 @@ 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.common.lib.HexDamageTypes -import at.petrak.hexcasting.mixin.accessor.AccessorDamageSource import net.minecraft.world.entity.Mob import net.minecraft.world.item.DyeColor @@ -14,11 +13,7 @@ class MishapAlreadyBrainswept(val mob: Mob) : Mishap() { dyeColor(DyeColor.GREEN) override fun execute(ctx: CastingEnvironment, errorCtx: Context, stack: MutableList) { - trulyHurt( - mob, - (mob.damageSources() as AccessorDamageSource).`hex$source`(HexDamageTypes.OVERCAST, ctx.castingEntity)!!, - mob.health - ) + mob.hurt(mob.damageSources().source(HexDamageTypes.OVERCAST, ctx.castingEntity), mob.health) } override fun particleSpray(ctx: CastingEnvironment) = diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadBrainsweep.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadBrainsweep.kt index 7054802563..601273fbb0 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadBrainsweep.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadBrainsweep.kt @@ -5,7 +5,6 @@ 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.common.lib.HexDamageTypes -import at.petrak.hexcasting.mixin.accessor.AccessorDamageSource import net.minecraft.core.BlockPos import net.minecraft.world.entity.Mob import net.minecraft.world.item.DyeColor @@ -16,11 +15,7 @@ class MishapBadBrainsweep(val mob: Mob, val pos: BlockPos) : Mishap() { dyeColor(DyeColor.GREEN) override fun execute(ctx: CastingEnvironment, errorCtx: Context, stack: MutableList) { - trulyHurt( - mob, - (mob.damageSources() as AccessorDamageSource).`hex$source`(HexDamageTypes.OVERCAST, ctx.castingEntity)!!, - 1f - ) + trulyHurt(mob, mob.damageSources().source(HexDamageTypes.OVERCAST, ctx.castingEntity), 1f) } override fun particleSpray(ctx: CastingEnvironment): ParticleSpray { diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadEntity.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadEntity.kt index a9334f0137..f176e62769 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadEntity.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadEntity.kt @@ -19,7 +19,7 @@ class MishapBadEntity(val entity: Entity, val wanted: Component) : Mishap() { } override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = - error("bad_entity", wanted, entity.displayName!!.plainCopy().aqua) + error("bad_entity", wanted, entity.displayName?.plainCopy()?.aqua ?: entity.type.description.plainCopy().aqua) companion object { @JvmStatic diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapDivideByZero.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapDivideByZero.kt index 98050ee244..b31a0c84f3 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapDivideByZero.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapDivideByZero.kt @@ -17,7 +17,7 @@ class MishapDivideByZero(val operand1: Component, val operand2: Component, val s dyeColor(DyeColor.RED) override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { - stack.add(GarbageIota()) + stack.add(GarbageIota.INSTANCE) env.mishapEnvironment.damage(0.5f) } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapEntityTooFarAway.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapEntityTooFarAway.kt index d486bff74d..5f196d376f 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapEntityTooFarAway.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapEntityTooFarAway.kt @@ -3,6 +3,7 @@ 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.aqua import net.minecraft.network.chat.Component import net.minecraft.world.entity.Entity import net.minecraft.world.item.DyeColor @@ -16,5 +17,5 @@ class MishapEntityTooFarAway(val entity: Entity) : Mishap() { } override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context): Component = - error("entity_too_far", entity.displayName!!) + error("entity_too_far", entity.displayName?.plainCopy() ?: entity.type.description) } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapEntityUnavailable.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapEntityUnavailable.kt new file mode 100644 index 0000000000..9ec7232fb9 --- /dev/null +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapEntityUnavailable.kt @@ -0,0 +1,20 @@ +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.aqua +import net.minecraft.ChatFormatting +import net.minecraft.network.chat.Component +import net.minecraft.world.item.DyeColor +import java.util.* + +class MishapEntityUnavailable(val entityId: UUID, val entityName: Component?) : Mishap() { + override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = + dyeColor(DyeColor.BROWN) + + override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) {} + + override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = + error("unavailable_entity", entityName?.plainCopy()?.aqua ?: Component.literal(entityId.toString()).withStyle(ChatFormatting.AQUA)) +} diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapEvalTooMuch.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapEvalTooMuch.kt index 24ecda81e8..1634cd63e1 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapEvalTooMuch.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapEvalTooMuch.kt @@ -14,5 +14,5 @@ class MishapEvalTooMuch : Mishap() { } override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = - error("eval_too_deep") + error("eval_too_much") } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapImmuneEntity.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapImmuneEntity.kt index 1a027a1a77..ca2622947a 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapImmuneEntity.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapImmuneEntity.kt @@ -4,6 +4,8 @@ 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.aqua +import net.minecraft.core.registries.Registries +import net.minecraft.network.chat.Component import net.minecraft.world.entity.Entity import net.minecraft.world.item.DyeColor @@ -16,5 +18,5 @@ class MishapImmuneEntity(val entity: Entity) : Mishap() { } override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = - error("immune_entity", entity.displayName!!.plainCopy().aqua) + error("immune_entity", entity.displayName?.plainCopy()?.aqua ?: entity.type.description.plainCopy().aqua) } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidIota.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidIota.kt index 17e71d6044..3645a95ab7 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidIota.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidIota.kt @@ -20,7 +20,7 @@ class MishapInvalidIota( dyeColor(DyeColor.GRAY) override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { - stack[stack.size - 1 - reverseIdx] = GarbageIota(); + stack[stack.size - 1 - reverseIdx] = GarbageIota.INSTANCE; } override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidOperatorArgs.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidOperatorArgs.kt index a16c083f4c..187ecd8dac 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidOperatorArgs.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidOperatorArgs.kt @@ -18,7 +18,7 @@ class MishapInvalidOperatorArgs(val perpetrators: List) : Mishap() { override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { for (i in perpetrators.indices) { - stack[stack.size - 1 - i] = GarbageIota() + stack[stack.size - 1 - i] = GarbageIota.INSTANCE } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidPattern.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidPattern.kt index 20fbd31fb5..e52b71a2cc 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidPattern.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidPattern.kt @@ -14,7 +14,7 @@ class MishapInvalidPattern : Mishap() { override fun resolutionType(ctx: CastingEnvironment) = ResolvedPatternType.INVALID override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { - stack.add(GarbageIota()) + stack.add(GarbageIota.INSTANCE) } override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapLocationInWrongDimension.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapLocationInWrongDimension.kt index 2d0e721838..c13b88af58 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapLocationInWrongDimension.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapLocationInWrongDimension.kt @@ -13,7 +13,7 @@ class MishapLocationInWrongDimension(val properDimension: ResourceLocation) : Mi dyeColor(DyeColor.MAGENTA) override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { - stack.add(GarbageIota()) + stack.add(GarbageIota.INSTANCE) } override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context): Component = diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapNotEnoughArgs.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapNotEnoughArgs.kt index 646f42c927..beed34a8de 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapNotEnoughArgs.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapNotEnoughArgs.kt @@ -11,7 +11,7 @@ class MishapNotEnoughArgs(val expected: Int, val got: Int) : Mishap() { dyeColor(DyeColor.LIGHT_GRAY) override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { - repeat(expected - got) { stack.add(GarbageIota()) } + repeat(expected - got) { stack.add(GarbageIota.INSTANCE) } } override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapOthersName.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapOthersName.kt index e6ea0326ed..629ed69189 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapOthersName.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapOthersName.kt @@ -5,6 +5,7 @@ import at.petrak.hexcasting.api.casting.iota.EntityIota import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.ListIota import at.petrak.hexcasting.api.pigment.FrozenPigment +import net.minecraft.server.level.ServerLevel import net.minecraft.world.entity.player.Player import net.minecraft.world.item.DyeColor @@ -33,14 +34,19 @@ class MishapOthersName(val confidant: Player) : Mishap() { * If `caster` is non-null, it will ignore that when checking. */ @JvmStatic - fun getTrueNameFromDatum(datum: Iota, caster: Player?): Player? { + fun getTrueNameFromDatum(level: ServerLevel, datum: Iota, caster: Player?): Player? { val poolToSearch = ArrayDeque() poolToSearch.addLast(datum) while (poolToSearch.isNotEmpty()) { val datumToCheck = poolToSearch.removeFirst() - if (datumToCheck is EntityIota && datumToCheck.entity is Player && datumToCheck.entity != caster) - return datumToCheck.entity as Player + + if(datumToCheck is EntityIota) { + var ent = datumToCheck.getOrFindEntity(level) + if(ent is Player && ent != caster) + return ent + } + val datumSubIotas = datumToCheck.subIotas() if (datumSubIotas != null) poolToSearch.addAll(datumSubIotas) @@ -50,8 +56,8 @@ class MishapOthersName(val confidant: Player) : Mishap() { } @JvmStatic - fun getTrueNameFromArgs(datums: List, caster: Player?): Player? { - return datums.firstNotNullOfOrNull { getTrueNameFromDatum(it, caster) } + fun getTrueNameFromArgs(level: ServerLevel, datums: List, caster: Player?): Player? { + return datums.firstNotNullOfOrNull { getTrueNameFromDatum(level, it, caster) } } } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapStackSize.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapStackSize.kt index 571e39bcd9..87dc91a010 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapStackSize.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapStackSize.kt @@ -16,7 +16,7 @@ class MishapStackSize() : Mishap() { override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { stack.clear() - stack.add(GarbageIota()) + stack.add(GarbageIota.INSTANCE) } override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/circle/MishapNoSpellCircle.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/circle/MishapNoSpellCircle.kt index ba8fe81034..b1615fe604 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/circle/MishapNoSpellCircle.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/circle/MishapNoSpellCircle.kt @@ -4,22 +4,20 @@ import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.mishaps.Mishap import at.petrak.hexcasting.api.pigment.FrozenPigment -import net.minecraft.resources.ResourceLocation +import net.minecraft.core.component.DataComponents import net.minecraft.server.level.ServerPlayer import net.minecraft.world.entity.player.Player import net.minecraft.world.item.DyeColor import net.minecraft.world.item.ItemStack +import net.minecraft.world.item.enchantment.EnchantmentHelper +import net.minecraft.world.item.enchantment.Enchantments class MishapNoSpellCircle : Mishap() { override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = dyeColor(DyeColor.LIGHT_BLUE) // FIXME: make me work with any entity and not just players - private inline fun dropAll( - player: Player, - stacks: MutableList, - filter: (ItemStack) -> Boolean = { true } - ) { + private inline fun dropAll(player: Player, stacks: MutableList, filter: (ItemStack) -> Boolean = { true }) { for (index in stacks.indices) { val item = stacks[index] if (!item.isEmpty && filter(item)) { @@ -36,7 +34,7 @@ class MishapNoSpellCircle : Mishap() { dropAll(caster, caster.inventory.items) dropAll(caster, caster.inventory.offhand) dropAll(caster, caster.inventory.armor) { - it.enchantments.keySet().any { ench -> ench.`is`(ResourceLocation.parse("minecraft:binding_curse")) } + it.get(DataComponents.ENCHANTMENTS)?.keySet()?.any { e -> e.`is`(Enchantments.BINDING_CURSE) } != true } } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/item/IotaHolderItem.java b/Common/src/main/java/at/petrak/hexcasting/api/item/IotaHolderItem.java index c312383129..db7e60859c 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/item/IotaHolderItem.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/item/IotaHolderItem.java @@ -5,6 +5,7 @@ import at.petrak.hexcasting.api.utils.HexUtils; import at.petrak.hexcasting.api.utils.NBTHelper; import at.petrak.hexcasting.client.ClientTickCounter; +import at.petrak.hexcasting.common.lib.HexDataComponents; import at.petrak.hexcasting.common.lib.hex.HexIotaTypes; import net.minecraft.ChatFormatting; import net.minecraft.nbt.CompoundTag; @@ -26,30 +27,15 @@ * and the appropriate cap/CC will be attached. */ public interface IotaHolderItem { - /** - * If this key is set on the item, we ignore the rest of the item and render this as if it were of the - * {@link at.petrak.hexcasting.api.casting.iota.IotaType IotaType} given by the resource location. - *

- * This is not useful to the player at all. - */ - String TAG_OVERRIDE_VISUALLY = "VisualOverride"; - - @Nullable - CompoundTag readIotaTag(ItemStack stack); @Nullable - default Iota readIota(ItemStack stack, ServerLevel world) { - if (!(stack.getItem() instanceof IotaHolderItem dh)) { + default Iota readIota(ItemStack stack) { + if (!(stack.getItem() instanceof IotaHolderItem)) { // this should be checked via mishap beforehand throw new IllegalArgumentException("stack's item must be an IotaHolderItem but was " + stack.getItem()); } - var tag = dh.readIotaTag(stack); - if (tag != null) { - return IotaType.deserialize(tag, world); - } else { - return null; - } + return stack.get(HexDataComponents.IOTA); } /** @@ -61,28 +47,18 @@ default Iota emptyIota(ItemStack stack) { } default int getColor(ItemStack stack) { - if (NBTHelper.hasString(stack, TAG_OVERRIDE_VISUALLY)) { - var override = NBTHelper.getString(stack, TAG_OVERRIDE_VISUALLY); - - if (override != null && ResourceLocation.isValidResourceLocation(override)) { - var key = new ResourceLocation(override); - if (HexIotaTypes.REGISTRY.containsKey(key)) { - var iotaType = HexIotaTypes.REGISTRY.get(key); - if (iotaType != null) { - return iotaType.color(); - } - } - } - - return 0xFF000000 | Mth.hsvToRgb(ClientTickCounter.getTotal() * 2 % 360 / 360F, 0.75F, 1F); + var override = stack.get(HexDataComponents.VISUAL_OVERRIDE); + //noinspection OptionalAssignedToNull + if (override != null) { + return override.map(IotaType::color).orElseGet(() -> 0xFF000000 | Mth.hsvToRgb(ClientTickCounter.getTotal() * 2 % 360 / 360F, 0.75F, 1F)); } - var tag = this.readIotaTag(stack); - if (tag == null) { + var iota = this.readIota(stack); + if (iota == null) { return HexUtils.ERROR_COLOR; } - return IotaType.getColor(tag); + return iota.getType().color(); } /** @@ -102,15 +78,16 @@ default int getColor(ItemStack stack) { static void appendHoverText(IotaHolderItem self, ItemStack stack, List components, TooltipFlag flag) { - var datumTag = self.readIotaTag(stack); - if (datumTag != null) { - var cmp = IotaType.getDisplay(datumTag); + var datum = self.readIota(stack); + if (datum != null) { + var cmp = datum.display(); components.add(Component.translatable("hexcasting.spelldata.onitem", cmp)); - if (flag.isAdvanced()) { - components.add(Component.literal("").append(NbtUtils.toPrettyComponent(datumTag))); - } - } else if (NBTHelper.hasString(stack, IotaHolderItem.TAG_OVERRIDE_VISUALLY)) { + //TODO port: show NBT in advanced display + /*if (flag.isAdvanced()) { + components.add(Component.literal("").append(NbtUtils.toPrettyComponent(datum))); + }*/ + } else if (stack.has(HexDataComponents.VISUAL_OVERRIDE)) { components.add(Component.translatable("hexcasting.spelldata.onitem", Component.translatable("hexcasting.spelldata.anything").withStyle(ChatFormatting.LIGHT_PURPLE))); } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/item/VariantItem.java b/Common/src/main/java/at/petrak/hexcasting/api/item/VariantItem.java index 6bdca2d2d7..d242fe9edb 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/item/VariantItem.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/item/VariantItem.java @@ -1,6 +1,7 @@ package at.petrak.hexcasting.api.item; import at.petrak.hexcasting.api.utils.NBTHelper; +import at.petrak.hexcasting.common.lib.HexDataComponents; import net.minecraft.world.item.ItemStack; /** @@ -10,16 +11,16 @@ * and the appropriate cap/CC will be attached. */ public interface VariantItem { - String TAG_VARIANT = "variant"; int numVariants(); default int getVariant(ItemStack stack) { - return NBTHelper.getInt(stack, TAG_VARIANT, 0); + var variant = stack.get(HexDataComponents.VARIANT); + return variant != null ? variant : 0; } default void setVariant(ItemStack stack, int variant) { - NBTHelper.putInt(stack, TAG_VARIANT, clampVariant(variant)); + stack.set(HexDataComponents.VARIANT, clampVariant(variant)); } default int clampVariant(int variant) { diff --git a/Common/src/main/java/at/petrak/hexcasting/api/mod/HexConfig.java b/Common/src/main/java/at/petrak/hexcasting/api/mod/HexConfig.java index 19458cbc8e..f22b1b82a2 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/mod/HexConfig.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/mod/HexConfig.java @@ -67,6 +67,8 @@ public interface ServerConfigAccess { boolean isActionAllowedInCircles(ResourceLocation actionID); + boolean doesGreaterTeleportSplatItems(); + boolean doVillagersTakeOffenseAtMindMurder(); // fun fact, although dimension keys are a RegistryHolder, they aren't a registry, so i can't do tags @@ -74,10 +76,15 @@ public interface ServerConfigAccess { boolean trueNameHasAmbit(); + double traderScrollChance(); + int DEFAULT_MAX_OP_COUNT = 100_000; int DEFAULT_MAX_SPELL_CIRCLE_LENGTH = 1024; int DEFAULT_OP_BREAK_HARVEST_LEVEL = 3; + double DEFAULT_TRADER_SCROLL_CHANCE = 0.2; + boolean DEFAULT_GREATER_TELEPORT_SPLATS_ITEMS = true; + boolean DEFAULT_VILLAGERS_DISLIKE_MIND_MURDER = true; List DEFAULT_DIM_TP_DENYLIST = List.of("twilightforest:twilight_forest"); @@ -99,11 +106,9 @@ default Tier opBreakHarvestLevel() { // Simple extensions for resource location configs public static boolean anyMatch(List keys, ResourceLocation key) { for (String s : keys) { - if (ResourceLocation.isValidResourceLocation(s)) { - var rl = new ResourceLocation(s); - if (rl.equals(key)) { - return true; - } + var rl = ResourceLocation.tryParse(s); + if (rl != null && rl.equals(key)) { + return true; } } return false; diff --git a/Common/src/main/java/at/petrak/hexcasting/api/mod/HexTags.java b/Common/src/main/java/at/petrak/hexcasting/api/mod/HexTags.java index 238afae719..a9c5b2d4e7 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/mod/HexTags.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/mod/HexTags.java @@ -47,6 +47,8 @@ public static final class Blocks { public static final TagKey CHEAP_TO_BREAK_BLOCK = create("cheap_to_break_block"); + public static final TagKey HEX_UNBREAKABLE = create("hex_unbreakable"); + public static TagKey create(String name) { return TagKey.create(Registries.BLOCK, modLoc(name)); } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/pigment/FrozenPigment.java b/Common/src/main/java/at/petrak/hexcasting/api/pigment/FrozenPigment.java index f5cd478e0e..b9a42d6680 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/pigment/FrozenPigment.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/pigment/FrozenPigment.java @@ -2,8 +2,14 @@ import at.petrak.hexcasting.common.lib.HexItems; import at.petrak.hexcasting.xplat.IXplatAbstractions; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.Util; +import net.minecraft.core.HolderLookup; +import net.minecraft.core.UUIDUtil; import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.world.item.ItemStack; import java.util.UUID; @@ -16,33 +22,20 @@ * Get it once, and then query it a lot. */ public record FrozenPigment(ItemStack item, UUID owner) { - - public static final String TAG_STACK = "stack"; - public static final String TAG_OWNER = "owner"; - public static final Supplier DEFAULT = - () -> new FrozenPigment(new ItemStack(HexItems.DEFAULT_PIGMENT), Util.NIL_UUID); - - public CompoundTag serializeToNBT() { - var out = new CompoundTag(); - out.put(TAG_STACK, this.item.save(new CompoundTag())); - out.putUUID(TAG_OWNER, this.owner); - return out; - } - - public static FrozenPigment fromNBT(CompoundTag tag) { - if (tag.isEmpty()) { - return FrozenPigment.DEFAULT.get(); - } - try { - CompoundTag stackTag = tag.getCompound(TAG_STACK); - var stack = ItemStack.of(stackTag); - var uuid = tag.getUUID(TAG_OWNER); - return new FrozenPigment(stack, uuid); - } catch (NullPointerException exn) { - return FrozenPigment.DEFAULT.get(); - } - } + () -> new FrozenPigment(new ItemStack(HexItems.DEFAULT_PIGMENT), Util.NIL_UUID); + + public static Codec CODEC = RecordCodecBuilder.create(inst -> + inst.group( + ItemStack.CODEC.fieldOf("stack").forGetter(FrozenPigment::item), + UUIDUtil.CODEC.fieldOf("owner").forGetter(FrozenPigment::owner) + ).apply(inst, FrozenPigment::new)).orElseGet(FrozenPigment.DEFAULT); + //TODO port: maybe default here too somehow?.. + public static StreamCodec STREAM_CODEC = StreamCodec.composite( + ItemStack.STREAM_CODEC, FrozenPigment::item, + UUIDUtil.STREAM_CODEC, FrozenPigment::owner, + FrozenPigment::new + ); public ColorProvider getColorProvider() { return IXplatAbstractions.INSTANCE.getColorProvider(this); diff --git a/Common/src/main/java/at/petrak/hexcasting/api/player/AltioraAbility.java b/Common/src/main/java/at/petrak/hexcasting/api/player/AltioraAbility.java index 304a02121d..b16c295711 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/player/AltioraAbility.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/player/AltioraAbility.java @@ -1,5 +1,9 @@ package at.petrak.hexcasting.api.player; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; + /** * Note that this just keeps track of state, actually giving the player the elytra ability is handled * differently per platform @@ -7,4 +11,8 @@ * @param gracePeriod so the flight isn't immediately removed because the player started on the ground */ public record AltioraAbility(int gracePeriod) { + public static final StreamCodec STREAM_CODEC = ByteBufCodecs.VAR_INT.map( + AltioraAbility::new, + AltioraAbility::gracePeriod + ).mapStream(b -> b); } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/player/Sentinel.java b/Common/src/main/java/at/petrak/hexcasting/api/player/Sentinel.java index 867b4fca34..189a88b74a 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/player/Sentinel.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/player/Sentinel.java @@ -1,5 +1,10 @@ package at.petrak.hexcasting.api.player; +import at.petrak.paucal.api.PaucalCodecs; +import net.minecraft.core.registries.Registries; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.resources.ResourceKey; import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; @@ -8,4 +13,11 @@ * A null sentinel means no sentinel */ public record Sentinel(boolean extendsRange, Vec3 position, ResourceKey dimension) { + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.BOOL, Sentinel::extendsRange, + PaucalCodecs.VEC3, Sentinel::position, + ResourceKey.streamCodec(Registries.DIMENSION), Sentinel::dimension, + Sentinel::new + ); } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/utils/HexUtils.kt b/Common/src/main/java/at/petrak/hexcasting/api/utils/HexUtils.kt index 7629783a56..a4302bd3c4 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/utils/HexUtils.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/utils/HexUtils.kt @@ -16,6 +16,7 @@ import net.minecraft.resources.ResourceKey import net.minecraft.resources.ResourceLocation import net.minecraft.tags.TagKey import net.minecraft.world.InteractionHand +import net.minecraft.world.item.ItemStack import net.minecraft.world.phys.Vec2 import net.minecraft.world.phys.Vec3 import java.lang.ref.WeakReference @@ -43,7 +44,6 @@ fun vecFromNBT(tag: LongArray): Vec3 = if (tag.size != 3) Vec3.ZERO else Double.fromBits(tag[1]), Double.fromBits(tag[2]) ) - fun vecFromNBT(tag: CompoundTag): Vec3 { return if (!tag.contains("x") || !tag.contains("y") || !tag.contains("z")) Vec3.ZERO @@ -258,15 +258,6 @@ inline operator fun WeakValue.setValue(thisRef: Any?, property: KProperty this.value = value } -/** - * Returns an empty list if it's too complicated. - */ -fun Iterable.serializeToNBT() = - if (IotaType.isTooLargeToSerialize(this)) - ListTag() - else - ListIota(this.toList()).serialize() - fun Iterable.serializeToNBT(): ByteArrayTag { val out = ByteArray(if (this is Collection<*>) this.size else 10) for ((i, b) in this.withIndex()) { @@ -282,13 +273,6 @@ fun List.zipWithDefault(array: ByteArray, default: (idx: Int) -> Byte): L return list } -// -//// Copy the impl from forge -//fun ItemStack.serializeToNBT(): CompoundTag { -// val out = CompoundTag() -// this.save(out) -// return out -//} @Suppress("UNCHECKED_CAST") @Throws(IllegalArgumentException::class) diff --git a/Common/src/main/java/at/petrak/hexcasting/api/utils/NBTHelper.kt b/Common/src/main/java/at/petrak/hexcasting/api/utils/NBTHelper.kt index f72ee92e31..5d33a71992 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/utils/NBTHelper.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/utils/NBTHelper.kt @@ -1,7 +1,5 @@ @file:JvmName("NBTHelper") -// TODO this entire file needs to be HEAVILY refactored. also i need to understand components - package at.petrak.hexcasting.api.utils import net.minecraft.nbt.* @@ -117,12 +115,9 @@ fun CompoundTag.getList(key: String, objType: Byte): ListTag = getList(key, objT // Get-or-create -fun CompoundTag.getOrCreateCompound(key: String): CompoundTag = - getCompound(key) ?: CompoundTag().also { putCompound(key, it) } - +fun CompoundTag.getOrCreateCompound(key: String): CompoundTag = getCompound(key) ?: CompoundTag().also { putCompound(key, it) } fun CompoundTag.getOrCreateList(key: String, objType: Byte) = getOrCreateList(key, objType.toInt()) -fun CompoundTag.getOrCreateList(key: String, objType: Int): ListTag = - if (hasList(key, objType)) getList(key, objType) else ListTag().also { putList(key, it) } +fun CompoundTag.getOrCreateList(key: String, objType: Int): ListTag = if (hasList(key, objType)) getList(key, objType) else ListTag().also { putList(key, it) } // ================================================================================================================ Tag @@ -141,12 +136,10 @@ val Tag.asLongArray: LongArray val array = this.asIntArray LongArray(array.size) { array[it].toLong() } } - is ByteArrayTag -> { val array = this.asByteArray LongArray(array.size) { array[it].toLong() } } - else -> LongArray(0) } @@ -157,12 +150,10 @@ val Tag.asIntArray: IntArray val array = this.asLongArray IntArray(array.size) { array[it].toInt() } } - is ByteArrayTag -> { val array = this.asByteArray IntArray(array.size) { array[it].toInt() } } - else -> IntArray(0) } @@ -173,12 +164,10 @@ val Tag.asByteArray: ByteArray val array = this.asLongArray ByteArray(array.size) { array[it].toByte() } } - is IntArrayTag -> { val array = this.asIntArray ByteArray(array.size) { array[it].toByte() } } - else -> ByteArray(0) } @@ -187,98 +176,3 @@ val Tag.asCompound get() = this as? CompoundTag ?: CompoundTag() // asString is defined in Tag val Tag.asList get() = this as? ListTag ?: ListTag() val Tag.asUUID: UUID get() = if (this is IntArrayTag && this.size == 4) NbtUtils.loadUUID(this) else UUID(0, 0) - -// ========================================================================================================== ItemStack - -// Checks for containment - -fun ItemStack.hasNumber(key: String) = tag.hasNumber(key) -fun ItemStack.hasByte(key: String) = tag.hasByte(key) -fun ItemStack.hasShort(key: String) = tag.hasShort(key) -fun ItemStack.hasInt(key: String) = tag.hasInt(key) -fun ItemStack.hasLong(key: String) = tag.hasLong(key) -fun ItemStack.hasFloat(key: String) = tag.hasFloat(key) -fun ItemStack.hasDouble(key: String) = tag.hasDouble(key) -fun ItemStack.hasLongArray(key: String) = tag.hasLongArray(key) -fun ItemStack.hasIntArray(key: String) = tag.hasIntArray(key) -fun ItemStack.hasByteArray(key: String) = tag.hasByteArray(key) -fun ItemStack.hasCompound(key: String) = tag.hasCompound(key) -fun ItemStack.hasString(key: String) = tag.hasString(key) -fun ItemStack.hasList(key: String) = tag.hasList(key) -fun ItemStack.hasList(key: String, objType: Int) = tag.hasList(key, objType) -fun ItemStack.hasList(key: String, objType: Byte) = tag.hasList(key, objType) -fun ItemStack.hasUUID(key: String) = tag.hasUUID(key) - -@JvmName("contains") -fun ItemStack.containsTag(key: String) = tag.contains(key) - -@JvmName("contains") -fun ItemStack.containsTag(key: String, id: Byte) = tag.contains(key, id) - -@JvmName("contains") -fun ItemStack.containsTag(key: String, id: Int) = tag.contains(key, id) - -// Puts - -fun ItemStack.putBoolean(key: String, value: Boolean) = orCreateTag.putBoolean(key, value) -fun ItemStack.putByte(key: String, value: Byte) = orCreateTag.putByte(key, value) -fun ItemStack.putShort(key: String, value: Short) = orCreateTag.putShort(key, value) -fun ItemStack.putInt(key: String, value: Int) = orCreateTag.putInt(key, value) -fun ItemStack.putLong(key: String, value: Long) = orCreateTag.putLong(key, value) -fun ItemStack.putFloat(key: String, value: Float) = orCreateTag.putFloat(key, value) -fun ItemStack.putDouble(key: String, value: Double) = orCreateTag.putDouble(key, value) - -fun ItemStack.putLongArray(key: String, value: LongArray) = orCreateTag.putLongArray(key, value) -fun ItemStack.putIntArray(key: String, value: IntArray) = orCreateTag.putIntArray(key, value) -fun ItemStack.putByteArray(key: String, value: ByteArray) = orCreateTag.putByteArray(key, value) -fun ItemStack.putCompound(key: String, value: CompoundTag) = putTag(key, value) -fun ItemStack.putString(key: String, value: String) = orCreateTag.putString(key, value) -fun ItemStack.putList(key: String, value: ListTag) = putTag(key, value) -fun ItemStack.putUUID(key: String, value: UUID) = orCreateTag.putUUID(key, value) - -@JvmName("put") -fun ItemStack.putTag(key: String, value: Tag) = orCreateTag.put(key, value) - -// Remove - -fun ItemStack.remove(key: String) = removeTagKey(key) - -// Gets - -@JvmOverloads -fun ItemStack.getBoolean(key: String, defaultExpected: Boolean = false) = tag.getBoolean(key, defaultExpected) - -@JvmOverloads -fun ItemStack.getByte(key: String, defaultExpected: Byte = 0) = tag.getByte(key, defaultExpected) - -@JvmOverloads -fun ItemStack.getShort(key: String, defaultExpected: Short = 0) = tag.getShort(key, defaultExpected) - -@JvmOverloads -fun ItemStack.getInt(key: String, defaultExpected: Int = 0) = tag.getInt(key, defaultExpected) - -@JvmOverloads -fun ItemStack.getLong(key: String, defaultExpected: Long = 0) = tag.getLong(key, defaultExpected) - -@JvmOverloads -fun ItemStack.getFloat(key: String, defaultExpected: Float = 0f) = tag.getFloat(key, defaultExpected) - -@JvmOverloads -fun ItemStack.getDouble(key: String, defaultExpected: Double = 0.0) = tag.getDouble(key, defaultExpected) - -fun ItemStack.getLongArray(key: String) = tag.getLongArray(key) -fun ItemStack.getIntArray(key: String) = tag.getIntArray(key) -fun ItemStack.getByteArray(key: String) = tag.getByteArray(key) -fun ItemStack.getCompound(key: String) = tag.getCompound(key) -fun ItemStack.getString(key: String) = tag.getString(key) -fun ItemStack.getList(key: String, objType: Int) = tag.getList(key, objType) -fun ItemStack.getUUID(key: String) = tag.getUUID(key) - -@JvmName("get") -fun ItemStack.getTag(key: String) = tag.get(key) - -// Get-or-create - -fun ItemStack.getOrCreateCompound(key: String): CompoundTag = getOrCreateTagElement(key) -fun ItemStack.getOrCreateList(key: String, objType: Byte) = orCreateTag.getOrCreateList(key, objType) -fun ItemStack.getOrCreateList(key: String, objType: Int) = orCreateTag.getOrCreateList(key, objType) diff --git a/Common/src/main/java/at/petrak/hexcasting/client/RegisterClientStuff.java b/Common/src/main/java/at/petrak/hexcasting/client/RegisterClientStuff.java index 75658fa63a..1d4967d6c7 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/RegisterClientStuff.java +++ b/Common/src/main/java/at/petrak/hexcasting/client/RegisterClientStuff.java @@ -22,6 +22,7 @@ import at.petrak.hexcasting.common.items.storage.*; import at.petrak.hexcasting.common.lib.HexBlockEntities; import at.petrak.hexcasting.common.lib.HexBlocks; +import at.petrak.hexcasting.common.lib.HexDataComponents; import at.petrak.hexcasting.common.lib.HexItems; import at.petrak.hexcasting.xplat.IClientXplatAbstractions; import net.minecraft.client.color.block.BlockColor; @@ -30,7 +31,9 @@ import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; import net.minecraft.client.resources.model.BakedModel; import net.minecraft.client.resources.model.ModelBakery; +import net.minecraft.client.resources.model.ModelResourceLocation; import net.minecraft.core.Registry; +import net.minecraft.core.component.DataComponents; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.packs.resources.ResourceManager; @@ -56,25 +59,27 @@ public class RegisterClientStuff { public static void init() { registerSealableDataHolderOverrides(HexItems.FOCUS, - stack -> HexItems.FOCUS.readIotaTag(stack) != null, + stack -> stack.has(HexDataComponents.IOTA), ItemFocus::isSealed); registerSealableDataHolderOverrides(HexItems.SPELLBOOK, - stack -> HexItems.SPELLBOOK.readIotaTag(stack) != null, + stack -> HexItems.SPELLBOOK.readIota(stack) != null, ItemSpellbook::isSealed); registerVariantOverrides(HexItems.FOCUS, HexItems.FOCUS::getVariant); registerVariantOverrides(HexItems.SPELLBOOK, HexItems.SPELLBOOK::getVariant); + registerVariantOverrides(HexItems.ANCIENT_CYPHER, HexItems.ANCIENT_CYPHER::getVariant); registerVariantOverrides(HexItems.CYPHER, HexItems.CYPHER::getVariant); registerVariantOverrides(HexItems.TRINKET, HexItems.TRINKET::getVariant); registerVariantOverrides(HexItems.ARTIFACT, HexItems.ARTIFACT::getVariant); IClientXplatAbstractions.INSTANCE.registerItemProperty(HexItems.THOUGHT_KNOT, ItemThoughtKnot.WRITTEN_PRED, (stack, level, holder, holderID) -> { - if (NBTHelper.contains(stack, ItemThoughtKnot.TAG_DATA)) { + if (stack.has(HexDataComponents.IOTA)) { return 1; } else { return 0; } }); + registerPackagedSpellOverrides(HexItems.ANCIENT_CYPHER); registerPackagedSpellOverrides(HexItems.CYPHER); registerPackagedSpellOverrides(HexItems.TRINKET); registerPackagedSpellOverrides(HexItems.ARTIFACT); @@ -132,7 +137,7 @@ public static void init() { x.registerEntityRenderer(HexEntities.WALL_SCROLL, WallScrollRenderer::new); -// for (var tex : new ResourceLocation[]{ +// for (var tex : ResourceLocation.fromNamespaceAndPath[]{ // PatternTooltipComponent.PRISTINE_BG, // PatternTooltipComponent.ANCIENT_BG, // PatternTooltipComponent.SLATE_BG @@ -164,11 +169,11 @@ public static void registerColorProviders(BiConsumer itemColorR // this gets called for particles for some irritating reason return 0xff_ffffff; } - var iotaTag = beas.getIotaTag(); - if (iotaTag == null) { + var iota = beas.getIota(); + if (iota == null) { return 0xff_ffffff; } - return IotaType.getColor(iotaTag); + return iota.getType().color(); }, HexBlocks.AKASHIC_BOOKSHELF); } @@ -190,7 +195,7 @@ private static void registerSealableDataHolderOverrides(IotaHolderItem item, Pre Predicate isSealed) { IClientXplatAbstractions.INSTANCE.registerItemProperty((Item) item, ItemFocus.OVERLAY_PRED, (stack, level, holder, holderID) -> { - if (!hasIota.test(stack) && !NBTHelper.hasString(stack, IotaHolderItem.TAG_OVERRIDE_VISUALLY)) { + if (!hasIota.test(stack) && !stack.has(HexDataComponents.VISUAL_OVERRIDE)) { return 0; } if (!isSealed.test(stack)) { @@ -207,7 +212,7 @@ private static void registerVariantOverrides(VariantItem item, Function NBTHelper.hasString(stack, ItemScroll.TAG_OP_ID) ? 1f : 0f); + (stack, level, holder, holderID) -> stack.has(HexDataComponents.ACTION) ? 1f : 0f); } private static void registerPackagedSpellOverrides(ItemPackagedHex item) { @@ -220,7 +225,7 @@ private static void registerPackagedSpellOverrides(ItemPackagedHex item) { private static void registerWandOverrides(ItemStaff item) { IClientXplatAbstractions.INSTANCE.registerItemProperty(item, ItemStaff.FUNNY_LEVEL_PREDICATE, (stack, level, holder, holderID) -> { - if (!stack.hasCustomHoverName()) { + if (!stack.has(DataComponents.CUSTOM_NAME)) { return 0; } var name = stack.getHoverName().getString().toLowerCase(Locale.ROOT); @@ -254,7 +259,7 @@ void registerBlockEntityRenderer(BlockEntityType type BlockEntityRendererProvider berp); } - public static void onModelRegister(ResourceManager recMan, Consumer extraModels) { + public static void onModelRegister(ResourceManager recMan, Consumer extraModels) { for (var type : QUENCHED_ALLAY_TYPES.entrySet()) { var blockLoc = BuiltInRegistries.BLOCK.getKey(type.getKey()); var locStart = "block/"; @@ -262,12 +267,12 @@ public static void onModelRegister(ResourceManager recMan, Consumer map) { + public static void onModelBake(ModelBakery loader, Map map) { for (var type : QUENCHED_ALLAY_TYPES.entrySet()) { var blockLoc = BuiltInRegistries.BLOCK.getKey(type.getKey()); var locStart = "block/"; @@ -276,7 +281,7 @@ public static void onModelBake(ModelBakery loader, Map(); for (int i = 0; i < BlockQuenchedAllay.VARIANTS; i++) { - var variantLoc = modLoc(locStart + blockLoc.getPath() + "_" + i); + var variantLoc = new ModelResourceLocation(modLoc(locStart + blockLoc.getPath() + "_" + i), ModelResourceLocation.STANDALONE_VARIANT); var model = map.get(variantLoc); list.add(model); } diff --git a/Common/src/main/java/at/petrak/hexcasting/client/entity/WallScrollRenderer.java b/Common/src/main/java/at/petrak/hexcasting/client/entity/WallScrollRenderer.java index d17e617cd9..9e88bcf384 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/entity/WallScrollRenderer.java +++ b/Common/src/main/java/at/petrak/hexcasting/client/entity/WallScrollRenderer.java @@ -56,42 +56,41 @@ public void render(EntityWallScroll wallScroll, float yaw, float partialTicks, P float margin = 1f / 48f; var last = ps.last(); var mat = last.pose(); - var norm = last.normal(); RenderType layer = RenderType.entityCutout(this.getTextureLocation(wallScroll)); var verts = bufSource.getBuffer(layer); // Remember: CCW // Front face - vertex(mat, norm, light, verts, 0, 0, dz, 0, 0, 0, 0, -1); - vertex(mat, norm, light, verts, 0, dy, dz, 0, 1, 0, 0, -1); - vertex(mat, norm, light, verts, dx, dy, dz, 1, 1, 0, 0, -1); - vertex(mat, norm, light, verts, dx, 0, dz, 1, 0, 0, 0, -1); + vertex(mat, last, light, verts, 0, 0, dz, 0, 0, 0, 0, -1); + vertex(mat, last, light, verts, 0, dy, dz, 0, 1, 0, 0, -1); + vertex(mat, last, light, verts, dx, dy, dz, 1, 1, 0, 0, -1); + vertex(mat, last, light, verts, dx, 0, dz, 1, 0, 0, 0, -1); // Back face - vertex(mat, norm, light, verts, 0, 0, 0, 0, 0, 0, 0, 1); - vertex(mat, norm, light, verts, dx, 0, 0, 1, 0, 0, 0, 1); - vertex(mat, norm, light, verts, dx, dy, 0, 1, 1, 0, 0, 1); - vertex(mat, norm, light, verts, 0, dy, 0, 0, 1, 0, 0, 1); + vertex(mat, last, light, verts, 0, 0, 0, 0, 0, 0, 0, 1); + vertex(mat, last, light, verts, dx, 0, 0, 1, 0, 0, 0, 1); + vertex(mat, last, light, verts, dx, dy, 0, 1, 1, 0, 0, 1); + vertex(mat, last, light, verts, 0, dy, 0, 0, 1, 0, 0, 1); // Top face - vertex(mat, norm, light, verts, 0, 0, 0, 0, 0, 0, -1, 0); - vertex(mat, norm, light, verts, 0, 0, dz, 0, margin, 0, -1, 0); - vertex(mat, norm, light, verts, dx, 0, dz, 1, margin, 0, -1, 0); - vertex(mat, norm, light, verts, dx, 0, 0, 1, 0, 0, -1, 0); + vertex(mat, last, light, verts, 0, 0, 0, 0, 0, 0, -1, 0); + vertex(mat, last, light, verts, 0, 0, dz, 0, margin, 0, -1, 0); + vertex(mat, last, light, verts, dx, 0, dz, 1, margin, 0, -1, 0); + vertex(mat, last, light, verts, dx, 0, 0, 1, 0, 0, -1, 0); // Left face - vertex(mat, norm, light, verts, 0, 0, 0, 0, 0, -1, 0, 0); - vertex(mat, norm, light, verts, 0, dy, 0, 0, 1, -1, 0, 0); - vertex(mat, norm, light, verts, 0, dy, dz, margin, 1, -1, 0, 0); - vertex(mat, norm, light, verts, 0, 0, dz, margin, 0, -1, 0, 0); + vertex(mat, last, light, verts, 0, 0, 0, 0, 0, -1, 0, 0); + vertex(mat, last, light, verts, 0, dy, 0, 0, 1, -1, 0, 0); + vertex(mat, last, light, verts, 0, dy, dz, margin, 1, -1, 0, 0); + vertex(mat, last, light, verts, 0, 0, dz, margin, 0, -1, 0, 0); // Right face - vertex(mat, norm, light, verts, dx, 0, dz, 1 - margin, 0, 1, 0, 0); - vertex(mat, norm, light, verts, dx, dy, dz, 1 - margin, 1, 1, 0, 0); - vertex(mat, norm, light, verts, dx, dy, 0, 1, 1, 1, 0, 0); - vertex(mat, norm, light, verts, dx, 0, 0, 1, 0, 1, 0, 0); + vertex(mat, last, light, verts, dx, 0, dz, 1 - margin, 0, 1, 0, 0); + vertex(mat, last, light, verts, dx, dy, dz, 1 - margin, 1, 1, 0, 0); + vertex(mat, last, light, verts, dx, dy, 0, 1, 1, 1, 0, 0); + vertex(mat, last, light, verts, dx, 0, 0, 1, 0, 1, 0, 0); // Bottom face - vertex(mat, norm, light, verts, 0, dy, dz, 0, 1 - margin, 0, 1, 0); - vertex(mat, norm, light, verts, 0, dy, 0, 0, 1, 0, 1, 0); - vertex(mat, norm, light, verts, dx, dy, 0, 1, 1, 0, 1, 0); - vertex(mat, norm, light, verts, dx, dy, dz, 1, 1 - margin, 0, 1, 0); + vertex(mat, last, light, verts, 0, dy, dz, 0, 1 - margin, 0, 1, 0); + vertex(mat, last, light, verts, 0, dy, 0, 0, 1, 0, 1, 0); + vertex(mat, last, light, verts, dx, dy, 0, 1, 1, 0, 1, 0); + vertex(mat, last, light, verts, dx, dy, dz, 1, 1 - margin, 0, 1, 0); ps.popPose(); @@ -124,13 +123,14 @@ public ResourceLocation getTextureLocation(EntityWallScroll wallScroll) { } } - private static void vertex(Matrix4f mat, Matrix3f normal, int light, VertexConsumer verts, float x, float y, + private static void vertex(Matrix4f mat, PoseStack.Pose last, int light, VertexConsumer verts, float x, float y, float z, float u, float v, float nx, float ny, float nz) { - verts.vertex(mat, x, y, z) - .color(0xffffffff) - .uv(u, v).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(light) - .normal(normal, nx, ny, nz) - .endVertex(); + verts.addVertex(mat, x, y, z) + .setColor(0xffffffff) + .setUv(u, v) + .setOverlay(OverlayTexture.NO_OVERLAY) + .setLight(light) + .setNormal(last, nx, ny, nz); } } diff --git a/Common/src/main/java/at/petrak/hexcasting/client/gui/GuiSpellcasting.kt b/Common/src/main/java/at/petrak/hexcasting/client/gui/GuiSpellcasting.kt index 0a9f66cd2b..b45e4923ac 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/gui/GuiSpellcasting.kt +++ b/Common/src/main/java/at/petrak/hexcasting/client/gui/GuiSpellcasting.kt @@ -3,6 +3,7 @@ package at.petrak.hexcasting.client.gui import at.petrak.hexcasting.api.casting.eval.ExecutionClientView import at.petrak.hexcasting.api.casting.eval.ResolvedPattern import at.petrak.hexcasting.api.casting.eval.ResolvedPatternType +import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.IotaType import at.petrak.hexcasting.api.casting.math.HexAngle import at.petrak.hexcasting.api.casting.math.HexCoord @@ -28,7 +29,9 @@ import net.minecraft.client.gui.screens.Screen import net.minecraft.client.renderer.GameRenderer import net.minecraft.client.resources.sounds.SimpleSoundInstance import net.minecraft.client.resources.sounds.SoundInstance +import net.minecraft.core.Holder import net.minecraft.nbt.CompoundTag +import net.minecraft.nbt.NbtOps import net.minecraft.sounds.SoundSource import net.minecraft.util.FormattedCharSequence import net.minecraft.util.Mth @@ -40,7 +43,7 @@ import kotlin.math.* class GuiSpellcasting constructor( private val handOpenedWith: InteractionHand, private var patterns: MutableList, - private var cachedStack: List, + private var cachedStack: List, private var cachedRavenmind: CompoundTag?, private var parenCount: Int, ) : Screen("gui.hexcasting.spellcasting".asTranslatedComponent) { @@ -85,7 +88,7 @@ class GuiSpellcasting constructor( val mc = Minecraft.getInstance() val width = (this.width * LHS_IOTAS_ALLOCATION).toInt() this.stackDescs = - this.cachedStack.map { IotaType.getDisplayWithMaxWidth(it, width, mc.font) } + this.cachedStack.map { it.displayWithMaxWidth(width, mc.font) } .asReversed() // this.parenDescs = if (this.cachedParens.isNotEmpty()) // this.cachedParens.flatMap { HexIotaTypes.getDisplayWithMaxWidth(it, width, mc.font) } @@ -96,8 +99,8 @@ class GuiSpellcasting constructor( this.parenDescs = emptyList() this.ravenmind = this.cachedRavenmind?.let { - IotaType.getDisplayWithMaxWidth( - it, + val iota = IotaType.TYPED_CODEC.parse(NbtOps.INSTANCE, it).getOrThrow() + iota.displayWithMaxWidth( (this.width * RHS_IOTAS_ALLOCATION).toInt(), mc.font ) @@ -122,7 +125,7 @@ class GuiSpellcasting constructor( val player = minecraft.player if (player != null) { val heldItem = player.getItemInHand(handOpenedWith) - if (heldItem.isEmpty || !heldItem.`is`(HexTags.Items.STAVES)) + if (heldItem.isEmpty || !heldItem.`is`(HexTags.Items.STAVES) || player.getAttributeValue(HexAttributes.FEEBLE_MIND) > 0) closeForReal() } } @@ -291,16 +294,16 @@ class GuiSpellcasting constructor( return false } - override fun mouseScrolled(pMouseX: Double, pMouseY: Double, pDelta: Double): Boolean { - super.mouseScrolled(pMouseX, pMouseY, pDelta) + override fun mouseScrolled(mouseX: Double, mouseY: Double, scrollX: Double, scrollY: Double): Boolean { + super.mouseScrolled(mouseX, mouseY, scrollX, scrollY) val mouseHandler = Minecraft.getInstance().mouseHandler - if (mouseHandler.accumulatedScroll != 0.0 && sign(pDelta) != sign(mouseHandler.accumulatedScroll)) { + if (mouseHandler.accumulatedScroll != 0.0 && sign(scrollY) != sign(mouseHandler.accumulatedScroll)) { mouseHandler.accumulatedScroll = 0.0 } - mouseHandler.accumulatedScroll += pDelta + mouseHandler.accumulatedScroll += scrollY val accumulation: Int = mouseHandler.accumulatedScroll.toInt() if (accumulation == 0) { return true @@ -308,7 +311,7 @@ class GuiSpellcasting constructor( mouseHandler.accumulatedScroll -= accumulation.toDouble() - ShiftScrollListener.onScroll(pDelta, false) + ShiftScrollListener.onScroll(scrollY, false) return true } diff --git a/Common/src/main/java/at/petrak/hexcasting/client/ktxt/ClientAccessorWrappers.kt b/Common/src/main/java/at/petrak/hexcasting/client/ktxt/ClientAccessorWrappers.kt index 5863d7f050..94dc5b0d13 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/ktxt/ClientAccessorWrappers.kt +++ b/Common/src/main/java/at/petrak/hexcasting/client/ktxt/ClientAccessorWrappers.kt @@ -5,5 +5,5 @@ import at.petrak.hexcasting.mixin.accessor.client.AccessorMouseHandler import net.minecraft.client.MouseHandler var MouseHandler.accumulatedScroll: Double - get() = (this as AccessorMouseHandler).`hex$getAccumulatedScroll`() - set(value) = (this as AccessorMouseHandler).`hex$setAccumulatedScroll`(value) + get() = (this as AccessorMouseHandler).`hex$getAccumulatedScrollY`() + set(value) = (this as AccessorMouseHandler).`hex$setAccumulatedScrollY`(value) diff --git a/Common/src/main/java/at/petrak/hexcasting/client/model/AltioraLayer.java b/Common/src/main/java/at/petrak/hexcasting/client/model/AltioraLayer.java index a354d6eba3..07cbcd3d6f 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/model/AltioraLayer.java +++ b/Common/src/main/java/at/petrak/hexcasting/client/model/AltioraLayer.java @@ -43,8 +43,9 @@ public void render(PoseStack ps, MultiBufferSource buffer, int packedLight, Abst this.getParentModel().copyPropertiesTo(this.elytraModel); this.elytraModel.setupAnim(player, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch); VertexConsumer verts = ItemRenderer.getArmorFoilBuffer( - buffer, RenderType.armorCutoutNoCull(TEX_LOC), false, true); - this.elytraModel.renderToBuffer(ps, verts, packedLight, OverlayTexture.NO_OVERLAY, 1.0F, 1.0F, 1.0F, 1.0F); + buffer, RenderType.armorCutoutNoCull(TEX_LOC), true); + // TODO port: check color + this.elytraModel.renderToBuffer(ps, verts, packedLight, OverlayTexture.NO_OVERLAY, -1); ps.popPose(); } diff --git a/Common/src/main/java/at/petrak/hexcasting/client/model/MyOwnArmorModelWithBlackjackAndHookers.java b/Common/src/main/java/at/petrak/hexcasting/client/model/MyOwnArmorModelWithBlackjackAndHookers.java index fc63fcdf72..0bdd3fb2d1 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/model/MyOwnArmorModelWithBlackjackAndHookers.java +++ b/Common/src/main/java/at/petrak/hexcasting/client/model/MyOwnArmorModelWithBlackjackAndHookers.java @@ -52,10 +52,9 @@ public void setupAnim(LivingEntity entity, float limbSwing, float limbSwingAmoun } @Override - public void renderToBuffer(PoseStack ms, VertexConsumer buffer, int light, int overlay, float r, float g, float b - , float a) { + public void renderToBuffer(PoseStack ms, VertexConsumer buffer, int light, int overlay, int color) { setPartVisibility(slot); - super.renderToBuffer(ms, buffer, light, overlay, r, g, b, a); + super.renderToBuffer(ms, buffer, light, overlay, color); } // [VanillaCopy] HumanoidArmorLayer diff --git a/Common/src/main/java/at/petrak/hexcasting/client/particles/ConjureParticle.java b/Common/src/main/java/at/petrak/hexcasting/client/particles/ConjureParticle.java index 122e536e75..411b089535 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/particles/ConjureParticle.java +++ b/Common/src/main/java/at/petrak/hexcasting/client/particles/ConjureParticle.java @@ -91,7 +91,7 @@ public Particle createParticle(ConjureParticleOptions type, ClientLevel level, // https://github.com/VazkiiMods/Botania/blob/db85d778ab23f44c11181209319066d1f04a9e3d/Xplat/src/main/java/vazkii/botania/client/fx/FXWisp.java private record ConjureRenderType() implements ParticleRenderType { @Override - public void begin(BufferBuilder buf, TextureManager texMan) { + public BufferBuilder begin(Tesselator tess, TextureManager texMan) { Minecraft.getInstance().gameRenderer.lightTexture().turnOnLightLayer(); RenderSystem.depthMask(false); RenderSystem.enableBlend(); @@ -100,18 +100,8 @@ public void begin(BufferBuilder buf, TextureManager texMan) { RenderSystem.setShaderTexture(0, TextureAtlas.LOCATION_PARTICLES); var tex = texMan.getTexture(TextureAtlas.LOCATION_PARTICLES); IClientXplatAbstractions.INSTANCE.setFilterSave(tex, true, false); - buf.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.PARTICLE); RenderSystem.enableDepthTest(); - } - - @Override - public void end(Tesselator tess) { - tess.end(); - IClientXplatAbstractions.INSTANCE.restoreLastFilter( - Minecraft.getInstance().getTextureManager().getTexture(TextureAtlas.LOCATION_PARTICLES) - ); - RenderSystem.disableBlend(); - RenderSystem.depthMask(true); + return tess.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.PARTICLE); } @Override diff --git a/Common/src/main/java/at/petrak/hexcasting/client/render/HexAdditionalRenderers.java b/Common/src/main/java/at/petrak/hexcasting/client/render/HexAdditionalRenderers.java index 1861a9b8fb..29def93978 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/render/HexAdditionalRenderers.java +++ b/Common/src/main/java/at/petrak/hexcasting/client/render/HexAdditionalRenderers.java @@ -19,6 +19,7 @@ import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.player.LocalPlayer; import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.core.Holder; import net.minecraft.locale.Language; import net.minecraft.network.chat.FormattedText; import net.minecraft.network.chat.Style; @@ -75,7 +76,6 @@ private static void renderSentinel(Sentinel sentinel, LocalPlayer owner, var tess = Tesselator.getInstance(); - var buf = tess.getBuilder(); var neo = ps.last().pose(); RenderSystem.enableBlend(); RenderSystem.setShader(GameRenderer::getRendertypeLinesShader); @@ -86,23 +86,23 @@ private static void renderSentinel(Sentinel sentinel, LocalPlayer owner, var pigment = IXplatAbstractions.INSTANCE.getPigment(owner); var colProvider = pigment.getColorProvider(); + + // Icosahedron inscribed inside the unit sphere + var buf = tess.begin(VertexFormat.Mode.LINES, DefaultVertexFormat.POSITION_COLOR_NORMAL); + BiConsumer v = (l, r) -> { int lcolor = colProvider.getColor(time, new Vec3(l[0], l[1], l[2])), rcolor = colProvider.getColor(time, new Vec3(r[0], r[1], r[2])); var normal = new Vector3f(r[0] - l[0], r[1] - l[1], r[2] - l[2]); normal.normalize(); - buf.vertex(neo, l[0], l[1], l[2]) - .color(lcolor) - .normal(ps.last().normal(), normal.x(), normal.y(), normal.z()) - .endVertex(); - buf.vertex(neo, r[0], r[1], r[2]) - .color(rcolor) - .normal(ps.last().normal(), -normal.x(), -normal.y(), -normal.z()) - .endVertex(); + buf.addVertex(neo, l[0], l[1], l[2]) + .setColor(lcolor) + .setNormal(ps.last(), normal.x(), normal.y(), normal.z()); + buf.addVertex(neo, r[0], r[1], r[2]) + .setColor(rcolor) + .setNormal(ps.last(), -normal.x(), -normal.y(), -normal.z()); }; - // Icosahedron inscribed inside the unit sphere - buf.begin(VertexFormat.Mode.LINES, DefaultVertexFormat.POSITION_COLOR_NORMAL); for (int side = 0; side <= 1; side++) { var ring = (side == 0) ? Icos.BOTTOM_RING : Icos.TOP_RING; var apex = (side == 0) ? Icos.BOTTOM : Icos.TOP; @@ -123,7 +123,7 @@ private static void renderSentinel(Sentinel sentinel, LocalPlayer owner, v.accept(Icos.TOP_RING[(i + 2) % 5], bottom); v.accept(bottom, Icos.TOP_RING[(i + 3) % 5]); } - tess.end(); + //tess.end(); RenderSystem.enableDepthTest(); RenderSystem.enableCull(); @@ -159,7 +159,7 @@ private static void tryRenderScryingLensOverlay(GuiGraphics graphics, float part return; } - if (player.getAttributeValue(HexAttributes.SCRY_SIGHT) <= 0.0) + if (player.getAttributeValue(HexAttributes.SCRY_SIGHT) <= 0.0 || player.getAttributeValue(HexAttributes.FEEBLE_MIND) > 0) return; var hitRes = mc.hitResult; diff --git a/Common/src/main/java/at/petrak/hexcasting/client/render/PatternTextureManager.java b/Common/src/main/java/at/petrak/hexcasting/client/render/PatternTextureManager.java index 8486124920..b59e1e8e75 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/render/PatternTextureManager.java +++ b/Common/src/main/java/at/petrak/hexcasting/client/render/PatternTextureManager.java @@ -4,11 +4,12 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.texture.DynamicTexture; import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.FastColor; +import net.minecraft.util.Mth; import net.minecraft.util.Tuple; import net.minecraft.world.phys.Vec2; -import java.awt.*; -import java.awt.image.BufferedImage; +import java.awt.geom.Line2D; import java.util.List; import java.util.*; import java.util.concurrent.*; @@ -86,46 +87,38 @@ private static Map registerTextures(String patTextureK } private static NativeImage drawLines(List points, HexPatternPoints staticPoints, float unscaledLineWidth, int resPerUnit) { - BufferedImage img = new BufferedImage((int)(staticPoints.fullWidth*resPerUnit), (int)(staticPoints.fullHeight*resPerUnit), BufferedImage.TYPE_INT_ARGB); - Graphics2D g2d = img.createGraphics(); - g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - - g2d.setColor(new Color(0xFF_FFFFFF)); // set it to white so we can reuse the texture with different colors - g2d.setStroke(new BasicStroke(unscaledLineWidth * resPerUnit, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); + NativeImage nativeImage = new NativeImage((int)(staticPoints.fullWidth*resPerUnit), (int)(staticPoints.fullHeight*resPerUnit), true); for (int i = 0; i < points.size() - 1; i++) { Tuple pointFrom = getTextureCoordinates(points.get(i), staticPoints, resPerUnit); Tuple pointTo = getTextureCoordinates(points.get(i+1), staticPoints, resPerUnit); - g2d.drawLine(pointFrom.getA(), pointFrom.getB(), pointTo.getA(), pointTo.getB()); + drawLine(nativeImage, pointFrom.getA(), pointFrom.getB(), pointTo.getA(), pointTo.getB(), unscaledLineWidth * resPerUnit); } - g2d.dispose(); - NativeImage nativeImage = new NativeImage(img.getWidth(), img.getHeight(), true); - for (int y = 0; y < img.getHeight(); y++) - for (int x = 0; x < img.getWidth(); x++) - nativeImage.setPixelRGBA(x, y, img.getRGB(x, y)); return nativeImage; } + private static void drawLine(NativeImage image, int x0, int y0, int x1, int y1, float width) { + var line = new Line2D.Float(x0, y0, x1, y1); + var bounds = line.getBounds(); + double halfWidth = width / 2; + for (int x = (int) (bounds.x - width - 1); x < (int) (bounds.x + bounds.width + width + 1); x++) { + for (int y = (int) (bounds.y - width - 1); y < (int) (bounds.y + bounds.height + width + 1); y++) { + double dist = line.ptSegDist(x, y); + int alpha = (int) (Mth.clamp(halfWidth - dist + 0.5, 0, 1) * 255); + if (alpha > 0) { + int oldAlpha = FastColor.ARGB32.alpha(image.getPixelRGBA(x, y)); + int newAlpha = Math.max(oldAlpha, alpha); + image.setPixelRGBA(x, y, 0xFFFFFF | (newAlpha << 24)); + } + } + } + } + private static Tuple getTextureCoordinates(Vec2 point, HexPatternPoints staticPoints, int resPerUnit) { int x = (int) ( point.x * resPerUnit); int y = (int) ( point.y * resPerUnit); return new Tuple<>(x, y); } - // keeping this around just in case we ever decide to put the dots in the textures instead of dynamic - private static void drawHexagon(Graphics2D g2d, int x, int y, int radius) { - int fracOfCircle = 6; - Polygon hexagon = new Polygon(); - - for (int i = 0; i < fracOfCircle; i++) { - double theta = (i / (double) fracOfCircle) * Math.PI * 2; - int hx = (int) (x + Math.cos(theta) * radius); - int hy = (int) (y + Math.sin(theta) * radius); - hexagon.addPoint(hx, hy); - } - - g2d.fill(hexagon); - } - public static void repaint() { repaintIndex++; patternTexturesToAdd.clear(); diff --git a/Common/src/main/java/at/petrak/hexcasting/client/render/RenderLib.kt b/Common/src/main/java/at/petrak/hexcasting/client/render/RenderLib.kt index 8603befcf1..cc01757023 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/render/RenderLib.kt +++ b/Common/src/main/java/at/petrak/hexcasting/client/render/RenderLib.kt @@ -112,10 +112,8 @@ fun drawLineSeq( val normal = Vec2(-tangent.y, tangent.x) fun color(time: Float): Int = - FastColor.ARGB32.color( - Mth.lerp(time, a1, a2).toInt(), Mth.lerp(time, r1, r2).toInt(), - Mth.lerp(time, g1, g2).toInt(), Mth.lerp(time, b1, b2).toInt() - ) + FastColor.ARGB32.color(Mth.lerp(time, a1, a2).toInt(), Mth.lerp(time, r1, r2).toInt(), + Mth.lerp(time, g1, g2).toInt(), Mth.lerp(time, b1, b2).toInt()) val color1 = color(i.toFloat() / n) val color2 = color((i + 1f) / n) @@ -222,8 +220,7 @@ fun drawPatternFromPoints( lastSegmentLenProportion: Float, seed: Double ) { - val zappyPts = - makeZappy(points, dupIndices, 10, 2.5f, 0.1f, flowIrregular, readabilityOffset, lastSegmentLenProportion, seed) + val zappyPts = makeZappy(points, dupIndices, 10, 2.5f, 0.1f, flowIrregular, readabilityOffset, lastSegmentLenProportion, seed) val nodes = if (drawLast) { points } else { @@ -356,13 +353,7 @@ fun findDupIndices(pts: Iterable): Set { * include primitive drawing code... */ fun drawSpot(mat: Matrix4f, point: Vec2, radius: Float, r: Float, g: Float, b: Float, a: Float) { - drawSpot( - mat, - point, - radius, - ARGB32.color((a * 255).toInt(), (r * 255).toInt(), (g * 255).toInt(), (b * 255).toInt()), - VCDrawHelper.Basic(1f) - ) + drawSpot(mat, point, radius, ARGB32.color((a*255).toInt(), (r*255).toInt(), (g*255).toInt(), (b*255).toInt()), VCDrawHelper.Basic(1f)) } fun drawSpot(mat: Matrix4f, point: Vec2, radius: Float, color: Int, vcHelper: VCDrawHelper) { @@ -465,5 +456,4 @@ fun renderQuad( .setColor(color) buf.addVertex(mat, x + w, y, 0f) .setColor(color) - buf.buildOrThrow() } diff --git a/Common/src/main/java/at/petrak/hexcasting/client/render/ScryingLensOverlays.java b/Common/src/main/java/at/petrak/hexcasting/client/render/ScryingLensOverlays.java index 32aed05c7a..7aac8fe1af 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/render/ScryingLensOverlays.java +++ b/Common/src/main/java/at/petrak/hexcasting/client/render/ScryingLensOverlays.java @@ -61,9 +61,9 @@ public static void addScryingLensStuff() { ScryingLensOverlayRegistry.addDisplayer(HexBlocks.AKASHIC_BOOKSHELF, (lines, state, pos, observer, world, direction) -> { if (world.getBlockEntity(pos) instanceof BlockEntityAkashicBookshelf tile) { - var iotaTag = tile.getIotaTag(); - if (iotaTag != null) { - var display = IotaType.getDisplay(iotaTag); + var iota = tile.getIota(); + if (iota != null) { + var display = iota.display(); lines.add(new Pair<>(new ItemStack(Items.BOOK), display)); } } diff --git a/Common/src/main/java/at/petrak/hexcasting/client/render/VCDrawHelper.kt b/Common/src/main/java/at/petrak/hexcasting/client/render/VCDrawHelper.kt index 5076ad45b3..5fa673b252 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/render/VCDrawHelper.kt +++ b/Common/src/main/java/at/petrak/hexcasting/client/render/VCDrawHelper.kt @@ -18,13 +18,11 @@ import net.minecraft.world.phys.Vec3 import org.joml.Matrix4f -// TODO sam you're going to need to fix this, i have no idea what is going on here interface VCDrawHelper { fun vcSetupAndSupply(vertMode: VertexFormat.Mode): VertexConsumer fun vertex(vc: VertexConsumer, color: Int, pos: Vec2, matrix: Matrix4f) { - vertex(vc, color, pos, Vec2(0f, 0f), matrix) + vertex(vc, color, pos, Vec2(0f,0f), matrix) } - fun vertex(vc: VertexConsumer, color: Int, pos: Vec2, uv: Vec2, matrix: Matrix4f) fun vcEndDrawer(vc: VertexConsumer) @@ -35,15 +33,15 @@ interface VCDrawHelper { val WHITE: ResourceLocation = HexAPI.modLoc("textures/entity/white.png") @JvmStatic - fun getHelper(worldlyBits: WorldlyBits?, ps: PoseStack, z: Float, texture: ResourceLocation): VCDrawHelper { - if (worldlyBits != null) { + fun getHelper(worldlyBits: WorldlyBits?, ps: PoseStack, z: Float, texture: ResourceLocation) : VCDrawHelper { + if(worldlyBits != null){ return Worldly(worldlyBits, ps, z, texture) } return Basic(z, texture) } @JvmStatic - fun getHelper(worldlyBits: WorldlyBits?, ps: PoseStack, z: Float): VCDrawHelper { + fun getHelper(worldlyBits: WorldlyBits?, ps: PoseStack, z: Float) : VCDrawHelper { return getHelper(worldlyBits, ps, z, WHITE) } } @@ -53,32 +51,27 @@ interface VCDrawHelper { override fun vcSetupAndSupply(vertMode: VertexFormat.Mode): VertexConsumer { val tess = Tesselator.getInstance() val buf = tess.begin(vertMode, DefaultVertexFormat.POSITION_TEX_COLOR) - RenderSystem.setShader(GameRenderer::getPositionTexColorShader); + RenderSystem.setShader(GameRenderer::getPositionTexColorShader) RenderSystem.disableCull() RenderSystem.enableDepthTest() RenderSystem.enableBlend() - RenderSystem.blendFunc( - GlStateManager.SourceFactor.SRC_ALPHA, - GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA - ) + RenderSystem.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, + GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA) RenderSystem.setShaderTexture(0, texture) return buf } - - override fun vertex(vc: VertexConsumer, color: Int, pos: Vec2, uv: Vec2, matrix: Matrix4f) { - vc.vertex(matrix, pos.x, pos.y, z).color(color).uv(uv.x, uv.y).endVertex() + override fun vertex(vc: VertexConsumer, color: Int, pos: Vec2, uv: Vec2, matrix: Matrix4f){ + vc.addVertex(matrix, pos.x, pos.y, z).setColor(color).setUv(uv.x, uv.y) } - override fun vcEndDrawer(vc: VertexConsumer) { - Tesselator.getInstance().end() + if(vc is BufferBuilder) + BufferUploader.drawWithShader(vc.buildOrThrow()) } } - class Worldly(val worldlyBits: WorldlyBits, val ps: PoseStack, val z: Float, val texture: ResourceLocation) : - VCDrawHelper { + class Worldly(val worldlyBits: WorldlyBits, val ps: PoseStack, val z: Float, val texture: ResourceLocation) : VCDrawHelper { - var lastVertMode: VertexFormat.Mode? = - null // i guess this assumes that the vcHelper is only used once at a time? maybe reconsider that + var lastVertMode: VertexFormat.Mode ?= null // i guess this assumes that the vcHelper is only used once at a time? maybe reconsider that override fun vcSetupAndSupply(vertMode: VertexFormat.Mode): VertexConsumer { val provider = worldlyBits.provider @@ -87,57 +80,53 @@ interface VCDrawHelper { provider.endBatch() } lastVertMode = vertMode - val buf = Tesselator.getInstance().builder - if (vertMode == VertexFormat.Mode.QUADS) { + val tess = Tesselator.getInstance() + if(vertMode == VertexFormat.Mode.QUADS){ val layer = RenderType.entityTranslucentCull(texture) layer.setupRenderState() if (provider == null) { - buf.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.NEW_ENTITY) + val buf = tess.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.NEW_ENTITY) RenderSystem.setShader { GameRenderer.getRendertypeEntityTranslucentCullShader() } return buf } else { return provider.getBuffer(layer) } } - buf.begin(vertMode, DefaultVertexFormat.NEW_ENTITY) + val buf = tess.begin( vertMode, DefaultVertexFormat.NEW_ENTITY ) // Generally this would be handled by a RenderLayer, but that doesn't seem to actually work here,, RenderSystem.setShaderTexture(0, texture) RenderSystem.enableDepthTest() RenderSystem.disableCull() Minecraft.getInstance().gameRenderer.lightTexture().turnOnLightLayer() RenderSystem.enableBlend() - RenderSystem.blendFuncSeparate( - GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, - GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA - ) + RenderSystem.blendFuncSeparate( GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, + GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA ) RenderSystem.setShaderColor(1f, 1f, 1f, 1f); if (Minecraft.useShaderTransparency()) { Minecraft.getInstance().levelRenderer.translucentTarget!!.bindWrite(false) } - RenderSystem.setShader(GameRenderer::getRendertypeEntityTranslucentCullShader) + RenderSystem.setShader( GameRenderer::getRendertypeEntityTranslucentCullShader ) return buf } - override fun vertex(vc: VertexConsumer, color: Int, pos: Vec2, uv: Vec2, matrix: Matrix4f) { - val nv = worldlyBits.normal ?: Vec3(1.0, 1.0, 1.0) - vc.vertex(matrix, pos.x, pos.y, z) - .color(color) - .uv(uv.x, uv.y) - .overlayCoords(OverlayTexture.NO_OVERLAY) - .uv2(worldlyBits.light ?: LightTexture.FULL_BRIGHT) - .normal(ps.last().normal(), nv.x.toFloat(), nv.y.toFloat(), nv.z.toFloat()) - - vc.endVertex() + override fun vertex(vc: VertexConsumer, color: Int, pos: Vec2, uv: Vec2, matrix: Matrix4f){ + val nv = worldlyBits.normal?: Vec3(1.0, 1.0, 1.0) + vc.addVertex(matrix, pos.x, pos.y, z) + .setColor(color) + .setUv(uv.x, uv.y) + .setOverlay(OverlayTexture.NO_OVERLAY) + .setLight(worldlyBits.light?: LightTexture.FULL_BRIGHT ) + .setNormal(ps.last(), nv.x.toFloat(), nv.y.toFloat(), nv.z.toFloat()) } - - override fun vcEndDrawer(vc: VertexConsumer) { - if (lastVertMode == VertexFormat.Mode.QUADS) { - if (provider == null) { + override fun vcEndDrawer(vc: VertexConsumer){ + if(lastVertMode == VertexFormat.Mode.QUADS){ + if (provider == null && vc is BufferBuilder) { val layer = RenderType.entityTranslucentCull(texture) - layer.end(Tesselator.getInstance().builder, VertexSorting.ORTHOGRAPHIC_Z) + layer.draw(vc.buildOrThrow()) //TODO port: , VertexSorting.ORTHOGRAPHIC_Z } } else { - Tesselator.getInstance().end() + if(vc is BufferBuilder) + BufferUploader.drawWithShader(vc.buildOrThrow()) Minecraft.getInstance().gameRenderer.lightTexture().turnOffLightLayer() RenderSystem.disableBlend() RenderSystem.defaultBlendFunc() diff --git a/Common/src/main/java/at/petrak/hexcasting/client/render/WorldlyPatternRenderHelpers.java b/Common/src/main/java/at/petrak/hexcasting/client/render/WorldlyPatternRenderHelpers.java index 68c00d5d92..b1da11a2a9 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/render/WorldlyPatternRenderHelpers.java +++ b/Common/src/main/java/at/petrak/hexcasting/client/render/WorldlyPatternRenderHelpers.java @@ -140,7 +140,7 @@ public static void renderPattern(HexPattern pattern, PatternSettings patSets, Pa PoseStack noNormalInv = new PoseStack(); noNormalInv.scale(1, 1, -1); - ps.mulPoseMatrix(noNormalInv.last().pose()); + ps.mulPose(noNormalInv.last().pose()); PatternRenderer.renderPattern(pattern, ps, new PatternRenderer.WorldlyBits(bufSource, light, normal), patSets, patColors, seed, blockSize * 512); diff --git a/Common/src/main/java/at/petrak/hexcasting/client/render/be/BlockEntityQuenchedAllayRenderer.java b/Common/src/main/java/at/petrak/hexcasting/client/render/be/BlockEntityQuenchedAllayRenderer.java index 15f89ad049..0d107bcebd 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/render/be/BlockEntityQuenchedAllayRenderer.java +++ b/Common/src/main/java/at/petrak/hexcasting/client/render/be/BlockEntityQuenchedAllayRenderer.java @@ -42,7 +42,7 @@ public void render(BlockEntityQuenchedAllay blockEntity, float partialTick, Pose // Forge fixes BEs rendering offscreen; Fabric doesn't! // So we do a special check on Fabric only var pos = blockEntity.getBlockPos(); - var aabb = new AABB(pos.offset(-1, 0, -1), pos.offset(1, 1, 1)); + var aabb = new AABB(pos.offset(-1, 0, -1).getCenter(), pos.offset(1, 1, 1).getCenter()); if (IClientXplatAbstractions.INSTANCE.fabricAdditionalQuenchFrustumCheck(aabb)) { doRender((BlockQuenchedAllay) blockEntity.getBlockState().getBlock(), this.ctx.getBlockRenderDispatcher(), poseStack, bufferSource, packedLight, packedOverlay); } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/blocks/BlockConjured.java b/Common/src/main/java/at/petrak/hexcasting/common/blocks/BlockConjured.java index 078b819a3c..616880da50 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/blocks/BlockConjured.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/blocks/BlockConjured.java @@ -33,10 +33,11 @@ public BlockConjured(Properties properties) { } @Override - public void playerWillDestroy(Level pLevel, BlockPos pPos, BlockState pState, Player pPlayer) { - super.playerWillDestroy(pLevel, pPos, pState, pPlayer); + public BlockState playerWillDestroy(Level pLevel, BlockPos pPos, BlockState pState, Player pPlayer) { + var res = super.playerWillDestroy(pLevel, pPos, pState, pPlayer); // For some reason the block doesn't play breaking noises. So we fix that! pPlayer.playSound(SoundEvents.AMETHYST_BLOCK_BREAK, 1f, 1f); + return res; } @Nullable diff --git a/Common/src/main/java/at/petrak/hexcasting/common/blocks/akashic/BlockAkashicBookshelf.java b/Common/src/main/java/at/petrak/hexcasting/common/blocks/akashic/BlockAkashicBookshelf.java index 39545fd968..d36dff4297 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/blocks/akashic/BlockAkashicBookshelf.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/blocks/akashic/BlockAkashicBookshelf.java @@ -10,7 +10,9 @@ import net.minecraft.sounds.SoundSource; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; +import net.minecraft.world.ItemInteractionResult; import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.context.BlockPlaceContext; import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelReader; @@ -39,24 +41,33 @@ public BlockAkashicBookshelf(Properties p_49795_) { } @Override - public InteractionResult use(BlockState pState, Level pLevel, BlockPos pPos, Player pPlayer, InteractionHand pHand, - BlockHitResult pHit) { - if (pLevel.getBlockEntity(pPos) instanceof BlockEntityAkashicBookshelf shelf) { - var stack = pPlayer.getItemInHand(pHand); + protected ItemInteractionResult useItemOn(ItemStack stack, BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hitResult) { + if (level.getBlockEntity(pos) instanceof BlockEntityAkashicBookshelf shelf) { if (stack.getItem() instanceof ItemScroll scroll) { - if (!pLevel.isClientSide()) { + if (!level.isClientSide()) { scroll.writeDatum(stack, new PatternIota(shelf.getPattern())); } - pLevel.playSound(pPlayer, pPos, HexSounds.SCROLL_SCRIBBLE, SoundSource.BLOCKS, 1f, 1f); - return InteractionResult.sidedSuccess(pLevel.isClientSide); - } else if (pPlayer.isDiscrete() && pHand == InteractionHand.MAIN_HAND && stack.isEmpty()) { - if (!pLevel.isClientSide()) { + level.playSound(player, pos, HexSounds.SCROLL_SCRIBBLE, SoundSource.BLOCKS, 1f, 1f); + return ItemInteractionResult.sidedSuccess(level.isClientSide); + } + } + + return stack.isEmpty() && hand == InteractionHand.MAIN_HAND + ? ItemInteractionResult.SKIP_DEFAULT_BLOCK_INTERACTION + : ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; + } + + @Override + protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) { + if (level.getBlockEntity(pos) instanceof BlockEntityAkashicBookshelf shelf) { + if (player.isDiscrete()) { + if (!level.isClientSide()) { shelf.clearIota(); } - pLevel.playSound(pPlayer, pPos, HexSounds.SCROLL_SCRIBBLE, SoundSource.BLOCKS, - 1f, 0.8f); - return InteractionResult.sidedSuccess(pLevel.isClientSide); + level.playSound(player, pos, HexSounds.SCROLL_SCRIBBLE, SoundSource.BLOCKS, + 1f, 0.8f); + return InteractionResult.sidedSuccess(level.isClientSide); } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/blocks/akashic/BlockAkashicRecord.java b/Common/src/main/java/at/petrak/hexcasting/common/blocks/akashic/BlockAkashicRecord.java index db3f96ac14..dc14338edd 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/blocks/akashic/BlockAkashicRecord.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/blocks/akashic/BlockAkashicRecord.java @@ -4,6 +4,7 @@ import at.petrak.hexcasting.api.casting.iota.IotaType; import at.petrak.hexcasting.api.casting.math.HexPattern; import net.minecraft.core.BlockPos; +import net.minecraft.nbt.NbtOps; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; @@ -45,8 +46,7 @@ BlockPos addNewDatum(BlockPos herePos, Level level, HexPattern key, Iota datum) } } - public @Nullable - Iota lookupPattern(BlockPos herePos, HexPattern key, ServerLevel slevel) { + public @Nullable Iota lookupPattern(BlockPos herePos, HexPattern key, ServerLevel slevel) { var foundPos = AkashicFloodfiller.floodFillFor(herePos, slevel, (pos, bs, world) -> world.getBlockEntity(pos) instanceof BlockEntityAkashicBookshelf tile @@ -56,8 +56,7 @@ Iota lookupPattern(BlockPos herePos, HexPattern key, ServerLevel slevel) { } var tile = (BlockEntityAkashicBookshelf) slevel.getBlockEntity(foundPos); - var tag = tile.getIotaTag(); - return tag == null ? null : IotaType.deserialize(tag, slevel); + return tile != null ? tile.getIota() : null; } // TODO get comparators working again and also cache the number of iotas somehow? diff --git a/Common/src/main/java/at/petrak/hexcasting/common/blocks/akashic/BlockEntityAkashicBookshelf.java b/Common/src/main/java/at/petrak/hexcasting/common/blocks/akashic/BlockEntityAkashicBookshelf.java index d6e4cd8041..2e5569dd4c 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/blocks/akashic/BlockEntityAkashicBookshelf.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/blocks/akashic/BlockEntityAkashicBookshelf.java @@ -7,7 +7,10 @@ import at.petrak.hexcasting.client.render.HexPatternPoints; import at.petrak.hexcasting.common.lib.HexBlockEntities; import net.minecraft.core.BlockPos; +import net.minecraft.core.HolderLookup; import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtOps; +import net.minecraft.nbt.Tag; import net.minecraft.world.level.block.state.BlockState; import org.jetbrains.annotations.Nullable; @@ -18,10 +21,11 @@ public class BlockEntityAkashicBookshelf extends HexBlockEntity { // This is only not null if this stores any data. private HexPattern pattern = null; + // TODO port: check if it works // When the world is first loading we can sometimes try to deser this from nbt without the world existing yet. // We also need a way to display the iota to the client. // For both these cases we save just the tag of the iota. - private CompoundTag iotaTag = null; + private Iota iota = null; public HexPatternPoints points; @@ -35,14 +39,20 @@ public HexPattern getPattern() { } @Nullable - public CompoundTag getIotaTag() { - return iotaTag; + public Iota getIota() { + return iota; } + /*@Nullable + public Tag getIotaTag() { + return iotaTag; + }*/ + public void setNewMapping(HexPattern pattern, Iota iota) { var previouslyEmpty = this.pattern == null; this.pattern = pattern; - this.iotaTag = IotaType.serialize(iota); + this.iota = iota; + //this.iotaTag = IotaType.TYPED_CODEC.encodeStart(NbtOps.INSTANCE, iota).getOrThrow(); if (previouslyEmpty) { var oldBs = this.getBlockState(); @@ -57,7 +67,8 @@ public void setNewMapping(HexPattern pattern, Iota iota) { public void clearIota() { var previouslyEmpty = this.pattern == null; this.pattern = null; - this.iotaTag = null; + //this.iotaTag = null; + this.iota = null; if (!previouslyEmpty) { var oldBs = this.getBlockState(); @@ -70,23 +81,25 @@ public void clearIota() { } @Override - protected void saveModData(CompoundTag compoundTag) { - if (this.pattern != null && this.iotaTag != null) { - compoundTag.put(TAG_PATTERN, this.pattern.serializeToNBT()); - compoundTag.put(TAG_IOTA, this.iotaTag); + protected void saveModData(CompoundTag compoundTag, HolderLookup.Provider registries) { + if (this.pattern != null && this.iota != null) { + compoundTag.put(TAG_PATTERN, HexPattern.CODEC.encodeStart(NbtOps.INSTANCE, pattern).getOrThrow()); + compoundTag.put(TAG_IOTA, IotaType.TYPED_CODEC.encodeStart(NbtOps.INSTANCE, iota).getOrThrow()); } else { compoundTag.putBoolean(TAG_DUMMY, false); } } @Override - protected void loadModData(CompoundTag tag) { + protected void loadModData(CompoundTag tag, HolderLookup.Provider registries) { if (tag.contains(TAG_PATTERN) && tag.contains(TAG_IOTA)) { - this.pattern = HexPattern.fromNBT(tag.getCompound(TAG_PATTERN)); - this.iotaTag = tag.getCompound(TAG_IOTA); + this.pattern = HexPattern.CODEC.parse(NbtOps.INSTANCE, tag.getCompound(TAG_PATTERN)).getOrThrow(); + //this.iotaTag = tag.getCompound(TAG_IOTA); + this.iota = IotaType.TYPED_CODEC.parse(NbtOps.INSTANCE, tag.getCompound(TAG_IOTA)).getOrThrow(); } else if (tag.contains(TAG_DUMMY)) { this.pattern = null; - this.iotaTag = null; + //this.iotaTag = null; + this.iota = null; } } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/blocks/circles/BlockEntitySlate.java b/Common/src/main/java/at/petrak/hexcasting/common/blocks/circles/BlockEntitySlate.java index 9a0ec965bc..acb0c4ca4b 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/blocks/circles/BlockEntitySlate.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/blocks/circles/BlockEntitySlate.java @@ -4,7 +4,9 @@ import at.petrak.hexcasting.api.casting.math.HexPattern; import at.petrak.hexcasting.common.lib.HexBlockEntities; import net.minecraft.core.BlockPos; +import net.minecraft.core.HolderLookup; import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtOps; import net.minecraft.nbt.Tag; import net.minecraft.world.level.block.state.BlockState; import org.jetbrains.annotations.Nullable; @@ -20,23 +22,19 @@ public BlockEntitySlate(BlockPos pos, BlockState state) { } @Override - protected void saveModData(CompoundTag tag) { + protected void saveModData(CompoundTag tag, HolderLookup.Provider registries) { if (this.pattern != null) { - tag.put(TAG_PATTERN, this.pattern.serializeToNBT()); + tag.put(TAG_PATTERN, HexPattern.CODEC.encodeStart(NbtOps.INSTANCE, pattern).getOrThrow()); } else { tag.put(TAG_PATTERN, new CompoundTag()); } } @Override - protected void loadModData(CompoundTag tag) { + protected void loadModData(CompoundTag tag, HolderLookup.Provider registries) { if (tag.contains(TAG_PATTERN, Tag.TAG_COMPOUND)) { - CompoundTag patternTag = tag.getCompound(TAG_PATTERN); - if (HexPattern.isPattern(patternTag)) { - this.pattern = HexPattern.fromNBT(patternTag); - } else { - this.pattern = null; - } + Tag patternTag = tag.get(TAG_PATTERN); + this.pattern = HexPattern.CODEC.parse(NbtOps.INSTANCE, patternTag).result().orElse(null); } else { this.pattern = null; } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/blocks/circles/impetuses/BlockEntityLookingImpetus.java b/Common/src/main/java/at/petrak/hexcasting/common/blocks/circles/impetuses/BlockEntityLookingImpetus.java index 963d62a649..6355f37fc5 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/blocks/circles/impetuses/BlockEntityLookingImpetus.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/blocks/circles/impetuses/BlockEntityLookingImpetus.java @@ -5,6 +5,7 @@ import at.petrak.hexcasting.common.lib.HexBlockEntities; import at.petrak.hexcasting.common.lib.HexSounds; import net.minecraft.core.BlockPos; +import net.minecraft.core.HolderLookup; import net.minecraft.nbt.CompoundTag; import net.minecraft.server.level.ServerPlayer; import net.minecraft.sounds.SoundSource; @@ -35,8 +36,9 @@ public static void serverTick(Level level, BlockPos pos, BlockState bs, BlockEnt int prevLookAmt = self.lookAmount; int range = 20; + //TODO port: test AABB check, it's Vec3 now instead of BlockPos var players = level.getEntitiesOfClass(ServerPlayer.class, - new AABB(pos.offset(-range, -range, -range), pos.offset(range, range, range))); + new AABB(pos.offset(-range, -range, -range).getCenter(), pos.offset(range, range, range).getCenter())); ServerPlayer looker = null; for (var player : players) { @@ -84,14 +86,14 @@ public static void serverTick(Level level, BlockPos pos, BlockState bs, BlockEnt } @Override - protected void saveModData(CompoundTag tag) { - super.saveModData(tag); + protected void saveModData(CompoundTag tag, HolderLookup.Provider registries) { + super.saveModData(tag, registries); tag.putInt(TAG_LOOK_AMOUNT, this.lookAmount); } @Override - protected void loadModData(CompoundTag tag) { - super.loadModData(tag); + protected void loadModData(CompoundTag tag, HolderLookup.Provider registries) { + super.loadModData(tag, registries); this.lookAmount = tag.getInt(TAG_LOOK_AMOUNT); } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/blocks/circles/impetuses/BlockEntityRedstoneImpetus.java b/Common/src/main/java/at/petrak/hexcasting/common/blocks/circles/impetuses/BlockEntityRedstoneImpetus.java index b776d156ce..385b591e8a 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/blocks/circles/impetuses/BlockEntityRedstoneImpetus.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/blocks/circles/impetuses/BlockEntityRedstoneImpetus.java @@ -8,15 +8,20 @@ import com.mojang.datafixers.util.Pair; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; +import net.minecraft.core.HolderLookup; +import net.minecraft.core.component.DataComponents; import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtOps; import net.minecraft.nbt.NbtUtils; import net.minecraft.nbt.Tag; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; +import net.minecraft.util.ExtraCodecs; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; +import net.minecraft.world.item.component.ResolvableProfile; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.state.BlockState; import org.jetbrains.annotations.Nullable; @@ -31,15 +36,14 @@ public class BlockEntityRedstoneImpetus extends BlockEntityAbstractImpetus { private GameProfile storedPlayerProfile = null; private UUID storedPlayer = null; - private GameProfile cachedDisplayProfile = null; + private ResolvableProfile cachedDisplayProfile = null; private ItemStack cachedDisplayStack = null; public BlockEntityRedstoneImpetus(BlockPos pWorldPosition, BlockState pBlockState) { super(HexBlockEntities.IMPETUS_REDSTONE_TILE, pWorldPosition, pBlockState); } - protected @Nullable - GameProfile getPlayerName() { + protected @Nullable GameProfile getPlayerName() { if (this.level instanceof ServerLevel) { Player player = getStoredPlayer(); if (player != null) { @@ -61,6 +65,7 @@ public void clearPlayer() { this.storedPlayer = null; } + //TODO port: test player profiles public void updatePlayerProfile() { ServerPlayer player = getStoredPlayer(); if (player != null) { @@ -99,17 +104,18 @@ public void applyScryingLensOverlay(List> lines, Direction hitFace) { super.applyScryingLensOverlay(lines, state, pos, observer, world, hitFace); - var name = this.getPlayerName(); - if (name != null) { - if (!name.equals(cachedDisplayProfile) || cachedDisplayStack == null) { - cachedDisplayProfile = name; + var plProfile = this.getPlayerName(); + if (plProfile != null) { + var resolvableProfile = new ResolvableProfile(plProfile); + if (!plProfile.equals(resolvableProfile) || cachedDisplayStack == null) { + cachedDisplayProfile = resolvableProfile; var head = new ItemStack(Items.PLAYER_HEAD); - NBTHelper.put(head, "SkullOwner", NbtUtils.writeGameProfile(new CompoundTag(), name)); - head.getItem().verifyTagAfterLoad(head.getOrCreateTag()); + head.set(DataComponents.PROFILE, resolvableProfile); + head.getItem().verifyComponentsAfterLoad(head); cachedDisplayStack = head; } lines.add(new Pair<>(cachedDisplayStack, - Component.translatable("hexcasting.tooltip.lens.impetus.redstone.bound", name.getName()))); + Component.translatable("hexcasting.tooltip.lens.impetus.redstone.bound", plProfile.getName()))); } else { lines.add(new Pair<>(new ItemStack(Items.BARRIER), Component.translatable("hexcasting.tooltip.lens.impetus.redstone.bound.none"))); @@ -117,26 +123,26 @@ public void applyScryingLensOverlay(List> lines, } @Override - protected void saveModData(CompoundTag tag) { - super.saveModData(tag); + protected void saveModData(CompoundTag tag, HolderLookup.Provider registries) { + super.saveModData(tag, registries); if (this.storedPlayer != null) { tag.putUUID(TAG_STORED_PLAYER, this.storedPlayer); } if (this.storedPlayerProfile != null) { - tag.put(TAG_STORED_PLAYER_PROFILE, NbtUtils.writeGameProfile(new CompoundTag(), storedPlayerProfile)); + tag.put(TAG_STORED_PLAYER_PROFILE, ExtraCodecs.GAME_PROFILE.encodeStart(NbtOps.INSTANCE, storedPlayerProfile).getOrThrow()); } } @Override - protected void loadModData(CompoundTag tag) { - super.loadModData(tag); + protected void loadModData(CompoundTag tag, HolderLookup.Provider registries) { + super.loadModData(tag, registries); if (tag.contains(TAG_STORED_PLAYER, Tag.TAG_INT_ARRAY)) { this.storedPlayer = tag.getUUID(TAG_STORED_PLAYER); } else { this.storedPlayer = null; } if (tag.contains(TAG_STORED_PLAYER_PROFILE, Tag.TAG_COMPOUND)) { - this.storedPlayerProfile = NbtUtils.readGameProfile(tag.getCompound(TAG_STORED_PLAYER_PROFILE)); + this.storedPlayerProfile = ExtraCodecs.GAME_PROFILE.parse(NbtOps.INSTANCE, tag.getCompound(TAG_STORED_PLAYER_PROFILE)).getOrThrow(); } else { this.storedPlayerProfile = null; } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/blocks/circles/impetuses/BlockLookingImpetus.java b/Common/src/main/java/at/petrak/hexcasting/common/blocks/circles/impetuses/BlockLookingImpetus.java index 6cb5a1c245..b84a5d052c 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/blocks/circles/impetuses/BlockLookingImpetus.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/blocks/circles/impetuses/BlockLookingImpetus.java @@ -1,6 +1,7 @@ package at.petrak.hexcasting.common.blocks.circles.impetuses; import at.petrak.hexcasting.api.block.circle.BlockAbstractImpetus; +import at.petrak.hexcasting.api.casting.circles.BlockEntityAbstractImpetus; import at.petrak.hexcasting.common.lib.HexBlockEntities; import net.minecraft.core.BlockPos; import net.minecraft.world.level.Level; @@ -16,6 +17,11 @@ public BlockLookingImpetus(Properties p_49795_) { super(p_49795_); } + @Override + public BlockEntityType getBlockEntityType() { + return HexBlockEntities.IMPETUS_LOOK_TILE; + } + @Nullable @Override public BlockEntity newBlockEntity(BlockPos pPos, BlockState pState) { diff --git a/Common/src/main/java/at/petrak/hexcasting/common/blocks/circles/impetuses/BlockRedstoneImpetus.java b/Common/src/main/java/at/petrak/hexcasting/common/blocks/circles/impetuses/BlockRedstoneImpetus.java index fe4fb73e1b..168fb42a9c 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/blocks/circles/impetuses/BlockRedstoneImpetus.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/blocks/circles/impetuses/BlockRedstoneImpetus.java @@ -1,7 +1,9 @@ package at.petrak.hexcasting.common.blocks.circles.impetuses; import at.petrak.hexcasting.api.block.circle.BlockAbstractImpetus; +import at.petrak.hexcasting.api.casting.circles.BlockEntityAbstractImpetus; import at.petrak.hexcasting.api.casting.iota.EntityIota; +import at.petrak.hexcasting.common.lib.HexBlockEntities; import at.petrak.hexcasting.common.lib.HexSounds; import at.petrak.hexcasting.xplat.IXplatAbstractions; import net.minecraft.core.BlockPos; @@ -10,10 +12,13 @@ import net.minecraft.util.RandomSource; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; +import net.minecraft.world.ItemInteractionResult; import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.StateDefinition; import net.minecraft.world.level.block.state.properties.BlockStateProperties; @@ -28,6 +33,11 @@ public BlockRedstoneImpetus(Properties p_49795_) { super(p_49795_); } + @Override + public BlockEntityType getBlockEntityType() { + return HexBlockEntities.IMPETUS_REDSTONE_TILE; + } + @Nullable @Override public BlockEntity newBlockEntity(BlockPos pPos, BlockState pState) { @@ -41,37 +51,38 @@ protected void createBlockStateDefinition(StateDefinition.Builder getBlockEntityType() { + return HexBlockEntities.IMPETUS_RIGHTCLICK_TILE; + } + @Nullable @Override public BlockEntity newBlockEntity(BlockPos pPos, BlockState pState) { @@ -24,14 +32,13 @@ public BlockEntity newBlockEntity(BlockPos pPos, BlockState pState) { } @Override - public InteractionResult use(BlockState pState, Level pLevel, BlockPos pPos, Player pPlayer, InteractionHand pHand, - BlockHitResult pHit) { - if (!pPlayer.isShiftKeyDown()) { - var tile = pLevel.getBlockEntity(pPos); + protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) { + if (!player.isShiftKeyDown()) { + var tile = level.getBlockEntity(pos); if (tile instanceof BlockEntityRightClickImpetus impetus) { - if (pPlayer instanceof ServerPlayer serverPlayer) { + if (player instanceof ServerPlayer sPlayer) { // impetus.activateSpellCircle(serverPlayer); - impetus.startExecution(serverPlayer); + impetus.startExecution(sPlayer); } return InteractionResult.SUCCESS; } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/blocks/decoration/BlockAmethystDirectional.java b/Common/src/main/java/at/petrak/hexcasting/common/blocks/decoration/BlockAmethystDirectional.java index 8206a583a7..8eaea34e68 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/blocks/decoration/BlockAmethystDirectional.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/blocks/decoration/BlockAmethystDirectional.java @@ -1,5 +1,6 @@ package at.petrak.hexcasting.common.blocks.decoration; +import com.mojang.serialization.MapCodec; import net.minecraft.core.BlockPos; import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; @@ -8,11 +9,14 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.DirectionalBlock; +import net.minecraft.world.level.block.EndRodBlock; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.StateDefinition; import net.minecraft.world.phys.BlockHitResult; public class BlockAmethystDirectional extends DirectionalBlock { + public static final MapCodec CODEC = simpleCodec(BlockAmethystDirectional::new); + public BlockAmethystDirectional(Properties properties) { super(properties); } @@ -23,7 +27,6 @@ public void onProjectileHit(Level level, BlockState state, BlockHitResult result level.playSound(null, pos, SoundEvents.AMETHYST_BLOCK_HIT, SoundSource.BLOCKS, 1.0F, 0.5F + level.random.nextFloat() * 1.2F); level.playSound(null, pos, SoundEvents.AMETHYST_BLOCK_CHIME, SoundSource.BLOCKS, 1.0F, 0.5F + level.random.nextFloat() * 1.2F); } - } protected void createBlockStateDefinition(StateDefinition.Builder $$0) { @@ -33,4 +36,9 @@ protected void createBlockStateDefinition(StateDefinition.Builder codec() { + return CODEC; + } } \ No newline at end of file diff --git a/Common/src/main/java/at/petrak/hexcasting/common/blocks/decoration/BlockHexDoor.java b/Common/src/main/java/at/petrak/hexcasting/common/blocks/decoration/BlockHexDoor.java index 6bc4459c00..c94970d4fb 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/blocks/decoration/BlockHexDoor.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/blocks/decoration/BlockHexDoor.java @@ -10,7 +10,7 @@ public class BlockHexDoor extends DoorBlock { public BlockHexDoor(Properties $$0) { - super($$0, HexBlockSetTypes.EDIFIED_WOOD); + super(HexBlockSetTypes.EDIFIED_WOOD, $$0); } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/blocks/decoration/BlockHexFenceGate.java b/Common/src/main/java/at/petrak/hexcasting/common/blocks/decoration/BlockHexFenceGate.java index 10fc89230e..a36a2a6c3f 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/blocks/decoration/BlockHexFenceGate.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/blocks/decoration/BlockHexFenceGate.java @@ -12,7 +12,7 @@ public class BlockHexFenceGate extends FenceGateBlock { public BlockHexFenceGate(Properties $$0) { - super($$0, WoodType.DARK_OAK); + super(WoodType.DARK_OAK, $$0); } @SoftImplement("forge") diff --git a/Common/src/main/java/at/petrak/hexcasting/common/blocks/decoration/BlockHexPressurePlate.java b/Common/src/main/java/at/petrak/hexcasting/common/blocks/decoration/BlockHexPressurePlate.java index 5e6a517b1d..0017c066b1 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/blocks/decoration/BlockHexPressurePlate.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/blocks/decoration/BlockHexPressurePlate.java @@ -9,8 +9,8 @@ import net.minecraft.world.level.block.state.BlockState; public class BlockHexPressurePlate extends PressurePlateBlock { - public BlockHexPressurePlate(Sensitivity $$0, Properties $$1) { - super($$0, $$1, HexBlockSetTypes.EDIFIED_WOOD); + public BlockHexPressurePlate(Properties $$0) { + super(HexBlockSetTypes.EDIFIED_WOOD, $$0); } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/blocks/decoration/BlockHexTrapdoor.java b/Common/src/main/java/at/petrak/hexcasting/common/blocks/decoration/BlockHexTrapdoor.java index 3e2620c59b..62d49a6eeb 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/blocks/decoration/BlockHexTrapdoor.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/blocks/decoration/BlockHexTrapdoor.java @@ -10,7 +10,7 @@ public class BlockHexTrapdoor extends TrapDoorBlock { public BlockHexTrapdoor(Properties $$0) { - super($$0, HexBlockSetTypes.EDIFIED_WOOD); + super(HexBlockSetTypes.EDIFIED_WOOD, $$0); } @SoftImplement("forge") diff --git a/Common/src/main/java/at/petrak/hexcasting/common/blocks/decoration/BlockHexWoodButton.java b/Common/src/main/java/at/petrak/hexcasting/common/blocks/decoration/BlockHexWoodButton.java index 355f9edb9a..3676b5a009 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/blocks/decoration/BlockHexWoodButton.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/blocks/decoration/BlockHexWoodButton.java @@ -10,7 +10,7 @@ public class BlockHexWoodButton extends ButtonBlock { public BlockHexWoodButton(Properties $$0) { - super($$0, BlockSetType.DARK_OAK, 30, true); + super(BlockSetType.DARK_OAK, 30, $$0); } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/blocks/entity/BlockEntityConjured.java b/Common/src/main/java/at/petrak/hexcasting/common/blocks/entity/BlockEntityConjured.java index 5ac5004b91..e9caf5c417 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/blocks/entity/BlockEntityConjured.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/blocks/entity/BlockEntityConjured.java @@ -7,7 +7,9 @@ import at.petrak.hexcasting.common.lib.HexBlockEntities; import at.petrak.hexcasting.common.particles.ConjureParticleOptions; import net.minecraft.core.BlockPos; +import net.minecraft.core.HolderLookup; import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtOps; import net.minecraft.world.entity.Entity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.Vec3; @@ -89,13 +91,13 @@ public void landParticle(Entity entity, int number) { } @Override - protected void saveModData(CompoundTag tag) { - tag.put(TAG_COLORIZER, this.colorizer.serializeToNBT()); + protected void saveModData(CompoundTag tag, HolderLookup.Provider registries) { + tag.put(TAG_COLORIZER, FrozenPigment.CODEC.encodeStart(NbtOps.INSTANCE, colorizer).getOrThrow()); } @Override - protected void loadModData(CompoundTag tag) { - this.colorizer = FrozenPigment.fromNBT(tag.getCompound(TAG_COLORIZER)); + protected void loadModData(CompoundTag tag, HolderLookup.Provider registries) { + this.colorizer = FrozenPigment.CODEC.parse(NbtOps.INSTANCE, tag.getCompound(TAG_COLORIZER)).getOrThrow(); } public FrozenPigment getColorizer() { diff --git a/Common/src/main/java/at/petrak/hexcasting/common/blocks/entity/BlockEntityQuenchedAllay.java b/Common/src/main/java/at/petrak/hexcasting/common/blocks/entity/BlockEntityQuenchedAllay.java index dac5512a58..186bc613ab 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/blocks/entity/BlockEntityQuenchedAllay.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/blocks/entity/BlockEntityQuenchedAllay.java @@ -4,6 +4,7 @@ import at.petrak.hexcasting.common.blocks.BlockQuenchedAllay; import at.petrak.hexcasting.common.lib.HexBlockEntities; import net.minecraft.core.BlockPos; +import net.minecraft.core.HolderLookup; import net.minecraft.nbt.CompoundTag; import net.minecraft.world.level.block.state.BlockState; @@ -22,12 +23,12 @@ public static BiFunction fromKno } @Override - protected void saveModData(CompoundTag tag) { + protected void saveModData(CompoundTag tag, HolderLookup.Provider registries) { } @Override - protected void loadModData(CompoundTag tag) { + protected void loadModData(CompoundTag tag, HolderLookup.Provider registries) { } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/akashic/OpAkashicRead.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/akashic/OpAkashicRead.kt index 34a28f0d26..552ba4e5ac 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/akashic/OpAkashicRead.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/akashic/OpAkashicRead.kt @@ -24,6 +24,6 @@ object OpAkashicRead : ConstMediaAction { } val datum = record.lookupPattern(pos, key, env.world) - return listOf(datum ?: NullIota()) + return listOf(datum ?: NullIota.INSTANCE) } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/akashic/OpAkashicWrite.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/akashic/OpAkashicWrite.kt index 2089965835..5ee2cf655a 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/akashic/OpAkashicWrite.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/akashic/OpAkashicWrite.kt @@ -34,7 +34,7 @@ object OpAkashicWrite : SpellAction { throw MishapNoAkashicRecord(pos) } - val trueName = MishapOthersName.getTrueNameFromDatum(datum, env.castingEntity as? ServerPlayer) + val trueName = MishapOthersName.getTrueNameFromDatum(env.world, datum, env.castingEntity as? ServerPlayer) if (trueName != null) throw MishapOthersName(trueName) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpIndex.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpIndex.kt index dacaa022a8..261cf0f696 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpIndex.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpIndex.kt @@ -13,7 +13,7 @@ object OpIndex : ConstMediaAction { override fun execute(args: List, env: CastingEnvironment): List { val list = args.getList(0, argc).toMutableList() val index = args.getDouble(1, argc) - val x = list.getOrElse(index.roundToInt()) { NullIota() } + val x = list.getOrElse(index.roundToInt()) { NullIota.INSTANCE } return listOf(x) } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpUnCons.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpUnCons.kt index 211e91283d..5156595309 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpUnCons.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/lists/OpUnCons.kt @@ -14,6 +14,6 @@ object OpUnCons : ConstMediaAction { if (list.nonEmpty) { return listOf(ListIota(list.cdr), list.car) } - return listOf(args[0], NullIota()) + return listOf(args[0], NullIota.INSTANCE) } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/local/OpPeekLocal.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/local/OpPeekLocal.kt index 375b5bbcc0..f0e4b994c6 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/local/OpPeekLocal.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/local/OpPeekLocal.kt @@ -9,15 +9,16 @@ import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation import at.petrak.hexcasting.api.casting.iota.IotaType import at.petrak.hexcasting.api.casting.iota.NullIota import at.petrak.hexcasting.common.lib.hex.HexEvalSounds +import net.minecraft.nbt.NbtOps object OpPeekLocal : Action { override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult { val stack = image.stack.toMutableList() val rm = if (image.userData.contains(HexAPI.RAVENMIND_USERDATA)) { - IotaType.deserialize(image.userData.getCompound(HexAPI.RAVENMIND_USERDATA), env.world) + IotaType.TYPED_CODEC.parse(NbtOps.INSTANCE, image.userData.getCompound(HexAPI.RAVENMIND_USERDATA)).getOrThrow() } else { - NullIota() + NullIota.INSTANCE } stack.add(rm) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/local/OpPushLocal.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/local/OpPushLocal.kt index 59c8a7e078..0346451238 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/local/OpPushLocal.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/local/OpPushLocal.kt @@ -10,6 +10,8 @@ import at.petrak.hexcasting.api.casting.iota.IotaType import at.petrak.hexcasting.api.casting.mishaps.MishapNotEnoughArgs import at.petrak.hexcasting.common.lib.hex.HexEvalSounds import at.petrak.hexcasting.common.lib.hex.HexIotaTypes +import net.minecraft.nbt.NbtOps +import net.minecraft.nbt.Tag object OpPushLocal : Action { override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult { @@ -22,7 +24,7 @@ object OpPushLocal : Action { if (newLocal.type == HexIotaTypes.NULL) image.userData.remove(HexAPI.RAVENMIND_USERDATA) else - image.userData.put(HexAPI.RAVENMIND_USERDATA, IotaType.serialize(newLocal)) + image.userData.put(HexAPI.RAVENMIND_USERDATA, IotaType.TYPED_CODEC.encodeStart(NbtOps.INSTANCE, newLocal).getOrThrow()) val image2 = image.withUsedOp().copy(stack = stack) return OperationResult(image2, listOf(), continuation, HexEvalSounds.NORMAL_EXECUTE) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpCanEntityHexFly.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpCanEntityHexFly.kt index 8e79bd84da..82d8202fbc 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpCanEntityHexFly.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpCanEntityHexFly.kt @@ -11,7 +11,7 @@ object OpCanEntityHexFly : ConstMediaAction { override val argc = 1 override fun execute(args: List, env: CastingEnvironment): List { - val player = args.getPlayer(0, argc) + val player = args.getPlayer(env.world, 0, argc) env.assertEntityInRange(player) val flightAbility = IXplatAbstractions.INSTANCE.getFlight(player) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpEntityHeight.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpEntityHeight.kt index 5e84528387..d8907cc416 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpEntityHeight.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpEntityHeight.kt @@ -10,7 +10,7 @@ object OpEntityHeight : ConstMediaAction { override val argc = 1 override fun execute(args: List, env: CastingEnvironment): List { - val e = args.getEntity(0, argc) + val e = args.getEntity(env.world, 0, argc) env.assertEntityInRange(e) return e.bbHeight.asActionResult } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpEntityLook.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpEntityLook.kt index 23e47e9076..b1eaed2c6f 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpEntityLook.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpEntityLook.kt @@ -10,7 +10,7 @@ object OpEntityLook : ConstMediaAction { override val argc = 1 override fun execute(args: List, env: CastingEnvironment): List { - val e = args.getEntity(0, argc) + val e = args.getEntity(env.world, 0, argc) env.assertEntityInRange(e) return e.lookAngle.asActionResult } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpEntityPos.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpEntityPos.kt index 06a6e1cb36..2cb8188297 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpEntityPos.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpEntityPos.kt @@ -10,7 +10,7 @@ class OpEntityPos(val feet: Boolean) : ConstMediaAction { override val argc = 1 override fun execute(args: List, env: CastingEnvironment): List { - val e = args.getEntity(0, argc) + val e = args.getEntity(env.world, 0, argc) env.assertEntityInRange(e) return (if (this.feet) e.position() else e.eyePosition).asActionResult } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpEntityVelocity.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpEntityVelocity.kt index 8ce1097d56..293329a8bc 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpEntityVelocity.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpEntityVelocity.kt @@ -11,7 +11,7 @@ object OpEntityVelocity : ConstMediaAction { override val argc = 1 override fun execute(args: List, env: CastingEnvironment): List { - val e = args.getEntity(0, argc) + val e = args.getEntity(env.world, 0, argc) env.assertEntityInRange(e) val vel = HexAPI.instance().getEntityVelocitySpecial(e) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/raycast/OpBlockAxisRaycast.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/raycast/OpBlockAxisRaycast.kt index 2aa68ecf28..37d7aa33e9 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/raycast/OpBlockAxisRaycast.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/raycast/OpBlockAxisRaycast.kt @@ -35,7 +35,7 @@ object OpBlockAxisRaycast : ConstMediaAction { return if (blockHitResult.type == HitResult.Type.BLOCK && env.isVecInRange(Vec3.atCenterOf(blockHitResult.blockPos))) { blockHitResult.direction.step().asActionResult } else { - listOf(NullIota()) + listOf(NullIota.INSTANCE) } } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/raycast/OpBlockRaycast.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/raycast/OpBlockRaycast.kt index 33a2e990eb..34bd19b8aa 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/raycast/OpBlockRaycast.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/raycast/OpBlockRaycast.kt @@ -39,7 +39,7 @@ object OpBlockRaycast : ConstMediaAction { // TODO some action that has the "weird" version? blockHitResult.blockPos.asActionResult } else { - listOf(NullIota()) + listOf(NullIota.INSTANCE) } } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/raycast/OpEntityRaycast.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/raycast/OpEntityRaycast.kt index 64ea54525a..75ea1d5adf 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/raycast/OpEntityRaycast.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/raycast/OpEntityRaycast.kt @@ -38,7 +38,7 @@ object OpEntityRaycast : ConstMediaAction { return if (entityHitResult != null && env.isEntityInRange(entityHitResult.entity)) { entityHitResult.entity.asActionResult } else { - listOf(NullIota()) + listOf(NullIota.INSTANCE) } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpRead.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpRead.kt index 51791b6d26..0c8087b4b3 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpRead.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpRead.kt @@ -12,7 +12,7 @@ object OpRead : ConstMediaAction { override fun execute(args: List, env: CastingEnvironment): List { val (handStack) = env.getHeldItemToOperateOn { val dataHolder = IXplatAbstractions.INSTANCE.findDataHolder(it) - dataHolder != null && (dataHolder.readIota(env.world) != null || dataHolder.emptyIota() != null) + dataHolder != null && (dataHolder.readIota() != null || dataHolder.emptyIota() != null) } // If there are no data holders that are readable, find a data holder that isn't readable // so that the error message is more helpful. @@ -24,7 +24,7 @@ object OpRead : ConstMediaAction { val datumHolder = IXplatAbstractions.INSTANCE.findDataHolder(handStack) ?: throw MishapBadOffhandItem.of(handStack, "iota.read") - val datum = datumHolder.readIota(env.world) + val datum = datumHolder.readIota() ?: datumHolder.emptyIota() ?: throw MishapBadOffhandItem.of(handStack, "iota.read") diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpReadable.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpReadable.kt index d368b9d87b..93d234dfc0 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpReadable.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpReadable.kt @@ -18,7 +18,7 @@ object OpReadable : ConstMediaAction { ?: return false.asActionResult // If the datum contains no iota, return whether it has a default empty iota. - datumHolder.readIota(env.world) + datumHolder.readIota() ?: return (datumHolder.emptyIota() != null).asActionResult return true.asActionResult diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpTheCoolerRead.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpTheCoolerRead.kt index 4fd4a69f8b..060ebe9d77 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpTheCoolerRead.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpTheCoolerRead.kt @@ -14,14 +14,14 @@ object OpTheCoolerRead : ConstMediaAction { args: List, env: CastingEnvironment ): List { - val target = args.getEntity(0, argc) + val target = args.getEntity(env.world, 0, argc) env.assertEntityInRange(target) val datumHolder = IXplatAbstractions.INSTANCE.findDataHolder(target) ?: throw MishapBadEntity.of(target, "iota.read") - val datum = datumHolder.readIota(env.world) + val datum = datumHolder.readIota() ?: datumHolder.emptyIota() ?: throw MishapBadEntity.of(target, "iota.read") return listOf(datum) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpTheCoolerReadable.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpTheCoolerReadable.kt index aa118182af..2b191da486 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpTheCoolerReadable.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpTheCoolerReadable.kt @@ -14,13 +14,13 @@ object OpTheCoolerReadable : ConstMediaAction { args: List, env: CastingEnvironment ): List { - val target = args.getEntity(0, argc) + val target = args.getEntity(env.world, 0, argc) env.assertEntityInRange(target) val datumHolder = IXplatAbstractions.INSTANCE.findDataHolder(target) ?: return false.asActionResult - datumHolder.readIota(env.world) + datumHolder.readIota() ?: datumHolder.emptyIota() ?: return false.asActionResult diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpTheCoolerWritable.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpTheCoolerWritable.kt index 598ae8b145..e76a6dba84 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpTheCoolerWritable.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpTheCoolerWritable.kt @@ -15,13 +15,13 @@ object OpTheCoolerWritable : ConstMediaAction { args: List, env: CastingEnvironment ): List { - val target = args.getEntity(0, argc) + val target = args.getEntity(env.world, 0, argc) env.assertEntityInRange(target) val datumHolder = IXplatAbstractions.INSTANCE.findDataHolder(target) ?: return false.asActionResult - val success = datumHolder.writeIota(NullIota(), true) + val success = datumHolder.writeIota(NullIota.INSTANCE, true) return success.asActionResult } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpTheCoolerWrite.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpTheCoolerWrite.kt index 27e02a8f97..326705b32a 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpTheCoolerWrite.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpTheCoolerWrite.kt @@ -19,7 +19,7 @@ object OpTheCoolerWrite : SpellAction { args: List, env: CastingEnvironment ): SpellAction.Result { - val target = args.getEntity(0, argc) + val target = args.getEntity(env.world, 0, argc) val datum = args[1] env.assertEntityInRange(target) @@ -32,7 +32,7 @@ object OpTheCoolerWrite : SpellAction { // We pass null here so that even the own caster won't be allowed into a focus. // Otherwise, you could sentinel scout to people and remotely write their names into things using a cleric circle. - val trueName = MishapOthersName.getTrueNameFromDatum(datum, null) + val trueName = MishapOthersName.getTrueNameFromDatum(env.world, datum, null) if (trueName != null) throw MishapOthersName(trueName) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpWrite.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpWrite.kt index 317dbc0453..66407097a7 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpWrite.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/rw/OpWrite.kt @@ -37,7 +37,7 @@ object OpWrite : SpellAction { if (!datumHolder.writeIota(datum, true)) throw MishapBadOffhandItem.of(handStack, "iota.readonly", datum.display()) - val trueName = MishapOthersName.getTrueNameFromDatum(datum, env.castingEntity as? ServerPlayer) + val trueName = MishapOthersName.getTrueNameFromDatum(env.world, datum, env.castingEntity as? ServerPlayer) if (trueName != null) throw MishapOthersName(trueName) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpAddMotion.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpAddMotion.kt index 7f45168f85..90c1d15a0b 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpAddMotion.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpAddMotion.kt @@ -25,7 +25,7 @@ object OpAddMotion : SpellAction { env: CastingEnvironment, userData: CompoundTag ): SpellAction.Result { - val target = args.getEntity(0, argc) + val target = args.getEntity(env.world, 0, argc) val motion = args.getVec3(1, argc) env.assertEntityInRange(target) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpBlink.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpBlink.kt index a26f460d74..34a9862be8 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpBlink.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpBlink.kt @@ -20,14 +20,13 @@ import kotlin.math.roundToLong object OpBlink : SpellAction { override val argc = 2 override fun execute( - args: List, - env: CastingEnvironment + args: List, + env: CastingEnvironment ): SpellAction.Result { - val target = args.getEntity(0, argc) + val target = args.getEntity(env.world, 0, argc) val delta = args.getDouble(1, argc) env.assertEntityInRange(target) - // TODO: is this the same as canChangeDimensions? and what does that boolean do anyways if (!target.canUsePortal(true) || target.type.`is`(HexTags.Entities.CANNOT_TELEPORT)) throw MishapImmuneEntity(target) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpColorize.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpColorize.kt index 1011420536..0c7da5c6f4 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpColorize.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpColorize.kt @@ -15,8 +15,8 @@ object OpColorize : SpellAction { override val argc = 0 override fun execute( - args: List, - env: CastingEnvironment + args: List, + env: CastingEnvironment ): SpellAction.Result { val (handStack) = env.getHeldItemToOperateOn(IXplatAbstractions.INSTANCE::isPigment) ?: throw MishapBadOffhandItem.of(ItemStack.EMPTY, "colorizer") // TODO: hack diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpDestroyFluid.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpDestroyFluid.kt index 17c1aa43a2..7f6da8e60d 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpDestroyFluid.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpDestroyFluid.kt @@ -23,8 +23,8 @@ import net.minecraft.world.phys.Vec3 object OpDestroyFluid : SpellAction { override val argc = 1 override fun execute( - args: List, - env: CastingEnvironment + args: List, + env: CastingEnvironment ): SpellAction.Result { val vecPos = args.getVec3(0, argc) val pos = BlockPos.containing(vecPos) @@ -79,7 +79,7 @@ object OpDestroyFluid : SpellAction { ) { val success = if (blockstate.block is BucketPickup && !(blockstate.block as BucketPickup).pickupBlock( - env.caster, + env.castingEntity as? ServerPlayer, env.world, here, blockstate diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpFlight.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpFlight.kt index 9258cc059e..82d5e87da3 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpFlight.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpFlight.kt @@ -31,7 +31,7 @@ class OpFlight(val type: Type) : SpellAction { args: List, env: CastingEnvironment ): SpellAction.Result { - val target = args.getPlayer(0, argc) + val target = args.getPlayer(env.world, 0, argc) val theArg = args.getPositiveDouble(1, argc) env.assertEntityInRange(target) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpIgnite.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpIgnite.kt index 4ad9a736f7..10e55fa507 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpIgnite.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpIgnite.kt @@ -27,12 +27,12 @@ import net.minecraft.world.phys.Vec3 object OpIgnite : SpellAction { override val argc = 1 override fun execute( - args: List, - env: CastingEnvironment + args: List, + env: CastingEnvironment ): SpellAction.Result { when (val target = args[0]) { is EntityIota -> { - val entity = args.getEntity(0, argc) + val entity = args.getEntity(env.world, 0, argc) env.assertEntityInRange(entity) return SpellAction.Result( EntitySpell(entity), @@ -40,7 +40,6 @@ object OpIgnite : SpellAction { listOf(ParticleSpray.burst(entity.position(), 1.0)) ) } - is Vec3Iota -> { val block = args.getBlockPos(0, argc) env.assertPosInRangeForEditing(block) @@ -50,7 +49,6 @@ object OpIgnite : SpellAction { listOf(ParticleSpray.burst(Vec3.atCenterOf(BlockPos(block)), 1.0)) ) } - else -> throw MishapInvalidIota.ofType(target, 0, "entity_or_vector") } } @@ -64,12 +62,7 @@ object OpIgnite : SpellAction { } fun tryToClick(ctx: CastingEnvironment, pos: BlockPos, item: Item): Boolean { - return IXplatAbstractions.INSTANCE.isPlacingAllowed( - ctx.world, - pos, - ItemStack(item), - ctx.castingEntity as? ServerPlayer - ) && + return IXplatAbstractions.INSTANCE.isPlacingAllowed(ctx.world, pos, ItemStack(item), ctx.castingEntity as? ServerPlayer) && item.useOn( UseOnContext( ctx.world, @@ -84,7 +77,9 @@ object OpIgnite : SpellAction { private data class EntitySpell(val entity: Entity) : RenderedSpell { override fun cast(env: CastingEnvironment) { - entity.igniteForSeconds(8f) + if (!entity.fireImmune()) { + entity.igniteForSeconds(8.0f) + } } } } \ No newline at end of file diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpMakeBattery.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpMakeBattery.kt index 5e86b23504..c21d8f5578 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpMakeBattery.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpMakeBattery.kt @@ -26,7 +26,7 @@ object OpMakeBattery : SpellAction { args: List, env: CastingEnvironment ): SpellAction.Result { - val entity = args.getItemEntity(0, argc) + val entity = args.getItemEntity(env.world, 0, argc) val (handStack, hand) = env.getHeldItemToOperateOn { it.`is`(HexTags.Items.PHIAL_BASE) } ?: throw MishapBadOffhandItem.of(ItemStack.EMPTY.copy(), "bottle") // TODO: hack diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpMakePackagedSpell.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpMakePackagedSpell.kt index 2601a70696..11b8290ed1 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpMakePackagedSpell.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpMakePackagedSpell.kt @@ -17,26 +17,30 @@ import at.petrak.hexcasting.xplat.IXplatAbstractions import net.minecraft.server.level.ServerPlayer import net.minecraft.world.entity.item.ItemEntity import net.minecraft.world.item.ItemStack +import net.minecraft.network.chat.Component +import java.util.function.Predicate; // TODO: How to handle in circles -class OpMakePackagedSpell(val itemType: T, val cost: Long) : SpellAction { +class OpMakePackagedSpell(val isValid: Predicate, val expectedTypeDesc: Component, val cost: Long) : SpellAction { + constructor(itemType: ItemPackagedHex, cost: Long) : this({s -> s.`is`(itemType)}, itemType.description, cost) {} + override val argc = 2 override fun execute( args: List, env: CastingEnvironment ): SpellAction.Result { - val entity = args.getItemEntity(0, argc) + val entity = args.getItemEntity(env.world, 0, argc) val patterns = args.getList(1, argc).toList() val (handStack) = env.getHeldItemToOperateOn { val hexHolder = IXplatAbstractions.INSTANCE.findHexHolder(it) - it.`is`(itemType) && hexHolder != null && !hexHolder.hasHex() + isValid.test(it) && hexHolder != null && !hexHolder.hasHex() } - ?: throw MishapBadOffhandItem(ItemStack.EMPTY.copy(), itemType.description) // TODO: hack + ?: throw MishapBadOffhandItem(ItemStack.EMPTY.copy(), expectedTypeDesc) // TODO: hack val hexHolder = IXplatAbstractions.INSTANCE.findHexHolder(handStack) - if (!handStack.`is`(itemType)) { - throw MishapBadOffhandItem(handStack, itemType.description) + if (!isValid.test(handStack)) { + throw MishapBadOffhandItem(handStack, expectedTypeDesc) } else if (hexHolder == null || hexHolder.hasHex()) { throw MishapBadOffhandItem.of(handStack, "iota.write") } @@ -54,7 +58,7 @@ class OpMakePackagedSpell(val itemType: T, val cost: Long) ) } - val trueName = MishapOthersName.getTrueNameFromArgs(patterns, env.castingEntity as? ServerPlayer) + val trueName = MishapOthersName.getTrueNameFromArgs(env.world, patterns, env.castingEntity as? ServerPlayer) if (trueName != null) throw MishapOthersName(trueName) 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 97cff21530..16a7dcc247 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 @@ -9,7 +9,6 @@ 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.misc.MediaConstants -import at.petrak.hexcasting.mixin.accessor.AccessorUseOnContext import at.petrak.hexcasting.xplat.IXplatAbstractions import net.minecraft.core.BlockPos import net.minecraft.core.Direction @@ -21,6 +20,7 @@ import net.minecraft.world.InteractionResult import net.minecraft.world.item.BlockItem import net.minecraft.world.item.ItemStack import net.minecraft.world.item.context.BlockPlaceContext +import net.minecraft.world.item.context.UseOnContext import net.minecraft.world.phys.BlockHitResult import net.minecraft.world.phys.Vec3 @@ -40,15 +40,7 @@ object OpPlaceBlock : SpellAction { ) val itemUseCtx = env .queryForMatchingStack { it.item is BlockItem } - ?.let { - AccessorUseOnContext.`hex$new`( - env.world, - env.castingEntity as? ServerPlayer, - env.castingHand, - it, - blockHit - ) - } + ?.let { UseOnContext(env.world, env.castingEntity as? ServerPlayer, env.castingHand, it, blockHit) } ?: throw MishapBadOffhandItem.of(ItemStack.EMPTY, "placeable") val placeContext = BlockPlaceContext(itemUseCtx) @@ -85,20 +77,14 @@ object OpPlaceBlock : SpellAction { spoofedStack.count = 1 val itemUseCtx = - AccessorUseOnContext.`hex$new`( - env.world, - caster as? ServerPlayer, - env.otherHand, - spoofedStack, - blockHit - ) + UseOnContext(env.world, caster as? ServerPlayer, env.otherHand, spoofedStack, blockHit) val placeContext = BlockPlaceContext(itemUseCtx) if (bstate.canBeReplaced(placeContext)) { - if (env.withdrawItem({ it == placeeStack }, 1, false)) { + if (env.withdrawItem({ ItemStack.isSameItemSameComponents(it, placeeStack) }, 1, false)) { val res = spoofedStack.useOn(placeContext) if (res != InteractionResult.FAIL) { - env.withdrawItem({ it == placeeStack }, 1, true) + env.withdrawItem({ ItemStack.isSameItemSameComponents(it, placeeStack) }, 1, true) env.world.playSound( caster as? ServerPlayer, diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpPotionEffect.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpPotionEffect.kt index a6a565d8d8..fcca24ddf9 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpPotionEffect.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpPotionEffect.kt @@ -19,10 +19,10 @@ class OpPotionEffect( get() = if (this.allowPotency) 3 else 2 override fun execute( - args: List, - env: CastingEnvironment + args: List, + env: CastingEnvironment ): SpellAction.Result { - val target = args.getLivingEntityButNotArmorStand(0, argc) + val target = args.getLivingEntityButNotArmorStand(env.world, 0, argc) val duration = args.getPositiveDouble(1, argc) val potency = if (this.allowPotency) args.getDoubleBetween(2, 1.0, 127.0, argc) @@ -42,12 +42,7 @@ class OpPotionEffect( ) } - private class Spell( - val effect: Holder, - val target: LivingEntity, - val duration: Double, - val potency: Double - ) : + private class Spell(val effect: Holder, val target: LivingEntity, val duration: Double, val potency: Double) : RenderedSpell { override fun cast(env: CastingEnvironment) { if (duration > 1.0 / 20.0) { diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpRecharge.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpRecharge.kt index 0b7fcb6dfd..b45191bc32 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpRecharge.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpRecharge.kt @@ -21,7 +21,7 @@ object OpRecharge : SpellAction { args: List, env: CastingEnvironment ): SpellAction.Result { - val entity = args.getItemEntity(0, argc) + val entity = args.getItemEntity(env.world, 0, argc) val (handStack) = env.getHeldItemToOperateOn { val media = IXplatAbstractions.INSTANCE.findMediaHolder(it) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpTheOnlyReasonAnyoneDownloadedPsi.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpTheOnlyReasonAnyoneDownloadedPsi.kt index 623caf778b..0b663b871c 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpTheOnlyReasonAnyoneDownloadedPsi.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpTheOnlyReasonAnyoneDownloadedPsi.kt @@ -7,13 +7,13 @@ 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.misc.MediaConstants -import at.petrak.hexcasting.mixin.accessor.AccessorUseOnContext import net.minecraft.core.BlockPos import net.minecraft.core.Direction import net.minecraft.server.level.ServerPlayer import net.minecraft.world.InteractionHand import net.minecraft.world.item.ItemStack import net.minecraft.world.item.Items +import net.minecraft.world.item.context.UseOnContext import net.minecraft.world.phys.BlockHitResult import net.minecraft.world.phys.Vec3 @@ -21,8 +21,8 @@ import net.minecraft.world.phys.Vec3 object OpTheOnlyReasonAnyoneDownloadedPsi : SpellAction { override val argc = 1 override fun execute( - args: List, - env: CastingEnvironment + args: List, + env: CastingEnvironment ): SpellAction.Result { val target = args.getBlockPos(0, argc) env.assertPosInRangeForEditing(target) @@ -38,13 +38,7 @@ object OpTheOnlyReasonAnyoneDownloadedPsi : SpellAction { override fun cast(env: CastingEnvironment) { // https://github.com/VazkiiMods/Psi/blob/master/src/main/java/vazkii/psi/common/spell/trick/PieceTrickOvergrow.java val hit = BlockHitResult(Vec3.ZERO, Direction.UP, pos, false) - val fakeContext = AccessorUseOnContext.`hex$new`( - env.world, - env.castingEntity as? ServerPlayer, - InteractionHand.MAIN_HAND, - ItemStack(Items.BONE_MEAL), - hit - ) + val fakeContext = UseOnContext(env.world, env.castingEntity as? ServerPlayer, InteractionHand.MAIN_HAND, ItemStack(Items.BONE_MEAL), hit) Items.BONE_MEAL.useOn(fakeContext) } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/great/OpAltiora.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/great/OpAltiora.kt index 515518cadc..8d71bfba57 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/great/OpAltiora.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/great/OpAltiora.kt @@ -20,7 +20,7 @@ object OpAltiora : SpellAction { override val argc = 1 override fun execute(args: List, env: CastingEnvironment): SpellAction.Result { - val target = args.getPlayer(0, argc) + val target = args.getPlayer(env.world, 0, argc) env.assertEntityInRange(target) return SpellAction.Result( diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/great/OpBrainsweep.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/great/OpBrainsweep.kt index 256ccc703a..04dd9e80e1 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/great/OpBrainsweep.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/great/OpBrainsweep.kt @@ -32,10 +32,10 @@ object OpBrainsweep : SpellAction { override fun hasCastingSound(ctx: CastingEnvironment) = false override fun execute( - args: List, - env: CastingEnvironment + args: List, + env: CastingEnvironment ): SpellAction.Result { - val sacrifice = args.getMob(0, argc) + val sacrifice = args.getMob(env.world, 0, argc) val vecPos = args.getVec3(1, argc) val pos = BlockPos.containing(vecPos) @@ -54,9 +54,10 @@ object OpBrainsweep : SpellAction { val state = env.world.getBlockState(pos) val recman = env.world.recipeManager - // TODO they changed recipes again val recipes = recman.getAllRecipesFor(HexRecipeStuffRegistry.BRAINSWEEP_TYPE) - val recipe = recipes.find { it.matches(state, sacrifice, env.world) } + val recipe = recipes.asSequence() + .map { it.value } + .find { it.matches(state, sacrifice, env.world) } ?: throw MishapBadBrainsweep(sacrifice, pos) return SpellAction.Result( diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/great/OpTeleport.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/great/OpTeleport.kt index 81a19a37a8..dbe42846ea 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/great/OpTeleport.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/great/OpTeleport.kt @@ -15,11 +15,13 @@ import at.petrak.hexcasting.api.mod.HexTags import at.petrak.hexcasting.common.msgs.MsgBlinkS2C import at.petrak.hexcasting.xplat.IXplatAbstractions import net.minecraft.core.BlockPos +import net.minecraft.core.component.DataComponents import net.minecraft.server.level.ServerLevel import net.minecraft.server.level.ServerPlayer import net.minecraft.server.level.TicketType import net.minecraft.world.entity.Entity import net.minecraft.world.item.enchantment.EnchantmentHelper +import net.minecraft.world.item.enchantment.Enchantments import net.minecraft.world.level.ChunkPos import net.minecraft.world.phys.Vec3 @@ -28,15 +30,14 @@ import net.minecraft.world.phys.Vec3 object OpTeleport : SpellAction { override val argc = 2 override fun execute( - args: List, - env: CastingEnvironment + args: List, + env: CastingEnvironment ): SpellAction.Result { - val teleportee = args.getEntity(0, argc) + val teleportee = args.getEntity(env.world, 0, argc) val delta = args.getVec3(1, argc) env.assertEntityInRange(teleportee) - // TODO: see todos on blink if (!teleportee.canUsePortal(true) || teleportee.type.`is`(HexTags.Entities.CANNOT_TELEPORT)) throw MishapImmuneEntity(teleportee) @@ -63,7 +64,7 @@ object OpTeleport : SpellAction { teleportRespectSticky(teleportee, delta, env.world) - if (teleportee is ServerPlayer && teleportee == env.castingEntity) { + if (HexConfig.server().doesGreaterTeleportSplatItems() && teleportee is ServerPlayer && teleportee == env.castingEntity) { // Drop items conditionally, based on distance teleported. // MOST IMPORTANT: Never drop main hand item, since if it's a trinket, it will get duplicated later. @@ -73,7 +74,7 @@ object OpTeleport : SpellAction { // having to rearrange those. Also it makes sense for LORE REASONS probably, since the caster is more // aware of items they use often. for (armorItem in teleportee.inventory.armor) { - if (EnchantmentHelper.hasBindingCurse(armorItem)) + if (armorItem.get(DataComponents.ENCHANTMENTS)?.keySet()?.any { e -> e.`is`(Enchantments.BINDING_CURSE) } == true) continue if (Math.random() < baseDropChance * 0.25) { diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/sentinel/OpGetSentinelPos.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/sentinel/OpGetSentinelPos.kt index fa56812ca5..1363ed9528 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/sentinel/OpGetSentinelPos.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/sentinel/OpGetSentinelPos.kt @@ -18,7 +18,7 @@ object OpGetSentinelPos : ConstMediaAction { if (env.castingEntity !is ServerPlayer) throw MishapBadCaster() - val sentinel = IXplatAbstractions.INSTANCE.getSentinel(env.castingEntity as? ServerPlayer) ?: return listOf(NullIota()) + val sentinel = IXplatAbstractions.INSTANCE.getSentinel(env.castingEntity as? ServerPlayer) ?: return listOf(NullIota.INSTANCE) if (sentinel.dimension != env.world.dimension()) throw MishapLocationInWrongDimension(sentinel.dimension.location()) return sentinel.position.asActionResult diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/sentinel/OpGetSentinelWayfind.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/sentinel/OpGetSentinelWayfind.kt index cad52447ed..aacc6ea486 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/sentinel/OpGetSentinelWayfind.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/sentinel/OpGetSentinelWayfind.kt @@ -23,7 +23,7 @@ object OpGetSentinelWayfind : ConstMediaAction { val from = args.getVec3(0, argc) - val sentinel = IXplatAbstractions.INSTANCE.getSentinel(env.castingEntity as? ServerPlayer) ?: return listOf(NullIota()) + val sentinel = IXplatAbstractions.INSTANCE.getSentinel(env.castingEntity as? ServerPlayer) ?: return listOf(NullIota.INSTANCE) if (sentinel.dimension != env.world.dimension()) throw MishapLocationInWrongDimension(sentinel.dimension.location()) diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorIndex.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorIndex.kt index 2ecb5fc140..e08265b4e0 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorIndex.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorIndex.kt @@ -15,7 +15,7 @@ object OperatorIndex : OperatorBasic(2, IotaMultiPredicate.pair(IotaPredicate.of val it = iotas.iterator() val list = downcast(it.next(), LIST).list.toMutableList() val index = downcast(it.next(), DOUBLE).double - val x = list.getOrElse(index.roundToInt()) { NullIota() } + val x = list.getOrElse(index.roundToInt()) { NullIota.INSTANCE } return listOf(x) } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorUnCons.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorUnCons.kt index 54f0de69c2..be234fd5b7 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorUnCons.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorUnCons.kt @@ -17,6 +17,6 @@ object OperatorUnCons : OperatorBasic(1, IotaMultiPredicate.all(IotaPredicate.of val list = it.nextList(arity) if (list.nonEmpty) return listOf(ListIota(list.cdr), list.car) - return listOf(ListIota(list), NullIota()) + return listOf(ListIota(list), NullIota.INSTANCE) } } \ No newline at end of file diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorUnappend.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorUnappend.kt index 6d60362b0d..d318ff21a4 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorUnappend.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/arithmetic/operator/list/OperatorUnappend.kt @@ -15,7 +15,7 @@ object OperatorUnappend : OperatorBasic(1, IotaMultiPredicate.all(IotaPredicate. override fun apply(iotas: Iterable, env: CastingEnvironment): Iterable { val it = iotas.iterator().withIndex() val list = it.nextList(arity).toMutableList() - val last = list.removeLastOrNull() ?: NullIota() + val last = list.removeLastOrNull() ?: NullIota.INSTANCE return listOf(ListIota(list), last) } } \ No newline at end of file diff --git a/Common/src/main/java/at/petrak/hexcasting/common/command/ListPerWorldPatternsCommand.java b/Common/src/main/java/at/petrak/hexcasting/common/command/ListPerWorldPatternsCommand.java index f39e14d47f..27c50f072f 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/command/ListPerWorldPatternsCommand.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/command/ListPerWorldPatternsCommand.java @@ -7,7 +7,9 @@ import at.petrak.hexcasting.api.utils.HexUtils; import at.petrak.hexcasting.common.casting.PatternRegistryManifest; import at.petrak.hexcasting.common.items.storage.ItemScroll; +import at.petrak.hexcasting.common.lib.HexDataComponents; import at.petrak.hexcasting.common.lib.HexItems; +import at.petrak.hexcasting.common.lib.HexRegistries; import at.petrak.hexcasting.server.ScrungledPatternsSave; import at.petrak.hexcasting.xplat.IXplatAbstractions; import com.mojang.brigadier.builder.LiteralArgumentBuilder; @@ -18,6 +20,7 @@ import net.minecraft.core.Registry; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.item.ItemStack; @@ -32,18 +35,18 @@ public static void add(LiteralArgumentBuilder cmd) { .then(Commands.literal("list") .executes(ctx -> list(ctx.getSource()))) .then(Commands.literal("give") - .then(Commands.argument("patternName", PatternResLocArgument.id()) + .then(Commands.argument("patternName", PatternResKeyArgument.id()) .executes(ctx -> giveOne(ctx.getSource(), getDefaultTarget(ctx.getSource()), - ResourceLocationArgument.getId(ctx, "patternName"), - PatternResLocArgument.getPattern(ctx, "patternName"))) + PatternResKeyArgument.getPatternKey(ctx, "patternName"), + PatternResKeyArgument.getPattern(ctx, "patternName"))) .then(Commands.argument("targets", EntityArgument.players()) .executes(ctx -> giveOne(ctx.getSource(), EntityArgument.getPlayers(ctx, "targets"), - ResourceLocationArgument.getId(ctx, "patternName"), - PatternResLocArgument.getPattern(ctx, "patternName")))))) + PatternResKeyArgument.getPatternKey(ctx, "patternName"), + PatternResKeyArgument.getPattern(ctx, "patternName")))))) .then(Commands.literal("giveAll") .executes(ctx -> giveAll(ctx.getSource(), @@ -98,18 +101,15 @@ private static int giveAll(CommandSourceStack source, Collection t var startDir = found.getSecond().canonicalStartDir(); var pat = HexPattern.fromAngles(signature, startDir); - var tag = new CompoundTag(); - tag.putString(ItemScroll.TAG_OP_ID, key.location().toString()); - tag.put(ItemScroll.TAG_PATTERN, pat.serializeToNBT()); - var stack = new ItemStack(HexItems.SCROLL_LARGE); - stack.setTag(tag); + stack.set(HexDataComponents.ACTION, key); + stack.set(HexDataComponents.PATTERN, pat); for (var player : targets) { var stackEntity = player.drop(stack, false); if (stackEntity != null) { stackEntity.setNoPickUpDelay(); - stackEntity.setThrower(player.getUUID()); + stackEntity.setThrower(player); } count++; @@ -130,20 +130,17 @@ private static int giveAll(CommandSourceStack source, Collection t } private static int giveOne(CommandSourceStack source, Collection targets, - ResourceLocation patternName, HexPattern pat) { + ResourceKey actionKey, HexPattern pat) { if (!targets.isEmpty()) { - var tag = new CompoundTag(); - tag.putString(ItemScroll.TAG_OP_ID, patternName.toString()); - tag.put(ItemScroll.TAG_PATTERN, pat.serializeToNBT()); - var stack = new ItemStack(HexItems.SCROLL_LARGE); - stack.setTag(tag); + stack.set(HexDataComponents.ACTION, actionKey); + stack.set(HexDataComponents.PATTERN, pat); source.sendSuccess(() -> Component.translatable( "command.hexcasting.pats.specific.success", stack.getDisplayName(), - patternName, + actionKey.location(), targets.size() == 1 ? targets.iterator().next().getDisplayName() : targets.size()), true); @@ -151,7 +148,7 @@ private static int giveOne(CommandSourceStack source, Collection t var stackEntity = player.drop(stack, false); if (stackEntity != null) { stackEntity.setNoPickUpDelay(); - stackEntity.setThrower(player.getUUID()); + stackEntity.setThrower(player); } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/command/PatternResKeyArgument.java b/Common/src/main/java/at/petrak/hexcasting/common/command/PatternResKeyArgument.java new file mode 100644 index 0000000000..4413203b37 --- /dev/null +++ b/Common/src/main/java/at/petrak/hexcasting/common/command/PatternResKeyArgument.java @@ -0,0 +1,83 @@ +package at.petrak.hexcasting.common.command; + +import at.petrak.hexcasting.api.casting.ActionRegistryEntry; +import at.petrak.hexcasting.api.casting.math.HexPattern; +import at.petrak.hexcasting.api.mod.HexTags; +import at.petrak.hexcasting.api.utils.HexUtils; +import at.petrak.hexcasting.common.casting.PatternRegistryManifest; +import at.petrak.hexcasting.common.lib.HexRegistries; +import at.petrak.hexcasting.xplat.IXplatAbstractions; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.exceptions.DynamicCommandExceptionType; +import com.mojang.brigadier.suggestion.Suggestions; +import com.mojang.brigadier.suggestion.SuggestionsBuilder; +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.commands.SharedSuggestionProvider; +import net.minecraft.commands.arguments.ResourceKeyArgument; +import net.minecraft.commands.arguments.ResourceLocationArgument; +import net.minecraft.core.Registry; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.crafting.RecipeHolder; +import net.minecraft.world.item.crafting.RecipeManager; + +import java.util.ArrayList; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; + +public class PatternResKeyArgument extends ResourceKeyArgument { + private static final DynamicCommandExceptionType ERROR_UNKNOWN_PATTERN = new DynamicCommandExceptionType( + (errorer) -> + Component.translatable("hexcasting.pattern.unknown", errorer) + ); + + public PatternResKeyArgument() { + super(HexRegistries.ACTION); + } + + public static PatternResKeyArgument id() { + return new PatternResKeyArgument(); + } + + @Override + public CompletableFuture listSuggestions(CommandContext context, SuggestionsBuilder builder) { + var suggestions = new ArrayList(); + var registry = IXplatAbstractions.INSTANCE.getActionRegistry(); + for (var key : registry.registryKeySet()) { + if (HexUtils.isOfTag(registry, key, HexTags.Actions.PER_WORLD_PATTERN)) { + suggestions.add(key.location().toString()); + } + } + + return SharedSuggestionProvider.suggest(suggestions, builder); + } + + public static ResourceKey getResourceKey( + CommandContext context, + String argumentName, + ResourceKey> registryKey, + DynamicCommandExceptionType exceptionType + ) throws CommandSyntaxException { + ResourceKey key = context.getArgument(argumentName, ResourceKey.class); + Optional> optional = key.cast(registryKey); + return optional.orElseThrow(() -> exceptionType.create(key.location())); + } + + public static ResourceKey getPatternKey( + CommandContext ctx, String argumentName) throws CommandSyntaxException { + return getResourceKey(ctx, argumentName, HexRegistries.ACTION, ERROR_UNKNOWN_PATTERN); + } + + public static HexPattern getPattern( + CommandContext ctx, String argumentName) throws CommandSyntaxException { + var targetKey = getPatternKey(ctx, argumentName); + var foundPat = PatternRegistryManifest.getCanonicalStrokesPerWorld(targetKey, ctx.getSource().getServer().overworld()); + if (foundPat == null) { + throw ERROR_UNKNOWN_PATTERN.create(targetKey.location()); + } else { + return foundPat; + } + } +} diff --git a/Common/src/main/java/at/petrak/hexcasting/common/command/PatternResLocArgument.java b/Common/src/main/java/at/petrak/hexcasting/common/command/PatternResLocArgument.java index 6403a422c9..d3a8813238 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/command/PatternResLocArgument.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/command/PatternResLocArgument.java @@ -20,6 +20,7 @@ import java.util.ArrayList; import java.util.concurrent.CompletableFuture; +@Deprecated public class PatternResLocArgument extends ResourceLocationArgument { private static final DynamicCommandExceptionType ERROR_UNKNOWN_PATTERN = new DynamicCommandExceptionType( (errorer) -> diff --git a/Common/src/main/java/at/petrak/hexcasting/common/entities/EntityWallScroll.java b/Common/src/main/java/at/petrak/hexcasting/common/entities/EntityWallScroll.java index 03d916c8f7..0d3de91530 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/entities/EntityWallScroll.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/entities/EntityWallScroll.java @@ -4,6 +4,7 @@ import at.petrak.hexcasting.api.utils.HexUtils; import at.petrak.hexcasting.api.utils.NBTHelper; import at.petrak.hexcasting.common.items.storage.ItemScroll; +import at.petrak.hexcasting.common.lib.HexDataComponents; import at.petrak.hexcasting.common.lib.HexItems; import at.petrak.hexcasting.common.lib.HexSounds; import at.petrak.hexcasting.common.msgs.MsgNewWallScrollS2C; @@ -13,11 +14,13 @@ import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.common.ClientCommonPacketListener; import net.minecraft.network.protocol.game.ClientGamePacketListener; import net.minecraft.network.protocol.game.ClientboundAddEntityPacket; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.SynchedEntityData; +import net.minecraft.server.level.ServerEntity; import net.minecraft.server.level.ServerLevel; import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; @@ -26,10 +29,12 @@ import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.decoration.HangingEntity; +import net.minecraft.world.entity.decoration.PaintingVariant; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.GameRules; import net.minecraft.world.level.Level; +import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.Vec3; import org.jetbrains.annotations.Nullable; @@ -61,20 +66,13 @@ public EntityWallScroll(Level world, BlockPos pos, Direction dir, ItemStack scro } public void recalculateDisplay() { - CompoundTag patternTag = NBTHelper.getCompound(scroll, ItemScroll.TAG_PATTERN); - if (patternTag != null) { - this.pattern = HexPattern.fromNBT(patternTag); - this.isAncient = NBTHelper.hasString(scroll, ItemScroll.TAG_OP_ID); - } else { - this.pattern = null; - this.isAncient = false; - } + this.pattern = scroll.get(HexDataComponents.PATTERN); + this.isAncient = scroll.has(HexDataComponents.ACTION); } @Override - protected void defineSynchedData() { - super.defineSynchedData(); - this.entityData.define(SHOWS_STROKE_ORDER, false); + protected void defineSynchedData(SynchedEntityData.Builder builder) { + builder.define(SHOWS_STROKE_ORDER, false); } public boolean getShowsStrokeOrder() { @@ -86,13 +84,17 @@ public void setShowsStrokeOrder(boolean b) { } @Override - public int getWidth() { - return 16 * blockSize; - } - - @Override - public int getHeight() { - return 16 * blockSize; + protected AABB calculateBoundingBox(BlockPos pos, Direction p_direction) { + float f = 0.46875F; + Vec3 vec3 = Vec3.atCenterOf(pos).relative(p_direction, -0.46875); + double d0 = blockSize % 2 == 0 ? 0.5 : 0.0; + Direction direction = p_direction.getCounterClockWise(); + Vec3 vec31 = vec3.relative(direction, d0).relative(Direction.UP, d0); + Direction.Axis direction$axis = p_direction.getAxis(); + double d2 = direction$axis == Direction.Axis.X ? 0.0625 : blockSize; + double d3 = blockSize; + double d4 = direction$axis == Direction.Axis.Z ? 0.0625 : blockSize; + return AABB.ofSize(vec31, d2, d3, d4); } @Override @@ -138,9 +140,9 @@ public void playPlacementSound() { } @Override - public Packet getAddEntityPacket() { + public Packet getAddEntityPacket(ServerEntity entity) { return IXplatAbstractions.INSTANCE.toVanillaClientboundPacket( - new MsgNewWallScrollS2C(new ClientboundAddEntityPacket(this), + new MsgNewWallScrollS2C(new ClientboundAddEntityPacket(this, this.direction.get3DDataValue(), this.getPos()), pos, direction, scroll, getShowsStrokeOrder(), blockSize)); } @@ -160,7 +162,7 @@ public void readSpawnData(BlockPos pos, Direction dir, ItemStack scrollItem, @Override public void addAdditionalSaveData(CompoundTag tag) { tag.putByte("direction", (byte) this.direction.ordinal()); - tag.put("scroll", HexUtils.serializeToNBT(this.scroll)); + tag.put("scroll", this.scroll.save(registryAccess())); tag.putBoolean("showsStrokeOrder", this.getShowsStrokeOrder()); tag.putInt("blockSize", this.blockSize); super.addAdditionalSaveData(tag); @@ -169,7 +171,7 @@ public void addAdditionalSaveData(CompoundTag tag) { @Override public void readAdditionalSaveData(CompoundTag tag) { this.direction = Direction.values()[tag.getByte("direction")]; - this.scroll = ItemStack.of(tag.getCompound("scroll")); + this.scroll = ItemStack.parse(registryAccess(), tag.getCompound("scroll")).orElse(ItemStack.EMPTY); this.blockSize = tag.getInt("blockSize"); this.setDirection(this.direction); @@ -187,9 +189,8 @@ public void moveTo(double pX, double pY, double pZ, float pYaw, float pPitch) { } @Override - public void lerpTo(double pX, double pY, double pZ, float pYaw, float pPitch, int pPosRotationIncrements, - boolean pTeleport) { - BlockPos blockpos = this.pos.offset((int) (pX - this.getX()), (int) (pY - this.getY()), (int) (pZ - this.getZ())); + public void lerpTo(double x, double y, double z, float yRot, float xRot, int steps) { + BlockPos blockpos = this.pos.offset((int) (x - this.getX()), (int) (y - this.getY()), (int) (z - this.getZ())); this.setPos(blockpos.getX(), blockpos.getY(), blockpos.getZ()); } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/impl/HexAPIImpl.java b/Common/src/main/java/at/petrak/hexcasting/common/impl/HexAPIImpl.java index 0ff996b907..c80424c0a5 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/impl/HexAPIImpl.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/impl/HexAPIImpl.java @@ -21,6 +21,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Collections; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.function.Consumer; @@ -96,50 +97,15 @@ public FrozenPigment getColorizer(Player player) { return IXplatAbstractions.INSTANCE.getPigment(player); } - ArmorMaterial ARMOR_MATERIAL = new ArmorMaterial() { - - @Override - public int getDurabilityForType(ArmorItem.Type type) { - return 0; - } - - @Override - public int getDefenseForType(ArmorItem.Type type) { - return 0; - } - - @Override - public int getEnchantmentValue() { - return 0; - } - - @NotNull - @Override - public SoundEvent getEquipSound() { - return SoundEvents.ARMOR_EQUIP_LEATHER; - } - - @NotNull - @Override - public Ingredient getRepairIngredient() { - return Ingredient.EMPTY; - } - - @Override - public String getName() { - return "robes"; - } - - @Override - public float getToughness() { - return 0; - } - - @Override - public float getKnockbackResistance() { - return 0; - } - }; + ArmorMaterial ARMOR_MATERIAL = new ArmorMaterial( + Collections.emptyMap(), + 0, + SoundEvents.ARMOR_EQUIP_LEATHER, + () -> Ingredient.EMPTY, + Collections.emptyList(), // TODO check textures. If not - use robes here from original code + 0, + 0 + ); @Override public ArmorMaterial robesMaterial() { diff --git a/Common/src/main/java/at/petrak/hexcasting/common/items/HexBaubleItem.java b/Common/src/main/java/at/petrak/hexcasting/common/items/HexBaubleItem.java index ed208b1b64..fc84afbeb4 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/items/HexBaubleItem.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/items/HexBaubleItem.java @@ -1,6 +1,7 @@ package at.petrak.hexcasting.common.items; import com.google.common.collect.Multimap; +import net.minecraft.core.Holder; import net.minecraft.world.entity.ai.attributes.Attribute; import net.minecraft.world.entity.ai.attributes.AttributeModifier; import net.minecraft.world.item.ItemStack; @@ -10,5 +11,5 @@ * I feel like botnia probably does it this way becase it's older than xplat curios */ public interface HexBaubleItem { - Multimap getHexBaubleAttrs(ItemStack stack); + Multimap, AttributeModifier> getHexBaubleAttrs(ItemStack stack); } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/items/ItemJewelerHammer.java b/Common/src/main/java/at/petrak/hexcasting/common/items/ItemJewelerHammer.java index d5b059f5f7..f1d6135e74 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/items/ItemJewelerHammer.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/items/ItemJewelerHammer.java @@ -2,16 +2,18 @@ import at.petrak.hexcasting.common.lib.HexItems; import net.minecraft.core.BlockPos; +import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.PickaxeItem; import net.minecraft.world.item.Tier; +import net.minecraft.world.item.component.ItemAttributeModifiers; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; public class ItemJewelerHammer extends PickaxeItem { - public ItemJewelerHammer(Tier tier, int damageMod, float attackSpeedMod, Properties props) { - super(tier, damageMod, attackSpeedMod, props); + public ItemJewelerHammer(Tier tier, Properties props) { + super(tier, props); } public static boolean shouldFailToBreak(Player player, BlockState state, BlockPos pos) { diff --git a/Common/src/main/java/at/petrak/hexcasting/common/items/ItemLens.java b/Common/src/main/java/at/petrak/hexcasting/common/items/ItemLens.java index 4b77873f29..ec8e4249b5 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/items/ItemLens.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/items/ItemLens.java @@ -1,18 +1,22 @@ package at.petrak.hexcasting.common.items; import at.petrak.hexcasting.annotations.SoftImplement; +import at.petrak.hexcasting.api.HexAPI; import at.petrak.hexcasting.common.lib.HexAttributes; import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; -import net.minecraft.core.BlockSource; +import net.minecraft.core.Holder; +import net.minecraft.core.dispenser.BlockSource; import net.minecraft.core.dispenser.OptionalDispenseItemBehavior; import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.EquipmentSlotGroup; import net.minecraft.world.entity.ai.attributes.Attribute; import net.minecraft.world.entity.ai.attributes.AttributeModifier; import net.minecraft.world.item.ArmorItem; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; //import net.minecraft.world.item.Wearable; +import net.minecraft.world.item.component.ItemAttributeModifiers; import net.minecraft.world.level.block.DispenserBlock; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -24,18 +28,15 @@ public class ItemLens extends Item implements HexBaubleItem { // Wearable, // The 0.1 is *additive* public static final AttributeModifier GRID_ZOOM = new AttributeModifier( - UUID.fromString("59d739b8-d419-45f7-a4ea-0efee0e3adf5"), - "Scrying Lens Zoom", 0.33, AttributeModifier.Operation.MULTIPLY_BASE); + HexAPI.modLoc("scrying_lens_zoom"), 0.33, AttributeModifier.Operation.ADD_MULTIPLIED_BASE); public static final AttributeModifier SCRY_SIGHT = new AttributeModifier( - UUID.fromString("e2e6e5d4-f978-4c11-8fdc-82a5af83385c"), - "Scrying Lens Sight", 1.0, AttributeModifier.Operation.ADDITION); + HexAPI.modLoc("scrying_lens_sight"), 1.0, AttributeModifier.Operation.ADD_VALUE); public ItemLens(Properties pProperties) { super(pProperties); DispenserBlock.registerBehavior(this, new OptionalDispenseItemBehavior() { - protected @NotNull - ItemStack execute(@NotNull BlockSource world, @NotNull ItemStack stack) { + protected @NotNull ItemStack execute(@NotNull BlockSource world, @NotNull ItemStack stack) { this.setSuccess(ArmorItem.dispenseArmor(world, stack)); return stack; } @@ -43,18 +44,21 @@ ItemStack execute(@NotNull BlockSource world, @NotNull ItemStack stack) { } @Override - public Multimap getDefaultAttributeModifiers(EquipmentSlot slot) { - var out = HashMultimap.create(super.getDefaultAttributeModifiers(slot)); - if (slot == EquipmentSlot.HEAD || slot == EquipmentSlot.MAINHAND || slot == EquipmentSlot.OFFHAND) { - out.put(HexAttributes.GRID_ZOOM, GRID_ZOOM); - out.put(HexAttributes.SCRY_SIGHT, SCRY_SIGHT); - } - return out; + public ItemAttributeModifiers getDefaultAttributeModifiers(ItemStack stack) { + return ItemAttributeModifiers.builder() + .add(HexAttributes.GRID_ZOOM, GRID_ZOOM, EquipmentSlotGroup.HEAD) + .add(HexAttributes.GRID_ZOOM, GRID_ZOOM, EquipmentSlotGroup.MAINHAND) + .add(HexAttributes.GRID_ZOOM, GRID_ZOOM, EquipmentSlotGroup.OFFHAND) + + .add(HexAttributes.SCRY_SIGHT, SCRY_SIGHT, EquipmentSlotGroup.HEAD) + .add(HexAttributes.SCRY_SIGHT, SCRY_SIGHT, EquipmentSlotGroup.MAINHAND) + .add(HexAttributes.SCRY_SIGHT, SCRY_SIGHT, EquipmentSlotGroup.OFFHAND) + .build(); } @Override - public Multimap getHexBaubleAttrs(ItemStack stack) { - HashMultimap out = HashMultimap.create(); + public Multimap, AttributeModifier> getHexBaubleAttrs(ItemStack stack) { + HashMultimap, AttributeModifier> out = HashMultimap.create(); out.put(HexAttributes.GRID_ZOOM, GRID_ZOOM); out.put(HexAttributes.SCRY_SIGHT, SCRY_SIGHT); return out; diff --git a/Common/src/main/java/at/petrak/hexcasting/common/items/ItemLoreFragment.java b/Common/src/main/java/at/petrak/hexcasting/common/items/ItemLoreFragment.java index 3d2f347bee..52e88072fd 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/items/ItemLoreFragment.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/items/ItemLoreFragment.java @@ -2,6 +2,7 @@ import at.petrak.hexcasting.common.lib.HexSounds; import net.minecraft.advancements.Advancement; +import net.minecraft.advancements.AdvancementHolder; import net.minecraft.advancements.CriteriaTriggers; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; @@ -49,11 +50,11 @@ public InteractionResultHolder use(Level level, Player player, Intera return InteractionResultHolder.success(handStack); } - Advancement unfoundLore = null; + AdvancementHolder unfoundLore = null; var shuffled = new ArrayList<>(NAMES); Collections.shuffle(shuffled); for (var advID : shuffled) { - var adv = splayer.server.getAdvancements().getAdvancement(advID); + var adv = splayer.server.getAdvancements().get(advID); if (adv == null) { continue; // uh oh } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/items/ItemStaff.java b/Common/src/main/java/at/petrak/hexcasting/common/items/ItemStaff.java index c571aadf58..7fc41bdf3b 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/items/ItemStaff.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/items/ItemStaff.java @@ -1,10 +1,13 @@ package at.petrak.hexcasting.common.items; import at.petrak.hexcasting.api.HexAPI; +import at.petrak.hexcasting.common.lib.HexAttributes; import at.petrak.hexcasting.common.lib.HexSounds; import at.petrak.hexcasting.common.msgs.MsgClearSpiralPatternsS2C; import at.petrak.hexcasting.common.msgs.MsgOpenSpellGuiS2C; import at.petrak.hexcasting.xplat.IXplatAbstractions; +import net.minecraft.core.Holder; +import net.minecraft.nbt.CompoundTag; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerPlayer; import net.minecraft.stats.Stats; @@ -17,7 +20,7 @@ public class ItemStaff extends Item { // 0 = normal. 1 = old. 2 = cherry preview - public static final ResourceLocation FUNNY_LEVEL_PREDICATE = new ResourceLocation(HexAPI.MOD_ID, "funny_level"); + public static final ResourceLocation FUNNY_LEVEL_PREDICATE = ResourceLocation.fromNamespaceAndPath(HexAPI.MOD_ID, "funny_level"); public ItemStaff(Properties pProperties) { super(pProperties); @@ -25,6 +28,9 @@ public ItemStaff(Properties pProperties) { @Override public InteractionResultHolder use(Level world, Player player, InteractionHand hand) { + if (player.getAttributeValue(HexAttributes.FEEBLE_MIND) > 0){ + return InteractionResultHolder.fail(player.getItemInHand(hand)); + } if (player.isShiftKeyDown()) { if (world.isClientSide()) { player.playSound(HexSounds.STAFF_RESET, 1f, 1f); @@ -37,12 +43,16 @@ public InteractionResultHolder use(Level world, Player player, Intera } if (!world.isClientSide() && player instanceof ServerPlayer serverPlayer) { - var harness = IXplatAbstractions.INSTANCE.getStaffcastVM(serverPlayer, hand); + var vm = IXplatAbstractions.INSTANCE.getStaffcastVM(serverPlayer, hand); var patterns = IXplatAbstractions.INSTANCE.getPatternsSavedInUi(serverPlayer); - var descs = harness.generateDescs(); + + var userData = vm.getImage().getUserData(); + CompoundTag ravenmind = null; + if(userData.contains(HexAPI.RAVENMIND_USERDATA)) + ravenmind = userData.getCompound(HexAPI.RAVENMIND_USERDATA); IXplatAbstractions.INSTANCE.sendPacketToPlayer(serverPlayer, - new MsgOpenSpellGuiS2C(hand, patterns, descs.getFirst(), descs.getSecond(), + new MsgOpenSpellGuiS2C(hand, patterns, vm.getImage().getStack(), ravenmind, 0)); // TODO: Fix! } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/items/armor/ItemRobes.java b/Common/src/main/java/at/petrak/hexcasting/common/items/armor/ItemRobes.java index 3ec73cbdc6..9ddef43531 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/items/armor/ItemRobes.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/items/armor/ItemRobes.java @@ -1,6 +1,7 @@ package at.petrak.hexcasting.common.items.armor; import at.petrak.hexcasting.api.HexAPI; +import net.minecraft.core.Holder; import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.item.ArmorItem; @@ -13,7 +14,7 @@ public class ItemRobes extends ArmorItem { public final ArmorItem.Type type; public ItemRobes(ArmorItem.Type type, Properties properties) { - super(HexAPI.instance().robesMaterial(), type, properties); + super(Holder.direct(HexAPI.instance().robesMaterial()), type, properties); this.type = type; } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/items/magic/DebugUnlockerHolder.java b/Common/src/main/java/at/petrak/hexcasting/common/items/magic/DebugUnlockerHolder.java index 045a6eeb76..a3bc73ded4 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/items/magic/DebugUnlockerHolder.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/items/magic/DebugUnlockerHolder.java @@ -1,6 +1,7 @@ package at.petrak.hexcasting.common.items.magic; import at.petrak.hexcasting.api.addldata.ADMediaHolder; +import at.petrak.hexcasting.common.lib.HexDataComponents; import net.minecraft.world.item.ItemStack; public record DebugUnlockerHolder(ItemStack creativeUnlocker) implements ADMediaHolder { @@ -41,14 +42,14 @@ public boolean canConstructBattery() { @Override public long withdrawMedia(long cost, boolean simulate) { - ItemCreativeUnlocker.addToLongArray(creativeUnlocker, ItemCreativeUnlocker.TAG_EXTRACTIONS, cost); + ItemCreativeUnlocker.addToLongArray(creativeUnlocker, HexDataComponents.MEDIA_EXTRACTIONS, cost); return cost < 0 ? getMedia() : cost; } @Override public long insertMedia(long amount, boolean simulate) { - ItemCreativeUnlocker.addToLongArray(creativeUnlocker, ItemCreativeUnlocker.TAG_INSERTIONS, amount); + ItemCreativeUnlocker.addToLongArray(creativeUnlocker, HexDataComponents.MEDIA_INSERTIONS, amount); return amount; } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/items/magic/ItemAncientCypher.java b/Common/src/main/java/at/petrak/hexcasting/common/items/magic/ItemAncientCypher.java new file mode 100644 index 0000000000..b6e8d2ef02 --- /dev/null +++ b/Common/src/main/java/at/petrak/hexcasting/common/items/magic/ItemAncientCypher.java @@ -0,0 +1,59 @@ +package at.petrak.hexcasting.common.items.magic; + +import at.petrak.hexcasting.api.casting.iota.IotaType; +import at.petrak.hexcasting.api.utils.NBTHelper; +import at.petrak.hexcasting.common.lib.HexDataComponents; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.Tag; +import net.minecraft.ChatFormatting; +import net.minecraft.network.chat.Component; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.level.Level; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class ItemAncientCypher extends ItemCypher { + public static final String TAG_HEX_NAME = "hex_name"; + + public ItemAncientCypher(Properties pProperties) { + super(pProperties); + } + + @Override + public void clearHex(ItemStack stack) { + super.clearHex(stack); + stack.remove(HexDataComponents.HEX_NAME); + } + + @Override + public Component getName(ItemStack stack) { + var descID = this.getDescriptionId(stack); + var hexName = stack.get(HexDataComponents.HEX_NAME); + if (hexName != null) { + return Component.translatable(descID + ".preset", Component.translatable(hexName)); + } else { + return Component.translatable(descID); + } + } + + @Override + public void appendHoverText(ItemStack stack, TooltipContext context, List tooltipComponents, TooltipFlag tooltipFlag) { + // display media fullness as usual + super.appendHoverText(stack, context, tooltipComponents, tooltipFlag); + + var patterns = stack.get(HexDataComponents.PATTERNS); + + // also show contained spell + if(patterns != null) { + var storedHex = Component.translatable("hexcasting.tooltip.stored_hex"); + + for(var iota : patterns) { + storedHex.append(iota.display().plainCopy().withStyle(ChatFormatting.DARK_PURPLE)); + } + + tooltipComponents.add(storedHex); + } + } +} diff --git a/Common/src/main/java/at/petrak/hexcasting/common/items/magic/ItemCreativeUnlocker.java b/Common/src/main/java/at/petrak/hexcasting/common/items/magic/ItemCreativeUnlocker.java index 586f8b2c02..8697b5ac42 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/items/magic/ItemCreativeUnlocker.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/items/magic/ItemCreativeUnlocker.java @@ -4,12 +4,14 @@ import at.petrak.hexcasting.api.item.MediaHolderItem; import at.petrak.hexcasting.api.misc.DiscoveryHandlers; import at.petrak.hexcasting.api.misc.MediaConstants; -import at.petrak.hexcasting.api.utils.NBTHelper; import at.petrak.hexcasting.common.items.ItemLoreFragment; +import at.petrak.hexcasting.common.lib.HexDataComponents; import at.petrak.hexcasting.common.lib.HexItems; import at.petrak.hexcasting.common.lib.HexSounds; import net.minecraft.ChatFormatting; -import net.minecraft.advancements.Advancement; +import net.minecraft.advancements.AdvancementNode; +import net.minecraft.core.component.DataComponentType; +import net.minecraft.core.component.DataComponents; import net.minecraft.locale.Language; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; @@ -27,7 +29,6 @@ import net.minecraft.world.item.context.UseOnContext; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; -import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Arrays; @@ -70,7 +71,7 @@ public static boolean isDebug(ItemStack stack) { } public static boolean isDebug(ItemStack stack, String flag) { - if (!stack.is(HexItems.CREATIVE_UNLOCKER) || !stack.hasCustomHoverName()) { + if (!stack.is(HexItems.CREATIVE_UNLOCKER) || !stack.has(DataComponents.CUSTOM_NAME)) { return false; } var keywords = Arrays.asList(stack.getHoverName().getString().toLowerCase(Locale.ROOT).split(" ")); @@ -124,31 +125,17 @@ public boolean canRecharge(ItemStack stack) { return true; } - public static void addToIntArray(ItemStack stack, String tag, int n) { - int[] arr = NBTHelper.getIntArray(stack, tag); - if (arr == null) { - arr = new int[0]; - } - int[] newArr = Arrays.copyOf(arr, arr.length + 1); - newArr[newArr.length - 1] = n; - NBTHelper.putIntArray(stack, tag, newArr); - } - - public static void addToLongArray(ItemStack stack, String tag, long n) { - long[] arr = NBTHelper.getLongArray(stack, tag); - if (arr == null) { - arr = new long[0]; - } - long[] newArr = Arrays.copyOf(arr, arr.length + 1); - newArr[newArr.length - 1] = n; - NBTHelper.putLongArray(stack, tag, newArr); + public static void addToLongArray(ItemStack stack, DataComponentType> type, long n) { + var list = stack.getOrDefault(type, new ArrayList()); + list.add(n); + stack.set(type, list); } @Override public long withdrawMedia(ItemStack stack, long cost, boolean simulate) { // In case it's withdrawn through other means if (!simulate && isDebug(stack, DISPLAY_MEDIA)) { - addToLongArray(stack, TAG_EXTRACTIONS, cost); + addToLongArray(stack, HexDataComponents.MEDIA_EXTRACTIONS, cost); } return cost < 0 ? getMedia(stack) : cost; @@ -158,7 +145,7 @@ public long withdrawMedia(ItemStack stack, long cost, boolean simulate) { public long insertMedia(ItemStack stack, long amount, boolean simulate) { // In case it's inserted through other means if (!simulate && isDebug(stack, DISPLAY_MEDIA)) { - addToLongArray(stack, TAG_INSERTIONS, amount); + addToLongArray(stack, HexDataComponents.MEDIA_INSERTIONS, amount); } return amount < 0 ? getMaxMedia(stack) : amount; @@ -172,16 +159,16 @@ public boolean isFoil(ItemStack stack) { @Override public void inventoryTick(ItemStack stack, Level level, Entity entity, int slot, boolean selected) { if (isDebug(stack, DISPLAY_MEDIA) && !level.isClientSide) { - debugDisplay(stack, TAG_EXTRACTIONS, "withdrawn", "all_media", entity); - debugDisplay(stack, TAG_INSERTIONS, "inserted", "infinite_media", entity); + debugDisplay(stack, HexDataComponents.MEDIA_EXTRACTIONS, "withdrawn", "all_media", entity); + debugDisplay(stack, HexDataComponents.MEDIA_INSERTIONS, "inserted", "infinite_media", entity); } } - private void debugDisplay(ItemStack stack, String tag, String langKey, String allKey, Entity entity) { - long[] arr = NBTHelper.getLongArray(stack, tag); - if (arr != null) { - NBTHelper.remove(stack, tag); - for (long i : arr) { + private void debugDisplay(ItemStack stack, DataComponentType> type, String langKey, String allKey, Entity entity) { + var list = stack.get(type); + if (list != null) { + stack.remove(type); + for (long i : list) { if (i < 0) { entity.sendSystemMessage(Component.translatable("hexcasting.debug.media_" + langKey, stack.getDisplayName(), @@ -217,19 +204,21 @@ public ItemStack finishUsingItem(ItemStack stack, Level level, LivingEntity cons var names = new ArrayList<>(ItemLoreFragment.NAMES); names.add(0, modLoc("root")); for (var name : names) { - var rootAdv = slevel.getServer().getAdvancements().getAdvancement(name); + var rootAdv = slevel.getServer().getAdvancements().tree().get(name); if (rootAdv != null) { - var children = new ArrayList(); + var children = new ArrayList(); children.add(rootAdv); - addChildren(rootAdv, children); + collectChildrenRecursively(rootAdv, children); var adman = player.getAdvancements(); + + for (var kid : children) { - var progress = adman.getOrStartProgress(kid); + var progress = adman.getOrStartProgress(kid.holder()); if (!progress.isDone()) { for (String crit : progress.getRemainingCriteria()) { - adman.award(kid, crit); + adman.award(kid.holder(), crit); } } } @@ -252,9 +241,9 @@ private static MutableComponent rainbow(MutableComponent component, int shift, L } @Override - public void appendHoverText(ItemStack stack, @Nullable Level level, List tooltipComponents, + public void appendHoverText(ItemStack stack, TooltipContext context, List tooltipComponents, TooltipFlag isAdvanced) { - Component emphasized = infiniteMedia(level); + Component emphasized = infiniteMedia(context.level()); MutableComponent modName = Component.translatable("item.hexcasting.creative_unlocker.mod_name").withStyle( (s) -> s.withColor(ItemMediaHolder.HEX_COLOR)); @@ -264,10 +253,10 @@ public void appendHoverText(ItemStack stack, @Nullable Level level, List out) { - for (Advancement kiddo : root.getChildren()) { + private static void collectChildrenRecursively(AdvancementNode root, List out) { + for (AdvancementNode kiddo : root.children()) { out.add(kiddo); - addChildren(kiddo, out); + collectChildrenRecursively(kiddo, out); } } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/items/magic/ItemMediaHolder.java b/Common/src/main/java/at/petrak/hexcasting/common/items/magic/ItemMediaHolder.java index 5bc736a2fa..8603d61e98 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/items/magic/ItemMediaHolder.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/items/magic/ItemMediaHolder.java @@ -5,6 +5,7 @@ import at.petrak.hexcasting.api.utils.MathUtils; import at.petrak.hexcasting.api.utils.MediaHelper; import at.petrak.hexcasting.api.utils.NBTHelper; +import at.petrak.hexcasting.common.lib.HexDataComponents; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.TextColor; import net.minecraft.util.Mth; @@ -39,8 +40,8 @@ public ItemMediaHolder(Properties pProperties) { public static ItemStack withMedia(ItemStack stack, long media, long maxMedia) { Item item = stack.getItem(); if (item instanceof ItemMediaHolder) { - NBTHelper.putLong(stack, TAG_MEDIA, media); - NBTHelper.putLong(stack, TAG_MAX_MEDIA, maxMedia); + stack.set(HexDataComponents.MEDIA, media); + stack.set(HexDataComponents.MEDIA_MAX, media); } return stack; @@ -48,23 +49,19 @@ public static ItemStack withMedia(ItemStack stack, long media, long maxMedia) { @Override public long getMedia(ItemStack stack) { - if (NBTHelper.hasInt(stack, TAG_MEDIA)) - return NBTHelper.getInt(stack, TAG_MEDIA); - - return NBTHelper.getLong(stack, TAG_MEDIA); + var media = stack.get(HexDataComponents.MEDIA); + return media != null ? media : 0L; } @Override public long getMaxMedia(ItemStack stack) { - if (NBTHelper.hasInt(stack, TAG_MAX_MEDIA)) - return NBTHelper.getInt(stack, TAG_MAX_MEDIA); - - return NBTHelper.getLong(stack, TAG_MAX_MEDIA); + var maxMedia = stack.get(HexDataComponents.MEDIA_MAX); + return maxMedia != null ? maxMedia : 0L; } @Override public void setMedia(ItemStack stack, long media) { - NBTHelper.putLong(stack, TAG_MEDIA, MathUtils.clamp(media, 0, getMaxMedia(stack))); + stack.set(HexDataComponents.MEDIA, MathUtils.clamp(media, 0, getMaxMedia(stack))); } @Override @@ -86,18 +83,18 @@ public int getBarWidth(ItemStack pStack) { return MediaHelper.mediaBarWidth(media, maxMedia); } - @Override + // TODO port: where did it came from? + /*@Override public boolean canBeDepleted() { return false; - } + }*/ @Override - public void appendHoverText(ItemStack pStack, @Nullable Level pLevel, List pTooltipComponents, - TooltipFlag pIsAdvanced) { - var maxMedia = getMaxMedia(pStack); + public void appendHoverText(ItemStack stack, TooltipContext context, List tooltipComponents, TooltipFlag tooltipFlag) { + var maxMedia = getMaxMedia(stack); if (maxMedia > 0) { - var media = getMedia(pStack); - var fullness = getMediaFullness(pStack); + var media = getMedia(stack); + var fullness = getMediaFullness(stack); var color = TextColor.fromRgb(MediaHelper.mediaBarColor(media, maxMedia)); @@ -109,11 +106,11 @@ public void appendHoverText(ItemStack pStack, @Nullable Level pLevel, List style.withColor(HEX_COLOR)); percentFull.withStyle(style -> style.withColor(color)); - pTooltipComponents.add( + tooltipComponents.add( Component.translatable("hexcasting.tooltip.media_amount.advanced", mediamount, maxCapacity, percentFull)); } - super.appendHoverText(pStack, pLevel, pTooltipComponents, pIsAdvanced); + super.appendHoverText(stack, context, tooltipComponents, tooltipFlag); } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/items/magic/ItemPackagedHex.java b/Common/src/main/java/at/petrak/hexcasting/common/items/magic/ItemPackagedHex.java index a189fd0703..5f976f86d8 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/items/magic/ItemPackagedHex.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/items/magic/ItemPackagedHex.java @@ -9,6 +9,7 @@ import at.petrak.hexcasting.api.item.HexHolderItem; import at.petrak.hexcasting.api.pigment.FrozenPigment; import at.petrak.hexcasting.api.utils.NBTHelper; +import at.petrak.hexcasting.common.lib.HexDataComponents; import at.petrak.hexcasting.common.msgs.MsgNewSpiralPatternsS2C; import at.petrak.hexcasting.xplat.IXplatAbstractions; import net.minecraft.nbt.CompoundTag; @@ -22,6 +23,7 @@ import net.minecraft.stats.Stats; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResultHolder; +import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.UseAnim; @@ -62,53 +64,34 @@ public boolean canProvideMedia(ItemStack stack) { @Override public boolean hasHex(ItemStack stack) { - return NBTHelper.hasList(stack, TAG_PROGRAM, Tag.TAG_COMPOUND); + return stack.has(HexDataComponents.PATTERNS); } @Override public @Nullable List getHex(ItemStack stack, ServerLevel level) { - var patsTag = NBTHelper.getList(stack, TAG_PROGRAM, Tag.TAG_COMPOUND); - - if (patsTag == null) { - return null; - } - - var out = new ArrayList(); - for (var patTag : patsTag) { - CompoundTag tag = NBTHelper.getAsCompound(patTag); - out.add(IotaType.deserialize(tag, level)); - } - return out; + return stack.get(HexDataComponents.PATTERNS); } @Override public void writeHex(ItemStack stack, List program, @Nullable FrozenPigment pigment, long media) { - ListTag patsTag = new ListTag(); - for (Iota pat : program) { - patsTag.add(IotaType.serialize(pat)); - } - - NBTHelper.putList(stack, TAG_PROGRAM, patsTag); + stack.set(HexDataComponents.PATTERNS, program); if (pigment != null) - NBTHelper.putCompound(stack, TAG_PIGMENT, pigment.serializeToNBT()); + stack.set(HexDataComponents.PIGMENT, pigment); withMedia(stack, media, media); } @Override public void clearHex(ItemStack stack) { - NBTHelper.remove(stack, TAG_PROGRAM); - NBTHelper.remove(stack, TAG_PIGMENT); - NBTHelper.remove(stack, TAG_MEDIA); - NBTHelper.remove(stack, TAG_MAX_MEDIA); + stack.remove(HexDataComponents.PATTERNS); + stack.remove(HexDataComponents.PIGMENT); + stack.remove(HexDataComponents.MEDIA); + stack.remove(HexDataComponents.MEDIA_MAX); } @Override public @Nullable FrozenPigment getPigment(ItemStack stack) { - var ctag = NBTHelper.getCompound(stack, TAG_PIGMENT); - if (ctag == null) - return null; - return FrozenPigment.fromNBT(ctag); + return stack.get(HexDataComponents.PIGMENT); } @Override @@ -128,8 +111,8 @@ public InteractionResultHolder use(Level world, Player player, Intera } var sPlayer = (ServerPlayer) player; var ctx = new PackagedItemCastEnv(sPlayer, usedHand); - var harness = CastingVM.empty(ctx); - var clientView = harness.queueExecuteAndWrapIotas(instrs, sPlayer.serverLevel()); + var vm = CastingVM.empty(ctx); + var clientView = vm.queueExecuteAndWrapIotas(instrs, sPlayer.serverLevel()); var patterns = instrs.stream() .filter(i -> i instanceof PatternIota) @@ -167,7 +150,7 @@ public InteractionResultHolder use(Level world, Player player, Intera if (broken) { stack.shrink(1); - player.broadcastBreakEvent(usedHand); + sPlayer.onEquippedItemBroken(stack.getItem(), usedHand == InteractionHand.MAIN_HAND ? EquipmentSlot.MAINHAND : EquipmentSlot.OFFHAND); return InteractionResultHolder.consume(stack); } else { return InteractionResultHolder.success(stack); diff --git a/Common/src/main/java/at/petrak/hexcasting/common/items/pigment/ItemUUIDPigment.java b/Common/src/main/java/at/petrak/hexcasting/common/items/pigment/ItemUUIDPigment.java index c895177f47..6ce75671e9 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/items/pigment/ItemUUIDPigment.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/items/pigment/ItemUUIDPigment.java @@ -4,6 +4,7 @@ import at.petrak.hexcasting.api.item.PigmentItem; import at.petrak.hexcasting.api.pigment.ColorProvider; import at.petrak.paucal.api.PaucalAPI; +import at.petrak.paucal.xplat.common.ContributorsManifest; import com.google.gson.JsonElement; import com.google.gson.JsonPrimitive; import net.minecraft.world.item.Item; @@ -28,7 +29,7 @@ protected static class MyColorProvider extends ColorProvider { private final int[] colors; MyColorProvider(UUID owner) { - var contributor = PaucalAPI.instance().getContributor(owner); + var contributor = ContributorsManifest.getContributor(owner); if (contributor != null) { var colorList = contributor.otherVals().getAsJsonArray("hexcasting:colorizer"); if (colorList != null) { diff --git a/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemAbacus.java b/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemAbacus.java index ad8527581f..76b3571686 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemAbacus.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemAbacus.java @@ -5,6 +5,7 @@ import at.petrak.hexcasting.api.casting.iota.IotaType; import at.petrak.hexcasting.api.item.IotaHolderItem; import at.petrak.hexcasting.api.utils.NBTHelper; +import at.petrak.hexcasting.common.lib.HexDataComponents; import at.petrak.hexcasting.common.lib.HexSounds; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; @@ -20,17 +21,14 @@ import java.util.List; public class ItemAbacus extends Item implements IotaHolderItem { - public static final String TAG_VALUE = "value"; public ItemAbacus(Properties pProperties) { super(pProperties); } @Override - public @Nullable - CompoundTag readIotaTag(ItemStack stack) { - var datum = new DoubleIota(NBTHelper.getDouble(stack, TAG_VALUE)); - return IotaType.serialize(datum); + public @Nullable Iota readIota(ItemStack stack) { + return new DoubleIota(stack.getOrDefault(HexDataComponents.ABACUS_VALUE, 0.0)); } @Override @@ -52,13 +50,13 @@ public void writeDatum(ItemStack stack, Iota datum) { public InteractionResultHolder use(Level world, Player player, InteractionHand hand) { var stack = player.getItemInHand(hand); if (player.isShiftKeyDown()) { - double oldNum = NBTHelper.getDouble(stack, TAG_VALUE); - stack.removeTagKey(TAG_VALUE); + Double oldNum = stack.get(HexDataComponents.ABACUS_VALUE); + stack.remove(HexDataComponents.ABACUS_VALUE); player.playSound(HexSounds.ABACUS_SHAKE, 1f, 1f); var key = "hexcasting.tooltip.abacus.reset"; - if (oldNum == 69) { + if (oldNum != null && oldNum == 69) { key += ".nice"; } player.displayClientMessage(Component.translatable(key), true); @@ -70,8 +68,7 @@ public InteractionResultHolder use(Level world, Player player, Intera } @Override - public void appendHoverText(ItemStack pStack, @Nullable Level pLevel, List pTooltipComponents, - TooltipFlag pIsAdvanced) { - IotaHolderItem.appendHoverText(this, pStack, pTooltipComponents, pIsAdvanced); + public void appendHoverText(ItemStack stack, TooltipContext context, List tooltipComponents, TooltipFlag tooltipFlag) { + IotaHolderItem.appendHoverText(this, stack, tooltipComponents, tooltipFlag); } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemFocus.java b/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemFocus.java index 8d08c9923f..e713477d43 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemFocus.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemFocus.java @@ -5,9 +5,11 @@ import at.petrak.hexcasting.api.item.IotaHolderItem; import at.petrak.hexcasting.api.item.VariantItem; import at.petrak.hexcasting.api.utils.NBTHelper; +import at.petrak.hexcasting.common.lib.HexDataComponents; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.Unit; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.TooltipFlag; @@ -26,21 +28,13 @@ public class ItemFocus extends Item implements IotaHolderItem, VariantItem { public static final ResourceLocation VARIANT_PRED = modLoc("variant"); public static final int NUM_VARIANTS = 8; - public static final String TAG_DATA = "data"; - public static final String TAG_SEALED = "sealed"; - public ItemFocus(Properties pProperties) { super(pProperties); } - @Override - public @Nullable CompoundTag readIotaTag(ItemStack stack) { - return NBTHelper.getCompound(stack, TAG_DATA); - } - @Override public String getDescriptionId(ItemStack stack) { - return super.getDescriptionId(stack) + (NBTHelper.getBoolean(stack, TAG_SEALED) ? ".sealed" : ""); + return super.getDescriptionId(stack) + (stack.has(HexDataComponents.SEALED) ? ".sealed" : ""); } @Override @@ -56,25 +50,24 @@ public boolean canWrite(ItemStack stack, Iota datum) { @Override public void writeDatum(ItemStack stack, Iota datum) { if (datum == null) { - stack.removeTagKey(TAG_DATA); - stack.removeTagKey(TAG_SEALED); + stack.remove(HexDataComponents.IOTA); + stack.remove(HexDataComponents.SEALED); } else if (!isSealed(stack)) { - NBTHelper.put(stack, TAG_DATA, IotaType.serialize(datum)); + stack.set(HexDataComponents.IOTA, datum); } } @Override - public void appendHoverText(ItemStack pStack, @Nullable Level pLevel, List pTooltipComponents, - TooltipFlag pIsAdvanced) { - IotaHolderItem.appendHoverText(this, pStack, pTooltipComponents, pIsAdvanced); + public void appendHoverText(ItemStack stack, TooltipContext context, List tooltipComponents, TooltipFlag tooltipFlag) { + IotaHolderItem.appendHoverText(this, stack, tooltipComponents, tooltipFlag); } public static boolean isSealed(ItemStack stack) { - return NBTHelper.getBoolean(stack, TAG_SEALED); + return stack.has(HexDataComponents.SEALED); } public static void seal(ItemStack stack) { - NBTHelper.putBoolean(stack, TAG_SEALED, true); + stack.set(HexDataComponents.SEALED, Unit.INSTANCE); } @Override @@ -85,6 +78,6 @@ public int numVariants() { @Override public void setVariant(ItemStack stack, int variant) { if (!isSealed(stack)) - NBTHelper.putInt(stack, TAG_VARIANT, clampVariant(variant)); + VariantItem.super.setVariant(stack, variant); } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemScroll.java b/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemScroll.java index 036e5129b4..b9d5ca6003 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemScroll.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemScroll.java @@ -1,5 +1,6 @@ package at.petrak.hexcasting.common.items.storage; +import at.petrak.hexcasting.api.casting.ActionRegistryEntry; import at.petrak.hexcasting.api.casting.iota.Iota; import at.petrak.hexcasting.api.casting.iota.PatternIota; import at.petrak.hexcasting.api.casting.math.HexPattern; @@ -7,40 +8,48 @@ import at.petrak.hexcasting.api.utils.NBTHelper; import at.petrak.hexcasting.client.gui.PatternTooltipComponent; import at.petrak.hexcasting.common.entities.EntityWallScroll; +import at.petrak.hexcasting.common.lib.HexDataComponents; import at.petrak.hexcasting.common.lib.hex.HexIotaTypes; import at.petrak.hexcasting.common.misc.PatternTooltip; +import at.petrak.hexcasting.common.casting.PatternRegistryManifest; import at.petrak.hexcasting.interop.inline.InlinePatternData; +import at.petrak.hexcasting.xplat.IXplatAbstractions; +import net.minecraft.ChatFormatting; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; +import net.minecraft.core.component.DataComponents; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.ResourceKey; import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.tooltip.TooltipComponent; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; import net.minecraft.world.item.context.UseOnContext; import net.minecraft.world.level.gameevent.GameEvent; +import net.minecraft.world.level.Level; import org.jetbrains.annotations.Nullable; import java.util.Optional; +import java.util.List; import static at.petrak.hexcasting.api.HexAPI.modLoc; /** - * TAG_OP_ID and TAG_PATTERN: "Ancient Scroll of %s" (Great Spells) + * TAG_OP_ID and TAG_PATTERN: "Ancient Scroll of %s" (per-world pattern preloaded) + *
+ * TAG_OP_ID: "Ancient Scroll of %s" (per-world pattern loaded on inv tick) *
* TAG_PATTERN: "Scroll" (custom) *
* (none): "Empty Scroll" - *
- * TAG_OP_ID: invalid */ public class ItemScroll extends Item implements IotaHolderItem { - public static final String TAG_OP_ID = "op_id"; - public static final String TAG_PATTERN = "pattern"; public static final ResourceLocation ANCIENT_PREDICATE = modLoc("ancient"); public final int blockSize; @@ -50,18 +59,14 @@ public ItemScroll(Properties pProperties, int blockSize) { this.blockSize = blockSize; } - @Override - public @Nullable - CompoundTag readIotaTag(ItemStack stack) { - CompoundTag pattern = NBTHelper.getCompound(stack, TAG_PATTERN); - if (pattern == null) { - return null; + // this produces a scroll that will load the correct pattern for your world once it ticks + public static ItemStack withPerWorldPattern(ItemStack stack, ResourceKey action) { + Item item = stack.getItem(); + if (item instanceof ItemScroll) { + stack.set(HexDataComponents.ACTION, action); } - // We store only the data part of the iota; pretend the rest of it's there - var out = new CompoundTag(); - out.putString(HexIotaTypes.KEY_TYPE, "hexcasting:pattern"); - out.put(HexIotaTypes.KEY_DATA, pattern); - return out; + + return stack; } @Override @@ -78,9 +83,9 @@ public boolean canWrite(ItemStack stack, Iota datum) { public void writeDatum(ItemStack stack, Iota datum) { if (this.canWrite(stack, datum)) { if (datum instanceof PatternIota pat) { - NBTHelper.putCompound(stack, TAG_PATTERN, pat.getPattern().serializeToNBT()); + stack.set(HexDataComponents.PATTERN, pat.getPattern()); } else if (datum == null) { - NBTHelper.remove(stack, TAG_PATTERN); + stack.remove(HexDataComponents.PATTERN); } } } @@ -101,9 +106,9 @@ public InteractionResult useOn(UseOnContext ctx) { var scrollEntity = new EntityWallScroll(level, posInFront, direction, scrollStack, false, this.blockSize); // i guess - var stackTag = itemstack.getTag(); - if (stackTag != null) { - EntityType.updateCustomEntityTag(level, player, scrollEntity, stackTag); + var customData = itemstack.get(DataComponents.CUSTOM_DATA); + if (customData != null) { + EntityType.updateCustomEntityTag(level, player, scrollEntity, customData); } if (scrollEntity.survives()) { @@ -128,15 +133,14 @@ protected boolean mayPlace(Player pPlayer, Direction pDirection, ItemStack pHang @Override public Component getName(ItemStack pStack) { var descID = this.getDescriptionId(pStack); - var ancientId = NBTHelper.getString(pStack, TAG_OP_ID); - if (ancientId != null) { + var ancientAction = pStack.get(HexDataComponents.ACTION); + if (ancientAction != null) { return Component.translatable(descID + ".of", - Component.translatable("hexcasting.action." + ResourceLocation.tryParse(ancientId))); - } else if (NBTHelper.hasCompound(pStack, TAG_PATTERN)) { - var compound = NBTHelper.getCompound(pStack, ItemScroll.TAG_PATTERN); + Component.translatable("hexcasting.action." + ancientAction.location())); + } else if (pStack.has(HexDataComponents.PATTERN)) { + var pattern = pStack.get(HexDataComponents.PATTERN); var patternLabel = Component.literal(""); - if (compound != null) { - var pattern = HexPattern.fromNBT(compound); + if (pattern != null) { patternLabel = Component.literal(": ").append(new InlinePatternData(pattern).asText(false)); } return Component.translatable(descID).append(patternLabel); @@ -145,16 +149,38 @@ public Component getName(ItemStack pStack) { } } - // purposely no hover text + @Override + public void inventoryTick(ItemStack pStack, Level pLevel, Entity pEntity, int pSlotId, boolean pIsSelected) { + // the needs_purchase tag is used so you can't see the pattern on scrolls sold by a wandering trader + // once you put the scroll into your inventory, this removes the tag to reveal the pattern + if(pStack.has(HexDataComponents.NEEDS_PURCHASE)) + pStack.remove(HexDataComponents.NEEDS_PURCHASE); + // if op_id is set but there's no stored pattern, attempt to load the pattern on inv tick + if (pStack.has(HexDataComponents.ACTION) && !pStack.has(HexDataComponents.PATTERN) && pEntity.getServer() != null) { + var action = pStack.get(HexDataComponents.ACTION); + var pat = PatternRegistryManifest.getCanonicalStrokesPerWorld(action, pEntity.getServer().overworld()); + pStack.set(HexDataComponents.PATTERN, pat); + } + } + + @Override + public void appendHoverText(ItemStack stack, TooltipContext context, List tooltipComponents, TooltipFlag tooltipFlag) { + if (stack.has(HexDataComponents.NEEDS_PURCHASE)) { + var needsPurchase = Component.translatable("hexcasting.tooltip.scroll.needs_purchase"); + tooltipComponents.add(needsPurchase.withStyle(ChatFormatting.GRAY)); + } else if (stack.has(HexDataComponents.ACTION) && !stack.has(HexDataComponents.PATTERN)) { + var notLoaded = Component.translatable("hexcasting.tooltip.scroll.pattern_not_loaded"); + tooltipComponents.add(notLoaded.withStyle(ChatFormatting.GRAY)); + } + } @Override public Optional getTooltipImage(ItemStack stack) { - var compound = NBTHelper.getCompound(stack, ItemScroll.TAG_PATTERN); - if (compound != null) { - var pattern = HexPattern.fromNBT(compound); + var pattern = stack.get(HexDataComponents.PATTERN); + if (pattern != null && !stack.has(HexDataComponents.NEEDS_PURCHASE)) { return Optional.of(new PatternTooltip( pattern, - NBTHelper.hasString(stack, ItemScroll.TAG_OP_ID) + stack.has(HexDataComponents.ACTION) ? PatternTooltipComponent.ANCIENT_BG : PatternTooltipComponent.PRISTINE_BG)); } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemSlate.java b/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemSlate.java index 98227d1eab..e01858f660 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemSlate.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemSlate.java @@ -12,7 +12,9 @@ import at.petrak.hexcasting.common.lib.hex.HexIotaTypes; import at.petrak.hexcasting.common.misc.PatternTooltip; import at.petrak.hexcasting.interop.inline.InlinePatternData; +import net.minecraft.core.component.DataComponents; import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtOps; import net.minecraft.nbt.Tag; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; @@ -21,6 +23,7 @@ import net.minecraft.world.inventory.tooltip.TooltipComponent; import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.component.CustomData; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; import org.jetbrains.annotations.Nullable; @@ -46,14 +49,11 @@ public Component getName(ItemStack pStack) { } public static Optional getPattern(ItemStack stack){ - var bet = NBTHelper.getCompound(stack, "BlockEntityTag"); + var bet = stack.get(DataComponents.BLOCK_ENTITY_DATA); - if (bet != null && bet.contains(BlockEntitySlate.TAG_PATTERN, Tag.TAG_COMPOUND)) { - var patTag = bet.getCompound(BlockEntitySlate.TAG_PATTERN); - if (!patTag.isEmpty()) { - var pattern = HexPattern.fromNBT(patTag); - return Optional.of(pattern); - } + if (bet != null && bet.contains(BlockEntitySlate.TAG_PATTERN)) { + var pattern = bet.read(HexPattern.CODEC.fieldOf(BlockEntitySlate.TAG_PATTERN)).result().orElse(null); + return Optional.ofNullable(pattern); } return Optional.empty(); } @@ -65,7 +65,7 @@ public static boolean hasPattern(ItemStack stack) { @SoftImplement("IForgeItem") public boolean onEntityItemUpdate(ItemStack stack, ItemEntity entity) { if (!hasPattern(stack)) { - NBTHelper.remove(stack, "BlockEntityTag"); + stack.remove(DataComponents.BLOCK_ENTITY_DATA); } return false; } @@ -73,27 +73,22 @@ public boolean onEntityItemUpdate(ItemStack stack, ItemEntity entity) { @Override public void inventoryTick(ItemStack pStack, Level pLevel, Entity pEntity, int pSlotId, boolean pIsSelected) { if (!hasPattern(pStack)) { - NBTHelper.remove(pStack, "BlockEntityTag"); + pStack.remove(DataComponents.BLOCK_ENTITY_DATA); } } @Override - public @Nullable - CompoundTag readIotaTag(ItemStack stack) { - var bet = NBTHelper.getCompound(stack, "BlockEntityTag"); + public @Nullable Iota readIota(ItemStack stack) { + var bet = stack.get(DataComponents.BLOCK_ENTITY_DATA);; - if (bet == null || !bet.contains(BlockEntitySlate.TAG_PATTERN, Tag.TAG_COMPOUND)) { + if (bet == null || !bet.contains(BlockEntitySlate.TAG_PATTERN)) { return null; } - var patTag = bet.getCompound(BlockEntitySlate.TAG_PATTERN); - if (patTag.isEmpty()) { - return null; - } - var out = new CompoundTag(); - out.putString(HexIotaTypes.KEY_TYPE, "hexcasting:pattern"); - out.put(HexIotaTypes.KEY_DATA, patTag); - return out; + return bet.read(HexPattern.CODEC.fieldOf(BlockEntitySlate.TAG_PATTERN)) + .result() + .map(PatternIota::new) + .orElse(null); } @Override @@ -110,14 +105,23 @@ public boolean canWrite(ItemStack stack, Iota datum) { public void writeDatum(ItemStack stack, Iota datum) { if (this.canWrite(stack, datum)) { if (datum == null) { - var beTag = NBTHelper.getOrCreateCompound(stack, "BlockEntityTag"); - beTag.remove(BlockEntitySlate.TAG_PATTERN); - if (beTag.isEmpty()) { - NBTHelper.remove(stack, "BlockEntityTag"); - } + var beData = stack.get(DataComponents.BLOCK_ENTITY_DATA); + beData.update(tag -> { + tag.remove(BlockEntitySlate.TAG_PATTERN); + }); + + if(beData.isEmpty()) + stack.remove(DataComponents.BLOCK_ENTITY_DATA); } else if (datum instanceof PatternIota pat) { - var beTag = NBTHelper.getOrCreateCompound(stack, "BlockEntityTag"); - beTag.put(BlockEntitySlate.TAG_PATTERN, pat.getPattern().serializeToNBT()); + stack.update(DataComponents.BLOCK_ENTITY_DATA, CustomData.of(new CompoundTag()), data -> { + data.update(tag -> + tag.put(BlockEntitySlate.TAG_PATTERN, HexPattern.CODEC + .encodeStart(NbtOps.INSTANCE, pat.getPattern()) + .getOrThrow() + ) + ); + return data; + }); } } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemSpellbook.java b/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemSpellbook.java index b7521f7619..600a9314c8 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemSpellbook.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemSpellbook.java @@ -5,7 +5,9 @@ import at.petrak.hexcasting.api.item.IotaHolderItem; import at.petrak.hexcasting.api.item.VariantItem; import at.petrak.hexcasting.api.utils.NBTHelper; +import at.petrak.hexcasting.common.lib.HexDataComponents; import net.minecraft.ChatFormatting; +import net.minecraft.core.component.DataComponents; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.Tag; import net.minecraft.network.chat.Component; @@ -17,28 +19,15 @@ import net.minecraft.world.level.Level; import org.jetbrains.annotations.Nullable; +import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.stream.Stream; import static at.petrak.hexcasting.common.items.storage.ItemFocus.NUM_VARIANTS; public class ItemSpellbook extends Item implements IotaHolderItem, VariantItem { - public static String TAG_SELECTED_PAGE = "page_idx"; - // this is a CompoundTag of string numerical keys to SpellData - // it is 1-indexed, so that 0/0 can be the special case of "it is empty" - public static String TAG_PAGES = "pages"; - - // this stores the names of pages, to be restored when you scroll - // it is 1-indexed, and the 0-case for TAG_PAGES will be treated as 1 - public static String TAG_PAGE_NAMES = "page_names"; - - // this stores the sealed status of each page, to be restored when you scroll - // it is 1-indexed, and the 0-case for TAG_PAGES will be treated as 1 - public static String TAG_SEALED = "sealed_pages"; - - // this stores which variant of the spellbook should be rendered - public static final String TAG_VARIANT = "variant"; - public static final int MAX_PAGES = 64; public ItemSpellbook(Properties properties) { @@ -46,12 +35,11 @@ public ItemSpellbook(Properties properties) { } @Override - public void appendHoverText(ItemStack stack, @Nullable Level level, List tooltip, - TooltipFlag isAdvanced) { + public void appendHoverText(ItemStack stack, TooltipContext context, List tooltip, TooltipFlag isAdvanced) { boolean sealed = isSealed(stack); boolean empty = false; - if (NBTHelper.hasNumber(stack, TAG_SELECTED_PAGE)) { - var pageIdx = NBTHelper.getInt(stack, TAG_SELECTED_PAGE); + if (stack.has(HexDataComponents.SELECTED_PAGE)) { + var pageIdx = stack.get(HexDataComponents.SELECTED_PAGE); int highest = highestPage(stack); if (highest != 0) { if (sealed) { @@ -74,7 +62,7 @@ public void appendHoverText(ItemStack stack, @Nullable Level level, List(savedNames); + mutNames.put(nameKey, customName); + stack.set(HexDataComponents.PAGE_NAMES, mutNames); + } + } else { + var mutNames = new HashMap(); + mutNames.put(nameKey, customName); + stack.set(HexDataComponents.PAGE_NAMES, mutNames); + } + } else if(savedNames != null) { + var mutNames = new HashMap<>(savedNames); + mutNames.remove(nameKey); + if(mutNames.isEmpty()) { + stack.remove(HexDataComponents.PAGE_NAMES); + } else { + stack.set(HexDataComponents.PAGE_NAMES, mutNames); + } } } public static boolean arePagesEmpty(ItemStack stack) { - CompoundTag tag = NBTHelper.getCompound(stack, TAG_PAGES); - return tag == null || tag.isEmpty(); + var pages = stack.get(HexDataComponents.PAGES); + return pages == null || pages.isEmpty(); } @Override - public @Nullable - CompoundTag readIotaTag(ItemStack stack) { + public @Nullable Iota readIota(ItemStack stack) { int idx = getPage(stack, 1); var key = String.valueOf(idx); - var tag = NBTHelper.getCompound(stack, TAG_PAGES); - if (tag != null && tag.contains(key, Tag.TAG_COMPOUND)) { - return tag.getCompound(key); + var pages = stack.get(HexDataComponents.PAGES); + if (pages != null && pages.containsKey(key)) { + return pages.get(key); } else { return null; } @@ -146,30 +152,61 @@ public void writeDatum(ItemStack stack, Iota datum) { int idx = getPage(stack, 1); var key = String.valueOf(idx); - CompoundTag pages = NBTHelper.getCompound(stack, TAG_PAGES); + + var pages = stack.get(HexDataComponents.PAGES); + if (pages != null) { + var pagesMut = new HashMap<>(pages); + if (datum == null) { - pages.remove(key); - NBTHelper.remove(NBTHelper.getCompound(stack, TAG_SEALED), key); + pagesMut.remove(key); + var seals = stack.get(HexDataComponents.PAGE_SEALS); + if(seals != null) { + var sealsMut = new HashMap<>(seals); + + sealsMut.remove(key); + + if(sealsMut.isEmpty()) { + stack.remove(HexDataComponents.PAGE_SEALS); + } else { + stack.set(HexDataComponents.PAGE_SEALS, sealsMut); + } + } } else { - pages.put(key, IotaType.serialize(datum)); + pagesMut.put(key, datum); } - if (pages.isEmpty()) { - NBTHelper.remove(stack, TAG_PAGES); + if (pagesMut.isEmpty()) { + stack.remove(HexDataComponents.PAGES); + } else { + stack.set(HexDataComponents.PAGES, pagesMut); } } else if (datum != null) { - NBTHelper.getOrCreateCompound(stack, TAG_PAGES).put(key, IotaType.serialize(datum)); + var map = new HashMap(); + map.put(key, datum); + stack.set(HexDataComponents.PAGES, map); } else { - NBTHelper.remove(NBTHelper.getCompound(stack, TAG_SEALED), key); + var seals = stack.get(HexDataComponents.PAGE_SEALS); + if(seals != null) { + var sealsMut = new HashMap<>(seals); + sealsMut.remove(key); + + if(sealsMut.isEmpty()) { + stack.remove(HexDataComponents.PAGE_SEALS); + } else { + stack.set(HexDataComponents.PAGE_SEALS, sealsMut); + } + } } } public static int getPage(ItemStack stack, int ifEmpty) { if (arePagesEmpty(stack)) { return ifEmpty; - } else if (NBTHelper.hasNumber(stack, TAG_SELECTED_PAGE)) { - int index = NBTHelper.getInt(stack, TAG_SELECTED_PAGE); + } else if (stack.has(HexDataComponents.SELECTED_PAGE)) { + var index = stack.get(HexDataComponents.SELECTED_PAGE); + if(index == null) + return 1; if (index == 0) { index = 1; } @@ -183,36 +220,41 @@ public static void setSealed(ItemStack stack, boolean sealed) { int index = getPage(stack, 1); String nameKey = String.valueOf(index); - CompoundTag names = NBTHelper.getOrCreateCompound(stack, TAG_SEALED); + + var seals = stack.get(HexDataComponents.PAGE_SEALS); + + var sealsMut = seals != null ? new HashMap<>(seals) : new HashMap(); if (!sealed) { - names.remove(nameKey); + sealsMut.remove(nameKey); } else { - names.putBoolean(nameKey, true); + sealsMut.put(nameKey, true); } - if (names.isEmpty()) { - NBTHelper.remove(stack, TAG_SEALED); + if (sealsMut.isEmpty()) { + stack.remove(HexDataComponents.PAGE_SEALS); } else { - NBTHelper.putCompound(stack, TAG_SEALED, names); + stack.set(HexDataComponents.PAGE_SEALS, sealsMut); } - } public static boolean isSealed(ItemStack stack) { int index = getPage(stack, 1); String nameKey = String.valueOf(index); - CompoundTag names = NBTHelper.getCompound(stack, TAG_SEALED); - return NBTHelper.getBoolean(names, nameKey); + var seals = stack.get(HexDataComponents.PAGE_SEALS); + if(seals == null) + return false; + var v = seals.get(nameKey); + return v != null && v; } public static int highestPage(ItemStack stack) { - CompoundTag tag = NBTHelper.getCompound(stack, TAG_PAGES); - if (tag == null) { + var pages = stack.get(HexDataComponents.PAGES); + if (pages == null) { return 0; } - return tag.getAllKeys().stream().flatMap(s -> { + return pages.keySet().stream().flatMap(s -> { try { return Stream.of(Integer.parseInt(s)); } catch (NumberFormatException e) { @@ -228,16 +270,16 @@ public static int rotatePageIdx(ItemStack stack, boolean increase) { idx = Math.max(1, idx); } idx = Mth.clamp(idx, 0, MAX_PAGES); - NBTHelper.putInt(stack, TAG_SELECTED_PAGE, idx); + stack.set(HexDataComponents.SELECTED_PAGE, idx); - CompoundTag names = NBTHelper.getCompound(stack, TAG_PAGE_NAMES); + var names = stack.getOrDefault(HexDataComponents.PAGE_NAMES, Collections.emptyMap()); int shiftedIdx = Math.max(1, idx); String nameKey = String.valueOf(shiftedIdx); - String name = NBTHelper.getString(names, nameKey); + Component name = names.get(nameKey); if (name != null) { - stack.setHoverName(Component.Serializer.fromJson(name)); + stack.set(DataComponents.CUSTOM_NAME, name); } else { - stack.resetHoverName(); + stack.remove(DataComponents.CUSTOM_NAME); } return idx; @@ -251,6 +293,6 @@ public int numVariants() { @Override public void setVariant(ItemStack stack, int variant) { if (!isSealed(stack)) - NBTHelper.putInt(stack, TAG_VARIANT, clampVariant(variant)); + stack.set(HexDataComponents.VARIANT, clampVariant(variant)); } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemThoughtKnot.java b/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemThoughtKnot.java index 9e867cc250..2cc1ec3033 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemThoughtKnot.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/items/storage/ItemThoughtKnot.java @@ -4,6 +4,7 @@ import at.petrak.hexcasting.api.casting.iota.IotaType; import at.petrak.hexcasting.api.item.IotaHolderItem; import at.petrak.hexcasting.api.utils.NBTHelper; +import at.petrak.hexcasting.common.lib.HexDataComponents; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; @@ -21,20 +22,13 @@ public class ItemThoughtKnot extends Item implements IotaHolderItem { public static final ResourceLocation WRITTEN_PRED = modLoc("written"); - public static final String TAG_DATA = "data"; - public ItemThoughtKnot(Properties properties) { super(properties); } - @Override - public @Nullable CompoundTag readIotaTag(ItemStack stack) { - return NBTHelper.getCompound(stack, TAG_DATA); - } - @Override public boolean writeable(ItemStack stack) { - return !NBTHelper.contains(stack, TAG_DATA); + return !stack.has(HexDataComponents.IOTA); } @Override @@ -45,12 +39,12 @@ public boolean canWrite(ItemStack stack, @Nullable Iota iota) { @Override public void writeDatum(ItemStack stack, @Nullable Iota iota) { if (iota != null) { - NBTHelper.putCompound(stack, TAG_DATA, IotaType.serialize(iota)); + stack.set(HexDataComponents.IOTA, iota); } } @Override - public void appendHoverText(ItemStack pStack, @Nullable Level pLevel, + public void appendHoverText(ItemStack pStack, TooltipContext context, List pTooltipComponents, TooltipFlag pIsAdvanced) { IotaHolderItem.appendHoverText(this, pStack, pTooltipComponents, pIsAdvanced); } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/lib/HexAttributes.java b/Common/src/main/java/at/petrak/hexcasting/common/lib/HexAttributes.java index 844ff55883..707ec6544c 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/lib/HexAttributes.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/lib/HexAttributes.java @@ -1,45 +1,43 @@ package at.petrak.hexcasting.common.lib; -import at.petrak.hexcasting.api.HexAPI; -import net.minecraft.resources.ResourceLocation; +import at.petrak.hexcasting.api.casting.eval.env.PlayerBasedCastEnv; +import at.petrak.hexcasting.xplat.IXplatAbstractions; +import at.petrak.hexcasting.xplat.IXplatRegister; +import net.minecraft.core.Holder; +import net.minecraft.core.registries.Registries; import net.minecraft.world.entity.ai.attributes.Attribute; import net.minecraft.world.entity.ai.attributes.RangedAttribute; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.function.BiConsumer; +import static at.petrak.hexcasting.api.HexAPI.MOD_ID; -import static at.petrak.hexcasting.api.HexAPI.modLoc; - -/** - * On forge: these are setup in ForgeHexInit - * On fabric: it's a mixin - *

- * TODO how to do this in 1.21 - */ public class HexAttributes { - public static void register(BiConsumer r) { - for (var e : ATTRIBUTES.entrySet()) { - r.accept(e.getValue(), e.getKey()); - } - } + private static final IXplatRegister REGISTER = IXplatAbstractions.INSTANCE + .createRegistar(Registries.ATTRIBUTE); - private static final Map ATTRIBUTES = new LinkedHashMap<>(); + public static void register() { + REGISTER.registerAll(); + } - public static final Attribute GRID_ZOOM = make("grid_zoom", new RangedAttribute( - HexAPI.MOD_ID + ".attributes.grid_zoom", 1.0, 0.5, 4.0)).setSyncable(true); + public static final Holder GRID_ZOOM = REGISTER.registerHolder("grid_zoom", () -> new RangedAttribute( + MOD_ID + ".attributes.grid_zoom", 1.0, 0.5, 4.0).setSyncable(true)); /** * Whether you have the lens overlay when looking at something. 0 = no, > 0 = yes. */ - public static final Attribute SCRY_SIGHT = make("scry_sight", new RangedAttribute( - HexAPI.MOD_ID + ".attributes.scry_sight", 0.0, 0.0, 1.0)).setSyncable(true); - - private static T make(String id, T attr) { - var old = ATTRIBUTES.put(modLoc(id), attr); - if (old != null) { - throw new IllegalArgumentException("Typo? Duplicate id " + id); - } - return attr; - } + public static final Holder SCRY_SIGHT = REGISTER.registerHolder("scry_sight", () -> new RangedAttribute( + MOD_ID + ".attributes.scry_sight", 0.0, 0.0, 1.0).setSyncable(true)); + + //whether the player is allowed to use staffcasting and scrying lenses + public static final Holder FEEBLE_MIND = REGISTER.registerHolder("feeble_mind", () -> new RangedAttribute( + MOD_ID + ".attributes.feeble_mind", 0.0, 0.0, 1.0).setSyncable(true)); + + //a multiplier to adjust media consumption across the board + public static final Holder MEDIA_CONSUMPTION_MODIFIER = REGISTER.registerHolder("media_consumption", () -> new RangedAttribute( + MOD_ID + ".attributes.media_consumption", 1.0, 0.0, Double.MAX_VALUE).setSyncable(true)); + + public static final Holder AMBIT_RADIUS = REGISTER.registerHolder("ambit_radius", () -> new RangedAttribute( + MOD_ID + ".attributes.ambit_radius", PlayerBasedCastEnv.DEFAULT_AMBIT_RADIUS, 0.0, Double.MAX_VALUE).setSyncable(true)); + + public static final Holder SENTINEL_RADIUS = REGISTER.registerHolder("sentinel_radius", () -> new RangedAttribute( + MOD_ID + ".attributes.sentinel_radius", PlayerBasedCastEnv.DEFAULT_SENTINEL_RADIUS, 0.0, Double.MAX_VALUE).setSyncable(true)); } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/lib/HexBlockEntities.java b/Common/src/main/java/at/petrak/hexcasting/common/lib/HexBlockEntities.java index 6e22920668..e29584155a 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/lib/HexBlockEntities.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/lib/HexBlockEntities.java @@ -80,7 +80,7 @@ public static BlockEntityType typeForQuenchedAllay(Blo private static BlockEntityType register(String id, BiFunction func, Block... blocks) { var ret = IXplatAbstractions.INSTANCE.createBlockEntityType(func, blocks); - var old = BLOCK_ENTITIES.put(new ResourceLocation(HexAPI.MOD_ID, id), ret); + var old = BLOCK_ENTITIES.put(ResourceLocation.fromNamespaceAndPath(HexAPI.MOD_ID, id), ret); if (old != null) { throw new IllegalArgumentException("Duplicate id " + id); } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/lib/HexBlocks.java b/Common/src/main/java/at/petrak/hexcasting/common/lib/HexBlocks.java index 97e58a75e4..86ae60c3fe 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/lib/HexBlocks.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/lib/HexBlocks.java @@ -19,6 +19,7 @@ import at.petrak.hexcasting.common.blocks.decoration.*; import com.mojang.datafixers.util.Pair; import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.ColorRGBA; import net.minecraft.world.entity.EntityType; import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.CreativeModeTab; @@ -65,7 +66,7 @@ public static void registerBlockCreativeTab(Consumer r, CreativeModeTab t private static BlockBehaviour.Properties slateish() { return BlockBehaviour.Properties - .copy(Blocks.DEEPSLATE_TILES) + .ofFullCopy(Blocks.DEEPSLATE_TILES) .strength(4f, 4f); } @@ -85,7 +86,7 @@ private static BlockBehaviour.Properties akashicWoodyHard() { private static BlockBehaviour.Properties woodyHard(MapColor color) { return BlockBehaviour.Properties - .copy(Blocks.OAK_LOG) + .ofFullCopy(Blocks.OAK_LOG) .mapColor(color) .sound(SoundType.WOOD) .strength(3f, 4f); @@ -97,7 +98,7 @@ private static BlockBehaviour.Properties edifiedWoody() { private static BlockBehaviour.Properties woody(MapColor color) { return BlockBehaviour.Properties - .copy(Blocks.OAK_LOG) + .ofFullCopy(Blocks.OAK_LOG) .mapColor(color) .sound(SoundType.WOOD) .strength(2f); @@ -105,7 +106,7 @@ private static BlockBehaviour.Properties woody(MapColor color) { private static BlockBehaviour.Properties leaves(MapColor color) { return BlockBehaviour.Properties - .copy(Blocks.OAK_LEAVES) + .ofFullCopy(Blocks.OAK_LEAVES) .strength(0.2F) .randomTicks() .sound(SoundType.GRASS) @@ -118,7 +119,7 @@ private static BlockBehaviour.Properties leaves(MapColor color) { // we have to make it emit light because otherwise it occludes itself and is always dark private static BlockBehaviour.Properties quenched() { return BlockBehaviour.Properties - .copy(Blocks.AMETHYST_BLOCK) + .ofFullCopy(Blocks.AMETHYST_BLOCK) .lightLevel($ -> 4) .noOcclusion(); } @@ -203,17 +204,17 @@ private static BlockBehaviour.Properties quenched() { public static final Block SLATE_BRICKS = blockItem("slate_bricks", new Block(slateish().strength(2f, 4f))); public static final Block SLATE_BRICKS_SMALL = blockItem("slate_bricks_small", new Block(slateish().strength(2f, 4f))); public static final RotatedPillarBlock SLATE_PILLAR = blockItem("slate_pillar", new RotatedPillarBlock(slateish().strength(2f, 4f))); - public static final SandBlock AMETHYST_DUST_BLOCK = blockItem("amethyst_dust_block", - new SandBlock(0xff_b38ef3, BlockBehaviour.Properties.copy(Blocks.SAND).mapColor(MapColor.COLOR_PURPLE) + public static final ColoredFallingBlock AMETHYST_DUST_BLOCK = blockItem("amethyst_dust_block", + new ColoredFallingBlock(new ColorRGBA(0xb38ef3_ff), BlockBehaviour.Properties.ofFullCopy(Blocks.SAND).mapColor(MapColor.COLOR_PURPLE) .strength(0.5f).sound(SoundType.SAND))); public static final AmethystBlock AMETHYST_TILES = blockItem("amethyst_tiles", - new AmethystBlock(BlockBehaviour.Properties.copy(Blocks.AMETHYST_BLOCK))); + new AmethystBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.AMETHYST_BLOCK))); public static final AmethystBlock AMETHYST_BRICKS = blockItem("amethyst_bricks", - new AmethystBlock(BlockBehaviour.Properties.copy(Blocks.AMETHYST_BLOCK))); + new AmethystBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.AMETHYST_BLOCK))); public static final AmethystBlock AMETHYST_BRICKS_SMALL = blockItem("amethyst_bricks_small", - new AmethystBlock(BlockBehaviour.Properties.copy(Blocks.AMETHYST_BLOCK))); + new AmethystBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.AMETHYST_BLOCK))); public static final BlockAmethystDirectional AMETHYST_PILLAR = blockItem("amethyst_pillar", - new BlockAmethystDirectional(BlockBehaviour.Properties.copy(Blocks.AMETHYST_BLOCK))); + new BlockAmethystDirectional(BlockBehaviour.Properties.ofFullCopy(Blocks.AMETHYST_BLOCK))); public static final Block SLATE_AMETHYST_TILES = blockItem("slate_amethyst_tiles", new Block(slateish().strength(2f, 4f))); public static final Block SLATE_AMETHYST_BRICKS = blockItem("slate_amethyst_bricks", new Block(slateish().strength(2f, 4f))); public static final Block SLATE_AMETHYST_BRICKS_SMALL = blockItem("slate_amethyst_bricks_small", new Block(slateish().strength(2f, 4f))); @@ -275,8 +276,7 @@ private static BlockBehaviour.Properties quenched() { public static final ButtonBlock EDIFIED_BUTTON = blockItem("edified_button", new BlockHexWoodButton(edifiedWoody().noOcclusion().noCollission())); public static final PressurePlateBlock EDIFIED_PRESSURE_PLATE = blockItem("edified_pressure_plate", - new BlockHexPressurePlate(PressurePlateBlock.Sensitivity.EVERYTHING, - edifiedWoody().noOcclusion().noCollission())); + new BlockHexPressurePlate(edifiedWoody().noOcclusion().noCollission())); public static final BlockAkashicLeaves AMETHYST_EDIFIED_LEAVES = blockItem("amethyst_edified_leaves", new BlockAkashicLeaves(leaves(MapColor.COLOR_PURPLE))); public static final BlockAkashicLeaves AVENTURINE_EDIFIED_LEAVES = blockItem("aventurine_edified_leaves", diff --git a/Common/src/main/java/at/petrak/hexcasting/common/lib/HexConfiguredFeatures.java b/Common/src/main/java/at/petrak/hexcasting/common/lib/HexConfiguredFeatures.java index 05f06de4e8..391b9cac1b 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/lib/HexConfiguredFeatures.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/lib/HexConfiguredFeatures.java @@ -12,6 +12,6 @@ public class HexConfiguredFeatures { public static final ResourceKey> CITRINE_EDIFIED_TREE = createKey("citrine_edified_tree"); private static ResourceKey> createKey(String name) { - return ResourceKey.create(Registries.CONFIGURED_FEATURE, new ResourceLocation(HexAPI.MOD_ID, name)); + return ResourceKey.create(Registries.CONFIGURED_FEATURE, ResourceLocation.fromNamespaceAndPath(HexAPI.MOD_ID, name)); } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/lib/HexCreativeTabs.java b/Common/src/main/java/at/petrak/hexcasting/common/lib/HexCreativeTabs.java index 93cfd63011..58a521e32d 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/lib/HexCreativeTabs.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/lib/HexCreativeTabs.java @@ -4,6 +4,7 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.CreativeModeTab; import net.minecraft.world.item.ItemStack; +import at.petrak.hexcasting.common.items.storage.ItemScroll; import java.util.LinkedHashMap; import java.util.Map; @@ -20,11 +21,14 @@ public static void registerCreativeTabs(BiConsumer TABS = new LinkedHashMap<>(); - public static final CreativeModeTab HEX = register("hexcasting", CreativeModeTab.builder(CreativeModeTab.Row.TOP, 7) + public static final CreativeModeTab HEX = register("hexcasting", CreativeModeTab.builder() .icon(() -> new ItemStack(HexItems.SPELLBOOK))); + public static final CreativeModeTab SCROLLS = register("scrolls", CreativeModeTab.builder() + .icon(() -> new ItemStack(HexItems.SCROLL_LARGE))); + private static CreativeModeTab register(String name, CreativeModeTab.Builder tabBuilder) { - var tab = tabBuilder.title(Component.translatable("itemGroup." + name)).build(); + var tab = tabBuilder.title(Component.translatable("itemGroup.hexcasting." + name)).build(); var old = TABS.put(modLoc(name), tab); if (old != null) { throw new IllegalArgumentException("Typo? Duplicate id " + name); diff --git a/Common/src/main/java/at/petrak/hexcasting/common/lib/HexDamageTypes.java b/Common/src/main/java/at/petrak/hexcasting/common/lib/HexDamageTypes.java index 6eb7c8f1fa..6bd0f900fc 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/lib/HexDamageTypes.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/lib/HexDamageTypes.java @@ -9,8 +9,7 @@ import static at.petrak.hexcasting.api.HexAPI.modLoc; public class HexDamageTypes { - public static final ResourceKey OVERCAST = ResourceKey.create(Registries.DAMAGE_TYPE, modLoc( - "overcast")); + public static final ResourceKey OVERCAST = ResourceKey.create(Registries.DAMAGE_TYPE, modLoc("overcast")); public static void bootstrap(BootstrapContext ctx) { ctx.register(OVERCAST, new DamageType( diff --git a/Common/src/main/java/at/petrak/hexcasting/common/lib/HexDataComponents.java b/Common/src/main/java/at/petrak/hexcasting/common/lib/HexDataComponents.java new file mode 100644 index 0000000000..9c81dff7c9 --- /dev/null +++ b/Common/src/main/java/at/petrak/hexcasting/common/lib/HexDataComponents.java @@ -0,0 +1,165 @@ +package at.petrak.hexcasting.common.lib; + +import at.petrak.hexcasting.api.casting.ActionRegistryEntry; +import at.petrak.hexcasting.api.casting.iota.Iota; +import at.petrak.hexcasting.api.casting.iota.IotaType; +import at.petrak.hexcasting.api.casting.math.HexPattern; +import at.petrak.hexcasting.api.pigment.FrozenPigment; +import com.mojang.serialization.Codec; +import net.minecraft.core.component.DataComponentType; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.ComponentSerialization; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.Unit; + +import java.util.*; +import java.util.function.BiConsumer; + +import static at.petrak.hexcasting.api.HexAPI.modLoc; + +public class HexDataComponents { + public static void registerDataComponents(BiConsumer, ResourceLocation> r) { + for (var e : DATA_COMPONENTS.entrySet()) { + r.accept(e.getValue(), e.getKey()); + } + } + + private static final Map> DATA_COMPONENTS = new LinkedHashMap<>(); + + public static final DataComponentType PATTERN = register("pattern", + DataComponentType.builder() + .persistent(HexPattern.CODEC) + .networkSynchronized(HexPattern.STREAM_CODEC) + .build()); + public static final DataComponentType> ACTION = register("op_id", + DataComponentType.>builder() + .persistent(ResourceKey.codec(HexRegistries.ACTION)) + .networkSynchronized(ResourceKey.streamCodec(HexRegistries.ACTION)) + .build()); + public static final DataComponentType NEEDS_PURCHASE = register("needs_purchase", + DataComponentType.builder() + .networkSynchronized(StreamCodec.unit(Unit.INSTANCE)) + .build()); + /** + * If this datacomponent is set on the item, we ignore the rest of the item and render this as if it were of the + * {@link at.petrak.hexcasting.api.casting.iota.IotaType IotaType} given by the resource location. + *

+ * This is not useful to the player at all. + */ + public static final DataComponentType>> VISUAL_OVERRIDE = register("visual_override", + DataComponentType.>>builder() + .networkSynchronized(ByteBufCodecs.optional(ByteBufCodecs.registry(HexRegistries.IOTA_TYPE))) + .build()); + public static final DataComponentType VARIANT = register("variant", + DataComponentType.builder() + .persistent(Codec.intRange(0, Integer.MAX_VALUE)) + .networkSynchronized(ByteBufCodecs.VAR_INT) + .build()); + public static final DataComponentType SEALED = register("sealed", + DataComponentType.builder() + .persistent(Codec.unit(Unit.INSTANCE)) + .networkSynchronized(StreamCodec.unit(Unit.INSTANCE)) + .build()); + // TODO port: Data components must implement equals and hashCode. Keep in mind they must also be immutable + public static final DataComponentType IOTA = register("iota", + DataComponentType.builder() + .persistent(IotaType.TYPED_CODEC) + .networkSynchronized(IotaType.TYPED_STREAM_CODEC) + .build()); + + public static final DataComponentType> PATTERNS = register("patterns", + DataComponentType.>builder() + .persistent(IotaType.TYPED_CODEC.listOf()) + .networkSynchronized(IotaType.TYPED_STREAM_CODEC.apply(ByteBufCodecs.list())) + .build()); + public static final DataComponentType MEDIA = register("media", + DataComponentType.builder() + .persistent(Codec.LONG) + .networkSynchronized(ByteBufCodecs.VAR_LONG) + .build()); + public static final DataComponentType MEDIA_MAX = register("start_media", + DataComponentType.builder() + .persistent(Codec.LONG) + .networkSynchronized(ByteBufCodecs.VAR_LONG) + .build()); + public static final DataComponentType HEX_NAME = register("hex_name", + DataComponentType.builder() + .persistent(Codec.STRING) + .networkSynchronized(ByteBufCodecs.STRING_UTF8) + .build()); + + public static final DataComponentType PIGMENT = register("pigment", + DataComponentType.builder() + .persistent(FrozenPigment.CODEC) + .networkSynchronized(FrozenPigment.STREAM_CODEC) + .build()); + + public static final DataComponentType ABACUS_VALUE = register("abacus_value", + DataComponentType.builder() + .persistent(Codec.DOUBLE) + .networkSynchronized(ByteBufCodecs.DOUBLE) + .build()); + + public static final DataComponentType SELECTED_PAGE = register("page_idx", + DataComponentType.builder() + .persistent(Codec.INT) + .networkSynchronized(ByteBufCodecs.INT) + .build()); + + public static final DataComponentType> PAGES = register("pages", + DataComponentType.>builder() + .persistent(Codec.unboundedMap(Codec.STRING, IotaType.TYPED_CODEC)) + .networkSynchronized(ByteBufCodecs.map( + HashMap::newHashMap, + ByteBufCodecs.STRING_UTF8, + IotaType.TYPED_STREAM_CODEC + )) + .build()); + + public static final DataComponentType> PAGE_NAMES = register("page_names", + DataComponentType.>builder() + .persistent(Codec.unboundedMap(Codec.STRING, ComponentSerialization.CODEC)) + .networkSynchronized(ByteBufCodecs.map( + HashMap::newHashMap, + ByteBufCodecs.STRING_UTF8, + ComponentSerialization.STREAM_CODEC + )) + .build()); + + public static final DataComponentType> PAGE_SEALS = register("sealed_pages", + DataComponentType.>builder() + .persistent(Codec.unboundedMap(Codec.STRING, Codec.BOOL)) + .networkSynchronized(ByteBufCodecs.map( + HashMap::newHashMap, + ByteBufCodecs.STRING_UTF8, + ByteBufCodecs.BOOL + )) + .build()); + + public static final DataComponentType> MEDIA_EXTRACTIONS = register("media_extractions", + DataComponentType.>builder() + .persistent(Codec.LONG.listOf()) + .networkSynchronized(ByteBufCodecs.VAR_LONG.apply(ByteBufCodecs.list())) + .build()); + + public static final DataComponentType> MEDIA_INSERTIONS = register("media_insertions", + DataComponentType.>builder() + .persistent(Codec.LONG.listOf()) + .networkSynchronized(ByteBufCodecs.VAR_LONG.apply(ByteBufCodecs.list())) + .build()); + + + private static DataComponentType register( + String id, + DataComponentType lift + ) { + var old = DATA_COMPONENTS.put(modLoc(id), lift); + if (old != null) { + throw new IllegalArgumentException("Typo? Duplicate id " + id); + } + return lift; + } +} diff --git a/Common/src/main/java/at/petrak/hexcasting/common/lib/HexItems.java b/Common/src/main/java/at/petrak/hexcasting/common/lib/HexItems.java index a85889e104..86922ba750 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/lib/HexItems.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/lib/HexItems.java @@ -1,6 +1,9 @@ package at.petrak.hexcasting.common.lib; import at.petrak.hexcasting.api.misc.MediaConstants; +import at.petrak.hexcasting.api.utils.HexUtils; +import at.petrak.hexcasting.api.casting.ActionRegistryEntry; +import at.petrak.hexcasting.api.mod.HexTags; import at.petrak.hexcasting.common.items.ItemJewelerHammer; import at.petrak.hexcasting.common.items.ItemLens; import at.petrak.hexcasting.common.items.ItemLoreFragment; @@ -14,10 +17,16 @@ import at.petrak.hexcasting.xplat.IXplatAbstractions; import com.google.common.base.Suppliers; import net.minecraft.Util; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.EquipmentSlotGroup; +import net.minecraft.world.entity.ai.attributes.AttributeModifier; +import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.food.FoodProperties; import net.minecraft.world.item.*; +import net.minecraft.world.item.component.ItemAttributeModifiers; import org.jetbrains.annotations.Nullable; import java.util.*; @@ -35,7 +44,9 @@ public static void registerItems(BiConsumer r) { } public static void registerItemCreativeTab(CreativeModeTab.Output r, CreativeModeTab tab) { - for (var item : ITEM_TABS.getOrDefault(tab, List.of())) { + if (tab == HexCreativeTabs.SCROLLS) + generateScrollEntries(r); + for (var item : ITEM_TABS.getOrDefault(tab, Collections.emptyList())) { item.register(r); } } @@ -66,20 +77,33 @@ public static void registerItemCreativeTab(CreativeModeTab.Output r, CreativeMod public static final ItemStaff STAFF_MINDSPLICE = make("staff/mindsplice", new ItemStaff(unstackable())); public static final ItemLens SCRYING_LENS = make("lens", new ItemLens( - IXplatAbstractions.INSTANCE.addEquipSlotFabric(EquipmentSlot.HEAD) - .stacksTo(1))); + IXplatAbstractions.INSTANCE.addEquipSlotFabric(EquipmentSlot.HEAD) + .stacksTo(1))); public static final ItemAbacus ABACUS = make("abacus", new ItemAbacus(unstackable())); public static final ItemThoughtKnot THOUGHT_KNOT = make("thought_knot", new ItemThoughtKnot(unstackable())); public static final ItemFocus FOCUS = make("focus", new ItemFocus(unstackable())); public static final ItemSpellbook SPELLBOOK = make("spellbook", new ItemSpellbook(unstackable())); + public static final ItemCypher ANCIENT_CYPHER = make("ancient_cypher", new ItemAncientCypher(unstackable())); public static final ItemCypher CYPHER = make("cypher", new ItemCypher(unstackable())); public static final ItemTrinket TRINKET = make("trinket", new ItemTrinket(unstackable().rarity(Rarity.UNCOMMON))); public static final ItemArtifact ARTIFACT = make("artifact", new ItemArtifact(unstackable().rarity(Rarity.RARE))); public static final ItemJewelerHammer JEWELER_HAMMER = make("jeweler_hammer", - new ItemJewelerHammer(Tiers.IRON, 0, -2.8F, props().stacksTo(1).defaultDurability(Tiers.DIAMOND.getUses()))); + new ItemJewelerHammer(Tiers.IRON, props() + .stacksTo(1) + .durability(Tiers.DIAMOND.getUses()) + .attributes(ItemAttributeModifiers.builder() + .add(Attributes.ATTACK_SPEED, new AttributeModifier( + modLoc("jeweler_hammer_speed"), + -2.8, + AttributeModifier.Operation.ADD_VALUE + ), EquipmentSlotGroup.ANY) + .build() + ) + ) + ); public static final ItemScroll SCROLL_SMOL = make("scroll_small", new ItemScroll(props(), 1)); public static final ItemScroll SCROLL_MEDIUM = make("scroll_medium", new ItemScroll(props(), 2)); @@ -88,7 +112,7 @@ public static void registerItemCreativeTab(CreativeModeTab.Output r, CreativeMod public static final ItemSlate SLATE = make("slate", new ItemSlate(HexBlocks.SLATE, props())); public static final ItemMediaBattery BATTERY = make("battery", - new ItemMediaBattery(unstackable()), null); + new ItemMediaBattery(unstackable()), null); public static final Supplier BATTERY_DUST_STACK = addToTab(() -> ItemMediaBattery.withMedia( new ItemStack(HexItems.BATTERY), @@ -106,7 +130,6 @@ public static void registerItemCreativeTab(CreativeModeTab.Output r, CreativeMod new ItemStack(HexItems.BATTERY), MediaConstants.QUENCHED_SHARD_UNIT * 64, MediaConstants.QUENCHED_SHARD_UNIT * 64), HexCreativeTabs.HEX); - public static final Supplier BATTERY_QUENCHED_BLOCK_STACK = addToTab(() -> ItemMediaBattery.withMedia( new ItemStack(HexItems.BATTERY), MediaConstants.QUENCHED_BLOCK_UNIT * 64, @@ -123,27 +146,27 @@ public static void registerItemCreativeTab(CreativeModeTab.Output r, CreativeMod var out = new EnumMap(ItemPridePigment.Type.class); for (var politicsInMyVidya : ItemPridePigment.Type.values()) { out.put(politicsInMyVidya, make("pride_colorizer_" + politicsInMyVidya.getName(), - new ItemPridePigment(politicsInMyVidya, unstackable()))); + new ItemPridePigment(politicsInMyVidya, unstackable()))); } return out; }); public static final Item UUID_PIGMENT = make("uuid_colorizer", new ItemUUIDPigment(unstackable())); public static final Item DEFAULT_PIGMENT = make("default_colorizer", - new ItemAmethystAndCopperPigment(unstackable())); + new ItemAmethystAndCopperPigment(unstackable())); // BUFF SANDVICH public static final Item SUBMARINE_SANDWICH = make("sub_sandwich", - new Item(props().food(new FoodProperties.Builder().nutrition(14).saturationMod(1.2f).build()))); + new Item(props().food(new FoodProperties.Builder().nutrition(14).saturationModifier(1.2f).build()))); public static final ItemLoreFragment LORE_FRAGMENT = make("lore_fragment", - new ItemLoreFragment(unstackable() - .rarity(Rarity.RARE))); + new ItemLoreFragment(unstackable() + .rarity(Rarity.RARE))); public static final ItemCreativeUnlocker CREATIVE_UNLOCKER = make("creative_unlocker", - new ItemCreativeUnlocker(unstackable() - .rarity(Rarity.EPIC) - .food(new FoodProperties.Builder().nutrition(20).saturationMod(1f).alwaysEat().build()))); + new ItemCreativeUnlocker(unstackable() + .rarity(Rarity.EPIC) + .food(new FoodProperties.Builder().nutrition(20).saturationModifier(1f).alwaysEdible().build()))); // @@ -155,6 +178,21 @@ public static Item.Properties unstackable() { return props().stacksTo(1); } + private static void generateScrollEntries(CreativeModeTab.Output r) { + var keyList = new ArrayList>(); + Registry regi = IXplatAbstractions.INSTANCE.getActionRegistry(); + for (var key : regi.registryKeySet()) + if (HexUtils.isOfTag(regi, key, HexTags.Actions.PER_WORLD_PATTERN)) + keyList.add(key); + keyList.sort(Comparator.comparing(ResourceKey::location)); + for (var key : keyList) { + r.accept(ItemScroll.withPerWorldPattern( + new ItemStack(HexItems.SCROLL_LARGE), + key + )); + } + } + private static T make(ResourceLocation id, T item, @Nullable CreativeModeTab tab) { var old = ITEMS.put(id, item); if (old != null) { diff --git a/Common/src/main/java/at/petrak/hexcasting/common/lib/HexLootFunctions.java b/Common/src/main/java/at/petrak/hexcasting/common/lib/HexLootFunctions.java index bebc94ad42..a8b813d5ba 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/lib/HexLootFunctions.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/lib/HexLootFunctions.java @@ -1,8 +1,10 @@ package at.petrak.hexcasting.common.lib; import at.petrak.hexcasting.common.loot.AddPerWorldPatternToScrollFunc; +import at.petrak.hexcasting.common.loot.AddHexToAncientCypherFunc; import at.petrak.hexcasting.common.loot.AmethystReducerFunc; import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.storage.loot.functions.LootItemConditionalFunction; import net.minecraft.world.level.storage.loot.functions.LootItemFunctionType; import java.util.LinkedHashMap; @@ -12,20 +14,25 @@ import static at.petrak.hexcasting.api.HexAPI.modLoc; public class HexLootFunctions { - public static void registerSerializers(BiConsumer r) { + public static void registerSerializers(BiConsumer, ResourceLocation> r) { for (var e : LOOT_FUNCS.entrySet()) { r.accept(e.getValue(), e.getKey()); } } - private static final Map LOOT_FUNCS = new LinkedHashMap<>(); + private static final Map> LOOT_FUNCS = new LinkedHashMap<>(); - public static final LootItemFunctionType PATTERN_SCROLL = register("pattern_scroll", - new LootItemFunctionType(new AddPerWorldPatternToScrollFunc.Serializer())); - public static final LootItemFunctionType AMETHYST_SHARD_REDUCER = register("amethyst_shard_reducer", - new LootItemFunctionType(new AmethystReducerFunc.Serializer())); + public static final LootItemFunctionType PATTERN_SCROLL = register("pattern_scroll", + new LootItemFunctionType<>(AddPerWorldPatternToScrollFunc.CODEC)); + public static final LootItemFunctionType HEX_CYPHER = register("hex_cypher", + new LootItemFunctionType<>(AddHexToAncientCypherFunc.CODEC)); + public static final LootItemFunctionType AMETHYST_SHARD_REDUCER = register("amethyst_shard_reducer", + new LootItemFunctionType<>(AmethystReducerFunc.CODEC)); - private static LootItemFunctionType register(String id, LootItemFunctionType lift) { + private static LootItemFunctionType register( + String id, + LootItemFunctionType lift + ) { var old = LOOT_FUNCS.put(modLoc(id), lift); if (old != null) { throw new IllegalArgumentException("Typo? Duplicate id " + id); diff --git a/Common/src/main/java/at/petrak/hexcasting/common/lib/HexMobEffects.java b/Common/src/main/java/at/petrak/hexcasting/common/lib/HexMobEffects.java index 6398bfea27..d9a3f6cf1b 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/lib/HexMobEffects.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/lib/HexMobEffects.java @@ -1,6 +1,8 @@ package at.petrak.hexcasting.common.lib; +import at.petrak.hexcasting.api.HexAPI; import at.petrak.hexcasting.common.misc.HexMobEffect; +import net.minecraft.core.Holder; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.effect.MobEffect; import net.minecraft.world.effect.MobEffectCategory; @@ -23,12 +25,12 @@ public static void register(BiConsumer r) { public static final MobEffect ENLARGE_GRID = make("enlarge_grid", new HexMobEffect(MobEffectCategory.BENEFICIAL, 0xc875ff)) - .addAttributeModifier(HexAttributes.GRID_ZOOM, "d4afaf0f-df37-4253-9fa7-029e8e4415d9", - 0.25, AttributeModifier.Operation.MULTIPLY_TOTAL); + .addAttributeModifier(HexAttributes.GRID_ZOOM, HexAPI.modLoc("enlarge_grid"), + 0.25, AttributeModifier.Operation.ADD_MULTIPLIED_TOTAL); public static final MobEffect SHRINK_GRID = make("shrink_grid", new HexMobEffect(MobEffectCategory.HARMFUL, 0xc0e660)) - .addAttributeModifier(HexAttributes.GRID_ZOOM, "1ce492a9-8bf5-4091-a482-c6d9399e448a", - -0.2, AttributeModifier.Operation.MULTIPLY_TOTAL); + .addAttributeModifier(HexAttributes.GRID_ZOOM, HexAPI.modLoc("shrink_grid"), + -0.2, AttributeModifier.Operation.ADD_MULTIPLIED_TOTAL); private static T make(String id, T effect) { diff --git a/Common/src/main/java/at/petrak/hexcasting/common/lib/HexPotions.java b/Common/src/main/java/at/petrak/hexcasting/common/lib/HexPotions.java index e86409e77c..11ed7f7dcb 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/lib/HexPotions.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/lib/HexPotions.java @@ -1,53 +1,57 @@ package at.petrak.hexcasting.common.lib; +import net.minecraft.core.Holder; +import net.minecraft.core.RegistryAccess; +import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.item.Items; import net.minecraft.world.item.alchemy.Potion; +import net.minecraft.world.item.alchemy.PotionBrewing; import net.minecraft.world.item.alchemy.Potions; -import net.minecraft.world.item.Items; import java.util.LinkedHashMap; import java.util.Map; import java.util.function.BiConsumer; import static at.petrak.hexcasting.api.HexAPI.modLoc; -import at.petrak.hexcasting.mixin.accessor.AccessorPotionBrewing; public class HexPotions { - public static void register(BiConsumer r) { - for (var e : POTIONS.entrySet()) { - r.accept(e.getValue(), e.getKey()); - } - HexPotions.addRecipes(); - } - private static final Map POTIONS = new LinkedHashMap<>(); public static final Potion ENLARGE_GRID = make("enlarge_grid", - new Potion("enlarge_grid", new MobEffectInstance(HexMobEffects.ENLARGE_GRID, 3600))); + new Potion("enlarge_grid", new MobEffectInstance(Holder.direct(HexMobEffects.ENLARGE_GRID), 3600))); public static final Potion ENLARGE_GRID_LONG = make("enlarge_grid_long", - new Potion("enlarge_grid_long", new MobEffectInstance(HexMobEffects.ENLARGE_GRID, 9600))); + new Potion("enlarge_grid_long", new MobEffectInstance(Holder.direct(HexMobEffects.ENLARGE_GRID), 9600))); public static final Potion ENLARGE_GRID_STRONG = make("enlarge_grid_strong", - new Potion("enlarge_grid_strong", new MobEffectInstance(HexMobEffects.ENLARGE_GRID, 1800, 1))); + new Potion("enlarge_grid_strong", new MobEffectInstance(Holder.direct(HexMobEffects.ENLARGE_GRID), 1800, 1))); public static final Potion SHRINK_GRID = make("shrink_grid", - new Potion("shrink_grid", new MobEffectInstance(HexMobEffects.SHRINK_GRID, 3600))); + new Potion("shrink_grid", new MobEffectInstance(Holder.direct(HexMobEffects.SHRINK_GRID), 3600))); public static final Potion SHRINK_GRID_LONG = make("shrink_grid_long", - new Potion("shrink_grid_long", new MobEffectInstance(HexMobEffects.SHRINK_GRID, 9600))); + new Potion("shrink_grid_long", new MobEffectInstance(Holder.direct(HexMobEffects.SHRINK_GRID), 9600))); public static final Potion SHRINK_GRID_STRONG = make("shrink_grid_strong", - new Potion("shrink_grid_strong", new MobEffectInstance(HexMobEffects.SHRINK_GRID, 1800, 1))); + new Potion("shrink_grid_strong", new MobEffectInstance(Holder.direct(HexMobEffects.SHRINK_GRID), 1800, 1))); + + public static void registerPotions(BiConsumer r) { + for (var e : POTIONS.entrySet()) { + r.accept(e.getValue(), e.getKey()); + } + } + + public static void addRecipes(PotionBrewing.Builder builder, RegistryAccess registryAccess) { + var potionRegistry = registryAccess.registryOrThrow(Registries.POTION); - public static void addRecipes() { - AccessorPotionBrewing.addMix(Potions.AWKWARD, HexItems.AMETHYST_DUST, ENLARGE_GRID); - AccessorPotionBrewing.addMix(ENLARGE_GRID, Items.REDSTONE, ENLARGE_GRID_LONG); - AccessorPotionBrewing.addMix(ENLARGE_GRID, Items.GLOWSTONE_DUST, ENLARGE_GRID_STRONG); + builder.addMix(Potions.AWKWARD, HexItems.AMETHYST_DUST, potionRegistry.wrapAsHolder(ENLARGE_GRID)); + builder.addMix(potionRegistry.wrapAsHolder(ENLARGE_GRID), Items.REDSTONE, potionRegistry.wrapAsHolder(ENLARGE_GRID_LONG)); + builder.addMix(potionRegistry.wrapAsHolder(ENLARGE_GRID), Items.GLOWSTONE_DUST, potionRegistry.wrapAsHolder(ENLARGE_GRID_STRONG)); - AccessorPotionBrewing.addMix(ENLARGE_GRID, Items.FERMENTED_SPIDER_EYE, SHRINK_GRID); - AccessorPotionBrewing.addMix(ENLARGE_GRID_LONG, Items.FERMENTED_SPIDER_EYE, SHRINK_GRID_LONG); - AccessorPotionBrewing.addMix(ENLARGE_GRID_STRONG, Items.FERMENTED_SPIDER_EYE, SHRINK_GRID_STRONG); + builder.addMix(potionRegistry.wrapAsHolder(ENLARGE_GRID), Items.FERMENTED_SPIDER_EYE, potionRegistry.wrapAsHolder(SHRINK_GRID)); + builder.addMix(potionRegistry.wrapAsHolder(ENLARGE_GRID_LONG), Items.FERMENTED_SPIDER_EYE, potionRegistry.wrapAsHolder(SHRINK_GRID_LONG)); + builder.addMix(potionRegistry.wrapAsHolder(ENLARGE_GRID_STRONG), Items.FERMENTED_SPIDER_EYE, potionRegistry.wrapAsHolder(SHRINK_GRID_STRONG)); - AccessorPotionBrewing.addMix(SHRINK_GRID, Items.REDSTONE, SHRINK_GRID_LONG); - AccessorPotionBrewing.addMix(SHRINK_GRID, Items.GLOWSTONE_DUST, SHRINK_GRID_STRONG); + builder.addMix(potionRegistry.wrapAsHolder(SHRINK_GRID), Items.REDSTONE, potionRegistry.wrapAsHolder(SHRINK_GRID_LONG)); + builder.addMix(potionRegistry.wrapAsHolder(SHRINK_GRID), Items.GLOWSTONE_DUST, potionRegistry.wrapAsHolder(SHRINK_GRID_STRONG)); } private static T make(String id, T potion) { diff --git a/Common/src/main/java/at/petrak/hexcasting/common/lib/HexRegistries.java b/Common/src/main/java/at/petrak/hexcasting/common/lib/HexRegistries.java index e529e9b889..9ea3f26bec 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/lib/HexRegistries.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/lib/HexRegistries.java @@ -6,6 +6,8 @@ import at.petrak.hexcasting.api.casting.eval.sideeffects.EvalSound; import at.petrak.hexcasting.api.casting.eval.vm.ContinuationFrame; import at.petrak.hexcasting.api.casting.iota.IotaType; +import at.petrak.hexcasting.common.recipe.ingredient.state.StateIngredientType; +import at.petrak.hexcasting.common.recipe.ingredient.brainsweep.BrainsweepeeIngredientType; import net.minecraft.core.Registry; import net.minecraft.resources.ResourceKey; @@ -18,4 +20,6 @@ public class HexRegistries { public static final ResourceKey> ARITHMETIC = ResourceKey.createRegistryKey(modLoc("arithmetic")); public static final ResourceKey>> CONTINUATION_TYPE = ResourceKey.createRegistryKey(modLoc("continuation_type")); public static final ResourceKey> EVAL_SOUND = ResourceKey.createRegistryKey(modLoc("eval_sound")); + public static final ResourceKey>> STATE_INGREDIENT = ResourceKey.createRegistryKey(modLoc("state_ingredient")); + public static final ResourceKey>> BRAINSWEEPEE_INGREDIENT = ResourceKey.createRegistryKey(modLoc("brainsweepee_ingredient")); } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/lib/hex/HexActions.java b/Common/src/main/java/at/petrak/hexcasting/common/lib/hex/HexActions.java index dc57ed4997..634a0b4ef5 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/lib/hex/HexActions.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/lib/hex/HexActions.java @@ -275,16 +275,16 @@ public class HexActions { new ActionRegistryEntry(HexPattern.fromAngles("adaa", HexDir.WEST), OpBeep.INSTANCE)); public static final ActionRegistryEntry CRAFT$CYPHER = make("craft/cypher", new ActionRegistryEntry( - HexPattern.fromAngles("waqqqqq", HexDir.EAST), new OpMakePackagedSpell<>(HexItems.CYPHER, - MediaConstants.CRYSTAL_UNIT) + HexPattern.fromAngles("waqqqqq", HexDir.EAST), + new OpMakePackagedSpell(s -> (s.is(HexItems.CYPHER)||s.is(HexItems.ANCIENT_CYPHER)), HexItems.CYPHER.getDescription(), MediaConstants.CRYSTAL_UNIT) )); public static final ActionRegistryEntry CRAFT$TRINKET = make("craft/trinket", new ActionRegistryEntry( - HexPattern.fromAngles( - "wwaqqqqqeaqeaeqqqeaeq", HexDir.EAST), new OpMakePackagedSpell<>(HexItems.TRINKET, - 5 * MediaConstants.CRYSTAL_UNIT))); + HexPattern.fromAngles("wwaqqqqqeaqeaeqqqeaeq", HexDir.EAST), + new OpMakePackagedSpell(HexItems.TRINKET, 5 * MediaConstants.CRYSTAL_UNIT) + )); public static final ActionRegistryEntry CRAFT$ARTIFACT = make("craft/artifact", new ActionRegistryEntry( HexPattern.fromAngles("wwaqqqqqeawqwqwqwqwqwwqqeadaeqqeqqeadaeqq", HexDir.EAST), - new OpMakePackagedSpell<>(HexItems.ARTIFACT, 10 * MediaConstants.CRYSTAL_UNIT) + new OpMakePackagedSpell(HexItems.ARTIFACT, 10 * MediaConstants.CRYSTAL_UNIT) )); public static final ActionRegistryEntry CRAFT$BATTERY = make("craft/battery", new ActionRegistryEntry( HexPattern.fromAngles("aqqqaqwwaqqqqqeqaqqqawwqwqwqwqwqw", HexDir.SOUTH_WEST), OpMakeBattery.INSTANCE)); @@ -423,7 +423,7 @@ public class HexActions { // == Consts == public static final ActionRegistryEntry CONST$NULL = make("const/null", - new ActionRegistryEntry(HexPattern.fromAngles("d", HexDir.EAST), Action.makeConstantOp(new NullIota()))); + new ActionRegistryEntry(HexPattern.fromAngles("d", HexDir.EAST), Action.makeConstantOp(NullIota.INSTANCE))); public static final ActionRegistryEntry CONST$TRUE = make("const/true", new ActionRegistryEntry(HexPattern.fromAngles("aqae", diff --git a/Common/src/main/java/at/petrak/hexcasting/common/lib/hex/HexIotaTypes.java b/Common/src/main/java/at/petrak/hexcasting/common/lib/hex/HexIotaTypes.java index 0526e9ac56..e103d7720e 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/lib/hex/HexIotaTypes.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/lib/hex/HexIotaTypes.java @@ -19,18 +19,9 @@ @ParametersAreNonnullByDefault public class HexIotaTypes { public static final Registry> REGISTRY = IXplatAbstractions.INSTANCE.getIotaTypeRegistry(); - public static final String - KEY_TYPE = HexAPI.MOD_ID + ":type", - KEY_DATA = HexAPI.MOD_ID + ":data"; public static final int MAX_SERIALIZATION_DEPTH = 256; public static final int MAX_SERIALIZATION_TOTAL = 1024; - public static void registerTypes(BiConsumer, ResourceLocation> r) { - for (var e : TYPES.entrySet()) { - r.accept(e.getValue(), e.getKey()); - } - } - private static final Map> TYPES = new LinkedHashMap<>(); public static final IotaType NULL = type("null", NullIota.TYPE); @@ -43,6 +34,12 @@ public static void registerTypes(BiConsumer, ResourceLocation> r) { public static final IotaType VEC3 = type("vec3", Vec3Iota.TYPE); public static final IotaType CONTINUATION = type("continuation", ContinuationIota.TYPE); + public static void registerTypes(BiConsumer, ResourceLocation> r) { + for (var e : TYPES.entrySet()) { + r.accept(e.getValue(), e.getKey()); + } + } + private static > T type(String name, T type) { var old = TYPES.put(modLoc(name), type); diff --git a/Common/src/main/java/at/petrak/hexcasting/common/loot/AddHexToAncientCypherFunc.java b/Common/src/main/java/at/petrak/hexcasting/common/loot/AddHexToAncientCypherFunc.java new file mode 100644 index 0000000000..a82f688389 --- /dev/null +++ b/Common/src/main/java/at/petrak/hexcasting/common/loot/AddHexToAncientCypherFunc.java @@ -0,0 +1,93 @@ +package at.petrak.hexcasting.common.loot; + +import at.petrak.hexcasting.api.casting.iota.PatternIota; +import at.petrak.hexcasting.api.casting.iota.IotaType; +import at.petrak.hexcasting.api.casting.math.HexDir; +import at.petrak.hexcasting.api.casting.math.HexPattern; +import at.petrak.hexcasting.api.item.VariantItem; +import at.petrak.hexcasting.api.misc.MediaConstants; +import at.petrak.hexcasting.common.items.magic.ItemAncientCypher; +import at.petrak.hexcasting.common.lib.HexDataComponents; +import at.petrak.hexcasting.common.lib.HexLootFunctions; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.util.RandomSource; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.level.storage.loot.functions.LootItemConditionalFunction; +import net.minecraft.world.level.storage.loot.functions.LootItemFunctionType; +import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import com.mojang.datafixers.util.Pair; + +/** + * Add a random preset hex to the ancient cypher, and select a random variant. + *

+ * The function itself is only used on Fabric but the behavior {@link AddHexToAncientCypherFunc#doStatic} + * is used on both sides + */ +public class AddHexToAncientCypherFunc extends LootItemConditionalFunction { + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec( + p_344674_ -> commonFields(p_344674_) + .apply(p_344674_, AddHexToAncientCypherFunc::new) + ); + + public AddHexToAncientCypherFunc(List lootItemConditions) { + super(lootItemConditions); + } + + /** + * This doesn't actually have any params so extract behaviour out for the benefit of forge + */ + public static ItemStack doStatic(ItemStack stack, RandomSource rand) { + var hex = LOOT_HEXES.get(rand.nextInt(LOOT_HEXES.size())); + + stack.set(HexDataComponents.HEX_NAME, hex.getFirst()); + stack.set(HexDataComponents.MEDIA, 32 * MediaConstants.SHARD_UNIT); + stack.set(HexDataComponents.MEDIA_MAX, 32 * MediaConstants.SHARD_UNIT); + stack.set(HexDataComponents.VARIANT, rand.nextInt(8)); + stack.set(HexDataComponents.PATTERNS, Arrays.stream(hex.getSecond()).map(el -> { + var pieces = el.split(" "); + return new PatternIota(HexPattern.fromAngles(pieces[1],HexDir.fromString(pieces[0]))); + }).collect(Collectors.toList())); + + return stack; + } + + @Override + protected ItemStack run(ItemStack stack, LootContext ctx) { + return doStatic(stack, ctx.getRandom()); + } + + @Override + public LootItemFunctionType getType() { + return HexLootFunctions.HEX_CYPHER; + } + + // TODO: make this datapackable + private static final List> LOOT_HEXES = List.of( + new Pair<>("hexcasting.loot_hex.shatter", new String[] {"NORTH_EAST qaq","EAST aa","NORTH_EAST qaq","NORTH_EAST wa","EAST wqaawdd","EAST qaqqqqq"}), + new Pair<>("hexcasting.loot_hex.kindle", new String[] {"NORTH_EAST qaq","EAST aa","NORTH_EAST qaq","NORTH_EAST wa","EAST wqaawdd","SOUTH_EAST aaqawawa"}), + new Pair<>("hexcasting.loot_hex.illuminate", new String[] {"NORTH_EAST qaq","EAST aa","NORTH_EAST qaq","NORTH_EAST wa","EAST aadadaaw","EAST wqaawdd","NORTH_EAST ddqdd","EAST weddwaa","NORTH_EAST waaw","NORTH_EAST qqd"}), + new Pair<>("hexcasting.loot_hex.growth", new String[] {"NORTH_EAST qaq","EAST aa","NORTH_EAST qaq","NORTH_EAST wa","EAST aadadaaw","EAST wqaawdd","NORTH_EAST ddqdd","EAST weddwaa","NORTH_EAST waaw","SOUTH_EAST aqaaedwd","EAST aadaadaa","NORTH_EAST wqaqwawqaqw","NORTH_EAST wqaqwawqaqw","NORTH_EAST wqaqwawqaqw"}), + new Pair<>("hexcasting.loot_hex.lunge", new String[] {"NORTH_EAST qaq","EAST aadaa","NORTH_EAST wa","SOUTH_EAST aqaawa","SOUTH_EAST waqaw","SOUTH_WEST awqqqwaqw"}), + new Pair<>("hexcasting.loot_hex.sidestep", new String[] {"NORTH_EAST qaq","EAST aadaa","NORTH_EAST wa","NORTH_WEST eqqq","SOUTH_EAST aqaawd","SOUTH_EAST e","NORTH_WEST qqqqqew","SOUTH_WEST eeeeeqw","SOUTH_EAST awdd","NORTH_EAST wdedw","SOUTH_WEST awqqqwaqw"}), + new Pair<>("hexcasting.loot_hex.ascend", new String[] {"NORTH_EAST qaq","SOUTH_EAST aqaae","WEST qqqqqawwawawd"}), + new Pair<>("hexcasting.loot_hex.blink", new String[] {"NORTH_EAST qaq","EAST aadaa","EAST aa","NORTH_EAST qaq","NORTH_EAST wa","EAST wqaawdd","NORTH_EAST qaq","EAST aa","NORTH_WEST wddw","NORTH_EAST wqaqw","SOUTH_EAST aqaaw","NORTH_WEST wddw","SOUTH_WEST awqqqwaq"}), + new Pair<>("hexcasting.loot_hex.blastoff", new String[] {"NORTH_EAST qaq","NORTH_WEST qqqqqew","SOUTH_EAST aqaawaa","SOUTH_EAST waqaw","SOUTH_WEST awqqqwaqw"}), + new Pair<>("hexcasting.loot_hex.radar", new String[] {"WEST qqq","EAST aadaa","EAST aa","SOUTH_EAST aqaawa","SOUTH_WEST ewdqdwe","NORTH_EAST de","EAST eee","NORTH_EAST qaq","EAST aa","SOUTH_EAST aqaaeaqq","SOUTH_EAST qqqqqwdeddwd","NORTH_EAST dadad"}), + new Pair<>("hexcasting.loot_hex.beckon", new String[] {"NORTH_EAST qaq","EAST aa","NORTH_EAST qaq","NORTH_EAST wa","EAST weaqa","EAST aadaa","EAST dd","NORTH_EAST qaq","EAST aa","EAST aawdd","NORTH_WEST wddw","EAST aadaa","NORTH_EAST wqaqw","NORTH_EAST wdedw","SOUTH_EAST aqaawa","SOUTH_EAST waqaw","SOUTH_WEST awqqqwaqw"}), + new Pair<>("hexcasting.loot_hex.detonate", new String[] {"NORTH_EAST qaq","EAST aa","SOUTH_EAST aqaaedwd","EAST ddwddwdd"}), + new Pair<>("hexcasting.loot_hex.shockwave", new String[] {"NORTH_EAST qaq","EAST aa","SOUTH_EAST aqaawaa","EAST aadaadaa","SOUTH_EAST aqawqadaq","SOUTH_EAST aqaaedwd","EAST aawaawaa","NORTH_EAST qqa","EAST qaqqqqq"}), + new Pair<>("hexcasting.loot_hex.heat_wave", new String[] {"WEST qqq","SOUTH_EAST aaqawawa","EAST eee","NORTH_EAST qaq","EAST aa","SOUTH_EAST aqaae","SOUTH_EAST qqqqqwded","SOUTH_WEST aaqwqaa","SOUTH_EAST a","NORTH_EAST dadad"}), + new Pair<>("hexcasting.loot_hex.wither_wave", new String[] {"WEST qqq","SOUTH_EAST aqaae","SOUTH_EAST aqaaw","SOUTH_WEST qqqqqaewawawe","EAST eee","NORTH_EAST qaq","EAST aa","SOUTH_EAST aqaae","SOUTH_EAST qqqqqwdeddwd","SOUTH_WEST aaqwqaa","SOUTH_EAST a","NORTH_EAST dadad"}), + new Pair<>("hexcasting.loot_hex.flight_zone", new String[] {"NORTH_EAST qaq","SOUTH_EAST aqaaq","SOUTH_WEST awawaawq"}) + ); +} diff --git a/Common/src/main/java/at/petrak/hexcasting/common/loot/AddPerWorldPatternToScrollFunc.java b/Common/src/main/java/at/petrak/hexcasting/common/loot/AddPerWorldPatternToScrollFunc.java index 30c9f97370..870714dd87 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/loot/AddPerWorldPatternToScrollFunc.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/loot/AddPerWorldPatternToScrollFunc.java @@ -3,23 +3,28 @@ import at.petrak.hexcasting.api.casting.ActionRegistryEntry; import at.petrak.hexcasting.api.mod.HexTags; import at.petrak.hexcasting.api.utils.HexUtils; +import at.petrak.hexcasting.api.utils.NBTHelper; import at.petrak.hexcasting.common.casting.PatternRegistryManifest; import at.petrak.hexcasting.common.items.storage.ItemScroll; +import at.petrak.hexcasting.common.lib.HexDataComponents; import at.petrak.hexcasting.common.lib.HexLootFunctions; import at.petrak.hexcasting.xplat.IXplatAbstractions; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonObject; -import com.google.gson.JsonSerializationContext; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.util.RandomSource; import net.minecraft.core.Registry; -import net.minecraft.nbt.CompoundTag; import net.minecraft.resources.ResourceKey; +import net.minecraft.server.level.ServerLevel; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.enchantment.Enchantment; import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.level.storage.loot.functions.ApplyBonusCount; import net.minecraft.world.level.storage.loot.functions.LootItemConditionalFunction; import net.minecraft.world.level.storage.loot.functions.LootItemFunctionType; import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; import java.util.ArrayList; +import java.util.List; /** * Slap a random per-world pattern on the scroll. @@ -28,15 +33,19 @@ * is used on both sides */ public class AddPerWorldPatternToScrollFunc extends LootItemConditionalFunction { - public AddPerWorldPatternToScrollFunc(LootItemCondition[] lootItemConditions) { + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec( + p_344674_ -> commonFields(p_344674_) + .apply(p_344674_, AddPerWorldPatternToScrollFunc::new) + ); + + public AddPerWorldPatternToScrollFunc(List lootItemConditions) { super(lootItemConditions); } /** * This doesn't actually have any params so extract behaviour out for the benefit of forge */ - public static ItemStack doStatic(ItemStack stack, LootContext ctx) { - var rand = ctx.getRandom(); + public static ItemStack doStatic(ItemStack stack, RandomSource rand, ServerLevel overworld) { var perWorldKeys = new ArrayList>(); Registry regi = IXplatAbstractions.INSTANCE.getActionRegistry(); for (var key : regi.registryKeySet()) { @@ -44,38 +53,20 @@ public static ItemStack doStatic(ItemStack stack, LootContext ctx) { perWorldKeys.add(key); } } - var key = perWorldKeys.get(rand.nextInt(perWorldKeys.size())); - - var pat = PatternRegistryManifest.getCanonicalStrokesPerWorld(key, ctx.getLevel().getServer().overworld()); - var tag = new CompoundTag(); - tag.putString(ItemScroll.TAG_OP_ID, key.location().toString()); - tag.put(ItemScroll.TAG_PATTERN, pat.serializeToNBT()); - - stack.getOrCreateTag().merge(tag); - + var patternKey = perWorldKeys.get(rand.nextInt(perWorldKeys.size())); + var pat = PatternRegistryManifest.getCanonicalStrokesPerWorld(patternKey, overworld); + stack.set(HexDataComponents.ACTION, patternKey); + stack.set(HexDataComponents.PATTERN, pat); return stack; } @Override protected ItemStack run(ItemStack stack, LootContext ctx) { - return doStatic(stack, ctx); + return doStatic(stack, ctx.getRandom(), ctx.getLevel().getServer().overworld()); } @Override - public LootItemFunctionType getType() { + public LootItemFunctionType getType() { return HexLootFunctions.PATTERN_SCROLL; } - - public static class Serializer extends LootItemConditionalFunction.Serializer { - @Override - public void serialize(JsonObject json, AddPerWorldPatternToScrollFunc value, JsonSerializationContext ctx) { - super.serialize(json, value, ctx); - } - - @Override - public AddPerWorldPatternToScrollFunc deserialize(JsonObject object, JsonDeserializationContext ctx, - LootItemCondition[] conditions) { - return new AddPerWorldPatternToScrollFunc(conditions); - } - } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/loot/AmethystReducerFunc.java b/Common/src/main/java/at/petrak/hexcasting/common/loot/AmethystReducerFunc.java index cee38be6dd..26c9be0992 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/loot/AmethystReducerFunc.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/loot/AmethystReducerFunc.java @@ -1,10 +1,9 @@ package at.petrak.hexcasting.common.loot; import at.petrak.hexcasting.common.lib.HexLootFunctions; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonObject; -import com.google.gson.JsonSerializationContext; -import net.minecraft.util.GsonHelper; +import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.level.storage.loot.LootContext; @@ -12,14 +11,28 @@ import net.minecraft.world.level.storage.loot.functions.LootItemFunctionType; import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; +import java.util.List; + public class AmethystReducerFunc extends LootItemConditionalFunction { - public final double delta; + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec( + p_344674_ -> commonFields(p_344674_) + .and( + Codec.DOUBLE.fieldOf("delta").forGetter(AmethystReducerFunc::getDelta) + ) + .apply(p_344674_, AmethystReducerFunc::new) + ); + + private final double delta; - public AmethystReducerFunc(LootItemCondition[] lootItemConditions, double delta) { + public AmethystReducerFunc(List lootItemConditions, double delta) { super(lootItemConditions); this.delta = delta; } + public double getDelta() { + return delta; + } + public static ItemStack doStatic(ItemStack stack, LootContext ctx, double amount) { if (stack.is(Items.AMETHYST_SHARD)) { stack.setCount((int) (stack.getCount() * (1 + amount))); @@ -33,22 +46,7 @@ protected ItemStack run(ItemStack stack, LootContext ctx) { } @Override - public LootItemFunctionType getType() { + public LootItemFunctionType getType() { return HexLootFunctions.AMETHYST_SHARD_REDUCER; } - - public static class Serializer extends LootItemConditionalFunction.Serializer { - @Override - public void serialize(JsonObject json, AmethystReducerFunc value, JsonSerializationContext ctx) { - super.serialize(json, value, ctx); - json.addProperty("delta", value.delta); - } - - @Override - public AmethystReducerFunc deserialize(JsonObject object, JsonDeserializationContext ctx, - LootItemCondition[] conditions) { - var delta = GsonHelper.getAsDouble(object, "delta"); - return new AmethystReducerFunc(conditions, delta); - } - } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/loot/HexLootHandler.java b/Common/src/main/java/at/petrak/hexcasting/common/loot/HexLootHandler.java index e0788d5446..a8d8679f15 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/loot/HexLootHandler.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/loot/HexLootHandler.java @@ -1,19 +1,22 @@ package at.petrak.hexcasting.common.loot; import com.google.common.collect.ImmutableList; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.RandomSource; +import net.minecraft.world.level.storage.loot.LootTable; import static at.petrak.hexcasting.api.HexAPI.modLoc; // https://github.com/VazkiiMods/Botania/blob/1.18.x/Xplat/src/main/java/vazkii/botania/common/loot/LootHandler.java // We need to inject dungeon loot (scrolls and lore), make amethyst drop fewer shards, and the extra dust stuff. // On forge: -// - Scrolls and lore are done with a loot mod +// - Scrolls, lore, and cyphers are done with a loot mod // - Amethyst drop fiddling is done with another loot mod; the shard delta is in the loot mod data and the rest of // the stuff is loaded from TABLE_INJECT_AMETHYST_CLUSTER // On fabric: -// - Scrolls and lore are done with a lootLoad listener and the amounts are loaded from config +// - Scrolls, lore, and cyphers are done with a lootLoad listener and the amounts are loaded from config // - Amethyst shard reduction is done with a loot function mixed in to always be on amethyst clusters, god, cause I // don't think it's facile to use the loot pool api to try to figure out which pool is for the amethyst and reduce it // - Amethyst dust and crystals are done by adding the loot table Forge uses in directly via listener @@ -24,41 +27,51 @@ public class HexLootHandler { // In places where it doesn't really make sense to have them lore-wise just put them rarely anyways // to make it less of a PITA for new players - new ScrollInjection(new ResourceLocation("minecraft", "chests/simple_dungeon"), 1), - new ScrollInjection(new ResourceLocation("minecraft", "chests/abandoned_mineshaft"), 1), - new ScrollInjection(new ResourceLocation("minecraft", "chests/bastion_other"), 1), - new ScrollInjection(new ResourceLocation("minecraft", "chests/nether_bridge"), 1), + new ScrollInjection(ResourceLocation.fromNamespaceAndPath("minecraft", "chests/simple_dungeon"), 1), + new ScrollInjection(ResourceLocation.fromNamespaceAndPath("minecraft", "chests/abandoned_mineshaft"), 1), + new ScrollInjection(ResourceLocation.fromNamespaceAndPath("minecraft", "chests/bastion_other"), 1), + new ScrollInjection(ResourceLocation.fromNamespaceAndPath("minecraft", "chests/nether_bridge"), 1), - new ScrollInjection(new ResourceLocation("minecraft", "chests/jungle_temple"), 2), - new ScrollInjection(new ResourceLocation("minecraft", "chests/desert_pyramid"), 2), - new ScrollInjection(new ResourceLocation("minecraft", "chests/village/village_cartographer"), 2), + new ScrollInjection(ResourceLocation.fromNamespaceAndPath("minecraft", "chests/jungle_temple"), 2), + new ScrollInjection(ResourceLocation.fromNamespaceAndPath("minecraft", "chests/desert_pyramid"), 2), + new ScrollInjection(ResourceLocation.fromNamespaceAndPath("minecraft", "chests/village/village_cartographer"), 2), - new ScrollInjection(new ResourceLocation("minecraft", "chests/shipwreck_map"), 3), - new ScrollInjection(new ResourceLocation("minecraft", "chests/bastion_treasure"), 3), - new ScrollInjection(new ResourceLocation("minecraft", "chests/end_city_treasure"), 3), + new ScrollInjection(ResourceLocation.fromNamespaceAndPath("minecraft", "chests/shipwreck_map"), 3), + new ScrollInjection(ResourceLocation.fromNamespaceAndPath("minecraft", "chests/bastion_treasure"), 3), + new ScrollInjection(ResourceLocation.fromNamespaceAndPath("minecraft", "chests/end_city_treasure"), 3), // ancient city chests have amethyst in them, thinking emoji - new ScrollInjection(new ResourceLocation("minecraft", "chests/ancient_city"), 4), + new ScrollInjection(ResourceLocation.fromNamespaceAndPath("minecraft", "chests/ancient_city"), 4), // wonder what those pillagers are up to with those scrolls - new ScrollInjection(new ResourceLocation("minecraft", "chests/pillager_outpost"), 4), + new ScrollInjection(ResourceLocation.fromNamespaceAndPath("minecraft", "chests/pillager_outpost"), 4), // if you manage to find one of these things you deserve a lot of scrolls - new ScrollInjection(new ResourceLocation("minecraft", "chests/woodland_mansion"), 5), - new ScrollInjection(new ResourceLocation("minecraft", "chests/stronghold_library"), 5) + new ScrollInjection(ResourceLocation.fromNamespaceAndPath("minecraft", "chests/woodland_mansion"), 5), + new ScrollInjection(ResourceLocation.fromNamespaceAndPath("minecraft", "chests/stronghold_library"), 5) ); public static final ImmutableList DEFAULT_LORE_INJECTS = ImmutableList.of( - new ResourceLocation("minecraft", "chests/simple_dungeon"), - new ResourceLocation("minecraft", "chests/abandoned_mineshaft"), - new ResourceLocation("minecraft", "chests/pillager_outpost"), - new ResourceLocation("minecraft", "chests/woodland_mansion"), - new ResourceLocation("minecraft", "chests/stronghold_library"), + ResourceLocation.fromNamespaceAndPath("minecraft", "chests/simple_dungeon"), + ResourceLocation.fromNamespaceAndPath("minecraft", "chests/abandoned_mineshaft"), + ResourceLocation.fromNamespaceAndPath("minecraft", "chests/pillager_outpost"), + ResourceLocation.fromNamespaceAndPath("minecraft", "chests/woodland_mansion"), + ResourceLocation.fromNamespaceAndPath("minecraft", "chests/stronghold_library"), // >:) - new ResourceLocation("minecraft", "chests/village/village_desert_house"), - new ResourceLocation("minecraft", "chests/village/village_plains_house"), - new ResourceLocation("minecraft", "chests/village/village_savanna_house"), - new ResourceLocation("minecraft", "chests/village/village_snowy_house"), - new ResourceLocation("minecraft", "chests/village/village_taiga_house") + ResourceLocation.fromNamespaceAndPath("minecraft", "chests/village/village_desert_house"), + ResourceLocation.fromNamespaceAndPath("minecraft", "chests/village/village_plains_house"), + ResourceLocation.fromNamespaceAndPath("minecraft", "chests/village/village_savanna_house"), + ResourceLocation.fromNamespaceAndPath("minecraft", "chests/village/village_snowy_house"), + ResourceLocation.fromNamespaceAndPath("minecraft", "chests/village/village_taiga_house") + ); + + public static final ImmutableList DEFAULT_CYPHER_INJECTS = ImmutableList.of( + ResourceLocation.fromNamespaceAndPath("minecraft", "chests/simple_dungeon"), + ResourceLocation.fromNamespaceAndPath("minecraft", "chests/abandoned_mineshaft"), + ResourceLocation.fromNamespaceAndPath("minecraft", "chests/stronghold_corridor"), + ResourceLocation.fromNamespaceAndPath("minecraft", "chests/jungle_temple"), + ResourceLocation.fromNamespaceAndPath("minecraft", "chests/desert_pyramid"), + ResourceLocation.fromNamespaceAndPath("minecraft", "chests/ancient_city"), + ResourceLocation.fromNamespaceAndPath("minecraft", "chests/nether_bridge") ); public static int getScrollCount(int range, RandomSource random) { @@ -67,8 +80,9 @@ public static int getScrollCount(int range, RandomSource random) { public static final double DEFAULT_SHARD_MODIFICATION = -0.5; public static final double DEFAULT_LORE_CHANCE = 0.4; + public static final double DEFAULT_CYPHER_CHANCE = 0.4; - public static final ResourceLocation TABLE_INJECT_AMETHYST_CLUSTER = modLoc("inject/amethyst_cluster"); + public static final ResourceKey TABLE_INJECT_AMETHYST_CLUSTER = ResourceKey.create(Registries.LOOT_TABLE, modLoc("inject/amethyst_cluster")); public record ScrollInjection(ResourceLocation injectee, int countRange) { } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/misc/AkashicTreeGrower.java b/Common/src/main/java/at/petrak/hexcasting/common/misc/AkashicTreeGrower.java index d346979600..7dbfe1fa90 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/misc/AkashicTreeGrower.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/misc/AkashicTreeGrower.java @@ -2,15 +2,21 @@ import at.petrak.hexcasting.common.lib.HexConfiguredFeatures; import com.google.common.collect.Lists; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Holder; +import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceKey; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.tags.BlockTags; import net.minecraft.util.RandomSource; -import net.minecraft.world.level.block.grower.AbstractTreeGrower; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.chunk.ChunkGenerator; import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; import java.util.List; -// TODO they fucking changed the trees AGAIN -public class AkashicTreeGrower extends AbstractTreeGrower { +public class AkashicTreeGrower { public static final AkashicTreeGrower INSTANCE = new AkashicTreeGrower(); public static final List>> GROWERS = Lists.newArrayList(); @@ -21,8 +27,49 @@ public static void init() { GROWERS.add(HexConfiguredFeatures.CITRINE_EDIFIED_TREE); } - @Override - protected ResourceKey> getConfiguredFeature(RandomSource pRandom, boolean pLargeHive) { + private ResourceKey> getConfiguredFeature(RandomSource pRandom, boolean pLargeHive) { return GROWERS.get(pRandom.nextInt(GROWERS.size())); } + + public boolean growTree(ServerLevel level, ChunkGenerator chunkGenerator, BlockPos pos, BlockState state, RandomSource random) { + ResourceKey> treeFeatureKey = getConfiguredFeature(random, hasFlowers(level, pos)); + if (treeFeatureKey == null) { + return false; + } else { + Holder> holder1 = level.registryAccess() + .registryOrThrow(Registries.CONFIGURED_FEATURE) + .getHolder(treeFeatureKey) + .orElse(null); + var event = net.neoforged.neoforge.event.EventHooks.fireBlockGrowFeature(level, random, pos, holder1); + holder1 = event.getFeature(); + if (event.isCanceled()) return false; + if (holder1 == null) { + return false; + } else { + ConfiguredFeature configuredfeature1 = holder1.value(); + BlockState blockstate1 = level.getFluidState(pos).createLegacyBlock(); + level.setBlock(pos, blockstate1, 4); + if (configuredfeature1.place(level, chunkGenerator, random, pos)) { + if (level.getBlockState(pos) == blockstate1) { + level.sendBlockUpdated(pos, state, blockstate1, 2); + } + + return true; + } else { + level.setBlock(pos, state, 4); + return false; + } + } + } + } + + private boolean hasFlowers(LevelAccessor level, BlockPos pos) { + for (BlockPos blockpos : BlockPos.MutableBlockPos.betweenClosed(pos.below().north(2).west(2), pos.above().south(2).east(2))) { + if (level.getBlockState(blockpos).is(BlockTags.FLOWERS)) { + return true; + } + } + + return false; + } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgBeepS2C.java b/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgBeepS2C.java index 852fc675af..946d2c4aa2 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgBeepS2C.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgBeepS2C.java @@ -1,56 +1,45 @@ package at.petrak.hexcasting.common.msgs; -import io.netty.buffer.ByteBuf; +import at.petrak.hexcasting.api.HexAPI; +import at.petrak.paucal.api.PaucalCodecs; import net.minecraft.client.Minecraft; import net.minecraft.core.particles.ParticleTypes; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.sounds.SoundSource; import net.minecraft.world.level.block.state.properties.NoteBlockInstrument; import net.minecraft.world.phys.Vec3; -import static at.petrak.hexcasting.api.HexAPI.modLoc; +public record MsgBeepS2C(Vec3 target, int note, NoteBlockInstrument instrument) implements CustomPacketPayload { + public static final CustomPacketPayload.Type TYPE = new CustomPacketPayload.Type<>(HexAPI.modLoc("beep")); -public record MsgBeepS2C(Vec3 target, int note, NoteBlockInstrument instrument) implements IMessage { - public static final ResourceLocation ID = modLoc("beep"); + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + PaucalCodecs.VEC3, MsgBeepS2C::target, + ByteBufCodecs.VAR_INT, MsgBeepS2C::note, + ByteBufCodecs.idMapper( + (num) -> NoteBlockInstrument.values()[num], + NoteBlockInstrument::ordinal + ), MsgBeepS2C::instrument, + MsgBeepS2C::new + ); @Override - public ResourceLocation getFabricId() { - return ID; - } - - public static MsgBeepS2C deserialize(ByteBuf buffer) { - var buf = new FriendlyByteBuf(buffer); - var x = buf.readDouble(); - var y = buf.readDouble(); - var z = buf.readDouble(); - var note = buf.readInt(); - var instrument = buf.readEnum(NoteBlockInstrument.class); - return new MsgBeepS2C(new Vec3(x, y, z), note, instrument); - } - - @Override - public void serialize(FriendlyByteBuf buf) { - buf.writeDouble(this.target.x); - buf.writeDouble(this.target.y); - buf.writeDouble(this.target.z); - buf.writeInt(this.note); - buf.writeEnum(instrument); + public CustomPacketPayload.Type type() { + return TYPE; } public static void handle(MsgBeepS2C msg) { - Minecraft.getInstance().execute(new Runnable() { - @Override - public void run() { - var minecraft = Minecraft.getInstance(); - var world = minecraft.level; - if (world != null) { - float pitch = (float) Math.pow(2, (msg.note() - 12) / 12.0); - world.playLocalSound(msg.target().x, msg.target().y, msg.target().z, - msg.instrument().getSoundEvent().value(), SoundSource.PLAYERS, 3, pitch, false); - world.addParticle(ParticleTypes.NOTE, msg.target().x, msg.target().y + 0.2, msg.target().z, - msg.note() / 24.0, 0, 0); - } + Minecraft.getInstance().execute(() -> { + var minecraft = Minecraft.getInstance(); + var world = minecraft.level; + if (world != null) { + float pitch = (float) Math.pow(2, (msg.note() - 12) / 12.0); + world.playLocalSound(msg.target().x, msg.target().y, msg.target().z, + msg.instrument().getSoundEvent().value(), SoundSource.PLAYERS, 3, pitch, false); + world.addParticle(ParticleTypes.NOTE, msg.target().x, msg.target().y + 0.2, msg.target().z, + msg.note() / 24.0, 0, 0); } }); } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgBlinkS2C.java b/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgBlinkS2C.java index ab75bc20ed..df770313ee 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgBlinkS2C.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgBlinkS2C.java @@ -1,8 +1,15 @@ package at.petrak.hexcasting.common.msgs; +import at.petrak.hexcasting.api.HexAPI; +import at.petrak.hexcasting.api.casting.eval.ExecutionClientView; +import at.petrak.paucal.api.PaucalCodecs; import io.netty.buffer.ByteBuf; import net.minecraft.client.Minecraft; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.phys.Vec3; @@ -11,27 +18,17 @@ /** * Sent server->client to synchronize OpBlink when the target is a player. */ -public record MsgBlinkS2C(Vec3 addedPosition) implements IMessage { - public static final ResourceLocation ID = modLoc("blink"); +public record MsgBlinkS2C(Vec3 addedPosition) implements CustomPacketPayload { + public static final CustomPacketPayload.Type TYPE = new CustomPacketPayload.Type<>(HexAPI.modLoc("blink")); - @Override - public ResourceLocation getFabricId() { - return ID; - } - - public static MsgBlinkS2C deserialize(ByteBuf buffer) { - var buf = new FriendlyByteBuf(buffer); - var x = buf.readDouble(); - var y = buf.readDouble(); - var z = buf.readDouble(); - return new MsgBlinkS2C(new Vec3(x, y, z)); - } + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + PaucalCodecs.VEC3, MsgBlinkS2C::addedPosition, + MsgBlinkS2C::new + ); @Override - public void serialize(FriendlyByteBuf buf) { - buf.writeDouble(this.addedPosition.x); - buf.writeDouble(this.addedPosition.y); - buf.writeDouble(this.addedPosition.z); + public CustomPacketPayload.Type type() { + return TYPE; } public static void handle(MsgBlinkS2C self) { diff --git a/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgCastParticleS2C.java b/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgCastParticleS2C.java index 9ec659b8b6..1b64420ffe 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgCastParticleS2C.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgCastParticleS2C.java @@ -1,5 +1,6 @@ package at.petrak.hexcasting.common.msgs; +import at.petrak.hexcasting.api.HexAPI; import at.petrak.hexcasting.api.casting.ParticleSpray; import at.petrak.hexcasting.api.pigment.FrozenPigment; import at.petrak.hexcasting.client.ClientTickCounter; @@ -7,6 +8,9 @@ import io.netty.buffer.ByteBuf; import net.minecraft.client.Minecraft; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.Mth; import net.minecraft.world.phys.Vec3; @@ -18,47 +22,20 @@ /** * Sent server->client to spray particles everywhere. */ -public record MsgCastParticleS2C(ParticleSpray spray, FrozenPigment colorizer) implements IMessage { - public static final ResourceLocation ID = modLoc("cprtcl"); +public record MsgCastParticleS2C(ParticleSpray spray, FrozenPigment colorizer) implements CustomPacketPayload { + public static final CustomPacketPayload.Type TYPE = new CustomPacketPayload.Type<>(HexAPI.modLoc("cprtcl")); - @Override - public ResourceLocation getFabricId() { - return ID; - } - - public static MsgCastParticleS2C deserialize(ByteBuf buffer) { - var buf = new FriendlyByteBuf(buffer); - var posX = buf.readDouble(); - var posY = buf.readDouble(); - var posZ = buf.readDouble(); - var velX = buf.readDouble(); - var velY = buf.readDouble(); - var velZ = buf.readDouble(); - var fuzziness = buf.readDouble(); - var spread = buf.readDouble(); - var count = buf.readInt(); - var tag = buf.readAnySizeNbt(); - var colorizer = FrozenPigment.fromNBT(tag); - return new MsgCastParticleS2C( - new ParticleSpray(new Vec3(posX, posY, posZ), new Vec3(velX, velY, velZ), fuzziness, spread, count), - colorizer); - } + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ParticleSpray.getSTREAM_CODEC(), MsgCastParticleS2C::spray, + FrozenPigment.STREAM_CODEC, MsgCastParticleS2C::colorizer, + MsgCastParticleS2C::new + ); @Override - public void serialize(FriendlyByteBuf buf) { - buf.writeDouble(this.spray.getPos().x); - buf.writeDouble(this.spray.getPos().y); - buf.writeDouble(this.spray.getPos().z); - buf.writeDouble(this.spray.getVel().x); - buf.writeDouble(this.spray.getVel().y); - buf.writeDouble(this.spray.getVel().z); - buf.writeDouble(this.spray.getFuzziness()); - buf.writeDouble(this.spray.getSpread()); - buf.writeInt(this.spray.getCount()); - buf.writeNbt(this.colorizer.serializeToNBT()); + public Type type() { + return TYPE; } - private static final Random RANDOM = new Random(); // https://math.stackexchange.com/questions/44689/how-to-find-a-random-axis-or-unit-vector-in-3d @@ -69,41 +46,38 @@ private static Vec3 randomInCircle(double maxTh) { } public static void handle(MsgCastParticleS2C msg) { - Minecraft.getInstance().execute(new Runnable() { - @Override - public void run() { - var colProvider = msg.colorizer().getColorProvider(); - for (int i = 0; i < msg.spray().getCount(); i++) { - // For the colors, pick any random time to get a mix of colors + Minecraft.getInstance().execute(() -> { + var colProvider = msg.colorizer().getColorProvider(); + for (int i = 0; i < msg.spray().getCount(); i++) { + // For the colors, pick any random time to get a mix of colors - var offset = randomInCircle(Mth.TWO_PI).normalize() - .scale(RANDOM.nextFloat() * msg.spray().getFuzziness() / 2); - var pos = msg.spray().getPos().add(offset); + var offset = randomInCircle(Mth.TWO_PI).normalize() + .scale(RANDOM.nextFloat() * msg.spray().getFuzziness() / 2); + var pos = msg.spray().getPos().add(offset); - var phi = Math.acos(1.0 - RANDOM.nextDouble() * (1.0 - Math.cos(msg.spray().getSpread()))); - var theta = Math.PI * 2.0 * RANDOM.nextDouble(); - var v = msg.spray().getVel().normalize(); - // pick any old vector to get a vector normal to v with - Vec3 k; - if (v.x == 0.0 && v.y == 0.0) { - // oops, pick a *different* normal - k = new Vec3(1.0, 0.0, 0.0); - } else { - k = v.cross(new Vec3(0.0, 0.0, 1.0)); - } - var velUnlen = v.scale(Math.cos(phi)) - .add(k.scale(Math.sin(phi) * Math.cos(theta))) - .add(v.cross(k).scale(Math.sin(phi) * Math.sin(theta))); - var vel = velUnlen.scale(msg.spray().getVel().length() / 20); + var phi = Math.acos(1.0 - RANDOM.nextDouble() * (1.0 - Math.cos(msg.spray().getSpread()))); + var theta = Math.PI * 2.0 * RANDOM.nextDouble(); + var v = msg.spray().getVel().normalize(); + // pick any old vector to get a vector normal to v with + Vec3 k; + if (v.x == 0.0 && v.y == 0.0) { + // oops, pick a *different* normal + k = new Vec3(1.0, 0.0, 0.0); + } else { + k = v.cross(new Vec3(0.0, 0.0, 1.0)); + } + var velUnlen = v.scale(Math.cos(phi)) + .add(k.scale(Math.sin(phi) * Math.cos(theta))) + .add(v.cross(k).scale(Math.sin(phi) * Math.sin(theta))); + var vel = velUnlen.scale(msg.spray().getVel().length() / 20); - var color = colProvider.getColor(ClientTickCounter.getTotal(), velUnlen); + var color = colProvider.getColor(ClientTickCounter.getTotal(), velUnlen); - Minecraft.getInstance().level.addParticle( - new ConjureParticleOptions(color), - pos.x, pos.y, pos.z, - vel.x, vel.y, vel.z - ); - } + Minecraft.getInstance().level.addParticle( + new ConjureParticleOptions(color), + pos.x, pos.y, pos.z, + vel.x, vel.y, vel.z + ); } }); } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgClearSpiralPatternsS2C.java b/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgClearSpiralPatternsS2C.java index 1f454ba700..ef4d539a6e 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgClearSpiralPatternsS2C.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgClearSpiralPatternsS2C.java @@ -1,46 +1,42 @@ package at.petrak.hexcasting.common.msgs; +import at.petrak.hexcasting.api.HexAPI; +import at.petrak.hexcasting.api.casting.math.HexPattern; import at.petrak.hexcasting.xplat.IClientXplatAbstractions; import io.netty.buffer.ByteBuf; import net.minecraft.client.Minecraft; +import net.minecraft.core.UUIDUtil; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.resources.ResourceLocation; import java.util.UUID; import static at.petrak.hexcasting.api.HexAPI.modLoc; -public record MsgClearSpiralPatternsS2C(UUID playerUUID) implements IMessage { - public static final ResourceLocation ID = modLoc("clr_spi_pats_sc"); +public record MsgClearSpiralPatternsS2C(UUID playerUUID) implements CustomPacketPayload { + public static final CustomPacketPayload.Type TYPE = new CustomPacketPayload.Type<>(HexAPI.modLoc("clr_spi_pats_sc")); - @Override - public ResourceLocation getFabricId() { - return ID; - } - - public static MsgClearSpiralPatternsS2C deserialize(ByteBuf buffer) { - var buf = new FriendlyByteBuf(buffer); - - var player = buf.readUUID(); - - return new MsgClearSpiralPatternsS2C(player); - } + public static final StreamCodec STREAM_CODEC = UUIDUtil.STREAM_CODEC.map( + MsgClearSpiralPatternsS2C::new, + MsgClearSpiralPatternsS2C::playerUUID + ).mapStream(b -> b); @Override - public void serialize(FriendlyByteBuf buf) { - buf.writeUUID(playerUUID); + public CustomPacketPayload.Type type() { + return TYPE; } public static void handle(MsgClearSpiralPatternsS2C self) { - Minecraft.getInstance().execute(new Runnable() { - @Override - public void run() { - var mc = Minecraft.getInstance(); - assert mc.level != null; - var player = mc.level.getPlayerByUUID(self.playerUUID); - var stack = IClientXplatAbstractions.INSTANCE.getClientCastingStack(player); - stack.slowClear(); - } + Minecraft.getInstance().execute(() -> { + var mc = Minecraft.getInstance(); + assert mc.level != null; + var player = mc.level.getPlayerByUUID(self.playerUUID); + var stack = IClientXplatAbstractions.INSTANCE.getClientCastingStack(player); + stack.slowClear(); }); } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgNewSpellPatternC2S.java b/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgNewSpellPatternC2S.java index ce19d966b3..06440b01b6 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgNewSpellPatternC2S.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgNewSpellPatternC2S.java @@ -1,11 +1,16 @@ package at.petrak.hexcasting.common.msgs; +import at.petrak.hexcasting.api.HexAPI; import at.petrak.hexcasting.api.casting.eval.ResolvedPattern; import at.petrak.hexcasting.api.casting.eval.env.StaffCastEnv; import at.petrak.hexcasting.api.casting.math.HexPattern; +import at.petrak.hexcasting.api.pigment.FrozenPigment; import io.netty.buffer.ByteBuf; import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.InteractionHand; @@ -13,43 +18,27 @@ import java.util.ArrayList; import java.util.List; -import static at.petrak.hexcasting.api.HexAPI.modLoc; - /** * Sent client->server when the player finishes drawing a pattern. * Server will send back a {@link MsgNewSpellPatternS2C} packet */ public record MsgNewSpellPatternC2S(InteractionHand handUsed, HexPattern pattern, - List resolvedPatterns) - implements IMessage { - public static final ResourceLocation ID = modLoc("pat_cs"); - - @Override - public ResourceLocation getFabricId() { - return ID; - } - - public static MsgNewSpellPatternC2S deserialize(ByteBuf buffer) { - var buf = new FriendlyByteBuf(buffer); - var hand = buf.readEnum(InteractionHand.class); - var pattern = HexPattern.fromNBT(buf.readNbt()); - - var resolvedPatternsLen = buf.readInt(); - var resolvedPatterns = new ArrayList(resolvedPatternsLen); - for (int i = 0; i < resolvedPatternsLen; i++) { - resolvedPatterns.add(ResolvedPattern.fromNBT(buf.readNbt())); - } - return new MsgNewSpellPatternC2S(hand, pattern, resolvedPatterns); - } + List resolvedPatterns) implements CustomPacketPayload { + public static final CustomPacketPayload.Type TYPE = new CustomPacketPayload.Type<>(HexAPI.modLoc("pat_cs")); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.BOOL.map( + isMain -> isMain ? InteractionHand.MAIN_HAND : InteractionHand.OFF_HAND, + hand -> hand == InteractionHand.MAIN_HAND + ), MsgNewSpellPatternC2S::handUsed, + HexPattern.STREAM_CODEC, MsgNewSpellPatternC2S::pattern, + ResolvedPattern.STREAM_CODEC.apply(ByteBufCodecs.list()), MsgNewSpellPatternC2S::resolvedPatterns, + MsgNewSpellPatternC2S::new + ); @Override - public void serialize(FriendlyByteBuf buf) { - buf.writeEnum(handUsed); - buf.writeNbt(this.pattern.serializeToNBT()); - buf.writeInt(this.resolvedPatterns.size()); - for (var pat : this.resolvedPatterns) { - buf.writeNbt(pat.serializeToNBT()); - } + public Type type() { + return TYPE; } public void handle(MinecraftServer server, ServerPlayer sender) { diff --git a/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgNewSpellPatternS2C.java b/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgNewSpellPatternS2C.java index cadf3dd100..bb0af803ac 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgNewSpellPatternS2C.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgNewSpellPatternS2C.java @@ -1,13 +1,21 @@ package at.petrak.hexcasting.common.msgs; +import at.petrak.hexcasting.api.HexAPI; import at.petrak.hexcasting.api.casting.eval.ExecutionClientView; +import at.petrak.hexcasting.api.casting.eval.ResolvedPattern; import at.petrak.hexcasting.api.casting.eval.ResolvedPatternType; +import at.petrak.hexcasting.api.casting.math.HexPattern; import at.petrak.hexcasting.client.gui.GuiSpellcasting; import at.petrak.hexcasting.common.lib.HexSounds; import io.netty.buffer.ByteBuf; import net.minecraft.client.Minecraft; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.InteractionHand; import java.util.Optional; @@ -16,52 +24,30 @@ /** * Sent server->client when the player finishes casting a spell. */ -public record MsgNewSpellPatternS2C(ExecutionClientView info, int index) implements IMessage { - public static final ResourceLocation ID = modLoc("pat_sc"); +public record MsgNewSpellPatternS2C(ExecutionClientView info, int index) implements CustomPacketPayload { + public static final CustomPacketPayload.Type TYPE = new CustomPacketPayload.Type<>(HexAPI.modLoc("pat_sc")); - @Override - public ResourceLocation getFabricId() { - return ID; - } - - public static MsgNewSpellPatternS2C deserialize(ByteBuf buffer) { - var buf = new FriendlyByteBuf(buffer); - - var isStackEmpty = buf.readBoolean(); - var resolutionType = buf.readEnum(ResolvedPatternType.class); - var index = buf.readInt(); - - var stack = buf.readList(FriendlyByteBuf::readNbt); - var raven = buf.readOptional(FriendlyByteBuf::readNbt).orElse(null); - - return new MsgNewSpellPatternS2C( - new ExecutionClientView(isStackEmpty, resolutionType, stack, raven), index - ); - } + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ExecutionClientView.getSTREAM_CODEC(), MsgNewSpellPatternS2C::info, + ByteBufCodecs.VAR_INT, MsgNewSpellPatternS2C::index, + MsgNewSpellPatternS2C::new + ); @Override - public void serialize(FriendlyByteBuf buf) { - buf.writeBoolean(this.info.isStackClear()); - buf.writeEnum(this.info.getResolutionType()); - buf.writeInt(this.index); - - buf.writeCollection(this.info.getStackDescs(), FriendlyByteBuf::writeNbt); - buf.writeOptional(Optional.ofNullable(this.info.getRavenmind()), FriendlyByteBuf::writeNbt); + public CustomPacketPayload.Type type() { + return TYPE; } public static void handle(MsgNewSpellPatternS2C self) { - Minecraft.getInstance().execute(new Runnable() { - @Override - public void run() { - var mc = Minecraft.getInstance(); - if (self.info().isStackClear()) { - // don't pay attention to the screen, so it also stops when we die - mc.getSoundManager().stop(HexSounds.CASTING_AMBIANCE.getLocation(), null); - } - var screen = Minecraft.getInstance().screen; - if (screen instanceof GuiSpellcasting spellGui) { - spellGui.recvServerUpdate(self.info(), self.index()); - } + Minecraft.getInstance().execute(() -> { + var mc = Minecraft.getInstance(); + if (self.info().isStackClear()) { + // don't pay attention to the screen, so it also stops when we die + mc.getSoundManager().stop(HexSounds.CASTING_AMBIANCE.getLocation(), null); + } + var screen = Minecraft.getInstance().screen; + if (screen instanceof GuiSpellcasting spellGui) { + spellGui.recvServerUpdate(self.info(), self.index()); } }); } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgNewSpiralPatternsS2C.java b/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgNewSpiralPatternsS2C.java index 9c5a02180c..9b1a844353 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgNewSpiralPatternsS2C.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgNewSpiralPatternsS2C.java @@ -1,10 +1,16 @@ package at.petrak.hexcasting.common.msgs; +import at.petrak.hexcasting.api.HexAPI; import at.petrak.hexcasting.api.casting.math.HexPattern; import at.petrak.hexcasting.xplat.IClientXplatAbstractions; import io.netty.buffer.ByteBuf; import net.minecraft.client.Minecraft; +import net.minecraft.core.UUIDUtil; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.resources.ResourceLocation; import java.util.ArrayList; @@ -13,44 +19,30 @@ import static at.petrak.hexcasting.api.HexAPI.modLoc; -public record MsgNewSpiralPatternsS2C(UUID playerUUID, List patterns, int lifetime) implements IMessage { - public static final ResourceLocation ID = modLoc("spi_pats_sc"); +public record MsgNewSpiralPatternsS2C(UUID playerUUID, List patterns, int lifetime) implements CustomPacketPayload { + public static final CustomPacketPayload.Type TYPE = new CustomPacketPayload.Type<>(HexAPI.modLoc("spi_pats_sc")); - @Override - public ResourceLocation getFabricId() { - return ID; - } - - public static MsgNewSpiralPatternsS2C deserialize(ByteBuf buffer) { - var buf = new FriendlyByteBuf(buffer); - - var player = buf.readUUID(); - var patterns = buf.readCollection(ArrayList::new, buff -> HexPattern.fromNBT(buf.readNbt())); - var lifetime = buf.readInt(); - - - return new MsgNewSpiralPatternsS2C(player, patterns, lifetime); - } + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + UUIDUtil.STREAM_CODEC, MsgNewSpiralPatternsS2C::playerUUID, + HexPattern.STREAM_CODEC.apply(ByteBufCodecs.list()), MsgNewSpiralPatternsS2C::patterns, + ByteBufCodecs.VAR_INT, MsgNewSpiralPatternsS2C::lifetime, + MsgNewSpiralPatternsS2C::new + ); @Override - public void serialize(FriendlyByteBuf buf) { - buf.writeUUID(playerUUID); - buf.writeCollection(patterns, (buff, pattern) -> buff.writeNbt(pattern.serializeToNBT())); - buf.writeInt(lifetime); + public CustomPacketPayload.Type type() { + return TYPE; } public static void handle(MsgNewSpiralPatternsS2C self) { - Minecraft.getInstance().execute(new Runnable() { - @Override - public void run() { - var mc = Minecraft.getInstance(); - assert mc.level != null; - var player = mc.level.getPlayerByUUID(self.playerUUID); - var stack = IClientXplatAbstractions.INSTANCE.getClientCastingStack(player); - - for (var pattern : self.patterns) - stack.addPattern(pattern, self.lifetime); - } + Minecraft.getInstance().execute(() -> { + var mc = Minecraft.getInstance(); + assert mc.level != null; + var player = mc.level.getPlayerByUUID(self.playerUUID); + var stack = IClientXplatAbstractions.INSTANCE.getClientCastingStack(player); + + for (var pattern : self.patterns) + stack.addPattern(pattern, self.lifetime); }); } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgNewWallScrollS2C.java b/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgNewWallScrollS2C.java index 67e77248cc..6cdd30003c 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgNewWallScrollS2C.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgNewWallScrollS2C.java @@ -1,59 +1,53 @@ package at.petrak.hexcasting.common.msgs; +import at.petrak.hexcasting.api.HexAPI; import at.petrak.hexcasting.api.utils.HexUtils; import at.petrak.hexcasting.common.entities.EntityWallScroll; +import at.petrak.paucal.api.PaucalCodecs; import net.minecraft.client.Minecraft; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.network.protocol.game.ClientboundAddEntityPacket; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.state.properties.NoteBlockInstrument; import static at.petrak.hexcasting.api.HexAPI.modLoc; // https://github.com/VazkiiMods/Botania/blob/1.18.x/Xplat/src/main/java/vazkii/botania/network/clientbound/PacketSpawnDoppleganger.java public record MsgNewWallScrollS2C(ClientboundAddEntityPacket inner, BlockPos pos, Direction dir, ItemStack scrollItem, - boolean showsStrokeOrder, int blockSize) implements IMessage { - public static final ResourceLocation ID = modLoc("wallscr"); + boolean showsStrokeOrder, int blockSize) implements CustomPacketPayload { + public static final CustomPacketPayload.Type TYPE = new CustomPacketPayload.Type<>(HexAPI.modLoc("wallscr")); - @Override - public ResourceLocation getFabricId() { - return ID; - } + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ClientboundAddEntityPacket.STREAM_CODEC, MsgNewWallScrollS2C::inner, + BlockPos.STREAM_CODEC, MsgNewWallScrollS2C::pos, + Direction.STREAM_CODEC, MsgNewWallScrollS2C::dir, + ItemStack.STREAM_CODEC, MsgNewWallScrollS2C::scrollItem, + ByteBufCodecs.BOOL, MsgNewWallScrollS2C::showsStrokeOrder, + ByteBufCodecs.VAR_INT, MsgNewWallScrollS2C::blockSize, + MsgNewWallScrollS2C::new + ); @Override - public void serialize(FriendlyByteBuf buf) { - inner.write(buf); - buf.writeBlockPos(pos); - buf.writeByte(dir.ordinal()); - buf.writeItem(scrollItem); - buf.writeBoolean(showsStrokeOrder); - buf.writeVarInt(blockSize); - } - - public static MsgNewWallScrollS2C deserialize(FriendlyByteBuf buf) { - var inner = new ClientboundAddEntityPacket(buf); - var pos = buf.readBlockPos(); - var dir = HexUtils.getSafe(Direction.values(), buf.readByte()); - var scroll = buf.readItem(); - var strokeOrder = buf.readBoolean(); - var blockSize = buf.readVarInt(); - return new MsgNewWallScrollS2C(inner, pos, dir, scroll, strokeOrder, blockSize); + public CustomPacketPayload.Type type() { + return TYPE; } public static void handle(MsgNewWallScrollS2C self) { - Minecraft.getInstance().execute(new Runnable() { - @Override - public void run() { - var player = Minecraft.getInstance().player; - if (player != null) { - player.connection.handleAddEntity(self.inner); - var e = player.level().getEntity(self.inner.getId()); - if (e instanceof EntityWallScroll scroll) { - scroll.readSpawnData(self.pos, self.dir, self.scrollItem, self.showsStrokeOrder, - self.blockSize); - } + Minecraft.getInstance().execute(() -> { + var player = Minecraft.getInstance().player; + if (player != null) { + player.connection.handleAddEntity(self.inner); + var e = player.level().getEntity(self.inner.getId()); + if (e instanceof EntityWallScroll scroll) { + scroll.readSpawnData(self.pos, self.dir, self.scrollItem, self.showsStrokeOrder, + self.blockSize); } } }); diff --git a/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgOpenSpellGuiS2C.java b/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgOpenSpellGuiS2C.java index a06e608bdb..f50ed7d26d 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgOpenSpellGuiS2C.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgOpenSpellGuiS2C.java @@ -1,15 +1,26 @@ package at.petrak.hexcasting.common.msgs; +import at.petrak.hexcasting.api.HexAPI; import at.petrak.hexcasting.api.casting.eval.ResolvedPattern; +import at.petrak.hexcasting.api.casting.iota.Iota; +import at.petrak.hexcasting.api.casting.iota.IotaType; +import at.petrak.hexcasting.api.casting.math.HexPattern; import at.petrak.hexcasting.client.gui.GuiSpellcasting; import io.netty.buffer.ByteBuf; import net.minecraft.client.Minecraft; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.ExtraCodecs; import net.minecraft.world.InteractionHand; +import org.jetbrains.annotations.Nullable; import java.util.List; +import java.util.Optional; import static at.petrak.hexcasting.api.HexAPI.modLoc; @@ -17,53 +28,40 @@ * Sent server->client when the player opens the spell gui to request the server provide the current stack. */ public record MsgOpenSpellGuiS2C(InteractionHand hand, List patterns, - List stack, + List stack, + @Nullable CompoundTag ravenmind, int parenCount ) - implements IMessage { - public static final ResourceLocation ID = modLoc("cgui"); + implements CustomPacketPayload { + public static final CustomPacketPayload.Type TYPE = new CustomPacketPayload.Type<>(HexAPI.modLoc("cgui")); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.BOOL.map( + isMain -> isMain ? InteractionHand.MAIN_HAND : InteractionHand.OFF_HAND, + hand -> hand == InteractionHand.MAIN_HAND + ), MsgOpenSpellGuiS2C::hand, + ResolvedPattern.STREAM_CODEC.apply(ByteBufCodecs.list()), MsgOpenSpellGuiS2C::patterns, + IotaType.TYPED_STREAM_CODEC.apply(ByteBufCodecs.list()), MsgOpenSpellGuiS2C::stack, + ByteBufCodecs.optional(ByteBufCodecs.COMPOUND_TAG).map( + opt -> opt.orElse(null), + Optional::ofNullable + ), MsgOpenSpellGuiS2C::ravenmind, + ByteBufCodecs.VAR_INT, MsgOpenSpellGuiS2C::parenCount, + MsgOpenSpellGuiS2C::new + ); @Override - public ResourceLocation getFabricId() { - return ID; - } - - public static MsgOpenSpellGuiS2C deserialize(ByteBuf buffer) { - var buf = new FriendlyByteBuf(buffer); - - var hand = buf.readEnum(InteractionHand.class); - - var patterns = buf.readList(fbb -> ResolvedPattern.fromNBT(fbb.readAnySizeNbt())); - - var stack = buf.readList(FriendlyByteBuf::readNbt); - var raven = buf.readAnySizeNbt(); - - var parenCount = buf.readVarInt(); - - return new MsgOpenSpellGuiS2C(hand, patterns, stack, raven, parenCount); - } - - public void serialize(FriendlyByteBuf buf) { - buf.writeEnum(this.hand); - - buf.writeCollection(this.patterns, (fbb, pat) -> fbb.writeNbt(pat.serializeToNBT())); - - buf.writeCollection(this.stack, FriendlyByteBuf::writeNbt); - buf.writeNbt(this.ravenmind); - - buf.writeVarInt(this.parenCount); + public Type type() { + return TYPE; } public static void handle(MsgOpenSpellGuiS2C msg) { - Minecraft.getInstance().execute(new Runnable() { - @Override - public void run() { - var mc = Minecraft.getInstance(); - mc.setScreen( - new GuiSpellcasting(msg.hand(), msg.patterns(), msg.stack, msg.ravenmind, - msg.parenCount)); - } + Minecraft.getInstance().execute(() -> { + var mc = Minecraft.getInstance(); + mc.setScreen( + new GuiSpellcasting(msg.hand(), msg.patterns(), msg.stack, msg.ravenmind, + msg.parenCount)); }); } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgRecalcWallScrollDisplayS2C.java b/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgRecalcWallScrollDisplayS2C.java index 137c97f534..44ee8f9b21 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgRecalcWallScrollDisplayS2C.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgRecalcWallScrollDisplayS2C.java @@ -1,47 +1,46 @@ package at.petrak.hexcasting.common.msgs; +import at.petrak.hexcasting.api.HexAPI; import at.petrak.hexcasting.common.entities.EntityWallScroll; import io.netty.buffer.ByteBuf; import net.minecraft.client.Minecraft; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.network.protocol.game.ClientboundAddEntityPacket; import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.ItemStack; import static at.petrak.hexcasting.api.HexAPI.modLoc; /** * Sent S->C to have a wall scroll recalculate its pattern, to get readability offset. */ -public record MsgRecalcWallScrollDisplayS2C(int entityId, boolean showStrokeOrder) implements IMessage { - public static final ResourceLocation ID = modLoc("redoscroll"); +public record MsgRecalcWallScrollDisplayS2C(int entityId, boolean showStrokeOrder) implements CustomPacketPayload { + public static final CustomPacketPayload.Type TYPE = new CustomPacketPayload.Type<>(HexAPI.modLoc("redoscroll")); - public static MsgRecalcWallScrollDisplayS2C deserialize(ByteBuf buffer) { - var buf = new FriendlyByteBuf(buffer); - var id = buf.readVarInt(); - var showStrokeOrder = buf.readBoolean(); - return new MsgRecalcWallScrollDisplayS2C(id, showStrokeOrder); - } - - @Override - public void serialize(FriendlyByteBuf buf) { - buf.writeVarInt(entityId); - buf.writeBoolean(showStrokeOrder); - } + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.VAR_INT, MsgRecalcWallScrollDisplayS2C::entityId, + ByteBufCodecs.BOOL, MsgRecalcWallScrollDisplayS2C::showStrokeOrder, + MsgRecalcWallScrollDisplayS2C::new + ); @Override - public ResourceLocation getFabricId() { - return ID; + public CustomPacketPayload.Type type() { + return TYPE; } public static void handle(MsgRecalcWallScrollDisplayS2C msg) { - Minecraft.getInstance().execute(new Runnable() { - @Override - public void run() { - var mc = Minecraft.getInstance(); - var entity = mc.level.getEntity(msg.entityId); - if (entity instanceof EntityWallScroll scroll - && scroll.getShowsStrokeOrder() != msg.showStrokeOrder) { - scroll.recalculateDisplay(); - } + Minecraft.getInstance().execute(() -> { + var mc = Minecraft.getInstance(); + var entity = mc.level.getEntity(msg.entityId); + if (entity instanceof EntityWallScroll scroll + && scroll.getShowsStrokeOrder() != msg.showStrokeOrder) { + scroll.recalculateDisplay(); } }); } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgShiftScrollC2S.java b/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgShiftScrollC2S.java index e1f4d354a6..fb487a0c96 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgShiftScrollC2S.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/msgs/MsgShiftScrollC2S.java @@ -1,16 +1,25 @@ package at.petrak.hexcasting.common.msgs; +import at.petrak.hexcasting.api.HexAPI; +import at.petrak.hexcasting.api.casting.eval.ResolvedPattern; import at.petrak.hexcasting.api.casting.iota.IotaType; +import at.petrak.hexcasting.api.casting.math.HexPattern; import at.petrak.hexcasting.api.utils.NBTHelper; import at.petrak.hexcasting.common.items.storage.ItemAbacus; import at.petrak.hexcasting.common.items.storage.ItemSpellbook; +import at.petrak.hexcasting.common.lib.HexDataComponents; import at.petrak.hexcasting.common.lib.HexItems; import at.petrak.hexcasting.common.lib.HexSounds; import io.netty.buffer.ByteBuf; import net.minecraft.ChatFormatting; +import net.minecraft.core.component.DataComponents; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; @@ -25,30 +34,21 @@ * or scrolls in the spellcasting UI. */ public record MsgShiftScrollC2S(double mainHandDelta, double offHandDelta, boolean isCtrl, boolean invertSpellbook, - boolean invertAbacus) implements IMessage { - public static final ResourceLocation ID = modLoc("scroll"); + boolean invertAbacus) implements CustomPacketPayload { + public static final CustomPacketPayload.Type TYPE = new CustomPacketPayload.Type<>(HexAPI.modLoc("scroll")); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.DOUBLE, MsgShiftScrollC2S::mainHandDelta, + ByteBufCodecs.DOUBLE, MsgShiftScrollC2S::offHandDelta, + ByteBufCodecs.BOOL, MsgShiftScrollC2S::isCtrl, + ByteBufCodecs.BOOL, MsgShiftScrollC2S::invertSpellbook, + ByteBufCodecs.BOOL, MsgShiftScrollC2S::invertAbacus, + MsgShiftScrollC2S::new + ); @Override - public ResourceLocation getFabricId() { - return ID; - } - - public static MsgShiftScrollC2S deserialize(ByteBuf buffer) { - var buf = new FriendlyByteBuf(buffer); - var mainHandDelta = buf.readDouble(); - var offHandDelta = buf.readDouble(); - var isCtrl = buf.readBoolean(); - var invertSpellbook = buf.readBoolean(); - var invertAbacus = buf.readBoolean(); - return new MsgShiftScrollC2S(mainHandDelta, offHandDelta, isCtrl, invertSpellbook, invertAbacus); - } - - public void serialize(FriendlyByteBuf buf) { - buf.writeDouble(this.mainHandDelta); - buf.writeDouble(this.offHandDelta); - buf.writeBoolean(this.isCtrl); - buf.writeBoolean(this.invertSpellbook); - buf.writeBoolean(this.invertAbacus); + public Type type() { + return TYPE; } public void handle(MinecraftServer server, ServerPlayer sender) { @@ -82,19 +82,19 @@ private void spellbook(ServerPlayer sender, InteractionHand hand, ItemStack stac var sealed = ItemSpellbook.isSealed(stack); MutableComponent component; - if (hand == InteractionHand.OFF_HAND && stack.hasCustomHoverName()) { + if (hand == InteractionHand.OFF_HAND && stack.has(DataComponents.CUSTOM_NAME)) { if (sealed) { component = Component.translatable("hexcasting.tooltip.spellbook.page_with_name.sealed", Component.literal(String.valueOf(newIdx)).withStyle(ChatFormatting.WHITE), Component.literal(String.valueOf(len)).withStyle(ChatFormatting.WHITE), - Component.literal("").withStyle(stack.getRarity().color, ChatFormatting.ITALIC) + Component.literal("").withStyle(stack.getRarity().getStyleModifier()).withStyle(ChatFormatting.ITALIC) .append(stack.getHoverName()), Component.translatable("hexcasting.tooltip.spellbook.sealed").withStyle(ChatFormatting.GOLD)); } else { component = Component.translatable("hexcasting.tooltip.spellbook.page_with_name", Component.literal(String.valueOf(newIdx)).withStyle(ChatFormatting.WHITE), Component.literal(String.valueOf(len)).withStyle(ChatFormatting.WHITE), - Component.literal("").withStyle(stack.getRarity().color, ChatFormatting.ITALIC) + Component.literal("").withStyle(stack.getRarity().getStyleModifier()).withStyle(ChatFormatting.ITALIC) .append(stack.getHoverName())); } @@ -120,7 +120,9 @@ private void abacus(ServerPlayer sender, InteractionHand hand, ItemStack stack, } var increase = delta < 0; - double num = NBTHelper.getDouble(stack, ItemAbacus.TAG_VALUE); + Double num = stack.get(HexDataComponents.ABACUS_VALUE); + if(num == null) + num = 0.0; double shiftDelta; float pitch; @@ -135,16 +137,16 @@ private void abacus(ServerPlayer sender, InteractionHand hand, ItemStack stack, int scale = Math.max((int) Math.floor(Math.abs(delta)), 1); num += scale * shiftDelta * (increase ? 1 : -1); - NBTHelper.putDouble(stack, ItemAbacus.TAG_VALUE, num); + stack.set(HexDataComponents.ABACUS_VALUE, num); pitch *= (increase ? 1.05f : 0.95f); pitch += (Math.random() - 0.5) * 0.1; sender.level().playSound(null, sender.getX(), sender.getY(), sender.getZ(), HexSounds.ABACUS, SoundSource.PLAYERS, 0.5f, pitch); - var datumTag = HexItems.ABACUS.readIotaTag(stack); - if (datumTag != null) { - var popup = IotaType.getDisplay(datumTag); + var datum = HexItems.ABACUS.readIota(stack); + if (datum != null) { + var popup = datum.display(); sender.displayClientMessage( Component.translatable("hexcasting.tooltip.abacus", popup).withStyle(ChatFormatting.GREEN), true); } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/particles/ConjureParticleOptions.java b/Common/src/main/java/at/petrak/hexcasting/common/particles/ConjureParticleOptions.java index 79df382994..f5696edbe4 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/particles/ConjureParticleOptions.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/particles/ConjureParticleOptions.java @@ -4,10 +4,14 @@ import com.mojang.brigadier.StringReader; import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.core.particles.ParticleOptions; import net.minecraft.core.particles.ParticleType; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; import java.util.Locale; @@ -17,50 +21,32 @@ public ParticleType getType() { return HexParticles.CONJURE_PARTICLE; } - @Override - public void writeToNetwork(FriendlyByteBuf buf) { - buf.writeInt(this.color); - } - - @Override - public String writeToString() { - return String.format(Locale.ROOT, "%s %s", this.color); - } - - public static final Deserializer DESERIALIZER = new Deserializer<>() { - @Override - public ConjureParticleOptions fromCommand(ParticleType type, - StringReader reader) throws CommandSyntaxException { - - reader.expect(' '); - var color = reader.readInt(); - return new ConjureParticleOptions(color); - } - - @Override - public ConjureParticleOptions fromNetwork(ParticleType type, - FriendlyByteBuf buf) { - var col = buf.readInt(); - return new ConjureParticleOptions(col); - } - }; - public static class Type extends ParticleType { public Type(boolean pOverrideLimiter) { - super(pOverrideLimiter, DESERIALIZER); + super(pOverrideLimiter); } - public static final Codec CODEC = RecordCodecBuilder.create( + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec( instance -> instance.group( Codec.INT.fieldOf("color") .forGetter((ConjureParticleOptions o) -> o.color) ) .apply(instance, ConjureParticleOptions::new) ); + public static final StreamCodec STREAM_CODEC = + StreamCodec.composite( + ByteBufCodecs.VAR_INT, ConjureParticleOptions::color, + ConjureParticleOptions::new + ); @Override - public Codec codec() { + public MapCodec codec() { return CODEC; } + + @Override + public StreamCodec streamCodec() { + return STREAM_CODEC; + } } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/recipe/BrainsweepRecipe.java b/Common/src/main/java/at/petrak/hexcasting/common/recipe/BrainsweepRecipe.java index 8f6db1efb0..e6e00fb988 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/recipe/BrainsweepRecipe.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/recipe/BrainsweepRecipe.java @@ -1,18 +1,21 @@ package at.petrak.hexcasting.common.recipe; -import at.petrak.hexcasting.common.recipe.ingredient.StateIngredient; -import at.petrak.hexcasting.common.recipe.ingredient.StateIngredientHelper; +import at.petrak.hexcasting.common.recipe.ingredient.state.StateIngredient; +import at.petrak.hexcasting.common.recipe.ingredient.state.StateIngredients; import at.petrak.hexcasting.common.recipe.ingredient.brainsweep.BrainsweepeeIngredient; -import com.google.gson.JsonObject; -import net.minecraft.core.RegistryAccess; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.resources.ResourceLocation; +import at.petrak.hexcasting.common.recipe.ingredient.brainsweep.BrainsweepeeIngredients; +import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.core.HolderLookup; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.server.level.ServerLevel; -import net.minecraft.util.GsonHelper; -import net.minecraft.world.Container; import net.minecraft.world.entity.Entity; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.Recipe; +import net.minecraft.world.item.crafting.RecipeInput; import net.minecraft.world.item.crafting.RecipeSerializer; import net.minecraft.world.item.crafting.RecipeType; import net.minecraft.world.level.Level; @@ -23,21 +26,15 @@ // God I am a horrible person public record BrainsweepRecipe( - ResourceLocation id, StateIngredient blockIn, BrainsweepeeIngredient entityIn, long mediaCost, BlockState result -) implements Recipe { +) implements Recipe { public boolean matches(BlockState blockIn, Entity victim, ServerLevel level) { return this.blockIn.test(blockIn) && this.entityIn.test(victim, level); } - @Override - public ResourceLocation getId() { - return id; - } - @Override public RecipeType getType() { return HexRecipeStuffRegistry.BRAINSWEEP_TYPE; @@ -51,12 +48,12 @@ public RecipeSerializer getSerializer() { // in order to get this to be a "Recipe" we need to do a lot of bending-over-backwards // to get the implementation to be satisfied even though we never use it @Override - public boolean matches(Container pContainer, Level pLevel) { + public boolean matches(RecipeInput input, Level level) { return false; } @Override - public ItemStack assemble(Container pContainer, RegistryAccess access) { + public ItemStack assemble(RecipeInput input, HolderLookup.Provider registries) { return ItemStack.EMPTY; } @@ -66,7 +63,7 @@ public boolean canCraftInDimensions(int pWidth, int pHeight) { } @Override - public ItemStack getResultItem(RegistryAccess registryAccess) { + public ItemStack getResultItem(HolderLookup.Provider registries) { return ItemStack.EMPTY.copy(); } @@ -84,30 +81,31 @@ public static BlockState copyProperties(BlockState original, BlockState copyTo) } public static class Serializer extends RecipeSerializerBase { - @Override - public @NotNull BrainsweepRecipe fromJson(ResourceLocation recipeID, JsonObject json) { - var blockIn = StateIngredientHelper.deserialize(GsonHelper.getAsJsonObject(json, "blockIn")); - var villagerIn = BrainsweepeeIngredient.deserialize(GsonHelper.getAsJsonObject(json, "entityIn")); - var cost = GsonHelper.getAsInt(json, "cost"); - var result = StateIngredientHelper.readBlockState(GsonHelper.getAsJsonObject(json, "result")); - return new BrainsweepRecipe(recipeID, blockIn, villagerIn, cost, result); - } + public static MapCodec CODEC = RecordCodecBuilder.mapCodec(inst -> + inst.group( + StateIngredients.TYPED_CODEC.fieldOf("blockIn").forGetter(BrainsweepRecipe::blockIn), + BrainsweepeeIngredients.TYPED_CODEC.fieldOf("entityIn").forGetter(BrainsweepRecipe::entityIn), + Codec.LONG.fieldOf("cost").forGetter(BrainsweepRecipe::mediaCost), + BlockState.CODEC.fieldOf("result").forGetter(BrainsweepRecipe::result) + ).apply(inst, BrainsweepRecipe::new) + ); + public static StreamCodec STREAM_CODEC = StreamCodec.composite( + StateIngredients.TYPED_STREAM_CODEC, BrainsweepRecipe::blockIn, + BrainsweepeeIngredients.TYPED_STREAM_CODEC, BrainsweepRecipe::entityIn, + ByteBufCodecs.VAR_LONG, BrainsweepRecipe::mediaCost, + ByteBufCodecs.VAR_INT, (recipe) -> Block.getId(recipe.result), + (state, ent, cost, stateId) -> + new BrainsweepRecipe(state, ent, cost, Block.stateById(stateId)) + ); @Override - public void toNetwork(FriendlyByteBuf buf, BrainsweepRecipe recipe) { - recipe.blockIn.write(buf); - recipe.entityIn.wrapWrite(buf); - buf.writeVarLong(recipe.mediaCost); - buf.writeVarInt(Block.getId(recipe.result)); + public @NotNull MapCodec codec() { + return CODEC; } @Override - public @NotNull BrainsweepRecipe fromNetwork(ResourceLocation recipeID, FriendlyByteBuf buf) { - var blockIn = StateIngredientHelper.read(buf); - var brainsweepeeIn = BrainsweepeeIngredient.read(buf); - var cost = buf.readVarLong(); - var result = Block.stateById(buf.readVarInt()); - return new BrainsweepRecipe(recipeID, blockIn, brainsweepeeIn, cost, result); + public @NotNull StreamCodec streamCodec() { + return STREAM_CODEC; } } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/recipe/SealSpellbookRecipe.java b/Common/src/main/java/at/petrak/hexcasting/common/recipe/SealSpellbookRecipe.java index 570d6631be..52797baf6c 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/recipe/SealSpellbookRecipe.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/recipe/SealSpellbookRecipe.java @@ -1,19 +1,18 @@ package at.petrak.hexcasting.common.recipe; -import at.petrak.hexcasting.api.item.IotaHolderItem; -import at.petrak.hexcasting.api.utils.NBTHelper; import at.petrak.hexcasting.common.items.storage.ItemSpellbook; +import at.petrak.hexcasting.common.lib.HexDataComponents; import at.petrak.hexcasting.common.lib.HexItems; import at.petrak.hexcasting.xplat.IXplatAbstractions; +import net.minecraft.core.HolderLookup; import net.minecraft.core.NonNullList; -import net.minecraft.core.RegistryAccess; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.inventory.CraftingContainer; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.item.crafting.*; import org.jetbrains.annotations.NotNull; +import java.util.Optional; + public class SealSpellbookRecipe extends ShapelessRecipe { public static final SimpleCraftingRecipeSerializer SERIALIZER = new SimpleCraftingRecipeSerializer<>(SealSpellbookRecipe::new); @@ -21,7 +20,7 @@ public class SealSpellbookRecipe extends ShapelessRecipe { private static ItemStack getSealedStack() { ItemStack output = new ItemStack(HexItems.SPELLBOOK); ItemSpellbook.setSealed(output, true); - NBTHelper.putString(output, IotaHolderItem.TAG_OVERRIDE_VISUALLY, "any"); + output.set(HexDataComponents.VISUAL_OVERRIDE, Optional.empty()); return output; } @@ -32,15 +31,15 @@ private static NonNullList createIngredients() { return ingredients; } - public SealSpellbookRecipe(ResourceLocation id, CraftingBookCategory category) { - super(id, "", category, getSealedStack(), createIngredients()); + public SealSpellbookRecipe(CraftingBookCategory category) { + super("", category, getSealedStack(), createIngredients()); } @Override - public @NotNull ItemStack assemble(CraftingContainer inv, RegistryAccess access) { + public @NotNull ItemStack assemble(CraftingInput inv, HolderLookup.RegistryLookup.@NotNull Provider registryProvider) { ItemStack out = ItemStack.EMPTY; - for (int i = 0; i < inv.getContainerSize(); i++) { + for (int i = 0; i < inv.size(); i++) { var stack = inv.getItem(i); if (stack.is(HexItems.SPELLBOOK)) { out = stack.copy(); diff --git a/Common/src/main/java/at/petrak/hexcasting/common/recipe/SealThingsRecipe.java b/Common/src/main/java/at/petrak/hexcasting/common/recipe/SealThingsRecipe.java index 365d68fe59..0da1e86001 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/recipe/SealThingsRecipe.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/recipe/SealThingsRecipe.java @@ -3,16 +3,15 @@ import at.petrak.hexcasting.api.mod.HexTags; import at.petrak.hexcasting.common.items.storage.ItemFocus; import at.petrak.hexcasting.common.items.storage.ItemSpellbook; +import at.petrak.hexcasting.common.lib.HexDataComponents; import at.petrak.hexcasting.common.lib.HexItems; +import net.minecraft.core.HolderLookup; import net.minecraft.core.RegistryAccess; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.StringRepresentable; import net.minecraft.world.inventory.CraftingContainer; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.crafting.CraftingBookCategory; -import net.minecraft.world.item.crafting.CustomRecipe; -import net.minecraft.world.item.crafting.RecipeSerializer; -import net.minecraft.world.item.crafting.SimpleCraftingRecipeSerializer; +import net.minecraft.world.item.crafting.*; import net.minecraft.world.level.Level; import org.jetbrains.annotations.NotNull; @@ -26,8 +25,8 @@ public class SealThingsRecipe extends CustomRecipe { public static final SimpleCraftingRecipeSerializer SPELLBOOK_SERIALIZER = new SimpleCraftingRecipeSerializer<>(SealThingsRecipe::spellbook); - public SealThingsRecipe(ResourceLocation id, CraftingBookCategory category, Sealee sealee) { - super(id, category); + public SealThingsRecipe(CraftingBookCategory category, Sealee sealee) { + super(category); this.sealee = sealee; } @@ -38,11 +37,11 @@ public boolean canCraftInDimensions(int width, int height) { } @Override - public boolean matches(CraftingContainer container, Level level) { + public boolean matches(CraftingInput container, Level level) { boolean foundComb = false; boolean foundSealee = false; - for (int i = 0; i < container.getContainerSize(); i++) { + for (int i = 0; i < container.size(); i++) { var stack = container.getItem(i); if (this.sealee.isCorrectSealee(stack)) { if (foundSealee) return false; @@ -57,10 +56,10 @@ public boolean matches(CraftingContainer container, Level level) { } @Override - public ItemStack assemble(CraftingContainer inv, RegistryAccess registryAccess) { + public @NotNull ItemStack assemble(CraftingInput inv, HolderLookup.RegistryLookup.@NotNull Provider registryProvider) { ItemStack sealee = ItemStack.EMPTY; - for (int i = 0; i < inv.getContainerSize(); i++) { + for (int i = 0; i < inv.size(); i++) { var stack = inv.getItem(i); if (this.sealee.isCorrectSealee(stack)) { sealee = stack.copy(); @@ -84,12 +83,12 @@ public ItemStack assemble(CraftingContainer inv, RegistryAccess registryAccess) }; } - public static SealThingsRecipe focus(ResourceLocation id, CraftingBookCategory category) { - return new SealThingsRecipe(id, category, Sealee.FOCUS); + public static SealThingsRecipe focus(CraftingBookCategory category) { + return new SealThingsRecipe(category, Sealee.FOCUS); } - public static SealThingsRecipe spellbook(ResourceLocation id, CraftingBookCategory category) { - return new SealThingsRecipe(id, category, Sealee.SPELLBOOK); + public static SealThingsRecipe spellbook(CraftingBookCategory category) { + return new SealThingsRecipe(category, Sealee.SPELLBOOK); } public enum Sealee implements StringRepresentable { @@ -104,10 +103,10 @@ public String getSerializedName() { public boolean isCorrectSealee(ItemStack stack) { return switch (this) { case FOCUS -> stack.is(HexItems.FOCUS) - && HexItems.FOCUS.readIotaTag(stack) != null + && stack.has(HexDataComponents.IOTA) && !ItemFocus.isSealed(stack); case SPELLBOOK -> stack.is(HexItems.SPELLBOOK) - && HexItems.SPELLBOOK.readIotaTag(stack) != null + && HexItems.SPELLBOOK.readIota(stack) != null && !ItemSpellbook.isSealed(stack); }; } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/StateIngredientHelper.java b/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/StateIngredientHelper.java deleted file mode 100644 index 97e09d9d36..0000000000 --- a/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/StateIngredientHelper.java +++ /dev/null @@ -1,167 +0,0 @@ -package at.petrak.hexcasting.common.recipe.ingredient; - -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.mojang.serialization.Dynamic; -import com.mojang.serialization.JsonOps; -import net.minecraft.core.Registry; -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.NbtOps; -import net.minecraft.nbt.NbtUtils; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.tags.TagKey; -import net.minecraft.util.GsonHelper; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import java.util.*; - -public class StateIngredientHelper { - public static StateIngredient of(Block block) { - return new StateIngredientBlock(block); - } - - public static StateIngredient of(BlockState state) { - return new StateIngredientBlockState(state); - } - - public static StateIngredient of(TagKey tag) { - return of(tag.location()); - } - - public static StateIngredient of(ResourceLocation id) { - return new StateIngredientTag(id); - } - - public static StateIngredient of(Collection blocks) { - return new StateIngredientBlocks(blocks); - } - - public static StateIngredient tagExcluding(TagKey tag, StateIngredient... excluded) { - return new StateIngredientTagExcluding(tag.location(), List.of(excluded)); - } - - public static StateIngredient deserialize(JsonObject object) { - switch (GsonHelper.getAsString(object, "type")) { - case "tag": - return new StateIngredientTag(new ResourceLocation(GsonHelper.getAsString(object, "tag"))); - case "block": - return new StateIngredientBlock( - BuiltInRegistries.BLOCK.get(new ResourceLocation(GsonHelper.getAsString(object, "block")))); - case "state": - return new StateIngredientBlockState(readBlockState(object)); - case "blocks": - List blocks = new ArrayList<>(); - for (JsonElement element : GsonHelper.getAsJsonArray(object, "blocks")) { - blocks.add(BuiltInRegistries.BLOCK.get(new ResourceLocation(element.getAsString()))); - } - return new StateIngredientBlocks(blocks); - case "tag_excluding": - ResourceLocation tag = new ResourceLocation(GsonHelper.getAsString(object, "tag")); - List ingr = new ArrayList<>(); - for (JsonElement element : GsonHelper.getAsJsonArray(object, "exclude")) { - ingr.add(deserialize(GsonHelper.convertToJsonObject(element, "exclude entry"))); - } - return new StateIngredientTagExcluding(tag, ingr); - default: - throw new JsonParseException("Unknown type!"); - } - } - - /** - * Deserializes a state ingredient, but removes air from its data, - * and returns null if the ingredient only matched air. - */ - @Nullable - public static StateIngredient tryDeserialize(JsonObject object) { - StateIngredient ingr = deserialize(object); - if (ingr instanceof StateIngredientTag sit) { - if (sit.resolve().findAny().isEmpty()) { - return null; - } - return ingr; - } - if (ingr instanceof StateIngredientBlock || ingr instanceof StateIngredientBlockState) { - if (ingr.test(Blocks.AIR.defaultBlockState())) { - return null; - } - } else if (ingr instanceof StateIngredientBlocks sib) { - Collection blocks = sib.blocks; - List list = new ArrayList<>(blocks); - if (list.removeIf(b -> b == Blocks.AIR)) { - if (list.size() == 0) { - return null; - } - return of(list); - } - } - return ingr; - } - - public static StateIngredient read(FriendlyByteBuf buffer) { - switch (buffer.readVarInt()) { - case 0: - int count = buffer.readVarInt(); - Set set = new HashSet<>(); - for (int i = 0; i < count; i++) { - int id = buffer.readVarInt(); - Block block = BuiltInRegistries.BLOCK.byId(id); - set.add(block); - } - return new StateIngredientBlocks(set); - case 1: - return new StateIngredientBlock(BuiltInRegistries.BLOCK.byId(buffer.readVarInt())); - case 2: - return new StateIngredientBlockState(Block.stateById(buffer.readVarInt())); - default: - throw new IllegalArgumentException("Unknown input discriminator!"); - } - } - - /** - * Writes data about the block state to the provided json object. - */ - public static JsonObject serializeBlockState(BlockState state) { - CompoundTag nbt = NbtUtils.writeBlockState(state); - renameTag(nbt, "Name", "name"); - renameTag(nbt, "Properties", "properties"); - Dynamic dyn = new Dynamic<>(NbtOps.INSTANCE, nbt); - return dyn.convert(JsonOps.INSTANCE).getValue().getAsJsonObject(); - } - - /** - * Reads the block state from the provided json object. - */ - public static BlockState readBlockState(JsonObject object) { - CompoundTag nbt = (CompoundTag) new Dynamic<>(JsonOps.INSTANCE, object).convert(NbtOps.INSTANCE).getValue(); - renameTag(nbt, "name", "Name"); - renameTag(nbt, "properties", "Properties"); - String name = nbt.getString("Name"); - ResourceLocation id = ResourceLocation.tryParse(name); - if (id == null || !BuiltInRegistries.BLOCK.getOptional(id).isPresent()) { - throw new IllegalArgumentException("Invalid or unknown block ID: " + name); - } - return NbtUtils.readBlockState(BuiltInRegistries.BLOCK.asLookup(), nbt); - } - - @Deprecated - @Nonnull - public static List toStackList(StateIngredient input) { - return input.getDisplayedStacks(); - } - - private static void renameTag(CompoundTag tag, String from, String to) { - var t = tag.get(from); - if (t != null) { - tag.remove(from); - tag.put(to, t); - } - } -} \ No newline at end of file diff --git a/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/brainsweep/BrainsweepeeIngredient.java b/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/brainsweep/BrainsweepeeIngredient.java index 6e777cc2d0..16cc965a18 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/brainsweep/BrainsweepeeIngredient.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/brainsweep/BrainsweepeeIngredient.java @@ -21,21 +21,15 @@ // // .equals must make sense public abstract class BrainsweepeeIngredient { + + public abstract BrainsweepeeIngredientType getType(); + public abstract boolean test(Entity entity, ServerLevel level); public abstract Component getName(); public abstract List getTooltip(boolean advanced); - public abstract JsonObject serialize(); - - public void wrapWrite(FriendlyByteBuf buf) { - buf.writeEnum(this.ingrType()); - this.write(buf); - } - - public abstract void write(FriendlyByteBuf buf); - /** * For the benefit of showing to the client, return an example of the entity. *

@@ -44,41 +38,6 @@ public void wrapWrite(FriendlyByteBuf buf) { @Nullable public abstract Entity exampleEntity(Level level); - public abstract Type ingrType(); - - public abstract String getSomeKindOfReasonableIDForEmi(); - - public static BrainsweepeeIngredient read(FriendlyByteBuf buf) { - var type = buf.readEnum(Type.class); - return switch (type) { - case VILLAGER -> VillagerIngredient.read(buf); - case ENTITY_TYPE -> EntityTypeIngredient.read(buf); - case ENTITY_TAG -> EntityTagIngredient.read(buf); - }; - } - - public static BrainsweepeeIngredient deserialize(JsonObject json) { - var typestr = GsonHelper.getAsString(json, "type"); - var type = Type.valueOf(typestr.toUpperCase(Locale.ROOT)); - return switch (type) { - case VILLAGER -> VillagerIngredient.deserialize(json); - case ENTITY_TYPE -> EntityTypeIngredient.deserialize(json); - case ENTITY_TAG -> EntityTagIngredient.deserialize(json); - }; - } - - // TODO: make this a registry? - public enum Type implements StringRepresentable { - VILLAGER, - ENTITY_TYPE, - ENTITY_TAG; - - @Override - public String getSerializedName() { - return this.name().toLowerCase(Locale.ROOT); - } - } - public static Component getModNameComponent(String namespace) { String mod = IXplatAbstractions.INSTANCE.getModName(namespace); return Component.literal(mod).withStyle(ChatFormatting.BLUE, ChatFormatting.ITALIC); diff --git a/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/brainsweep/BrainsweepeeIngredientType.java b/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/brainsweep/BrainsweepeeIngredientType.java new file mode 100644 index 0000000000..1b493d7141 --- /dev/null +++ b/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/brainsweep/BrainsweepeeIngredientType.java @@ -0,0 +1,12 @@ +package at.petrak.hexcasting.common.recipe.ingredient.brainsweep; + +import com.mojang.serialization.MapCodec; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; + +public interface BrainsweepeeIngredientType { + + MapCodec codec(); + + StreamCodec streamCodec(); +} diff --git a/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/brainsweep/BrainsweepeeIngredients.java b/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/brainsweep/BrainsweepeeIngredients.java new file mode 100644 index 0000000000..7ad77853aa --- /dev/null +++ b/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/brainsweep/BrainsweepeeIngredients.java @@ -0,0 +1,100 @@ +package at.petrak.hexcasting.common.recipe.ingredient.brainsweep; + +import at.petrak.hexcasting.api.HexAPI; +import at.petrak.hexcasting.common.lib.HexRegistries; +import at.petrak.hexcasting.xplat.IXplatAbstractions; +import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.chat.Component; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.tags.TagKey; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.npc.VillagerProfession; +import net.minecraft.world.entity.npc.VillagerType; +import net.minecraft.world.level.Level; +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.function.BiConsumer; + +public class BrainsweepeeIngredients { + public static final Codec TYPED_CODEC = Codec.lazyInitialized(() -> IXplatAbstractions.INSTANCE + .getBrainsweepeeIngredientRegistry() + .byNameCodec() + .dispatch("type", BrainsweepeeIngredient::getType, BrainsweepeeIngredientType::codec)); + public static final StreamCodec TYPED_STREAM_CODEC = ByteBufCodecs + .registry(HexRegistries.BRAINSWEEPEE_INGREDIENT) + .dispatch(BrainsweepeeIngredient::getType, BrainsweepeeIngredientType::streamCodec); + + public static final BrainsweepeeIngredientType ENTITY_TYPE = new EntityTypeIngredient.Type(); + public static final BrainsweepeeIngredientType TAG = new EntityTagIngredient.Type(); + public static final BrainsweepeeIngredientType VILLAGER = new VillagerIngredient.Type(); + + public static final BrainsweepeeIngredientType NONE_TYPE = new BrainsweepeeIngredientType<>() { + @Override + public MapCodec codec() { + return MapCodec.unit(NONE); + } + + @Override + public StreamCodec streamCodec() { + return StreamCodec.unit(NONE); + } + }; + + public static final BrainsweepeeIngredient NONE = new BrainsweepeeIngredient() { + + @Override + public BrainsweepeeIngredientType getType() { + return NONE_TYPE; + } + + @Override + public boolean test(Entity entity, ServerLevel level) { + return false; + } + + @Override + public Component getName() { + return Component.literal("none"); + } + + @Override + public List getTooltip(boolean advanced) { + return List.of(); + } + + @Override + public @Nullable Entity exampleEntity(Level level) { + return null; + } + }; + + public static void register(BiConsumer, ResourceLocation> r) { + r.accept(NONE_TYPE, HexAPI.modLoc("none")); + r.accept(ENTITY_TYPE, HexAPI.modLoc("entity_type")); + r.accept(TAG, HexAPI.modLoc("entity_tag")); + r.accept(VILLAGER, HexAPI.modLoc("villager")); + } + + public static BrainsweepeeIngredient of(EntityType entityType) { + return new EntityTypeIngredient(entityType); + } + + public static BrainsweepeeIngredient of(TagKey> tagKey) { + return new EntityTagIngredient(tagKey); + } + + public static BrainsweepeeIngredient of( + @Nullable VillagerProfession profession, + @Nullable VillagerType biome, + int minLevel + ) { + return new VillagerIngredient(profession, biome, minLevel); + } +} diff --git a/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/brainsweep/EntityTagIngredient.java b/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/brainsweep/EntityTagIngredient.java index cb6b0a0912..978b0d4cce 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/brainsweep/EntityTagIngredient.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/brainsweep/EntityTagIngredient.java @@ -1,17 +1,17 @@ package at.petrak.hexcasting.common.recipe.ingredient.brainsweep; -import com.google.gson.JsonObject; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.ChatFormatting; import net.minecraft.client.resources.language.I18n; -import net.minecraft.core.Registry; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.Registries; -import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.chat.Component; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerLevel; import net.minecraft.tags.TagKey; -import net.minecraft.util.GsonHelper; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; import net.minecraft.world.level.Level; @@ -27,6 +27,15 @@ public EntityTagIngredient(TagKey> tag) { this.entityTypeTag = tag; } + @Override + public BrainsweepeeIngredientType getType() { + return BrainsweepeeIngredients.TAG; + } + + public TagKey> getTag() { + return entityTypeTag; + } + @Override public boolean test(Entity entity, ServerLevel level) { return entity.getType().is(this.entityTypeTag); @@ -79,49 +88,6 @@ public Entity exampleEntity(Level level) { } } - @Override - public JsonObject serialize() { - var obj = new JsonObject(); - obj.addProperty("type", Type.ENTITY_TAG.getSerializedName()); - - obj.addProperty("tag", this.entityTypeTag.location().toString()); - - return obj; - } - - @Override - public void write(FriendlyByteBuf buf) { - buf.writeResourceLocation(this.entityTypeTag.location()); - } - - public static EntityTagIngredient deserialize(JsonObject obj) { - var tagLoc = ResourceLocation.tryParse(GsonHelper.getAsString(obj, "tag")); - if (tagLoc == null) { - throw new IllegalArgumentException("unknown tag " + obj); - } - var type = TagKey.create(Registries.ENTITY_TYPE, tagLoc); - return new EntityTagIngredient(type); - } - - public static EntityTagIngredient read(FriendlyByteBuf buf) { - var typeLoc = buf.readResourceLocation(); - var type = TagKey.create(Registries.ENTITY_TYPE, typeLoc); - return new EntityTagIngredient(type); - } - - @Override - public Type ingrType() { - return Type.ENTITY_TAG; - } - - @Override - public String getSomeKindOfReasonableIDForEmi() { - var resloc = this.entityTypeTag.location(); - return resloc.getNamespace() - + "//" - + resloc.getPath(); - } - @Override public boolean equals(Object o) { if (this == o) return true; @@ -134,4 +100,25 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hashCode(this.entityTypeTag); } + + + public static class Type implements BrainsweepeeIngredientType { + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( + TagKey.hashedCodec(Registries.ENTITY_TYPE).fieldOf("tag").forGetter(EntityTagIngredient::getTag) + ).apply(instance, EntityTagIngredient::new)); + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ResourceLocation.STREAM_CODEC.map(id -> TagKey.create(Registries.ENTITY_TYPE, id), TagKey::location), EntityTagIngredient::getTag, + EntityTagIngredient::new + ); + + @Override + public MapCodec codec() { + return CODEC; + } + + @Override + public StreamCodec streamCodec() { + return STREAM_CODEC; + } + } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/brainsweep/EntityTypeIngredient.java b/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/brainsweep/EntityTypeIngredient.java index f510c17d2e..68383eda31 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/brainsweep/EntityTypeIngredient.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/brainsweep/EntityTypeIngredient.java @@ -1,10 +1,15 @@ package at.petrak.hexcasting.common.recipe.ingredient.brainsweep; import com.google.gson.JsonObject; -import net.minecraft.core.Registry; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.core.registries.Registries; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.chat.Component; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerLevel; import net.minecraft.util.GsonHelper; @@ -22,6 +27,15 @@ public EntityTypeIngredient(EntityType entityType) { this.entityType = entityType; } + @Override + public BrainsweepeeIngredientType getType() { + return BrainsweepeeIngredients.ENTITY_TYPE; + } + + public EntityType getEntityType() { + return entityType; + } + @Override public boolean test(Entity entity, ServerLevel level) { // entity types are singletons @@ -46,46 +60,6 @@ public Entity exampleEntity(Level level) { return this.entityType.create(level); } - @Override - public JsonObject serialize() { - var obj = new JsonObject(); - obj.addProperty("type", Type.ENTITY_TYPE.getSerializedName()); - obj.addProperty("entityType", BuiltInRegistries.ENTITY_TYPE.getKey(this.entityType).toString()); - - return obj; - } - - @Override - public void write(FriendlyByteBuf buf) { - buf.writeVarInt(BuiltInRegistries.ENTITY_TYPE.getId(this.entityType)); - } - - public static EntityTypeIngredient deserialize(JsonObject obj) { - var typeLoc = ResourceLocation.tryParse(GsonHelper.getAsString(obj, "entityType")); - if (typeLoc == null || !BuiltInRegistries.ENTITY_TYPE.containsKey(typeLoc)) { - throw new IllegalArgumentException("unknown entity type " + typeLoc); - } - return new EntityTypeIngredient(BuiltInRegistries.ENTITY_TYPE.get(typeLoc)); - } - - public static EntityTypeIngredient read(FriendlyByteBuf buf) { - var tyId = buf.readVarInt(); - return new EntityTypeIngredient(BuiltInRegistries.ENTITY_TYPE.byId(tyId)); - } - - @Override - public Type ingrType() { - return Type.ENTITY_TYPE; - } - - @Override - public String getSomeKindOfReasonableIDForEmi() { - var resloc = BuiltInRegistries.ENTITY_TYPE.getKey(this.entityType); - return resloc.getNamespace() - + "//" - + resloc.getPath(); - } - @Override public boolean equals(Object o) { if (this == o) return true; @@ -98,4 +72,25 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hash(entityType); } + + + public static class Type implements BrainsweepeeIngredientType { + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( + BuiltInRegistries.ENTITY_TYPE.byNameCodec().fieldOf("entityType").forGetter(EntityTypeIngredient::getEntityType) + ).apply(instance, EntityTypeIngredient::new)); + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.registry(Registries.ENTITY_TYPE), EntityTypeIngredient::getEntityType, + EntityTypeIngredient::new + ); + + @Override + public MapCodec codec() { + return CODEC; + } + + @Override + public StreamCodec streamCodec() { + return STREAM_CODEC; + } + } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/brainsweep/VillagerIngredient.java b/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/brainsweep/VillagerIngredient.java index d3cf2e63ef..ab91129415 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/brainsweep/VillagerIngredient.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/brainsweep/VillagerIngredient.java @@ -1,13 +1,20 @@ package at.petrak.hexcasting.common.recipe.ingredient.brainsweep; import com.google.gson.JsonObject; +import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.ChatFormatting; import net.minecraft.core.Registry; import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.core.registries.Registries; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerLevel; import net.minecraft.util.GsonHelper; @@ -22,6 +29,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; +import java.util.Optional; /** * Special case for villagers so we can have biome/profession/level reqs @@ -41,6 +49,23 @@ public VillagerIngredient( this.minLevel = minLevel; } + @Override + public BrainsweepeeIngredientType getType() { + return BrainsweepeeIngredients.VILLAGER; + } + + public @Nullable VillagerProfession getProfession() { + return profession; + } + + public @Nullable VillagerType getBiome() { + return biome; + } + + public int getMinLevel() { + return minLevel; + } + @Override public boolean test(Entity entity, ServerLevel level) { if (!(entity instanceof Villager villager)) return false; @@ -149,97 +174,6 @@ public Component getName() { return component; } - @Override - public JsonObject serialize() { - var obj = new JsonObject(); - obj.addProperty("type", Type.VILLAGER.getSerializedName()); - - if (this.profession != null) { - obj.addProperty("profession", this.profession.toString()); - } - if (this.biome != null) { - obj.addProperty("biome", this.biome.toString()); - } - obj.addProperty("minLevel", this.minLevel); - return obj; - } - - @Override - public void write(FriendlyByteBuf buf) { - if (this.profession != null) { - buf.writeVarInt(1); - buf.writeVarInt(BuiltInRegistries.VILLAGER_PROFESSION.getId(this.profession)); - } else { - buf.writeVarInt(0); - } - if (this.biome != null) { - buf.writeVarInt(1); - buf.writeVarInt(BuiltInRegistries.VILLAGER_TYPE.getId(this.biome)); - } else { - buf.writeVarInt(0); - } - buf.writeInt(this.minLevel); - } - - public static VillagerIngredient deserialize(JsonObject json) { - VillagerProfession profession = null; - if (json.has("profession") && !json.get("profession").isJsonNull()) { - profession = BuiltInRegistries.VILLAGER_PROFESSION.get(new ResourceLocation(GsonHelper.getAsString(json, - "profession"))); - } - VillagerType biome = null; - if (json.has("biome") && !json.get("biome").isJsonNull()) { - biome = BuiltInRegistries.VILLAGER_TYPE.get(new ResourceLocation(GsonHelper.getAsString(json, "biome"))); - } - int minLevel = GsonHelper.getAsInt(json, "minLevel"); - return new VillagerIngredient(profession, biome, minLevel); - } - - public static VillagerIngredient read(FriendlyByteBuf buf) { - VillagerProfession profession = null; - var hasProfession = buf.readVarInt(); - if (hasProfession != 0) { - profession = BuiltInRegistries.VILLAGER_PROFESSION.byId(buf.readVarInt()); - } - VillagerType biome = null; - var hasBiome = buf.readVarInt(); - if (hasBiome != 0) { - biome = BuiltInRegistries.VILLAGER_TYPE.byId(buf.readVarInt()); - } - int minLevel = buf.readInt(); - return new VillagerIngredient(profession, biome, minLevel); - } - - @Override - public Type ingrType() { - return Type.VILLAGER; - } - - @Override - public String getSomeKindOfReasonableIDForEmi() { - var bob = new StringBuilder(); - if (this.profession != null) { - var profLoc = BuiltInRegistries.VILLAGER_PROFESSION.getKey(this.profession); - bob.append(profLoc.getNamespace()) - .append("//") - .append(profLoc.getPath()); - } else { - bob.append("null"); - } - bob.append("_"); - if (this.biome != null) { - var biomeLoc = BuiltInRegistries.VILLAGER_TYPE.getKey(this.biome); - bob.append(biomeLoc.getNamespace()) - .append("//") - .append(biomeLoc.getPath()); - } else { - bob.append("null"); - } - - bob.append(this.minLevel); - return bob.toString(); - } - @Override public boolean equals(Object o) { if (this == o) return true; @@ -253,4 +187,29 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hash(profession, biome, minLevel); } + + + public static class Type implements BrainsweepeeIngredientType { + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( + BuiltInRegistries.VILLAGER_PROFESSION.byNameCodec().optionalFieldOf("profession").forGetter(ing -> Optional.ofNullable(ing.getProfession())), + BuiltInRegistries.VILLAGER_TYPE.byNameCodec().optionalFieldOf("biome").forGetter(ing -> Optional.ofNullable(ing.getBiome())), + Codec.INT.fieldOf("minLevel").forGetter(VillagerIngredient::getMinLevel) + ).apply(instance, (a, b, c) -> new VillagerIngredient(a.orElse(null), b.orElse(null), c))); + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.optional(ByteBufCodecs.registry(Registries.VILLAGER_PROFESSION)), ing -> Optional.ofNullable(ing.getProfession()), + ByteBufCodecs.optional(ByteBufCodecs.registry(Registries.VILLAGER_TYPE)), ing -> Optional.ofNullable(ing.getBiome()), + ByteBufCodecs.VAR_INT, VillagerIngredient::getMinLevel, + (a, b, c) -> new VillagerIngredient(a.orElse(null), b.orElse(null), c) + ); + + @Override + public MapCodec codec() { + return CODEC; + } + + @Override + public StreamCodec streamCodec() { + return STREAM_CODEC; + } + } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/StateIngredient.java b/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/state/StateIngredient.java similarity index 80% rename from Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/StateIngredient.java rename to Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/state/StateIngredient.java index cd2cca2268..464e703d09 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/StateIngredient.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/state/StateIngredient.java @@ -1,8 +1,6 @@ -package at.petrak.hexcasting.common.recipe.ingredient; +package at.petrak.hexcasting.common.recipe.ingredient.state; -import com.google.gson.JsonObject; -import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.chat.Component; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.state.BlockState; @@ -15,15 +13,14 @@ // https://github.com/VazkiiMods/Botania/blob/1.18.x/Common/src/main/java/vazkii/botania/api/recipe/StateIngredient.java // good artists copy and all public interface StateIngredient extends Predicate { + + StateIngredientType getType(); + @Override boolean test(BlockState state); BlockState pick(Random random); - JsonObject serialize(); - - void write(FriendlyByteBuf buffer); - List getDisplayedStacks(); /** diff --git a/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/StateIngredientBlock.java b/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/state/StateIngredientBlock.java similarity index 54% rename from Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/StateIngredientBlock.java rename to Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/state/StateIngredientBlock.java index ac9febaf7f..cfb1209cd5 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/StateIngredientBlock.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/state/StateIngredientBlock.java @@ -1,9 +1,12 @@ -package at.petrak.hexcasting.common.recipe.ingredient; +package at.petrak.hexcasting.common.recipe.ingredient.state; -import com.google.gson.JsonObject; -import net.minecraft.core.Registry; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.core.registries.Registries; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.level.block.Block; @@ -20,6 +23,11 @@ public StateIngredientBlock(Block block) { this.block = block; } + @Override + public StateIngredientType getType() { + return StateIngredients.BLOCK_TYPE; + } + @Override public boolean test(BlockState blockState) { return block == blockState.getBlock(); @@ -30,20 +38,6 @@ public BlockState pick(Random random) { return block.defaultBlockState(); } - @Override - public JsonObject serialize() { - JsonObject object = new JsonObject(); - object.addProperty("type", "block"); - object.addProperty("block", BuiltInRegistries.BLOCK.getKey(block).toString()); - return object; - } - - @Override - public void write(FriendlyByteBuf buffer) { - buffer.writeVarInt(1); - buffer.writeVarInt(BuiltInRegistries.BLOCK.getId(block)); - } - @Override public List getDisplayedStacks() { if (block.asItem() == Items.AIR) { @@ -81,4 +75,25 @@ public int hashCode() { public String toString() { return "StateIngredientBlock{" + block + "}"; } + + + public static class Type implements StateIngredientType { + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( + BuiltInRegistries.BLOCK.byNameCodec().fieldOf("block").forGetter(StateIngredientBlock::getBlock) + ).apply(instance, StateIngredientBlock::new)); + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.registry(Registries.BLOCK), StateIngredientBlock::getBlock, + StateIngredientBlock::new + ); + + @Override + public MapCodec codec() { + return CODEC; + } + + @Override + public StreamCodec streamCodec() { + return STREAM_CODEC; + } + } } \ No newline at end of file diff --git a/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/StateIngredientBlockState.java b/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/state/StateIngredientBlockState.java similarity index 62% rename from Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/StateIngredientBlockState.java rename to Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/state/StateIngredientBlockState.java index c1018f47df..7a01d09e47 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/StateIngredientBlockState.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/state/StateIngredientBlockState.java @@ -1,10 +1,12 @@ -package at.petrak.hexcasting.common.recipe.ingredient; +package at.petrak.hexcasting.common.recipe.ingredient.state; -import com.google.common.collect.ImmutableMap; -import com.google.gson.JsonObject; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.ChatFormatting; -import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.chat.Component; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.level.block.Block; @@ -21,6 +23,11 @@ public StateIngredientBlockState(BlockState state) { this.state = state; } + @Override + public StateIngredientType getType() { + return StateIngredients.BLOCK_STATE; + } + @Override public boolean test(BlockState blockState) { return this.state == blockState; @@ -31,19 +38,6 @@ public BlockState pick(Random random) { return state; } - @Override - public JsonObject serialize() { - JsonObject object = StateIngredientHelper.serializeBlockState(state); - object.addProperty("type", "state"); - return object; - } - - @Override - public void write(FriendlyByteBuf buffer) { - buffer.writeVarInt(2); - buffer.writeVarInt(Block.getId(state)); - } - @Override public List getDisplayedStacks() { Block block = state.getBlock(); @@ -56,7 +50,7 @@ public List getDisplayedStacks() { @Nullable @Override public List descriptionTooltip() { - ImmutableMap, Comparable> map = state.getValues(); + Map, Comparable> map = state.getValues(); if (map.isEmpty()) { return StateIngredient.super.descriptionTooltip(); } @@ -100,4 +94,25 @@ public int hashCode() { public String toString() { return "StateIngredientBlockState{" + state + "}"; } + + + public static class Type implements StateIngredientType { + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( + BlockState.CODEC.fieldOf("state").forGetter(StateIngredientBlockState::getState) + ).apply(instance, StateIngredientBlockState::new)); + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.VAR_INT.map(Block::stateById, Block::getId), StateIngredientBlockState::getState, + StateIngredientBlockState::new + ); + + @Override + public MapCodec codec() { + return CODEC; + } + + @Override + public StreamCodec streamCodec() { + return STREAM_CODEC; + } + } } \ No newline at end of file diff --git a/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/StateIngredientBlocks.java b/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/state/StateIngredientBlocks.java similarity index 58% rename from Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/StateIngredientBlocks.java rename to Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/state/StateIngredientBlocks.java index eb0291709f..4f828e2f13 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/StateIngredientBlocks.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/state/StateIngredientBlocks.java @@ -1,11 +1,13 @@ -package at.petrak.hexcasting.common.recipe.ingredient; +package at.petrak.hexcasting.common.recipe.ingredient.state; import com.google.common.collect.ImmutableSet; -import com.google.gson.JsonArray; -import com.google.gson.JsonObject; -import net.minecraft.core.Registry; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.core.registries.Registries; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.level.block.Block; @@ -25,6 +27,11 @@ public StateIngredientBlocks(Collection blocks) { this.blocks = ImmutableSet.copyOf(blocks); } + @Override + public StateIngredientType getType() { + return StateIngredients.BLOCKS; + } + @Override public boolean test(BlockState state) { return blocks.contains(state.getBlock()); @@ -35,28 +42,6 @@ public BlockState pick(Random random) { return blocks.asList().get(random.nextInt(blocks.size())).defaultBlockState(); } - @Override - public JsonObject serialize() { - JsonObject object = new JsonObject(); - object.addProperty("type", "blocks"); - JsonArray array = new JsonArray(); - for (Block block : blocks) { - array.add(BuiltInRegistries.BLOCK.getKey(block).toString()); - } - object.add("blocks", array); - return object; - } - - @Override - public void write(FriendlyByteBuf buffer) { - List blocks = getBlocks(); - buffer.writeVarInt(0); - buffer.writeVarInt(blocks.size()); - for (Block block : blocks) { - buffer.writeVarInt(BuiltInRegistries.BLOCK.getId(block)); - } - } - @Override public List getDisplayedStacks() { return blocks.stream() @@ -95,4 +80,25 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hash(blocks); } + + + public static class Type implements StateIngredientType { + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( + BuiltInRegistries.BLOCK.byNameCodec().listOf().fieldOf("block").forGetter(StateIngredientBlocks::getBlocks) + ).apply(instance, StateIngredientBlocks::new)); + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.registry(Registries.BLOCK).apply(ByteBufCodecs.list()), StateIngredientBlocks::getBlocks, + StateIngredientBlocks::new + ); + + @Override + public MapCodec codec() { + return CODEC; + } + + @Override + public StreamCodec streamCodec() { + return STREAM_CODEC; + } + } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/StateIngredientTag.java b/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/state/StateIngredientTag.java similarity index 61% rename from Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/StateIngredientTag.java rename to Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/state/StateIngredientTag.java index 5850bd1bf2..dac2e84b3b 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/StateIngredientTag.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/state/StateIngredientTag.java @@ -1,11 +1,13 @@ -package at.petrak.hexcasting.common.recipe.ingredient; +package at.petrak.hexcasting.common.recipe.ingredient.state; import com.google.common.collect.ImmutableSet; -import com.google.gson.JsonObject; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.core.Holder; -import net.minecraft.core.Registry; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.Registries; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.TagKey; import net.minecraft.world.item.ItemStack; @@ -23,9 +25,14 @@ public class StateIngredientTag extends StateIngredientBlocks { private final TagKey tag; - public StateIngredientTag(ResourceLocation tag) { + public StateIngredientTag(TagKey tag) { super(ImmutableSet.of()); - this.tag = TagKey.create(Registries.BLOCK, tag); + this.tag = tag; + } + + @Override + public StateIngredientType getType() { + return StateIngredients.TAG; } public Stream resolve() { @@ -47,14 +54,6 @@ public BlockState pick(Random random) { return values.get(random.nextInt(values.size())).defaultBlockState(); } - @Override - public JsonObject serialize() { - JsonObject object = new JsonObject(); - object.addProperty("type", "tag"); - object.addProperty("tag", tag.location().toString()); - return object; - } - @Override public List getDisplayedStacks() { return resolve() @@ -74,8 +73,8 @@ public List getDisplayed() { return resolve().map(Block::defaultBlockState).collect(Collectors.toList()); } - public ResourceLocation getTagId() { - return tag.location(); + public TagKey getTag() { + return tag; } @Override @@ -98,4 +97,25 @@ public int hashCode() { public String toString() { return "StateIngredientTag{" + tag + "}"; } + + + public static class Type implements StateIngredientType { + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( + TagKey.hashedCodec(Registries.BLOCK).fieldOf("tag").forGetter(StateIngredientTag::getTag) + ).apply(instance, StateIngredientTag::new)); + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ResourceLocation.STREAM_CODEC.map(id -> TagKey.create(Registries.BLOCK, id), TagKey::location), StateIngredientTag::getTag, + StateIngredientTag::new + ); + + @Override + public MapCodec codec() { + return CODEC; + } + + @Override + public StreamCodec streamCodec() { + return STREAM_CODEC; + } + } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/StateIngredientTagExcluding.java b/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/state/StateIngredientTagExcluding.java similarity index 51% rename from Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/StateIngredientTagExcluding.java rename to Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/state/StateIngredientTagExcluding.java index b77dd7ddc3..2a08f605be 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/StateIngredientTagExcluding.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/state/StateIngredientTagExcluding.java @@ -1,8 +1,13 @@ -package at.petrak.hexcasting.common.recipe.ingredient; +package at.petrak.hexcasting.common.recipe.ingredient.state; -import com.google.gson.JsonArray; -import com.google.gson.JsonObject; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.core.registries.Registries; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.resources.ResourceLocation; +import net.minecraft.tags.TagKey; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.level.block.Block; @@ -16,11 +21,16 @@ public class StateIngredientTagExcluding extends StateIngredientTag { private final List excludes; - public StateIngredientTagExcluding(ResourceLocation id, Collection excludes) { - super(id); + public StateIngredientTagExcluding(TagKey tag, Collection excludes) { + super(tag); this.excludes = List.copyOf(excludes); } + @Override + public StateIngredientType getType() { + return StateIngredients.TAG_EXCLUDING; + } + @Override public boolean test(BlockState state) { if (!super.test(state)) { @@ -57,19 +67,6 @@ public int hashCode() { return super.hashCode(); } - @Override - public JsonObject serialize() { - JsonObject object = new JsonObject(); - object.addProperty("type", "tag_excluding"); - object.addProperty("tag", getTagId().toString()); - JsonArray array = new JsonArray(); - for (StateIngredient exclude : excludes) { - array.add(exclude.serialize()); - } - object.add("exclude", array); - return object; - } - @Override public List getDisplayedStacks() { return getBlocks().stream() @@ -92,4 +89,30 @@ public List getDisplayed() { .filter(this::isNotExcluded) .toList(); } + + public List getExcludes() { + return excludes; + } + + public static class Type implements StateIngredientType { + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( + TagKey.hashedCodec(Registries.BLOCK).fieldOf("tag").forGetter(StateIngredientTagExcluding::getTag), + StateIngredients.TYPED_CODEC.listOf().fieldOf("excludes").forGetter(StateIngredientTagExcluding::getExcludes) + ).apply(instance, StateIngredientTagExcluding::new)); + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ResourceLocation.STREAM_CODEC.map(id -> TagKey.create(Registries.BLOCK, id), TagKey::location), StateIngredientTagExcluding::getTag, + StateIngredients.TYPED_STREAM_CODEC.apply(ByteBufCodecs.list()), StateIngredientTagExcluding::getExcludes, + StateIngredientTagExcluding::new + ); + + @Override + public MapCodec codec() { + return CODEC; + } + + @Override + public StreamCodec streamCodec() { + return STREAM_CODEC; + } + } } \ No newline at end of file diff --git a/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/state/StateIngredientType.java b/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/state/StateIngredientType.java new file mode 100644 index 0000000000..da8a3ed7b7 --- /dev/null +++ b/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/state/StateIngredientType.java @@ -0,0 +1,12 @@ +package at.petrak.hexcasting.common.recipe.ingredient.state; + +import com.mojang.serialization.MapCodec; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; + +public interface StateIngredientType { + + MapCodec codec(); + + StreamCodec streamCodec(); +} diff --git a/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/state/StateIngredients.java b/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/state/StateIngredients.java new file mode 100644 index 0000000000..9c7ed400de --- /dev/null +++ b/Common/src/main/java/at/petrak/hexcasting/common/recipe/ingredient/state/StateIngredients.java @@ -0,0 +1,95 @@ +package at.petrak.hexcasting.common.recipe.ingredient.state; + +import at.petrak.hexcasting.api.HexAPI; +import at.petrak.hexcasting.common.lib.HexRegistries; +import at.petrak.hexcasting.xplat.IXplatAbstractions; +import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.tags.TagKey; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; + +import java.util.List; +import java.util.Random; +import java.util.function.BiConsumer; + +public class StateIngredients { + public static final Codec TYPED_CODEC = Codec.lazyInitialized(() -> IXplatAbstractions.INSTANCE + .getStateIngredientRegistry() + .byNameCodec() + .dispatch("type", StateIngredient::getType, StateIngredientType::codec)); + public static final StreamCodec TYPED_STREAM_CODEC = ByteBufCodecs + .registry(HexRegistries.STATE_INGREDIENT) + .dispatch(StateIngredient::getType, StateIngredientType::streamCodec); + + public static final StateIngredientType BLOCK_TYPE = new StateIngredientBlock.Type(); + public static final StateIngredientType BLOCK_STATE = new StateIngredientBlockState.Type(); + public static final StateIngredientType BLOCKS = new StateIngredientBlocks.Type(); + public static final StateIngredientType TAG = new StateIngredientTag.Type(); + public static final StateIngredientType TAG_EXCLUDING = new StateIngredientTagExcluding.Type(); + + public static final StateIngredientType NONE_TYPE = new StateIngredientType<>() { + @Override + public MapCodec codec() { + return MapCodec.unit(NONE); + } + + @Override + public StreamCodec streamCodec() { + return StreamCodec.unit(NONE); + } + }; + + public static final StateIngredient NONE = new StateIngredient() { + @Override + public boolean test(BlockState state) { + return true; + } + + @Override + public BlockState pick(Random random) { + throw new UnsupportedOperationException("Should never try to pick from NONE state ingredient"); + } + + @Override + public StateIngredientType getType() { + return NONE_TYPE; + } + + @Override + public List getDisplayedStacks() { + return List.of(); + } + + @Override + public List getDisplayed() { + return List.of(); + } + }; + + public static void register(BiConsumer, ResourceLocation> r) { + r.accept(NONE_TYPE, HexAPI.modLoc("none")); + r.accept(BLOCK_TYPE, HexAPI.modLoc("block")); + r.accept(BLOCK_STATE, HexAPI.modLoc("state")); + r.accept(BLOCKS, HexAPI.modLoc("blocks")); + r.accept(TAG, HexAPI.modLoc("tag")); + r.accept(TAG_EXCLUDING, HexAPI.modLoc("tag_excluding")); + } + + public static StateIngredient of(Block block) { + return new StateIngredientBlock(block); + } + + public static StateIngredient of(BlockState state) { + return new StateIngredientBlockState(state); + } + + public static StateIngredient of(TagKey tag) { + return new StateIngredientTag(tag); + } +} diff --git a/Common/src/main/java/at/petrak/hexcasting/datagen/HexAdvancements.java b/Common/src/main/java/at/petrak/hexcasting/datagen/HexAdvancements.java index d095b06044..9aa505a229 100644 --- a/Common/src/main/java/at/petrak/hexcasting/datagen/HexAdvancements.java +++ b/Common/src/main/java/at/petrak/hexcasting/datagen/HexAdvancements.java @@ -1,31 +1,28 @@ package at.petrak.hexcasting.datagen; import at.petrak.hexcasting.api.HexAPI; -import at.petrak.hexcasting.api.advancements.FailToCastGreatSpellTrigger; -import at.petrak.hexcasting.api.advancements.MinMaxLongs; -import at.petrak.hexcasting.api.advancements.OvercastTrigger; -import at.petrak.hexcasting.api.advancements.SpendMediaTrigger; +import at.petrak.hexcasting.api.advancements.*; import at.petrak.hexcasting.api.misc.MediaConstants; import at.petrak.hexcasting.api.mod.HexTags; import at.petrak.hexcasting.common.items.ItemLoreFragment; import at.petrak.hexcasting.common.lib.HexBlocks; import at.petrak.hexcasting.common.lib.HexItems; import at.petrak.paucal.api.datagen.PaucalAdvancementSubProvider; -import net.minecraft.advancements.Advancement; -import net.minecraft.advancements.DisplayInfo; -import net.minecraft.advancements.FrameType; +import net.minecraft.advancements.*; import net.minecraft.advancements.critereon.*; import net.minecraft.core.HolderLookup; +import net.minecraft.core.registries.Registries; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; +import java.util.Optional; import java.util.function.Consumer; public class HexAdvancements extends PaucalAdvancementSubProvider { public static final OvercastTrigger.Instance ENLIGHTEN = - new OvercastTrigger.Instance(ContextAwarePredicate.ANY, + new OvercastTrigger.Instance(Optional.empty(), MinMaxBounds.Ints.ANY, // add a little bit of slop here. use 80% or more health ... MinMaxBounds.Doubles.atLeast(0.8), @@ -39,15 +36,15 @@ public HexAdvancements() { } @Override - public void generate(HolderLookup.Provider provider, Consumer consumer) { + public void generate(HolderLookup.Provider provider, Consumer consumer) { var root = Advancement.Builder.advancement() // what an ergonomic design decision // i am so happy that data generators are the future .display(new DisplayInfo(new ItemStack(Items.BUDDING_AMETHYST), Component.translatable("advancement.hexcasting:root"), Component.translatable("advancement.hexcasting:root.desc"), - new ResourceLocation("minecraft", "textures/block/calcite.png"), - FrameType.TASK, true, true, true)) + Optional.of(ResourceLocation.withDefaultNamespace("textures/block/calcite.png")), + AdvancementType.TASK, true, true, true)) // the only thing making this vaguely tolerable is the knowledge the json files are worse somehow .addCriterion("has_charged_amethyst", InventoryChangeTrigger.TriggerInstance.hasItems( ItemPredicate.Builder.item().of(HexTags.Items.GRANTS_ROOT_ADVANCEMENT).build())) @@ -58,8 +55,8 @@ public void generate(HolderLookup.Provider provider, Consumer consu .display(new DisplayInfo(new ItemStack(HexItems.CREATIVE_UNLOCKER), Component.translatable("advancement.hexcasting:creative_unlocker"), Component.translatable("advancement.hexcasting:creative_unlocker.desc"), - new ResourceLocation("minecraft", "textures/block/calcite.png"), - FrameType.TASK, true, false, true)) + Optional.of(ResourceLocation.withDefaultNamespace("textures/block/calcite.png")), + AdvancementType.TASK, true, false, true)) .parent(root) .addCriterion("has_creative_unlocker", InventoryChangeTrigger.TriggerInstance.hasItems( ItemPredicate.Builder.item().of(HexItems.CREATIVE_UNLOCKER).build())) @@ -67,62 +64,72 @@ public void generate(HolderLookup.Provider provider, Consumer consu // weird names so we have alphabetical parity Advancement.Builder.advancement() - .display(simpleDisplay(Items.GLISTERING_MELON_SLICE, "wasteful_cast", FrameType.TASK)) + .display(simpleDisplay(Items.GLISTERING_MELON_SLICE, "wasteful_cast", AdvancementType.TASK)) .parent(root) - .addCriterion("waste_amt", new SpendMediaTrigger.Instance(ContextAwarePredicate.ANY, - MinMaxLongs.ANY, - MinMaxLongs.atLeast(89 * MediaConstants.DUST_UNIT / 10))) + .addCriterion("waste_amt", new Criterion<>( + HexAdvancementTriggers.SPEND_MEDIA_TRIGGER, + new SpendMediaTrigger.Instance(Optional.empty(), + MinMaxLongs.ANY, + MinMaxLongs.atLeast(89 * MediaConstants.DUST_UNIT / 10)) + )) .save(consumer, prefix("aaa_wasteful_cast")); Advancement.Builder.advancement() - .display(simpleDisplay(HexItems.CHARGED_AMETHYST, "big_cast", FrameType.TASK)) + .display(simpleDisplay(HexItems.CHARGED_AMETHYST, "big_cast", AdvancementType.TASK)) .parent(root) - .addCriterion("cast_amt", new SpendMediaTrigger.Instance(ContextAwarePredicate.ANY, - MinMaxLongs.atLeast(64 * MediaConstants.CRYSTAL_UNIT), - MinMaxLongs.ANY)) + .addCriterion("cast_amt", new Criterion<>( + HexAdvancementTriggers.SPEND_MEDIA_TRIGGER, + new SpendMediaTrigger.Instance(Optional.empty(), + MinMaxLongs.atLeast(64 * MediaConstants.CRYSTAL_UNIT), + MinMaxLongs.ANY) + )) .save(consumer, prefix("aab_big_cast")); var impotence = Advancement.Builder.advancement() - .display(simpleDisplay(Items.BLAZE_POWDER, "y_u_no_cast_angy", FrameType.TASK)) + .display(simpleDisplay(Items.BLAZE_POWDER, "y_u_no_cast_angy", AdvancementType.TASK)) .parent(root) .addCriterion("did_the_thing", - new FailToCastGreatSpellTrigger.Instance(ContextAwarePredicate.ANY)) + new Criterion<>(HexAdvancementTriggers.FAIL_GREAT_SPELL_TRIGGER, + new FailToCastGreatSpellTrigger.Instance(Optional.empty()))) .save(consumer, prefix("y_u_no_cast_angy")); var opened_eyes = Advancement.Builder.advancement() - .display(simpleDisplay(Items.ENDER_EYE, "opened_eyes", FrameType.TASK)) + .display(simpleDisplay(Items.ENDER_EYE, "opened_eyes", AdvancementType.TASK)) .parent(impotence) .addCriterion("health_used", - new OvercastTrigger.Instance(ContextAwarePredicate.ANY, - MinMaxBounds.Ints.ANY, - MinMaxBounds.Doubles.ANY, - // you can't just kill yourself - MinMaxBounds.Doubles.atLeast(0.0))) + new Criterion<>( + HexAdvancementTriggers.OVERCAST_TRIGGER, + new OvercastTrigger.Instance(Optional.empty(), + MinMaxBounds.Ints.ANY, + MinMaxBounds.Doubles.ANY, + // you can't just kill yourself + MinMaxBounds.Doubles.atLeast(0.0))) + ) .save(consumer, prefix("opened_eyes")); Advancement.Builder.advancement() .display(new DisplayInfo(new ItemStack(Items.MUSIC_DISC_11), Component.translatable("advancement.hexcasting:enlightenment"), Component.translatable("advancement.hexcasting:enlightenment.desc"), - null, - FrameType.CHALLENGE, true, true, true)) + Optional.empty(), + AdvancementType.CHALLENGE, true, true, true)) .parent(opened_eyes) - .addCriterion("health_used", ENLIGHTEN) + .addCriterion("health_used", new Criterion<>(HexAdvancementTriggers.OVERCAST_TRIGGER, ENLIGHTEN)) .save(consumer, prefix("enlightenment")); var loreRoot = Advancement.Builder.advancement() - .display(simpleDisplayWithBackground(HexBlocks.AKASHIC_LIGATURE, "lore", FrameType.GOAL, + .display(simpleDisplayWithBackground(HexBlocks.AKASHIC_LIGATURE, "lore", AdvancementType.GOAL, modLoc("textures/block/slate.png"))) - .addCriterion("used_item", new ConsumeItemTrigger.TriggerInstance(ContextAwarePredicate.ANY, - ItemPredicate.Builder.item().of(HexItems.LORE_FRAGMENT).build())) + .addCriterion("used_item", new Criterion<>(CriteriaTriggers.CONSUME_ITEM, new ConsumeItemTrigger.TriggerInstance(Optional.empty(), + Optional.of(ItemPredicate.Builder.item().of(HexItems.LORE_FRAGMENT).build())))) .save(consumer, prefix("lore")); for (var advId : ItemLoreFragment.NAMES) { Advancement.Builder.advancement() .display(new DisplayInfo(new ItemStack(HexItems.LORE_FRAGMENT), Component.translatable("advancement." + advId), Component.empty(), - null, FrameType.TASK, true, true, true)) + Optional.empty(), AdvancementType.TASK, true, true, true)) .parent(loreRoot) - .addCriterion(ItemLoreFragment.CRITEREON_KEY, new ImpossibleTrigger.TriggerInstance()) + .addCriterion(ItemLoreFragment.CRITEREON_KEY, new Criterion<>(CriteriaTriggers.IMPOSSIBLE, new ImpossibleTrigger.TriggerInstance())) .save(consumer, advId.toString()); } diff --git a/Common/src/main/java/at/petrak/hexcasting/datagen/HexLootTables.java b/Common/src/main/java/at/petrak/hexcasting/datagen/HexLootTables.java index 386320703c..071842dd0d 100644 --- a/Common/src/main/java/at/petrak/hexcasting/datagen/HexLootTables.java +++ b/Common/src/main/java/at/petrak/hexcasting/datagen/HexLootTables.java @@ -3,17 +3,21 @@ import at.petrak.hexcasting.api.HexAPI; import at.petrak.hexcasting.common.blocks.circles.BlockEntitySlate; import at.petrak.hexcasting.common.lib.HexBlocks; +import at.petrak.hexcasting.common.lib.HexDataComponents; import at.petrak.hexcasting.common.lib.HexItems; import at.petrak.hexcasting.common.loot.HexLootHandler; import at.petrak.hexcasting.xplat.IXplatAbstractions; import at.petrak.paucal.api.datagen.PaucalLootTableSubProvider; -import net.minecraft.advancements.critereon.EnchantmentPredicate; -import net.minecraft.advancements.critereon.ItemPredicate; -import net.minecraft.advancements.critereon.MinMaxBounds; -import net.minecraft.advancements.critereon.StatePropertiesPredicate; +import net.minecraft.advancements.critereon.*; +import net.minecraft.core.HolderLookup; +import net.minecraft.core.component.DataComponentPredicate; +import net.minecraft.core.component.DataComponents; +import net.minecraft.core.registries.Registries; import net.minecraft.data.DataProvider; +import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.ItemTags; +import net.minecraft.world.item.enchantment.Enchantment; import net.minecraft.world.item.enchantment.Enchantments; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.DoorBlock; @@ -26,23 +30,27 @@ import net.minecraft.world.level.storage.loot.entries.LootItem; import net.minecraft.world.level.storage.loot.functions.ApplyBonusCount; import net.minecraft.world.level.storage.loot.functions.ApplyExplosionDecay; -import net.minecraft.world.level.storage.loot.functions.CopyNbtFunction; +import net.minecraft.world.level.storage.loot.functions.CopyComponentsFunction; import net.minecraft.world.level.storage.loot.functions.SetItemCountFunction; import net.minecraft.world.level.storage.loot.predicates.*; import net.minecraft.world.level.storage.loot.providers.nbt.ContextNbtProvider; import net.minecraft.world.level.storage.loot.providers.number.ConstantValue; import net.minecraft.world.level.storage.loot.providers.number.UniformGenerator; +import java.util.List; import java.util.Map; public class HexLootTables extends PaucalLootTableSubProvider { - public HexLootTables() { + private final HolderLookup.Provider registries; + + public HexLootTables(HolderLookup.Provider registries) { super(HexAPI.MOD_ID); + this.registries = registries; } @Override protected void makeLootTables(Map blockTables, - Map lootTables) { + Map, LootTable.Builder> lootTables) { dropSelf(blockTables, HexBlocks.IMPETUS_EMPTY, HexBlocks.IMPETUS_RIGHTCLICK, HexBlocks.IMPETUS_LOOK, HexBlocks.IMPETUS_REDSTONE, HexBlocks.EMPTY_DIRECTRIX, HexBlocks.DIRECTRIX_REDSTONE, HexBlocks.DIRECTRIX_BOOLEAN, @@ -61,17 +69,20 @@ protected void makeLootTables(Map blockTables, HexBlocks.EDIFIED_TRAPDOOR, HexBlocks.EDIFIED_STAIRS, HexBlocks.EDIFIED_FENCE, HexBlocks.EDIFIED_FENCE_GATE, HexBlocks.EDIFIED_PRESSURE_PLATE, HexBlocks.EDIFIED_BUTTON); + HolderLookup.RegistryLookup enchRegistryLookup = this.registries.lookupOrThrow(Registries.ENCHANTMENT); + makeSlabTable(blockTables, HexBlocks.EDIFIED_SLAB); - makeLeafTable(blockTables, HexBlocks.AMETHYST_EDIFIED_LEAVES); - makeLeafTable(blockTables, HexBlocks.AVENTURINE_EDIFIED_LEAVES); - makeLeafTable(blockTables, HexBlocks.CITRINE_EDIFIED_LEAVES); + makeLeafTable(blockTables, HexBlocks.AMETHYST_EDIFIED_LEAVES, enchRegistryLookup); + makeLeafTable(blockTables, HexBlocks.AVENTURINE_EDIFIED_LEAVES, enchRegistryLookup); + makeLeafTable(blockTables, HexBlocks.CITRINE_EDIFIED_LEAVES, enchRegistryLookup); var slatePool = LootPool.lootPool() .setRolls(ConstantValue.exactly(1)) .add(LootItem.lootTableItem(HexBlocks.SLATE) - .apply(CopyNbtFunction.copyData(ContextNbtProvider.BLOCK_ENTITY) - .copy(BlockEntitySlate.TAG_PATTERN, "BlockEntityTag." + BlockEntitySlate.TAG_PATTERN))); + .apply(CopyComponentsFunction.copyComponents(CopyComponentsFunction.Source.BLOCK_ENTITY) + .include(HexDataComponents.PATTERN) + )); blockTables.put(HexBlocks.SLATE, LootTable.lootTable().withPool(slatePool)); var doorPool = dropThisPool(HexBlocks.EDIFIED_DOOR, 1) @@ -80,10 +91,13 @@ protected void makeLootTables(Map blockTables, )); blockTables.put(HexBlocks.EDIFIED_DOOR, LootTable.lootTable().withPool(doorPool)); - var silkTouchCond = MatchTool.toolMatches( - ItemPredicate.Builder.item().hasEnchantment( - new EnchantmentPredicate(Enchantments.SILK_TOUCH, MinMaxBounds.Ints.ANY))); + ItemPredicate.Builder.item().withSubPredicate( + ItemSubPredicates.ENCHANTMENTS, + ItemEnchantmentsPredicate.enchantments( + List.of(new EnchantmentPredicate(enchRegistryLookup.getOrThrow(Enchantments.SILK_TOUCH), MinMaxBounds.Ints.atLeast(1))) + ) + )); var noSilkTouchCond = silkTouchCond.invert(); var goodAtAmethystingCond = MatchTool.toolMatches( ItemPredicate.Builder.item().of(ItemTags.CLUSTER_MAX_HARVESTABLES) @@ -92,7 +106,7 @@ protected void makeLootTables(Map blockTables, var dustPoolWhenGood = LootPool.lootPool() .add(LootItem.lootTableItem(HexItems.AMETHYST_DUST)) .apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 4))) - .apply(ApplyBonusCount.addOreBonusCount(Enchantments.BLOCK_FORTUNE)) + .apply(ApplyBonusCount.addOreBonusCount(enchRegistryLookup.getOrThrow(Enchantments.FORTUNE))) .when(noSilkTouchCond).when(goodAtAmethystingCond); var dustPoolWhenBad = LootPool.lootPool() @@ -104,7 +118,7 @@ protected void makeLootTables(Map blockTables, .add(LootItem.lootTableItem(HexItems.CHARGED_AMETHYST)) .apply(SetItemCountFunction.setCount(ConstantValue.exactly(1))) .when(noSilkTouchCond).when(goodAtAmethystingCond) - .when(BonusLevelTableCondition.bonusLevelFlatChance(Enchantments.BLOCK_FORTUNE, + .when(BonusLevelTableCondition.bonusLevelFlatChance(enchRegistryLookup.getOrThrow(Enchantments.FORTUNE), 0.25f, 0.35f, 0.5f, 0.75f, 1.0f)); var isThatAnMFingBadBrandonSandersonReference = LootPool.lootPool() @@ -126,19 +140,24 @@ protected void makeLootTables(Map blockTables, LootItem.lootTableItem(HexItems.QUENCHED_SHARD) .apply(SetItemCountFunction.setCount(UniformGenerator.between(2f, 4f))) .apply(SetItemCountFunction.setCount(ConstantValue.exactly(1), true) - .when(BonusLevelTableCondition.bonusLevelFlatChance(Enchantments.BLOCK_FORTUNE, + .when(BonusLevelTableCondition.bonusLevelFlatChance(enchRegistryLookup.getOrThrow(Enchantments.FORTUNE), 0.25f, 0.5f, 0.75f, 1.0f))) )); blockTables.put(HexBlocks.QUENCHED_ALLAY, LootTable.lootTable().withPool(quenchedPool)); } - private void makeLeafTable(Map lootTables, Block block) { + private void makeLeafTable(Map lootTables, Block block, HolderLookup.RegistryLookup enchRegistryLookup) { var leafPool = dropThisPool(block, 1) .when(AnyOfCondition.anyOf( IXplatAbstractions.INSTANCE.isShearsCondition(), MatchTool.toolMatches(ItemPredicate.Builder.item() - .hasEnchantment(new EnchantmentPredicate(Enchantments.SILK_TOUCH, MinMaxBounds.Ints.atLeast(1)))) - )); + .withSubPredicate( + ItemSubPredicates.ENCHANTMENTS, + ItemEnchantmentsPredicate.enchantments( + List.of(new EnchantmentPredicate(enchRegistryLookup.getOrThrow(Enchantments.SILK_TOUCH), MinMaxBounds.Ints.atLeast(1))) + ) + ) + ))); lootTables.put(block, LootTable.lootTable().withPool(leafPool)); } diff --git a/Common/src/main/java/at/petrak/hexcasting/datagen/recipe/HexplatRecipes.java b/Common/src/main/java/at/petrak/hexcasting/datagen/recipe/HexplatRecipes.java index 828c8ad92f..3e04446993 100644 --- a/Common/src/main/java/at/petrak/hexcasting/datagen/recipe/HexplatRecipes.java +++ b/Common/src/main/java/at/petrak/hexcasting/datagen/recipe/HexplatRecipes.java @@ -1,6 +1,7 @@ package at.petrak.hexcasting.datagen.recipe; import at.petrak.hexcasting.api.HexAPI; +import at.petrak.hexcasting.api.advancements.HexAdvancementTriggers; import at.petrak.hexcasting.api.misc.MediaConstants; import at.petrak.hexcasting.api.mod.HexTags; import at.petrak.hexcasting.common.blocks.decoration.BlockAkashicLog; @@ -9,40 +10,44 @@ import at.petrak.hexcasting.common.lib.HexBlocks; import at.petrak.hexcasting.common.lib.HexItems; import at.petrak.hexcasting.common.recipe.SealThingsRecipe; -import at.petrak.hexcasting.common.recipe.ingredient.StateIngredientHelper; +import at.petrak.hexcasting.common.recipe.ingredient.state.StateIngredients; import at.petrak.hexcasting.common.recipe.ingredient.brainsweep.EntityTypeIngredient; import at.petrak.hexcasting.common.recipe.ingredient.brainsweep.VillagerIngredient; import at.petrak.hexcasting.datagen.HexAdvancements; import at.petrak.hexcasting.datagen.IXplatConditionsBuilder; import at.petrak.hexcasting.datagen.IXplatIngredients; import at.petrak.hexcasting.datagen.recipe.builders.BrainsweepRecipeBuilder; -import at.petrak.hexcasting.datagen.recipe.builders.CompatIngredientValue; -import at.petrak.hexcasting.datagen.recipe.builders.CreateCrushingRecipeBuilder; -import at.petrak.hexcasting.datagen.recipe.builders.FarmersDelightCuttingRecipeBuilder; -import at.petrak.paucal.api.datagen.PaucalRecipeProvider; +import net.minecraft.advancements.CriteriaTriggers; +import net.minecraft.advancements.Criterion; +import net.minecraft.advancements.critereon.InventoryChangeTrigger; +import net.minecraft.advancements.critereon.ItemPredicate; +import net.minecraft.core.HolderLookup; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.data.PackOutput; import net.minecraft.data.recipes.*; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.sounds.SoundEvents; import net.minecraft.tags.ItemTags; +import net.minecraft.tags.TagKey; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.npc.VillagerProfession; import net.minecraft.world.item.DyeColor; import net.minecraft.world.item.DyeItem; import net.minecraft.world.item.Item; import net.minecraft.world.item.Items; -import net.minecraft.world.item.crafting.Ingredient; -import net.minecraft.world.item.crafting.SimpleCraftingRecipeSerializer; +import net.minecraft.world.item.crafting.*; +import net.minecraft.world.level.ItemLike; import net.minecraft.world.level.block.Blocks; +import org.jetbrains.annotations.Nullable; import java.util.List; import java.util.Map; -import java.util.function.Consumer; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; import java.util.function.Function; +import static at.petrak.hexcasting.api.HexAPI.modLoc; + // TODO: need to do a big refactor of this class cause it's giant and unwieldy, probably as part of #360 -public class HexplatRecipes extends PaucalRecipeProvider { +public class HexplatRecipes extends RecipeProvider { private final IXplatIngredients ingredients; private final Function conditions; @@ -61,17 +66,17 @@ public class HexplatRecipes extends PaucalRecipeProvider { Map.entry(HexBlocks.STRIPPED_EDIFIED_LOG, HexBlocks.STRIPPED_EDIFIED_WOOD) ); - public HexplatRecipes(PackOutput output, IXplatIngredients ingredients, + public HexplatRecipes(PackOutput output, CompletableFuture registries, IXplatIngredients ingredients, Function conditions) { - super(output, HexAPI.MOD_ID); + super(output, registries); this.ingredients = ingredients; this.conditions = conditions; } @Override - public void buildRecipes(Consumer recipes) { - specialRecipe(recipes, SealThingsRecipe.FOCUS_SERIALIZER); - specialRecipe(recipes, SealThingsRecipe.SPELLBOOK_SERIALIZER); + public void buildRecipes(RecipeOutput recipes) { + specialRecipe(recipes, SealThingsRecipe.FOCUS_SERIALIZER, SealThingsRecipe::focus); + specialRecipe(recipes, SealThingsRecipe.SPELLBOOK_SERIALIZER, SealThingsRecipe::spellbook); staffRecipe(recipes, HexItems.STAFF_OAK, Items.OAK_PLANKS); staffRecipe(recipes, HexItems.STAFF_BIRCH, Items.BIRCH_PLANKS); @@ -142,7 +147,8 @@ public void buildRecipes(Consumer recipes) { .define('F', ingredients.goldIngot()) .define('A', HexItems.CHARGED_AMETHYST) // why in god's name does minecraft have two different places for item tags - .define('D', ItemTags.MUSIC_DISCS) + // TODO port: check if good for music discs + .define('D', ItemTags.CREEPER_DROP_MUSIC_DISCS) .pattern(" F ") .pattern("FAF") .pattern(" D ") @@ -195,11 +201,12 @@ public void buildRecipes(Consumer recipes) { gayRecipe(recipes, ItemPridePigment.Type.INTERSEX, Ingredient.of(Items.AZALEA)); gayRecipe(recipes, ItemPridePigment.Type.LESBIAN, Ingredient.of(Items.HONEYCOMB)); gayRecipe(recipes, ItemPridePigment.Type.NONBINARY, Ingredient.of(Items.MOSS_BLOCK)); - gayRecipe(recipes, ItemPridePigment.Type.PANSEXUAL, ingredients.whenModIngredient( + // TODO port: This is neither an item value nor a tag value. + /*gayRecipe(recipes, ItemPridePigment.Type.PANSEXUAL, ingredients.whenModIngredient( Ingredient.of(Items.CARROT), "farmersdelight", CompatIngredientValue.of("farmersdelight:skillet") - )); + ));*/ gayRecipe(recipes, ItemPridePigment.Type.PLURAL, Ingredient.of(Items.REPEATER)); gayRecipe(recipes, ItemPridePigment.Type.TRANSGENDER, Ingredient.of(Items.EGG)); @@ -395,7 +402,7 @@ public void buildRecipes(Consumer recipes) { .pattern("PSS") .pattern("BAB") .pattern("SSP") - .unlockedBy("enlightenment", enlightenment).save(recipes); + .unlockedBy("enlightenment", new Criterion<>(HexAdvancementTriggers.OVERCAST_TRIGGER, enlightenment)).save(recipes); ShapedRecipeBuilder.shaped(RecipeCategory.REDSTONE, HexBlocks.EMPTY_DIRECTRIX) .define('C', Items.COMPARATOR) @@ -405,7 +412,7 @@ public void buildRecipes(Consumer recipes) { .pattern("CSS") .pattern("OAO") .pattern("SSC") - .unlockedBy("enlightenment", enlightenment).save(recipes); + .unlockedBy("enlightenment", new Criterion<>(HexAdvancementTriggers.OVERCAST_TRIGGER, enlightenment)).save(recipes); ShapedRecipeBuilder.shaped(RecipeCategory.REDSTONE, HexBlocks.AKASHIC_BOOKSHELF) .define('L', HexTags.Items.EDIFIED_LOGS) @@ -414,7 +421,7 @@ public void buildRecipes(Consumer recipes) { /*this is the*/.pattern("LPL") // and what i have for you today is .pattern("CCC") .pattern("LPL") - .unlockedBy("enlightenment", enlightenment).save(recipes); + .unlockedBy("enlightenment", new Criterion<>(HexAdvancementTriggers.OVERCAST_TRIGGER, enlightenment)).save(recipes); ShapedRecipeBuilder.shaped(RecipeCategory.REDSTONE, HexBlocks.AKASHIC_LIGATURE, 4) .define('L', HexTags.Items.EDIFIED_LOGS) @@ -425,66 +432,66 @@ public void buildRecipes(Consumer recipes) { .pattern("LPL") .pattern("123") .pattern("LPL") - .unlockedBy("enlightenment", enlightenment).save(recipes); + .unlockedBy("enlightenment", new Criterion<>(HexAdvancementTriggers.OVERCAST_TRIGGER, enlightenment)).save(recipes); - new BrainsweepRecipeBuilder(StateIngredientHelper.of(Blocks.AMETHYST_BLOCK), + new BrainsweepRecipeBuilder(StateIngredients.of(Blocks.AMETHYST_BLOCK), new VillagerIngredient(null, null, 3), Blocks.BUDDING_AMETHYST.defaultBlockState(), MediaConstants.CRYSTAL_UNIT * 10) - .unlockedBy("enlightenment", enlightenment) - .save(recipes, modLoc("brainsweep/budding_amethyst")); + .unlockedBy("enlightenment", new Criterion<>(HexAdvancementTriggers.OVERCAST_TRIGGER, enlightenment)) + .save(recipes, modLoc("budding_amethyst")); - new BrainsweepRecipeBuilder(StateIngredientHelper.of(HexBlocks.IMPETUS_EMPTY), + new BrainsweepRecipeBuilder(StateIngredients.of(HexBlocks.IMPETUS_EMPTY), new VillagerIngredient(VillagerProfession.TOOLSMITH, null, 2), HexBlocks.IMPETUS_RIGHTCLICK.defaultBlockState(), MediaConstants.CRYSTAL_UNIT * 10) - .unlockedBy("enlightenment", enlightenment) - .save(recipes, modLoc("brainsweep/impetus_rightclick")); + .unlockedBy("enlightenment", new Criterion<>(HexAdvancementTriggers.OVERCAST_TRIGGER, enlightenment)) + .save(recipes, modLoc("impetus_rightclick")); - new BrainsweepRecipeBuilder(StateIngredientHelper.of(HexBlocks.IMPETUS_EMPTY), + new BrainsweepRecipeBuilder(StateIngredients.of(HexBlocks.IMPETUS_EMPTY), new VillagerIngredient(VillagerProfession.FLETCHER, null, 2), HexBlocks.IMPETUS_LOOK.defaultBlockState(), MediaConstants.CRYSTAL_UNIT * 10) - .unlockedBy("enlightenment", enlightenment) - .save(recipes, modLoc("brainsweep/impetus_look")); + .unlockedBy("enlightenment", new Criterion<>(HexAdvancementTriggers.OVERCAST_TRIGGER, enlightenment)) + .save(recipes, modLoc("impetus_look")); - new BrainsweepRecipeBuilder(StateIngredientHelper.of(HexBlocks.IMPETUS_EMPTY), + new BrainsweepRecipeBuilder(StateIngredients.of(HexBlocks.IMPETUS_EMPTY), new VillagerIngredient(VillagerProfession.CLERIC, null, 2), HexBlocks.IMPETUS_REDSTONE.defaultBlockState(), MediaConstants.CRYSTAL_UNIT * 10) - .unlockedBy("enlightenment", enlightenment) - .save(recipes, modLoc("brainsweep/impetus_storedplayer")); + .unlockedBy("enlightenment", new Criterion<>(HexAdvancementTriggers.OVERCAST_TRIGGER, enlightenment)) + .save(recipes, modLoc("impetus_storedplayer")); - new BrainsweepRecipeBuilder(StateIngredientHelper.of(HexBlocks.EMPTY_DIRECTRIX), + new BrainsweepRecipeBuilder(StateIngredients.of(HexBlocks.EMPTY_DIRECTRIX), new VillagerIngredient(VillagerProfession.MASON, null, 1), HexBlocks.DIRECTRIX_REDSTONE.defaultBlockState(), MediaConstants.CRYSTAL_UNIT * 10) - .unlockedBy("enlightenment", enlightenment) - .save(recipes, modLoc("brainsweep/directrix_redstone")); + .unlockedBy("enlightenment", new Criterion<>(HexAdvancementTriggers.OVERCAST_TRIGGER, enlightenment)) + .save(recipes, modLoc("directrix_redstone")); - new BrainsweepRecipeBuilder(StateIngredientHelper.of(HexBlocks.EMPTY_DIRECTRIX), + new BrainsweepRecipeBuilder(StateIngredients.of(HexBlocks.EMPTY_DIRECTRIX), new VillagerIngredient(VillagerProfession.SHEPHERD, null, 1), HexBlocks.DIRECTRIX_BOOLEAN.defaultBlockState(), MediaConstants.CRYSTAL_UNIT * 10) - .unlockedBy("enlightenment", enlightenment) - .save(recipes, modLoc("brainsweep/directrix_boolean")); + .unlockedBy("enlightenment", new Criterion<>(HexAdvancementTriggers.OVERCAST_TRIGGER, enlightenment)) + .save(recipes, modLoc("directrix_boolean")); - new BrainsweepRecipeBuilder(StateIngredientHelper.of(HexBlocks.AKASHIC_LIGATURE), + new BrainsweepRecipeBuilder(StateIngredients.of(HexBlocks.AKASHIC_LIGATURE), new VillagerIngredient(VillagerProfession.LIBRARIAN, null, 5), HexBlocks.AKASHIC_RECORD.defaultBlockState(), MediaConstants.CRYSTAL_UNIT * 10) - .unlockedBy("enlightenment", enlightenment) - .save(recipes, modLoc("brainsweep/akashic_record")); + .unlockedBy("enlightenment", new Criterion<>(HexAdvancementTriggers.OVERCAST_TRIGGER, enlightenment)) + .save(recipes, modLoc("akashic_record")); // Temporary tests - new BrainsweepRecipeBuilder(StateIngredientHelper.of(Blocks.AMETHYST_BLOCK), + new BrainsweepRecipeBuilder(StateIngredients.of(Blocks.AMETHYST_BLOCK), new EntityTypeIngredient(EntityType.ALLAY), HexBlocks.QUENCHED_ALLAY.defaultBlockState(), MediaConstants.CRYSTAL_UNIT) - .unlockedBy("enlightenment", enlightenment) - .save(recipes, modLoc("brainsweep/quench_allay")); + .unlockedBy("enlightenment", new Criterion<>(HexAdvancementTriggers.OVERCAST_TRIGGER, enlightenment)) + .save(recipes, modLoc("quench_allay")); // Create compat - this.conditions.apply(new CreateCrushingRecipeBuilder() + /*this.conditions.apply(new CreateCrushingRecipeBuilder() .withInput(Blocks.AMETHYST_CLUSTER) .duration(150) .withOutput(Items.AMETHYST_SHARD, 7) .withOutput(HexItems.AMETHYST_DUST, 5) .withOutput(0.25f, HexItems.CHARGED_AMETHYST)) .whenModLoaded("create") - .save(recipes, new ResourceLocation("create", "crushing/amethyst_cluster")); + .save(recipes, ResourceLocation.fromNamespaceAndPath("create", "crushing/amethyst_cluster")); this.conditions.apply(new CreateCrushingRecipeBuilder() .withInput(Blocks.AMETHYST_BLOCK) @@ -492,7 +499,7 @@ public void buildRecipes(Consumer recipes) { .withOutput(Items.AMETHYST_SHARD, 3) .withOutput(0.5f, HexItems.AMETHYST_DUST, 4)) .whenModLoaded("create") - .save(recipes, new ResourceLocation("create", "crushing/amethyst_block")); + .save(recipes, ResourceLocation.fromNamespaceAndPath("create", "crushing/amethyst_block")); this.conditions.apply(new CreateCrushingRecipeBuilder() .withInput(Items.AMETHYST_SHARD) @@ -535,14 +542,14 @@ public void buildRecipes(Consumer recipes) { .withTool(ingredients.axeDig()) .withOutput(HexBlocks.EDIFIED_PLANKS)) .whenModLoaded("farmersdelight") - .save(recipes, modLoc("compat/farmersdelight/cutting/akashic_door")); + .save(recipes, modLoc("compat/farmersdelight/cutting/akashic_door"));*/ } - private void staffRecipe(Consumer recipes, ItemStaff staff, Item plank) { + private void staffRecipe(RecipeOutput recipes, ItemStaff staff, Item plank) { staffRecipe(recipes, staff, Ingredient.of(plank)); } - private void staffRecipe(Consumer recipes, ItemStaff staff, Ingredient plank) { + private void staffRecipe(RecipeOutput recipes, ItemStaff staff, Ingredient plank) { ShapedRecipeBuilder.shaped(RecipeCategory.TOOLS, staff) .define('W', plank) .define('S', Items.STICK) @@ -554,7 +561,7 @@ private void staffRecipe(Consumer recipes, ItemStaff staff, Ingr .save(recipes); } - private void gayRecipe(Consumer recipes, ItemPridePigment.Type type, Ingredient material) { + private void gayRecipe(RecipeOutput recipes, ItemPridePigment.Type type, Ingredient material) { var colorizer = HexItems.PRIDE_PIGMENTS.get(type); ShapedRecipeBuilder.shaped(RecipeCategory.MISC, colorizer) .define('D', HexItems.AMETHYST_DUST) @@ -566,8 +573,148 @@ private void gayRecipe(Consumer recipes, ItemPridePigment.Type t .save(recipes); } - private void specialRecipe(Consumer consumer, SimpleCraftingRecipeSerializer serializer) { + private > void specialRecipe(RecipeOutput consumer, RecipeSerializer serializer, Function recipeFunc) { var name = BuiltInRegistries.RECIPE_SERIALIZER.getKey(serializer); - SpecialRecipeBuilder.special(serializer).save(consumer, HexAPI.MOD_ID + ":dynamic" + name.getPath()); + SpecialRecipeBuilder.special(recipeFunc::apply).save(consumer, HexAPI.MOD_ID + ":dynamic" + name.getPath()); + } + + protected static Criterion hasItem(ItemLike p_125978_) { + return paucalInventoryTrigger(ItemPredicate.Builder.item().of(p_125978_).build()); + } + + protected static Criterion hasItem(TagKey p_206407_) { + return paucalInventoryTrigger(ItemPredicate.Builder.item().of(p_206407_).build()); + } + + /** + * Prefixed with {@code paucal} to avoid collisions when Forge ATs {@link RecipeProvider#inventoryTrigger}. + */ + protected static Criterion paucalInventoryTrigger(ItemPredicate... $$0) { + return new Criterion<>( + CriteriaTriggers.INVENTORY_CHANGED, + new InventoryChangeTrigger.TriggerInstance(Optional.empty(), InventoryChangeTrigger.TriggerInstance.Slots.ANY, List.of($$0)) + ); + } + + // ================================= From PAUCAL 1.20 + + protected ShapedRecipeBuilder ring(RecipeCategory category, ItemLike out, int count, Ingredient outer, @Nullable Ingredient inner) { + return ringCornered(category, out, count, outer, outer, inner); + } + + protected ShapedRecipeBuilder ring(RecipeCategory category, ItemLike out, int count, ItemLike outer, @Nullable ItemLike inner) { + return ring(category, out, count, Ingredient.of(outer), ingredientOf(inner)); + } + + protected ShapedRecipeBuilder ring(RecipeCategory category, ItemLike out, int count, TagKey outer, @Nullable TagKey inner) { + return ring(category, out, count, Ingredient.of(outer), ingredientOf(inner)); + } + + protected ShapedRecipeBuilder ringCornerless(RecipeCategory category, ItemLike out, int count, Ingredient outer, + @Nullable Ingredient inner) { + return ringCornered(category, out, count, outer, null, inner); + } + + protected ShapedRecipeBuilder ringCornerless(RecipeCategory category, ItemLike out, int count, ItemLike outer, @Nullable ItemLike inner) { + return ringCornerless(category, out, count, Ingredient.of(outer), ingredientOf(inner)); + } + + protected ShapedRecipeBuilder ringAll(RecipeCategory category, ItemLike out, int count, Ingredient outer, @Nullable Ingredient inner) { + return ringCornered(category, out, count, outer, outer, inner); + } + + protected ShapedRecipeBuilder ringAll(RecipeCategory category, ItemLike out, int count, ItemLike outer, @Nullable ItemLike inner) { + return ringAll(category, out, count, Ingredient.of(outer), ingredientOf(inner)); + } + + protected ShapedRecipeBuilder ringCornered(RecipeCategory category, ItemLike out, int count, @Nullable Ingredient cardinal, + @Nullable Ingredient diagonal, @Nullable Ingredient inner) { + if (cardinal == null && diagonal == null && inner == null) { + throw new IllegalArgumentException("at least one ingredient must be non-null"); + } + if (inner != null && cardinal == null && diagonal == null) { + throw new IllegalArgumentException("if inner is non-null, either cardinal or diagonal must not be"); + } + + var builder = ShapedRecipeBuilder.shaped(category, out, count); + var C = ' '; + if (cardinal != null) { + builder.define('C', cardinal); + C = 'C'; + } + var D = ' '; + if (diagonal != null) { + builder.define('D', diagonal); + D = 'D'; + } + var I = ' '; + if (inner != null) { + builder.define('I', inner); + I = 'I'; + } + + builder + .pattern(String.format("%c%c%c", D, C, D)) + .pattern(String.format("%c%c%c", C, I, C)) + .pattern(String.format("%c%c%c", D, C, D)); + + return builder; + } + + protected ShapedRecipeBuilder stack(RecipeCategory category, ItemLike out, int count, Ingredient top, Ingredient bottom) { + return ShapedRecipeBuilder.shaped(category, out, count) + .define('T', top) + .define('B', bottom) + .pattern("T") + .pattern("B"); + } + + protected ShapedRecipeBuilder stack(RecipeCategory category, ItemLike out, int count, ItemLike top, ItemLike bottom) { + return stack(category, out, count, Ingredient.of(top), Ingredient.of(bottom)); + } + + protected ShapedRecipeBuilder stack(RecipeCategory category, ItemLike out, int count, TagKey top, TagKey bottom) { + return stack(category, out, count, Ingredient.of(top), Ingredient.of(bottom)); + } + + + protected ShapedRecipeBuilder stick(RecipeCategory category, ItemLike out, int count, Ingredient input) { + return stack(category, out, count, input, input); + } + + protected ShapedRecipeBuilder stick(RecipeCategory category, ItemLike out, int count, ItemLike input) { + return stick(category, out, count, Ingredient.of(input)); + } + + protected ShapedRecipeBuilder stick(RecipeCategory category, ItemLike out, int count, TagKey input) { + return stick(category, out, count, Ingredient.of(input)); + } + + /** + * @param largeSize True for a 3x3, false for a 2x2 + */ + protected void packing(RecipeCategory category, ItemLike free, ItemLike compressed, String freeName, boolean largeSize, RecipeOutput recipes) { + var pack = ShapedRecipeBuilder.shaped(category, compressed) + .define('X', free); + if (largeSize) { + pack.pattern("XXX").pattern("XXX").pattern("XXX"); + } else { + pack.pattern("XX").pattern("XX"); + } + pack.unlockedBy("has_item", hasItem(free)).save(recipes, modLoc(freeName + "_packing")); + + ShapelessRecipeBuilder.shapeless(category, free, largeSize ? 9 : 4) + .requires(compressed) + .unlockedBy("has_item", hasItem(free)).save(recipes, modLoc(freeName + "_unpacking")); + } + + @Nullable + protected Ingredient ingredientOf(@Nullable ItemLike item) { + return item == null ? null : Ingredient.of(item); + } + + @Nullable + protected Ingredient ingredientOf(@Nullable TagKey item) { + return item == null ? null : Ingredient.of(item); } } diff --git a/Common/src/main/java/at/petrak/hexcasting/datagen/recipe/builders/BrainsweepRecipeBuilder.java b/Common/src/main/java/at/petrak/hexcasting/datagen/recipe/builders/BrainsweepRecipeBuilder.java index 09465dfd03..d1ffa3df38 100644 --- a/Common/src/main/java/at/petrak/hexcasting/datagen/recipe/builders/BrainsweepRecipeBuilder.java +++ b/Common/src/main/java/at/petrak/hexcasting/datagen/recipe/builders/BrainsweepRecipeBuilder.java @@ -1,24 +1,22 @@ package at.petrak.hexcasting.datagen.recipe.builders; -import at.petrak.hexcasting.common.recipe.HexRecipeStuffRegistry; -import at.petrak.hexcasting.common.recipe.ingredient.StateIngredient; -import at.petrak.hexcasting.common.recipe.ingredient.StateIngredientHelper; +import at.petrak.hexcasting.common.recipe.BrainsweepRecipe; +import at.petrak.hexcasting.common.recipe.ingredient.state.StateIngredient; import at.petrak.hexcasting.common.recipe.ingredient.brainsweep.BrainsweepeeIngredient; -import com.google.gson.JsonObject; import net.minecraft.advancements.Advancement; +import net.minecraft.advancements.AdvancementRequirements; import net.minecraft.advancements.AdvancementRewards; -import net.minecraft.advancements.CriterionTriggerInstance; -import net.minecraft.advancements.RequirementsStrategy; +import net.minecraft.advancements.Criterion; import net.minecraft.advancements.critereon.RecipeUnlockedTrigger; -import net.minecraft.data.recipes.FinishedRecipe; import net.minecraft.data.recipes.RecipeBuilder; +import net.minecraft.data.recipes.RecipeOutput; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.Item; -import net.minecraft.world.item.crafting.RecipeSerializer; import net.minecraft.world.level.block.state.BlockState; import org.jetbrains.annotations.Nullable; -import java.util.function.Consumer; +import java.util.LinkedHashMap; +import java.util.Map; public class BrainsweepRecipeBuilder implements RecipeBuilder { private final StateIngredient blockIn; @@ -26,7 +24,7 @@ public class BrainsweepRecipeBuilder implements RecipeBuilder { private final long mediaCost; private final BlockState result; - private final Advancement.Builder advancement; + private final Map> criteria = new LinkedHashMap<>(); public BrainsweepRecipeBuilder(StateIngredient blockIn, BrainsweepeeIngredient entityIn, BlockState result, long mediaCost) { @@ -34,12 +32,11 @@ public BrainsweepRecipeBuilder(StateIngredient blockIn, BrainsweepeeIngredient e this.entityIn = entityIn; this.result = result; this.mediaCost = mediaCost; - this.advancement = Advancement.Builder.advancement(); } @Override - public RecipeBuilder unlockedBy(String pCriterionName, CriterionTriggerInstance pCriterionTrigger) { - this.advancement.addCriterion(pCriterionName, pCriterionTrigger); + public RecipeBuilder unlockedBy(String pCriterionName, Criterion pCriterionTrigger) { + criteria.put(pCriterionName, pCriterionTrigger); return this; } @@ -54,53 +51,14 @@ public Item getResult() { } @Override - public void save(Consumer pFinishedRecipeConsumer, ResourceLocation pRecipeId) { - if (this.advancement.getCriteria().isEmpty()) { - throw new IllegalStateException("No way of obtaining recipe " + pRecipeId); - } + public void save(RecipeOutput recipeOutput, ResourceLocation id) { + Advancement.Builder advancement = recipeOutput.advancement() + .addCriterion("has_the_recipe", RecipeUnlockedTrigger.unlocked(id)) + .rewards(AdvancementRewards.Builder.recipe(id)) + .requirements(AdvancementRequirements.Strategy.OR); + this.criteria.forEach(advancement::addCriterion); - this.advancement.parent(new ResourceLocation("recipes/root")) - .addCriterion("has_the_recipe", RecipeUnlockedTrigger.unlocked(pRecipeId)) - .rewards(AdvancementRewards.Builder.recipe(pRecipeId)) - .requirements(RequirementsStrategy.OR); - pFinishedRecipeConsumer.accept(new Result( - pRecipeId, - this.blockIn, this.entityIn, this.mediaCost, this.result, - this.advancement, - new ResourceLocation(pRecipeId.getNamespace(), "recipes/brainsweep/" + pRecipeId.getPath()))); - } - - public record Result(ResourceLocation id, StateIngredient blockIn, BrainsweepeeIngredient villagerIn, - long mediaCost, BlockState result, Advancement.Builder advancement, - ResourceLocation advancementId) implements FinishedRecipe { - @Override - public void serializeRecipeData(JsonObject json) { - json.add("blockIn", this.blockIn.serialize()); - json.add("entityIn", this.villagerIn.serialize()); - json.addProperty("cost", this.mediaCost); - json.add("result", StateIngredientHelper.serializeBlockState(this.result)); - } - - @Override - public ResourceLocation getId() { - return this.id; - } - - @Override - public RecipeSerializer getType() { - return HexRecipeStuffRegistry.BRAINSWEEP; - } - - @Nullable - @Override - public JsonObject serializeAdvancement() { - return this.advancement.serializeToJson(); - } - - @Nullable - @Override - public ResourceLocation getAdvancementId() { - return this.advancementId; - } + var recipe = new BrainsweepRecipe(blockIn, entityIn, mediaCost, result); + recipeOutput.accept(id.withPrefix("brainsweep/"), recipe, advancement.build(id.withPrefix("recipes/brainsweep/"))); } } diff --git a/Common/src/main/java/at/petrak/hexcasting/datagen/recipe/builders/CreateCrushingRecipeBuilder.java b/Common/src/main/java/at/petrak/hexcasting/datagen/recipe/builders/CreateCrushingRecipeBuilder.java index 77743d9a31..ed66b649cd 100644 --- a/Common/src/main/java/at/petrak/hexcasting/datagen/recipe/builders/CreateCrushingRecipeBuilder.java +++ b/Common/src/main/java/at/petrak/hexcasting/datagen/recipe/builders/CreateCrushingRecipeBuilder.java @@ -2,9 +2,9 @@ import com.google.gson.JsonArray; import com.google.gson.JsonObject; -import net.minecraft.advancements.CriterionTriggerInstance; -import net.minecraft.data.recipes.FinishedRecipe; +import net.minecraft.advancements.Criterion; import net.minecraft.data.recipes.RecipeBuilder; +import net.minecraft.data.recipes.RecipeOutput; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; @@ -31,7 +31,7 @@ public class CreateCrushingRecipeBuilder implements RecipeBuilder { private int processingTime = 100; @Override - public @NotNull CreateCrushingRecipeBuilder unlockedBy(@NotNull String name, @NotNull CriterionTriggerInstance trigger) { + public RecipeBuilder unlockedBy(String name, Criterion criterion) { return this; } @@ -76,7 +76,7 @@ public CreateCrushingRecipeBuilder withOutput(float chance, ItemLike output, int } public CreateCrushingRecipeBuilder withOutput(ItemStack output, float chance) { - this.results.add(new ItemProcessingOutput(output, chance)); + //this.results.add(new ItemProcessingOutput(output, chance)); return this; } @@ -93,7 +93,7 @@ public CreateCrushingRecipeBuilder withOutput(float chance, String name) { } public CreateCrushingRecipeBuilder withOutput(float chance, String name, int count) { - this.results.add(new CompatProcessingOutput(name, count, chance)); + //this.results.add(new CompatProcessingOutput(name, count, chance)); return this; } @@ -103,61 +103,7 @@ public CreateCrushingRecipeBuilder withOutput(float chance, String name, int cou } @Override - public void save(@NotNull Consumer consumer, @NotNull ResourceLocation resourceLocation) { - consumer.accept(new CrushingRecipe(resourceLocation)); - } - - public class CrushingRecipe implements FinishedRecipe { - - private final ResourceLocation id; - - public CrushingRecipe(ResourceLocation id) { - this.id = id; - } - - @Override - public void serializeRecipeData(@NotNull JsonObject json) { - json.addProperty("type", "create:crushing"); - - if (!group.isEmpty()) { - json.addProperty("group", group); - } - - JsonArray jsonIngredients = new JsonArray(); - JsonArray jsonOutputs = new JsonArray(); - - jsonIngredients.add(input.toJson()); + public void save(RecipeOutput recipeOutput, ResourceLocation id) { - results.forEach(o -> jsonOutputs.add(o.serialize())); - - json.add("ingredients", jsonIngredients); - json.add("results", jsonOutputs); - - int processingDuration = processingTime; - if (processingDuration > 0) { - json.addProperty("processingTime", processingDuration); - } - } - - @Override - public @NotNull ResourceLocation getId() { - return id; - } - - @Override - public @NotNull RecipeSerializer getType() { - return RecipeSerializer.SHAPELESS_RECIPE; // Irrelevant, we implement serialization ourselves - } - - @Override - public JsonObject serializeAdvancement() { - return null; - } - - @Override - public ResourceLocation getAdvancementId() { - return null; - } } - } diff --git a/Common/src/main/java/at/petrak/hexcasting/datagen/recipe/builders/FarmersDelightCuttingRecipeBuilder.java b/Common/src/main/java/at/petrak/hexcasting/datagen/recipe/builders/FarmersDelightCuttingRecipeBuilder.java index 8fbc4e7be1..a5daeb205e 100644 --- a/Common/src/main/java/at/petrak/hexcasting/datagen/recipe/builders/FarmersDelightCuttingRecipeBuilder.java +++ b/Common/src/main/java/at/petrak/hexcasting/datagen/recipe/builders/FarmersDelightCuttingRecipeBuilder.java @@ -3,11 +3,12 @@ import com.google.common.collect.Lists; import com.google.gson.JsonArray; import com.google.gson.JsonObject; +import net.minecraft.advancements.Criterion; import net.minecraft.advancements.CriterionTriggerInstance; import net.minecraft.core.Registry; import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.data.recipes.FinishedRecipe; import net.minecraft.data.recipes.RecipeBuilder; +import net.minecraft.data.recipes.RecipeOutput; import net.minecraft.resources.ResourceLocation; import net.minecraft.sounds.SoundEvent; import net.minecraft.world.item.Item; @@ -30,7 +31,7 @@ public class FarmersDelightCuttingRecipeBuilder implements RecipeBuilder { private SoundEvent sound; @Override - public FarmersDelightCuttingRecipeBuilder unlockedBy(String s, CriterionTriggerInstance criterionTriggerInstance) { + public FarmersDelightCuttingRecipeBuilder unlockedBy(String s, Criterion criterionTriggerInstance) { return this; } @@ -75,7 +76,7 @@ public FarmersDelightCuttingRecipeBuilder withOutput(float chance, ItemLike outp } public FarmersDelightCuttingRecipeBuilder withOutput(ItemStack output, float chance) { - this.outputs.add(new ItemProcessingOutput(output, chance)); + //this.outputs.add(new ItemProcessingOutput(output, chance)); return this; } @@ -107,60 +108,7 @@ public FarmersDelightCuttingRecipeBuilder withSound(SoundEvent sound) { } @Override - public void save(Consumer consumer, ResourceLocation resourceLocation) { - consumer.accept(new CuttingRecipe(resourceLocation)); - } - - public class CuttingRecipe implements FinishedRecipe { - - private final ResourceLocation id; - - public CuttingRecipe(ResourceLocation id) { - this.id = id; - } - - @Override - public void serializeRecipeData(@NotNull JsonObject json) { - json.addProperty("type", "farmersdelight:cutting"); - - if (!group.isEmpty()) { - json.addProperty("group", group); - } - - JsonArray jsonIngredients = new JsonArray(); - JsonArray jsonOutputs = new JsonArray(); - - jsonIngredients.add(input.toJson()); - - outputs.forEach(o -> jsonOutputs.add(o.serialize())); - - json.add("ingredients", jsonIngredients); - json.add("tool", toolAction.serialize()); - json.add("result", jsonOutputs); - - if (sound != null) { - json.addProperty("sound", BuiltInRegistries.SOUND_EVENT.getKey(sound).toString()); - } - } - - @Override - public @NotNull ResourceLocation getId() { - return id; - } - - @Override - public @NotNull RecipeSerializer getType() { - return RecipeSerializer.SHAPELESS_RECIPE; // Irrelevant, we implement serialization ourselves - } - - @Override - public JsonObject serializeAdvancement() { - return null; - } + public void save(RecipeOutput recipeOutput, ResourceLocation id) { - @Override - public ResourceLocation getAdvancementId() { - return null; - } } } diff --git a/Common/src/main/java/at/petrak/hexcasting/datagen/recipe/builders/ItemProcessingOutput.java b/Common/src/main/java/at/petrak/hexcasting/datagen/recipe/builders/ItemProcessingOutput.java deleted file mode 100644 index 245c3d607b..0000000000 --- a/Common/src/main/java/at/petrak/hexcasting/datagen/recipe/builders/ItemProcessingOutput.java +++ /dev/null @@ -1,28 +0,0 @@ -package at.petrak.hexcasting.datagen.recipe.builders; - -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import net.minecraft.core.Registry; -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.item.ItemStack; - -public record ItemProcessingOutput(ItemStack stack, float chance) implements ProcessingOutput { - @Override - public JsonObject serialize() { - JsonObject json = new JsonObject(); - ResourceLocation resourceLocation = BuiltInRegistries.ITEM.getKey(stack.getItem()); - json.addProperty("item", resourceLocation.toString()); - int count = stack.getCount(); - if (count != 1) { - json.addProperty("count", count); - } - if (stack.hasTag()) { - json.add("nbt", JsonParser.parseString(stack.getTag().toString())); - } - if (chance != 1) { - json.addProperty("chance", chance); - } - return json; - } -} diff --git a/Common/src/main/java/at/petrak/hexcasting/datagen/tag/HexActionTagProvider.java b/Common/src/main/java/at/petrak/hexcasting/datagen/tag/HexActionTagProvider.java index 4b083c5731..e3ef8bc1a1 100644 --- a/Common/src/main/java/at/petrak/hexcasting/datagen/tag/HexActionTagProvider.java +++ b/Common/src/main/java/at/petrak/hexcasting/datagen/tag/HexActionTagProvider.java @@ -43,7 +43,7 @@ private static TagKey ersatzActionTag(TagKeycreateRegistryKey( - new ResourceLocation("foobar", "hexcasting/tags/action")); + ResourceLocation.fromNamespaceAndPath("foobar", "hexcasting/tags/action")); return TagKey.create(fakeKey, real.location()); } else { return real; diff --git a/Common/src/main/java/at/petrak/hexcasting/datagen/tag/HexBlockTagProvider.java b/Common/src/main/java/at/petrak/hexcasting/datagen/tag/HexBlockTagProvider.java index c354a0464e..dc1e2f4d9c 100644 --- a/Common/src/main/java/at/petrak/hexcasting/datagen/tag/HexBlockTagProvider.java +++ b/Common/src/main/java/at/petrak/hexcasting/datagen/tag/HexBlockTagProvider.java @@ -1,13 +1,14 @@ package at.petrak.hexcasting.datagen.tag; +import at.petrak.hexcasting.api.HexAPI; import at.petrak.hexcasting.api.mod.HexTags; import at.petrak.hexcasting.common.lib.HexBlocks; import at.petrak.hexcasting.xplat.IXplatTags; -import at.petrak.paucal.api.datagen.PaucalBlockTagProvider; import net.minecraft.core.HolderLookup; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.Registries; import net.minecraft.data.PackOutput; +import net.minecraft.data.tags.TagsProvider; import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.BlockTags; import net.minecraft.tags.TagKey; @@ -16,12 +17,11 @@ import java.util.concurrent.CompletableFuture; -public class HexBlockTagProvider extends PaucalBlockTagProvider { +public class HexBlockTagProvider extends TagsProvider { public final IXplatTags xtags; - public HexBlockTagProvider(PackOutput output, CompletableFuture lookupProvider, - IXplatTags xtags) { - super(output, lookupProvider); + public HexBlockTagProvider(PackOutput output, CompletableFuture lookupProvider, IXplatTags xtags) { + super(output, Registries.BLOCK, lookupProvider, HexAPI.MOD_ID, null); this.xtags = xtags; } @@ -35,6 +35,9 @@ protected void addTags(HolderLookup.Provider provider) { .addTag(HexTags.Blocks.IMPETI) .addTag(HexTags.Blocks.DIRECTRICES); + tag(HexTags.Blocks.HEX_UNBREAKABLE) + .addTag(BlockTags.NEEDS_DIAMOND_TOOL); + add(tag(BlockTags.MINEABLE_WITH_PICKAXE), HexBlocks.SLATE_BLOCK, HexBlocks.SLATE_TILES, HexBlocks.SLATE_BRICKS, HexBlocks.SLATE_BRICKS_SMALL, HexBlocks.SLATE_PILLAR, HexBlocks.SLATE, @@ -134,11 +137,11 @@ protected void addTags(HolderLookup.Provider provider) { HexBlocks.CONJURED_BLOCK, HexBlocks.CONJURED_LIGHT); // this is a hack but fixes #532 - var createBrittle = TagKey.create(Registries.BLOCK, new ResourceLocation("create", "brittle")); + var createBrittle = TagKey.create(Registries.BLOCK, ResourceLocation.fromNamespaceAndPath("create", "brittle")); tag(createBrittle).addOptionalTag(BuiltInRegistries.BLOCK.getKey(HexBlocks.SLATE)); } - void add(TagAppender appender, Block... blocks) { + void add(TagsProvider.TagAppender appender, Block... blocks) { for (Block block : blocks) { appender.add(BuiltInRegistries.BLOCK.getResourceKey(block).orElseThrow()); } diff --git a/Common/src/main/java/at/petrak/hexcasting/datagen/tag/HexItemTagProvider.java b/Common/src/main/java/at/petrak/hexcasting/datagen/tag/HexItemTagProvider.java index 520df8a48c..2a55206672 100644 --- a/Common/src/main/java/at/petrak/hexcasting/datagen/tag/HexItemTagProvider.java +++ b/Common/src/main/java/at/petrak/hexcasting/datagen/tag/HexItemTagProvider.java @@ -4,12 +4,13 @@ import at.petrak.hexcasting.api.mod.HexTags; import at.petrak.hexcasting.common.lib.HexItems; import at.petrak.hexcasting.xplat.IXplatTags; -import at.petrak.paucal.api.datagen.PaucalItemTagProvider; import net.minecraft.core.HolderLookup; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.data.DataGenerator; import net.minecraft.data.PackOutput; +import net.minecraft.data.tags.ItemTagsProvider; import net.minecraft.data.tags.TagsProvider; +import net.minecraft.data.tags.VanillaItemTagsProvider; import net.minecraft.tags.BlockTags; import net.minecraft.tags.ItemTags; import net.minecraft.world.item.Item; @@ -18,16 +19,14 @@ import java.util.concurrent.CompletableFuture; -public class HexItemTagProvider extends PaucalItemTagProvider { +public class HexItemTagProvider extends ItemTagsProvider { private final IXplatTags xtags; - public HexItemTagProvider(PackOutput output, CompletableFuture lookup, TagsProvider pBlockTagsProvider, IXplatTags xtags) { - super(output, lookup, HexAPI.MOD_ID, pBlockTagsProvider); + public HexItemTagProvider(PackOutput output, CompletableFuture lookup, CompletableFuture> pBlockTagsProvider, IXplatTags xtags) { + super(output, lookup, pBlockTagsProvider, HexAPI.MOD_ID, null); this.xtags = xtags; } - - @Override protected void addTags(HolderLookup.Provider provider) { add(tag(xtags.gems()), diff --git a/Common/src/main/java/at/petrak/hexcasting/interop/inline/InlinePatternData.java b/Common/src/main/java/at/petrak/hexcasting/interop/inline/InlinePatternData.java index 5dc2dba2ff..f8d4f7c425 100644 --- a/Common/src/main/java/at/petrak/hexcasting/interop/inline/InlinePatternData.java +++ b/Common/src/main/java/at/petrak/hexcasting/interop/inline/InlinePatternData.java @@ -9,6 +9,7 @@ import com.mojang.serialization.Codec; import com.samsthenerd.inline.api.InlineData; import net.minecraft.ChatFormatting; +import net.minecraft.core.component.DataComponents; import net.minecraft.network.chat.ClickEvent; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.HoverEvent; @@ -42,7 +43,7 @@ public ResourceLocation getRendererId(){ public Style getExtraStyle() { ItemStack scrollStack = new ItemStack(HexItems.SCROLL_MEDIUM); HexItems.SCROLL_MEDIUM.writeDatum(scrollStack, new PatternIota(pattern)); - scrollStack.setHoverName(getPatternName(pattern).copy().withStyle(ChatFormatting.WHITE)); + scrollStack.set(DataComponents.ITEM_NAME, getPatternName(pattern).copy().withStyle(ChatFormatting.WHITE)); HoverEvent he = new HoverEvent(HoverEvent.Action.SHOW_ITEM, new HoverEvent.ItemStackInfo(scrollStack)); ClickEvent ce = new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, pattern.toString()); return Style.EMPTY.withHoverEvent(he).withClickEvent(ce); @@ -70,7 +71,7 @@ public Component asText(boolean withExtra) { } public static class InlinePatternDataType implements InlineDataType { - private static final ResourceLocation ID = new ResourceLocation(HexAPI.MOD_ID, "pattern"); + private static final ResourceLocation ID = ResourceLocation.fromNamespaceAndPath(HexAPI.MOD_ID, "pattern"); public static final InlinePatternDataType INSTANCE = new InlinePatternDataType(); @Override diff --git a/Common/src/main/java/at/petrak/hexcasting/interop/patchouli/AbstractPatternComponent.java b/Common/src/main/java/at/petrak/hexcasting/interop/patchouli/AbstractPatternComponent.java index 997bb09411..531bb2a85e 100644 --- a/Common/src/main/java/at/petrak/hexcasting/interop/patchouli/AbstractPatternComponent.java +++ b/Common/src/main/java/at/petrak/hexcasting/interop/patchouli/AbstractPatternComponent.java @@ -6,6 +6,7 @@ import at.petrak.hexcasting.client.render.PatternSettings; import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.core.HolderLookup; import vazkii.patchouli.api.IComponentRenderContext; import vazkii.patchouli.api.ICustomComponent; import vazkii.patchouli.api.IVariable; @@ -77,7 +78,7 @@ public void render(GuiGraphics graphics, IComponentRenderContext context, float } @Override - public void onVariablesAvailable(UnaryOperator lookup) { + public void onVariablesAvailable(UnaryOperator lookup, HolderLookup.RegistryLookup.Provider registries) { this.patterns = this.getPatterns(lookup); } diff --git a/Common/src/main/java/at/petrak/hexcasting/interop/patchouli/BrainsweepProcessor.java b/Common/src/main/java/at/petrak/hexcasting/interop/patchouli/BrainsweepProcessor.java index 576e82bb42..98ced2a109 100644 --- a/Common/src/main/java/at/petrak/hexcasting/interop/patchouli/BrainsweepProcessor.java +++ b/Common/src/main/java/at/petrak/hexcasting/interop/patchouli/BrainsweepProcessor.java @@ -26,13 +26,13 @@ public class BrainsweepProcessor implements IComponentProcessor { @Override public void setup(Level level, IVariableProvider vars) { - var id = new ResourceLocation(vars.get("recipe").asString()); + var id = ResourceLocation.parse(vars.get("recipe", level.registryAccess()).asString()); var recman = level.getRecipeManager(); var brainsweepings = recman.getAllRecipesFor(HexRecipeStuffRegistry.BRAINSWEEP_TYPE); for (var poisonApples : brainsweepings) { - if (poisonApples.getId().equals(id)) { - this.recipe = poisonApples; + if (poisonApples.id().equals(id)) { + this.recipe = poisonApples.value(); break; } } @@ -46,14 +46,14 @@ public IVariable process(Level level, String key) { switch (key) { case "header" -> { - return IVariable.from(this.recipe.result().getBlock().getName()); + return IVariable.from(this.recipe.result().getBlock().getName(), level.registryAccess()); } case "input" -> { var inputStacks = this.recipe.blockIn().getDisplayedStacks(); - return IVariable.from(inputStacks.toArray(new ItemStack[0])); + return IVariable.from(inputStacks.toArray(new ItemStack[0]), level.registryAccess()); } case "result" -> { - return IVariable.from(new ItemStack(this.recipe.result().getBlock())); + return IVariable.from(new ItemStack(this.recipe.result().getBlock()), level.registryAccess()); } case "entity" -> { @@ -79,8 +79,8 @@ public IVariable process(Level level, String key) { return IVariable.wrapList(this.recipe.entityIn() .getTooltip(mc.options.advancedItemTooltips) .stream() - .map(IVariable::from) - .toList()); + .map(v -> IVariable.from(v, level.registryAccess())) + .toList(), level.registryAccess()); } case "mediaCost" -> { record ItemCost(Item item, int cost) { @@ -98,14 +98,14 @@ public boolean dividesEvenly (int dividend) { List validItemStacks = Arrays.stream(costs) .filter(itemCost -> itemCost.dividesEvenly((int)this.recipe.mediaCost())) .map(validItemCost -> new ItemStack(validItemCost.item, (int) this.recipe.mediaCost() / validItemCost.cost)) - .map(IVariable::from) + .map(v -> IVariable.from(v, level.registryAccess())) .toList(); if (!validItemStacks.isEmpty()) { - return IVariable.wrapList(validItemStacks); + return IVariable.wrapList(validItemStacks, level.registryAccess()); } // fallback: display in terms of dust - return IVariable.from(new ItemStack(HexItems.AMETHYST_DUST, (int) (this.recipe.mediaCost() / MediaConstants.DUST_UNIT))); + return IVariable.from(new ItemStack(HexItems.AMETHYST_DUST, (int) (this.recipe.mediaCost() / MediaConstants.DUST_UNIT)), level.registryAccess()); } default -> { return null; diff --git a/Common/src/main/java/at/petrak/hexcasting/interop/patchouli/CustomComponentTooltip.java b/Common/src/main/java/at/petrak/hexcasting/interop/patchouli/CustomComponentTooltip.java index 13972ce372..37e02355f0 100644 --- a/Common/src/main/java/at/petrak/hexcasting/interop/patchouli/CustomComponentTooltip.java +++ b/Common/src/main/java/at/petrak/hexcasting/interop/patchouli/CustomComponentTooltip.java @@ -3,6 +3,7 @@ import com.google.gson.annotations.SerializedName; import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.core.HolderLookup; import net.minecraft.network.chat.Component; import vazkii.patchouli.api.IComponentRenderContext; import vazkii.patchouli.api.ICustomComponent; @@ -19,6 +20,7 @@ public class CustomComponentTooltip implements ICustomComponent { IVariable tooltipReference; transient IVariable tooltipVar; + transient HolderLookup.Provider registries; transient List tooltip; transient int x, y; @@ -28,7 +30,7 @@ public void build(int componentX, int componentY, int pageNum) { x = componentX; y = componentY; tooltip = new ArrayList<>(); - for (IVariable s : tooltipVar.asListOrSingleton()) { + for (IVariable s : tooltipVar.asListOrSingleton(registries)) { tooltip.add(s.as(Component.class)); } } @@ -41,7 +43,8 @@ public void render(GuiGraphics graphics, IComponentRenderContext context, float } @Override - public void onVariablesAvailable(UnaryOperator lookup) { + public void onVariablesAvailable(UnaryOperator lookup, HolderLookup.Provider registries) { tooltipVar = lookup.apply(tooltipReference); + this.registries = registries; } } diff --git a/Common/src/main/java/at/petrak/hexcasting/interop/patchouli/LookupPatternComponent.java b/Common/src/main/java/at/petrak/hexcasting/interop/patchouli/LookupPatternComponent.java index 632c7abf79..9692f573dc 100644 --- a/Common/src/main/java/at/petrak/hexcasting/interop/patchouli/LookupPatternComponent.java +++ b/Common/src/main/java/at/petrak/hexcasting/interop/patchouli/LookupPatternComponent.java @@ -4,6 +4,7 @@ import at.petrak.hexcasting.api.mod.HexTags; import at.petrak.hexcasting.xplat.IXplatAbstractions; import com.google.gson.annotations.SerializedName; +import net.minecraft.core.HolderLookup; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import vazkii.patchouli.api.IVariable; @@ -37,10 +38,10 @@ public boolean showStrokeOrder() { } @Override - public void onVariablesAvailable(UnaryOperator lookup) { + public void onVariablesAvailable(UnaryOperator lookup, HolderLookup.Provider registries) { var opName = lookup.apply(IVariable.wrap(this.opNameRaw)).asString(); this.opName = ResourceLocation.tryParse(opName); - super.onVariablesAvailable(lookup); + super.onVariablesAvailable(lookup, registries); } } diff --git a/Common/src/main/java/at/petrak/hexcasting/interop/patchouli/ManualPatternComponent.java b/Common/src/main/java/at/petrak/hexcasting/interop/patchouli/ManualPatternComponent.java index 06f77903ba..768bc855fd 100644 --- a/Common/src/main/java/at/petrak/hexcasting/interop/patchouli/ManualPatternComponent.java +++ b/Common/src/main/java/at/petrak/hexcasting/interop/patchouli/ManualPatternComponent.java @@ -5,6 +5,7 @@ import com.google.gson.Gson; import com.google.gson.JsonElement; import com.google.gson.annotations.SerializedName; +import net.minecraft.core.HolderLookup; import vazkii.patchouli.api.IVariable; import java.util.ArrayList; @@ -21,11 +22,12 @@ public class ManualPatternComponent extends AbstractPatternComponent { public String strokeOrderRaw; protected transient boolean strokeOrder; + private transient HolderLookup.RegistryLookup.Provider registries; @Override public List getPatterns(UnaryOperator lookup) { this.strokeOrder = lookup.apply(IVariable.wrap(this.strokeOrderRaw)).asBoolean(true); - var patsRaw = lookup.apply(IVariable.wrap(patternsRaw)).asListOrSingleton(); + var patsRaw = lookup.apply(IVariable.wrap(patternsRaw)).asListOrSingleton(registries); var out = new ArrayList(); for (var ivar : patsRaw) { @@ -46,9 +48,10 @@ public boolean showStrokeOrder() { } @Override - public void onVariablesAvailable(UnaryOperator lookup) { + public void onVariablesAvailable(UnaryOperator lookup, HolderLookup.RegistryLookup.Provider registries) { this.strokeOrder = IVariable.wrap(this.strokeOrderRaw).asBoolean(true); + this.registries = registries; - super.onVariablesAvailable(lookup); + super.onVariablesAvailable(lookup, registries); } } diff --git a/Common/src/main/java/at/petrak/hexcasting/interop/patchouli/MultiCraftingProcessor.java b/Common/src/main/java/at/petrak/hexcasting/interop/patchouli/MultiCraftingProcessor.java index 055128b7a5..8311181fe6 100644 --- a/Common/src/main/java/at/petrak/hexcasting/interop/patchouli/MultiCraftingProcessor.java +++ b/Common/src/main/java/at/petrak/hexcasting/interop/patchouli/MultiCraftingProcessor.java @@ -16,6 +16,8 @@ import net.minecraft.world.item.crafting.RecipeType; import net.minecraft.world.item.crafting.ShapedRecipe; import net.minecraft.world.level.Level; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import vazkii.patchouli.api.IComponentProcessor; import vazkii.patchouli.api.IVariable; import vazkii.patchouli.api.IVariableProvider; @@ -32,10 +34,10 @@ public class MultiCraftingProcessor implements IComponentProcessor { @Override public void setup(Level level, IVariableProvider vars) { - List names = vars.get("recipes").asStream().map(IVariable::asString).collect(Collectors.toList()); + List names = vars.get("recipes", level.registryAccess()).asStream(level.registryAccess()).map(IVariable::asString).toList(); this.recipes = new ArrayList<>(); for (String name : names) { - CraftingRecipe recipe = PatchouliUtils.getRecipe(RecipeType.CRAFTING, new ResourceLocation(name)); + CraftingRecipe recipe = PatchouliUtils.getRecipe(RecipeType.CRAFTING, ResourceLocation.parse(name)); if (recipe != null) { recipes.add(recipe); if (shapeless) { @@ -55,13 +57,13 @@ public void setup(Level level, IVariableProvider vars) { } @Override - public IVariable process(Level level, String key) { + public @Nullable IVariable process(Level level, String key) { if (recipes.isEmpty()) { return null; } if (key.equals("heading")) { if (!hasCustomHeading) { - return IVariable.from(recipes.get(0).getResultItem(level.registryAccess()).getHoverName()); + return IVariable.from(recipes.getFirst().getResultItem(level.registryAccess()).getHoverName(), level.registryAccess()); } return null; } @@ -85,14 +87,17 @@ public IVariable process(Level level, String key) { ingredients.add(list.size() > index ? list.get(index) : Ingredient.EMPTY); } } - return PatchouliUtils.interweaveIngredients(ingredients, longestIngredientSize); + return PatchouliUtils.interweaveIngredients(ingredients, longestIngredientSize, level.registryAccess()); } if (key.equals("output")) { return IVariable.wrapList( - recipes.stream().map(recipe -> recipe.getResultItem(level.registryAccess())).map(IVariable::from).collect(Collectors.toList())); + recipes.stream() + .map(recipe -> recipe.getResultItem(level.registryAccess())) + .map(v -> IVariable.from(v, level.registryAccess())) + .collect(Collectors.toList()), level.registryAccess()); } if (key.equals("shapeless")) { - return IVariable.wrap(shapeless); + return IVariable.wrap(shapeless, level.registryAccess()); } return null; } diff --git a/Common/src/main/java/at/petrak/hexcasting/interop/patchouli/PatchouliUtils.java b/Common/src/main/java/at/petrak/hexcasting/interop/patchouli/PatchouliUtils.java index 574b296e1b..e149dd62c9 100644 --- a/Common/src/main/java/at/petrak/hexcasting/interop/patchouli/PatchouliUtils.java +++ b/Common/src/main/java/at/petrak/hexcasting/interop/patchouli/PatchouliUtils.java @@ -1,12 +1,10 @@ package at.petrak.hexcasting.interop.patchouli; import net.minecraft.client.Minecraft; +import net.minecraft.core.HolderLookup; import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.Container; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.crafting.Ingredient; -import net.minecraft.world.item.crafting.Recipe; -import net.minecraft.world.item.crafting.RecipeType; +import net.minecraft.world.item.crafting.*; import vazkii.patchouli.api.IVariable; import java.util.ArrayList; @@ -22,13 +20,15 @@ */ public class PatchouliUtils { @SuppressWarnings("unchecked") - public static , C extends Container> T getRecipe(RecipeType type, ResourceLocation id) { + public static , I extends RecipeInput> T getRecipe(RecipeType type, ResourceLocation id) { // PageDoubleRecipeRegistry if (Minecraft.getInstance().level == null) { return null; } else { var manager = Minecraft.getInstance().level.getRecipeManager(); + return (T) manager.byKey(id) + .map(RecipeHolder::value) .filter((recipe) -> recipe.getType() == type).orElse(null); } } @@ -42,10 +42,11 @@ public static , C extends Container> T getRecipe(RecipeType< * @param longestIngredientSize Longest ingredient in the entire recipe * @return Serialized Patchouli ingredient string */ - public static IVariable interweaveIngredients(List ingredients, int longestIngredientSize) { + public static IVariable interweaveIngredients(List ingredients, int longestIngredientSize, HolderLookup.RegistryLookup.Provider registries) { if (ingredients.size() == 1) { - return IVariable.wrapList(Arrays.stream(ingredients.get(0).getItems()).map(IVariable::from).collect( - Collectors.toList())); + return IVariable.wrapList(Arrays.stream(ingredients.get(0).getItems()) + .map(v -> IVariable.from(v, registries)) + .collect(Collectors.toList()), registries); } ItemStack[] empty = {ItemStack.EMPTY}; @@ -60,17 +61,18 @@ public static IVariable interweaveIngredients(List ingredients, int List list = new ArrayList<>(stacks.size() * longestIngredientSize); for (int i = 0; i < longestIngredientSize; i++) { for (ItemStack[] stack : stacks) { - list.add(IVariable.from(stack[i % stack.length])); + list.add(IVariable.from(stack[i % stack.length], registries)); } } - return IVariable.wrapList(list); + return IVariable.wrapList(list, registries); } /** * Overload of the method above that uses the provided list's longest ingredient size. */ - public static IVariable interweaveIngredients(List ingredients) { + public static IVariable interweaveIngredients(List ingredients, HolderLookup.RegistryLookup.Provider registries) { return interweaveIngredients(ingredients, - ingredients.stream().mapToInt(ingr -> ingr.getItems().length).max().orElse(1)); + ingredients.stream().mapToInt(ingr -> ingr.getItems().length).max().orElse(1), registries + ); } } diff --git a/Common/src/main/java/at/petrak/hexcasting/interop/patchouli/PatternProcessor.java b/Common/src/main/java/at/petrak/hexcasting/interop/patchouli/PatternProcessor.java index 94e9e258b8..3c474040fc 100644 --- a/Common/src/main/java/at/petrak/hexcasting/interop/patchouli/PatternProcessor.java +++ b/Common/src/main/java/at/petrak/hexcasting/interop/patchouli/PatternProcessor.java @@ -12,9 +12,9 @@ public class PatternProcessor implements IComponentProcessor { @Override public void setup(Level level, IVariableProvider vars) { if (vars.has("header")) - translationKey = vars.get("header").asString(); + translationKey = vars.get("header", level.registryAccess()).asString(); else { - IVariable key = vars.get("op_id"); + IVariable key = vars.get("op_id", level.registryAccess()); String opName = key.asString(); String prefix = "hexcasting.action."; @@ -26,7 +26,7 @@ public void setup(Level level, IVariableProvider vars) { @Override public IVariable process(Level level, String key) { if (key.equals("translation_key")) { - return IVariable.wrap(translationKey); + return IVariable.wrap(translationKey, level.registryAccess()); } return null; diff --git a/Common/src/main/java/at/petrak/hexcasting/interop/pehkui/OpGetScale.kt b/Common/src/main/java/at/petrak/hexcasting/interop/pehkui/OpGetScale.kt index d1a9868c51..83f9e9de20 100644 --- a/Common/src/main/java/at/petrak/hexcasting/interop/pehkui/OpGetScale.kt +++ b/Common/src/main/java/at/petrak/hexcasting/interop/pehkui/OpGetScale.kt @@ -11,7 +11,7 @@ object OpGetScale : ConstMediaAction { override val argc = 1 override fun execute(args: List, env: CastingEnvironment): List { - val target = args.getEntity(0, argc) + val target = args.getEntity(env.world, 0, argc) env.assertEntityInRange(target) return IXplatAbstractions.INSTANCE.pehkuiApi.getScale(target).toDouble().asActionResult } diff --git a/Common/src/main/java/at/petrak/hexcasting/interop/pehkui/OpSetScale.kt b/Common/src/main/java/at/petrak/hexcasting/interop/pehkui/OpSetScale.kt index 9c171c5784..80883870ac 100644 --- a/Common/src/main/java/at/petrak/hexcasting/interop/pehkui/OpSetScale.kt +++ b/Common/src/main/java/at/petrak/hexcasting/interop/pehkui/OpSetScale.kt @@ -17,7 +17,7 @@ object OpSetScale : SpellAction { args: List, env: CastingEnvironment ): SpellAction.Result { - val target = args.getEntity(0, argc) + val target = args.getEntity(env.world, 0, argc) val scale = args.getDoubleBetween(1, 1.0 / 32.0, 8.0, argc) env.assertEntityInRange(target) diff --git a/Common/src/main/java/at/petrak/hexcasting/mixin/MixinWanderingTrader.java b/Common/src/main/java/at/petrak/hexcasting/mixin/MixinWanderingTrader.java new file mode 100644 index 0000000000..f8172dc5b2 --- /dev/null +++ b/Common/src/main/java/at/petrak/hexcasting/mixin/MixinWanderingTrader.java @@ -0,0 +1,40 @@ +package at.petrak.hexcasting.mixin; + +import at.petrak.hexcasting.common.lib.HexDataComponents; +import net.minecraft.util.Unit; +import net.minecraft.world.entity.npc.WanderingTrader; +import net.minecraft.world.item.trading.ItemCost; +import net.minecraft.world.item.trading.MerchantOffers; +import net.minecraft.world.item.trading.MerchantOffer; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.util.RandomSource; +import net.minecraft.server.MinecraftServer; +import at.petrak.hexcasting.api.mod.HexConfig; +import at.petrak.hexcasting.api.utils.NBTHelper; +import at.petrak.hexcasting.common.lib.HexItems; +import at.petrak.hexcasting.common.loot.AddPerWorldPatternToScrollFunc; +import at.petrak.hexcasting.common.items.storage.ItemScroll; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +// Adds ancient scrolls to the wandering trader by replacing the special trade in the last slot +@Mixin(WanderingTrader.class) +public class MixinWanderingTrader { + @Inject(method = "updateTrades", at = @At("RETURN")) + private void addNewTrades(CallbackInfo ci) { + var self = (WanderingTrader) (Object) this; + MerchantOffers offerList = self.getOffers(); + if (offerList == null) + return; + RandomSource rand = self.getRandom(); + if (rand.nextFloat() < HexConfig.server().traderScrollChance() && self.getServer() != null) { + ItemStack scroll = new ItemStack(HexItems.SCROLL_LARGE); + AddPerWorldPatternToScrollFunc.doStatic(scroll, rand, self.getServer().overworld()); + scroll.set(HexDataComponents.NEEDS_PURCHASE, Unit.INSTANCE); + offerList.set(5, new MerchantOffer(new ItemCost(Items.EMERALD, 12), scroll, 1, 1, 1)); + } + } +} diff --git a/Common/src/main/java/at/petrak/hexcasting/mixin/accessor/AccessorDamageSource.java b/Common/src/main/java/at/petrak/hexcasting/mixin/accessor/AccessorDamageSource.java deleted file mode 100644 index bf64c438fc..0000000000 --- a/Common/src/main/java/at/petrak/hexcasting/mixin/accessor/AccessorDamageSource.java +++ /dev/null @@ -1,17 +0,0 @@ -package at.petrak.hexcasting.mixin.accessor; - -import net.minecraft.resources.ResourceKey; -import net.minecraft.world.damagesource.DamageSource; -import net.minecraft.world.damagesource.DamageSources; -import net.minecraft.world.damagesource.DamageType; -import net.minecraft.world.entity.Entity; -import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Invoker; - -@Mixin(DamageSources.class) -public interface AccessorDamageSource { - @Invoker("source") - @Nullable - DamageSource hex$source(ResourceKey key, @Nullable Entity entity); -} diff --git a/Common/src/main/java/at/petrak/hexcasting/mixin/accessor/AccessorLootTable.java b/Common/src/main/java/at/petrak/hexcasting/mixin/accessor/AccessorLootTable.java index d2be3c734d..b5661c8e97 100644 --- a/Common/src/main/java/at/petrak/hexcasting/mixin/accessor/AccessorLootTable.java +++ b/Common/src/main/java/at/petrak/hexcasting/mixin/accessor/AccessorLootTable.java @@ -8,16 +8,17 @@ import org.spongepowered.asm.mixin.Mutable; import org.spongepowered.asm.mixin.gen.Accessor; +import java.util.List; import java.util.function.BiFunction; @Mixin(LootTable.class) public interface AccessorLootTable { @Accessor("functions") - LootItemFunction[] hex$getFunctions(); + List hex$getFunctions(); @Accessor("functions") @Mutable - void hex$setFunctions(LootItemFunction[] lifs); + void hex$setFunctions(List lifs); @Accessor("compositeFunction") @Mutable diff --git a/Common/src/main/java/at/petrak/hexcasting/mixin/accessor/AccessorPotionBrewing.java b/Common/src/main/java/at/petrak/hexcasting/mixin/accessor/AccessorPotionBrewing.java deleted file mode 100644 index 88fe176a12..0000000000 --- a/Common/src/main/java/at/petrak/hexcasting/mixin/accessor/AccessorPotionBrewing.java +++ /dev/null @@ -1,14 +0,0 @@ -package at.petrak.hexcasting.mixin.accessor; - -import net.minecraft.world.item.Item; -import net.minecraft.world.item.alchemy.Potion; -import net.minecraft.world.item.alchemy.PotionBrewing; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Invoker; - -@Mixin(PotionBrewing.class) -public interface AccessorPotionBrewing { - @Invoker("addMix") - static void addMix(Potion p_43514_, Item p_43515_, Potion p_43516_) { - } -} diff --git a/Common/src/main/java/at/petrak/hexcasting/mixin/accessor/CriteriaTriggersAccessor.java b/Common/src/main/java/at/petrak/hexcasting/mixin/accessor/CriteriaTriggersAccessor.java deleted file mode 100644 index 5aaf071208..0000000000 --- a/Common/src/main/java/at/petrak/hexcasting/mixin/accessor/CriteriaTriggersAccessor.java +++ /dev/null @@ -1,14 +0,0 @@ -package at.petrak.hexcasting.mixin.accessor; - -import net.minecraft.advancements.CriteriaTriggers; -import net.minecraft.advancements.CriterionTrigger; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Invoker; - -@Mixin(CriteriaTriggers.class) -public interface CriteriaTriggersAccessor { - @Invoker("register") - static > T hex$register(T trigger) { - throw new UnsupportedOperationException(); - } -} diff --git a/Common/src/main/java/at/petrak/hexcasting/mixin/accessor/client/AccessorMouseHandler.java b/Common/src/main/java/at/petrak/hexcasting/mixin/accessor/client/AccessorMouseHandler.java index 54343bb81c..80e30a5dff 100644 --- a/Common/src/main/java/at/petrak/hexcasting/mixin/accessor/client/AccessorMouseHandler.java +++ b/Common/src/main/java/at/petrak/hexcasting/mixin/accessor/client/AccessorMouseHandler.java @@ -6,9 +6,9 @@ @Mixin(MouseHandler.class) public interface AccessorMouseHandler { - @Accessor("accumulatedScroll") - double hex$getAccumulatedScroll(); + @Accessor("accumulatedScrollY") + double hex$getAccumulatedScrollY(); - @Accessor("accumulatedScroll") - void hex$setAccumulatedScroll(double scroll); + @Accessor("accumulatedScrollY") + void hex$setAccumulatedScrollY(double scroll); } diff --git a/Common/src/main/java/at/petrak/hexcasting/server/ScrungledPatternsSave.java b/Common/src/main/java/at/petrak/hexcasting/server/ScrungledPatternsSave.java index 2407d3571a..569e74d8d8 100644 --- a/Common/src/main/java/at/petrak/hexcasting/server/ScrungledPatternsSave.java +++ b/Common/src/main/java/at/petrak/hexcasting/server/ScrungledPatternsSave.java @@ -7,6 +7,7 @@ import at.petrak.hexcasting.api.utils.HexUtils; import at.petrak.hexcasting.xplat.IXplatAbstractions; import com.mojang.datafixers.util.Pair; +import net.minecraft.core.HolderLookup; import net.minecraft.nbt.CompoundTag; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; @@ -61,7 +62,7 @@ public Pair lookupReverse(ResourceKey { var inner = new CompoundTag(); @@ -72,7 +73,7 @@ public CompoundTag save(CompoundTag tag) { return tag; } - private static ScrungledPatternsSave load(CompoundTag tag) { + private static ScrungledPatternsSave load(CompoundTag tag, HolderLookup.Provider lookup) { var registryKey = IXplatAbstractions.INSTANCE.getActionRegistry().key(); var map = new HashMap(); @@ -83,7 +84,7 @@ private static ScrungledPatternsSave load(CompoundTag tag) { var rawKey = inner.getString(TAG_KEY); var dir = HexDir.values()[rawDir]; - var key = ResourceKey.create(registryKey, new ResourceLocation(rawKey)); + var key = ResourceKey.create(registryKey, ResourceLocation.parse(rawKey)); map.put(sig, new PerWorldEntry(key, dir)); } @@ -116,8 +117,10 @@ public static ScrungledPatternsSave createFromScratch(long seed) { public static ScrungledPatternsSave open(ServerLevel overworld) { return overworld.getDataStorage().computeIfAbsent( - ScrungledPatternsSave::load, - () -> ScrungledPatternsSave.createFromScratch(overworld.getSeed()), + new SavedData.Factory<>( + () -> ScrungledPatternsSave.createFromScratch(overworld.getSeed()), + ScrungledPatternsSave::load + ), TAG_SAVED_DATA); } diff --git a/Common/src/main/java/at/petrak/hexcasting/xplat/IClientXplatAbstractions.java b/Common/src/main/java/at/petrak/hexcasting/xplat/IClientXplatAbstractions.java index 81806255b3..53ad1b5536 100644 --- a/Common/src/main/java/at/petrak/hexcasting/xplat/IClientXplatAbstractions.java +++ b/Common/src/main/java/at/petrak/hexcasting/xplat/IClientXplatAbstractions.java @@ -7,6 +7,7 @@ import net.minecraft.client.renderer.entity.EntityRendererProvider; import net.minecraft.client.renderer.item.ItemPropertyFunction; import net.minecraft.client.renderer.texture.AbstractTexture; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; @@ -19,7 +20,7 @@ import java.util.stream.Collectors; public interface IClientXplatAbstractions { - void sendPacketToServer(IMessage packet); + void sendPacketToServer(CustomPacketPayload packet); void setRenderLayer(Block block, RenderType type); diff --git a/Common/src/main/java/at/petrak/hexcasting/xplat/IXplatAbstractions.java b/Common/src/main/java/at/petrak/hexcasting/xplat/IXplatAbstractions.java index 86dbc24586..fc95829842 100644 --- a/Common/src/main/java/at/petrak/hexcasting/xplat/IXplatAbstractions.java +++ b/Common/src/main/java/at/petrak/hexcasting/xplat/IXplatAbstractions.java @@ -19,13 +19,16 @@ import at.petrak.hexcasting.api.player.AltioraAbility; import at.petrak.hexcasting.api.player.FlightAbility; import at.petrak.hexcasting.api.player.Sentinel; -import at.petrak.hexcasting.common.msgs.IMessage; +import at.petrak.hexcasting.common.recipe.ingredient.state.StateIngredientType; +import at.petrak.hexcasting.common.recipe.ingredient.brainsweep.BrainsweepeeIngredientType; import at.petrak.hexcasting.interop.pehkui.PehkuiInterop; import com.mojang.authlib.GameProfile; import net.minecraft.core.BlockPos; import net.minecraft.core.Registry; import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.network.protocol.game.ClientGamePacketListener; +import net.minecraft.resources.ResourceKey; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.InteractionHand; @@ -65,14 +68,14 @@ public interface IXplatAbstractions { void initPlatformSpecific(); - void sendPacketToPlayer(ServerPlayer target, IMessage packet); + void sendPacketToPlayer(ServerPlayer target, CustomPacketPayload packet); - void sendPacketNear(Vec3 pos, double radius, ServerLevel dimension, IMessage packet); + void sendPacketNear(Vec3 pos, double radius, ServerLevel dimension, CustomPacketPayload packet); - void sendPacketTracking(Entity entity, IMessage packet); + void sendPacketTracking(Entity entity, CustomPacketPayload packet); // https://github.com/VazkiiMods/Botania/blob/13b7bcd9cbb6b1a418b0afe455662d29b46f1a7f/Xplat/src/main/java/vazkii/botania/xplat/IXplatAbstractions.java#L157 - Packet toVanillaClientboundPacket(IMessage message); + Packet toVanillaClientboundPacket(CustomPacketPayload message); // double getReachDistance(Player player); @@ -115,9 +118,6 @@ public interface IXplatAbstractions { @Nullable ADMediaHolder findMediaHolder(ItemStack stack); - @Nullable - ADMediaHolder findMediaHolder(ServerPlayer player); - @Nullable ADIotaHolder findDataHolder(ItemStack stack); @@ -180,12 +180,18 @@ BlockEntityType createBlockEntityType(BiFunction getEvalSoundRegistry(); + Registry> getStateIngredientRegistry(); + + Registry> getBrainsweepeeIngredientRegistry(); + GameProfile HEXCASTING = new GameProfile(UUID.fromString("8BE7E9DA-1667-11EE-BE56-0242AC120002"), "[HexCasting]"); boolean isBreakingAllowed(ServerLevel world, BlockPos pos, BlockState state, @Nullable Player player); boolean isPlacingAllowed(ServerLevel world, BlockPos pos, ItemStack blockStack, @Nullable Player player); + IXplatRegister createRegistar(ResourceKey> registryKey); + // interop PehkuiInterop.ApiAbstraction getPehkuiApi(); diff --git a/Common/src/main/java/at/petrak/hexcasting/xplat/IXplatRegister.java b/Common/src/main/java/at/petrak/hexcasting/xplat/IXplatRegister.java new file mode 100644 index 0000000000..76d9091fd6 --- /dev/null +++ b/Common/src/main/java/at/petrak/hexcasting/xplat/IXplatRegister.java @@ -0,0 +1,21 @@ +package at.petrak.hexcasting.xplat; + +import net.minecraft.core.Holder; + +import java.util.function.Supplier; + +/** + * Handles registration + * @param + */ +public interface IXplatRegister { + + Supplier register(String id, Supplier provider); + + Holder registerHolder(String id, Supplier provider); + + /** + * Call from mod initializer to actually register all entries in this register + */ + void registerAll(); +} \ No newline at end of file diff --git a/Common/src/main/resources/architectury.common.json b/Common/src/main/resources/architectury.common.json new file mode 100644 index 0000000000..e4a0a01454 --- /dev/null +++ b/Common/src/main/resources/architectury.common.json @@ -0,0 +1,3 @@ +{ + "accessWidener": "hexplat.accesswidener" +} \ No newline at end of file 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 2eb861e346..86c043ce36 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 @@ -46,6 +46,11 @@ "": "Focus", sealed: "Sealed Focus", }, + + ancient_cypher: { + "": "Ancient Cypher", + preset: "Ancient Cypher: %s", + }, thought_knot: "Thought-Knot", spellbook: "Spellbook", @@ -252,8 +257,8 @@ }, "itemGroup.hexcasting": { - "": "Hexcasting", - creative_tab: "Hexcasting", + hexcasting: "Hex Casting", + scrolls: "Hex Casting (Scrolls)", }, "gui.hexcasting": { @@ -368,23 +373,42 @@ "": "Circle Action Deny List", "@Tooltip": "Resource locations of disallowed actions within circles. Trying to cast one of these from a circle will result in a mishap.", }, + greaterTeleportSplatsItems: { + "": "Greater Teleport Splats Items", + "@Tooltip": "Whether items should fly out of the player's inventory when using Greater Teleport" + }, villagersOffendedByMindMurder: { "": "Villagers Offended By Mind Murder", "@Tooltip": "Whether villagers should be angry at the player when other villagers are mindflayed", }, + traderScrollChance: { + "": "Wandering Trader Scroll Chance", + "@Tooltip": "The chance for wandering traders to sell an Ancient Scroll", + }, scrollInjectionsRaw: { "": "Scroll Injection Weights", "@Tooltip": "Maps the names of loot tables to the amount of per-world patterns on scrolls should go in them. There's about a 50% chance to get any scrolls in a given chest marked here; once that is met, between 1 and that many scrolls are generated.", }, + loreInjectionsRaw: { + "": "Lore Injection Sites", + "@Tooltip": "Lists the loot tables that lore fragments should be added to.", + }, + loreChance: { + "": "Lore Fragment Chance", + "@Tooltip": "The chance for lore fragments to appear in any of the above loot tables.", + }, + cypherInjectionsRaw: { + "": "Ancient Cypher Injection Sites", + "@Tooltip": "Lists the loot tables that ancient cyphers should be added to.", + }, + cypherChance: { + "": "Ancient Cypher Chance", + "@Tooltip": "The chance for ancient cyphers to appear in any of the above loot tables.", + }, amethystShardModification: { "": "Amethyst Shard Drop Rate Change", "@Tooltip": "How much the number of amethyst shards dropped from clusters is increased/decreased.", }, - - // TODO: are these used anywhere?? - "fewScrollTables.@Tooltip": "Loot tables that a small number of Ancient Scrolls are injected into", - "someScrollTables.@Tooltip": "Loot tables that a decent number of Ancient Scrolls are injected into", - "manyScrollTables.@Tooltip": "Loot tables that a huge number of Ancient Scrolls are injected into", }, }, }, @@ -499,6 +523,25 @@ infinite_media: "Infinite", }, + loot_hex: { + "shatter": "Shatter", + "kindle": "Kindle", + "illuminate": "Illuminate", + "growth": "Growth", + "lunge": "Lunge", + "sidestep": "Sidestep", + "ascend": "Ascend", + "blink": "Blink", + "blastoff": "Blastoff", + "radar": "Radar", + "beckon": "Beckon", + "detonate": "Detonate", + "shockwave": "Shockwave", + "heat_wave": "Heat Wave", + "wither_wave": "Wither Wave", + "flight_zone": "Flight Zone", + }, + // TODO: post-eigengrau make these less anticlimactic message: { cant_overcast: "That Hex needed more media than I had... I should double-check my math.", @@ -521,6 +564,11 @@ }, sealed: "Sealed", }, + + scroll: { + needs_purchase: "Purchase to show pattern", + pattern_not_loaded: "Place in inventory to load pattern", + }, abacus: { "": "%d", @@ -562,6 +610,7 @@ media: "%d dust", media_amount: "Contains: %s (%s)", "media_amount.advanced": "Contains: %s/%s (%s)", + stored_hex: "Hex: ", list_contents: "[%s]", null_iota: "Null", @@ -586,6 +635,7 @@ add_segment: "Adding line", }, cast: { + fail: "Mishap crunches", normal: "Action hums", spell: "Spell boinks", hermes: "Hermes' twangs", @@ -614,8 +664,12 @@ attributes: { grid_zoom: "Casting Grid Size", + media_consumption: "Media Consumption", + ambit_radius: "Player Ambit Radius", + sentinel_radius: "Sentinel Ambit Radius", // TODO: the +1 is kind of janky scry_sight: "Scrying Sight", + feeble_mind: "Feeble Mind" }, // Action localizations @@ -927,7 +981,7 @@ wrong_dimension: "cannot see %s from %s", entity_too_far: "%s is out of range", immune_entity: "cannot alter %s", - eval_too_deep: "Recursively evaluated too deep", + 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", bad_entity: "needs %s but got %s", @@ -1159,6 +1213,7 @@ // why is this called "hexcasting"? hexcasting: "Casting Items", + ancient_cyphers: "Ancient Cyphers", phials: "Phials of Media", potions: "Hex Potions", pigments: "Pigments", @@ -1383,8 +1438,8 @@ "retrospection.title": "Hasty Retrospection", retrospection: "I attempted to draw $(l:patterns/patterns_as_iotas#hexcasting:close_paren)$(action)Retrospection/$ without first drawing $(l:patterns/patterns_as_iotas#hexcasting:open_paren)$(action)Introspection/$.$(br2)Causes orange sparks, and pushes the pattern for $(l:patterns/patterns_as_iotas#hexcasting:close_paren)$(action)Retrospection/$ to the stack as a pattern iota.", - "too_deep.title": "Delve Too Deep", - too_deep: "Evaluated too many spells with meta-evaluation from one spell.$(br2)Causes dark blue sparks, and chokes all the air out of me.", + "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.", "true_name.title": "Transgress Other", true_name: "I attempted to $(l:patterns/readwrite#hexcasting:write)$(action)save a reference/$ to another player to a permanent medium.$(br2)Causes black sparks, and robs me of my sight for approximately one minute.", @@ -1475,7 +1530,7 @@ "2": "Like a $(l:items/focus)$(item)Focus/$, there exists a simple method to prevent accidental overwriting. Crafting it with a $(item)Honeycomb/$ will lacquer the current page, preventing $(l:patterns/readwrite#hexcasting:write)$(action)Scribe's Gambit/$ from modifying its contents. Also like a $(l:items/focus)$(item)Focus/$, using $(l:patterns/spells/hexcasting#hexcasting:erase)$(action)Erase Item/$ will remove the lacquer along with the page's contents.$(br2)I can also name each page individually in an anvil. Naming it will change only the name of the currently selected page, for easy browsing.", "crafting.desc": "$(italic)Wizards love words. Most of them read a great deal, and indeed one strong sign of a potential wizard is the inability to get to sleep without reading something first.", }, - + scroll: { "1": "A $(l:items/scroll)$(item)Scroll/$ is a convenient method of sharing a pattern with others. I can copy a pattern onto one with $(l:patterns/readwrite#hexcasting:write)$(action)Scribe's Gambit/$, after which it will display in a tooltip.$(br2)I can also place them on the wall as decoration or edification, like a painting, in sizes from 1x1 to 3x3 blocks. Using $(l:items/amethyst)$(item)Amethyst Dust/$ on such a scroll will have it display the stroke order.", "2": "In addition, I can also find so-called $(l:items/scroll)$(item)Ancient Scrolls/$ in the dungeons and strongholds of the world. These contain the stroke order of $(thing)Great Spells/$, powerful magicks rumored to be too powerful for the hands and minds of mortals...$(br2)If those \"mortals\" couldn't cast them, I'm not sure they deserve to know them.", @@ -1498,6 +1553,11 @@ "5": "Each infusion spell requires an entity and a list of patterns on the stack. The entity must be a _media-holding item entity (i.e. $(l:items/amethyst)$(item)amethyst/$ crystals, dropped on the ground); the entity is consumed and forms the battery.$(br2)Usefully, it seems that the _media in the battery is not consumed in chunks as it is when casting with a $(l:items/staff)$(item)Staff/$-- rather, the _media \"melts down\" into one continuous pool. Thus, if I store a _Hex that only costs one $(l:items/amethyst)$(item)Amethyst Dust/$'s worth of media, a $(l:items/amethyst)$(item)Charged Crystal/$ used as the battery will allow me to cast it 10 times.", "crafting.desc": "$(italic)We have a saying in our field: \"Magic isn't\". It doesn't \"just work,\" it doesn't respond to your thoughts, you can't throw fireballs or create a roast dinner from thin air or turn a bunch of muggers into frogs and snails./$", }, + + ancient_cyphers: { + "1": "While adventuring, I've come across what appear to be $(l:items/hexcasting)$(item)Cyphers/$ created by the Hexcasters of the ancient past. These $(item)Ancient Cyphers/$ work just like the ones I can craft: they can't be recharged, and will break when their reserve of _Media runs out. However, unlike my own $(l:items/hexcasting)$(item)Cyphers/$, their decayed structure allows me to glimpse the _Hex stored within.", + "2": "These may be useful for learning new techniques - who better to teach me than ancient masters of the art?$(br2)Alternatively, I could erase the contents of one and store my own _Hex inside, creating a casting item that clearly displays its own function." + }, phials: { "1": "I find it quite ... irritating, how Nature refuses to give me change for my work. If all I have on hand is $(l:items/amethyst)$(item)Charged Amethyst/$, even the tiniest $(l:patterns/basics#hexcasting:raycast)$(action)Archer's Distillation/$ will consume the entire crystal, wasting the remaining _media.$(br2)Fortunately, it seems I've found a way to somewhat allay this problem.", @@ -1557,7 +1617,7 @@ spellcircles: { "1": "I KNOW what the $(l:items/slate)$(item)slates/$ are for. The grand assemblies lost to time. The patterns scribed on them can be actuated in sequence, automatically. Thought and power ricocheting through, one by one by one by one by one by through and through and THROUGH AND -- I must not I must not I should know better than to think that way.", - "2": "To start the ritual I need an $(l:greatwork/impetus)$(item)Impetus/$ to create a self-sustaining wave of _media. That wave travels along a track of $(l:items/slate)$(item)slates/$ or other blocks suitable for the energies, one by one, collecting any patterns it finds. Once the wave circles back around to the $(l:greatwork/impetus)$(item)Impetus/$, all the patterns encountered are cast in order.$(br2)The direction the _media exits any given block MUST be unambiguous, or the casting will fail at the block with too many neighbors.", + "2": "To start the ritual I need an $(l:greatwork/impetus)$(item)Impetus/$ to create a self-sustaining wave of _media. That wave travels along a track of $(l:items/slate)$(item)slates/$ or other suitable blocks, casting any patterns it finds.$(br2)If there is no way for the wave to return to the $(l:greatwork/impetus)$(item)Impetus/$, the casting will fail immediately. Also, the direction the wave exits any given block MUST be unambiguous, or the casting will fail at the block with too many neighbors.", "3": "As a result, the outline of the spell \"circle\" may be any closed shape, concave or convex, and it may face any direction. In fact, with the application of certain other blocks it is possible to make a spell circle that spans all three dimensions. I doubt such an oddity has very much use, but I must allocate myself a bit of vapid levity to encourage my crude mind to continue my work.", "4": "Miracle of miracles, the circle will withdraw _media neither from my inventory nor my mind. Instead, crystallized shards of _media must be provided to the $(l:greatwork/impetus)$(item)Impetus/$ via hopper, or other such artifice.$(br2)The application of a $(l:items/lens)$(item)Scrying Lens/$ will show how much _media is inside an $(l:greatwork/impetus)$(item)Impetus/$, in units of dust.", "5": "However, a spell cast from a circle does have one major limitation: it is unable to affect anything outside of the circle's bounds. That is, it cannot interact with anything outside of the cuboid of minimum size which encloses every block composing it (so a concave spell circle can still affect things in the concavity).", diff --git a/Common/src/main/resources/assets/hexcasting/lang/ru_ru.flatten.json5 b/Common/src/main/resources/assets/hexcasting/lang/ru_ru.flatten.json5 index 1b94caa75f..45889fe332 100644 --- a/Common/src/main/resources/assets/hexcasting/lang/ru_ru.flatten.json5 +++ b/Common/src/main/resources/assets/hexcasting/lang/ru_ru.flatten.json5 @@ -211,8 +211,8 @@ }, "itemGroup.hexcasting": { - "": "Hexcasting", - creative_tab: "Hexcasting", + hexcasting: "Hex Casting", + scrolls: "Hex Casting (Scrolls)", }, "gui.hexcasting": { @@ -335,11 +335,6 @@ "": "Amethyst Shard Drop Rate Change", "@Tooltip": "How much the number of amethyst shards dropped from clusters is increased/decreased.", }, - - // TODO: are these used anywhere?? - "fewScrollTables.@Tooltip": "Loot tables that a small number of Ancient Scrolls are injected into", - "someScrollTables.@Tooltip": "Loot tables that a decent number of Ancient Scrolls are injected into", - "manyScrollTables.@Tooltip": "Loot tables that a huge number of Ancient Scrolls are injected into", }, }, }, @@ -863,7 +858,7 @@ wrong_dimension: "не удается увидеть %s из %s", entity_too_far: "%s находится вне диапазона", immune_entity: "невозможно изменить %s", - eval_too_deep: "Рекурсивные вычисления слишком глубокие", + eval_too_much: "Рекурсивные вычисления слишком глубокие", no_item: "нуждается в %s, но ничего не получает", "no_item.offhand": "нуждается в %s в другой руке, но ничего не получил", bad_entity: "нуждается в %s, но получил %s", @@ -1294,8 +1289,8 @@ "retrospection.title": "Поспешная Ретроспектива", retrospection: "Я попытался нарисовать $(l:patterns/patterns_as_iotas#hexcasting:close_paren)$(action)Ретроспектива/$ без предварительного рисования $(l:patterns/patterns_as_iotas#hexcasting:open_paren)$(action)Интроспекция/$.$(br2)Вызывает оранжевые искры и помещает шаблон для $(l:patterns/patterns_as_iotas#hexcasting:close_paren)$(action)Ретроспектива/$ в стек как шаблон иота.", - "too_deep.title": "Слишком глубоко", - too_deep: "Оценено слишком много заклинаний с метаоценкой от одного заклинания.$(br2)Вызывает темно-синие искры и лишает меня всего воздуха.", + "too_many_patterns.title": "Слишком глубоко", + too_many_patterns: "Оценено слишком много заклинаний с метаоценкой от одного заклинания.$(br2)Вызывает темно-синие искры и лишает меня всего воздуха.", "true_name.title": "Нарушение Законов", true_name: "Я попытался $(l:patterns/readwrite#hexcasting:write)$(action)сохранить истинное имя/$ другого игрока на постоянный носитель.$(br2)Вызывает черные искры и лишает меня зрения примерно на одну минуту.", diff --git a/Common/src/main/resources/assets/hexcasting/lang/zh_cn.flatten.json5 b/Common/src/main/resources/assets/hexcasting/lang/zh_cn.flatten.json5 index 7715983dec..59d9b0d847 100644 --- a/Common/src/main/resources/assets/hexcasting/lang/zh_cn.flatten.json5 +++ b/Common/src/main/resources/assets/hexcasting/lang/zh_cn.flatten.json5 @@ -164,7 +164,7 @@ slate_amethyst_: { tiles: "板岩紫晶瓦", bricks: "板岩紫晶砖", - bricks_small: "板岩紫晶砖", + bricks_small: "板岩紫晶小型砖", pillar: "板岩紫晶柱", }, @@ -252,8 +252,8 @@ }, "itemGroup.hexcasting": { - "": "咒法学", - creative_tab: "咒法学", + hexcasting: "咒法学", + scrolls: "咒法学", }, "gui.hexcasting": { @@ -268,7 +268,7 @@ }, "tag.item.hexcasting": { - brainswept_circle_components: "剥离意识环组件", + brainswept_circle_components: "剥离意识所得法术环组件", directrices: "导向石", grants_root_advancement: "给予根进度", impeti: "促动石", @@ -380,11 +380,6 @@ "": "紫水晶碎片掉落率变化量", "@Tooltip": "采掘紫水晶簇时紫水晶碎片掉落数量相较原版的改变量", }, - - // TODO: are these used anywhere?? - "option.server.fewScrollTables.@Tooltip": "会额外生成较少数量卷轴的战利品表", - "option.server.someScrollTables.@Tooltip": "会额外生成中等数量卷轴的战利品表", - "option.server.manyScrollTables.@Tooltip": "会额外生成较大数量卷轴的战利品表", }, }, }, @@ -586,6 +581,7 @@ add_segment: "绘制线段", }, cast: { + fail: "事故:轰鸣", normal: "操作:嗡鸣", spell: "法术:施放", hermes: "赫尔墨斯之策略:鸣响", @@ -606,6 +602,7 @@ "scroll.scribble": "卷轴:被涂写", "impetus.fletcher.tick": "制箭师促动石:咔哒", "impetus.redstone.register": "牧师促动石:叮~", + "impetus.redstone.clear": "牧师促动石:清空", "lore_fragment.read": "故事残卷:被阅读", "flight.ambience": "玩家:飞翔", "flight.finish": "飞翔结束", @@ -815,6 +812,7 @@ flight: "翱翔", "flight/range": "隐士之飞行", "flight/time": "旅者之飞行", + "flight/can_fly": "飞行员之纯化", lightning: "召雷", summon_rain: "召雨", @@ -925,7 +923,7 @@ wrong_dimension: "无法在%2$s中影响到%1$s", entity_too_far: "%s超出影响范围", immune_entity: "无法影响到%s", - eval_too_deep: "递归深度过大", + eval_too_much: "运行了过多图案", no_item: "需要%s,而实际无对应物品", "no_item.offhand": "需要在另一只手里持有%s,而实际无对应物品", bad_entity: "需要%s,而实际接受了%s", @@ -1381,8 +1379,8 @@ "retrospection.title": "反思过急", retrospection: "试图在绘制$(l:patterns/patterns_as_iotas#hexcasting:open_paren)$(action)内省/$前绘制$(l:patterns/patterns_as_iotas#hexcasting:close_paren)$(action)反思/$。$(br2)产生橙色火花,并压入一个$(l:patterns/patterns_as_iotas#hexcasting:close_paren)$(action)反思/$对应的图案。", - "too_deep.title": "钻研过深", - too_deep: "在一个法术内以元运行方式运行过多法术。$(br2)产生暗蓝色火花,并使我窒息。", + "too_many_patterns.title": "陷入沉思", + too_many_patterns: "在单个$(hex)咒术/$试图运行过多图案,通常是因为不小心制造了死循环。$(br2)产生暗蓝色火花,并使我窒息。", "true_name.title": "违犯他人", true_name: "试图在某种永久性媒介中$(l:patterns/readwrite#hexcasting:write)$(action)存储/$代表另一位玩家的 iota。$(br2)产生黑色火花,并致盲大约一分钟。", @@ -1555,7 +1553,7 @@ spellcircles: { "1": "我终于知道$(l:items/slate)$(item)石板/$的用途了。早已遗落的卓伟结构。镌刻其上的图案会按顺序自动运行。思维和能量在其中穿梭,一个接一个接一个接一个接一个穿梭穿梭穿梭——我不能我不能我不能跟着它的思维应该去理解。", - "2": "我需要$(l:greatwork/impetus)$(item)促动石/$作为一种自我维持的$(media)媒质/$波源来启动仪式。而产生的波就会随着$(l:items/slate)$(item)石板/$或是其他和这种波亲和性好的方块穿梭,一个接一个地收集碰到的图案。当波最终回到$(l:greatwork/impetus)$(item)促动石/$处时,所有碰到的图案就会按顺序运行。$(br2)$(media)媒质/$流出任何方块的方向必须唯一而确定,否则法术环会在分叉处失效。", + "2": "我需要$(l:greatwork/impetus)$(item)促动石/$作为一种自我维持的$(media)媒质/$波源来启动仪式。产生的波会随着$(l:items/slate)$(item)石板/$或是其他合适的方块穿梭,运行它碰到的图案。$(br2)如果波无法回到$(l:greatwork/impetus)$(item)促动石/$处,施法会立即失败。而且,波流出任何方块的方向必须唯一而确定,否则法术环会在分叉处失效。", "3": "因此,法术“环”必须是一个封闭的图形,凹多边形和凸多边形均可,方向也随意。实际上,借助某些其他方块,法术环可在所有三个维度上随意排布。这种性质可能没什么大用,但我必须给大脑一点刺激,好让研究继续下去。", "4": "真是精妙。法术环不会从我的物品栏或我的意识中汲取$(media)媒质/$,而是要通过漏斗(或类似装置)向$(l:greatwork/impetus)$(item)促动石/$提供晶态的$(media)媒质/$。$(br2)$(l:items/lens)$(item)探知透镜/$能以紫水晶粉为单位显示$(l:greatwork/impetus)$(item)促动石/$中的$(media)媒质/$量。", "5": "然而,用法术环施放的法术有一个限制:它无法影响环外的事物。也即,它无法影响到能将整个法术环包起的最小长方体外的事物(有凹进部分的法术环仍能影响凹进部分内的事物)。", @@ -1598,8 +1596,8 @@ quenching_allays: { "1": "$(l)它们就是小块媒质。/$我怎么没早点发现呢?它们——我是一堆血肉再加上一小点……是被赐予了一小点的思维,但悦灵是能维持自稳的媒质集群,再被按到一小点血肉上去。所有东西就都说得通了——它们对媒质的趋向性,它们对音乐的种种反应,$(l)我现在理解了/$,$(l)但/$为何前人$(l)没有/$?", "2": "理解这点后,唯一$(l)正确/$的选择就是去征服它们奇异的意识——它们奇异的自我——也是它们的全部、一个意识、一个自我、一段尾声。它们的性状似乎揭示了某些东西。我能……我能使用它们压缩$(media)媒质/$,将两束思维叠放在一起,形体与认知,多与一。$(br2)这个过程不知怎么的会自行产生$(media)媒质/$。这是怎么回事?也许——也许是$(l)我/$的缘故,是完成这项任务的过程——", - "3": "它不重要。我不重要。它们不重要,重要的只有功用。这就是了。$(br2)这肯定相当痛苦。", - "4": "所得的产物十分脆弱。直接破坏会将其打碎成碎片,$(thing)时运/$则能增加产量……如果需要获得方块本身,那要有精准采集才行。$(br2)产生的碎片相当于将 3 个$(l:items/amethyst)$(item)充能紫水晶/$拼在一起。方块则相当于 4 个碎片。", + "3": "它不重要。我不重要。它们不重要,重要的只有功用。这就是了。$(br2)这肯定相当痛苦。$(br2)十份$(l:items/amethyst)$(item)紫水晶粉/$,就是启动如此恶劣仪式的代价。", + "4": "所得的产物十分脆弱。直接破坏会将其打碎成碎片,$(thing)时运/$则能增加产量……如果需要获得方块本身,那要有精准采集才行。$(br2)产生的碎片相当于 3 个$(l:items/amethyst)$(item)充能紫水晶/$拼在一起。方块则相当于 4 个碎片。", "5": "它们变幻莫测,好像会在我的手中不断变形闪烁,若是给予它们来自另一种$(media)媒质/$形态的引导,它们便会变成对应的形态,且$(media)媒质/$总量前后不变。", }, @@ -1942,7 +1940,7 @@ "1": "$(italic)去吧!现在一切都已完成,$(br)只须留着一个人作哨卫。/$$(br2)$(l:patterns/spells/sentinels)$(thing)哨卫/$是一种能被$(hex)咒术/$召唤出的神秘力量,就和亲人或是侍卫一样。对我而言,它是一个旋转着的几何体,而其他人看不见它。", "2": "它有些有趣的性质:$(li)它似乎不可被触摸,没人摸得到它。$(li)只有我的$(hex)咒术/$才能与之交互。$(li)一旦召唤,在被驱除前它都将留在原位。$(li)只要我离它足够近,我就能透过方块看见它。", - "sentinel/create": "在给定位置召唤哨卫$(l:patterns/spells/sentinels)$(thing)哨卫/$。消耗大约 1 个$(l:items/amethyst)$(item)紫水晶粉/$。", + "sentinel/create": "在给定位置召唤$(l:patterns/spells/sentinels)$(thing)哨卫/$。消耗大约 1 个$(l:items/amethyst)$(item)紫水晶粉/$。", "sentinel/destroy": "将我的$(l:patterns/spells/sentinels)$(thing)哨卫/$从世界中驱除出去。消耗极少量$(media)媒质/$。", "sentinel/get_pos": "将我的$(l:patterns/spells/sentinels)$(thing)哨卫/$的位置加到栈中,若并未召唤则加入一个 $(l:casting/influences)$(thing)Null/$。消耗极少量$(media)媒质/$。", "sentinel/wayfind": "将栈顶的位置向量变为从我的位置指向$(l:patterns/spells/sentinels)$(thing)哨卫/$的单位向量,若并未召唤则变为 $(l:casting/influences)$(thing)Null/$。消耗极少量$(media)媒质/$。", @@ -1961,6 +1959,10 @@ "time.1": "受时间限制的飞行法术。", "time.2": "第二参数代表持续时间(以秒计),在此限制内,法术能保持稳定。持续时间超过限制就会结束该法术,滞空的物体会直接坠向地面。$(br2)此法术相对较昂贵,每秒持续时间消耗大约 1 个$(l:items/amethyst)$(item)充能紫水晶/$。我觉得它极其适合长途旅行。", + + // Putting this in this category instead of elsewhere -- see sentinel chapter also containing some reflections/nonspells + "can_fly.1": "检查玩家是否处于$(l:patterns/spells/flight#hexcasting:flight/range)隐士之飞行/$或$(l:patterns/spells/flight#hexcasting:flight/time)旅者之飞行/$的影响之下。", + "can_fly.2": "不会检查玩家是否能以其他方式飞行。$(br2)我不太清楚这个图案有什么用途,但我相信,愿意用它的人自会清楚。" }, create_lava: { diff --git a/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/casting/mishaps.json b/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/casting/mishaps.json index 08fb6d0335..5a01a51556 100644 --- a/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/casting/mishaps.json +++ b/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/casting/mishaps.json @@ -75,8 +75,8 @@ }, { "type": "patchouli:text", - "title": "hexcasting.page.mishaps.too_deep.title", - "text": "hexcasting.page.mishaps.too_deep" + "title": "hexcasting.page.mishaps.too_many_patterns.title", + "text": "hexcasting.page.mishaps.too_many_patterns" }, { "type": "patchouli:text", diff --git a/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/casting/vectors.json b/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/casting/vectors.json index 5823bfa7a3..bf28be0282 100644 --- a/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/casting/vectors.json +++ b/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/casting/vectors.json @@ -20,7 +20,7 @@ "type": "patchouli:link", "text": "hexcasting.page.vectors.3", "link_text": "hexcasting.page.vectors.3.link_text", - "url": "https://psi.vazkii.us/codex.php#vectorPrimer" + "url": "https://psi.vazkii.net/codex.php#vectorPrimer" } ] } diff --git a/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/greatwork/akashiclib.json b/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/greatwork/akashiclib.json index 25cfde8ead..ad63b36001 100644 --- a/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/greatwork/akashiclib.json +++ b/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/greatwork/akashiclib.json @@ -22,7 +22,7 @@ { "type": "patchouli:crafting", "recipe": "hexcasting:akashic_bookshelf", - "recipe2": "hexcasting:akashic_connector" + "recipe2": "hexcasting:akashic_ligature" }, { "type": "patchouli:text", diff --git a/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/items/ancient_cyphers.json b/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/items/ancient_cyphers.json new file mode 100644 index 0000000000..9a000fea58 --- /dev/null +++ b/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/items/ancient_cyphers.json @@ -0,0 +1,18 @@ +{ + "name": "hexcasting.entry.ancient_cyphers", + "category": "hexcasting:items", + "icon": "hexcasting:ancient_cypher", + "sortnum": 7, + "advancement": "hexcasting:root", + "pages": [ + { + "type": "patchouli:text", + "text": "hexcasting.page.ancient_cyphers.1" + }, + { + "type": "patchouli:spotlight", + "text": "hexcasting.page.ancient_cyphers.2", + "item": "hexcasting:ancient_cypher[hexcasting:variant=0],hexcasting:ancient_cypher[hexcasting:variant=1],hexcasting:ancient_cypher[hexcasting:variant=2],hexcasting:ancient_cypher[hexcasting:variant=3],hexcasting:ancient_cypher[hexcasting:variant=4],hexcasting:ancient_cypher[hexcasting:variant=5],hexcasting:ancient_cypher[hexcasting:variant=6],hexcasting:ancient_cypher[hexcasting:variant=7]" + } + ] + } \ No newline at end of file diff --git a/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/items/hexcasting.json b/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/items/hexcasting.json index b28262d6b8..03e8990b3a 100644 --- a/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/items/hexcasting.json +++ b/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/items/hexcasting.json @@ -1,7 +1,7 @@ { "name": "hexcasting.entry.hexcasting", "category": "hexcasting:items", - "icon": "hexcasting:artifact{patterns:[]}", + "icon": "hexcasting:artifact", "sortnum": 6, "advancement": "hexcasting:root", "pages": [ diff --git a/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/items/phials.json b/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/items/phials.json index 0f930d1ec8..7e264464fe 100644 --- a/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/items/phials.json +++ b/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/items/phials.json @@ -21,7 +21,7 @@ { "type": "patchouli:spotlight", "text": "hexcasting.page.phials.desc", - "item": "hexcasting:battery{\"hexcasting:media\":640000,\"hexcasting:start_media\":640000}", + "item": "hexcasting:battery[hexcasting:media=640000,hexcasting:start_media=640000]", "link_recipe": true } ] diff --git a/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/items/potions.json b/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/items/potions.json index a0db5dd70b..fcc3d2ff9f 100644 --- a/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/items/potions.json +++ b/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/items/potions.json @@ -1,7 +1,7 @@ { "name": "hexcasting.entry.potions", "category": "hexcasting:items", - "icon": "minecraft:potion{Potion:\"hexcasting:enlarge_grid\"}", + "icon": "minecraft:potion[minecraft:potion_contents={potion:\"hexcasting:enlarge_grid\"}]", "sortnum": 8, "advancement": "hexcasting:root", "read_by_default": true, @@ -14,7 +14,7 @@ "type": "patchouli:spotlight", "title": "hexcasting.page.potions.effects.header", "text": "hexcasting.page.potions.2", - "item": "minecraft:potion{Potion:\"hexcasting:enlarge_grid\"},minecraft:potion{Potion:\"hexcasting:enlarge_grid_long\"},minecraft:potion{Potion:\"hexcasting:enlarge_grid_strong\"},minecraft:potion{Potion:\"hexcasting:shrink_grid\"},minecraft:potion{Potion:\"hexcasting:shrink_grid_long\"},minecraft:potion{Potion:\"hexcasting:shrink_grid_strong\"}" + "item": "minecraft:potion[minecraft:potion_contents={potion:\"hexcasting:enlarge_grid\"}],minecraft:potion[minecraft:potion_contents={potion:\"hexcasting:enlarge_grid_long\"}],minecraft:potion[minecraft:potion_contents={potion:\"hexcasting:enlarge_grid_strong\"}],minecraft:potion[minecraft:potion_contents={potion:\"hexcasting:shrink_grid\"}],minecraft:potion[minecraft:potion_contents={potion:\"hexcasting:shrink_grid_long\"}],minecraft:potion[minecraft:potion_contents={potion:\"hexcasting:shrink_grid_strong\"}]" } ] } diff --git a/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/items/staff.json b/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/items/staff.json index 9e89746d5a..8ea8dab475 100644 --- a/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/items/staff.json +++ b/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/items/staff.json @@ -24,6 +24,8 @@ "hexcasting:staff/crimson", "hexcasting:staff/warped", "hexcasting:staff/mangrove", + "hexcasting:staff/bamboo", + "hexcasting:staff/cherry", "hexcasting:staff/edified" ] } diff --git a/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/patterns/great_spells/make_battery.json b/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/patterns/great_spells/make_battery.json index 2ffd387b21..94c15f5bd1 100644 --- a/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/patterns/great_spells/make_battery.json +++ b/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/patterns/great_spells/make_battery.json @@ -1,7 +1,7 @@ { "name": "hexcasting.action.hexcasting:craft/battery", "category": "hexcasting:patterns/great_spells", - "icon": "hexcasting:battery{media:10000,max_media:10000}", + "icon": "hexcasting:battery[hexcasting:media=10000,hexcasting:start_media=10000]", "sortnum": 6, "advancement": "hexcasting:root", "read_by_default": true, diff --git a/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/patterns/great_spells/zeniths.json b/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/patterns/great_spells/zeniths.json index b5899a67c3..476fe9083b 100644 --- a/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/patterns/great_spells/zeniths.json +++ b/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/patterns/great_spells/zeniths.json @@ -1,7 +1,7 @@ { "name": "hexcasting.entry.zeniths", "category": "hexcasting:patterns/great_spells", - "icon": "minecraft:potion{Potion:'minecraft:regeneration'}", + "icon": "minecraft:potion[minecraft:potion_contents={potion:\"minecraft:regeneration\"}]", "advancement": "hexcasting:root", "sortnum": 4, "read_by_default": true, diff --git a/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/patterns/spells/hexcasting.json b/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/patterns/spells/hexcasting.json index 06cd64b47f..fbbdbc5d40 100644 --- a/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/patterns/spells/hexcasting.json +++ b/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/patterns/spells/hexcasting.json @@ -1,7 +1,7 @@ { "name": "hexcasting.entry.hexcasting_spell", "category": "hexcasting:patterns/spells", - "icon": "hexcasting:artifact{patterns:[]}", + "icon": "hexcasting:artifact", "sortnum": 3, "advancement": "hexcasting:root", "read_by_default": true, diff --git a/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/patterns/spells/nadirs.json b/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/patterns/spells/nadirs.json index 8d7efd5c11..37374393c1 100644 --- a/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/patterns/spells/nadirs.json +++ b/Common/src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us/entries/patterns/spells/nadirs.json @@ -1,7 +1,7 @@ { "name": "hexcasting.entry.nadirs", "category": "hexcasting:patterns/spells", - "icon": "minecraft:potion{Potion:'minecraft:poison'}", + "icon": "minecraft:potion[minecraft:potion_contents={potion:\"minecraft:poison\"}]", "advancement": "hexcasting:root", "sortnum": 2, "read_by_default": true, diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/cad/0_ancient_cypher.png b/Common/src/main/resources/assets/hexcasting/textures/item/cad/0_ancient_cypher.png new file mode 100644 index 0000000000..844e9eca1d Binary files /dev/null and b/Common/src/main/resources/assets/hexcasting/textures/item/cad/0_ancient_cypher.png differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/cad/0_ancient_cypher_overlay.png b/Common/src/main/resources/assets/hexcasting/textures/item/cad/0_ancient_cypher_overlay.png new file mode 100644 index 0000000000..95df139be8 Binary files /dev/null and b/Common/src/main/resources/assets/hexcasting/textures/item/cad/0_ancient_cypher_overlay.png differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/cad/1_ancient_cypher.png b/Common/src/main/resources/assets/hexcasting/textures/item/cad/1_ancient_cypher.png new file mode 100644 index 0000000000..ac4ca4c8bb Binary files /dev/null and b/Common/src/main/resources/assets/hexcasting/textures/item/cad/1_ancient_cypher.png differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/cad/1_ancient_cypher_overlay.png b/Common/src/main/resources/assets/hexcasting/textures/item/cad/1_ancient_cypher_overlay.png new file mode 100644 index 0000000000..9cecaa2933 Binary files /dev/null and b/Common/src/main/resources/assets/hexcasting/textures/item/cad/1_ancient_cypher_overlay.png differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/cad/2_ancient_cypher.png b/Common/src/main/resources/assets/hexcasting/textures/item/cad/2_ancient_cypher.png new file mode 100644 index 0000000000..7fc5a246f5 Binary files /dev/null and b/Common/src/main/resources/assets/hexcasting/textures/item/cad/2_ancient_cypher.png differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/cad/2_ancient_cypher_overlay.png b/Common/src/main/resources/assets/hexcasting/textures/item/cad/2_ancient_cypher_overlay.png new file mode 100644 index 0000000000..f0ea5738a5 Binary files /dev/null and b/Common/src/main/resources/assets/hexcasting/textures/item/cad/2_ancient_cypher_overlay.png differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/cad/3_ancient_cypher.png b/Common/src/main/resources/assets/hexcasting/textures/item/cad/3_ancient_cypher.png new file mode 100644 index 0000000000..3aae1ef12b Binary files /dev/null and b/Common/src/main/resources/assets/hexcasting/textures/item/cad/3_ancient_cypher.png differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/cad/3_ancient_cypher_overlay.png b/Common/src/main/resources/assets/hexcasting/textures/item/cad/3_ancient_cypher_overlay.png new file mode 100644 index 0000000000..911afbadde Binary files /dev/null and b/Common/src/main/resources/assets/hexcasting/textures/item/cad/3_ancient_cypher_overlay.png differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/cad/4_ancient_cypher.png b/Common/src/main/resources/assets/hexcasting/textures/item/cad/4_ancient_cypher.png new file mode 100644 index 0000000000..e52c0d34d4 Binary files /dev/null and b/Common/src/main/resources/assets/hexcasting/textures/item/cad/4_ancient_cypher.png differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/cad/4_ancient_cypher_overlay.png b/Common/src/main/resources/assets/hexcasting/textures/item/cad/4_ancient_cypher_overlay.png new file mode 100644 index 0000000000..e5a60b5f0c Binary files /dev/null and b/Common/src/main/resources/assets/hexcasting/textures/item/cad/4_ancient_cypher_overlay.png differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/cad/5_ancient_cypher.png b/Common/src/main/resources/assets/hexcasting/textures/item/cad/5_ancient_cypher.png new file mode 100644 index 0000000000..a17fcfc223 Binary files /dev/null and b/Common/src/main/resources/assets/hexcasting/textures/item/cad/5_ancient_cypher.png differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/cad/5_ancient_cypher_overlay.png b/Common/src/main/resources/assets/hexcasting/textures/item/cad/5_ancient_cypher_overlay.png new file mode 100644 index 0000000000..2847ac3bdc Binary files /dev/null and b/Common/src/main/resources/assets/hexcasting/textures/item/cad/5_ancient_cypher_overlay.png differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/cad/6_ancient_cypher.png b/Common/src/main/resources/assets/hexcasting/textures/item/cad/6_ancient_cypher.png new file mode 100644 index 0000000000..509b48f17d Binary files /dev/null and b/Common/src/main/resources/assets/hexcasting/textures/item/cad/6_ancient_cypher.png differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/cad/6_ancient_cypher_overlay.png b/Common/src/main/resources/assets/hexcasting/textures/item/cad/6_ancient_cypher_overlay.png new file mode 100644 index 0000000000..dab10d51a5 Binary files /dev/null and b/Common/src/main/resources/assets/hexcasting/textures/item/cad/6_ancient_cypher_overlay.png differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/cad/7_ancient_cypher.png b/Common/src/main/resources/assets/hexcasting/textures/item/cad/7_ancient_cypher.png new file mode 100644 index 0000000000..77f72ab422 Binary files /dev/null and b/Common/src/main/resources/assets/hexcasting/textures/item/cad/7_ancient_cypher.png differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/cad/7_ancient_cypher_overlay.png b/Common/src/main/resources/assets/hexcasting/textures/item/cad/7_ancient_cypher_overlay.png new file mode 100644 index 0000000000..ac56ac22cf Binary files /dev/null and b/Common/src/main/resources/assets/hexcasting/textures/item/cad/7_ancient_cypher_overlay.png differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/scroll_ancient_large.png b/Common/src/main/resources/assets/hexcasting/textures/item/scroll_ancient_large.png index b81f651b73..04bc429df4 100644 Binary files a/Common/src/main/resources/assets/hexcasting/textures/item/scroll_ancient_large.png and b/Common/src/main/resources/assets/hexcasting/textures/item/scroll_ancient_large.png differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/scroll_ancient_medium.png b/Common/src/main/resources/assets/hexcasting/textures/item/scroll_ancient_medium.png index 58adf2fc4d..90f4877fa5 100644 Binary files a/Common/src/main/resources/assets/hexcasting/textures/item/scroll_ancient_medium.png and b/Common/src/main/resources/assets/hexcasting/textures/item/scroll_ancient_medium.png differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/scroll_ancient_small.png b/Common/src/main/resources/assets/hexcasting/textures/item/scroll_ancient_small.png index 88a87a7720..aabd00acae 100644 Binary files a/Common/src/main/resources/assets/hexcasting/textures/item/scroll_ancient_small.png and b/Common/src/main/resources/assets/hexcasting/textures/item/scroll_ancient_small.png differ diff --git a/Common/src/main/resources/data/hexcasting/advancements/grant_patchi_book.json b/Common/src/main/resources/data/hexcasting/advancement/grant_patchi_book.json similarity index 100% rename from Common/src/main/resources/data/hexcasting/advancements/grant_patchi_book.json rename to Common/src/main/resources/data/hexcasting/advancement/grant_patchi_book.json diff --git a/Common/src/main/resources/data/hexcasting/item_modifiers/amethyst_shard_reducer.json b/Common/src/main/resources/data/hexcasting/item_modifier/amethyst_shard_reducer.json similarity index 100% rename from Common/src/main/resources/data/hexcasting/item_modifiers/amethyst_shard_reducer.json rename to Common/src/main/resources/data/hexcasting/item_modifier/amethyst_shard_reducer.json diff --git a/Common/src/main/resources/data/hexcasting/loot_tables/grant_patchi_book.json b/Common/src/main/resources/data/hexcasting/loot_table/grant_patchi_book.json similarity index 100% rename from Common/src/main/resources/data/hexcasting/loot_tables/grant_patchi_book.json rename to Common/src/main/resources/data/hexcasting/loot_table/grant_patchi_book.json diff --git a/Common/src/main/resources/data/hexcasting/recipes/patchi_book.json b/Common/src/main/resources/data/hexcasting/recipe/patchi_book.json similarity index 100% rename from Common/src/main/resources/data/hexcasting/recipes/patchi_book.json rename to Common/src/main/resources/data/hexcasting/recipe/patchi_book.json diff --git a/Common/src/main/resources/data/hexcasting/tags/entity_types/cannot_teleport.json b/Common/src/main/resources/data/hexcasting/tags/entity_type/cannot_teleport.json similarity index 100% rename from Common/src/main/resources/data/hexcasting/tags/entity_types/cannot_teleport.json rename to Common/src/main/resources/data/hexcasting/tags/entity_type/cannot_teleport.json diff --git a/Common/src/main/resources/data/hexcasting/tags/entity_types/sticky_teleporters.json b/Common/src/main/resources/data/hexcasting/tags/entity_type/sticky_teleporters.json similarity index 100% rename from Common/src/main/resources/data/hexcasting/tags/entity_types/sticky_teleporters.json rename to Common/src/main/resources/data/hexcasting/tags/entity_type/sticky_teleporters.json diff --git a/Common/src/main/resources/data/minecraft/tags/items/cluster_max_harvestables.json b/Common/src/main/resources/data/minecraft/tags/item/cluster_max_harvestables.json similarity index 100% rename from Common/src/main/resources/data/minecraft/tags/items/cluster_max_harvestables.json rename to Common/src/main/resources/data/minecraft/tags/item/cluster_max_harvestables.json diff --git a/Common/src/main/resources/hexplat.accesswidener b/Common/src/main/resources/hexplat.accesswidener index d8a1955d13..d60621d9cf 100644 --- a/Common/src/main/resources/hexplat.accesswidener +++ b/Common/src/main/resources/hexplat.accesswidener @@ -1,10 +1,10 @@ accessWidener v1 named -accessible class net/minecraft/client/renderer/RenderType$CompositeRenderType -accessible class net/minecraft/client/renderer/RenderType$CompositeState -accessible field net/minecraft/client/renderer/RenderType$CompositeState textureState Lnet/minecraft/client/renderer/RenderStateShard$EmptyTextureStateShard; -accessible class net/minecraft/client/renderer/RenderStateShard$EmptyTextureStateShard -accessible class net/minecraft/world/item/crafting/Ingredient$Value -accessible method net/minecraft/world/item/crafting/Ingredient (Ljava/util/stream/Stream;)V -accessible method net/minecraft/world/item/context/UseOnContext (Lnet/minecraft/world/level/Level;Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/world/InteractionHand;Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/phys/BlockHitResult;)V -accessible method net/minecraft/world/damagesource/DamageSources source (Lnet/minecraft/resources/ResourceKey;)Lnet/minecraft/world/damagesource/DamageSource; -accessible method net/minecraft/world/damagesource/DamageSources source (Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/world/entity/Entity;)Lnet/minecraft/world/damagesource/DamageSource; \ No newline at end of file +accessible class net/minecraft/client/renderer/RenderType$CompositeRenderType +accessible class net/minecraft/client/renderer/RenderType$CompositeState +accessible field net/minecraft/client/renderer/RenderType$CompositeState textureState Lnet/minecraft/client/renderer/RenderStateShard$EmptyTextureStateShard; +accessible class net/minecraft/client/renderer/RenderStateShard$EmptyTextureStateShard +accessible class net/minecraft/world/item/crafting/Ingredient$Value +accessible method net/minecraft/world/item/crafting/Ingredient (Ljava/util/stream/Stream;)V +#accessible method net/minecraft/world/item/context/UseOnContext (Lnet/minecraft/world/level/Level;Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/world/InteractionHand;Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/phys/BlockHitResult;)V +#accessible method net/minecraft/world/damagesource/DamageSources source (Lnet/minecraft/resources/ResourceKey;)Lnet/minecraft/world/damagesource/DamageSource; +#accessible method net/minecraft/world/damagesource/DamageSources source (Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/world/entity/Entity;)Lnet/minecraft/world/damagesource/DamageSource; \ No newline at end of file diff --git a/Common/src/main/resources/hexplat.mixins.json b/Common/src/main/resources/hexplat.mixins.json index 11f0dde236..39a6da0bd1 100644 --- a/Common/src/main/resources/hexplat.mixins.json +++ b/Common/src/main/resources/hexplat.mixins.json @@ -9,16 +9,14 @@ "MixinMob", "MixinRaider", "MixinVillager", + "MixinWanderingTrader", "MixinWitch", "accessor.AccessorAbstractArrow", - "accessor.AccessorDamageSource", "accessor.AccessorEntity", "accessor.AccessorLivingEntity", "accessor.AccessorLootTable", - "accessor.AccessorPotionBrewing", "accessor.AccessorUseOnContext", - "accessor.AccessorVillager", - "accessor.CriteriaTriggersAccessor" + "accessor.AccessorVillager" ], "client": [ "accessor.client.AccessorBlockEntityRenderDispatcher", diff --git a/Fabric/build.gradle b/Fabric/build.gradle index ff0e8b62d7..73a876162b 100644 --- a/Fabric/build.gradle +++ b/Fabric/build.gradle @@ -12,9 +12,17 @@ pkSubproj { pkPublish = true curseforgeJar = remapJar.archiveFile - curseforgeDependencies[] + curseforgeDependencies([ + "paucal:0.6.0", "patchouli:1.20.1-80", "fabric-language-kotlin:1.9.4+kotlin.1.8.21", + "inline:1.20.1-1.0.1", "cloth-config:11.1.0", + "cardinal-components-api:5.2.1", "fabric-api:0.84" + ]) modrinthJar = remapJar.archiveFile - modrinthDependencies[] + modrinthDependencies([ + "paucal:0.6.0", "patchouli:1.20.1-80", "fabric-language-kotlin:1.9.4+kotlin.1.8.21", + "inline:1.20.1-1.0.1", "cloth-config:11.1.0", + "cardinal-components-api:5.2.1", "fabric-api:0.84" + ]) } diff --git a/Fabric/src/generated/resources/.cache/19f2b40f78e342d65a8cb499a41e3fcb2eadaca3 b/Fabric/src/generated/resources/.cache/19f2b40f78e342d65a8cb499a41e3fcb2eadaca3 index 6b6009aeea..a2a95b576a 100644 --- a/Fabric/src/generated/resources/.cache/19f2b40f78e342d65a8cb499a41e3fcb2eadaca3 +++ b/Fabric/src/generated/resources/.cache/19f2b40f78e342d65a8cb499a41e3fcb2eadaca3 @@ -1,58 +1,58 @@ -// 1.20.1 2024-11-19T11:30:28.198417333 Hex Casting/Loot Tables -1dd4268edf7d6fa247013ab45541c7bfb915eef8 data/hexcasting/loot_tables/blocks/amethyst_bricks_small.json -601384d888edab27efe4a33027bb557eb7cb6ca2 data/hexcasting/loot_tables/blocks/edified_log_purple.json -2c9af74a82ca462e5986354966d5a0a1fd5a2083 data/hexcasting/loot_tables/blocks/slate_tiles.json -7c9c94d5b6b570d25eff32d4fa2ecc1e842e5231 data/hexcasting/loot_tables/blocks/quenched_allay_tiles.json -ecaeb4d5703a7aa206627ed38ee71aeb7e93d688 data/hexcasting/loot_tables/blocks/impetus/rightclick.json -a4e0194d8966a24531e43e04437cdb2a96456898 data/hexcasting/loot_tables/blocks/edified_tile.json -847bc3ead8a88a8f210a24e7732c28d50aa2f5dc data/hexcasting/loot_tables/blocks/edified_planks.json -92331eb19422730ffda0a3e52427a75aa1f7aff2 data/hexcasting/loot_tables/blocks/ancient_scroll_paper_lantern.json -4efd95d408d050c36ff21b18f3c37116491fef92 data/hexcasting/loot_tables/blocks/directrix/redstone.json -8c6c0486170537d73b923a2b9f83722107fc8716 data/hexcasting/loot_tables/blocks/edified_log_aventurine.json -ab86e126a704550d3f21c0b43f99fdc2665e4b09 data/hexcasting/loot_tables/blocks/slate_amethyst_tiles.json -7123b1a0469d7bd5bf8a2772182d222bf354df1a data/hexcasting/loot_tables/blocks/slate_bricks_small.json -b6c23fdde4f2c22c81f008604d5ff1c32ca8eb61 data/hexcasting/loot_tables/blocks/amethyst_tiles.json -b706c8a064f717c57104c48ea42aa860b45cf7a4 data/hexcasting/loot_tables/blocks/amethyst_dust_block.json -6eecc98b606d7ea5ec6f4c1fa4f63f7c1eba9223 data/hexcasting/loot_tables/blocks/slate_amethyst_bricks.json -b19ac49146149555038e6d2e06200d514df1ef43 data/hexcasting/loot_tables/blocks/akashic_bookshelf.json -9ff760d5db5628328ea9274c98e18a08f1ab983e data/hexcasting/loot_tables/blocks/slate_block.json -2ab674e834184b4e17dc002556d4473cac137445 data/hexcasting/loot_tables/blocks/edified_slab.json -df5496da8e48b61a171bc7a3936495c016cc002e data/hexcasting/loot_tables/blocks/directrix/empty.json -49940d1cb2599212e2837d7ed66c6c66e54f80f8 data/hexcasting/loot_tables/blocks/akashic_record.json -c81a5cb81141ab1fe09dd5dd3a0968b69dfffbd7 data/hexcasting/loot_tables/blocks/stripped_edified_log.json -10cb1b94596ac7131efe3bd5c36c1543ddba9302 data/hexcasting/loot_tables/blocks/impetus/redstone.json -499af9f15cf0a7f16fd2939e5d3af60a8089cc3e data/hexcasting/loot_tables/blocks/slate_bricks.json -147e0739a712a9050856cebcad1757b3f418f647 data/hexcasting/loot_tables/blocks/edified_trapdoor.json -2ad288784b0dc106ace2e6e0a40669f83476c414 data/hexcasting/loot_tables/blocks/slate.json -6c35afda4ca349f3506fe08f86f0afe58a6f2c44 data/hexcasting/loot_tables/blocks/quenched_allay.json -e6ff979aa47877c1b807075c448defd249cd3484 data/hexcasting/loot_tables/blocks/slate_amethyst_pillar.json -55f265961463a89c243ec8ac1970c70185f064a6 data/hexcasting/loot_tables/blocks/edified_button.json -c15d3ced89c882dfe552f84435fcdd560b729567 data/hexcasting/loot_tables/blocks/scroll_paper.json -1c6b077aae560e780be29e74ddcd4b0ca10ce3cf data/hexcasting/loot_tables/blocks/impetus/empty.json -dc4c6d270b8e93d05ac8ddeb1b9dd1d64828ac5d data/hexcasting/loot_tables/blocks/stripped_edified_wood.json -a62ffbcec2aa40172e05cd9fcd8e70e295d008e9 data/hexcasting/loot_tables/blocks/edified_fence_gate.json -cc7313cc33609fe1120baa7b4db631eaa29fbba1 data/hexcasting/loot_tables/blocks/citrine_edified_leaves.json -6920654f50532b5e557646e34edc4872339eb79f data/hexcasting/loot_tables/blocks/edified_log_amethyst.json -849afa706e7479d1c11bb40ae223ae5833e71286 data/hexcasting/loot_tables/blocks/scroll_paper_lantern.json -9905b767be7849e02a8e4ec4170af1bdde4e7fab data/hexcasting/loot_tables/blocks/edified_stairs.json -92528799c8ee13ff26c3c505e4dfb286c30f97c7 data/hexcasting/loot_tables/blocks/akashic_connector.json -45dc91d820caa5c421fe6f2afc7f71e45d6acd4d data/hexcasting/loot_tables/blocks/slate_pillar.json -1a1236e54c24b5aeff05919c73c76151da2cf115 data/hexcasting/loot_tables/blocks/amethyst_sconce.json -74159c21634679a6ab1dde1c181433db8b31c6ae data/hexcasting/loot_tables/blocks/edified_log_citrine.json -30f06db8c1ea74c9f4d95474e412336d065ac888 data/hexcasting/loot_tables/blocks/edified_door.json -95be0cf7f277257671631929462131b6d611119a data/hexcasting/loot_tables/inject/amethyst_cluster.json -bedbc2bd04f79372aedea64214ba2ea49cde9640 data/hexcasting/loot_tables/blocks/amethyst_edified_leaves.json -44658abcf122575878834d276ebcf5d8a6b7b398 data/hexcasting/loot_tables/blocks/aventurine_edified_leaves.json -cf6ff1ed1ee6fdbb05af16468a0a0ced79ac334e data/hexcasting/loot_tables/blocks/amethyst_bricks.json -45ae0ec668a07aa5b33d491377b2978f69f9f019 data/hexcasting/loot_tables/blocks/edified_panel.json -5f8d09e8c759d05cf9c2265ae28ea942cfbbe2be data/hexcasting/loot_tables/blocks/edified_pressure_plate.json -c426245d51f1e0fa0db7c4bfb454284d75506c9c data/hexcasting/loot_tables/blocks/quenched_allay_bricks.json -0b734693c926045b60fb515814b7a6695d0295fc data/hexcasting/loot_tables/blocks/impetus/look.json -d16fa9e366d48646686470c2d1f9bda4db3a1afa data/hexcasting/loot_tables/blocks/ancient_scroll_paper.json -2ac70e3c3600c88b2544d9755fc634216a7a523c data/hexcasting/loot_tables/blocks/edified_wood.json -509ecbb9731e75b63638c6012b2f986f131fd42f data/hexcasting/loot_tables/blocks/slate_amethyst_bricks_small.json -2902c4dae60875a1b2daf0a948a49a3419d8ec9d data/hexcasting/loot_tables/blocks/edified_log.json -434c2a6d2645e56e9a6ca56249ffa84645558e3b data/hexcasting/loot_tables/blocks/quenched_allay_bricks_small.json -65fe724d4c4ba8b0ab7d7a11bf37687413d9119d data/hexcasting/loot_tables/blocks/edified_fence.json -f1145860d80ff053970b1ad4f3b2f5d9f28e7c73 data/hexcasting/loot_tables/blocks/directrix/boolean.json -8ea8fd68719a960c2e132df441564a70c0e376a8 data/hexcasting/loot_tables/blocks/amethyst_pillar.json +// 1.20.1 2025-01-23T15:50:44.3944222 Hex Casting/Loot Tables +4efd95d408d050c36ff21b18f3c37116491fef92 data\hexcasting\loot_tables\blocks\directrix\redstone.json +c81a5cb81141ab1fe09dd5dd3a0968b69dfffbd7 data\hexcasting\loot_tables\blocks\stripped_edified_log.json +a62ffbcec2aa40172e05cd9fcd8e70e295d008e9 data\hexcasting\loot_tables\blocks\edified_fence_gate.json +8ea8fd68719a960c2e132df441564a70c0e376a8 data\hexcasting\loot_tables\blocks\amethyst_pillar.json +9905b767be7849e02a8e4ec4170af1bdde4e7fab data\hexcasting\loot_tables\blocks\edified_stairs.json +0b734693c926045b60fb515814b7a6695d0295fc data\hexcasting\loot_tables\blocks\impetus\look.json +ab86e126a704550d3f21c0b43f99fdc2665e4b09 data\hexcasting\loot_tables\blocks\slate_amethyst_tiles.json +2c9af74a82ca462e5986354966d5a0a1fd5a2083 data\hexcasting\loot_tables\blocks\slate_tiles.json +bedbc2bd04f79372aedea64214ba2ea49cde9640 data\hexcasting\loot_tables\blocks\amethyst_edified_leaves.json +45dc91d820caa5c421fe6f2afc7f71e45d6acd4d data\hexcasting\loot_tables\blocks\slate_pillar.json +6c35afda4ca349f3506fe08f86f0afe58a6f2c44 data\hexcasting\loot_tables\blocks\quenched_allay.json +2902c4dae60875a1b2daf0a948a49a3419d8ec9d data\hexcasting\loot_tables\blocks\edified_log.json +95be0cf7f277257671631929462131b6d611119a data\hexcasting\loot_tables\inject\amethyst_cluster.json +b19ac49146149555038e6d2e06200d514df1ef43 data\hexcasting\loot_tables\blocks\akashic_bookshelf.json +c426245d51f1e0fa0db7c4bfb454284d75506c9c data\hexcasting\loot_tables\blocks\quenched_allay_bricks.json +6920654f50532b5e557646e34edc4872339eb79f data\hexcasting\loot_tables\blocks\edified_log_amethyst.json +6eecc98b606d7ea5ec6f4c1fa4f63f7c1eba9223 data\hexcasting\loot_tables\blocks\slate_amethyst_bricks.json +2ad288784b0dc106ace2e6e0a40669f83476c414 data\hexcasting\loot_tables\blocks\slate.json +49940d1cb2599212e2837d7ed66c6c66e54f80f8 data\hexcasting\loot_tables\blocks\akashic_record.json +d16fa9e366d48646686470c2d1f9bda4db3a1afa data\hexcasting\loot_tables\blocks\ancient_scroll_paper.json +cc7313cc33609fe1120baa7b4db631eaa29fbba1 data\hexcasting\loot_tables\blocks\citrine_edified_leaves.json +df5496da8e48b61a171bc7a3936495c016cc002e data\hexcasting\loot_tables\blocks\directrix\empty.json +92528799c8ee13ff26c3c505e4dfb286c30f97c7 data\hexcasting\loot_tables\blocks\akashic_connector.json +434c2a6d2645e56e9a6ca56249ffa84645558e3b data\hexcasting\loot_tables\blocks\quenched_allay_bricks_small.json +601384d888edab27efe4a33027bb557eb7cb6ca2 data\hexcasting\loot_tables\blocks\edified_log_purple.json +45ae0ec668a07aa5b33d491377b2978f69f9f019 data\hexcasting\loot_tables\blocks\edified_panel.json +55f265961463a89c243ec8ac1970c70185f064a6 data\hexcasting\loot_tables\blocks\edified_button.json +7123b1a0469d7bd5bf8a2772182d222bf354df1a data\hexcasting\loot_tables\blocks\slate_bricks_small.json +509ecbb9731e75b63638c6012b2f986f131fd42f data\hexcasting\loot_tables\blocks\slate_amethyst_bricks_small.json +74159c21634679a6ab1dde1c181433db8b31c6ae data\hexcasting\loot_tables\blocks\edified_log_citrine.json +1dd4268edf7d6fa247013ab45541c7bfb915eef8 data\hexcasting\loot_tables\blocks\amethyst_bricks_small.json +499af9f15cf0a7f16fd2939e5d3af60a8089cc3e data\hexcasting\loot_tables\blocks\slate_bricks.json +30f06db8c1ea74c9f4d95474e412336d065ac888 data\hexcasting\loot_tables\blocks\edified_door.json +7c9c94d5b6b570d25eff32d4fa2ecc1e842e5231 data\hexcasting\loot_tables\blocks\quenched_allay_tiles.json +65fe724d4c4ba8b0ab7d7a11bf37687413d9119d data\hexcasting\loot_tables\blocks\edified_fence.json +cf6ff1ed1ee6fdbb05af16468a0a0ced79ac334e data\hexcasting\loot_tables\blocks\amethyst_bricks.json +8c6c0486170537d73b923a2b9f83722107fc8716 data\hexcasting\loot_tables\blocks\edified_log_aventurine.json +dc4c6d270b8e93d05ac8ddeb1b9dd1d64828ac5d data\hexcasting\loot_tables\blocks\stripped_edified_wood.json +2ab674e834184b4e17dc002556d4473cac137445 data\hexcasting\loot_tables\blocks\edified_slab.json +e6ff979aa47877c1b807075c448defd249cd3484 data\hexcasting\loot_tables\blocks\slate_amethyst_pillar.json +9ff760d5db5628328ea9274c98e18a08f1ab983e data\hexcasting\loot_tables\blocks\slate_block.json +f1145860d80ff053970b1ad4f3b2f5d9f28e7c73 data\hexcasting\loot_tables\blocks\directrix\boolean.json +44658abcf122575878834d276ebcf5d8a6b7b398 data\hexcasting\loot_tables\blocks\aventurine_edified_leaves.json +849afa706e7479d1c11bb40ae223ae5833e71286 data\hexcasting\loot_tables\blocks\scroll_paper_lantern.json +b6c23fdde4f2c22c81f008604d5ff1c32ca8eb61 data\hexcasting\loot_tables\blocks\amethyst_tiles.json +10cb1b94596ac7131efe3bd5c36c1543ddba9302 data\hexcasting\loot_tables\blocks\impetus\redstone.json +147e0739a712a9050856cebcad1757b3f418f647 data\hexcasting\loot_tables\blocks\edified_trapdoor.json +5f8d09e8c759d05cf9c2265ae28ea942cfbbe2be data\hexcasting\loot_tables\blocks\edified_pressure_plate.json +ecaeb4d5703a7aa206627ed38ee71aeb7e93d688 data\hexcasting\loot_tables\blocks\impetus\rightclick.json +a4e0194d8966a24531e43e04437cdb2a96456898 data\hexcasting\loot_tables\blocks\edified_tile.json +1a1236e54c24b5aeff05919c73c76151da2cf115 data\hexcasting\loot_tables\blocks\amethyst_sconce.json +c15d3ced89c882dfe552f84435fcdd560b729567 data\hexcasting\loot_tables\blocks\scroll_paper.json +92331eb19422730ffda0a3e52427a75aa1f7aff2 data\hexcasting\loot_tables\blocks\ancient_scroll_paper_lantern.json +b706c8a064f717c57104c48ea42aa860b45cf7a4 data\hexcasting\loot_tables\blocks\amethyst_dust_block.json +2ac70e3c3600c88b2544d9755fc634216a7a523c data\hexcasting\loot_tables\blocks\edified_wood.json +1c6b077aae560e780be29e74ddcd4b0ca10ce3cf data\hexcasting\loot_tables\blocks\impetus\empty.json +847bc3ead8a88a8f210a24e7732c28d50aa2f5dc data\hexcasting\loot_tables\blocks\edified_planks.json diff --git a/Fabric/src/generated/resources/.cache/2ba8da2cf2d44ff18dc72cc891b094eca6836a5c b/Fabric/src/generated/resources/.cache/2ba8da2cf2d44ff18dc72cc891b094eca6836a5c index 262e081e97..0e1d57cba2 100644 --- a/Fabric/src/generated/resources/.cache/2ba8da2cf2d44ff18dc72cc891b094eca6836a5c +++ b/Fabric/src/generated/resources/.cache/2ba8da2cf2d44ff18dc72cc891b094eca6836a5c @@ -1,25 +1,25 @@ -// 1.20.1 2024-11-19T11:30:28.203782887 Hex Casting/Tags for minecraft:item -5928bad07d3872bb60f29ef4f3c885c8e1967c20 data/hexcasting/tags/items/phial_base.json -fdb48f194d7937ab6b423fa4b90a4d438bf6dd90 data/minecraft/tags/items/wooden_doors.json -fdb48f194d7937ab6b423fa4b90a4d438bf6dd90 data/minecraft/tags/items/doors.json -37cff4ce449b8069b59b2327d78e073fc026d348 data/minecraft/tags/items/wooden_pressure_plates.json -30780136e6469a01369d7e278998edb6d7f6a16b data/hexcasting/tags/items/staves.json -20183cd61968ff6548df2dde1100b6378d68d64b data/minecraft/tags/items/wooden_buttons.json -c562b4be24d0b6b13f3c65599d3bfa3bf2c4ce21 data/hexcasting/tags/items/edified_logs.json -e186f43ed06770e698c886691f91b2c6acdb5a2a data/hexcasting/tags/items/seal_materials.json -4461ef6db41a675fd077dd833cfd0ea537e755be data/c/tags/items/amethyst_dusts.json -5216ba5c57db29b8dee9aebc63a2e3b17c97dc17 data/minecraft/tags/items/trapdoors.json -e5df19a1dc6eadf14cd9b0f0fe45a74330b745e9 data/minecraft/tags/items/planks.json -c72a147bc65d26424df199388969ebd11119aed3 data/hexcasting/tags/items/brainswept_circle_components.json -5216ba5c57db29b8dee9aebc63a2e3b17c97dc17 data/minecraft/tags/items/wooden_trapdoors.json -bdb90cee0e88e02f0b98f12d5dd212adfaca9afd data/hexcasting/tags/items/impeti.json -e5df19a1dc6eadf14cd9b0f0fe45a74330b745e9 data/hexcasting/tags/items/edified_planks.json -20183cd61968ff6548df2dde1100b6378d68d64b data/minecraft/tags/items/buttons.json -38d781b60c5c37dc025d4c7e9ec5aa680f2a5835 data/c/tags/items/gems.json -c562b4be24d0b6b13f3c65599d3bfa3bf2c4ce21 data/minecraft/tags/items/logs_that_burn.json -ef8ae066fea6277ba2ab43faf18757b88f7c4803 data/hexcasting/tags/items/grants_root_advancement.json -5f3b600b4fd98744bd08c993ce7bcb9c2f195cd2 data/minecraft/tags/items/leaves.json -9d18fb7a889031a704ca0e553600e1d6f8c3759d data/hexcasting/tags/items/directrices.json -c562b4be24d0b6b13f3c65599d3bfa3bf2c4ce21 data/minecraft/tags/items/logs.json -5bbfd513fd2eb2090b0c2d1ec33504deb79d53b9 data/minecraft/tags/items/slabs.json -5bbfd513fd2eb2090b0c2d1ec33504deb79d53b9 data/minecraft/tags/items/wooden_slabs.json +// 1.20.1 2025-01-23T15:50:44.4049409 Hex Casting/Tags for minecraft:item +e5df19a1dc6eadf14cd9b0f0fe45a74330b745e9 data\minecraft\tags\items\planks.json +c562b4be24d0b6b13f3c65599d3bfa3bf2c4ce21 data\minecraft\tags\items\logs.json +20183cd61968ff6548df2dde1100b6378d68d64b data\minecraft\tags\items\wooden_buttons.json +5bbfd513fd2eb2090b0c2d1ec33504deb79d53b9 data\minecraft\tags\items\slabs.json +ef8ae066fea6277ba2ab43faf18757b88f7c4803 data\hexcasting\tags\items\grants_root_advancement.json +e5df19a1dc6eadf14cd9b0f0fe45a74330b745e9 data\hexcasting\tags\items\edified_planks.json +fdb48f194d7937ab6b423fa4b90a4d438bf6dd90 data\minecraft\tags\items\wooden_doors.json +4461ef6db41a675fd077dd833cfd0ea537e755be data\c\tags\items\amethyst_dusts.json +38d781b60c5c37dc025d4c7e9ec5aa680f2a5835 data\c\tags\items\gems.json +c562b4be24d0b6b13f3c65599d3bfa3bf2c4ce21 data\hexcasting\tags\items\edified_logs.json +c72a147bc65d26424df199388969ebd11119aed3 data\hexcasting\tags\items\brainswept_circle_components.json +30780136e6469a01369d7e278998edb6d7f6a16b data\hexcasting\tags\items\staves.json +5bbfd513fd2eb2090b0c2d1ec33504deb79d53b9 data\minecraft\tags\items\wooden_slabs.json +5216ba5c57db29b8dee9aebc63a2e3b17c97dc17 data\minecraft\tags\items\wooden_trapdoors.json +9d18fb7a889031a704ca0e553600e1d6f8c3759d data\hexcasting\tags\items\directrices.json +e186f43ed06770e698c886691f91b2c6acdb5a2a data\hexcasting\tags\items\seal_materials.json +5928bad07d3872bb60f29ef4f3c885c8e1967c20 data\hexcasting\tags\items\phial_base.json +fdb48f194d7937ab6b423fa4b90a4d438bf6dd90 data\minecraft\tags\items\doors.json +37cff4ce449b8069b59b2327d78e073fc026d348 data\minecraft\tags\items\wooden_pressure_plates.json +bdb90cee0e88e02f0b98f12d5dd212adfaca9afd data\hexcasting\tags\items\impeti.json +20183cd61968ff6548df2dde1100b6378d68d64b data\minecraft\tags\items\buttons.json +5f3b600b4fd98744bd08c993ce7bcb9c2f195cd2 data\minecraft\tags\items\leaves.json +5216ba5c57db29b8dee9aebc63a2e3b17c97dc17 data\minecraft\tags\items\trapdoors.json +c562b4be24d0b6b13f3c65599d3bfa3bf2c4ce21 data\minecraft\tags\items\logs_that_burn.json diff --git a/Fabric/src/generated/resources/.cache/3cb4ab563deee432e7d307024048f57946bafb1c b/Fabric/src/generated/resources/.cache/3cb4ab563deee432e7d307024048f57946bafb1c index 0177cee9a1..c7442d4c4d 100644 --- a/Fabric/src/generated/resources/.cache/3cb4ab563deee432e7d307024048f57946bafb1c +++ b/Fabric/src/generated/resources/.cache/3cb4ab563deee432e7d307024048f57946bafb1c @@ -1,4 +1,4 @@ -// 1.20.1 2024-11-19T11:30:28.208319781 Hex Casting/Tags for hexcasting:action -6fe30f41e2bcd48589caab26d210a513dce1ab7c data/hexcasting/tags/action/per_world_pattern.json -6fe30f41e2bcd48589caab26d210a513dce1ab7c data/hexcasting/tags/action/requires_enlightenment.json -6fe30f41e2bcd48589caab26d210a513dce1ab7c data/hexcasting/tags/action/can_start_enlighten.json +// 1.20.1 2025-01-23T15:50:44.4152906 Hex Casting/Tags for hexcasting:action +6fe30f41e2bcd48589caab26d210a513dce1ab7c data\hexcasting\tags\action\per_world_pattern.json +6fe30f41e2bcd48589caab26d210a513dce1ab7c data\hexcasting\tags\action\can_start_enlighten.json +6fe30f41e2bcd48589caab26d210a513dce1ab7c data\hexcasting\tags\action\requires_enlightenment.json diff --git a/Fabric/src/generated/resources/.cache/812fdb58b7018b2d5c5af7da57a2b1857fa66794 b/Fabric/src/generated/resources/.cache/812fdb58b7018b2d5c5af7da57a2b1857fa66794 index 82cfeba7fa..657625c00a 100644 --- a/Fabric/src/generated/resources/.cache/812fdb58b7018b2d5c5af7da57a2b1857fa66794 +++ b/Fabric/src/generated/resources/.cache/812fdb58b7018b2d5c5af7da57a2b1857fa66794 @@ -1,34 +1,34 @@ -// 1.20.1 2024-11-19T11:30:28.20228007 Hex Casting/Tags for minecraft:block -c72a147bc65d26424df199388969ebd11119aed3 data/hexcasting/tags/blocks/brainswept_circle_components.json -357eddf3cee6f16725bed0701d57b2ca3097d74d data/minecraft/tags/blocks/mineable/shovel.json -20183cd61968ff6548df2dde1100b6378d68d64b data/minecraft/tags/blocks/buttons.json -8cd7a960fd719f200b0bf38100cd17c73b66d39c data/minecraft/tags/blocks/mineable/pickaxe.json -643994ee757a533cfb5001689e0f0263956b8a35 data/minecraft/tags/blocks/mineable/axe.json -5f3b600b4fd98744bd08c993ce7bcb9c2f195cd2 data/minecraft/tags/blocks/mineable/hoe.json -6ae561f7399e39ffa0e97bd0569aeffa9eabff6a data/hexcasting/tags/blocks/water_plants.json -e8d5ef7eabb567228b279b2419e4f042082d7491 data/minecraft/tags/blocks/fences.json -c562b4be24d0b6b13f3c65599d3bfa3bf2c4ce21 data/minecraft/tags/blocks/logs_that_burn.json -eba53f6c7645de4ef5ffb1e10ef34a4c23e98887 data/hexcasting/tags/blocks/cheap_to_break_block.json -7e1e353cb7f561f086898f991ece48e047991934 data/minecraft/tags/blocks/unstable_bottom_center.json -5f3b600b4fd98744bd08c993ce7bcb9c2f195cd2 data/minecraft/tags/blocks/leaves.json -281cb08b9b68ef049820c4f3f36b40820044681e data/minecraft/tags/blocks/wooden_stairs.json -6f52ca5e42991af6d7b829f626010ce304277464 data/minecraft/tags/blocks/crystal_sound_blocks.json -5216ba5c57db29b8dee9aebc63a2e3b17c97dc17 data/minecraft/tags/blocks/trapdoors.json -37cff4ce449b8069b59b2327d78e073fc026d348 data/minecraft/tags/blocks/wooden_pressure_plates.json -20183cd61968ff6548df2dde1100b6378d68d64b data/minecraft/tags/blocks/wooden_buttons.json -5216ba5c57db29b8dee9aebc63a2e3b17c97dc17 data/minecraft/tags/blocks/wooden_trapdoors.json -7acae0c88f5ead65339db1b11b16f60214434c86 data/minecraft/tags/blocks/wooden_fences.json -fdb48f194d7937ab6b423fa4b90a4d438bf6dd90 data/minecraft/tags/blocks/wooden_doors.json -7e1e353cb7f561f086898f991ece48e047991934 data/minecraft/tags/blocks/fence_gates.json -c562b4be24d0b6b13f3c65599d3bfa3bf2c4ce21 data/minecraft/tags/blocks/logs.json -c562b4be24d0b6b13f3c65599d3bfa3bf2c4ce21 data/hexcasting/tags/blocks/edified_logs.json -5bbfd513fd2eb2090b0c2d1ec33504deb79d53b9 data/minecraft/tags/blocks/slabs.json -e5df19a1dc6eadf14cd9b0f0fe45a74330b745e9 data/minecraft/tags/blocks/planks.json -4b84fc8b7976df220be382bdda66ecf25ceee559 data/create/tags/blocks/brittle.json -281cb08b9b68ef049820c4f3f36b40820044681e data/minecraft/tags/blocks/stairs.json -bdb90cee0e88e02f0b98f12d5dd212adfaca9afd data/hexcasting/tags/blocks/impeti.json -9d18fb7a889031a704ca0e553600e1d6f8c3759d data/hexcasting/tags/blocks/directrices.json -37cff4ce449b8069b59b2327d78e073fc026d348 data/minecraft/tags/blocks/pressure_plates.json -fdb48f194d7937ab6b423fa4b90a4d438bf6dd90 data/minecraft/tags/blocks/doors.json -5bbfd513fd2eb2090b0c2d1ec33504deb79d53b9 data/minecraft/tags/blocks/wooden_slabs.json -e5df19a1dc6eadf14cd9b0f0fe45a74330b745e9 data/hexcasting/tags/blocks/edified_planks.json +// 1.20.1 2025-01-23T15:50:44.400399 Hex Casting/Tags for minecraft:block +e8d5ef7eabb567228b279b2419e4f042082d7491 data\minecraft\tags\blocks\fences.json +7e1e353cb7f561f086898f991ece48e047991934 data\minecraft\tags\blocks\fence_gates.json +fdb48f194d7937ab6b423fa4b90a4d438bf6dd90 data\minecraft\tags\blocks\doors.json +c72a147bc65d26424df199388969ebd11119aed3 data\hexcasting\tags\blocks\brainswept_circle_components.json +5f3b600b4fd98744bd08c993ce7bcb9c2f195cd2 data\minecraft\tags\blocks\leaves.json +bdb90cee0e88e02f0b98f12d5dd212adfaca9afd data\hexcasting\tags\blocks\impeti.json +37cff4ce449b8069b59b2327d78e073fc026d348 data\minecraft\tags\blocks\pressure_plates.json +8cd7a960fd719f200b0bf38100cd17c73b66d39c data\minecraft\tags\blocks\mineable\pickaxe.json +c562b4be24d0b6b13f3c65599d3bfa3bf2c4ce21 data\minecraft\tags\blocks\logs_that_burn.json +357eddf3cee6f16725bed0701d57b2ca3097d74d data\minecraft\tags\blocks\mineable\shovel.json +4b84fc8b7976df220be382bdda66ecf25ceee559 data\create\tags\blocks\brittle.json +5bbfd513fd2eb2090b0c2d1ec33504deb79d53b9 data\minecraft\tags\blocks\slabs.json +7acae0c88f5ead65339db1b11b16f60214434c86 data\minecraft\tags\blocks\wooden_fences.json +281cb08b9b68ef049820c4f3f36b40820044681e data\minecraft\tags\blocks\wooden_stairs.json +5216ba5c57db29b8dee9aebc63a2e3b17c97dc17 data\minecraft\tags\blocks\trapdoors.json +643994ee757a533cfb5001689e0f0263956b8a35 data\minecraft\tags\blocks\mineable\axe.json +5216ba5c57db29b8dee9aebc63a2e3b17c97dc17 data\minecraft\tags\blocks\wooden_trapdoors.json +20183cd61968ff6548df2dde1100b6378d68d64b data\minecraft\tags\blocks\wooden_buttons.json +37cff4ce449b8069b59b2327d78e073fc026d348 data\minecraft\tags\blocks\wooden_pressure_plates.json +6f52ca5e42991af6d7b829f626010ce304277464 data\minecraft\tags\blocks\crystal_sound_blocks.json +6ae561f7399e39ffa0e97bd0569aeffa9eabff6a data\hexcasting\tags\blocks\water_plants.json +9d18fb7a889031a704ca0e553600e1d6f8c3759d data\hexcasting\tags\blocks\directrices.json +7e1e353cb7f561f086898f991ece48e047991934 data\minecraft\tags\blocks\unstable_bottom_center.json +c562b4be24d0b6b13f3c65599d3bfa3bf2c4ce21 data\minecraft\tags\blocks\logs.json +20183cd61968ff6548df2dde1100b6378d68d64b data\minecraft\tags\blocks\buttons.json +e5df19a1dc6eadf14cd9b0f0fe45a74330b745e9 data\minecraft\tags\blocks\planks.json +e5df19a1dc6eadf14cd9b0f0fe45a74330b745e9 data\hexcasting\tags\blocks\edified_planks.json +5bbfd513fd2eb2090b0c2d1ec33504deb79d53b9 data\minecraft\tags\blocks\wooden_slabs.json +fdb48f194d7937ab6b423fa4b90a4d438bf6dd90 data\minecraft\tags\blocks\wooden_doors.json +281cb08b9b68ef049820c4f3f36b40820044681e data\minecraft\tags\blocks\stairs.json +eba53f6c7645de4ef5ffb1e10ef34a4c23e98887 data\hexcasting\tags\blocks\cheap_to_break_block.json +5f3b600b4fd98744bd08c993ce7bcb9c2f195cd2 data\minecraft\tags\blocks\mineable\hoe.json +c562b4be24d0b6b13f3c65599d3bfa3bf2c4ce21 data\hexcasting\tags\blocks\edified_logs.json diff --git a/Fabric/src/generated/resources/.cache/c70ef2fe5da52437c1f53bcc9ea0e416f16bcc0b b/Fabric/src/generated/resources/.cache/c70ef2fe5da52437c1f53bcc9ea0e416f16bcc0b index f29d046638..c845076e2a 100644 --- a/Fabric/src/generated/resources/.cache/c70ef2fe5da52437c1f53bcc9ea0e416f16bcc0b +++ b/Fabric/src/generated/resources/.cache/c70ef2fe5da52437c1f53bcc9ea0e416f16bcc0b @@ -1,220 +1,220 @@ -// 1.20.1 2024-11-19T11:30:28.205075318 Hex Casting/Recipes -f482a4349786388cc8f11d5550548f7d60265438 data/hexcasting/recipes/staff/mangrove.json -b10d590e918e35b16578a8b739a1c4e7e2202e16 data/hexcasting/advancements/recipes/misc/dye_colorizer_cyan.json -7aa3bf4a3d6fb92743b29dfe89d50537fefc0db9 data/hexcasting/advancements/recipes/misc/pride_colorizer_intersex.json -648f1862fde1dd8ade80b2991b8c8e3991389e95 data/hexcasting/recipes/dye_colorizer_light_blue.json -23eff6111b0385b66d3ad5fbabfc625f426517a6 data/hexcasting/advancements/recipes/brainsweep/brainsweep/directrix_redstone.json -a3130e3098e35b75afae4f31996d9ab7468e0bc3 data/hexcasting/advancements/recipes/tools/thought_knot.json -c8f2ad363e4d20054f4e56fde02c8775a45a7169 data/hexcasting/recipes/artifact.json -f80dbf59957be175fbcd63224005e09c4cd1a122 data/hexcasting/recipes/compat/farmersdelight/cutting/edified_log_citrine.json -2fff80cd3dabd2bc1744eecd72b2364b0f91c7c1 data/hexcasting/advancements/recipes/misc/dye_colorizer_yellow.json -9269b17eaae3217422352354fc6006c9808b398c data/hexcasting/recipes/dye_colorizer_black.json -441f336edb635e5d8c2a7183906fed1c501f06fd data/hexcasting/recipes/pride_colorizer_bisexual.json -a72a0fcc0f3a81d31b30a7a626aef537796ca73b data/hexcasting/advancements/recipes/tools/staff/quenched.json -2aa7d74e29a7c5ee4f1b8835cf7c6109eed81d77 data/hexcasting/recipes/brainsweep/quench_allay.json -2c292e12b5e85b1701740c222e5c5465799ad1dc data/hexcasting/recipes/pride_colorizer_aroace.json -5d6d73e16a36da5f9df6a7b8ac859181d401766d data/hexcasting/recipes/uuid_colorizer.json -49e706193bb57a957091e419bd0d8aa58135da1f data/hexcasting/recipes/dye_colorizer_green.json -2cea013887734cbc4971bcd57e7e4f6a2b25c8e1 data/hexcasting/advancements/recipes/tools/focus.json -36d26f34d0405ff2d1e728e5b5174502686e3590 data/hexcasting/advancements/recipes/brainsweep/brainsweep/budding_amethyst.json -daa7b13d5370f4306f8cdf3037fc346e8918950a data/hexcasting/recipes/dye_colorizer_brown.json -b94bc4dd4a63db10af86c524ba00eae157c1824b data/hexcasting/advancements/recipes/building_blocks/edified_fence_gate.json -9ea4fe5272ce2241d98f30359f55cfc1936c7b48 data/hexcasting/advancements/recipes/tools/staff/cherry.json -e0609202271e402d8ae58e4f8eaf11dcdda10a9e data/hexcasting/recipes/brainsweep/akashic_record.json -c3f7b03fe184ed5e54a8ae06d130adf507b7683d data/hexcasting/recipes/staff/bamboo.json -7ca0f9fc6e8ae1ad08ef5c29a0b279b891f7d8d4 data/hexcasting/advancements/recipes/misc/pride_colorizer_aroace.json -4aaefc65af5fe69d312247fdda7d983edf8dcd9a data/hexcasting/recipes/pride_colorizer_intersex.json -641d8c38b8109665314fccbebd9068ba10b04118 data/hexcasting/advancements/recipes/misc/dye_colorizer_gray.json -fd2f25b0a71806c96af5a307fad76f66de6210a4 data/hexcasting/advancements/recipes/building_blocks/slate_block.json -b1f8375aaf0d66035dee720ea59605f69fc0a154 data/hexcasting/recipes/edified_fence.json -ae88fcdecbfbdd0a0fe778467421a3b32d7ed735 data/create/recipes/crushing/amethyst_cluster.json -6ed61e03c51dc653cd66e643a6d33fe9105ff171 data/hexcasting/advancements/recipes/brainsweep/brainsweep/directrix_boolean.json -8b7136c206b799a2e394aa02316b0509674ff64f data/hexcasting/advancements/recipes/tools/staff/bamboo.json -fb852d8e4bcfa7b75f41a6ac7dc1e76b00d95fb1 data/hexcasting/advancements/recipes/misc/dye_colorizer_red.json -5401828f85e709b5817ecc8464dc63e536a730dc data/hexcasting/recipes/staff/cherry.json -54335e0004423899ad37763a1d8456cc0a6e72a7 data/hexcasting/advancements/recipes/misc/decompose_quenched_shard/charged.json -c1846dd794f5cc5814b8a839291e82512a02ba12 data/hexcasting/advancements/recipes/misc/pride_colorizer_plural.json -0ead307e47242ba140584f6bd20088a1fa7c2909 data/hexcasting/recipes/directrix/empty.json -b7084f131b0cdb9c2c698a3c5b3450d69e788d6e data/hexcasting/recipes/dye_colorizer_yellow.json -55ea553a96e1d6a54385890f7c48fe7b2bed6871 data/hexcasting/advancements/recipes/tools/trinket.json -2003fed3aa4eb622b6b07a9e65946fb40be14420 data/hexcasting/advancements/recipes/brainsweep/brainsweep/impetus_rightclick.json -1b092acfc3115702c74e141492e649d58512f259 data/hexcasting/recipes/staff/oak.json -5a90084c03d6e8424872870c8b65f4771b447f03 data/hexcasting/recipes/brainsweep/budding_amethyst.json -61e53f02baefd31308e99407d56403dfc18e36e1 data/hexcasting/recipes/akashic_connector.json -93ed0491548920bc75797d18501c750ef07fe3ea data/hexcasting/advancements/recipes/misc/pride_colorizer_bisexual.json -0f2e63a9361d18aac764f6a4a4f13b9b862ac2ee data/hexcasting/recipes/compat/create/crushing/amethyst_shard.json -c4b985635c3b1a519d7a83da65daba5bdd3a5f59 data/hexcasting/advancements/recipes/decorations/ageing_scroll_paper_lantern.json -b6720c1c73455ad817bac9b5ca2ca045c5c4050c data/hexcasting/recipes/pride_colorizer_agender.json -5f216dbb7b89fd837e2dd73e3ed41c8d412de234 data/hexcasting/advancements/recipes/misc/decompose_quenched_shard/dust.json -903cbe4d4c4e5abcd5e006f9d0237e8c596228ba data/hexcasting/recipes/edified_tile.json -fb486df96798724da2fcc0df5706f19bc1ff94dc data/hexcasting/advancements/recipes/misc/dye_colorizer_light_blue.json -410bfde90cb977db3f13814e94484fa11fca7cfc data/hexcasting/recipes/thought_knot.json -30352d8ad510768770bb1b2d378959b7a502f825 data/hexcasting/advancements/recipes/brainsweep/brainsweep/impetus_look.json -a8cab28cffdf495253a320094d202fccc5aeb113 data/hexcasting/advancements/recipes/decorations/ancient_scroll_paper_lantern.json -af8fe74b624df4a31727347b9826614a66092b0a data/hexcasting/advancements/recipes/misc/pride_colorizer_agender.json -e765ee2bd324240e8ed3d625be431de3281f0070 data/hexcasting/recipes/dye_colorizer_gray.json -a0b87b1b21506708d09c9295b7afc13de6b1fce6 data/hexcasting/recipes/pride_colorizer_aromantic.json -4d941fc399c6b7a470513a572ecd88982823da84 data/hexcasting/advancements/recipes/building_blocks/edified_wood.json -aa1caae7eba6aede0f179619488e2253b3b723dd data/hexcasting/recipes/focus_rotated.json -505eb9192df0b48867e58e09ce36b2259dc6d3e8 data/hexcasting/advancements/recipes/decorations/scroll.json -1d1e73244fb3da633d8a5f84bad93c6022a94368 data/hexcasting/advancements/recipes/misc/pride_colorizer_demiboy.json -71d38559bf455ea343ac0237a57db4d3f0833a7c data/hexcasting/advancements/recipes/misc/dye_colorizer_magenta.json -fd7c8325fcaa6a718e90c09251b447fb365523d4 data/hexcasting/recipes/pride_colorizer_demiboy.json -b5946314683e5a823b577a18d13fb437a35aafd5 data/hexcasting/recipes/decompose_quenched_shard/charged.json -011f8daf15148d4b77686c6d382d8f5c288a333d data/hexcasting/advancements/recipes/building_blocks/ancient_scroll_paper.json -494aa470790ae46baebbf24ee5b76f5885c1af1a data/hexcasting/recipes/ageing_scroll_paper_lantern.json -c6228d72ca800a7dd336e82bbb9b4f20f89de29d data/hexcasting/advancements/recipes/redstone/edified_pressure_plate.json -5889e2df2fb4e1ea29f2590b96bb3aa94961a09a data/hexcasting/recipes/scroll.json -a9111ff52513200af47b79cf98b2e545699497bb data/hexcasting/advancements/recipes/building_blocks/amethyst_tiles.json -e9166f40c8797cdbf3d8062dfa35c74f850f1000 data/hexcasting/advancements/recipes/misc/dye_colorizer_white.json -2c56c267e23e75d5a3b9358d424d69642e001b50 data/hexcasting/recipes/decompose_quenched_shard/dust.json -ea87956c49dcfabb0d39af45c016130d258181da data/hexcasting/recipes/staff/birch.json -98c0843e6a83b91820f1c720e206295eec20ff95 data/hexcasting/recipes/ancient_scroll_paper.json -bc8fe4d2f55fe119b0b146a71782a3d4788380b1 data/create/recipes/crushing/amethyst_block.json -97062771a426f6e4b9e3bfd6daa62b1d4b3c7039 data/hexcasting/recipes/abacus.json -24c244e53c7e47b85845d2ee36b1665410cf495a data/hexcasting/recipes/edified_planks.json -417695497a95436186c1a4ed842d7975d754f9eb data/hexcasting/recipes/stripped_edified_wood.json -7f2f29981df2ca4464ee0250180e670f5331f65b data/hexcasting/recipes/dye_colorizer_pink.json -ea63e49709bd80cb9f4cd1fe13e9bd0281101c9a data/hexcasting/recipes/slate.json -f64fa00d85a9abb24e89b0d2c9f818001371f5e6 data/hexcasting/recipes/slate_block.json -14f3b217e150efbbff329d67aec96f818a1da99c data/hexcasting/recipes/dye_colorizer_purple.json -9b7c5220fbaf3e84fa9e81eae322eed5d37b22d3 data/hexcasting/recipes/pride_colorizer_transgender.json -17a1adf747b99848381ca8e7c5e2cd9dd96c014f data/hexcasting/advancements/recipes/misc/default_colorizer.json -a85cfbd7988f5df0b18d160591605aea8e6808d2 data/hexcasting/recipes/trinket.json -4003f297be29810cebde4995fb2838c2c68a25ea data/hexcasting/recipes/pride_colorizer_lesbian.json -41a570f970c9af8229cb1140a11a5220fac00957 data/hexcasting/advancements/recipes/tools/staff/spruce.json -b300f7729e75614fce412457f6717686680f81da data/hexcasting/recipes/sub_sandwich.json -0b951ce7b9d1bfb07ae012b12225b595d36c6e66 data/hexcasting/recipes/amethyst_dust_packing.json -2b64261bd4aefdc55d35400f25835434f88856cf data/hexcasting/recipes/amethyst_tiles.json -963d87d2738686e5398a178b8b369228ff067403 data/hexcasting/recipes/spellbook.json -6e2dc32f975d987b8dfd329507334f647bceadc0 data/hexcasting/advancements/recipes/tools/staff/mangrove.json -996c8361766377a70e0b5a5caff3076fc6031b0a data/hexcasting/recipes/impetus/empty.json -71f821f5d24b0bf9ecd860d51e055628fe4af50c data/hexcasting/recipes/edified_panel.json -7166cd4355d11c209bc7749bc862caddcfd795fb data/hexcasting/recipes/dye_colorizer_cyan.json -f347f4ce869207e62a7887df1252505a3432e12a data/hexcasting/recipes/pride_colorizer_genderfluid.json -1b570b35288be9f6faab1536d6e45cb52eb088c0 data/hexcasting/advancements/recipes/tools/staff/dark_oak.json -31ec6474ddae967a6c1dadf9be8292d375510364 data/hexcasting/advancements/recipes/building_blocks/edified_tile.json -5e66982df6a1074c81f381898033b521ca337695 data/hexcasting/recipes/staff/quenched.json -45915b542d8070f2502a4047218679b08033b12d data/hexcasting/advancements/recipes/decorations/scroll_paper_lantern.json -946cde51bbfc2af344b078f6b39389ffc44462f4 data/hexcasting/advancements/recipes/brainsweep/brainsweep/impetus_storedplayer.json -1093cccc6b1c45eb91f7c1680ef575a7bffb2744 data/hexcasting/advancements/recipes/building_blocks/edified_planks.json -72447ac69a0d85f91064180d3c852040a9e33832 data/hexcasting/recipes/pride_colorizer_asexual.json -0e792d49c81d2164e827d1bdedaa0fa358dfc437 data/hexcasting/advancements/recipes/misc/pride_colorizer_aromantic.json -b84c113ef5321c9df9ac9080de03e8d8639feab2 data/hexcasting/advancements/recipes/misc/pride_colorizer_genderqueer.json -e6a592721234448f2ee7ec402bca10a9b78b4677 data/hexcasting/advancements/recipes/decorations/slate.json -de38d15e7a91c77df24c1dc954b3e98ee197876f data/hexcasting/recipes/focus.json -157ee5fba985bbd01a87f44578890dab5489a8e5 data/hexcasting/advancements/recipes/misc/dye_colorizer_green.json -c1541738df1ee41c362ad3b9c3a9f0e181bd5c62 data/hexcasting/recipes/pride_colorizer_plural.json -233aeedc73173427e7b2287772a4f914f97b072c data/hexcasting/recipes/dye_colorizer_red.json -12bd3d04c791ef16aad5e992f038d6726229a436 data/hexcasting/advancements/recipes/tools/artifact.json -862f1a61a296a834df8a93dbd5a6cdfa2df15721 data/hexcasting/advancements/recipes/tools/staff/acacia.json -a1f9df0537c0ef33a1164cf94e8ff4b1094f889f data/hexcasting/advancements/recipes/tools/staff/warped.json -b6e762c198b9632defd7f8b11287702abecd681d data/hexcasting/recipes/staff/mindsplice.json -7c479398bbc7185a2c3efd568ad266d8109245bf data/hexcasting/advancements/recipes/redstone/edified_door.json -5fab1b9c93304a53a4c305b511704458e4593444 data/hexcasting/recipes/pride_colorizer_demigirl.json -e536791d0c6fb48206e6e30d56879eaf0a9e4bd7 data/hexcasting/recipes/akashic_bookshelf.json -b90ad4cbffc2e3c01671dfe8bda5e42d9b8a685c data/hexcasting/advancements/recipes/tools/staff/crimson.json -68ab70e0b4e432a3492767c5597ecd836f106714 data/hexcasting/advancements/recipes/tools/staff/mindsplice.json -c2ef04b311251b4eb22320b2f5313c54533a9974 data/hexcasting/advancements/recipes/tools/staff/birch.json -1a0d55e6824c078453c1d44e885a1c51ba707a41 data/hexcasting/recipes/dye_colorizer_white.json -8f8773a541bc6a4a6c55a23f4f98b5da4f61a031 data/hexcasting/recipes/scroll_paper.json -bc729ac7cf84d29a99cd34d50c152c0b9d20bd7a data/hexcasting/advancements/recipes/brainsweep/brainsweep/akashic_record.json -4a803e049915fd3c7144155ae3a1b05a917ea290 data/hexcasting/recipes/pride_colorizer_pansexual.json -8bea75fdc5e64c464dcf5f85166e767ff44e6dc2 data/hexcasting/advancements/recipes/misc/pride_colorizer_lesbian.json -0654e70ed1ed8be20ae3dd9f4955cd14f9fa40d0 data/hexcasting/advancements/recipes/tools/staff/jungle.json -5e98cec2084f0cfbb959c3ec39bd85a3369f443b data/hexcasting/advancements/recipes/tools/abacus.json -0b172aef920da7ba63fe152903ce005c1f5df5f1 data/hexcasting/recipes/staff/acacia.json -7e1a5a873d655e0efba80f22ae9b1de4f248e67a data/hexcasting/advancements/recipes/misc/decompose_quenched_shard/shard.json -3608f0ec056f2c5d29a9a89305218497fd2c4383 data/hexcasting/recipes/stonecutting/amethyst_tiles.json -2a2f60fb0f63ee278b74c418acf04575304c521f data/hexcasting/advancements/recipes/tools/jeweler_hammer.json -8c043c7f6a7911b67324e2fd42f0b3b19a792af3 data/hexcasting/recipes/ancient_scroll_paper_lantern.json -4680e9dafcf9b60b3485609519d66eefcfd539bc data/hexcasting/recipes/staff/dark_oak.json -095aeb2882c6849f10fb6536e7c780790778e5e7 data/hexcasting/recipes/staff/jungle.json -b624d103d944a8a1d4d8a9e85c198a5492b476f8 data/hexcasting/advancements/recipes/redstone/edified_trapdoor.json -eb9ebf77f0daa32f665a60888fcda19c940f0b2f data/hexcasting/advancements/recipes/misc/pride_colorizer_demigirl.json -8f7b81add0153ad94900acc66cd8174ae7115f64 data/hexcasting/advancements/recipes/building_blocks/slate_block_from_slates.json -838b91c33a72a58aa286607eaaa17cdd6b4c90ba data/hexcasting/recipes/amethyst_sconce.json -664ce1a38c9b1c9ec21b7e078631e181fc0b2498 data/hexcasting/recipes/staff/edified.json -7522be58b09554a3f1a54d5b2343c3eab01447a3 data/hexcasting/recipes/dye_colorizer_magenta.json -ee5db13cbb33d9c62bcb1eb645e2c4bea97ad44a data/hexcasting/advancements/recipes/building_blocks/amethyst_dust_unpacking.json -203b7035125390abb4ed77b3a4dca8f8f8f57bc5 data/hexcasting/recipes/dye_colorizer_light_gray.json -00853ec1885c1f72674c07caf6fd04904e248f8f data/hexcasting/recipes/brainsweep/directrix_boolean.json -f8ee073c1c03f1c11147e4801eeba1f86e5459ba data/hexcasting/recipes/dye_colorizer_blue.json -a366ea3750adc0d336ab8f318c40baed3f9c3eb7 data/hexcasting/recipes/brainsweep/impetus_storedplayer.json -51b047601368a103be166d907633b196d2d8a4e8 data/hexcasting/recipes/compat/farmersdelight/cutting/edified_log.json -f4c56ea7143ce92a0ae0b663310e53644a7309f7 data/hexcasting/advancements/recipes/misc/pride_colorizer_pansexual.json -6f2634e5588aede8e29157ecc859652d8a9f4065 data/hexcasting/advancements/recipes/misc/dye_colorizer_orange.json -f1bae034d27d218bf262a8c777b787d232489f16 data/hexcasting/recipes/lens.json -06402fb37fe4bb05918d13dbfdb89f4c2b67f3ec data/hexcasting/advancements/recipes/tools/cypher.json -ed5c690324e3d9b55599f00f078ae225072a2e7f data/hexcasting/recipes/brainsweep/impetus_rightclick.json -c43fb770003c8d882fd9c1e7d1ecb5f196cba1ab data/hexcasting/recipes/cypher.json -4d5e4a6374731b2d0a90c70a5d489703fd966977 data/hexcasting/advancements/recipes/misc/dye_colorizer_lime.json -0864e8b86bdad0bf9ab2ddeb0cd5a182808b5a0a data/hexcasting/recipes/default_colorizer.json -7d71eb93bbb0856167cf4521283e39f0048078ee data/hexcasting/advancements/recipes/redstone/edified_button.json -72f70637aea1c11683e9ee91d83c2807c6ec33a9 data/hexcasting/recipes/compat/farmersdelight/cutting/akashic_trapdoor.json -1e51cd4f527b3aea4d61d91829e47c191c9c05bb data/hexcasting/recipes/pride_colorizer_gay.json -42b8e462de1d7006de3a7658757377450e773107 data/hexcasting/advancements/recipes/misc/dye_colorizer_blue.json -775560efa36581389c0319435bda035be262ed4f data/hexcasting/advancements/recipes/building_blocks/edified_stairs.json -09096a40275b6c49d4b4e6984869aa43b34712c3 data/hexcasting/recipes/dynamicseal_focus.json -8f515bf8ccea70b3d88845ed83966dc0c66082f6 data/hexcasting/advancements/recipes/tools/staff/oak.json -b29f9d9c14e60ded1148680e2e0ef405b5a3c845 data/hexcasting/advancements/recipes/misc/uuid_colorizer.json -071e5875b13b60aac33bc97e408d2ca710ac5d02 data/hexcasting/advancements/recipes/building_blocks/stonecutting/amethyst_tiles.json -3bf96944a8eed8b8d3f5d96b609297727c078cb7 data/hexcasting/advancements/recipes/misc/dye_colorizer_purple.json -846baaef37844216b57bb9b35e52b1bb6b56b413 data/hexcasting/advancements/recipes/decorations/scroll_small.json -db5ae3a2fda235cf1c83fd83e0026a262e668217 data/hexcasting/advancements/recipes/building_blocks/edified_slab.json -6493676f8ca93a7be8d70e25d69ddad935b3f16b data/hexcasting/advancements/recipes/tools/lens.json -a8d604ba059d54502837809815d3ac9bbcaa89bf data/hexcasting/advancements/recipes/redstone/akashic_bookshelf.json -0aaf55492e850d2bb1ec2f9986406ca61fde4cfd data/hexcasting/recipes/dye_colorizer_lime.json -dcc9bf721dd40724abcc69f1f7e8a1610dbf88f3 data/hexcasting/recipes/compat/farmersdelight/cutting/akashic_door.json -f81053a3269c1b371be3f8057bad4803056ee0f9 data/hexcasting/recipes/dye_colorizer_orange.json -f77518b6993fe8e31de10af286c33ab72c0f9077 data/hexcasting/advancements/recipes/redstone/impetus/empty.json -3b03fdae3896212a0b8b9b3a2d4880d197e67d2d data/hexcasting/recipes/jeweler_hammer.json -d7de5d626fd799a2522af36f0c62c52fe490e6d2 data/hexcasting/recipes/edified_door.json -aa7558ec1baf6070efbe448d886e20e964e33f96 data/hexcasting/advancements/recipes/brainsweep/brainsweep/quench_allay.json -cedc2889c4f327b18755bbe8c3c595d302e2a9d0 data/hexcasting/recipes/decompose_quenched_shard/shard.json -8c52917fc7041c483fb6dfe8d16c90f096f2beaf data/hexcasting/recipes/compat/farmersdelight/cutting/edified_log_amethyst.json -40ed21dc80d39236ca0e6d2cea60861c637cf931 data/hexcasting/advancements/recipes/misc/pride_colorizer_nonbinary.json -ef96ae9709ec931ce6b6af8a539f9bc483236449 data/hexcasting/recipes/scroll_medium.json -61fafd43af83bdca6720d0993ab71f40a8bebd40 data/hexcasting/advancements/recipes/redstone/akashic_connector.json -f08a0aee92b281ae325d907e6fe4a3b03980f2aa data/hexcasting/advancements/recipes/tools/staff/edified.json -7552df3fc726cc4cdaa88aa4823eff6ce069fb75 data/hexcasting/recipes/slate_block_from_slates.json -77369113dc54d1c64b9101861dd8a1930bf1c1c4 data/hexcasting/recipes/edified_wood.json -1ad54df5eaee3d1e810d2c91bd03f626084e30b6 data/hexcasting/recipes/edified_trapdoor.json -ce9d0b976f7cc8ad4a0815bbea6c43115addb90f data/hexcasting/advancements/recipes/building_blocks/scroll_paper.json -af9a260c24e0a65eea321f0dd9dd2fa7d648707f data/hexcasting/advancements/recipes/building_blocks/amethyst_dust_packing.json -923e7cd200518042f11474713eca9ccad126dab7 data/hexcasting/recipes/staff/spruce.json -ad647a2078099344ea7f9836a68e1bf8e8119277 data/hexcasting/advancements/recipes/misc/dye_colorizer_brown.json -0038883bd294cc8a1b324d6782478d5e37b4dbf9 data/hexcasting/advancements/recipes/misc/dye_colorizer_pink.json -170af3c83a45f9550827cc48e4bb5a621d06d685 data/hexcasting/advancements/recipes/misc/pride_colorizer_transgender.json -8815ea5d8d7379062e050adc5736cc579c3bdd9e data/hexcasting/recipes/edified_stairs.json -b6fa898369ac52cdd9d7f91e3b8a2cb881c3829f data/hexcasting/advancements/recipes/decorations/scroll_medium.json -04902d4eca30560bc601a8196d82f74f3fa5b191 data/hexcasting/recipes/dynamicseal_spellbook.json -d6b7a9392320c11866b3f139f97977dc9f55bc47 data/hexcasting/recipes/scroll_small.json -8e48c680b38666c2e7da71fbe4ceddf5d99a5cbc data/hexcasting/advancements/recipes/food/sub_sandwich.json -5e28e2c352366720ce91b73f8c8c38e217f7198d data/hexcasting/recipes/edified_fence_gate.json -004e0694b3bf53140be7df89a4defc255b800619 data/hexcasting/advancements/recipes/tools/focus_rotated.json -faaa9c39dbcdd131c5fbec9ac6a26d6dc5e72053 data/hexcasting/advancements/recipes/misc/dye_colorizer_light_gray.json -55602e415fc1b797439b674050887e9e388558c9 data/hexcasting/advancements/recipes/building_blocks/edified_panel.json -151875101066f7af5788c7a2e1c6b342971a546a data/hexcasting/recipes/compat/farmersdelight/cutting/akashic_wood.json -0bd7c9f4a9bf29c1b63b2f9378f0a7e2f594b7b7 data/hexcasting/recipes/pride_colorizer_nonbinary.json -ea46e570a43cd3ea1cc78c51d9da45d93944730a data/hexcasting/advancements/recipes/redstone/directrix/empty.json -b20be6eb5a8b60567871444e65d773ec9a67ece1 data/hexcasting/recipes/staff/crimson.json -c03c81dc123294472e8bb6f836c319e96f8db4f5 data/hexcasting/advancements/recipes/building_blocks/edified_fence.json -92bdf87687d8823036fae6bd01782c653831286b data/hexcasting/recipes/brainsweep/impetus_look.json -06ca609ba1a32f094cf6edbc989bc9ddaf9d342c data/hexcasting/advancements/recipes/misc/pride_colorizer_genderfluid.json -552c235dc58a46a3e57913c9b9faf3f21abeae32 data/hexcasting/advancements/recipes/building_blocks/stripped_edified_wood.json -c2a0a489967db4064dfbe1ee6367e132665f3c00 data/hexcasting/recipes/edified_slab.json -1a9dd55a24f56a4e9467f1117e0898f7e71ade67 data/hexcasting/advancements/recipes/decorations/amethyst_sconce.json -27dc4a1647f264c45b27f5552fd9403a02853484 data/hexcasting/advancements/recipes/tools/spellbook.json -2eacf53894ae97712dc3874777e29dce0a0e5540 data/hexcasting/advancements/recipes/misc/pride_colorizer_asexual.json -e11aeded7f5d3fdd224627c67661bbd993901703 data/hexcasting/recipes/edified_pressure_plate.json -e691130641b11c0a030a51c71dee0ba356f3b5bd data/hexcasting/recipes/compat/farmersdelight/cutting/edified_log_aventurine.json -7baf0777533737aef68bcac36944943b77138d29 data/hexcasting/recipes/edified_button.json -63189af501442318a90c16d6951e51c0c5d6d4f3 data/hexcasting/recipes/compat/farmersdelight/cutting/edified_log_purple.json -499c5c09e3772989350f9ab3264b8692449a6dea data/hexcasting/advancements/recipes/misc/pride_colorizer_gay.json -b16ff5314d457bc7e9e224e102d1e04ce3a62361 data/hexcasting/recipes/brainsweep/directrix_redstone.json -bd63b845e02ee4b1b9abe168a196335ccbed1ca5 data/hexcasting/recipes/scroll_paper_lantern.json -afb422ad4a918ee0161bf077f09475bb1da2b4eb data/hexcasting/recipes/amethyst_dust_unpacking.json -d47352426739a0fc500a385d820d767a307e1d16 data/hexcasting/advancements/recipes/misc/dye_colorizer_black.json -f0e71ae8c6a9170669f44096a55a875d11497c56 data/hexcasting/recipes/staff/warped.json -78958099bf4337ad281580d90f434b3074ad18c8 data/hexcasting/recipes/pride_colorizer_genderqueer.json +// 1.20.1 2025-01-23T15:50:44.4089311 Hex Casting/Recipes +1d1e73244fb3da633d8a5f84bad93c6022a94368 data\hexcasting\advancements\recipes\misc\pride_colorizer_demiboy.json +49e706193bb57a957091e419bd0d8aa58135da1f data\hexcasting\recipes\dye_colorizer_green.json +071e5875b13b60aac33bc97e408d2ca710ac5d02 data\hexcasting\advancements\recipes\building_blocks\stonecutting\amethyst_tiles.json +fb852d8e4bcfa7b75f41a6ac7dc1e76b00d95fb1 data\hexcasting\advancements\recipes\misc\dye_colorizer_red.json +9269b17eaae3217422352354fc6006c9808b398c data\hexcasting\recipes\dye_colorizer_black.json +5d6d73e16a36da5f9df6a7b8ac859181d401766d data\hexcasting\recipes\uuid_colorizer.json +e11aeded7f5d3fdd224627c67661bbd993901703 data\hexcasting\recipes\edified_pressure_plate.json +8c52917fc7041c483fb6dfe8d16c90f096f2beaf data\hexcasting\recipes\compat\farmersdelight\cutting\edified_log_amethyst.json +d6b7a9392320c11866b3f139f97977dc9f55bc47 data\hexcasting\recipes\scroll_small.json +c1846dd794f5cc5814b8a839291e82512a02ba12 data\hexcasting\advancements\recipes\misc\pride_colorizer_plural.json +17a1adf747b99848381ca8e7c5e2cd9dd96c014f data\hexcasting\advancements\recipes\misc\default_colorizer.json +f347f4ce869207e62a7887df1252505a3432e12a data\hexcasting\recipes\pride_colorizer_genderfluid.json +f8ee073c1c03f1c11147e4801eeba1f86e5459ba data\hexcasting\recipes\dye_colorizer_blue.json +b16ff5314d457bc7e9e224e102d1e04ce3a62361 data\hexcasting\recipes\brainsweep\directrix_redstone.json +862f1a61a296a834df8a93dbd5a6cdfa2df15721 data\hexcasting\advancements\recipes\tools\staff\acacia.json +ea87956c49dcfabb0d39af45c016130d258181da data\hexcasting\recipes\staff\birch.json +5e66982df6a1074c81f381898033b521ca337695 data\hexcasting\recipes\staff\quenched.json +ee5db13cbb33d9c62bcb1eb645e2c4bea97ad44a data\hexcasting\advancements\recipes\building_blocks\amethyst_dust_unpacking.json +f4c56ea7143ce92a0ae0b663310e53644a7309f7 data\hexcasting\advancements\recipes\misc\pride_colorizer_pansexual.json +3b03fdae3896212a0b8b9b3a2d4880d197e67d2d data\hexcasting\recipes\jeweler_hammer.json +7ca0f9fc6e8ae1ad08ef5c29a0b279b891f7d8d4 data\hexcasting\advancements\recipes\misc\pride_colorizer_aroace.json +b6fa898369ac52cdd9d7f91e3b8a2cb881c3829f data\hexcasting\advancements\recipes\decorations\scroll_medium.json +0654e70ed1ed8be20ae3dd9f4955cd14f9fa40d0 data\hexcasting\advancements\recipes\tools\staff\jungle.json +1b570b35288be9f6faab1536d6e45cb52eb088c0 data\hexcasting\advancements\recipes\tools\staff\dark_oak.json +505eb9192df0b48867e58e09ce36b2259dc6d3e8 data\hexcasting\advancements\recipes\decorations\scroll.json +09096a40275b6c49d4b4e6984869aa43b34712c3 data\hexcasting\recipes\dynamicseal_focus.json +b7084f131b0cdb9c2c698a3c5b3450d69e788d6e data\hexcasting\recipes\dye_colorizer_yellow.json +55602e415fc1b797439b674050887e9e388558c9 data\hexcasting\advancements\recipes\building_blocks\edified_panel.json +a9111ff52513200af47b79cf98b2e545699497bb data\hexcasting\advancements\recipes\building_blocks\amethyst_tiles.json +ea63e49709bd80cb9f4cd1fe13e9bd0281101c9a data\hexcasting\recipes\slate.json +8e48c680b38666c2e7da71fbe4ceddf5d99a5cbc data\hexcasting\advancements\recipes\food\sub_sandwich.json +4d5e4a6374731b2d0a90c70a5d489703fd966977 data\hexcasting\advancements\recipes\misc\dye_colorizer_lime.json +7552df3fc726cc4cdaa88aa4823eff6ce069fb75 data\hexcasting\recipes\slate_block_from_slates.json +72f70637aea1c11683e9ee91d83c2807c6ec33a9 data\hexcasting\recipes\compat\farmersdelight\cutting\akashic_trapdoor.json +2cea013887734cbc4971bcd57e7e4f6a2b25c8e1 data\hexcasting\advancements\recipes\tools\focus.json +f1bae034d27d218bf262a8c777b787d232489f16 data\hexcasting\recipes\lens.json +963d87d2738686e5398a178b8b369228ff067403 data\hexcasting\recipes\spellbook.json +f0e71ae8c6a9170669f44096a55a875d11497c56 data\hexcasting\recipes\staff\warped.json +7c479398bbc7185a2c3efd568ad266d8109245bf data\hexcasting\advancements\recipes\redstone\edified_door.json +7baf0777533737aef68bcac36944943b77138d29 data\hexcasting\recipes\edified_button.json +daa7b13d5370f4306f8cdf3037fc346e8918950a data\hexcasting\recipes\dye_colorizer_brown.json +f08a0aee92b281ae325d907e6fe4a3b03980f2aa data\hexcasting\advancements\recipes\tools\staff\edified.json +61fafd43af83bdca6720d0993ab71f40a8bebd40 data\hexcasting\advancements\recipes\redstone\akashic_connector.json +00853ec1885c1f72674c07caf6fd04904e248f8f data\hexcasting\recipes\brainsweep\directrix_boolean.json +b90ad4cbffc2e3c01671dfe8bda5e42d9b8a685c data\hexcasting\advancements\recipes\tools\staff\crimson.json +ef96ae9709ec931ce6b6af8a539f9bc483236449 data\hexcasting\recipes\scroll_medium.json +552c235dc58a46a3e57913c9b9faf3f21abeae32 data\hexcasting\advancements\recipes\building_blocks\stripped_edified_wood.json +a0b87b1b21506708d09c9295b7afc13de6b1fce6 data\hexcasting\recipes\pride_colorizer_aromantic.json +ae88fcdecbfbdd0a0fe778467421a3b32d7ed735 data\create\recipes\crushing\amethyst_cluster.json +aa7558ec1baf6070efbe448d886e20e964e33f96 data\hexcasting\advancements\recipes\brainsweep\brainsweep\quench_allay.json +a8d604ba059d54502837809815d3ac9bbcaa89bf data\hexcasting\advancements\recipes\redstone\akashic_bookshelf.json +5889e2df2fb4e1ea29f2590b96bb3aa94961a09a data\hexcasting\recipes\scroll.json +0038883bd294cc8a1b324d6782478d5e37b4dbf9 data\hexcasting\advancements\recipes\misc\dye_colorizer_pink.json +71f821f5d24b0bf9ecd860d51e055628fe4af50c data\hexcasting\recipes\edified_panel.json +7e1a5a873d655e0efba80f22ae9b1de4f248e67a data\hexcasting\advancements\recipes\misc\decompose_quenched_shard\shard.json +417695497a95436186c1a4ed842d7975d754f9eb data\hexcasting\recipes\stripped_edified_wood.json +92bdf87687d8823036fae6bd01782c653831286b data\hexcasting\recipes\brainsweep\impetus_look.json +3608f0ec056f2c5d29a9a89305218497fd2c4383 data\hexcasting\recipes\stonecutting\amethyst_tiles.json +8815ea5d8d7379062e050adc5736cc579c3bdd9e data\hexcasting\recipes\edified_stairs.json +f482a4349786388cc8f11d5550548f7d60265438 data\hexcasting\recipes\staff\mangrove.json +6e2dc32f975d987b8dfd329507334f647bceadc0 data\hexcasting\advancements\recipes\tools\staff\mangrove.json +5a90084c03d6e8424872870c8b65f4771b447f03 data\hexcasting\recipes\brainsweep\budding_amethyst.json +2eacf53894ae97712dc3874777e29dce0a0e5540 data\hexcasting\advancements\recipes\misc\pride_colorizer_asexual.json +af9a260c24e0a65eea321f0dd9dd2fa7d648707f data\hexcasting\advancements\recipes\building_blocks\amethyst_dust_packing.json +24c244e53c7e47b85845d2ee36b1665410cf495a data\hexcasting\recipes\edified_planks.json +b84c113ef5321c9df9ac9080de03e8d8639feab2 data\hexcasting\advancements\recipes\misc\pride_colorizer_genderqueer.json +97062771a426f6e4b9e3bfd6daa62b1d4b3c7039 data\hexcasting\recipes\abacus.json +41a570f970c9af8229cb1140a11a5220fac00957 data\hexcasting\advancements\recipes\tools\staff\spruce.json +2c56c267e23e75d5a3b9358d424d69642e001b50 data\hexcasting\recipes\decompose_quenched_shard\dust.json +4003f297be29810cebde4995fb2838c2c68a25ea data\hexcasting\recipes\pride_colorizer_lesbian.json +5f216dbb7b89fd837e2dd73e3ed41c8d412de234 data\hexcasting\advancements\recipes\misc\decompose_quenched_shard\dust.json +648f1862fde1dd8ade80b2991b8c8e3991389e95 data\hexcasting\recipes\dye_colorizer_light_blue.json +fb486df96798724da2fcc0df5706f19bc1ff94dc data\hexcasting\advancements\recipes\misc\dye_colorizer_light_blue.json +946cde51bbfc2af344b078f6b39389ffc44462f4 data\hexcasting\advancements\recipes\brainsweep\brainsweep\impetus_storedplayer.json +0b951ce7b9d1bfb07ae012b12225b595d36c6e66 data\hexcasting\recipes\amethyst_dust_packing.json +838b91c33a72a58aa286607eaaa17cdd6b4c90ba data\hexcasting\recipes\amethyst_sconce.json +8f515bf8ccea70b3d88845ed83966dc0c66082f6 data\hexcasting\advancements\recipes\tools\staff\oak.json +0f2e63a9361d18aac764f6a4a4f13b9b862ac2ee data\hexcasting\recipes\compat\create\crushing\amethyst_shard.json +cedc2889c4f327b18755bbe8c3c595d302e2a9d0 data\hexcasting\recipes\decompose_quenched_shard\shard.json +2003fed3aa4eb622b6b07a9e65946fb40be14420 data\hexcasting\advancements\recipes\brainsweep\brainsweep\impetus_rightclick.json +7d71eb93bbb0856167cf4521283e39f0048078ee data\hexcasting\advancements\recipes\redstone\edified_button.json +0bd7c9f4a9bf29c1b63b2f9378f0a7e2f594b7b7 data\hexcasting\recipes\pride_colorizer_nonbinary.json +157ee5fba985bbd01a87f44578890dab5489a8e5 data\hexcasting\advancements\recipes\misc\dye_colorizer_green.json +c2ef04b311251b4eb22320b2f5313c54533a9974 data\hexcasting\advancements\recipes\tools\staff\birch.json +2fff80cd3dabd2bc1744eecd72b2364b0f91c7c1 data\hexcasting\advancements\recipes\misc\dye_colorizer_yellow.json +e536791d0c6fb48206e6e30d56879eaf0a9e4bd7 data\hexcasting\recipes\akashic_bookshelf.json +faaa9c39dbcdd131c5fbec9ac6a26d6dc5e72053 data\hexcasting\advancements\recipes\misc\dye_colorizer_light_gray.json +e0609202271e402d8ae58e4f8eaf11dcdda10a9e data\hexcasting\recipes\brainsweep\akashic_record.json +3bf96944a8eed8b8d3f5d96b609297727c078cb7 data\hexcasting\advancements\recipes\misc\dye_colorizer_purple.json +203b7035125390abb4ed77b3a4dca8f8f8f57bc5 data\hexcasting\recipes\dye_colorizer_light_gray.json +e691130641b11c0a030a51c71dee0ba356f3b5bd data\hexcasting\recipes\compat\farmersdelight\cutting\edified_log_aventurine.json +8f7b81add0153ad94900acc66cd8174ae7115f64 data\hexcasting\advancements\recipes\building_blocks\slate_block_from_slates.json +06402fb37fe4bb05918d13dbfdb89f4c2b67f3ec data\hexcasting\advancements\recipes\tools\cypher.json +c8f2ad363e4d20054f4e56fde02c8775a45a7169 data\hexcasting\recipes\artifact.json +8bea75fdc5e64c464dcf5f85166e767ff44e6dc2 data\hexcasting\advancements\recipes\misc\pride_colorizer_lesbian.json +c6228d72ca800a7dd336e82bbb9b4f20f89de29d data\hexcasting\advancements\recipes\redstone\edified_pressure_plate.json +0aaf55492e850d2bb1ec2f9986406ca61fde4cfd data\hexcasting\recipes\dye_colorizer_lime.json +e6a592721234448f2ee7ec402bca10a9b78b4677 data\hexcasting\advancements\recipes\decorations\slate.json +e9166f40c8797cdbf3d8062dfa35c74f850f1000 data\hexcasting\advancements\recipes\misc\dye_colorizer_white.json +2aa7d74e29a7c5ee4f1b8835cf7c6109eed81d77 data\hexcasting\recipes\brainsweep\quench_allay.json +f81053a3269c1b371be3f8057bad4803056ee0f9 data\hexcasting\recipes\dye_colorizer_orange.json +bc729ac7cf84d29a99cd34d50c152c0b9d20bd7a data\hexcasting\advancements\recipes\brainsweep\brainsweep\akashic_record.json +1a9dd55a24f56a4e9467f1117e0898f7e71ade67 data\hexcasting\advancements\recipes\decorations\amethyst_sconce.json +d7de5d626fd799a2522af36f0c62c52fe490e6d2 data\hexcasting\recipes\edified_door.json +c3f7b03fe184ed5e54a8ae06d130adf507b7683d data\hexcasting\recipes\staff\bamboo.json +6f2634e5588aede8e29157ecc859652d8a9f4065 data\hexcasting\advancements\recipes\misc\dye_colorizer_orange.json +b10d590e918e35b16578a8b739a1c4e7e2202e16 data\hexcasting\advancements\recipes\misc\dye_colorizer_cyan.json +0e792d49c81d2164e827d1bdedaa0fa358dfc437 data\hexcasting\advancements\recipes\misc\pride_colorizer_aromantic.json +afb422ad4a918ee0161bf077f09475bb1da2b4eb data\hexcasting\recipes\amethyst_dust_unpacking.json +98c0843e6a83b91820f1c720e206295eec20ff95 data\hexcasting\recipes\ancient_scroll_paper.json +011f8daf15148d4b77686c6d382d8f5c288a333d data\hexcasting\advancements\recipes\building_blocks\ancient_scroll_paper.json +9b7c5220fbaf3e84fa9e81eae322eed5d37b22d3 data\hexcasting\recipes\pride_colorizer_transgender.json +a1f9df0537c0ef33a1164cf94e8ff4b1094f889f data\hexcasting\advancements\recipes\tools\staff\warped.json +54335e0004423899ad37763a1d8456cc0a6e72a7 data\hexcasting\advancements\recipes\misc\decompose_quenched_shard\charged.json +641d8c38b8109665314fccbebd9068ba10b04118 data\hexcasting\advancements\recipes\misc\dye_colorizer_gray.json +5e98cec2084f0cfbb959c3ec39bd85a3369f443b data\hexcasting\advancements\recipes\tools\abacus.json +b300f7729e75614fce412457f6717686680f81da data\hexcasting\recipes\sub_sandwich.json +1a0d55e6824c078453c1d44e885a1c51ba707a41 data\hexcasting\recipes\dye_colorizer_white.json +36d26f34d0405ff2d1e728e5b5174502686e3590 data\hexcasting\advancements\recipes\brainsweep\brainsweep\budding_amethyst.json +903cbe4d4c4e5abcd5e006f9d0237e8c596228ba data\hexcasting\recipes\edified_tile.json +1093cccc6b1c45eb91f7c1680ef575a7bffb2744 data\hexcasting\advancements\recipes\building_blocks\edified_planks.json +233aeedc73173427e7b2287772a4f914f97b072c data\hexcasting\recipes\dye_colorizer_red.json +2a2f60fb0f63ee278b74c418acf04575304c521f data\hexcasting\advancements\recipes\tools\jeweler_hammer.json +004e0694b3bf53140be7df89a4defc255b800619 data\hexcasting\advancements\recipes\tools\focus_rotated.json +ea46e570a43cd3ea1cc78c51d9da45d93944730a data\hexcasting\advancements\recipes\redstone\directrix\empty.json +4d941fc399c6b7a470513a572ecd88982823da84 data\hexcasting\advancements\recipes\building_blocks\edified_wood.json +aa1caae7eba6aede0f179619488e2253b3b723dd data\hexcasting\recipes\focus_rotated.json +b1f8375aaf0d66035dee720ea59605f69fc0a154 data\hexcasting\recipes\edified_fence.json +1b092acfc3115702c74e141492e649d58512f259 data\hexcasting\recipes\staff\oak.json +0864e8b86bdad0bf9ab2ddeb0cd5a182808b5a0a data\hexcasting\recipes\default_colorizer.json +40ed21dc80d39236ca0e6d2cea60861c637cf931 data\hexcasting\advancements\recipes\misc\pride_colorizer_nonbinary.json +04902d4eca30560bc601a8196d82f74f3fa5b191 data\hexcasting\recipes\dynamicseal_spellbook.json +bd63b845e02ee4b1b9abe168a196335ccbed1ca5 data\hexcasting\recipes\scroll_paper_lantern.json +996c8361766377a70e0b5a5caff3076fc6031b0a data\hexcasting\recipes\impetus\empty.json +8b7136c206b799a2e394aa02316b0509674ff64f data\hexcasting\advancements\recipes\tools\staff\bamboo.json +c1541738df1ee41c362ad3b9c3a9f0e181bd5c62 data\hexcasting\recipes\pride_colorizer_plural.json +4a803e049915fd3c7144155ae3a1b05a917ea290 data\hexcasting\recipes\pride_colorizer_pansexual.json +71d38559bf455ea343ac0237a57db4d3f0833a7c data\hexcasting\advancements\recipes\misc\dye_colorizer_magenta.json +9ea4fe5272ce2241d98f30359f55cfc1936c7b48 data\hexcasting\advancements\recipes\tools\staff\cherry.json +72447ac69a0d85f91064180d3c852040a9e33832 data\hexcasting\recipes\pride_colorizer_asexual.json +a8cab28cffdf495253a320094d202fccc5aeb113 data\hexcasting\advancements\recipes\decorations\ancient_scroll_paper_lantern.json +14f3b217e150efbbff329d67aec96f818a1da99c data\hexcasting\recipes\dye_colorizer_purple.json +1e51cd4f527b3aea4d61d91829e47c191c9c05bb data\hexcasting\recipes\pride_colorizer_gay.json +f64fa00d85a9abb24e89b0d2c9f818001371f5e6 data\hexcasting\recipes\slate_block.json +a85cfbd7988f5df0b18d160591605aea8e6808d2 data\hexcasting\recipes\trinket.json +63189af501442318a90c16d6951e51c0c5d6d4f3 data\hexcasting\recipes\compat\farmersdelight\cutting\edified_log_purple.json +494aa470790ae46baebbf24ee5b76f5885c1af1a data\hexcasting\recipes\ageing_scroll_paper_lantern.json +bc8fe4d2f55fe119b0b146a71782a3d4788380b1 data\create\recipes\crushing\amethyst_block.json +7522be58b09554a3f1a54d5b2343c3eab01447a3 data\hexcasting\recipes\dye_colorizer_magenta.json +b624d103d944a8a1d4d8a9e85c198a5492b476f8 data\hexcasting\advancements\recipes\redstone\edified_trapdoor.json +a3130e3098e35b75afae4f31996d9ab7468e0bc3 data\hexcasting\advancements\recipes\tools\thought_knot.json +23eff6111b0385b66d3ad5fbabfc625f426517a6 data\hexcasting\advancements\recipes\brainsweep\brainsweep\directrix_redstone.json +c43fb770003c8d882fd9c1e7d1ecb5f196cba1ab data\hexcasting\recipes\cypher.json +2c292e12b5e85b1701740c222e5c5465799ad1dc data\hexcasting\recipes\pride_colorizer_aroace.json +dcc9bf721dd40724abcc69f1f7e8a1610dbf88f3 data\hexcasting\recipes\compat\farmersdelight\cutting\akashic_door.json +f77518b6993fe8e31de10af286c33ab72c0f9077 data\hexcasting\advancements\recipes\redstone\impetus\empty.json +93ed0491548920bc75797d18501c750ef07fe3ea data\hexcasting\advancements\recipes\misc\pride_colorizer_bisexual.json +27dc4a1647f264c45b27f5552fd9403a02853484 data\hexcasting\advancements\recipes\tools\spellbook.json +7166cd4355d11c209bc7749bc862caddcfd795fb data\hexcasting\recipes\dye_colorizer_cyan.json +b6720c1c73455ad817bac9b5ca2ca045c5c4050c data\hexcasting\recipes\pride_colorizer_agender.json +ed5c690324e3d9b55599f00f078ae225072a2e7f data\hexcasting\recipes\brainsweep\impetus_rightclick.json +c4b985635c3b1a519d7a83da65daba5bdd3a5f59 data\hexcasting\advancements\recipes\decorations\ageing_scroll_paper_lantern.json +846baaef37844216b57bb9b35e52b1bb6b56b413 data\hexcasting\advancements\recipes\decorations\scroll_small.json +441f336edb635e5d8c2a7183906fed1c501f06fd data\hexcasting\recipes\pride_colorizer_bisexual.json +f80dbf59957be175fbcd63224005e09c4cd1a122 data\hexcasting\recipes\compat\farmersdelight\cutting\edified_log_citrine.json +a72a0fcc0f3a81d31b30a7a626aef537796ca73b data\hexcasting\advancements\recipes\tools\staff\quenched.json +8f8773a541bc6a4a6c55a23f4f98b5da4f61a031 data\hexcasting\recipes\scroll_paper.json +4680e9dafcf9b60b3485609519d66eefcfd539bc data\hexcasting\recipes\staff\dark_oak.json +77369113dc54d1c64b9101861dd8a1930bf1c1c4 data\hexcasting\recipes\edified_wood.json +45915b542d8070f2502a4047218679b08033b12d data\hexcasting\advancements\recipes\decorations\scroll_paper_lantern.json +a366ea3750adc0d336ab8f318c40baed3f9c3eb7 data\hexcasting\recipes\brainsweep\impetus_storedplayer.json +151875101066f7af5788c7a2e1c6b342971a546a data\hexcasting\recipes\compat\farmersdelight\cutting\akashic_wood.json +b94bc4dd4a63db10af86c524ba00eae157c1824b data\hexcasting\advancements\recipes\building_blocks\edified_fence_gate.json +c2a0a489967db4064dfbe1ee6367e132665f3c00 data\hexcasting\recipes\edified_slab.json +5e28e2c352366720ce91b73f8c8c38e217f7198d data\hexcasting\recipes\edified_fence_gate.json +6493676f8ca93a7be8d70e25d69ddad935b3f16b data\hexcasting\advancements\recipes\tools\lens.json +b5946314683e5a823b577a18d13fb437a35aafd5 data\hexcasting\recipes\decompose_quenched_shard\charged.json +c03c81dc123294472e8bb6f836c319e96f8db4f5 data\hexcasting\advancements\recipes\building_blocks\edified_fence.json +b29f9d9c14e60ded1148680e2e0ef405b5a3c845 data\hexcasting\advancements\recipes\misc\uuid_colorizer.json +78958099bf4337ad281580d90f434b3074ad18c8 data\hexcasting\recipes\pride_colorizer_genderqueer.json +0b172aef920da7ba63fe152903ce005c1f5df5f1 data\hexcasting\recipes\staff\acacia.json +31ec6474ddae967a6c1dadf9be8292d375510364 data\hexcasting\advancements\recipes\building_blocks\edified_tile.json +d47352426739a0fc500a385d820d767a307e1d16 data\hexcasting\advancements\recipes\misc\dye_colorizer_black.json +095aeb2882c6849f10fb6536e7c780790778e5e7 data\hexcasting\recipes\staff\jungle.json +923e7cd200518042f11474713eca9ccad126dab7 data\hexcasting\recipes\staff\spruce.json +fd7c8325fcaa6a718e90c09251b447fb365523d4 data\hexcasting\recipes\pride_colorizer_demiboy.json +2b64261bd4aefdc55d35400f25835434f88856cf data\hexcasting\recipes\amethyst_tiles.json +12bd3d04c791ef16aad5e992f038d6726229a436 data\hexcasting\advancements\recipes\tools\artifact.json +de38d15e7a91c77df24c1dc954b3e98ee197876f data\hexcasting\recipes\focus.json +fd2f25b0a71806c96af5a307fad76f66de6210a4 data\hexcasting\advancements\recipes\building_blocks\slate_block.json +1ad54df5eaee3d1e810d2c91bd03f626084e30b6 data\hexcasting\recipes\edified_trapdoor.json +4aaefc65af5fe69d312247fdda7d983edf8dcd9a data\hexcasting\recipes\pride_colorizer_intersex.json +b20be6eb5a8b60567871444e65d773ec9a67ece1 data\hexcasting\recipes\staff\crimson.json +775560efa36581389c0319435bda035be262ed4f data\hexcasting\advancements\recipes\building_blocks\edified_stairs.json +ce9d0b976f7cc8ad4a0815bbea6c43115addb90f data\hexcasting\advancements\recipes\building_blocks\scroll_paper.json +db5ae3a2fda235cf1c83fd83e0026a262e668217 data\hexcasting\advancements\recipes\building_blocks\edified_slab.json +06ca609ba1a32f094cf6edbc989bc9ddaf9d342c data\hexcasting\advancements\recipes\misc\pride_colorizer_genderfluid.json +af8fe74b624df4a31727347b9826614a66092b0a data\hexcasting\advancements\recipes\misc\pride_colorizer_agender.json +664ce1a38c9b1c9ec21b7e078631e181fc0b2498 data\hexcasting\recipes\staff\edified.json +b6e762c198b9632defd7f8b11287702abecd681d data\hexcasting\recipes\staff\mindsplice.json +5401828f85e709b5817ecc8464dc63e536a730dc data\hexcasting\recipes\staff\cherry.json +51b047601368a103be166d907633b196d2d8a4e8 data\hexcasting\recipes\compat\farmersdelight\cutting\edified_log.json +42b8e462de1d7006de3a7658757377450e773107 data\hexcasting\advancements\recipes\misc\dye_colorizer_blue.json +499c5c09e3772989350f9ab3264b8692449a6dea data\hexcasting\advancements\recipes\misc\pride_colorizer_gay.json +30352d8ad510768770bb1b2d378959b7a502f825 data\hexcasting\advancements\recipes\brainsweep\brainsweep\impetus_look.json +6ed61e03c51dc653cd66e643a6d33fe9105ff171 data\hexcasting\advancements\recipes\brainsweep\brainsweep\directrix_boolean.json +0ead307e47242ba140584f6bd20088a1fa7c2909 data\hexcasting\recipes\directrix\empty.json +68ab70e0b4e432a3492767c5597ecd836f106714 data\hexcasting\advancements\recipes\tools\staff\mindsplice.json +5fab1b9c93304a53a4c305b511704458e4593444 data\hexcasting\recipes\pride_colorizer_demigirl.json +170af3c83a45f9550827cc48e4bb5a621d06d685 data\hexcasting\advancements\recipes\misc\pride_colorizer_transgender.json +7f2f29981df2ca4464ee0250180e670f5331f65b data\hexcasting\recipes\dye_colorizer_pink.json +61e53f02baefd31308e99407d56403dfc18e36e1 data\hexcasting\recipes\akashic_connector.json +eb9ebf77f0daa32f665a60888fcda19c940f0b2f data\hexcasting\advancements\recipes\misc\pride_colorizer_demigirl.json +7aa3bf4a3d6fb92743b29dfe89d50537fefc0db9 data\hexcasting\advancements\recipes\misc\pride_colorizer_intersex.json +410bfde90cb977db3f13814e94484fa11fca7cfc data\hexcasting\recipes\thought_knot.json +55ea553a96e1d6a54385890f7c48fe7b2bed6871 data\hexcasting\advancements\recipes\tools\trinket.json +e765ee2bd324240e8ed3d625be431de3281f0070 data\hexcasting\recipes\dye_colorizer_gray.json +ad647a2078099344ea7f9836a68e1bf8e8119277 data\hexcasting\advancements\recipes\misc\dye_colorizer_brown.json +8c043c7f6a7911b67324e2fd42f0b3b19a792af3 data\hexcasting\recipes\ancient_scroll_paper_lantern.json diff --git a/Fabric/src/main/java/at/petrak/hexcasting/fabric/FabricHexConfig.java b/Fabric/src/main/java/at/petrak/hexcasting/fabric/FabricHexConfig.java index a49ab760f3..a0ff01d315 100644 --- a/Fabric/src/main/java/at/petrak/hexcasting/fabric/FabricHexConfig.java +++ b/Fabric/src/main/java/at/petrak/hexcasting/fabric/FabricHexConfig.java @@ -15,6 +15,7 @@ import me.shedaniel.autoconfig.serializer.PartitioningSerializer; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.RandomSource; import net.minecraft.util.Mth; import net.minecraft.world.level.Level; @@ -181,13 +182,16 @@ public static final class Server implements HexConfig.ServerConfigAccess, Config @ConfigEntry.Gui.Tooltip private List circleActionDenyList = List.of(); @ConfigEntry.Gui.Tooltip + private boolean greaterTeleportSplatsItems = DEFAULT_GREATER_TELEPORT_SPLATS_ITEMS; + @ConfigEntry.Gui.Tooltip private boolean villagersOffendedByMindMurder = DEFAULT_VILLAGERS_DISLIKE_MIND_MURDER; @ConfigEntry.Gui.Tooltip private boolean doesTrueNameHaveAmbit = DEFAULT_TRUE_NAME_HAS_AMBIT; - - @ConfigEntry.Gui.Tooltip private List tpDimDenylist = DEFAULT_DIM_TP_DENYLIST; + + @ConfigEntry.Gui.Tooltip + private double traderScrollChance = DEFAULT_TRADER_SCROLL_CHANCE; // ModMenu bad and doesn't like java objects in here so we do stupid string parsing @ConfigEntry.Gui.Tooltip @@ -209,11 +213,22 @@ public static final class Server implements HexConfig.ServerConfigAccess, Config @ConfigEntry.Gui.Tooltip private double loreChance = HexLootHandler.DEFAULT_LORE_CHANCE; + @ConfigEntry.Gui.Tooltip + private List cypherInjectionsRaw = HexLootHandler.DEFAULT_CYPHER_INJECTS + .stream() + .map(ResourceLocation::toString) + .toList(); + @ConfigEntry.Gui.Excluded + private transient List cypherInjections; + @ConfigEntry.Gui.Tooltip + private double cypherChance = HexLootHandler.DEFAULT_CYPHER_CHANCE; + @Override public void validatePostLoad() throws ValidationException { this.maxOpCount = Math.max(this.maxOpCount, 0); this.maxSpellCircleLength = Math.max(this.maxSpellCircleLength, 4); + this.traderScrollChance = Mth.clamp(this.traderScrollChance, 0.0, 1.0); this.scrollInjections = new Object2IntOpenHashMap<>(); try { @@ -239,6 +254,18 @@ public void validatePostLoad() throws ValidationException { } this.loreChance = Mth.clamp(this.loreChance, 0.0, 1.0); + + this.cypherInjections = new ArrayList<>(); + try { + for (var table : this.cypherInjectionsRaw) { + ResourceLocation loc = new ResourceLocation(table); + this.cypherInjections.add(loc); + } + } catch (Exception e) { + throw new ValidationException("Bad parsing of cypher injects", e); + } + + this.cypherChance = Mth.clamp(this.cypherChance, 0.0, 1.0); } @Override @@ -266,6 +293,9 @@ public boolean isActionAllowedInCircles(ResourceLocation actionID) { return noneMatch(circleActionDenyList, actionID); } + @Override + public boolean doesGreaterTeleportSplatItems() { return greaterTeleportSplatsItems; } + @Override public boolean doVillagersTakeOffenseAtMindMurder() { return villagersOffendedByMindMurder; @@ -281,6 +311,10 @@ public boolean trueNameHasAmbit() { return doesTrueNameHaveAmbit; } + public double traderScrollChance() { + return traderScrollChance; + } + /** * Returns -1 if none is found */ @@ -292,8 +326,16 @@ public boolean shouldInjectLore(ResourceLocation lootTable) { return anyMatchResLoc(this.loreInjections, lootTable); } - public double getLoreChance() { + public double loreChance() { return loreChance; } + + public boolean shouldInjectCyphers(ResourceLocation lootTable) { + return anyMatchResLoc(this.cypherInjections, lootTable); + } + + public double cypherChance() { + return cypherChance; + } } } diff --git a/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/CCStaffcastImage.java b/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/CCStaffcastImage.java index bb6018946f..383deefaab 100644 --- a/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/CCStaffcastImage.java +++ b/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/CCStaffcastImage.java @@ -10,7 +10,7 @@ import org.jetbrains.annotations.Nullable; public class CCStaffcastImage implements Component { - public static final String TAG_HARNESS = "harness"; + public static final String TAG_VM = "harness"; private final ServerPlayer owner; private CompoundTag lazyLoadedTag = new CompoundTag(); @@ -39,11 +39,11 @@ public void setImage(@Nullable CastingImage image) { @Override public void readFromNbt(CompoundTag tag) { - this.lazyLoadedTag = tag.getCompound(TAG_HARNESS); + this.lazyLoadedTag = tag.getCompound(TAG_VM); } @Override public void writeToNbt(CompoundTag tag) { - tag.put(TAG_HARNESS, this.lazyLoadedTag); + tag.put(TAG_VM, this.lazyLoadedTag); } } diff --git a/Fabric/src/main/java/at/petrak/hexcasting/fabric/loot/FabricHexLootModJankery.java b/Fabric/src/main/java/at/petrak/hexcasting/fabric/loot/FabricHexLootModJankery.java index 5aadc8df41..75b4410e43 100644 --- a/Fabric/src/main/java/at/petrak/hexcasting/fabric/loot/FabricHexLootModJankery.java +++ b/Fabric/src/main/java/at/petrak/hexcasting/fabric/loot/FabricHexLootModJankery.java @@ -2,6 +2,7 @@ import at.petrak.hexcasting.common.lib.HexItems; import at.petrak.hexcasting.common.loot.AddPerWorldPatternToScrollFunc; +import at.petrak.hexcasting.common.loot.AddHexToAncientCypherFunc; import at.petrak.hexcasting.fabric.FabricHexInitializer; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.block.Blocks; @@ -33,7 +34,11 @@ public static void lootLoad(ResourceLocation id, Consumer addP } if (FabricHexInitializer.CONFIG.server.shouldInjectLore(id)) { - addPool.accept(makeLoreAddPool(FabricHexInitializer.CONFIG.server.getLoreChance())); + addPool.accept(makeLoreAddPool(FabricHexInitializer.CONFIG.server.loreChance())); + } + + if (FabricHexInitializer.CONFIG.server.shouldInjectCyphers(id)) { + addPool.accept(makeCypherAddPool(FabricHexInitializer.CONFIG.server.cypherChance())); } } @@ -56,4 +61,12 @@ private static LootPool.Builder makeLoreAddPool(double chance) { .setRolls(ConstantValue.exactly(1)) .add(LootItem.lootTableItem(HexItems.LORE_FRAGMENT)); } + + private static LootPool.Builder makeCypherAddPool(double chance) { + return LootPool.lootPool() + .when(LootItemRandomChanceCondition.randomChance((float) chance)) + .setRolls(ConstantValue.exactly(1)) + .add(LootItem.lootTableItem(HexItems.ANCIENT_CYPHER)) + .apply(() -> new AddHexToAncientCypherFunc(new LootItemCondition[0])); + } } diff --git a/Fabric/src/main/java/at/petrak/hexcasting/fabric/mixin/FabricPlayerMixin.java b/Fabric/src/main/java/at/petrak/hexcasting/fabric/mixin/FabricPlayerMixin.java index 2c7584663f..45a22117b7 100644 --- a/Fabric/src/main/java/at/petrak/hexcasting/fabric/mixin/FabricPlayerMixin.java +++ b/Fabric/src/main/java/at/petrak/hexcasting/fabric/mixin/FabricPlayerMixin.java @@ -22,5 +22,9 @@ protected FabricPlayerMixin(EntityType entityType, Level var out = cir.getReturnValue(); out.add(HexAttributes.GRID_ZOOM); out.add(HexAttributes.SCRY_SIGHT); + out.add(HexAttributes.FEEBLE_MIND); + out.add(HexAttributes.MEDIA_CONSUMPTION_MODIFIER); + out.add(HexAttributes.AMBIT_RADIUS); + out.add(HexAttributes.SENTINEL_RADIUS); } } diff --git a/Neoforge/build.gradle b/Neoforge/build.gradle index bea4ef7681..59a78e9373 100644 --- a/Neoforge/build.gradle +++ b/Neoforge/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'com.gradleup.shadow' +} + architectury { platformSetupLoomIde() neoForge() @@ -30,6 +34,7 @@ configurations { repositories { mavenCentral() + mavenLocal() // If you have mod jar dependencies in ./libs, you can declare them as a repository like so: flatDir { @@ -63,24 +68,24 @@ dependencies { neoForge "net.neoforged:neoforge:${neoforgeVersion}" common(project(path: ':Common', configuration: 'namedElements')) { transitive false } shadowBundle(project(path: ':Common', configuration: 'transformProductionNeoForge')) { transitive false } - implementation "thedarkcolour:kotlinforforge:$kotlinForForgeVersion" + modImplementation "thedarkcolour:kotlinforforge:$kotlinForForgeVersion" // === MANDATORY DEPS === - implementation "at.petra-k:paucal:$paucalVersion+$minecraftVersion-common" - implementation "vazkii.patchouli:Patchouli:1.21-$patchouliVersion-NEOFORGE-SNAPSHOT" - implementation "top.theillusivec4.caelus:caelus-forge:$caelusVersion" -// implementation("com.samsthenerd.inline:inline-forge:$minecraftVersion-$inlineVersion") + modImplementation "at.petra-k:paucal:$paucalVersion+$minecraftVersion-common" + modImplementation "vazkii.patchouli:Patchouli:1.21-$patchouliVersion-NEOFORGE-SNAPSHOT" + modImplementation "top.theillusivec4.caelus:caelus-forge:$caelusVersion" + modImplementation "com.samsthenerd.inline:inline-common:1.21.1-1.2.2-74" // needed for inline to run runtimeOnly("me.shedaniel.cloth:cloth-config-forge:$clothConfigVersion") // === OPTIONAL DEPS === - compileOnly "dev.emi:emi-neoforge:${emiVersion}:api" - runtimeOnly "dev.emi:emi-neoforge:${emiVersion}" + modCompileOnly "dev.emi:emi-neoforge:${emiVersion}:api" + modRuntimeOnly "dev.emi:emi-neoforge:${emiVersion}" modImplementation "io.wispforest:accessories-neoforge:$accessoriesVersion" - api("com.github.Virtuoel:Pehkui:${pehkuiVersion}-1.21-neoforge") + modApi("com.github.Virtuoel:Pehkui:${pehkuiVersion}-1.21-neoforge") // "Required due to issues with JIJ dependency resolving in arch or something" // https://github.com/wisp-forest/accessories @@ -138,4 +143,11 @@ processResources { } } -jar.finalizedBy('reobfJar') \ No newline at end of file +shadowJar { + configurations = [project.configurations.shadowBundle] + archiveClassifier = 'dev-shadow' +} + +remapJar { + inputFile.set shadowJar.archiveFile +} \ No newline at end of file diff --git a/Neoforge/gradle.properties b/Neoforge/gradle.properties index 83205facce..e1594fa813 100644 --- a/Neoforge/gradle.properties +++ b/Neoforge/gradle.properties @@ -1,8 +1,8 @@ -neoforgeVersion=21.1.81 +neoforgeVersion=21.1.172 loom.platform=neoforge -kotlinForForgeVersion=5.6.0 +kotlinForForgeVersion=5.8.0 curiosVersion=5.2.0-beta.3 caelusVersion=3.1.0+1.20 diff --git a/Neoforge/src/generated/resources/data/forge/loot_modifiers/global_loot_modifiers.json b/Neoforge/src/generated/resources/data/forge/loot_modifiers/global_loot_modifiers.json index 978f1f8d21..46e71c9b97 100644 --- a/Neoforge/src/generated/resources/data/forge/loot_modifiers/global_loot_modifiers.json +++ b/Neoforge/src/generated/resources/data/forge/loot_modifiers/global_loot_modifiers.json @@ -3,9 +3,13 @@ "hexcasting:scroll/minecraft/chests/nether_bridge", "hexcasting:scroll/minecraft/chests/village/village_cartographer", "hexcasting:lore/minecraft/chests/village/village_taiga_house", + "hexcasting:cypher/minecraft/chests/ancient_city", + "hexcasting:cypher/minecraft/chests/jungle_temple", "hexcasting:scroll/minecraft/chests/shipwreck_map", "hexcasting:lore/minecraft/chests/village/village_snowy_house", "hexcasting:scroll/minecraft/chests/abandoned_mineshaft", + "hexcasting:cypher/minecraft/chests/simple_dungeon", + "hexcasting:cypher/minecraft/chests/desert_pyramid", "hexcasting:amethyst_cluster", "hexcasting:lore/minecraft/chests/village/village_plains_house", "hexcasting:lore/minecraft/chests/stronghold_library", @@ -20,10 +24,13 @@ "hexcasting:scroll/minecraft/chests/desert_pyramid", "hexcasting:lore/minecraft/chests/abandoned_mineshaft", "hexcasting:lore/minecraft/chests/pillager_outpost", + "hexcasting:cypher/minecraft/chests/stronghold_corridor", "hexcasting:scroll/minecraft/chests/ancient_city", "hexcasting:scroll/minecraft/chests/stronghold_library", "hexcasting:lore/minecraft/chests/simple_dungeon", + "hexcasting:cypher/minecraft/chests/abandoned_mineshaft", "hexcasting:scroll/minecraft/chests/woodland_mansion", + "hexcasting:cypher/minecraft/chests/nether_bridge", "hexcasting:scroll/minecraft/chests/simple_dungeon" ], "replace": false diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/ForgeHexClientInitializer.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/ForgeHexClientInitializer.java index 30e0e2a53e..f159d4969a 100644 --- a/Neoforge/src/main/java/at/petrak/hexcasting/forge/ForgeHexClientInitializer.java +++ b/Neoforge/src/main/java/at/petrak/hexcasting/forge/ForgeHexClientInitializer.java @@ -1,5 +1,6 @@ package at.petrak.hexcasting.forge; +import at.petrak.hexcasting.api.client.ClientCastingStack; import at.petrak.hexcasting.client.ClientTickCounter; import at.petrak.hexcasting.client.RegisterClientStuff; import at.petrak.hexcasting.client.ShiftScrollListener; @@ -11,6 +12,7 @@ import at.petrak.hexcasting.common.casting.PatternRegistryManifest; import at.petrak.hexcasting.common.lib.HexParticles; import at.petrak.hexcasting.common.misc.PatternTooltip; +import at.petrak.hexcasting.forge.lib.ForgeHexAttachments; import at.petrak.hexcasting.interop.HexInterop; import net.minecraft.client.Minecraft; import net.minecraft.client.color.block.BlockColors; @@ -23,11 +25,11 @@ import net.minecraft.client.renderer.entity.LivingEntityRenderer; import net.minecraft.core.particles.ParticleOptions; import net.minecraft.core.particles.ParticleType; -import net.minecraftforge.client.event.*; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.TickEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent; +import net.neoforged.neoforge.client.event.*; +import net.neoforged.neoforge.common.NeoForge; +import net.neoforged.neoforge.event.tick.PlayerTickEvent; import java.io.IOException; import java.util.function.Function; @@ -48,40 +50,43 @@ public static void clientInit(FMLClientSetupEvent evt) { (colorizer, block) -> GLOBAL_BLOCK_COLORS.register(colorizer, block)); }); - var evBus = MinecraftForge.EVENT_BUS; + var evBus = NeoForge.EVENT_BUS; evBus.addListener((ClientPlayerNetworkEvent.LoggingIn e) -> PatternRegistryManifest.processRegistry(null)); + // TODO port: check if gametimedelta is the right one evBus.addListener((RenderLevelStageEvent e) -> { if (e.getStage().equals(RenderLevelStageEvent.Stage.AFTER_PARTICLES)) { - HexAdditionalRenderers.overlayLevel(e.getPoseStack(), e.getPartialTick()); + HexAdditionalRenderers.overlayLevel(e.getPoseStack(), e.getPartialTick().getGameTimeDeltaTicks()); } }); evBus.addListener((RenderGuiEvent.Post e) -> { - HexAdditionalRenderers.overlayGui(e.getGuiGraphics(), e.getPartialTick()); + HexAdditionalRenderers.overlayGui(e.getGuiGraphics(), e.getPartialTick().getGameTimeDeltaTicks()); }); - - evBus.addListener((TickEvent.RenderTickEvent e) -> { - if (e.phase == TickEvent.Phase.START) { - ClientTickCounter.renderTickStart(e.renderTickTime); - } + //TODO port: maybe replace with DeltaTracker from Mojang? + evBus.addListener((RenderFrameEvent.Pre e) -> { + ClientTickCounter.renderTickStart(e.getPartialTick().getGameTimeDeltaTicks()); }); - evBus.addListener((TickEvent.ClientTickEvent e) -> { - if (e.phase == TickEvent.Phase.END) { - ClientTickCounter.clientTickEnd(); - ShiftScrollListener.clientTickEnd(); - } + evBus.addListener((ClientTickEvent.Post e) -> { + ClientTickCounter.clientTickEnd(); + ShiftScrollListener.clientTickEnd(); }); evBus.addListener((InputEvent.MouseScrollingEvent e) -> { - var cancel = ShiftScrollListener.onScrollInGameplay(e.getScrollDelta()); + var cancel = ShiftScrollListener.onScrollInGameplay(e.getScrollDeltaY()); e.setCanceled(cancel); }); + evBus.addListener((PlayerTickEvent.Pre ev) -> { + if(!ev.getEntity().isDeadOrDying()) { + ev.getEntity().getData(ForgeHexAttachments.CLIENT_CASTING_STACK).tick(); + } + }); + HexInterop.clientInit(); } diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/ForgeHexConfig.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/ForgeHexConfig.java index bf219312fc..203f067aec 100644 --- a/Neoforge/src/main/java/at/petrak/hexcasting/forge/ForgeHexConfig.java +++ b/Neoforge/src/main/java/at/petrak/hexcasting/forge/ForgeHexConfig.java @@ -4,23 +4,23 @@ import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.Level; -import net.minecraftforge.common.ForgeConfigSpec; +import net.neoforged.neoforge.common.ModConfigSpec; import java.util.List; import static at.petrak.hexcasting.api.mod.HexConfig.noneMatch; public class ForgeHexConfig implements HexConfig.CommonConfigAccess { - private static ForgeConfigSpec.LongValue dustMediaAmount; - private static ForgeConfigSpec.LongValue shardMediaAmount; - private static ForgeConfigSpec.LongValue chargedCrystalMediaAmount; - private static ForgeConfigSpec.DoubleValue mediaToHealthRate; + private static ModConfigSpec.LongValue dustMediaAmount; + private static ModConfigSpec.LongValue shardMediaAmount; + private static ModConfigSpec.LongValue chargedCrystalMediaAmount; + private static ModConfigSpec.DoubleValue mediaToHealthRate; - private static ForgeConfigSpec.IntValue cypherCooldown; - private static ForgeConfigSpec.IntValue trinketCooldown; - private static ForgeConfigSpec.IntValue artifactCooldown; + private static ModConfigSpec.IntValue cypherCooldown; + private static ModConfigSpec.IntValue trinketCooldown; + private static ModConfigSpec.IntValue artifactCooldown; - public ForgeHexConfig(ForgeConfigSpec.Builder builder) { + public ForgeHexConfig(ModConfigSpec.Builder builder) { builder.push("Media Amounts"); dustMediaAmount = builder.comment("How much media a single Amethyst Dust item is worth") .defineInRange("dustMediaAmount", DEFAULT_DUST_MEDIA_AMOUNT, 0, Integer.MAX_VALUE); @@ -78,13 +78,13 @@ public int artifactCooldown() { } public static class Client implements HexConfig.ClientConfigAccess { - private static ForgeConfigSpec.BooleanValue ctrlTogglesOffStrokeOrder; - private static ForgeConfigSpec.BooleanValue invertSpellbookScrollDirection; - private static ForgeConfigSpec.BooleanValue invertAbacusScrollDirection; - private static ForgeConfigSpec.DoubleValue gridSnapThreshold; - private static ForgeConfigSpec.BooleanValue clickingTogglesDrawing; + private static ModConfigSpec.BooleanValue ctrlTogglesOffStrokeOrder; + private static ModConfigSpec.BooleanValue invertSpellbookScrollDirection; + private static ModConfigSpec.BooleanValue invertAbacusScrollDirection; + private static ModConfigSpec.DoubleValue gridSnapThreshold; + private static ModConfigSpec.BooleanValue clickingTogglesDrawing; - public Client(ForgeConfigSpec.Builder builder) { + public Client(ModConfigSpec.Builder builder) { ctrlTogglesOffStrokeOrder = builder.comment( "Whether the ctrl key will instead turn *off* the color gradient on patterns") .define("ctrlTogglesOffStrokeOrder", DEFAULT_CTRL_TOGGLES_OFF_STROKE_ORDER); @@ -131,26 +131,24 @@ public boolean clickingTogglesDrawing() { } public static class Server implements HexConfig.ServerConfigAccess { - private static ForgeConfigSpec.IntValue opBreakHarvestLevel; - private static ForgeConfigSpec.IntValue maxOpCount; + private static ModConfigSpec.IntValue opBreakHarvestLevel; + private static ModConfigSpec.IntValue maxOpCount; + private static ModConfigSpec.IntValue maxSpellCircleLength; + private static ModConfigSpec.ConfigValue> actionDenyList; + private static ModConfigSpec.ConfigValue> circleActionDenyList; - private static ForgeConfigSpec.IntValue maxSpellCircleLength; + private static ModConfigSpec.BooleanValue greaterTeleportSplatsItems; + private static ModConfigSpec.BooleanValue villagersOffendedByMindMurder; + private static ModConfigSpec.ConfigValue> tpDimDenyList; + private static ModConfigSpec.BooleanValue doesTrueNameHaveAmbit; + private static ModConfigSpec.DoubleValue traderScrollChance; - private static ForgeConfigSpec.ConfigValue> actionDenyList; - private static ForgeConfigSpec.ConfigValue> circleActionDenyList; + private static ModConfigSpec.ConfigValue> fewScrollTables; + private static ModConfigSpec.ConfigValue> someScrollTables; + private static ModConfigSpec.ConfigValue> manyScrollTables; - private static ForgeConfigSpec.BooleanValue villagersOffendedByMindMurder; - private static ForgeConfigSpec.ConfigValue> tpDimDenyList; - - private static ForgeConfigSpec.BooleanValue doesTrueNameHaveAmbit; - - private static ForgeConfigSpec.ConfigValue> fewScrollTables; - private static ForgeConfigSpec.ConfigValue> someScrollTables; - private static ForgeConfigSpec.ConfigValue> manyScrollTables; - - - public Server(ForgeConfigSpec.Builder builder) { + public Server(ModConfigSpec.Builder builder) { builder.push("Spells"); maxOpCount = builder.comment("The maximum number of actions that can be executed in one tick, to avoid " + "hanging the server.") @@ -171,10 +169,18 @@ public Server(ForgeConfigSpec.Builder builder) { .defineList("circleActionDenyList", List.of(), Server::isValidReslocArg); builder.pop(); + builder.push("Loot"); + traderScrollChance = builder.comment("The chance for wandering traders to sell an Ancient Scroll") + .defineInRange("traderScrollChance", DEFAULT_TRADER_SCROLL_CHANCE, 0.0, 1.0); + actionDenyList = builder.comment( "Resource locations of disallowed actions. Trying to cast one of these will result in a mishap.") .defineList("actionDenyList", List.of(), Server::isValidReslocArg); + greaterTeleportSplatsItems = builder.comment( + "Should items fly out of the player's inventory when using Greater Teleport?" + ).define("greaterTeleportSplatsItems", DEFAULT_GREATER_TELEPORT_SPLATS_ITEMS); + villagersOffendedByMindMurder = builder.comment( "Should villagers take offense when you flay the mind of their fellow villagers?") .define("villagersOffendedByMindMurder", true); @@ -212,6 +218,9 @@ public boolean isActionAllowedInCircles(ResourceLocation actionID) { return noneMatch(circleActionDenyList.get(), actionID); } + @Override + public boolean doesGreaterTeleportSplatItems() { return greaterTeleportSplatsItems.get(); } + @Override public boolean doVillagersTakeOffenseAtMindMurder() { return villagersOffendedByMindMurder.get(); @@ -227,8 +236,13 @@ public boolean trueNameHasAmbit() { return doesTrueNameHaveAmbit.get(); } + @Override + public double traderScrollChance() { + return traderScrollChance.get(); + } + private static boolean isValidReslocArg(Object o) { - return o instanceof String s && ResourceLocation.isValidResourceLocation(s); + return o instanceof String s && ResourceLocation.tryParse(s) != null; } } } diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/ForgeHexInitializer.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/ForgeHexInitializer.java index 16bc2a0549..53128fdf48 100644 --- a/Neoforge/src/main/java/at/petrak/hexcasting/forge/ForgeHexInitializer.java +++ b/Neoforge/src/main/java/at/petrak/hexcasting/forge/ForgeHexInitializer.java @@ -13,26 +13,23 @@ import at.petrak.hexcasting.common.items.ItemJewelerHammer; import at.petrak.hexcasting.common.lib.*; import at.petrak.hexcasting.common.lib.hex.*; -import at.petrak.hexcasting.common.misc.AkashicTreeGrower; -import at.petrak.hexcasting.common.misc.BrainsweepingEvents; -import at.petrak.hexcasting.common.misc.PlayerPositionRecorder; -import at.petrak.hexcasting.common.misc.RegisterMisc; +import at.petrak.hexcasting.common.misc.*; import at.petrak.hexcasting.common.recipe.HexRecipeStuffRegistry; +import at.petrak.hexcasting.common.recipe.ingredient.brainsweep.BrainsweepeeIngredients; +import at.petrak.hexcasting.common.recipe.ingredient.state.StateIngredients; import at.petrak.hexcasting.forge.cap.CapSyncers; import at.petrak.hexcasting.forge.cap.ForgeCapabilityHandler; -import at.petrak.hexcasting.forge.cap.adimpl.CapClientCastingStack; import at.petrak.hexcasting.forge.datagen.ForgeHexDataGenerators; import at.petrak.hexcasting.forge.interop.curios.CuriosApiInterop; import at.petrak.hexcasting.forge.interop.curios.CuriosRenderers; import at.petrak.hexcasting.forge.lib.ForgeHexArgumentTypeRegistry; +import at.petrak.hexcasting.forge.lib.ForgeHexAttachments; +import at.petrak.hexcasting.forge.lib.ForgeHexIngredientTypes; import at.petrak.hexcasting.forge.lib.ForgeHexLootMods; import at.petrak.hexcasting.forge.network.ForgePacketHandler; import at.petrak.hexcasting.forge.network.MsgBrainsweepAck; -import at.petrak.hexcasting.forge.recipe.ForgeModConditionalIngredient; -import at.petrak.hexcasting.forge.recipe.ForgeUnsealedIngredient; import at.petrak.hexcasting.interop.HexInterop; import at.petrak.hexcasting.xplat.IXplatAbstractions; -import net.minecraft.core.MappedRegistry; import net.minecraft.core.Registry; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.Registries; @@ -43,73 +40,70 @@ import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.Mob; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.BlockSetType; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.common.ForgeConfigSpec; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.common.ToolActions; -import net.minecraftforge.common.crafting.CraftingHelper; -import net.minecraftforge.event.BuildCreativeModeTabContentsEvent; -import net.minecraftforge.event.RegisterCommandsEvent; -import net.minecraftforge.event.TickEvent; -import net.minecraftforge.event.entity.EntityAttributeModificationEvent; -import net.minecraftforge.event.entity.living.LivingConversionEvent; -import net.minecraftforge.event.entity.living.LivingEvent; -import net.minecraftforge.event.entity.player.PlayerEvent; -import net.minecraftforge.event.entity.player.PlayerInteractEvent; -import net.minecraftforge.event.level.BlockEvent; -import net.minecraftforge.event.server.ServerStartedEvent; -import net.minecraftforge.eventbus.api.IEventBus; -import net.minecraftforge.fml.DistExecutor; -import net.minecraftforge.fml.ModList; -import net.minecraftforge.fml.ModLoadingContext; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.config.ModConfig; -import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; -import net.minecraftforge.network.PacketDistributor; -import net.minecraftforge.registries.RegisterEvent; -import thedarkcolour.kotlinforforge.KotlinModLoadingContext; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.fml.ModContainer; +import net.neoforged.fml.ModList; +import net.neoforged.fml.common.Mod; +import net.neoforged.fml.config.ModConfig; +import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent; +import net.neoforged.fml.loading.FMLEnvironment; +import net.neoforged.neoforge.common.ItemAbilities; +import net.neoforged.neoforge.common.ModConfigSpec; +import net.neoforged.neoforge.common.NeoForge; +import net.neoforged.neoforge.event.BuildCreativeModeTabContentsEvent; +import net.neoforged.neoforge.event.RegisterCommandsEvent; +import net.neoforged.neoforge.event.brewing.RegisterBrewingRecipesEvent; +import net.neoforged.neoforge.event.entity.EntityAttributeModificationEvent; +import net.neoforged.neoforge.event.entity.living.LivingConversionEvent; +import net.neoforged.neoforge.event.entity.player.PlayerEvent; +import net.neoforged.neoforge.event.entity.player.PlayerInteractEvent; +import net.neoforged.neoforge.event.level.BlockEvent; +import net.neoforged.neoforge.event.server.ServerStartedEvent; +import net.neoforged.neoforge.event.tick.EntityTickEvent; +import net.neoforged.neoforge.event.tick.LevelTickEvent; +import net.neoforged.neoforge.network.PacketDistributor; +import net.neoforged.neoforge.registries.NewRegistryEvent; +import net.neoforged.neoforge.registries.RegisterEvent; +import thedarkcolour.kotlinforforge.neoforge.KotlinModLoadingContext; import java.util.function.BiConsumer; import java.util.function.Consumer; @Mod(HexAPI.MOD_ID) public class ForgeHexInitializer { - public ForgeHexInitializer() { - initConfig(); + public ForgeHexInitializer(ModContainer modContainer) { + initConfig(modContainer); initRegistries(); initRegistry(); initListeners(); } - private static void initConfig() { - var config = new ForgeConfigSpec.Builder().configure(ForgeHexConfig::new); - var clientConfig = new ForgeConfigSpec.Builder().configure(ForgeHexConfig.Client::new); - var serverConfig = new ForgeConfigSpec.Builder().configure(ForgeHexConfig.Server::new); + private static void initConfig(ModContainer modContainer) { + var config = new ModConfigSpec.Builder().configure(ForgeHexConfig::new); + var clientConfig = new ModConfigSpec.Builder().configure(ForgeHexConfig.Client::new); + var serverConfig = new ModConfigSpec.Builder().configure(ForgeHexConfig.Server::new); HexConfig.setCommon(config.getLeft()); HexConfig.setClient(clientConfig.getLeft()); HexConfig.setServer(serverConfig.getLeft()); - var mlc = ModLoadingContext.get(); - mlc.registerConfig(ModConfig.Type.COMMON, config.getRight()); - mlc.registerConfig(ModConfig.Type.CLIENT, clientConfig.getRight()); - mlc.registerConfig(ModConfig.Type.SERVER, serverConfig.getRight()); + modContainer.registerConfig(ModConfig.Type.COMMON, config.getRight()); + modContainer.registerConfig(ModConfig.Type.CLIENT, clientConfig.getRight()); + modContainer.registerConfig(ModConfig.Type.SERVER, serverConfig.getRight()); } public static void initRegistries() { - if (!(BuiltInRegistries.REGISTRY instanceof MappedRegistry rootRegistry)) return; - rootRegistry.unfreeze(); - - IXplatAbstractions.INSTANCE.getActionRegistry(); - IXplatAbstractions.INSTANCE.getSpecialHandlerRegistry(); - IXplatAbstractions.INSTANCE.getIotaTypeRegistry(); - IXplatAbstractions.INSTANCE.getArithmeticRegistry(); - IXplatAbstractions.INSTANCE.getContinuationTypeRegistry(); - IXplatAbstractions.INSTANCE.getEvalSoundRegistry(); - - rootRegistry.freeze(); + getModEventBus().addListener(NewRegistryEvent.class, ev -> { + ev.register(IXplatAbstractions.INSTANCE.getActionRegistry()); + ev.register(IXplatAbstractions.INSTANCE.getSpecialHandlerRegistry()); + ev.register(IXplatAbstractions.INSTANCE.getIotaTypeRegistry()); + ev.register(IXplatAbstractions.INSTANCE.getArithmeticRegistry()); + ev.register(IXplatAbstractions.INSTANCE.getContinuationTypeRegistry()); + ev.register(IXplatAbstractions.INSTANCE.getEvalSoundRegistry()); + ev.register(IXplatAbstractions.INSTANCE.getStateIngredientRegistry()); + ev.register(IXplatAbstractions.INSTANCE.getBrainsweepeeIngredientRegistry()); + }); } private static void initRegistry() { @@ -123,51 +117,59 @@ private static void initRegistry() { bind(Registries.ITEM, HexBlocks::registerBlockItems); bind(Registries.BLOCK_ENTITY_TYPE, HexBlockEntities::registerTiles); bind(Registries.ITEM, HexItems::registerItems); + bind(Registries.DATA_COMPONENT_TYPE, HexDataComponents::registerDataComponents); bind(Registries.RECIPE_SERIALIZER, HexRecipeStuffRegistry::registerSerializers); bind(Registries.RECIPE_TYPE, HexRecipeStuffRegistry::registerTypes); bind(Registries.ENTITY_TYPE, HexEntities::registerEntities); - bind(Registries.ATTRIBUTE, HexAttributes::register); + // Testing out new registration system + HexAttributes.register(); bind(Registries.MOB_EFFECT, HexMobEffects::register); - bind(Registries.POTION, HexPotions::register); - + bind(Registries.POTION, HexPotions::registerPotions); bind(Registries.PARTICLE_TYPE, HexParticles::registerParticles); + bind(Registries.TRIGGER_TYPE, HexAdvancementTriggers::registerTriggers); + bind(HexRegistries.IOTA_TYPE, HexIotaTypes::registerTypes); bind(HexRegistries.ACTION, HexActions::register); bind(HexRegistries.SPECIAL_HANDLER, HexSpecialHandlers::register); bind(HexRegistries.ARITHMETIC, HexArithmetics::register); bind(HexRegistries.CONTINUATION_TYPE, HexContinuationTypes::registerContinuations); bind(HexRegistries.EVAL_SOUND, HexEvalSounds::register); + bind(HexRegistries.STATE_INGREDIENT, StateIngredients::register); + bind(HexRegistries.BRAINSWEEPEE_INGREDIENT, BrainsweepeeIngredients::register); ForgeHexArgumentTypeRegistry.ARGUMENT_TYPES.register(getModEventBus()); ForgeHexLootMods.REGISTRY.register(getModEventBus()); - - HexAdvancementTriggers.registerTriggers(); + ForgeHexIngredientTypes.INGREDIENT_TYPES.register(getModEventBus()); + ForgeHexAttachments.register(); RegisterMisc.register(); } // https://github.com/VazkiiMods/Botania/blob/1.18.x/Forge/src/main/java/vazkii/botania/forge/ForgeCommonInitializer.java - private static void bind(ResourceKey> registry, - Consumer> source) { + private static void bind(ResourceKey> registry, Consumer> source) { getModEventBus().addListener((RegisterEvent event) -> { if (registry.equals(event.getRegistryKey())) { - source.accept((t, rl) -> event.register(registry, rl, () -> t)); + source.accept((t, rl) -> { + event.register(registry, rl, () -> t); + }); } }); } private static void initListeners() { var modBus = getModEventBus(); - var evBus = MinecraftForge.EVENT_BUS; + var evBus = NeoForge.EVENT_BUS; + + if(FMLEnvironment.dist == Dist.CLIENT) + modBus.register(ForgeHexClientInitializer.class); - DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> modBus.register(ForgeHexClientInitializer.class)); + ForgePacketHandler.init(modBus); modBus.addListener((FMLCommonSetupEvent evt) -> evt.enqueueWork(() -> { - ForgePacketHandler.init(); HexComposting.setup(); HexStrippables.init(); // Forge does not strictly require TreeGrowers to initialize during early game stages, unlike Fabric @@ -190,17 +192,12 @@ private static void initListeners() { // We have to do these at some point when the registries are still open modBus.addListener((RegisterEvent evt) -> { if (evt.getRegistryKey().equals(Registries.ITEM)) { - CraftingHelper.register(ForgeUnsealedIngredient.ID, ForgeUnsealedIngredient.Serializer.INSTANCE); - CraftingHelper.register(ForgeModConditionalIngredient.ID, - ForgeModConditionalIngredient.Serializer.INSTANCE); HexStatistics.register(); HexLootFunctions.registerSerializers((lift, id) -> Registry.register(BuiltInRegistries.LOOT_FUNCTION_TYPE, id, lift)); } }); - evBus.register(CapClientCastingStack.class); - evBus.addListener((PlayerInteractEvent.EntityInteract evt) -> { var res = BrainsweepingEvents.interactWithBrainswept( evt.getEntity(), evt.getLevel(), evt.getHand(), evt.getTarget(), null); @@ -212,15 +209,15 @@ private static void initListeners() { evBus.addListener((LivingConversionEvent.Post evt) -> BrainsweepingEvents.copyBrainsweepPostTransformation(evt.getEntity(), evt.getOutcome())); - evBus.addListener((LivingEvent.LivingTickEvent evt) -> { + evBus.addListener((EntityTickEvent.Post evt) -> { if (evt.getEntity() instanceof ServerPlayer splayer) { OpFlight.tickDownFlight(splayer); OpAltiora.checkPlayerCollision(splayer); } }); - evBus.addListener((TickEvent.LevelTickEvent evt) -> { - if (evt.phase == TickEvent.Phase.END && evt.level instanceof ServerLevel world) { + evBus.addListener((LevelTickEvent.Post evt) -> { + if (evt.getLevel() instanceof ServerLevel world) { PlayerPositionRecorder.updateAllPlayers(world); } }); @@ -248,14 +245,13 @@ private static void initListeners() { Entity target = evt.getTarget(); if (evt.getTarget() instanceof ServerPlayer serverPlayer && target instanceof Mob mob && IXplatAbstractions.INSTANCE.isBrainswept(mob)) { - ForgePacketHandler.getNetwork() - .send(PacketDistributor.PLAYER.with(() -> serverPlayer), MsgBrainsweepAck.of(mob)); + PacketDistributor.sendToPlayer(serverPlayer, MsgBrainsweepAck.of(mob)); } }); // Implemented with a mixin on Farbc evBus.addListener((BlockEvent.BlockToolModificationEvent evt) -> { - if (!evt.isSimulated() && evt.getToolAction() == ToolActions.AXE_STRIP) { + if (!evt.isSimulated() && evt.getItemAbility() == ItemAbilities.AXE_STRIP) { BlockState bs = evt.getState(); var output = HexStrippables.STRIPPABLES.get(bs.getBlock()); if (output != null) { @@ -264,31 +260,34 @@ private static void initListeners() { } }); + evBus.addListener(RegisterBrewingRecipesEvent.class, ev -> { + HexPotions.addRecipes(ev.getBuilder(), ev.getRegistryAccess()); + }); + // Caps are cardinal components on farbc modBus.addListener(ForgeCapabilityHandler::registerCaps); - evBus.addGenericListener(ItemStack.class, ForgeCapabilityHandler::attachItemCaps); - evBus.addGenericListener(BlockEntity.class, ForgeCapabilityHandler::attachBlockEntityCaps); - evBus.addGenericListener(Entity.class, ForgeCapabilityHandler::attachEntityCaps); modBus.register(ForgeHexDataGenerators.class); - modBus.register(ForgeCapabilityHandler.class); evBus.register(CapSyncers.class); modBus.addListener((EntityAttributeModificationEvent e) -> { e.add(EntityType.PLAYER, HexAttributes.GRID_ZOOM); e.add(EntityType.PLAYER, HexAttributes.SCRY_SIGHT); + e.add(EntityType.PLAYER, HexAttributes.FEEBLE_MIND); + e.add(EntityType.PLAYER, HexAttributes.MEDIA_CONSUMPTION_MODIFIER); + e.add(EntityType.PLAYER, HexAttributes.AMBIT_RADIUS); + e.add(EntityType.PLAYER, HexAttributes.SENTINEL_RADIUS); }); if (ModList.get().isLoaded(HexInterop.Forge.CURIOS_API_ID)) { - modBus.addListener(CuriosApiInterop::onInterModEnqueue); modBus.addListener(CuriosApiInterop::onClientSetup); - DistExecutor.unsafeRunWhenOn(Dist.CLIENT, - () -> () -> modBus.addListener(CuriosRenderers::onLayerRegister)); + if(FMLEnvironment.dist == Dist.CLIENT) + modBus.addListener(CuriosRenderers::onLayerRegister); } } // aaaauughhg - private static IEventBus getModEventBus() { + public static IEventBus getModEventBus() { return KotlinModLoadingContext.Companion.get().getKEventBus(); } } diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/cap/CapSyncers.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/cap/CapSyncers.java index 89e26d4474..a5a3952072 100644 --- a/Neoforge/src/main/java/at/petrak/hexcasting/forge/cap/CapSyncers.java +++ b/Neoforge/src/main/java/at/petrak/hexcasting/forge/cap/CapSyncers.java @@ -6,8 +6,8 @@ import at.petrak.hexcasting.xplat.IXplatAbstractions; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.InteractionHand; -import net.minecraftforge.event.entity.player.PlayerEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.neoforge.event.entity.player.PlayerEvent; public class CapSyncers { @SubscribeEvent diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/cap/ForgeCapabilityHandler.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/cap/ForgeCapabilityHandler.java index 502357ab3a..fe9bdc42ff 100644 --- a/Neoforge/src/main/java/at/petrak/hexcasting/forge/cap/ForgeCapabilityHandler.java +++ b/Neoforge/src/main/java/at/petrak/hexcasting/forge/cap/ForgeCapabilityHandler.java @@ -1,13 +1,14 @@ package at.petrak.hexcasting.forge.cap; -import at.petrak.hexcasting.api.addldata.*; -import at.petrak.hexcasting.api.casting.circles.BlockEntityAbstractImpetus; +import at.petrak.hexcasting.api.addldata.ADMediaHolder; +import at.petrak.hexcasting.api.addldata.ItemDelegatingEntityIotaHolder; +import at.petrak.hexcasting.api.block.circle.BlockAbstractImpetus; import at.petrak.hexcasting.api.casting.iota.DoubleIota; import at.petrak.hexcasting.api.client.ClientCastingStack; import at.petrak.hexcasting.api.item.*; import at.petrak.hexcasting.api.misc.MediaConstants; import at.petrak.hexcasting.api.mod.HexConfig; -import at.petrak.hexcasting.common.entities.EntityWallScroll; +import at.petrak.hexcasting.common.entities.HexEntities; import at.petrak.hexcasting.common.items.HexBaubleItem; import at.petrak.hexcasting.common.lib.HexBlocks; import at.petrak.hexcasting.common.lib.HexItems; @@ -15,202 +16,93 @@ import at.petrak.hexcasting.forge.interop.curios.CuriosApiInterop; import at.petrak.hexcasting.interop.HexInterop; import at.petrak.hexcasting.xplat.IXplatAbstractions; -import net.minecraft.core.Direction; +import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.decoration.ItemFrame; -import net.minecraft.world.entity.item.ItemEntity; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.item.Item; import net.minecraft.world.item.Items; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraftforge.common.capabilities.Capability; -import net.minecraftforge.common.capabilities.ForgeCapabilities; -import net.minecraftforge.common.capabilities.ICapabilityProvider; -import net.minecraftforge.common.capabilities.RegisterCapabilitiesEvent; -import net.minecraftforge.common.util.LazyOptional; -import net.minecraftforge.common.util.NonNullSupplier; -import net.minecraftforge.event.AttachCapabilitiesEvent; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.function.BooleanSupplier; -import java.util.function.Function; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.neoforged.neoforge.capabilities.Capabilities; +import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent; import static at.petrak.hexcasting.api.HexAPI.modLoc; public class ForgeCapabilityHandler { - /** - * Items that store an iota to their tag. - */ - public static final ResourceLocation IOTA_STORAGE_CAP = modLoc("iota_holder"); - /** - * Items that intrinsically store an iota. - */ - public static final ResourceLocation IOTA_STATIC_CAP = modLoc("iota_item"); - /** - * Items that store a variable amount of media to their tag. - */ - public static final ResourceLocation MEDIA_STORAGE_CAP = modLoc("media_holder"); - /** - * Items that statically provide media. - */ - public static final ResourceLocation MEDIA_STATIC_CAP = modLoc("media_item"); - /** - * Items that store a packaged Hex. - */ - public static final ResourceLocation HEX_HOLDER_CAP = modLoc("hex_item"); - /** - * Items that have multiple visual variants. - */ - public static final ResourceLocation VARIANT_ITEM_CAP = modLoc("variant_item"); - /** - * Items that work as pigments. - */ - public static final ResourceLocation PIGMENT_CAP = modLoc("pigment"); - public static final ResourceLocation CURIO_CAP = modLoc("curio"); - - public static final ResourceLocation IMPETUS_HANDLER = modLoc("impetus_items"); - - /** - * Used to render the pattern spiral around players while casting. - */ - public static final ResourceLocation PATTERN_SPIRAL = modLoc("pattern_spiral"); public static void registerCaps(RegisterCapabilitiesEvent evt) { - evt.register(ADMediaHolder.class); - evt.register(ADIotaHolder.class); - evt.register(ADHexHolder.class); - evt.register(ADPigment.class); - } - - public static void attachItemCaps(AttachCapabilitiesEvent evt) { - ItemStack stack = evt.getObject(); - - if (stack.getItem() instanceof MediaHolderItem holder) { - evt.addCapability(MEDIA_STORAGE_CAP, - provide(stack, HexCapabilities.MEDIA, () -> new CapItemMediaHolder(holder, stack))); - } else if (stack.is(HexItems.AMETHYST_DUST)) { - evt.addCapability(MEDIA_STATIC_CAP, provide(stack, HexCapabilities.MEDIA, () -> - new CapStaticMediaHolder(HexConfig.common()::dustMediaAmount, ADMediaHolder.AMETHYST_DUST_PRIORITY, - stack))); - } else if (stack.is(Items.AMETHYST_SHARD)) { - evt.addCapability(MEDIA_STATIC_CAP, provide(stack, HexCapabilities.MEDIA, () -> new CapStaticMediaHolder( - HexConfig.common()::shardMediaAmount, ADMediaHolder.AMETHYST_SHARD_PRIORITY, stack))); - } else if (stack.is(HexItems.CHARGED_AMETHYST)) { - evt.addCapability(MEDIA_STATIC_CAP, - provide(stack, HexCapabilities.MEDIA, () -> new CapStaticMediaHolder( - HexConfig.common()::chargedCrystalMediaAmount, ADMediaHolder.CHARGED_AMETHYST_PRIORITY, stack))); - } else if (stack.is(HexItems.QUENCHED_SHARD)) { - // no one uses the config - evt.addCapability(MEDIA_STATIC_CAP, - provide(stack, HexCapabilities.MEDIA, () -> new CapStaticMediaHolder( - () -> MediaConstants.QUENCHED_SHARD_UNIT, ADMediaHolder.QUENCHED_SHARD_PRIORITY, stack))); - } else if (stack.is(HexBlocks.QUENCHED_ALLAY.asItem())) { - // no one uses the config - evt.addCapability(MEDIA_STATIC_CAP, - provide(stack, HexCapabilities.MEDIA, () -> new CapStaticMediaHolder( - () -> MediaConstants.QUENCHED_BLOCK_UNIT, ADMediaHolder.QUENCHED_ALLAY_PRIORITY, stack))); - } - - if (stack.getItem() instanceof IotaHolderItem holder) { - evt.addCapability(IOTA_STORAGE_CAP, - provide(stack, HexCapabilities.IOTA, () -> new CapItemIotaHolder(holder, stack))); - } else if (stack.is(Items.PUMPKIN_PIE)) { - // haha yes - evt.addCapability(IOTA_STATIC_CAP, provide(stack, HexCapabilities.IOTA, () -> - new CapStaticIotaHolder((s) -> new DoubleIota(Math.PI * s.getCount()), stack))); - } - - if (stack.getItem() instanceof HexHolderItem holder) { - evt.addCapability(HEX_HOLDER_CAP, - provide(stack, HexCapabilities.STORED_HEX, () -> new CapItemHexHolder(holder, stack))); + for(Item item : BuiltInRegistries.ITEM) { + if(item instanceof MediaHolderItem holder) + evt.registerItem(HexCapabilities.Item.MEDIA, (stack, ctx) -> new CapItemMediaHolder(holder, stack), item); + if(item instanceof IotaHolderItem holder) + evt.registerItem(HexCapabilities.Item.IOTA, (stack, ctx) -> new CapItemIotaHolder(holder, stack), item); + if(item instanceof HexHolderItem holder) + evt.registerItem(HexCapabilities.Item.STORED_HEX, (stack, ctx) -> new CapItemHexHolder(holder, stack), item); + if(item instanceof VariantItem holder) + evt.registerItem(HexCapabilities.Item.VARIANT_ITEM, (stack, ctx) -> new CapItemVariantItem(holder, stack), item); + if(item instanceof PigmentItem holder) + evt.registerItem(HexCapabilities.Item.COLOR, (stack, ctx) -> new CapItemPigment(holder, stack), item); + if(item instanceof HexBaubleItem && IXplatAbstractions.INSTANCE.isModPresent(HexInterop.Forge.CURIOS_API_ID)) + CuriosApiInterop.registerCap(evt, item); } - if (stack.getItem() instanceof VariantItem variantItem) { - evt.addCapability(VARIANT_ITEM_CAP, - provide(stack, HexCapabilities.VARIANT_ITEM, () -> new CapItemVariantItem(variantItem, stack))); - } - - if (stack.getItem() instanceof PigmentItem pigment) { - evt.addCapability(PIGMENT_CAP, - provide(stack, HexCapabilities.COLOR, () -> new CapItemPigment(pigment, stack))); - } - - if (IXplatAbstractions.INSTANCE.isModPresent(HexInterop.Forge.CURIOS_API_ID) - && stack.getItem() instanceof HexBaubleItem) { - evt.addCapability(CURIO_CAP, CuriosApiInterop.curioCap(stack)); - } - } - - public static void attachEntityCaps(AttachCapabilitiesEvent evt) { - var entity = evt.getObject(); - if (entity instanceof ItemEntity item) { - evt.addCapability(IOTA_STORAGE_CAP, wrapItemEntityDelegate(item, - ItemDelegatingEntityIotaHolder.ToItemEntity::new)); - } else if (entity instanceof ItemFrame frame) { - evt.addCapability(IOTA_STORAGE_CAP, wrapItemEntityDelegate(frame, - ItemDelegatingEntityIotaHolder.ToItemFrame::new)); - } else if (entity instanceof EntityWallScroll scroll) { - evt.addCapability(IOTA_STORAGE_CAP, wrapItemEntityDelegate(scroll, - ItemDelegatingEntityIotaHolder.ToWallScroll::new)); - } else if (entity instanceof Player player) { - evt.addCapability(PATTERN_SPIRAL, provide(player, HexCapabilities.CLIENT_CASTING_STACK, - () -> new CapClientCastingStack(player, new ClientCastingStack()))); - } - } - public static void attachBlockEntityCaps(AttachCapabilitiesEvent evt) { - if (evt.getObject() instanceof BlockEntityAbstractImpetus impetus) { - evt.addCapability(IMPETUS_HANDLER, provide(impetus, ForgeCapabilities.ITEM_HANDLER, - () -> new ForgeImpetusCapability(impetus))); - } - } - - // i do not know why we need super here - private static SimpleProvider wrapItemEntityDelegate(E entity, - Function make) { - return provide(entity, HexCapabilities.IOTA, - () -> new CapEntityIotaHolder.Wrapper(make.apply(entity))); - } - - private static SimpleProvider provide(Entity entity, Capability capability, - NonNullSupplier supplier) { - return provide(entity::isRemoved, capability, supplier); - } - - private static SimpleProvider provide(BlockEntity be, Capability capability, - NonNullSupplier supplier) { - return provide(be::isRemoved, capability, supplier); - } - - public static SimpleProvider provide(ItemStack stack, Capability capability, - NonNullSupplier supplier) { - return provide(stack::isEmpty, capability, supplier); - } - - private static SimpleProvider provide(BooleanSupplier invalidated, Capability capability, - NonNullSupplier supplier) { - return new SimpleProvider<>(invalidated, capability, LazyOptional.of(supplier)); - } - - public static ICapabilityProvider makeProvider(Capability cap, U instance) { - LazyOptional lazyInstanceButNotReally = LazyOptional.of(() -> instance); - return new SimpleProvider<>(() -> false, cap, lazyInstanceButNotReally); - } - - public record SimpleProvider(BooleanSupplier invalidated, - Capability capability, - LazyOptional instance) implements ICapabilityProvider { - - @NotNull - @Override - public LazyOptional getCapability(@NotNull Capability cap, @Nullable Direction side) { - if (invalidated.getAsBoolean()) { - return LazyOptional.empty(); + evt.registerItem( + HexCapabilities.Item.MEDIA, + (stack, ctx) -> new CapStaticMediaHolder(HexConfig.common()::dustMediaAmount, ADMediaHolder.AMETHYST_DUST_PRIORITY, stack), + HexItems.AMETHYST_DUST + ); + evt.registerItem( + HexCapabilities.Item.MEDIA, + (stack, ctx) -> new CapStaticMediaHolder(HexConfig.common()::shardMediaAmount, ADMediaHolder.AMETHYST_SHARD_PRIORITY, stack), + Items.AMETHYST_SHARD + ); + evt.registerItem( + HexCapabilities.Item.MEDIA, + (stack, ctx) -> new CapStaticMediaHolder(HexConfig.common()::chargedCrystalMediaAmount, ADMediaHolder.CHARGED_AMETHYST_PRIORITY, stack), + HexItems.CHARGED_AMETHYST + ); + evt.registerItem( + HexCapabilities.Item.MEDIA, + (stack, ctx) -> new CapStaticMediaHolder(() -> MediaConstants.QUENCHED_SHARD_UNIT, ADMediaHolder.QUENCHED_SHARD_PRIORITY, stack), + HexItems.QUENCHED_SHARD + ); + evt.registerItem( + HexCapabilities.Item.MEDIA, + (stack, ctx) -> new CapStaticMediaHolder(() -> MediaConstants.QUENCHED_BLOCK_UNIT, ADMediaHolder.QUENCHED_ALLAY_PRIORITY, stack), + HexBlocks.QUENCHED_ALLAY.asItem() + ); + + // haha yes + evt.registerItem( + HexCapabilities.Item.IOTA, + (stack, ctx) -> new CapStaticIotaHolder((s) -> new DoubleIota(Math.PI * s.getCount()), stack), + Items.PUMPKIN_PIE + ); + + evt.registerEntity( + HexCapabilities.Entity.IOTA, + EntityType.ITEM, + (ent, ctx) -> new ItemDelegatingEntityIotaHolder.ToItemEntity(ent) + ); + evt.registerEntity( + HexCapabilities.Entity.IOTA, + EntityType.ITEM_FRAME, + (ent, ctx) -> new ItemDelegatingEntityIotaHolder.ToItemFrame(ent) + ); + evt.registerEntity( + HexCapabilities.Entity.IOTA, + HexEntities.WALL_SCROLL, + (ent, ctx) -> new ItemDelegatingEntityIotaHolder.ToWallScroll(ent) + ); + + for(Block block : BuiltInRegistries.BLOCK) { + if(block instanceof BlockAbstractImpetus imBlock) { + evt.registerBlockEntity( + Capabilities.ItemHandler.BLOCK, + imBlock.getBlockEntityType(), + (be, dir) -> new ForgeImpetusCapability(be) + ); } - - return cap == capability ? instance.cast() : LazyOptional.empty(); } } - } diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/cap/ForgeImpetusCapability.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/cap/ForgeImpetusCapability.java index 9da53fa9a5..45d22e2eb8 100644 --- a/Neoforge/src/main/java/at/petrak/hexcasting/forge/cap/ForgeImpetusCapability.java +++ b/Neoforge/src/main/java/at/petrak/hexcasting/forge/cap/ForgeImpetusCapability.java @@ -2,7 +2,7 @@ import at.petrak.hexcasting.api.casting.circles.BlockEntityAbstractImpetus; import net.minecraft.world.item.ItemStack; -import net.minecraftforge.items.IItemHandler; +import net.neoforged.neoforge.items.IItemHandler; import org.jetbrains.annotations.NotNull; public record ForgeImpetusCapability(BlockEntityAbstractImpetus impetus) implements IItemHandler { diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/cap/HexCapabilities.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/cap/HexCapabilities.java index 9db3e48d0a..7856cabc5c 100644 --- a/Neoforge/src/main/java/at/petrak/hexcasting/forge/cap/HexCapabilities.java +++ b/Neoforge/src/main/java/at/petrak/hexcasting/forge/cap/HexCapabilities.java @@ -1,25 +1,26 @@ package at.petrak.hexcasting.forge.cap; import at.petrak.hexcasting.api.addldata.*; -import at.petrak.hexcasting.api.client.ClientCastingStack; -import net.minecraftforge.common.capabilities.Capability; -import net.minecraftforge.common.capabilities.CapabilityManager; -import net.minecraftforge.common.capabilities.CapabilityToken; +import net.neoforged.neoforge.capabilities.EntityCapability; +import net.neoforged.neoforge.capabilities.ItemCapability; -import java.util.function.Supplier; +import static at.petrak.hexcasting.api.HexAPI.modLoc; public final class HexCapabilities { - public static final Capability MEDIA = CapabilityManager.get(new CapabilityToken<>() { - }); - public static final Capability IOTA = CapabilityManager.get(new CapabilityToken<>() { - }); - public static final Capability STORED_HEX = CapabilityManager.get(new CapabilityToken<>() { - }); - public static final Capability VARIANT_ITEM = CapabilityManager.get(new CapabilityToken<>() { - }); - public static final Capability COLOR = CapabilityManager.get(new CapabilityToken<>() { - }); - public static final Capability> CLIENT_CASTING_STACK = CapabilityManager.get(new CapabilityToken<>() { - }); + public static final class Item { + public static final ItemCapability MEDIA = ItemCapability.createVoid(modLoc("media_holder"), ADMediaHolder.class); + public static final ItemCapability IOTA = ItemCapability.createVoid(modLoc("iota_holder"), ADIotaHolder.class); + public static final ItemCapability STORED_HEX = ItemCapability.createVoid(modLoc("hex_holder"), ADHexHolder.class); + public static final ItemCapability VARIANT_ITEM = ItemCapability.createVoid(modLoc("variant"), ADVariantItem.class); + public static final ItemCapability COLOR = ItemCapability.createVoid(modLoc("color"), ADPigment.class); + } + + public static final class Entity { + public static final EntityCapability MEDIA = EntityCapability.createVoid(modLoc("media_holder"), ADMediaHolder.class); + public static final EntityCapability IOTA = EntityCapability.createVoid(modLoc("iota_holder"), ADIotaHolder.class); + public static final EntityCapability STORED_HEX = EntityCapability.createVoid(modLoc("hex_holder"), ADHexHolder.class); + public static final EntityCapability VARIANT_ITEM = EntityCapability.createVoid(modLoc("variant"), ADVariantItem.class); + public static final EntityCapability COLOR = EntityCapability.createVoid(modLoc("color"), ADPigment.class); + } } diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/cap/adimpl/CapClientCastingStack.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/cap/adimpl/CapClientCastingStack.java deleted file mode 100644 index bdba8678ca..0000000000 --- a/Neoforge/src/main/java/at/petrak/hexcasting/forge/cap/adimpl/CapClientCastingStack.java +++ /dev/null @@ -1,24 +0,0 @@ -package at.petrak.hexcasting.forge.cap.adimpl; - -import at.petrak.hexcasting.api.client.ClientCastingStack; -import at.petrak.hexcasting.forge.cap.HexCapabilities; -import net.minecraft.world.entity.player.Player; -import net.minecraftforge.event.TickEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.LogicalSide; - -import java.util.function.Supplier; - -public record CapClientCastingStack(Player player, ClientCastingStack clientCastingStack) implements Supplier { - @Override - public ClientCastingStack get() { - return clientCastingStack; - } - - @SubscribeEvent - public static void tickClientPlayer(TickEvent.PlayerTickEvent evt) { - if (evt.side == LogicalSide.CLIENT && !evt.player.isDeadOrDying()) - evt.player.getCapability(HexCapabilities.CLIENT_CASTING_STACK).resolve() - .ifPresent(CastingStack -> CastingStack.get().tick()); - } -} diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/cap/adimpl/CapEntityIotaHolder.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/cap/adimpl/CapEntityIotaHolder.java index a8623e6249..a8e0e77ba8 100644 --- a/Neoforge/src/main/java/at/petrak/hexcasting/forge/cap/adimpl/CapEntityIotaHolder.java +++ b/Neoforge/src/main/java/at/petrak/hexcasting/forge/cap/adimpl/CapEntityIotaHolder.java @@ -15,12 +15,6 @@ public Wrapper(ItemDelegatingEntityIotaHolder inner) { this.inner = inner; } - - @Override - public @Nullable CompoundTag readIotaTag() { - return inner.readIotaTag(); - } - @Override public boolean writeable() { return inner.writeable(); @@ -32,8 +26,8 @@ public boolean writeIota(@Nullable Iota iota, boolean simulate) { } @Override - public @Nullable Iota readIota(ServerLevel world) { - return inner.readIota(world); + public @Nullable Iota readIota() { + return inner.readIota(); } @Override diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/cap/adimpl/CapItemIotaHolder.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/cap/adimpl/CapItemIotaHolder.java index 29caaeb0d0..603742bf3c 100644 --- a/Neoforge/src/main/java/at/petrak/hexcasting/forge/cap/adimpl/CapItemIotaHolder.java +++ b/Neoforge/src/main/java/at/petrak/hexcasting/forge/cap/adimpl/CapItemIotaHolder.java @@ -8,19 +8,12 @@ import net.minecraft.world.item.ItemStack; import org.jetbrains.annotations.Nullable; -public record CapItemIotaHolder(IotaHolderItem holder, - ItemStack stack) implements ADIotaHolder { +public record CapItemIotaHolder(IotaHolderItem holder, ItemStack stack) implements ADIotaHolder { @Override public @Nullable - CompoundTag readIotaTag() { - return holder.readIotaTag(stack); - } - - @Override - public @Nullable - Iota readIota(ServerLevel world) { - return holder.readIota(stack, world); + Iota readIota() { + return holder.readIota(stack); } @Override diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/cap/adimpl/CapStaticIotaHolder.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/cap/adimpl/CapStaticIotaHolder.java index f94cd93455..c0e5f947c8 100644 --- a/Neoforge/src/main/java/at/petrak/hexcasting/forge/cap/adimpl/CapStaticIotaHolder.java +++ b/Neoforge/src/main/java/at/petrak/hexcasting/forge/cap/adimpl/CapStaticIotaHolder.java @@ -15,14 +15,7 @@ public record CapStaticIotaHolder(Function provider, @Override public @Nullable - CompoundTag readIotaTag() { - var iota = provider.apply(stack); - return iota == null ? null : IotaType.serialize(iota); - } - - @Override - public @Nullable - Iota readIota(ServerLevel world) { + Iota readIota() { return provider.apply(stack); } diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/datagen/ForgeHexConditionsBuilder.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/datagen/ForgeHexConditionsBuilder.java index 93b1cfe529..ac7cac67af 100644 --- a/Neoforge/src/main/java/at/petrak/hexcasting/forge/datagen/ForgeHexConditionsBuilder.java +++ b/Neoforge/src/main/java/at/petrak/hexcasting/forge/datagen/ForgeHexConditionsBuilder.java @@ -1,20 +1,18 @@ package at.petrak.hexcasting.forge.datagen; import at.petrak.hexcasting.datagen.IXplatConditionsBuilder; -import net.minecraft.advancements.CriterionTriggerInstance; -import net.minecraft.data.recipes.FinishedRecipe; +import net.minecraft.advancements.Criterion; import net.minecraft.data.recipes.RecipeBuilder; +import net.minecraft.data.recipes.RecipeOutput; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.Item; -import net.minecraftforge.common.crafting.ConditionalRecipe; -import net.minecraftforge.common.crafting.conditions.ICondition; -import net.minecraftforge.common.crafting.conditions.IConditionBuilder; +import net.neoforged.neoforge.common.conditions.ICondition; +import net.neoforged.neoforge.common.conditions.IConditionBuilder; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; -import java.util.function.Consumer; public class ForgeHexConditionsBuilder implements IXplatConditionsBuilder, IConditionBuilder { private final List conditions = new ArrayList<>(); @@ -38,8 +36,8 @@ public IXplatConditionsBuilder whenModMissing(String modid) { @Override public @NotNull RecipeBuilder unlockedBy(@NotNull String string, - @NotNull CriterionTriggerInstance criterionTriggerInstance) { - return parent.unlockedBy(string, criterionTriggerInstance); + @NotNull Criterion criterion) { + return parent.unlockedBy(string, criterion); } @Override @@ -53,12 +51,9 @@ public IXplatConditionsBuilder whenModMissing(String modid) { } @Override - public void save(@NotNull Consumer consumer, @NotNull ResourceLocation resourceLocation) { - var conditionalBuilder = ConditionalRecipe.builder(); - for (ICondition condition : conditions) { - conditionalBuilder.addCondition(condition); - } - conditionalBuilder.addRecipe(recipeConsumer -> parent.save(recipeConsumer, resourceLocation)) - .build(consumer, resourceLocation); + public void save(RecipeOutput recipeOutput, ResourceLocation id) { + var out = recipeOutput.withConditions(conditions.toArray(ICondition[]::new)); + + parent.save(out, id); } } diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/datagen/ForgeHexDataGenerators.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/datagen/ForgeHexDataGenerators.java index c5ed351ea7..0598ab7110 100644 --- a/Neoforge/src/main/java/at/petrak/hexcasting/forge/datagen/ForgeHexDataGenerators.java +++ b/Neoforge/src/main/java/at/petrak/hexcasting/forge/datagen/ForgeHexDataGenerators.java @@ -28,12 +28,12 @@ import net.minecraft.world.item.Items; import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets; -import net.minecraftforge.common.Tags; -import net.minecraftforge.common.ToolActions; -import net.minecraftforge.common.data.DatapackBuiltinEntriesProvider; -import net.minecraftforge.common.data.ExistingFileHelper; -import net.minecraftforge.data.event.GatherDataEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.neoforge.common.ItemAbilities; +import net.neoforged.neoforge.common.Tags; +import net.neoforged.neoforge.common.data.DatapackBuiltinEntriesProvider; +import net.neoforged.neoforge.common.data.ExistingFileHelper; +import net.neoforged.neoforge.data.event.GatherDataEvent; import java.util.EnumMap; import java.util.List; @@ -43,12 +43,12 @@ public class ForgeHexDataGenerators { @SubscribeEvent public static void generateData(GatherDataEvent ev) { - if (System.getProperty("hexcasting.xplat_datagen") != null) { + //if (System.getProperty("hexcasting.xplat_datagen") != null) { configureXplatDatagen(ev); - } - if (System.getProperty("hexcasting.forge_datagen") != null) { + //} + //if (System.getProperty("hexcasting.forge_datagen") != null) { configureForgeDatagen(ev); - } + //} } private static void configureXplatDatagen(GatherDataEvent ev) { @@ -88,23 +88,24 @@ private static void configureForgeDatagen(GatherDataEvent ev) { var lookup = ev.getLookupProvider(); ExistingFileHelper efh = ev.getExistingFileHelper(); gen.addProvider(ev.includeServer(), new LootTableProvider( - output, Set.of(), List.of(new LootTableProvider.SubProviderEntry(HexLootTables::new, LootContextParamSets.ALL_PARAMS)) + output, Set.of(), List.of(new LootTableProvider.SubProviderEntry(HexLootTables::new, LootContextParamSets.ALL_PARAMS)), ev.getLookupProvider() )); - gen.addProvider(ev.includeServer(), new HexplatRecipes(output, INGREDIENTS, ForgeHexConditionsBuilder::new)); + gen.addProvider(ev.includeServer(), new HexplatRecipes(output, lookup, INGREDIENTS, ForgeHexConditionsBuilder::new)); // TODO: refactor? var xtags = IXplatAbstractions.INSTANCE.tags(); + var blockTagProvider = new HexBlockTagProvider(output, lookup, xtags); ((TagsProviderEFHSetter) blockTagProvider).setEFH(efh); gen.addProvider(ev.includeServer(), blockTagProvider); - var itemTagProvider = new HexItemTagProvider(output, lookup, blockTagProvider, IXplatAbstractions.INSTANCE.tags()); + var itemTagProvider = new HexItemTagProvider(output, lookup, blockTagProvider.contentsGetter(), IXplatAbstractions.INSTANCE.tags()); ((TagsProviderEFHSetter) itemTagProvider).setEFH(efh); gen.addProvider(ev.includeServer(), itemTagProvider); var hexTagProvider = new HexActionTagProvider(output, lookup); ((TagsProviderEFHSetter) hexTagProvider).setEFH(efh); gen.addProvider(ev.includeServer(), hexTagProvider); - gen.addProvider(ev.includeServer(), new ForgeHexLootModGen(output)); + gen.addProvider(ev.includeServer(), new ForgeHexLootModGen(output, ev.getLookupProvider())); } private static final IXplatIngredients INGREDIENTS = new IXplatIngredients() { @@ -115,7 +116,7 @@ public Ingredient glowstoneDust() { @Override public Ingredient leather() { - return Ingredient.of(Tags.Items.LEATHER); + return Ingredient.of(Tags.Items.LEATHERS); } @Override @@ -156,13 +157,13 @@ public EnumMap dyes() { public Ingredient stick() { return Ingredient.fromValues(Stream.of( new Ingredient.ItemValue(new ItemStack(Items.STICK)), - new Ingredient.TagValue(ItemTags.create(new ResourceLocation("forge", "rods/wooden"))) + new Ingredient.TagValue(ItemTags.create(ResourceLocation.fromNamespaceAndPath("forge", "rods/wooden"))) )); } @Override public Ingredient whenModIngredient(Ingredient defaultIngredient, String modid, Ingredient modIngredient) { - return ForgeModConditionalIngredient.of(defaultIngredient, modid, modIngredient); + return ForgeModConditionalIngredient.of(defaultIngredient, modid, modIngredient).toVanilla(); } // https://github.com/vectorwing/FarmersDelight/blob/1.18.2/src/generated/resources/data/farmersdelight/recipes/cutting/amethyst_block.json @@ -171,7 +172,7 @@ public FarmersDelightToolIngredient axeStrip() { return () -> { JsonObject object = new JsonObject(); object.addProperty("type", "farmersdelight:tool_action"); - object.addProperty("action", ToolActions.AXE_STRIP.name()); + object.addProperty("action", ItemAbilities.AXE_STRIP.name()); return object; }; } @@ -181,7 +182,7 @@ public FarmersDelightToolIngredient axeDig() { return () -> { JsonObject object = new JsonObject(); object.addProperty("type", "farmersdelight:tool_action"); - object.addProperty("action", ToolActions.AXE_DIG.name()); + object.addProperty("action", ItemAbilities.AXE_DIG.name()); return object; }; } diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/datagen/ForgeHexLootModGen.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/datagen/ForgeHexLootModGen.java index d1a85e93e7..210c098ad5 100644 --- a/Neoforge/src/main/java/at/petrak/hexcasting/forge/datagen/ForgeHexLootModGen.java +++ b/Neoforge/src/main/java/at/petrak/hexcasting/forge/datagen/ForgeHexLootModGen.java @@ -5,15 +5,20 @@ import at.petrak.hexcasting.forge.loot.ForgeHexAmethystLootMod; import at.petrak.hexcasting.forge.loot.ForgeHexLoreLootMod; import at.petrak.hexcasting.forge.loot.ForgeHexScrollLootMod; +import at.petrak.hexcasting.forge.loot.ForgeHexCypherLootMod; +import net.minecraft.core.HolderLookup; import net.minecraft.data.PackOutput; +import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; -import net.minecraftforge.common.data.GlobalLootModifierProvider; -import net.minecraftforge.common.loot.LootTableIdCondition; +import net.neoforged.neoforge.common.data.GlobalLootModifierProvider; +import net.neoforged.neoforge.common.loot.LootTableIdCondition; + +import java.util.concurrent.CompletableFuture; public class ForgeHexLootModGen extends GlobalLootModifierProvider { - public ForgeHexLootModGen(PackOutput output) { - super(output, HexAPI.MOD_ID); + public ForgeHexLootModGen(PackOutput output, CompletableFuture registries) { + super(output, registries, HexAPI.MOD_ID); } @Override @@ -28,13 +33,19 @@ protected void start() { for (var injection : HexLootHandler.DEFAULT_LORE_INJECTS) { var name = "lore/%s/%s".formatted(injection.getNamespace(), injection.getPath()); add(name, new ForgeHexLoreLootMod(new LootItemCondition[]{ - LootTableIdCondition.builder(injection).build(), + LootTableIdCondition.builder(injection).build() }, HexLootHandler.DEFAULT_LORE_CHANCE)); } + for (var injection : HexLootHandler.DEFAULT_CYPHER_INJECTS) { + var name = "cypher/%s/%s".formatted(injection.getNamespace(), injection.getPath()); + add(name, new ForgeHexCypherLootMod(new LootItemCondition[]{ + LootTableIdCondition.builder(injection).build() + }, HexLootHandler.DEFAULT_CYPHER_CHANCE)); + } + add("amethyst_cluster", new ForgeHexAmethystLootMod(new LootItemCondition[]{ - LootTableIdCondition.builder(Blocks.AMETHYST_CLUSTER.getLootTable()).build() + LootTableIdCondition.builder(Blocks.AMETHYST_CLUSTER.getLootTable().location()).build() }, HexLootHandler.DEFAULT_SHARD_MODIFICATION)); - } } diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/datagen/TagsProviderEFHSetter.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/datagen/TagsProviderEFHSetter.java index ddda7d2966..d7a14b6358 100644 --- a/Neoforge/src/main/java/at/petrak/hexcasting/forge/datagen/TagsProviderEFHSetter.java +++ b/Neoforge/src/main/java/at/petrak/hexcasting/forge/datagen/TagsProviderEFHSetter.java @@ -1,6 +1,6 @@ package at.petrak.hexcasting.forge.datagen; -import net.minecraftforge.common.data.ExistingFileHelper; +import net.neoforged.neoforge.common.data.ExistingFileHelper; public interface TagsProviderEFHSetter { void setEFH(ExistingFileHelper efh); diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/datagen/xplat/HexBlockStatesAndModels.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/datagen/xplat/HexBlockStatesAndModels.java index f4e30e8a42..063845abf8 100644 --- a/Neoforge/src/main/java/at/petrak/hexcasting/forge/datagen/xplat/HexBlockStatesAndModels.java +++ b/Neoforge/src/main/java/at/petrak/hexcasting/forge/datagen/xplat/HexBlockStatesAndModels.java @@ -7,19 +7,18 @@ import at.petrak.hexcasting.common.blocks.circles.directrix.BlockBooleanDirectrix; import at.petrak.hexcasting.common.blocks.circles.directrix.BlockRedstoneDirectrix; import at.petrak.hexcasting.common.lib.HexBlocks; -import at.petrak.paucal.api.forge.datagen.PaucalBlockStateAndModelProvider; +import at.petrak.paucal.forge.api.datagen.PaucalBlockStateAndModelProvider; import net.minecraft.core.Direction; -import net.minecraft.data.DataGenerator; import net.minecraft.data.PackOutput; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.properties.BlockStateProperties; -import net.minecraftforge.client.model.generators.BlockModelBuilder; -import net.minecraftforge.client.model.generators.ConfiguredModel; -import net.minecraftforge.client.model.generators.ModelBuilder; -import net.minecraftforge.common.data.ExistingFileHelper; +import net.neoforged.neoforge.client.model.generators.BlockModelBuilder; +import net.neoforged.neoforge.client.model.generators.ConfiguredModel; +import net.neoforged.neoforge.client.model.generators.ModelBuilder; +import net.neoforged.neoforge.common.data.ExistingFileHelper; -import static net.minecraftforge.client.model.generators.ModelProvider.BLOCK_FOLDER; +import static net.neoforged.neoforge.client.model.generators.ModelProvider.BLOCK_FOLDER; public class HexBlockStatesAndModels extends PaucalBlockStateAndModelProvider { public HexBlockStatesAndModels(PackOutput output, ExistingFileHelper exFileHelper) { @@ -186,7 +185,7 @@ protected void registerStatesAndModels() { blockAndItem(HexBlocks.EDIFIED_PANEL, models().cubeAll("edified_panel", modLoc("block/edified_panel"))); blockAndItem(HexBlocks.EDIFIED_TILE, models().cubeAll("edified_tile", modLoc("block/edified_tile"))); - ResourceLocation leavesParent = new ResourceLocation("block/leaves"); + ResourceLocation leavesParent = ResourceLocation.withDefaultNamespace("block/leaves"); blockAndItem(HexBlocks.AMETHYST_EDIFIED_LEAVES, models().withExistingParent("amethyst_edified_leaves", leavesParent) .texture("all", modLoc("block/amethyst_edified_leaves")) diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/datagen/xplat/HexItemModels.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/datagen/xplat/HexItemModels.java index 7def15a4e4..8704d66482 100644 --- a/Neoforge/src/main/java/at/petrak/hexcasting/forge/datagen/xplat/HexItemModels.java +++ b/Neoforge/src/main/java/at/petrak/hexcasting/forge/datagen/xplat/HexItemModels.java @@ -13,35 +13,37 @@ import at.petrak.hexcasting.common.items.storage.ItemThoughtKnot; import at.petrak.hexcasting.common.lib.HexBlocks; import at.petrak.hexcasting.common.lib.HexItems; -import at.petrak.paucal.api.forge.datagen.PaucalItemModelProvider; -import net.minecraft.client.renderer.block.model.ItemTransforms; -import net.minecraft.data.DataGenerator; +import at.petrak.paucal.forge.api.datagen.PaucalItemModelProvider; +import net.minecraft.core.HolderLookup; +import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.data.PackOutput; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.DyeColor; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemDisplayContext; import net.minecraft.world.level.block.Block; -import net.minecraftforge.client.model.generators.ModelFile; -import net.minecraftforge.common.data.ExistingFileHelper; -import net.minecraftforge.registries.ForgeRegistries; +import net.neoforged.neoforge.client.model.generators.ModelFile; +import net.neoforged.neoforge.common.data.ExistingFileHelper; import java.util.Objects; +import java.util.concurrent.CompletableFuture; import java.util.function.BiFunction; public class HexItemModels extends PaucalItemModelProvider { + public HexItemModels(PackOutput output, ExistingFileHelper existingFileHelper) { super(output, HexAPI.MOD_ID, existingFileHelper); } private static final String[] PHIAL_SIZES = {"small", "medium", "large", "larger", "largest"}; - private static String getPath(Item item) { - return Objects.requireNonNull(ForgeRegistries.ITEMS.getKey(item)).getPath(); + // TODO port: maybe consider using registry lookup? But it's completable future... Not sure + private String getPath(Item item) { + return Objects.requireNonNull(BuiltInRegistries.ITEM.getKey(item)).getPath(); } - private static String getPath(Block block) { - return Objects.requireNonNull(ForgeRegistries.BLOCKS.getKey(block)).getPath(); + private String getPath(Block block) { + return Objects.requireNonNull(BuiltInRegistries.BLOCK.getKey(block)).getPath(); } @Override @@ -55,11 +57,11 @@ protected void registerModels() { simpleItem(HexItems.LORE_FRAGMENT); singleTexture(getPath(HexBlocks.CONJURED_BLOCK), - new ResourceLocation("item/generated"), - "layer0", new ResourceLocation("item/amethyst_shard")); + ResourceLocation.withDefaultNamespace("item/generated"), + "layer0", ResourceLocation.withDefaultNamespace("item/amethyst_shard")); singleTexture(getPath(HexBlocks.CONJURED_LIGHT), - new ResourceLocation("item/generated"), - "layer0", new ResourceLocation("item/amethyst_shard")); + ResourceLocation.withDefaultNamespace("item/generated"), + "layer0", ResourceLocation.withDefaultNamespace("item/amethyst_shard")); for (var age : new String[]{"pristine", "ancient"}) { for (var size : new String[]{"small", "medium", "large"}) { @@ -78,9 +80,9 @@ protected void registerModels() { .translation(-2.5f, 0f, -8f) .scale(0.4f); - singleTexture("old_staff", new ResourceLocation("item/handheld_rod"), + singleTexture("old_staff", ResourceLocation.withDefaultNamespace("item/handheld_rod"), "layer0", modLoc("item/staff/old")); - singleTexture("cherry_staff", new ResourceLocation("item/handheld_rod"), + singleTexture("cherry_staff", ResourceLocation.withDefaultNamespace("item/handheld_rod"), "layer0", modLoc("item/staff/cherry")); buildStaff(HexItems.STAFF_OAK, "oak"); @@ -99,10 +101,10 @@ protected void registerModels() { // again, doesn't like paths with slashes in them, so we do it manually buildFourVariantGaslight("item/staff/quenched", "item/staff/quenched", (name, path) -> - singleTexture(path.getPath(), new ResourceLocation("item/handheld_rod"), + singleTexture(path.getPath(), ResourceLocation.withDefaultNamespace("item/handheld_rod"), "layer0", modLoc(path.getPath()))); buildFourVariantGaslight(getPath(HexItems.QUENCHED_SHARD), "item/quenched_shard", (name, path) -> - singleTexture(path.getPath(), new ResourceLocation("item/handheld"), + singleTexture(path.getPath(), ResourceLocation.withDefaultNamespace("item/handheld"), "layer0", modLoc(path.getPath()))); buildFourVariantGaslight(getPath(HexBlocks.QUENCHED_ALLAY), "block/quenched_allay", (name, path) -> cubeAll(path.getPath(), path)); @@ -119,6 +121,7 @@ protected void registerModels() { buildSealableIotaHolder(HexItems.FOCUS, "focus", HexItems.FOCUS.numVariants()); buildSealableIotaHolder(HexItems.SPELLBOOK, "spellbook", HexItems.SPELLBOOK.numVariants()); + buildPackagedSpell(HexItems.ANCIENT_CYPHER, "ancient_cypher", HexItems.ANCIENT_CYPHER.numVariants()); buildPackagedSpell(HexItems.CYPHER, "cypher", HexItems.CYPHER.numVariants()); buildPackagedSpell(HexItems.TRINKET, "trinket", HexItems.TRINKET.numVariants()); buildPackagedSpell(HexItems.ARTIFACT, "artifact", HexItems.ARTIFACT.numVariants()); @@ -129,7 +132,7 @@ protected void registerModels() { String name = "phial_" + PHIAL_SIZES[size] + "_" + fill; singleTexture( name, - new ResourceLocation("item/generated"), + ResourceLocation.withDefaultNamespace("item/generated"), "layer0", modLoc("item/phial/" + name)); float fillProp = (float) fill / maxFill; @@ -143,17 +146,17 @@ protected void registerModels() { for (var dye : DyeColor.values()) { singleTexture(getPath(HexItems.DYE_PIGMENTS.get(dye)), - new ResourceLocation("item/generated"), + ResourceLocation.withDefaultNamespace("item/generated"), "layer0", modLoc("item/colorizer/dye_" + dye.getName())); } for (var type : ItemPridePigment.Type.values()) { singleTexture(getPath(HexItems.PRIDE_PIGMENTS.get(type)), - new ResourceLocation("item/generated"), + ResourceLocation.withDefaultNamespace("item/generated"), "layer0", modLoc("item/colorizer/pride_" + type.getName())); } - singleTexture(getPath(HexItems.UUID_PIGMENT), new ResourceLocation("item/generated"), + singleTexture(getPath(HexItems.UUID_PIGMENT), ResourceLocation.withDefaultNamespace("item/generated"), "layer0", modLoc("item/colorizer/uuid")); - singleTexture(getPath(HexItems.DEFAULT_PIGMENT), new ResourceLocation("item/generated"), + singleTexture(getPath(HexItems.DEFAULT_PIGMENT), ResourceLocation.withDefaultNamespace("item/generated"), "layer0", modLoc("item/colorizer/uuid")); simpleItem(modLoc("slate_blank")); @@ -204,16 +207,16 @@ protected void registerModels() { getBuilder(getPath(HexBlocks.EDIFIED_SLAB)).parent( new ModelFile.UncheckedModelFile(modLoc("block/edified_slab"))); getBuilder(getPath(HexBlocks.EDIFIED_BUTTON)).parent( - new ModelFile.UncheckedModelFile(new ResourceLocation("block/button_inventory"))) + new ModelFile.UncheckedModelFile(ResourceLocation.withDefaultNamespace("block/button_inventory"))) .texture("texture", modLoc("block/edified_planks")); getBuilder(getPath(HexBlocks.EDIFIED_PRESSURE_PLATE)) .parent(new ModelFile.UncheckedModelFile(modLoc("block/edified_pressure_plate"))); } private void buildThoughtKnot() { - var unwritten = singleTexture("thought_knot", new ResourceLocation("item/generated"), + var unwritten = singleTexture("thought_knot", ResourceLocation.withDefaultNamespace("item/generated"), "layer0", modLoc("item/thought_knot")); - var written = withExistingParent("thought_knot_written", new ResourceLocation("item/generated")) + var written = withExistingParent("thought_knot_written", ResourceLocation.withDefaultNamespace("item/generated")) .texture("layer0", modLoc("item/thought_knot")) .texture("layer1", modLoc("item/thought_knot_overlay")); getBuilder("thought_knot") @@ -227,14 +230,14 @@ private void buildSealableIotaHolder(Item item, String stub, int numVariants) { var name = getPath(item); var builder = getBuilder(name); for (int i = 0; i < numVariants; i++) { - var plain = i == 0 ? singleTexture(name, new ResourceLocation("item/generated"), + var plain = i == 0 ? singleTexture(name, ResourceLocation.withDefaultNamespace("item/generated"), "layer0", modLoc("item/cad/" + i + "_" + stub + "_empty")) - : withExistingParent(name + "_" + i, new ResourceLocation("item/generated")) + : withExistingParent(name + "_" + i, ResourceLocation.withDefaultNamespace("item/generated")) .texture("layer0", modLoc("item/cad/" + i + "_" + stub + "_empty")); - var unsealed = withExistingParent(name + "_" + i + "_filled", new ResourceLocation("item/generated")) + var unsealed = withExistingParent(name + "_" + i + "_filled", ResourceLocation.withDefaultNamespace("item/generated")) .texture("layer0", modLoc("item/cad/" + i + "_" + stub + "_filled")) .texture("layer1", modLoc("item/cad/" + i + "_" + stub + "_filled_overlay")); - var sealed = withExistingParent(name + "_" + i + "_sealed", new ResourceLocation("item/generated")) + var sealed = withExistingParent(name + "_" + i + "_sealed", ResourceLocation.withDefaultNamespace("item/generated")) .texture("layer0", modLoc("item/cad/" + i + "_" + stub + "_sealed")) .texture("layer1", modLoc("item/cad/" + i + "_" + stub + "_sealed_overlay")); builder.override().predicate(ItemFocus.VARIANT_PRED, i).predicate(ItemFocus.OVERLAY_PRED, 0f) @@ -257,7 +260,7 @@ private void buildScroll(Item item, String size) { } private void buildStaff(Item item, String name) { - singleTexture("item/" + getPath(item), new ResourceLocation("item/handheld_rod"), + singleTexture("item/" + getPath(item), ResourceLocation.withDefaultNamespace("item/handheld_rod"), "layer0", modLoc("item/staff/" + name)); getBuilder(getPath(item)) .override() @@ -275,11 +278,11 @@ private void buildPackagedSpell(Item item, String stub, int numVariants) { var name = getPath(item); var builder = getBuilder(name); for (int i = 0; i < numVariants; i++) { - var plain = i == 0 ? singleTexture(name, new ResourceLocation("item/generated"), + var plain = i == 0 ? singleTexture(name, ResourceLocation.withDefaultNamespace("item/generated"), "layer0", modLoc("item/cad/" + i + "_" + stub)) - : withExistingParent(name + "_" + i, new ResourceLocation("item/generated")) + : withExistingParent(name + "_" + i, ResourceLocation.withDefaultNamespace("item/generated")) .texture("layer0", modLoc("item/cad/" + i + "_" + stub)); - var filled = withExistingParent(name + "_" + i + "_filled", new ResourceLocation("item/generated")) + var filled = withExistingParent(name + "_" + i + "_filled", ResourceLocation.withDefaultNamespace("item/generated")) .texture("layer0", modLoc("item/cad/" + i + "_" + stub)) .texture("layer1", modLoc("item/cad/" + i + "_" + stub + "_overlay")); builder.override().predicate(ItemFocus.VARIANT_PRED, i).predicate(ItemPackagedHex.HAS_PATTERNS_PRED, -0.01f) diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/interop/curios/CuriosApiInterop.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/interop/curios/CuriosApiInterop.java index dfb750c35a..2d13ccb6d9 100644 --- a/Neoforge/src/main/java/at/petrak/hexcasting/forge/interop/curios/CuriosApiInterop.java +++ b/Neoforge/src/main/java/at/petrak/hexcasting/forge/interop/curios/CuriosApiInterop.java @@ -3,25 +3,19 @@ import at.petrak.hexcasting.api.misc.DiscoveryHandlers; import at.petrak.hexcasting.common.items.HexBaubleItem; import at.petrak.hexcasting.common.items.magic.ItemCreativeUnlocker; -import at.petrak.hexcasting.forge.cap.ForgeCapabilityHandler; -import at.petrak.hexcasting.interop.HexInterop; import com.google.common.collect.Multimap; +import net.minecraft.core.Holder; +import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.ai.attributes.Attribute; import net.minecraft.world.entity.ai.attributes.AttributeModifier; +import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; -import net.minecraftforge.common.capabilities.ICapabilityProvider; -import net.minecraftforge.fml.InterModComms; -import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; -import net.minecraftforge.fml.event.lifecycle.InterModEnqueueEvent; +import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent; +import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent; import top.theillusivec4.curios.api.CuriosCapability; import top.theillusivec4.curios.api.SlotContext; -import top.theillusivec4.curios.api.SlotTypeMessage; -import top.theillusivec4.curios.api.SlotTypePreset; import top.theillusivec4.curios.api.type.capability.ICurio; -import java.util.UUID; -import java.util.concurrent.atomic.AtomicReference; - public class CuriosApiInterop { static class Wrapper implements ICurio { private final ItemStack stack; @@ -42,40 +36,35 @@ public ItemStack getStack() { } @Override - public Multimap getAttributeModifiers(SlotContext slotContext, UUID uuid) { - var map = ICurio.super.getAttributeModifiers(slotContext, uuid); + public Multimap, AttributeModifier> getAttributeModifiers(SlotContext slotContext, ResourceLocation id) { + var map = ICurio.super.getAttributeModifiers(slotContext, id); map.putAll(this.bauble.getHexBaubleAttrs(this.stack)); return map; } } - public static ICapabilityProvider curioCap(ItemStack stack) { - return ForgeCapabilityHandler.makeProvider(CuriosCapability.ITEM, new Wrapper(stack)); - } - public static void init() { DiscoveryHandlers.addDebugItemDiscoverer((player, type) -> { - AtomicReference result = new AtomicReference<>(ItemStack.EMPTY); - player.getCapability(CuriosCapability.INVENTORY).ifPresent(handler -> { - for (var stacksHandler : handler.getCurios().values()) { + var inv = player.getCapability(CuriosCapability.INVENTORY); + + if(inv != null) { + for (var stacksHandler : inv.getCurios().values()) { var stacks = stacksHandler.getStacks(); for (int i = 0; i < stacks.getSlots(); i++) { var stack = stacks.getStackInSlot(i); if (ItemCreativeUnlocker.isDebug(stack, type)) { - result.set(stack); - return; + return stack; } } } - }); - return result.get(); + } + return ItemStack.EMPTY; }); } - public static void onInterModEnqueue(final InterModEnqueueEvent event) { - InterModComms.sendTo(HexInterop.Forge.CURIOS_API_ID, SlotTypeMessage.REGISTER_TYPE, - () -> SlotTypePreset.HEAD.getMessageBuilder().build()); + public static void registerCap(RegisterCapabilitiesEvent evt, Item item) { + evt.registerItem(CuriosCapability.ITEM, (stack, ctx) -> new Wrapper(stack), item); } public static void onClientSetup(final FMLClientSetupEvent event) { diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/interop/curios/CuriosRenderers.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/interop/curios/CuriosRenderers.java index 3ec7edd483..a7785611ee 100644 --- a/Neoforge/src/main/java/at/petrak/hexcasting/forge/interop/curios/CuriosRenderers.java +++ b/Neoforge/src/main/java/at/petrak/hexcasting/forge/interop/curios/CuriosRenderers.java @@ -8,12 +8,9 @@ import net.minecraft.client.model.geom.builders.CubeListBuilder; import net.minecraft.client.model.geom.builders.LayerDefinition; import net.minecraft.client.model.geom.builders.MeshDefinition; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; -import net.minecraftforge.client.event.EntityRenderersEvent; +import net.neoforged.neoforge.client.event.EntityRenderersEvent; import top.theillusivec4.curios.api.client.CuriosRendererRegistry; -@OnlyIn(Dist.CLIENT) public class CuriosRenderers { public static void register() { CuriosRendererRegistry.register(HexItems.SCRYING_LENS, () -> new LensCurioRenderer(Minecraft.getInstance().getEntityModels().bakeLayer(LensCurioRenderer.LAYER))); diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/interop/curios/LensCurioRenderer.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/interop/curios/LensCurioRenderer.java index 38f5ff065f..a9f590d950 100644 --- a/Neoforge/src/main/java/at/petrak/hexcasting/forge/interop/curios/LensCurioRenderer.java +++ b/Neoforge/src/main/java/at/petrak/hexcasting/forge/interop/curios/LensCurioRenderer.java @@ -19,7 +19,7 @@ import top.theillusivec4.curios.api.client.ICurioRenderer; public class LensCurioRenderer implements ICurioRenderer { - public static final ModelLayerLocation LAYER = new ModelLayerLocation(new ResourceLocation(HexAPI.MOD_ID, "lens"), "lens"); + public static final ModelLayerLocation LAYER = new ModelLayerLocation(ResourceLocation.fromNamespaceAndPath(HexAPI.MOD_ID, "lens"), "lens"); private final HumanoidModel model; diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/interop/jei/BrainsweepRecipeCategory.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/interop/jei/BrainsweepRecipeCategory.java index 6dddb8015a..9c739a32a0 100644 --- a/Neoforge/src/main/java/at/petrak/hexcasting/forge/interop/jei/BrainsweepRecipeCategory.java +++ b/Neoforge/src/main/java/at/petrak/hexcasting/forge/interop/jei/BrainsweepRecipeCategory.java @@ -1,9 +1,11 @@ package at.petrak.hexcasting.forge.interop.jei; import at.petrak.hexcasting.client.ClientTickCounter; +import at.petrak.hexcasting.common.casting.actions.spells.OpEdifySapling; import at.petrak.hexcasting.common.recipe.BrainsweepRecipe; import com.mojang.blaze3d.systems.RenderSystem; import mezz.jei.api.gui.builder.IRecipeLayoutBuilder; +import mezz.jei.api.gui.builder.ITooltipBuilder; import mezz.jei.api.gui.drawable.IDrawable; import mezz.jei.api.gui.drawable.IDrawableStatic; import mezz.jei.api.gui.ingredient.IRecipeSlotsView; @@ -18,8 +20,6 @@ import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.ItemStack; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; import org.jetbrains.annotations.NotNull; import java.util.Collections; @@ -44,16 +44,19 @@ public BrainsweepRecipeCategory(IGuiHelper guiHelper) { } @Override - @OnlyIn(Dist.CLIENT) public @NotNull Component getTitle() { return localizedName; } @Override - public @NotNull - IDrawable getBackground() { - return background; + public int getWidth() { + return background.getWidth(); + } + + @Override + public int getHeight() { + return background.getHeight(); } @Override @@ -63,19 +66,16 @@ IDrawable getIcon() { } @Override - public @NotNull - List getTooltipStrings(@NotNull BrainsweepRecipe recipe, - @NotNull IRecipeSlotsView recipeSlotsView, double mouseX, double mouseY) { + public void getTooltip(ITooltipBuilder tooltip, BrainsweepRecipe recipe, IRecipeSlotsView recipeSlotsView, double mouseX, double mouseY) { if (37 <= mouseX && mouseX <= 37 + 26 && 19 <= mouseY && mouseY <= 19 + 48) { Minecraft mc = Minecraft.getInstance(); - return recipe.entityIn().getTooltip(mc.options.advancedItemTooltips); + tooltip.addAll(recipe.entityIn().getTooltip(mc.options.advancedItemTooltips)); } - - return Collections.emptyList(); } @Override public void draw(@NotNull BrainsweepRecipe recipe, @NotNull IRecipeSlotsView recipeSlotsView, @NotNull GuiGraphics graphics, double mouseX, double mouseY) { + background.draw(graphics); ClientLevel level = Minecraft.getInstance().level; if (level != null) { var example = recipe.entityIn().exampleEntity(level); diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/interop/jei/EdifyRecipeCategory.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/interop/jei/EdifyRecipeCategory.java index 84ab9bab31..10c8d91a44 100644 --- a/Neoforge/src/main/java/at/petrak/hexcasting/forge/interop/jei/EdifyRecipeCategory.java +++ b/Neoforge/src/main/java/at/petrak/hexcasting/forge/interop/jei/EdifyRecipeCategory.java @@ -5,18 +5,18 @@ import mezz.jei.api.gui.builder.IRecipeLayoutBuilder; import mezz.jei.api.gui.drawable.IDrawable; import mezz.jei.api.gui.drawable.IDrawableStatic; +import mezz.jei.api.gui.ingredient.IRecipeSlotsView; import mezz.jei.api.helpers.IGuiHelper; import mezz.jei.api.recipe.IFocusGroup; import mezz.jei.api.recipe.RecipeIngredientRole; import mezz.jei.api.recipe.RecipeType; import mezz.jei.api.recipe.category.IRecipeCategory; +import net.minecraft.client.gui.GuiGraphics; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.ItemTags; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.Ingredient; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; import org.jetbrains.annotations.NotNull; import static at.petrak.hexcasting.api.HexAPI.modLoc; @@ -37,14 +37,23 @@ public EdifyRecipeCategory(IGuiHelper guiHelper) { } @Override - @OnlyIn(Dist.CLIENT) public @NotNull Component getTitle() { return localizedName; } @Override - public @NotNull IDrawable getBackground() { - return background; + public int getWidth() { + return background.getWidth(); + } + + @Override + public int getHeight() { + return background.getHeight(); + } + + @Override + public void draw(OpEdifySapling recipe, IRecipeSlotsView recipeSlotsView, GuiGraphics guiGraphics, double mouseX, double mouseY) { + background.draw(guiGraphics); } @Override diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/interop/jei/HexJEIPlugin.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/interop/jei/HexJEIPlugin.java index 32572ba10c..6e708cfacd 100644 --- a/Neoforge/src/main/java/at/petrak/hexcasting/forge/interop/jei/HexJEIPlugin.java +++ b/Neoforge/src/main/java/at/petrak/hexcasting/forge/interop/jei/HexJEIPlugin.java @@ -17,6 +17,7 @@ import net.minecraft.client.Minecraft; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.RecipeHolder; import net.minecraft.world.level.Level; import org.jetbrains.annotations.NotNull; @@ -57,7 +58,7 @@ public void registerRecipes(@NotNull IRecipeRegistration registration) { Level level = Minecraft.getInstance().level; if (level != null) { registration.addRecipes(BRAINSWEEPING, - level.getRecipeManager().getAllRecipesFor(HexRecipeStuffRegistry.BRAINSWEEP_TYPE)); + level.getRecipeManager().getAllRecipesFor(HexRecipeStuffRegistry.BRAINSWEEP_TYPE).stream().map(RecipeHolder::value).toList()); } if (PhialRecipeStackBuilder.shouldAddRecipe()) { diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/interop/jei/PhialRecipeCategory.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/interop/jei/PhialRecipeCategory.java index 23a4272a4e..46d1645998 100644 --- a/Neoforge/src/main/java/at/petrak/hexcasting/forge/interop/jei/PhialRecipeCategory.java +++ b/Neoforge/src/main/java/at/petrak/hexcasting/forge/interop/jei/PhialRecipeCategory.java @@ -1,21 +1,22 @@ package at.petrak.hexcasting.forge.interop.jei; import at.petrak.hexcasting.api.mod.HexTags; +import at.petrak.hexcasting.common.casting.actions.spells.OpEdifySapling; import at.petrak.hexcasting.common.casting.actions.spells.OpMakeBattery; import at.petrak.hexcasting.interop.utils.PhialRecipeStackBuilder; import mezz.jei.api.gui.builder.IRecipeLayoutBuilder; import mezz.jei.api.gui.drawable.IDrawable; import mezz.jei.api.gui.drawable.IDrawableStatic; +import mezz.jei.api.gui.ingredient.IRecipeSlotsView; import mezz.jei.api.helpers.IGuiHelper; import mezz.jei.api.recipe.IFocusGroup; import mezz.jei.api.recipe.RecipeIngredientRole; import mezz.jei.api.recipe.RecipeType; import mezz.jei.api.recipe.category.IRecipeCategory; +import net.minecraft.client.gui.GuiGraphics; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.crafting.Ingredient; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; import org.jetbrains.annotations.NotNull; import static at.petrak.hexcasting.api.HexAPI.modLoc; @@ -36,14 +37,23 @@ public PhialRecipeCategory(IGuiHelper guiHelper) { } @Override - @OnlyIn(Dist.CLIENT) public @NotNull Component getTitle() { return localizedName; } @Override - public @NotNull IDrawable getBackground() { - return background; + public int getWidth() { + return background.getWidth(); + } + + @Override + public int getHeight() { + return background.getHeight(); + } + + @Override + public void draw(OpMakeBattery recipe, IRecipeSlotsView recipeSlotsView, GuiGraphics guiGraphics, double mouseX, double mouseY) { + background.draw(guiGraphics); } @Override diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/lib/ForgeHexArgumentTypeRegistry.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/lib/ForgeHexArgumentTypeRegistry.java index 4a3450372a..4dfa83695f 100644 --- a/Neoforge/src/main/java/at/petrak/hexcasting/forge/lib/ForgeHexArgumentTypeRegistry.java +++ b/Neoforge/src/main/java/at/petrak/hexcasting/forge/lib/ForgeHexArgumentTypeRegistry.java @@ -1,30 +1,30 @@ package at.petrak.hexcasting.forge.lib; import at.petrak.hexcasting.api.HexAPI; -import at.petrak.hexcasting.common.command.PatternResLocArgument; +import at.petrak.hexcasting.common.command.PatternResKeyArgument; import com.mojang.brigadier.arguments.ArgumentType; import net.minecraft.commands.synchronization.ArgumentTypeInfo; import net.minecraft.commands.synchronization.ArgumentTypeInfos; import net.minecraft.commands.synchronization.SingletonArgumentInfo; -import net.minecraftforge.registries.DeferredRegister; -import net.minecraftforge.registries.ForgeRegistries; -import net.minecraftforge.registries.RegistryObject; +import net.minecraft.core.registries.Registries; +import net.neoforged.neoforge.registries.DeferredHolder; +import net.neoforged.neoforge.registries.DeferredRegister; // ArgumentTypeInfos.java public class ForgeHexArgumentTypeRegistry { public static final DeferredRegister> ARGUMENT_TYPES = DeferredRegister.create( - ForgeRegistries.COMMAND_ARGUMENT_TYPES, HexAPI.MOD_ID); + Registries.COMMAND_ARGUMENT_TYPE, HexAPI.MOD_ID); // how fucking ergonomic - public static final RegistryObject.Template>> - PATTERN_RESLOC = register(PatternResLocArgument.class, + public static final DeferredHolder, ArgumentTypeInfo.Template>> + PATTERN_RESLOC = register(PatternResKeyArgument.class, "pattern", - SingletonArgumentInfo.contextFree(PatternResLocArgument::id) + SingletonArgumentInfo.contextFree(PatternResKeyArgument::id) ); private static , T extends ArgumentTypeInfo.Template, I extends ArgumentTypeInfo> - RegistryObject> register( + DeferredHolder, ArgumentTypeInfo> register( Class clazz, String name, ArgumentTypeInfo ati) { diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/lib/ForgeHexAttachments.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/lib/ForgeHexAttachments.java new file mode 100644 index 0000000000..ce096c70bd --- /dev/null +++ b/Neoforge/src/main/java/at/petrak/hexcasting/forge/lib/ForgeHexAttachments.java @@ -0,0 +1,23 @@ +package at.petrak.hexcasting.forge.lib; + +import at.petrak.hexcasting.api.HexAPI; +import at.petrak.hexcasting.api.client.ClientCastingStack; +import at.petrak.hexcasting.forge.ForgeHexInitializer; +import net.neoforged.neoforge.attachment.AttachmentType; +import net.neoforged.neoforge.registries.DeferredRegister; +import net.neoforged.neoforge.registries.NeoForgeRegistries; + +import java.util.function.Supplier; + +public class ForgeHexAttachments { + private static final DeferredRegister> ATTACHMENT_TYPES = DeferredRegister.create(NeoForgeRegistries.ATTACHMENT_TYPES, HexAPI.MOD_ID); + + // TODO port: maybe make client-side only? + public static final Supplier> CLIENT_CASTING_STACK = ATTACHMENT_TYPES.register( + "casting_stack", () -> AttachmentType.builder(ClientCastingStack::new).build() + ); + + public static void register() { + ATTACHMENT_TYPES.register(ForgeHexInitializer.getModEventBus()); + } +} diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/lib/ForgeHexIngredientTypes.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/lib/ForgeHexIngredientTypes.java new file mode 100644 index 0000000000..e4361c7bce --- /dev/null +++ b/Neoforge/src/main/java/at/petrak/hexcasting/forge/lib/ForgeHexIngredientTypes.java @@ -0,0 +1,29 @@ +package at.petrak.hexcasting.forge.lib; + +import at.petrak.hexcasting.api.HexAPI; +import at.petrak.hexcasting.forge.loot.ForgeHexAmethystLootMod; +import at.petrak.hexcasting.forge.loot.ForgeHexCypherLootMod; +import at.petrak.hexcasting.forge.loot.ForgeHexLoreLootMod; +import at.petrak.hexcasting.forge.loot.ForgeHexScrollLootMod; +import at.petrak.hexcasting.forge.recipe.ForgeModConditionalIngredient; +import at.petrak.hexcasting.forge.recipe.ForgeUnsealedIngredient; +import com.mojang.serialization.MapCodec; +import net.neoforged.neoforge.common.crafting.IngredientType; +import net.neoforged.neoforge.common.loot.IGlobalLootModifier; +import net.neoforged.neoforge.registries.DeferredHolder; +import net.neoforged.neoforge.registries.DeferredRegister; +import net.neoforged.neoforge.registries.NeoForgeRegistries; + +import java.util.function.Supplier; + +public class ForgeHexIngredientTypes { + public static final DeferredRegister> INGREDIENT_TYPES = + DeferredRegister.create(NeoForgeRegistries.Keys.INGREDIENT_TYPES, HexAPI.MOD_ID); + + public static final Supplier> UNSEALED_INGREDIENT = + INGREDIENT_TYPES.register("unsealed", + () -> new IngredientType<>(ForgeUnsealedIngredient.CODEC, ForgeUnsealedIngredient.STREAM_CODEC)); + public static final Supplier> MOD_CONDITIONAL_INGREDIENT = + INGREDIENT_TYPES.register("mod_conditional", + () -> new IngredientType<>(ForgeModConditionalIngredient.CODEC, ForgeModConditionalIngredient.STREAM_CODEC)); +} diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/lib/ForgeHexLootMods.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/lib/ForgeHexLootMods.java index a967358df2..e6e36db9b4 100644 --- a/Neoforge/src/main/java/at/petrak/hexcasting/forge/lib/ForgeHexLootMods.java +++ b/Neoforge/src/main/java/at/petrak/hexcasting/forge/lib/ForgeHexLootMods.java @@ -4,20 +4,25 @@ import at.petrak.hexcasting.forge.loot.ForgeHexAmethystLootMod; import at.petrak.hexcasting.forge.loot.ForgeHexLoreLootMod; import at.petrak.hexcasting.forge.loot.ForgeHexScrollLootMod; +import at.petrak.hexcasting.forge.loot.ForgeHexCypherLootMod; import com.mojang.serialization.Codec; -import net.minecraftforge.common.loot.IGlobalLootModifier; -import net.minecraftforge.registries.DeferredRegister; -import net.minecraftforge.registries.ForgeRegistries; -import net.minecraftforge.registries.RegistryObject; +import com.mojang.serialization.MapCodec; +import net.minecraft.core.registries.Registries; +import net.neoforged.neoforge.common.loot.IGlobalLootModifier; +import net.neoforged.neoforge.registries.DeferredHolder; +import net.neoforged.neoforge.registries.DeferredRegister; +import net.neoforged.neoforge.registries.NeoForgeRegistries; public class ForgeHexLootMods { - public static final DeferredRegister> REGISTRY = DeferredRegister.create( - ForgeRegistries.Keys.GLOBAL_LOOT_MODIFIER_SERIALIZERS, HexAPI.MOD_ID); + public static final DeferredRegister> REGISTRY = DeferredRegister.create( + NeoForgeRegistries.Keys.GLOBAL_LOOT_MODIFIER_SERIALIZERS, HexAPI.MOD_ID); - public static final RegistryObject> INJECT_SCROLLS = REGISTRY.register( + public static final DeferredHolder, MapCodec> INJECT_SCROLLS = REGISTRY.register( "inject_scrolls", ForgeHexScrollLootMod.CODEC); - public static final RegistryObject> INJECT_LORE = REGISTRY.register( + public static final DeferredHolder, MapCodec> INJECT_LORE = REGISTRY.register( "inject_lore", ForgeHexLoreLootMod.CODEC); - public static final RegistryObject> AMETHYST = REGISTRY.register( + public static final DeferredHolder, MapCodec> INJECT_CYPHERS = REGISTRY.register( + "inject_cyphers", ForgeHexCypherLootMod.CODEC); + public static final DeferredHolder, MapCodec> AMETHYST = REGISTRY.register( "amethyst_cluster", ForgeHexAmethystLootMod.CODEC); } diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/loot/ForgeHexAmethystLootMod.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/loot/ForgeHexAmethystLootMod.java index 671e9cec5b..47ea0dad38 100644 --- a/Neoforge/src/main/java/at/petrak/hexcasting/forge/loot/ForgeHexAmethystLootMod.java +++ b/Neoforge/src/main/java/at/petrak/hexcasting/forge/loot/ForgeHexAmethystLootMod.java @@ -5,19 +5,21 @@ import at.petrak.hexcasting.forge.lib.ForgeHexLootMods; import com.google.common.base.Suppliers; import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import net.minecraft.core.registries.Registries; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.storage.loot.LootContext; import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; -import net.minecraftforge.common.loot.LootModifier; +import net.neoforged.neoforge.common.loot.LootModifier; import org.jetbrains.annotations.NotNull; import java.util.function.Supplier; public class ForgeHexAmethystLootMod extends LootModifier { - public static final Supplier> CODEC = - Suppliers.memoize(() -> RecordCodecBuilder.create( + public static final Supplier> CODEC = + Suppliers.memoize(() -> RecordCodecBuilder.mapCodec( inst -> codecStart(inst).and( Codec.DOUBLE.fieldOf("shardDelta").forGetter(it -> it.shardDelta) ).apply(inst, ForgeHexAmethystLootMod::new) @@ -33,8 +35,12 @@ public ForgeHexAmethystLootMod(LootItemCondition[] conditionsIn, double shardDel @Override protected @NotNull ObjectArrayList doApply(ObjectArrayList generatedLoot, LootContext context) { - var injectPool = context.getResolver().getLootTable(HexLootHandler.TABLE_INJECT_AMETHYST_CLUSTER); - injectPool.getRandomItemsRaw(context, generatedLoot::add); + var injectPool = context.getResolver() + .lookupOrThrow(Registries.LOOT_TABLE) + .getOrThrow(HexLootHandler.TABLE_INJECT_AMETHYST_CLUSTER) + .value(); + //TODO check if should be raw with modifiers applied or not + injectPool.getRandomItems(context, generatedLoot::add); for (var stack : generatedLoot) { AmethystReducerFunc.doStatic(stack, context, this.shardDelta); @@ -44,7 +50,7 @@ public ForgeHexAmethystLootMod(LootItemCondition[] conditionsIn, double shardDel } @Override - public Codec codec() { + public MapCodec codec() { return ForgeHexLootMods.AMETHYST.get(); } } diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/loot/ForgeHexCypherLootMod.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/loot/ForgeHexCypherLootMod.java new file mode 100644 index 0000000000..ad5e2d13c7 --- /dev/null +++ b/Neoforge/src/main/java/at/petrak/hexcasting/forge/loot/ForgeHexCypherLootMod.java @@ -0,0 +1,49 @@ +package at.petrak.hexcasting.forge.loot; + +import at.petrak.hexcasting.common.lib.HexItems; +import at.petrak.hexcasting.common.loot.AddHexToAncientCypherFunc; +import at.petrak.hexcasting.forge.lib.ForgeHexLootMods; +import com.google.common.base.Suppliers; +import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; +import net.neoforged.neoforge.common.loot.LootModifier; +import org.jetbrains.annotations.NotNull; + +import java.util.function.Supplier; + +public class ForgeHexCypherLootMod extends LootModifier { + public static final Supplier> CODEC = + Suppliers.memoize(() -> RecordCodecBuilder.mapCodec( + inst -> codecStart(inst).and( + Codec.DOUBLE.fieldOf("chance").forGetter(it -> it.chance) + ).apply(inst, ForgeHexCypherLootMod::new) + )); + + public final double chance; + + public ForgeHexCypherLootMod(LootItemCondition[] conditionsIn, double chance) { + super(conditionsIn); + this.chance = chance; + } + + @Override + protected @NotNull ObjectArrayList doApply(ObjectArrayList generatedLoot, + LootContext context) { + if (context.getRandom().nextDouble() < this.chance) { + var newStack = new ItemStack(HexItems.ANCIENT_CYPHER); + AddHexToAncientCypherFunc.doStatic(newStack, context.getRandom()); + generatedLoot.add(newStack); + } + return generatedLoot; + } + + @Override + public MapCodec codec() { + return ForgeHexLootMods.INJECT_CYPHERS.get(); + } +} diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/loot/ForgeHexLoreLootMod.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/loot/ForgeHexLoreLootMod.java index e5de13a237..b12b8a85df 100644 --- a/Neoforge/src/main/java/at/petrak/hexcasting/forge/loot/ForgeHexLoreLootMod.java +++ b/Neoforge/src/main/java/at/petrak/hexcasting/forge/loot/ForgeHexLoreLootMod.java @@ -4,19 +4,20 @@ import at.petrak.hexcasting.forge.lib.ForgeHexLootMods; import com.google.common.base.Suppliers; import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.storage.loot.LootContext; import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; -import net.minecraftforge.common.loot.LootModifier; +import net.neoforged.neoforge.common.loot.LootModifier; import org.jetbrains.annotations.NotNull; import java.util.function.Supplier; public class ForgeHexLoreLootMod extends LootModifier { - public static final Supplier> CODEC = - Suppliers.memoize(() -> RecordCodecBuilder.create( + public static final Supplier> CODEC = + Suppliers.memoize(() -> RecordCodecBuilder.mapCodec( inst -> codecStart(inst).and( Codec.DOUBLE.fieldOf("chance").forGetter(it -> it.chance) ).apply(inst, ForgeHexLoreLootMod::new) @@ -39,7 +40,7 @@ public ForgeHexLoreLootMod(LootItemCondition[] conditionsIn, double chance) { } @Override - public Codec codec() { + public MapCodec codec() { return ForgeHexLootMods.INJECT_LORE.get(); } } diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/loot/ForgeHexScrollLootMod.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/loot/ForgeHexScrollLootMod.java index ffae0a85ce..107c95a647 100644 --- a/Neoforge/src/main/java/at/petrak/hexcasting/forge/loot/ForgeHexScrollLootMod.java +++ b/Neoforge/src/main/java/at/petrak/hexcasting/forge/loot/ForgeHexScrollLootMod.java @@ -6,25 +6,26 @@ import at.petrak.hexcasting.forge.lib.ForgeHexLootMods; import com.google.common.base.Suppliers; import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.storage.loot.LootContext; import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; -import net.minecraftforge.common.loot.IGlobalLootModifier; -import net.minecraftforge.common.loot.LootModifier; +import net.neoforged.neoforge.common.loot.IGlobalLootModifier; +import net.neoforged.neoforge.common.loot.LootModifier; import org.jetbrains.annotations.NotNull; import java.util.function.Supplier; public class ForgeHexScrollLootMod extends LootModifier { - public static final Supplier> CODEC = - Suppliers.memoize(() -> RecordCodecBuilder.create( + public static final Supplier> CODEC = + Suppliers.memoize(() -> RecordCodecBuilder.mapCodec( inst -> codecStart(inst).and( Codec.INT.fieldOf("countRange").forGetter(it -> it.countRange) ).apply(inst, ForgeHexScrollLootMod::new) )); - + public final int countRange; public ForgeHexScrollLootMod(LootItemCondition[] conditionsIn, int countRange) { @@ -38,14 +39,14 @@ public ForgeHexScrollLootMod(LootItemCondition[] conditionsIn, int countRange) { int count = HexLootHandler.getScrollCount(this.countRange, context.getRandom()); for (int i = 0; i < count; i++) { var newStack = new ItemStack(HexItems.SCROLL_LARGE); - AddPerWorldPatternToScrollFunc.doStatic(newStack, context); + AddPerWorldPatternToScrollFunc.doStatic(newStack, context.getRandom(), context.getLevel().getServer().overworld()); generatedLoot.add(newStack); } return generatedLoot; } @Override - public Codec codec() { + public MapCodec codec() { return ForgeHexLootMods.INJECT_SCROLLS.get(); } } diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/mixin/ForgeAccessorBuiltInRegistries.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/mixin/ForgeAccessorBuiltInRegistries.java deleted file mode 100644 index b086d8714d..0000000000 --- a/Neoforge/src/main/java/at/petrak/hexcasting/forge/mixin/ForgeAccessorBuiltInRegistries.java +++ /dev/null @@ -1,25 +0,0 @@ -package at.petrak.hexcasting.forge.mixin; - -import net.minecraft.core.DefaultedRegistry; -import net.minecraft.core.Registry; -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.resources.ResourceKey; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Invoker; - -@Mixin(BuiltInRegistries.class) -public interface ForgeAccessorBuiltInRegistries { - @Invoker("registerDefaulted") - static DefaultedRegistry hex$registerDefaulted(ResourceKey> registryName, - String defaultId, - BuiltInRegistries.RegistryBootstrap bootstrap) { - throw new IllegalStateException(); - } - - @Invoker("registerSimple") - static Registry hex$registerSimple(ResourceKey> registryName, - BuiltInRegistries.RegistryBootstrap bootstrap) { - throw new IllegalStateException(); - } -} - diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/mixin/ForgeMixinTagsProvider.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/mixin/ForgeMixinTagsProvider.java index e815506337..4d731fac7e 100644 --- a/Neoforge/src/main/java/at/petrak/hexcasting/forge/mixin/ForgeMixinTagsProvider.java +++ b/Neoforge/src/main/java/at/petrak/hexcasting/forge/mixin/ForgeMixinTagsProvider.java @@ -2,7 +2,7 @@ import at.petrak.hexcasting.forge.datagen.TagsProviderEFHSetter; import net.minecraft.data.tags.TagsProvider; -import net.minecraftforge.common.data.ExistingFileHelper; +import net.neoforged.neoforge.common.data.ExistingFileHelper; import org.objectweb.asm.Opcodes; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -25,7 +25,7 @@ public void setEFH(ExistingFileHelper efh) { @Redirect(method = "missing(Lnet/minecraft/tags/TagEntry;)Z", at = @At( value = "FIELD", - target = "Lnet/minecraft/data/tags/TagsProvider;existingFileHelper:Lnet/minecraftforge/common/data/ExistingFileHelper;", + target = "Lnet/minecraft/data/tags/TagsProvider;existingFileHelper:Lnet/neoforged/neoforge/common/data/ExistingFileHelper;", opcode = Opcodes.GETFIELD), remap = false) private ExistingFileHelper hex$missingRedirect(TagsProvider instance) { @@ -34,9 +34,9 @@ public void setEFH(ExistingFileHelper efh) { return actualFileHelper; } - @Redirect(method = "lambda$getOrCreateRawBuilder$9(Lnet/minecraft/resources/ResourceLocation;)Lnet/minecraft/tags/TagBuilder;", at = @At( + @Redirect(method = "getOrCreateRawBuilder", at = @At( value = "FIELD", - target = "Lnet/minecraft/data/tags/TagsProvider;existingFileHelper:Lnet/minecraftforge/common/data/ExistingFileHelper;", + target = "Lnet/minecraft/data/tags/TagsProvider;existingFileHelper:Lnet/neoforged/neoforge/common/data/ExistingFileHelper;", opcode = Opcodes.GETFIELD), remap = false) private ExistingFileHelper hex$getOrCreateRawBuilderRedirect(TagsProvider instance) { diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/network/ForgePacketHandler.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/network/ForgePacketHandler.java index 78485aa6f9..5245c0c3a0 100644 --- a/Neoforge/src/main/java/at/petrak/hexcasting/forge/network/ForgePacketHandler.java +++ b/Neoforge/src/main/java/at/petrak/hexcasting/forge/network/ForgePacketHandler.java @@ -1,82 +1,69 @@ package at.petrak.hexcasting.forge.network; import at.petrak.hexcasting.common.msgs.*; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; -import net.minecraftforge.network.NetworkEvent; -import net.minecraftforge.network.NetworkRegistry; -import net.minecraftforge.network.simple.SimpleChannel; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent; +import net.neoforged.neoforge.network.handling.IPayloadHandler; +import net.neoforged.neoforge.network.registration.PayloadRegistrar; import org.apache.logging.log4j.util.TriConsumer; -import java.util.function.BiConsumer; import java.util.function.Consumer; -import java.util.function.Supplier; - -import static at.petrak.hexcasting.api.HexAPI.modLoc; public class ForgePacketHandler { - private static final String PROTOCOL_VERSION = "1"; - private static final SimpleChannel NETWORK = NetworkRegistry.newSimpleChannel( - modLoc("main"), - () -> PROTOCOL_VERSION, - PROTOCOL_VERSION::equals, - PROTOCOL_VERSION::equals - ); - - public static SimpleChannel getNetwork() { - return NETWORK; - } - public static void init() { - int messageIdx = 0; + public static void init(IEventBus modBus) { + modBus.addListener(RegisterPayloadHandlersEvent.class, ev -> { + final PayloadRegistrar registar = ev.registrar("1"); - // Client -> server - NETWORK.registerMessage(messageIdx++, MsgNewSpellPatternC2S.class, MsgNewSpellPatternC2S::serialize, - MsgNewSpellPatternC2S::deserialize, makeServerBoundHandler(MsgNewSpellPatternC2S::handle)); - NETWORK.registerMessage(messageIdx++, MsgShiftScrollC2S.class, MsgShiftScrollC2S::serialize, - MsgShiftScrollC2S::deserialize, makeServerBoundHandler(MsgShiftScrollC2S::handle)); + // Client -> server + registar.playToServer(MsgNewSpellPatternC2S.TYPE, MsgNewSpellPatternC2S.STREAM_CODEC, + makeServerBoundHandler(MsgNewSpellPatternC2S::handle)); + registar.playToServer(MsgShiftScrollC2S.TYPE, MsgShiftScrollC2S.STREAM_CODEC, + makeServerBoundHandler(MsgShiftScrollC2S::handle)); - // Server -> client - NETWORK.registerMessage(messageIdx++, MsgNewSpellPatternS2C.class, MsgNewSpellPatternS2C::serialize, - MsgNewSpellPatternS2C::deserialize, makeClientBoundHandler(MsgNewSpellPatternS2C::handle)); - NETWORK.registerMessage(messageIdx++, MsgBlinkS2C.class, MsgBlinkS2C::serialize, - MsgBlinkS2C::deserialize, makeClientBoundHandler(MsgBlinkS2C::handle)); - NETWORK.registerMessage(messageIdx++, MsgSentinelStatusUpdateAck.class, MsgSentinelStatusUpdateAck::serialize, - MsgSentinelStatusUpdateAck::deserialize, makeClientBoundHandler(MsgSentinelStatusUpdateAck::handle)); - NETWORK.registerMessage(messageIdx++, MsgPigmentUpdateAck.class, MsgPigmentUpdateAck::serialize, - MsgPigmentUpdateAck::deserialize, makeClientBoundHandler(MsgPigmentUpdateAck::handle)); - NETWORK.registerMessage(messageIdx++, MsgAltioraUpdateAck.class, MsgAltioraUpdateAck::serialize, - MsgAltioraUpdateAck::deserialize, makeClientBoundHandler(MsgAltioraUpdateAck::handle)); - NETWORK.registerMessage(messageIdx++, MsgCastParticleS2C.class, MsgCastParticleS2C::serialize, - MsgCastParticleS2C::deserialize, makeClientBoundHandler(MsgCastParticleS2C::handle)); - NETWORK.registerMessage(messageIdx++, MsgOpenSpellGuiS2C.class, MsgOpenSpellGuiS2C::serialize, - MsgOpenSpellGuiS2C::deserialize, makeClientBoundHandler(MsgOpenSpellGuiS2C::handle)); - NETWORK.registerMessage(messageIdx++, MsgBeepS2C.class, MsgBeepS2C::serialize, - MsgBeepS2C::deserialize, makeClientBoundHandler(MsgBeepS2C::handle)); - NETWORK.registerMessage(messageIdx++, MsgBrainsweepAck.class, MsgBrainsweepAck::serialize, - MsgBrainsweepAck::deserialize, makeClientBoundHandler(MsgBrainsweepAck::handle)); - NETWORK.registerMessage(messageIdx++, MsgNewWallScrollS2C.class, MsgNewWallScrollS2C::serialize, - MsgNewWallScrollS2C::deserialize, makeClientBoundHandler(MsgNewWallScrollS2C::handle)); - NETWORK.registerMessage(messageIdx++, MsgRecalcWallScrollDisplayS2C.class, MsgRecalcWallScrollDisplayS2C::serialize, - MsgRecalcWallScrollDisplayS2C::deserialize, makeClientBoundHandler(MsgRecalcWallScrollDisplayS2C::handle)); - NETWORK.registerMessage(messageIdx++, MsgNewSpiralPatternsS2C.class, MsgNewSpiralPatternsS2C::serialize, - MsgNewSpiralPatternsS2C::deserialize, makeClientBoundHandler(MsgNewSpiralPatternsS2C::handle)); - NETWORK.registerMessage(messageIdx++, MsgClearSpiralPatternsS2C.class, MsgClearSpiralPatternsS2C::serialize, - MsgClearSpiralPatternsS2C::deserialize, makeClientBoundHandler(MsgClearSpiralPatternsS2C::handle)); + // Server -> client + registar.playToClient(MsgNewSpellPatternS2C.TYPE, MsgNewSpellPatternS2C.STREAM_CODEC, + makeClientBoundHandler(MsgNewSpellPatternS2C::handle)); + registar.playToClient(MsgBlinkS2C.TYPE, MsgBlinkS2C.STREAM_CODEC, + makeClientBoundHandler(MsgBlinkS2C::handle)); + registar.playToClient(MsgSentinelStatusUpdateAck.TYPE, MsgSentinelStatusUpdateAck.STREAM_CODEC, + makeClientBoundHandler(MsgSentinelStatusUpdateAck::handle)); + registar.playToClient(MsgPigmentUpdateAck.TYPE, MsgPigmentUpdateAck.STREAM_CODEC, + makeClientBoundHandler(MsgPigmentUpdateAck::handle)); + registar.playToClient(MsgAltioraUpdateAck.TYPE, MsgAltioraUpdateAck.STREAM_CODEC, + makeClientBoundHandler(MsgAltioraUpdateAck::handle)); + registar.playToClient(MsgCastParticleS2C.TYPE, MsgCastParticleS2C.STREAM_CODEC, + makeClientBoundHandler(MsgCastParticleS2C::handle)); + registar.playToClient(MsgOpenSpellGuiS2C.TYPE, MsgOpenSpellGuiS2C.STREAM_CODEC, + makeClientBoundHandler(MsgOpenSpellGuiS2C::handle)); + registar.playToClient(MsgBeepS2C.TYPE, MsgBeepS2C.STREAM_CODEC, + makeClientBoundHandler(MsgBeepS2C::handle)); + registar.playToClient(MsgBrainsweepAck.TYPE, MsgBrainsweepAck.STREAM_CODEC, + makeClientBoundHandler(MsgBrainsweepAck::handle)); + registar.playToClient(MsgNewWallScrollS2C.TYPE, MsgNewWallScrollS2C.STREAM_CODEC, + makeClientBoundHandler(MsgNewWallScrollS2C::handle)); + registar.playToClient(MsgRecalcWallScrollDisplayS2C.TYPE, MsgRecalcWallScrollDisplayS2C.STREAM_CODEC, + makeClientBoundHandler(MsgRecalcWallScrollDisplayS2C::handle)); + registar.playToClient(MsgNewSpiralPatternsS2C.TYPE, MsgNewSpiralPatternsS2C.STREAM_CODEC, + makeClientBoundHandler(MsgNewSpiralPatternsS2C::handle)); + registar.playToClient(MsgClearSpiralPatternsS2C.TYPE, MsgClearSpiralPatternsS2C.STREAM_CODEC, + makeClientBoundHandler(MsgClearSpiralPatternsS2C::handle)); + }); } - private static BiConsumer> makeServerBoundHandler( + private static IPayloadHandler makeServerBoundHandler( TriConsumer handler) { return (m, ctx) -> { - handler.accept(m, ctx.get().getSender().getServer(), ctx.get().getSender()); - ctx.get().setPacketHandled(true); + handler.accept(m, ctx.player().getServer(), (ServerPlayer) ctx.player()); }; } - private static BiConsumer> makeClientBoundHandler(Consumer consumer) { + private static IPayloadHandler makeClientBoundHandler(Consumer consumer) { return (m, ctx) -> { consumer.accept(m); - ctx.get().setPacketHandled(true); }; } } diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/network/MsgAltioraUpdateAck.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/network/MsgAltioraUpdateAck.java index 0e932b55ea..b3934d0342 100644 --- a/Neoforge/src/main/java/at/petrak/hexcasting/forge/network/MsgAltioraUpdateAck.java +++ b/Neoforge/src/main/java/at/petrak/hexcasting/forge/network/MsgAltioraUpdateAck.java @@ -1,51 +1,38 @@ package at.petrak.hexcasting.forge.network; +import at.petrak.hexcasting.api.HexAPI; import at.petrak.hexcasting.api.player.AltioraAbility; -import at.petrak.hexcasting.common.msgs.IMessage; import at.petrak.hexcasting.xplat.IXplatAbstractions; -import io.netty.buffer.ByteBuf; import net.minecraft.client.Minecraft; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import org.jetbrains.annotations.Nullable; -import static at.petrak.hexcasting.api.HexAPI.modLoc; +import java.util.Optional; -public record MsgAltioraUpdateAck(@Nullable AltioraAbility altiora) implements IMessage { - public static final ResourceLocation ID = modLoc("altiora"); +public record MsgAltioraUpdateAck(@Nullable AltioraAbility altiora) implements CustomPacketPayload { + public static final CustomPacketPayload.Type TYPE = new CustomPacketPayload.Type<>(HexAPI.modLoc("altiora")); - @Override - public ResourceLocation getFabricId() { - return ID; - } - - public static MsgAltioraUpdateAck deserialize(ByteBuf buffer) { - var buf = new FriendlyByteBuf(buffer); - - var extant = buf.readBoolean(); - if (!extant) { - return new MsgAltioraUpdateAck(null); - } - var grace = buf.readVarInt(); - return new MsgAltioraUpdateAck(new AltioraAbility(grace)); - } + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.optional(AltioraAbility.STREAM_CODEC).map( + opt -> opt.orElse(null), + Optional::ofNullable + ), MsgAltioraUpdateAck::altiora, + MsgAltioraUpdateAck::new + ); @Override - public void serialize(FriendlyByteBuf buf) { - buf.writeBoolean(this.altiora != null); - if (this.altiora != null) { - buf.writeVarInt(this.altiora.gracePeriod()); - } + public CustomPacketPayload.Type type() { + return TYPE; } public static void handle(MsgAltioraUpdateAck self) { - Minecraft.getInstance().execute(new Runnable() { - @Override - public void run() { - var player = Minecraft.getInstance().player; - if (player != null) { - IXplatAbstractions.INSTANCE.setAltiora(player, self.altiora); - } + Minecraft.getInstance().execute(() -> { + var player = Minecraft.getInstance().player; + if (player != null) { + IXplatAbstractions.INSTANCE.setAltiora(player, self.altiora); } }); } diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/network/MsgBrainsweepAck.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/network/MsgBrainsweepAck.java index c9d24606fc..4471de9948 100644 --- a/Neoforge/src/main/java/at/petrak/hexcasting/forge/network/MsgBrainsweepAck.java +++ b/Neoforge/src/main/java/at/petrak/hexcasting/forge/network/MsgBrainsweepAck.java @@ -1,37 +1,38 @@ package at.petrak.hexcasting.forge.network; +import at.petrak.hexcasting.api.HexAPI; +import at.petrak.hexcasting.api.player.Sentinel; import at.petrak.hexcasting.common.msgs.IMessage; import at.petrak.hexcasting.xplat.IXplatAbstractions; import io.netty.buffer.ByteBuf; import net.minecraft.client.Minecraft; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Mob; +import java.util.Optional; + import static at.petrak.hexcasting.api.HexAPI.modLoc; /** * Sent server->client to synchronize the status of a brainswept mob. */ -public record MsgBrainsweepAck(int target) implements IMessage { - public static final ResourceLocation ID = modLoc("sweep"); - - @Override - public ResourceLocation getFabricId() { - return ID; - } - - public static MsgBrainsweepAck deserialize(ByteBuf buffer) { - var buf = new FriendlyByteBuf(buffer); +public record MsgBrainsweepAck(int target) implements CustomPacketPayload { + public static final CustomPacketPayload.Type TYPE = new CustomPacketPayload.Type<>(HexAPI.modLoc("sweep")); - var target = buf.readInt(); - return new MsgBrainsweepAck(target); - } + public static final StreamCodec STREAM_CODEC = ByteBufCodecs.INT.map( + MsgBrainsweepAck::new, + MsgBrainsweepAck::target + ).mapStream(b -> b); @Override - public void serialize(FriendlyByteBuf buf) { - buf.writeInt(target); + public CustomPacketPayload.Type type() { + return TYPE; } public static MsgBrainsweepAck of(Entity target) { @@ -39,15 +40,12 @@ public static MsgBrainsweepAck of(Entity target) { } public static void handle(MsgBrainsweepAck msg) { - Minecraft.getInstance().execute(new Runnable() { - @Override - public void run() { - var level = Minecraft.getInstance().level; - if (level != null) { - Entity entity = level.getEntity(msg.target()); - if (entity instanceof Mob living) { - IXplatAbstractions.INSTANCE.setBrainsweepAddlData(living); - } + Minecraft.getInstance().execute(() -> { + var level = Minecraft.getInstance().level; + if (level != null) { + Entity entity = level.getEntity(msg.target()); + if (entity instanceof Mob living) { + IXplatAbstractions.INSTANCE.setBrainsweepAddlData(living); } } }); diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/network/MsgPigmentUpdateAck.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/network/MsgPigmentUpdateAck.java index c38266b1ae..77e413b16f 100644 --- a/Neoforge/src/main/java/at/petrak/hexcasting/forge/network/MsgPigmentUpdateAck.java +++ b/Neoforge/src/main/java/at/petrak/hexcasting/forge/network/MsgPigmentUpdateAck.java @@ -1,11 +1,17 @@ package at.petrak.hexcasting.forge.network; +import at.petrak.hexcasting.api.HexAPI; import at.petrak.hexcasting.api.pigment.FrozenPigment; import at.petrak.hexcasting.common.msgs.IMessage; +import at.petrak.hexcasting.common.msgs.MsgBlinkS2C; import at.petrak.hexcasting.xplat.IXplatAbstractions; +import at.petrak.paucal.api.PaucalCodecs; import io.netty.buffer.ByteBuf; import net.minecraft.client.Minecraft; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.resources.ResourceLocation; import static at.petrak.hexcasting.api.HexAPI.modLoc; @@ -13,35 +19,24 @@ /** * Sent server->client to synchronize the status of the sentinel. */ -public record MsgPigmentUpdateAck(FrozenPigment update) implements IMessage { - public static final ResourceLocation ID = modLoc("color"); +public record MsgPigmentUpdateAck(FrozenPigment update) implements CustomPacketPayload { + public static final CustomPacketPayload.Type TYPE = new CustomPacketPayload.Type<>(HexAPI.modLoc("color")); - @Override - public ResourceLocation getFabricId() { - return ID; - } - - public static MsgPigmentUpdateAck deserialize(ByteBuf buffer) { - var buf = new FriendlyByteBuf(buffer); - - var tag = buf.readAnySizeNbt(); - var colorizer = FrozenPigment.fromNBT(tag); - return new MsgPigmentUpdateAck(colorizer); - } + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + FrozenPigment.STREAM_CODEC, MsgPigmentUpdateAck::update, + MsgPigmentUpdateAck::new + ); @Override - public void serialize(FriendlyByteBuf buf) { - buf.writeNbt(this.update.serializeToNBT()); + public CustomPacketPayload.Type type() { + return TYPE; } public static void handle(MsgPigmentUpdateAck self) { - Minecraft.getInstance().execute(new Runnable() { - @Override - public void run() { - var player = Minecraft.getInstance().player; - if (player != null) { - IXplatAbstractions.INSTANCE.setPigment(player, self.update()); - } + Minecraft.getInstance().execute(() -> { + var player = Minecraft.getInstance().player; + if (player != null) { + IXplatAbstractions.INSTANCE.setPigment(player, self.update()); } }); } diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/network/MsgSentinelStatusUpdateAck.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/network/MsgSentinelStatusUpdateAck.java index dc8f712d8e..f0971773ae 100644 --- a/Neoforge/src/main/java/at/petrak/hexcasting/forge/network/MsgSentinelStatusUpdateAck.java +++ b/Neoforge/src/main/java/at/petrak/hexcasting/forge/network/MsgSentinelStatusUpdateAck.java @@ -1,70 +1,53 @@ package at.petrak.hexcasting.forge.network; +import at.petrak.hexcasting.api.HexAPI; import at.petrak.hexcasting.api.player.Sentinel; import at.petrak.hexcasting.common.msgs.IMessage; +import at.petrak.hexcasting.common.msgs.MsgBlinkS2C; import at.petrak.hexcasting.xplat.IXplatAbstractions; +import at.petrak.paucal.api.PaucalCodecs; import io.netty.buffer.ByteBuf; import net.minecraft.client.Minecraft; import net.minecraft.core.registries.Registries; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.phys.Vec3; import javax.annotation.Nullable; +import java.util.Optional; + import static at.petrak.hexcasting.api.HexAPI.modLoc; /** * Sent server->client to synchronize the status of the sentinel. */ -public record MsgSentinelStatusUpdateAck(@Nullable Sentinel update) implements IMessage { - public static final ResourceLocation ID = modLoc("sntnl"); - - @Override - public ResourceLocation getFabricId() { - return ID; - } - - public static MsgSentinelStatusUpdateAck deserialize(ByteBuf buffer) { - var buf = new FriendlyByteBuf(buffer); +public record MsgSentinelStatusUpdateAck(@Nullable Sentinel update) implements CustomPacketPayload { + public static final CustomPacketPayload.Type TYPE = new CustomPacketPayload.Type<>(HexAPI.modLoc("sntnl")); - var exists = buf.readBoolean(); - if (!exists) { - return new MsgSentinelStatusUpdateAck(null); - } + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.optional(Sentinel.STREAM_CODEC).map( + opt -> opt.orElse(null), + Optional::ofNullable + ), MsgSentinelStatusUpdateAck::update, + MsgSentinelStatusUpdateAck::new + ); - var greater = buf.readBoolean(); - var origin = new Vec3(buf.readDouble(), buf.readDouble(), buf.readDouble()); - var dimension = ResourceKey.create(Registries.DIMENSION, buf.readResourceLocation()); - - var sentinel = new Sentinel(greater, origin, dimension); - return new MsgSentinelStatusUpdateAck(sentinel); - } - - public void serialize(FriendlyByteBuf buf) { - if (update == null) { - buf.writeBoolean(false); - return; - } - - buf.writeBoolean(true); - buf.writeBoolean(update.extendsRange()); - buf.writeDouble(update.position().x); - buf.writeDouble(update.position().y); - buf.writeDouble(update.position().z); - buf.writeResourceLocation(update.dimension().location()); + @Override + public CustomPacketPayload.Type type() { + return TYPE; } public static void handle(MsgSentinelStatusUpdateAck self) { - //noinspection Convert2Lambda - Minecraft.getInstance().execute(new Runnable() { - @Override - public void run() { - var player = Minecraft.getInstance().player; - if (player != null) { - IXplatAbstractions.INSTANCE.setSentinel(player, self.update()); - } + Minecraft.getInstance().execute(() -> { + var player = Minecraft.getInstance().player; + if (player != null) { + IXplatAbstractions.INSTANCE.setSentinel(player, self.update()); } }); } diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/recipe/ForgeModConditionalIngredient.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/recipe/ForgeModConditionalIngredient.java index 0969291d47..2d82273ca8 100644 --- a/Neoforge/src/main/java/at/petrak/hexcasting/forge/recipe/ForgeModConditionalIngredient.java +++ b/Neoforge/src/main/java/at/petrak/hexcasting/forge/recipe/ForgeModConditionalIngredient.java @@ -1,25 +1,43 @@ package at.petrak.hexcasting.forge.recipe; +import at.petrak.hexcasting.forge.lib.ForgeHexIngredientTypes; import at.petrak.hexcasting.xplat.IXplatAbstractions; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParseException; +import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.Ingredient; -import net.minecraftforge.common.crafting.AbstractIngredient; -import net.minecraftforge.common.crafting.IIngredientSerializer; +import net.neoforged.neoforge.common.crafting.ICustomIngredient; +import net.neoforged.neoforge.common.crafting.IngredientType; import org.jetbrains.annotations.NotNull; import javax.annotation.Nullable; import java.util.Arrays; import java.util.Objects; +import java.util.stream.Stream; import static at.petrak.hexcasting.api.HexAPI.modLoc; -public class ForgeModConditionalIngredient extends AbstractIngredient { - public static final ResourceLocation ID = modLoc("mod_conditional"); +public class ForgeModConditionalIngredient implements ICustomIngredient { + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(inst -> inst.group( + Ingredient.CODEC.fieldOf("if_loaded").forGetter(ForgeModConditionalIngredient::getMain), + Codec.STRING.fieldOf("modid").forGetter(ForgeModConditionalIngredient::getModid), + Ingredient.CODEC.fieldOf("default").forGetter(ForgeModConditionalIngredient::getIfModLoaded) + ).apply(inst, ForgeModConditionalIngredient::of)); + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + Ingredient.CONTENTS_STREAM_CODEC, ForgeModConditionalIngredient::getMain, + ByteBufCodecs.STRING_UTF8, ForgeModConditionalIngredient::getModid, + Ingredient.CONTENTS_STREAM_CODEC, ForgeModConditionalIngredient::getIfModLoaded, + ForgeModConditionalIngredient::new + ); private final Ingredient main; private final String modid; @@ -28,14 +46,28 @@ public class ForgeModConditionalIngredient extends AbstractIngredient { private final Ingredient toUse; protected ForgeModConditionalIngredient(Ingredient main, String modid, Ingredient ifModLoaded) { - super(IXplatAbstractions.INSTANCE.isModPresent(modid) ? Arrays.stream(ifModLoaded.values) : Arrays.stream(main.values)); this.main = main; this.modid = modid; this.ifModLoaded = ifModLoaded; - this.toUse = IXplatAbstractions.INSTANCE.isModPresent(modid) ? ifModLoaded : main; } + public String getModid() { + return modid; + } + + public Ingredient getMain() { + return main; + } + + public Ingredient getIfModLoaded() { + return ifModLoaded; + } + + public Ingredient getToUse() { + return toUse; + } + /** * Creates a new ingredient matching the given stack */ @@ -49,66 +81,17 @@ public boolean test(@Nullable ItemStack input) { } @Override - public boolean isSimple() { - return toUse.isSimple(); + public Stream getItems() { + return Arrays.stream(toUse.getItems()); } @Override - public @NotNull JsonElement toJson() { - JsonObject json = new JsonObject(); - json.addProperty("type", Objects.toString(ID)); - json.add("default", main.toJson()); - json.addProperty("modid", modid); - json.add("if_loaded", ifModLoaded.toJson()); - return json; + public boolean isSimple() { + return toUse.isSimple(); } @Override - public @NotNull IIngredientSerializer getSerializer() { - return Serializer.INSTANCE; - } - - public static @NotNull Ingredient fromNetwork(FriendlyByteBuf friendlyByteBuf) { - return Ingredient.fromNetwork(friendlyByteBuf); // Just send the actual ingredient - } - - public static Ingredient fromJson(JsonObject object) { - if (object.has("type") && object.getAsJsonPrimitive("type").getAsString().equals(ID.toString())) { - if (object.has("modid") && IXplatAbstractions.INSTANCE.isModPresent(object.getAsJsonPrimitive("modid").getAsString())) { - try { - Ingredient ingredient = Ingredient.fromJson(object.get("if_loaded")); - if (!ingredient.isEmpty()) { - return ingredient; - } - } catch (JsonParseException e) { - // NO-OP - } - } - - return Ingredient.fromJson(object.get("default")); - } - - return Ingredient.of(); - } - - public static class Serializer implements IIngredientSerializer { - public static final Serializer INSTANCE = new Serializer(); - - @Override - public @NotNull Ingredient parse(@NotNull FriendlyByteBuf buffer) { - return fromNetwork(buffer); - } - - @Override - public @NotNull Ingredient parse(@NotNull JsonObject json) { - return fromJson(json); - } - - @Override - public void write(@NotNull FriendlyByteBuf buffer, @NotNull Ingredient ingredient) { - if (ingredient instanceof ForgeModConditionalIngredient conditionalIngredient) - conditionalIngredient.toUse.toNetwork(buffer); - // It shouldn't be possible to not be a ForgeModConditionalIngredient here - } + public IngredientType getType() { + return ForgeHexIngredientTypes.MOD_CONDITIONAL_INGREDIENT.get(); } } diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/recipe/ForgeUnsealedIngredient.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/recipe/ForgeUnsealedIngredient.java index 434104aa9b..f0f77e1cce 100644 --- a/Neoforge/src/main/java/at/petrak/hexcasting/forge/recipe/ForgeUnsealedIngredient.java +++ b/Neoforge/src/main/java/at/petrak/hexcasting/forge/recipe/ForgeUnsealedIngredient.java @@ -4,42 +4,56 @@ import at.petrak.hexcasting.api.casting.iota.NullIota; import at.petrak.hexcasting.api.item.IotaHolderItem; import at.petrak.hexcasting.api.utils.NBTHelper; +import at.petrak.hexcasting.common.lib.HexDataComponents; +import at.petrak.hexcasting.forge.lib.ForgeHexIngredientTypes; import at.petrak.hexcasting.xplat.IXplatAbstractions; import com.google.gson.JsonElement; import com.google.gson.JsonObject; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.Unit; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.Ingredient; -import net.minecraftforge.common.crafting.AbstractIngredient; -import net.minecraftforge.common.crafting.CraftingHelper; -import net.minecraftforge.common.crafting.IIngredientSerializer; -import net.minecraftforge.common.crafting.PartialNBTIngredient; -import net.minecraftforge.registries.ForgeRegistries; +import net.neoforged.neoforge.common.crafting.ICustomIngredient; +import net.neoforged.neoforge.common.crafting.IngredientType; import org.jetbrains.annotations.NotNull; import javax.annotation.Nullable; import java.util.Objects; +import java.util.Optional; import java.util.stream.Stream; import static at.petrak.hexcasting.api.HexAPI.modLoc; -public class ForgeUnsealedIngredient extends AbstractIngredient { - public static final ResourceLocation ID = modLoc("unsealed"); +public class ForgeUnsealedIngredient implements ICustomIngredient { + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(inst -> inst.group( + ItemStack.CODEC.fieldOf("stack").forGetter(ForgeUnsealedIngredient::getStack) + ).apply(inst, ForgeUnsealedIngredient::new)); + public static final StreamCodec STREAM_CODEC = ItemStack.STREAM_CODEC.map( + ForgeUnsealedIngredient::of, + ForgeUnsealedIngredient::getStack + ); private final ItemStack stack; private static ItemStack createStack(ItemStack base) { ItemStack newStack = base.copy(); - NBTHelper.putString(newStack, IotaHolderItem.TAG_OVERRIDE_VISUALLY, "any"); + base.set(HexDataComponents.VISUAL_OVERRIDE, Optional.empty()); return newStack; } protected ForgeUnsealedIngredient(ItemStack stack) { - super(Stream.of(new Ingredient.ItemValue(createStack(stack)))); this.stack = stack; } + public ItemStack getStack() { + return stack; + } + /** * Creates a new ingredient matching the given stack */ @@ -55,7 +69,7 @@ public boolean test(@Nullable ItemStack input) { if (this.stack.getItem() == input.getItem() && this.stack.getDamageValue() == input.getDamageValue()) { ADIotaHolder holder = IXplatAbstractions.INSTANCE.findDataHolder(this.stack); if (holder != null) { - return holder.readIotaTag() != null && holder.writeIota(new NullIota(), true); + return holder.readIota() != null && holder.writeIota(NullIota.INSTANCE, true); } } @@ -63,41 +77,17 @@ public boolean test(@Nullable ItemStack input) { } @Override - public boolean isSimple() { - return false; + public Stream getItems() { + return Stream.of(createStack(stack)); } @Override - public @NotNull IIngredientSerializer getSerializer() { - return ForgeUnsealedIngredient.Serializer.INSTANCE; + public boolean isSimple() { + return false; } @Override - public @NotNull JsonElement toJson() { - JsonObject json = new JsonObject(); - // TODO: should this be Partial or Strict - json.addProperty("type", Objects.toString(CraftingHelper.getID(PartialNBTIngredient.Serializer.INSTANCE))); - json.addProperty("item", Objects.toString(ForgeRegistries.ITEMS.getKey(stack.getItem()))); - return json; - } - - - public static class Serializer implements IIngredientSerializer { - public static final ForgeUnsealedIngredient.Serializer INSTANCE = new ForgeUnsealedIngredient.Serializer(); - - @Override - public @NotNull ForgeUnsealedIngredient parse(FriendlyByteBuf buffer) { - return new ForgeUnsealedIngredient(buffer.readItem()); - } - - @Override - public @NotNull ForgeUnsealedIngredient parse(@NotNull JsonObject json) { - return new ForgeUnsealedIngredient(CraftingHelper.getItemStack(json, true)); - } - - @Override - public void write(FriendlyByteBuf buffer, ForgeUnsealedIngredient ingredient) { - buffer.writeItem(ingredient.stack); - } + public IngredientType getType() { + return ForgeHexIngredientTypes.UNSEALED_INGREDIENT.get(); } } diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/xplat/ForgeClientXplatImpl.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/xplat/ForgeClientXplatImpl.java index d33c2654b0..0419b3c49a 100644 --- a/Neoforge/src/main/java/at/petrak/hexcasting/forge/xplat/ForgeClientXplatImpl.java +++ b/Neoforge/src/main/java/at/petrak/hexcasting/forge/xplat/ForgeClientXplatImpl.java @@ -1,9 +1,7 @@ package at.petrak.hexcasting.forge.xplat; import at.petrak.hexcasting.api.client.ClientCastingStack; -import at.petrak.hexcasting.common.msgs.IMessage; -import at.petrak.hexcasting.forge.cap.HexCapabilities; -import at.petrak.hexcasting.forge.network.ForgePacketHandler; +import at.petrak.hexcasting.forge.lib.ForgeHexAttachments; import at.petrak.hexcasting.xplat.IClientXplatAbstractions; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.entity.EntityRendererProvider; @@ -11,6 +9,7 @@ import net.minecraft.client.renderer.item.ItemProperties; import net.minecraft.client.renderer.item.ItemPropertyFunction; import net.minecraft.client.renderer.texture.AbstractTexture; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; @@ -18,11 +17,12 @@ import net.minecraft.world.item.Item; import net.minecraft.world.level.block.Block; import net.minecraft.world.phys.AABB; +import net.neoforged.neoforge.network.PacketDistributor; public class ForgeClientXplatImpl implements IClientXplatAbstractions { @Override - public void sendPacketToServer(IMessage packet) { - ForgePacketHandler.getNetwork().sendToServer(packet); + public void sendPacketToServer(CustomPacketPayload packet) { + PacketDistributor.sendToServer(packet); } @Override @@ -49,10 +49,7 @@ public void registerItemProperty(Item item, ResourceLocation id, ItemPropertyFun @Override public ClientCastingStack getClientCastingStack(Player player) { - var maybeCap = player.getCapability(HexCapabilities.CLIENT_CASTING_STACK).resolve(); - if (maybeCap.isEmpty()) - return new ClientCastingStack(); // lie - return maybeCap.get().get(); + return player.getData(ForgeHexAttachments.CLIENT_CASTING_STACK); } @Override diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/xplat/ForgeRegister.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/xplat/ForgeRegister.java new file mode 100644 index 0000000000..b4c7dd9f0e --- /dev/null +++ b/Neoforge/src/main/java/at/petrak/hexcasting/forge/xplat/ForgeRegister.java @@ -0,0 +1,31 @@ +package at.petrak.hexcasting.forge.xplat; + +import at.petrak.hexcasting.forge.ForgeHexInitializer; +import at.petrak.hexcasting.xplat.IXplatRegister; +import net.minecraft.core.Holder; +import net.neoforged.neoforge.registries.DeferredRegister; + +import java.util.function.Supplier; + +public class ForgeRegister implements IXplatRegister { + private final DeferredRegister register; + + public ForgeRegister(DeferredRegister register) { + this.register = register; + } + + @Override + public void registerAll() { + register.register(ForgeHexInitializer.getModEventBus()); + } + + @Override + public Supplier register(String id, Supplier provider) { + return register.register(id, provider); + } + + @Override + public Holder registerHolder(String id, Supplier provider) { + return register.register(id, provider); + } +} diff --git a/Neoforge/src/main/java/at/petrak/hexcasting/forge/xplat/ForgeXplatImpl.java b/Neoforge/src/main/java/at/petrak/hexcasting/forge/xplat/ForgeXplatImpl.java index 9d9188599d..9410eecac3 100644 --- a/Neoforge/src/main/java/at/petrak/hexcasting/forge/xplat/ForgeXplatImpl.java +++ b/Neoforge/src/main/java/at/petrak/hexcasting/forge/xplat/ForgeXplatImpl.java @@ -1,5 +1,6 @@ package at.petrak.hexcasting.forge.xplat; +import at.petrak.hexcasting.api.HexAPI; import at.petrak.hexcasting.api.addldata.ADHexHolder; import at.petrak.hexcasting.api.addldata.ADIotaHolder; import at.petrak.hexcasting.api.addldata.ADMediaHolder; @@ -22,31 +23,29 @@ import at.petrak.hexcasting.api.player.Sentinel; import at.petrak.hexcasting.api.utils.HexUtils; import at.petrak.hexcasting.common.lib.HexRegistries; -import at.petrak.hexcasting.common.lib.hex.HexContinuationTypes; -import at.petrak.hexcasting.common.lib.hex.HexEvalSounds; -import at.petrak.hexcasting.common.lib.hex.HexIotaTypes; -import at.petrak.hexcasting.common.msgs.IMessage; +import at.petrak.hexcasting.common.recipe.ingredient.state.StateIngredientType; +import at.petrak.hexcasting.common.recipe.ingredient.brainsweep.BrainsweepeeIngredientType; import at.petrak.hexcasting.forge.cap.CapSyncers; import at.petrak.hexcasting.forge.cap.HexCapabilities; import at.petrak.hexcasting.forge.interop.curios.CuriosApiInterop; -import at.petrak.hexcasting.forge.mixin.ForgeAccessorBuiltInRegistries; -import at.petrak.hexcasting.forge.network.ForgePacketHandler; import at.petrak.hexcasting.forge.network.MsgBrainsweepAck; import at.petrak.hexcasting.forge.recipe.ForgeUnsealedIngredient; import at.petrak.hexcasting.interop.HexInterop; import at.petrak.hexcasting.interop.pehkui.PehkuiInterop; import at.petrak.hexcasting.xplat.IXplatAbstractions; +import at.petrak.hexcasting.xplat.IXplatRegister; import at.petrak.hexcasting.xplat.IXplatTags; import at.petrak.hexcasting.xplat.Platform; -import com.google.common.base.Suppliers; +import com.illusivesoulworks.caelus.api.CaelusApi; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.Registry; import net.minecraft.core.registries.Registries; import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.NbtOps; import net.minecraft.nbt.Tag; import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.network.protocol.game.ClientGamePacketListener; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; @@ -72,35 +71,39 @@ import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.Vec3; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.common.*; -import net.minecraftforge.common.loot.CanToolPerformAction; -import net.minecraftforge.common.util.FakePlayerFactory; -import net.minecraftforge.event.level.BlockEvent; -import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.FluidType; -import net.minecraftforge.fluids.FluidUtil; -import net.minecraftforge.fluids.capability.IFluidHandler; -import net.minecraftforge.fml.ModContainer; -import net.minecraftforge.fml.ModList; -import net.minecraftforge.fml.loading.FMLLoader; -import net.minecraftforge.network.NetworkDirection; -import net.minecraftforge.network.PacketDistributor; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.fml.ModContainer; +import net.neoforged.fml.ModList; +import net.neoforged.fml.loading.FMLLoader; +import net.neoforged.neoforge.common.CommonHooks; +import net.neoforged.neoforge.common.ItemAbilities; +import net.neoforged.neoforge.common.NeoForge; +import net.neoforged.neoforge.common.loot.CanItemPerformAbility; +import net.neoforged.neoforge.common.util.FakePlayerFactory; +import net.neoforged.neoforge.event.level.BlockEvent; +import net.neoforged.neoforge.fluids.FluidStack; +import net.neoforged.neoforge.fluids.FluidType; +import net.neoforged.neoforge.fluids.FluidUtil; +import net.neoforged.neoforge.fluids.capability.IFluidHandler; +import net.neoforged.neoforge.network.PacketDistributor; +import net.neoforged.neoforge.registries.DeferredRegister; +import net.neoforged.neoforge.registries.RegistryBuilder; import org.jetbrains.annotations.Nullable; -import top.theillusivec4.caelus.api.CaelusApi; import virtuoel.pehkui.api.ScaleTypes; -import java.util.ArrayList; import java.util.List; import java.util.Optional; -import java.util.UUID; import java.util.function.BiFunction; -import java.util.function.Supplier; import static at.petrak.hexcasting.api.HexAPI.modLoc; -import static net.minecraftforge.fluids.capability.IFluidHandler.FluidAction.EXECUTE; public class ForgeXplatImpl implements IXplatAbstractions { + + @Override + public IXplatRegister createRegistar(ResourceKey> registryKey) { + return new ForgeRegister<>(DeferredRegister.create(registryKey, HexAPI.MOD_ID)); + } + @Override public Platform platform() { return Platform.FORGE; @@ -133,8 +136,7 @@ public void setBrainsweepAddlData(Mob mob) { mob.getPersistentData().putBoolean(TAG_BRAINSWEPT, true); if (mob.level() instanceof ServerLevel) { - ForgePacketHandler.getNetwork() - .send(PacketDistributor.TRACKING_ENTITY.with(() -> mob), MsgBrainsweepAck.of(mob)); + PacketDistributor.sendToPlayersTrackingEntity(mob, MsgBrainsweepAck.of(mob)); } } @@ -166,15 +168,17 @@ public void setAltiora(Player player, @Nullable AltioraAbility altiora) { } // The elytra ability is done with an event on fabric - var elytraing = CaelusApi.getInstance().getFlightAttribute(); + // TODO port: added null check, test if still works + var elytraing = CaelusApi.getInstance().getFallFlyingAttribute(); var inst = player.getAttributes().getInstance(elytraing); if (altiora != null) { - if (inst.getModifier(ALTIORA_ATTRIBUTE_ID) == null) { - inst.addTransientModifier(new AttributeModifier(ALTIORA_ATTRIBUTE_ID, "Altiora", 1.0, - AttributeModifier.Operation.ADDITION)); + if (inst != null && !inst.hasModifier(ALTIORA_ATTRIBUTE_ID)) { + inst.addTransientModifier(new AttributeModifier(ALTIORA_ATTRIBUTE_ID, 1.0, + AttributeModifier.Operation.ADD_VALUE)); } } else { - inst.removeModifier(ALTIORA_ATTRIBUTE_ID); + if(inst != null) + inst.removeModifier(ALTIORA_ATTRIBUTE_ID); } if (player instanceof ServerPlayer serverPlayer) { @@ -188,7 +192,7 @@ public void setAltiora(Player player, @Nullable AltioraAbility altiora) { CompoundTag tag = player.getPersistentData(); if (pigment != null) - tag.put(TAG_PIGMENT, pigment.serializeToNBT()); + tag.put(TAG_PIGMENT, FrozenPigment.CODEC.encodeStart(NbtOps.INSTANCE, pigment).getOrThrow()); else tag.remove(TAG_PIGMENT); @@ -220,16 +224,12 @@ public void setSentinel(Player player, @Nullable Sentinel sentinel) { @Override public void setStaffcastImage(ServerPlayer player, @Nullable CastingImage image) { - player.getPersistentData().put(TAG_HARNESS, image == null ? new CompoundTag() : image.serializeToNbt()); + player.getPersistentData().put(TAG_VM, image == null ? new CompoundTag() : CastingImage.getCODEC().encodeStart(NbtOps.INSTANCE, image).getOrThrow()); } @Override public void setPatterns(ServerPlayer player, List patterns) { - var listTag = new ListTag(); - for (ResolvedPattern pattern : patterns) { - listTag.add(pattern.serializeToNBT()); - } - player.getPersistentData().put(TAG_PATTERNS, listTag); + player.getPersistentData().put(TAG_PATTERNS, ResolvedPattern.CODEC.listOf().encodeStart(NbtOps.INSTANCE, patterns).getOrThrow()); } @Override @@ -246,7 +246,7 @@ public FlightAbility getFlight(ServerPlayer player) { var origin = HexUtils.vecFromNBT(tag.getCompound(TAG_FLIGHT_ORIGIN)); var radius = tag.getDouble(TAG_FLIGHT_RADIUS); var dimension = ResourceKey.create(Registries.DIMENSION, - new ResourceLocation(tag.getString(TAG_FLIGHT_DIMENSION))); + ResourceLocation.parse(tag.getString(TAG_FLIGHT_DIMENSION))); return new FlightAbility(timeLeft, dimension, origin, radius); } return null; @@ -265,9 +265,10 @@ public AltioraAbility getAltiora(Player player) { @Override public FrozenPigment getPigment(Player player) { - return FrozenPigment.fromNBT(player.getPersistentData().getCompound(TAG_PIGMENT)); + return FrozenPigment.CODEC.parse(NbtOps.INSTANCE, player.getPersistentData().getCompound(TAG_PIGMENT)).getOrThrow(); } + //TODO port: replace with codec? @Override public Sentinel getSentinel(Player player) { CompoundTag tag = player.getPersistentData(); @@ -277,112 +278,88 @@ public Sentinel getSentinel(Player player) { } var extendsRange = tag.getBoolean(TAG_SENTINEL_GREATER); var position = HexUtils.vecFromNBT(tag.getCompound(TAG_SENTINEL_POSITION)); - var dimension = ResourceKey.create(Registries.DIMENSION, - new ResourceLocation(tag.getString(TAG_SENTINEL_DIMENSION))); + var dimension = ResourceKey.create(Registries.DIMENSION, ResourceLocation.parse(tag.getString(TAG_SENTINEL_DIMENSION))); return new Sentinel(extendsRange, position, dimension); } @Override public CastingVM getStaffcastVM(ServerPlayer player, InteractionHand hand) { - // This is always from a staff because we don't need to load the harness when casting from item + // This is always from a staff because we don't need to load the VM when casting from item var ctx = new StaffCastEnv(player, hand); - return new CastingVM(CastingImage.loadFromNbt(player.getPersistentData().getCompound(TAG_HARNESS), - player.serverLevel()), ctx); + return new CastingVM(CastingImage.getCODEC().parse(NbtOps.INSTANCE, player.getPersistentData().getCompound(TAG_VM)).getOrThrow(), ctx); } @Override public List getPatternsSavedInUi(ServerPlayer player) { - ListTag patternsTag = player.getPersistentData().getList(TAG_PATTERNS, Tag.TAG_COMPOUND); - - List patterns = new ArrayList<>(patternsTag.size()); - - for (int i = 0; i < patternsTag.size(); i++) { - patterns.add(ResolvedPattern.fromNBT(patternsTag.getCompound(i))); - } - return patterns; + return ResolvedPattern.CODEC.listOf().parse(NbtOps.INSTANCE, player.getPersistentData().getList(TAG_PATTERNS, Tag.TAG_COMPOUND)).getOrThrow(); } @Override public void clearCastingData(ServerPlayer player) { - player.getPersistentData().remove(TAG_HARNESS); + player.getPersistentData().remove(TAG_VM); player.getPersistentData().remove(TAG_PATTERNS); } @Override public @Nullable ADMediaHolder findMediaHolder(ItemStack stack) { - var maybeCap = stack.getCapability(HexCapabilities.MEDIA).resolve(); - return maybeCap.orElse(null); - } - - @Override - public @Nullable ADMediaHolder findMediaHolder(ServerPlayer player) { - var maybeCap = player.getCapability(HexCapabilities.MEDIA).resolve(); - return maybeCap.orElse(null); + return stack.getCapability(HexCapabilities.Item.MEDIA); } @Override public @Nullable ADIotaHolder findDataHolder(ItemStack stack) { - var maybeCap = stack.getCapability(HexCapabilities.IOTA).resolve(); - return maybeCap.orElse(null); + return stack.getCapability(HexCapabilities.Item.IOTA); } @Override public @Nullable ADIotaHolder findDataHolder(Entity entity) { - var maybeCap = entity.getCapability(HexCapabilities.IOTA).resolve(); - return maybeCap.orElse(null); + return entity.getCapability(HexCapabilities.Entity.IOTA); } @Override public @Nullable ADHexHolder findHexHolder(ItemStack stack) { - var maybeCap = stack.getCapability(HexCapabilities.STORED_HEX).resolve(); - return maybeCap.orElse(null); + return stack.getCapability(HexCapabilities.Item.STORED_HEX); } @Override public @Nullable ADVariantItem findVariantHolder(ItemStack stack) { - var maybeCap = stack.getCapability(HexCapabilities.VARIANT_ITEM).resolve(); - return maybeCap.orElse(null); + return stack.getCapability(HexCapabilities.Item.VARIANT_ITEM); } @Override public boolean isPigment(ItemStack stack) { - return stack.getCapability(HexCapabilities.COLOR).isPresent(); + return stack.getCapability(HexCapabilities.Item.COLOR) != null; } @Override public ColorProvider getColorProvider(FrozenPigment pigment) { - var maybePigment = pigment.item().getCapability(HexCapabilities.COLOR).resolve(); - if (maybePigment.isPresent()) { - return maybePigment.get().provideColor(pigment.owner()); - } - return ColorProvider.MISSING; + var adPigment = pigment.item().getCapability(HexCapabilities.Item.COLOR); + return adPigment != null ? adPigment.provideColor(pigment.owner()) : ColorProvider.MISSING; } @Override - public void sendPacketToPlayer(ServerPlayer target, IMessage packet) { - ForgePacketHandler.getNetwork().send(PacketDistributor.PLAYER.with(() -> target), packet); + public void sendPacketToPlayer(ServerPlayer target, CustomPacketPayload packet) { + PacketDistributor.sendToPlayer(target, packet); } @Override - public void sendPacketNear(Vec3 pos, double radius, ServerLevel dimension, IMessage packet) { - ForgePacketHandler.getNetwork().send(PacketDistributor.NEAR.with(() -> new PacketDistributor.TargetPoint( - pos.x, pos.y, pos.z, radius * radius, dimension.dimension() - )), packet); + public void sendPacketNear(Vec3 pos, double radius, ServerLevel dimension, CustomPacketPayload packet) { + PacketDistributor.sendToPlayersNear(dimension, null, pos.x, pos.y, pos.z, radius, packet); } @Override - public void sendPacketTracking(Entity entity, IMessage packet) { - ForgePacketHandler.getNetwork().send(PacketDistributor.TRACKING_ENTITY.with(() -> entity), packet); + public void sendPacketTracking(Entity entity, CustomPacketPayload packet) { + PacketDistributor.sendToPlayersTrackingEntity(entity, packet); } @Override - public Packet toVanillaClientboundPacket(IMessage message) { + public Packet toVanillaClientboundPacket(CustomPacketPayload message) { + // TODO port: test cast //noinspection unchecked - return (Packet) ForgePacketHandler.getNetwork().toVanillaPacket(message, NetworkDirection.PLAY_TO_CLIENT); + return (Packet) (Object) message.toVanillaClientbound(); } @Override @@ -393,19 +370,19 @@ public BlockEntityType createBlockEntityType(BiFuncti @Override public boolean tryPlaceFluid(Level level, InteractionHand hand, BlockPos pos, Fluid fluid) { - Optional handler = FluidUtil.getFluidHandler(level, pos, Direction.UP).resolve(); + Optional handler = FluidUtil.getFluidHandler(level, pos, Direction.UP); return handler.isPresent() && - handler.get().fill(new FluidStack(fluid, FluidType.BUCKET_VOLUME), EXECUTE) > 0; + handler.get().fill(new FluidStack(fluid, FluidType.BUCKET_VOLUME), IFluidHandler.FluidAction.EXECUTE) > 0; } @Override public boolean drainAllFluid(Level level, BlockPos pos) { - Optional handler = FluidUtil.getFluidHandler(level, pos, Direction.UP).resolve(); + Optional handler = FluidUtil.getFluidHandler(level, pos, Direction.UP); if (handler.isPresent()) { boolean any = false; IFluidHandler pool = handler.get(); for (int i = 0; i < pool.getTanks(); i++) { - if (!pool.drain(pool.getFluidInTank(i), EXECUTE).isEmpty()) { + if (!pool.drain(pool.getFluidInTank(i), IFluidHandler.FluidAction.EXECUTE).isEmpty()) { any = true; } } @@ -416,12 +393,13 @@ public boolean drainAllFluid(Level level, BlockPos pos) { @Override public Ingredient getUnsealedIngredient(ItemStack stack) { - return ForgeUnsealedIngredient.of(stack); + return ForgeUnsealedIngredient.of(stack).toVanilla(); } @Override public boolean isCorrectTierForDrops(Tier tier, BlockState bs) { - return !bs.requiresCorrectToolForDrops() || TierSortingRegistry.isCorrectTierForDrops(tier, bs); + // TODO port: check tag + return !bs.is(HexTags.Blocks.HEX_UNBREAKABLE); } @Override @@ -432,12 +410,12 @@ public Item.Properties addEquipSlotFabric(EquipmentSlot slot) { private static final IXplatTags TAGS = new IXplatTags() { @Override public TagKey amethystDust() { - return HexTags.Items.create(new ResourceLocation("forge", "dusts/amethyst")); + return HexTags.Items.create(ResourceLocation.fromNamespaceAndPath("forge", "dusts/amethyst")); } @Override public TagKey gems() { - return HexTags.Items.create(new ResourceLocation("forge", "gems")); + return HexTags.Items.create(ResourceLocation.fromNamespaceAndPath("forge", "gems")); } }; @@ -448,7 +426,7 @@ public IXplatTags tags() { @Override public LootItemCondition.Builder isShearsCondition() { - return CanToolPerformAction.canToolPerformAction(ToolActions.SHEARS_DIG); + return CanItemPerformAbility.canItemPerformAbility(ItemAbilities.SHEARS_DIG); } @Override @@ -463,70 +441,83 @@ public String getModName(String namespace) { return namespace; } - private static final Supplier> ACTION_REGISTRY = Suppliers.memoize(() -> - ForgeAccessorBuiltInRegistries.hex$registerSimple( - HexRegistries.ACTION, null) - ); - private static final Supplier>> SPECIAL_HANDLER_REGISTRY = - Suppliers.memoize(() -> - ForgeAccessorBuiltInRegistries.hex$registerSimple( - HexRegistries.SPECIAL_HANDLER, null) - ); - private static final Supplier>> IOTA_TYPE_REGISTRY = Suppliers.memoize(() -> - ForgeAccessorBuiltInRegistries.hex$registerDefaulted( - HexRegistries.IOTA_TYPE, - modLoc("null").toString(), registry -> HexIotaTypes.NULL) - ); - private static final Supplier> ARITHMETIC_REGISTRY = Suppliers.memoize(() -> - ForgeAccessorBuiltInRegistries.hex$registerSimple( - HexRegistries.ARITHMETIC, null) - ); - private static final Supplier>> CONTINUATION_TYPE_REGISTRY = Suppliers.memoize(() -> - ForgeAccessorBuiltInRegistries.hex$registerDefaulted( - HexRegistries.CONTINUATION_TYPE, - modLoc("end").toString(), registry -> HexContinuationTypes.END) - ); - private static final Supplier> EVAL_SOUND_REGISTRY = Suppliers.memoize(() -> - ForgeAccessorBuiltInRegistries.hex$registerDefaulted( - HexRegistries.EVAL_SOUND, - modLoc("nothing").toString(), registry -> HexEvalSounds.NOTHING) - ); + private static final Registry ACTION_REGISTRY = new RegistryBuilder<>(HexRegistries.ACTION) + .sync(true) + .create(); + private static final Registry> SPECIAL_HANDLER_REGISTRY = new RegistryBuilder<>(HexRegistries.SPECIAL_HANDLER) + .sync(true) + .create(); + private static final Registry> IOTA_TYPE_REGISTRY = new RegistryBuilder<>(HexRegistries.IOTA_TYPE) + .sync(true) + .defaultKey(modLoc("null")) + .create(); + + private static final Registry ARITHMETIC_REGISTRY = new RegistryBuilder<>(HexRegistries.ARITHMETIC) + .sync(true) + .create(); + + private static final Registry> CONTINUATION_TYPE_REGISTRY = new RegistryBuilder<>(HexRegistries.CONTINUATION_TYPE) + .sync(true) + .defaultKey(modLoc("end")) + .create(); + private static final Registry EVAL_SOUND_REGISTRY = new RegistryBuilder<>(HexRegistries.EVAL_SOUND) + .sync(true) + .defaultKey(modLoc("nothing")) + .create(); + private static final Registry> STATE_INGREDIENT_REGISTRY = new RegistryBuilder<>(HexRegistries.STATE_INGREDIENT) + .sync(true) + .defaultKey(modLoc("none")) + .create(); + private static final Registry> BRAINSWEEPEE_INGREDIENT_REGISTRY = new RegistryBuilder<>(HexRegistries.BRAINSWEEPEE_INGREDIENT) + .sync(true) + .defaultKey(modLoc("none")) + .create(); @Override public Registry getActionRegistry() { - return ACTION_REGISTRY.get(); + return ACTION_REGISTRY; } @Override public Registry> getSpecialHandlerRegistry() { - return SPECIAL_HANDLER_REGISTRY.get(); + return SPECIAL_HANDLER_REGISTRY; } @Override public Registry> getIotaTypeRegistry() { - return IOTA_TYPE_REGISTRY.get(); + return IOTA_TYPE_REGISTRY; } @Override public Registry getArithmeticRegistry() { - return ARITHMETIC_REGISTRY.get(); + return ARITHMETIC_REGISTRY; } @Override public Registry> getContinuationTypeRegistry() { - return CONTINUATION_TYPE_REGISTRY.get(); + return CONTINUATION_TYPE_REGISTRY; } @Override public Registry getEvalSoundRegistry() { - return EVAL_SOUND_REGISTRY.get(); + return EVAL_SOUND_REGISTRY; + } + + @Override + public Registry> getStateIngredientRegistry() { + return STATE_INGREDIENT_REGISTRY; + } + + @Override + public Registry> getBrainsweepeeIngredientRegistry() { + return BRAINSWEEPEE_INGREDIENT_REGISTRY; } @Override public boolean isBreakingAllowed(ServerLevel world, BlockPos pos, BlockState state, @Nullable Player player) { if (player == null) player = FakePlayerFactory.get(world, HEXCASTING); - return !MinecraftForge.EVENT_BUS.post(new BlockEvent.BreakEvent(world, pos, state, player)); + return !NeoForge.EVENT_BUS.post(new BlockEvent.BreakEvent(world, pos, state, player)).isCanceled(); } @Override @@ -535,7 +526,7 @@ public boolean isPlacingAllowed(ServerLevel world, BlockPos pos, ItemStack block player = FakePlayerFactory.get(world, HEXCASTING); ItemStack cached = player.getMainHandItem(); player.setItemInHand(InteractionHand.MAIN_HAND, blockStack.copy()); - var evt = ForgeHooks.onRightClickBlock(player, InteractionHand.MAIN_HAND, pos, + var evt = CommonHooks.onRightClickBlock(player, InteractionHand.MAIN_HAND, pos, new BlockHitResult(Vec3.atCenterOf(pos), Direction.DOWN, pos, true)); player.setItemInHand(InteractionHand.MAIN_HAND, cached); return !evt.isCanceled(); @@ -583,8 +574,8 @@ public void setScale(Entity e, float scale) { public static final String TAG_ALTIORA_ALLOWED = "hexcasting:altiora_allowed"; public static final String TAG_ALTIORA_GRACE = "hexcasting:altiora_grace_period"; - public static final UUID ALTIORA_ATTRIBUTE_ID = UUID.fromString("91897c79-3ebb-468c-a265-40418ed01c41"); + public static final ResourceLocation ALTIORA_ATTRIBUTE_ID = modLoc("altiora"); - public static final String TAG_HARNESS = "hexcasting:spell_harness"; + public static final String TAG_VM = "hexcasting:spell_harness"; public static final String TAG_PATTERNS = "hexcasting:spell_patterns"; } diff --git a/Neoforge/src/main/resources/data/curios/tags/items/head.json b/Neoforge/src/main/resources/data/curios/tags/item/head.json similarity index 100% rename from Neoforge/src/main/resources/data/curios/tags/items/head.json rename to Neoforge/src/main/resources/data/curios/tags/item/head.json diff --git a/Neoforge/src/main/resources/data/hexcasting/curios/entities/head.json b/Neoforge/src/main/resources/data/hexcasting/curios/entities/head.json new file mode 100644 index 0000000000..361fd3f548 --- /dev/null +++ b/Neoforge/src/main/resources/data/hexcasting/curios/entities/head.json @@ -0,0 +1,8 @@ +{ + "entities": [ + "player" + ], + "slots": [ + "head" + ] +} \ No newline at end of file diff --git a/Neoforge/src/main/resources/hexcasting_forge.mixins.json b/Neoforge/src/main/resources/hexcasting_forge.mixins.json index 3a50c75493..d05981caff 100644 --- a/Neoforge/src/main/resources/hexcasting_forge.mixins.json +++ b/Neoforge/src/main/resources/hexcasting_forge.mixins.json @@ -5,7 +5,6 @@ "refmap": "hexcasting.mixins.refmap.json", "package": "at.petrak.hexcasting.forge.mixin", "mixins": [ - "ForgeAccessorBuiltInRegistries", "ForgeMixinCursedRecipeSerializerBase", "ForgeMixinTagsProvider" ], diff --git a/build.gradle b/build.gradle index 2b02304af4..df494b9824 100644 --- a/build.gradle +++ b/build.gradle @@ -1,8 +1,11 @@ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget + plugins { // used for something?? - id 'dev.architectury.loom' version '1.7-SNAPSHOT' apply false + id 'dev.architectury.loom' version '1.10-SNAPSHOT' apply false // used for multi-loader stuff, NOT for the archi API id 'architectury-plugin' version '3.4-SNAPSHOT' + id 'com.gradleup.shadow' version '8.3.6' apply false id "org.jetbrains.kotlin.jvm" @@ -87,7 +90,7 @@ subprojects { // Disables Gradle's custom module metadata from being published to maven. The // metadata includes mapped dependencies which are not reasonably consumable by // other mod developers. - tasks.withType(GenerateModuleMetadata) { + tasks.withType(GenerateModuleMetadata).configureEach { enabled = false } @@ -99,7 +102,7 @@ allprojects { } gradle.projectsEvaluated { - tasks.withType(JavaCompile) { + tasks.withType(JavaCompile).configureEach { options.compilerArgs << "-Xmaxerrs" << "1000" } } @@ -109,13 +112,13 @@ allprojects { } compileKotlin { - kotlinOptions { - jvmTarget = "21" + compilerOptions { + jvmTarget = JvmTarget.JVM_21 } } compileTestKotlin { - kotlinOptions { - jvmTarget = "21" + compilerOptions { + jvmTarget = JvmTarget.JVM_21 } } diff --git a/gradle.properties b/gradle.properties index 94d51bc876..637f71e108 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,8 +12,11 @@ minecraftVersion=1.21.1 kotlinVersion=2.0.21 modVersion=0.12.0-devel +fabric_loader_version=0.16.14 + # this is the version published to modrinth/cf i swear -paucalVersion=0.7.1-pre-23 +# haha not anymore it's from mavenLocal +paucalVersion=0.7.2 patchouliVersion=88 accessoriesVersion=1.1.0-beta.16+1.21.1 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 9355b41557..ca025c83a7 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/settings.gradle b/settings.gradle index b4f6d8d642..d8e8add79f 100644 --- a/settings.gradle +++ b/settings.gradle @@ -19,4 +19,4 @@ pluginManagement { } rootProject.name = 'Hex Casting' -include("Common", "Fabric", "Neoforge") +include("Common", /*"Fabric",*/ "Neoforge")