125 lines
4.1 KiB
Java
125 lines
4.1 KiB
Java
package com.yaohun.petsystem.util.wolf;
|
|
|
|
import com.yaohun.petsystem.PetMain;
|
|
import com.yaohun.petsystem.model.PetNbt;
|
|
import org.bukkit.Bukkit;
|
|
import org.bukkit.Location;
|
|
import org.bukkit.attribute.Attribute;
|
|
import org.bukkit.attribute.AttributeInstance;
|
|
import org.bukkit.block.Block;
|
|
import org.bukkit.entity.LivingEntity;
|
|
import org.bukkit.entity.Player;
|
|
import org.bukkit.entity.Wolf;
|
|
import org.bukkit.scheduler.BukkitRunnable;
|
|
|
|
import java.util.UUID;
|
|
|
|
public class CustomWolf {
|
|
|
|
private static final double STOP_DISTANCE_SQ = 9.0D;
|
|
private static final double TELEPORT_DISTANCE_SQ = 144.0D;
|
|
private static final double FOLLOW_SPEED = 1.2D;
|
|
private static final double DEFAULT_MOVEMENT_SPEED = 0.4D;
|
|
private static final long FOLLOW_INTERVAL_TICKS = 10L;
|
|
|
|
private final UUID ownerUuid;
|
|
private final Wolf wolf;
|
|
|
|
private CustomWolf(UUID ownerUuid, Wolf wolf) {
|
|
this.ownerUuid = ownerUuid;
|
|
this.wolf = wolf;
|
|
startFollowTask();
|
|
}
|
|
|
|
public Wolf getBukkitEntity() {
|
|
return wolf;
|
|
}
|
|
|
|
public LivingEntity getBukkitLivingEntity() {
|
|
return wolf;
|
|
}
|
|
|
|
public UUID getUUID() {
|
|
return wolf.getUniqueId();
|
|
}
|
|
|
|
public boolean isRemoved() {
|
|
return !wolf.isValid();
|
|
}
|
|
|
|
public static CustomWolf spawnCustomWolf(Player owner, PetNbt petNbt) {
|
|
Wolf wolf = owner.getWorld().spawn(owner.getLocation(), Wolf.class, entity -> {
|
|
entity.setSilent(true);
|
|
entity.setTamed(true);
|
|
entity.setOwner(owner);
|
|
entity.setSitting(false);
|
|
entity.setRemoveWhenFarAway(false);
|
|
|
|
double maxHealth = Math.max(1.0D, petNbt.maxHealth);
|
|
double health = Math.max(1.0D, Math.min(petNbt.health, maxHealth));
|
|
double damage = Math.max(0.0D, petNbt.damage);
|
|
|
|
setAttribute(entity, Attribute.MAX_HEALTH, maxHealth);
|
|
setAttribute(entity, Attribute.MOVEMENT_SPEED, DEFAULT_MOVEMENT_SPEED);
|
|
setAttribute(entity, Attribute.ATTACK_DAMAGE, damage);
|
|
entity.setHealth(health);
|
|
});
|
|
return new CustomWolf(owner.getUniqueId(), wolf);
|
|
}
|
|
|
|
private void startFollowTask() {
|
|
new BukkitRunnable() {
|
|
@Override
|
|
public void run() {
|
|
if (!wolf.isValid() || wolf.isDead()) {
|
|
cancel();
|
|
return;
|
|
}
|
|
Player owner = Bukkit.getPlayer(ownerUuid);
|
|
if (owner == null || !owner.isOnline()) {
|
|
wolf.remove();
|
|
cancel();
|
|
return;
|
|
}
|
|
if (owner.isDead()) {
|
|
wolf.setTarget(null);
|
|
return;
|
|
}
|
|
if (!owner.getWorld().equals(wolf.getWorld())) {
|
|
teleportToOwner(owner);
|
|
return;
|
|
}
|
|
double distanceSq = wolf.getLocation().distanceSquared(owner.getLocation());
|
|
if (distanceSq < STOP_DISTANCE_SQ) {
|
|
wolf.setTarget(null);
|
|
return;
|
|
}
|
|
if (distanceSq > TELEPORT_DISTANCE_SQ) {
|
|
teleportToOwner(owner);
|
|
}
|
|
}
|
|
}.runTaskTimer(PetMain.inst(), FOLLOW_INTERVAL_TICKS, FOLLOW_INTERVAL_TICKS);
|
|
}
|
|
|
|
private void teleportToOwner(Player owner) {
|
|
Location location = owner.getLocation();
|
|
if (isSafeTeleportLocation(location)) {
|
|
wolf.teleport(location);
|
|
}
|
|
}
|
|
|
|
private boolean isSafeTeleportLocation(Location location) {
|
|
Block feet = location.getBlock();
|
|
Block head = feet.getRelative(0, 1, 0);
|
|
Block ground = feet.getRelative(0, -1, 0);
|
|
return feet.isPassable() && head.isPassable() && ground.getType().isSolid();
|
|
}
|
|
|
|
private static void setAttribute(LivingEntity entity, Attribute attribute, double value) {
|
|
AttributeInstance instance = entity.getAttribute(attribute);
|
|
if (instance != null) {
|
|
instance.setBaseValue(value);
|
|
}
|
|
}
|
|
}
|