From f8b44cd8ceb0209e952792bd90087ceeff844409 Mon Sep 17 00:00:00 2001
From: TfT_02 <tft_02@hotmail.com>
Date: Tue, 13 Nov 2012 16:50:00 +0100
Subject: [PATCH] New Salvage ability for Repair!

Added a fully working ability to Repair. With this ability you can
salvage items and get bars in return.

- Added new permission node for Salvage ability
- Added new config options for Salvage
- Added new locale strings for Salvage
- Added a check to make sure that Repair Anvil != Salvage Anvil
---
 .../commands/skills/RepairCommand.java        |  11 +-
 .../java/com/gmail/nossr50/config/Config.java |   5 +
 .../nossr50/datatypes/PlayerProfile.java      |  13 +-
 .../nossr50/listeners/BlockListener.java      |   4 +
 .../nossr50/listeners/PlayerListener.java     |  11 +
 src/main/java/com/gmail/nossr50/mcMMO.java    |   5 +
 .../gmail/nossr50/skills/repair/Salvage.java  | 219 ++++++++++++++++++
 .../com/gmail/nossr50/util/BlockChecks.java   |   2 +-
 .../com/gmail/nossr50/util/Permissions.java   |   5 +
 src/main/resources/config.yml                 |   5 +
 .../resources/locale/locale_en_US.properties  |   6 +
 src/main/resources/plugin.yml                 |   3 +
 12 files changed, 286 insertions(+), 3 deletions(-)
 create mode 100644 src/main/java/com/gmail/nossr50/skills/repair/Salvage.java

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 89aab4651..d4b17bad4 100644
--- a/src/main/java/com/gmail/nossr50/commands/skills/RepairCommand.java
+++ b/src/main/java/com/gmail/nossr50/commands/skills/RepairCommand.java
@@ -16,6 +16,7 @@ public class RepairCommand extends SkillCommand {
     private boolean canSuperRepair;
     private boolean canMasterRepair;
     private boolean canArcaneForge;
+    private boolean canSalvage;
     private boolean canRepairStone;
     private boolean canRepairIron;
     private boolean canRepairGold;
@@ -24,6 +25,7 @@ public class RepairCommand extends SkillCommand {
     private boolean canRepairLeather;
     private boolean canRepairWood;
 
+    private int salvageLevel;
     private int diamondLevel;
     private int goldLevel;
     private int ironLevel;
@@ -45,6 +47,8 @@ public class RepairCommand extends SkillCommand {
         goldLevel = (goldRepairable == null) ? 0 : goldRepairable.getMinimumLevel();
         ironLevel = (ironRepairable == null) ? 0 : ironRepairable.getMinimumLevel();
         stoneLevel = (stoneRepairable == null) ? 0 : stoneRepairable.getMinimumLevel();
+        
+        salvageLevel = Config.getInstance().getSalvageUnlockLevel();
 
         repairMasteryBonus = percent.format(skillValue / 500);
 
@@ -63,6 +67,7 @@ public class RepairCommand extends SkillCommand {
         canSuperRepair = permInstance.repairBonus(player);
         canMasterRepair = permInstance.repairMastery(player);
         canArcaneForge = permInstance.arcaneForging(player);
+        canSalvage = permInstance.salvage(player);
         canRepairDiamond = permInstance.diamondRepair(player);
         canRepairGold = permInstance.goldRepair(player);
         canRepairIron = permInstance.ironRepair(player);
@@ -74,7 +79,7 @@ public class RepairCommand extends SkillCommand {
 
     @Override
     protected boolean effectsHeaderPermissions() {
-        return canArcaneForge || canRepairDiamond || canRepairGold || canRepairIron || canMasterRepair || canRepairStone || canSuperRepair || canRepairString || canRepairWood || canRepairLeather;
+        return canArcaneForge || canSalvage || canRepairDiamond || canRepairGold || canRepairIron || canMasterRepair || canRepairStone || canSuperRepair || canRepairString || canRepairWood || canRepairLeather;
     }
 
     @Override
@@ -107,6 +112,10 @@ public class RepairCommand extends SkillCommand {
             player.sendMessage(LocaleLoader.getString("Effects.Template", new Object[] { LocaleLoader.getString("Repair.Effect.6", new Object[] { diamondLevel }), LocaleLoader.getString("Repair.Effect.7") }));
         }
 
+        if (canSalvage && salvageLevel > 0) {
+            player.sendMessage(LocaleLoader.getString("Effects.Template", new Object[] { LocaleLoader.getString("Repair.Effect.16", new Object[] { salvageLevel }), LocaleLoader.getString("Repair.Effect.17") }));
+        }
+
         if (canArcaneForge) {
             player.sendMessage(LocaleLoader.getString("Effects.Template", new Object[] { LocaleLoader.getString("Repair.Effect.8"), LocaleLoader.getString("Repair.Effect.9") }));
         }
diff --git a/src/main/java/com/gmail/nossr50/config/Config.java b/src/main/java/com/gmail/nossr50/config/Config.java
index 06051229a..bc24028d0 100644
--- a/src/main/java/com/gmail/nossr50/config/Config.java
+++ b/src/main/java/com/gmail/nossr50/config/Config.java
@@ -270,6 +270,11 @@ public class Config extends ConfigLoader {
     /* Repair */
     public boolean getRepairAnvilMessagesEnabled() { return config.getBoolean("Skills.Repair.Anvil_Messages", true); }
     public int getRepairAnvilId() { return config.getInt("Skills.Repair.Anvil_ID", 42); }
+    public boolean getSalvageEnabled() { return config.getBoolean("Skills.Repair.Salvage_enabled", true); }
+    public int getSalvageAnvilId() { return config.getInt("Skills.Repair.Salvage_Anvil_ID", 41); }
+    public int getSalvageUnlockLevel() { return config.getInt("Skills.Repair.Salvage_UnlockLevel", 600); }
+    public boolean getSalvageTools() { return config.getBoolean("Skills.Repair.Salvage_tools", true); }
+    public boolean getSalvageArmor() { return config.getBoolean("Skills.Repair.Salvage_armor", true); }
 
     /* Taming */
     public int getTamingXPWolf() { return config.getInt("Experience.Taming.Animal_Taming.Wolf", 250); }
diff --git a/src/main/java/com/gmail/nossr50/datatypes/PlayerProfile.java b/src/main/java/com/gmail/nossr50/datatypes/PlayerProfile.java
index b0b0c4f50..4806fc2ec 100644
--- a/src/main/java/com/gmail/nossr50/datatypes/PlayerProfile.java
+++ b/src/main/java/com/gmail/nossr50/datatypes/PlayerProfile.java
@@ -31,6 +31,7 @@ public class PlayerProfile {
     private boolean loaded;
 
     private boolean placedAnvil;
+    private boolean placedSalvageAnvil;
     private boolean partyChatMode, adminChatMode;
     private boolean godMode;
     private boolean greenTerraMode, treeFellerMode, superBreakerMode, gigaDrillBreakerMode, serratedStrikesMode, skullSplitterMode, berserkMode;
@@ -491,7 +492,7 @@ public class PlayerProfile {
     }
 
     /*
-     * Anvil Placement
+     * Repair Anvil Placement
      */
 
     public void togglePlacedAnvil() {
@@ -501,6 +502,16 @@ public class PlayerProfile {
     public Boolean getPlacedAnvil() {
         return placedAnvil;
     }
+    /*
+     * Salvage Anvil Placement
+     */
+    public void togglePlacedSalvageAnvil() {
+    	placedSalvageAnvil = !placedSalvageAnvil;
+    }
+
+    public Boolean getPlacedSalvageAnvil() {
+        return placedSalvageAnvil;
+    }
 
     /*
      * HUD Stuff
diff --git a/src/main/java/com/gmail/nossr50/listeners/BlockListener.java b/src/main/java/com/gmail/nossr50/listeners/BlockListener.java
index 21b9c3a2e..6acd9edbb 100644
--- a/src/main/java/com/gmail/nossr50/listeners/BlockListener.java
+++ b/src/main/java/com/gmail/nossr50/listeners/BlockListener.java
@@ -34,6 +34,7 @@ import com.gmail.nossr50.skills.gathering.Herbalism;
 import com.gmail.nossr50.skills.gathering.Mining;
 import com.gmail.nossr50.skills.gathering.WoodCutting;
 import com.gmail.nossr50.skills.repair.Repair;
+import com.gmail.nossr50.skills.repair.Salvage;
 import com.gmail.nossr50.spout.SpoutSounds;
 import com.gmail.nossr50.util.BlockChecks;
 import com.gmail.nossr50.util.ItemChecks;
@@ -154,6 +155,9 @@ public class BlockListener implements Listener {
         if (id == configInstance.getRepairAnvilId() && configInstance.getRepairAnvilMessagesEnabled()) {
             Repair.placedAnvilCheck(player, id);
         }
+        if (id == configInstance.getSalvageAnvilId() && configInstance.getRepairAnvilMessagesEnabled()) {
+            Salvage.placedAnvilCheck(player, id);
+        }
     }
 
     /**
diff --git a/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java b/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java
index 165b3425f..750366516 100644
--- a/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java
+++ b/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java
@@ -1,6 +1,7 @@
 package com.gmail.nossr50.listeners;
 
 import org.bukkit.ChatColor;
+import org.bukkit.Location;
 import org.bukkit.Material;
 import org.bukkit.block.Block;
 import org.bukkit.entity.LivingEntity;
@@ -36,6 +37,7 @@ import com.gmail.nossr50.runnables.BleedTimer;
 import com.gmail.nossr50.skills.gathering.BlastMining;
 import com.gmail.nossr50.skills.gathering.Fishing;
 import com.gmail.nossr50.skills.gathering.Herbalism;
+import com.gmail.nossr50.skills.repair.Salvage;
 import com.gmail.nossr50.skills.taming.TamingManager;
 import com.gmail.nossr50.util.BlockChecks;
 import com.gmail.nossr50.util.Item;
@@ -259,6 +261,15 @@ public class PlayerListener implements Listener {
                     player.updateInventory();
                 }
             }
+            /* SALVAGE CHECKS */
+            if (Permissions.getInstance().salvage(player) && block.getTypeId() == Config.getInstance().getSalvageAnvilId()) {
+                if (Salvage.isSalvageable(inHand)) {
+					final Location location = block.getLocation();
+                	Salvage.handleSalvage(player, location, inHand);
+                    event.setCancelled(true);
+                    player.updateInventory();
+                }
+            }
 
             /* ACTIVATION CHECKS */
             if (Config.getInstance().getAbilitiesEnabled() && BlockChecks.abilityBlockCheck(block)) {
diff --git a/src/main/java/com/gmail/nossr50/mcMMO.java b/src/main/java/com/gmail/nossr50/mcMMO.java
index 7286b9dd5..1fad77781 100644
--- a/src/main/java/com/gmail/nossr50/mcMMO.java
+++ b/src/main/java/com/gmail/nossr50/mcMMO.java
@@ -145,6 +145,11 @@ public class mcMMO extends JavaPlugin {
         repairables.addAll(rManager.getLoadedRepairables());
         repairManager = RepairManagerFactory.getRepairManager(repairables.size());
         repairManager.registerRepairables(repairables);
+        
+        //Check if Repair Anvil and Salvage Anvil have different itemID's
+        if (configInstance.getSalvageAnvilId() == configInstance.getRepairAnvilId()){
+        	System.out.println("[WARNING!] Can't use the same itemID for Repair/Salvage Anvils!" );
+        }
 
         if (!configInstance.getUseMySQL()) {
             Users.loadUsers();
diff --git a/src/main/java/com/gmail/nossr50/skills/repair/Salvage.java b/src/main/java/com/gmail/nossr50/skills/repair/Salvage.java
new file mode 100644
index 000000000..2ab52d136
--- /dev/null
+++ b/src/main/java/com/gmail/nossr50/skills/repair/Salvage.java
@@ -0,0 +1,219 @@
+package com.gmail.nossr50.skills.repair;
+
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.World;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
+import org.getspout.spoutapi.SpoutManager;
+import org.getspout.spoutapi.player.SpoutPlayer;
+
+import com.gmail.nossr50.mcMMO;
+import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.datatypes.PlayerProfile;
+import com.gmail.nossr50.datatypes.SkillType;
+import com.gmail.nossr50.locale.LocaleLoader;
+import com.gmail.nossr50.util.ItemChecks;
+import com.gmail.nossr50.util.Permissions;
+import com.gmail.nossr50.util.Users;
+
+public class Salvage {
+
+	private static Config configInstance = Config.getInstance();
+	private static Permissions permInstance = Permissions.getInstance();
+
+	public static void handleSalvage(final Player player, final Location location, final ItemStack inHand) {
+		if (!permInstance.salvage(player) || !configInstance.getSalvageEnabled()) {
+			return;
+		}
+
+		final PlayerProfile profile = Users.getProfile(player);
+		final int skillLevel = profile.getSkillLevel(SkillType.REPAIR);
+		final int unlockLevel = configInstance.getSalvageUnlockLevel();
+
+		if (skillLevel >= unlockLevel) {
+			final World world = player.getWorld();
+			final float currentdura = inHand.getDurability();
+
+			if (currentdura == 0) {
+				final int salvagedAmount = getSalvagedAmount(inHand);
+				final int itemID = getSalvagedItemID(inHand);
+
+				player.setItemInHand(new ItemStack(0));
+				location.setY(location.getY() + 1);
+				world.dropItem(location, new ItemStack(itemID, salvagedAmount));
+                player.sendMessage(LocaleLoader.getString("Repair.Skills.SalvageSuccess"));
+			} else {
+                player.sendMessage(LocaleLoader.getString("Repair.Skills.NotFullDurability"));
+			}
+		} else {
+            player.sendMessage(LocaleLoader.getString("Repair.Skills.AdeptSalvage"));
+		}
+	}
+
+	public static int getSalvagedItemID(final ItemStack inHand) {
+		int salvagedItem = 0;
+		switch (inHand.getType()) {
+		case DIAMOND_PICKAXE:
+		case DIAMOND_SPADE:
+		case DIAMOND_AXE:
+		case DIAMOND_SWORD:
+		case DIAMOND_HOE:
+		case DIAMOND_HELMET:
+		case DIAMOND_CHESTPLATE:
+		case DIAMOND_LEGGINGS:
+		case DIAMOND_BOOTS:
+			salvagedItem = 264;
+			break;
+		case GOLD_PICKAXE:
+		case GOLD_SPADE:
+		case GOLD_AXE:
+		case GOLD_SWORD:
+		case GOLD_HOE:
+		case GOLD_HELMET:
+		case GOLD_CHESTPLATE:
+		case GOLD_LEGGINGS:
+		case GOLD_BOOTS:
+			salvagedItem = 266;
+			break;
+		case IRON_PICKAXE:
+		case IRON_SPADE:
+		case IRON_AXE:
+		case IRON_SWORD:
+		case IRON_HOE:
+		case IRON_HELMET:
+		case IRON_CHESTPLATE:
+		case IRON_LEGGINGS:
+		case IRON_BOOTS:
+			salvagedItem = 265;
+			break;
+		case STONE_PICKAXE:
+		case STONE_SPADE:
+		case STONE_AXE:
+		case STONE_SWORD:
+		case STONE_HOE:
+			salvagedItem = 4;
+			break;
+		case WOOD_PICKAXE:
+		case WOOD_SPADE:
+		case WOOD_AXE:
+		case WOOD_SWORD:
+		case WOOD_HOE:
+			salvagedItem = 5;
+			break;
+		case LEATHER_HELMET:
+		case LEATHER_CHESTPLATE:
+		case LEATHER_LEGGINGS:
+		case LEATHER_BOOTS:
+			salvagedItem = 334;
+			break;
+		default:
+			break;
+		}
+		return salvagedItem;
+	}
+
+	public static int getSalvagedAmount(final ItemStack inHand) {
+		int salvagedAmount = 0;
+		switch (inHand.getType()) {
+		case DIAMOND_PICKAXE:
+		case GOLD_PICKAXE:
+		case IRON_PICKAXE:
+		case STONE_PICKAXE:
+		case WOOD_PICKAXE:
+		case DIAMOND_AXE:
+		case GOLD_AXE:
+		case IRON_AXE:
+		case STONE_AXE:
+		case WOOD_AXE:
+			salvagedAmount = 3;
+			break;
+		case DIAMOND_SPADE:
+		case GOLD_SPADE:
+		case IRON_SPADE:
+		case STONE_SPADE:
+		case WOOD_SPADE:
+			salvagedAmount = 1;
+			break;
+		case DIAMOND_SWORD:
+		case GOLD_SWORD:
+		case IRON_SWORD:
+		case STONE_SWORD:
+		case WOOD_SWORD:
+		case DIAMOND_HOE:
+		case GOLD_HOE:
+		case IRON_HOE:
+		case STONE_HOE:
+		case WOOD_HOE:
+			salvagedAmount = 2;
+			break;
+		case DIAMOND_HELMET:
+		case GOLD_HELMET:
+		case IRON_HELMET:
+		case LEATHER_HELMET:
+			salvagedAmount = 5;
+			break;
+		case DIAMOND_CHESTPLATE:
+		case GOLD_CHESTPLATE:
+		case IRON_CHESTPLATE:
+		case LEATHER_CHESTPLATE:
+			salvagedAmount = 8;
+			break;
+		case DIAMOND_LEGGINGS:
+		case GOLD_LEGGINGS:
+		case IRON_LEGGINGS:
+		case LEATHER_LEGGINGS:
+			salvagedAmount = 7;
+			break;
+		case DIAMOND_BOOTS:
+		case GOLD_BOOTS:
+		case IRON_BOOTS:
+		case LEATHER_BOOTS:
+			salvagedAmount = 4;
+			break;
+		default:
+			break;
+		}
+		return salvagedAmount;
+	}
+
+	/**
+	 * 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(final Player player, final int anvilID) {
+		final PlayerProfile profile = Users.getProfile(player);
+
+		if (!profile.getPlacedSalvageAnvil()) {
+			if (mcMMO.spoutEnabled) {
+				final SpoutPlayer spoutPlayer = SpoutManager.getPlayer(player);
+
+				if (spoutPlayer.isSpoutCraftEnabled()) {
+					spoutPlayer.sendNotification("[mcMMO] Anvil Placed", "Right click to salvage!", Material.getMaterial(anvilID));
+				}
+			} else {
+                player.sendMessage(LocaleLoader.getString("Repair.Listener.Anvil2"));
+			}
+
+			profile.togglePlacedSalvageAnvil();
+		}
+	}
+
+	/**
+	 * Checks if the item is salvageable.
+	 * 
+	 * @param is Item to check
+	 * @return true if the item is salvageable, false otherwise
+	 */
+	public static boolean isSalvageable(final ItemStack is) {
+		if (configInstance.getSalvageTools() && ItemChecks.isTool(is)) {
+			return true;
+		}
+		if (configInstance.getSalvageArmor() && ItemChecks.isArmor(is)) {
+			return true;
+		}
+		return false;
+	}
+}
diff --git a/src/main/java/com/gmail/nossr50/util/BlockChecks.java b/src/main/java/com/gmail/nossr50/util/BlockChecks.java
index 82b055eeb..18c6c35eb 100644
--- a/src/main/java/com/gmail/nossr50/util/BlockChecks.java
+++ b/src/main/java/com/gmail/nossr50/util/BlockChecks.java
@@ -105,7 +105,7 @@ public class BlockChecks {
             return false;
 
         default:
-            if (block.getTypeId() == Config.getInstance().getRepairAnvilId()) {
+            if (block.getTypeId() == Config.getInstance().getRepairAnvilId() | block.getTypeId() == Config.getInstance().getSalvageAnvilId()) {
                 return false;
             }
             else {
diff --git a/src/main/java/com/gmail/nossr50/util/Permissions.java b/src/main/java/com/gmail/nossr50/util/Permissions.java
index d72f4bbb8..7cad1b6f6 100644
--- a/src/main/java/com/gmail/nossr50/util/Permissions.java
+++ b/src/main/java/com/gmail/nossr50/util/Permissions.java
@@ -208,6 +208,11 @@ public class Permissions {
         return player.hasPermission("mcmmo.ability.repair.stringrepair");
     }
 
+    public boolean salvage(Player player) {
+        return player.hasPermission("mcmmo.ability.repair.salvage");
+    }
+
+
     /*
      * MCMMO.ABILITY.UNARMED.*
      */
diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
index f0d202226..0335674a6 100644
--- a/src/main/resources/config.yml
+++ b/src/main/resources/config.yml
@@ -172,6 +172,11 @@ Skills:
         Level_Cap: 0
         Anvil_Messages: true
         Anvil_ID: 42
+        Salvage_enabled: true
+        Salvage_Anvil_ID: 41
+        Salvage_UnlockLevel: 600
+        Salvage_tools: true
+        Salvage_armor: true
     Swords:
         Enabled_For_PVP: true
         Enabled_For_PVE: true
diff --git a/src/main/resources/locale/locale_en_US.properties b/src/main/resources/locale/locale_en_US.properties
index 0bd4b8bf1..f7dcbf626 100644
--- a/src/main/resources/locale/locale_en_US.properties
+++ b/src/main/resources/locale/locale_en_US.properties
@@ -205,9 +205,13 @@ Repair.Effect.6=Diamond Repair ({0}+ SKILL)
 Repair.Effect.7=Repair Diamond Tools & Armor
 Repair.Effect.8=Arcane Forging
 Repair.Effect.9=Repair magic items
+Repair.Effect.16=Salvage ({0}+ SKILL)
+Repair.Effect.17=Salvage Tools & Armor
 Repair.Listener.Anvil=[[DARK_RED]]You have placed an anvil, anvils can repair tools and armor.
+Repair.Listener.Anvil2=[[DARK_RED]]You have placed a Salvage anvil, use this to Salvage tools and armor.
 Repair.Listener=Repair: 
 Repair.SkillName=REPAIR
+Repair.Skills.AdeptSalvage=[[DARK_RED]]You're not skilled enough to Salvage items.
 Repair.Skills.AdeptDiamond=[[DARK_RED]]You're not skilled enough to repair Diamond.
 Repair.Skills.AdeptGold=[[DARK_RED]]You're not skilled enough to repair Gold.
 Repair.Skills.AdeptIron=[[DARK_RED]]You're not skilled enough to repair Iron.
@@ -215,6 +219,8 @@ Repair.Skills.AdeptStone=[[DARK_RED]]You're not skilled enough to repair Stone.
 Repair.Skills.Adept=[[RED]]You must be level [[YELLOW]]{0}[[RED]] to repair [[YELLOW]]{1}
 Repair.Skills.FeltEasy=[[GRAY]]That felt easy.
 Repair.Skills.FullDurability=[[GRAY]]That is at full durability.
+Repair.Skills.SalvageSuccess=[[GRAY]]Item salvaged!
+Repair.Skills.NotFullDurability=[[DARK_RED]]You can't salvage damaged items.
 Repair.Skills.Mastery=[[RED]]Repair Mastery: [[YELLOW]]Extra {0} durability restored
 Repair.Skills.StackedItems=[[DARK_RED]]You can't repair stacked items.
 Repair.Skills.Super.Chance=[[RED]]Super Repair Chance: [[YELLOW]]{0}
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index e231df3e4..7cfc84091 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -366,6 +366,7 @@ permissions:
             mcmmo.ability.repair.repairbonus: true
             mcmmo.ability.repair.repairmastery: true
             mcmmo.ability.repair.arcaneforging: true
+            mcmmo.ability.repair.salvage: true
             mcmmo.ability.repair.woodrepair: true
             mcmmo.ability.repair.stonerepair: true
             mcmmo.ability.repair.leatherrepair: true
@@ -383,6 +384,8 @@ permissions:
         description: Allows access to Repair Mastery
     mcmmo.ability.repair.arcaneforging:
         description: Allows access to the Arcane Forging ability
+    mcmmo.ability.repair.salvage:
+        description: Allows access to the Salvage ability
     mcmmo.ability.repair.woodrepair:
         description: Allows ability to repair Wood tools
     mcmmo.ability.repair.stonerepair:
