Compare commits
78 commits
Author | SHA1 | Date | |
---|---|---|---|
2e3264f037 | |||
d385189a97 | |||
3e3cf73150 | |||
a166f05023 | |||
b11f1c5ced | |||
4a1e4c3269 | |||
a1cb9f7fab | |||
d25682902d | |||
88270d541f | |||
c6f4f3adbc | |||
127b035bbb | |||
88f86d96f4 | |||
31807fe8f7 | |||
c66a5debbc | |||
717dd3e5ad | |||
dd77b14c59 | |||
e88e1b553d | |||
3f3b899ecb | |||
ccaa83a2f9 | |||
1d1efb2a3d | |||
6d3bd9b98f | |||
c8004cc7a4 | |||
77aa0e7380 | |||
3c426a89ee | |||
b50d12464a | |||
f9723bbb8c | |||
b3f285e859 | |||
aaae2e5020 | |||
8f20cec693 | |||
662082211e | |||
4eb5bb846d | |||
bc20923933 | |||
e3ba2718cb | |||
64efb43abd | |||
0a90b0eda2 | |||
47fc2532d0 | |||
05d0f928dd | |||
25402313e7 | |||
0bdfa15aa2 | |||
609e018f9e | |||
0d810ec34f | |||
0fd9ca94d8 | |||
d4e22d157e | |||
bb188a0a6c | |||
ea072d9e64 | |||
81b6958960 | |||
0bffbaaa99 | |||
8501c4ce34 | |||
31ff708d80 | |||
e70d2edb22 | |||
228f68bad9 | |||
28f74a8287 | |||
2ccb3c47e3 | |||
96abc3df0e | |||
63042fd9d8 | |||
afa7684023 | |||
e5e7fa18d4 | |||
f060a83c32 | |||
487818cae2 | |||
33db54e979 | |||
ef12c71e92 | |||
9d8bf7c568 | |||
36b631eadb | |||
26193d9352 | |||
76ba2f5f8a | |||
eacbdb4014 | |||
139357b679 | |||
05be814a8e | |||
32559dc94d | |||
a97545246f | |||
7d611c0220 | |||
cb7255a5ed | |||
e745ff6773 | |||
488cc3ea74 | |||
67a32a6267 | |||
1342c8cbef | |||
80386c4262 | |||
473376943a |
|
@ -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"
|
||||
|
|
BIN
Common/libs/paucal-common-1.20.1-0.6.0.jar
Normal file
BIN
Common/libs/paucal-common-1.20.1-0.6.0.jar
Normal file
Binary file not shown.
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"parent": "hexcasting:block/circle/directrix/boolean/lit_false_east"
|
||||
}
|
|
@ -29,5 +29,6 @@
|
|||
[
|
||||
"waste_amt"
|
||||
]
|
||||
]
|
||||
],
|
||||
"sends_telemetry_event": true
|
||||
}
|
|
@ -29,5 +29,6 @@
|
|||
[
|
||||
"cast_amt"
|
||||
]
|
||||
]
|
||||
],
|
||||
"sends_telemetry_event": true
|
||||
}
|
|
@ -33,5 +33,6 @@
|
|||
[
|
||||
"health_used"
|
||||
]
|
||||
]
|
||||
],
|
||||
"sends_telemetry_event": true
|
||||
}
|
|
@ -31,5 +31,6 @@
|
|||
[
|
||||
"used_item"
|
||||
]
|
||||
]
|
||||
],
|
||||
"sends_telemetry_event": true
|
||||
}
|
|
@ -24,5 +24,6 @@
|
|||
[
|
||||
"grant"
|
||||
]
|
||||
]
|
||||
],
|
||||
"sends_telemetry_event": true
|
||||
}
|
|
@ -24,5 +24,6 @@
|
|||
[
|
||||
"grant"
|
||||
]
|
||||
]
|
||||
],
|
||||
"sends_telemetry_event": true
|
||||
}
|
|
@ -24,5 +24,6 @@
|
|||
[
|
||||
"grant"
|
||||
]
|
||||
]
|
||||
],
|
||||
"sends_telemetry_event": true
|
||||
}
|
|
@ -24,5 +24,6 @@
|
|||
[
|
||||
"grant"
|
||||
]
|
||||
]
|
||||
],
|
||||
"sends_telemetry_event": true
|
||||
}
|
|
@ -24,5 +24,6 @@
|
|||
[
|
||||
"grant"
|
||||
]
|
||||
]
|
||||
],
|
||||
"sends_telemetry_event": true
|
||||
}
|
|
@ -24,5 +24,6 @@
|
|||
[
|
||||
"grant"
|
||||
]
|
||||
]
|
||||
],
|
||||
"sends_telemetry_event": true
|
||||
}
|
|
@ -24,5 +24,6 @@
|
|||
[
|
||||
"grant"
|
||||
]
|
||||
]
|
||||
],
|
||||
"sends_telemetry_event": true
|
||||
}
|
|
@ -24,5 +24,6 @@
|
|||
[
|
||||
"grant"
|
||||
]
|
||||
]
|
||||
],
|
||||
"sends_telemetry_event": true
|
||||
}
|
|
@ -29,5 +29,6 @@
|
|||
[
|
||||
"health_used"
|
||||
]
|
||||
]
|
||||
],
|
||||
"sends_telemetry_event": true
|
||||
}
|
|
@ -31,5 +31,6 @@
|
|||
[
|
||||
"has_charged_amethyst"
|
||||
]
|
||||
]
|
||||
],
|
||||
"sends_telemetry_event": true
|
||||
}
|
|
@ -24,5 +24,6 @@
|
|||
[
|
||||
"did_the_thing"
|
||||
]
|
||||
]
|
||||
],
|
||||
"sends_telemetry_event": true
|
||||
}
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
)
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"))
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<Iota, Iota>, then it should be an iterable over the keys *and*
|
||||
* values of the map. If you implemented a typed List<Double> iota for some reason, you should instad override
|
||||
* values of the map. If you implemented a typed List<Double> iota for some reason, you should instead override
|
||||
* {@link Iota#size}.
|
||||
*/
|
||||
public @Nullable Iterable<Iota> subIotas() {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
) {
|
||||
|
||||
|
|
|
@ -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) =
|
||||
|
|
|
@ -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) =
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
|
@ -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()
|
||||
}
|
||||
}
|
|
@ -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
Loading…
Reference in a new issue