From 2f6b269895c2464746f9f367f767bd7f91b1af9a Mon Sep 17 00:00:00 2001 From: ian1337 Date: Tue, 29 Sep 2026 16:17:32 +0200 Subject: [PATCH] [add] Capybara --- .../masterwild/entity/ModEntities.java | 4 + .../entity/client/capibara/CapybaraModel.java | 97 +++++++++++++++++++ .../client/capibara/CapybaraRenderer.java | 33 +++++++ .../entity/custom/CapybaraEntity.java | 56 +++++++++++ .../masterwild/event/ModEventBusEvents.java | 11 +-- 5 files changed, 193 insertions(+), 8 deletions(-) create mode 100644 src/main/java/ovh/glitchlabs/masterwild/entity/client/capibara/CapybaraModel.java create mode 100644 src/main/java/ovh/glitchlabs/masterwild/entity/client/capibara/CapybaraRenderer.java create mode 100644 src/main/java/ovh/glitchlabs/masterwild/entity/custom/CapybaraEntity.java diff --git a/src/main/java/ovh/glitchlabs/masterwild/entity/ModEntities.java b/src/main/java/ovh/glitchlabs/masterwild/entity/ModEntities.java index 9d9a23a..96525b1 100644 --- a/src/main/java/ovh/glitchlabs/masterwild/entity/ModEntities.java +++ b/src/main/java/ovh/glitchlabs/masterwild/entity/ModEntities.java @@ -50,6 +50,10 @@ public class ModEntities { ENTITY_TYPES.register("monkey", () -> EntityType.Builder.of(MonkeyEntity::new, MobCategory.CREATURE) .sized(0.6f, 0.5f).build("monkey")); + public static final Supplier> CAPYBARA = + ENTITY_TYPES.register("capybara", () -> EntityType.Builder.of(CapybaraEntity::new, MobCategory.CREATURE) + .sized(0.6f, 0.5f).build("capybara")); + public static void register(IEventBus eventBus) { ENTITY_TYPES.register(eventBus); diff --git a/src/main/java/ovh/glitchlabs/masterwild/entity/client/capibara/CapybaraModel.java b/src/main/java/ovh/glitchlabs/masterwild/entity/client/capibara/CapybaraModel.java new file mode 100644 index 0000000..b8739b9 --- /dev/null +++ b/src/main/java/ovh/glitchlabs/masterwild/entity/client/capibara/CapybaraModel.java @@ -0,0 +1,97 @@ +package ovh.glitchlabs.masterwild.entity.client.capibara; + +// Made with Blockbench 5.2.1 +// Exported for Minecraft version 1.17 or later with Mojang mappings +// Paste this class into your mod and generate all required imports +import net.minecraft.client.model.HierarchicalModel; +import net.minecraft.client.model.geom.ModelLayerLocation; +import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.client.model.geom.PartPose; +import net.minecraft.client.model.geom.builders.*; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.Mth; +import ovh.glitchlabs.masterwild.Masterwild; +import ovh.glitchlabs.masterwild.entity.custom.CapybaraEntity; + +public class CapybaraModel extends HierarchicalModel { + // This layer location should be baked with EntityRendererProvider.Context in the entity renderer and passed into this model's constructor + public static final ModelLayerLocation LAYER_LOCATION = new ModelLayerLocation(ResourceLocation.fromNamespaceAndPath(Masterwild.MODID, "capibara"), "main"); + private final ModelPart capybara; + private final ModelPart body; + private final ModelPart body2; + private final ModelPart legs; + private final ModelPart R_front_Leg; + private final ModelPart R_back_Leg; + private final ModelPart L_back_Leg; + private final ModelPart L_front_Leg; + private final ModelPart head; + + public CapybaraModel(ModelPart root) { + this.capybara = root.getChild("capybara"); + this.body = this.capybara.getChild("body"); + this.body2 = this.body.getChild("body2"); + this.legs = this.body.getChild("legs"); + this.R_front_Leg = this.legs.getChild("R_front_Leg"); + this.R_back_Leg = this.legs.getChild("R_back_Leg"); + this.L_back_Leg = this.legs.getChild("L_back_Leg"); + this.L_front_Leg = this.legs.getChild("L_front_Leg"); + this.head = this.capybara.getChild("head"); + } + + public static LayerDefinition createBodyLayer() { + MeshDefinition meshdefinition = new MeshDefinition(); + PartDefinition partdefinition = meshdefinition.getRoot(); + + PartDefinition capybara = partdefinition.addOrReplaceChild("capybara", CubeListBuilder.create(), PartPose.offset(0.0F, 24.0F, 0.0F)); + + PartDefinition body = capybara.addOrReplaceChild("body", CubeListBuilder.create(), PartPose.offset(-1.0F, -3.375F, -6.0F)); + + PartDefinition body2 = body.addOrReplaceChild("body2", CubeListBuilder.create(), PartPose.offset(1.0F, -0.375F, -1.0F)); + + PartDefinition cube_r1 = body2.addOrReplaceChild("cube_r1", CubeListBuilder.create().texOffs(-18, -14).addBox(-5.0F, -10.0F, -1.0F, 10.0F, 10.0F, 16.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(0.0F, 0.0F, 0.0F, 0.0436F, 0.0F, 0.0F)); + + PartDefinition legs = body.addOrReplaceChild("legs", CubeListBuilder.create(), PartPose.offset(-1.0F, 0.375F, 1.0F)); + + PartDefinition R_front_Leg = legs.addOrReplaceChild("R_front_Leg", CubeListBuilder.create().texOffs(-1, -1).mirror().addBox(-1.5F, 0.0F, -1.5F, 3.0F, 4.0F, 3.0F, new CubeDeformation(0.0F)).mirror(false), PartPose.offset(-0.5F, -1.0F, 0.5F)); + + PartDefinition R_back_Leg = legs.addOrReplaceChild("R_back_Leg", CubeListBuilder.create().texOffs(0, 0).mirror().addBox(-1.5F, 0.5F, -1.5F, 3.0F, 5.0F, 3.0F, new CubeDeformation(0.0F)).mirror(false), PartPose.offset(-0.75F, -2.5F, 10.5F)); + + PartDefinition L_back_Leg = legs.addOrReplaceChild("L_back_Leg", CubeListBuilder.create().texOffs(-1, -1).addBox(-1.5F, 0.5F, -1.5F, 3.0F, 5.0F, 3.0F, new CubeDeformation(0.0F)), PartPose.offset(4.75F, -2.5F, 10.5F)); + + PartDefinition L_front_Leg = legs.addOrReplaceChild("L_front_Leg", CubeListBuilder.create().texOffs(-1, -1).addBox(-1.5F, 0.0F, -1.5F, 3.0F, 4.0F, 3.0F, new CubeDeformation(0.0F)), PartPose.offset(4.5F, -1.0F, 0.5F)); + + PartDefinition head = capybara.addOrReplaceChild("head", CubeListBuilder.create().texOffs(-12, -9).addBox(-3.5F, -5.1825F, -9.311F, 7.0F, 7.0F, 11.0F, new CubeDeformation(0.0F)), PartPose.offset(0.0F, -11.5675F, -6.689F)); + + PartDefinition cube_r2 = head.addOrReplaceChild("cube_r2", CubeListBuilder.create().texOffs(1, 0).addBox(0.0F, -2.0F, -1.0F, 1.0F, 2.0F, 2.0F, new CubeDeformation(0.0F)) + .texOffs(0, 0).mirror().addBox(7.0F, -2.0F, -1.0F, 1.0F, 2.0F, 2.0F, new CubeDeformation(0.0F)).mirror(false), PartPose.offsetAndRotation(-4.0F, -4.1825F, -1.311F, -0.2182F, 0.0F, 0.0F)); + + return LayerDefinition.create(meshdefinition, 16, 16); + } + + @Override + public void setupAnim(CapybaraEntity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch) { + this.root().getAllParts().forEach(ModelPart::resetPose); + this.applyHeadRotation(netHeadYaw, headPitch); + this.walk(limbSwing, limbSwingAmount); + } + + private void applyHeadRotation(float headYaw, float headPitch) { + headYaw = Mth.clamp(headYaw, -30f, 30f); + headPitch = Mth.clamp(headPitch, -25f, 45f); + this.head.yRot = headYaw * ((float) Math.PI / 180f); + this.head.xRot = headPitch * ((float) Math.PI / 180f); + } + + private void walk(float limbSwing, float limbSwingAmount) { + float amount = 1.0F * limbSwingAmount; + this.R_front_Leg.xRot = Mth.cos(limbSwing * 0.6662F) * amount; + this.L_back_Leg.xRot = Mth.cos(limbSwing * 0.6662F) * amount; + this.L_front_Leg.xRot = Mth.cos(limbSwing * 0.6662F + (float) Math.PI) * amount; + this.R_back_Leg.xRot = Mth.cos(limbSwing * 0.6662F + (float) Math.PI) * amount; + } + + @Override + public ModelPart root() { + return capybara; + } +} \ No newline at end of file diff --git a/src/main/java/ovh/glitchlabs/masterwild/entity/client/capibara/CapybaraRenderer.java b/src/main/java/ovh/glitchlabs/masterwild/entity/client/capibara/CapybaraRenderer.java new file mode 100644 index 0000000..355e12f --- /dev/null +++ b/src/main/java/ovh/glitchlabs/masterwild/entity/client/capibara/CapybaraRenderer.java @@ -0,0 +1,33 @@ +package ovh.glitchlabs.masterwild.entity.client.capibara; + +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.renderer.entity.EntityRendererProvider; +import net.minecraft.client.renderer.entity.MobRenderer; +import net.minecraft.resources.ResourceLocation; +import ovh.glitchlabs.masterwild.Masterwild; +import ovh.glitchlabs.masterwild.entity.custom.CapybaraEntity; + +public class CapybaraRenderer extends MobRenderer> { + private static final ResourceLocation TEXTURE = + ResourceLocation.fromNamespaceAndPath(Masterwild.MODID, "textures/entity/capibara.png"); + private static final float ADULT_SCALE = 1.5f; + private static final float BABY_SCALE = 0.5f; + private static final float SHADOW = 0.45f; + + public CapybaraRenderer(EntityRendererProvider.Context context) { + super(context, new CapybaraModel<>(context.bakeLayer(CapybaraModel.LAYER_LOCATION)), SHADOW); + } + + @Override + public ResourceLocation getTextureLocation(CapybaraEntity entity) { + return TEXTURE; + } + + @Override + protected void scale(CapybaraEntity entity, PoseStack poseStack, float partialTick) { + float scale = entity.isBaby() ? BABY_SCALE : ADULT_SCALE; + poseStack.scale(scale, scale, scale); + this.shadowRadius = SHADOW * scale; + } + +} diff --git a/src/main/java/ovh/glitchlabs/masterwild/entity/custom/CapybaraEntity.java b/src/main/java/ovh/glitchlabs/masterwild/entity/custom/CapybaraEntity.java new file mode 100644 index 0000000..a92ae2d --- /dev/null +++ b/src/main/java/ovh/glitchlabs/masterwild/entity/custom/CapybaraEntity.java @@ -0,0 +1,56 @@ +package ovh.glitchlabs.masterwild.entity.custom; + +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.AgeableMob; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.ai.attributes.AttributeSupplier; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.entity.ai.goal.*; +import net.minecraft.world.entity.animal.Animal; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.level.Level; +import org.jetbrains.annotations.Nullable; + +public class CapybaraEntity extends Animal { + private static final Ingredient FOOD = Ingredient.of(Items.SHORT_GRASS, Items.MELON); + + public CapybaraEntity(EntityType entityType, Level level) { + super(entityType, level); + } + + public static AttributeSupplier.Builder createAttributes() { + return Mob.createMobAttributes() + .add(Attributes.MAX_HEALTH, 10) + .add(Attributes.MOVEMENT_SPEED, 0.4) + .add(Attributes.FOLLOW_RANGE, 8) + .add(Attributes.KNOCKBACK_RESISTANCE, 0.3) + .add(Attributes.STEP_HEIGHT, 0.6); + } + + @Override + protected void registerGoals() { + this.goalSelector.addGoal(0, new FloatGoal(this)); + this.goalSelector.addGoal(1, new PanicGoal(this, 1.5)); + this.goalSelector.addGoal(2, new BreedGoal(this, 1.0)); + this.goalSelector.addGoal(3, new TemptGoal(this, 1.1, FOOD, false)); + this.goalSelector.addGoal(4, new FollowParentGoal(this, 1.1)); + this.goalSelector.addGoal(5, new WaterAvoidingRandomStrollGoal(this, 0.8)); + this.goalSelector.addGoal(6, new LookAtPlayerGoal(this, Player.class, 6.0F)); + this.goalSelector.addGoal(7, new RandomLookAroundGoal(this)); + } + + @Override + public boolean isFood(ItemStack itemStack) { + return FOOD.test(itemStack); + } + + + @Override + public @Nullable AgeableMob getBreedOffspring(ServerLevel serverLevel, AgeableMob ageableMob) { + return null; + } +} diff --git a/src/main/java/ovh/glitchlabs/masterwild/event/ModEventBusEvents.java b/src/main/java/ovh/glitchlabs/masterwild/event/ModEventBusEvents.java index 473f02f..914f144 100644 --- a/src/main/java/ovh/glitchlabs/masterwild/event/ModEventBusEvents.java +++ b/src/main/java/ovh/glitchlabs/masterwild/event/ModEventBusEvents.java @@ -1,22 +1,17 @@ package ovh.glitchlabs.masterwild.event; -import net.minecraft.world.entity.SpawnPlacementType; -import net.minecraft.world.entity.SpawnPlacementTypes; -import net.minecraft.world.entity.animal.Animal; -import net.minecraft.world.level.levelgen.Heightmap; import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.neoforge.client.event.EntityRenderersEvent; import net.neoforged.neoforge.event.entity.EntityAttributeCreationEvent; -import net.neoforged.neoforge.event.entity.RegisterSpawnPlacementsEvent; import ovh.glitchlabs.masterwild.Masterwild; import ovh.glitchlabs.masterwild.entity.ModEntities; -import ovh.glitchlabs.masterwild.entity.client.Monkey.MonkeyModel; import ovh.glitchlabs.masterwild.entity.client.Pinguin.PinguinModel; import ovh.glitchlabs.masterwild.entity.client.Raccoon.RaccoonModel; import ovh.glitchlabs.masterwild.entity.client.Rooster.RoosterModel; import ovh.glitchlabs.masterwild.entity.client.Shark.SharkModel; import ovh.glitchlabs.masterwild.entity.client.butterfly.ButterflyModel; +import ovh.glitchlabs.masterwild.entity.client.capibara.CapybaraModel; import ovh.glitchlabs.masterwild.entity.client.firefly.FireflyModel; import ovh.glitchlabs.masterwild.entity.client.hedgehog.HedgehogModel; import ovh.glitchlabs.masterwild.entity.client.red_panda.Red_PandaModel; @@ -34,7 +29,7 @@ public class ModEventBusEvents { event.registerLayerDefinition(Red_PandaModel.LAYER_LOCATION, Red_PandaModel::createBodyLayer); event.registerLayerDefinition(ButterflyModel.LAYER_LOCATION, ButterflyModel::createBodyLayer); event.registerLayerDefinition(RaccoonModel.LAYER_LOCATION, RaccoonModel::createBodyLayer); - event.registerLayerDefinition(MonkeyModel.LAYER_LOCATION, MonkeyModel::createBodyLayer); + event.registerLayerDefinition(CapybaraModel.LAYER_LOCATION, RaccoonModel::createBodyLayer); } @SubscribeEvent @@ -46,6 +41,6 @@ public class ModEventBusEvents { event.put(ModEntities.HEDGEHOG.get(), HedgehogEntity.createAttributes().build()); event.put(ModEntities.RED_PANDA.get(), Red_PandaEntity.createAttributes().build()); event.put(ModEntities.RACCOON.get(), RaccoonEntity.createAttributes().build()); - event.put(ModEntities.MONKEY.get(), MonkeyEntity.createAttributes().build()); + event.put(ModEntities.CAPYBARA.get(), CapybaraEntity.createAttributes().build()); } }