minecraft-src/net/minecraft/world/entity/ai/goal/LlamaFollowCaravanGoal.java
2025-07-04 01:41:11 +03:00

128 lines
3.5 KiB
Java

package net.minecraft.world.entity.ai.goal;
import java.util.EnumSet;
import java.util.List;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.animal.horse.Llama;
import net.minecraft.world.entity.decoration.LeashFenceKnotEntity;
import net.minecraft.world.phys.Vec3;
public class LlamaFollowCaravanGoal extends Goal {
public final Llama llama;
private double speedModifier;
private static final int CARAVAN_LIMIT = 8;
private int distCheckCounter;
public LlamaFollowCaravanGoal(Llama llama, double speedModifier) {
this.llama = llama;
this.speedModifier = speedModifier;
this.setFlags(EnumSet.of(Goal.Flag.MOVE));
}
@Override
public boolean canUse() {
if (!this.llama.isLeashed() && !this.llama.inCaravan()) {
List<Entity> list = this.llama.level().getEntities(this.llama, this.llama.getBoundingBox().inflate(9.0, 4.0, 9.0), entityx -> {
EntityType<?> entityType = entityx.getType();
return entityType == EntityType.LLAMA || entityType == EntityType.TRADER_LLAMA;
});
Llama llama = null;
double d = Double.MAX_VALUE;
for (Entity entity : list) {
Llama llama2 = (Llama)entity;
if (llama2.inCaravan() && !llama2.hasCaravanTail()) {
double e = this.llama.distanceToSqr(llama2);
if (!(e > d)) {
d = e;
llama = llama2;
}
}
}
if (llama == null) {
for (Entity entityx : list) {
Llama llama2 = (Llama)entityx;
if (llama2.isLeashed() && !llama2.hasCaravanTail()) {
double e = this.llama.distanceToSqr(llama2);
if (!(e > d)) {
d = e;
llama = llama2;
}
}
}
}
if (llama == null) {
return false;
} else if (d < 4.0) {
return false;
} else if (!llama.isLeashed() && !this.firstIsLeashed(llama, 1)) {
return false;
} else {
this.llama.joinCaravan(llama);
return true;
}
} else {
return false;
}
}
@Override
public boolean canContinueToUse() {
if (this.llama.inCaravan() && this.llama.getCaravanHead().isAlive() && this.firstIsLeashed(this.llama, 0)) {
double d = this.llama.distanceToSqr(this.llama.getCaravanHead());
if (d > 676.0) {
if (this.speedModifier <= 3.0) {
this.speedModifier *= 1.2;
this.distCheckCounter = reducedTickDelay(40);
return true;
}
if (this.distCheckCounter == 0) {
return false;
}
}
if (this.distCheckCounter > 0) {
this.distCheckCounter--;
}
return true;
} else {
return false;
}
}
@Override
public void stop() {
this.llama.leaveCaravan();
this.speedModifier = 2.1;
}
@Override
public void tick() {
if (this.llama.inCaravan()) {
if (!(this.llama.getLeashHolder() instanceof LeashFenceKnotEntity)) {
Llama llama = this.llama.getCaravanHead();
double d = this.llama.distanceTo(llama);
float f = 2.0F;
Vec3 vec3 = new Vec3(llama.getX() - this.llama.getX(), llama.getY() - this.llama.getY(), llama.getZ() - this.llama.getZ())
.normalize()
.scale(Math.max(d - 2.0, 0.0));
this.llama.getNavigation().moveTo(this.llama.getX() + vec3.x, this.llama.getY() + vec3.y, this.llama.getZ() + vec3.z, this.speedModifier);
}
}
}
private boolean firstIsLeashed(Llama llama, int leashedQueuePosition) {
if (leashedQueuePosition > 8) {
return false;
} else if (llama.inCaravan()) {
return llama.getCaravanHead().isLeashed() ? true : this.firstIsLeashed(llama.getCaravanHead(), ++leashedQueuePosition);
} else {
return false;
}
}
}