diff --git a/src/main/java/com/minelittlepony/unicopia/ability/ChangelingDisguiseAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/ChangelingDisguiseAbility.java index d2413203..8016e272 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/ChangelingDisguiseAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/ChangelingDisguiseAbility.java @@ -70,6 +70,7 @@ public class ChangelingDisguiseAbility extends ChangelingFeedAbility { iplayer.setSpell(disc); return disc; }).setDisguise(looked); + player.calculateDimensions(); iplayer.setDirty(); } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/DisguiseSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/DisguiseSpell.java index 1cde6c5f..d0eacf15 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/DisguiseSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/DisguiseSpell.java @@ -7,7 +7,6 @@ import javax.annotation.Nullable; import com.minelittlepony.unicopia.Affinity; import com.minelittlepony.unicopia.InteractionManager; import com.minelittlepony.unicopia.Owned; -import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.ability.FlightPredicate; import com.minelittlepony.unicopia.ability.HeightPredicate; import com.minelittlepony.unicopia.ability.magic.AttachableSpell; @@ -25,7 +24,6 @@ import com.mojang.authlib.GameProfile; import net.minecraft.block.entity.SkullBlockEntity; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; -import net.minecraft.entity.EquipmentSlot; import net.minecraft.entity.FallingBlockEntity; import net.minecraft.entity.Flutterer; import net.minecraft.entity.LivingEntity; @@ -37,11 +35,9 @@ import net.minecraft.entity.mob.FlyingEntity; import net.minecraft.entity.mob.MobEntity; import net.minecraft.entity.mob.ShulkerEntity; import net.minecraft.entity.mob.VexEntity; -import net.minecraft.entity.passive.TameableEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.projectile.ProjectileEntity; import net.minecraft.entity.projectile.ShulkerBulletEntity; -import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundTag; public class DisguiseSpell extends AbstractSpell implements AttachableSpell, Suppressable, FlightPredicate, HeightPredicate { @@ -157,7 +153,6 @@ public class DisguiseSpell extends AbstractSpell implements AttachableSpell, Sup onEntityLoaded(source); } - @SuppressWarnings("unchecked") protected void checkAndCreateDisguiseEntity(Caster source) { if (entity == null && entityNbt != null) { CompoundTag nbt = entityNbt; @@ -175,14 +170,12 @@ public class DisguiseSpell extends AbstractSpell implements AttachableSpell, Sup } else { if (source.isClient()) { entity = EntityType.fromTag(nbt).map(type -> type.create(source.getWorld())).orElse(null); - EntityBehaviour.forEntity(entity).ifPresent(behaviour -> { - ((EntityBehaviour)behaviour).onCreate(entity); - }); + if (entity != null) { + EntityBehaviour.forEntity(entity).onCreate(entity); + } } else { entity = EntityType.loadEntityWithPassengers(nbt, source.getWorld(), e -> { - EntityBehaviour.forEntity(e).ifPresent(behaviour -> { - ((EntityBehaviour)behaviour).onCreate(e); - }); + EntityBehaviour.forEntity(e).onCreate(e); return e; }); @@ -212,122 +205,6 @@ public class DisguiseSpell extends AbstractSpell implements AttachableSpell, Sup return getDisguise() == projectile; } - protected void copyBaseAttributes(LivingEntity from, Entity to) { - - // Set first because position calculations rely on it - to.age = from.age; - to.removed = from.removed; - to.setOnGround(from.isOnGround()); - - if (isAttachedEntity(entity)) { - - double x = Math.floor(from.getX()) + 0.5; - double y = Math.floor(from.getY()); - double z = Math.floor(from.getZ()) + 0.5; - - to.prevX = x; - to.prevY = y; - to.prevZ = z; - - to.lastRenderX = x; - to.lastRenderY = y; - to.lastRenderZ = z; - - to.updatePosition(x, y, z); - - if (entity instanceof FallingBlockEntity) { - ((FallingBlockEntity)entity).setFallingBlockPos(from.getBlockPos()); - } - } else { - to.copyPositionAndRotation(from); - - to.prevX = from.prevX; - to.prevY = from.prevY; - to.prevZ = from.prevZ; - - to.chunkX = from.chunkX; - to.chunkY = from.chunkY; - to.chunkZ = from.chunkZ; - - to.lastRenderX = from.lastRenderX; - to.lastRenderY = from.lastRenderY; - to.lastRenderZ = from.lastRenderZ; - } - - if (to instanceof PlayerEntity) { - PlayerEntity l = (PlayerEntity)to; - - l.capeX = l.getX(); - l.capeY = l.getY(); - l.capeZ = l.getZ(); - } - - to.setVelocity(from.getVelocity()); - - to.pitch = from.pitch; - to.prevPitch = from.prevPitch; - to.yaw = from.yaw; - to.prevYaw = from.prevYaw; - to.horizontalSpeed = from.horizontalSpeed; - to.prevHorizontalSpeed = from.prevHorizontalSpeed; - - to.distanceTraveled = from.distanceTraveled; - - if (to instanceof LivingEntity) { - LivingEntity l = (LivingEntity)to; - - l.headYaw = from.headYaw; - l.prevHeadYaw = from.prevHeadYaw; - l.bodyYaw = from.bodyYaw; - l.prevBodyYaw = from.prevBodyYaw; - - l.limbDistance = from.limbDistance; - l.limbAngle = from.limbAngle; - l.lastLimbDistance = from.lastLimbDistance; - - l.handSwingProgress = from.handSwingProgress; - l.lastHandSwingProgress = from.lastHandSwingProgress; - l.handSwingTicks = from.handSwingTicks; - l.handSwinging = from.handSwinging; - - l.hurtTime = from.hurtTime; - l.deathTime = from.deathTime; - l.stuckStingerTimer = from.stuckStingerTimer; - l.stuckArrowTimer = from.stuckArrowTimer; - l.setHealth(from.getHealth()); - - for (EquipmentSlot i : EquipmentSlot.values()) { - ItemStack neu = from.getEquippedStack(i); - ItemStack old = l.getEquippedStack(i); - if (old != neu) { - l.equipStack(i, neu); - } - } - } - - /*if (to instanceof RangedAttackMob) { - ItemStack activeItem = from.getActiveItem(); - - ((RangedAttackMob)to).setSwingingArms(!activeItem.isEmpty() && activeItem.getUseAction() == UseAction.BOW); - }*/ - - if (to instanceof TameableEntity) { - ((TameableEntity)to).setSitting(from.isSneaking()); - } - - if (from.age < 100 || from instanceof PlayerEntity && ((PlayerEntity)from).isCreative()) { - to.extinguish(); - } - - if (to.isOnFire()) { - from.setOnFireFor(1); - } else { - from.extinguish(); - } - - to.setSneaking(from.isSneaking()); - } - @Override public boolean updateOnPerson(Caster caster) { return update(caster); @@ -370,6 +247,7 @@ public class DisguiseSpell extends AbstractSpell implements AttachableSpell, Sup ((Pony) source).setInvisible(false); } + owner.calculateDimensions(); return false; } @@ -382,15 +260,15 @@ public class DisguiseSpell extends AbstractSpell implements AttachableSpell, Sup entity.setInvisible(false); entity.setNoGravity(true); - copyBaseAttributes(owner, entity); + EntityBehaviour behaviour = EntityBehaviour.forEntity(entity); + + behaviour.copyBaseAttributes(owner, entity); if (tick && !skipsUpdate(entity)) { entity.tick(); } - EntityBehaviour.forEntity(entity).ifPresent(b -> { - ((EntityBehaviour)b).update(source, entity); - }); + behaviour.update(source, entity); if (source instanceof Pony) { Pony player = (Pony)source; @@ -410,11 +288,9 @@ public class DisguiseSpell extends AbstractSpell implements AttachableSpell, Sup entity.setInvisible(true); entity.setPos(entity.getX(), Integer.MIN_VALUE, entity.getY()); } - - return player.getSpecies() == Race.CHANGELING; } - return !source.getOwner().removed; + return !source.getOwner().isDead(); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/ChickenBehaviour.java b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/ChickenBehaviour.java index 78f65439..d763eda0 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/ChickenBehaviour.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/ChickenBehaviour.java @@ -1,19 +1,67 @@ package com.minelittlepony.unicopia.entity.behaviour; import com.minelittlepony.unicopia.ability.magic.Caster; +import com.minelittlepony.unicopia.entity.player.Pony; import net.minecraft.entity.Entity; +import net.minecraft.entity.EquipmentSlot; import net.minecraft.entity.passive.ChickenEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.sound.SoundEvents; import net.minecraft.util.math.Vec3d; public class ChickenBehaviour extends EntityBehaviour { + + @Override + protected boolean skipSlot(EquipmentSlot slot) { + return slot == EquipmentSlot.OFFHAND; + } + @Override public void update(Caster source, ChickenEntity entity) { + entity.eggLayTime = Integer.MAX_VALUE; + + if (source instanceof Pony) { + Pony player = (Pony)source; + + + if (player.sneakingChanged()) { + ItemStack egg = entity.getEquippedStack(EquipmentSlot.OFFHAND); + + if (player.getOwner().isSneaking()) { + if (egg.isEmpty()) { + egg = new ItemStack(Items.EGG); + + int slot = player.getOwner().inventory.method_7371(egg); + if (slot > -1) { + player.getOwner().inventory.removeStack(slot, 1); + entity.playSound(SoundEvents.ENTITY_CHICKEN_EGG, + 1, + (entity.world.random.nextFloat() - entity.world.random.nextFloat()) * 0.2F + 4 + ); + entity.equipStack(EquipmentSlot.OFFHAND, egg); + } + } + } else if (egg.getItem() == Items.EGG) { + entity.equipStack(EquipmentSlot.OFFHAND, ItemStack.EMPTY); + entity.eggLayTime = 0; + } + } + } + Entity src = source.getEntity(); + + if (src.isOnGround() || src instanceof PlayerEntity && ((PlayerEntity)src).abilities.flying) { + return; + } + Vec3d vel = src.getVelocity(); - if (!src.isOnGround() && vel.y < 0) { + if (vel.y < 0) { src.setVelocity(vel.multiply(1, 0.6, 1)); } + } } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/EntityBehaviour.java b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/EntityBehaviour.java index e839b462..5628dbdd 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/EntityBehaviour.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/EntityBehaviour.java @@ -1,39 +1,174 @@ package com.minelittlepony.unicopia.entity.behaviour; -import java.util.Optional; import java.util.function.Supplier; import javax.annotation.Nullable; import com.minelittlepony.unicopia.ability.magic.Caster; +import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell; import com.minelittlepony.unicopia.util.Registries; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; +import net.minecraft.entity.EquipmentSlot; +import net.minecraft.entity.FallingBlockEntity; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.passive.TameableEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; import net.minecraft.util.Identifier; import net.minecraft.util.registry.Registry; -public abstract class EntityBehaviour { +public class EntityBehaviour { + private static final EntityBehaviour DEFAULT = new EntityBehaviour<>(); private static final Registry> REGISTRY = Registries.createSimple(new Identifier("unicopia", "entity_behaviour")); - public abstract void update(Caster source, T entity); + public void update(Caster source, T entity) { + + } public void onCreate(T entity) { entity.extinguish(); } + public void copyBaseAttributes(LivingEntity from, Entity to) { + // Set first because position calculations rely on it + to.age = from.age; + to.removed = from.removed; + to.setOnGround(from.isOnGround()); + + if (DisguiseSpell.isAttachedEntity(to)) { + + double x = Math.floor(from.getX()) + 0.5; + double y = Math.floor(from.getY()); + double z = Math.floor(from.getZ()) + 0.5; + + to.prevX = x; + to.prevY = y; + to.prevZ = z; + + to.lastRenderX = x; + to.lastRenderY = y; + to.lastRenderZ = z; + + to.updatePosition(x, y, z); + + if (to instanceof FallingBlockEntity) { + ((FallingBlockEntity)to).setFallingBlockPos(from.getBlockPos()); + } + } else { + to.copyPositionAndRotation(from); + + to.prevX = from.prevX; + to.prevY = from.prevY; + to.prevZ = from.prevZ; + + to.chunkX = from.chunkX; + to.chunkY = from.chunkY; + to.chunkZ = from.chunkZ; + + to.lastRenderX = from.lastRenderX; + to.lastRenderY = from.lastRenderY; + to.lastRenderZ = from.lastRenderZ; + } + + if (to instanceof PlayerEntity) { + PlayerEntity l = (PlayerEntity)to; + + l.capeX = l.getX(); + l.capeY = l.getY(); + l.capeZ = l.getZ(); + } + + to.setVelocity(from.getVelocity()); + + to.pitch = from.pitch; + to.prevPitch = from.prevPitch; + to.yaw = from.yaw; + to.prevYaw = from.prevYaw; + to.horizontalSpeed = from.horizontalSpeed; + to.prevHorizontalSpeed = from.prevHorizontalSpeed; + + to.distanceTraveled = from.distanceTraveled; + + if (to instanceof LivingEntity) { + LivingEntity l = (LivingEntity)to; + + l.headYaw = from.headYaw; + l.prevHeadYaw = from.prevHeadYaw; + l.bodyYaw = from.bodyYaw; + l.prevBodyYaw = from.prevBodyYaw; + + l.limbDistance = from.limbDistance; + l.limbAngle = from.limbAngle; + l.lastLimbDistance = from.lastLimbDistance; + + l.handSwingProgress = from.handSwingProgress; + l.lastHandSwingProgress = from.lastHandSwingProgress; + l.handSwingTicks = from.handSwingTicks; + l.handSwinging = from.handSwinging; + + l.hurtTime = from.hurtTime; + l.deathTime = from.deathTime; + l.stuckStingerTimer = from.stuckStingerTimer; + l.stuckArrowTimer = from.stuckArrowTimer; + l.setHealth(from.getHealth()); + + copyInventory(from, l); + } + + /*if (to instanceof RangedAttackMob) { + ItemStack activeItem = from.getActiveItem(); + + ((RangedAttackMob)to).setSwingingArms(!activeItem.isEmpty() && activeItem.getUseAction() == UseAction.BOW); + }*/ + + if (to instanceof TameableEntity) { + ((TameableEntity)to).setSitting(from.isSneaking()); + } + + if (from.age < 100 || from instanceof PlayerEntity && ((PlayerEntity)from).isCreative()) { + to.extinguish(); + } + + if (to.isOnFire()) { + from.setOnFireFor(1); + } else { + from.extinguish(); + } + + to.setSneaking(from.isSneaking()); + } + + protected void copyInventory(LivingEntity from, LivingEntity l) { + for (EquipmentSlot i : EquipmentSlot.values()) { + if (!skipSlot(i)) { + ItemStack neu = from.getEquippedStack(i); + ItemStack old = l.getEquippedStack(i); + if (old != neu) { + l.equipStack(i, neu); + } + } + } + } + + protected boolean skipSlot(EquipmentSlot slot) { + return false; + } + public static void register(Supplier> behaviour, EntityType... types) { for (EntityType type : types) { Registry.register(REGISTRY, EntityType.getId(type), behaviour.get()); } } - public static Optional> forEntity(@Nullable Entity entity) { + @SuppressWarnings("unchecked") + public static EntityBehaviour forEntity(@Nullable T entity) { if (entity == null) { - return Optional.empty(); + return (EntityBehaviour)DEFAULT; } - return REGISTRY.getOrEmpty(EntityType.getId(entity.getType())); + return (EntityBehaviour)REGISTRY.getOrEmpty(EntityType.getId(entity.getType())).orElse(DEFAULT); } static {