merge from main
This commit is contained in:
commit
ca5ccf60f6
228 changed files with 3150 additions and 931 deletions
|
@ -1,20 +1,25 @@
|
|||
// 1.19.2 2023-01-22T12:41:02.49644171 Item Models: hexcasting
|
||||
// 1.19.2 2023-02-17T23:19:00.76285061 Item Models: hexcasting
|
||||
9af2754cb1e53eeaa85618cf92651b4878cf62b1 assets/hexcasting/models/block/quenched_allay_0.json
|
||||
de4ff723b4332d4e26bd01f74e0485e28c9a2178 assets/hexcasting/models/block/quenched_allay_1.json
|
||||
4c29163e07f3a903017e38a9cc102f4b37db20b1 assets/hexcasting/models/block/quenched_allay_2.json
|
||||
487d34cd8e70b3e468337228b74af5c1b4d14c53 assets/hexcasting/models/block/quenched_allay_3.json
|
||||
f2156b3a7041cf99891b528393db64c6b9ca1a4f assets/hexcasting/models/item/abacus.json
|
||||
933059cd7c2dbaff0e643c644c14af0c0e77aa29 assets/hexcasting/models/item/acacia_staff.json
|
||||
f183fcd384db929bf56e397965057218abc32ddb assets/hexcasting/models/item/acacia_staff.json
|
||||
19730853397b109cfedd0c3bbda83d5de6cd15b9 assets/hexcasting/models/item/akashic_record.json
|
||||
8c735feff09d46d00ed681311f46f61a50cfdc9b assets/hexcasting/models/item/amethyst_dust.json
|
||||
d1b0892de9d751e7bebc763e6407d5285363c851 assets/hexcasting/models/item/artifact.json
|
||||
7eb3eb776e70eb616c12ada500b9d1d6a3249a6a assets/hexcasting/models/item/artifact_filled.json
|
||||
82e3be7bbdad92d2b4c728be54d9d2f2809a0ac2 assets/hexcasting/models/item/battery.json
|
||||
d1310c25bca32980214aa1054eddb1772fb55d12 assets/hexcasting/models/item/birch_staff.json
|
||||
71acb8ff7f0457c46683c16da339363f39c7ea8b assets/hexcasting/models/item/birch_staff.json
|
||||
ec7c3a51882a432185fdbb6a449e66165b6a4c4c assets/hexcasting/models/item/charged_amethyst.json
|
||||
d614c0fd8acb1c18b4211b090d438326d74507f8 assets/hexcasting/models/item/cherry_staff.json
|
||||
c64ed609ece68994ce23dd2809145040bce13579 assets/hexcasting/models/item/conjured.json
|
||||
c64ed609ece68994ce23dd2809145040bce13579 assets/hexcasting/models/item/conjured_block.json
|
||||
c8da4227db3c80e3e2e7f2fb2ae2649656429d68 assets/hexcasting/models/item/creative_unlocker.json
|
||||
b0ad71595b450f5b9a6bdc2a14fc03afef0b850a assets/hexcasting/models/item/crimson_staff.json
|
||||
fd00d0c14663804b78911d7aa73606b88e90ef22 assets/hexcasting/models/item/crimson_staff.json
|
||||
e47acd1d6ef29a3e1941afb1b212bd40b963cb72 assets/hexcasting/models/item/cypher.json
|
||||
2db55347092ad6bc9e58bc968e88a3b6c5fd77c1 assets/hexcasting/models/item/cypher_filled.json
|
||||
cfaf12703ca40959bc5bedac4d1c120273704fcf assets/hexcasting/models/item/dark_oak_staff.json
|
||||
73ded6154a6e2f6929a05c5625372c9e0498db3d assets/hexcasting/models/item/dark_oak_staff.json
|
||||
113c51af571a92009f5f687a82e10bc5ce97b010 assets/hexcasting/models/item/dye_colorizer_black.json
|
||||
b5a04716775ba2e1b137abc513025b2f1065e5d1 assets/hexcasting/models/item/dye_colorizer_blue.json
|
||||
0bb3afbd937b2e07523a581f6e3f389e11078595 assets/hexcasting/models/item/dye_colorizer_brown.json
|
||||
|
@ -36,7 +41,7 @@ c9faada6299f388afc2d2798843d2b45159950d1 assets/hexcasting/models/item/edified_d
|
|||
7f22e012a844cc2c5e30b0fcbdc2e7e4afac1c40 assets/hexcasting/models/item/edified_log.json
|
||||
6b2c9d4aca0c869d7e18707c22b00c14e1d30f0c assets/hexcasting/models/item/edified_pressure_plate.json
|
||||
31b4d60ff15a6d6de7aecb6feeba25a366bba2fd assets/hexcasting/models/item/edified_slab.json
|
||||
ff0e3934116fdae9ecad0d006402868914ab42ec assets/hexcasting/models/item/edified_staff.json
|
||||
aec5d99a7501bdbe7fd7d4ab3640e726682ef0f1 assets/hexcasting/models/item/edified_staff.json
|
||||
2584421c2e9e1cdf22a703018b54cf449613d7d9 assets/hexcasting/models/item/edified_stairs.json
|
||||
ae58c5b7c304d33cbde60caf44a4c4ee4ec1a633 assets/hexcasting/models/item/edified_trapdoor.json
|
||||
084183e4351973c8165f6f459c0f0dba2463d957 assets/hexcasting/models/item/edified_wood.json
|
||||
|
@ -44,11 +49,12 @@ ae58c5b7c304d33cbde60caf44a4c4ee4ec1a633 assets/hexcasting/models/item/edified_t
|
|||
947d1539d88f9d6fd0afcdf831f4327356d19baf assets/hexcasting/models/item/focus_filled.json
|
||||
cb2d973af25a2ec07e6094ecc106c896a06918dc assets/hexcasting/models/item/focus_sealed.json
|
||||
6ec61fea7d8c49cc0c45b64857fd926451b4845f assets/hexcasting/models/item/jeweler_hammer.json
|
||||
c34501cbfc0bb1b6943b4a9986fbe927ff177c61 assets/hexcasting/models/item/jungle_staff.json
|
||||
0777d2158566f7389f4becd2fb2c77664de90c6a assets/hexcasting/models/item/jungle_staff.json
|
||||
abfc028c974a02780aed3d7a5859352503bbd920 assets/hexcasting/models/item/lens.json
|
||||
a34a6d777ae265c7e49c8bb23c15f04359236544 assets/hexcasting/models/item/lore_fragment.json
|
||||
371c16c6c882d6d0370135a8953c408fa1658bed assets/hexcasting/models/item/mangrove_staff.json
|
||||
a17e45161b6723e72c710695a536e39ba0905725 assets/hexcasting/models/item/oak_staff.json
|
||||
dbd52dd3d429578cc81b8b3142d25f8d84501273 assets/hexcasting/models/item/mangrove_staff.json
|
||||
b8fe3a6b792c6014831f047d4c40eaae9f939b1b assets/hexcasting/models/item/mindsplice_staff.json
|
||||
4b65b6848d43cc27adf7e59ebdffd59281fe3937 assets/hexcasting/models/item/oak_staff.json
|
||||
38d1dc73c49d185b86c098b13611bf3ec07b255c assets/hexcasting/models/item/old_staff.json
|
||||
82fa0a2bb17e40c0b3f826e97b2e95445ec24ab8 assets/hexcasting/models/item/patchouli_book.json
|
||||
d69d10e6cb967b98b3294cc86174182c671de671 assets/hexcasting/models/item/phial_large_0.json
|
||||
|
@ -82,6 +88,13 @@ d60b723c44183b59cbadfd02a911dab5e89e0e61 assets/hexcasting/models/item/pride_col
|
|||
6253bab7bd9162f75782c5bc899f46cd941d01ad assets/hexcasting/models/item/pride_colorizer_pansexual.json
|
||||
c67e74e2a323872c3b34b113df99da8b77a501c6 assets/hexcasting/models/item/pride_colorizer_plural.json
|
||||
7c4191ec2479b0a67e578da49d459deea8294ec4 assets/hexcasting/models/item/pride_colorizer_transgender.json
|
||||
5038e069909e2dcf8664bcde81b229c8e27191ae assets/hexcasting/models/item/quenched_allay.json
|
||||
a8859c93236b88f9ed46a4957f5723965ce04e03 assets/hexcasting/models/item/quenched_allay_shard.json
|
||||
8105007d186fe2c6bea6958dd85d1b2ed3cecb58 assets/hexcasting/models/item/quenched_shard_0.json
|
||||
aef7d4b759bcc8a1d5b886b8a0170657e447a8d8 assets/hexcasting/models/item/quenched_shard_1.json
|
||||
4a08374ef00de51381df9659488cb305e7c8674f assets/hexcasting/models/item/quenched_shard_2.json
|
||||
181aac0f66e5c3937f49da3f5d577f1c8045c635 assets/hexcasting/models/item/quenched_shard_3.json
|
||||
628df1d43bb959bd7424253d2cf367947e147155 assets/hexcasting/models/item/quenched_staff.json
|
||||
1ac1d158da25a8f8ec4b8771445d1ec9d42e9519 assets/hexcasting/models/item/scroll.json
|
||||
ae2a8b6eb8a4ef17926e20c6982bc01120ff32b7 assets/hexcasting/models/item/scroll_ancient_large.json
|
||||
7478e4b91169a3ab9def5af8662db9696eb33a34 assets/hexcasting/models/item/scroll_ancient_medium.json
|
||||
|
@ -97,11 +110,17 @@ e6452f95b60240e0067769d7f32a0b9fa7718a1b assets/hexcasting/models/item/slate_wri
|
|||
986674763b45e0f9381f9f34a708082e5230652a assets/hexcasting/models/item/spellbook.json
|
||||
f962c13ab9e299885387cee35b16006651821e81 assets/hexcasting/models/item/spellbook_filled.json
|
||||
c29e6e7b2168eeeb13b1fc3e93ffc3e0c9bd11ce assets/hexcasting/models/item/spellbook_sealed.json
|
||||
2f422cc59c84f6c997475367967390186adce5f0 assets/hexcasting/models/item/spruce_staff.json
|
||||
bc2dbafadff333484c397675325df15f95e8b9f1 assets/hexcasting/models/item/spruce_staff.json
|
||||
65bbc32202a58cdae91165e059e53bcfb2c54e10 assets/hexcasting/models/item/staves/quenched_0.json
|
||||
9d8d276d077fc9ee355d4af5b62d5f63087ed6e1 assets/hexcasting/models/item/staves/quenched_1.json
|
||||
ff1f37ac81e58185d9ea63d1ef75558e30f2e193 assets/hexcasting/models/item/staves/quenched_2.json
|
||||
5cb3a83a9e601d4955e0c5456c621c4ac3f3d76e assets/hexcasting/models/item/staves/quenched_3.json
|
||||
d6ebc87cb0fa6f86bee3a4eade7329ebb0cf2d38 assets/hexcasting/models/item/stripped_edified_log.json
|
||||
ea3f18f75776022127f3a108119e3f7a5c211c0f assets/hexcasting/models/item/stripped_edified_wood.json
|
||||
0a100b64e77394606018320bbc5752a546fe0af4 assets/hexcasting/models/item/sub_sandwich.json
|
||||
6a7f5af82cf8ec72c3457ef4c1ae11a76717bf88 assets/hexcasting/models/item/thought_knot.json
|
||||
93b2191ffab47003f661b75a85cd833ec64f0c15 assets/hexcasting/models/item/thought_knot_written.json
|
||||
5f4831d11d8f45b037a6f48e12d2e794ada7b961 assets/hexcasting/models/item/trinket.json
|
||||
946970e74b8d3c76c15191f494bc1f3d7e36aa43 assets/hexcasting/models/item/trinket_filled.json
|
||||
c6523de66cbfae3a1e6361c635cc693a0a089bb3 assets/hexcasting/models/item/uuid_colorizer.json
|
||||
a882b3dbb46c9abee345c446fb83f4d293442c5f assets/hexcasting/models/item/warped_staff.json
|
||||
30e95dd075eab5379410ce5a7e0cd53dfb606005 assets/hexcasting/models/item/warped_staff.json
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// 1.19.2 2022-11-05T14:30:43.69127 Block States: hexcasting
|
||||
// 1.19.2 2023-02-17T23:01:49.857526865 Block States: hexcasting
|
||||
901e38574bdaa40ea4a0f6e773a88a95d9c03e55 assets/hexcasting/blockstates/akashic_bookshelf.json
|
||||
32a77ef668198002563d68be35a24fa93c8d454a assets/hexcasting/blockstates/akashic_connector.json
|
||||
85080ce0a0387583a839e4788517d675a1a35e24 assets/hexcasting/blockstates/akashic_record.json
|
||||
|
@ -29,6 +29,7 @@ e44322f1178e121b70f45e5242d5b0e9a11c211c assets/hexcasting/blockstates/edified_w
|
|||
4ffe2f23f6774045d40e3763efa161da84d777c8 assets/hexcasting/blockstates/impetus_look.json
|
||||
1e45bbe847d2edbec8189249f9afb58acda3fe05 assets/hexcasting/blockstates/impetus_rightclick.json
|
||||
1d568faf935ff3c67d6a7f074a5d0d3ef6406101 assets/hexcasting/blockstates/impetus_storedplayer.json
|
||||
c41c3f2f39c9fa8a319a705e2183112df18cb4f8 assets/hexcasting/blockstates/quenched_allay.json
|
||||
0aca7e2e67793a21ffc794c02fb2b22d02d2058a assets/hexcasting/blockstates/scroll_paper.json
|
||||
e5c88e23be0552d4c06062510e8feeab510472ef assets/hexcasting/blockstates/scroll_paper_lantern.json
|
||||
ef6b44bd2360926cb9dcde5bb3f1380385acea90 assets/hexcasting/blockstates/slate.json
|
||||
|
@ -134,6 +135,7 @@ de2a5fd9b621e5086852f2191c360d9274b9b10c assets/hexcasting/models/block/impetus_
|
|||
7ac5cb74f321b061c1e93b859540b508c7dcdaa4 assets/hexcasting/models/block/impetus_storedplayer_lit_south.json
|
||||
46c29660e3fa78aeaa264268b43017f4b0c0d655 assets/hexcasting/models/block/impetus_storedplayer_lit_up.json
|
||||
4d22557274958179da4671c43c2f387336a701a2 assets/hexcasting/models/block/impetus_storedplayer_lit_west.json
|
||||
9af2754cb1e53eeaa85618cf92651b4878cf62b1 assets/hexcasting/models/block/quenched_allay.json
|
||||
e1e7ce0bcc08a53b3e6634f7e5b7a6cf488cf45b assets/hexcasting/models/block/redstone_directrix_powered_dim_down.json
|
||||
fb22e529f1ca638b7e952176694ab1912eb4274b assets/hexcasting/models/block/redstone_directrix_powered_dim_east.json
|
||||
a5a53ec6a3cd54592dcb224245a4515a2b3b72ed assets/hexcasting/models/block/redstone_directrix_powered_dim_north.json
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"variants": {
|
||||
"": {
|
||||
"model": "hexcasting:block/quenched_allay"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:block/cube_all",
|
||||
"textures": {
|
||||
"all": "hexcasting:block/quenched_allay_0"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:block/cube_all",
|
||||
"textures": {
|
||||
"all": "hexcasting:block/quenched_allay_0"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:block/cube_all",
|
||||
"textures": {
|
||||
"all": "hexcasting:block/quenched_allay_1"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:block/cube_all",
|
||||
"textures": {
|
||||
"all": "hexcasting:block/quenched_allay_2"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:block/cube_all",
|
||||
"textures": {
|
||||
"all": "hexcasting:block/quenched_allay_3"
|
||||
}
|
||||
}
|
|
@ -8,9 +8,9 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"model": "hexcasting:item/old_staff",
|
||||
"model": "hexcasting:item/cherry_staff",
|
||||
"predicate": {
|
||||
"hexcasting:funny_level": 1.0
|
||||
"hexcasting:funny_level": 2.0
|
||||
}
|
||||
}
|
||||
],
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"model": "hexcasting:item/old_staff",
|
||||
"model": "hexcasting:item/cherry_staff",
|
||||
"predicate": {
|
||||
"hexcasting:funny_level": 1.0
|
||||
"hexcasting:funny_level": 2.0
|
||||
}
|
||||
}
|
||||
],
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:item/handheld_rod",
|
||||
"textures": {
|
||||
"layer0": "hexcasting:item/staves/cherry"
|
||||
}
|
||||
}
|
|
@ -8,9 +8,9 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"model": "hexcasting:item/old_staff",
|
||||
"model": "hexcasting:item/cherry_staff",
|
||||
"predicate": {
|
||||
"hexcasting:funny_level": 1.0
|
||||
"hexcasting:funny_level": 2.0
|
||||
}
|
||||
}
|
||||
],
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"model": "hexcasting:item/old_staff",
|
||||
"model": "hexcasting:item/cherry_staff",
|
||||
"predicate": {
|
||||
"hexcasting:funny_level": 1.0
|
||||
"hexcasting:funny_level": 2.0
|
||||
}
|
||||
}
|
||||
],
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"model": "hexcasting:item/old_staff",
|
||||
"model": "hexcasting:item/cherry_staff",
|
||||
"predicate": {
|
||||
"hexcasting:funny_level": 1.0
|
||||
"hexcasting:funny_level": 2.0
|
||||
}
|
||||
}
|
||||
],
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"model": "hexcasting:item/old_staff",
|
||||
"model": "hexcasting:item/cherry_staff",
|
||||
"predicate": {
|
||||
"hexcasting:funny_level": 1.0
|
||||
"hexcasting:funny_level": 2.0
|
||||
}
|
||||
}
|
||||
],
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"model": "hexcasting:item/old_staff",
|
||||
"model": "hexcasting:item/cherry_staff",
|
||||
"predicate": {
|
||||
"hexcasting:funny_level": 1.0
|
||||
"hexcasting:funny_level": 2.0
|
||||
}
|
||||
}
|
||||
],
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"parent": "minecraft:item/handheld_rod",
|
||||
"overrides": [
|
||||
{
|
||||
"model": "hexcasting:item/mindsplice_staff",
|
||||
"predicate": {
|
||||
"hexcasting:funny_level": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "hexcasting:item/cherry_staff",
|
||||
"predicate": {
|
||||
"hexcasting:funny_level": 2.0
|
||||
}
|
||||
}
|
||||
],
|
||||
"textures": {
|
||||
"layer0": "hexcasting:item/staves/mindsplice"
|
||||
}
|
||||
}
|
|
@ -8,9 +8,9 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"model": "hexcasting:item/old_staff",
|
||||
"model": "hexcasting:item/cherry_staff",
|
||||
"predicate": {
|
||||
"hexcasting:funny_level": 1.0
|
||||
"hexcasting:funny_level": 2.0
|
||||
}
|
||||
}
|
||||
],
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"overrides": [
|
||||
{
|
||||
"model": "hexcasting:block/quenched_allay_0",
|
||||
"predicate": {
|
||||
"hexcasting:variant": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "hexcasting:block/quenched_allay_1",
|
||||
"predicate": {
|
||||
"hexcasting:variant": 1.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "hexcasting:block/quenched_allay_2",
|
||||
"predicate": {
|
||||
"hexcasting:variant": 2.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "hexcasting:block/quenched_allay_3",
|
||||
"predicate": {
|
||||
"hexcasting:variant": 3.0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"overrides": [
|
||||
{
|
||||
"model": "hexcasting:item/quenched_shard_0",
|
||||
"predicate": {
|
||||
"hexcasting:variant": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "hexcasting:item/quenched_shard_1",
|
||||
"predicate": {
|
||||
"hexcasting:variant": 1.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "hexcasting:item/quenched_shard_2",
|
||||
"predicate": {
|
||||
"hexcasting:variant": 2.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "hexcasting:item/quenched_shard_3",
|
||||
"predicate": {
|
||||
"hexcasting:variant": 3.0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:item/handheld",
|
||||
"textures": {
|
||||
"layer0": "hexcasting:item/quenched_shard_0"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:item/handheld",
|
||||
"textures": {
|
||||
"layer0": "hexcasting:item/quenched_shard_1"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:item/handheld",
|
||||
"textures": {
|
||||
"layer0": "hexcasting:item/quenched_shard_2"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:item/handheld",
|
||||
"textures": {
|
||||
"layer0": "hexcasting:item/quenched_shard_3"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"overrides": [
|
||||
{
|
||||
"model": "hexcasting:item/staves/quenched_0",
|
||||
"predicate": {
|
||||
"hexcasting:variant": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "hexcasting:item/staves/quenched_1",
|
||||
"predicate": {
|
||||
"hexcasting:variant": 1.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "hexcasting:item/staves/quenched_2",
|
||||
"predicate": {
|
||||
"hexcasting:variant": 2.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "hexcasting:item/staves/quenched_3",
|
||||
"predicate": {
|
||||
"hexcasting:variant": 3.0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -8,9 +8,9 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"model": "hexcasting:item/old_staff",
|
||||
"model": "hexcasting:item/cherry_staff",
|
||||
"predicate": {
|
||||
"hexcasting:funny_level": 1.0
|
||||
"hexcasting:funny_level": 2.0
|
||||
}
|
||||
}
|
||||
],
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:item/handheld_rod",
|
||||
"textures": {
|
||||
"layer0": "hexcasting:item/staves/quenched_0"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:item/handheld_rod",
|
||||
"textures": {
|
||||
"layer0": "hexcasting:item/staves/quenched_1"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:item/handheld_rod",
|
||||
"textures": {
|
||||
"layer0": "hexcasting:item/staves/quenched_2"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:item/handheld_rod",
|
||||
"textures": {
|
||||
"layer0": "hexcasting:item/staves/quenched_3"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"parent": "minecraft:item/generated",
|
||||
"overrides": [
|
||||
{
|
||||
"model": "hexcasting:item/thought_knot",
|
||||
"predicate": {
|
||||
"hexcasting:written": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "hexcasting:item/thought_knot_written",
|
||||
"predicate": {
|
||||
"hexcasting:written": 1.0
|
||||
}
|
||||
}
|
||||
],
|
||||
"textures": {
|
||||
"layer0": "hexcasting:item/thought_knot"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"parent": "minecraft:item/generated",
|
||||
"textures": {
|
||||
"layer0": "hexcasting:item/thought_knot",
|
||||
"layer1": "hexcasting:item/thought_knot_overlay"
|
||||
}
|
||||
}
|
|
@ -8,9 +8,9 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"model": "hexcasting:item/old_staff",
|
||||
"model": "hexcasting:item/cherry_staff",
|
||||
"predicate": {
|
||||
"hexcasting:funny_level": 1.0
|
||||
"hexcasting:funny_level": 2.0
|
||||
}
|
||||
}
|
||||
],
|
||||
|
|
|
@ -42,7 +42,7 @@ public interface ADMediaHolder {
|
|||
|
||||
/**
|
||||
* The priority for this media holder to be selected when casting a hex. Higher priorities are taken first.
|
||||
*
|
||||
* <p>
|
||||
* By default,
|
||||
* * Charged Amethyst has priority 1000
|
||||
* * Amethyst Shards have priority 2000
|
||||
|
@ -58,9 +58,9 @@ public interface ADMediaHolder {
|
|||
|
||||
/**
|
||||
* Withdraws media from the holder. Returns the amount of media extracted, which may be less or more than the cost.
|
||||
*
|
||||
* <p>
|
||||
* Even if {@link ADMediaHolder#canProvide} is false, you can still withdraw media this way.
|
||||
*
|
||||
* <p>
|
||||
* Withdrawing a negative amount will act as though you attempted to withdraw as much media as the holder contains.
|
||||
*/
|
||||
default int withdrawMedia(int cost, boolean simulate) {
|
||||
|
@ -77,10 +77,11 @@ public interface ADMediaHolder {
|
|||
|
||||
/**
|
||||
* Inserts media into the holder. Returns the amount of media inserted, which may be less than the requested amount.
|
||||
*
|
||||
* <p>
|
||||
* Even if {@link ADMediaHolder#canRecharge} is false, you can still insert media this way.
|
||||
*
|
||||
* Inserting a negative amount will act as though you attempted to insert exactly as much media as the holder was missing.
|
||||
* <p>
|
||||
* Inserting a negative amount will act as though you attempted to insert exactly as much media as the holder was
|
||||
* missing.
|
||||
*/
|
||||
default int insertMedia(int amount, boolean simulate) {
|
||||
var mediaHere = getMedia();
|
||||
|
@ -101,6 +102,7 @@ public interface ADMediaHolder {
|
|||
return inserting;
|
||||
}
|
||||
|
||||
int QUENCHED_ALLAY_PRIORITY = 900;
|
||||
int CHARGED_AMETHYST_PRIORITY = 1000;
|
||||
int AMETHYST_SHARD_PRIORITY = 2000;
|
||||
int AMETHYST_DUST_PRIORITY = 3000;
|
||||
|
|
|
@ -6,6 +6,10 @@ import at.petrak.hexcasting.xplat.IXplatAbstractions
|
|||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
/**
|
||||
* @param fuzziness the radius of the sphere the particle might happen in (pos)
|
||||
* @param spread the max angle in radians the particle can move in, in relation to vel
|
||||
*/
|
||||
data class ParticleSpray(val pos: Vec3, val vel: Vec3, val fuzziness: Double, val spread: Double, val count: Int = 20) {
|
||||
companion object {
|
||||
@JvmStatic
|
||||
|
|
|
@ -4,4 +4,7 @@ public final class MediaConstants {
|
|||
public static final int DUST_UNIT = 10000;
|
||||
public static final int SHARD_UNIT = 5 * DUST_UNIT;
|
||||
public static final int CRYSTAL_UNIT = 10 * DUST_UNIT;
|
||||
|
||||
public static final int QUENCHED_SHARD_UNIT = 3 * CRYSTAL_UNIT;
|
||||
public static final int QUENCHED_BLOCK_UNIT = 4 * QUENCHED_SHARD_UNIT;
|
||||
}
|
||||
|
|
|
@ -21,11 +21,21 @@ public class HexConfig {
|
|||
|
||||
double mediaToHealthRate();
|
||||
|
||||
int cypherCooldown();
|
||||
|
||||
int trinketCooldown();
|
||||
|
||||
int artifactCooldown();
|
||||
|
||||
int DEFAULT_DUST_MEDIA_AMOUNT = MediaConstants.DUST_UNIT;
|
||||
int DEFAULT_SHARD_MEDIA_AMOUNT = MediaConstants.SHARD_UNIT;
|
||||
int DEFAULT_CHARGED_MEDIA_AMOUNT = MediaConstants.CRYSTAL_UNIT;
|
||||
double DEFAULT_MEDIA_TO_HEALTH_RATE = 2 * MediaConstants.CRYSTAL_UNIT / 20.0;
|
||||
|
||||
int DEFAULT_CYPHER_COOLDOWN = 8;
|
||||
int DEFAULT_TRINKET_COOLDOWN = 5;
|
||||
int DEFAULT_ARTIFACT_COOLDOWN = 3;
|
||||
|
||||
}
|
||||
|
||||
public interface ClientConfigAccess {
|
||||
|
|
|
@ -20,6 +20,10 @@ public class HexTags {
|
|||
public static final TagKey<Item> GRANTS_ROOT_ADVANCEMENT = create("grants_root_advancement");
|
||||
public static final TagKey<Item> SEAL_MATERIALS = create("seal_materials");
|
||||
|
||||
public static final TagKey<Item> IMPETI = create("impeti");
|
||||
public static final TagKey<Item> DIRECTRICES = create("directrices");
|
||||
public static final TagKey<Item> MINDFLAYED_CIRCLE_COMPONENTS = create("brainswept_circle_components");
|
||||
|
||||
public static TagKey<Item> create(String name) {
|
||||
return create(modLoc(name));
|
||||
}
|
||||
|
@ -33,6 +37,11 @@ public class HexTags {
|
|||
public static final TagKey<Block> EDIFIED_LOGS = create("edified_logs");
|
||||
public static final TagKey<Block> EDIFIED_PLANKS = create("edified_planks");
|
||||
|
||||
|
||||
public static final TagKey<Block> IMPETI = create("impeti");
|
||||
public static final TagKey<Block> DIRECTRICES = create("directrices");
|
||||
public static final TagKey<Block> MINDFLAYED_CIRCLE_COMPONENTS = create("brainswept_circle_components");
|
||||
|
||||
public static TagKey<Block> create(String name) {
|
||||
return TagKey.create(Registry.BLOCK_REGISTRY, modLoc(name));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
package at.petrak.hexcasting.api.player;
|
||||
|
||||
/**
|
||||
* Note that this just keeps track of state, actually giving the player the elytra ability is handled
|
||||
* differently per platform
|
||||
*
|
||||
* @param gracePeriod so the flight isn't immediately removed because the player started on the ground
|
||||
*/
|
||||
public record AltioraAbility(int gracePeriod) {
|
||||
}
|
|
@ -4,8 +4,9 @@ import net.minecraft.resources.ResourceKey;
|
|||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public record FlightAbility(boolean allowed, int timeLeft, ResourceKey<Level> dimension, Vec3 origin, double radius) {
|
||||
public static FlightAbility deny() {
|
||||
return new FlightAbility(false, 0, Level.OVERWORLD, Vec3.ZERO, 0);
|
||||
}
|
||||
/**
|
||||
* @param timeLeft sentinel of -1 for infinite
|
||||
* @param radius sentinel of negative for infinite
|
||||
*/
|
||||
public record FlightAbility(int timeLeft, ResourceKey<Level> dimension, Vec3 origin, double radius) {
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package at.petrak.hexcasting.client;
|
||||
|
||||
import at.petrak.hexcasting.client.render.GaslightingTracker;
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
||||
public class ClientTickCounter {
|
||||
|
@ -18,6 +19,7 @@ public class ClientTickCounter {
|
|||
if (!Minecraft.getInstance().isPaused()) {
|
||||
++ticksInGame;
|
||||
partialTicks = 0.0F;
|
||||
GaslightingTracker.postFrameCheckRendered();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,66 +1,71 @@
|
|||
package at.petrak.hexcasting.client;
|
||||
|
||||
import at.petrak.hexcasting.api.block.circle.BlockAbstractImpetus;
|
||||
import at.petrak.hexcasting.api.block.circle.BlockEntityAbstractImpetus;
|
||||
import at.petrak.hexcasting.api.casting.iota.IotaType;
|
||||
import at.petrak.hexcasting.api.client.ScryingLensOverlayRegistry;
|
||||
import at.petrak.hexcasting.api.item.IotaHolderItem;
|
||||
import at.petrak.hexcasting.api.item.MediaHolderItem;
|
||||
import at.petrak.hexcasting.api.misc.MediaConstants;
|
||||
import at.petrak.hexcasting.api.utils.NBTHelper;
|
||||
import at.petrak.hexcasting.client.be.BlockEntityAkashicBookshelfRenderer;
|
||||
import at.petrak.hexcasting.client.be.BlockEntitySlateRenderer;
|
||||
import at.petrak.hexcasting.client.entity.WallScrollRenderer;
|
||||
import at.petrak.hexcasting.client.render.GaslightingTracker;
|
||||
import at.petrak.hexcasting.client.render.ScryingLensOverlays;
|
||||
import at.petrak.hexcasting.client.render.be.BlockEntityAkashicBookshelfRenderer;
|
||||
import at.petrak.hexcasting.client.render.be.BlockEntityQuenchedAllayRenderer;
|
||||
import at.petrak.hexcasting.client.render.be.BlockEntitySlateRenderer;
|
||||
import at.petrak.hexcasting.common.blocks.BlockQuenchedAllay;
|
||||
import at.petrak.hexcasting.common.blocks.akashic.BlockAkashicBookshelf;
|
||||
import at.petrak.hexcasting.common.blocks.akashic.BlockEntityAkashicBookshelf;
|
||||
import at.petrak.hexcasting.common.entities.HexEntities;
|
||||
import at.petrak.hexcasting.common.items.*;
|
||||
import at.petrak.hexcasting.common.items.ItemStaff;
|
||||
import at.petrak.hexcasting.common.items.magic.ItemMediaBattery;
|
||||
import at.petrak.hexcasting.common.items.magic.ItemPackagedHex;
|
||||
import at.petrak.hexcasting.common.items.storage.*;
|
||||
import at.petrak.hexcasting.common.lib.HexBlockEntities;
|
||||
import at.petrak.hexcasting.common.lib.HexBlocks;
|
||||
import at.petrak.hexcasting.common.lib.HexItems;
|
||||
import at.petrak.hexcasting.xplat.IClientXplatAbstractions;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.client.color.block.BlockColor;
|
||||
import net.minecraft.client.color.item.ItemColor;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.Style;
|
||||
import net.minecraft.network.chat.TextColor;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.client.resources.model.ModelBakery;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.packs.resources.ResourceManager;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.*;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.properties.ComparatorMode;
|
||||
import net.minecraft.world.level.block.state.properties.NoteBlockInstrument;
|
||||
import net.minecraft.world.level.block.state.properties.RailShape;
|
||||
import net.minecraft.world.level.material.MaterialColor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.ToIntFunction;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
import static at.petrak.hexcasting.api.HexAPI.modLoc;
|
||||
|
||||
public class RegisterClientStuff {
|
||||
public static List<BakedModel> QUENCHED_ALLAY_VARIANTS = new ArrayList<>();
|
||||
|
||||
public static void init() {
|
||||
registerDataHolderOverrides(HexItems.FOCUS,
|
||||
registerSealableDataHolderOverrides(HexItems.FOCUS,
|
||||
stack -> HexItems.FOCUS.readIotaTag(stack) != null,
|
||||
ItemFocus::isSealed);
|
||||
registerDataHolderOverrides(HexItems.SPELLBOOK,
|
||||
registerSealableDataHolderOverrides(HexItems.SPELLBOOK,
|
||||
stack -> HexItems.SPELLBOOK.readIotaTag(stack) != null,
|
||||
ItemSpellbook::isSealed);
|
||||
IClientXplatAbstractions.INSTANCE.registerItemProperty(HexItems.THOUGHT_KNOT, ItemThoughtKnot.WRITTEN_PRED,
|
||||
(stack, level, holder, holderID) -> {
|
||||
if (NBTHelper.contains(stack, ItemThoughtKnot.TAG_DATA)) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
|
||||
registerPackagedSpellOverrides(HexItems.CYPHER);
|
||||
registerPackagedSpellOverrides(HexItems.TRINKET);
|
||||
|
@ -93,6 +98,12 @@ public class RegisterClientStuff {
|
|||
registerWandOverrides(HexItems.STAFF_DARK_OAK);
|
||||
registerWandOverrides(HexItems.STAFF_ACACIA);
|
||||
registerWandOverrides(HexItems.STAFF_EDIFIED);
|
||||
// purposely skip quenched
|
||||
registerWandOverrides(HexItems.STAFF_MINDSPLICE);
|
||||
|
||||
registerGaslight4(HexItems.STAFF_QUENCHED);
|
||||
registerGaslight4(HexBlocks.QUENCHED_ALLAY.asItem());
|
||||
registerGaslight4(HexItems.QUENCHED_SHARD);
|
||||
|
||||
x.setRenderLayer(HexBlocks.CONJURED_LIGHT, RenderType.cutout());
|
||||
x.setRenderLayer(HexBlocks.CONJURED_BLOCK, RenderType.cutout());
|
||||
|
@ -106,6 +117,7 @@ public class RegisterClientStuff {
|
|||
x.setRenderLayer(HexBlocks.CITRINE_EDIFIED_LEAVES, RenderType.cutoutMipped());
|
||||
|
||||
x.setRenderLayer(HexBlocks.AKASHIC_RECORD, RenderType.translucent());
|
||||
x.setRenderLayer(HexBlocks.QUENCHED_ALLAY, RenderType.translucent());
|
||||
|
||||
x.registerEntityRenderer(HexEntities.WALL_SCROLL, WallScrollRenderer::new);
|
||||
|
||||
|
@ -117,13 +129,20 @@ public class RegisterClientStuff {
|
|||
// Minecraft.getInstance().getTextureManager().bindForSetup(tex);
|
||||
// }
|
||||
|
||||
addScryingLensStuff();
|
||||
ScryingLensOverlays.addScryingLensStuff();
|
||||
}
|
||||
|
||||
private static void registerGaslight4(Item item) {
|
||||
IClientXplatAbstractions.INSTANCE.registerItemProperty(item,
|
||||
GaslightingTracker.GASLIGHTING_PRED, (stack, level, holder, holderID) ->
|
||||
Math.abs(GaslightingTracker.getGaslightingAmount() % 4));
|
||||
}
|
||||
|
||||
public static void registerColorProviders(BiConsumer<ItemColor, Item> itemColorRegistry,
|
||||
BiConsumer<BlockColor, Block> blockColorRegistry) {
|
||||
itemColorRegistry.accept(makeIotaStorageColorizer(HexItems.FOCUS::getColor), HexItems.FOCUS);
|
||||
itemColorRegistry.accept(makeIotaStorageColorizer(HexItems.SPELLBOOK::getColor), HexItems.SPELLBOOK);
|
||||
itemColorRegistry.accept(makeIotaStorageColorizer(HexItems.THOUGHT_KNOT::getColor), HexItems.THOUGHT_KNOT);
|
||||
|
||||
blockColorRegistry.accept((bs, level, pos, idx) -> {
|
||||
if (!bs.getValue(BlockAkashicBookshelf.HAS_BOOKS) || level == null || pos == null) {
|
||||
|
@ -156,153 +175,7 @@ public class RegisterClientStuff {
|
|||
};
|
||||
}
|
||||
|
||||
private static void addScryingLensStuff() {
|
||||
ScryingLensOverlayRegistry.addPredicateDisplayer(
|
||||
(state, pos, observer, world, direction) -> state.getBlock() instanceof BlockAbstractImpetus,
|
||||
(lines, state, pos, observer, world, direction) -> {
|
||||
if (world.getBlockEntity(pos) instanceof BlockEntityAbstractImpetus beai) {
|
||||
beai.applyScryingLensOverlay(lines, state, pos, observer, world, direction);
|
||||
}
|
||||
});
|
||||
|
||||
ScryingLensOverlayRegistry.addDisplayer(Blocks.NOTE_BLOCK,
|
||||
(lines, state, pos, observer, world, direction) -> {
|
||||
int note = state.getValue(NoteBlock.NOTE);
|
||||
|
||||
float rCol = Math.max(0.0F, Mth.sin((note / 24F + 0.0F) * Mth.TWO_PI) * 0.65F + 0.35F);
|
||||
float gCol = Math.max(0.0F, Mth.sin((note / 24F + 0.33333334F) * Mth.TWO_PI) * 0.65F + 0.35F);
|
||||
float bCol = Math.max(0.0F, Mth.sin((note / 24F + 0.6666667F) * Mth.TWO_PI) * 0.65F + 0.35F);
|
||||
|
||||
int noteColor = 0xFF_000000 | Mth.color(rCol, gCol, bCol);
|
||||
|
||||
var instrument = state.getValue(NoteBlock.INSTRUMENT);
|
||||
|
||||
lines.add(new Pair<>(
|
||||
new ItemStack(Items.MUSIC_DISC_CHIRP),
|
||||
Component.literal(String.valueOf(instrument.ordinal()))
|
||||
.withStyle(color(instrumentColor(instrument)))));
|
||||
lines.add(new Pair<>(
|
||||
new ItemStack(Items.NOTE_BLOCK),
|
||||
Component.literal(String.valueOf(note))
|
||||
.withStyle(color(noteColor))));
|
||||
});
|
||||
|
||||
ScryingLensOverlayRegistry.addDisplayer(HexBlocks.AKASHIC_BOOKSHELF,
|
||||
(lines, state, pos, observer, world, direction) -> {
|
||||
if (world.getBlockEntity(pos) instanceof BlockEntityAkashicBookshelf tile) {
|
||||
var iotaTag = tile.getIotaTag();
|
||||
if (iotaTag != null) {
|
||||
var display = IotaType.getDisplay(iotaTag);
|
||||
lines.add(new Pair<>(new ItemStack(Items.BOOK), display));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ScryingLensOverlayRegistry.addDisplayer(Blocks.COMPARATOR,
|
||||
(lines, state, pos, observer, world, direction) -> {
|
||||
int comparatorValue = ScryingLensOverlayRegistry.getComparatorValue(true);
|
||||
lines.add(new Pair<>(
|
||||
new ItemStack(Items.REDSTONE),
|
||||
Component.literal(comparatorValue == -1 ? "" : String.valueOf(comparatorValue))
|
||||
.withStyle(redstoneColor(comparatorValue))));
|
||||
|
||||
boolean compare = state.getValue(ComparatorBlock.MODE) == ComparatorMode.COMPARE;
|
||||
|
||||
lines.add(new Pair<>(
|
||||
new ItemStack(Items.REDSTONE_TORCH),
|
||||
Component.literal(compare ? ">=" : "-")
|
||||
.withStyle(redstoneColor(compare ? 0 : 15))));
|
||||
});
|
||||
|
||||
ScryingLensOverlayRegistry.addDisplayer(Blocks.POWERED_RAIL,
|
||||
(lines, state, pos, observer, world, direction) -> {
|
||||
int power = getPoweredRailStrength(world, pos, state);
|
||||
lines.add(new Pair<>(
|
||||
new ItemStack(Items.POWERED_RAIL),
|
||||
Component.literal(String.valueOf(power))
|
||||
.withStyle(redstoneColor(power, 9))));
|
||||
});
|
||||
|
||||
ScryingLensOverlayRegistry.addDisplayer(Blocks.REPEATER,
|
||||
(lines, state, pos, observer, world, direction) -> lines.add(new Pair<>(
|
||||
new ItemStack(Items.CLOCK),
|
||||
Component.literal(String.valueOf(state.getValue(RepeaterBlock.DELAY)))
|
||||
.withStyle(ChatFormatting.YELLOW))));
|
||||
|
||||
ScryingLensOverlayRegistry.addPredicateDisplayer(
|
||||
(state, pos, observer, world, direction) -> state.getBlock() instanceof BeehiveBlock,
|
||||
(lines, state, pos, observer, world, direction) -> {
|
||||
int count = ScryingLensOverlayRegistry.getBeeValue();
|
||||
lines.add(new Pair<>(new ItemStack(Items.BEE_NEST), count == -1 ? Component.empty() :
|
||||
Component.translatable(
|
||||
"hexcasting.tooltip.lens.bee" + (count == 1 ? ".single" : ""),
|
||||
count
|
||||
)));
|
||||
});
|
||||
|
||||
ScryingLensOverlayRegistry.addPredicateDisplayer(
|
||||
(state, pos, observer, world, direction) -> state.isSignalSource() && !state.is(
|
||||
Blocks.COMPARATOR),
|
||||
(lines, state, pos, observer, world, direction) -> {
|
||||
int signalStrength = 0;
|
||||
if (state.getBlock() instanceof RedStoneWireBlock) {
|
||||
signalStrength = state.getValue(RedStoneWireBlock.POWER);
|
||||
} else {
|
||||
for (Direction dir : Direction.values()) {
|
||||
signalStrength = Math.max(signalStrength, state.getSignal(world, pos, dir));
|
||||
}
|
||||
}
|
||||
|
||||
lines.add(0, new Pair<>(
|
||||
new ItemStack(Items.REDSTONE),
|
||||
Component.literal(String.valueOf(signalStrength))
|
||||
.withStyle(redstoneColor(signalStrength))));
|
||||
});
|
||||
|
||||
ScryingLensOverlayRegistry.addPredicateDisplayer(
|
||||
(state, pos, observer, world, direction) -> state.hasAnalogOutputSignal(),
|
||||
(lines, state, pos, observer, world, direction) -> {
|
||||
int comparatorValue = ScryingLensOverlayRegistry.getComparatorValue(false);
|
||||
lines.add(
|
||||
new Pair<>(
|
||||
new ItemStack(Items.COMPARATOR),
|
||||
Component.literal(comparatorValue == -1 ? "" : String.valueOf(comparatorValue))
|
||||
.withStyle(redstoneColor(comparatorValue))));
|
||||
});
|
||||
}
|
||||
|
||||
private static UnaryOperator<Style> color(int color) {
|
||||
return (style) -> style.withColor(TextColor.fromRgb(color));
|
||||
}
|
||||
|
||||
private static UnaryOperator<Style> redstoneColor(int power) {
|
||||
return redstoneColor(power, 15);
|
||||
}
|
||||
|
||||
private static UnaryOperator<Style> redstoneColor(int power, int max) {
|
||||
return color(RedStoneWireBlock.getColorForPower(Mth.clamp((power * max) / 15, 0, 15)));
|
||||
}
|
||||
|
||||
private static int instrumentColor(NoteBlockInstrument instrument) {
|
||||
return switch (instrument) {
|
||||
case BASEDRUM -> MaterialColor.STONE.col;
|
||||
case SNARE, XYLOPHONE, PLING -> MaterialColor.SAND.col;
|
||||
case HAT -> MaterialColor.QUARTZ.col;
|
||||
case BASS -> MaterialColor.WOOD.col;
|
||||
case FLUTE -> MaterialColor.CLAY.col;
|
||||
case BELL -> MaterialColor.GOLD.col;
|
||||
case GUITAR -> MaterialColor.WOOL.col;
|
||||
case CHIME -> MaterialColor.ICE.col;
|
||||
case IRON_XYLOPHONE -> MaterialColor.METAL.col;
|
||||
case COW_BELL -> MaterialColor.COLOR_BROWN.col;
|
||||
case DIDGERIDOO -> MaterialColor.COLOR_ORANGE.col;
|
||||
case BIT -> MaterialColor.EMERALD.col;
|
||||
case BANJO -> MaterialColor.COLOR_YELLOW.col;
|
||||
default -> -1;
|
||||
};
|
||||
}
|
||||
|
||||
private static void registerDataHolderOverrides(IotaHolderItem item, Predicate<ItemStack> hasIota,
|
||||
private static void registerSealableDataHolderOverrides(IotaHolderItem item, Predicate<ItemStack> hasIota,
|
||||
Predicate<ItemStack> isSealed) {
|
||||
IClientXplatAbstractions.INSTANCE.registerItemProperty((Item) item, ItemFocus.OVERLAY_PRED,
|
||||
(stack, level, holder, holderID) -> {
|
||||
|
@ -316,116 +189,6 @@ public class RegisterClientStuff {
|
|||
});
|
||||
}
|
||||
|
||||
private static int getPoweredRailStrength(Level level, BlockPos pos, BlockState state) {
|
||||
if (level.hasNeighborSignal(pos))
|
||||
return 9;
|
||||
int positiveValue = findPoweredRailSignal(level, pos, state, true, 0);
|
||||
int negativeValue = findPoweredRailSignal(level, pos, state, false, 0);
|
||||
return Math.max(positiveValue, negativeValue);
|
||||
}
|
||||
|
||||
// Copypasta from PoweredRailBlock.class
|
||||
private static int findPoweredRailSignal(Level level, BlockPos pos, BlockState state, boolean travelPositive,
|
||||
int depth) {
|
||||
if (depth >= 8) {
|
||||
return 0;
|
||||
} else {
|
||||
int x = pos.getX();
|
||||
int y = pos.getY();
|
||||
int z = pos.getZ();
|
||||
boolean descending = true;
|
||||
RailShape shape = state.getValue(PoweredRailBlock.SHAPE);
|
||||
switch (shape) {
|
||||
case NORTH_SOUTH:
|
||||
if (travelPositive) {
|
||||
++z;
|
||||
} else {
|
||||
--z;
|
||||
}
|
||||
break;
|
||||
case EAST_WEST:
|
||||
if (travelPositive) {
|
||||
--x;
|
||||
} else {
|
||||
++x;
|
||||
}
|
||||
break;
|
||||
case ASCENDING_EAST:
|
||||
if (travelPositive) {
|
||||
--x;
|
||||
} else {
|
||||
++x;
|
||||
++y;
|
||||
descending = false;
|
||||
}
|
||||
|
||||
shape = RailShape.EAST_WEST;
|
||||
break;
|
||||
case ASCENDING_WEST:
|
||||
if (travelPositive) {
|
||||
--x;
|
||||
++y;
|
||||
descending = false;
|
||||
} else {
|
||||
++x;
|
||||
}
|
||||
|
||||
shape = RailShape.EAST_WEST;
|
||||
break;
|
||||
case ASCENDING_NORTH:
|
||||
if (travelPositive) {
|
||||
++z;
|
||||
} else {
|
||||
--z;
|
||||
++y;
|
||||
descending = false;
|
||||
}
|
||||
|
||||
shape = RailShape.NORTH_SOUTH;
|
||||
break;
|
||||
case ASCENDING_SOUTH:
|
||||
if (travelPositive) {
|
||||
++z;
|
||||
++y;
|
||||
descending = false;
|
||||
} else {
|
||||
--z;
|
||||
}
|
||||
|
||||
shape = RailShape.NORTH_SOUTH;
|
||||
}
|
||||
|
||||
int power = getPowerFromRail(level, new BlockPos(x, y, z), travelPositive, depth, shape);
|
||||
|
||||
if (power > 0) {
|
||||
return power;
|
||||
} else if (descending) {
|
||||
return getPowerFromRail(level, new BlockPos(x, y - 1, z), travelPositive, depth, shape);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static int getPowerFromRail(Level level, BlockPos pos, boolean travelPositive, int depth, RailShape shape) {
|
||||
BlockState otherState = level.getBlockState(pos);
|
||||
if (!otherState.is(Blocks.POWERED_RAIL)) {
|
||||
return 0;
|
||||
} else {
|
||||
RailShape otherShape = otherState.getValue(PoweredRailBlock.SHAPE);
|
||||
if (shape == RailShape.EAST_WEST && (otherShape == RailShape.NORTH_SOUTH || otherShape == RailShape.ASCENDING_NORTH || otherShape == RailShape.ASCENDING_SOUTH)) {
|
||||
return 0;
|
||||
} else if (shape == RailShape.NORTH_SOUTH && (otherShape == RailShape.EAST_WEST || otherShape == RailShape.ASCENDING_EAST || otherShape == RailShape.ASCENDING_WEST)) {
|
||||
return 0;
|
||||
} else if (otherState.getValue(PoweredRailBlock.POWERED)) {
|
||||
return level.hasNeighborSignal(pos) ? 8 - depth : findPoweredRailSignal(level, pos, otherState,
|
||||
travelPositive, depth + 1);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void registerScrollOverrides(ItemScroll scroll) {
|
||||
IClientXplatAbstractions.INSTANCE.registerItemProperty(scroll, ItemScroll.ANCIENT_PREDICATE,
|
||||
(stack, level, holder, holderID) -> NBTHelper.hasString(stack, ItemScroll.TAG_OP_ID) ? 1f : 0f);
|
||||
|
@ -447,6 +210,8 @@ public class RegisterClientStuff {
|
|||
var name = stack.getHoverName().getString().toLowerCase(Locale.ROOT);
|
||||
if (name.contains("old")) {
|
||||
return 1f;
|
||||
} else if (name.contains("cherry")) {
|
||||
return 2f;
|
||||
} else {
|
||||
return 0f;
|
||||
}
|
||||
|
@ -457,6 +222,8 @@ public class RegisterClientStuff {
|
|||
registerer.registerBlockEntityRenderer(HexBlockEntities.SLATE_TILE, BlockEntitySlateRenderer::new);
|
||||
registerer.registerBlockEntityRenderer(HexBlockEntities.AKASHIC_BOOKSHELF_TILE,
|
||||
BlockEntityAkashicBookshelfRenderer::new);
|
||||
registerer.registerBlockEntityRenderer(HexBlockEntities.QUENCHED_ALLAY_TILE,
|
||||
BlockEntityQuenchedAllayRenderer::new);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
|
@ -464,4 +231,18 @@ public class RegisterClientStuff {
|
|||
<T extends BlockEntity> void registerBlockEntityRenderer(BlockEntityType<T> type,
|
||||
BlockEntityRendererProvider<? super T> berp);
|
||||
}
|
||||
|
||||
public static void onModelRegister(ResourceManager recMan, Consumer<ResourceLocation> extraModels) {
|
||||
for (int i = 0; i < BlockQuenchedAllay.VARIANTS; i++) {
|
||||
extraModels.accept(modLoc("block/quenched_allay_" + i));
|
||||
}
|
||||
}
|
||||
|
||||
public static void onModelBake(ModelBakery loader, Map<ResourceLocation, BakedModel> map) {
|
||||
for (int i = 0; i < BlockQuenchedAllay.VARIANTS; i++) {
|
||||
var variantLoc = modLoc("block/quenched_allay_" + i);
|
||||
var model = map.get(variantLoc);
|
||||
QUENCHED_ALLAY_VARIANTS.add(model);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package at.petrak.hexcasting.client.entity;
|
||||
|
||||
import at.petrak.hexcasting.client.RenderLib;
|
||||
import at.petrak.hexcasting.client.render.RenderLib;
|
||||
import at.petrak.hexcasting.common.entities.EntityWallScroll;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
|
|
|
@ -12,8 +12,10 @@ import at.petrak.hexcasting.api.misc.DiscoveryHandlers
|
|||
import at.petrak.hexcasting.api.mod.HexConfig
|
||||
import at.petrak.hexcasting.api.mod.HexTags
|
||||
import at.petrak.hexcasting.api.utils.asTranslatedComponent
|
||||
import at.petrak.hexcasting.client.*
|
||||
import at.petrak.hexcasting.client.ClientTickCounter
|
||||
import at.petrak.hexcasting.client.ShiftScrollListener
|
||||
import at.petrak.hexcasting.client.ktxt.accumulatedScroll
|
||||
import at.petrak.hexcasting.client.render.*
|
||||
import at.petrak.hexcasting.client.sound.GridSoundInstance
|
||||
import at.petrak.hexcasting.common.lib.HexSounds
|
||||
import at.petrak.hexcasting.common.network.MsgNewSpellPatternSyn
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package at.petrak.hexcasting.client.gui;
|
||||
|
||||
import at.petrak.hexcasting.api.casting.math.HexPattern;
|
||||
import at.petrak.hexcasting.client.RenderLib;
|
||||
import at.petrak.hexcasting.client.render.RenderLib;
|
||||
import at.petrak.hexcasting.common.misc.PatternTooltip;
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
|
|
|
@ -24,47 +24,43 @@ public class ConjureParticle extends TextureSheetParticle {
|
|||
private static final Random RANDOM = new Random();
|
||||
|
||||
private final SpriteSet sprites;
|
||||
private final boolean light;
|
||||
|
||||
ConjureParticle(ClientLevel pLevel, double x, double y, double z, double dx, double dy, double dz,
|
||||
SpriteSet pSprites, int color, boolean light) {
|
||||
SpriteSet pSprites, int color) {
|
||||
super(pLevel, x, y, z, dx, dy, dz);
|
||||
this.light = light;
|
||||
this.quadSize *= light ? 0.9f : 0.75f;
|
||||
this.quadSize *= 0.9f;
|
||||
this.setParticleSpeed(dx, dy, dz);
|
||||
|
||||
var r = FastColor.ARGB32.red(color);
|
||||
var g = FastColor.ARGB32.green(color);
|
||||
var b = FastColor.ARGB32.blue(color);
|
||||
this.setColor(r / 255f, g / 255f, b / 255f);
|
||||
this.setAlpha(light ? 0.3f : 1.0f);
|
||||
this.setAlpha(0.3f);
|
||||
|
||||
this.friction = 0.96F;
|
||||
this.gravity = light && dy != 0 && dx != 0 && dz != 0 ? -0.01F : 0F;
|
||||
this.gravity = dy != 0 && dx != 0 && dz != 0 ? -0.01F : 0F;
|
||||
this.speedUpWhenYMotionIsBlocked = true;
|
||||
this.sprites = pSprites;
|
||||
|
||||
this.roll = RANDOM.nextFloat(360);
|
||||
this.oRoll = this.roll;
|
||||
|
||||
this.lifetime = (int) ((light ? 64.0D : 32.0D) / ((Math.random() + 3f) * 0.25f));
|
||||
this.lifetime = (int) (64.0 / ((Math.random() + 3f) * 0.25f));
|
||||
this.hasPhysics = false;
|
||||
this.setSpriteFromAge(pSprites);
|
||||
}
|
||||
|
||||
public @NotNull ParticleRenderType getRenderType() {
|
||||
return this.light ? LIGHT_RENDER_TYPE : CONJURE_RENDER_TYPE;
|
||||
return CONJURE_RENDER_TYPE;
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
super.tick();
|
||||
this.setSpriteFromAge(this.sprites);
|
||||
this.alpha = 1.0f - ((float) this.age / (float) this.lifetime);
|
||||
if (light) {
|
||||
this.alpha *= 0.3f;
|
||||
this.quadSize *= 0.96f;
|
||||
}
|
||||
}
|
||||
|
||||
public void setSpriteFromAge(@NotNull SpriteSet pSprite) {
|
||||
if (!this.removed) {
|
||||
|
@ -88,13 +84,12 @@ public class ConjureParticle extends TextureSheetParticle {
|
|||
public Particle createParticle(ConjureParticleOptions type, ClientLevel level,
|
||||
double pX, double pY, double pZ,
|
||||
double pXSpeed, double pYSpeed, double pZSpeed) {
|
||||
return new ConjureParticle(level, pX, pY, pZ, pXSpeed, pYSpeed, pZSpeed, this.sprite, type.color(),
|
||||
type.isLight());
|
||||
return new ConjureParticle(level, pX, pY, pZ, pXSpeed, pYSpeed, pZSpeed, this.sprite, type.color());
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/VazkiiMods/Botania/blob/db85d778ab23f44c11181209319066d1f04a9e3d/Xplat/src/main/java/vazkii/botania/client/fx/FXWisp.java
|
||||
private record ConjureRenderType(boolean light) implements ParticleRenderType {
|
||||
private record ConjureRenderType() implements ParticleRenderType {
|
||||
@Override
|
||||
public void begin(BufferBuilder buf, TextureManager texMan) {
|
||||
Minecraft.getInstance().gameRenderer.lightTexture().turnOnLightLayer();
|
||||
|
@ -104,7 +99,7 @@ public class ConjureParticle extends TextureSheetParticle {
|
|||
|
||||
RenderSystem.setShaderTexture(0, TextureAtlas.LOCATION_PARTICLES);
|
||||
var tex = texMan.getTexture(TextureAtlas.LOCATION_PARTICLES);
|
||||
IClientXplatAbstractions.INSTANCE.setFilterSave(tex, this.light, false);
|
||||
IClientXplatAbstractions.INSTANCE.setFilterSave(tex, true, false);
|
||||
buf.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.PARTICLE);
|
||||
RenderSystem.enableDepthTest();
|
||||
}
|
||||
|
@ -121,10 +116,9 @@ public class ConjureParticle extends TextureSheetParticle {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return HexAPI.MOD_ID + (light ? ":light" : ":conjure");
|
||||
return HexAPI.MOD_ID + ":conjure";
|
||||
}
|
||||
}
|
||||
|
||||
public static final ConjureRenderType CONJURE_RENDER_TYPE = new ConjureRenderType(false);
|
||||
public static final ConjureRenderType LIGHT_RENDER_TYPE = new ConjureRenderType(true);
|
||||
public static final ConjureRenderType CONJURE_RENDER_TYPE = new ConjureRenderType();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
package at.petrak.hexcasting.client.render;
|
||||
|
||||
import at.petrak.hexcasting.xplat.IXplatAbstractions;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import net.minecraft.client.model.ElytraModel;
|
||||
import net.minecraft.client.model.EntityModel;
|
||||
import net.minecraft.client.model.geom.EntityModelSet;
|
||||
import net.minecraft.client.player.AbstractClientPlayer;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.entity.ItemRenderer;
|
||||
import net.minecraft.client.renderer.entity.RenderLayerParent;
|
||||
import net.minecraft.client.renderer.entity.layers.RenderLayer;
|
||||
import net.minecraft.client.renderer.texture.OverlayTexture;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
import net.minecraft.world.item.Items;
|
||||
|
||||
import static at.petrak.hexcasting.api.HexAPI.modLoc;
|
||||
|
||||
public class AltioraLayer<M extends EntityModel<AbstractClientPlayer>> extends RenderLayer<AbstractClientPlayer, M> {
|
||||
private static final ResourceLocation TEX_LOC = modLoc("textures/misc/altiora.png");
|
||||
|
||||
private final ElytraModel<AbstractClientPlayer> elytraModel;
|
||||
|
||||
public AltioraLayer(RenderLayerParent<AbstractClientPlayer, M> renderer, EntityModelSet ems) {
|
||||
super(renderer);
|
||||
this.elytraModel = new ElytraModel<>(ems.bakeLayer(HexModelLayers.ALTIORA));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(PoseStack ps, MultiBufferSource buffer, int packedLight, AbstractClientPlayer player,
|
||||
float limbSwing, float limbSwingAmount, float partialTick, float ageInTicks, float netHeadYaw,
|
||||
float headPitch) {
|
||||
var altiora = IXplatAbstractions.INSTANCE.getAltiora(player);
|
||||
// do a best effort to not render over other elytra, although we can never patch up everything
|
||||
var chestSlot = player.getItemBySlot(EquipmentSlot.CHEST);
|
||||
if (altiora != null && !chestSlot.is(Items.ELYTRA)) {
|
||||
ps.pushPose();
|
||||
ps.translate(0.0, 0.0, 0.125);
|
||||
|
||||
this.getParentModel().copyPropertiesTo(this.elytraModel);
|
||||
this.elytraModel.setupAnim(player, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch);
|
||||
VertexConsumer verts = ItemRenderer.getArmorFoilBuffer(
|
||||
buffer, RenderType.armorCutoutNoCull(TEX_LOC), false, true);
|
||||
this.elytraModel.renderToBuffer(ps, verts, packedLight, OverlayTexture.NO_OVERLAY, 1.0F, 1.0F, 1.0F, 1.0F);
|
||||
|
||||
ps.popPose();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package at.petrak.hexcasting.client.render;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
import static at.petrak.hexcasting.api.HexAPI.modLoc;
|
||||
|
||||
// *nothing* that changes can be looked at for changes
|
||||
public class GaslightingTracker {
|
||||
private static int GASLIGHTING_AMOUNT = 0;
|
||||
private static int LOOKING_COOLDOWN_MAX = 40;
|
||||
private static int LOOKING_COOLDOWN = LOOKING_COOLDOWN_MAX;
|
||||
|
||||
public static ResourceLocation GASLIGHTING_PRED = modLoc("variant");
|
||||
|
||||
public static int getGaslightingAmount() {
|
||||
LOOKING_COOLDOWN = LOOKING_COOLDOWN_MAX;
|
||||
return GASLIGHTING_AMOUNT;
|
||||
}
|
||||
|
||||
public static void postFrameCheckRendered() {
|
||||
if (LOOKING_COOLDOWN > 0) {
|
||||
LOOKING_COOLDOWN -= 1;
|
||||
} else {
|
||||
GASLIGHTING_AMOUNT += 1;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,8 +1,9 @@
|
|||
package at.petrak.hexcasting.client;
|
||||
package at.petrak.hexcasting.client.render;
|
||||
|
||||
import at.petrak.hexcasting.api.client.ScryingLensOverlayRegistry;
|
||||
import at.petrak.hexcasting.api.misc.DiscoveryHandlers;
|
||||
import at.petrak.hexcasting.api.player.Sentinel;
|
||||
import at.petrak.hexcasting.client.ClientTickCounter;
|
||||
import at.petrak.hexcasting.xplat.IXplatAbstractions;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
|
@ -0,0 +1,30 @@
|
|||
package at.petrak.hexcasting.client.render;
|
||||
|
||||
import net.minecraft.client.model.ElytraModel;
|
||||
import net.minecraft.client.model.geom.ModelLayerLocation;
|
||||
import net.minecraft.client.model.geom.builders.LayerDefinition;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static at.petrak.hexcasting.api.HexAPI.modLoc;
|
||||
|
||||
// https://github.com/VazkiiMods/Botania/blob/1.19.x/Xplat/src/main/java/vazkii/botania/client/model/BotaniaModelLayers.java
|
||||
public class HexModelLayers {
|
||||
public static final ModelLayerLocation ALTIORA = make("altiora");
|
||||
|
||||
private static ModelLayerLocation make(String name) {
|
||||
return make(name, "main");
|
||||
}
|
||||
|
||||
private static ModelLayerLocation make(String name, String layer) {
|
||||
// Don't add to vanilla's ModelLayers. It seems to only be used for error checking
|
||||
// And would be annoying to do under Forge's parallel mod loading
|
||||
return new ModelLayerLocation(modLoc(name), layer);
|
||||
}
|
||||
|
||||
// combine with https://github.com/VazkiiMods/Botania/blob/1.19.x/Xplat/src/main/java/vazkii/botania/client/model/BotaniaLayerDefinitions.java
|
||||
public static void init(BiConsumer<ModelLayerLocation, Supplier<LayerDefinition>> consumer) {
|
||||
consumer.accept(ALTIORA, ElytraModel::createLayer);
|
||||
}
|
||||
}
|
|
@ -1,10 +1,11 @@
|
|||
@file:JvmName("RenderLib")
|
||||
|
||||
package at.petrak.hexcasting.client
|
||||
package at.petrak.hexcasting.client.render
|
||||
|
||||
import at.petrak.hexcasting.api.casting.math.HexPattern
|
||||
import at.petrak.hexcasting.api.mod.HexConfig
|
||||
import at.petrak.hexcasting.api.utils.TAU
|
||||
import at.petrak.hexcasting.client.ClientTickCounter
|
||||
import com.mojang.blaze3d.systems.RenderSystem
|
||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat
|
||||
import com.mojang.blaze3d.vertex.PoseStack
|
|
@ -0,0 +1,288 @@
|
|||
package at.petrak.hexcasting.client.render;
|
||||
|
||||
import at.petrak.hexcasting.api.block.circle.BlockAbstractImpetus;
|
||||
import at.petrak.hexcasting.api.block.circle.BlockEntityAbstractImpetus;
|
||||
import at.petrak.hexcasting.api.client.ScryingLensOverlayRegistry;
|
||||
import at.petrak.hexcasting.common.blocks.akashic.BlockEntityAkashicBookshelf;
|
||||
import at.petrak.hexcasting.common.lib.HexBlocks;
|
||||
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.Style;
|
||||
import net.minecraft.network.chat.TextColor;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.*;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.properties.ComparatorMode;
|
||||
import net.minecraft.world.level.block.state.properties.NoteBlockInstrument;
|
||||
import net.minecraft.world.level.block.state.properties.RailShape;
|
||||
import net.minecraft.world.level.material.MaterialColor;
|
||||
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
public class ScryingLensOverlays {
|
||||
public static void addScryingLensStuff() {
|
||||
ScryingLensOverlayRegistry.addPredicateDisplayer(
|
||||
(state, pos, observer, world, direction) -> state.getBlock() instanceof BlockAbstractImpetus,
|
||||
(lines, state, pos, observer, world, direction) -> {
|
||||
if (world.getBlockEntity(pos) instanceof BlockEntityAbstractImpetus beai) {
|
||||
beai.applyScryingLensOverlay(lines, state, pos, observer, world, direction);
|
||||
}
|
||||
});
|
||||
|
||||
ScryingLensOverlayRegistry.addDisplayer(Blocks.NOTE_BLOCK,
|
||||
(lines, state, pos, observer, world, direction) -> {
|
||||
int note = state.getValue(NoteBlock.NOTE);
|
||||
|
||||
float rCol = Math.max(0.0F, Mth.sin((note / 24F + 0.0F) * Mth.TWO_PI) * 0.65F + 0.35F);
|
||||
float gCol = Math.max(0.0F, Mth.sin((note / 24F + 0.33333334F) * Mth.TWO_PI) * 0.65F + 0.35F);
|
||||
float bCol = Math.max(0.0F, Mth.sin((note / 24F + 0.6666667F) * Mth.TWO_PI) * 0.65F + 0.35F);
|
||||
|
||||
int noteColor = 0xFF_000000 | Mth.color(rCol, gCol, bCol);
|
||||
|
||||
var instrument = state.getValue(NoteBlock.INSTRUMENT);
|
||||
|
||||
lines.add(new Pair<>(
|
||||
new ItemStack(Items.MUSIC_DISC_CHIRP),
|
||||
Component.literal(String.valueOf(instrument.ordinal()))
|
||||
.withStyle(color(instrumentColor(instrument)))));
|
||||
lines.add(new Pair<>(
|
||||
new ItemStack(Items.NOTE_BLOCK),
|
||||
Component.literal(String.valueOf(note))
|
||||
.withStyle(color(noteColor))));
|
||||
});
|
||||
|
||||
ScryingLensOverlayRegistry.addDisplayer(HexBlocks.AKASHIC_BOOKSHELF,
|
||||
(lines, state, pos, observer, world, direction) -> {
|
||||
if (world.getBlockEntity(pos) instanceof BlockEntityAkashicBookshelf tile) {
|
||||
var iotaTag = tile.getIotaTag();
|
||||
if (iotaTag != null) {
|
||||
var display = HexIotaTypes.getDisplay(iotaTag);
|
||||
lines.add(new Pair<>(new ItemStack(Items.BOOK), display));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ScryingLensOverlayRegistry.addDisplayer(Blocks.COMPARATOR,
|
||||
(lines, state, pos, observer, world, direction) -> {
|
||||
int comparatorValue = ScryingLensOverlayRegistry.getComparatorValue(true);
|
||||
lines.add(new Pair<>(
|
||||
new ItemStack(Items.REDSTONE),
|
||||
Component.literal(comparatorValue == -1 ? "" : String.valueOf(comparatorValue))
|
||||
.withStyle(redstoneColor(comparatorValue))));
|
||||
|
||||
boolean compare = state.getValue(ComparatorBlock.MODE) == ComparatorMode.COMPARE;
|
||||
|
||||
lines.add(new Pair<>(
|
||||
new ItemStack(Items.REDSTONE_TORCH),
|
||||
Component.literal(compare ? ">=" : "-")
|
||||
.withStyle(redstoneColor(compare ? 0 : 15))));
|
||||
});
|
||||
|
||||
ScryingLensOverlayRegistry.addDisplayer(Blocks.POWERED_RAIL,
|
||||
(lines, state, pos, observer, world, direction) -> {
|
||||
int power = getPoweredRailStrength(world, pos, state);
|
||||
lines.add(new Pair<>(
|
||||
new ItemStack(Items.POWERED_RAIL),
|
||||
Component.literal(String.valueOf(power))
|
||||
.withStyle(redstoneColor(power, 9))));
|
||||
});
|
||||
|
||||
ScryingLensOverlayRegistry.addDisplayer(Blocks.REPEATER,
|
||||
(lines, state, pos, observer, world, direction) -> lines.add(new Pair<>(
|
||||
new ItemStack(Items.CLOCK),
|
||||
Component.literal(String.valueOf(state.getValue(RepeaterBlock.DELAY)))
|
||||
.withStyle(ChatFormatting.YELLOW))));
|
||||
|
||||
ScryingLensOverlayRegistry.addPredicateDisplayer(
|
||||
(state, pos, observer, world, direction) -> state.getBlock() instanceof BeehiveBlock,
|
||||
(lines, state, pos, observer, world, direction) -> {
|
||||
int count = ScryingLensOverlayRegistry.getBeeValue();
|
||||
lines.add(new Pair<>(new ItemStack(Items.BEE_NEST), count == -1 ? Component.empty() :
|
||||
Component.translatable(
|
||||
"hexcasting.tooltip.lens.bee" + (count == 1 ? ".single" : ""),
|
||||
count
|
||||
)));
|
||||
});
|
||||
|
||||
ScryingLensOverlayRegistry.addPredicateDisplayer(
|
||||
(state, pos, observer, world, direction) -> state.isSignalSource() && !state.is(
|
||||
Blocks.COMPARATOR),
|
||||
(lines, state, pos, observer, world, direction) -> {
|
||||
int signalStrength = 0;
|
||||
if (state.getBlock() instanceof RedStoneWireBlock) {
|
||||
signalStrength = state.getValue(RedStoneWireBlock.POWER);
|
||||
} else {
|
||||
for (Direction dir : Direction.values()) {
|
||||
signalStrength = Math.max(signalStrength, state.getSignal(world, pos, dir));
|
||||
}
|
||||
}
|
||||
|
||||
lines.add(0, new Pair<>(
|
||||
new ItemStack(Items.REDSTONE),
|
||||
Component.literal(String.valueOf(signalStrength))
|
||||
.withStyle(redstoneColor(signalStrength))));
|
||||
});
|
||||
|
||||
ScryingLensOverlayRegistry.addPredicateDisplayer(
|
||||
(state, pos, observer, world, direction) -> state.hasAnalogOutputSignal(),
|
||||
(lines, state, pos, observer, world, direction) -> {
|
||||
int comparatorValue = ScryingLensOverlayRegistry.getComparatorValue(false);
|
||||
lines.add(
|
||||
new Pair<>(
|
||||
new ItemStack(Items.COMPARATOR),
|
||||
Component.literal(comparatorValue == -1 ? "" : String.valueOf(comparatorValue))
|
||||
.withStyle(redstoneColor(comparatorValue))));
|
||||
});
|
||||
}
|
||||
|
||||
private static int getPoweredRailStrength(Level level, BlockPos pos, BlockState state) {
|
||||
if (level.hasNeighborSignal(pos))
|
||||
return 9;
|
||||
int positiveValue = findPoweredRailSignal(level, pos, state, true, 0);
|
||||
int negativeValue = findPoweredRailSignal(level, pos, state, false, 0);
|
||||
return Math.max(positiveValue, negativeValue);
|
||||
}
|
||||
|
||||
// Copypasta from PoweredRailBlock.class
|
||||
private static int findPoweredRailSignal(Level level, BlockPos pos, BlockState state, boolean travelPositive,
|
||||
int depth) {
|
||||
if (depth >= 8) {
|
||||
return 0;
|
||||
} else {
|
||||
int x = pos.getX();
|
||||
int y = pos.getY();
|
||||
int z = pos.getZ();
|
||||
boolean descending = true;
|
||||
RailShape shape = state.getValue(PoweredRailBlock.SHAPE);
|
||||
switch (shape) {
|
||||
case NORTH_SOUTH:
|
||||
if (travelPositive) {
|
||||
++z;
|
||||
} else {
|
||||
--z;
|
||||
}
|
||||
break;
|
||||
case EAST_WEST:
|
||||
if (travelPositive) {
|
||||
--x;
|
||||
} else {
|
||||
++x;
|
||||
}
|
||||
break;
|
||||
case ASCENDING_EAST:
|
||||
if (travelPositive) {
|
||||
--x;
|
||||
} else {
|
||||
++x;
|
||||
++y;
|
||||
descending = false;
|
||||
}
|
||||
|
||||
shape = RailShape.EAST_WEST;
|
||||
break;
|
||||
case ASCENDING_WEST:
|
||||
if (travelPositive) {
|
||||
--x;
|
||||
++y;
|
||||
descending = false;
|
||||
} else {
|
||||
++x;
|
||||
}
|
||||
|
||||
shape = RailShape.EAST_WEST;
|
||||
break;
|
||||
case ASCENDING_NORTH:
|
||||
if (travelPositive) {
|
||||
++z;
|
||||
} else {
|
||||
--z;
|
||||
++y;
|
||||
descending = false;
|
||||
}
|
||||
|
||||
shape = RailShape.NORTH_SOUTH;
|
||||
break;
|
||||
case ASCENDING_SOUTH:
|
||||
if (travelPositive) {
|
||||
++z;
|
||||
++y;
|
||||
descending = false;
|
||||
} else {
|
||||
--z;
|
||||
}
|
||||
|
||||
shape = RailShape.NORTH_SOUTH;
|
||||
}
|
||||
|
||||
int power = getPowerFromRail(level, new BlockPos(x, y, z), travelPositive, depth,
|
||||
shape);
|
||||
|
||||
if (power > 0) {
|
||||
return power;
|
||||
} else if (descending) {
|
||||
return getPowerFromRail(level, new BlockPos(x, y - 1, z), travelPositive, depth,
|
||||
shape);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static UnaryOperator<Style> color(int color) {
|
||||
return (style) -> style.withColor(TextColor.fromRgb(color));
|
||||
}
|
||||
|
||||
private static UnaryOperator<Style> redstoneColor(int power) {
|
||||
return redstoneColor(power, 15);
|
||||
}
|
||||
|
||||
private static UnaryOperator<Style> redstoneColor(int power, int max) {
|
||||
return color(RedStoneWireBlock.getColorForPower(Mth.clamp((power * max) / 15, 0, 15)));
|
||||
}
|
||||
|
||||
private static int instrumentColor(NoteBlockInstrument instrument) {
|
||||
return switch (instrument) {
|
||||
case BASEDRUM -> MaterialColor.STONE.col;
|
||||
case SNARE, XYLOPHONE, PLING -> MaterialColor.SAND.col;
|
||||
case HAT -> MaterialColor.QUARTZ.col;
|
||||
case BASS -> MaterialColor.WOOD.col;
|
||||
case FLUTE -> MaterialColor.CLAY.col;
|
||||
case BELL -> MaterialColor.GOLD.col;
|
||||
case GUITAR -> MaterialColor.WOOL.col;
|
||||
case CHIME -> MaterialColor.ICE.col;
|
||||
case IRON_XYLOPHONE -> MaterialColor.METAL.col;
|
||||
case COW_BELL -> MaterialColor.COLOR_BROWN.col;
|
||||
case DIDGERIDOO -> MaterialColor.COLOR_ORANGE.col;
|
||||
case BIT -> MaterialColor.EMERALD.col;
|
||||
case BANJO -> MaterialColor.COLOR_YELLOW.col;
|
||||
default -> -1;
|
||||
};
|
||||
}
|
||||
|
||||
private static int getPowerFromRail(Level level, BlockPos pos, boolean travelPositive, int depth, RailShape shape) {
|
||||
BlockState otherState = level.getBlockState(pos);
|
||||
if (!otherState.is(Blocks.POWERED_RAIL)) {
|
||||
return 0;
|
||||
} else {
|
||||
RailShape otherShape = otherState.getValue(PoweredRailBlock.SHAPE);
|
||||
if (shape == RailShape.EAST_WEST && (otherShape == RailShape.NORTH_SOUTH || otherShape == RailShape.ASCENDING_NORTH || otherShape == RailShape.ASCENDING_SOUTH)) {
|
||||
return 0;
|
||||
} else if (shape == RailShape.NORTH_SOUTH && (otherShape == RailShape.EAST_WEST || otherShape == RailShape.ASCENDING_EAST || otherShape == RailShape.ASCENDING_WEST)) {
|
||||
return 0;
|
||||
} else if (otherState.getValue(PoweredRailBlock.POWERED)) {
|
||||
return level.hasNeighborSignal(pos) ? 8 - depth : findPoweredRailSignal(level, pos, otherState,
|
||||
travelPositive, depth + 1);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
package at.petrak.hexcasting.client.be;
|
||||
package at.petrak.hexcasting.client.render.be;
|
||||
|
||||
import at.petrak.hexcasting.api.casting.math.HexPattern;
|
||||
import at.petrak.hexcasting.client.RenderLib;
|
||||
import at.petrak.hexcasting.client.render.RenderLib;
|
||||
import at.petrak.hexcasting.common.blocks.akashic.BlockAkashicBookshelf;
|
||||
import at.petrak.hexcasting.common.blocks.akashic.BlockEntityAkashicBookshelf;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
|
@ -0,0 +1,54 @@
|
|||
package at.petrak.hexcasting.client.render.be;
|
||||
|
||||
import at.petrak.hexcasting.client.RegisterClientStuff;
|
||||
import at.petrak.hexcasting.client.render.GaslightingTracker;
|
||||
import at.petrak.hexcasting.common.blocks.BlockQuenchedAllay;
|
||||
import at.petrak.hexcasting.common.blocks.entity.BlockEntityQuenchedAllay;
|
||||
import at.petrak.hexcasting.xplat.IClientXplatAbstractions;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.block.BlockRenderDispatcher;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
|
||||
// TODO: this doesn't cover the block being *behind* something. Is it possible to cleanly do that?
|
||||
// it would probably require some depth-texture bullshit that I don't want to worry about
|
||||
public class BlockEntityQuenchedAllayRenderer implements BlockEntityRenderer<BlockEntityQuenchedAllay> {
|
||||
private final BlockEntityRendererProvider.Context ctx;
|
||||
|
||||
public BlockEntityQuenchedAllayRenderer(BlockEntityRendererProvider.Context ctx) {
|
||||
this.ctx = ctx;
|
||||
}
|
||||
|
||||
private static void doRender(BlockRenderDispatcher dispatcher, PoseStack ps, MultiBufferSource bufSource,
|
||||
int packedLight, int packedOverlay) {
|
||||
var buffer = bufSource.getBuffer(RenderType.translucent());
|
||||
var pose = ps.last();
|
||||
|
||||
var idx = Math.abs(GaslightingTracker.getGaslightingAmount() % BlockQuenchedAllay.VARIANTS);
|
||||
var model = RegisterClientStuff.QUENCHED_ALLAY_VARIANTS.get(idx);
|
||||
|
||||
dispatcher.getModelRenderer().renderModel(pose, buffer, null, model, 1f, 1f, 1f, packedLight, packedOverlay);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(BlockEntityQuenchedAllay blockEntity, float partialTick, PoseStack poseStack,
|
||||
MultiBufferSource bufferSource, int packedLight, int packedOverlay) {
|
||||
// https://github.com/MinecraftForge/MinecraftForge/blob/79dfdb0ace9694f9dd0f1d9e8c5c24a0ae2d77f8/patches/minecraft/net/minecraft/client/renderer/LevelRenderer.java.patch#L68
|
||||
// Forge fixes BEs rendering offscreen; Fabric doesn't!
|
||||
// So we do a special check on Fabric only
|
||||
var pos = blockEntity.getBlockPos();
|
||||
var aabb = new AABB(pos.offset(-1, 0, -1), pos.offset(1, 1, 1));
|
||||
if (IClientXplatAbstractions.INSTANCE.fabricAdditionalQuenchFrustumCheck(aabb)) {
|
||||
doRender(this.ctx.getBlockRenderDispatcher(), poseStack, bufferSource, packedLight, packedOverlay);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRenderOffScreen(BlockEntityQuenchedAllay blockEntity) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
package at.petrak.hexcasting.client.be;
|
||||
package at.petrak.hexcasting.client.render.be;
|
||||
|
||||
import at.petrak.hexcasting.client.RenderLib;
|
||||
import at.petrak.hexcasting.client.render.RenderLib;
|
||||
import at.petrak.hexcasting.common.blocks.circles.BlockEntitySlate;
|
||||
import at.petrak.hexcasting.common.blocks.circles.BlockSlate;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
|
@ -1,4 +1,4 @@
|
|||
package at.petrak.hexcasting.client.shader;
|
||||
package at.petrak.hexcasting.client.render.shader;
|
||||
|
||||
import at.petrak.hexcasting.mixin.accessor.client.AccessorCompositeRenderType;
|
||||
import at.petrak.hexcasting.mixin.accessor.client.AccessorEmptyTextureStateShard;
|
||||
|
@ -13,7 +13,8 @@ import org.jetbrains.annotations.NotNull;
|
|||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
|
||||
public record FakeBufferSource(MultiBufferSource parent, Function<ResourceLocation, RenderType> mapper) implements MultiBufferSource {
|
||||
public record FakeBufferSource(MultiBufferSource parent,
|
||||
Function<ResourceLocation, RenderType> mapper) implements MultiBufferSource {
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("ConstantConditions")
|
|
@ -1,4 +1,4 @@
|
|||
package at.petrak.hexcasting.client.shader;
|
||||
package at.petrak.hexcasting.client.render.shader;
|
||||
|
||||
import at.petrak.hexcasting.api.HexAPI;
|
||||
import at.petrak.hexcasting.mixin.accessor.client.AccessorRenderType;
|
||||
|
@ -13,7 +13,8 @@ import java.util.function.Function;
|
|||
// https://github.com/VazkiiMods/Botania/blob/3a43accc2fbc439c9f2f00a698f8f8ad017503db/Common/src/main/java/vazkii/botania/client/core/helper/RenderHelper.java
|
||||
public final class HexRenderTypes extends RenderType {
|
||||
|
||||
private HexRenderTypes(String string, VertexFormat vertexFormat, VertexFormat.Mode mode, int i, boolean bl, boolean bl2, Runnable runnable, Runnable runnable2) {
|
||||
private HexRenderTypes(String string, VertexFormat vertexFormat, VertexFormat.Mode mode, int i, boolean bl,
|
||||
boolean bl2, Runnable runnable, Runnable runnable2) {
|
||||
super(string, vertexFormat, mode, i, bl, bl2, runnable, runnable2);
|
||||
throw new UnsupportedOperationException("Should not be instantiated");
|
||||
}
|
||||
|
@ -33,7 +34,8 @@ public final class HexRenderTypes extends RenderType {
|
|||
.setOverlayState(OVERLAY)
|
||||
.createCompositeState(true);
|
||||
|
||||
return makeLayer(HexAPI.MOD_ID + ":grayscale", DefaultVertexFormat.NEW_ENTITY, VertexFormat.Mode.QUADS, 256, true, false, glState);
|
||||
return makeLayer(HexAPI.MOD_ID + ":grayscale", DefaultVertexFormat.NEW_ENTITY, VertexFormat.Mode.QUADS, 256,
|
||||
true, false, glState);
|
||||
});
|
||||
|
||||
public static RenderType getGrayscaleLayer(ResourceLocation texture) {
|
|
@ -1,4 +1,4 @@
|
|||
package at.petrak.hexcasting.client.shader;
|
||||
package at.petrak.hexcasting.client.render.shader;
|
||||
|
||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
|
@ -11,6 +11,7 @@ import java.util.function.Consumer;
|
|||
// https://github.com/VazkiiMods/Botania/blob/3a43accc2fbc439c9f2f00a698f8f8ad017503db/Common/src/main/java/vazkii/botania/client/core/helper/CoreShaders.java
|
||||
public class HexShaders {
|
||||
private static ShaderInstance grayscale;
|
||||
|
||||
public static void init(ResourceManager resourceManager,
|
||||
Consumer<Pair<ShaderInstance, Consumer<ShaderInstance>>> registrations) throws IOException {
|
||||
registrations.accept(Pair.of(
|
|
@ -0,0 +1,59 @@
|
|||
package at.petrak.hexcasting.common.blocks;
|
||||
|
||||
import at.petrak.hexcasting.common.blocks.entity.BlockEntityQuenchedAllay;
|
||||
import at.petrak.hexcasting.common.particles.ConjureParticleOptions;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.particles.ParticleOptions;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.EntityBlock;
|
||||
import net.minecraft.world.level.block.RenderShape;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class BlockQuenchedAllay extends Block implements EntityBlock {
|
||||
public static final int VARIANTS = 4;
|
||||
|
||||
public BlockQuenchedAllay(Properties properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
|
||||
return new BlockEntityQuenchedAllay(pos, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RenderShape getRenderShape(BlockState state) {
|
||||
return RenderShape.INVISIBLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void animateTick(BlockState state, Level level, BlockPos pos, RandomSource rand) {
|
||||
ParticleOptions options = new ConjureParticleOptions(0x8932b8);
|
||||
Vec3 center = Vec3.atCenterOf(pos);
|
||||
for (Direction direction : Direction.values()) {
|
||||
int dX = direction.getStepX();
|
||||
int dY = direction.getStepY();
|
||||
int dZ = direction.getStepZ();
|
||||
|
||||
int count = rand.nextInt(10) / 4;
|
||||
for (int i = 0; i < count; i++) {
|
||||
double pX = center.x + (dX == 0 ? Mth.nextDouble(rand, -0.5D, 0.5D) : (double) dX * 0.55D);
|
||||
double pY = center.y + (dY == 0 ? Mth.nextDouble(rand, -0.5D, 0.5D) : (double) dY * 0.55D);
|
||||
double pZ = center.z + (dZ == 0 ? Mth.nextDouble(rand, -0.5D, 0.5D) : (double) dZ * 0.55D);
|
||||
double vPerp = Mth.nextDouble(rand, 0.0, 0.01);
|
||||
double vX = vPerp * dX;
|
||||
double vY = vPerp * dY;
|
||||
double vZ = vPerp * dZ;
|
||||
level.addParticle(options, pX, pY, pZ, vX, vY, vZ);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@ package at.petrak.hexcasting.common.blocks.akashic;
|
|||
|
||||
import at.petrak.hexcasting.annotations.SoftImplement;
|
||||
import at.petrak.hexcasting.api.casting.iota.PatternIota;
|
||||
import at.petrak.hexcasting.common.items.ItemScroll;
|
||||
import at.petrak.hexcasting.common.items.storage.ItemScroll;
|
||||
import at.petrak.hexcasting.common.lib.HexSounds;
|
||||
import at.petrak.hexcasting.xplat.IForgeLikeBlock;
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
|
|
@ -32,7 +32,7 @@ public class BlockSconce extends AmethystBlock {
|
|||
var cy = pPos.getY() + 0.5;
|
||||
var cz = pPos.getZ() + 0.5;
|
||||
int[] colors = {0xff_6f4fab, 0xff_b38ef3, 0xff_cfa0f3, 0xff_cfa0f3, 0xff_fffdd5};
|
||||
pLevel.addParticle(new ConjureParticleOptions(colors[rand.nextInt(colors.length)], true), cx, cy, cz,
|
||||
pLevel.addParticle(new ConjureParticleOptions(colors[rand.nextInt(colors.length)]), cx, cy, cz,
|
||||
rand.triangle(-0.01f, 0.01f), rand.triangle(0.01f, 0.05f), rand.triangle(-0.01f, 0.01f));
|
||||
if (rand.nextFloat() < 0.08f) {
|
||||
pLevel.playLocalSound(cx, cy, cz,
|
||||
|
|
|
@ -31,7 +31,7 @@ public class BlockEntityConjured extends HexBlockEntity {
|
|||
.add(new Vec3(RANDOM.nextFloat(), RANDOM.nextFloat(), RANDOM.nextFloat()).scale(
|
||||
RANDOM.nextFloat() * 3)));
|
||||
assert level != null;
|
||||
level.addParticle(new ConjureParticleOptions(color, false),
|
||||
level.addParticle(new ConjureParticleOptions(color),
|
||||
pEntity.getX() + (RANDOM.nextFloat() * 0.6D) - 0.3D,
|
||||
getBlockPos().getY() + (RANDOM.nextFloat() * 0.05D) + 0.95D,
|
||||
pEntity.getZ() + (RANDOM.nextFloat() * 0.6D) - 0.3D,
|
||||
|
@ -50,7 +50,7 @@ public class BlockEntityConjured extends HexBlockEntity {
|
|||
assert level != null;
|
||||
if (getBlockState().getBlock() instanceof BlockConjuredLight) {
|
||||
if (RANDOM.nextFloat() < 0.5) {
|
||||
level.addParticle(new ConjureParticleOptions(color, true),
|
||||
level.addParticle(new ConjureParticleOptions(color),
|
||||
(double) getBlockPos().getX() + 0.45D + (RANDOM.nextFloat() * 0.1D),
|
||||
(double) getBlockPos().getY() + 0.45D + (RANDOM.nextFloat() * 0.1D),
|
||||
(double) getBlockPos().getZ() + 0.45D + (RANDOM.nextFloat() * 0.1D),
|
||||
|
@ -60,7 +60,7 @@ public class BlockEntityConjured extends HexBlockEntity {
|
|||
}
|
||||
} else {
|
||||
if (RANDOM.nextFloat() < 0.2) {
|
||||
level.addParticle(new ConjureParticleOptions(color, false),
|
||||
level.addParticle(new ConjureParticleOptions(color),
|
||||
(double) getBlockPos().getX() + RANDOM.nextFloat(),
|
||||
(double) getBlockPos().getY() + RANDOM.nextFloat(),
|
||||
(double) getBlockPos().getZ() + RANDOM.nextFloat(),
|
||||
|
@ -78,7 +78,7 @@ public class BlockEntityConjured extends HexBlockEntity {
|
|||
.add(new Vec3(RANDOM.nextFloat(), RANDOM.nextFloat(), RANDOM.nextFloat()).scale(
|
||||
RANDOM.nextFloat() * 3)));
|
||||
assert level != null;
|
||||
level.addParticle(new ConjureParticleOptions(color, false),
|
||||
level.addParticle(new ConjureParticleOptions(color),
|
||||
entity.getX() + (RANDOM.nextFloat() * 0.8D) - 0.2D,
|
||||
getBlockPos().getY() + (RANDOM.nextFloat() * 0.05D) + 0.95D,
|
||||
entity.getZ() + (RANDOM.nextFloat() * 0.8D) - 0.2D,
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
package at.petrak.hexcasting.common.blocks.entity;
|
||||
|
||||
import at.petrak.hexcasting.api.block.HexBlockEntity;
|
||||
import at.petrak.hexcasting.common.lib.HexBlockEntities;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
/**
|
||||
* No-op BE just to have a BER
|
||||
*/
|
||||
public class BlockEntityQuenchedAllay extends HexBlockEntity {
|
||||
public BlockEntityQuenchedAllay(BlockPos pos, BlockState blockState) {
|
||||
super(HexBlockEntities.QUENCHED_ALLAY_TILE, pos, blockState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveModData(CompoundTag tag) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadModData(CompoundTag tag) {
|
||||
|
||||
}
|
||||
}
|
|
@ -1,13 +1,13 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.spells
|
||||
|
||||
import at.petrak.hexcasting.api.misc.MediaConstants
|
||||
import at.petrak.hexcasting.api.mod.HexConfig
|
||||
import at.petrak.hexcasting.api.casting.ParticleSpray
|
||||
import at.petrak.hexcasting.api.casting.RenderedSpell
|
||||
import at.petrak.hexcasting.api.casting.castables.SpellAction
|
||||
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment
|
||||
import at.petrak.hexcasting.api.casting.getBlockPos
|
||||
import at.petrak.hexcasting.api.casting.iota.Iota
|
||||
import at.petrak.hexcasting.api.misc.MediaConstants
|
||||
import at.petrak.hexcasting.api.mod.HexConfig
|
||||
import at.petrak.hexcasting.xplat.IXplatAbstractions
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
@ -25,7 +25,7 @@ object OpBreakBlock : SpellAction {
|
|||
|
||||
return Triple(
|
||||
Spell(pos),
|
||||
(MediaConstants.DUST_UNIT * 1.125).toInt(),
|
||||
MediaConstants.DUST_UNIT / 8,
|
||||
listOf(ParticleSpray.burst(Vec3.atCenterOf(pos), 1.0))
|
||||
)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,197 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.spells
|
||||
|
||||
import at.petrak.hexcasting.api.casting.ParticleSpray
|
||||
import at.petrak.hexcasting.api.casting.RenderedSpell
|
||||
import at.petrak.hexcasting.api.casting.castables.SpellAction
|
||||
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment
|
||||
import at.petrak.hexcasting.api.casting.getPlayer
|
||||
import at.petrak.hexcasting.api.casting.getPositiveDouble
|
||||
import at.petrak.hexcasting.api.casting.iota.Iota
|
||||
import at.petrak.hexcasting.api.misc.FrozenColorizer
|
||||
import at.petrak.hexcasting.api.misc.MediaConstants
|
||||
import at.petrak.hexcasting.api.player.FlightAbility
|
||||
import at.petrak.hexcasting.common.lib.HexItems
|
||||
import at.petrak.hexcasting.common.lib.HexSounds
|
||||
import at.petrak.hexcasting.xplat.IXplatAbstractions
|
||||
import net.minecraft.Util
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.sounds.SoundSource
|
||||
import net.minecraft.util.Mth
|
||||
import net.minecraft.world.item.DyeColor
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.phys.Vec3
|
||||
import kotlin.math.max
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
class OpFlight(val type: Type) : SpellAction {
|
||||
override val argc = 2
|
||||
override fun execute(
|
||||
args: List<Iota>,
|
||||
ctx: CastingEnvironment
|
||||
): Triple<RenderedSpell, Int, List<ParticleSpray>> {
|
||||
val target = args.getPlayer(0, argc)
|
||||
val theArg = args.getPositiveDouble(1, argc)
|
||||
ctx.assertEntityInRange(target)
|
||||
|
||||
val cost = when (this.type) {
|
||||
Type.LimitRange -> theArg * MediaConstants.DUST_UNIT
|
||||
// A second of flight should cost 1 shard
|
||||
Type.LimitTime -> theArg * MediaConstants.SHARD_UNIT
|
||||
}.roundToInt()
|
||||
|
||||
// Convert to ticks
|
||||
return Triple(
|
||||
Spell(this.type, target, theArg),
|
||||
cost,
|
||||
listOf(ParticleSpray(target.position(), Vec3(0.0, 2.0, 0.0), 0.0, 0.1))
|
||||
)
|
||||
}
|
||||
|
||||
enum class Type {
|
||||
LimitRange,
|
||||
LimitTime;
|
||||
|
||||
}
|
||||
|
||||
data class Spell(val type: Type, val target: ServerPlayer, val theArg: Double) : RenderedSpell {
|
||||
override fun cast(ctx: CastingEnvironment) {
|
||||
if (target.abilities.mayfly) {
|
||||
// Don't accidentally clobber someone else's flight
|
||||
// TODO make this a mishap?
|
||||
return
|
||||
}
|
||||
|
||||
val dim = target.level.dimension()
|
||||
val origin = target.position()
|
||||
|
||||
val flight = when (this.type) {
|
||||
Type.LimitRange -> FlightAbility(-1, dim, origin, theArg)
|
||||
Type.LimitTime -> FlightAbility((theArg * 20.0).roundToInt(), dim, origin, -1.0)
|
||||
}
|
||||
|
||||
IXplatAbstractions.INSTANCE.setFlight(target, flight)
|
||||
|
||||
target.abilities.mayfly = true
|
||||
target.onUpdateAbilities()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
// blocks from the edge
|
||||
private val DIST_DANGER_THRESHOLD = 4.0
|
||||
|
||||
// seconds left
|
||||
private val TIME_DANGER_THRESHOLD = 7.0 * 20.0
|
||||
|
||||
@JvmStatic
|
||||
fun tickAllPlayers(world: ServerLevel) {
|
||||
for (player in world.players()) {
|
||||
tickDownFlight(player)
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun tickDownFlight(player: ServerPlayer) {
|
||||
val flight = IXplatAbstractions.INSTANCE.getFlight(player)
|
||||
|
||||
if (flight != null) {
|
||||
val danger = getDanger(player, flight)
|
||||
if (danger >= 1.0) {
|
||||
IXplatAbstractions.INSTANCE.setFlight(player, null)
|
||||
// stop shin smashing bonke
|
||||
|
||||
if (!player.isCreative && !player.isSpectator) {
|
||||
val abilities = player.abilities
|
||||
abilities.flying = false
|
||||
abilities.mayfly = false
|
||||
player.onUpdateAbilities()
|
||||
}
|
||||
player.level.playSound(null, player.x, player.y, player.z, HexSounds.FLIGHT_FINISH, SoundSource.PLAYERS, 2f, 1f)
|
||||
val superDangerSpray = ParticleSpray(player.position(), Vec3(0.0, 1.0, 0.0), Math.PI, 0.4, count = 20)
|
||||
superDangerSpray.sprayParticles(player.getLevel(), FrozenColorizer(ItemStack(HexItems.DYE_COLORIZERS[DyeColor.RED]!!), Util.NIL_UUID))
|
||||
superDangerSpray.sprayParticles(player.getLevel(), FrozenColorizer(ItemStack(HexItems.DYE_COLORIZERS[DyeColor.BLACK]!!), Util.NIL_UUID))
|
||||
} else {
|
||||
if (!player.abilities.mayfly) {
|
||||
player.abilities.mayfly = true
|
||||
player.onUpdateAbilities()
|
||||
}
|
||||
val time2 = if (flight.timeLeft >= 0) {
|
||||
flight.timeLeft - 1
|
||||
} else {
|
||||
flight.timeLeft
|
||||
}
|
||||
IXplatAbstractions.INSTANCE.setFlight(
|
||||
player,
|
||||
FlightAbility(
|
||||
time2,
|
||||
flight.dimension,
|
||||
flight.origin,
|
||||
flight.radius
|
||||
)
|
||||
)
|
||||
|
||||
val particleCount = 5
|
||||
val dangerParticleCount = (particleCount * danger).roundToInt()
|
||||
val okParticleCount = particleCount - dangerParticleCount
|
||||
val oneDangerParticleCount = Mth.ceil(dangerParticleCount / 2.0)
|
||||
val color = IXplatAbstractions.INSTANCE.getColorizer(player)
|
||||
|
||||
// TODO: have the particles go in the opposite direction of the velocity?
|
||||
ParticleSpray(player.position(), Vec3(0.0, -0.6, 0.0), 0.6, Math.PI * 0.3, count = okParticleCount)
|
||||
.sprayParticles(player.getLevel(), color)
|
||||
val dangerSpray = ParticleSpray(player.position(), Vec3(0.0, 1.0, 0.0), 0.3, Math.PI * 0.75, count = 0)
|
||||
dangerSpray.copy(count = oneDangerParticleCount)
|
||||
.sprayParticles(player.getLevel(), FrozenColorizer(ItemStack(HexItems.DYE_COLORIZERS[DyeColor.BLACK]!!), Util.NIL_UUID))
|
||||
dangerSpray.copy(count = oneDangerParticleCount)
|
||||
.sprayParticles(player.getLevel(), FrozenColorizer(ItemStack(HexItems.DYE_COLORIZERS[DyeColor.RED]!!), Util.NIL_UUID))
|
||||
|
||||
if (player.level.random.nextFloat() < 0.02)
|
||||
player.level.playSound(null, player.x, player.y, player.z, HexSounds.FLIGHT_AMBIENCE, SoundSource.PLAYERS, 0.2f, 1f)
|
||||
|
||||
if (flight.radius >= 0.0) {
|
||||
// Show the origin
|
||||
val spoofedOrigin = flight.origin.add(0.0, 1.0, 0.0)
|
||||
ParticleSpray(spoofedOrigin, Vec3(0.0, 1.0, 0.0), 0.5, Math.PI * 0.1, count = 5)
|
||||
.sprayParticles(player.getLevel(), color)
|
||||
ParticleSpray(spoofedOrigin, Vec3(0.0, -1.0, 0.0), 1.5, Math.PI * 0.25, count = 5)
|
||||
.sprayParticles(player.getLevel(), color)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return a number from 0 (totally fine) to 1 (danger will robinson, stop the flight)
|
||||
// it's a double for particle reason
|
||||
private fun getDanger(player: ServerPlayer, flight: FlightAbility): Double {
|
||||
val radiusDanger = if (flight.radius >= 0.0) {
|
||||
if (player.level.dimension() != flight.dimension) {
|
||||
1.0
|
||||
} else {
|
||||
// Limit it only in X/Z
|
||||
val posXZ = Vec3(player.x, 0.0, player.z)
|
||||
val originXZ = Vec3(flight.origin.x, 0.0, flight.origin.z)
|
||||
val dist = posXZ.distanceTo(originXZ)
|
||||
val distFromEdge = flight.radius - dist
|
||||
if (distFromEdge >= DIST_DANGER_THRESHOLD) {
|
||||
0.0
|
||||
} else if (dist > flight.radius) {
|
||||
1.0
|
||||
} else {
|
||||
1.0 - (distFromEdge / DIST_DANGER_THRESHOLD)
|
||||
}
|
||||
}
|
||||
} else 0.0
|
||||
val timeDanger = if (flight.timeLeft >= 0) {
|
||||
if (flight.timeLeft >= TIME_DANGER_THRESHOLD) {
|
||||
0.0
|
||||
} else {
|
||||
val timeDanger = TIME_DANGER_THRESHOLD - flight.timeLeft
|
||||
timeDanger / TIME_DANGER_THRESHOLD
|
||||
}
|
||||
} else 0.0
|
||||
return max(radiusDanger, timeDanger)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.spells.great
|
||||
|
||||
import at.petrak.hexcasting.api.casting.ParticleSpray
|
||||
import at.petrak.hexcasting.api.casting.RenderedSpell
|
||||
import at.petrak.hexcasting.api.casting.castables.SpellAction
|
||||
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment
|
||||
import at.petrak.hexcasting.api.casting.getPlayer
|
||||
import at.petrak.hexcasting.api.casting.iota.Iota
|
||||
import at.petrak.hexcasting.api.misc.MediaConstants
|
||||
import at.petrak.hexcasting.api.player.AltioraAbility
|
||||
import at.petrak.hexcasting.common.lib.HexSounds
|
||||
import at.petrak.hexcasting.xplat.IXplatAbstractions
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.sounds.SoundSource
|
||||
import net.minecraft.world.phys.Vec3
|
||||
import kotlin.math.max
|
||||
|
||||
object OpAltiora : SpellAction {
|
||||
override val argc = 1
|
||||
|
||||
override fun execute(args: List<Iota>, ctx: CastingEnvironment): Triple<RenderedSpell, Int, List<ParticleSpray>> {
|
||||
val target = args.getPlayer(0, argc)
|
||||
ctx.assertEntityInRange(target)
|
||||
|
||||
return Triple(
|
||||
Spell(target),
|
||||
MediaConstants.CRYSTAL_UNIT,
|
||||
listOf(
|
||||
ParticleSpray.burst(target.position(), 0.5),
|
||||
ParticleSpray(target.position(), Vec3(0.0, 2.0, 0.0), 0.0, 0.1)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private data class Spell(val target: ServerPlayer) : RenderedSpell {
|
||||
override fun cast(ctx: CastingEnvironment) {
|
||||
target.push(0.0, 1.5, 0.0)
|
||||
// They won't move otherwise?
|
||||
target.hurtMarked = true
|
||||
|
||||
IXplatAbstractions.INSTANCE.setAltiora(target, AltioraAbility(GRACE_PERIOD))
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun checkPlayerCollision(player: ServerPlayer) {
|
||||
val altiora = IXplatAbstractions.INSTANCE.getAltiora(player);
|
||||
if (altiora != null) {
|
||||
if (altiora.gracePeriod == 0 && (player.isOnGround || player.horizontalCollision)) {
|
||||
IXplatAbstractions.INSTANCE.setAltiora(player, null)
|
||||
player.level.playSound(null, player.x, player.y, player.z, HexSounds.FLIGHT_FINISH, SoundSource.PLAYERS, 2f, 1f)
|
||||
} else {
|
||||
val grace2 = max(altiora.gracePeriod - 1, 0)
|
||||
IXplatAbstractions.INSTANCE.setAltiora(player, AltioraAbility(grace2))
|
||||
|
||||
if (player.level.random.nextFloat() < 0.02)
|
||||
player.level.playSound(null, player.x, player.y, player.z, HexSounds.FLIGHT_AMBIENCE, SoundSource.PLAYERS, 0.2f, 1f)
|
||||
|
||||
val color = IXplatAbstractions.INSTANCE.getColorizer(player)
|
||||
ParticleSpray(player.position(), Vec3(0.0, -0.2, 0.0), 0.4, Math.PI * 0.5, count = 3)
|
||||
.sprayParticles(player.getLevel(), color)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun checkAllPlayers(world: ServerLevel) {
|
||||
for (player in world.players()) {
|
||||
checkPlayerCollision(player)
|
||||
}
|
||||
}
|
||||
|
||||
private val GRACE_PERIOD = 20
|
||||
}
|
|
@ -1,107 +0,0 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.spells.great
|
||||
|
||||
import at.petrak.hexcasting.api.casting.*
|
||||
import at.petrak.hexcasting.api.casting.castables.SpellAction
|
||||
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment
|
||||
import at.petrak.hexcasting.api.casting.iota.Iota
|
||||
import at.petrak.hexcasting.api.misc.MediaConstants
|
||||
import at.petrak.hexcasting.api.player.FlightAbility
|
||||
import at.petrak.hexcasting.xplat.IXplatAbstractions
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.phys.Vec3
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
object OpFlight : SpellAction {
|
||||
override val argc = 3
|
||||
override fun execute(
|
||||
args: List<Iota>,
|
||||
ctx: CastingEnvironment
|
||||
): Triple<RenderedSpell, Int, List<ParticleSpray>> {
|
||||
val target = args.getPlayer(0, argc)
|
||||
val timeRaw = args.getPositiveDouble(1, argc)
|
||||
val radiusRaw = args.getPositiveDouble(2, argc)
|
||||
ctx.assertEntityInRange(target)
|
||||
|
||||
// Convert to ticks
|
||||
val time = (timeRaw * 20.0).roundToInt()
|
||||
return Triple(
|
||||
Spell(target, time, radiusRaw, ctx.position),
|
||||
(MediaConstants.DUST_UNIT * 0.25 * (timeRaw * radiusRaw + 1.0)).roundToInt(),
|
||||
listOf(ParticleSpray(target.position(), Vec3(0.0, 2.0, 0.0), 0.0, 0.1))
|
||||
)
|
||||
}
|
||||
|
||||
data class Spell(val target: ServerPlayer, val time: Int, val radius: Double, val origin: Vec3) : RenderedSpell {
|
||||
override fun cast(ctx: CastingEnvironment) {
|
||||
if (target.abilities.mayfly) {
|
||||
// Don't accidentally clobber someone else's flight
|
||||
return
|
||||
}
|
||||
|
||||
IXplatAbstractions.INSTANCE.setFlight(
|
||||
target,
|
||||
FlightAbility(
|
||||
true,
|
||||
time,
|
||||
target.level.dimension(),
|
||||
origin,
|
||||
radius
|
||||
)
|
||||
)
|
||||
|
||||
target.abilities.mayfly = true
|
||||
target.abilities.flying = true
|
||||
target.onUpdateAbilities()
|
||||
// Launch the player into the air to really emphasize the flight
|
||||
target.push(0.0, 1.0, 0.0)
|
||||
target.hurtMarked = true // Whyyyyy
|
||||
}
|
||||
}
|
||||
|
||||
fun tickDownFlight(entity: LivingEntity) {
|
||||
if (entity !is ServerPlayer) return
|
||||
|
||||
val flight = IXplatAbstractions.INSTANCE.getFlight(entity)
|
||||
|
||||
if (flight.allowed) {
|
||||
val flightTime = flight.timeLeft - 1
|
||||
if (flightTime < 0 || flight.origin.distanceToSqr(entity.position()) > flight.radius * flight.radius || flight.dimension != entity.level.dimension()) {
|
||||
if (!entity.isOnGround) {
|
||||
entity.fallDistance = 1_000_000f
|
||||
}
|
||||
IXplatAbstractions.INSTANCE.setFlight(entity, FlightAbility.deny())
|
||||
|
||||
if (!entity.isCreative && !entity.isSpectator) {
|
||||
val abilities = entity.abilities
|
||||
abilities.flying = false
|
||||
abilities.mayfly = false
|
||||
entity.onUpdateAbilities()
|
||||
}
|
||||
} else {
|
||||
if (!entity.abilities.mayfly) {
|
||||
entity.abilities.mayfly = true
|
||||
entity.onUpdateAbilities()
|
||||
}
|
||||
IXplatAbstractions.INSTANCE.setFlight(
|
||||
entity,
|
||||
FlightAbility(
|
||||
true,
|
||||
flightTime,
|
||||
flight.dimension,
|
||||
flight.origin,
|
||||
flight.radius
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun tickAllPlayers(world: ServerLevel) {
|
||||
for (player in world.players()) {
|
||||
tickDownFlight(player)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,7 +3,7 @@ package at.petrak.hexcasting.common.command;
|
|||
import at.petrak.hexcasting.api.casting.iota.PatternIota;
|
||||
import at.petrak.hexcasting.api.casting.math.HexPattern;
|
||||
import at.petrak.hexcasting.common.casting.PatternRegistryManifest;
|
||||
import at.petrak.hexcasting.common.items.ItemScroll;
|
||||
import at.petrak.hexcasting.common.items.storage.ItemScroll;
|
||||
import at.petrak.hexcasting.common.lib.HexItems;
|
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
|
|
|
@ -3,8 +3,8 @@ package at.petrak.hexcasting.common.entities;
|
|||
import at.petrak.hexcasting.api.casting.math.HexPattern;
|
||||
import at.petrak.hexcasting.api.utils.HexUtils;
|
||||
import at.petrak.hexcasting.api.utils.NBTHelper;
|
||||
import at.petrak.hexcasting.client.RenderLib;
|
||||
import at.petrak.hexcasting.common.items.ItemScroll;
|
||||
import at.petrak.hexcasting.client.render.RenderLib;
|
||||
import at.petrak.hexcasting.common.items.storage.ItemScroll;
|
||||
import at.petrak.hexcasting.common.lib.HexItems;
|
||||
import at.petrak.hexcasting.common.lib.HexSounds;
|
||||
import at.petrak.hexcasting.common.network.MsgNewWallScrollAck;
|
||||
|
|
|
@ -15,7 +15,7 @@ import net.minecraft.world.item.ItemStack;
|
|||
import net.minecraft.world.level.Level;
|
||||
|
||||
public class ItemStaff extends Item {
|
||||
// 0 = normal. 1 = old. 2 = bosnia
|
||||
// 0 = normal. 1 = old. 2 = cherry preview
|
||||
public static final ResourceLocation FUNNY_LEVEL_PREDICATE = new ResourceLocation(HexAPI.MOD_ID, "funny_level");
|
||||
|
||||
public ItemStaff(Properties pProperties) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package at.petrak.hexcasting.common.items.magic;
|
||||
|
||||
import at.petrak.hexcasting.api.mod.HexConfig;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
public class ItemArtifact extends ItemPackagedHex {
|
||||
|
@ -16,4 +17,9 @@ public class ItemArtifact extends ItemPackagedHex {
|
|||
public boolean breakAfterDepletion() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int cooldown() {
|
||||
return HexConfig.common().artifactCooldown();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package at.petrak.hexcasting.common.items.magic;
|
||||
|
||||
import at.petrak.hexcasting.api.mod.HexConfig;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
public class ItemCypher extends ItemPackagedHex {
|
||||
|
@ -16,4 +17,9 @@ public class ItemCypher extends ItemPackagedHex {
|
|||
public boolean breakAfterDepletion() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int cooldown() {
|
||||
return HexConfig.common().cypherCooldown();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,6 +40,8 @@ public abstract class ItemPackagedHex extends ItemMediaHolder implements HexHold
|
|||
|
||||
public abstract boolean breakAfterDepletion();
|
||||
|
||||
public abstract int cooldown();
|
||||
|
||||
@Override
|
||||
public boolean canRecharge(ItemStack stack) {
|
||||
return !breakAfterDepletion();
|
||||
|
@ -120,7 +122,7 @@ public abstract class ItemPackagedHex extends ItemMediaHolder implements HexHold
|
|||
}
|
||||
player.awardStat(stat);
|
||||
|
||||
sPlayer.getCooldowns().addCooldown(this, 5);
|
||||
sPlayer.getCooldowns().addCooldown(this, this.cooldown());
|
||||
|
||||
if (broken) {
|
||||
stack.shrink(1);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package at.petrak.hexcasting.common.items.magic;
|
||||
|
||||
import at.petrak.hexcasting.api.mod.HexConfig;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
public class ItemTrinket extends ItemPackagedHex {
|
||||
|
@ -16,4 +17,9 @@ public class ItemTrinket extends ItemPackagedHex {
|
|||
public boolean breakAfterDepletion() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int cooldown() {
|
||||
return HexConfig.common().trinketCooldown();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package at.petrak.hexcasting.common.items;
|
||||
package at.petrak.hexcasting.common.items.storage;
|
||||
|
||||
import at.petrak.hexcasting.api.casting.iota.DoubleIota;
|
||||
import at.petrak.hexcasting.api.casting.iota.Iota;
|
|
@ -1,4 +1,4 @@
|
|||
package at.petrak.hexcasting.common.items;
|
||||
package at.petrak.hexcasting.common.items.storage;
|
||||
|
||||
import at.petrak.hexcasting.api.casting.iota.Iota;
|
||||
import at.petrak.hexcasting.api.casting.iota.IotaType;
|
|
@ -1,4 +1,4 @@
|
|||
package at.petrak.hexcasting.common.items;
|
||||
package at.petrak.hexcasting.common.items.storage;
|
||||
|
||||
import at.petrak.hexcasting.api.casting.iota.Iota;
|
||||
import at.petrak.hexcasting.api.casting.iota.PatternIota;
|
|
@ -1,4 +1,4 @@
|
|||
package at.petrak.hexcasting.common.items;
|
||||
package at.petrak.hexcasting.common.items.storage;
|
||||
|
||||
import at.petrak.hexcasting.annotations.SoftImplement;
|
||||
import at.petrak.hexcasting.api.HexAPI;
|
|
@ -1,4 +1,4 @@
|
|||
package at.petrak.hexcasting.common.items;
|
||||
package at.petrak.hexcasting.common.items.storage;
|
||||
|
||||
import at.petrak.hexcasting.api.casting.iota.Iota;
|
||||
import at.petrak.hexcasting.api.casting.iota.IotaType;
|
|
@ -0,0 +1,52 @@
|
|||
package at.petrak.hexcasting.common.items.storage;
|
||||
|
||||
import at.petrak.hexcasting.api.casting.iota.Iota;
|
||||
import at.petrak.hexcasting.api.item.IotaHolderItem;
|
||||
import at.petrak.hexcasting.api.utils.NBTHelper;
|
||||
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.TooltipFlag;
|
||||
import net.minecraft.world.level.Level;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static at.petrak.hexcasting.api.HexAPI.modLoc;
|
||||
|
||||
// Would love to be able to just write to a piece of string but the api requires it to be the same item
|
||||
public class ItemThoughtKnot extends Item implements IotaHolderItem {
|
||||
public static final ResourceLocation WRITTEN_PRED = modLoc("written");
|
||||
|
||||
public static final String TAG_DATA = "data";
|
||||
|
||||
public ItemThoughtKnot(Properties properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable CompoundTag readIotaTag(ItemStack stack) {
|
||||
return NBTHelper.getCompound(stack, TAG_DATA);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canWrite(ItemStack stack, @Nullable Iota iota) {
|
||||
return iota != null && !NBTHelper.contains(stack, TAG_DATA);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDatum(ItemStack stack, @Nullable Iota iota) {
|
||||
if (iota != null) {
|
||||
NBTHelper.putCompound(stack, TAG_DATA, HexIotaTypes.serialize(iota));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHoverText(ItemStack pStack, @Nullable Level pLevel,
|
||||
List<Component> pTooltipComponents, TooltipFlag pIsAdvanced) {
|
||||
IotaHolderItem.appendHoverText(this, pStack, pTooltipComponents, pIsAdvanced);
|
||||
}
|
||||
}
|
|
@ -3,10 +3,7 @@ package at.petrak.hexcasting.common.lib;
|
|||
import at.petrak.hexcasting.api.HexAPI;
|
||||
import at.petrak.hexcasting.common.blocks.akashic.BlockEntityAkashicBookshelf;
|
||||
import at.petrak.hexcasting.common.blocks.circles.BlockEntitySlate;
|
||||
import at.petrak.hexcasting.common.blocks.entity.BlockEntityConjured;
|
||||
import at.petrak.hexcasting.common.blocks.entity.BlockEntityLookingImpetus;
|
||||
import at.petrak.hexcasting.common.blocks.entity.BlockEntityRightClickImpetus;
|
||||
import at.petrak.hexcasting.common.blocks.entity.BlockEntityStoredPlayerImpetus;
|
||||
import at.petrak.hexcasting.common.blocks.entity.*;
|
||||
import at.petrak.hexcasting.xplat.IXplatAbstractions;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
@ -51,6 +48,9 @@ public class HexBlockEntities {
|
|||
"slate_tile",
|
||||
BlockEntitySlate::new, HexBlocks.SLATE);
|
||||
|
||||
public static final BlockEntityType<BlockEntityQuenchedAllay> QUENCHED_ALLAY_TILE = register(
|
||||
"quenched_allay_tile", BlockEntityQuenchedAllay::new, HexBlocks.QUENCHED_ALLAY);
|
||||
|
||||
private static <T extends BlockEntity> BlockEntityType<T> register(String id,
|
||||
BiFunction<BlockPos, BlockState, T> func, Block... blocks) {
|
||||
var ret = IXplatAbstractions.INSTANCE.createBlockEntityType(func, blocks);
|
||||
|
|
|
@ -4,6 +4,7 @@ import at.petrak.hexcasting.api.block.circle.BlockAbstractImpetus;
|
|||
import at.petrak.hexcasting.common.blocks.BlockConjured;
|
||||
import at.petrak.hexcasting.common.blocks.BlockConjuredLight;
|
||||
import at.petrak.hexcasting.common.blocks.BlockFlammable;
|
||||
import at.petrak.hexcasting.common.blocks.BlockQuenchedAllay;
|
||||
import at.petrak.hexcasting.common.blocks.akashic.BlockAkashicBookshelf;
|
||||
import at.petrak.hexcasting.common.blocks.akashic.BlockAkashicLigature;
|
||||
import at.petrak.hexcasting.common.blocks.akashic.BlockAkashicRecord;
|
||||
|
@ -20,6 +21,7 @@ import net.minecraft.resources.ResourceLocation;
|
|||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.item.BlockItem;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.Rarity;
|
||||
import net.minecraft.world.level.block.*;
|
||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||
import net.minecraft.world.level.material.Material;
|
||||
|
@ -146,6 +148,13 @@ public class HexBlocks {
|
|||
public static final BlockAkashicLigature AKASHIC_LIGATURE = blockItem("akashic_connector",
|
||||
new BlockAkashicLigature(akashicWoodyHard().lightLevel(bs -> 4)));
|
||||
|
||||
// we have to make it emit light because otherwise it occludes itself and is always dark
|
||||
public static final BlockQuenchedAllay QUENCHED_ALLAY = blockItem("quenched_allay", new BlockQuenchedAllay(
|
||||
BlockBehaviour.Properties
|
||||
.copy(Blocks.AMETHYST_BLOCK)
|
||||
.lightLevel($ -> 4)
|
||||
.noOcclusion()));
|
||||
|
||||
// Decoration?!
|
||||
public static final Block SLATE_BLOCK = blockItem("slate_block", new Block(slateish().strength(2f, 4f)));
|
||||
public static final SandBlock AMETHYST_DUST_BLOCK = blockItem("amethyst_dust_block",
|
||||
|
@ -166,7 +175,8 @@ public class HexBlocks {
|
|||
new BlockSconce(BlockBehaviour.Properties.of(Material.AMETHYST, MaterialColor.COLOR_PURPLE)
|
||||
.sound(SoundType.AMETHYST)
|
||||
.strength(1f)
|
||||
.lightLevel($ -> 15)));
|
||||
.lightLevel($ -> 15)),
|
||||
HexItems.props().rarity(Rarity.RARE));
|
||||
|
||||
public static final BlockAkashicLog EDIFIED_LOG = blockItem("edified_log",
|
||||
new BlockAkashicLog(edifiedWoody()));
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
package at.petrak.hexcasting.common.lib;
|
||||
|
||||
import at.petrak.hexcasting.common.items.*;
|
||||
import at.petrak.hexcasting.common.items.ItemJewelerHammer;
|
||||
import at.petrak.hexcasting.common.items.ItemLens;
|
||||
import at.petrak.hexcasting.common.items.ItemLoreFragment;
|
||||
import at.petrak.hexcasting.common.items.ItemStaff;
|
||||
import at.petrak.hexcasting.common.items.colorizer.ItemDyeColorizer;
|
||||
import at.petrak.hexcasting.common.items.colorizer.ItemPrideColorizer;
|
||||
import at.petrak.hexcasting.common.items.colorizer.ItemUUIDColorizer;
|
||||
import at.petrak.hexcasting.common.items.magic.*;
|
||||
import at.petrak.hexcasting.common.items.storage.*;
|
||||
import at.petrak.hexcasting.xplat.IXplatAbstractions;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
@ -32,6 +36,8 @@ public class HexItems {
|
|||
public static final Item AMETHYST_DUST = make("amethyst_dust", new Item(props()));
|
||||
public static final Item CHARGED_AMETHYST = make("charged_amethyst", new Item(props()));
|
||||
|
||||
public static final Item QUENCHED_SHARD = make("quenched_allay_shard", new Item(props()));
|
||||
|
||||
public static final ItemStaff STAFF_OAK = make("oak_staff", new ItemStaff(unstackable()));
|
||||
public static final ItemStaff STAFF_SPRUCE = make("spruce_staff", new ItemStaff(unstackable()));
|
||||
public static final ItemStaff STAFF_BIRCH = make("birch_staff", new ItemStaff(unstackable()));
|
||||
|
@ -42,6 +48,9 @@ public class HexItems {
|
|||
public static final ItemStaff STAFF_WARPED = make("warped_staff", new ItemStaff(unstackable()));
|
||||
public static final ItemStaff STAFF_MANGROVE = make("mangrove_staff", new ItemStaff(unstackable()));
|
||||
public static final ItemStaff STAFF_EDIFIED = make("edified_staff", new ItemStaff(unstackable()));
|
||||
public static final ItemStaff STAFF_QUENCHED = make("quenched_staff", new ItemStaff(unstackable()));
|
||||
// mindsplice staffaratus
|
||||
public static final ItemStaff STAFF_MINDSPLICE = make("mindsplice_staff", new ItemStaff(unstackable()));
|
||||
|
||||
public static final ItemLens SCRYING_LENS = make("lens", new ItemLens(
|
||||
IXplatAbstractions.INSTANCE.addEquipSlotFabric(EquipmentSlot.HEAD)
|
||||
|
@ -49,6 +58,7 @@ public class HexItems {
|
|||
.tab(IXplatAbstractions.INSTANCE.getTab())));
|
||||
|
||||
public static final ItemAbacus ABACUS = make("abacus", new ItemAbacus(unstackable()));
|
||||
public static final ItemThoughtKnot THOUGHT_KNOT = make("thought_knot", new ItemThoughtKnot(unstackable()));
|
||||
public static final ItemFocus FOCUS = make("focus", new ItemFocus(unstackable()));
|
||||
public static final ItemSpellbook SPELLBOOK = make("spellbook", new ItemSpellbook(unstackable()));
|
||||
|
||||
|
|
|
@ -25,9 +25,7 @@ public class HexParticles {
|
|||
private static final Map<ResourceLocation, ParticleType<?>> PARTICLES = new LinkedHashMap<>();
|
||||
|
||||
public static final ConjureParticleOptions.Type CONJURE_PARTICLE = register(
|
||||
"conjure_block_particle", new ConjureParticleOptions.Type(false));
|
||||
public static final ConjureParticleOptions.Type LIGHT_PARTICLE = register(
|
||||
"conjure_light_particle", new ConjureParticleOptions.Type(false));
|
||||
"conjure_particle", new ConjureParticleOptions.Type(false));
|
||||
|
||||
private static <O extends ParticleOptions, T extends ParticleType<O>> T register(String id, T particle) {
|
||||
var old = PARTICLES.put(modLoc(id), particle);
|
||||
|
@ -39,12 +37,12 @@ public class HexParticles {
|
|||
|
||||
public static class FactoryHandler {
|
||||
public interface Consumer {
|
||||
<T extends ParticleOptions> void register(ParticleType<T> type, Function<SpriteSet, ParticleProvider<T>> constructor);
|
||||
<T extends ParticleOptions> void register(ParticleType<T> type,
|
||||
Function<SpriteSet, ParticleProvider<T>> constructor);
|
||||
}
|
||||
|
||||
public static void registerFactories(Consumer consumer) {
|
||||
consumer.register(CONJURE_PARTICLE, ConjureParticle.Provider::new);
|
||||
consumer.register(LIGHT_PARTICLE, ConjureParticle.Provider::new);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,6 +42,9 @@ public class HexSounds {
|
|||
|
||||
public static final SoundEvent READ_LORE_FRAGMENT = sound("lore_fragment.read");
|
||||
|
||||
public static final SoundEvent FLIGHT_AMBIENCE = sound("flight.ambience");
|
||||
public static final SoundEvent FLIGHT_FINISH = sound("flight.finish");
|
||||
|
||||
private static SoundEvent sound(String name) {
|
||||
var id = modLoc(name);
|
||||
var sound = new SoundEvent(id);
|
||||
|
|
|
@ -334,6 +334,13 @@ public class HexActions {
|
|||
MediaConstants.DUST_UNIT / 3, true, true)
|
||||
));
|
||||
|
||||
public static final ActionRegistryEntry FLIGHT$RANGE = make("flight/range",
|
||||
new ActionRegistryEntry(HexPattern.fromAngles("awawaawq", HexDir.SOUTH_WEST),
|
||||
new OpFlight(OpFlight.Type.LimitRange)));
|
||||
public static final ActionRegistryEntry FLIGHT$TIME = make("flight/time",
|
||||
new ActionRegistryEntry(HexPattern.fromAngles("dwdwdewq", HexDir.NORTH_EAST),
|
||||
new OpFlight(OpFlight.Type.LimitTime)));
|
||||
|
||||
public static final ActionRegistryEntry SENTINEL$CREATE = make("sentinel/create",
|
||||
new ActionRegistryEntry(HexPattern.fromAngles("waeawae", HexDir.EAST), new OpCreateSentinel(false)));
|
||||
public static final ActionRegistryEntry SENTINEL$DESTROY = make("sentinel/destroy",
|
||||
|
@ -345,8 +352,11 @@ public class HexActions {
|
|||
|
||||
public static final ActionRegistryEntry LIGHTNING = make("lightning",
|
||||
new ActionRegistryEntry(HexPattern.fromAngles("waadwawdaaweewq", HexDir.EAST), OpLightning.INSTANCE));
|
||||
public static final ActionRegistryEntry FLIGHT = make("flight",
|
||||
new ActionRegistryEntry(HexPattern.fromAngles("eawwaeawawaa", HexDir.NORTH_WEST), OpFlight.INSTANCE));
|
||||
|
||||
public static final ActionRegistryEntry ALTIORA = make("flight",
|
||||
new ActionRegistryEntry(HexPattern.fromAngles("eawwaeawawaa", HexDir.NORTH_WEST), OpAltiora.INSTANCE));
|
||||
|
||||
|
||||
public static final ActionRegistryEntry CREATE_LAVA = make("create_lava",
|
||||
new ActionRegistryEntry(HexPattern.fromAngles("eaqawqadaqd", HexDir.EAST), new OpCreateFluid(
|
||||
MediaConstants.CRYSTAL_UNIT,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package at.petrak.hexcasting.common.loot;
|
||||
|
||||
import at.petrak.hexcasting.common.casting.PatternRegistryManifest;
|
||||
import at.petrak.hexcasting.common.items.ItemScroll;
|
||||
import at.petrak.hexcasting.common.items.storage.ItemScroll;
|
||||
import at.petrak.hexcasting.common.lib.HexLootFunctions;
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonObject;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package at.petrak.hexcasting.common.network;
|
||||
|
||||
import at.petrak.hexcasting.api.misc.FrozenColorizer;
|
||||
import at.petrak.hexcasting.api.casting.ParticleSpray;
|
||||
import at.petrak.hexcasting.api.misc.FrozenColorizer;
|
||||
import at.petrak.hexcasting.common.particles.ConjureParticleOptions;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
@ -96,7 +96,7 @@ public record MsgCastParticleAck(ParticleSpray spray, FrozenColorizer colorizer)
|
|||
var vel = velUnlen.scale(msg.spray().getVel().length() / 20);
|
||||
|
||||
Minecraft.getInstance().level.addParticle(
|
||||
new ConjureParticleOptions(color, false),
|
||||
new ConjureParticleOptions(color),
|
||||
pos.x, pos.y, pos.z,
|
||||
vel.x, vel.y, vel.z
|
||||
);
|
||||
|
|
|
@ -2,8 +2,8 @@ package at.petrak.hexcasting.common.network;
|
|||
|
||||
import at.petrak.hexcasting.api.casting.iota.IotaType;
|
||||
import at.petrak.hexcasting.api.utils.NBTHelper;
|
||||
import at.petrak.hexcasting.common.items.ItemAbacus;
|
||||
import at.petrak.hexcasting.common.items.ItemSpellbook;
|
||||
import at.petrak.hexcasting.common.items.storage.ItemAbacus;
|
||||
import at.petrak.hexcasting.common.items.storage.ItemSpellbook;
|
||||
import at.petrak.hexcasting.common.lib.HexItems;
|
||||
import at.petrak.hexcasting.common.lib.HexSounds;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
|
|
@ -11,21 +11,20 @@ import net.minecraft.network.FriendlyByteBuf;
|
|||
|
||||
import java.util.Locale;
|
||||
|
||||
public record ConjureParticleOptions(int color, boolean isLight) implements ParticleOptions {
|
||||
public record ConjureParticleOptions(int color) implements ParticleOptions {
|
||||
@Override
|
||||
public ParticleType<?> getType() {
|
||||
return (this.isLight ? HexParticles.LIGHT_PARTICLE : HexParticles.CONJURE_PARTICLE);
|
||||
return HexParticles.CONJURE_PARTICLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToNetwork(FriendlyByteBuf buf) {
|
||||
buf.writeInt(this.color);
|
||||
buf.writeBoolean(this.isLight);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String writeToString() {
|
||||
return String.format(Locale.ROOT, "%s %s", this.color, this.isLight);
|
||||
return String.format(Locale.ROOT, "%s %s", this.color);
|
||||
}
|
||||
|
||||
public static final Deserializer<ConjureParticleOptions> DESERIALIZER = new Deserializer<>() {
|
||||
|
@ -35,18 +34,14 @@ public record ConjureParticleOptions(int color, boolean isLight) implements Part
|
|||
|
||||
reader.expect(' ');
|
||||
var color = reader.readInt();
|
||||
reader.expect(' ');
|
||||
var isLight = reader.readBoolean();
|
||||
|
||||
return new ConjureParticleOptions(color, isLight);
|
||||
return new ConjureParticleOptions(color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConjureParticleOptions fromNetwork(ParticleType<ConjureParticleOptions> type,
|
||||
FriendlyByteBuf buf) {
|
||||
var col = buf.readInt();
|
||||
var isLight = buf.readBoolean();
|
||||
return new ConjureParticleOptions(col, isLight);
|
||||
return new ConjureParticleOptions(col);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -58,8 +53,7 @@ public record ConjureParticleOptions(int color, boolean isLight) implements Part
|
|||
public static final Codec<ConjureParticleOptions> CODEC = RecordCodecBuilder.create(
|
||||
instance -> instance.group(
|
||||
Codec.INT.fieldOf("color")
|
||||
.forGetter((ConjureParticleOptions o) -> o.color),
|
||||
Codec.BOOL.fieldOf("isLight").forGetter(ConjureParticleOptions::isLight)
|
||||
.forGetter((ConjureParticleOptions o) -> o.color)
|
||||
)
|
||||
.apply(instance, ConjureParticleOptions::new)
|
||||
);
|
||||
|
|
|
@ -2,7 +2,7 @@ package at.petrak.hexcasting.common.recipe;
|
|||
|
||||
import at.petrak.hexcasting.api.item.IotaHolderItem;
|
||||
import at.petrak.hexcasting.api.utils.NBTHelper;
|
||||
import at.petrak.hexcasting.common.items.ItemSpellbook;
|
||||
import at.petrak.hexcasting.common.items.storage.ItemSpellbook;
|
||||
import at.petrak.hexcasting.common.lib.HexItems;
|
||||
import at.petrak.hexcasting.xplat.IXplatAbstractions;
|
||||
import net.minecraft.core.NonNullList;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package at.petrak.hexcasting.common.recipe;
|
||||
|
||||
import at.petrak.hexcasting.api.mod.HexTags;
|
||||
import at.petrak.hexcasting.common.items.ItemFocus;
|
||||
import at.petrak.hexcasting.common.items.ItemSpellbook;
|
||||
import at.petrak.hexcasting.common.items.storage.ItemFocus;
|
||||
import at.petrak.hexcasting.common.items.storage.ItemSpellbook;
|
||||
import at.petrak.hexcasting.common.lib.HexItems;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.StringRepresentable;
|
||||
|
|
|
@ -21,6 +21,7 @@ import net.minecraft.world.level.block.state.properties.DoubleBlockHalf;
|
|||
import net.minecraft.world.level.block.state.properties.SlabType;
|
||||
import net.minecraft.world.level.storage.loot.LootPool;
|
||||
import net.minecraft.world.level.storage.loot.LootTable;
|
||||
import net.minecraft.world.level.storage.loot.entries.AlternativesEntry;
|
||||
import net.minecraft.world.level.storage.loot.entries.LootItem;
|
||||
import net.minecraft.world.level.storage.loot.functions.ApplyBonusCount;
|
||||
import net.minecraft.world.level.storage.loot.functions.ApplyExplosionDecay;
|
||||
|
@ -74,10 +75,10 @@ public class HexLootTables extends PaucalLootTableProvider {
|
|||
blockTables.put(HexBlocks.EDIFIED_DOOR, LootTable.lootTable().withPool(doorPool));
|
||||
|
||||
|
||||
var noSilkTouchCond = MatchTool.toolMatches(
|
||||
var silkTouchCond = MatchTool.toolMatches(
|
||||
ItemPredicate.Builder.item().hasEnchantment(
|
||||
new EnchantmentPredicate(Enchantments.SILK_TOUCH, MinMaxBounds.Ints.ANY)))
|
||||
.invert();
|
||||
new EnchantmentPredicate(Enchantments.SILK_TOUCH, MinMaxBounds.Ints.ANY)));
|
||||
var noSilkTouchCond = silkTouchCond.invert();
|
||||
var goodAtAmethystingCond = MatchTool.toolMatches(
|
||||
ItemPredicate.Builder.item().of(ItemTags.CLUSTER_MAX_HARVESTABLES)
|
||||
);
|
||||
|
@ -111,6 +112,18 @@ public class HexLootTables extends PaucalLootTableProvider {
|
|||
.withPool(dustPoolWhenBad)
|
||||
.withPool(isThatAnMFingBrandonSandersonReference)
|
||||
.withPool(isThatAnMFingBadBrandonSandersonReference));
|
||||
|
||||
// it looks like loot groups are bugged?
|
||||
// so instead we add some and then *increment* the amount, gated behind the cond
|
||||
var quenchedPool = LootPool.lootPool().add(AlternativesEntry.alternatives(
|
||||
LootItem.lootTableItem(HexBlocks.QUENCHED_ALLAY).when(silkTouchCond),
|
||||
LootItem.lootTableItem(HexItems.QUENCHED_SHARD)
|
||||
.apply(SetItemCountFunction.setCount(UniformGenerator.between(2f, 4f)))
|
||||
.apply(SetItemCountFunction.setCount(ConstantValue.exactly(1), true)
|
||||
.when(BonusLevelTableCondition.bonusLevelFlatChance(Enchantments.BLOCK_FORTUNE,
|
||||
0.25f, 0.5f, 0.75f, 1.0f)))
|
||||
));
|
||||
blockTables.put(HexBlocks.QUENCHED_ALLAY, LootTable.lootTable().withPool(quenchedPool));
|
||||
}
|
||||
|
||||
private void makeLeafTable(Map<Block, LootTable.Builder> lootTables, Block block) {
|
||||
|
|
|
@ -9,7 +9,6 @@ import at.petrak.hexcasting.common.lib.HexBlocks;
|
|||
import at.petrak.hexcasting.common.lib.HexItems;
|
||||
import at.petrak.hexcasting.common.recipe.SealThingsRecipe;
|
||||
import at.petrak.hexcasting.common.recipe.ingredient.StateIngredientHelper;
|
||||
import at.petrak.hexcasting.common.recipe.ingredient.brainsweep.EntityTagIngredient;
|
||||
import at.petrak.hexcasting.common.recipe.ingredient.brainsweep.EntityTypeIngredient;
|
||||
import at.petrak.hexcasting.common.recipe.ingredient.brainsweep.VillagerIngredient;
|
||||
import at.petrak.hexcasting.datagen.HexAdvancements;
|
||||
|
@ -25,8 +24,6 @@ import net.minecraft.data.DataGenerator;
|
|||
import net.minecraft.data.recipes.*;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.tags.BlockTags;
|
||||
import net.minecraft.tags.EntityTypeTags;
|
||||
import net.minecraft.tags.ItemTags;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.npc.VillagerProfession;
|
||||
|
@ -70,7 +67,14 @@ public class HexplatRecipes extends PaucalRecipeProvider {
|
|||
staffRecipe(recipes, HexItems.STAFF_WARPED, Items.WARPED_PLANKS);
|
||||
staffRecipe(recipes, HexItems.STAFF_MANGROVE, Items.MANGROVE_PLANKS);
|
||||
staffRecipe(recipes, HexItems.STAFF_EDIFIED, HexBlocks.EDIFIED_PLANKS.asItem());
|
||||
staffRecipe(recipes, HexItems.STAFF_QUENCHED, HexItems.QUENCHED_SHARD);
|
||||
staffRecipe(recipes, HexItems.STAFF_MINDSPLICE, Ingredient.of(HexTags.Items.MINDFLAYED_CIRCLE_COMPONENTS));
|
||||
|
||||
ShapelessRecipeBuilder.shapeless(HexItems.THOUGHT_KNOT)
|
||||
.requires(HexItems.AMETHYST_DUST)
|
||||
.requires(Items.STRING)
|
||||
.unlockedBy("has_item", hasItem(HexTags.Items.STAVES))
|
||||
.save(recipes);
|
||||
ShapedRecipeBuilder.shaped(HexItems.FOCUS)
|
||||
.define('G', ingredients.glowstoneDust())
|
||||
.define('L', ingredients.leather())
|
||||
|
@ -229,6 +233,25 @@ public class HexplatRecipes extends PaucalRecipeProvider {
|
|||
.pattern(" S ")
|
||||
.unlockedBy("has_item", hasItem(Items.AMETHYST_SHARD)).save(recipes);
|
||||
|
||||
ShapelessRecipeBuilder.shapeless(HexItems.AMETHYST_DUST,
|
||||
(MediaConstants.QUENCHED_SHARD_UNIT / MediaConstants.DUST_UNIT) + 1)
|
||||
.requires(HexItems.QUENCHED_SHARD)
|
||||
.requires(HexItems.AMETHYST_DUST)
|
||||
.unlockedBy("has_item", hasItem(HexItems.QUENCHED_SHARD))
|
||||
.save(recipes, modLoc("decompose_quenched_shard/dust"));
|
||||
ShapelessRecipeBuilder.shapeless(Items.AMETHYST_SHARD,
|
||||
(MediaConstants.QUENCHED_SHARD_UNIT / MediaConstants.SHARD_UNIT) + 1)
|
||||
.requires(HexItems.QUENCHED_SHARD)
|
||||
.requires(Items.AMETHYST_SHARD)
|
||||
.unlockedBy("has_item", hasItem(HexItems.QUENCHED_SHARD))
|
||||
.save(recipes, modLoc("decompose_quenched_shard/shard"));
|
||||
ShapelessRecipeBuilder.shapeless(HexItems.CHARGED_AMETHYST,
|
||||
(MediaConstants.QUENCHED_SHARD_UNIT / MediaConstants.CRYSTAL_UNIT) + 1)
|
||||
.requires(HexItems.QUENCHED_SHARD)
|
||||
.requires(HexItems.CHARGED_AMETHYST)
|
||||
.unlockedBy("has_item", hasItem(HexItems.QUENCHED_SHARD))
|
||||
.save(recipes, modLoc("decompose_quenched_shard/charged"));
|
||||
|
||||
ShapedRecipeBuilder.shaped(HexBlocks.SLATE_BLOCK)
|
||||
.define('S', HexItems.SLATE)
|
||||
.pattern("S")
|
||||
|
@ -413,16 +436,11 @@ public class HexplatRecipes extends PaucalRecipeProvider {
|
|||
.save(recipes, modLoc("brainsweep/akashic_record"));
|
||||
|
||||
// Temporary tests
|
||||
new BrainsweepRecipeBuilder(StateIngredientHelper.of(BlockTags.SMALL_FLOWERS),
|
||||
new BrainsweepRecipeBuilder(StateIngredientHelper.of(Blocks.AMETHYST_BLOCK),
|
||||
new EntityTypeIngredient(EntityType.ALLAY),
|
||||
Blocks.AMETHYST_CLUSTER.defaultBlockState(), MediaConstants.SHARD_UNIT)
|
||||
HexBlocks.QUENCHED_ALLAY.defaultBlockState(), MediaConstants.CRYSTAL_UNIT)
|
||||
.unlockedBy("enlightenment", enlightenment)
|
||||
.save(recipes, modLoc("brainsweep/testing/flowey_the_flower"));
|
||||
new BrainsweepRecipeBuilder(StateIngredientHelper.of(Blocks.SCAFFOLDING),
|
||||
new EntityTagIngredient(EntityTypeTags.SKELETONS),
|
||||
Blocks.BONE_BLOCK.defaultBlockState(), MediaConstants.SHARD_UNIT)
|
||||
.unlockedBy("enlightenment", enlightenment)
|
||||
.save(recipes, modLoc("brainsweep/testing/bad_to_the_bone"));
|
||||
.save(recipes, modLoc("brainsweep/quench_allay"));
|
||||
|
||||
// Create compat
|
||||
this.conditions.apply(new CreateCrushingRecipeBuilder()
|
||||
|
@ -485,6 +503,10 @@ public class HexplatRecipes extends PaucalRecipeProvider {
|
|||
}
|
||||
|
||||
private void staffRecipe(Consumer<FinishedRecipe> recipes, ItemStaff staff, Item plank) {
|
||||
staffRecipe(recipes, staff, Ingredient.of(plank));
|
||||
}
|
||||
|
||||
private void staffRecipe(Consumer<FinishedRecipe> recipes, ItemStaff staff, Ingredient plank) {
|
||||
ShapedRecipeBuilder.shaped(staff)
|
||||
.define('W', plank)
|
||||
.define('S', Items.STICK)
|
||||
|
|
|
@ -17,12 +17,21 @@ public class HexBlockTagProvider extends PaucalBlockTagProvider {
|
|||
|
||||
@Override
|
||||
public void addTags() {
|
||||
tag(HexTags.Blocks.IMPETI)
|
||||
.add(HexBlocks.IMPETUS_LOOK, HexBlocks.IMPETUS_RIGHTCLICK, HexBlocks.IMPETUS_STOREDPLAYER);
|
||||
tag(HexTags.Blocks.DIRECTRICES)
|
||||
.add(HexBlocks.DIRECTRIX_REDSTONE);
|
||||
tag(HexTags.Blocks.MINDFLAYED_CIRCLE_COMPONENTS)
|
||||
.addTag(HexTags.Blocks.IMPETI)
|
||||
.addTag(HexTags.Blocks.DIRECTRICES);
|
||||
|
||||
tag(BlockTags.MINEABLE_WITH_PICKAXE)
|
||||
.add(HexBlocks.SLATE_BLOCK, HexBlocks.SLATE,
|
||||
HexBlocks.EMPTY_DIRECTRIX, HexBlocks.DIRECTRIX_REDSTONE,
|
||||
HexBlocks.EMPTY_IMPETUS,
|
||||
HexBlocks.IMPETUS_RIGHTCLICK, HexBlocks.IMPETUS_LOOK, HexBlocks.IMPETUS_STOREDPLAYER,
|
||||
HexBlocks.AMETHYST_TILES, HexBlocks.SCONCE);
|
||||
HexBlocks.AMETHYST_TILES, HexBlocks.SCONCE,
|
||||
HexBlocks.QUENCHED_ALLAY);
|
||||
|
||||
tag(BlockTags.MINEABLE_WITH_SHOVEL)
|
||||
.add(HexBlocks.AMETHYST_DUST_BLOCK);
|
||||
|
|
|
@ -27,7 +27,8 @@ public class HexItemTagProvider extends PaucalItemTagProvider {
|
|||
tag(HexTags.Items.STAVES).add(HexItems.STAFF_EDIFIED,
|
||||
HexItems.STAFF_OAK, HexItems.STAFF_SPRUCE, HexItems.STAFF_BIRCH,
|
||||
HexItems.STAFF_JUNGLE, HexItems.STAFF_ACACIA, HexItems.STAFF_DARK_OAK,
|
||||
HexItems.STAFF_CRIMSON, HexItems.STAFF_WARPED, HexItems.STAFF_MANGROVE);
|
||||
HexItems.STAFF_CRIMSON, HexItems.STAFF_WARPED, HexItems.STAFF_MANGROVE,
|
||||
HexItems.STAFF_QUENCHED, HexItems.STAFF_MINDSPLICE);
|
||||
|
||||
tag(HexTags.Items.PHIAL_BASE).add(Items.GLASS_BOTTLE);
|
||||
tag(HexTags.Items.GRANTS_ROOT_ADVANCEMENT).add(HexItems.AMETHYST_DUST, Items.AMETHYST_SHARD,
|
||||
|
@ -36,6 +37,9 @@ public class HexItemTagProvider extends PaucalItemTagProvider {
|
|||
|
||||
this.copy(HexTags.Blocks.EDIFIED_LOGS, HexTags.Items.EDIFIED_LOGS);
|
||||
this.copy(HexTags.Blocks.EDIFIED_PLANKS, HexTags.Items.EDIFIED_PLANKS);
|
||||
this.copy(HexTags.Blocks.IMPETI, HexTags.Items.IMPETI);
|
||||
this.copy(HexTags.Blocks.DIRECTRICES, HexTags.Items.DIRECTRICES);
|
||||
this.copy(HexTags.Blocks.MINDFLAYED_CIRCLE_COMPONENTS, HexTags.Items.MINDFLAYED_CIRCLE_COMPONENTS);
|
||||
this.copy(BlockTags.LOGS_THAT_BURN, ItemTags.LOGS_THAT_BURN);
|
||||
this.copy(BlockTags.LOGS, ItemTags.LOGS);
|
||||
this.copy(BlockTags.PLANKS, ItemTags.PLANKS);
|
||||
|
|
|
@ -2,7 +2,7 @@ package at.petrak.hexcasting.interop.patchouli;
|
|||
|
||||
import at.petrak.hexcasting.api.casting.math.HexCoord;
|
||||
import at.petrak.hexcasting.api.casting.math.HexPattern;
|
||||
import at.petrak.hexcasting.client.RenderLib;
|
||||
import at.petrak.hexcasting.client.render.RenderLib;
|
||||
import at.petrak.hexcasting.interop.utils.PatternDrawingUtil;
|
||||
import at.petrak.hexcasting.interop.utils.PatternEntry;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
|
|
|
@ -3,7 +3,7 @@ package at.petrak.hexcasting.interop.utils;
|
|||
import at.petrak.hexcasting.api.casting.math.HexCoord;
|
||||
import at.petrak.hexcasting.api.casting.math.HexPattern;
|
||||
import at.petrak.hexcasting.api.utils.HexUtils;
|
||||
import at.petrak.hexcasting.client.RenderLib;
|
||||
import at.petrak.hexcasting.client.render.RenderLib;
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
package at.petrak.hexcasting.mixin.accessor.client;
|
||||
|
||||
import net.minecraft.client.renderer.block.BlockRenderDispatcher;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRenderDispatcher;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Mixin(BlockEntityRenderDispatcher.class)
|
||||
public interface AccessorBlockEntityRenderDispatcher {
|
||||
@Accessor("blockRenderDispatcher")
|
||||
Supplier<BlockRenderDispatcher> hex$getBlockRenderDispatcher();
|
||||
}
|
|
@ -21,14 +21,16 @@ import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
|||
public abstract class MixinClientLevel {
|
||||
|
||||
@Inject(method = "doAnimateTick",
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/Block;animateTick(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/util/RandomSource;)V"),
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/Block;animateTick" +
|
||||
"(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/Level;" +
|
||||
"Lnet/minecraft/core/BlockPos;Lnet/minecraft/util/RandomSource;)V"),
|
||||
locals = LocalCapture.CAPTURE_FAILSOFT)
|
||||
public void addBuddingAmethystParticles(int $$0, int $$1, int $$2, int $$3, RandomSource rand, Block $$5,
|
||||
BlockPos.MutableBlockPos pos, CallbackInfo ci, int trueX, int trueY, int trueZ, BlockState state) {
|
||||
ClientLevel self = ((ClientLevel) (Object) this);
|
||||
|
||||
if (state.is(Blocks.BUDDING_AMETHYST)) {
|
||||
ParticleOptions options = new ConjureParticleOptions(0x8932b8, true);
|
||||
ParticleOptions options = new ConjureParticleOptions(0x8932b8);
|
||||
Vec3 center = Vec3.atCenterOf(pos);
|
||||
for (Direction direction : Direction.values()) {
|
||||
int dX = direction.getStepX();
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue