From 1a3d94f94ec21c69172200c3b45241e5b8aa55b8 Mon Sep 17 00:00:00 2001 From: SushiCannibale Date: Thu, 31 Jul 2025 14:24:11 +0200 Subject: [PATCH] feat: flower crown --- .../client/CharmsAndFabricsLayers.java | 12 ++ .../client/CharmsFabricsClient.java | 11 +- .../client/model/FlowerCrownModel.java | 111 +++++++++++++++++- .../client/renderer/FlowerCrownRenderer.java | 38 +++++- .../common/item/FlowerCrown.java | 16 +++ .../models/accessory/flower_crown.png | Bin 0 -> 552 bytes .../curios/entities/entities.json | 12 +- .../templates/META-INF/neoforge.mods.toml | 7 ++ 8 files changed, 189 insertions(+), 18 deletions(-) create mode 100644 src/main/java/fr/sushi/charmsnfabrics/client/CharmsAndFabricsLayers.java create mode 100644 src/main/resources/assets/charmsnfabrics/textures/models/accessory/flower_crown.png diff --git a/src/main/java/fr/sushi/charmsnfabrics/client/CharmsAndFabricsLayers.java b/src/main/java/fr/sushi/charmsnfabrics/client/CharmsAndFabricsLayers.java new file mode 100644 index 0000000..429f56c --- /dev/null +++ b/src/main/java/fr/sushi/charmsnfabrics/client/CharmsAndFabricsLayers.java @@ -0,0 +1,12 @@ +package fr.sushi.charmsnfabrics.client; + +import fr.sushi.charmsnfabrics.CharmsAndFabrics; +import net.minecraft.client.model.geom.ModelLayerLocation; +import net.minecraft.resources.ResourceLocation; + +public class CharmsAndFabricsLayers +{ + public static final ModelLayerLocation CROWN_LAYER = new ModelLayerLocation( + ResourceLocation.fromNamespaceAndPath(CharmsAndFabrics.MODID, + "flower_crown_model"), "crown"); +} diff --git a/src/main/java/fr/sushi/charmsnfabrics/client/CharmsFabricsClient.java b/src/main/java/fr/sushi/charmsnfabrics/client/CharmsFabricsClient.java index 964a261..355f328 100644 --- a/src/main/java/fr/sushi/charmsnfabrics/client/CharmsFabricsClient.java +++ b/src/main/java/fr/sushi/charmsnfabrics/client/CharmsFabricsClient.java @@ -1,15 +1,16 @@ 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.IEventBus; 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; @@ -31,4 +32,12 @@ public class CharmsFabricsClient 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/model/FlowerCrownModel.java b/src/main/java/fr/sushi/charmsnfabrics/client/model/FlowerCrownModel.java index fcc48bc..a6f0a7e 100644 --- a/src/main/java/fr/sushi/charmsnfabrics/client/model/FlowerCrownModel.java +++ b/src/main/java/fr/sushi/charmsnfabrics/client/model/FlowerCrownModel.java @@ -1,6 +1,111 @@ package fr.sushi.charmsnfabrics.client.model; -public class FlowerCrownModel -{ +import net.minecraft.client.model.HumanoidModel; +import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.client.model.geom.PartPose; +import net.minecraft.client.model.geom.builders.*; +import net.minecraft.client.renderer.entity.state.HumanoidRenderState; -} +public class FlowerCrownModel extends HumanoidModel +{ + private final ModelPart crown; + private final ModelPart flowers; + + public FlowerCrownModel(ModelPart root) + { + super(root); + this.crown = this.getHead().getChild("crown"); + this.flowers = this.getHead().getChild("flowers"); + } + + public static LayerDefinition createLayer() + { + MeshDefinition meshdefinition = + HumanoidModel.createMesh(CubeDeformation.NONE, 0.0f); + PartDefinition partdefinition = meshdefinition.getRoot(); + PartDefinition partDefinition1 = partdefinition.clearChild("head"); + partDefinition1.clearChild("hat"); + partdefinition.clearChild("body"); + partdefinition.clearChild("left_arm"); + partdefinition.clearChild("right_arm"); + partdefinition.clearChild("left_leg"); + partdefinition.clearChild("right_leg"); + PartDefinition crown = partDefinition1.addOrReplaceChild("crown", + CubeListBuilder.create().texOffs(0, 0) + .addBox(-4.0F, -2.0F, -4.0F, 8.0F, 2.0F, 8.0F), + PartPose.offset(0.0F, -6.0F, 0.0F)); + PartDefinition cube_r1 = crown.addOrReplaceChild("cube_r1", + CubeListBuilder.create().texOffs(0, 7) + .addBox(0.0F, -2.0F, -5.0F, 0.0F, 3.0F, 10.0F), + PartPose.offsetAndRotation(4.0F, -1.5F, 0.0F, -3.1416F, 0.0F, + -2.7489F)); + PartDefinition cube_r2 = crown.addOrReplaceChild("cube_r2", + CubeListBuilder.create().texOffs(0, 7) + .addBox(0.0F, -2.0F, -5.0F, 0.0F, 3.0F, 10.0F), + PartPose.offsetAndRotation(4.0F, -0.5F, 0.0F, 0.0F, 0.0F, + 2.7489F)); + PartDefinition cube_r3 = crown.addOrReplaceChild("cube_r3", + CubeListBuilder.create().texOffs(0, 1) + .addBox(0.0F, -2.0F, -5.0F, 0.0F, 3.0F, 10.0F), + PartPose.offsetAndRotation(-4.0F, -1.5F, 0.0F, -3.1416F, 0.0F, + 2.7489F)); + PartDefinition cube_r4 = crown.addOrReplaceChild("cube_r4", + CubeListBuilder.create().texOffs(0, 1) + .addBox(0.0F, -2.0F, -5.0F, 0.0F, 3.0F, 10.0F), + PartPose.offsetAndRotation(-4.0F, -0.5F, 0.0F, 0.0F, 0.0F, + -2.7489F)); + PartDefinition cube_r5 = crown.addOrReplaceChild("cube_r5", + CubeListBuilder.create().texOffs(0, 20) + .addBox(-5.0F, -2.0F, 0.0F, 10.0F, 3.0F, 0.0F), + PartPose.offsetAndRotation(0.0F, -1.5F, 4.0F, -0.3927F, 0.0F, + 0.0F)); + PartDefinition cube_r6 = crown.addOrReplaceChild("cube_r6", + CubeListBuilder.create().texOffs(0, 20) + .addBox(-5.0F, -2.0F, 0.0F, 10.0F, 3.0F, 0.0F), + PartPose.offsetAndRotation(0.0F, -0.5F, 4.0F, -0.3927F, 0.0F, + -3.1416F)); + PartDefinition cube_r7 = crown.addOrReplaceChild("cube_r7", + CubeListBuilder.create().texOffs(0, 14) + .addBox(-5.0F, -2.0F, 0.0F, 10.0F, 3.0F, 0.0F), + PartPose.offsetAndRotation(0.0F, -1.5F, -4.0F, 2.7489F, 0.0F, + 3.1416F)); + PartDefinition cube_r8 = crown.addOrReplaceChild("cube_r8", + CubeListBuilder.create().texOffs(0, 14) + .addBox(-5.0F, -2.0F, 0.0F, 10.0F, 3.0F, 0.0F), + PartPose.offsetAndRotation(0.0F, -0.5F, -4.0F, 2.7489F, 0.0F, + 0.0F)); + PartDefinition flowers = partDefinition1.addOrReplaceChild("flowers", + CubeListBuilder.create().texOffs(0, 23) + .addBox(0.0F, -4.0F, -5.0F, 4.0F, 4.0F, 0.0F) + .texOffs(8, 23) + .addBox(5.0F, -2.0F, -4.0F, 0.0F, 3.0F, 3.0F) + .texOffs(0, 19) + .addBox(5.0F, -3.0F, 0.0F, 0.0F, 4.0F, 4.0F) + .texOffs(0, 27) + .addBox(-5.0F, -3.0F, -5.0F, 4.0F, 4.0F, 0.0F) + .texOffs(8, 26) + .addBox(2.0F, -4.0F, 4.5F, 3.0F, 3.0F, 0.0F) + .texOffs(8, 23) + .addBox(-1.0F, -2.0F, 4.5F, 3.0F, 3.0F, 0.0F) + .texOffs(0, 27) + .addBox(-5.0F, -4.0F, 4.5F, 4.0F, 4.0F, 0.0F) + .texOffs(8, 20) + .addBox(-4.5F, -2.0F, 1.25F, 0.0F, 3.0F, 3.0F) + .texOffs(0, 19) + .addBox(-5.0F, -4.0F, -3.75F, 0.0F, 4.0F, 4.0F), + PartPose.offset(0.0F, -6.0F, 0.0F)); + return LayerDefinition.create(meshdefinition, 32, 32); + } + + @Override + public void setupAnim(HumanoidRenderState renderState) + { + super.setupAnim(renderState); + this.flowers.xScale = 1.2f; + this.flowers.yScale = 1.2f; + this.flowers.zScale = 1.2f; + this.crown.xScale = 1.2f; + this.crown.yScale = 1.2f; + this.crown.zScale = 1.2f; + } +} \ No newline at end of file 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 3c55b5a..735a45b 100644 --- a/src/main/java/fr/sushi/charmsnfabrics/client/renderer/FlowerCrownRenderer.java +++ b/src/main/java/fr/sushi/charmsnfabrics/client/renderer/FlowerCrownRenderer.java @@ -1,11 +1,20 @@ 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.model.FlowerCrownModel; +import fr.sushi.charmsnfabrics.common.item.FlowerCrown; +import net.minecraft.client.Minecraft; import net.minecraft.client.model.EntityModel; import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.entity.EntityRendererProvider; +import net.minecraft.client.renderer.entity.ItemRenderer; import net.minecraft.client.renderer.entity.RenderLayerParent; import net.minecraft.client.renderer.entity.state.LivingEntityRenderState; +import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.ItemStack; import org.jetbrains.annotations.NotNull; import top.theillusivec4.curios.api.SlotContext; @@ -13,9 +22,32 @@ import top.theillusivec4.curios.api.client.ICurioRenderer; public class FlowerCrownRenderer implements ICurioRenderer { - @Override - public > void render(ItemStack stack, SlotContext slotContext, PoseStack poseStack, @NotNull MultiBufferSource renderTypeBuffer, int packedLight, S renderState, RenderLayerParent renderLayerParent, EntityRendererProvider.Context context, float yRotation, float xRotation) + private final FlowerCrownModel model; + + public FlowerCrownRenderer() { - System.out.println("UwU"); + this.model = new FlowerCrownModel( + Minecraft.getInstance().getEntityModels() + .bakeLayer(CharmsAndFabricsLayers.CROWN_LAYER)); + } + + @Override + public > void render( + ItemStack stack, SlotContext slotContext, PoseStack poseStack, + @NotNull MultiBufferSource renderTypeBuffer, int packedLight, + S renderState, RenderLayerParent renderLayerParent, + EntityRendererProvider.Context context, float yRotation, + float xRotation) + { + FlowerCrown item = (FlowerCrown) stack.getItem(); + ResourceLocation texture = item.getModelTexture(); + VertexConsumer vertexconsumer = + ItemRenderer.getArmorFoilBuffer(renderTypeBuffer, + RenderType.entityCutout( + texture), + stack.hasFoil()); + ICurioRenderer.setupHumanoidAnimations(this.model, renderState); + this.model.renderToBuffer(poseStack, vertexconsumer, packedLight, + OverlayTexture.NO_OVERLAY); } } diff --git a/src/main/java/fr/sushi/charmsnfabrics/common/item/FlowerCrown.java b/src/main/java/fr/sushi/charmsnfabrics/common/item/FlowerCrown.java index 26fa226..80bb504 100644 --- a/src/main/java/fr/sushi/charmsnfabrics/common/item/FlowerCrown.java +++ b/src/main/java/fr/sushi/charmsnfabrics/common/item/FlowerCrown.java @@ -1,5 +1,9 @@ package fr.sushi.charmsnfabrics.common.item; +import fr.sushi.charmsnfabrics.CharmsAndFabrics; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import top.theillusivec4.curios.api.SlotContext; @@ -17,4 +21,16 @@ public class FlowerCrown extends Item implements ICurioItem { return slotContext.identifier().contains("head"); } + + @Override + public boolean canEquip(SlotContext slotContext, ItemStack stack) + { + return slotContext.identifier().contains("head"); + } + + public ResourceLocation getModelTexture() + { + return ResourceLocation.fromNamespaceAndPath(CharmsAndFabrics.MODID, + "textures/models/accessory/flower_crown.png"); + } } diff --git a/src/main/resources/assets/charmsnfabrics/textures/models/accessory/flower_crown.png b/src/main/resources/assets/charmsnfabrics/textures/models/accessory/flower_crown.png new file mode 100644 index 0000000000000000000000000000000000000000..3c2b5ef59ce3a5e4a0deb50b53e43bd45cc88ca1 GIT binary patch literal 552 zcmV+@0@wYCP)Px$;z>k7R9J=Wm9c6YK@f(&v(&_$Y(rcGH!f@mOG?rOgPMR*XE3O6ij;W<6?p(X zgC9VRAhmFj!l2gRGn~~4R0ts~#1+1+lt~e0vpUX76t<9w{^n+8Xa0Y8X73I**kFVI z9YLd0mia6oR}gOQ9;j7|xc=!uiQX`>Pk>srxRBc$M%1cB0B-IcY>x7{d;q5hB>;NE zh~V|tyeMH>%#G&?0$>F-HlGES%#Eq9Ygrr8+V#N2RYlZpbjp$y|C^ju5hy{fAaok{ z3wHvb)3{&glL~8&Tl4KpxK2G?5!%M*TAmfls#z6z_|?|=>~}Cd1{b-4*pa1c(&Ktr zc&?r9ZFlWuHLGAt3EXxsBhFgWvHa^M)(3xj6MVk`;EVvUx4t)wmJ(lFRYZSGTJy3; z5VjKu+legmvuq#8hwVfT_ujGn{@9Y2&n`)B`_?~s`;l&QYVEL{NafSEmyb?<6dF!G z?~vT~8HEOb!@WMQ-s~{?Zm73*gKl#w_110x&}Az1mLGA8ZgVPn!YtnylWBW{F-FoN z>KkL^NAy9W@mO5jtN7FPk;vn@sIWYq%hUCd-GnRXRUFtF#4!LenJ|cB262o`CIIMK qX@B3&+_k+S8jmG?O5Z14Tl@rXn~y*>ho;>C0000