diff --git a/README.md b/README.md index ea9a8b52a..067c4cd9d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ Biomancy -[![Biomancy Version](https://img.shields.io/badge/Biomancy-1.0.0--beta.2-yellow)](https://github.com/Elenterius/Biomancy) +[![Biomancy Version](https://img.shields.io/badge/Biomancy-1.0.0--beta.3-yellow)](https://github.com/Elenterius/Biomancy) [![Forge Version](https://img.shields.io/badge/Minecraft%20Forge-1.16.5--36.1.4-orange)](https://files.minecraftforge.net/maven/net/minecraftforge/forge/index_1.16.5.html) Biomancy is a Biopunk inspired Mod and themed around flesh magic and bio-manipulation. diff --git a/gradle.properties b/gradle.properties index 719ab5dab..44657297b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,4 +4,4 @@ org.gradle.jvmargs=-Xmx3G org.gradle.daemon=false mc_version=1.16.5 forge_version=36.1.4 -mod_version=1.0.0-beta.2 +mod_version=1.0.0-beta.3 diff --git a/media/digester_and_decomposer.png b/media/digester_and_decomposer.png new file mode 100644 index 000000000..2dc93bea0 Binary files /dev/null and b/media/digester_and_decomposer.png differ diff --git a/scripts/biomancy_production_digraph.gml b/scripts/biomancy_production_digraph.gml index 1ec1e53cc..fff92e391 100644 --- a/scripts/biomancy_production_digraph.gml +++ b/scripts/biomancy_production_digraph.gml @@ -30,7 +30,7 @@ graph [ ] node [ id 7 - label "bolus_from_mc_acacia_leaves_chewing" + label "bolus_from_average_biomass_chewing" ] node [ id 8 @@ -38,4857 +38,2599 @@ graph [ ] node [ id 9 - label "minecraft_acacia_leaves" + label "tag=biomancy_average_biomass" ] node [ id 10 - label "bolus_from_mc_acacia_sapling_chewing" + label "bolus_from_good_biomass_chewing" ] node [ id 11 - label "minecraft_acacia_sapling" + label "tag=biomancy_good_biomass" ] node [ id 12 - label "bolus_from_mc_allium_chewing" + label "bolus_from_poor_biomass_chewing" ] node [ id 13 - label "minecraft_allium" + label "tag=biomancy_poor_biomass" ] node [ id 14 - label "bolus_from_mc_apple_chewing" + label "bolus_from_superb_biomass_chewing" ] node [ id 15 - label "minecraft_apple" + label "tag=biomancy_superb_biomass" ] node [ id 16 - label "bolus_from_mc_azure_bluet_chewing" + label "cobblestone_from_stone_chewing" ] node [ id 17 - label "minecraft_azure_bluet" + label "minecraft_cobblestone" ] node [ id 18 - label "bolus_from_mc_baked_potato_chewing" + label "minecraft_stone" ] node [ id 19 - label "minecraft_baked_potato" + label "enchanted_book_attuned_bane_1_evolution_pool" ] node [ id 20 - label "bolus_from_mc_beetroot_chewing" + label "minecraft_enchanted_book" ] node [ id 21 - label "minecraft_beetroot" + label "tag=biomancy_stomachs" ] node [ id 22 - label "bolus_from_mc_beetroot_seeds_chewing" + label "biomancy_eroding_bile" ] node [ id 23 - label "minecraft_beetroot_seeds" + label "biomancy_rejuvenating_mucus" ] node [ id 24 - label "bolus_from_mc_birch_leaves_chewing" + label "enchanted_book_attuned_bane_2_evolution_pool" ] node [ id 25 - label "minecraft_birch_leaves" + label "enchanted_book_attuned_bane_3_evolution_pool" ] node [ id 26 - label "bolus_from_mc_birch_sapling_chewing" + label "enchanted_book_attuned_bane_4_evolution_pool" ] node [ id 27 - label "minecraft_birch_sapling" + label "enchanted_book_attuned_bane_5_evolution_pool" ] node [ id 28 - label "bolus_from_mc_blue_orchid_chewing" + label "entity_storage_evolution_pool" ] node [ id 29 - label "minecraft_blue_orchid" + label "biomancy_entity_storage" ] node [ id 30 - label "bolus_from_mc_bread_chewing" + label "minecraft_egg" ] node [ id 31 - label "minecraft_bread" + label "minecraft_ender_chest" ] node [ id 32 - label "bolus_from_mc_brown_mushroom_block_chewing" + label "eroding_bile_decomposing" ] node [ id 33 - label "minecraft_brown_mushroom_block" + label "biomancy_flesh_lump" ] node [ id 34 - label "bolus_from_mc_brown_mushroom_chewing" + label "minecraft_rotten_flesh" ] node [ id 35 - label "minecraft_brown_mushroom" + label "fleshborn_axe_evolution_pool" ] node [ id 36 - label "bolus_from_mc_cactus_chewing" + label "biomancy_fleshborn_axe" ] node [ id 37 - label "minecraft_cactus" + label "minecraft_iron_axe" ] node [ id 38 - label "bolus_from_mc_cake_chewing" + label "minecraft_bone" ] node [ id 39 - label "minecraft_cake" + label "fleshborn_chest_evolution_pool" ] node [ id 40 - label "bolus_from_mc_carrot_chewing" + label "biomancy_fleshborn_chest" ] node [ id 41 - label "minecraft_carrot" + label "minecraft_chest" ] node [ id 42 - label "bolus_from_mc_carved_pumpkin_chewing" + label "fleshborn_door_evolution_pool" ] node [ id 43 - label "minecraft_carved_pumpkin" + label "biomancy_fleshborn_door" ] node [ id 44 - label "bolus_from_mc_cocoa_beans_chewing" + label "minecraft_iron_door" ] node [ id 45 - label "minecraft_cocoa_beans" + label "fleshborn_guan_dao_evolution_pool" ] node [ id 46 - label "bolus_from_mc_cookie_chewing" + label "biomancy_fleshborn_guan_dao" ] node [ id 47 - label "minecraft_cookie" + label "biomancy_oculus" ] node [ id 48 - label "bolus_from_mc_cornflower_chewing" + label "minecraft_diamond_sword" ] node [ id 49 - label "minecraft_cornflower" + label "minecraft_diamond_axe" ] node [ id 50 - label "bolus_from_mc_crimson_fungus_chewing" + label "fleshborn_pickaxe_evolution_pool" ] node [ id 51 - label "minecraft_crimson_fungus" + label "biomancy_fleshborn_pickaxe" ] node [ id 52 - label "bolus_from_mc_crimson_roots_chewing" + label "minecraft_iron_pickaxe" ] node [ id 53 - label "minecraft_crimson_roots" + label "fleshborn_pressure_plate_evolution_pool" ] node [ id 54 - label "bolus_from_mc_dandelion_chewing" + label "biomancy_fleshborn_pressure_plate" ] node [ id 55 - label "minecraft_dandelion" + label "minecraft_heavy_weighted_pressure_plate" ] node [ id 56 - label "bolus_from_mc_dark_oak_leaves_chewing" + label "fleshborn_shovel_evolution_pool" ] node [ id 57 - label "minecraft_dark_oak_leaves" + label "biomancy_fleshborn_shovel" ] node [ id 58 - label "bolus_from_mc_dark_oak_sapling_chewing" + label "minecraft_iron_shovel" ] node [ id 59 - label "minecraft_dark_oak_sapling" + label "fleshborn_trapdoor_evolution_pool" ] node [ id 60 - label "bolus_from_mc_dried_kelp_block_chewing" + label "biomancy_fleshborn_trapdoor" ] node [ id 61 - label "minecraft_dried_kelp_block" + label "minecraft_iron_trapdoor" ] node [ id 62 - label "bolus_from_mc_dried_kelp_chewing" + label "fleshborn_war_axe_evolution_pool" ] node [ id 63 - label "minecraft_dried_kelp" + label "biomancy_fleshborn_war_axe" ] node [ id 64 - label "bolus_from_mc_fern_chewing" + label "flesh_lump_decomposing" ] node [ id 65 - label "minecraft_fern" + label "biomancy_mutagenic_bile" ] node [ id 66 - label "bolus_from_mc_grass_chewing" + label "minecraft_chicken" ] node [ id 67 - label "minecraft_grass" + label "flesh_lump_from_raw_meat_decomposing" ] node [ id 68 - label "bolus_from_mc_hay_block_chewing" + label "biomancy_skin_chunk" ] node [ id 69 - label "minecraft_hay_block" + label "biomancy_bone_scraps" ] node [ id 70 - label "bolus_from_mc_jungle_leaves_chewing" + label "tag=biomancy_raw_meats" ] node [ id 71 - label "minecraft_jungle_leaves" + label "gold_nugget_evolution_pool" ] node [ id 72 - label "bolus_from_mc_jungle_sapling_chewing" + label "minecraft_gold_nugget" ] node [ id 73 - label "minecraft_jungle_sapling" + label "gravel_from_cobblestone_chewing" ] node [ id 74 - label "bolus_from_mc_kelp_chewing" + label "minecraft_gravel" ] node [ id 75 - label "minecraft_kelp" + label "gulge_evolution_pool" ] node [ id 76 - label "bolus_from_mc_large_fern_chewing" + label "biomancy_gulge" ] node [ id 77 - label "minecraft_large_fern" + label "hormone_bile_0_decomposing" ] node [ id 78 - label "bolus_from_mc_lilac_chewing" + label "minecraft_ink_sac" ] node [ id 79 - label "minecraft_lilac" + label "hormone_bile_1_decomposing" ] node [ id 80 - label "bolus_from_mc_lily_of_the_valley_chewing" + label "minecraft_rabbit_foot" ] node [ id 81 - label "minecraft_lily_of_the_valley" + label "hormone_bile_2_decomposing" ] node [ id 82 - label "bolus_from_mc_lily_pad_chewing" + label "minecraft_ghast_tear" ] node [ id 83 - label "minecraft_lily_pad" + label "hormone_bile_3_decomposing" ] node [ id 84 - label "bolus_from_mc_melon_chewing" + label "minecraft_spider_eye" ] node [ id 85 - label "minecraft_melon" + label "hormone_bile_4_decomposing" ] node [ id 86 - label "bolus_from_mc_melon_seeds_chewing" + label "minecraft_fermented_spider_eye" ] node [ id 87 - label "minecraft_melon_seeds" + label "hormone_bile_5_decomposing" ] node [ id 88 - label "bolus_from_mc_melon_slice_chewing" + label "minecraft_honeycomb" ] node [ id 89 - label "minecraft_melon_slice" + label "hormone_bile_6_decomposing" ] node [ id 90 - label "bolus_from_mc_mushroom_stem_chewing" + label "minecraft_slime_ball" ] node [ id 91 - label "minecraft_mushroom_stem" + label "iron_nugget_evolution_pool" ] node [ id 92 - label "bolus_from_mc_nether_sprouts_chewing" + label "minecraft_iron_nugget" ] node [ id 93 - label "minecraft_nether_sprouts" + label "keratin_filaments_0_decomposing" ] node [ id 94 - label "bolus_from_mc_nether_wart_block_chewing" + label "minecraft_scute" ] node [ id 95 - label "minecraft_nether_wart_block" + label "keratin_filaments_1_decomposing" ] node [ id 96 - label "bolus_from_mc_nether_wart_chewing" + label "tag=forge_leather" ] node [ id 97 - label "minecraft_nether_wart" + label "keratin_filaments_2_decomposing" ] node [ id 98 - label "bolus_from_mc_oak_leaves_chewing" + label "minecraft_rabbit_hide" ] node [ id 99 - label "minecraft_oak_leaves" + label "keratin_filaments_3_decomposing" ] node [ id 100 - label "bolus_from_mc_oak_sapling_chewing" + label "tag=forge_feathers" ] node [ id 101 - label "minecraft_oak_sapling" + label "keratin_filaments_4_decomposing" ] node [ id 102 - label "bolus_from_mc_orange_tulip_chewing" + label "tag=forge_string" ] node [ id 103 - label "minecraft_orange_tulip" + label "keratin_filaments_5_decomposing" ] node [ id 104 - label "bolus_from_mc_oxeye_daisy_chewing" + label "tag=minecraft_wool" ] node [ id 105 - label "minecraft_oxeye_daisy" + label "keratin_filaments_6_decomposing" ] node [ id 106 - label "bolus_from_mc_peony_chewing" + label "tag=minecraft_carpets" ] node [ id 107 - label "minecraft_peony" + label "keratin_filaments_7_decomposing" ] node [ id 108 - label "bolus_from_mc_pink_tulip_chewing" + label "minecraft_lead" ] node [ id 109 - label "minecraft_pink_tulip" + label "keratin_filaments_8_decomposing" ] node [ id 110 - label "bolus_from_mc_poppy_chewing" + label "minecraft_phantom_membrane" ] node [ id 111 - label "minecraft_poppy" + label "keratin_filaments_9_decomposing" ] node [ id 112 - label "bolus_from_mc_potato_chewing" + label "minecraft_prismarine_shard" ] node [ id 113 - label "minecraft_potato" + label "leech_claw_evolution_pool" ] node [ id 114 - label "bolus_from_mc_pumpkin_chewing" + label "biomancy_leech_claw" ] node [ id 115 - label "minecraft_pumpkin" + label "biomancy_injection_device" ] node [ id 116 - label "bolus_from_mc_pumpkin_pie_chewing" + label "long_range_claw_evolution_pool" ] node [ id 117 - label "minecraft_pumpkin_pie" + label "biomancy_long_range_claw" ] node [ id 118 - label "bolus_from_mc_pumpkin_seeds_chewing" + label "biomancy_sharp_bone" ] node [ id 119 - label "minecraft_pumpkin_seeds" + label "mutagenic_bile_0_decomposing" ] node [ id 120 - label "bolus_from_mc_red_mushroom_block_chewing" + label "biomancy_digestate" ] node [ id 121 - label "minecraft_red_mushroom_block" + label "minecraft_warped_fungus" ] node [ id 122 - label "bolus_from_mc_red_mushroom_chewing" + label "mutagenic_bile_1_decomposing" ] node [ id 123 - label "minecraft_red_mushroom" + label "minecraft_warped_wart_block" ] node [ id 124 - label "bolus_from_mc_red_tulip_chewing" + label "mutagenic_bile_2_decomposing" ] node [ id 125 - label "minecraft_red_tulip" + label "minecraft_warped_roots" ] node [ id 126 - label "bolus_from_mc_rose_bush_chewing" + label "nutrient_paste_from_average_biomass_digesting" ] node [ id 127 - label "minecraft_rose_bush" + label "biomancy_nutrient_paste" ] node [ id 128 - label "bolus_from_mc_seagrass_chewing" + label "nutrient_paste_from_bolus_digesting" ] node [ id 129 - label "minecraft_seagrass" + label "nutrient_paste_from_cooked_meat_digesting" ] node [ id 130 - label "bolus_from_mc_sea_pickle_chewing" + label "tag=biomancy_cooked_meats" ] node [ id 131 - label "minecraft_sea_pickle" + label "nutrient_paste_from_good_biomass_digesting" ] node [ id 132 - label "bolus_from_mc_shroomlight_chewing" + label "nutrient_paste_from_poor_biomass_digesting" ] node [ id 133 - label "minecraft_shroomlight" + label "nutrient_paste_from_raw_meat_digesting" ] node [ id 134 - label "bolus_from_mc_spruce_leaves_chewing" + label "nutrient_paste_from_superb_biomass_digesting" ] node [ id 135 - label "minecraft_spruce_leaves" + label "oxide_powder_0_decomposing" ] node [ id 136 - label "bolus_from_mc_spruce_sapling_chewing" + label "tag=forge_eggs" ] node [ id 137 - label "minecraft_spruce_sapling" + label "oxide_powder_1_decomposing" ] node [ id 138 - label "bolus_from_mc_sugar_cane_chewing" + label "minecraft_turtle_egg" ] node [ id 139 - label "minecraft_sugar_cane" + label "oxide_powder_2_decomposing" ] node [ id 140 - label "bolus_from_mc_sunflower_chewing" + label "tag=forge_bones" ] node [ id 141 - label "minecraft_sunflower" + label "oxide_powder_3_decomposing" ] node [ id 142 - label "bolus_from_mc_sweet_berries_chewing" + label "minecraft_bone_meal" ] node [ id 143 - label "minecraft_sweet_berries" + label "oxide_powder_from_gold_ingot_chewing" ] node [ id 144 - label "bolus_from_mc_tall_grass_chewing" + label "tag=forge_ingots/gold" ] node [ id 145 - label "minecraft_tall_grass" + label "oxide_powder_from_gold_nugget_chewing" ] node [ id 146 - label "bolus_from_mc_twisting_vines_chewing" + label "tag=forge_nuggets/gold" ] node [ id 147 - label "minecraft_twisting_vines" + label "oxide_powder_from_iron_ingot_chewing" ] node [ id 148 - label "bolus_from_mc_vine_chewing" + label "tag=forge_ingots/iron" ] node [ id 149 - label "minecraft_vine" + label "oxide_powder_from_iron_nugget_chewing" ] node [ id 150 - label "bolus_from_mc_warped_fungus_chewing" + label "tag=forge_nuggets/iron" ] node [ id 151 - label "minecraft_warped_fungus" + label "oxide_powder_from_netherite_ingot_chewing" ] node [ id 152 - label "bolus_from_mc_warped_roots_chewing" + label "tag=forge_ingots/netherite" ] node [ id 153 - label "minecraft_warped_roots" + label "oxide_powder_from_netherite_scrap_chewing" ] node [ id 154 - label "bolus_from_mc_warped_wart_block_chewing" + label "minecraft_netherite_scrap" ] node [ id 155 - label "minecraft_warped_wart_block" + label "oxide_powder_from_red_sand_decomposing" ] node [ id 156 - label "bolus_from_mc_weeping_vines_chewing" + label "biomancy_silicate_paste" ] node [ id 157 - label "minecraft_weeping_vines" + label "minecraft_red_sand" ] node [ id 158 - label "bolus_from_mc_wheat_chewing" + label "prismarine_crystals_evolution_pool" ] node [ id 159 - label "minecraft_wheat" + label "minecraft_prismarine_crystals" ] node [ id 160 - label "bolus_from_mc_wheat_seeds_chewing" + label "minecraft_quartz" ] node [ id 161 - label "minecraft_wheat_seeds" + label "minecraft_lapis_lazuli" ] node [ id 162 - label "bolus_from_mc_white_tulip_chewing" + label "tag=minecraft_fishes" ] node [ id 163 - label "minecraft_white_tulip" + label "prismarine_shard_evolution_pool" ] node [ id 164 - label "bolus_from_mc_wither_rose_chewing" + label "quartz_evolution_pool" ] node [ id 165 - label "minecraft_wither_rose" + label "red_sand_from_red_sandstone_chewing" ] node [ id 166 - label "cobblestone_from_stone_chewing" + label "minecraft_red_sandstone" ] node [ id 167 - label "minecraft_cobblestone" + label "rejuvenating_mucus_decomposing" ] node [ id 168 - label "minecraft_stone" + label "minecraft_suspicious_stew" ] node [ id 169 - label "enchanted_book_attuned_bane_1_evolution_pool" + label "rejuvenating_mucus_from_cooked_meat_decomposing" ] node [ id 170 - label "minecraft_enchanted_book" + label "rejuvenating_mucus_from_healing_potion_decomposing" ] node [ id 171 - label "biomancy_artificial_stomach" + label "minecraft_potion" ] node [ id 172 - label "biomancy_eroding_bile" + label "rejuvenating_mucus_from_long_regen_potion_decomposing" ] node [ id 173 - label "biomancy_rejuvenating_mucus" + label "rejuvenating_mucus_from_regen_potion_decomposing" ] node [ id 174 - label "enchanted_book_attuned_bane_2_evolution_pool" + label "rejuvenating_mucus_from_strong_healing_potion_decomposing" ] node [ id 175 - label "enchanted_book_attuned_bane_3_evolution_pool" + label "rejuvenating_mucus_from_strong_regen_potion_decomposing" ] node [ id 176 - label "enchanted_book_attuned_bane_4_evolution_pool" + label "sand_from_gravel_chewing" ] node [ id 177 - label "enchanted_book_attuned_bane_5_evolution_pool" + label "minecraft_sand" ] node [ id 178 - label "entity_storage_evolution_pool" + label "sand_from_sandstone_chewing" ] node [ id 179 - label "biomancy_entity_storage" + label "minecraft_sandstone" ] node [ id 180 - label "minecraft_egg" + label "shulker_shell_evolution_pool" ] node [ id 181 - label "minecraft_ender_chest" + label "minecraft_shulker_shell" ] node [ id 182 - label "eroding_bile_decomposing" + label "minecraft_popped_chorus_fruit" ] node [ id 183 - label "biomancy_flesh_lump" + label "silicate_paste_0_decomposing" ] node [ id 184 - label "minecraft_rotten_flesh" + label "minecraft_andesite" ] node [ id 185 - label "fleshborn_axe_evolution_pool" + label "silicate_paste_10_decomposing" ] node [ id 186 - label "biomancy_fleshborn_axe" + label "tag=forge_gems/prismarine" ] node [ id 187 - label "minecraft_iron_axe" + label "silicate_paste_11_decomposing" ] node [ id 188 - label "minecraft_bone" + label "minecraft_kelp" ] node [ id 189 - label "fleshborn_chest_evolution_pool" + label "silicate_paste_12_decomposing" ] node [ id 190 - label "biomancy_fleshborn_chest" + label "minecraft_dried_kelp" ] node [ id 191 - label "minecraft_chest" + label "silicate_paste_13_decomposing" ] node [ id 192 - label "fleshborn_door_evolution_pool" + label "minecraft_dried_kelp_block" ] node [ id 193 - label "biomancy_fleshborn_door" + label "silicate_paste_1_decomposing" ] node [ id 194 - label "minecraft_iron_door" + label "minecraft_diorite" ] node [ id 195 - label "fleshborn_guan_dao_evolution_pool" + label "silicate_paste_2_decomposing" ] node [ id 196 - label "biomancy_fleshborn_guan_dao" + label "minecraft_granite" ] node [ id 197 - label "biomancy_oculus" + label "silicate_paste_3_decomposing" ] node [ id 198 - label "minecraft_diamond_sword" + label "minecraft_redstone" ] node [ id 199 - label "minecraft_diamond_axe" + label "silicate_paste_4_decomposing" ] node [ id 200 - label "fleshborn_pickaxe_evolution_pool" + label "minecraft_nautilus_shell" ] node [ id 201 - label "biomancy_fleshborn_pickaxe" + label "silicate_paste_5_decomposing" ] node [ id 202 - label "minecraft_iron_pickaxe" + label "silicate_paste_6_decomposing" ] node [ id 203 - label "fleshborn_pressure_plate_evolution_pool" + label "minecraft_glowstone_dust" ] node [ id 204 - label "biomancy_fleshborn_pressure_plate" + label "silicate_paste_7_decomposing" ] node [ id 205 - label "minecraft_heavy_weighted_pressure_plate" + label "tag=forge_gems/emerald" ] node [ id 206 - label "fleshborn_shovel_evolution_pool" + label "silicate_paste_8_decomposing" ] node [ id 207 - label "biomancy_fleshborn_shovel" + label "tag=forge_gems/lapis" ] node [ id 208 - label "minecraft_iron_shovel" + label "silicate_paste_9_decomposing" ] node [ id 209 - label "fleshborn_trapdoor_evolution_pool" + label "tag=forge_gems/quartz" ] node [ id 210 - label "biomancy_fleshborn_trapdoor" + label "silicate_paste_from_red_sand_chewing" ] node [ id 211 - label "minecraft_iron_trapdoor" + label "silicate_paste_from_sand_chewing" ] node [ id 212 - label "fleshborn_war_axe_evolution_pool" + label "single_item_bag_evolution_pool" ] node [ id 213 - label "biomancy_fleshborn_war_axe" + label "biomancy_single_item_bag" ] node [ id 214 - label "flesh_lump_decomposing" + label "minecraft_hopper" ] node [ id 215 - label "biomancy_mutagenic_bile" + label "skeleton_skull_decomposing" ] node [ id 216 - label "minecraft_chicken" + label "minecraft_skeleton_skull" ] node [ id 217 - label "flesh_lump_from_raw_meat_decomposing" + label "minecraft_zombie_head" ] node [ id 218 - label "biomancy_skin_chunk" + label "sugar_from_average_biomass_decomposing" ] node [ id 219 - label "biomancy_bone_scraps" + label "minecraft_sugar" ] node [ id 220 - label "tag=biomancy_raw_meats" + label "sugar_from_good_biomass_decomposing" ] node [ id 221 - label "gold_nugget_evolution_pool" - ] - node [ - id 222 - label "minecraft_gold_nugget" - ] - node [ - id 223 - label "gravel_from_cobblestone_chewing" - ] - node [ - id 224 - label "minecraft_gravel" - ] - node [ - id 225 - label "gulge_evolution_pool" - ] - node [ - id 226 - label "biomancy_gulge" - ] - node [ - id 227 - label "hormone_bile_0_decomposing" - ] - node [ - id 228 - label "minecraft_ink_sac" - ] - node [ - id 229 - label "hormone_bile_1_decomposing" - ] - node [ - id 230 - label "minecraft_rabbit_foot" - ] - node [ - id 231 - label "hormone_bile_2_decomposing" - ] - node [ - id 232 - label "minecraft_ghast_tear" - ] - node [ - id 233 - label "hormone_bile_3_decomposing" - ] - node [ - id 234 - label "minecraft_spider_eye" - ] - node [ - id 235 - label "hormone_bile_4_decomposing" - ] - node [ - id 236 - label "minecraft_fermented_spider_eye" - ] - node [ - id 237 - label "hormone_bile_5_decomposing" - ] - node [ - id 238 - label "minecraft_honeycomb" - ] - node [ - id 239 - label "hormone_bile_6_decomposing" - ] - node [ - id 240 - label "minecraft_slime_ball" - ] - node [ - id 241 - label "iron_nugget_evolution_pool" - ] - node [ - id 242 - label "minecraft_iron_nugget" - ] - node [ - id 243 - label "keratin_filaments_0_decomposing" - ] - node [ - id 244 - label "minecraft_scute" - ] - node [ - id 245 - label "keratin_filaments_1_decomposing" - ] - node [ - id 246 - label "tag=forge_leather" - ] - node [ - id 247 - label "keratin_filaments_2_decomposing" - ] - node [ - id 248 - label "minecraft_rabbit_hide" - ] - node [ - id 249 - label "keratin_filaments_3_decomposing" - ] - node [ - id 250 - label "tag=forge_feathers" - ] - node [ - id 251 - label "keratin_filaments_4_decomposing" - ] - node [ - id 252 - label "tag=forge_string" - ] - node [ - id 253 - label "keratin_filaments_5_decomposing" - ] - node [ - id 254 - label "tag=minecraft_wool" - ] - node [ - id 255 - label "keratin_filaments_6_decomposing" - ] - node [ - id 256 - label "tag=minecraft_carpets" - ] - node [ - id 257 - label "keratin_filaments_7_decomposing" - ] - node [ - id 258 - label "minecraft_lead" - ] - node [ - id 259 - label "keratin_filaments_8_decomposing" - ] - node [ - id 260 - label "minecraft_phantom_membrane" - ] - node [ - id 261 - label "keratin_filaments_9_decomposing" - ] - node [ - id 262 - label "minecraft_prismarine_shard" - ] - node [ - id 263 - label "leech_claw_evolution_pool" - ] - node [ - id 264 - label "biomancy_leech_claw" - ] - node [ - id 265 - label "biomancy_injection_device" - ] - node [ - id 266 - label "long_range_claw_evolution_pool" - ] - node [ - id 267 - label "biomancy_long_range_claw" - ] - node [ - id 268 - label "biomancy_sharp_bone" - ] - node [ - id 269 - label "mutagenic_bile_0_decomposing" - ] - node [ - id 270 - label "biomancy_digestate" - ] - node [ - id 271 - label "mutagenic_bile_1_decomposing" - ] - node [ - id 272 - label "mutagenic_bile_2_decomposing" - ] - node [ - id 273 - label "nutrient_paste_digesting" - ] - node [ - id 274 - label "biomancy_nutrient_paste" - ] - node [ - id 275 - label "oxide_powder_0_decomposing" - ] - node [ - id 276 - label "tag=forge_eggs" - ] - node [ - id 277 - label "oxide_powder_1_decomposing" - ] - node [ - id 278 - label "minecraft_turtle_egg" - ] - node [ - id 279 - label "oxide_powder_2_decomposing" - ] - node [ - id 280 - label "tag=forge_bones" - ] - node [ - id 281 - label "oxide_powder_3_decomposing" - ] - node [ - id 282 - label "minecraft_bone_meal" - ] - node [ - id 283 - label "oxide_powder_from_gold_ingot_chewing" - ] - node [ - id 284 - label "tag=forge_ingots/gold" - ] - node [ - id 285 - label "oxide_powder_from_gold_nugget_chewing" - ] - node [ - id 286 - label "tag=forge_nuggets/gold" - ] - node [ - id 287 - label "oxide_powder_from_iron_ingot_chewing" - ] - node [ - id 288 - label "tag=forge_ingots/iron" - ] - node [ - id 289 - label "oxide_powder_from_iron_nugget_chewing" - ] - node [ - id 290 - label "tag=forge_nuggets/iron" - ] - node [ - id 291 - label "oxide_powder_from_netherite_ingot_chewing" - ] - node [ - id 292 - label "tag=forge_ingots/netherite" - ] - node [ - id 293 - label "oxide_powder_from_netherite_scrap_chewing" - ] - node [ - id 294 - label "minecraft_netherite_scrap" - ] - node [ - id 295 - label "oxide_powder_from_red_sand_decomposing" - ] - node [ - id 296 - label "biomancy_silicate_paste" - ] - node [ - id 297 - label "minecraft_red_sand" - ] - node [ - id 298 - label "prismarine_crystals_evolution_pool" - ] - node [ - id 299 - label "minecraft_prismarine_crystals" - ] - node [ - id 300 - label "minecraft_quartz" - ] - node [ - id 301 - label "minecraft_lapis_lazuli" - ] - node [ - id 302 - label "tag=minecraft_fishes" - ] - node [ - id 303 - label "prismarine_shard_evolution_pool" - ] - node [ - id 304 - label "quartz_evolution_pool" - ] - node [ - id 305 - label "red_sand_from_red_sandstone_chewing" - ] - node [ - id 306 - label "minecraft_red_sandstone" - ] - node [ - id 307 - label "rejuvenating_mucus_decomposing" - ] - node [ - id 308 - label "minecraft_suspicious_stew" - ] - node [ - id 309 - label "rejuvenating_mucus_from_cooked_meat_decomposing" - ] - node [ - id 310 - label "tag=biomancy_cooked_meats" - ] - node [ - id 311 - label "rejuvenating_mucus_from_healing_potion_decomposing" - ] - node [ - id 312 - label "minecraft_potion" - ] - node [ - id 313 - label "rejuvenating_mucus_from_long_regen_potion_decomposing" - ] - node [ - id 314 - label "rejuvenating_mucus_from_regen_potion_decomposing" - ] - node [ - id 315 - label "rejuvenating_mucus_from_strong_healing_potion_decomposing" - ] - node [ - id 316 - label "rejuvenating_mucus_from_strong_regen_potion_decomposing" - ] - node [ - id 317 - label "sand_from_gravel_chewing" - ] - node [ - id 318 - label "minecraft_sand" - ] - node [ - id 319 - label "sand_from_sandstone_chewing" - ] - node [ - id 320 - label "minecraft_sandstone" - ] - node [ - id 321 - label "shulker_shell_evolution_pool" - ] - node [ - id 322 - label "minecraft_shulker_shell" - ] - node [ - id 323 - label "minecraft_popped_chorus_fruit" - ] - node [ - id 324 - label "silicate_paste_0_decomposing" - ] - node [ - id 325 - label "minecraft_andesite" - ] - node [ - id 326 - label "silicate_paste_10_decomposing" - ] - node [ - id 327 - label "tag=forge_gems/prismarine" - ] - node [ - id 328 - label "silicate_paste_11_decomposing" - ] - node [ - id 329 - label "silicate_paste_12_decomposing" - ] - node [ - id 330 - label "silicate_paste_13_decomposing" - ] - node [ - id 331 - label "silicate_paste_1_decomposing" - ] - node [ - id 332 - label "minecraft_diorite" - ] - node [ - id 333 - label "silicate_paste_2_decomposing" - ] - node [ - id 334 - label "minecraft_granite" - ] - node [ - id 335 - label "silicate_paste_3_decomposing" - ] - node [ - id 336 - label "minecraft_redstone" - ] - node [ - id 337 - label "silicate_paste_4_decomposing" - ] - node [ - id 338 - label "minecraft_nautilus_shell" - ] - node [ - id 339 - label "silicate_paste_5_decomposing" - ] - node [ - id 340 - label "silicate_paste_6_decomposing" - ] - node [ - id 341 - label "minecraft_glowstone_dust" - ] - node [ - id 342 - label "silicate_paste_7_decomposing" - ] - node [ - id 343 - label "tag=forge_gems/emerald" - ] - node [ - id 344 - label "silicate_paste_8_decomposing" - ] - node [ - id 345 - label "tag=forge_gems/lapis" - ] - node [ - id 346 - label "silicate_paste_9_decomposing" - ] - node [ - id 347 - label "tag=forge_gems/quartz" - ] - node [ - id 348 - label "silicate_paste_from_red_sand_chewing" - ] - node [ - id 349 - label "silicate_paste_from_sand_chewing" - ] - node [ - id 350 - label "single_item_bag_evolution_pool" - ] - node [ - id 351 - label "biomancy_single_item_bag" - ] - node [ - id 352 - label "minecraft_hopper" - ] - node [ - id 353 - label "skeleton_skull_decomposing" - ] - node [ - id 354 - label "minecraft_skeleton_skull" - ] - node [ - id 355 - label "minecraft_zombie_head" - ] - node [ - id 356 - label "sugar_from_mc_acacia_leaves_decomposing" - ] - node [ - id 357 - label "minecraft_sugar" - ] - node [ - id 358 - label "sugar_from_mc_acacia_sapling_decomposing" - ] - node [ - id 359 - label "sugar_from_mc_allium_decomposing" - ] - node [ - id 360 - label "sugar_from_mc_apple_decomposing" - ] - node [ - id 361 - label "sugar_from_mc_azure_bluet_decomposing" - ] - node [ - id 362 - label "sugar_from_mc_baked_potato_decomposing" - ] - node [ - id 363 - label "sugar_from_mc_beetroot_decomposing" - ] - node [ - id 364 - label "sugar_from_mc_beetroot_seeds_decomposing" - ] - node [ - id 365 - label "sugar_from_mc_birch_leaves_decomposing" - ] - node [ - id 366 - label "sugar_from_mc_birch_sapling_decomposing" - ] - node [ - id 367 - label "sugar_from_mc_blue_orchid_decomposing" - ] - node [ - id 368 - label "sugar_from_mc_bread_decomposing" - ] - node [ - id 369 - label "sugar_from_mc_brown_mushroom_block_decomposing" - ] - node [ - id 370 - label "sugar_from_mc_brown_mushroom_decomposing" - ] - node [ - id 371 - label "sugar_from_mc_cactus_decomposing" - ] - node [ - id 372 - label "sugar_from_mc_cake_decomposing" - ] - node [ - id 373 - label "sugar_from_mc_carrot_decomposing" - ] - node [ - id 374 - label "sugar_from_mc_carved_pumpkin_decomposing" - ] - node [ - id 375 - label "sugar_from_mc_cocoa_beans_decomposing" - ] - node [ - id 376 - label "sugar_from_mc_cookie_decomposing" - ] - node [ - id 377 - label "sugar_from_mc_cornflower_decomposing" - ] - node [ - id 378 - label "sugar_from_mc_crimson_fungus_decomposing" - ] - node [ - id 379 - label "sugar_from_mc_crimson_roots_decomposing" - ] - node [ - id 380 - label "sugar_from_mc_dandelion_decomposing" - ] - node [ - id 381 - label "sugar_from_mc_dark_oak_leaves_decomposing" - ] - node [ - id 382 - label "sugar_from_mc_dark_oak_sapling_decomposing" - ] - node [ - id 383 - label "sugar_from_mc_dried_kelp_block_decomposing" - ] - node [ - id 384 - label "sugar_from_mc_dried_kelp_decomposing" - ] - node [ - id 385 - label "sugar_from_mc_fern_decomposing" - ] - node [ - id 386 - label "sugar_from_mc_grass_decomposing" - ] - node [ - id 387 - label "sugar_from_mc_hay_block_decomposing" - ] - node [ - id 388 - label "sugar_from_mc_jungle_leaves_decomposing" - ] - node [ - id 389 - label "sugar_from_mc_jungle_sapling_decomposing" - ] - node [ - id 390 - label "sugar_from_mc_kelp_decomposing" - ] - node [ - id 391 - label "sugar_from_mc_large_fern_decomposing" - ] - node [ - id 392 - label "sugar_from_mc_lilac_decomposing" - ] - node [ - id 393 - label "sugar_from_mc_lily_of_the_valley_decomposing" - ] - node [ - id 394 - label "sugar_from_mc_lily_pad_decomposing" - ] - node [ - id 395 - label "sugar_from_mc_melon_decomposing" - ] - node [ - id 396 - label "sugar_from_mc_melon_seeds_decomposing" - ] - node [ - id 397 - label "sugar_from_mc_melon_slice_decomposing" - ] - node [ - id 398 - label "sugar_from_mc_mushroom_stem_decomposing" - ] - node [ - id 399 - label "sugar_from_mc_nether_sprouts_decomposing" - ] - node [ - id 400 - label "sugar_from_mc_nether_wart_block_decomposing" - ] - node [ - id 401 - label "sugar_from_mc_nether_wart_decomposing" - ] - node [ - id 402 - label "sugar_from_mc_oak_leaves_decomposing" - ] - node [ - id 403 - label "sugar_from_mc_oak_sapling_decomposing" - ] - node [ - id 404 - label "sugar_from_mc_orange_tulip_decomposing" - ] - node [ - id 405 - label "sugar_from_mc_oxeye_daisy_decomposing" - ] - node [ - id 406 - label "sugar_from_mc_peony_decomposing" - ] - node [ - id 407 - label "sugar_from_mc_pink_tulip_decomposing" - ] - node [ - id 408 - label "sugar_from_mc_poppy_decomposing" - ] - node [ - id 409 - label "sugar_from_mc_potato_decomposing" - ] - node [ - id 410 - label "sugar_from_mc_pumpkin_decomposing" - ] - node [ - id 411 - label "sugar_from_mc_pumpkin_pie_decomposing" - ] - node [ - id 412 - label "sugar_from_mc_pumpkin_seeds_decomposing" - ] - node [ - id 413 - label "sugar_from_mc_red_mushroom_block_decomposing" - ] - node [ - id 414 - label "sugar_from_mc_red_mushroom_decomposing" - ] - node [ - id 415 - label "sugar_from_mc_red_tulip_decomposing" - ] - node [ - id 416 - label "sugar_from_mc_rose_bush_decomposing" - ] - node [ - id 417 - label "sugar_from_mc_seagrass_decomposing" - ] - node [ - id 418 - label "sugar_from_mc_sea_pickle_decomposing" - ] - node [ - id 419 - label "sugar_from_mc_shroomlight_decomposing" - ] - node [ - id 420 - label "sugar_from_mc_spruce_leaves_decomposing" - ] - node [ - id 421 - label "sugar_from_mc_spruce_sapling_decomposing" - ] - node [ - id 422 - label "sugar_from_mc_sugar_cane_decomposing" - ] - node [ - id 423 - label "sugar_from_mc_sunflower_decomposing" - ] - node [ - id 424 - label "sugar_from_mc_sweet_berries_decomposing" - ] - node [ - id 425 - label "sugar_from_mc_tall_grass_decomposing" - ] - node [ - id 426 - label "sugar_from_mc_twisting_vines_decomposing" - ] - node [ - id 427 - label "sugar_from_mc_vine_decomposing" - ] - node [ - id 428 - label "sugar_from_mc_warped_fungus_decomposing" - ] - node [ - id 429 - label "sugar_from_mc_warped_roots_decomposing" - ] - node [ - id 430 - label "sugar_from_mc_warped_wart_block_decomposing" - ] - node [ - id 431 - label "sugar_from_mc_weeping_vines_decomposing" - ] - node [ - id 432 - label "sugar_from_mc_wheat_decomposing" - ] - node [ - id 433 - label "sugar_from_mc_wheat_seeds_decomposing" - ] - node [ - id 434 - label "sugar_from_mc_white_tulip_decomposing" - ] - node [ - id 435 - label "sugar_from_mc_wither_rose_decomposing" - ] - node [ - id 436 - label "tooth_gun_evolution_pool" - ] - node [ - id 437 - label "biomancy_tooth_gun" - ] - node [ - id 438 - label "minecraft_crossbow" - ] - node [ - id 439 - label "unveiling_oculi_evolution_pool" - ] - node [ - id 440 - label "biomancy_unveiling_oculi" - ] - node [ - id 441 - label "minecraft_iron_helmet" - ] - node [ - id 442 - label "withershot_evolution_pool" - ] - node [ - id 443 - label "biomancy_withershot" - ] - node [ - id 444 - label "minecraft_nether_star" - ] - node [ - id 445 - label "minecraft_wither_skeleton_skull" - ] - node [ - id 446 - label "wither_skeleton_skull_evolution_pool" - ] - node [ - id 447 - label "zombie_head_evolution_pool" - ] - node [ - id 448 - label "minecraft_player_head" - ] - edge [ - source 0 - target 1 - weight 1 - ] - edge [ - source 1 - target 185 - weight 3 - ] - edge [ - source 1 - target 189 - weight 1 - ] - edge [ - source 1 - target 192 - weight 1 - ] - edge [ - source 1 - target 195 - weight 1 - ] - edge [ - source 1 - target 200 - weight 3 - ] - edge [ - source 1 - target 203 - weight 1 - ] - edge [ - source 1 - target 206 - weight 1 - ] - edge [ - source 1 - target 209 - weight 1 - ] - edge [ - source 1 - target 225 - weight 1 - ] - edge [ - source 1 - target 263 - weight 1 - ] - edge [ - source 1 - target 266 - weight 1 - ] - edge [ - source 1 - target 436 - weight 1 - ] - edge [ - source 1 - target 439 - weight 1 - ] - edge [ - source 2 - target 0 - weight 1 - ] - edge [ - source 3 - target 0 - weight 1 - ] - edge [ - source 4 - target 0 - weight 2 - ] - edge [ - source 4 - target 221 - weight 5 - ] - edge [ - source 4 - target 241 - weight 5 - ] - edge [ - source 5 - target 0 - weight 1 - ] - edge [ - source 5 - target 178 - weight 2 - ] - edge [ - source 5 - target 189 - weight 2 - ] - edge [ - source 5 - target 192 - weight 2 - ] - edge [ - source 5 - target 203 - weight 2 - ] - edge [ - source 5 - target 206 - weight 2 - ] - edge [ - source 5 - target 209 - weight 2 - ] - edge [ - source 5 - target 212 - weight 2 - ] - edge [ - source 5 - target 303 - weight 2 - ] - edge [ - source 5 - target 350 - weight 2 - ] - edge [ - source 6 - target 0 - weight 1 - ] - edge [ - source 6 - target 185 - weight 1 - ] - edge [ - source 6 - target 189 - weight 1 - ] - edge [ - source 6 - target 192 - weight 1 - ] - edge [ - source 6 - target 200 - weight 1 - ] - edge [ - source 6 - target 203 - weight 1 - ] - edge [ - source 6 - target 206 - weight 1 - ] - edge [ - source 6 - target 209 - weight 1 - ] - edge [ - source 6 - target 212 - weight 1 - ] - edge [ - source 7 - target 8 - weight 1 - ] - edge [ - source 8 - target 273 - weight 1 - ] - edge [ - source 9 - target 7 - weight 1 - ] - edge [ - source 9 - target 356 - weight 1 - ] - edge [ - source 10 - target 8 - weight 1 - ] - edge [ - source 11 - target 10 - weight 1 - ] - edge [ - source 11 - target 358 - weight 1 - ] - edge [ - source 12 - target 8 - weight 4 - ] - edge [ - source 13 - target 12 - weight 1 - ] - edge [ - source 13 - target 359 - weight 1 - ] - edge [ - source 14 - target 8 - weight 4 - ] - edge [ - source 15 - target 14 - weight 1 - ] - edge [ - source 15 - target 360 - weight 1 - ] - edge [ - source 16 - target 8 - weight 4 - ] - edge [ - source 17 - target 16 - weight 1 - ] - edge [ - source 17 - target 361 - weight 1 - ] - edge [ - source 18 - target 8 - weight 5 - ] - edge [ - source 19 - target 18 - weight 1 - ] - edge [ - source 19 - target 362 - weight 1 - ] - edge [ - source 20 - target 8 - weight 4 - ] - edge [ - source 21 - target 20 - weight 1 - ] - edge [ - source 21 - target 363 - weight 1 - ] - edge [ - source 22 - target 8 - weight 1 - ] - edge [ - source 23 - target 22 - weight 1 - ] - edge [ - source 23 - target 364 - weight 1 - ] - edge [ - source 24 - target 8 - weight 1 - ] - edge [ - source 25 - target 24 - weight 1 - ] - edge [ - source 25 - target 365 - weight 1 - ] - edge [ - source 26 - target 8 - weight 1 - ] - edge [ - source 27 - target 26 - weight 1 - ] - edge [ - source 27 - target 366 - weight 1 - ] - edge [ - source 28 - target 8 - weight 4 - ] - edge [ - source 29 - target 28 - weight 1 - ] - edge [ - source 29 - target 367 - weight 1 - ] - edge [ - source 30 - target 8 - weight 5 - ] - edge [ - source 31 - target 30 - weight 1 - ] - edge [ - source 31 - target 368 - weight 1 - ] - edge [ - source 32 - target 8 - weight 5 - ] - edge [ - source 33 - target 32 - weight 1 - ] - edge [ - source 33 - target 369 - weight 1 - ] - edge [ - source 34 - target 8 - weight 4 - ] - edge [ - source 35 - target 34 - weight 1 - ] - edge [ - source 35 - target 370 - weight 1 - ] - edge [ - source 36 - target 8 - weight 2 - ] - edge [ - source 37 - target 36 - weight 1 - ] - edge [ - source 37 - target 371 - weight 1 - ] - edge [ - source 38 - target 8 - weight 6 - ] - edge [ - source 39 - target 38 - weight 1 - ] - edge [ - source 39 - target 372 - weight 1 - ] - edge [ - source 40 - target 8 - weight 4 - ] - edge [ - source 41 - target 40 - weight 1 - ] - edge [ - source 41 - target 373 - weight 1 - ] - edge [ - source 42 - target 8 - weight 4 - ] - edge [ - source 43 - target 42 - weight 1 - ] - edge [ - source 43 - target 374 - weight 1 - ] - edge [ - source 44 - target 8 - weight 4 - ] - edge [ - source 45 - target 44 - weight 1 - ] - edge [ - source 45 - target 375 - weight 1 - ] - edge [ - source 46 - target 8 - weight 5 - ] - edge [ - source 47 - target 46 - weight 1 - ] - edge [ - source 47 - target 376 - weight 1 - ] - edge [ - source 48 - target 8 - weight 4 - ] - edge [ - source 49 - target 48 - weight 1 - ] - edge [ - source 49 - target 377 - weight 1 - ] - edge [ - source 50 - target 8 - weight 4 - ] - edge [ - source 51 - target 50 - weight 1 - ] - edge [ - source 51 - target 378 - weight 1 - ] - edge [ - source 52 - target 8 - weight 4 - ] - edge [ - source 53 - target 52 - weight 1 - ] - edge [ - source 53 - target 379 - weight 1 - ] - edge [ - source 54 - target 8 - weight 4 - ] - edge [ - source 55 - target 54 - weight 1 - ] - edge [ - source 55 - target 380 - weight 1 - ] - edge [ - source 56 - target 8 - weight 1 - ] - edge [ - source 57 - target 56 - weight 1 - ] - edge [ - source 57 - target 381 - weight 1 - ] - edge [ - source 58 - target 8 - weight 1 - ] - edge [ - source 59 - target 58 - weight 1 - ] - edge [ - source 59 - target 382 - weight 1 - ] - edge [ - source 60 - target 8 - weight 2 - ] - edge [ - source 61 - target 60 - weight 1 - ] - edge [ - source 61 - target 330 - weight 1 - ] - edge [ - source 61 - target 383 - weight 1 - ] - edge [ - source 62 - target 8 - weight 1 - ] - edge [ - source 63 - target 62 - weight 1 - ] - edge [ - source 63 - target 329 - weight 6 - ] - edge [ - source 63 - target 384 - weight 1 - ] - edge [ - source 64 - target 8 - weight 4 - ] - edge [ - source 65 - target 64 - weight 1 - ] - edge [ - source 65 - target 385 - weight 1 - ] - edge [ - source 66 - target 8 - weight 1 - ] - edge [ - source 67 - target 66 - weight 1 - ] - edge [ - source 67 - target 386 - weight 1 - ] - edge [ - source 68 - target 8 - weight 5 - ] - edge [ - source 69 - target 68 - weight 1 - ] - edge [ - source 69 - target 387 - weight 1 - ] - edge [ - source 70 - target 8 - weight 1 - ] - edge [ - source 71 - target 70 - weight 1 - ] - edge [ - source 71 - target 388 - weight 1 - ] - edge [ - source 72 - target 8 - weight 1 - ] - edge [ - source 73 - target 72 - weight 1 - ] - edge [ - source 73 - target 389 - weight 1 - ] - edge [ - source 74 - target 8 - weight 1 - ] - edge [ - source 75 - target 74 - weight 1 - ] - edge [ - source 75 - target 328 - weight 6 - ] - edge [ - source 75 - target 390 - weight 1 - ] - edge [ - source 76 - target 8 - weight 4 - ] - edge [ - source 77 - target 76 - weight 1 - ] - edge [ - source 77 - target 391 - weight 1 - ] - edge [ - source 78 - target 8 - weight 4 - ] - edge [ - source 79 - target 78 - weight 1 - ] - edge [ - source 79 - target 392 - weight 1 - ] - edge [ - source 80 - target 8 - weight 4 - ] - edge [ - source 81 - target 80 - weight 1 - ] - edge [ - source 81 - target 393 - weight 1 - ] - edge [ - source 82 - target 8 - weight 4 - ] - edge [ - source 83 - target 82 - weight 1 - ] - edge [ - source 83 - target 394 - weight 1 - ] - edge [ - source 84 - target 8 - weight 4 - ] - edge [ - source 85 - target 84 - weight 1 - ] - edge [ - source 85 - target 395 - weight 1 - ] - edge [ - source 86 - target 8 - weight 1 - ] - edge [ - source 87 - target 86 - weight 1 - ] - edge [ - source 87 - target 396 - weight 1 - ] - edge [ - source 88 - target 8 - weight 2 - ] - edge [ - source 89 - target 88 - weight 1 - ] - edge [ - source 89 - target 397 - weight 1 - ] - edge [ - source 90 - target 8 - weight 4 - ] - edge [ - source 91 - target 90 - weight 1 - ] - edge [ - source 91 - target 398 - weight 1 - ] - edge [ - source 92 - target 8 - weight 2 - ] - edge [ - source 93 - target 92 - weight 1 - ] - edge [ - source 93 - target 399 - weight 1 - ] - edge [ - source 94 - target 8 - weight 5 - ] - edge [ - source 95 - target 94 - weight 1 - ] - edge [ - source 95 - target 400 - weight 1 - ] - edge [ - source 96 - target 8 - weight 4 - ] - edge [ - source 97 - target 96 - weight 1 - ] - edge [ - source 97 - target 401 - weight 1 - ] - edge [ - source 98 - target 8 - weight 1 - ] - edge [ - source 99 - target 98 - weight 1 - ] - edge [ - source 99 - target 402 - weight 1 - ] - edge [ - source 100 - target 8 - weight 1 - ] - edge [ - source 101 - target 100 - weight 1 - ] - edge [ - source 101 - target 403 - weight 1 - ] - edge [ - source 102 - target 8 - weight 4 - ] - edge [ - source 103 - target 102 - weight 1 - ] - edge [ - source 103 - target 404 - weight 1 - ] - edge [ - source 104 - target 8 - weight 4 - ] - edge [ - source 105 - target 104 - weight 1 - ] - edge [ - source 105 - target 405 - weight 1 - ] - edge [ - source 106 - target 8 - weight 4 - ] - edge [ - source 107 - target 106 - weight 1 - ] - edge [ - source 107 - target 406 - weight 1 - ] - edge [ - source 108 - target 8 - weight 4 - ] - edge [ - source 109 - target 108 - weight 1 - ] - edge [ - source 109 - target 407 - weight 1 - ] - edge [ - source 110 - target 8 - weight 4 - ] - edge [ - source 111 - target 110 - weight 1 - ] - edge [ - source 111 - target 408 - weight 1 - ] - edge [ - source 112 - target 8 - weight 4 - ] - edge [ - source 113 - target 112 - weight 1 - ] - edge [ - source 113 - target 409 - weight 1 - ] - edge [ - source 114 - target 8 - weight 4 - ] - edge [ - source 115 - target 114 - weight 1 - ] - edge [ - source 115 - target 410 - weight 1 - ] - edge [ - source 116 - target 8 - weight 6 - ] - edge [ - source 117 - target 116 - weight 1 - ] - edge [ - source 117 - target 411 - weight 1 - ] - edge [ - source 118 - target 8 - weight 1 - ] - edge [ - source 119 - target 118 - weight 1 - ] - edge [ - source 119 - target 412 - weight 1 - ] - edge [ - source 120 - target 8 - weight 5 - ] - edge [ - source 121 - target 120 - weight 1 - ] - edge [ - source 121 - target 413 - weight 1 - ] - edge [ - source 122 - target 8 - weight 4 - ] - edge [ - source 123 - target 122 - weight 1 - ] - edge [ - source 123 - target 414 - weight 1 - ] - edge [ - source 124 - target 8 - weight 4 - ] - edge [ - source 125 - target 124 - weight 1 - ] - edge [ - source 125 - target 415 - weight 1 - ] - edge [ - source 126 - target 8 - weight 4 - ] - edge [ - source 127 - target 126 - weight 1 - ] - edge [ - source 127 - target 416 - weight 1 - ] - edge [ - source 128 - target 8 - weight 1 - ] - edge [ - source 129 - target 128 - weight 1 - ] - edge [ - source 129 - target 417 - weight 1 - ] - edge [ - source 130 - target 8 - weight 4 - ] - edge [ - source 131 - target 130 - weight 1 - ] - edge [ - source 131 - target 418 - weight 1 - ] - edge [ - source 132 - target 8 - weight 4 - ] - edge [ - source 133 - target 132 - weight 1 - ] - edge [ - source 133 - target 419 - weight 1 - ] - edge [ - source 134 - target 8 - weight 1 - ] - edge [ - source 135 - target 134 - weight 1 - ] - edge [ - source 135 - target 420 - weight 1 - ] - edge [ - source 136 - target 8 - weight 1 - ] - edge [ - source 137 - target 136 - weight 1 - ] - edge [ - source 137 - target 421 - weight 1 + label "sugar_from_poor_biomass_decomposing" ] - edge [ - source 138 - target 8 - weight 2 - ] - edge [ - source 139 - target 138 - weight 1 - ] - edge [ - source 139 - target 422 - weight 1 - ] - edge [ - source 140 - target 8 - weight 4 - ] - edge [ - source 141 - target 140 - weight 1 - ] - edge [ - source 141 - target 423 - weight 1 - ] - edge [ - source 142 - target 8 - weight 1 + node [ + id 222 + label "sugar_from_superb_biomass_decomposing" ] - edge [ - source 143 - target 142 - weight 1 + node [ + id 223 + label "tooth_gun_evolution_pool" ] - edge [ - source 143 - target 424 - weight 1 + node [ + id 224 + label "biomancy_tooth_gun" ] - edge [ - source 144 - target 8 - weight 2 + node [ + id 225 + label "minecraft_crossbow" ] - edge [ - source 145 - target 144 - weight 1 + node [ + id 226 + label "unveiling_oculi_evolution_pool" ] - edge [ - source 145 - target 425 - weight 1 + node [ + id 227 + label "biomancy_unveiling_oculi" ] - edge [ - source 146 - target 8 - weight 2 + node [ + id 228 + label "minecraft_iron_helmet" ] - edge [ - source 147 - target 146 - weight 1 + node [ + id 229 + label "withershot_evolution_pool" ] - edge [ - source 147 - target 426 - weight 1 + node [ + id 230 + label "biomancy_withershot" ] - edge [ - source 148 - target 8 - weight 2 + node [ + id 231 + label "minecraft_nether_star" ] - edge [ - source 149 - target 148 - weight 1 + node [ + id 232 + label "minecraft_wither_skeleton_skull" ] - edge [ - source 149 - target 427 - weight 1 + node [ + id 233 + label "wither_skeleton_skull_evolution_pool" ] - edge [ - source 150 - target 8 - weight 4 + node [ + id 234 + label "minecraft_wither_rose" ] - edge [ - source 151 - target 150 - weight 1 + node [ + id 235 + label "zombie_head_evolution_pool" ] - edge [ - source 151 - target 269 - weight 1 + node [ + id 236 + label "minecraft_player_head" ] edge [ - source 151 - target 428 + source 0 + target 1 weight 1 ] edge [ - source 152 - target 8 - weight 4 + source 1 + target 35 + weight 3 ] edge [ - source 153 - target 152 + source 1 + target 39 weight 1 ] edge [ - source 153 - target 272 - weight 2 - ] - edge [ - source 153 - target 429 + source 1 + target 42 weight 1 ] edge [ - source 154 - target 8 - weight 5 - ] - edge [ - source 155 - target 154 + source 1 + target 45 weight 1 ] edge [ - source 155 - target 271 - weight 1 + source 1 + target 50 + weight 3 ] edge [ - source 155 - target 430 + source 1 + target 53 weight 1 ] edge [ - source 156 - target 8 - weight 2 - ] - edge [ - source 157 - target 156 + source 1 + target 56 weight 1 ] edge [ - source 157 - target 431 + source 1 + target 59 weight 1 ] edge [ - source 158 - target 8 - weight 4 - ] - edge [ - source 159 - target 158 + source 1 + target 75 weight 1 ] edge [ - source 159 - target 432 + source 1 + target 113 weight 1 ] edge [ - source 160 - target 8 + source 1 + target 116 weight 1 ] edge [ - source 161 - target 160 + source 1 + target 223 weight 1 ] edge [ - source 161 - target 433 + source 1 + target 226 weight 1 ] edge [ - source 162 - target 8 - weight 4 - ] - edge [ - source 163 - target 162 + source 2 + target 0 weight 1 ] edge [ - source 163 - target 434 + source 3 + target 0 weight 1 ] edge [ - source 164 - target 8 - weight 4 - ] - edge [ - source 165 - target 164 - weight 1 + source 4 + target 0 + weight 2 ] edge [ - source 165 - target 435 - weight 1 + source 4 + target 71 + weight 5 ] edge [ - source 165 - target 446 - weight 1 + source 4 + target 91 + weight 5 ] edge [ - source 166 - target 167 + source 5 + target 0 weight 1 ] edge [ - source 167 - target 223 - weight 1 + source 5 + target 28 + weight 2 ] edge [ - source 168 - target 166 - weight 1 + source 5 + target 39 + weight 2 ] edge [ - source 169 - target 170 - weight 1 + source 5 + target 42 + weight 2 ] edge [ - source 170 - target 169 - weight 3 + source 5 + target 53 + weight 2 ] edge [ - source 170 - target 174 - weight 3 + source 5 + target 56 + weight 2 ] edge [ - source 170 - target 175 - weight 3 + source 5 + target 59 + weight 2 ] edge [ - source 170 - target 176 - weight 3 + source 5 + target 62 + weight 2 ] edge [ - source 170 - target 177 - weight 3 + source 5 + target 163 + weight 2 ] edge [ - source 170 - target 195 - weight 1 + source 5 + target 212 + weight 2 ] edge [ - source 170 - target 263 + source 6 + target 0 weight 1 ] edge [ - source 170 - target 266 + source 6 + target 35 weight 1 ] edge [ - source 171 - target 169 + source 6 + target 39 weight 1 ] edge [ - source 171 - target 174 + source 6 + target 42 weight 1 ] edge [ - source 171 - target 175 + source 6 + target 50 weight 1 ] edge [ - source 171 - target 176 + source 6 + target 53 weight 1 ] edge [ - source 171 - target 177 + source 6 + target 56 weight 1 ] edge [ - source 171 - target 178 - weight 2 + source 6 + target 59 + weight 1 ] edge [ - source 171 - target 212 + source 6 + target 62 weight 1 ] edge [ - source 171 - target 225 + source 7 + target 8 weight 4 ] edge [ - source 171 - target 350 - weight 2 - ] - edge [ - source 171 - target 436 + source 8 + target 128 weight 1 ] edge [ - source 172 - target 169 + source 9 + target 7 weight 1 ] edge [ - source 172 - target 174 + source 9 + target 126 weight 1 ] edge [ - source 172 - target 175 + source 9 + target 218 weight 1 ] edge [ - source 172 - target 176 - weight 1 + source 10 + target 8 + weight 6 ] edge [ - source 172 - target 177 + source 11 + target 10 weight 1 ] edge [ - source 172 - target 442 + source 11 + target 131 weight 1 ] edge [ - source 172 - target 446 - weight 2 - ] - edge [ - source 172 - target 447 - weight 2 - ] - edge [ - source 173 - target 169 + source 11 + target 220 weight 1 ] edge [ - source 173 - target 174 - weight 1 + source 12 + target 8 + weight 2 ] edge [ - source 173 - target 175 + source 13 + target 12 weight 1 ] edge [ - source 173 - target 176 + source 13 + target 132 weight 1 ] edge [ - source 173 - target 177 + source 13 + target 221 weight 1 ] edge [ - source 174 - target 170 - weight 1 + source 14 + target 8 + weight 8 ] edge [ - source 175 - target 170 + source 15 + target 14 weight 1 ] edge [ - source 176 - target 170 + source 15 + target 134 weight 1 ] edge [ - source 177 - target 170 + source 15 + target 222 weight 1 ] edge [ - source 178 - target 179 + source 16 + target 17 weight 1 ] edge [ - source 180 - target 178 + source 17 + target 73 weight 1 ] edge [ - source 181 - target 178 + source 18 + target 16 weight 1 ] edge [ - source 182 - target 172 + source 19 + target 20 weight 1 ] edge [ - source 182 - target 183 - weight 0.2 + source 20 + target 19 + weight 3 ] edge [ - source 184 - target 182 - weight 1 + source 20 + target 24 + weight 3 ] edge [ - source 184 - target 447 - weight 1 + source 20 + target 25 + weight 3 ] edge [ - source 185 - target 186 - weight 1 + source 20 + target 26 + weight 3 ] edge [ - source 186 - target 212 - weight 1 + source 20 + target 27 + weight 3 ] edge [ - source 187 - target 185 + source 20 + target 45 weight 1 ] edge [ - source 188 - target 185 + source 20 + target 113 weight 1 ] edge [ - source 188 - target 195 + source 20 + target 116 weight 1 ] edge [ - source 188 - target 200 + source 21 + target 19 weight 1 ] edge [ - source 188 - target 206 + source 21 + target 24 weight 1 ] edge [ - source 189 - target 190 + source 21 + target 25 weight 1 ] edge [ - source 190 - target 225 + source 21 + target 26 weight 1 ] edge [ - source 190 - target 350 + source 21 + target 27 weight 1 ] edge [ - source 191 - target 189 + source 21 + target 28 weight 2 ] edge [ - source 192 - target 193 - weight 1 - ] - edge [ - source 194 - target 192 - weight 1 - ] - edge [ - source 195 - target 196 + source 21 + target 62 weight 1 ] edge [ - source 197 - target 195 - weight 1 + source 21 + target 75 + weight 4 ] edge [ - source 197 - target 203 - weight 1 + source 21 + target 212 + weight 2 ] edge [ - source 197 - target 209 + source 21 + target 223 weight 1 ] edge [ - source 197 - target 212 + source 22 + target 19 weight 1 ] edge [ - source 197 - target 263 + source 22 + target 24 weight 1 ] edge [ - source 197 - target 266 + source 22 + target 25 weight 1 ] edge [ - source 197 - target 439 - weight 4 - ] - edge [ - source 198 - target 195 + source 22 + target 26 weight 1 ] edge [ - source 198 - target 263 + source 22 + target 27 weight 1 ] edge [ - source 198 - target 266 + source 22 + target 229 weight 1 ] edge [ - source 199 - target 195 - weight 1 + source 22 + target 233 + weight 2 ] edge [ - source 200 - target 201 - weight 1 + source 22 + target 235 + weight 2 ] edge [ - source 202 - target 200 + source 23 + target 19 weight 1 ] edge [ - source 203 - target 204 + source 23 + target 24 weight 1 ] edge [ - source 205 - target 203 + source 23 + target 25 weight 1 ] edge [ - source 206 - target 207 + source 23 + target 26 weight 1 ] - edge [ - source 208 - target 206 + edge [ + source 23 + target 27 weight 1 ] edge [ - source 209 - target 210 + source 24 + target 20 weight 1 ] edge [ - source 211 - target 209 + source 25 + target 20 weight 1 ] edge [ - source 212 - target 213 + source 26 + target 20 weight 1 ] edge [ - source 214 - target 183 + source 27 + target 20 weight 1 ] edge [ - source 214 - target 215 - weight 0.3 + source 28 + target 29 + weight 1 ] edge [ - source 216 - target 214 + source 30 + target 28 weight 1 ] edge [ - source 217 - target 183 - weight 2 + source 31 + target 28 + weight 1 ] edge [ - source 217 - target 218 - weight 0.4 + source 32 + target 22 + weight 1 ] edge [ - source 217 - target 219 + source 32 + target 33 weight 0.2 ] edge [ - source 220 - target 217 + source 34 + target 32 weight 1 ] edge [ - source 221 - target 222 - weight 5 - ] - edge [ - source 222 - target 221 + source 34 + target 235 weight 1 ] edge [ - source 223 - target 224 + source 35 + target 36 weight 1 ] edge [ - source 224 - target 317 + source 36 + target 62 weight 1 ] edge [ - source 225 - target 226 + source 37 + target 35 weight 1 ] edge [ - source 227 - target 6 + source 38 + target 35 weight 1 ] edge [ - source 228 - target 227 - weight 2 + source 38 + target 45 + weight 1 ] edge [ - source 229 - target 6 - weight 3 + source 38 + target 50 + weight 1 ] edge [ - source 230 - target 229 + source 38 + target 56 weight 1 ] edge [ - source 231 - target 6 - weight 3 + source 39 + target 40 + weight 1 ] edge [ - source 232 - target 231 + source 40 + target 75 weight 1 ] edge [ - source 233 - target 6 + source 40 + target 212 weight 1 ] edge [ - source 234 - target 233 - weight 6 + source 41 + target 39 + weight 2 ] edge [ - source 235 - target 6 + source 42 + target 43 weight 1 ] edge [ - source 236 - target 235 - weight 4 + source 44 + target 42 + weight 1 ] edge [ - source 237 - target 6 + source 45 + target 46 weight 1 ] edge [ - source 238 - target 237 - weight 2 + source 47 + target 45 + weight 1 ] edge [ - source 239 - target 6 + source 47 + target 53 weight 1 ] edge [ - source 239 - target 215 - weight 0.15 + source 47 + target 59 + weight 1 ] edge [ - source 239 - target 172 - weight 0.2 + source 47 + target 62 + weight 1 ] edge [ - source 239 - target 173 - weight 0.2 + source 47 + target 113 + weight 1 ] edge [ - source 240 - target 239 + source 47 + target 116 weight 1 ] edge [ - source 241 - target 242 - weight 5 + source 47 + target 226 + weight 4 ] edge [ - source 242 - target 241 + source 48 + target 45 weight 1 ] edge [ - source 243 - target 5 - weight 3 - ] - edge [ - source 244 - target 243 + source 48 + target 113 weight 1 ] edge [ - source 245 - target 5 + source 48 + target 116 weight 1 ] edge [ - source 246 - target 245 + source 49 + target 45 weight 1 ] edge [ - source 247 - target 5 - weight 2 + source 50 + target 51 + weight 1 ] edge [ - source 248 - target 247 + source 52 + target 50 weight 1 ] edge [ - source 249 - target 5 + source 53 + target 54 weight 1 ] edge [ - source 250 - target 249 - weight 4 + source 55 + target 53 + weight 1 ] edge [ - source 251 - target 5 + source 56 + target 57 weight 1 ] edge [ - source 252 - target 251 - weight 4 + source 58 + target 56 + weight 1 ] edge [ - source 253 - target 5 + source 59 + target 60 weight 1 ] edge [ - source 254 - target 253 + source 61 + target 59 weight 1 ] edge [ - source 255 - target 5 + source 62 + target 63 weight 1 ] edge [ - source 256 - target 255 + source 64 + target 33 weight 1 ] edge [ - source 257 - target 5 - weight 1 + source 64 + target 65 + weight 0.3 ] edge [ - source 258 - target 257 + source 66 + target 64 weight 1 ] edge [ - source 259 - target 5 - weight 3 + source 67 + target 33 + weight 2 ] edge [ - source 260 - target 259 - weight 1 + source 67 + target 68 + weight 0.4 ] edge [ - source 261 - target 5 - weight 1 + source 67 + target 69 + weight 0.2 ] edge [ - source 262 - target 261 + source 70 + target 67 weight 1 ] edge [ - source 263 - target 264 + source 70 + target 133 weight 1 ] edge [ - source 265 - target 263 - weight 1 + source 71 + target 72 + weight 5 ] edge [ - source 265 - target 436 + source 72 + target 71 weight 1 ] edge [ - source 266 - target 267 + source 73 + target 74 weight 1 ] edge [ - source 268 - target 266 - weight 2 + source 74 + target 176 + weight 1 ] edge [ - source 269 - target 215 + source 75 + target 76 weight 1 ] edge [ - source 269 - target 270 - weight 0.4 + source 77 + target 6 + weight 1 ] edge [ - source 271 - target 215 - weight 6 + source 78 + target 77 + weight 2 ] edge [ - source 271 - target 270 - weight 0.6 + source 79 + target 6 + weight 3 ] edge [ - source 272 - target 215 + source 80 + target 79 weight 1 ] edge [ - source 272 - target 270 - weight 0.4 + source 81 + target 6 + weight 3 ] edge [ - source 273 - target 274 + source 82 + target 81 weight 1 ] edge [ - source 273 - target 270 - weight 1.0 - ] - edge [ - source 275 - target 4 + source 83 + target 6 weight 1 ] edge [ - source 275 - target 215 - weight 0.05 - ] - edge [ - source 276 - target 275 + source 84 + target 83 weight 6 ] edge [ - source 277 - target 4 + source 85 + target 6 weight 1 ] edge [ - source 277 - target 215 - weight 0.05 - ] - edge [ - source 278 - target 277 - weight 6 + source 86 + target 85 + weight 4 ] edge [ - source 279 - target 4 + source 87 + target 6 weight 1 ] edge [ - source 280 - target 279 + source 88 + target 87 weight 2 ] edge [ - source 281 - target 4 + source 89 + target 6 weight 1 ] edge [ - source 282 - target 281 - weight 6 + source 89 + target 65 + weight 0.15 + ] + edge [ + source 89 + target 22 + weight 0.2 ] edge [ - source 283 - target 4 - weight 9 + source 89 + target 23 + weight 0.2 ] edge [ - source 284 - target 283 + source 90 + target 89 weight 1 ] edge [ - source 285 - target 4 - weight 1 + source 91 + target 92 + weight 5 ] edge [ - source 286 - target 285 + source 92 + target 91 weight 1 ] edge [ - source 287 - target 4 - weight 9 + source 93 + target 5 + weight 3 ] edge [ - source 288 - target 287 + source 94 + target 93 weight 1 ] edge [ - source 289 - target 4 + source 95 + target 5 weight 1 ] edge [ - source 290 - target 289 + source 96 + target 95 weight 1 ] edge [ - source 291 - target 4 - weight 60 + source 97 + target 5 + weight 2 ] edge [ - source 292 - target 291 + source 98 + target 97 weight 1 ] edge [ - source 293 - target 4 - weight 6 - ] - edge [ - source 294 - target 293 + source 99 + target 5 weight 1 ] edge [ - source 295 - target 4 - weight 0.5 + source 100 + target 99 + weight 4 ] edge [ - source 295 - target 296 - weight 0.8 + source 101 + target 5 + weight 1 ] edge [ - source 296 - target 298 - weight 2 + source 102 + target 101 + weight 4 ] edge [ - source 296 - target 304 - weight 5 + source 103 + target 5 + weight 1 ] edge [ - source 296 - target 321 - weight 4 + source 104 + target 103 + weight 1 ] edge [ - source 296 - target 436 + source 105 + target 5 weight 1 ] edge [ - source 297 - target 295 - weight 2 + source 106 + target 105 + weight 1 ] edge [ - source 297 - target 348 + source 107 + target 5 weight 1 ] edge [ - source 298 - target 299 + source 108 + target 107 weight 1 ] edge [ - source 300 - target 298 - weight 1 + source 109 + target 5 + weight 3 ] edge [ - source 300 - target 303 + source 110 + target 109 weight 1 ] edge [ - source 300 - target 304 + source 111 + target 5 weight 1 ] edge [ - source 301 - target 298 + source 112 + target 111 weight 1 ] edge [ - source 301 - target 303 + source 113 + target 114 weight 1 ] edge [ - source 302 - target 298 + source 115 + target 113 weight 1 ] edge [ - source 302 - target 303 + source 115 + target 223 weight 1 ] edge [ - source 303 - target 262 + source 116 + target 117 weight 1 ] edge [ - source 304 - target 300 - weight 3 + source 118 + target 116 + weight 2 ] edge [ - source 305 - target 297 - weight 4 + source 119 + target 65 + weight 1 ] edge [ - source 306 - target 305 - weight 1 + source 119 + target 120 + weight 0.4 ] edge [ - source 307 - target 173 + source 121 + target 119 weight 1 ] edge [ - source 307 - target 215 - weight 0.15 + source 122 + target 65 + weight 6 ] edge [ - source 308 - target 307 - weight 1 + source 122 + target 120 + weight 0.6 ] edge [ - source 309 - target 173 + source 123 + target 122 weight 1 ] edge [ - source 310 - target 309 + source 124 + target 65 weight 1 ] edge [ - source 311 - target 173 - weight 3 - ] - edge [ - source 312 - target 311 - weight 1 + source 124 + target 120 + weight 0.4 ] edge [ - source 312 - target 313 - weight 1 + source 125 + target 124 + weight 2 ] edge [ - source 312 - target 314 - weight 1 + source 126 + target 127 + weight 2 ] edge [ - source 312 - target 315 - weight 1 + source 126 + target 120 + weight 0.3 ] edge [ - source 312 - target 316 + source 128 + target 127 weight 1 ] edge [ - source 313 - target 173 - weight 5 + source 128 + target 120 + weight 1.0 ] edge [ - source 314 - target 173 + source 129 + target 127 weight 3 ] edge [ - source 315 - target 173 - weight 5 - ] - edge [ - source 316 - target 173 - weight 5 + source 129 + target 120 + weight 0.5 ] edge [ - source 317 - target 318 + source 130 + target 129 weight 1 ] edge [ - source 318 - target 349 + source 130 + target 169 weight 1 ] edge [ - source 319 - target 318 - weight 4 + source 131 + target 127 + weight 3 ] edge [ - source 320 - target 319 - weight 1 + source 131 + target 120 + weight 0.5 ] edge [ - source 321 - target 322 + source 132 + target 127 weight 1 ] edge [ - source 322 - target 339 - weight 1 + source 132 + target 120 + weight 0.15 ] edge [ - source 323 - target 321 + source 133 + target 127 weight 2 ] edge [ - source 324 - target 296 - weight 1 + source 133 + target 120 + weight 0.3 ] edge [ - source 325 - target 324 - weight 2 + source 134 + target 127 + weight 4 ] edge [ - source 326 - target 296 - weight 3 + source 134 + target 120 + weight 0.6 ] edge [ - source 327 - target 326 + source 135 + target 4 weight 1 ] edge [ - source 328 - target 296 - weight 1 + source 135 + target 65 + weight 0.05 ] edge [ - source 328 - target 270 - weight 0.3 + source 136 + target 135 + weight 6 ] edge [ - source 329 - target 296 + source 137 + target 4 weight 1 ] edge [ - source 329 - target 270 - weight 0.3 - ] - edge [ - source 330 - target 296 - weight 0.5 + source 137 + target 65 + weight 0.05 ] edge [ - source 330 - target 270 - weight 0.4 + source 138 + target 137 + weight 6 ] edge [ - source 331 - target 296 + source 139 + target 4 weight 1 ] edge [ - source 332 - target 331 + source 140 + target 139 weight 2 ] edge [ - source 333 - target 296 - weight 0.5 + source 141 + target 4 + weight 1 ] edge [ - source 334 - target 333 - weight 2 + source 142 + target 141 + weight 6 ] edge [ - source 335 - target 296 - weight 1 + source 143 + target 4 + weight 9 ] edge [ - source 336 - target 335 - weight 6 + source 144 + target 143 + weight 1 ] edge [ - source 337 - target 296 - weight 3 + source 145 + target 4 + weight 1 ] edge [ - source 337 - target 215 - weight 1.0 + source 146 + target 145 + weight 1 ] edge [ - source 338 - target 337 - weight 1 + source 147 + target 4 + weight 9 ] edge [ - source 339 - target 296 - weight 4 + source 148 + target 147 + weight 1 ] edge [ - source 340 - target 296 + source 149 + target 4 weight 1 ] edge [ - source 341 - target 340 - weight 6 + source 150 + target 149 + weight 1 ] edge [ - source 342 - target 296 - weight 3 + source 151 + target 4 + weight 60 ] edge [ - source 343 - target 342 + source 152 + target 151 weight 1 ] edge [ - source 344 - target 296 - weight 1 + source 153 + target 4 + weight 6 ] edge [ - source 345 - target 344 + source 154 + target 153 weight 1 ] edge [ - source 346 - target 296 + source 155 + target 4 weight 0.5 ] edge [ - source 347 - target 346 - weight 1 + source 155 + target 156 + weight 0.8 ] edge [ - source 348 - target 296 - weight 1 + source 156 + target 158 + weight 2 ] edge [ - source 349 - target 296 - weight 2 + source 156 + target 164 + weight 5 ] edge [ - source 350 - target 351 - weight 1 + source 156 + target 180 + weight 4 ] edge [ - source 352 - target 350 + source 156 + target 223 weight 1 ] edge [ - source 353 - target 354 - weight 1 + source 157 + target 155 + weight 2 ] edge [ - source 353 - target 172 - weight 1.0 + source 157 + target 210 + weight 1 ] edge [ - source 353 - target 183 - weight 0.2 + source 158 + target 159 + weight 1 ] edge [ - source 354 - target 436 + source 160 + target 158 weight 1 ] edge [ - source 354 - target 446 + source 160 + target 163 weight 1 ] edge [ - source 355 - target 353 + source 160 + target 164 weight 1 ] edge [ - source 356 - target 357 + source 161 + target 158 weight 1 ] edge [ - source 358 - target 357 + source 161 + target 163 weight 1 ] edge [ - source 359 - target 357 - weight 4 + source 162 + target 158 + weight 1 ] edge [ - source 360 - target 357 - weight 4 + source 162 + target 163 + weight 1 ] edge [ - source 361 - target 357 - weight 4 + source 163 + target 112 + weight 1 ] edge [ - source 362 - target 357 - weight 5 + source 164 + target 160 + weight 3 ] edge [ - source 363 - target 357 + source 165 + target 157 weight 4 ] edge [ - source 364 - target 357 + source 166 + target 165 weight 1 ] edge [ - source 365 - target 357 + source 167 + target 23 weight 1 ] edge [ - source 366 - target 357 + source 167 + target 65 + weight 0.15 + ] + edge [ + source 168 + target 167 weight 1 ] edge [ - source 367 - target 357 - weight 4 + source 169 + target 23 + weight 1 ] edge [ - source 368 - target 357 - weight 5 + source 170 + target 23 + weight 3 ] edge [ - source 369 - target 357 - weight 5 + source 171 + target 170 + weight 1 ] edge [ - source 370 - target 357 - weight 4 + source 171 + target 172 + weight 1 ] edge [ - source 371 - target 357 - weight 2 + source 171 + target 173 + weight 1 ] edge [ - source 372 - target 357 - weight 6 + source 171 + target 174 + weight 1 ] edge [ - source 373 - target 357 - weight 4 + source 171 + target 175 + weight 1 ] edge [ - source 374 - target 357 - weight 4 + source 172 + target 23 + weight 5 ] edge [ - source 375 - target 357 - weight 4 + source 173 + target 23 + weight 3 ] edge [ - source 376 - target 357 + source 174 + target 23 weight 5 ] edge [ - source 377 - target 357 - weight 4 + source 175 + target 23 + weight 5 ] edge [ - source 378 - target 357 - weight 4 + source 176 + target 177 + weight 1 ] edge [ - source 379 - target 357 - weight 4 + source 177 + target 211 + weight 1 ] edge [ - source 380 - target 357 + source 178 + target 177 weight 4 ] edge [ - source 381 - target 357 + source 179 + target 178 weight 1 ] edge [ - source 382 - target 357 + source 180 + target 181 weight 1 ] edge [ - source 383 - target 357 - weight 2 - ] - edge [ - source 384 - target 357 + source 181 + target 201 weight 1 ] edge [ - source 385 - target 357 - weight 4 + source 182 + target 180 + weight 2 ] edge [ - source 386 - target 357 + source 183 + target 156 weight 1 ] edge [ - source 387 - target 357 - weight 5 + source 184 + target 183 + weight 2 ] edge [ - source 388 - target 357 - weight 1 + source 185 + target 156 + weight 3 ] edge [ - source 389 - target 357 + source 186 + target 185 weight 1 ] edge [ - source 390 - target 357 + source 187 + target 156 weight 1 ] edge [ - source 391 - target 357 - weight 4 - ] - edge [ - source 392 - target 357 - weight 4 - ] - edge [ - source 393 - target 357 - weight 4 - ] - edge [ - source 394 - target 357 - weight 4 + source 187 + target 120 + weight 0.3 ] edge [ - source 395 - target 357 - weight 4 + source 188 + target 187 + weight 6 ] edge [ - source 396 - target 357 + source 189 + target 156 weight 1 ] edge [ - source 397 - target 357 - weight 2 - ] - edge [ - source 398 - target 357 - weight 4 + source 189 + target 120 + weight 0.3 ] edge [ - source 399 - target 357 - weight 2 + source 190 + target 189 + weight 6 ] edge [ - source 400 - target 357 - weight 5 + source 191 + target 156 + weight 0.5 ] edge [ - source 401 - target 357 - weight 4 + source 191 + target 120 + weight 0.4 ] edge [ - source 402 - target 357 + source 192 + target 191 weight 1 ] edge [ - source 403 - target 357 + source 193 + target 156 weight 1 ] edge [ - source 404 - target 357 - weight 4 + source 194 + target 193 + weight 2 ] edge [ - source 405 - target 357 - weight 4 + source 195 + target 156 + weight 0.5 ] edge [ - source 406 - target 357 - weight 4 + source 196 + target 195 + weight 2 ] edge [ - source 407 - target 357 - weight 4 + source 197 + target 156 + weight 1 ] edge [ - source 408 - target 357 - weight 4 + source 198 + target 197 + weight 6 ] edge [ - source 409 - target 357 - weight 4 + source 199 + target 156 + weight 3 ] edge [ - source 410 - target 357 - weight 4 + source 199 + target 65 + weight 1.0 ] edge [ - source 411 - target 357 - weight 6 + source 200 + target 199 + weight 1 ] edge [ - source 412 - target 357 - weight 1 + source 201 + target 156 + weight 4 ] edge [ - source 413 - target 357 - weight 5 + source 202 + target 156 + weight 1 ] edge [ - source 414 - target 357 - weight 4 + source 203 + target 202 + weight 6 ] edge [ - source 415 - target 357 - weight 4 + source 204 + target 156 + weight 3 ] edge [ - source 416 - target 357 - weight 4 + source 205 + target 204 + weight 1 ] edge [ - source 417 - target 357 + source 206 + target 156 weight 1 ] edge [ - source 418 - target 357 - weight 4 + source 207 + target 206 + weight 1 ] edge [ - source 419 - target 357 - weight 4 + source 208 + target 156 + weight 0.5 ] edge [ - source 420 - target 357 + source 209 + target 208 weight 1 ] edge [ - source 421 - target 357 + source 210 + target 156 weight 1 ] edge [ - source 422 - target 357 + source 211 + target 156 weight 2 ] edge [ - source 423 - target 357 - weight 4 + source 212 + target 213 + weight 1 ] edge [ - source 424 - target 357 + source 214 + target 212 weight 1 ] edge [ - source 425 - target 357 - weight 2 + source 215 + target 216 + weight 1 ] edge [ - source 426 - target 357 - weight 2 + source 215 + target 22 + weight 1.0 ] edge [ - source 427 - target 357 - weight 2 + source 215 + target 33 + weight 0.2 ] edge [ - source 428 - target 357 - weight 4 + source 216 + target 223 + weight 1 ] edge [ - source 429 - target 357 - weight 4 + source 216 + target 233 + weight 1 ] edge [ - source 430 - target 357 - weight 5 + source 217 + target 215 + weight 1 ] edge [ - source 431 - target 357 + source 218 + target 219 weight 2 ] edge [ - source 432 - target 357 + source 220 + target 219 weight 4 ] edge [ - source 433 - target 357 + source 221 + target 219 weight 1 ] edge [ - source 434 - target 357 - weight 4 + source 222 + target 219 + weight 6 ] edge [ - source 435 - target 357 - weight 4 + source 223 + target 224 + weight 1 ] edge [ - source 436 - target 437 + source 224 + target 229 weight 1 ] edge [ - source 437 - target 442 + source 225 + target 223 weight 1 ] edge [ - source 438 - target 436 + source 226 + target 227 weight 1 ] edge [ - source 439 - target 440 + source 228 + target 226 weight 1 ] edge [ - source 441 - target 439 + source 229 + target 230 weight 1 ] edge [ - source 442 - target 443 + source 231 + target 229 weight 1 ] edge [ - source 444 - target 442 + source 232 + target 229 weight 1 ] edge [ - source 445 - target 442 + source 233 + target 232 weight 1 ] edge [ - source 446 - target 445 + source 234 + target 233 weight 1 ] edge [ - source 447 - target 355 + source 235 + target 217 weight 1 ] edge [ - source 448 - target 447 + source 236 + target 235 weight 1 ] ] diff --git a/scripts/biomancy_production_digraph_twopi.pdf b/scripts/biomancy_production_digraph_twopi.pdf index 403aba84b..82c28ecaa 100644 Binary files a/scripts/biomancy_production_digraph_twopi.pdf and b/scripts/biomancy_production_digraph_twopi.pdf differ diff --git a/src/generated/resources/data/biomancy/advancements/recipes/biomancy/vile_melon_from_campfire.json b/src/generated/resources/data/biomancy/advancements/recipes/biomancy/vile_melon_from_campfire.json deleted file mode 100644 index ef41d9488..000000000 --- a/src/generated/resources/data/biomancy/advancements/recipes/biomancy/vile_melon_from_campfire.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "biomancy:vile_melon_from_campfire" - ] - }, - "criteria": { - "has_vile_melon_slice": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { - "item": "biomancy:vile_melon_slice" - } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "biomancy:vile_melon_from_campfire" - } - } - }, - "requirements": [ - [ - "has_vile_melon_slice", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/generated/resources/data/biomancy/advancements/recipes/biomancy/vile_melon_from_smelting.json b/src/generated/resources/data/biomancy/advancements/recipes/biomancy/vile_melon_from_smelting.json deleted file mode 100644 index 956869eb1..000000000 --- a/src/generated/resources/data/biomancy/advancements/recipes/biomancy/vile_melon_from_smelting.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "biomancy:vile_melon_from_smelting" - ] - }, - "criteria": { - "has_vile_melon_slice": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { - "item": "biomancy:vile_melon_slice" - } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "biomancy:vile_melon_from_smelting" - } - } - }, - "requirements": [ - [ - "has_vile_melon_slice", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/generated/resources/data/biomancy/advancements/recipes/biomancy/vile_melon_seeds.json b/src/generated/resources/data/biomancy/advancements/recipes/biomancy/vile_melon_seeds.json deleted file mode 100644 index d7751c112..000000000 --- a/src/generated/resources/data/biomancy/advancements/recipes/biomancy/vile_melon_seeds.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "biomancy:vile_melon_seeds" - ] - }, - "criteria": { - "has_vile_melon_slice": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { - "item": "biomancy:vile_melon_slice" - } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "biomancy:vile_melon_seeds" - } - } - }, - "requirements": [ - [ - "has_vile_melon_slice", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/generated/resources/data/biomancy/loot_tables/blocks/mutated_flesh_block.json b/src/generated/resources/data/biomancy/loot_tables/blocks/mutated_flesh_block.json deleted file mode 100644 index b14fbad75..000000000 --- a/src/generated/resources/data/biomancy/loot_tables/blocks/mutated_flesh_block.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "rolls": 1, - "entries": [ - { - "type": "minecraft:item", - "functions": [ - { - "function": "minecraft:copy_state", - "block": "biomancy:mutated_flesh_block", - "properties": [ - "type" - ] - } - ], - "name": "biomancy:mutated_flesh_block" - } - ], - "conditions": [ - { - "condition": "minecraft:survives_explosion" - } - ] - } - ] -} \ No newline at end of file diff --git a/src/generated/resources/data/biomancy/loot_tables/blocks/vile_melon_block.json b/src/generated/resources/data/biomancy/loot_tables/blocks/vile_melon_block.json deleted file mode 100644 index f945360e1..000000000 --- a/src/generated/resources/data/biomancy/loot_tables/blocks/vile_melon_block.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "rolls": 1, - "entries": [ - { - "type": "minecraft:item", - "name": "biomancy:vile_melon_block" - } - ], - "conditions": [ - { - "condition": "minecraft:survives_explosion" - } - ] - } - ] -} \ No newline at end of file diff --git a/src/generated/resources/data/biomancy/loot_tables/blocks/vile_melon_crop.json b/src/generated/resources/data/biomancy/loot_tables/blocks/vile_melon_crop.json deleted file mode 100644 index ad3e820d4..000000000 --- a/src/generated/resources/data/biomancy/loot_tables/blocks/vile_melon_crop.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "rolls": 1.0, - "entries": [ - { - "type": "minecraft:alternatives", - "children": [ - { - "type": "minecraft:item", - "conditions": [ - { - "condition": "minecraft:block_state_property", - "block": "biomancy:vile_melon_crop", - "properties": { - "age": "7" - } - } - ], - "name": "biomancy:vile_melon_block" - }, - { - "type": "minecraft:item", - "name": "biomancy:vile_melon_seeds" - } - ] - } - ] - } - ], - "functions": [ - { - "function": "minecraft:explosion_decay" - } - ] -} \ No newline at end of file diff --git a/src/generated/resources/data/biomancy/recipes/vile_melon_from_campfire.json b/src/generated/resources/data/biomancy/recipes/vile_melon_from_campfire.json deleted file mode 100644 index c83d4574e..000000000 --- a/src/generated/resources/data/biomancy/recipes/vile_melon_from_campfire.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "type": "minecraft:campfire_cooking", - "ingredient": { - "item": "biomancy:vile_melon_slice" - }, - "result": "biomancy:cooked_vile_melon_slice", - "experience": 0.35, - "cookingtime": 600 -} \ No newline at end of file diff --git a/src/generated/resources/data/biomancy/recipes/vile_melon_from_smelting.json b/src/generated/resources/data/biomancy/recipes/vile_melon_from_smelting.json deleted file mode 100644 index 42fbee594..000000000 --- a/src/generated/resources/data/biomancy/recipes/vile_melon_from_smelting.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "type": "minecraft:smelting", - "ingredient": { - "item": "biomancy:vile_melon_slice" - }, - "result": "biomancy:cooked_vile_melon_slice", - "experience": 0.35, - "cookingtime": 100 -} \ No newline at end of file diff --git a/src/generated/resources/data/biomancy/recipes/vile_melon_seeds.json b/src/generated/resources/data/biomancy/recipes/vile_melon_seeds.json deleted file mode 100644 index 9598fbe46..000000000 --- a/src/generated/resources/data/biomancy/recipes/vile_melon_seeds.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "type": "minecraft:crafting_shapeless", - "ingredients": [ - { - "item": "biomancy:vile_melon_slice" - } - ], - "result": { - "item": "biomancy:vile_melon_seeds" - } -} \ No newline at end of file diff --git a/src/main/java/com/github/elenterius/biomancy/block/BlightPustuleBlock.java b/src/main/java/com/github/elenterius/biomancy/block/BlightPustuleBlock.java deleted file mode 100644 index 5061bd8a2..000000000 --- a/src/main/java/com/github/elenterius/biomancy/block/BlightPustuleBlock.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.github.elenterius.biomancy.block; - -import net.minecraft.block.Block; -import net.minecraft.block.BlockState; -import net.minecraft.item.BlockItemUseContext; -import net.minecraft.state.DirectionProperty; -import net.minecraft.state.StateContainer; -import net.minecraft.state.properties.BlockStateProperties; -import net.minecraft.util.Direction; -import net.minecraft.util.Mirror; -import net.minecraft.util.Rotation; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.shapes.ISelectionContext; -import net.minecraft.util.math.shapes.VoxelShape; -import net.minecraft.util.math.vector.Vector3d; -import net.minecraft.world.IBlockReader; -import net.minecraft.world.IWorldReader; - -import javax.annotation.Nullable; - -public class BlightPustuleBlock extends FleshPlantBlock { - public static final DirectionProperty FACING = BlockStateProperties.FACING; - - protected static final VoxelShape SHAPE_UP = Block.makeCuboidShape(2.0D, 0.0D, 2.0D, 14.0D, 4.0D, 14.0D); - protected static final VoxelShape SHAPE_DOWN = Block.makeCuboidShape(2.0D, 12.0D, 2.0D, 14.0D, 16.0D, 14.0D); - protected static final VoxelShape SHAPE_EAST = Block.makeCuboidShape(0.0D, 2.0D, 2.0D, 4.0D, 14.0D, 14.0D); - protected static final VoxelShape SHAPE_WEST = Block.makeCuboidShape(12.0D, 2.0D, 2.0D, 16.0D, 14.0D, 14.0D); - protected static final VoxelShape SHAPE_SOUTH = Block.makeCuboidShape(2.0D, 2.0D, 0.0D, 14.0D, 14.0D, 4.0D); - protected static final VoxelShape SHAPE_NORTH = Block.makeCuboidShape(2.0D, 2.0D, 12.0D, 14.0D, 14.0D, 16.0D); - - public BlightPustuleBlock(Properties properties) { - super(properties); - setDefaultState(getDefaultState().with(FACING, Direction.UP)); - } - - @Override - protected void fillStateContainer(StateContainer.Builder builder) { - builder.add(FACING); - } - - @Override - public boolean isValidPosition(BlockState state, IWorldReader worldIn, BlockPos pos) { - Direction direction = state.get(FACING); - BlockPos blockpos = pos.offset(direction.getOpposite()); - BlockState blockstate = worldIn.getBlockState(blockpos); - return blockstate.isSolidSide(worldIn, blockpos, direction); - } - - @Nullable - @Override - public BlockState getStateForPlacement(BlockItemUseContext context) { - return getDefaultState().with(FACING, context.getFace()); - } - - @Override - public BlockState rotate(BlockState state, Rotation rot) { - return state.with(FACING, rot.rotate(state.get(FACING))); - } - - @Override - public BlockState mirror(BlockState state, Mirror mirrorIn) { - return state.rotate(mirrorIn.toRotation(state.get(FACING))); - } - - @Override - public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) { - Vector3d vec = state.getOffset(worldIn, pos); - switch (state.get(FACING)) { - case UP: - default: - return SHAPE_UP.withOffset(vec.x, vec.y, vec.z); - case DOWN: - return SHAPE_DOWN.withOffset(vec.x, vec.y, vec.z); - case NORTH: - return SHAPE_NORTH.withOffset(vec.x, vec.y, vec.z); - case SOUTH: - return SHAPE_SOUTH.withOffset(vec.x, vec.y, vec.z); - case WEST: - return SHAPE_WEST.withOffset(vec.x, vec.y, vec.z); - case EAST: - return SHAPE_EAST.withOffset(vec.x, vec.y, vec.z); - } - } - - @Override - public OffsetType getOffsetType() { - return OffsetType.NONE; - } -} diff --git a/src/main/java/com/github/elenterius/biomancy/block/ChewerBlock.java b/src/main/java/com/github/elenterius/biomancy/block/ChewerBlock.java index 0c01498df..db6f049cb 100644 --- a/src/main/java/com/github/elenterius/biomancy/block/ChewerBlock.java +++ b/src/main/java/com/github/elenterius/biomancy/block/ChewerBlock.java @@ -1,50 +1,33 @@ package com.github.elenterius.biomancy.block; -import com.github.elenterius.biomancy.init.ModBlocks; import com.github.elenterius.biomancy.tileentity.ChewerTileEntity; import com.github.elenterius.biomancy.tileentity.state.ChewerStateData; import com.github.elenterius.biomancy.util.ClientTextUtil; import com.github.elenterius.biomancy.util.TextUtil; import com.github.elenterius.biomancy.util.VoxelShapeUtil; -import net.minecraft.block.Block; import net.minecraft.block.BlockRenderType; import net.minecraft.block.BlockState; import net.minecraft.client.util.ITooltipFlag; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.entity.player.ServerPlayerEntity; -import net.minecraft.inventory.container.INamedContainerProvider; -import net.minecraft.item.BlockItemUseContext; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundNBT; -import net.minecraft.state.BooleanProperty; -import net.minecraft.state.DirectionProperty; -import net.minecraft.state.StateContainer; -import net.minecraft.state.properties.BlockStateProperties; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.*; +import net.minecraft.util.Direction; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.BlockRayTraceResult; -import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.shapes.IBooleanFunction; import net.minecraft.util.math.shapes.ISelectionContext; import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.util.math.shapes.VoxelShapes; import net.minecraft.util.text.ITextComponent; import net.minecraft.world.IBlockReader; -import net.minecraft.world.World; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; -import net.minecraftforge.fml.network.NetworkHooks; import javax.annotation.Nullable; +import java.text.DecimalFormat; import java.util.List; import java.util.stream.Stream; -public class ChewerBlock extends OwnableContainerBlock { - - public static final BooleanProperty CRAFTING = ModBlocks.CRAFTING_PROPERTY; - public static final DirectionProperty FACING = BlockStateProperties.HORIZONTAL_FACING; +public class ChewerBlock extends MachineBlock { public static final VoxelShape NORTH_SHAPE = createVoxelShape(Direction.NORTH); public static final VoxelShape SOUTH_SHAPE = createVoxelShape(Direction.SOUTH); @@ -53,7 +36,6 @@ public class ChewerBlock extends OwnableContainerBlock { public ChewerBlock(Properties builder) { super(builder); - setDefaultState(stateContainer.getBaseState().with(CRAFTING, false).with(FACING, Direction.NORTH)); } private static VoxelShape createVoxelShape(Direction direction) { @@ -63,6 +45,12 @@ private static VoxelShape createVoxelShape(Direction direction) { return Stream.of(VoxelShapeUtil.createWithFacing(direction, aabb0), VoxelShapeUtil.createWithFacing(direction, aabb1), VoxelShapeUtil.createWithFacing(direction, aabb2)).reduce((v1, v2) -> VoxelShapes.combineAndSimplify(v1, v2, IBooleanFunction.OR)).get(); } + @Nullable + @Override + public ChewerTileEntity createNewTileEntity(IBlockReader worldIn) { + return new ChewerTileEntity(); + } + @OnlyIn(Dist.CLIENT) @Override public void addInformation(ItemStack stack, @Nullable IBlockReader worldIn, List tooltip, ITooltipFlag flagIn) { @@ -70,64 +58,13 @@ public void addInformation(ItemStack stack, @Nullable IBlockReader worldIn, List CompoundNBT nbt = stack.getChildTag("BlockEntityTag"); if (nbt != null) { tooltip.add(ClientTextUtil.EMPTY_LINE_HACK()); - int mainFuel = (int) (MathHelper.clamp(nbt.getShort(ChewerStateData.NBT_KEY_FUEL) / (float) ChewerTileEntity.MAX_FUEL, 0f, 1f) * 100); - tooltip.add(TextUtil.getTranslationText("tooltip", "biofuel").appendString(": " + mainFuel + "%")); + int fuel = nbt.getShort(ChewerStateData.NBT_KEY_FUEL); + DecimalFormat df = ClientTextUtil.getDecimalFormatter("#,###,###"); + tooltip.add(TextUtil.getTranslationText("tooltip", "biofuel").appendString(String.format(": %s/%s", df.format(fuel), df.format(ChewerTileEntity.MAX_FUEL)))); } super.addInformation(stack, worldIn, tooltip, flagIn); } - @Override - protected void fillStateContainer(StateContainer.Builder builder) { - builder.add(CRAFTING, FACING); - } - - @Override - public BlockState getStateForPlacement(BlockItemUseContext context) { - return getDefaultState().with(FACING, context.getPlacementHorizontalFacing().getOpposite()); - } - - @Override - public void onReplaced(BlockState state, World world, BlockPos blockPos, BlockState newState, boolean isMoving) { - if (state.getBlock() != newState.getBlock()) { - TileEntity tileEntity = world.getTileEntity(blockPos); - if (tileEntity instanceof ChewerTileEntity) { - ((ChewerTileEntity) tileEntity).dropAllInvContents(world, blockPos); - } - super.onReplaced(state, world, blockPos, newState, isMoving); - } - } - - @Override - public ActionResultType onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult hit) { - if (worldIn.isRemote()) return ActionResultType.SUCCESS; - - //TODO: verify that authorization works - INamedContainerProvider containerProvider = getContainer(state, worldIn, pos); - if (containerProvider != null && player instanceof ServerPlayerEntity) { - ServerPlayerEntity serverPlayerEntity = (ServerPlayerEntity) player; - NetworkHooks.openGui(serverPlayerEntity, containerProvider, (packetBuffer) -> {}); - return ActionResultType.SUCCESS; - } - - return ActionResultType.FAIL; - } - - @Nullable - @Override - public TileEntity createNewTileEntity(IBlockReader worldIn) { - return new ChewerTileEntity(); - } - - @Override - public BlockState rotate(BlockState state, Rotation rot) { - return state.with(FACING, rot.rotate(state.get(FACING))); - } - - @Override - public BlockState mirror(BlockState state, Mirror mirrorIn) { - return state.rotate(mirrorIn.toRotation(state.get(FACING))); - } - @Override public BlockRenderType getRenderType(BlockState state) { return BlockRenderType.MODEL; diff --git a/src/main/java/com/github/elenterius/biomancy/block/DecomposerBlock.java b/src/main/java/com/github/elenterius/biomancy/block/DecomposerBlock.java index f2b7323f6..eba14e865 100644 --- a/src/main/java/com/github/elenterius/biomancy/block/DecomposerBlock.java +++ b/src/main/java/com/github/elenterius/biomancy/block/DecomposerBlock.java @@ -1,30 +1,19 @@ package com.github.elenterius.biomancy.block; -import com.github.elenterius.biomancy.init.ModBlocks; import com.github.elenterius.biomancy.tileentity.DecomposerTileEntity; +import com.github.elenterius.biomancy.tileentity.state.DecomposerStateData; import com.github.elenterius.biomancy.util.ClientTextUtil; import com.github.elenterius.biomancy.util.TextUtil; -import com.github.elenterius.biomancy.util.VoxelShapeUtil; import net.minecraft.block.Block; import net.minecraft.block.BlockRenderType; import net.minecraft.block.BlockState; import net.minecraft.client.util.ITooltipFlag; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.entity.player.ServerPlayerEntity; -import net.minecraft.inventory.container.INamedContainerProvider; -import net.minecraft.item.BlockItemUseContext; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundNBT; -import net.minecraft.state.BooleanProperty; -import net.minecraft.state.DirectionProperty; -import net.minecraft.state.StateContainer; -import net.minecraft.state.properties.BlockStateProperties; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.*; -import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.particles.ParticleTypes; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.SoundEvents; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.BlockRayTraceResult; -import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.shapes.IBooleanFunction; import net.minecraft.util.math.shapes.ISelectionContext; import net.minecraft.util.math.shapes.VoxelShape; @@ -34,32 +23,34 @@ import net.minecraft.world.World; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; -import net.minecraftforge.fml.network.NetworkHooks; import javax.annotation.Nullable; +import java.text.DecimalFormat; import java.util.List; +import java.util.Random; import java.util.stream.Stream; -public class DecomposerBlock extends OwnableContainerBlock { +public class DecomposerBlock extends MachineBlock { - public static final BooleanProperty DECOMPOSING = ModBlocks.CRAFTING_PROPERTY; - public static final DirectionProperty FACING = BlockStateProperties.HORIZONTAL_FACING; - - public static final VoxelShape NORTH_SHAPE = createVoxelShape(Direction.NORTH); - public static final VoxelShape SOUTH_SHAPE = createVoxelShape(Direction.SOUTH); - public static final VoxelShape EAST_SHAPE = createVoxelShape(Direction.EAST); - public static final VoxelShape WEST_SHAPE = createVoxelShape(Direction.WEST); + public static final VoxelShape SHAPE = createVoxelShape(); public DecomposerBlock(Properties builder) { super(builder); - setDefaultState(stateContainer.getBaseState().with(DECOMPOSING, false).with(FACING, Direction.NORTH)); } - private static VoxelShape createVoxelShape(Direction direction) { - AxisAlignedBB aabb0 = VoxelShapeUtil.createUnitAABB(0, 0, 3, 16, 14, 16); - AxisAlignedBB aabb1 = VoxelShapeUtil.createUnitAABB(4, 14, 4, 12, 16, 12); - AxisAlignedBB aabb2 = VoxelShapeUtil.createUnitAABB(3, 1, 0, 13, 10, 3); - return Stream.of(VoxelShapeUtil.createWithFacing(direction, aabb0), VoxelShapeUtil.createWithFacing(direction, aabb1), VoxelShapeUtil.createWithFacing(direction, aabb2)).reduce((v1, v2) -> VoxelShapes.combineAndSimplify(v1, v2, IBooleanFunction.OR)).get(); + private static VoxelShape createVoxelShape() { + return Stream.of( + Block.makeCuboidShape(1, 0, 1, 15, 1, 15), + Block.makeCuboidShape(0, 1, 0, 16, 10, 16), + Block.makeCuboidShape(1, 10, 1, 15, 12, 15), + Block.makeCuboidShape(2, 12, 2, 14, 16, 14) + ).reduce((v1, v2) -> VoxelShapes.combineAndSimplify(v1, v2, IBooleanFunction.OR)).get(); + } + + @Nullable + @Override + public DecomposerTileEntity createNewTileEntity(IBlockReader worldIn) { + return new DecomposerTileEntity(); } @OnlyIn(Dist.CLIENT) @@ -69,84 +60,41 @@ public void addInformation(ItemStack stack, @Nullable IBlockReader worldIn, List CompoundNBT nbt = stack.getChildTag("BlockEntityTag"); if (nbt != null) { tooltip.add(ClientTextUtil.EMPTY_LINE_HACK()); - int mainFuel = (int) (MathHelper.clamp(nbt.getShort("MainFuel") / (float) DecomposerTileEntity.MAX_FUEL, 0f, 1f) * 100); - int speedFuel = (int) (MathHelper.clamp(nbt.getShort("SpeedFuel") / (float) DecomposerTileEntity.MAX_FUEL, 0f, 1f) * 100); - tooltip.add(TextUtil.getTranslationText("tooltip", "biofuel").appendString(": " + mainFuel + "%")); - tooltip.add(TextUtil.getTranslationText("tooltip", "speed_fuel").appendString(": " + speedFuel + "%")); + int fuel = nbt.getShort(DecomposerStateData.NBT_KEY_MAIN_FUEL); + DecimalFormat df = ClientTextUtil.getDecimalFormatter("#,###,###"); + tooltip.add(TextUtil.getTranslationText("tooltip", "biofuel").appendString(String.format(": %s/%s", df.format(fuel), df.format(DecomposerTileEntity.MAX_FUEL)))); } super.addInformation(stack, worldIn, tooltip, flagIn); } @Override - protected void fillStateContainer(StateContainer.Builder builder) { - builder.add(DECOMPOSING, FACING); + public BlockRenderType getRenderType(BlockState state) { + return BlockRenderType.MODEL; } @Override - public BlockState getStateForPlacement(BlockItemUseContext context) { - return getDefaultState().with(FACING, context.getPlacementHorizontalFacing().getOpposite()); + public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) { + return SHAPE; } @Override - public void onReplaced(BlockState state, World world, BlockPos blockPos, BlockState newState, boolean isMoving) { - if (state.getBlock() != newState.getBlock()) { - TileEntity tileEntity = world.getTileEntity(blockPos); - if (tileEntity instanceof DecomposerTileEntity) { - ((DecomposerTileEntity) tileEntity).dropAllInvContents(world, blockPos); + @OnlyIn(Dist.CLIENT) + public void animateTick(BlockState stateIn, World worldIn, BlockPos pos, Random rand) { + if (rand.nextInt(4) == 0) { + boolean isCrafting = stateIn.get(CRAFTING); + if (isCrafting) { + int n = rand.nextInt(5); + int color = 0xc7b15d; + double r = (double) (color >> 16 & 255) / 255d; + double g = (double) (color >> 8 & 255) / 255d; + double b = (double) (color & 255) / 255d; + for (int i = 0; i < n; i++) { + worldIn.addParticle(ParticleTypes.ENTITY_EFFECT, pos.getX() + 0.2d + rand.nextFloat() - 0.2d, pos.getY() + 0.3d, pos.getZ() + 0.2d + rand.nextFloat() - 0.2d, r, g, b); + } + if (n > 0 && rand.nextInt(3) == 0) { + worldIn.playSound(pos.getX(), pos.getY(), pos.getZ(), SoundEvents.ENTITY_TROPICAL_FISH_FLOP, SoundCategory.BLOCKS, 0.2f + rand.nextFloat() * 0.2f, 0.9f + rand.nextFloat() * 0.15f, false); + } } - super.onReplaced(state, world, blockPos, newState, isMoving); - } - } - - @Override - public ActionResultType onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult hit) { - if (worldIn.isRemote()) return ActionResultType.SUCCESS; - - //TODO: verify that authorization works - INamedContainerProvider containerProvider = getContainer(state, worldIn, pos); - if (containerProvider != null && player instanceof ServerPlayerEntity) { - ServerPlayerEntity serverPlayerEntity = (ServerPlayerEntity) player; - NetworkHooks.openGui(serverPlayerEntity, containerProvider, (packetBuffer) -> {}); - return ActionResultType.SUCCESS; - } - - return ActionResultType.FAIL; - } - - @Nullable - @Override - public TileEntity createNewTileEntity(IBlockReader worldIn) { - return new DecomposerTileEntity(); - } - - @Override - public BlockState rotate(BlockState state, Rotation rot) { - return state.with(FACING, rot.rotate(state.get(FACING))); - } - - @Override - public BlockState mirror(BlockState state, Mirror mirrorIn) { - return state.rotate(mirrorIn.toRotation(state.get(FACING))); - } - - @Override - public BlockRenderType getRenderType(BlockState state) { - return BlockRenderType.MODEL; - } - - @Override - public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) { - Direction facing = state.get(FACING); - switch (facing) { - case NORTH: - return NORTH_SHAPE; - case SOUTH: - return SOUTH_SHAPE; - case WEST: - return WEST_SHAPE; - case EAST: - return EAST_SHAPE; } - return VoxelShapes.fullCube(); } } diff --git a/src/main/java/com/github/elenterius/biomancy/block/DigesterBlock.java b/src/main/java/com/github/elenterius/biomancy/block/DigesterBlock.java index d4aab8d33..9e074d81a 100644 --- a/src/main/java/com/github/elenterius/biomancy/block/DigesterBlock.java +++ b/src/main/java/com/github/elenterius/biomancy/block/DigesterBlock.java @@ -1,30 +1,18 @@ package com.github.elenterius.biomancy.block; -import com.github.elenterius.biomancy.init.ModBlocks; import com.github.elenterius.biomancy.tileentity.DigesterTileEntity; import com.github.elenterius.biomancy.tileentity.state.DigesterStateData; import com.github.elenterius.biomancy.util.ClientTextUtil; -import com.github.elenterius.biomancy.util.VoxelShapeUtil; import net.minecraft.block.Block; import net.minecraft.block.BlockRenderType; import net.minecraft.block.BlockState; import net.minecraft.client.util.ITooltipFlag; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.entity.player.ServerPlayerEntity; -import net.minecraft.inventory.container.INamedContainerProvider; -import net.minecraft.item.BlockItemUseContext; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundNBT; -import net.minecraft.state.BooleanProperty; -import net.minecraft.state.DirectionProperty; -import net.minecraft.state.StateContainer; -import net.minecraft.state.properties.BlockStateProperties; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.*; -import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.Direction; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.SoundEvents; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.BlockRayTraceResult; -import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.shapes.IBooleanFunction; import net.minecraft.util.math.shapes.ISelectionContext; import net.minecraft.util.math.shapes.VoxelShape; @@ -35,32 +23,33 @@ import net.minecraft.world.World; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; -import net.minecraftforge.fml.network.NetworkHooks; import javax.annotation.Nullable; +import java.text.DecimalFormat; import java.util.List; +import java.util.Random; import java.util.stream.Stream; -public class DigesterBlock extends OwnableContainerBlock { +public class DigesterBlock extends MachineBlock { - public static final BooleanProperty CRAFTING = ModBlocks.CRAFTING_PROPERTY; - public static final DirectionProperty FACING = BlockStateProperties.HORIZONTAL_FACING; - - public static final VoxelShape NORTH_SHAPE = createVoxelShape(Direction.NORTH); - public static final VoxelShape SOUTH_SHAPE = createVoxelShape(Direction.SOUTH); - public static final VoxelShape EAST_SHAPE = createVoxelShape(Direction.EAST); - public static final VoxelShape WEST_SHAPE = createVoxelShape(Direction.WEST); + public static final VoxelShape UP_SHAPE = createVoxelShape(Direction.UP); public DigesterBlock(Properties builder) { super(builder); - setDefaultState(stateContainer.getBaseState().with(CRAFTING, false).with(FACING, Direction.NORTH)); } private static VoxelShape createVoxelShape(Direction direction) { - AxisAlignedBB aabb0 = VoxelShapeUtil.createUnitAABB(0, 0, 3, 16, 14, 16); - AxisAlignedBB aabb1 = VoxelShapeUtil.createUnitAABB(4, 14, 4, 12, 16, 12); - AxisAlignedBB aabb2 = VoxelShapeUtil.createUnitAABB(3, 1, 0, 13, 10, 3); - return Stream.of(VoxelShapeUtil.createWithFacing(direction, aabb0), VoxelShapeUtil.createWithFacing(direction, aabb1), VoxelShapeUtil.createWithFacing(direction, aabb2)).reduce((v1, v2) -> VoxelShapes.combineAndSimplify(v1, v2, IBooleanFunction.OR)).get(); + return Stream.of( + Block.makeCuboidShape(4.5, 14, 4.5, 11.5, 16, 11.5), + Block.makeCuboidShape(4, 0, 4, 12, 4, 12), + Block.makeCuboidShape(3, 4, 3, 13, 14, 13) + ).reduce((v1, v2) -> VoxelShapes.combineAndSimplify(v1, v2, IBooleanFunction.OR)).get(); + } + + @Nullable + @Override + public DigesterTileEntity createNewTileEntity(IBlockReader worldIn) { + return new DigesterTileEntity(); } @OnlyIn(Dist.CLIENT) @@ -71,82 +60,45 @@ public void addInformation(ItemStack stack, @Nullable IBlockReader worldIn, List if (nbt != null) { tooltip.add(ClientTextUtil.EMPTY_LINE_HACK()); CompoundNBT fuelNbt = nbt.getCompound(DigesterStateData.NBT_KEY_FUEL); - int mainFuel = (int) (MathHelper.clamp(fuelNbt.getInt("Amount") / (float) DigesterTileEntity.MAX_FUEL, 0f, 1f) * 100); - tooltip.add(new TranslationTextComponent("fluid." + fuelNbt.getString("FluidName").replace(":", ".").replace("/", ".")).appendString(": " + mainFuel + "%")); + int fuel = fuelNbt.getInt("Amount"); + String translationKey = "fluid." + fuelNbt.getString("FluidName").replace(":", ".").replace("/", "."); + DecimalFormat df = ClientTextUtil.getDecimalFormatter("#,###,###"); + tooltip.add(new TranslationTextComponent(translationKey).appendString(String.format(": %s/%s", df.format(fuel), df.format(DigesterTileEntity.MAX_FUEL)))); } super.addInformation(stack, worldIn, tooltip, flagIn); } @Override - protected void fillStateContainer(StateContainer.Builder builder) { - builder.add(CRAFTING, FACING); + public BlockRenderType getRenderType(BlockState state) { + return BlockRenderType.MODEL; } @Override - public BlockState getStateForPlacement(BlockItemUseContext context) { - return getDefaultState().with(FACING, context.getPlacementHorizontalFacing().getOpposite()); + public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) { + return UP_SHAPE; +// Direction facing = state.get(FACING); +// switch (facing) { +// case NORTH: +// return NORTH_SHAPE; +// case SOUTH: +// return SOUTH_SHAPE; +// case WEST: +// return WEST_SHAPE; +// case EAST: +// return EAST_SHAPE; +// } +// return VoxelShapes.fullCube(); } @Override - public void onReplaced(BlockState state, World world, BlockPos blockPos, BlockState newState, boolean isMoving) { - if (state.getBlock() != newState.getBlock()) { - TileEntity tileEntity = world.getTileEntity(blockPos); - if (tileEntity instanceof DigesterTileEntity) { - ((DigesterTileEntity) tileEntity).dropAllInvContents(world, blockPos); + @OnlyIn(Dist.CLIENT) + public void animateTick(BlockState stateIn, World worldIn, BlockPos pos, Random rand) { + if (worldIn.getGameTime() % 10L == 0 && rand.nextInt(2) == 0) { + boolean isCrafting = stateIn.get(CRAFTING); + if (isCrafting) { + worldIn.playSound(pos.getX(), pos.getY(), pos.getZ(), SoundEvents.ENTITY_PLAYER_BURP, SoundCategory.BLOCKS, 0.3f + rand.nextFloat() * 0.2f, 0.75f + rand.nextFloat() * 0.5f, false); } - super.onReplaced(state, world, blockPos, newState, isMoving); } } - @Override - public ActionResultType onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult hit) { - if (worldIn.isRemote()) return ActionResultType.SUCCESS; - - //TODO: verify that authorization works - INamedContainerProvider containerProvider = getContainer(state, worldIn, pos); - if (containerProvider != null && player instanceof ServerPlayerEntity) { - ServerPlayerEntity serverPlayerEntity = (ServerPlayerEntity) player; - NetworkHooks.openGui(serverPlayerEntity, containerProvider, (packetBuffer) -> {}); - return ActionResultType.SUCCESS; - } - - return ActionResultType.FAIL; - } - - @Nullable - @Override - public TileEntity createNewTileEntity(IBlockReader worldIn) { - return new DigesterTileEntity(); - } - - @Override - public BlockState rotate(BlockState state, Rotation rot) { - return state.with(FACING, rot.rotate(state.get(FACING))); - } - - @Override - public BlockState mirror(BlockState state, Mirror mirrorIn) { - return state.rotate(mirrorIn.toRotation(state.get(FACING))); - } - - @Override - public BlockRenderType getRenderType(BlockState state) { - return BlockRenderType.MODEL; - } - - @Override - public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) { - Direction facing = state.get(FACING); - switch (facing) { - case NORTH: - return NORTH_SHAPE; - case SOUTH: - return SOUTH_SHAPE; - case WEST: - return WEST_SHAPE; - case EAST: - return EAST_SHAPE; - } - return VoxelShapes.fullCube(); - } } diff --git a/src/main/java/com/github/elenterius/biomancy/block/EvolutionPoolBlock.java b/src/main/java/com/github/elenterius/biomancy/block/EvolutionPoolBlock.java index 25c8de3f3..11b7fdf18 100644 --- a/src/main/java/com/github/elenterius/biomancy/block/EvolutionPoolBlock.java +++ b/src/main/java/com/github/elenterius/biomancy/block/EvolutionPoolBlock.java @@ -49,7 +49,6 @@ public class EvolutionPoolBlock extends OwnableContainerBlock { public static final EnumProperty MULTI_BLOCK_PART = EnumProperty.create("part", MultiBlockPart.class); public static final BooleanProperty CONTROLLER = BooleanProperty.create("controller"); - public static final BooleanProperty CRAFTING = ModBlocks.CRAFTING_PROPERTY; public static final Direction8[] SORTED_POS_OFFSETS = new Direction8[]{Direction8.NORTH, Direction8.SOUTH, Direction8.WEST, Direction8.EAST, Direction8.NORTH_WEST, Direction8.NORTH_WEST, Direction8.SOUTH_WEST, Direction8.SOUTH_EAST}; public static final VoxelShape FLOOR_SHAPE = Block.makeCuboidShape(0, 0, 0, 16, 3, 16); @@ -73,12 +72,12 @@ public class EvolutionPoolBlock extends OwnableContainerBlock { public EvolutionPoolBlock(Properties properties) { super(properties); - setDefaultState(stateContainer.getBaseState().with(MULTI_BLOCK_PART, MultiBlockPart.MIDDLE).with(CONTROLLER, false).with(CRAFTING, false)); + setDefaultState(stateContainer.getBaseState().with(MULTI_BLOCK_PART, MultiBlockPart.MIDDLE).with(CONTROLLER, false).with(MachineBlock.CRAFTING, false)); } @Override protected void fillStateContainer(StateContainer.Builder builder) { - builder.add(MULTI_BLOCK_PART, CONTROLLER, CRAFTING); + builder.add(MULTI_BLOCK_PART, CONTROLLER, MachineBlock.CRAFTING); } @Nullable @@ -151,6 +150,9 @@ else if (tile instanceof EvolutionPoolTileEntity) { ((EvolutionPoolTileEntity) tile).dropAllInvContents(worldIn, pos); ((EvolutionPoolTileEntity) tile).scheduleMultiBlockDeconstruction(true); } + if (state.get(MachineBlock.CRAFTING)) { + worldIn.updateComparatorOutputLevel(pos, this); + } super.onReplaced(state, worldIn, pos, newState, isMoving); } } @@ -304,7 +306,7 @@ public void onEntityCollision(BlockState state, World worldIn, BlockPos pos, Ent tile = ((OwnableTileEntityDelegator) tile).getDelegate(); } if (tile instanceof EvolutionPoolTileEntity) { - if (EvolutionPoolTileEntity.isItemValidFuel(stack)) { + if (EvolutionPoolTileEntity.VALID_FUEL_ITEM.test(stack)) { ItemStack remainder = ((EvolutionPoolTileEntity) tile).addFuel(stack); if (remainder.getCount() != stack.getCount()) { ((ItemEntity) entityIn).setItem(remainder); @@ -331,6 +333,16 @@ public void onEntityCollision(BlockState state, World worldIn, BlockPos pos, Ent } } + @Override + public boolean hasComparatorInputOverride(BlockState state) { + return true; + } + + @Override + public int getComparatorInputOverride(BlockState blockState, World worldIn, BlockPos pos) { + return blockState.get(MachineBlock.CRAFTING) ? 15 : 0; + } + @Override public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) { MultiBlockPart part = state.get(MULTI_BLOCK_PART); @@ -361,7 +373,7 @@ public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, @OnlyIn(Dist.CLIENT) public void animateTick(BlockState stateIn, World worldIn, BlockPos pos, Random rand) { if (rand.nextInt(4) == 0) { - boolean isCrafting = stateIn.get(CRAFTING); + boolean isCrafting = stateIn.get(MachineBlock.CRAFTING); if (isCrafting) { int n = rand.nextInt(5); MultiBlockPart part = stateIn.get(MULTI_BLOCK_PART); diff --git a/src/main/java/com/github/elenterius/biomancy/block/FleshMelonCropBlock.java b/src/main/java/com/github/elenterius/biomancy/block/FleshMelonCropBlock.java index 482c329c5..c1b6fab00 100644 --- a/src/main/java/com/github/elenterius/biomancy/block/FleshMelonCropBlock.java +++ b/src/main/java/com/github/elenterius/biomancy/block/FleshMelonCropBlock.java @@ -1,8 +1,8 @@ package com.github.elenterius.biomancy.block; -import com.github.elenterius.biomancy.init.ModItems; import net.minecraft.block.Block; import net.minecraft.block.BlockState; +import net.minecraft.item.Items; import net.minecraft.util.IItemProvider; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.shapes.ISelectionContext; @@ -35,7 +35,8 @@ public VoxelShape getCollisionShape(BlockState state, IBlockReader worldIn, Bloc @Override public IItemProvider getSeedsItem() { - return ModItems.VILE_MELON_SEEDS.get(); + return Items.AIR; //TODO: revert this +// return ModItems.VILE_MELON_SEEDS.get(); } } diff --git a/src/main/java/com/github/elenterius/biomancy/block/ImpalerBlock.java b/src/main/java/com/github/elenterius/biomancy/block/ImpalerBlock.java deleted file mode 100644 index 32eee8b4b..000000000 --- a/src/main/java/com/github/elenterius/biomancy/block/ImpalerBlock.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.github.elenterius.biomancy.block; - -import net.minecraft.block.BlockState; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.world.IBlockReader; - -import javax.annotation.Nullable; - -public class ImpalerBlock extends OwnableBlock { - - public ImpalerBlock(Properties properties) { - super(properties); - //TODO: implement - } - - @Nullable - @Override - public TileEntity createTileEntity(BlockState state, IBlockReader world) { - return null; //TODO: create tile entity - } - -} diff --git a/src/main/java/com/github/elenterius/biomancy/block/MachineBlock.java b/src/main/java/com/github/elenterius/biomancy/block/MachineBlock.java new file mode 100644 index 000000000..dacd33f56 --- /dev/null +++ b/src/main/java/com/github/elenterius/biomancy/block/MachineBlock.java @@ -0,0 +1,146 @@ +package com.github.elenterius.biomancy.block; + +import com.github.elenterius.biomancy.init.ModBlocks; +import com.github.elenterius.biomancy.tileentity.MachineTileEntity; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraft.inventory.container.INamedContainerProvider; +import net.minecraft.item.BlockItemUseContext; +import net.minecraft.state.BooleanProperty; +import net.minecraft.state.DirectionProperty; +import net.minecraft.state.StateContainer; +import net.minecraft.state.properties.BlockStateProperties; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.*; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockRayTraceResult; +import net.minecraft.world.IBlockReader; +import net.minecraft.world.World; +import net.minecraft.world.server.ServerWorld; +import net.minecraftforge.common.util.Constants; +import net.minecraftforge.fml.network.NetworkHooks; + +import javax.annotation.Nullable; +import java.util.Random; + +public abstract class MachineBlock> extends OwnableContainerBlock { + + public static final BooleanProperty CRAFTING = ModBlocks.CRAFTING_PROPERTY; + public static final BooleanProperty POWERED = BlockStateProperties.POWERED; + public static final DirectionProperty FACING = BlockStateProperties.HORIZONTAL_FACING; + + protected MachineBlock(Properties builder) { + super(builder); + setDefaultState(stateContainer.getBaseState().with(POWERED, false).with(CRAFTING, false).with(FACING, Direction.NORTH)); + } + + @Nullable + @Override + public abstract T createNewTileEntity(IBlockReader worldIn); + + @Override + protected void fillStateContainer(StateContainer.Builder builder) { + builder.add(POWERED, CRAFTING, FACING); + } + + @Override + public BlockState getStateForPlacement(BlockItemUseContext context) { + return getDefaultState().with(FACING, context.getPlacementHorizontalFacing().getOpposite()); + } + + @Override + public ActionResultType onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult hit) { + if (worldIn.isRemote()) return ActionResultType.SUCCESS; + + //TODO: verify that authorization works + INamedContainerProvider containerProvider = getContainer(state, worldIn, pos); + if (containerProvider != null && player instanceof ServerPlayerEntity) { + ServerPlayerEntity serverPlayerEntity = (ServerPlayerEntity) player; + NetworkHooks.openGui(serverPlayerEntity, containerProvider, (packetBuffer) -> {}); + return ActionResultType.SUCCESS; + } + + return ActionResultType.FAIL; + } + + protected int getRedstoneLevel(BlockState state) { + return state.get(POWERED) ? 15 : 0; + } + + protected int getPoweredDuration() { + return 2; + } + + @Override + public void tick(BlockState state, ServerWorld worldIn, BlockPos pos, Random rand) { + if (state.get(POWERED)) { //after pending block update deactivate redstone + worldIn.setBlockState(pos, state.with(POWERED, Boolean.FALSE), Constants.BlockFlags.DEFAULT); + updateNeighbors(worldIn, pos); + } + } + + @Override + public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) { + if (!isMoving && !state.matchesBlock(newState.getBlock())) { + if (state.get(POWERED)) { + updateNeighbors(worldIn, pos); + } + TileEntity tileEntity = worldIn.getTileEntity(pos); + if (tileEntity instanceof MachineTileEntity) { + ((MachineTileEntity) tileEntity).dropAllInvContents(worldIn, pos); + } + if (state.get(CRAFTING)) { + worldIn.updateComparatorOutputLevel(pos, this); + } + super.onReplaced(state, worldIn, pos, newState, isMoving); + } + } + + public void powerBlock(World worldIn, BlockPos pos, BlockState state) { + worldIn.setBlockState(pos, state.with(POWERED, Boolean.TRUE), Constants.BlockFlags.DEFAULT); + updateNeighbors(worldIn, pos); + worldIn.getPendingBlockTicks().scheduleTick(pos, this, getPoweredDuration()); + } + + @Override + public int getWeakPower(BlockState blockState, IBlockReader blockAccess, BlockPos pos, Direction side) { + return getRedstoneLevel(blockState); + } + + @Override + public int getStrongPower(BlockState blockState, IBlockReader blockAccess, BlockPos pos, Direction side) { + return getRedstoneLevel(blockState); + } + + @Override + public boolean canProvidePower(BlockState state) { + return true; + } + + @Override + public boolean hasComparatorInputOverride(BlockState state) { + return true; + } + + @Override + public int getComparatorInputOverride(BlockState blockState, World worldIn, BlockPos pos) { + return blockState.get(CRAFTING) ? 15 : 0; + } + + protected void updateNeighbors(World worldIn, BlockPos pos) { + worldIn.notifyNeighborsOfStateChange(pos, this); +// worldIn.notifyNeighborsOfStateChange(pos.down(), this); + } + + @Override + public BlockState rotate(BlockState state, Rotation rot) { + return state.with(FACING, rot.rotate(state.get(FACING))); + } + + @Override + public BlockState mirror(BlockState state, Mirror mirrorIn) { + return state.rotate(mirrorIn.toRotation(state.get(FACING))); + } +} diff --git a/src/main/java/com/github/elenterius/biomancy/block/MeatsoupCauldronBlock.java b/src/main/java/com/github/elenterius/biomancy/block/MeatsoupCauldronBlock.java index 92026f312..aaf9963c1 100644 --- a/src/main/java/com/github/elenterius/biomancy/block/MeatsoupCauldronBlock.java +++ b/src/main/java/com/github/elenterius/biomancy/block/MeatsoupCauldronBlock.java @@ -115,6 +115,23 @@ else if (!Flags.isFlagSet(flagValue, Flags.BONE_MEAL) && item instanceof BoneMea worldIn.getPendingBlockTicks().scheduleTick(pos, state.getBlock(), 55 + 1 + worldIn.rand.nextInt(20)); } } + else if (level >= MAX_LEVEL - 3 && level < MAX_LEVEL - 1) { + if (item instanceof PotionItem) { + Potion potion = PotionUtils.getPotionFromItem(stack); + if (potion == Potions.HEALING || potion == Potions.REGENERATION) { + stack.grow(-1); + entityIn.entityDropItem(stack.hasContainerItem() ? stack.getContainerItem() : new ItemStack(Items.GLASS_BOTTLE)); + setSoupLevel(worldIn, pos, state, flagValue, level, 1); + worldIn.playSound(null, pos, SoundEvents.ITEM_BOTTLE_EMPTY, SoundCategory.BLOCKS, 1f, 1f); + } + else if (potion == Potions.STRONG_HEALING || potion == Potions.STRONG_REGENERATION || potion == Potions.LONG_REGENERATION) { + stack.grow(-1); + entityIn.entityDropItem(stack.hasContainerItem() ? stack.getContainerItem() : new ItemStack(Items.GLASS_BOTTLE)); + setSoupLevel(worldIn, pos, state, flagValue, level, 2); + worldIn.playSound(null, pos, SoundEvents.ITEM_BOTTLE_EMPTY, SoundCategory.BLOCKS, 1f, 1f); + } + } + } } } } diff --git a/src/main/java/com/github/elenterius/biomancy/capabilities/InputFilterItemStackHandler.java b/src/main/java/com/github/elenterius/biomancy/capabilities/InputFilterItemStackHandler.java new file mode 100644 index 000000000..b9ba7e37b --- /dev/null +++ b/src/main/java/com/github/elenterius/biomancy/capabilities/InputFilterItemStackHandler.java @@ -0,0 +1,61 @@ +package com.github.elenterius.biomancy.capabilities; + +import net.minecraft.item.ItemStack; +import net.minecraftforge.items.IItemHandler; +import net.minecraftforge.items.ItemStackHandler; + +import javax.annotation.Nonnull; +import java.util.function.Predicate; + +/** + * Delegator that only allows item insertion of valid items.
+ * Used to expose inventory capabilities that only allow item insertion of specific items. + */ +public class InputFilterItemStackHandler implements IItemHandler { + + private final ItemStackHandler itemStackHandler; + private final Predicate validItems; + + public InputFilterItemStackHandler(ItemStackHandler itemStackHandler, Predicate validItems) { + this.itemStackHandler = itemStackHandler; + this.validItems = validItems; + } + + @Override + public boolean isItemValid(int slot, @Nonnull ItemStack stack) { + return validItems.test(stack); + } + + @Override + @Nonnull + public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate) { + if (!validItems.test(stack)) { + return stack; + } + + return itemStackHandler.insertItem(slot, stack, simulate); + } + + @Override + public int getSlots() { + return itemStackHandler.getSlots(); + } + + @Override + @Nonnull + public ItemStack getStackInSlot(int slot) { + return itemStackHandler.getStackInSlot(slot); + } + + @Override + @Nonnull + public ItemStack extractItem(int slot, int amount, boolean simulate) { + return itemStackHandler.extractItem(slot, amount, simulate); + } + + @Override + public int getSlotLimit(int slot) { + return itemStackHandler.getSlotLimit(slot); + } + +} diff --git a/src/main/java/com/github/elenterius/biomancy/client/gui/ChewerContainerScreen.java b/src/main/java/com/github/elenterius/biomancy/client/gui/ChewerContainerScreen.java index 381662e4f..083e05b67 100644 --- a/src/main/java/com/github/elenterius/biomancy/client/gui/ChewerContainerScreen.java +++ b/src/main/java/com/github/elenterius/biomancy/client/gui/ChewerContainerScreen.java @@ -3,6 +3,7 @@ import com.github.elenterius.biomancy.BiomancyMod; import com.github.elenterius.biomancy.client.gui.drawable.ProgressBar; import com.github.elenterius.biomancy.inventory.ChewerContainer; +import com.github.elenterius.biomancy.util.ClientTextUtil; import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.gui.screen.inventory.ContainerScreen; @@ -10,9 +11,8 @@ import net.minecraft.util.ResourceLocation; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.TranslationTextComponent; -import net.minecraftforge.client.MinecraftForgeClient; -import java.text.NumberFormat; +import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; @@ -65,9 +65,9 @@ protected void renderHoveredTooltip(MatrixStack matrixStack, int mouseX, int mou List hoveringText = new ArrayList<>(); if (progressBar.isMouseInside(guiLeft, guiTop, mouseX, mouseY)) { - float fuel = container.getFuelNormalized(); - NumberFormat percentFormatter = NumberFormat.getPercentInstance(MinecraftForgeClient.getLocale()); - hoveringText.add(new TranslationTextComponent(container.getFuelTranslationKey()).appendString(": " + percentFormatter.format(fuel))); + int fuel = container.getFuel(); + DecimalFormat df = ClientTextUtil.getDecimalFormatter("#,###,###"); + hoveringText.add(new TranslationTextComponent(container.getFuelTranslationKey()).appendString(": " + df.format(fuel))); } if (!hoveringText.isEmpty()) { diff --git a/src/main/java/com/github/elenterius/biomancy/client/gui/DecomposerContainerScreen.java b/src/main/java/com/github/elenterius/biomancy/client/gui/DecomposerContainerScreen.java index 2dfe06a1b..29c21a814 100644 --- a/src/main/java/com/github/elenterius/biomancy/client/gui/DecomposerContainerScreen.java +++ b/src/main/java/com/github/elenterius/biomancy/client/gui/DecomposerContainerScreen.java @@ -3,6 +3,7 @@ import com.github.elenterius.biomancy.BiomancyMod; import com.github.elenterius.biomancy.client.gui.drawable.ProgressBar; import com.github.elenterius.biomancy.inventory.DecomposerContainer; +import com.github.elenterius.biomancy.util.ClientTextUtil; import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.gui.screen.inventory.ContainerScreen; @@ -10,9 +11,8 @@ import net.minecraft.util.ResourceLocation; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.TranslationTextComponent; -import net.minecraftforge.client.MinecraftForgeClient; -import java.text.NumberFormat; +import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; @@ -65,9 +65,9 @@ protected void renderHoveredTooltip(MatrixStack matrixStack, int mouseX, int mou List hoveringText = new ArrayList<>(); if (progressBar.isMouseInside(guiLeft, guiTop, mouseX, mouseY)) { - float fuel = container.getFuelNormalized(); - NumberFormat percentFormatter = NumberFormat.getPercentInstance(MinecraftForgeClient.getLocale()); - hoveringText.add(new TranslationTextComponent(container.getFuelTranslationKey()).appendString(": " + percentFormatter.format(fuel))); + int fuel = container.getFuel(); + DecimalFormat df = ClientTextUtil.getDecimalFormatter("#,###,###"); + hoveringText.add(new TranslationTextComponent(container.getFuelTranslationKey()).appendString(": " + df.format(fuel))); } if (!hoveringText.isEmpty()) { diff --git a/src/main/java/com/github/elenterius/biomancy/client/gui/DigesterContainerScreen.java b/src/main/java/com/github/elenterius/biomancy/client/gui/DigesterContainerScreen.java index 1f6cc1fe3..b2722e1df 100644 --- a/src/main/java/com/github/elenterius/biomancy/client/gui/DigesterContainerScreen.java +++ b/src/main/java/com/github/elenterius/biomancy/client/gui/DigesterContainerScreen.java @@ -3,6 +3,7 @@ import com.github.elenterius.biomancy.BiomancyMod; import com.github.elenterius.biomancy.client.gui.drawable.ProgressBar; import com.github.elenterius.biomancy.inventory.DigesterContainer; +import com.github.elenterius.biomancy.util.ClientTextUtil; import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.gui.screen.inventory.ContainerScreen; @@ -10,9 +11,8 @@ import net.minecraft.util.ResourceLocation; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.TranslationTextComponent; -import net.minecraftforge.client.MinecraftForgeClient; -import java.text.NumberFormat; +import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; @@ -65,9 +65,9 @@ protected void renderHoveredTooltip(MatrixStack matrixStack, int mouseX, int mou List hoveringText = new ArrayList<>(); if (progressBar.isMouseInside(guiLeft, guiTop, mouseX, mouseY)) { - float fuel = container.getFuelNormalized(); - NumberFormat percentFormatter = NumberFormat.getPercentInstance(MinecraftForgeClient.getLocale()); - hoveringText.add(new TranslationTextComponent(container.getFuelTranslationKey()).appendString(": " + percentFormatter.format(fuel))); + int fuel = container.getFuel(); + DecimalFormat df = ClientTextUtil.getDecimalFormatter("#,###,###"); + hoveringText.add(new TranslationTextComponent(container.getFuelTranslationKey()).appendString(": " + df.format(fuel))); } if (!hoveringText.isEmpty()) { diff --git a/src/main/java/com/github/elenterius/biomancy/client/gui/EvolutionPoolContainerScreen.java b/src/main/java/com/github/elenterius/biomancy/client/gui/EvolutionPoolContainerScreen.java index 6e9a4f4dc..7ee6ad390 100644 --- a/src/main/java/com/github/elenterius/biomancy/client/gui/EvolutionPoolContainerScreen.java +++ b/src/main/java/com/github/elenterius/biomancy/client/gui/EvolutionPoolContainerScreen.java @@ -3,6 +3,7 @@ import com.github.elenterius.biomancy.BiomancyMod; import com.github.elenterius.biomancy.client.gui.drawable.ProgressBar; import com.github.elenterius.biomancy.inventory.EvolutionPoolContainer; +import com.github.elenterius.biomancy.util.ClientTextUtil; import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.gui.screen.inventory.ContainerScreen; @@ -10,9 +11,8 @@ import net.minecraft.util.ResourceLocation; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.TranslationTextComponent; -import net.minecraftforge.client.MinecraftForgeClient; -import java.text.NumberFormat; +import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; @@ -65,9 +65,9 @@ protected void renderHoveredTooltip(MatrixStack matrixStack, int mouseX, int mou List hoveringText = new ArrayList<>(); if (progressBar.isMouseInside(guiLeft, guiTop, mouseX, mouseY)) { - float fuel = container.getFuelNormalized(); - NumberFormat percentFormatter = NumberFormat.getPercentInstance(MinecraftForgeClient.getLocale()); - hoveringText.add(new TranslationTextComponent(container.getFuelTranslationKey()).appendString(": " + percentFormatter.format(fuel))); + int fuel = container.getFuel(); + DecimalFormat df = ClientTextUtil.getDecimalFormatter("#,###,###"); + hoveringText.add(new TranslationTextComponent(container.getFuelTranslationKey()).appendString(": " + df.format(fuel))); } if (!hoveringText.isEmpty()) { diff --git a/src/main/java/com/github/elenterius/biomancy/client/renderer/ClientRenderHandler.java b/src/main/java/com/github/elenterius/biomancy/client/renderer/ClientRenderHandler.java index da6b3d44b..7258739a6 100644 --- a/src/main/java/com/github/elenterius/biomancy/client/renderer/ClientRenderHandler.java +++ b/src/main/java/com/github/elenterius/biomancy/client/renderer/ClientRenderHandler.java @@ -3,11 +3,14 @@ import com.github.elenterius.biomancy.BiomancyMod; import com.github.elenterius.biomancy.enchantment.AttunedDamageEnchantment; import com.github.elenterius.biomancy.init.ModEnchantments; +import com.github.elenterius.biomancy.init.ModItems; import com.github.elenterius.biomancy.item.IAreaHarvestingItem; import com.github.elenterius.biomancy.item.IHighlightRayTraceResultItem; +import com.github.elenterius.biomancy.item.InjectionDeviceItem; import com.github.elenterius.biomancy.item.ItemStorageBagItem; import com.github.elenterius.biomancy.item.weapon.shootable.ProjectileWeaponItem; import com.github.elenterius.biomancy.item.weapon.shootable.SinewBowItem; +import com.github.elenterius.biomancy.reagent.Reagent; import com.github.elenterius.biomancy.util.PlayerInteractionUtil; import com.github.elenterius.biomancy.util.RayTraceUtil; import com.mojang.blaze3d.matrix.MatrixStack; @@ -142,6 +145,9 @@ else if (item instanceof ProjectileWeaponItem) { else if (item instanceof ItemStorageBagItem) { renderItemStorageBagOverlay(matrix, scaledWidth, scaledHeight, mc, player, heldStack, (ItemStorageBagItem) item); } + else if (item instanceof InjectionDeviceItem) { + renderInjectionDeviceOverlay(matrix, scaledWidth, scaledHeight, mc, player, heldStack, (InjectionDeviceItem) item); + } } } @@ -160,7 +166,7 @@ private static void renderItemStorageBagOverlay(MatrixStack matrixStack, int sca LazyOptional capability = tile.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY); if (capability.isPresent()) { mc.getTextureManager().bindTexture(ITEM_BAG_INDICATOR_TEX); - int x = scaledWidth / 2 - 33; + int x = scaledWidth / 2 - 16 - 8; int y = scaledHeight / 2 + 9; AbstractGui.blit(matrixStack, x, y, 0, mode == ItemStorageBagItem.Mode.DEVOUR ? 0 : 16, 32, 16, 32, 32); @@ -187,6 +193,30 @@ private static void renderBowOverlay(MatrixStack matrixStack, int scaledWidth, i drawRectangularProgressIndicator(matrixStack, x, y, 25f, pullProgress, 0xFFFEFEFE); } + private static void renderInjectionDeviceOverlay(MatrixStack matrix, int scaledWidth, int scaledHeight, Minecraft mc, ClientPlayerEntity player, ItemStack stack, InjectionDeviceItem item) { + byte amount = item.getReagentAmount(stack); + if (amount < 1) return; + + Reagent reagent = item.getReagent(stack); + if (reagent != null) { + FontRenderer fontRenderer = mc.fontRenderer; + String text = amount + "x"; + + int x = scaledWidth - 16 - 4; + int y = scaledHeight - 16 - 4; + matrix.push(); + float scale = 1.5f; //make font bigger + matrix.translate(x - fontRenderer.getStringWidth(text) * scale, y + 16 - fontRenderer.FONT_HEIGHT * scale, 0); + matrix.scale(scale, scale, 0); + AbstractGui.drawString(matrix, fontRenderer, text, 0, 0, 0xFFFEFEFE); + matrix.pop(); + + ItemStack reagentStack = new ItemStack(ModItems.REAGENT.get()); + Reagent.serialize(reagent, reagentStack.getOrCreateTag()); + mc.getItemRenderer().renderItemIntoGUI(reagentStack, x, y); + } + } + private static void renderGunOverlay(MatrixStack matrix, int scaledWidth, int scaledHeight, Minecraft mc, ClientPlayerEntity player, ItemStack stack, ProjectileWeaponItem item) { FontRenderer fontRenderer = mc.fontRenderer; diff --git a/src/main/java/com/github/elenterius/biomancy/datagen/ModBlockLootTables.java b/src/main/java/com/github/elenterius/biomancy/datagen/ModBlockLootTables.java index 0c58745d1..9541841f8 100644 --- a/src/main/java/com/github/elenterius/biomancy/datagen/ModBlockLootTables.java +++ b/src/main/java/com/github/elenterius/biomancy/datagen/ModBlockLootTables.java @@ -7,13 +7,10 @@ import net.minecraft.advancements.criterion.StatePropertiesPredicate; import net.minecraft.block.Block; import net.minecraft.block.Blocks; -import net.minecraft.block.CropsBlock; import net.minecraft.block.DoorBlock; import net.minecraft.data.loot.BlockLootTables; -import net.minecraft.item.Item; import net.minecraft.loot.*; import net.minecraft.loot.conditions.BlockStateProperty; -import net.minecraft.loot.conditions.ILootCondition; import net.minecraft.loot.functions.CopyBlockState; import net.minecraft.loot.functions.CopyName; import net.minecraft.loot.functions.CopyNbt; @@ -91,23 +88,23 @@ protected static LootTable.Builder droppingMutatedFlesh(Block flesh) { .addEntry(ItemLootEntry.builder(flesh).acceptFunction(CopyBlockState.func_227545_a_(flesh).func_227552_a_(MutatedFleshBlock.MUTATION_TYPE))))); } - protected static LootTable.Builder droppingFruitWithBonusOrSeeds(Block block, Item fruit, Item seeds) { - ILootCondition.IBuilder conditionBuilder = BlockStateProperty.builder(ModBlocks.VILE_MELON_CROP.get()).fromProperties(StatePropertiesPredicate.Builder.newBuilder().withIntProp(CropsBlock.AGE, 7)); - return withExplosionDecay(block, LootTable.builder().addLootPool(LootPool.builder().addEntry(ItemLootEntry.builder(fruit).acceptCondition(conditionBuilder).alternatively(ItemLootEntry.builder(seeds))))); - } +// protected static LootTable.Builder droppingFruitWithBonusOrSeeds(Block block, Item fruit, Item seeds) { +// ILootCondition.IBuilder conditionBuilder = BlockStateProperty.builder(ModBlocks.VILE_MELON_CROP.get()).fromProperties(StatePropertiesPredicate.Builder.newBuilder().withIntProp(CropsBlock.AGE, 7)); +// return withExplosionDecay(block, LootTable.builder().addLootPool(LootPool.builder().addEntry(ItemLootEntry.builder(fruit).acceptCondition(conditionBuilder).alternatively(ItemLootEntry.builder(seeds))))); +// } @Override protected void addTables() { - registerDropSelfLootTable(ModBlocks.VILE_MELON_BLOCK.get()); - registerLootTable(ModBlocks.VILE_MELON_CROP.get(), droppingFruitWithBonusOrSeeds(ModBlocks.VILE_MELON_CROP.get(), ModItems.VILE_MELON_BLOCK.get(), ModItems.VILE_MELON_SEEDS.get())); +// registerDropSelfLootTable(ModBlocks.VILE_MELON_BLOCK.get()); +// registerLootTable(ModBlocks.VILE_MELON_CROP.get(), droppingFruitWithBonusOrSeeds(ModBlocks.VILE_MELON_CROP.get(), ModItems.VILE_MELON_BLOCK.get(), ModItems.VILE_MELON_SEEDS.get())); registerDropSelfLootTable(ModBlocks.FLESH_TENTACLE.get()); registerDropSelfLootTable(ModBlocks.FLESH_BLOCK.get()); registerLootTable(ModBlocks.NECROTIC_FLESH_BLOCK.get(), droppingRandomly(ModItems.NECROTIC_FLESH.get(), BinomialRange.of(9, 0.5f))); registerLootTable(ModBlocks.FLESH_BLOCK_SLAB.get(), BlockLootTables::droppingSlab); registerDropSelfLootTable(ModBlocks.FLESH_BLOCK_STAIRS.get()); - registerLootTable(ModBlocks.MUTATED_FLESH_BLOCK.get(), ModBlockLootTables::droppingMutatedFlesh); +// registerLootTable(ModBlocks.MUTATED_FLESH_BLOCK.get(), ModBlockLootTables::droppingMutatedFlesh); registerLootTable(ModBlocks.FLESHBORN_DOOR.get(), ModBlockLootTables::droppingSimpleOwnableDoor); registerLootTable(ModBlocks.FLESHBORN_TRAPDOOR.get(), ModBlockLootTables::droppingSimpleOwnable); registerLootTable(ModBlocks.FLESHBORN_PRESSURE_PLATE.get(), ModBlockLootTables::droppingSimpleOwnable); diff --git a/src/main/java/com/github/elenterius/biomancy/datagen/ModRecipeProvider.java b/src/main/java/com/github/elenterius/biomancy/datagen/ModRecipeProvider.java index 6d5b3fdca..0bba96f38 100644 --- a/src/main/java/com/github/elenterius/biomancy/datagen/ModRecipeProvider.java +++ b/src/main/java/com/github/elenterius/biomancy/datagen/ModRecipeProvider.java @@ -619,11 +619,11 @@ private void registerCookingRecipes(Consumer consumer) { CookingRecipeBuilder.smeltingRecipe(Ingredient.fromItems(ModItems.SILICATE_PASTE.get()), Items.GLASS_PANE, 0.1F, 100) .addCriterion("has_silicate", hasItem(ModItems.SILICATE_PASTE.get())).build(consumer, new ResourceLocation(BiomancyMod.MOD_ID, "glass_pane_from_smelting_silicate")); - CookingRecipeBuilder.cookingRecipe(Ingredient.fromItems(ModItems.VILE_MELON_SLICE.get()), ModItems.COOKED_VILE_MELON_SLICE.get(), 0.35F, 100, IRecipeSerializer.SMELTING) - .addCriterion("has_vile_melon_slice", hasItem(ModItems.VILE_MELON_SLICE.get())).build(consumer, new ResourceLocation(BiomancyMod.MOD_ID, "vile_melon_from_smelting")); - - CookingRecipeBuilder.cookingRecipe(Ingredient.fromItems(ModItems.VILE_MELON_SLICE.get()), ModItems.COOKED_VILE_MELON_SLICE.get(), 0.35F, 600, IRecipeSerializer.CAMPFIRE_COOKING) - .addCriterion("has_vile_melon_slice", hasItem(ModItems.VILE_MELON_SLICE.get())).build(consumer, new ResourceLocation(BiomancyMod.MOD_ID, "vile_melon_from_campfire")); +// CookingRecipeBuilder.cookingRecipe(Ingredient.fromItems(ModItems.VILE_MELON_SLICE.get()), ModItems.COOKED_VILE_MELON_SLICE.get(), 0.35F, 100, IRecipeSerializer.SMELTING) +// .addCriterion("has_vile_melon_slice", hasItem(ModItems.VILE_MELON_SLICE.get())).build(consumer, new ResourceLocation(BiomancyMod.MOD_ID, "vile_melon_from_smelting")); +// +// CookingRecipeBuilder.cookingRecipe(Ingredient.fromItems(ModItems.VILE_MELON_SLICE.get()), ModItems.COOKED_VILE_MELON_SLICE.get(), 0.35F, 600, IRecipeSerializer.CAMPFIRE_COOKING) +// .addCriterion("has_vile_melon_slice", hasItem(ModItems.VILE_MELON_SLICE.get())).build(consumer, new ResourceLocation(BiomancyMod.MOD_ID, "vile_melon_from_campfire")); } private void registerWorkbenchRecipes(Consumer consumer) { @@ -791,9 +791,9 @@ private void registerWorkbenchRecipes(Consumer consumer) { .patternLine("SBS").patternLine("NNN") .addCriterion("has_nutrient_paste", hasItem(ModItems.NUTRIENT_PASTE.get())).build(consumer); - ShapelessRecipeBuilder.shapelessRecipe(ModItems.VILE_MELON_SEEDS.get()) - .addIngredient(ModItems.VILE_MELON_SLICE.get()) - .addCriterion("has_vile_melon_slice", hasItem(ModItems.VILE_MELON_SLICE.get())).build(consumer); +// ShapelessRecipeBuilder.shapelessRecipe(ModItems.VILE_MELON_SEEDS.get()) +// .addIngredient(ModItems.VILE_MELON_SLICE.get()) +// .addCriterion("has_vile_melon_slice", hasItem(ModItems.VILE_MELON_SLICE.get())).build(consumer); // misc //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ShapelessRecipeBuilder.shapelessRecipe(Items.DIORITE) diff --git a/src/main/java/com/github/elenterius/biomancy/init/ClientSetupHandler.java b/src/main/java/com/github/elenterius/biomancy/init/ClientSetupHandler.java index 696724f62..a6e679d80 100644 --- a/src/main/java/com/github/elenterius/biomancy/init/ClientSetupHandler.java +++ b/src/main/java/com/github/elenterius/biomancy/init/ClientSetupHandler.java @@ -81,11 +81,14 @@ public static void onClientSetup(FMLClientSetupEvent event) { ItemModelsProperties.registerProperty(ModItems.BONE_SCRAPS.get(), new ResourceLocation("type"), (stack, clientWorld, livingEntity) -> stack.getOrCreateTag().getInt("ScrapType")); RenderTypeLookup.setRenderLayer(ModBlocks.FLESH_TENTACLE.get(), RenderType.getCutout()); - RenderTypeLookup.setRenderLayer(ModBlocks.VILE_MELON_CROP.get(), RenderType.getCutout()); +// RenderTypeLookup.setRenderLayer(ModBlocks.VILE_MELON_CROP.get(), RenderType.getCutout()); RenderTypeLookup.setRenderLayer(ModBlocks.FLESHBORN_DOOR.get(), RenderType.getCutout()); RenderTypeLookup.setRenderLayer(ModBlocks.FLESHBORN_TRAPDOOR.get(), RenderType.getCutout()); RenderTypeLookup.setRenderLayer(ModBlocks.EVOLUTION_POOL.get(), RenderType.getTranslucent()); + RenderTypeLookup.setRenderLayer(ModBlocks.DECOMPOSER.get(), RenderType.getTranslucent()); + RenderTypeLookup.setRenderLayer(ModBlocks.DIGESTER.get(), RenderType.getCutout()); + RenderTypeLookup.setRenderLayer(ModBlocks.CHEWER.get(), RenderType.getCutout()); // RenderTypeLookup.setRenderLayer(ModBlocks.LUMINOUS_SOIL.get(), renderType -> renderType == RenderType.getCutout() || renderType == RenderType.getTranslucent()); // RenderTypeLookup.setRenderLayer(ModBlocks.BLIGHT_PUSTULE_SMALL.get(), RenderType.getCutout()); @@ -97,8 +100,8 @@ public static void onBlockModelRegistry(final ModelRegistryEvent event) {} @SubscribeEvent public static void onItemColorRegistry(final ColorHandlerEvent.Item event) { - event.getItemColors().register((stack, index) -> 0xff6981, ModItems.VILE_MELON_BLOCK.get(), ModItems.VILE_MELON_SEEDS.get(), ModItems.VILE_MELON_SLICE.get()); - event.getItemColors().register((stack, index) -> 0x6c2e1f, ModItems.COOKED_VILE_MELON_SLICE.get()); +// event.getItemColors().register((stack, index) -> 0xff6981, ModItems.VILE_MELON_BLOCK.get(), ModItems.VILE_MELON_SEEDS.get(), ModItems.VILE_MELON_SLICE.get()); +// event.getItemColors().register((stack, index) -> 0x6c2e1f, ModItems.COOKED_VILE_MELON_SLICE.get()); event.getItemColors().register((stack, index) -> 0x8d758c, ModItems.NECROTIC_FLESH.get(), ModItems.NECROTIC_FLESH_BLOCK.get()); event.getItemColors().register((stack, index) -> index == 1 ? ModItems.INJECTION_DEVICE.get().getReagentColor(stack) : -1, ModItems.INJECTION_DEVICE.get()); @@ -108,7 +111,7 @@ public static void onItemColorRegistry(final ColorHandlerEvent.Item event) { @SubscribeEvent public static void onItemColorRegistry(final ColorHandlerEvent.Block event) { - event.getBlockColors().register((state, displayReader, pos, index) -> 0xff6981, ModBlocks.VILE_MELON_BLOCK.get(), ModBlocks.VILE_MELON_CROP.get()); +// event.getBlockColors().register((state, displayReader, pos, index) -> 0xff6981, ModBlocks.VILE_MELON_BLOCK.get(), ModBlocks.VILE_MELON_CROP.get()); event.getBlockColors().register((state, displayReader, pos, index) -> 0x8d758c, ModBlocks.NECROTIC_FLESH_BLOCK.get()); } diff --git a/src/main/java/com/github/elenterius/biomancy/init/ModBlocks.java b/src/main/java/com/github/elenterius/biomancy/init/ModBlocks.java index dbd2c199f..2e178bf19 100644 --- a/src/main/java/com/github/elenterius/biomancy/init/ModBlocks.java +++ b/src/main/java/com/github/elenterius/biomancy/init/ModBlocks.java @@ -43,12 +43,12 @@ public final class ModBlocks { public static final RegistryObject FLESH_BLOCK = BLOCKS.register("flesh_block", () -> new FleshBlock(createFleshProperties())); public static final RegistryObject FLESH_BLOCK_SLAB = BLOCKS.register("flesh_block_slab", () -> new SlabBlock(createFleshProperties())); public static final RegistryObject FLESH_BLOCK_STAIRS = BLOCKS.register("flesh_block_stairs", () -> new StairsBlock(() -> FLESH_BLOCK.get().getDefaultState(), createFleshProperties())); - public static final RegistryObject MUTATED_FLESH_BLOCK = BLOCKS.register("mutated_flesh_block", () -> new MutatedFleshBlock(createFleshProperties())); +// public static final RegistryObject MUTATED_FLESH_BLOCK = BLOCKS.register("mutated_flesh_block", () -> new MutatedFleshBlock(createFleshProperties())); public static final RegistryObject NECROTIC_FLESH_BLOCK = BLOCKS.register("necrotic_flesh_block", () -> new FleshBlock(createFleshProperties())); //Plant - public static final RegistryObject VILE_MELON_BLOCK = BLOCKS.register("vile_melon_block", () -> new Block(Block.Properties.create(Material.GOURD, MaterialColor.PINK).hardnessAndResistance(1f).sound(SoundType.WOOD))); - public static final RegistryObject VILE_MELON_CROP = BLOCKS.register("vile_melon_crop", () -> new FleshMelonCropBlock(Block.Properties.create(Material.PLANTS, MaterialColor.PINK).tickRandomly().hardnessAndResistance(0.2f).sound(SoundType.STEM))); +// public static final RegistryObject VILE_MELON_BLOCK = BLOCKS.register("vile_melon_block", () -> new Block(Block.Properties.create(Material.GOURD, MaterialColor.PINK).hardnessAndResistance(1f).sound(SoundType.WOOD))); +// public static final RegistryObject VILE_MELON_CROP = BLOCKS.register("vile_melon_crop", () -> new FleshMelonCropBlock(Block.Properties.create(Material.PLANTS, MaterialColor.PINK).tickRandomly().hardnessAndResistance(0.2f).sound(SoundType.STEM))); //Bio-Constructs public static final RegistryObject FLESHBORN_DOOR = BLOCKS.register("fleshborn_door", () -> new OwnableDoorBlock(createFleshProperties().notSolid())); diff --git a/src/main/java/com/github/elenterius/biomancy/init/ModItems.java b/src/main/java/com/github/elenterius/biomancy/init/ModItems.java index 2fb215d68..424586e33 100644 --- a/src/main/java/com/github/elenterius/biomancy/init/ModItems.java +++ b/src/main/java/com/github/elenterius/biomancy/init/ModItems.java @@ -79,8 +79,8 @@ public final class ModItems { public static final RegistryObject HORMONE_BILE = ITEMS.register("hormone_bile", () -> new Item(createItemProperties())); // Food - public static final RegistryObject VILE_MELON_SLICE = ITEMS.register("vile_melon_slice", () -> new Item(createItemProperties().food(ModFoods.VILE_MELON_SLICE))); - public static final RegistryObject COOKED_VILE_MELON_SLICE = ITEMS.register("cooked_vile_melon_slice", () -> new Item(createItemProperties().food(ModFoods.COOKED_VILE_MELON_SLICE))); +// public static final RegistryObject VILE_MELON_SLICE = ITEMS.register("vile_melon_slice", () -> new Item(createItemProperties().food(ModFoods.VILE_MELON_SLICE))); +// public static final RegistryObject COOKED_VILE_MELON_SLICE = ITEMS.register("cooked_vile_melon_slice", () -> new Item(createItemProperties().food(ModFoods.COOKED_VILE_MELON_SLICE))); public static final RegistryObject NUTRIENT_BAR = ITEMS.register("nutrient_bar", () -> new Item(createItemProperties().food(ModFoods.NUTRIENT_BAR))); // Spawn Eggs @@ -99,8 +99,8 @@ public final class ModItems { /* **** Block Items ********************************************* */ //crops - public static final RegistryObject VILE_MELON_SEEDS = ITEMS.register("vile_melon_seeds", () -> new BlockNamedItem(ModBlocks.VILE_MELON_CROP.get(), createItemProperties())); - public static final RegistryObject VILE_MELON_BLOCK = ITEMS.register("vile_melon_block", () -> new BlockItem(ModBlocks.VILE_MELON_BLOCK.get(), createItemProperties())); +// public static final RegistryObject VILE_MELON_SEEDS = ITEMS.register("vile_melon_seeds", () -> new BlockNamedItem(ModBlocks.VILE_MELON_CROP.get(), createItemProperties())); +// public static final RegistryObject VILE_MELON_BLOCK = ITEMS.register("vile_melon_block", () -> new BlockItem(ModBlocks.VILE_MELON_BLOCK.get(), createItemProperties())); //decoration blocks public static final RegistryObject FLESH_TENTACLE = ITEMS.register("flesh_tentacle", () -> new BlockItem(ModBlocks.FLESH_TENTACLE.get(), createItemProperties())); @@ -109,7 +109,7 @@ public final class ModItems { public static final RegistryObject FLESH_BLOCK = ITEMS.register("flesh_block", () -> new BlockItem(ModBlocks.FLESH_BLOCK.get(), createItemProperties())); public static final RegistryObject FLESH_BLOCK_SLAB = ITEMS.register("flesh_block_slab", () -> new BlockItem(ModBlocks.FLESH_BLOCK_SLAB.get(), createItemProperties())); public static final RegistryObject FLESH_BLOCK_STAIRS = ITEMS.register("flesh_block_stairs", () -> new BlockItem(ModBlocks.FLESH_BLOCK_STAIRS.get(), createItemProperties())); - public static final RegistryObject MUTATED_FLESH_BLOCK = ITEMS.register("mutated_flesh_block", () -> new BlockItem(ModBlocks.MUTATED_FLESH_BLOCK.get(), createItemProperties())); +// public static final RegistryObject MUTATED_FLESH_BLOCK = ITEMS.register("mutated_flesh_block", () -> new BlockItem(ModBlocks.MUTATED_FLESH_BLOCK.get(), createItemProperties())); public static final RegistryObject NECROTIC_FLESH_BLOCK = ITEMS.register("necrotic_flesh_block", () -> new BlockItem(ModBlocks.NECROTIC_FLESH_BLOCK.get(), createItemProperties())); //bio-construct blocks diff --git a/src/main/java/com/github/elenterius/biomancy/init/ModRecipes.java b/src/main/java/com/github/elenterius/biomancy/init/ModRecipes.java index d27fda136..28f763170 100644 --- a/src/main/java/com/github/elenterius/biomancy/init/ModRecipes.java +++ b/src/main/java/com/github/elenterius/biomancy/init/ModRecipes.java @@ -33,10 +33,10 @@ public final class ModRecipes { public static final RegistryObject> DECOMPOSING_SERIALIZER = RECIPE_SERIALIZERS.register("decomposing", DecomposerRecipe.Serializer::new); public static final RegistryObject> EVOLUTION_POOL_SERIALIZER = RECIPE_SERIALIZERS.register("evolution_pool", EvolutionPoolRecipe.Serializer::new); - public static final IRecipeType CHEWER_RECIPE_TYPE = createRecipeType("chewing"); - public static final IRecipeType DIGESTER_RECIPE_TYPE = createRecipeType("digesting"); - public static final IRecipeType DECOMPOSING_RECIPE_TYPE = createRecipeType("decomposing"); - public static final IRecipeType EVOLUTION_POOL_RECIPE_TYPE = createRecipeType("evolution_pool"); + public static final BioMechanicalRecipeType CHEWER_RECIPE_TYPE = createRecipeType("chewing"); + public static final BioMechanicalRecipeType DIGESTER_RECIPE_TYPE = createRecipeType("digesting"); + public static final BioMechanicalRecipeType DECOMPOSING_RECIPE_TYPE = createRecipeType("decomposing"); + public static final BioMechanicalRecipeType EVOLUTION_POOL_RECIPE_TYPE = createRecipeType("evolution_pool"); public static final ImmutableSet>> RECIPE_TYPES = ImmutableSet.of(CHEWER_RECIPE_TYPE, DIGESTER_RECIPE_TYPE, DECOMPOSING_RECIPE_TYPE, EVOLUTION_POOL_RECIPE_TYPE); public static final ItemPredicate ANY_MEATLESS_FOOD_ITEM_PREDICATE = new ItemPredicate() { @@ -69,13 +69,8 @@ public static void registerRecipeTypes() { Registry.register(Registry.RECIPE_TYPE, BiomancyMod.createRL("evolution_pool"), EVOLUTION_POOL_RECIPE_TYPE); } - private static > IRecipeType createRecipeType(String name) { - return new IRecipeType() { - @Override - public String toString() { - return name; - } - }; + private static BioMechanicalRecipeType createRecipeType(String name) { + return new BioMechanicalRecipeType<>(name); } } diff --git a/src/main/java/com/github/elenterius/biomancy/integration/jei/DecomposerRecipeCategory.java b/src/main/java/com/github/elenterius/biomancy/integration/jei/DecomposerRecipeCategory.java index cb88aac36..013ce0475 100644 --- a/src/main/java/com/github/elenterius/biomancy/integration/jei/DecomposerRecipeCategory.java +++ b/src/main/java/com/github/elenterius/biomancy/integration/jei/DecomposerRecipeCategory.java @@ -115,7 +115,7 @@ public void setRecipe(IRecipeLayout layout, DecomposerRecipe recipe, IIngredient @Override public void draw(DecomposerRecipe recipe, MatrixStack matrixStack, double mouseX, double mouseY) { - int ticks = recipe.getDecomposingTime(); + int ticks = recipe.getCraftingTime(); if (ticks > 0) { int seconds = ticks / 20; TranslationTextComponent timeString = new TranslationTextComponent("gui.jei.category.smelting.time.seconds", seconds); diff --git a/src/main/java/com/github/elenterius/biomancy/inventory/ChewerContainer.java b/src/main/java/com/github/elenterius/biomancy/inventory/ChewerContainer.java index 95dcfb4e9..f283d4b85 100644 --- a/src/main/java/com/github/elenterius/biomancy/inventory/ChewerContainer.java +++ b/src/main/java/com/github/elenterius/biomancy/inventory/ChewerContainer.java @@ -4,6 +4,7 @@ import com.github.elenterius.biomancy.init.ModContainerTypes; import com.github.elenterius.biomancy.tileentity.ChewerTileEntity; import com.github.elenterius.biomancy.tileentity.state.ChewerStateData; +import com.github.elenterius.biomancy.util.BiofuelUtil; import com.github.elenterius.biomancy.util.TextUtil; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; @@ -19,13 +20,13 @@ public class ChewerContainer extends Container { - protected final SimpleInvContents fuelContents; + protected final FuelInvContents fuelContents; protected final SimpleInvContents inputContents; protected final SimpleInvContents outputContents; private final ChewerStateData stateData; private final World world; - private ChewerContainer(int screenId, PlayerInventory playerInventory, SimpleInvContents fuelContents, SimpleInvContents inputContents, SimpleInvContents outputContents, ChewerStateData stateData) { + private ChewerContainer(int screenId, PlayerInventory playerInventory, FuelInvContents fuelContents, SimpleInvContents inputContents, SimpleInvContents outputContents, ChewerStateData stateData) { super(ModContainerTypes.CHEWER.get(), screenId); this.fuelContents = fuelContents; this.inputContents = inputContents; @@ -63,7 +64,7 @@ private ChewerContainer(int screenId, PlayerInventory playerInventory, SimpleInv addSlot(new Slot(fuelContents, 0, posX, posY) { @Override public boolean isItemValid(ItemStack stack) { - return ChewerTileEntity.isItemValidFuel(stack); + return BiofuelUtil.isItemValidFuel(stack); } }); @@ -72,12 +73,12 @@ public boolean isItemValid(ItemStack stack) { addSlot(new OutputSlot(outputContents, 0, 107, 26)); } - public static ChewerContainer createServerContainer(int screenId, PlayerInventory playerInventory, SimpleInvContents fuelContents, SimpleInvContents inputContents, SimpleInvContents outputContents, ChewerStateData stateData) { + public static ChewerContainer createServerContainer(int screenId, PlayerInventory playerInventory, FuelInvContents fuelContents, SimpleInvContents inputContents, SimpleInvContents outputContents, ChewerStateData stateData) { return new ChewerContainer(screenId, playerInventory, fuelContents, inputContents, outputContents, stateData); } public static ChewerContainer createClientContainer(int screenId, PlayerInventory playerInventory, PacketBuffer extraData) { - SimpleInvContents fuelContents = SimpleInvContents.createClientContents(ChewerTileEntity.FUEL_SLOTS_COUNT); + FuelInvContents fuelContents = FuelInvContents.createClientContents(ChewerTileEntity.FUEL_SLOTS_COUNT); SimpleInvContents inputContents = SimpleInvContents.createClientContents(ChewerTileEntity.INPUT_SLOTS_COUNT); SimpleInvContents outputContents = SimpleInvContents.createClientContents(ChewerTileEntity.OUTPUT_SLOTS_COUNT); ChewerStateData stateData = new ChewerStateData(); @@ -95,6 +96,10 @@ public float getCraftingProgressNormalized() { return MathHelper.clamp(stateData.timeElapsed / (float) stateData.timeForCompletion, 0f, 1f); } + public int getFuel() { + return stateData.fuel; + } + public float getFuelNormalized() { return MathHelper.clamp(stateData.fuel / (float) ChewerTileEntity.MAX_FUEL, 0f, 1f); } @@ -132,10 +137,10 @@ public ItemStack transferStackInSlot(PlayerEntity playerIn, int sourceSlotIndex) case PLAYER_HOTBAR: case PLAYER_MAIN_INVENTORY: - if (ChewerTileEntity.getRecipeForItem(world, sourceStack).isPresent()) { + if (ChewerTileEntity.RECIPE_TYPE.getRecipeForItem(world, sourceStack).isPresent()) { successfulTransfer = mergeInto(SlotZone.INPUT_ZONE, sourceStack, false); } - if (!successfulTransfer && ChewerTileEntity.isItemValidFuel(sourceStack)) { + if (!successfulTransfer && BiofuelUtil.isItemValidFuel(sourceStack)) { successfulTransfer = mergeInto(SlotZone.FUEL_ZONE, sourceStack, true); } if (!successfulTransfer) { diff --git a/src/main/java/com/github/elenterius/biomancy/inventory/DecomposerContainer.java b/src/main/java/com/github/elenterius/biomancy/inventory/DecomposerContainer.java index b390599ef..70134d719 100644 --- a/src/main/java/com/github/elenterius/biomancy/inventory/DecomposerContainer.java +++ b/src/main/java/com/github/elenterius/biomancy/inventory/DecomposerContainer.java @@ -4,6 +4,7 @@ import com.github.elenterius.biomancy.init.ModContainerTypes; import com.github.elenterius.biomancy.tileentity.DecomposerTileEntity; import com.github.elenterius.biomancy.tileentity.state.DecomposerStateData; +import com.github.elenterius.biomancy.util.BiofuelUtil; import com.github.elenterius.biomancy.util.TextUtil; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; @@ -19,13 +20,13 @@ public class DecomposerContainer extends Container { - protected final SimpleInvContents fuelContents; + protected final FuelInvContents fuelContents; protected final SimpleInvContents inputContents; protected final SimpleInvContents outputContents; private final DecomposerStateData decomposerState; private final World world; - private DecomposerContainer(int screenId, PlayerInventory playerInventory, SimpleInvContents fuelContents, SimpleInvContents inputContents, SimpleInvContents outputContents, DecomposerStateData decomposerState) { + private DecomposerContainer(int screenId, PlayerInventory playerInventory, FuelInvContents fuelContents, SimpleInvContents inputContents, SimpleInvContents outputContents, DecomposerStateData decomposerState) { super(ModContainerTypes.DECOMPOSER.get(), screenId); this.fuelContents = fuelContents; this.inputContents = inputContents; @@ -63,7 +64,7 @@ private DecomposerContainer(int screenId, PlayerInventory playerInventory, Simpl addSlot(new Slot(fuelContents, 0, posX, posY) { @Override public boolean isItemValid(ItemStack stack) { - return DecomposerTileEntity.isItemValidFuel(stack); + return BiofuelUtil.isItemValidFuel(stack); } }); @@ -82,12 +83,12 @@ public boolean isItemValid(ItemStack stack) { addSlot(new OutputSlot(outputContents, 3, outputPosX + 18, posY + 18)); } - public static DecomposerContainer createServerContainer(int screenId, PlayerInventory playerInventory, SimpleInvContents fuelContents, SimpleInvContents inputContents, SimpleInvContents outputContents, DecomposerStateData decomposerState) { + public static DecomposerContainer createServerContainer(int screenId, PlayerInventory playerInventory, FuelInvContents fuelContents, SimpleInvContents inputContents, SimpleInvContents outputContents, DecomposerStateData decomposerState) { return new DecomposerContainer(screenId, playerInventory, fuelContents, inputContents, outputContents, decomposerState); } public static DecomposerContainer createClientContainer(int screenId, PlayerInventory playerInventory, PacketBuffer extraData) { - SimpleInvContents fuelContents = SimpleInvContents.createClientContents(DecomposerTileEntity.FUEL_SLOTS_COUNT); + FuelInvContents fuelContents = FuelInvContents.createClientContents(DecomposerTileEntity.FUEL_SLOTS_COUNT); SimpleInvContents inputContents = SimpleInvContents.createClientContents(DecomposerTileEntity.INPUT_SLOTS_COUNT); SimpleInvContents outputContents = SimpleInvContents.createClientContents(DecomposerTileEntity.OUTPUT_SLOTS_COUNT); DecomposerStateData decomposerState = new DecomposerStateData(); @@ -105,8 +106,12 @@ public float getCraftingProgressNormalized() { return MathHelper.clamp(decomposerState.timeElapsed / (float) decomposerState.timeForCompletion, 0f, 1f); } + public int getFuel() { + return decomposerState.fuel; + } + public float getFuelNormalized() { - return MathHelper.clamp(decomposerState.mainFuel / (float) DecomposerTileEntity.MAX_FUEL, 0f, 1f); + return MathHelper.clamp(decomposerState.fuel / (float) DecomposerTileEntity.MAX_FUEL, 0f, 1f); } public String getFuelTranslationKey() { @@ -146,10 +151,10 @@ public ItemStack transferStackInSlot(PlayerEntity playerIn, int sourceSlotIndex) case PLAYER_HOTBAR: case PLAYER_MAIN_INVENTORY: - if (DecomposerTileEntity.getRecipeForItem(world, sourceStack).isPresent()) { + if (DecomposerTileEntity.RECIPE_TYPE.getRecipeForItem(world, sourceStack).isPresent()) { successfulTransfer = mergeInto(SlotZone.INPUT_ZONE, sourceStack, false); } - if (!successfulTransfer && DecomposerTileEntity.isItemValidFuel(sourceStack)) { + if (!successfulTransfer && BiofuelUtil.isItemValidFuel(sourceStack)) { successfulTransfer = mergeInto(SlotZone.FUEL_ZONE, sourceStack, true); } if (!successfulTransfer) { diff --git a/src/main/java/com/github/elenterius/biomancy/inventory/DigesterContainer.java b/src/main/java/com/github/elenterius/biomancy/inventory/DigesterContainer.java index 9ef7ce1c5..61f0752ca 100644 --- a/src/main/java/com/github/elenterius/biomancy/inventory/DigesterContainer.java +++ b/src/main/java/com/github/elenterius/biomancy/inventory/DigesterContainer.java @@ -62,7 +62,7 @@ private DigesterContainer(int screenId, PlayerInventory playerInventory, SimpleI addSlot(new Slot(fuelContents, 0, 17, 17) { @Override public boolean isItemValid(ItemStack stack) { - return DigesterTileEntity.isItemValidFuel(stack); + return DigesterTileEntity.VALID_FUEL_ITEM.test(stack); } }); @@ -98,6 +98,10 @@ public float getCraftingProgressNormalized() { return MathHelper.clamp(stateData.timeElapsed / (float) stateData.timeForCompletion, 0f, 1f); } + public int getFuel() { + return stateData.fuel.getFluidAmount(); + } + public float getFuelNormalized() { return MathHelper.clamp(stateData.fuel.getFluidAmount() / (float) stateData.fuel.getCapacity(), 0f, 1f); } @@ -137,10 +141,10 @@ public ItemStack transferStackInSlot(PlayerEntity playerIn, int sourceSlotIndex) case PLAYER_HOTBAR: case PLAYER_MAIN_INVENTORY: - if (DigesterTileEntity.getRecipeForItem(world, sourceStack).isPresent()) { + if (DigesterTileEntity.RECIPE_TYPE.getRecipeForItem(world, sourceStack).isPresent()) { successfulTransfer = mergeInto(SlotZone.INPUT_ZONE, sourceStack, false); } - if (!successfulTransfer && DigesterTileEntity.isItemValidFuel(sourceStack)) { + if (!successfulTransfer && DigesterTileEntity.VALID_FUEL_ITEM.test(sourceStack)) { successfulTransfer = mergeInto(SlotZone.FUEL_ZONE, sourceStack, true); } if (!successfulTransfer) { diff --git a/src/main/java/com/github/elenterius/biomancy/inventory/EvolutionPoolContainer.java b/src/main/java/com/github/elenterius/biomancy/inventory/EvolutionPoolContainer.java index 17d3e3a3e..0e44b7c70 100644 --- a/src/main/java/com/github/elenterius/biomancy/inventory/EvolutionPoolContainer.java +++ b/src/main/java/com/github/elenterius/biomancy/inventory/EvolutionPoolContainer.java @@ -63,7 +63,7 @@ private EvolutionPoolContainer(int screenId, PlayerInventory playerInventory, Si addSlot(new Slot(fuelContents, 0, posX, posY) { @Override public boolean isItemValid(ItemStack stack) { - return EvolutionPoolTileEntity.isItemValidFuel(stack); + return EvolutionPoolTileEntity.VALID_FUEL_ITEM.test(stack); } }); @@ -101,6 +101,10 @@ public float getCraftingProgressNormalized() { return MathHelper.clamp(stateData.timeElapsed / (float) stateData.timeForCompletion, 0f, 1f); } + public int getFuel() { + return stateData.fuel; + } + public float getFuelNormalized() { return MathHelper.clamp(stateData.fuel / (float) EvolutionPoolTileEntity.MAX_FUEL, 0f, 1f); } @@ -134,10 +138,10 @@ public ItemStack transferStackInSlot(PlayerEntity playerIn, int sourceSlotIndex) case PLAYER_HOTBAR: case PLAYER_MAIN_INVENTORY: - if (EvolutionPoolTileEntity.getRecipeForItem(world, sourceStack).isPresent()) { + if (EvolutionPoolTileEntity.RECIPE_TYPE.getRecipeForItem(world, sourceStack).isPresent()) { successfulTransfer = mergeInto(SlotZone.INPUT_ZONE, sourceStack, false); } - if (!successfulTransfer && EvolutionPoolTileEntity.isItemValidFuel(sourceStack)) { + if (!successfulTransfer && EvolutionPoolTileEntity.VALID_FUEL_ITEM.test(sourceStack)) { successfulTransfer = mergeInto(SlotZone.FUEL_ZONE, sourceStack, true); } if (!successfulTransfer) { diff --git a/src/main/java/com/github/elenterius/biomancy/inventory/FuelInvContents.java b/src/main/java/com/github/elenterius/biomancy/inventory/FuelInvContents.java new file mode 100644 index 000000000..6ce61c20e --- /dev/null +++ b/src/main/java/com/github/elenterius/biomancy/inventory/FuelInvContents.java @@ -0,0 +1,31 @@ +package com.github.elenterius.biomancy.inventory; + +import com.github.elenterius.biomancy.capabilities.InputFilterItemStackHandler; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.items.IItemHandler; +import net.minecraftforge.items.ItemStackHandler; + +import java.util.function.Predicate; + +public class FuelInvContents extends SimpleInvContents { + + FuelInvContents(int slotAmount) { + super(slotAmount); + } + + FuelInvContents(ItemStackHandler itemStackHandler, LazyOptional optionalItemStackHandler, Predicate canPlayerAccessInventory, Notify markDirtyNotifier) { + super(itemStackHandler, optionalItemStackHandler, canPlayerAccessInventory, markDirtyNotifier); + } + + public static FuelInvContents createServerContents(int slotAmount, Predicate isItemValid, Predicate canPlayerAccessInventory, Notify markDirtyNotifier) { + ItemStackHandler itemStackHandler = new ItemStackHandler(slotAmount); + return new FuelInvContents(itemStackHandler, LazyOptional.of(() -> new InputFilterItemStackHandler(itemStackHandler, isItemValid)), canPlayerAccessInventory, markDirtyNotifier); + } + + public static FuelInvContents createClientContents(int slotAmount) { + return new FuelInvContents(slotAmount); + } + +} diff --git a/src/main/java/com/github/elenterius/biomancy/inventory/SimpleInvContents.java b/src/main/java/com/github/elenterius/biomancy/inventory/SimpleInvContents.java index 87e256678..3549639aa 100644 --- a/src/main/java/com/github/elenterius/biomancy/inventory/SimpleInvContents.java +++ b/src/main/java/com/github/elenterius/biomancy/inventory/SimpleInvContents.java @@ -32,6 +32,13 @@ public class SimpleInvContents implements IInventory { optionalItemStackHandler = LazyOptional.of(() -> itemStackHandler); } + SimpleInvContents(ItemStackHandler itemStackHandlerIn, LazyOptional optionalItemStackHandlerIn, Predicate canPlayerAccessInventory, Notify markDirtyNotifier) { + itemStackHandler = itemStackHandlerIn; + optionalItemStackHandler = optionalItemStackHandlerIn; + this.canPlayerAccessInventory = canPlayerAccessInventory; + this.markDirtyNotifier = markDirtyNotifier; + } + SimpleInvContents(int slotAmount, ISHandlerType handlerType) { itemStackHandler = new ItemStackHandler(slotAmount); switch (handlerType) { diff --git a/src/main/java/com/github/elenterius/biomancy/item/InjectionDeviceItem.java b/src/main/java/com/github/elenterius/biomancy/item/InjectionDeviceItem.java index 8c32cea4d..22ec700bf 100644 --- a/src/main/java/com/github/elenterius/biomancy/item/InjectionDeviceItem.java +++ b/src/main/java/com/github/elenterius/biomancy/item/InjectionDeviceItem.java @@ -40,10 +40,9 @@ public InjectionDeviceItem(Properties properties) { @Override public void addInformation(ItemStack stack, @Nullable World worldIn, List tooltip, ITooltipFlag flagIn) { tooltip.add(ClientTextUtil.getItemInfoTooltip(this).setStyle(ClientTextUtil.LORE_STYLE)); - CompoundNBT nbt = stack.getOrCreateTag(); - Reagent reagent = Reagent.deserialize(nbt); + Reagent reagent = getReagent(stack); if (reagent != null) { - byte amount = nbt.getByte(NBT_KEY_REAGENT_AMOUNT); + byte amount = getReagentAmount(stack); tooltip.add(new StringTextComponent(String.format("Amount: %d/4", amount)).mergeStyle(TextFormatting.GRAY)); reagent.addInfoToTooltip(stack, worldIn, tooltip, flagIn); } @@ -54,7 +53,7 @@ public void addInformation(ItemStack stack, @Nullable World worldIn, List onItemRightClick(World worldIn, PlayerEntity play ItemStack offhandStack = playerIn.getHeldItemOffhand(); if (!offhandStack.isEmpty()) { if (offhandStack.getItem() == ModItems.REAGENT.get()) { - if (addReagent(offhandStack, heldStack)) { + if (addReagent(offhandStack, heldStack, playerIn)) { playSFX(worldIn, playerIn, SoundEvents.ITEM_ARMOR_EQUIP_GENERIC); return ActionResult.resultFail(heldStack); } @@ -112,7 +116,7 @@ private boolean extractReagent(ItemStack containerStack, ItemStack gunStack, Pla byte amount = getReagentAmount(gunStack); if (amount < 1) return false; - Reagent storedReagent = Reagent.deserialize(gunStack.getOrCreateTag()); + Reagent storedReagent = getReagent(gunStack); if (storedReagent != null) { ItemStack stack = new ItemStack(ModItems.REAGENT.get()); Reagent.serialize(storedReagent, stack.getOrCreateTag()); @@ -128,19 +132,24 @@ private boolean extractReagent(ItemStack containerStack, ItemStack gunStack, Pla return false; } - private boolean addReagent(ItemStack ammoStack, ItemStack gunStack) { + private boolean addReagent(ItemStack ammoStack, ItemStack gunStack, PlayerEntity playerIn) { byte amount = getReagentAmount(gunStack); if (amount >= getMaxReagentAmount()) return false; - Reagent reagentIn = Reagent.deserialize(ammoStack.getOrCreateTag()); - Reagent storedReagent = Reagent.deserialize(gunStack.getOrCreateTag()); + Reagent reagentIn = getReagent(ammoStack); + Reagent storedReagent = getReagent(gunStack); if (reagentIn != null) { if (storedReagent == null) { - CompoundNBT nbt = gunStack.getOrCreateTag(); - Reagent.serialize(reagentIn, nbt); - Reagent.copyAdditionalData(ammoStack.getOrCreateTag(), nbt); + CompoundNBT gunNbt = gunStack.getOrCreateTag(); + Reagent.serialize(reagentIn, gunNbt); + Reagent.copyAdditionalData(ammoStack.getOrCreateTag(), gunNbt); setReagentAmount(gunStack, (byte) 1); ammoStack.grow(-1); + + ItemStack stack = new ItemStack(ModItems.GLASS_VIAL.get()); + if (!playerIn.addItemStackToInventory(stack)) { + playerIn.entityDropItem(stack); + } return true; } else { @@ -153,6 +162,11 @@ private boolean addReagent(ItemStack ammoStack, ItemStack gunStack) { } setReagentAmount(gunStack, (byte) (amount + 1)); ammoStack.grow(-1); + + ItemStack stack = new ItemStack(ModItems.GLASS_VIAL.get()); + if (!playerIn.addItemStackToInventory(stack)) { + playerIn.entityDropItem(stack); + } return true; } } @@ -167,13 +181,13 @@ public ActionResultType onItemUse(ItemUseContext context) { if (context.getPlayer() != null && !context.getPlayer().canPlayerEdit(context.getPos().offset(context.getFace()), context.getFace(), stack)) return ActionResultType.FAIL; - Reagent reagent = Reagent.deserialize(stack.getOrCreateTag()); + Reagent reagent = getReagent(stack); if (reagent != null) { World world = context.getWorld(); boolean success = reagent.affectBlock(stack.getOrCreateTag().getCompound(Reagent.NBT_KEY_DATA), context.getPlayer(), world, context.getPos(), context.getFace()); if (success) { if (!world.isRemote) { - addReagentAmount(stack, (byte) -1); + if (context.getPlayer() == null || !context.getPlayer().isCreative()) addReagentAmount(stack, (byte) -1); world.playEvent(Constants.WorldEvents.BONEMEAL_PARTICLES, context.getPos().up(), 0); playSFX(world, context.getPlayer(), ModSoundEvents.INJECT.get()); } @@ -189,12 +203,13 @@ public ActionResultType onItemUse(ItemUseContext context) { @Override public ActionResultType itemInteractionForEntity(ItemStack stack, PlayerEntity player, LivingEntity target, Hand hand) { - Reagent reagent = Reagent.deserialize(stack.getOrCreateTag()); + Reagent reagent = getReagent(stack); if (reagent != null) { if (reagent.affectEntity(stack.getOrCreateTag().getCompound(Reagent.NBT_KEY_DATA), player, target)) { if (!target.world.isRemote) { if (reagent.isAttributeModifier()) reagent.applyAttributesModifiersToEntity(target); - addReagentAmount(stack, (byte) -1); + if (!player.isCreative()) addReagentAmount(stack, (byte) -1); + target.world.playEvent(Constants.WorldEvents.SPAWN_EXPLOSION_PARTICLE, target.getPosition(), 0); playSFX(target.world, player, ModSoundEvents.INJECT.get()); } @@ -204,7 +219,7 @@ public ActionResultType itemInteractionForEntity(ItemStack stack, PlayerEntity p if (player.world.isRemote) playSFX(player.world, player, SoundEvents.BLOCK_DISPENSER_FAIL); return ActionResultType.FAIL; } - else { //it's essentially empty + else { //the device is empty if (!target.world.isRemote) { CompoundNBT reagentNbt = BloodSampleReagent.getBloodSampleFromEntity(player, target); if (reagentNbt != null && !reagentNbt.isEmpty()) { @@ -228,15 +243,36 @@ public ActionResultType itemInteractionForEntity(ItemStack stack, PlayerEntity p } public boolean interactWithPlayerSelf(ItemStack stack, PlayerEntity player) { - Reagent reagent = Reagent.deserialize(stack.getOrCreateTag()); + Reagent reagent = getReagent(stack); if (reagent != null) { boolean success = reagent.affectPlayerSelf(stack.getOrCreateTag().getCompound(Reagent.NBT_KEY_DATA), player); - if (!player.world.isRemote && success && reagent.isAttributeModifier()) { - reagent.applyAttributesModifiersToEntity(player); + if (success && !player.world.isRemote) { + if (reagent.isAttributeModifier()) reagent.applyAttributesModifiersToEntity(player); + if (!player.isCreative()) addReagentAmount(stack, (byte) -1); } return success; } - return false; + else { //the device is empty + if (!player.world.isRemote) { + CompoundNBT reagentNbt = BloodSampleReagent.getBloodSampleFromEntityUnchecked(player); + if (reagentNbt != null && !reagentNbt.isEmpty()) { + CompoundNBT nbt = stack.getOrCreateTag(); + Reagent.serialize(ModReagents.BLOOD_SAMPLE.get(), nbt); + nbt.put(Reagent.NBT_KEY_DATA, reagentNbt); + setReagentAmount(stack, getMaxReagentAmount()); + + playSFX(player.world, player, ModSoundEvents.INJECT.get()); + player.attackEntityFrom(DamageSource.causeBeeStingDamage(player), 0.5f); + + if (player.isCreative()) { + player.setHeldItem(player.getActiveHand(), stack); //fix for creative mode (normally the stack is not modified in creative) + } + return true; + } + else return false; + } + else return true; + } } @OnlyIn(Dist.CLIENT) diff --git a/src/main/java/com/github/elenterius/biomancy/item/weapon/ClawWeaponItem.java b/src/main/java/com/github/elenterius/biomancy/item/weapon/ClawWeaponItem.java index 26db79e71..9bd0cb796 100644 --- a/src/main/java/com/github/elenterius/biomancy/item/weapon/ClawWeaponItem.java +++ b/src/main/java/com/github/elenterius/biomancy/item/weapon/ClawWeaponItem.java @@ -37,7 +37,7 @@ public ClawWeaponItem(IItemTier tier, int attackDamageIn, float attackSpeedIn, P protected Multimap createAttributeModifiers() { ImmutableMultimap.Builder builder = ImmutableMultimap.builder(); - Multimap swordAttributes = ((SwordItemMixinAccessor) this).getAttributeModifiers(); + Multimap swordAttributes = ((SwordItemMixinAccessor) this).biomancy_attributeModifiers(); swordAttributes.forEach(builder::put); addAdditionalAttributeModifiers(builder); return builder.build(); diff --git a/src/main/java/com/github/elenterius/biomancy/item/weapon/LongRangeClawItem.java b/src/main/java/com/github/elenterius/biomancy/item/weapon/LongRangeClawItem.java index 023f4bb75..2968dc84e 100644 --- a/src/main/java/com/github/elenterius/biomancy/item/weapon/LongRangeClawItem.java +++ b/src/main/java/com/github/elenterius/biomancy/item/weapon/LongRangeClawItem.java @@ -10,7 +10,6 @@ import com.google.common.collect.Multimap; import net.minecraft.block.BlockState; import net.minecraft.client.util.ITooltipFlag; -import net.minecraft.enchantment.Enchantments; import net.minecraft.entity.Entity; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.ai.attributes.Attribute; @@ -20,10 +19,8 @@ import net.minecraft.inventory.EquipmentSlotType; import net.minecraft.item.IItemTier; import net.minecraft.item.Item; -import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundNBT; -import net.minecraft.util.NonNullList; import net.minecraft.util.SoundEvents; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockRayTraceResult; @@ -86,15 +83,6 @@ public ITextComponent getHighlightTip(ItemStack stack, ITextComponent displayNam return displayName; } - @Override - public void fillItemGroup(ItemGroup group, NonNullList items) { - if (isInGroup(group)) { - ItemStack stack = new ItemStack(this); - stack.addEnchantment(Enchantments.SWEEPING, 3); - items.add(stack); - } - } - protected Multimap createAttributeModifiersV2() { ImmutableMultimap.Builder builder = ImmutableMultimap.builder(); Multimap clawAttributes = lazyAttributeModifiers.get(); diff --git a/src/main/java/com/github/elenterius/biomancy/item/weapon/PoleWeaponItem.java b/src/main/java/com/github/elenterius/biomancy/item/weapon/PoleWeaponItem.java index a53d98808..4ed4f1a8f 100644 --- a/src/main/java/com/github/elenterius/biomancy/item/weapon/PoleWeaponItem.java +++ b/src/main/java/com/github/elenterius/biomancy/item/weapon/PoleWeaponItem.java @@ -25,7 +25,7 @@ public PoleWeaponItem(IItemTier tier, int attackDamageIn, float attackSpeedIn, P protected Multimap createAttributeModifiers() { ImmutableMultimap.Builder builder = ImmutableMultimap.builder(); - Multimap swordAttributes = ((SwordItemMixinAccessor) this).getAttributeModifiers(); + Multimap swordAttributes = ((SwordItemMixinAccessor) this).biomancy_attributeModifiers(); swordAttributes.forEach(builder::put); addAdditionalAttributeModifiers(builder); return builder.build(); diff --git a/src/main/java/com/github/elenterius/biomancy/item/weapon/shootable/ProjectileWeaponItem.java b/src/main/java/com/github/elenterius/biomancy/item/weapon/shootable/ProjectileWeaponItem.java index 34e005b6d..eeaad3ad7 100644 --- a/src/main/java/com/github/elenterius/biomancy/item/weapon/shootable/ProjectileWeaponItem.java +++ b/src/main/java/com/github/elenterius/biomancy/item/weapon/shootable/ProjectileWeaponItem.java @@ -21,6 +21,7 @@ import net.minecraft.nbt.CompoundNBT; import net.minecraft.util.*; import net.minecraft.util.math.MathHelper; +import net.minecraft.util.text.IFormattableTextComponent; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.StringTextComponent; import net.minecraft.util.text.TextFormatting; @@ -68,16 +69,21 @@ public void addInformation(ItemStack stack, @Nullable World worldIn, List onClientKeyPress(ItemStack stack, ClientWorld world, PlayerEntity player, byte flags) { @@ -110,7 +116,7 @@ public int getUseDuration(ItemStack stack) { @Override public UseAction getUseAction(ItemStack stack) { - return UseAction.BOW; + return UseAction.NONE; } @Override diff --git a/src/main/java/com/github/elenterius/biomancy/mixin/ArmorStandEntityAccessor.java b/src/main/java/com/github/elenterius/biomancy/mixin/ArmorStandEntityAccessor.java index bb1178e48..a2e16e848 100644 --- a/src/main/java/com/github/elenterius/biomancy/mixin/ArmorStandEntityAccessor.java +++ b/src/main/java/com/github/elenterius/biomancy/mixin/ArmorStandEntityAccessor.java @@ -7,7 +7,7 @@ @Mixin(ArmorStandEntity.class) public interface ArmorStandEntityAccessor { - @Invoker - void callSetSmall(boolean flag); + @Invoker("setSmall") + void biomancy_setSmall(boolean flag); } diff --git a/src/main/java/com/github/elenterius/biomancy/mixin/CauldronBlockMixin.java b/src/main/java/com/github/elenterius/biomancy/mixin/CauldronBlockMixin.java new file mode 100644 index 000000000..3b93fbc9a --- /dev/null +++ b/src/main/java/com/github/elenterius/biomancy/mixin/CauldronBlockMixin.java @@ -0,0 +1,53 @@ +package com.github.elenterius.biomancy.mixin; + +import com.github.elenterius.biomancy.block.MeatsoupCauldronBlock; +import com.github.elenterius.biomancy.init.ModBlocks; +import com.github.elenterius.biomancy.init.ModTags; +import net.minecraft.block.BlockState; +import net.minecraft.block.CauldronBlock; +import net.minecraft.entity.Entity; +import net.minecraft.entity.item.ItemEntity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.state.IntegerProperty; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.SoundEvents; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraftforge.common.util.Constants; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(CauldronBlock.class) +public abstract class CauldronBlockMixin { + + @Shadow + @Final + public static IntegerProperty LEVEL; + + @Inject(method = "onEntityCollision", at = @At("HEAD"), cancellable = true) + protected void biomancy_onEntityCollision(BlockState state, World worldIn, BlockPos pos, Entity entityIn, CallbackInfo ci) { + if (!worldIn.isRemote && entityIn instanceof ItemEntity) { + int waterLevel = state.get(LEVEL); + if (waterLevel == 0) { + ItemStack stack = ((ItemEntity) entityIn).getItem(); + Item item = stack.getItem(); + if (item.isIn(ModTags.Items.RAW_MEATS)) { + int amount = Math.min(stack.getCount(), 5); + ((ItemEntity) entityIn).getItem().grow(-amount); + + BlockState meatState = ModBlocks.MEATSOUP_CAULDRON.get().getDefaultState().with(MeatsoupCauldronBlock.LEVEL, amount); + worldIn.setBlockState(pos, meatState, Constants.BlockFlags.BLOCK_UPDATE); + worldIn.playSound(null, pos, SoundEvents.ENTITY_SLIME_SQUISH_SMALL, SoundCategory.BLOCKS, 1f, 0.5f); + + ci.cancel(); + } + } + } + } + +} diff --git a/src/main/java/com/github/elenterius/biomancy/mixin/RecipeManagerMixinAccessor.java b/src/main/java/com/github/elenterius/biomancy/mixin/RecipeManagerMixinAccessor.java index 21b0f181f..919fe429b 100644 --- a/src/main/java/com/github/elenterius/biomancy/mixin/RecipeManagerMixinAccessor.java +++ b/src/main/java/com/github/elenterius/biomancy/mixin/RecipeManagerMixinAccessor.java @@ -13,7 +13,7 @@ @Mixin(RecipeManager.class) public interface RecipeManagerMixinAccessor { - @Invoker - > Map> callGetRecipes(IRecipeType recipeTypeIn); + @Invoker("getRecipes") + > Map> biomancy_getRecipes(IRecipeType recipeTypeIn); } diff --git a/src/main/java/com/github/elenterius/biomancy/mixin/SlimeEntityAccessor.java b/src/main/java/com/github/elenterius/biomancy/mixin/SlimeEntityAccessor.java index 9ac4a551c..fb8c2c125 100644 --- a/src/main/java/com/github/elenterius/biomancy/mixin/SlimeEntityAccessor.java +++ b/src/main/java/com/github/elenterius/biomancy/mixin/SlimeEntityAccessor.java @@ -7,7 +7,7 @@ @Mixin(SlimeEntity.class) public interface SlimeEntityAccessor { - @Invoker - void callSetSlimeSize(int size, boolean resetHealth); + @Invoker("setSlimeSize") + void biomancy_setSlimeSize(int size, boolean resetHealth); } diff --git a/src/main/java/com/github/elenterius/biomancy/mixin/SwordItemMixinAccessor.java b/src/main/java/com/github/elenterius/biomancy/mixin/SwordItemMixinAccessor.java index 797ecf733..8a4424a3a 100644 --- a/src/main/java/com/github/elenterius/biomancy/mixin/SwordItemMixinAccessor.java +++ b/src/main/java/com/github/elenterius/biomancy/mixin/SwordItemMixinAccessor.java @@ -10,7 +10,7 @@ @Mixin(SwordItem.class) public interface SwordItemMixinAccessor { - @Accessor - Multimap getAttributeModifiers(); + @Accessor("attributeModifiers") + Multimap biomancy_attributeModifiers(); } diff --git a/src/main/java/com/github/elenterius/biomancy/mixin/ZombieVillagerEntityMixinAccessor.java b/src/main/java/com/github/elenterius/biomancy/mixin/ZombieVillagerEntityMixinAccessor.java new file mode 100644 index 000000000..11ade2dd2 --- /dev/null +++ b/src/main/java/com/github/elenterius/biomancy/mixin/ZombieVillagerEntityMixinAccessor.java @@ -0,0 +1,14 @@ +package com.github.elenterius.biomancy.mixin; + +import net.minecraft.entity.monster.ZombieVillagerEntity; +import net.minecraft.world.server.ServerWorld; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(ZombieVillagerEntity.class) +public interface ZombieVillagerEntityMixinAccessor { + + @Invoker("cureZombie") + void biomancy_cureZombie(ServerWorld world); + +} diff --git a/src/main/java/com/github/elenterius/biomancy/mixin/client/ItemStackMixinAccessor.java b/src/main/java/com/github/elenterius/biomancy/mixin/client/ClientItemStackMixinAccessor.java similarity index 52% rename from src/main/java/com/github/elenterius/biomancy/mixin/client/ItemStackMixinAccessor.java rename to src/main/java/com/github/elenterius/biomancy/mixin/client/ClientItemStackMixinAccessor.java index 779e4ebde..d220b45ec 100644 --- a/src/main/java/com/github/elenterius/biomancy/mixin/client/ItemStackMixinAccessor.java +++ b/src/main/java/com/github/elenterius/biomancy/mixin/client/ClientItemStackMixinAccessor.java @@ -5,14 +5,14 @@ import org.spongepowered.asm.mixin.gen.Invoker; @Mixin(ItemStack.class) -public interface ItemStackMixinAccessor { +public interface ClientItemStackMixinAccessor { // client side - @Invoker(value = "func_242393_J") - int getHideFlags(); + @Invoker("func_242393_J") + int biomancy_getHideFlags(); //client side - @Invoker(value = "func_242394_a") - static boolean isToolTipVisible(int hideFlags, ItemStack.TooltipDisplayFlags tooltipFlag) { + @Invoker("func_242394_a") + static boolean biomancy_isToolTipVisible(int hideFlags, ItemStack.TooltipDisplayFlags tooltipFlag) { return false; } } diff --git a/src/main/java/com/github/elenterius/biomancy/mixin/client/LivingRendererMixin.java b/src/main/java/com/github/elenterius/biomancy/mixin/client/LivingRendererMixin.java index f121893a8..b1980befc 100644 --- a/src/main/java/com/github/elenterius/biomancy/mixin/client/LivingRendererMixin.java +++ b/src/main/java/com/github/elenterius/biomancy/mixin/client/LivingRendererMixin.java @@ -1,10 +1,5 @@ package com.github.elenterius.biomancy.mixin.client; -import com.mojang.blaze3d.matrix.MatrixStack; -import com.mojang.blaze3d.vertex.IVertexBuilder; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.IRenderTypeBuffer; -import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.entity.EntityRenderer; import net.minecraft.client.renderer.entity.EntityRendererManager; import net.minecraft.client.renderer.entity.IEntityRenderer; @@ -12,29 +7,28 @@ import net.minecraft.client.renderer.entity.model.EntityModel; import net.minecraft.entity.LivingEntity; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.LocalCapture; @Mixin(LivingRenderer.class) public abstract class LivingRendererMixin> extends EntityRenderer implements IEntityRenderer { - @Shadow - protected M entityModel; +// @Shadow +// protected M entityModel; +// protected LivingRendererMixin(EntityRendererManager renderManager) { super(renderManager); } - @Inject(method = "render", locals = LocalCapture.CAPTURE_FAILSOFT, at = @At(value = "FIELD", ordinal = 5, shift = At.Shift.AFTER, - target = "Lnet/minecraft/client/renderer/entity/LivingRenderer;entityModel:Lnet/minecraft/client/renderer/entity/model/EntityModel;")) - protected void biomancy_onPostRenderModel(LivingEntity entityIn, float entityYaw, float partialTicks, MatrixStack matrixStackIn, IRenderTypeBuffer bufferIn, int packedLightIn, CallbackInfo ci, - boolean shouldSit, float f, float f1, float f2, float f6, float f7, float f8, float f5, Minecraft minecraft, boolean flag, boolean flag1, boolean flag2, - RenderType rendertype, IVertexBuilder ivertexbuilder, int i) { - // if the entity is invisible but visible to player then render the entity a second time - if (flag1) { - entityModel.render(matrixStackIn, ivertexbuilder, packedLightIn, i, 1.0F, 1.0F, 1.0F, 0.5F); // - } - } + //FIXME: Incompatible with Optifine. Removing this doesn't affect gameplay. + //TODO: Write more robust & better mixin. +// @Inject(method = "render", locals = LocalCapture.CAPTURE_FAILSOFT, at = @At(value = "FIELD", ordinal = 5, shift = At.Shift.AFTER, +// target = "Lnet/minecraft/client/renderer/entity/LivingRenderer;entityModel:Lnet/minecraft/client/renderer/entity/model/EntityModel;")) +// protected void biomancy_onPostRenderModel(LivingEntity entityIn, float entityYaw, float partialTicks, MatrixStack matrixStackIn, IRenderTypeBuffer bufferIn, int packedLightIn, CallbackInfo ci, +// boolean shouldSit, float f, float f1, float f2, float f6, float f7, float f8, float f5, Minecraft minecraft, boolean flag, boolean flag1, boolean flag2, +// RenderType rendertype, IVertexBuilder ivertexbuilder, int i) { +// // if the entity is invisible but visible to player then render the entity a second time +// if (flag1) { +// entityModel.render(matrixStackIn, ivertexbuilder, packedLightIn, i, 1.0F, 1.0F, 1.0F, 0.5F); // +// } +// } + } diff --git a/src/main/java/com/github/elenterius/biomancy/mixin/client/PlayerRendererMixin.java b/src/main/java/com/github/elenterius/biomancy/mixin/client/PlayerRendererMixin.java index 96d1655e2..171b95e83 100644 --- a/src/main/java/com/github/elenterius/biomancy/mixin/client/PlayerRendererMixin.java +++ b/src/main/java/com/github/elenterius/biomancy/mixin/client/PlayerRendererMixin.java @@ -6,9 +6,10 @@ @Mixin(PlayerRenderer.class) public abstract class PlayerRendererMixin { + //TODO: this will probably also break with optifine // @Inject(method = "func_241741_a_", cancellable = true, locals = LocalCapture.CAPTURE_FAILSOFT, at = @At(value = "FIELD", target = "Lnet/minecraft/client/renderer/entity/model/BipedModel$ArmPose;ITEM:Lnet/minecraft/client/renderer/entity/model/BipedModel$ArmPose;")) // private static void biomancy_onGetArmPose(AbstractClientPlayerEntity player, Hand hand, CallbackInfoReturnable cir, ItemStack itemstack) { -// if (!player.isSwingInProgress && itemstack.getItem() == ModItems.INFESTED_RIFLE.get() && ModItems.INFESTED_RIFLE.get().hasAmmo(itemstack)) { +// if (!player.isSwingInProgress && itemstack.getItem() instanceof ProjectileWeaponItem && ((ProjectileWeaponItem) itemstack.getItem()).hasAmmo(itemstack)) { // cir.setReturnValue(BipedModel.ArmPose.CROSSBOW_HOLD); // } // } diff --git a/src/main/java/com/github/elenterius/biomancy/reagent/BloodSampleReagent.java b/src/main/java/com/github/elenterius/biomancy/reagent/BloodSampleReagent.java index 4642f1931..98d6b9fba 100644 --- a/src/main/java/com/github/elenterius/biomancy/reagent/BloodSampleReagent.java +++ b/src/main/java/com/github/elenterius/biomancy/reagent/BloodSampleReagent.java @@ -35,27 +35,38 @@ private static boolean isNonBoss(LivingEntity target) { @Nullable public static CompoundNBT getBloodSampleFromEntity(PlayerEntity player, LivingEntity target) { boolean isValidEntity = target.isAlive() && (isNonBoss(target) || player.isCreative()); - if (isValidEntity) { - CompoundNBT nbt = new CompoundNBT(); - String typeId = target.getEntityString(); - if (typeId != null) { - nbt.putString("EntityTypeId", typeId); - nbt.putString("Name", target.getType().getTranslationKey()); - nbt.putBoolean("IsPlayer", target instanceof PlayerEntity); - nbt.putUniqueId("EntityUUID", target.getUniqueID()); - return nbt; - } + return isValidEntity ? getBloodSampleFromEntityUnchecked(target) : null; + } + + @Nullable + public static CompoundNBT getBloodSampleFromEntityUnchecked(LivingEntity target) { + CompoundNBT nbt = new CompoundNBT(); + String typeId = target instanceof PlayerEntity ? getPlayerTypeId((PlayerEntity) target) : target.getEntityString(); + if (typeId != null) { + nbt.putString("EntityTypeId", typeId); + nbt.putString("Name", target.getType().getTranslationKey()); + nbt.putBoolean("IsPlayer", target instanceof PlayerEntity); + nbt.putUniqueId("EntityUUID", target.getUniqueID()); + return nbt; } return null; } + private static String getPlayerTypeId(PlayerEntity playerEntity) { + return EntityType.getKey(playerEntity.getType()).toString(); + } + @OnlyIn(Dist.CLIENT) @Override public void addInfoToTooltip(ItemStack stack, @Nullable World worldIn, List tooltip, ITooltipFlag flagIn) { CompoundNBT nbt = stack.getOrCreateTag(); if (nbt.contains(NBT_KEY_DATA)) { CompoundNBT reagentNbt = nbt.getCompound(NBT_KEY_DATA); - tooltip.add(ClientTextUtil.getTooltipText("contains_dna", new TranslationTextComponent(reagentNbt.getString("Name"))).mergeStyle(TextFormatting.GRAY)); + if (reagentNbt.getBoolean("IsPlayer")) { + String playerName = " " + ClientTextUtil.tryToGetPlayerNameOnClientSide(reagentNbt.getUniqueId("EntityUUID")); + tooltip.add(ClientTextUtil.getTooltipText("contains_dna", new TranslationTextComponent(reagentNbt.getString("Name")).appendString(playerName)).mergeStyle(TextFormatting.GRAY)); + } + else tooltip.add(ClientTextUtil.getTooltipText("contains_dna", new TranslationTextComponent(reagentNbt.getString("Name"))).mergeStyle(TextFormatting.GRAY)); } if (ClientTextUtil.showExtraInfo(tooltip)) { tooltip.add(new TranslationTextComponent(getTranslationKey().replace("reagent", "tooltip")).mergeStyle(ClientTextUtil.LORE_STYLE)); diff --git a/src/main/java/com/github/elenterius/biomancy/reagent/CleansingReagent.java b/src/main/java/com/github/elenterius/biomancy/reagent/CleansingReagent.java index ae6bc6869..61dc38097 100644 --- a/src/main/java/com/github/elenterius/biomancy/reagent/CleansingReagent.java +++ b/src/main/java/com/github/elenterius/biomancy/reagent/CleansingReagent.java @@ -1,12 +1,17 @@ package com.github.elenterius.biomancy.reagent; import com.github.elenterius.biomancy.entity.aberration.FleshBlobEntity; +import com.github.elenterius.biomancy.mixin.ZombieVillagerEntityMixinAccessor; +import net.minecraft.entity.EntityType; import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.monster.ZombieVillagerEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.nbt.CompoundNBT; import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import net.minecraft.world.server.ServerWorld; +import net.minecraftforge.event.ForgeEventFactory; import javax.annotation.Nullable; @@ -27,6 +32,11 @@ public boolean affectEntity(CompoundNBT nbt, @Nullable LivingEntity source, Livi if (target instanceof FleshBlobEntity) { ((FleshBlobEntity) target).clearForeignEntityDNA(); } + else if (target instanceof ZombieVillagerEntity) { + if (!target.world.isRemote && ForgeEventFactory.canLivingConvert(target, EntityType.VILLAGER, (timer) -> {})) { + ((ZombieVillagerEntityMixinAccessor) target).biomancy_cureZombie((ServerWorld) target.world); + } + } return true; } diff --git a/src/main/java/com/github/elenterius/biomancy/reagent/GrowthReagent.java b/src/main/java/com/github/elenterius/biomancy/reagent/GrowthReagent.java index 7fa3571f6..3f197b86a 100644 --- a/src/main/java/com/github/elenterius/biomancy/reagent/GrowthReagent.java +++ b/src/main/java/com/github/elenterius/biomancy/reagent/GrowthReagent.java @@ -117,7 +117,7 @@ public boolean affectEntity(CompoundNBT nbt, @Nullable LivingEntity source, Livi if (!target.world.isRemote) { int slimeSize = ((SlimeEntity) target).getSlimeSize(); if (slimeSize < 25) { - ((SlimeEntityAccessor) target).callSetSlimeSize(slimeSize + 1, false); + ((SlimeEntityAccessor) target).biomancy_setSlimeSize(slimeSize + 1, false); } else { target.attackEntityFrom(DamageSource.causeExplosionDamage(source), target.getHealth()); //"explode" slime @@ -143,7 +143,7 @@ else if (target instanceof ArmorStandEntity) { // EntityDataManager dataManager = target.getDataManager(); // byte status = dataManager.get(ArmorStandEntity.STATUS); // dataManager.set(ArmorStandEntity.STATUS, (byte) (status & ~1)); - ((ArmorStandEntityAccessor) target).callSetSmall(false); + ((ArmorStandEntityAccessor) target).biomancy_setSmall(false); return true; } } diff --git a/src/main/java/com/github/elenterius/biomancy/reagent/MutagenReagent.java b/src/main/java/com/github/elenterius/biomancy/reagent/MutagenReagent.java index d8ff1c8f3..1d4ae512a 100644 --- a/src/main/java/com/github/elenterius/biomancy/reagent/MutagenReagent.java +++ b/src/main/java/com/github/elenterius/biomancy/reagent/MutagenReagent.java @@ -5,7 +5,10 @@ import com.github.elenterius.biomancy.entity.golem.IOwnableCreature; import com.github.elenterius.biomancy.init.ModEffects; import com.github.elenterius.biomancy.init.ModEntityTypes; -import net.minecraft.entity.*; +import com.github.elenterius.biomancy.util.MobUtil; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.Pose; import net.minecraft.entity.merchant.villager.VillagerEntity; import net.minecraft.entity.monster.GuardianEntity; import net.minecraft.entity.passive.AnimalEntity; @@ -26,7 +29,6 @@ import javax.annotation.Nullable; import java.util.Collection; import java.util.List; -import java.util.function.BiConsumer; public class MutagenReagent extends Reagent { @@ -46,7 +48,7 @@ public boolean affectEntity(CompoundNBT nbt, @Nullable LivingEntity source, Livi int amplifier = 0; int duration = 0; for (EffectInstance effectInstance : effects) { - if (effectInstance.getPotion() == ModEffects.FLESH_EATING_DISEASE.get()) { + if (effectInstance.getPotion() == ModEffects.RAVENOUS_HUNGER.get()) { amplifier = effectInstance.getAmplifier(); duration = effectInstance.getDuration(); break; @@ -55,8 +57,11 @@ public boolean affectEntity(CompoundNBT nbt, @Nullable LivingEntity source, Livi amplifier += 1; duration += 5 * 120; - if (!convertLivingEntity(source, target, amplifier)) { - EffectInstance effectInstance = new EffectInstance(ModEffects.FLESH_EATING_DISEASE.get(), duration, amplifier); + if (convertLivingEntity(source, target, amplifier)) { + if (!target.isSilent()) target.world.playEvent(null, Constants.WorldEvents.ZOMBIE_INFECT_SOUND, target.getPosition(), 0); + } + else { + EffectInstance effectInstance = new EffectInstance(ModEffects.RAVENOUS_HUNGER.get(), duration, amplifier); target.addPotionEffect(effectInstance); } } @@ -84,31 +89,31 @@ public boolean affectPlayerSelf(CompoundNBT nbt, PlayerEntity targetSelf) { private boolean convertLivingEntity(@Nullable LivingEntity source, LivingEntity target, int amplifier) { ServerWorld world = (ServerWorld) target.world; - if (amplifier < 2) return false; + if (amplifier < 1) return false; if (target instanceof GuardianEntity) { - return convertMobEntityTo(world, (GuardianEntity) target, EntityType.ELDER_GUARDIAN); + return MobUtil.convertMobEntityTo(world, (GuardianEntity) target, EntityType.ELDER_GUARDIAN); } else if (target instanceof VillagerEntity) { - return convertMobEntityTo(world, (VillagerEntity) target, EntityType.PILLAGER, false); + return MobUtil.convertMobEntityTo(world, (VillagerEntity) target, EntityType.PILLAGER, false); } else if (target instanceof SheepEntity && !(target instanceof FailedSheepEntity)) { float v = world.rand.nextFloat(); if (v < 0.04f) - return convertMobEntityTo(world, (SheepEntity) target, ModEntityTypes.CHROMA_SHEEP.get()); + return MobUtil.convertMobEntityTo(world, (SheepEntity) target, ModEntityTypes.CHROMA_SHEEP.get()); else if (v < 0.2f) - return convertMobEntityTo(world, (SheepEntity) target, ModEntityTypes.THICK_WOOL_SHEEP.get()); + return MobUtil.convertMobEntityTo(world, (SheepEntity) target, ModEntityTypes.THICK_WOOL_SHEEP.get()); else if (v < 0.45f) - return convertMobEntityTo(world, (SheepEntity) target, ModEntityTypes.SILKY_WOOL_SHEEP.get()); + return MobUtil.convertMobEntityTo(world, (SheepEntity) target, ModEntityTypes.SILKY_WOOL_SHEEP.get()); else if (v < 0.8f) - return convertMobEntityTo(world, (SheepEntity) target, ModEntityTypes.FAILED_SHEEP.get()); + return MobUtil.convertMobEntityTo(world, (SheepEntity) target, ModEntityTypes.FAILED_SHEEP.get()); } else if (target instanceof FleshBlobEntity) { return convertFleshBlob(world, source, (FleshBlobEntity) target); } else if (target instanceof AnimalEntity && !(target instanceof TameableEntity) && !(target instanceof IOwnableCreature)) { if (world.rand.nextFloat() < 0.4f) { - return convertMobEntityTo(world, (AnimalEntity) target, ModEntityTypes.FLESH_BLOB.get(), true, (oldEntity, outcome) -> { + return MobUtil.convertMobEntityTo(world, (AnimalEntity) target, ModEntityTypes.FLESH_BLOB.get(), true, (oldEntity, outcome) -> { int size = MathHelper.clamp(Math.round(oldEntity.getSize(Pose.STANDING).height), 1, 10); if (size > 1) outcome.setBlobSize((byte) size, true); }); @@ -118,31 +123,6 @@ else if (target instanceof AnimalEntity && !(target instanceof TameableEntity) & return false; } - private boolean convertMobEntityTo(ServerWorld world, E entityIn, EntityType outcomeType) { - return convertMobEntityTo(world, entityIn, outcomeType, true); - } - - private boolean convertMobEntityTo(ServerWorld world, E entityIn, EntityType outcomeType, boolean copyEquipment) { - return convertMobEntityTo(world, entityIn, outcomeType, copyEquipment, (oldEntity, outcome) -> {}); - } - - private boolean convertMobEntityTo(ServerWorld world, E oldEntity, EntityType outcomeType, boolean copyEquipment, BiConsumer onConvert) { - if (ForgeEventFactory.canLivingConvert(oldEntity, outcomeType, (timer) -> {})) { - T newEntity = oldEntity.func_233656_b_(outcomeType, copyEquipment);// create new entity with same settings & equipment and remove old entity - if (newEntity != null) { - newEntity.onInitialSpawn(world, world.getDifficultyForLocation(oldEntity.getPosition()), SpawnReason.CONVERSION, null, null); - newEntity.hurtResistantTime = 60; - onConvert.accept(oldEntity, newEntity); - ForgeEventFactory.onLivingConvert(oldEntity, newEntity); - if (!oldEntity.isSilent()) { - world.playEvent(null, Constants.WorldEvents.ZOMBIE_INFECT_SOUND, oldEntity.getPosition(), 0); - } - return true; - } - } - return false; - } - private boolean convertFleshBlob(ServerWorld world, @Nullable LivingEntity source, FleshBlobEntity target) { if (world.rand.nextFloat() < 0.7f && target.getBlobSize() < 6) { if (target.hasForeignEntityDNA()) { @@ -152,7 +132,7 @@ private boolean convertFleshBlob(ServerWorld world, @Nullable LivingEntity sourc if (dnaCount == 1) { EntityType entityType = entityDNAs.get(0); if (entityType == EntityType.PLAYER) { - return convertMobEntityTo(world, target, ModEntityTypes.FLESHKIN.get(), false, (fleshBlob, fleshkin) -> { + return MobUtil.convertMobEntityTo(world, target, ModEntityTypes.FLESHKIN.get(), false, (fleshBlob, fleshkin) -> { if (!fleshBlob.isHangry()) { if (source != null) fleshkin.setOwnerUUID(source.getUniqueID()); } @@ -160,14 +140,14 @@ private boolean convertFleshBlob(ServerWorld world, @Nullable LivingEntity sourc }); } else { - return convertLivingEntityTo(world, target, entityType); + return MobUtil.convertLivingEntityTo(world, target, entityType); } } else if (dnaCount == 2) { EntityType typeA = entityDNAs.get(0); EntityType typeB = entityDNAs.get(1); if ((typeA == EntityType.CAVE_SPIDER && typeB == EntityType.CREEPER) || (typeB == EntityType.CAVE_SPIDER && typeA == EntityType.CREEPER)) { - return convertMobEntityTo(world, target, ModEntityTypes.BOOMLING.get(), false); + return MobUtil.convertMobEntityTo(world, target, ModEntityTypes.BOOMLING.get(), false); } } else { @@ -188,32 +168,4 @@ else if (dnaCount == 2) { return false; } - private boolean convertLivingEntityTo(ServerWorld world, LivingEntity oldEntity, EntityType outcomeType) { - if (oldEntity.removed) return false; - - Entity entity = outcomeType.create(world); - if (entity != null) { - if (entity instanceof LivingEntity) { - //noinspection unchecked - EntityType entityType = (EntityType) outcomeType; - if (ForgeEventFactory.canLivingConvert(oldEntity, entityType, (timer) -> {})) { - entity.copyLocationAndAnglesFrom(oldEntity); - oldEntity.remove(); - world.addEntity(entity); - if (entity instanceof MobEntity) { - ((MobEntity) entity).onInitialSpawn(world, world.getDifficultyForLocation(oldEntity.getPosition()), SpawnReason.CONVERSION, null, null); - } - entity.hurtResistantTime = 60; - ForgeEventFactory.onLivingConvert(oldEntity, (LivingEntity) entity); - if (!oldEntity.isSilent()) world.playEvent(null, Constants.WorldEvents.ZOMBIE_INFECT_SOUND, oldEntity.getPosition(), 0); - return true; - } - } - - entity.remove(); - } - - return false; - } - } diff --git a/src/main/java/com/github/elenterius/biomancy/reagent/Reagent.java b/src/main/java/com/github/elenterius/biomancy/reagent/Reagent.java index 49d703596..715cac9f9 100644 --- a/src/main/java/com/github/elenterius/biomancy/reagent/Reagent.java +++ b/src/main/java/com/github/elenterius/biomancy/reagent/Reagent.java @@ -47,7 +47,10 @@ public static void remove(CompoundNBT nbt) { } public static void copyAdditionalData(CompoundNBT fromNbt, CompoundNBT toNbt) { - toNbt.put(NBT_KEY_DATA, fromNbt.getCompound(NBT_KEY_DATA).copy()); + if (fromNbt.contains(NBT_KEY_DATA)) { + CompoundNBT data = fromNbt.getCompound(NBT_KEY_DATA); + if (!data.isEmpty()) toNbt.put(NBT_KEY_DATA, data.copy()); + } } public static void serialize(Reagent reagent, CompoundNBT nbt) { diff --git a/src/main/java/com/github/elenterius/biomancy/reagent/RejuvenationReagent.java b/src/main/java/com/github/elenterius/biomancy/reagent/RejuvenationReagent.java index 009a9cf0a..cc5f9e02a 100644 --- a/src/main/java/com/github/elenterius/biomancy/reagent/RejuvenationReagent.java +++ b/src/main/java/com/github/elenterius/biomancy/reagent/RejuvenationReagent.java @@ -63,7 +63,7 @@ public boolean affectEntity(CompoundNBT nbt, @Nullable LivingEntity source, Livi if (!target.world.isRemote) { int slimeSize = ((SlimeEntity) target).getSlimeSize(); if (slimeSize > 1) { - ((SlimeEntityAccessor) target).callSetSlimeSize(slimeSize - 1, false); + ((SlimeEntityAccessor) target).biomancy_setSlimeSize(slimeSize - 1, false); } } return true; @@ -86,7 +86,7 @@ else if (target instanceof ArmorStandEntity) { // EntityDataManager dataManager = target.getDataManager(); // byte status = dataManager.get(ArmorStandEntity.STATUS); // dataManager.set(ArmorStandEntity.STATUS, (byte) (status | 1)); //inverse = (byte)(status & ~1) - ((ArmorStandEntityAccessor) target).callSetSmall(true); + ((ArmorStandEntityAccessor) target).biomancy_setSmall(true); return true; } } diff --git a/src/main/java/com/github/elenterius/biomancy/recipe/AbstractBioMechanicalRecipe.java b/src/main/java/com/github/elenterius/biomancy/recipe/AbstractBioMechanicalRecipe.java new file mode 100644 index 000000000..28a13a4ab --- /dev/null +++ b/src/main/java/com/github/elenterius/biomancy/recipe/AbstractBioMechanicalRecipe.java @@ -0,0 +1,38 @@ +package com.github.elenterius.biomancy.recipe; + +import net.minecraft.inventory.IInventory; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.items.ItemHandlerHelper; + +public abstract class AbstractBioMechanicalRecipe implements IRecipe { + + private final ResourceLocation registryKey; + private final int time; + + public AbstractBioMechanicalRecipe(ResourceLocation registryKeyIn, int craftingTimeIn) { + registryKey = registryKeyIn; + time = craftingTimeIn; + } + + @Override + public ResourceLocation getId() { + return registryKey; + } + + public int getCraftingTime() { + return time; + } + + public boolean areRecipesEqual(AbstractBioMechanicalRecipe other, boolean relaxed) { + boolean flag = registryKey.equals(other.getId()); + if (!relaxed && !ItemHandlerHelper.canItemStacksStack(getRecipeOutput(), other.getRecipeOutput())) { + return false; + } + return flag; + } + + public static boolean areRecipesEqual(AbstractBioMechanicalRecipe recipeA, AbstractBioMechanicalRecipe recipeB, boolean relaxed) { + return recipeA.areRecipesEqual(recipeB, relaxed); + } +} diff --git a/src/main/java/com/github/elenterius/biomancy/recipe/BioMechanicalRecipeType.java b/src/main/java/com/github/elenterius/biomancy/recipe/BioMechanicalRecipeType.java new file mode 100644 index 000000000..d82a3fad2 --- /dev/null +++ b/src/main/java/com/github/elenterius/biomancy/recipe/BioMechanicalRecipeType.java @@ -0,0 +1,41 @@ +package com.github.elenterius.biomancy.recipe; + +import com.github.elenterius.biomancy.mixin.RecipeManagerMixinAccessor; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.IRecipeType; +import net.minecraft.item.crafting.Ingredient; +import net.minecraft.item.crafting.RecipeManager; +import net.minecraft.world.World; + +import java.util.Optional; + +public class BioMechanicalRecipeType implements IRecipeType { + private final String name; + + public BioMechanicalRecipeType(String nameIn) { + this.name = nameIn; + } + + @Override + public String toString() { + return name; + } + + public Optional getRecipeFromInventory(World world, IInventory inputInv) { + RecipeManager recipeManager = world.getRecipeManager(); + return recipeManager.getRecipe(this, inputInv, world); + } + + public Optional getRecipeForItem(World world, ItemStack stack) { + RecipeManagerMixinAccessor recipeManager = (RecipeManagerMixinAccessor) world.getRecipeManager(); + //noinspection unchecked + return recipeManager.biomancy_getRecipes(this).values().stream().map(recipe -> (T) recipe) + .filter(recipe -> { + for (Ingredient ingredient : recipe.getIngredients()) { + if (ingredient.test(stack)) return true; + } + return false; + }).findFirst(); + } +} diff --git a/src/main/java/com/github/elenterius/biomancy/recipe/ChewerRecipe.java b/src/main/java/com/github/elenterius/biomancy/recipe/ChewerRecipe.java index d8cde8f41..044c1d540 100644 --- a/src/main/java/com/github/elenterius/biomancy/recipe/ChewerRecipe.java +++ b/src/main/java/com/github/elenterius/biomancy/recipe/ChewerRecipe.java @@ -4,7 +4,10 @@ import com.google.gson.JsonObject; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; -import net.minecraft.item.crafting.*; +import net.minecraft.item.crafting.IRecipeSerializer; +import net.minecraft.item.crafting.IRecipeType; +import net.minecraft.item.crafting.Ingredient; +import net.minecraft.item.crafting.ShapedRecipe; import net.minecraft.network.PacketBuffer; import net.minecraft.util.JSONUtils; import net.minecraft.util.NonNullList; @@ -14,18 +17,15 @@ import javax.annotation.Nullable; -public class ChewerRecipe implements IRecipe { +public class ChewerRecipe extends AbstractBioMechanicalRecipe { - private final ResourceLocation registryId; private final Ingredient ingredient; private final ItemStack recipeResult; - private final int time; - public ChewerRecipe(ResourceLocation keyIn, ItemStack result, int timeIn, Ingredient ingredientIn) { - registryId = keyIn; + public ChewerRecipe(ResourceLocation registryKey, ItemStack result, int craftingTimeIn, Ingredient ingredientIn) { + super(registryKey, craftingTimeIn); ingredient = ingredientIn; recipeResult = result; - time = timeIn; } @Override @@ -55,11 +55,6 @@ public NonNullList getIngredients() { return list; } - @Override - public ResourceLocation getId() { - return registryId; - } - @Override public IRecipeSerializer getSerializer() { return ModRecipes.CHEWER_SERIALIZER.get(); @@ -70,10 +65,6 @@ public IRecipeType getType() { return ModRecipes.CHEWER_RECIPE_TYPE; } - public int getCraftingTime() { - return time; - } - public static class Serializer extends ForgeRegistryEntry> implements IRecipeSerializer { private static Ingredient readIngredient(JsonObject jsonObj) { @@ -104,7 +95,7 @@ public ChewerRecipe read(ResourceLocation recipeId, PacketBuffer buffer) { public void write(PacketBuffer buffer, ChewerRecipe recipe) { //server side buffer.writeItemStack(recipe.recipeResult); - buffer.writeInt(recipe.time); + buffer.writeInt(recipe.getCraftingTime()); recipe.ingredient.write(buffer); } } diff --git a/src/main/java/com/github/elenterius/biomancy/recipe/DecomposerRecipe.java b/src/main/java/com/github/elenterius/biomancy/recipe/DecomposerRecipe.java index 2812b7dfb..a7270e99e 100644 --- a/src/main/java/com/github/elenterius/biomancy/recipe/DecomposerRecipe.java +++ b/src/main/java/com/github/elenterius/biomancy/recipe/DecomposerRecipe.java @@ -18,23 +18,20 @@ import java.util.ArrayList; import java.util.List; -public class DecomposerRecipe implements IRecipe { +public class DecomposerRecipe extends AbstractBioMechanicalRecipe { public static final int MAX_INGREDIENTS = 2 * 3; public static final int MAX_BYPRODUCTS = 3; private final NonNullList recipeIngredients; private final ItemStack recipeResult; - private final int time; private final List byproducts; - private final ResourceLocation key; private final boolean isSimple; - public DecomposerRecipe(ResourceLocation keyIn, ItemStack result, int timeIn, NonNullList ingredients, List byproducts) { - key = keyIn; + public DecomposerRecipe(ResourceLocation registryKey, ItemStack result, int craftingTime, NonNullList ingredients, List byproducts) { + super(registryKey, craftingTime); recipeIngredients = ingredients; recipeResult = result; - time = timeIn; this.byproducts = byproducts; isSimple = ingredients.stream().allMatch(Ingredient::isSimple); } @@ -76,10 +73,6 @@ public List getByproducts() { return byproducts; } - public int getDecomposingTime() { - return time; - } - @Override public ItemStack getRecipeOutput() { return recipeResult; @@ -95,11 +88,6 @@ public IRecipeType getType() { return ModRecipes.DECOMPOSING_RECIPE_TYPE; } - @Override - public ResourceLocation getId() { - return key; - } - public static class Serializer extends ForgeRegistryEntry> implements IRecipeSerializer { private static NonNullList readIngredients(JsonArray jsonArray) { @@ -168,7 +156,7 @@ public DecomposerRecipe read(ResourceLocation recipeId, PacketBuffer buffer) { public void write(PacketBuffer buffer, DecomposerRecipe recipe) { //server side buffer.writeItemStack(recipe.recipeResult); - buffer.writeInt(recipe.time); + buffer.writeInt(recipe.getCraftingTime()); buffer.writeVarInt(recipe.byproducts.size()); for (Byproduct byproduct : recipe.byproducts) { diff --git a/src/main/java/com/github/elenterius/biomancy/recipe/DigesterRecipe.java b/src/main/java/com/github/elenterius/biomancy/recipe/DigesterRecipe.java index b3fd99c96..3433e9175 100644 --- a/src/main/java/com/github/elenterius/biomancy/recipe/DigesterRecipe.java +++ b/src/main/java/com/github/elenterius/biomancy/recipe/DigesterRecipe.java @@ -4,7 +4,10 @@ import com.google.gson.JsonObject; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; -import net.minecraft.item.crafting.*; +import net.minecraft.item.crafting.IRecipeSerializer; +import net.minecraft.item.crafting.IRecipeType; +import net.minecraft.item.crafting.Ingredient; +import net.minecraft.item.crafting.ShapedRecipe; import net.minecraft.network.PacketBuffer; import net.minecraft.util.JSONUtils; import net.minecraft.util.NonNullList; @@ -14,20 +17,17 @@ import javax.annotation.Nullable; -public class DigesterRecipe implements IRecipe { +public class DigesterRecipe extends AbstractBioMechanicalRecipe { - private final ResourceLocation registryId; private final Ingredient ingredient; private final ItemStack result; private final Byproduct byproduct; - private final int time; - public DigesterRecipe(ResourceLocation keyIn, ItemStack resultIn, @Nullable Byproduct byproductIn, int timeIn, Ingredient ingredientIn) { - registryId = keyIn; + public DigesterRecipe(ResourceLocation registryKey, ItemStack resultIn, @Nullable Byproduct byproductIn, int craftingTime, Ingredient ingredientIn) { + super(registryKey, craftingTime); ingredient = ingredientIn; result = resultIn; byproduct = byproductIn; - time = timeIn; } @Override @@ -62,11 +62,6 @@ public NonNullList getIngredients() { return list; } - @Override - public ResourceLocation getId() { - return registryId; - } - @Override public IRecipeSerializer getSerializer() { return ModRecipes.DIGESTER_SERIALIZER.get(); @@ -77,10 +72,6 @@ public IRecipeType getType() { return ModRecipes.DIGESTER_RECIPE_TYPE; } - public int getCraftingTime() { - return time; - } - public static class Serializer extends ForgeRegistryEntry> implements IRecipeSerializer { private static Ingredient readIngredient(JsonObject jsonObj) { @@ -115,7 +106,7 @@ public DigesterRecipe read(ResourceLocation recipeId, PacketBuffer buffer) { public void write(PacketBuffer buffer, DigesterRecipe recipe) { //server side buffer.writeItemStack(recipe.result); - buffer.writeInt(recipe.time); + buffer.writeInt(recipe.getCraftingTime()); recipe.ingredient.write(buffer); boolean hasByproduct = recipe.byproduct != null; diff --git a/src/main/java/com/github/elenterius/biomancy/recipe/EvolutionPoolRecipe.java b/src/main/java/com/github/elenterius/biomancy/recipe/EvolutionPoolRecipe.java index ec64cbf6a..424787d5f 100644 --- a/src/main/java/com/github/elenterius/biomancy/recipe/EvolutionPoolRecipe.java +++ b/src/main/java/com/github/elenterius/biomancy/recipe/EvolutionPoolRecipe.java @@ -18,22 +18,19 @@ import javax.annotation.Nullable; import java.util.ArrayList; -public class EvolutionPoolRecipe implements IRecipe { +public class EvolutionPoolRecipe extends AbstractBioMechanicalRecipe { public static final int MAX_INGREDIENTS = 6; private final NonNullList recipeIngredients; private final ItemStack recipeResult; - private final int time; private final boolean isSimple; - private final ResourceLocation registryId; - public EvolutionPoolRecipe(ResourceLocation keyIn, ItemStack result, int timeIn, NonNullList ingredients) { - registryId = keyIn; + public EvolutionPoolRecipe(ResourceLocation registryKey, ItemStack result, int craftingTime, NonNullList ingredients) { + super(registryKey, craftingTime); recipeIngredients = ingredients; recipeResult = result; - time = timeIn; isSimple = ingredients.stream().allMatch(Ingredient::isSimple); } @@ -75,11 +72,6 @@ public NonNullList getIngredients() { return recipeIngredients; } - @Override - public ResourceLocation getId() { - return registryId; - } - @Override public IRecipeSerializer getSerializer() { return ModRecipes.EVOLUTION_POOL_SERIALIZER.get(); @@ -90,10 +82,6 @@ public IRecipeType getType() { return ModRecipes.EVOLUTION_POOL_RECIPE_TYPE; } - public int getCraftingTime() { - return time; - } - public static class Serializer extends ForgeRegistryEntry> implements IRecipeSerializer { private static NonNullList readIngredients(JsonArray jsonArray) { @@ -144,7 +132,7 @@ public EvolutionPoolRecipe read(ResourceLocation recipeId, PacketBuffer buffer) public void write(PacketBuffer buffer, EvolutionPoolRecipe recipe) { //server side buffer.writeItemStack(recipe.recipeResult); - buffer.writeInt(recipe.time); + buffer.writeInt(recipe.getCraftingTime()); buffer.writeVarInt(recipe.recipeIngredients.size()); for (Ingredient ingredient : recipe.recipeIngredients) { diff --git a/src/main/java/com/github/elenterius/biomancy/statuseffect/RavenousHungerEffect.java b/src/main/java/com/github/elenterius/biomancy/statuseffect/RavenousHungerEffect.java index b19cfea60..259c48f53 100644 --- a/src/main/java/com/github/elenterius/biomancy/statuseffect/RavenousHungerEffect.java +++ b/src/main/java/com/github/elenterius/biomancy/statuseffect/RavenousHungerEffect.java @@ -42,6 +42,6 @@ public boolean isReady(int duration, int amplifier) { @Override public List getCurativeItems() { // ModTags.Items.RAW_MEATS.getAllElements().stream().map(ItemStack::new).collect(Collectors.toList()); - return ImmutableList.of(new ItemStack(Items.MELON_SLICE), new ItemStack(Items.HONEY_BOTTLE), new ItemStack(ModItems.NUTRIENT_BAR.get()), new ItemStack(ModItems.VILE_MELON_SLICE.get()), new ItemStack(ModItems.COOKED_VILE_MELON_SLICE.get())); + return ImmutableList.of(new ItemStack(Items.MELON_SLICE), new ItemStack(Items.HONEY_BOTTLE), new ItemStack(ModItems.NUTRIENT_BAR.get()) /*, new ItemStack(ModItems.VILE_MELON_SLICE.get()), new ItemStack(ModItems.COOKED_VILE_MELON_SLICE.get())*/); } } diff --git a/src/main/java/com/github/elenterius/biomancy/tileentity/ChewerTileEntity.java b/src/main/java/com/github/elenterius/biomancy/tileentity/ChewerTileEntity.java index 98d81a06e..4ecee69e7 100644 --- a/src/main/java/com/github/elenterius/biomancy/tileentity/ChewerTileEntity.java +++ b/src/main/java/com/github/elenterius/biomancy/tileentity/ChewerTileEntity.java @@ -1,15 +1,14 @@ package com.github.elenterius.biomancy.tileentity; -import com.github.elenterius.biomancy.block.ChewerBlock; -import com.github.elenterius.biomancy.init.ModItems; import com.github.elenterius.biomancy.init.ModRecipes; import com.github.elenterius.biomancy.init.ModTileEntityTypes; import com.github.elenterius.biomancy.inventory.ChewerContainer; +import com.github.elenterius.biomancy.inventory.FuelInvContents; import com.github.elenterius.biomancy.inventory.SimpleInvContents; -import com.github.elenterius.biomancy.mixin.RecipeManagerMixinAccessor; +import com.github.elenterius.biomancy.recipe.BioMechanicalRecipeType; import com.github.elenterius.biomancy.recipe.ChewerRecipe; import com.github.elenterius.biomancy.tileentity.state.ChewerStateData; -import com.github.elenterius.biomancy.tileentity.state.CraftingState; +import com.github.elenterius.biomancy.util.BiofuelUtil; import com.github.elenterius.biomancy.util.TextUtil; import net.minecraft.block.BlockState; import net.minecraft.entity.player.PlayerEntity; @@ -17,28 +16,20 @@ import net.minecraft.inventory.IInventory; import net.minecraft.inventory.InventoryHelper; import net.minecraft.inventory.container.Container; -import net.minecraft.inventory.container.INamedContainerProvider; import net.minecraft.item.ItemStack; -import net.minecraft.item.crafting.Ingredient; -import net.minecraft.item.crafting.RecipeManager; import net.minecraft.nbt.CompoundNBT; -import net.minecraft.tileentity.ITickableTileEntity; import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.MathHelper; import net.minecraft.util.text.ITextComponent; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; -import net.minecraftforge.common.util.Constants; import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.items.CapabilityItemHandler; -import net.minecraftforge.items.ItemHandlerHelper; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import java.util.Optional; -public class ChewerTileEntity extends OwnableTileEntity implements INamedContainerProvider, ITickableTileEntity { +public class ChewerTileEntity extends MachineTileEntity { public static final int FUEL_SLOTS_COUNT = 1; public static final int INPUT_SLOTS_COUNT = 1; @@ -47,133 +38,82 @@ public class ChewerTileEntity extends OwnableTileEntity implements INamedContain public static final int DEFAULT_TIME = 200; public static final int MAX_FUEL = 32_000; public static final short FUEL_COST = 2; - public static final float FUEL_CONVERSION = FUEL_COST * DEFAULT_TIME / 4f; + public static final BioMechanicalRecipeType RECIPE_TYPE = ModRecipes.CHEWER_RECIPE_TYPE; private final ChewerStateData stateData = new ChewerStateData(); - private final SimpleInvContents fuelContents; + private final FuelInvContents fuelContents; private final SimpleInvContents inputContents; private final SimpleInvContents outputContents; public ChewerTileEntity() { super(ModTileEntityTypes.CHEWER.get()); - fuelContents = SimpleInvContents.createServerContents(FUEL_SLOTS_COUNT, this::canPlayerOpenInv, this::markDirty); + fuelContents = FuelInvContents.createServerContents(FUEL_SLOTS_COUNT, this::isItemValidFuel, this::canPlayerOpenInv, this::markDirty); inputContents = SimpleInvContents.createServerContents(INPUT_SLOTS_COUNT, this::canPlayerOpenInv, this::markDirty); outputContents = SimpleInvContents.createServerContents(OUTPUT_SLOTS_COUNT, SimpleInvContents.ISHandlerType.NO_INSERT, this::canPlayerOpenInv, this::markDirty); } - public static Optional getRecipeForItem(World world, ItemStack stackIn) { - RecipeManagerMixinAccessor recipeManager = (RecipeManagerMixinAccessor) world.getRecipeManager(); - - return recipeManager.callGetRecipes(ModRecipes.CHEWER_RECIPE_TYPE).values().stream().map((recipe) -> (ChewerRecipe) recipe) - .filter(recipe -> { - for (Ingredient ingredient : recipe.getIngredients()) { - if (ingredient.test(stackIn)) return true; - } - return false; - }).findFirst(); + @Override + protected ChewerStateData getStateData() { + return stateData; } - public static boolean areRecipesEqual(ChewerRecipe recipeA, ChewerRecipe recipeB, boolean relaxed) { - boolean flag = recipeA.getId().equals(recipeB.getId()); - if (!relaxed && !ItemHandlerHelper.canItemStacksStack(recipeA.getRecipeOutput(), recipeB.getRecipeOutput())) { - return false; - } - return flag; + @Override + public BioMechanicalRecipeType getRecipeType() { + return RECIPE_TYPE; } - public static Optional getRecipeForInput(World world, IInventory inputInv) { - RecipeManager recipeManager = world.getRecipeManager(); - return recipeManager.getRecipe(ModRecipes.CHEWER_RECIPE_TYPE, inputInv, world); + @Override + public int getFuelAmount() { + return stateData.fuel; } - public static boolean isItemValidFuel(ItemStack stack) { - return stack.getItem() == ModItems.NUTRIENT_PASTE.get() || stack.getItem() == ModItems.NUTRIENT_BAR.get(); + @Override + public void setFuelAmount(int newAmount) { + stateData.fuel = (short) newAmount; } @Override - protected ITextComponent getDefaultName() { - return TextUtil.getTranslationText("container", "chewer"); + public void addFuelAmount(int addAmount) { + stateData.fuel += addAmount; } - @Nullable @Override - public Container createMenu(int screenId, PlayerInventory playerInv, PlayerEntity player) { - return ChewerContainer.createServerContainer(screenId, playerInv, fuelContents, inputContents, outputContents, stateData); + public int getMaxFuelAmount() { + return MAX_FUEL; } @Override - public void tick() { - if (world == null || world.isRemote) return; - - if (world.getGameTime() % 10L == 0L) { - refuel(); - } - - ChewerRecipe recipeToCraft = getRecipeForInput(world, inputContents).orElse(null); - if (recipeToCraft == null) { - stateData.cancelCrafting(); - } - else { - ItemStack itemToCraft = recipeToCraft.getRecipeOutput(); // .copy() - if (itemToCraft.isEmpty()) { - stateData.cancelCrafting(); - } - else { - if (outputContents.doesItemStackFit(0, itemToCraft)) { - if (stateData.getCraftingState() == CraftingState.NONE) { - stateData.setCraftingState(CraftingState.IN_PROGRESS); - stateData.clear(); //safe guard, shouldn't be needed - stateData.setCraftingGoalRecipe(recipeToCraft); // this also sets the time required for crafting - } - else if (!stateData.isCraftingCanceled()) { - ChewerRecipe recipeCraftingGoal = stateData.getCraftingGoalRecipe(world).orElse(null); - if (recipeCraftingGoal == null || !areRecipesEqual(recipeToCraft, recipeCraftingGoal, true)) { - stateData.cancelCrafting(); - } - } - } - else { - if (stateData.getCraftingState() != CraftingState.COMPLETED) stateData.cancelCrafting(); - } - } + public int getFuelCost() { + return FUEL_COST; + } - //change crafting progress - if (stateData.getCraftingState() == CraftingState.IN_PROGRESS) { - if (consumeFuel()) stateData.timeElapsed += 1; - else stateData.timeElapsed -= 2; + @Override + public boolean isItemValidFuel(ItemStack stack) { + return BiofuelUtil.isItemValidFuel(stack); + } - if (stateData.timeElapsed < 0) stateData.timeElapsed = 0; - } + @Override + public float getItemFuelValue(ItemStack stackIn) { + return BiofuelUtil.getItemFuelValue(stackIn); + } - //craft items - if (stateData.getCraftingState() == CraftingState.IN_PROGRESS || stateData.getCraftingState() == CraftingState.COMPLETED) { - if (stateData.timeElapsed >= stateData.timeForCompletion) { - stateData.setCraftingState(CraftingState.COMPLETED); - if (craftItem(recipeToCraft)) { - stateData.setCraftingState(CraftingState.NONE); - } - } - } - } + @Override + public ItemStack getStackInFuelSlot() { + return fuelContents.getStackInSlot(0); + } - //clean-up states - if (stateData.isCraftingCanceled()) { - stateData.setCraftingState(CraftingState.NONE); - stateData.clear(); - } - else if (stateData.getCraftingState() == CraftingState.NONE) { - stateData.clear(); - } + @Override + public void setStackInFuelSlot(ItemStack stack) { + fuelContents.setInventorySlotContents(0, stack); + } - BlockState oldBlockState = world.getBlockState(pos); - BlockState newBlockState = oldBlockState.with(ChewerBlock.CRAFTING, stateData.getCraftingState() == CraftingState.IN_PROGRESS); - if (!newBlockState.equals(oldBlockState)) { - world.setBlockState(pos, newBlockState, Constants.BlockFlags.BLOCK_UPDATE); - markDirty(); - } + @Override + protected boolean doesItemFitIntoOutputInventory(ItemStack stackToCraft) { + return outputContents.doesItemStackFit(0, stackToCraft); } - private boolean craftItem(ChewerRecipe recipeToCraft) { + @Override + protected boolean craftRecipe(ChewerRecipe recipeToCraft, World world) { ItemStack result = recipeToCraft.getCraftingResult(inputContents); if (!result.isEmpty() && outputContents.doesItemStackFit(0, result)) { for (int idx = 0; idx < inputContents.getSizeInventory(); idx++) { @@ -186,42 +126,23 @@ private boolean craftItem(ChewerRecipe recipeToCraft) { return false; } - private boolean consumeFuel() { - if (stateData.fuel >= FUEL_COST) { - stateData.fuel -= FUEL_COST; - return true; - } - return false; + @Override + protected IInventory getInputInventory() { + return inputContents; } - public void refuel() { - if (stateData.fuel < MAX_FUEL) { - ItemStack stack = fuelContents.getStackInSlot(0); - if (isItemValidFuel(stack)) { - ItemStack remainder = addFuel(stack); - if (remainder.getCount() != stack.getCount()) { - fuelContents.setInventorySlotContents(0, remainder); - markDirty(); - } - } - } + @Override + protected ITextComponent getDefaultName() { + return TextUtil.getTranslationText("container", "chewer"); } - public ItemStack addFuel(ItemStack stackIn) { - if (world == null || world.isRemote()) return stackIn; - - if (!stackIn.isEmpty() && stateData.fuel < MAX_FUEL) { - float fuelConversion = FUEL_CONVERSION * (stackIn.getItem() == ModItems.NUTRIENT_BAR.get() ? 5 : 1); - int itemsNeeded = Math.round(Math.max(0, MAX_FUEL - stateData.fuel) / fuelConversion); - int consumeAmount = Math.min(stackIn.getCount(), itemsNeeded); - if (consumeAmount > 0) { - stateData.fuel = (short) MathHelper.clamp(stateData.fuel + fuelConversion * consumeAmount, 0, MAX_FUEL + fuelConversion); - return ItemHandlerHelper.copyStackWithSize(stackIn, stackIn.getCount() - consumeAmount); - } - } - return stackIn; + @Nullable + @Override + public Container createMenu(int screenId, PlayerInventory playerInv, PlayerEntity player) { + return ChewerContainer.createServerContainer(screenId, playerInv, fuelContents, inputContents, outputContents, stateData); } + @Override public void dropAllInvContents(World world, BlockPos pos) { InventoryHelper.dropInventoryItems(world, pos, fuelContents); InventoryHelper.dropInventoryItems(world, pos, inputContents); diff --git a/src/main/java/com/github/elenterius/biomancy/tileentity/DecomposerTileEntity.java b/src/main/java/com/github/elenterius/biomancy/tileentity/DecomposerTileEntity.java index e11dd2a4c..fa95e2e39 100644 --- a/src/main/java/com/github/elenterius/biomancy/tileentity/DecomposerTileEntity.java +++ b/src/main/java/com/github/elenterius/biomancy/tileentity/DecomposerTileEntity.java @@ -1,16 +1,15 @@ package com.github.elenterius.biomancy.tileentity; -import com.github.elenterius.biomancy.block.DecomposerBlock; -import com.github.elenterius.biomancy.init.ModItems; import com.github.elenterius.biomancy.init.ModRecipes; import com.github.elenterius.biomancy.init.ModTileEntityTypes; import com.github.elenterius.biomancy.inventory.DecomposerContainer; +import com.github.elenterius.biomancy.inventory.FuelInvContents; import com.github.elenterius.biomancy.inventory.SimpleInvContents; -import com.github.elenterius.biomancy.mixin.RecipeManagerMixinAccessor; +import com.github.elenterius.biomancy.recipe.BioMechanicalRecipeType; import com.github.elenterius.biomancy.recipe.Byproduct; import com.github.elenterius.biomancy.recipe.DecomposerRecipe; -import com.github.elenterius.biomancy.tileentity.state.CraftingState; import com.github.elenterius.biomancy.tileentity.state.DecomposerStateData; +import com.github.elenterius.biomancy.util.BiofuelUtil; import com.github.elenterius.biomancy.util.TextUtil; import net.minecraft.block.BlockState; import net.minecraft.entity.player.PlayerEntity; @@ -18,169 +17,103 @@ import net.minecraft.inventory.IInventory; import net.minecraft.inventory.InventoryHelper; import net.minecraft.inventory.container.Container; -import net.minecraft.inventory.container.INamedContainerProvider; import net.minecraft.item.ItemStack; -import net.minecraft.item.crafting.Ingredient; -import net.minecraft.item.crafting.RecipeManager; import net.minecraft.nbt.CompoundNBT; -import net.minecraft.tileentity.ITickableTileEntity; import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.MathHelper; import net.minecraft.util.text.ITextComponent; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; -import net.minecraftforge.common.util.Constants; import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.items.CapabilityItemHandler; -import net.minecraftforge.items.ItemHandlerHelper; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import java.util.Optional; -import java.util.Random; -public class DecomposerTileEntity extends OwnableTileEntity implements INamedContainerProvider, ITickableTileEntity { +public class DecomposerTileEntity extends MachineTileEntity { public static final int FUEL_SLOTS_COUNT = 1; public static final int INPUT_SLOTS_COUNT = DecomposerRecipe.MAX_INGREDIENTS; public static final int OUTPUT_SLOTS_COUNT = 1 + DecomposerRecipe.MAX_BYPRODUCTS; - public static final int DEFAULT_TIME = 200; public static final int MAX_FUEL = 32_000; public static final short FUEL_COST = 5; - public static final float FUEL_CONVERSION = FUEL_COST * DEFAULT_TIME / 4f; + public static final BioMechanicalRecipeType RECIPE_TYPE = ModRecipes.DECOMPOSING_RECIPE_TYPE; private final DecomposerStateData stateData = new DecomposerStateData(); - private final SimpleInvContents fuelContents; + private final FuelInvContents fuelContents; private final SimpleInvContents inputContents; private final SimpleInvContents outputContents; public DecomposerTileEntity() { super(ModTileEntityTypes.DECOMPOSER.get()); - fuelContents = SimpleInvContents.createServerContents(FUEL_SLOTS_COUNT, this::canPlayerOpenInv, this::markDirty); + fuelContents = FuelInvContents.createServerContents(FUEL_SLOTS_COUNT, this::isItemValidFuel, this::canPlayerOpenInv, this::markDirty); inputContents = SimpleInvContents.createServerContents(INPUT_SLOTS_COUNT, this::canPlayerOpenInv, this::markDirty); outputContents = SimpleInvContents.createServerContents(OUTPUT_SLOTS_COUNT, SimpleInvContents.ISHandlerType.NO_INSERT, this::canPlayerOpenInv, this::markDirty); } - public static boolean areRecipesEqual(DecomposerRecipe recipeA, DecomposerRecipe recipeB, boolean relaxed) { - boolean flag = recipeA.getId().equals(recipeB.getId()); - if (!relaxed && !ItemHandlerHelper.canItemStacksStack(recipeA.getRecipeOutput(), recipeB.getRecipeOutput())) { - return false; - } - return flag; + @Override + protected DecomposerStateData getStateData() { + return stateData; } - public static ItemStack getRecipeResult(World world, IInventory inputInv) { - Optional recipe = getRecipeForInput(world, inputInv); - return recipe.map(decomposingRecipe -> decomposingRecipe.getRecipeOutput().copy()).orElse(ItemStack.EMPTY); + @Override + public BioMechanicalRecipeType getRecipeType() { + return RECIPE_TYPE; } - public static int getCraftingTime(World world, IInventory inputInv) { - Optional recipe = getRecipeForInput(world, inputInv); - return recipe.map(DecomposerRecipe::getDecomposingTime).orElse(0); + @Override + public int getFuelAmount() { + return stateData.fuel; } - public static Optional getRecipeForInput(World world, IInventory inputInv) { - RecipeManager recipeManager = world.getRecipeManager(); - return recipeManager.getRecipe(ModRecipes.DECOMPOSING_RECIPE_TYPE, inputInv, world); + @Override + public void setFuelAmount(int newAmount) { + stateData.fuel = (short) newAmount; } - public static Optional getRecipeForItem(World world, ItemStack stack) { - RecipeManagerMixinAccessor recipeManager = (RecipeManagerMixinAccessor) world.getRecipeManager(); - - return recipeManager.callGetRecipes(ModRecipes.DECOMPOSING_RECIPE_TYPE).values().stream().map((recipe) -> (DecomposerRecipe) recipe) - .filter(recipe -> { - for (Ingredient ingredient : recipe.getIngredients()) { - if (ingredient.test(stack)) return true; - } - return false; - }).findFirst(); + @Override + public void addFuelAmount(int addAmount) { + stateData.fuel += addAmount; } - public static boolean isItemValidFuel(ItemStack stack) { - return stack.getItem() == ModItems.NUTRIENT_PASTE.get() || stack.getItem() == ModItems.NUTRIENT_BAR.get(); + @Override + public int getMaxFuelAmount() { + return MAX_FUEL; } - @Nullable @Override - public Container createMenu(int screenId, PlayerInventory playerInv, PlayerEntity player) { - return DecomposerContainer.createServerContainer(screenId, playerInv, fuelContents, inputContents, outputContents, stateData); + public int getFuelCost() { + return FUEL_COST; } @Override - public void tick() { - if (world == null || world.isRemote) return; - - if (world.getGameTime() % 10L == 0L) { - refuel(); - } - - DecomposerRecipe recipeToCraft = getRecipeForInput(world, inputContents).orElse(null); - if (recipeToCraft == null) { - stateData.cancelCrafting(); - } - else { - ItemStack itemToCraft = recipeToCraft.getRecipeOutput().copy(); - if (itemToCraft.isEmpty()) { - stateData.cancelCrafting(); - } - else { - if (outputContents.doesItemStackFit(0, itemToCraft)) { - if (stateData.getCraftingState() == CraftingState.NONE) { - stateData.setCraftingState(CraftingState.IN_PROGRESS); - stateData.clear(); //safe guard, shouldn't be needed - stateData.setCraftingGoalRecipe(recipeToCraft); // this also sets the time required for crafting - } - else if (!stateData.isCraftingCanceled()) { - DecomposerRecipe recipeCraftingGoal = stateData.getCraftingGoalRecipe(world).orElse(null); - if (recipeCraftingGoal == null || !areRecipesEqual(recipeToCraft, recipeCraftingGoal, true)) { - stateData.cancelCrafting(); - } - } - } - else { - if (stateData.getCraftingState() != CraftingState.COMPLETED) stateData.cancelCrafting(); - } - } - - //change crafting progress - if (stateData.getCraftingState() == CraftingState.IN_PROGRESS) { - if (consumeFuel()) stateData.timeElapsed += consumeSpeedFuel() ? 2 : 1; - else stateData.timeElapsed -= 2; + public boolean isItemValidFuel(ItemStack stack) { + return BiofuelUtil.isItemValidFuel(stack); + } - if (stateData.timeElapsed < 0) stateData.timeElapsed = 0; - } + @Override + public float getItemFuelValue(ItemStack stackIn) { + return BiofuelUtil.getItemFuelValue(stackIn); + } - //craft items - if (stateData.getCraftingState() == CraftingState.IN_PROGRESS || stateData.getCraftingState() == CraftingState.COMPLETED) { - if (stateData.timeElapsed >= stateData.timeForCompletion) { - stateData.setCraftingState(CraftingState.COMPLETED); - if (craftItems(recipeToCraft, world.rand)) { - stateData.setCraftingState(CraftingState.NONE); - } - } - } - } + @Override + public ItemStack getStackInFuelSlot() { + return fuelContents.getStackInSlot(0); + } - //clean-up states - if (stateData.isCraftingCanceled()) { - stateData.setCraftingState(CraftingState.NONE); - stateData.clear(); - } - else if (stateData.getCraftingState() == CraftingState.NONE) { - stateData.clear(); - } + @Override + public void setStackInFuelSlot(ItemStack stack) { + fuelContents.setInventorySlotContents(0, stack); + } - BlockState oldBlockState = world.getBlockState(pos); - BlockState newBlockState = oldBlockState.with(DecomposerBlock.DECOMPOSING, stateData.getCraftingState() == CraftingState.IN_PROGRESS); - if (!newBlockState.equals(oldBlockState)) { - world.setBlockState(pos, newBlockState, Constants.BlockFlags.BLOCK_UPDATE); - markDirty(); - } + @Override + protected boolean doesItemFitIntoOutputInventory(ItemStack stackToCraft) { + return outputContents.doesItemStackFit(0, stackToCraft); } - private boolean craftItems(DecomposerRecipe recipeToCraft, Random rand) { + @Override + protected boolean craftRecipe(DecomposerRecipe recipeToCraft, World world) { ItemStack result = recipeToCraft.getCraftingResult(inputContents); if (!result.isEmpty() && outputContents.doesItemStackFit(0, result)) { for (int idx = 0; idx < inputContents.getSizeInventory(); idx++) { @@ -191,7 +124,7 @@ private boolean craftItems(DecomposerRecipe recipeToCraft, Random rand) { //output optional byproducts for (Byproduct byproduct : recipeToCraft.getByproducts()) { - if (rand.nextFloat() <= byproduct.getChance()) { + if (world.rand.nextFloat() <= byproduct.getChance()) { ItemStack stack = byproduct.getItemStack(); for (int idx = 1; idx < outputContents.getSizeInventory(); idx++) { //index 0 is reserved for the main crafting output stack = outputContents.insertItemStack(idx, stack); //update stack with remainder @@ -205,50 +138,31 @@ private boolean craftItems(DecomposerRecipe recipeToCraft, Random rand) { return false; } - private boolean consumeSpeedFuel() { - if (stateData.speedFuel >= FUEL_COST + 5) { - stateData.speedFuel -= FUEL_COST + 5; - return true; - } - return false; + @Override + protected IInventory getInputInventory() { + return inputContents; } - private boolean consumeFuel() { - if (stateData.mainFuel >= FUEL_COST) { - stateData.mainFuel -= FUEL_COST; - return true; - } - return false; + @Override + protected ITextComponent getDefaultName() { + return TextUtil.getTranslationText("container", "decomposer"); } - public void refuel() { - if (stateData.mainFuel < MAX_FUEL) { - ItemStack stack = fuelContents.getStackInSlot(0); - if (isItemValidFuel(stack)) { - ItemStack remainder = addFuel(stack); - if (remainder.getCount() != stack.getCount()) { - fuelContents.setInventorySlotContents(0, remainder); - markDirty(); - } - } - } + @Nullable + @Override + public Container createMenu(int screenId, PlayerInventory playerInv, PlayerEntity player) { + return DecomposerContainer.createServerContainer(screenId, playerInv, fuelContents, inputContents, outputContents, stateData); } - public ItemStack addFuel(ItemStack stackIn) { - if (world == null || world.isRemote()) return stackIn; - - if (!stackIn.isEmpty() && stateData.mainFuel < MAX_FUEL) { - float fuelConversion = FUEL_CONVERSION * (stackIn.getItem() == ModItems.NUTRIENT_BAR.get() ? 5 : 1); - int itemsNeeded = Math.round(Math.max(0, MAX_FUEL - stateData.mainFuel) / fuelConversion); - int consumeAmount = Math.min(stackIn.getCount(), itemsNeeded); - if (consumeAmount > 0) { - stateData.mainFuel = (short) MathHelper.clamp(stateData.mainFuel + fuelConversion * consumeAmount, 0, MAX_FUEL + fuelConversion); - return ItemHandlerHelper.copyStackWithSize(stackIn, stackIn.getCount() - consumeAmount); - } + private boolean consumeSpeedFuel() { + if (stateData.speedFuel >= FUEL_COST + 5) { + stateData.speedFuel -= FUEL_COST + 5; + return true; } - return stackIn; + return false; } + @Override public void dropAllInvContents(World world, BlockPos pos) { InventoryHelper.dropInventoryItems(world, pos, fuelContents); InventoryHelper.dropInventoryItems(world, pos, inputContents); @@ -307,9 +221,4 @@ public LazyOptional getCapability(@Nonnull Capability cap, @Nullable D return super.getCapability(cap, side); } - @Override - protected ITextComponent getDefaultName() { - return TextUtil.getTranslationText("container", "decomposer"); - } - } diff --git a/src/main/java/com/github/elenterius/biomancy/tileentity/DigesterTileEntity.java b/src/main/java/com/github/elenterius/biomancy/tileentity/DigesterTileEntity.java index f1d740431..118351cb6 100644 --- a/src/main/java/com/github/elenterius/biomancy/tileentity/DigesterTileEntity.java +++ b/src/main/java/com/github/elenterius/biomancy/tileentity/DigesterTileEntity.java @@ -1,14 +1,13 @@ package com.github.elenterius.biomancy.tileentity; -import com.github.elenterius.biomancy.block.DigesterBlock; import com.github.elenterius.biomancy.init.ModRecipes; import com.github.elenterius.biomancy.init.ModTileEntityTypes; import com.github.elenterius.biomancy.inventory.DigesterContainer; +import com.github.elenterius.biomancy.inventory.FuelInvContents; import com.github.elenterius.biomancy.inventory.SimpleInvContents; -import com.github.elenterius.biomancy.mixin.RecipeManagerMixinAccessor; +import com.github.elenterius.biomancy.recipe.BioMechanicalRecipeType; import com.github.elenterius.biomancy.recipe.Byproduct; import com.github.elenterius.biomancy.recipe.DigesterRecipe; -import com.github.elenterius.biomancy.tileentity.state.CraftingState; import com.github.elenterius.biomancy.tileentity.state.DigesterStateData; import com.github.elenterius.biomancy.util.TextUtil; import net.minecraft.block.BlockState; @@ -18,21 +17,16 @@ import net.minecraft.inventory.IInventory; import net.minecraft.inventory.InventoryHelper; import net.minecraft.inventory.container.Container; -import net.minecraft.inventory.container.INamedContainerProvider; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; -import net.minecraft.item.crafting.Ingredient; -import net.minecraft.item.crafting.RecipeManager; import net.minecraft.nbt.CompoundNBT; import net.minecraft.potion.PotionUtils; import net.minecraft.potion.Potions; -import net.minecraft.tileentity.ITickableTileEntity; import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; import net.minecraft.util.text.ITextComponent; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; -import net.minecraftforge.common.util.Constants; import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.fluids.FluidActionResult; import net.minecraftforge.fluids.FluidStack; @@ -40,14 +34,12 @@ import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.items.CapabilityItemHandler; -import net.minecraftforge.items.ItemHandlerHelper; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import java.util.Optional; -import java.util.Random; +import java.util.function.Predicate; -public class DigesterTileEntity extends OwnableTileEntity implements INamedContainerProvider, ITickableTileEntity { +public class DigesterTileEntity extends MachineTileEntity { public static final int FUEL_SLOTS_COUNT = 1; public static final int FUEL_OUT_SLOTS_COUNT = 1; @@ -56,130 +48,102 @@ public class DigesterTileEntity extends OwnableTileEntity implements INamedConta public static final int MAX_FUEL = 32_000; public static final short FUEL_COST = 1; + public static final Predicate VALID_FUEL_ITEM = stack -> { + if (stack.getItem() == Items.POTION && PotionUtils.getPotionFromItem(stack) == Potions.WATER) return true; + return FluidUtil.getFluidContained(stack).map(DigesterTileEntity::isFluidValidFuel).orElse(false); + }; + public static final BioMechanicalRecipeType RECIPE_TYPE = ModRecipes.DIGESTER_RECIPE_TYPE; private final DigesterStateData stateData = new DigesterStateData(); - private final SimpleInvContents fuelContents; + private final FuelInvContents fuelContents; private final SimpleInvContents fuelOutContents; private final SimpleInvContents inputContents; private final SimpleInvContents outputContents; public DigesterTileEntity() { super(ModTileEntityTypes.DIGESTER.get()); - fuelContents = SimpleInvContents.createServerContents(FUEL_SLOTS_COUNT, this::canPlayerOpenInv, this::markDirty); - fuelOutContents = SimpleInvContents.createServerContents(FUEL_OUT_SLOTS_COUNT, this::canPlayerOpenInv, this::markDirty); + fuelContents = FuelInvContents.createServerContents(FUEL_SLOTS_COUNT, this::isItemValidFuel, this::canPlayerOpenInv, this::markDirty); + fuelOutContents = SimpleInvContents.createServerContents(FUEL_OUT_SLOTS_COUNT, SimpleInvContents.ISHandlerType.NO_INSERT, this::canPlayerOpenInv, this::markDirty); inputContents = SimpleInvContents.createServerContents(INPUT_SLOTS_COUNT, this::canPlayerOpenInv, this::markDirty); outputContents = SimpleInvContents.createServerContents(OUTPUT_SLOTS_COUNT, SimpleInvContents.ISHandlerType.NO_INSERT, this::canPlayerOpenInv, this::markDirty); } - public static Optional getRecipeForItem(World world, ItemStack stackIn) { - RecipeManagerMixinAccessor recipeManager = (RecipeManagerMixinAccessor) world.getRecipeManager(); - - return recipeManager.callGetRecipes(ModRecipes.DIGESTER_RECIPE_TYPE).values().stream().map((recipe) -> (DigesterRecipe) recipe) - .filter(recipe -> { - for (Ingredient ingredient : recipe.getIngredients()) { - if (ingredient.test(stackIn)) return true; - } - return false; - }).findFirst(); + @Override + protected DigesterStateData getStateData() { + return stateData; } - public static boolean areRecipesEqual(DigesterRecipe recipeA, DigesterRecipe recipeB, boolean relaxed) { - boolean flag = recipeA.getId().equals(recipeB.getId()); - if (!relaxed && !ItemHandlerHelper.canItemStacksStack(recipeA.getRecipeOutput(), recipeB.getRecipeOutput())) { - return false; - } - return flag; + @Override + public BioMechanicalRecipeType getRecipeType() { + return RECIPE_TYPE; } - public static Optional getRecipeForInput(World world, IInventory inputInv) { - RecipeManager recipeManager = world.getRecipeManager(); - return recipeManager.getRecipe(ModRecipes.DIGESTER_RECIPE_TYPE, inputInv, world); + @Override + public int getFuelAmount() { + return stateData.fuel.getFluidAmount(); } @Override - protected ITextComponent getDefaultName() { - return TextUtil.getTranslationText("container", "digester"); + public void setFuelAmount(int newAmount) { + if (stateData.fuel.isEmpty()) { + stateData.fuel.setFluid(new FluidStack(Fluids.WATER, newAmount)); + } + else { + stateData.fuel.getFluid().setAmount(newAmount); + } } - @Nullable @Override - public Container createMenu(int screenId, PlayerInventory playerInv, PlayerEntity player) { - return DigesterContainer.createServerContainer(screenId, playerInv, fuelContents, fuelOutContents, inputContents, outputContents, stateData); + public void addFuelAmount(int addAmount) { + if (stateData.fuel.isEmpty()) { + if (addAmount > 0) stateData.fuel.setFluid(new FluidStack(Fluids.WATER, addAmount)); + } + else { + stateData.fuel.getFluid().grow(addAmount); + } } @Override - public void tick() { - if (world == null || world.isRemote) return; + public int getMaxFuelAmount() { + return MAX_FUEL; + } - if (world.getGameTime() % 10L == 0L) { - refuel(); - } + @Override + public int getFuelCost() { + return FUEL_COST; + } - DigesterRecipe recipeToCraft = getRecipeForInput(world, inputContents).orElse(null); - if (recipeToCraft == null) { - stateData.cancelCrafting(); - } - else { - ItemStack itemToCraft = recipeToCraft.getRecipeOutput(); // .copy() - if (itemToCraft.isEmpty()) { - stateData.cancelCrafting(); - } - else { - if (outputContents.doesItemStackFit(0, itemToCraft)) { - if (stateData.getCraftingState() == CraftingState.NONE) { - stateData.setCraftingState(CraftingState.IN_PROGRESS); - stateData.clear(); //safe guard, shouldn't be needed - stateData.setCraftingGoalRecipe(recipeToCraft); // this also sets the time required for crafting - } - else if (!stateData.isCraftingCanceled()) { - DigesterRecipe recipeCraftingGoal = stateData.getCraftingGoalRecipe(world).orElse(null); - if (recipeCraftingGoal == null || !areRecipesEqual(recipeToCraft, recipeCraftingGoal, true)) { - stateData.cancelCrafting(); - } - } - } - else { - if (stateData.getCraftingState() != CraftingState.COMPLETED) stateData.cancelCrafting(); - } - } + public static boolean isFluidValidFuel(FluidStack fluidStack) { + return fluidStack.getFluid() == Fluids.WATER; + } - //change crafting progress - if (stateData.getCraftingState() == CraftingState.IN_PROGRESS) { - if (consumeFuel()) stateData.timeElapsed += 1; - else stateData.timeElapsed -= 2; + @Override + public boolean isItemValidFuel(ItemStack stack) { + return VALID_FUEL_ITEM.test(stack); + } - if (stateData.timeElapsed < 0) stateData.timeElapsed = 0; - } + @Override + public float getItemFuelValue(ItemStack stackIn) { + return 1; + } - //craft items - if (stateData.getCraftingState() == CraftingState.IN_PROGRESS || stateData.getCraftingState() == CraftingState.COMPLETED) { - if (stateData.timeElapsed >= stateData.timeForCompletion) { - stateData.setCraftingState(CraftingState.COMPLETED); - if (craftItems(recipeToCraft, world.rand)) { - stateData.setCraftingState(CraftingState.NONE); - } - } - } - } + @Override + public ItemStack getStackInFuelSlot() { + return fuelContents.getStackInSlot(0); + } - //clean-up states - if (stateData.isCraftingCanceled()) { - stateData.setCraftingState(CraftingState.NONE); - stateData.clear(); - } - else if (stateData.getCraftingState() == CraftingState.NONE) { - stateData.clear(); - } + @Override + public void setStackInFuelSlot(ItemStack stack) { + fuelContents.setInventorySlotContents(0, stack); + } - BlockState oldBlockState = world.getBlockState(pos); - BlockState newBlockState = oldBlockState.with(DigesterBlock.CRAFTING, stateData.getCraftingState() == CraftingState.IN_PROGRESS); - if (!newBlockState.equals(oldBlockState)) { - world.setBlockState(pos, newBlockState, Constants.BlockFlags.BLOCK_UPDATE); - markDirty(); - } + @Override + protected boolean doesItemFitIntoOutputInventory(ItemStack stackToCraft) { + return outputContents.doesItemStackFit(0, stackToCraft); } - private boolean craftItems(DigesterRecipe recipeToCraft, Random rand) { + @Override + protected boolean craftRecipe(DigesterRecipe recipeToCraft, World world) { ItemStack result = recipeToCraft.getCraftingResult(inputContents); if (!result.isEmpty() && outputContents.doesItemStackFit(0, result)) { for (int idx = 0; idx < inputContents.getSizeInventory(); idx++) { @@ -188,7 +152,7 @@ private boolean craftItems(DigesterRecipe recipeToCraft, Random rand) { outputContents.insertItemStack(0, result); Byproduct byproduct = recipeToCraft.getByproduct(); - if (byproduct != null && rand.nextFloat() <= byproduct.getChance()) { + if (byproduct != null && world.rand.nextFloat() <= byproduct.getChance()) { ItemStack stack = byproduct.getItemStack(); for (int idx = 1; idx < outputContents.getSizeInventory(); idx++) { //index 0 is reserved for the main crafting output stack = outputContents.insertItemStack(idx, stack); //update stack with remainder @@ -202,23 +166,7 @@ private boolean craftItems(DigesterRecipe recipeToCraft, Random rand) { return false; } - private boolean consumeFuel() { - if (stateData.fuel.getFluidAmount() >= FUEL_COST) { - stateData.fuel.getFluid().shrink(FUEL_COST); - return true; - } - return false; - } - - public static boolean isFluidValidFuel(FluidStack fluidStack) { - return fluidStack.getFluid() == Fluids.WATER; - } - - public static boolean isItemValidFuel(ItemStack stack) { - if (stack.getItem() == Items.POTION && PotionUtils.getPotionFromItem(stack) == Potions.WATER) return true; - return FluidUtil.getFluidContained(stack).map(DigesterTileEntity::isFluidValidFuel).orElse(false); - } - + @Override public void refuel() { int fluidAmount = stateData.fuel.getFluidAmount(); int maxFluidAmount = stateData.fuel.getCapacity(); @@ -253,6 +201,23 @@ public void refuel() { } } + @Override + protected IInventory getInputInventory() { + return inputContents; + } + + @Override + protected ITextComponent getDefaultName() { + return TextUtil.getTranslationText("container", "digester"); + } + + @Nullable + @Override + public Container createMenu(int screenId, PlayerInventory playerInv, PlayerEntity player) { + return DigesterContainer.createServerContainer(screenId, playerInv, fuelContents, fuelOutContents, inputContents, outputContents, stateData); + } + + @Override public void dropAllInvContents(World world, BlockPos pos) { InventoryHelper.dropInventoryItems(world, pos, fuelContents); InventoryHelper.dropInventoryItems(world, pos, fuelOutContents); diff --git a/src/main/java/com/github/elenterius/biomancy/tileentity/EvolutionPoolTileEntity.java b/src/main/java/com/github/elenterius/biomancy/tileentity/EvolutionPoolTileEntity.java index c82b65742..5dd7a7903 100644 --- a/src/main/java/com/github/elenterius/biomancy/tileentity/EvolutionPoolTileEntity.java +++ b/src/main/java/com/github/elenterius/biomancy/tileentity/EvolutionPoolTileEntity.java @@ -1,13 +1,13 @@ package com.github.elenterius.biomancy.tileentity; -import com.github.elenterius.biomancy.block.EvolutionPoolBlock; import com.github.elenterius.biomancy.init.ModBlocks; import com.github.elenterius.biomancy.init.ModItems; import com.github.elenterius.biomancy.init.ModRecipes; import com.github.elenterius.biomancy.init.ModTileEntityTypes; import com.github.elenterius.biomancy.inventory.EvolutionPoolContainer; +import com.github.elenterius.biomancy.inventory.FuelInvContents; import com.github.elenterius.biomancy.inventory.SimpleInvContents; -import com.github.elenterius.biomancy.mixin.RecipeManagerMixinAccessor; +import com.github.elenterius.biomancy.recipe.BioMechanicalRecipeType; import com.github.elenterius.biomancy.recipe.EvolutionPoolRecipe; import com.github.elenterius.biomancy.tileentity.state.CraftingState; import com.github.elenterius.biomancy.tileentity.state.EvolutionPoolStateData; @@ -18,19 +18,14 @@ import net.minecraft.inventory.IInventory; import net.minecraft.inventory.InventoryHelper; import net.minecraft.inventory.container.Container; -import net.minecraft.inventory.container.INamedContainerProvider; import net.minecraft.item.ItemStack; -import net.minecraft.item.crafting.Ingredient; -import net.minecraft.item.crafting.RecipeManager; import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.INBT; import net.minecraft.nbt.ListNBT; import net.minecraft.nbt.LongNBT; -import net.minecraft.tileentity.ITickableTileEntity; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.MathHelper; import net.minecraft.util.text.ITextComponent; import net.minecraft.world.TickPriority; import net.minecraft.world.World; @@ -38,15 +33,14 @@ import net.minecraftforge.common.util.Constants; import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.items.CapabilityItemHandler; -import net.minecraftforge.items.ItemHandlerHelper; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.HashSet; -import java.util.Optional; import java.util.Set; +import java.util.function.Predicate; -public class EvolutionPoolTileEntity extends OwnableTileEntity implements INamedContainerProvider, ITickableTileEntity { +public class EvolutionPoolTileEntity extends MachineTileEntity{ public static final int FUEL_SLOTS_COUNT = 1; public static final int INPUT_SLOTS_COUNT = 6; @@ -55,10 +49,12 @@ public class EvolutionPoolTileEntity extends OwnableTileEntity implements INamed public static final int DEFAULT_TIME = 400; public static final int MAX_FUEL = 32_000; public static final short FUEL_COST = 2; - public static final float FUEL_CONVERSION = FUEL_COST * DEFAULT_TIME / 4f; + public static final float ITEM_FUEL_VALUE = 200; // FUEL_COST * DEFAULT_TIME / 4f + public static final Predicate VALID_FUEL_ITEM = stack -> stack.getItem() == ModItems.MUTAGENIC_BILE.get(); + public static final BioMechanicalRecipeType RECIPE_TYPE = ModRecipes.EVOLUTION_POOL_RECIPE_TYPE; private final EvolutionPoolStateData stateData = new EvolutionPoolStateData(); - private final SimpleInvContents fuelContents; + private final FuelInvContents fuelContents; private final SimpleInvContents inputContents; private final SimpleInvContents outputContents; private final Set subTiles = new HashSet<>(); @@ -66,38 +62,88 @@ public class EvolutionPoolTileEntity extends OwnableTileEntity implements INamed public EvolutionPoolTileEntity() { super(ModTileEntityTypes.EVOLUTION_POOL.get()); - fuelContents = SimpleInvContents.createServerContents(FUEL_SLOTS_COUNT, this::canPlayerOpenInv, this::markDirty); + fuelContents = FuelInvContents.createServerContents(FUEL_SLOTS_COUNT, this::isItemValidFuel, this::canPlayerOpenInv, this::markDirty); inputContents = SimpleInvContents.createServerContents(INPUT_SLOTS_COUNT, this::canPlayerOpenInv, this::markDirty); outputContents = SimpleInvContents.createServerContents(OUTPUT_SLOTS_COUNT, SimpleInvContents.ISHandlerType.NO_INSERT, this::canPlayerOpenInv, this::markDirty); } - public static Optional getRecipeForItem(World world, ItemStack stackIn) { - RecipeManagerMixinAccessor recipeManager = (RecipeManagerMixinAccessor) world.getRecipeManager(); + @Override + protected EvolutionPoolStateData getStateData() { + return stateData; + } - return recipeManager.callGetRecipes(ModRecipes.EVOLUTION_POOL_RECIPE_TYPE).values().stream().map((recipe) -> (EvolutionPoolRecipe) recipe) - .filter(recipe -> { - for (Ingredient ingredient : recipe.getIngredients()) { - if (ingredient.test(stackIn)) return true; - } - return false; - }).findFirst(); + @Override + public BioMechanicalRecipeType getRecipeType() { + return RECIPE_TYPE; } - public static boolean areRecipesEqual(EvolutionPoolRecipe recipeA, EvolutionPoolRecipe recipeB, boolean relaxed) { - boolean flag = recipeA.getId().equals(recipeB.getId()); - if (!relaxed && !ItemHandlerHelper.canItemStacksStack(recipeA.getRecipeOutput(), recipeB.getRecipeOutput())) { - return false; - } - return flag; + @Override + public int getFuelAmount() { + return stateData.fuel; + } + + @Override + public void setFuelAmount(int newAmount) { + stateData.fuel = (short) newAmount; + } + + @Override + public void addFuelAmount(int addAmount) { + stateData.fuel += addAmount; + } + + @Override + public int getMaxFuelAmount() { + return MAX_FUEL; + } + + @Override + public int getFuelCost() { + return FUEL_COST; + } + + @Override + public boolean isItemValidFuel(ItemStack stack) { + return VALID_FUEL_ITEM.test(stack); + } + + @Override + public float getItemFuelValue(ItemStack stackIn) { + return ITEM_FUEL_VALUE; } - public static Optional getRecipeForInput(World world, IInventory inputInv) { - RecipeManager recipeManager = world.getRecipeManager(); - return recipeManager.getRecipe(ModRecipes.EVOLUTION_POOL_RECIPE_TYPE, inputInv, world); + @Override + public ItemStack getStackInFuelSlot() { + return fuelContents.getStackInSlot(0); + } + + @Override + public void setStackInFuelSlot(ItemStack stack) { + fuelContents.setInventorySlotContents(0, stack); } - public static boolean isItemValidFuel(ItemStack stack) { - return stack.getItem() == ModItems.MUTAGENIC_BILE.get(); + @Override + protected boolean doesItemFitIntoOutputInventory(ItemStack stackToCraft) { + return outputContents.doesItemStackFit(0, stackToCraft); + } + + @Override + protected boolean craftRecipe(EvolutionPoolRecipe recipeToCraft, World world) { + ItemStack result = recipeToCraft.getCraftingResult(inputContents); + if (!result.isEmpty() && outputContents.doesItemStackFit(0, result)) { + for (int idx = 0; idx < inputContents.getSizeInventory(); idx++) { + inputContents.decrStackSize(idx, 1); + } + outputContents.insertItemStack(0, result); + markDirty(); + return true; + } + return false; + } + + @Override + protected IInventory getInputInventory() { + return inputContents; } @Override @@ -213,75 +259,19 @@ public boolean validateSubTile(World worldIn, BlockPos posIn) { @Override public void tick() { if (world == null || world.isRemote || !isValidMultiBlock) return; + super.tick(); + } - if (world.getGameTime() % 10L == 0L) { - refuel(); - } - - EvolutionPoolRecipe recipeToCraft = getRecipeForInput(world, inputContents).orElse(null); - if (recipeToCraft == null) { - stateData.cancelCrafting(); - } - else { - ItemStack itemToCraft = recipeToCraft.getRecipeOutput().copy(); - if (itemToCraft.isEmpty()) { - stateData.cancelCrafting(); - } - else { - if (outputContents.doesItemStackFit(0, itemToCraft)) { - if (stateData.getCraftingState() == CraftingState.NONE) { - stateData.setCraftingState(CraftingState.IN_PROGRESS); - stateData.clear(); //safe guard, shouldn't be needed - stateData.setCraftingGoalRecipe(recipeToCraft); // this also sets the time required for crafting - } - else if (!stateData.isCraftingCanceled()) { - EvolutionPoolRecipe recipeCraftingGoal = stateData.getCraftingGoalRecipe(world).orElse(null); - if (recipeCraftingGoal == null || !areRecipesEqual(recipeToCraft, recipeCraftingGoal, true)) { - stateData.cancelCrafting(); - } - } - } - else { - if (stateData.getCraftingState() != CraftingState.COMPLETED) stateData.cancelCrafting(); - } - } - - //change crafting progress - if (stateData.getCraftingState() == CraftingState.IN_PROGRESS) { - if (consumeFuel()) stateData.timeElapsed += 1; - else stateData.timeElapsed -= 2; - - if (stateData.timeElapsed < 0) stateData.timeElapsed = 0; - } - - //craft items - if (stateData.getCraftingState() == CraftingState.IN_PROGRESS || stateData.getCraftingState() == CraftingState.COMPLETED) { - if (stateData.timeElapsed >= stateData.timeForCompletion) { - stateData.setCraftingState(CraftingState.COMPLETED); - if (craftItem(recipeToCraft)) { - stateData.setCraftingState(CraftingState.NONE); - } - } - } - } - - //clean-up states - if (stateData.isCraftingCanceled()) { - stateData.setCraftingState(CraftingState.NONE); - stateData.clear(); - } - else if (stateData.getCraftingState() == CraftingState.NONE) { - stateData.clear(); - } - - updateMultiBlockStates(world, stateData.getCraftingState() == CraftingState.IN_PROGRESS); + @Override + protected void updateBlockState(World world, EvolutionPoolStateData tileState, boolean powerBlock) { + updateMultiBlockStates(world, tileState.getCraftingState() == CraftingState.IN_PROGRESS); } private void updateMultiBlockStates(World worldIn, boolean isCraftingInProgress) { boolean isDirty = false; BlockState oldBlockState = worldIn.getBlockState(pos); - BlockState newBlockState = oldBlockState.with(EvolutionPoolBlock.CRAFTING, isCraftingInProgress); + BlockState newBlockState = oldBlockState.with(getIsCraftingBlockStateProperty(), isCraftingInProgress); if (!newBlockState.equals(oldBlockState)) { worldIn.setBlockState(pos, newBlockState, Constants.BlockFlags.BLOCK_UPDATE); isDirty = true; @@ -289,7 +279,7 @@ private void updateMultiBlockStates(World worldIn, boolean isCraftingInProgress) for (BlockPos subPos : subTiles) { oldBlockState = worldIn.getBlockState(subPos); - newBlockState = oldBlockState.with(EvolutionPoolBlock.CRAFTING, isCraftingInProgress); + newBlockState = oldBlockState.with(getIsCraftingBlockStateProperty(), isCraftingInProgress); if (!newBlockState.equals(oldBlockState)) { worldIn.setBlockState(subPos, newBlockState, Constants.BlockFlags.BLOCK_UPDATE); isDirty = true; @@ -299,54 +289,7 @@ private void updateMultiBlockStates(World worldIn, boolean isCraftingInProgress) if (isDirty) markDirty(); } - private boolean consumeFuel() { - if (stateData.fuel >= FUEL_COST) { - stateData.fuel -= FUEL_COST; - return true; - } - return false; - } - - private boolean craftItem(EvolutionPoolRecipe recipeToCraft) { - ItemStack result = recipeToCraft.getCraftingResult(inputContents); - if (!result.isEmpty() && outputContents.doesItemStackFit(0, result)) { - for (int idx = 0; idx < inputContents.getSizeInventory(); idx++) { - inputContents.decrStackSize(idx, 1); - } - outputContents.insertItemStack(0, result); - markDirty(); - return true; - } - return false; - } - - public void refuel() { - if (stateData.fuel < MAX_FUEL) { - ItemStack stack = fuelContents.getStackInSlot(0); - if (isItemValidFuel(stack)) { - ItemStack remainder = addFuel(stack); - if (remainder.getCount() != stack.getCount()) { - fuelContents.setInventorySlotContents(0, remainder); - markDirty(); - } - } - } - } - - public ItemStack addFuel(ItemStack stackIn) { - if (world == null || world.isRemote()) return stackIn; - - if (!stackIn.isEmpty() && stateData.fuel < MAX_FUEL) { - int itemsNeeded = Math.round(Math.max(0, MAX_FUEL - stateData.fuel) / FUEL_CONVERSION); - int consumeAmount = Math.min(stackIn.getCount(), itemsNeeded); - if (consumeAmount > 0) { - stateData.fuel = (short) MathHelper.clamp(stateData.fuel + FUEL_CONVERSION * consumeAmount, 0, MAX_FUEL + FUEL_CONVERSION); - return ItemHandlerHelper.copyStackWithSize(stackIn, stackIn.getCount() - consumeAmount); - } - } - return stackIn; - } - + @Override public void dropAllInvContents(World world, BlockPos pos) { InventoryHelper.dropInventoryItems(world, pos, fuelContents); InventoryHelper.dropInventoryItems(world, pos, inputContents); diff --git a/src/main/java/com/github/elenterius/biomancy/tileentity/MachineTileEntity.java b/src/main/java/com/github/elenterius/biomancy/tileentity/MachineTileEntity.java new file mode 100644 index 000000000..21d890450 --- /dev/null +++ b/src/main/java/com/github/elenterius/biomancy/tileentity/MachineTileEntity.java @@ -0,0 +1,205 @@ +package com.github.elenterius.biomancy.tileentity; + +import com.github.elenterius.biomancy.block.MachineBlock; +import com.github.elenterius.biomancy.recipe.AbstractBioMechanicalRecipe; +import com.github.elenterius.biomancy.recipe.BioMechanicalRecipeType; +import com.github.elenterius.biomancy.tileentity.state.CraftingState; +import com.github.elenterius.biomancy.tileentity.state.RecipeCraftingStateData; +import net.minecraft.block.BlockState; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.container.INamedContainerProvider; +import net.minecraft.item.ItemStack; +import net.minecraft.state.BooleanProperty; +import net.minecraft.tileentity.ITickableTileEntity; +import net.minecraft.tileentity.TileEntityType; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.world.World; +import net.minecraftforge.common.util.Constants; +import net.minecraftforge.items.ItemHandlerHelper; + +import javax.annotation.Nullable; + +public abstract class MachineTileEntity> extends OwnableTileEntity implements INamedContainerProvider, ITickableTileEntity { + + public MachineTileEntity(TileEntityType entityType) { + super(entityType); + } + + protected abstract S getStateData(); + + public abstract BioMechanicalRecipeType getRecipeType(); + + public abstract int getFuelAmount(); + + public abstract void setFuelAmount(int newAmount); + + public abstract void addFuelAmount(int addAmount); + + public abstract int getMaxFuelAmount(); + + public abstract int getFuelCost(); + + public abstract boolean isItemValidFuel(ItemStack stack); + + public abstract float getItemFuelValue(ItemStack stackIn); + + public abstract ItemStack getStackInFuelSlot(); + + public abstract void setStackInFuelSlot(ItemStack stack); + + protected abstract boolean doesItemFitIntoOutputInventory(ItemStack stackToCraft); + + protected abstract boolean craftRecipe(R recipeToCraft, World world); + + @Nullable + protected R resolveRecipeFromInventory(World world, IInventory inputInv) { + return getRecipeType().getRecipeFromInventory(world, inputInv).orElse(null); + } + + protected abstract IInventory getInputInventory(); + + public abstract void dropAllInvContents(World world, BlockPos pos); + + public boolean consumeFuel() { + int fuelCost = getFuelCost(); + if (getFuelAmount() >= fuelCost) { + addFuelAmount(-fuelCost); + return true; + } + return false; + } + + public void refuel() { + if (getFuelAmount() < getMaxFuelAmount()) { + ItemStack stack = getStackInFuelSlot(); + if (isItemValidFuel(stack)) { + ItemStack remainder = addFuel(stack); + if (remainder.getCount() != stack.getCount()) { + setStackInFuelSlot(remainder); + markDirty(); + } + } + } + } + + public ItemStack addFuel(ItemStack stackIn) { + if (world == null || world.isRemote()) return stackIn; + + if (!stackIn.isEmpty() && getFuelAmount() < getMaxFuelAmount()) { + float itemFuelValue = getItemFuelValue(stackIn); + if (itemFuelValue <= 0f) return stackIn; + + int itemsNeeded = Math.round(Math.max(0, getMaxFuelAmount() - getFuelAmount()) / itemFuelValue); + int consumeAmount = Math.min(stackIn.getCount(), itemsNeeded); + if (consumeAmount > 0) { + short newFuel = (short) MathHelper.clamp(getFuelAmount() + itemFuelValue * consumeAmount, 0, getMaxFuelAmount() + itemFuelValue); + setFuelAmount(newFuel); + return ItemHandlerHelper.copyStackWithSize(stackIn, stackIn.getCount() - consumeAmount); + } + } + return stackIn; + } + + @Override + public void tick() { + if (world == null || world.isRemote) return; + + if (world.getGameTime() % 10L == 0L) { + refuel(); + } + + R craftingGoal = resolveRecipeFromInventory(world, getInputInventory()); //get the currently possible crafting goal + S state = getStateData(); + boolean emitRedstoneSignal = false; + if (craftingGoal == null) { + state.cancelCrafting(); + } + else { + ItemStack itemToCraft = craftingGoal.getRecipeOutput(); // this should be a ItemStack.copy() + if (itemToCraft.isEmpty()) { + state.cancelCrafting(); + } + else { + if (doesItemFitIntoOutputInventory(itemToCraft)) { + if (state.getCraftingState() == CraftingState.NONE) { // nothing is being crafted, try to start crafting + int totalFuelCost = craftingGoal.getCraftingTime() * getFuelCost(); + if (getFuelAmount() >= totalFuelCost) { //make sure there is enough fuel to craft the recipe + state.setCraftingState(CraftingState.IN_PROGRESS); + state.clear(); //safe guard, shouldn't be needed + state.setCraftingGoalRecipe(craftingGoal); // this also sets the time required for crafting + } + } + else if (!state.isCraftingCanceled()) { // something is being crafted, check that the crafting goals match + R prevCraftingGoal = state.getCraftingGoalRecipe(world).orElse(null); + if (prevCraftingGoal == null || !craftingGoal.areRecipesEqual(prevCraftingGoal, true)) { + state.cancelCrafting(); + } + } + } + else { + if (state.getCraftingState() != CraftingState.COMPLETED) { + state.cancelCrafting(); + } + } + } + + //change crafting progress + if (state.getCraftingState() == CraftingState.IN_PROGRESS) { + if (consumeFuel()) state.timeElapsed += 1; + else state.timeElapsed -= 2; + + if (state.timeElapsed < 0) state.timeElapsed = 0; + } + + //craft the recipe output + if (state.getCraftingState() == CraftingState.IN_PROGRESS || state.getCraftingState() == CraftingState.COMPLETED) { + if (state.timeElapsed >= state.timeForCompletion) { + state.setCraftingState(CraftingState.COMPLETED); + if (craftRecipe(craftingGoal, world)) { + emitRedstoneSignal = true; + state.setCraftingState(CraftingState.NONE); + } + } + } + } + + //clean-up states + if (state.isCraftingCanceled()) { + state.setCraftingState(CraftingState.NONE); + state.clear(); + } + else if (state.getCraftingState() == CraftingState.NONE) { + state.clear(); + } + + //update BlockState to reflect tile state + updateBlockState(world, state, emitRedstoneSignal); + } + + protected BooleanProperty getIsCraftingBlockStateProperty() { + return MachineBlock.CRAFTING; + } + + protected void updateBlockState(World world, S tileState, boolean redstoneSignal) { + BlockState oldBlockState = world.getBlockState(pos); + BlockState newBlockState = oldBlockState.with(getIsCraftingBlockStateProperty(), tileState.getCraftingState() == CraftingState.IN_PROGRESS); + if (!newBlockState.equals(oldBlockState)) { + if (redstoneSignal) { + if (newBlockState.getBlock() instanceof MachineBlock) { + ((MachineBlock) newBlockState.getBlock()).powerBlock(world, pos, newBlockState); + } + } + else { + world.setBlockState(pos, newBlockState, Constants.BlockFlags.BLOCK_UPDATE); + } + markDirty(); + } + else if (redstoneSignal) { + if (newBlockState.getBlock() instanceof MachineBlock) { + ((MachineBlock) newBlockState.getBlock()).powerBlock(world, pos, oldBlockState); + } + } + } + +} diff --git a/src/main/java/com/github/elenterius/biomancy/tileentity/state/ChewerStateData.java b/src/main/java/com/github/elenterius/biomancy/tileentity/state/ChewerStateData.java index 1f70a651c..3e070066a 100644 --- a/src/main/java/com/github/elenterius/biomancy/tileentity/state/ChewerStateData.java +++ b/src/main/java/com/github/elenterius/biomancy/tileentity/state/ChewerStateData.java @@ -2,20 +2,12 @@ import com.github.elenterius.biomancy.recipe.ChewerRecipe; import net.minecraft.nbt.CompoundNBT; -import net.minecraft.util.IIntArray; -public class ChewerStateData extends RecipeCraftingStateData implements IIntArray { +public class ChewerStateData extends RecipeCraftingStateData { - public static final String NBT_KEY_TIME_ELAPSED = "TimeElapsed"; - public static final String NBT_KEY_TIME_FOR_COMPLETION = "TimeForCompletion"; public static final String NBT_KEY_FUEL = "Fuel"; - - public static final int TIME_INDEX = 0; - public static final int TIME_FOR_COMPLETION_INDEX = 1; public static final int FUEL_INDEX = 2; - public int timeElapsed; - public int timeForCompletion; public short fuel; //biofuel (nutrient paste) @Override @@ -23,39 +15,18 @@ Class getRecipeType() { return ChewerRecipe.class; } - @Override - public void setCraftingGoalRecipe(ChewerRecipe recipe) { - super.setCraftingGoalRecipe(recipe); - timeForCompletion = recipe.getCraftingTime(); - } - - @Override - public void clear() { - timeElapsed = 0; - timeForCompletion = 0; - super.clear(); - } - @Override public void serializeNBT(CompoundNBT nbt) { super.serializeNBT(nbt); - nbt.putInt(NBT_KEY_TIME_ELAPSED, timeElapsed); - nbt.putInt(NBT_KEY_TIME_FOR_COMPLETION, timeForCompletion); nbt.putShort(NBT_KEY_FUEL, fuel); } @Override public void deserializeNBT(CompoundNBT nbt) { super.deserializeNBT(nbt); - timeElapsed = nbt.getInt(NBT_KEY_TIME_ELAPSED); - timeForCompletion = nbt.getInt(NBT_KEY_TIME_FOR_COMPLETION); fuel = nbt.getShort(NBT_KEY_FUEL); } - private void validateIndex(int index) { - if (index < 0 || index >= size()) throw new IndexOutOfBoundsException("Index out of bounds:" + index); - } - @Override public int get(int index) { validateIndex(index); diff --git a/src/main/java/com/github/elenterius/biomancy/tileentity/state/DecomposerStateData.java b/src/main/java/com/github/elenterius/biomancy/tileentity/state/DecomposerStateData.java index 07f2ab1bd..0d39e3baf 100644 --- a/src/main/java/com/github/elenterius/biomancy/tileentity/state/DecomposerStateData.java +++ b/src/main/java/com/github/elenterius/biomancy/tileentity/state/DecomposerStateData.java @@ -2,23 +2,16 @@ import com.github.elenterius.biomancy.recipe.DecomposerRecipe; import net.minecraft.nbt.CompoundNBT; -import net.minecraft.util.IIntArray; -public class DecomposerStateData extends RecipeCraftingStateData implements IIntArray { +public class DecomposerStateData extends RecipeCraftingStateData { - public static final int TIME_INDEX = 0; - public static final int TIME_FOR_COMPLETION_INDEX = 1; public static final int FUEL_INDEX = 2; public static final int SPEED_FUEL_INDEX = 3; - public static final String NBT_KEY_TIME_ELAPSED = "TimeElapsed"; - public static final String NBT_KEY_TIME_FOR_COMPLETION = "TimeForCompletion"; public static final String NBT_KEY_MAIN_FUEL = "MainFuel"; public static final String NBT_KEY_SPEED_FUEL = "SpeedFuel"; - public int timeElapsed; - public int timeForCompletion; - public short mainFuel; //raw-meat (fake "saturation", we use the food healing value instead) + public short fuel; //raw-meat (fake "saturation", we use the food healing value instead) public short speedFuel; //glucose ("candy", food that contains sugar) @Override @@ -26,34 +19,17 @@ Class getRecipeType() { return DecomposerRecipe.class; } - @Override - public void setCraftingGoalRecipe(DecomposerRecipe recipe) { - super.setCraftingGoalRecipe(recipe); - timeForCompletion = recipe.getDecomposingTime(); - } - - @Override - public void clear() { - timeElapsed = 0; - timeForCompletion = 0; - super.clear(); - } - @Override public void serializeNBT(CompoundNBT nbt) { super.serializeNBT(nbt); - if (timeElapsed > 0) nbt.putInt(NBT_KEY_TIME_ELAPSED, timeElapsed); - if (timeForCompletion > 0) nbt.putInt(NBT_KEY_TIME_FOR_COMPLETION, timeForCompletion); - if (mainFuel > 0) nbt.putShort(NBT_KEY_MAIN_FUEL, mainFuel); + if (fuel > 0) nbt.putShort(NBT_KEY_MAIN_FUEL, fuel); if (speedFuel > 0) nbt.putShort(NBT_KEY_SPEED_FUEL, speedFuel); } @Override public void deserializeNBT(CompoundNBT nbt) { super.deserializeNBT(nbt); - timeElapsed = nbt.getInt(NBT_KEY_TIME_ELAPSED); - timeForCompletion = nbt.getInt(NBT_KEY_TIME_FOR_COMPLETION); - mainFuel = nbt.getShort(NBT_KEY_MAIN_FUEL); + fuel = nbt.getShort(NBT_KEY_MAIN_FUEL); speedFuel = nbt.getShort(NBT_KEY_SPEED_FUEL); } @@ -62,7 +38,7 @@ public int get(int index) { validateIndex(index); if (index == TIME_INDEX) return timeElapsed; else if (index == TIME_FOR_COMPLETION_INDEX) return timeForCompletion; - else if (index == FUEL_INDEX) return mainFuel; + else if (index == FUEL_INDEX) return fuel; else if (index == SPEED_FUEL_INDEX) return speedFuel; else return 0; } @@ -72,14 +48,10 @@ public void set(int index, int value) { validateIndex(index); if (index == TIME_INDEX) timeElapsed = value; else if (index == TIME_FOR_COMPLETION_INDEX) timeForCompletion = value; - else if (index == FUEL_INDEX) mainFuel = (short) value; + else if (index == FUEL_INDEX) fuel = (short) value; else if (index == SPEED_FUEL_INDEX) speedFuel = (short) value; } - private void validateIndex(int index) { - if (index < 0 || index >= size()) throw new IndexOutOfBoundsException("Index out of bounds:" + index); - } - @Override public int size() { return 4; diff --git a/src/main/java/com/github/elenterius/biomancy/tileentity/state/DigesterStateData.java b/src/main/java/com/github/elenterius/biomancy/tileentity/state/DigesterStateData.java index 1538274db..543997592 100644 --- a/src/main/java/com/github/elenterius/biomancy/tileentity/state/DigesterStateData.java +++ b/src/main/java/com/github/elenterius/biomancy/tileentity/state/DigesterStateData.java @@ -4,25 +4,16 @@ import com.github.elenterius.biomancy.tileentity.DigesterTileEntity; import net.minecraft.fluid.Fluids; import net.minecraft.nbt.CompoundNBT; -import net.minecraft.util.IIntArray; import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.fluids.capability.templates.FluidTank; -public class DigesterStateData extends RecipeCraftingStateData implements IIntArray { +public class DigesterStateData extends RecipeCraftingStateData { - public static final String NBT_KEY_TIME_ELAPSED = "TimeElapsed"; - public static final String NBT_KEY_TIME_FOR_COMPLETION = "TimeForCompletion"; public static final String NBT_KEY_FUEL = "Fuel"; - - public static final int TIME_INDEX = 0; - public static final int TIME_FOR_COMPLETION_INDEX = 1; public static final int FUEL_INDEX = 2; - public int timeElapsed; - public int timeForCompletion; - public FluidTank fuel = new FluidTank(DigesterTileEntity.MAX_FUEL, fluidStack -> fluidStack.getFluid() == Fluids.WATER); private final LazyOptional optionalFluidHandler = LazyOptional.of(() -> fuel); @@ -35,39 +26,18 @@ Class getRecipeType() { return DigesterRecipe.class; } - @Override - public void setCraftingGoalRecipe(DigesterRecipe recipe) { - super.setCraftingGoalRecipe(recipe); - timeForCompletion = recipe.getCraftingTime(); - } - - @Override - public void clear() { - timeElapsed = 0; - timeForCompletion = 0; - super.clear(); - } - @Override public void serializeNBT(CompoundNBT nbt) { super.serializeNBT(nbt); - nbt.putInt(NBT_KEY_TIME_ELAPSED, timeElapsed); - nbt.putInt(NBT_KEY_TIME_FOR_COMPLETION, timeForCompletion); nbt.put(NBT_KEY_FUEL, fuel.writeToNBT(new CompoundNBT())); } @Override public void deserializeNBT(CompoundNBT nbt) { super.deserializeNBT(nbt); - timeElapsed = nbt.getInt(NBT_KEY_TIME_ELAPSED); - timeForCompletion = nbt.getInt(NBT_KEY_TIME_FOR_COMPLETION); fuel.readFromNBT(nbt.getCompound(NBT_KEY_FUEL)); } - private void validateIndex(int index) { - if (index < 0 || index >= size()) throw new IndexOutOfBoundsException("Index out of bounds:" + index); - } - @Override public int get(int index) { validateIndex(index); diff --git a/src/main/java/com/github/elenterius/biomancy/tileentity/state/EvolutionPoolStateData.java b/src/main/java/com/github/elenterius/biomancy/tileentity/state/EvolutionPoolStateData.java index c72a4d967..fcbb54e77 100644 --- a/src/main/java/com/github/elenterius/biomancy/tileentity/state/EvolutionPoolStateData.java +++ b/src/main/java/com/github/elenterius/biomancy/tileentity/state/EvolutionPoolStateData.java @@ -2,20 +2,11 @@ import com.github.elenterius.biomancy.recipe.EvolutionPoolRecipe; import net.minecraft.nbt.CompoundNBT; -import net.minecraft.util.IIntArray; -public class EvolutionPoolStateData extends RecipeCraftingStateData implements IIntArray { +public class EvolutionPoolStateData extends RecipeCraftingStateData { - public static final int TIME_INDEX = 0; - public static final int TIME_FOR_COMPLETION_INDEX = 1; public static final int FUEL_INDEX = 2; - - public static final String NBT_KEY_TIME_ELAPSED = "TimeElapsed"; - public static final String NBT_KEY_TIME_FOR_COMPLETION = "TimeForCompletion"; public static final String NBT_KEY_FUEL = "Fuel"; - - public int timeElapsed; - public int timeForCompletion; public short fuel; //mutagenic bile @Override @@ -23,39 +14,18 @@ Class getRecipeType() { return EvolutionPoolRecipe.class; } - @Override - public void setCraftingGoalRecipe(EvolutionPoolRecipe recipe) { - super.setCraftingGoalRecipe(recipe); - timeForCompletion = recipe.getCraftingTime(); - } - - @Override - public void clear() { - timeElapsed = 0; - timeForCompletion = 0; - super.clear(); - } - @Override public void serializeNBT(CompoundNBT nbt) { super.serializeNBT(nbt); - nbt.putInt(NBT_KEY_TIME_ELAPSED, timeElapsed); - nbt.putInt(NBT_KEY_TIME_FOR_COMPLETION, timeForCompletion); nbt.putShort(NBT_KEY_FUEL, fuel); } @Override public void deserializeNBT(CompoundNBT nbt) { super.deserializeNBT(nbt); - timeElapsed = nbt.getInt(NBT_KEY_TIME_ELAPSED); - timeForCompletion = nbt.getInt(NBT_KEY_TIME_FOR_COMPLETION); fuel = nbt.getShort(NBT_KEY_FUEL); } - private void validateIndex(int index) { - if (index < 0 || index >= size()) throw new IndexOutOfBoundsException("Index out of bounds:" + index); - } - @Override public int get(int index) { validateIndex(index); diff --git a/src/main/java/com/github/elenterius/biomancy/tileentity/state/RecipeCraftingStateData.java b/src/main/java/com/github/elenterius/biomancy/tileentity/state/RecipeCraftingStateData.java index 9ecaa1f0d..5c7e25725 100644 --- a/src/main/java/com/github/elenterius/biomancy/tileentity/state/RecipeCraftingStateData.java +++ b/src/main/java/com/github/elenterius/biomancy/tileentity/state/RecipeCraftingStateData.java @@ -1,16 +1,26 @@ package com.github.elenterius.biomancy.tileentity.state; +import com.github.elenterius.biomancy.recipe.AbstractBioMechanicalRecipe; import net.minecraft.item.crafting.IRecipe; import net.minecraft.item.crafting.RecipeManager; import net.minecraft.nbt.CompoundNBT; +import net.minecraft.util.IIntArray; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; import java.util.Optional; -public abstract class RecipeCraftingStateData> { +public abstract class RecipeCraftingStateData implements IIntArray { public static final String NBT_KEY_RECIPE_ID = "RecipeId"; + public static final String NBT_KEY_TIME_ELAPSED = "TimeElapsed"; + public static final String NBT_KEY_TIME_FOR_COMPLETION = "TimeForCompletion"; + + public static final int TIME_INDEX = 0; + public static final int TIME_FOR_COMPLETION_INDEX = 1; + + public int timeElapsed; + public int timeForCompletion; private CraftingState craftingState = CraftingState.NONE; private ResourceLocation recipeId; //we don't store the recipe reference, this way we don't have to check if the recipe was changed in the meantime @@ -52,10 +62,13 @@ public Optional getCraftingGoalRecipe(World world) { public void setCraftingGoalRecipe(T recipe) { recipeId = recipe.getId(); + timeForCompletion = recipe.getCraftingTime(); } public void clear() { recipeId = null; + timeElapsed = 0; + timeForCompletion = 0; } public void serializeNBT(CompoundNBT nbt) { @@ -63,6 +76,8 @@ public void serializeNBT(CompoundNBT nbt) { if (recipeId != null) { nbt.putString(NBT_KEY_RECIPE_ID, recipeId.toString()); } + nbt.putInt(NBT_KEY_TIME_ELAPSED, timeElapsed); + nbt.putInt(NBT_KEY_TIME_FOR_COMPLETION, timeForCompletion); } public void deserializeNBT(CompoundNBT nbt) { @@ -72,6 +87,32 @@ public void deserializeNBT(CompoundNBT nbt) { recipeId = ResourceLocation.tryCreate(id); } else recipeId = null; + timeElapsed = nbt.getInt(NBT_KEY_TIME_ELAPSED); + timeForCompletion = nbt.getInt(NBT_KEY_TIME_FOR_COMPLETION); } + protected void validateIndex(int index) { + if (index < 0 || index >= size()) throw new IndexOutOfBoundsException("Index out of bounds:" + index); + } + + @Override + public int get(int index) { + validateIndex(index); + if (index == TIME_INDEX) return timeElapsed; + else if (index == TIME_FOR_COMPLETION_INDEX) return timeForCompletion; + return 0; + } + + @Override + public void set(int index, int value) { + validateIndex(index); + if (index == TIME_INDEX) timeElapsed = value; + else if (index == TIME_FOR_COMPLETION_INDEX) timeForCompletion = value; + } + + @Override + public int size() { + return 2; + }; + } diff --git a/src/main/java/com/github/elenterius/biomancy/util/BiofuelUtil.java b/src/main/java/com/github/elenterius/biomancy/util/BiofuelUtil.java new file mode 100644 index 000000000..918513215 --- /dev/null +++ b/src/main/java/com/github/elenterius/biomancy/util/BiofuelUtil.java @@ -0,0 +1,30 @@ +package com.github.elenterius.biomancy.util; + +import com.github.elenterius.biomancy.init.ModItems; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; + +import java.util.function.Predicate; + +public final class BiofuelUtil { + + private BiofuelUtil() {} + + public static short DEFAULT_FUEL_VALUE = 200; + public static byte NUTRIENT_PASTE_MULTIPLIER = 1; + public static byte NUTRIENT_BAR_MULTIPLIER = 6; + + public static final Predicate VALID_SOLID_FUEL = stack -> stack.getItem() == ModItems.NUTRIENT_PASTE.get() || stack.getItem() == ModItems.NUTRIENT_BAR.get(); + + public static boolean isItemValidFuel(ItemStack stackIn) { + return VALID_SOLID_FUEL.test(stackIn); + } + + public static float getItemFuelValue(ItemStack stackIn) { + Item item = stackIn.getItem(); + if (item == ModItems.NUTRIENT_BAR.get()) return DEFAULT_FUEL_VALUE * NUTRIENT_BAR_MULTIPLIER; + if (item == ModItems.NUTRIENT_PASTE.get()) return DEFAULT_FUEL_VALUE * NUTRIENT_PASTE_MULTIPLIER; + return 0; + } + +} diff --git a/src/main/java/com/github/elenterius/biomancy/util/ClientTextUtil.java b/src/main/java/com/github/elenterius/biomancy/util/ClientTextUtil.java index 3d49e33ae..03a99fb7d 100644 --- a/src/main/java/com/github/elenterius/biomancy/util/ClientTextUtil.java +++ b/src/main/java/com/github/elenterius/biomancy/util/ClientTextUtil.java @@ -1,7 +1,7 @@ package com.github.elenterius.biomancy.util; import com.github.elenterius.biomancy.init.ClientSetupHandler; -import com.github.elenterius.biomancy.mixin.client.ItemStackMixinAccessor; +import com.github.elenterius.biomancy.mixin.client.ClientItemStackMixinAccessor; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screen.Screen; import net.minecraft.entity.player.PlayerEntity; @@ -68,11 +68,11 @@ public static IFormattableTextComponent getDefaultKey() { public static int getHideFlags(ItemStack stack) { //noinspection ConstantConditions - return ((ItemStackMixinAccessor) (Object) stack).getHideFlags(); + return ((ClientItemStackMixinAccessor) (Object) stack).biomancy_getHideFlags(); } public static boolean isToolTipVisible(ItemStack stack, ItemStack.TooltipDisplayFlags flags) { - return ItemStackMixinAccessor.isToolTipVisible(getHideFlags(stack), flags); + return ClientItemStackMixinAccessor.biomancy_isToolTipVisible(getHideFlags(stack), flags); } public static void setTooltipVisible(ItemStack stack, ItemStack.TooltipDisplayFlags tooltipDisplay) { diff --git a/src/main/java/com/github/elenterius/biomancy/util/MobUtil.java b/src/main/java/com/github/elenterius/biomancy/util/MobUtil.java new file mode 100644 index 000000000..de9c965d1 --- /dev/null +++ b/src/main/java/com/github/elenterius/biomancy/util/MobUtil.java @@ -0,0 +1,61 @@ +package com.github.elenterius.biomancy.util; + +import net.minecraft.entity.*; +import net.minecraft.world.server.ServerWorld; +import net.minecraftforge.event.ForgeEventFactory; + +import java.util.function.BiConsumer; + +public final class MobUtil { + + private MobUtil() {} + + public static boolean convertMobEntityTo(ServerWorld world, E entityIn, EntityType outcomeType) { + return convertMobEntityTo(world, entityIn, outcomeType, true); + } + + public static boolean convertMobEntityTo(ServerWorld world, E entityIn, EntityType outcomeType, boolean copyEquipment) { + return convertMobEntityTo(world, entityIn, outcomeType, copyEquipment, (oldEntity, outcome) -> {}); + } + + public static boolean convertMobEntityTo(ServerWorld world, E oldEntity, EntityType outcomeType, boolean copyEquipment, BiConsumer onConvert) { + if (ForgeEventFactory.canLivingConvert(oldEntity, outcomeType, (timer) -> {})) { + T newEntity = oldEntity.func_233656_b_(outcomeType, copyEquipment);// create new entity with same settings & equipment and remove old entity + if (newEntity != null) { + newEntity.onInitialSpawn(world, world.getDifficultyForLocation(oldEntity.getPosition()), SpawnReason.CONVERSION, null, null); + newEntity.hurtResistantTime = 60; + onConvert.accept(oldEntity, newEntity); + ForgeEventFactory.onLivingConvert(oldEntity, newEntity); + return true; + } + } + return false; + } + + public static boolean convertLivingEntityTo(ServerWorld world, LivingEntity oldEntity, EntityType outcomeType) { + if (oldEntity.removed) return false; + + Entity entity = outcomeType.create(world); + if (entity != null) { + if (entity instanceof LivingEntity) { + //noinspection unchecked + EntityType entityType = (EntityType) outcomeType; + if (ForgeEventFactory.canLivingConvert(oldEntity, entityType, (timer) -> {})) { + entity.copyLocationAndAnglesFrom(oldEntity); + oldEntity.remove(); + world.addEntity(entity); + if (entity instanceof MobEntity) { + ((MobEntity) entity).onInitialSpawn(world, world.getDifficultyForLocation(oldEntity.getPosition()), SpawnReason.CONVERSION, null, null); + } + entity.hurtResistantTime = 60; + ForgeEventFactory.onLivingConvert(oldEntity, (LivingEntity) entity); + return true; + } + } + + entity.remove(); + } + + return false; + } +} diff --git a/src/main/java/com/github/elenterius/biomancy/util/WorldUtil.java b/src/main/java/com/github/elenterius/biomancy/util/WorldUtil.java deleted file mode 100644 index 499eab63f..000000000 --- a/src/main/java/com/github/elenterius/biomancy/util/WorldUtil.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.github.elenterius.biomancy.util; - -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.IWorldReader; - -public final class WorldUtil { - private WorldUtil() {} - - public static boolean isAir(IWorldReader reader, BlockPos pos) { - return reader.getBlockState(pos).isAir(reader, pos); //TODO: update this in mc 1.17 - } - -} diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml index a9aaebd76..08ca494fd 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/mods.toml @@ -9,12 +9,12 @@ showAsResourcePack = false modId = "biomancy" version = "${file.jarVersion}" displayName = "Biomancy" -displayURL = "https://github.com/Elenterius/Biomancy" #optional +displayURL = "https://www.curseforge.com/minecraft/mc-mods/biomancy" #optional logoFile = "text_logo.png" #optional logoBlur = false -credits = "I thank GPT-Neo 1.3B for writting support ;)" +credits = "I'm grateful to Selea for their feedback and help with models & mod design choices. Furthermore I thank GPT-Neo 1.3B for helping me to find the right words ;)" authors = "Elenterius" #optional -description = '''Biomancy is a Biopunk inspired Mod and themed around flesh magic and bio-manipulation.''' +description = '''Biopunk and Flesh Magic inspired tech-magic mod that has a fleshy art theme.''' [[dependencies.biomancy]] #optional modId = "forge" diff --git a/src/main/resources/assets/biomancy/blockstates/chewer.json b/src/main/resources/assets/biomancy/blockstates/chewer.json index b408684eb..85768d129 100644 --- a/src/main/resources/assets/biomancy/blockstates/chewer.json +++ b/src/main/resources/assets/biomancy/blockstates/chewer.json @@ -1,18 +1,18 @@ { "variants": { "facing=east": { - "model": "biomancy:block/decomposer", + "model": "biomancy:block/chewer", "y": 90 }, "facing=north": { - "model": "biomancy:block/decomposer" + "model": "biomancy:block/chewer" }, "facing=south": { - "model": "biomancy:block/decomposer", + "model": "biomancy:block/chewer", "y": 180 }, "facing=west": { - "model": "biomancy:block/decomposer", + "model": "biomancy:block/chewer", "y": 270 } } diff --git a/src/main/resources/assets/biomancy/blockstates/digester.json b/src/main/resources/assets/biomancy/blockstates/digester.json index b408684eb..cfd967795 100644 --- a/src/main/resources/assets/biomancy/blockstates/digester.json +++ b/src/main/resources/assets/biomancy/blockstates/digester.json @@ -1,18 +1,18 @@ { "variants": { "facing=east": { - "model": "biomancy:block/decomposer", + "model": "biomancy:block/digester", "y": 90 }, "facing=north": { - "model": "biomancy:block/decomposer" + "model": "biomancy:block/digester" }, "facing=south": { - "model": "biomancy:block/decomposer", + "model": "biomancy:block/digester", "y": 180 }, "facing=west": { - "model": "biomancy:block/decomposer", + "model": "biomancy:block/digester", "y": 270 } } diff --git a/src/main/resources/assets/biomancy/blockstates/meatsoup_cauldron.json b/src/main/resources/assets/biomancy/blockstates/meatsoup_cauldron.json index ad4f3a1f4..240fca43a 100644 --- a/src/main/resources/assets/biomancy/blockstates/meatsoup_cauldron.json +++ b/src/main/resources/assets/biomancy/blockstates/meatsoup_cauldron.json @@ -25,7 +25,7 @@ "model": "biomancy:block/meatsoup_cauldron_level3" }, "level=8": { - "model": "biomancy:block/meatsoup_cauldron_level3" + "model": "biomancy:block/meatsoup_cauldron_level4" } } } \ No newline at end of file diff --git a/src/main/resources/assets/biomancy/models/block/chewer.json b/src/main/resources/assets/biomancy/models/block/chewer.json index ba2a84102..f01e4a2a1 100644 --- a/src/main/resources/assets/biomancy/models/block/chewer.json +++ b/src/main/resources/assets/biomancy/models/block/chewer.json @@ -5,8 +5,8 @@ "particle": "biomancy:block/flesh_bland", "flesh": "biomancy:block/flesh_bland", "neck": "biomancy:block/neck_hole", - "tooths": "biomancy:block/tooths", - "front": "biomancy:block/decomposer_front" + "tooths": "biomancy:block/teeth_0", + "front": "biomancy:block/chewer_front" }, "elements": [ { diff --git a/src/main/resources/assets/biomancy/models/block/decomposer.json b/src/main/resources/assets/biomancy/models/block/decomposer.json index ba2a84102..29e1ce0e9 100644 --- a/src/main/resources/assets/biomancy/models/block/decomposer.json +++ b/src/main/resources/assets/biomancy/models/block/decomposer.json @@ -1,2111 +1,687 @@ { - "credit": "Made by Elenterius", - "parent": "block/block", - "textures": { - "particle": "biomancy:block/flesh_bland", - "flesh": "biomancy:block/flesh_bland", - "neck": "biomancy:block/neck_hole", - "tooths": "biomancy:block/tooths", - "front": "biomancy:block/decomposer_front" - }, - "elements": [ - { - "name": "container", - "from": [ - 0, - 0, - 3 - ], - "to": [ - 16, - 14, - 16 - ], - "rotation": { - "angle": 0, - "axis": "y", - "origin": [ - 7, - 6, - 7 - ] - }, - "faces": { - "north": { - "uv": [ - 0, - 2, - 16, - 16 - ], - "texture": "#front" - }, - "east": { - "uv": [ - 0, - 2, - 13, - 16 - ], - "texture": "#flesh", - "cullface": "east" - }, - "south": { - "uv": [ - 0, - 2, - 16, - 16 - ], - "texture": "#flesh", - "cullface": "south" - }, - "west": { - "uv": [ - 3, - 2, - 16, - 16 - ], - "texture": "#flesh", - "cullface": "west" - }, - "up": { - "uv": [ - 16, - 16, - 0, - 3 - ], - "texture": "#flesh" - }, - "down": { - "uv": [ - 16, - 0, - 0, - 13 - ], - "texture": "#flesh", - "cullface": "down" - } - } - }, - { - "name": "neck", - "from": [ - 4, - 14, - 4 - ], - "to": [ - 12, - 16, - 12 - ], - "rotation": { - "angle": 0, - "axis": "y", - "origin": [ - 8, - 15, - 8 - ] - }, - "faces": { - "north": { - "uv": [ - 8, - 8, - 16, - 10 - ], - "texture": "#neck" - }, - "east": { - "uv": [ - 8, - 0, - 16, - 2 - ], - "texture": "#neck" - }, - "south": { - "uv": [ - 8, - 2, - 16, - 4 - ], - "texture": "#neck" - }, - "west": { - "uv": [ - 8, - 4, - 16, - 6 - ], - "texture": "#neck" - }, - "up": { - "uv": [ - 8, - 8, - 0, - 0 - ], - "texture": "#neck", - "cullface": "up" - } - } - }, - { - "from": [ - 7, - 7.425, - 2.125 - ], - "to": [ - 9, - 9.425, - 4.125 - ], - "rotation": { - "angle": 0, - "axis": "y", - "origin": [ - 8, - 7.82145, - 1.625 - ] - }, - "faces": { - "north": { - "uv": [ - 0, - 0, - 1, - 1 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 0, - 1, - 1, - 2 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 1, - 1, - 2, - 2 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 1, - 0, - 2, - 1 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 1, - 3, - 0, - 2 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 2, - 2, - 1, - 3 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 7.5, - 6.925, - 0.125 - ], - "to": [ - 8.5, - 7.925, - 2.125 - ], - "rotation": { - "angle": 0, - "axis": "y", - "origin": [ - 8, - 7.82145, - 1.625 - ] - }, - "faces": { - "north": { - "uv": [ - 6.5, - 0.5, - 7, - 1 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 0, - 6, - 1, - 6.5 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 6.5, - 1, - 7, - 1.5 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 1, - 6, - 2, - 6.5 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 2.5, - 7, - 2, - 6 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 3, - 6, - 2.5, - 7 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 7.5, - 5.925, - 0.125 - ], - "to": [ - 8.5, - 6.925, - 1.125 - ], - "rotation": { - "angle": 0, - "axis": "y", - "origin": [ - 8, - 7.82145, - 1.625 - ] - }, - "faces": { - "north": { - "uv": [ - 6.5, - 1.5, - 7, - 2 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 6.5, - 2, - 7, - 2.5 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 6.5, - 3.5, - 7, - 4 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 6.5, - 4, - 7, - 4.5 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 7, - 5, - 6.5, - 4.5 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 7, - 5, - 6.5, - 5.5 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 7.5, - 7.925, - 1.125 - ], - "to": [ - 8.5, - 8.925, - 2.125 - ], - "rotation": { - "angle": 0, - "axis": "y", - "origin": [ - 8, - 7.82145, - 1.625 - ] - }, - "faces": { - "north": { - "uv": [ - 0, - 7, - 0.5, - 7.5 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 0.5, - 7, - 1, - 7.5 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 2, - 7, - 2.5, - 7.5 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 2.5, - 7, - 3, - 7.5 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 3.5, - 7.5, - 3, - 7 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 4, - 7, - 3.5, - 7.5 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 3, - 6.425, - 2.125 - ], - "to": [ - 5, - 8.425, - 4.125 - ], - "rotation": { - "angle": 0, - "axis": "y", - "origin": [ - 8, - 6.82145, - 1.625 - ] - }, - "faces": { - "north": { - "uv": [ - 2, - 2, - 3, - 3 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 2, - 0, - 3, - 1 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 2, - 1, - 3, - 2 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 0, - 3, - 1, - 4 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 2, - 4, - 1, - 3 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 3, - 3, - 2, - 4 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 5.09835, - 8.57665, - 0.125 - ], - "to": [ - 6.09835, - 9.57665, - 2.125 - ], - "rotation": { - "angle": 45, - "axis": "z", - "origin": [ - 8, - 6.82145, - 1.625 - ] - }, - "faces": { - "north": { - "uv": [ - 4, - 7, - 4.5, - 7.5 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 3, - 6, - 4, - 6.5 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 4.5, - 7, - 5, - 7.5 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 4, - 6, - 5, - 6.5 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 5.5, - 7, - 5, - 6 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 6, - 6, - 5.5, - 7 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 5.09835, - 9.57665, - 1.125 - ], - "to": [ - 6.09835, - 10.57665, - 2.125 - ], - "rotation": { - "angle": 45, - "axis": "z", - "origin": [ - 8, - 6.82145, - 1.625 - ] - }, - "faces": { - "north": { - "uv": [ - 5, - 7, - 5.5, - 7.5 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 5.5, - 7, - 6, - 7.5 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 7, - 7, - 7.5, - 7.5 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 7, - 0, - 7.5, - 0.5 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 7.5, - 1, - 7, - 0.5 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 7.5, - 1, - 7, - 1.5 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 5.09835, - 7.57665, - 0.125 - ], - "to": [ - 6.09835, - 8.57665, - 1.125 - ], - "rotation": { - "angle": 45, - "axis": "z", - "origin": [ - 8, - 6.82145, - 1.625 - ] - }, - "faces": { - "north": { - "uv": [ - 7, - 1.5, - 7.5, - 2 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 7, - 2, - 7.5, - 2.5 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 7, - 2.5, - 7.5, - 3 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 7, - 3, - 7.5, - 3.5 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 7.5, - 4, - 7, - 3.5 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 7.5, - 4, - 7, - 4.5 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 11, - 6.425, - 2.125 - ], - "to": [ - 13, - 8.425, - 4.125 - ], - "rotation": { - "angle": 0, - "axis": "y", - "origin": [ - 8, - 6.82145, - 1.625 - ] - }, - "faces": { - "north": { - "uv": [ - 3, - 3, - 4, - 4 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 3, - 0, - 4, - 1 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 3, - 1, - 4, - 2 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 3, - 2, - 4, - 3 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 1, - 5, - 0, - 4 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 2, - 4, - 1, - 5 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 9.90165, - 8.57665, - 0.125 - ], - "to": [ - 10.90165, - 9.57665, - 2.125 - ], - "rotation": { - "angle": -45, - "axis": "z", - "origin": [ - 8, - 6.82145, - 1.625 - ] - }, - "faces": { - "north": { - "uv": [ - 7, - 4.5, - 7.5, - 5 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 6, - 6, - 7, - 6.5 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 7, - 5, - 7.5, - 5.5 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 6, - 0, - 7, - 0.5 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 6.5, - 1.5, - 6, - 0.5 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 6.5, - 1.5, - 6, - 2.5 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 9.90165, - 7.57665, - 0.125 - ], - "to": [ - 10.90165, - 8.57665, - 1.125 - ], - "rotation": { - "angle": -45, - "axis": "z", - "origin": [ - 8, - 6.82145, - 1.625 - ] - }, - "faces": { - "north": { - "uv": [ - 7, - 5.5, - 7.5, - 6 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 7, - 6, - 7.5, - 6.5 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 7, - 6.5, - 7.5, - 7 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 0, - 7.5, - 0.5, - 8 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 1, - 8, - 0.5, - 7.5 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 1.5, - 7.5, - 1, - 8 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 9.90165, - 9.57665, - 1.125 - ], - "to": [ - 10.90165, - 10.57665, - 2.125 - ], - "rotation": { - "angle": -45, - "axis": "z", - "origin": [ - 8, - 6.82145, - 1.625 - ] - }, - "faces": { - "north": { - "uv": [ - 1.5, - 7.5, - 2, - 8 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 2, - 7.5, - 2.5, - 8 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 2.5, - 7.5, - 3, - 8 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 3, - 7.5, - 3.5, - 8 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 4, - 8, - 3.5, - 7.5 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 4.5, - 7.5, - 4, - 8 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 7, - 1.125, - 2.125 - ], - "to": [ - 9, - 3.125, - 4.125 - ], - "rotation": { - "angle": 0, - "axis": "y", - "origin": [ - 8.125, - 2.25, - 1.875 - ] - }, - "faces": { - "north": { - "uv": [ - 2, - 4, - 3, - 5 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 3, - 4, - 4, - 5 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 4, - 4, - 5, - 5 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 4, - 0, - 5, - 1 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 5, - 2, - 4, - 1 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 5, - 2, - 4, - 3 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 7.5, - 2.625, - 0.125 - ], - "to": [ - 8.5, - 3.625, - 2.125 - ], - "rotation": { - "angle": 0, - "axis": "y", - "origin": [ - 7.625, - 2.75, - 1.875 - ] - }, - "faces": { - "north": { - "uv": [ - 4.5, - 7.5, - 5, - 8 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 6, - 2.5, - 7, - 3 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 5, - 7.5, - 5.5, - 8 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 6, - 3, - 7, - 3.5 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 6.5, - 4.5, - 6, - 3.5 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 6.5, - 4.5, - 6, - 5.5 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 7.5, - 3.625, - 0.125 - ], - "to": [ - 8.5, - 4.625, - 1.125 - ], - "rotation": { - "angle": 0, - "axis": "y", - "origin": [ - 8.625, - 3.75, - 0.875 - ] - }, - "faces": { - "north": { - "uv": [ - 5.5, - 7.5, - 6, - 8 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 6, - 7.5, - 6.5, - 8 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 6.5, - 7.5, - 7, - 8 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 7, - 7.5, - 7.5, - 8 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 8, - 8, - 7.5, - 7.5 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 8, - 0, - 7.5, - 0.5 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 7.5, - 1.625, - 1.125 - ], - "to": [ - 8.5, - 2.625, - 2.125 - ], - "rotation": { - "angle": 0, - "axis": "y", - "origin": [ - 7.625, - 2.75, - 1.875 - ] - }, - "faces": { - "north": { - "uv": [ - 7.5, - 0.5, - 8, - 1 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 7.5, - 1, - 8, - 1.5 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 7.5, - 1.5, - 8, - 2 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 7.5, - 2, - 8, - 2.5 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 8, - 3, - 7.5, - 2.5 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 8, - 3, - 7.5, - 3.5 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 3, - 2.125, - 2.125 - ], - "to": [ - 5, - 4.125, - 4.125 - ], - "rotation": { - "angle": 0, - "axis": "y", - "origin": [ - 4.125, - 3.25, - 1.875 - ] - }, - "faces": { - "north": { - "uv": [ - 4, - 3, - 5, - 4 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 0, - 5, - 1, - 6 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 1, - 5, - 2, - 6 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 2, - 5, - 3, - 6 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 4, - 6, - 3, - 5 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 5, - 5, - 4, - 6 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 3.5, - 3.625, - 0.125 - ], - "to": [ - 4.5, - 4.625, - 2.125 - ], - "rotation": { - "angle": -45, - "axis": "z", - "origin": [ - 4, - 3.125, - 2.125 - ] - }, - "faces": { - "north": { - "uv": [ - 7.5, - 3.5, - 8, - 4 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 6, - 5.5, - 7, - 6 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 7.5, - 4, - 8, - 4.5 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 0, - 6.5, - 1, - 7 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 1.5, - 7.5, - 1, - 6.5 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 2, - 6.5, - 1.5, - 7.5 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 3.5, - 2.625, - 1.125 - ], - "to": [ - 4.5, - 3.625, - 2.125 - ], - "rotation": { - "angle": -45, - "axis": "z", - "origin": [ - 4, - 3.125, - 2.125 - ] - }, - "faces": { - "north": { - "uv": [ - 7.5, - 4.5, - 8, - 5 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 7.5, - 5, - 8, - 5.5 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 7.5, - 5.5, - 8, - 6 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 7.5, - 6, - 8, - 6.5 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 8, - 7, - 7.5, - 6.5 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 8, - 7, - 7.5, - 7.5 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 3.5, - 4.625, - 0.125 - ], - "to": [ - 4.5, - 5.625, - 1.125 - ], - "rotation": { - "angle": -45, - "axis": "z", - "origin": [ - 4, - 3.125, - 2.125 - ] - }, - "faces": { - "north": { - "uv": [ - 0, - 8, - 0.5, - 8.5 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 0.5, - 8, - 1, - 8.5 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 1, - 8, - 1.5, - 8.5 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 1.5, - 8, - 2, - 8.5 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 2.5, - 8.5, - 2, - 8 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 3, - 8, - 2.5, - 8.5 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 11, - 2.125, - 2.125 - ], - "to": [ - 13, - 4.125, - 4.125 - ], - "rotation": { - "angle": 0, - "axis": "y", - "origin": [ - 12, - 3.125, - 2.125 - ] - }, - "faces": { - "north": { - "uv": [ - 5, - 5, - 6, - 6 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 5, - 0, - 6, - 1 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 5, - 1, - 6, - 2 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 5, - 2, - 6, - 3 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 6, - 4, - 5, - 3 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 6, - 4, - 5, - 5 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 11.5, - 3.625, - 0.125 - ], - "to": [ - 12.5, - 4.625, - 2.125 - ], - "rotation": { - "angle": 45, - "axis": "z", - "origin": [ - 12, - 3.125, - 2.125 - ] - }, - "faces": { - "north": { - "uv": [ - 3, - 8, - 3.5, - 8.5 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 3, - 6.5, - 4, - 7 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 3.5, - 8, - 4, - 8.5 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 4, - 6.5, - 5, - 7 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 6.5, - 7.5, - 6, - 6.5 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 7, - 6.5, - 6.5, - 7.5 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 11.5, - 4.625, - 0.125 - ], - "to": [ - 12.5, - 5.625, - 1.125 - ], - "rotation": { - "angle": 45, - "axis": "z", - "origin": [ - 12, - 3.125, - 2.125 - ] - }, - "faces": { - "north": { - "uv": [ - 4, - 8, - 4.5, - 8.5 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 4.5, - 8, - 5, - 8.5 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 5, - 8, - 5.5, - 8.5 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 5.5, - 8, - 6, - 8.5 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 6.5, - 8.5, - 6, - 8 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 7, - 8, - 6.5, - 8.5 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 11.5, - 2.625, - 1.125 - ], - "to": [ - 12.5, - 3.625, - 2.125 - ], - "rotation": { - "angle": 45, - "axis": "z", - "origin": [ - 12, - 3.125, - 2.125 - ] - }, - "faces": { - "north": { - "uv": [ - 7, - 8, - 7.5, - 8.5 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 7.5, - 8, - 8, - 8.5 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 8, - 8, - 8.5, - 8.5 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 8, - 0, - 8.5, - 0.5 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 8.5, - 1, - 8, - 0.5 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 8.5, - 1, - 8, - 1.5 - ], - "texture": "#tooths" - } - } - } - ], - "groups": [ - 0, - 1, - { - "name": "group", - "origin": [ - 8, - 12, - 8 - ], - "children": [ - { - "name": "tooth", - "origin": [ - 8, - 8, - 8 - ], - "children": [ - 2, - 3, - 4, - 5 - ] - }, - { - "name": "tooth", - "origin": [ - 8, - 8, - 8 - ], - "children": [ - 6, - 7, - 8, - 9 - ] - }, - { - "name": "tooth", - "origin": [ - 8, - 8, - 8 - ], - "children": [ - 10, - 11, - 12, - 13 - ] - }, - { - "name": "tooth", - "origin": [ - 8, - 8, - 8 - ], - "children": [ - 14, - 15, - 16, - 17 - ] - }, - { - "name": "tooth", - "origin": [ - 8, - 8, - 8 - ], - "children": [ - 18, - 19, - 20, - 21 - ] - }, - { - "name": "tooth", - "origin": [ - 8, - 8, - 8 - ], - "children": [ - 22, - 23, - 24, - 25 - ] - } - ] - } - ] + "credit": "Made by Selea", + "parent": "block/block", + "textures": { + "bottom": "biomancy:block/flesh_hole", + "particle": "biomancy:block/flesh_bland", + "skin": "biomancy:block/flesh_bland", + "muscle": "biomancy:block/muscle", + "fluid": "biomancy:block/decomposer_fluid", + "teeth": "biomancy:block/teeth_0" + }, + "elements": [ + { + "from": [1, 0, 1], + "to": [15, 1, 15], + "faces": { + "north": {"uv": [0, 0, 14, 1], "texture": "#skin"}, + "east": {"uv": [0, 0, 14, 1], "texture": "#skin"}, + "south": {"uv": [0, 0, 14, 1], "texture": "#skin"}, + "west": {"uv": [0, 0, 14, 1], "texture": "#skin"}, + "up": {"uv": [0, 0, 14, 14], "texture": "#muscle"}, + "down": {"uv": [1, 1, 15, 15], "texture": "#bottom"} + } + }, + { + "from": [1, 1, 0], + "to": [15, 10, 1], + "faces": { + "north": {"uv": [0, 0, 14, 9], "texture": "#skin"}, + "east": {"uv": [0, 0, 1, 9], "texture": "#skin"}, + "south": {"uv": [0, 0, 14, 9], "texture": "#muscle"}, + "west": {"uv": [0, 0, 1, 9], "texture": "#skin"}, + "up": {"uv": [0, 0, 14, 1], "texture": "#skin"}, + "down": {"uv": [0, 0, 14, 1], "texture": "#skin"} + } + }, + { + "from": [0, 1, 1], + "to": [1, 10, 15], + "faces": { + "north": {"uv": [0, 0, 1, 9], "texture": "#skin"}, + "east": {"uv": [0, 0, 14, 9], "texture": "#muscle"}, + "south": {"uv": [0, 0, 1, 9], "texture": "#skin"}, + "west": {"uv": [0, 0, 14, 9], "texture": "#skin"}, + "up": {"uv": [0, 0, 1, 14], "texture": "#skin"}, + "down": {"uv": [0, 0, 1, 14], "texture": "#skin"} + } + }, + { + "from": [15, 1, 1], + "to": [16, 10, 15], + "faces": { + "north": {"uv": [0, 0, 1, 9], "texture": "#skin"}, + "east": {"uv": [0, 0, 14, 9], "texture": "#skin"}, + "south": {"uv": [0, 0, 1, 9], "texture": "#skin"}, + "west": {"uv": [0, 0, 14, 9], "texture": "#muscle"}, + "up": {"uv": [0, 0, 1, 14], "texture": "#skin"}, + "down": {"uv": [0, 0, 1, 14], "texture": "#skin"} + } + }, + { + "from": [1, 1, 15], + "to": [15, 10, 16], + "faces": { + "north": {"uv": [0, 0, 14, 9], "texture": "#muscle"}, + "east": {"uv": [0, 0, 1, 9], "texture": "#skin"}, + "south": {"uv": [0, 0, 14, 9], "texture": "#skin"}, + "west": {"uv": [0, 0, 1, 9], "texture": "#skin"}, + "up": {"uv": [0, 0, 14, 1], "texture": "#skin"}, + "down": {"uv": [0, 0, 14, 1], "texture": "#skin"} + } + }, + { + "name": "fluid", + "from": [1, 6, 1], + "to": [15, 6, 15], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 6, 8]}, + "faces": { + "north": {"uv": [0, 0, 14, 0], "texture": "#fluid"}, + "east": {"uv": [0, 0, 14, 0], "texture": "#fluid"}, + "south": {"uv": [0, 0, 14, 0], "texture": "#fluid"}, + "west": {"uv": [0, 0, 14, 0], "texture": "#fluid"}, + "up": {"uv": [14, 14, 0, 0], "texture": "#fluid"} + } + }, + { + "from": [3, 15, 3], + "to": [6, 16, 6], + "rotation": {"angle": 0, "axis": "z", "origin": [1, 10, 1]}, + "faces": { + "north": {"uv": [0, 0, 3, 1], "texture": "#skin"}, + "east": {"uv": [0, 0, 3, 1], "texture": "#skin"}, + "south": {"uv": [0, 0, 3, 1], "texture": "#skin"}, + "west": {"uv": [0, 0, 3, 1], "texture": "#skin"}, + "up": {"uv": [0, 0, 3, 3], "texture": "#skin"}, + "down": {"uv": [0, 0, 3, 3], "texture": "#muscle"} + } + }, + { + "from": [1, 10, 1], + "to": [7, 12, 2], + "rotation": {"angle": 0, "axis": "z", "origin": [1, 10, 1]}, + "faces": { + "north": {"uv": [0, 0, 6, 2], "texture": "#skin"}, + "east": {"uv": [0, 0, 1, 2], "texture": "#skin"}, + "south": {"uv": [0, 0, 6, 2], "texture": "#muscle"}, + "west": {"uv": [0, 0, 1, 2], "texture": "#skin"}, + "up": {"uv": [0, 0, 6, 1], "texture": "#skin"}, + "down": {"uv": [0, 0, 6, 1], "texture": "#muscle"} + } + }, + { + "from": [2, 12, 2], + "to": [6, 15, 3], + "rotation": {"angle": 0, "axis": "z", "origin": [1, 10, 1]}, + "faces": { + "north": {"uv": [0, 0, 4, 3], "texture": "#skin"}, + "east": {"uv": [0, 0, 1, 3], "texture": "#skin"}, + "south": {"uv": [0, 0, 4, 3], "texture": "#muscle"}, + "west": {"uv": [0, 0, 1, 3], "texture": "#skin"}, + "up": {"uv": [0, 0, 4, 1], "texture": "#skin"}, + "down": {"uv": [0, 0, 4, 1], "texture": "#muscle"} + } + }, + { + "from": [2, 12, 3], + "to": [3, 15, 6], + "rotation": {"angle": 0, "axis": "z", "origin": [1, 10, 1]}, + "faces": { + "north": {"uv": [0, 0, 1, 3], "texture": "#skin"}, + "east": {"uv": [0, 0, 3, 3], "texture": "#muscle"}, + "south": {"uv": [0, 0, 1, 3], "texture": "#skin"}, + "west": {"uv": [0, 0, 3, 3], "texture": "#skin"}, + "up": {"uv": [0, 0, 1, 3], "texture": "#skin"}, + "down": {"uv": [0, 0, 1, 3], "texture": "#muscle"} + } + }, + { + "from": [1, 10, 2], + "to": [2, 12, 7], + "rotation": {"angle": 0, "axis": "z", "origin": [1, 10, 1]}, + "faces": { + "north": {"uv": [0, 0, 1, 2], "texture": "#skin"}, + "east": {"uv": [0, 0, 5, 2], "texture": "#muscle"}, + "south": {"uv": [0, 0, 1, 2], "texture": "#skin"}, + "west": {"uv": [0, 0, 5, 2], "texture": "#skin"}, + "up": {"uv": [0, 0, 1, 5], "texture": "#skin"}, + "down": {"uv": [0, 0, 1, 5], "texture": "#muscle"} + } + }, + { + "from": [3, 15, 6], + "to": [4, 16, 7], + "rotation": {"angle": 0, "axis": "z", "origin": [1, 10, 1]}, + "faces": { + "north": {"uv": [1.5, 6, 2, 6.5], "texture": "#teeth"}, + "east": {"uv": [3.5, 7, 4, 7.5], "texture": "#teeth"}, + "south": {"uv": [6.5, 0, 7, 0.5], "texture": "#teeth"}, + "west": {"uv": [0.5, 6.5, 1, 7], "texture": "#teeth"}, + "up": {"uv": [6, 7.5, 6.5, 8], "texture": "#teeth"}, + "down": {"uv": [1, 6.5, 1.5, 7], "texture": "#teeth"} + } + }, + { + "from": [2, 13, 6], + "to": [3, 14, 7], + "rotation": {"angle": 0, "axis": "z", "origin": [1, 10, 1]}, + "faces": { + "north": {"uv": [1.5, 6, 2, 6.5], "texture": "#teeth"}, + "east": {"uv": [3.5, 7, 4, 7.5], "texture": "#teeth"}, + "south": {"uv": [6.5, 0, 7, 0.5], "texture": "#teeth"}, + "west": {"uv": [0.5, 6.5, 1, 7], "texture": "#teeth"}, + "up": {"uv": [6, 7.5, 6.5, 8], "texture": "#teeth"}, + "down": {"uv": [1, 6.5, 1.5, 7], "texture": "#teeth"} + } + }, + { + "from": [5, 15, 6], + "to": [6, 16, 7], + "rotation": {"angle": 0, "axis": "z", "origin": [1, 10, 1]}, + "faces": { + "north": {"uv": [1.5, 6, 2, 6.5], "texture": "#teeth"}, + "east": {"uv": [3.5, 7, 4, 7.5], "texture": "#teeth"}, + "south": {"uv": [6.5, 0, 7, 0.5], "texture": "#teeth"}, + "west": {"uv": [0.5, 6.5, 1, 7], "texture": "#teeth"}, + "up": {"uv": [5, 8, 5.5, 8.5], "texture": "#teeth"}, + "down": {"uv": [1, 6.5, 1.5, 7], "texture": "#teeth"} + } + }, + { + "from": [6, 15, 5], + "to": [7, 16, 6], + "rotation": {"angle": 0, "axis": "z", "origin": [1, 10, 1]}, + "faces": { + "north": {"uv": [1.5, 6, 2, 6.5], "texture": "#teeth"}, + "east": {"uv": [3.5, 7, 4, 7.5], "texture": "#teeth"}, + "south": {"uv": [6.5, 0, 7, 0.5], "texture": "#teeth"}, + "west": {"uv": [0.5, 6.5, 1, 7], "texture": "#teeth"}, + "up": {"uv": [6, 7.5, 6.5, 8], "texture": "#teeth"}, + "down": {"uv": [1, 6.5, 1.5, 7], "texture": "#teeth"} + } + }, + { + "from": [6, 15, 3], + "to": [7, 16, 4], + "rotation": {"angle": 0, "axis": "z", "origin": [1, 10, 1]}, + "faces": { + "north": {"uv": [1.5, 6, 2, 6.5], "texture": "#teeth"}, + "east": {"uv": [3.5, 7, 4, 7.5], "texture": "#teeth"}, + "south": {"uv": [6.5, 0, 7, 0.5], "texture": "#teeth"}, + "west": {"uv": [0.5, 6.5, 1, 7], "texture": "#teeth"}, + "up": {"uv": [3.5, 7, 4, 7.5], "texture": "#teeth"}, + "down": {"uv": [1, 6.5, 1.5, 7], "texture": "#teeth"} + } + }, + { + "from": [6, 13, 2], + "to": [7, 14, 3], + "rotation": {"angle": 0, "axis": "z", "origin": [1, 10, 1]}, + "faces": { + "north": {"uv": [1.5, 6, 2, 6.5], "texture": "#teeth"}, + "east": {"uv": [3.5, 7, 4, 7.5], "texture": "#teeth"}, + "south": {"uv": [6.5, 0, 7, 0.5], "texture": "#teeth"}, + "west": {"uv": [0.5, 6.5, 1, 7], "texture": "#teeth"}, + "up": {"uv": [6, 7.5, 6.5, 8], "texture": "#teeth"}, + "down": {"uv": [1, 6.5, 1.5, 7], "texture": "#teeth"} + } + }, + { + "from": [3, 15, 10], + "to": [6, 16, 13], + "rotation": {"angle": 0, "axis": "y", "origin": [1, 10, 15]}, + "faces": { + "north": {"uv": [0, 0, 3, 1], "texture": "#skin"}, + "east": {"uv": [0, 0, 3, 1], "texture": "#skin"}, + "south": {"uv": [0, 0, 3, 1], "texture": "#skin"}, + "west": {"uv": [0, 0, 3, 1], "texture": "#skin"}, + "up": {"uv": [0, 0, 3, 3], "rotation": 270, "texture": "#skin"}, + "down": {"uv": [0, 0, 3, 3], "rotation": 90, "texture": "#muscle"} + } + }, + { + "from": [1, 10, 9], + "to": [2, 12, 15], + "rotation": {"angle": 0, "axis": "y", "origin": [1, 10, 15]}, + "faces": { + "north": {"uv": [0, 0, 1, 2], "texture": "#skin"}, + "east": {"uv": [0, 0, 6, 2], "texture": "#muscle"}, + "south": {"uv": [0, 0, 1, 2], "texture": "#skin"}, + "west": {"uv": [0, 0, 6, 2], "texture": "#skin"}, + "up": {"uv": [0, 0, 6, 1], "rotation": 270, "texture": "#skin"}, + "down": {"uv": [0, 0, 6, 1], "rotation": 90, "texture": "#muscle"} + } + }, + { + "from": [2, 12, 10], + "to": [3, 15, 14], + "rotation": {"angle": 0, "axis": "y", "origin": [1, 10, 15]}, + "faces": { + "north": {"uv": [0, 0, 1, 3], "texture": "#muscle"}, + "east": {"uv": [0, 0, 4, 3], "texture": "#muscle"}, + "south": {"uv": [0, 0, 1, 3], "texture": "#skin"}, + "west": {"uv": [0, 0, 4, 3], "texture": "#skin"}, + "up": {"uv": [0, 0, 4, 1], "rotation": 270, "texture": "#skin"}, + "down": {"uv": [0, 0, 4, 1], "rotation": 90, "texture": "#muscle"} + } + }, + { + "from": [3, 12, 13], + "to": [6, 15, 14], + "rotation": {"angle": 0, "axis": "y", "origin": [1, 10, 15]}, + "faces": { + "north": {"uv": [0, 0, 3, 3], "texture": "#muscle"}, + "east": {"uv": [0, 0, 1, 3], "texture": "#skin"}, + "south": {"uv": [0, 0, 3, 3], "texture": "#skin"}, + "west": {"uv": [0, 0, 1, 3], "texture": "#skin"}, + "up": {"uv": [0, 0, 1, 3], "rotation": 270, "texture": "#skin"}, + "down": {"uv": [0, 0, 1, 3], "rotation": 90, "texture": "#muscle"} + } + }, + { + "from": [2, 10, 14], + "to": [7, 12, 15], + "rotation": {"angle": 0, "axis": "y", "origin": [1, 10, 15]}, + "faces": { + "north": {"uv": [0, 0, 5, 2], "texture": "#muscle"}, + "east": {"uv": [0, 0, 1, 2], "texture": "#skin"}, + "south": {"uv": [0, 0, 5, 2], "texture": "#skin"}, + "west": {"uv": [0, 0, 1, 2], "texture": "#skin"}, + "up": {"uv": [0, 0, 1, 5], "rotation": 270, "texture": "#skin"}, + "down": {"uv": [0, 0, 1, 5], "rotation": 90, "texture": "#muscle"} + } + }, + { + "from": [6, 15, 12], + "to": [7, 16, 13], + "rotation": {"angle": 0, "axis": "y", "origin": [1, 10, 15]}, + "faces": { + "north": {"uv": [1.5, 6, 2, 6.5], "texture": "#teeth"}, + "east": {"uv": [3.5, 7, 4, 7.5], "texture": "#teeth"}, + "south": {"uv": [6.5, 0, 7, 0.5], "texture": "#teeth"}, + "west": {"uv": [0.5, 6.5, 1, 7], "texture": "#teeth"}, + "up": {"uv": [5.5, 7, 6, 7.5], "rotation": 270, "texture": "#teeth"}, + "down": {"uv": [1, 6.5, 1.5, 7], "rotation": 90, "texture": "#teeth"} + } + }, + { + "from": [6, 13, 13], + "to": [7, 14, 14], + "rotation": {"angle": 0, "axis": "y", "origin": [1, 10, 15]}, + "faces": { + "north": {"uv": [1.5, 6, 2, 6.5], "texture": "#teeth"}, + "east": {"uv": [3.5, 7, 4, 7.5], "texture": "#teeth"}, + "south": {"uv": [6.5, 0, 7, 0.5], "texture": "#teeth"}, + "west": {"uv": [0.5, 6.5, 1, 7], "texture": "#teeth"}, + "up": {"uv": [6, 7.5, 6.5, 8], "rotation": 270, "texture": "#teeth"}, + "down": {"uv": [1, 6.5, 1.5, 7], "rotation": 90, "texture": "#teeth"} + } + }, + { + "from": [6, 15, 10], + "to": [7, 16, 11], + "rotation": {"angle": 0, "axis": "y", "origin": [1, 10, 15]}, + "faces": { + "north": {"uv": [1.5, 6, 2, 6.5], "texture": "#teeth"}, + "east": {"uv": [3.5, 7, 4, 7.5], "texture": "#teeth"}, + "south": {"uv": [6.5, 0, 7, 0.5], "texture": "#teeth"}, + "west": {"uv": [0.5, 6.5, 1, 7], "texture": "#teeth"}, + "up": {"uv": [6, 7.5, 6.5, 8], "rotation": 270, "texture": "#teeth"}, + "down": {"uv": [1, 6.5, 1.5, 7], "rotation": 90, "texture": "#teeth"} + } + }, + { + "from": [5, 15, 9], + "to": [6, 16, 10], + "rotation": {"angle": 0, "axis": "y", "origin": [1, 10, 15]}, + "faces": { + "north": {"uv": [1.5, 6, 2, 6.5], "texture": "#teeth"}, + "east": {"uv": [4, 6.5, 4.5, 7], "texture": "#teeth"}, + "south": {"uv": [6.5, 0, 7, 0.5], "texture": "#teeth"}, + "west": {"uv": [0.5, 6.5, 1, 7], "texture": "#teeth"}, + "up": {"uv": [6, 7.5, 6.5, 8], "rotation": 270, "texture": "#teeth"}, + "down": {"uv": [1, 6.5, 1.5, 7], "rotation": 90, "texture": "#teeth"} + } + }, + { + "from": [3, 15, 9], + "to": [4, 16, 10], + "rotation": {"angle": 0, "axis": "y", "origin": [1, 10, 15]}, + "faces": { + "north": {"uv": [1.5, 6, 2, 6.5], "texture": "#teeth"}, + "east": {"uv": [3.5, 7, 4, 7.5], "texture": "#teeth"}, + "south": {"uv": [6.5, 0, 7, 0.5], "texture": "#teeth"}, + "west": {"uv": [0.5, 6.5, 1, 7], "texture": "#teeth"}, + "up": {"uv": [6, 7.5, 6.5, 8], "rotation": 270, "texture": "#teeth"}, + "down": {"uv": [1, 6.5, 1.5, 7], "rotation": 90, "texture": "#teeth"} + } + }, + { + "from": [2, 13, 9], + "to": [3, 14, 10], + "rotation": {"angle": 0, "axis": "y", "origin": [1, 10, 15]}, + "faces": { + "north": {"uv": [1.5, 6, 2, 6.5], "texture": "#teeth"}, + "east": {"uv": [3.5, 7, 4, 7.5], "texture": "#teeth"}, + "south": {"uv": [6.5, 0, 7, 0.5], "texture": "#teeth"}, + "west": {"uv": [0.5, 6.5, 1, 7], "texture": "#teeth"}, + "up": {"uv": [0.5, 6.5, 1, 7], "rotation": 270, "texture": "#teeth"}, + "down": {"uv": [1, 6.5, 1.5, 7], "rotation": 90, "texture": "#teeth"} + } + }, + { + "from": [10, 15, 10], + "to": [13, 16, 13], + "rotation": {"angle": 0, "axis": "y", "origin": [15, 10, 15]}, + "faces": { + "north": {"uv": [0, 0, 3, 1], "texture": "#skin"}, + "east": {"uv": [0, 0, 3, 1], "texture": "#skin"}, + "south": {"uv": [0, 0, 3, 1], "texture": "#skin"}, + "west": {"uv": [0, 0, 3, 1], "texture": "#skin"}, + "up": {"uv": [0, 0, 3, 3], "rotation": 180, "texture": "#skin"}, + "down": {"uv": [0, 0, 3, 3], "rotation": 180, "texture": "#muscle"} + } + }, + { + "from": [9, 10, 14], + "to": [15, 12, 15], + "rotation": {"angle": 0, "axis": "y", "origin": [15, 10, 15]}, + "faces": { + "north": {"uv": [0, 0, 6, 2], "texture": "#muscle"}, + "east": {"uv": [0, 0, 1, 2], "texture": "#skin"}, + "south": {"uv": [0, 0, 6, 2], "texture": "#skin"}, + "west": {"uv": [0, 0, 1, 2], "texture": "#skin"}, + "up": {"uv": [0, 0, 6, 1], "rotation": 180, "texture": "#skin"}, + "down": {"uv": [0, 0, 6, 1], "rotation": 180, "texture": "#muscle"} + } + }, + { + "from": [10, 12, 13], + "to": [14, 15, 14], + "rotation": {"angle": 0, "axis": "y", "origin": [15, 10, 15]}, + "faces": { + "north": {"uv": [0, 0, 4, 3], "texture": "#muscle"}, + "east": {"uv": [0, 0, 1, 3], "texture": "#skin"}, + "south": {"uv": [0, 0, 4, 3], "texture": "#skin"}, + "west": {"uv": [0, 0, 1, 3], "texture": "#skin"}, + "up": {"uv": [0, 0, 4, 1], "rotation": 180, "texture": "#skin"}, + "down": {"uv": [0, 0, 4, 1], "rotation": 180, "texture": "#muscle"} + } + }, + { + "from": [13, 12, 10], + "to": [14, 15, 13], + "rotation": {"angle": 0, "axis": "y", "origin": [15, 10, 15]}, + "faces": { + "north": {"uv": [0, 0, 1, 3], "texture": "#skin"}, + "east": {"uv": [0, 0, 3, 3], "texture": "#skin"}, + "south": {"uv": [0, 0, 1, 3], "texture": "#skin"}, + "west": {"uv": [0, 0, 3, 3], "texture": "#muscle"}, + "up": {"uv": [0, 0, 1, 3], "rotation": 180, "texture": "#skin"}, + "down": {"uv": [0, 0, 1, 3], "rotation": 180, "texture": "#muscle"} + } + }, + { + "from": [14, 10, 9], + "to": [15, 12, 14], + "rotation": {"angle": 0, "axis": "y", "origin": [15, 10, 15]}, + "faces": { + "north": {"uv": [0, 0, 1, 2], "texture": "#skin"}, + "east": {"uv": [0, 0, 5, 2], "texture": "#skin"}, + "south": {"uv": [0, 0, 1, 2], "texture": "#skin"}, + "west": {"uv": [0, 0, 5, 2], "texture": "#muscle"}, + "up": {"uv": [0, 0, 1, 5], "rotation": 180, "texture": "#skin"}, + "down": {"uv": [0, 0, 1, 5], "rotation": 180, "texture": "#muscle"} + } + }, + { + "from": [12, 15, 9], + "to": [13, 16, 10], + "rotation": {"angle": 0, "axis": "y", "origin": [15, 10, 15]}, + "faces": { + "north": {"uv": [1.5, 6, 2, 6.5], "texture": "#teeth"}, + "east": {"uv": [3.5, 7, 4, 7.5], "texture": "#teeth"}, + "south": {"uv": [6.5, 0, 7, 0.5], "texture": "#teeth"}, + "west": {"uv": [1, 6, 1.5, 6.5], "texture": "#teeth"}, + "up": {"uv": [6, 7.5, 6.5, 8], "rotation": 180, "texture": "#teeth"}, + "down": {"uv": [1, 6.5, 1.5, 7], "rotation": 180, "texture": "#teeth"} + } + }, + { + "from": [13, 13, 9], + "to": [14, 14, 10], + "rotation": {"angle": 0, "axis": "y", "origin": [15, 10, 15]}, + "faces": { + "north": {"uv": [1.5, 6, 2, 6.5], "texture": "#teeth"}, + "east": {"uv": [3.5, 7, 4, 7.5], "texture": "#teeth"}, + "south": {"uv": [6.5, 0, 7, 0.5], "texture": "#teeth"}, + "west": {"uv": [0.5, 6.5, 1, 7], "texture": "#teeth"}, + "up": {"uv": [6.5, 0, 7, 0.5], "rotation": 180, "texture": "#teeth"}, + "down": {"uv": [1, 6.5, 1.5, 7], "rotation": 180, "texture": "#teeth"} + } + }, + { + "from": [10, 15, 9], + "to": [11, 16, 10], + "rotation": {"angle": 0, "axis": "y", "origin": [15, 10, 15]}, + "faces": { + "north": {"uv": [1.5, 6, 2, 6.5], "texture": "#teeth"}, + "east": {"uv": [3.5, 7, 4, 7.5], "texture": "#teeth"}, + "south": {"uv": [6.5, 0, 7, 0.5], "texture": "#teeth"}, + "west": {"uv": [0.5, 6.5, 1, 7], "texture": "#teeth"}, + "up": {"uv": [6, 7.5, 6.5, 8], "rotation": 180, "texture": "#teeth"}, + "down": {"uv": [1, 6.5, 1.5, 7], "rotation": 180, "texture": "#teeth"} + } + }, + { + "from": [9, 15, 10], + "to": [10, 16, 11], + "rotation": {"angle": 0, "axis": "y", "origin": [15, 10, 15]}, + "faces": { + "north": {"uv": [1.5, 6, 2, 6.5], "texture": "#teeth"}, + "east": {"uv": [3.5, 7, 4, 7.5], "texture": "#teeth"}, + "south": {"uv": [6.5, 0, 7, 0.5], "texture": "#teeth"}, + "west": {"uv": [0.5, 6.5, 1, 7], "texture": "#teeth"}, + "up": {"uv": [4.5, 6.5, 5, 7], "rotation": 180, "texture": "#teeth"}, + "down": {"uv": [1, 6.5, 1.5, 7], "rotation": 180, "texture": "#teeth"} + } + }, + { + "from": [9, 15, 12], + "to": [10, 16, 13], + "rotation": {"angle": 0, "axis": "y", "origin": [15, 10, 15]}, + "faces": { + "north": {"uv": [1.5, 6, 2, 6.5], "texture": "#teeth"}, + "east": {"uv": [3.5, 7, 4, 7.5], "texture": "#teeth"}, + "south": {"uv": [6.5, 0, 7, 0.5], "texture": "#teeth"}, + "west": {"uv": [0.5, 6.5, 1, 7], "texture": "#teeth"}, + "up": {"uv": [6, 7.5, 6.5, 8], "rotation": 180, "texture": "#teeth"}, + "down": {"uv": [1, 6.5, 1.5, 7], "rotation": 180, "texture": "#teeth"} + } + }, + { + "from": [9, 13, 13], + "to": [10, 14, 14], + "rotation": {"angle": 0, "axis": "y", "origin": [15, 10, 15]}, + "faces": { + "north": {"uv": [1.5, 6, 2, 6.5], "texture": "#teeth"}, + "east": {"uv": [3.5, 7, 4, 7.5], "texture": "#teeth"}, + "south": {"uv": [6.5, 0, 7, 0.5], "texture": "#teeth"}, + "west": {"uv": [0.5, 6.5, 1, 7], "texture": "#teeth"}, + "up": {"uv": [6, 7.5, 6.5, 8], "rotation": 180, "texture": "#teeth"}, + "down": {"uv": [1, 6.5, 1.5, 7], "rotation": 180, "texture": "#teeth"} + } + }, + { + "from": [10, 15, 3], + "to": [13, 16, 6], + "rotation": {"angle": 0, "axis": "y", "origin": [15, 10, 1]}, + "faces": { + "north": {"uv": [0, 0, 3, 1], "texture": "#skin"}, + "east": {"uv": [0, 0, 3, 1], "texture": "#skin"}, + "south": {"uv": [0, 0, 3, 1], "texture": "#skin"}, + "west": {"uv": [0, 0, 3, 1], "texture": "#skin"}, + "up": {"uv": [0, 0, 3, 3], "rotation": 90, "texture": "#skin"}, + "down": {"uv": [0, 0, 3, 3], "rotation": 270, "texture": "#muscle"} + } + }, + { + "from": [14, 10, 1], + "to": [15, 12, 7], + "rotation": {"angle": 0, "axis": "y", "origin": [15, 10, 1]}, + "faces": { + "north": {"uv": [0, 0, 1, 2], "texture": "#skin"}, + "east": {"uv": [0, 0, 6, 2], "texture": "#skin"}, + "south": {"uv": [0, 0, 1, 2], "texture": "#skin"}, + "west": {"uv": [0, 0, 6, 2], "texture": "#muscle"}, + "up": {"uv": [0, 0, 6, 1], "rotation": 90, "texture": "#skin"}, + "down": {"uv": [0, 0, 6, 1], "rotation": 270, "texture": "#muscle"} + } + }, + { + "from": [13, 12, 2], + "to": [14, 15, 6], + "rotation": {"angle": 0, "axis": "y", "origin": [15, 10, 1]}, + "faces": { + "north": {"uv": [0, 0, 1, 3], "texture": "#skin"}, + "east": {"uv": [0, 0, 4, 3], "texture": "#skin"}, + "south": {"uv": [0, 0, 1, 3], "texture": "#skin"}, + "west": {"uv": [0, 0, 4, 3], "texture": "#muscle"}, + "up": {"uv": [0, 0, 4, 1], "rotation": 90, "texture": "#skin"}, + "down": {"uv": [0, 0, 4, 1], "rotation": 270, "texture": "#muscle"} + } + }, + { + "from": [10, 12, 2], + "to": [13, 15, 3], + "rotation": {"angle": 0, "axis": "y", "origin": [15, 10, 1]}, + "faces": { + "north": {"uv": [0, 0, 3, 3], "texture": "#skin"}, + "east": {"uv": [0, 0, 1, 3], "texture": "#skin"}, + "south": {"uv": [0, 0, 3, 3], "texture": "#muscle"}, + "west": {"uv": [0, 0, 1, 3], "texture": "#skin"}, + "up": {"uv": [0, 0, 1, 3], "rotation": 90, "texture": "#skin"}, + "down": {"uv": [0, 0, 1, 3], "rotation": 270, "texture": "#muscle"} + } + }, + { + "from": [9, 10, 1], + "to": [14, 12, 2], + "rotation": {"angle": 0, "axis": "y", "origin": [15, 10, 1]}, + "faces": { + "north": {"uv": [0, 0, 5, 2], "texture": "#skin"}, + "east": {"uv": [0, 0, 1, 2], "texture": "#skin"}, + "south": {"uv": [0, 0, 5, 2], "texture": "#muscle"}, + "west": {"uv": [0, 0, 1, 2], "texture": "#skin"}, + "up": {"uv": [0, 0, 1, 5], "rotation": 90, "texture": "#skin"}, + "down": {"uv": [0, 0, 1, 5], "rotation": 270, "texture": "#muscle"} + } + }, + { + "from": [9, 15, 3], + "to": [10, 16, 4], + "rotation": {"angle": 0, "axis": "y", "origin": [15, 10, 1]}, + "faces": { + "north": {"uv": [1.5, 6, 2, 6.5], "texture": "#teeth"}, + "east": {"uv": [3.5, 7, 4, 7.5], "texture": "#teeth"}, + "south": {"uv": [6.5, 0, 7, 0.5], "texture": "#teeth"}, + "west": {"uv": [0.5, 6.5, 1, 7], "texture": "#teeth"}, + "up": {"uv": [6, 7.5, 6.5, 8], "rotation": 90, "texture": "#teeth"}, + "down": {"uv": [1, 6.5, 1.5, 7], "rotation": 270, "texture": "#teeth"} + } + }, + { + "from": [9, 13, 2], + "to": [10, 14, 3], + "rotation": {"angle": 0, "axis": "y", "origin": [15, 10, 1]}, + "faces": { + "north": {"uv": [1.5, 6, 2, 6.5], "texture": "#teeth"}, + "east": {"uv": [3.5, 7, 4, 7.5], "texture": "#teeth"}, + "south": {"uv": [6.5, 0, 7, 0.5], "texture": "#teeth"}, + "west": {"uv": [0.5, 6.5, 1, 7], "texture": "#teeth"}, + "up": {"uv": [6, 7.5, 6.5, 8], "rotation": 90, "texture": "#teeth"}, + "down": {"uv": [1, 6.5, 1.5, 7], "rotation": 270, "texture": "#teeth"} + } + }, + { + "from": [9, 15, 5], + "to": [10, 16, 6], + "rotation": {"angle": 0, "axis": "y", "origin": [15, 10, 1]}, + "faces": { + "north": {"uv": [1.5, 6, 2, 6.5], "texture": "#teeth"}, + "east": {"uv": [3.5, 7, 4, 7.5], "texture": "#teeth"}, + "south": {"uv": [6.5, 0, 7, 0.5], "texture": "#teeth"}, + "west": {"uv": [0.5, 6.5, 1, 7], "texture": "#teeth"}, + "up": {"uv": [0.5, 6.5, 1, 7], "rotation": 90, "texture": "#teeth"}, + "down": {"uv": [1, 6.5, 1.5, 7], "rotation": 270, "texture": "#teeth"} + } + }, + { + "from": [10, 15, 6], + "to": [11, 16, 7], + "rotation": {"angle": 0, "axis": "y", "origin": [15, 10, 1]}, + "faces": { + "north": {"uv": [1.5, 6, 2, 6.5], "texture": "#teeth"}, + "east": {"uv": [3.5, 7, 4, 7.5], "texture": "#teeth"}, + "south": {"uv": [6.5, 0, 7, 0.5], "texture": "#teeth"}, + "west": {"uv": [0.5, 6.5, 1, 7], "texture": "#teeth"}, + "up": {"uv": [6, 7.5, 6.5, 8], "rotation": 90, "texture": "#teeth"}, + "down": {"uv": [1, 6.5, 1.5, 7], "rotation": 270, "texture": "#teeth"} + } + }, + { + "from": [12, 15, 6], + "to": [13, 16, 7], + "rotation": {"angle": 0, "axis": "y", "origin": [15, 10, 1]}, + "faces": { + "north": {"uv": [1.5, 6, 2, 6.5], "texture": "#teeth"}, + "east": {"uv": [3.5, 7, 4, 7.5], "texture": "#teeth"}, + "south": {"uv": [6.5, 0, 7, 0.5], "texture": "#teeth"}, + "west": {"uv": [0.5, 6.5, 1, 7], "texture": "#teeth"}, + "up": {"uv": [6, 7.5, 6.5, 8], "rotation": 90, "texture": "#teeth"}, + "down": {"uv": [1, 6.5, 1.5, 7], "rotation": 270, "texture": "#teeth"} + } + }, + { + "from": [13, 13, 6], + "to": [14, 14, 7], + "rotation": {"angle": 0, "axis": "y", "origin": [15, 10, 1]}, + "faces": { + "north": {"uv": [1.5, 6, 2, 6.5], "texture": "#teeth"}, + "east": {"uv": [3.5, 7, 4, 7.5], "texture": "#teeth"}, + "south": {"uv": [6.5, 0, 7, 0.5], "texture": "#teeth"}, + "west": {"uv": [0.5, 6.5, 1, 7], "texture": "#teeth"}, + "up": {"uv": [6, 7.5, 6.5, 8], "rotation": 90, "texture": "#teeth"}, + "down": {"uv": [1, 6.5, 1.5, 7], "rotation": 270, "texture": "#teeth"} + } + } + ], + "groups": [ + { + "name": "base", + "origin": [8, 8, 8], + "children": [0, 1, 2, 3, 4, 5, + { + "name": "jaw1", + "origin": [0, 0, 0], + "children": [6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] + }, + { + "name": "jaw2", + "origin": [0, 0, 0], + "children": [17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27] + }, + { + "name": "jaw3", + "origin": [0, 0, 0], + "children": [28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38] + }, + { + "name": "jaw4", + "origin": [0, 0, 0], + "children": [39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49] + } + ] + } + ] } \ No newline at end of file diff --git a/src/main/resources/assets/biomancy/models/block/digester.json b/src/main/resources/assets/biomancy/models/block/digester.json index ba2a84102..7959c0246 100644 --- a/src/main/resources/assets/biomancy/models/block/digester.json +++ b/src/main/resources/assets/biomancy/models/block/digester.json @@ -1,2111 +1,92 @@ { - "credit": "Made by Elenterius", - "parent": "block/block", - "textures": { - "particle": "biomancy:block/flesh_bland", - "flesh": "biomancy:block/flesh_bland", - "neck": "biomancy:block/neck_hole", - "tooths": "biomancy:block/tooths", - "front": "biomancy:block/decomposer_front" - }, - "elements": [ - { - "name": "container", - "from": [ - 0, - 0, - 3 - ], - "to": [ - 16, - 14, - 16 - ], - "rotation": { - "angle": 0, - "axis": "y", - "origin": [ - 7, - 6, - 7 - ] - }, - "faces": { - "north": { - "uv": [ - 0, - 2, - 16, - 16 - ], - "texture": "#front" - }, - "east": { - "uv": [ - 0, - 2, - 13, - 16 - ], - "texture": "#flesh", - "cullface": "east" - }, - "south": { - "uv": [ - 0, - 2, - 16, - 16 - ], - "texture": "#flesh", - "cullface": "south" - }, - "west": { - "uv": [ - 3, - 2, - 16, - 16 - ], - "texture": "#flesh", - "cullface": "west" - }, - "up": { - "uv": [ - 16, - 16, - 0, - 3 - ], - "texture": "#flesh" - }, - "down": { - "uv": [ - 16, - 0, - 0, - 13 - ], - "texture": "#flesh", - "cullface": "down" - } - } - }, - { - "name": "neck", - "from": [ - 4, - 14, - 4 - ], - "to": [ - 12, - 16, - 12 - ], - "rotation": { - "angle": 0, - "axis": "y", - "origin": [ - 8, - 15, - 8 - ] - }, - "faces": { - "north": { - "uv": [ - 8, - 8, - 16, - 10 - ], - "texture": "#neck" - }, - "east": { - "uv": [ - 8, - 0, - 16, - 2 - ], - "texture": "#neck" - }, - "south": { - "uv": [ - 8, - 2, - 16, - 4 - ], - "texture": "#neck" - }, - "west": { - "uv": [ - 8, - 4, - 16, - 6 - ], - "texture": "#neck" - }, - "up": { - "uv": [ - 8, - 8, - 0, - 0 - ], - "texture": "#neck", - "cullface": "up" - } - } - }, - { - "from": [ - 7, - 7.425, - 2.125 - ], - "to": [ - 9, - 9.425, - 4.125 - ], - "rotation": { - "angle": 0, - "axis": "y", - "origin": [ - 8, - 7.82145, - 1.625 - ] - }, - "faces": { - "north": { - "uv": [ - 0, - 0, - 1, - 1 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 0, - 1, - 1, - 2 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 1, - 1, - 2, - 2 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 1, - 0, - 2, - 1 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 1, - 3, - 0, - 2 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 2, - 2, - 1, - 3 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 7.5, - 6.925, - 0.125 - ], - "to": [ - 8.5, - 7.925, - 2.125 - ], - "rotation": { - "angle": 0, - "axis": "y", - "origin": [ - 8, - 7.82145, - 1.625 - ] - }, - "faces": { - "north": { - "uv": [ - 6.5, - 0.5, - 7, - 1 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 0, - 6, - 1, - 6.5 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 6.5, - 1, - 7, - 1.5 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 1, - 6, - 2, - 6.5 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 2.5, - 7, - 2, - 6 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 3, - 6, - 2.5, - 7 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 7.5, - 5.925, - 0.125 - ], - "to": [ - 8.5, - 6.925, - 1.125 - ], - "rotation": { - "angle": 0, - "axis": "y", - "origin": [ - 8, - 7.82145, - 1.625 - ] - }, - "faces": { - "north": { - "uv": [ - 6.5, - 1.5, - 7, - 2 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 6.5, - 2, - 7, - 2.5 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 6.5, - 3.5, - 7, - 4 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 6.5, - 4, - 7, - 4.5 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 7, - 5, - 6.5, - 4.5 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 7, - 5, - 6.5, - 5.5 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 7.5, - 7.925, - 1.125 - ], - "to": [ - 8.5, - 8.925, - 2.125 - ], - "rotation": { - "angle": 0, - "axis": "y", - "origin": [ - 8, - 7.82145, - 1.625 - ] - }, - "faces": { - "north": { - "uv": [ - 0, - 7, - 0.5, - 7.5 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 0.5, - 7, - 1, - 7.5 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 2, - 7, - 2.5, - 7.5 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 2.5, - 7, - 3, - 7.5 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 3.5, - 7.5, - 3, - 7 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 4, - 7, - 3.5, - 7.5 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 3, - 6.425, - 2.125 - ], - "to": [ - 5, - 8.425, - 4.125 - ], - "rotation": { - "angle": 0, - "axis": "y", - "origin": [ - 8, - 6.82145, - 1.625 - ] - }, - "faces": { - "north": { - "uv": [ - 2, - 2, - 3, - 3 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 2, - 0, - 3, - 1 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 2, - 1, - 3, - 2 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 0, - 3, - 1, - 4 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 2, - 4, - 1, - 3 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 3, - 3, - 2, - 4 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 5.09835, - 8.57665, - 0.125 - ], - "to": [ - 6.09835, - 9.57665, - 2.125 - ], - "rotation": { - "angle": 45, - "axis": "z", - "origin": [ - 8, - 6.82145, - 1.625 - ] - }, - "faces": { - "north": { - "uv": [ - 4, - 7, - 4.5, - 7.5 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 3, - 6, - 4, - 6.5 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 4.5, - 7, - 5, - 7.5 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 4, - 6, - 5, - 6.5 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 5.5, - 7, - 5, - 6 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 6, - 6, - 5.5, - 7 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 5.09835, - 9.57665, - 1.125 - ], - "to": [ - 6.09835, - 10.57665, - 2.125 - ], - "rotation": { - "angle": 45, - "axis": "z", - "origin": [ - 8, - 6.82145, - 1.625 - ] - }, - "faces": { - "north": { - "uv": [ - 5, - 7, - 5.5, - 7.5 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 5.5, - 7, - 6, - 7.5 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 7, - 7, - 7.5, - 7.5 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 7, - 0, - 7.5, - 0.5 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 7.5, - 1, - 7, - 0.5 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 7.5, - 1, - 7, - 1.5 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 5.09835, - 7.57665, - 0.125 - ], - "to": [ - 6.09835, - 8.57665, - 1.125 - ], - "rotation": { - "angle": 45, - "axis": "z", - "origin": [ - 8, - 6.82145, - 1.625 - ] - }, - "faces": { - "north": { - "uv": [ - 7, - 1.5, - 7.5, - 2 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 7, - 2, - 7.5, - 2.5 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 7, - 2.5, - 7.5, - 3 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 7, - 3, - 7.5, - 3.5 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 7.5, - 4, - 7, - 3.5 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 7.5, - 4, - 7, - 4.5 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 11, - 6.425, - 2.125 - ], - "to": [ - 13, - 8.425, - 4.125 - ], - "rotation": { - "angle": 0, - "axis": "y", - "origin": [ - 8, - 6.82145, - 1.625 - ] - }, - "faces": { - "north": { - "uv": [ - 3, - 3, - 4, - 4 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 3, - 0, - 4, - 1 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 3, - 1, - 4, - 2 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 3, - 2, - 4, - 3 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 1, - 5, - 0, - 4 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 2, - 4, - 1, - 5 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 9.90165, - 8.57665, - 0.125 - ], - "to": [ - 10.90165, - 9.57665, - 2.125 - ], - "rotation": { - "angle": -45, - "axis": "z", - "origin": [ - 8, - 6.82145, - 1.625 - ] - }, - "faces": { - "north": { - "uv": [ - 7, - 4.5, - 7.5, - 5 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 6, - 6, - 7, - 6.5 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 7, - 5, - 7.5, - 5.5 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 6, - 0, - 7, - 0.5 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 6.5, - 1.5, - 6, - 0.5 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 6.5, - 1.5, - 6, - 2.5 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 9.90165, - 7.57665, - 0.125 - ], - "to": [ - 10.90165, - 8.57665, - 1.125 - ], - "rotation": { - "angle": -45, - "axis": "z", - "origin": [ - 8, - 6.82145, - 1.625 - ] - }, - "faces": { - "north": { - "uv": [ - 7, - 5.5, - 7.5, - 6 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 7, - 6, - 7.5, - 6.5 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 7, - 6.5, - 7.5, - 7 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 0, - 7.5, - 0.5, - 8 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 1, - 8, - 0.5, - 7.5 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 1.5, - 7.5, - 1, - 8 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 9.90165, - 9.57665, - 1.125 - ], - "to": [ - 10.90165, - 10.57665, - 2.125 - ], - "rotation": { - "angle": -45, - "axis": "z", - "origin": [ - 8, - 6.82145, - 1.625 - ] - }, - "faces": { - "north": { - "uv": [ - 1.5, - 7.5, - 2, - 8 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 2, - 7.5, - 2.5, - 8 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 2.5, - 7.5, - 3, - 8 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 3, - 7.5, - 3.5, - 8 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 4, - 8, - 3.5, - 7.5 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 4.5, - 7.5, - 4, - 8 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 7, - 1.125, - 2.125 - ], - "to": [ - 9, - 3.125, - 4.125 - ], - "rotation": { - "angle": 0, - "axis": "y", - "origin": [ - 8.125, - 2.25, - 1.875 - ] - }, - "faces": { - "north": { - "uv": [ - 2, - 4, - 3, - 5 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 3, - 4, - 4, - 5 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 4, - 4, - 5, - 5 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 4, - 0, - 5, - 1 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 5, - 2, - 4, - 1 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 5, - 2, - 4, - 3 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 7.5, - 2.625, - 0.125 - ], - "to": [ - 8.5, - 3.625, - 2.125 - ], - "rotation": { - "angle": 0, - "axis": "y", - "origin": [ - 7.625, - 2.75, - 1.875 - ] - }, - "faces": { - "north": { - "uv": [ - 4.5, - 7.5, - 5, - 8 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 6, - 2.5, - 7, - 3 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 5, - 7.5, - 5.5, - 8 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 6, - 3, - 7, - 3.5 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 6.5, - 4.5, - 6, - 3.5 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 6.5, - 4.5, - 6, - 5.5 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 7.5, - 3.625, - 0.125 - ], - "to": [ - 8.5, - 4.625, - 1.125 - ], - "rotation": { - "angle": 0, - "axis": "y", - "origin": [ - 8.625, - 3.75, - 0.875 - ] - }, - "faces": { - "north": { - "uv": [ - 5.5, - 7.5, - 6, - 8 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 6, - 7.5, - 6.5, - 8 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 6.5, - 7.5, - 7, - 8 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 7, - 7.5, - 7.5, - 8 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 8, - 8, - 7.5, - 7.5 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 8, - 0, - 7.5, - 0.5 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 7.5, - 1.625, - 1.125 - ], - "to": [ - 8.5, - 2.625, - 2.125 - ], - "rotation": { - "angle": 0, - "axis": "y", - "origin": [ - 7.625, - 2.75, - 1.875 - ] - }, - "faces": { - "north": { - "uv": [ - 7.5, - 0.5, - 8, - 1 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 7.5, - 1, - 8, - 1.5 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 7.5, - 1.5, - 8, - 2 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 7.5, - 2, - 8, - 2.5 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 8, - 3, - 7.5, - 2.5 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 8, - 3, - 7.5, - 3.5 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 3, - 2.125, - 2.125 - ], - "to": [ - 5, - 4.125, - 4.125 - ], - "rotation": { - "angle": 0, - "axis": "y", - "origin": [ - 4.125, - 3.25, - 1.875 - ] - }, - "faces": { - "north": { - "uv": [ - 4, - 3, - 5, - 4 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 0, - 5, - 1, - 6 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 1, - 5, - 2, - 6 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 2, - 5, - 3, - 6 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 4, - 6, - 3, - 5 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 5, - 5, - 4, - 6 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 3.5, - 3.625, - 0.125 - ], - "to": [ - 4.5, - 4.625, - 2.125 - ], - "rotation": { - "angle": -45, - "axis": "z", - "origin": [ - 4, - 3.125, - 2.125 - ] - }, - "faces": { - "north": { - "uv": [ - 7.5, - 3.5, - 8, - 4 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 6, - 5.5, - 7, - 6 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 7.5, - 4, - 8, - 4.5 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 0, - 6.5, - 1, - 7 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 1.5, - 7.5, - 1, - 6.5 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 2, - 6.5, - 1.5, - 7.5 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 3.5, - 2.625, - 1.125 - ], - "to": [ - 4.5, - 3.625, - 2.125 - ], - "rotation": { - "angle": -45, - "axis": "z", - "origin": [ - 4, - 3.125, - 2.125 - ] - }, - "faces": { - "north": { - "uv": [ - 7.5, - 4.5, - 8, - 5 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 7.5, - 5, - 8, - 5.5 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 7.5, - 5.5, - 8, - 6 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 7.5, - 6, - 8, - 6.5 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 8, - 7, - 7.5, - 6.5 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 8, - 7, - 7.5, - 7.5 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 3.5, - 4.625, - 0.125 - ], - "to": [ - 4.5, - 5.625, - 1.125 - ], - "rotation": { - "angle": -45, - "axis": "z", - "origin": [ - 4, - 3.125, - 2.125 - ] - }, - "faces": { - "north": { - "uv": [ - 0, - 8, - 0.5, - 8.5 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 0.5, - 8, - 1, - 8.5 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 1, - 8, - 1.5, - 8.5 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 1.5, - 8, - 2, - 8.5 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 2.5, - 8.5, - 2, - 8 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 3, - 8, - 2.5, - 8.5 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 11, - 2.125, - 2.125 - ], - "to": [ - 13, - 4.125, - 4.125 - ], - "rotation": { - "angle": 0, - "axis": "y", - "origin": [ - 12, - 3.125, - 2.125 - ] - }, - "faces": { - "north": { - "uv": [ - 5, - 5, - 6, - 6 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 5, - 0, - 6, - 1 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 5, - 1, - 6, - 2 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 5, - 2, - 6, - 3 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 6, - 4, - 5, - 3 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 6, - 4, - 5, - 5 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 11.5, - 3.625, - 0.125 - ], - "to": [ - 12.5, - 4.625, - 2.125 - ], - "rotation": { - "angle": 45, - "axis": "z", - "origin": [ - 12, - 3.125, - 2.125 - ] - }, - "faces": { - "north": { - "uv": [ - 3, - 8, - 3.5, - 8.5 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 3, - 6.5, - 4, - 7 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 3.5, - 8, - 4, - 8.5 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 4, - 6.5, - 5, - 7 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 6.5, - 7.5, - 6, - 6.5 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 7, - 6.5, - 6.5, - 7.5 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 11.5, - 4.625, - 0.125 - ], - "to": [ - 12.5, - 5.625, - 1.125 - ], - "rotation": { - "angle": 45, - "axis": "z", - "origin": [ - 12, - 3.125, - 2.125 - ] - }, - "faces": { - "north": { - "uv": [ - 4, - 8, - 4.5, - 8.5 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 4.5, - 8, - 5, - 8.5 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 5, - 8, - 5.5, - 8.5 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 5.5, - 8, - 6, - 8.5 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 6.5, - 8.5, - 6, - 8 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 7, - 8, - 6.5, - 8.5 - ], - "texture": "#tooths" - } - } - }, - { - "from": [ - 11.5, - 2.625, - 1.125 - ], - "to": [ - 12.5, - 3.625, - 2.125 - ], - "rotation": { - "angle": 45, - "axis": "z", - "origin": [ - 12, - 3.125, - 2.125 - ] - }, - "faces": { - "north": { - "uv": [ - 7, - 8, - 7.5, - 8.5 - ], - "texture": "#tooths" - }, - "east": { - "uv": [ - 7.5, - 8, - 8, - 8.5 - ], - "texture": "#tooths" - }, - "south": { - "uv": [ - 8, - 8, - 8.5, - 8.5 - ], - "texture": "#tooths" - }, - "west": { - "uv": [ - 8, - 0, - 8.5, - 0.5 - ], - "texture": "#tooths" - }, - "up": { - "uv": [ - 8.5, - 1, - 8, - 0.5 - ], - "texture": "#tooths" - }, - "down": { - "uv": [ - 8.5, - 1, - 8, - 1.5 - ], - "texture": "#tooths" - } - } - } - ], - "groups": [ - 0, - 1, - { - "name": "group", - "origin": [ - 8, - 12, - 8 - ], - "children": [ - { - "name": "tooth", - "origin": [ - 8, - 8, - 8 - ], - "children": [ - 2, - 3, - 4, - 5 - ] - }, - { - "name": "tooth", - "origin": [ - 8, - 8, - 8 - ], - "children": [ - 6, - 7, - 8, - 9 - ] - }, - { - "name": "tooth", - "origin": [ - 8, - 8, - 8 - ], - "children": [ - 10, - 11, - 12, - 13 - ] - }, - { - "name": "tooth", - "origin": [ - 8, - 8, - 8 - ], - "children": [ - 14, - 15, - 16, - 17 - ] - }, - { - "name": "tooth", - "origin": [ - 8, - 8, - 8 - ], - "children": [ - 18, - 19, - 20, - 21 - ] - }, - { - "name": "tooth", - "origin": [ - 8, - 8, - 8 - ], - "children": [ - 22, - 23, - 24, - 25 - ] - } - ] - } - ] + "credit": "Made by Selea & Modified by Elenterius", + "parent": "block/block", + "textures": { + "tendrils": "biomancy:block/flesh_tendrils", + "top": "biomancy:block/flesh_hole", + "mouth": "biomancy:block/digester_mouth", + "particle": "biomancy:block/flesh_rough_1", + "skin": "biomancy:block/flesh_rough_1" + }, + "elements": [ + { + "from": [3, 5, 3], + "to": [13, 13, 13], + "rotation": {"angle": 45, "axis": "y", "origin": [8, 9, 8]}, + "faces": { + "north": {"uv": [0, 7, 10, 15], "texture": "#skin"}, + "east": {"uv": [0, 4, 10, 12], "texture": "#skin"}, + "south": {"uv": [3, 7, 13, 15], "texture": "#skin"}, + "west": {"uv": [5, 0, 15, 8], "texture": "#skin"}, + "up": {"uv": [4, 3, 14, 13], "texture": "#skin"}, + "down": {"uv": [3, 2, 13, 12], "texture": "#skin"} + } + }, + { + "from": [3, 4, 3], + "to": [13, 14, 13], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 9, 8]}, + "faces": { + "north": {"uv": [5, 0, 15, 10], "texture": "#skin"}, + "east": {"uv": [4, 4, 14, 14], "texture": "#skin"}, + "south": {"uv": [4, 0, 14, 10], "texture": "#skin"}, + "west": {"uv": [0, 4, 10, 14], "texture": "#skin"}, + "up": {"uv": [3, 3, 13, 13], "texture": "#top"}, + "down": {"uv": [1, 0, 11, 10], "texture": "#skin"} + } + }, + { + "name": "mouth", + "from": [4.94975, 14, 4.94975], + "to": [10.94975, 16, 10.94975], + "rotation": {"angle": -45, "axis": "y", "origin": [7.94975, 15, 7.94975]}, + "faces": { + "north": {"uv": [0, 6, 6, 8], "texture": "#mouth"}, + "east": {"uv": [6, 0, 12, 2], "texture": "#mouth"}, + "south": {"uv": [6, 2, 12, 4], "texture": "#mouth"}, + "west": {"uv": [6, 4, 12, 6], "texture": "#mouth"}, + "up": {"uv": [6, 6, 0, 0], "texture": "#mouth"} + } + }, + { + "name": "base", + "from": [4, 1, 4], + "to": [12, 4, 12], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 3.5, 8]}, + "faces": { + "north": {"uv": [6, 0, 14, 3], "texture": "#skin"}, + "east": {"uv": [1, 9, 9, 12], "texture": "#skin"}, + "south": {"uv": [5, 8, 13, 11], "texture": "#skin"}, + "west": {"uv": [3, 2, 11, 5], "texture": "#skin"}, + "down": {"uv": [7, 0, 15, 8], "texture": "#skin"} + } + }, + { + "name": "base", + "from": [5, 0, 5], + "to": [11, 1, 11], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 3.5, 8]}, + "faces": { + "north": {"uv": [6, 0, 12, 1], "texture": "#skin"}, + "east": {"uv": [1, 9, 7, 10], "texture": "#skin"}, + "south": {"uv": [5, 8, 11, 9], "texture": "#skin"}, + "west": {"uv": [3, 2, 9, 3], "texture": "#skin"}, + "down": {"uv": [7, 0, 13, 6], "texture": "#skin"} + } + }, + { + "name": "tendrils", + "from": [0, 0.001, 0], + "to": [16, 0.001, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 0.001, 8]}, + "faces": { + "north": {"uv": [0, 0, 16, 0], "texture": "#missing"}, + "east": {"uv": [0, 0, 16, 0], "texture": "#missing"}, + "south": {"uv": [0, 0, 16, 0], "texture": "#missing"}, + "west": {"uv": [0, 0, 16, 0], "texture": "#missing"}, + "up": {"uv": [0, 0, 16, 16], "texture": "#tendrils"}, + "down": {"uv": [16, 0, 0, 16], "rotation": 180, "texture": "#tendrils", "cullface": "down"} + } + } + ] } \ No newline at end of file diff --git a/src/main/resources/assets/biomancy/models/block/meatsoup_cauldron_level1.json b/src/main/resources/assets/biomancy/models/block/meatsoup_cauldron_level1.json index 0a522ace9..4d8dc4475 100644 --- a/src/main/resources/assets/biomancy/models/block/meatsoup_cauldron_level1.json +++ b/src/main/resources/assets/biomancy/models/block/meatsoup_cauldron_level1.json @@ -1,6 +1,6 @@ { "parent": "minecraft:block/cauldron_level1", "textures": { - "water": "biomancy:block/flesh_bland" + "water": "biomancy:block/muscle" } } \ No newline at end of file diff --git a/src/main/resources/assets/biomancy/models/block/meatsoup_cauldron_level2.json b/src/main/resources/assets/biomancy/models/block/meatsoup_cauldron_level2.json index 7879b320a..403f8dd5f 100644 --- a/src/main/resources/assets/biomancy/models/block/meatsoup_cauldron_level2.json +++ b/src/main/resources/assets/biomancy/models/block/meatsoup_cauldron_level2.json @@ -1,6 +1,6 @@ { "parent": "minecraft:block/cauldron_level2", "textures": { - "water": "biomancy:block/flesh_bland" + "water": "biomancy:block/muscle" } } \ No newline at end of file diff --git a/src/main/resources/assets/biomancy/models/block/meatsoup_cauldron_level3.json b/src/main/resources/assets/biomancy/models/block/meatsoup_cauldron_level3.json index fe900dbfe..fdb9e6f05 100644 --- a/src/main/resources/assets/biomancy/models/block/meatsoup_cauldron_level3.json +++ b/src/main/resources/assets/biomancy/models/block/meatsoup_cauldron_level3.json @@ -1,6 +1,6 @@ { "parent": "minecraft:block/cauldron_level3", "textures": { - "water": "biomancy:block/flesh_bland" + "water": "biomancy:block/muscle" } } \ No newline at end of file diff --git a/src/main/resources/assets/biomancy/models/block/meatsoup_cauldron_level4.json b/src/main/resources/assets/biomancy/models/block/meatsoup_cauldron_level4.json new file mode 100644 index 000000000..fe900dbfe --- /dev/null +++ b/src/main/resources/assets/biomancy/models/block/meatsoup_cauldron_level4.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cauldron_level3", + "textures": { + "water": "biomancy:block/flesh_bland" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/biomancy/textures/block/decomposer_front.png b/src/main/resources/assets/biomancy/textures/block/chewer_front.png similarity index 100% rename from src/main/resources/assets/biomancy/textures/block/decomposer_front.png rename to src/main/resources/assets/biomancy/textures/block/chewer_front.png diff --git a/src/main/resources/assets/biomancy/textures/block/decomposer_fluid.png b/src/main/resources/assets/biomancy/textures/block/decomposer_fluid.png new file mode 100644 index 000000000..d06c5fdf7 Binary files /dev/null and b/src/main/resources/assets/biomancy/textures/block/decomposer_fluid.png differ diff --git a/src/main/resources/assets/biomancy/textures/block/digester_mouth.png b/src/main/resources/assets/biomancy/textures/block/digester_mouth.png new file mode 100644 index 000000000..cd0831852 Binary files /dev/null and b/src/main/resources/assets/biomancy/textures/block/digester_mouth.png differ diff --git a/src/main/resources/assets/biomancy/textures/block/flesh_hole.png b/src/main/resources/assets/biomancy/textures/block/flesh_hole.png new file mode 100644 index 000000000..d8ec65c07 Binary files /dev/null and b/src/main/resources/assets/biomancy/textures/block/flesh_hole.png differ diff --git a/src/main/resources/assets/biomancy/textures/block/flesh_rough_0.png b/src/main/resources/assets/biomancy/textures/block/flesh_rough_0.png index f2a10a742..155d8b81e 100644 Binary files a/src/main/resources/assets/biomancy/textures/block/flesh_rough_0.png and b/src/main/resources/assets/biomancy/textures/block/flesh_rough_0.png differ diff --git a/src/main/resources/assets/biomancy/textures/block/flesh_rough_1.png b/src/main/resources/assets/biomancy/textures/block/flesh_rough_1.png index 85541762e..559bc71d1 100644 Binary files a/src/main/resources/assets/biomancy/textures/block/flesh_rough_1.png and b/src/main/resources/assets/biomancy/textures/block/flesh_rough_1.png differ diff --git a/src/main/resources/assets/biomancy/textures/block/flesh_rough_2.png b/src/main/resources/assets/biomancy/textures/block/flesh_rough_2.png index 96cd1fa8b..62cbb5918 100644 Binary files a/src/main/resources/assets/biomancy/textures/block/flesh_rough_2.png and b/src/main/resources/assets/biomancy/textures/block/flesh_rough_2.png differ diff --git a/src/main/resources/assets/biomancy/textures/block/flesh_tendrils.png b/src/main/resources/assets/biomancy/textures/block/flesh_tendrils.png new file mode 100644 index 000000000..b5d65492a Binary files /dev/null and b/src/main/resources/assets/biomancy/textures/block/flesh_tendrils.png differ diff --git a/src/main/resources/assets/biomancy/textures/block/teeth.png b/src/main/resources/assets/biomancy/textures/block/teeth.png new file mode 100644 index 000000000..143349222 Binary files /dev/null and b/src/main/resources/assets/biomancy/textures/block/teeth.png differ diff --git a/src/main/resources/assets/biomancy/textures/block/tooths.png b/src/main/resources/assets/biomancy/textures/block/teeth_0.png similarity index 100% rename from src/main/resources/assets/biomancy/textures/block/tooths.png rename to src/main/resources/assets/biomancy/textures/block/teeth_0.png diff --git a/src/main/resources/assets/biomancy/textures/entity/aggressive_flesh_blob.png b/src/main/resources/assets/biomancy/textures/entity/aggressive_flesh_blob.png index e508a4a97..6d654242f 100644 Binary files a/src/main/resources/assets/biomancy/textures/entity/aggressive_flesh_blob.png and b/src/main/resources/assets/biomancy/textures/entity/aggressive_flesh_blob.png differ diff --git a/src/main/resources/assets/biomancy/textures/entity/flesh_blob.psd b/src/main/resources/assets/biomancy/textures/entity/flesh_blob.psd new file mode 100644 index 000000000..83a6c924f Binary files /dev/null and b/src/main/resources/assets/biomancy/textures/entity/flesh_blob.psd differ diff --git a/src/main/resources/assets/biomancy/textures/entity/slimflesh.png b/src/main/resources/assets/biomancy/textures/entity/slimflesh.png deleted file mode 100644 index d73565430..000000000 Binary files a/src/main/resources/assets/biomancy/textures/entity/slimflesh.png and /dev/null differ diff --git a/src/main/resources/assets/biomancy/textures/item/stomach.png b/src/main/resources/assets/biomancy/textures/item/stomach.png index 2721335b1..ea64f10b1 100644 Binary files a/src/main/resources/assets/biomancy/textures/item/stomach.png and b/src/main/resources/assets/biomancy/textures/item/stomach.png differ diff --git a/src/main/resources/biomancy.mixins.json b/src/main/resources/biomancy.mixins.json index b30843b42..ee0a47f46 100644 --- a/src/main/resources/biomancy.mixins.json +++ b/src/main/resources/biomancy.mixins.json @@ -6,6 +6,7 @@ "mixins": [ "ArmorStandEntityAccessor", "CapabilityProviderMixin", + "CauldronBlockMixin", "DamageSourceMixin", "GrindstoneContainerMixin", "LivingEntityMixin", @@ -14,13 +15,14 @@ "RecipeManagerMixinAccessor", "ServerPlayerEntityMixin", "SlimeEntityAccessor", - "SwordItemMixinAccessor" + "SwordItemMixinAccessor", + "ZombieVillagerEntityMixinAccessor" ], "client": [ + "client.ClientItemStackMixinAccessor", "client.ClientRecipeBookMixin", "client.EntityMixin", "client.GetMouseOverMixin", - "client.ItemStackMixinAccessor", "client.LivingRendererMixin", "client.MinecraftMixin", "client.PlayerRendererMixin"