From de5b422a41bd5c03f445cbe24b856f3434c5afc1 Mon Sep 17 00:00:00 2001 From: WayofTime Date: Sun, 8 Nov 2020 21:35:26 -0500 Subject: [PATCH] Reimplemented Sentient Tools Reimplemented the Sentient Axe, Pickaxe, and Shovel, as well as fixed the ability for the sentient weaponry to drop aspected Will. --- src/generated/resources/.cache/cache | 23 +- .../assets/bloodmagic/lang/en_us.json | 3 + .../bloodmagic/models/item/soulaxe.json | 34 ++ .../bloodmagic/models/item/soulpickaxe.json | 34 ++ .../bloodmagic/models/item/soulshovel.json | 34 ++ .../models/item/variants/soulaxe.json | 6 + .../item/variants/soulaxe_corrosive.json | 6 + .../item/variants/soulaxe_destructive.json | 6 + .../item/variants/soulaxe_steadfast.json | 6 + .../item/variants/soulaxe_vengeful.json | 6 + .../models/item/variants/soulpickaxe.json | 6 + .../item/variants/soulpickaxe_corrosive.json | 6 + .../variants/soulpickaxe_destructive.json | 6 + .../item/variants/soulpickaxe_steadfast.json | 6 + .../item/variants/soulpickaxe_vengeful.json | 6 + .../models/item/variants/soulshovel.json | 6 + .../item/variants/soulshovel_corrosive.json | 6 + .../item/variants/soulshovel_destructive.json | 6 + .../item/variants/soulshovel_steadfast.json | 6 + .../item/variants/soulshovel_vengeful.json | 6 + .../recipes/soulforge/sentientaxe.json | 15 + .../recipes/soulforge/sentientpickaxe.json | 15 + .../recipes/soulforge/sentientshovel.json | 15 + .../bloodmagic/client/ClientEvents.java | 3 + .../common/data/GeneratorItemModels.java | 21 + .../common/data/GeneratorLanguage.java | 3 + .../common/item/BloodMagicItems.java | 6 + .../common/item/soul/ItemSentientAxe.java | 555 +++++++++++++++++ .../common/item/soul/ItemSentientPickaxe.java | 557 +++++++++++++++++ .../common/item/soul/ItemSentientShovel.java | 558 ++++++++++++++++++ .../common/item/soul/ItemSentientSword.java | 20 +- .../recipe/TartaricForgeRecipeProvider.java | 3 + 32 files changed, 1987 insertions(+), 2 deletions(-) create mode 100644 src/generated/resources/assets/bloodmagic/models/item/soulaxe.json create mode 100644 src/generated/resources/assets/bloodmagic/models/item/soulpickaxe.json create mode 100644 src/generated/resources/assets/bloodmagic/models/item/soulshovel.json create mode 100644 src/generated/resources/assets/bloodmagic/models/item/variants/soulaxe.json create mode 100644 src/generated/resources/assets/bloodmagic/models/item/variants/soulaxe_corrosive.json create mode 100644 src/generated/resources/assets/bloodmagic/models/item/variants/soulaxe_destructive.json create mode 100644 src/generated/resources/assets/bloodmagic/models/item/variants/soulaxe_steadfast.json create mode 100644 src/generated/resources/assets/bloodmagic/models/item/variants/soulaxe_vengeful.json create mode 100644 src/generated/resources/assets/bloodmagic/models/item/variants/soulpickaxe.json create mode 100644 src/generated/resources/assets/bloodmagic/models/item/variants/soulpickaxe_corrosive.json create mode 100644 src/generated/resources/assets/bloodmagic/models/item/variants/soulpickaxe_destructive.json create mode 100644 src/generated/resources/assets/bloodmagic/models/item/variants/soulpickaxe_steadfast.json create mode 100644 src/generated/resources/assets/bloodmagic/models/item/variants/soulpickaxe_vengeful.json create mode 100644 src/generated/resources/assets/bloodmagic/models/item/variants/soulshovel.json create mode 100644 src/generated/resources/assets/bloodmagic/models/item/variants/soulshovel_corrosive.json create mode 100644 src/generated/resources/assets/bloodmagic/models/item/variants/soulshovel_destructive.json create mode 100644 src/generated/resources/assets/bloodmagic/models/item/variants/soulshovel_steadfast.json create mode 100644 src/generated/resources/assets/bloodmagic/models/item/variants/soulshovel_vengeful.json create mode 100644 src/generated/resources/data/bloodmagic/recipes/soulforge/sentientaxe.json create mode 100644 src/generated/resources/data/bloodmagic/recipes/soulforge/sentientpickaxe.json create mode 100644 src/generated/resources/data/bloodmagic/recipes/soulforge/sentientshovel.json create mode 100644 src/main/java/wayoftime/bloodmagic/common/item/soul/ItemSentientAxe.java create mode 100644 src/main/java/wayoftime/bloodmagic/common/item/soul/ItemSentientPickaxe.java create mode 100644 src/main/java/wayoftime/bloodmagic/common/item/soul/ItemSentientShovel.java diff --git a/src/generated/resources/.cache/cache b/src/generated/resources/.cache/cache index f15f91d3..1c80a1da 100644 --- a/src/generated/resources/.cache/cache +++ b/src/generated/resources/.cache/cache @@ -25,7 +25,7 @@ b03040d7a168653bf8df3600033b8fde2383db30 assets/bloodmagic/blockstates/selfsacri f1ca47098385a955155cab9c2a97219e02d390a0 assets/bloodmagic/blockstates/steadfastdemoncrystal.json 48ed6b25a5d8d8074c38d772fdc27c1753d42c36 assets/bloodmagic/blockstates/vengefuldemoncrystal.json e6d9cf699667aaa47efff37b2b033895dee29c15 assets/bloodmagic/blockstates/waterritualstone.json -d6115a34fd581edc2112a9b9e25bfda52468377f assets/bloodmagic/lang/en_us.json +271eafb345e1acb8080dfe6c74dded0175d29150 assets/bloodmagic/lang/en_us.json 34445195b9f2459475cde53454bc8e37d32865d7 assets/bloodmagic/models/block/accelerationrune.json bcdbccc49d4509571be6988762ab87126275a4c8 assets/bloodmagic/models/block/airritualstone.json adf6c0b1e25451609486dc8c8cfbd9cf0f8c67f4 assets/bloodmagic/models/block/alchemicalreactionchamber.json @@ -167,10 +167,13 @@ b23b701e93011247714ebdaffd6d52e918ba3d8a assets/bloodmagic/models/item/saltpeter b8582a5cd6ca35279e9b35931f1c5ca089b094b8 assets/bloodmagic/models/item/sanguinereverter.json cc71421e98ee7ee047a4cfbb6cb69529c2b02d4e assets/bloodmagic/models/item/selfsacrificerune.json ea5747638d0b5dcc03f008b202cc60a11e0827bb assets/bloodmagic/models/item/sigilofmagnetism.json +db0f63198089161b8d4ecfb1ec8a45f7dc5ba83d assets/bloodmagic/models/item/soulaxe.json 9ec68a2dcf04b987c3c5d5c6c52195e3deccacbb assets/bloodmagic/models/item/soulgemcommon.json 6501bb4b72457e8107bec818f26de6178b655203 assets/bloodmagic/models/item/soulgemgreater.json ad010d9680cd748bd04c8fc36262c236f7d90105 assets/bloodmagic/models/item/soulgemlesser.json b49e7f34913e32ccb68eeb6f6c196ff6b209f482 assets/bloodmagic/models/item/soulgempetty.json +c873e91c70eef9ad4c39aeb2fe8b9aa16a26cccd assets/bloodmagic/models/item/soulpickaxe.json +bde2befafc97fd89a428dfa3f39fc970e9a3ae29 assets/bloodmagic/models/item/soulshovel.json f8db155d49b0f2c37504bac46a8974d4bf90db3e assets/bloodmagic/models/item/soulsnare.json fe2b201007c974229509f6900c6eb8b03d158b0a assets/bloodmagic/models/item/soulsword.json 52d21027ac6fed000e77b5e8ad9102319b25cb33 assets/bloodmagic/models/item/speedrune.json @@ -185,6 +188,11 @@ be3772fd711ccf4a2adfad122a8b39e8a36e874a assets/bloodmagic/models/item/variants/ 7dec45f3167426d975564692a80196cdb3f4bdb4 assets/bloodmagic/models/item/variants/miningsigil_deactivated.json 79c61e61656a934397c92626809c1869b0617fc3 assets/bloodmagic/models/item/variants/sigilofmagnetism_activated.json 129ace1f4a25f22bd09215603248a25adcf234e0 assets/bloodmagic/models/item/variants/sigilofmagnetism_deactivated.json +81e1cb0664f53f30ad195fc4330786b71db9e20c assets/bloodmagic/models/item/variants/soulaxe.json +2254b45194021cdd3fbc7d384d958b031a8e7cea assets/bloodmagic/models/item/variants/soulaxe_corrosive.json +c11750d01a720a1b0eca0610ec12cba0fef4d5da assets/bloodmagic/models/item/variants/soulaxe_destructive.json +368e428410c7c6d6bf444970221bb5ebe5f6bacd assets/bloodmagic/models/item/variants/soulaxe_steadfast.json +267875926ed261400a10371e044e9f54aafa637a assets/bloodmagic/models/item/variants/soulaxe_vengeful.json cddaa2be8db3aff90933fb772b92cab735ebf11e assets/bloodmagic/models/item/variants/soulgemcommon.json 874aa708d02de2315e29033b2f67fd313edc8aff assets/bloodmagic/models/item/variants/soulgemcommon_corrosive.json 3ca3c4251a8907c1c47caf49e53a711265e0e92c assets/bloodmagic/models/item/variants/soulgemcommon_destructive.json @@ -205,6 +213,16 @@ fb9e51a933316daa4a99b6e6c9a2606dc354f0dc assets/bloodmagic/models/item/variants/ 0a15d2c90a8d139c1689579460379e5feefaddec assets/bloodmagic/models/item/variants/soulgempetty_destructive.json a94516c3019969baa379f4a32d68736010cb473a assets/bloodmagic/models/item/variants/soulgempetty_steadfast.json eabd2e88451ef42250e86c6675868b322aa0db92 assets/bloodmagic/models/item/variants/soulgempetty_vengeful.json +cebb0537b96480ac99314840a45107108b1bbc3a assets/bloodmagic/models/item/variants/soulpickaxe.json +2045e6593e80a11da9c60d0bdcef456503141232 assets/bloodmagic/models/item/variants/soulpickaxe_corrosive.json +37144adb7eb312c66a3567faeb3ece5aeef76e70 assets/bloodmagic/models/item/variants/soulpickaxe_destructive.json +e09d7927fdb84c372d36b290e3c69f728c922675 assets/bloodmagic/models/item/variants/soulpickaxe_steadfast.json +bec6cecf74db6a32fb5890b0596ddb7e2bf2daef assets/bloodmagic/models/item/variants/soulpickaxe_vengeful.json +501142d1ff49eaf663e9a2044da17b8b5a25e361 assets/bloodmagic/models/item/variants/soulshovel.json +f65e2a2d4f0cae6c3dc986274c2dee0f1773cfb2 assets/bloodmagic/models/item/variants/soulshovel_corrosive.json +6c6b04b81358bb82b4d127fc621190dc2804fd45 assets/bloodmagic/models/item/variants/soulshovel_destructive.json +0e193ee2b27783f3d10461977c7d719be96af203 assets/bloodmagic/models/item/variants/soulshovel_steadfast.json +a8a7f03cc24f0d796e8868ace72f50ec4343dd5b assets/bloodmagic/models/item/variants/soulshovel_vengeful.json 0cd32e8e693d85b8a81e96ea305ffafb4a72e861 assets/bloodmagic/models/item/variants/soulsword_activated.json 60831276c8b0a5ecfa8e1a7beee6c5a4838cae69 assets/bloodmagic/models/item/variants/soulsword_corrosive_activated.json 792bb3a3e613808890cf0c31585318dc8e16891d assets/bloodmagic/models/item/variants/soulsword_corrosive_deactivated.json @@ -390,6 +408,9 @@ e517023dc3e32929344ff5415397fc833bfbc29a data/bloodmagic/recipes/soulforge/reage c0e75e0e12290d191245c5b0b5b13bc739d2ff44 data/bloodmagic/recipes/soulforge/reagent_void.json a222d09abf1ea61feb684f2ac23d011c2034f526 data/bloodmagic/recipes/soulforge/reagent_water.json 4a4340f334c51beaacb77fd201298ad94b71e79c data/bloodmagic/recipes/soulforge/sanguine_reverter.json +799c9b83373966f70bbd6777cdae0ff2ff89fd84 data/bloodmagic/recipes/soulforge/sentientaxe.json +6d94372ffffbe36ca91ed2a5e46991bff896726c data/bloodmagic/recipes/soulforge/sentientpickaxe.json +6dcced40126f950b85f868aa04c77e90b71b69f2 data/bloodmagic/recipes/soulforge/sentientshovel.json 7e281841a2953c1284d332c2bbf75097f8128241 data/bloodmagic/recipes/soulforge/sentientsword.json c4102a1573e632d0b9f894353b0d522a51a7c65e data/bloodmagic/recipes/soulforge/steadfast_crystal_block.json 3aa852edda803a2225ebe53d2daa55bd46b0a1b9 data/bloodmagic/recipes/soulforge/vengeful_crystal_block.json diff --git a/src/generated/resources/assets/bloodmagic/lang/en_us.json b/src/generated/resources/assets/bloodmagic/lang/en_us.json index 3c491f6b..32eb1978 100644 --- a/src/generated/resources/assets/bloodmagic/lang/en_us.json +++ b/src/generated/resources/assets/bloodmagic/lang/en_us.json @@ -101,10 +101,13 @@ "item.bloodmagic.saltpeter": "Saltpeter", "item.bloodmagic.sanguinereverter": "Sanguine Reverter", "item.bloodmagic.sigilofmagnetism": "Sigil of Magnetism", + "item.bloodmagic.soulaxe": "Sentient Axe", "item.bloodmagic.soulgemcommon": "Common Tartaric Gem", "item.bloodmagic.soulgemgreater": "Greater Tartaric Gem", "item.bloodmagic.soulgemlesser": "Lesser Tartaric Gem", "item.bloodmagic.soulgempetty": "Petty Tartaric Gem", + "item.bloodmagic.soulpickaxe": "Sentient Pickaxe", + "item.bloodmagic.soulshovel": "Sentient Shovel", "item.bloodmagic.soulsnare": "Soul Snare", "item.bloodmagic.soulsword": "Sentient Sword", "item.bloodmagic.steadfastcrystal": "Steadfast Will Crystal", diff --git a/src/generated/resources/assets/bloodmagic/models/item/soulaxe.json b/src/generated/resources/assets/bloodmagic/models/item/soulaxe.json new file mode 100644 index 00000000..7a752a51 --- /dev/null +++ b/src/generated/resources/assets/bloodmagic/models/item/soulaxe.json @@ -0,0 +1,34 @@ +{ + "overrides": [ + { + "predicate": { + "bloodmagic:type": 0.0 + }, + "model": "bloodmagic:item/variants/soulaxe" + }, + { + "predicate": { + "bloodmagic:type": 1.0 + }, + "model": "bloodmagic:item/variants/soulaxe_corrosive" + }, + { + "predicate": { + "bloodmagic:type": 2.0 + }, + "model": "bloodmagic:item/variants/soulaxe_destructive" + }, + { + "predicate": { + "bloodmagic:type": 3.0 + }, + "model": "bloodmagic:item/variants/soulaxe_vengeful" + }, + { + "predicate": { + "bloodmagic:type": 4.0 + }, + "model": "bloodmagic:item/variants/soulaxe_steadfast" + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/assets/bloodmagic/models/item/soulpickaxe.json b/src/generated/resources/assets/bloodmagic/models/item/soulpickaxe.json new file mode 100644 index 00000000..14619409 --- /dev/null +++ b/src/generated/resources/assets/bloodmagic/models/item/soulpickaxe.json @@ -0,0 +1,34 @@ +{ + "overrides": [ + { + "predicate": { + "bloodmagic:type": 0.0 + }, + "model": "bloodmagic:item/variants/soulpickaxe" + }, + { + "predicate": { + "bloodmagic:type": 1.0 + }, + "model": "bloodmagic:item/variants/soulpickaxe_corrosive" + }, + { + "predicate": { + "bloodmagic:type": 2.0 + }, + "model": "bloodmagic:item/variants/soulpickaxe_destructive" + }, + { + "predicate": { + "bloodmagic:type": 3.0 + }, + "model": "bloodmagic:item/variants/soulpickaxe_vengeful" + }, + { + "predicate": { + "bloodmagic:type": 4.0 + }, + "model": "bloodmagic:item/variants/soulpickaxe_steadfast" + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/assets/bloodmagic/models/item/soulshovel.json b/src/generated/resources/assets/bloodmagic/models/item/soulshovel.json new file mode 100644 index 00000000..b6d3c67e --- /dev/null +++ b/src/generated/resources/assets/bloodmagic/models/item/soulshovel.json @@ -0,0 +1,34 @@ +{ + "overrides": [ + { + "predicate": { + "bloodmagic:type": 0.0 + }, + "model": "bloodmagic:item/variants/soulshovel" + }, + { + "predicate": { + "bloodmagic:type": 1.0 + }, + "model": "bloodmagic:item/variants/soulshovel_corrosive" + }, + { + "predicate": { + "bloodmagic:type": 2.0 + }, + "model": "bloodmagic:item/variants/soulshovel_destructive" + }, + { + "predicate": { + "bloodmagic:type": 3.0 + }, + "model": "bloodmagic:item/variants/soulshovel_vengeful" + }, + { + "predicate": { + "bloodmagic:type": 4.0 + }, + "model": "bloodmagic:item/variants/soulshovel_steadfast" + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/assets/bloodmagic/models/item/variants/soulaxe.json b/src/generated/resources/assets/bloodmagic/models/item/variants/soulaxe.json new file mode 100644 index 00000000..30fdc78b --- /dev/null +++ b/src/generated/resources/assets/bloodmagic/models/item/variants/soulaxe.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/handheld", + "textures": { + "layer0": "bloodmagic:item/soulaxe" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/bloodmagic/models/item/variants/soulaxe_corrosive.json b/src/generated/resources/assets/bloodmagic/models/item/variants/soulaxe_corrosive.json new file mode 100644 index 00000000..a55f906f --- /dev/null +++ b/src/generated/resources/assets/bloodmagic/models/item/variants/soulaxe_corrosive.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/handheld", + "textures": { + "layer0": "bloodmagic:item/soulaxe_corrosive" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/bloodmagic/models/item/variants/soulaxe_destructive.json b/src/generated/resources/assets/bloodmagic/models/item/variants/soulaxe_destructive.json new file mode 100644 index 00000000..8df2b5f9 --- /dev/null +++ b/src/generated/resources/assets/bloodmagic/models/item/variants/soulaxe_destructive.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/handheld", + "textures": { + "layer0": "bloodmagic:item/soulaxe_destructive" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/bloodmagic/models/item/variants/soulaxe_steadfast.json b/src/generated/resources/assets/bloodmagic/models/item/variants/soulaxe_steadfast.json new file mode 100644 index 00000000..d67ffdc2 --- /dev/null +++ b/src/generated/resources/assets/bloodmagic/models/item/variants/soulaxe_steadfast.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/handheld", + "textures": { + "layer0": "bloodmagic:item/soulaxe_steadfast" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/bloodmagic/models/item/variants/soulaxe_vengeful.json b/src/generated/resources/assets/bloodmagic/models/item/variants/soulaxe_vengeful.json new file mode 100644 index 00000000..57f65f4c --- /dev/null +++ b/src/generated/resources/assets/bloodmagic/models/item/variants/soulaxe_vengeful.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/handheld", + "textures": { + "layer0": "bloodmagic:item/soulaxe_vengeful" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/bloodmagic/models/item/variants/soulpickaxe.json b/src/generated/resources/assets/bloodmagic/models/item/variants/soulpickaxe.json new file mode 100644 index 00000000..fe117924 --- /dev/null +++ b/src/generated/resources/assets/bloodmagic/models/item/variants/soulpickaxe.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/handheld", + "textures": { + "layer0": "bloodmagic:item/soulpickaxe" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/bloodmagic/models/item/variants/soulpickaxe_corrosive.json b/src/generated/resources/assets/bloodmagic/models/item/variants/soulpickaxe_corrosive.json new file mode 100644 index 00000000..1e88cff5 --- /dev/null +++ b/src/generated/resources/assets/bloodmagic/models/item/variants/soulpickaxe_corrosive.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/handheld", + "textures": { + "layer0": "bloodmagic:item/soulpickaxe_corrosive" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/bloodmagic/models/item/variants/soulpickaxe_destructive.json b/src/generated/resources/assets/bloodmagic/models/item/variants/soulpickaxe_destructive.json new file mode 100644 index 00000000..2aaac132 --- /dev/null +++ b/src/generated/resources/assets/bloodmagic/models/item/variants/soulpickaxe_destructive.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/handheld", + "textures": { + "layer0": "bloodmagic:item/soulpickaxe_destructive" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/bloodmagic/models/item/variants/soulpickaxe_steadfast.json b/src/generated/resources/assets/bloodmagic/models/item/variants/soulpickaxe_steadfast.json new file mode 100644 index 00000000..8f6ed094 --- /dev/null +++ b/src/generated/resources/assets/bloodmagic/models/item/variants/soulpickaxe_steadfast.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/handheld", + "textures": { + "layer0": "bloodmagic:item/soulpickaxe_steadfast" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/bloodmagic/models/item/variants/soulpickaxe_vengeful.json b/src/generated/resources/assets/bloodmagic/models/item/variants/soulpickaxe_vengeful.json new file mode 100644 index 00000000..bd938ace --- /dev/null +++ b/src/generated/resources/assets/bloodmagic/models/item/variants/soulpickaxe_vengeful.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/handheld", + "textures": { + "layer0": "bloodmagic:item/soulpickaxe_vengeful" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/bloodmagic/models/item/variants/soulshovel.json b/src/generated/resources/assets/bloodmagic/models/item/variants/soulshovel.json new file mode 100644 index 00000000..ad3f0972 --- /dev/null +++ b/src/generated/resources/assets/bloodmagic/models/item/variants/soulshovel.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/handheld", + "textures": { + "layer0": "bloodmagic:item/soulshovel" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/bloodmagic/models/item/variants/soulshovel_corrosive.json b/src/generated/resources/assets/bloodmagic/models/item/variants/soulshovel_corrosive.json new file mode 100644 index 00000000..93b102a0 --- /dev/null +++ b/src/generated/resources/assets/bloodmagic/models/item/variants/soulshovel_corrosive.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/handheld", + "textures": { + "layer0": "bloodmagic:item/soulshovel_corrosive" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/bloodmagic/models/item/variants/soulshovel_destructive.json b/src/generated/resources/assets/bloodmagic/models/item/variants/soulshovel_destructive.json new file mode 100644 index 00000000..34bbd132 --- /dev/null +++ b/src/generated/resources/assets/bloodmagic/models/item/variants/soulshovel_destructive.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/handheld", + "textures": { + "layer0": "bloodmagic:item/soulshovel_destructive" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/bloodmagic/models/item/variants/soulshovel_steadfast.json b/src/generated/resources/assets/bloodmagic/models/item/variants/soulshovel_steadfast.json new file mode 100644 index 00000000..3da6185d --- /dev/null +++ b/src/generated/resources/assets/bloodmagic/models/item/variants/soulshovel_steadfast.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/handheld", + "textures": { + "layer0": "bloodmagic:item/soulshovel_steadfast" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/bloodmagic/models/item/variants/soulshovel_vengeful.json b/src/generated/resources/assets/bloodmagic/models/item/variants/soulshovel_vengeful.json new file mode 100644 index 00000000..2a9bbdf2 --- /dev/null +++ b/src/generated/resources/assets/bloodmagic/models/item/variants/soulshovel_vengeful.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/handheld", + "textures": { + "layer0": "bloodmagic:item/soulshovel_vengeful" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/bloodmagic/recipes/soulforge/sentientaxe.json b/src/generated/resources/data/bloodmagic/recipes/soulforge/sentientaxe.json new file mode 100644 index 00000000..ee04cc66 --- /dev/null +++ b/src/generated/resources/data/bloodmagic/recipes/soulforge/sentientaxe.json @@ -0,0 +1,15 @@ +{ + "type": "bloodmagic:soulforge", + "input0": { + "item": "bloodmagic:soulgempetty" + }, + "input1": { + "item": "minecraft:iron_axe" + }, + "output": { + "item": "bloodmagic:soulaxe", + "nbt": "{Damage:0}" + }, + "minimumDrain": 0.0, + "drain": 0.0 +} \ No newline at end of file diff --git a/src/generated/resources/data/bloodmagic/recipes/soulforge/sentientpickaxe.json b/src/generated/resources/data/bloodmagic/recipes/soulforge/sentientpickaxe.json new file mode 100644 index 00000000..c553a505 --- /dev/null +++ b/src/generated/resources/data/bloodmagic/recipes/soulforge/sentientpickaxe.json @@ -0,0 +1,15 @@ +{ + "type": "bloodmagic:soulforge", + "input0": { + "item": "bloodmagic:soulgempetty" + }, + "input1": { + "item": "minecraft:iron_pickaxe" + }, + "output": { + "item": "bloodmagic:soulpickaxe", + "nbt": "{Damage:0}" + }, + "minimumDrain": 0.0, + "drain": 0.0 +} \ No newline at end of file diff --git a/src/generated/resources/data/bloodmagic/recipes/soulforge/sentientshovel.json b/src/generated/resources/data/bloodmagic/recipes/soulforge/sentientshovel.json new file mode 100644 index 00000000..205d060e --- /dev/null +++ b/src/generated/resources/data/bloodmagic/recipes/soulforge/sentientshovel.json @@ -0,0 +1,15 @@ +{ + "type": "bloodmagic:soulforge", + "input0": { + "item": "bloodmagic:soulgempetty" + }, + "input1": { + "item": "minecraft:iron_shovel" + }, + "output": { + "item": "bloodmagic:soulshovel", + "nbt": "{Damage:0}" + }, + "minimumDrain": 0.0, + "drain": 0.0 +} \ No newline at end of file diff --git a/src/main/java/wayoftime/bloodmagic/client/ClientEvents.java b/src/main/java/wayoftime/bloodmagic/client/ClientEvents.java index 53d4dd9d..b4b33440 100644 --- a/src/main/java/wayoftime/bloodmagic/client/ClientEvents.java +++ b/src/main/java/wayoftime/bloodmagic/client/ClientEvents.java @@ -72,6 +72,9 @@ public class ClientEvents registerToggleableProperties(BloodMagicItems.MAGNETISM_SIGIL.get()); registerToggleableProperties(BloodMagicItems.ICE_SIGIL.get()); registerMultiWillTool(BloodMagicItems.SENTIENT_SWORD.get()); + registerMultiWillTool(BloodMagicItems.SENTIENT_AXE.get()); + registerMultiWillTool(BloodMagicItems.SENTIENT_PICKAXE.get()); + registerMultiWillTool(BloodMagicItems.SENTIENT_SHOVEL.get()); registerMultiWillTool(BloodMagicItems.PETTY_GEM.get()); registerMultiWillTool(BloodMagicItems.LESSER_GEM.get()); registerMultiWillTool(BloodMagicItems.COMMON_GEM.get()); diff --git a/src/main/java/wayoftime/bloodmagic/common/data/GeneratorItemModels.java b/src/main/java/wayoftime/bloodmagic/common/data/GeneratorItemModels.java index 026a575f..ef2d5612 100644 --- a/src/main/java/wayoftime/bloodmagic/common/data/GeneratorItemModels.java +++ b/src/main/java/wayoftime/bloodmagic/common/data/GeneratorItemModels.java @@ -60,6 +60,9 @@ public class GeneratorItemModels extends ItemModelProvider registerDemonWillVariantItem(BloodMagicItems.COMMON_GEM.get()); registerDemonWillVariantItem(BloodMagicItems.GREATER_GEM.get()); registerDemonSword(BloodMagicItems.SENTIENT_SWORD.get()); + registerDemonTool(BloodMagicItems.SENTIENT_AXE.get()); + registerDemonTool(BloodMagicItems.SENTIENT_PICKAXE.get()); + registerDemonTool(BloodMagicItems.SENTIENT_SHOVEL.get()); } private void registerCustomBlockPath(Block block, String newPath) @@ -124,4 +127,22 @@ public class GeneratorItemModels extends ItemModelProvider } } } + + private void registerDemonTool(Item item) + { + String path = item.getRegistryName().getPath(); + ItemModelBuilder builder = getBuilder(path); + + for (EnumDemonWillType type : EnumDemonWillType.values()) + { + String name = ""; + if (type.ordinal() != 0) + { + name = "_" + type.name().toLowerCase() + name; + } + ModelFile willFile = singleTexture("item/variants/" + path + name, mcLoc("item/handheld"), "layer0", modLoc("item/" + path + name)); + builder = builder.override().predicate(BloodMagic.rl("type"), type.ordinal()).model(willFile).end(); + + } + } } diff --git a/src/main/java/wayoftime/bloodmagic/common/data/GeneratorLanguage.java b/src/main/java/wayoftime/bloodmagic/common/data/GeneratorLanguage.java index fa078b10..3b584545 100644 --- a/src/main/java/wayoftime/bloodmagic/common/data/GeneratorLanguage.java +++ b/src/main/java/wayoftime/bloodmagic/common/data/GeneratorLanguage.java @@ -229,6 +229,9 @@ public class GeneratorLanguage extends LanguageProvider addItem(BloodMagicItems.MONSTER_SOUL_VENGEFUL, "Demon Will"); addItem(BloodMagicItems.SOUL_SNARE, "Soul Snare"); addItem(BloodMagicItems.SENTIENT_SWORD, "Sentient Sword"); + addItem(BloodMagicItems.SENTIENT_AXE, "Sentient Axe"); + addItem(BloodMagicItems.SENTIENT_PICKAXE, "Sentient Pickaxe"); + addItem(BloodMagicItems.SENTIENT_SHOVEL, "Sentient Shovel"); addItem(BloodMagicItems.WEAK_ACTIVATION_CRYSTAL, "Weak Activation Crystal"); addItem(BloodMagicItems.AWAKENED_ACTIVATION_CRYSTAL, "Awakened Activation Crystal"); diff --git a/src/main/java/wayoftime/bloodmagic/common/item/BloodMagicItems.java b/src/main/java/wayoftime/bloodmagic/common/item/BloodMagicItems.java index d21368be..cf7c3b09 100644 --- a/src/main/java/wayoftime/bloodmagic/common/item/BloodMagicItems.java +++ b/src/main/java/wayoftime/bloodmagic/common/item/BloodMagicItems.java @@ -21,6 +21,9 @@ import wayoftime.bloodmagic.common.item.sigil.ItemSigilMagnetism; import wayoftime.bloodmagic.common.item.sigil.ItemSigilVoid; import wayoftime.bloodmagic.common.item.sigil.ItemSigilWater; import wayoftime.bloodmagic.common.item.soul.ItemMonsterSoul; +import wayoftime.bloodmagic.common.item.soul.ItemSentientAxe; +import wayoftime.bloodmagic.common.item.soul.ItemSentientPickaxe; +import wayoftime.bloodmagic.common.item.soul.ItemSentientShovel; import wayoftime.bloodmagic.common.item.soul.ItemSentientSword; import wayoftime.bloodmagic.common.item.soul.ItemSoulGem; import wayoftime.bloodmagic.common.item.soul.ItemSoulSnare; @@ -146,6 +149,9 @@ public class BloodMagicItems public static final RegistryObject SOUL_SNARE = BASICITEMS.register("soulsnare", ItemSoulSnare::new); public static final RegistryObject SENTIENT_SWORD = ITEMS.register("soulsword", () -> new ItemSentientSword()); + public static final RegistryObject SENTIENT_AXE = ITEMS.register("soulaxe", () -> new ItemSentientAxe()); + public static final RegistryObject SENTIENT_PICKAXE = ITEMS.register("soulpickaxe", () -> new ItemSentientPickaxe()); + public static final RegistryObject SENTIENT_SHOVEL = ITEMS.register("soulshovel", () -> new ItemSentientShovel()); public static final RegistryObject RAW_CRYSTAL_BLOCK_ITEM = ITEMS.register("rawdemoncrystal", () -> new BlockItem(BloodMagicBlocks.RAW_CRYSTAL_BLOCK.get(), new Item.Properties().group(BloodMagic.TAB))); public static final RegistryObject CORROSIVE_CRYSTAL_BLOCK_ITEM = ITEMS.register("corrosivedemoncrystal", () -> new BlockItem(BloodMagicBlocks.CORROSIVE_CRYSTAL_BLOCK.get(), new Item.Properties().group(BloodMagic.TAB))); diff --git a/src/main/java/wayoftime/bloodmagic/common/item/soul/ItemSentientAxe.java b/src/main/java/wayoftime/bloodmagic/common/item/soul/ItemSentientAxe.java new file mode 100644 index 00000000..e3a0be8c --- /dev/null +++ b/src/main/java/wayoftime/bloodmagic/common/item/soul/ItemSentientAxe.java @@ -0,0 +1,555 @@ +package wayoftime.bloodmagic.common.item.soul; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.UUID; + +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimap; + +import net.minecraft.block.BlockState; +import net.minecraft.client.util.ITooltipFlag; +import net.minecraft.entity.Entity; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.ai.attributes.Attribute; +import net.minecraft.entity.ai.attributes.AttributeModifier; +import net.minecraft.entity.ai.attributes.Attributes; +import net.minecraft.entity.monster.IMob; +import net.minecraft.entity.monster.SlimeEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.inventory.EquipmentSlotType; +import net.minecraft.item.AxeItem; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.potion.EffectInstance; +import net.minecraft.potion.Effects; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Hand; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TranslationTextComponent; +import net.minecraft.world.Difficulty; +import net.minecraft.world.World; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import wayoftime.bloodmagic.BloodMagic; +import wayoftime.bloodmagic.common.item.BMItemTier; +import wayoftime.bloodmagic.common.item.BloodMagicItems; +import wayoftime.bloodmagic.iface.IMultiWillTool; +import wayoftime.bloodmagic.util.Constants; +import wayoftime.bloodmagic.util.helper.NBTHelper; +import wayoftime.bloodmagic.will.EnumDemonWillType; +import wayoftime.bloodmagic.will.IDemonWill; +import wayoftime.bloodmagic.will.IDemonWillWeapon; +import wayoftime.bloodmagic.will.PlayerDemonWillHandler; + +public class ItemSentientAxe extends AxeItem implements IDemonWillWeapon, IMultiWillTool +{ + public static int[] soulBracket = new int[] { 16, 60, 200, 400, 1000 }; + public static double[] defaultDamageAdded = new double[] { 1, 2, 3, 3.5, 4 }; + public static double[] destructiveDamageAdded = new double[] { 2, 3, 4, 5, 6 }; + public static double[] vengefulDamageAdded = new double[] { 0, 0.5, 1, 1.5, 2 }; + public static double[] steadfastDamageAdded = new double[] { 0, 0.5, 1, 1.5, 2 }; + public static double[] defaultDigSpeedAdded = new double[] { 1, 1.5, 2, 3, 4 }; + public static double[] soulDrainPerSwing = new double[] { 0.05, 0.1, 0.2, 0.4, 0.75 }; + public static double[] soulDrop = new double[] { 2, 4, 7, 10, 13 }; + public static double[] staticDrop = new double[] { 1, 1, 2, 3, 3 }; + + public static double[] healthBonus = new double[] { 0, 0, 0, 0, 0 }; // TODO: Think of implementing this later + public static double[] vengefulAttackSpeed = new double[] { -3, -2.8, -2.7, -2.6, -2.5 }; + public static double[] destructiveAttackSpeed = new double[] { -3.1, -3.1, -3.2, -3.3, -3.3 }; + + public static int[] absorptionTime = new int[] { 200, 300, 400, 500, 600 }; + + public static double maxAbsorptionHearts = 10; + + public static int[] poisonTime = new int[] { 25, 50, 60, 80, 100 }; + public static int[] poisonLevel = new int[] { 0, 0, 0, 1, 1 }; + + public static double[] movementSpeed = new double[] { 0.05, 0.1, 0.15, 0.2, 0.25 }; + + public final double baseAttackDamage = 8; + public final double baseAttackSpeed = -3; + + public ItemSentientAxe() + { + super(BMItemTier.SENTIENT, 8, -3.1f, new Item.Properties().maxDamage(520).group(BloodMagic.TAB)); +// super(RegistrarBloodMagicItems.SOUL_TOOL_MATERIAL, 8.0F, 3.1F); + } + + @Override + public float getDestroySpeed(ItemStack stack, BlockState state) + { + float value = super.getDestroySpeed(stack, state); + if (value > 1) + { + return (float) (value + getDigSpeedOfSword(stack)); + } else + { + return value; + } + } + + public void recalculatePowers(ItemStack stack, World world, PlayerEntity player) + { + EnumDemonWillType type = PlayerDemonWillHandler.getLargestWillType(player); + double soulsRemaining = PlayerDemonWillHandler.getTotalDemonWill(type, player); + this.setCurrentType(stack, soulsRemaining > 0 ? type : EnumDemonWillType.DEFAULT); + int level = getLevel(stack, soulsRemaining); + + double drain = level >= 0 ? soulDrainPerSwing[level] : 0; + double extraDamage = getExtraDamage(type, level); + + setDrainOfActivatedSword(stack, drain); + setDamageOfActivatedSword(stack, baseAttackDamage + extraDamage); + setStaticDropOfActivatedSword(stack, level >= 0 ? staticDrop[level] : 1); + setDropOfActivatedSword(stack, level >= 0 ? soulDrop[level] : 0); + setAttackSpeedOfSword(stack, level >= 0 ? getAttackSpeed(type, level) : baseAttackSpeed); + setHealthBonusOfSword(stack, level >= 0 ? getHealthBonus(type, level) : 0); + setSpeedOfSword(stack, level >= 0 ? getMovementSpeed(type, level) : 0); + setDigSpeedOfSword(stack, level >= 0 ? getDigSpeed(type, level) : 0); + } + + public double getExtraDamage(EnumDemonWillType type, int willBracket) + { + if (willBracket < 0) + { + return 0; + } + + switch (type) + { + case CORROSIVE: + case DEFAULT: + return defaultDamageAdded[willBracket]; + case DESTRUCTIVE: + return destructiveDamageAdded[willBracket]; + case VENGEFUL: + return vengefulDamageAdded[willBracket]; + case STEADFAST: + return steadfastDamageAdded[willBracket]; + } + + return 0; + } + + public double getAttackSpeed(EnumDemonWillType type, int willBracket) + { + switch (type) + { + case VENGEFUL: + return vengefulAttackSpeed[willBracket]; + case DESTRUCTIVE: + return destructiveAttackSpeed[willBracket]; + default: + return -2.9; + } + } + + public double getHealthBonus(EnumDemonWillType type, int willBracket) + { + switch (type) + { + case STEADFAST: + return healthBonus[willBracket]; + default: + return 0; + } + } + + public double getMovementSpeed(EnumDemonWillType type, int willBracket) + { + switch (type) + { + case VENGEFUL: + return movementSpeed[willBracket]; + default: + return 0; + } + } + + public double getDigSpeed(EnumDemonWillType type, int willBracket) + { + switch (type) + { + case VENGEFUL: +// return movementSpeed[willBracket]; + default: + return defaultDigSpeedAdded[willBracket]; + } + } + + public void applyEffectToEntity(EnumDemonWillType type, int willBracket, LivingEntity target, PlayerEntity attacker) + { + switch (type) + { + case CORROSIVE: + target.addPotionEffect(new EffectInstance(Effects.WITHER, poisonTime[willBracket], poisonLevel[willBracket])); + break; + case DEFAULT: + break; + case DESTRUCTIVE: + break; + case STEADFAST: + if (!target.isAlive()) + { + float absorption = attacker.getAbsorptionAmount(); + attacker.addPotionEffect(new EffectInstance(Effects.ABSORPTION, absorptionTime[willBracket], 127)); + attacker.setAbsorptionAmount((float) Math.min(absorption + target.getMaxHealth() + * 0.05f, maxAbsorptionHearts)); + } + break; + case VENGEFUL: + break; + } + } + + @Override + public boolean hitEntity(ItemStack stack, LivingEntity target, LivingEntity attacker) + { + if (super.hitEntity(stack, target, attacker)) + { + if (attacker instanceof PlayerEntity) + { + PlayerEntity attackerPlayer = (PlayerEntity) attacker; + this.recalculatePowers(stack, attackerPlayer.getEntityWorld(), attackerPlayer); + EnumDemonWillType type = this.getCurrentType(stack); + double will = PlayerDemonWillHandler.getTotalDemonWill(type, attackerPlayer); + int willBracket = this.getLevel(stack, will); + + applyEffectToEntity(type, willBracket, target, attackerPlayer); + + ItemStack offStack = attackerPlayer.getItemStackFromSlot(EquipmentSlotType.OFFHAND); +// if (offStack.getItem() instanceof ISentientSwordEffectProvider) +// { +// ISentientSwordEffectProvider provider = (ISentientSwordEffectProvider) offStack.getItem(); +// if (provider.providesEffectForWill(type)) +// { +// provider.applyOnHitEffect(type, stack, offStack, attacker, target); +// } +// } + } + + return true; + } + + return false; + } + + @Override + public EnumDemonWillType getCurrentType(ItemStack stack) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + + if (!tag.contains(Constants.NBT.WILL_TYPE)) + { + return EnumDemonWillType.DEFAULT; + } + + return EnumDemonWillType.valueOf(tag.getString(Constants.NBT.WILL_TYPE).toUpperCase(Locale.ENGLISH)); + } + + public void setCurrentType(ItemStack stack, EnumDemonWillType type) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + + tag.putString(Constants.NBT.WILL_TYPE, type.toString()); + } + + @Override + public ActionResult onItemRightClick(World world, PlayerEntity player, Hand hand) + { + recalculatePowers(player.getHeldItem(hand), world, player); + + return super.onItemRightClick(world, player, hand); + } + + @Override + public boolean shouldCauseReequipAnimation(ItemStack oldStack, ItemStack newStack, boolean slotChanged) + { + return oldStack.getItem() != newStack.getItem(); + } + + private int getLevel(ItemStack stack, double soulsRemaining) + { + int lvl = -1; + for (int i = 0; i < soulBracket.length; i++) + { + if (soulsRemaining >= soulBracket[i]) + { + lvl = i; + } + } + + return lvl; + } + + @Override + @OnlyIn(Dist.CLIENT) + public void addInformation(ItemStack stack, World world, List tooltip, ITooltipFlag flag) + { + if (!stack.hasTag()) + return; + + tooltip.add(new TranslationTextComponent("tooltip.bloodmagic.sentientAxe.desc")); + tooltip.add(new TranslationTextComponent("tooltip.bloodmagic.currentType." + getCurrentType(stack).name().toLowerCase())); + } + + @Override + public boolean onLeftClickEntity(ItemStack stack, PlayerEntity player, Entity entity) + { + recalculatePowers(stack, player.getEntityWorld(), player); + + double drain = this.getDrainOfActivatedSword(stack); + if (drain > 0) + { + EnumDemonWillType type = getCurrentType(stack); + double soulsRemaining = PlayerDemonWillHandler.getTotalDemonWill(type, player); + + if (drain > soulsRemaining) + { + return false; + } else + { + PlayerDemonWillHandler.consumeDemonWill(type, player, drain); + } + } + + return super.onLeftClickEntity(stack, player, entity); + } + + @Override + public List getRandomDemonWillDrop(LivingEntity killedEntity, LivingEntity attackingEntity, ItemStack stack, int looting) + { + List soulList = new ArrayList<>(); + + if (killedEntity.getEntityWorld().getDifficulty() != Difficulty.PEACEFUL && !(killedEntity instanceof IMob)) + { + return soulList; + } + + double willModifier = killedEntity instanceof SlimeEntity ? 0.67 : 1; + + IDemonWill soul; + + EnumDemonWillType type = this.getCurrentType(stack); + switch (type) + { + case CORROSIVE: + soul = ((IDemonWill) BloodMagicItems.MONSTER_SOUL_CORROSIVE.get()); + break; + case DESTRUCTIVE: + soul = ((IDemonWill) BloodMagicItems.MONSTER_SOUL_DESTRUCTIVE.get()); + break; + case STEADFAST: + soul = ((IDemonWill) BloodMagicItems.MONSTER_SOUL_STEADFAST.get()); + break; + case VENGEFUL: + soul = ((IDemonWill) BloodMagicItems.MONSTER_SOUL_VENGEFUL.get()); + break; + default: + soul = ((IDemonWill) BloodMagicItems.MONSTER_SOUL_RAW.get()); + break; + } + + for (int i = 0; i <= looting; i++) + { + if (i == 0 || attackingEntity.getEntityWorld().rand.nextDouble() < 0.4) + { + ItemStack soulStack = soul.createWill(willModifier * (this.getDropOfActivatedSword(stack) + * attackingEntity.getEntityWorld().rand.nextDouble() + this.getStaticDropOfActivatedSword(stack)) + * killedEntity.getMaxHealth() / 20d); + soulList.add(soulStack); + } + } + + return soulList; + } + + // TODO: Change attack speed. + @Override + public Multimap getAttributeModifiers(EquipmentSlotType slot, ItemStack stack) + { + Multimap multimap = HashMultimap.create(); + if (slot == EquipmentSlotType.MAINHAND) + { + multimap.put(Attributes.ATTACK_DAMAGE, new AttributeModifier(ATTACK_DAMAGE_MODIFIER, "Weapon modifier", getDamageOfActivatedSword(stack), AttributeModifier.Operation.ADDITION)); + multimap.put(Attributes.ATTACK_SPEED, new AttributeModifier(ATTACK_SPEED_MODIFIER, "Weapon modifier", this.getAttackSpeedOfSword(stack), AttributeModifier.Operation.ADDITION)); + multimap.put(Attributes.MAX_HEALTH, new AttributeModifier(new UUID(0, 31818145), "Weapon modifier", this.getHealthBonusOfSword(stack), AttributeModifier.Operation.ADDITION)); + multimap.put(Attributes.MOVEMENT_SPEED, new AttributeModifier(new UUID(0, 4218052), "Weapon modifier", this.getSpeedOfSword(stack), AttributeModifier.Operation.ADDITION)); + } + + return multimap; + } + + public double getDamageOfActivatedSword(ItemStack stack) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + return tag.getDouble(Constants.NBT.SOUL_SWORD_DAMAGE); + } + + public void setDamageOfActivatedSword(ItemStack stack, double damage) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + + tag.putDouble(Constants.NBT.SOUL_SWORD_DAMAGE, damage); + } + + public double getDrainOfActivatedSword(ItemStack stack) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + return tag.getDouble(Constants.NBT.SOUL_SWORD_ACTIVE_DRAIN); + } + + public void setDrainOfActivatedSword(ItemStack stack, double drain) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + + tag.putDouble(Constants.NBT.SOUL_SWORD_ACTIVE_DRAIN, drain); + } + + public double getStaticDropOfActivatedSword(ItemStack stack) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + return tag.getDouble(Constants.NBT.SOUL_SWORD_STATIC_DROP); + } + + public void setStaticDropOfActivatedSword(ItemStack stack, double drop) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + + tag.putDouble(Constants.NBT.SOUL_SWORD_STATIC_DROP, drop); + } + + public double getDropOfActivatedSword(ItemStack stack) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + return tag.getDouble(Constants.NBT.SOUL_SWORD_DROP); + } + + public void setDropOfActivatedSword(ItemStack stack, double drop) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + + tag.putDouble(Constants.NBT.SOUL_SWORD_DROP, drop); + } + + public double getHealthBonusOfSword(ItemStack stack) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + return tag.getDouble(Constants.NBT.SOUL_SWORD_HEALTH); + } + + public void setHealthBonusOfSword(ItemStack stack, double hp) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + + tag.putDouble(Constants.NBT.SOUL_SWORD_HEALTH, hp); + } + + public double getAttackSpeedOfSword(ItemStack stack) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + return tag.getDouble(Constants.NBT.SOUL_SWORD_ATTACK_SPEED); + } + + public void setAttackSpeedOfSword(ItemStack stack, double speed) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + + tag.putDouble(Constants.NBT.SOUL_SWORD_ATTACK_SPEED, speed); + } + + public double getSpeedOfSword(ItemStack stack) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + return tag.getDouble(Constants.NBT.SOUL_SWORD_SPEED); + } + + public void setSpeedOfSword(ItemStack stack, double speed) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + + tag.putDouble(Constants.NBT.SOUL_SWORD_SPEED, speed); + } + + public double getDigSpeedOfSword(ItemStack stack) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + return tag.getDouble(Constants.NBT.SOUL_SWORD_DIG_SPEED); + } + + public void setDigSpeedOfSword(ItemStack stack, double speed) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + + tag.putDouble(Constants.NBT.SOUL_SWORD_DIG_SPEED, speed); + } + +// @Override +// public boolean spawnSentientEntityOnDrop(ItemStack droppedStack, PlayerEntity player) { +// World world = player.getEntityWorld(); +// if (!world.isRemote) { +// this.recalculatePowers(droppedStack, world, player); +// +// EnumDemonWillType type = this.getCurrentType(droppedStack); +// double soulsRemaining = PlayerDemonWillHandler.getTotalDemonWill(type, player); +// if (soulsRemaining < 1024) { +// return false; +// } +// +// PlayerDemonWillHandler.consumeDemonWill(type, player, 100); +// +// EntitySentientSpecter specterEntity = new EntitySentientSpecter(world); +// specterEntity.setPosition(player.posX, player.posY, player.posZ); +// world.spawnEntity(specterEntity); +// +// specterEntity.setItemStackToSlot(EquipmentSlotType.MAINHAND, droppedStack.copy()); +// +// specterEntity.setType(this.getCurrentType(droppedStack)); +// specterEntity.setOwner(player); +// specterEntity.setTamed(true); +// +// return true; +// } +// +// return false; +// } +} \ No newline at end of file diff --git a/src/main/java/wayoftime/bloodmagic/common/item/soul/ItemSentientPickaxe.java b/src/main/java/wayoftime/bloodmagic/common/item/soul/ItemSentientPickaxe.java new file mode 100644 index 00000000..304ec6a5 --- /dev/null +++ b/src/main/java/wayoftime/bloodmagic/common/item/soul/ItemSentientPickaxe.java @@ -0,0 +1,557 @@ +package wayoftime.bloodmagic.common.item.soul; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.UUID; + +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimap; + +import net.minecraft.block.BlockState; +import net.minecraft.client.util.ITooltipFlag; +import net.minecraft.entity.Entity; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.ai.attributes.Attribute; +import net.minecraft.entity.ai.attributes.AttributeModifier; +import net.minecraft.entity.ai.attributes.Attributes; +import net.minecraft.entity.monster.IMob; +import net.minecraft.entity.monster.SlimeEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.inventory.EquipmentSlotType; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.PickaxeItem; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.potion.EffectInstance; +import net.minecraft.potion.Effects; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Hand; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TranslationTextComponent; +import net.minecraft.world.Difficulty; +import net.minecraft.world.World; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import wayoftime.bloodmagic.BloodMagic; +import wayoftime.bloodmagic.common.item.BMItemTier; +import wayoftime.bloodmagic.common.item.BloodMagicItems; +import wayoftime.bloodmagic.iface.IMultiWillTool; +import wayoftime.bloodmagic.util.Constants; +import wayoftime.bloodmagic.util.helper.NBTHelper; +import wayoftime.bloodmagic.will.EnumDemonWillType; +import wayoftime.bloodmagic.will.IDemonWill; +import wayoftime.bloodmagic.will.IDemonWillWeapon; +import wayoftime.bloodmagic.will.PlayerDemonWillHandler; + +public class ItemSentientPickaxe extends PickaxeItem implements IDemonWillWeapon, IMultiWillTool +{ + public static int[] soulBracket = new int[] { 16, 60, 200, 400, 1000 }; + public static double[] defaultDamageAdded = new double[] { 1, 2, 3, 3.5, 4 }; + public static double[] destructiveDamageAdded = new double[] { 2, 3, 4, 5, 6 }; + public static double[] vengefulDamageAdded = new double[] { 0, 0.5, 1, 1.5, 2 }; + public static double[] steadfastDamageAdded = new double[] { 0, 0.5, 1, 1.5, 2 }; + public static double[] defaultDigSpeedAdded = new double[] { 1, 1.5, 2, 3, 4 }; + public static double[] soulDrainPerSwing = new double[] { 0.05, 0.1, 0.2, 0.4, 0.75 }; + public static double[] soulDrop = new double[] { 2, 4, 7, 10, 13 }; + public static double[] staticDrop = new double[] { 1, 1, 2, 3, 3 }; + + public static double[] healthBonus = new double[] { 0, 0, 0, 0, 0 }; // TODO: Think of implementing this later + public static double[] vengefulAttackSpeed = new double[] { -3, -2.8, -2.7, -2.6, -2.5 }; + public static double[] destructiveAttackSpeed = new double[] { -3.1, -3.1, -3.2, -3.3, -3.3 }; + + public static int[] absorptionTime = new int[] { 200, 300, 400, 500, 600 }; + + public static double maxAbsorptionHearts = 10; + + public static int[] poisonTime = new int[] { 25, 50, 60, 80, 100 }; + public static int[] poisonLevel = new int[] { 0, 0, 0, 1, 1 }; + + public static double[] movementSpeed = new double[] { 0.05, 0.1, 0.15, 0.2, 0.25 }; + + public static final double baseAttackDamage = 3; + public static final double baseAttackSpeed = -2.8; + + public ItemSentientPickaxe() + { + super(BMItemTier.SENTIENT, (int) baseAttackDamage, (float) baseAttackSpeed, new Item.Properties().maxDamage(520).group(BloodMagic.TAB)); + } + + @Override + public float getDestroySpeed(ItemStack stack, BlockState state) + { + float value = super.getDestroySpeed(stack, state); + if (value > 1) + { + return (float) (value + getDigSpeedOfSword(stack)); + } else + { + return value; + } + } + + public void recalculatePowers(ItemStack stack, World world, PlayerEntity player) + { + EnumDemonWillType type = PlayerDemonWillHandler.getLargestWillType(player); + double soulsRemaining = PlayerDemonWillHandler.getTotalDemonWill(type, player); + this.setCurrentType(stack, soulsRemaining > 0 ? type : EnumDemonWillType.DEFAULT); + int level = getLevel(stack, soulsRemaining); + + double drain = level >= 0 ? soulDrainPerSwing[level] : 0; + double extraDamage = getExtraDamage(type, level); + + setDrainOfActivatedSword(stack, drain); + setDamageOfActivatedSword(stack, baseAttackDamage + extraDamage); + setStaticDropOfActivatedSword(stack, level >= 0 ? staticDrop[level] : 1); + setDropOfActivatedSword(stack, level >= 0 ? soulDrop[level] : 0); + setAttackSpeedOfSword(stack, level >= 0 ? getAttackSpeed(type, level) : baseAttackSpeed); + setHealthBonusOfSword(stack, level >= 0 ? getHealthBonus(type, level) : 0); + setSpeedOfSword(stack, level >= 0 ? getMovementSpeed(type, level) : 0); + setDigSpeedOfSword(stack, level >= 0 ? getDigSpeed(type, level) : 0); + } + + public double getExtraDamage(EnumDemonWillType type, int willBracket) + { + if (willBracket < 0) + { + return 0; + } + + switch (type) + { + case CORROSIVE: + case DEFAULT: + return defaultDamageAdded[willBracket]; + case DESTRUCTIVE: + return destructiveDamageAdded[willBracket]; + case VENGEFUL: + return vengefulDamageAdded[willBracket]; + case STEADFAST: + return steadfastDamageAdded[willBracket]; + } + + return 0; + } + + public double getAttackSpeed(EnumDemonWillType type, int willBracket) + { + switch (type) + { + case VENGEFUL: + return vengefulAttackSpeed[willBracket]; + case DESTRUCTIVE: + return destructiveAttackSpeed[willBracket]; + default: + return -2.9; + } + } + + public double getHealthBonus(EnumDemonWillType type, int willBracket) + { + switch (type) + { + case STEADFAST: + return healthBonus[willBracket]; + default: + return 0; + } + } + + public double getMovementSpeed(EnumDemonWillType type, int willBracket) + { + switch (type) + { + case VENGEFUL: + return movementSpeed[willBracket]; + default: + return 0; + } + } + + public double getDigSpeed(EnumDemonWillType type, int willBracket) + { + switch (type) + { + case VENGEFUL: +// return movementSpeed[willBracket]; + default: + return defaultDigSpeedAdded[willBracket]; + } + } + + public void applyEffectToEntity(EnumDemonWillType type, int willBracket, LivingEntity target, PlayerEntity attacker) + { + switch (type) + { + case CORROSIVE: + target.addPotionEffect(new EffectInstance(Effects.WITHER, poisonTime[willBracket], poisonLevel[willBracket])); + break; + case DEFAULT: + break; + case DESTRUCTIVE: + break; + case STEADFAST: + if (!target.isAlive()) + { + float absorption = attacker.getAbsorptionAmount(); + attacker.addPotionEffect(new EffectInstance(Effects.ABSORPTION, absorptionTime[willBracket], 127)); + attacker.setAbsorptionAmount((float) Math.min(absorption + target.getMaxHealth() + * 0.05f, maxAbsorptionHearts)); + } + break; + case VENGEFUL: + break; + } + } + + @Override + public boolean hitEntity(ItemStack stack, LivingEntity target, LivingEntity attacker) + { + if (super.hitEntity(stack, target, attacker)) + { + if (attacker instanceof PlayerEntity) + { + PlayerEntity attackerPlayer = (PlayerEntity) attacker; + this.recalculatePowers(stack, attackerPlayer.getEntityWorld(), attackerPlayer); + EnumDemonWillType type = this.getCurrentType(stack); + double will = PlayerDemonWillHandler.getTotalDemonWill(type, attackerPlayer); + int willBracket = this.getLevel(stack, will); + + applyEffectToEntity(type, willBracket, target, attackerPlayer); + +// ItemStack offStack = attackerPlayer.getItemStackFromSlot(EquipmentSlotType.OFFHAND); +// if (offStack.getItem() instanceof ISentientSwordEffectProvider) +// { +// ISentientSwordEffectProvider provider = (ISentientSwordEffectProvider) offStack.getItem(); +// if (provider.providesEffectForWill(type)) +// { +// provider.applyOnHitEffect(type, stack, offStack, attacker, target); +// } +// } + } + + return true; + } + + return false; + } + + @Override + public EnumDemonWillType getCurrentType(ItemStack stack) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + + if (!tag.contains(Constants.NBT.WILL_TYPE)) + { + return EnumDemonWillType.DEFAULT; + } + + return EnumDemonWillType.valueOf(tag.getString(Constants.NBT.WILL_TYPE).toUpperCase(Locale.ENGLISH)); + } + + public void setCurrentType(ItemStack stack, EnumDemonWillType type) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + + tag.putString(Constants.NBT.WILL_TYPE, type.toString()); + } + + @Override + public ActionResult onItemRightClick(World world, PlayerEntity player, Hand hand) + { + recalculatePowers(player.getHeldItem(hand), world, player); + return super.onItemRightClick(world, player, hand); + } + + @Override + public boolean shouldCauseReequipAnimation(ItemStack oldStack, ItemStack newStack, boolean slotChanged) + { + return oldStack.getItem() != newStack.getItem(); + } + + private int getLevel(ItemStack stack, double soulsRemaining) + { + int lvl = -1; + for (int i = 0; i < soulBracket.length; i++) + { + if (soulsRemaining >= soulBracket[i]) + { + lvl = i; + } + } + + return lvl; + } + + @Override + @OnlyIn(Dist.CLIENT) + public void addInformation(ItemStack stack, World world, List tooltip, ITooltipFlag flag) + { + if (!stack.hasTag()) + return; + +// tooltip.addAll(Arrays.asList(TextHelper.cutLongString(TextHelper.localizeEffect("tooltip.bloodmagic.sentientSword.desc")))); + tooltip.add(new TranslationTextComponent("tooltip.bloodmagic.sentientPickaxe.desc")); + tooltip.add(new TranslationTextComponent("tooltip.bloodmagic.currentType." + getCurrentType(stack).name().toLowerCase())); + } + + @Override + public boolean onLeftClickEntity(ItemStack stack, PlayerEntity player, Entity entity) + { + recalculatePowers(stack, player.getEntityWorld(), player); + + double drain = this.getDrainOfActivatedSword(stack); + if (drain > 0) + { + EnumDemonWillType type = getCurrentType(stack); + double soulsRemaining = PlayerDemonWillHandler.getTotalDemonWill(type, player); + + if (drain > soulsRemaining) + { + return false; + } else + { + PlayerDemonWillHandler.consumeDemonWill(type, player, drain); + } + } + + return super.onLeftClickEntity(stack, player, entity); + } + + @Override + public List getRandomDemonWillDrop(LivingEntity killedEntity, LivingEntity attackingEntity, ItemStack stack, int looting) + { + List soulList = new ArrayList<>(); + + if (killedEntity.getEntityWorld().getDifficulty() != Difficulty.PEACEFUL && !(killedEntity instanceof IMob)) + { + return soulList; + } + + double willModifier = killedEntity instanceof SlimeEntity ? 0.67 : 1; + + IDemonWill soul; + + EnumDemonWillType type = this.getCurrentType(stack); + switch (type) + { + case CORROSIVE: + soul = ((IDemonWill) BloodMagicItems.MONSTER_SOUL_CORROSIVE.get()); + break; + case DESTRUCTIVE: + soul = ((IDemonWill) BloodMagicItems.MONSTER_SOUL_DESTRUCTIVE.get()); + break; + case STEADFAST: + soul = ((IDemonWill) BloodMagicItems.MONSTER_SOUL_STEADFAST.get()); + break; + case VENGEFUL: + soul = ((IDemonWill) BloodMagicItems.MONSTER_SOUL_VENGEFUL.get()); + break; + default: + soul = ((IDemonWill) BloodMagicItems.MONSTER_SOUL_RAW.get()); + break; + } + + for (int i = 0; i <= looting; i++) + { + if (i == 0 || attackingEntity.getEntityWorld().rand.nextDouble() < 0.4) + { + ItemStack soulStack = soul.createWill(willModifier * (this.getDropOfActivatedSword(stack) + * attackingEntity.getEntityWorld().rand.nextDouble() + this.getStaticDropOfActivatedSword(stack)) + * killedEntity.getMaxHealth() / 20d); + soulList.add(soulStack); + } + } + + return soulList; + } + + // TODO: Change attack speed. + @Override + public Multimap getAttributeModifiers(EquipmentSlotType slot, ItemStack stack) + { + Multimap multimap = HashMultimap.create(); + if (slot == EquipmentSlotType.MAINHAND) + { + multimap.put(Attributes.ATTACK_DAMAGE, new AttributeModifier(ATTACK_DAMAGE_MODIFIER, "Weapon modifier", getDamageOfActivatedSword(stack), AttributeModifier.Operation.ADDITION)); + multimap.put(Attributes.ATTACK_SPEED, new AttributeModifier(ATTACK_SPEED_MODIFIER, "Weapon modifier", this.getAttackSpeedOfSword(stack), AttributeModifier.Operation.ADDITION)); + multimap.put(Attributes.MAX_HEALTH, new AttributeModifier(new UUID(0, 31818145), "Weapon modifier", this.getHealthBonusOfSword(stack), AttributeModifier.Operation.ADDITION)); + multimap.put(Attributes.MOVEMENT_SPEED, new AttributeModifier(new UUID(0, 4218052), "Weapon modifier", this.getSpeedOfSword(stack), AttributeModifier.Operation.ADDITION)); + } + + return multimap; + } + + public double getDamageOfActivatedSword(ItemStack stack) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + return tag.getDouble(Constants.NBT.SOUL_SWORD_DAMAGE); + } + + public void setDamageOfActivatedSword(ItemStack stack, double damage) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + + tag.putDouble(Constants.NBT.SOUL_SWORD_DAMAGE, damage); + } + + public double getDrainOfActivatedSword(ItemStack stack) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + return tag.getDouble(Constants.NBT.SOUL_SWORD_ACTIVE_DRAIN); + } + + public void setDrainOfActivatedSword(ItemStack stack, double drain) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + + tag.putDouble(Constants.NBT.SOUL_SWORD_ACTIVE_DRAIN, drain); + } + + public double getStaticDropOfActivatedSword(ItemStack stack) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + return tag.getDouble(Constants.NBT.SOUL_SWORD_STATIC_DROP); + } + + public void setStaticDropOfActivatedSword(ItemStack stack, double drop) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + + tag.putDouble(Constants.NBT.SOUL_SWORD_STATIC_DROP, drop); + } + + public double getDropOfActivatedSword(ItemStack stack) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + return tag.getDouble(Constants.NBT.SOUL_SWORD_DROP); + } + + public void setDropOfActivatedSword(ItemStack stack, double drop) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + + tag.putDouble(Constants.NBT.SOUL_SWORD_DROP, drop); + } + + public double getHealthBonusOfSword(ItemStack stack) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + return tag.getDouble(Constants.NBT.SOUL_SWORD_HEALTH); + } + + public void setHealthBonusOfSword(ItemStack stack, double hp) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + + tag.putDouble(Constants.NBT.SOUL_SWORD_HEALTH, hp); + } + + public double getAttackSpeedOfSword(ItemStack stack) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + return tag.getDouble(Constants.NBT.SOUL_SWORD_ATTACK_SPEED); + } + + public void setAttackSpeedOfSword(ItemStack stack, double speed) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + + tag.putDouble(Constants.NBT.SOUL_SWORD_ATTACK_SPEED, speed); + } + + public double getSpeedOfSword(ItemStack stack) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + return tag.getDouble(Constants.NBT.SOUL_SWORD_SPEED); + } + + public void setSpeedOfSword(ItemStack stack, double speed) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + + tag.putDouble(Constants.NBT.SOUL_SWORD_SPEED, speed); + } + + public double getDigSpeedOfSword(ItemStack stack) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + return tag.getDouble(Constants.NBT.SOUL_SWORD_DIG_SPEED); + } + + public void setDigSpeedOfSword(ItemStack stack, double speed) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + + tag.putDouble(Constants.NBT.SOUL_SWORD_DIG_SPEED, speed); + } + +// @Override +// public boolean spawnSentientEntityOnDrop(ItemStack droppedStack, PlayerEntity player) +// { +// World world = player.getEntityWorld(); +// if (!world.isRemote) +// { +// this.recalculatePowers(droppedStack, world, player); +// +// EnumDemonWillType type = this.getCurrentType(droppedStack); +// double soulsRemaining = PlayerDemonWillHandler.getTotalDemonWill(type, player); +// if (soulsRemaining < 1024) +// { +// return false; +// } +// +// PlayerDemonWillHandler.consumeDemonWill(type, player, 100); +// +// EntitySentientSpecter specterEntity = new EntitySentientSpecter(world); +// specterEntity.setPosition(player.posX, player.posY, player.posZ); +// world.spawnEntity(specterEntity); +// +// specterEntity.setItemStackToSlot(EquipmentSlotType.MAINHAND, droppedStack.copy()); +// +// specterEntity.setType(this.getCurrentType(droppedStack)); +// specterEntity.setOwner(player); +// specterEntity.setTamed(true); +// +// return true; +// } +// +// return false; +// } +} \ No newline at end of file diff --git a/src/main/java/wayoftime/bloodmagic/common/item/soul/ItemSentientShovel.java b/src/main/java/wayoftime/bloodmagic/common/item/soul/ItemSentientShovel.java new file mode 100644 index 00000000..eae1f54e --- /dev/null +++ b/src/main/java/wayoftime/bloodmagic/common/item/soul/ItemSentientShovel.java @@ -0,0 +1,558 @@ +package wayoftime.bloodmagic.common.item.soul; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.UUID; + +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimap; + +import net.minecraft.block.BlockState; +import net.minecraft.client.util.ITooltipFlag; +import net.minecraft.entity.Entity; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.ai.attributes.Attribute; +import net.minecraft.entity.ai.attributes.AttributeModifier; +import net.minecraft.entity.ai.attributes.Attributes; +import net.minecraft.entity.monster.IMob; +import net.minecraft.entity.monster.SlimeEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.inventory.EquipmentSlotType; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.ShovelItem; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.potion.EffectInstance; +import net.minecraft.potion.Effects; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Hand; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TranslationTextComponent; +import net.minecraft.world.Difficulty; +import net.minecraft.world.World; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import wayoftime.bloodmagic.BloodMagic; +import wayoftime.bloodmagic.common.item.BMItemTier; +import wayoftime.bloodmagic.common.item.BloodMagicItems; +import wayoftime.bloodmagic.iface.IMultiWillTool; +import wayoftime.bloodmagic.util.Constants; +import wayoftime.bloodmagic.util.helper.NBTHelper; +import wayoftime.bloodmagic.will.EnumDemonWillType; +import wayoftime.bloodmagic.will.IDemonWill; +import wayoftime.bloodmagic.will.IDemonWillWeapon; +import wayoftime.bloodmagic.will.PlayerDemonWillHandler; + +public class ItemSentientShovel extends ShovelItem implements IDemonWillWeapon, IMultiWillTool +{ + public static int[] soulBracket = new int[] { 16, 60, 200, 400, 1000 }; + public static double[] defaultDamageAdded = new double[] { 1, 2, 3, 3.5, 4 }; + public static double[] destructiveDamageAdded = new double[] { 2, 3, 4, 5, 6 }; + public static double[] vengefulDamageAdded = new double[] { 0, 0.5, 1, 1.5, 2 }; + public static double[] steadfastDamageAdded = new double[] { 0, 0.5, 1, 1.5, 2 }; + public static double[] defaultDigSpeedAdded = new double[] { 1, 1.5, 2, 3, 4 }; + public static double[] soulDrainPerSwing = new double[] { 0.05, 0.1, 0.2, 0.4, 0.75 }; + public static double[] soulDrop = new double[] { 2, 4, 7, 10, 13 }; + public static double[] staticDrop = new double[] { 1, 1, 2, 3, 3 }; + + public static double[] healthBonus = new double[] { 0, 0, 0, 0, 0 }; // TODO: Think of implementing this later + public static double[] vengefulAttackSpeed = new double[] { -3, -2.8, -2.7, -2.6, -2.5 }; + public static double[] destructiveAttackSpeed = new double[] { -3.1, -3.1, -3.2, -3.3, -3.3 }; + + public static int[] absorptionTime = new int[] { 200, 300, 400, 500, 600 }; + + public static double maxAbsorptionHearts = 10; + + public static int[] poisonTime = new int[] { 25, 50, 60, 80, 100 }; + public static int[] poisonLevel = new int[] { 0, 0, 0, 1, 1 }; + + public static double[] movementSpeed = new double[] { 0.05, 0.1, 0.15, 0.2, 0.25 }; + + public static final double baseAttackDamage = 3; + public static final double baseAttackSpeed = -2.8; + + public ItemSentientShovel() + { + super(BMItemTier.SENTIENT, (int) baseAttackDamage, (float) baseAttackSpeed, new Item.Properties().maxDamage(520).group(BloodMagic.TAB)); + } + + @Override + public float getDestroySpeed(ItemStack stack, BlockState state) + { + float value = super.getDestroySpeed(stack, state); + if (value > 1) + { + return (float) (value + getDigSpeedOfSword(stack)); + } else + { + return value; + } + } + + public void recalculatePowers(ItemStack stack, World world, PlayerEntity player) + { + EnumDemonWillType type = PlayerDemonWillHandler.getLargestWillType(player); + double soulsRemaining = PlayerDemonWillHandler.getTotalDemonWill(type, player); + this.setCurrentType(stack, soulsRemaining > 0 ? type : EnumDemonWillType.DEFAULT); + int level = getLevel(stack, soulsRemaining); + + double drain = level >= 0 ? soulDrainPerSwing[level] : 0; + double extraDamage = getExtraDamage(type, level); + + setDrainOfActivatedSword(stack, drain); + setDamageOfActivatedSword(stack, baseAttackDamage + extraDamage); + setStaticDropOfActivatedSword(stack, level >= 0 ? staticDrop[level] : 1); + setDropOfActivatedSword(stack, level >= 0 ? soulDrop[level] : 0); + setAttackSpeedOfSword(stack, level >= 0 ? getAttackSpeed(type, level) : baseAttackSpeed); + setHealthBonusOfSword(stack, level >= 0 ? getHealthBonus(type, level) : 0); + setSpeedOfSword(stack, level >= 0 ? getMovementSpeed(type, level) : 0); + setDigSpeedOfSword(stack, level >= 0 ? getDigSpeed(type, level) : 0); + } + + public double getExtraDamage(EnumDemonWillType type, int willBracket) + { + if (willBracket < 0) + { + return 0; + } + + switch (type) + { + case CORROSIVE: + case DEFAULT: + return defaultDamageAdded[willBracket]; + case DESTRUCTIVE: + return destructiveDamageAdded[willBracket]; + case VENGEFUL: + return vengefulDamageAdded[willBracket]; + case STEADFAST: + return steadfastDamageAdded[willBracket]; + } + + return 0; + } + + public double getAttackSpeed(EnumDemonWillType type, int willBracket) + { + switch (type) + { + case VENGEFUL: + return vengefulAttackSpeed[willBracket]; + case DESTRUCTIVE: + return destructiveAttackSpeed[willBracket]; + default: + return -2.9; + } + } + + public double getHealthBonus(EnumDemonWillType type, int willBracket) + { + switch (type) + { + case STEADFAST: + return healthBonus[willBracket]; + default: + return 0; + } + } + + public double getMovementSpeed(EnumDemonWillType type, int willBracket) + { + switch (type) + { + case VENGEFUL: + return movementSpeed[willBracket]; + default: + return 0; + } + } + + public double getDigSpeed(EnumDemonWillType type, int willBracket) + { + switch (type) + { + case VENGEFUL: +// return movementSpeed[willBracket]; + default: + return defaultDigSpeedAdded[willBracket]; + } + } + + public void applyEffectToEntity(EnumDemonWillType type, int willBracket, LivingEntity target, PlayerEntity attacker) + { + switch (type) + { + case CORROSIVE: + target.addPotionEffect(new EffectInstance(Effects.WITHER, poisonTime[willBracket], poisonLevel[willBracket])); + break; + case DEFAULT: + break; + case DESTRUCTIVE: + break; + case STEADFAST: + if (!target.isAlive()) + { + float absorption = attacker.getAbsorptionAmount(); + attacker.addPotionEffect(new EffectInstance(Effects.ABSORPTION, absorptionTime[willBracket], 127)); + attacker.setAbsorptionAmount((float) Math.min(absorption + target.getMaxHealth() + * 0.05f, maxAbsorptionHearts)); + } + break; + case VENGEFUL: + break; + } + } + + @Override + public boolean hitEntity(ItemStack stack, LivingEntity target, LivingEntity attacker) + { + if (super.hitEntity(stack, target, attacker)) + { + if (attacker instanceof PlayerEntity) + { + PlayerEntity attackerPlayer = (PlayerEntity) attacker; + this.recalculatePowers(stack, attackerPlayer.getEntityWorld(), attackerPlayer); + EnumDemonWillType type = this.getCurrentType(stack); + double will = PlayerDemonWillHandler.getTotalDemonWill(type, attackerPlayer); + int willBracket = this.getLevel(stack, will); + + applyEffectToEntity(type, willBracket, target, attackerPlayer); + +// ItemStack offStack = attackerPlayer.getItemStackFromSlot(EquipmentSlotType.OFFHAND); +// if (offStack.getItem() instanceof ISentientSwordEffectProvider) +// { +// ISentientSwordEffectProvider provider = (ISentientSwordEffectProvider) offStack.getItem(); +// if (provider.providesEffectForWill(type)) +// { +// provider.applyOnHitEffect(type, stack, offStack, attacker, target); +// } +// } + } + + return true; + } + + return false; + } + + @Override + public EnumDemonWillType getCurrentType(ItemStack stack) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + + if (!tag.contains(Constants.NBT.WILL_TYPE)) + { + return EnumDemonWillType.DEFAULT; + } + + return EnumDemonWillType.valueOf(tag.getString(Constants.NBT.WILL_TYPE).toUpperCase(Locale.ENGLISH)); + } + + public void setCurrentType(ItemStack stack, EnumDemonWillType type) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + + tag.putString(Constants.NBT.WILL_TYPE, type.toString()); + } + + @Override + public ActionResult onItemRightClick(World world, PlayerEntity player, Hand hand) + { + recalculatePowers(player.getHeldItem(hand), world, player); + + return super.onItemRightClick(world, player, hand); + } + + @Override + public boolean shouldCauseReequipAnimation(ItemStack oldStack, ItemStack newStack, boolean slotChanged) + { + return oldStack.getItem() != newStack.getItem(); + } + + private int getLevel(ItemStack stack, double soulsRemaining) + { + int lvl = -1; + for (int i = 0; i < soulBracket.length; i++) + { + if (soulsRemaining >= soulBracket[i]) + { + lvl = i; + } + } + + return lvl; + } + + @Override + @OnlyIn(Dist.CLIENT) + public void addInformation(ItemStack stack, World world, List tooltip, ITooltipFlag flag) + { + if (!stack.hasTag()) + return; + +// tooltip.addAll(Arrays.asList(TextHelper.cutLongString(TextHelper.localizeEffect("tooltip.bloodmagic.sentientSword.desc")))); + tooltip.add(new TranslationTextComponent("tooltip.bloodmagic.sentientShovel.desc")); + tooltip.add(new TranslationTextComponent("tooltip.bloodmagic.currentType." + getCurrentType(stack).name().toLowerCase())); + } + + @Override + public boolean onLeftClickEntity(ItemStack stack, PlayerEntity player, Entity entity) + { + recalculatePowers(stack, player.getEntityWorld(), player); + + double drain = this.getDrainOfActivatedSword(stack); + if (drain > 0) + { + EnumDemonWillType type = getCurrentType(stack); + double soulsRemaining = PlayerDemonWillHandler.getTotalDemonWill(type, player); + + if (drain > soulsRemaining) + { + return false; + } else + { + PlayerDemonWillHandler.consumeDemonWill(type, player, drain); + } + } + + return super.onLeftClickEntity(stack, player, entity); + } + + @Override + public List getRandomDemonWillDrop(LivingEntity killedEntity, LivingEntity attackingEntity, ItemStack stack, int looting) + { + List soulList = new ArrayList<>(); + + if (killedEntity.getEntityWorld().getDifficulty() != Difficulty.PEACEFUL && !(killedEntity instanceof IMob)) + { + return soulList; + } + + double willModifier = killedEntity instanceof SlimeEntity ? 0.67 : 1; + + IDemonWill soul; + + EnumDemonWillType type = this.getCurrentType(stack); + switch (type) + { + case CORROSIVE: + soul = ((IDemonWill) BloodMagicItems.MONSTER_SOUL_CORROSIVE.get()); + break; + case DESTRUCTIVE: + soul = ((IDemonWill) BloodMagicItems.MONSTER_SOUL_DESTRUCTIVE.get()); + break; + case STEADFAST: + soul = ((IDemonWill) BloodMagicItems.MONSTER_SOUL_STEADFAST.get()); + break; + case VENGEFUL: + soul = ((IDemonWill) BloodMagicItems.MONSTER_SOUL_VENGEFUL.get()); + break; + default: + soul = ((IDemonWill) BloodMagicItems.MONSTER_SOUL_RAW.get()); + break; + } + + for (int i = 0; i <= looting; i++) + { + if (i == 0 || attackingEntity.getEntityWorld().rand.nextDouble() < 0.4) + { + ItemStack soulStack = soul.createWill(willModifier * (this.getDropOfActivatedSword(stack) + * attackingEntity.getEntityWorld().rand.nextDouble() + this.getStaticDropOfActivatedSword(stack)) + * killedEntity.getMaxHealth() / 20d); + soulList.add(soulStack); + } + } + + return soulList; + } + + // TODO: Change attack speed. + @Override + public Multimap getAttributeModifiers(EquipmentSlotType slot, ItemStack stack) + { + Multimap multimap = HashMultimap.create(); + if (slot == EquipmentSlotType.MAINHAND) + { + multimap.put(Attributes.ATTACK_DAMAGE, new AttributeModifier(ATTACK_DAMAGE_MODIFIER, "Weapon modifier", getDamageOfActivatedSword(stack), AttributeModifier.Operation.ADDITION)); + multimap.put(Attributes.ATTACK_SPEED, new AttributeModifier(ATTACK_SPEED_MODIFIER, "Weapon modifier", this.getAttackSpeedOfSword(stack), AttributeModifier.Operation.ADDITION)); + multimap.put(Attributes.MAX_HEALTH, new AttributeModifier(new UUID(0, 31818145), "Weapon modifier", this.getHealthBonusOfSword(stack), AttributeModifier.Operation.ADDITION)); + multimap.put(Attributes.MOVEMENT_SPEED, new AttributeModifier(new UUID(0, 4218052), "Weapon modifier", this.getSpeedOfSword(stack), AttributeModifier.Operation.ADDITION)); + } + + return multimap; + } + + public double getDamageOfActivatedSword(ItemStack stack) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + return tag.getDouble(Constants.NBT.SOUL_SWORD_DAMAGE); + } + + public void setDamageOfActivatedSword(ItemStack stack, double damage) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + + tag.putDouble(Constants.NBT.SOUL_SWORD_DAMAGE, damage); + } + + public double getDrainOfActivatedSword(ItemStack stack) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + return tag.getDouble(Constants.NBT.SOUL_SWORD_ACTIVE_DRAIN); + } + + public void setDrainOfActivatedSword(ItemStack stack, double drain) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + + tag.putDouble(Constants.NBT.SOUL_SWORD_ACTIVE_DRAIN, drain); + } + + public double getStaticDropOfActivatedSword(ItemStack stack) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + return tag.getDouble(Constants.NBT.SOUL_SWORD_STATIC_DROP); + } + + public void setStaticDropOfActivatedSword(ItemStack stack, double drop) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + + tag.putDouble(Constants.NBT.SOUL_SWORD_STATIC_DROP, drop); + } + + public double getDropOfActivatedSword(ItemStack stack) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + return tag.getDouble(Constants.NBT.SOUL_SWORD_DROP); + } + + public void setDropOfActivatedSword(ItemStack stack, double drop) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + + tag.putDouble(Constants.NBT.SOUL_SWORD_DROP, drop); + } + + public double getHealthBonusOfSword(ItemStack stack) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + return tag.getDouble(Constants.NBT.SOUL_SWORD_HEALTH); + } + + public void setHealthBonusOfSword(ItemStack stack, double hp) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + + tag.putDouble(Constants.NBT.SOUL_SWORD_HEALTH, hp); + } + + public double getAttackSpeedOfSword(ItemStack stack) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + return tag.getDouble(Constants.NBT.SOUL_SWORD_ATTACK_SPEED); + } + + public void setAttackSpeedOfSword(ItemStack stack, double speed) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + + tag.putDouble(Constants.NBT.SOUL_SWORD_ATTACK_SPEED, speed); + } + + public double getSpeedOfSword(ItemStack stack) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + return tag.getDouble(Constants.NBT.SOUL_SWORD_SPEED); + } + + public void setSpeedOfSword(ItemStack stack, double speed) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + + tag.putDouble(Constants.NBT.SOUL_SWORD_SPEED, speed); + } + + public double getDigSpeedOfSword(ItemStack stack) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + return tag.getDouble(Constants.NBT.SOUL_SWORD_DIG_SPEED); + } + + public void setDigSpeedOfSword(ItemStack stack, double speed) + { + NBTHelper.checkNBT(stack); + + CompoundNBT tag = stack.getTag(); + + tag.putDouble(Constants.NBT.SOUL_SWORD_DIG_SPEED, speed); + } + +// @Override +// public boolean spawnSentientEntityOnDrop(ItemStack droppedStack, PlayerEntity player) +// { +// World world = player.getEntityWorld(); +// if (!world.isRemote) +// { +// this.recalculatePowers(droppedStack, world, player); +// +// EnumDemonWillType type = this.getCurrentType(droppedStack); +// double soulsRemaining = PlayerDemonWillHandler.getTotalDemonWill(type, player); +// if (soulsRemaining < 1024) +// { +// return false; +// } +// +// PlayerDemonWillHandler.consumeDemonWill(type, player, 100); +// +// EntitySentientSpecter specterEntity = new EntitySentientSpecter(world); +// specterEntity.setPosition(player.posX, player.posY, player.posZ); +// world.spawnEntity(specterEntity); +// +// specterEntity.setItemStackToSlot(EquipmentSlotType.MAINHAND, droppedStack.copy()); +// +// specterEntity.setType(this.getCurrentType(droppedStack)); +// specterEntity.setOwner(player); +// specterEntity.setTamed(true); +// +// return true; +// } +// +// return false; +// } +} diff --git a/src/main/java/wayoftime/bloodmagic/common/item/soul/ItemSentientSword.java b/src/main/java/wayoftime/bloodmagic/common/item/soul/ItemSentientSword.java index 3271ac3e..e149931c 100644 --- a/src/main/java/wayoftime/bloodmagic/common/item/soul/ItemSentientSword.java +++ b/src/main/java/wayoftime/bloodmagic/common/item/soul/ItemSentientSword.java @@ -335,9 +335,27 @@ public class ItemSentientSword extends SwordItem implements IDemonWillWeapon, IM double willModifier = killedEntity instanceof SlimeEntity ? 0.67 : 1; - IDemonWill soul = ((IDemonWill) BloodMagicItems.MONSTER_SOUL_RAW.get()); + IDemonWill soul; EnumDemonWillType type = this.getCurrentType(stack); + switch (type) + { + case CORROSIVE: + soul = ((IDemonWill) BloodMagicItems.MONSTER_SOUL_CORROSIVE.get()); + break; + case DESTRUCTIVE: + soul = ((IDemonWill) BloodMagicItems.MONSTER_SOUL_DESTRUCTIVE.get()); + break; + case STEADFAST: + soul = ((IDemonWill) BloodMagicItems.MONSTER_SOUL_STEADFAST.get()); + break; + case VENGEFUL: + soul = ((IDemonWill) BloodMagicItems.MONSTER_SOUL_VENGEFUL.get()); + break; + default: + soul = ((IDemonWill) BloodMagicItems.MONSTER_SOUL_RAW.get()); + break; + } for (int i = 0; i <= looting; i++) { diff --git a/src/main/java/wayoftime/bloodmagic/common/recipe/TartaricForgeRecipeProvider.java b/src/main/java/wayoftime/bloodmagic/common/recipe/TartaricForgeRecipeProvider.java index bf176061..fce5ea2e 100644 --- a/src/main/java/wayoftime/bloodmagic/common/recipe/TartaricForgeRecipeProvider.java +++ b/src/main/java/wayoftime/bloodmagic/common/recipe/TartaricForgeRecipeProvider.java @@ -27,6 +27,9 @@ public class TartaricForgeRecipeProvider implements ISubRecipeProvider TartaricForgeRecipeBuilder.tartaricForge(new ItemStack(BloodMagicItems.GREATER_GEM.get()), 1000, 100, Ingredient.fromItems(BloodMagicItems.COMMON_GEM.get()), Ingredient.fromItems(BloodMagicItems.DEMONIC_SLATE.get()), Ingredient.fromItems(BloodMagicItems.WEAK_BLOOD_SHARD.get()), Ingredient.fromTag(BloodMagicTags.CRYSTAL_DEMON)).build(consumer, BloodMagic.rl(basePath + "greatertartaricgem")); TartaricForgeRecipeBuilder.tartaricForge(new ItemStack(BloodMagicItems.SENTIENT_SWORD.get()), 0, 0, Ingredient.fromItems(BloodMagicItems.PETTY_GEM.get()), Ingredient.fromItems(Items.IRON_SWORD)).build(consumer, BloodMagic.rl(basePath + "sentientsword")); + TartaricForgeRecipeBuilder.tartaricForge(new ItemStack(BloodMagicItems.SENTIENT_AXE.get()), 0, 0, Ingredient.fromItems(BloodMagicItems.PETTY_GEM.get()), Ingredient.fromItems(Items.IRON_AXE)).build(consumer, BloodMagic.rl(basePath + "sentientaxe")); + TartaricForgeRecipeBuilder.tartaricForge(new ItemStack(BloodMagicItems.SENTIENT_PICKAXE.get()), 0, 0, Ingredient.fromItems(BloodMagicItems.PETTY_GEM.get()), Ingredient.fromItems(Items.IRON_PICKAXE)).build(consumer, BloodMagic.rl(basePath + "sentientpickaxe")); + TartaricForgeRecipeBuilder.tartaricForge(new ItemStack(BloodMagicItems.SENTIENT_SHOVEL.get()), 0, 0, Ingredient.fromItems(BloodMagicItems.PETTY_GEM.get()), Ingredient.fromItems(Items.IRON_SHOVEL)).build(consumer, BloodMagic.rl(basePath + "sentientshovel")); TartaricForgeRecipeBuilder.tartaricForge(new ItemStack(BloodMagicItems.REAGENT_AIR.get()), 128, 20, Ingredient.fromItems(Items.GHAST_TEAR), Ingredient.fromTag(Tags.Items.FEATHERS), Ingredient.fromTag(Tags.Items.FEATHERS)).build(consumer, BloodMagic.rl(basePath + "reagent_air")); TartaricForgeRecipeBuilder.tartaricForge(new ItemStack(BloodMagicItems.ARCANE_ASHES.get()), 0, 0, Ingredient.fromTag(Tags.Items.DUSTS_REDSTONE), Ingredient.fromTag(Tags.Items.DYES_WHITE), Ingredient.fromTag(Tags.Items.GUNPOWDER), Ingredient.fromTag(ItemTags.COALS)).build(consumer, BloodMagic.rl(basePath + "arcaneashes"));