Compare commits

...

79 commits

Author SHA1 Message Date
petrak@ f9d8e1aaba this isn't working i give up for now 2023-08-05 18:07:51 -05:00
petrak@ caa6e1ac0a ask amo why it isn't finding the targets 2023-07-21 12:46:16 -05:00
petrak@ d385189a97 i give up on post-processing 2023-07-21 10:54:26 -05:00
petrak@ 3e3cf73150
Merge pull request #496 from Talia-12/1.20.1
1.20.1
2023-07-20 10:24:34 -04:00
petrak@ a166f05023
Merge pull request #494 from Cypher121/patch-3
Make interop patchouli flag only set if it's true
2023-07-20 10:24:16 -04:00
Talia-12 b11f1c5ced unseal 2023-07-21 00:02:18 +10:00
Talia-12 4a1e4c3269 added registry for ContinuationFrame types! 2023-07-20 22:38:21 +10:00
Talia-12 a1cb9f7fab add CreativeTab to fabric. 2023-07-20 19:25:54 +10:00
Talia-12 d25682902d got boolean directrix textured and modelled properly. 2023-07-20 15:40:03 +10:00
Talia-12 88270d541f also clear the STATE property when the directrix is no longer energized. 2023-07-20 00:11:49 +10:00
Talia-12 c6f4f3adbc boolean directrix also changes the STATE property properly. 2023-07-20 00:09:52 +10:00
Talia-12 127b035bbb updated gradle since apparently that was necessary(???). Got fabric booting and a world loading successfully! 2023-07-19 01:06:28 +10:00
Talia-12 88f86d96f4 pulled in all the code from #493 to render patterns around the player while casting, fixed it up to actually work in multiplayer (can't test it cause of the patchouli server bug but I'm fairly sure it'll work). 2023-07-13 20:42:20 +10:00
Talia-12 31807fe8f7 fixed example 4.5 2023-07-13 00:16:48 +10:00
Talia-12 c66a5debbc EntityRaycast actually is working, I was just testing it wrong 2023-07-13 00:14:44 +10:00
Talia-12 717dd3e5ad fixed stuff from the merge from petra, and fixed raycasts to work without a player. 2023-07-12 18:26:19 +10:00
Talia-12 dd77b14c59 fix up some patchouli stuff 2023-07-12 17:28:14 +10:00
Talia-12 e88e1b553d Merge remote-tracking branch 'petra_origin/1.20' into 1.20.1 2023-07-11 21:36:47 +10:00
Talia-12 3f3b899ecb fix more int->long stuff 2023-07-11 16:34:03 +10:00
Talia-12 ccaa83a2f9 fix packagedItems being unable to cast if they have no saved pigment. 2023-07-11 15:57:24 +10:00
Talia-12 1d1efb2a3d make spell costs longs. 2023-07-11 15:53:12 +10:00
Talia-12 6d3bd9b98f inc (discovered currently impossible to play on server due to patchouli bug) 2023-07-10 21:52:48 +10:00
Talia-12 c8004cc7a4 fix AltioraLayer addLayer by removing mixin. 2023-07-10 21:40:34 +10:00
Talia-12 77aa0e7380 renamed some things, made IotaType.serialize actually check if custom iotas are too big. 2023-07-10 19:38:54 +10:00
Talia-12 3c426a89ee allow RenderedSpells to modify the stack/userdata. 2023-07-10 11:51:45 +10:00
Talia-12 b50d12464a add new Any iotapredicate. 2023-07-10 00:00:24 +10:00
Talia-12 f9723bbb8c version inc 2023-07-09 21:54:26 +10:00
Talia-12 b3f285e859 rename modify_in_place to replace. 2023-07-09 21:20:21 +10:00
Talia-12 aaae2e5020 give Arithmetic operators access to the casting env (to be used in MoreIotas for the ExtractItemType operator, needed to get the item type of the block at a position) 2023-07-09 21:15:39 +10:00
petrak@ 8f20cec693 patchouli work might be bikeshedding right now tbh 2023-07-08 17:28:10 -05:00
June 662082211e
Make interop patchouli flag not set to false 2023-07-08 23:04:35 +02:00
petrak@ 4eb5bb846d augh. actually do git properly and actually be on 1.20.1 2023-07-08 15:57:42 -05:00
petrak@ bc20923933 fix merge conflict 2023-07-08 15:53:36 -05:00
petrak@ e3ba2718cb kind of sort of start patchi stuff 2023-07-08 15:52:34 -05:00
petrak@ 64efb43abd bandaid-fix some patchi things 2023-07-08 15:38:14 -05:00
Talia-12 0a90b0eda2 add Either IotaMultiPredicate 2023-07-09 00:56:52 +10:00
Talia-12 47fc2532d0 actually launching on fabric 2023-07-08 23:38:13 +10:00
Talia-12 05d0f928dd fix OpBreakBlock to work with circles, as well as making it easier to do the same with OpMakeBattery in the future 2023-07-08 22:25:32 +10:00
Talia-12 25402313e7 rename ctx to env in places. 2023-07-08 21:32:17 +10:00
Talia-12 0bdfa15aa2 fix sentinel, remove broken test and unused method it was testing 2023-07-03 17:19:45 +10:00
Talia-12 609e018f9e version inc 2023-07-03 00:20:24 +10:00
Talia-12 0d810ec34f fix null player issues on isBreakingAllowed and isPlacingAllowed 2023-06-29 20:35:42 +10:00
Talia-12 0fd9ca94d8 fixed some mixins 2023-06-29 02:03:12 +10:00
Talia-12 d4e22d157e book fully functional! 2023-06-29 01:59:48 +10:00
Talia-12 bb188a0a6c ran fabric datagen 2023-06-29 01:45:48 +10:00
Talia-12 ea072d9e64 fixed fabric datagen 2023-06-29 01:45:14 +10:00
Talia-12 81b6958960 running forge datagen 2023-06-29 01:26:36 +10:00
Talia-12 0bffbaaa99 fixed forge datagen (JANK MIXINS) 2023-06-29 01:25:21 +10:00
Talia-12 8501c4ce34 fixed up the registry nonsense and got forge actually able to get into the world!!!!!! 2023-06-29 00:00:04 +10:00
Talia-12 31ff708d80 successfully building!! fixed a bunch of EMI stuff 2023-06-24 00:40:56 +10:00
Talia-12 e70d2edb22 fixxyfixxyfixxy 2023-06-24 00:03:54 +10:00
Talia-12 228f68bad9 delete gravity API interop since gravity API is quilt-only now 2023-06-23 16:25:02 +10:00
Talia-12 28f74a8287 get rid of reach attributes since its unused 2023-06-23 16:24:31 +10:00
Talia-12 2ccb3c47e3 fix amethyst loot table inject 2023-06-23 16:16:32 +10:00
Talia-12 96abc3df0e fixed some forge renderer stuff 2023-06-23 16:05:04 +10:00
Talia-12 63042fd9d8 fix patchouli stuff now that snapshot is available 2023-06-23 15:43:04 +10:00
Talia-12 afa7684023 add quenched stuff to phial recipes. 2023-06-23 15:16:31 +10:00
Talia-12 e5e7fa18d4 fix creative tabs 2023-06-23 15:15:19 +10:00
Talia-12 f060a83c32 maybe fix how forge registries work? 2023-06-23 13:55:47 +10:00
Talia-12 487818cae2 mucking around with how to actually register the hex-registries on forge, committing this so I don't lose it in case I want to come back to it 2023-06-22 01:51:26 +10:00
Talia-12 33db54e979 fixed the damage types stuff, and HexItemModels. 2023-06-22 00:45:00 +10:00
Talia-12 ef12c71e92 fixed datagen for loottables and advancements. 2023-06-22 00:11:15 +10:00
Talia-12 9d8bf7c568 start fixing up AkashicTreeGrower to datagen the ConfiguredFeatures, and fix some other datagen stuff. 2023-06-21 18:43:15 +10:00
Talia-12 36b631eadb added BlockSetType for edified wood, fixed HexAxtionTagProvider 2023-06-21 17:01:36 +10:00
petrak@ 26193d9352 start making the docs usable 2023-06-20 10:47:09 -05:00
Talia-12 76ba2f5f8a fixed fabric not having cardinal-components properly registered. 2023-06-21 00:41:31 +10:00
Talia-12 eacbdb4014 changing all the things that were easy to change 2023-06-20 23:53:32 +10:00
Talia-12 139357b679 actually add these 2023-06-20 22:55:10 +10:00
Talia-12 05be814a8e fix some recipes, make some rendering fixes more idiomatic, do some more rendering fixes 2023-06-20 22:54:52 +10:00
Talia-12 32559dc94d fix some datagen 2023-06-20 22:14:16 +10:00
Talia-12 a97545246f all the Common kotlin stuff is now compiling apparently 2023-06-20 22:04:49 +10:00
Talia-12 7d611c0220 add some maths helpers for no-longer-present methods, add a tag for which blocks can be removed by OpDestroyFluid. 2023-06-20 19:26:26 +10:00
Talia-12 cb7255a5ed fixed some more actions 2023-06-20 18:58:02 +10:00
Talia-12 e745ff6773 vague more attempts at Datagen fixes 2023-06-20 18:50:29 +10:00
Talia-12 488cc3ea74 fixed up Hexplat Recipes 2023-06-19 23:11:21 +10:00
Talia-12 67a32a6267 some progress; BlockPos(vec) is now BlockPos.containing(vec). Materials are gone, so block properties seem to be mostly made by copying from other blocks and changing relevant things. Data generation seems to have changed, and recipes need a recipe category. 2023-06-19 23:01:33 +10:00
Talia-12 1342c8cbef started working top to bottom fixing things. 2023-06-15 23:11:45 +10:00
Talia-12 80386c4262 fixed dependencies to point at 1.20 version where those are available, haven't yet tried to build/launch at all 2023-06-15 16:51:26 +10:00
Talia-12 473376943a started updating things to 1.20, halted by patchouli (and presumably others) not being done for 1.20 yet 2023-06-15 15:34:35 +10:00
982 changed files with 6179 additions and 3152 deletions

View file

@ -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"

Binary file not shown.

View file

@ -1,4 +1,4 @@
// 1.19.2 2023-06-20T14:09:26.505719553 Item Models: hexcasting
// 1.20.1 2023-07-20T13:02:46.02554864 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

View file

@ -1,4 +1,4 @@
// 1.19.2 2023-06-20T14:09:26.510463293 Block States: hexcasting
// 1.20.1 2023-07-20T13:02:46.030398565 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,6 +15,7 @@ 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
@ -67,6 +68,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
@ -232,6 +269,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

View file

@ -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-07-20T13:02:46.032697075 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

View file

@ -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
}
}
}

View file

@ -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"
}
}

View file

@ -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"
}
}

View file

@ -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"
}
}

View file

@ -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"
}
}

View file

@ -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"
}
}

View file

@ -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"
}
}

View file

@ -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"
}
}

View file

@ -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"
}
}

View file

@ -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"
}
}

View file

@ -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"
}
}

View file

@ -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"
}
}

View file

@ -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"
}
}

View file

@ -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"
}
}

View file

@ -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"
}
}

View file

@ -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"
}
}

View file

@ -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"
}
}

View file

@ -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"
}
}

View file

@ -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"
}
}

View file

@ -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"
}
}

View file

@ -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"
}
}

View file

@ -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"
}
}

View file

@ -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"
}
}

View file

@ -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"
}
}

View file

@ -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"
}
}

View file

@ -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"
}
}

View file

@ -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"
}
}

View file

@ -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"
}
}

View file

@ -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"
}
}

View file

@ -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"
}
}

View file

@ -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"
}
}

View file

@ -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"
}
}

View file

@ -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"
}
}

View file

@ -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"
}
}

View file

@ -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"
}
}

View file

@ -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"
}
}

View file

@ -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"
}
}

View file

@ -0,0 +1,3 @@
{
"parent": "hexcasting:block/circle/directrix/boolean/lit_false_east"
}

View file

@ -29,5 +29,6 @@
[
"waste_amt"
]
]
],
"sends_telemetry_event": true
}

View file

@ -29,5 +29,6 @@
[
"cast_amt"
]
]
],
"sends_telemetry_event": true
}

View file

@ -33,5 +33,6 @@
[
"health_used"
]
]
],
"sends_telemetry_event": true
}

View file

@ -31,5 +31,6 @@
[
"used_item"
]
]
],
"sends_telemetry_event": true
}

View file

@ -24,5 +24,6 @@
[
"grant"
]
]
],
"sends_telemetry_event": true
}

View file

@ -24,5 +24,6 @@
[
"grant"
]
]
],
"sends_telemetry_event": true
}

View file

@ -24,5 +24,6 @@
[
"grant"
]
]
],
"sends_telemetry_event": true
}

View file

@ -24,5 +24,6 @@
[
"grant"
]
]
],
"sends_telemetry_event": true
}

View file

@ -24,5 +24,6 @@
[
"grant"
]
]
],
"sends_telemetry_event": true
}

View file

@ -24,5 +24,6 @@
[
"grant"
]
]
],
"sends_telemetry_event": true
}

View file

@ -24,5 +24,6 @@
[
"grant"
]
]
],
"sends_telemetry_event": true
}

View file

@ -24,5 +24,6 @@
[
"grant"
]
]
],
"sends_telemetry_event": true
}

View file

@ -29,5 +29,6 @@
[
"health_used"
]
]
],
"sends_telemetry_event": true
}

View file

@ -31,5 +31,6 @@
[
"has_charged_amethyst"
]
]
],
"sends_telemetry_event": true
}

View file

@ -24,5 +24,6 @@
[
"did_the_thing"
]
]
],
"sends_telemetry_event": true
}

View file

@ -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)

View file

@ -19,6 +19,7 @@ import net.minecraft.world.entity.EntityType;
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 @@ public interface HexAPI {
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;
}

View file

@ -14,8 +14,7 @@ public class FailToCastGreatSpellTrigger extends SimpleCriterionTrigger<FailToCa
}
@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 class FailToCastGreatSpellTrigger extends SimpleCriterionTrigger<FailToCa
}
public static class Instance extends AbstractCriterionTriggerInstance {
public Instance(EntityPredicate.Composite pPlayer) {
super(ID, pPlayer);
public Instance(ContextAwarePredicate predicate) {
super(ID, predicate);
}
@Override

View file

@ -24,7 +24,7 @@ public class OvercastTrigger extends SimpleCriterionTrigger<OvercastTrigger.Inst
}
@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 class OvercastTrigger extends SimpleCriterionTrigger<OvercastTrigger.Inst
// 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;

View file

@ -17,8 +17,8 @@ public class SpendMediaTrigger extends SimpleCriterionTrigger<SpendMediaTrigger.
}
@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 class SpendMediaTrigger extends SimpleCriterionTrigger<SpendMediaTrigger.
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;

View file

@ -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<Iota>.getIntBetween(idx: Int, min: Int, max: Int, argc: Int = 0): Int {
fun List<Iota>.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")

View file

@ -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
}
}

View file

@ -2,6 +2,7 @@ package at.petrak.hexcasting.api.casting.arithmetic.engine;
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.iota.Iota;
import at.petrak.hexcasting.api.casting.math.HexPattern;
import at.petrak.hexcasting.api.casting.mishaps.Mishap;
@ -65,10 +66,11 @@ public class ArithmeticEngine {
* @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.
* @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<Iota> run(HexPattern pattern, Stack<Iota> iotas, int startingLength) throws Mishap {
public Iterable<Iota> run(HexPattern pattern, Stack<Iota> iotas, int startingLength, CastingEnvironment env) throws Mishap {
var candidates = operators.get(pattern);
if (candidates == null)
throw new InvalidOperatorException("the pattern " + pattern + " is not an operator."); //
@ -84,7 +86,7 @@ public class ArithmeticEngine {
}
Collections.reverse(args);
var op = resolveCandidates(args, hash, candidates);
return op.apply(args);
return op.apply(args, env);
}
private Operator resolveCandidates(List<Iota> args, HashCons hash, OpCandidates candidates) {

View file

@ -1,6 +1,7 @@
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.iota.Iota;
import at.petrak.hexcasting.api.casting.iota.IotaType;
import at.petrak.hexcasting.api.casting.mishaps.Mishap;
@ -36,10 +37,11 @@ public abstract class Operator {
/**
* 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}.
* @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.
*/
public abstract @NotNull Iterable<Iota> apply(@NotNull Iterable<Iota> iotas) throws Mishap;
public abstract @NotNull Iterable<Iota> apply(@NotNull Iterable<Iota> iotas, @NotNull CastingEnvironment env) throws Mishap;
/**
* A helper method to take an iota that you know is of iotaType and returning it as an iota of that type.

View file

@ -2,6 +2,7 @@ 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.iota.Iota;
import org.jetbrains.annotations.NotNull;
@ -20,7 +21,7 @@ public class OperatorBinary extends Operator {
}
@Override
public @NotNull Iterable<Iota> apply(@NotNull Iterable<Iota> iotas) {
public @NotNull Iterable<Iota> apply(@NotNull Iterable<Iota> iotas, @NotNull CastingEnvironment env) {
var it = iotas.iterator();
return List.of(inner.apply(it.next(), it.next()));
}

View file

@ -2,6 +2,7 @@ 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.iota.Iota;
import org.jetbrains.annotations.NotNull;
@ -20,7 +21,7 @@ public class OperatorUnary extends Operator {
}
@Override
public @NotNull Iterable<Iota> apply(@NotNull Iterable<Iota> iotas) {
public @NotNull Iterable<Iota> apply(@NotNull Iterable<Iota> iotas, @NotNull CastingEnvironment env) {
return List.of(inner.apply(iotas.iterator().next()));
}
}

View file

@ -34,6 +34,14 @@ public interface IotaMultiPredicate {
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<Iota> iotas) {
@ -73,4 +81,11 @@ public interface IotaMultiPredicate {
return true;
}
}
record Either(IotaMultiPredicate first, IotaMultiPredicate second) implements IotaMultiPredicate {
@Override
public boolean test(Iterable<Iota> iotas) {
return first.test(iotas) || second.test(iotas);
}
}
}

View file

@ -3,6 +3,8 @@ package at.petrak.hexcasting.api.casting.arithmetic.predicates;
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 @@ public interface IotaPredicate {
return new Or(left, right);
}
static IotaPredicate any(IotaPredicate... any) {
return new Any(any);
}
static IotaPredicate any(List<IotaPredicate> 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 interface IotaPredicate {
}
}
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) {

View file

@ -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<Iota>, env: CastingEnvironment): List<Iota>

View file

@ -24,7 +24,7 @@ data class OperationAction(val pattern: HexPattern) : Action {
stack.addAll(stackList)
val startingLength = stackList.size
return try {
val ret: Iterable<Iota> = HexArithmetics.getEngine().run(pattern, stack, startingLength)
val ret: Iterable<Iota> = HexArithmetics.getEngine().run(pattern, stack, startingLength, env)
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)

View file

@ -21,13 +21,13 @@ interface SpellAction : Action {
fun execute(
args: List<Iota>,
ctx: CastingEnvironment
env: CastingEnvironment
): Result
fun executeWithUserdata(
args: List<Iota>, ctx: CastingEnvironment, userData: CompoundTag
args: List<Iota>, 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<ParticleSpray>, val opCount: Long = 1)
data class Result(val effect: RenderedSpell, val cost: Long, val particles: List<ParticleSpray>, val opCount: Long = 1)
}

View file

@ -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<OperatorSideEffect>,
val resolutionType: ResolvedPatternType,
val sound: EvalSound,
val cast: Iota,
val continuation: SpellContinuation,
val newData: CastingImage?,
val sideEffects: List<OperatorSideEffect>,
val resolutionType: ResolvedPatternType,
val sound: EvalSound,
)

View file

@ -62,6 +62,15 @@ public abstract class CastingEnvironment {
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,9 +81,7 @@ public abstract class CastingEnvironment {
} else {
key = null;
}
if (!HexConfig.server().isActionAllowed(key)) {
throw new MishapDisallowedSpell();
}
return key;
}
/**
@ -112,7 +119,7 @@ public abstract class CastingEnvironment {
public abstract boolean hasEditPermissionsAt(BlockPos vec);
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);
}
@ -175,14 +182,6 @@ public abstract class CastingEnvironment {
return HexUtils.otherHand(this.getCastingHand());
}
/**
* Get the item in the "other hand."
* <p>
* 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 +257,9 @@ public abstract class CastingEnvironment {
if (stackOk.test(stack)) {
presentCount += stack.getCount();
matches.add(stack);
if (presentCount >= count)
break;
}
}
if (presentCount < count) {
@ -268,7 +270,7 @@ public abstract class CastingEnvironment {
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 +284,12 @@ public abstract class CastingEnvironment {
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<ItemStack> stackOk, ItemStack replaceWith, @Nullable InteractionHand hand);
/**
* The order/mode stacks should be discovered in
*/

View file

@ -2,26 +2,31 @@ package at.petrak.hexcasting.api.casting.eval.env;
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,6 +60,17 @@ public class CircleCastEnv extends CastingEnvironment {
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) {
// we always want to play this sound one at a time
@ -110,7 +126,7 @@ public class CircleCastEnv extends CastingEnvironment {
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;
@ -130,11 +146,6 @@ public class CircleCastEnv extends CastingEnvironment {
return InteractionHand.MAIN_HAND;
}
@Override
public ItemStack getAlternateItem() {
return ItemStack.EMPTY.copy(); // TODO: adjacent inventory/item frame?
}
@Override
protected List<ItemStack> getUsableStacks(StackDiscoveryMode mode) {
return new ArrayList<>(); // TODO: Could do something like get items in inventories adjacent to the circle?
@ -145,6 +156,11 @@ public class CircleCastEnv extends CastingEnvironment {
return List.of(); // TODO: Adjacent inv!
}
@Override
public boolean replaceItem(Predicate<ItemStack> stackOk, ItemStack replaceWith, @Nullable InteractionHand hand) {
return false; // TODO: Adjacent inv!
}
@Override
public FrozenPigment getPigment() {
var impetus = this.getImpetus();

View file

@ -2,12 +2,16 @@ package at.petrak.hexcasting.api.casting.eval.env;
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,6 +23,15 @@ public class PackagedItemCastEnv extends PlayerBasedCastEnv {
@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());
}
@ -56,7 +69,10 @@ public class PackagedItemCastEnv extends PlayerBasedCastEnv {
public FrozenPigment getPigment() {
var casterStack = this.caster.getItemInHand(this.castingHand);
var casterHexHolder = IXplatAbstractions.INSTANCE.findHexHolder(casterStack);
return casterHexHolder.getPigment();
var hexHolderPigment = casterHexHolder.getPigment();
if (hexHolderPigment != null)
return hexHolderPigment;
return IXplatAbstractions.INSTANCE.getPigment(this.caster);
}
public EvalSound getSound() {

View file

@ -9,12 +9,12 @@ 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.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 org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
import static at.petrak.hexcasting.api.HexAPI.modLoc;
@ -40,13 +41,13 @@ 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;
}
@ -121,12 +122,54 @@ public abstract class PlayerBasedCastEnv extends CastingEnvironment {
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<ItemStack> 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) {
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;
@ -140,23 +183,14 @@ public abstract class PlayerBasedCastEnv extends CastingEnvironment {
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;
}
}
/**
* Search the player's inventory for media ADs and use them.
*/
protected long extractMediaFromInventory(long costLeft, boolean allowOvercast) {
List<ADMediaHolder> sources = MediaHelper.scanPlayerForMediaStuff(this.caster);
var startCost = costLeft;
for (var source : sources) {
var found = MediaHelper.extractMedia(source, (int) costLeft, true, false);
costLeft -= found;
@ -170,7 +204,7 @@ public abstract class PlayerBasedCastEnv extends CastingEnvironment {
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 +214,8 @@ public abstract class PlayerBasedCastEnv extends CastingEnvironment {
costLeft -= actuallyTaken;
}
this.caster.awardStat(HexStatistics.MEDIA_USED, (int) (startCost - costLeft));
return costLeft;
}
@ -195,8 +231,8 @@ public abstract class PlayerBasedCastEnv extends CastingEnvironment {
}
@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

View file

@ -2,10 +2,9 @@ package at.petrak.hexcasting.api.casting.eval.env;
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 @@ import net.minecraft.world.phys.Vec3;
public class PlayerBasedMishapEnv extends MishapEnvironment {
public PlayerBasedMishapEnv(ServerPlayer player) {
super(player.getLevel(), player);
super(player.serverLevel(), player);
}
@Override
@ -36,13 +35,13 @@ public class PlayerBasedMishapEnv extends MishapEnvironment {
@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);
}

View file

@ -9,8 +9,7 @@ import at.petrak.hexcasting.api.casting.iota.PatternIota;
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 class StaffCastEnv extends PlayerBasedCastEnv {
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) {
@ -95,7 +102,7 @@ public class StaffCastEnv extends PlayerBasedCastEnv {
// 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 class StaffCastEnv extends PlayerBasedCastEnv {
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));
}
}
}

View file

@ -2,6 +2,7 @@ package at.petrak.hexcasting.api.casting.eval.sideeffects
import at.petrak.hexcasting.api.casting.ParticleSpray
import at.petrak.hexcasting.api.casting.RenderedSpell
import at.petrak.hexcasting.api.casting.eval.env.PlayerBasedCastEnv
import at.petrak.hexcasting.api.casting.eval.vm.CastingVM
import at.petrak.hexcasting.api.casting.mishaps.Mishap
import at.petrak.hexcasting.api.mod.HexStatistics
@ -36,7 +37,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 +45,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
}
}

View file

@ -80,11 +80,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 +107,7 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) {
// This means something very bad has happened
exception.printStackTrace()
return CastResult(
iota,
continuation,
null,
listOf(

View file

@ -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<U : ContinuationFrame> {
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)
"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()
)
return (tag.get(HexContinuationTypes.KEY_DATA) as? CompoundTag)?.let { type.deserializeFromNBT(it, world) }
?: FrameEvaluate(SpellList.LList(0, listOf()), false)
}
else -> 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
}
/**
* 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
}
val typeKey = tag.getString(HexContinuationTypes.KEY_TYPE)
if (!ResourceLocation.isValidResourceLocation(typeKey)) {
return null
}
val typeLoc = ResourceLocation(typeKey)
return HexContinuationTypes.REGISTRY[typeLoc]
}
}
}

View file

@ -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<FrameEvaluate> = object : ContinuationFrame.Type<FrameEvaluate> {
override fun deserializeFromNBT(tag: CompoundTag, world: ServerLevel): FrameEvaluate {
return FrameEvaluate(
HexIotaTypes.LIST.deserialize(
tag.getList("patterns", Tag.TAG_COMPOUND),
world
)!!.list,
tag.getBoolean("isMetacasting"))
}
}
}
}

View file

@ -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<FrameFinishEval> = object : ContinuationFrame.Type<FrameFinishEval> {
override fun deserializeFromNBT(tag: CompoundTag, world: ServerLevel) = FrameFinishEval
}
override val type = TYPE
}

View file

@ -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<FrameForEach> = object : ContinuationFrame.Type<FrameForEach> {
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()
)
}
}
}
}

View file

@ -23,7 +23,7 @@ sealed interface SpellContinuation {
var self = this
val frames = mutableListOf<CompoundTag>()
while (self is NotDone) {
frames.add(self.frame.serializeToNBT())
frames.add(ContinuationFrame.toNBT(self.frame))
self = self.next
}
return frames

View file

@ -48,7 +48,7 @@ public class ContinuationIota extends Iota {
@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

View file

@ -54,17 +54,17 @@ public abstract class Iota {
*/
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 abstract class Iota {
* 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&lt;Iota, Iota&gt;, then it should be an iterable over the keys *and*
* values of the map. If you implemented a typed List&lt;Double&gt; iota for some reason, you should instad override
* values of the map. If you implemented a typed List&lt;Double&gt; iota for some reason, you should instead override
* {@link Iota#size}.
*/
public @Nullable Iterable<Iota> subIotas() {

View file

@ -17,6 +17,7 @@ import net.minecraft.util.FormattedCharSequence;
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 abstract class IotaType<T extends 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 abstract class IotaType<T extends Iota> {
}
public static boolean isTooLargeToSerialize(Iterable<Iota> examinee) {
return isTooLargeToSerialize(examinee, 1);
}
private static boolean isTooLargeToSerialize(Iterable<Iota> 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();

View file

@ -115,21 +115,21 @@ public class PatternIota extends Iota {
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);
}
}

View file

@ -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
) {

View file

@ -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<Iota>) {
mob.hurt(HexDamageSources.overcastDamageFrom(env.caster), mob.health)
override fun execute(ctx: CastingEnvironment, errorCtx: Context, stack: MutableList<Iota>) {
mob.hurt(mob.damageSources().source(HexDamageTypes.OVERCAST, ctx.caster), mob.health)
}
override fun particleSpray(ctx: CastingEnvironment) =

View file

@ -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<Iota>) {
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<Iota>) {
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) =

View file

@ -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<Iota>) {
trulyHurt(mob, HexDamageSources.overcastDamageFrom(env.caster), 1f)
override fun execute(ctx: CastingEnvironment, errorCtx: Context, stack: MutableList<Iota>) {
trulyHurt(mob, mob.damageSources().source(HexDamageTypes.OVERCAST, ctx.caster), 1f)
}
override fun particleSpray(ctx: CastingEnvironment): ParticleSpray {

View file

@ -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)
}
}

View file

@ -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<HexPatternRenderHolder>()
private var toRemove = mutableSetOf<HexPatternRenderHolder>()
private var toAdd = ArrayList<HexPatternRenderHolder>()
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<HexPatternRenderHolder> {
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()
}
}

View file

@ -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<Vec2> = 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()
}
}

View file

@ -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
}
}

Some files were not shown because too many files have changed in this diff Show more