package de.tobiyas.racesandclasses.pets; import java.util.EnumMap; import java.util.HashSet; import org.bukkit.Location; import org.bukkit.entity.Ageable; import org.bukkit.entity.Creature; import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Tameable; import org.bukkit.metadata.FixedMetadataValue; import de.tobiyas.racesandclasses.RacesAndClasses; import de.tobiyas.racesandclasses.pets.target.EntityAttackTarget; import de.tobiyas.racesandclasses.pets.target.LocationTarget; import de.tobiyas.racesandclasses.pets.target.OwnerTarget; import de.tobiyas.racesandclasses.pets.target.Target; import de.tobiyas.racesandclasses.pets.target.Target.TargetType; import de.tobiyas.racesandclasses.playermanagement.player.RaCPlayer; public class SpawnedPet { /** * The pet that should be spawned. */ private final Pet pet; /** * The Owner of the Pet. */ private final RaCPlayer owner; /** * The Pet. */ private Entity petEntity; /** * The Enum Map for Targets. */ private final EnumMap<Target.TargetType, Target> targets = new EnumMap<>(Target.TargetType.class); public SpawnedPet(Pet pet, RaCPlayer owner) { this.pet = pet; this.owner = owner; targets.put(TargetType.Owner, new OwnerTarget(owner)); } /** * Despawns the Pet. */ public void despawn(){ if(petEntity != null) { petEntity.remove(); petEntity.removeMetadata("pet", RacesAndClasses.getPlugin()); } petEntity = null; } /** * Spawns the Pet. */ public boolean spawnAt(Location location){ if(petEntity != null) despawn(); petEntity = location.getWorld().spawnEntity(location, pet.getPetType()); if(petEntity != null){ petEntity.setMetadata("pet", new FixedMetadataValue(RacesAndClasses.getPlugin(), this)); //Living Entity. if(petEntity instanceof LivingEntity){ LivingEntity livingPet = (LivingEntity) petEntity; livingPet.setMaxHealth(pet.getPetMaxHealth()); } //Tameable. if(petEntity instanceof Tameable){ Tameable tameable = (Tameable) petEntity; tameable.setOwner(owner.getRealPlayer()); } //Set baby or not. if(petEntity instanceof Ageable){ Ageable ageable = (Ageable) petEntity; if(pet.isBaby()) ageable.setBaby(); else ageable.setAdult(); } //Name stuff petEntity.setCustomName(pet.getPetName()); petEntity.setCustomNameVisible(true); //Targeting revalidateTarget(); } return petEntity != null && petEntity.isValid(); } public Pet getPet() { return pet; } public Entity getPetEntity() { return petEntity; } public RaCPlayer getOwner() { return owner; } /** * Sets the new Target. * * @param currentTarget to set. */ public void setCurrentTarget(LivingEntity currentTarget) { if(currentTarget == null && isSpawned() && (petEntity instanceof Creature)) { ((Creature)petEntity).setTarget(null); return; } targets.put(TargetType.Entity, new EntityAttackTarget(currentTarget)); revalidateTarget(); } /** * If the Pet is spawned. * * @return true if spawned. */ public boolean isSpawned() { return petEntity != null && petEntity.isValid(); } /** * Sets the new Current target. * * @param newLocation to set. */ public void setNewCurrentTargetLocation(Location newLocation) { this.targets.put(TargetType.Location, new LocationTarget(newLocation)); revalidateTarget(); } /** * Shows the current Target to the Owner. */ public void showCurrentTargetToOwner(){ Target target = getTarget(); if(target != null) target.showToOwner(owner); } /** * Revalidates the current Target. */ public void revalidateTarget(){ if(!isSpawned()) return; Target current = getTarget(); if(current != null) current.setTarget((LivingEntity) getPetEntity()); } /** * Returns the current target. * * @return the current Target or null if entity == null */ public Target getTarget(){ if(!isSpawned()) return null; for(Target target : new HashSet<Target>(targets.values())){ if(!target.valid(this)) { targets.remove(target.getType()); } } int prio = 0; Target current = null; for(Target target : new HashSet<Target>(targets.values())){ if(target.getPriority() > prio) { current = target; prio = target.getPriority(); } } return current; } /** * Returns the Distance to the Owner. * @return the distance to the Owner. */ public double getDistanceToOwner() { if(!owner.isOnline()) return Double.MAX_VALUE; if(!isSpawned()) return Double.MAX_VALUE; if(owner.getWorld() != petEntity.getWorld()) return Double.MAX_VALUE; return owner.getLocation().distance(petEntity.getLocation()); } }