From b43ed1975b20de87bb1645941f242eeb652e0a07 Mon Sep 17 00:00:00 2001 From: Sollace Date: Fri, 29 Jan 2021 18:37:41 +0200 Subject: [PATCH] Fixed shields being offset and fixed shields applying to entities that they shouldn't --- .../unicopia/ability/magic/Caster.java | 7 +++++- .../unicopia/ability/magic/CasterUtils.java | 5 +--- .../ability/magic/spell/AttractiveSpell.java | 2 +- .../ability/magic/spell/FireSpell.java | 4 ++-- .../ability/magic/spell/IceSpell.java | 5 ++-- .../ability/magic/spell/InfernoSpell.java | 6 ++--- .../ability/magic/spell/NecromancySpell.java | 3 +-- .../ability/magic/spell/ShieldSpell.java | 23 ++++++++++++++++--- .../unicopia/entity/behaviour/Disguise.java | 2 +- .../MixinPersistentProjectileEntity.java | 12 ++++++++++ .../unicopia/projectile/ProjectileUtil.java | 17 ++++++++++---- .../unicopia/util/VecHelper.java | 12 +++++----- src/main/resources/unicopia.mixin.json | 1 + 13 files changed, 70 insertions(+), 29 deletions(-) create mode 100644 src/main/java/com/minelittlepony/unicopia/mixin/MixinPersistentProjectileEntity.java diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/Caster.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/Caster.java index 0ee201ab..e329de55 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/Caster.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/Caster.java @@ -1,6 +1,7 @@ package com.minelittlepony.unicopia.ability.magic; import java.util.Optional; +import java.util.function.Predicate; import java.util.stream.Stream; import javax.annotation.Nullable; @@ -107,7 +108,11 @@ public interface Caster extends Owned, Levelled, Affi return CasterUtils.findInRange(this, radius); } + default Stream findAllEntitiesInRange(double radius, @Nullable Predicate test) { + return VecHelper.findInRange(getEntity(), getWorld(), getOriginVector(), radius, test).stream(); + } + default Stream findAllEntitiesInRange(double radius) { - return VecHelper.findInRange(getEntity(), getWorld(), getOrigin(), radius, null).stream(); + return findAllEntitiesInRange(radius, null); } } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/CasterUtils.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/CasterUtils.java index 350029f6..246635b3 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/CasterUtils.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/CasterUtils.java @@ -7,8 +7,6 @@ import javax.annotation.Nullable; import com.minelittlepony.unicopia.EquinePredicates; import com.minelittlepony.unicopia.entity.PonyContainer; -import com.minelittlepony.unicopia.util.VecHelper; - import net.minecraft.entity.Entity; import net.minecraft.entity.LivingEntity; @@ -17,8 +15,7 @@ public class CasterUtils { * Finds all surrounding spells within range from the given caster. */ static Stream> findInRange(Caster source, double radius) { - return VecHelper.findInRange(source.getEntity(), source.getWorld(), source.getOrigin(), radius, EquinePredicates.IS_CASTER) - .stream() + return source.findAllEntitiesInRange(radius, EquinePredicates.IS_CASTER) .map(e -> toCaster(e).filter(o -> o != source)) .filter(Optional::isPresent) .map(Optional::get); diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AttractiveSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AttractiveSpell.java index 1e1c3f7d..1a344d05 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AttractiveSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AttractiveSpell.java @@ -60,7 +60,7 @@ public class AttractiveSpell extends ShieldSpell implements Thrown { protected List getTargets(Caster source, double radius) { if (homingPos != null) { - return VecHelper.findInRange(source.getEntity(), source.getWorld(), source.getOrigin(), radius, i -> i instanceof ItemEntity); + return VecHelper.findInRange(source.getEntity(), source.getWorld(), source.getOriginVector(), radius, i -> i instanceof ItemEntity); } return super.getTargets(source, radius); diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/FireSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/FireSpell.java index fa568e08..aa1d6632 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/FireSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/FireSpell.java @@ -66,7 +66,7 @@ public class FireSpell extends AbstractRangedAreaSpell implements Thrown { return PosHelper.getAllInRegionMutable(source.getOrigin(), EFFECT_RANGE).reduce(false, (r, i) -> applyBlocks(source.getWorld(), i), (a, b) -> a || b) - || applyEntities(null, source.getWorld(), source.getOrigin()); + || applyEntities(null, source.getWorld(), source.getOriginVector()); } @Override @@ -130,7 +130,7 @@ public class FireSpell extends AbstractRangedAreaSpell implements Thrown { return false; } - protected boolean applyEntities(Entity owner, World world, BlockPos pos) { + protected boolean applyEntities(Entity owner, World world, Vec3d pos) { return !VecHelper.findInRange(owner, world, pos, 3, i -> applyEntitySingle(owner, world, i)).isEmpty(); } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/IceSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/IceSpell.java index a01d3e58..0cc8c2b7 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/IceSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/IceSpell.java @@ -21,6 +21,7 @@ import net.minecraft.entity.TntEntity; import net.minecraft.particle.ParticleTypes; import net.minecraft.tag.BlockTags; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; public class IceSpell extends AbstractRangedAreaSpell implements Thrown { @@ -50,14 +51,14 @@ public class IceSpell extends AbstractRangedAreaSpell implements Thrown { PosHelper.getAllInRegionMutable(source.getOrigin(), effect_range) .forEach(i -> applyBlockSingle(owner, source.getWorld(), i)); - return applyEntities(source.getMaster(), source.getWorld(), source.getOrigin()); + return applyEntities(source.getMaster(), source.getWorld(), source.getOriginVector()); } @Override public void render(Caster source) { } - protected boolean applyEntities(LivingEntity owner, World world, BlockPos pos) { + protected boolean applyEntities(LivingEntity owner, World world, Vec3d pos) { return !VecHelper.findInRange(owner, world, pos, 3, i -> applyEntitySingle(owner, i)).isEmpty(); } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/InfernoSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/InfernoSpell.java index a6a0aff7..d184a438 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/InfernoSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/InfernoSpell.java @@ -57,10 +57,10 @@ public class InfernoSpell extends FireSpell { shape = new Sphere(false, radius - 1); for (int i = 0; i < radius * 2; i++) { if (w.random.nextInt(12) == 0) { - BlockPos pos = new BlockPos(shape.computePoint(w.random).add(origin)); + Vec3d vec = shape.computePoint(w.random).add(origin); - if (!applyBlocks(w, pos)) { - applyEntities(source.getMaster(), w, pos); + if (!applyBlocks(w, new BlockPos(vec))) { + applyEntities(source.getMaster(), w, vec); } } } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/NecromancySpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/NecromancySpell.java index 044363c4..e3e52ce4 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/NecromancySpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/NecromancySpell.java @@ -5,7 +5,6 @@ import java.util.List; import com.google.common.collect.Lists; import com.minelittlepony.unicopia.Affinity; import com.minelittlepony.unicopia.ability.magic.Caster; -import com.minelittlepony.unicopia.util.VecHelper; import com.minelittlepony.unicopia.util.WorldEvent; import com.minelittlepony.unicopia.util.shape.Shape; import com.minelittlepony.unicopia.util.shape.Sphere; @@ -62,7 +61,7 @@ public class NecromancySpell extends AbstractRangedAreaSpell { Vec3d origin = source.getOriginVector(); - if (VecHelper.findInRange(source.getEntity(), source.getWorld(), source.getOrigin(), radius * 4, e -> e instanceof ZombieEntity).size() >= 10 * (1 + additional)) { + if (source.findAllEntitiesInRange(radius * 4, e -> e instanceof ZombieEntity).count() >= 10 * (1 + additional)) { return true; } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ShieldSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ShieldSpell.java index ed26503f..a92e5faa 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ShieldSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ShieldSpell.java @@ -16,9 +16,14 @@ import com.minelittlepony.unicopia.projectile.ProjectileUtil; import com.minelittlepony.unicopia.util.shape.Sphere; import net.minecraft.entity.Entity; -import net.minecraft.entity.ItemEntity; +import net.minecraft.entity.EyeOfEnderEntity; +import net.minecraft.entity.FallingBlockEntity; import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.TntEntity; +import net.minecraft.entity.decoration.ArmorStandEntity; import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.vehicle.AbstractMinecartEntity; +import net.minecraft.entity.vehicle.BoatEntity; import net.minecraft.sound.SoundEvents; import net.minecraft.util.math.Vec3d; @@ -100,7 +105,19 @@ public class ShieldSpell extends AbstractRangedAreaSpell implements Attached { boolean ownerIsValid = source.getAffinity() != Affinity.BAD && EquinePredicates.PLAYER_UNICORN.test(owner); return source.findAllEntitiesInRange(radius) - .filter(entity -> !(entity instanceof ItemEntity || (ownerIsValid && Pony.equal(entity, owner)))) + .filter(entity -> { + return + (entity instanceof LivingEntity + || entity instanceof TntEntity + || entity instanceof FallingBlockEntity + || entity instanceof EyeOfEnderEntity + || entity instanceof BoatEntity + || ProjectileUtil.isFlyingProjectile(entity) + || entity instanceof AbstractMinecartEntity) + && !(entity instanceof ArmorStandEntity) + && !(owner.isConnectedThroughVehicle(entity)) + && !(ownerIsValid && Pony.equal(entity, owner)); + }) .collect(Collectors.toList()); } @@ -126,7 +143,7 @@ public class ShieldSpell extends AbstractRangedAreaSpell implements Attached { protected void applyRadialEffect(Caster source, Entity target, double distance, double radius) { Vec3d pos = source.getOriginVector(); - if (ProjectileUtil.isProjectile(target)) { + if (ProjectileUtil.isFlyingProjectile(target)) { if (!ProjectileUtil.isProjectileThrownBy(target, source.getMaster())) { if (distance < 1) { target.playSound(SoundEvents.ENTITY_ZOMBIE_VILLAGER_CURE, 0.1F, 1); diff --git a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/Disguise.java b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/Disguise.java index 89e0908e..f8b00f4e 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/Disguise.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/Disguise.java @@ -196,7 +196,7 @@ public class Disguise implements NbtSerialisable { || entity instanceof VexEntity || entity instanceof ShulkerBulletEntity || entity instanceof Flutterer - || ProjectileUtil.isProjectile(entity)) { + || ProjectileUtil.isFlyingProjectile(entity)) { return FlightType.INSECTOID; } diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinPersistentProjectileEntity.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinPersistentProjectileEntity.java new file mode 100644 index 00000000..1d0c31ff --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinPersistentProjectileEntity.java @@ -0,0 +1,12 @@ +package com.minelittlepony.unicopia.mixin; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import net.minecraft.entity.projectile.PersistentProjectileEntity; + +@Mixin(PersistentProjectileEntity.class) +public interface MixinPersistentProjectileEntity { + @Accessor("inGround") + boolean isInGround(); +} diff --git a/src/main/java/com/minelittlepony/unicopia/projectile/ProjectileUtil.java b/src/main/java/com/minelittlepony/unicopia/projectile/ProjectileUtil.java index 68b32cc8..108cec41 100644 --- a/src/main/java/com/minelittlepony/unicopia/projectile/ProjectileUtil.java +++ b/src/main/java/com/minelittlepony/unicopia/projectile/ProjectileUtil.java @@ -2,23 +2,32 @@ package com.minelittlepony.unicopia.projectile; import javax.annotation.Nullable; +import com.minelittlepony.unicopia.mixin.MixinPersistentProjectileEntity; + import net.minecraft.entity.Entity; import net.minecraft.entity.projectile.ProjectileEntity; import net.minecraft.util.math.Vec3d; -public class ProjectileUtil { +public interface ProjectileUtil { /** * Checks if the given entity is a projectile. */ - public static boolean isProjectile(Entity e) { + static boolean isProjectile(Entity e) { return e instanceof ProjectileEntity; } + /** + * Checks if the given entity is a projectile that is not stuck in the ground. + */ + static boolean isFlyingProjectile(Entity e) { + return isProjectile(e) && !(e instanceof MixinPersistentProjectileEntity && ((MixinPersistentProjectileEntity)e).isInGround()); + } + /** * Checks if the given projectile was thrown by the given entity */ - public static boolean isProjectileThrownBy(Entity throwable, @Nullable T e) { + static boolean isProjectileThrownBy(Entity throwable, @Nullable T e) { return e != null && isProjectile(throwable) && e.equals(((ProjectileEntity) throwable).getOwner()); } @@ -31,7 +40,7 @@ public class ProjectileUtil { * @param inaccuracy Inaccuracy * @return True the projectile's heading was set, false otherwise */ - public static void setThrowableHeading(Entity throwable, Vec3d heading, float velocity, float inaccuracy) { + static void setThrowableHeading(Entity throwable, Vec3d heading, float velocity, float inaccuracy) { if (throwable instanceof ProjectileEntity) { ((ProjectileEntity)throwable).setVelocity(heading.x, heading.y, heading.z, velocity, inaccuracy); diff --git a/src/main/java/com/minelittlepony/unicopia/util/VecHelper.java b/src/main/java/com/minelittlepony/unicopia/util/VecHelper.java index 71bdba5d..9c592c65 100644 --- a/src/main/java/com/minelittlepony/unicopia/util/VecHelper.java +++ b/src/main/java/com/minelittlepony/unicopia/util/VecHelper.java @@ -6,25 +6,25 @@ import javax.annotation.Nullable; import net.minecraft.entity.Entity; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Box; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; public interface VecHelper { - static Predicate inRange(BlockPos center, double range) { + static Predicate inRange(Vec3d center, double range) { double rad = Math.pow(range, 2); return e -> { - return e.squaredDistanceTo(center.getX(), center.getY(), center.getZ()) <= rad - || e.squaredDistanceTo(center.getX(), center.getY() - e.getStandingEyeHeight(), center.getZ()) <= rad; + return e.squaredDistanceTo(center) <= rad + || e.squaredDistanceTo(center.getX(), center.getY() - e.getStandingEyeHeight(), center.getZ()) <= rad; }; } - static List findInRange(@Nullable Entity origin, World w, BlockPos pos, double radius, @Nullable Predicate predicate) { - return w.getOtherEntities(origin, new Box(pos).expand(radius), predicate == null ? inRange(pos, radius) : inRange(pos, radius).and(predicate)); + static List findInRange(@Nullable Entity origin, World w, Vec3d pos, double radius, @Nullable Predicate predicate) { + return w.getOtherEntities(origin, Box.method_29968(pos).expand(radius), predicate == null ? inRange(pos, radius) : inRange(pos, radius).and(predicate)); } + /** * Gets all entities within a given range from the player. */ diff --git a/src/main/resources/unicopia.mixin.json b/src/main/resources/unicopia.mixin.json index e6fac879..a691beb2 100644 --- a/src/main/resources/unicopia.mixin.json +++ b/src/main/resources/unicopia.mixin.json @@ -13,6 +13,7 @@ "MixinItems", "MixinLivingEntity", "MixinMilkBucketItem", + "MixinPersistentProjectileEntity", "MixinPlayerEntity", "MixinProjectileEntity", "MixinServerPlayerEntity",