diff --git a/.gitignore b/.gitignore index 6c344479b..36af21bed 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,7 @@ build # other eclipse run +.DS_Store # Files from Forge MDK forge*changelog.txt diff --git a/Common/build.gradle b/Common/build.gradle index b9c6433d5..2c84ea11f 100644 --- a/Common/build.gradle +++ b/Common/build.gradle @@ -27,14 +27,19 @@ repositories { name = "ModMaven" url = "https://modmaven.dev" } + + // If you have mod jar dependencies in ./libs, you can declare them as a repository like so: + flatDir { + dir 'libs' + } } dependencies { compileOnly group: 'org.spongepowered', name: 'mixin', version: '0.8.5' implementation group: 'com.google.code.findbugs', name: 'jsr305', version: '3.0.1' - compileOnly "at.petra-k.paucal:paucal-common-$minecraftVersion:$paucalVersion" - compileOnly "vazkii.patchouli:Patchouli-xplat:$minecraftVersion-$patchouliVersion" + compileOnly "${modID}:paucal-common-$minecraftVersion:$paucalVersion" + compileOnly "vazkii.patchouli:Patchouli-xplat:$minecraftVersion-$patchouliVersion-SNAPSHOT" compileOnly "org.jetbrains:annotations:$jetbrainsAnnotationsVersion" testCompileOnly "org.jetbrains:annotations:$jetbrainsAnnotationsVersion" diff --git a/Common/libs/paucal-common-1.20.1-0.6.0.jar b/Common/libs/paucal-common-1.20.1-0.6.0.jar new file mode 100644 index 000000000..5d6e2c0ad Binary files /dev/null and b/Common/libs/paucal-common-1.20.1-0.6.0.jar differ diff --git a/Common/src/generated/resources/.cache/8f7cd5c924d3264b7777ef1696459761f9a70902 b/Common/src/generated/resources/.cache/8f7cd5c924d3264b7777ef1696459761f9a70902 index cb18fdd6a..8cf64135d 100644 --- a/Common/src/generated/resources/.cache/8f7cd5c924d3264b7777ef1696459761f9a70902 +++ b/Common/src/generated/resources/.cache/8f7cd5c924d3264b7777ef1696459761f9a70902 @@ -1,4 +1,4 @@ -// 1.19.2 2023-06-20T14:09:26.505719553 Item Models: hexcasting +// 1.20.1 2023-12-24T17:59:13.7584156 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 @@ -76,6 +76,8 @@ de7f7dec75da3170672de5c46a87ff47297db12b assets/hexcasting/models/item/dye_color 667ea00dbc366ee41e97f21c099001440212d183 assets/hexcasting/models/item/dye_colorizer_yellow.json f867a3b2bbc117a782d49f0819b60f4727d1f483 assets/hexcasting/models/item/edified_button.json c9faada6299f388afc2d2798843d2b45159950d1 assets/hexcasting/models/item/edified_door.json +32f6086df25000e0af341e49ab60fa214f0c4a52 assets/hexcasting/models/item/edified_fence.json +12b4c0ce637123f5a39c00c4c973958f5106eecf assets/hexcasting/models/item/edified_fence_gate.json 7f22e012a844cc2c5e30b0fcbdc2e7e4afac1c40 assets/hexcasting/models/item/edified_log.json 8197108bfba4b5963e3c0b1e76a04b8a0d6aae03 assets/hexcasting/models/item/edified_log_amethyst.json 7d6bd7d94d4417f85444c387fc34d9b6947858f1 assets/hexcasting/models/item/edified_log_aventurine.json @@ -115,11 +117,6 @@ abfc028c974a02780aed3d7a5859352503bbd920 assets/hexcasting/models/item/lens.json a34a6d777ae265c7e49c8bb23c15f04359236544 assets/hexcasting/models/item/lore_fragment.json a3e134b79977545049da01671f3a1bd636d14789 assets/hexcasting/models/item/old_staff.json 82fa0a2bb17e40c0b3f826e97b2e95445ec24ab8 assets/hexcasting/models/item/patchouli_book.json -d69d10e6cb967b98b3294cc86174182c671de671 assets/hexcasting/models/item/phial_large_0.json -9b7805bec9481956b0ccc6c65dd8e02d3b3cdf54 assets/hexcasting/models/item/phial_large_1.json -596a866a0fac7cfe916d1e78f2a5f20856493c62 assets/hexcasting/models/item/phial_large_2.json -34aacc4fb999949e455d01548546a52eafb97e24 assets/hexcasting/models/item/phial_large_3.json -3a6f6b51e72a040d039abae580ef5db2a6c8101d assets/hexcasting/models/item/phial_large_4.json 91186c79af073cc390a1f1e6712540e1a49b716e assets/hexcasting/models/item/phial_larger_0.json 548d6999c6b5cb2c5b8d36d190fc849632f9f8ea assets/hexcasting/models/item/phial_larger_1.json 3162e3b88e59a9ab4b9df345724a0964db695688 assets/hexcasting/models/item/phial_larger_2.json @@ -130,6 +127,11 @@ e20faba33418dac72ff3ad360eeb6fce3fce2728 assets/hexcasting/models/item/phial_lar f0623e9b9192098dff982fabf1e598a27f96b7a8 assets/hexcasting/models/item/phial_largest_2.json 911736f4e2e3d825fb01f13dd32bf0108b68df99 assets/hexcasting/models/item/phial_largest_3.json 86d475f4c5bda63a564604e828f408ac6769e9eb assets/hexcasting/models/item/phial_largest_4.json +d69d10e6cb967b98b3294cc86174182c671de671 assets/hexcasting/models/item/phial_large_0.json +9b7805bec9481956b0ccc6c65dd8e02d3b3cdf54 assets/hexcasting/models/item/phial_large_1.json +596a866a0fac7cfe916d1e78f2a5f20856493c62 assets/hexcasting/models/item/phial_large_2.json +34aacc4fb999949e455d01548546a52eafb97e24 assets/hexcasting/models/item/phial_large_3.json +3a6f6b51e72a040d039abae580ef5db2a6c8101d assets/hexcasting/models/item/phial_large_4.json d5a3a98a51146a94b95ea84d49236fc83b08b807 assets/hexcasting/models/item/phial_medium_0.json 2165d19e514a3358fb8e3ceb91efd2fbc47ddebd assets/hexcasting/models/item/phial_medium_1.json 89933a425604fb6c0599848df3fef62ab07ea5a2 assets/hexcasting/models/item/phial_medium_2.json @@ -204,7 +206,9 @@ a1dc5817c7c62e0d6e4c1ca1c5bfba6973a9b253 assets/hexcasting/models/item/spellbook e43bfc743664dc23cbb2aaa4a66072ce1bbb5c2f assets/hexcasting/models/item/spellbook_7_filled.json 32210f56cb33747d9890de18300ae936cc8b0f77 assets/hexcasting/models/item/spellbook_7_sealed.json f791313aa7bb01b418676ffaeeb09286ca9bddff assets/hexcasting/models/item/staff/acacia.json +e1f5949b5ea4e5056909d9a74f4c578114d905f1 assets/hexcasting/models/item/staff/bamboo.json 19acf04c62128275b8fb468e89a30ab94d6e5a1a assets/hexcasting/models/item/staff/birch.json +3ed3e3d86dcbc29d2e6fb59b9c6a7e455e9a3332 assets/hexcasting/models/item/staff/cherry.json 244ba74a82a188df6fd258affcdd4b1a7320e617 assets/hexcasting/models/item/staff/crimson.json ee609f36641d4689512b54aa343eafd1d53881e6 assets/hexcasting/models/item/staff/dark_oak.json eb9d51207fddad95d375ccbe0f96df12893312d0 assets/hexcasting/models/item/staff/edified.json @@ -242,7 +246,9 @@ b9d891572f572d76c0c0aef0afc3d3cb80f72c30 assets/hexcasting/models/item/trinket_7 4a8b82a628a3c4b16c4a45d3689799c8d9cf8bf8 assets/hexcasting/models/item/trinket_7_filled.json c6523de66cbfae3a1e6361c635cc693a0a089bb3 assets/hexcasting/models/item/uuid_colorizer.json c0af5573a4acb5eeacf49ab309d32b6f90ea8a5d assets/hexcasting/models/staff/acacia.json +1f90275c1d6829f0cdaf71f2c3b234c39cd7290d assets/hexcasting/models/staff/bamboo.json ac7a4b95db8bde9da23dd4fa76d8086a67e166f8 assets/hexcasting/models/staff/birch.json +f7fca510f1f2c8ab5a90e96fa52abf717e3f836e assets/hexcasting/models/staff/cherry.json b3f3fae3237d9f65d631fe3a6608ed76d9e0034d assets/hexcasting/models/staff/crimson.json 202de3e9a1bb7cd2ac2781937f4d03afe3947195 assets/hexcasting/models/staff/dark_oak.json a03d8c4cd52afb51668450f0b47ef278bb75ebec assets/hexcasting/models/staff/edified.json diff --git a/Common/src/generated/resources/.cache/d2fe5b6fab5fdc7ee7ca336c062752306bdf6128 b/Common/src/generated/resources/.cache/d2fe5b6fab5fdc7ee7ca336c062752306bdf6128 index d68a84da1..cab0548ef 100644 --- a/Common/src/generated/resources/.cache/d2fe5b6fab5fdc7ee7ca336c062752306bdf6128 +++ b/Common/src/generated/resources/.cache/d2fe5b6fab5fdc7ee7ca336c062752306bdf6128 @@ -1,4 +1,4 @@ -// 1.19.2 2023-06-20T14:09:26.510463293 Block States: hexcasting +// 1.20.1 2023-12-24T17:59:13.7624167 Block States: hexcasting 901e38574bdaa40ea4a0f6e773a88a95d9c03e55 assets/hexcasting/blockstates/akashic_bookshelf.json 32a77ef668198002563d68be35a24fa93c8d454a assets/hexcasting/blockstates/akashic_connector.json 85080ce0a0387583a839e4788517d675a1a35e24 assets/hexcasting/blockstates/akashic_record.json @@ -15,10 +15,13 @@ d422119401df3daae032f86ea740b6065a92c44c assets/hexcasting/blockstates/amethyst_ fa6dfbc40e5b9b22c01356e8a3848d242c414c02 assets/hexcasting/blockstates/citrine_edified_leaves.json dc268e4c50e5e155fc5414a5f6b58ce1782bd39b assets/hexcasting/blockstates/conjured_block.json dc268e4c50e5e155fc5414a5f6b58ce1782bd39b assets/hexcasting/blockstates/conjured_light.json +dffbe9894baae1c0c0dd3377659ce6fcb71ae634 assets/hexcasting/blockstates/directrix/boolean.json b76cc8a2d66700417046c0dc671badd9af3eb519 assets/hexcasting/blockstates/directrix/empty.json 365eba1c32a7a33698120bc7f12670d29087e999 assets/hexcasting/blockstates/directrix/redstone.json e125b73869a438bafa7f47cfa4c8d837e2463c6f assets/hexcasting/blockstates/edified_button.json 749d29dc5e11aeba703022dd66aad939d211a3b9 assets/hexcasting/blockstates/edified_door.json +cff9717cca70e2754bb4d0d5e695335e85adf212 assets/hexcasting/blockstates/edified_fence.json +05c8ef11fbde183dc9ed578b65d512df29c3b2f5 assets/hexcasting/blockstates/edified_fence_gate.json 9080ec8bb4142aa3f80775fb017d821585cdfeba assets/hexcasting/blockstates/edified_log.json b9bbfe3288a699ef51ee0d21ec8e335f811353ca assets/hexcasting/blockstates/edified_log_amethyst.json fc0f4407ef06ac962b5985db31800e05c8f1d1be assets/hexcasting/blockstates/edified_log_aventurine.json @@ -67,6 +70,42 @@ e2a738dede302484f7c8d19dde58c08f841f0432 assets/hexcasting/models/block/akashic_ c0a2818ae1162e8b93d32a913602ba8523476695 assets/hexcasting/models/block/ancient_scroll_paper.json 77d0a5c4496678f96da5103b49777e612e3cba1e assets/hexcasting/models/block/ancient_scroll_paper_lantern.json 8b6de8cb9ccea9a8e4ce207f0b72048881c11da9 assets/hexcasting/models/block/aventurine_edified_leaves.json +bd1e5a7d3b5945c596919d7ec114d3904199d217 assets/hexcasting/models/block/circle/directrix/boolean/dim_false_down.json +bd1e5a7d3b5945c596919d7ec114d3904199d217 assets/hexcasting/models/block/circle/directrix/boolean/dim_false_east.json +bd1e5a7d3b5945c596919d7ec114d3904199d217 assets/hexcasting/models/block/circle/directrix/boolean/dim_false_north.json +bd1e5a7d3b5945c596919d7ec114d3904199d217 assets/hexcasting/models/block/circle/directrix/boolean/dim_false_south.json +bd1e5a7d3b5945c596919d7ec114d3904199d217 assets/hexcasting/models/block/circle/directrix/boolean/dim_false_up.json +bd1e5a7d3b5945c596919d7ec114d3904199d217 assets/hexcasting/models/block/circle/directrix/boolean/dim_false_west.json +2441d51bf7b8b81a1d930dc3adc7ad6b0f64024b assets/hexcasting/models/block/circle/directrix/boolean/dim_neither_down.json +2441d51bf7b8b81a1d930dc3adc7ad6b0f64024b assets/hexcasting/models/block/circle/directrix/boolean/dim_neither_east.json +2441d51bf7b8b81a1d930dc3adc7ad6b0f64024b assets/hexcasting/models/block/circle/directrix/boolean/dim_neither_north.json +2441d51bf7b8b81a1d930dc3adc7ad6b0f64024b assets/hexcasting/models/block/circle/directrix/boolean/dim_neither_south.json +2441d51bf7b8b81a1d930dc3adc7ad6b0f64024b assets/hexcasting/models/block/circle/directrix/boolean/dim_neither_up.json +2441d51bf7b8b81a1d930dc3adc7ad6b0f64024b assets/hexcasting/models/block/circle/directrix/boolean/dim_neither_west.json +76183d9b39ce0dff814befd20ee2681e4809607e assets/hexcasting/models/block/circle/directrix/boolean/dim_true_down.json +76183d9b39ce0dff814befd20ee2681e4809607e assets/hexcasting/models/block/circle/directrix/boolean/dim_true_east.json +76183d9b39ce0dff814befd20ee2681e4809607e assets/hexcasting/models/block/circle/directrix/boolean/dim_true_north.json +76183d9b39ce0dff814befd20ee2681e4809607e assets/hexcasting/models/block/circle/directrix/boolean/dim_true_south.json +76183d9b39ce0dff814befd20ee2681e4809607e assets/hexcasting/models/block/circle/directrix/boolean/dim_true_up.json +76183d9b39ce0dff814befd20ee2681e4809607e assets/hexcasting/models/block/circle/directrix/boolean/dim_true_west.json +0d757dfb13f75a2e7fb41b8a8f0281c2adfe56ec assets/hexcasting/models/block/circle/directrix/boolean/lit_false_down.json +0d757dfb13f75a2e7fb41b8a8f0281c2adfe56ec assets/hexcasting/models/block/circle/directrix/boolean/lit_false_east.json +0d757dfb13f75a2e7fb41b8a8f0281c2adfe56ec assets/hexcasting/models/block/circle/directrix/boolean/lit_false_north.json +0d757dfb13f75a2e7fb41b8a8f0281c2adfe56ec assets/hexcasting/models/block/circle/directrix/boolean/lit_false_south.json +0d757dfb13f75a2e7fb41b8a8f0281c2adfe56ec assets/hexcasting/models/block/circle/directrix/boolean/lit_false_up.json +0d757dfb13f75a2e7fb41b8a8f0281c2adfe56ec assets/hexcasting/models/block/circle/directrix/boolean/lit_false_west.json +2441d51bf7b8b81a1d930dc3adc7ad6b0f64024b assets/hexcasting/models/block/circle/directrix/boolean/lit_neither_down.json +2441d51bf7b8b81a1d930dc3adc7ad6b0f64024b assets/hexcasting/models/block/circle/directrix/boolean/lit_neither_east.json +2441d51bf7b8b81a1d930dc3adc7ad6b0f64024b assets/hexcasting/models/block/circle/directrix/boolean/lit_neither_north.json +2441d51bf7b8b81a1d930dc3adc7ad6b0f64024b assets/hexcasting/models/block/circle/directrix/boolean/lit_neither_south.json +2441d51bf7b8b81a1d930dc3adc7ad6b0f64024b assets/hexcasting/models/block/circle/directrix/boolean/lit_neither_up.json +2441d51bf7b8b81a1d930dc3adc7ad6b0f64024b assets/hexcasting/models/block/circle/directrix/boolean/lit_neither_west.json +7274390d61c51c344fc86870190f3d9ce2b58205 assets/hexcasting/models/block/circle/directrix/boolean/lit_true_down.json +7274390d61c51c344fc86870190f3d9ce2b58205 assets/hexcasting/models/block/circle/directrix/boolean/lit_true_east.json +7274390d61c51c344fc86870190f3d9ce2b58205 assets/hexcasting/models/block/circle/directrix/boolean/lit_true_north.json +7274390d61c51c344fc86870190f3d9ce2b58205 assets/hexcasting/models/block/circle/directrix/boolean/lit_true_south.json +7274390d61c51c344fc86870190f3d9ce2b58205 assets/hexcasting/models/block/circle/directrix/boolean/lit_true_up.json +7274390d61c51c344fc86870190f3d9ce2b58205 assets/hexcasting/models/block/circle/directrix/boolean/lit_true_west.json 598a6b87cfc622b59d7aa25e08173bfbba86cf9a assets/hexcasting/models/block/circle/directrix/empty/dim_down.json 598a6b87cfc622b59d7aa25e08173bfbba86cf9a assets/hexcasting/models/block/circle/directrix/empty/dim_east.json 598a6b87cfc622b59d7aa25e08173bfbba86cf9a assets/hexcasting/models/block/circle/directrix/empty/dim_north.json @@ -177,6 +216,12 @@ b13efe9e1aade0163a8d378184a19a639b98c460 assets/hexcasting/models/block/edified_ 11922c18e84d393bc99380d52c187bbaa6079359 assets/hexcasting/models/block/edified_door_top_left_open.json 729cf57ba13bf915999b4297aadb2ef6848d0337 assets/hexcasting/models/block/edified_door_top_right.json db3008a51e611ee3ffb86b5829df6b7da6bfcc61 assets/hexcasting/models/block/edified_door_top_right_open.json +04bc3e2c715f624bb873e3abd5c6fcb33dd09f49 assets/hexcasting/models/block/edified_fence_gate.json +27dee730d090c1049e80c3870941ec35a3a8605e assets/hexcasting/models/block/edified_fence_gate_open.json +039ef4a7c1b07295a15bce55e4f779d517491ea5 assets/hexcasting/models/block/edified_fence_gate_wall.json +0cb10fa56c56ed495e13572d964862bccb24d8c4 assets/hexcasting/models/block/edified_fence_gate_wall_open.json +380b40dab77e4a86043723678071f924c3927928 assets/hexcasting/models/block/edified_fence_post.json +f185f0483b97314b9d5ab9e14dc787456532ec27 assets/hexcasting/models/block/edified_fence_side.json c5433d0b5c9f039ae3c314c8a82c7e1d3238447d assets/hexcasting/models/block/edified_log.json 4e779dbe1d8dfcb2d500bf43d71ecf0bd0104eac assets/hexcasting/models/block/edified_log_amethyst.json 5c9d3a002deae195ba8bff03ac106c302d36792d assets/hexcasting/models/block/edified_log_amethyst_horizontal.json @@ -232,6 +277,7 @@ fa23967e352823f0fc9e2bdd11a9cbac7c47b135 assets/hexcasting/models/item/amethyst_ d4a109488c27fc5d60e9054cd1485f1982040ff3 assets/hexcasting/models/item/ancient_scroll_paper_lantern.json 7c2b9b5296ba5e3c261bb237555e7d4082ad9303 assets/hexcasting/models/item/aventurine_edified_leaves.json 50b0a55c712887ceb02bc835a1111cf855c11b6e assets/hexcasting/models/item/citrine_edified_leaves.json +25a1386a5f4fca414f0e2509ce489616b24b9c9c assets/hexcasting/models/item/directrix/boolean.json c24d9c5ec6c7f3212ea814ecd40e56bdc94c22a8 assets/hexcasting/models/item/directrix/empty.json c84399ca55a1ac9b37ed4b8153b4469fa5ed9c5a assets/hexcasting/models/item/directrix/redstone.json 96e1cd457414bddbddda1383564c6a566808f958 assets/hexcasting/models/item/edified_panel.json diff --git a/Common/src/generated/resources/.cache/e5c5eb35b4ba40351ecb7d9f04c3527f2f5779b0 b/Common/src/generated/resources/.cache/e5c5eb35b4ba40351ecb7d9f04c3527f2f5779b0 index 6f11e29b3..d97c48d9f 100644 --- a/Common/src/generated/resources/.cache/e5c5eb35b4ba40351ecb7d9f04c3527f2f5779b0 +++ b/Common/src/generated/resources/.cache/e5c5eb35b4ba40351ecb7d9f04c3527f2f5779b0 @@ -1,16 +1,16 @@ -// 1.19.2 2023-06-20T14:09:26.512847541 Advancements -b21f0b7f0cda29a7e84693df8139f2fecfeea960 data/hexcasting/advancements/aaa_wasteful_cast.json -9d8b41dd8ddfccdf2cd19433d8d7d3cf934e64db data/hexcasting/advancements/aab_big_cast.json -425b42f6da5fd6498053f565dce1f171997dbb8b data/hexcasting/advancements/enlightenment.json -8f97205fa79270eab688aa3019d6fe7dd8c8b0d3 data/hexcasting/advancements/lore.json -fcce2d31886ec60aa23f8b4ba799c17672735b59 data/hexcasting/advancements/lore/cardamom1.json -a69a7cb1948868efdf0efc79b17a89545b21b000 data/hexcasting/advancements/lore/cardamom2.json -cfd1f38e41803259b776f1a69d0e8d520b201a02 data/hexcasting/advancements/lore/cardamom3.json -b4617dbc021e22cfa43d1f086b1651c503e6ccb5 data/hexcasting/advancements/lore/cardamom4.json -3863835e510506b96e23953cd6d29407ca158738 data/hexcasting/advancements/lore/cardamom5.json -2f5ad49936d58c7097ac7f8fbbf3f66f9f90fd2c data/hexcasting/advancements/lore/experiment1.json -9a4eba1c9d7868906e8ea1b4ec287f54a2c379b5 data/hexcasting/advancements/lore/experiment2.json -dea2c9b5682b246820fcf2d71bbc1580a19bd8a5 data/hexcasting/advancements/lore/inventory.json -bf319d71d9e706f9131c9484be1bc83ca2b8b6a3 data/hexcasting/advancements/opened_eyes.json -d19039a73324eb7532d035d08442f3b68bb13bcb data/hexcasting/advancements/root.json -b1b82068d65d6872c258d905d4f78499e8227ccf data/hexcasting/advancements/y_u_no_cast_angy.json +// 1.20.1 2023-12-24T17:59:13.7659226 Advancements +4016b178322c4784c12c66c227d5b4ff2e43d32d data/hexcasting/advancements/aaa_wasteful_cast.json +6469361b24f473b4d7d900828e6bbf2bdabf916b data/hexcasting/advancements/aab_big_cast.json +e02605ac2dff5c426e1d0a58d46daefecda11946 data/hexcasting/advancements/enlightenment.json +e2679742ac4e23ba4c79c17d209f16d42d7bccd8 data/hexcasting/advancements/lore.json +6c3fc955783d450e12494b193e985a403b203f0a data/hexcasting/advancements/lore/cardamom1.json +2191ef660f29f328fbdb3baca4f33585045c999e data/hexcasting/advancements/lore/cardamom2.json +fccce07d88f98719750516d2dbbc7ed186769c80 data/hexcasting/advancements/lore/cardamom3.json +cee68eb79ae27b6a83a25cf014d19c6bc4575cc0 data/hexcasting/advancements/lore/cardamom4.json +752744633e3b9500baebd5a4f8fa35e0c2d79ede data/hexcasting/advancements/lore/cardamom5.json +5898f7083f74a490b100b0a2282df242548baf7c data/hexcasting/advancements/lore/experiment1.json +8985672cbf68098dc416fd1f9e69d46212d04512 data/hexcasting/advancements/lore/experiment2.json +841c8eb27ad70aeaf0c9f7936fc8460cca0996fb data/hexcasting/advancements/lore/inventory.json +d273b4dc581c0029cde2208e264a6d32492cd18f data/hexcasting/advancements/opened_eyes.json +1cac020fa7b47ff386e7492f49e27803d506825d data/hexcasting/advancements/root.json +e4cee07b5809ebf27f1c1d48f66856153f7088f4 data/hexcasting/advancements/y_u_no_cast_angy.json diff --git a/Common/src/generated/resources/assets/hexcasting/blockstates/directrix/boolean.json b/Common/src/generated/resources/assets/hexcasting/blockstates/directrix/boolean.json new file mode 100644 index 000000000..155f55cfe --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/blockstates/directrix/boolean.json @@ -0,0 +1,142 @@ +{ + "variants": { + "energized=false,facing=down,state=false": { + "model": "hexcasting:block/circle/directrix/boolean/dim_false_down", + "x": 90 + }, + "energized=false,facing=down,state=neither": { + "model": "hexcasting:block/circle/directrix/boolean/dim_neither_down", + "x": 90 + }, + "energized=false,facing=down,state=true": { + "model": "hexcasting:block/circle/directrix/boolean/dim_true_down", + "x": 90 + }, + "energized=false,facing=east,state=false": { + "model": "hexcasting:block/circle/directrix/boolean/dim_false_east", + "y": 90 + }, + "energized=false,facing=east,state=neither": { + "model": "hexcasting:block/circle/directrix/boolean/dim_neither_east", + "y": 90 + }, + "energized=false,facing=east,state=true": { + "model": "hexcasting:block/circle/directrix/boolean/dim_true_east", + "y": 90 + }, + "energized=false,facing=north,state=false": { + "model": "hexcasting:block/circle/directrix/boolean/dim_false_north" + }, + "energized=false,facing=north,state=neither": { + "model": "hexcasting:block/circle/directrix/boolean/dim_neither_north" + }, + "energized=false,facing=north,state=true": { + "model": "hexcasting:block/circle/directrix/boolean/dim_true_north" + }, + "energized=false,facing=south,state=false": { + "model": "hexcasting:block/circle/directrix/boolean/dim_false_south", + "y": 180 + }, + "energized=false,facing=south,state=neither": { + "model": "hexcasting:block/circle/directrix/boolean/dim_neither_south", + "y": 180 + }, + "energized=false,facing=south,state=true": { + "model": "hexcasting:block/circle/directrix/boolean/dim_true_south", + "y": 180 + }, + "energized=false,facing=up,state=false": { + "model": "hexcasting:block/circle/directrix/boolean/dim_false_up", + "x": -90 + }, + "energized=false,facing=up,state=neither": { + "model": "hexcasting:block/circle/directrix/boolean/dim_neither_up", + "x": -90 + }, + "energized=false,facing=up,state=true": { + "model": "hexcasting:block/circle/directrix/boolean/dim_true_up", + "x": -90 + }, + "energized=false,facing=west,state=false": { + "model": "hexcasting:block/circle/directrix/boolean/dim_false_west", + "y": 270 + }, + "energized=false,facing=west,state=neither": { + "model": "hexcasting:block/circle/directrix/boolean/dim_neither_west", + "y": 270 + }, + "energized=false,facing=west,state=true": { + "model": "hexcasting:block/circle/directrix/boolean/dim_true_west", + "y": 270 + }, + "energized=true,facing=down,state=false": { + "model": "hexcasting:block/circle/directrix/boolean/lit_false_down", + "x": 90 + }, + "energized=true,facing=down,state=neither": { + "model": "hexcasting:block/circle/directrix/boolean/lit_neither_down", + "x": 90 + }, + "energized=true,facing=down,state=true": { + "model": "hexcasting:block/circle/directrix/boolean/lit_true_down", + "x": 90 + }, + "energized=true,facing=east,state=false": { + "model": "hexcasting:block/circle/directrix/boolean/lit_false_east", + "y": 90 + }, + "energized=true,facing=east,state=neither": { + "model": "hexcasting:block/circle/directrix/boolean/lit_neither_east", + "y": 90 + }, + "energized=true,facing=east,state=true": { + "model": "hexcasting:block/circle/directrix/boolean/lit_true_east", + "y": 90 + }, + "energized=true,facing=north,state=false": { + "model": "hexcasting:block/circle/directrix/boolean/lit_false_north" + }, + "energized=true,facing=north,state=neither": { + "model": "hexcasting:block/circle/directrix/boolean/lit_neither_north" + }, + "energized=true,facing=north,state=true": { + "model": "hexcasting:block/circle/directrix/boolean/lit_true_north" + }, + "energized=true,facing=south,state=false": { + "model": "hexcasting:block/circle/directrix/boolean/lit_false_south", + "y": 180 + }, + "energized=true,facing=south,state=neither": { + "model": "hexcasting:block/circle/directrix/boolean/lit_neither_south", + "y": 180 + }, + "energized=true,facing=south,state=true": { + "model": "hexcasting:block/circle/directrix/boolean/lit_true_south", + "y": 180 + }, + "energized=true,facing=up,state=false": { + "model": "hexcasting:block/circle/directrix/boolean/lit_false_up", + "x": -90 + }, + "energized=true,facing=up,state=neither": { + "model": "hexcasting:block/circle/directrix/boolean/lit_neither_up", + "x": -90 + }, + "energized=true,facing=up,state=true": { + "model": "hexcasting:block/circle/directrix/boolean/lit_true_up", + "x": -90 + }, + "energized=true,facing=west,state=false": { + "model": "hexcasting:block/circle/directrix/boolean/lit_false_west", + "y": 270 + }, + "energized=true,facing=west,state=neither": { + "model": "hexcasting:block/circle/directrix/boolean/lit_neither_west", + "y": 270 + }, + "energized=true,facing=west,state=true": { + "model": "hexcasting:block/circle/directrix/boolean/lit_true_west", + "y": 270 + } + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/blockstates/edified_fence.json b/Common/src/generated/resources/assets/hexcasting/blockstates/edified_fence.json new file mode 100644 index 000000000..7167013cf --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/blockstates/edified_fence.json @@ -0,0 +1,48 @@ +{ + "multipart": [ + { + "apply": { + "model": "hexcasting:block/edified_fence_post" + } + }, + { + "apply": { + "model": "hexcasting:block/edified_fence_side", + "uvlock": true + }, + "when": { + "north": "true" + } + }, + { + "apply": { + "model": "hexcasting:block/edified_fence_side", + "uvlock": true, + "y": 180 + }, + "when": { + "south": "true" + } + }, + { + "apply": { + "model": "hexcasting:block/edified_fence_side", + "uvlock": true, + "y": 270 + }, + "when": { + "west": "true" + } + }, + { + "apply": { + "model": "hexcasting:block/edified_fence_side", + "uvlock": true, + "y": 90 + }, + "when": { + "east": "true" + } + } + ] +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/blockstates/edified_fence_gate.json b/Common/src/generated/resources/assets/hexcasting/blockstates/edified_fence_gate.json new file mode 100644 index 000000000..f925ddfdd --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/blockstates/edified_fence_gate.json @@ -0,0 +1,80 @@ +{ + "variants": { + "facing=east,in_wall=false,open=false": { + "model": "hexcasting:block/edified_fence_gate", + "uvlock": true, + "y": 270 + }, + "facing=east,in_wall=false,open=true": { + "model": "hexcasting:block/edified_fence_gate_open", + "uvlock": true, + "y": 270 + }, + "facing=east,in_wall=true,open=false": { + "model": "hexcasting:block/edified_fence_gate_wall", + "uvlock": true, + "y": 270 + }, + "facing=east,in_wall=true,open=true": { + "model": "hexcasting:block/edified_fence_gate_wall_open", + "uvlock": true, + "y": 270 + }, + "facing=north,in_wall=false,open=false": { + "model": "hexcasting:block/edified_fence_gate", + "uvlock": true, + "y": 180 + }, + "facing=north,in_wall=false,open=true": { + "model": "hexcasting:block/edified_fence_gate_open", + "uvlock": true, + "y": 180 + }, + "facing=north,in_wall=true,open=false": { + "model": "hexcasting:block/edified_fence_gate_wall", + "uvlock": true, + "y": 180 + }, + "facing=north,in_wall=true,open=true": { + "model": "hexcasting:block/edified_fence_gate_wall_open", + "uvlock": true, + "y": 180 + }, + "facing=south,in_wall=false,open=false": { + "model": "hexcasting:block/edified_fence_gate", + "uvlock": true + }, + "facing=south,in_wall=false,open=true": { + "model": "hexcasting:block/edified_fence_gate_open", + "uvlock": true + }, + "facing=south,in_wall=true,open=false": { + "model": "hexcasting:block/edified_fence_gate_wall", + "uvlock": true + }, + "facing=south,in_wall=true,open=true": { + "model": "hexcasting:block/edified_fence_gate_wall_open", + "uvlock": true + }, + "facing=west,in_wall=false,open=false": { + "model": "hexcasting:block/edified_fence_gate", + "uvlock": true, + "y": 90 + }, + "facing=west,in_wall=false,open=true": { + "model": "hexcasting:block/edified_fence_gate_open", + "uvlock": true, + "y": 90 + }, + "facing=west,in_wall=true,open=false": { + "model": "hexcasting:block/edified_fence_gate_wall", + "uvlock": true, + "y": 90 + }, + "facing=west,in_wall=true,open=true": { + "model": "hexcasting:block/edified_fence_gate_wall_open", + "uvlock": true, + "y": 90 + } + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_false_down.json b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_false_down.json new file mode 100644 index 000000000..59d6517a5 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_false_down.json @@ -0,0 +1,12 @@ +{ + "parent": "minecraft:block/cube", + "textures": { + "down": "hexcasting:block/circle/bottom", + "east": "hexcasting:block/circle/directrix/boolean/left_false", + "north": "hexcasting:block/circle/directrix/boolean/front_dim_false", + "particle": "hexcasting:block/slate", + "south": "hexcasting:block/circle/directrix/boolean/back_not_true", + "up": "hexcasting:block/circle/directrix/boolean/top_false", + "west": "hexcasting:block/circle/directrix/boolean/right_false" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_false_east.json b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_false_east.json new file mode 100644 index 000000000..59d6517a5 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_false_east.json @@ -0,0 +1,12 @@ +{ + "parent": "minecraft:block/cube", + "textures": { + "down": "hexcasting:block/circle/bottom", + "east": "hexcasting:block/circle/directrix/boolean/left_false", + "north": "hexcasting:block/circle/directrix/boolean/front_dim_false", + "particle": "hexcasting:block/slate", + "south": "hexcasting:block/circle/directrix/boolean/back_not_true", + "up": "hexcasting:block/circle/directrix/boolean/top_false", + "west": "hexcasting:block/circle/directrix/boolean/right_false" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_false_north.json b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_false_north.json new file mode 100644 index 000000000..59d6517a5 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_false_north.json @@ -0,0 +1,12 @@ +{ + "parent": "minecraft:block/cube", + "textures": { + "down": "hexcasting:block/circle/bottom", + "east": "hexcasting:block/circle/directrix/boolean/left_false", + "north": "hexcasting:block/circle/directrix/boolean/front_dim_false", + "particle": "hexcasting:block/slate", + "south": "hexcasting:block/circle/directrix/boolean/back_not_true", + "up": "hexcasting:block/circle/directrix/boolean/top_false", + "west": "hexcasting:block/circle/directrix/boolean/right_false" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_false_south.json b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_false_south.json new file mode 100644 index 000000000..59d6517a5 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_false_south.json @@ -0,0 +1,12 @@ +{ + "parent": "minecraft:block/cube", + "textures": { + "down": "hexcasting:block/circle/bottom", + "east": "hexcasting:block/circle/directrix/boolean/left_false", + "north": "hexcasting:block/circle/directrix/boolean/front_dim_false", + "particle": "hexcasting:block/slate", + "south": "hexcasting:block/circle/directrix/boolean/back_not_true", + "up": "hexcasting:block/circle/directrix/boolean/top_false", + "west": "hexcasting:block/circle/directrix/boolean/right_false" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_false_up.json b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_false_up.json new file mode 100644 index 000000000..59d6517a5 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_false_up.json @@ -0,0 +1,12 @@ +{ + "parent": "minecraft:block/cube", + "textures": { + "down": "hexcasting:block/circle/bottom", + "east": "hexcasting:block/circle/directrix/boolean/left_false", + "north": "hexcasting:block/circle/directrix/boolean/front_dim_false", + "particle": "hexcasting:block/slate", + "south": "hexcasting:block/circle/directrix/boolean/back_not_true", + "up": "hexcasting:block/circle/directrix/boolean/top_false", + "west": "hexcasting:block/circle/directrix/boolean/right_false" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_false_west.json b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_false_west.json new file mode 100644 index 000000000..59d6517a5 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_false_west.json @@ -0,0 +1,12 @@ +{ + "parent": "minecraft:block/cube", + "textures": { + "down": "hexcasting:block/circle/bottom", + "east": "hexcasting:block/circle/directrix/boolean/left_false", + "north": "hexcasting:block/circle/directrix/boolean/front_dim_false", + "particle": "hexcasting:block/slate", + "south": "hexcasting:block/circle/directrix/boolean/back_not_true", + "up": "hexcasting:block/circle/directrix/boolean/top_false", + "west": "hexcasting:block/circle/directrix/boolean/right_false" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_neither_down.json b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_neither_down.json new file mode 100644 index 000000000..ec90eae94 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_neither_down.json @@ -0,0 +1,12 @@ +{ + "parent": "minecraft:block/cube", + "textures": { + "down": "hexcasting:block/circle/bottom", + "east": "hexcasting:block/circle/directrix/boolean/left_neither", + "north": "hexcasting:block/circle/directrix/boolean/front_not_false", + "particle": "hexcasting:block/slate", + "south": "hexcasting:block/circle/directrix/boolean/back_not_true", + "up": "hexcasting:block/circle/directrix/boolean/top_neither", + "west": "hexcasting:block/circle/directrix/boolean/right_neither" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_neither_east.json b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_neither_east.json new file mode 100644 index 000000000..ec90eae94 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_neither_east.json @@ -0,0 +1,12 @@ +{ + "parent": "minecraft:block/cube", + "textures": { + "down": "hexcasting:block/circle/bottom", + "east": "hexcasting:block/circle/directrix/boolean/left_neither", + "north": "hexcasting:block/circle/directrix/boolean/front_not_false", + "particle": "hexcasting:block/slate", + "south": "hexcasting:block/circle/directrix/boolean/back_not_true", + "up": "hexcasting:block/circle/directrix/boolean/top_neither", + "west": "hexcasting:block/circle/directrix/boolean/right_neither" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_neither_north.json b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_neither_north.json new file mode 100644 index 000000000..ec90eae94 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_neither_north.json @@ -0,0 +1,12 @@ +{ + "parent": "minecraft:block/cube", + "textures": { + "down": "hexcasting:block/circle/bottom", + "east": "hexcasting:block/circle/directrix/boolean/left_neither", + "north": "hexcasting:block/circle/directrix/boolean/front_not_false", + "particle": "hexcasting:block/slate", + "south": "hexcasting:block/circle/directrix/boolean/back_not_true", + "up": "hexcasting:block/circle/directrix/boolean/top_neither", + "west": "hexcasting:block/circle/directrix/boolean/right_neither" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_neither_south.json b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_neither_south.json new file mode 100644 index 000000000..ec90eae94 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_neither_south.json @@ -0,0 +1,12 @@ +{ + "parent": "minecraft:block/cube", + "textures": { + "down": "hexcasting:block/circle/bottom", + "east": "hexcasting:block/circle/directrix/boolean/left_neither", + "north": "hexcasting:block/circle/directrix/boolean/front_not_false", + "particle": "hexcasting:block/slate", + "south": "hexcasting:block/circle/directrix/boolean/back_not_true", + "up": "hexcasting:block/circle/directrix/boolean/top_neither", + "west": "hexcasting:block/circle/directrix/boolean/right_neither" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_neither_up.json b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_neither_up.json new file mode 100644 index 000000000..ec90eae94 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_neither_up.json @@ -0,0 +1,12 @@ +{ + "parent": "minecraft:block/cube", + "textures": { + "down": "hexcasting:block/circle/bottom", + "east": "hexcasting:block/circle/directrix/boolean/left_neither", + "north": "hexcasting:block/circle/directrix/boolean/front_not_false", + "particle": "hexcasting:block/slate", + "south": "hexcasting:block/circle/directrix/boolean/back_not_true", + "up": "hexcasting:block/circle/directrix/boolean/top_neither", + "west": "hexcasting:block/circle/directrix/boolean/right_neither" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_neither_west.json b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_neither_west.json new file mode 100644 index 000000000..ec90eae94 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_neither_west.json @@ -0,0 +1,12 @@ +{ + "parent": "minecraft:block/cube", + "textures": { + "down": "hexcasting:block/circle/bottom", + "east": "hexcasting:block/circle/directrix/boolean/left_neither", + "north": "hexcasting:block/circle/directrix/boolean/front_not_false", + "particle": "hexcasting:block/slate", + "south": "hexcasting:block/circle/directrix/boolean/back_not_true", + "up": "hexcasting:block/circle/directrix/boolean/top_neither", + "west": "hexcasting:block/circle/directrix/boolean/right_neither" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_true_down.json b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_true_down.json new file mode 100644 index 000000000..70f47f026 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_true_down.json @@ -0,0 +1,12 @@ +{ + "parent": "minecraft:block/cube", + "textures": { + "down": "hexcasting:block/circle/bottom", + "east": "hexcasting:block/circle/directrix/boolean/left_true", + "north": "hexcasting:block/circle/directrix/boolean/front_not_false", + "particle": "hexcasting:block/slate", + "south": "hexcasting:block/circle/directrix/boolean/back_dim_true", + "up": "hexcasting:block/circle/directrix/boolean/top_true", + "west": "hexcasting:block/circle/directrix/boolean/right_true" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_true_east.json b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_true_east.json new file mode 100644 index 000000000..70f47f026 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_true_east.json @@ -0,0 +1,12 @@ +{ + "parent": "minecraft:block/cube", + "textures": { + "down": "hexcasting:block/circle/bottom", + "east": "hexcasting:block/circle/directrix/boolean/left_true", + "north": "hexcasting:block/circle/directrix/boolean/front_not_false", + "particle": "hexcasting:block/slate", + "south": "hexcasting:block/circle/directrix/boolean/back_dim_true", + "up": "hexcasting:block/circle/directrix/boolean/top_true", + "west": "hexcasting:block/circle/directrix/boolean/right_true" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_true_north.json b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_true_north.json new file mode 100644 index 000000000..70f47f026 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_true_north.json @@ -0,0 +1,12 @@ +{ + "parent": "minecraft:block/cube", + "textures": { + "down": "hexcasting:block/circle/bottom", + "east": "hexcasting:block/circle/directrix/boolean/left_true", + "north": "hexcasting:block/circle/directrix/boolean/front_not_false", + "particle": "hexcasting:block/slate", + "south": "hexcasting:block/circle/directrix/boolean/back_dim_true", + "up": "hexcasting:block/circle/directrix/boolean/top_true", + "west": "hexcasting:block/circle/directrix/boolean/right_true" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_true_south.json b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_true_south.json new file mode 100644 index 000000000..70f47f026 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_true_south.json @@ -0,0 +1,12 @@ +{ + "parent": "minecraft:block/cube", + "textures": { + "down": "hexcasting:block/circle/bottom", + "east": "hexcasting:block/circle/directrix/boolean/left_true", + "north": "hexcasting:block/circle/directrix/boolean/front_not_false", + "particle": "hexcasting:block/slate", + "south": "hexcasting:block/circle/directrix/boolean/back_dim_true", + "up": "hexcasting:block/circle/directrix/boolean/top_true", + "west": "hexcasting:block/circle/directrix/boolean/right_true" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_true_up.json b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_true_up.json new file mode 100644 index 000000000..70f47f026 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_true_up.json @@ -0,0 +1,12 @@ +{ + "parent": "minecraft:block/cube", + "textures": { + "down": "hexcasting:block/circle/bottom", + "east": "hexcasting:block/circle/directrix/boolean/left_true", + "north": "hexcasting:block/circle/directrix/boolean/front_not_false", + "particle": "hexcasting:block/slate", + "south": "hexcasting:block/circle/directrix/boolean/back_dim_true", + "up": "hexcasting:block/circle/directrix/boolean/top_true", + "west": "hexcasting:block/circle/directrix/boolean/right_true" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_true_west.json b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_true_west.json new file mode 100644 index 000000000..70f47f026 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/dim_true_west.json @@ -0,0 +1,12 @@ +{ + "parent": "minecraft:block/cube", + "textures": { + "down": "hexcasting:block/circle/bottom", + "east": "hexcasting:block/circle/directrix/boolean/left_true", + "north": "hexcasting:block/circle/directrix/boolean/front_not_false", + "particle": "hexcasting:block/slate", + "south": "hexcasting:block/circle/directrix/boolean/back_dim_true", + "up": "hexcasting:block/circle/directrix/boolean/top_true", + "west": "hexcasting:block/circle/directrix/boolean/right_true" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_false_down.json b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_false_down.json new file mode 100644 index 000000000..618362394 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_false_down.json @@ -0,0 +1,12 @@ +{ + "parent": "minecraft:block/cube", + "textures": { + "down": "hexcasting:block/circle/bottom", + "east": "hexcasting:block/circle/directrix/boolean/left_false", + "north": "hexcasting:block/circle/directrix/boolean/front_lit_false", + "particle": "hexcasting:block/slate", + "south": "hexcasting:block/circle/directrix/boolean/back_not_true", + "up": "hexcasting:block/circle/directrix/boolean/top_false", + "west": "hexcasting:block/circle/directrix/boolean/right_false" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_false_east.json b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_false_east.json new file mode 100644 index 000000000..618362394 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_false_east.json @@ -0,0 +1,12 @@ +{ + "parent": "minecraft:block/cube", + "textures": { + "down": "hexcasting:block/circle/bottom", + "east": "hexcasting:block/circle/directrix/boolean/left_false", + "north": "hexcasting:block/circle/directrix/boolean/front_lit_false", + "particle": "hexcasting:block/slate", + "south": "hexcasting:block/circle/directrix/boolean/back_not_true", + "up": "hexcasting:block/circle/directrix/boolean/top_false", + "west": "hexcasting:block/circle/directrix/boolean/right_false" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_false_north.json b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_false_north.json new file mode 100644 index 000000000..618362394 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_false_north.json @@ -0,0 +1,12 @@ +{ + "parent": "minecraft:block/cube", + "textures": { + "down": "hexcasting:block/circle/bottom", + "east": "hexcasting:block/circle/directrix/boolean/left_false", + "north": "hexcasting:block/circle/directrix/boolean/front_lit_false", + "particle": "hexcasting:block/slate", + "south": "hexcasting:block/circle/directrix/boolean/back_not_true", + "up": "hexcasting:block/circle/directrix/boolean/top_false", + "west": "hexcasting:block/circle/directrix/boolean/right_false" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_false_south.json b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_false_south.json new file mode 100644 index 000000000..618362394 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_false_south.json @@ -0,0 +1,12 @@ +{ + "parent": "minecraft:block/cube", + "textures": { + "down": "hexcasting:block/circle/bottom", + "east": "hexcasting:block/circle/directrix/boolean/left_false", + "north": "hexcasting:block/circle/directrix/boolean/front_lit_false", + "particle": "hexcasting:block/slate", + "south": "hexcasting:block/circle/directrix/boolean/back_not_true", + "up": "hexcasting:block/circle/directrix/boolean/top_false", + "west": "hexcasting:block/circle/directrix/boolean/right_false" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_false_up.json b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_false_up.json new file mode 100644 index 000000000..618362394 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_false_up.json @@ -0,0 +1,12 @@ +{ + "parent": "minecraft:block/cube", + "textures": { + "down": "hexcasting:block/circle/bottom", + "east": "hexcasting:block/circle/directrix/boolean/left_false", + "north": "hexcasting:block/circle/directrix/boolean/front_lit_false", + "particle": "hexcasting:block/slate", + "south": "hexcasting:block/circle/directrix/boolean/back_not_true", + "up": "hexcasting:block/circle/directrix/boolean/top_false", + "west": "hexcasting:block/circle/directrix/boolean/right_false" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_false_west.json b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_false_west.json new file mode 100644 index 000000000..618362394 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_false_west.json @@ -0,0 +1,12 @@ +{ + "parent": "minecraft:block/cube", + "textures": { + "down": "hexcasting:block/circle/bottom", + "east": "hexcasting:block/circle/directrix/boolean/left_false", + "north": "hexcasting:block/circle/directrix/boolean/front_lit_false", + "particle": "hexcasting:block/slate", + "south": "hexcasting:block/circle/directrix/boolean/back_not_true", + "up": "hexcasting:block/circle/directrix/boolean/top_false", + "west": "hexcasting:block/circle/directrix/boolean/right_false" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_neither_down.json b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_neither_down.json new file mode 100644 index 000000000..ec90eae94 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_neither_down.json @@ -0,0 +1,12 @@ +{ + "parent": "minecraft:block/cube", + "textures": { + "down": "hexcasting:block/circle/bottom", + "east": "hexcasting:block/circle/directrix/boolean/left_neither", + "north": "hexcasting:block/circle/directrix/boolean/front_not_false", + "particle": "hexcasting:block/slate", + "south": "hexcasting:block/circle/directrix/boolean/back_not_true", + "up": "hexcasting:block/circle/directrix/boolean/top_neither", + "west": "hexcasting:block/circle/directrix/boolean/right_neither" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_neither_east.json b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_neither_east.json new file mode 100644 index 000000000..ec90eae94 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_neither_east.json @@ -0,0 +1,12 @@ +{ + "parent": "minecraft:block/cube", + "textures": { + "down": "hexcasting:block/circle/bottom", + "east": "hexcasting:block/circle/directrix/boolean/left_neither", + "north": "hexcasting:block/circle/directrix/boolean/front_not_false", + "particle": "hexcasting:block/slate", + "south": "hexcasting:block/circle/directrix/boolean/back_not_true", + "up": "hexcasting:block/circle/directrix/boolean/top_neither", + "west": "hexcasting:block/circle/directrix/boolean/right_neither" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_neither_north.json b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_neither_north.json new file mode 100644 index 000000000..ec90eae94 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_neither_north.json @@ -0,0 +1,12 @@ +{ + "parent": "minecraft:block/cube", + "textures": { + "down": "hexcasting:block/circle/bottom", + "east": "hexcasting:block/circle/directrix/boolean/left_neither", + "north": "hexcasting:block/circle/directrix/boolean/front_not_false", + "particle": "hexcasting:block/slate", + "south": "hexcasting:block/circle/directrix/boolean/back_not_true", + "up": "hexcasting:block/circle/directrix/boolean/top_neither", + "west": "hexcasting:block/circle/directrix/boolean/right_neither" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_neither_south.json b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_neither_south.json new file mode 100644 index 000000000..ec90eae94 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_neither_south.json @@ -0,0 +1,12 @@ +{ + "parent": "minecraft:block/cube", + "textures": { + "down": "hexcasting:block/circle/bottom", + "east": "hexcasting:block/circle/directrix/boolean/left_neither", + "north": "hexcasting:block/circle/directrix/boolean/front_not_false", + "particle": "hexcasting:block/slate", + "south": "hexcasting:block/circle/directrix/boolean/back_not_true", + "up": "hexcasting:block/circle/directrix/boolean/top_neither", + "west": "hexcasting:block/circle/directrix/boolean/right_neither" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_neither_up.json b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_neither_up.json new file mode 100644 index 000000000..ec90eae94 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_neither_up.json @@ -0,0 +1,12 @@ +{ + "parent": "minecraft:block/cube", + "textures": { + "down": "hexcasting:block/circle/bottom", + "east": "hexcasting:block/circle/directrix/boolean/left_neither", + "north": "hexcasting:block/circle/directrix/boolean/front_not_false", + "particle": "hexcasting:block/slate", + "south": "hexcasting:block/circle/directrix/boolean/back_not_true", + "up": "hexcasting:block/circle/directrix/boolean/top_neither", + "west": "hexcasting:block/circle/directrix/boolean/right_neither" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_neither_west.json b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_neither_west.json new file mode 100644 index 000000000..ec90eae94 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_neither_west.json @@ -0,0 +1,12 @@ +{ + "parent": "minecraft:block/cube", + "textures": { + "down": "hexcasting:block/circle/bottom", + "east": "hexcasting:block/circle/directrix/boolean/left_neither", + "north": "hexcasting:block/circle/directrix/boolean/front_not_false", + "particle": "hexcasting:block/slate", + "south": "hexcasting:block/circle/directrix/boolean/back_not_true", + "up": "hexcasting:block/circle/directrix/boolean/top_neither", + "west": "hexcasting:block/circle/directrix/boolean/right_neither" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_true_down.json b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_true_down.json new file mode 100644 index 000000000..0eac9a0e3 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_true_down.json @@ -0,0 +1,12 @@ +{ + "parent": "minecraft:block/cube", + "textures": { + "down": "hexcasting:block/circle/bottom", + "east": "hexcasting:block/circle/directrix/boolean/left_true", + "north": "hexcasting:block/circle/directrix/boolean/front_not_false", + "particle": "hexcasting:block/slate", + "south": "hexcasting:block/circle/directrix/boolean/back_lit_true", + "up": "hexcasting:block/circle/directrix/boolean/top_true", + "west": "hexcasting:block/circle/directrix/boolean/right_true" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_true_east.json b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_true_east.json new file mode 100644 index 000000000..0eac9a0e3 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_true_east.json @@ -0,0 +1,12 @@ +{ + "parent": "minecraft:block/cube", + "textures": { + "down": "hexcasting:block/circle/bottom", + "east": "hexcasting:block/circle/directrix/boolean/left_true", + "north": "hexcasting:block/circle/directrix/boolean/front_not_false", + "particle": "hexcasting:block/slate", + "south": "hexcasting:block/circle/directrix/boolean/back_lit_true", + "up": "hexcasting:block/circle/directrix/boolean/top_true", + "west": "hexcasting:block/circle/directrix/boolean/right_true" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_true_north.json b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_true_north.json new file mode 100644 index 000000000..0eac9a0e3 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_true_north.json @@ -0,0 +1,12 @@ +{ + "parent": "minecraft:block/cube", + "textures": { + "down": "hexcasting:block/circle/bottom", + "east": "hexcasting:block/circle/directrix/boolean/left_true", + "north": "hexcasting:block/circle/directrix/boolean/front_not_false", + "particle": "hexcasting:block/slate", + "south": "hexcasting:block/circle/directrix/boolean/back_lit_true", + "up": "hexcasting:block/circle/directrix/boolean/top_true", + "west": "hexcasting:block/circle/directrix/boolean/right_true" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_true_south.json b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_true_south.json new file mode 100644 index 000000000..0eac9a0e3 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_true_south.json @@ -0,0 +1,12 @@ +{ + "parent": "minecraft:block/cube", + "textures": { + "down": "hexcasting:block/circle/bottom", + "east": "hexcasting:block/circle/directrix/boolean/left_true", + "north": "hexcasting:block/circle/directrix/boolean/front_not_false", + "particle": "hexcasting:block/slate", + "south": "hexcasting:block/circle/directrix/boolean/back_lit_true", + "up": "hexcasting:block/circle/directrix/boolean/top_true", + "west": "hexcasting:block/circle/directrix/boolean/right_true" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_true_up.json b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_true_up.json new file mode 100644 index 000000000..0eac9a0e3 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_true_up.json @@ -0,0 +1,12 @@ +{ + "parent": "minecraft:block/cube", + "textures": { + "down": "hexcasting:block/circle/bottom", + "east": "hexcasting:block/circle/directrix/boolean/left_true", + "north": "hexcasting:block/circle/directrix/boolean/front_not_false", + "particle": "hexcasting:block/slate", + "south": "hexcasting:block/circle/directrix/boolean/back_lit_true", + "up": "hexcasting:block/circle/directrix/boolean/top_true", + "west": "hexcasting:block/circle/directrix/boolean/right_true" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_true_west.json b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_true_west.json new file mode 100644 index 000000000..0eac9a0e3 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/block/circle/directrix/boolean/lit_true_west.json @@ -0,0 +1,12 @@ +{ + "parent": "minecraft:block/cube", + "textures": { + "down": "hexcasting:block/circle/bottom", + "east": "hexcasting:block/circle/directrix/boolean/left_true", + "north": "hexcasting:block/circle/directrix/boolean/front_not_false", + "particle": "hexcasting:block/slate", + "south": "hexcasting:block/circle/directrix/boolean/back_lit_true", + "up": "hexcasting:block/circle/directrix/boolean/top_true", + "west": "hexcasting:block/circle/directrix/boolean/right_true" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/block/edified_fence_gate.json b/Common/src/generated/resources/assets/hexcasting/models/block/edified_fence_gate.json new file mode 100644 index 000000000..c3015ca6d --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/block/edified_fence_gate.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/template_fence_gate", + "textures": { + "texture": "hexcasting:block/edified_planks" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/block/edified_fence_gate_open.json b/Common/src/generated/resources/assets/hexcasting/models/block/edified_fence_gate_open.json new file mode 100644 index 000000000..ac141eb40 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/block/edified_fence_gate_open.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/template_fence_gate_open", + "textures": { + "texture": "hexcasting:block/edified_planks" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/block/edified_fence_gate_wall.json b/Common/src/generated/resources/assets/hexcasting/models/block/edified_fence_gate_wall.json new file mode 100644 index 000000000..ea98b1674 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/block/edified_fence_gate_wall.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/template_fence_gate_wall", + "textures": { + "texture": "hexcasting:block/edified_planks" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/block/edified_fence_gate_wall_open.json b/Common/src/generated/resources/assets/hexcasting/models/block/edified_fence_gate_wall_open.json new file mode 100644 index 000000000..86d82ca2f --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/block/edified_fence_gate_wall_open.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/template_fence_gate_wall_open", + "textures": { + "texture": "hexcasting:block/edified_planks" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/block/edified_fence_post.json b/Common/src/generated/resources/assets/hexcasting/models/block/edified_fence_post.json new file mode 100644 index 000000000..281f2acc6 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/block/edified_fence_post.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/fence_post", + "textures": { + "texture": "hexcasting:block/edified_planks" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/block/edified_fence_side.json b/Common/src/generated/resources/assets/hexcasting/models/block/edified_fence_side.json new file mode 100644 index 000000000..707af51bf --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/block/edified_fence_side.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/fence_side", + "textures": { + "texture": "hexcasting:block/edified_planks" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/item/directrix/boolean.json b/Common/src/generated/resources/assets/hexcasting/models/item/directrix/boolean.json new file mode 100644 index 000000000..cd729d804 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/item/directrix/boolean.json @@ -0,0 +1,3 @@ +{ + "parent": "hexcasting:block/circle/directrix/boolean/lit_false_east" +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/item/edified_fence.json b/Common/src/generated/resources/assets/hexcasting/models/item/edified_fence.json new file mode 100644 index 000000000..db31b0190 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/item/edified_fence.json @@ -0,0 +1,3 @@ +{ + "parent": "hexcasting:block/edified_fence_inventory" +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/item/edified_fence_gate.json b/Common/src/generated/resources/assets/hexcasting/models/item/edified_fence_gate.json new file mode 100644 index 000000000..3dfe52119 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/item/edified_fence_gate.json @@ -0,0 +1,3 @@ +{ + "parent": "hexcasting:block/edified_fence_gate" +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/item/staff/bamboo.json b/Common/src/generated/resources/assets/hexcasting/models/item/staff/bamboo.json new file mode 100644 index 000000000..cb0018898 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/item/staff/bamboo.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/handheld_rod", + "textures": { + "layer0": "hexcasting:item/staff/bamboo" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/item/staff/cherry.json b/Common/src/generated/resources/assets/hexcasting/models/item/staff/cherry.json new file mode 100644 index 000000000..1fb639851 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/item/staff/cherry.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/handheld_rod", + "textures": { + "layer0": "hexcasting:item/staff/cherry" + } +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/staff/bamboo.json b/Common/src/generated/resources/assets/hexcasting/models/staff/bamboo.json new file mode 100644 index 000000000..c0f063051 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/staff/bamboo.json @@ -0,0 +1,16 @@ +{ + "overrides": [ + { + "model": "hexcasting:item/bamboo_staff", + "predicate": { + "hexcasting:funny_level": 0.0 + } + }, + { + "model": "hexcasting:item/cherry_staff", + "predicate": { + "hexcasting:funny_level": 2.0 + } + } + ] +} \ No newline at end of file diff --git a/Common/src/generated/resources/assets/hexcasting/models/staff/cherry.json b/Common/src/generated/resources/assets/hexcasting/models/staff/cherry.json new file mode 100644 index 000000000..9a663a248 --- /dev/null +++ b/Common/src/generated/resources/assets/hexcasting/models/staff/cherry.json @@ -0,0 +1,16 @@ +{ + "overrides": [ + { + "model": "hexcasting:item/cherry_staff", + "predicate": { + "hexcasting:funny_level": 0.0 + } + }, + { + "model": "hexcasting:item/cherry_staff", + "predicate": { + "hexcasting:funny_level": 2.0 + } + } + ] +} \ No newline at end of file diff --git a/Common/src/generated/resources/data/hexcasting/advancements/aaa_wasteful_cast.json b/Common/src/generated/resources/data/hexcasting/advancements/aaa_wasteful_cast.json index 3f3346575..f99059e6a 100644 --- a/Common/src/generated/resources/data/hexcasting/advancements/aaa_wasteful_cast.json +++ b/Common/src/generated/resources/data/hexcasting/advancements/aaa_wasteful_cast.json @@ -29,5 +29,6 @@ [ "waste_amt" ] - ] + ], + "sends_telemetry_event": true } \ No newline at end of file diff --git a/Common/src/generated/resources/data/hexcasting/advancements/aab_big_cast.json b/Common/src/generated/resources/data/hexcasting/advancements/aab_big_cast.json index 8955dface..50da8818b 100644 --- a/Common/src/generated/resources/data/hexcasting/advancements/aab_big_cast.json +++ b/Common/src/generated/resources/data/hexcasting/advancements/aab_big_cast.json @@ -29,5 +29,6 @@ [ "cast_amt" ] - ] + ], + "sends_telemetry_event": true } \ No newline at end of file diff --git a/Common/src/generated/resources/data/hexcasting/advancements/enlightenment.json b/Common/src/generated/resources/data/hexcasting/advancements/enlightenment.json index 4488f2073..5bac738e0 100644 --- a/Common/src/generated/resources/data/hexcasting/advancements/enlightenment.json +++ b/Common/src/generated/resources/data/hexcasting/advancements/enlightenment.json @@ -33,5 +33,6 @@ [ "health_used" ] - ] + ], + "sends_telemetry_event": true } \ No newline at end of file diff --git a/Common/src/generated/resources/data/hexcasting/advancements/lore.json b/Common/src/generated/resources/data/hexcasting/advancements/lore.json index 9df730ebb..b4f178e9c 100644 --- a/Common/src/generated/resources/data/hexcasting/advancements/lore.json +++ b/Common/src/generated/resources/data/hexcasting/advancements/lore.json @@ -31,5 +31,6 @@ [ "used_item" ] - ] + ], + "sends_telemetry_event": true } \ No newline at end of file diff --git a/Common/src/generated/resources/data/hexcasting/advancements/lore/cardamom1.json b/Common/src/generated/resources/data/hexcasting/advancements/lore/cardamom1.json index 72ae9ab81..7156d9cf2 100644 --- a/Common/src/generated/resources/data/hexcasting/advancements/lore/cardamom1.json +++ b/Common/src/generated/resources/data/hexcasting/advancements/lore/cardamom1.json @@ -24,5 +24,6 @@ [ "grant" ] - ] + ], + "sends_telemetry_event": true } \ No newline at end of file diff --git a/Common/src/generated/resources/data/hexcasting/advancements/lore/cardamom2.json b/Common/src/generated/resources/data/hexcasting/advancements/lore/cardamom2.json index 985837365..8bd660cee 100644 --- a/Common/src/generated/resources/data/hexcasting/advancements/lore/cardamom2.json +++ b/Common/src/generated/resources/data/hexcasting/advancements/lore/cardamom2.json @@ -24,5 +24,6 @@ [ "grant" ] - ] + ], + "sends_telemetry_event": true } \ No newline at end of file diff --git a/Common/src/generated/resources/data/hexcasting/advancements/lore/cardamom3.json b/Common/src/generated/resources/data/hexcasting/advancements/lore/cardamom3.json index 540bcc57b..b51d711a7 100644 --- a/Common/src/generated/resources/data/hexcasting/advancements/lore/cardamom3.json +++ b/Common/src/generated/resources/data/hexcasting/advancements/lore/cardamom3.json @@ -24,5 +24,6 @@ [ "grant" ] - ] + ], + "sends_telemetry_event": true } \ No newline at end of file diff --git a/Common/src/generated/resources/data/hexcasting/advancements/lore/cardamom4.json b/Common/src/generated/resources/data/hexcasting/advancements/lore/cardamom4.json index 1d7cd8e71..0e6c717ba 100644 --- a/Common/src/generated/resources/data/hexcasting/advancements/lore/cardamom4.json +++ b/Common/src/generated/resources/data/hexcasting/advancements/lore/cardamom4.json @@ -24,5 +24,6 @@ [ "grant" ] - ] + ], + "sends_telemetry_event": true } \ No newline at end of file diff --git a/Common/src/generated/resources/data/hexcasting/advancements/lore/cardamom5.json b/Common/src/generated/resources/data/hexcasting/advancements/lore/cardamom5.json index 765c064cb..58e227f7b 100644 --- a/Common/src/generated/resources/data/hexcasting/advancements/lore/cardamom5.json +++ b/Common/src/generated/resources/data/hexcasting/advancements/lore/cardamom5.json @@ -24,5 +24,6 @@ [ "grant" ] - ] + ], + "sends_telemetry_event": true } \ No newline at end of file diff --git a/Common/src/generated/resources/data/hexcasting/advancements/lore/experiment1.json b/Common/src/generated/resources/data/hexcasting/advancements/lore/experiment1.json index f6a26fb8f..c87166196 100644 --- a/Common/src/generated/resources/data/hexcasting/advancements/lore/experiment1.json +++ b/Common/src/generated/resources/data/hexcasting/advancements/lore/experiment1.json @@ -24,5 +24,6 @@ [ "grant" ] - ] + ], + "sends_telemetry_event": true } \ No newline at end of file diff --git a/Common/src/generated/resources/data/hexcasting/advancements/lore/experiment2.json b/Common/src/generated/resources/data/hexcasting/advancements/lore/experiment2.json index de4705e99..e527c0242 100644 --- a/Common/src/generated/resources/data/hexcasting/advancements/lore/experiment2.json +++ b/Common/src/generated/resources/data/hexcasting/advancements/lore/experiment2.json @@ -24,5 +24,6 @@ [ "grant" ] - ] + ], + "sends_telemetry_event": true } \ No newline at end of file diff --git a/Common/src/generated/resources/data/hexcasting/advancements/lore/inventory.json b/Common/src/generated/resources/data/hexcasting/advancements/lore/inventory.json index 528479185..c8e4ba361 100644 --- a/Common/src/generated/resources/data/hexcasting/advancements/lore/inventory.json +++ b/Common/src/generated/resources/data/hexcasting/advancements/lore/inventory.json @@ -24,5 +24,6 @@ [ "grant" ] - ] + ], + "sends_telemetry_event": true } \ No newline at end of file diff --git a/Common/src/generated/resources/data/hexcasting/advancements/opened_eyes.json b/Common/src/generated/resources/data/hexcasting/advancements/opened_eyes.json index fde104661..ba036e451 100644 --- a/Common/src/generated/resources/data/hexcasting/advancements/opened_eyes.json +++ b/Common/src/generated/resources/data/hexcasting/advancements/opened_eyes.json @@ -29,5 +29,6 @@ [ "health_used" ] - ] + ], + "sends_telemetry_event": true } \ No newline at end of file diff --git a/Common/src/generated/resources/data/hexcasting/advancements/root.json b/Common/src/generated/resources/data/hexcasting/advancements/root.json index 33e7a6de6..645f76cd6 100644 --- a/Common/src/generated/resources/data/hexcasting/advancements/root.json +++ b/Common/src/generated/resources/data/hexcasting/advancements/root.json @@ -31,5 +31,6 @@ [ "has_charged_amethyst" ] - ] + ], + "sends_telemetry_event": true } \ No newline at end of file diff --git a/Common/src/generated/resources/data/hexcasting/advancements/y_u_no_cast_angy.json b/Common/src/generated/resources/data/hexcasting/advancements/y_u_no_cast_angy.json index 49ebde358..a8843f373 100644 --- a/Common/src/generated/resources/data/hexcasting/advancements/y_u_no_cast_angy.json +++ b/Common/src/generated/resources/data/hexcasting/advancements/y_u_no_cast_angy.json @@ -24,5 +24,6 @@ [ "did_the_thing" ] - ] + ], + "sends_telemetry_event": true } \ No newline at end of file diff --git a/Common/src/main/java/at/petrak/hexcasting/README.md b/Common/src/main/java/at/petrak/hexcasting/README.md index ffbae0146..bb6d151cf 100644 --- a/Common/src/main/java/at/petrak/hexcasting/README.md +++ b/Common/src/main/java/at/petrak/hexcasting/README.md @@ -2,8 +2,8 @@ Hello, intrepid Github reader! The "flavor text" words for things in this mod and the internal names are different. (Sorry.) -- A "Hex" is a `Cast`, cast through a [`CastingHarness`](api/casting/eval/vm/CastingVM.kt) +- A "Hex" is a `Continuation`, cast through a [`CastingVM`](api/casting/eval/vm/CastingVM.kt) - A "Pattern" is a [`HexPattern`](api/casting/math/HexPattern.kt) -- An "Action" is an [`Operator`](api/casting/castables/Action.kt) +- An "Action" is an [`Action`](api/casting/castables/Action.kt) - An action that pushes a spell is a [`Spell`](api/casting/castables/SpellAction.kt) 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 b57ae8f1c..8ddde5669 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/HexAPI.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/HexAPI.java @@ -19,6 +19,7 @@ import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ArmorItem; import net.minecraft.world.item.ArmorMaterial; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.Ingredient; @@ -166,12 +167,12 @@ default FrozenPigment getColorizer(Player player) { ArmorMaterial DUMMY_ARMOR_MATERIAL = new ArmorMaterial() { @Override - public int getDurabilityForSlot(@NotNull EquipmentSlot slot) { + public int getDurabilityForType(ArmorItem.Type type) { return 0; } @Override - public int getDefenseForSlot(@NotNull EquipmentSlot slot) { + public int getDefenseForType(ArmorItem.Type type) { return 0; } 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 661791544..fe85fec5b 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 @@ -14,8 +14,7 @@ public ResourceLocation getId() { } @Override - public Instance createInstance(JsonObject json, EntityPredicate.Composite predicate, - DeserializationContext pContext) { + protected Instance createInstance(JsonObject json, ContextAwarePredicate predicate, DeserializationContext context) { return new Instance(predicate); } @@ -24,8 +23,8 @@ public void trigger(ServerPlayer player) { } public static class Instance extends AbstractCriterionTriggerInstance { - public Instance(EntityPredicate.Composite pPlayer) { - super(ID, pPlayer); + public Instance(ContextAwarePredicate predicate) { + super(ID, predicate); } @Override 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 ae972d1cd..b1661e869 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 @@ -24,7 +24,7 @@ public ResourceLocation getId() { } @Override - protected Instance createInstance(JsonObject json, EntityPredicate.Composite predicate, + protected Instance createInstance(JsonObject json, ContextAwarePredicate predicate, DeserializationContext pContext) { return new Instance(predicate, MinMaxBounds.Ints.fromJson(json.get(TAG_MEDIA_GENERATED)), @@ -47,7 +47,7 @@ public static class Instance extends AbstractCriterionTriggerInstance { // DID YOU KNOW THERES ONE TO CHECK THE WORLD TIME, BUT NOT THE HEALTH!? protected final MinMaxBounds.Doubles healthLeft; - public Instance(EntityPredicate.Composite predicate, MinMaxBounds.Ints mediaGenerated, + public Instance(ContextAwarePredicate predicate, MinMaxBounds.Ints mediaGenerated, MinMaxBounds.Doubles healthUsed, MinMaxBounds.Doubles healthLeft) { super(OvercastTrigger.ID, predicate); this.mediaGenerated = mediaGenerated; 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 3679711df..aa12d472c 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 @@ -17,8 +17,8 @@ public ResourceLocation getId() { } @Override - protected Instance createInstance(JsonObject json, EntityPredicate.Composite predicate, - DeserializationContext pContext) { + protected Instance createInstance(JsonObject json, ContextAwarePredicate predicate, + DeserializationContext context) { return new Instance(predicate, MinMaxBounds.Ints.fromJson(json.get(TAG_MEDIA_SPENT)), MinMaxBounds.Ints.fromJson(json.get(TAG_MEDIA_WASTED))); @@ -32,7 +32,7 @@ public static class Instance extends AbstractCriterionTriggerInstance { protected final MinMaxBounds.Ints mediaSpent; protected final MinMaxBounds.Ints mediaWasted; - public Instance(EntityPredicate.Composite predicate, MinMaxBounds.Ints mediaSpent, + public Instance(ContextAwarePredicate predicate, MinMaxBounds.Ints mediaSpent, MinMaxBounds.Ints mediaWasted) { super(SpendMediaTrigger.ID, predicate); this.mediaSpent = mediaSpent; 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 aec3a7b29..26f39da2f 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 @@ -8,7 +8,6 @@ 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 com.mojang.math.Vector3f import net.minecraft.core.BlockPos import net.minecraft.server.level.ServerPlayer import net.minecraft.world.entity.Entity @@ -17,6 +16,7 @@ import net.minecraft.world.entity.Mob import net.minecraft.world.entity.decoration.ArmorStand import net.minecraft.world.entity.item.ItemEntity import net.minecraft.world.phys.Vec3 +import org.joml.Vector3f import java.util.function.DoubleUnaryOperator import kotlin.math.abs import kotlin.math.roundToInt @@ -238,7 +238,7 @@ fun List.getIntBetween(idx: Int, min: Int, max: Int, argc: Int = 0): Int { fun List.getBlockPos(idx: Int, argc: Int = 0): BlockPos { val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) } if (x is Vec3Iota) { - return BlockPos(x.vec3) + return BlockPos.containing(x.vec3) } throw MishapInvalidIota.ofType(x, if (argc == 0) idx else argc - (idx + 1), "vector") diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/RenderedSpell.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/RenderedSpell.kt index 1240d3b72..20ea047d9 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/RenderedSpell.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/RenderedSpell.kt @@ -1,7 +1,13 @@ package at.petrak.hexcasting.api.casting import at.petrak.hexcasting.api.casting.eval.CastingEnvironment +import at.petrak.hexcasting.api.casting.eval.vm.CastingImage interface RenderedSpell { - fun cast(ctx: CastingEnvironment) + fun cast(env: CastingEnvironment) + + fun cast(env: CastingEnvironment, image: CastingImage): CastingImage? { + cast(env) + return null + } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/engine/ArithmeticEngine.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/engine/ArithmeticEngine.java index 515631e20..2f7e1fe7d 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/engine/ArithmeticEngine.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/engine/ArithmeticEngine.java @@ -2,6 +2,10 @@ import at.petrak.hexcasting.api.casting.arithmetic.Arithmetic; import at.petrak.hexcasting.api.casting.arithmetic.operator.Operator; +import at.petrak.hexcasting.api.casting.eval.CastingEnvironment; +import at.petrak.hexcasting.api.casting.eval.OperationResult; +import at.petrak.hexcasting.api.casting.eval.vm.CastingImage; +import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation; import at.petrak.hexcasting.api.casting.iota.Iota; import at.petrak.hexcasting.api.casting.math.HexPattern; import at.petrak.hexcasting.api.casting.mishaps.Mishap; @@ -63,28 +67,34 @@ public Iterable operatorSyms() { /** * Runs one of the contained Operators assigned to the given pattern, modifying the passed stack of iotas. * @param pattern The pattern that was drawn, used to determine which operators are candidates. - * @param iotas The current stack. - * @param startingLength The length of the stack before the operator executes (used for errors). + * @param env The casting environment. + * @param image The casting image. + * @param continuation The current continuation. * @return The iotas to be added to the stack. * @throws Mishap mishaps if invalid input to the operators is given by the caster. */ - public Iterable run(HexPattern pattern, Stack iotas, int startingLength) throws Mishap { + public OperationResult run(HexPattern pattern, CastingEnvironment env, CastingImage image, SpellContinuation continuation) throws Mishap { + var stackList = image.getStack(); + var stack = new Stack(); + stack.addAll(stackList); + var startingLength = stackList.size(); + var candidates = operators.get(pattern); if (candidates == null) throw new InvalidOperatorException("the pattern " + pattern + " is not an operator."); // HashCons hash = new HashCons.Pattern(pattern); var args = new ArrayList(candidates.arity()); for (var i = 0; i < candidates.arity(); i++) { - if (iotas.isEmpty()) { + if (stack.isEmpty()) { throw new MishapNotEnoughArgs(candidates.arity, startingLength); } - var iota = iotas.pop(); + var iota = stack.pop(); hash = new HashCons.Pair(iota.getType(), hash); args.add(iota); } Collections.reverse(args); var op = resolveCandidates(args, hash, candidates); - return op.apply(args); + return op.operate(env, image, continuation); } private Operator resolveCandidates(List args, HashCons hash, OpCandidates candidates) { diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/operator/Operator.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/operator/Operator.java deleted file mode 100644 index cab8b216b..000000000 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/operator/Operator.java +++ /dev/null @@ -1,53 +0,0 @@ -package at.petrak.hexcasting.api.casting.arithmetic.operator; - -import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate; -import at.petrak.hexcasting.api.casting.iota.Iota; -import at.petrak.hexcasting.api.casting.iota.IotaType; -import at.petrak.hexcasting.api.casting.mishaps.Mishap; -import org.jetbrains.annotations.NotNull; - -/** - * Represents an Operator, similar to Action except that it also has a defined set of IotaTypes that it accepts, and - * there can be multiple Operators 'assigned' to the same pattern in different Arithmetics as long as they don't have - * overlapping matched types. (Overlapping matched types is not checked for, but will have undefined behaviour). - */ -public abstract class Operator { - /** - * The number of arguments from the stack that this Operator requires; all Operators with the same pattern must have - * the same arity. - */ - public final int arity; - - /** - * A function that should return true if the passed list of Iotas satisfies this Operator's type constraints, and false otherwise. - */ - public final IotaMultiPredicate accepts; - - /** - * @param arity The number of arguments from the stack that this Operator requires; all Operators with the same pattern must have arity. - * @param accepts A function that should return true if the passed list of Iotas satisfies this Operator's type constraints, and false otherwise. - */ - public Operator(int arity, IotaMultiPredicate accepts) { - this.arity = arity; - this.accepts = accepts; - } - - /** - /** - * The method called when this Operator is actually acting on the stack, for real. - * @param iotas An iterable of iotas with {@link Operator#arity} elements that satisfied {@link Operator#accepts}. - * @return the iotas that this operator will return to the stack (with the first element of the returned iterable being placed deepest into the stack, and the last element on top of the stack). - * @throws Mishap if the Operator mishaps for any reason it will be passed up the chain. - */ - public abstract @NotNull Iterable apply(@NotNull Iterable iotas) throws Mishap; - - /** - * A helper method to take an iota that you know is of iotaType and returning it as an iota of that type. - */ - @SuppressWarnings("unchecked") - public static T downcast(Iota iota, IotaType iotaType) { - if (iota.getType() != iotaType) - throw new IllegalStateException("Attempting to downcast " + iota + " to type: " + iotaType); - return (T) iota; - } -} diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/operator/Operator.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/operator/Operator.kt new file mode 100644 index 000000000..8804e0d62 --- /dev/null +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/operator/Operator.kt @@ -0,0 +1,43 @@ +package at.petrak.hexcasting.api.casting.arithmetic.operator + +import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate +import at.petrak.hexcasting.api.casting.eval.CastingEnvironment +import at.petrak.hexcasting.api.casting.eval.OperationResult +import at.petrak.hexcasting.api.casting.eval.vm.CastingImage +import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation +import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.casting.iota.IotaType +import at.petrak.hexcasting.api.casting.mishaps.Mishap +import at.petrak.hexcasting.common.lib.hex.HexEvalSounds +import java.util.function.Consumer + +abstract class Operator +/** + * @param arity The number of arguments from the stack that this Operator requires; all Operators with the same pattern must have arity. + * @param accepts A function that should return true if the passed list of Iotas satisfies this Operator's type constraints, and false otherwise. + */ + ( + @JvmField + val arity: Int, + @JvmField + val accepts: IotaMultiPredicate +) { + + /** + * Functionally update the image. Return the image and any side effects. + */ + @Throws(Mishap::class) + abstract fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult + + + companion object { + /** + * A helper method to take an iota that you know is of iotaType and returning it as an iota of that type. + */ + @JvmStatic + fun downcast(iota: Iota, iotaType: IotaType): T { + check(iota.type === iotaType) { "Attempting to downcast $iota to type: $iotaType" } + return iota as T + } + } +} \ No newline at end of file diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/operator/OperatorBasic.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/operator/OperatorBasic.kt new file mode 100644 index 000000000..1d43c890c --- /dev/null +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/operator/OperatorBasic.kt @@ -0,0 +1,39 @@ +package at.petrak.hexcasting.api.casting.arithmetic.operator + +import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate +import at.petrak.hexcasting.api.casting.eval.CastingEnvironment +import at.petrak.hexcasting.api.casting.eval.OperationResult +import at.petrak.hexcasting.api.casting.eval.vm.CastingImage +import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation +import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.casting.mishaps.Mishap +import at.petrak.hexcasting.common.lib.hex.HexEvalSounds +import java.util.function.Consumer + +abstract class OperatorBasic(arity: Int, accepts: IotaMultiPredicate) : Operator(arity, accepts) { + + @Throws(Mishap::class) + override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult { + val stack = image.stack.toMutableList() + val args = stack.takeLast(arity) + repeat(arity) { stack.removeLast() } + + val ret = apply(args, env) + ret.forEach(Consumer { e: Iota -> stack.add(e) }) + + val image2 = image.copy(stack = stack, opsConsumed = image.opsConsumed + 1) + return OperationResult(image2, listOf(), continuation, HexEvalSounds.NORMAL_EXECUTE) + } + + /** + * / ** + * The method called when this Operator is actually acting on the stack, for real. + * @param iotas An iterable of iotas with [Operator.arity] elements that satisfied [Operator.accepts]. + * @param env The casting environment, to make use of if this operator needs it. + * @return the iotas that this operator will return to the stack (with the first element of the returned iterable being placed deepest into the stack, and the last element on top of the stack). + * @throws Mishap if the Operator mishaps for any reason it will be passed up the chain. + */ + @Throws(Mishap::class) + abstract fun apply(iotas: Iterable, env: CastingEnvironment): Iterable + +} \ No newline at end of file diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/operator/OperatorBinary.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/operator/OperatorBinary.java index 5baa7f06f..02914dc4d 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/operator/OperatorBinary.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/operator/OperatorBinary.java @@ -2,6 +2,7 @@ import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate; +import at.petrak.hexcasting.api.casting.eval.CastingEnvironment; import at.petrak.hexcasting.api.casting.iota.Iota; import org.jetbrains.annotations.NotNull; @@ -11,7 +12,7 @@ /** * A helper class for defining {@link Operator}s of two iotas. */ -public class OperatorBinary extends Operator { +public class OperatorBinary extends OperatorBasic { public BinaryOperator inner; public OperatorBinary(IotaMultiPredicate accepts, BinaryOperator inner) { @@ -20,7 +21,7 @@ public OperatorBinary(IotaMultiPredicate accepts, BinaryOperator inner) { } @Override - public @NotNull Iterable apply(@NotNull Iterable iotas) { + public @NotNull Iterable apply(Iterable iotas, @NotNull CastingEnvironment env) { var it = iotas.iterator(); return List.of(inner.apply(it.next(), it.next())); } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/operator/OperatorUnary.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/operator/OperatorUnary.java index bce499022..9797b83b1 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/operator/OperatorUnary.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/operator/OperatorUnary.java @@ -2,6 +2,7 @@ import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate; +import at.petrak.hexcasting.api.casting.eval.CastingEnvironment; import at.petrak.hexcasting.api.casting.iota.Iota; import org.jetbrains.annotations.NotNull; @@ -11,7 +12,7 @@ /** * A helper class for defining {@link Operator}s of one iota. */ -public class OperatorUnary extends Operator { +public class OperatorUnary extends OperatorBasic { public UnaryOperator inner; public OperatorUnary(IotaMultiPredicate accepts, UnaryOperator inner) { @@ -20,7 +21,7 @@ public OperatorUnary(IotaMultiPredicate accepts, UnaryOperator inner) { } @Override - public @NotNull Iterable apply(@NotNull Iterable iotas) { + public @NotNull Iterable apply(Iterable iotas, @NotNull CastingEnvironment env) { return List.of(inner.apply(iotas.iterator().next())); } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/predicates/IotaMultiPredicate.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/predicates/IotaMultiPredicate.java index 4c960080c..63a64b5a0 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/predicates/IotaMultiPredicate.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/predicates/IotaMultiPredicate.java @@ -34,6 +34,14 @@ static IotaMultiPredicate triple(IotaPredicate first, IotaPredicate second, Iota static IotaMultiPredicate any(IotaPredicate needs, IotaPredicate fallback) { return new Any(needs, fallback); } + + /** + * The resulting IotaMultiPredicate returns true if either the first returns true or the second returns true. + */ + static IotaMultiPredicate either(IotaMultiPredicate first, IotaMultiPredicate second) { + return new Either(first, second); + } + record Pair(IotaPredicate first, IotaPredicate second) implements IotaMultiPredicate { @Override public boolean test(Iterable iotas) { @@ -73,4 +81,11 @@ public boolean test(Iterable iotas) { return true; } } + + record Either(IotaMultiPredicate first, IotaMultiPredicate second) implements IotaMultiPredicate { + @Override + public boolean test(Iterable iotas) { + return first.test(iotas) || second.test(iotas); + } + } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/predicates/IotaPredicate.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/predicates/IotaPredicate.java index afc270d5d..41d064814 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/predicates/IotaPredicate.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/predicates/IotaPredicate.java @@ -3,6 +3,8 @@ import at.petrak.hexcasting.api.casting.iota.Iota; import at.petrak.hexcasting.api.casting.iota.IotaType; +import java.util.List; + /** * Used to determine whether a given iota is an acceptable type for the operator that is storing this. It must be strictly a function * of the passed Iota's IotaType, or the caching done by ArithmeticEngine will be invalid. @@ -18,6 +20,14 @@ static IotaPredicate or(IotaPredicate left, IotaPredicate right) { return new Or(left, right); } + static IotaPredicate any(IotaPredicate... any) { + return new Any(any); + } + + static IotaPredicate any(List any) { + return new Any(any.toArray(IotaPredicate[]::new)); + } + /** * The resulting IotaPredicate returns true if the given iota's type is type. */ @@ -32,6 +42,18 @@ public boolean test(Iota iota) { } } + record Any(IotaPredicate[] any) implements IotaPredicate { + + @Override + public boolean test(Iota iota) { + for (var i : any) { + if (i.test(iota)) + return true; + } + return false; + } + } + record OfType(IotaType type) implements IotaPredicate { @Override public boolean test(Iota iota) { diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/ConstMediaAction.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/ConstMediaAction.kt index 6c4cab403..a907764c7 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/ConstMediaAction.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/ConstMediaAction.kt @@ -14,7 +14,7 @@ import at.petrak.hexcasting.common.lib.hex.HexEvalSounds */ interface ConstMediaAction : Action { val argc: Int - val mediaCost: Int + val mediaCost: Long get() = 0 fun execute(args: List, env: CastingEnvironment): List diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/OperationAction.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/OperationAction.kt index 4edb98204..c2c5b06ee 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/OperationAction.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/OperationAction.kt @@ -5,13 +5,9 @@ import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.eval.OperationResult import at.petrak.hexcasting.api.casting.eval.vm.CastingImage import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation -import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.math.HexPattern import at.petrak.hexcasting.api.casting.mishaps.MishapInvalidOperatorArgs import at.petrak.hexcasting.common.lib.hex.HexArithmetics -import at.petrak.hexcasting.common.lib.hex.HexEvalSounds -import java.util.* -import java.util.function.Consumer /** * Represents an Operator with the give pattern as its identifier, a special type of Action that calls a different function depending on the type of its arguments. @@ -19,15 +15,8 @@ import java.util.function.Consumer */ data class OperationAction(val pattern: HexPattern) : Action { override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult { - val stackList = image.stack - val stack = Stack() - stack.addAll(stackList) - val startingLength = stackList.size return try { - val ret: Iterable = HexArithmetics.getEngine().run(pattern, stack, startingLength) - ret.forEach(Consumer { e: Iota -> stack.add(e) }) - val image2 = image.copy(stack = stack, opsConsumed = image.opsConsumed + 1) // TODO: maybe let operators figure out how many ops to consume? - OperationResult(image2, listOf(), continuation, HexEvalSounds.NORMAL_EXECUTE) + HexArithmetics.getEngine().run(pattern, env, image, continuation) } catch (e: NoOperatorCandidatesException) { throw MishapInvalidOperatorArgs(e.args, e.pattern) } 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 3816f6ed3..bcea2cd95 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 @@ -21,13 +21,13 @@ interface SpellAction : Action { fun execute( args: List, - ctx: CastingEnvironment + env: CastingEnvironment ): Result fun executeWithUserdata( - args: List, ctx: CastingEnvironment, userData: CompoundTag + args: List, env: CastingEnvironment, userData: CompoundTag ): Result { - return this.execute(args, ctx) + return this.execute(args, env) } override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult { @@ -64,5 +64,5 @@ interface SpellAction : Action { return OperationResult(image2, sideEffects, continuation, sound) } - data class Result(val effect: RenderedSpell, val cost: Int, val particles: List, val opCount: Long = 1) + data class Result(val effect: RenderedSpell, val cost: Long, val particles: List, val opCount: Long = 1) } 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 b94efc149..c0b4d4442 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 @@ -4,17 +4,20 @@ import at.petrak.hexcasting.api.casting.eval.sideeffects.EvalSound import at.petrak.hexcasting.api.casting.eval.sideeffects.OperatorSideEffect import at.petrak.hexcasting.api.casting.eval.vm.CastingImage 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. * - * Contains the next thing to execute after this is finished, the modified state of the stack, + * 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, * and side effects, as well as display information for the client. */ data class CastResult( - val continuation: SpellContinuation, - val newData: CastingImage?, - val sideEffects: List, - val resolutionType: ResolvedPatternType, - val sound: EvalSound, + val cast: Iota, + val continuation: SpellContinuation, + val newData: CastingImage?, + val sideEffects: List, + val resolutionType: ResolvedPatternType, + val sound: EvalSound, ) 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 784efa7c7..59453dcd7 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 @@ -16,22 +16,59 @@ import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.phys.Vec3; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.function.Consumer; import java.util.function.Predicate; +import static at.petrak.hexcasting.api.HexAPI.modLoc; +import static at.petrak.hexcasting.api.casting.eval.CastingEnvironmentComponent.*; + /** * Environment within which hexes are cast. *

* Stuff like "the player with a staff," "the player with a trinket," "spell circles," */ public abstract class CastingEnvironment { + /** + * Stores all listeners that should be notified whenever a CastingEnvironment is initialised. + */ + private static final List> createEventListeners = new ArrayList<>(); + + /** + * Add a listener that will be called whenever a new CastingEnvironment is created. + */ + public static void addCreateEventListener(Consumer listener) { + createEventListeners.add(listener); + } + + private boolean createEventTriggered = false; + + public final void triggerCreateEvent() { + if (!createEventTriggered) { + for (var listener : createEventListeners) + listener.accept(this); + createEventTriggered = true; + } + } + + protected final ServerLevel world; + protected Map, @NotNull CastingEnvironmentComponent> componentMap = new HashMap<>(); + private final List postExecutions = new ArrayList<>(); + private final List extractMedias = new ArrayList<>(); + private final List isVecInRanges = new ArrayList<>(); + private final List hasEditPermissionsAts = new ArrayList<>(); + protected CastingEnvironment(ServerLevel world) { this.world = world; } @@ -54,6 +91,39 @@ public final ServerLevel getWorld() { */ public abstract MishapEnvironment getMishapEnvironment(); + public void addExtension(@NotNull T extension) { + componentMap.put(extension.getKey(), extension); + if (extension instanceof PostExecution postExecution) + postExecutions.add(postExecution); + if (extension instanceof ExtractMedia extractMedia) + extractMedias.add(extractMedia); + if (extension instanceof IsVecInRange isVecInRange) + isVecInRanges.add(isVecInRange); + if (extension instanceof HasEditPermissionsAt hasEditPermissionsAt) + hasEditPermissionsAts.add(hasEditPermissionsAt); + } + + public void removeExtension(@NotNull CastingEnvironmentComponent.Key key) { + var extension = componentMap.remove(key); + if (extension == null) + return; + + if (extension instanceof PostExecution postExecution) + postExecutions.remove(postExecution); + if (extension instanceof ExtractMedia extractMedia) + extractMedias.remove(extractMedia); + if (extension instanceof IsVecInRange isVecInRange) + isVecInRanges.remove(isVecInRange); + if (extension instanceof HasEditPermissionsAt hasEditPermissionsAt) + hasEditPermissionsAts.remove(hasEditPermissionsAt); + } + + @Nullable + @SuppressWarnings("unchecked") + public T getExtension(@NotNull CastingEnvironmentComponent.Key key) { + return (T) componentMap.get(key); + } + /** * If something about this ARE itself is invalid, mishap. *

@@ -62,6 +132,15 @@ public final ServerLevel getWorld() { public void precheckAction(PatternShapeMatch match) throws Mishap { // TODO: this doesn't let you select special handlers. // Might be worth making a "no casting" tag on each thing + ResourceLocation key = actionKey(match); + + if (!HexConfig.server().isActionAllowed(key)) { + throw new MishapDisallowedSpell(); + } + } + + @Nullable + protected ResourceLocation actionKey(PatternShapeMatch match) { ResourceLocation key; if (match instanceof PatternShapeMatch.Normal normal) { key = normal.key.location(); @@ -72,15 +151,16 @@ public void precheckAction(PatternShapeMatch match) throws Mishap { } else { key = null; } - if (!HexConfig.server().isActionAllowed(key)) { - throw new MishapDisallowedSpell(); - } + return key; } /** * Do whatever you like after a pattern is executed. */ - public abstract void postExecution(CastResult result); + public void postExecution(CastResult result) { + for (var postExecutionComponent : postExecutions) + postExecutionComponent.onPostExecution(result); + } public abstract Vec3 mishapSprayPos(); @@ -88,7 +168,27 @@ public void precheckAction(PatternShapeMatch match) throws Mishap { * Return whether this env can cast great spells. */ public boolean isEnlightened() { - return false; + var caster = this.getCaster(); + if (caster == null) + return false; + + var adv = this.world.getServer().getAdvancements().getAdvancement(modLoc("enlightenment")); + if (adv == null) + return false; + + return caster.getAdvancements().getOrStartProgress(adv).isDone(); + } + + /** + * Attempt to extract the given amount of media. Returns the amount of media left in the cost. + *

+ * If there was enough media found, it will return less or equal to zero; if there wasn't, it will be + * positive. + */ + public long extractMedia(long cost) { + for (var extractMediaComponent : extractMedias) + cost = extractMediaComponent.onExtractMedia(cost); + return extractMediaEnvironment(cost); } /** @@ -97,22 +197,44 @@ public boolean isEnlightened() { * If there was enough media found, it will return less or equal to zero; if there wasn't, it will be * positive. */ - public abstract long extractMedia(long cost); + protected abstract long extractMediaEnvironment(long cost); + + /** + * Get if the vec is close enough, to the player or sentinel ... + *

+ * Doesn't take into account being out of the world. + */ + public boolean isVecInRange(Vec3 vec) { + boolean isInRange = isVecInRangeEnvironment(vec); + for (var isVecInRangeComponent : isVecInRanges) + isInRange = isVecInRangeComponent.onIsVecInRange(vec, isInRange); + return isInRange; + } /** * Get if the vec is close enough, to the player or sentinel ... *

* Doesn't take into account being out of the world. */ - public abstract boolean isVecInRange(Vec3 vec); + protected abstract boolean isVecInRangeEnvironment(Vec3 vec); + + /** + * Return whether the caster can edit blocks at the given permission (i.e. not adventure mode, etc.) + */ + public boolean hasEditPermissionsAt(BlockPos pos) { + boolean hasEditPermissionsAt = hasEditPermissionsAtEnvironment(pos); + for (var hasEditPermissionsAtComponent : hasEditPermissionsAts) + hasEditPermissionsAt = hasEditPermissionsAtComponent.onHasEditPermissionsAt(pos, hasEditPermissionsAt); + return hasEditPermissionsAt; + } /** * Return whether the caster can edit blocks at the given permission (i.e. not adventure mode, etc.) */ - public abstract boolean hasEditPermissionsAt(BlockPos vec); + protected abstract boolean hasEditPermissionsAtEnvironment(BlockPos pos); public final boolean isVecInWorld(Vec3 vec) { - return this.world.isInWorldBounds(new BlockPos(vec)) + return this.world.isInWorldBounds(BlockPos.containing(vec)) && this.world.getWorldBorder().isWithinBounds(vec.x, vec.z, 0.5); } @@ -121,7 +243,7 @@ public final boolean isVecInAmbit(Vec3 vec) { } public final boolean isEntityInRange(Entity e) { - return this.isVecInRange(e.position()); + return e instanceof Player || this.isVecInRange(e.position()); } /** @@ -175,14 +297,6 @@ public InteractionHand getOtherHand() { return HexUtils.otherHand(this.getCastingHand()); } - /** - * Get the item in the "other hand." - *

- * If that hand is empty, or if they cannot have that hand, return Empty. - * Probably return a clone of Empty, actually... - */ - public abstract ItemStack getAlternateItem(); - /** * Get all the item stacks this env can use. */ @@ -258,6 +372,9 @@ public boolean withdrawItem(Predicate stackOk, int count, boolean act if (stackOk.test(stack)) { presentCount += stack.getCount(); matches.add(stack); + + if (presentCount >= count) + break; } } if (presentCount < count) { @@ -268,7 +385,7 @@ public boolean withdrawItem(Predicate stackOk, int count, boolean act return true; } // Otherwise do the removal - var remaining = presentCount; + var remaining = count; for (ItemStack match : matches) { var toWithdraw = Math.min(match.getCount(), remaining); match.shrink(toWithdraw); @@ -282,6 +399,12 @@ public boolean withdrawItem(Predicate stackOk, int count, boolean act throw new IllegalStateException("unreachable"); } + /** + * Attempt to replace the first stack found which matches the predicate with the stack to replace with. + * @return whether it was successful. + */ + public abstract boolean replaceItem(Predicate stackOk, ItemStack replaceWith, @Nullable InteractionHand hand); + /** * The order/mode stacks should be discovered in */ diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastingEnvironmentComponent.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastingEnvironmentComponent.java new file mode 100644 index 000000000..fd8de3da7 --- /dev/null +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastingEnvironmentComponent.java @@ -0,0 +1,41 @@ +package at.petrak.hexcasting.api.casting.eval; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.phys.Vec3; + +public interface CastingEnvironmentComponent { + Key getKey(); + + interface Key {} + + interface PostExecution extends CastingEnvironmentComponent { + /** + * Do whatever you like after a pattern is executed. + */ + void onPostExecution(CastResult result); + } + + interface ExtractMedia extends CastingEnvironmentComponent { + /** + * Receives the cost that is being extracted, should return the + * remaining cost after deducting whatever cost source this component + * is responsible for (should be >= 0). All Components are executed + * before the CastingEnvironment's extractMedia is executed. + */ + long onExtractMedia(long cost); + } + + interface IsVecInRange extends CastingEnvironmentComponent { + /** + * Receives the vec, and the current return value, and returns the new return value. + */ + boolean onIsVecInRange(Vec3 vec, boolean current); + } + + interface HasEditPermissionsAt extends CastingEnvironmentComponent { + /** + * Receives the vec, and the current return value, and returns the new return value. + */ + boolean onHasEditPermissionsAt(BlockPos pos, boolean current); + } +} 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 1bb5d3a9b..7bbda1ea3 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 @@ -2,26 +2,31 @@ import at.petrak.hexcasting.api.HexAPI; import at.petrak.hexcasting.api.casting.ParticleSpray; +import at.petrak.hexcasting.api.casting.PatternShapeMatch; import at.petrak.hexcasting.api.casting.circles.BlockEntityAbstractImpetus; import at.petrak.hexcasting.api.casting.circles.CircleExecutionState; import at.petrak.hexcasting.api.casting.eval.CastResult; import at.petrak.hexcasting.api.casting.eval.CastingEnvironment; import at.petrak.hexcasting.api.casting.eval.MishapEnvironment; import at.petrak.hexcasting.api.casting.eval.sideeffects.OperatorSideEffect; +import at.petrak.hexcasting.api.casting.mishaps.Mishap; +import at.petrak.hexcasting.api.casting.mishaps.MishapDisallowedSpell; +import at.petrak.hexcasting.api.mod.HexConfig; import at.petrak.hexcasting.api.pigment.FrozenPigment; import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.sounds.SoundSource; import net.minecraft.world.InteractionHand; -import net.minecraft.world.item.DyeColor; import net.minecraft.world.item.ItemStack; import net.minecraft.world.phys.Vec3; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; +import java.util.function.Predicate; import static at.petrak.hexcasting.api.casting.eval.env.PlayerBasedCastEnv.SENTINEL_RADIUS; @@ -55,8 +60,21 @@ public MishapEnvironment getMishapEnvironment() { return new CircleMishapEnv(this.world, this.execState); } + @Override + public void precheckAction(PatternShapeMatch match) throws Mishap { + super.precheckAction(match); + + ResourceLocation key = actionKey(match); + + if (!HexConfig.server().isActionAllowedInCircles(key)) { + throw new MishapDisallowedSpell("disallowed_circle"); + } + } + @Override public void postExecution(CastResult result) { + super.postExecution(result); + // we always want to play this sound one at a time var sound = result.getSound().sound(); if (sound != null) { @@ -87,7 +105,7 @@ public Vec3 mishapSprayPos() { } @Override - public long extractMedia(long cost) { + public long extractMediaEnvironment(long cost) { var entity = this.getImpetus(); if (entity == null) return cost; @@ -104,13 +122,13 @@ public long extractMedia(long cost) { } @Override - public boolean isVecInRange(Vec3 vec) { + public boolean isVecInRangeEnvironment(Vec3 vec) { var caster = this.execState.getCaster(this.world); if (caster != null) { var sentinel = HexAPI.instance().getSentinel(caster); if (sentinel != null && sentinel.extendsRange() - && caster.getLevel().dimension() == sentinel.dimension() + && caster.level().dimension() == sentinel.dimension() && vec.distanceToSqr(sentinel.position()) <= SENTINEL_RADIUS * SENTINEL_RADIUS ) { return true; @@ -121,7 +139,7 @@ public boolean isVecInRange(Vec3 vec) { } @Override - public boolean hasEditPermissionsAt(BlockPos vec) { + public boolean hasEditPermissionsAtEnvironment(BlockPos pos) { return true; } @@ -130,11 +148,6 @@ public InteractionHand getCastingHand() { return InteractionHand.MAIN_HAND; } - @Override - public ItemStack getAlternateItem() { - return ItemStack.EMPTY.copy(); // TODO: adjacent inventory/item frame? - } - @Override protected List getUsableStacks(StackDiscoveryMode mode) { return new ArrayList<>(); // TODO: Could do something like get items in inventories adjacent to the circle? @@ -145,6 +158,11 @@ protected List getPrimaryStacks() { return List.of(); // TODO: Adjacent inv! } + @Override + public boolean replaceItem(Predicate stackOk, ItemStack replaceWith, @Nullable InteractionHand hand) { + return false; // TODO: Adjacent inv! + } + @Override public FrozenPigment getPigment() { var impetus = this.getImpetus(); diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PackagedItemCastEnv.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PackagedItemCastEnv.java index 984a08893..2a736d55d 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PackagedItemCastEnv.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PackagedItemCastEnv.java @@ -2,12 +2,16 @@ import at.petrak.hexcasting.api.casting.eval.CastResult; import at.petrak.hexcasting.api.casting.eval.sideeffects.EvalSound; +import at.petrak.hexcasting.api.casting.iota.PatternIota; import at.petrak.hexcasting.api.pigment.FrozenPigment; import at.petrak.hexcasting.common.lib.hex.HexEvalSounds; +import at.petrak.hexcasting.common.msgs.MsgNewSpiralPatternsS2C; import at.petrak.hexcasting.xplat.IXplatAbstractions; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.InteractionHand; +import java.util.List; + public class PackagedItemCastEnv extends PlayerBasedCastEnv { protected EvalSound sound = HexEvalSounds.NOTHING; @@ -19,17 +23,28 @@ public PackagedItemCastEnv(ServerPlayer caster, InteractionHand castingHand) { @Override public void postExecution(CastResult result) { super.postExecution(result); + + if (result.component1() instanceof PatternIota patternIota) { + var packet = new MsgNewSpiralPatternsS2C( + this.caster.getUUID(), List.of(patternIota.getPattern()), 140 + ); + IXplatAbstractions.INSTANCE.sendPacketToPlayer(this.caster, packet); + IXplatAbstractions.INSTANCE.sendPacketTracking(this.caster, packet); + } + // TODO: how do we know when to actually play this sound? this.sound = this.sound.greaterOf(result.getSound()); } @Override - public long extractMedia(long costLeft) { + public long extractMediaEnvironment(long costLeft) { if (this.caster.isCreative()) return 0; var casterStack = this.caster.getItemInHand(this.castingHand); var casterHexHolder = IXplatAbstractions.INSTANCE.findHexHolder(casterStack); + if (casterHexHolder == null) + return costLeft; var canCastFromInv = casterHexHolder.canDrawMediaFromInventory(); var casterMediaHolder = IXplatAbstractions.INSTANCE.findMediaHolder(casterStack); @@ -56,7 +71,12 @@ public InteractionHand getCastingHand() { public FrozenPigment getPigment() { var casterStack = this.caster.getItemInHand(this.castingHand); var casterHexHolder = IXplatAbstractions.INSTANCE.findHexHolder(casterStack); - return casterHexHolder.getPigment(); + if (casterHexHolder == null) + return IXplatAbstractions.INSTANCE.getPigment(this.caster); + var hexHolderPigment = casterHexHolder.getPigment(); + if (hexHolderPigment != null) + return hexHolderPigment; + return IXplatAbstractions.INSTANCE.getPigment(this.caster); } public EvalSound getSound() { 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 f81fce9eb..724028803 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 @@ -9,12 +9,12 @@ import at.petrak.hexcasting.api.casting.eval.MishapEnvironment; import at.petrak.hexcasting.api.casting.eval.sideeffects.OperatorSideEffect; import at.petrak.hexcasting.api.casting.mishaps.Mishap; -import at.petrak.hexcasting.api.misc.HexDamageSources; import at.petrak.hexcasting.api.mod.HexConfig; import at.petrak.hexcasting.api.mod.HexStatistics; 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.HexDamageTypes; import at.petrak.hexcasting.xplat.IXplatAbstractions; import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; @@ -29,6 +29,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.function.Predicate; import static at.petrak.hexcasting.api.HexAPI.modLoc; @@ -40,18 +41,20 @@ public abstract class PlayerBasedCastEnv extends CastingEnvironment { protected final InteractionHand castingHand; protected PlayerBasedCastEnv(ServerPlayer caster, InteractionHand castingHand) { - super(caster.getLevel()); + super(caster.serverLevel()); this.caster = caster; this.castingHand = castingHand; } @Override - public @Nullable ServerPlayer getCaster() { + public ServerPlayer getCaster() { return this.caster; } @Override public void postExecution(CastResult result) { + super.postExecution(result); + for (var sideEffect : result.getSideEffects()) { if (sideEffect instanceof OperatorSideEffect.DoMishap doMishap) { this.sendMishapMsgToPlayer(doMishap); @@ -121,12 +124,54 @@ protected List getPrimaryStacks() { this.castingHand)); } + ItemStack getAlternateItem() { + var otherHand = HexUtils.otherHand(this.castingHand); + var stack = this.caster.getItemInHand(otherHand); + if (stack.isEmpty()) { + return ItemStack.EMPTY.copy(); + } else { + return stack; + } + } + + @Override + public boolean replaceItem(Predicate stackOk, ItemStack replaceWith, @Nullable InteractionHand hand) { + if (caster == null) + return false; + + if (hand != null && stackOk.test(caster.getItemInHand(hand))) { + caster.setItemInHand(hand, replaceWith); + return true; + } + + Inventory inv = this.caster.getInventory(); + for (int i = inv.items.size() - 1; i >= 0; i--) { + if (i != inv.selected) { + if (stackOk.test(inv.items.get(i))) { + inv.setItem(i, replaceWith); + return true; + } + } + } + + if (stackOk.test(caster.getItemInHand(getOtherHand()))) { + caster.setItemInHand(getOtherHand(), replaceWith); + return true; + } + if (stackOk.test(caster.getItemInHand(getCastingHand()))) { + caster.setItemInHand(getCastingHand(), replaceWith); + return true; + } + + return false; + } + @Override - public boolean isVecInRange(Vec3 vec) { + public boolean isVecInRangeEnvironment(Vec3 vec) { var sentinel = HexAPI.instance().getSentinel(this.caster); if (sentinel != null && sentinel.extendsRange() - && this.caster.getLevel().dimension() == sentinel.dimension() + && this.caster.level().dimension() == sentinel.dimension() && vec.distanceToSqr(sentinel.position()) <= SENTINEL_RADIUS * SENTINEL_RADIUS ) { return true; @@ -136,19 +181,8 @@ public boolean isVecInRange(Vec3 vec) { } @Override - public boolean hasEditPermissionsAt(BlockPos vec) { - return this.caster.gameMode.getGameModeForPlayer() != GameType.ADVENTURE && this.world.mayInteract(this.caster, vec); - } - - @Override - public ItemStack getAlternateItem() { - var otherHand = HexUtils.otherHand(this.castingHand); - var stack = this.caster.getItemInHand(otherHand); - if (stack.isEmpty()) { - return ItemStack.EMPTY.copy(); - } else { - return stack; - } + public boolean hasEditPermissionsAtEnvironment(BlockPos pos) { + return this.caster.gameMode.getGameModeForPlayer() != GameType.ADVENTURE && this.world.mayInteract(this.caster, pos); } /** @@ -157,8 +191,10 @@ public ItemStack getAlternateItem() { protected long extractMediaFromInventory(long costLeft, boolean allowOvercast) { List sources = MediaHelper.scanPlayerForMediaStuff(this.caster); + var startCost = costLeft; + for (var source : sources) { - var found = MediaHelper.extractMedia(source, (int) costLeft, true, false); + var found = MediaHelper.extractMedia(source, costLeft, false, false); costLeft -= found; if (costLeft <= 0) { break; @@ -170,7 +206,7 @@ protected long extractMediaFromInventory(long costLeft, boolean allowOvercast) { double healthToRemove = Math.max(costLeft / mediaToHealth, 0.5); var mediaAbleToCastFromHP = this.caster.getHealth() * mediaToHealth; - Mishap.trulyHurt(this.caster, HexDamageSources.OVERCAST, (float) healthToRemove); + Mishap.trulyHurt(this.caster, this.caster.damageSources().source(HexDamageTypes.OVERCAST), (float) healthToRemove); var actuallyTaken = Mth.ceil(mediaAbleToCastFromHP - (this.caster.getHealth() * mediaToHealth)); @@ -180,6 +216,8 @@ protected long extractMediaFromInventory(long costLeft, boolean allowOvercast) { costLeft -= actuallyTaken; } + this.caster.awardStat(HexStatistics.MEDIA_USED, (int) (startCost - costLeft)); + return costLeft; } @@ -195,8 +233,8 @@ protected boolean canOvercast() { } @Override - public void produceParticles(ParticleSpray particles, FrozenPigment colorizer) { - particles.sprayParticles(this.world, colorizer); + public void produceParticles(ParticleSpray particles, FrozenPigment pigment) { + particles.sprayParticles(this.world, pigment); } @Override diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PlayerBasedMishapEnv.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PlayerBasedMishapEnv.java index 592ff1f24..370ba5002 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PlayerBasedMishapEnv.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PlayerBasedMishapEnv.java @@ -2,10 +2,9 @@ import at.petrak.hexcasting.api.casting.eval.MishapEnvironment; import at.petrak.hexcasting.api.casting.mishaps.Mishap; -import at.petrak.hexcasting.api.misc.HexDamageSources; +import at.petrak.hexcasting.common.lib.HexDamageTypes; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.InteractionHand; -import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.effect.MobEffects; import net.minecraft.world.item.ItemStack; @@ -13,7 +12,7 @@ public class PlayerBasedMishapEnv extends MishapEnvironment { public PlayerBasedMishapEnv(ServerPlayer player) { - super(player.getLevel(), player); + super(player.serverLevel(), player); } @Override @@ -36,13 +35,13 @@ public void dropHeldItems() { @Override public void damage(float healthProportion) { - Mishap.trulyHurt(this.caster, HexDamageSources.OVERCAST, this.caster.getHealth() * healthProportion); + Mishap.trulyHurt(this.caster, this.caster.damageSources().source(HexDamageTypes.OVERCAST), this.caster.getHealth() * healthProportion); } @Override public void drown() { if (this.caster.getAirSupply() < 200) { - this.caster.hurt(DamageSource.DROWN, 2f); + this.caster.hurt(this.caster.damageSources().drown(), 2f); } this.caster.setAirSupply(0); } 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 38b6bfda7..9b63ece8d 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 @@ -9,8 +9,7 @@ import at.petrak.hexcasting.api.casting.math.HexCoord; import at.petrak.hexcasting.api.mod.HexStatistics; import at.petrak.hexcasting.api.pigment.FrozenPigment; -import at.petrak.hexcasting.common.msgs.MsgNewSpellPatternC2S; -import at.petrak.hexcasting.common.msgs.MsgNewSpellPatternS2C; +import at.petrak.hexcasting.common.msgs.*; import at.petrak.hexcasting.xplat.IXplatAbstractions; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerPlayer; @@ -35,6 +34,14 @@ public StaffCastEnv(ServerPlayer caster, InteractionHand castingHand) { public void postExecution(CastResult result) { super.postExecution(result); + if (result.component1() instanceof PatternIota patternIota) { + var packet = new MsgNewSpiralPatternsS2C( + this.caster.getUUID(), List.of(patternIota.getPattern()), Integer.MAX_VALUE + ); + IXplatAbstractions.INSTANCE.sendPacketToPlayer(this.caster, packet); + IXplatAbstractions.INSTANCE.sendPacketTracking(this.caster, packet); + } + // we always want to play this sound one at a time var sound = result.getSound().sound(); if (sound != null) { @@ -45,7 +52,7 @@ public void postExecution(CastResult result) { } @Override - public long extractMedia(long cost) { + public long extractMediaEnvironment(long cost) { if (this.caster.isCreative()) return 0; @@ -95,7 +102,7 @@ public static void handleNewPatternOnServer(ServerPlayer sender, MsgNewSpellPatt // TODO: do we reset the number of evals run via the staff? because each new pat is a new tick. - ExecutionClientView clientInfo = vm.queueExecuteAndWrapIota(new PatternIota(msg.pattern()), sender.getLevel()); + ExecutionClientView clientInfo = vm.queueExecuteAndWrapIota(new PatternIota(msg.pattern()), sender.serverLevel()); if (clientInfo.isStackClear()) { IXplatAbstractions.INSTANCE.setStaffcastImage(sender, null); @@ -111,11 +118,20 @@ public static void handleNewPatternOnServer(ServerPlayer sender, MsgNewSpellPatt IXplatAbstractions.INSTANCE.sendPacketToPlayer(sender, new MsgNewSpellPatternS2C(clientInfo, resolvedPatterns.size() - 1)); + IMessage packet; + if (clientInfo.isStackClear()) { + packet = new MsgClearSpiralPatternsS2C(sender.getUUID()); + } else { + packet = new MsgNewSpiralPatternsS2C(sender.getUUID(), List.of(msg.pattern()), Integer.MAX_VALUE); + } + IXplatAbstractions.INSTANCE.sendPacketToPlayer(sender, packet); + IXplatAbstractions.INSTANCE.sendPacketTracking(sender, packet); + if (clientInfo.getResolutionType().getSuccess()) { // Somehow we lost spraying particles on each new pattern, so do it here // this also nicely prevents particle spam on trinkets new ParticleSpray(sender.position(), new Vec3(0.0, 1.5, 0.0), 0.4, Math.PI / 3, 30) - .sprayParticles(sender.getLevel(), IXplatAbstractions.INSTANCE.getPigment(sender)); + .sprayParticles(sender.serverLevel(), IXplatAbstractions.INSTANCE.getPigment(sender)); } } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/sideeffects/OperatorSideEffect.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/sideeffects/OperatorSideEffect.kt index a7619b98f..2ea80b191 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/sideeffects/OperatorSideEffect.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/sideeffects/OperatorSideEffect.kt @@ -36,7 +36,7 @@ sealed class OperatorSideEffect { ) : OperatorSideEffect() { override fun performEffect(harness: CastingVM): Boolean { - this.spell.cast(harness.env) + this.spell.cast(harness.env, harness.image)?.let { harness.image = it } if (awardStat) harness.env.caster?.awardStat(HexStatistics.SPELLS_CAST) @@ -44,9 +44,9 @@ sealed class OperatorSideEffect { } } - data class ConsumeMedia(val amount: Int) : OperatorSideEffect() { + data class ConsumeMedia(val amount: Long) : OperatorSideEffect() { override fun performEffect(harness: CastingVM): Boolean { - val leftoverMedia = harness.env.extractMedia(this.amount.toLong()) + val leftoverMedia = harness.env.extractMedia(this.amount) return leftoverMedia > 0 } } 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 f2bcce36b..d2cdfbdb0 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 @@ -23,6 +23,10 @@ import net.minecraft.server.level.ServerLevel * [CastingEnvironment] to affect the world. */ class CastingVM(var image: CastingImage, val env: CastingEnvironment) { + init { + env.triggerCreateEvent() + } + /** * Execute a single iota. */ @@ -80,11 +84,12 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) { // ALSO TODO need to add reader macro-style things try { this.handleParentheses(iota)?.let { (data, resolutionType) -> - return@executeInner CastResult(continuation, data, listOf(), resolutionType, HexEvalSounds.NORMAL_EXECUTE) + return@executeInner CastResult(iota, continuation, data, listOf(), resolutionType, HexEvalSounds.NORMAL_EXECUTE) } } catch (e: MishapTooManyCloseParens) { // This is ridiculous and needs to be fixed return CastResult( + iota, continuation, null, listOf( @@ -106,6 +111,7 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) { // This means something very bad has happened exception.printStackTrace() return CastResult( + iota, continuation, null, listOf( 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 8cb2fcc54..8000ec09a 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 @@ -3,14 +3,12 @@ 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.Iota -import at.petrak.hexcasting.api.utils.getList -import at.petrak.hexcasting.api.utils.hasList -import at.petrak.hexcasting.common.lib.hex.HexIotaTypes +import at.petrak.hexcasting.common.lib.hex.HexContinuationTypes import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.Tag +import net.minecraft.resources.ResourceLocation import net.minecraft.server.level.ServerLevel -// TODO this should probably be a registry too /** * A single frame of evaluation during the execution of a spell. * @@ -24,7 +22,7 @@ import net.minecraft.server.level.ServerLevel * Once the stack of frames is empty, there are no more computations to run, so we're done. * */ -sealed interface ContinuationFrame { +interface ContinuationFrame { /** * Step the evaluation forward once. * For Evaluate, this consumes one pattern; for ForEach this queues the next iteration of the outer loop. @@ -49,34 +47,62 @@ sealed interface ContinuationFrame { */ fun size(): Int + 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 { - return when (tag.getString("type")) { - "evaluate" -> FrameEvaluate( - HexIotaTypes.LIST.deserialize( - tag.getList("patterns", Tag.TAG_COMPOUND), - world - )!!.list, - tag.getBoolean("isMetacasting") - ) + val type = getTypeFromTag(tag) ?: return FrameEvaluate(SpellList.LList(0, listOf()), false) + + return (tag.get(HexContinuationTypes.KEY_DATA) as? CompoundTag)?.let { type.deserializeFromNBT(it, world) } + ?: FrameEvaluate(SpellList.LList(0, listOf()), false) + } + + /** + * 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) + + val data = frame.serializeToNBT() + + val out = CompoundTag() + out.putString(HexContinuationTypes.KEY_TYPE, typeId.toString()) + out.put(HexContinuationTypes.KEY_DATA, data) + return out + } - "end" -> FrameFinishEval - "foreach" -> 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() - ) + /** + * This method attempts to find the type from the `type` key. + * See [ContinuationFrame.serializeToNBT] for the storage format. + * + * @return `null` if it cannot get the type. + */ + private fun getTypeFromTag(tag: CompoundTag): Type<*>? { + if (!tag.contains(HexContinuationTypes.KEY_TYPE, Tag.TAG_STRING.toInt())) { + return null + } - else -> FrameEvaluate(SpellList.LList(0, listOf()), false) + val typeKey = tag.getString(HexContinuationTypes.KEY_TYPE) + if (!ResourceLocation.isValidResourceLocation(typeKey)) { + return null } + + val typeLoc = ResourceLocation(typeKey) + 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 98914f30c..141148dfd 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 @@ -4,9 +4,14 @@ 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.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 net.minecraft.server.level.ServerLevel /** @@ -39,15 +44,31 @@ data class FrameEvaluate(val list: SpellList, val isMetacasting: Boolean) : Cont } } else { // If there are no patterns (e.g. empty Hermes), just return OK. - CastResult(continuation, null, listOf(), ResolvedPatternType.EVALUATED, HexEvalSounds.HERMES) + CastResult(ListIota(list), continuation, null, listOf(), ResolvedPatternType.EVALUATED, HexEvalSounds.HERMES) } } override fun serializeToNBT() = NBTBuilder { - "type" %= "evaluate" "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")) + } + + } + } } \ 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 c7909d844..72bbb8c80 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 @@ -3,8 +3,10 @@ package at.petrak.hexcasting.api.casting.eval.vm 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.NullIota import at.petrak.hexcasting.api.utils.NBTBuilder import at.petrak.hexcasting.common.lib.hex.HexEvalSounds +import net.minecraft.nbt.CompoundTag import net.minecraft.server.level.ServerLevel /** @@ -22,6 +24,7 @@ object FrameFinishEval : ContinuationFrame { harness: CastingVM ): CastResult { return CastResult( + NullIota(), continuation, null, listOf(), @@ -30,9 +33,14 @@ object FrameFinishEval : ContinuationFrame { ) } - override fun serializeToNBT() = NBTBuilder { - "type" %= "end" - } + override fun serializeToNBT() = CompoundTag() override fun size() = 0 + + @JvmField + val TYPE: ContinuationFrame.Type = object : ContinuationFrame.Type { + override fun deserializeFromNBT(tag: CompoundTag, world: ServerLevel) = FrameFinishEval + } + + 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 ad1627702..ec587cb78 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 @@ -6,8 +6,13 @@ 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.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 net.minecraft.server.level.ServerLevel /** @@ -52,8 +57,6 @@ data class FrameForEach( // If we still have data to process... val (stackTop, newImage, newCont) = if (data.nonEmpty) { - // Increment the evaluation depth, - // push the next datum to the top of the stack, val cont2 = continuation // put the next Thoth object back on the stack for the next Thoth cycle, @@ -68,6 +71,7 @@ data class FrameForEach( val tStack = stack.toMutableList() tStack.add(stackTop) return CastResult( + ListIota(code), newCont, newImage.copy(stack = tStack), listOf(), @@ -77,7 +81,6 @@ data class FrameForEach( } override fun serializeToNBT() = NBTBuilder { - "type" %= "foreach" "data" %= data.serializeToNBT() "code" %= code.serializeToNBT() if (baseStack != null) @@ -86,4 +89,27 @@ data class FrameForEach( } override fun size() = data.size() + code.size() + acc.size + (baseStack?.size ?: 0) + + override val type: ContinuationFrame.Type<*> = TYPE + + 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() + ) + } + + } + } } 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 4efb9c4af..ec706c285 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 @@ -23,7 +23,7 @@ sealed interface SpellContinuation { var self = this val frames = mutableListOf() while (self is NotDone) { - frames.add(self.frame.serializeToNBT()) + frames.add(ContinuationFrame.toNBT(self.frame)) self = self.next } return frames 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 23ff4bd86..13764c467 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 @@ -48,7 +48,7 @@ Tag serialize() { @Override public @NotNull CastResult execute(CastingVM vm, ServerLevel world, SpellContinuation continuation) { - return new CastResult(this.getContinuation(), vm.getImage(), List.of(), ResolvedPatternType.EVALUATED, HexEvalSounds.HERMES); + return new CastResult(this, this.getContinuation(), vm.getImage(), List.of(), ResolvedPatternType.EVALUATED, HexEvalSounds.HERMES); } @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 151cc5184..7f024abc9 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 @@ -54,17 +54,17 @@ protected Iota(@NotNull IotaType type, @NotNull Object payload) { */ public @NotNull CastResult execute(CastingVM vm, ServerLevel world, SpellContinuation continuation) { return new CastResult( + this, continuation, - null, + null, // Should never matter List.of( new OperatorSideEffect.DoMishap( new MishapUnescapedValue(this), new Mishap.Context(new HexPattern(HexDir.WEST, List.of()), null) ) - ), // Should never matter + ), ResolvedPatternType.INVALID, - HexEvalSounds.MISHAP - ); + HexEvalSounds.MISHAP); } /** @@ -78,7 +78,7 @@ public boolean executable() { * This method is called to determine whether the iota is above the max serialisation depth/serialisation count * limits. It should return every "iota" that is a subelement of this iota. * For example, if you implemented a Map<Iota, Iota>, then it should be an iterable over the keys *and* - * values of the map. If you implemented a typed List<Double> iota for some reason, you should instad override + * values of the map. If you implemented a typed List<Double> iota for some reason, you should instead override * {@link Iota#size}. */ public @Nullable Iterable subIotas() { 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 12b376fca..4bcf9b4b1 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 @@ -17,6 +17,7 @@ import javax.annotation.Nullable; import java.util.ArrayDeque; import java.util.Collections; +import java.util.List; import java.util.Objects; // Take notes from ForgeRegistryEntry @@ -64,7 +65,7 @@ public static CompoundTag serialize(Iota iota) { } // We check if it's too big on serialization; if it is we just return a garbage. - if (iota instanceof ListIota listIota && isTooLargeToSerialize(listIota.getList())) { + if (isTooLargeToSerialize(List.of(iota), 0)) { // Garbage will never be too large so we just recurse return serialize(new GarbageIota()); } @@ -76,12 +77,16 @@ public static CompoundTag serialize(Iota iota) { } public static boolean isTooLargeToSerialize(Iterable examinee) { + return isTooLargeToSerialize(examinee, 1); + } + + private static boolean isTooLargeToSerialize(Iterable examinee, int startingCount) { // We don't recurse here, just a work queue (or work stack, if we liked.) // Each element is a found sub-iota, and how deep it is. // // TODO: is it worth trying to cache the depth and size statically on a SpellList. var listsToExamine = new ArrayDeque<>(Collections.singleton(new Pair<>(examinee, 0))); - int totalEltsFound = 1; // count the first list + int totalEltsFound = startingCount; // count the first list while (!listsToExamine.isEmpty()) { var iotaPair = listsToExamine.removeFirst(); var sublist = iotaPair.getFirst(); 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 1d57bd7fc..e6c3a56a1 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 @@ -115,21 +115,21 @@ public boolean toleratesOther(Iota that) { var sideEffects = result.getSideEffects(); return new CastResult( + this, cont2, result.getNewImage(), sideEffects, ResolvedPatternType.EVALUATED, - result.getSound() - ); + result.getSound()); } catch (Mishap mishap) { return new CastResult( + this, continuation, null, List.of(new OperatorSideEffect.DoMishap(mishap, new Mishap.Context(this.getPattern(), castedName))), mishap.resolutionType(vm.getEnv()), - HexEvalSounds.MISHAP - ); + HexEvalSounds.MISHAP); } } 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 a60e247a2..9d9d7fbf6 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 @@ -29,7 +29,7 @@ public Vec3 getVec3() { @Override public boolean isTruthy() { var v = this.getVec3(); - return v.x != 0.0 && v.y != 0.0 && v.z != 0.0; + return !(v.x == 0.0 && v.y == 0.0 && v.z == 0.0); } @Override diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/Mishap.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/Mishap.kt index 69cd6eba3..b9462fdda 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/Mishap.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/Mishap.kt @@ -80,7 +80,7 @@ abstract class Mishap : Throwable() { companion object { @JvmStatic fun trulyHurt(entity: LivingEntity, source: DamageSource, amount: Float) { - entity.setHurtWithStamp(source, entity.level.gameTime) + entity.setHurtWithStamp(source, entity.level().gameTime) val targetHealth = entity.health - amount if (entity.invulnerableTime > 10) { @@ -92,7 +92,7 @@ abstract class Mishap : Throwable() { } if (!entity.hurt(source, amount) && !entity.isInvulnerableTo(source) && - !entity.level.isClientSide && + !entity.level().isClientSide && !entity.isDeadOrDying ) { 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 ac93c5752..9e5918d93 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 @@ -3,8 +3,8 @@ package at.petrak.hexcasting.api.casting.mishaps import at.petrak.hexcasting.api.casting.ParticleSpray import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota -import at.petrak.hexcasting.api.misc.HexDamageSources import at.petrak.hexcasting.api.pigment.FrozenPigment +import at.petrak.hexcasting.common.lib.HexDamageTypes import net.minecraft.world.entity.Mob import net.minecraft.world.item.DyeColor @@ -12,8 +12,8 @@ class MishapAlreadyBrainswept(val mob: Mob) : Mishap() { override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = dyeColor(DyeColor.GREEN) - override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { - mob.hurt(HexDamageSources.overcastDamageFrom(env.caster), mob.health) + override fun execute(ctx: CastingEnvironment, errorCtx: Context, stack: MutableList) { + mob.hurt(mob.damageSources().source(HexDamageTypes.OVERCAST, ctx.caster), mob.health) } override fun particleSpray(ctx: CastingEnvironment) = diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadBlock.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadBlock.kt index cf0e587c0..b97a1b72f 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadBlock.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadBlock.kt @@ -9,14 +9,15 @@ import net.minecraft.core.BlockPos import net.minecraft.network.chat.Component import net.minecraft.world.item.DyeColor import net.minecraft.world.level.Explosion +import net.minecraft.world.level.Level import net.minecraft.world.phys.Vec3 class MishapBadBlock(val pos: BlockPos, val expected: Component) : Mishap() { override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = dyeColor(DyeColor.LIME) - override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { - env.world.explode(null, pos.x + 0.5, pos.y + 0.5, pos.z + 0.5, 0.25f, Explosion.BlockInteraction.NONE) + override fun execute(ctx: CastingEnvironment, errorCtx: Context, stack: MutableList) { + ctx.world.explode(null, pos.x + 0.5, pos.y + 0.5, pos.z + 0.5, 0.25f, Level.ExplosionInteraction.NONE) } 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 7d5ec37b5..4e2353509 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 @@ -3,8 +3,8 @@ package at.petrak.hexcasting.api.casting.mishaps import at.petrak.hexcasting.api.casting.ParticleSpray import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.Iota -import at.petrak.hexcasting.api.misc.HexDamageSources import at.petrak.hexcasting.api.pigment.FrozenPigment +import at.petrak.hexcasting.common.lib.HexDamageTypes import net.minecraft.core.BlockPos import net.minecraft.world.entity.Mob import net.minecraft.world.item.DyeColor @@ -14,8 +14,8 @@ class MishapBadBrainsweep(val mob: Mob, val pos: BlockPos) : Mishap() { override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = dyeColor(DyeColor.GREEN) - override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { - trulyHurt(mob, HexDamageSources.overcastDamageFrom(env.caster), 1f) + override fun execute(ctx: CastingEnvironment, errorCtx: Context, stack: MutableList) { + trulyHurt(mob, mob.damageSources().source(HexDamageTypes.OVERCAST, ctx.caster), 1f) } override fun particleSpray(ctx: CastingEnvironment): ParticleSpray { diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapShameOnYou.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapShameOnYou.kt index 45ee62ff8..855d82c8a 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapShameOnYou.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapShameOnYou.kt @@ -2,8 +2,8 @@ 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.misc.HexDamageSources import at.petrak.hexcasting.api.pigment.FrozenPigment +import at.petrak.hexcasting.common.lib.HexDamageTypes import net.minecraft.world.item.DyeColor class MishapShameOnYou() : Mishap() { @@ -14,7 +14,7 @@ class MishapShameOnYou() : Mishap() { val caster = env.caster if (caster != null) { // FIXME: handle null caster case - Mishap.trulyHurt(caster, HexDamageSources.SHAME, 69420f) + trulyHurt(caster, caster.damageSources().source(HexDamageTypes.SHAME_ON_YOU), 69420f) } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/client/ClientCastingStack.kt b/Common/src/main/java/at/petrak/hexcasting/api/client/ClientCastingStack.kt new file mode 100644 index 000000000..249adc092 --- /dev/null +++ b/Common/src/main/java/at/petrak/hexcasting/api/client/ClientCastingStack.kt @@ -0,0 +1,61 @@ +package at.petrak.hexcasting.api.client + +import at.petrak.hexcasting.api.casting.math.HexPattern +import kotlin.math.min + + +class ClientCastingStack { + private var patterns = ArrayList() + private var toRemove = mutableSetOf() + + private var toAdd = ArrayList() + + fun addPattern(pattern: HexPattern?, lifetime: Int) { + if (pattern == null) return + if (patterns.stream().anyMatch { patternRenderHolder -> patternRenderHolder.pattern.hashCode() == pattern.hashCode() }) { + return + } + if (patterns.size > 100) { + patterns.removeAt(0) + } + patterns.add(HexPatternRenderHolder(pattern, lifetime)) + } + + fun slowClear() { + patterns.forEach { it.lifetime = min(it.lifetime, 140) } + } + + fun getPatterns(): List { + return patterns + } + + fun getPattern(index: Int): HexPattern? = patterns.getOrNull(index)?.pattern + + fun getPatternHolder(index: Int): HexPatternRenderHolder? = patterns.getOrNull(index) + + fun size(): Int { + return patterns.size + } + + fun tick() { + // tick without getting a cme + toAdd.forEach { pattern -> + if (patterns.size > 100) { + patterns.removeAt(0) + } + patterns.add(pattern) + } + + toAdd.clear() + + patterns.forEach { pattern -> + pattern.tick() + if (pattern.lifetime <= 0) { + toRemove.add(pattern) + } + } + + patterns.removeAll(toRemove) + toRemove.clear() + } +} \ No newline at end of file diff --git a/Common/src/main/java/at/petrak/hexcasting/api/client/ClientRenderHelper.kt b/Common/src/main/java/at/petrak/hexcasting/api/client/ClientRenderHelper.kt new file mode 100644 index 000000000..374e89c93 --- /dev/null +++ b/Common/src/main/java/at/petrak/hexcasting/api/client/ClientRenderHelper.kt @@ -0,0 +1,86 @@ +@file:JvmName("ClientRenderHelper") +package at.petrak.hexcasting.api.client + +import at.petrak.hexcasting.client.ClientTickCounter +import at.petrak.hexcasting.client.render.drawLineSeq +import at.petrak.hexcasting.client.render.findDupIndices +import at.petrak.hexcasting.client.render.makeZappy +import at.petrak.hexcasting.client.render.screenCol +import at.petrak.hexcasting.xplat.IClientXplatAbstractions +import at.petrak.hexcasting.xplat.IXplatAbstractions +import com.mojang.blaze3d.systems.RenderSystem +import com.mojang.blaze3d.vertex.PoseStack +import com.mojang.math.Axis +import net.minecraft.client.renderer.GameRenderer +import net.minecraft.world.entity.player.Player +import net.minecraft.world.phys.Vec2 +import kotlin.math.abs +import kotlin.math.cos +import kotlin.math.floor +import kotlin.math.sin + + +fun renderCastingStack(ps: PoseStack, player: Player, pticks: Float) { + val stack = IClientXplatAbstractions.INSTANCE.getClientCastingStack(player) + + for (k in 0 until stack.getPatterns().size) { + val patternRenderHolder = stack.getPatternHolder(k) ?: continue + val pattern = patternRenderHolder.pattern + val lifetime = patternRenderHolder.lifetime + val lifetimeOffset = if (lifetime <= 5f) (5f - lifetime) / 5f else 0f + + ps.pushPose() + ps.mulPose(Axis.YP.rotationDegrees(((player.level().gameTime + pticks) * (sin(k * 12.543565f) * 3.4f) * (k / 12.43f) % 360 + (1 + k) * 45f))) + ps.translate(0.0, 1 + sin(k.toDouble()) * 0.75, 0.75 + cos((k / 8.0)) * 0.25 + cos((player.level().gameTime + pticks) / (7 + k / 4)) * 0.065) + ps.scale(1 / 24f * (1 - lifetimeOffset), 1 / 24f * (1 - lifetimeOffset), 1 / 24f * (1 - lifetimeOffset)) + ps.translate(0.0, floor((k / 8.0)), 0.0) + ps.translate(0.0, sin((player.level().gameTime + pticks) / (7.0 + k / 8.0)), 0.0) + + val oldShader = RenderSystem.getShader() + RenderSystem.setShader { GameRenderer.getPositionColorShader() } + RenderSystem.enableDepthTest() + RenderSystem.disableCull() + val com1 = pattern.getCenter(1f) + val lines1 = pattern.toLines(1f, Vec2.ZERO) + var maxDx = -1f + var maxDy = -1f + for (line in lines1) { + val dx = abs(line.x - com1.x) + if (dx > maxDx) { + maxDx = dx + } + val dy = abs(line.y - com1.y) + if (dy > maxDy) { + maxDy = dy + } + } + val scale = 3.8f.coerceAtMost((16 / 2.5f / maxDx).coerceAtMost(16 / 2.5f / maxDy)) + val com2 = pattern.getCenter(scale) + val lines2 = pattern.toLines(scale, com2.negated()).toMutableList() + for (i in lines2.indices) { + val line = lines2[i] + lines2[i] = Vec2(line.x, -line.y) + } + val variance = 0.65f + val speed = 0.1f + val stupidHash = player.hashCode().toDouble() + val zappy: List = makeZappy(lines2, findDupIndices(pattern.positions()), + 5, variance, speed, 0.2f, 0f, + 1f, stupidHash) + val outer: Int = IXplatAbstractions.INSTANCE.getPigment(player).colorProvider.getColor( + ClientTickCounter.getTotal() / 2f, + patternRenderHolder.getColourPos(player.random)) + val rgbOnly = outer and 0x00FFFFFF + var newAlpha = outer ushr 24 + if (lifetime <= 60) { + newAlpha = floor((lifetime / 60f * 255).toDouble()).toInt() + } + val newARGB = newAlpha shl 24 or rgbOnly + val inner: Int = screenCol(newARGB) + drawLineSeq(ps.last().pose(), zappy, 0.35f, 0f, newARGB, newARGB) + drawLineSeq(ps.last().pose(), zappy, 0.14f, 0.01f, inner, inner) + ps.popPose() + RenderSystem.setShader { oldShader } + RenderSystem.enableCull() + } +} \ No newline at end of file diff --git a/Common/src/main/java/at/petrak/hexcasting/api/client/HexPatternRenderHolder.kt b/Common/src/main/java/at/petrak/hexcasting/api/client/HexPatternRenderHolder.kt new file mode 100644 index 000000000..3092f3727 --- /dev/null +++ b/Common/src/main/java/at/petrak/hexcasting/api/client/HexPatternRenderHolder.kt @@ -0,0 +1,19 @@ +package at.petrak.hexcasting.api.client + +import at.petrak.hexcasting.api.casting.math.HexPattern +import net.minecraft.util.RandomSource +import net.minecraft.world.phys.Vec3 + +data class HexPatternRenderHolder(val pattern: HexPattern, var lifetime: Int) { + private var colourPos: Vec3? = null + + fun getColourPos(random: RandomSource): Vec3 { + return colourPos ?: let { + Vec3(random.nextDouble(), random.nextDouble(), random.nextDouble()).normalize().scale(3.0).also { colourPos = it } + } + } + + fun tick() { + lifetime -= 1 + } +} \ No newline at end of file diff --git a/Common/src/main/java/at/petrak/hexcasting/api/client/ScryingLensOverlayRegistry.java b/Common/src/main/java/at/petrak/hexcasting/api/client/ScryingLensOverlayRegistry.java index 05fd1c84f..da72b78b4 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/client/ScryingLensOverlayRegistry.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/client/ScryingLensOverlayRegistry.java @@ -5,6 +5,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.Registry; +import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.player.Player; @@ -35,7 +36,7 @@ public final class ScryingLensOverlayRegistry { * @throws IllegalArgumentException if the block is already registered. */ public static void addDisplayer(Block block, OverlayBuilder displayer) { - addDisplayer(Registry.BLOCK.getKey(block), displayer); + addDisplayer(BuiltInRegistries.BLOCK.getKey(block), displayer); } /** @@ -67,7 +68,7 @@ public static void addPredicateDisplayer(OverlayPredicate predicate, OverlayBuil Player observer, Level world, Direction hitFace) { List> lines = Lists.newArrayList(); - var idLookedup = ID_LOOKUP.get(Registry.BLOCK.getKey(state.getBlock())); + var idLookedup = ID_LOOKUP.get(BuiltInRegistries.BLOCK.getKey(state.getBlock())); if (idLookedup != null) { idLookedup.addLines(lines, state, pos, observer, world, hitFace); } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/misc/DamageSourceOvercast.java b/Common/src/main/java/at/petrak/hexcasting/api/misc/DamageSourceOvercast.java deleted file mode 100644 index 9cd89eeab..000000000 --- a/Common/src/main/java/at/petrak/hexcasting/api/misc/DamageSourceOvercast.java +++ /dev/null @@ -1,12 +0,0 @@ -package at.petrak.hexcasting.api.misc; - -import net.minecraft.world.damagesource.DamageSource; - -public class DamageSourceOvercast extends DamageSource { - public DamageSourceOvercast() { - super("hexcasting.overcast"); - this.bypassArmor(); - this.bypassMagic(); - this.setMagic(); - } -} diff --git a/Common/src/main/java/at/petrak/hexcasting/api/misc/DamageSourceShameOnYou.java b/Common/src/main/java/at/petrak/hexcasting/api/misc/DamageSourceShameOnYou.java deleted file mode 100644 index 32595b851..000000000 --- a/Common/src/main/java/at/petrak/hexcasting/api/misc/DamageSourceShameOnYou.java +++ /dev/null @@ -1,12 +0,0 @@ -package at.petrak.hexcasting.api.misc; - -import net.minecraft.world.damagesource.DamageSource; - -public class DamageSourceShameOnYou extends DamageSource { - public DamageSourceShameOnYou() { - super("hexcasting.shame"); - this.bypassArmor(); - this.bypassMagic(); - this.setMagic(); - } -} diff --git a/Common/src/main/java/at/petrak/hexcasting/api/misc/EntityDamageSourceOvercast.java b/Common/src/main/java/at/petrak/hexcasting/api/misc/EntityDamageSourceOvercast.java deleted file mode 100644 index 659ccbff7..000000000 --- a/Common/src/main/java/at/petrak/hexcasting/api/misc/EntityDamageSourceOvercast.java +++ /dev/null @@ -1,13 +0,0 @@ -package at.petrak.hexcasting.api.misc; - -import net.minecraft.world.damagesource.EntityDamageSource; -import net.minecraft.world.entity.Entity; - -public class EntityDamageSourceOvercast extends EntityDamageSource { - public EntityDamageSourceOvercast(Entity entity) { - super("hexcasting.overcast", entity); - this.bypassArmor(); - this.bypassMagic(); - this.setMagic(); - } -} diff --git a/Common/src/main/java/at/petrak/hexcasting/api/misc/HexDamageSources.java b/Common/src/main/java/at/petrak/hexcasting/api/misc/HexDamageSources.java deleted file mode 100644 index 8dd06719e..000000000 --- a/Common/src/main/java/at/petrak/hexcasting/api/misc/HexDamageSources.java +++ /dev/null @@ -1,13 +0,0 @@ -package at.petrak.hexcasting.api.misc; - -import net.minecraft.world.damagesource.DamageSource; -import net.minecraft.world.entity.Entity; - -public final class HexDamageSources { - public static final DamageSourceOvercast OVERCAST = new DamageSourceOvercast(); - public static final DamageSourceShameOnYou SHAME = new DamageSourceShameOnYou(); - - public static DamageSource overcastDamageFrom(Entity cause) { - return new EntityDamageSourceOvercast(cause); - } -} diff --git a/Common/src/main/java/at/petrak/hexcasting/api/misc/MediaConstants.java b/Common/src/main/java/at/petrak/hexcasting/api/misc/MediaConstants.java index 73764c7c2..f09571070 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/misc/MediaConstants.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/misc/MediaConstants.java @@ -1,10 +1,10 @@ package at.petrak.hexcasting.api.misc; public final class MediaConstants { - public static final int DUST_UNIT = 10000; - public static final int SHARD_UNIT = 5 * DUST_UNIT; - public static final int CRYSTAL_UNIT = 10 * DUST_UNIT; + public static final long DUST_UNIT = 10000; + public static final long SHARD_UNIT = 5 * DUST_UNIT; + public static final long CRYSTAL_UNIT = 10 * DUST_UNIT; - public static final int QUENCHED_SHARD_UNIT = 3 * CRYSTAL_UNIT; - public static final int QUENCHED_BLOCK_UNIT = 4 * QUENCHED_SHARD_UNIT; + public static final long QUENCHED_SHARD_UNIT = 3 * CRYSTAL_UNIT; + public static final long QUENCHED_BLOCK_UNIT = 4 * QUENCHED_SHARD_UNIT; } 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 2210b89d9..be86acef1 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 @@ -13,11 +13,11 @@ public class HexConfig { public interface CommonConfigAccess { - int dustMediaAmount(); + long dustMediaAmount(); - int shardMediaAmount(); + long shardMediaAmount(); - int chargedCrystalMediaAmount(); + long chargedCrystalMediaAmount(); double mediaToHealthRate(); @@ -27,9 +27,9 @@ public interface CommonConfigAccess { int artifactCooldown(); - int DEFAULT_DUST_MEDIA_AMOUNT = MediaConstants.DUST_UNIT; - int DEFAULT_SHARD_MEDIA_AMOUNT = MediaConstants.SHARD_UNIT; - int DEFAULT_CHARGED_MEDIA_AMOUNT = MediaConstants.CRYSTAL_UNIT; + long DEFAULT_DUST_MEDIA_AMOUNT = MediaConstants.DUST_UNIT; + long DEFAULT_SHARD_MEDIA_AMOUNT = MediaConstants.SHARD_UNIT; + long DEFAULT_CHARGED_MEDIA_AMOUNT = MediaConstants.CRYSTAL_UNIT; double DEFAULT_MEDIA_TO_HEALTH_RATE = 2 * MediaConstants.CRYSTAL_UNIT / 20.0; int DEFAULT_CYPHER_COOLDOWN = 8; diff --git a/Common/src/main/java/at/petrak/hexcasting/api/mod/HexStatistics.java b/Common/src/main/java/at/petrak/hexcasting/api/mod/HexStatistics.java index 5262980d5..fd38fdc7b 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/mod/HexStatistics.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/mod/HexStatistics.java @@ -2,6 +2,7 @@ import at.petrak.hexcasting.api.misc.MediaConstants; import net.minecraft.core.Registry; +import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.resources.ResourceLocation; import net.minecraft.stats.StatFormatter; import net.minecraft.stats.Stats; @@ -10,9 +11,9 @@ public class HexStatistics { public static final ResourceLocation MEDIA_USED = makeCustomStat("media_used", - mediamount -> StatFormatter.DEFAULT.format(mediamount / MediaConstants.DUST_UNIT)); + mediamount -> StatFormatter.DEFAULT.format((int) (mediamount / MediaConstants.DUST_UNIT))); public static final ResourceLocation MEDIA_OVERCAST = makeCustomStat("media_overcast", - mediamount -> StatFormatter.DEFAULT.format(mediamount / MediaConstants.DUST_UNIT)); + mediamount -> StatFormatter.DEFAULT.format((int) (mediamount / MediaConstants.DUST_UNIT))); public static final ResourceLocation PATTERNS_DRAWN = makeCustomStat("patterns_drawn", StatFormatter.DEFAULT); public static final ResourceLocation SPELLS_CAST = makeCustomStat("spells_cast", StatFormatter.DEFAULT); @@ -22,7 +23,7 @@ public static void register() { private static ResourceLocation makeCustomStat(String key, StatFormatter formatter) { ResourceLocation resourcelocation = modLoc(key); - Registry.register(Registry.CUSTOM_STAT, key, resourcelocation); + Registry.register(BuiltInRegistries.CUSTOM_STAT, key, resourcelocation); Stats.CUSTOM.get(resourcelocation, formatter); return resourcelocation; } 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 a30d4f9ba..d8e77e3c7 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 @@ -3,6 +3,8 @@ import at.petrak.hexcasting.api.casting.ActionRegistryEntry; import at.petrak.hexcasting.xplat.IXplatAbstractions; import net.minecraft.core.Registry; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.TagKey; import net.minecraft.world.entity.EntityType; @@ -29,7 +31,7 @@ public static TagKey create(String name) { } public static TagKey create(ResourceLocation id) { - return TagKey.create(Registry.ITEM_REGISTRY, id); + return TagKey.create(Registries.ITEM, id); } } @@ -42,8 +44,11 @@ public static final class Blocks { public static final TagKey DIRECTRICES = create("directrices"); public static final TagKey MINDFLAYED_CIRCLE_COMPONENTS = create("brainswept_circle_components"); + // Used to determine what blocks should be replaced with air by OpDestroyFluid + public static final TagKey WATER_PLANTS = create("water_plants"); + public static TagKey create(String name) { - return TagKey.create(Registry.BLOCK_REGISTRY, modLoc(name)); + return TagKey.create(Registries.BLOCK, modLoc(name)); } } @@ -54,7 +59,7 @@ public static final class Entities { public static final TagKey> NO_BRAINSWEEPING = create("cannot_brainsweep"); public static TagKey> create(String name) { - return TagKey.create(Registry.ENTITY_TYPE_REGISTRY, modLoc(name)); + return TagKey.create(Registries.ENTITY_TYPE, modLoc(name)); } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/utils/MathUtils.kt b/Common/src/main/java/at/petrak/hexcasting/api/utils/MathUtils.kt new file mode 100644 index 000000000..84448cc39 --- /dev/null +++ b/Common/src/main/java/at/petrak/hexcasting/api/utils/MathUtils.kt @@ -0,0 +1,38 @@ +package at.petrak.hexcasting.api.utils + +import org.joml.Quaternionf +import org.joml.Vector3f +import kotlin.math.* + +object MathUtils { + @JvmStatic + fun clamp(long: Long, min: Long, max: Long): Long + = if (long <= min) min + else if (long >= max) max + else long +} + +object QuaternionfUtils { + @JvmStatic + val ONE: Quaternionf + get() = Quaternionf(0.0f, 0.0f, 0.0f, 1.0f) + + @JvmStatic + fun fromXYZDegrees(vector3f: Vector3f): Quaternionf { + return fromXYZ(Math.toRadians(vector3f.x().toDouble()).toFloat(), Math.toRadians(vector3f.y().toDouble()).toFloat(), Math.toRadians(vector3f.z().toDouble()).toFloat()) + } + + @JvmStatic + fun fromXYZ(vector3f: Vector3f): Quaternionf { + return fromXYZ(vector3f.x(), vector3f.y(), vector3f.z()) + } + + @JvmStatic + fun fromXYZ(f: Float, g: Float, h: Float): Quaternionf { + val quaternion = ONE + quaternion.mul(Quaternionf(sin((f / 2.0f)), 0.0f, 0.0f, cos((f / 2.0f)))) + quaternion.mul(Quaternionf(0.0f, sin((g / 2.0f)), 0.0f, cos((g / 2.0f)))) + quaternion.mul(Quaternionf(0.0f, 0.0f, sin((h / 2.0f)), cos((h / 2.0f)))) + return quaternion + } +} \ No newline at end of file diff --git a/Common/src/main/java/at/petrak/hexcasting/api/utils/MediaHelper.kt b/Common/src/main/java/at/petrak/hexcasting/api/utils/MediaHelper.kt index c7852e2d6..b5fc189d5 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/utils/MediaHelper.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/utils/MediaHelper.kt @@ -21,7 +21,7 @@ fun isMediaItem(stack: ItemStack): Boolean { * Extract [cost] media from [stack]. If [cost] is less than zero, extract all media instead. * This may mutate [stack] (and may consume it) unless [simulate] is set. * - * If [drainForBatteries] is false, this will only consider forms of media that can be used to make new batteries. + * If [drainForBatteries] is true, this will only consider forms of media that can be used to make new batteries. * * Return the amount of media extracted. This may be over [cost] if media is wasted. */ @@ -41,7 +41,7 @@ fun extractMedia( * Extract [cost] media from [holder]. If [cost] is less than zero, extract all media instead. * This may mutate the stack underlying [holder] (and may consume it) unless [simulate] is set. * - * If [drainForBatteries] is false, this will only consider forms of media that can be used to make new batteries. + * If [drainForBatteries] is true, this will only consider forms of media that can be used to make new batteries. * * Return the amount of media extracted. This may be over [cost] if media is wasted. */ 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 4594acca4..75658fa63 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/RegisterClientStuff.java +++ b/Common/src/main/java/at/petrak/hexcasting/client/RegisterClientStuff.java @@ -31,6 +31,7 @@ import net.minecraft.client.resources.model.BakedModel; import net.minecraft.client.resources.model.ModelBakery; import net.minecraft.core.Registry; +import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.packs.resources.ResourceManager; import net.minecraft.world.item.Item; @@ -255,7 +256,7 @@ void registerBlockEntityRenderer(BlockEntityType type public static void onModelRegister(ResourceManager recMan, Consumer extraModels) { for (var type : QUENCHED_ALLAY_TYPES.entrySet()) { - var blockLoc = Registry.BLOCK.getKey(type.getKey()); + var blockLoc = BuiltInRegistries.BLOCK.getKey(type.getKey()); var locStart = "block/"; if (type.getValue()) locStart += "deco/"; @@ -268,7 +269,7 @@ public static void onModelRegister(ResourceManager recMan, Consumer map) { for (var type : QUENCHED_ALLAY_TYPES.entrySet()) { - var blockLoc = Registry.BLOCK.getKey(type.getKey()); + var blockLoc = BuiltInRegistries.BLOCK.getKey(type.getKey()); var locStart = "block/"; if (type.getValue()) locStart += "deco/"; 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 14a86cd20..351acbef7 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 @@ -1,13 +1,12 @@ package at.petrak.hexcasting.client.entity; +import at.petrak.hexcasting.client.render.PatternTextureManager; import at.petrak.hexcasting.client.render.RenderLib; import at.petrak.hexcasting.common.entities.EntityWallScroll; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; -import com.mojang.math.Matrix3f; -import com.mojang.math.Matrix4f; -import com.mojang.math.Vector3f; +import com.mojang.math.Axis; import net.minecraft.client.renderer.GameRenderer; import net.minecraft.client.renderer.LevelRenderer; import net.minecraft.client.renderer.MultiBufferSource; @@ -18,6 +17,8 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.util.Mth; import net.minecraft.world.phys.Vec2; +import org.joml.Matrix3f; +import org.joml.Matrix4f; import java.util.List; @@ -45,10 +46,10 @@ public void render(EntityWallScroll wallScroll, float yaw, float partialTicks, P ps.pushPose(); - ps.mulPose(Vector3f.YP.rotationDegrees(180f - yaw)); - ps.mulPose(Vector3f.ZP.rotationDegrees(180f)); + ps.mulPose(Axis.YP.rotationDegrees(180f - yaw)); + ps.mulPose(Axis.ZP.rotationDegrees(180f)); - int light = LevelRenderer.getLightColor(wallScroll.level, wallScroll.getPos()); + int light = LevelRenderer.getLightColor(wallScroll.level(), wallScroll.getPos()); { ps.pushPose(); @@ -97,13 +98,17 @@ public void render(EntityWallScroll wallScroll, float yaw, float partialTicks, P vertex(mat, norm, light, verts, dx, dy, dz, 1, 1 - margin, 0, 1, 0); ps.popPose(); + + if (PatternTextureManager.useTextures && wallScroll.points != null) + PatternTextureManager.renderPatternForScroll(wallScroll.points.pointsKey, ps, bufSource, light, wallScroll.points.zappyPoints, wallScroll.blockSize, wallScroll.getShowsStrokeOrder()); } - if (wallScroll.zappyPoints != null) { - var points = wallScroll.zappyPoints; + //TODO: remove old rendering if not needed anymore for comparison + if (!PatternTextureManager.useTextures && wallScroll.points != null) { + var points = wallScroll.points.zappyPoints; ps.pushPose(); - ps.mulPose(Vector3f.YP.rotationDegrees(180f)); + ps.mulPose(Axis.YP.rotationDegrees(180f)); ps.translate(0, 0, 1.1f / 16f); // make smaller scrolls not be charlie kirk-sized // i swear, learning about these functions with asymptotes where slope != 0 is the most useful thing @@ -158,8 +163,8 @@ public ResourceLocation getTextureLocation(EntityWallScroll wallScroll) { } private static void vertex(Matrix4f mat, Matrix3f normal, int light, VertexConsumer verts, float x, float y, - float z, float u, - float v, float nx, float ny, float nz) { + 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) 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 321915fcf..a039b5264 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 @@ -23,6 +23,7 @@ import at.petrak.hexcasting.xplat.IClientXplatAbstractions import com.mojang.blaze3d.systems.RenderSystem import com.mojang.blaze3d.vertex.PoseStack import net.minecraft.client.Minecraft +import net.minecraft.client.gui.GuiGraphics import net.minecraft.client.gui.screens.Screen import net.minecraft.client.renderer.GameRenderer import net.minecraft.client.resources.sounds.SimpleSoundInstance @@ -300,12 +301,14 @@ class GuiSpellcasting constructor( } - override fun render(ps: PoseStack, pMouseX: Int, pMouseY: Int, pPartialTick: Float) { - super.render(ps, pMouseX, pMouseY, pPartialTick) + override fun render(graphics: GuiGraphics, pMouseX: Int, pMouseY: Int, pPartialTick: Float) { + super.render(graphics, pMouseX, pMouseY, pPartialTick) this.ambianceSoundInstance?.mousePosX = pMouseX / this.width.toDouble() this.ambianceSoundInstance?.mousePosY = pMouseX / this.width.toDouble() + val ps = graphics.pose() // TODO: Determine if this is still necessary. + val mat = ps.last().pose() val prevShader = RenderSystem.getShader() RenderSystem.setShader(GameRenderer::getPositionColorShader) @@ -425,7 +428,7 @@ class GuiSpellcasting constructor( ps.translate(0.0, 0.0, 1.0) RenderSystem.setShader { prevShader } for (desc in this.stackDescs) { - font.draw(ps, desc, 5f, 7f, -1) + graphics.drawString(font, desc, 5, 7, -1) // TODO: Confirm this works ps.translate(0.0, 10.0, 0.0) } } @@ -451,7 +454,7 @@ class GuiSpellcasting constructor( val color = 0x00_ffffff or (opacity shl 24) RenderSystem.setShader { prevShader } - font.draw(ps, kotlinBad, 0f, 0f, color) + graphics.drawString(font, kotlinBad, 0, 0, color) // TODO: Confirm this works ps.popPose() } diff --git a/Common/src/main/java/at/petrak/hexcasting/client/gui/PatternTooltipComponent.java b/Common/src/main/java/at/petrak/hexcasting/client/gui/PatternTooltipComponent.java index 3e0801e94..42d768ddd 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/gui/PatternTooltipComponent.java +++ b/Common/src/main/java/at/petrak/hexcasting/client/gui/PatternTooltipComponent.java @@ -7,7 +7,7 @@ import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.client.gui.Font; -import net.minecraft.client.gui.GuiComponent; +import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; import net.minecraft.client.renderer.GameRenderer; import net.minecraft.client.renderer.entity.ItemRenderer; @@ -33,6 +33,7 @@ public class PatternTooltipComponent implements ClientTooltipComponent { public static final ResourceLocation SLATE_BG = modLoc("textures/gui/slate.png"); private static final float RENDER_SIZE = 128f; + private static final int TEXTURE_SIZE = 48; private final HexPattern pattern; private final List zappyPoints; @@ -63,16 +64,17 @@ public static ClientTooltipComponent tryConvert(TooltipComponent cmp) { } @Override - public void renderImage(Font font, int mouseX, int mouseY, PoseStack ps, ItemRenderer pItemRenderer, - int pBlitOffset) { + public void renderImage(Font font, int mouseX, int mouseY, GuiGraphics graphics) { var width = this.getWidth(font); var height = this.getHeight(); + var ps = graphics.pose(); + // far as i can tell "mouseX" and "mouseY" are actually the positions of the corner of the tooltip ps.pushPose(); ps.translate(mouseX, mouseY, 500); RenderSystem.enableBlend(); - renderBG(ps, this.background, pBlitOffset); + renderBG(graphics, this.background); // renderText happens *before* renderImage for some asinine reason // RenderSystem.disableBlend(); @@ -101,13 +103,14 @@ public void renderImage(Font font, int mouseX, int mouseY, PoseStack ps, ItemRen ps.popPose(); } - private static void renderBG(PoseStack ps, ResourceLocation background, int blitOffset) { - RenderSystem.setShaderColor(1f, 1f, 1f, 1f); - RenderSystem.setShaderTexture(0, background); - // x y blitoffset sw sh w h ... ? - // parchment doesn't have this mapped - GuiComponent.blit(ps, 0, 0, blitOffset, 0f, 0f, (int) RENDER_SIZE, (int) RENDER_SIZE, (int) RENDER_SIZE, - (int) RENDER_SIZE); + private static void renderBG(GuiGraphics graphics, ResourceLocation background) { + graphics.blit( + background, // texture + 0, 0, // x, y + (int) RENDER_SIZE, (int) RENDER_SIZE, // renderWidth, renderHeight + 0f, 0f, // u, v (textureCoords) + TEXTURE_SIZE, TEXTURE_SIZE, // regionWidth, regionHeight (texture sample dimensions) + TEXTURE_SIZE, TEXTURE_SIZE); // textureWidth, textureHeight (total dimensions of texture) } @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 c654e5699..1861a9b8f 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 @@ -2,6 +2,7 @@ import at.petrak.hexcasting.api.client.ScryingLensOverlayRegistry; import at.petrak.hexcasting.api.player.Sentinel; +import at.petrak.hexcasting.api.utils.QuaternionfUtils; import at.petrak.hexcasting.client.ClientTickCounter; import at.petrak.hexcasting.common.lib.HexAttributes; import at.petrak.hexcasting.xplat.IXplatAbstractions; @@ -13,9 +14,8 @@ import com.mojang.blaze3d.vertex.Tesselator; import com.mojang.blaze3d.vertex.VertexFormat; import com.mojang.datafixers.util.Pair; -import com.mojang.math.Quaternion; -import com.mojang.math.Vector3f; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.player.LocalPlayer; import net.minecraft.client.renderer.GameRenderer; @@ -27,6 +27,7 @@ import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.Vec3; +import org.joml.Vector3f; import java.util.List; import java.util.function.BiConsumer; @@ -36,14 +37,14 @@ public static void overlayLevel(PoseStack ps, float partialTick) { var player = Minecraft.getInstance().player; if (player != null) { var sentinel = IXplatAbstractions.INSTANCE.getSentinel(player); - if (sentinel != null && player.getLevel().dimension().equals(sentinel.dimension())) { + if (sentinel != null && player.level().dimension().equals(sentinel.dimension())) { renderSentinel(sentinel, player, ps, partialTick); } } } - public static void overlayGui(PoseStack ps, float partialTicks) { - tryRenderScryingLensOverlay(ps, partialTicks); + public static void overlayGui(GuiGraphics graphics, float partialTicks) { + tryRenderScryingLensOverlay(graphics, partialTicks); } private static void renderSentinel(Sentinel sentinel, LocalPlayer owner, @@ -64,9 +65,9 @@ private static void renderSentinel(Sentinel sentinel, LocalPlayer owner, var magnitude = 0.1f; ps.translate(0, Mth.sin(bobSpeed * time) * magnitude, 0); var spinSpeed = 1f / 30; - ps.mulPose(Quaternion.fromXYZ(new Vector3f(0, spinSpeed * time, 0))); + ps.mulPose(QuaternionfUtils.fromXYZ(new Vector3f(0, spinSpeed * time, 0))); if (sentinel.extendsRange()) { - ps.mulPose(Quaternion.fromXYZ(new Vector3f(spinSpeed * time / 8f, 0, 0))); + ps.mulPose(QuaternionfUtils.fromXYZ(new Vector3f(spinSpeed * time / 8f, 0, 0))); } float scale = 0.5f; @@ -83,8 +84,8 @@ private static void renderSentinel(Sentinel sentinel, LocalPlayer owner, RenderSystem.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); RenderSystem.lineWidth(5f); - var colorizer = IXplatAbstractions.INSTANCE.getPigment(owner); - var colProvider = colorizer.getColorProvider(); + var pigment = IXplatAbstractions.INSTANCE.getPigment(owner); + var colProvider = pigment.getColorProvider(); 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])); @@ -148,8 +149,9 @@ private static class Icos { } } - private static void tryRenderScryingLensOverlay(PoseStack ps, float partialTicks) { + private static void tryRenderScryingLensOverlay(GuiGraphics graphics, float partialTicks) { var mc = Minecraft.getInstance(); + var ps = graphics.pose(); LocalPlayer player = mc.player; ClientLevel level = mc.level; @@ -196,16 +198,16 @@ private static void tryRenderScryingLensOverlay(PoseStack ps, float partialTicks var stack = pair.getFirst(); if (!stack.isEmpty()) { // this draws centered in the Y ... - RenderLib.renderItemStackInGui(ps, pair.getFirst(), 0, 0); + graphics.renderItem(pair.getFirst(), 0, 0); } - float tx = stack.isEmpty() ? 0 : 18; - float ty = 5; + int tx = stack.isEmpty() ? 0 : 18; + int ty = 5; // but this draws where y=0 is the baseline var text = pair.getSecond(); for (var line : text) { var actualLine = Language.getInstance().getVisualOrder(line); - mc.font.drawShadow(ps, actualLine, tx, ty, 0xffffffff); + graphics.drawString(mc.font, actualLine, tx, ty, 0xffffffff); ps.translate(0, mc.font.lineHeight, 0); } if (text.isEmpty()) { diff --git a/Common/src/main/java/at/petrak/hexcasting/client/render/HexPatternPoints.java b/Common/src/main/java/at/petrak/hexcasting/client/render/HexPatternPoints.java new file mode 100644 index 000000000..b033e8de3 --- /dev/null +++ b/Common/src/main/java/at/petrak/hexcasting/client/render/HexPatternPoints.java @@ -0,0 +1,15 @@ +package at.petrak.hexcasting.client.render; + +import net.minecraft.world.phys.Vec2; + +import java.util.List; + +public class HexPatternPoints { + public List zappyPoints = null; + public String pointsKey = null; //TODO: if a string key isnt performant enough override hashcode for points + + public HexPatternPoints(List zappyPoints) { + this.zappyPoints = zappyPoints; + pointsKey = PatternTextureManager.getPointsKey(zappyPoints); + } +} \ No newline at end of file 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 new file mode 100644 index 000000000..c28116900 --- /dev/null +++ b/Common/src/main/java/at/petrak/hexcasting/client/render/PatternTextureManager.java @@ -0,0 +1,357 @@ +package at.petrak.hexcasting.client.render; + +import at.petrak.hexcasting.api.block.HexBlockEntity; +import at.petrak.hexcasting.api.casting.math.HexPattern; +import at.petrak.hexcasting.common.blocks.akashic.BlockAkashicBookshelf; +import at.petrak.hexcasting.common.blocks.akashic.BlockEntityAkashicBookshelf; +import at.petrak.hexcasting.common.blocks.circles.BlockEntitySlate; +import at.petrak.hexcasting.common.blocks.circles.BlockSlate; +import com.mojang.blaze3d.platform.NativeImage; +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import com.mojang.math.Axis; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.texture.DynamicTexture; +import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.Tuple; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.AttachFace; +import net.minecraft.world.phys.Vec2; +import org.joml.Matrix3f; +import org.joml.Matrix4f; + +import java.awt.*; +import java.awt.image.BufferedImage; +import java.util.HashMap; +import java.util.List; +import java.util.concurrent.*; +import java.util.stream.Collectors; + +public class PatternTextureManager { + + //TODO: remove if not needed anymore for comparison + public static boolean useTextures = true; + public static int repaintIndex = 0; + public static int resolutionScaler = 4; + public static int fastRenderScaleFactor = 8; // e.g. this is 8, resolution is 1024, so render at 1024/8 = 128 + + public static int resolutionByBlockSize = 128 * resolutionScaler; + public static int paddingByBlockSize = 16 * resolutionScaler; + public static int circleRadiusByBlockSize = 2 * resolutionScaler; + public static int scaleLimit = 4 * resolutionScaler; + public static int scrollLineWidth = 3 * resolutionScaler; + public static int otherLineWidth = 4 * resolutionScaler; + + public static void setResolutionScaler(int resolutionScaler) { + PatternTextureManager.resolutionScaler = resolutionScaler; + resolutionByBlockSize = 128 * resolutionScaler; + paddingByBlockSize = 16 * resolutionScaler; + circleRadiusByBlockSize = 2 * resolutionScaler; + scaleLimit = 4 * resolutionScaler; + scrollLineWidth = 3 * resolutionScaler; + otherLineWidth = 4 * resolutionScaler; + } + + private static final ConcurrentMap patternTexturesToAdd = new ConcurrentHashMap<>(); + // basically newCachedThreadPool, but with a max pool size + private static final ExecutorService executor = new ThreadPoolExecutor(0, 16, 60L, TimeUnit.SECONDS, new LinkedBlockingDeque<>()); + + + private static final HashMap patternTextures = new HashMap<>(); + + public static String getPointsKey(List zappyPoints) + { + return zappyPoints.stream() + .map(p -> String.format("(%f,%f)", p.x, p.y)) + .collect(Collectors.joining(";")); + } + + public static HexPatternPoints generateHexPatternPoints(HexBlockEntity tile, HexPattern pattern, float flowIrregular) + { + var stupidHash = tile.getBlockPos().hashCode(); + var lines1 = pattern.toLines(1, Vec2.ZERO); + var zappyPoints = RenderLib.makeZappy(lines1, RenderLib.findDupIndices(pattern.positions()), + 10, 0.5f, 0f, flowIrregular, 0f, 1f, stupidHash); + return new HexPatternPoints(zappyPoints); + } + + public static void renderPatternForScroll(String pointsKey, PoseStack ps, MultiBufferSource bufSource, int light, List zappyPoints, int blockSize, boolean showStrokeOrder) + { + renderPattern(pointsKey, ps, bufSource, light, zappyPoints, blockSize, showStrokeOrder, false, true, false,false, true,-1); + } + public static void renderPatternForSlate(BlockEntitySlate tile, HexPattern pattern, PoseStack ps, MultiBufferSource buffer, int light, BlockState bs) + { + if(tile.points == null) + tile.points = generateHexPatternPoints(tile, pattern, 0.2f); + + boolean isOnWall = bs.getValue(BlockSlate.ATTACH_FACE) == AttachFace.WALL; + boolean isOnCeiling = bs.getValue(BlockSlate.ATTACH_FACE) == AttachFace.CEILING; + int facing = bs.getValue(BlockSlate.FACING).get2DDataValue(); + + renderPatternForBlockEntity(tile.points, ps, buffer, light, isOnWall, isOnCeiling, true, facing); + } + public static void renderPatternForAkashicBookshelf(BlockEntityAkashicBookshelf tile, HexPattern pattern, PoseStack ps, MultiBufferSource buffer, int light, BlockState bs) + { + if(tile.points == null) + tile.points = generateHexPatternPoints(tile, pattern, 0f); + + int facing = bs.getValue(BlockAkashicBookshelf.FACING).get2DDataValue(); + renderPatternForBlockEntity(tile.points, ps, buffer, light, true, false, false, facing); + } + + public static void renderPatternForBlockEntity(HexPatternPoints points, PoseStack ps, MultiBufferSource buffer, int light, boolean isOnWall, boolean isOnCeiling, boolean isSlate, int facing) + { + var oldShader = RenderSystem.getShader(); + ps.pushPose(); + RenderSystem.setShader(GameRenderer::getPositionTexShader); + renderPattern(points.pointsKey, ps, buffer, light, points.zappyPoints, 1, false, true, isOnWall, isOnCeiling, isSlate, false, facing); + ps.popPose(); + RenderSystem.setShader(() -> oldShader); + } + + public static void renderPattern(String pointsKey, PoseStack ps, MultiBufferSource bufSource, int light, List zappyPoints, int blockSize, boolean showStrokeOrder, boolean useFullSize, boolean isOnWall, boolean isOnCeiling, boolean isSlate, boolean isScroll, int facing) + { + ps.pushPose(); + + PoseStack.Pose last = ps.last(); + Matrix4f mat = last.pose(); + Matrix3f normal = last.normal(); + + float x = blockSize, y = blockSize, z = (-1f / 16f) - 0.01f; + float nx = 0, ny = 0, nz = 0; + + //TODO: refactor this mess of a method + + if(isOnWall) + { + if(isScroll) + { + ps.translate(-blockSize / 2f, -blockSize / 2f, 1f / 32f); + nz = -1; + } + else + { + ps.mulPose(Axis.ZP.rotationDegrees(180)); + + if(isSlate) + { + if(facing == 0) + ps.translate(0,-1,0); + if(facing == 1) + ps.translate(-1,-1,0); + if(facing == 2) + ps.translate(-1,-1,1); + if(facing == 3) + ps.translate(0,-1,1); + } + else + { + z = -0.01f; + if(facing == 0) + ps.translate(0,-1,1); + if(facing == 1) + ps.translate(0,-1,0); + if(facing == 2) + ps.translate(-1,-1,0); + if(facing == 3) + ps.translate(-1,-1,1); + } + + if(facing == 0) + ps.mulPose(Axis.YP.rotationDegrees(180)); + if(facing == 1) + ps.mulPose(Axis.YP.rotationDegrees(270)); + if(facing == 3) + ps.mulPose(Axis.YP.rotationDegrees(90)); + + if(facing == 0 || facing == 2) + nz = -1; + if(facing == 1 || facing == 3) + nx = -1; + ps.translate(0,0,0); + } + } + else //slates on the floor or ceiling + { + if(facing == 0) + ps.translate(0,0,0); + if(facing == 1) + ps.translate(1,0,0); + if(facing == 2) + ps.translate(1,0,1); + if(facing == 3) + ps.translate(0,0,1); + ps.mulPose(Axis.YP.rotationDegrees(facing*-90)); + + if(isOnCeiling) + { + ps.mulPose(Axis.XP.rotationDegrees(-90)); + ps.translate(0,-1,1); + } + else + ps.mulPose(Axis.XP.rotationDegrees(90)); + nz = -1; + } + + int lineWidth = otherLineWidth; + int outerColor = 0xff_d2c8c8; + int innerColor = 0xc8_322b33; + if(isScroll) + lineWidth = scrollLineWidth; + + ResourceLocation texture = getTexture(zappyPoints, pointsKey, blockSize, showStrokeOrder, lineWidth, useFullSize, new Color(innerColor), new Color(outerColor)); + VertexConsumer verts = bufSource.getBuffer(RenderType.entityCutout(texture)); + + vertex(mat, normal, light, verts, 0, 0, z, 0, 0, nx, ny, nz); + vertex(mat, normal, light, verts, 0, y, z, 0, 1, nx, ny, nz); + vertex(mat, normal, light, verts, x, y, z, 1, 1, nx, ny, nz); + vertex(mat, normal, light, verts, x, 0, z, 1, 0, nx, ny, nz); + + ps.popPose(); + } + + private static void vertex(Matrix4f mat, Matrix3f normal, 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(); + } + + public static ResourceLocation getTexture(List points, String pointsKey, int blockSize, boolean showsStrokeOrder, float lineWidth, boolean useFullSize, Color innerColor, Color outerColor) { + if (patternTexturesToAdd.containsKey(pointsKey)) { + var patternTexture = patternTexturesToAdd.remove(pointsKey); + var oldPatternTexture = patternTextures.put(pointsKey, patternTexture); + if (oldPatternTexture != null) + Minecraft.getInstance().getTextureManager().getTexture(oldPatternTexture).close(); + + return patternTexture; + } + if (patternTextures.containsKey(pointsKey)) + return patternTextures.get(pointsKey); + + // render a higher-resolution texture in a background thread so it eventually becomes all nice nice and pretty + executor.submit(() -> { + var slowTexture = createTexture(points, blockSize, showsStrokeOrder, lineWidth, useFullSize, innerColor, outerColor, false); + + // TextureManager#register doesn't look very thread-safe, so move back to the main thread after the slow part is done + Minecraft.getInstance().execute(() -> registerTexture(points, pointsKey, slowTexture, true)); + }); + + // quickly create and cache a low-resolution texture so the client has something to look at + var fastTexture = createTexture(points, blockSize, showsStrokeOrder, lineWidth, useFullSize, innerColor, outerColor, true); + return registerTexture(points, pointsKey, fastTexture, false); + } + + private static DynamicTexture createTexture(List points, int blockSize, boolean showsStrokeOrder, float lineWidth, boolean useFullSize, Color innerColor, Color outerColor, boolean fastRender) + { + int resolution = resolutionByBlockSize * blockSize; + int padding = paddingByBlockSize * blockSize; + + if (fastRender) { + resolution /= fastRenderScaleFactor; + padding /= fastRenderScaleFactor; + lineWidth /= (float)fastRenderScaleFactor; + } + + double minX = Double.MAX_VALUE, maxX = Double.MIN_VALUE, minY = Double.MAX_VALUE, maxY = Double.MIN_VALUE; + for (Vec2 point : points) + { + minX = Math.min(minX, point.x); + maxX = Math.max(maxX, point.x); + minY = Math.min(minY, point.y); + maxY = Math.max(maxY, point.y); + } + + double rangeX = maxX - minX; + double rangeY = maxY - minY; + + double scale = Math.min((resolution - 2 * padding) / rangeX, (resolution - 2 * padding) / rangeY); + + double limit = blockSize * scaleLimit; + if (!useFullSize && scale > limit) + scale = limit; + + double offsetX = ((resolution - 2 * padding) - rangeX * scale) / 2; + double offsetY = ((resolution - 2 * padding) - rangeY * scale) / 2; + + BufferedImage img = new BufferedImage(resolution, resolution, BufferedImage.TYPE_INT_ARGB); + Graphics2D g2d = img.createGraphics(); + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + g2d.setColor(outerColor); + g2d.setStroke(new BasicStroke((blockSize * 5f / 3f) * lineWidth, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); + drawLines(g2d, points, minX, minY, scale, offsetX, offsetY, padding); + + g2d.setColor(innerColor); + g2d.setStroke(new BasicStroke((blockSize * 2f / 3f) * lineWidth, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); + drawLines(g2d, points, minX, minY, scale, offsetX, offsetY, padding); + + + if (showsStrokeOrder) { + g2d.setColor(new Color(0xff_d77b5b)); + Tuple point = getTextureCoordinates(points.get(0), minX, minY, scale, offsetX, offsetY, padding); + int spotRadius = circleRadiusByBlockSize * blockSize; + drawHexagon(g2d, point.getA(), point.getB(), spotRadius); + } + + 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 new DynamicTexture(nativeImage); + } + + private static ResourceLocation registerTexture(List points, String pointsKey, DynamicTexture dynamicTexture, boolean isSlow) { + // isSlow used to register different textures for the low-resolution, fastly rendered version of each texture + // and the high-resolution, slowly rendered version (this means the slow doesn't replace the fast in the texture manager, + // which causes occasional visual stuttering for a frame). + String name = "hex_pattern_texture_" + points.hashCode() + "_" + repaintIndex + "_" + (isSlow ? "slow" : "fast") + ".png"; + ResourceLocation resourceLocation = Minecraft.getInstance().getTextureManager().register(name, dynamicTexture); + patternTexturesToAdd.put(pointsKey, resourceLocation); + return resourceLocation; + } + + private static void drawLines(Graphics2D g2d, List points, double minX, double minY, double scale, double offsetX, double offsetY, int padding) { + for (int i = 0; i < points.size() - 1; i++) { + Tuple pointFrom = getTextureCoordinates(points.get(i), minX, minY, scale, offsetX, offsetY, padding); + Tuple pointTo = getTextureCoordinates(points.get(i+1), minX, minY, scale, offsetX, offsetY, padding); + g2d.drawLine(pointFrom.getA(), pointFrom.getB(), pointTo.getA(), pointTo.getB()); + } + } + + private static Tuple getTextureCoordinates(Vec2 point, double minX, double minY, double scale, double offsetX, double offsetY, int padding) { + int x = (int) ((point.x - minX) * scale + offsetX) + padding; + int y = (int) ((point.y - minY) * scale + offsetY) + padding; + return new Tuple<>(x, y); + } + + 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(); + patternTextures.clear(); + } +} \ No newline at end of file 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 e6827be36..38d70fdfa 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 @@ -4,27 +4,27 @@ package at.petrak.hexcasting.client.render import at.petrak.hexcasting.api.casting.math.HexPattern import at.petrak.hexcasting.api.mod.HexConfig -import at.petrak.hexcasting.api.utils.TAU +import at.petrak.hexcasting.api.utils.* import at.petrak.hexcasting.client.ClientTickCounter -import com.mojang.blaze3d.systems.RenderSystem +import at.petrak.hexcasting.client.gui.GuiSpellcasting import com.mojang.blaze3d.vertex.DefaultVertexFormat import com.mojang.blaze3d.vertex.PoseStack import com.mojang.blaze3d.vertex.Tesselator import com.mojang.blaze3d.vertex.VertexFormat -import com.mojang.math.Matrix4f -import com.mojang.math.Vector3f +import com.mojang.math.Axis import net.minecraft.client.Minecraft +import net.minecraft.client.gui.GuiGraphics import net.minecraft.client.gui.screens.Screen import net.minecraft.client.renderer.MultiBufferSource import net.minecraft.core.BlockPos import net.minecraft.util.FastColor import net.minecraft.util.Mth import net.minecraft.world.entity.Entity -import net.minecraft.world.item.ItemStack import net.minecraft.world.level.Level import net.minecraft.world.level.levelgen.SingleThreadedRandomSource import net.minecraft.world.level.levelgen.synth.SimplexNoise import net.minecraft.world.phys.Vec2 +import org.joml.Matrix4f import kotlin.math.abs import kotlin.math.min import kotlin.math.roundToInt @@ -77,16 +77,16 @@ fun drawLineSeq( val joinAngles = FloatArray(n) val joinOffsets = FloatArray(n) for (i in 2 until n) { - val p0 = points[i - 2]; - val p1 = points[i - 1]; - val p2 = points[i]; + val p0 = points[i - 2] + val p1 = points[i - 1] + val p2 = points[i] val prev = p1.add(p0.negated()) val next = p2.add(p1.negated()) val angle = Mth.atan2((prev.x * next.y - prev.y * next.x).toDouble(), (prev.x * next.x + prev.y * next.y).toDouble()) .toFloat() joinAngles[i - 1] = angle - val clamp = Math.min(prev.length(), next.length()) / (width * 0.5f); + val clamp = prev.length().coerceAtMost(next.length()) / (width * 0.5f) joinOffsets[i - 1] = Mth.clamp(Mth.sin(angle) / (1 + Mth.cos(angle)), -clamp, clamp) } @@ -227,7 +227,7 @@ fun drawPatternFromPoints( dodge(FastColor.ARGB32.green(head)) / 255f, dodge(FastColor.ARGB32.blue(head)) / 255f, FastColor.ARGB32.alpha(head) / 255f - ); + ) } } @@ -402,42 +402,31 @@ fun getCenteredPattern(pattern: HexPattern, width: Float, height: Float, minSize return scale to lines2 } -fun renderItemStackInGui(ms: PoseStack, stack: ItemStack, x: Int, y: Int) { - transferMsToGl(ms) { Minecraft.getInstance().itemRenderer.renderAndDecorateItem(stack, x, y) } -} - -fun transferMsToGl(ms: PoseStack, toRun: Runnable) { - val mvs = RenderSystem.getModelViewStack() - mvs.pushPose() - mvs.mulPoseMatrix(ms.last().pose()) - RenderSystem.applyModelViewMatrix() - toRun.run() - mvs.popPose() - RenderSystem.applyModelViewMatrix() -} - @JvmOverloads fun renderEntity( - ms: PoseStack, entity: Entity, world: Level, x: Float, y: Float, rotation: Float, + graphics: GuiGraphics, entity: Entity, world: Level, x: Float, y: Float, rotation: Float, renderScale: Float, offset: Float, bufferTransformer: (MultiBufferSource) -> MultiBufferSource = { it -> it } ) { val rotation = if (Screen.hasShiftDown()) 0.0f else rotation - entity.level = world - ms.pushPose() - ms.translate(x.toDouble(), y.toDouble(), 50.0) - ms.scale(renderScale, renderScale, renderScale) - ms.translate(0.0, offset.toDouble(), 0.0) - ms.mulPose(Vector3f.ZP.rotationDegrees(180.0f)) - ms.mulPose(Vector3f.YP.rotationDegrees(rotation)) + // TODO: Figure out why this is here and whether removing it will break things +// entity.level = world + val ps = graphics.pose() + + ps.pushPose() + ps.translate(x.toDouble(), y.toDouble(), 50.0) + ps.scale(renderScale, renderScale, renderScale) + ps.translate(0.0, offset.toDouble(), 0.0) + ps.mulPose(Axis.ZP.rotationDegrees(180.0f)) + ps.mulPose(Axis.YP.rotationDegrees(rotation)) val erd = Minecraft.getInstance().entityRenderDispatcher val immediate = Minecraft.getInstance().renderBuffers().bufferSource() erd.setRenderShadow(false) - erd.render(entity, 0.0, 0.0, 0.0, 0.0f, 1.0f, ms, bufferTransformer(immediate), 0xf000f0) + erd.render(entity, 0.0, 0.0, 0.0, 0.0f, 1.0f, ps, bufferTransformer(immediate), 0xf000f0) erd.setRenderShadow(true) immediate.endBatch() - ms.popPose() + ps.popPose() } /** 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 6e2e8d930..32aed05c7 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 @@ -22,7 +22,7 @@ import net.minecraft.world.level.block.state.properties.ComparatorMode; import net.minecraft.world.level.block.state.properties.NoteBlockInstrument; import net.minecraft.world.level.block.state.properties.RailShape; -import net.minecraft.world.level.material.MaterialColor; +import net.minecraft.world.level.material.MapColor; import java.util.function.UnaryOperator; @@ -228,19 +228,19 @@ private static UnaryOperator