diff --git a/Changelog.txt b/Changelog.txt index d2bb435d4..827dca26d 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -163,6 +163,68 @@ Version 2.2.0 Added API method to grab the level cap of a skill by its PrimarySkillType ENUM definition Added API method to check if a skill was being level capped Added 'UndefinedSkillBehaviour' for trying to use a method that has no behaviour defined for the provided skill +Version 2.1.77 + Added minimum quantity back to Repair config + + NOTES: I removed this last patch because I did not consider that server admins might be allowing users to repair items without crafting recipes (as of last patch mcMMO determines minimum quantity via counting ingredients in a recipe) + If you do not define minimum quantity in the repair config, mcMMO will grab the minimum quantity automatically as I programmed it to do as of last patch, otherwise if it is defined, mcMMO will respect that and use that for calculations. + The minimum quanitty should be set to the number of ingredients used to craft the recipe, for example 8 for diamond chestplate etc, you do not need to define this unless you are allowing players to repair custom items. + +Version 2.1.76 + Advanced Salvage has been renamed to Scrap Collector + Scrap Collector has 8 ranks, the first rank is unlocked at level 2 (Level 20 in RetroMode) + You can not salvage without at least 1 rank in Scrap Collector now (formerly Advanced Salvage) + Fixed a bug where Repair was repairing too much + Fixed a bug where Arcane Salvage was used to determine how many materials a player could salvage from an item instead of Scrap Collector (formerly Advanced Salvage) + Fixed a bug where messages about an item being too damage to salvage were being sent twice + Removed the minimum quantity field from the repair config + Removed the item data (metadata) field from repair config as its not used anymore + Salvage will no longer return the max amount of materials possible, instead you are guaranteed one item and then some luck is involved on how many items are returned. + Updated Chinese locale (thanks to the user named 89009332 from github) + + New locale strings + Salvage.Skills.Lottery.Normal + Salvage.Skills.Lottery.Perfect + Salvage.Skills.Lottery.Untrained + Salvage.SubSkill.ScrapCollector.Name + Salvage.SubSkill.ScrapCollector.Description + Salvage.SubSkill.ScrapCollector.Stat + + (API) SALVAGE_ARCANE_SALVAGE in SubSkillType has been renamed to SALVAGE_SCRAP_COLLECTOR + + NOTES: + You do not need to update your configs for this update. + + How Salvage works + As an example, say you had enough skill to gain up to 5 items from salvaging something, and that item has enough durability to yield up to 5 materials, salvage will play out like this... + First off, you will be guaranteed 1 material, after this you have 80% chance to get the next material, if successful, another dice roll is conducted but lowers your odds by 20%, you chance to succeed will never fall below 33% + If you fail a dice roll, it will still conduct dice rolls for the remaining maximum amount of materials returned but your odds of success are only lowered upon a successful dice roll, the sum of the successful dice rolls is used to calculate how many items you are given back, the first item is guaranteed and has no dice rolls, which means for example the Diamond Shovel will always succeed. + +Version 2.1.75 + Fixed a bug that prevented Fortune from working correctly if a Double Drop was triggered + +Version 2.1.74 + Fixed a NPE that could occur during certain events if a skill was disabled in coreskills.yml (Sorry!) + +Version 2.1.73 + Fixed a NPE that could occur if an entire skill was disabled in coreskills.yml + +Version 2.1.72 + Fixed a NPE if a server shutdown with no player data needing to be saved (the error is harmless but spammy) + Fixed a NPE that could occur if Roll was disabled in coreskills.yml + +Version 2.1.71 + Salvage will now always ask for confirmation before breaking your items (instead of only asking for enchanted items) + Repair will now always ask for confirmation before repairing items (instead of only asking for enchanted items) + Gold & Iron Blocks will no longer trigger tool ready messages + Salvage & Repair anvils will no longer work on multi-item stacks + + NOTES: You can still turn the confirmation off in config.yml + +Version 2.1.70 + Added new DatabaseAPI to the API package, has features relating to database operations + Fixed a bug where shulker boxes (without colors) would activate tool ready messages + Version 2.1.69 Fixed a few places where mcMMO would not save player data immediately which may cause players to lose a few minutes of progress diff --git a/src/main/java/com/gmail/nossr50/api/DatabaseAPI.java b/src/main/java/com/gmail/nossr50/api/DatabaseAPI.java new file mode 100644 index 000000000..76caad65b --- /dev/null +++ b/src/main/java/com/gmail/nossr50/api/DatabaseAPI.java @@ -0,0 +1,33 @@ +package com.gmail.nossr50.api; + +import com.gmail.nossr50.datatypes.player.PlayerProfile; +import com.gmail.nossr50.mcMMO; + +import java.util.UUID; + +public class DatabaseAPI { + + /** + * Checks if a player exists in the mcMMO Database + * @param uuid player UUID + * @return true if the player exists in the DB, false if they do not + */ + public boolean doesPlayerExistInDB(String uuid) { + return doesPlayerExistInDB(UUID.fromString(uuid)); + } + + /** + * Checks if a player exists in the mcMMO Database + * @param uuid player UUID + * @return true if the player exists in the DB, false if they do not + */ + public boolean doesPlayerExistInDB(UUID uuid) { + PlayerProfile playerProfile = mcMMO.getDatabaseManager().loadPlayerProfile(uuid); + + if(playerProfile.isLoaded()) + return true; + else + return false; + } + +} diff --git a/src/main/java/com/gmail/nossr50/commands/skills/SalvageCommand.java b/src/main/java/com/gmail/nossr50/commands/skills/SalvageCommand.java index cd4ffec81..82b6544d1 100644 --- a/src/main/java/com/gmail/nossr50/commands/skills/SalvageCommand.java +++ b/src/main/java/com/gmail/nossr50/commands/skills/SalvageCommand.java @@ -15,7 +15,7 @@ import java.util.ArrayList; import java.util.List; public class SalvageCommand extends SkillCommand { - private boolean canAdvancedSalvage; + private boolean canScrapCollector; private boolean canArcaneSalvage; public SalvageCommand() { @@ -30,7 +30,7 @@ public class SalvageCommand extends SkillCommand { @Override protected void permissionsCheck(Player player) { - canAdvancedSalvage = canUseSubskill(player, SubSkillType.SALVAGE_ADVANCED_SALVAGE); + canScrapCollector = canUseSubskill(player, SubSkillType.SALVAGE_SCRAP_COLLECTOR); canArcaneSalvage = canUseSubskill(player, SubSkillType.SALVAGE_ARCANE_SALVAGE); } @@ -39,9 +39,11 @@ public class SalvageCommand extends SkillCommand { List messages = new ArrayList<>(); SalvageManager salvageManager = UserManager.getPlayer(player).getSalvageManager(); - if (canAdvancedSalvage) { - messages.add(LocaleLoader.getString("Ability.Generic.Template", LocaleLoader.getString("Salvage.Ability.Bonus.0"), - LocaleLoader.getString("Salvage.Ability.Bonus.1", salvageManager.getSalvageableAmount()))); + if (canScrapCollector) { + messages.add(getStatMessage(false, true, + SubSkillType.SALVAGE_SCRAP_COLLECTOR, + String.valueOf(RankUtils.getRank(player, SubSkillType.SALVAGE_SCRAP_COLLECTOR)), + RankUtils.getHighestRankStr(SubSkillType.SALVAGE_SCRAP_COLLECTOR))); } if (canArcaneSalvage) { diff --git a/src/main/java/com/gmail/nossr50/core/MaterialMapStore.java b/src/main/java/com/gmail/nossr50/core/MaterialMapStore.java index ba064029b..544b28bd4 100644 --- a/src/main/java/com/gmail/nossr50/core/MaterialMapStore.java +++ b/src/main/java/com/gmail/nossr50/core/MaterialMapStore.java @@ -264,6 +264,7 @@ public class MaterialMapStore { abilityBlackList.add("light_gray_shulker_box"); abilityBlackList.add("white_shulker_box"); abilityBlackList.add("yellow_shulker_box"); + abilityBlackList.add("shulker_box"); abilityBlackList.add("wall_sign"); //1.13 and lower? abilityBlackList.add("sign"); //1.13 and lower? } @@ -353,6 +354,7 @@ public class MaterialMapStore { toolBlackList.add("light_gray_shulker_box"); toolBlackList.add("white_shulker_box"); toolBlackList.add("yellow_shulker_box"); + toolBlackList.add("shulker_box"); toolBlackList.add("acacia_sign"); toolBlackList.add("acacia_wall_sign"); toolBlackList.add("birch_sign"); @@ -389,6 +391,8 @@ public class MaterialMapStore { toolBlackList.add("oak_wood"); toolBlackList.add("spruce_log"); toolBlackList.add("spruce_wood"); + toolBlackList.add("iron_block"); + toolBlackList.add("gold_block"); } private void addToHashSet(String string, HashSet stringHashSet) { diff --git a/src/main/java/com/gmail/nossr50/core/SkillPropertiesManager.java b/src/main/java/com/gmail/nossr50/core/SkillPropertiesManager.java index 88bb3c636..daf753770 100644 --- a/src/main/java/com/gmail/nossr50/core/SkillPropertiesManager.java +++ b/src/main/java/com/gmail/nossr50/core/SkillPropertiesManager.java @@ -1,7 +1,6 @@ package com.gmail.nossr50.core; import com.gmail.nossr50.config.ConfigConstants; -import com.gmail.nossr50.config.hocon.HOCONUtil; import com.gmail.nossr50.datatypes.skills.PrimarySkillType; import com.gmail.nossr50.datatypes.skills.SubSkillType; import com.gmail.nossr50.datatypes.skills.properties.MaxBonusLevel; @@ -84,19 +83,24 @@ public class SkillPropertiesManager { CommentedConfigurationNode childNode = it.next(); - Object lastObjectInPath = childNode.getPath()[childNode.getPath().length + 1]; - + Object lastObjectInPath = childNode.getPath()[childNode.getPath().length - 1]; String nodeName = lastObjectInPath.toString(); - if(nodeName.equalsIgnoreCase(ConfigConstants.MAX_BONUS_LEVEL_FIELD_NAME)) { - attemptRegisterMaxBonusLevel(subSkillType, childNode); - } else if(nodeName.equalsIgnoreCase(ConfigConstants.MAX_CHANCE_FIELD_NAME)) { - attemptRegisterMaxChance(subSkillType, childNode); - } else if(nodeName.equalsIgnoreCase(ConfigConstants.STATIC_ACTIVATION_FIELD_NAME)) { - attemptRegisterStaticChance(subSkillType, childNode); - } else if(nodeName.equalsIgnoreCase(ConfigConstants.MAX_BONUS_PERCENTAGE_FIELD_NAME)) { - attemptRegisterMaxBonusPercentage(subSkillType, childNode); + switch(nodeName) { + case ConfigConstants.MAX_BONUS_LEVEL_FIELD_NAME: + attemptRegisterMaxBonusLevel(subSkillType, childNode); + break; + case ConfigConstants.MAX_CHANCE_FIELD_NAME: + attemptRegisterMaxChance(subSkillType, childNode); + break; + case ConfigConstants.STATIC_ACTIVATION_FIELD_NAME: + attemptRegisterStaticChance(subSkillType, childNode); + break; + case ConfigConstants.MAX_BONUS_PERCENTAGE_FIELD_NAME: + attemptRegisterMaxBonusPercentage(subSkillType, childNode); + break; } + } } } diff --git a/src/main/java/com/gmail/nossr50/datatypes/interactions/NotificationType.java b/src/main/java/com/gmail/nossr50/datatypes/interactions/NotificationType.java index 37bc8b8cd..3f3a8a086 100644 --- a/src/main/java/com/gmail/nossr50/datatypes/interactions/NotificationType.java +++ b/src/main/java/com/gmail/nossr50/datatypes/interactions/NotificationType.java @@ -20,6 +20,7 @@ public enum NotificationType { SUPER_ABILITY("SuperAbilityInteraction"), SUPER_ABILITY_ALERT_OTHERS("SuperAbilityAlertOthers"), ITEM_MESSAGE("ItemMessage"), + CHAT_ONLY("ChatOnly"), PARTY_MESSAGE("PartyMessage"); final String niceName; diff --git a/src/main/java/com/gmail/nossr50/datatypes/skills/PrimarySkillType.java b/src/main/java/com/gmail/nossr50/datatypes/skills/PrimarySkillType.java index e42d3149d..3c1cb267e 100644 --- a/src/main/java/com/gmail/nossr50/datatypes/skills/PrimarySkillType.java +++ b/src/main/java/com/gmail/nossr50/datatypes/skills/PrimarySkillType.java @@ -51,7 +51,7 @@ public enum PrimarySkillType { REPAIR(RepairManager.class, Color.SILVER, ImmutableList.of(SubSkillType.REPAIR_ARCANE_FORGING, SubSkillType.REPAIR_REPAIR_MASTERY, SubSkillType.REPAIR_SUPER_REPAIR), "Repair"), SALVAGE(SalvageManager.class, Color.ORANGE, - ImmutableList.of(SubSkillType.SALVAGE_ADVANCED_SALVAGE, SubSkillType.SALVAGE_ARCANE_SALVAGE), "Salvage"), + ImmutableList.of(SubSkillType.SALVAGE_SCRAP_COLLECTOR, SubSkillType.SALVAGE_ARCANE_SALVAGE), "Salvage"), SMELTING(SmeltingManager.class, Color.YELLOW, ImmutableList.of(SubSkillType.SMELTING_UNDERSTANDING_THE_ART, /*SubSkillType.SMELTING_FLUX_MINING,*/ SubSkillType.SMELTING_FUEL_EFFICIENCY, SubSkillType.SMELTING_SECOND_SMELT), "Smelting"), SWORDS(SwordsManager.class, Color.fromRGB(178, 34, 34), SuperAbilityType.SERRATED_STRIKES, ToolType.SWORD, diff --git a/src/main/java/com/gmail/nossr50/datatypes/skills/SubSkillType.java b/src/main/java/com/gmail/nossr50/datatypes/skills/SubSkillType.java index 44ab15c72..f741d6094 100644 --- a/src/main/java/com/gmail/nossr50/datatypes/skills/SubSkillType.java +++ b/src/main/java/com/gmail/nossr50/datatypes/skills/SubSkillType.java @@ -61,7 +61,7 @@ public enum SubSkillType { REPAIR_SUPER_REPAIR(1), /* Salvage */ - SALVAGE_ADVANCED_SALVAGE(1), + SALVAGE_SCRAP_COLLECTOR(8), SALVAGE_ARCANE_SALVAGE(8), /* Smelting */ diff --git a/src/main/java/com/gmail/nossr50/dumpster/mods/CustomToolConfig.java b/src/main/java/com/gmail/nossr50/dumpster/mods/CustomToolConfig.java deleted file mode 100644 index f39000679..000000000 --- a/src/main/java/com/gmail/nossr50/dumpster/mods/CustomToolConfig.java +++ /dev/null @@ -1,102 +0,0 @@ -package com.gmail.nossr50.dumpster.mods; - -/* -public class CustomToolConfig extends Config { - //TODO: Disabled until modded servers come back - public List customAxes = new ArrayList(); - public List customBows = new ArrayList(); - public List customHoes = new ArrayList(); - public List customPickaxes = new ArrayList(); - public List customShovels = new ArrayList(); - public List customSwords = new ArrayList(); - public HashMap customToolMap = new HashMap(); - public List repairables = new ArrayList(); - private boolean needsUpdate = false; - - protected CustomToolConfig(String fileName) { - //super(McmmoCore.getDataFolderPath().getPath() + "mods", fileName, false); - super(mcMMO.p.getDataFolder().getPath() + "mods", fileName, false); - loadKeys(); - } - - @Override - protected void loadKeys() { - loadTool("Axes", customAxes); - loadTool("Bows", customBows); - loadTool("Hoes", customHoes); - loadTool("Pickaxes", customPickaxes); - loadTool("Shovels", customShovels); - loadTool("Swords", customSwords); - - if (needsUpdate) { - needsUpdate = false; - backup(); - } - } - - private void loadTool(String toolType, List materialList) { - if (needsUpdate) { - return; - } - - ConfigurationSection toolSection = config.getConfigurationSection(toolType); - - if (toolSection == null) { - return; - } - - Set toolConfigSet = toolSection.getKeys(false); - - for (String toolName : toolConfigSet) { - if (config.contains(toolType + "." + toolName + "." + ".ID")) { - needsUpdate = true; - return; - } - - Material toolMaterial = Material.matchMaterial(toolName); - - if (toolMaterial == null) { - plugin.getLogger().warning("Invalid material name. This item will be skipped. - " + toolName); - continue; - } - - boolean repairable = getBooleanValue(toolType + "." + toolName + ".Repairable"); - Material repairMaterial = Material.matchMaterial(getStringValue(toolType + "." + toolName + ".Repair_Material", "")); - - if (repairable && (repairMaterial == null)) { - plugin.getLogger().warning("Incomplete repair information. This item will be unrepairable. - " + toolName); - repairable = false; - } - - if (repairable) { - byte repairData = (byte) getIntValue(toolType + "." + toolName + ".Repair_Material_Data_Value", -1); - int repairQuantity = SkillUtils.getRepairAndSalvageQuantities(new ItemStack(toolMaterial), repairMaterial, repairData); - - if (repairQuantity == 0) { - repairQuantity = getIntValue(toolType + "." + toolName + ".Repair_Material_Quantity", 2); - } - - String repairItemName = getStringValue(toolType + "." + toolName + ".Repair_Material_Pretty_Name"); - int repairMinimumLevel = getIntValue(toolType + "." + toolName + ".Repair_MinimumLevel", 0); - double repairXpMultiplier = getDoubleValue(toolType + "." + toolName + ".Repair_XpMultiplier", 1); - - short durability = toolMaterial.getMaxDurability(); - - if (durability == 0) { - durability = (short) getIntValue(toolType + "." + toolName + ".Durability", 60); - } - - repairables.add(RepairableFactory.getRepairable(toolMaterial, repairMaterial, repairData, repairItemName, repairMinimumLevel, repairQuantity, durability, ItemType.TOOL, ItemMaterialCategory.OTHER, repairXpMultiplier)); - } - - double multiplier = getDoubleValue(toolType + "." + toolName + ".XP_Modifier", 1.0); - boolean abilityEnabled = getBooleanValue(toolType + "." + toolName + ".Ability_Enabled", true); - int tier = getIntValue(toolType + "." + toolName + ".Tier", 1); - - CustomTool tool = new CustomTool(tier, abilityEnabled, multiplier); - - materialList.add(toolMaterial); - customToolMap.put(toolMaterial, tool); - } - } -}*/ diff --git a/src/main/java/com/gmail/nossr50/listeners/BlockListener.java b/src/main/java/com/gmail/nossr50/listeners/BlockListener.java index e75a718cf..7f8de6e6b 100644 --- a/src/main/java/com/gmail/nossr50/listeners/BlockListener.java +++ b/src/main/java/com/gmail/nossr50/listeners/BlockListener.java @@ -72,10 +72,11 @@ public class BlockListener implements Listener { for (int i = 0; i < bonusCount; i++) { event.getBlock().getWorld().dropItemNaturally(event.getBlockState().getLocation(), is); } - - event.getBlock().removeMetadata(MetadataConstants.BONUS_DROPS_METAKEY, plugin); } } + + if(event.getBlock().hasMetadata(MetadataConstants.BONUS_DROPS_METAKEY)) + event.getBlock().removeMetadata(MetadataConstants.BONUS_DROPS_METAKEY, plugin); } /*@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) diff --git a/src/main/java/com/gmail/nossr50/listeners/InteractionManager.java b/src/main/java/com/gmail/nossr50/listeners/InteractionManager.java index 2a7689d4a..5080de891 100644 --- a/src/main/java/com/gmail/nossr50/listeners/InteractionManager.java +++ b/src/main/java/com/gmail/nossr50/listeners/InteractionManager.java @@ -15,12 +15,7 @@ public class InteractionManager { private static HashMap subSkillNameMap; //Used for mmoinfo optimization private static ArrayList subSkillList; - /** - * Registers subskills with the Interaction registration - * - * @param abstractSubSkill the target subskill to register - */ - public static void registerSubSkill(AbstractSubSkill abstractSubSkill) { + public static void initMaps() { /* INIT MAPS */ if (interactRegister == null) interactRegister = new HashMap<>(); @@ -30,7 +25,14 @@ public class InteractionManager { if (subSkillNameMap == null) subSkillNameMap = new HashMap<>(); + } + /** + * Registers subskills with the Interaction registration + * @param abstractSubSkill the target subskill to register + */ + public static void registerSubSkill(AbstractSubSkill abstractSubSkill) + { //Store a unique copy of each subskill if (!subSkillList.contains(abstractSubSkill)) subSkillList.add(abstractSubSkill); @@ -70,8 +72,13 @@ public class InteractionManager { * @param plugin instance of mcMMO plugin * @param curInteractType the associated interaction type */ - public static void processEvent(Event event, mcMMO plugin, InteractType curInteractType) { - for (Interaction interaction : interactRegister.get(curInteractType)) { + public static void processEvent(Event event, mcMMO plugin, InteractType curInteractType) + { + if(interactRegister.get(curInteractType) == null) + return; + + for(Interaction interaction : interactRegister.get(curInteractType)) + { interaction.doInteraction(event, plugin); } } diff --git a/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java b/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java index 050a18ecc..9a3c2219f 100644 --- a/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java +++ b/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java @@ -26,6 +26,7 @@ import com.gmail.nossr50.skills.salvage.SalvageManager; import com.gmail.nossr50.skills.taming.TamingManager; import com.gmail.nossr50.util.*; import com.gmail.nossr50.util.player.UserManager; +import com.gmail.nossr50.util.skills.RankUtils; import com.gmail.nossr50.util.skills.SkillUtils; import com.gmail.nossr50.util.sounds.SoundManager; import com.gmail.nossr50.util.sounds.SoundType; @@ -599,27 +600,34 @@ public class PlayerListener implements Listener { if (!mcMMO.getConfigManager().getConfigSuperAbilities().isMustSneakToActivate() || player.isSneaking()) { /* REPAIR CHECKS */ - if (type == Repair.getInstance().getAnvilMaterial() && PrimarySkillType.REPAIR.getPermissions(player) && mcMMO.getRepairableManager().isRepairable(heldItem)) { + if (type == Repair.getInstance().getAnvilMaterial() + && PrimarySkillType.REPAIR.getPermissions(player) + && mcMMO.getRepairableManager().isRepairable(heldItem) + && heldItem.getAmount() <= 1) { RepairManager repairManager = mcMMOPlayer.getRepairManager(); event.setCancelled(true); // Make sure the player knows what he's doing when trying to repair an enchanted item - if (!(heldItem.getEnchantments().size() > 0) || repairManager.checkConfirmation(true)) { + if (repairManager.checkConfirmation(true)) { repairManager.handleRepair(heldItem); player.updateInventory(); } } /* SALVAGE CHECKS */ - else if (type == Salvage.anvilMaterial && PrimarySkillType.SALVAGE.getPermissions(player) && mcMMO.getSalvageableManager().isSalvageable(heldItem)) { - SalvageManager salvageManager = UserManager.getPlayer(player).getSalvageManager(); - event.setCancelled(true); + else if (type == Salvage.anvilMaterial + && PrimarySkillType.SALVAGE.getPermissions(player) + && RankUtils.hasUnlockedSubskill(player, SubSkillType.SALVAGE_SCRAP_COLLECTOR) + && mcMMO.getSalvageableManager().isSalvageable(heldItem) + && heldItem.getAmount() <= 1) { + SalvageManager salvageManager = UserManager.getPlayer(player).getSalvageManager(); + event.setCancelled(true); - // Make sure the player knows what he's doing when trying to salvage an enchanted item - if (!(heldItem.getEnchantments().size() > 0) || salvageManager.checkConfirmation(true)) { - SkillUtils.handleAbilitySpeedDecrease(player); - salvageManager.handleSalvage(block.getLocation(), heldItem); - player.updateInventory(); - } + // Make sure the player knows what he's doing when trying to salvage an enchanted item + if (salvageManager.checkConfirmation(true)) { + SkillUtils.handleAbilitySpeedDecrease(player); + salvageManager.handleSalvage(block.getLocation(), heldItem); + player.updateInventory(); + } } } /* BLAST MINING CHECK */ diff --git a/src/main/java/com/gmail/nossr50/mcMMO.java b/src/main/java/com/gmail/nossr50/mcMMO.java index 95be2416d..f616179fe 100644 --- a/src/main/java/com/gmail/nossr50/mcMMO.java +++ b/src/main/java/com/gmail/nossr50/mcMMO.java @@ -503,6 +503,8 @@ public class mcMMO extends JavaPlugin { */ if (mcMMO.getConfigManager().getConfigCoreSkills().isAcrobaticsEnabled()) { + InteractionManager.initMaps(); //Init maps + System.out.println("[mcMMO]" + " enabling Acrobatics Skills"); //TODO: Should do this differently 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 3e01c2aa2..fc654de36 100644 --- a/src/main/java/com/gmail/nossr50/skills/repair/RepairManager.java +++ b/src/main/java/com/gmail/nossr50/skills/repair/RepairManager.java @@ -114,9 +114,8 @@ public class RepairManager extends SkillManager { return; } - - //byte repairMaterialMetadata = repairable.getRepairMaterialMetadata(); ItemStack toRemove = new ItemStack(repairMaterial); + toRemove.setAmount(1); short startDurability = item.getDurability(); @@ -126,26 +125,6 @@ public class RepairManager extends SkillManager { return; } - // Check if they have the proper material to repair with - /*if (!inventory.contains(repairMaterial)) { - String prettyName = repairable.getRepairMaterialPrettyName() == null ? StringUtils.getPrettyItemString(repairMaterial) : repairable.getRepairMaterialPrettyName(); - - String materialsNeeded = ""; - - if (repairMaterialMetadata != (byte) -1 && !inventory.containsAtLeast(toRemove, 1)) { - materialsNeeded += ":" + repairMaterialMetadata; - } - - NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE_FAILED, "Skills.NeedMore.Extra", prettyName, materialsNeeded); - return; - }*/ - - // Do not repair stacked items - if (item.getAmount() != 1) { - NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE_FAILED, "Repair.Skills.StackedItems"); - return; - } - // Clear ability buffs before trying to repair. SkillUtils.removeAbilityBuff(item); @@ -165,11 +144,6 @@ public class RepairManager extends SkillManager { } // Remove the item - /*if (repairMaterialMetadata == -1) { - toRemove = inventory.getItem(inventory.first(repairMaterial)).clone(); - toRemove.setAmount(1); - }*/ - inventory.removeItem(toRemove); // Give out XP like candy diff --git a/src/main/java/com/gmail/nossr50/skills/repair/repairables/Repairable.java b/src/main/java/com/gmail/nossr50/skills/repair/repairables/Repairable.java index 931163284..8547964d5 100644 --- a/src/main/java/com/gmail/nossr50/skills/repair/repairables/Repairable.java +++ b/src/main/java/com/gmail/nossr50/skills/repair/repairables/Repairable.java @@ -8,7 +8,6 @@ import org.bukkit.Material; import java.util.Collections; import java.util.List; - public class Repairable { private final Material itemMaterial; private final List repairMaterials; diff --git a/src/main/java/com/gmail/nossr50/skills/salvage/SalvageManager.java b/src/main/java/com/gmail/nossr50/skills/salvage/SalvageManager.java index acb4447ba..5826a4b94 100644 --- a/src/main/java/com/gmail/nossr50/skills/salvage/SalvageManager.java +++ b/src/main/java/com/gmail/nossr50/skills/salvage/SalvageManager.java @@ -89,16 +89,12 @@ public class SalvageManager extends SkillManager { return; } - if (item.getDurability() != 0 && (!RankUtils.hasUnlockedSubskill(player, SubSkillType.SALVAGE_ADVANCED_SALVAGE) || !Permissions.advancedSalvage(player))) { - NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE_FAILED, "Salvage.Skills.Adept.Damaged"); - return; - } + int maxAmountSalvageable = Salvage.calculateSalvageableAmount(item.getDurability(), salvageable.getMaximumDurability(), salvageable.getMaximumQuantity()); - int salvageableAmount = Salvage.calculateSalvageableAmount(item.getDurability(), salvageable.getMaximumDurability(), salvageable.getMaximumQuantity()); + int salvageableAmount = maxAmountSalvageable; if (salvageableAmount == 0) { NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE_FAILED, "Salvage.Skills.TooDamaged"); - player.sendMessage(LocaleLoader.getString("Salvage.Skills.TooDamaged")); return; } @@ -114,7 +110,30 @@ public class SalvageManager extends SkillManager { enchantBook = arcaneSalvageCheck(enchants); } - ItemStack salvageResults = new ItemStack(salvageable.getSalvagedItemMaterial(), salvageableAmount); + //Lottery on Salvageable Amount + + int lotteryResults = 1; + int chanceOfSuccess = 80; + + for(int x = 1; x < salvageableAmount-1; x++) { + + if(RandomChanceUtil.rollDice(chanceOfSuccess, 100)) { + chanceOfSuccess-=20; + Math.max(chanceOfSuccess, 33); + + lotteryResults+=1; + } + } + + if(lotteryResults == salvageableAmount) { + NotificationManager.sendPlayerInformationChatOnly(player, "Salvage.Skills.Lottery.Perfect", String.valueOf(lotteryResults), StringUtils.getPrettyItemString(item.getType())); + } else if(RankUtils.isPlayerMaxRankInSubSkill(player, SubSkillType.SALVAGE_ARCANE_SALVAGE)) { + NotificationManager.sendPlayerInformationChatOnly(player, "Salvage.Skills.Lottery.Normal", String.valueOf(lotteryResults), StringUtils.getPrettyItemString(item.getType())); + } else { + NotificationManager.sendPlayerInformationChatOnly(player, "Salvage.Skills.Lottery.Untrained", String.valueOf(lotteryResults), StringUtils.getPrettyItemString(item.getType())); + } + + ItemStack salvageResults = new ItemStack(salvageable.getSalvagedItemMaterial(), lotteryResults); //Call event if (EventUtils.callSalvageCheckEvent(player, item, salvageResults, enchantBook).isCancelled()) { diff --git a/src/main/java/com/gmail/nossr50/util/TextComponentFactory.java b/src/main/java/com/gmail/nossr50/util/TextComponentFactory.java index d5fdd82aa..68331e0e3 100644 --- a/src/main/java/com/gmail/nossr50/util/TextComponentFactory.java +++ b/src/main/java/com/gmail/nossr50/util/TextComponentFactory.java @@ -1,6 +1,5 @@ package com.gmail.nossr50.util; -import com.gmail.nossr50.datatypes.interactions.NotificationType; import com.gmail.nossr50.datatypes.json.McMMOUrl; import com.gmail.nossr50.datatypes.json.McMMOWebLinks; import com.gmail.nossr50.datatypes.skills.PrimarySkillType; @@ -26,18 +25,19 @@ public class TextComponentFactory { /** * Makes a text component using strings from a locale and supports passing an undefined number of variables to the LocaleLoader * - * @param localeKey target locale string address - * @param notificationType type of notification - * @param values vars to be passed to the locale loader + * @param localeKey target locale string address + * @param values vars to be passed to the locale loader * @return */ - public static TextComponent getNotificationMultipleValues(String localeKey, NotificationType notificationType, String... values) { + public static TextComponent getNotificationMultipleValues(String localeKey, String... values) + { String preColoredString = LocaleLoader.getString(localeKey, (Object[]) values); TextComponent msg = new TextComponent(preColoredString); return new TextComponent(msg); } - public static TextComponent getNotificationTextComponentFromLocale(String localeKey, NotificationType notificationType) { + public static TextComponent getNotificationTextComponentFromLocale(String localeKey) + { return getNotificationTextComponent(LocaleLoader.getString(localeKey)); } diff --git a/src/main/java/com/gmail/nossr50/util/player/NotificationManager.java b/src/main/java/com/gmail/nossr50/util/player/NotificationManager.java index 39019f279..afcfa837d 100644 --- a/src/main/java/com/gmail/nossr50/util/player/NotificationManager.java +++ b/src/main/java/com/gmail/nossr50/util/player/NotificationManager.java @@ -37,7 +37,7 @@ public class NotificationManager { ChatMessageType destination = AdvancedConfig.getInstance().doesNotificationUseActionBar(notificationType) ? ChatMessageType.ACTION_BAR : ChatMessageType.SYSTEM; - TextComponent message = TextComponentFactory.getNotificationTextComponentFromLocale(key, notificationType); + TextComponent message = TextComponentFactory.getNotificationTextComponentFromLocale(key); McMMOPlayerNotificationEvent customEvent = checkNotificationEvent(player, notificationType, destination, message); sendNotification(player, customEvent); @@ -65,13 +65,23 @@ public class NotificationManager { sendPlayerInformation(targetPlayer, notificationType, key, values); } - public static void sendPlayerInformation(Player player, NotificationType notificationType, String key, String... values) { - if (UserManager.getPlayer(player) == null || !UserManager.getPlayer(player).useChatNotifications()) + public static void sendPlayerInformationChatOnly(Player player, String key, String... values) + { + if(UserManager.getPlayer(player) == null || !UserManager.getPlayer(player).useChatNotifications()) + return; + + String preColoredString = LocaleLoader.getString(key, (Object[]) values); + player.sendMessage(preColoredString); + } + + public static void sendPlayerInformation(Player player, NotificationType notificationType, String key, String... values) + { + if(UserManager.getPlayer(player) == null || !UserManager.getPlayer(player).useChatNotifications()) return; ChatMessageType destination = AdvancedConfig.getInstance().doesNotificationUseActionBar(notificationType) ? ChatMessageType.ACTION_BAR : ChatMessageType.SYSTEM; - TextComponent message = TextComponentFactory.getNotificationMultipleValues(key, notificationType, values); + TextComponent message = TextComponentFactory.getNotificationMultipleValues(key, values); McMMOPlayerNotificationEvent customEvent = checkNotificationEvent(player, notificationType, destination, message); sendNotification(player, customEvent); diff --git a/src/main/java/com/gmail/nossr50/util/player/UserManager.java b/src/main/java/com/gmail/nossr50/util/player/UserManager.java index 1378d9473..17784f7db 100644 --- a/src/main/java/com/gmail/nossr50/util/player/UserManager.java +++ b/src/main/java/com/gmail/nossr50/util/player/UserManager.java @@ -68,6 +68,9 @@ public final class UserManager { * Save all users ON THIS THREAD. */ public static void saveAll() { + if(playerDataSet == null) + return; + ImmutableList trackedSyncData = ImmutableList.copyOf(playerDataSet); mcMMO.p.getLogger().info("Saving mcMMOPlayers... (" + trackedSyncData.size() + ")"); diff --git a/src/main/java/com/gmail/nossr50/util/skills/RankUtils.java b/src/main/java/com/gmail/nossr50/util/skills/RankUtils.java index 35b2fd5b8..2f0636cb2 100644 --- a/src/main/java/com/gmail/nossr50/util/skills/RankUtils.java +++ b/src/main/java/com/gmail/nossr50/util/skills/RankUtils.java @@ -397,4 +397,10 @@ public class RankUtils { return mcMMO.getConfigManager().getConfigLeveling().getLevelCap(subSkillType.getParentSkill()); } + public static boolean isPlayerMaxRankInSubSkill(Player player, SubSkillType subSkillType) { + int playerRank = getRank(player, subSkillType); + int highestRank = getHighestRank(subSkillType); + + return playerRank == highestRank; + } } \ No newline at end of file diff --git a/src/main/java/com/gmail/nossr50/util/skills/SkillUtils.java b/src/main/java/com/gmail/nossr50/util/skills/SkillUtils.java index e6325d06a..5d3245a21 100644 --- a/src/main/java/com/gmail/nossr50/util/skills/SkillUtils.java +++ b/src/main/java/com/gmail/nossr50/util/skills/SkillUtils.java @@ -13,6 +13,7 @@ import com.gmail.nossr50.util.ItemUtils; import com.gmail.nossr50.util.Misc; import com.gmail.nossr50.util.StringUtils; import com.gmail.nossr50.util.player.NotificationManager; +import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.enchantments.Enchantment; @@ -24,6 +25,7 @@ import org.bukkit.inventory.ShapelessRecipe; import org.bukkit.inventory.meta.ItemMeta; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; public class SkillUtils { @@ -268,33 +270,33 @@ public class SkillUtils { } public static int getRepairAndSalvageQuantities(ItemStack item) { - return getRepairAndSalvageQuantities(item, getRepairAndSalvageItem(item), (byte) -1); + return getRepairAndSalvageQuantities(item.getType(), getRepairAndSalvageItem(item)); } - public static int getRepairAndSalvageQuantities(ItemStack item, Material repairMaterial, byte repairMetadata) { - // Workaround for Bukkit bug where damaged items would not return any recipes - item = item.clone(); - item.setDurability((short) 0); - + public static int getRepairAndSalvageQuantities(Material itemMaterial, Material recipeMaterial) { int quantity = 0; - List recipes = mcMMO.p.getServer().getRecipesFor(item); - if (recipes.isEmpty()) { - return quantity; - } + for(Iterator recipeIterator = Bukkit.getServer().recipeIterator(); recipeIterator.hasNext();) { + Recipe bukkitRecipe = recipeIterator.next(); - Recipe recipe = recipes.get(0); + if(bukkitRecipe.getResult().getType() != itemMaterial) + continue; - if (recipe instanceof ShapelessRecipe) { - for (ItemStack ingredient : ((ShapelessRecipe) recipe).getIngredientList()) { - if (ingredient != null && (repairMaterial == null || ingredient.getType() == repairMaterial) && (repairMetadata == -1 || ingredient.getType().equals(repairMaterial))) { - quantity += ingredient.getAmount(); + if(bukkitRecipe instanceof ShapelessRecipe) { + for (ItemStack ingredient : ((ShapelessRecipe) bukkitRecipe).getIngredientList()) { + if (ingredient != null + && (recipeMaterial == null || ingredient.getType() == recipeMaterial) + && (ingredient.getType() == recipeMaterial)) { + quantity += ingredient.getAmount(); + } } - } - } else if (recipe instanceof ShapedRecipe) { - for (ItemStack ingredient : ((ShapedRecipe) recipe).getIngredientMap().values()) { - if (ingredient != null && (repairMaterial == null || ingredient.getType() == repairMaterial) && (repairMetadata == -1 || ingredient.getType().equals(repairMaterial))) { - quantity += ingredient.getAmount(); + } else if(bukkitRecipe instanceof ShapedRecipe) { + for (ItemStack ingredient : ((ShapedRecipe) bukkitRecipe).getIngredientMap().values()) { + if (ingredient != null + && (recipeMaterial == null || ingredient.getType() == recipeMaterial) + && (ingredient.getType() == recipeMaterial)) { + quantity += ingredient.getAmount(); + } } } } diff --git a/src/main/resources/locale/locale_en_US.properties b/src/main/resources/locale/locale_en_US.properties index f41620c2f..9ebdd1507 100644 --- a/src/main/resources/locale/locale_en_US.properties +++ b/src/main/resources/locale/locale_en_US.properties @@ -51,6 +51,8 @@ JSON.Notification.SuperAbility={0} #These are the JSON Strings used for SubSkills JSON.Acrobatics.Roll.Interaction.Activated=Test [[RED]]Rolled Test JSON.Acrobatics.SubSkill.Roll.Details.Tips=If you hold sneak while falling you can prevent up to twice the damage that you would normally take! +Anvil.SingleItemStack=[[RED]]You cannot salvage or repair item stacks that have more than one item, split the stack first. + #DO NOT USE COLOR CODES IN THE JSON KEYS #COLORS ARE DEFINED IN advanced.yml IF YOU WISH TO CHANGE THEM # BEGIN STYLING @@ -368,14 +370,14 @@ Repair.Arcane.Perfect=[[GREEN]]You have sustained the arcane energies in this it Salvage.Pretty.Name=Salvage Salvage.SubSkill.UnderstandingTheArt.Name=Understanding The Art Salvage.SubSkill.UnderstandingTheArt.Description=You're not just digging through your neighbors trash, you're taking care of the environment.\nPowers up various properties of Salvaging. -Salvage.SubSkill.AdvancedSalvage.Name=Advanced Salvage -Salvage.SubSkill.AdvancedSalvage.Description=Salvage damaged items +Salvage.SubSkill.ScrapCollector.Name=Scrap Collector +Salvage.SubSkill.ScrapCollector.Description=Salvage materials from an item, a perfect salvage depends on skill and luck. +Salvage.SubSkill.ScrapCollector.Stat=Scrap Collector: [[GREEN]]Salvage up to [[YELLOW]]{0}[[GREEN]] items. Some luck is involved. Salvage.SubSkill.ArcaneSalvage.Name=Arcane Salvaging Salvage.SubSkill.ArcaneSalvage.Description=Extract enchantments from items Salvage.SubSkill.ArcaneSalvage.Stat=Arcane Salvaging: [[YELLOW]]Rank {0}/{1} -Salvage.Ability.Locked.0=LOCKED UNTIL {0}+ SKILL (ADVANCED SALVAGE) -Salvage.Ability.Bonus.0=Advanced Salvage -Salvage.Ability.Bonus.1={0} Max Materials Recovered from Salvaging +Salvage.Ability.Bonus.0=Scrap Collector +Salvage.Ability.Bonus.1=Salvage up to [[YELLOW]]{0}[[GREEN]] items. Some luck is involved. Salvage.Arcane.ExtractFull=[[GRAY]]AS Full-Enchant Chance Salvage.Arcane.ExtractPartial=[[GRAY]]AS Partial-Enchant Chance Salvage.Skills.Success=[[GREEN]]Item salvaged! @@ -388,6 +390,9 @@ Salvage.Skills.ArcaneSuccess=[[GREEN]]You able to extract all of the knowledge c Salvage.Listener.Anvil=[[DARK_RED]]You have placed a Salvage anvil, use this to Salvage tools and armor. Salvage.Listener=Salvage: Salvage.SkillName=SALVAGE +Salvage.Skills.Lottery.Normal=[[GOLD]]You were able to salvage [[GREEN]]{0}[[GOLD]] materials from [[DARK_AQUA]]{1}[[GOLD]]. +Salvage.Skills.Lottery.Perfect=[[GREEN]][[BOLD]]Perfect![[RESET]][[GOLD]] You salvaged [[GREEN]]{1}[[GOLD]] effortlessly, retrieving [[DARK_AQUA]]{0}[[GOLD]] materials. +Salvage.Skills.Lottery.Untrained=[[GRAY]]You aren't properly trained in salvaging. You were only able to recover [[RED]]{0}[[GRAY]] materials from [[GREEN]]{1}[[GRAY]]. #Anvil (Shared between SALVAGE and REPAIR) Anvil.Unbreakable=This item is unbreakable! #SWORDS diff --git a/src/main/resources/locale/locale_zh_CN.properties b/src/main/resources/locale/locale_zh_CN.properties index 21ae88bad..ca2d1bffb 100644 --- a/src/main/resources/locale/locale_zh_CN.properties +++ b/src/main/resources/locale/locale_zh_CN.properties @@ -51,6 +51,8 @@ JSON.Notification.SuperAbility={0} #These are the JSON Strings used for SubSkills JSON.Acrobatics.Roll.Interaction.Activated=\u6d4b\u8bd5 [[RED]]\u7ffb\u6eda\u6d4b\u8bd5 JSON.Acrobatics.SubSkill.Roll.Details.Tips=\u5982\u679c\u4f60\u5728\u6454\u843d\u65f6\u6309\u4e0b\u6f5c\u884c\u952e,\u4f60\u5c06\u89e6\u53d1\u4e24\u500d\u7ffb\u6eda\u6548\u679c +Anvil.SingleItemStack=[[RED]]\u4f60\u4e0d\u80fd\u5206\u89e3\u8d27\u4fee\u590d\u6709\u591a\u4e2a\u7269\u54c1\u7684\u7269\u54c1\u5806, \u8bf7\u62c6\u5206\u540e\u518d\u4f7f\u7528. + #DO NOT USE COLOR CODES IN THE JSON KEYS #COLORS ARE DEFINED IN advanced.yml IF YOU WISH TO CHANGE THEM # BEGIN STYLING @@ -98,6 +100,8 @@ Commands.Party.Header=[[RED]]-----[][[GREEN]]\u961f\u4f0d[[RED]][]----- Commands.Party.Features.Header=[[RED]]-----[][[GREEN]]FEATURES[[RED]][]----- # XP BAR Allows for the following variables -- {0} = Skill Level, {1} Current XP, {2} XP Needed for next level, {3} Power Level, {4} Percentage of Level # Make sure you turn on Experience_Bars.ThisMayCauseLag.AlwaysUpdateTitlesWhenXPIsGained if you want the XP bar title to update every time a player gains XP! +XPBar.Template={0} +XPBar.Template.EarlyGameBoost=[[GOLD]]\u6b63\u5728\u5b66\u4e60\u65b0\u6280\u80fd... XPBar.Acrobatics=\u6742\u6280 Lv.[[GOLD]]{0} XPBar.Alchemy=\u70bc\u91d1 Lv.[[GOLD]]{0} XPBar.Archery=\u7bad\u672f Lv.[[GOLD]]{0} @@ -817,6 +821,18 @@ Commands.Event.Stop=[[GREEN]]mcMMO[[DARK_AQUA]] \u4e8b\u4ef6\u7ed3\u675f! Commands.Event.Stop.Subtitle=[[GREEN]]\u6211\u5e0c\u671b\u4f60\u73a9\u7684\u5f00\u5fc3! Commands.Event.XP=[[DARK_AQUA]]\u591a\u500d\u7ecf\u9a8c\u901f\u7387\u4e3a [[GOLD]]{0}[[DARK_AQUA]] \u500d XPRate.Event=[[GOLD]]mcMMO \u73b0\u5728\u6b63\u5904\u4e8e\u591a\u500d\u7ecf\u9a8c\u4e8b\u4ef6\u9636\u6bb5! \u7ecf\u9a8c\u83b7\u53d6\u7387\u4e3a {0}\u500d! + +# Admin Notifications +Server.ConsoleName=[[YELLOW]][Server] +Notifications.Admin.XPRate.Start.Self=[[GRAY]]\u4f60\u5df2\u5c06\u5168\u5c40\u591a\u500d\u7ecf\u9a8c\u8bbe\u7f6e\u4e3a [[GOLD]]{0} \u500d +Notifications.Admin.XPRate.End.Self=[[GRAY]]\u4f60\u7ed3\u675f\u4e86\u591a\u500d\u7ecf\u9a8c\u4e8b\u4ef6. +Notifications.Admin.XPRate.End.Others={0} [[GRAY]]\u7ed3\u675f\u4e86\u591a\u500d\u7ecf\u9a8c\u4e8b\u4ef6 +Notifications.Admin.XPRate.Start.Others={0} [[GRAY]]\u5df2\u542f\u52a8\u6216\u4fee\u6539\u5177\u6709\u5168\u5c40 {1} \u500d\u7684\u591a\u500d\u7ecf\u9a8c\u4e8b\u4ef6 +Notifications.Admin.Format.Others=[[GOLD]]([[GREEN]]mcMMO [[DARK_AQUA]]Admin[[GOLD]]) [[GRAY]]{0} +Notifications.Admin.Format.Self=[[GOLD]]([[GREEN]]mcMMO[[GOLD]]) [[GRAY]]{0} + +# Event + #GUIDES Guides.Available=[[GRAY]]{0} \u7684\u5411\u5bfc - \u8f93\u5165 /{1} ? [\u9875\u6570] Guides.Header=[[GOLD]]-=[[GREEN]]{0} \u5411\u5bfc[[GOLD]]=- diff --git a/src/main/resources/repair.vanilla.yml b/src/main/resources/repair.vanilla.yml index c0d8180cd..49eec21d7 100644 --- a/src/main/resources/repair.vanilla.yml +++ b/src/main/resources/repair.vanilla.yml @@ -30,7 +30,7 @@ # # MinimumQuantity: This is the minimum number of items needed to repair this item ignoring all other repair bonuses. ## This is typically the number of the repair material needed to create a new item, for example for a sword it is 2, for an axe it is 3 -## This defaults to 2 +## If this isn't set, mcMMO will try to look up the minimum quantity for the item via recipes. It is not necessary to define this field. # # XpMultiplier: This is the amount to multiply the xp bonus by. ## This defaults to 1 diff --git a/src/main/resources/skillranks.yml b/src/main/resources/skillranks.yml index 0656b18a8..211b44e63 100644 --- a/src/main/resources/skillranks.yml +++ b/src/main/resources/skillranks.yml @@ -282,11 +282,25 @@ Smelting: Rank_7: 850 Rank_8: 1000 Salvage: - AdvancedSalvage: + ScrapCollector: Standard: - Rank_1: 35 + Rank_1: 2 + Rank_2: 10 + Rank_3: 15 + Rank_4: 20 + Rank_5: 25 + Rank_6: 30 + Rank_7: 35 + Rank_8: 40 RetroMode: - Rank_1: 350 + Rank_1: 20 + Rank_2: 100 + Rank_3: 150 + Rank_4: 200 + Rank_5: 250 + Rank_6: 300 + Rank_7: 350 + Rank_8: 400 ArcaneSalvage: Standard: Rank_1: 10