/* * This file is part of EchoPet. * * EchoPet is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * EchoPet is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with EchoPet. If not, see <http://www.gnu.org/licenses/>. */ package com.dsh105.echopet.api; import com.dsh105.commodus.StringUtil; import com.dsh105.echopet.compat.api.ai.*; import com.dsh105.echopet.compat.api.entity.IPet; import com.dsh105.echopet.compat.api.entity.PetData; import com.dsh105.echopet.compat.api.entity.PetType; import com.dsh105.echopet.compat.api.plugin.EchoPet; import com.dsh105.echopet.compat.api.reflection.SafeConstructor; import com.dsh105.echopet.compat.api.util.Lang; import com.dsh105.echopet.compat.api.util.MenuUtil; import com.dsh105.echopet.compat.api.util.ReflectionUtil; import com.dsh105.echopet.compat.api.util.menu.MenuOption; import com.dsh105.echopet.compat.api.util.menu.PetMenu; import com.dsh105.echopet.compat.api.util.menu.SelectorLayout; import org.bukkit.Location; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import java.util.ArrayList; public class EchoPetAPI { private static EchoPetAPI instance; public static EchoPetAPI getAPI() { if (instance == null) { instance = new EchoPetAPI(); } return instance; } /** * Gives a {@link com.dsh105.echopet.api.pet.Pet} to the specified {@link Player} * <p/> * Pets will be spawned immediately next to the target player, linked until it is removed. * * @param player the {@link org.bukkit.entity.Player} that will be provided with a {@link * com.dsh105.echopet.api.pet.Pet} * @param petType the {@link com.dsh105.echopet.compat.api.entity.PetType} (type of {@link * com.dsh105.echopet.api.pet.Pet}) that will be given to the player * @param sendMessage defines if the plugin sends a message to the target {@link Player} * @return the {@link com.dsh105.echopet.api.pet.Pet} created */ public IPet givePet(Player player, PetType petType, boolean sendMessage) { if (player != null && petType != null) { IPet pet = EchoPet.getManager().createPet(player, petType, sendMessage); if (pet == null) { EchoPet.LOG.severe("Failed to give " + petType.toString() + " to " + player.getName() + " through the EchoPetAPI. Maybe this PetType is disabled in the Config.yml?"); return null; } if (sendMessage) { Lang.sendTo(player, Lang.CREATE_PET.toString().replace("%type%", StringUtil.capitalise(petType.toString()))); } return pet; } return null; } /** * Removes a {@link com.dsh105.echopet.api.pet.Pet} if the {@link org.bukkit.entity.Player} has one active * * @param player the {@link org.bukkit.entity.Player} to remove their {@link com.dsh105.echopet.api.pet.Pet} * from * @param sendMessage defines if the plugin sends a message to the target {@link org.bukkit.entity.Player} */ public void removePet(Player player, boolean sendMessage, boolean save) { EchoPet.getManager().removePets(player, true); if (save) { if (hasPet(player)) { EchoPet.getManager().saveFileData("autosave", EchoPet.getManager().getPet(player)); EchoPet.getSqlManager().saveToDatabase(EchoPet.getManager().getPet(player), false); } } if (sendMessage) { Lang.sendTo(player, Lang.REMOVE_PET.toString()); } } /** * Checks if a {@link org.bukkit.entity.Player} has a {@link com.dsh105.echopet.api.pet.Pet} * * @param player the {@link org.bukkit.entity.Player} used to check for {@link com.dsh105.echopet.api.pet.Pet} * @return true if {@link org.bukkit.entity.Player} has a {@link com.dsh105.echopet.api.pet.Pet}, false if not */ public boolean hasPet(Player player) { return EchoPet.getManager().getPet(player) != null; } /** * Gets a {@link org.bukkit.entity.Player}'s {@link com.dsh105.echopet.api.pet.Pet} * * @param player the {@link org.bukkit.entity.Player} to get the {@link com.dsh105.echopet.api.pet.Pet} of * @return the {@link com.dsh105.echopet.api.pet.Pet} instance linked to the {@link org.bukkit.entity.Player} */ public IPet getPet(Player player) { return EchoPet.getManager().getPet(player); } /** * Gets all active {@link com.dsh105.echopet.api.pet.Pet} * * @return an array of all active {@link com.dsh105.echopet.api.pet.Pet}s */ public IPet[] getAllPets() { ArrayList<IPet> pets = EchoPet.getManager().getPets(); return pets.toArray(new IPet[pets.size()]); } /** * Teleports a {@link com.dsh105.echopet.api.pet.Pet} to a {@link org.bukkit.Location} * * @param pet the {@link com.dsh105.echopet.api.pet.Pet} to be teleported * @param location the {@link org.bukkit.Location} to teleport the {@link com.dsh105.echopet.api.pet.Pet} to * @return success of teleportation */ public boolean teleportPet(IPet pet, Location location) { if (pet == null) { EchoPet.LOG.severe("Failed to teleport Pet to Location through the EchoPetAPI. {@link com.dsh105.echopet.api.pet.Pet} cannot be null."); return false; } if (pet.isHat() || pet.isOwnerRiding()) { return false; } return pet.teleport(location); } /** * Save a {@link com.dsh105.echopet.api.pet.Pet} to file or an SQL Database * * @param pet {@link com.dsh105.echopet.api.pet.Pet} to be saved * @param saveType whether to save to file or SQL database * @return success of save */ public boolean savePet(IPet pet, SaveType saveType) { if (pet == null) { EchoPet.LOG.severe("Failed to save Pet file through the EchoPetAPI. Pet cannot be null."); return false; } if (saveType == SaveType.SQL) { EchoPet.getSqlManager().saveToDatabase(pet, false); } else if (saveType == SaveType.FILE) { EchoPet.getManager().saveFileData("autosave", pet); } return true; } /** * Adds {@link com.dsh105.echopet.compat.api.entity.PetData} to a {@link com.dsh105.echopet.api.pet.Pet} * * @param pet the {@link com.dsh105.echopet.api.pet.Pet} to add the data to * @param petData {@link com.dsh105.echopet.compat.api.entity.PetData} to add to the {@link * com.dsh105.echopet.api.pet.Pet} */ public void addData(IPet pet, PetData petData) { if (pet == null) { EchoPet.LOG.severe("Failed to add PetData [" + petData.toString() + "] to Pet through the EchoPetAPI. Pet cannot be null."); return; } EchoPet.getManager().setData(pet, new PetData[]{petData}, true); } /** * Removes {@link PetData} from a {@link com.dsh105.echopet.api.pet.Pet} * * @param pet the {@link com.dsh105.echopet.api.pet.Pet} to remove the data from * @param petData {@link PetData} to remove to the {@link com.dsh105.echopet.api.pet.Pet} */ public void removeData(IPet pet, PetData petData) { if (pet == null) { EchoPet.LOG.severe("Failed to remove PetData [" + petData.toString() + "] from Pet through the EchoPetAPI. Pet cannot be null."); return; } EchoPet.getManager().setData(pet, new PetData[]{petData}, false); } /** * Checks if a {@link com.dsh105.echopet.api.pet.Pet} has specific {@link PetData} * * @param pet the {@link com.dsh105.echopet.api.pet.Pet} to search * @param petData the {@link PetData} searched for in the {@link com.dsh105.echopet.api.pet.Pet} instance * @return true if the {@link com.dsh105.echopet.api.pet.Pet} has the specified {@link PetData} */ public boolean hasData(IPet pet, PetData petData) { if (pet == null) { EchoPet.LOG.severe("Failed to check PetData [" + petData.toString() + "] of Pet through the EchoPetAPI. Pet cannot be null."); return false; } return pet.getPetData().contains(petData); } /** * Opens the Pet Selector GUI Menu * * @param player {@link org.bukkit.entity.Player} to view the Menu * @param sendMessage defines if the plugin sends a message to the target {@link org.bukkit.entity.Player} */ public void openPetSelector(Player player, boolean sendMessage) { SelectorLayout.getSelectorMenu().showTo(player); if (false) { Lang.sendTo(player, Lang.OPEN_SELECTOR.toString()); } } /** * Opens the Pet Selector GUI Menu * * @param player {@link org.bukkit.entity.Player} to view the menu */ public void openPetSelector(Player player) { this.openPetSelector(player, false); } /** * Opens the Pet Data GUI Menu * * @param player {@link org.bukkit.entity.Player} to view the Menu * @param sendMessage defines if the plugin sends a message to the target {@link org.bukkit.entity.Player} */ public void openPetDataMenu(Player player, boolean sendMessage) { IPet pet = EchoPet.getManager().getPet(player); if (pet == null) { return; } ArrayList<MenuOption> options = MenuUtil.createOptionList(pet.getPetType()); PetMenu menu = new PetMenu(pet, options, pet.getPetType() == PetType.HORSE ? 18 : 9); menu.open(sendMessage); } /** * Opens the Pet Data GUI Menu * * @param player {@link org.bukkit.entity.Player} to view the menu */ public void openPetDataMenu(Player player) { this.openPetDataMenu(player, false); } /** * Set a target for the {@link com.dsh105.echopet.api.pet.Pet} to attack * * @param pet the attacker * @param target the {@link org.bukkit.entity.LivingEntity} for the {@link com.dsh105.echopet.api.pet.Pet} to * attack */ public void setAttackTarget(IPet pet, LivingEntity target) { if (pet == null) { EchoPet.LOG.severe("Failed to set attack target for Pet through the EchoPetAPI. Pet cannot be null."); return; } if (target == null) { EchoPet.LOG.severe("Failed to set attack target for Pet through the EchoPetAPI. Target cannot be null."); return; } if (pet.getEntityPet().getPetGoalSelector().getGoal("Attack") != null) { pet.getCraftPet().setTarget(target); } } /** * Get the {@link org.bukkit.entity.LivingEntity} that a {@link com.dsh105.echopet.api.pet.Pet} is targeting * * @param pet the attacker * @return {@link org.bukkit.entity.LivingEntity} being attacked, null if none */ public LivingEntity getAttackTarget(IPet pet) { if (pet == null) { EchoPet.LOG.severe("Failed to get attack target for Pet through the EchoPetAPI. Pet cannot be null."); } return pet.getCraftPet().getTarget(); } /** * Add a predefined {@link com.dsh105.echopet.compat.api.ai.PetGoal} to a {@link com.dsh105.echopet.api.pet.Pet} * from the API * * @param pet the {@link com.dsh105.echopet.api.pet.Pet} to add the goal to * @param goalType type of goal */ public void addGoal(IPet pet, GoalType goalType) { if (pet == null) { EchoPet.LOG.severe("Failed to add PetGoal to Pet AI through the EchoPetAPI. Pet cannot be null."); return; } if (goalType == GoalType.ATTACK) { pet.getEntityPet().getPetGoalSelector().addGoal(new SafeConstructor<APetGoalMeleeAttack>(ReflectionUtil.getVersionedClass("entity.ai.PetGoalMeleeAttack"), ReflectionUtil.getVersionedClass("entity.EntityPet"), double.class, int.class).newInstance(pet.getEntityPet(), EchoPet.getConfig().getDouble("attack.lockRange", 0.0D), EchoPet.getConfig().getInt("attack.ticksBetweenAttacks", 20)), 3); } else if (goalType == GoalType.FLOAT) { pet.getEntityPet().getPetGoalSelector().addGoal(new SafeConstructor<APetGoalFloat>(ReflectionUtil.getVersionedClass("entity.ai.PetGoalFloat"), ReflectionUtil.getVersionedClass("entity.EntityPet")).newInstance(pet.getEntityPet()), 0); } else if (goalType == GoalType.FOLLOW_OWNER) { pet.getEntityPet().getPetGoalSelector().addGoal(new SafeConstructor<APetGoalFollowOwner>(ReflectionUtil.getVersionedClass("entity.ai.PetGoalFollowOwner"), ReflectionUtil.getVersionedClass("entity.EntityPet"), double.class, double.class, double.class).newInstance(pet.getEntityPet(), pet.getEntityPet().getSizeCategory().getStartWalk(pet.getPetType()), pet.getEntityPet().getSizeCategory().getStopWalk(pet.getPetType()), pet.getEntityPet().getSizeCategory().getTeleport(pet.getPetType())), 1); } else if (goalType == GoalType.LOOK_AT_PLAYER) { pet.getEntityPet().getPetGoalSelector().addGoal(new SafeConstructor<APetGoalLookAtPlayer>(ReflectionUtil.getVersionedClass("entity.ai.PetGoalLookAtPlayer"), ReflectionUtil.getVersionedClass("entity.EntityPet"), Class.class, float.class).newInstance(pet.getEntityPet(), ReflectionUtil.getNMSClass("EntityHuman"), 8.0F), 2); } } /** * Add an implementation of {@link com.dsh105.echopet.compat.api.ai.PetGoal} to a {@link * com.dsh105.echopet.api.pet.Pet} * * @param pet the {@link com.dsh105.echopet.api.pet.Pet} to add the {@link com.dsh105.echopet.compat.api.ai.PetGoal} * to * @param goal the {@link com.dsh105.echopet.compat.api.ai.PetGoal} to add * @param identifier a {@link java.lang.String} to identify the goal */ public void addGoal(IPet pet, PetGoal goal, String identifier, int priority) { if (pet == null) { EchoPet.LOG.severe("Failed to add PetGoal to Pet AI through the EchoPetAPI. Pet cannot be null."); return; } if (goal == null) { EchoPet.LOG.severe("Failed to add PetGoal to Pet AI through the EchoPetAPI. Goal cannot be null."); return; } pet.getEntityPet().getPetGoalSelector().addGoal(identifier, goal, priority); } /** * Remove a predefined goal from a {@link com.dsh105.echopet.api.pet.Pet}'s AI * * @param pet {@link com.dsh105.echopet.api.pet.Pet} to remove the goal from * @param goalType type of goal */ public void removeGoal(IPet pet, GoalType goalType) { if (pet == null) { EchoPet.LOG.severe("Failed to remove PetGoal from Pet AI through the EchoPetAPI. Pet cannot be null."); return; } pet.getEntityPet().getPetGoalSelector().removeGoal(goalType.getGoalString()); } /** * Remove a goal from a {@link com.dsh105.echopet.api.pet.Pet}'s AI * <p/> * The goal is identified using a string, initiated when the goal is added to the {@link * com.dsh105.echopet.api.pet.Pet} * * @param pet {@link com.dsh105.echopet.api.pet.Pet} to remove the goal from * @param identifier String that identifies a {@link com.dsh105.echopet.compat.api.ai.PetGoal} */ public void removeGoal(IPet pet, String identifier) { if (pet == null) { EchoPet.LOG.severe("Failed to remove PetGoal from Pet AI through the EchoPetAPI. Pet cannot be null."); return; } pet.getEntityPet().getPetGoalSelector().removeGoal(identifier); } /** * Remove a goal from a {@link com.dsh105.echopet.api.pet.Pet}'s AI * * @param pet {@link com.dsh105.echopet.api.pet.Pet} to remove the goal from * @param petGoal {@link com.dsh105.echopet.compat.api.ai.PetGoal} to remove */ public void removeGoal(IPet pet, PetGoal petGoal) { if (pet == null) { EchoPet.LOG.severe("Failed to remove PetGoal from Pet AI through the EchoPetAPI. Pet cannot be null."); return; } if (petGoal == null) { EchoPet.LOG.severe("Failed to remove PetGoal from Pet AI through the EchoPetAPI. Goal cannot be null."); return; } pet.getEntityPet().getPetGoalSelector().removeGoal(petGoal); } /** * {@link Enum} of predefined {@link com.dsh105.echopet.compat.api.ai.PetGoal}s */ public enum GoalType { ATTACK("Attack"), FLOAT("Float"), FOLLOW_OWNER("Float"), LOOK_AT_PLAYER("LookAtPlayer"); private String goalString; GoalType(String goalString) { this.goalString = goalString; } public String getGoalString() { return this.goalString; } } /** * Types used for saving {@link com.dsh105.echopet.api.pet.Pet}s */ public enum SaveType { SQL, FILE } }