mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-27 15:17:59 +01:00
Fix shields targetting the entity it belongs to
This commit is contained in:
parent
bbe9eb0068
commit
4151b66e99
12 changed files with 71 additions and 59 deletions
|
@ -5,6 +5,8 @@ import java.util.UUID;
|
|||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.item.FriendshipBraceletItem;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
|
||||
/**
|
||||
|
@ -27,14 +29,23 @@ public interface Owned<E extends Entity> {
|
|||
* Since {@link Owned#getMaster()} will only return if the owner is loaded, use this to perform checks
|
||||
* in the owner's absence.
|
||||
*/
|
||||
default Optional<UUID> getMasterId() {
|
||||
return Optional.of(getMaster()).map(Entity::getUuid);
|
||||
Optional<UUID> getMasterId();
|
||||
|
||||
default boolean isOwnerOrFriend(Entity target) {
|
||||
return FriendshipBraceletItem.isComrade(this, target) || isOwnerOrVehicle(target);
|
||||
}
|
||||
|
||||
default boolean isOwnerOrVehicle(@Nullable Entity target) {
|
||||
if (isOwnedBy(target)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Entity owner = getMaster();
|
||||
return target != null && owner != null && owner.isConnectedThroughVehicle(target);
|
||||
}
|
||||
|
||||
default boolean isOwnedBy(@Nullable Object owner) {
|
||||
return owner instanceof Entity e
|
||||
&& getMasterId().isPresent()
|
||||
&& e.getUuid().equals(getMasterId().get());
|
||||
return owner instanceof Entity e && e.getUuid().equals(getMasterId().orElse(null));
|
||||
}
|
||||
|
||||
default boolean hasCommonOwner(Owned<?> sibling) {
|
||||
|
|
|
@ -19,4 +19,8 @@ public interface Affine {
|
|||
default boolean isFriendlyTogether(Affine other) {
|
||||
return getAffinity() != Affinity.BAD && other.getAffinity() != Affinity.BAD;
|
||||
}
|
||||
|
||||
default boolean applyInversion(Affine other, boolean friendly) {
|
||||
return isEnemy(other) ? !friendly : friendly;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -97,7 +97,6 @@ public class DarkVortexSpell extends AttractiveSpell implements ProjectileDelega
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isFriendlyTogether(Affine other) {
|
||||
return accumulatedMass < 4;
|
||||
|
|
|
@ -48,7 +48,7 @@ public class FireBoltSpell extends AbstractSpell implements HomingSpell,
|
|||
if (caster instanceof MagicProjectileEntity && getTraits().get(Trait.FOCUS) >= 50) {
|
||||
caster.findAllEntitiesInRange(
|
||||
getTraits().get(Trait.FOCUS) - 49,
|
||||
EntityPredicates.VALID_LIVING_ENTITY.and(TargetSelecter.notOwnerOrFriend(this, caster))
|
||||
EntityPredicates.VALID_LIVING_ENTITY.and(TargetSelecter.validTarget(this, caster))
|
||||
).findFirst().ifPresent(target -> {
|
||||
((MagicProjectileEntity)caster).setHomingTarget(target);
|
||||
});
|
||||
|
@ -60,7 +60,7 @@ public class FireBoltSpell extends AbstractSpell implements HomingSpell,
|
|||
if (getTraits().get(Trait.FOCUS) >= 50 && target.getOrEmpty(caster.asWorld()).isEmpty()) {
|
||||
target.set(caster.findAllEntitiesInRange(
|
||||
getTraits().get(Trait.FOCUS) - 49,
|
||||
EntityPredicates.VALID_LIVING_ENTITY.and(TargetSelecter.notOwnerOrFriend(this, caster))
|
||||
EntityPredicates.VALID_LIVING_ENTITY.and(TargetSelecter.validTarget(this, caster))
|
||||
).findFirst().orElse(null));
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@ import net.minecraft.entity.Entity;
|
|||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.network.packet.s2c.play.PositionFlag;
|
||||
import net.minecraft.particle.ParticleEffect;
|
||||
import net.minecraft.particle.ParticleTypes;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
@ -101,13 +100,7 @@ public class PortalSpell extends AbstractSpell implements PlaceableSpell.Placeme
|
|||
if (situation == Situation.GROUND) {
|
||||
|
||||
if (source.isClient()) {
|
||||
Vec3d origin = source.getOriginVector();
|
||||
|
||||
ParticleEffect effect = getTarget()
|
||||
.map(target -> (ParticleEffect)new FollowingParticleEffect(UParticles.HEALTH_DRAIN, target.pos(), 0.2F).withChild(ParticleTypes.ELECTRIC_SPARK))
|
||||
.orElse(ParticleTypes.ELECTRIC_SPARK);
|
||||
|
||||
source.spawnParticles(origin, particleArea, 5, pos -> {
|
||||
source.spawnParticles(particleArea, 5, pos -> {
|
||||
source.addParticle(ParticleTypes.ELECTRIC_SPARK, pos, Vec3d.ZERO);
|
||||
});
|
||||
} else {
|
||||
|
|
|
@ -41,7 +41,7 @@ public class ShieldSpell extends AbstractSpell {
|
|||
.with(Trait.AIR, 9)
|
||||
.build();
|
||||
|
||||
private final TargetSelecter targetSelecter = new TargetSelecter(this);
|
||||
private final TargetSelecter targetSelecter = new TargetSelecter(this).setFilter(this::isValidTarget);
|
||||
|
||||
private float prevRadius;
|
||||
private float radius;
|
||||
|
@ -174,11 +174,8 @@ public class ShieldSpell extends AbstractSpell {
|
|||
}
|
||||
|
||||
protected long applyEntities(Caster<?> source) {
|
||||
double radius = this.radius;
|
||||
|
||||
Vec3d origin = getOrigin(source);
|
||||
|
||||
targetSelecter.getEntities(source, radius, this::isValidTarget).forEach(i -> {
|
||||
targetSelecter.getEntities(source, radius).forEach(i -> {
|
||||
try {
|
||||
applyRadialEffect(source, i, i.getPos().distanceTo(origin), radius);
|
||||
} catch (Throwable e) {
|
||||
|
|
|
@ -11,26 +11,31 @@ import com.minelittlepony.unicopia.EquinePredicates;
|
|||
import com.minelittlepony.unicopia.ability.magic.Affine;
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
import com.minelittlepony.unicopia.item.FriendshipBraceletItem;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.predicate.entity.EntityPredicates;
|
||||
|
||||
public class TargetSelecter {
|
||||
|
||||
private final Map<UUID, Target> targets = new TreeMap<>();
|
||||
|
||||
private final Spell spell;
|
||||
|
||||
private BiPredicate<Caster<?>, Entity> filter = (a, b) -> true;
|
||||
|
||||
public TargetSelecter(Spell spell) {
|
||||
this.spell = spell;
|
||||
}
|
||||
|
||||
public Stream<Entity> getEntities(Caster<?> source, double radius, BiPredicate<Caster<?>, Entity> filter) {
|
||||
public TargetSelecter setFilter(BiPredicate<Caster<?>, Entity> filter) {
|
||||
this.filter = filter;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Stream<Entity> getEntities(Caster<?> source, double radius) {
|
||||
targets.values().removeIf(Target::tick);
|
||||
return source.findAllEntitiesInRange(radius)
|
||||
.filter(entity -> entity.isAlive() && !entity.isRemoved() && notOwnerOrFriend(spell, source, entity))
|
||||
.filter(EntityPredicates.VALID_ENTITY)
|
||||
.filter(EquinePredicates.EXCEPT_MAGIC_IMMUNE)
|
||||
.filter(e -> filter.test(source, e))
|
||||
.filter(entity -> entity != source.asEntity() && validTarget(spell, source, entity) && filter.test(source, entity))
|
||||
.map(i -> {
|
||||
targets.computeIfAbsent(i.getUuid(), Target::new);
|
||||
return i;
|
||||
|
@ -41,35 +46,19 @@ public class TargetSelecter {
|
|||
return targets.values().stream().filter(Target::canHurt).count();
|
||||
}
|
||||
|
||||
public static <T extends Entity> Predicate<T> notOwnerOrFriend(Affine affine, Caster<?> source) {
|
||||
return target -> notOwnerOrFriend(affine, source, target);
|
||||
public static <T extends Entity> Predicate<T> validTarget(Affine affine, Caster<?> source) {
|
||||
return target -> validTarget(affine, source, target);
|
||||
}
|
||||
|
||||
public static <T extends Entity> Predicate<T> isOwnerOrFriend(Affine affine, Caster<?> source) {
|
||||
return target -> isOwnerOrFriend(affine, source, target);
|
||||
}
|
||||
|
||||
public static <T extends Entity> boolean notOwnerOrFriend(Affine affine, Caster<?> source, Entity target) {
|
||||
public static boolean validTarget(Affine affine, Caster<?> source, Entity target) {
|
||||
return !isOwnerOrFriend(affine, source, target);
|
||||
}
|
||||
|
||||
public static <T extends Entity> boolean isOwnerOrFriend(Affine affine, Caster<?> source, Entity target) {
|
||||
Entity owner = source.getMaster();
|
||||
|
||||
var equine = Pony.of(target);
|
||||
if (equine.isPresent() && !affine.isFriendlyTogether(equine.get())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (affine.isEnemy(source)) {
|
||||
return FriendshipBraceletItem.isComrade(source, target);
|
||||
}
|
||||
|
||||
return FriendshipBraceletItem.isComrade(source, target)
|
||||
|| (owner != null && (Pony.equal(target, owner) || owner.isConnectedThroughVehicle(target)));
|
||||
public static boolean isOwnerOrFriend(Affine affine, Caster<?> source, Entity target) {
|
||||
return affine.applyInversion(source, source.isOwnerOrFriend(target));
|
||||
}
|
||||
|
||||
static final class Target {
|
||||
private static final class Target {
|
||||
private int cooldown = 20;
|
||||
|
||||
Target(UUID id) { }
|
||||
|
|
|
@ -60,7 +60,7 @@ public class Creature extends Living<LivingEntity> implements WeaklyOwned.Mutabl
|
|||
private boolean discordedChanged = true;
|
||||
private int smittenTicks;
|
||||
|
||||
private final Predicate<LivingEntity> targetPredicate = TargetSelecter.<LivingEntity>notOwnerOrFriend(() -> getOriginatingCaster().getAffinity(), this).and(e -> {
|
||||
private final Predicate<LivingEntity> targetPredicate = TargetSelecter.<LivingEntity>validTarget(() -> getOriginatingCaster().getAffinity(), this).and(e -> {
|
||||
return Equine.of(e)
|
||||
.filter(eq -> eq instanceof Creature)
|
||||
.filter(eq -> isDiscorded() != ((Creature)eq).hasCommonOwner(this))
|
||||
|
|
|
@ -362,6 +362,11 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
|||
return asEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<UUID> getMasterId() {
|
||||
return Optional.of(asEntity().getUuid());
|
||||
}
|
||||
|
||||
public void onSpawn() {
|
||||
if (entity.getWorld() instanceof ServerWorld sw && sw.getServer().getSaveProperties().getGameMode() != GameMode.ADVENTURE) {
|
||||
boolean mustAvoidSun = getObservedSpecies() == Race.BAT && MeteorlogicalUtil.isPositionExposedToSun(sw, getOrigin());
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
package com.minelittlepony.unicopia.entity.player.dummy;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
|
@ -13,6 +16,7 @@ import net.minecraft.client.network.ClientPlayNetworkHandler;
|
|||
import net.minecraft.client.network.PlayerListEntry;
|
||||
import net.minecraft.client.render.entity.PlayerModelPart;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EquipmentSlot;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
@ -79,4 +83,9 @@ public class DummyClientPlayerEntity extends AbstractClientPlayerEntity implemen
|
|||
public void setMaster(PlayerEntity owner) {
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<UUID> getMasterId() {
|
||||
return Optional.ofNullable(owner).map(Entity::getUuid);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
package com.minelittlepony.unicopia.entity.player.dummy;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.InteractionManager;
|
||||
|
@ -7,6 +10,7 @@ import com.minelittlepony.unicopia.Owned;
|
|||
import com.mojang.authlib.GameProfile;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EquipmentSlot;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
@ -42,6 +46,11 @@ public class DummyPlayerEntity extends PlayerEntity implements Owned<PlayerEntit
|
|||
this.owner = owner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<UUID> getMasterId() {
|
||||
return Optional.ofNullable(owner).map(Entity::getUuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRenderName() {
|
||||
return !InteractionManager.instance().isClientPlayer(getMaster());
|
||||
|
|
|
@ -7,6 +7,7 @@ import java.util.stream.Stream;
|
|||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.EquinePredicates;
|
||||
import com.minelittlepony.unicopia.Owned;
|
||||
import com.minelittlepony.unicopia.USounds;
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.compat.trinkets.TrinketsDelegate;
|
||||
|
@ -113,15 +114,10 @@ public class FriendshipBraceletItem extends WearableItem implements DyeableItem,
|
|||
&& ((FriendshipBraceletItem)stack.getItem()).checkSignature(stack, player);
|
||||
}
|
||||
|
||||
public static boolean isComrade(Caster<?> caster, Entity entity) {
|
||||
if (entity instanceof LivingEntity) {
|
||||
return caster.getMasterId()
|
||||
.filter(id -> getWornBangles((LivingEntity)entity)
|
||||
.anyMatch(stack -> isSignedBy(stack, id))
|
||||
)
|
||||
.isPresent();
|
||||
}
|
||||
return false;
|
||||
public static boolean isComrade(Owned<?> caster, Entity entity) {
|
||||
return entity instanceof LivingEntity l && caster.getMasterId()
|
||||
.filter(id -> getWornBangles(l).anyMatch(stack -> isSignedBy(stack, id)))
|
||||
.isPresent();
|
||||
}
|
||||
|
||||
public static Stream<Pony> getPartyMembers(Caster<?> caster, double radius) {
|
||||
|
|
Loading…
Reference in a new issue