From d9d56c634c15690605652901da5b71cbf7fe1378 Mon Sep 17 00:00:00 2001 From: Sollace Date: Sun, 27 Mar 2022 17:47:52 +0200 Subject: [PATCH] Pigs love muffins --- .../unicopia/client/render/AnimalPoser.java | 36 ++++++++ .../unicopia/entity/Creature.java | 44 ++++++++++ .../unicopia/entity/ai/BreakHeartGoal.java | 2 +- .../unicopia/entity/ai/EatMuffinGoal.java | 83 +++++++++++++++++++ .../unicopia/item/ProjectileItem.java | 6 +- .../mixin/client/MixinAnimalModel.java | 12 +++ .../client/MixinLivingEntityRenderer.java | 5 ++ src/main/resources/unicopia.mixin.json | 1 + 8 files changed, 183 insertions(+), 6 deletions(-) create mode 100644 src/main/java/com/minelittlepony/unicopia/client/render/AnimalPoser.java create mode 100644 src/main/java/com/minelittlepony/unicopia/entity/ai/EatMuffinGoal.java create mode 100644 src/main/java/com/minelittlepony/unicopia/mixin/client/MixinAnimalModel.java diff --git a/src/main/java/com/minelittlepony/unicopia/client/render/AnimalPoser.java b/src/main/java/com/minelittlepony/unicopia/client/render/AnimalPoser.java new file mode 100644 index 00000000..5fc00c9f --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/client/render/AnimalPoser.java @@ -0,0 +1,36 @@ +package com.minelittlepony.unicopia.client.render; + +import com.minelittlepony.unicopia.entity.Creature; +import com.minelittlepony.unicopia.entity.Equine; +import com.minelittlepony.unicopia.mixin.client.MixinAnimalModel; + +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.render.entity.model.EntityModel; +import net.minecraft.client.render.entity.model.QuadrupedEntityModel; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.mob.MobEntity; +import net.minecraft.entity.passive.PigEntity; + +public class AnimalPoser { + public static final AnimalPoser INSTANCE = new AnimalPoser(); + + public void applyPosing(MatrixStack matrices, MobEntity entity, EntityModel model) { + + if (entity instanceof PigEntity && model instanceof QuadrupedEntityModel quad) { + Equine.of((LivingEntity)entity) + .filter(eq -> eq instanceof Creature) + .map(Creature.class::cast) + .ifPresent(creature -> { + float tickDelta = MinecraftClient.getInstance().getTickDelta(); + float headAngle = creature.getHeadAngle(tickDelta); + float neckAngle = 12; + + ((MixinAnimalModel)quad).invokeGetHeadParts().forEach(part -> { + part.pivotY = neckAngle; + part.pitch = headAngle; + }); + }); + } + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/entity/Creature.java b/src/main/java/com/minelittlepony/unicopia/entity/Creature.java index 8a159ebd..ad72e539 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/Creature.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/Creature.java @@ -15,6 +15,7 @@ import com.minelittlepony.unicopia.ability.magic.spell.Spell; import com.minelittlepony.unicopia.ability.magic.spell.effect.TargetSelecter; import com.minelittlepony.unicopia.entity.ai.BreakHeartGoal; import com.minelittlepony.unicopia.entity.ai.DynamicTargetGoal; +import com.minelittlepony.unicopia.entity.ai.EatMuffinGoal; import com.minelittlepony.unicopia.entity.ai.WantItTakeItGoal; import com.minelittlepony.unicopia.entity.player.PlayerAttributes; @@ -32,15 +33,18 @@ import net.minecraft.entity.data.TrackedDataHandlerRegistry; import net.minecraft.entity.mob.HostileEntity; import net.minecraft.entity.mob.MobEntity; import net.minecraft.entity.mob.SlimeEntity; +import net.minecraft.entity.passive.PigEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtElement; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; public class Creature extends Living implements WeaklyOwned { private static final TrackedData EFFECT = DataTracker.registerData(LivingEntity.class, TrackedDataHandlerRegistry.NBT_COMPOUND); private static final TrackedData MASTER = DataTracker.registerData(LivingEntity.class, TrackedDataHandlerRegistry.NBT_COMPOUND); public static final TrackedData GRAVITY = DataTracker.registerData(LivingEntity.class, TrackedDataHandlerRegistry.FLOAT); + private static final TrackedData EATING = DataTracker.registerData(LivingEntity.class, TrackedDataHandlerRegistry.INTEGER); private static final LevelStore LEVELS = Levelled.fixed(0); @@ -55,10 +59,15 @@ public class Creature extends Living implements WeaklyOwned(entity, GRAVITY); entity.getDataTracker().startTracking(MASTER, master.toNBT()); + entity.getDataTracker().startTracking(EATING, 0); } @Override @@ -115,6 +124,10 @@ public class Creature extends Living implements WeaklyOwned implements WeaklyOwned= 4 && eatTimer <= 36) { + return 1; + } + if (eatTimer < 4) { + return (eatTimer - delta) / 4F; + } + return -(eatTimer - 40 - delta) / 4F; + } + + public float getHeadAngle(float delta) { + if (eatTimer > 4 && eatTimer <= 36) { + float f = (eatTimer - 4 - delta) / 32F; + return 0.62831855f + 0.21991149f * MathHelper.sin(f * 28.7F); + } + if (eatTimer > 0) { + return 0.62831855f; + } + return entity.getPitch() * ((float)Math.PI / 180); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/entity/ai/BreakHeartGoal.java b/src/main/java/com/minelittlepony/unicopia/entity/ai/BreakHeartGoal.java index fcd6be3d..4bd81fdc 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/ai/BreakHeartGoal.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/ai/BreakHeartGoal.java @@ -22,7 +22,7 @@ public class BreakHeartGoal extends Goal { public BreakHeartGoal(MobEntity mob, DynamicTargetGoal targetter) { this.mob = mob; this.targetter = targetter; - this.setControls(EnumSet.of(Goal.Control.MOVE, Goal.Control.LOOK)); + this.setControls(EnumSet.of(Goal.Control.MOVE, Goal.Control.LOOK, Goal.Control.JUMP)); target = targetter.addPredicate(this::canTarget); } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/ai/EatMuffinGoal.java b/src/main/java/com/minelittlepony/unicopia/entity/ai/EatMuffinGoal.java new file mode 100644 index 00000000..5f9880c0 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/entity/ai/EatMuffinGoal.java @@ -0,0 +1,83 @@ +package com.minelittlepony.unicopia.entity.ai; + +import com.minelittlepony.unicopia.entity.PhysicsBodyProjectileEntity; +import com.minelittlepony.unicopia.item.UItems; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.mob.MobEntity; +import net.minecraft.entity.passive.AnimalEntity; +import net.minecraft.entity.player.PlayerEntity; + +public class EatMuffinGoal extends BreakHeartGoal { + + private int timer; + + private boolean eatingStarted; + + public EatMuffinGoal(MobEntity mob, DynamicTargetGoal targetter) { + super(mob, targetter); + } + + public int getTimer() { + return eatingStarted ? timer : 0; + } + + @Override + public void start() { + eatingStarted = false; + timer = getTickCount(10); + mob.getNavigation().stop(); + } + + @Override + public void stop() { + super.stop(); + eatingStarted = false; + timer = 0; + } + + @Override + public boolean shouldContinue() { + return timer > 0 && super.shouldContinue(); + } + + @Override + protected boolean canTarget(Entity e) { + return !e.isRemoved() + && e instanceof PhysicsBodyProjectileEntity + && ((PhysicsBodyProjectileEntity)e).getStack().getItem() == UItems.MUFFIN + && mob.getVisibilityCache().canSee(e); + } + + @Override + protected void attackTarget(Entity target, double reach, double distance) { + double speed = 1D; + + if (distance > 5) { + speed += 0.5; + } + if (distance < 2) { + speed += 0.1D; + } + + mob.getNavigation().startMovingTo(target, speed); + + if (distance <= reach + 0.5) { + eatingStarted = true; + + if (target instanceof PhysicsBodyProjectileEntity projectile) { + mob.eatFood(mob.world, projectile.getStack()); + projectile.discard(); + + if (mob instanceof AnimalEntity animal) { + if (mob.world.random.nextInt(12) == 0) { + Entity player = ((PhysicsBodyProjectileEntity) target).getOwner(); + + animal.lovePlayer(player instanceof PlayerEntity ? (PlayerEntity)player : null); + animal.setLoveTicks(1000); + } + } + } + } + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/item/ProjectileItem.java b/src/main/java/com/minelittlepony/unicopia/item/ProjectileItem.java index 01e11646..2c5a913d 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/ProjectileItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/ProjectileItem.java @@ -29,11 +29,7 @@ abstract class ProjectileItem extends Item implements ProjectileDelegate use(World world, PlayerEntity player, Hand hand) { if (isFood() && !player.isSneaking()) { - TypedActionResult eaten = super.use(world, player, hand); - - if (eaten.getResult().isAccepted()) { - return eaten; - } + return super.use(world, player, hand); } ItemStack stack = player.getStackInHand(hand); diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinAnimalModel.java b/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinAnimalModel.java new file mode 100644 index 00000000..75f188aa --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinAnimalModel.java @@ -0,0 +1,12 @@ +package com.minelittlepony.unicopia.mixin.client; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; +import net.minecraft.client.model.ModelPart; +import net.minecraft.client.render.entity.model.AnimalModel; + +@Mixin(AnimalModel.class) +public interface MixinAnimalModel { + @Invoker("getHeadParts") + Iterable invokeGetHeadParts(); +} diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinLivingEntityRenderer.java b/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinLivingEntityRenderer.java index 49cf2102..c3809fcf 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinLivingEntityRenderer.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinLivingEntityRenderer.java @@ -6,6 +6,7 @@ import org.spongepowered.asm.mixin.injection.At.Shift; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import com.minelittlepony.unicopia.client.render.AnimalPoser; import com.minelittlepony.unicopia.client.render.PlayerPoser; import net.minecraft.client.render.VertexConsumerProvider; @@ -16,6 +17,7 @@ import net.minecraft.client.render.entity.model.BipedEntityModel; import net.minecraft.client.render.entity.model.EntityModel; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.mob.MobEntity; import net.minecraft.entity.player.PlayerEntity; @Mixin(LivingEntityRenderer.class) @@ -37,5 +39,8 @@ abstract class MixinLivingEntityRenderer)getModel()); } + if (entity instanceof MobEntity mob) { + AnimalPoser.INSTANCE.applyPosing(matrices, mob, getModel()); + } } } diff --git a/src/main/resources/unicopia.mixin.json b/src/main/resources/unicopia.mixin.json index d7b89ee6..3b2490fc 100644 --- a/src/main/resources/unicopia.mixin.json +++ b/src/main/resources/unicopia.mixin.json @@ -32,6 +32,7 @@ "MixinWorldChunk" ], "client": [ + "client.MixinAnimalModel", "client.MixinArmorFeatureRenderer", "client.MixinCamera", "client.MixinClientPlayerInteractionManager",