diff --git a/src/main/java/net/voltexstudios/VoltexDesertUpdate.java b/src/main/java/net/voltexstudios/VoltexDesertUpdate.java index 9c81c84..d0dc7de 100644 --- a/src/main/java/net/voltexstudios/VoltexDesertUpdate.java +++ b/src/main/java/net/voltexstudios/VoltexDesertUpdate.java @@ -2,7 +2,9 @@ package net.voltexstudios; import net.fabricmc.api.ModInitializer; +import net.fabricmc.fabric.api.object.builder.v1.entity.FabricDefaultAttributeRegistry; import net.voltexstudios.entity.ModEntities; +import net.voltexstudios.entity.custom.VultureEntity; import net.voltexstudios.item.ModItems; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -20,5 +22,7 @@ public class VoltexDesertUpdate implements ModInitializer { ModItems.registerModItems(); ModEntities.registerModEntities(); + + FabricDefaultAttributeRegistry.register(ModEntities.VULTURE_ENTITY, VultureEntity.createAttributes()); } } \ No newline at end of file diff --git a/src/main/java/net/voltexstudios/VoltexDesertUpdateClient.java b/src/main/java/net/voltexstudios/VoltexDesertUpdateClient.java index 0063d81..c4d05d0 100644 --- a/src/main/java/net/voltexstudios/VoltexDesertUpdateClient.java +++ b/src/main/java/net/voltexstudios/VoltexDesertUpdateClient.java @@ -1,7 +1,11 @@ package net.voltexstudios; import net.fabricmc.api.ClientModInitializer; - +import net.fabricmc.fabric.api.client.rendering.v1.EntityModelLayerRegistry; +import net.fabricmc.fabric.api.client.rendering.v1.EntityRendererRegistry; +import net.voltexstudios.entity.ModEntities; +import net.voltexstudios.entity.client.VultureModel; +import net.voltexstudios.entity.client.VultureRenderer; public class VoltexDesertUpdateClient implements ClientModInitializer { @@ -9,6 +13,7 @@ public class VoltexDesertUpdateClient implements ClientModInitializer { public void onInitializeClient() { VoltexDesertUpdate.LOGGER.info("Initializing Desert Update Client"); - + EntityModelLayerRegistry.registerModelLayer(VultureModel.VULTURE, VultureModel::getTexturedModelData); + EntityRendererRegistry.register(ModEntities.VULTURE_ENTITY, VultureRenderer::new); } } diff --git a/src/main/java/net/voltexstudios/entity/ModEntities.java b/src/main/java/net/voltexstudios/entity/ModEntities.java index d20f289..20ce049 100644 --- a/src/main/java/net/voltexstudios/entity/ModEntities.java +++ b/src/main/java/net/voltexstudios/entity/ModEntities.java @@ -7,9 +7,16 @@ import net.minecraft.registry.Registry; import net.minecraft.util.Identifier; import net.voltexstudios.VoltexDesertUpdate; import net.voltexstudios.entity.custom.DuneProjectileEntity; +import net.voltexstudios.entity.custom.VultureEntity; public class ModEntities { + //TODO alter dimensions + public static final EntityType<VultureEntity> VULTURE_ENTITY = Registry.register(Registries.ENTITY_TYPE, + Identifier.of(VoltexDesertUpdate.MOD_ID, "vulture_entity"), + EntityType.Builder.create(VultureEntity::new, SpawnGroup.CREATURE) + .dimensions(0.75f, 1f).build()); + public static final EntityType<DuneProjectileEntity> DUNE_PROJECTILE_ENTITY = Registry.register(Registries.ENTITY_TYPE, Identifier.of(VoltexDesertUpdate.MOD_ID, "dune_projectile_entity"), EntityType.Builder.<DuneProjectileEntity>create(DuneProjectileEntity::new, SpawnGroup.MISC) diff --git a/src/main/java/net/voltexstudios/entity/client/VultureAnimations.java b/src/main/java/net/voltexstudios/entity/client/VultureAnimations.java new file mode 100644 index 0000000..f95461d --- /dev/null +++ b/src/main/java/net/voltexstudios/entity/client/VultureAnimations.java @@ -0,0 +1,51 @@ +package net.voltexstudios.entity.client; + +import net.minecraft.client.render.entity.animation.Animation; +import net.minecraft.client.render.entity.animation.AnimationHelper; +import net.minecraft.client.render.entity.animation.Keyframe; +import net.minecraft.client.render.entity.animation.Transformation; + +public class VultureAnimations { + public static final Animation ANIM_VULTURE_FLYING = Animation.Builder.create(0f) + .addBoneAnimation("mambo", + new Transformation(Transformation.Targets.ROTATE, + new Keyframe(0f, AnimationHelper.createRotationalVector(45f, 0f, 0f), + Transformation.Interpolations.LINEAR))) + .addBoneAnimation("head", + new Transformation(Transformation.Targets.ROTATE, + new Keyframe(0f, AnimationHelper.createRotationalVector(-45f, 0f, 0f), + Transformation.Interpolations.LINEAR))) + .addBoneAnimation("leftWing", + new Transformation(Transformation.Targets.TRANSLATE, + new Keyframe(0f, AnimationHelper.createTranslationalVector(0f, 2f, 2f), + Transformation.Interpolations.LINEAR))) + .addBoneAnimation("leftWing", + new Transformation(Transformation.Targets.ROTATE, + new Keyframe(0f, AnimationHelper.createRotationalVector(90f, 45f, 90f), + Transformation.Interpolations.LINEAR))) + .addBoneAnimation("rightWing", + new Transformation(Transformation.Targets.TRANSLATE, + new Keyframe(0f, AnimationHelper.createTranslationalVector(0f, 2f, 2f), + Transformation.Interpolations.LINEAR))) + .addBoneAnimation("rightWing", + new Transformation(Transformation.Targets.ROTATE, + new Keyframe(0f, AnimationHelper.createRotationalVector(90f, -45f, -90f), + Transformation.Interpolations.LINEAR))) + .addBoneAnimation("leftLeg", + new Transformation(Transformation.Targets.TRANSLATE, + new Keyframe(0f, AnimationHelper.createTranslationalVector(-0.25f, 0f, 0f), + Transformation.Interpolations.LINEAR))) + .addBoneAnimation("leftLeg", + new Transformation(Transformation.Targets.ROTATE, + new Keyframe(0f, AnimationHelper.createRotationalVector(45f, 0f, 0f), + Transformation.Interpolations.LINEAR))) + .addBoneAnimation("rightLeg", + new Transformation(Transformation.Targets.TRANSLATE, + new Keyframe(0f, AnimationHelper.createTranslationalVector(0.25f, 0f, 0f), + Transformation.Interpolations.LINEAR))) + .addBoneAnimation("rightLeg", + new Transformation(Transformation.Targets.ROTATE, + new Keyframe(0f, AnimationHelper.createRotationalVector(45f, 0f, 0f), + Transformation.Interpolations.LINEAR))).build(); + +} diff --git a/src/main/java/net/voltexstudios/entity/client/VultureModel.java b/src/main/java/net/voltexstudios/entity/client/VultureModel.java new file mode 100644 index 0000000..4264341 --- /dev/null +++ b/src/main/java/net/voltexstudios/entity/client/VultureModel.java @@ -0,0 +1,83 @@ +package net.voltexstudios.entity.client; + +import net.minecraft.client.model.*; +import net.minecraft.client.render.VertexConsumer; +import net.minecraft.client.render.entity.model.EntityModelLayer; +import net.minecraft.client.render.entity.model.SinglePartEntityModel; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.MathHelper; +import net.voltexstudios.VoltexDesertUpdate; +import net.voltexstudios.entity.custom.VultureEntity; + +public class VultureModel<T extends VultureEntity> extends SinglePartEntityModel<T> { + + public static final EntityModelLayer VULTURE = new EntityModelLayer(Identifier.of(VoltexDesertUpdate.MOD_ID, "vulture"), "main"); + + private final ModelPart vulture; + private final ModelPart head; + private final ModelPart body; + + public VultureModel(ModelPart root) { + this.vulture = root.getChild("mambo"); + this.body = vulture.getChild("body"); + this.head = vulture.getChild("head"); + } + + public static TexturedModelData getTexturedModelData() { + ModelData modelData = new ModelData(); + ModelPartData modelPartData = modelData.getRoot(); + ModelPartData mambo = modelPartData.addChild("mambo", ModelPartBuilder.create(), ModelTransform.pivot(0.0F, 15.0F, 1.0F)); + + ModelPartData head = mambo.addChild("head", ModelPartBuilder.create().uv(26, 8).cuboid(-2.0F, -1.0F, -4.0F, 2.0F, 2.0F, 5.0F, new Dilation(0.0F)) + .uv(38, 38).cuboid(-2.0F, -3.0F, -4.0F, 2.0F, 2.0F, 2.0F, new Dilation(0.0F)) + .uv(0, 35).cuboid(-2.5F, -6.0F, -5.0F, 3.0F, 3.0F, 3.0F, new Dilation(0.0F)) + .uv(12, 38).cuboid(-2.0F, -6.0F, -8.0F, 2.0F, 3.0F, 3.0F, new Dilation(0.0F)) + .uv(26, 15).cuboid(-2.0F, -3.0F, -8.0F, 2.0F, 1.0F, 0.0F, new Dilation(0.0F)), ModelTransform.pivot(1.0F, -4.0F, -3.0F)); + + ModelPartData body = mambo.addChild("body", ModelPartBuilder.create().uv(0, 0).cuboid(-3.0F, -5.0F, -3.0F, 6.0F, 10.0F, 7.0F, new Dilation(0.0F)), ModelTransform.of(0.0F, 1.0F, 0.0F, 0.7854F, 0.0F, 0.0F)); + + ModelPartData tail = body.addChild("tail", ModelPartBuilder.create().uv(26, 0).cuboid(-3.0F, 0.0F, -4.0F, 6.0F, 4.0F, 4.0F, new Dilation(0.0F)), ModelTransform.pivot(0.0F, 5.0F, 4.0F)); + + ModelPartData leftWing = mambo.addChild("leftWing", ModelPartBuilder.create().uv(0, 17).cuboid(-0.5F, -1.5F, -1.0F, 1.0F, 7.0F, 11.0F, new Dilation(0.0F)), ModelTransform.pivot(3.5F, -1.5F, -3.0F)); + + ModelPartData rightWing = mambo.addChild("rightWing", ModelPartBuilder.create().uv(24, 17).cuboid(-0.5F, -1.5F, -1.0F, 1.0F, 7.0F, 11.0F, new Dilation(0.0F)), ModelTransform.pivot(-3.5F, -1.5F, -3.0F)); + + ModelPartData leftLeg = mambo.addChild("leftLeg", ModelPartBuilder.create().uv(22, 38).cuboid(-1.0F, -0.1667F, -1.0F, 2.0F, 5.0F, 2.0F, new Dilation(0.0F)) + .uv(26, 16).cuboid(-0.5F, 4.8333F, 1.0F, 1.0F, 0.0F, 1.0F, new Dilation(0.0F)) + .uv(12, 35).cuboid(-2.0F, 4.8333F, -3.0F, 4.0F, 0.0F, 3.0F, new Dilation(0.0F)), ModelTransform.pivot(2.0F, 4.1667F, -1.0F)); + + ModelPartData rightLeg = mambo.addChild("rightLeg", ModelPartBuilder.create().uv(30, 38).cuboid(-1.0F, -0.1667F, -1.0F, 2.0F, 5.0F, 2.0F, new Dilation(0.0F)) + .uv(30, 15).cuboid(-0.5F, 4.8333F, 1.0F, 1.0F, 0.0F, 1.0F, new Dilation(0.0F)) + .uv(26, 35).cuboid(-2.0F, 4.8333F, -3.0F, 4.0F, 0.0F, 3.0F, new Dilation(0.0F)), ModelTransform.pivot(-2.0F, 4.1667F, -1.0F)); + return TexturedModelData.of(modelData, 64, 64); + } + @Override + public void setAngles(VultureEntity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch) { + this.getPart().traverse().forEach(ModelPart::resetTransform); + this.setHeadAngles(netHeadYaw, headPitch); + + //TODO add Animation + //this.animateMovement(VultureAnimations.ANIM_VULTURE_WALK, limbSwing, limbSwingAmount, 2f, 2.5f); + //this.updateAnimation(entity.idleAnimationState, VultureAnimations.ANIM_MANTIS_IDLE, ageInTicks, 1f); + } + + private void setHeadAngles(float headYaw, float headPitch) { + headYaw = MathHelper.clamp(headYaw, -30.0F, 30.0F); + headPitch = MathHelper.clamp(headPitch, -25.0F, 45.0F); + + this.head.yaw = headYaw * 0.017453292F; + this.head.pitch = headPitch * 0.017453292F; + } + + + @Override + public void render(MatrixStack matrices, VertexConsumer vertexConsumer, int light, int overlay, int color) { + vulture.render(matrices, vertexConsumer, light, overlay, color); + } + + @Override + public ModelPart getPart() { + return vulture; + } +} diff --git a/src/main/java/net/voltexstudios/entity/client/VultureRenderer.java b/src/main/java/net/voltexstudios/entity/client/VultureRenderer.java new file mode 100644 index 0000000..acb7438 --- /dev/null +++ b/src/main/java/net/voltexstudios/entity/client/VultureRenderer.java @@ -0,0 +1,32 @@ +package net.voltexstudios.entity.client; + +import net.minecraft.client.render.VertexConsumerProvider; +import net.minecraft.client.render.entity.EntityRendererFactory; +import net.minecraft.client.render.entity.MobEntityRenderer; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.util.Identifier; +import net.voltexstudios.VoltexDesertUpdate; +import net.voltexstudios.entity.custom.VultureEntity; + +public class VultureRenderer extends MobEntityRenderer<VultureEntity, VultureModel<VultureEntity>> { + + public VultureRenderer(EntityRendererFactory.Context context) { + super(context, new VultureModel<>(context.getPart(VultureModel.VULTURE)), 0.5f); + } + + @Override + public Identifier getTexture(VultureEntity entity) { + return Identifier.of(VoltexDesertUpdate.MOD_ID, "textures/entity/vulture/vulture.png"); + } + + @Override + public void render(VultureEntity livingEntity, float f, float g, MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int i) { + if(livingEntity.isBaby()) { + matrixStack.scale(0.5f, 0.5f, 0.5f); + } else { + matrixStack.scale(1f, 1f, 1f); + } + + super.render(livingEntity, f, g, matrixStack, vertexConsumerProvider, i); + } +} diff --git a/src/main/java/net/voltexstudios/entity/custom/VultureEntity.java b/src/main/java/net/voltexstudios/entity/custom/VultureEntity.java new file mode 100644 index 0000000..4f9e2b4 --- /dev/null +++ b/src/main/java/net/voltexstudios/entity/custom/VultureEntity.java @@ -0,0 +1,74 @@ +package net.voltexstudios.entity.custom; + +import net.minecraft.entity.AnimationState; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.ai.goal.LookAroundGoal; +import net.minecraft.entity.ai.goal.LookAtEntityGoal; +import net.minecraft.entity.ai.goal.WanderAroundGoal; +import net.minecraft.entity.attribute.DefaultAttributeContainer; +import net.minecraft.entity.attribute.EntityAttributes; +import net.minecraft.entity.mob.MobEntity; +import net.minecraft.entity.passive.AnimalEntity; +import net.minecraft.entity.passive.PassiveEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.world.World; +import net.voltexstudios.entity.ModEntities; +import org.jetbrains.annotations.Nullable; + +public class VultureEntity extends AnimalEntity { + + public final AnimationState idleAnimationState = new AnimationState(); + private int idleAnimationTimeout; + + public VultureEntity(EntityType<? extends AnimalEntity> entityType, World world) { + super(entityType, world); + } + + @Override + protected void initGoals() { + this.goalSelector.add(0, new WanderAroundGoal(this, 1.0)); + this.goalSelector.add(1, new LookAtEntityGoal(this, PlayerEntity.class, 6.0F)); + this.goalSelector.add(2, new LookAroundGoal(this)); + } + + private void setupAnimationStates() { + if (this.idleAnimationTimeout <= 0) { + this.idleAnimationTimeout = 40; + this.idleAnimationState.start(this.age); + } else { + --this.idleAnimationTimeout; + } + } + + @Override + public void tick() { + super.tick(); + + if (this.getWorld().isClient()) { + this.setupAnimationStates(); + } + } + + //TODO alter attributes + public static DefaultAttributeContainer.Builder createAttributes() { + return MobEntity.createMobAttributes() + .add(EntityAttributes.GENERIC_MAX_HEALTH, 10.0) + .add(EntityAttributes.GENERIC_FLYING_SPEED, 1.5F) + .add(EntityAttributes.GENERIC_MOVEMENT_SPEED, 0.6F) + .add(EntityAttributes.GENERIC_ATTACK_DAMAGE, 10.0) + .add(EntityAttributes.GENERIC_FOLLOW_RANGE, 48.0); + } + + @Override + public boolean isBreedingItem(ItemStack stack) { + return false; + } + + @Nullable + @Override + public PassiveEntity createChild(ServerWorld world, PassiveEntity entity) { + return ModEntities.VULTURE_ENTITY.create(world); + } +} diff --git a/src/main/resources/assets/voltexdesertupdate/lang/en_us.json b/src/main/resources/assets/voltexdesertupdate/lang/en_us.json index a9a1e3c..8caf65a 100644 --- a/src/main/resources/assets/voltexdesertupdate/lang/en_us.json +++ b/src/main/resources/assets/voltexdesertupdate/lang/en_us.json @@ -1,3 +1,5 @@ { - "item.voltexdesertupdate.dune_staff": "Staff of the Dunes" + "item.voltexdesertupdate.dune_staff": "Staff of the Dunes", + + "entity.voltexdesertupdate.vulture": "Vulture" } \ No newline at end of file diff --git a/src/main/resources/assets/voltexdesertupdate/textures/entity/vulture/vulture.png b/src/main/resources/assets/voltexdesertupdate/textures/entity/vulture/vulture.png new file mode 100644 index 0000000..61c450a Binary files /dev/null and b/src/main/resources/assets/voltexdesertupdate/textures/entity/vulture/vulture.png differ