diff --git a/src/datagen/java/com/github/elenterius/biomancy/datagen/loot/ModBlockLoot.java b/src/datagen/java/com/github/elenterius/biomancy/datagen/loot/ModBlockLoot.java index 2fd27bdbb..2012e5649 100644 --- a/src/datagen/java/com/github/elenterius/biomancy/datagen/loot/ModBlockLoot.java +++ b/src/datagen/java/com/github/elenterius/biomancy/datagen/loot/ModBlockLoot.java @@ -70,6 +70,7 @@ protected void addTables() { dropSelf(ModBlocks.PRIMORDIAL_CRADLE.get()); dropSelf(ModBlocks.TONGUE.get()); + dropSelf(ModBlocks.MAW_HOPPER.get()); add(ModBlocks.STORAGE_SAC.get(), ModBlockLoot::dropWithInventory); add(ModBlocks.BIO_FORGE.get(), BlockLoot::createNameableBlockEntityTable); diff --git a/src/datagen/java/com/github/elenterius/biomancy/datagen/recipes/ModRecipeProvider.java b/src/datagen/java/com/github/elenterius/biomancy/datagen/recipes/ModRecipeProvider.java index 183fd2f73..f41add000 100644 --- a/src/datagen/java/com/github/elenterius/biomancy/datagen/recipes/ModRecipeProvider.java +++ b/src/datagen/java/com/github/elenterius/biomancy/datagen/recipes/ModRecipeProvider.java @@ -719,6 +719,14 @@ private void registerBioForgeRecipes(Consumer consumer) { .setCategory(ModBioForgeTabs.MACHINES) .unlockedBy(ModItems.LIVING_FLESH.get()).save(consumer); + BioForgeRecipeBuilder.create(ModItems.MAW_HOPPER.get()) + .addIngredient(ModItems.LIVING_FLESH.get()) + .addIngredient(ModItems.FLESH_BITS.get(), 5) + .addIngredient(ModItems.BONE_FRAGMENTS.get(), 3) + .addIngredient(ModItems.ELASTIC_FIBERS.get(), 10) + .setCategory(ModBioForgeTabs.MACHINES) + .unlockedBy(ModItems.LIVING_FLESH.get()).save(consumer); + BioForgeRecipeBuilder.create(new ItemData(ModItems.FLESHKIN_PRESSURE_PLATE.get())) .addIngredient(ModItems.LIVING_FLESH.get()) .addIngredient(ModItems.BONE_FRAGMENTS.get(), 3) diff --git a/src/datagen/java/com/github/elenterius/biomancy/datagen/translations/EnglishTranslationProvider.java b/src/datagen/java/com/github/elenterius/biomancy/datagen/translations/EnglishTranslationProvider.java index 2fbc175e9..8291069ce 100644 --- a/src/datagen/java/com/github/elenterius/biomancy/datagen/translations/EnglishTranslationProvider.java +++ b/src/datagen/java/com/github/elenterius/biomancy/datagen/translations/EnglishTranslationProvider.java @@ -405,6 +405,7 @@ private void addBlockTranslations() { addBlock(ModBlocks.VOICE_BOX, "Modular Larynx", EMPTY_STRING); addBlock(ModBlocks.TONGUE, "Tongue", "Extracts up to 3 items of the same type every 24 ticks from containers its attached to and drops them on the ground."); + addBlock(ModBlocks.MAW_HOPPER, "Maw Hopper", "A fleshy sister of the hopper. Transfers up to 16 items every 24 ticks."); addBlock(ModBlocks.STORAGE_SAC, "Storage Sac", "Cheap Shulker-like storage sac that also works like a bundle."); diff --git a/src/generated/resources/assets/biomancy/lang/en_us.json b/src/generated/resources/assets/biomancy/lang/en_us.json index 03455ad4d..b7bc81e61 100644 --- a/src/generated/resources/assets/biomancy/lang/en_us.json +++ b/src/generated/resources/assets/biomancy/lang/en_us.json @@ -1,19 +1,19 @@ { - "itemGroup.biomancy": "Biomancy 2", - "key.categories.biomancy": "Biomancy 2 Mod", - "key.biomancy.item_default": "Default Item Action", - "item.biomancy.mob_sinew": "Sinew", - "item.biomancy.mob_sinew.tooltip": "Tissue made of Elastic Fibers.", - "item.biomancy.mob_fang": "Sharp Fang", - "item.biomancy.mob_fang.tooltip": "Cutting tooth made of Bone tissue rich in Bio-Minerals.", - "item.biomancy.mob_claw": "Sharp Claw", - "item.biomancy.mob_claw.tooltip": "Hardened Claw made of tough fibers and rich in Bio-Minerals.", - "item.biomancy.mob_marrow": "Bone Marrow", - "item.biomancy.mob_marrow.tooltip": "Marrow extracted from the bones of your victims. Rich in Hormones and Bio-Minerals. ", - "item.biomancy.withered_mob_marrow": "Withered Bone Marrow", - "item.biomancy.withered_mob_marrow.tooltip": "Withered Marrow, some dark fluid is oozing out of it.\nMaybe you should suck it dry...", - "item.biomancy.mob_gland": "Bile Gland", - "item.biomancy.mob_gland.tooltip": "Organ sac filled with bile to the brim.", + "itemGroup.biomancy": "Biomancy 2", + "key.categories.biomancy": "Biomancy 2 Mod", + "key.biomancy.item_default": "Default Item Action", + "item.biomancy.mob_sinew": "Sinew", + "item.biomancy.mob_sinew.tooltip": "Tissue made of Elastic Fibers.", + "item.biomancy.mob_fang": "Sharp Fang", + "item.biomancy.mob_fang.tooltip": "Cutting tooth made of Bone tissue rich in Bio-Minerals.", + "item.biomancy.mob_claw": "Sharp Claw", + "item.biomancy.mob_claw.tooltip": "Hardened Claw made of tough fibers and rich in Bio-Minerals.", + "item.biomancy.mob_marrow": "Bone Marrow", + "item.biomancy.mob_marrow.tooltip": "Marrow extracted from the bones of your victims. Rich in Hormones and Bio-Minerals. ", + "item.biomancy.withered_mob_marrow": "Withered Bone Marrow", + "item.biomancy.withered_mob_marrow.tooltip": "Withered Marrow, some dark fluid is oozing out of it.\nMaybe you should suck it dry...", + "item.biomancy.mob_gland": "Bile Gland", + "item.biomancy.mob_gland.tooltip": "Organ sac filled with bile to the brim.", "item.biomancy.toxin_gland": "Toxin Gland", "item.biomancy.toxin_gland.tooltip": "A organ full of toxin, maybe you should drink this...", "item.biomancy.volatile_gland": "Volatile Gland", @@ -120,45 +120,47 @@ "item.biomancy.absorption_boost": "Absorption Stimulant", "serum.biomancy.absorption_boost.tooltip": "Grants stackable absorption health points for Mobs and Players.", "serum.biomancy.insomnia_cure": "Insomnia Cure", - "item.biomancy.insomnia_cure": "Insomnia Cure", - "serum.biomancy.insomnia_cure.tooltip": "Resets the last slept time, no need to sleep for quite some time.", - "item.biomancy.mascot_patterns": "Banner Pattern", - "item.biomancy.mascot_patterns.desc": "Biomancy Mascot", - "item.biomancy.hungry_flesh_blob_spawn_egg": "Hungry Flesh Blob Spawn Egg", - "item.biomancy.flesh_blob_spawn_egg": "Flesh Blob Spawn Egg", - "item.biomancy.malignant_flesh_blob_spawn_egg": "Malignant Flesh Blob Spawn Egg", - "block.biomancy.primordial_cradle": "Primordial Cradle", - "block.biomancy.primordial_cradle.tooltip": "Offer adequate Tributes to the cradle and summon forth primordial messengers of exquisite flesh.", - "block.biomancy.decomposer": "Decomposer", - "block.biomancy.decomposer.tooltip": "A bio-machine that deconstructs items into their base components.\nThe bio-machine consumes nutrients to function.", - "block.biomancy.digester": "Digester", - "block.biomancy.digester.tooltip": "A machine born from flesh that converts food and plants into nutrients.", - "block.biomancy.bio_forge": "Bio-Forge", - "block.biomancy.bio_forge.tooltip": "Crafting Station", - "block.biomancy.bio_lab": "Bio-Lab", - "block.biomancy.bio_lab.tooltip": "Bio-alchemical Brewer", - "block.biomancy.voice_box": "Modular Larynx", - "block.biomancy.voice_box.tooltip": "", - "block.biomancy.tongue": "Tongue", - "block.biomancy.tongue.tooltip": "Extracts up to 3 items of the same type every 24 ticks from containers its attached to and drops them on the ground.", - "block.biomancy.storage_sac": "Storage Sac", - "block.biomancy.storage_sac.tooltip": "Cheap Shulker-like storage sac that also works like a bundle.", - "block.biomancy.fleshkin_chest": "Fleshkin Chest", - "block.biomancy.fleshkin_chest.tooltip": "A fleshkin forged into the shape of a chest with sharp teeth and a resilient stomach allowing it to keeps its contents when mined.\nOnly its master may open and takes its content without repercussion.\n\nIt's fangs look awfully sharp...", - "block.biomancy.fleshkin_door": "Fleshkin Door", - "block.biomancy.fleshkin_door.tooltip": "", - "block.biomancy.fleshkin_trapdoor": "Fleshkin Trap Door", - "block.biomancy.fleshkin_trapdoor.tooltip": "", - "block.biomancy.fleshkin_pressure_plate": "Fleshkin Pressure Sensor", - "block.biomancy.fleshkin_pressure_plate.tooltip": "Fleshkin pancake. Yummy...\nIt has two behaviors, either it only activates for its owner or it only works for everyone else.\n\nSneak click to change its behavior.", - "block.biomancy.flesh": "Flesh Block", - "block.biomancy.flesh.tooltip": "A generic block of flesh... Don't bother me with this!", - "block.biomancy.flesh_slab": "Flesh Slab", - "block.biomancy.flesh_slab.tooltip": "A generic slab of flesh... Don't bother me with this!", - "block.biomancy.flesh_stairs": "Flesh Stairs", - "block.biomancy.flesh_stairs.tooltip": "Stairs made of generic flesh... Don't bother me with this!", - "block.biomancy.flesh_wall": "Flesh Wall", - "block.biomancy.flesh_wall.tooltip": "A generic wall of flesh.", + "item.biomancy.insomnia_cure": "Insomnia Cure", + "serum.biomancy.insomnia_cure.tooltip": "Resets the last slept time, no need to sleep for quite some time.", + "item.biomancy.mascot_patterns": "Banner Pattern", + "item.biomancy.mascot_patterns.desc": "Biomancy Mascot", + "item.biomancy.hungry_flesh_blob_spawn_egg": "Hungry Flesh Blob Spawn Egg", + "item.biomancy.flesh_blob_spawn_egg": "Flesh Blob Spawn Egg", + "item.biomancy.malignant_flesh_blob_spawn_egg": "Malignant Flesh Blob Spawn Egg", + "block.biomancy.primordial_cradle": "Primordial Cradle", + "block.biomancy.primordial_cradle.tooltip": "Offer adequate Tributes to the cradle and summon forth primordial messengers of exquisite flesh.", + "block.biomancy.decomposer": "Decomposer", + "block.biomancy.decomposer.tooltip": "A bio-machine that deconstructs items into their base components.\nThe bio-machine consumes nutrients to function.", + "block.biomancy.digester": "Digester", + "block.biomancy.digester.tooltip": "A machine born from flesh that converts food and plants into nutrients.", + "block.biomancy.bio_forge": "Bio-Forge", + "block.biomancy.bio_forge.tooltip": "Crafting Station", + "block.biomancy.bio_lab": "Bio-Lab", + "block.biomancy.bio_lab.tooltip": "Bio-alchemical Brewer", + "block.biomancy.voice_box": "Modular Larynx", + "block.biomancy.voice_box.tooltip": "", + "block.biomancy.tongue": "Tongue", + "block.biomancy.tongue.tooltip": "Extracts up to 3 items of the same type every 24 ticks from containers its attached to and drops them on the ground.", + "block.biomancy.maw_hopper": "Maw Hopper", + "block.biomancy.maw_hopper.tooltip": "A fleshy sister of the hopper. Transfers up to 16 items every 24 ticks.", + "block.biomancy.storage_sac": "Storage Sac", + "block.biomancy.storage_sac.tooltip": "Cheap Shulker-like storage sac that also works like a bundle.", + "block.biomancy.fleshkin_chest": "Fleshkin Chest", + "block.biomancy.fleshkin_chest.tooltip": "A fleshkin forged into the shape of a chest with sharp teeth and a resilient stomach allowing it to keeps its contents when mined.\nOnly its master may open and takes its content without repercussion.\n\nIt's fangs look awfully sharp...", + "block.biomancy.fleshkin_door": "Fleshkin Door", + "block.biomancy.fleshkin_door.tooltip": "", + "block.biomancy.fleshkin_trapdoor": "Fleshkin Trap Door", + "block.biomancy.fleshkin_trapdoor.tooltip": "", + "block.biomancy.fleshkin_pressure_plate": "Fleshkin Pressure Sensor", + "block.biomancy.fleshkin_pressure_plate.tooltip": "Fleshkin pancake. Yummy...\nIt has two behaviors, either it only activates for its owner or it only works for everyone else.\n\nSneak click to change its behavior.", + "block.biomancy.flesh": "Flesh Block", + "block.biomancy.flesh.tooltip": "A generic block of flesh... Don't bother me with this!", + "block.biomancy.flesh_slab": "Flesh Slab", + "block.biomancy.flesh_slab.tooltip": "A generic slab of flesh... Don't bother me with this!", + "block.biomancy.flesh_stairs": "Flesh Stairs", + "block.biomancy.flesh_stairs.tooltip": "Stairs made of generic flesh... Don't bother me with this!", + "block.biomancy.flesh_wall": "Flesh Wall", + "block.biomancy.flesh_wall.tooltip": "A generic wall of flesh.", "block.biomancy.packed_flesh": "Packed Flesh Block", "block.biomancy.packed_flesh.tooltip": "Tenacious Block of flesh. Is it tough enough?", "block.biomancy.packed_flesh_slab": "Packed Flesh Slab", @@ -229,26 +231,26 @@ "tooltip.biomancy.bile_fuel": "Bile", "tooltip.biomancy.contains_unique_dna": "Contains Unique Genetic Sequences", "tooltip.biomancy.press_button_to": "Press %1$s to %2$s", - "tooltip.biomancy.owner": "Owner: %1$s", - "tooltip.biomancy.slots": "Slots", - "tooltip.biomancy.drops_from": "Drops from", - "tooltip.biomancy.and_more": "and more...", - "tooltip.biomancy.action.show_info": "show info", - "tooltip.biomancy.action.self_inject": "inject yourself", - "tooltip.biomancy.action.self_extract": "extract from yourself", - "tooltip.biomancy.action.open_inventory": "open its inventory", - "tooltip.biomancy.action.activate": "activate", - "tooltip.biomancy.action.deactivate": "deactivate", - "tooltip.biomancy.action.reload": "reload", - "tooltip.biomancy.action.cycle": "cycle", - "tooltip.biomancy.fire_rate": "Fire Rate", - "tooltip.biomancy.accuracy": "Accuracy", - "tooltip.biomancy.ammo": "Ammo", - "tooltip.biomancy.reload_time": "Reload Time", - "tooltip.biomancy.projectile_damage": "Projectile Damage", - "tooltip.biomancy.living_tool_state_is": "The Tool is %1$s", - "state.biomancy.living_tool.dormant": "Dormant", - "state.biomancy.living_tool.awake": "Awake", + "tooltip.biomancy.owner": "Owner: %1$s", + "tooltip.biomancy.slots": "Slots", + "tooltip.biomancy.drops_from": "Drops from", + "tooltip.biomancy.and_more": "and more...", + "tooltip.biomancy.action.show_info": "show info", + "tooltip.biomancy.action.self_inject": "inject yourself", + "tooltip.biomancy.action.self_extract": "extract from yourself", + "tooltip.biomancy.action.open_inventory": "open its inventory", + "tooltip.biomancy.action.activate": "activate", + "tooltip.biomancy.action.deactivate": "deactivate", + "tooltip.biomancy.action.reload": "reload", + "tooltip.biomancy.action.cycle": "cycle", + "tooltip.biomancy.fire_rate": "Fire Rate", + "tooltip.biomancy.accuracy": "Accuracy", + "tooltip.biomancy.ammo": "Ammo", + "tooltip.biomancy.reload_time": "Reload Time", + "tooltip.biomancy.projectile_damage": "Projectile Damage", + "tooltip.biomancy.living_tool_state_is": "The Tool is %1$s", + "state.biomancy.living_tool.dormant": "Dormant", + "state.biomancy.living_tool.awake": "Awake", "state.biomancy.living_tool.exalted": "Exalted", "msg.biomancy.not_sleepy": "You don't feel sleepy...", "msg.biomancy.set_behavior_command": "%1$s will now execute the %2$s command", @@ -281,26 +283,26 @@ "sounds.biomancy.fleshkin_chest.close": "Close Fleshy Chest", "sounds.biomancy.fleshkin_chest.bite_attack": "Fleshy Chest Bite Attack", "sounds.biomancy.fleshkin_chest.no": "Fleshy Chest says No", - "sounds.biomancy.block.creator.spawn_mob": "Primordial Cradle Spawns a Mob", - "sounds.biomancy.block.creator.became_full": "Primordial Cradle became full", - "sounds.biomancy.block.creator.eat": "Primordial Cradle Eating", - "sounds.biomancy.block.creator.no": "Primordial Cradle says No", - "sounds.biomancy.ui.storage_sac.open": "Open Menu of Storage Sac", - "sounds.biomancy.ui.bio_forge.open": "Open Menu of Bio-Forge", - "sounds.biomancy.ui.bio_forge.select_recipe": "Select Recipe in Bio-Forge", - "sounds.biomancy.ui.bio_forge.take_result": "Craft Item in Bio-Forge", - "sounds.biomancy.block.decomposer.crafting": "Decomposer is crafting", - "sounds.biomancy.ui.decomposer.open": "Open Menu of Decomposer", - "sounds.biomancy.block.decomposer.eat": "Decomposer is eating", - "sounds.biomancy.block.decomposer.crafting_random": "Decomposer is burping", - "sounds.biomancy.block.decomposer.crafting_completed": "Decomposer finished crafting", - "sounds.biomancy.block.bio_lab.crafting": "Bio-Lab is crafting", - "sounds.biomancy.ui.bio_lab.open": "Open Menu of Bio-Lab", - "sounds.biomancy.block.bio_lab.crafting_random": "Bio-Lab is slurping", - "sounds.biomancy.block.bio_lab.crafting_completed": "Bio-Lab finished crafting", - "sounds.biomancy.block.digester.crafting": "Digester is crafting", - "sounds.biomancy.ui.digester.open": "Open Menu of Digester", - "sounds.biomancy.block.digester.crafting_random": "Digester is burping", + "sounds.biomancy.block.creator.spawn_mob": "Primordial Cradle Spawns a Mob", + "sounds.biomancy.block.creator.became_full": "Primordial Cradle became full", + "sounds.biomancy.block.creator.eat": "Primordial Cradle Eating", + "sounds.biomancy.block.creator.no": "Primordial Cradle says No", + "sounds.biomancy.ui.storage_sac.open": "Open Menu of Storage Sac", + "sounds.biomancy.ui.bio_forge.open": "Open Menu of Bio-Forge", + "sounds.biomancy.ui.bio_forge.select_recipe": "Select Recipe in Bio-Forge", + "sounds.biomancy.ui.bio_forge.take_result": "Craft Item in Bio-Forge", + "sounds.biomancy.block.decomposer.crafting": "Decomposer is crafting", + "sounds.biomancy.ui.decomposer.open": "Open Menu of Decomposer", + "sounds.biomancy.block.decomposer.eat": "Decomposer is eating", + "sounds.biomancy.block.decomposer.crafting_random": "Decomposer is burping", + "sounds.biomancy.block.decomposer.crafting_completed": "Decomposer finished crafting", + "sounds.biomancy.block.bio_lab.crafting": "Bio-Lab is crafting", + "sounds.biomancy.ui.bio_lab.open": "Open Menu of Bio-Lab", + "sounds.biomancy.block.bio_lab.crafting_random": "Bio-Lab is slurping", + "sounds.biomancy.block.bio_lab.crafting_completed": "Bio-Lab finished crafting", + "sounds.biomancy.block.digester.crafting": "Digester is crafting", + "sounds.biomancy.ui.digester.open": "Open Menu of Digester", + "sounds.biomancy.block.digester.crafting_random": "Digester is burping", "sounds.biomancy.block.digester.crafting_completed": "Digester finished crafting", "sounds.biomancy.entity.flesh_blob.jump": "Flesh Blob Jump", "sounds.biomancy.entity.flesh_blob.hurt": "Flesh Blob Hurt", diff --git a/src/main/java/com/github/elenterius/biomancy/client/render/block/mawhopper/MawHopperModel.java b/src/main/java/com/github/elenterius/biomancy/client/render/block/mawhopper/MawHopperModel.java new file mode 100644 index 000000000..ce421238a --- /dev/null +++ b/src/main/java/com/github/elenterius/biomancy/client/render/block/mawhopper/MawHopperModel.java @@ -0,0 +1,23 @@ +package com.github.elenterius.biomancy.client.render.block.mawhopper; + +import com.github.elenterius.biomancy.BiomancyMod; +import com.github.elenterius.biomancy.world.block.mawhopper.MawHopperBlockEntity; +import net.minecraft.resources.ResourceLocation; +import software.bernie.geckolib3.model.AnimatedGeoModel; + +public class MawHopperModel extends AnimatedGeoModel { + @Override + public ResourceLocation getModelResource(MawHopperBlockEntity blockEntity) { + return BiomancyMod.createRL("geo/block/maw_hopper.geo.json"); + } + + @Override + public ResourceLocation getTextureResource(MawHopperBlockEntity blockEntity) { + return BiomancyMod.createRL("textures/block/maw_hopper.png"); + } + + @Override + public ResourceLocation getAnimationResource(MawHopperBlockEntity blockEntity) { + return BiomancyMod.createRL("animations/block/maw_hopper.animation.json"); + } +} diff --git a/src/main/java/com/github/elenterius/biomancy/client/render/block/mawhopper/MawHopperRenderer.java b/src/main/java/com/github/elenterius/biomancy/client/render/block/mawhopper/MawHopperRenderer.java new file mode 100644 index 000000000..31780e40a --- /dev/null +++ b/src/main/java/com/github/elenterius/biomancy/client/render/block/mawhopper/MawHopperRenderer.java @@ -0,0 +1,21 @@ +package com.github.elenterius.biomancy.client.render.block.mawhopper; + +import com.github.elenterius.biomancy.client.render.block.CustomGeoBlockRenderer; +import com.github.elenterius.biomancy.world.block.mawhopper.MawHopperBlockEntity; +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; +import net.minecraft.core.Direction; + +public class MawHopperRenderer extends CustomGeoBlockRenderer { + public MawHopperRenderer(BlockEntityRendererProvider.Context context) { + super(context, new MawHopperModel()); + } + + @Override + protected void rotateBlock(Direction facing, PoseStack poseStack) { + poseStack.translate(0, 0.5, 0); + poseStack.mulPose(facing.getRotation()); + poseStack.translate(0, -0.5, 0); + } + +} diff --git a/src/main/java/com/github/elenterius/biomancy/init/ModBlockEntities.java b/src/main/java/com/github/elenterius/biomancy/init/ModBlockEntities.java index ac4936570..4bd83f079 100644 --- a/src/main/java/com/github/elenterius/biomancy/init/ModBlockEntities.java +++ b/src/main/java/com/github/elenterius/biomancy/init/ModBlockEntities.java @@ -8,6 +8,7 @@ import com.github.elenterius.biomancy.world.block.digester.DigesterBlockEntity; import com.github.elenterius.biomancy.world.block.entity.BlockEntityDelegator; import com.github.elenterius.biomancy.world.block.fleshkinchest.FleshkinChestBlockEntity; +import com.github.elenterius.biomancy.world.block.mawhopper.MawHopperBlockEntity; import com.github.elenterius.biomancy.world.block.modularlarynx.VoiceBoxBlockEntity; import com.github.elenterius.biomancy.world.block.ownable.OwnableBlockEntity; import com.github.elenterius.biomancy.world.block.storagesac.StorageSacBlockEntity; @@ -32,6 +33,7 @@ public final class ModBlockEntities { public static final RegistryObject> DIGESTER = register(ModBlocks.DIGESTER, DigesterBlockEntity::new); public static final RegistryObject> TONGUE = register(ModBlocks.TONGUE, TongueBlockEntity::new); + public static final RegistryObject> MAW_HOPPER = register(ModBlocks.MAW_HOPPER, MawHopperBlockEntity::new); public static final RegistryObject> STORAGE_SAC = register(ModBlocks.STORAGE_SAC, StorageSacBlockEntity::new); public static final RegistryObject> FLESHKIN_CHEST = register(ModBlocks.FLESHKIN_CHEST, FleshkinChestBlockEntity::new); public static final RegistryObject> VOICE_BOX = register(ModBlocks.VOICE_BOX, VoiceBoxBlockEntity::new); 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 c8521fa01..94583eecb 100644 --- a/src/main/java/com/github/elenterius/biomancy/init/ModBlocks.java +++ b/src/main/java/com/github/elenterius/biomancy/init/ModBlocks.java @@ -8,6 +8,7 @@ import com.github.elenterius.biomancy.world.block.decomposer.DecomposerBlock; import com.github.elenterius.biomancy.world.block.digester.DigesterBlock; import com.github.elenterius.biomancy.world.block.fleshkinchest.FleshkinChestBlock; +import com.github.elenterius.biomancy.world.block.mawhopper.MawHopperBlock; import com.github.elenterius.biomancy.world.block.modularlarynx.VoiceBoxBlock; import com.github.elenterius.biomancy.world.block.ownable.OwnableDoorBlock; import com.github.elenterius.biomancy.world.block.ownable.OwnablePressurePlateBlock; @@ -62,6 +63,7 @@ public final class ModBlocks { //## Automation & Storage public static final RegistryObject STORAGE_SAC = BLOCKS.register("storage_sac", () -> new StorageSacBlock(createFleshProperties())); public static final RegistryObject TONGUE = BLOCKS.register("tongue", () -> new TongueBlock(createFleshProperties())); + public static final RegistryObject MAW_HOPPER = BLOCKS.register("maw_hopper", () -> new MawHopperBlock(createFleshProperties())); //## Ownable public static final RegistryObject FLESHKIN_CHEST = BLOCKS.register("fleshkin_chest", () -> new FleshkinChestBlock(createFleshProperties())); 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 a576490fb..edba3408c 100644 --- a/src/main/java/com/github/elenterius/biomancy/init/ModItems.java +++ b/src/main/java/com/github/elenterius/biomancy/init/ModItems.java @@ -117,6 +117,7 @@ public final class ModItems { //## Storage & Automation public static final RegistryObject TONGUE = registerSimpleBlockItem(ModBlocks.TONGUE, ModRarities.UNCOMMON); + public static final RegistryObject MAW_HOPPER = registerBlockItem(ModBlocks.MAW_HOPPER, block -> new BEWLBlockItem(block, createBaseProperties().rarity(ModRarities.UNCOMMON))); public static final RegistryObject FLESHKIN_CHEST = ITEMS.register(ModBlocks.FLESHKIN_CHEST.getId().getPath(), () -> new FleshkinChestBlockItem(ModBlocks.FLESHKIN_CHEST.get(), createBaseProperties().rarity(ModRarities.UNCOMMON))); public static final RegistryObject STORAGE_SAC = ITEMS.register(ModBlocks.STORAGE_SAC.getId().getPath(), () -> new StorageSacBlockItem(ModBlocks.STORAGE_SAC.get(), createBaseProperties())); diff --git a/src/main/java/com/github/elenterius/biomancy/init/client/ClientSetupHandler.java b/src/main/java/com/github/elenterius/biomancy/init/client/ClientSetupHandler.java index c87a1adc0..e2fac7ac6 100644 --- a/src/main/java/com/github/elenterius/biomancy/init/client/ClientSetupHandler.java +++ b/src/main/java/com/github/elenterius/biomancy/init/client/ClientSetupHandler.java @@ -12,6 +12,7 @@ import com.github.elenterius.biomancy.client.render.block.decomposer.DecomposerRenderer; import com.github.elenterius.biomancy.client.render.block.digester.DigesterRenderer; import com.github.elenterius.biomancy.client.render.block.fleshkinchest.FleshkinChestRenderer; +import com.github.elenterius.biomancy.client.render.block.mawhopper.MawHopperRenderer; import com.github.elenterius.biomancy.client.render.block.storagesac.StorageSacRenderer; import com.github.elenterius.biomancy.client.render.block.tongue.TongueBlockEntityRenderer; import com.github.elenterius.biomancy.client.render.entity.AcidProjectileRenderer; @@ -85,6 +86,7 @@ public static void registerRenderers(final EntityRenderersEvent.RegisterRenderer event.registerBlockEntityRenderer(ModBlockEntities.TONGUE.get(), TongueBlockEntityRenderer::new); event.registerBlockEntityRenderer(ModBlockEntities.FLESHKIN_CHEST.get(), FleshkinChestRenderer::new); event.registerBlockEntityRenderer(ModBlockEntities.STORAGE_SAC.get(), StorageSacRenderer::new); + event.registerBlockEntityRenderer(ModBlockEntities.MAW_HOPPER.get(), MawHopperRenderer::new); event.registerEntityRenderer(ModEntityTypes.HUNGRY_FLESH_BLOB.get(), FleshBlobRenderer::new); event.registerEntityRenderer(ModEntityTypes.FLESH_BLOB.get(), FleshBlobRenderer::new); diff --git a/src/main/java/com/github/elenterius/biomancy/world/block/mawhopper/MawHopperBlock.java b/src/main/java/com/github/elenterius/biomancy/world/block/mawhopper/MawHopperBlock.java new file mode 100644 index 000000000..3b690dd24 --- /dev/null +++ b/src/main/java/com/github/elenterius/biomancy/world/block/mawhopper/MawHopperBlock.java @@ -0,0 +1,132 @@ +package com.github.elenterius.biomancy.world.block.mawhopper; + +import com.github.elenterius.biomancy.init.ModBlockEntities; +import com.github.elenterius.biomancy.util.VoxelShapeUtil; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.BaseEntityBlock; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Mirror; +import net.minecraft.world.level.block.Rotation; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityTicker; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.DirectionProperty; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.shapes.BooleanOp; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.Shapes; +import net.minecraft.world.phys.shapes.VoxelShape; +import org.jetbrains.annotations.Nullable; + +import java.util.stream.Stream; + +public class MawHopperBlock extends BaseEntityBlock { + + public static final DirectionProperty FACING = BlockStateProperties.FACING; + + public static final VoxelShape SHAPE_UP = createVoxelShape(Direction.UP); + public static final VoxelShape SHAPE_DOWN = createVoxelShape(Direction.DOWN); + public static final VoxelShape SHAPE_NORTH = createVoxelShape(Direction.NORTH); + public static final VoxelShape SHAPE_SOUTH = createVoxelShape(Direction.SOUTH); + public static final VoxelShape SHAPE_WEST = createVoxelShape(Direction.WEST); + public static final VoxelShape SHAPE_EAST = createVoxelShape(Direction.EAST); + + public MawHopperBlock(Properties properties) { + super(properties); + } + + private static VoxelShape createVoxelShape(Direction direction) { + return Stream.of( + VoxelShapeUtil.createXZRotatedTowards(direction, 7, 0, 7, 9, 2, 9), + VoxelShapeUtil.createXZRotatedTowards(direction, 6, 2, 6, 10, 6, 10), + VoxelShapeUtil.createXZRotatedTowards(direction, 5, 6, 5, 11, 10, 11), + VoxelShapeUtil.createXZRotatedTowards(direction, 3, 10, 3, 13, 13, 13), + VoxelShapeUtil.createXZRotatedTowards(direction, 0, 13, 3, 16, 16, 13), + VoxelShapeUtil.createXZRotatedTowards(direction, 3, 13, 0, 13, 16, 16) + ).reduce((a, b) -> Shapes.join(a, b, BooleanOp.OR)).orElse(Shapes.block()); + } + + public static Direction getDirection(BlockState state) { + return state.getValue(FACING); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder builder) { + builder.add(FACING); + } + + @Nullable + @Override + public BlockState getStateForPlacement(BlockPlaceContext context) { + return defaultBlockState().setValue(FACING, context.getClickedFace()); + } + + @Override + public InteractionResult use(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { + return super.use(state, level, pos, player, hand, hit); + } + + @Override + public void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean isMoving) { + if (!state.is(newState.getBlock())) { + if (level.getBlockEntity(pos) instanceof MawHopperBlockEntity blockEntity) { + blockEntity.dropContainerContents(level, pos); + } + super.onRemove(state, level, pos, newState, isMoving); + } + } + + @Nullable + @Override + public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { + return ModBlockEntities.MAW_HOPPER.get().create(pos, state); + } + + @Nullable + @Override + public BlockEntityTicker getTicker(Level level, BlockState state, BlockEntityType blockEntityType) { + return level.isClientSide ? null : createTickerHelper(blockEntityType, ModBlockEntities.MAW_HOPPER.get(), MawHopperBlockEntity::serverTick); + } + + @Override + public void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) { + BlockEntity blockentity = level.getBlockEntity(pos); + if (blockentity instanceof MawHopperBlockEntity blockEntity) { + MawHopperBlockEntity.entityInside(level, pos, state, blockEntity, entity); + } + } + + @Override + public VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) { + return switch (state.getValue(FACING)) { + case DOWN -> SHAPE_DOWN; + case NORTH -> SHAPE_NORTH; + case SOUTH -> SHAPE_SOUTH; + case WEST -> SHAPE_WEST; + case EAST -> SHAPE_EAST; + default -> SHAPE_UP; + }; + } + + @Override + public BlockState rotate(BlockState state, Rotation rot) { + return state.setValue(FACING, rot.rotate(state.getValue(FACING))); + } + + @Override + public BlockState mirror(BlockState state, Mirror mirror) { + return state.rotate(mirror.getRotation(state.getValue(FACING))); + } + +} diff --git a/src/main/java/com/github/elenterius/biomancy/world/block/mawhopper/MawHopperBlockEntity.java b/src/main/java/com/github/elenterius/biomancy/world/block/mawhopper/MawHopperBlockEntity.java new file mode 100644 index 000000000..243b46251 --- /dev/null +++ b/src/main/java/com/github/elenterius/biomancy/world/block/mawhopper/MawHopperBlockEntity.java @@ -0,0 +1,230 @@ +package com.github.elenterius.biomancy.world.block.mawhopper; + +import com.github.elenterius.biomancy.BiomancyMod; +import com.github.elenterius.biomancy.init.ModBlockEntities; +import com.github.elenterius.biomancy.init.ModCapabilities; +import com.github.elenterius.biomancy.world.inventory.itemhandler.EnhancedItemHandler; +import com.github.elenterius.biomancy.world.inventory.itemhandler.SingleItemStackHandler; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.Containers; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntitySelector; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.AABB; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.items.IItemHandler; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import software.bernie.geckolib3.core.IAnimatable; +import software.bernie.geckolib3.core.PlayState; +import software.bernie.geckolib3.core.builder.AnimationBuilder; +import software.bernie.geckolib3.core.controller.AnimationController; +import software.bernie.geckolib3.core.event.predicate.AnimationEvent; +import software.bernie.geckolib3.core.manager.AnimationData; +import software.bernie.geckolib3.core.manager.AnimationFactory; +import software.bernie.geckolib3.util.GeckoLibUtil; + +import java.util.List; + +public class MawHopperBlockEntity extends BlockEntity implements IAnimatable { + + public static final String INVENTORY_TAG = "Inventory"; + public static final int ITEM_TRANSFER_AMOUNT = 16; + public static final int DURATION = 24; + public static final int DELAY = 8 + 1; //ceil(31.2) --> 32 + + private int ticks = BiomancyMod.GLOBAL_RANDOM.nextInt(DURATION); + + private final SingleItemStackHandler inventory; + private LazyOptional optionalItemHandler; + + private final AnimationFactory animationFactory = GeckoLibUtil.createFactory(this); + + public MawHopperBlockEntity(BlockPos pos, BlockState blockState) { + super(ModBlockEntities.MAW_HOPPER.get(), pos, blockState); + inventory = new SingleItemStackHandler() { + @Override + protected void onContentsChanged() { + setChanged(); + } + }; + optionalItemHandler = LazyOptional.of(() -> inventory); + } + + public static void serverTick(Level level, BlockPos pos, BlockState state, MawHopperBlockEntity entity) { + entity.serverTick((ServerLevel) level, pos, state); + } + + private static LazyOptional getItemHandler(ServerLevel level, BlockPos pos, @Nullable Direction direction) { + BlockState state = level.getBlockState(pos); + if (state.hasBlockEntity()) { + BlockEntity blockEntity = level.getBlockEntity(pos); + if (blockEntity != null) { + LazyOptional capability = blockEntity.getCapability(ModCapabilities.ITEM_HANDLER, direction); + if (capability.isPresent()) return capability; + } + } + + List list = level.getEntities((Entity) null, new AABB(pos), entity -> entity.getCapability(ModCapabilities.ITEM_HANDLER, direction).isPresent()); + if (!list.isEmpty()) { + int index = level.random.nextInt(list.size()); + return list.get(index).getCapability(ModCapabilities.ITEM_HANDLER, direction); + } + + return LazyOptional.empty(); + } + + public static void entityInside(Level level, BlockPos pos, BlockState state, MawHopperBlockEntity blockEntity, Entity entity) { + if (level.isClientSide) return; + + if (entity instanceof ItemEntity itemEntity) { + AABB aabb = new AABB(pos.relative(MawHopperBlock.getDirection(state))); + if (aabb.intersects(entity.getBoundingBox())) { + addItem(blockEntity.inventory, itemEntity); + } + } + } + + private static boolean addItem(SingleItemStackHandler handler, ItemEntity itemEntity) { + ItemStack copy = itemEntity.getItem().copy(); + int oldCount = copy.getCount(); + + ItemStack remainder = handler.insertItem(copy, false); + + if (remainder.isEmpty()) { + itemEntity.discard(); + return true; + } + + if (remainder.getCount() != oldCount) { + itemEntity.setItem(remainder); + return true; + } + + return false; + } + + @Override + public @NotNull LazyOptional getCapability(@NotNull Capability cap, @Nullable Direction side) { + if (!remove && cap == ModCapabilities.ITEM_HANDLER) return optionalItemHandler.cast(); + return super.getCapability(cap, side); + } + + @Override + public void invalidateCaps() { + super.invalidateCaps(); + optionalItemHandler.invalidate(); + } + + @Override + public void reviveCaps() { + super.reviveCaps(); + optionalItemHandler = LazyOptional.of(() -> inventory); + } + + private void serverTick(ServerLevel level, BlockPos pos, BlockState state) { + ticks++; + + if (ticks % DURATION == 0 && !inventory.isEmpty()) { + Direction direction = MawHopperBlock.getDirection(state); + BlockPos insertPos = pos.relative(direction.getOpposite()); + if (level.isLoaded(insertPos)) { + LazyOptional itemHandler = getItemHandler(level, insertPos, direction); + itemHandler.map(this::tryToInsertItems); + } + } + + if (ticks % (DURATION + DELAY) == 0 && !inventory.isFull()) { + BlockPos pullPos = pos.relative(MawHopperBlock.getDirection(state)); + if (level.isLoaded(pullPos)) { + LazyOptional itemHandler = getItemHandler(level, pullPos, Direction.DOWN); + if (!itemHandler.map(this::tryToExtractItems).orElse(false)) { + pullItemEntities(level, pullPos); + } + } + } + } + + private boolean tryToInsertItems(IItemHandler itemHandler) { + ItemStack stack = inventory.extractItem(ITEM_TRANSFER_AMOUNT, false); + if (stack.isEmpty()) return false; + int oldCount = stack.getCount(); + + EnhancedItemHandler handler = new EnhancedItemHandler(itemHandler); + ItemStack remainder = handler.insertItem(stack, false); + + boolean success = remainder.getCount() != oldCount; + + if (!remainder.isEmpty()) { + inventory.insertItem(remainder, false); + } + + return success; + } + + private boolean tryToExtractItems(IItemHandler itemHandler) { + if (inventory.isFull()) return false; + + EnhancedItemHandler handler = new EnhancedItemHandler(itemHandler); + ItemStack extractedStack = handler.extractItemFirstFound(ITEM_TRANSFER_AMOUNT, false); + if (!extractedStack.isEmpty()) { + inventory.insertItem(extractedStack, false); + return true; + } + + return false; + } + + private void pullItemEntities(ServerLevel level, BlockPos pos) { + List entities = level.getEntitiesOfClass(ItemEntity.class, new AABB(pos), EntitySelector.ENTITY_STILL_ALIVE); + for (ItemEntity itemEntity : entities) { + if (addItem(inventory, itemEntity)) return; + } + } + + public void dropContainerContents(Level level, BlockPos pos) { + Containers.dropItemStack(level, pos.getX(), pos.getY(), pos.getZ(), inventory.getStack()); + } + + @Override + protected void saveAdditional(CompoundTag tag) { + super.saveAdditional(tag); + tag.put(INVENTORY_TAG, inventory.serializeNBT()); + } + + @Override + public void load(CompoundTag tag) { + super.load(tag); + inventory.deserializeNBT(tag.getCompound(INVENTORY_TAG)); + } + + private PlayState handleAnim(AnimationEvent event) { + // if (inventory.isEmpty()) { + // event.getController().setAnimation(new AnimationBuilder().loop("idle")); + // } + // else { + // event.getController().setAnimation(new AnimationBuilder().loop("pumping")); + // } + event.getController().setAnimation(new AnimationBuilder().loop("pumping")); + return PlayState.CONTINUE; + } + + @Override + public void registerControllers(AnimationData data) { + data.addAnimationController(new AnimationController<>(this, "controller", 0, this::handleAnim)); + } + + @Override + public AnimationFactory getFactory() { + return animationFactory; + } + +} diff --git a/src/main/java/com/github/elenterius/biomancy/world/block/mawhopper/package-info.java b/src/main/java/com/github/elenterius/biomancy/world/block/mawhopper/package-info.java new file mode 100644 index 000000000..d2cbedd68 --- /dev/null +++ b/src/main/java/com/github/elenterius/biomancy/world/block/mawhopper/package-info.java @@ -0,0 +1,7 @@ +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +package com.github.elenterius.biomancy.world.block.mawhopper; + +import net.minecraft.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file diff --git a/src/main/resources/assets/biomancy/animations/block/maw_hopper.animation.json b/src/main/resources/assets/biomancy/animations/block/maw_hopper.animation.json new file mode 100644 index 000000000..02c8e909e --- /dev/null +++ b/src/main/resources/assets/biomancy/animations/block/maw_hopper.animation.json @@ -0,0 +1,253 @@ +{ + "format_version": "1.8.0", + "animations": { + "idle": { + "loop": true, + "animation_length": 2, + "override_previous_animation": true, + "bones": { + "teeth_1": { + "rotation": { + "0.0": { + "vector": [ 0, 0, 0 ] + }, + "2.0": { + "vector": [ 0, 720, 0 ] + } + } + }, + "teeth_2": { + "rotation": { + "0.0": { + "vector": [ 0, -45, 0 ] + }, + "2.0": { + "vector": [ 0, -585, 0 ] + } + } + }, + "teeth_3": { + "rotation": { + "0.0": { + "vector": [ 0, 0, 0 ] + }, + "2.0": { + "vector": [ 0, 360, 0 ] + } + } + } + } + }, + "pumping": { + "loop": true, + "animation_length": 2.125, + "override_previous_animation": true, + "bones": { + "teeth_1": { + "rotation": { + "0.0": { + "vector": [ 0, 0, 0 ] + }, + "2.125": { + "vector": [ 0, 720, 0 ] + } + } + }, + "teeth_2": { + "rotation": { + "0.0": { + "vector": [ 0, -45, 0 ] + }, + "2.125": { + "vector": [ 0, -585, 0 ] + } + } + }, + "teeth_3": { + "rotation": { + "0.0": { + "vector": [ 0, 0, 0 ] + }, + "2.125": { + "vector": [ 0, 360, 0 ] + } + } + }, + "segment_1": { + "scale": { + "0.0": { + "vector": [ 1.045, 1, 1.045 ] + }, + "0.2083": { + "vector": [ 1.075, 1, 1.075 ] + }, + "0.4167": { + "vector": [ 1, 1, 1 ] + }, + "0.5833": { + "vector": [ 1.075, 1, 1.075 ] + }, + "0.7917": { + "vector": [ 1, 1, 1 ] + }, + "1.0": { + "vector": [ 1.075, 1, 1.075 ] + }, + "1.2083": { + "vector": [ 1, 1, 1 ] + }, + "1.4167": { + "vector": [ 1.075, 1, 1.075 ] + }, + "1.5833": { + "vector": [ 1, 1, 1 ] + }, + "1.7917": { + "vector": [ 1.075, 1, 1.075 ] + }, + "2.0": { + "vector": [ 1, 1, 1 ] + }, + "2.125": { + "vector": [ 1.045, 1, 1.045 ] + } + } + }, + "segment_2": { + "scale": { + "0.0": { + "vector": [ 1.03, 1, 1.03 ] + }, + "0.0417": { + "vector": [ 1, 1, 1 ] + }, + "0.25": { + "vector": [ 1.075, 1, 1.075 ] + }, + "0.4583": { + "vector": [ 1, 1, 1 ] + }, + "0.625": { + "vector": [ 1.075, 1, 1.075 ] + }, + "0.8333": { + "vector": [ 1, 1, 1 ] + }, + "1.0417": { + "vector": [ 1.075, 1, 1.075 ] + }, + "1.25": { + "vector": [ 1, 1, 1 ] + }, + "1.4583": { + "vector": [ 1.075, 1, 1.075 ] + }, + "1.625": { + "vector": [ 1, 1, 1 ] + }, + "1.8333": { + "vector": [ 1.075, 1, 1.075 ] + }, + "2.0417": { + "vector": [ 1, 1, 1 ] + }, + "2.125": { + "vector": [ 1.03, 1, 1.03 ] + } + } + }, + "segment_3": { + "scale": { + "0.0": { + "vector": [ 1, 1, 1 ] + }, + "0.0833": { + "vector": [ 1, 1, 1 ] + }, + "0.2917": { + "vector": [ 1.075, 1, 1.075 ] + }, + "0.5": { + "vector": [ 1, 1, 1 ] + }, + "0.6667": { + "vector": [ 1.075, 1, 1.075 ] + }, + "0.875": { + "vector": [ 1, 1, 1 ] + }, + "1.0833": { + "vector": [ 1.075, 1, 1.075 ] + }, + "1.2917": { + "vector": [ 1, 1, 1 ] + }, + "1.5": { + "vector": [ 1.075, 1, 1.075 ] + }, + "1.6667": { + "vector": [ 1, 1, 1 ] + }, + "1.875": { + "vector": [ 1.075, 1, 1.075 ] + }, + "2.0833": { + "vector": [ 1, 1, 1 ] + }, + "2.125": { + "vector": [ 1, 1, 1 ] + } + } + }, + "segment_4": { + "scale": { + "0.125": { + "vector": [ 1, 1, 1 ] + }, + "0.3333": { + "vector": [ 1.075, 1, 1.075 ], + "easing": "linear" + }, + "0.5417": { + "vector": [ 1, 1, 1 ], + "easing": "linear" + }, + "0.7083": { + "vector": [ 1.075, 1, 1.075 ], + "easing": "linear" + }, + "0.9167": { + "vector": [ 1, 1, 1 ], + "easing": "linear" + }, + "1.125": { + "vector": [ 1.075, 1, 1.075 ], + "easing": "linear" + }, + "1.3333": { + "vector": [ 1, 1, 1 ], + "easing": "linear" + }, + "1.5417": { + "vector": [ 1.075, 1, 1.075 ], + "easing": "linear" + }, + "1.7083": { + "vector": [ 1, 1, 1 ], + "easing": "linear" + }, + "1.9167": { + "vector": [ 1.075, 1, 1.075 ], + "easing": "linear" + }, + "2.125": { + "vector": [ 1, 1, 1 ], + "easing": "linear" + } + } + } + } + } + }, + "geckolib_format_version": 2 +} \ No newline at end of file diff --git a/src/main/resources/assets/biomancy/blockstates/maw_hopper.json b/src/main/resources/assets/biomancy/blockstates/maw_hopper.json new file mode 100644 index 000000000..05b01036e --- /dev/null +++ b/src/main/resources/assets/biomancy/blockstates/maw_hopper.json @@ -0,0 +1,8 @@ +{ + "variants": { + "": { + "model": "biomancy:block/maw_hopper" + } + } +} + diff --git a/src/main/resources/assets/biomancy/geo/block/maw_hopper.geo.json b/src/main/resources/assets/biomancy/geo/block/maw_hopper.geo.json new file mode 100644 index 000000000..d60e96e06 --- /dev/null +++ b/src/main/resources/assets/biomancy/geo/block/maw_hopper.geo.json @@ -0,0 +1,402 @@ +{ + "format_version": "1.12.0", + "minecraft:geometry": [ + { + "description": { + "identifier": "geometry.maw_hopper", + "texture_width": 64, + "texture_height": 64, + "visible_bounds_width": 2, + "visible_bounds_height": 2.5, + "visible_bounds_offset": [ 0, 0.75, 0 ] + }, + "bones": [ + { + "name": "root", + "pivot": [ 0, 0, 0 ], + "cubes": [ + { + "origin": [ -5, 13, -8 ], + "size": [ 10, 3, 3 ], + "uv": { + "north": { + "uv": [ 20, 15 ], + "uv_size": [ 10, 3 ] + }, + "east": { + "uv": [ 17, 32 ], + "uv_size": [ 3, 3 ] + }, + "south": { + "uv": [ 20, 18 ], + "uv_size": [ 10, 3 ] + }, + "west": { + "uv": [ 20, 34 ], + "uv_size": [ 3, 3 ] + }, + "up": { + "uv": [ 20, 21 ], + "uv_size": [ 10, 3 ] + }, + "down": { + "uv": [ 10, 26 ], + "uv_size": [ 10, -3 ] + } + } + }, + { + "origin": [ -5, 13, 5 ], + "size": [ 10, 3, 3 ], + "uv": { + "north": { + "uv": [ 20, 24 ], + "uv_size": [ 10, 3 ] + }, + "east": { + "uv": [ 23, 34 ], + "uv_size": [ 3, 3 ] + }, + "south": { + "uv": [ 26, 0 ], + "uv_size": [ 10, 3 ] + }, + "west": { + "uv": [ 26, 34 ], + "uv_size": [ 3, 3 ] + }, + "up": { + "uv": [ 26, 3 ], + "uv_size": [ 10, 3 ] + }, + "down": { + "uv": [ 10, 29 ], + "uv_size": [ 10, -3 ] + } + } + }, + { + "origin": [ -8, 13, -5 ], + "size": [ 3, 3, 10 ], + "uv": { + "north": { + "uv": [ 29, 34 ], + "uv_size": [ 3, 3 ] + }, + "east": { + "uv": [ 20, 27 ], + "uv_size": [ 10, 3 ] + }, + "south": { + "uv": [ 32, 34 ], + "uv_size": [ 3, 3 ] + }, + "west": { + "uv": [ 10, 29 ], + "uv_size": [ 10, 3 ] + }, + "up": { + "uv": [ 0, 30 ], + "uv_size": [ 3, 10 ] + }, + "down": { + "uv": [ 3, 40 ], + "uv_size": [ 3, -10 ] + } + } + }, + { + "origin": [ 5, 13, -5 ], + "size": [ 3, 3, 10 ], + "uv": { + "north": { + "uv": [ 17, 35 ], + "uv_size": [ 3, 3 ] + }, + "east": { + "uv": [ 30, 6 ], + "uv_size": [ 10, 3 ] + }, + "south": { + "uv": [ 35, 34 ], + "uv_size": [ 3, 3 ] + }, + "west": { + "uv": [ 30, 9 ], + "uv_size": [ 10, 3 ] + }, + "up": { + "uv": [ 6, 30 ], + "uv_size": [ 3, 10 ] + }, + "down": { + "uv": [ 30, 22 ], + "uv_size": [ 3, -10 ] + } + } + }, + { + "origin": [ 3, 13, -5 ], + "size": [ 2, 3, 2 ], + "uv": { + "east": { + "uv": [ 36, 0 ], + "uv_size": [ 2, 3 ] + }, + "south": { + "uv": [ 36, 3 ], + "uv_size": [ 2, 3 ] + }, + "up": { + "uv": [ 37, 12 ], + "uv_size": [ 2, 2 ] + } + } + }, + { + "origin": [ 3, 13, 3 ], + "size": [ 2, 3, 2 ], + "uv": { + "north": { + "uv": [ 9, 36 ], + "uv_size": [ 2, 3 ] + }, + "east": { + "uv": [ 11, 36 ], + "uv_size": [ 2, 3 ] + }, + "up": { + "uv": [ 37, 16 ], + "uv_size": [ 2, 2 ] + } + } + }, + { + "origin": [ -5, 13, 3 ], + "size": [ 2, 3, 2 ], + "uv": { + "north": { + "uv": [ 13, 36 ], + "uv_size": [ 2, 3 ] + }, + "west": { + "uv": [ 15, 36 ], + "uv_size": [ 2, 3 ] + }, + "up": { + "uv": [ 20, 37 ], + "uv_size": [ 2, 2 ] + } + } + }, + { + "origin": [ -5, 13, -5 ], + "size": [ 2, 3, 2 ], + "uv": { + "south": { + "uv": [ 36, 20 ], + "uv_size": [ 2, 3 ] + }, + "west": { + "uv": [ 36, 23 ], + "uv_size": [ 2, 3 ] + }, + "up": { + "uv": [ 24, 37 ], + "uv_size": [ 2, 2 ] + } + } + } + ] + }, + { + "name": "segment_1", + "parent": "root", + "pivot": [ 0, 0, 0 ], + "cubes": [ + { + "origin": [ -5, 10, -5 ], + "size": [ 10, 3, 10 ], + "uv": { + "north": { + "uv": [ 20, 6 ], + "uv_size": [ 10, 3 ] + }, + "east": { + "uv": [ 20, 9 ], + "uv_size": [ 10, 3 ] + }, + "south": { + "uv": [ 10, 20 ], + "uv_size": [ 10, 3 ] + }, + "west": { + "uv": [ 20, 12 ], + "uv_size": [ 10, 3 ] + }, + "up": { + "uv": [ 0, 0 ], + "uv_size": [ 10, 10 ] + }, + "down": { + "uv": [ 0, 20 ], + "uv_size": [ 10, -10 ] + } + } + } + ] + }, + { + "name": "segment_2", + "parent": "root", + "pivot": [ 0, 0, 0 ], + "cubes": [ + { + "origin": [ -3, 6, -3 ], + "size": [ 6, 4, 6 ], + "uv": { + "north": { + "uv": [ 20, 30 ], + "uv_size": [ 6, 4 ] + }, + "east": { + "uv": [ 30, 22 ], + "uv_size": [ 6, 4 ] + }, + "south": { + "uv": [ 26, 30 ], + "uv_size": [ 6, 4 ] + }, + "west": { + "uv": [ 30, 26 ], + "uv_size": [ 6, 4 ] + }, + "down": { + "uv": [ 20, 6 ], + "uv_size": [ 6, -6 ] + } + } + } + ] + }, + { + "name": "segment_3", + "parent": "root", + "pivot": [ 0, 0, 0 ], + "cubes": [ + { + "origin": [ -2, 2, -2 ], + "size": [ 4, 4, 4 ], + "uv": { + "north": { + "uv": [ 9, 32 ], + "uv_size": [ 4, 4 ] + }, + "east": { + "uv": [ 13, 32 ], + "uv_size": [ 4, 4 ] + }, + "south": { + "uv": [ 32, 30 ], + "uv_size": [ 4, 4 ] + }, + "west": { + "uv": [ 33, 12 ], + "uv_size": [ 4, 4 ] + }, + "down": { + "uv": [ 33, 20 ], + "uv_size": [ 4, -4 ] + } + } + } + ] + }, + { + "name": "segment_4", + "parent": "root", + "pivot": [ 0, 0, 0 ], + "cubes": [ + { + "origin": [ -1, 0, -1 ], + "size": [ 2, 2, 2 ], + "uv": { + "north": { + "uv": [ 33, 20 ], + "uv_size": [ 2, 2 ] + }, + "east": { + "uv": [ 36, 26 ], + "uv_size": [ 2, 2 ] + }, + "south": { + "uv": [ 36, 28 ], + "uv_size": [ 2, 2 ] + }, + "west": { + "uv": [ 36, 30 ], + "uv_size": [ 2, 2 ] + }, + "down": { + "uv": [ 36, 34 ], + "uv_size": [ 2, -2 ] + } + } + } + ] + }, + { + "name": "teeth_1", + "parent": "root", + "pivot": [ 0, 2, 0 ], + "cubes": [ + { + "origin": [ -5, 15.75, -5 ], + "size": [ 10, 0, 10 ], + "uv": { + "up": { + "uv": [ 10, 0 ], + "uv_size": [ 10, 10 ] + } + } + } + ] + }, + { + "name": "teeth_2", + "parent": "root", + "pivot": [ 0, 2, 0 ], + "cubes": [ + { + "origin": [ -5, 14.75, -5 ], + "size": [ 10, 0, 10 ], + "uv": { + "up": { + "uv": [ 10, 10 ], + "uv_size": [ 10, 10 ] + } + } + } + ] + }, + { + "name": "teeth_3", + "parent": "root", + "pivot": [ 0, 2, 0 ], + "cubes": [ + { + "origin": [ -5, 13.75, -5 ], + "size": [ 10, 0, 10 ], + "uv": { + "up": { + "uv": [ 0, 20 ], + "uv_size": [ 10, 10 ] + } + } + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/biomancy/models/block/maw_hopper.json b/src/main/resources/assets/biomancy/models/block/maw_hopper.json new file mode 100644 index 000000000..85ef65bea --- /dev/null +++ b/src/main/resources/assets/biomancy/models/block/maw_hopper.json @@ -0,0 +1,5 @@ +{ + "textures": { + "particle": "biomancy:block/packed_flesh" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/biomancy/models/item/maw_hopper.json b/src/main/resources/assets/biomancy/models/item/maw_hopper.json new file mode 100644 index 000000000..db35e3ef4 --- /dev/null +++ b/src/main/resources/assets/biomancy/models/item/maw_hopper.json @@ -0,0 +1,119 @@ +{ + "credit": "Made with Blockbench", + "parent": "builtin/entity", + "texture_size": [ + 64, + 64 + ], + "display": { + "thirdperson_righthand": { + "rotation": [ + 38, + 45, + 0 + ], + "translation": [ + 0, + -0.25, + 0.5 + ], + "scale": [ + 0.375, + 0.375, + 0.375 + ] + }, + "thirdperson_lefthand": { + "rotation": [ + 28, + 45, + 0 + ], + "translation": [ + 0, + -0.25, + 0.5 + ], + "scale": [ + 0.375, + 0.375, + 0.375 + ] + }, + "firstperson_righthand": { + "rotation": [ + 0, + 45, + 0 + ], + "translation": [ + 0, + -3.25, + 0 + ], + "scale": [ + 0.4, + 0.4, + 0.4 + ] + }, + "firstperson_lefthand": { + "rotation": [ + 0, + 225, + 0 + ], + "translation": [ + 0, + -3.25, + 0 + ], + "scale": [ + 0.4, + 0.4, + 0.4 + ] + }, + "ground": { + "translation": [ + 0, + 3, + 0 + ], + "scale": [ + 0.25, + 0.25, + 0.25 + ] + }, + "gui": { + "rotation": [ + 30, + 225, + 0 + ], + "translation": [ + 0, + -6, + 0 + ], + "scale": [ + 0.625, + 0.625, + 0.625 + ] + }, + "fixed": { + "translation": [ + 0, + -4, + 0 + ], + "scale": [ + 0.5, + 0.5, + 0.5 + ] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/biomancy/textures/block/maw_hopper.png b/src/main/resources/assets/biomancy/textures/block/maw_hopper.png new file mode 100644 index 000000000..be9d0341f Binary files /dev/null and b/src/main/resources/assets/biomancy/textures/block/maw_hopper.png differ