diff --git a/.gitignore b/.gitignore index 31d2550..15e241e 100644 --- a/.gitignore +++ b/.gitignore @@ -23,4 +23,5 @@ run runs run-data -repo \ No newline at end of file +repo +src/generated diff --git a/src/main/java/fr/sushi/charmsnfabrics/CharmsAndFabrics.java b/src/main/java/fr/sushi/charmsnfabrics/CharmsAndFabrics.java index 85081a2..03c9d77 100644 --- a/src/main/java/fr/sushi/charmsnfabrics/CharmsAndFabrics.java +++ b/src/main/java/fr/sushi/charmsnfabrics/CharmsAndFabrics.java @@ -1,38 +1,19 @@ package fr.sushi.charmsnfabrics; -import fr.sushi.charmsnfabrics.common.CharmsAndFabricRegistries; -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.core.registries.Registries; -import net.minecraft.network.chat.Component; -import net.minecraft.world.food.FoodProperties; -import net.minecraft.world.item.BlockItem; -import net.minecraft.world.item.CreativeModeTab; -import net.minecraft.world.item.CreativeModeTabs; -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.minecraft.world.level.material.MapColor; +import fr.sushi.charmsnfabrics.common.CnFRegistries; +import net.neoforged.api.distmarker.Dist; import net.neoforged.bus.api.IEventBus; -import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.fml.common.Mod; import net.neoforged.fml.config.ModConfig; import net.neoforged.fml.ModContainer; -import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent; -import net.neoforged.neoforge.common.NeoForge; -import net.neoforged.neoforge.event.BuildCreativeModeTabContentsEvent; -import net.neoforged.neoforge.event.server.ServerStartingEvent; -import net.neoforged.neoforge.registries.DeferredBlock; -import net.neoforged.neoforge.registries.DeferredHolder; -import net.neoforged.neoforge.registries.DeferredItem; -import net.neoforged.neoforge.registries.DeferredRegister; @Mod(CharmsAndFabrics.MODID) public class CharmsAndFabrics { public static final String MODID = "charmsnfabrics"; public CharmsAndFabrics(IEventBus modEventBus, ModContainer modContainer) { - CharmsAndFabricRegistries.register(modEventBus); + CnFRegistries.register(modEventBus); modContainer.registerConfig(ModConfig.Type.COMMON, Config.SPEC); } diff --git a/src/main/java/fr/sushi/charmsnfabrics/client/CharmsFabricsClient.java b/src/main/java/fr/sushi/charmsnfabrics/client/CharmsFabricsClient.java deleted file mode 100644 index 355f328..0000000 --- a/src/main/java/fr/sushi/charmsnfabrics/client/CharmsFabricsClient.java +++ /dev/null @@ -1,43 +0,0 @@ -package fr.sushi.charmsnfabrics.client; - -import fr.sushi.charmsnfabrics.CharmsAndFabrics; -import fr.sushi.charmsnfabrics.client.model.FlowerCrownModel; -import fr.sushi.charmsnfabrics.client.renderer.FlowerCrownRenderer; -import fr.sushi.charmsnfabrics.common.CharmsAndFabricRegistries; -import net.neoforged.api.distmarker.Dist; -import net.neoforged.bus.api.SubscribeEvent; -import net.neoforged.fml.ModContainer; -import net.neoforged.fml.common.EventBusSubscriber; -import net.neoforged.fml.common.Mod; -import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent; -import net.neoforged.neoforge.client.event.EntityRenderersEvent; -import net.neoforged.neoforge.client.gui.ConfigurationScreen; -import net.neoforged.neoforge.client.gui.IConfigScreenFactory; -import top.theillusivec4.curios.api.client.ICurioRenderer; - -@Mod(value = CharmsAndFabrics.MODID, dist = Dist.CLIENT) -@EventBusSubscriber(modid = CharmsAndFabrics.MODID, value = Dist.CLIENT) -public class CharmsFabricsClient -{ - public CharmsFabricsClient(ModContainer container) - { - container.registerExtensionPoint(IConfigScreenFactory.class, - ConfigurationScreen::new); - } - - @SubscribeEvent - private static void onClientSetup(final FMLClientSetupEvent event) - { - ICurioRenderer.register( - CharmsAndFabricRegistries.Items.FLOWER_CROWN.get(), - FlowerCrownRenderer::new); - } - - @SubscribeEvent - private static void onRegisterLayerDefinitions( - final EntityRenderersEvent.RegisterLayerDefinitions event) - { - event.registerLayerDefinition(CharmsAndFabricsLayers.CROWN_LAYER, - FlowerCrownModel::createLayer); - } -} diff --git a/src/main/java/fr/sushi/charmsnfabrics/client/CnFClient.java b/src/main/java/fr/sushi/charmsnfabrics/client/CnFClient.java new file mode 100644 index 0000000..1792c08 --- /dev/null +++ b/src/main/java/fr/sushi/charmsnfabrics/client/CnFClient.java @@ -0,0 +1,73 @@ +package fr.sushi.charmsnfabrics.client; + +import fr.sushi.charmsnfabrics.CharmsAndFabrics; +import fr.sushi.charmsnfabrics.client.datagen.CnFBlockLootProvider; +import fr.sushi.charmsnfabrics.client.datagen.CnFBlockTagsProvider; +import fr.sushi.charmsnfabrics.client.datagen.CnFModelProvider; +import fr.sushi.charmsnfabrics.client.model.FlowerCrownModel; +import fr.sushi.charmsnfabrics.client.renderer.FloralWorkbenchRenderer; +import fr.sushi.charmsnfabrics.client.renderer.FlowerCrownRenderer; +import fr.sushi.charmsnfabrics.common.CnFRegistries; +import net.minecraft.data.loot.LootTableProvider; +import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.ModContainer; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.fml.common.Mod; +import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent; +import net.neoforged.neoforge.client.event.EntityRenderersEvent; +import net.neoforged.neoforge.client.gui.ConfigurationScreen; +import net.neoforged.neoforge.client.gui.IConfigScreenFactory; +import net.neoforged.neoforge.data.event.GatherDataEvent; +import top.theillusivec4.curios.api.client.ICurioRenderer; + +import java.util.List; +import java.util.Set; + +@Mod(value = CharmsAndFabrics.MODID, dist = Dist.CLIENT) +@EventBusSubscriber(modid = CharmsAndFabrics.MODID, value = Dist.CLIENT) +public class CnFClient +{ + public CnFClient(ModContainer container) + { + container.registerExtensionPoint(IConfigScreenFactory.class, + ConfigurationScreen::new); + } + + @SubscribeEvent + private static void onClientSetup(final FMLClientSetupEvent event) + { + ICurioRenderer.register(CnFRegistries.Items.FLOWER_CROWN.get(), + FlowerCrownRenderer::new); + } + + @SubscribeEvent + private static void onRegisterLayerDefinitions( + final EntityRenderersEvent.RegisterLayerDefinitions event) + { + event.registerLayerDefinition(CnFLayers.CROWN_LAYER, + FlowerCrownModel::createLayer); + } + + @SubscribeEvent + private static void onRegisterRenderers( + final EntityRenderersEvent.RegisterRenderers event) + { + event.registerBlockEntityRenderer( + CnFRegistries.Entities.FLORAL_WORKBENCH_BLOCKENTITY.get(), + FloralWorkbenchRenderer::new); + } + + @SubscribeEvent + private static void onGatherClientData(final GatherDataEvent.Client event) + { + event.createProvider(CnFModelProvider::new); + event.createProvider( + (output, lookup) -> new LootTableProvider(output, Set.of(), + List.of(new LootTableProvider.SubProviderEntry( + CnFBlockLootProvider::new, + LootContextParamSets.BLOCK)), lookup)); + event.createProvider(CnFBlockTagsProvider::new); + } +} diff --git a/src/main/java/fr/sushi/charmsnfabrics/client/CharmsAndFabricsLayers.java b/src/main/java/fr/sushi/charmsnfabrics/client/CnFLayers.java similarity index 91% rename from src/main/java/fr/sushi/charmsnfabrics/client/CharmsAndFabricsLayers.java rename to src/main/java/fr/sushi/charmsnfabrics/client/CnFLayers.java index 429f56c..56e1f36 100644 --- a/src/main/java/fr/sushi/charmsnfabrics/client/CharmsAndFabricsLayers.java +++ b/src/main/java/fr/sushi/charmsnfabrics/client/CnFLayers.java @@ -4,7 +4,7 @@ import fr.sushi.charmsnfabrics.CharmsAndFabrics; import net.minecraft.client.model.geom.ModelLayerLocation; import net.minecraft.resources.ResourceLocation; -public class CharmsAndFabricsLayers +public class CnFLayers { public static final ModelLayerLocation CROWN_LAYER = new ModelLayerLocation( ResourceLocation.fromNamespaceAndPath(CharmsAndFabrics.MODID, diff --git a/src/main/java/fr/sushi/charmsnfabrics/client/datagen/CnFBlockLootProvider.java b/src/main/java/fr/sushi/charmsnfabrics/client/datagen/CnFBlockLootProvider.java new file mode 100644 index 0000000..84061ca --- /dev/null +++ b/src/main/java/fr/sushi/charmsnfabrics/client/datagen/CnFBlockLootProvider.java @@ -0,0 +1,31 @@ +package fr.sushi.charmsnfabrics.client.datagen; + +import fr.sushi.charmsnfabrics.common.CnFRegistries; +import net.minecraft.core.HolderLookup; +import net.minecraft.data.loot.BlockLootSubProvider; +import net.minecraft.world.flag.FeatureFlags; +import net.minecraft.world.level.block.Block; + +import java.util.Set; + +public class CnFBlockLootProvider extends BlockLootSubProvider +{ + public CnFBlockLootProvider(HolderLookup.Provider registries) + { + super(Set.of(), FeatureFlags.DEFAULT_FLAGS, registries); + } + + @Override + protected Iterable getKnownBlocks() + { + return CnFRegistries.Blocks.BLOCKS.getEntries().stream() + .map(block -> (Block) block.get()) + .toList(); + } + + @Override + protected void generate() + { + this.dropSelf(CnFRegistries.Blocks.FLORAL_WORKBENCH.get()); + } +} diff --git a/src/main/java/fr/sushi/charmsnfabrics/client/datagen/CnFBlockTagsProvider.java b/src/main/java/fr/sushi/charmsnfabrics/client/datagen/CnFBlockTagsProvider.java new file mode 100644 index 0000000..79cb54b --- /dev/null +++ b/src/main/java/fr/sushi/charmsnfabrics/client/datagen/CnFBlockTagsProvider.java @@ -0,0 +1,25 @@ +package fr.sushi.charmsnfabrics.client.datagen; + +import fr.sushi.charmsnfabrics.CharmsAndFabrics; +import fr.sushi.charmsnfabrics.common.CnFRegistries; +import net.minecraft.core.HolderLookup; +import net.minecraft.data.PackOutput; +import net.minecraft.tags.BlockTags; +import net.neoforged.neoforge.common.data.BlockTagsProvider; + +import java.util.concurrent.CompletableFuture; + +public class CnFBlockTagsProvider extends BlockTagsProvider +{ + public CnFBlockTagsProvider(PackOutput output, + CompletableFuture lookupProvider) + { + super(output, lookupProvider, CharmsAndFabrics.MODID); + } + + @Override + protected void addTags(HolderLookup.Provider provider) + { + this.tag(BlockTags.MINEABLE_WITH_AXE).add(CnFRegistries.Blocks.FLORAL_WORKBENCH.get()); + } +} diff --git a/src/main/java/fr/sushi/charmsnfabrics/client/datagen/CnFModelProvider.java b/src/main/java/fr/sushi/charmsnfabrics/client/datagen/CnFModelProvider.java new file mode 100644 index 0000000..2f72c5f --- /dev/null +++ b/src/main/java/fr/sushi/charmsnfabrics/client/datagen/CnFModelProvider.java @@ -0,0 +1,49 @@ +package fr.sushi.charmsnfabrics.client.datagen; + +import fr.sushi.charmsnfabrics.CharmsAndFabrics; +import fr.sushi.charmsnfabrics.common.CnFRegistries; +import net.minecraft.client.data.models.BlockModelGenerators; +import net.minecraft.client.data.models.ItemModelGenerators; +import net.minecraft.client.data.models.ModelProvider; +import net.minecraft.client.data.models.MultiVariant; +import net.minecraft.client.data.models.model.ModelLocationUtils; +import net.minecraft.client.data.models.model.ModelTemplates; +import net.minecraft.data.PackOutput; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.block.Block; + +public class CnFModelProvider extends ModelProvider +{ + public CnFModelProvider(PackOutput output) + { + super(output, CharmsAndFabrics.MODID); + } + + private void registerFloralWorkbench(BlockModelGenerators blockModels) + { + Block block = CnFRegistries.Blocks.FLORAL_WORKBENCH.get(); + ResourceLocation model = ModelLocationUtils.getModelLocation(block); + + MultiVariant variants = BlockModelGenerators.plainVariant(model); + blockModels.blockStateOutput.accept( + BlockModelGenerators.createSimpleBlock(block, variants) + .with(BlockModelGenerators.ROTATION_HORIZONTAL_FACING_ALT)); + // blockModels.modelOutput.accept(ModelLocationUtils.getModelLocation(block)); + } + + private void registerFlowerCrown(ItemModelGenerators itemModels) + { + Item item = CnFRegistries.Items.FLOWER_CROWN.get(); + + itemModels.generateFlatItem(item, ModelTemplates.FLAT_ITEM); + } + + @Override + protected void registerModels(BlockModelGenerators blockModels, + ItemModelGenerators itemModels) + { + this.registerFlowerCrown(itemModels); + this.registerFloralWorkbench(blockModels); + } +} diff --git a/src/main/java/fr/sushi/charmsnfabrics/client/renderer/FloralWorkbenchRenderer.java b/src/main/java/fr/sushi/charmsnfabrics/client/renderer/FloralWorkbenchRenderer.java new file mode 100644 index 0000000..6e2c83f --- /dev/null +++ b/src/main/java/fr/sushi/charmsnfabrics/client/renderer/FloralWorkbenchRenderer.java @@ -0,0 +1,49 @@ +package fr.sushi.charmsnfabrics.client.renderer; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import com.mojang.math.Axis; +import fr.sushi.charmsnfabrics.CharmsAndFabrics; +import fr.sushi.charmsnfabrics.client.CnFLayers; +import fr.sushi.charmsnfabrics.client.model.FlowerCrownModel; +import fr.sushi.charmsnfabrics.common.entities.block.FloralWorkbenchBlockEntity; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; +import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.phys.Vec3; + +public class FloralWorkbenchRenderer implements BlockEntityRenderer +{ + private final FlowerCrownModel model; + + public FloralWorkbenchRenderer(BlockEntityRendererProvider.Context ctx) + { + this.model = new FlowerCrownModel(ctx.bakeLayer(CnFLayers.CROWN_LAYER)); + } + + @Override + public void render(FloralWorkbenchBlockEntity blockEntity, + float partialTick, PoseStack poseStack, + MultiBufferSource bufferSource, int packedLight, int packedOverlay, + Vec3 cameraPos) + { + if (!blockEntity.hasCrown()) { + return; + } + poseStack.pushPose(); + float yRot = + blockEntity.getRandomSource().nextFloat() * (float) Math.PI * partialTick; + poseStack.translate(0.5f, 1.625f, 0.5f); +// poseStack.rotateAround(Axis.YP.rotationDegrees(yRot), 0.0f, 0.0f, 0.0f); + ResourceLocation texture = + ResourceLocation.fromNamespaceAndPath(CharmsAndFabrics.MODID, + "textures/models/accessory/flower_crown.png"); + VertexConsumer consumer = + bufferSource.getBuffer(RenderType.entityCutout(texture)); + this.model.renderToBuffer(poseStack, consumer, packedLight, packedOverlay); + poseStack.popPose(); + } +} diff --git a/src/main/java/fr/sushi/charmsnfabrics/client/renderer/FlowerCrownRenderer.java b/src/main/java/fr/sushi/charmsnfabrics/client/renderer/FlowerCrownRenderer.java index 735a45b..8afa348 100644 --- a/src/main/java/fr/sushi/charmsnfabrics/client/renderer/FlowerCrownRenderer.java +++ b/src/main/java/fr/sushi/charmsnfabrics/client/renderer/FlowerCrownRenderer.java @@ -2,7 +2,7 @@ package fr.sushi.charmsnfabrics.client.renderer; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; -import fr.sushi.charmsnfabrics.client.CharmsAndFabricsLayers; +import fr.sushi.charmsnfabrics.client.CnFLayers; import fr.sushi.charmsnfabrics.client.model.FlowerCrownModel; import fr.sushi.charmsnfabrics.common.item.FlowerCrown; import net.minecraft.client.Minecraft; @@ -28,7 +28,7 @@ public class FlowerCrownRenderer implements ICurioRenderer { this.model = new FlowerCrownModel( Minecraft.getInstance().getEntityModels() - .bakeLayer(CharmsAndFabricsLayers.CROWN_LAYER)); + .bakeLayer(CnFLayers.CROWN_LAYER)); } @Override @@ -43,11 +43,9 @@ public class FlowerCrownRenderer implements ICurioRenderer ResourceLocation texture = item.getModelTexture(); VertexConsumer vertexconsumer = ItemRenderer.getArmorFoilBuffer(renderTypeBuffer, - RenderType.entityCutout( - texture), - stack.hasFoil()); + RenderType.entityCutout(texture), stack.hasFoil()); ICurioRenderer.setupHumanoidAnimations(this.model, renderState); this.model.renderToBuffer(poseStack, vertexconsumer, packedLight, - OverlayTexture.NO_OVERLAY); + OverlayTexture.NO_OVERLAY); } } diff --git a/src/main/java/fr/sushi/charmsnfabrics/common/CharmsAndFabricRegistries.java b/src/main/java/fr/sushi/charmsnfabrics/common/CharmsAndFabricRegistries.java deleted file mode 100644 index b48376c..0000000 --- a/src/main/java/fr/sushi/charmsnfabrics/common/CharmsAndFabricRegistries.java +++ /dev/null @@ -1,56 +0,0 @@ -package fr.sushi.charmsnfabrics.common; - -import fr.sushi.charmsnfabrics.CharmsAndFabrics; -import fr.sushi.charmsnfabrics.common.item.FlowerCrown; -import net.minecraft.core.registries.Registries; -import net.minecraft.network.chat.Component; -import net.minecraft.world.item.CreativeModeTab; -import net.minecraft.world.item.CreativeModeTabs; -import net.minecraft.world.item.Item; -import net.neoforged.bus.api.IEventBus; -import net.neoforged.neoforge.registries.DeferredHolder; -import net.neoforged.neoforge.registries.DeferredItem; -import net.neoforged.neoforge.registries.DeferredRegister; - -public class CharmsAndFabricRegistries -{ - public static class Items - { - public static final DeferredRegister.Items ITEMS = - DeferredRegister.createItems(CharmsAndFabrics.MODID); - public static final DeferredItem FLOWER_CROWN = - ITEMS.registerItem("flower_crown", - (properties) -> new FlowerCrown( - properties.stacksTo(1))); - } - - public static class Tabs - { - public static final DeferredRegister - CREATIVE_MODE_TABS = - DeferredRegister.create(Registries.CREATIVE_MODE_TAB, - CharmsAndFabrics.MODID); - public static final DeferredHolder - EXAMPLE_TAB = CREATIVE_MODE_TABS.register("charmsnfabrics_tab", - () -> CreativeModeTab - .builder() - .title(Component.translatable( - "itemGroup.charmsnfabrics")) - .withTabsBefore( - CreativeModeTabs.COMBAT) - .icon(Items.FLOWER_CROWN.get()::getDefaultInstance) - .displayItems( - (parameters, output) -> - { - output.accept( - Items.FLOWER_CROWN.get()); - }) - .build()); - } - - public static void register(IEventBus bus) - { - Items.ITEMS.register(bus); - Tabs.CREATIVE_MODE_TABS.register(bus); - } -} diff --git a/src/main/java/fr/sushi/charmsnfabrics/common/CnFRegistries.java b/src/main/java/fr/sushi/charmsnfabrics/common/CnFRegistries.java new file mode 100644 index 0000000..33e439b --- /dev/null +++ b/src/main/java/fr/sushi/charmsnfabrics/common/CnFRegistries.java @@ -0,0 +1,110 @@ +package fr.sushi.charmsnfabrics.common; + +import fr.sushi.charmsnfabrics.CharmsAndFabrics; +import fr.sushi.charmsnfabrics.common.block.FloralWorkbench; +import fr.sushi.charmsnfabrics.common.entities.block.FloralWorkbenchBlockEntity; +import fr.sushi.charmsnfabrics.common.item.FlowerCrown; +import net.minecraft.core.registries.Registries; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceKey; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.CreativeModeTab; +import net.minecraft.world.item.CreativeModeTabs; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.SoundType; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.material.MapColor; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.neoforge.registries.DeferredBlock; +import net.neoforged.neoforge.registries.DeferredHolder; +import net.neoforged.neoforge.registries.DeferredItem; +import net.neoforged.neoforge.registries.DeferredRegister; + +import java.util.Set; +import java.util.function.Supplier; + +public class CnFRegistries +{ + public static class Items + { + public static final DeferredRegister.Items ITEMS = + DeferredRegister.createItems(CharmsAndFabrics.MODID); + public static final DeferredItem FLOWER_CROWN = + ITEMS.registerItem("flower_crown", + (properties) -> new FlowerCrown( + properties.stacksTo(1))); + /* BlockItems */ + public static final DeferredItem FLORAL_WORKBENCH = + ITEMS.registerItem("floral_workbench", + properties -> new BlockItem( + Blocks.FLORAL_WORKBENCH.get(), properties)); + } + + public static class Blocks + { + public static final DeferredRegister.Blocks BLOCKS = + DeferredRegister.createBlocks(CharmsAndFabrics.MODID); + public static final DeferredBlock FLORAL_WORKBENCH = + BLOCKS.register("floral_workbench", + registry_name -> new FloralWorkbench( + BlockBehaviour.Properties.of() + .setId(ResourceKey.create( + Registries.BLOCK, + registry_name)) + .noOcclusion() + .mapColor( + MapColor.WOOD) + .strength(2.0f, 3.0f) + .sound(SoundType.WOOD) + .ignitedByLava())); + } + + public static class Tabs + { + public static final DeferredRegister + CREATIVE_MODE_TABS = + DeferredRegister.create(Registries.CREATIVE_MODE_TAB, + CharmsAndFabrics.MODID); + public static final DeferredHolder + CHARMS_AND_FABRICS_TAB = + CREATIVE_MODE_TABS.register("charmsnfabrics_tab", + () -> CreativeModeTab.builder() + .title(Component.translatable( + "itemGroup.charmsnfabrics")) + .withTabsBefore( + CreativeModeTabs.COMBAT) + .icon(Items.FLOWER_CROWN.get()::getDefaultInstance) + .displayItems( + (parameters, output) -> + { + output.accept( + Items.FLOWER_CROWN.get()); + output.accept( + Blocks.FLORAL_WORKBENCH.toStack()); + }).build()); + } + + public static class Entities + { + public static final DeferredRegister> + BLOCK_ENTITY_TYPES = + DeferredRegister.create(Registries.BLOCK_ENTITY_TYPE, + CharmsAndFabrics.MODID); + public static final Supplier> + FLORAL_WORKBENCH_BLOCKENTITY = + BLOCK_ENTITY_TYPES.register("floral_workbench_entity", + () -> new BlockEntityType<>( + FloralWorkbenchBlockEntity::new, + Set.of(Blocks.FLORAL_WORKBENCH.get()))); + } + + public static void register(IEventBus bus) + { + Items.ITEMS.register(bus); + Blocks.BLOCKS.register(bus); + Tabs.CREATIVE_MODE_TABS.register(bus); + Entities.BLOCK_ENTITY_TYPES.register(bus); + } +} diff --git a/src/main/java/fr/sushi/charmsnfabrics/common/block/FloralWorkbench.java b/src/main/java/fr/sushi/charmsnfabrics/common/block/FloralWorkbench.java new file mode 100644 index 0000000..6e13989 --- /dev/null +++ b/src/main/java/fr/sushi/charmsnfabrics/common/block/FloralWorkbench.java @@ -0,0 +1,154 @@ +package fr.sushi.charmsnfabrics.common.block; + +import com.mojang.serialization.MapCodec; +import fr.sushi.charmsnfabrics.common.CnFRegistries; +import fr.sushi.charmsnfabrics.common.entities.block.FloralWorkbenchBlockEntity; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.*; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +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.HorizontalDirectionalBlock; +import net.minecraft.world.level.block.Rotation; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.EnumProperty; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.Shapes; +import net.minecraft.world.phys.shapes.VoxelShape; +import net.neoforged.neoforge.items.IItemHandler; +import org.jetbrains.annotations.Nullable; + +import java.util.Map; + +public class FloralWorkbench extends BaseEntityBlock +{ + public static final MapCodec CODEC = + simpleCodec(FloralWorkbench::new); + + public static final EnumProperty FACING = + HorizontalDirectionalBlock.FACING; + + private static final VoxelShape LEGS = + Shapes.or(Block.box(1.0, 0.0, 1.0, 3.0, 12.0, 3.0), + Block.box(1.0, 0.0, 13.0, 3.0, 12.0, 15.0), + Block.box(13.0, 0.0, 13.0, 15.0, 12.0, 15.0), + Block.box(13.0, 0.0, 1.0, 15.0, 12.0, 3.0)); + private static final VoxelShape TABLE = Block.column(16.0, 12.0, 14.0); + private static final VoxelShape SUPPORT = Block.column(12.0, 2.0, 3.0); + private static final Map SHAPES = + Shapes.rotateHorizontalAxis(Shapes.or(LEGS, TABLE, SUPPORT)); + + public FloralWorkbench(BlockBehaviour.Properties properties) + { + super(properties); + this.registerDefaultState( + this.stateDefinition.any().setValue(FACING, Direction.NORTH)); + } + + @Override + protected MapCodec codec() + { + return CODEC; + } + + @Override + protected void createBlockStateDefinition( + StateDefinition.Builder builder) + { + builder.add(FACING); + } + + @Override + public @Nullable BlockState getStateForPlacement(BlockPlaceContext ctx) + { + return this.defaultBlockState().setValue(FACING, + ctx.getHorizontalDirection().getClockWise()); + } + + @Override + protected BlockState rotate(BlockState state, Rotation rot) + { + return state.setValue(FACING, rot.rotate(state.getValue(FACING))); + } + + @Override + protected VoxelShape getShape(BlockState state, BlockGetter level, + BlockPos pos, CollisionContext context) + { + return SHAPES.get(state.getValue(FACING).getAxis()); + } + + @Override + public @Nullable BlockEntity newBlockEntity(BlockPos pos, BlockState state) + { + return new FloralWorkbenchBlockEntity(pos, state); + } + + @Override + protected InteractionResult useItemOn(ItemStack stack, BlockState state, + Level level, BlockPos pos, Player player, InteractionHand hand, + BlockHitResult hitResult) + { + if (level.getBlockEntity( + pos) instanceof FloralWorkbenchBlockEntity blockentity) + { + boolean hasCrown = blockentity.hasCrown(); + boolean emptyHand = stack.isEmpty(); + if (!level.isClientSide()) + { + IItemHandler handler = blockentity.getItemHandler(); + + if (hasCrown && emptyHand) + { + ItemStack extracted = handler.extractItem(0, 1, false); + if (!player.hasInfiniteMaterials()) + { + Containers.dropItemStack(level, pos.getX(), + pos.getY() + 1.0f, pos.getZ(), extracted); + } + blockentity.setChanged(); + level.sendBlockUpdated(pos, state, state, 3); + return InteractionResult.SUCCESS_SERVER; + } + else if (stack.is(CnFRegistries.Items.FLOWER_CROWN.get()) && + !hasCrown) + { + handler.insertItem(0, stack.copy(), false); + stack.consume(1, player); + blockentity.setChanged(); + level.sendBlockUpdated(pos, state, state, 3); + return InteractionResult.CONSUME; + } + else + { + return InteractionResult.PASS; + } + } + else + { + return !hasCrown ^ emptyHand ? InteractionResult.SUCCESS : + InteractionResult.PASS; + } + } + else + { + return InteractionResult.PASS; + } + } + + @Override + protected @Nullable MenuProvider getMenuProvider(BlockState state, + Level level, BlockPos pos) + { + return null; + } +} diff --git a/src/main/java/fr/sushi/charmsnfabrics/common/entities/block/FloralWorkbenchBlockEntity.java b/src/main/java/fr/sushi/charmsnfabrics/common/entities/block/FloralWorkbenchBlockEntity.java new file mode 100644 index 0000000..ab090e0 --- /dev/null +++ b/src/main/java/fr/sushi/charmsnfabrics/common/entities/block/FloralWorkbenchBlockEntity.java @@ -0,0 +1,86 @@ +package fr.sushi.charmsnfabrics.common.entities.block; + +import fr.sushi.charmsnfabrics.common.CnFRegistries; +import net.minecraft.core.BlockPos; +import net.minecraft.core.HolderLookup; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.Connection; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ClientGamePacketListener; +import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.neoforged.neoforge.items.IItemHandler; +import net.neoforged.neoforge.items.ItemStackHandler; +import org.jetbrains.annotations.Nullable; + +public class FloralWorkbenchBlockEntity extends BlockEntity +{ + private final RandomSource randomSource = RandomSource.create(); + private final ItemStackHandler itemHandler = new ItemStackHandler(1); + + public FloralWorkbenchBlockEntity(BlockPos pos, BlockState blockState) + { + super(CnFRegistries.Entities.FLORAL_WORKBENCH_BLOCKENTITY.get(), pos, + blockState); + } + + @Override + protected void saveAdditional(CompoundTag nbt, + HolderLookup.Provider levelRegistry) + { + super.saveAdditional(nbt, levelRegistry); + CompoundTag tag = itemHandler.serializeNBT(levelRegistry); + nbt.put("Inventory", tag); + } + + @Override + protected void loadAdditional(CompoundTag nbt, + HolderLookup.Provider levelRegistry) + { + super.loadAdditional(nbt, levelRegistry); + nbt.getCompound("Inventory") + .ifPresent(tag -> itemHandler.deserializeNBT(levelRegistry, tag)); + } + + @Override + public CompoundTag getUpdateTag(HolderLookup.Provider registries) + { + CompoundTag tag = super.getUpdateTag(registries); + tag.put("Inventory", itemHandler.serializeNBT(registries)); + return tag; + } + + + @Override + public void handleUpdateTag(CompoundTag nbt, + HolderLookup.Provider lookupProvider) + { + super.handleUpdateTag(nbt, lookupProvider); + nbt.getCompound("Inventory") + .ifPresent(tag -> itemHandler.deserializeNBT(lookupProvider, tag)); + } + + @Override + public @Nullable Packet getUpdatePacket() + { + return ClientboundBlockEntityDataPacket.create(this); + } + + public RandomSource getRandomSource() + { + return this.randomSource; + } + + public boolean hasCrown() + { + return this.itemHandler.getStackInSlot(0) + .is(CnFRegistries.Items.FLOWER_CROWN.get()); + } + + public IItemHandler getItemHandler() + { + return this.itemHandler; + } +} diff --git a/src/main/resources/assets/charmsnfabrics/items/flower_crown.json b/src/main/resources/assets/charmsnfabrics/items/flower_crown.json deleted file mode 100644 index efc1da8..0000000 --- a/src/main/resources/assets/charmsnfabrics/items/flower_crown.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "model": { - "type": "minecraft:model", - "model": "charmsnfabrics:item/flower_crown" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/charmsnfabrics/lang/en_us.json b/src/main/resources/assets/charmsnfabrics/lang/en_us.json index b9b2646..8872566 100644 --- a/src/main/resources/assets/charmsnfabrics/lang/en_us.json +++ b/src/main/resources/assets/charmsnfabrics/lang/en_us.json @@ -1,6 +1,7 @@ { "itemGroup.charmsnfabrics": "Charms & Fabrics", "item.charmsnfabrics.flower_crown": "Flower Crown", + "item.charmsnfabrics.floral_workbench": "Floral Workbench", "charmsnfabrics.configuration.title": "Charms & Fabrics Configs", "charmsnfabrics.configuration.section.charmsnfabrics.common.toml": "Charms & Fabrics Configs", diff --git a/src/main/resources/assets/charmsnfabrics/models/block/floral_workbench.json b/src/main/resources/assets/charmsnfabrics/models/block/floral_workbench.json new file mode 100644 index 0000000..e9d022f --- /dev/null +++ b/src/main/resources/assets/charmsnfabrics/models/block/floral_workbench.json @@ -0,0 +1,201 @@ +{ + "format_version": "1.21.6", + "credit": "Made with Blockbench", + "texture_size": [64, 64], + "render_type": "minecraft:cutout_mipped", + "textures": { + "0": "charmsnfabrics:block/floral_workbench", + "particle": "minecraft:block/oak_planks" + }, + "elements": [ + { + "from": [1, 0, 1], + "to": [3, 12, 3], + "faces": { + "north": {"uv": [0.5, 12.5, 1, 15.5], "texture": "#0"}, + "east": {"uv": [0, 12.5, 0.5, 15.5], "texture": "#0"}, + "south": {"uv": [1.5, 12.5, 2, 15.5], "texture": "#0"}, + "west": {"uv": [1, 12.5, 1.5, 15.5], "texture": "#0"}, + "up": {"uv": [1, 12.5, 0.5, 12], "texture": "#0"}, + "down": {"uv": [1.5, 12, 1, 12.5], "texture": "#0"} + } + }, + { + "from": [1, 0, 13], + "to": [3, 12, 15], + "faces": { + "north": {"uv": [0.5, 12.5, 1, 15.5], "texture": "#0"}, + "east": {"uv": [0, 12.5, 0.5, 15.5], "texture": "#0"}, + "south": {"uv": [1.5, 12.5, 2, 15.5], "texture": "#0"}, + "west": {"uv": [1, 12.5, 1.5, 15.5], "texture": "#0"}, + "up": {"uv": [1, 12.5, 0.5, 12], "texture": "#0"}, + "down": {"uv": [1.5, 12, 1, 12.5], "texture": "#0"} + } + }, + { + "from": [13, 0, 13], + "to": [15, 12, 15], + "faces": { + "north": {"uv": [0.5, 12.5, 1, 15.5], "texture": "#0"}, + "east": {"uv": [0, 12.5, 0.5, 15.5], "texture": "#0"}, + "south": {"uv": [1.5, 12.5, 2, 15.5], "texture": "#0"}, + "west": {"uv": [1, 12.5, 1.5, 15.5], "texture": "#0"}, + "up": {"uv": [1, 12.5, 0.5, 12], "texture": "#0"}, + "down": {"uv": [1.5, 12, 1, 12.5], "texture": "#0"} + } + }, + { + "from": [13, 0, 1], + "to": [15, 12, 3], + "faces": { + "north": {"uv": [0.5, 12.5, 1, 15.5], "texture": "#0"}, + "east": {"uv": [0, 12.5, 0.5, 15.5], "texture": "#0"}, + "south": {"uv": [1.5, 12.5, 2, 15.5], "texture": "#0"}, + "west": {"uv": [1, 12.5, 1.5, 15.5], "texture": "#0"}, + "up": {"uv": [1, 12.5, 0.5, 12], "texture": "#0"}, + "down": {"uv": [1.5, 12, 1, 12.5], "texture": "#0"} + } + }, + { + "from": [0, 12, 0], + "to": [16, 14, 16], + "faces": { + "north": {"uv": [4, 15.5, 8, 16], "texture": "#0"}, + "east": {"uv": [0, 15.5, 4, 16], "texture": "#0"}, + "south": {"uv": [12, 15.5, 16, 16], "texture": "#0"}, + "west": {"uv": [8, 15.5, 12, 16], "texture": "#0"}, + "up": {"uv": [8, 15.5, 4, 11.5], "texture": "#0"}, + "down": {"uv": [12, 11.5, 8, 15.5], "texture": "#0"} + } + }, + { + "from": [2, 2, 2], + "to": [14, 3, 14], + "faces": { + "north": {"uv": [3, 11.25, 6, 11.5], "texture": "#0"}, + "east": {"uv": [0, 11.25, 3, 11.5], "texture": "#0"}, + "south": {"uv": [9, 11.25, 12, 11.5], "texture": "#0"}, + "west": {"uv": [6, 11.25, 9, 11.5], "texture": "#0"}, + "up": {"uv": [6, 11.25, 3, 8.25], "texture": "#0"}, + "down": {"uv": [9, 8.25, 6, 11.25], "texture": "#0"} + } + }, + { + "from": [3, 14, 3], + "to": [13, 15, 13], + "faces": { + "north": {"uv": [2.5, 8, 5, 8.25], "texture": "#0"}, + "east": {"uv": [0, 8, 2.5, 8.25], "texture": "#0"}, + "south": {"uv": [7.5, 8, 10, 8.25], "texture": "#0"}, + "west": {"uv": [5, 8, 7.5, 8.25], "texture": "#0"}, + "up": {"uv": [5, 8, 2.5, 5.5], "texture": "#0"}, + "down": {"uv": [7.5, 5.5, 5, 8], "texture": "#0"} + } + }, + { + "from": [0, 14.25, 0], + "to": [16, 14.25, 16], + "faces": { + "north": {"uv": [7.5, 8, 11.5, 8], "texture": "#0"}, + "east": {"uv": [3.5, 8, 7.5, 8], "texture": "#0"}, + "south": {"uv": [15.5, 8, 19.5, 8], "texture": "#0"}, + "west": {"uv": [11.5, 8, 15.5, 8], "texture": "#0"}, + "up": {"uv": [11.5, 8, 7.5, 4], "texture": "#0"}, + "down": {"uv": [15.5, 4, 11.5, 8], "texture": "#0"} + } + }, + { + "from": [0, 0, -0.25], + "to": [8, 14, -0.25], + "faces": { + "north": {"uv": [12, 8, 14, 11.5], "texture": "#0"}, + "east": {"uv": [12, 8, 12, 11.5], "texture": "#0"}, + "south": {"uv": [14, 8, 16, 11.5], "texture": "#0"}, + "west": {"uv": [14, 8, 14, 11.5], "texture": "#0"}, + "up": {"uv": [14, 8, 12, 8], "texture": "#0"}, + "down": {"uv": [16, 8, 14, 8], "texture": "#0"} + } + }, + { + "from": [8, 0, 16.25], + "to": [16, 14, 16.25], + "faces": { + "north": {"uv": [12, 11.5, 14, 15], "texture": "#0"}, + "east": {"uv": [12, 11.5, 12, 15], "texture": "#0"}, + "south": {"uv": [14, 11.5, 16, 15], "texture": "#0"}, + "west": {"uv": [14, 11.5, 14, 15], "texture": "#0"}, + "up": {"uv": [14, 11.5, 12, 11.5], "texture": "#0"}, + "down": {"uv": [16, 11.5, 14, 11.5], "texture": "#0"} + } + }, + { + "from": [4, 3, 3], + "to": [9, 5, 8], + "faces": { + "north": {"uv": [1.75, 3.5, 3, 4], "texture": "#0"}, + "east": {"uv": [0.5, 3.5, 1.75, 4], "texture": "#0"}, + "south": {"uv": [4.25, 3.5, 5.5, 4], "texture": "#0"}, + "west": {"uv": [3, 3.5, 4.25, 4], "texture": "#0"}, + "up": {"uv": [3, 3.5, 1.75, 2.25], "texture": "#0"}, + "down": {"uv": [4.25, 2.25, 3, 3.5], "texture": "#0"} + } + }, + { + "from": [4, 3, 9], + "to": [12, 5, 13], + "faces": { + "north": {"uv": [1, 5, 3, 5.5], "texture": "#0"}, + "east": {"uv": [0, 5, 1, 5.5], "texture": "#0"}, + "south": {"uv": [4, 5, 6, 5.5], "texture": "#0"}, + "west": {"uv": [3, 5, 4, 5.5], "texture": "#0"}, + "up": {"uv": [3, 5, 1, 4], "texture": "#0"}, + "down": {"uv": [5, 4, 3, 5], "texture": "#0"} + } + } + ], + "display": { + "thirdperson_righthand": { + "scale": [0.5, 0.5, 0.5] + }, + "thirdperson_lefthand": { + "scale": [0.5, 0.5, 0.5] + }, + "firstperson_righthand": { + "scale": [0.5, 0.5, 0.5] + }, + "firstperson_lefthand": { + "scale": [0.5, 0.5, 0.5] + }, + "ground": { + "translation": [0, 2, 0], + "scale": [0.25, 0.25, 0.25] + }, + "gui": { + "rotation": [30, 45, 0], + "scale": [0.625, 0.625, 0.625] + }, + "head": { + "translation": [0, 1, 0] + } + }, + "groups": [ + { + "name": "legs", + "origin": [8, 8, 8], + "color": 0, + "children": [0, 1, 2, 3] + }, + { + "name": "station", + "origin": [8, 8, 8], + "color": 0, + "children": [4, 5, 6] + }, + { + "name": "decoration", + "origin": [8, 8, 8], + "color": 0, + "children": [7, 8, 9, 10, 11] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/charmsnfabrics/models/item/flower_crown.json b/src/main/resources/assets/charmsnfabrics/models/item/flower_crown.json deleted file mode 100644 index a6aaaa6..0000000 --- a/src/main/resources/assets/charmsnfabrics/models/item/flower_crown.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "minecraft:item/generated", - "textures": { - "layer0": "charmsnfabrics:item/flower_crown" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/charmsnfabrics/textures/block/floral_workbench.png b/src/main/resources/assets/charmsnfabrics/textures/block/floral_workbench.png new file mode 100644 index 0000000..06ba6c0 Binary files /dev/null and b/src/main/resources/assets/charmsnfabrics/textures/block/floral_workbench.png differ diff --git a/src/main/resources/assets/charmsnfabrics/textures/gui/container/floral_workbench.png b/src/main/resources/assets/charmsnfabrics/textures/gui/container/floral_workbench.png new file mode 100644 index 0000000..de8290c Binary files /dev/null and b/src/main/resources/assets/charmsnfabrics/textures/gui/container/floral_workbench.png differ diff --git a/src/main/resources/assets/charmsnfabrics/textures/item/flower_crown.png b/src/main/resources/assets/charmsnfabrics/textures/item/flower_crown.png index d3be2ec..7912290 100644 Binary files a/src/main/resources/assets/charmsnfabrics/textures/item/flower_crown.png and b/src/main/resources/assets/charmsnfabrics/textures/item/flower_crown.png differ diff --git a/src/main/templates/META-INF/neoforge.mods.toml b/src/main/templates/META-INF/neoforge.mods.toml index eadb321..8fa20aa 100644 --- a/src/main/templates/META-INF/neoforge.mods.toml +++ b/src/main/templates/META-INF/neoforge.mods.toml @@ -89,7 +89,7 @@ description='''${mod_description}''' [[dependencies.${mod_id}]] modId="curios" type="required" - versionRange="[11.0.1,)" + versionRange="[11.0.1,]" ordering="BEFORE" side="BOTH"