mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-27 15:17:59 +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.DynamicTargetGoal;
|
||||||
import com.minelittlepony.unicopia.entity.ai.EatMuffinGoal;
|
import com.minelittlepony.unicopia.entity.ai.EatMuffinGoal;
|
||||||
import com.minelittlepony.unicopia.entity.ai.FleeExplosionGoal;
|
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.ai.WantItTakeItGoal;
|
||||||
import com.minelittlepony.unicopia.entity.mob.UEntityAttributes;
|
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) {
|
if (entity.getType().getSpawnGroup() == SpawnGroup.MONSTER) {
|
||||||
goals.add(3, new BreakHeartGoal((MobEntity)entity, targetter));
|
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) {
|
if (entity instanceof PigEntity pig) {
|
||||||
eatMuffinGoal = new EatMuffinGoal(pig, targetter);
|
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 LandingEventHandler landEvent = addTicker(new LandingEventHandler(this));
|
||||||
private final Enchantments enchants = addTicker(new Enchantments(this));
|
private final Enchantments enchants = addTicker(new Enchantments(this));
|
||||||
private final ItemTracker armour = addTicker(new ItemTracker(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);
|
private final Transportation<T> transportation = new Transportation<>(this);
|
||||||
|
|
||||||
protected Living(T entity, TrackedData<NbtCompound> effect) {
|
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",
|
"compatibilityLevel": "JAVA_17",
|
||||||
"mixins": [
|
"mixins": [
|
||||||
"MixinAbstractDecorationEntity",
|
"MixinAbstractDecorationEntity",
|
||||||
|
"MixinAbstractSkeletonEntity",
|
||||||
"MixinBlazeEntity",
|
"MixinBlazeEntity",
|
||||||
"MixinBlock",
|
"MixinBlock",
|
||||||
"MixinBlockEntity",
|
"MixinBlockEntity",
|
||||||
|
|
Loading…
Reference in a new issue