mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-27 15:17:59 +01:00
Fixed shields being offset and fixed shields applying to entities that they shouldn't
This commit is contained in:
parent
543fd7aee0
commit
b43ed1975b
13 changed files with 70 additions and 29 deletions
|
@ -1,6 +1,7 @@
|
||||||
package com.minelittlepony.unicopia.ability.magic;
|
package com.minelittlepony.unicopia.ability.magic;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.function.Predicate;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
@ -107,7 +108,11 @@ public interface Caster<E extends LivingEntity> extends Owned<E>, Levelled, Affi
|
||||||
return CasterUtils.findInRange(this, radius);
|
return CasterUtils.findInRange(this, radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default Stream<Entity> findAllEntitiesInRange(double radius, @Nullable Predicate<Entity> test) {
|
||||||
|
return VecHelper.findInRange(getEntity(), getWorld(), getOriginVector(), radius, test).stream();
|
||||||
|
}
|
||||||
|
|
||||||
default Stream<Entity> findAllEntitiesInRange(double radius) {
|
default Stream<Entity> findAllEntitiesInRange(double radius) {
|
||||||
return VecHelper.findInRange(getEntity(), getWorld(), getOrigin(), radius, null).stream();
|
return findAllEntitiesInRange(radius, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,6 @@ import javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.EquinePredicates;
|
import com.minelittlepony.unicopia.EquinePredicates;
|
||||||
import com.minelittlepony.unicopia.entity.PonyContainer;
|
import com.minelittlepony.unicopia.entity.PonyContainer;
|
||||||
import com.minelittlepony.unicopia.util.VecHelper;
|
|
||||||
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.LivingEntity;
|
import net.minecraft.entity.LivingEntity;
|
||||||
|
|
||||||
|
@ -17,8 +15,7 @@ public class CasterUtils {
|
||||||
* Finds all surrounding spells within range from the given caster.
|
* Finds all surrounding spells within range from the given caster.
|
||||||
*/
|
*/
|
||||||
static Stream<Caster<?>> findInRange(Caster<?> source, double radius) {
|
static Stream<Caster<?>> findInRange(Caster<?> source, double radius) {
|
||||||
return VecHelper.findInRange(source.getEntity(), source.getWorld(), source.getOrigin(), radius, EquinePredicates.IS_CASTER)
|
return source.findAllEntitiesInRange(radius, EquinePredicates.IS_CASTER)
|
||||||
.stream()
|
|
||||||
.map(e -> toCaster(e).filter(o -> o != source))
|
.map(e -> toCaster(e).filter(o -> o != source))
|
||||||
.filter(Optional::isPresent)
|
.filter(Optional::isPresent)
|
||||||
.map(Optional::get);
|
.map(Optional::get);
|
||||||
|
|
|
@ -60,7 +60,7 @@ public class AttractiveSpell extends ShieldSpell implements Thrown {
|
||||||
protected List<Entity> getTargets(Caster<?> source, double radius) {
|
protected List<Entity> getTargets(Caster<?> source, double radius) {
|
||||||
|
|
||||||
if (homingPos != null) {
|
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);
|
return super.getTargets(source, radius);
|
||||||
|
|
|
@ -66,7 +66,7 @@ public class FireSpell extends AbstractRangedAreaSpell implements Thrown {
|
||||||
return PosHelper.getAllInRegionMutable(source.getOrigin(), EFFECT_RANGE).reduce(false,
|
return PosHelper.getAllInRegionMutable(source.getOrigin(), EFFECT_RANGE).reduce(false,
|
||||||
(r, i) -> applyBlocks(source.getWorld(), i),
|
(r, i) -> applyBlocks(source.getWorld(), i),
|
||||||
(a, b) -> a || b)
|
(a, b) -> a || b)
|
||||||
|| applyEntities(null, source.getWorld(), source.getOrigin());
|
|| applyEntities(null, source.getWorld(), source.getOriginVector());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -130,7 +130,7 @@ public class FireSpell extends AbstractRangedAreaSpell implements Thrown {
|
||||||
return false;
|
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();
|
return !VecHelper.findInRange(owner, world, pos, 3, i -> applyEntitySingle(owner, world, i)).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ import net.minecraft.entity.TntEntity;
|
||||||
import net.minecraft.particle.ParticleTypes;
|
import net.minecraft.particle.ParticleTypes;
|
||||||
import net.minecraft.tag.BlockTags;
|
import net.minecraft.tag.BlockTags;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public class IceSpell extends AbstractRangedAreaSpell implements Thrown {
|
public class IceSpell extends AbstractRangedAreaSpell implements Thrown {
|
||||||
|
@ -50,14 +51,14 @@ public class IceSpell extends AbstractRangedAreaSpell implements Thrown {
|
||||||
PosHelper.getAllInRegionMutable(source.getOrigin(), effect_range)
|
PosHelper.getAllInRegionMutable(source.getOrigin(), effect_range)
|
||||||
.forEach(i -> applyBlockSingle(owner, source.getWorld(), i));
|
.forEach(i -> applyBlockSingle(owner, source.getWorld(), i));
|
||||||
|
|
||||||
return applyEntities(source.getMaster(), source.getWorld(), source.getOrigin());
|
return applyEntities(source.getMaster(), source.getWorld(), source.getOriginVector());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(Caster<?> source) {
|
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();
|
return !VecHelper.findInRange(owner, world, pos, 3, i -> applyEntitySingle(owner, i)).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,10 +57,10 @@ public class InfernoSpell extends FireSpell {
|
||||||
shape = new Sphere(false, radius - 1);
|
shape = new Sphere(false, radius - 1);
|
||||||
for (int i = 0; i < radius * 2; i++) {
|
for (int i = 0; i < radius * 2; i++) {
|
||||||
if (w.random.nextInt(12) == 0) {
|
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)) {
|
if (!applyBlocks(w, new BlockPos(vec))) {
|
||||||
applyEntities(source.getMaster(), w, pos);
|
applyEntities(source.getMaster(), w, vec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ import java.util.List;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.minelittlepony.unicopia.Affinity;
|
import com.minelittlepony.unicopia.Affinity;
|
||||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||||
import com.minelittlepony.unicopia.util.VecHelper;
|
|
||||||
import com.minelittlepony.unicopia.util.WorldEvent;
|
import com.minelittlepony.unicopia.util.WorldEvent;
|
||||||
import com.minelittlepony.unicopia.util.shape.Shape;
|
import com.minelittlepony.unicopia.util.shape.Shape;
|
||||||
import com.minelittlepony.unicopia.util.shape.Sphere;
|
import com.minelittlepony.unicopia.util.shape.Sphere;
|
||||||
|
@ -62,7 +61,7 @@ public class NecromancySpell extends AbstractRangedAreaSpell {
|
||||||
|
|
||||||
Vec3d origin = source.getOriginVector();
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,9 +16,14 @@ import com.minelittlepony.unicopia.projectile.ProjectileUtil;
|
||||||
import com.minelittlepony.unicopia.util.shape.Sphere;
|
import com.minelittlepony.unicopia.util.shape.Sphere;
|
||||||
|
|
||||||
import net.minecraft.entity.Entity;
|
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.LivingEntity;
|
||||||
|
import net.minecraft.entity.TntEntity;
|
||||||
|
import net.minecraft.entity.decoration.ArmorStandEntity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
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.sound.SoundEvents;
|
||||||
import net.minecraft.util.math.Vec3d;
|
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);
|
boolean ownerIsValid = source.getAffinity() != Affinity.BAD && EquinePredicates.PLAYER_UNICORN.test(owner);
|
||||||
|
|
||||||
return source.findAllEntitiesInRange(radius)
|
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());
|
.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) {
|
protected void applyRadialEffect(Caster<?> source, Entity target, double distance, double radius) {
|
||||||
Vec3d pos = source.getOriginVector();
|
Vec3d pos = source.getOriginVector();
|
||||||
|
|
||||||
if (ProjectileUtil.isProjectile(target)) {
|
if (ProjectileUtil.isFlyingProjectile(target)) {
|
||||||
if (!ProjectileUtil.isProjectileThrownBy(target, source.getMaster())) {
|
if (!ProjectileUtil.isProjectileThrownBy(target, source.getMaster())) {
|
||||||
if (distance < 1) {
|
if (distance < 1) {
|
||||||
target.playSound(SoundEvents.ENTITY_ZOMBIE_VILLAGER_CURE, 0.1F, 1);
|
target.playSound(SoundEvents.ENTITY_ZOMBIE_VILLAGER_CURE, 0.1F, 1);
|
||||||
|
|
|
@ -196,7 +196,7 @@ public class Disguise implements NbtSerialisable {
|
||||||
|| entity instanceof VexEntity
|
|| entity instanceof VexEntity
|
||||||
|| entity instanceof ShulkerBulletEntity
|
|| entity instanceof ShulkerBulletEntity
|
||||||
|| entity instanceof Flutterer
|
|| entity instanceof Flutterer
|
||||||
|| ProjectileUtil.isProjectile(entity)) {
|
|| ProjectileUtil.isFlyingProjectile(entity)) {
|
||||||
return FlightType.INSECTOID;
|
return FlightType.INSECTOID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
|
@ -2,23 +2,32 @@ package com.minelittlepony.unicopia.projectile;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.minelittlepony.unicopia.mixin.MixinPersistentProjectileEntity;
|
||||||
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.projectile.ProjectileEntity;
|
import net.minecraft.entity.projectile.ProjectileEntity;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
public class ProjectileUtil {
|
public interface ProjectileUtil {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the given entity is a projectile.
|
* Checks if the given entity is a projectile.
|
||||||
*/
|
*/
|
||||||
public static boolean isProjectile(Entity e) {
|
static boolean isProjectile(Entity e) {
|
||||||
return e instanceof ProjectileEntity;
|
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
|
* Checks if the given projectile was thrown by the given entity
|
||||||
*/
|
*/
|
||||||
public static <T extends Entity> boolean isProjectileThrownBy(Entity throwable, @Nullable T e) {
|
static <T extends Entity> boolean isProjectileThrownBy(Entity throwable, @Nullable T e) {
|
||||||
return e != null && isProjectile(throwable) && e.equals(((ProjectileEntity) throwable).getOwner());
|
return e != null && isProjectile(throwable) && e.equals(((ProjectileEntity) throwable).getOwner());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +40,7 @@ public class ProjectileUtil {
|
||||||
* @param inaccuracy Inaccuracy
|
* @param inaccuracy Inaccuracy
|
||||||
* @return True the projectile's heading was set, false otherwise
|
* @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) {
|
if (throwable instanceof ProjectileEntity) {
|
||||||
((ProjectileEntity)throwable).setVelocity(heading.x, heading.y, heading.z, velocity, inaccuracy);
|
((ProjectileEntity)throwable).setVelocity(heading.x, heading.y, heading.z, velocity, inaccuracy);
|
||||||
|
|
|
@ -6,25 +6,25 @@ import javax.annotation.Nullable;
|
||||||
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.math.Box;
|
import net.minecraft.util.math.Box;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public interface VecHelper {
|
public interface VecHelper {
|
||||||
|
|
||||||
static Predicate<Entity> inRange(BlockPos center, double range) {
|
static Predicate<Entity> inRange(Vec3d center, double range) {
|
||||||
double rad = Math.pow(range, 2);
|
double rad = Math.pow(range, 2);
|
||||||
return e -> {
|
return e -> {
|
||||||
return e.squaredDistanceTo(center.getX(), center.getY(), center.getZ()) <= rad
|
return e.squaredDistanceTo(center) <= rad
|
||||||
|| e.squaredDistanceTo(center.getX(), center.getY() - e.getStandingEyeHeight(), center.getZ()) <= rad;
|
|| e.squaredDistanceTo(center.getX(), center.getY() - e.getStandingEyeHeight(), center.getZ()) <= rad;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static List<Entity> findInRange(@Nullable Entity origin, World w, BlockPos pos, double radius, @Nullable Predicate<Entity> predicate) {
|
static List<Entity> findInRange(@Nullable Entity origin, World w, Vec3d pos, double radius, @Nullable Predicate<Entity> predicate) {
|
||||||
return w.getOtherEntities(origin, new Box(pos).expand(radius), predicate == null ? inRange(pos, radius) : inRange(pos, radius).and(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.
|
* Gets all entities within a given range from the player.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
"MixinItems",
|
"MixinItems",
|
||||||
"MixinLivingEntity",
|
"MixinLivingEntity",
|
||||||
"MixinMilkBucketItem",
|
"MixinMilkBucketItem",
|
||||||
|
"MixinPersistentProjectileEntity",
|
||||||
"MixinPlayerEntity",
|
"MixinPlayerEntity",
|
||||||
"MixinProjectileEntity",
|
"MixinProjectileEntity",
|
||||||
"MixinServerPlayerEntity",
|
"MixinServerPlayerEntity",
|
||||||
|
|
Loading…
Reference in a new issue