mirror of
https://github.com/Sollace/Unicopia.git
synced 2025-03-28 13:57:46 +01:00
134 lines
3.9 KiB
Java
134 lines
3.9 KiB
Java
package com.minelittlepony.unicopia.entity;
|
|
|
|
import java.util.EnumSet;
|
|
|
|
import com.minelittlepony.unicopia.magic.Caster;
|
|
|
|
import net.minecraft.block.BlockState;
|
|
import net.minecraft.entity.LivingEntity;
|
|
import net.minecraft.entity.ai.goal.Goal;
|
|
import net.minecraft.entity.ai.pathing.BirdNavigation;
|
|
import net.minecraft.entity.ai.pathing.EntityNavigation;
|
|
import net.minecraft.entity.ai.pathing.MobNavigation;
|
|
import net.minecraft.entity.ai.pathing.PathNodeType;
|
|
import net.minecraft.entity.mob.MobEntity;
|
|
import net.minecraft.entity.player.PlayerEntity;
|
|
import net.minecraft.util.math.BlockPos;
|
|
import net.minecraft.util.math.MathHelper;
|
|
import net.minecraft.world.WorldView;
|
|
|
|
public class FollowCasterGoal<T extends MobEntity> extends Goal {
|
|
|
|
protected final Caster<?> caster;
|
|
|
|
protected final MobEntity entity;
|
|
|
|
protected LivingEntity owner;
|
|
|
|
protected final WorldView world;
|
|
|
|
public final double followSpeed;
|
|
|
|
private final EntityNavigation navigation;
|
|
|
|
private int timeout;
|
|
|
|
public float maxDistance;
|
|
public float minDistance;
|
|
|
|
private float oldWaterCost;
|
|
|
|
public FollowCasterGoal(Caster<T> caster, double followSpeed, float minDist, float maxDist) {
|
|
this.caster = caster;
|
|
|
|
this.entity = (MobEntity)caster.getEntity();
|
|
this.world = caster.getWorld();
|
|
|
|
this.followSpeed = followSpeed;
|
|
navigation = entity.getNavigation();
|
|
minDistance = minDist;
|
|
maxDistance = maxDist;
|
|
setControls(EnumSet.of(Goal.Control.MOVE, Goal.Control.LOOK));
|
|
|
|
if (!(navigation instanceof MobNavigation || navigation instanceof BirdNavigation)) {
|
|
throw new IllegalArgumentException("Unsupported mob type for FollowCasterGoal");
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean canStart() {
|
|
LivingEntity owner = caster.getOwner();
|
|
|
|
if (owner == null
|
|
|| (owner instanceof PlayerEntity && ((PlayerEntity)owner).isSpectator())
|
|
|| entity.squaredDistanceTo(owner) < (minDistance * minDistance)) {
|
|
return false;
|
|
}
|
|
|
|
this.owner = owner;
|
|
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean shouldContinue() {
|
|
return !navigation.isIdle()
|
|
&& entity.squaredDistanceTo(owner) > (maxDistance * maxDistance);
|
|
}
|
|
|
|
@Override
|
|
public void start() {
|
|
timeout = 0;
|
|
oldWaterCost = entity.getPathfindingPenalty(PathNodeType.WATER);
|
|
entity.setPathfindingPenalty(PathNodeType.WATER, 0);
|
|
}
|
|
|
|
@Override
|
|
public void stop() {
|
|
owner = null;
|
|
navigation.stop();
|
|
entity.setPathfindingPenalty(PathNodeType.WATER, oldWaterCost);
|
|
}
|
|
|
|
@Override
|
|
public void tick() {
|
|
entity.getLookControl().lookAt(owner, 10, entity.getLookPitchSpeed());
|
|
|
|
if (--timeout > 0) {
|
|
return;
|
|
}
|
|
|
|
timeout = 10;
|
|
|
|
if (navigation.startMovingTo(owner, followSpeed)
|
|
|| entity.isLeashed()
|
|
|| entity.hasVehicle()
|
|
|| entity.squaredDistanceTo(owner) < 144) {
|
|
return;
|
|
}
|
|
|
|
int x = MathHelper.floor(owner.getX()) - 2;
|
|
int y = MathHelper.floor(owner.getBoundingBox().y1);
|
|
int z = MathHelper.floor(owner.getZ()) - 2;
|
|
|
|
for (int offX = 0; offX <= 4; offX++) {
|
|
for (int offZ = 0; offZ <= 4; offZ++) {
|
|
if ((offX < 1 || offZ < 1 || offX > 3 || offZ > 3) && canMoveInto(new BlockPos(x + offX, y - 1, z + offZ))) {
|
|
|
|
entity.updatePositionAndAngles((x + offX) + 0.5F, y, (z + offZ) + 0.5F, entity.headYaw, entity.pitch);
|
|
navigation.stop();
|
|
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
protected boolean canMoveInto(BlockPos pos) {
|
|
BlockState state = world.getBlockState(pos);
|
|
|
|
return state.allowsSpawning(world, pos, entity.getType())
|
|
&& world.isAir(pos.up())
|
|
&& world.isAir(pos.up(2));
|
|
}
|
|
}
|