This commit is contained in:
Taylor Becker 2017-12-30 16:35:34 +00:00 committed by GitHub
commit 5a215f746c
1 changed files with 189 additions and 158 deletions

View File

@ -27,6 +27,7 @@ import me.shansen.nbt.NbtReflection;
import org.bukkit.Effect;
import org.bukkit.Material;
import org.bukkit.attribute.Attribute;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.*;
import org.bukkit.event.EventHandler;
@ -40,13 +41,15 @@ import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.File;
import java.util.Objects;
import java.util.Optional;
public class EggCatcherEntityListener implements Listener {
private final boolean usePermissions;
private final boolean useCatchChance;
private final boolean useHealthPercentage;
private final boolean looseEggOnFail;
private final boolean loseEggOnFail;
private final boolean useVaultCost;
private final boolean useItemCost;
private final boolean explosionEffect;
@ -65,8 +68,8 @@ public class EggCatcherEntityListener implements Listener {
private final boolean logCaptures;
FileConfiguration config;
JavaPlugin plugin;
private final File captureLogFile;
private final EggCatcherLogger captureLogger;
private final File captureLogFile;
private final EggCatcherLogger captureLogger;
public EggCatcherEntityListener(JavaPlugin plugin) {
@ -75,7 +78,7 @@ public class EggCatcherEntityListener implements Listener {
this.usePermissions = this.config.getBoolean("UsePermissions", true);
this.useCatchChance = this.config.getBoolean("UseCatchChance", true);
this.useHealthPercentage = this.config.getBoolean("UseHealthPercentage", false);
this.looseEggOnFail = this.config.getBoolean("LooseEggOnFail", true);
this.loseEggOnFail = this.config.getBoolean("LooseEggOnFail", true);
this.useVaultCost = this.config.getBoolean("UseVaultCost", false);
this.useItemCost = this.config.getBoolean("UseItemCost", false);
this.explosionEffect = this.config.getBoolean("ExplosionEffect", true);
@ -92,159 +95,67 @@ public class EggCatcherEntityListener implements Listener {
this.vaultTargetBankAccount = this.config.getString("VaultTargetBankAccount", "");
this.deleteVillagerInventoryOnCatch = this.config.getBoolean("DeleteVillagerInventoryOnCatch", false);
this.logCaptures = this.config.getBoolean("LogEggCaptures", false);
this.captureLogFile = new File(plugin.getDataFolder(), "captures.txt");
this.captureLogger = new EggCatcherLogger(captureLogFile);
}
this.captureLogFile = new File(plugin.getDataFolder(), "captures.txt");
this.captureLogger = new EggCatcherLogger(captureLogFile);
}
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
public void onEntityHitByEgg(EntityDamageEvent event) {
EntityDamageByEntityEvent damageEvent = null;
Egg egg = null;
EggType eggType = null;
double vaultCost = 0.0;
final Entity entity = event.getEntity();
Optional.of(event)
// only capture entity damage by other entities, don't care about block damage
.filter(EntityDamageByEntityEvent.class::isInstance)
.map(EntityDamageByEntityEvent.class::cast)
// egg catcher event restrictions
.filter(this::checkIsEggEvent)
.filter(this::checkAnimalRestrictions)
.map(entityEvent -> new EggCaptureEvent(entity, (Egg) entityEvent.getDamager()))
.ifPresent(eggEvent -> this.plugin.getServer().getPluginManager().callEvent(eggEvent));
}
@EventHandler(ignoreCancelled = true, priority = EventPriority.NORMAL)
public void onEggCaptureEvent(EggCaptureEvent event) {
Egg egg = event.getEgg();
Entity entity = event.getEntity();
if (!(event instanceof EntityDamageByEntityEvent)) {
return;
}
damageEvent = (EntityDamageByEntityEvent) event;
if (!(damageEvent.getDamager() instanceof Egg)) {
return;
}
egg = (Egg) damageEvent.getDamager();
eggType = EggType.getEggType(entity);
if (eggType == null) {
return;
}
EggType eggType = EggType.getEggType(entity);
if (!this.spawnChickenOnFail) {
EggCatcher.eggs.add(egg);
}
if (this.preventCatchingBabyAnimals) {
if (entity instanceof Ageable) {
if (!((Ageable) entity).isAdult()) {
return;
}
}
}
if (this.preventCatchingTamedAnimals) {
if (entity instanceof Tameable) {
if (((Tameable) entity).isTamed()) {
return;
}
}
}
if (this.preventCatchingShearedSheeps) {
if (entity instanceof Sheep) {
if (((Sheep) entity).isSheared()) {
return;
}
}
}
EggCaptureEvent eggCaptureEvent = new EggCaptureEvent(entity, egg);
this.plugin.getServer().getPluginManager().callEvent(eggCaptureEvent);
if (eggCaptureEvent.isCancelled()) {
return;
}
if (egg.getShooter() instanceof Player) {
Player player = (Player) egg.getShooter();
double vaultCost = getVaultCost(player, Objects.requireNonNull(eggType).getFriendlyName());
ItemStack itemCost = getItemCost(player, eggType.getFriendlyName());
if (this.usePermissions) {
if (!player.hasPermission("eggcatcher.catch." + eggType.getFriendlyName().toLowerCase())) {
player.sendMessage(config.getString("Messages.PermissionFail"));
if (!this.looseEggOnFail) {
player.getInventory().addItem(new ItemStack(Material.EGG, 1));
EggCatcher.eggs.add(egg);
}
return;
}
// check that the player can actually catch this mob
if (!playerHasRequirements(event, player, vaultCost, itemCost)) {
return;
}
if (this.useHealthPercentage) {
double healthPercentage = config.getDouble("HealthPercentage." + eggType.getFriendlyName());
double currentHealth = ((LivingEntity) entity).getHealth() * 100.0 / ((LivingEntity) entity)
.getMaxHealth();
if (healthPercentage < currentHealth) {
if (this.healthPercentageFailMessage.length() > 0) {
player.sendMessage(String.format(this.healthPercentageFailMessage, healthPercentage));
}
if (!this.looseEggOnFail) {
player.getInventory().addItem(new ItemStack(Material.EGG, 1));
EggCatcher.eggs.add(egg);
}
return;
}
// send chance success message
if (this.useCatchChance && this.catchChanceSuccessMessage.length() != 0) {
player.sendMessage(this.catchChanceSuccessMessage);
}
if (this.useCatchChance) {
double catchChance = config.getDouble("CatchChance." + eggType.getFriendlyName());
if (Math.random() * 100 <= catchChance) {
if (this.catchChanceSuccessMessage.length() > 0) {
player.sendMessage(catchChanceSuccessMessage);
}
} else {
if (this.catchChanceFailMessage.length() > 0) {
player.sendMessage(this.catchChanceFailMessage);
}
if (!this.looseEggOnFail) {
player.getInventory().addItem(new ItemStack(Material.EGG, 1));
EggCatcher.eggs.add(egg);
}
return;
// withdraw money
if (vaultCost > 0) {
EggCatcher.economy.withdrawPlayer(player, vaultCost);
if (!this.vaultTargetBankAccount.isEmpty()) {
EggCatcher.economy.bankDeposit(this.vaultTargetBankAccount, vaultCost);
}
}
boolean freeCatch = player.hasPermission("eggcatcher.free");
if (this.useVaultCost && !freeCatch) {
vaultCost = config.getDouble("VaultCost." + eggType.getFriendlyName());
if (!EggCatcher.economy.has(player.getName(), vaultCost)) {
player.sendMessage(String.format(config.getString("Messages.VaultFail"), vaultCost));
if (!this.looseEggOnFail) {
player.getInventory().addItem(new ItemStack(Material.EGG, 1));
EggCatcher.eggs.add(egg);
}
return;
} else {
EggCatcher.economy.withdrawPlayer(player.getName(), vaultCost);
if (!this.vaultTargetBankAccount.isEmpty()) {
EggCatcher.economy.bankDeposit(this.vaultTargetBankAccount, vaultCost);
}
player.sendMessage(String.format(config.getString("Messages.VaultSuccess"), vaultCost));
}
player.sendMessage(String.format(config.getString("Messages.VaultSuccess"), vaultCost));
}
if (this.useItemCost && !freeCatch) {
int itemId = config.getInt("ItemCost.ItemId", 266);
int itemData = config.getInt("ItemCost.ItemData", 0);
int itemAmount = config.getInt("ItemCost.Amount." + eggType.getFriendlyName(), 0);
@SuppressWarnings("deprecation")
ItemStack itemStack = new ItemStack(itemId, itemAmount, (short) itemData);
if (player.getInventory().containsAtLeast(itemStack, itemStack.getAmount())) {
player.sendMessage(String.format(config.getString("Messages.ItemCostSuccess"),
String.valueOf(itemAmount)));
player.getInventory().removeItem(itemStack);
} else {
player.sendMessage(String.format(config.getString("Messages.ItemCostFail"),
String.valueOf(itemAmount)));
if (!this.looseEggOnFail) {
player.getInventory().addItem(new ItemStack(Material.EGG, 1));
EggCatcher.eggs.add(egg);
}
return;
}
// withdraw items
if (itemCost != null) {
player.sendMessage(String.format(config.getString("Messages.ItemCostSuccess"),
String.valueOf(itemCost.getAmount())));
player.getInventory().removeItem(itemCost);
}
} else {
// Dispenser
@ -268,10 +179,8 @@ public class EggCatcherEntityListener implements Listener {
}
ItemStack eggStack = new ItemStack(Material.MONSTER_EGG, 1, eggType.getCreatureId());
eggStack = NbtReflection.setNewEntityTag(eggStack, entity.getType().getName());
String customName = ((LivingEntity) entity).getCustomName();
String customName = entity.getCustomName();
if (customName != null) {
// Entity had custom name
@ -280,25 +189,17 @@ public class EggCatcherEntityListener implements Listener {
eggStack.setItemMeta(meta);
}
if(entity instanceof Pig) {
if(((Pig)entity).hasSaddle()) {
entity.getWorld().dropItem(entity.getLocation(), new ItemStack(Material.SADDLE, 1));
}
}
if(entity instanceof Horse) {
if(((Horse) entity).isCarryingChest()){
entity.getWorld().dropItemNaturally(entity.getLocation(), new ItemStack(Material.CHEST));
}
}
if((entity instanceof Villager && !this.deleteVillagerInventoryOnCatch) ||
if (entity instanceof Pig && ((Pig) entity).hasSaddle()) {
entity.getWorld().dropItem(entity.getLocation(), new ItemStack(Material.SADDLE, 1));
} else if (entity instanceof ChestedHorse && ((ChestedHorse) entity).isCarryingChest()) {
entity.getWorld().dropItemNaturally(entity.getLocation(), new ItemStack(Material.CHEST));
} else if ((entity instanceof Villager && !this.deleteVillagerInventoryOnCatch) ||
(!(entity instanceof Villager) && entity instanceof InventoryHolder)) {
ItemStack[] items = ((InventoryHolder) entity).getInventory().getContents();
for(ItemStack itemStack : items) {
if(itemStack!=null){
for (ItemStack itemStack : items) {
if (itemStack != null) {
entity.getWorld().dropItemNaturally(entity.getLocation(), itemStack);
}
}
@ -311,9 +212,139 @@ public class EggCatcherEntityListener implements Listener {
EggCatcher.eggs.add(egg);
}
}
if (this.logCaptures){
captureLogger.logToFile("Player " + ((Player) egg.getShooter()).getName() + " caught " + entity.getType() + " at X" + Math.round(entity.getLocation().getX()) + ",Y" + Math.round(entity.getLocation().getY()) + ",Z" + Math.round(entity.getLocation().getZ()));
if (this.logCaptures) {
captureLogger.logToFile(String.format("Player %s caught %s at X%d,Y%d,Z%d",
((Player) egg.getShooter()).getName(),
entity.getType().toString(),
Math.round(entity.getLocation().getX()),
Math.round(entity.getLocation().getY()),
Math.round(entity.getLocation().getZ())));
}
}
/**
* Check that the player satisfies requirements necessary to capture mob
*
* @param event egg capture event
* @param player player causing event
* @param vaultCost economy cost to capture mob
* @param itemCost item cost to capture mob
* @return if player should catch the mob
*/
private boolean playerHasRequirements(EggCaptureEvent event, Player player, double vaultCost, ItemStack itemCost) {
LivingEntity entity = (LivingEntity) event.getEntity();
String eggType = Objects.requireNonNull(EggType.getEggType(event.getEntity())).getFriendlyName();
double entityHealthRequirement = getEntityHealthRequirement(eggType);
String message = null;
boolean hasRequirements = true;
// perform player egg capture validations
if (this.usePermissions && !player.hasPermission("eggcatcher.catch." + eggType.toLowerCase())) {
hasRequirements = false;
message = config.getString("Messages.PermissionFail");
} else if (entityHealthRequirement > 0 && entityHealthRequirement < getEntityHealthPercentage(entity)) {
hasRequirements = false;
if (this.healthPercentageFailMessage.length() > 0) {
message = String.format(this.healthPercentageFailMessage, entityHealthRequirement);
}
} else if (this.useCatchChance && Math.random() * 100 > config.getDouble("CatchChance." + eggType)) {
hasRequirements = false;
message = this.catchChanceFailMessage;
} else if (vaultCost > 0 && !EggCatcher.economy.has(player, vaultCost)) {
hasRequirements = false;
message = String.format(config.getString("Messages.VaultFail"), vaultCost);
} else if (itemCost != null && !player.getInventory().containsAtLeast(itemCost, itemCost.getAmount())) {
hasRequirements = false;
message = String.format(config.getString("Messages.ItemCostFail"), String.valueOf(itemCost.getAmount()));
}
if (message != null && message.length() != 0) {
player.sendMessage(message);
}
if (!hasRequirements) {
if (!this.loseEggOnFail) {
player.getInventory().addItem(new ItemStack(Material.EGG, 1));
EggCatcher.eggs.add(event.getEgg());
}
}
return hasRequirements;
}
/**
* Get the vault (economy) cost of capturing the given egg mob
*
* @param p player attempting to capture mob
* @param eggType friendly name of the mob egg being caught
* @return vault cost of capturing the mob egg
*/
private double getVaultCost(Player p, String eggType) {
return this.useVaultCost && !p.hasPermission("eggcatcher.free") ? config.getDouble("VaultCost." + eggType) : 0;
}
/**
* Get the item cost of catching a mob egg
*
* @param p player attempting to capture mob
* @param eggType friendly name of the mob egg being caught
* @return item cost of capturing the mob egg
*/
private ItemStack getItemCost(Player p, String eggType) {
if (this.useItemCost && !p.hasPermission("eggcatcher.free")) {
int itemId = config.getInt("ItemCost.ItemId", 266);
int itemData = config.getInt("ItemCost.ItemData", 0);
int itemAmount = config.getInt("ItemCost.Amount." + eggType, 0);
return new ItemStack(itemId, itemAmount, (short) itemData);
}
return null;
}
/**
* Get the required health percentage to catch given mob egg
*
* @param eggType friendly name of mob egg type being caught
* @return required health percentage to catch given mob egg
*/
private double getEntityHealthRequirement(String eggType) {
return this.useHealthPercentage ? config.getDouble("HealthPercentage." + eggType) : 0;
}
/**
* Get the current percentage of max health an entity currently has
*
* @param entity Entity to get health percentage of
* @return current percentage of max health an entity currently has
*/
private double getEntityHealthPercentage(LivingEntity entity) {
return entity.getHealth() * 100.0 / entity.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue();
}
/**
* Check that the EntityDamageByEntityEvent is damage done by a valid egg to a valid egg-able mob
*
* @param e EntityDamageByEntityEvent
* @return if this event is a valid egg capture
*/
private boolean checkIsEggEvent(EntityDamageByEntityEvent e) {
return e.getDamager() instanceof Egg && EggType.getEggType(e.getEntity()) != null;
}
/**
* Check that the entity being damaged satisfies the configured baby/tamed/sheared restrictions
*
* @param e entity damage by entity event
* @return if the entity being damated satisfies the restrictions
*/
private boolean checkAnimalRestrictions(EntityDamageByEntityEvent e) {
Entity entity = e.getEntity();
return !(
(this.preventCatchingBabyAnimals && entity instanceof Ageable && !((Ageable) entity).isAdult()) ||
(this.preventCatchingTamedAnimals && entity instanceof Tameable && ((Tameable) entity).isTamed()) ||
(this.preventCatchingShearedSheeps && entity instanceof Sheep && ((Sheep) entity).isSheared())
);
}
}