package de.flo56958.minetinker.modifiers; import de.flo56958.minetinker.MineTinker; import de.flo56958.minetinker.data.ModifierFailCause; import de.flo56958.minetinker.data.ToolType; import de.flo56958.minetinker.events.ModifierApplyEvent; import de.flo56958.minetinker.events.ModifierFailEvent; import de.flo56958.minetinker.modifiers.types.ExtraModifier; import de.flo56958.minetinker.utils.ChatWriter; import de.flo56958.minetinker.utils.ConfigurationManager; import de.flo56958.minetinker.utils.LanguageManager; import org.bukkit.*; import org.bukkit.attribute.Attribute; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; import org.bukkit.inventory.ShapedRecipe; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginManager; import java.io.File; import java.util.Collections; import java.util.List; import java.util.Set; public abstract class Modifier { protected static final ModManager modManager = ModManager.instance(); protected static final PluginManager pluginManager = Bukkit.getPluginManager(); private final Plugin source; private final String fileName; protected String description; private String name; private ChatColor color; private int maxLvl; private ItemStack modItem = new ItemStack(Material.BEDROCK); protected int slotCost; protected int customModelData = -1; /** * Class constructor * * @param source The Plugin that registered the Modifier */ protected Modifier(Plugin source) { this.fileName = getKey().replace("'", "") + ".yml"; ConfigurationManager.loadConfig("Modifiers" + File.separator, this.fileName); this.source = source; } boolean checkAndAdd(Player player, ItemStack tool, String permission, boolean isCommand, boolean fromRandom, boolean silent) { if ((modManager.getFreeSlots(tool) < this.getSlotCost() && !this.equals(ExtraModifier.instance())) && !isCommand) { if (!silent) pluginManager.callEvent(new ModifierFailEvent(player, tool, this, ModifierFailCause.NO_FREE_SLOTS, false)); return false; } if (!player.hasPermission("minetinker.modifiers." + permission + ".apply")) { if (!silent) pluginManager.callEvent(new ModifierFailEvent(player, tool, this, ModifierFailCause.NO_PERMISSION, isCommand)); return false; } FileConfiguration modifiersconfig = ConfigurationManager.getConfig("Modifiers.yml"); if (!(modifiersconfig.getBoolean("CommandIgnoresToolTypes") && isCommand && !fromRandom) && !this.isMaterialCompatible(tool.getType())) { if (!silent) pluginManager.callEvent(new ModifierFailEvent(player, tool, this, ModifierFailCause.INVALID_TOOLTYPE, isCommand)); return false; } if (!(modifiersconfig.getBoolean("CommandIgnoresMaxLevel") && isCommand && !fromRandom) && modManager.getModLevel(tool, this) >= this.getMaxLvl()) { if (!silent) pluginManager.callEvent(new ModifierFailEvent(player, tool, this, ModifierFailCause.MOD_MAXLEVEL, isCommand)); return false; } if (!(modManager.hasMod(tool, this) && modifiersconfig.getBoolean("IgnoreIncompatibilityIfModifierAlreadyApplied"))) { if (fromRandom || !(modifiersconfig.getBoolean("CommandIgnoresIncompatibilities") && isCommand)) { Set<Modifier> incompatibility = modManager.getIncompatibilities(this); for (Modifier m : incompatibility) { if (modManager.hasMod(tool, m)) { if (!silent) pluginManager.callEvent(new ModifierFailEvent(player, tool, this, ModifierFailCause.INCOMPATIBLE_MODIFIERS, isCommand)); return false; } if (modifiersconfig.getBoolean("IncompatibilitiesConsiderEnchants")) { for (Enchantment e : m.getAppliedEnchantments()) { if (!tool.hasItemMeta()) return false; if (tool.getItemMeta().hasEnchant(e)) { if (!silent) pluginManager.callEvent(new ModifierFailEvent(player, tool, this, ModifierFailCause.INCOMPATIBLE_MODIFIERS, isCommand)); return false; } } } } } } modManager.addMod(tool, this); if (!isCommand) { modManager.setFreeSlots(tool, modManager.getFreeSlots(tool) - this.getSlotCost()); } else { if (!silent) { ModifierApplyEvent event = new ModifierApplyEvent(player, tool, this, modManager.getFreeSlots(tool), true); Bukkit.getPluginManager().callEvent(event); } } return true; } public abstract String getKey(); public abstract List<ToolType> getAllowedTools(); public String getDescription() { return description; } public ChatColor getColor() { return color; } public int getMaxLvl() { return maxLvl; } public int getSlotCost() { return slotCost; } public ItemStack getModItem() { return modItem; } public boolean hasRecipe() { return getConfig().getBoolean("Recipe.Enabled", false); } Plugin getSource() { return source; } //for other Plugins/Addons that register Modifiers public String getName() { return this.name; } public int getEnchantCost() { return getConfig().getInt("EnchantCost", 10); } public boolean isEnchantable() { return getConfig().getBoolean("Enchantable", false); } /** * changes the core settings of the Modifier (like a secondary constructor) */ protected void init(Material m) { FileConfiguration config = getConfig(); try { this.color = ChatWriter.getColor(config.getString("Color", "%WHITE%")); } catch (IllegalArgumentException | ArrayIndexOutOfBoundsException ignored) { this.color = ChatColor.WHITE; ChatWriter.logError("Illegal Color detected for Modifier " + this.getKey()); } this.maxLvl = config.getInt("MaxLevel"); this.slotCost = config.getInt("SlotCost", 1); if (source.equals(MineTinker.getPlugin())) { //normal Languagesystem-Integration String langStart = "Modifier." + getKey(); this.name = LanguageManager.getString(langStart + ".Name"); this.description = LanguageManager.getString(langStart + ".Description"); this.modItem = modManager.createModifierItem(m, this.color + LanguageManager.getString(langStart + ".ModifierItemName"), ChatColor.WHITE + LanguageManager.getString(langStart + ".DescriptionModifierItem"), this); } else { //use the config values instead this.name = config.getString("Name", ""); this.description = ChatWriter.addColors(config.getString("Description", "")); this.modItem = modManager.createModifierItem(m, this.color + config.getString("ModifierItemName", ""), ChatWriter.addColors(config.getString("DescriptionModifierItem", "")), this); } ItemMeta itemMeta = this.modItem.getItemMeta(); if (itemMeta != null) itemMeta.setCustomModelData(this.customModelData); this.modItem.setItemMeta(itemMeta); if (ConfigurationManager.getConfig("Modifiers.yml").getBoolean("UseCustomModelData", false)) { this.modItem.setType(Material.STICK); } } /** * applies the Modifier to the tool * * @param player the Player * @param tool the Tool to modify * @return true if successful * false if failure */ public boolean applyMod(Player player, ItemStack tool, boolean isCommand) { return true; } /** * what should be done to the Tool if the Modifier gets removed * * @param tool the Tool */ public void removeMod(ItemStack tool) { ItemMeta meta = tool.getItemMeta(); if (meta != null) { for (Enchantment enchantment : getAppliedEnchantments()) { meta.removeEnchant(enchantment); } for (Attribute attribute : getAppliedAttributes()) { meta.removeAttributeModifier(attribute); } tool.setItemMeta(meta); } } /** * reloads the settings of the Modifier */ public abstract void reload(); /** * @return is the modifier allowed */ public boolean isAllowed() { return getConfig().getBoolean("Allowed", true); } public String getFileName() { return fileName; } /** * @return a list of enchantments that may be applied when the modifier is applied */ public List<Enchantment> getAppliedEnchantments() { return Collections.emptyList(); } /** * @return a list of attributes that may be applied when the modifier is applied */ public List<Attribute> getAppliedAttributes() { return Collections.emptyList(); } @SuppressWarnings("BooleanMethodIsAlwaysInverted") protected boolean isMaterialCompatible(Material material) { for (ToolType toolType : getAllowedTools()) { if (toolType.contains(material)) { return true; } } return false; } protected FileConfiguration getConfig() { return ConfigurationManager.getConfig(this.getFileName()); } protected void registerCraftingRecipe() { if (!hasRecipe()) { return; } FileConfiguration config = getConfig(); try { NamespacedKey nkey = new NamespacedKey(MineTinker.getPlugin(), "Modifier_" + getKey()); ShapedRecipe newRecipe = new ShapedRecipe(nkey, this.getModItem()); //reload recipe String top = config.getString("Recipe.Top"); String middle = config.getString("Recipe.Middle"); String bottom = config.getString("Recipe.Bottom"); ConfigurationSection materials = config.getConfigurationSection("Recipe.Materials"); newRecipe.shape(top, middle, bottom); //makes recipe if (materials != null) { for (String key : materials.getKeys(false)) { String materialName = materials.getString(key); if (materialName == null) { ChatWriter.logInfo(LanguageManager.getString("Modifier.MaterialEntryNotFound")); return; } Material material = Material.getMaterial(materialName); if (material == null) { ChatWriter.log(false, "Material [" + materialName + "] is null for mod [" + this.name + "]"); return; } else { newRecipe.setIngredient(key.charAt(0), material); } } } else { ChatWriter.logError("Could not register recipe for the " + this.name + "-Modifier!"); //executes if the recipe could not initialize ChatWriter.logError("Cause: Malformed recipe config."); return; } MineTinker.getPlugin().getServer().addRecipe(newRecipe); //adds recipe ChatWriter.log(false, "Registered recipe for the " + this.name + "-Modifier!"); ModManager.instance().recipe_Namespaces.add(nkey); } catch (Exception e) { ChatWriter.logError("Could not register recipe for the " + this.name + "-Modifier!"); //executes if the recipe could not initialize } } public boolean equals(Object o) { if (o instanceof Modifier) { return ((Modifier) o).getKey().equals(this.getKey()); } return false; } // ---------------------- Enchantable Stuff ---------------------- public void enchantItem(Player player) { if (!player.hasPermission("minetinker.modifiers." + getKey().replace("-", "").toLowerCase() + ".craft")) { return; } if (getConfig().getBoolean("Recipe.Enabled")) { return; } Location location = player.getLocation(); World world = location.getWorld(); PlayerInventory inventory = player.getInventory(); if (world == null) { return; } if (player.getGameMode() == GameMode.CREATIVE) { if (inventory.addItem(getModItem()).size() != 0) { //adds items to (full) inventory world.dropItem(location, getModItem()); } // no else as it gets added in if if (MineTinker.getPlugin().getConfig().getBoolean("Sound.OnEnchanting")) { player.playSound(location, Sound.BLOCK_ENCHANTMENT_TABLE_USE, 1.0F, 0.5F); } ChatWriter.log(false, player.getDisplayName() + " created a " + getName() + "-Modifiers in Creative!"); } else if (player.getLevel() >= getEnchantCost()) { int amount = inventory.getItemInMainHand().getAmount(); int newLevel = player.getLevel() - getEnchantCost(); player.setLevel(newLevel); inventory.getItemInMainHand().setAmount(amount - 1); if (inventory.addItem(getModItem()).size() != 0) { //adds items to (full) inventory world.dropItem(location, getModItem()); } // no else as it gets added in if if (MineTinker.getPlugin().getConfig().getBoolean("Sound.OnEnchanting")) { player.playSound(location, Sound.BLOCK_ENCHANTMENT_TABLE_USE, 1.0F, 0.5F); } ChatWriter.log(false, player.getDisplayName() + " created a " + getName() + "-Modifiers!"); } else { ChatWriter.sendActionBar(player, ChatColor.RED + LanguageManager.getString("Modifier.Enchantable.LevelsRequired", player) .replace("%amount", String.valueOf(getEnchantCost()))); ChatWriter.log(false, player.getDisplayName() + " tried to create a " + getName() + "-Modifiers but had not enough levels!"); } } }