diff --git a/src/main/java/com/gmail/nossr50/commands/skills/RepairCommand.java b/src/main/java/com/gmail/nossr50/commands/skills/RepairCommand.java index a05c16527..e01fce126 100644 --- a/src/main/java/com/gmail/nossr50/commands/skills/RepairCommand.java +++ b/src/main/java/com/gmail/nossr50/commands/skills/RepairCommand.java @@ -9,6 +9,7 @@ import com.gmail.nossr50.skills.repair.Repair; import com.gmail.nossr50.skills.repair.Repairable; import com.gmail.nossr50.skills.repair.Salvage; import com.gmail.nossr50.util.Permissions; +import com.gmail.nossr50.util.player.UserManager; public class RepairCommand extends SkillCommand { private int arcaneForgingRank; @@ -41,10 +42,10 @@ public class RepairCommand extends SkillCommand { @Override protected void dataCalculations() { // We're using pickaxes here, not the best but it works - Repairable diamondRepairable = mcMMO.repairManager.getRepairable(Material.DIAMOND_PICKAXE.getId()); - Repairable goldRepairable = mcMMO.repairManager.getRepairable(Material.GOLD_PICKAXE.getId()); - Repairable ironRepairable = mcMMO.repairManager.getRepairable(Material.IRON_PICKAXE.getId()); - Repairable stoneRepairable = mcMMO.repairManager.getRepairable(Material.STONE_PICKAXE.getId()); + Repairable diamondRepairable = mcMMO.repairableManager.getRepairable(Material.DIAMOND_PICKAXE.getId()); + Repairable goldRepairable = mcMMO.repairableManager.getRepairable(Material.GOLD_PICKAXE.getId()); + Repairable ironRepairable = mcMMO.repairableManager.getRepairable(Material.IRON_PICKAXE.getId()); + Repairable stoneRepairable = mcMMO.repairableManager.getRepairable(Material.STONE_PICKAXE.getId()); // TODO: This isn't really accurate - if they don't have pickaxes loaded it doesn't always mean the repair level is 0 diamondLevel = (diamondRepairable == null) ? 0 : diamondRepairable.getMinimumLevel(); @@ -66,7 +67,7 @@ public class RepairCommand extends SkillCommand { superRepairChanceLucky = superRepairStrings[1]; // ARCANE FORGING - arcaneForgingRank = Repair.getArcaneForgingRank(profile); + arcaneForgingRank = UserManager.getPlayer(player).getRepairManager().getArcaneForgingRank(); } @Override @@ -155,11 +156,11 @@ public class RepairCommand extends SkillCommand { player.sendMessage(LocaleLoader.getString("Repair.Arcane.Rank", arcaneForgingRank)); if (Repair.arcaneForgingEnchantLoss) { - player.sendMessage(LocaleLoader.getString("Repair.Arcane.Chance.Success", (arcaneBypass ? 100 : Repair.getEnchantChance(arcaneForgingRank)))); + player.sendMessage(LocaleLoader.getString("Repair.Arcane.Chance.Success", (arcaneBypass ? 100 : UserManager.getPlayer(player).getRepairManager().getKeepEnchantChance()))); } if (Repair.arcaneForgingDowngrades) { - player.sendMessage(LocaleLoader.getString("Repair.Arcane.Chance.Downgrade", (arcaneBypass ? 0 : Repair.getDowngradeChance(arcaneForgingRank)))); + player.sendMessage(LocaleLoader.getString("Repair.Arcane.Chance.Downgrade", (arcaneBypass ? 0 : UserManager.getPlayer(player).getRepairManager().getDowngradeEnchantChance()))); } } } diff --git a/src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java b/src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java index 7e89c7d59..55b367fc5 100644 --- a/src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java +++ b/src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java @@ -28,6 +28,7 @@ import com.gmail.nossr50.skills.excavation.ExcavationManager; import com.gmail.nossr50.skills.fishing.FishingManager; import com.gmail.nossr50.skills.herbalism.HerbalismManager; import com.gmail.nossr50.skills.mining.MiningManager; +import com.gmail.nossr50.skills.repair.RepairManager; import com.gmail.nossr50.skills.smelting.SmeltingManager; import com.gmail.nossr50.skills.swords.SwordsManager; import com.gmail.nossr50.skills.taming.TamingManager; @@ -144,6 +145,10 @@ public class McMMOPlayer { return (MiningManager) skillManagers.get(SkillType.MINING); } + public RepairManager getRepairManager() { + return (RepairManager) skillManagers.get(SkillType.REPAIR); + } + public SmeltingManager getSmeltingManager() { return (SmeltingManager) skillManagers.get(SkillType.SMELTING); } diff --git a/src/main/java/com/gmail/nossr50/listeners/BlockListener.java b/src/main/java/com/gmail/nossr50/listeners/BlockListener.java index 930a6dbc0..4bd87939a 100644 --- a/src/main/java/com/gmail/nossr50/listeners/BlockListener.java +++ b/src/main/java/com/gmail/nossr50/listeners/BlockListener.java @@ -35,6 +35,7 @@ import com.gmail.nossr50.skills.excavation.ExcavationManager; import com.gmail.nossr50.skills.herbalism.HerbalismManager; import com.gmail.nossr50.skills.mining.MiningManager; import com.gmail.nossr50.skills.repair.Repair; +import com.gmail.nossr50.skills.repair.RepairManager; import com.gmail.nossr50.skills.repair.Salvage; import com.gmail.nossr50.skills.smelting.SmeltingManager; import com.gmail.nossr50.skills.unarmed.Unarmed; @@ -116,10 +117,11 @@ public class BlockListener implements Listener { } if (Repair.anvilMessagesEnabled) { + RepairManager repairManager = UserManager.getPlayer(player).getRepairManager(); int blockID = blockState.getTypeId(); if (blockID == Repair.anvilID) { - Repair.placedAnvilCheck(player, blockID); + repairManager.placedAnvilCheck(blockID); } else if (blockID == Salvage.anvilID) { Salvage.placedAnvilCheck(player, blockID); diff --git a/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java b/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java index 76760c682..837794269 100644 --- a/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java +++ b/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java @@ -285,8 +285,8 @@ public class PlayerListener implements Listener { int blockID = block.getTypeId(); /* REPAIR CHECKS */ - if (blockID == Repair.anvilID && Permissions.skillEnabled(player, SkillType.REPAIR) && mcMMO.repairManager.isRepairable(heldItem)) { - mcMMO.repairManager.handleRepair(mcMMOPlayer, heldItem); + if (blockID == Repair.anvilID && Permissions.skillEnabled(player, SkillType.REPAIR) && mcMMO.repairableManager.isRepairable(heldItem)) { + UserManager.getPlayer(player).getRepairManager().handleRepair(heldItem); event.setCancelled(true); player.updateInventory(); } diff --git a/src/main/java/com/gmail/nossr50/mcMMO.java b/src/main/java/com/gmail/nossr50/mcMMO.java index 17b43990c..f4ec03e5c 100644 --- a/src/main/java/com/gmail/nossr50/mcMMO.java +++ b/src/main/java/com/gmail/nossr50/mcMMO.java @@ -45,8 +45,8 @@ import com.gmail.nossr50.runnables.party.PartyLoaderTask; import com.gmail.nossr50.runnables.skills.BleedTimerTask; import com.gmail.nossr50.runnables.skills.SkillMonitorTask; import com.gmail.nossr50.skills.child.ChildConfig; -import com.gmail.nossr50.skills.repair.RepairManager; -import com.gmail.nossr50.skills.repair.RepairManagerFactory; +import com.gmail.nossr50.skills.repair.RepairableManager; +import com.gmail.nossr50.skills.repair.RepairableManagerFactory; import com.gmail.nossr50.skills.repair.Repairable; import com.gmail.nossr50.skills.repair.config.RepairConfigManager; import com.gmail.nossr50.util.LogFilter; @@ -71,7 +71,7 @@ public class mcMMO extends JavaPlugin { public static mcMMO p; public static ChunkManager placeStore; - public static RepairManager repairManager; + public static RepairableManager repairableManager; // Jar Stuff public static File mcmmo; @@ -377,8 +377,8 @@ public class mcMMO extends JavaPlugin { // Load repair configs, make manager, and register them at this time RepairConfigManager rManager = new RepairConfigManager(this); repairables.addAll(rManager.getLoadedRepairables()); - repairManager = RepairManagerFactory.getRepairManager(repairables.size()); - repairManager.registerRepairables(repairables); + repairableManager = RepairableManagerFactory.getRepairManager(repairables.size()); + repairableManager.registerRepairables(repairables); // Check if Repair Anvil and Salvage Anvil have different itemID's if (configInstance.getSalvageAnvilId() == configInstance.getRepairAnvilId()) { diff --git a/src/main/java/com/gmail/nossr50/skills/repair/Repair.java b/src/main/java/com/gmail/nossr50/skills/repair/Repair.java index b8e658c93..aa281c7a3 100644 --- a/src/main/java/com/gmail/nossr50/skills/repair/Repair.java +++ b/src/main/java/com/gmail/nossr50/skills/repair/Repair.java @@ -1,29 +1,46 @@ package com.gmail.nossr50.skills.repair; -import java.util.Map; -import java.util.Map.Entry; - -import org.bukkit.Material; -import org.bukkit.Sound; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -import org.getspout.spoutapi.SpoutManager; -import org.getspout.spoutapi.player.SpoutPlayer; +import org.bukkit.inventory.PlayerInventory; -import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.config.AdvancedConfig; import com.gmail.nossr50.config.Config; -import com.gmail.nossr50.datatypes.player.McMMOPlayer; -import com.gmail.nossr50.datatypes.player.PlayerProfile; -import com.gmail.nossr50.datatypes.skills.SkillType; -import com.gmail.nossr50.locale.LocaleLoader; -import com.gmail.nossr50.util.Misc; -import com.gmail.nossr50.util.Permissions; -import com.gmail.nossr50.util.player.UserManager; -import com.gmail.nossr50.util.skills.PerksUtils; public class Repair { + // The order of the values is extremely important, a few methods depend on it to work properly + protected enum Tier { + FOUR(4) { + @Override public int getLevel() { return AdvancedConfig.getInstance().getArcaneForgingRankLevels4(); } + @Override public int getKeepEnchantChance() { return AdvancedConfig.getInstance().getArcaneForgingKeepEnchantsChanceRank4(); } + @Override public int getDowngradeEnchantChance() { return AdvancedConfig.getInstance().getArcaneForgingDowngradeChanceRank4(); }}, + THREE(3) { + @Override public int getLevel() { return AdvancedConfig.getInstance().getArcaneForgingRankLevels3(); } + @Override public int getKeepEnchantChance() { return AdvancedConfig.getInstance().getArcaneForgingKeepEnchantsChanceRank3(); } + @Override public int getDowngradeEnchantChance() { return AdvancedConfig.getInstance().getArcaneForgingDowngradeChanceRank4(); }}, + TWO(2) { + @Override public int getLevel() { return AdvancedConfig.getInstance().getArcaneForgingRankLevels2(); } + @Override public int getKeepEnchantChance() { return AdvancedConfig.getInstance().getArcaneForgingKeepEnchantsChanceRank2(); } + @Override public int getDowngradeEnchantChance() { return AdvancedConfig.getInstance().getArcaneForgingDowngradeChanceRank4(); }}, + ONE(1) { + @Override public int getLevel() { return AdvancedConfig.getInstance().getArcaneForgingRankLevels1(); } + @Override public int getKeepEnchantChance() { return AdvancedConfig.getInstance().getArcaneForgingKeepEnchantsChanceRank1(); } + @Override public int getDowngradeEnchantChance() { return AdvancedConfig.getInstance().getArcaneForgingDowngradeChanceRank4(); }}; + + int numerical; + + private Tier(int numerical) { + this.numerical = numerical; + } + + public int toNumerical() { + return numerical; + } + + abstract protected int getLevel(); + abstract protected int getKeepEnchantChance(); + abstract protected int getDowngradeEnchantChance(); + } + public static int repairMasteryMaxBonusLevel = AdvancedConfig.getInstance().getRepairMasteryMaxLevel(); public static double repairMasteryMaxBonus = AdvancedConfig.getInstance().getRepairMasteryMaxBonus(); @@ -37,244 +54,57 @@ public class Repair { public static boolean anvilMessagesEnabled = Config.getInstance().getRepairAnvilMessagesEnabled(); /** - * Get current Arcane Forging rank. + * Search the inventory for an item and return the index. * - * @param profile The PlayerProfile of the player to get the rank for - * @return The player's current Arcane Forging rank + * @param inventory PlayerInventory to scan + * @param itemId Item id to look for + * @return index location where the item was found, or -1 if not found */ - public static int getArcaneForgingRank(PlayerProfile profile) { - int skillLevel = profile.getSkillLevel(SkillType.REPAIR); + protected static int findInInventory(PlayerInventory inventory, int itemId) { + int location = inventory.first(itemId); - if (skillLevel >= AdvancedConfig.getInstance().getArcaneForgingRankLevels4()) { - return 4; - } - else if (skillLevel >= AdvancedConfig.getInstance().getArcaneForgingRankLevels3()) { - return 3; - } - else if (skillLevel >= AdvancedConfig.getInstance().getArcaneForgingRankLevels2()) { - return 2; - } - else if (skillLevel >= AdvancedConfig.getInstance().getArcaneForgingRankLevels1()) { - return 1; - } - else { - return 0; + // VALIDATE + if (inventory.getItem(location).getTypeId() == itemId) { + return location; } + + return -1; } /** - * Handles removing & downgrading enchants. + * Search the inventory for an item and return the index. * - * @param player Player repairing the item - * @param is Item being repaired + * @param inventory PlayerInventory to scan + * @param itemId Item id to look for + * @param metadata Metadata to look for + * @return index location where the item was found, or -1 if not found */ - protected static void addEnchants(Player player, ItemStack is) { - if (Permissions.arcaneBypass(player)) { - player.sendMessage(LocaleLoader.getString("Repair.Arcane.Perfect")); - return; - } - Map enchants = is.getEnchantments(); + protected static int findInInventory(PlayerInventory inventory, int itemId, byte metadata) { + int location = -1; - if (enchants.size() == 0) { - return; - } - - int rank = getArcaneForgingRank(UserManager.getPlayer(player).getProfile()); - - if (rank == 0 || !Permissions.arcaneForging(player)) { - for (Enchantment x : enchants.keySet()) { - is.removeEnchantment(x); + for (ItemStack item : inventory.getContents()) { + if (item == null) { + continue; } - player.sendMessage(LocaleLoader.getString("Repair.Arcane.Lost")); - return; - } - boolean downgraded = false; - - for (Entry enchant : enchants.entrySet()) { - Enchantment enchantment = enchant.getKey(); - - int activationChance = PerksUtils.handleLuckyPerks(player, SkillType.REPAIR); - - if (Misc.getRandom().nextInt(activationChance) <= getEnchantChance(rank)) { - int enchantLevel = enchant.getValue(); - - if (arcaneForgingDowngrades && enchantLevel > 1) { - if (Misc.getRandom().nextInt(activationChance) < getDowngradeChance(rank)) { - is.addEnchantment(enchantment, --enchantLevel); - downgraded = true; - } - } - } - else { - is.removeEnchantment(enchantment); + if (item.getTypeId() == itemId && item.getData().getData() == metadata) { + return location; } } - Map newEnchants = is.getEnchantments(); - - if (newEnchants.isEmpty()) { - player.sendMessage(LocaleLoader.getString("Repair.Arcane.Fail")); - } - else if (downgraded || newEnchants.size() < enchants.size()) { - player.sendMessage(LocaleLoader.getString("Repair.Arcane.Downgrade")); - } - else { - player.sendMessage(LocaleLoader.getString("Repair.Arcane.Perfect")); - } + return location; } /** - * Gets chance of keeping enchantment during repair. + * Decrease the amount of items in this slot by one * - * @param rank Arcane Forging rank - * @return The chance of keeping the enchantment + * @param inventory PlayerInventory to work in + * @param index Item index to decrement */ - public static int getEnchantChance(int rank) { - switch (rank) { - case 4: - return AdvancedConfig.getInstance().getArcaneForgingKeepEnchantsChanceRank4(); + protected static void removeOneFrom(PlayerInventory inventory, int index) { + ItemStack item = inventory.getItem(index).clone(); + item.setAmount(1); - case 3: - return AdvancedConfig.getInstance().getArcaneForgingKeepEnchantsChanceRank3(); - - case 2: - return AdvancedConfig.getInstance().getArcaneForgingKeepEnchantsChanceRank2(); - - case 1: - return AdvancedConfig.getInstance().getArcaneForgingKeepEnchantsChanceRank1(); - - default: - return 0; - } - } - - /** - * Gets chance of enchantment being downgraded during repair. - * - * @param rank Arcane Forging rank - * @return The chance of the enchantment being downgraded - */ - public static int getDowngradeChance(int rank) { - switch (rank) { - case 4: - return AdvancedConfig.getInstance().getArcaneForgingDowngradeChanceRank4(); - - case 3: - return AdvancedConfig.getInstance().getArcaneForgingDowngradeChanceRank3(); - - case 2: - return AdvancedConfig.getInstance().getArcaneForgingDowngradeChanceRank2(); - - case 1: - return AdvancedConfig.getInstance().getArcaneForgingDowngradeChanceRank1(); - - default: - return 100; - } - } - - /** - * Checks for Super Repair bonus. - * - * @param player The player repairing an item - * @return true if bonus granted, false otherwise - */ - public static boolean checkPlayerProcRepair(Player player) { - int skillLevel = UserManager.getPlayer(player).getProfile().getSkillLevel(SkillType.REPAIR); - - int chance = (int) ((superRepairMaxChance / superRepairMaxBonusLevel) * skillLevel); - if (skillLevel >= superRepairMaxBonusLevel) { - chance = (int) superRepairMaxChance; - } - - int activationChance = PerksUtils.handleLuckyPerks(player, SkillType.REPAIR); - - if (chance > Misc.getRandom().nextInt(activationChance) && Permissions.superRepair(player)) { - player.sendMessage(LocaleLoader.getString("Repair.Skills.FeltEasy")); - return true; - } - return false; - } - - /** - * Handles notifications for placing an anvil. - * - * @param player The player placing the anvil - * @param anvilID The item ID of the anvil block - */ - public static void placedAnvilCheck(Player player, int anvilID) { - McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player); - - if (!mcMMOPlayer.getPlacedAnvil()) { - if (mcMMO.spoutEnabled) { - SpoutPlayer spoutPlayer = SpoutManager.getPlayer(player); - - if (spoutPlayer.isSpoutCraftEnabled()) { - spoutPlayer.sendNotification(LocaleLoader.getString("Repair.AnvilPlaced.Spout1"), LocaleLoader.getString("Repair.AnvilPlaced.Spout2"), Material.getMaterial(anvilID)); - } - } - else { - player.sendMessage(LocaleLoader.getString("Repair.Listener.Anvil")); - } - - player.playSound(player.getLocation(), Sound.ANVIL_LAND, Misc.ANVIL_USE_VOLUME, Misc.ANVIL_USE_PITCH); - mcMMOPlayer.togglePlacedAnvil(); - } - } - - /** - * Handle the Xp gain for repair events. - * - * @param mcMMOPlayer Player repairing the item - * @param durabilityBefore Durability of the item before repair - * @param modify Amount to modify the durability by - */ - protected static void xpHandler(McMMOPlayer mcMMOPlayer, short durabilityBefore, short durabilityAfter, double modify) { - short dif = (short) ((durabilityBefore - durabilityAfter) * modify); - Player player = mcMMOPlayer.getPlayer(); - - player.playSound(player.getLocation(), Sound.ANVIL_USE, Misc.ANVIL_USE_VOLUME, Misc.ANVIL_USE_PITCH); - mcMMOPlayer.beginXpGain(SkillType.REPAIR, dif * 10); - } - - /** - * Computes repair bonuses. - * - * @param player The player repairing an item - * @param skillLevel the skillLevel of the player in Repair - * @param durability The durability of the item being repaired - * @param repairAmount The base amount of durability repaired to the item - * @return The final amount of durability repaired to the item - */ - protected static short repairCalculate(Player player, int skillLevel, short durability, int repairAmount) { - float bonus; - if (skillLevel >= repairMasteryMaxBonusLevel) { - bonus = (float) (repairMasteryMaxBonus / 100F); - } - else { - bonus = (((float) skillLevel) / ((float) repairMasteryMaxBonusLevel)) * (float) ((repairMasteryMaxBonus) / 100F); - } - - if (Permissions.repairMastery(player)) { - bonus = repairAmount * bonus; - repairAmount += (int) bonus; - } - - if (checkPlayerProcRepair(player)) { - repairAmount = (int) (repairAmount * 2D); - } - - if (repairAmount <= 0 || repairAmount > 32767) { - repairAmount = 32767; - } - - durability -= repairAmount; - - if (durability < 0) { - durability = 0; - } - - return durability; + inventory.removeItem(item); } } diff --git a/src/main/java/com/gmail/nossr50/skills/repair/RepairManager.java b/src/main/java/com/gmail/nossr50/skills/repair/RepairManager.java index f7a2007e4..e3f509960 100644 --- a/src/main/java/com/gmail/nossr50/skills/repair/RepairManager.java +++ b/src/main/java/com/gmail/nossr50/skills/repair/RepairManager.java @@ -1,55 +1,318 @@ -package com.gmail.nossr50.skills.repair; - -import java.util.List; - -import org.bukkit.inventory.ItemStack; - -import com.gmail.nossr50.datatypes.player.McMMOPlayer; - -public interface RepairManager { - /** - * Register a repairable with the RepairManager - * - * @param repairable Repairable to register - */ - public void registerRepairable(Repairable repairable); - - /** - * Register a list of repairables with the RepairManager - * - * @param repairables List to register - */ - public void registerRepairables(List repairables); - - /** - * Checks if an item is repairable - * - * @param itemId id to check if repairable - * @return true if repairable, false if not - */ - public boolean isRepairable(int itemId); - - /** - * Checks if an item is repairable - * - * @param itemStack Item to check if repairable - * @return true if repairable, false if not - */ - public boolean isRepairable(ItemStack itemStack); - - /** - * Gets the repairable with this id - * - * @param id Id of the repairable to look for - * @return the repairable, can be null - */ - public Repairable getRepairable(int id); - - /** - * Handle the repairing of this object - * - * @param mcMMOPlayer Player that is repairing an item - * @param item ItemStack that is being repaired - */ - public void handleRepair(McMMOPlayer mcMMOPlayer, ItemStack item); -} +package com.gmail.nossr50.skills.repair; + +import java.util.Map; +import java.util.Map.Entry; + +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; +import org.getspout.spoutapi.SpoutManager; +import org.getspout.spoutapi.player.SpoutPlayer; + +import com.gmail.nossr50.mcMMO; +import com.gmail.nossr50.datatypes.player.McMMOPlayer; +import com.gmail.nossr50.datatypes.skills.SkillType; +import com.gmail.nossr50.events.skills.repair.McMMOPlayerRepairCheckEvent; +import com.gmail.nossr50.locale.LocaleLoader; +import com.gmail.nossr50.skills.SkillManager; +import com.gmail.nossr50.skills.repair.Repair.Tier; +import com.gmail.nossr50.util.Misc; +import com.gmail.nossr50.util.Permissions; +import com.gmail.nossr50.util.StringUtils; +import com.gmail.nossr50.util.skills.SkillUtils; + +public class RepairManager extends SkillManager { + public RepairManager(McMMOPlayer mcMMOPlayer) { + super(mcMMOPlayer, SkillType.REPAIR); + } + + /** + * Handles notifications for placing an anvil. + * + * @param anvilID The item ID of the anvil block + */ + public void placedAnvilCheck(int anvilID) { + Player player = getPlayer(); + + if (mcMMOPlayer.getPlacedAnvil()) { + return; + } + + if (mcMMO.spoutEnabled) { + SpoutPlayer spoutPlayer = SpoutManager.getPlayer(player); + + if (spoutPlayer.isSpoutCraftEnabled()) { + spoutPlayer.sendNotification(LocaleLoader.getString("Repair.AnvilPlaced.Spout1"), LocaleLoader.getString("Repair.AnvilPlaced.Spout2"), Material.getMaterial(anvilID)); + } + } + else { + player.sendMessage(LocaleLoader.getString("Repair.Listener.Anvil")); + } + + player.playSound(player.getLocation(), Sound.ANVIL_LAND, Misc.ANVIL_USE_VOLUME, Misc.ANVIL_USE_PITCH); + mcMMOPlayer.togglePlacedAnvil(); + } + + public void handleRepair(ItemStack item) { + Player player = getPlayer(); + int itemId = item.getTypeId(); + + Repairable repairable = mcMMO.repairableManager.getRepairable(itemId); + + // Permissions checks on material and item types + if (!repairable.getRepairItemType().getPermissions(player)) { + player.sendMessage(LocaleLoader.getString("mcMMO.NoPermission")); + return; + } + + if (!repairable.getRepairMaterialType().getPermissions(player)) { + player.sendMessage(LocaleLoader.getString("mcMMO.NoPermission")); + return; + } + + int skillLevel = getSkillLevel(); + int minimumRepairableLevel = repairable.getMinimumLevel(); + + // Level check + if (skillLevel < minimumRepairableLevel) { + player.sendMessage(LocaleLoader.getString("Repair.Skills.Adept", minimumRepairableLevel, StringUtils.getPrettyItemString(itemId))); + return; + } + + PlayerInventory inventory = player.getInventory(); + + int repairMaterialId = repairable.getRepairMaterialId(); + byte repairMaterialMetadata = repairable.getRepairMaterialMetadata(); + + // Check if they have the proper material to repair with + if (!inventory.contains(repairMaterialId)) { + String message = LocaleLoader.getString("Skills.NeedMore", StringUtils.getPrettyItemString(repairMaterialId)); + + if (repairMaterialMetadata != (byte) -1) { + // TODO: Do something nicer than append the metadata as a :# ? + if (Repair.findInInventory(inventory, repairMaterialId, repairMaterialMetadata) == -1) { + message += ":" + repairMaterialMetadata; + } + } + + player.sendMessage(message); + return; + } + + short startDurability = item.getDurability(); + + // Do not repair if at full durability + if (startDurability <= 0) { + player.sendMessage(LocaleLoader.getString("Repair.Skills.FullDurability")); + return; + } + + // Do not repair stacked items + if (item.getAmount() != 1) { + player.sendMessage(LocaleLoader.getString("Repair.Skills.StackedItems")); + return; + } + + // Clear ability buffs before trying to repair. + SkillUtils.removeAbilityBuff(item); + + // Lets get down to business, + // To defeat, the huns. + int baseRepairAmount = repairable.getBaseRepairDurability(); // Did they send me daughters? + short newDurability = repairCalculate(startDurability, baseRepairAmount); // When I asked for sons? + + // We're going to hold onto our repair item location + int repairItemLocation; + if (repairable.getRepairMaterialMetadata() == (byte) -1) { + repairItemLocation = Repair.findInInventory(inventory, repairMaterialId); + } + else { + // Special case for when the repairable has metadata that must be addressed + repairItemLocation = Repair.findInInventory(inventory, repairMaterialId, repairMaterialMetadata); + } + + // This should never happen, but if it does we need to complain loudly about it. + if (repairItemLocation == -1) { + player.sendMessage(LocaleLoader.getString("Repair.Error")); + return; + } + + // Call event + McMMOPlayerRepairCheckEvent event = new McMMOPlayerRepairCheckEvent(player, (short) (startDurability - newDurability), inventory.getItem(repairItemLocation), item); + mcMMO.p.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) { + return; + } + + // Handle the enchants + if (Repair.arcaneForgingEnchantLoss) { + addEnchants(item); + } + + // Remove the item + Repair.removeOneFrom(inventory, repairItemLocation); + + // Give out XP like candy + applyXpGain((int) ((startDurability - newDurability) * repairable.getXpMultiplier()) * 10); + + // BWONG BWONG BWONG + player.playSound(player.getLocation(), Sound.ANVIL_USE, Misc.ANVIL_USE_VOLUME, Misc.ANVIL_USE_PITCH); + + // Repair the item! + item.setDurability(newDurability); + } + + /** + * Gets the Arcane Forging rank + * + * @return the current Arcane Forging rank + */ + public int getArcaneForgingRank() { + int skillLevel = getSkillLevel(); + + for (Tier tier : Tier.values()) { + if (skillLevel >= tier.getLevel()) { + return tier.toNumerical(); + } + } + + return 0; + } + + /** + * Gets chance of keeping enchantment during repair. + * + * @return The chance of keeping the enchantment + */ + public int getKeepEnchantChance() { + int skillLevel = getSkillLevel(); + + for (Tier tier : Tier.values()) { + if (skillLevel >= tier.getLevel()) { + return tier.getKeepEnchantChance(); + } + } + + return 0; + } + + /** + * Gets chance of enchantment being downgraded during repair. + * + * @return The chance of the enchantment being downgraded + */ + public int getDowngradeEnchantChance() { + int skillLevel = getSkillLevel(); + + for (Tier tier : Tier.values()) { + if (skillLevel >= tier.getLevel()) { + return tier.getDowngradeEnchantChance(); + } + } + + return 100; + } + + /** + * Computes repair bonuses. + * + * @param durability The durability of the item being repaired + * @param repairAmount The base amount of durability repaired to the item + * @return The final amount of durability repaired to the item + */ + private short repairCalculate(short durability, int repairAmount) { + Player player = getPlayer(); + + if (Permissions.repairMastery(player)) { + double bonus = repairAmount * Math.min((((Repair.repairMasteryMaxBonus / Repair.repairMasteryMaxBonusLevel) * getSkillLevel()) / 100.0D), Repair.repairMasteryMaxBonus / 100.0D); + repairAmount += bonus; + } + + if (Permissions.superRepair(player) && checkPlayerProcRepair()) { + repairAmount *= 2.0D; + } + + if (repairAmount <= 0 || repairAmount > Short.MAX_VALUE) { + repairAmount = Short.MAX_VALUE; + } + + return (short) Math.max(durability - repairAmount, 0); + } + + /** + * Checks for Super Repair bonus. + * + * @return true if bonus granted, false otherwise + */ + private boolean checkPlayerProcRepair() { + if (SkillUtils.activationSuccessful(getSkillLevel(), getActivationChance(), Repair.superRepairMaxChance, Repair.superRepairMaxBonusLevel)) { + getPlayer().sendMessage(LocaleLoader.getString("Repair.Skills.FeltEasy")); + return true; + } + + return false; + } + + /** + * Handles removing & downgrading enchants. + * + * @param item Item being repaired + */ + private void addEnchants(ItemStack item) { + Player player = getPlayer(); + + if (Permissions.arcaneBypass(player)) { + player.sendMessage(LocaleLoader.getString("Repair.Arcane.Perfect")); + return; + } + + Map enchants = item.getEnchantments(); + + if (enchants.size() == 0) { + return; + } + + if (getArcaneForgingRank() == 0 || !Permissions.arcaneForging(player)) { + for (Enchantment enchant : enchants.keySet()) { + item.removeEnchantment(enchant); + } + + player.sendMessage(LocaleLoader.getString("Repair.Arcane.Lost")); + return; + } + + boolean downgraded = false; + + for (Entry enchant : enchants.entrySet()) { + Enchantment enchantment = enchant.getKey(); + + if (getKeepEnchantChance() > Misc.getRandom().nextInt(activationChance)) { + int enchantLevel = enchant.getValue(); + + if (Repair.arcaneForgingDowngrades && enchantLevel > 1 && getDowngradeEnchantChance() > Misc.getRandom().nextInt(activationChance)) { + item.addEnchantment(enchantment, enchantLevel--); + downgraded = true; + } + } + else { + item.removeEnchantment(enchantment); + } + } + + Map newEnchants = item.getEnchantments(); + + if (newEnchants.isEmpty()) { + player.sendMessage(LocaleLoader.getString("Repair.Arcane.Fail")); + } + else if (downgraded || newEnchants.size() < enchants.size()) { + player.sendMessage(LocaleLoader.getString("Repair.Arcane.Downgrade")); + } + else { + player.sendMessage(LocaleLoader.getString("Repair.Arcane.Perfect")); + } + } +} diff --git a/src/main/java/com/gmail/nossr50/skills/repair/RepairManagerFactory.java b/src/main/java/com/gmail/nossr50/skills/repair/RepairManagerFactory.java deleted file mode 100644 index dcdec8e6c..000000000 --- a/src/main/java/com/gmail/nossr50/skills/repair/RepairManagerFactory.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.gmail.nossr50.skills.repair; - -public class RepairManagerFactory { - public static RepairManager getRepairManager() { - // TODO: Add in loading from config what type of manager we want. - return new SimpleRepairManager(); - } - - public static RepairManager getRepairManager(int repairablesSize) { - // TODO: Add in loading from config what type of manager we want. - return new SimpleRepairManager(repairablesSize); - } -} diff --git a/src/main/java/com/gmail/nossr50/skills/repair/RepairableManager.java b/src/main/java/com/gmail/nossr50/skills/repair/RepairableManager.java new file mode 100644 index 000000000..41f1ab067 --- /dev/null +++ b/src/main/java/com/gmail/nossr50/skills/repair/RepairableManager.java @@ -0,0 +1,45 @@ +package com.gmail.nossr50.skills.repair; + +import java.util.List; + +import org.bukkit.inventory.ItemStack; + +public interface RepairableManager { + /** + * Register a repairable with the RepairManager + * + * @param repairable Repairable to register + */ + public void registerRepairable(Repairable repairable); + + /** + * Register a list of repairables with the RepairManager + * + * @param repairables List to register + */ + public void registerRepairables(List repairables); + + /** + * Checks if an item is repairable + * + * @param itemId id to check if repairable + * @return true if repairable, false if not + */ + public boolean isRepairable(int itemId); + + /** + * Checks if an item is repairable + * + * @param itemStack Item to check if repairable + * @return true if repairable, false if not + */ + public boolean isRepairable(ItemStack itemStack); + + /** + * Gets the repairable with this id + * + * @param id Id of the repairable to look for + * @return the repairable, can be null + */ + public Repairable getRepairable(int id); +} diff --git a/src/main/java/com/gmail/nossr50/skills/repair/RepairableManagerFactory.java b/src/main/java/com/gmail/nossr50/skills/repair/RepairableManagerFactory.java new file mode 100644 index 000000000..32cdd47b9 --- /dev/null +++ b/src/main/java/com/gmail/nossr50/skills/repair/RepairableManagerFactory.java @@ -0,0 +1,13 @@ +package com.gmail.nossr50.skills.repair; + +public class RepairableManagerFactory { + public static RepairableManager getRepairManager() { + // TODO: Add in loading from config what type of manager we want. + return new SimpleRepairableManager(); + } + + public static RepairableManager getRepairManager(int repairablesSize) { + // TODO: Add in loading from config what type of manager we want. + return new SimpleRepairableManager(repairablesSize); + } +} diff --git a/src/main/java/com/gmail/nossr50/skills/repair/SimpleRepairManager.java b/src/main/java/com/gmail/nossr50/skills/repair/SimpleRepairManager.java deleted file mode 100644 index ffdb1aa28..000000000 --- a/src/main/java/com/gmail/nossr50/skills/repair/SimpleRepairManager.java +++ /dev/null @@ -1,214 +0,0 @@ -package com.gmail.nossr50.skills.repair; - -import java.util.HashMap; -import java.util.List; - -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.PlayerInventory; - -import com.gmail.nossr50.config.AdvancedConfig; -import com.gmail.nossr50.datatypes.player.McMMOPlayer; -import com.gmail.nossr50.datatypes.skills.SkillType; -import com.gmail.nossr50.events.skills.repair.McMMOPlayerRepairCheckEvent; -import com.gmail.nossr50.locale.LocaleLoader; -import com.gmail.nossr50.util.Permissions; -import com.gmail.nossr50.util.StringUtils; -import com.gmail.nossr50.util.skills.SkillUtils; - -public class SimpleRepairManager implements RepairManager { - private HashMap repairables; - - protected SimpleRepairManager() { - this(55); - } - - protected SimpleRepairManager(int repairablesSize) { - this.repairables = new HashMap(repairablesSize); - } - - @Override - public void registerRepairable(Repairable repairable) { - Integer itemId = repairable.getItemId(); - repairables.put(itemId, repairable); - } - - @Override - public void registerRepairables(List repairables) { - for (Repairable repairable : repairables) { - registerRepairable(repairable); - } - } - - @Override - public boolean isRepairable(int itemId) { - return repairables.containsKey(itemId); - } - - @Override - public boolean isRepairable(ItemStack itemStack) { - return isRepairable(itemStack.getTypeId()); - } - - @Override - public Repairable getRepairable(int id) { - return repairables.get(id); - } - - @Override - public void handleRepair(McMMOPlayer mcMMOPlayer, ItemStack item) { - Player player = mcMMOPlayer.getPlayer(); - Repairable repairable = repairables.get(item.getTypeId()); - - // Permissions checks on material and item types - if (!repairable.getRepairItemType().getPermissions(player)) { - player.sendMessage(LocaleLoader.getString("mcMMO.NoPermission")); - return; - } - - if (!repairable.getRepairMaterialType().getPermissions(player)) { - player.sendMessage(LocaleLoader.getString("mcMMO.NoPermission")); - return; - } - - int skillLevel = mcMMOPlayer.getProfile().getSkillLevel(SkillType.REPAIR); - - // Level check - if (skillLevel < repairable.getMinimumLevel()) { - player.sendMessage(LocaleLoader.getString("Repair.Skills.Adept", repairable.getMinimumLevel(), StringUtils.getPrettyItemString(item.getTypeId()))); - return; - } - - PlayerInventory inventory = player.getInventory(); - - // Check if they have the proper material to repair with - if (!inventory.contains(repairable.getRepairMaterialId())) { - String message = LocaleLoader.getString("Skills.NeedMore", StringUtils.getPrettyItemString(repairable.getRepairMaterialId())); - if (repairable.getRepairMaterialMetadata() != (byte) -1) { - // TODO: Do something nicer than append the metadata as a :# ? - if (findInInventory(inventory, repairable.getRepairMaterialId(), repairable.getRepairMaterialMetadata()) == -1) { - message += ":" + repairable.getRepairMaterialMetadata(); - } - } - player.sendMessage(message); - return; - } - - short startDurability = item.getDurability(); - - // Do not repair if at full durability - if (startDurability <= 0) { - player.sendMessage(LocaleLoader.getString("Repair.Skills.FullDurability")); - return; - } - - // Do not repair stacked items - if (item.getAmount() != 1) { - player.sendMessage(LocaleLoader.getString("Repair.Skills.StackedItems")); - return; - } - - // Clear ability buffs before trying to repair. - SkillUtils.removeAbilityBuff(item); - - // Lets get down to business, - // To defeat, the huns. - int baseRepairAmount = repairable.getBaseRepairDurability(); // Did they send me daughters? - short newDurability = Repair.repairCalculate(player, skillLevel, startDurability, baseRepairAmount); // When I asked for sons? - - // We're going to hold onto our repair item location - int repairItemLocation; - if (repairable.getRepairMaterialMetadata() == (byte) -1) { - repairItemLocation = findInInventory(inventory, repairable.getRepairMaterialId()); - } - else { - // Special case for when the repairable has metadata that must be addressed - repairItemLocation = findInInventory(inventory, repairable.getRepairMaterialId(), repairable.getRepairMaterialMetadata()); - } - - // This should never happen, but if it does we need to complain loudly about it. - if (repairItemLocation == -1) { - player.sendMessage(LocaleLoader.getString("Repair.Error")); - return; - } - - // Call event - McMMOPlayerRepairCheckEvent event = new McMMOPlayerRepairCheckEvent(player, (short) (startDurability - newDurability), inventory.getItem(repairItemLocation), item); - Bukkit.getServer().getPluginManager().callEvent(event); - - if (event.isCancelled()) { - return; - } - - // Handle the enchants - if (AdvancedConfig.getInstance().getArcaneForgingEnchantLossEnabled() && !Permissions.arcaneBypass(player)) { - // Generalize away enchantment work - Repair.addEnchants(player, item); - } - - // Remove the item - removeOneFrom(inventory, repairItemLocation); - - // Give out XP like candy - Repair.xpHandler(mcMMOPlayer, startDurability, newDurability, repairable.getXpMultiplier()); - - // Repair the item! - item.setDurability(newDurability); - } - - /** - * Decrease the amount of items in this slot by one - * - * @param inventory PlayerInventory to work in - * @param index Item index to decrement - */ - private void removeOneFrom(PlayerInventory inventory, int index) { - ItemStack item = inventory.getItem(index).clone(); - item.setAmount(1); - - inventory.removeItem(item); - } - - /** - * Search the inventory for an item and return the index. - * - * @param inventory PlayerInventory to scan - * @param itemId Item id to look for - * @return index location where the item was found, or -1 if not found - */ - private int findInInventory(PlayerInventory inventory, int itemId) { - int location = inventory.first(itemId); - - // VALIDATE - if (inventory.getItem(location).getTypeId() == itemId) { - return location; - } - - return -1; - } - - /** - * Search the inventory for an item and return the index. - * - * @param inventory PlayerInventory to scan - * @param itemId Item id to look for - * @param metadata Metadata to look for - * @return index location where the item was found, or -1 if not found - */ - private int findInInventory(PlayerInventory inventory, int itemId, byte metadata) { - int location = -1; - - for (ItemStack item : inventory.getContents()) { - if (item == null) { - continue; - } - - if (item.getTypeId() == itemId && item.getData().getData() == metadata) { - return location; - } - } - - return location; - } -} diff --git a/src/main/java/com/gmail/nossr50/skills/repair/SimpleRepairableManager.java b/src/main/java/com/gmail/nossr50/skills/repair/SimpleRepairableManager.java new file mode 100644 index 000000000..ae1e7f089 --- /dev/null +++ b/src/main/java/com/gmail/nossr50/skills/repair/SimpleRepairableManager.java @@ -0,0 +1,46 @@ +package com.gmail.nossr50.skills.repair; + +import java.util.HashMap; +import java.util.List; + +import org.bukkit.inventory.ItemStack; + +public class SimpleRepairableManager implements RepairableManager { + private HashMap repairables; + + protected SimpleRepairableManager() { + this(55); + } + + protected SimpleRepairableManager(int repairablesSize) { + this.repairables = new HashMap(repairablesSize); + } + + @Override + public void registerRepairable(Repairable repairable) { + Integer itemId = repairable.getItemId(); + repairables.put(itemId, repairable); + } + + @Override + public void registerRepairables(List repairables) { + for (Repairable repairable : repairables) { + registerRepairable(repairable); + } + } + + @Override + public boolean isRepairable(int itemId) { + return repairables.containsKey(itemId); + } + + @Override + public boolean isRepairable(ItemStack itemStack) { + return isRepairable(itemStack.getTypeId()); + } + + @Override + public Repairable getRepairable(int id) { + return repairables.get(id); + } +}