mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-23 21:38:00 +01:00
Configure skeletons to target flying players over players on the ground, and fire at them with more accuracy
This commit is contained in:
parent
5d4c0d0dd0
commit
b4126b839b
6 changed files with 112 additions and 1 deletions
|
@ -17,6 +17,8 @@ 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.FleeExplosionGoal;
|
||||
import com.minelittlepony.unicopia.entity.ai.PrioritizedActiveTargetGoal;
|
||||
import com.minelittlepony.unicopia.entity.ai.TargettingUtil;
|
||||
import com.minelittlepony.unicopia.entity.ai.WantItTakeItGoal;
|
||||
import com.minelittlepony.unicopia.entity.mob.UEntityAttributes;
|
||||
|
||||
|
@ -152,6 +154,9 @@ public class Creature extends Living<LivingEntity> implements WeaklyOwned.Mutabl
|
|||
}
|
||||
if (entity.getType().getSpawnGroup() == SpawnGroup.MONSTER) {
|
||||
goals.add(3, new BreakHeartGoal((MobEntity)entity, targetter));
|
||||
if (entity instanceof AbstractSkeletonEntity) {
|
||||
targets.add(1, new PrioritizedActiveTargetGoal<>((MobEntity)entity, PlayerEntity.class, TargettingUtil.FLYING_PREFERRED, true));
|
||||
}
|
||||
}
|
||||
if (entity instanceof PigEntity pig) {
|
||||
eatMuffinGoal = new EatMuffinGoal(pig, targetter);
|
||||
|
|
|
@ -98,7 +98,6 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
|
|||
private final LandingEventHandler landEvent = addTicker(new LandingEventHandler(this));
|
||||
private final Enchantments enchants = addTicker(new Enchantments(this));
|
||||
private final ItemTracker armour = addTicker(new ItemTracker(this));
|
||||
//private final Transportation<T> transportation = new Transportation<>(this);
|
||||
private final Transportation<T> transportation = new Transportation<>(this);
|
||||
|
||||
protected Living(T entity, TrackedData<NbtCompound> effect) {
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
package com.minelittlepony.unicopia.entity.ai;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.function.Predicate;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.ai.goal.ActiveTargetGoal;
|
||||
import net.minecraft.entity.mob.MobEntity;
|
||||
|
||||
public class PrioritizedActiveTargetGoal<T extends LivingEntity> extends ActiveTargetGoal<T> {
|
||||
|
||||
private final Comparator<T> prioritySorting;
|
||||
|
||||
public PrioritizedActiveTargetGoal(MobEntity mob, Class<T> targetClass, Comparator<T> prioritySorting, boolean checkVisibility) {
|
||||
super(mob, targetClass, checkVisibility);
|
||||
this.prioritySorting = prioritySorting;
|
||||
}
|
||||
|
||||
public PrioritizedActiveTargetGoal(MobEntity mob, Class<T> targetClass, Comparator<T> prioritySorting, boolean checkVisibility, Predicate<LivingEntity> targetPredicate) {
|
||||
super(mob, targetClass, 10, checkVisibility, false, targetPredicate);
|
||||
this.prioritySorting = prioritySorting;
|
||||
}
|
||||
|
||||
public PrioritizedActiveTargetGoal(MobEntity mob, Class<T> targetClass, Comparator<T> prioritySorting, boolean checkVisibility, boolean checkCanNavigate) {
|
||||
super(mob, targetClass, 10, checkVisibility, checkCanNavigate, null);
|
||||
this.prioritySorting = prioritySorting;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void findClosestTarget() {
|
||||
targetEntity = TargettingUtil.getTargets(targetClass, targetPredicate, mob, getSearchBox(getFollowRange()))
|
||||
.sorted(prioritySorting.thenComparing(TargettingUtil.nearestTo(mob)))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package com.minelittlepony.unicopia.entity.ai;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.ai.TargetPredicate;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.util.math.Box;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
public interface TargettingUtil {
|
||||
Comparator<PlayerEntity> FLYING_PREFERRED = Comparator.comparing(e -> Pony.of(e).getPhysics().isFlying() ? 0 : 1);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
static <T extends LivingEntity> Stream<T> getTargets(Class<T> type, TargetPredicate predicate, LivingEntity subject, Box searchArea) {
|
||||
if (type == PlayerEntity.class || type == ServerPlayerEntity.class) {
|
||||
return (Stream<T>)subject.getWorld().getPlayers(predicate, subject, searchArea).stream();
|
||||
}
|
||||
return subject.getWorld().getTargets(type, predicate, subject, searchArea).stream();
|
||||
}
|
||||
|
||||
static <T extends Entity> Comparator<T> nearestTo(LivingEntity subject) {
|
||||
Vec3d fromPos = subject.getEyePos();
|
||||
return Comparator.comparing(e -> fromPos.distanceTo(e.getPos()));
|
||||
}
|
||||
|
||||
static Vec3d getProjectedPos(LivingEntity entity) {
|
||||
if (entity instanceof PlayerEntity player) {
|
||||
Vec3d velocity = Pony.of(player).getPhysics().getClientVelocity();
|
||||
System.out.println(velocity);
|
||||
return entity.getEyePos().add(velocity.multiply(1.5)).add(0, -1, 0);
|
||||
}
|
||||
return entity.getEyePos().add(entity.getVelocity());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package com.minelittlepony.unicopia.mixin;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||
|
||||
import com.minelittlepony.unicopia.entity.ai.TargettingUtil;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.mob.AbstractSkeletonEntity;
|
||||
import net.minecraft.entity.mob.HostileEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.projectile.PersistentProjectileEntity;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
@Mixin(AbstractSkeletonEntity.class)
|
||||
abstract class MixinAbstractSkeletonEntity extends HostileEntity {
|
||||
MixinAbstractSkeletonEntity() { super(null, null); }
|
||||
|
||||
@ModifyArg(method = "attack", at = @At(value = "INVOKE", target = "net/minecraft/world/World.spawnEntity(Lnet/minecraft/entity/Entity;)Z"))
|
||||
private Entity modifyAccuracy(Entity entity) {
|
||||
if (entity instanceof PersistentProjectileEntity projectile && getTarget() instanceof PlayerEntity player && Pony.of(player).getPhysics().isFlying()) {
|
||||
Vec3d targetPos = TargettingUtil.getProjectedPos(player)
|
||||
.add(0, player.getHeight() * 0.33333F, 0)
|
||||
.subtract(projectile.getPos());
|
||||
projectile.setVelocity(targetPos.x, targetPos.y + targetPos.horizontalLength() * 0.2, targetPos.z, 1.6F, (14 - getWorld().getDifficulty().getId() * 4) * 0.25F);
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@
|
|||
"compatibilityLevel": "JAVA_17",
|
||||
"mixins": [
|
||||
"MixinAbstractDecorationEntity",
|
||||
"MixinAbstractSkeletonEntity",
|
||||
"MixinBlazeEntity",
|
||||
"MixinBlock",
|
||||
"MixinBlockEntity",
|
||||
|
|
Loading…
Reference in a new issue