diff --git a/build.gradle b/build.gradle index 76a6341..09c486a 100644 --- a/build.gradle +++ b/build.gradle @@ -222,3 +222,7 @@ publishing { tasks.withType(JavaCompile).configureEach { options.encoding = 'UTF-8' // Use the UTF-8 charset for Java compilation } + +task showMeCache doLast() { + configurations.compileClasspath.each { println it } +} diff --git a/src/main/java/com/imbgt/ibg/Config.java b/src/main/java/com/imbgt/ibg/Config.java index 3f82b3b..e9d5992 100644 --- a/src/main/java/com/imbgt/ibg/Config.java +++ b/src/main/java/com/imbgt/ibg/Config.java @@ -8,7 +8,6 @@ import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.event.config.ModConfigEvent; import net.minecraftforge.registries.ForgeRegistries; -import java.util.Collections; import java.util.List; import java.util.Set; import java.util.stream.Collectors; @@ -46,7 +45,7 @@ public class Config private static boolean validateItemName(final Object obj) { - return obj instanceof final String itemName && ForgeRegistries.ITEMS.containsKey(new ResourceLocation(itemName)); + return obj instanceof final String itemName && ForgeRegistries.ITEMS.containsKey(ResourceLocation.parse(itemName)); } @SubscribeEvent @@ -58,7 +57,7 @@ public class Config // convert the list of strings into a set of items items = ITEM_STRINGS.get().stream() - .map(itemName -> ForgeRegistries.ITEMS.getValue(new ResourceLocation(itemName))) + .map(itemName -> ForgeRegistries.ITEMS.getValue(ResourceLocation.parse(itemName))) .collect(Collectors.toSet()); } } diff --git a/src/main/java/com/imbgt/ibg/IBG.java b/src/main/java/com/imbgt/ibg/IBG.java index ea17623..eab2af2 100644 --- a/src/main/java/com/imbgt/ibg/IBG.java +++ b/src/main/java/com/imbgt/ibg/IBG.java @@ -1,10 +1,14 @@ package com.imbgt.ibg; +import com.imbgt.ibg.block.ModBlocks; +import com.imbgt.ibg.block.entity.ModBlockEntities; +import com.imbgt.ibg.block.entity.client.AnimatedBlockRenderer; import com.imbgt.ibg.item.ModItems; import com.mojang.logging.LogUtils; -import net.minecraft.client.Minecraft; + +import net.minecraft.client.renderer.blockentity.BlockEntityRenderers; +import net.minecraft.client.renderer.entity.EntityRenderers; import net.minecraft.world.item.CreativeModeTabs; -import net.minecraft.world.level.block.Blocks; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.BuildCreativeModeTabContentsEvent; @@ -16,33 +20,31 @@ import net.minecraftforge.fml.config.ModConfig; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; -import net.minecraftforge.registries.ForgeRegistries; +import software.bernie.geckolib.GeckoLib; + import org.slf4j.Logger; -// The value here should match an entry in the META-INF/mods.toml file @Mod(IBG.MOD_ID) public class IBG { - // Define mod id in a common place for everything to reference public static final String MOD_ID = "ibg"; - // Directly reference a slf4j logger private static final Logger LOGGER = LogUtils.getLogger(); public IBG(FMLJavaModLoadingContext context) { IEventBus modEventBus = context.getModEventBus(); ModItems.register(modEventBus); + ModBlocks.register(modEventBus); + + ModBlockEntities.register(modEventBus); + + GeckoLib.initialize(); - // Register the commonSetup method for modloading modEventBus.addListener(this::commonSetup); - // Register ourselves for server and other game events we are interested in MinecraftForge.EVENT_BUS.register(this); - // Register the item to a creative tab modEventBus.addListener(this::addCreative); - // Register our mod's ForgeConfigSpec so that Forge can create and load the - // config file for us context.registerConfig(ModConfig.Type.COMMON, Config.SPEC); } @@ -51,7 +53,7 @@ public class IBG { // Add the example block item to the building blocks tab private void addCreative(BuildCreativeModeTabContentsEvent event) { - if(event.getTabKey() == CreativeModeTabs.REDSTONE_BLOCKS) { + if (event.getTabKey() == CreativeModeTabs.REDSTONE_BLOCKS) { event.accept(ModItems.LATHE); } } @@ -67,6 +69,7 @@ public class IBG { public static class ClientModEvents { @SubscribeEvent public static void onClientSetup(FMLClientSetupEvent event) { + BlockEntityRenderers.register(ModBlockEntities.ANIMATED_BLOCK_ENTITY.get(), AnimatedBlockRenderer::new); } } } diff --git a/src/main/java/com/imbgt/ibg/block/ModBlocks.java b/src/main/java/com/imbgt/ibg/block/ModBlocks.java new file mode 100644 index 0000000..3e40a9c --- /dev/null +++ b/src/main/java/com/imbgt/ibg/block/ModBlocks.java @@ -0,0 +1,38 @@ +package com.imbgt.ibg.block; + +import java.util.function.Supplier; + +import com.imbgt.ibg.IBG; +import com.imbgt.ibg.block.custom.AnimatedBlock; +import com.imbgt.ibg.item.ModItems; + +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; +import net.minecraftforge.registries.RegistryObject; + +public class ModBlocks { + public static final DeferredRegister BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, IBG.MOD_ID); + + public static final RegistryObject ANIMATED_BLOCK = BLOCKS.register("animated_block", + () -> new AnimatedBlock(BlockBehaviour.Properties.copy(Blocks.IRON_BLOCK).noOcclusion())); + + private static RegistryObject registerBlock(String name, Supplier block) { + RegistryObject toReturn = BLOCKS.register(name, block); + registerBlockItem(name, toReturn); + return toReturn; + } + + private static RegistryObject registerBlockItem(String name, RegistryObject block) { + return ModItems.ITEMS_REGISTER.register(name, () -> new BlockItem(block.get(), new Item.Properties())); + } + + public static void register(IEventBus eventBus) { + BLOCKS.register(eventBus); + } +} diff --git a/src/main/java/com/imbgt/ibg/block/custom/AnimatedBlock.java b/src/main/java/com/imbgt/ibg/block/custom/AnimatedBlock.java new file mode 100644 index 0000000..b6bfd4d --- /dev/null +++ b/src/main/java/com/imbgt/ibg/block/custom/AnimatedBlock.java @@ -0,0 +1,29 @@ +package com.imbgt.ibg.block.custom; + +import net.minecraft.world.level.block.BaseEntityBlock; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.block.RenderShape; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import org.jetbrains.annotations.Nullable; + +import com.imbgt.ibg.block.entity.AnimatedBlockEntity; + + +public class AnimatedBlock extends BaseEntityBlock { + + public AnimatedBlock(Properties properties) { + super(properties); + } + + @Nullable + @Override + public BlockEntity newBlockEntity(BlockPos blockPos, BlockState state) { + return new AnimatedBlockEntity(blockPos, state); + } + + @Override + public RenderShape getRenderShape(BlockState state) { + return RenderShape.ENTITYBLOCK_ANIMATED; + } +} diff --git a/src/main/java/com/imbgt/ibg/block/entity/AnimatedBlockEntity.java b/src/main/java/com/imbgt/ibg/block/entity/AnimatedBlockEntity.java new file mode 100644 index 0000000..3328810 --- /dev/null +++ b/src/main/java/com/imbgt/ibg/block/entity/AnimatedBlockEntity.java @@ -0,0 +1,41 @@ +package com.imbgt.ibg.block.entity; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import software.bernie.geckolib.animatable.GeoBlockEntity; +import software.bernie.geckolib.core.animatable.GeoAnimatable; +import software.bernie.geckolib.core.animatable.instance.AnimatableInstanceCache; +import software.bernie.geckolib.core.animatable.instance.SingletonAnimatableInstanceCache; +import software.bernie.geckolib.core.animation.*; +import software.bernie.geckolib.core.object.PlayState; +import software.bernie.geckolib.util.RenderUtils; + +public class AnimatedBlockEntity extends BlockEntity implements GeoBlockEntity { + + private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); + + public AnimatedBlockEntity(BlockPos pos, BlockState state) { + super(ModBlockEntities.ANIMATED_BLOCK_ENTITY.get(), pos, state); + } + + @Override + public void registerControllers(AnimatableManager.ControllerRegistrar controllerRegistrar) { + controllerRegistrar.add(new AnimationController<>(this, "controller", 0, this::predicate)); + } + + private PlayState predicate(AnimationState tAnimationState) { + tAnimationState.getController().setAnimation(RawAnimation.begin().then("idle", Animation.LoopType.LOOP)); + return PlayState.CONTINUE; + } + + @Override + public AnimatableInstanceCache getAnimatableInstanceCache() { + return cache; + } + + @Override + public double getTick(Object blockEntity) { + return RenderUtils.getCurrentTick(); + } +} diff --git a/src/main/java/com/imbgt/ibg/block/entity/ModBlockEntities.java b/src/main/java/com/imbgt/ibg/block/entity/ModBlockEntities.java new file mode 100644 index 0000000..168dbd3 --- /dev/null +++ b/src/main/java/com/imbgt/ibg/block/entity/ModBlockEntities.java @@ -0,0 +1,24 @@ +package com.imbgt.ibg.block.entity; + +import com.imbgt.ibg.IBG; +import com.imbgt.ibg.block.ModBlocks; + +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; +import net.minecraftforge.registries.RegistryObject; + +public class ModBlockEntities { + + public static final DeferredRegister> BLOCK_ENTITIES = DeferredRegister + .create(ForgeRegistries.BLOCK_ENTITY_TYPES, IBG.MOD_ID); + + public static final RegistryObject> ANIMATED_BLOCK_ENTITY = BLOCK_ENTITIES + .register("animated_block_entity", () -> BlockEntityType.Builder.of(AnimatedBlockEntity::new, + ModBlocks.ANIMATED_BLOCK.get()).build(null)); + + public static void register(IEventBus eventBus) { + BLOCK_ENTITIES.register(eventBus); + } +} diff --git a/src/main/java/com/imbgt/ibg/block/entity/client/AnimatedBlockModel.java b/src/main/java/com/imbgt/ibg/block/entity/client/AnimatedBlockModel.java new file mode 100644 index 0000000..077fdca --- /dev/null +++ b/src/main/java/com/imbgt/ibg/block/entity/client/AnimatedBlockModel.java @@ -0,0 +1,25 @@ +package com.imbgt.ibg.block.entity.client; + +import com.imbgt.ibg.IBG; +import com.imbgt.ibg.block.entity.AnimatedBlockEntity; + +import net.minecraft.resources.ResourceLocation; +import software.bernie.geckolib.model.GeoModel; + +public class AnimatedBlockModel extends GeoModel { + @Override + public ResourceLocation getModelResource(AnimatedBlockEntity animatable) { + return ResourceLocation.fromNamespaceAndPath(IBG.MOD_ID, "geo/animated_block.geo.json"); + } + + @Override + public ResourceLocation getTextureResource(AnimatedBlockEntity animatable) { + return ResourceLocation.fromNamespaceAndPath(IBG.MOD_ID, "textures/block/animated_block.png"); + } + + @Override + public ResourceLocation getAnimationResource(AnimatedBlockEntity animatable) { + return ResourceLocation.fromNamespaceAndPath(IBG.MOD_ID, "animations/animated_block.animation.json"); + } + +} diff --git a/src/main/java/com/imbgt/ibg/block/entity/client/AnimatedBlockRenderer.java b/src/main/java/com/imbgt/ibg/block/entity/client/AnimatedBlockRenderer.java new file mode 100644 index 0000000..2cd9bdb --- /dev/null +++ b/src/main/java/com/imbgt/ibg/block/entity/client/AnimatedBlockRenderer.java @@ -0,0 +1,12 @@ +package com.imbgt.ibg.block.entity.client; + +import com.imbgt.ibg.block.entity.AnimatedBlockEntity; + +import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; +import software.bernie.geckolib.renderer.GeoBlockRenderer; + +public class AnimatedBlockRenderer extends GeoBlockRenderer { + public AnimatedBlockRenderer(BlockEntityRendererProvider.Context context) { + super(new AnimatedBlockModel()); + } +} diff --git a/src/main/java/com/imbgt/ibg/item/ModItems.java b/src/main/java/com/imbgt/ibg/item/ModItems.java index 87f13e8..66bafd9 100644 --- a/src/main/java/com/imbgt/ibg/item/ModItems.java +++ b/src/main/java/com/imbgt/ibg/item/ModItems.java @@ -1,6 +1,8 @@ package com.imbgt.ibg.item; import com.imbgt.ibg.IBG; +import com.imbgt.ibg.block.ModBlocks; +import com.imbgt.ibg.item.custom.AnimatedBlockItem; import net.minecraft.world.item.Item; import net.minecraftforge.eventbus.api.IEventBus; @@ -15,6 +17,9 @@ public class ModItems { public static final RegistryObject LATHE = ITEMS_REGISTER.register("lathe",() -> new Item(new Item.Properties())); + public static final RegistryObject ANIMATED_BLOCK_ITEM = ITEMS_REGISTER.register("animated_block", + () -> new AnimatedBlockItem(ModBlocks.ANIMATED_BLOCK.get(), new Item.Properties())); + public static void register(IEventBus eventBus) { ITEMS_REGISTER.register(eventBus); } diff --git a/src/main/java/com/imbgt/ibg/item/client/AnimatedBlockItemModel.java b/src/main/java/com/imbgt/ibg/item/client/AnimatedBlockItemModel.java new file mode 100644 index 0000000..047c5f2 --- /dev/null +++ b/src/main/java/com/imbgt/ibg/item/client/AnimatedBlockItemModel.java @@ -0,0 +1,22 @@ +package com.imbgt.ibg.item.client; +import net.minecraft.resources.ResourceLocation; +import software.bernie.geckolib.model.GeoModel; + +import com.imbgt.ibg.IBG; +import com.imbgt.ibg.item.custom.AnimatedBlockItem; + +public class AnimatedBlockItemModel extends GeoModel { + @Override + public ResourceLocation getModelResource(AnimatedBlockItem animatable) { + return new ResourceLocation(IBG.MOD_ID, "geo/animated_block.geo.json"); } + + @Override + public ResourceLocation getTextureResource(AnimatedBlockItem animatable) { + return new ResourceLocation(IBG.MOD_ID, "textures/block/animated_block.png"); + } + + @Override + public ResourceLocation getAnimationResource(AnimatedBlockItem animatable) { + return new ResourceLocation(IBG.MOD_ID, "animations/animated_block.animation.json"); + } +} diff --git a/src/main/java/com/imbgt/ibg/item/client/AnimatedBlockItemRenderer.java b/src/main/java/com/imbgt/ibg/item/client/AnimatedBlockItemRenderer.java new file mode 100644 index 0000000..46349d4 --- /dev/null +++ b/src/main/java/com/imbgt/ibg/item/client/AnimatedBlockItemRenderer.java @@ -0,0 +1,11 @@ +package com.imbgt.ibg.item.client; + +import com.imbgt.ibg.item.custom.AnimatedBlockItem; + +import software.bernie.geckolib.renderer.GeoItemRenderer; + +public class AnimatedBlockItemRenderer extends GeoItemRenderer { + public AnimatedBlockItemRenderer() { + super(new AnimatedBlockItemModel()); + } +} diff --git a/src/main/java/com/imbgt/ibg/item/custom/AnimatedBlockItem.java b/src/main/java/com/imbgt/ibg/item/custom/AnimatedBlockItem.java new file mode 100644 index 0000000..b0f53fd --- /dev/null +++ b/src/main/java/com/imbgt/ibg/item/custom/AnimatedBlockItem.java @@ -0,0 +1,62 @@ +package com.imbgt.ibg.item.custom; + +import java.util.function.Consumer; + +import com.imbgt.ibg.item.client.AnimatedBlockItemRenderer; + +import net.minecraft.client.renderer.BlockEntityWithoutLevelRenderer; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.level.block.Block; +import net.minecraftforge.client.extensions.common.IClientItemExtensions; +import software.bernie.geckolib.animatable.GeoItem; +import software.bernie.geckolib.animatable.SingletonGeoAnimatable; +import software.bernie.geckolib.core.animatable.GeoAnimatable; +import software.bernie.geckolib.core.animatable.instance.AnimatableInstanceCache; +import software.bernie.geckolib.core.animatable.instance.SingletonAnimatableInstanceCache; +import software.bernie.geckolib.core.animation.*; +import software.bernie.geckolib.core.object.PlayState; +import software.bernie.geckolib.util.RenderUtils; + +public class AnimatedBlockItem extends BlockItem implements GeoItem { + private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); + + public AnimatedBlockItem(Block block, Properties properties) { + super(block, properties); + SingletonGeoAnimatable.registerSyncedAnimatable(this); + } + + @Override + public void initializeClient(Consumer consumer) { + consumer.accept(new IClientItemExtensions() { + private AnimatedBlockItemRenderer renderer; + + @Override + public BlockEntityWithoutLevelRenderer getCustomRenderer() { + if (this.renderer == null) + this.renderer = new AnimatedBlockItemRenderer(); + + return this.renderer; + } + }); + } + + @Override + public void registerControllers(AnimatableManager.ControllerRegistrar controllerRegistrar) { + controllerRegistrar.add(new AnimationController<>(this, "controller", 0, this::predicate)); + } + + private PlayState predicate(AnimationState tAnimationState) { + tAnimationState.getController().setAnimation(RawAnimation.begin().then("idle", Animation.LoopType.LOOP)); + return PlayState.CONTINUE; + } + + @Override + public AnimatableInstanceCache getAnimatableInstanceCache() { + return cache; + } + + @Override + public double getTick(Object itemStack) { + return RenderUtils.getCurrentTick(); + } +} diff --git a/src/main/resources/assets/ibg/animations/animated_block.animation.json b/src/main/resources/assets/ibg/animations/animated_block.animation.json new file mode 100644 index 0000000..7e177eb --- /dev/null +++ b/src/main/resources/assets/ibg/animations/animated_block.animation.json @@ -0,0 +1,17 @@ +{ + "format_version": "1.8.0", + "animations": { + "idle": { + "loop": true, + "animation_length": 2.96, + "bones": { + "bone2": { + "position": { + "vector": [0, "math.sin(query.anim_time*120)", 0] + } + } + } + } + }, + "geckolib_format_version": 2 +} diff --git a/src/main/resources/assets/ibg/blockstates/animated_block.json b/src/main/resources/assets/ibg/blockstates/animated_block.json new file mode 100644 index 0000000..097eecf --- /dev/null +++ b/src/main/resources/assets/ibg/blockstates/animated_block.json @@ -0,0 +1,5 @@ +{ + "variants": { + "": { "model": "ibg:block/animated_block" } + } +} diff --git a/src/main/resources/assets/ibg/geo/animated_block.geo.json b/src/main/resources/assets/ibg/geo/animated_block.geo.json new file mode 100644 index 0000000..9cea90f --- /dev/null +++ b/src/main/resources/assets/ibg/geo/animated_block.geo.json @@ -0,0 +1,34 @@ +{ + "format_version": "1.12.0", + "minecraft:geometry": [ + { + "description": { + "identifier": "geometry.unknown", + "texture_width": 64, + "texture_height": 64, + "visible_bounds_width": 2, + "visible_bounds_height": 2.5, + "visible_bounds_offset": [0, 0.75, 0] + }, + "bones": [ + { + "name": "bone", + "pivot": [0, 0, 0], + "cubes": [ + {"origin": [-3, 4, -3], "size": [6, 2, 6], "uv": [0, 32]}, + {"origin": [-1, 6, -1], "size": [2, 4.5, 2], "uv": [0, 8]}, + {"origin": [-6, 2, -6], "size": [12, 2, 12], "uv": [0, 18]}, + {"origin": [-8, 0, -8], "size": [16, 2, 16], "uv": [0, 0]} + ] + }, + { + "name": "bone2", + "pivot": [0, 0, 0], + "cubes": [ + {"origin": [-2, 12, -2], "size": [4, 4, 4], "uv": [0, 0]} + ] + } + ] + } + ] +} diff --git a/src/main/resources/assets/ibg/lang/en_us.json b/src/main/resources/assets/ibg/lang/en_us.json index ea9e045..6e6b6c7 100644 --- a/src/main/resources/assets/ibg/lang/en_us.json +++ b/src/main/resources/assets/ibg/lang/en_us.json @@ -1,3 +1,4 @@ { - "item.ibg.lathe": "Lathe" + "item.ibg.lathe": "Lathe", + "block.ibg.animated_block": "Animated Block" } diff --git a/src/main/resources/assets/ibg/models/block/animated_block.json b/src/main/resources/assets/ibg/models/block/animated_block.json new file mode 100644 index 0000000..8cc1e85 --- /dev/null +++ b/src/main/resources/assets/ibg/models/block/animated_block.json @@ -0,0 +1,99 @@ +{ + "credit": "Made with Blockbench", + "parent": "builtin/entity", + "texture_size": [ + 64, + 64 + ], + "display": { + "thirdperson_righthand": { + "rotation": [ + 22, + 0, + 0 + ], + "translation": [ + 0, + -2, + 0 + ], + "scale": [ + 0.4, + 0.4, + 0.4 + ] + }, + "thirdperson_lefthand": { + "rotation": [ + 22, + 0, + 0 + ], + "translation": [ + 0, + -2, + 0 + ], + "scale": [ + 0.4, + 0.4, + 0.4 + ] + }, + "firstperson_righthand": { + "scale": [ + 0.6, + 0.6, + 0.6 + ] + }, + "firstperson_lefthand": { + "scale": [ + 0.6, + 0.6, + 0.6 + ] + }, + "ground": { + "translation": [ + 0, + -3.25, + 0 + ], + "scale": [ + 0.75, + 0.75, + 0.75 + ] + }, + "gui": { + "rotation": [ + 26.31, + 40.81, + -8.27 + ], + "translation": [ + 0, + -5.25, + 0 + ], + "scale": [ + 0.65, + 0.65, + 0.65 + ] + }, + "fixed": { + "rotation": [ + -18.75, + 54.5, + 0 + ], + "translation": [ + 0, + -7, + 2 + ] + } + } +} diff --git a/src/main/resources/assets/ibg/models/item/animated_block.json b/src/main/resources/assets/ibg/models/item/animated_block.json new file mode 100644 index 0000000..d9b2eb2 --- /dev/null +++ b/src/main/resources/assets/ibg/models/item/animated_block.json @@ -0,0 +1,3 @@ +{ + "parent": "ibg:block/animated_block" +} diff --git a/src/main/resources/assets/ibg/textures/block/animated_block.png b/src/main/resources/assets/ibg/textures/block/animated_block.png new file mode 100644 index 0000000..65e5722 Binary files /dev/null and b/src/main/resources/assets/ibg/textures/block/animated_block.png differ